Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2:
nilfs2: fix disorder in cp count on error during deleting checkpoints
nilfs2: fix lockdep warning between regular file and inode file
nilfs2: fix incorrect KERN_CRIT messages in case of write failures
nilfs2: fix hang problem of log writer which occurs after write failures
nilfs2: remove unlikely directive causing mis-conversion of error code
diff --git a/Documentation/DocBook/mac80211.tmpl b/Documentation/DocBook/mac80211.tmpl
index e369866..f3f37f1 100644
--- a/Documentation/DocBook/mac80211.tmpl
+++ b/Documentation/DocBook/mac80211.tmpl
@@ -184,8 +184,6 @@
!Finclude/net/mac80211.h ieee80211_ctstoself_get
!Finclude/net/mac80211.h ieee80211_ctstoself_duration
!Finclude/net/mac80211.h ieee80211_generic_frame_duration
-!Finclude/net/mac80211.h ieee80211_get_hdrlen_from_skb
-!Finclude/net/mac80211.h ieee80211_hdrlen
!Finclude/net/mac80211.h ieee80211_wake_queue
!Finclude/net/mac80211.h ieee80211_stop_queue
!Finclude/net/mac80211.h ieee80211_wake_queues
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index a52adfc..3d1b0ab 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -25,7 +25,7 @@
"tda10046lifeview", "av7110", "dec2000t", "dec2540t",
"dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
"or51211", "or51132_qam", "or51132_vsb", "bluebird",
- "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2" );
+ "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718" );
# Check args
syntax() if (scalar(@ARGV) != 1);
@@ -381,6 +381,57 @@
$allfiles;
}
+sub mpc718 {
+ my $archive = 'Yuan MPC718 TV Tuner Card 2.13.10.1016.zip';
+ my $url = "ftp://ftp.work.acer-euro.com/desktop/aspire_idea510/vista/Drivers/$archive";
+ my $fwfile = "dvb-cx18-mpc718-mt352.fw";
+ my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+
+ checkstandard();
+ wgetfile($archive, $url);
+ unzip($archive, $tmpdir);
+
+ my $sourcefile = "$tmpdir/Yuan MPC718 TV Tuner Card 2.13.10.1016/mpc718_32bit/yuanrap.sys";
+ my $found = 0;
+
+ open IN, '<', $sourcefile or die "Couldn't open $sourcefile to extract $fwfile data\n";
+ binmode IN;
+ open OUT, '>', $fwfile;
+ binmode OUT;
+ {
+ # Block scope because we change the line terminator variable $/
+ my $prevlen = 0;
+ my $currlen;
+
+ # Buried in the data segment are 3 runs of almost identical
+ # register-value pairs that end in 0x5d 0x01 which is a "TUNER GO"
+ # command for the MT352.
+ # Pull out the middle run (because it's easy) of register-value
+ # pairs to make the "firmware" file.
+
+ local $/ = "\x5d\x01"; # MT352 "TUNER GO"
+
+ while (<IN>) {
+ $currlen = length($_);
+ if ($prevlen == $currlen && $currlen <= 64) {
+ chop; chop; # Get rid of "TUNER GO"
+ s/^\0\0//; # get rid of leading 00 00 if it's there
+ printf OUT "$_";
+ $found = 1;
+ last;
+ }
+ $prevlen = $currlen;
+ }
+ }
+ close OUT;
+ close IN;
+ if (!$found) {
+ unlink $fwfile;
+ die "Couldn't find valid register-value sequence in $sourcefile for $fwfile\n";
+ }
+ $fwfile;
+}
+
sub cx23885 {
my $url = "http://linuxtv.org/downloads/firmware/";
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index f8cd450..09e031c 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -458,3 +458,13 @@
but the old version has been kept around for easier testing. Note this
doesn't impact the old P5 and WinChip machine check handlers.
Who: Andi Kleen <andi@firstfloor.org>
+
+----------------------------
+
+What: lock_policy_rwsem_* and unlock_policy_rwsem_* will not be
+ exported interface anymore.
+When: 2.6.33
+Why: cpu_policy_rwsem has a new cleaner definition making it local to
+ cpufreq core and contained inside cpufreq.c. Other dependent
+ drivers should not use it in order to safely avoid lockdep issues.
+Who: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index d77fbd8..dd1a6d4 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1720,8 +1720,8 @@
oprofile.cpu_type= Force an oprofile cpu type
This might be useful if you have an older oprofile
userland or if you want common events.
- Format: { archperfmon }
- archperfmon: [X86] Force use of architectural
+ Format: { arch_perfmon }
+ arch_perfmon: [X86] Force use of architectural
perfmon on Intel CPUs instead of the
CPU specific event set.
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index 873630e..014d255 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -66,3 +66,4 @@
68 -> Terratec AV350 (em2860) [0ccd:0084]
69 -> KWorld ATSC 315U HDTV TV Box (em2882) [eb1a:a313]
70 -> Evga inDtube (em2882)
+ 71 -> Silvercrest Webcam 1.3mpix (em2820/em2840)
diff --git a/MAINTAINERS b/MAINTAINERS
index 381190c..e4b1a3d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5803,17 +5803,17 @@
M: trivial@kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git
S: Maintained
-F: drivers/char/tty_*
-F: drivers/serial/serial_core.c
-F: include/linux/serial_core.h
-F: include/linux/serial.h
-F: include/linux/tty.h
TTY LAYER
P: Alan Cox
M: alan@lxorguk.ukuu.org.uk
S: Maintained
T: stgit http://zeniv.linux.org.uk/~alan/ttydev/
+F: drivers/char/tty_*
+F: drivers/serial/serial_core.c
+F: include/linux/serial_core.h
+F: include/linux/serial.h
+F: include/linux/tty.h
TULIP NETWORK DRIVERS
P: Grant Grundler
diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h
index d069526..60c83ab 100644
--- a/arch/alpha/include/asm/thread_info.h
+++ b/arch/alpha/include/asm/thread_info.h
@@ -37,6 +37,7 @@
.task = &tsk, \
.exec_domain = &default_exec_domain, \
.addr_limit = KERNEL_DS, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
diff --git a/arch/arm/configs/kb9202_defconfig b/arch/arm/configs/kb9202_defconfig
index 8e74c66..605a846 100644
--- a/arch/arm/configs/kb9202_defconfig
+++ b/arch/arm/configs/kb9202_defconfig
@@ -1,109 +1,246 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc2
-# Sun Aug 14 19:26:59 2005
+# Linux kernel version: 2.6.30-rc8
+# Wed Jun 3 13:52:33 2009
#
CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_MMU=y
-CONFIG_UID16=y
+# CONFIG_NO_IOPORT is not set
+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_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-
-#
-# Code maturity level options
-#
-# CONFIG_EXPERIMENTAL is not set
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# General setup
#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
-# CONFIG_SYSVIPC is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_AUDIT=y
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-# CONFIG_KOBJECT_UEVENT is not set
-# CONFIG_IKCONFIG is not set
+CONFIG_ANON_INODES=y
# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_STRIP_ASM_SYMS 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_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
+CONFIG_MARKERS=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK 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=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
#
-# Loadable module support
+# IO Schedulers
#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
#
# System Type
#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_AAEC2000 is not set
# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MMP 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_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_AAEC2000 is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91RM9200=y
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
#
-# AT91RM9200 Implementations
+# Atmel AT91 System-on-Chip
#
+CONFIG_ARCH_AT91RM9200=y
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+# CONFIG_ARCH_AT91SAM9G20 is not set
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91RM9200 Board Type
+#
+# CONFIG_MACH_ONEARM is not set
# CONFIG_ARCH_AT91RM9200DK is not set
# CONFIG_MACH_AT91RM9200EK is not set
# CONFIG_MACH_CSB337 is not set
# CONFIG_MACH_CSB637 is not set
# CONFIG_MACH_CARMEVA is not set
+# CONFIG_MACH_ATEB9200 is not set
CONFIG_MACH_KB9200=y
+# CONFIG_MACH_PICOTUX2XX is not set
+# CONFIG_MACH_KAFA is not set
+# CONFIG_MACH_ECBAT91 is not set
+# CONFIG_MACH_YL9200 is not set
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_TIMER_HZ=128
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# 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_32=y
CONFIG_CPU_ARM920T=y
-CONFIG_CPU_32v4=y
+CONFIG_CPU_32v4T=y
CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_PABRT_NOIFAR=y
CONFIG_CPU_CACHE_V4WT=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
@@ -112,23 +249,48 @@
# CONFIG_CPU_ICACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_OUTER_CACHE is not set
#
# Bus support
#
-CONFIG_ISA_DMA_API=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCCARD is not set
#
# Kernel Features
#
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+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=y
+CONFIG_HZ=128
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
+# 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=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
# CONFIG_LEDS is not set
CONFIG_ALIGNMENT_TRAP=y
@@ -137,8 +299,16 @@
#
CONFIG_ZBOOT_ROM_TEXT=0x10000000
CONFIG_ZBOOT_ROM_BSS=0x20040000
-CONFIG_ZBOOT_ROM=y
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram rw initrd=0x20210000,654933"
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_CMDLINE="noinitrd root=/dev/mtdblock0 rootfstype=jffs2 mem=64M"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
#
# Floating point emulation
@@ -149,19 +319,93 @@
#
CONFIG_FPE_NWFPE=y
# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
#
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
CONFIG_BINFMT_MISC=y
-# CONFIG_ARTHUR is not set
#
# Power management options
#
# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -170,53 +414,156 @@
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-CONFIG_DEBUG_DRIVER=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# 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
#
-# Memory Technology Devices (MTD)
+# User Modules And Translation Layers
#
-# CONFIG_MTD is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
#
-# Parallel port support
+# RAM/ROM/Flash chip drivers
#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS 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_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_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=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+CONFIG_MTD_UBI_GLUEBI=y
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+CONFIG_ATMEL_SSC=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
#
-# IO Schedulers
+# EEPROM support
#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -232,145 +579,87 @@
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
-# SCSI Transport Attributes
+# SCSI Transports
#
-# CONFIG_SCSI_SPI_ATTRS is not set
+CONFIG_SCSI_SPI_ATTRS=m
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=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
-
-#
-# Ethernet (10 or 100Mbit)
-#
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
CONFIG_ARM_AT91_ETHER=y
+# CONFIG_AX88796 is not set
# CONFIG_SMC91X is not set
# CONFIG_DM9000 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_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
#
-# Ethernet (1000 Mbit)
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
#
#
-# Ethernet (10000 Mbit)
+# USB Network Adapters
#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
-
-#
-# ISDN subsystem
-#
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_ISDN is not set
#
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -380,7 +669,6 @@
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
@@ -390,23 +678,25 @@
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
#
# Hardware I/O ports
#
-CONFIG_SERIO=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO is not set
# CONFIG_GAMEPORT 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
#
@@ -419,159 +709,232 @@
#
CONFIG_SERIAL_ATMEL=y
CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_AT91RM9200_RTC is not set
-# CONFIG_DTLK is not set
+# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_AT91_SPI is not set
-
-#
-# I2C support
-#
+# CONFIG_TCG_TPM is not set
# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
#
-# Misc devices
+# Memory mapped GPIO expanders:
#
#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT91RM9200_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE 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_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
# Multimedia devices
#
-# CONFIG_VIDEO_DEV is not set
#
-# Digital Video Broadcasting Devices
+# Multimedia core support
#
-# CONFIG_DVB is not set
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
#
# Graphics support
#
-# CONFIG_FB is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_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=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+# 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 is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
#
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_FONT_MINI_4x6=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
# CONFIG_SOUND is not set
-
-#
-# USB support
-#
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
CONFIG_USB=y
-CONFIG_USB_DEBUG=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=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF 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_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
#
# USB Device Class drivers
#
-# CONFIG_USB_BLUETOOTH_TTY is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# 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=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-
-#
-# USB Input Devices
-#
-# CONFIG_USB_HID is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+CONFIG_USB_LIBUSUAL=y
#
# USB Imaging devices
#
+# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_MON is not set
-
-#
# USB port drivers
#
-
-#
-# USB Serial Converter support
-#
# CONFIG_USB_SERIAL is not set
#
@@ -579,55 +942,129 @@
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_IDMOUSE is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
#
-# MMC/SD Card support
+# OTG and related infrastructure
#
-# CONFIG_MMC is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+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 is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_AT91=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# 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_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AT91RM9200=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
#
# File systems
#
CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-# CONFIG_EXT2_FS_POSIX_ACL is not set
-# CONFIG_EXT2_FS_SECURITY is not set
+# 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 is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
-# XFS support
+# Caches
#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
+# CONFIG_FSCACHE is not set
#
# CD-ROM/DVD Filesystems
@@ -639,7 +1076,7 @@
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
+# CONFIG_MSDOS_FS is not set
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
@@ -649,53 +1086,70 @@
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
-CONFIG_DEVPTS_FS_XATTR=y
-# CONFIG_DEVPTS_FS_SECURITY is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_UBIFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+# CONFIG_NILFS2_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFSD is not set
+# CONFIG_NFS_V4 is not set
CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
@@ -719,7 +1173,7 @@
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ASCII=y
+# CONFIG_NLS_ASCII is not set
# CONFIG_NLS_ISO8859_1 is not set
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
@@ -733,47 +1187,119 @@
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
-# CONFIG_MAGIC_SYSRQ is not set
-CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig
index 2d827e1..4762d90 100644
--- a/arch/arm/configs/u300_defconfig
+++ b/arch/arm/configs/u300_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc6
-# Mon Jun 1 09:18:22 2009
+# Linux kernel version: 2.6.31-rc1
+# Thu Jul 2 00:16:59 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -9,7 +9,7 @@
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
+CONFIG_HAVE_TCM=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,13 +18,12 @@
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
#
# General setup
@@ -68,7 +67,6 @@
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -81,8 +79,13 @@
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
# CONFIG_AIO is not set
+
+#
+# Performance Counters
+#
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
@@ -94,6 +97,10 @@
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
@@ -106,7 +113,7 @@
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -138,9 +145,9 @@
# 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_IMX is not set
# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
@@ -216,8 +223,8 @@
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-# CONFIG_OUTER_CACHE is not set
CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
CONFIG_COMMON_CLKDEV=y
#
@@ -243,7 +250,6 @@
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
-CONFIG_ARCH_FLATMEM_HAS_HOLES=y
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
# CONFIG_HIGHMEM is not set
@@ -258,17 +264,18 @@
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
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="root=/dev/mtdblock2 rw rootfstype=yaffs2 console=ttyAMA0,115200n8 ab3100.force=0,0x48 mtdparts=u300nand:128k@0x0(bootrecords)ro,8064k@128k(free)ro,253952k@8192k(platform) lpj=515072"
+CONFIG_CMDLINE="root=/dev/ram0 rw rootfstype=rootfs console=ttyAMA0,115200n8 lpj=515072"
# CONFIG_XIP_KERNEL is not set
# CONFIG_KEXEC is not set
@@ -359,6 +366,7 @@
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -497,6 +505,7 @@
# 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 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -538,6 +547,7 @@
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_LM8323 is not set
# CONFIG_KEYBOARD_GPIO is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
@@ -597,9 +607,11 @@
#
# 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_SIMTEC is not set
+CONFIG_I2C_STU300=y
#
# External I2C/SMBus adapter drivers
@@ -620,7 +632,6 @@
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
@@ -635,6 +646,7 @@
#
# CONFIG_SPI_BITBANG is not set
# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_PL022=y
#
# SPI Protocol Masters
@@ -647,6 +659,7 @@
# CONFIG_PDA_POWER is not set
# CONFIG_BATTERY_DS2760 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_THERMAL_HWMON is not set
@@ -657,6 +670,7 @@
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_COH901327_WATCHDOG=y
CONFIG_SSB_POSSIBLE=y
#
@@ -678,22 +692,9 @@
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+CONFIG_AB3100_CORE=y
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
@@ -760,6 +761,11 @@
# CONFIG_SND_VERBOSE_PROCFS is not set
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# 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_DRIVERS is not set
# CONFIG_SND_ARM is not set
# CONFIG_SND_SPI is not set
@@ -770,7 +776,7 @@
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_MMC=y
-# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_DEBUG=y
# CONFIG_MMC_UNSAFE_RESUME is not set
#
@@ -797,7 +803,7 @@
#
# CONFIG_LEDS_PCA9532 is not set
# CONFIG_LEDS_GPIO is not set
-# CONFIG_LEDS_LP5521 is not set
+# CONFIG_LEDS_LP3944 is not set
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_DAC124S085 is not set
# CONFIG_LEDS_BD2802 is not set
@@ -845,6 +851,7 @@
# 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
@@ -887,7 +894,10 @@
# CONFIG_REGULATOR_DEBUG is not set
# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_LP3971 is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -900,16 +910,20 @@
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
CONFIG_FUSE_FS=y
+# CONFIG_CUSE is not set
#
# Caches
@@ -1033,6 +1047,7 @@
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
@@ -1063,18 +1078,16 @@
# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
@@ -1109,6 +1122,7 @@
# CONFIG_CRC32 is not set
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_ALLOCATOR=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 1cd2d64..c433c6c 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -285,15 +285,6 @@
#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
#define pte_special(pte) (0)
-/*
- * The following only works if pte_present() is not true.
- */
-#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
-#define pte_to_pgoff(x) (pte_val(x) >> 2)
-#define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE)
-
-#define PTE_FILE_MAX_BITS 30
-
#define PTE_BIT_FUNC(fn,op) \
static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
@@ -384,16 +375,50 @@
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-/* Encode and decode a swap entry.
+/*
+ * Encode and decode a swap entry. Swap entries are stored in the Linux
+ * page tables as follows:
*
- * We support up to 32GB of swap on 4k machines
+ * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * <--------------- offset --------------------> <--- type --> 0 0
+ *
+ * This gives us up to 127 swap files and 32GB per swap file. Note that
+ * the offset field is always non-zero.
*/
-#define __swp_type(x) (((x).val >> 2) & 0x7f)
-#define __swp_offset(x) ((x).val >> 9)
-#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) })
+#define __SWP_TYPE_SHIFT 2
+#define __SWP_TYPE_BITS 7
+#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
+#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
+
+#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
+#define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT)
+#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) })
+
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
+/*
+ * It is an error for the kernel to have more swap files than we can
+ * encode in the PTEs. This ensures that we know when MAX_SWAPFILES
+ * is increased beyond what we presently support.
+ */
+#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
+
+/*
+ * Encode and decode a file entry. File entries are stored in the Linux
+ * page tables as follows:
+ *
+ * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * <------------------------ offset -------------------------> 1 0
+ */
+#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
+#define pte_to_pgoff(x) (pte_val(x) >> 2)
+#define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE)
+
+#define PTE_FILE_MAX_BITS 30
+
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
/* FIXME: this is not correct */
#define kern_addr_valid(addr) (1)
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 4f88482..73394e5 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -73,7 +73,7 @@
.task = &tsk, \
.exec_domain = &default_exec_domain, \
.flags = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c
index 5cd04d6..111f7ea 100644
--- a/arch/arm/mach-u300/clock.c
+++ b/arch/arm/mach-u300/clock.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/io.h>
+#include <linux/seq_file.h>
#include <asm/clkdev.h>
#include <mach/hardware.h>
@@ -702,6 +703,7 @@
.rate = 52000000, /* this varies! */
.hw_ctrld = true,
.reset = false,
+ .lock = __SPIN_LOCK_UNLOCKED(amba_clk.lock),
};
/*
@@ -720,6 +722,7 @@
.set_rate = clk_set_rate_cpuclk,
.get_rate = clk_get_rate_cpuclk,
.round_rate = clk_round_rate_cpuclk,
+ .lock = __SPIN_LOCK_UNLOCKED(cpu_clk.lock),
};
static struct clk nandif_clk = {
@@ -732,6 +735,7 @@
.clk_val = U300_SYSCON_SBCER_NANDIF_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(nandif_clk.lock),
};
static struct clk semi_clk = {
@@ -744,6 +748,7 @@
.clk_val = U300_SYSCON_SBCER_SEMI_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(semi_clk.lock),
};
#ifdef CONFIG_MACH_U300_BS335
@@ -758,6 +763,7 @@
.clk_val = U300_SYSCON_SBCER_ISP_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(isp_clk.lock),
};
static struct clk cds_clk = {
@@ -771,6 +777,7 @@
.clk_val = U300_SYSCON_SBCER_CDS_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(cds_clk.lock),
};
#endif
@@ -785,6 +792,7 @@
.clk_val = U300_SYSCON_SBCER_DMAC_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(dma_clk.lock),
};
static struct clk aaif_clk = {
@@ -798,6 +806,7 @@
.clk_val = U300_SYSCON_SBCER_AAIF_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(aaif_clk.lock),
};
static struct clk apex_clk = {
@@ -811,6 +820,7 @@
.clk_val = U300_SYSCON_SBCER_APEX_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(apex_clk.lock),
};
static struct clk video_enc_clk = {
@@ -825,6 +835,7 @@
.clk_val = U300_SYSCON_SBCER_VIDEO_ENC_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(video_enc_clk.lock),
};
static struct clk xgam_clk = {
@@ -839,6 +850,7 @@
.get_rate = clk_get_rate_xgamclk,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(xgam_clk.lock),
};
/* This clock is used to activate the video encoder */
@@ -854,6 +866,7 @@
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
.get_rate = clk_get_rate_ahb_clk,
+ .lock = __SPIN_LOCK_UNLOCKED(ahb_clk.lock),
};
@@ -871,6 +884,7 @@
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
.get_rate = clk_get_rate_ahb_clk,
+ .lock = __SPIN_LOCK_UNLOCKED(ahb_subsys_clk.lock),
};
static struct clk intcon_clk = {
@@ -882,6 +896,8 @@
.res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
.res_mask = U300_SYSCON_RRR_INTCON_RESET_EN,
/* INTCON can be reset but not clock-gated */
+ .lock = __SPIN_LOCK_UNLOCKED(intcon_clk.lock),
+
};
static struct clk mspro_clk = {
@@ -895,6 +911,7 @@
.clk_val = U300_SYSCON_SBCER_MSPRO_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(mspro_clk.lock),
};
static struct clk emif_clk = {
@@ -909,6 +926,7 @@
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
.get_rate = clk_get_rate_emif_clk,
+ .lock = __SPIN_LOCK_UNLOCKED(emif_clk.lock),
};
@@ -926,6 +944,7 @@
.clk_val = U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(fast_clk.lock),
};
static struct clk mmcsd_clk = {
@@ -942,6 +961,7 @@
.round_rate = clk_round_rate_mclk,
.disable = syscon_clk_disable,
.enable = syscon_clk_enable,
+ .lock = __SPIN_LOCK_UNLOCKED(mmcsd_clk.lock),
};
static struct clk i2s0_clk = {
@@ -956,6 +976,7 @@
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
.get_rate = clk_get_rate_i2s_i2c_spi,
+ .lock = __SPIN_LOCK_UNLOCKED(i2s0_clk.lock),
};
static struct clk i2s1_clk = {
@@ -970,6 +991,7 @@
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
.get_rate = clk_get_rate_i2s_i2c_spi,
+ .lock = __SPIN_LOCK_UNLOCKED(i2s1_clk.lock),
};
static struct clk i2c0_clk = {
@@ -984,6 +1006,7 @@
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
.get_rate = clk_get_rate_i2s_i2c_spi,
+ .lock = __SPIN_LOCK_UNLOCKED(i2c0_clk.lock),
};
static struct clk i2c1_clk = {
@@ -998,6 +1021,7 @@
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
.get_rate = clk_get_rate_i2s_i2c_spi,
+ .lock = __SPIN_LOCK_UNLOCKED(i2c1_clk.lock),
};
static struct clk spi_clk = {
@@ -1012,6 +1036,7 @@
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
.get_rate = clk_get_rate_i2s_i2c_spi,
+ .lock = __SPIN_LOCK_UNLOCKED(spi_clk.lock),
};
#ifdef CONFIG_MACH_U300_BS335
@@ -1026,6 +1051,7 @@
.clk_val = U300_SYSCON_SBCER_UART1_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(uart1_clk.lock),
};
#endif
@@ -1044,6 +1070,7 @@
.clk_val = U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(slow_clk.lock),
};
/* TODO: implement SYSCON clock? */
@@ -1055,6 +1082,7 @@
.rate = 32768,
.reset = false,
/* This is always on, cannot be enabled/disabled or reset */
+ .lock = __SPIN_LOCK_UNLOCKED(wdog_clk.lock),
};
/* This one is hardwired to PLL13 */
@@ -1069,6 +1097,7 @@
.clk_val = U300_SYSCON_SBCER_UART_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(uart_clk.lock),
};
static struct clk keypad_clk = {
@@ -1082,6 +1111,7 @@
.clk_val = U300_SYSCON_SBCER_KEYPAD_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(keypad_clk.lock),
};
static struct clk gpio_clk = {
@@ -1095,6 +1125,7 @@
.clk_val = U300_SYSCON_SBCER_GPIO_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(gpio_clk.lock),
};
static struct clk rtc_clk = {
@@ -1106,6 +1137,7 @@
.res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
.res_mask = U300_SYSCON_RSR_RTC_RESET_EN,
/* This clock is always on, cannot be enabled/disabled */
+ .lock = __SPIN_LOCK_UNLOCKED(rtc_clk.lock),
};
static struct clk bustr_clk = {
@@ -1119,6 +1151,7 @@
.clk_val = U300_SYSCON_SBCER_BTR_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(bustr_clk.lock),
};
static struct clk evhist_clk = {
@@ -1132,6 +1165,7 @@
.clk_val = U300_SYSCON_SBCER_EH_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(evhist_clk.lock),
};
static struct clk timer_clk = {
@@ -1145,6 +1179,7 @@
.clk_val = U300_SYSCON_SBCER_ACC_TMR_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(timer_clk.lock),
};
static struct clk app_timer_clk = {
@@ -1158,6 +1193,7 @@
.clk_val = U300_SYSCON_SBCER_APP_TMR_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(app_timer_clk.lock),
};
#ifdef CONFIG_MACH_U300_BS335
@@ -1172,6 +1208,7 @@
.clk_val = U300_SYSCON_SBCER_PPM_CLK_EN,
.enable = syscon_clk_enable,
.disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(ppm_clk.lock),
};
#endif
@@ -1187,53 +1224,53 @@
*/
static struct clk_lookup lookups[] = {
/* Connected directly to the AMBA bus */
- DEF_LOOKUP("amba", &amba_clk),
- DEF_LOOKUP("cpu", &cpu_clk),
- DEF_LOOKUP("nandif", &nandif_clk),
- DEF_LOOKUP("semi", &semi_clk),
+ DEF_LOOKUP("amba", &amba_clk),
+ DEF_LOOKUP("cpu", &cpu_clk),
+ DEF_LOOKUP("fsmc", &nandif_clk),
+ DEF_LOOKUP("semi", &semi_clk),
#ifdef CONFIG_MACH_U300_BS335
- DEF_LOOKUP("isp", &isp_clk),
- DEF_LOOKUP("cds", &cds_clk),
+ DEF_LOOKUP("isp", &isp_clk),
+ DEF_LOOKUP("cds", &cds_clk),
#endif
- DEF_LOOKUP("dma", &dma_clk),
- DEF_LOOKUP("aaif", &aaif_clk),
- DEF_LOOKUP("apex", &apex_clk),
+ DEF_LOOKUP("dma", &dma_clk),
+ DEF_LOOKUP("msl", &aaif_clk),
+ DEF_LOOKUP("apex", &apex_clk),
DEF_LOOKUP("video_enc", &video_enc_clk),
- DEF_LOOKUP("xgam", &xgam_clk),
- DEF_LOOKUP("ahb", &ahb_clk),
+ DEF_LOOKUP("xgam", &xgam_clk),
+ DEF_LOOKUP("ahb", &ahb_clk),
/* AHB bridge clocks */
- DEF_LOOKUP("ahb", &ahb_subsys_clk),
- DEF_LOOKUP("intcon", &intcon_clk),
- DEF_LOOKUP("mspro", &mspro_clk),
- DEF_LOOKUP("pl172", &emif_clk),
+ DEF_LOOKUP("ahb_subsys", &ahb_subsys_clk),
+ DEF_LOOKUP("intcon", &intcon_clk),
+ DEF_LOOKUP("mspro", &mspro_clk),
+ DEF_LOOKUP("pl172", &emif_clk),
/* FAST bridge clocks */
- DEF_LOOKUP("fast", &fast_clk),
- DEF_LOOKUP("mmci", &mmcsd_clk),
+ DEF_LOOKUP("fast", &fast_clk),
+ DEF_LOOKUP("mmci", &mmcsd_clk),
/*
* The .0 and .1 identifiers on these comes from the platform device
* .id field and are assigned when the platform devices are registered.
*/
- DEF_LOOKUP("i2s.0", &i2s0_clk),
- DEF_LOOKUP("i2s.1", &i2s1_clk),
- DEF_LOOKUP("stddci2c.0", &i2c0_clk),
- DEF_LOOKUP("stddci2c.1", &i2c1_clk),
- DEF_LOOKUP("pl022", &spi_clk),
+ DEF_LOOKUP("i2s.0", &i2s0_clk),
+ DEF_LOOKUP("i2s.1", &i2s1_clk),
+ DEF_LOOKUP("stu300.0", &i2c0_clk),
+ DEF_LOOKUP("stu300.1", &i2c1_clk),
+ DEF_LOOKUP("pl022", &spi_clk),
#ifdef CONFIG_MACH_U300_BS335
- DEF_LOOKUP("uart1", &uart1_clk),
+ DEF_LOOKUP("uart1", &uart1_clk),
#endif
/* SLOW bridge clocks */
- DEF_LOOKUP("slow", &slow_clk),
- DEF_LOOKUP("wdog", &wdog_clk),
- DEF_LOOKUP("uart0", &uart_clk),
- DEF_LOOKUP("apptimer", &app_timer_clk),
- DEF_LOOKUP("keypad", &keypad_clk),
+ DEF_LOOKUP("slow", &slow_clk),
+ DEF_LOOKUP("coh901327_wdog", &wdog_clk),
+ DEF_LOOKUP("uart0", &uart_clk),
+ DEF_LOOKUP("apptimer", &app_timer_clk),
+ DEF_LOOKUP("coh901461-keypad", &keypad_clk),
DEF_LOOKUP("u300-gpio", &gpio_clk),
- DEF_LOOKUP("rtc0", &rtc_clk),
- DEF_LOOKUP("bustr", &bustr_clk),
- DEF_LOOKUP("evhist", &evhist_clk),
- DEF_LOOKUP("timer", &timer_clk),
+ DEF_LOOKUP("rtc-coh901331", &rtc_clk),
+ DEF_LOOKUP("bustr", &bustr_clk),
+ DEF_LOOKUP("evhist", &evhist_clk),
+ DEF_LOOKUP("timer", &timer_clk),
#ifdef CONFIG_MACH_U300_BS335
- DEF_LOOKUP("ppm", &ppm_clk),
+ DEF_LOOKUP("ppm", &ppm_clk),
#endif
};
@@ -1427,16 +1464,20 @@
.release = single_release,
};
-static void init_clk_read_procfs(void)
+static int __init init_clk_read_debugfs(void)
{
/* Expose a simple debugfs interface to view all clocks */
(void) debugfs_create_file("u300_clocks", S_IFREG | S_IRUGO,
- NULL, NULL, &u300_clocks_operations);
+ NULL, NULL,
+ &u300_clocks_operations);
+ return 0;
}
-#else
-static inline void init_clk_read_procfs(void)
-{
-}
+/*
+ * This needs to come in after the core_initcall() for the
+ * overall clocks, because debugfs is not available until
+ * the subsystems come up.
+ */
+module_init(init_clk_read_debugfs);
#endif
static int __init u300_clock_init(void)
@@ -1462,8 +1503,6 @@
clk_register();
- init_clk_read_procfs();
-
/*
* Some of these may be on when we boot the system so make sure they
* are turned OFF.
diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c
index 195e48e..ac5c800 100644
--- a/arch/arm/mm/proc-syms.c
+++ b/arch/arm/mm/proc-syms.c
@@ -27,6 +27,7 @@
EXPORT_SYMBOL(__cpuc_flush_user_all);
EXPORT_SYMBOL(__cpuc_flush_user_range);
EXPORT_SYMBOL(__cpuc_coherent_kern_range);
+EXPORT_SYMBOL(__cpuc_flush_dcache_page);
EXPORT_SYMBOL(dmac_inv_range); /* because of flush_ioremap_region() */
#else
EXPORT_SYMBOL(cpu_cache);
diff --git a/arch/avr32/include/asm/thread_info.h b/arch/avr32/include/asm/thread_info.h
index 4442f8d..fc42de5 100644
--- a/arch/avr32/include/asm/thread_info.h
+++ b/arch/avr32/include/asm/thread_info.h
@@ -40,7 +40,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall \
} \
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c
index 6e3d491..b91b204 100644
--- a/arch/avr32/kernel/traps.c
+++ b/arch/avr32/kernel/traps.c
@@ -32,22 +32,25 @@
spin_lock_irq(&die_lock);
bust_spinlocks(1);
- printk(KERN_ALERT "Oops: %s, sig: %ld [#%d]\n" KERN_EMERG,
+ printk(KERN_ALERT "Oops: %s, sig: %ld [#%d]\n",
str, err, ++die_counter);
+
+ printk(KERN_EMERG);
+
#ifdef CONFIG_PREEMPT
- printk("PREEMPT ");
+ printk(KERN_CONT "PREEMPT ");
#endif
#ifdef CONFIG_FRAME_POINTER
- printk("FRAME_POINTER ");
+ printk(KERN_CONT "FRAME_POINTER ");
#endif
if (current_cpu_data.features & AVR32_FEATURE_OCD) {
unsigned long did = ocd_read(DID);
- printk("chip: 0x%03lx:0x%04lx rev %lu\n",
+ printk(KERN_CONT "chip: 0x%03lx:0x%04lx rev %lu\n",
(did >> 1) & 0x7ff,
(did >> 12) & 0x7fff,
(did >> 28) & 0xf);
} else {
- printk("cpu: arch %u r%u / core %u r%u\n",
+ printk(KERN_CONT "cpu: arch %u r%u / core %u r%u\n",
current_cpu_data.arch_type,
current_cpu_data.arch_revision,
current_cpu_data.cpu_type,
diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h
index 2920087..2bbfdd9 100644
--- a/arch/blackfin/include/asm/thread_info.h
+++ b/arch/blackfin/include/asm/thread_info.h
@@ -77,7 +77,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 298f023..6136c33 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -408,13 +408,14 @@
bfin_memmap.map[i].addr + bfin_memmap.map[i].size);
switch (bfin_memmap.map[i].type) {
case BFIN_MEMMAP_RAM:
- printk("(usable)\n");
- break;
+ printk(KERN_CONT "(usable)\n");
+ break;
case BFIN_MEMMAP_RESERVED:
- printk("(reserved)\n");
- break;
- default: printk("type %lu\n", bfin_memmap.map[i].type);
- break;
+ printk(KERN_CONT "(reserved)\n");
+ break;
+ default:
+ printk(KERN_CONT "type %lu\n", bfin_memmap.map[i].type);
+ break;
}
}
}
@@ -614,19 +615,19 @@
printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20);
printk(KERN_INFO "Memory map:\n"
- KERN_INFO " fixedcode = 0x%p-0x%p\n"
- KERN_INFO " text = 0x%p-0x%p\n"
- KERN_INFO " rodata = 0x%p-0x%p\n"
- KERN_INFO " bss = 0x%p-0x%p\n"
- KERN_INFO " data = 0x%p-0x%p\n"
- KERN_INFO " stack = 0x%p-0x%p\n"
- KERN_INFO " init = 0x%p-0x%p\n"
- KERN_INFO " available = 0x%p-0x%p\n"
+ " fixedcode = 0x%p-0x%p\n"
+ " text = 0x%p-0x%p\n"
+ " rodata = 0x%p-0x%p\n"
+ " bss = 0x%p-0x%p\n"
+ " data = 0x%p-0x%p\n"
+ " stack = 0x%p-0x%p\n"
+ " init = 0x%p-0x%p\n"
+ " available = 0x%p-0x%p\n"
#ifdef CONFIG_MTD_UCLINUX
- KERN_INFO " rootfs = 0x%p-0x%p\n"
+ " rootfs = 0x%p-0x%p\n"
#endif
#if DMA_UNCACHED_REGION > 0
- KERN_INFO " DMA Zone = 0x%p-0x%p\n"
+ " DMA Zone = 0x%p-0x%p\n"
#endif
, (void *)FIXED_CODE_START, (void *)FIXED_CODE_END,
_stext, _etext,
@@ -859,13 +860,13 @@
#endif
printk(KERN_INFO "Hardware Trace ");
if (bfin_read_TBUFCTL() & 0x1)
- printk("Active ");
+ printk(KERN_CONT "Active ");
else
- printk("Off ");
+ printk(KERN_CONT "Off ");
if (bfin_read_TBUFCTL() & 0x2)
- printk("and Enabled\n");
+ printk(KERN_CONT "and Enabled\n");
else
- printk("and Disabled\n");
+ printk(KERN_CONT "and Disabled\n");
#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
/* we need to initialize the Flashrom device here since we might
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 8eeb457..8a1caf2 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -212,7 +212,7 @@
console_verbose();
oops_in_progress = 1;
#ifdef CONFIG_DEBUG_VERBOSE
- printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n");
+ printk(KERN_EMERG "Double Fault\n");
#ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT
if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) {
unsigned int cpu = smp_processor_id();
@@ -583,15 +583,14 @@
#ifndef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE
if (trapnr == VEC_CPLB_I_M || trapnr == VEC_CPLB_M)
verbose_printk(KERN_NOTICE "No trace since you do not have "
- "CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE enabled\n"
- KERN_NOTICE "\n");
+ "CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE enabled\n\n");
else
#endif
dump_bfin_trace_buffer();
if (oops_in_progress) {
/* Dump the current kernel stack */
- verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "Kernel Stack\n");
+ verbose_printk(KERN_NOTICE "Kernel Stack\n");
show_stack(current, NULL);
print_modules();
#ifndef CONFIG_ACCESS_CHECK
@@ -906,7 +905,7 @@
ret_addr = 0;
if (!j && i % 8 == 0)
- printk("\n" KERN_NOTICE "%p:",addr);
+ printk(KERN_NOTICE "%p:",addr);
/* if it is an odd address, or zero, just skip it */
if (*addr & 0x1 || !*addr)
@@ -996,9 +995,9 @@
printk(KERN_NOTICE "CPU = %d\n", current_thread_info()->cpu);
if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START)
- verbose_printk(KERN_NOTICE "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n"
- KERN_NOTICE " BSS = 0x%p-0x%p USER-STACK = 0x%p\n"
- KERN_NOTICE "\n",
+ verbose_printk(KERN_NOTICE
+ "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n"
+ " BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n",
(void *)current->mm->start_code,
(void *)current->mm->end_code,
(void *)current->mm->start_data,
@@ -1009,8 +1008,8 @@
else
verbose_printk(KERN_NOTICE "invalid mm\n");
} else
- verbose_printk(KERN_NOTICE "\n" KERN_NOTICE
- "No Valid process in current context\n");
+ verbose_printk(KERN_NOTICE
+ "No Valid process in current context\n");
#endif
}
@@ -1028,7 +1027,7 @@
addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10;
addr++) {
if (!((unsigned long)addr & 0xF))
- verbose_printk("\n" KERN_NOTICE "0x%p: ", addr);
+ verbose_printk(KERN_NOTICE "0x%p: ", addr);
if (!get_instruction(&val, addr)) {
val = 0;
@@ -1056,9 +1055,9 @@
oops_in_progress)){
verbose_printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n");
#ifndef CONFIG_DEBUG_HWERR
- verbose_printk(KERN_NOTICE "The remaining message may be meaningless\n"
- KERN_NOTICE "You should enable CONFIG_DEBUG_HWERR to get a"
- " better idea where it came from\n");
+ verbose_printk(KERN_NOTICE
+"The remaining message may be meaningless\n"
+"You should enable CONFIG_DEBUG_HWERR to get a better idea where it came from\n");
#else
/* If we are handling only one peripheral interrupt
* and current mm and pid are valid, and the last error
@@ -1114,9 +1113,10 @@
verbose_printk(KERN_NOTICE "%s", linux_banner);
- verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted());
+ verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n",
+ print_tainted());
verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n",
- (long)fp->seqstat, fp->ipend, fp->syscfg);
+ (long)fp->seqstat, fp->ipend, fp->syscfg);
if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) {
verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n",
(fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);
@@ -1184,7 +1184,7 @@
verbose_printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf);
}
- verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "PROCESSOR STATE:\n");
+ verbose_printk(KERN_NOTICE "PROCESSOR STATE:\n");
verbose_printk(KERN_NOTICE " R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n",
fp->r0, fp->r1, fp->r2, fp->r3);
verbose_printk(KERN_NOTICE " R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n",
diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h
index bc5b293..c3aade3 100644
--- a/arch/cris/include/asm/thread_info.h
+++ b/arch/cris/include/asm/thread_info.h
@@ -50,8 +50,6 @@
/*
* macros/functions for gaining access to the thread information structure
- *
- * preempt_count needs to be 1 initially, until the scheduler is functional.
*/
#ifndef __ASSEMBLY__
#define INIT_THREAD_INFO(tsk) \
@@ -60,7 +58,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.restart_block = { \
.fn = do_no_restart_syscall, \
diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h
index e8a5ed7..e608e05 100644
--- a/arch/frv/include/asm/thread_info.h
+++ b/arch/frv/include/asm/thread_info.h
@@ -56,8 +56,6 @@
/*
* macros/functions for gaining access to the thread information structure
- *
- * preempt_count needs to be 1 initially, until the scheduler is functional.
*/
#ifndef __ASSEMBLY__
@@ -67,7 +65,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.restart_block = { \
.fn = do_no_restart_syscall, \
diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
index 700014d..8bbc8b0 100644
--- a/arch/h8300/include/asm/thread_info.h
+++ b/arch/h8300/include/asm/thread_info.h
@@ -36,7 +36,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h
index ae69226..8ce2e38 100644
--- a/arch/ia64/include/asm/thread_info.h
+++ b/arch/ia64/include/asm/thread_info.h
@@ -48,7 +48,7 @@
.flags = 0, \
.cpu = 0, \
.addr_limit = KERNEL_DS, \
- .preempt_count = 0, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 729298f..7de76dd 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -537,7 +537,7 @@
/*
* PCI BIOS setup, always defaults to SAL interface
*/
-char * __devinit
+char * __init
pcibios_setup (char *str)
{
return str;
diff --git a/arch/m32r/include/asm/thread_info.h b/arch/m32r/include/asm/thread_info.h
index 8589d46..07bb5bd 100644
--- a/arch/m32r/include/asm/thread_info.h
+++ b/arch/m32r/include/asm/thread_info.h
@@ -57,8 +57,6 @@
/*
* macros/functions for gaining access to the thread information structure
- *
- * preempt_count needs to be 1 initially, until the scheduler is functional.
*/
#ifndef __ASSEMBLY__
@@ -68,7 +66,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.restart_block = { \
.fn = do_no_restart_syscall, \
diff --git a/arch/m68k/include/asm/thread_info_mm.h b/arch/m68k/include/asm/thread_info_mm.h
index af0fda4..6ea5c33 100644
--- a/arch/m68k/include/asm/thread_info_mm.h
+++ b/arch/m68k/include/asm/thread_info_mm.h
@@ -19,6 +19,7 @@
{ \
.task = &tsk, \
.exec_domain = &default_exec_domain, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
diff --git a/arch/m68k/include/asm/thread_info_no.h b/arch/m68k/include/asm/thread_info_no.h
index 82529f4..c2bde5e 100644
--- a/arch/m68k/include/asm/thread_info_no.h
+++ b/arch/m68k/include/asm/thread_info_no.h
@@ -49,6 +49,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index 1e96c6e..8f8f4ab 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -290,7 +290,7 @@
unsigned char *tp;
int i;
- printk(KERN_EMERG "\n" KERN_EMERG "CURRENT PROCESS:\n" KERN_EMERG "\n");
+ printk(KERN_EMERG "\nCURRENT PROCESS:\n\n");
printk(KERN_EMERG "COMM=%s PID=%d\n", current->comm, current->pid);
if (current->mm) {
@@ -301,8 +301,7 @@
(int) current->mm->end_data,
(int) current->mm->end_data,
(int) current->mm->brk);
- printk(KERN_EMERG "USER-STACK=%08x KERNEL-STACK=%08x\n"
- KERN_EMERG "\n",
+ printk(KERN_EMERG "USER-STACK=%08x KERNEL-STACK=%08x\n\n",
(int) current->mm->start_stack,
(int)(((unsigned long) current) + THREAD_SIZE));
}
@@ -313,35 +312,35 @@
fp->d0, fp->d1, fp->d2, fp->d3);
printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
fp->d4, fp->d5, fp->a0, fp->a1);
- printk(KERN_EMERG "\n" KERN_EMERG "USP: %08x TRAPFRAME: %08x\n",
+ printk(KERN_EMERG "\nUSP: %08x TRAPFRAME: %08x\n",
(unsigned int) rdusp(), (unsigned int) fp);
- printk(KERN_EMERG "\n" KERN_EMERG "CODE:");
+ printk(KERN_EMERG "\nCODE:");
tp = ((unsigned char *) fp->pc) - 0x20;
for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) {
if ((i % 0x10) == 0)
- printk("\n" KERN_EMERG "%08x: ", (int) (tp + i));
+ printk(KERN_EMERG "%08x: ", (int) (tp + i));
printk("%08x ", (int) *sp++);
}
- printk("\n" KERN_EMERG "\n");
+ printk(KERN_EMERG "\n");
printk(KERN_EMERG "KERNEL STACK:");
tp = ((unsigned char *) fp) - 0x40;
for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
if ((i % 0x10) == 0)
- printk("\n" KERN_EMERG "%08x: ", (int) (tp + i));
+ printk(KERN_EMERG "%08x: ", (int) (tp + i));
printk("%08x ", (int) *sp++);
}
- printk("\n" KERN_EMERG "\n");
+ printk(KERN_EMERG "\n");
printk(KERN_EMERG "USER STACK:");
tp = (unsigned char *) (rdusp() - 0x10);
for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
if ((i % 0x10) == 0)
- printk("\n" KERN_EMERG "%08x: ", (int) (tp + i));
+ printk(KERN_EMERG "%08x: ", (int) (tp + i));
printk("%08x ", (int) *sp++);
}
- printk("\n" KERN_EMERG "\n");
+ printk(KERN_EMERG "\n");
}
/*
diff --git a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c
index 51d3253..3739c8f 100644
--- a/arch/m68knommu/kernel/traps.c
+++ b/arch/m68knommu/kernel/traps.c
@@ -111,7 +111,7 @@
if (i % 5)
printk(KERN_CONT " [%08lx] ", addr);
else
- printk(KERN_CONT "\n" KERN_EMERG " [%08lx] ", addr);
+ printk(KERN_EMERG " [%08lx] ", addr);
i++;
#endif
}
@@ -137,8 +137,8 @@
if (stack + 1 + i > endstack)
break;
if (i % 8 == 0)
- printk("\n" KERN_EMERG " ");
- printk(" %08lx", *(stack + i));
+ printk(KERN_EMERG " ");
+ printk(KERN_CONT " %08lx", *(stack + i));
}
printk("\n");
i = 0;
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index b50b845..2db722d 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -53,6 +53,9 @@
config GENERIC_GPIO
def_bool y
+config GENERIC_CSUM
+ def_bool y
+
config PCI
def_bool n
diff --git a/arch/microblaze/include/asm/atomic.h b/arch/microblaze/include/asm/atomic.h
index 0de612a..6d2e1d4 100644
--- a/arch/microblaze/include/asm/atomic.h
+++ b/arch/microblaze/include/asm/atomic.h
@@ -1,95 +1,7 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
#ifndef _ASM_MICROBLAZE_ATOMIC_H
#define _ASM_MICROBLAZE_ATOMIC_H
-#include <linux/types.h>
-#include <linux/compiler.h> /* likely */
-#include <asm/system.h> /* local_irq_XXX and friends */
-
-#define ATOMIC_INIT(i) { (i) }
-#define atomic_read(v) ((v)->counter)
-#define atomic_set(v, i) (((v)->counter) = (i))
-
-#define atomic_inc(v) (atomic_add_return(1, (v)))
-#define atomic_dec(v) (atomic_sub_return(1, (v)))
-
-#define atomic_add(i, v) (atomic_add_return(i, (v)))
-#define atomic_sub(i, v) (atomic_sub_return(i, (v)))
-
-#define atomic_inc_return(v) (atomic_add_return(1, (v)))
-#define atomic_dec_return(v) (atomic_sub_return(1, (v)))
-
-#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0)
-#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
-
-#define atomic_inc_not_zero(v) (atomic_add_unless((v), 1, 0))
-
-#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
-
-static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
-{
- int ret;
- unsigned long flags;
-
- local_irq_save(flags);
- ret = v->counter;
- if (likely(ret == old))
- v->counter = new;
- local_irq_restore(flags);
-
- return ret;
-}
-
-static inline int atomic_add_unless(atomic_t *v, int a, int u)
-{
- int c, old;
-
- c = atomic_read(v);
- while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
- c = old;
- return c != u;
-}
-
-static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
-{
- unsigned long flags;
-
- local_irq_save(flags);
- *addr &= ~mask;
- local_irq_restore(flags);
-}
-
-/**
- * atomic_add_return - add and return
- * @i: integer value to add
- * @v: pointer of type atomic_t
- *
- * Atomically adds @i to @v and returns @i + @v
- */
-static inline int atomic_add_return(int i, atomic_t *v)
-{
- unsigned long flags;
- int val;
-
- local_irq_save(flags);
- val = v->counter;
- v->counter = val += i;
- local_irq_restore(flags);
-
- return val;
-}
-
-static inline int atomic_sub_return(int i, atomic_t *v)
-{
- return atomic_add_return(-i, v);
-}
+#include <asm-generic/atomic.h>
/*
* Atomically test *v and decrement if it is greater than 0.
@@ -109,15 +21,4 @@
return res;
}
-#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-
-/* Atomic operations are already serializing */
-#define smp_mb__before_atomic_dec() barrier()
-#define smp_mb__after_atomic_dec() barrier()
-#define smp_mb__before_atomic_inc() barrier()
-#define smp_mb__after_atomic_inc() barrier()
-
-#include <asm-generic/atomic-long.h>
-
#endif /* _ASM_MICROBLAZE_ATOMIC_H */
diff --git a/arch/microblaze/include/asm/bitops.h b/arch/microblaze/include/asm/bitops.h
index d6df1fd..a72468f 100644
--- a/arch/microblaze/include/asm/bitops.h
+++ b/arch/microblaze/include/asm/bitops.h
@@ -1,27 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_BITOPS_H
-#define _ASM_MICROBLAZE_BITOPS_H
-
-/*
- * Copyright 1992, Linus Torvalds.
- */
-
-#include <asm/byteorder.h> /* swab32 */
-#include <asm/system.h> /* save_flags */
-
-/*
- * clear_bit() doesn't provide any barrier for the compiler.
- */
-#define smp_mb__before_clear_bit() barrier()
-#define smp_mb__after_clear_bit() barrier()
#include <asm-generic/bitops.h>
-#include <asm-generic/bitops/__fls.h>
-
-#endif /* _ASM_MICROBLAZE_BITOPS_H */
diff --git a/arch/microblaze/include/asm/bug.h b/arch/microblaze/include/asm/bug.h
index 8eb2cdd..b12fd89 100644
--- a/arch/microblaze/include/asm/bug.h
+++ b/arch/microblaze/include/asm/bug.h
@@ -1,15 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_BUG_H
-#define _ASM_MICROBLAZE_BUG_H
-
-#include <linux/kernel.h>
#include <asm-generic/bug.h>
-
-#endif /* _ASM_MICROBLAZE_BUG_H */
diff --git a/arch/microblaze/include/asm/bugs.h b/arch/microblaze/include/asm/bugs.h
index f2c6593..61791e1 100644
--- a/arch/microblaze/include/asm/bugs.h
+++ b/arch/microblaze/include/asm/bugs.h
@@ -1,17 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_BUGS_H
-#define _ASM_MICROBLAZE_BUGS_H
-
-static inline void check_bugs(void)
-{
- /* nothing to do */
-}
-
-#endif /* _ASM_MICROBLAZE_BUGS_H */
+#include <asm-generic/bugs.h>
diff --git a/arch/microblaze/include/asm/checksum.h b/arch/microblaze/include/asm/checksum.h
index 97ea46b..128bf03 100644
--- a/arch/microblaze/include/asm/checksum.h
+++ b/arch/microblaze/include/asm/checksum.h
@@ -10,12 +10,11 @@
#ifndef _ASM_MICROBLAZE_CHECKSUM_H
#define _ASM_MICROBLAZE_CHECKSUM_H
-#include <linux/in6.h>
-
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
+#define csum_tcpudp_nofold csum_tcpudp_nofold
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
@@ -30,71 +29,6 @@
return sum;
}
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-extern __wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- * the same as csum_partial, but copies from src while it
- * checksums
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-extern __wsum csum_partial_copy(const void *src, void *dst, int len,
- __wsum sum);
-
-/*
- * the same as csum_partial_copy, but copies from user space.
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
- int len, __wsum sum, int *csum_err);
-
-#define csum_partial_copy_nocheck(src, dst, len, sum) \
- csum_partial_copy((src), (dst), (len), (sum))
-
-/*
- * This is a version of ip_compute_csum() optimized for IP headers,
- * which always checksum on 4 octet boundaries.
- *
- */
-extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
-
-/*
- * Fold a partial checksum
- */
-static inline __sum16 csum_fold(__wsum csum)
-{
- u32 sum = (__force u32)csum;
- sum = (sum & 0xffff) + (sum >> 16);
- sum = (sum & 0xffff) + (sum >> 16);
- return (__force __sum16)~sum;
-}
-
-static inline __sum16
-csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
- unsigned short proto, __wsum sum)
-{
- return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-extern __sum16 ip_compute_csum(const void *buff, int len);
+#include <asm-generic/checksum.h>
#endif /* _ASM_MICROBLAZE_CHECKSUM_H */
diff --git a/arch/microblaze/include/asm/fb.h b/arch/microblaze/include/asm/fb.h
new file mode 100644
index 0000000..3a4988e
--- /dev/null
+++ b/arch/microblaze/include/asm/fb.h
@@ -0,0 +1 @@
+#include <asm-generic/fb.h>
diff --git a/arch/microblaze/include/asm/hardirq.h b/arch/microblaze/include/asm/hardirq.h
index 0f2d6b0..41e1e1a 100644
--- a/arch/microblaze/include/asm/hardirq.h
+++ b/arch/microblaze/include/asm/hardirq.h
@@ -9,21 +9,11 @@
#ifndef _ASM_MICROBLAZE_HARDIRQ_H
#define _ASM_MICROBLAZE_HARDIRQ_H
-#include <linux/cache.h>
-#include <linux/irq.h>
-#include <asm/irq.h>
-#include <asm/current.h>
-#include <linux/ptrace.h>
-
/* should be defined in each interrupt controller driver */
extern unsigned int get_irq(struct pt_regs *regs);
-typedef struct {
- unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
+#define ack_bad_irq ack_bad_irq
void ack_bad_irq(unsigned int irq);
-
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+#include <asm-generic/hardirq.h>
#endif /* _ASM_MICROBLAZE_HARDIRQ_H */
diff --git a/arch/microblaze/include/asm/ioctls.h b/arch/microblaze/include/asm/ioctls.h
index 03582b2..ec34c76 100644
--- a/arch/microblaze/include/asm/ioctls.h
+++ b/arch/microblaze/include/asm/ioctls.h
@@ -1,91 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_IOCTLS_H
-#define _ASM_MICROBLAZE_IOCTLS_H
-
-#include <linux/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-/* Get Pty Number (of pty-mux device) */
-#define TIOCGPTN _IOR('T', 0x30, unsigned int)
-#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */
-
-#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-
-#define FIOQSIZE 0x545E
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
-#endif /* _ASM_MICROBLAZE_IOCTLS_H */
+#include <asm-generic/ioctls.h>
diff --git a/arch/microblaze/include/asm/ipcbuf.h b/arch/microblaze/include/asm/ipcbuf.h
index b056fa4..84c7e51 100644
--- a/arch/microblaze/include/asm/ipcbuf.h
+++ b/arch/microblaze/include/asm/ipcbuf.h
@@ -1,36 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_IPCBUF_H
-#define _ASM_MICROBLAZE_IPCBUF_H
-
-/*
- * The user_ipc_perm structure for microblaze architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 32-bit mode_t and seq
- * - 2 miscellaneous 32-bit values
- */
-
-struct ipc64_perm {
- __kernel_key_t key;
- __kernel_uid32_t uid;
- __kernel_gid32_t gid;
- __kernel_uid32_t cuid;
- __kernel_gid32_t cgid;
- __kernel_mode_t mode;
- unsigned short __pad1;
- unsigned short seq;
- unsigned short __pad2;
- unsigned long __unused1;
- unsigned long __unused2;
-};
-
-#endif /* _ASM_MICROBLAZE_IPCBUF_H */
+#include <asm-generic/ipcbuf.h>
diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h
index db515de..90f0505 100644
--- a/arch/microblaze/include/asm/irq.h
+++ b/arch/microblaze/include/asm/irq.h
@@ -10,6 +10,7 @@
#define _ASM_MICROBLAZE_IRQ_H
#define NR_IRQS 32
+#include <asm-generic/irq.h>
#include <linux/interrupt.h>
@@ -17,11 +18,6 @@
#define NO_IRQ (-1)
-static inline int irq_canonicalize(int irq)
-{
- return irq;
-}
-
struct pt_regs;
extern void do_IRQ(struct pt_regs *regs);
diff --git a/arch/microblaze/include/asm/mman.h b/arch/microblaze/include/asm/mman.h
index 4914b13..8eebf89 100644
--- a/arch/microblaze/include/asm/mman.h
+++ b/arch/microblaze/include/asm/mman.h
@@ -1,25 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_MMAN_H
-#define _ASM_MICROBLAZE_MMAN_H
-
#include <asm-generic/mman.h>
-
-#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
-#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
-#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
-#define MAP_LOCKED 0x2000 /* pages are locked */
-#define MAP_NORESERVE 0x4000 /* don't check for reservations */
-#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
-#define MAP_NONBLOCK 0x10000 /* do not block on IO */
-
-#define MCL_CURRENT 1 /* lock all current mappings */
-#define MCL_FUTURE 2 /* lock all future mappings */
-
-#endif /* _ASM_MICROBLAZE_MMAN_H */
diff --git a/arch/microblaze/include/asm/mmu.h b/arch/microblaze/include/asm/mmu.h
index 66cad6a..8d6a654 100644
--- a/arch/microblaze/include/asm/mmu.h
+++ b/arch/microblaze/include/asm/mmu.h
@@ -12,12 +12,7 @@
#define _ASM_MICROBLAZE_MMU_H
# ifndef CONFIG_MMU
-# ifndef __ASSEMBLY__
-typedef struct {
- struct vm_list_struct *vmlist;
- unsigned long end_brk;
-} mm_context_t;
-# endif /* __ASSEMBLY__ */
+# include <asm-generic/mmu.h>
# else /* CONFIG_MMU */
# ifdef __KERNEL__
# ifndef __ASSEMBLY__
diff --git a/arch/microblaze/include/asm/mmu_context.h b/arch/microblaze/include/asm/mmu_context.h
index 385fed1..24eab16 100644
--- a/arch/microblaze/include/asm/mmu_context.h
+++ b/arch/microblaze/include/asm/mmu_context.h
@@ -1,5 +1,5 @@
#ifdef CONFIG_MMU
# include "mmu_context_mm.h"
#else
-# include "mmu_context_no.h"
+# include <asm-generic/mmu_context.h>
#endif
diff --git a/arch/microblaze/include/asm/mmu_context_no.h b/arch/microblaze/include/asm/mmu_context_no.h
deleted file mode 100644
index ba55671..0000000
--- a/arch/microblaze/include/asm/mmu_context_no.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
- * Copyright (C) 2008-2009 PetaLogix
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_MMU_CONTEXT_H
-#define _ASM_MICROBLAZE_MMU_CONTEXT_H
-
-# define init_new_context(tsk, mm) ({ 0; })
-
-# define enter_lazy_tlb(mm, tsk) do {} while (0)
-# define change_mm_context(old, ctx, _pml4) do {} while (0)
-# define destroy_context(mm) do {} while (0)
-# define deactivate_mm(tsk, mm) do {} while (0)
-# define switch_mm(prev, next, tsk) do {} while (0)
-# define activate_mm(prev, next) do {} while (0)
-
-#endif /* _ASM_MICROBLAZE_MMU_CONTEXT_H */
diff --git a/arch/microblaze/include/asm/module.h b/arch/microblaze/include/asm/module.h
index 914565a..7be1347 100644
--- a/arch/microblaze/include/asm/module.h
+++ b/arch/microblaze/include/asm/module.h
@@ -9,6 +9,8 @@
#ifndef _ASM_MICROBLAZE_MODULE_H
#define _ASM_MICROBLAZE_MODULE_H
+#include <asm-generic/module.h>
+
/* Microblaze Relocations */
#define R_MICROBLAZE_NONE 0
#define R_MICROBLAZE_32 1
@@ -24,14 +26,6 @@
/* Keep this the last entry. */
#define R_MICROBLAZE_NUM 11
-struct mod_arch_specific {
- int foo;
-};
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
typedef struct { volatile int counter; } module_t;
#endif /* _ASM_MICROBLAZE_MODULE_H */
diff --git a/arch/microblaze/include/asm/msgbuf.h b/arch/microblaze/include/asm/msgbuf.h
index 09dd970..809134c 100644
--- a/arch/microblaze/include/asm/msgbuf.h
+++ b/arch/microblaze/include/asm/msgbuf.h
@@ -1,31 +1 @@
-#ifndef _ASM_MICROBLAZE_MSGBUF_H
-#define _ASM_MICROBLAZE_MSGBUF_H
-
-/*
- * The msqid64_ds structure for microblaze architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 64-bit time_t to solve y2038 problem
- * - 2 miscellaneous 32-bit values
- */
-
-struct msqid64_ds {
- struct ipc64_perm msg_perm;
- __kernel_time_t msg_stime; /* last msgsnd time */
- unsigned long __unused1;
- __kernel_time_t msg_rtime; /* last msgrcv time */
- unsigned long __unused2;
- __kernel_time_t msg_ctime; /* last change time */
- unsigned long __unused3;
- unsigned long msg_cbytes; /* current number of bytes on queue */
- unsigned long msg_qnum; /* number of messages in queue */
- unsigned long msg_qbytes; /* max number of bytes on queue */
- __kernel_pid_t msg_lspid; /* pid of last msgsnd */
- __kernel_pid_t msg_lrpid; /* last receive pid */
- unsigned long __unused4;
- unsigned long __unused5;
-};
-
-#endif /* _ASM_MICROBLAZE_MSGBUF_H */
+#include <asm-generic/msgbuf.h>
diff --git a/arch/microblaze/include/asm/param.h b/arch/microblaze/include/asm/param.h
index 8c538a4..965d454 100644
--- a/arch/microblaze/include/asm/param.h
+++ b/arch/microblaze/include/asm/param.h
@@ -1,30 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_PARAM_H
-#define _ASM_MICROBLAZE_PARAM_H
-
-#ifdef __KERNEL__
-#define HZ CONFIG_HZ /* internal kernel timer frequency */
-#define USER_HZ 100 /* for user interfaces in "ticks" */
-#define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */
-#endif /* __KERNEL__ */
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-
-#endif /* _ASM_MICROBLAZE_PARAM_H */
+#include <asm-generic/param.h>
diff --git a/arch/microblaze/include/asm/parport.h b/arch/microblaze/include/asm/parport.h
new file mode 100644
index 0000000..cf252af
--- /dev/null
+++ b/arch/microblaze/include/asm/parport.h
@@ -0,0 +1 @@
+#include <asm-generic/parport.h>
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
index ca03794..9f0df5f 100644
--- a/arch/microblaze/include/asm/pci.h
+++ b/arch/microblaze/include/asm/pci.h
@@ -1 +1 @@
-#include <linux/io.h>
+#include <asm-generic/pci.h>
diff --git a/arch/microblaze/include/asm/posix_types.h b/arch/microblaze/include/asm/posix_types.h
index 8c758b2..0e15039 100644
--- a/arch/microblaze/include/asm/posix_types.h
+++ b/arch/microblaze/include/asm/posix_types.h
@@ -1,73 +1,9 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
#ifndef _ASM_MICROBLAZE_POSIX_TYPES_H
#define _ASM_MICROBLAZE_POSIX_TYPES_H
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc. Also, we cannot
- * assume GCC is being used.
- */
-
-typedef unsigned long __kernel_ino_t;
typedef unsigned short __kernel_mode_t;
-typedef unsigned int __kernel_nlink_t;
-typedef long __kernel_off_t;
-typedef int __kernel_pid_t;
-typedef unsigned int __kernel_ipc_pid_t;
-typedef unsigned int __kernel_uid_t;
-typedef unsigned int __kernel_gid_t;
-typedef unsigned long __kernel_size_t;
-typedef long __kernel_ssize_t;
-typedef int __kernel_ptrdiff_t;
-typedef long __kernel_time_t;
-typedef long __kernel_suseconds_t;
-typedef long __kernel_clock_t;
-typedef int __kernel_timer_t;
-typedef int __kernel_clockid_t;
-typedef int __kernel_daddr_t;
-typedef char *__kernel_caddr_t;
-typedef unsigned short __kernel_uid16_t;
-typedef unsigned short __kernel_gid16_t;
-typedef unsigned int __kernel_uid32_t;
-typedef unsigned int __kernel_gid32_t;
+#define __kernel_mode_t __kernel_mode_t
-typedef unsigned int __kernel_old_uid_t;
-typedef unsigned int __kernel_old_gid_t;
-typedef unsigned int __kernel_old_dev_t;
-
-#ifdef __GNUC__
-typedef long long __kernel_loff_t;
-#endif
-
-typedef struct {
-#if defined(__KERNEL__) || defined(__USE_ALL)
- int val[2];
-#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
- int __val[2];
-#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
-
-#undef __FD_SET
-#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
-
-#undef __FD_CLR
-#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-
-#undef __FD_ISSET
-#define __FD_ISSET(d, set) (!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d)))
-
-#undef __FD_ZERO
-#define __FD_ZERO(fdsetp) (memset(fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
-
-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+#include <asm-generic/posix_types.h>
#endif /* _ASM_MICROBLAZE_POSIX_TYPES_H */
diff --git a/arch/microblaze/include/asm/scatterlist.h b/arch/microblaze/include/asm/scatterlist.h
index 08ff1d0..35d786f 100644
--- a/arch/microblaze/include/asm/scatterlist.h
+++ b/arch/microblaze/include/asm/scatterlist.h
@@ -1,28 +1 @@
-/*
- * Copyright (C) 2008 Michal Simek <monstr@monstr.eu>
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_SCATTERLIST_H
-#define _ASM_MICROBLAZE_SCATTERLIST_H
-
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
- unsigned long sg_magic;
-#endif
- unsigned long page_link;
- dma_addr_t dma_address;
- unsigned int offset;
- unsigned int length;
-};
-
-#define sg_dma_address(sg) ((sg)->dma_address)
-#define sg_dma_len(sg) ((sg)->length)
-
-#define ISA_DMA_THRESHOLD (~0UL)
-
-#endif /* _ASM_MICROBLAZE_SCATTERLIST_H */
+#include <asm-generic/scatterlist.h>
diff --git a/arch/microblaze/include/asm/sembuf.h b/arch/microblaze/include/asm/sembuf.h
index b804ed7..7673b83 100644
--- a/arch/microblaze/include/asm/sembuf.h
+++ b/arch/microblaze/include/asm/sembuf.h
@@ -1,34 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_SEMBUF_H
-#define _ASM_MICROBLAZE_SEMBUF_H
-
-/*
- * The semid64_ds structure for microblaze architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 64-bit time_t to solve y2038 problem
- * - 2 miscellaneous 32-bit values
- */
-
-struct semid64_ds {
- struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t sem_otime; /* last semop time */
- unsigned long __unused1;
- __kernel_time_t sem_ctime; /* last change time */
- unsigned long __unused2;
- unsigned long sem_nsems; /* no. of semaphores in array */
- unsigned long __unused3;
- unsigned long __unused4;
-};
-
-
-#endif /* _ASM_MICROBLAZE_SEMBUF_H */
+#include <asm-generic/sembuf.h>
diff --git a/arch/microblaze/include/asm/serial.h b/arch/microblaze/include/asm/serial.h
index 39bfc8c..a0cb0ca 100644
--- a/arch/microblaze/include/asm/serial.h
+++ b/arch/microblaze/include/asm/serial.h
@@ -1,14 +1 @@
-/*
- * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_SERIAL_H
-#define _ASM_MICROBLAZE_SERIAL_H
-
-# define BASE_BAUD (1843200 / 16)
-
-#endif /* _ASM_MICROBLAZE_SERIAL_H */
+#include <asm-generic/serial.h>
diff --git a/arch/microblaze/include/asm/shmbuf.h b/arch/microblaze/include/asm/shmbuf.h
index f829c58..83c05fc 100644
--- a/arch/microblaze/include/asm/shmbuf.h
+++ b/arch/microblaze/include/asm/shmbuf.h
@@ -1,42 +1 @@
-#ifndef _ASM_MICROBLAZE_SHMBUF_H
-#define _ASM_MICROBLAZE_SHMBUF_H
-
-/*
- * The shmid64_ds structure for microblaze architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 64-bit time_t to solve y2038 problem
- * - 2 miscellaneous 32-bit values
- */
-
-struct shmid64_ds {
- struct ipc64_perm shm_perm; /* operation perms */
- size_t shm_segsz; /* size of segment (bytes) */
- __kernel_time_t shm_atime; /* last attach time */
- unsigned long __unused1;
- __kernel_time_t shm_dtime; /* last detach time */
- unsigned long __unused2;
- __kernel_time_t shm_ctime; /* last change time */
- unsigned long __unused3;
- __kernel_pid_t shm_cpid; /* pid of creator */
- __kernel_pid_t shm_lpid; /* pid of last operator */
- unsigned long shm_nattch; /* no. of current attaches */
- unsigned long __unused4;
- unsigned long __unused5;
-};
-
-struct shminfo64 {
- unsigned long shmmax;
- unsigned long shmmin;
- unsigned long shmmni;
- unsigned long shmseg;
- unsigned long shmall;
- unsigned long __unused1;
- unsigned long __unused2;
- unsigned long __unused3;
- unsigned long __unused4;
-};
-
-#endif /* _ASM_MICROBLAZE_SHMBUF_H */
+#include <asm-generic/shmbuf.h>
diff --git a/arch/microblaze/include/asm/shmparam.h b/arch/microblaze/include/asm/shmparam.h
index 9f5fc2b..93f30de 100644
--- a/arch/microblaze/include/asm/shmparam.h
+++ b/arch/microblaze/include/asm/shmparam.h
@@ -1,6 +1 @@
-#ifndef _ASM_MICROBLAZE_SHMPARAM_H
-#define _ASM_MICROBLAZE_SHMPARAM_H
-
-#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
-
-#endif /* _ASM_MICROBLAZE_SHMPARAM_H */
+#include <asm-generic/shmparam.h>
diff --git a/arch/microblaze/include/asm/siginfo.h b/arch/microblaze/include/asm/siginfo.h
index f162911..0815d29 100644
--- a/arch/microblaze/include/asm/siginfo.h
+++ b/arch/microblaze/include/asm/siginfo.h
@@ -1,15 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_SIGINFO_H
-#define _ASM_MICROBLAZE_SIGINFO_H
-
-#include <linux/types.h>
#include <asm-generic/siginfo.h>
-
-#endif /* _ASM_MICROBLAZE_SIGINFO_H */
diff --git a/arch/microblaze/include/asm/signal.h b/arch/microblaze/include/asm/signal.h
index 46bc226..7b1573c 100644
--- a/arch/microblaze/include/asm/signal.h
+++ b/arch/microblaze/include/asm/signal.h
@@ -1,165 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- * Yasushi SHOJI <yashi@atmark-techno.com>
- * Tetsuya OHKAWA <tetsuya@atmark-techno.com>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_SIGNAL_H
-#define _ASM_MICROBLAZE_SIGNAL_H
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP 0x00000001
-#define SA_NOCLDWAIT 0x00000002
-#define SA_SIGINFO 0x00000004
-#define SA_ONSTACK 0x08000000
-#define SA_RESTART 0x10000000
-#define SA_NODEFER 0x40000000
-#define SA_RESETHAND 0x80000000
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-
-#define SA_RESTORER 0x04000000
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 2048
-#define SIGSTKSZ 8192
-
-# ifndef __ASSEMBLY__
-# include <linux/types.h>
-# include <asm-generic/signal-defs.h>
-
-/* Avoid too many header ordering problems. */
-struct siginfo;
-
-# ifdef __KERNEL__
-/*
- * Most things should be clean enough to redefine this at will, if care
- * is taken to make libc match.
- */
-# define _NSIG 64
-# define _NSIG_BPW 32
-# define _NSIG_WORDS (_NSIG / _NSIG_BPW)
-
-typedef unsigned long old_sigset_t; /* at least 32 bits */
-
-typedef struct {
- unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
-struct old_sigaction {
- __sighandler_t sa_handler;
- old_sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
-};
-
-struct sigaction {
- __sighandler_t sa_handler;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
- sigset_t sa_mask; /* mask last for extensibility */
-};
-
-struct k_sigaction {
- struct sigaction sa;
-};
-
-# include <asm/sigcontext.h>
-# undef __HAVE_ARCH_SIG_BITOPS
-
-# define ptrace_signal_deliver(regs, cookie) do { } while (0)
-
-# else /* !__KERNEL__ */
-
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-# define NSIG 32
-typedef unsigned long sigset_t;
-
-struct sigaction {
- union {
- __sighandler_t _sa_handler;
- void (*_sa_sigaction)(int, struct siginfo *, void *);
- } _u;
- sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
-};
-
-# define sa_handler _u._sa_handler
-# define sa_sigaction _u._sa_sigaction
-
-# endif /* __KERNEL__ */
-
-typedef struct sigaltstack {
- void *ss_sp;
- int ss_flags;
- size_t ss_size;
-} stack_t;
-
-# endif /* __ASSEMBLY__ */
-#endif /* _ASM_MICROBLAZE_SIGNAL_H */
+#include <asm-generic/signal.h>
diff --git a/arch/microblaze/include/asm/socket.h b/arch/microblaze/include/asm/socket.h
index 8259368..6b71384 100644
--- a/arch/microblaze/include/asm/socket.h
+++ b/arch/microblaze/include/asm/socket.h
@@ -1,69 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_SOCKET_H
-#define _ASM_MICROBLAZE_SOCKET_H
-
-#include <asm/sockios.h>
-
-/* For setsockoptions(2) */
-#define SOL_SOCKET 1
-
-#define SO_DEBUG 1
-#define SO_REUSEADDR 2
-#define SO_TYPE 3
-#define SO_ERROR 4
-#define SO_DONTROUTE 5
-#define SO_BROADCAST 6
-#define SO_SNDBUF 7
-#define SO_RCVBUF 8
-#define SO_SNDBUFFORCE 32
-#define SO_RCVBUFFORCE 33
-#define SO_KEEPALIVE 9
-#define SO_OOBINLINE 10
-#define SO_NO_CHECK 11
-#define SO_PRIORITY 12
-#define SO_LINGER 13
-#define SO_BSDCOMPAT 14
-/* To add :#define SO_REUSEPORT 15 */
-#define SO_PASSCRED 16
-#define SO_PEERCRED 17
-#define SO_RCVLOWAT 18
-#define SO_SNDLOWAT 19
-#define SO_RCVTIMEO 20
-#define SO_SNDTIMEO 21
-
-/* Security levels - as per NRL IPv6 - don't actually do anything */
-#define SO_SECURITY_AUTHENTICATION 22
-#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
-#define SO_SECURITY_ENCRYPTION_NETWORK 24
-
-#define SO_BINDTODEVICE 25
-
-/* Socket filtering */
-#define SO_ATTACH_FILTER 26
-#define SO_DETACH_FILTER 27
-
-#define SO_PEERNAME 28
-#define SO_TIMESTAMP 29
-#define SCM_TIMESTAMP SO_TIMESTAMP
-
-#define SO_ACCEPTCONN 30
-
-#define SO_PEERSEC 31
-#define SO_PASSSEC 34
-
-#define SO_TIMESTAMPNS 35
-#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
-
-#define SO_MARK 36
-
-#define SO_TIMESTAMPING 37
-#define SCM_TIMESTAMPING SO_TIMESTAMPING
-
-#endif /* _ASM_MICROBLAZE_SOCKET_H */
+#include <asm-generic/socket.h>
diff --git a/arch/microblaze/include/asm/sockios.h b/arch/microblaze/include/asm/sockios.h
index 9fff57a..def6d47 100644
--- a/arch/microblaze/include/asm/sockios.h
+++ b/arch/microblaze/include/asm/sockios.h
@@ -1,23 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_SOCKIOS_H
-#define _ASM_MICROBLAZE_SOCKIOS_H
-
-#include <linux/ioctl.h>
-
-/* Socket-level I/O control calls. */
-#define FIOSETOWN 0x8901
-#define SIOCSPGRP 0x8902
-#define FIOGETOWN 0x8903
-#define SIOCGPGRP 0x8904
-#define SIOCATMARK 0x8905
-#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
-#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
-
-#endif /* _ASM_MICROBLAZE_SOCKIOS_H */
+#include <asm-generic/sockios.h>
diff --git a/arch/microblaze/include/asm/stat.h b/arch/microblaze/include/asm/stat.h
index a15f775..3dc90fa 100644
--- a/arch/microblaze/include/asm/stat.h
+++ b/arch/microblaze/include/asm/stat.h
@@ -1,68 +1 @@
-/*
- * Microblaze stat structure
- *
- * Copyright (C) 2001,02,03 NEC Electronics Corporation
- * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file COPYING in the main directory of this
- * archive for more details.
- *
- * Written by Miles Bader <miles@gnu.org>
- */
-
-#ifndef _ASM_MICROBLAZE_STAT_H
-#define _ASM_MICROBLAZE_STAT_H
-
-#include <linux/posix_types.h>
-
-#define STAT_HAVE_NSEC 1
-
-struct stat {
- unsigned long st_dev;
- unsigned long st_ino;
- unsigned int st_mode;
- unsigned int st_nlink;
- unsigned int st_uid;
- unsigned int st_gid;
- unsigned long st_rdev;
- unsigned long __pad1;
- long st_size;
- int st_blksize;
- int __pad2;
- long st_blocks;
- int st_atime;
- unsigned int st_atime_nsec;
- int st_mtime;
- unsigned int st_mtime_nsec;
- int st_ctime;
- unsigned int st_ctime_nsec;
- unsigned long __unused4;
- unsigned long __unused5;
-};
-
-struct stat64 {
- unsigned long long st_dev; /* Device. */
- unsigned long long st_ino; /* File serial number. */
- unsigned int st_mode; /* File mode. */
- unsigned int st_nlink; /* Link count. */
- unsigned int st_uid; /* User ID of the file's owner. */
- unsigned int st_gid; /* Group ID of the file's group. */
- unsigned long long st_rdev; /* Device number, if device. */
- unsigned long long __pad1;
- long long st_size; /* Size of file, in bytes. */
- int st_blksize; /* Optimal block size for I/O. */
- int __pad2;
- long long st_blocks; /* Number 512-byte blocks allocated. */
- int st_atime; /* Time of last access. */
- unsigned int st_atime_nsec;
- int st_mtime; /* Time of last modification. */
- unsigned int st_mtime_nsec;
- int st_ctime; /* Time of last status change. */
- unsigned int st_ctime_nsec;
- unsigned int __unused4;
- unsigned int __unused5;
-};
-
-#endif /* _ASM_MICROBLAZE_STAT_H */
-
+#include <asm-generic/stat.h>
diff --git a/arch/microblaze/include/asm/swab.h b/arch/microblaze/include/asm/swab.h
index b375d7b..7847e56 100644
--- a/arch/microblaze/include/asm/swab.h
+++ b/arch/microblaze/include/asm/swab.h
@@ -1,8 +1 @@
-#ifndef _ASM_MICROBLAZE_SWAB_H
-#define _ASM_MICROBLAZE_SWAB_H
-
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
-#define __SWAB_64_THRU_32__
-#endif
-
-#endif /* _ASM_MICROBLAZE_SWAB_H */
+#include <asm-generic/swab.h>
diff --git a/arch/microblaze/include/asm/syscalls.h b/arch/microblaze/include/asm/syscalls.h
index ddea9eb..720761c 100644
--- a/arch/microblaze/include/asm/syscalls.h
+++ b/arch/microblaze/include/asm/syscalls.h
@@ -1,48 +1,8 @@
#ifndef __ASM_MICROBLAZE_SYSCALLS_H
-#define __ASM_MICROBLAZE_SYSCALLS_H
-#ifdef __KERNEL__
-#include <linux/compiler.h>
-#include <linux/linkage.h>
-#include <linux/types.h>
-#include <linux/signal.h>
+asmlinkage long sys_clone(int flags, unsigned long stack, struct pt_regs *regs);
+#define sys_clone sys_clone
-/* FIXME will be removed */
-asmlinkage int sys_ipc(uint call, int first, int second,
- int third, void *ptr, long fifth);
+#include <asm-generic/syscalls.h>
-struct pt_regs;
-asmlinkage int sys_vfork(struct pt_regs *regs);
-asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs);
-asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv,
- char __user *__user *envp, struct pt_regs *regs);
-
-asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff);
-
-asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t offset);
-
-/* from signal.c */
-asmlinkage int sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs);
-
-asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
- struct pt_regs *regs);
-
-asmlinkage int sys_sigaction(int sig, const struct old_sigaction *act,
- struct old_sigaction *oact);
-
-asmlinkage long sys_rt_sigaction(int sig, const struct sigaction __user *act,
- struct sigaction __user *oact, size_t sigsetsize);
-
-asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
- struct pt_regs *regs);
-
-asmlinkage int sys_sigreturn(struct pt_regs *regs);
-
-asmlinkage int sys_rt_sigreturn(struct pt_regs *regs);
-
-#endif /* __KERNEL__ */
#endif /* __ASM_MICROBLAZE_SYSCALLS_H */
diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h
index c4e3088..b1ed615 100644
--- a/arch/microblaze/include/asm/system.h
+++ b/arch/microblaze/include/asm/system.h
@@ -13,6 +13,9 @@
#include <asm/setup.h>
#include <asm/irqflags.h>
+#include <asm-generic/cmpxchg.h>
+#include <asm-generic/cmpxchg-local.h>
+
struct task_struct;
struct thread_info;
diff --git a/arch/microblaze/include/asm/termbits.h b/arch/microblaze/include/asm/termbits.h
index a1b64bc..3935b10 100644
--- a/arch/microblaze/include/asm/termbits.h
+++ b/arch/microblaze/include/asm/termbits.h
@@ -1,203 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_TERMBITS_H
-#define _ASM_MICROBLAZE_TERMBITS_H
-
-#include <linux/posix_types.h>
-
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
-typedef unsigned int tcflag_t;
-
-#define NCCS 19
-struct termios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
-};
-
-struct ktermios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
- speed_t c_ispeed; /* input speed */
- speed_t c_ospeed; /* output speed */
-};
-
-/* c_cc characters */
-
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VTIME 5
-#define VMIN 6
-#define VSWTC 7
-#define VSTART 8
-#define VSTOP 9
-#define VSUSP 10
-#define VEOL 11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE 14
-#define VLNEXT 15
-#define VEOL2 16
-
-/* c_iflag bits */
-
-#define IGNBRK 0000001
-#define BRKINT 0000002
-#define IGNPAR 0000004
-#define PARMRK 0000010
-#define INPCK 0000020
-#define ISTRIP 0000040
-#define INLCR 0000100
-#define IGNCR 0000200
-#define ICRNL 0000400
-#define IUCLC 0001000
-#define IXON 0002000
-#define IXANY 0004000
-#define IXOFF 0010000
-#define IMAXBEL 0020000
-#define IUTF8 0040000
-
-/* c_oflag bits */
-
-#define OPOST 0000001
-#define OLCUC 0000002
-#define ONLCR 0000004
-#define OCRNL 0000010
-#define ONOCR 0000020
-#define ONLRET 0000040
-#define OFILL 0000100
-#define OFDEL 0000200
-#define NLDLY 0000400
-#define NL0 0000000
-#define NL1 0000400
-#define CRDLY 0003000
-#define CR0 0000000
-#define CR1 0001000
-#define CR2 0002000
-#define CR3 0003000
-#define TABDLY 0014000
-#define TAB0 0000000
-#define TAB1 0004000
-#define TAB2 0010000
-#define TAB3 0014000
-#define XTABS 0014000
-#define BSDLY 0020000
-#define BS0 0000000
-#define BS1 0020000
-#define VTDLY 0040000
-#define VT0 0000000
-#define VT1 0040000
-#define FFDLY 0100000
-#define FF0 0000000
-#define FF1 0100000
-
-/* c_cflag bit meaning */
-
-#define CBAUD 0010017
-#define B0 0000000 /* hang up */
-#define B50 0000001
-#define B75 0000002
-#define B110 0000003
-#define B134 0000004
-#define B150 0000005
-#define B200 0000006
-#define B300 0000007
-#define B600 0000010
-#define B1200 0000011
-#define B1800 0000012
-#define B2400 0000013
-#define B4800 0000014
-#define B9600 0000015
-#define B19200 0000016
-#define B38400 0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE 0000060
-#define CS5 0000000
-#define CS6 0000020
-#define CS7 0000040
-#define CS8 0000060
-#define CSTOPB 0000100
-#define CREAD 0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL 0002000
-#define CLOCAL 0004000
-#define CBAUDEX 0010000
-#define B57600 0010001
-#define B115200 0010002
-#define B230400 0010003
-#define B460800 0010004
-#define B500000 0010005
-#define B576000 0010006
-#define B921600 0010007
-#define BOTHER 0010000
-#define B1000000 0010010
-#define B1152000 0010011
-#define B1500000 0010012
-#define B2000000 0010013
-#define B2500000 0010014
-#define B3000000 0010015
-#define B3500000 0010016
-#define B4000000 0010017
-#define CIBAUD 002003600000 /* input baud rate (not used) */
-#define CMSPAR 010000000000 /* mark or space (stick) parity */
-#define CRTSCTS 020000000000 /* flow control */
-
-#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
-
-/* c_lflag bits */
-
-#define ISIG 0000001
-#define ICANON 0000002
-#define XCASE 0000004
-#define ECHO 0000010
-#define ECHOE 0000020
-#define ECHOK 0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-#define IEXTEN 0100000
-
-/* tcflow() and TCXONC use these */
-
-#define TCOOFF 0
-#define TCOON 1
-#define TCIOFF 2
-#define TCION 3
-
-/* tcflush() and TCFLSH use these */
-
-#define TCIFLUSH 0
-#define TCOFLUSH 1
-#define TCIOFLUSH 2
-
-/* tcsetattr uses these */
-
-#define TCSANOW 0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-#endif /* _ASM_MICROBLAZE_TERMBITS_H */
+#include <asm-generic/termbits.h>
diff --git a/arch/microblaze/include/asm/termios.h b/arch/microblaze/include/asm/termios.h
index 47a46d1..280d78a 100644
--- a/arch/microblaze/include/asm/termios.h
+++ b/arch/microblaze/include/asm/termios.h
@@ -1,88 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_TERMIOS_H
-#define _ASM_MICROBLAZE_TERMIOS_H
-
-#include <linux/string.h>
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
-
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
-#ifdef __KERNEL__
-/* intr=^C quit=^| erase=del kill=^U
- eof=^D vtime=\0 vmin=\1 sxtc=\0
- start=^Q stop=^S susp=^Z eol=\0
- reprint=^R discard=^U werase=^W lnext=^V
- eol2=\0
-*/
-#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
-#endif
-
-/* Modem lines */
-
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_OUT1 0x2000
-#define TIOCM_OUT2 0x4000
-#define TIOCM_LOOP 0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-/* Line disciplines */
-
-#define N_TTY 0
-#define N_SLIP 1
-#define N_MOUSE 2
-#define N_PPP 3
-#define N_STRIP 4
-#define N_AX25 5
-#define N_X25 6 /* X.25 async */
-#define N_6PACK 7
-#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */
-#define N_R3964 9 /* Reserved for Simatic R3964 module */
-#define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */
-#define N_IRDA 11 /* Linux IR - http://irda.sourceforge.net/ */
-#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards
- about SMS messages */
-#define N_HDLC 13 /* synchronous HDLC */
-#define N_SYNC_PPP 14
-#define N_HCI 15 /* Bluetooth HCI UART */
-
-#ifdef __KERNEL__
-
-#include <asm-generic/termios-base.h>
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_MICROBLAZE_TERMIOS_H */
+#include <asm-generic/termios.h>
diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h
index 7fac444..6e92885 100644
--- a/arch/microblaze/include/asm/thread_info.h
+++ b/arch/microblaze/include/asm/thread_info.h
@@ -75,8 +75,6 @@
/*
* macros/functions for gaining access to the thread information structure
- *
- * preempt_count needs to be 1 initially, until the scheduler is functional.
*/
#define INIT_THREAD_INFO(tsk) \
{ \
@@ -84,7 +82,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.restart_block = { \
.fn = do_no_restart_syscall, \
diff --git a/arch/microblaze/include/asm/timex.h b/arch/microblaze/include/asm/timex.h
index 678525d..befcf3d 100644
--- a/arch/microblaze/include/asm/timex.h
+++ b/arch/microblaze/include/asm/timex.h
@@ -9,10 +9,8 @@
#ifndef _ASM_MICROBLAZE_TIMEX_H
#define _ASM_MICROBLAZE_TIMEX_H
+#include <asm-generic/timex.h>
+
#define CLOCK_TICK_RATE 1000 /* Timer input freq. */
-typedef unsigned long cycles_t;
-
-#define get_cycles() (0)
-
#endif /* _ASM_TIMEX_H */
diff --git a/arch/microblaze/include/asm/types.h b/arch/microblaze/include/asm/types.h
index bebc018..b9e79bc 100644
--- a/arch/microblaze/include/asm/types.h
+++ b/arch/microblaze/include/asm/types.h
@@ -1,38 +1 @@
-/*
- * Copyright (C) Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_TYPES_H
-#define _ASM_MICROBLAZE_TYPES_H
-
-/*
- * This file is never included by application software unless
- * explicitly requested (e.g., via linux/types.h) in which case the
- * application is Linux specific so (user-) name space pollution is
- * not a major issue. However, for interoperability, libraries still
- * need to be careful to avoid a name clashes.
- */
-
-#include <asm-generic/int-ll64.h>
-
-# ifndef __ASSEMBLY__
-
-typedef unsigned short umode_t;
-
-/*
- * These aren't exported outside the kernel to avoid name space clashes
- */
-# ifdef __KERNEL__
-# define BITS_PER_LONG 32
-
-/* Dma addresses are 32-bits wide. */
-
-typedef u32 dma_addr_t;
-
-# endif/* __KERNEL__ */
-# endif /* __ASSEMBLY__ */
-#endif /* _ASM_MICROBLAZE_TYPES_H */
+#include <asm-generic/types.h>
diff --git a/arch/microblaze/include/asm/ucontext.h b/arch/microblaze/include/asm/ucontext.h
index 11f6bb3..9bc07b9 100644
--- a/arch/microblaze/include/asm/ucontext.h
+++ b/arch/microblaze/include/asm/ucontext.h
@@ -1,22 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_UCONTEXT_H
-#define _ASM_MICROBLAZE_UCONTEXT_H
-
-#include <asm/sigcontext.h>
-
-struct ucontext {
- unsigned long uc_flags;
- struct ucontext *uc_link;
- stack_t uc_stack;
- struct sigcontext uc_mcontext;
- sigset_t uc_sigmask; /* mask last for extensibility */
-};
-
-#endif /* _ASM_MICROBLAZE_UCONTEXT_H */
+#include <asm-generic/ucontext.h>
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h
index b5e2f5f..0b85232 100644
--- a/arch/microblaze/include/asm/unistd.h
+++ b/arch/microblaze/include/asm/unistd.h
@@ -380,8 +380,10 @@
#define __NR_accept04 362 /* new */
#define __NR_preadv 363 /* new */
#define __NR_pwritev 364 /* new */
+#define __NR_rt_tgsigqueueinfo 365 /* new */
+#define __NR_perf_counter_open 366 /* new */
-#define __NR_syscalls 365
+#define __NR_syscalls 367
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
@@ -408,7 +410,7 @@
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-/* #define __ARCH_WANT_SYS_RT_SIGSUSPEND */
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
/*
* "Conditional" syscalls
diff --git a/arch/microblaze/include/asm/vga.h b/arch/microblaze/include/asm/vga.h
index 8b13789..89d82fd 100644
--- a/arch/microblaze/include/asm/vga.h
+++ b/arch/microblaze/include/asm/vga.h
@@ -1 +1 @@
-
+#include <asm-generic/vga.h>
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
index 1fce6b8..9083d85 100644
--- a/arch/microblaze/kernel/entry-nommu.S
+++ b/arch/microblaze/kernel/entry-nommu.S
@@ -551,30 +551,22 @@
rtid r14, 0
nop
-sys_vfork_wrapper:
- brid sys_vfork
+sys_vfork:
+ brid microblaze_vfork
addk r5, r1, r0
-sys_clone_wrapper:
- brid sys_clone
+sys_clone:
+ brid microblaze_clone
addk r7, r1, r0
-sys_execve_wrapper:
- brid sys_execve
+sys_execve:
+ brid microblaze_execve
addk r8, r1, r0
-sys_sigreturn_wrapper:
- brid sys_sigreturn
- addk r5, r1, r0
-
sys_rt_sigreturn_wrapper:
brid sys_rt_sigreturn
addk r5, r1, r0
-sys_sigsuspend_wrapper:
- brid sys_rt_sigsuspend
- addk r6, r1, r0
-
sys_rt_sigsuspend_wrapper:
brid sys_rt_sigsuspend
addk r7, r1, r0
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 91a0e7b..c7353e7 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -429,12 +429,11 @@
brid ret_from_trap; /* Do normal trap return */
nop;
-C_ENTRY(sys_vfork_wrapper):
+C_ENTRY(sys_vfork):
+ brid microblaze_vfork /* Do real work (tail-call) */
la r5, r1, PTO
- brid sys_vfork /* Do real work (tail-call) */
- nop
-C_ENTRY(sys_clone_wrapper):
+C_ENTRY(sys_clone):
bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */
lwi r6, r1, PTO+PT_R1; /* If so, use paret's stack ptr */
1: la r7, r1, PTO; /* Arg 2: parent context */
@@ -444,20 +443,9 @@
brid do_fork /* Do real work (tail-call) */
nop;
-C_ENTRY(sys_execve_wrapper):
+C_ENTRY(sys_execve):
la r8, r1, PTO; /* add user context as 4th arg */
- brid sys_execve; /* Do real work (tail-call).*/
- nop;
-
-C_ENTRY(sys_sigsuspend_wrapper):
- swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
- swi r4, r1, PTO+PT_R4;
- la r6, r1, PTO; /* add user context as 2nd arg */
- bralid r15, sys_sigsuspend; /* Do real work.*/
- nop;
- lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
- lwi r4, r1, PTO+PT_R4;
- bri ret_from_trap /* fall through will not work here due to align */
+ brid microblaze_execve; /* Do real work (tail-call).*/
nop;
C_ENTRY(sys_rt_sigsuspend_wrapper):
@@ -471,18 +459,6 @@
bri ret_from_trap /* fall through will not work here due to align */
nop;
-
-C_ENTRY(sys_sigreturn_wrapper):
- swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
- swi r4, r1, PTO+PT_R4;
- la r5, r1, PTO; /* add user context as 1st arg */
- brlid r15, sys_sigreturn; /* Do real work.*/
- nop;
- lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
- lwi r4, r1, PTO+PT_R4;
- bri ret_from_trap /* fall through will not work here due to align */
- nop;
-
C_ENTRY(sys_rt_sigreturn_wrapper):
swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
swi r4, r1, PTO+PT_R4;
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 4c0e652..493819c 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -45,91 +45,8 @@
asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall);
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-asmlinkage int
-sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs)
-{
- sigset_t saveset;
- mask &= _BLOCKABLE;
- spin_lock_irq(¤t->sighand->siglock);
- saveset = current->blocked;
- siginitset(¤t->blocked, mask);
- recalc_sigpending();
- spin_unlock_irq(¤t->sighand->siglock);
-
- regs->r3 = -EINTR;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal(regs, &saveset, 1))
- return -EINTR;
- }
-}
-
-asmlinkage int
-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
- struct pt_regs *regs)
-{
- sigset_t saveset, newset;
-
- /* XXX: Don't preclude handling different sized sigset_t's. */
- if (sigsetsize != sizeof(sigset_t))
- return -EINVAL;
-
- if (copy_from_user(&newset, unewset, sizeof(newset)))
- return -EFAULT;
- sigdelsetmask(&newset, ~_BLOCKABLE);
- spin_lock_irq(¤t->sighand->siglock);
- saveset = current->blocked;
- current->blocked = newset;
- recalc_sigpending();
- spin_unlock_irq(¤t->sighand->siglock);
-
- regs->r3 = -EINTR;
- while (1) {
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- if (do_signal(regs, &saveset, 1))
- return -EINTR;
- }
-}
-
-asmlinkage int
-sys_sigaction(int sig, const struct old_sigaction *act,
- struct old_sigaction *oact)
-{
- struct k_sigaction new_ka, old_ka;
- int ret;
-
- if (act) {
- old_sigset_t mask;
- if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
- return -EFAULT;
- __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __get_user(mask, &act->sa_mask);
- siginitset(&new_ka.sa.sa_mask, mask);
- }
-
- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-
- if (!ret && oact) {
- if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
- return -EFAULT;
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
- }
-
- return ret;
-}
-
-asmlinkage int
+asmlinkage long
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
struct pt_regs *regs)
{
@@ -139,7 +56,6 @@
/*
* Do a signal return; undo the signal stack.
*/
-
struct sigframe {
struct sigcontext sc;
unsigned long extramask[_NSIG_WORDS-1];
@@ -176,40 +92,7 @@
return err;
}
-asmlinkage int sys_sigreturn(struct pt_regs *regs)
-{
- struct sigframe *frame =
- (struct sigframe *)(regs->r1 + STATE_SAVE_ARG_SPACE);
-
- sigset_t set;
- int rval;
-
- if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
- goto badframe;
-
- if (__get_user(set.sig[0], &frame->sc.oldmask)
- || (_NSIG_WORDS > 1
- && __copy_from_user(&set.sig[1], &frame->extramask,
- sizeof(frame->extramask))))
- goto badframe;
-
- sigdelsetmask(&set, ~_BLOCKABLE);
-
- spin_lock_irq(¤t->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(¤t->sighand->siglock);
-
- if (restore_sigcontext(regs, &frame->sc, &rval))
- goto badframe;
- return rval;
-
-badframe:
- force_sig(SIGSEGV, current);
- return 0;
-}
-
-asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
{
struct rt_sigframe __user *frame =
(struct rt_sigframe __user *)(regs->r1 + STATE_SAVE_ARG_SPACE);
@@ -324,21 +207,17 @@
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
/* minus 8 is offset to cater for "rtsd r15,8" */
- if (ka->sa.sa_flags & SA_RESTORER) {
- regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8;
- } else {
- /* addi r12, r0, __NR_sigreturn */
- err |= __put_user(0x31800000 | __NR_rt_sigreturn ,
- frame->tramp + 0);
- /* brki r14, 0x8 */
- err |= __put_user(0xb9cc0008, frame->tramp + 1);
+ /* addi r12, r0, __NR_sigreturn */
+ err |= __put_user(0x31800000 | __NR_rt_sigreturn ,
+ frame->tramp + 0);
+ /* brki r14, 0x8 */
+ err |= __put_user(0xb9cc0008, frame->tramp + 1);
- /* Return from sighandler will jump to the tramp.
- Negative 8 offset because return is rtsd r15, 8 */
- regs->r15 = ((unsigned long)frame->tramp)-8;
+ /* Return from sighandler will jump to the tramp.
+ Negative 8 offset because return is rtsd r15, 8 */
+ regs->r15 = ((unsigned long)frame->tramp)-8;
- __invalidate_cache_sigtramp((unsigned long)frame->tramp);
- }
+ __invalidate_cache_sigtramp((unsigned long)frame->tramp);
if (err)
goto give_sigsegv;
@@ -405,7 +284,7 @@
* OK, we're invoking a handler
*/
-static void
+static int
handle_signal(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
{
@@ -426,6 +305,7 @@
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
}
+ return 1;
}
/*
@@ -456,7 +336,9 @@
if (kernel_mode(regs))
return 1;
- if (!oldset)
+ if (current_thread_info()->status & TS_RESTORE_SIGMASK)
+ oldset = ¤t->saved_sigmask;
+ else
oldset = ¤t->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -464,13 +346,31 @@
/* Whee! Actually deliver the signal. */
if (in_syscall)
handle_restart(regs, &ka, 1);
- handle_signal(signr, &ka, &info, oldset, regs);
+ if (handle_signal(signr, &ka, &info, oldset, regs)) {
+ /*
+ * A signal was successfully delivered; the saved
+ * sigmask will have been stored in the signal frame,
+ * and will be restored by sigreturn, so we can simply
+ * clear the TS_RESTORE_SIGMASK flag.
+ */
+ current_thread_info()->status &=
+ ~TS_RESTORE_SIGMASK;
+ }
return 1;
}
if (in_syscall)
handle_restart(regs, NULL, 0);
+ /*
+ * If there's no signal to deliver, we just put the saved sigmask
+ * back.
+ */
+ if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
+ current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+ sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
+ }
+
/* Did we come from a system call? */
return 0;
}
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
index 31905ff..8c9ebac 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -39,7 +39,7 @@
*
* This is really horribly ugly. This will be remove with new toolchain.
*/
-asmlinkage int
+asmlinkage long
sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth)
{
int version, ret;
@@ -134,20 +134,20 @@
return ret;
}
-asmlinkage int sys_vfork(struct pt_regs *regs)
+asmlinkage long microblaze_vfork(struct pt_regs *regs)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1,
regs, 0, NULL, NULL);
}
-asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs)
+asmlinkage long microblaze_clone(int flags, unsigned long stack, struct pt_regs *regs)
{
if (!stack)
stack = regs->r1;
return do_fork(flags, stack, regs, 0, NULL, NULL);
}
-asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv,
+asmlinkage long microblaze_execve(char __user *filenamei, char __user *__user *argv,
char __user *__user *envp, struct pt_regs *regs)
{
int error;
@@ -163,8 +163,8 @@
return error;
}
-asmlinkage unsigned long
-sys_mmap2(unsigned long addr, size_t len,
+asmlinkage long
+sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
@@ -189,18 +189,18 @@
return ret;
}
-asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
+asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
- unsigned long fd, off_t offset)
+ unsigned long fd, off_t pgoff)
{
int err = -EINVAL;
- if (offset & ~PAGE_MASK) {
+ if (pgoff & ~PAGE_MASK) {
printk(KERN_INFO "no pagemask in mmap\r\n");
goto out;
}
- err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+ err = sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
out:
return err;
}
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index 376d178..31b32a6 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -15,7 +15,7 @@
.long sys_creat
.long sys_link
.long sys_unlink /* 10 */
- .long sys_execve_wrapper
+ .long sys_execve
.long sys_chdir
.long sys_time
.long sys_mknod
@@ -71,12 +71,12 @@
.long sys_getppid
.long sys_getpgrp /* 65 */
.long sys_setsid
- .long sys_sigaction
+ .long sys_ni_syscall /* sys_sigaction */
.long sys_sgetmask
.long sys_ssetmask
.long sys_setreuid /* 70 */
.long sys_setregid
- .long sys_sigsuspend_wrapper
+ .long sys_ni_syscall /* sys_sigsuspend_wrapper */
.long sys_sigpending
.long sys_sethostname
.long sys_setrlimit /* 75 */
@@ -123,8 +123,8 @@
.long sys_sysinfo
.long sys_ipc
.long sys_fsync
- .long sys_sigreturn_wrapper
- .long sys_clone_wrapper /* 120 */
+ .long sys_ni_syscall /* sys_sigreturn_wrapper */
+ .long sys_clone /* 120 */
.long sys_setdomainname
.long sys_newuname
.long sys_ni_syscall /* modify_ldt */
@@ -194,7 +194,7 @@
.long sys_sendfile
.long sys_ni_syscall /* reserved for streams1 */
.long sys_ni_syscall /* reserved for streams2 */
- .long sys_vfork_wrapper /* 190 */
+ .long sys_vfork /* 190 */
.long sys_getrlimit
.long sys_mmap2 /* mmap2 */
.long sys_truncate64
@@ -369,3 +369,5 @@
.long sys_ni_syscall
.long sys_ni_syscall
.long sys_ni_syscall
+ .long sys_rt_tgsigqueueinfo /* 365 */
+ .long sys_perf_counter_open
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile
index 71c8cb6..b579db0 100644
--- a/arch/microblaze/lib/Makefile
+++ b/arch/microblaze/lib/Makefile
@@ -2,7 +2,7 @@
# Makefile
#
-lib-y := memset.o checksum.o
+lib-y := memset.o
ifeq ($(CONFIG_OPT_LIB_ASM),y)
lib-y += fastcopy.o
diff --git a/arch/microblaze/lib/checksum.c b/arch/microblaze/lib/checksum.c
deleted file mode 100644
index f08e745..0000000
--- a/arch/microblaze/lib/checksum.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- *
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * IP/TCP/UDP checksumming routines
- *
- * Authors: Jorge Cwik, <jorge@laser.satlink.net>
- * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
- * Tom May, <ftom@netcom.com>
- * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
- * Lots of code moved from tcp.c and ip.c; see those files
- * for more names.
- *
- * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:
- * Fixed some nasty bugs, causing some horrible crashes.
- * A: At some points, the sum (%0) was used as
- * length-counter instead of the length counter
- * (%1). Thanks to Roman Hodek for pointing this out.
- * B: GCC seems to mess up if one uses too many
- * data-registers to hold input values and one tries to
- * specify d0 and d1 as scratch registers. Letting gcc
- * choose these registers itself solves the problem.
- *
- * 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.
- */
-
-/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access
- kills, so most of the assembly has to go. */
-
-#include <linux/module.h>
-#include <net/checksum.h>
-
-#include <asm/byteorder.h>
-
-static inline unsigned short from32to16(unsigned long x)
-{
- /* add up 16-bit and 16-bit for 16+c bit */
- x = (x & 0xffff) + (x >> 16);
- /* add up carry.. */
- x = (x & 0xffff) + (x >> 16);
- return x;
-}
-
-static unsigned int do_csum(const unsigned char *buff, int len)
-{
- int odd, count;
- unsigned long result = 0;
-
- if (len <= 0)
- goto out;
- odd = 1 & (unsigned long) buff;
- if (odd) {
- result = *buff;
- len--;
- buff++;
- }
- count = len >> 1; /* nr of 16-bit words.. */
- if (count) {
- if (2 & (unsigned long) buff) {
- result += *(unsigned short *) buff;
- count--;
- len -= 2;
- buff += 2;
- }
- count >>= 1; /* nr of 32-bit words.. */
- if (count) {
- unsigned long carry = 0;
- do {
- unsigned long w = *(unsigned long *) buff;
- count--;
- buff += 4;
- result += carry;
- result += w;
- carry = (w > result);
- } while (count);
- result += carry;
- result = (result & 0xffff) + (result >> 16);
- }
- if (len & 2) {
- result += *(unsigned short *) buff;
- buff += 2;
- }
- }
- if (len & 1)
- result += (*buff << 8);
- result = from32to16(result);
- if (odd)
- result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
-out:
- return result;
-}
-
-/*
- * This is a version of ip_compute_csum() optimized for IP headers,
- * which always checksum on 4 octet boundaries.
- */
-__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
-{
- return (__force __sum16)~do_csum(iph, ihl*4);
-}
-EXPORT_SYMBOL(ip_fast_csum);
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-__wsum csum_partial(const void *buff, int len, __wsum wsum)
-{
- unsigned int sum = (__force unsigned int)wsum;
- unsigned int result = do_csum(buff, len);
-
- /* add in old sum, and carry.. */
- result += sum;
- if (sum > result)
- result += 1;
- return (__force __wsum)result;
-}
-EXPORT_SYMBOL(csum_partial);
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-__sum16 ip_compute_csum(const void *buff, int len)
-{
- return (__force __sum16)~do_csum(buff, len);
-}
-EXPORT_SYMBOL(ip_compute_csum);
-
-/*
- * copy from fs while checksumming, otherwise like csum_partial
- */
-__wsum
-csum_partial_copy_from_user(const void __user *src, void *dst, int len,
- __wsum sum, int *csum_err)
-{
- int missing;
-
- missing = __copy_from_user(dst, src, len);
- if (missing) {
- memset(dst + len - missing, 0, missing);
- *csum_err = -EFAULT;
- } else
- *csum_err = 0;
-
- return csum_partial(dst, len, sum);
-}
-EXPORT_SYMBOL(csum_partial_copy_from_user);
-
-/*
- * copy from ds while checksumming, otherwise like csum_partial
- */
-__wsum
-csum_partial_copy(const void *src, void *dst, int len, __wsum sum)
-{
- memcpy(dst, src, len);
- return csum_partial(dst, len, sum);
-}
-EXPORT_SYMBOL(csum_partial_copy);
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index b5a701c..8d92c4e 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -80,15 +80,15 @@
memory_size = memory_end - memory_start;
PAGE_OFFSET = memory_start;
printk(KERN_INFO "%s: Main mem: 0x%x-0x%x, "
- "size 0x%08x\n", __func__, memory_start,
- memory_end, memory_size);
+ "size 0x%08x\n", __func__, (u32) memory_start,
+ (u32) memory_end, (u32) memory_size);
break;
}
}
if (!memory_start || !memory_end) {
panic("%s: Missing memory setting 0x%08x-0x%08x\n",
- __func__, memory_start, memory_end);
+ __func__, (u32) memory_start, (u32) memory_end);
}
/* reservation of region where is the kernel */
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index 143a481..f9df720 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -39,8 +39,6 @@
/*
* macros/functions for gaining access to the thread information structure
- *
- * preempt_count needs to be 1 initially, until the scheduler is functional.
*/
#define INIT_THREAD_INFO(tsk) \
{ \
@@ -48,7 +46,7 @@
.exec_domain = &default_exec_domain, \
.flags = _TIF_FIXADE, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.restart_block = { \
.fn = do_no_restart_syscall, \
diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h
index e58b9a4..35d2ed6 100644
--- a/arch/mn10300/include/asm/pci.h
+++ b/arch/mn10300/include/asm/pci.h
@@ -70,10 +70,6 @@
*/
#define PCI_DMA_BUS_IS_PHYS (1)
-
-/* This is always fine. */
-#define pci_dac_dma_supported(pci_dev, mask) (0)
-
/* Return the index of the PCI controller for device. */
static inline int pci_controller_num(struct pci_dev *dev)
{
diff --git a/arch/mn10300/include/asm/thread_info.h b/arch/mn10300/include/asm/thread_info.h
index 78a3881..58d64f8 100644
--- a/arch/mn10300/include/asm/thread_info.h
+++ b/arch/mn10300/include/asm/thread_info.h
@@ -65,8 +65,6 @@
/*
* macros/functions for gaining access to the thread information structure
- *
- * preempt_count needs to be 1 initially, until the scheduler is functional.
*/
#ifndef __ASSEMBLY__
@@ -76,7 +74,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.restart_block = { \
.fn = do_no_restart_syscall, \
diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c
index 681ad8c..0dfdc50 100644
--- a/arch/mn10300/kernel/traps.c
+++ b/arch/mn10300/kernel/traps.c
@@ -136,8 +136,7 @@
unsigned long *stack, addr, module_start, module_end;
int i;
- printk(KERN_EMERG "\n"
- KERN_EMERG "Call Trace:");
+ printk(KERN_EMERG "\nCall Trace:");
stack = sp;
i = 0;
@@ -153,7 +152,7 @@
printk("\n");
#else
if ((i % 6) == 0)
- printk("\n" KERN_EMERG " ");
+ printk(KERN_EMERG " ");
printk("[<%08lx>] ", addr);
i++;
#endif
@@ -180,7 +179,7 @@
if (((long) stack & (THREAD_SIZE - 1)) == 0)
break;
if ((i % 8) == 0)
- printk("\n" KERN_EMERG " ");
+ printk(KERN_EMERG " ");
printk("%08lx ", *stack++);
}
@@ -264,8 +263,7 @@
show_stack(current, (unsigned long *) sp);
#if 0
- printk(KERN_EMERG "\n"
- KERN_EMERG "Code: ");
+ printk(KERN_EMERG "\nCode: ");
if (regs->pc < PAGE_OFFSET)
goto bad;
@@ -311,16 +309,14 @@
{
console_verbose();
spin_lock_irq(&die_lock);
- printk(KERN_EMERG "\n"
- KERN_EMERG "%s: %04x\n",
+ printk(KERN_EMERG "\n%s: %04x\n",
str, code & 0xffff);
show_registers(regs);
if (regs->pc >= 0x02000000 && regs->pc < 0x04000000 &&
(regs->epsw & (EPSW_IM | EPSW_IE)) != (EPSW_IM | EPSW_IE)) {
printk(KERN_EMERG "Exception in usermode interrupt handler\n");
- printk(KERN_EMERG "\n"
- KERN_EMERG " Please connect to kernel debugger !!\n");
+ printk(KERN_EMERG "\nPlease connect to kernel debugger !!\n");
asm volatile ("0: bra 0b");
}
@@ -429,9 +425,8 @@
{
console_verbose();
- printk(KERN_EMERG "\n"
- KERN_EMERG "Asynchronous I/O Bus Error\n"
- KERN_EMERG "==========================\n");
+ printk(KERN_EMERG "Asynchronous I/O Bus Error\n");
+ printk(KERN_EMERG "==========================\n");
if (bcberr & BCBERR_BEME)
printk(KERN_EMERG "- Multiple recorded errors\n");
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h
index 0407959..4ce0edf 100644
--- a/arch/parisc/include/asm/thread_info.h
+++ b/arch/parisc/include/asm/thread_info.h
@@ -23,7 +23,7 @@
.flags = 0, \
.cpu = 0, \
.addr_limit = KERNEL_DS, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall \
} \
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 61c0707..1f3aa8d 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -156,7 +156,7 @@
* software. The user has to press the button himself. */
printk(KERN_EMERG "System shut down completed.\n"
- KERN_EMERG "Please power this system off now.");
+ "Please power this system off now.");
}
void (*pm_power_off)(void) = machine_power_off;
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index c32f5d6..528f0ff 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -250,15 +250,14 @@
oops_enter();
/* Amuse the user in a SPARC fashion */
- if (err) printk(
-KERN_CRIT " _______________________________ \n"
-KERN_CRIT " < Your System ate a SPARC! Gah! >\n"
-KERN_CRIT " ------------------------------- \n"
-KERN_CRIT " \\ ^__^\n"
-KERN_CRIT " \\ (xx)\\_______\n"
-KERN_CRIT " (__)\\ )\\/\\\n"
-KERN_CRIT " U ||----w |\n"
-KERN_CRIT " || ||\n");
+ if (err) printk(KERN_CRIT
+ " _______________________________ \n"
+ " < Your System ate a SPARC! Gah! >\n"
+ " ------------------------------- \n"
+ " \\ ^__^\n"
+ " (__)\\ )\\/\\\n"
+ " U ||----w |\n"
+ " || ||\n");
/* unlock the pdc lock if necessary */
pdc_emergency_unlock();
@@ -797,7 +796,8 @@
else
printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ",
code);
- printk("pid=%d command='%s'\n", task_pid_nr(current), current->comm);
+ printk(KERN_CONT "pid=%d command='%s'\n",
+ task_pid_nr(current), current->comm);
show_regs(regs);
#endif
si.si_signo = SIGSEGV;
diff --git a/arch/powerpc/boot/dts/warp.dts b/arch/powerpc/boot/dts/warp.dts
index 01bfb56..31605ee 100644
--- a/arch/powerpc/boot/dts/warp.dts
+++ b/arch/powerpc/boot/dts/warp.dts
@@ -261,10 +261,11 @@
compatible = "gpio-leds";
green {
gpios = <&GPIO1 0 0>;
- default-state = "on";
+ default-state = "keep";
};
red {
gpios = <&GPIO1 1 0>;
+ default-state = "keep";
};
};
diff --git a/arch/powerpc/configs/44x/warp_defconfig b/arch/powerpc/configs/44x/warp_defconfig
index 3b77f09..787635f 100644
--- a/arch/powerpc/configs/44x/warp_defconfig
+++ b/arch/powerpc/configs/44x/warp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Fri Jan 23 07:57:16 2009
+# Linux kernel version: 2.6.30
+# Tue Jun 9 23:35:36 2009
#
# CONFIG_PPC64 is not set
@@ -41,6 +41,7 @@
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
CONFIG_PPC=y
CONFIG_EARLY_PRINTK=y
@@ -53,10 +54,12 @@
# CONFIG_GENERIC_TBSYNC is not set
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
# CONFIG_DEFAULT_UIMAGE is not set
CONFIG_PPC_DCR_NATIVE=y
# CONFIG_PPC_DCR_MMIO is not set
CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -74,7 +77,17 @@
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
@@ -82,27 +95,29 @@
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
# CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# 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_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_HOTPLUG is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -110,10 +125,13 @@
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -121,6 +139,7 @@
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -133,7 +152,6 @@
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -149,11 +167,6 @@
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -173,10 +186,11 @@
# CONFIG_ARCHES is not set
# CONFIG_CANYONLANDS is not set
# CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
# CONFIG_YOSEMITE is not set
# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
# CONFIG_PPC44x_SIMPLE is not set
-# CONFIG_PPC4xx_GPIO is not set
+CONFIG_PPC4xx_GPIO=y
CONFIG_440EP=y
CONFIG_IBM440EP_ERR42=y
# CONFIG_IPIC is not set
@@ -235,9 +249,13 @@
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_STDBINUTILS=y
CONFIG_PPC_4K_PAGES=y
# CONFIG_PPC_16K_PAGES is not set
# CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
CONFIG_FORCE_MAX_ZONEORDER=11
CONFIG_PROC_DEVICETREE=y
CONFIG_CMDLINE_BOOL=y
@@ -256,6 +274,7 @@
# CONFIG_PCI_DOMAINS is not set
# CONFIG_PCI_SYSCALL is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
# CONFIG_HAS_RAPIDIO is not set
#
@@ -271,14 +290,12 @@
CONFIG_KERNEL_START=0xc0000000
CONFIG_PHYSICAL_START=0x00000000
CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
CONFIG_CONSISTENT_SIZE=0x00200000
CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -353,6 +370,7 @@
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -365,7 +383,6 @@
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
# CONFIG_WIRELESS is not set
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
@@ -378,8 +395,12 @@
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_STANDALONE is not set
CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
@@ -471,13 +492,21 @@
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
#
# UBI - Unsorted block images
#
-# CONFIG_MTD_UBI is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
CONFIG_OF_DEVICE=y
+CONFIG_OF_GPIO=y
CONFIG_OF_I2C=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
@@ -495,10 +524,17 @@
# CONFIG_XILINX_SYSACE is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_AT24=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -529,7 +565,7 @@
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set
-CONFIG_SCSI_WAIT_SCAN=m
+# CONFIG_SCSI_WAIT_SCAN is not set
#
# SCSI Transports
@@ -541,10 +577,12 @@
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -554,6 +592,8 @@
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
CONFIG_IBM_NEW_EMAC=y
CONFIG_IBM_NEW_EMAC_RXB=128
CONFIG_IBM_NEW_EMAC_TXB=64
@@ -577,7 +617,6 @@
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -646,6 +685,7 @@
# CONFIG_HVC_UDBG is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_NVRAM is not set
# CONFIG_GEN_RTC is not set
# CONFIG_R3964 is not set
@@ -663,6 +703,7 @@
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
+# CONFIG_I2C_GPIO is not set
CONFIG_I2C_IBM_IIC=y
# CONFIG_I2C_MPC is not set
# CONFIG_I2C_OCORES is not set
@@ -685,12 +726,9 @@
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-CONFIG_EEPROM_AT24=y
-CONFIG_EEPROM_LEGACY=y
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -699,7 +737,30 @@
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
-# CONFIG_GPIOLIB is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_XILINX is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
@@ -721,6 +782,7 @@
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -735,11 +797,15 @@
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
@@ -785,6 +851,7 @@
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
@@ -870,11 +937,11 @@
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
@@ -915,7 +982,6 @@
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -929,6 +995,8 @@
#
# OTG and related infrastructure
#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
@@ -946,6 +1014,7 @@
#
# CONFIG_MMC_SDHCI is not set
# CONFIG_MMC_WBSD is not set
+CONFIG_MMC_PIKASD=y
# CONFIG_MEMSTICK is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
@@ -953,16 +1022,31 @@
#
# LED drivers
#
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_GPIO_PLATFORM is not set
+CONFIG_LEDS_GPIO_OF=y
+# CONFIG_LEDS_LP5521 is not set
# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
#
# LED Triggers
#
-# CONFIG_LEDS_TRIGGERS is not set
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
# CONFIG_ACCESSIBILITY is not set
# CONFIG_EDAC is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -973,6 +1057,7 @@
# 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 is not set
# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
@@ -993,6 +1078,11 @@
# CONFIG_FUSE_FS is not set
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
@@ -1039,6 +1129,12 @@
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1049,6 +1145,7 @@
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1060,7 +1157,6 @@
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1115,6 +1211,7 @@
# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_UTF8=y
# CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
@@ -1122,7 +1219,7 @@
CONFIG_BITREVERSE=y
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=y
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
CONFIG_CRC_T10DIF=y
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
@@ -1130,16 +1227,19 @@
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
#
# Kernel hacking
#
-# CONFIG_PRINTK_TIME is not set
+CONFIG_PRINTK_TIME=y
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
@@ -1152,11 +1252,15 @@
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_DEBUG_SLAB is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1180,9 +1284,12 @@
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -1190,24 +1297,27 @@
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
CONFIG_PRINT_STACK_DEPTH=64
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_CODE_PATCHING_SELFTEST is not set
# CONFIG_FTR_FIXUP_SELFTEST is not set
# CONFIG_MSI_BITMAP_SELFTEST is not set
# CONFIG_XMON is not set
CONFIG_IRQSTACKS=y
# CONFIG_VIRQ_DEBUG is not set
-CONFIG_BDI_SWITCH=y
+# CONFIG_BDI_SWITCH is not set
# CONFIG_PPC_EARLY_DEBUG is not set
#
@@ -1223,6 +1333,8 @@
# Crypto core or helper
#
# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
# CONFIG_CRYPTO_MANAGER is not set
# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
@@ -1294,13 +1406,15 @@
#
# Compression
#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
#
# Random Number Generation
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
# CONFIG_PPC_CLOCK is not set
# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/include/asm/delay.h b/arch/powerpc/include/asm/delay.h
index 1e2eb41..52e4d54 100644
--- a/arch/powerpc/include/asm/delay.h
+++ b/arch/powerpc/include/asm/delay.h
@@ -63,6 +63,8 @@
udelay(delay); \
else \
cpu_relax(); \
+ if (!__ret) \
+ __ret = (condition); \
__ret; \
})
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index 9aba5a3..c8b3292 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -46,15 +46,13 @@
/*
* macros/functions for gaining access to the thread information structure
- *
- * preempt_count needs to be 1 initially, until the scheduler is functional.
*/
#define INIT_THREAD_INFO(tsk) \
{ \
.task = &tsk, \
.exec_domain = &default_exec_domain, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
diff --git a/arch/powerpc/kernel/mpc7450-pmu.c b/arch/powerpc/kernel/mpc7450-pmu.c
index 75ff47f..c244133 100644
--- a/arch/powerpc/kernel/mpc7450-pmu.c
+++ b/arch/powerpc/kernel/mpc7450-pmu.c
@@ -10,7 +10,6 @@
*/
#include <linux/string.h>
#include <linux/perf_counter.h>
-#include <linux/string.h>
#include <asm/reg.h>
#include <asm/cputable.h>
diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c
index 5d755ef..5a9f5cb 100644
--- a/arch/powerpc/kernel/power7-pmu.c
+++ b/arch/powerpc/kernel/power7-pmu.c
@@ -358,6 +358,7 @@
.get_constraint = power7_get_constraint,
.get_alternatives = power7_get_alternatives,
.disable_pmc = power7_disable_pmc,
+ .flags = PPMU_ALT_SIPR,
.n_generic = ARRAY_SIZE(power7_generic_events),
.generic_events = power7_generic_events,
.cache_events = &power7_cache_events,
diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c
index 6637c87..833097a 100644
--- a/arch/powerpc/kernel/ppc970-pmu.c
+++ b/arch/powerpc/kernel/ppc970-pmu.c
@@ -10,7 +10,6 @@
*/
#include <linux/string.h>
#include <linux/perf_counter.h>
-#include <linux/string.h>
#include <asm/reg.h>
#include <asm/cputable.h>
diff --git a/arch/powerpc/mm/gup.c b/arch/powerpc/mm/gup.c
index bc400c7..bc122a1 100644
--- a/arch/powerpc/mm/gup.c
+++ b/arch/powerpc/mm/gup.c
@@ -159,7 +159,7 @@
int psize;
#endif
- pr_debug("%s(%lx,%x,%s)\n", __func__, start, nr_pages, write ? "write" : "read");
+ pr_devel("%s(%lx,%x,%s)\n", __func__, start, nr_pages, write ? "write" : "read");
start &= PAGE_MASK;
addr = start;
@@ -170,7 +170,7 @@
start, len)))
goto slow_irqon;
- pr_debug(" aligned: %lx .. %lx\n", start, end);
+ pr_devel(" aligned: %lx .. %lx\n", start, end);
#ifdef CONFIG_HUGETLB_PAGE
/* We bail out on slice boundary crossing when hugetlb is
@@ -234,7 +234,7 @@
do {
VM_BUG_ON(shift != mmu_psize_defs[get_slice_psize(mm, a)].shift);
ptep = huge_pte_offset(mm, a);
- pr_debug(" %016lx: huge ptep %p\n", a, ptep);
+ pr_devel(" %016lx: huge ptep %p\n", a, ptep);
if (!ptep || !gup_huge_pte(ptep, hstate, &a, end, write, pages,
&nr))
goto slow;
@@ -249,7 +249,7 @@
#ifdef CONFIG_PPC64
VM_BUG_ON(shift != mmu_psize_defs[get_slice_psize(mm, addr)].shift);
#endif
- pr_debug(" %016lx: normal pgd %p\n", addr,
+ pr_devel(" %016lx: normal pgd %p\n", addr,
(void *)pgd_val(pgd));
next = pgd_addr_end(addr, end);
if (pgd_none(pgd))
@@ -269,7 +269,7 @@
slow:
local_irq_enable();
slow_irqon:
- pr_debug(" slow path ! nr = %d\n", nr);
+ pr_devel(" slow path ! nr = %d\n", nr);
/* Try to get the remaining pages with get_user_pages */
start += nr << PAGE_SHIFT;
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index 8343986..92a1971 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -89,7 +89,7 @@
id = first_context;
continue;
}
- pr_debug("[%d] steal context %d from mm @%p\n",
+ pr_devel("[%d] steal context %d from mm @%p\n",
smp_processor_id(), id, mm);
/* Mark this mm has having no context anymore */
@@ -126,7 +126,7 @@
/* Pick up the victim mm */
mm = context_mm[id];
- pr_debug("[%d] steal context %d from mm @%p\n", cpu, id, mm);
+ pr_devel("[%d] steal context %d from mm @%p\n", cpu, id, mm);
/* Flush the TLB for that context */
local_flush_tlb_mm(mm);
@@ -180,7 +180,7 @@
spin_lock(&context_lock);
#ifndef DEBUG_STEAL_ONLY
- pr_debug("[%d] activating context for mm @%p, active=%d, id=%d\n",
+ pr_devel("[%d] activating context for mm @%p, active=%d, id=%d\n",
cpu, next, next->context.active, next->context.id);
#endif
@@ -189,7 +189,7 @@
next->context.active++;
if (prev) {
#ifndef DEBUG_STEAL_ONLY
- pr_debug(" old context %p active was: %d\n",
+ pr_devel(" old context %p active was: %d\n",
prev, prev->context.active);
#endif
WARN_ON(prev->context.active < 1);
@@ -236,7 +236,7 @@
next->context.id = id;
#ifndef DEBUG_STEAL_ONLY
- pr_debug("[%d] picked up new id %d, nrf is now %d\n",
+ pr_devel("[%d] picked up new id %d, nrf is now %d\n",
cpu, id, nr_free_contexts);
#endif
@@ -247,7 +247,7 @@
* local TLB for it and unmark it before we use it
*/
if (test_bit(id, stale_map[cpu])) {
- pr_debug("[%d] flushing stale context %d for mm @%p !\n",
+ pr_devel("[%d] flushing stale context %d for mm @%p !\n",
cpu, id, next);
local_flush_tlb_mm(next);
@@ -314,13 +314,13 @@
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
- pr_debug("MMU: Allocating stale context map for CPU %d\n", cpu);
+ pr_devel("MMU: Allocating stale context map for CPU %d\n", cpu);
stale_map[cpu] = kzalloc(CTX_MAP_SIZE, GFP_KERNEL);
break;
#ifdef CONFIG_HOTPLUG_CPU
case CPU_DEAD:
case CPU_DEAD_FROZEN:
- pr_debug("MMU: Freeing stale context map for CPU %d\n", cpu);
+ pr_devel("MMU: Freeing stale context map for CPU %d\n", cpu);
kfree(stale_map[cpu]);
stale_map[cpu] = NULL;
break;
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index ae1d67c..627767d 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -129,12 +129,12 @@
page = pfn_to_page(pfn);
if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) {
- pr_debug("do_dcache_icache_coherency... flushing\n");
+ pr_devel("do_dcache_icache_coherency... flushing\n");
flush_dcache_icache_page(page);
set_bit(PG_arch_1, &page->flags);
}
else
- pr_debug("do_dcache_icache_coherency... already clean\n");
+ pr_devel("do_dcache_icache_coherency... already clean\n");
return __pte(pte_val(pte) | _PAGE_HWEXEC);
}
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 3b52c80..5b7038f 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -14,8 +14,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#undef DEBUG
-
#include <asm/pgtable.h>
#include <asm/mmu.h>
#include <asm/mmu_context.h>
@@ -27,11 +25,6 @@
#include <linux/compiler.h>
#include <asm/udbg.h>
-#ifdef DEBUG
-#define DBG(fmt...) printk(fmt)
-#else
-#define DBG pr_debug
-#endif
extern void slb_allocate_realmode(unsigned long ea);
extern void slb_allocate_user(unsigned long ea);
@@ -285,13 +278,13 @@
patch_slb_encoding(slb_compare_rr_to_size,
mmu_slb_size);
- DBG("SLB: linear LLP = %04lx\n", linear_llp);
- DBG("SLB: io LLP = %04lx\n", io_llp);
+ pr_devel("SLB: linear LLP = %04lx\n", linear_llp);
+ pr_devel("SLB: io LLP = %04lx\n", io_llp);
#ifdef CONFIG_SPARSEMEM_VMEMMAP
patch_slb_encoding(slb_miss_kernel_load_vmemmap,
SLB_VSID_KERNEL | vmemmap_llp);
- DBG("SLB: vmemmap LLP = %04lx\n", vmemmap_llp);
+ pr_devel("SLB: vmemmap LLP = %04lx\n", vmemmap_llp);
#endif
}
diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c
index 1be1b5e..937eb90 100644
--- a/arch/powerpc/mm/tlb_hash64.c
+++ b/arch/powerpc/mm/tlb_hash64.c
@@ -72,7 +72,7 @@
*/
if (huge) {
#ifdef CONFIG_HUGETLB_PAGE
- psize = get_slice_psize(mm, addr);;
+ psize = get_slice_psize(mm, addr);
#else
BUG();
psize = pte_pagesize_index(mm, addr, pte); /* shutup gcc */
diff --git a/arch/powerpc/oprofile/cell/vma_map.c b/arch/powerpc/oprofile/cell/vma_map.c
index 258fa44..c591339 100644
--- a/arch/powerpc/oprofile/cell/vma_map.c
+++ b/arch/powerpc/oprofile/cell/vma_map.c
@@ -185,7 +185,7 @@
goto fail;
if (shdr_str.sh_type != SHT_STRTAB)
- goto fail;;
+ goto fail;
for (j = 0; j < shdr.sh_size / sizeof (sym); j++) {
if (copy_from_user(&sym, spu_elf_start +
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index 0362c88..e5c1b09 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -64,8 +64,6 @@
};
-static u32 post_info;
-
static int __init warp_post_info(void)
{
struct device_node *np;
@@ -87,10 +85,9 @@
iounmap(fpga);
- if (post1 || post2) {
+ if (post1 || post2)
printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
- post_info = 1;
- } else
+ else
printk(KERN_INFO "Warp POST OK\n");
return 0;
@@ -166,6 +163,9 @@
value ^= 1;
mdelay(500);
}
+
+ /* Not reached */
+ return IRQ_HANDLED;
}
static int pika_setup_leds(void)
@@ -179,15 +179,10 @@
}
for_each_child_of_node(np, child)
- if (strcmp(child->name, "green") == 0) {
+ if (strcmp(child->name, "green") == 0)
green_led = of_get_gpio(child, 0);
- /* Turn back on the green LED */
- gpio_set_value(green_led, 1);
- } else if (strcmp(child->name, "red") == 0) {
+ else if (strcmp(child->name, "red") == 0)
red_led = of_get_gpio(child, 0);
- /* Set based on post */
- gpio_set_value(red_led, post_info);
- }
of_node_put(np);
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index ddf0bdc..7ee979f 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -147,7 +147,7 @@
goto out;
}
- priv = alloc_bootmem(sizeof(struct pq2ads_pci_pic));
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
of_node_put(np);
ret = -ENOMEM;
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index c71498d..aca5741 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -85,7 +85,7 @@
static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
{
- pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
+ pr_devel("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
dcr_write(msic->dcr_host, dcr_n, val);
}
@@ -98,7 +98,7 @@
int retry = 0;
write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG);
- pr_debug("axon_msi: original write_offset 0x%x\n", write_offset);
+ pr_devel("axon_msi: original write_offset 0x%x\n", write_offset);
/* write_offset doesn't wrap properly, so we have to mask it */
write_offset &= MSIC_FIFO_SIZE_MASK;
@@ -108,7 +108,7 @@
msi = le32_to_cpu(msic->fifo_virt[idx]);
msi &= 0xFFFF;
- pr_debug("axon_msi: woff %x roff %x msi %x\n",
+ pr_devel("axon_msi: woff %x roff %x msi %x\n",
write_offset, msic->read_offset, msi);
if (msi < NR_IRQS && irq_map[msi].host == msic->irq_host) {
@@ -123,12 +123,12 @@
*/
udelay(1);
retry++;
- pr_debug("axon_msi: invalid irq 0x%x!\n", msi);
+ pr_devel("axon_msi: invalid irq 0x%x!\n", msi);
continue;
}
if (retry) {
- pr_debug("axon_msi: late irq 0x%x, retry %d\n",
+ pr_devel("axon_msi: late irq 0x%x, retry %d\n",
msi, retry);
retry = 0;
}
@@ -332,7 +332,7 @@
struct axon_msic *msic = dev_get_drvdata(&device->dev);
u32 tmp;
- pr_debug("axon_msi: disabling %s\n",
+ pr_devel("axon_msi: disabling %s\n",
msic->irq_host->of_node->full_name);
tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
@@ -349,7 +349,7 @@
unsigned int virq;
int dcr_base, dcr_len;
- pr_debug("axon_msi: setting up dn %s\n", dn->full_name);
+ pr_devel("axon_msi: setting up dn %s\n", dn->full_name);
msic = kzalloc(sizeof(struct axon_msic), GFP_KERNEL);
if (!msic) {
@@ -403,7 +403,7 @@
set_irq_data(virq, msic);
set_irq_chained_handler(virq, axon_msi_cascade);
- pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq);
+ pr_devel("axon_msi: irq 0x%x setup for axon_msi\n", virq);
/* Enable the MSIC hardware */
msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, msic->fifo_phys >> 32);
@@ -484,13 +484,13 @@
addr = of_translate_address(dn, of_get_property(dn, "reg", NULL));
if (addr == OF_BAD_ADDR) {
- pr_debug("axon_msi: couldn't translate reg property\n");
+ pr_devel("axon_msi: couldn't translate reg property\n");
return;
}
msic->trigger = ioremap(addr, 0x4);
if (!msic->trigger) {
- pr_debug("axon_msi: ioremap failed\n");
+ pr_devel("axon_msi: ioremap failed\n");
return;
}
@@ -498,7 +498,7 @@
if (!debugfs_create_file(name, 0600, powerpc_debugfs_root,
msic, &fops_msic)) {
- pr_debug("axon_msi: debugfs_create_file failed!\n");
+ pr_devel("axon_msi: debugfs_create_file failed!\n");
return;
}
}
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index 22ecfbe..708c751 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -251,7 +251,7 @@
static struct pmf_function *pfunc_cpu_setfreq_high;
static struct pmf_function *pfunc_cpu_setfreq_low;
static struct pmf_function *pfunc_cpu_getfreq;
-static struct pmf_function *pfunc_slewing_done;;
+static struct pmf_function *pfunc_slewing_done;
static int g5_pfunc_switch_freq(int speed_mode)
{
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index dce7363..d212006 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -609,7 +609,7 @@
np = of_find_node_by_name(NULL, "via-pmu");
if (np == NULL)
goto not_found;
- viaint = irq_of_parse_and_map(np, 0);;
+ viaint = irq_of_parse_and_map(np, 0);
not_found:
#endif /* CONFIG_ADB_PMU */
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 9fead0f..3f763c5 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -284,7 +284,6 @@
int result;
dump_mmio_region(r);
-;
result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
r->lpar_addr);
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index e3139fa..903eb9e 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -286,7 +286,7 @@
unsigned long hpte_v, hpte_r;
if (!(vflags & HPTE_V_BOLTED))
- pr_debug("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
+ pr_devel("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
"rflags=%lx, vflags=%lx, psize=%d)\n",
hpte_group, va, pa, rflags, vflags, psize);
@@ -294,7 +294,7 @@
hpte_r = hpte_encode_r(pa, psize) | rflags;
if (!(vflags & HPTE_V_BOLTED))
- pr_debug(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
+ pr_devel(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
/* Now fill in the actual HPTE */
/* Set CEC cookie to 0 */
@@ -311,7 +311,7 @@
lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot);
if (unlikely(lpar_rc == H_PTEG_FULL)) {
if (!(vflags & HPTE_V_BOLTED))
- pr_debug(" full\n");
+ pr_devel(" full\n");
return -1;
}
@@ -322,11 +322,11 @@
*/
if (unlikely(lpar_rc != H_SUCCESS)) {
if (!(vflags & HPTE_V_BOLTED))
- pr_debug(" lpar err %lu\n", lpar_rc);
+ pr_devel(" lpar err %lu\n", lpar_rc);
return -2;
}
if (!(vflags & HPTE_V_BOLTED))
- pr_debug(" -> slot: %lu\n", slot & 7);
+ pr_devel(" -> slot: %lu\n", slot & 7);
/* Because of iSeries, we have to pass down the secondary
* bucket bit here as well
@@ -418,17 +418,17 @@
want_v = hpte_encode_avpn(va, psize, ssize);
- pr_debug(" update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...",
+ pr_devel(" update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...",
want_v, slot, flags, psize);
lpar_rc = plpar_pte_protect(flags, slot, want_v);
if (lpar_rc == H_NOT_FOUND) {
- pr_debug("not found !\n");
+ pr_devel("not found !\n");
return -1;
}
- pr_debug("ok\n");
+ pr_devel("ok\n");
BUG_ON(lpar_rc != H_SUCCESS);
@@ -503,7 +503,7 @@
unsigned long lpar_rc;
unsigned long dummy1, dummy2;
- pr_debug(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
+ pr_devel(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
slot, va, psize, local);
want_v = hpte_encode_avpn(va, psize, ssize);
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index be3581a..419f8a6 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -190,10 +190,10 @@
int call_status;
int server;
- pr_debug("xics: unmask virq %d\n", virq);
+ pr_devel("xics: unmask virq %d\n", virq);
irq = (unsigned int)irq_map[virq].hwirq;
- pr_debug(" -> map to hwirq 0x%x\n", irq);
+ pr_devel(" -> map to hwirq 0x%x\n", irq);
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
return;
@@ -252,7 +252,7 @@
{
unsigned int irq;
- pr_debug("xics: mask virq %d\n", virq);
+ pr_devel("xics: mask virq %d\n", virq);
irq = (unsigned int)irq_map[virq].hwirq;
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
@@ -414,7 +414,7 @@
static int xics_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
- pr_debug("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
+ pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
/* Insert the interrupt mapping into the radix tree for fast lookup */
irq_radix_revmap_insert(xics_host, virq, hw);
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 39db9d1..cbb3bed 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -965,7 +965,7 @@
break;
default:
str = "Unknown";
- break;;
+ break;
}
dev_info(dev, "Hardware port width: %s\n", str);
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index a86d3ce..69e2630 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -728,12 +728,10 @@
if (ret)
return NULL;
- ipic = alloc_bootmem(sizeof(struct ipic));
+ ipic = kzalloc(sizeof(*ipic), GFP_KERNEL);
if (ipic == NULL)
return NULL;
- memset(ipic, 0, sizeof(struct ipic));
-
ipic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
NR_IPIC_INTS,
&ipic_host_ops, 0);
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index d46de1f..3981ae4 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -508,9 +508,8 @@
printk(KERN_INFO "mpic: Setting up HT PICs workarounds for U3/U4\n");
/* Allocate fixups array */
- mpic->fixups = alloc_bootmem(128 * sizeof(struct mpic_irq_fixup));
+ mpic->fixups = kzalloc(128 * sizeof(*mpic->fixups), GFP_KERNEL);
BUG_ON(mpic->fixups == NULL);
- memset(mpic->fixups, 0, 128 * sizeof(struct mpic_irq_fixup));
/* Init spinlock */
spin_lock_init(&mpic->fixup_lock);
@@ -1109,9 +1108,8 @@
psize /= 4;
bits = intvec_top + 1;
mapsize = BITS_TO_LONGS(bits) * sizeof(unsigned long);
- mpic->protected = alloc_bootmem(mapsize);
+ mpic->protected = kzalloc(mapsize, GFP_KERNEL);
BUG_ON(mpic->protected == NULL);
- memset(mpic->protected, 0, mapsize);
for (i = 0; i < psize; i++) {
if (psrc[i] > intvec_top)
continue;
@@ -1353,7 +1351,8 @@
#ifdef CONFIG_PM
/* allocate memory to save mpic state */
- mpic->save_data = alloc_bootmem(mpic->num_sources * sizeof(struct mpic_irq_save));
+ mpic->save_data = kmalloc(mpic->num_sources * sizeof(*mpic->save_data),
+ GFP_KERNEL);
BUG_ON(mpic->save_data == NULL);
#endif
}
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index daefc93..6ff9d71 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -1531,7 +1531,7 @@
*/
/* Calculate window size */
- sa = (0xffffffffffffffffull << ilog2(ep_size));;
+ sa = (0xffffffffffffffffull << ilog2(ep_size));
/* Setup BAR0 */
out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa));
@@ -1550,7 +1550,7 @@
out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(ep_addr));
} else {
/* Calculate window size */
- sa = (0xffffffffffffffffull << ilog2(size));;
+ sa = (0xffffffffffffffffull << ilog2(size));
if (res->flags & IORESOURCE_PREFETCH)
sa |= 0x8;
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 63cdf98..074905c 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -333,12 +333,10 @@
if (ret)
return;
- qe_ic = alloc_bootmem(sizeof(struct qe_ic));
+ qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL);
if (qe_ic == NULL)
return;
- memset(qe_ic, 0, sizeof(struct qe_ic));
-
qe_ic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
NR_QE_IC_INTS, &qe_ic_host_ops, 0);
if (qe_ic->irqhost == NULL)
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index d35405c..466ce9a 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -258,11 +258,10 @@
BUG_ON(! of_device_is_compatible(node, "ibm,uic"));
- uic = alloc_bootmem(sizeof(*uic));
+ uic = kzalloc(sizeof(*uic), GFP_KERNEL);
if (! uic)
return NULL; /* FIXME: panic? */
- memset(uic, 0, sizeof(*uic));
spin_lock_init(&uic->lock);
indexp = of_get_property(node, "cell-index", &len);
if (!indexp || (len != sizeof(u32))) {
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index 925bcc6..ba1cab9 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -61,7 +61,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index c050a8d..8fed45a 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -19,6 +19,7 @@
#include <linux/smc91x.h>
#include <linux/gpio.h>
#include <linux/input.h>
+#include <linux/usb/r8a66597.h>
#include <video/sh_mobile_lcdc.h>
#include <media/sh_mobile_ceu.h>
#include <asm/io.h>
@@ -302,6 +303,34 @@
.resource = sh_eth_resources,
};
+static struct r8a66597_platdata sh7724_usb0_host_data = {
+};
+
+static struct resource sh7724_usb0_host_resources[] = {
+ [0] = {
+ .start = 0xa4d80000,
+ .end = 0xa4d800ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 65,
+ .end = 65,
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct platform_device sh7724_usb0_host_device = {
+ .name = "r8a66597_hcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL, /* not use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sh7724_usb0_host_data,
+ },
+ .num_resources = ARRAY_SIZE(sh7724_usb0_host_resources),
+ .resource = sh7724_usb0_host_resources,
+};
+
static struct platform_device *ms7724se_devices[] __initdata = {
&heartbeat_device,
&smc91x_eth_device,
@@ -311,6 +340,7 @@
&ceu1_device,
&keysc_device,
&sh_eth_device,
+ &sh7724_usb0_host_device,
};
#define EEPROM_OP 0xBA206000
@@ -364,6 +394,7 @@
#define SW4140 0xBA201000
#define FPGA_OUT 0xBA200400
#define PORT_HIZA 0xA4050158
+#define PORT_MSELCRB 0xA4050182
#define SW41_A 0x0100
#define SW41_B 0x0200
@@ -373,6 +404,7 @@
#define SW41_F 0x2000
#define SW41_G 0x4000
#define SW41_H 0x8000
+
static int __init devices_setup(void)
{
u16 sw = ctrl_inw(SW4140); /* select camera, monitor */
@@ -385,6 +417,12 @@
(1 << 14)), /* RMII */
FPGA_OUT);
+ /* turn on USB clocks, use external clock */
+ ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
+
+ /* enable USB0 port */
+ ctrl_outw(0x0600, 0xa40501d4);
+
/* enable IRQ 0,1,2 */
gpio_request(GPIO_FN_INTC_IRQ0, NULL);
gpio_request(GPIO_FN_INTC_IRQ1, NULL);
diff --git a/arch/sh/include/asm/perf_counter.h b/arch/sh/include/asm/perf_counter.h
index 61c2b40..d8e6bb9 100644
--- a/arch/sh/include/asm/perf_counter.h
+++ b/arch/sh/include/asm/perf_counter.h
@@ -4,4 +4,6 @@
/* SH only supports software counters through this interface. */
static inline void set_perf_counter_pending(void) {}
+#define PERF_COUNTER_INDEX_OFFSET 0
+
#endif /* __ASM_SH_PERF_COUNTER_H */
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h
index f09ac48..d570ac2 100644
--- a/arch/sh/include/asm/thread_info.h
+++ b/arch/sh/include/asm/thread_info.h
@@ -51,7 +51,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.restart_block = { \
.fn = do_no_restart_syscall, \
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h
index 0f7b0e5..844d73a 100644
--- a/arch/sparc/include/asm/thread_info_32.h
+++ b/arch/sparc/include/asm/thread_info_32.h
@@ -54,8 +54,6 @@
/*
* macros/functions for gaining access to the thread information structure
- *
- * preempt_count needs to be 1 initially, until the scheduler is functional.
*/
#define INIT_THREAD_INFO(tsk) \
{ \
@@ -64,7 +62,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 6586572..1b45a7b 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -125,8 +125,6 @@
/*
* macros/functions for gaining access to the thread information structure
- *
- * preempt_count needs to be 1 initially, until the scheduler is functional.
*/
#ifndef __ASSEMBLY__
@@ -135,7 +133,7 @@
.task = &tsk, \
.flags = ((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT, \
.exec_domain = &default_exec_domain, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h
index 62274ab..fd911f8 100644
--- a/arch/um/include/asm/thread_info.h
+++ b/arch/um/include/asm/thread_info.h
@@ -32,7 +32,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.restart_block = { \
.fn = do_no_restart_syscall, \
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index 56d43d0..0960de5 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -70,8 +70,8 @@
if (kstack_end(stack))
break;
if (i && ((i % 8) == 0))
- printk("\n" KERN_INFO " ");
- printk("%08lx ", *stack++);
+ printk(KERN_INFO " ");
+ printk(KERN_CONT "%08lx ", *stack++);
}
show_trace(task, esp);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c07f722..738bdc6 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1913,6 +1913,18 @@
recommended you say N here while the DMAR code remains
experimental.
+config DMAR_BROKEN_GFX_WA
+ def_bool n
+ prompt "Workaround broken graphics drivers (going away soon)"
+ depends on DMAR
+ ---help---
+ Current Graphics drivers tend to use physical address
+ for DMA and avoid using DMA APIs. Setting this config
+ option permits the IOMMU driver to set a unity map for
+ all the OS-visible memory. Hence the driver can continue
+ to use physical addresses for DMA, at least until this
+ option is removed in the 2.6.32 kernel.
+
config DMAR_FLOPPY_WA
def_bool y
depends on DMAR
diff --git a/arch/x86/boot/video-bios.c b/arch/x86/boot/video-bios.c
index d660be4..49e0c18 100644
--- a/arch/x86/boot/video-bios.c
+++ b/arch/x86/boot/video-bios.c
@@ -37,14 +37,13 @@
ireg.al = mode; /* AH=0x00 Set Video Mode */
intcall(0x10, &ireg, NULL);
-
ireg.ah = 0x0f; /* Get Current Video Mode */
intcall(0x10, &ireg, &oreg);
do_restore = 1; /* Assume video contents were lost */
/* Not all BIOSes are clean with the top bit */
- new_mode = ireg.al & 0x7f;
+ new_mode = oreg.al & 0x7f;
if (new_mode == mode)
return 0; /* Mode change OK */
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
index c700147..275dd17 100644
--- a/arch/x86/boot/video-vesa.c
+++ b/arch/x86/boot/video-vesa.c
@@ -45,7 +45,7 @@
ireg.di = (size_t)&vginfo;
intcall(0x10, &ireg, &oreg);
- if (ireg.ax != 0x004f ||
+ if (oreg.ax != 0x004f ||
vginfo.signature != VESA_MAGIC ||
vginfo.version < 0x0102)
return 0; /* Not present */
@@ -70,7 +70,7 @@
ireg.di = (size_t)&vminfo;
intcall(0x10, &ireg, &oreg);
- if (ireg.ax != 0x004f)
+ if (oreg.ax != 0x004f)
continue;
if ((vminfo.mode_attr & 0x15) == 0x05) {
diff --git a/arch/x86/include/asm/atomic_32.h b/arch/x86/include/asm/atomic_32.h
index 2503d4e..dc5a667 100644
--- a/arch/x86/include/asm/atomic_32.h
+++ b/arch/x86/include/asm/atomic_32.h
@@ -19,7 +19,10 @@
*
* Atomically reads the value of @v.
*/
-#define atomic_read(v) ((v)->counter)
+static inline int atomic_read(const atomic_t *v)
+{
+ return v->counter;
+}
/**
* atomic_set - set atomic variable
@@ -28,7 +31,10 @@
*
* Atomically sets the value of @v to @i.
*/
-#define atomic_set(v, i) (((v)->counter) = (i))
+static inline void atomic_set(atomic_t *v, int i)
+{
+ v->counter = i;
+}
/**
* atomic_add - add integer to atomic variable
@@ -200,8 +206,15 @@
return atomic_add_return(-i, v);
}
-#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
-#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+ return cmpxchg(&v->counter, old, new);
+}
+
+static inline int atomic_xchg(atomic_t *v, int new)
+{
+ return xchg(&v->counter, new);
+}
/**
* atomic_add_unless - add unless the number is already a given value
@@ -250,45 +263,12 @@
/* An 64bit atomic type */
typedef struct {
- unsigned long long counter;
+ u64 __aligned(8) counter;
} atomic64_t;
#define ATOMIC64_INIT(val) { (val) }
-/**
- * atomic64_read - read atomic64 variable
- * @ptr: pointer of type atomic64_t
- *
- * Atomically reads the value of @v.
- * Doesn't imply a read memory barrier.
- */
-#define __atomic64_read(ptr) ((ptr)->counter)
-
-static inline unsigned long long
-cmpxchg8b(unsigned long long *ptr, unsigned long long old, unsigned long long new)
-{
- asm volatile(
-
- LOCK_PREFIX "cmpxchg8b (%[ptr])\n"
-
- : "=A" (old)
-
- : [ptr] "D" (ptr),
- "A" (old),
- "b" (ll_low(new)),
- "c" (ll_high(new))
-
- : "memory");
-
- return old;
-}
-
-static inline unsigned long long
-atomic64_cmpxchg(atomic64_t *ptr, unsigned long long old_val,
- unsigned long long new_val)
-{
- return cmpxchg8b(&ptr->counter, old_val, new_val);
-}
+extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val);
/**
* atomic64_xchg - xchg atomic64 variable
@@ -298,18 +278,7 @@
* Atomically xchgs the value of @ptr to @new_val and returns
* the old value.
*/
-
-static inline unsigned long long
-atomic64_xchg(atomic64_t *ptr, unsigned long long new_val)
-{
- unsigned long long old_val;
-
- do {
- old_val = atomic_read(ptr);
- } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val);
-
- return old_val;
-}
+extern u64 atomic64_xchg(atomic64_t *ptr, u64 new_val);
/**
* atomic64_set - set atomic64 variable
@@ -318,10 +287,7 @@
*
* Atomically sets the value of @ptr to @new_val.
*/
-static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val)
-{
- atomic64_xchg(ptr, new_val);
-}
+extern void atomic64_set(atomic64_t *ptr, u64 new_val);
/**
* atomic64_read - read atomic64 variable
@@ -329,17 +295,30 @@
*
* Atomically reads the value of @ptr and returns it.
*/
-static inline unsigned long long atomic64_read(atomic64_t *ptr)
+static inline u64 atomic64_read(atomic64_t *ptr)
{
- unsigned long long curr_val;
+ u64 res;
- do {
- curr_val = __atomic64_read(ptr);
- } while (atomic64_cmpxchg(ptr, curr_val, curr_val) != curr_val);
+ /*
+ * Note, we inline this atomic64_t primitive because
+ * it only clobbers EAX/EDX and leaves the others
+ * untouched. We also (somewhat subtly) rely on the
+ * fact that cmpxchg8b returns the current 64-bit value
+ * of the memory location we are touching:
+ */
+ asm volatile(
+ "mov %%ebx, %%eax\n\t"
+ "mov %%ecx, %%edx\n\t"
+ LOCK_PREFIX "cmpxchg8b %1\n"
+ : "=&A" (res)
+ : "m" (*ptr)
+ );
- return curr_val;
+ return res;
}
+extern u64 atomic64_read(atomic64_t *ptr);
+
/**
* atomic64_add_return - add and return
* @delta: integer value to add
@@ -347,34 +326,14 @@
*
* Atomically adds @delta to @ptr and returns @delta + *@ptr
*/
-static inline unsigned long long
-atomic64_add_return(unsigned long long delta, atomic64_t *ptr)
-{
- unsigned long long old_val, new_val;
+extern u64 atomic64_add_return(u64 delta, atomic64_t *ptr);
- do {
- old_val = atomic_read(ptr);
- new_val = old_val + delta;
-
- } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val);
-
- return new_val;
-}
-
-static inline long atomic64_sub_return(unsigned long long delta, atomic64_t *ptr)
-{
- return atomic64_add_return(-delta, ptr);
-}
-
-static inline long atomic64_inc_return(atomic64_t *ptr)
-{
- return atomic64_add_return(1, ptr);
-}
-
-static inline long atomic64_dec_return(atomic64_t *ptr)
-{
- return atomic64_sub_return(1, ptr);
-}
+/*
+ * Other variants with different arithmetic operators:
+ */
+extern u64 atomic64_sub_return(u64 delta, atomic64_t *ptr);
+extern u64 atomic64_inc_return(atomic64_t *ptr);
+extern u64 atomic64_dec_return(atomic64_t *ptr);
/**
* atomic64_add - add integer to atomic64 variable
@@ -383,10 +342,7 @@
*
* Atomically adds @delta to @ptr.
*/
-static inline void atomic64_add(unsigned long long delta, atomic64_t *ptr)
-{
- atomic64_add_return(delta, ptr);
-}
+extern void atomic64_add(u64 delta, atomic64_t *ptr);
/**
* atomic64_sub - subtract the atomic64 variable
@@ -395,10 +351,7 @@
*
* Atomically subtracts @delta from @ptr.
*/
-static inline void atomic64_sub(unsigned long long delta, atomic64_t *ptr)
-{
- atomic64_add(-delta, ptr);
-}
+extern void atomic64_sub(u64 delta, atomic64_t *ptr);
/**
* atomic64_sub_and_test - subtract value from variable and test result
@@ -409,13 +362,7 @@
* true if the result is zero, or false for all
* other cases.
*/
-static inline int
-atomic64_sub_and_test(unsigned long long delta, atomic64_t *ptr)
-{
- unsigned long long old_val = atomic64_sub_return(delta, ptr);
-
- return old_val == 0;
-}
+extern int atomic64_sub_and_test(u64 delta, atomic64_t *ptr);
/**
* atomic64_inc - increment atomic64 variable
@@ -423,10 +370,7 @@
*
* Atomically increments @ptr by 1.
*/
-static inline void atomic64_inc(atomic64_t *ptr)
-{
- atomic64_add(1, ptr);
-}
+extern void atomic64_inc(atomic64_t *ptr);
/**
* atomic64_dec - decrement atomic64 variable
@@ -434,10 +378,7 @@
*
* Atomically decrements @ptr by 1.
*/
-static inline void atomic64_dec(atomic64_t *ptr)
-{
- atomic64_sub(1, ptr);
-}
+extern void atomic64_dec(atomic64_t *ptr);
/**
* atomic64_dec_and_test - decrement and test
@@ -447,10 +388,7 @@
* returns true if the result is 0, or false for all other
* cases.
*/
-static inline int atomic64_dec_and_test(atomic64_t *ptr)
-{
- return atomic64_sub_and_test(1, ptr);
-}
+extern int atomic64_dec_and_test(atomic64_t *ptr);
/**
* atomic64_inc_and_test - increment and test
@@ -460,10 +398,7 @@
* and returns true if the result is zero, or false for all
* other cases.
*/
-static inline int atomic64_inc_and_test(atomic64_t *ptr)
-{
- return atomic64_sub_and_test(-1, ptr);
-}
+extern int atomic64_inc_and_test(atomic64_t *ptr);
/**
* atomic64_add_negative - add and test if negative
@@ -474,13 +409,7 @@
* if the result is negative, or false when
* result is greater than or equal to zero.
*/
-static inline int
-atomic64_add_negative(unsigned long long delta, atomic64_t *ptr)
-{
- long long old_val = atomic64_add_return(delta, ptr);
-
- return old_val < 0;
-}
+extern int atomic64_add_negative(u64 delta, atomic64_t *ptr);
#include <asm-generic/atomic-long.h>
#endif /* _ASM_X86_ATOMIC_32_H */
diff --git a/arch/x86/include/asm/atomic_64.h b/arch/x86/include/asm/atomic_64.h
index 0d63602..d605dc2 100644
--- a/arch/x86/include/asm/atomic_64.h
+++ b/arch/x86/include/asm/atomic_64.h
@@ -18,7 +18,10 @@
*
* Atomically reads the value of @v.
*/
-#define atomic_read(v) ((v)->counter)
+static inline int atomic_read(const atomic_t *v)
+{
+ return v->counter;
+}
/**
* atomic_set - set atomic variable
@@ -27,7 +30,10 @@
*
* Atomically sets the value of @v to @i.
*/
-#define atomic_set(v, i) (((v)->counter) = (i))
+static inline void atomic_set(atomic_t *v, int i)
+{
+ v->counter = i;
+}
/**
* atomic_add - add integer to atomic variable
@@ -192,7 +198,10 @@
* Atomically reads the value of @v.
* Doesn't imply a read memory barrier.
*/
-#define atomic64_read(v) ((v)->counter)
+static inline long atomic64_read(const atomic64_t *v)
+{
+ return v->counter;
+}
/**
* atomic64_set - set atomic64 variable
@@ -201,7 +210,10 @@
*
* Atomically sets the value of @v to @i.
*/
-#define atomic64_set(v, i) (((v)->counter) = (i))
+static inline void atomic64_set(atomic64_t *v, long i)
+{
+ v->counter = i;
+}
/**
* atomic64_add - add integer to atomic64 variable
@@ -355,11 +367,25 @@
#define atomic64_inc_return(v) (atomic64_add_return(1, (v)))
#define atomic64_dec_return(v) (atomic64_sub_return(1, (v)))
-#define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
-#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new)
+{
+ return cmpxchg(&v->counter, old, new);
+}
-#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
-#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
+static inline long atomic64_xchg(atomic64_t *v, long new)
+{
+ return xchg(&v->counter, new);
+}
+
+static inline long atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+ return cmpxchg(&v->counter, old, new);
+}
+
+static inline long atomic_xchg(atomic_t *v, int new)
+{
+ return xchg(&v->counter, new);
+}
/**
* atomic_add_unless - add unless the number is a given value
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 2d81af3..7b2d71d 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -111,12 +111,9 @@
#ifdef CONFIG_PARAVIRT
FIX_PARAVIRT_BOOTMAP,
#endif
- FIX_TEXT_POKE0, /* reserve 2 pages for text_poke() */
- FIX_TEXT_POKE1,
+ FIX_TEXT_POKE1, /* reserve 2 pages for text_poke() */
+ FIX_TEXT_POKE0, /* first page is last, because allocation is backward */
__end_of_permanent_fixed_addresses,
-#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
- FIX_OHCI1394_BASE,
-#endif
/*
* 256 temporary boot-time mappings, used by early_ioremap(),
* before ioremap() is functional.
@@ -129,6 +126,9 @@
FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
(__end_of_permanent_fixed_addresses & 255),
FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1,
+#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
+ FIX_OHCI1394_BASE,
+#endif
#ifdef CONFIG_X86_32
FIX_WP_TEST,
#endif
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 1692fb5..6be7fc2 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -246,10 +246,6 @@
#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38)
#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39)
-/* Intel Model 6 */
-#define MSR_P6_EVNTSEL0 0x00000186
-#define MSR_P6_EVNTSEL1 0x00000187
-
/* P4/Xeon+ specific */
#define MSR_IA32_MCG_EAX 0x00000180
#define MSR_IA32_MCG_EBX 0x00000181
diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h
index c972644..c86e5ed4 100644
--- a/arch/x86/include/asm/nmi.h
+++ b/arch/x86/include/asm/nmi.h
@@ -72,7 +72,6 @@
int lapic_watchdog_init(unsigned nmi_hz);
int lapic_wd_event(unsigned nmi_hz);
unsigned lapic_adjust_nmi_hz(unsigned hz);
-int lapic_watchdog_ok(void);
void disable_lapic_nmi_watchdog(void);
void enable_lapic_nmi_watchdog(void);
void stop_nmi(void);
diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h
index b7e5db8..4e77853 100644
--- a/arch/x86/include/asm/spinlock.h
+++ b/arch/x86/include/asm/spinlock.h
@@ -302,4 +302,8 @@
#define _raw_read_relax(lock) cpu_relax()
#define _raw_write_relax(lock) cpu_relax()
+/* The {read|write|spin}_lock() on x86 are full memory barriers. */
+static inline void smp_mb__after_lock(void) { }
+#define ARCH_HAS_SMP_MB_AFTER_LOCK
+
#endif /* _ASM_X86_SPINLOCK_H */
diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
index f517944..cf86a5e 100644
--- a/arch/x86/include/asm/stacktrace.h
+++ b/arch/x86/include/asm/stacktrace.h
@@ -3,6 +3,8 @@
extern int kstack_depth_to_print;
+int x86_is_stack_id(int id, char *name);
+
/* Generic stack tracer with callbacks */
struct stacktrace_ops {
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index b078352..fad7d40 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -49,7 +49,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.restart_block = { \
.fn = do_no_restart_syscall, \
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 6c327b8..430d5b2 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -26,6 +26,8 @@
CFLAGS_paravirt.o := $(nostackp)
GCOV_PROFILE_vsyscall_64.o := n
GCOV_PROFILE_hpet.o := n
+GCOV_PROFILE_tsc.o := n
+GCOV_PROFILE_paravirt.o := n
obj-y := process_$(BITS).o signal.o entry_$(BITS).o
obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 9372f04..6c99f50 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1192,7 +1192,7 @@
return 0;
}
-struct notifier_block device_nb = {
+static struct notifier_block device_nb = {
.notifier_call = device_change_notifier,
};
@@ -1763,7 +1763,7 @@
flag |= __GFP_ZERO;
virt_addr = (void *)__get_free_pages(flag, get_order(size));
if (!virt_addr)
- return 0;
+ return NULL;
paddr = virt_to_phys(virt_addr);
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 10b2acc..c1b17e9 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -472,6 +472,8 @@
if (iommu->evt_buf == NULL)
return NULL;
+ iommu->evt_buf_size = EVT_BUFFER_SIZE;
+
return iommu->evt_buf;
}
@@ -691,6 +693,7 @@
devid = e->devid;
devid_to = e->ext >> 8;
+ set_dev_entry_from_acpi(iommu, devid , e->flags, 0);
set_dev_entry_from_acpi(iommu, devid_to, e->flags, 0);
amd_iommu_alias_table[devid] = devid_to;
break;
@@ -749,11 +752,13 @@
devid = e->devid;
for (dev_i = devid_start; dev_i <= devid; ++dev_i) {
- if (alias)
+ if (alias) {
amd_iommu_alias_table[dev_i] = devid_to;
- set_dev_entry_from_acpi(iommu,
- amd_iommu_alias_table[dev_i],
- flags, ext_flags);
+ set_dev_entry_from_acpi(iommu,
+ devid_to, flags, ext_flags);
+ }
+ set_dev_entry_from_acpi(iommu, dev_i,
+ flags, ext_flags);
}
break;
default:
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 8c7c042..0a1c283 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -140,7 +140,6 @@
#ifdef CONFIG_X86_X2APIC
/* x2apic enabled before OS handover */
static int x2apic_preenabled;
-static int disable_x2apic;
static __init int setup_nox2apic(char *str)
{
if (x2apic_enabled()) {
@@ -149,7 +148,6 @@
return 0;
}
- disable_x2apic = 1;
setup_clear_cpu_cap(X86_FEATURE_X2APIC);
return 0;
}
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 4d0216f..90b5e6e 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1716,25 +1716,19 @@
return;
}
-__apicdebuginit(void) print_APIC_bitfield(int base)
+__apicdebuginit(void) print_APIC_field(int base)
{
- unsigned int v;
- int i, j;
+ int i;
if (apic_verbosity == APIC_QUIET)
return;
- printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG);
- for (i = 0; i < 8; i++) {
- v = apic_read(base + i*0x10);
- for (j = 0; j < 32; j++) {
- if (v & (1<<j))
- printk("1");
- else
- printk("0");
- }
- printk("\n");
- }
+ printk(KERN_DEBUG);
+
+ for (i = 0; i < 8; i++)
+ printk(KERN_CONT "%08x", apic_read(base + i*0x10));
+
+ printk(KERN_CONT "\n");
}
__apicdebuginit(void) print_local_APIC(void *dummy)
@@ -1745,7 +1739,7 @@
if (apic_verbosity == APIC_QUIET)
return;
- printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
+ printk(KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
smp_processor_id(), hard_smp_processor_id());
v = apic_read(APIC_ID);
printk(KERN_INFO "... APIC ID: %08x (%01x)\n", v, read_apic_id());
@@ -1786,11 +1780,11 @@
printk(KERN_DEBUG "... APIC SPIV: %08x\n", v);
printk(KERN_DEBUG "... APIC ISR field:\n");
- print_APIC_bitfield(APIC_ISR);
+ print_APIC_field(APIC_ISR);
printk(KERN_DEBUG "... APIC TMR field:\n");
- print_APIC_bitfield(APIC_TMR);
+ print_APIC_field(APIC_TMR);
printk(KERN_DEBUG "... APIC IRR field:\n");
- print_APIC_bitfield(APIC_IRR);
+ print_APIC_field(APIC_IRR);
if (APIC_INTEGRATED(ver)) { /* !82489DX */
if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index 81cbe64..2a50ef8 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -299,7 +299,7 @@
static int transition_fid_vid(struct powernow_k8_data *data,
u32 reqfid, u32 reqvid)
{
- if (core_voltage_pre_transition(data, reqvid))
+ if (core_voltage_pre_transition(data, reqvid, reqfid))
return 1;
if (core_frequency_transition(data, reqfid))
@@ -327,17 +327,20 @@
/* Phase 1 - core voltage transition ... setup voltage */
static int core_voltage_pre_transition(struct powernow_k8_data *data,
- u32 reqvid)
+ u32 reqvid, u32 reqfid)
{
u32 rvosteps = data->rvo;
u32 savefid = data->currfid;
- u32 maxvid, lo;
+ u32 maxvid, lo, rvomult = 1;
dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, "
"reqvid 0x%x, rvo 0x%x\n",
smp_processor_id(),
data->currfid, data->currvid, reqvid, data->rvo);
+ if ((savefid < LO_FID_TABLE_TOP) && (reqfid < LO_FID_TABLE_TOP))
+ rvomult = 2;
+ rvosteps *= rvomult;
rdmsr(MSR_FIDVID_STATUS, lo, maxvid);
maxvid = 0x1f & (maxvid >> 16);
dprintk("ph1 maxvid=0x%x\n", maxvid);
@@ -351,7 +354,8 @@
return 1;
}
- while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) {
+ while ((rvosteps > 0) &&
+ ((rvomult * data->rvo + data->currvid) > reqvid)) {
if (data->currvid == maxvid) {
rvosteps = 0;
} else {
@@ -384,13 +388,6 @@
u32 vcoreqfid, vcocurrfid, vcofiddiff;
u32 fid_interval, savevid = data->currvid;
- if ((reqfid < HI_FID_TABLE_BOTTOM) &&
- (data->currfid < HI_FID_TABLE_BOTTOM)) {
- printk(KERN_ERR PFX "ph2: illegal lo-lo transition "
- "0x%x 0x%x\n", reqfid, data->currfid);
- return 1;
- }
-
if (data->currfid == reqfid) {
printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n",
data->currfid);
@@ -407,6 +404,9 @@
vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
: vcoreqfid - vcocurrfid;
+ if ((reqfid <= LO_FID_TABLE_TOP) && (data->currfid <= LO_FID_TABLE_TOP))
+ vcofiddiff = 0;
+
while (vcofiddiff > 2) {
(data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
@@ -1081,14 +1081,6 @@
return 0;
}
- if ((fid < HI_FID_TABLE_BOTTOM) &&
- (data->currfid < HI_FID_TABLE_BOTTOM)) {
- printk(KERN_ERR PFX
- "ignoring illegal change in lo freq table-%x to 0x%x\n",
- data->currfid, fid);
- return 1;
- }
-
dprintk("cpu %d, changing to fid 0x%x, vid 0x%x\n",
smp_processor_id(), fid, vid);
freqs.old = find_khz_freq_from_fid(data->currfid);
@@ -1267,7 +1259,7 @@
{
static const char ACPI_PSS_BIOS_BUG_MSG[] =
KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
- KERN_ERR FW_BUG PFX "Try again with latest BIOS.\n";
+ FW_BUG PFX "Try again with latest BIOS.\n";
struct powernow_k8_data *data;
struct init_on_cpu init_on_cpu;
int rc;
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
index c9c1190..02ce824 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
@@ -215,7 +215,8 @@
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k8", msg)
-static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid);
+static int core_voltage_pre_transition(struct powernow_k8_data *data,
+ u32 reqvid, u32 regfid);
static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid);
static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index af425b8..484c1e5 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -194,14 +194,14 @@
m->cs, m->ip);
if (m->cs == __KERNEL_CS)
print_symbol("{%s}", m->ip);
- printk("\n");
+ printk(KERN_CONT "\n");
}
printk(KERN_EMERG "TSC %llx ", m->tsc);
if (m->addr)
- printk("ADDR %llx ", m->addr);
+ printk(KERN_CONT "ADDR %llx ", m->addr);
if (m->misc)
- printk("MISC %llx ", m->misc);
- printk("\n");
+ printk(KERN_CONT "MISC %llx ", m->misc);
+ printk(KERN_CONT "\n");
printk(KERN_EMERG "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n",
m->cpuvendor, m->cpuid, m->time, m->socketid,
m->apicid);
@@ -209,13 +209,13 @@
static void print_mce_head(void)
{
- printk(KERN_EMERG "\n" KERN_EMERG "HARDWARE ERROR\n");
+ printk(KERN_EMERG "\nHARDWARE ERROR\n");
}
static void print_mce_tail(void)
{
printk(KERN_EMERG "This is not a software problem!\n"
- KERN_EMERG "Run through mcelog --ascii to decode and contact your hardware vendor\n");
+ "Run through mcelog --ascii to decode and contact your hardware vendor\n");
}
#define PANIC_TIMEOUT 5 /* 5 seconds */
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c
index d4cf4ce..36c3dc7 100644
--- a/arch/x86/kernel/cpu/perf_counter.c
+++ b/arch/x86/kernel/cpu/perf_counter.c
@@ -1561,6 +1561,7 @@
static DEFINE_PER_CPU(struct perf_callchain_entry, irq_entry);
static DEFINE_PER_CPU(struct perf_callchain_entry, nmi_entry);
+static DEFINE_PER_CPU(int, in_nmi_frame);
static void
@@ -1576,7 +1577,9 @@
static int backtrace_stack(void *data, char *name)
{
- /* Process all stacks: */
+ per_cpu(in_nmi_frame, smp_processor_id()) =
+ x86_is_stack_id(NMI_STACK, name);
+
return 0;
}
@@ -1584,6 +1587,9 @@
{
struct perf_callchain_entry *entry = data;
+ if (per_cpu(in_nmi_frame, smp_processor_id()))
+ return;
+
if (reliable)
callchain_store(entry, addr);
}
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index 5c481f6..e60ed74 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -803,8 +803,3 @@
wd_ops->rearm(wd, nmi_hz);
return 1;
}
-
-int lapic_watchdog_ok(void)
-{
- return wd_ops != NULL;
-}
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index d593cd1..bca5fba 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -19,6 +19,12 @@
#include "dumpstack.h"
+/* Just a stub for now */
+int x86_is_stack_id(int id, char *name)
+{
+ return 0;
+}
+
void dump_trace(struct task_struct *task, struct pt_regs *regs,
unsigned long *stack, unsigned long bp,
const struct stacktrace_ops *ops, void *data)
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index d35db59..54b0a32 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -19,10 +19,8 @@
#include "dumpstack.h"
-static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
- unsigned *usedp, char **idp)
-{
- static char ids[][8] = {
+
+static char x86_stack_ids[][8] = {
[DEBUG_STACK - 1] = "#DB",
[NMI_STACK - 1] = "NMI",
[DOUBLEFAULT_STACK - 1] = "#DF",
@@ -33,6 +31,15 @@
N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]"
#endif
};
+
+int x86_is_stack_id(int id, char *name)
+{
+ return x86_stack_ids[id - 1] == name;
+}
+
+static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
+ unsigned *usedp, char **idp)
+{
unsigned k;
/*
@@ -61,7 +68,7 @@
if (*usedp & (1U << k))
break;
*usedp |= 1U << k;
- *idp = ids[k];
+ *idp = x86_stack_ids[k];
return (unsigned long *)end;
}
/*
@@ -81,12 +88,13 @@
do {
++j;
end -= EXCEPTION_STKSZ;
- ids[j][4] = '1' + (j - N_EXCEPTION_STACKS);
+ x86_stack_ids[j][4] = '1' +
+ (j - N_EXCEPTION_STACKS);
} while (stack < end - EXCEPTION_STKSZ);
if (*usedp & (1U << j))
break;
*usedp |= 1U << j;
- *idp = ids[j];
+ *idp = x86_stack_ids[j];
return (unsigned long *)end;
}
#endif
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index c4ca89d..5cb5725 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -627,10 +627,9 @@
#ifdef CONFIG_X86_64
if (!found) {
gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024;
- printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit "
- "address range\n"
- KERN_ERR "PCI: Unassigned devices with 32bit resource "
- "registers may break!\n");
+ printk(KERN_ERR
+ "PCI: Warning: Cannot find a gap in the 32bit address range\n"
+ "PCI: Unassigned devices with 32bit resource registers may break!\n");
}
#endif
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index a78ecad..c664d51 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -200,7 +200,7 @@
state->mode = paravirt_get_lazy_mode();
}
-static void paravirt_ops_setup(void)
+static void __init paravirt_ops_setup(void)
{
pv_info.name = "KVM";
pv_info.paravirt_enabled = 1;
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index cfd9f90..d2e56b8 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -675,7 +675,7 @@
nommu:
/* Should not happen anymore */
printk(KERN_WARNING "PCI-DMA: More than 4GB of RAM and no IOMMU\n"
- KERN_WARNING "falling back to iommu=soft.\n");
+ "falling back to iommu=soft.\n");
return -1;
}
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index f9d3563..07c3189 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -10,6 +10,7 @@
lib-y += memcpy_$(BITS).o
ifeq ($(CONFIG_X86_32),y)
+ obj-y += atomic64_32.o
lib-y += checksum_32.o
lib-y += strstr_32.o
lib-y += semaphore_32.o string_32.o
diff --git a/arch/x86/lib/atomic64_32.c b/arch/x86/lib/atomic64_32.c
new file mode 100644
index 0000000..824fa0b
--- /dev/null
+++ b/arch/x86/lib/atomic64_32.c
@@ -0,0 +1,230 @@
+#include <linux/compiler.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include <asm/processor.h>
+#include <asm/cmpxchg.h>
+#include <asm/atomic.h>
+
+static noinline u64 cmpxchg8b(u64 *ptr, u64 old, u64 new)
+{
+ u32 low = new;
+ u32 high = new >> 32;
+
+ asm volatile(
+ LOCK_PREFIX "cmpxchg8b %1\n"
+ : "+A" (old), "+m" (*ptr)
+ : "b" (low), "c" (high)
+ );
+ return old;
+}
+
+u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val)
+{
+ return cmpxchg8b(&ptr->counter, old_val, new_val);
+}
+EXPORT_SYMBOL(atomic64_cmpxchg);
+
+/**
+ * atomic64_xchg - xchg atomic64 variable
+ * @ptr: pointer to type atomic64_t
+ * @new_val: value to assign
+ *
+ * Atomically xchgs the value of @ptr to @new_val and returns
+ * the old value.
+ */
+u64 atomic64_xchg(atomic64_t *ptr, u64 new_val)
+{
+ /*
+ * Try first with a (possibly incorrect) assumption about
+ * what we have there. We'll do two loops most likely,
+ * but we'll get an ownership MESI transaction straight away
+ * instead of a read transaction followed by a
+ * flush-for-ownership transaction:
+ */
+ u64 old_val, real_val = 0;
+
+ do {
+ old_val = real_val;
+
+ real_val = atomic64_cmpxchg(ptr, old_val, new_val);
+
+ } while (real_val != old_val);
+
+ return old_val;
+}
+EXPORT_SYMBOL(atomic64_xchg);
+
+/**
+ * atomic64_set - set atomic64 variable
+ * @ptr: pointer to type atomic64_t
+ * @new_val: value to assign
+ *
+ * Atomically sets the value of @ptr to @new_val.
+ */
+void atomic64_set(atomic64_t *ptr, u64 new_val)
+{
+ atomic64_xchg(ptr, new_val);
+}
+EXPORT_SYMBOL(atomic64_set);
+
+/**
+EXPORT_SYMBOL(atomic64_read);
+ * atomic64_add_return - add and return
+ * @delta: integer value to add
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically adds @delta to @ptr and returns @delta + *@ptr
+ */
+noinline u64 atomic64_add_return(u64 delta, atomic64_t *ptr)
+{
+ /*
+ * Try first with a (possibly incorrect) assumption about
+ * what we have there. We'll do two loops most likely,
+ * but we'll get an ownership MESI transaction straight away
+ * instead of a read transaction followed by a
+ * flush-for-ownership transaction:
+ */
+ u64 old_val, new_val, real_val = 0;
+
+ do {
+ old_val = real_val;
+ new_val = old_val + delta;
+
+ real_val = atomic64_cmpxchg(ptr, old_val, new_val);
+
+ } while (real_val != old_val);
+
+ return new_val;
+}
+EXPORT_SYMBOL(atomic64_add_return);
+
+u64 atomic64_sub_return(u64 delta, atomic64_t *ptr)
+{
+ return atomic64_add_return(-delta, ptr);
+}
+EXPORT_SYMBOL(atomic64_sub_return);
+
+u64 atomic64_inc_return(atomic64_t *ptr)
+{
+ return atomic64_add_return(1, ptr);
+}
+EXPORT_SYMBOL(atomic64_inc_return);
+
+u64 atomic64_dec_return(atomic64_t *ptr)
+{
+ return atomic64_sub_return(1, ptr);
+}
+EXPORT_SYMBOL(atomic64_dec_return);
+
+/**
+ * atomic64_add - add integer to atomic64 variable
+ * @delta: integer value to add
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically adds @delta to @ptr.
+ */
+void atomic64_add(u64 delta, atomic64_t *ptr)
+{
+ atomic64_add_return(delta, ptr);
+}
+EXPORT_SYMBOL(atomic64_add);
+
+/**
+ * atomic64_sub - subtract the atomic64 variable
+ * @delta: integer value to subtract
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically subtracts @delta from @ptr.
+ */
+void atomic64_sub(u64 delta, atomic64_t *ptr)
+{
+ atomic64_add(-delta, ptr);
+}
+EXPORT_SYMBOL(atomic64_sub);
+
+/**
+ * atomic64_sub_and_test - subtract value from variable and test result
+ * @delta: integer value to subtract
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically subtracts @delta from @ptr and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+int atomic64_sub_and_test(u64 delta, atomic64_t *ptr)
+{
+ u64 new_val = atomic64_sub_return(delta, ptr);
+
+ return new_val == 0;
+}
+EXPORT_SYMBOL(atomic64_sub_and_test);
+
+/**
+ * atomic64_inc - increment atomic64 variable
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically increments @ptr by 1.
+ */
+void atomic64_inc(atomic64_t *ptr)
+{
+ atomic64_add(1, ptr);
+}
+EXPORT_SYMBOL(atomic64_inc);
+
+/**
+ * atomic64_dec - decrement atomic64 variable
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically decrements @ptr by 1.
+ */
+void atomic64_dec(atomic64_t *ptr)
+{
+ atomic64_sub(1, ptr);
+}
+EXPORT_SYMBOL(atomic64_dec);
+
+/**
+ * atomic64_dec_and_test - decrement and test
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically decrements @ptr by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+int atomic64_dec_and_test(atomic64_t *ptr)
+{
+ return atomic64_sub_and_test(1, ptr);
+}
+EXPORT_SYMBOL(atomic64_dec_and_test);
+
+/**
+ * atomic64_inc_and_test - increment and test
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically increments @ptr by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+int atomic64_inc_and_test(atomic64_t *ptr)
+{
+ return atomic64_sub_and_test(-1, ptr);
+}
+EXPORT_SYMBOL(atomic64_inc_and_test);
+
+/**
+ * atomic64_add_negative - add and test if negative
+ * @delta: integer value to add
+ * @ptr: pointer to type atomic64_t
+ *
+ * Atomically adds @delta to @ptr and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+int atomic64_add_negative(u64 delta, atomic64_t *ptr)
+{
+ s64 new_val = atomic64_add_return(delta, ptr);
+
+ return new_val < 0;
+}
+EXPORT_SYMBOL(atomic64_add_negative);
diff --git a/arch/x86/lib/clear_page_64.S b/arch/x86/lib/clear_page_64.S
index 9a10a78..ebeafcc 100644
--- a/arch/x86/lib/clear_page_64.S
+++ b/arch/x86/lib/clear_page_64.S
@@ -5,15 +5,14 @@
* Zero a page.
* rdi page
*/
- ALIGN
-clear_page_c:
+ENTRY(clear_page_c)
CFI_STARTPROC
movl $4096/8,%ecx
xorl %eax,%eax
rep stosq
ret
CFI_ENDPROC
-ENDPROC(clear_page)
+ENDPROC(clear_page_c)
ENTRY(clear_page)
CFI_STARTPROC
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S
index f118c11..6ba0f7b 100644
--- a/arch/x86/lib/copy_user_64.S
+++ b/arch/x86/lib/copy_user_64.S
@@ -75,6 +75,7 @@
jae bad_to_user
ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
CFI_ENDPROC
+ENDPROC(copy_to_user)
/* Standard copy_from_user with segment limit checking */
ENTRY(copy_from_user)
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 78a5fff..85307cc 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -426,10 +426,11 @@
}
static const char errata93_warning[] =
-KERN_ERR "******* Your BIOS seems to not contain a fix for K8 errata #93\n"
-KERN_ERR "******* Working around it, but it may cause SEGVs or burn power.\n"
-KERN_ERR "******* Please consider a BIOS update.\n"
-KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
+KERN_ERR
+"******* Your BIOS seems to not contain a fix for K8 errata #93\n"
+"******* Working around it, but it may cause SEGVs or burn power.\n"
+"******* Please consider a BIOS update.\n"
+"******* Disabling USB legacy in the BIOS may also help.\n";
/*
* No vm86 mode in 64-bit mode:
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 47ce9a2..0607119 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -12,6 +12,7 @@
#include <asm/system.h>
#include <asm/tlbflush.h>
#include <asm/tlb.h>
+#include <asm/proto.h>
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index b177652..6176fe8 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -598,8 +598,15 @@
sparse_memory_present_with_active_regions(MAX_NUMNODES);
sparse_init();
- /* clear the default setting with node 0 */
- nodes_clear(node_states[N_NORMAL_MEMORY]);
+
+ /*
+ * clear the default setting with node 0
+ * note: don't use nodes_clear here, that is really clearing when
+ * numa support is not compiled in, and later node_set_state
+ * will not set it back.
+ */
+ node_clear_state(0, N_NORMAL_MEMORY);
+
free_area_init_nodes(max_zone_pfns);
}
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index b07dd8d..89b9a5c 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -390,7 +390,7 @@
static int force_arch_perfmon;
static int force_cpu_type(const char *str, struct kernel_param *kp)
{
- if (!strcmp(str, "archperfmon")) {
+ if (!strcmp(str, "arch_perfmon")) {
force_arch_perfmon = 1;
printk(KERN_INFO "oprofile: forcing architectural perfmon\n");
}
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index b26626d..1014eb4 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -68,6 +68,10 @@
unsigned long flags;
struct resource *root;
int max_root_bus_resources = PCI_BUS_NUM_RESOURCES;
+ u64 start, end;
+
+ if (bus_has_transparent_bridge(info->bus))
+ max_root_bus_resources -= 3;
status = resource_to_addr(acpi_res, &addr);
if (!ACPI_SUCCESS(status))
@@ -84,25 +88,24 @@
} else
return AE_OK;
- res = &info->res[info->res_num];
- res->name = info->name;
- res->flags = flags;
- res->start = addr.minimum + addr.translation_offset;
- res->end = res->start + addr.address_length - 1;
- res->child = NULL;
-
- if (bus_has_transparent_bridge(info->bus))
- max_root_bus_resources -= 3;
+ start = addr.minimum + addr.translation_offset;
+ end = start + addr.address_length - 1;
if (info->res_num >= max_root_bus_resources) {
printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx "
"from %s for %s due to _CRS returning more than "
- "%d resource descriptors\n", (unsigned long) res->start,
- (unsigned long) res->end, root->name, info->name,
+ "%d resource descriptors\n", (unsigned long) start,
+ (unsigned long) end, root->name, info->name,
max_root_bus_resources);
- info->res_num++;
return AE_OK;
}
+ res = &info->res[info->res_num];
+ res->name = info->name;
+ res->flags = flags;
+ res->start = start;
+ res->end = end;
+ res->child = NULL;
+
if (insert_resource(root, res)) {
printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx "
"from %s for %s\n", (unsigned long) res->start,
@@ -115,23 +118,6 @@
}
static void
-adjust_transparent_bridge_resources(struct pci_bus *bus)
-{
- struct pci_dev *dev;
-
- list_for_each_entry(dev, &bus->devices, bus_list) {
- int i;
- u16 class = dev->class >> 8;
-
- if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent) {
- for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
- dev->subordinate->resource[i] =
- dev->bus->resource[i - 3];
- }
- }
-}
-
-static void
get_current_resources(struct acpi_device *device, int busnum,
int domain, struct pci_bus *bus)
{
@@ -158,8 +144,6 @@
info.res_num = 0;
acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
&info);
- if (info.res_num)
- adjust_transparent_bridge_resources(bus);
return;
@@ -222,8 +206,15 @@
*/
memcpy(bus->sysdata, sd, sizeof(*sd));
kfree(sd);
- } else
- bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd);
+ } else {
+ bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd);
+ if (bus) {
+ if (pci_probe & PCI_USE__CRS)
+ get_current_resources(device, busnum, domain,
+ bus);
+ bus->subordinate = pci_scan_child_bus(bus);
+ }
+ }
if (!bus)
kfree(sd);
@@ -238,8 +229,6 @@
#endif
}
- if (bus && (pci_probe & PCI_USE__CRS))
- get_current_resources(device, busnum, domain, bus);
return bus;
}
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index f893d6a..3ffa10d 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -100,8 +100,9 @@
int j;
struct pci_root_info *info;
- /* don't go for it if _CRS is used */
- if (pci_probe & PCI_USE__CRS)
+ /* don't go for it if _CRS is used already */
+ if (b->resource[0] != &ioport_resource ||
+ b->resource[1] != &iomem_resource)
return;
/* if only one root bus, don't need to anything */
@@ -116,6 +117,9 @@
if (i == pci_root_num)
return;
+ printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
+ b->number);
+
info = &pci_root_info[i];
for (j = 0; j < info->res_num; j++) {
struct resource *res;
diff --git a/arch/x86/power/Makefile b/arch/x86/power/Makefile
index de2abbd..a6a198c 100644
--- a/arch/x86/power/Makefile
+++ b/arch/x86/power/Makefile
@@ -1,7 +1,7 @@
# __restore_processor_state() restores %gs after S3 resume and so should not
# itself be stack-protected
nostackp := $(call cc-option, -fno-stack-protector)
-CFLAGS_cpu_$(BITS).o := $(nostackp)
+CFLAGS_cpu.o := $(nostackp)
obj-$(CONFIG_PM_SLEEP) += cpu.o
obj-$(CONFIG_HIBERNATION) += hibernate_$(BITS).o hibernate_asm_$(BITS).o
diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/asm/thread_info.h
index 0f4fe1f..1316564 100644
--- a/arch/xtensa/include/asm/thread_info.h
+++ b/arch/xtensa/include/asm/thread_info.h
@@ -80,8 +80,6 @@
/*
* macros/functions for gaining access to the thread information structure
- *
- * preempt_count needs to be 1 initially, until the scheduler is functional.
*/
#ifndef __ASSEMBLY__
@@ -92,7 +90,7 @@
.exec_domain = &default_exec_domain, \
.flags = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.restart_block = { \
.fn = do_no_restart_syscall, \
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index ba9ab93..e64efac 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -354,10 +354,10 @@
for (i = 0; i < 16; i++) {
if ((i % 8) == 0)
- printk ("\n" KERN_INFO "a%02d: ", i);
- printk("%08lx ", regs->areg[i]);
+ printk(KERN_INFO "a%02d:", i);
+ printk(KERN_CONT " %08lx", regs->areg[i]);
}
- printk("\n");
+ printk(KERN_CONT "\n");
printk("pc: %08lx, ps: %08lx, depc: %08lx, excvaddr: %08lx\n",
regs->pc, regs->ps, regs->depc, regs->excvaddr);
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 3d763fd..2466506 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -207,6 +207,16 @@
void __iomem *tmp;
int i, ret;
+ device_initialize(&dev->dev);
+
+ /*
+ * Copy from device_add
+ */
+ if (dev->dev.init_name) {
+ dev_set_name(&dev->dev, "%s", dev->dev.init_name);
+ dev->dev.init_name = NULL;
+ }
+
dev->dev.release = amba_device_release;
dev->dev.bus = &amba_bustype;
dev->dev.dma_mask = &dev->dma_mask;
@@ -240,7 +250,7 @@
goto err_release;
}
- ret = device_register(&dev->dev);
+ ret = device_add(&dev->dev);
if (ret)
goto err_release;
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index ddeb819..fc46653 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -357,7 +357,7 @@
kfree(fw_priv->pages);
kfree(fw_priv->fw_id);
kfree(fw_priv);
- put_device(dev);
+ kfree(dev);
module_put(THIS_MODULE);
}
@@ -408,13 +408,11 @@
if (retval) {
dev_err(device, "%s: device_register failed\n", __func__);
put_device(f_dev);
- goto error_kfree_fw_id;
+ return retval;
}
*dev_p = f_dev;
return 0;
-error_kfree_fw_id:
- kfree(fw_priv->fw_id);
error_kfree:
kfree(f_dev);
kfree(fw_priv);
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index fae7254..58a3e57 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -762,6 +762,7 @@
dev->power.status = DPM_ON;
if (error == -EAGAIN) {
put_device(dev);
+ error = 0;
continue;
}
printk(KERN_ERR "PM: Failed to prepare device %s "
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 9c6e5b0..2f07b7c 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1645,7 +1645,7 @@
{
int drive,drives,nomem;
- printk(KERN_INFO "FD: probing units\n" KERN_INFO "found ");
+ printk(KERN_INFO "FD: probing units\nfound ");
drives=0;
nomem=0;
for(drive=0;drive<FD_MAX_UNITS;drive++) {
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index f08491a..b20abe10 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -390,9 +390,10 @@
static void ace_dump_regs(struct ace_device *ace)
{
- dev_info(ace->dev, " ctrl: %.8x seccnt/cmd: %.4x ver:%.4x\n"
- KERN_INFO " status:%.8x mpu_lba:%.8x busmode:%4x\n"
- KERN_INFO " error: %.8x cfg_lba:%.8x fatstat:%.4x\n",
+ dev_info(ace->dev,
+ " ctrl: %.8x seccnt/cmd: %.4x ver:%.4x\n"
+ " status:%.8x mpu_lba:%.8x busmode:%4x\n"
+ " error: %.8x cfg_lba:%.8x fatstat:%.4x\n",
ace_in32(ace, ACE_CTRL),
ace_in(ace, ACE_SECCNTCMD),
ace_in(ace, ACE_VERSION),
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c
index 5dcbe60..91b53eb 100644
--- a/drivers/char/hw_random/intel-rng.c
+++ b/drivers/char/hw_random/intel-rng.c
@@ -305,10 +305,11 @@
(BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))
== BIOS_CNTL_LOCK_ENABLE_MASK) {
static __initdata /*const*/ char warning[] =
- KERN_WARNING PFX "Firmware space is locked read-only. If you can't or\n"
- KERN_WARNING PFX "don't want to disable this in firmware setup, and if\n"
- KERN_WARNING PFX "you are certain that your system has a functional\n"
- KERN_WARNING PFX "RNG, try using the 'no_fwh_detect' option.\n";
+ KERN_WARNING
+PFX "Firmware space is locked read-only. If you can't or\n"
+PFX "don't want to disable this in firmware setup, and if\n"
+PFX "you are certain that your system has a functional\n"
+PFX "RNG, try using the 'no_fwh_detect' option.\n";
if (no_fwh_detect)
return -ENODEV;
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 4159292..621d118 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1478,10 +1478,10 @@
status = inw(base + 0x4);
if (status != 0) {
dev_warn(&pdev->dev, "Card%d rejected load header:\n"
- KERN_WARNING "Address:0x%x\n"
- KERN_WARNING "Count:0x%x\n"
- KERN_WARNING "Status:0x%x\n",
- index + 1, frame->addr, frame->count, status);
+ "Address:0x%x\n"
+ "Count:0x%x\n"
+ "Status:0x%x\n",
+ index + 1, frame->addr, frame->count, status);
goto errrelfw;
}
outsw(base, frame->data, word_count);
@@ -1526,10 +1526,10 @@
status = inw(base + 0x4);
if (status != 0) {
dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
- KERN_WARNING "Address:0x%x\n"
- KERN_WARNING "Count:0x%x\n"
- KERN_WARNING "Status: 0x%x\n",
- index + 1, frame->addr, frame->count, status);
+ "Address:0x%x\n"
+ "Count:0x%x\n"
+ "Status: 0x%x\n",
+ index + 1, frame->addr, frame->count, status);
goto errrelfw;
}
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index daebe1b..9d1b4f5 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -75,114 +75,88 @@
*/
static void pty_unthrottle(struct tty_struct *tty)
{
- struct tty_struct *o_tty = tty->link;
-
- if (!o_tty)
- return;
-
- tty_wakeup(o_tty);
+ tty_wakeup(tty->link);
set_bit(TTY_THROTTLED, &tty->flags);
}
-/*
- * WSH 05/24/97: modified to
- * (1) use space in tty->flip instead of a shared temp buffer
- * The flip buffers aren't being used for a pty, so there's lots
- * of space available. The buffer is protected by a per-pty
- * semaphore that should almost never come under contention.
- * (2) avoid redundant copying for cases where count >> receive_room
- * N.B. Calls from user space may now return an error code instead of
- * a count.
+/**
+ * pty_space - report space left for writing
+ * @to: tty we are writing into
*
- * FIXME: Our pty_write method is called with our ldisc lock held but
- * not our partners. We can't just wait on the other one blindly without
- * risking deadlocks. At some point when everything has settled down we need
- * to look into making pty_write at least able to sleep over an ldisc change.
- *
- * The return on no ldisc is a bit counter intuitive but the logic works
- * like this. During an ldisc change the other end will flush its buffers. We
- * thus return the full length which is identical to the case where we had
- * proper locking and happened to queue the bytes just before the flush during
- * the ldisc change.
+ * The tty buffers allow 64K but we sneak a peak and clip at 8K this
+ * allows a lot of overspill room for echo and other fun messes to
+ * be handled properly
*/
+
+static int pty_space(struct tty_struct *to)
+{
+ int n = 8192 - to->buf.memory_used;
+ if (n < 0)
+ return 0;
+ return n;
+}
+
+/**
+ * pty_write - write to a pty
+ * @tty: the tty we write from
+ * @buf: kernel buffer of data
+ * @count: bytes to write
+ *
+ * Our "hardware" write method. Data is coming from the ldisc which
+ * may be in a non sleeping state. We simply throw this at the other
+ * end of the link as if we were an IRQ handler receiving stuff for
+ * the other side of the pty/tty pair.
+ */
+
static int pty_write(struct tty_struct *tty, const unsigned char *buf,
int count)
{
struct tty_struct *to = tty->link;
- struct tty_ldisc *ld;
- int c = count;
+ int c;
- if (!to || tty->stopped)
+ if (tty->stopped)
return 0;
- ld = tty_ldisc_ref(to);
- if (ld) {
- c = to->receive_room;
- if (c > count)
- c = count;
- ld->ops->receive_buf(to, buf, NULL, c);
- tty_ldisc_deref(ld);
+ /* This isn't locked but our 8K is quite sloppy so no
+ big deal */
+
+ c = pty_space(to);
+ if (c > count)
+ c = count;
+ if (c > 0) {
+ /* Stuff the data into the input queue of the other end */
+ c = tty_insert_flip_string(to, buf, c);
+ /* And shovel */
+ tty_flip_buffer_push(to);
+ tty_wakeup(tty);
}
return c;
}
+/**
+ * pty_write_room - write space
+ * @tty: tty we are writing from
+ *
+ * Report how many bytes the ldisc can send into the queue for
+ * the other device.
+ */
+
static int pty_write_room(struct tty_struct *tty)
{
- struct tty_struct *to = tty->link;
-
- if (!to || tty->stopped)
- return 0;
-
- return to->receive_room;
+ return pty_space(tty->link);
}
-/*
- * WSH 05/24/97: Modified for asymmetric MASTER/SLAVE behavior
- * The chars_in_buffer() value is used by the ldisc select() function
- * to hold off writing when chars_in_buffer > WAKEUP_CHARS (== 256).
- * The pty driver chars_in_buffer() Master/Slave must behave differently:
+/**
+ * pty_chars_in_buffer - characters currently in our tx queue
+ * @tty: our tty
*
- * The Master side needs to allow typed-ahead commands to accumulate
- * while being canonicalized, so we report "our buffer" as empty until
- * some threshold is reached, and then report the count. (Any count >
- * WAKEUP_CHARS is regarded by select() as "full".) To avoid deadlock
- * the count returned must be 0 if no canonical data is available to be
- * read. (The N_TTY ldisc.chars_in_buffer now knows this.)
- *
- * The Slave side passes all characters in raw mode to the Master side's
- * buffer where they can be read immediately, so in this case we can
- * return the true count in the buffer.
+ * Report how much we have in the transmit queue. As everything is
+ * instantly at the other end this is easy to implement.
*/
+
static int pty_chars_in_buffer(struct tty_struct *tty)
{
- struct tty_struct *to = tty->link;
- struct tty_ldisc *ld;
- int count = 0;
-
- /* We should get the line discipline lock for "tty->link" */
- if (!to)
- return 0;
- /* We cannot take a sleeping reference here without deadlocking with
- an ldisc change - but it doesn't really matter */
- ld = tty_ldisc_ref(to);
- if (ld == NULL)
- return 0;
-
- /* The ldisc must report 0 if no characters available to be read */
- if (ld->ops->chars_in_buffer)
- count = ld->ops->chars_in_buffer(to);
-
- tty_ldisc_deref(ld);
-
- if (tty->driver->subtype == PTY_TYPE_SLAVE)
- return count;
-
- /* Master side driver ... if the other side's read buffer is less than
- * half full, return 0 to allow writers to proceed; otherwise return
- * the count. This leaves a comfortable margin to avoid overflow,
- * and still allows half a buffer's worth of typed-ahead commands.
- */
- return (count < N_TTY_BUF_SIZE/2) ? 0 : count;
+ return 0;
}
/* Set the lock flag on a pty */
@@ -202,20 +176,10 @@
{
struct tty_struct *to = tty->link;
unsigned long flags;
- struct tty_ldisc *ld;
if (!to)
return;
- ld = tty_ldisc_ref(to);
-
- /* The other end is changing discipline */
- if (!ld)
- return;
-
- if (ld->ops->flush_buffer)
- to->ldisc->ops->flush_buffer(to);
- tty_ldisc_deref(ld);
-
+ /* tty_buffer_flush(to); FIXME */
if (to->packet) {
spin_lock_irqsave(&tty->ctrl_lock, flags);
tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 6e2ec0b..b90eda8 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -761,6 +761,10 @@
* cpufreq_add_dev - add a CPU device
*
* Adds the cpufreq interface for a CPU device.
+ *
+ * The Oracle says: try running cpufreq registration/unregistration concurrently
+ * with with cpu hotplugging and all hell will break loose. Tried to clean this
+ * mess up, but more thorough testing is needed. - Mathieu
*/
static int cpufreq_add_dev(struct sys_device *sys_dev)
{
@@ -772,9 +776,6 @@
struct sys_device *cpu_sys_dev;
unsigned long flags;
unsigned int j;
-#ifdef CONFIG_SMP
- struct cpufreq_policy *managed_policy;
-#endif
if (cpu_is_offline(cpu))
return 0;
@@ -804,15 +805,12 @@
goto nomem_out;
}
if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) {
- kfree(policy);
ret = -ENOMEM;
- goto nomem_out;
+ goto err_free_policy;
}
if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) {
- free_cpumask_var(policy->cpus);
- kfree(policy);
ret = -ENOMEM;
- goto nomem_out;
+ goto err_free_cpumask;
}
policy->cpu = cpu;
@@ -820,7 +818,8 @@
/* Initially set CPU itself as the policy_cpu */
per_cpu(policy_cpu, cpu) = cpu;
- lock_policy_rwsem_write(cpu);
+ ret = (lock_policy_rwsem_write(cpu) < 0);
+ WARN_ON(ret);
init_completion(&policy->kobj_unregister);
INIT_WORK(&policy->update, handle_update);
@@ -833,7 +832,7 @@
ret = cpufreq_driver->init(policy);
if (ret) {
dprintk("initialization failed\n");
- goto err_out;
+ goto err_unlock_policy;
}
policy->user_policy.min = policy->min;
policy->user_policy.max = policy->max;
@@ -852,21 +851,29 @@
#endif
for_each_cpu(j, policy->cpus) {
+ struct cpufreq_policy *managed_policy;
+
if (cpu == j)
continue;
/* Check for existing affected CPUs.
* They may not be aware of it due to CPU Hotplug.
*/
- managed_policy = cpufreq_cpu_get(j); /* FIXME: Where is this released? What about error paths? */
+ managed_policy = cpufreq_cpu_get(j);
if (unlikely(managed_policy)) {
/* Set proper policy_cpu */
unlock_policy_rwsem_write(cpu);
per_cpu(policy_cpu, cpu) = managed_policy->cpu;
- if (lock_policy_rwsem_write(cpu) < 0)
- goto err_out_driver_exit;
+ if (lock_policy_rwsem_write(cpu) < 0) {
+ /* Should not go through policy unlock path */
+ if (cpufreq_driver->exit)
+ cpufreq_driver->exit(policy);
+ ret = -EBUSY;
+ cpufreq_cpu_put(managed_policy);
+ goto err_free_cpumask;
+ }
spin_lock_irqsave(&cpufreq_driver_lock, flags);
cpumask_copy(managed_policy->cpus, policy->cpus);
@@ -877,12 +884,14 @@
ret = sysfs_create_link(&sys_dev->kobj,
&managed_policy->kobj,
"cpufreq");
- if (ret)
- goto err_out_driver_exit;
-
- cpufreq_debug_enable_ratelimit();
- ret = 0;
- goto err_out_driver_exit; /* call driver->exit() */
+ if (!ret)
+ cpufreq_cpu_put(managed_policy);
+ /*
+ * Success. We only needed to be added to the mask.
+ * Call driver->exit() because only the cpu parent of
+ * the kobj needed to call init().
+ */
+ goto out_driver_exit; /* call driver->exit() */
}
}
#endif
@@ -892,25 +901,25 @@
ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj,
"cpufreq");
if (ret)
- goto err_out_driver_exit;
+ goto out_driver_exit;
/* set up files for this cpu device */
drv_attr = cpufreq_driver->attr;
while ((drv_attr) && (*drv_attr)) {
ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
if (ret)
- goto err_out_driver_exit;
+ goto err_out_kobj_put;
drv_attr++;
}
if (cpufreq_driver->get) {
ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
if (ret)
- goto err_out_driver_exit;
+ goto err_out_kobj_put;
}
if (cpufreq_driver->target) {
ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
if (ret)
- goto err_out_driver_exit;
+ goto err_out_kobj_put;
}
spin_lock_irqsave(&cpufreq_driver_lock, flags);
@@ -922,18 +931,22 @@
/* symlink affected CPUs */
for_each_cpu(j, policy->cpus) {
+ struct cpufreq_policy *managed_policy;
+
if (j == cpu)
continue;
if (!cpu_online(j))
continue;
dprintk("CPU %u already managed, adding link\n", j);
- cpufreq_cpu_get(cpu);
+ managed_policy = cpufreq_cpu_get(cpu);
cpu_sys_dev = get_cpu_sysdev(j);
ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
"cpufreq");
- if (ret)
+ if (ret) {
+ cpufreq_cpu_put(managed_policy);
goto err_out_unregister;
+ }
}
policy->governor = NULL; /* to assure that the starting sequence is
@@ -965,17 +978,20 @@
per_cpu(cpufreq_cpu_data, j) = NULL;
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+err_out_kobj_put:
kobject_put(&policy->kobj);
wait_for_completion(&policy->kobj_unregister);
-err_out_driver_exit:
+out_driver_exit:
if (cpufreq_driver->exit)
cpufreq_driver->exit(policy);
-err_out:
+err_unlock_policy:
unlock_policy_rwsem_write(cpu);
+err_free_cpumask:
+ free_cpumask_var(policy->cpus);
+err_free_policy:
kfree(policy);
-
nomem_out:
module_put(cpufreq_driver->owner);
module_out:
@@ -1070,8 +1086,6 @@
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
#endif
- unlock_policy_rwsem_write(cpu);
-
if (cpufreq_driver->target)
__cpufreq_governor(data, CPUFREQ_GOV_STOP);
@@ -1088,6 +1102,8 @@
if (cpufreq_driver->exit)
cpufreq_driver->exit(data);
+ unlock_policy_rwsem_write(cpu);
+
free_cpumask_var(data->related_cpus);
free_cpumask_var(data->cpus);
kfree(data);
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 7fc58af..5749050 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -63,22 +63,20 @@
unsigned int down_skip;
unsigned int requested_freq;
int cpu;
- unsigned int enable:1;
+ /*
+ * percpu mutex that serializes governor limit change with
+ * do_dbs_timer invocation. We do not want do_dbs_timer to run
+ * when user is changing the governor or limits.
+ */
+ struct mutex timer_mutex;
};
static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
static unsigned int dbs_enable; /* number of CPUs using this policy */
/*
- * DEADLOCK ALERT! There is a ordering requirement between cpu_hotplug
- * lock and dbs_mutex. cpu_hotplug lock should always be held before
- * dbs_mutex. If any function that can potentially take cpu_hotplug lock
- * (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then
- * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock
- * is recursive for the same process. -Venki
- * DEADLOCK ALERT! (2) : do_dbs_timer() must not take the dbs_mutex, because it
- * would deadlock with cancel_delayed_work_sync(), which is needed for proper
- * raceless workqueue teardown.
+ * dbs_mutex protects data in dbs_tuners_ins from concurrent changes on
+ * different CPUs. It protects dbs_enable in governor start/stop.
*/
static DEFINE_MUTEX(dbs_mutex);
@@ -143,9 +141,6 @@
struct cpufreq_policy *policy;
- if (!this_dbs_info->enable)
- return 0;
-
policy = this_dbs_info->cur_policy;
/*
@@ -488,18 +483,12 @@
delay -= jiffies % delay;
- if (lock_policy_rwsem_write(cpu) < 0)
- return;
-
- if (!dbs_info->enable) {
- unlock_policy_rwsem_write(cpu);
- return;
- }
+ mutex_lock(&dbs_info->timer_mutex);
dbs_check_cpu(dbs_info);
queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay);
- unlock_policy_rwsem_write(cpu);
+ mutex_unlock(&dbs_info->timer_mutex);
}
static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
@@ -508,7 +497,6 @@
int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
delay -= jiffies % delay;
- dbs_info->enable = 1;
INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
queue_delayed_work_on(dbs_info->cpu, kconservative_wq, &dbs_info->work,
delay);
@@ -516,7 +504,6 @@
static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
{
- dbs_info->enable = 0;
cancel_delayed_work_sync(&dbs_info->work);
}
@@ -535,9 +522,6 @@
if ((!cpu_online(cpu)) || (!policy->cur))
return -EINVAL;
- if (this_dbs_info->enable) /* Already enabled */
- break;
-
mutex_lock(&dbs_mutex);
rc = sysfs_create_group(&policy->kobj, &dbs_attr_group);
@@ -561,6 +545,7 @@
this_dbs_info->down_skip = 0;
this_dbs_info->requested_freq = policy->cur;
+ mutex_init(&this_dbs_info->timer_mutex);
dbs_enable++;
/*
* Start the timerschedule work, when this governor
@@ -590,17 +575,19 @@
&dbs_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
}
- dbs_timer_init(this_dbs_info);
-
mutex_unlock(&dbs_mutex);
+ dbs_timer_init(this_dbs_info);
+
break;
case CPUFREQ_GOV_STOP:
- mutex_lock(&dbs_mutex);
dbs_timer_exit(this_dbs_info);
+
+ mutex_lock(&dbs_mutex);
sysfs_remove_group(&policy->kobj, &dbs_attr_group);
dbs_enable--;
+ mutex_destroy(&this_dbs_info->timer_mutex);
/*
* Stop the timerschedule work, when this governor
@@ -616,7 +603,7 @@
break;
case CPUFREQ_GOV_LIMITS:
- mutex_lock(&dbs_mutex);
+ mutex_lock(&this_dbs_info->timer_mutex);
if (policy->max < this_dbs_info->cur_policy->cur)
__cpufreq_driver_target(
this_dbs_info->cur_policy,
@@ -625,7 +612,7 @@
__cpufreq_driver_target(
this_dbs_info->cur_policy,
policy->min, CPUFREQ_RELATION_L);
- mutex_unlock(&dbs_mutex);
+ mutex_unlock(&this_dbs_info->timer_mutex);
break;
}
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 1911d17..d6ba142 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -70,23 +70,21 @@
unsigned int freq_lo_jiffies;
unsigned int freq_hi_jiffies;
int cpu;
- unsigned int enable:1,
- sample_type:1;
+ unsigned int sample_type:1;
+ /*
+ * percpu mutex that serializes governor limit change with
+ * do_dbs_timer invocation. We do not want do_dbs_timer to run
+ * when user is changing the governor or limits.
+ */
+ struct mutex timer_mutex;
};
static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
static unsigned int dbs_enable; /* number of CPUs using this policy */
/*
- * DEADLOCK ALERT! There is a ordering requirement between cpu_hotplug
- * lock and dbs_mutex. cpu_hotplug lock should always be held before
- * dbs_mutex. If any function that can potentially take cpu_hotplug lock
- * (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then
- * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock
- * is recursive for the same process. -Venki
- * DEADLOCK ALERT! (2) : do_dbs_timer() must not take the dbs_mutex, because it
- * would deadlock with cancel_delayed_work_sync(), which is needed for proper
- * raceless workqueue teardown.
+ * dbs_mutex protects data in dbs_tuners_ins from concurrent changes on
+ * different CPUs. It protects dbs_enable in governor start/stop.
*/
static DEFINE_MUTEX(dbs_mutex);
@@ -192,13 +190,18 @@
return freq_hi;
}
+static void ondemand_powersave_bias_init_cpu(int cpu)
+{
+ struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu);
+ dbs_info->freq_table = cpufreq_frequency_get_table(cpu);
+ dbs_info->freq_lo = 0;
+}
+
static void ondemand_powersave_bias_init(void)
{
int i;
for_each_online_cpu(i) {
- struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, i);
- dbs_info->freq_table = cpufreq_frequency_get_table(i);
- dbs_info->freq_lo = 0;
+ ondemand_powersave_bias_init_cpu(i);
}
}
@@ -240,12 +243,10 @@
unsigned int input;
int ret;
ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
mutex_lock(&dbs_mutex);
- if (ret != 1) {
- mutex_unlock(&dbs_mutex);
- return -EINVAL;
- }
dbs_tuners_ins.sampling_rate = max(input, min_sampling_rate);
mutex_unlock(&dbs_mutex);
@@ -259,13 +260,12 @@
int ret;
ret = sscanf(buf, "%u", &input);
- mutex_lock(&dbs_mutex);
if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD ||
input < MIN_FREQUENCY_UP_THRESHOLD) {
- mutex_unlock(&dbs_mutex);
return -EINVAL;
}
+ mutex_lock(&dbs_mutex);
dbs_tuners_ins.up_threshold = input;
mutex_unlock(&dbs_mutex);
@@ -363,9 +363,6 @@
struct cpufreq_policy *policy;
unsigned int j;
- if (!this_dbs_info->enable)
- return;
-
this_dbs_info->freq_lo = 0;
policy = this_dbs_info->cur_policy;
@@ -493,14 +490,7 @@
int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
delay -= jiffies % delay;
-
- if (lock_policy_rwsem_write(cpu) < 0)
- return;
-
- if (!dbs_info->enable) {
- unlock_policy_rwsem_write(cpu);
- return;
- }
+ mutex_lock(&dbs_info->timer_mutex);
/* Common NORMAL_SAMPLE setup */
dbs_info->sample_type = DBS_NORMAL_SAMPLE;
@@ -517,7 +507,7 @@
dbs_info->freq_lo, CPUFREQ_RELATION_H);
}
queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay);
- unlock_policy_rwsem_write(cpu);
+ mutex_unlock(&dbs_info->timer_mutex);
}
static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
@@ -526,8 +516,6 @@
int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
delay -= jiffies % delay;
- dbs_info->enable = 1;
- ondemand_powersave_bias_init();
dbs_info->sample_type = DBS_NORMAL_SAMPLE;
INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work,
@@ -536,7 +524,6 @@
static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
{
- dbs_info->enable = 0;
cancel_delayed_work_sync(&dbs_info->work);
}
@@ -555,19 +542,15 @@
if ((!cpu_online(cpu)) || (!policy->cur))
return -EINVAL;
- if (this_dbs_info->enable) /* Already enabled */
- break;
-
mutex_lock(&dbs_mutex);
- dbs_enable++;
rc = sysfs_create_group(&policy->kobj, &dbs_attr_group);
if (rc) {
- dbs_enable--;
mutex_unlock(&dbs_mutex);
return rc;
}
+ dbs_enable++;
for_each_cpu(j, policy->cpus) {
struct cpu_dbs_info_s *j_dbs_info;
j_dbs_info = &per_cpu(cpu_dbs_info, j);
@@ -581,6 +564,8 @@
}
}
this_dbs_info->cpu = cpu;
+ ondemand_powersave_bias_init_cpu(cpu);
+ mutex_init(&this_dbs_info->timer_mutex);
/*
* Start the timerschedule work, when this governor
* is used for first time
@@ -598,29 +583,31 @@
max(min_sampling_rate,
latency * LATENCY_MULTIPLIER);
}
- dbs_timer_init(this_dbs_info);
-
mutex_unlock(&dbs_mutex);
+
+ dbs_timer_init(this_dbs_info);
break;
case CPUFREQ_GOV_STOP:
- mutex_lock(&dbs_mutex);
dbs_timer_exit(this_dbs_info);
+
+ mutex_lock(&dbs_mutex);
sysfs_remove_group(&policy->kobj, &dbs_attr_group);
+ mutex_destroy(&this_dbs_info->timer_mutex);
dbs_enable--;
mutex_unlock(&dbs_mutex);
break;
case CPUFREQ_GOV_LIMITS:
- mutex_lock(&dbs_mutex);
+ mutex_lock(&this_dbs_info->timer_mutex);
if (policy->max < this_dbs_info->cur_policy->cur)
__cpufreq_driver_target(this_dbs_info->cur_policy,
policy->max, CPUFREQ_RELATION_H);
else if (policy->min > this_dbs_info->cur_policy->cur)
__cpufreq_driver_target(this_dbs_info->cur_policy,
policy->min, CPUFREQ_RELATION_L);
- mutex_unlock(&dbs_mutex);
+ mutex_unlock(&this_dbs_info->timer_mutex);
break;
}
return 0;
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c
index 543fcca..f74edae 100644
--- a/drivers/firewire/core-card.c
+++ b/drivers/firewire/core-card.c
@@ -196,8 +196,8 @@
{
int channel, bandwidth = 0;
- fw_iso_resource_manage(card, generation, 1ULL << 31,
- &channel, &bandwidth, true);
+ fw_iso_resource_manage(card, generation, 1ULL << 31, &channel,
+ &bandwidth, true, card->bm_transaction_data);
if (channel == 31) {
card->broadcast_channel_allocated = true;
device_for_each_child(card->device, (void *)(long)generation,
@@ -230,7 +230,6 @@
bool do_reset = false;
bool root_device_is_running;
bool root_device_is_cmc;
- __be32 lock_data[2];
spin_lock_irqsave(&card->lock, flags);
@@ -273,22 +272,23 @@
goto pick_me;
}
- lock_data[0] = cpu_to_be32(0x3f);
- lock_data[1] = cpu_to_be32(local_id);
+ card->bm_transaction_data[0] = cpu_to_be32(0x3f);
+ card->bm_transaction_data[1] = cpu_to_be32(local_id);
spin_unlock_irqrestore(&card->lock, flags);
rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
irm_id, generation, SCODE_100,
CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
- lock_data, sizeof(lock_data));
+ card->bm_transaction_data,
+ sizeof(card->bm_transaction_data));
if (rcode == RCODE_GENERATION)
/* Another bus reset, BM work has been rescheduled. */
goto out;
if (rcode == RCODE_COMPLETE &&
- lock_data[0] != cpu_to_be32(0x3f)) {
+ card->bm_transaction_data[0] != cpu_to_be32(0x3f)) {
/* Somebody else is BM. Only act as IRM. */
if (local_id == irm_id)
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index d1d30c6..ced186d 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -125,6 +125,7 @@
int generation;
u64 channels;
s32 bandwidth;
+ __be32 transaction_data[2];
struct iso_resource_event *e_alloc, *e_dealloc;
};
@@ -1049,7 +1050,8 @@
r->channels, &channel, &bandwidth,
todo == ISO_RES_ALLOC ||
todo == ISO_RES_REALLOC ||
- todo == ISO_RES_ALLOC_ONCE);
+ todo == ISO_RES_ALLOC_ONCE,
+ r->transaction_data);
/*
* Is this generation outdated already? As long as this resource sticks
* in the idr, it will be scheduled again for a newer generation or at
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c
index 166f19c..110e731 100644
--- a/drivers/firewire/core-iso.c
+++ b/drivers/firewire/core-iso.c
@@ -177,9 +177,8 @@
*/
static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
- int bandwidth, bool allocate)
+ int bandwidth, bool allocate, __be32 data[2])
{
- __be32 data[2];
int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0;
/*
@@ -215,9 +214,9 @@
}
static int manage_channel(struct fw_card *card, int irm_id, int generation,
- u32 channels_mask, u64 offset, bool allocate)
+ u32 channels_mask, u64 offset, bool allocate, __be32 data[2])
{
- __be32 data[2], c, all, old;
+ __be32 c, all, old;
int i, retry = 5;
old = all = allocate ? cpu_to_be32(~0) : 0;
@@ -260,7 +259,7 @@
}
static void deallocate_channel(struct fw_card *card, int irm_id,
- int generation, int channel)
+ int generation, int channel, __be32 buffer[2])
{
u32 mask;
u64 offset;
@@ -269,7 +268,7 @@
offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI :
CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO;
- manage_channel(card, irm_id, generation, mask, offset, false);
+ manage_channel(card, irm_id, generation, mask, offset, false, buffer);
}
/**
@@ -298,7 +297,7 @@
*/
void fw_iso_resource_manage(struct fw_card *card, int generation,
u64 channels_mask, int *channel, int *bandwidth,
- bool allocate)
+ bool allocate, __be32 buffer[2])
{
u32 channels_hi = channels_mask; /* channels 31...0 */
u32 channels_lo = channels_mask >> 32; /* channels 63...32 */
@@ -310,10 +309,12 @@
if (channels_hi)
c = manage_channel(card, irm_id, generation, channels_hi,
- CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, allocate);
+ CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI,
+ allocate, buffer);
if (channels_lo && c < 0) {
c = manage_channel(card, irm_id, generation, channels_lo,
- CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, allocate);
+ CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO,
+ allocate, buffer);
if (c >= 0)
c += 32;
}
@@ -325,12 +326,13 @@
if (*bandwidth == 0)
return;
- ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate);
+ ret = manage_bandwidth(card, irm_id, generation, *bandwidth,
+ allocate, buffer);
if (ret < 0)
*bandwidth = 0;
if (allocate && ret < 0 && c >= 0) {
- deallocate_channel(card, irm_id, generation, c);
+ deallocate_channel(card, irm_id, generation, c, buffer);
*channel = ret;
}
}
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index c3cfc64..6052816 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -120,7 +120,8 @@
int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma);
void fw_iso_resource_manage(struct fw_card *card, int generation,
- u64 channels_mask, int *channel, int *bandwidth, bool allocate);
+ u64 channels_mask, int *channel, int *bandwidth,
+ bool allocate, __be32 buffer[2]);
/* -topology */
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 24c4563..8d51568 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -201,6 +201,12 @@
#define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */
/*
+ * There is no transport protocol limit to the CDB length, but we implement
+ * a fixed length only. 16 bytes is enough for disks larger than 2 TB.
+ */
+#define SBP2_MAX_CDB_SIZE 16
+
+/*
* The default maximum s/g segment size of a FireWire controller is
* usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to
* be quadlet-aligned, we set the length limit to 0xffff & ~3.
@@ -312,7 +318,7 @@
struct sbp2_pointer next;
struct sbp2_pointer data_descriptor;
__be32 misc;
- u8 command_block[12];
+ u8 command_block[SBP2_MAX_CDB_SIZE];
} request;
struct scsi_cmnd *cmd;
scsi_done_fn_t done;
@@ -1146,6 +1152,8 @@
if (fw_device_enable_phys_dma(device) < 0)
goto fail_shost_put;
+ shost->max_cmd_len = SBP2_MAX_CDB_SIZE;
+
if (scsi_add_host(shost, &unit->device) < 0)
goto fail_shost_put;
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index e447674..b1bc6e2 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -85,10 +85,11 @@
{
volatile struct iic_regs __iomem *iic = dev->vaddr;
printk(KERN_DEBUG "ibm-iic%d: %s\n", dev->idx, header);
- printk(KERN_DEBUG " cntl = 0x%02x, mdcntl = 0x%02x\n"
- KERN_DEBUG " sts = 0x%02x, extsts = 0x%02x\n"
- KERN_DEBUG " clkdiv = 0x%02x, xfrcnt = 0x%02x\n"
- KERN_DEBUG " xtcntlss = 0x%02x, directcntl = 0x%02x\n",
+ printk(KERN_DEBUG
+ " cntl = 0x%02x, mdcntl = 0x%02x\n"
+ " sts = 0x%02x, extsts = 0x%02x\n"
+ " clkdiv = 0x%02x, xfrcnt = 0x%02x\n"
+ " xtcntlss = 0x%02x, directcntl = 0x%02x\n",
in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts),
in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt),
in_8(&iic->xtcntlss), in_8(&iic->directcntl));
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index d5f3c77..db96138 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -466,14 +466,10 @@
if (!ide_lock_port(hwif)) {
ide_hwif_t *prev_port;
+
+ WARN_ON_ONCE(hwif->rq);
repeat:
prev_port = hwif->host->cur_port;
-
- if (drive->dev_flags & IDE_DFLAG_BLOCKED)
- rq = hwif->rq;
- else
- WARN_ON_ONCE(hwif->rq);
-
if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
time_after(drive->sleep, jiffies)) {
ide_unlock_port(hwif);
@@ -500,29 +496,43 @@
hwif->cur_dev = drive;
drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);
- if (rq == NULL) {
- spin_unlock_irq(&hwif->lock);
- spin_lock_irq(q->queue_lock);
- /*
- * we know that the queue isn't empty, but this can
- * happen if ->prep_rq_fn() decides to kill a request
- */
+ spin_unlock_irq(&hwif->lock);
+ spin_lock_irq(q->queue_lock);
+ /*
+ * we know that the queue isn't empty, but this can happen
+ * if the q->prep_rq_fn() decides to kill a request
+ */
+ if (!rq)
rq = blk_fetch_request(drive->queue);
- spin_unlock_irq(q->queue_lock);
- spin_lock_irq(&hwif->lock);
- if (rq == NULL) {
- ide_unlock_port(hwif);
- goto out;
- }
+ spin_unlock_irq(q->queue_lock);
+ spin_lock_irq(&hwif->lock);
+
+ if (!rq) {
+ ide_unlock_port(hwif);
+ goto out;
}
/*
* Sanity: don't accept a request that isn't a PM request
- * if we are currently power managed.
+ * if we are currently power managed. This is very important as
+ * blk_stop_queue() doesn't prevent the blk_fetch_request()
+ * above to return us whatever is in the queue. Since we call
+ * ide_do_request() ourselves, we end up taking requests while
+ * the queue is blocked...
+ *
+ * We let requests forced at head of queue with ide-preempt
+ * though. I hope that doesn't happen too much, hopefully not
+ * unless the subdriver triggers such a thing in its own PM
+ * state machine.
*/
- BUG_ON((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
- blk_pm_request(rq) == 0);
+ if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
+ blk_pm_request(rq) == 0 &&
+ (rq->cmd_flags & REQ_PREEMPT) == 0) {
+ /* there should be no pending command at this point */
+ ide_unlock_port(hwif);
+ goto plug_device;
+ }
hwif->rq = rq;
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 83b734a..52b25f8 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -880,6 +880,7 @@
}
shost->hostdata[0] = (unsigned long)lu;
+ shost->max_cmd_len = SBP2_MAX_CDB_SIZE;
if (!scsi_add_host(shost, &ud->device)) {
lu->shost = shost;
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index c5036f1..64a3a66 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -25,6 +25,12 @@
#define SBP2_DEVICE_NAME "sbp2"
/*
+ * There is no transport protocol limit to the CDB length, but we implement
+ * a fixed length only. 16 bytes is enough for disks larger than 2 TB.
+ */
+#define SBP2_MAX_CDB_SIZE 16
+
+/*
* SBP-2 specific definitions
*/
@@ -51,7 +57,7 @@
u32 data_descriptor_hi;
u32 data_descriptor_lo;
u32 misc;
- u8 cdb[12];
+ u8 cdb[SBP2_MAX_CDB_SIZE];
} __attribute__((packed));
#define SBP2_LOGIN_REQUEST 0x0
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 9d8f796..a6b989a 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -12,6 +12,42 @@
if INPUT_KEYBOARD
+config KEYBOARD_AAED2000
+ tristate "AAED-2000 keyboard"
+ depends on MACH_AAED2000
+ select INPUT_POLLDEV
+ default y
+ help
+ Say Y here to enable the keyboard on the Agilent AAED-2000
+ development board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called aaed2000_kbd.
+
+config KEYBOARD_AMIGA
+ tristate "Amiga keyboard"
+ depends on AMIGA
+ help
+ Say Y here if you are running Linux on any AMIGA and have a keyboard
+ attached.
+
+ To compile this driver as a module, choose M here: the
+ module will be called amikbd.
+
+config ATARI_KBD_CORE
+ bool
+
+config KEYBOARD_ATARI
+ tristate "Atari keyboard"
+ depends on ATARI
+ select ATARI_KBD_CORE
+ help
+ Say Y here if you are running Linux on any Atari and have a keyboard
+ attached.
+
+ To compile this driver as a module, choose M here: the
+ module will be called atakbd.
+
config KEYBOARD_ATKBD
tristate "AT keyboard" if EMBEDDED || !X86
default y
@@ -68,16 +104,25 @@
right-hand column will be interpreted as the key shown in the
left-hand column.
-config KEYBOARD_SUNKBD
- tristate "Sun Type 4 and Type 5 keyboard"
- select SERIO
+config KEYBOARD_BFIN
+ tristate "Blackfin BF54x keypad support"
+ depends on (BF54x && !BF544)
help
- Say Y here if you want to use a Sun Type 4 or Type 5 keyboard,
- connected either to the Sun keyboard connector or to an serial
- (RS-232) port via a simple adapter.
+ Say Y here if you want to use the BF54x keypad.
To compile this driver as a module, choose M here: the
- module will be called sunkbd.
+ module will be called bf54x-keys.
+
+config KEYBOARD_CORGI
+ tristate "Corgi keyboard"
+ depends on PXA_SHARPSL
+ default y
+ help
+ Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx
+ series of PDAs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called corgikbd.
config KEYBOARD_LKKBD
tristate "DECstation/VAXstation LK201/LK401 keyboard"
@@ -91,113 +136,38 @@
To compile this driver as a module, choose M here: the
module will be called lkkbd.
-config KEYBOARD_LOCOMO
- tristate "LoCoMo Keyboard Support"
- depends on SHARP_LOCOMO && INPUT_KEYBOARD
+config KEYBOARD_EP93XX
+ tristate "EP93xx Matrix Keypad support"
+ depends on ARCH_EP93XX
help
- Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
+ Say Y here to enable the matrix keypad on the Cirrus EP93XX.
To compile this driver as a module, choose M here: the
- module will be called locomokbd.
+ module will be called ep93xx_keypad.
-config KEYBOARD_XTKBD
- tristate "XT keyboard"
- select SERIO
+config KEYBOARD_GPIO
+ tristate "GPIO Buttons"
+ depends on GENERIC_GPIO
help
- Say Y here if you want to use the old IBM PC/XT keyboard (or
- compatible) on your system. This is only possible with a
- parallel port keyboard adapter, you cannot connect it to the
- keyboard port on a PC that runs Linux.
+ This driver implements support for buttons connected
+ to GPIO pins of various CPUs (and some other chips).
+
+ Say Y here if your device has buttons connected
+ directly to such GPIO pins. Your board-specific
+ setup logic must also provide a platform device,
+ with configuration data saying which GPIOs are used.
To compile this driver as a module, choose M here: the
- module will be called xtkbd.
+ module will be called gpio_keys.
-config KEYBOARD_NEWTON
- tristate "Newton keyboard"
- select SERIO
+config KEYBOARD_MATRIX
+ tristate "GPIO driven matrix keypad support"
+ depends on GENERIC_GPIO
help
- Say Y here if you have a Newton keyboard on a serial port.
+ Enable support for GPIO driven matrix keypad.
To compile this driver as a module, choose M here: the
- module will be called newtonkbd.
-
-config KEYBOARD_STOWAWAY
- tristate "Stowaway keyboard"
- select SERIO
- help
- Say Y here if you have a Stowaway keyboard on a serial port.
- Stowaway compatible keyboards like Dicota Input-PDA keyboard
- are also supported by this driver.
-
- To compile this driver as a module, choose M here: the
- module will be called stowaway.
-
-config KEYBOARD_CORGI
- tristate "Corgi keyboard"
- depends on PXA_SHARPSL
- default y
- help
- Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx
- series of PDAs.
-
- To compile this driver as a module, choose M here: the
- module will be called corgikbd.
-
-config KEYBOARD_SPITZ
- tristate "Spitz keyboard"
- depends on PXA_SHARPSL
- default y
- help
- Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
- SL-C3000 and Sl-C3100 series of PDAs.
-
- To compile this driver as a module, choose M here: the
- module will be called spitzkbd.
-
-config KEYBOARD_TOSA
- tristate "Tosa keyboard"
- depends on MACH_TOSA
- default y
- help
- Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa)
-
- To compile this driver as a module, choose M here: the
- module will be called tosakbd.
-
-config KEYBOARD_TOSA_USE_EXT_KEYCODES
- bool "Tosa keyboard: use extended keycodes"
- depends on KEYBOARD_TOSA
- default n
- help
- Say Y here to enable the tosa keyboard driver to generate extended
- (>= 127) keycodes. Be aware, that they can't be correctly interpreted
- by either console keyboard driver or by Kdrive keybd driver.
-
- Say Y only if you know, what you are doing!
-
-config KEYBOARD_AMIGA
- tristate "Amiga keyboard"
- depends on AMIGA
- help
- Say Y here if you are running Linux on any AMIGA and have a keyboard
- attached.
-
- To compile this driver as a module, choose M here: the
- module will be called amikbd.
-
-config ATARI_KBD_CORE
- bool
-
-config KEYBOARD_ATARI
- tristate "Atari keyboard"
- depends on ATARI
- select ATARI_KBD_CORE
- help
- Say Y here if you are running Linux on any Atari and have a keyboard
- attached.
-
- To compile this driver as a module, choose M here: the
- module will be called atakbd.
+ module will be called matrix_keypad.
config KEYBOARD_HIL_OLD
tristate "HP HIL keyboard support (simple driver)"
@@ -261,20 +231,39 @@
To compile this driver as a module, choose M here: the
module will be called lm8323.
-config KEYBOARD_OMAP
- tristate "TI OMAP keypad support"
- depends on (ARCH_OMAP1 || ARCH_OMAP2)
+config KEYBOARD_LOCOMO
+ tristate "LoCoMo Keyboard Support"
+ depends on SHARP_LOCOMO
help
- Say Y here if you want to use the OMAP keypad.
+ Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
To compile this driver as a module, choose M here: the
- module will be called omap-keypad.
+ module will be called locomokbd.
+
+config KEYBOARD_MAPLE
+ tristate "Maple bus keyboard"
+ depends on SH_DREAMCAST && MAPLE
+ help
+ Say Y here if you have a Dreamcast console running Linux and have
+ a keyboard attached to its Maple bus.
+
+ To compile this driver as a module, choose M here: the
+ module will be called maple_keyb.
+
+config KEYBOARD_NEWTON
+ tristate "Newton keyboard"
+ select SERIO
+ help
+ Say Y here if you have a Newton keyboard on a serial port.
+
+ To compile this driver as a module, choose M here: the
+ module will be called newtonkbd.
config KEYBOARD_PXA27x
tristate "PXA27x/PXA3xx keypad support"
depends on PXA27x || PXA3xx
help
- Enable support for PXA27x/PXA3xx keypad controller
+ Enable support for PXA27x/PXA3xx keypad controller.
To compile this driver as a module, choose M here: the
module will be called pxa27x_keypad.
@@ -288,51 +277,38 @@
To compile this driver as a module, choose M here: the
module will be called pxa930_rotary.
-config KEYBOARD_AAED2000
- tristate "AAED-2000 keyboard"
- depends on MACH_AAED2000
- select INPUT_POLLDEV
+config KEYBOARD_SPITZ
+ tristate "Spitz keyboard"
+ depends on PXA_SHARPSL
default y
help
- Say Y here to enable the keyboard on the Agilent AAED-2000
- development board.
+ Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
+ SL-C3000 and Sl-C3100 series of PDAs.
To compile this driver as a module, choose M here: the
- module will be called aaed2000_kbd.
+ module will be called spitzkbd.
-config KEYBOARD_GPIO
- tristate "GPIO Buttons"
- depends on GENERIC_GPIO
+config KEYBOARD_STOWAWAY
+ tristate "Stowaway keyboard"
+ select SERIO
help
- This driver implements support for buttons connected
- to GPIO pins of various CPUs (and some other chips).
-
- Say Y here if your device has buttons connected
- directly to such GPIO pins. Your board-specific
- setup logic must also provide a platform device,
- with configuration data saying which GPIOs are used.
+ Say Y here if you have a Stowaway keyboard on a serial port.
+ Stowaway compatible keyboards like Dicota Input-PDA keyboard
+ are also supported by this driver.
To compile this driver as a module, choose M here: the
- module will be called gpio-keys.
+ module will be called stowaway.
-config KEYBOARD_MAPLE
- tristate "Maple bus keyboard"
- depends on SH_DREAMCAST && MAPLE
+config KEYBOARD_SUNKBD
+ tristate "Sun Type 4 and Type 5 keyboard"
+ select SERIO
help
- Say Y here if you have a Dreamcast console running Linux and have
- a keyboard attached to its Maple bus.
+ Say Y here if you want to use a Sun Type 4 or Type 5 keyboard,
+ connected either to the Sun keyboard connector or to an serial
+ (RS-232) port via a simple adapter.
To compile this driver as a module, choose M here: the
- module will be called maple_keyb.
-
-config KEYBOARD_BFIN
- tristate "Blackfin BF54x keypad support"
- depends on (BF54x && !BF544)
- help
- Say Y here if you want to use the BF54x keypad.
-
- To compile this driver as a module, choose M here: the
- module will be called bf54x-keys.
+ module will be called sunkbd.
config KEYBOARD_SH_KEYSC
tristate "SuperH KEYSC keypad support"
@@ -344,13 +320,45 @@
To compile this driver as a module, choose M here: the
module will be called sh_keysc.
-config KEYBOARD_EP93XX
- tristate "EP93xx Matrix Keypad support"
- depends on ARCH_EP93XX
+config KEYBOARD_OMAP
+ tristate "TI OMAP keypad support"
+ depends on (ARCH_OMAP1 || ARCH_OMAP2)
help
- Say Y here to enable the matrix keypad on the Cirrus EP93XX.
+ Say Y here if you want to use the OMAP keypad.
To compile this driver as a module, choose M here: the
- module will be called ep93xx_keypad.
+ module will be called omap-keypad.
+
+config KEYBOARD_TOSA
+ tristate "Tosa keyboard"
+ depends on MACH_TOSA
+ default y
+ help
+ Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa)
+
+ To compile this driver as a module, choose M here: the
+ module will be called tosakbd.
+
+config KEYBOARD_TOSA_USE_EXT_KEYCODES
+ bool "Tosa keyboard: use extended keycodes"
+ depends on KEYBOARD_TOSA
+ help
+ Say Y here to enable the tosa keyboard driver to generate extended
+ (>= 127) keycodes. Be aware, that they can't be correctly interpreted
+ by either console keyboard driver or by Kdrive keybd driver.
+
+ Say Y only if you know, what you are doing!
+
+config KEYBOARD_XTKBD
+ tristate "XT keyboard"
+ select SERIO
+ help
+ Say Y here if you want to use the old IBM PC/XT keyboard (or
+ compatible) on your system. This is only possible with a
+ parallel port keyboard adapter, you cannot connect it to the
+ keyboard port on a PC that runs Linux.
+
+ To compile this driver as a module, choose M here: the
+ module will be called xtkbd.
endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 156b647..b5b5eae 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -4,29 +4,30 @@
# Each configuration option enables a list of files.
-obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o
-obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
-obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o
-obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
+obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o
obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o
-obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o
-obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
-obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
+obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o
+obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o
obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
-obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
-obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o
+obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
+obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
+obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o
+obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o
+obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o
obj-$(CONFIG_KEYBOARD_LM8323) += lm8323.o
+obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o
+obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o
+obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o
+obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o
obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o
-obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
-obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
-obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o
-obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o
-obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o
-obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o
obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
-obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
+obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
+obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
+obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
+obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o
+obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index 2157cd7..efed0c9 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -29,7 +29,8 @@
struct gpio_button_data {
struct gpio_keys_button *button;
struct input_dev *input;
- struct delayed_work work;
+ struct timer_list timer;
+ struct work_struct work;
};
struct gpio_keys_drvdata {
@@ -40,7 +41,7 @@
static void gpio_keys_report_event(struct work_struct *work)
{
struct gpio_button_data *bdata =
- container_of(work, struct gpio_button_data, work.work);
+ container_of(work, struct gpio_button_data, work);
struct gpio_keys_button *button = bdata->button;
struct input_dev *input = bdata->input;
unsigned int type = button->type ?: EV_KEY;
@@ -50,17 +51,25 @@
input_sync(input);
}
+static void gpio_keys_timer(unsigned long _data)
+{
+ struct gpio_button_data *data = (struct gpio_button_data *)_data;
+
+ schedule_work(&data->work);
+}
+
static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
{
struct gpio_button_data *bdata = dev_id;
struct gpio_keys_button *button = bdata->button;
- unsigned long delay;
BUG_ON(irq != gpio_to_irq(button->gpio));
- delay = button->debounce_interval ?
- msecs_to_jiffies(button->debounce_interval) : 0;
- schedule_delayed_work(&bdata->work, delay);
+ if (button->debounce_interval)
+ mod_timer(&bdata->timer,
+ jiffies + msecs_to_jiffies(button->debounce_interval));
+ else
+ schedule_work(&bdata->work);
return IRQ_HANDLED;
}
@@ -107,7 +116,9 @@
bdata->input = input;
bdata->button = button;
- INIT_DELAYED_WORK(&bdata->work, gpio_keys_report_event);
+ setup_timer(&bdata->timer,
+ gpio_keys_timer, (unsigned long)bdata);
+ INIT_WORK(&bdata->work, gpio_keys_report_event);
error = gpio_request(button->gpio, button->desc ?: "gpio_keys");
if (error < 0) {
@@ -166,7 +177,9 @@
fail2:
while (--i >= 0) {
free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
- cancel_delayed_work_sync(&ddata->data[i].work);
+ if (pdata->buttons[i].debounce_interval)
+ del_timer_sync(&ddata->data[i].timer);
+ cancel_work_sync(&ddata->data[i].work);
gpio_free(pdata->buttons[i].gpio);
}
@@ -190,7 +203,9 @@
for (i = 0; i < pdata->nbuttons; i++) {
int irq = gpio_to_irq(pdata->buttons[i].gpio);
free_irq(irq, &ddata->data[i]);
- cancel_delayed_work_sync(&ddata->data[i].work);
+ if (pdata->buttons[i].debounce_interval)
+ del_timer_sync(&ddata->data[i].timer);
+ cancel_work_sync(&ddata->data[i].work);
gpio_free(pdata->buttons[i].gpio);
}
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
new file mode 100644
index 0000000..e9b2e7cb
--- /dev/null
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -0,0 +1,453 @@
+/*
+ * GPIO driven matrix keyboard driver
+ *
+ * Copyright (c) 2008 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on corgikbd.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/input/matrix_keypad.h>
+
+struct matrix_keypad {
+ const struct matrix_keypad_platform_data *pdata;
+ struct input_dev *input_dev;
+ unsigned short *keycodes;
+
+ uint32_t last_key_state[MATRIX_MAX_COLS];
+ struct delayed_work work;
+ bool scan_pending;
+ bool stopped;
+ spinlock_t lock;
+};
+
+/*
+ * NOTE: normally the GPIO has to be put into HiZ when de-activated to cause
+ * minmal side effect when scanning other columns, here it is configured to
+ * be input, and it should work on most platforms.
+ */
+static void __activate_col(const struct matrix_keypad_platform_data *pdata,
+ int col, bool on)
+{
+ bool level_on = !pdata->active_low;
+
+ if (on) {
+ gpio_direction_output(pdata->col_gpios[col], level_on);
+ } else {
+ gpio_set_value_cansleep(pdata->col_gpios[col], !level_on);
+ gpio_direction_input(pdata->col_gpios[col]);
+ }
+}
+
+static void activate_col(const struct matrix_keypad_platform_data *pdata,
+ int col, bool on)
+{
+ __activate_col(pdata, col, on);
+
+ if (on && pdata->col_scan_delay_us)
+ udelay(pdata->col_scan_delay_us);
+}
+
+static void activate_all_cols(const struct matrix_keypad_platform_data *pdata,
+ bool on)
+{
+ int col;
+
+ for (col = 0; col < pdata->num_col_gpios; col++)
+ __activate_col(pdata, col, on);
+}
+
+static bool row_asserted(const struct matrix_keypad_platform_data *pdata,
+ int row)
+{
+ return gpio_get_value_cansleep(pdata->row_gpios[row]) ?
+ !pdata->active_low : pdata->active_low;
+}
+
+static void enable_row_irqs(struct matrix_keypad *keypad)
+{
+ const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+ int i;
+
+ for (i = 0; i < pdata->num_row_gpios; i++)
+ enable_irq(gpio_to_irq(pdata->row_gpios[i]));
+}
+
+static void disable_row_irqs(struct matrix_keypad *keypad)
+{
+ const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+ int i;
+
+ for (i = 0; i < pdata->num_row_gpios; i++)
+ disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i]));
+}
+
+/*
+ * This gets the keys from keyboard and reports it to input subsystem
+ */
+static void matrix_keypad_scan(struct work_struct *work)
+{
+ struct matrix_keypad *keypad =
+ container_of(work, struct matrix_keypad, work.work);
+ struct input_dev *input_dev = keypad->input_dev;
+ const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+ uint32_t new_state[MATRIX_MAX_COLS];
+ int row, col, code;
+
+ /* de-activate all columns for scanning */
+ activate_all_cols(pdata, false);
+
+ memset(new_state, 0, sizeof(new_state));
+
+ /* assert each column and read the row status out */
+ for (col = 0; col < pdata->num_col_gpios; col++) {
+
+ activate_col(pdata, col, true);
+
+ for (row = 0; row < pdata->num_row_gpios; row++)
+ new_state[col] |=
+ row_asserted(pdata, row) ? (1 << row) : 0;
+
+ activate_col(pdata, col, false);
+ }
+
+ for (col = 0; col < pdata->num_col_gpios; col++) {
+ uint32_t bits_changed;
+
+ bits_changed = keypad->last_key_state[col] ^ new_state[col];
+ if (bits_changed == 0)
+ continue;
+
+ for (row = 0; row < pdata->num_row_gpios; row++) {
+ if ((bits_changed & (1 << row)) == 0)
+ continue;
+
+ code = (row << 4) + col;
+ input_event(input_dev, EV_MSC, MSC_SCAN, code);
+ input_report_key(input_dev,
+ keypad->keycodes[code],
+ new_state[col] & (1 << row));
+ }
+ }
+ input_sync(input_dev);
+
+ memcpy(keypad->last_key_state, new_state, sizeof(new_state));
+
+ activate_all_cols(pdata, true);
+
+ /* Enable IRQs again */
+ spin_lock_irq(&keypad->lock);
+ keypad->scan_pending = false;
+ enable_row_irqs(keypad);
+ spin_unlock_irq(&keypad->lock);
+}
+
+static irqreturn_t matrix_keypad_interrupt(int irq, void *id)
+{
+ struct matrix_keypad *keypad = id;
+ unsigned long flags;
+
+ spin_lock_irqsave(&keypad->lock, flags);
+
+ /*
+ * See if another IRQ beaten us to it and scheduled the
+ * scan already. In that case we should not try to
+ * disable IRQs again.
+ */
+ if (unlikely(keypad->scan_pending || keypad->stopped))
+ goto out;
+
+ disable_row_irqs(keypad);
+ keypad->scan_pending = true;
+ schedule_delayed_work(&keypad->work,
+ msecs_to_jiffies(keypad->pdata->debounce_ms));
+
+out:
+ spin_unlock_irqrestore(&keypad->lock, flags);
+ return IRQ_HANDLED;
+}
+
+static int matrix_keypad_start(struct input_dev *dev)
+{
+ struct matrix_keypad *keypad = input_get_drvdata(dev);
+
+ keypad->stopped = false;
+ mb();
+
+ /*
+ * Schedule an immediate key scan to capture current key state;
+ * columns will be activated and IRQs be enabled after the scan.
+ */
+ schedule_delayed_work(&keypad->work, 0);
+
+ return 0;
+}
+
+static void matrix_keypad_stop(struct input_dev *dev)
+{
+ struct matrix_keypad *keypad = input_get_drvdata(dev);
+
+ keypad->stopped = true;
+ mb();
+ flush_work(&keypad->work.work);
+ /*
+ * matrix_keypad_scan() will leave IRQs enabled;
+ * we should disable them now.
+ */
+ disable_row_irqs(keypad);
+}
+
+#ifdef CONFIG_PM
+static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct matrix_keypad *keypad = platform_get_drvdata(pdev);
+ const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+ int i;
+
+ matrix_keypad_stop(keypad->input_dev);
+
+ if (device_may_wakeup(&pdev->dev))
+ for (i = 0; i < pdata->num_row_gpios; i++)
+ enable_irq_wake(gpio_to_irq(pdata->row_gpios[i]));
+
+ return 0;
+}
+
+static int matrix_keypad_resume(struct platform_device *pdev)
+{
+ struct matrix_keypad *keypad = platform_get_drvdata(pdev);
+ const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+ int i;
+
+ if (device_may_wakeup(&pdev->dev))
+ for (i = 0; i < pdata->num_row_gpios; i++)
+ disable_irq_wake(gpio_to_irq(pdata->row_gpios[i]));
+
+ matrix_keypad_start(keypad->input_dev);
+
+ return 0;
+}
+#else
+#define matrix_keypad_suspend NULL
+#define matrix_keypad_resume NULL
+#endif
+
+static int __devinit init_matrix_gpio(struct platform_device *pdev,
+ struct matrix_keypad *keypad)
+{
+ const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+ int i, err = -EINVAL;
+
+ /* initialized strobe lines as outputs, activated */
+ for (i = 0; i < pdata->num_col_gpios; i++) {
+ err = gpio_request(pdata->col_gpios[i], "matrix_kbd_col");
+ if (err) {
+ dev_err(&pdev->dev,
+ "failed to request GPIO%d for COL%d\n",
+ pdata->col_gpios[i], i);
+ goto err_free_cols;
+ }
+
+ gpio_direction_output(pdata->col_gpios[i], !pdata->active_low);
+ }
+
+ for (i = 0; i < pdata->num_row_gpios; i++) {
+ err = gpio_request(pdata->row_gpios[i], "matrix_kbd_row");
+ if (err) {
+ dev_err(&pdev->dev,
+ "failed to request GPIO%d for ROW%d\n",
+ pdata->row_gpios[i], i);
+ goto err_free_rows;
+ }
+
+ gpio_direction_input(pdata->row_gpios[i]);
+ }
+
+ for (i = 0; i < pdata->num_row_gpios; i++) {
+ err = request_irq(gpio_to_irq(pdata->row_gpios[i]),
+ matrix_keypad_interrupt,
+ IRQF_DISABLED |
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "matrix-keypad", keypad);
+ if (err) {
+ dev_err(&pdev->dev,
+ "Unable to acquire interrupt for GPIO line %i\n",
+ pdata->row_gpios[i]);
+ goto err_free_irqs;
+ }
+ }
+
+ /* initialized as disabled - enabled by input->open */
+ disable_row_irqs(keypad);
+ return 0;
+
+err_free_irqs:
+ while (--i >= 0)
+ free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
+ i = pdata->num_row_gpios;
+err_free_rows:
+ while (--i >= 0)
+ gpio_free(pdata->row_gpios[i]);
+ i = pdata->num_col_gpios;
+err_free_cols:
+ while (--i >= 0)
+ gpio_free(pdata->col_gpios[i]);
+
+ return err;
+}
+
+static int __devinit matrix_keypad_probe(struct platform_device *pdev)
+{
+ const struct matrix_keypad_platform_data *pdata;
+ const struct matrix_keymap_data *keymap_data;
+ struct matrix_keypad *keypad;
+ struct input_dev *input_dev;
+ unsigned short *keycodes;
+ int i;
+ int err;
+
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data defined\n");
+ return -EINVAL;
+ }
+
+ keymap_data = pdata->keymap_data;
+ if (!keymap_data) {
+ dev_err(&pdev->dev, "no keymap data defined\n");
+ return -EINVAL;
+ }
+
+ if (!keymap_data->max_keymap_size) {
+ dev_err(&pdev->dev, "invalid keymap data supplied\n");
+ return -EINVAL;
+ }
+
+ keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL);
+ keycodes = kzalloc(keymap_data->max_keymap_size *
+ sizeof(keypad->keycodes),
+ GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!keypad || !keycodes || !input_dev) {
+ err = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ keypad->input_dev = input_dev;
+ keypad->pdata = pdata;
+ keypad->keycodes = keycodes;
+ keypad->stopped = true;
+ INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan);
+ spin_lock_init(&keypad->lock);
+
+ input_dev->name = pdev->name;
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->dev.parent = &pdev->dev;
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+ input_dev->open = matrix_keypad_start;
+ input_dev->close = matrix_keypad_stop;
+
+ input_dev->keycode = keycodes;
+ input_dev->keycodesize = sizeof(*keycodes);
+ input_dev->keycodemax = keymap_data->max_keymap_size;
+
+ for (i = 0; i < keymap_data->keymap_size; i++) {
+ unsigned int key = keymap_data->keymap[i];
+ unsigned int row = KEY_ROW(key);
+ unsigned int col = KEY_COL(key);
+ unsigned short code = KEY_VAL(key);
+
+ keycodes[(row << 4) + col] = code;
+ __set_bit(code, input_dev->keybit);
+ }
+ __clear_bit(KEY_RESERVED, input_dev->keybit);
+
+ input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+ input_set_drvdata(input_dev, keypad);
+
+ err = init_matrix_gpio(pdev, keypad);
+ if (err)
+ goto err_free_mem;
+
+ err = input_register_device(keypad->input_dev);
+ if (err)
+ goto err_free_mem;
+
+ device_init_wakeup(&pdev->dev, pdata->wakeup);
+ platform_set_drvdata(pdev, keypad);
+
+ return 0;
+
+err_free_mem:
+ input_free_device(input_dev);
+ kfree(keycodes);
+ kfree(keypad);
+ return err;
+}
+
+static int __devexit matrix_keypad_remove(struct platform_device *pdev)
+{
+ struct matrix_keypad *keypad = platform_get_drvdata(pdev);
+ const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+ int i;
+
+ device_init_wakeup(&pdev->dev, 0);
+
+ for (i = 0; i < pdata->num_row_gpios; i++) {
+ free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
+ gpio_free(pdata->row_gpios[i]);
+ }
+
+ for (i = 0; i < pdata->num_col_gpios; i++)
+ gpio_free(pdata->col_gpios[i]);
+
+ input_unregister_device(keypad->input_dev);
+ platform_set_drvdata(pdev, NULL);
+ kfree(keypad->keycodes);
+ kfree(keypad);
+
+ return 0;
+}
+
+static struct platform_driver matrix_keypad_driver = {
+ .probe = matrix_keypad_probe,
+ .remove = __devexit_p(matrix_keypad_remove),
+ .suspend = matrix_keypad_suspend,
+ .resume = matrix_keypad_resume,
+ .driver = {
+ .name = "matrix-keypad",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init matrix_keypad_init(void)
+{
+ return platform_driver_register(&matrix_keypad_driver);
+}
+
+static void __exit matrix_keypad_exit(void)
+{
+ platform_driver_unregister(&matrix_keypad_driver);
+}
+
+module_init(matrix_keypad_init);
+module_exit(matrix_keypad_exit);
+
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("GPIO Driven Matrix Keypad Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:matrix-keypad");
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c
index 5e5eb88..7b6ce17 100644
--- a/drivers/input/mouse/gpio_mouse.c
+++ b/drivers/input/mouse/gpio_mouse.c
@@ -46,7 +46,7 @@
input_sync(input);
}
-static int __init gpio_mouse_probe(struct platform_device *pdev)
+static int __devinit gpio_mouse_probe(struct platform_device *pdev)
{
struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data;
struct input_polled_dev *input_poll;
@@ -170,10 +170,8 @@
return 0;
}
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:gpio_mouse");
-
static struct platform_driver gpio_mouse_device_driver = {
+ .probe = gpio_mouse_probe,
.remove = __devexit_p(gpio_mouse_remove),
.driver = {
.name = "gpio_mouse",
@@ -183,8 +181,7 @@
static int __init gpio_mouse_init(void)
{
- return platform_driver_probe(&gpio_mouse_device_driver,
- gpio_mouse_probe);
+ return platform_driver_register(&gpio_mouse_device_driver);
}
module_init(gpio_mouse_init);
@@ -197,3 +194,5 @@
MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
MODULE_DESCRIPTION("GPIO mouse driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpio_mouse"); /* work with hotplug and coldplug */
+
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index fb8a3cd..924e8ed 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -392,6 +392,34 @@
DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
},
},
+ {
+ .ident = "Acer Aspire One 150",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
+ },
+ },
+ {
+ .ident = "Advent 4211",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"),
+ },
+ },
+ {
+ .ident = "Medion Akoya Mini E1210",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "E1210"),
+ },
+ },
+ {
+ .ident = "Mivvy M310",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
+ },
+ },
{ }
};
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index f919bf5..582245c 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -934,10 +934,11 @@
static int i8042_suspend(struct platform_device *dev, pm_message_t state)
{
- if (!i8042_suspended && state.event == PM_EVENT_SUSPEND) {
+ if (!i8042_suspended && state.event == PM_EVENT_SUSPEND)
i8042_controller_reset();
- i8042_suspended = true;
- }
+
+ i8042_suspended = state.event == PM_EVENT_SUSPEND ||
+ state.event == PM_EVENT_FREEZE;
return 0;
}
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index fb17573..d66f494 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -935,10 +935,11 @@
{
struct serio *serio = to_serio_port(dev);
- if (!serio->suspended && state.event == PM_EVENT_SUSPEND) {
+ if (!serio->suspended && state.event == PM_EVENT_SUSPEND)
serio_cleanup(serio);
- serio->suspended = true;
- }
+
+ serio->suspended = state.event == PM_EVENT_SUSPEND ||
+ state.event == PM_EVENT_FREEZE;
return 0;
}
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 38bf863..c896d6a 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -384,6 +384,8 @@
wacom_report_key(wcombo, BTN_STYLUS2, 0);
wacom_report_key(wcombo, BTN_TOUCH, 0);
wacom_report_abs(wcombo, ABS_WHEEL, 0);
+ if (wacom->features->type >= INTUOS3S)
+ wacom_report_abs(wcombo, ABS_Z, 0);
}
wacom_report_key(wcombo, wacom->tool[idx], 0);
wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
@@ -836,6 +838,7 @@
{ "Wacom DTU710", 8, 34080, 27660, 511, 0, PL },
{ "Wacom DTF521", 8, 6282, 4762, 511, 0, PL },
{ "Wacom DTF720", 8, 6858, 5506, 511, 0, PL },
+ { "Wacom DTF720a", 8, 6858, 5506, 511, 0, PL },
{ "Wacom Cintiq Partner",8, 20480, 15360, 511, 0, PTU },
{ "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS },
{ "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS },
@@ -897,8 +900,9 @@
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC2) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) },
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index ec51696..2d91049 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -294,32 +294,33 @@
{RSP_OK, 604,604, -1, 605, 5, {ACT_CMD+AT_MSN}},
{RSP_OK, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}},
{RSP_NULL, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}},
- {RSP_OK, 606,606, -1, 607, 5, {0}, "+VLS=17\r"}, /* set "Endgeraetemodus" */
+ {RSP_OK, 606,606, -1, 607, 5, {0}, "+VLS=17\r"},
{RSP_OK, 607,607, -1, 608,-1},
- //{RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 608, 0, {ACT_ERROR}},//DELETE
{RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 609, 5, {ACT_CMD+AT_DIAL}},
{RSP_OK, 609,609, -1, 650, 0, {ACT_DIALING}},
- {RSP_ZVLS, 608,608, 17, -1,-1, {ACT_DEBUG}},
- {RSP_ZCTP, 609,609, -1, -1,-1, {ACT_DEBUG}},
- {RSP_ZCPN, 609,609, -1, -1,-1, {ACT_DEBUG}},
{RSP_ERROR, 601,609, -1, 0, 0, {ACT_ABORTDIAL}},
{EV_TIMEOUT, 601,609, -1, 0, 0, {ACT_ABORTDIAL}},
- /* dialing */
- {RSP_ZCTP, 650,650, -1, -1,-1, {ACT_DEBUG}},
- {RSP_ZCPN, 650,650, -1, -1,-1, {ACT_DEBUG}},
- {RSP_ZSAU, 650,650,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}}, /* some devices don't send this */
+ /* optional dialing responses */
+ {EV_BC_OPEN, 650,650, -1, 651,-1},
+ {RSP_ZVLS, 608,651, 17, -1,-1, {ACT_DEBUG}},
+ {RSP_ZCTP, 609,651, -1, -1,-1, {ACT_DEBUG}},
+ {RSP_ZCPN, 609,651, -1, -1,-1, {ACT_DEBUG}},
+ {RSP_ZSAU, 650,651,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}},
- /* connection established */
- {RSP_ZSAU, 650,650,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, //FIXME -> DLE1
- {RSP_ZSAU, 750,750,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, //FIXME -> DLE1
-
- {EV_BC_OPEN, 800,800, -1, 800,-1, {ACT_NOTIFY_BC_UP}}, //FIXME new constate + timeout
+ /* connect */
+ {RSP_ZSAU, 650,650,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}},
+ {RSP_ZSAU, 651,651,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT,
+ ACT_NOTIFY_BC_UP}},
+ {RSP_ZSAU, 750,750,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}},
+ {RSP_ZSAU, 751,751,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT,
+ ACT_NOTIFY_BC_UP}},
+ {EV_BC_OPEN, 800,800, -1, 800,-1, {ACT_NOTIFY_BC_UP}},
/* remote hangup */
- {RSP_ZSAU, 650,650,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEREJECT}},
- {RSP_ZSAU, 750,750,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}},
+ {RSP_ZSAU, 650,651,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEREJECT}},
+ {RSP_ZSAU, 750,751,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}},
{RSP_ZSAU, 800,800,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}},
/* hangup */
@@ -358,7 +359,8 @@
{RSP_ZSAU, 700,729,ZSAU_ACTIVE, 0, 0, {ACT_ABORTACCEPT}},
{RSP_ZSAU, 700,729,ZSAU_DISCONNECT_IND, 0, 0, {ACT_ABORTACCEPT}},
- {EV_TIMEOUT, 750,750, -1, 0, 0, {ACT_CONNTIMEOUT}},
+ {EV_BC_OPEN, 750,750, -1, 751,-1},
+ {EV_TIMEOUT, 750,751, -1, 0, 0, {ACT_CONNTIMEOUT}},
/* B channel closed (general case) */
{EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME
@@ -876,12 +878,6 @@
static void bchannel_up(struct bc_state *bcs)
{
- if (!(bcs->chstate & CHS_D_UP)) {
- dev_notice(bcs->cs->dev, "%s: D channel not up\n", __func__);
- bcs->chstate |= CHS_D_UP;
- gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
- }
-
if (bcs->chstate & CHS_B_UP) {
dev_notice(bcs->cs->dev, "%s: B channel already up\n",
__func__);
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index db3a1e4..bed38fc 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -174,12 +174,6 @@
pr_err("invalid size %d\n", size);
return -EINVAL;
}
- src = iwb->read;
- if (unlikely(limit >= BAS_OUTBUFSIZE + BAS_OUTBUFPAD ||
- (read < src && limit >= src))) {
- pr_err("isoc write buffer frame reservation violated\n");
- return -EFAULT;
- }
#endif
if (read < write) {
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 0f4a70c4..d4351ff 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1756,9 +1756,10 @@
__u8 *uuid;
uuid = sb->set_uuid;
- printk(KERN_INFO "md: SB: (V:%u) (F:0x%08x) Array-ID:<%02x%02x%02x%02x"
- ":%02x%02x:%02x%02x:%02x%02x:%02x%02x%02x%02x%02x%02x>\n"
- KERN_INFO "md: Name: \"%s\" CT:%llu\n",
+ printk(KERN_INFO
+ "md: SB: (V:%u) (F:0x%08x) Array-ID:<%02x%02x%02x%02x"
+ ":%02x%02x:%02x%02x:%02x%02x:%02x%02x%02x%02x%02x%02x>\n"
+ "md: Name: \"%s\" CT:%llu\n",
le32_to_cpu(sb->major_version),
le32_to_cpu(sb->feature_map),
uuid[0], uuid[1], uuid[2], uuid[3],
@@ -1770,12 +1771,13 @@
& MD_SUPERBLOCK_1_TIME_SEC_MASK);
uuid = sb->device_uuid;
- printk(KERN_INFO "md: L%u SZ%llu RD:%u LO:%u CS:%u DO:%llu DS:%llu SO:%llu"
+ printk(KERN_INFO
+ "md: L%u SZ%llu RD:%u LO:%u CS:%u DO:%llu DS:%llu SO:%llu"
" RO:%llu\n"
- KERN_INFO "md: Dev:%08x UUID: %02x%02x%02x%02x:%02x%02x:%02x%02x:%02x%02x"
- ":%02x%02x%02x%02x%02x%02x\n"
- KERN_INFO "md: (F:0x%08x) UT:%llu Events:%llu ResyncOffset:%llu CSUM:0x%08x\n"
- KERN_INFO "md: (MaxDev:%u) \n",
+ "md: Dev:%08x UUID: %02x%02x%02x%02x:%02x%02x:%02x%02x:%02x%02x"
+ ":%02x%02x%02x%02x%02x%02x\n"
+ "md: (F:0x%08x) UT:%llu Events:%llu ResyncOffset:%llu CSUM:0x%08x\n"
+ "md: (MaxDev:%u) \n",
le32_to_cpu(sb->level),
(unsigned long long)le64_to_cpu(sb->size),
le32_to_cpu(sb->raid_disks),
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index b6da9c3..aa20ce8 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -1096,8 +1096,19 @@
}
/* All S-code tables need a 200kHz shift */
- if (priv->ctrl.demod)
+ if (priv->ctrl.demod) {
demod = priv->ctrl.demod + 200;
+ /*
+ * The DTV7 S-code table needs a 700 kHz shift.
+ * Thanks to Terry Wu <terrywu2009@gmail.com> for reporting this
+ *
+ * DTV7 is only used in Australia. Germany or Italy may also
+ * use this firmware after initialization, but a tune to a UHF
+ * channel should then cause DTV78 to be used.
+ */
+ if (type & DTV7)
+ demod += 500;
+ }
return generic_set_freq(fe, p->frequency,
T_DIGITAL_TV, type, 0, demod);
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 68eb449..d8d4214 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -1,5 +1,6 @@
config TTPCI_EEPROM
tristate
+ depends on I2C
default n
config DVB_AV7110
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 640421c..46d2163 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -1200,7 +1200,7 @@
video_unregister_device(radio->videodev);
kfree(radio->buffer);
kfree(radio);
- goto done;
+ goto unlock;
}
/* stop rds reception */
@@ -1213,9 +1213,8 @@
retval = si470x_stop(radio);
usb_autopm_put_interface(radio->intf);
}
-
+unlock:
mutex_unlock(&radio->disconnect_lock);
-
done:
return retval;
}
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 061e147..84b6fc1 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -312,6 +312,14 @@
OV7670 VGA camera. It currently only works with the M88ALP01
controller.
+config VIDEO_MT9V011
+ tristate "Micron mt9v011 sensor support"
+ depends on I2C && VIDEO_V4L2
+ ---help---
+ This is a Video4Linux2 sensor-level driver for the Micron
+ mt0v011 1.3 Mpixel camera. It currently only works with the
+ em28xx driver.
+
config VIDEO_TCM825X
tristate "TCM825x camera sensor support"
depends on I2C && VIDEO_V4L2
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 7fb3add..9f2e321 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -69,6 +69,7 @@
obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
+obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index c92a250..36f2d76 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -198,11 +198,14 @@
static const struct cx18_card cx18_card_mpc718 = {
.type = CX18_CARD_YUAN_MPC718,
- .name = "Yuan MPC718",
- .comment = "Analog video capture works; some audio line in may not.\n",
+ .name = "Yuan MPC718 MiniPCI DVB-T/Analog",
+ .comment = "Experimenters needed for device to work well.\n"
+ "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_418_AV,
- .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
+ .hw_muxer = CX18_HW_GPIO_MUX,
+ .hw_all = CX18_HW_418_AV | CX18_HW_TUNER |
+ CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@@ -211,27 +214,34 @@
{ CX18_CARD_INPUT_SVIDEO2, 2,
CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
{ CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
- { CX18_CARD_INPUT_COMPOSITE3, 2, CX18_AV_COMPOSITE3 },
},
.audio_inputs = {
{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 0 },
- { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL1, 0 },
+ { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
+ { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
},
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 0 },
.tuners = {
/* XC3028 tuner */
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
},
+ /* FIXME - the FM radio is just a guess and driver doesn't use SIF */
+ .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
.ddr = {
- /* Probably Samsung K4D263238G-VC33 memory */
- .chip_config = 0x003,
- .refresh = 0x30c,
- .timing1 = 0x23230b73,
- .timing2 = 0x08,
+ /* Hynix HY5DU283222B DDR RAM */
+ .chip_config = 0x303,
+ .refresh = 0x3bd,
+ .timing1 = 0x36320966,
+ .timing2 = 0x1f,
.tune_lane = 0,
.initial_emrs = 2,
},
+ .gpio_init.initial_value = 0x1,
+ .gpio_init.direction = 0x3,
+ /* FIXME - these GPIO's are just guesses */
+ .gpio_audio_input = { .mask = 0x3,
+ .tuner = 0x1,
+ .linein = 0x3,
+ .radio = 0x1 },
.xceive_pin = 0,
.pci_list = cx18_pci_mpc718,
.i2c = &cx18_i2c_std,
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 6ea3fe6..51a0c33 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -30,6 +30,10 @@
#include "s5h1409.h"
#include "mxl5005s.h"
#include "zl10353.h"
+
+#include <linux/firmware.h>
+#include "mt352.h"
+#include "mt352_priv.h"
#include "tuner-xc2028.h"
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
@@ -38,6 +42,11 @@
#define CX18_CLOCK_ENABLE2 0xc71024
#define CX18_DMUX_CLK_MASK 0x0080
+/*
+ * CX18_CARD_HVR_1600_ESMT
+ * CX18_CARD_HVR_1600_SAMSUNG
+ */
+
static struct mxl5005s_config hauppauge_hvr1600_tuner = {
.i2c_address = 0xC6 >> 1,
.if_freq = IF_FREQ_5380000HZ,
@@ -65,6 +74,9 @@
.mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
};
+/*
+ * CX18_CARD_LEADTEK_DVR3100H
+ */
/* Information/confirmation of proper config values provided by Terry Wu */
static struct zl10353_config leadtek_dvr3100h_demod = {
.demod_address = 0x1e >> 1, /* Datasheet suggested straps */
@@ -74,6 +86,121 @@
.disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
};
+/*
+ * CX18_CARD_YUAN_MPC718
+ */
+/*
+ * Due to
+ *
+ * 1. an absence of information on how to prgram the MT352
+ * 2. the Linux mt352 module pushing MT352 initialzation off onto us here
+ *
+ * We have to use an init sequence that *you* must extract from the Windows
+ * driver (yuanrap.sys) and which we load as a firmware.
+ *
+ * If someone can provide me with a Zarlink MT352 (Intel CE6352?) Design Manual
+ * with chip programming details, then I can remove this annoyance.
+ */
+static int yuan_mpc718_mt352_reqfw(struct cx18_stream *stream,
+ const struct firmware **fw)
+{
+ struct cx18 *cx = stream->cx;
+ const char *fn = "dvb-cx18-mpc718-mt352.fw";
+ int ret;
+
+ ret = request_firmware(fw, fn, &cx->pci_dev->dev);
+ if (ret)
+ CX18_ERR("Unable to open firmware file %s\n", fn);
+ else {
+ size_t sz = (*fw)->size;
+ if (sz < 2 || sz > 64 || (sz % 2) != 0) {
+ CX18_ERR("Firmware %s has a bad size: %lu bytes\n",
+ fn, (unsigned long) sz);
+ ret = -EILSEQ;
+ release_firmware(*fw);
+ *fw = NULL;
+ }
+ }
+
+ if (ret) {
+ CX18_ERR("The MPC718 board variant with the MT352 DVB-T"
+ "demodualtor will not work without it\n");
+ CX18_ERR("Run 'linux/Documentation/dvb/get_dvb_firmware "
+ "mpc718' if you need the firmware\n");
+ }
+ return ret;
+}
+
+static int yuan_mpc718_mt352_init(struct dvb_frontend *fe)
+{
+ struct cx18_dvb *dvb = container_of(fe->dvb,
+ struct cx18_dvb, dvb_adapter);
+ struct cx18_stream *stream = container_of(dvb, struct cx18_stream, dvb);
+ const struct firmware *fw = NULL;
+ int ret;
+ int i;
+ u8 buf[3];
+
+ ret = yuan_mpc718_mt352_reqfw(stream, &fw);
+ if (ret)
+ return ret;
+
+ /* Loop through all the register-value pairs in the firmware file */
+ for (i = 0; i < fw->size; i += 2) {
+ buf[0] = fw->data[i];
+ /* Intercept a few registers we want to set ourselves */
+ switch (buf[0]) {
+ case TRL_NOMINAL_RATE_0:
+ /* Set our custom OFDM bandwidth in the case below */
+ break;
+ case TRL_NOMINAL_RATE_1:
+ /* 6 MHz: 64/7 * 6/8 / 20.48 * 2^16 = 0x55b6.db6 */
+ /* 7 MHz: 64/7 * 7/8 / 20.48 * 2^16 = 0x6400 */
+ /* 8 MHz: 64/7 * 8/8 / 20.48 * 2^16 = 0x7249.249 */
+ buf[1] = 0x72;
+ buf[2] = 0x49;
+ mt352_write(fe, buf, 3);
+ break;
+ case INPUT_FREQ_0:
+ /* Set our custom IF in the case below */
+ break;
+ case INPUT_FREQ_1:
+ /* 4.56 MHz IF: (20.48 - 4.56)/20.48 * 2^14 = 0x31c0 */
+ buf[1] = 0x31;
+ buf[2] = 0xc0;
+ mt352_write(fe, buf, 3);
+ break;
+ default:
+ /* Pass through the register-value pair from the fw */
+ buf[1] = fw->data[i+1];
+ mt352_write(fe, buf, 2);
+ break;
+ }
+ }
+
+ buf[0] = (u8) TUNER_GO;
+ buf[1] = 0x01; /* Go */
+ mt352_write(fe, buf, 2);
+ release_firmware(fw);
+ return 0;
+}
+
+static struct mt352_config yuan_mpc718_mt352_demod = {
+ .demod_address = 0x1e >> 1,
+ .adc_clock = 20480, /* 20.480 MHz */
+ .if2 = 4560, /* 4.560 MHz */
+ .no_tuner = 1, /* XC3028 is not behind the gate */
+ .demod_init = yuan_mpc718_mt352_init,
+};
+
+static struct zl10353_config yuan_mpc718_zl10353_demod = {
+ .demod_address = 0x1e >> 1, /* Datasheet suggested straps */
+ .if2 = 45600, /* 4.560 MHz IF from the XC3028 */
+ .parallel_ts = 1, /* Not a serial TS */
+ .no_tuner = 1, /* XC3028 is not behind the gate */
+ .disable_i2c_gate_ctrl = 1, /* Disable the I2C gate */
+};
+
static int dvb_register(struct cx18_stream *stream);
/* Kernel DVB framework calls this when the feed needs to start.
@@ -113,6 +240,7 @@
break;
case CX18_CARD_LEADTEK_DVR3100H:
+ case CX18_CARD_YUAN_MPC718:
default:
/* Assumption - Parallel transport - Signalling
* undefined or default.
@@ -326,6 +454,38 @@
fe->ops.tuner_ops.set_config(fe, &ctrl);
}
break;
+ case CX18_CARD_YUAN_MPC718:
+ /*
+ * TODO
+ * Apparently, these cards also could instead have a
+ * DiBcom demod supported by one of the db7000 drivers
+ */
+ dvb->fe = dvb_attach(mt352_attach,
+ &yuan_mpc718_mt352_demod,
+ &cx->i2c_adap[1]);
+ if (dvb->fe == NULL)
+ dvb->fe = dvb_attach(zl10353_attach,
+ &yuan_mpc718_zl10353_demod,
+ &cx->i2c_adap[1]);
+ if (dvb->fe != NULL) {
+ struct dvb_frontend *fe;
+ struct xc2028_config cfg = {
+ .i2c_adap = &cx->i2c_adap[1],
+ .i2c_addr = 0xc2 >> 1,
+ .ctrl = NULL,
+ };
+ static struct xc2028_ctrl ctrl = {
+ .fname = XC2028_DEFAULT_FIRMWARE,
+ .max_len = 64,
+ .demod = XC3028_FE_ZARLINK456,
+ .type = XC2028_AUTO,
+ };
+
+ fe = dvb_attach(xc2028_attach, dvb->fe, &cfg);
+ if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
+ fe->ops.tuner_ops.set_config(fe, &ctrl);
+ }
+ break;
default:
/* No Digital Tv Support */
break;
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 48a9751..86ac529 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -463,6 +463,30 @@
.if_khz = 5380,
};
+static int cx23885_dvb_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *param)
+{
+ struct cx23885_tsport *port = fe->dvb->priv;
+ struct cx23885_dev *dev = port->dev;
+
+ switch (dev->board) {
+ case CX23885_BOARD_HAUPPAUGE_HVR1275:
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ cx23885_gpio_clear(dev, GPIO_5);
+ break;
+ case QAM_64:
+ case QAM_256:
+ default:
+ cx23885_gpio_set(dev, GPIO_5);
+ break;
+ }
+ break;
+ }
+ return (port->set_frontend_save) ?
+ port->set_frontend_save(fe, param) : -ENODEV;
+}
+
static int dvb_register(struct cx23885_tsport *port)
{
struct cx23885_dev *dev = port->dev;
@@ -502,6 +526,12 @@
0x60, &dev->i2c_bus[1].i2c_adap,
&hauppauge_hvr127x_config);
}
+
+ /* FIXME: temporary hack */
+ /* define bridge override to set_frontend */
+ port->set_frontend_save = fe0->dvb.frontend->ops.set_frontend;
+ fe0->dvb.frontend->ops.set_frontend = cx23885_dvb_set_frontend;
+
break;
case CX23885_BOARD_HAUPPAUGE_HVR1255:
i2c_bus = &dev->i2c_bus[0];
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 1a2ac51..214a55e 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -288,6 +288,10 @@
/* Allow a single tsport to have multiple frontends */
u32 num_frontends;
void *port_priv;
+
+ /* FIXME: temporary hack */
+ int (*set_frontend_save) (struct dvb_frontend *,
+ struct dvb_frontend_parameters *);
};
struct cx23885_dev {
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 16a5af3..6524b49 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -8,6 +8,8 @@
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_MT9V011 if VIDEO_HELPER_CHIPS_AUTO
+
---help---
This is a video4linux driver for Empia 28xx based TV cards.
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index c43fdb9..ebd24a2 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -58,6 +58,8 @@
module_param_array(card, int, NULL, 0444);
MODULE_PARM_DESC(card, "card type");
+#define MT9V011_VERSION 0x8243
+
/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
static unsigned long em28xx_devused;
@@ -191,6 +193,13 @@
{EM28XX_R08_GPIO, 0xff, 0xff, 10},
{ -1, -1, -1, -1},
};
+
+static struct em28xx_reg_seq silvercrest_reg_seq[] = {
+ {EM28XX_R08_GPIO, 0xff, 0xff, 10},
+ {EM28XX_R08_GPIO, 0x01, 0xf7, 10},
+ { -1, -1, -1, -1},
+};
+
/*
* Board definitions
*/
@@ -438,6 +447,18 @@
.amux = EM28XX_AMUX_VIDEO,
} },
},
+ [EM2820_BOARD_SILVERCREST_WEBCAM] = {
+ .name = "Silvercrest Webcam 1.3mpix",
+ .tuner_type = TUNER_ABSENT,
+ .is_27xx = 1,
+ .decoder = EM28XX_MT9V011,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = 0,
+ .amux = EM28XX_AMUX_VIDEO,
+ .gpio = silvercrest_reg_seq,
+ } },
+ },
[EM2821_BOARD_SUPERCOMP_USB_2] = {
.name = "Supercomp USB 2.0 TV",
.valid = EM28XX_BOARD_NOT_VALIDATED,
@@ -826,7 +847,7 @@
.tuner_gpio = default_tuner_gpio,
.decoder = EM28XX_TVP5150,
.has_dvb = 1,
- .dvb_gpio = default_analog,
+ .dvb_gpio = default_digital,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
.vmux = TVP5150_COMPOSITE0,
@@ -1639,6 +1660,11 @@
I2C_CLIENT_END
};
+static unsigned short mt9v011_addrs[] = {
+ 0xba >> 1,
+ I2C_CLIENT_END
+};
+
static unsigned short msp3400_addrs[] = {
0x80 >> 1,
0x88 >> 1,
@@ -1678,6 +1704,46 @@
EM28XX_I2C_FREQ_100_KHZ;
}
+/* HINT method: webcam I2C chips
+ *
+ * This method work for webcams with Micron sensors
+ */
+static int em28xx_hint_sensor(struct em28xx *dev)
+{
+ int rc;
+ char *sensor_name;
+ unsigned char cmd;
+ __be16 version_be;
+ u16 version;
+
+ if (dev->model != EM2820_BOARD_UNKNOWN)
+ return 0;
+
+ dev->i2c_client.addr = 0xba >> 1;
+ cmd = 0;
+ i2c_master_send(&dev->i2c_client, &cmd, 1);
+ rc = i2c_master_recv(&dev->i2c_client, (char *)&version_be, 2);
+ if (rc != 2)
+ return -EINVAL;
+
+ version = be16_to_cpu(version_be);
+
+ switch (version) {
+ case MT9V011_VERSION:
+ dev->model = EM2820_BOARD_SILVERCREST_WEBCAM;
+ sensor_name = "mt9v011";
+ break;
+ default:
+ printk("Unknown Sensor 0x%04x\n", be16_to_cpu(version));
+ return -EINVAL;
+ }
+
+ em28xx_errdev("Sensor is %s, assuming that webcam is %s\n",
+ sensor_name, em28xx_boards[dev->model].name);
+
+ return 0;
+}
+
/* Since em28xx_pre_card_setup() requires a proper dev->model,
* this won't work for boards with generic PCI IDs
*/
@@ -1706,7 +1772,10 @@
em28xx_info("chip ID is em2750\n");
break;
case CHIP_ID_EM2820:
- em28xx_info("chip ID is em2820\n");
+ if (dev->board.is_27xx)
+ em28xx_info("chip is em2710\n");
+ else
+ em28xx_info("chip ID is em2820\n");
break;
case CHIP_ID_EM2840:
em28xx_info("chip ID is em2840\n");
@@ -2158,6 +2227,10 @@
before probing the i2c bus. */
em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
break;
+ case EM2820_BOARD_SILVERCREST_WEBCAM:
+ /* FIXME: need to document the registers bellow */
+ em28xx_write_reg(dev, 0x0d, 0x42);
+ em28xx_write_reg(dev, 0x13, 0x08);
}
if (dev->board.has_snapshot_button)
@@ -2189,6 +2262,10 @@
v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
"tvp5150", "tvp5150", tvp5150_addrs);
+ if (dev->board.decoder == EM28XX_MT9V011)
+ v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "mt9v011", "mt9v011", mt9v011_addrs);
+
if (dev->board.adecoder == EM28XX_TVAUDIO)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
"tvaudio", "tvaudio", dev->board.tvaudio_addr);
@@ -2333,6 +2410,8 @@
return errCode;
}
+ em28xx_hint_sensor(dev);
+
/* Do board specific init and eeprom reading */
em28xx_card_setup(dev);
@@ -2573,6 +2652,7 @@
retval = em28xx_init_dev(&dev, udev, interface, nr);
if (retval) {
em28xx_devused &= ~(1<<dev->devno);
+ mutex_unlock(&dev->lock);
kfree(dev);
goto err;
}
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index c8d7ce8..079ab4d 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -648,17 +648,28 @@
int em28xx_set_outfmt(struct em28xx *dev)
{
int ret;
+ int vinmode, vinctl, outfmt;
+
+ outfmt = dev->format->reg;
+
+ if (dev->board.is_27xx) {
+ vinmode = 0x0d;
+ vinctl = 0x00;
+ } else {
+ vinmode = 0x10;
+ vinctl = 0x11;
+ }
ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT,
- dev->format->reg | 0x20, 0x3f);
+ outfmt | 0x20, 0xff);
+ if (ret < 0)
+ return ret;
+
+ ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, vinmode);
if (ret < 0)
return ret;
- ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, 0x10);
- if (ret < 0)
- return ret;
-
- return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x11);
+ return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctl);
}
static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
@@ -695,13 +706,19 @@
{
u8 mode;
/* the em2800 scaler only supports scaling down to 50% */
- if (dev->board.is_em2800)
+
+ if (dev->board.is_27xx) {
+ /* FIXME: Don't use the scaler yet */
+ mode = 0;
+ } else if (dev->board.is_em2800) {
mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
- else {
+ } else {
u8 buf[2];
+
buf[0] = h;
buf[1] = h >> 8;
em28xx_write_regs(dev, EM28XX_R30_HSCALELOW, (char *)buf, 2);
+
buf[0] = v;
buf[1] = v >> 8;
em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2);
@@ -720,8 +737,11 @@
height = norm_maxh(dev) >> 1;
em28xx_set_outfmt(dev);
+
+
em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
+
return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
}
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index e7b47c8..3da97c3 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -243,6 +243,14 @@
.mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
};
+static struct zl10353_config em28xx_terratec_xs_zl10353_xc3028 = {
+ .demod_address = (0x1e >> 1),
+ .no_tuner = 1,
+ .disable_i2c_gate_ctrl = 1,
+ .parallel_ts = 1,
+ .if2 = 45600,
+};
+
#ifdef EM28XX_DRX397XD_SUPPORT
/* [TODO] djh - not sure yet what the device config needs to contain */
static struct drx397xD_config em28xx_drx397xD_with_xc3028 = {
@@ -433,7 +441,6 @@
}
break;
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
- case EM2880_BOARD_TERRATEC_HYBRID_XS:
case EM2880_BOARD_KWORLD_DVB_310U:
case EM2880_BOARD_EMPIRE_DUAL_TV:
dvb->frontend = dvb_attach(zl10353_attach,
@@ -444,6 +451,25 @@
goto out_free;
}
break;
+ case EM2880_BOARD_TERRATEC_HYBRID_XS:
+ dvb->frontend = dvb_attach(zl10353_attach,
+ &em28xx_terratec_xs_zl10353_xc3028,
+ &dev->i2c_adap);
+ if (dvb->frontend == NULL) {
+ /* This board could have either a zl10353 or a mt352.
+ If the chip id isn't for zl10353, try mt352 */
+
+ /* FIXME: make support for mt352 work */
+ printk(KERN_ERR "version of this board with mt352 not "
+ "currently supported\n");
+ result = -EINVAL;
+ goto out_free;
+ }
+ if (attach_xc3028(0x61, dev) < 0) {
+ result = -EINVAL;
+ goto out_free;
+ }
+ break;
case EM2883_BOARD_KWORLD_HYBRID_330U:
case EM2882_BOARD_EVGA_INDTUBE:
dvb->frontend = dvb_attach(s5h1409_attach,
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 2c86fcf..27e33a2 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -483,7 +483,7 @@
[0xa0 >> 1] = "eeprom",
[0xb0 >> 1] = "tda9874",
[0xb8 >> 1] = "tvp5150a",
- [0xba >> 1] = "tvp5150a",
+ [0xba >> 1] = "webcam sensor or tvp5150a",
[0xc0 >> 1] = "tuner (analog)",
[0xc2 >> 1] = "tuner (analog)",
[0xc4 >> 1] = "tuner (analog)",
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 8fe1bee..14316c9 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -90,10 +90,35 @@
/* supported video standards */
static struct em28xx_fmt format[] = {
{
- .name = "16bpp YUY2, 4:2:2, packed",
+ .name = "16 bpp YUY2, 4:2:2, packed",
.fourcc = V4L2_PIX_FMT_YUYV,
.depth = 16,
.reg = EM28XX_OUTFMT_YUV422_Y0UY1V,
+ }, {
+ .name = "16 bpp RGB 565, LE",
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .depth = 16,
+ .reg = EM28XX_OUTFMT_RGB_16_656,
+ }, {
+ .name = "8 bpp Bayer BGBG..GRGR",
+ .fourcc = V4L2_PIX_FMT_SBGGR8,
+ .depth = 8,
+ .reg = EM28XX_OUTFMT_RGB_8_BGBG,
+ }, {
+ .name = "8 bpp Bayer GRGR..BGBG",
+ .fourcc = V4L2_PIX_FMT_SGRBG8,
+ .depth = 8,
+ .reg = EM28XX_OUTFMT_RGB_8_GRGR,
+ }, {
+ .name = "8 bpp Bayer GBGB..RGRG",
+ .fourcc = V4L2_PIX_FMT_SGBRG8,
+ .depth = 8,
+ .reg = EM28XX_OUTFMT_RGB_8_GBGB,
+ }, {
+ .name = "12 bpp YUV411",
+ .fourcc = V4L2_PIX_FMT_YUV411P,
+ .depth = 12,
+ .reg = EM28XX_OUTFMT_YUV411,
},
};
@@ -701,7 +726,11 @@
return -EINVAL;
}
- if (dev->board.is_em2800) {
+ if (dev->board.is_27xx) {
+ /* FIXME: This is the only supported fmt */
+ width = 640;
+ height = 480;
+ } else if (dev->board.is_em2800) {
/* the em2800 can only scale down to 50% */
height = height > (3 * maxh / 4) ? maxh : maxh / 2;
width = width > (3 * maxw / 4) ? maxw : maxw / 2;
@@ -733,13 +762,40 @@
return 0;
}
+static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc,
+ unsigned width, unsigned height)
+{
+ struct em28xx_fmt *fmt;
+
+ /* FIXME: This is the only supported fmt */
+ if (dev->board.is_27xx) {
+ width = 640;
+ height = 480;
+ }
+
+ fmt = format_by_fourcc(fourcc);
+ if (!fmt)
+ return -EINVAL;
+
+ dev->format = fmt;
+ dev->width = width;
+ dev->height = height;
+
+ /* set new image size */
+ get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
+
+ em28xx_set_alternate(dev);
+ em28xx_resolution_set(dev);
+
+ return 0;
+}
+
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;
int rc;
- struct em28xx_fmt *fmt;
rc = check_dev(dev);
if (rc < 0)
@@ -749,12 +805,6 @@
vidioc_try_fmt_vid_cap(file, priv, f);
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (!fmt) {
- rc = -EINVAL;
- goto out;
- }
-
if (videobuf_queue_is_busy(&fh->vb_vidq)) {
em28xx_errdev("%s queue busy\n", __func__);
rc = -EBUSY;
@@ -767,16 +817,8 @@
goto out;
}
- /* set new image size */
- dev->width = f->fmt.pix.width;
- dev->height = f->fmt.pix.height;
- dev->format = fmt;
- get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
-
- em28xx_set_alternate(dev);
- em28xx_resolution_set(dev);
-
- rc = 0;
+ rc = em28xx_set_video_format(dev, f->fmt.pix.pixelformat,
+ f->fmt.pix.width, f->fmt.pix.height);
out:
mutex_unlock(&dev->lock);
@@ -1616,11 +1658,6 @@
filp->private_data = fh;
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
- dev->width = norm_maxw(dev);
- dev->height = norm_maxh(dev);
- dev->hscale = 0;
- dev->vscale = 0;
-
em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
em28xx_set_alternate(dev);
em28xx_resolution_set(dev);
@@ -1962,15 +1999,14 @@
/* set default norm */
dev->norm = em28xx_video_template.current_norm;
- dev->width = norm_maxw(dev);
- dev->height = norm_maxh(dev);
dev->interlaced = EM28XX_INTERLACED_DEFAULT;
- dev->hscale = 0;
- dev->vscale = 0;
dev->ctl_input = 0;
/* Analog specific initialization */
dev->format = &format[0];
+ em28xx_set_video_format(dev, format[0].fourcc,
+ norm_maxw(dev), norm_maxh(dev));
+
video_mux(dev, dev->ctl_input);
/* Audio defaults */
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 813ce45..d90fef4 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -107,6 +107,7 @@
#define EM2860_BOARD_TERRATEC_AV350 68
#define EM2882_BOARD_KWORLD_ATSC_315U 69
#define EM2882_BOARD_EVGA_INDTUBE 70
+#define EM2820_BOARD_SILVERCREST_WEBCAM 71
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
@@ -360,6 +361,7 @@
EM28XX_NODECODER,
EM28XX_TVP5150,
EM28XX_SAA711X,
+ EM28XX_MT9V011,
};
enum em28xx_adecoder {
@@ -388,6 +390,7 @@
unsigned int max_range_640_480:1;
unsigned int has_dvb:1;
unsigned int has_snapshot_button:1;
+ unsigned int is_27xx:1;
unsigned int valid:1;
unsigned char xclk, i2c_speed;
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/video/gspca/stv06xx/stv06xx.h
index 9df7137..992ce53 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.h
@@ -36,10 +36,6 @@
#define STV_ISOC_ENDPOINT_ADDR 0x81
-#ifndef V4L2_PIX_FMT_SGRBG8
-#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G')
-#endif
-
#define STV_REG23 0x0423
/* Control registers of the STV0600 ASIC */
diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c
new file mode 100644
index 0000000..1fe8fc9
--- /dev/null
+++ b/drivers/media/video/mt9v011.c
@@ -0,0 +1,431 @@
+/*
+ * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor
+ *
+ * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com)
+ * This code is placed under the terms of the GNU General Public License v2
+ */
+
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/delay.h>
+#include <media/v4l2-device.h>
+#include "mt9v011.h"
+#include <media/v4l2-i2c-drv.h>
+#include <media/v4l2-chip-ident.h>
+
+MODULE_DESCRIPTION("Micron mt9v011 sensor driver");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_LICENSE("GPL");
+
+
+static int debug;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0-2)");
+
+/* supported controls */
+static struct v4l2_queryctrl mt9v011_qctrl[] = {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gain",
+ .minimum = 0,
+ .maximum = (1 << 10) - 1,
+ .step = 1,
+ .default_value = 0x0020,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Red Balance",
+ .minimum = -1 << 9,
+ .maximum = (1 << 9) - 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Blue Balance",
+ .minimum = -1 << 9,
+ .maximum = (1 << 9) - 1,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ },
+};
+
+struct mt9v011 {
+ struct v4l2_subdev sd;
+ unsigned width, height;
+
+ u16 global_gain, red_bal, blue_bal;
+};
+
+static inline struct mt9v011 *to_mt9v011(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct mt9v011, sd);
+}
+
+static int mt9v011_read(struct v4l2_subdev *sd, unsigned char addr)
+{
+ struct i2c_client *c = v4l2_get_subdevdata(sd);
+ __be16 buffer;
+ int rc, val;
+
+ rc = i2c_master_send(c, &addr, 1);
+ if (rc != 1)
+ v4l2_dbg(0, debug, sd,
+ "i2c i/o error: rc == %d (should be 1)\n", rc);
+
+ msleep(10);
+
+ rc = i2c_master_recv(c, (char *)&buffer, 2);
+ if (rc != 2)
+ v4l2_dbg(0, debug, sd,
+ "i2c i/o error: rc == %d (should be 2)\n", rc);
+
+ val = be16_to_cpu(buffer);
+
+ v4l2_dbg(2, debug, sd, "mt9v011: read 0x%02x = 0x%04x\n", addr, val);
+
+ return val;
+}
+
+static void mt9v011_write(struct v4l2_subdev *sd, unsigned char addr,
+ u16 value)
+{
+ struct i2c_client *c = v4l2_get_subdevdata(sd);
+ unsigned char buffer[3];
+ int rc;
+
+ buffer[0] = addr;
+ buffer[1] = value >> 8;
+ buffer[2] = value & 0xff;
+
+ v4l2_dbg(2, debug, sd,
+ "mt9v011: writing 0x%02x 0x%04x\n", buffer[0], value);
+ rc = i2c_master_send(c, buffer, 3);
+ if (rc != 3)
+ v4l2_dbg(0, debug, sd,
+ "i2c i/o error: rc == %d (should be 3)\n", rc);
+}
+
+
+struct i2c_reg_value {
+ unsigned char reg;
+ u16 value;
+};
+
+/*
+ * Values used at the original driver
+ * Some values are marked as Reserved at the datasheet
+ */
+static const struct i2c_reg_value mt9v011_init_default[] = {
+ { R0D_MT9V011_RESET, 0x0001 },
+ { R0D_MT9V011_RESET, 0x0000 },
+
+ { R0C_MT9V011_SHUTTER_DELAY, 0x0000 },
+ { R09_MT9V011_SHUTTER_WIDTH, 0x1fc },
+
+ { R0A_MT9V011_CLK_SPEED, 0x0000 },
+ { R1E_MT9V011_DIGITAL_ZOOM, 0x0000 },
+ { R20_MT9V011_READ_MODE, 0x1000 },
+
+ { R07_MT9V011_OUT_CTRL, 0x000a }, /* chip enable */
+};
+
+static void set_balance(struct v4l2_subdev *sd)
+{
+ struct mt9v011 *core = to_mt9v011(sd);
+ u16 green1_gain, green2_gain, blue_gain, red_gain;
+
+ green1_gain = core->global_gain;
+ green2_gain = core->global_gain;
+
+ blue_gain = core->global_gain +
+ core->global_gain * core->blue_bal / (1 << 9);
+
+ red_gain = core->global_gain +
+ core->global_gain * core->blue_bal / (1 << 9);
+
+ mt9v011_write(sd, R2B_MT9V011_GREEN_1_GAIN, green1_gain);
+ mt9v011_write(sd, R2E_MT9V011_GREEN_2_GAIN, green1_gain);
+ mt9v011_write(sd, R2C_MT9V011_BLUE_GAIN, blue_gain);
+ mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain);
+}
+
+static void set_res(struct v4l2_subdev *sd)
+{
+ struct mt9v011 *core = to_mt9v011(sd);
+ unsigned vstart, hstart;
+
+ /*
+ * The mt9v011 doesn't have scaling. So, in order to select the desired
+ * resolution, we're cropping at the middle of the sensor.
+ * hblank and vblank should be adjusted, in order to warrant that
+ * we'll preserve the line timings for 30 fps, no matter what resolution
+ * is selected.
+ * NOTE: datasheet says that width (and height) should be filled with
+ * width-1. However, this doesn't work, since one pixel per line will
+ * be missing.
+ */
+
+ hstart = 14 + (640 - core->width) / 2;
+ mt9v011_write(sd, R02_MT9V011_COLSTART, hstart);
+ mt9v011_write(sd, R04_MT9V011_WIDTH, core->width);
+ mt9v011_write(sd, R05_MT9V011_HBLANK, 771 - core->width);
+
+ vstart = 8 + (640 - core->height) / 2;
+ mt9v011_write(sd, R01_MT9V011_ROWSTART, vstart);
+ mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height);
+ mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height);
+};
+
+static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mt9v011_init_default); i++)
+ mt9v011_write(sd, mt9v011_init_default[i].reg,
+ mt9v011_init_default[i].value);
+
+ set_balance(sd);
+ set_res(sd);
+
+ return 0;
+};
+
+static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct mt9v011 *core = to_mt9v011(sd);
+
+ v4l2_dbg(1, debug, sd, "g_ctrl called\n");
+
+ switch (ctrl->id) {
+ case V4L2_CID_GAIN:
+ ctrl->value = core->global_gain;
+ return 0;
+ case V4L2_CID_RED_BALANCE:
+ ctrl->value = core->red_bal;
+ return 0;
+ case V4L2_CID_BLUE_BALANCE:
+ ctrl->value = core->blue_bal;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct mt9v011 *core = to_mt9v011(sd);
+ u8 i, n;
+ n = ARRAY_SIZE(mt9v011_qctrl);
+
+ for (i = 0; i < n; i++) {
+ if (ctrl->id != mt9v011_qctrl[i].id)
+ continue;
+ if (ctrl->value < mt9v011_qctrl[i].minimum ||
+ ctrl->value > mt9v011_qctrl[i].maximum)
+ return -ERANGE;
+ v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
+ ctrl->id, ctrl->value);
+ break;
+ }
+
+ switch (ctrl->id) {
+ case V4L2_CID_GAIN:
+ core->global_gain = ctrl->value;
+ break;
+ case V4L2_CID_RED_BALANCE:
+ core->red_bal = ctrl->value;
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ core->blue_bal = ctrl->value;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ set_balance(sd);
+
+ return 0;
+}
+
+static int mt9v011_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt)
+{
+ if (fmt->index > 0)
+ return -EINVAL;
+
+ fmt->flags = 0;
+ strcpy(fmt->description, "8 bpp Bayer GRGR..BGBG");
+ fmt->pixelformat = V4L2_PIX_FMT_SGRBG8;
+
+ return 0;
+}
+
+static int mt9v011_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ struct v4l2_pix_format *pix = &fmt->fmt.pix;
+
+ if (pix->pixelformat != V4L2_PIX_FMT_SGRBG8)
+ return -EINVAL;
+
+ v4l_bound_align_image(&pix->width, 48, 639, 1,
+ &pix->height, 32, 480, 1, 0);
+
+ return 0;
+}
+
+static int mt9v011_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ struct v4l2_pix_format *pix = &fmt->fmt.pix;
+ struct mt9v011 *core = to_mt9v011(sd);
+ int rc;
+
+ rc = mt9v011_try_fmt(sd, fmt);
+ if (rc < 0)
+ return -EINVAL;
+
+ core->width = pix->width;
+ core->height = pix->height;
+
+ set_res(sd);
+
+ return 0;
+}
+
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int mt9v011_g_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ if (!v4l2_chip_match_i2c_client(client, ®->match))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ reg->val = mt9v011_read(sd, reg->reg & 0xff);
+ reg->size = 2;
+
+ return 0;
+}
+
+static int mt9v011_s_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ if (!v4l2_chip_match_i2c_client(client, ®->match))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ mt9v011_write(sd, reg->reg & 0xff, reg->val & 0xffff);
+
+ return 0;
+}
+#endif
+
+static int mt9v011_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_MT9V011,
+ MT9V011_VERSION);
+}
+
+static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
+ .g_ctrl = mt9v011_g_ctrl,
+ .s_ctrl = mt9v011_s_ctrl,
+ .reset = mt9v011_reset,
+ .g_chip_ident = mt9v011_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = mt9v011_g_register,
+ .s_register = mt9v011_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_video_ops mt9v011_video_ops = {
+ .enum_fmt = mt9v011_enum_fmt,
+ .try_fmt = mt9v011_try_fmt,
+ .s_fmt = mt9v011_s_fmt,
+};
+
+static const struct v4l2_subdev_ops mt9v011_ops = {
+ .core = &mt9v011_core_ops,
+ .video = &mt9v011_video_ops,
+};
+
+
+/****************************************************************************
+ I2C Client & Driver
+ ****************************************************************************/
+
+static int mt9v011_probe(struct i2c_client *c,
+ const struct i2c_device_id *id)
+{
+ u16 version;
+ struct mt9v011 *core;
+ struct v4l2_subdev *sd;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(c->adapter,
+ I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+ return -EIO;
+
+ core = kzalloc(sizeof(struct mt9v011), GFP_KERNEL);
+ if (!core)
+ return -ENOMEM;
+
+ sd = &core->sd;
+ v4l2_i2c_subdev_init(sd, c, &mt9v011_ops);
+
+ /* Check if the sensor is really a MT9V011 */
+ version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
+ if (version != MT9V011_VERSION) {
+ v4l2_info(sd, "*** unknown micron chip detected (0x%04x.\n",
+ version);
+ kfree(core);
+ return -EINVAL;
+ }
+
+ core->global_gain = 0x0024;
+ core->width = 640;
+ core->height = 480;
+
+ v4l_info(c, "chip found @ 0x%02x (%s)\n",
+ c->addr << 1, c->adapter->name);
+
+ return 0;
+}
+
+static int mt9v011_remove(struct i2c_client *c)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(c);
+
+ v4l2_dbg(1, debug, sd,
+ "mt9v011.c: removing mt9v011 adapter on address 0x%x\n",
+ c->addr << 1);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_mt9v011(sd));
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct i2c_device_id mt9v011_id[] = {
+ { "mt9v011", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, mt9v011_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "mt9v011",
+ .probe = mt9v011_probe,
+ .remove = mt9v011_remove,
+ .id_table = mt9v011_id,
+};
diff --git a/drivers/media/video/mt9v011.h b/drivers/media/video/mt9v011.h
new file mode 100644
index 0000000..9e443ee
--- /dev/null
+++ b/drivers/media/video/mt9v011.h
@@ -0,0 +1,35 @@
+/*
+ * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor
+ *
+ * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com)
+ * This code is placed under the terms of the GNU General Public License v2
+ */
+
+#ifndef MT9V011_H_
+#define MT9V011_H_
+
+#define R00_MT9V011_CHIP_VERSION 0x00
+#define R01_MT9V011_ROWSTART 0x01
+#define R02_MT9V011_COLSTART 0x02
+#define R03_MT9V011_HEIGHT 0x03
+#define R04_MT9V011_WIDTH 0x04
+#define R05_MT9V011_HBLANK 0x05
+#define R06_MT9V011_VBLANK 0x06
+#define R07_MT9V011_OUT_CTRL 0x07
+#define R09_MT9V011_SHUTTER_WIDTH 0x09
+#define R0A_MT9V011_CLK_SPEED 0x0a
+#define R0B_MT9V011_RESTART 0x0b
+#define R0C_MT9V011_SHUTTER_DELAY 0x0c
+#define R0D_MT9V011_RESET 0x0d
+#define R1E_MT9V011_DIGITAL_ZOOM 0x1e
+#define R20_MT9V011_READ_MODE 0x20
+#define R2B_MT9V011_GREEN_1_GAIN 0x2b
+#define R2C_MT9V011_BLUE_GAIN 0x2c
+#define R2D_MT9V011_RED_GAIN 0x2d
+#define R2E_MT9V011_GREEN_2_GAIN 0x2e
+#define R35_MT9V011_GLOBAL_GAIN 0x35
+#define RF1_MT9V011_CHIP_ENABLE 0xf1
+
+#define MT9V011_VERSION 0x8243
+
+#endif
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 16f595d..9f5ae81 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -237,11 +237,11 @@
return -ENOMEM;
icd->num_user_formats = fmts;
- fmts = 0;
dev_dbg(&icd->dev, "Found %d supported formats.\n", fmts);
/* Second pass - actually fill data formats */
+ fmts = 0;
for (i = 0; i < icd->num_formats; i++)
if (!ici->ops->get_formats) {
icd->user_formats[i].host_fmt = icd->formats + i;
@@ -877,8 +877,11 @@
(unsigned short)~0;
ret = soc_camera_init_user_formats(icd);
- if (ret < 0)
+ if (ret < 0) {
+ if (icd->ops->remove)
+ icd->ops->remove(icd);
goto eiufmt;
+ }
icd->height = DEFAULT_HEIGHT;
icd->width = DEFAULT_WIDTH;
@@ -902,8 +905,10 @@
{
struct soc_camera_device *icd = to_soc_camera_dev(dev);
+ mutex_lock(&icd->video_lock);
if (icd->ops->remove)
icd->ops->remove(icd);
+ mutex_unlock(&icd->video_lock);
soc_camera_free_user_formats(icd);
@@ -1145,6 +1150,7 @@
}
EXPORT_SYMBOL(soc_camera_video_start);
+/* Called from client .remove() methods with .video_lock held */
void soc_camera_video_stop(struct soc_camera_device *icd)
{
struct video_device *vdev = icd->vdev;
@@ -1154,10 +1160,8 @@
if (!icd->dev.parent || !vdev)
return;
- mutex_lock(&icd->video_lock);
video_unregister_device(vdev);
icd->vdev = NULL;
- mutex_unlock(&icd->video_lock);
}
EXPORT_SYMBOL(soc_camera_video_stop);
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index cd72668..7705fc6 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -343,6 +343,53 @@
#define TO_U(r, g, b) \
(((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128)
+/* precalculate color bar values to speed up rendering */
+static void precalculate_bars(struct vivi_fh *fh)
+{
+ struct vivi_dev *dev = fh->dev;
+ unsigned char r, g, b;
+ int k, is_yuv;
+
+ fh->input = dev->input;
+
+ for (k = 0; k < 8; k++) {
+ r = bars[fh->input].bar[k][0];
+ g = bars[fh->input].bar[k][1];
+ b = bars[fh->input].bar[k][2];
+ is_yuv = 0;
+
+ switch (fh->fmt->fourcc) {
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
+ is_yuv = 1;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_RGB565X:
+ r >>= 3;
+ g >>= 2;
+ b >>= 3;
+ break;
+ case V4L2_PIX_FMT_RGB555:
+ case V4L2_PIX_FMT_RGB555X:
+ r >>= 3;
+ g >>= 3;
+ b >>= 3;
+ break;
+ }
+
+ if (is_yuv) {
+ fh->bars[k][0] = TO_Y(r, g, b); /* Luma */
+ fh->bars[k][1] = TO_U(r, g, b); /* Cb */
+ fh->bars[k][2] = TO_V(r, g, b); /* Cr */
+ } else {
+ fh->bars[k][0] = r;
+ fh->bars[k][1] = g;
+ fh->bars[k][2] = b;
+ }
+ }
+
+}
+
#define TSTAMP_MIN_Y 24
#define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15)
#define TSTAMP_INPUT_X 10
@@ -755,6 +802,8 @@
buf->vb.height = fh->height;
buf->vb.field = field;
+ precalculate_bars(fh);
+
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
rc = videobuf_iolock(vq, &buf->vb, NULL);
if (rc < 0)
@@ -893,53 +942,6 @@
return 0;
}
-/* precalculate color bar values to speed up rendering */
-static void precalculate_bars(struct vivi_fh *fh)
-{
- struct vivi_dev *dev = fh->dev;
- unsigned char r, g, b;
- int k, is_yuv;
-
- fh->input = dev->input;
-
- for (k = 0; k < 8; k++) {
- r = bars[fh->input].bar[k][0];
- g = bars[fh->input].bar[k][1];
- b = bars[fh->input].bar[k][2];
- is_yuv = 0;
-
- switch (fh->fmt->fourcc) {
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_UYVY:
- is_yuv = 1;
- break;
- case V4L2_PIX_FMT_RGB565:
- case V4L2_PIX_FMT_RGB565X:
- r >>= 3;
- g >>= 2;
- b >>= 3;
- break;
- case V4L2_PIX_FMT_RGB555:
- case V4L2_PIX_FMT_RGB555X:
- r >>= 3;
- g >>= 3;
- b >>= 3;
- break;
- }
-
- if (is_yuv) {
- fh->bars[k][0] = TO_Y(r, g, b); /* Luma */
- fh->bars[k][1] = TO_U(r, g, b); /* Cb */
- fh->bars[k][2] = TO_V(r, g, b); /* Cr */
- } else {
- fh->bars[k][0] = r;
- fh->bars[k][1] = g;
- fh->bars[k][2] = b;
- }
- }
-
-}
-
/*FIXME: This seems to be generic enough to be at videodev2 */
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
@@ -965,8 +967,6 @@
fh->vb_vidq.field = f->fmt.pix.field;
fh->type = f->type;
- precalculate_bars(fh);
-
ret = 0;
out:
mutex_unlock(&q->vb_lock);
@@ -1357,6 +1357,7 @@
goto unreg_dev;
*vfd = vivi_template;
+ vfd->debug = debug;
ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
if (ret < 0)
diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c
index 7ac12cb..5b6e58a 100644
--- a/drivers/mfd/dm355evm_msp.c
+++ b/drivers/mfd/dm355evm_msp.c
@@ -32,8 +32,7 @@
* This driver was tested with firmware revision A4.
*/
-#if defined(CONFIG_KEYBOARD_DM355EVM) \
- || defined(CONFIG_KEYBOARD_DM355EVM_MODULE)
+#if defined(CONFIG_INPUT_DM355EVM) || defined(CONFIG_INPUT_DM355EVM_MODULE)
#define msp_has_keyboard() true
#else
#define msp_has_keyboard() false
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
index 8d1c60a..5d778ec 100644
--- a/drivers/misc/sgi-xp/xpnet.c
+++ b/drivers/misc/sgi-xp/xpnet.c
@@ -235,7 +235,7 @@
skb->ip_summed = CHECKSUM_UNNECESSARY;
dev_dbg(xpnet, "passing skb to network layer\n"
- KERN_DEBUG "\tskb->head=0x%p skb->data=0x%p skb->tail=0x%p "
+ "\tskb->head=0x%p skb->data=0x%p skb->tail=0x%p "
"skb->end=0x%p skb->len=%d\n",
(void *)skb->head, (void *)skb->data, skb_tail_pointer(skb),
skb_end_pointer(skb), skb->len);
@@ -399,7 +399,7 @@
msg->buf_pa = xp_pa((void *)start_addr);
dev_dbg(xpnet, "sending XPC message to %d:%d\n"
- KERN_DEBUG "msg->buf_pa=0x%lx, msg->size=%u, "
+ "msg->buf_pa=0x%lx, msg->size=%u, "
"msg->leadin_ignore=%u, msg->tailout_ignore=%u\n",
dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size,
msg->leadin_ignore, msg->tailout_ignore);
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index 85a1817..08787f5 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -569,16 +569,8 @@
#ifdef DEBUG_DRIVER
/* dump the packet */
- {
- int i;
-
- for (i = 0; i < 64; i++) {
- if ((i % 16) == 0)
- printk("\n" KERN_DEBUG);
- printk ("%2.2x ", skb->data [i]);
- }
- printk("\n");
- }
+ print_hex_dump(KERN_DEBUG, "skb->data: ", DUMP_PREFIX_NONE,
+ 16, 1, skb->data, 64, true);
#endif
entry = lp->tx_new & lp->tx_ring_mod_mask;
ib->btx_ring [entry].length = (-skblen) | 0xf000;
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index d6d4ab3..7d227cda 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -158,15 +158,12 @@
void arcnet_dump_skb(struct net_device *dev,
struct sk_buff *skb, char *desc)
{
- int i;
+ char hdr[32];
- printk(KERN_DEBUG "%6s: skb dump (%s) follows:", dev->name, desc);
- for (i = 0; i < skb->len; i++) {
- if (i % 16 == 0)
- printk("\n" KERN_DEBUG "[%04X] ", i);
- printk("%02X ", ((u_char *) skb->data)[i]);
- }
- printk("\n");
+ /* dump the packet */
+ snprintf(hdr, sizeof(hdr), "%6s:%s skb->data:", dev->name, desc);
+ print_hex_dump(KERN_DEBUG, hdr, DUMP_PREFIX_OFFSET,
+ 16, 1, skb->data, skb->len, true);
}
EXPORT_SYMBOL(arcnet_dump_skb);
@@ -184,6 +181,7 @@
int i, length;
unsigned long flags = 0;
static uint8_t buf[512];
+ char hdr[32];
/* hw.copy_from_card expects IRQ context so take the IRQ lock
to keep it single threaded */
@@ -197,14 +195,10 @@
/* if the offset[0] byte is nonzero, this is a 256-byte packet */
length = (buf[2] ? 256 : 512);
- printk(KERN_DEBUG "%6s: packet dump (%s) follows:", dev->name, desc);
- for (i = 0; i < length; i++) {
- if (i % 16 == 0)
- printk("\n" KERN_DEBUG "[%04X] ", i);
- printk("%02X ", buf[i]);
- }
- printk("\n");
-
+ /* dump the packet */
+ snprintf(hdr, sizeof(hdr), "%6s:%s packet dump:", dev->name, desc);
+ print_hex_dump(KERN_DEBUG, hdr, DUMP_PREFIX_OFFSET,
+ 16, 1, buf, length, true);
}
#else
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h
index b02e805..29c33c7 100644
--- a/drivers/net/benet/be_hw.h
+++ b/drivers/net/benet/be_hw.h
@@ -55,6 +55,10 @@
#define MEMBAR_CTRL_INT_CTRL_PFUNC_MASK 0x7 /* bits 26 - 28 */
#define MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT 26
+/********* ISR0 Register offset **********/
+#define CEV_ISR0_OFFSET 0xC18
+#define CEV_ISR_SIZE 4
+
/********* Event Q door bell *************/
#define DB_EQ_OFFSET DB_CQ_OFFSET
#define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 308eb09..c43f6a1 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1274,15 +1274,17 @@
{
struct be_adapter *adapter = dev;
struct be_ctrl_info *ctrl = &adapter->ctrl;
- int rx, tx;
+ int isr;
- tx = event_handle(ctrl, &adapter->tx_eq);
- rx = event_handle(ctrl, &adapter->rx_eq);
+ isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET +
+ ctrl->pci_func * CEV_ISR_SIZE);
+ if (!isr)
+ return IRQ_NONE;
- if (rx || tx)
- return IRQ_HANDLED;
- else
- return IRQ_NONE;
+ event_handle(ctrl, &adapter->tx_eq);
+ event_handle(ctrl, &adapter->rx_eq);
+
+ return IRQ_HANDLED;
}
static irqreturn_t be_msix_rx(int irq, void *dev)
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 9578a3d..206144f 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -428,10 +428,11 @@
printk(KERN_DEBUG "phy registers:");
for (addr = 0; addr < 32; ++addr) {
if ((addr & 7) == 0)
- printk("\n" KERN_DEBUG);
- printk(" %.4x", bmac_mif_read(dev, addr));
+ printk(KERN_DEBUG);
+ printk(KERN_CONT " %.4x", bmac_mif_read(dev, addr));
}
- printk("\n");
+ printk(KERN_CONT "\n");
+
if (bp->is_bmac_plus) {
unsigned int capable, ctrl;
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 8678457..85a737c 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -902,6 +902,8 @@
u16 rx_quick_cons_trip;
u16 rx_ticks_int;
u16 rx_ticks;
+/* Maximal coalescing timeout in us */
+#define BNX2X_MAX_COALESCE_TOUT (0xf0*12)
u32 lin_cnt;
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 951714a..c36a5f3 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -484,8 +484,9 @@
mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
mark = ((mark + 0x3) & ~0x3);
- printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n" KERN_ERR, mark);
+ printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n", mark);
+ printk(KERN_ERR PFX);
for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) {
for (word = 0; word < 8; word++)
data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
@@ -500,7 +501,7 @@
data[8] = 0x0;
printk(KERN_CONT "%s", (char *)data);
}
- printk("\n" KERN_ERR PFX "end of fw dump\n");
+ printk(KERN_ERR PFX "end of fw dump\n");
}
static void bnx2x_panic_dump(struct bnx2x *bp)
@@ -4434,7 +4435,7 @@
REG_WR16(bp, BAR_USTRORM_INTMEM +
USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
U_SB_ETH_RX_CQ_INDEX),
- bp->rx_ticks ? 0 : 1);
+ (bp->rx_ticks/12) ? 0 : 1);
/* HC_INDEX_C_ETH_TX_CQ_CONS */
REG_WR8(bp, BAR_CSTRORM_INTMEM +
@@ -4444,7 +4445,7 @@
REG_WR16(bp, BAR_CSTRORM_INTMEM +
CSTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
C_SB_ETH_TX_CQ_INDEX),
- bp->tx_ticks ? 0 : 1);
+ (bp->tx_ticks/12) ? 0 : 1);
}
}
@@ -7354,7 +7355,7 @@
#ifdef BNX2X_STOP_ON_ERROR
BNX2X_ERR("reset task called but STOP_ON_ERROR defined"
" so reset not done to allow debug dump,\n"
- KERN_ERR " you will need to reboot when done\n");
+ " you will need to reboot when done\n");
return;
#endif
@@ -9069,12 +9070,12 @@
struct bnx2x *bp = netdev_priv(dev);
bp->rx_ticks = (u16) coal->rx_coalesce_usecs;
- if (bp->rx_ticks > 3000)
- bp->rx_ticks = 3000;
+ if (bp->rx_ticks > BNX2X_MAX_COALESCE_TOUT)
+ bp->rx_ticks = BNX2X_MAX_COALESCE_TOUT;
bp->tx_ticks = (u16) coal->tx_coalesce_usecs;
- if (bp->tx_ticks > 0x3000)
- bp->tx_ticks = 0x3000;
+ if (bp->tx_ticks > BNX2X_MAX_COALESCE_TOUT)
+ bp->tx_ticks = BNX2X_MAX_COALESCE_TOUT;
if (netif_running(dev))
bnx2x_update_coalesce(bp);
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 538dda4..fb5df5c 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -642,8 +642,7 @@
struct port_info *pi = netdev_priv(dev);
pi->qs = &adap->sge.qs[pi->first_qset];
- for (j = pi->first_qset; j < pi->first_qset + pi->nqsets;
- ++j, ++qset_idx) {
+ for (j = 0; j < pi->nqsets; ++j, ++qset_idx) {
set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO);
err = t3_sge_alloc_qset(adap, qset_idx, 1,
(adap->flags & USING_MSIX) ? qset_idx + 1 :
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 2df8fb0..12fd446 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -1820,11 +1820,19 @@
struct device *emac_dev = &priv->ndev->dev;
struct sockaddr *sa = addr;
+ if (!is_valid_ether_addr(sa->sa_data))
+ return -EINVAL;
+
/* Store mac addr in priv and rx channel and set it in EMAC hw */
memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len);
- memcpy(rxch->mac_addr, sa->sa_data, ndev->addr_len);
memcpy(ndev->dev_addr, sa->sa_data, ndev->addr_len);
- emac_setmac(priv, EMAC_DEF_RX_CH, rxch->mac_addr);
+
+ /* If the interface is down - rxch is NULL. */
+ /* MAC address is configured only after the interface is enabled. */
+ if (netif_running(ndev)) {
+ memcpy(rxch->mac_addr, sa->sa_data, ndev->addr_len);
+ emac_setmac(priv, EMAC_DEF_RX_CH, rxch->mac_addr);
+ }
if (netif_msg_drv(priv))
dev_notice(emac_dev, "DaVinci EMAC: emac_dev_setmac_addr %pM\n",
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index 895d721..4b6a219 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -268,8 +268,9 @@
printk(KERN_INFO "tx_coalesce:\t%d packets\n",
tx_coalesce);
if (np->coalesce)
- printk(KERN_INFO "rx_coalesce:\t%d packets\n"
- KERN_INFO "rx_timeout: \t%d ns\n",
+ printk(KERN_INFO
+ "rx_coalesce:\t%d packets\n"
+ "rx_timeout: \t%d ns\n",
np->rx_coalesce, np->rx_timeout*640);
if (np->vlan)
printk(KERN_INFO "vlan(id):\t%d\n", np->vlan);
@@ -1522,9 +1523,9 @@
printk (KERN_INFO "Operating at 10 Mbps, ");
}
if (bmcr & MII_BMCR_DUPLEX_MODE) {
- printk ("Full duplex\n");
+ printk (KERN_CONT "Full duplex\n");
} else {
- printk ("Half duplex\n");
+ printk (KERN_CONT "Half duplex\n");
}
}
if (np->tx_flow)
@@ -1614,9 +1615,9 @@
}
if (np->full_duplex) {
bmcr |= MII_BMCR_DUPLEX_MODE;
- printk ("Full duplex\n");
+ printk (KERN_CONT "Full duplex\n");
} else {
- printk ("Half duplex\n");
+ printk (KERN_CONT "Half duplex\n");
}
#if 0
/* Set 1000BaseT Master/Slave setting */
@@ -1669,9 +1670,9 @@
__u16 bmcr = mii_read (dev, phy_addr, PCS_BMCR);
printk (KERN_INFO "Operating at 1000 Mbps, ");
if (bmcr & MII_BMCR_DUPLEX_MODE) {
- printk ("Full duplex\n");
+ printk (KERN_CONT "Full duplex\n");
} else {
- printk ("Half duplex\n");
+ printk (KERN_CONT "Half duplex\n");
}
}
if (np->tx_flow)
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 8890c97..c0f185b 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -238,6 +238,7 @@
#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */
+#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */
/* Constants used to interpret the masked PCI-X bus speed. */
@@ -575,6 +576,8 @@
#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */
+#define PHY_CONTROL_LB 0x4000 /* PHY Loopback bit */
+
/* NVM Control */
#define E1000_EECD_SK 0x00000001 /* NVM Clock */
#define E1000_EECD_CS 0x00000002 /* NVM Chip Select */
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 163c1c0..fd44d9f 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -215,6 +215,7 @@
E1000_SWSM = 0x05B50, /* SW Semaphore */
E1000_FWSM = 0x05B54, /* FW Semaphore */
E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */
+ E1000_CRC_OFFSET = 0x05F50, /* CRC Offset register */
E1000_HICR = 0x08F00, /* Host Interface Control */
};
@@ -302,6 +303,9 @@
#define E1000_KMRNCTRLSTA_REN 0x00200000
#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */
#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
+#define E1000_KMRNCTRLSTA_K1_CONFIG 0x7
+#define E1000_KMRNCTRLSTA_K1_ENABLE 0x140E
+#define E1000_KMRNCTRLSTA_K1_DISABLE 0x1400
#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 9e23f50..d56c747 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -338,6 +338,7 @@
{
struct e1000_nvm_info *nvm = &hw->nvm;
struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
+ union ich8_hws_flash_status hsfsts;
u32 gfpreg;
u32 sector_base_addr;
u32 sector_end_addr;
@@ -374,6 +375,20 @@
/* Adjust to word count */
nvm->flash_bank_size /= sizeof(u16);
+ /*
+ * Make sure the flash bank size does not overwrite the 4k
+ * sector ranges. We may have 64k allotted to us but we only care
+ * about the first 2 4k sectors. Therefore, if we have anything less
+ * than 64k set in the HSFSTS register, we will reduce the bank size
+ * down to 4k and let the rest remain unused. If berasesz == 3, then
+ * we are working in 64k mode. Otherwise we are not.
+ */
+ if (nvm->flash_bank_size > E1000_ICH8_SHADOW_RAM_WORDS) {
+ hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
+ if (hsfsts.hsf_status.berasesz != 3)
+ nvm->flash_bank_size = E1000_ICH8_SHADOW_RAM_WORDS;
+ }
+
nvm->word_size = E1000_ICH8_SHADOW_RAM_WORDS;
/* Clear shadow ram */
@@ -446,6 +461,95 @@
return 0;
}
+/**
+ * e1000_check_for_copper_link_ich8lan - Check for link (Copper)
+ * @hw: pointer to the HW structure
+ *
+ * Checks to see of the link status of the hardware has changed. If a
+ * change in link status has been detected, then we read the PHY registers
+ * to get the current speed/duplex if link exists.
+ **/
+static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
+{
+ struct e1000_mac_info *mac = &hw->mac;
+ s32 ret_val;
+ bool link;
+
+ /*
+ * We only want to go out to the PHY registers to see if Auto-Neg
+ * has completed and/or if our link status has changed. The
+ * get_link_status flag is set upon receiving a Link Status
+ * Change or Rx Sequence Error interrupt.
+ */
+ if (!mac->get_link_status) {
+ ret_val = 0;
+ goto out;
+ }
+
+ if (hw->mac.type == e1000_pchlan) {
+ ret_val = e1000e_write_kmrn_reg(hw,
+ E1000_KMRNCTRLSTA_K1_CONFIG,
+ E1000_KMRNCTRLSTA_K1_ENABLE);
+ if (ret_val)
+ goto out;
+ }
+
+ /*
+ * First we want to see if the MII Status Register reports
+ * link. If so, then we want to get the current speed/duplex
+ * of the PHY.
+ */
+ ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
+ if (ret_val)
+ goto out;
+
+ if (!link)
+ goto out; /* No link detected */
+
+ mac->get_link_status = false;
+
+ if (hw->phy.type == e1000_phy_82578) {
+ ret_val = e1000_link_stall_workaround_hv(hw);
+ if (ret_val)
+ goto out;
+ }
+
+ /*
+ * Check if there was DownShift, must be checked
+ * immediately after link-up
+ */
+ e1000e_check_downshift(hw);
+
+ /*
+ * If we are forcing speed/duplex, then we simply return since
+ * we have already determined whether we have link or not.
+ */
+ if (!mac->autoneg) {
+ ret_val = -E1000_ERR_CONFIG;
+ goto out;
+ }
+
+ /*
+ * Auto-Neg is enabled. Auto Speed Detection takes care
+ * of MAC speed/duplex configuration. So we only need to
+ * configure Collision Distance in the MAC.
+ */
+ e1000e_config_collision_dist(hw);
+
+ /*
+ * Configure Flow Control now that Auto-Neg has completed.
+ * First, we need to restore the desired flow control
+ * settings because we may have had to re-autoneg with a
+ * different link partner.
+ */
+ ret_val = e1000e_config_fc_after_link_up(hw);
+ if (ret_val)
+ hw_dbg(hw, "Error configuring flow control\n");
+
+out:
+ return ret_val;
+}
+
static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
@@ -694,6 +798,38 @@
}
/**
+ * e1000_lan_init_done_ich8lan - Check for PHY config completion
+ * @hw: pointer to the HW structure
+ *
+ * Check the appropriate indication the MAC has finished configuring the
+ * PHY after a software reset.
+ **/
+static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw)
+{
+ u32 data, loop = E1000_ICH8_LAN_INIT_TIMEOUT;
+
+ /* Wait for basic configuration completes before proceeding */
+ do {
+ data = er32(STATUS);
+ data &= E1000_STATUS_LAN_INIT_DONE;
+ udelay(100);
+ } while ((!data) && --loop);
+
+ /*
+ * If basic configuration is incomplete before the above loop
+ * count reaches 0, loading the configuration from NVM will
+ * leave the PHY in a bad state possibly resulting in no link.
+ */
+ if (loop == 0)
+ hw_dbg(hw, "LAN_INIT_DONE not set, increase timeout\n");
+
+ /* Clear the Init Done bit for the next init event */
+ data = er32(STATUS);
+ data &= ~E1000_STATUS_LAN_INIT_DONE;
+ ew32(STATUS, data);
+}
+
+/**
* e1000_phy_hw_reset_ich8lan - Performs a PHY reset
* @hw: pointer to the HW structure
*
@@ -707,13 +843,15 @@
u32 i;
u32 data, cnf_size, cnf_base_addr, sw_cfg_mask;
s32 ret_val;
- u16 loop = E1000_ICH8_LAN_INIT_TIMEOUT;
u16 word_addr, reg_data, reg_addr, phy_page = 0;
ret_val = e1000e_phy_hw_reset_generic(hw);
if (ret_val)
return ret_val;
+ /* Allow time for h/w to get to a quiescent state after reset */
+ mdelay(10);
+
if (hw->mac.type == e1000_pchlan) {
ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
if (ret_val)
@@ -741,26 +879,8 @@
if (!(data & sw_cfg_mask))
return 0;
- /* Wait for basic configuration completes before proceeding*/
- do {
- data = er32(STATUS);
- data &= E1000_STATUS_LAN_INIT_DONE;
- udelay(100);
- } while ((!data) && --loop);
-
- /*
- * If basic configuration is incomplete before the above loop
- * count reaches 0, loading the configuration from NVM will
- * leave the PHY in a bad state possibly resulting in no link.
- */
- if (loop == 0) {
- hw_dbg(hw, "LAN_INIT_DONE not set, increase timeout\n");
- }
-
- /* Clear the Init Done bit for the next init event */
- data = er32(STATUS);
- data &= ~E1000_STATUS_LAN_INIT_DONE;
- ew32(STATUS, data);
+ /* Wait for basic configuration completes before proceeding */
+ e1000_lan_init_done_ich8lan(hw);
/*
* Make sure HW does not configure LCD from PHY
@@ -961,12 +1081,14 @@
phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
ew32(PHY_CTRL, phy_ctrl);
+ if (phy->type != e1000_phy_igp_3)
+ return 0;
+
/*
* Call gig speed drop workaround on LPLU before accessing
* any PHY registers
*/
- if ((hw->mac.type == e1000_ich8lan) &&
- (hw->phy.type == e1000_phy_igp_3))
+ if (hw->mac.type == e1000_ich8lan)
e1000e_gig_downshift_workaround_ich8lan(hw);
/* When LPLU is enabled, we should disable SmartSpeed */
@@ -979,6 +1101,9 @@
phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
ew32(PHY_CTRL, phy_ctrl);
+ if (phy->type != e1000_phy_igp_3)
+ return 0;
+
/*
* LPLU and SmartSpeed are mutually exclusive. LPLU is used
* during Dx states where the power conservation is most
@@ -1038,6 +1163,10 @@
if (!active) {
phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
ew32(PHY_CTRL, phy_ctrl);
+
+ if (phy->type != e1000_phy_igp_3)
+ return 0;
+
/*
* LPLU and SmartSpeed are mutually exclusive. LPLU is used
* during Dx states where the power conservation is most
@@ -1073,12 +1202,14 @@
phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
ew32(PHY_CTRL, phy_ctrl);
+ if (phy->type != e1000_phy_igp_3)
+ return 0;
+
/*
* Call gig speed drop workaround on LPLU before accessing
* any PHY registers
*/
- if ((hw->mac.type == e1000_ich8lan) &&
- (hw->phy.type == e1000_phy_igp_3))
+ if (hw->mac.type == e1000_ich8lan)
e1000e_gig_downshift_workaround_ich8lan(hw);
/* When LPLU is enabled, we should disable SmartSpeed */
@@ -1905,7 +2036,7 @@
break;
case 1:
sector_size = ICH_FLASH_SEG_SIZE_4K;
- iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_4K;
+ iteration = 1;
break;
case 2:
if (hw->mac.type == e1000_ich9lan) {
@@ -1917,7 +2048,7 @@
break;
case 3:
sector_size = ICH_FLASH_SEG_SIZE_64K;
- iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_64K;
+ iteration = 1;
break;
default:
return -E1000_ERR_NVM;
@@ -2143,6 +2274,12 @@
ctrl = er32(CTRL);
if (!e1000_check_reset_block(hw)) {
+ /* Clear PHY Reset Asserted bit */
+ if (hw->mac.type >= e1000_pchlan) {
+ u32 status = er32(STATUS);
+ ew32(STATUS, status & ~E1000_STATUS_PHYRA);
+ }
+
/*
* PHY HW reset requires MAC CORE reset at the same
* time to make sure the interface between MAC and the
@@ -2156,22 +2293,33 @@
ew32(CTRL, (ctrl | E1000_CTRL_RST));
msleep(20);
- if (!ret_val) {
- /* release the swflag because it is not reset by
- * hardware reset
- */
+ if (!ret_val)
e1000_release_swflag_ich8lan(hw);
+
+ if (ctrl & E1000_CTRL_PHY_RST)
+ ret_val = hw->phy.ops.get_cfg_done(hw);
+
+ if (hw->mac.type >= e1000_ich10lan) {
+ e1000_lan_init_done_ich8lan(hw);
+ } else {
+ ret_val = e1000e_get_auto_rd_done(hw);
+ if (ret_val) {
+ /*
+ * When auto config read does not complete, do not
+ * return with an error. This can happen in situations
+ * where there is no eeprom and prevents getting link.
+ */
+ hw_dbg(hw, "Auto Read Done did not complete\n");
+ }
}
- ret_val = e1000e_get_auto_rd_done(hw);
- if (ret_val) {
- /*
- * When auto config read does not complete, do not
- * return with an error. This can happen in situations
- * where there is no eeprom and prevents getting link.
- */
- hw_dbg(hw, "Auto Read Done did not complete\n");
- }
+ /*
+ * For PCH, this write will make sure that any noise
+ * will be detected as a CRC error and be dropped rather than show up
+ * as a bad packet to the DMA engine.
+ */
+ if (hw->mac.type == e1000_pchlan)
+ ew32(CRC_OFFSET, 0x65656565);
ew32(IMC, 0xffffffff);
icr = er32(ICR);
@@ -2222,6 +2370,18 @@
for (i = 0; i < mac->mta_reg_count; i++)
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
+ /*
+ * The 82578 Rx buffer will stall if wakeup is enabled in host and
+ * the ME. Reading the BM_WUC register will clear the host wakeup bit.
+ * Reset the phy after disabling host wakeup to reset the Rx buffer.
+ */
+ if (hw->phy.type == e1000_phy_82578) {
+ hw->phy.ops.read_phy_reg(hw, BM_WUC, &i);
+ ret_val = e1000_phy_hw_reset_ich8lan(hw);
+ if (ret_val)
+ return ret_val;
+ }
+
/* Setup link and flow control */
ret_val = e1000_setup_link_ich8lan(hw);
@@ -2254,16 +2414,6 @@
ew32(CTRL_EXT, ctrl_ext);
/*
- * The 82578 Rx buffer will stall if wakeup is enabled in host and
- * the ME. Reading the BM_WUC register will clear the host wakeup bit.
- * Reset the phy after disabling host wakeup to reset the Rx buffer.
- */
- if (hw->phy.type == e1000_phy_82578) {
- e1e_rphy(hw, BM_WUC, &i);
- e1000e_phy_hw_reset_generic(hw);
- }
-
- /*
* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link
* because the symbol error count will increment wildly if there
@@ -2485,6 +2635,14 @@
if (ret_val)
return ret_val;
+ if ((hw->mac.type == e1000_pchlan) && (*speed == SPEED_1000)) {
+ ret_val = e1000e_write_kmrn_reg(hw,
+ E1000_KMRNCTRLSTA_K1_CONFIG,
+ E1000_KMRNCTRLSTA_K1_DISABLE);
+ if (ret_val)
+ return ret_val;
+ }
+
if ((hw->mac.type == e1000_ich8lan) &&
(hw->phy.type == e1000_phy_igp_3) &&
(*speed == SPEED_1000)) {
@@ -2850,6 +3008,16 @@
{
u32 bank = 0;
+ if (hw->mac.type >= e1000_pchlan) {
+ u32 status = er32(STATUS);
+
+ if (status & E1000_STATUS_PHYRA)
+ ew32(STATUS, status & ~E1000_STATUS_PHYRA);
+ else
+ hw_dbg(hw,
+ "PHY Reset Asserted not set - needs delay\n");
+ }
+
e1000e_get_cfg_done(hw);
/* If EEPROM is not marked present, init the IGP 3 PHY manually */
@@ -2921,7 +3089,7 @@
static struct e1000_mac_operations ich8_mac_ops = {
.id_led_init = e1000e_id_led_init,
.check_mng_mode = e1000_check_mng_mode_ich8lan,
- .check_for_link = e1000e_check_for_copper_link,
+ .check_for_link = e1000_check_for_copper_link_ich8lan,
/* cleanup_led dependent on mac type */
.clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan,
.get_bus_info = e1000_get_bus_info_ich8lan,
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index be6d9e9..99ba2b8 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -378,12 +378,6 @@
mac->get_link_status = 0;
- if (hw->phy.type == e1000_phy_82578) {
- ret_val = e1000_link_stall_workaround_hv(hw);
- if (ret_val)
- return ret_val;
- }
-
/*
* Check if there was DownShift, must be checked
* immediately after link-up
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index e23459c..994401f 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -1531,7 +1531,12 @@
*/
ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
if (ret_val)
- break;
+ /*
+ * If the first read fails, another entity may have
+ * ownership of the resources, wait and try again to
+ * see if they have relinquished the resources yet.
+ */
+ udelay(usec_interval);
ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
@@ -2737,6 +2742,11 @@
if (hw->phy.type != e1000_phy_82578)
goto out;
+ /* Do not apply workaround if in PHY loopback bit 14 set */
+ hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &data);
+ if (data & PHY_CONTROL_LB)
+ goto out;
+
/* check if link is up and at 1Gbps */
ret_val = hw->phy.ops.read_phy_reg(hw, BM_CS_STATUS, &data);
if (ret_val)
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index b60e27d..88d7ebf 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -338,8 +338,7 @@
#ifndef MODULE
static int printed_version;
if (!printed_version++)
- printk (KERN_INFO "%s" KERN_INFO "%s",
- version, version2);
+ printk(KERN_INFO "%s%s", version, version2);
#endif
card_idx++;
@@ -1600,7 +1599,7 @@
{
/* when a module, this is printed whether or not devices are found in probe */
#ifdef MODULE
- printk (KERN_INFO "%s" KERN_INFO "%s",
+ printk (KERN_INFO "%s%s",
version, version2);
#endif
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index 891be28..48385c4 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -1209,17 +1209,20 @@
unsigned long flags;
int i;
- printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
- " resetting...\n", dev->name, ioread32(ioaddr + ISR));
+ printk(KERN_WARNING
+ "%s: Transmit timed out, status %8.8x, resetting...\n",
+ dev->name, ioread32(ioaddr + ISR));
{
printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring);
for (i = 0; i < RX_RING_SIZE; i++)
- printk(" %8.8x", (unsigned int) np->rx_ring[i].status);
- printk("\n" KERN_DEBUG " Tx ring %p: ", np->tx_ring);
+ printk(KERN_CONT " %8.8x",
+ (unsigned int) np->rx_ring[i].status);
+ printk(KERN_CONT "\n");
+ printk(KERN_DEBUG " Tx ring %p: ", np->tx_ring);
for (i = 0; i < TX_RING_SIZE; i++)
- printk(" %4.4x", np->tx_ring[i].status);
- printk("\n");
+ printk(KERN_CONT " %4.4x", np->tx_ring[i].status);
+ printk(KERN_CONT "\n");
}
spin_lock_irqsave(&np->lock, flags);
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 30b7dd6..cc47f3f 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -46,12 +46,12 @@
#else
-#define FEC_ECNTRL; 0x000 /* Ethernet control reg */
-#define FEC_IEVENT; 0x004 /* Interrupt even reg */
-#define FEC_IMASK; 0x008 /* Interrupt mask reg */
-#define FEC_IVEC; 0x00c /* Interrupt vec status reg */
-#define FEC_R_DES_ACTIVE; 0x010 /* Receive descriptor reg */
-#define FEC_X_DES_ACTIVE; 0x01c /* Transmit descriptor reg */
+#define FEC_ECNTRL 0x000 /* Ethernet control reg */
+#define FEC_IEVENT 0x004 /* Interrupt even reg */
+#define FEC_IMASK 0x008 /* Interrupt mask reg */
+#define FEC_IVEC 0x00c /* Interrupt vec status reg */
+#define FEC_R_DES_ACTIVE 0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE 0x014 /* Transmit descriptor reg */
#define FEC_MII_DATA 0x040 /* MII manage frame reg */
#define FEC_MII_SPEED 0x044 /* MII speed control reg */
#define FEC_R_BOUND 0x08c /* FIFO receive bound reg */
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 1094d29..3b4e076 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -3514,11 +3514,13 @@
nv_msi_workaround(np);
#ifdef CONFIG_FORCEDETH_NAPI
- napi_schedule(&np->napi);
-
- /* Disable furthur irq's
- (msix not enabled with napi) */
- writel(0, base + NvRegIrqMask);
+ if (napi_schedule_prep(&np->napi)) {
+ /*
+ * Disable further irq's (msix not enabled with napi)
+ */
+ writel(0, base + NvRegIrqMask);
+ __napi_schedule(&np->napi);
+ }
#else
do
@@ -3615,12 +3617,13 @@
nv_msi_workaround(np);
#ifdef CONFIG_FORCEDETH_NAPI
- napi_schedule(&np->napi);
-
- /* Disable furthur irq's
- (msix not enabled with napi) */
- writel(0, base + NvRegIrqMask);
-
+ if (napi_schedule_prep(&np->napi)) {
+ /*
+ * Disable further irq's (msix not enabled with napi)
+ */
+ writel(0, base + NvRegIrqMask);
+ __napi_schedule(&np->napi);
+ }
#else
do
{
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 9d5b62c..d62378c 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -173,8 +173,8 @@
static const char version[] __devinitconst =
KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n"
-KERN_INFO " Some modifications by Eric kasten <kasten@nscl.msu.edu>\n"
-KERN_INFO " Further modifications by Keith Underwood <keithu@parl.clemson.edu>\n";
+" Some modifications by Eric kasten <kasten@nscl.msu.edu>\n"
+" Further modifications by Keith Underwood <keithu@parl.clemson.edu>\n";
/* IP_MF appears to be only defined in <netinet/ip.h>, however,
@@ -1080,11 +1080,14 @@
{
printk(KERN_DEBUG " Rx ring %p: ", hmp->rx_ring);
for (i = 0; i < RX_RING_SIZE; i++)
- printk(" %8.8x", le32_to_cpu(hmp->rx_ring[i].status_n_length));
- printk("\n"KERN_DEBUG" Tx ring %p: ", hmp->tx_ring);
+ printk(KERN_CONT " %8.8x",
+ le32_to_cpu(hmp->rx_ring[i].status_n_length));
+ printk(KERN_CONT "\n");
+ printk(KERN_DEBUG" Tx ring %p: ", hmp->tx_ring);
for (i = 0; i < TX_RING_SIZE; i++)
- printk(" %4.4x", le32_to_cpu(hmp->tx_ring[i].status_n_length));
- printk("\n");
+ printk(KERN_CONT " %4.4x",
+ le32_to_cpu(hmp->tx_ring[i].status_n_length));
+ printk(KERN_CONT "\n");
}
/* Reinit the hardware and make sure the Rx and Tx processes
@@ -1753,13 +1756,13 @@
#ifdef __i386__
if (hamachi_debug > 2) {
- printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n",
+ printk(KERN_DEBUG " Tx ring at %8.8x:\n",
(int)hmp->tx_ring_dma);
for (i = 0; i < TX_RING_SIZE; i++)
- printk(" %c #%d desc. %8.8x %8.8x.\n",
+ printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x.\n",
readl(ioaddr + TxCurPtr) == (long)&hmp->tx_ring[i] ? '>' : ' ',
i, hmp->tx_ring[i].status_n_length, hmp->tx_ring[i].addr);
- printk("\n"KERN_DEBUG " Rx ring %8.8x:\n",
+ printk(KERN_DEBUG " Rx ring %8.8x:\n",
(int)hmp->rx_ring_dma);
for (i = 0; i < RX_RING_SIZE; i++) {
printk(KERN_DEBUG " %c #%d desc. %4.4x %8.8x\n",
@@ -1770,7 +1773,7 @@
u16 *addr = (u16 *)
hmp->rx_skbuff[i]->data;
int j;
-
+ printk(KERN_DEBUG "Addr: ");
for (j = 0; j < 0x50; j++)
printk(" %4.4x", addr[j]);
printk("\n");
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 5e4b7af..3527032 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -68,7 +68,7 @@
static const char bc_drvname[] = "baycom_epp";
static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-KERN_INFO "baycom_epp: version 0.7 compiled " __TIME__ " " __DATE__ "\n";
+"baycom_epp: version 0.7 compiled " __TIME__ " " __DATE__ "\n";
/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c
index 2e6fc4d..5f5af9a 100644
--- a/drivers/net/hamradio/baycom_par.c
+++ b/drivers/net/hamradio/baycom_par.c
@@ -102,7 +102,7 @@
static const char bc_drvname[] = "baycom_par";
static const char bc_drvinfo[] = KERN_INFO "baycom_par: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-KERN_INFO "baycom_par: version 0.9 compiled " __TIME__ " " __DATE__ "\n";
+"baycom_par: version 0.9 compiled " __TIME__ " " __DATE__ "\n";
/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
index b6a816e..aa4488e 100644
--- a/drivers/net/hamradio/baycom_ser_fdx.c
+++ b/drivers/net/hamradio/baycom_ser_fdx.c
@@ -91,7 +91,7 @@
static const char bc_drvname[] = "baycom_ser_fdx";
static const char bc_drvinfo[] = KERN_INFO "baycom_ser_fdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-KERN_INFO "baycom_ser_fdx: version 0.10 compiled " __TIME__ " " __DATE__ "\n";
+"baycom_ser_fdx: version 0.10 compiled " __TIME__ " " __DATE__ "\n";
/* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c
index 3bcc57a..88c5935 100644
--- a/drivers/net/hamradio/baycom_ser_hdx.c
+++ b/drivers/net/hamradio/baycom_ser_hdx.c
@@ -79,7 +79,7 @@
static const char bc_drvname[] = "baycom_ser_hdx";
static const char bc_drvinfo[] = KERN_INFO "baycom_ser_hdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-KERN_INFO "baycom_ser_hdx: version 0.10 compiled " __TIME__ " " __DATE__ "\n";
+"baycom_ser_hdx: version 0.10 compiled " __TIME__ " " __DATE__ "\n";
/* --------------------------------------------------------------------- */
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index efd9be2..ac28dd5 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -190,6 +190,10 @@
phy->ops.write_reg = igb_write_phy_reg_igp;
}
+ /* set lan id */
+ hw->bus.func = (rd32(E1000_STATUS) & E1000_STATUS_FUNC_MASK) >>
+ E1000_STATUS_FUNC_SHIFT;
+
/* Set phy->phy_addr and phy->id. */
ret_val = igb_get_phy_id_82575(hw);
if (ret_val)
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index d56890f..7c5978a 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -138,6 +138,10 @@
adapter->hw.fc.requested_mode = ixgbe_fc_none;
}
adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
+ adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+ }
adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
ixgbe_init_interrupt_scheme(adapter);
if (netif_running(netdev))
@@ -154,6 +158,8 @@
adapter->dcb_cfg.pfc_mode_enable = false;
adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
ixgbe_init_interrupt_scheme(adapter);
if (netif_running(netdev))
netdev->netdev_ops->ndo_open(netdev);
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 0f7b6a3..2a97800 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -1830,7 +1830,6 @@
break;
default:
wol->supported = 0;
- retval = 0;
}
return retval;
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 5588ef4..e3442f4 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -2697,19 +2697,23 @@
/*
* For hot-pluggable SFP+ devices, a new SFP+ module may have
- * arrived before interrupts were enabled. We need to kick off
- * the SFP+ module setup first, then try to bring up link.
+ * arrived before interrupts were enabled but after probe. Such
+ * devices wouldn't have their type identified yet. We need to
+ * kick off the SFP+ module setup first, then try to bring up link.
* If we're not hot-pluggable SFP+, we just need to configure link
* and bring it up.
*/
- err = hw->phy.ops.identify(hw);
- if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- dev_err(&adapter->pdev->dev, "failed to initialize because "
- "an unsupported SFP+ module type was detected.\n"
- "Reload the driver after installing a supported "
- "module.\n");
- ixgbe_down(adapter);
- return err;
+ if (hw->phy.type == ixgbe_phy_unknown) {
+ err = hw->phy.ops.identify(hw);
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+ /*
+ * Take the device down and schedule the sfp tasklet
+ * which will unregister_netdev and log it.
+ */
+ ixgbe_down(adapter);
+ schedule_work(&adapter->sfp_config_module_task);
+ return err;
+ }
}
if (ixgbe_is_sfp(hw)) {
@@ -3126,7 +3130,11 @@
#endif
if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
DPRINTK(PROBE, INFO, "FCOE enabled with RSS \n");
- ixgbe_set_rss_queues(adapter);
+ if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ||
+ (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))
+ ixgbe_set_fdir_queues(adapter);
+ else
+ ixgbe_set_rss_queues(adapter);
}
/* adding FCoE rx rings to the end */
f->mask = adapter->num_rx_queues;
@@ -3384,7 +3392,12 @@
}
#endif /* CONFIG_IXGBE_DCB */
if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
- ixgbe_cache_ring_rss(adapter);
+ if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ||
+ (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))
+ ixgbe_cache_ring_fdir(adapter);
+ else
+ ixgbe_cache_ring_rss(adapter);
+
fcoe_i = f->mask;
}
for (i = 0; i < f->indices; i++, fcoe_i++)
@@ -3724,7 +3737,7 @@
if ((hw->phy.type == ixgbe_phy_nl) &&
(hw->phy.sfp_type == ixgbe_sfp_type_not_present)) {
s32 ret = hw->phy.ops.identify_sfp(hw);
- if (ret)
+ if (ret == IXGBE_ERR_SFP_NOT_PRESENT)
goto reschedule;
ret = hw->phy.ops.reset(hw);
if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) {
@@ -4534,13 +4547,17 @@
u32 err;
adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK;
+
+ /* Time for electrical oscillations to settle down */
+ msleep(100);
err = hw->phy.ops.identify_sfp(hw);
+
if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
dev_err(&adapter->pdev->dev, "failed to initialize because "
"an unsupported SFP+ module type was detected.\n"
"Reload the driver after installing a supported "
"module.\n");
- ixgbe_down(adapter);
+ unregister_netdev(adapter->netdev);
return;
}
hw->mac.ops.setup_sfp(hw);
@@ -5570,12 +5587,6 @@
netdev->features |= NETIF_F_FCOE_CRC;
netdev->features |= NETIF_F_FSO;
netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1;
- DPRINTK(DRV, INFO, "FCoE enabled, "
- "disabling Flow Director\n");
- adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
- adapter->flags &=
- ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
- adapter->atr_sample_rate = 0;
} else {
adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;
}
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index 453e966..9ecad17 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -60,6 +60,7 @@
if (hw->phy.type == ixgbe_phy_unknown) {
for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
+ hw->phy.mdio.prtad = phy_addr;
if (mdio45_probe(&hw->phy.mdio, phy_addr) == 0) {
ixgbe_get_phy_id(hw);
hw->phy.type =
@@ -68,6 +69,8 @@
break;
}
}
+ /* clear value if nothing found */
+ hw->phy.mdio.prtad = 0;
} else {
status = 0;
}
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index c9bfe4e..78c0883 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -130,8 +130,8 @@
static const char version[] __devinitconst =
KERN_INFO DRV_NAME " dp8381x driver, version "
DRV_VERSION ", " DRV_RELDATE "\n"
- KERN_INFO " originally by Donald Becker <becker@scyld.com>\n"
- KERN_INFO " 2.4.x kernel port by Jeff Garzik, Tjeerd Mulder\n";
+ " originally by Donald Becker <becker@scyld.com>\n"
+ " 2.4.x kernel port by Jeff Garzik, Tjeerd Mulder\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("National Semiconductor DP8381x series PCI Ethernet driver");
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index 5c3e242..992dbff 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -321,7 +321,7 @@
}
if (ei_debug && version_printed++ == 0)
- printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
+ printk(KERN_INFO "%s%s", version1, version2);
printk(KERN_INFO "NE*000 ethercard probe at %#3lx:", ioaddr);
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 970cede..e1cdba7 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -60,7 +60,18 @@
#define _NETXEN_NIC_LINUX_SUBVERSION 30
#define NETXEN_NIC_LINUX_VERSIONID "4.0.30"
-#define NETXEN_VERSION_CODE(a, b, c) (((a) << 16) + ((b) << 8) + (c))
+#define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
+#define _major(v) (((v) >> 24) & 0xff)
+#define _minor(v) (((v) >> 16) & 0xff)
+#define _build(v) ((v) & 0xffff)
+
+/* version in image has weird encoding:
+ * 7:0 - major
+ * 15:8 - minor
+ * 31:16 - build (little endian)
+ */
+#define NETXEN_DECODE_VERSION(v) \
+ NETXEN_VERSION_CODE(((v) & 0xff), (((v) >> 8) & 0xff), ((v) >> 16))
#define NETXEN_NUM_FLASH_SECTORS (64)
#define NETXEN_FLASH_SECTOR_SIZE (64 * 1024)
@@ -614,6 +625,7 @@
#define NX_P2_MN_ROMIMAGE 0
#define NX_P3_CT_ROMIMAGE 1
#define NX_P3_MN_ROMIMAGE 2
+#define NX_FLASH_ROMIMAGE 3
#define NETXEN_USER_START_OLD NETXEN_PXE_START /* for backward compatibility */
@@ -1243,7 +1255,7 @@
u32 resv3;
u8 has_link_events;
- u8 resv1;
+ u8 fw_type;
u16 tx_context_id;
u16 mtu;
u16 is_up;
@@ -1387,6 +1399,7 @@
int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
int netxen_load_firmware(struct netxen_adapter *adapter);
+int netxen_need_fw_reset(struct netxen_adapter *adapter);
void netxen_request_firmware(struct netxen_adapter *adapter);
void netxen_release_firmware(struct netxen_adapter *adapter);
int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 3cc0478..8241036 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -853,6 +853,7 @@
#define NX_PEG_TUNE_CAPABILITY (NETXEN_CAM_RAM(0x02c))
#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14)
+#define NETXEN_PEG_ALIVE_COUNTER (NETXEN_CAM_RAM(0xb0))
#define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
#define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200)
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 055bb61..b899bd5 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -684,11 +684,84 @@
}
int
+netxen_need_fw_reset(struct netxen_adapter *adapter)
+{
+ u32 count, old_count;
+ u32 val, version, major, minor, build;
+ int i, timeout;
+ u8 fw_type;
+
+ /* NX2031 firmware doesn't support heartbit */
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return 1;
+
+ /* last attempt had failed */
+ if (NXRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED)
+ return 1;
+
+ old_count = count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
+
+ for (i = 0; i < 10; i++) {
+
+ timeout = msleep_interruptible(200);
+ if (timeout) {
+ NXWR32(adapter, CRB_CMDPEG_STATE,
+ PHAN_INITIALIZE_FAILED);
+ return -EINTR;
+ }
+
+ count = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
+ if (count != old_count)
+ break;
+ }
+
+ /* firmware is dead */
+ if (count == old_count)
+ return 1;
+
+ /* check if we have got newer or different file firmware */
+ if (adapter->fw) {
+
+ const struct firmware *fw = adapter->fw;
+
+ val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
+ version = NETXEN_DECODE_VERSION(val);
+
+ major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+ minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+ build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
+
+ if (version > NETXEN_VERSION_CODE(major, minor, build))
+ return 1;
+
+ if (version == NETXEN_VERSION_CODE(major, minor, build)) {
+
+ val = NXRD32(adapter, NETXEN_MIU_MN_CONTROL);
+ fw_type = (val & 0x4) ?
+ NX_P3_CT_ROMIMAGE : NX_P3_MN_ROMIMAGE;
+
+ if (adapter->fw_type != fw_type)
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static char *fw_name[] = {
+ "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin", "flash",
+};
+
+int
netxen_load_firmware(struct netxen_adapter *adapter)
{
u64 *ptr64;
u32 i, flashaddr, size;
const struct firmware *fw = adapter->fw;
+ struct pci_dev *pdev = adapter->pdev;
+
+ dev_info(&pdev->dev, "loading firmware from %s\n",
+ fw_name[adapter->fw_type]);
if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1);
@@ -756,7 +829,7 @@
netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
{
__le32 val;
- u32 major, minor, build, ver, min_ver, bios;
+ u32 ver, min_ver, bios;
struct pci_dev *pdev = adapter->pdev;
const struct firmware *fw = adapter->fw;
@@ -768,21 +841,18 @@
return -EINVAL;
val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
- major = (__force u32)val & 0xff;
- minor = ((__force u32)val >> 8) & 0xff;
- build = (__force u32)val >> 16;
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
min_ver = NETXEN_VERSION_CODE(4, 0, 216);
else
min_ver = NETXEN_VERSION_CODE(3, 4, 216);
- ver = NETXEN_VERSION_CODE(major, minor, build);
+ ver = NETXEN_DECODE_VERSION(val);
- if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
+ if ((_major(ver) > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
dev_err(&pdev->dev,
"%s: firmware version %d.%d.%d unsupported\n",
- fwname, major, minor, build);
+ fwname, _major(ver), _minor(ver), _build(ver));
return -EINVAL;
}
@@ -798,22 +868,21 @@
if (netxen_rom_fast_read(adapter,
NX_FW_VERSION_OFFSET, (int *)&val))
return -EIO;
- major = (__force u32)val & 0xff;
- minor = ((__force u32)val >> 8) & 0xff;
- build = (__force u32)val >> 16;
- if (NETXEN_VERSION_CODE(major, minor, build) > ver)
+ val = NETXEN_DECODE_VERSION(val);
+ if (val > ver) {
+ dev_info(&pdev->dev, "%s: firmware is older than flash\n",
+ fwname);
return -EINVAL;
+ }
NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
return 0;
}
-static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };
-
void netxen_request_firmware(struct netxen_adapter *adapter)
{
u32 capability, flashed_ver;
- int fw_type;
+ u8 fw_type;
struct pci_dev *pdev = adapter->pdev;
int rc = 0;
@@ -830,6 +899,8 @@
netxen_rom_fast_read(adapter,
NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
+ flashed_ver = NETXEN_DECODE_VERSION(flashed_ver);
+
if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY);
if (capability & NX_PEG_TUNE_MN_PRESENT) {
@@ -838,6 +909,10 @@
}
}
+ fw_type = NX_FLASH_ROMIMAGE;
+ adapter->fw = NULL;
+ goto done;
+
request_fw:
rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev);
if (rc != 0) {
@@ -846,6 +921,7 @@
goto request_mn;
}
+ fw_type = NX_FLASH_ROMIMAGE;
adapter->fw = NULL;
goto done;
}
@@ -859,16 +935,13 @@
goto request_mn;
}
+ fw_type = NX_FLASH_ROMIMAGE;
adapter->fw = NULL;
goto done;
}
done:
- if (adapter->fw)
- dev_info(&pdev->dev, "loading firmware from file %s\n",
- fw_name[fw_type]);
- else
- dev_info(&pdev->dev, "loading firmware from flash\n");
+ adapter->fw_type = fw_type;
}
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 2919a2d..27539dd 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -718,6 +718,10 @@
if (request_fw)
netxen_request_firmware(adapter);
+ err = netxen_need_fw_reset(adapter);
+ if (err <= 0)
+ return err;
+
if (first_boot != 0x55555555) {
NXWR32(adapter, CRB_CMDPEG_STATE, 0);
netxen_pinit_from_rom(adapter, 0);
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index 8c1f698..89f7b2a 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -105,7 +105,7 @@
static char version[] __devinitdata =
KERN_INFO NETDRV_DRIVER_LOAD_MSG "\n"
-KERN_INFO " Support available from http://foo.com/bar/baz.html\n";
+" Support available from http://foo.com/bar/baz.html\n";
/* define to 1 to enable PIO instead of MMIO */
#undef USE_IO_OPS
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index f51944b..06618af 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -298,14 +298,11 @@
strcpy(info->node.dev_name, dev->name);
- printk(KERN_INFO "%s: port %#3lx, irq %d,",
- dev->name, dev->base_addr, dev->irq);
- printk (" mmio %#5lx,", (u_long)ti->mmio);
- printk (" sram %#5lx,", (u_long)ti->sram_base << 12);
- printk ("\n" KERN_INFO " hwaddr=");
- for (i = 0; i < TR_ALEN; i++)
- printk("%02X", dev->dev_addr[i]);
- printk("\n");
+ printk(KERN_INFO
+ "%s: port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n",
+ dev->name, dev->base_addr, dev->irq,
+ (u_long)ti->mmio, (u_long)(ti->sram_base << 12),
+ dev->dev_addr);
return 0;
cs_failed:
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 02ef63e..36de91b 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -1425,15 +1425,12 @@
ladrf[byte] |= (1 << (hashcode & 7));
#ifdef PCMCIA_DEBUG
- if (pc_debug > 2) {
- printk(KERN_DEBUG " adr =");
- for (i = 0; i < 6; i++)
- printk(" %02X", adr[i]);
- printk("\n" KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63]"
- " =", hashcode);
- for (i = 0; i < 8; i++)
- printk(" %02X", ladrf[i]);
- printk("\n");
+ if (pc_debug > 2)
+ printk(KERN_DEBUG " adr =%pM\n", adr);
+ printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode);
+ for (i = 0; i < 8; i++)
+ printk(KERN_CONT " %02X", ladrf[i]);
+ printk(KERN_CONT "\n");
}
#endif
} /* BuildLAF */
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 652a368..9ef1c1b 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1727,6 +1727,7 @@
PCMCIA_DEVICE_PROD_ID12("PRETEC", "Ethernet CompactLAN 10BaseT 3.3V", 0xebf91155, 0x7f5a4f50),
PCMCIA_DEVICE_PROD_ID12("Psion Dacom", "Gold Card Ethernet", 0xf5f025c2, 0x3a30e110),
PCMCIA_DEVICE_PROD_ID12("=RELIA==", "Ethernet", 0xcdd0644a, 0x00b2e941),
+ PCMCIA_DEVICE_PROD_ID12("RIOS Systems Co.", "PC CARD3 ETHERNET", 0x7dd33481, 0x10b41826),
PCMCIA_DEVICE_PROD_ID12("RP", "1625B Ethernet NE2000 Compatible", 0xe3e66e22, 0xb96150df),
PCMCIA_DEVICE_PROD_ID12("RPTI", "EP400 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4a7e2ae0),
PCMCIA_DEVICE_PROD_ID12("RPTI", "EP401 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4bcbd7fd),
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 1c35e1d..2836815 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -485,7 +485,7 @@
&new_ring_dma_addr);
if (new_tx_ring == NULL) {
if (netif_msg_drv(lp))
- printk("\n" KERN_ERR
+ printk(KERN_ERR
"%s: Consistent memory allocation failed.\n",
dev->name);
return;
@@ -496,7 +496,7 @@
GFP_ATOMIC);
if (!new_dma_addr_list) {
if (netif_msg_drv(lp))
- printk("\n" KERN_ERR
+ printk(KERN_ERR
"%s: Memory allocation failed.\n", dev->name);
goto free_new_tx_ring;
}
@@ -505,7 +505,7 @@
GFP_ATOMIC);
if (!new_skb_list) {
if (netif_msg_drv(lp))
- printk("\n" KERN_ERR
+ printk(KERN_ERR
"%s: Memory allocation failed.\n", dev->name);
goto free_new_lists;
}
@@ -563,7 +563,7 @@
&new_ring_dma_addr);
if (new_rx_ring == NULL) {
if (netif_msg_drv(lp))
- printk("\n" KERN_ERR
+ printk(KERN_ERR
"%s: Consistent memory allocation failed.\n",
dev->name);
return;
@@ -574,7 +574,7 @@
GFP_ATOMIC);
if (!new_dma_addr_list) {
if (netif_msg_drv(lp))
- printk("\n" KERN_ERR
+ printk(KERN_ERR
"%s: Memory allocation failed.\n", dev->name);
goto free_new_rx_ring;
}
@@ -583,7 +583,7 @@
GFP_ATOMIC);
if (!new_skb_list) {
if (netif_msg_drv(lp))
- printk("\n" KERN_ERR
+ printk(KERN_ERR
"%s: Memory allocation failed.\n", dev->name);
goto free_new_lists;
}
@@ -1766,38 +1766,38 @@
/* Version 0x2623 and 0x2624 */
if (((chip_version + 1) & 0xfffe) == 0x2624) {
i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */
- printk("\n" KERN_INFO " tx_start_pt(0x%04x):", i);
+ printk(KERN_INFO " tx_start_pt(0x%04x):", i);
switch (i >> 10) {
case 0:
- printk(" 20 bytes,");
+ printk(KERN_CONT " 20 bytes,");
break;
case 1:
- printk(" 64 bytes,");
+ printk(KERN_CONT " 64 bytes,");
break;
case 2:
- printk(" 128 bytes,");
+ printk(KERN_CONT " 128 bytes,");
break;
case 3:
- printk("~220 bytes,");
+ printk(KERN_CONT "~220 bytes,");
break;
}
i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */
- printk(" BCR18(%x):", i & 0xffff);
+ printk(KERN_CONT " BCR18(%x):", i & 0xffff);
if (i & (1 << 5))
- printk("BurstWrEn ");
+ printk(KERN_CONT "BurstWrEn ");
if (i & (1 << 6))
- printk("BurstRdEn ");
+ printk(KERN_CONT "BurstRdEn ");
if (i & (1 << 7))
- printk("DWordIO ");
+ printk(KERN_CONT "DWordIO ");
if (i & (1 << 11))
- printk("NoUFlow ");
+ printk(KERN_CONT "NoUFlow ");
i = a->read_bcr(ioaddr, 25);
- printk("\n" KERN_INFO " SRAMSIZE=0x%04x,", i << 8);
+ printk(KERN_INFO " SRAMSIZE=0x%04x,", i << 8);
i = a->read_bcr(ioaddr, 26);
- printk(" SRAM_BND=0x%04x,", i << 8);
+ printk(KERN_CONT " SRAM_BND=0x%04x,", i << 8);
i = a->read_bcr(ioaddr, 27);
if (i & (1 << 14))
- printk("LowLatRx");
+ printk(KERN_CONT "LowLatRx");
}
}
@@ -1996,7 +1996,7 @@
&lp->tx_ring_dma_addr);
if (lp->tx_ring == NULL) {
if (netif_msg_drv(lp))
- printk("\n" KERN_ERR PFX
+ printk(KERN_ERR PFX
"%s: Consistent memory allocation failed.\n",
name);
return -ENOMEM;
@@ -2008,7 +2008,7 @@
&lp->rx_ring_dma_addr);
if (lp->rx_ring == NULL) {
if (netif_msg_drv(lp))
- printk("\n" KERN_ERR PFX
+ printk(KERN_ERR PFX
"%s: Consistent memory allocation failed.\n",
name);
return -ENOMEM;
@@ -2018,7 +2018,7 @@
GFP_ATOMIC);
if (!lp->tx_dma_addr) {
if (netif_msg_drv(lp))
- printk("\n" KERN_ERR PFX
+ printk(KERN_ERR PFX
"%s: Memory allocation failed.\n", name);
return -ENOMEM;
}
@@ -2027,7 +2027,7 @@
GFP_ATOMIC);
if (!lp->rx_dma_addr) {
if (netif_msg_drv(lp))
- printk("\n" KERN_ERR PFX
+ printk(KERN_ERR PFX
"%s: Memory allocation failed.\n", name);
return -ENOMEM;
}
@@ -2036,7 +2036,7 @@
GFP_ATOMIC);
if (!lp->tx_skbuff) {
if (netif_msg_drv(lp))
- printk("\n" KERN_ERR PFX
+ printk(KERN_ERR PFX
"%s: Memory allocation failed.\n", name);
return -ENOMEM;
}
@@ -2045,7 +2045,7 @@
GFP_ATOMIC);
if (!lp->rx_skbuff) {
if (netif_msg_drv(lp))
- printk("\n" KERN_ERR PFX
+ printk(KERN_ERR PFX
"%s: Memory allocation failed.\n", name);
return -ENOMEM;
}
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 61755cb..eda94fc 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -928,13 +928,32 @@
* Otherwise, it's 0, and we're
* still waiting for AN */
if (err > 0) {
- phydev->state = PHY_RUNNING;
+ err = phy_read_status(phydev);
+ if (err)
+ break;
+
+ if (phydev->link) {
+ phydev->state = PHY_RUNNING;
+ netif_carrier_on(phydev->attached_dev);
+ } else
+ phydev->state = PHY_NOLINK;
+ phydev->adjust_link(phydev->attached_dev);
} else {
phydev->state = PHY_AN;
phydev->link_timeout = PHY_AN_TIMEOUT;
}
- } else
- phydev->state = PHY_RUNNING;
+ } else {
+ err = phy_read_status(phydev);
+ if (err)
+ break;
+
+ if (phydev->link) {
+ phydev->state = PHY_RUNNING;
+ netif_carrier_on(phydev->attached_dev);
+ } else
+ phydev->state = PHY_NOLINK;
+ phydev->adjust_link(phydev->attached_dev);
+ }
break;
}
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 156e02e..6ed5317 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1607,6 +1607,8 @@
int ql_cam_route_initialize(struct ql_adapter *qdev);
int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
int ql_mb_about_fw(struct ql_adapter *qdev);
+void ql_link_on(struct ql_adapter *qdev);
+void ql_link_off(struct ql_adapter *qdev);
#if 1
#define QL_ALL_DUMP
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 37c99fe..eb6a9ee 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -59,7 +59,7 @@
cqicb->pkt_delay =
cpu_to_le16(qdev->tx_max_coalesced_frames);
cqicb->flags = FLAGS_LI;
- status = ql_write_cfg(qdev, cqicb, sizeof(cqicb),
+ status = ql_write_cfg(qdev, cqicb, sizeof(*cqicb),
CFG_LCQ, rx_ring->cq_id);
if (status) {
QPRINTK(qdev, IFUP, ERR,
@@ -82,7 +82,7 @@
cqicb->pkt_delay =
cpu_to_le16(qdev->rx_max_coalesced_frames);
cqicb->flags = FLAGS_LI;
- status = ql_write_cfg(qdev, cqicb, sizeof(cqicb),
+ status = ql_write_cfg(qdev, cqicb, sizeof(*cqicb),
CFG_LCQ, rx_ring->cq_id);
if (status) {
QPRINTK(qdev, IFUP, ERR,
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 90d1f76..5768af1 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -214,6 +214,10 @@
return -ENOMEM;
}
+ status = ql_sem_spinlock(qdev, SEM_ICB_MASK);
+ if (status)
+ return status;
+
status = ql_wait_cfg(qdev, bit);
if (status) {
QPRINTK(qdev, IFUP, ERR,
@@ -221,12 +225,8 @@
goto exit;
}
- status = ql_sem_spinlock(qdev, SEM_ICB_MASK);
- if (status)
- goto exit;
ql_write32(qdev, ICB_L, (u32) map);
ql_write32(qdev, ICB_H, (u32) (map >> 32));
- ql_sem_unlock(qdev, SEM_ICB_MASK); /* does flush too */
mask = CFG_Q_MASK | (bit << 16);
value = bit | (q_id << CFG_Q_SHIFT);
@@ -237,6 +237,7 @@
*/
status = ql_wait_cfg(qdev, bit);
exit:
+ ql_sem_unlock(qdev, SEM_ICB_MASK); /* does flush too */
pci_unmap_single(qdev->pdev, map, size, direction);
return status;
}
@@ -412,6 +413,57 @@
return status;
}
+/* Set or clear MAC address in hardware. We sometimes
+ * have to clear it to prevent wrong frame routing
+ * especially in a bonding environment.
+ */
+static int ql_set_mac_addr(struct ql_adapter *qdev, int set)
+{
+ int status;
+ char zero_mac_addr[ETH_ALEN];
+ char *addr;
+
+ if (set) {
+ addr = &qdev->ndev->dev_addr[0];
+ QPRINTK(qdev, IFUP, DEBUG,
+ "Set Mac addr %02x:%02x:%02x:%02x:%02x:%02x\n",
+ addr[0], addr[1], addr[2], addr[3],
+ addr[4], addr[5]);
+ } else {
+ memset(zero_mac_addr, 0, ETH_ALEN);
+ addr = &zero_mac_addr[0];
+ QPRINTK(qdev, IFUP, DEBUG,
+ "Clearing MAC address on %s\n",
+ qdev->ndev->name);
+ }
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ return status;
+ status = ql_set_mac_addr_reg(qdev, (u8 *) addr,
+ MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ QPRINTK(qdev, IFUP, ERR, "Failed to init mac "
+ "address.\n");
+ return status;
+}
+
+void ql_link_on(struct ql_adapter *qdev)
+{
+ QPRINTK(qdev, LINK, ERR, "%s: Link is up.\n",
+ qdev->ndev->name);
+ netif_carrier_on(qdev->ndev);
+ ql_set_mac_addr(qdev, 1);
+}
+
+void ql_link_off(struct ql_adapter *qdev)
+{
+ QPRINTK(qdev, LINK, ERR, "%s: Link is down.\n",
+ qdev->ndev->name);
+ netif_carrier_off(qdev->ndev);
+ ql_set_mac_addr(qdev, 0);
+}
+
/* Get a specific frame routing value from the CAM.
* Used for debug and reg dump.
*/
@@ -1628,7 +1680,7 @@
tx_ring = &qdev->tx_ring[mac_rsp->txq_idx];
tx_ring_desc = &tx_ring->q[mac_rsp->tid];
ql_unmap_send(qdev, tx_ring_desc, tx_ring_desc->map_cnt);
- qdev->stats.tx_bytes += tx_ring_desc->map_cnt;
+ qdev->stats.tx_bytes += (tx_ring_desc->skb)->len;
qdev->stats.tx_packets++;
dev_kfree_skb(tx_ring_desc->skb);
tx_ring_desc->skb = NULL;
@@ -1660,13 +1712,13 @@
/* Fire up a handler to reset the MPI processor. */
void ql_queue_fw_error(struct ql_adapter *qdev)
{
- netif_carrier_off(qdev->ndev);
+ ql_link_off(qdev);
queue_delayed_work(qdev->workqueue, &qdev->mpi_reset_work, 0);
}
void ql_queue_asic_error(struct ql_adapter *qdev)
{
- netif_carrier_off(qdev->ndev);
+ ql_link_off(qdev);
ql_disable_interrupts(qdev);
/* Clear adapter up bit to signal the recovery
* process that it shouldn't kill the reset worker
@@ -2104,7 +2156,7 @@
}
tx_ring_desc = &tx_ring->q[tx_ring->prod_idx];
mac_iocb_ptr = tx_ring_desc->queue_entry;
- memset((void *)mac_iocb_ptr, 0, sizeof(mac_iocb_ptr));
+ memset((void *)mac_iocb_ptr, 0, sizeof(*mac_iocb_ptr));
mac_iocb_ptr->opcode = OPCODE_OB_MAC_IOCB;
mac_iocb_ptr->tid = tx_ring_desc->index;
@@ -2743,7 +2795,7 @@
ql_init_tx_ring(qdev, tx_ring);
- err = ql_write_cfg(qdev, wqicb, sizeof(wqicb), CFG_LRQ,
+ err = ql_write_cfg(qdev, wqicb, sizeof(*wqicb), CFG_LRQ,
(u16) tx_ring->wq_id);
if (err) {
QPRINTK(qdev, IFUP, ERR, "Failed to load tx_ring.\n");
@@ -3008,7 +3060,7 @@
int i;
u8 *hash_id = (u8 *) ricb->hash_cq_id;
- memset((void *)ricb, 0, sizeof(ricb));
+ memset((void *)ricb, 0, sizeof(*ricb));
ricb->base_cq = qdev->rss_ring_first_cq_id | RSS_L4K;
ricb->flags =
@@ -3030,7 +3082,7 @@
QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n");
- status = ql_write_cfg(qdev, ricb, sizeof(ricb), CFG_LR, 0);
+ status = ql_write_cfg(qdev, ricb, sizeof(*ricb), CFG_LR, 0);
if (status) {
QPRINTK(qdev, IFUP, ERR, "Failed to load RICB.\n");
return status;
@@ -3039,25 +3091,40 @@
return status;
}
+static int ql_clear_routing_entries(struct ql_adapter *qdev)
+{
+ int i, status = 0;
+
+ status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+ if (status)
+ return status;
+ /* Clear all the entries in the routing table. */
+ for (i = 0; i < 16; i++) {
+ status = ql_set_routing_reg(qdev, i, 0, 0);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR,
+ "Failed to init routing register for CAM "
+ "packets.\n");
+ break;
+ }
+ }
+ ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
+ return status;
+}
+
/* Initialize the frame-to-queue routing. */
static int ql_route_initialize(struct ql_adapter *qdev)
{
int status = 0;
- int i;
status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
if (status)
return status;
/* Clear all the entries in the routing table. */
- for (i = 0; i < 16; i++) {
- status = ql_set_routing_reg(qdev, i, 0, 0);
- if (status) {
- QPRINTK(qdev, IFUP, ERR,
- "Failed to init routing register for CAM packets.\n");
- goto exit;
- }
- }
+ status = ql_clear_routing_entries(qdev);
+ if (status)
+ goto exit;
status = ql_set_routing_reg(qdev, RT_IDX_ALL_ERR_SLOT, RT_IDX_ERR, 1);
if (status) {
@@ -3096,14 +3163,15 @@
int ql_cam_route_initialize(struct ql_adapter *qdev)
{
- int status;
+ int status, set;
- status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
- if (status)
- return status;
- status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr,
- MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
- ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
+ /* If check if the link is up and use to
+ * determine if we are setting or clearing
+ * the MAC address in the CAM.
+ */
+ set = ql_read32(qdev, STS);
+ set &= qdev->port_link_up;
+ status = ql_set_mac_addr(qdev, set);
if (status) {
QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n");
return status;
@@ -3210,9 +3278,17 @@
{
u32 value;
int status = 0;
- unsigned long end_jiffies = jiffies +
- max((unsigned long)1, usecs_to_jiffies(30));
+ unsigned long end_jiffies;
+ /* Clear all the entries in the routing table. */
+ status = ql_clear_routing_entries(qdev);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Failed to clear routing bits.\n");
+ return status;
+ }
+
+ end_jiffies = jiffies +
+ max((unsigned long)1, usecs_to_jiffies(30));
ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
do {
@@ -3252,7 +3328,7 @@
int i, status = 0;
struct rx_ring *rx_ring;
- netif_carrier_off(qdev->ndev);
+ ql_link_off(qdev);
/* Don't kill the reset worker thread if we
* are in the process of recovery.
@@ -3319,8 +3395,12 @@
}
set_bit(QL_ADAPTER_UP, &qdev->flags);
ql_alloc_rx_buffers(qdev);
- if ((ql_read32(qdev, STS) & qdev->port_init))
- netif_carrier_on(qdev->ndev);
+ /* If the port is initialized and the
+ * link is up the turn on the carrier.
+ */
+ if ((ql_read32(qdev, STS) & qdev->port_init) &&
+ (ql_read32(qdev, STS) & qdev->port_link_up))
+ ql_link_on(qdev);
ql_enable_interrupts(qdev);
ql_enable_all_completion_interrupts(qdev);
netif_tx_start_all_queues(qdev->ndev);
@@ -3346,11 +3426,6 @@
return -ENOMEM;
}
status = ql_request_irq(qdev);
- if (status)
- goto err_irq;
- return status;
-err_irq:
- ql_free_mem_resources(qdev);
return status;
}
@@ -3414,7 +3489,7 @@
for (i = 0; i < qdev->tx_ring_count; i++) {
tx_ring = &qdev->tx_ring[i];
- memset((void *)tx_ring, 0, sizeof(tx_ring));
+ memset((void *)tx_ring, 0, sizeof(*tx_ring));
tx_ring->qdev = qdev;
tx_ring->wq_id = i;
tx_ring->wq_len = qdev->tx_ring_size;
@@ -3430,7 +3505,7 @@
for (i = 0; i < qdev->rx_ring_count; i++) {
rx_ring = &qdev->rx_ring[i];
- memset((void *)rx_ring, 0, sizeof(rx_ring));
+ memset((void *)rx_ring, 0, sizeof(*rx_ring));
rx_ring->qdev = qdev;
rx_ring->cq_id = i;
rx_ring->cpu = i % cpu_cnt; /* CPU to run handler on. */
@@ -3789,7 +3864,7 @@
int pos, err = 0;
u16 val16;
- memset((void *)qdev, 0, sizeof(qdev));
+ memset((void *)qdev, 0, sizeof(*qdev));
err = pci_enable_device(pdev);
if (err) {
dev_err(&pdev->dev, "PCI device enable failed.\n");
@@ -3976,7 +4051,7 @@
pci_disable_device(pdev);
return err;
}
- netif_carrier_off(ndev);
+ ql_link_off(qdev);
ql_display_dev_info(ndev);
cards_found++;
return 0;
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 71afbf8..6685bd9 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -238,7 +238,7 @@
&qdev->mpi_port_cfg_work, 0);
}
- netif_carrier_on(qdev->ndev);
+ ql_link_on(qdev);
}
static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp)
@@ -251,7 +251,7 @@
if (status)
QPRINTK(qdev, DRV, ERR, "Link down AEN broken!\n");
- netif_carrier_off(qdev->ndev);
+ ql_link_off(qdev);
}
static int ql_sfp_in(struct ql_adapter *qdev, struct mbox_params *mbcp)
@@ -849,7 +849,7 @@
case MB_CMD_PORT_RESET:
case MB_CMD_SET_PORT_CFG:
case MB_CMD_STOP_FW:
- netif_carrier_off(qdev->ndev);
+ ql_link_off(qdev);
/* Signal the resulting link up AEN
* that the frame routing and mac addr
* needs to be set.
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index ed63d23..961b539 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -49,8 +49,8 @@
#include <asm/processor.h>
#define DRV_NAME "r6040"
-#define DRV_VERSION "0.23"
-#define DRV_RELDATE "05May2009"
+#define DRV_VERSION "0.24"
+#define DRV_RELDATE "08Jul2009"
/* PHY CHIP Address */
#define PHY1_ADDR 1 /* For MAC1 */
@@ -704,8 +704,11 @@
/* Read MISR status and clear */
status = ioread16(ioaddr + MISR);
- if (status == 0x0000 || status == 0xffff)
+ if (status == 0x0000 || status == 0xffff) {
+ /* Restore RDC MAC interrupt */
+ iowrite16(misr, ioaddr + MIER);
return IRQ_NONE;
+ }
/* RX interrupt request */
if (status & RX_INTS) {
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index b60639b..66067f9 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -1938,7 +1938,7 @@
if (!res)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, res->end - res->start);
+ release_mem_region(res->start, resource_size(res));
iounmap(pdata->ioaddr);
@@ -1976,7 +1976,7 @@
retval = -ENODEV;
goto out_0;
}
- res_size = res->end - res->start + 1;
+ res_size = resource_size(res);
irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq_res) {
@@ -2104,7 +2104,7 @@
out_free_netdev_2:
free_netdev(dev);
out_release_io_1:
- release_mem_region(res->start, res->end - res->start);
+ release_mem_region(res->start, resource_size(res));
out_0:
return retval;
}
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 838cce8..669253c 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -180,7 +180,7 @@
/* These identify the driver base version and may not be removed. */
static const char version[] __devinitconst =
KERN_INFO "starfire.c:v1.03 7/26/2000 Written by Donald Becker <becker@scyld.com>\n"
-KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
+" (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver");
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 545f81b..d1521c3 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -1698,13 +1698,13 @@
#ifdef __i386__
if (netif_msg_hw(np)) {
- printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n",
+ printk(KERN_DEBUG " Tx ring at %8.8x:\n",
(int)(np->tx_ring_dma));
for (i = 0; i < TX_RING_SIZE; i++)
- printk(" #%d desc. %4.4x %8.8x %8.8x.\n",
+ printk(KERN_DEBUG " #%d desc. %4.4x %8.8x %8.8x.\n",
i, np->tx_ring[i].status, np->tx_ring[i].frag[0].addr,
np->tx_ring[i].frag[0].length);
- printk("\n"KERN_DEBUG " Rx ring %8.8x:\n",
+ printk(KERN_DEBUG " Rx ring %8.8x:\n",
(int)(np->rx_ring_dma));
for (i = 0; i < /*RX_RING_SIZE*/4 ; i++) {
printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x\n",
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 0f78f99..7030bd5 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -1132,7 +1132,9 @@
}
if (!is_valid_ether_addr(dev->dev_addr)) {
- printk("KERN_ERR: word1: %08x, word2: %08x\n", word1, word2);
+ printk(KERN_ERR
+ "%s: Invalid MAC address. word1: %08x, word2: %08x\n",
+ dev->name, word1, word2);
return -EINVAL;
}
@@ -1201,8 +1203,8 @@
__set_bit(hash, &data->mc_hash[0]);
} else {
printk(KERN_ERR
- "%s: got multicast address of length %d "
- "instead of 6.\n", dev->name,
+ "%s: got multicast address of length %d instead of 6.\n",
+ dev->name,
mc->dmi_addrlen);
}
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index 81f054d..ef49744 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -944,9 +944,10 @@
macmode &= ~FullDuplex;
if (netif_msg_link(de)) {
- printk(KERN_INFO "%s: set link %s\n"
- KERN_INFO "%s: mode 0x%x, sia 0x%x,0x%x,0x%x,0x%x\n"
- KERN_INFO "%s: set mode 0x%x, set sia 0x%x,0x%x,0x%x\n",
+ printk(KERN_INFO
+ "%s: set link %s\n"
+ "%s: mode 0x%x, sia 0x%x,0x%x,0x%x,0x%x\n"
+ "%s: set mode 0x%x, set sia 0x%x,0x%x,0x%x\n",
de->dev->name, media_name[media],
de->dev->name, dr32(MacMode), dr32(SIAStatus),
dr32(CSR13), dr32(CSR14), dr32(CSR15),
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 2abb5d3..99a6364 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -570,16 +570,18 @@
(unsigned int)tp->rx_ring[i].buffer2,
buf[0], buf[1], buf[2]);
for (j = 0; buf[j] != 0xee && j < 1600; j++)
- if (j < 100) printk(" %2.2x", buf[j]);
- printk(" j=%d.\n", j);
+ if (j < 100)
+ printk(KERN_CONT " %2.2x", buf[j]);
+ printk(KERN_CONT " j=%d.\n", j);
}
printk(KERN_DEBUG " Rx ring %8.8x: ", (int)tp->rx_ring);
for (i = 0; i < RX_RING_SIZE; i++)
- printk(" %8.8x", (unsigned int)tp->rx_ring[i].status);
- printk("\n" KERN_DEBUG " Tx ring %8.8x: ", (int)tp->tx_ring);
+ printk(KERN_CONT " %8.8x",
+ (unsigned int)tp->rx_ring[i].status);
+ printk(KERN_DEBUG " Tx ring %8.8x: ", (int)tp->tx_ring);
for (i = 0; i < TX_RING_SIZE; i++)
- printk(" %8.8x", (unsigned int)tp->tx_ring[i].status);
- printk("\n");
+ printk(KERN_CONT " %8.8x", (unsigned int)tp->tx_ring[i].status);
+ printk(KERN_CONT "\n");
}
#endif
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 842b1a2..0f15773 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -142,7 +142,7 @@
static const char version[] __initconst =
KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) "
DRV_RELDATE " Donald Becker <becker@scyld.com>\n"
- KERN_INFO " http://www.scyld.com/network/drivers.html\n";
+ " http://www.scyld.com/network/drivers.html\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("Winbond W89c840 Ethernet driver");
@@ -939,7 +939,7 @@
printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring);
for (i = 0; i < RX_RING_SIZE; i++)
printk(" %8.8x", (unsigned int)np->rx_ring[i].status);
- printk("\n"KERN_DEBUG" Tx ring %p: ", np->tx_ring);
+ printk(KERN_DEBUG" Tx ring %p: ", np->tx_ring);
for (i = 0; i < TX_RING_SIZE; i++)
printk(" %8.8x", np->tx_ring[i].status);
printk("\n");
@@ -1520,7 +1520,7 @@
printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x.\n",
i, np->tx_ring[i].length,
np->tx_ring[i].status, np->tx_ring[i].buffer1);
- printk("\n"KERN_DEBUG " Rx ring %8.8x:\n",
+ printk(KERN_DEBUG " Rx ring %8.8x:\n",
(int)np->rx_ring);
for (i = 0; i < RX_RING_SIZE; i++) {
printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x\n",
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 11a0ba4..027f7ab 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -486,12 +486,14 @@
{
struct tun_file *tfile = file->private_data;
struct tun_struct *tun = __tun_get(tfile);
- struct sock *sk = tun->sk;
+ struct sock *sk;
unsigned int mask = 0;
if (!tun)
return POLLERR;
+ sk = tun->sk;
+
DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);
poll_wait(file, &tun->socket.wait, wait);
@@ -1324,20 +1326,22 @@
struct tun_file *tfile = file->private_data;
struct tun_struct *tun;
-
- rtnl_lock();
tun = __tun_get(tfile);
if (tun) {
- DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
+ struct net_device *dev = tun->dev;
+
+ DBG(KERN_INFO "%s: tun_chr_close\n", dev->name);
__tun_detach(tun);
/* If desireable, unregister the netdevice. */
- if (!(tun->flags & TUN_PERSIST))
- unregister_netdevice(tun->dev);
-
+ if (!(tun->flags & TUN_PERSIST)) {
+ rtnl_lock();
+ if (dev->reg_state == NETREG_REGISTERED)
+ unregister_netdevice(dev);
+ rtnl_unlock();
+ }
}
- rtnl_unlock();
tun = tfile->tun;
if (tun)
diff --git a/drivers/net/wan/hd64570.c b/drivers/net/wan/hd64570.c
index 223238d..1ea1ef6 100644
--- a/drivers/net/wan/hd64570.c
+++ b/drivers/net/wan/hd64570.c
@@ -584,8 +584,9 @@
sca_in(DSR_RX(phy_node(port)), card) & DSR_DE ? "" : "in");
for (cnt = 0; cnt < port_to_card(port)->rx_ring_buffers; cnt++)
printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat)));
+ printk(KERN_CONT "\n");
- printk("\n" KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u "
+ printk(KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u "
"last=%u %sactive",
sca_inw(get_dmac_tx(port) + CDAL, card),
sca_inw(get_dmac_tx(port) + EDAL, card),
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c
index 497b003..f099c34 100644
--- a/drivers/net/wan/hd64572.c
+++ b/drivers/net/wan/hd64572.c
@@ -529,8 +529,9 @@
sca_in(DSR_RX(port->chan), card) & DSR_DE ? "" : "in");
for (cnt = 0; cnt < port->card->rx_ring_buffers; cnt++)
printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat)));
+ printk(KERN_CONT "\n");
- printk("\n" KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u "
+ printk(KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u "
"last=%u %sactive",
sca_inl(get_dmac_tx(port) + CDAL, card),
sca_inl(get_dmac_tx(port) + EDAL, card),
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index 3fb9dbc..d14e95a 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -326,11 +326,9 @@
}
if (pci_irq_line <= 0 || pci_irq_line >= nr_irqs)
- printk( KERN_WARNING " WARNING: The PCI BIOS assigned "
- "this PCI card to IRQ %d, which is unlikely "
- "to work!.\n"
- KERN_WARNING " You should use the PCI BIOS "
- "setup to assign a valid IRQ line.\n",
+ printk( KERN_WARNING
+ " WARNING: The PCI BIOS assigned this PCI card to IRQ %d, which is unlikely to work!.\n"
+ " You should use the PCI BIOS setup to assign a valid IRQ line.\n",
pci_irq_line );
/* avoiding re-enable dual adapters */
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index d26e7b4..eb0337c 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -1,5 +1,6 @@
config ATH_COMMON
tristate "Atheros Wireless Cards"
+ depends on WLAN_80211
depends on ATH5K || ATH9K || AR9170_USB
source "drivers/net/wireless/ath/ath5k/Kconfig"
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index b61a071..4ccf48e 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -355,7 +355,14 @@
}
if (bf_next == NULL) {
- INIT_LIST_HEAD(&bf_head);
+ /*
+ * Make sure the last desc is reclaimed if it
+ * not a holding desc.
+ */
+ if (!bf_last->bf_stale)
+ list_move_tail(&bf->list, &bf_head);
+ else
+ INIT_LIST_HEAD(&bf_head);
} else {
ASSERT(!list_empty(bf_q));
list_move_tail(&bf->list, &bf_head);
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index f580c28..4044806 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -648,6 +648,7 @@
u8 nr_devs;
bool radiotap_enabled;
+ bool radio_enabled;
/* The beacon we are currently using (AP or IBSS mode).
* This beacon stuff is protected by the irq_lock. */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 6456afe..e71c8d9 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3497,8 +3497,8 @@
if (phy->ops->set_rx_antenna)
phy->ops->set_rx_antenna(dev, antenna);
- if (!!conf->radio_enabled != phy->radio_on) {
- if (conf->radio_enabled) {
+ if (wl->radio_enabled != phy->radio_on) {
+ if (wl->radio_enabled) {
b43_software_rfkill(dev, false);
b43info(dev->wl, "Radio turned on by software\n");
if (!dev->radio_hw_enable) {
@@ -4339,6 +4339,7 @@
wl->beacon0_uploaded = 0;
wl->beacon1_uploaded = 0;
wl->beacon_templates_virgin = 1;
+ wl->radio_enabled = 1;
mutex_lock(&wl->mutex);
@@ -4378,6 +4379,7 @@
if (b43_status(dev) >= B43_STAT_STARTED)
b43_wireless_core_stop(dev);
b43_wireless_core_exit(dev);
+ wl->radio_enabled = 0;
mutex_unlock(&wl->mutex);
cancel_work_sync(&(wl->txpower_adjust_work));
@@ -4560,6 +4562,7 @@
B43_WARN_ON(1);
dev->phy.gmode = have_2ghz_phy;
+ dev->phy.radio_on = 1;
tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
b43_wireless_core_reset(dev, tmp);
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c
index 3cfc303..6c3a749 100644
--- a/drivers/net/wireless/b43/pcmcia.c
+++ b/drivers/net/wireless/b43/pcmcia.c
@@ -35,6 +35,7 @@
static /*const */ struct pcmcia_device_id b43_pcmcia_tbl[] = {
PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448),
+ PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476),
PCMCIA_DEVICE_NULL,
};
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index 77fda14..038baa8 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -607,6 +607,7 @@
u8 nr_devs;
bool radiotap_enabled;
+ bool radio_enabled;
/* The beacon we are currently using (AP or IBSS mode).
* This beacon stuff is protected by the irq_lock. */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index e5136fb..c4973c1 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2689,8 +2689,8 @@
/* Antennas for RX and management frame TX. */
b43legacy_mgmtframe_txantenna(dev, antenna_tx);
- if (!!conf->radio_enabled != phy->radio_on) {
- if (conf->radio_enabled) {
+ if (wl->radio_enabled != phy->radio_on) {
+ if (wl->radio_enabled) {
b43legacy_radio_turn_on(dev);
b43legacyinfo(dev->wl, "Radio turned on by software\n");
if (!dev->radio_hw_enable)
@@ -3441,6 +3441,7 @@
wl->beacon0_uploaded = 0;
wl->beacon1_uploaded = 0;
wl->beacon_templates_virgin = 1;
+ wl->radio_enabled = 1;
mutex_lock(&wl->mutex);
@@ -3479,6 +3480,7 @@
if (b43legacy_status(dev) >= B43legacy_STAT_STARTED)
b43legacy_wireless_core_stop(dev);
b43legacy_wireless_core_exit(dev);
+ wl->radio_enabled = 0;
mutex_unlock(&wl->mutex);
}
@@ -3620,6 +3622,7 @@
have_bphy = 1;
dev->phy.gmode = (have_gphy || have_bphy);
+ dev->phy.radio_on = 1;
tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0;
b43legacy_wireless_core_reset(dev, tmp);
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig
index 1eccb6d..030401d 100644
--- a/drivers/net/wireless/iwmc3200wifi/Kconfig
+++ b/drivers/net/wireless/iwmc3200wifi/Kconfig
@@ -4,6 +4,15 @@
depends on CFG80211
select WIRELESS_EXT
select FW_LOADER
+ help
+ The Intel Wireless Multicomm 3200 hardware is a combo
+ card with GPS, Bluetooth, WiMax and 802.11 radios. It
+ runs over SDIO and is typically found on Moorestown
+ based platform. This driver takes care of the 802.11
+ part, which is a fullmac one.
+
+ If you choose to build it as a module, it'll be called
+ iwmc3200wifi.ko.
config IWM_DEBUG
bool "Enable full debugging output in iwmc3200wifi"
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index e789c6e..a111bda 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -418,6 +418,7 @@
continue;
if (!data2->started || !hwsim_ps_rx_ok(data2, skb) ||
+ !data->channel || !data2->channel ||
data->channel->center_freq != data2->channel->center_freq ||
!(data->group & data2->group))
continue;
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index b618bd1..22ca122 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -823,30 +823,30 @@
struct p54_tx_info *range;
unsigned long flags;
- if (unlikely(!skb || !dev || skb_queue_empty(&priv->tx_queue)))
+ if (unlikely(!skb || !dev || !skb_queue_len(&priv->tx_queue)))
return;
- /* There used to be a check here to see if the SKB was on the
- * TX queue or not. This can never happen because all SKBs we
- * see here successfully went through p54_assign_address()
- * which means the SKB is on the ->tx_queue.
+ /*
+ * don't try to free an already unlinked skb
*/
+ if (unlikely((!skb->next) || (!skb->prev)))
+ return;
spin_lock_irqsave(&priv->tx_queue.lock, flags);
info = IEEE80211_SKB_CB(skb);
range = (void *)info->rate_driver_data;
- if (!skb_queue_is_first(&priv->tx_queue, skb)) {
+ if (skb->prev != (struct sk_buff *)&priv->tx_queue) {
struct ieee80211_tx_info *ni;
struct p54_tx_info *mr;
- ni = IEEE80211_SKB_CB(skb_queue_prev(&priv->tx_queue, skb));
+ ni = IEEE80211_SKB_CB(skb->prev);
mr = (struct p54_tx_info *)ni->rate_driver_data;
}
- if (!skb_queue_is_last(&priv->tx_queue, skb)) {
+ if (skb->next != (struct sk_buff *)&priv->tx_queue) {
struct ieee80211_tx_info *ni;
struct p54_tx_info *mr;
- ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue, skb));
+ ni = IEEE80211_SKB_CB(skb->next);
mr = (struct p54_tx_info *)ni->rate_driver_data;
}
__skb_unlink(skb, &priv->tx_queue);
@@ -864,13 +864,15 @@
unsigned long flags;
spin_lock_irqsave(&priv->tx_queue.lock, flags);
- skb_queue_walk(&priv->tx_queue, entry) {
+ entry = priv->tx_queue.next;
+ while (entry != (struct sk_buff *)&priv->tx_queue) {
struct p54_hdr *hdr = (struct p54_hdr *) entry->data;
if (hdr->req_id == req_id) {
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
return entry;
}
+ entry = entry->next;
}
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
return NULL;
@@ -888,33 +890,36 @@
int count, idx;
spin_lock_irqsave(&priv->tx_queue.lock, flags);
- skb_queue_walk(&priv->tx_queue, entry) {
+ entry = (struct sk_buff *) priv->tx_queue.next;
+ while (entry != (struct sk_buff *)&priv->tx_queue) {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
struct p54_hdr *entry_hdr;
struct p54_tx_data *entry_data;
unsigned int pad = 0, frame_len;
range = (void *)info->rate_driver_data;
- if (range->start_addr != addr)
+ if (range->start_addr != addr) {
+ entry = entry->next;
continue;
+ }
- if (!skb_queue_is_last(&priv->tx_queue, entry)) {
+ if (entry->next != (struct sk_buff *)&priv->tx_queue) {
struct ieee80211_tx_info *ni;
struct p54_tx_info *mr;
- ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue,
- entry));
+ ni = IEEE80211_SKB_CB(entry->next);
mr = (struct p54_tx_info *)ni->rate_driver_data;
}
__skb_unlink(entry, &priv->tx_queue);
- spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
frame_len = entry->len;
entry_hdr = (struct p54_hdr *) entry->data;
entry_data = (struct p54_tx_data *) entry_hdr->data;
- priv->tx_stats[entry_data->hw_queue].len--;
+ if (priv->tx_stats[entry_data->hw_queue].len)
+ priv->tx_stats[entry_data->hw_queue].len--;
priv->stats.dot11ACKFailureCount += payload->tries - 1;
+ spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
/*
* Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are
@@ -1164,21 +1169,23 @@
}
}
- skb_queue_walk(&priv->tx_queue, entry) {
+ entry = priv->tx_queue.next;
+ while (left--) {
u32 hole_size;
info = IEEE80211_SKB_CB(entry);
range = (void *)info->rate_driver_data;
hole_size = range->start_addr - last_addr;
if (!target_skb && hole_size >= len) {
- target_skb = skb_queue_prev(&priv->tx_queue, entry);
+ target_skb = entry->prev;
hole_size -= len;
target_addr = last_addr;
}
largest_hole = max(largest_hole, hole_size);
last_addr = range->end_addr;
+ entry = entry->next;
}
if (!target_skb && priv->rx_end - last_addr >= len) {
- target_skb = skb_peek_tail(&priv->tx_queue);
+ target_skb = priv->tx_queue.prev;
largest_hole = max(largest_hole, priv->rx_end - last_addr - len);
if (!skb_queue_empty(&priv->tx_queue)) {
info = IEEE80211_SKB_CB(target_skb);
@@ -2084,6 +2091,7 @@
static void p54_stop(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
+ struct sk_buff *skb;
mutex_lock(&priv->conf_mutex);
priv->mode = NL80211_IFTYPE_UNSPECIFIED;
@@ -2098,7 +2106,8 @@
p54_tx_cancel(dev, priv->cached_beacon);
priv->stop(dev);
- skb_queue_purge(&priv->tx_queue);
+ while ((skb = skb_dequeue(&priv->tx_queue)))
+ kfree_skb(skb);
priv->cached_beacon = NULL;
priv->tsf_high32 = priv->tsf_low32 = 0;
mutex_unlock(&priv->conf_mutex);
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index b10b038..698b11b 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -2427,11 +2427,10 @@
#ifdef PCMCIA_DEBUG
if (pc_debug > 3) {
- int i;
- printk(KERN_DEBUG "skb->data before untranslate");
- for (i = 0; i < 64; i++)
- printk("%02x ", skb->data[i]);
- printk("\n" KERN_DEBUG
+ print_hex_dump(KERN_DEBUG, "skb->data before untranslate: ",
+ DUMP_PREFIX_NONE, 16, 1,
+ skb->data, 64, true);
+ printk(KERN_DEBUG
"type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
ntohs(type), psnap->dsap, psnap->ssap, psnap->ctrl,
psnap->org[0], psnap->org[1], psnap->org[2]);
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 6af7064..c6d3006 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -3556,17 +3556,8 @@
cfblk.rcvstop = TRUE; /* Enable Receive Stop Register */
#ifdef DEBUG_I82593_SHOW
- {
- u_char *c = (u_char *) &cfblk;
- int i;
- printk(KERN_DEBUG "wavelan_cs: config block:");
- for(i = 0; i < sizeof(struct i82593_conf_block); i++,c++)
- {
- if((i % 16) == 0) printk("\n" KERN_DEBUG);
- printk("%02x ", *c);
- }
- printk("\n");
- }
+ print_hex_dump(KERN_DEBUG, "wavelan_cs: config block: ", DUMP_PREFIX_NONE,
+ 16, 1, &cfblk, sizeof(struct i82593_conf_block), false);
#endif
/* Copy the config block to the i82593 */
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 14a19ba..0e6e446 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -38,7 +38,6 @@
/* ZD1211 */
{ USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x0ace, 0xa211), .driver_info = DEVICE_ZD1211 },
- { USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 },
@@ -61,6 +60,7 @@
{ USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 },
/* ZD1211B */
+ { USB_DEVICE(0x054c, 0x0257), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
@@ -87,6 +87,7 @@
{ USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211B },
/* "Driverless" devices that need ejecting */
{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
{ USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 3c7a505..a075801 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -109,7 +109,7 @@
/* These identify the driver base version and may not be removed. */
static const char version[] __devinitconst =
KERN_INFO DRV_NAME ".c:v1.05 1/09/2001 Written by Donald Becker <becker@scyld.com>\n"
- KERN_INFO " (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n";
+ " (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver");
@@ -700,12 +700,15 @@
int i;
printk(KERN_WARNING " Rx ring %p: ", yp->rx_ring);
for (i = 0; i < RX_RING_SIZE; i++)
- printk(" %8.8x", yp->rx_ring[i].result_status);
- printk("\n"KERN_WARNING" Tx ring %p: ", yp->tx_ring);
+ printk(KERN_CONT " %8.8x",
+ yp->rx_ring[i].result_status);
+ printk(KERN_CONT "\n");
+ printk(KERN_WARNING" Tx ring %p: ", yp->tx_ring);
for (i = 0; i < TX_RING_SIZE; i++)
- printk(" %4.4x /%8.8x", yp->tx_status[i].tx_errs,
- yp->tx_ring[i].result_status);
- printk("\n");
+ printk(KERN_CONT " %4.4x /%8.8x",
+ yp->tx_status[i].tx_errs,
+ yp->tx_ring[i].result_status);
+ printk(KERN_CONT "\n");
}
/* If the hardware is found to hang regularly, we will update the code
@@ -1216,20 +1219,20 @@
#if defined(__i386__)
if (yellowfin_debug > 2) {
- printk("\n"KERN_DEBUG" Tx ring at %8.8llx:\n",
+ printk(KERN_DEBUG" Tx ring at %8.8llx:\n",
(unsigned long long)yp->tx_ring_dma);
for (i = 0; i < TX_RING_SIZE*2; i++)
- printk(" %c #%d desc. %8.8x %8.8x %8.8x %8.8x.\n",
+ printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x %8.8x %8.8x.\n",
ioread32(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ',
i, yp->tx_ring[i].dbdma_cmd, yp->tx_ring[i].addr,
yp->tx_ring[i].branch_addr, yp->tx_ring[i].result_status);
printk(KERN_DEBUG " Tx status %p:\n", yp->tx_status);
for (i = 0; i < TX_RING_SIZE; i++)
- printk(" #%d status %4.4x %4.4x %4.4x %4.4x.\n",
+ printk(KERN_DEBUG " #%d status %4.4x %4.4x %4.4x %4.4x.\n",
i, yp->tx_status[i].tx_cnt, yp->tx_status[i].tx_errs,
yp->tx_status[i].total_tx_cnt, yp->tx_status[i].paused);
- printk("\n"KERN_DEBUG " Rx ring %8.8llx:\n",
+ printk(KERN_DEBUG " Rx ring %8.8llx:\n",
(unsigned long long)yp->rx_ring_dma);
for (i = 0; i < RX_RING_SIZE; i++) {
printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x %8.8x\n",
diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c
index e1f6ce0..3c2270a 100644
--- a/drivers/oprofile/oprofile_stats.c
+++ b/drivers/oprofile/oprofile_stats.c
@@ -33,6 +33,7 @@
atomic_set(&oprofile_stats.sample_lost_no_mm, 0);
atomic_set(&oprofile_stats.sample_lost_no_mapping, 0);
atomic_set(&oprofile_stats.event_lost_overflow, 0);
+ atomic_set(&oprofile_stats.bt_lost_no_mapping, 0);
}
diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c
index c709ecc..0be1d50 100644
--- a/drivers/parisc/eisa_enumerator.c
+++ b/drivers/parisc/eisa_enumerator.c
@@ -101,7 +101,7 @@
printk("memory %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
result = request_resource(mem_parent, res);
if (result < 0) {
- printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
+ printk(KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
return result;
}
}
@@ -191,7 +191,7 @@
printk("ioports %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
result = request_resource(io_parent, res);
if (result < 0) {
- printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
+ printk(KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
return result;
}
}
@@ -224,7 +224,7 @@
case HPEE_PORT_INIT_WIDTH_BYTE:
s=1;
if (c & HPEE_PORT_INIT_MASK) {
- printk("\n" KERN_WARNING "port_init: unverified mask attribute\n");
+ printk(KERN_WARNING "port_init: unverified mask attribute\n");
outb((inb(get_16(buf+len+1) &
get_8(buf+len+3)) |
get_8(buf+len+4)), get_16(buf+len+1));
@@ -249,7 +249,7 @@
case HPEE_PORT_INIT_WIDTH_DWORD:
s=4;
if (c & HPEE_PORT_INIT_MASK) {
- printk("\n" KERN_WARNING "port_init: unverified mask attribute\n");
+ printk(KERN_WARNING "port_init: unverified mask attribute\n");
outl((inl(get_16(buf+len+1) &
get_32(buf+len+3)) |
get_32(buf+len+7)), get_16(buf+len+1));
@@ -259,7 +259,7 @@
break;
default:
- printk("\n" KERN_ERR "Invalid port init word %02x\n", c);
+ printk(KERN_ERR "Invalid port init word %02x\n", c);
return 0;
}
@@ -297,7 +297,7 @@
/* just skip past the type field */
len = get_8(buf);
if (len > 80) {
- printk("\n" KERN_ERR "eisa_enumerator: type info field too long (%d, max is 80)\n", len);
+ printk(KERN_ERR "eisa_enumerator: type info field too long (%d, max is 80)\n", len);
}
return 1+len;
@@ -398,7 +398,7 @@
}
if (p0 + function_len < pos) {
- printk("\n" KERN_ERR "eisa_enumerator: function %d length mis-match "
+ printk(KERN_ERR "eisa_enumerator: function %d length mis-match "
"got %d, expected %d\n",
num_func, pos-p0, function_len);
res=-1;
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 8445804..5c5043f 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -555,6 +555,8 @@
* @slot: pointer to the &struct hotplug_slot to register
* @devnr: device number
* @name: name registered with kobject core
+ * @owner: caller module owner
+ * @mod_name: caller module name
*
* Registers a hotplug slot with the pci hotplug subsystem, which will allow
* userspace interaction to the slot.
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 5307542..ebc9b8d 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -2117,6 +2117,47 @@
return 0;
}
+static int iommu_should_identity_map(struct pci_dev *pdev, int startup)
+{
+ if (iommu_identity_mapping == 2)
+ return IS_GFX_DEVICE(pdev);
+
+ /*
+ * We want to start off with all devices in the 1:1 domain, and
+ * take them out later if we find they can't access all of memory.
+ *
+ * However, we can't do this for PCI devices behind bridges,
+ * because all PCI devices behind the same bridge will end up
+ * with the same source-id on their transactions.
+ *
+ * Practically speaking, we can't change things around for these
+ * devices at run-time, because we can't be sure there'll be no
+ * DMA transactions in flight for any of their siblings.
+ *
+ * So PCI devices (unless they're on the root bus) as well as
+ * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
+ * the 1:1 domain, just in _case_ one of their siblings turns out
+ * not to be able to map all of memory.
+ */
+ if (!pdev->is_pcie) {
+ if (!pci_is_root_bus(pdev->bus))
+ return 0;
+ if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
+ return 0;
+ } else if (pdev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
+ return 0;
+
+ /*
+ * At boot time, we don't yet know if devices will be 64-bit capable.
+ * Assume that they will -- if they turn out not to be, then we can
+ * take them out of the 1:1 domain later.
+ */
+ if (!startup)
+ return pdev->dma_mask > DMA_BIT_MASK(32);
+
+ return 1;
+}
+
static int iommu_prepare_static_identity_mapping(void)
{
struct pci_dev *pdev = NULL;
@@ -2127,16 +2168,18 @@
return -EFAULT;
for_each_pci_dev(pdev) {
- printk(KERN_INFO "IOMMU: identity mapping for device %s\n",
- pci_name(pdev));
+ if (iommu_should_identity_map(pdev, 1)) {
+ printk(KERN_INFO "IOMMU: identity mapping for device %s\n",
+ pci_name(pdev));
- ret = domain_context_mapping(si_domain, pdev,
- CONTEXT_TT_MULTI_LEVEL);
- if (ret)
- return ret;
- ret = domain_add_dev_info(si_domain, pdev);
- if (ret)
- return ret;
+ ret = domain_context_mapping(si_domain, pdev,
+ CONTEXT_TT_MULTI_LEVEL);
+ if (ret)
+ return ret;
+ ret = domain_add_dev_info(si_domain, pdev);
+ if (ret)
+ return ret;
+ }
}
return 0;
@@ -2291,6 +2334,10 @@
* identity mapping if iommu_identity_mapping is set.
*/
if (!iommu_pass_through) {
+#ifdef CONFIG_DMAR_BROKEN_GFX_WA
+ if (!iommu_identity_mapping)
+ iommu_identity_mapping = 2;
+#endif
if (iommu_identity_mapping)
iommu_prepare_static_identity_mapping();
/*
@@ -2368,15 +2415,15 @@
return ret;
}
+/* Returns a number of VTD pages, but aligned to MM page size */
static inline unsigned long aligned_nrpages(unsigned long host_addr,
size_t size)
{
host_addr &= ~PAGE_MASK;
- host_addr += size + PAGE_SIZE - 1;
-
- return host_addr >> VTD_PAGE_SHIFT;
+ return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
}
+/* This takes a number of _MM_ pages, not VTD pages */
static struct iova *intel_alloc_iova(struct device *dev,
struct dmar_domain *domain,
unsigned long nrpages, uint64_t dma_mask)
@@ -2443,16 +2490,24 @@
}
/* Check if the pdev needs to go through non-identity map and unmap process.*/
-static int iommu_no_mapping(struct pci_dev *pdev)
+static int iommu_no_mapping(struct device *dev)
{
+ struct pci_dev *pdev;
int found;
+ if (unlikely(dev->bus != &pci_bus_type))
+ return 1;
+
+ pdev = to_pci_dev(dev);
+ if (iommu_dummy(pdev))
+ return 1;
+
if (!iommu_identity_mapping)
- return iommu_dummy(pdev);
+ return 0;
found = identity_mapping(pdev);
if (found) {
- if (pdev->dma_mask > DMA_BIT_MASK(32))
+ if (iommu_should_identity_map(pdev, 0))
return 1;
else {
/*
@@ -2469,9 +2524,12 @@
* In case of a detached 64 bit DMA device from vm, the device
* is put into si_domain for identity mapping.
*/
- if (pdev->dma_mask > DMA_BIT_MASK(32)) {
+ if (iommu_should_identity_map(pdev, 0)) {
int ret;
ret = domain_add_dev_info(si_domain, pdev);
+ if (ret)
+ return 0;
+ ret = domain_context_mapping(si_domain, pdev, CONTEXT_TT_MULTI_LEVEL);
if (!ret) {
printk(KERN_INFO "64bit %s uses identity mapping\n",
pci_name(pdev));
@@ -2480,7 +2538,7 @@
}
}
- return iommu_dummy(pdev);
+ return 0;
}
static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,
@@ -2496,7 +2554,7 @@
BUG_ON(dir == DMA_NONE);
- if (iommu_no_mapping(pdev))
+ if (iommu_no_mapping(hwdev))
return paddr;
domain = get_valid_domain_for_dev(pdev);
@@ -2506,7 +2564,8 @@
iommu = domain_get_iommu(domain);
size = aligned_nrpages(paddr, size);
- iova = intel_alloc_iova(hwdev, domain, size, pdev->dma_mask);
+ iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size),
+ pdev->dma_mask);
if (!iova)
goto error;
@@ -2635,7 +2694,7 @@
struct iova *iova;
struct intel_iommu *iommu;
- if (iommu_no_mapping(pdev))
+ if (iommu_no_mapping(dev))
return;
domain = find_domain(pdev);
@@ -2726,7 +2785,7 @@
struct iova *iova;
struct intel_iommu *iommu;
- if (iommu_no_mapping(pdev))
+ if (iommu_no_mapping(hwdev))
return;
domain = find_domain(pdev);
@@ -2785,7 +2844,7 @@
struct intel_iommu *iommu;
BUG_ON(dir == DMA_NONE);
- if (iommu_no_mapping(pdev))
+ if (iommu_no_mapping(hwdev))
return intel_nontranslate_map_sg(hwdev, sglist, nelems, dir);
domain = get_valid_domain_for_dev(pdev);
@@ -2797,7 +2856,8 @@
for_each_sg(sglist, sg, nelems, i)
size += aligned_nrpages(sg->offset, sg->length);
- iova = intel_alloc_iova(hwdev, domain, size, pdev->dma_mask);
+ iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size),
+ pdev->dma_mask);
if (!iova) {
sglist->dma_length = 0;
return 0;
@@ -3540,6 +3600,9 @@
{
struct dmar_domain *dmar_domain = domain->priv;
+ if (!size)
+ return;
+
dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT,
(iova + size - 1) >> VTD_PAGE_SHIFT);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index d9f06fb..d986afb 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -127,17 +127,23 @@
* reliably as devices without an INTx disable bit will then generate a
* level IRQ which will never be cleared.
*/
-static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
+static u32 __msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
{
u32 mask_bits = desc->masked;
if (!desc->msi_attrib.maskbit)
- return;
+ return 0;
mask_bits &= ~mask;
mask_bits |= flag;
pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits);
- desc->masked = mask_bits;
+
+ return mask_bits;
+}
+
+static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
+{
+ desc->masked = __msi_mask_irq(desc, mask, flag);
}
/*
@@ -147,15 +153,21 @@
* file. This saves a few milliseconds when initialising devices with lots
* of MSI-X interrupts.
*/
-static void msix_mask_irq(struct msi_desc *desc, u32 flag)
+static u32 __msix_mask_irq(struct msi_desc *desc, u32 flag)
{
u32 mask_bits = desc->masked;
unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
- PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
+ PCI_MSIX_ENTRY_VECTOR_CTRL;
mask_bits &= ~1;
mask_bits |= flag;
writel(mask_bits, desc->mask_base + offset);
- desc->masked = mask_bits;
+
+ return mask_bits;
+}
+
+static void msix_mask_irq(struct msi_desc *desc, u32 flag)
+{
+ desc->masked = __msix_mask_irq(desc, flag);
}
static void msi_set_mask_bit(unsigned irq, u32 flag)
@@ -188,9 +200,9 @@
void __iomem *base = entry->mask_base +
entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
- msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
- msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
- msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
+ msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR);
+ msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR);
+ msg->data = readl(base + PCI_MSIX_ENTRY_DATA);
} else {
struct pci_dev *dev = entry->dev;
int pos = entry->msi_attrib.pos;
@@ -225,11 +237,9 @@
base = entry->mask_base +
entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
- writel(msg->address_lo,
- base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
- writel(msg->address_hi,
- base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
- writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
+ writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR);
+ writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR);
+ writel(msg->data, base + PCI_MSIX_ENTRY_DATA);
} else {
struct pci_dev *dev = entry->dev;
int pos = entry->msi_attrib.pos;
@@ -385,6 +395,7 @@
/* Configure MSI capability structure */
ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
if (ret) {
+ msi_mask_irq(entry, mask, ~mask);
msi_free_irqs(dev);
return ret;
}
@@ -439,8 +450,14 @@
for (i = 0; i < nvec; i++) {
entry = alloc_msi_entry(dev);
- if (!entry)
- break;
+ if (!entry) {
+ if (!i)
+ iounmap(base);
+ else
+ msi_free_irqs(dev);
+ /* No enough memory. Don't try again */
+ return -ENOMEM;
+ }
j = entries[i].entry;
entry->msi_attrib.is_msix = 1;
@@ -487,7 +504,7 @@
set_irq_msi(entry->irq, entry);
j = entries[i].entry;
entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE +
- PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+ PCI_MSIX_ENTRY_VECTOR_CTRL);
msix_mask_irq(entry, 1);
i++;
}
@@ -611,9 +628,11 @@
pci_intx_for_msi(dev, 1);
dev->msi_enabled = 0;
+ /* Return the device with MSI unmasked as initial states */
pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &ctrl);
mask = msi_capable_mask(ctrl);
- msi_mask_irq(desc, mask, ~mask);
+ /* Keep cached state to be restored */
+ __msi_mask_irq(desc, mask, ~mask);
/* Restore dev->irq to its default pin-assertion irq */
dev->irq = desc->msi_attrib.default_irq;
@@ -653,7 +672,6 @@
list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
if (entry->msi_attrib.is_msix) {
- msix_mask_irq(entry, 1);
if (list_is_last(&entry->list, &dev->msi_list))
iounmap(entry->mask_base);
}
@@ -741,9 +759,17 @@
void pci_msix_shutdown(struct pci_dev* dev)
{
+ struct msi_desc *entry;
+
if (!pci_msi_enable || !dev || !dev->msix_enabled)
return;
+ /* Return the device with MSI-X masked as initial states */
+ list_for_each_entry(entry, &dev->msi_list, list) {
+ /* Keep cached states to be restored */
+ __msix_mask_irq(entry, 1);
+ }
+
msix_set_enable(dev, 0);
pci_intx_for_msi(dev, 1);
dev->msix_enabled = 0;
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index a066284..de27c1c 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -6,11 +6,11 @@
#ifndef MSI_H
#define MSI_H
-#define PCI_MSIX_ENTRY_SIZE 16
-#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0
-#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4
-#define PCI_MSIX_ENTRY_DATA_OFFSET 8
-#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12
+#define PCI_MSIX_ENTRY_SIZE 16
+#define PCI_MSIX_ENTRY_LOWER_ADDR 0
+#define PCI_MSIX_ENTRY_UPPER_ADDR 4
+#define PCI_MSIX_ENTRY_DATA 8
+#define PCI_MSIX_ENTRY_VECTOR_CTRL 12
#define msi_control_reg(base) (base + PCI_MSI_FLAGS)
#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6c93af5..dbd0f94 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1517,11 +1517,20 @@
*
* Perform INTx swizzling for a device behind one level of bridge. This is
* required by section 9.1 of the PCI-to-PCI bridge specification for devices
- * behind bridges on add-in cards.
+ * behind bridges on add-in cards. For devices with ARI enabled, the slot
+ * number is always 0 (see the Implementation Note in section 2.2.8.1 of
+ * the PCI Express Base Specification, Revision 2.1)
*/
u8 pci_swizzle_interrupt_pin(struct pci_dev *dev, u8 pin)
{
- return (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1;
+ int slot;
+
+ if (pci_ari_enabled(dev->bus))
+ slot = 0;
+ else
+ slot = PCI_SLOT(dev->devfn);
+
+ return (((pin - 1) + slot) % 4) + 1;
}
int
@@ -2171,7 +2180,7 @@
u16 ctrl;
struct pci_dev *pdev;
- if (dev->subordinate)
+ if (pci_is_root_bus(dev->bus) || dev->subordinate || !dev->bus->self)
return -ENOTTY;
list_for_each_entry(pdev, &dev->bus->devices, bus_list)
diff --git a/drivers/pci/pcie/aer/ecrc.c b/drivers/pci/pcie/aer/ecrc.c
index ece97df..a928d8a 100644
--- a/drivers/pci/pcie/aer/ecrc.c
+++ b/drivers/pci/pcie/aer/ecrc.c
@@ -106,7 +106,7 @@
disable_ecrc_checking(dev);
break;
case ECRC_POLICY_ON:
- enable_ecrc_checking(dev);;
+ enable_ecrc_checking(dev);
break;
default:
return;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 56552d7..06b9656 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1058,6 +1058,11 @@
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_ANY_ID, quirk_no_ata_d3);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, PCI_ANY_ID, quirk_no_ata_d3);
+/* ALi loses some register settings that we cannot then restore */
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, PCI_ANY_ID, quirk_no_ata_d3);
+/* VIA comes back fine but we need to keep it alive or ACPI GTM failures
+ occur when mode detecting */
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_no_ata_d3);
/* This was originally an Alpha specific thing, but it really fits here.
* The i82375 PCI/EISA bridge appears as non-classified. Fix that.
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index eddb074..8c02b6c 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -311,7 +311,7 @@
#include <linux/pci_hotplug.h>
/**
* pci_hp_create_link - create symbolic link to the hotplug driver module.
- * @slot: struct pci_slot
+ * @pci_slot: struct pci_slot
*
* Helper function for pci_hotplug_core.c to create symbolic link to
* the hotplug driver module.
@@ -334,7 +334,7 @@
/**
* pci_hp_remove_link - remove symbolic link to the hotplug driver module.
- * @slot: struct pci_slot
+ * @pci_slot: struct pci_slot
*
* Helper function for pci_hotplug_core.c to remove symbolic link to
* the hotplug driver module.
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index 9ad97ea..8eb0423 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -472,7 +472,8 @@
init_timer(&poll_timer);
/* Build interrupt mask */
- printk(", %d sockets\n" KERN_INFO " irq list (", sockets);
+ printk(KERN_CONT ", %d sockets\n", sockets);
+ printk(KERN_INFO " irq list (");
if (irq_list_count == 0)
mask = irq_mask;
else
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 4ac2311..ca50856 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -171,7 +171,7 @@
static int hp_wmi_set_block(void *data, bool blocked)
{
unsigned long b = (unsigned long) data;
- int query = BIT(b + 8) | ((!!blocked) << b);
+ int query = BIT(b + 8) | ((!blocked) << b);
return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query);
}
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 32b2773..713f7bf 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -283,7 +283,7 @@
stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
if (stat < 0)
- return;
+ goto unlock;
if (stat & DS1374_REG_SR_AF) {
stat &= ~DS1374_REG_SR_AF;
@@ -302,7 +302,7 @@
out:
if (!ds1374->exiting)
enable_irq(client->irq);
-
+unlock:
mutex_unlock(&ds1374->mutex);
}
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index 0471f880..4240b05 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -2826,8 +2826,7 @@
*/
local_irq_restore(flags);
- printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully\n"
- KERN_INFO " before abortion\n", HOSTNO);
+ printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully before abortion\n", HOSTNO);
/* Maybe it is sufficient just to release the ST-DMA lock... (if
* possible at all) At least, we should check if the lock could be
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index b12ad7c..18735b3 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -75,8 +75,9 @@
int i;
printk(KERN_DEBUG "mac53c94_queue %p: command is", cmd);
for (i = 0; i < cmd->cmd_len; ++i)
- printk(" %.2x", cmd->cmnd[i]);
- printk("\n" KERN_DEBUG "use_sg=%d request_bufflen=%d request_buffer=%p\n",
+ printk(KERN_CONT " %.2x", cmd->cmnd[i]);
+ printk(KERN_CONT "\n");
+ printk(KERN_DEBUG "use_sg=%d request_bufflen=%d request_buffer=%p\n",
scsi_sg_count(cmd), scsi_bufflen(cmd), scsi_sglist(cmd));
}
#endif
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index ef142fd..4d6f2fe 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -619,7 +619,7 @@
if (strcmp(current->comm, cmd) && printk_ratelimit()) {
printk(KERN_WARNING
"sg_write: data in/out %d/%d bytes for SCSI command 0x%x--"
- "guessing data in;\n" KERN_WARNING " "
+ "guessing data in;\n "
"program %s not setting count and/or reply_len properly\n",
old_hdr.reply_len - (int)SZ_SG_HEADER,
input_size, (unsigned int) cmnd[0],
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index bcaba86..75da6e5 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -2860,8 +2860,7 @@
*/
local_irq_restore(flags);
- printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully\n"
- KERN_INFO " before abortion\n", HOSTNO);
+ printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully before abortion\n", HOSTNO);
return SCSI_ABORT_NOT_RUNNING;
}
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 6160e03..e7108e7 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -60,11 +60,12 @@
static void moan_device(const char *str, struct pci_dev *dev)
{
- printk(KERN_WARNING "%s: %s\n"
- KERN_WARNING "Please send the output of lspci -vv, this\n"
- KERN_WARNING "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n"
- KERN_WARNING "manufacturer and name of serial board or\n"
- KERN_WARNING "modem board to rmk+serial@arm.linux.org.uk.\n",
+ printk(KERN_WARNING
+ "%s: %s\n"
+ "Please send the output of lspci -vv, this\n"
+ "message (0x%04x,0x%04x,0x%04x,0x%04x), the\n"
+ "manufacturer and name of serial board or\n"
+ "modem board to rmk+serial@arm.linux.org.uk.\n",
pci_name(dev), str, dev->vendor, dev->device,
dev->subsystem_vendor, dev->subsystem_device);
}
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 66f5267..8e2feb5 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -707,24 +707,25 @@
static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
{
- unsigned short ssr_status, scr_status;
+ unsigned short ssr_status, scr_status, err_enabled;
struct uart_port *port = ptr;
irqreturn_t ret = IRQ_NONE;
ssr_status = sci_in(port, SCxSR);
scr_status = sci_in(port, SCSCR);
+ err_enabled = scr_status & (SCI_CTRL_FLAGS_REIE | SCI_CTRL_FLAGS_RIE);
/* Tx Interrupt */
- if ((ssr_status & 0x0020) && (scr_status & SCI_CTRL_FLAGS_TIE))
+ if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE))
ret = sci_tx_interrupt(irq, ptr);
/* Rx Interrupt */
- if ((ssr_status & 0x0002) && (scr_status & SCI_CTRL_FLAGS_RIE))
+ if ((ssr_status & SCxSR_RDxF(port)) && (scr_status & SCI_CTRL_FLAGS_RIE))
ret = sci_rx_interrupt(irq, ptr);
/* Error Interrupt */
- if ((ssr_status & 0x0080) && (scr_status & SCI_CTRL_FLAGS_REIE))
+ if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled)
ret = sci_er_interrupt(irq, ptr);
/* Break Interrupt */
- if ((ssr_status & 0x0010) && (scr_status & SCI_CTRL_FLAGS_REIE))
+ if ((ssr_status & SCxSR_BRK(port)) && err_enabled)
ret = sci_br_interrupt(irq, ptr);
return ret;
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index fbfadba..100e7a5 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -583,7 +583,7 @@
ssb_printk(".");
err = ssb_pcmcia_sprom_write(bus, i, sprom[i]);
if (err) {
- ssb_printk("\n" KERN_NOTICE PFX
+ ssb_printk(KERN_NOTICE PFX
"Failed to write to SPROM.\n");
failed = 1;
break;
@@ -591,7 +591,7 @@
}
err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS);
if (err) {
- ssb_printk("\n" KERN_NOTICE PFX
+ ssb_printk(KERN_NOTICE PFX
"Could not disable SPROM write access.\n");
failed = 1;
}
@@ -678,7 +678,8 @@
sprom->board_rev = tuple.TupleData[1];
break;
case SSB_PCMCIA_CIS_PA:
- GOTO_ERROR_ON(tuple.TupleDataLen != 9,
+ GOTO_ERROR_ON((tuple.TupleDataLen != 9) &&
+ (tuple.TupleDataLen != 10),
"pa tpl size");
sprom->pa0b0 = tuple.TupleData[1] |
((u16)tuple.TupleData[2] << 8);
@@ -718,7 +719,8 @@
sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1];
break;
case SSB_PCMCIA_CIS_BFLAGS:
- GOTO_ERROR_ON(tuple.TupleDataLen != 3,
+ GOTO_ERROR_ON((tuple.TupleDataLen != 3) &&
+ (tuple.TupleDataLen != 5),
"bfl tpl size");
sprom->boardflags_lo = tuple.TupleData[1] |
((u16)tuple.TupleData[2] << 8);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index ce3f453..95ccfa0 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -648,7 +648,7 @@
struct urb *urb;
int length;
unsigned long flags;
- char buffer[4]; /* Any root hubs with > 31 ports? */
+ char buffer[6]; /* Any root hubs with > 31 ports? */
if (unlikely(!hcd->rh_registered))
return;
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 1576a05..0c03471 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -337,10 +337,10 @@
config SUPERH_ON_CHIP_R8A66597
boolean "Enable SuperH on-chip R8A66597 USB"
- depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723)
+ depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7724)
help
This driver enables support for the on-chip R8A66597 in the
- SH7366 and SH7723 processors.
+ SH7366, SH7723 and SH7724 processors.
config USB_WHCI_HCD
tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index f8d9045..0f7a30b 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -1261,7 +1261,7 @@
return -ENOMEM;
}
map[n].ptr = (unsigned char *) vaddr;
- map[n].pg = virt_to_page(vaddr);
+ map[n].pg = virt_to_page((void *) vaddr);
}
return 0;
}
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index fb8163d..a21efcd 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -226,9 +226,10 @@
clcdfb_enable(fb, regs.cntl);
#ifdef DEBUG
- printk(KERN_INFO "CLCD: Registers set to\n"
- KERN_INFO " %08x %08x %08x %08x\n"
- KERN_INFO " %08x %08x %08x %08x\n",
+ printk(KERN_INFO
+ "CLCD: Registers set to\n"
+ " %08x %08x %08x %08x\n"
+ " %08x %08x %08x %08x\n",
readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1),
readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3),
readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS),
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 497ff8a..8cd279b 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -2405,6 +2405,9 @@
return 0;
}
+/* fbhw->encode_fix() must be called with fb_info->mm_lock held
+ * if it is called after the register_framebuffer() - not a case here
+ */
static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
{
struct atafb_par par;
@@ -2414,9 +2417,7 @@
if (err)
return err;
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- mutex_lock(&info->mm_lock);
err = fbhw->encode_fix(fix, &par);
- mutex_unlock(&info->mm_lock);
return err;
}
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index cb88394..da05f08 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -261,6 +261,9 @@
/**
* atmel_lcdfb_alloc_video_memory - Allocate framebuffer memory
* @sinfo: the frame buffer to allocate memory for
+ *
+ * This function is called only from the atmel_lcdfb_probe()
+ * so no locking by fb_info->mm_lock around smem_len setting is needed.
*/
static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo)
{
@@ -270,9 +273,7 @@
smem_len = (var->xres_virtual * var->yres_virtual
* ((var->bits_per_pixel + 7) / 8));
- mutex_lock(&info->mm_lock);
info->fix.smem_len = max(smem_len, sinfo->smem_len);
- mutex_unlock(&info->mm_lock);
info->screen_base = dma_alloc_writecombine(info->device, info->fix.smem_len,
(dma_addr_t *)&info->fix.smem_start, GFP_KERNEL);
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 0bf2190..72d68b3 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -1223,12 +1223,6 @@
return -EINVAL;
}
- if (fsl_diu_set_par(info)) {
- printk(KERN_ERR "fb_set_par failed");
- fb_dealloc_cmap(&info->cmap);
- return -EINVAL;
- }
-
if (register_framebuffer(info) < 0) {
printk(KERN_ERR "register_framebuffer failed");
unmap_video_memory(info);
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c
index 020db7f..e7116a6 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/hitfb.c
@@ -44,9 +44,6 @@
.accel = FB_ACCEL_NONE,
};
-static u32 pseudo_palette[16];
-static struct fb_info fb_info;
-
static inline void hitfb_accel_wait(void)
{
while (fb_readw(HD64461_GRCFGR) & HD64461_GRCFGR_ACCSTATUS) ;
@@ -331,6 +328,8 @@
static int __init hitfb_probe(struct platform_device *dev)
{
unsigned short lcdclor, ldr3, ldvndr;
+ struct fb_info *info;
+ int ret;
if (fb_get_options("hitfb", NULL))
return -ENODEV;
@@ -384,32 +383,53 @@
break;
}
- fb_info.fbops = &hitfb_ops;
- fb_info.var = hitfb_var;
- fb_info.fix = hitfb_fix;
- fb_info.pseudo_palette = pseudo_palette;
- fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
+ info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
+ if (unlikely(!info))
+ return -ENOMEM;
+
+ info->fbops = &hitfb_ops;
+ info->var = hitfb_var;
+ info->fix = hitfb_fix;
+ info->pseudo_palette = info->par;
+ info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA;
- fb_info.screen_base = (void *)hitfb_fix.smem_start;
+ info->screen_base = (void *)hitfb_fix.smem_start;
- fb_alloc_cmap(&fb_info.cmap, 256, 0);
+ ret = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (unlikely(ret < 0))
+ goto err_fb;
- if (register_framebuffer(&fb_info) < 0)
- return -EINVAL;
+ ret = register_framebuffer(info);
+ if (unlikely(ret < 0))
+ goto err;
+
+ platform_set_drvdata(dev, info);
printk(KERN_INFO "fb%d: %s frame buffer device\n",
- fb_info.node, fb_info.fix.id);
+ info->node, info->fix.id);
+
return 0;
+
+err:
+ fb_dealloc_cmap(&info->cmap);
+err_fb:
+ framebuffer_release(info);
+ return ret;
}
static int __exit hitfb_remove(struct platform_device *dev)
{
- return unregister_framebuffer(&fb_info);
+ struct fb_info *info = platform_get_drvdata(dev);
+
+ unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
+ framebuffer_release(info);
+
+ return 0;
}
-#ifdef CONFIG_PM
-static int hitfb_suspend(struct platform_device *dev, pm_message_t state)
+static int hitfb_suspend(struct device *dev)
{
u16 v;
@@ -421,7 +441,7 @@
return 0;
}
-static int hitfb_resume(struct platform_device *dev)
+static int hitfb_resume(struct device *dev)
{
u16 v;
@@ -435,17 +455,19 @@
return 0;
}
-#endif
+
+static struct dev_pm_ops hitfb_dev_pm_ops = {
+ .suspend = hitfb_suspend,
+ .resume = hitfb_resume,
+};
static struct platform_driver hitfb_driver = {
.probe = hitfb_probe,
.remove = __exit_p(hitfb_remove),
-#ifdef CONFIG_PM
- .suspend = hitfb_suspend,
- .resume = hitfb_resume,
-#endif
.driver = {
.name = "hitfb",
+ .owner = THIS_MODULE,
+ .pm = &hitfb_dev_pm_ops,
},
};
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 7196067..5743ea2 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -2060,8 +2060,7 @@
fb_var_to_videomode(&mode, &info->var);
fb_add_videomode(&mode, &info->modelist);
- encode_fix(&info->fix, info);
-
+
i810fb_init_ringbuffer(info);
err = register_framebuffer(info);
diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c
index 0ce3b0a..a74e5da 100644
--- a/drivers/video/matrox/matroxfb_DAC1064.c
+++ b/drivers/video/matrox/matroxfb_DAC1064.c
@@ -454,9 +454,9 @@
dprintk(KERN_DEBUG "DAC1064regs ");
for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], ACCESS_FBINFO(hw).DACreg[i]);
- if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
+ if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... ");
}
- dprintk("\n" KERN_DEBUG "DAC1064clk ");
+ dprintk(KERN_DEBUG "DAC1064clk ");
for (i = 0; i < 6; i++)
dprintk("C%02X=%02X ", i, ACCESS_FBINFO(hw).DACclk[i]);
dprintk("\n");
diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/matrox/matroxfb_Ti3026.c
index 1352482..4e82511 100644
--- a/drivers/video/matrox/matroxfb_Ti3026.c
+++ b/drivers/video/matrox/matroxfb_Ti3026.c
@@ -651,9 +651,9 @@
dprintk(KERN_DEBUG "3026DACregs ");
for (i = 0; i < 21; i++) {
dprintk("R%02X=%02X ", DACseq[i], hw->DACreg[i]);
- if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
+ if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... ");
}
- dprintk("\n" KERN_DEBUG "DACclk ");
+ dprintk(KERN_DEBUG "DACclk ");
for (i = 0; i < 6; i++)
dprintk("C%02X=%02X ", i, hw->DACclk[i]);
dprintk("\n");
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 59c3a2e..0c1049b 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -1876,7 +1876,6 @@
}
matroxfb_init_fix(PMINFO2);
ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase));
- matroxfb_update_fix(PMINFO2);
/* Normalize values (namely yres_virtual) */
matroxfb_check_var(&vesafb_defined, &ACCESS_FBINFO(fbcon));
/* And put it into "current" var. Do NOT program hardware yet, or we'll not take over
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index 909e10a..ebcb5c6 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -289,16 +289,18 @@
#undef m2info
}
+/*
+ * This function is called before the register_framebuffer so
+ * no locking is needed.
+ */
static void matroxfb_dh_init_fix(struct matroxfb_dh_fb_info *m2info)
{
struct fb_fix_screeninfo *fix = &m2info->fbcon.fix;
strcpy(fix->id, "MATROX DH");
- mutex_lock(&m2info->fbcon.mm_lock);
fix->smem_start = m2info->video.base;
fix->smem_len = m2info->video.len_usable;
- mutex_unlock(&m2info->fbcon.mm_lock);
fix->ypanstep = 1;
fix->ywrapstep = 0;
fix->xpanstep = 8; /* TBD */
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index 567fb94..f8778cd 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -1365,11 +1365,6 @@
init_completion(&mx3fbi->flip_cmpl);
disable_irq(ichan->eof_irq);
dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq);
- ret = mx3fb_set_par(fbi);
- if (ret < 0)
- goto esetpar;
-
- mx3fb_blank(FB_BLANK_UNBLANK, fbi);
dev_info(dev, "registered, using mode %s\n", fb_mode);
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 43680e5..bb63c07 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -211,23 +211,21 @@
/**
* s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock.
+ * @id: window id.
* @sfb: The hardware state.
* @pixclock: The pixel clock wanted, in picoseconds.
*
* Given the specified pixel clock, work out the necessary divider to get
* close to the output frequency.
*/
-static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk)
+static int s3c_fb_calc_pixclk(unsigned char id, struct s3c_fb *sfb, unsigned int pixclk)
{
+ struct s3c_fb_pd_win *win = sfb->pdata->win[id];
unsigned long clk = clk_get_rate(sfb->bus_clk);
- unsigned long long tmp;
unsigned int result;
- tmp = (unsigned long long)clk;
- tmp *= pixclk;
-
- do_div(tmp, 1000000000UL);
- result = (unsigned int)tmp / 1000;
+ pixclk *= win->win_mode.refresh;
+ result = clk / pixclk;
dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n",
pixclk, clk, result, clk / result);
@@ -267,6 +265,7 @@
struct s3c_fb *sfb = win->parent;
void __iomem *regs = sfb->regs;
int win_no = win->index;
+ u32 osdc_data = 0;
u32 data;
u32 pagewidth;
int clkdiv;
@@ -302,7 +301,7 @@
/* use window 0 as the basis for the lcd output timings */
if (win_no == 0) {
- clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock);
+ clkdiv = s3c_fb_calc_pixclk(win_no, sfb, var->pixclock);
data = sfb->pdata->vidcon0;
data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR);
@@ -359,8 +358,6 @@
data = var->xres * var->yres;
- u32 osdc_data = 0;
-
osdc_data = VIDISD14C_ALPHA1_R(0xf) |
VIDISD14C_ALPHA1_G(0xf) |
VIDISD14C_ALPHA1_B(0xf);
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index da983b7..8f24564 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -31,7 +31,7 @@
unsigned long enabled; /* ME and SE in LDCNT2R */
struct sh_mobile_lcdc_chan_cfg cfg;
u32 pseudo_palette[PALETTE_NR];
- struct fb_info info;
+ struct fb_info *info;
dma_addr_t dma_handle;
struct fb_deferred_io defio;
struct scatterlist *sglist;
@@ -442,22 +442,22 @@
/* set bpp format in PKF[4:0] */
tmp = lcdc_read_chan(ch, LDDFR);
tmp &= ~(0x0001001f);
- tmp |= (priv->ch[k].info.var.bits_per_pixel == 16) ? 3 : 0;
+ tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0;
lcdc_write_chan(ch, LDDFR, tmp);
/* point out our frame buffer */
- lcdc_write_chan(ch, LDSA1R, ch->info.fix.smem_start);
+ lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start);
/* set line size */
- lcdc_write_chan(ch, LDMLSR, ch->info.fix.line_length);
+ lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length);
/* setup deferred io if SYS bus */
tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
if (ch->ldmt1r_value & (1 << 12) && tmp) {
ch->defio.deferred_io = sh_mobile_lcdc_deferred_io;
ch->defio.delay = msecs_to_jiffies(tmp);
- ch->info.fbdefio = &ch->defio;
- fb_deferred_io_init(&ch->info);
+ ch->info->fbdefio = &ch->defio;
+ fb_deferred_io_init(ch->info);
/* one-shot mode */
lcdc_write_chan(ch, LDSM1R, 1);
@@ -503,12 +503,12 @@
* flush frame, and wait for frame end interrupt
* clean up deferred io and enable clock
*/
- if (ch->info.fbdefio) {
+ if (ch->info->fbdefio) {
ch->frame_end = 0;
- schedule_delayed_work(&ch->info.deferred_work, 0);
+ schedule_delayed_work(&ch->info->deferred_work, 0);
wait_event(ch->frame_end_wait, ch->frame_end);
- fb_deferred_io_cleanup(&ch->info);
- ch->info.fbdefio = NULL;
+ fb_deferred_io_cleanup(ch->info);
+ ch->info->fbdefio = NULL;
sh_mobile_lcdc_clk_on(priv);
}
@@ -817,9 +817,16 @@
priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1);
for (i = 0; i < j; i++) {
- info = &priv->ch[i].info;
cfg = &priv->ch[i].cfg;
+ priv->ch[i].info = framebuffer_alloc(0, &pdev->dev);
+ if (!priv->ch[i].info) {
+ dev_err(&pdev->dev, "unable to allocate fb_info\n");
+ error = -ENOMEM;
+ break;
+ }
+
+ info = priv->ch[i].info;
info->fbops = &sh_mobile_lcdc_ops;
info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres;
info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres;
@@ -872,7 +879,7 @@
for (i = 0; i < j; i++) {
struct sh_mobile_lcdc_chan *ch = priv->ch + i;
- info = &ch->info;
+ info = ch->info;
if (info->fbdefio) {
priv->ch->sglist = vmalloc(sizeof(struct scatterlist) *
@@ -915,15 +922,15 @@
int i;
for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
- if (priv->ch[i].info.dev)
- unregister_framebuffer(&priv->ch[i].info);
+ if (priv->ch[i].info->dev)
+ unregister_framebuffer(priv->ch[i].info);
sh_mobile_lcdc_stop(priv);
for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
- info = &priv->ch[i].info;
+ info = priv->ch[i].info;
- if (!info->device)
+ if (!info || !info->device)
continue;
if (priv->ch[i].sglist)
@@ -932,6 +939,7 @@
dma_free_coherent(&pdev->dev, info->fix.smem_len,
info->screen_base, priv->ch[i].dma_handle);
fb_dealloc_cmap(&info->cmap);
+ framebuffer_release(info);
}
#ifdef CONFIG_HAVE_CLK
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index fd33455..4a067f0 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -6367,7 +6367,6 @@
sis_fb_info->fix = ivideo->sisfb_fix;
sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset;
sis_fb_info->fbops = &sisfb_ops;
- sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info);
sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 16d4f4c..924d794 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -1540,9 +1540,6 @@
if (ret)
dev_err(info->dev, "check_var() failed on initial setup?\n");
- /* ensure we've activated our new configuration */
- (fb->fbops->fb_set_par)(fb);
-
return 0;
}
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index eec9dcb..6120f0c 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1115,10 +1115,9 @@
if the device name contains the string "DX" and tell the
user how to reconfigure the card. */
if (strstr(sti->outptr.dev_name, "DX")) {
- printk(KERN_WARNING "WARNING: stifb framebuffer driver does not "
- "support '%s' in double-buffer mode.\n"
- KERN_WARNING "WARNING: Please disable the double-buffer mode "
- "in IPL menu (the PARISC-BIOS).\n",
+ printk(KERN_WARNING
+"WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n"
+"WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n",
sti->outptr.dev_name);
goto out_err0;
}
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 8a141c2..2376f68 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -748,8 +748,6 @@
goto out;
}
- w100fb_set_par(info);
-
if (register_framebuffer(info) < 0) {
err = -EINVAL;
goto out;
diff --git a/drivers/vlynq/Kconfig b/drivers/vlynq/Kconfig
index f654221..a9efb16 100644
--- a/drivers/vlynq/Kconfig
+++ b/drivers/vlynq/Kconfig
@@ -13,7 +13,7 @@
config VLYNQ_DEBUG
bool "VLYNQ bus debug"
- depends on VLYNQ && KERNEL_DEBUG
+ depends on VLYNQ && DEBUG_KERNEL
help
Turn on VLYNQ bus debugging.
diff --git a/drivers/vlynq/vlynq.c b/drivers/vlynq/vlynq.c
index 7335433..f05d2a3 100644
--- a/drivers/vlynq/vlynq.c
+++ b/drivers/vlynq/vlynq.c
@@ -76,7 +76,7 @@
u32 int_device[8];
};
-#ifdef VLYNQ_DEBUG
+#ifdef CONFIG_VLYNQ_DEBUG
static void vlynq_dump_regs(struct vlynq_device *dev)
{
int i;
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index 5c7011c..751c003 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -161,7 +161,7 @@
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
- int new_value, retval = -EINVAL;;
+ int new_value, retval = -EINVAL;
switch (cmd) {
case WDIOC_GETSUPPORT:
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c
index ee1caae..0162454 100644
--- a/drivers/watchdog/sa1100_wdt.c
+++ b/drivers/watchdog/sa1100_wdt.c
@@ -38,7 +38,7 @@
static unsigned long oscr_freq;
static unsigned long sa1100wdt_users;
-static int pre_margin;
+static unsigned int pre_margin;
static int boot_status;
/*
@@ -84,6 +84,7 @@
.options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT
| WDIOF_KEEPALIVEPING,
.identity = "SA1100/PXA255 Watchdog",
+ .firmware_version = 1,
};
static long sa1100dog_ioctl(struct file *file, unsigned int cmd,
@@ -118,7 +119,7 @@
if (ret)
break;
- if (time <= 0 || time > 255) {
+ if (time <= 0 || (oscr_freq * (long long)time >= 0xffffffff)) {
ret = -EINVAL;
break;
}
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index 916890a..f201acc 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -89,6 +89,11 @@
c = ((inb_p(WDT_EFDR) & 0xf7) | 0x04); /* select WDT0 */
outb_p(0x2b, WDT_EFER);
outb_p(c, WDT_EFDR); /* set GPIO3 to WDT0 */
+ } else if (c == 0x88) { /* W83627EHF */
+ outb_p(0x2d, WDT_EFER); /* select GPIO5 */
+ c = inb_p(WDT_EFDR) & ~0x01; /* PIN77 -> WDT0# */
+ outb_p(0x2d, WDT_EFER);
+ outb_p(c, WDT_EFDR); /* set GPIO5 to WDT0 */
}
outb_p(0x07, WDT_EFER); /* point to logical device number reg */
diff --git a/drivers/watchdog/w83697ug_wdt.c b/drivers/watchdog/w83697ug_wdt.c
index 883b5f7..a6c12de 100644
--- a/drivers/watchdog/w83697ug_wdt.c
+++ b/drivers/watchdog/w83697ug_wdt.c
@@ -149,8 +149,10 @@
{
spin_lock(&io_lock);
- if (w83697ug_select_wd_register() < 0)
+ if (w83697ug_select_wd_register() < 0) {
+ spin_unlock(&io_lock);
return;
+ }
outb_p(0xF4, WDT_EFER); /* Select CRF4 */
outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF4 */
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 891d2e9..abad71b 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -927,9 +927,9 @@
void __init xen_init_IRQ(void)
{
int i;
- size_t size = nr_cpu_ids * sizeof(struct cpu_evtchn_s);
- cpu_evtchn_mask_p = alloc_bootmem(size);
+ cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s),
+ GFP_KERNEL);
BUG_ON(cpu_evtchn_mask_p == NULL);
init_evtchn_cpu_bindings();
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index c52be53..5ffb570 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -17,7 +17,6 @@
#include <linux/pagemap.h>
#include <linux/mount.h>
#include <linux/namei.h>
-#include <linux/mnt_namespace.h>
#include "internal.h"
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 3a9b7a5..92888aa 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -5,7 +5,11 @@
on by default if server supports it). Add forceuid and forcegid
mount options (so that when negotiating unix extensions specifying
which uid mounted does not immediately force the server's reported
-uids to be overridden). Add support for scope moutn parm.
+uids to be overridden). Add support for scope mount parm. Improve
+hard link detection to use same inode for both. Do not set
+read-only dos attribute on directories (for chmod) since Windows
+explorer special cases this attribute bit for directories for
+a different purpose.
Version 1.58
------------
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index 4a4581c..051caec 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -86,6 +86,9 @@
/* strlen of ";user=" */
#define USER_KEY_LEN 6
+/* strlen of ";pid=0x" */
+#define PID_KEY_LEN 7
+
/* get a key struct with a SPNEGO security blob, suitable for session setup */
struct key *
cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
@@ -103,7 +106,8 @@
IP_KEY_LEN + INET6_ADDRSTRLEN +
MAX_MECH_STR_LEN +
UID_KEY_LEN + (sizeof(uid_t) * 2) +
- USER_KEY_LEN + strlen(sesInfo->userName) + 1;
+ USER_KEY_LEN + strlen(sesInfo->userName) +
+ PID_KEY_LEN + (sizeof(pid_t) * 2) + 1;
spnego_key = ERR_PTR(-ENOMEM);
description = kzalloc(desc_len, GFP_KERNEL);
@@ -141,6 +145,9 @@
dp = description + strlen(description);
sprintf(dp, ";user=%s", sesInfo->userName);
+ dp = description + strlen(description);
+ sprintf(dp, ";pid=0x%x", current->pid);
+
cFYI(1, ("key description = %s", description));
spnego_key = request_key(&cifs_spnego_key_type, description, "");
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 1403b5d..6941c22 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -327,7 +327,7 @@
static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
- struct inode *inode)
+ struct cifs_fattr *fattr)
{
int i;
int num_aces = 0;
@@ -340,7 +340,7 @@
if (!pdacl) {
/* no DACL in the security descriptor, set
all the permissions for user/group/other */
- inode->i_mode |= S_IRWXUGO;
+ fattr->cf_mode |= S_IRWXUGO;
return;
}
@@ -357,7 +357,7 @@
/* reset rwx permissions for user/group/other.
Also, if num_aces is 0 i.e. DACL has no ACEs,
user/group/other have no permissions */
- inode->i_mode &= ~(S_IRWXUGO);
+ fattr->cf_mode &= ~(S_IRWXUGO);
acl_base = (char *)pdacl;
acl_size = sizeof(struct cifs_acl);
@@ -379,17 +379,17 @@
if (compare_sids(&(ppace[i]->sid), pownersid))
access_flags_to_mode(ppace[i]->access_req,
ppace[i]->type,
- &(inode->i_mode),
+ &fattr->cf_mode,
&user_mask);
if (compare_sids(&(ppace[i]->sid), pgrpsid))
access_flags_to_mode(ppace[i]->access_req,
ppace[i]->type,
- &(inode->i_mode),
+ &fattr->cf_mode,
&group_mask);
if (compare_sids(&(ppace[i]->sid), &sid_everyone))
access_flags_to_mode(ppace[i]->access_req,
ppace[i]->type,
- &(inode->i_mode),
+ &fattr->cf_mode,
&other_mask);
/* memcpy((void *)(&(cifscred->aces[i])),
@@ -464,7 +464,7 @@
/* Convert CIFS ACL to POSIX form */
static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
- struct inode *inode)
+ struct cifs_fattr *fattr)
{
int rc;
struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
@@ -472,7 +472,7 @@
char *end_of_acl = ((char *)pntsd) + acl_len;
__u32 dacloffset;
- if ((inode == NULL) || (pntsd == NULL))
+ if (pntsd == NULL)
return -EIO;
owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
@@ -497,7 +497,7 @@
if (dacloffset)
parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
- group_sid_ptr, inode);
+ group_sid_ptr, fattr);
else
cFYI(1, ("no ACL")); /* BB grant all or default perms? */
@@ -508,7 +508,6 @@
memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
sizeof(struct cifs_sid)); */
-
return 0;
}
@@ -671,8 +670,9 @@
}
/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
-void acl_to_uid_mode(struct cifs_sb_info *cifs_sb, struct inode *inode,
- const char *path, const __u16 *pfid)
+void
+cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
+ struct inode *inode, const char *path, const __u16 *pfid)
{
struct cifs_ntsd *pntsd = NULL;
u32 acllen = 0;
@@ -687,7 +687,7 @@
/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
if (pntsd)
- rc = parse_sec_desc(pntsd, acllen, inode);
+ rc = parse_sec_desc(pntsd, acllen, fattr);
if (rc)
cFYI(1, ("parse sec desc failed rc = %d", rc));
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 9f669f9..44f3050 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -308,7 +308,6 @@
if (!cifs_inode)
return NULL;
cifs_inode->cifsAttrs = 0x20; /* default */
- atomic_set(&cifs_inode->inUse, 0);
cifs_inode->time = 0;
cifs_inode->write_behind_rc = 0;
/* Until the file is open and we have gotten oplock
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 9570a0e..6c17094 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -24,6 +24,19 @@
#define ROOT_I 2
+/*
+ * ino_t is 32-bits on 32-bit arch. We have to squash the 64-bit value down
+ * so that it will fit.
+ */
+static inline ino_t
+cifs_uniqueid_to_ino_t(u64 fileid)
+{
+ ino_t ino = (ino_t) fileid;
+ if (sizeof(ino_t) < sizeof(u64))
+ ino ^= fileid >> (sizeof(u64)-sizeof(ino_t)) * 8;
+ return ino;
+}
+
extern struct file_system_type cifs_fs_type;
extern const struct address_space_operations cifs_addr_ops;
extern const struct address_space_operations cifs_addr_ops_smallbuf;
@@ -100,5 +113,5 @@
extern const struct export_operations cifs_export_ops;
#endif /* EXPERIMENTAL */
-#define CIFS_VERSION "1.59"
+#define CIFS_VERSION "1.60"
#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index e1225e6..63f6cdf 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -364,13 +364,13 @@
struct list_head openFileList;
int write_behind_rc;
__u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
- atomic_t inUse; /* num concurrent users (local openers cifs) of file*/
unsigned long time; /* jiffies of last update/check of inode */
bool clientCanCacheRead:1; /* read oplock */
bool clientCanCacheAll:1; /* read and writebehind oplock */
bool oplockPending:1;
bool delete_pending:1; /* DELETE_ON_CLOSE is set */
u64 server_eof; /* current file size on server */
+ u64 uniqueid; /* server inode number */
struct inode vfs_inode;
};
@@ -472,6 +472,32 @@
char *node_name;
};
+/*
+ * common struct for holding inode info when searching for or updating an
+ * inode with new info
+ */
+
+#define CIFS_FATTR_DFS_REFERRAL 0x1
+#define CIFS_FATTR_DELETE_PENDING 0x2
+#define CIFS_FATTR_NEED_REVAL 0x4
+
+struct cifs_fattr {
+ u32 cf_flags;
+ u32 cf_cifsattrs;
+ u64 cf_uniqueid;
+ u64 cf_eof;
+ u64 cf_bytes;
+ uid_t cf_uid;
+ gid_t cf_gid;
+ umode_t cf_mode;
+ dev_t cf_rdev;
+ unsigned int cf_nlink;
+ unsigned int cf_dtype;
+ struct timespec cf_atime;
+ struct timespec cf_mtime;
+ struct timespec cf_ctime;
+};
+
static inline void free_dfs_info_param(struct dfs_info3_param *param)
{
if (param) {
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index a785f69..2d07f89 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -2328,19 +2328,7 @@
typedef struct {
__le32 NextEntryOffset;
__u32 ResumeKey; /* as with FileIndex - no need to convert */
- __le64 EndOfFile;
- __le64 NumOfBytes;
- __le64 LastStatusChange; /*SNIA specs DCE time for the 3 time fields */
- __le64 LastAccessTime;
- __le64 LastModificationTime;
- __le64 Uid;
- __le64 Gid;
- __le32 Type;
- __le64 DevMajor;
- __le64 DevMinor;
- __le64 UniqueId;
- __le64 Permissions;
- __le64 Nlinks;
+ FILE_UNIX_BASIC_INFO basic;
char FileName[1];
} __attribute__((packed)) FILE_UNIX_INFO; /* level 0x202 */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index c419416..da8fbf5 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -98,9 +98,13 @@
extern int cifs_posix_open(char *full_path, struct inode **pinode,
struct super_block *sb, int mode, int oflags,
int *poplock, __u16 *pnetfid, int xid);
-extern void posix_fill_in_inode(struct inode *tmp_inode,
- FILE_UNIX_BASIC_INFO *pData, int isNewInode);
-extern struct inode *cifs_new_inode(struct super_block *sb, __u64 *inum);
+extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
+ FILE_UNIX_BASIC_INFO *info,
+ struct cifs_sb_info *cifs_sb);
+extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
+extern struct inode *cifs_iget(struct super_block *sb,
+ struct cifs_fattr *fattr);
+
extern int cifs_get_inode_info(struct inode **pinode,
const unsigned char *search_path,
FILE_ALL_INFO *pfile_info,
@@ -108,8 +112,9 @@
extern int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path,
struct super_block *sb, int xid);
-extern void acl_to_uid_mode(struct cifs_sb_info *cifs_sb, struct inode *inode,
- const char *path, const __u16 *pfid);
+extern void cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
+ struct cifs_fattr *fattr, struct inode *inode,
+ const char *path, const __u16 *pfid);
extern int mode_to_acl(struct inode *inode, const char *path, __u64);
extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
@@ -215,7 +220,11 @@
dev_t device;
};
-extern int CIFSSMBUnixSetInfo(const int xid, struct cifsTconInfo *pTcon,
+extern int CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
+ const struct cifs_unix_set_info_args *args,
+ u16 fid, u32 pid_of_opener);
+
+extern int CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *pTcon,
char *fileName,
const struct cifs_unix_set_info_args *args,
const struct nls_table *nls_codepage,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 61007c6..922f5fe 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -5074,10 +5074,114 @@
}
#endif /* temporarily unneeded SetAttr legacy function */
+static void
+cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
+ const struct cifs_unix_set_info_args *args)
+{
+ u64 mode = args->mode;
+
+ /*
+ * Samba server ignores set of file size to zero due to bugs in some
+ * older clients, but we should be precise - we use SetFileSize to
+ * set file size and do not want to truncate file size to zero
+ * accidently as happened on one Samba server beta by putting
+ * zero instead of -1 here
+ */
+ data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
+ data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
+ data_offset->LastStatusChange = cpu_to_le64(args->ctime);
+ data_offset->LastAccessTime = cpu_to_le64(args->atime);
+ data_offset->LastModificationTime = cpu_to_le64(args->mtime);
+ data_offset->Uid = cpu_to_le64(args->uid);
+ data_offset->Gid = cpu_to_le64(args->gid);
+ /* better to leave device as zero when it is */
+ data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
+ data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
+ data_offset->Permissions = cpu_to_le64(mode);
+
+ if (S_ISREG(mode))
+ data_offset->Type = cpu_to_le32(UNIX_FILE);
+ else if (S_ISDIR(mode))
+ data_offset->Type = cpu_to_le32(UNIX_DIR);
+ else if (S_ISLNK(mode))
+ data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
+ else if (S_ISCHR(mode))
+ data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
+ else if (S_ISBLK(mode))
+ data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
+ else if (S_ISFIFO(mode))
+ data_offset->Type = cpu_to_le32(UNIX_FIFO);
+ else if (S_ISSOCK(mode))
+ data_offset->Type = cpu_to_le32(UNIX_SOCKET);
+}
+
int
-CIFSSMBUnixSetInfo(const int xid, struct cifsTconInfo *tcon, char *fileName,
- const struct cifs_unix_set_info_args *args,
- const struct nls_table *nls_codepage, int remap)
+CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
+ const struct cifs_unix_set_info_args *args,
+ u16 fid, u32 pid_of_opener)
+{
+ struct smb_com_transaction2_sfi_req *pSMB = NULL;
+ FILE_UNIX_BASIC_INFO *data_offset;
+ int rc = 0;
+ u16 params, param_offset, offset, byte_count, count;
+
+ cFYI(1, ("Set Unix Info (via SetFileInfo)"));
+ rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
+
+ if (rc)
+ return rc;
+
+ pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
+ pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
+
+ params = 6;
+ pSMB->MaxSetupCount = 0;
+ pSMB->Reserved = 0;
+ pSMB->Flags = 0;
+ pSMB->Timeout = 0;
+ pSMB->Reserved2 = 0;
+ param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
+ offset = param_offset + params;
+
+ data_offset = (FILE_UNIX_BASIC_INFO *)
+ ((char *)(&pSMB->hdr.Protocol) + offset);
+ count = sizeof(FILE_UNIX_BASIC_INFO);
+
+ pSMB->MaxParameterCount = cpu_to_le16(2);
+ /* BB find max SMB PDU from sess */
+ pSMB->MaxDataCount = cpu_to_le16(1000);
+ pSMB->SetupCount = 1;
+ pSMB->Reserved3 = 0;
+ pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
+ byte_count = 3 /* pad */ + params + count;
+ pSMB->DataCount = cpu_to_le16(count);
+ pSMB->ParameterCount = cpu_to_le16(params);
+ pSMB->TotalDataCount = pSMB->DataCount;
+ pSMB->TotalParameterCount = pSMB->ParameterCount;
+ pSMB->ParameterOffset = cpu_to_le16(param_offset);
+ pSMB->DataOffset = cpu_to_le16(offset);
+ pSMB->Fid = fid;
+ pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
+ pSMB->Reserved4 = 0;
+ pSMB->hdr.smb_buf_length += byte_count;
+ pSMB->ByteCount = cpu_to_le16(byte_count);
+
+ cifs_fill_unix_set_info(data_offset, args);
+
+ rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
+ if (rc)
+ cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
+
+ /* Note: On -EAGAIN error only caller can retry on handle based calls
+ since file handle passed in no longer valid */
+
+ return rc;
+}
+
+int
+CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName,
+ const struct cifs_unix_set_info_args *args,
+ const struct nls_table *nls_codepage, int remap)
{
TRANSACTION2_SPI_REQ *pSMB = NULL;
TRANSACTION2_SPI_RSP *pSMBr = NULL;
@@ -5086,7 +5190,6 @@
int bytes_returned = 0;
FILE_UNIX_BASIC_INFO *data_offset;
__u16 params, param_offset, offset, count, byte_count;
- __u64 mode = args->mode;
cFYI(1, ("In SetUID/GID/Mode"));
setPermsRetry:
@@ -5137,38 +5240,8 @@
pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
pSMB->Reserved4 = 0;
pSMB->hdr.smb_buf_length += byte_count;
- /* Samba server ignores set of file size to zero due to bugs in some
- older clients, but we should be precise - we use SetFileSize to
- set file size and do not want to truncate file size to zero
- accidently as happened on one Samba server beta by putting
- zero instead of -1 here */
- data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
- data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
- data_offset->LastStatusChange = cpu_to_le64(args->ctime);
- data_offset->LastAccessTime = cpu_to_le64(args->atime);
- data_offset->LastModificationTime = cpu_to_le64(args->mtime);
- data_offset->Uid = cpu_to_le64(args->uid);
- data_offset->Gid = cpu_to_le64(args->gid);
- /* better to leave device as zero when it is */
- data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
- data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
- data_offset->Permissions = cpu_to_le64(mode);
- if (S_ISREG(mode))
- data_offset->Type = cpu_to_le32(UNIX_FILE);
- else if (S_ISDIR(mode))
- data_offset->Type = cpu_to_le32(UNIX_DIR);
- else if (S_ISLNK(mode))
- data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
- else if (S_ISCHR(mode))
- data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
- else if (S_ISBLK(mode))
- data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
- else if (S_ISFIFO(mode))
- data_offset->Type = cpu_to_le32(UNIX_FIFO);
- else if (S_ISSOCK(mode))
- data_offset->Type = cpu_to_le32(UNIX_SOCKET);
-
+ cifs_fill_unix_set_info(data_offset, args);
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 7dc6b74..4326ffd 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -188,6 +188,7 @@
FILE_UNIX_BASIC_INFO *presp_data;
__u32 posix_flags = 0;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ struct cifs_fattr fattr;
cFYI(1, ("posix open %s", full_path));
@@ -236,22 +237,21 @@
if (presp_data->Type == cpu_to_le32(-1))
goto posix_open_ret; /* open ok, caller does qpathinfo */
- /* get new inode and set it up */
if (!pinode)
goto posix_open_ret; /* caller does not need info */
+ cifs_unix_basic_to_fattr(&fattr, presp_data, cifs_sb);
+
+ /* get new inode and set it up */
if (*pinode == NULL) {
- __u64 unique_id = le64_to_cpu(presp_data->UniqueId);
- *pinode = cifs_new_inode(sb, &unique_id);
+ *pinode = cifs_iget(sb, &fattr);
+ if (!*pinode) {
+ rc = -ENOMEM;
+ goto posix_open_ret;
+ }
+ } else {
+ cifs_fattr_to_inode(*pinode, &fattr);
}
- /* else an inode was passed in. Update its info, don't create one */
-
- /* We do not need to close the file if new_inode fails since
- the caller will retry qpathinfo as long as inode is null */
- if (*pinode == NULL)
- goto posix_open_ret;
-
- posix_fill_in_inode(*pinode, presp_data, 1);
cifs_fill_fileinfo(*pinode, *pnetfid, cifs_sb->tcon, write_only);
@@ -425,9 +425,10 @@
args.uid = NO_CHANGE_64;
args.gid = NO_CHANGE_64;
}
- CIFSSMBUnixSetInfo(xid, tcon, full_path, &args,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
} else {
/* BB implement mode setting via Windows security
descriptors e.g. */
@@ -515,10 +516,10 @@
args.uid = NO_CHANGE_64;
args.gid = NO_CHANGE_64;
}
- rc = CIFSSMBUnixSetInfo(xid, pTcon, full_path,
- &args, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
+ rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
if (!rc) {
rc = cifs_get_inode_info_unix(&newinode, full_path,
@@ -643,6 +644,15 @@
}
}
+ /*
+ * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
+ * the VFS handle the create.
+ */
+ if (nd->flags & LOOKUP_EXCL) {
+ d_instantiate(direntry, NULL);
+ return 0;
+ }
+
/* can not grab the rename sem here since it would
deadlock in the cases (beginning of sys_rename itself)
in which we already have the sb rename sem */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 97ce4bf..c34b7f8 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -448,9 +448,9 @@
.mtime = NO_CHANGE_64,
.device = 0,
};
- CIFSSMBUnixSetInfo(xid, tcon, full_path, &args,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
+ CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
}
}
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 155c9e7..18afe57 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -77,239 +77,202 @@
}
}
-static void cifs_unix_info_to_inode(struct inode *inode,
- FILE_UNIX_BASIC_INFO *info, int force_uid_gid)
+/* populate an inode with info from a cifs_fattr struct */
+void
+cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
{
+ struct cifsInodeInfo *cifs_i = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct cifsInodeInfo *cifsInfo = CIFS_I(inode);
- __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes);
- __u64 end_of_file = le64_to_cpu(info->EndOfFile);
+ unsigned long oldtime = cifs_i->time;
- inode->i_atime = cifs_NTtimeToUnix(info->LastAccessTime);
- inode->i_mtime =
- cifs_NTtimeToUnix(info->LastModificationTime);
- inode->i_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
- inode->i_mode = le64_to_cpu(info->Permissions);
+ inode->i_atime = fattr->cf_atime;
+ inode->i_mtime = fattr->cf_mtime;
+ inode->i_ctime = fattr->cf_ctime;
+ inode->i_rdev = fattr->cf_rdev;
+ inode->i_nlink = fattr->cf_nlink;
+ inode->i_uid = fattr->cf_uid;
+ inode->i_gid = fattr->cf_gid;
+
+ /* if dynperm is set, don't clobber existing mode */
+ if (inode->i_state & I_NEW ||
+ !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
+ inode->i_mode = fattr->cf_mode;
+
+ cifs_i->cifsAttrs = fattr->cf_cifsattrs;
+ cifs_i->uniqueid = fattr->cf_uniqueid;
+
+ if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
+ cifs_i->time = 0;
+ else
+ cifs_i->time = jiffies;
+
+ cFYI(1, ("inode 0x%p old_time=%ld new_time=%ld", inode,
+ oldtime, cifs_i->time));
+
+ cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
/*
- * Since we set the inode type below we need to mask off
- * to avoid strange results if bits set above.
+ * Can't safely change the file size here if the client is writing to
+ * it due to potential races.
*/
- inode->i_mode &= ~S_IFMT;
- switch (le32_to_cpu(info->Type)) {
- case UNIX_FILE:
- inode->i_mode |= S_IFREG;
- break;
- case UNIX_SYMLINK:
- inode->i_mode |= S_IFLNK;
- break;
- case UNIX_DIR:
- inode->i_mode |= S_IFDIR;
- break;
- case UNIX_CHARDEV:
- inode->i_mode |= S_IFCHR;
- inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor),
- le64_to_cpu(info->DevMinor) & MINORMASK);
- break;
- case UNIX_BLOCKDEV:
- inode->i_mode |= S_IFBLK;
- inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor),
- le64_to_cpu(info->DevMinor) & MINORMASK);
- break;
- case UNIX_FIFO:
- inode->i_mode |= S_IFIFO;
- break;
- case UNIX_SOCKET:
- inode->i_mode |= S_IFSOCK;
- break;
- default:
- /* safest to call it a file if we do not know */
- inode->i_mode |= S_IFREG;
- cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
- break;
- }
-
- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) &&
- !force_uid_gid)
- inode->i_uid = cifs_sb->mnt_uid;
- else
- inode->i_uid = le64_to_cpu(info->Uid);
-
- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) &&
- !force_uid_gid)
- inode->i_gid = cifs_sb->mnt_gid;
- else
- inode->i_gid = le64_to_cpu(info->Gid);
-
- inode->i_nlink = le64_to_cpu(info->Nlinks);
-
- cifsInfo->server_eof = end_of_file;
spin_lock(&inode->i_lock);
- if (is_size_safe_to_change(cifsInfo, end_of_file)) {
- /*
- * We can not safely change the file size here if the client
- * is writing to it due to potential races.
- */
- i_size_write(inode, end_of_file);
+ if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {
+ i_size_write(inode, fattr->cf_eof);
/*
* i_blocks is not related to (i_size / i_blksize),
* but instead 512 byte (2**9) size is required for
* calculating num blocks.
*/
- inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
+ inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
}
spin_unlock(&inode->i_lock);
+
+ cifs_set_ops(inode, fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL);
}
+/* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
+void
+cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
+ struct cifs_sb_info *cifs_sb)
+{
+ memset(fattr, 0, sizeof(*fattr));
+ fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
+ fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
+ fattr->cf_eof = le64_to_cpu(info->EndOfFile);
+
+ fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
+ fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);
+ fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
+ fattr->cf_mode = le64_to_cpu(info->Permissions);
+
+ /*
+ * Since we set the inode type below we need to mask off
+ * to avoid strange results if bits set above.
+ */
+ fattr->cf_mode &= ~S_IFMT;
+ switch (le32_to_cpu(info->Type)) {
+ case UNIX_FILE:
+ fattr->cf_mode |= S_IFREG;
+ fattr->cf_dtype = DT_REG;
+ break;
+ case UNIX_SYMLINK:
+ fattr->cf_mode |= S_IFLNK;
+ fattr->cf_dtype = DT_LNK;
+ break;
+ case UNIX_DIR:
+ fattr->cf_mode |= S_IFDIR;
+ fattr->cf_dtype = DT_DIR;
+ break;
+ case UNIX_CHARDEV:
+ fattr->cf_mode |= S_IFCHR;
+ fattr->cf_dtype = DT_CHR;
+ fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
+ le64_to_cpu(info->DevMinor) & MINORMASK);
+ break;
+ case UNIX_BLOCKDEV:
+ fattr->cf_mode |= S_IFBLK;
+ fattr->cf_dtype = DT_BLK;
+ fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
+ le64_to_cpu(info->DevMinor) & MINORMASK);
+ break;
+ case UNIX_FIFO:
+ fattr->cf_mode |= S_IFIFO;
+ fattr->cf_dtype = DT_FIFO;
+ break;
+ case UNIX_SOCKET:
+ fattr->cf_mode |= S_IFSOCK;
+ fattr->cf_dtype = DT_SOCK;
+ break;
+ default:
+ /* safest to call it a file if we do not know */
+ fattr->cf_mode |= S_IFREG;
+ fattr->cf_dtype = DT_REG;
+ cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
+ break;
+ }
+
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
+ fattr->cf_uid = cifs_sb->mnt_uid;
+ else
+ fattr->cf_uid = le64_to_cpu(info->Uid);
+
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
+ fattr->cf_gid = cifs_sb->mnt_gid;
+ else
+ fattr->cf_gid = le64_to_cpu(info->Gid);
+
+ fattr->cf_nlink = le64_to_cpu(info->Nlinks);
+}
/*
- * Needed to setup inode data for the directory which is the
- * junction to the new submount (ie to setup the fake directory
- * which represents a DFS referral)
- */
-static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat,
- struct super_block *sb)
-{
- struct inode *pinode = NULL;
-
- memset(pfnd_dat, 0, sizeof(FILE_UNIX_BASIC_INFO));
-
-/* __le64 pfnd_dat->EndOfFile = cpu_to_le64(0);
- __le64 pfnd_dat->NumOfBytes = cpu_to_le64(0);
- __u64 UniqueId = 0; */
- pfnd_dat->LastStatusChange =
- cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
- pfnd_dat->LastAccessTime =
- cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
- pfnd_dat->LastModificationTime =
- cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
- pfnd_dat->Type = cpu_to_le32(UNIX_DIR);
- pfnd_dat->Permissions = cpu_to_le64(S_IXUGO | S_IRWXU);
- pfnd_dat->Nlinks = cpu_to_le64(2);
- if (sb->s_root)
- pinode = sb->s_root->d_inode;
- if (pinode == NULL)
- return;
-
- /* fill in default values for the remaining based on root
- inode since we can not query the server for this inode info */
- pfnd_dat->DevMajor = cpu_to_le64(MAJOR(pinode->i_rdev));
- pfnd_dat->DevMinor = cpu_to_le64(MINOR(pinode->i_rdev));
- pfnd_dat->Uid = cpu_to_le64(pinode->i_uid);
- pfnd_dat->Gid = cpu_to_le64(pinode->i_gid);
-}
-
-/**
- * cifs_new inode - create new inode, initialize, and hash it
- * @sb - pointer to superblock
- * @inum - if valid pointer and serverino is enabled, replace i_ino with val
+ * Fill a cifs_fattr struct with fake inode info.
*
- * Create a new inode, initialize it for CIFS and hash it. Returns the new
- * inode or NULL if one couldn't be allocated.
- *
- * If the share isn't mounted with "serverino" or inum is a NULL pointer then
- * we'll just use the inode number assigned by new_inode(). Note that this can
- * mean i_ino collisions since the i_ino assigned by new_inode is not
- * guaranteed to be unique.
+ * Needed to setup cifs_fattr data for the directory which is the
+ * junction to the new submount (ie to setup the fake directory
+ * which represents a DFS referral).
*/
-struct inode *
-cifs_new_inode(struct super_block *sb, __u64 *inum)
+void
+cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
{
- struct inode *inode;
+ struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- inode = new_inode(sb);
- if (inode == NULL)
- return NULL;
+ cFYI(1, ("creating fake fattr for DFS referral"));
- /*
- * BB: Is i_ino == 0 legal? Here, we assume that it is. If it isn't we
- * stop passing inum as ptr. Are there sanity checks we can use to
- * ensure that the server is really filling in that field? Also,
- * if serverino is disabled, perhaps we should be using iunique()?
- */
- if (inum && (CIFS_SB(sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM))
- inode->i_ino = (unsigned long) *inum;
-
- /*
- * must set this here instead of cifs_alloc_inode since VFS will
- * clobber i_flags
- */
- if (sb->s_flags & MS_NOATIME)
- inode->i_flags |= S_NOATIME | S_NOCMTIME;
-
- insert_inode_hash(inode);
-
- return inode;
+ memset(fattr, 0, sizeof(*fattr));
+ fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
+ fattr->cf_uid = cifs_sb->mnt_uid;
+ fattr->cf_gid = cifs_sb->mnt_gid;
+ fattr->cf_atime = CURRENT_TIME;
+ fattr->cf_ctime = CURRENT_TIME;
+ fattr->cf_mtime = CURRENT_TIME;
+ fattr->cf_nlink = 2;
+ fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
}
int cifs_get_inode_info_unix(struct inode **pinode,
- const unsigned char *full_path, struct super_block *sb, int xid)
+ const unsigned char *full_path,
+ struct super_block *sb, int xid)
{
- int rc = 0;
+ int rc;
FILE_UNIX_BASIC_INFO find_data;
- struct cifsTconInfo *pTcon;
- struct inode *inode;
+ struct cifs_fattr fattr;
+ struct cifsTconInfo *tcon;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- bool is_dfs_referral = false;
- struct cifsInodeInfo *cifsInfo;
- __u64 num_of_bytes;
- __u64 end_of_file;
- pTcon = cifs_sb->tcon;
+ tcon = cifs_sb->tcon;
cFYI(1, ("Getting info on %s", full_path));
/* could have done a find first instead but this returns more info */
- rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &find_data,
+ rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc == -EREMOTE && !is_dfs_referral) {
- is_dfs_referral = true;
- cFYI(DBG2, ("DFS ref"));
- /* for DFS, server does not give us real inode data */
- fill_fake_finddataunix(&find_data, sb);
+
+ if (!rc) {
+ cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
+ } else if (rc == -EREMOTE) {
+ cifs_create_dfs_fattr(&fattr, sb);
rc = 0;
- } else if (rc)
- goto cgiiu_exit;
-
- num_of_bytes = le64_to_cpu(find_data.NumOfBytes);
- end_of_file = le64_to_cpu(find_data.EndOfFile);
-
- /* get new inode */
- if (*pinode == NULL) {
- __u64 unique_id = le64_to_cpu(find_data.UniqueId);
- *pinode = cifs_new_inode(sb, &unique_id);
- if (*pinode == NULL) {
- rc = -ENOMEM;
- goto cgiiu_exit;
- }
+ } else {
+ return rc;
}
- inode = *pinode;
- cifsInfo = CIFS_I(inode);
+ if (*pinode == NULL) {
+ /* get new inode */
+ *pinode = cifs_iget(sb, &fattr);
+ if (!*pinode)
+ rc = -ENOMEM;
+ } else {
+ /* we already have inode, update it */
+ cifs_fattr_to_inode(*pinode, &fattr);
+ }
- cFYI(1, ("Old time %ld", cifsInfo->time));
- cifsInfo->time = jiffies;
- cFYI(1, ("New time %ld", cifsInfo->time));
- /* this is ok to set on every inode revalidate */
- atomic_set(&cifsInfo->inUse, 1);
-
- cifs_unix_info_to_inode(inode, &find_data, 0);
-
- if (num_of_bytes < end_of_file)
- cFYI(1, ("allocation size less than end of file"));
- cFYI(1, ("Size %ld and blocks %llu",
- (unsigned long) inode->i_size,
- (unsigned long long)inode->i_blocks));
-
- cifs_set_ops(inode, is_dfs_referral);
-cgiiu_exit:
return rc;
}
-static int decode_sfu_inode(struct inode *inode, __u64 size,
- const unsigned char *path,
- struct cifs_sb_info *cifs_sb, int xid)
+static int
+cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
+ struct cifs_sb_info *cifs_sb, int xid)
{
int rc;
int oplock = 0;
@@ -321,10 +284,15 @@
pbuf = buf;
- if (size == 0) {
- inode->i_mode |= S_IFIFO;
+ fattr->cf_mode &= ~S_IFMT;
+
+ if (fattr->cf_eof == 0) {
+ fattr->cf_mode |= S_IFIFO;
+ fattr->cf_dtype = DT_FIFO;
return 0;
- } else if (size < 8) {
+ } else if (fattr->cf_eof < 8) {
+ fattr->cf_mode |= S_IFREG;
+ fattr->cf_dtype = DT_REG;
return -EINVAL; /* EOPNOTSUPP? */
}
@@ -336,42 +304,46 @@
if (rc == 0) {
int buf_type = CIFS_NO_BUFFER;
/* Read header */
- rc = CIFSSMBRead(xid, pTcon,
- netfid,
+ rc = CIFSSMBRead(xid, pTcon, netfid,
24 /* length */, 0 /* offset */,
&bytes_read, &pbuf, &buf_type);
if ((rc == 0) && (bytes_read >= 8)) {
if (memcmp("IntxBLK", pbuf, 8) == 0) {
cFYI(1, ("Block device"));
- inode->i_mode |= S_IFBLK;
+ fattr->cf_mode |= S_IFBLK;
+ fattr->cf_dtype = DT_BLK;
if (bytes_read == 24) {
/* we have enough to decode dev num */
__u64 mjr; /* major */
__u64 mnr; /* minor */
mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
- inode->i_rdev = MKDEV(mjr, mnr);
+ fattr->cf_rdev = MKDEV(mjr, mnr);
}
} else if (memcmp("IntxCHR", pbuf, 8) == 0) {
cFYI(1, ("Char device"));
- inode->i_mode |= S_IFCHR;
+ fattr->cf_mode |= S_IFCHR;
+ fattr->cf_dtype = DT_CHR;
if (bytes_read == 24) {
/* we have enough to decode dev num */
__u64 mjr; /* major */
__u64 mnr; /* minor */
mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
- inode->i_rdev = MKDEV(mjr, mnr);
+ fattr->cf_rdev = MKDEV(mjr, mnr);
}
} else if (memcmp("IntxLNK", pbuf, 7) == 0) {
cFYI(1, ("Symlink"));
- inode->i_mode |= S_IFLNK;
+ fattr->cf_mode |= S_IFLNK;
+ fattr->cf_dtype = DT_LNK;
} else {
- inode->i_mode |= S_IFREG; /* file? */
+ fattr->cf_mode |= S_IFREG; /* file? */
+ fattr->cf_dtype = DT_REG;
rc = -EOPNOTSUPP;
}
} else {
- inode->i_mode |= S_IFREG; /* then it is a file */
+ fattr->cf_mode |= S_IFREG; /* then it is a file */
+ fattr->cf_dtype = DT_REG;
rc = -EOPNOTSUPP; /* or some unknown SFU type */
}
CIFSSMBClose(xid, pTcon, netfid);
@@ -381,9 +353,13 @@
#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
-static int get_sfu_mode(struct inode *inode,
- const unsigned char *path,
- struct cifs_sb_info *cifs_sb, int xid)
+/*
+ * Fetch mode bits as provided by SFU.
+ *
+ * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ?
+ */
+static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
+ struct cifs_sb_info *cifs_sb, int xid)
{
#ifdef CONFIG_CIFS_XATTR
ssize_t rc;
@@ -391,68 +367,80 @@
__u32 mode;
rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
- ea_value, 4 /* size of buf */, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ ea_value, 4 /* size of buf */, cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc < 0)
return (int)rc;
else if (rc > 3) {
mode = le32_to_cpu(*((__le32 *)ea_value));
- inode->i_mode &= ~SFBITS_MASK;
- cFYI(1, ("special bits 0%o org mode 0%o", mode, inode->i_mode));
- inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode;
+ fattr->cf_mode &= ~SFBITS_MASK;
+ cFYI(1, ("special bits 0%o org mode 0%o", mode,
+ fattr->cf_mode));
+ fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
cFYI(1, ("special mode bits 0%o", mode));
- return 0;
- } else {
- return 0;
}
+
+ return 0;
#else
return -EOPNOTSUPP;
#endif
}
-/*
- * Needed to setup inode data for the directory which is the
- * junction to the new submount (ie to setup the fake directory
- * which represents a DFS referral)
- */
-static void fill_fake_finddata(FILE_ALL_INFO *pfnd_dat,
- struct super_block *sb)
+/* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
+void
+cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
+ struct cifs_sb_info *cifs_sb, bool adjust_tz)
{
- memset(pfnd_dat, 0, sizeof(FILE_ALL_INFO));
+ memset(fattr, 0, sizeof(*fattr));
+ fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
+ if (info->DeletePending)
+ fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING;
-/* __le64 pfnd_dat->AllocationSize = cpu_to_le64(0);
- __le64 pfnd_dat->EndOfFile = cpu_to_le64(0);
- __u8 pfnd_dat->DeletePending = 0;
- __u8 pfnd_data->Directory = 0;
- __le32 pfnd_dat->EASize = 0;
- __u64 pfnd_dat->IndexNumber = 0;
- __u64 pfnd_dat->IndexNumber1 = 0; */
- pfnd_dat->CreationTime =
- cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
- pfnd_dat->LastAccessTime =
- cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
- pfnd_dat->LastWriteTime =
- cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
- pfnd_dat->ChangeTime =
- cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
- pfnd_dat->Attributes = cpu_to_le32(ATTR_DIRECTORY);
- pfnd_dat->NumberOfLinks = cpu_to_le32(2);
+ if (info->LastAccessTime)
+ fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
+ else
+ fattr->cf_atime = CURRENT_TIME;
+
+ fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
+ fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
+
+ if (adjust_tz) {
+ fattr->cf_ctime.tv_sec += cifs_sb->tcon->ses->server->timeAdj;
+ fattr->cf_mtime.tv_sec += cifs_sb->tcon->ses->server->timeAdj;
+ }
+
+ fattr->cf_eof = le64_to_cpu(info->EndOfFile);
+ fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
+
+ if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
+ fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
+ fattr->cf_dtype = DT_DIR;
+ } else {
+ fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
+ fattr->cf_dtype = DT_REG;
+
+ /* clear write bits if ATTR_READONLY is set */
+ if (fattr->cf_cifsattrs & ATTR_READONLY)
+ fattr->cf_mode &= ~(S_IWUGO);
+ }
+
+ fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
+
+ fattr->cf_uid = cifs_sb->mnt_uid;
+ fattr->cf_gid = cifs_sb->mnt_gid;
}
int cifs_get_inode_info(struct inode **pinode,
const unsigned char *full_path, FILE_ALL_INFO *pfindData,
struct super_block *sb, int xid, const __u16 *pfid)
{
- int rc = 0;
- __u32 attr;
- struct cifsInodeInfo *cifsInfo;
+ int rc = 0, tmprc;
struct cifsTconInfo *pTcon;
- struct inode *inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
char *buf = NULL;
bool adjustTZ = false;
- bool is_dfs_referral = false;
- umode_t default_mode;
+ struct cifs_fattr fattr;
pTcon = cifs_sb->tcon;
cFYI(1, ("Getting info on %s", full_path));
@@ -487,164 +475,83 @@
adjustTZ = true;
}
}
- /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
- if (rc == -EREMOTE) {
- is_dfs_referral = true;
- fill_fake_finddata(pfindData, sb);
+
+ if (!rc) {
+ cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData,
+ cifs_sb, adjustTZ);
+ } else if (rc == -EREMOTE) {
+ cifs_create_dfs_fattr(&fattr, sb);
rc = 0;
- } else if (rc)
+ } else {
goto cgii_exit;
+ }
- attr = le32_to_cpu(pfindData->Attributes);
-
- /* get new inode */
+ /*
+ * If an inode wasn't passed in, then get the inode number
+ *
+ * Is an i_ino of zero legal? Can we use that to check if the server
+ * supports returning inode numbers? Are there other sanity checks we
+ * can use to ensure that the server is really filling in that field?
+ *
+ * We can not use the IndexNumber field by default from Windows or
+ * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA
+ * CIFS spec claims that this value is unique within the scope of a
+ * share, and the windows docs hint that it's actually unique
+ * per-machine.
+ *
+ * There may be higher info levels that work but are there Windows
+ * server or network appliances for which IndexNumber field is not
+ * guaranteed unique?
+ */
if (*pinode == NULL) {
- __u64 inode_num;
- __u64 *pinum = &inode_num;
-
- /* Is an i_ino of zero legal? Can we use that to check
- if the server supports returning inode numbers? Are
- there other sanity checks we can use to ensure that
- the server is really filling in that field? */
-
- /* We can not use the IndexNumber field by default from
- Windows or Samba (in ALL_INFO buf) but we can request
- it explicitly. It may not be unique presumably if
- the server has multiple devices mounted under one share */
-
- /* There may be higher info levels that work but are
- there Windows server or network appliances for which
- IndexNumber field is not guaranteed unique? */
-
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
int rc1 = 0;
rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
- full_path, pinum,
+ full_path, &fattr.cf_uniqueid,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc1) {
- cFYI(1, ("GetSrvInodeNum rc %d", rc1));
- pinum = NULL;
/* BB EOPNOSUPP disable SERVER_INUM? */
+ cFYI(1, ("GetSrvInodeNum rc %d", rc1));
+ fattr.cf_uniqueid = iunique(sb, ROOT_I);
}
} else {
- pinum = NULL;
+ fattr.cf_uniqueid = iunique(sb, ROOT_I);
}
-
- *pinode = cifs_new_inode(sb, pinum);
- if (*pinode == NULL) {
- rc = -ENOMEM;
- goto cgii_exit;
- }
- }
- inode = *pinode;
- cifsInfo = CIFS_I(inode);
- cifsInfo->cifsAttrs = attr;
- cifsInfo->delete_pending = pfindData->DeletePending ? true : false;
- cFYI(1, ("Old time %ld", cifsInfo->time));
- cifsInfo->time = jiffies;
- cFYI(1, ("New time %ld", cifsInfo->time));
-
- /* blksize needs to be multiple of two. So safer to default to
- blksize and blkbits set in superblock so 2**blkbits and blksize
- will match rather than setting to:
- (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
-
- /* Linux can not store file creation time so ignore it */
- if (pfindData->LastAccessTime)
- inode->i_atime = cifs_NTtimeToUnix(pfindData->LastAccessTime);
- else /* do not need to use current_fs_time - time not stored */
- inode->i_atime = CURRENT_TIME;
- inode->i_mtime = cifs_NTtimeToUnix(pfindData->LastWriteTime);
- inode->i_ctime = cifs_NTtimeToUnix(pfindData->ChangeTime);
- cFYI(DBG2, ("Attributes came in as 0x%x", attr));
- if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) {
- inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj;
- inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
- }
-
- /* get default inode mode */
- if (attr & ATTR_DIRECTORY)
- default_mode = cifs_sb->mnt_dir_mode;
- else
- default_mode = cifs_sb->mnt_file_mode;
-
- /* set permission bits */
- if (atomic_read(&cifsInfo->inUse) == 0 ||
- (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
- inode->i_mode = default_mode;
- else {
- /* just reenable write bits if !ATTR_READONLY */
- if ((inode->i_mode & S_IWUGO) == 0 &&
- (attr & ATTR_READONLY) == 0)
- inode->i_mode |= (S_IWUGO & default_mode);
-
- inode->i_mode &= ~S_IFMT;
- }
- /* clear write bits if ATTR_READONLY is set */
- if (attr & ATTR_READONLY)
- inode->i_mode &= ~S_IWUGO;
-
- /* set inode type */
- if ((attr & ATTR_SYSTEM) &&
- (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) {
- /* no need to fix endianness on 0 */
- if (pfindData->EndOfFile == 0)
- inode->i_mode |= S_IFIFO;
- else if (decode_sfu_inode(inode,
- le64_to_cpu(pfindData->EndOfFile),
- full_path, cifs_sb, xid))
- cFYI(1, ("unknown SFU file type\n"));
} else {
- if (attr & ATTR_DIRECTORY)
- inode->i_mode |= S_IFDIR;
- else
- inode->i_mode |= S_IFREG;
+ fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid;
}
- cifsInfo->server_eof = le64_to_cpu(pfindData->EndOfFile);
- spin_lock(&inode->i_lock);
- if (is_size_safe_to_change(cifsInfo, cifsInfo->server_eof)) {
- /* can not safely shrink the file size here if the
- client is writing to it due to potential races */
- i_size_write(inode, cifsInfo->server_eof);
-
- /* 512 bytes (2**9) is the fake blocksize that must be
- used for this calculation */
- inode->i_blocks = (512 - 1 + le64_to_cpu(
- pfindData->AllocationSize)) >> 9;
+ /* query for SFU type info if supported and needed */
+ if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
+ cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
+ tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
+ if (tmprc)
+ cFYI(1, ("cifs_sfu_type failed: %d", tmprc));
}
- spin_unlock(&inode->i_lock);
- inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks);
-
- /* BB fill in uid and gid here? with help from winbind?
- or retrieve from NTFS stream extended attribute */
#ifdef CONFIG_CIFS_EXPERIMENTAL
/* fill in 0777 bits from ACL */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
cFYI(1, ("Getting mode bits from ACL"));
- acl_to_uid_mode(cifs_sb, inode, full_path, pfid);
+ cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid);
}
#endif
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
- /* fill in remaining high mode bits e.g. SUID, VTX */
- get_sfu_mode(inode, full_path, cifs_sb, xid);
- } else if (atomic_read(&cifsInfo->inUse) == 0) {
- inode->i_uid = cifs_sb->mnt_uid;
- inode->i_gid = cifs_sb->mnt_gid;
- /* set so we do not keep refreshing these fields with
- bad data after user has changed them in memory */
- atomic_set(&cifsInfo->inUse, 1);
+
+ /* fill in remaining high mode bits e.g. SUID, VTX */
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
+ cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
+
+ if (!*pinode) {
+ *pinode = cifs_iget(sb, &fattr);
+ if (!*pinode)
+ rc = -ENOMEM;
+ } else {
+ cifs_fattr_to_inode(*pinode, &fattr);
}
- cifs_set_ops(inode, is_dfs_referral);
-
-
-
-
cgii_exit:
kfree(buf);
return rc;
@@ -695,33 +602,78 @@
return full_path;
}
+static int
+cifs_find_inode(struct inode *inode, void *opaque)
+{
+ struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
+
+ if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
+ return 0;
+
+ return 1;
+}
+
+static int
+cifs_init_inode(struct inode *inode, void *opaque)
+{
+ struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
+
+ CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
+ return 0;
+}
+
+/* Given fattrs, get a corresponding inode */
+struct inode *
+cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
+{
+ unsigned long hash;
+ struct inode *inode;
+
+ cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid));
+
+ /* hash down to 32-bits on 32-bit arch */
+ hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
+
+ inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
+
+ /* we have fattrs in hand, update the inode */
+ if (inode) {
+ cifs_fattr_to_inode(inode, fattr);
+ if (sb->s_flags & MS_NOATIME)
+ inode->i_flags |= S_NOATIME | S_NOCMTIME;
+ if (inode->i_state & I_NEW) {
+ inode->i_ino = hash;
+ unlock_new_inode(inode);
+ }
+ }
+
+ return inode;
+}
+
/* gets root inode */
struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
{
int xid;
struct cifs_sb_info *cifs_sb;
- struct inode *inode;
+ struct inode *inode = NULL;
long rc;
char *full_path;
- inode = iget_locked(sb, ino);
- if (!inode)
- return ERR_PTR(-ENOMEM);
- if (!(inode->i_state & I_NEW))
- return inode;
-
- cifs_sb = CIFS_SB(inode->i_sb);
+ cifs_sb = CIFS_SB(sb);
full_path = cifs_build_path_to_root(cifs_sb);
if (full_path == NULL)
return ERR_PTR(-ENOMEM);
xid = GetXid();
if (cifs_sb->tcon->unix_ext)
- rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
- xid);
+ rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
else
- rc = cifs_get_inode_info(&inode, full_path, NULL, inode->i_sb,
+ rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
xid, NULL);
+
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+
if (rc && cifs_sb->tcon->ipc) {
cFYI(1, ("ipc connection - fake read inode"));
inode->i_mode |= S_IFDIR;
@@ -737,7 +689,6 @@
return ERR_PTR(rc);
}
- unlock_new_inode(inode);
kfree(full_path);
/* can not call macro FreeXid here since in a void func
@@ -1063,44 +1014,6 @@
return rc;
}
-void posix_fill_in_inode(struct inode *tmp_inode,
- FILE_UNIX_BASIC_INFO *pData, int isNewInode)
-{
- struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
- loff_t local_size;
- struct timespec local_mtime;
-
- cifsInfo->time = jiffies;
- atomic_inc(&cifsInfo->inUse);
-
- /* save mtime and size */
- local_mtime = tmp_inode->i_mtime;
- local_size = tmp_inode->i_size;
-
- cifs_unix_info_to_inode(tmp_inode, pData, 1);
- cifs_set_ops(tmp_inode, false);
-
- if (!S_ISREG(tmp_inode->i_mode))
- return;
-
- /*
- * No sense invalidating pages for new inode
- * since we we have not started caching
- * readahead file data yet.
- */
- if (isNewInode)
- return;
-
- if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
- (local_size == tmp_inode->i_size)) {
- cFYI(1, ("inode exists but unchanged"));
- } else {
- /* file may have changed on server */
- cFYI(1, ("invalidate inode, readdir detected change"));
- invalidate_remote_inode(tmp_inode);
- }
-}
-
int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
{
int rc = 0, tmprc;
@@ -1109,6 +1022,7 @@
struct cifsTconInfo *pTcon;
char *full_path = NULL;
struct inode *newinode = NULL;
+ struct cifs_fattr fattr;
cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
@@ -1148,7 +1062,6 @@
cFYI(1, ("posix mkdir returned 0x%x", rc));
d_drop(direntry);
} else {
- __u64 unique_id;
if (pInfo->Type == cpu_to_le32(-1)) {
/* no return info, go query for it */
kfree(pInfo);
@@ -1162,20 +1075,15 @@
else
direntry->d_op = &cifs_dentry_ops;
- unique_id = le64_to_cpu(pInfo->UniqueId);
- newinode = cifs_new_inode(inode->i_sb, &unique_id);
- if (newinode == NULL) {
+ cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
+ newinode = cifs_iget(inode->i_sb, &fattr);
+ if (!newinode) {
kfree(pInfo);
goto mkdir_get_info;
}
- newinode->i_nlink = 2;
d_instantiate(direntry, newinode);
- /* we already checked in POSIXCreate whether
- frame was long enough */
- posix_fill_in_inode(direntry->d_inode,
- pInfo, 1 /* NewInode */);
#ifdef CONFIG_CIFS_DEBUG2
cFYI(1, ("instantiated dentry %p %s to inode %p",
direntry, direntry->d_name.name, newinode));
@@ -1238,10 +1146,10 @@
args.uid = NO_CHANGE_64;
args.gid = NO_CHANGE_64;
}
- CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
+ CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
} else {
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
(mode & S_IWUGO) == 0) {
@@ -1622,6 +1530,7 @@
if (!err) {
generic_fillattr(dentry->d_inode, stat);
stat->blksize = CIFS_MAX_MSGSIZE;
+ stat->ino = CIFS_I(dentry->d_inode)->uniqueid;
}
return err;
}
@@ -1786,6 +1695,7 @@
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsTconInfo *pTcon = cifs_sb->tcon;
struct cifs_unix_set_info_args *args = NULL;
+ struct cifsFileInfo *open_file;
cFYI(1, ("setattr_unix on file %s attrs->ia_valid=0x%x",
direntry->d_name.name, attrs->ia_valid));
@@ -1872,10 +1782,18 @@
args->ctime = NO_CHANGE_64;
args->device = 0;
- rc = CIFSSMBUnixSetInfo(xid, pTcon, full_path, args,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
+ open_file = find_writable_file(cifsInode);
+ if (open_file) {
+ u16 nfid = open_file->netfid;
+ u32 npid = open_file->pid;
+ rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
+ atomic_dec(&open_file->wrtPending);
+ } else {
+ rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
+ cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+ }
if (!rc)
rc = inode_setattr(inode, attrs);
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 86d0055..f823a4a 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -63,374 +63,123 @@
}
#endif /* DEBUG2 */
-/* Returns 1 if new inode created, 2 if both dentry and inode were */
-/* Might check in the future if inode number changed so we can rehash inode */
-static int
-construct_dentry(struct qstr *qstring, struct file *file,
- struct inode **ptmp_inode, struct dentry **pnew_dentry,
- __u64 *inum)
+/*
+ * Find the dentry that matches "name". If there isn't one, create one. If it's
+ * a negative dentry or the uniqueid changed, then drop it and recreate it.
+ */
+static struct dentry *
+cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
+ struct cifs_fattr *fattr)
{
- struct dentry *tmp_dentry = NULL;
- struct super_block *sb = file->f_path.dentry->d_sb;
- int rc = 0;
+ struct dentry *dentry, *alias;
+ struct inode *inode;
+ struct super_block *sb = parent->d_inode->i_sb;
- cFYI(1, ("For %s", qstring->name));
+ cFYI(1, ("For %s", name->name));
- qstring->hash = full_name_hash(qstring->name, qstring->len);
- tmp_dentry = d_lookup(file->f_path.dentry, qstring);
- if (tmp_dentry) {
- /* BB: overwrite old name? i.e. tmp_dentry->d_name and
- * tmp_dentry->d_name.len??
- */
- cFYI(0, ("existing dentry with inode 0x%p",
- tmp_dentry->d_inode));
- *ptmp_inode = tmp_dentry->d_inode;
- if (*ptmp_inode == NULL) {
- *ptmp_inode = cifs_new_inode(sb, inum);
- if (*ptmp_inode == NULL)
- return rc;
- rc = 1;
- }
- } else {
- tmp_dentry = d_alloc(file->f_path.dentry, qstring);
- if (tmp_dentry == NULL) {
- cERROR(1, ("Failed allocating dentry"));
- *ptmp_inode = NULL;
- return rc;
- }
-
- if (CIFS_SB(sb)->tcon->nocase)
- tmp_dentry->d_op = &cifs_ci_dentry_ops;
- else
- tmp_dentry->d_op = &cifs_dentry_ops;
-
- *ptmp_inode = cifs_new_inode(sb, inum);
- if (*ptmp_inode == NULL)
- return rc;
- rc = 2;
+ dentry = d_lookup(parent, name);
+ if (dentry) {
+ /* FIXME: check for inode number changes? */
+ if (dentry->d_inode != NULL)
+ return dentry;
+ d_drop(dentry);
+ dput(dentry);
}
- tmp_dentry->d_time = jiffies;
- *pnew_dentry = tmp_dentry;
- return rc;
+ dentry = d_alloc(parent, name);
+ if (dentry == NULL)
+ return NULL;
+
+ inode = cifs_iget(sb, fattr);
+ if (!inode) {
+ dput(dentry);
+ return NULL;
+ }
+
+ if (CIFS_SB(sb)->tcon->nocase)
+ dentry->d_op = &cifs_ci_dentry_ops;
+ else
+ dentry->d_op = &cifs_dentry_ops;
+
+ alias = d_materialise_unique(dentry, inode);
+ if (alias != NULL) {
+ dput(dentry);
+ if (IS_ERR(alias))
+ return NULL;
+ dentry = alias;
+ }
+
+ return dentry;
}
-static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
- char *buf, unsigned int *pobject_type, int isNewInode)
+static void
+cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
{
- loff_t local_size;
- struct timespec local_mtime;
+ fattr->cf_uid = cifs_sb->mnt_uid;
+ fattr->cf_gid = cifs_sb->mnt_gid;
- struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
- __u32 attr;
- __u64 allocation_size;
- __u64 end_of_file;
- umode_t default_mode;
-
- /* save mtime and size */
- local_mtime = tmp_inode->i_mtime;
- local_size = tmp_inode->i_size;
-
- if (new_buf_type) {
- FILE_DIRECTORY_INFO *pfindData = (FILE_DIRECTORY_INFO *)buf;
-
- attr = le32_to_cpu(pfindData->ExtFileAttributes);
- allocation_size = le64_to_cpu(pfindData->AllocationSize);
- end_of_file = le64_to_cpu(pfindData->EndOfFile);
- tmp_inode->i_atime =
- cifs_NTtimeToUnix(pfindData->LastAccessTime);
- tmp_inode->i_mtime =
- cifs_NTtimeToUnix(pfindData->LastWriteTime);
- tmp_inode->i_ctime =
- cifs_NTtimeToUnix(pfindData->ChangeTime);
- } else { /* legacy, OS2 and DOS style */
- int offset = cifs_sb->tcon->ses->server->timeAdj;
- FIND_FILE_STANDARD_INFO *pfindData =
- (FIND_FILE_STANDARD_INFO *)buf;
-
- tmp_inode->i_mtime = cnvrtDosUnixTm(pfindData->LastWriteDate,
- pfindData->LastWriteTime,
- offset);
- tmp_inode->i_atime = cnvrtDosUnixTm(pfindData->LastAccessDate,
- pfindData->LastAccessTime,
- offset);
- tmp_inode->i_ctime = cnvrtDosUnixTm(pfindData->LastWriteDate,
- pfindData->LastWriteTime,
- offset);
- attr = le16_to_cpu(pfindData->Attributes);
- allocation_size = le32_to_cpu(pfindData->AllocationSize);
- end_of_file = le32_to_cpu(pfindData->DataSize);
+ if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
+ fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
+ fattr->cf_dtype = DT_DIR;
+ } else {
+ fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
+ fattr->cf_dtype = DT_REG;
}
- /* Linux can not store file creation time unfortunately so ignore it */
+ if (fattr->cf_cifsattrs & ATTR_READONLY)
+ fattr->cf_mode &= ~S_IWUGO;
- cifsInfo->cifsAttrs = attr;
-#ifdef CONFIG_CIFS_EXPERIMENTAL
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
- /* get more accurate mode via ACL - so force inode refresh */
- cifsInfo->time = 0;
- } else
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
- cifsInfo->time = jiffies;
-
- /* treat dos attribute of read-only as read-only mode bit e.g. 555? */
- /* 2767 perms - indicate mandatory locking */
- /* BB fill in uid and gid here? with help from winbind?
- or retrieve from NTFS stream extended attribute */
- if (atomic_read(&cifsInfo->inUse) == 0) {
- tmp_inode->i_uid = cifs_sb->mnt_uid;
- tmp_inode->i_gid = cifs_sb->mnt_gid;
- }
-
- if (attr & ATTR_DIRECTORY)
- default_mode = cifs_sb->mnt_dir_mode;
- else
- default_mode = cifs_sb->mnt_file_mode;
-
- /* set initial permissions */
- if ((atomic_read(&cifsInfo->inUse) == 0) ||
- (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
- tmp_inode->i_mode = default_mode;
- else {
- /* just reenable write bits if !ATTR_READONLY */
- if ((tmp_inode->i_mode & S_IWUGO) == 0 &&
- (attr & ATTR_READONLY) == 0)
- tmp_inode->i_mode |= (S_IWUGO & default_mode);
-
- tmp_inode->i_mode &= ~S_IFMT;
- }
-
- /* clear write bits if ATTR_READONLY is set */
- if (attr & ATTR_READONLY)
- tmp_inode->i_mode &= ~S_IWUGO;
-
- /* set inode type */
- if ((attr & ATTR_SYSTEM) &&
- (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) {
- if (end_of_file == 0) {
- tmp_inode->i_mode |= S_IFIFO;
- *pobject_type = DT_FIFO;
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL &&
+ fattr->cf_cifsattrs & ATTR_SYSTEM) {
+ if (fattr->cf_eof == 0) {
+ fattr->cf_mode &= ~S_IFMT;
+ fattr->cf_mode |= S_IFIFO;
+ fattr->cf_dtype = DT_FIFO;
} else {
/*
- * trying to get the type can be slow, so just call
- * this a regular file for now, and mark for reval
+ * trying to get the type and mode via SFU can be slow,
+ * so just call those regular files for now, and mark
+ * for reval
*/
- tmp_inode->i_mode |= S_IFREG;
- *pobject_type = DT_REG;
- cifsInfo->time = 0;
+ fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
}
- } else {
- if (attr & ATTR_DIRECTORY) {
- tmp_inode->i_mode |= S_IFDIR;
- *pobject_type = DT_DIR;
- } else {
- tmp_inode->i_mode |= S_IFREG;
- *pobject_type = DT_REG;
- }
- }
-
- /* can not fill in nlink here as in qpathinfo version and Unx search */
- if (atomic_read(&cifsInfo->inUse) == 0)
- atomic_set(&cifsInfo->inUse, 1);
-
- cifsInfo->server_eof = end_of_file;
- spin_lock(&tmp_inode->i_lock);
- if (is_size_safe_to_change(cifsInfo, end_of_file)) {
- /* can not safely change the file size here if the
- client is writing to it due to potential races */
- i_size_write(tmp_inode, end_of_file);
-
- /* 512 bytes (2**9) is the fake blocksize that must be used */
- /* for this calculation, even though the reported blocksize is larger */
- tmp_inode->i_blocks = (512 - 1 + allocation_size) >> 9;
- }
- spin_unlock(&tmp_inode->i_lock);
-
- if (allocation_size < end_of_file)
- cFYI(1, ("May be sparse file, allocation less than file size"));
- cFYI(1, ("File Size %ld and blocks %llu",
- (unsigned long)tmp_inode->i_size,
- (unsigned long long)tmp_inode->i_blocks));
- if (S_ISREG(tmp_inode->i_mode)) {
- cFYI(1, ("File inode"));
- tmp_inode->i_op = &cifs_file_inode_ops;
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
- else
- tmp_inode->i_fop = &cifs_file_direct_ops;
- } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- tmp_inode->i_fop = &cifs_file_nobrl_ops;
- else
- tmp_inode->i_fop = &cifs_file_ops;
-
- if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
- (cifs_sb->tcon->ses->server->maxBuf <
- PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
- tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
- else
- tmp_inode->i_data.a_ops = &cifs_addr_ops;
-
- if (isNewInode)
- return; /* No sense invalidating pages for new inode
- since have not started caching readahead file
- data yet */
-
- if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
- (local_size == tmp_inode->i_size)) {
- cFYI(1, ("inode exists but unchanged"));
- } else {
- /* file may have changed on server */
- cFYI(1, ("invalidate inode, readdir detected change"));
- invalidate_remote_inode(tmp_inode);
- }
- } else if (S_ISDIR(tmp_inode->i_mode)) {
- cFYI(1, ("Directory inode"));
- tmp_inode->i_op = &cifs_dir_inode_ops;
- tmp_inode->i_fop = &cifs_dir_ops;
- } else if (S_ISLNK(tmp_inode->i_mode)) {
- cFYI(1, ("Symbolic Link inode"));
- tmp_inode->i_op = &cifs_symlink_inode_ops;
- } else {
- cFYI(1, ("Init special inode"));
- init_special_inode(tmp_inode, tmp_inode->i_mode,
- tmp_inode->i_rdev);
}
}
-static void unix_fill_in_inode(struct inode *tmp_inode,
- FILE_UNIX_INFO *pfindData, unsigned int *pobject_type, int isNewInode)
+void
+cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info,
+ struct cifs_sb_info *cifs_sb)
{
- loff_t local_size;
- struct timespec local_mtime;
+ memset(fattr, 0, sizeof(*fattr));
+ fattr->cf_cifsattrs = le32_to_cpu(info->ExtFileAttributes);
+ fattr->cf_eof = le64_to_cpu(info->EndOfFile);
+ fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
+ fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
+ fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
+ fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
- struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
+ cifs_fill_common_info(fattr, cifs_sb);
+}
- __u32 type = le32_to_cpu(pfindData->Type);
- __u64 num_of_bytes = le64_to_cpu(pfindData->NumOfBytes);
- __u64 end_of_file = le64_to_cpu(pfindData->EndOfFile);
- cifsInfo->time = jiffies;
- atomic_inc(&cifsInfo->inUse);
+void
+cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info,
+ struct cifs_sb_info *cifs_sb)
+{
+ int offset = cifs_sb->tcon->ses->server->timeAdj;
- /* save mtime and size */
- local_mtime = tmp_inode->i_mtime;
- local_size = tmp_inode->i_size;
+ memset(fattr, 0, sizeof(*fattr));
+ fattr->cf_atime = cnvrtDosUnixTm(info->LastAccessDate,
+ info->LastAccessTime, offset);
+ fattr->cf_ctime = cnvrtDosUnixTm(info->LastWriteDate,
+ info->LastWriteTime, offset);
+ fattr->cf_mtime = cnvrtDosUnixTm(info->LastWriteDate,
+ info->LastWriteTime, offset);
- tmp_inode->i_atime =
- cifs_NTtimeToUnix(pfindData->LastAccessTime);
- tmp_inode->i_mtime =
- cifs_NTtimeToUnix(pfindData->LastModificationTime);
- tmp_inode->i_ctime =
- cifs_NTtimeToUnix(pfindData->LastStatusChange);
+ fattr->cf_cifsattrs = le16_to_cpu(info->Attributes);
+ fattr->cf_bytes = le32_to_cpu(info->AllocationSize);
+ fattr->cf_eof = le32_to_cpu(info->DataSize);
- tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
- /* since we set the inode type below we need to mask off type
- to avoid strange results if bits above were corrupt */
- tmp_inode->i_mode &= ~S_IFMT;
- if (type == UNIX_FILE) {
- *pobject_type = DT_REG;
- tmp_inode->i_mode |= S_IFREG;
- } else if (type == UNIX_SYMLINK) {
- *pobject_type = DT_LNK;
- tmp_inode->i_mode |= S_IFLNK;
- } else if (type == UNIX_DIR) {
- *pobject_type = DT_DIR;
- tmp_inode->i_mode |= S_IFDIR;
- } else if (type == UNIX_CHARDEV) {
- *pobject_type = DT_CHR;
- tmp_inode->i_mode |= S_IFCHR;
- tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor),
- le64_to_cpu(pfindData->DevMinor) & MINORMASK);
- } else if (type == UNIX_BLOCKDEV) {
- *pobject_type = DT_BLK;
- tmp_inode->i_mode |= S_IFBLK;
- tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor),
- le64_to_cpu(pfindData->DevMinor) & MINORMASK);
- } else if (type == UNIX_FIFO) {
- *pobject_type = DT_FIFO;
- tmp_inode->i_mode |= S_IFIFO;
- } else if (type == UNIX_SOCKET) {
- *pobject_type = DT_SOCK;
- tmp_inode->i_mode |= S_IFSOCK;
- } else {
- /* safest to just call it a file */
- *pobject_type = DT_REG;
- tmp_inode->i_mode |= S_IFREG;
- cFYI(1, ("unknown inode type %d", type));
- }
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
- tmp_inode->i_uid = cifs_sb->mnt_uid;
- else
- tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
- tmp_inode->i_gid = cifs_sb->mnt_gid;
- else
- tmp_inode->i_gid = le64_to_cpu(pfindData->Gid);
- tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks);
-
- cifsInfo->server_eof = end_of_file;
- spin_lock(&tmp_inode->i_lock);
- if (is_size_safe_to_change(cifsInfo, end_of_file)) {
- /* can not safely change the file size here if the
- client is writing to it due to potential races */
- i_size_write(tmp_inode, end_of_file);
-
- /* 512 bytes (2**9) is the fake blocksize that must be used */
- /* for this calculation, not the real blocksize */
- tmp_inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
- }
- spin_unlock(&tmp_inode->i_lock);
-
- if (S_ISREG(tmp_inode->i_mode)) {
- cFYI(1, ("File inode"));
- tmp_inode->i_op = &cifs_file_inode_ops;
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
- else
- tmp_inode->i_fop = &cifs_file_direct_ops;
- } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- tmp_inode->i_fop = &cifs_file_nobrl_ops;
- else
- tmp_inode->i_fop = &cifs_file_ops;
-
- if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
- (cifs_sb->tcon->ses->server->maxBuf <
- PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE))
- tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
- else
- tmp_inode->i_data.a_ops = &cifs_addr_ops;
-
- if (isNewInode)
- return; /* No sense invalidating pages for new inode
- since we have not started caching readahead
- file data for it yet */
-
- if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
- (local_size == tmp_inode->i_size)) {
- cFYI(1, ("inode exists but unchanged"));
- } else {
- /* file may have changed on server */
- cFYI(1, ("invalidate inode, readdir detected change"));
- invalidate_remote_inode(tmp_inode);
- }
- } else if (S_ISDIR(tmp_inode->i_mode)) {
- cFYI(1, ("Directory inode"));
- tmp_inode->i_op = &cifs_dir_inode_ops;
- tmp_inode->i_fop = &cifs_dir_ops;
- } else if (S_ISLNK(tmp_inode->i_mode)) {
- cFYI(1, ("Symbolic Link inode"));
- tmp_inode->i_op = &cifs_symlink_inode_ops;
-/* tmp_inode->i_fop = *//* do not need to set to anything */
- } else {
- cFYI(1, ("Special inode"));
- init_special_inode(tmp_inode, tmp_inode->i_mode,
- tmp_inode->i_rdev);
- }
+ cifs_fill_common_info(fattr, cifs_sb);
}
/* BB eventually need to add the following helper function to
@@ -872,7 +621,7 @@
len = strnlen(filename, PATH_MAX);
}
- *pinum = le64_to_cpu(pFindData->UniqueId);
+ *pinum = le64_to_cpu(pFindData->basic.UniqueId);
} else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
FILE_DIRECTORY_INFO *pFindData =
(FILE_DIRECTORY_INFO *)current_entry;
@@ -932,11 +681,12 @@
int rc = 0;
struct qstr qstring;
struct cifsFileInfo *pCifsF;
- unsigned int obj_type;
- __u64 inum;
+ u64 inum;
+ ino_t ino;
+ struct super_block *sb;
struct cifs_sb_info *cifs_sb;
- struct inode *tmp_inode;
struct dentry *tmp_dentry;
+ struct cifs_fattr fattr;
/* get filename and len into qstring */
/* get dentry */
@@ -954,60 +704,53 @@
if (rc != 0)
return 0;
- cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
+ sb = file->f_path.dentry->d_sb;
+ cifs_sb = CIFS_SB(sb);
qstring.name = scratch_buf;
rc = cifs_get_name_from_search_buf(&qstring, pfindEntry,
pCifsF->srch_inf.info_level,
pCifsF->srch_inf.unicode, cifs_sb,
- max_len,
- &inum /* returned */);
+ max_len, &inum /* returned */);
if (rc)
return rc;
- /* only these two infolevels return valid inode numbers */
- if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX ||
- pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO)
- rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry,
- &inum);
- else
- rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry,
- NULL);
-
- if ((tmp_inode == NULL) || (tmp_dentry == NULL))
- return -ENOMEM;
-
- /* we pass in rc below, indicating whether it is a new inode,
- so we can figure out whether to invalidate the inode cached
- data if the file has changed */
if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX)
- unix_fill_in_inode(tmp_inode,
- (FILE_UNIX_INFO *)pfindEntry,
- &obj_type, rc);
+ cifs_unix_basic_to_fattr(&fattr,
+ &((FILE_UNIX_INFO *) pfindEntry)->basic,
+ cifs_sb);
else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD)
- fill_in_inode(tmp_inode, 0 /* old level 1 buffer type */,
- pfindEntry, &obj_type, rc);
+ cifs_std_info_to_fattr(&fattr, (FIND_FILE_STANDARD_INFO *)
+ pfindEntry, cifs_sb);
else
- fill_in_inode(tmp_inode, 1 /* NT */, pfindEntry, &obj_type, rc);
+ cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *)
+ pfindEntry, cifs_sb);
- if (rc) /* new inode - needs to be tied to dentry */ {
- d_instantiate(tmp_dentry, tmp_inode);
- if (rc == 2)
- d_rehash(tmp_dentry);
- }
+ /* FIXME: make _to_fattr functions fill this out */
+ if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO)
+ fattr.cf_uniqueid = inum;
+ else
+ fattr.cf_uniqueid = iunique(sb, ROOT_I);
+ ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
+ tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr);
rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
- tmp_inode->i_ino, obj_type);
+ ino, fattr.cf_dtype);
+
+ /*
+ * we can not return filldir errors to the caller since they are
+ * "normal" when the stat blocksize is too small - we return remapped
+ * error instead
+ *
+ * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above
+ * case already. Why should we be clobbering other errors from it?
+ */
if (rc) {
cFYI(1, ("filldir rc = %d", rc));
- /* we can not return filldir errors to the caller
- since they are "normal" when the stat blocksize
- is too small - we return remapped error instead */
rc = -EOVERFLOW;
}
-
dput(tmp_dentry);
return rc;
}
diff --git a/fs/compat.c b/fs/compat.c
index cdd51a3..fbadb94 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1486,8 +1486,8 @@
if (!bprm)
goto out_files;
- retval = mutex_lock_interruptible(¤t->cred_guard_mutex);
- if (retval < 0)
+ retval = -ERESTARTNOINTR;
+ if (mutex_lock_interruptible(¤t->cred_guard_mutex))
goto out_free;
current->in_execve = 1;
diff --git a/fs/exec.c b/fs/exec.c
index e639957..4a8849e 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1277,8 +1277,8 @@
if (!bprm)
goto out_files;
- retval = mutex_lock_interruptible(¤t->cred_guard_mutex);
- if (retval < 0)
+ retval = -ERESTARTNOINTR;
+ if (mutex_lock_interruptible(¤t->cred_guard_mutex))
goto out_free;
current->in_execve = 1;
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index a024474..b47679b 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -270,19 +270,21 @@
D2({
int i=0;
struct jffs2_raw_node_ref *this;
- printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n" KERN_DEBUG);
+ printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n");
this = ic->nodes;
+ printk(KERN_DEBUG);
while(this) {
- printk( "0x%08x(%d)->", ref_offset(this), ref_flags(this));
+ printk(KERN_CONT "0x%08x(%d)->",
+ ref_offset(this), ref_flags(this));
if (++i == 5) {
- printk("\n" KERN_DEBUG);
+ printk(KERN_DEBUG);
i=0;
}
this = this->next_in_ino;
}
- printk("\n");
+ printk(KERN_CONT "\n");
});
switch (ic->class) {
diff --git a/fs/namespace.c b/fs/namespace.c
index 3dc283f..277c28a 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -22,6 +22,7 @@
#include <linux/seq_file.h>
#include <linux/mnt_namespace.h>
#include <linux/namei.h>
+#include <linux/nsproxy.h>
#include <linux/security.h>
#include <linux/mount.h>
#include <linux/ramfs.h>
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index 46177cb..b35d2a6 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -30,7 +30,6 @@
#include <linux/nfs_idmap.h>
#include <linux/vfs.h>
#include <linux/namei.h>
-#include <linux/mnt_namespace.h>
#include <linux/security.h>
#include <asm/system.h>
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 607c579..70f36c0 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2042,8 +2042,8 @@
* changes */
invalidate_bdev(sb->s_bdev);
}
- mutex_lock(&inode->i_mutex);
mutex_lock(&dqopt->dqonoff_mutex);
+ mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
if (sb_has_quota_loaded(sb, type)) {
error = -EBUSY;
goto out_lock;
@@ -2094,7 +2094,6 @@
dqopt->files[type] = NULL;
iput(inode);
out_lock:
- mutex_unlock(&dqopt->dqonoff_mutex);
if (oldflags != -1) {
down_write(&dqopt->dqptr_sem);
/* Set the flags back (in the case of accidental quotaon()
@@ -2104,6 +2103,7 @@
up_write(&dqopt->dqptr_sem);
}
mutex_unlock(&inode->i_mutex);
+ mutex_unlock(&dqopt->dqonoff_mutex);
out_fmt:
put_quota_format(fmt);
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index d3aeb06..7adea74 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -24,7 +24,6 @@
#include <linux/exportfs.h>
#include <linux/quotaops.h>
#include <linux/vfs.h>
-#include <linux/mnt_namespace.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/crc32.h>
diff --git a/fs/sync.c b/fs/sync.c
index dd20002..3422ba6 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -112,8 +112,13 @@
mutex_unlock(&mutex);
}
+/*
+ * sync everything. Start out by waking pdflush, because that writes back
+ * all queues in parallel.
+ */
SYSCALL_DEFINE0(sync)
{
+ wakeup_pdflush(0);
sync_filesystems(0);
sync_filesystems(1);
if (unlikely(laptop_mode))
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 9345806..2524714 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -171,6 +171,7 @@
if (count > 0)
*off = offs + count;
+ kfree(temp);
return count;
}
diff --git a/include/linux/elfcore.h b/include/linux/elfcore.h
index 7605c5e..00d6a68 100644
--- a/include/linux/elfcore.h
+++ b/include/linux/elfcore.h
@@ -122,9 +122,10 @@
static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
{
-#ifdef ELF_CORE_COPY_TASK_REGS
-
+#if defined (ELF_CORE_COPY_TASK_REGS)
return ELF_CORE_COPY_TASK_REGS(t, elfregs);
+#elif defined (task_pt_regs)
+ elf_core_copy_regs(elfregs, task_pt_regs(t));
#endif
return 0;
}
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index 9823946..192d1e43 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -127,6 +127,7 @@
struct delayed_work work;
int bm_retries;
int bm_generation;
+ __be32 bm_transaction_data[2];
bool broadcast_channel_allocated;
u32 broadcast_channel;
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index ae3a187..70fdba2 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -78,6 +78,7 @@
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
#define ETH_P_TIPC 0x88CA /* TIPC */
+#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
#define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */
#define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h
new file mode 100644
index 0000000..7964516
--- /dev/null
+++ b/include/linux/input/matrix_keypad.h
@@ -0,0 +1,65 @@
+#ifndef _MATRIX_KEYPAD_H
+#define _MATRIX_KEYPAD_H
+
+#include <linux/types.h>
+#include <linux/input.h>
+
+#define MATRIX_MAX_ROWS 16
+#define MATRIX_MAX_COLS 16
+
+#define KEY(row, col, val) ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\
+ (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\
+ (val & 0xffff))
+
+#define KEY_ROW(k) (((k) >> 24) & 0xff)
+#define KEY_COL(k) (((k) >> 16) & 0xff)
+#define KEY_VAL(k) ((k) & 0xffff)
+
+/**
+ * struct matrix_keymap_data - keymap for matrix keyboards
+ * @keymap: pointer to array of uint32 values encoded with KEY() macro
+ * representing keymap
+ * @keymap_size: number of entries (initialized) in this keymap
+ * @max_keymap_size: maximum size of keymap supported by the device
+ *
+ * This structure is supposed to be used by platform code to supply
+ * keymaps to drivers that implement matrix-like keypads/keyboards.
+ */
+struct matrix_keymap_data {
+ const uint32_t *keymap;
+ unsigned int keymap_size;
+ unsigned int max_keymap_size;
+};
+
+/**
+ * struct matrix_keypad_platform_data - platform-dependent keypad data
+ * @keymap_data: pointer to &matrix_keymap_data
+ * @row_gpios: array of gpio numbers reporesenting rows
+ * @col_gpios: array of gpio numbers reporesenting colums
+ * @num_row_gpios: actual number of row gpios used by device
+ * @num_col_gpios: actual number of col gpios used by device
+ * @col_scan_delay_us: delay, measured in microseconds, that is
+ * needed before we can keypad after activating column gpio
+ * @debounce_ms: debounce interval in milliseconds
+ *
+ * This structure represents platform-specific data that use used by
+ * matrix_keypad driver to perform proper initialization.
+ */
+struct matrix_keypad_platform_data {
+ const struct matrix_keymap_data *keymap_data;
+
+ unsigned int row_gpios[MATRIX_MAX_ROWS];
+ unsigned int col_gpios[MATRIX_MAX_COLS];
+ unsigned int num_row_gpios;
+ unsigned int num_col_gpios;
+
+ unsigned int col_scan_delay_us;
+
+ /* key debounce interval in milli-second */
+ unsigned int debounce_ms;
+
+ bool active_low;
+ bool wakeup;
+};
+
+#endif /* _MATRIX_KEYPAD_H */
diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h
index 3beb259..d74785c 100644
--- a/include/linux/mnt_namespace.h
+++ b/include/linux/mnt_namespace.h
@@ -2,10 +2,9 @@
#define _NAMESPACE_H_
#ifdef __KERNEL__
-#include <linux/mount.h>
-#include <linux/sched.h>
-#include <linux/nsproxy.h>
+#include <linux/path.h>
#include <linux/seq_file.h>
+#include <linux/wait.h>
struct mnt_namespace {
atomic_t count;
@@ -28,14 +27,6 @@
extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *,
struct fs_struct *);
extern void put_mnt_ns(struct mnt_namespace *ns);
-
-static inline void exit_mnt_ns(struct task_struct *p)
-{
- struct mnt_namespace *ns = p->nsproxy->mnt_ns;
- if (ns)
- put_mnt_ns(ns);
-}
-
static inline void get_mnt_ns(struct mnt_namespace *ns)
{
atomic_inc(&ns->count);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d304ddf..115fb7b 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1145,7 +1145,7 @@
/* If you want to know what to call your pci_dev, ask this function.
* Again, it's a wrapper around the generic device.
*/
-static inline const char *pci_name(struct pci_dev *pdev)
+static inline const char *pci_name(const struct pci_dev *pdev)
{
return dev_name(&pdev->dev);
}
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index e73e242..2ce2983 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -99,7 +99,6 @@
#undef RFKILL_STATE_UNBLOCKED
#undef RFKILL_STATE_HARD_BLOCKED
-#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mutex.h>
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 0085d75..16a982e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -498,6 +498,15 @@
.sum_exec_runtime = 0, \
}
+/*
+ * Disable preemption until the scheduler is running.
+ * Reset by start_kernel()->sched_init()->init_idle().
+ *
+ * We include PREEMPT_ACTIVE to avoid cond_resched() from working
+ * before the scheduler is active -- see should_resched().
+ */
+#define INIT_PREEMPT_COUNT (1 + PREEMPT_ACTIVE)
+
/**
* struct thread_group_cputimer - thread group interval timer counts
* @cputime: thread group interval timers.
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 252b245..4be57ab 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -132,6 +132,11 @@
#endif /*__raw_spin_is_contended*/
#endif
+/* The lock does not imply full memory barrier. */
+#ifndef ARCH_HAS_SMP_MB_AFTER_LOCK
+static inline void smp_mb__after_lock(void) { smp_mb(); }
+#endif
+
/**
* spin_unlock_wait - wait until the spinlock gets unlocked
* @lock: the spinlock in question.
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index fa4242c..80de700 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -321,6 +321,8 @@
siginfo_t __user *uinfo,
const struct timespec __user *uts,
size_t sigsetsize);
+asmlinkage long sys_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig,
+ siginfo_t __user *uinfo);
asmlinkage long sys_kill(int pid, int sig);
asmlinkage long sys_tgkill(int tgid, int pid, int sig);
asmlinkage long sys_tkill(int pid, int sig);
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h
index 98a1d8c..99adcdc 100644
--- a/include/linux/sysrq.h
+++ b/include/linux/sysrq.h
@@ -14,6 +14,8 @@
#ifndef _LINUX_SYSRQ_H
#define _LINUX_SYSRQ_H
+#include <linux/errno.h>
+
struct pt_regs;
struct tty_struct;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 8a025d5..95846d9 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -318,6 +318,8 @@
/* see http://www.siliconimaging.com/RGB%20Bayer.htm */
#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */
#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */
+#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */
+
/*
* 10bit raw bayer, expanded to 16 bits
* xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb...
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index 4d7e227..11a4a2d 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -155,6 +155,9 @@
/* module cafe_ccic, just ident 8801 */
V4L2_IDENT_CAFE = 8801,
+ /* module mt9v011, just ident 8243 */
+ V4L2_IDENT_MT9V011 = 8243,
+
/* module tw9910: just ident 9910 */
V4L2_IDENT_TW9910 = 9910,
diff --git a/include/net/sock.h b/include/net/sock.h
index 352f06bb..2c0da92 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -54,6 +54,7 @@
#include <linux/filter.h>
#include <linux/rculist_nulls.h>
+#include <linux/poll.h>
#include <asm/atomic.h>
#include <net/dst.h>
@@ -1241,6 +1242,74 @@
return sk_wmem_alloc_get(sk) || sk_rmem_alloc_get(sk);
}
+/**
+ * sk_has_sleeper - check if there are any waiting processes
+ * @sk: socket
+ *
+ * Returns true if socket has waiting processes
+ *
+ * The purpose of the sk_has_sleeper and sock_poll_wait is to wrap the memory
+ * barrier call. They were added due to the race found within the tcp code.
+ *
+ * Consider following tcp code paths:
+ *
+ * CPU1 CPU2
+ *
+ * sys_select receive packet
+ * ... ...
+ * __add_wait_queue update tp->rcv_nxt
+ * ... ...
+ * tp->rcv_nxt check sock_def_readable
+ * ... {
+ * schedule ...
+ * if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ * wake_up_interruptible(sk->sk_sleep)
+ * ...
+ * }
+ *
+ * The race for tcp fires when the __add_wait_queue changes done by CPU1 stay
+ * in its cache, and so does the tp->rcv_nxt update on CPU2 side. The CPU1
+ * could then endup calling schedule and sleep forever if there are no more
+ * data on the socket.
+ *
+ * The sk_has_sleeper is always called right after a call to read_lock, so we
+ * can use smp_mb__after_lock barrier.
+ */
+static inline int sk_has_sleeper(struct sock *sk)
+{
+ /*
+ * We need to be sure we are in sync with the
+ * add_wait_queue modifications to the wait queue.
+ *
+ * This memory barrier is paired in the sock_poll_wait.
+ */
+ smp_mb__after_lock();
+ return sk->sk_sleep && waitqueue_active(sk->sk_sleep);
+}
+
+/**
+ * sock_poll_wait - place memory barrier behind the poll_wait call.
+ * @filp: file
+ * @wait_address: socket wait queue
+ * @p: poll_table
+ *
+ * See the comments in the sk_has_sleeper function.
+ */
+static inline void sock_poll_wait(struct file *filp,
+ wait_queue_head_t *wait_address, poll_table *p)
+{
+ if (p && wait_address) {
+ poll_wait(filp, wait_address, p);
+ /*
+ * We need to be sure we are in sync with the
+ * socket flags modification.
+ *
+ * This memory barrier is paired in the sk_has_sleeper.
+ */
+ smp_mb();
+ }
+}
+
/*
* Queue a received datagram if it will fit. Stream and sequenced
* protocols can't normally use this as they need to fit buffers in
diff --git a/kernel/exit.c b/kernel/exit.c
index 628d41f..869dc22 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -12,7 +12,6 @@
#include <linux/completion.h>
#include <linux/personality.h>
#include <linux/tty.h>
-#include <linux/mnt_namespace.h>
#include <linux/iocontext.h>
#include <linux/key.h>
#include <linux/security.h>
diff --git a/kernel/fork.c b/kernel/fork.c
index 467746b..bd29592 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -17,7 +17,6 @@
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/completion.h>
-#include <linux/mnt_namespace.h>
#include <linux/personality.h>
#include <linux/mempolicy.h>
#include <linux/sem.h>
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 7e95bed..385c31a 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -24,7 +24,6 @@
#include <linux/unistd.h>
#include <linux/kmod.h>
#include <linux/slab.h>
-#include <linux/mnt_namespace.h>
#include <linux/completion.h>
#include <linux/file.h>
#include <linux/fdtable.h>
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index c0fa54b..16b5739 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -237,13 +237,9 @@
{
struct kprobe_insn_page *kip;
struct hlist_node *pos, *next;
- int safety;
/* Ensure no-one is preepmted on the garbages */
- mutex_unlock(&kprobe_insn_mutex);
- safety = check_safety();
- mutex_lock(&kprobe_insn_mutex);
- if (safety != 0)
+ if (check_safety())
return -EAGAIN;
hlist_for_each_entry_safe(kip, pos, next, &kprobe_insn_pages, hlist) {
diff --git a/kernel/module.c b/kernel/module.c
index 38928fc..0a04983 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2451,9 +2451,9 @@
return ret;
}
if (ret > 0) {
- printk(KERN_WARNING "%s: '%s'->init suspiciously returned %d, "
- "it should follow 0/-E convention\n"
- KERN_WARNING "%s: loading module anyway...\n",
+ printk(KERN_WARNING
+"%s: '%s'->init suspiciously returned %d, it should follow 0/-E convention\n"
+"%s: loading module anyway...\n",
__func__, mod->name, ret,
__func__);
dump_stack();
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index d55a50d..a641eb7 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -2020,7 +2020,7 @@
static void perf_mmap_free_page(unsigned long addr)
{
- struct page *page = virt_to_page(addr);
+ struct page *page = virt_to_page((void *)addr);
page->mapping = NULL;
__free_page(page);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 61c78b2..082c320 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -181,8 +181,8 @@
* interference; SUID, SGID and LSM creds get determined differently
* under ptrace.
*/
- retval = mutex_lock_interruptible(&task->cred_guard_mutex);
- if (retval < 0)
+ retval = -ERESTARTNOINTR;
+ if (mutex_lock_interruptible(&task->cred_guard_mutex))
goto out;
task_lock(task);
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 0dccfbb..7717b95 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -1533,7 +1533,7 @@
int j;
struct rcu_node *rnp;
- printk(KERN_WARNING "Experimental hierarchical RCU implementation.\n");
+ printk(KERN_INFO "Hierarchical RCU implementation.\n");
#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
printk(KERN_INFO "RCU-based detection of stalled CPUs is enabled.\n");
#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
@@ -1546,7 +1546,6 @@
rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE, (void *)(long)i);
/* Register notifier for non-boot CPUs */
register_cpu_notifier(&rcu_nb);
- printk(KERN_WARNING "Experimental hierarchical RCU init done.\n");
}
module_param(blimit, int, 0);
diff --git a/kernel/sched.c b/kernel/sched.c
index 7c9098d..01f55ad 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -6541,6 +6541,11 @@
return 0;
}
+static inline int should_resched(void)
+{
+ return need_resched() && !(preempt_count() & PREEMPT_ACTIVE);
+}
+
static void __cond_resched(void)
{
#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
@@ -6560,8 +6565,7 @@
int __sched _cond_resched(void)
{
- if (need_resched() && !(preempt_count() & PREEMPT_ACTIVE) &&
- system_state == SYSTEM_RUNNING) {
+ if (should_resched()) {
__cond_resched();
return 1;
}
@@ -6579,12 +6583,12 @@
*/
int cond_resched_lock(spinlock_t *lock)
{
- int resched = need_resched() && system_state == SYSTEM_RUNNING;
+ int resched = should_resched();
int ret = 0;
if (spin_needbreak(lock) || resched) {
spin_unlock(lock);
- if (resched && need_resched())
+ if (resched)
__cond_resched();
else
cpu_relax();
@@ -6599,7 +6603,7 @@
{
BUG_ON(!in_softirq());
- if (need_resched() && system_state == SYSTEM_RUNNING) {
+ if (should_resched()) {
local_bh_enable();
__cond_resched();
local_bh_disable();
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 1551f47..019f380 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -226,13 +226,13 @@
the timings of the initcalls and traces key events and the identity
of tasks that can cause boot delays, such as context-switches.
- Its aim is to be parsed by the /scripts/bootgraph.pl tool to
+ Its aim is to be parsed by the scripts/bootgraph.pl tool to
produce pretty graphics about boot inefficiencies, giving a visual
representation of the delays during initcalls - but the raw
/debug/tracing/trace text output is readable too.
- You must pass in ftrace=initcall to the kernel command line
- to enable this on bootup.
+ You must pass in initcall_debug and ftrace=initcall to the kernel
+ command line to enable this on bootup.
config TRACE_BRANCH_PROFILING
bool
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index f3716bf..bce9e01 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3160,10 +3160,10 @@
ret = proc_dointvec(table, write, file, buffer, lenp, ppos);
- if (ret || !write || (last_ftrace_enabled == ftrace_enabled))
+ if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled))
goto out;
- last_ftrace_enabled = ftrace_enabled;
+ last_ftrace_enabled = !!ftrace_enabled;
if (ftrace_enabled) {
diff --git a/kernel/trace/trace_event_types.h b/kernel/trace/trace_event_types.h
index 5e32e37..6db005e 100644
--- a/kernel/trace/trace_event_types.h
+++ b/kernel/trace/trace_event_types.h
@@ -26,6 +26,9 @@
ftrace_graph_ret_entry, ignore,
TRACE_STRUCT(
TRACE_FIELD(unsigned long, ret.func, func)
+ TRACE_FIELD(unsigned long long, ret.calltime, calltime)
+ TRACE_FIELD(unsigned long long, ret.rettime, rettime)
+ TRACE_FIELD(unsigned long, ret.overrun, overrun)
TRACE_FIELD(int, ret.depth, depth)
),
TP_RAW_FMT("<-- %lx (%d)")
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index 7938f3a..e0c2545 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -27,8 +27,7 @@
{
int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len;
- s->buffer[len] = 0;
- seq_puts(m, s->buffer);
+ seq_write(m, s->buffer, len);
trace_seq_init(s);
}
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index 2d7aebd..e644af9 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -326,10 +326,10 @@
ret = proc_dointvec(table, write, file, buffer, lenp, ppos);
if (ret || !write ||
- (last_stack_tracer_enabled == stack_tracer_enabled))
+ (last_stack_tracer_enabled == !!stack_tracer_enabled))
goto out;
- last_stack_tracer_enabled = stack_tracer_enabled;
+ last_stack_tracer_enabled = !!stack_tracer_enabled;
if (stack_tracer_enabled)
register_ftrace_function(&trace_ops);
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 3b93129..65b0d99 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -716,7 +716,7 @@
for (i = 0; i < HASH_SIZE; ++i) {
INIT_LIST_HEAD(&dma_entry_hash[i].list);
- dma_entry_hash[i].lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&dma_entry_hash[i].lock);
}
if (dma_debug_fs_init() != 0) {
@@ -856,22 +856,21 @@
"stack [addr=%p]\n", addr);
}
-static inline bool overlap(void *addr, u64 size, void *start, void *end)
+static inline bool overlap(void *addr, unsigned long len, void *start, void *end)
{
- void *addr2 = (char *)addr + size;
+ unsigned long a1 = (unsigned long)addr;
+ unsigned long b1 = a1 + len;
+ unsigned long a2 = (unsigned long)start;
+ unsigned long b2 = (unsigned long)end;
- return ((addr >= start && addr < end) ||
- (addr2 >= start && addr2 < end) ||
- ((addr < start) && (addr2 >= end)));
+ return !(b1 <= a2 || a1 >= b2);
}
-static void check_for_illegal_area(struct device *dev, void *addr, u64 size)
+static void check_for_illegal_area(struct device *dev, void *addr, unsigned long len)
{
- if (overlap(addr, size, _text, _etext) ||
- overlap(addr, size, __start_rodata, __end_rodata))
- err_printk(dev, NULL, "DMA-API: device driver maps "
- "memory from kernel text or rodata "
- "[addr=%p] [size=%llu]\n", addr, size);
+ if (overlap(addr, len, _text, _etext) ||
+ overlap(addr, len, __start_rodata, __end_rodata))
+ err_printk(dev, NULL, "DMA-API: device driver maps memory from kernel text or rodata [addr=%p] [len=%lu]\n", addr, len);
}
static void check_sync(struct device *dev,
@@ -969,7 +968,8 @@
entry->type = dma_debug_single;
if (!PageHighMem(page)) {
- void *addr = ((char *)page_address(page)) + offset;
+ void *addr = page_address(page) + offset;
+
check_for_stack(dev, addr);
check_for_illegal_area(dev, addr, size);
}
diff --git a/mm/filemap.c b/mm/filemap.c
index 2239671..ccea3b6 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2272,6 +2272,7 @@
pagefault_enable();
flush_dcache_page(page);
+ mark_page_accessed(page);
status = a_ops->write_end(file, mapping, pos, bytes, copied,
page, fsdata);
if (unlikely(status < 0))
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e0f2cdf..ad7cd1c 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1983,7 +1983,7 @@
unsigned long alloc_end = addr + (PAGE_SIZE << order);
unsigned long used = addr + PAGE_ALIGN(size);
- split_page(virt_to_page(addr), order);
+ split_page(virt_to_page((void *)addr), order);
while (used < alloc_end) {
free_page(used);
used += PAGE_SIZE;
diff --git a/mm/slab.c b/mm/slab.c
index e74a16e..7b5d4de 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1544,9 +1544,6 @@
}
g_cpucache_up = EARLY;
-
- /* Annotate slab for lockdep -- annotate the malloc caches */
- init_lock_keys();
}
void __init kmem_cache_init_late(void)
@@ -1563,6 +1560,9 @@
/* Done! */
g_cpucache_up = FULL;
+ /* Annotate slab for lockdep -- annotate the malloc caches */
+ init_lock_keys();
+
/*
* Register a cpu startup notifier callback that initializes
* cpu_cache_get for all new cpus
@@ -2547,7 +2547,7 @@
}
if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU))
- synchronize_rcu();
+ rcu_barrier();
__kmem_cache_destroy(cachep);
mutex_unlock(&cache_chain_mutex);
diff --git a/mm/slob.c b/mm/slob.c
index c78742d..9641da3 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -595,6 +595,8 @@
void kmem_cache_destroy(struct kmem_cache *c)
{
kmemleak_free(c);
+ if (c->flags & SLAB_DESTROY_BY_RCU)
+ rcu_barrier();
slob_free(c, sizeof(struct kmem_cache));
}
EXPORT_SYMBOL(kmem_cache_destroy);
diff --git a/mm/slub.c b/mm/slub.c
index 819f056..a9201d8 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2595,6 +2595,8 @@
*/
void kmem_cache_destroy(struct kmem_cache *s)
{
+ if (s->flags & SLAB_DESTROY_BY_RCU)
+ rcu_barrier();
down_write(&slub_lock);
s->refcount--;
if (!s->refcount) {
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index a2a1814..8c2588e 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -735,12 +735,14 @@
if (!*p)
continue;
token = match_token(p, tokens, args);
- r = match_int(&args[0], &option);
- if (r < 0) {
- P9_DPRINTK(P9_DEBUG_ERROR,
- "integer field, but no integer?\n");
- ret = r;
- continue;
+ if (token != Opt_err) {
+ r = match_int(&args[0], &option);
+ if (r < 0) {
+ P9_DPRINTK(P9_DEBUG_ERROR,
+ "integer field, but no integer?\n");
+ ret = r;
+ continue;
+ }
}
switch (token) {
case Opt_port:
diff --git a/net/atm/common.c b/net/atm/common.c
index c1c9793..8c4d843 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -92,7 +92,7 @@
static void vcc_def_wakeup(struct sock *sk)
{
read_lock(&sk->sk_callback_lock);
- if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ if (sk_has_sleeper(sk))
wake_up(sk->sk_sleep);
read_unlock(&sk->sk_callback_lock);
}
@@ -110,7 +110,7 @@
read_lock(&sk->sk_callback_lock);
if (vcc_writable(sk)) {
- if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ if (sk_has_sleeper(sk))
wake_up_interruptible(sk->sk_sleep);
sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
@@ -594,7 +594,7 @@
struct atm_vcc *vcc;
unsigned int mask;
- poll_wait(file, sk->sk_sleep, wait);
+ sock_poll_wait(file, sk->sk_sleep, wait);
mask = 0;
vcc = ATM_SD(sock);
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 58abee1..b0fe692 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -712,7 +712,7 @@
struct sock *sk = sock->sk;
unsigned int mask;
- poll_wait(file, sk->sk_sleep, wait);
+ sock_poll_wait(file, sk->sk_sleep, wait);
mask = 0;
/* exceptional events? */
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 9675f31..df30feb 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -740,7 +740,7 @@
np->name);
break;
}
- cond_resched();
+ msleep(1);
}
/* If carrier appears to come up instantly, we don't
diff --git a/net/core/sock.c b/net/core/sock.c
index b0ba569..6354863 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1715,7 +1715,7 @@
static void sock_def_wakeup(struct sock *sk)
{
read_lock(&sk->sk_callback_lock);
- if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ if (sk_has_sleeper(sk))
wake_up_interruptible_all(sk->sk_sleep);
read_unlock(&sk->sk_callback_lock);
}
@@ -1723,7 +1723,7 @@
static void sock_def_error_report(struct sock *sk)
{
read_lock(&sk->sk_callback_lock);
- if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ if (sk_has_sleeper(sk))
wake_up_interruptible_poll(sk->sk_sleep, POLLERR);
sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR);
read_unlock(&sk->sk_callback_lock);
@@ -1732,7 +1732,7 @@
static void sock_def_readable(struct sock *sk, int len)
{
read_lock(&sk->sk_callback_lock);
- if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ if (sk_has_sleeper(sk))
wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN |
POLLRDNORM | POLLRDBAND);
sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
@@ -1747,7 +1747,7 @@
* progress. --DaveM
*/
if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) {
- if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ if (sk_has_sleeper(sk))
wake_up_interruptible_sync_poll(sk->sk_sleep, POLLOUT |
POLLWRNORM | POLLWRBAND);
diff --git a/net/dccp/output.c b/net/dccp/output.c
index c0e88c1..c96119f 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -196,7 +196,7 @@
{
read_lock(&sk->sk_callback_lock);
- if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ if (sk_has_sleeper(sk))
wake_up_interruptible(sk->sk_sleep);
/* Should agree with poll, otherwise some programs break */
if (sock_writeable(sk))
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 314a1b5..94ca8ea 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -311,7 +311,7 @@
unsigned int mask;
struct sock *sk = sock->sk;
- poll_wait(file, sk->sk_sleep, wait);
+ sock_poll_wait(file, sk->sk_sleep, wait);
if (sk->sk_state == DCCP_LISTEN)
return inet_csk_listen_poll(sk);
diff --git a/net/dsa/mv88e6xxx.c b/net/dsa/mv88e6xxx.c
index 4e4d8b5..efe661a 100644
--- a/net/dsa/mv88e6xxx.c
+++ b/net/dsa/mv88e6xxx.c
@@ -418,7 +418,7 @@
int i;
for (i = 0; i < 10; i++) {
- ret = REG_READ(REG_GLOBAL2, 0x1d);
+ ret = REG_READ(REG_GLOBAL, 0x1d);
if ((ret & 0x8000) == 0)
return 0;
}
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 00a54b2..63c2fa7 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -316,8 +316,8 @@
static const int halve_threshold = 25;
static const int inflate_threshold = 50;
-static const int halve_threshold_root = 8;
-static const int inflate_threshold_root = 15;
+static const int halve_threshold_root = 15;
+static const int inflate_threshold_root = 25;
static void __alias_free_mem(struct rcu_head *head)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 7870a53..9114524 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -339,7 +339,7 @@
struct sock *sk = sock->sk;
struct tcp_sock *tp = tcp_sk(sk);
- poll_wait(file, sk->sk_sleep, wait);
+ sock_poll_wait(file, sk->sk_sleep, wait);
if (sk->sk_state == TCP_LISTEN)
return inet_csk_listen_poll(sk);
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 60d918c..0071ee6 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -136,7 +136,8 @@
case IPPROTO_TCP:
case IPPROTO_SCTP:
case IPPROTO_DCCP:
- if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
+ if (xprth + 4 < skb->data ||
+ pskb_may_pull(skb, xprth + 4 - skb->data)) {
__be16 *ports = (__be16 *)xprth;
fl->fl_ip_sport = ports[!!reverse];
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3883b40..43b3c9f 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1916,8 +1916,32 @@
update_lft = 1;
else if (stored_lft <= MIN_VALID_LIFETIME) {
/* valid_lft <= stored_lft is always true */
- /* XXX: IPsec */
- update_lft = 0;
+ /*
+ * RFC 4862 Section 5.5.3e:
+ * "Note that the preferred lifetime of
+ * the corresponding address is always
+ * reset to the Preferred Lifetime in
+ * the received Prefix Information
+ * option, regardless of whether the
+ * valid lifetime is also reset or
+ * ignored."
+ *
+ * So if the preferred lifetime in
+ * this advertisement is different
+ * than what we have stored, but the
+ * valid lifetime is invalid, just
+ * reset prefered_lft.
+ *
+ * We must set the valid lifetime
+ * to the stored lifetime since we'll
+ * be updating the timestamp below,
+ * else we'll set it back to the
+ * minumum.
+ */
+ if (prefered_lft != ifp->prefered_lft) {
+ valid_lft = stored_lft;
+ update_lft = 1;
+ }
} else {
valid_lft = MIN_VALID_LIFETIME;
if (valid_lft < prefered_lft)
@@ -3085,7 +3109,7 @@
spin_unlock(&ifp->lock);
continue;
} else if (age >= ifp->prefered_lft) {
- /* jiffies - ifp->tsamp > age >= ifp->prefered_lft */
+ /* jiffies - ifp->tstamp > age >= ifp->prefered_lft */
int deprecate = 0;
if (!(ifp->flags&IFA_F_DEPRECATED)) {
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index b4b16a4..3a3c677 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -157,7 +157,8 @@
ipv6_addr_copy(&fl->fl6_dst, reverse ? &hdr->saddr : &hdr->daddr);
ipv6_addr_copy(&fl->fl6_src, reverse ? &hdr->daddr : &hdr->saddr);
- while (pskb_may_pull(skb, nh + offset + 1 - skb->data)) {
+ while (nh + offset + 1 < skb->data ||
+ pskb_may_pull(skb, nh + offset + 1 - skb->data)) {
nh = skb_network_header(skb);
exthdr = (struct ipv6_opt_hdr *)(nh + offset);
@@ -177,7 +178,8 @@
case IPPROTO_TCP:
case IPPROTO_SCTP:
case IPPROTO_DCCP:
- if (!onlyproto && pskb_may_pull(skb, nh + offset + 4 - skb->data)) {
+ if (!onlyproto && (nh + offset + 4 < skb->data ||
+ pskb_may_pull(skb, nh + offset + 4 - skb->data))) {
__be16 *ports = (__be16 *)exthdr;
fl->fl_ip_sport = ports[!!reverse];
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 6be5f92..49c15b4 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -306,7 +306,7 @@
static void iucv_sock_wake_msglim(struct sock *sk)
{
read_lock(&sk->sk_callback_lock);
- if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ if (sk_has_sleeper(sk))
wake_up_interruptible_all(sk->sk_sleep);
sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
read_unlock(&sk->sk_callback_lock);
@@ -1256,7 +1256,7 @@
struct sock *sk = sock->sk;
unsigned int mask = 0;
- poll_wait(file, sk->sk_sleep, wait);
+ sock_poll_wait(file, sk->sk_sleep, wait);
if (sk->sk_state == IUCV_LISTEN)
return iucv_accept_poll(sk);
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 003cb47..f49ef28 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -637,7 +637,7 @@
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct mesh_preq_queue *preq_node;
- preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_KERNEL);
+ preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC);
if (!preq_node) {
printk(KERN_DEBUG "Mesh HWMP: could not allocate PREQ node\n");
return;
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index b218b98..37771ab 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -66,7 +66,7 @@
for (i = rix; i >= 0; i--)
if (mi->r[i].rix == rix)
break;
- WARN_ON(mi->r[i].rix != rix);
+ WARN_ON(i < 0);
return i;
}
@@ -181,6 +181,9 @@
break;
ndx = rix_to_ndx(mi, ar[i].idx);
+ if (ndx < 0)
+ continue;
+
mi->r[ndx].attempts += ar[i].count;
if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0))
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index eac5e7b..bfe493e 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -63,7 +63,7 @@
_enter("%p", sk);
read_lock(&sk->sk_callback_lock);
if (rxrpc_writable(sk)) {
- if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ if (sk_has_sleeper(sk))
wake_up_interruptible(sk->sk_sleep);
sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
}
@@ -588,7 +588,7 @@
unsigned int mask;
struct sock *sk = sock->sk;
- poll_wait(file, sk->sk_sleep, wait);
+ sock_poll_wait(file, sk->sk_sleep, wait);
mask = 0;
/* the socket is readable if there are any messages waiting on the Rx
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 35ba035..971890d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -6652,21 +6652,6 @@
finish_wait(sk->sk_sleep, &wait);
}
-static void sctp_sock_rfree_frag(struct sk_buff *skb)
-{
- struct sk_buff *frag;
-
- if (!skb->data_len)
- goto done;
-
- /* Don't forget the fragments. */
- skb_walk_frags(skb, frag)
- sctp_sock_rfree_frag(frag);
-
-done:
- sctp_sock_rfree(skb);
-}
-
static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk)
{
struct sk_buff *frag;
@@ -6776,7 +6761,6 @@
sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) {
event = sctp_skb2event(skb);
if (event->asoc == assoc) {
- sctp_sock_rfree_frag(skb);
__skb_unlink(skb, &oldsk->sk_receive_queue);
__skb_queue_tail(&newsk->sk_receive_queue, skb);
sctp_skb_set_owner_r_frag(skb, newsk);
@@ -6807,7 +6791,6 @@
sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
event = sctp_skb2event(skb);
if (event->asoc == assoc) {
- sctp_sock_rfree_frag(skb);
__skb_unlink(skb, &oldsp->pd_lobby);
__skb_queue_tail(queue, skb);
sctp_skb_set_owner_r_frag(skb, newsk);
@@ -6822,15 +6805,11 @@
}
- sctp_skb_for_each(skb, &assoc->ulpq.reasm, tmp) {
- sctp_sock_rfree_frag(skb);
+ sctp_skb_for_each(skb, &assoc->ulpq.reasm, tmp)
sctp_skb_set_owner_r_frag(skb, newsk);
- }
- sctp_skb_for_each(skb, &assoc->ulpq.lobby, tmp) {
- sctp_sock_rfree_frag(skb);
+ sctp_skb_for_each(skb, &assoc->ulpq.lobby, tmp)
sctp_skb_set_owner_r_frag(skb, newsk);
- }
/* Set the type of socket to indicate that it is peeled off from the
* original UDP-style socket or created with the accept() call on a
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 36d4e44..fc3ebb9 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -315,7 +315,7 @@
{
read_lock(&sk->sk_callback_lock);
if (unix_writable(sk)) {
- if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ if (sk_has_sleeper(sk))
wake_up_interruptible_sync(sk->sk_sleep);
sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
}
@@ -1985,7 +1985,7 @@
struct sock *sk = sock->sk;
unsigned int mask;
- poll_wait(file, sk->sk_sleep, wait);
+ sock_poll_wait(file, sk->sk_sleep, wait);
mask = 0;
/* exceptional events? */
@@ -2022,7 +2022,7 @@
struct sock *sk = sock->sk, *other;
unsigned int mask, writable;
- poll_wait(file, sk->sk_sleep, wait);
+ sock_poll_wait(file, sk->sk_sleep, wait);
mask = 0;
/* exceptional events? */
@@ -2053,7 +2053,7 @@
other = unix_peer_get(sk);
if (other) {
if (unix_peer(other) != sk) {
- poll_wait(file, &unix_sk(other)->peer_wait,
+ sock_poll_wait(file, &unix_sk(other)->peer_wait,
wait);
if (unix_recvq_full(other))
writable = 0;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 241bddd..43bdb13 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -447,6 +447,7 @@
rdev = __cfg80211_drv_from_info(info);
if (IS_ERR(rdev)) {
+ mutex_unlock(&cfg80211_mutex);
result = PTR_ERR(rdev);
goto unlock;
}
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index e95b638..f8e71b3 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -366,7 +366,6 @@
found = rb_find_bss(dev, res);
if (found) {
- kref_get(&found->ref);
found->pub.beacon_interval = res->pub.beacon_interval;
found->pub.tsf = res->pub.tsf;
found->pub.signal = res->pub.signal;
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index e617aca..61b8ab3 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -644,7 +644,7 @@
int err;
int capture=1;
- /* snd_printk("KERN_DEBUG snd_p16v_pcm called. device=%d\n", device); */
+ /* snd_printk(KERN_DEBUG "snd_p16v_pcm called. device=%d\n", device); */
emu->p16v_device_offset = device;
if (rpcm)
*rpcm = NULL;
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index dd1ab61..9efd27f 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -296,9 +296,10 @@
static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
struct snd_usX2Y_substream *subs, struct urb *urb)
{
- snd_printk(KERN_ERR "Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
- KERN_ERR "Most propably some urb of usb-frame %i is still missing.\n"
- KERN_ERR "Cause could be too long delays in usb-hcd interrupt handling.\n",
+ snd_printk(KERN_ERR
+"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
+"Most propably some urb of usb-frame %i is still missing.\n"
+"Cause could be too long delays in usb-hcd interrupt handling.\n",
usb_get_current_frame_number(usX2Y->chip.dev),
subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 9c6d0ae3..7822b3d 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -164,7 +164,7 @@
# CFLAGS and LDFLAGS are for the users to override from the command line.
-CFLAGS = $(M64) -ggdb3 -Wall -Wstrict-prototypes -Wmissing-declarations -Wmissing-prototypes -std=gnu99 -Wdeclaration-after-statement -Werror -O6
+CFLAGS = $(M64) -ggdb3 -Wall -Wextra -Wstrict-prototypes -Wmissing-declarations -Wmissing-prototypes -std=gnu99 -Wdeclaration-after-statement -Werror -O6
LDFLAGS = -lpthread -lrt -lelf -lm
ALL_CFLAGS = $(CFLAGS)
ALL_LDFLAGS = $(LDFLAGS)
@@ -223,7 +223,7 @@
# Those must not be GNU-specific; they are shared with perl/ which may
# be built by a different compiler. (Note that this is an artifact now
# but it still might be nice to keep that distinction.)
-BASIC_CFLAGS =
+BASIC_CFLAGS = -Iutil/include
BASIC_LDFLAGS =
# Guard against environment variables
@@ -289,10 +289,11 @@
LIB_FILE=libperf.a
LIB_H += ../../include/linux/perf_counter.h
+LIB_H += ../../include/linux/rbtree.h
+LIB_H += ../../include/linux/list.h
+LIB_H += util/include/linux/list.h
LIB_H += perf.h
LIB_H += util/types.h
-LIB_H += util/list.h
-LIB_H += util/rbtree.h
LIB_H += util/levenshtein.h
LIB_H += util/parse-options.h
LIB_H += util/parse-events.h
@@ -305,6 +306,7 @@
LIB_H += util/run-command.h
LIB_H += util/sigchain.h
LIB_H += util/symbol.h
+LIB_H += util/module.h
LIB_H += util/color.h
LIB_OBJS += util/abspath.o
@@ -328,6 +330,7 @@
LIB_OBJS += util/wrapper.o
LIB_OBJS += util/sigchain.o
LIB_OBJS += util/symbol.o
+LIB_OBJS += util/module.o
LIB_OBJS += util/color.o
LIB_OBJS += util/pager.o
LIB_OBJS += util/header.o
@@ -381,12 +384,6 @@
endif
endif
-ifdef ZLIB_PATH
- BASIC_CFLAGS += -I$(ZLIB_PATH)/include
- EXTLIBS += -L$(ZLIB_PATH)/$(lib) $(CC_LD_DYNPATH)$(ZLIB_PATH)/$(lib)
-endif
-EXTLIBS += -lz
-
ifdef NEEDS_SOCKET
EXTLIBS += -lsocket
endif
@@ -697,6 +694,9 @@
util/config.o: util/config.c PERF-CFLAGS
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+util/rbtree.o: ../../lib/rbtree.c PERF-CFLAGS
+ $(QUIET_CC)$(CC) -o util/rbtree.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+
perf-%$X: %.o $(PERFLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 722c0f5..5f9eefe 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -10,9 +10,9 @@
#include "util/util.h"
#include "util/color.h"
-#include "util/list.h"
+#include <linux/list.h>
#include "util/cache.h"
-#include "util/rbtree.h"
+#include <linux/rbtree.h>
#include "util/symbol.h"
#include "util/string.h"
@@ -25,10 +25,6 @@
#define SHOW_USER 2
#define SHOW_HV 4
-#define MIN_GREEN 0.5
-#define MIN_RED 5.0
-
-
static char const *input_name = "perf.data";
static char *vmlinux = "vmlinux";
@@ -43,6 +39,10 @@
static int verbose;
+static int modules;
+
+static int full_paths;
+
static int print_line;
static unsigned long page_size;
@@ -160,7 +160,7 @@
static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip)
{
- return dso__find_symbol(kernel_dso, ip);
+ return dso__find_symbol(dso, ip);
}
static int load_kernel(void)
@@ -171,8 +171,8 @@
if (!kernel_dso)
return -1;
- err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose);
- if (err) {
+ err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules);
+ if (err <= 0) {
dso__delete(kernel_dso);
kernel_dso = NULL;
} else
@@ -203,7 +203,7 @@
return ip - map->start + map->pgoff;
}
-static u64 vdso__map_ip(struct map *map, u64 ip)
+static u64 vdso__map_ip(struct map *map __used, u64 ip)
{
return ip;
}
@@ -600,7 +600,7 @@
static int sort_dimension__add(char *tok)
{
- int i;
+ unsigned int i;
for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
struct sort_dimension *sd = &sort_dimensions[i];
@@ -1043,24 +1043,6 @@
return 0;
}
-static char *get_color(double percent)
-{
- char *color = PERF_COLOR_NORMAL;
-
- /*
- * We color high-overhead entries in red, mid-overhead
- * entries in green - and keep the low overhead places
- * normal:
- */
- if (percent >= MIN_RED)
- color = PERF_COLOR_RED;
- else {
- if (percent > MIN_GREEN)
- color = PERF_COLOR_GREEN;
- }
- return color;
-}
-
static int
parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
{
@@ -1069,7 +1051,7 @@
static const char *prev_color;
unsigned int offset;
size_t line_len;
- u64 line_ip;
+ s64 line_ip;
int ret;
char *c;
@@ -1122,7 +1104,7 @@
} else if (sym->hist_sum)
percent = 100.0 * hits / sym->hist_sum;
- color = get_color(percent);
+ color = get_percent_color(percent);
/*
* Also color the filename and line if needed, with
@@ -1258,7 +1240,7 @@
sym_ext = rb_entry(node, struct sym_ext, node);
percent = sym_ext->percent;
- color = get_color(percent);
+ color = get_percent_color(percent);
path = sym_ext->path;
color_fprintf(stdout, color, " %7.2f %s", percent, path);
@@ -1268,19 +1250,25 @@
static void annotate_sym(struct dso *dso, struct symbol *sym)
{
- char *filename = dso->name;
+ char *filename = dso->name, *d_filename;
u64 start, end, len;
char command[PATH_MAX*2];
FILE *file;
if (!filename)
return;
- if (dso == kernel_dso)
+ if (sym->module)
+ filename = sym->module->path;
+ else if (dso == kernel_dso)
filename = vmlinux;
start = sym->obj_start;
if (!start)
start = sym->start;
+ if (full_paths)
+ d_filename = filename;
+ else
+ d_filename = basename(filename);
end = start + sym->end - sym->start + 1;
len = sym->end - sym->start;
@@ -1291,13 +1279,14 @@
}
printf("\n\n------------------------------------------------\n");
- printf(" Percent | Source code & Disassembly of %s\n", filename);
+ printf(" Percent | Source code & Disassembly of %s\n", d_filename);
printf("------------------------------------------------\n");
if (verbose >= 2)
printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name);
- sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", (u64)start, (u64)end, filename);
+ sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s",
+ (u64)start, (u64)end, filename, filename);
if (verbose >= 3)
printf("doing: %s\n", command);
@@ -1428,7 +1417,7 @@
head += size;
- if (offset + head < stat.st_size)
+ if (offset + head < (unsigned long)stat.st_size)
goto more;
rc = EXIT_SUCCESS;
@@ -1472,8 +1461,12 @@
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"),
OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
+ OPT_BOOLEAN('m', "modules", &modules,
+ "load module symbols - WARNING: use only with -k and LIVE kernel"),
OPT_BOOLEAN('l', "print-line", &print_line,
"print matching source lines (may be slow)"),
+ OPT_BOOLEAN('P', "full-paths", &full_paths,
+ "Don't shorten the displayed pathnames"),
OPT_END()
};
@@ -1492,7 +1485,7 @@
free(str);
}
-int cmd_annotate(int argc, const char **argv, const char *prefix)
+int cmd_annotate(int argc, const char **argv, const char *prefix __used)
{
symbol__init();
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 0f32dc3..2599d86 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -3,6 +3,7 @@
*
* Builtin help command
*/
+#include "perf.h"
#include "util/cache.h"
#include "builtin.h"
#include "util/exec_cmd.h"
@@ -277,7 +278,7 @@
void list_common_cmds_help(void)
{
- int i, longest = 0;
+ unsigned int i, longest = 0;
for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
if (longest < strlen(common_cmds[i].name))
@@ -415,9 +416,10 @@
open_html(page_path.buf);
}
-int cmd_help(int argc, const char **argv, const char *prefix)
+int cmd_help(int argc, const char **argv, const char *prefix __used)
{
const char *alias;
+
load_command_list("perf-", &main_cmds, &other_cmds);
perf_config(perf_help_config, NULL);
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
index fe60e37..f990fa8 100644
--- a/tools/perf/builtin-list.c
+++ b/tools/perf/builtin-list.c
@@ -13,7 +13,7 @@
#include "util/parse-options.h"
#include "util/parse-events.h"
-int cmd_list(int argc, const char **argv, const char *prefix)
+int cmd_list(int argc __used, const char **argv __used, const char *prefix __used)
{
print_events();
return 0;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index d18546f..4ef78a5 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -294,7 +294,7 @@
while (1) {
char bf[BUFSIZ], *pbf = bf;
struct mmap_event mmap_ev = {
- .header.type = PERF_EVENT_MMAP,
+ .header = { .type = PERF_EVENT_MMAP },
};
int n;
size_t size;
@@ -650,7 +650,7 @@
OPT_END()
};
-int cmd_record(int argc, const char **argv, const char *prefix)
+int cmd_record(int argc, const char **argv, const char *prefix __used)
{
int counter;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 135b783..4e5cc26 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -10,9 +10,9 @@
#include "util/util.h"
#include "util/color.h"
-#include "util/list.h"
+#include <linux/list.h>
#include "util/cache.h"
-#include "util/rbtree.h"
+#include <linux/rbtree.h>
#include "util/symbol.h"
#include "util/string.h"
#include "util/callchain.h"
@@ -46,6 +46,8 @@
static int verbose;
#define eprintf(x...) do { if (verbose) fprintf(stderr, x); } while (0)
+static int modules;
+
static int full_paths;
static unsigned long page_size;
@@ -56,8 +58,17 @@
static regex_t parent_regex;
static int exclude_other = 1;
+
+static char callchain_default_opt[] = "fractal,0.5";
+
static int callchain;
+static
+struct callchain_param callchain_param = {
+ .mode = CHAIN_GRAPH_ABS,
+ .min_percent = 0.5
+};
+
static u64 sample_type;
struct ip_event {
@@ -121,6 +132,7 @@
static LIST_HEAD(dsos);
static struct dso *kernel_dso;
static struct dso *vdso;
+static struct dso *hypervisor_dso;
static void dsos__add(struct dso *dso)
{
@@ -176,7 +188,7 @@
static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip)
{
- return dso__find_symbol(kernel_dso, ip);
+ return dso__find_symbol(dso, ip);
}
static int load_kernel(void)
@@ -187,8 +199,8 @@
if (!kernel_dso)
return -1;
- err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose);
- if (err) {
+ err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules);
+ if (err <= 0) {
dso__delete(kernel_dso);
kernel_dso = NULL;
} else
@@ -202,6 +214,11 @@
dsos__add(vdso);
+ hypervisor_dso = dso__new("[hypervisor]", 0);
+ if (!hypervisor_dso)
+ return -1;
+ dsos__add(hypervisor_dso);
+
return err;
}
@@ -233,7 +250,7 @@
return ip - map->start + map->pgoff;
}
-static u64 vdso__map_ip(struct map *map, u64 ip)
+static u64 vdso__map_ip(struct map *map __used, u64 ip)
{
return ip;
}
@@ -640,7 +657,11 @@
if (self->sym) {
ret += fprintf(fp, "[%c] %s",
- self->dso == kernel_dso ? 'k' : '.', self->sym->name);
+ self->dso == kernel_dso ? 'k' :
+ self->dso == hypervisor_dso ? 'h' : '.', self->sym->name);
+
+ if (self->sym->module)
+ ret += fprintf(fp, "\t[%s]", self->sym->module->name);
} else {
ret += fprintf(fp, "%#016llx", (u64)self->ip);
}
@@ -705,7 +726,7 @@
static int sort_dimension__add(char *tok)
{
- int i;
+ unsigned int i;
for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
struct sort_dimension *sd = &sort_dimensions[i];
@@ -775,8 +796,109 @@
return cmp;
}
+static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask)
+{
+ int i;
+ size_t ret = 0;
+
+ ret += fprintf(fp, "%s", " ");
+
+ for (i = 0; i < depth; i++)
+ if (depth_mask & (1 << i))
+ ret += fprintf(fp, "| ");
+ else
+ ret += fprintf(fp, " ");
+
+ ret += fprintf(fp, "\n");
+
+ return ret;
+}
static size_t
-callchain__fprintf(FILE *fp, struct callchain_node *self, u64 total_samples)
+ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, int depth,
+ int depth_mask, int count, u64 total_samples,
+ int hits)
+{
+ int i;
+ size_t ret = 0;
+
+ ret += fprintf(fp, "%s", " ");
+ for (i = 0; i < depth; i++) {
+ if (depth_mask & (1 << i))
+ ret += fprintf(fp, "|");
+ else
+ ret += fprintf(fp, " ");
+ if (!count && i == depth - 1) {
+ double percent;
+
+ percent = hits * 100.0 / total_samples;
+ ret += percent_color_fprintf(fp, "--%2.2f%%-- ", percent);
+ } else
+ ret += fprintf(fp, "%s", " ");
+ }
+ if (chain->sym)
+ ret += fprintf(fp, "%s\n", chain->sym->name);
+ else
+ ret += fprintf(fp, "%p\n", (void *)(long)chain->ip);
+
+ return ret;
+}
+
+static size_t
+callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
+ u64 total_samples, int depth, int depth_mask)
+{
+ struct rb_node *node, *next;
+ struct callchain_node *child;
+ struct callchain_list *chain;
+ int new_depth_mask = depth_mask;
+ u64 new_total;
+ size_t ret = 0;
+ int i;
+
+ if (callchain_param.mode == CHAIN_GRAPH_REL)
+ new_total = self->cumul_hit;
+ else
+ new_total = total_samples;
+
+ node = rb_first(&self->rb_root);
+ while (node) {
+ child = rb_entry(node, struct callchain_node, rb_node);
+
+ /*
+ * The depth mask manages the output of pipes that show
+ * the depth. We don't want to keep the pipes of the current
+ * level for the last child of this depth
+ */
+ next = rb_next(node);
+ if (!next)
+ new_depth_mask &= ~(1 << (depth - 1));
+
+ /*
+ * But we keep the older depth mask for the line seperator
+ * to keep the level link until we reach the last child
+ */
+ ret += ipchain__fprintf_graph_line(fp, depth, depth_mask);
+ i = 0;
+ list_for_each_entry(chain, &child->val, list) {
+ if (chain->ip >= PERF_CONTEXT_MAX)
+ continue;
+ ret += ipchain__fprintf_graph(fp, chain, depth,
+ new_depth_mask, i++,
+ new_total,
+ child->cumul_hit);
+ }
+ ret += callchain__fprintf_graph(fp, child, new_total,
+ depth + 1,
+ new_depth_mask | (1 << depth));
+ node = next;
+ }
+
+ return ret;
+}
+
+static size_t
+callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
+ u64 total_samples)
{
struct callchain_list *chain;
size_t ret = 0;
@@ -784,11 +906,18 @@
if (!self)
return 0;
- ret += callchain__fprintf(fp, self->parent, total_samples);
+ ret += callchain__fprintf_flat(fp, self->parent, total_samples);
- list_for_each_entry(chain, &self->val, list)
- ret += fprintf(fp, " %p\n", (void *)chain->ip);
+ list_for_each_entry(chain, &self->val, list) {
+ if (chain->ip >= PERF_CONTEXT_MAX)
+ continue;
+ if (chain->sym)
+ ret += fprintf(fp, " %s\n", chain->sym->name);
+ else
+ ret += fprintf(fp, " %p\n",
+ (void *)(long)chain->ip);
+ }
return ret;
}
@@ -807,8 +936,19 @@
chain = rb_entry(rb_node, struct callchain_node, rb_node);
percent = chain->hit * 100.0 / total_samples;
- ret += fprintf(fp, " %6.2f%%\n", percent);
- ret += callchain__fprintf(fp, chain, total_samples);
+ switch (callchain_param.mode) {
+ case CHAIN_FLAT:
+ ret += percent_color_fprintf(fp, " %6.2f%%\n",
+ percent);
+ ret += callchain__fprintf_flat(fp, chain, total_samples);
+ break;
+ case CHAIN_GRAPH_ABS: /* Falldown */
+ case CHAIN_GRAPH_REL:
+ ret += callchain__fprintf_graph(fp, chain,
+ total_samples, 1, 1);
+ default:
+ break;
+ }
ret += fprintf(fp, "\n");
rb_node = rb_next(rb_node);
}
@@ -826,25 +966,10 @@
if (exclude_other && !self->parent)
return 0;
- if (total_samples) {
- double percent = self->count * 100.0 / total_samples;
- char *color = PERF_COLOR_NORMAL;
-
- /*
- * We color high-overhead entries in red, mid-overhead
- * entries in green - and keep the low overhead places
- * normal:
- */
- if (percent >= 5.0) {
- color = PERF_COLOR_RED;
- } else {
- if (percent >= 0.5)
- color = PERF_COLOR_GREEN;
- }
-
- ret = color_fprintf(fp, color, " %6.2f%%",
+ if (total_samples)
+ ret = percent_color_fprintf(fp, " %6.2f%%",
(self->count * 100.0) / total_samples);
- } else
+ else
ret = fprintf(fp, "%12Ld ", self->count);
list_for_each_entry(se, &hist_entry__sort_list, list) {
@@ -923,6 +1048,58 @@
return 0;
}
+static struct symbol **
+resolve_callchain(struct thread *thread, struct map *map __used,
+ struct ip_callchain *chain, struct hist_entry *entry)
+{
+ u64 context = PERF_CONTEXT_MAX;
+ struct symbol **syms = NULL;
+ unsigned int i;
+
+ if (callchain) {
+ syms = calloc(chain->nr, sizeof(*syms));
+ if (!syms) {
+ fprintf(stderr, "Can't allocate memory for symbols\n");
+ exit(-1);
+ }
+ }
+
+ for (i = 0; i < chain->nr; i++) {
+ u64 ip = chain->ips[i];
+ struct dso *dso = NULL;
+ struct symbol *sym;
+
+ if (ip >= PERF_CONTEXT_MAX) {
+ context = ip;
+ continue;
+ }
+
+ switch (context) {
+ case PERF_CONTEXT_HV:
+ dso = hypervisor_dso;
+ break;
+ case PERF_CONTEXT_KERNEL:
+ dso = kernel_dso;
+ break;
+ default:
+ break;
+ }
+
+ sym = resolve_symbol(thread, NULL, &dso, &ip);
+
+ if (sym) {
+ if (sort__has_parent && call__match(sym) &&
+ !entry->parent)
+ entry->parent = sym;
+ if (!callchain)
+ break;
+ syms[i] = sym;
+ }
+ }
+
+ return syms;
+}
+
/*
* collect histogram counts
*/
@@ -935,6 +1112,7 @@
struct rb_node **p = &hist.rb_node;
struct rb_node *parent = NULL;
struct hist_entry *he;
+ struct symbol **syms = NULL;
struct hist_entry entry = {
.thread = thread,
.map = map,
@@ -948,36 +1126,8 @@
};
int cmp;
- if (sort__has_parent && chain) {
- u64 context = PERF_CONTEXT_MAX;
- int i;
-
- for (i = 0; i < chain->nr; i++) {
- u64 ip = chain->ips[i];
- struct dso *dso = NULL;
- struct symbol *sym;
-
- if (ip >= PERF_CONTEXT_MAX) {
- context = ip;
- continue;
- }
-
- switch (context) {
- case PERF_CONTEXT_KERNEL:
- dso = kernel_dso;
- break;
- default:
- break;
- }
-
- sym = resolve_symbol(thread, NULL, &dso, &ip);
-
- if (sym && call__match(sym)) {
- entry.parent = sym;
- break;
- }
- }
- }
+ if ((sort__has_parent || callchain) && chain)
+ syms = resolve_callchain(thread, map, chain, &entry);
while (*p != NULL) {
parent = *p;
@@ -987,8 +1137,10 @@
if (!cmp) {
he->count += count;
- if (callchain)
- append_chain(&he->callchain, chain);
+ if (callchain) {
+ append_chain(&he->callchain, chain, syms);
+ free(syms);
+ }
return 0;
}
@@ -1004,7 +1156,8 @@
*he = entry;
if (callchain) {
callchain_init(&he->callchain);
- append_chain(&he->callchain, chain);
+ append_chain(&he->callchain, chain, syms);
+ free(syms);
}
rb_link_node(&he->rb_node, parent, p);
rb_insert_color(&he->rb_node, &hist);
@@ -1076,14 +1229,15 @@
static struct rb_root output_hists;
-static void output__insert_entry(struct hist_entry *he)
+static void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits)
{
struct rb_node **p = &output_hists.rb_node;
struct rb_node *parent = NULL;
struct hist_entry *iter;
if (callchain)
- sort_chain_to_rbtree(&he->sorted_chain, &he->callchain);
+ callchain_param.sort(&he->sorted_chain, &he->callchain,
+ min_callchain_hits, &callchain_param);
while (*p != NULL) {
parent = *p;
@@ -1099,11 +1253,14 @@
rb_insert_color(&he->rb_node, &output_hists);
}
-static void output__resort(void)
+static void output__resort(u64 total_samples)
{
struct rb_node *next;
struct hist_entry *n;
struct rb_root *tree = &hist;
+ u64 min_callchain_hits;
+
+ min_callchain_hits = total_samples * (callchain_param.min_percent / 100);
if (sort__need_collapse)
tree = &collapse_hists;
@@ -1115,7 +1272,7 @@
next = rb_next(&n->rb_node);
rb_erase(&n->rb_node, tree);
- output__insert_entry(n);
+ output__insert_entry(n, min_callchain_hits);
}
}
@@ -1141,7 +1298,7 @@
fprintf(fp, "# ........");
list_for_each_entry(se, &hist_entry__sort_list, list) {
- int i;
+ unsigned int i;
if (exclude_other && (se == &sort_parent))
continue;
@@ -1213,6 +1370,7 @@
struct map *map = NULL;
void *more_data = event->ip.__more_data;
struct ip_callchain *chain = NULL;
+ int cpumode;
if (sample_type & PERF_SAMPLE_PERIOD) {
period = *(u64 *)more_data;
@@ -1228,7 +1386,7 @@
(long long)period);
if (sample_type & PERF_SAMPLE_CALLCHAIN) {
- int i;
+ unsigned int i;
chain = (void *)more_data;
@@ -1256,7 +1414,9 @@
if (comm_list && !strlist__has_entry(comm_list, thread->comm))
return 0;
- if (event->header.misc & PERF_EVENT_MISC_KERNEL) {
+ cpumode = event->header.misc & PERF_EVENT_MISC_CPUMODE_MASK;
+
+ if (cpumode == PERF_EVENT_MISC_KERNEL) {
show = SHOW_KERNEL;
level = 'k';
@@ -1264,7 +1424,7 @@
dprintf(" ...... dso: %s\n", dso->name);
- } else if (event->header.misc & PERF_EVENT_MISC_USER) {
+ } else if (cpumode == PERF_EVENT_MISC_USER) {
show = SHOW_USER;
level = '.';
@@ -1272,6 +1432,9 @@
} else {
show = SHOW_HV;
level = 'H';
+
+ dso = hypervisor_dso;
+
dprintf(" ...... dso: [hypervisor]\n");
}
@@ -1534,9 +1697,19 @@
sample_type = perf_header__sample_type();
- if (sort__has_parent && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
- fprintf(stderr, "selected --sort parent, but no callchain data\n");
- exit(-1);
+ if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
+ if (sort__has_parent) {
+ fprintf(stderr, "selected --sort parent, but no"
+ " callchain data. Did you call"
+ " perf record without -g?\n");
+ exit(-1);
+ }
+ if (callchain) {
+ fprintf(stderr, "selected -c but no callchain data."
+ " Did you call perf record without"
+ " -g?\n");
+ exit(-1);
+ }
}
if (load_kernel() < 0) {
@@ -1619,7 +1792,7 @@
if (offset + head >= header->data_offset + header->data_size)
goto done;
- if (offset + head < stat.st_size)
+ if (offset + head < (unsigned long)stat.st_size)
goto more;
done:
@@ -1643,12 +1816,58 @@
dsos__fprintf(stdout);
collapse__resort();
- output__resort();
+ output__resort(total);
output__fprintf(stdout, total);
return rc;
}
+static int
+parse_callchain_opt(const struct option *opt __used, const char *arg,
+ int unset __used)
+{
+ char *tok;
+ char *endptr;
+
+ callchain = 1;
+
+ if (!arg)
+ return 0;
+
+ tok = strtok((char *)arg, ",");
+ if (!tok)
+ return -1;
+
+ /* get the output mode */
+ if (!strncmp(tok, "graph", strlen(arg)))
+ callchain_param.mode = CHAIN_GRAPH_ABS;
+
+ else if (!strncmp(tok, "flat", strlen(arg)))
+ callchain_param.mode = CHAIN_FLAT;
+
+ else if (!strncmp(tok, "fractal", strlen(arg)))
+ callchain_param.mode = CHAIN_GRAPH_REL;
+
+ else
+ return -1;
+
+ /* get the min percentage */
+ tok = strtok(NULL, ",");
+ if (!tok)
+ goto setup;
+
+ callchain_param.min_percent = strtod(tok, &endptr);
+ if (tok == endptr)
+ return -1;
+
+setup:
+ if (register_callchain_param(&callchain_param) < 0) {
+ fprintf(stderr, "Can't register callchain params\n");
+ return -1;
+ }
+ return 0;
+}
+
static const char * const report_usage[] = {
"perf report [<options>] <command>",
NULL
@@ -1662,6 +1881,8 @@
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"),
OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
+ OPT_BOOLEAN('m', "modules", &modules,
+ "load module symbols - WARNING: use only with -k and LIVE kernel"),
OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
"sort by key(s): pid, comm, dso, symbol, parent"),
OPT_BOOLEAN('P', "full-paths", &full_paths,
@@ -1670,7 +1891,9 @@
"regex filter to identify parent, see: '--sort parent'"),
OPT_BOOLEAN('x', "exclude-other", &exclude_other,
"Only display entries with parent-match"),
- OPT_BOOLEAN('c', "callchain", &callchain, "Display callchains"),
+ OPT_CALLBACK_DEFAULT('c', "callchain", NULL, "output_type,min_percent",
+ "Display callchains using output_type and min percent threshold. "
+ "Default: flat,0", &parse_callchain_opt, callchain_default_opt),
OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]",
"only consider symbols in these dsos"),
OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]",
@@ -1708,7 +1931,7 @@
}
}
-int cmd_report(int argc, const char **argv, const char *prefix)
+int cmd_report(int argc, const char **argv, const char *prefix __used)
{
symbol__init();
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 2e03524..27921a8 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -64,7 +64,7 @@
static int system_wide = 0;
static int verbose = 0;
-static int nr_cpus = 0;
+static unsigned int nr_cpus = 0;
static int run_idx = 0;
static int run_count = 1;
@@ -96,6 +96,10 @@
static u64 runtime_cycles_avg;
static u64 runtime_cycles_noise;
+#define MATCH_EVENT(t, c, counter) \
+ (attrs[counter].type == PERF_TYPE_##t && \
+ attrs[counter].config == PERF_COUNT_##c)
+
#define ERR_PERF_OPEN \
"Error: counter %d, sys_perf_counter_open() syscall returned with %d (%s)\n"
@@ -108,7 +112,8 @@
PERF_FORMAT_TOTAL_TIME_RUNNING;
if (system_wide) {
- int cpu;
+ unsigned int cpu;
+
for (cpu = 0; cpu < nr_cpus; cpu++) {
fd[cpu][counter] = sys_perf_counter_open(attr, -1, cpu, -1, 0);
if (fd[cpu][counter] < 0 && verbose)
@@ -132,13 +137,8 @@
*/
static inline int nsec_counter(int counter)
{
- if (attrs[counter].type != PERF_TYPE_SOFTWARE)
- return 0;
-
- if (attrs[counter].config == PERF_COUNT_SW_CPU_CLOCK)
- return 1;
-
- if (attrs[counter].config == PERF_COUNT_SW_TASK_CLOCK)
+ if (MATCH_EVENT(SOFTWARE, SW_CPU_CLOCK, counter) ||
+ MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter))
return 1;
return 0;
@@ -150,8 +150,8 @@
static void read_counter(int counter)
{
u64 *count, single_count[3];
- ssize_t res;
- int cpu, nv;
+ unsigned int cpu;
+ size_t res, nv;
int scaled;
count = event_res[run_idx][counter];
@@ -165,6 +165,7 @@
res = read(fd[cpu][counter], single_count, nv * sizeof(u64));
assert(res == nv * sizeof(u64));
+
close(fd[cpu][counter]);
fd[cpu][counter] = -1;
@@ -192,15 +193,13 @@
/*
* Save the full runtime - to allow normalization during printout:
*/
- if (attrs[counter].type == PERF_TYPE_SOFTWARE &&
- attrs[counter].config == PERF_COUNT_SW_TASK_CLOCK)
+ if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter))
runtime_nsecs[run_idx] = count[0];
- if (attrs[counter].type == PERF_TYPE_HARDWARE &&
- attrs[counter].config == PERF_COUNT_HW_CPU_CYCLES)
+ if (MATCH_EVENT(HARDWARE, HW_CPU_CYCLES, counter))
runtime_cycles[run_idx] = count[0];
}
-static int run_perf_stat(int argc, const char **argv)
+static int run_perf_stat(int argc __used, const char **argv)
{
unsigned long long t0, t1;
int status = 0;
@@ -240,7 +239,8 @@
/*
* Wait until the parent tells us to go.
*/
- read(go_pipe[0], &buf, 1);
+ if (read(go_pipe[0], &buf, 1) == -1)
+ perror("unable to read pipe");
execvp(argv[0], (char **)argv);
@@ -253,7 +253,8 @@
*/
close(child_ready_pipe[1]);
close(go_pipe[0]);
- read(child_ready_pipe[0], &buf, 1);
+ if (read(child_ready_pipe[0], &buf, 1) == -1)
+ perror("unable to read pipe");
close(child_ready_pipe[0]);
for (counter = 0; counter < nr_counters; counter++)
@@ -290,9 +291,7 @@
fprintf(stderr, " %14.6f %-24s", msecs, event_name(counter));
- if (attrs[counter].type == PERF_TYPE_SOFTWARE &&
- attrs[counter].config == PERF_COUNT_SW_TASK_CLOCK) {
-
+ if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) {
if (walltime_nsecs_avg)
fprintf(stderr, " # %10.3f CPUs ",
(double)count[0] / (double)walltime_nsecs_avg);
@@ -305,9 +304,7 @@
fprintf(stderr, " %14Ld %-24s", count[0], event_name(counter));
if (runtime_cycles_avg &&
- attrs[counter].type == PERF_TYPE_HARDWARE &&
- attrs[counter].config == PERF_COUNT_HW_INSTRUCTIONS) {
-
+ MATCH_EVENT(HARDWARE, HW_INSTRUCTIONS, counter)) {
fprintf(stderr, " # %10.3f IPC ",
(double)count[0] / (double)runtime_cycles_avg);
} else {
@@ -390,7 +387,7 @@
event_res_avg[j]+1, event_res[i][j]+1);
update_avg("counter/2", j,
event_res_avg[j]+2, event_res[i][j]+2);
- if (event_scaled[i][j] != -1)
+ if (event_scaled[i][j] != (u64)-1)
update_avg("scaled", j,
event_scaled_avg + j, event_scaled[i]+j);
else
@@ -510,7 +507,7 @@
OPT_END()
};
-int cmd_stat(int argc, const char **argv, const char *prefix)
+int cmd_stat(int argc, const char **argv, const char *prefix __used)
{
int status;
@@ -528,7 +525,7 @@
nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
assert(nr_cpus <= MAX_NR_CPUS);
- assert(nr_cpus >= 0);
+ assert((int)nr_cpus >= 0);
/*
* We dont want to block the signals - that would cause
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index cf0d21f..95d5c0a 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -23,7 +23,7 @@
#include "util/symbol.h"
#include "util/color.h"
#include "util/util.h"
-#include "util/rbtree.h"
+#include <linux/rbtree.h>
#include "util/parse-options.h"
#include "util/parse-events.h"
@@ -66,6 +66,7 @@
static unsigned int mmap_pages = 16;
static int freq = 0;
static int verbose = 0;
+static char *vmlinux = NULL;
static char *sym_filter;
static unsigned long filter_start;
@@ -238,7 +239,6 @@
for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
struct sym_entry *syme = rb_entry(nd, struct sym_entry, rb_node);
struct symbol *sym = (struct symbol *)(syme + 1);
- char *color = PERF_COLOR_NORMAL;
double pcnt;
if (++printed > print_entries || syme->snap_count < count_filter)
@@ -247,29 +247,20 @@
pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) /
sum_ksamples));
- /*
- * We color high-overhead entries in red, mid-overhead
- * entries in green - and keep the low overhead places
- * normal:
- */
- if (pcnt >= 5.0) {
- color = PERF_COLOR_RED;
- } else {
- if (pcnt >= 0.5)
- color = PERF_COLOR_GREEN;
- }
-
if (nr_counters == 1)
printf("%20.2f - ", syme->weight);
else
printf("%9.1f %10ld - ", syme->weight, syme->snap_count);
- color_fprintf(stdout, color, "%4.1f%%", pcnt);
- printf(" - %016llx : %s\n", sym->start, sym->name);
+ percent_color_fprintf(stdout, "%4.1f%%", pcnt);
+ printf(" - %016llx : %s", sym->start, sym->name);
+ if (sym->module)
+ printf("\t[%s]", sym->module->name);
+ printf("\n");
}
}
-static void *display_thread(void *arg)
+static void *display_thread(void *arg __used)
{
struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
int delay_msecs = delay_secs * 1000;
@@ -286,11 +277,31 @@
return NULL;
}
+/* Tag samples to be skipped. */
+static const char *skip_symbols[] = {
+ "default_idle",
+ "cpu_idle",
+ "enter_idle",
+ "exit_idle",
+ "mwait_idle",
+ "ppc64_runlatch_off",
+ "pseries_dedicated_idle_sleep",
+ NULL
+};
+
static int symbol_filter(struct dso *self, struct symbol *sym)
{
static int filter_match;
struct sym_entry *syme;
const char *name = sym->name;
+ int i;
+
+ /*
+ * ppc64 uses function descriptors and appends a '.' to the
+ * start of every instruction address. Remove it.
+ */
+ if (name[0] == '.')
+ name++;
if (!strcmp(name, "_text") ||
!strcmp(name, "_etext") ||
@@ -302,13 +313,12 @@
return 1;
syme = dso__sym_priv(self, sym);
- /* Tag samples to be skipped. */
- if (!strcmp("default_idle", name) ||
- !strcmp("cpu_idle", name) ||
- !strcmp("enter_idle", name) ||
- !strcmp("exit_idle", name) ||
- !strcmp("mwait_idle", name))
- syme->skip = 1;
+ for (i = 0; skip_symbols[i]; i++) {
+ if (!strcmp(skip_symbols[i], name)) {
+ syme->skip = 1;
+ break;
+ }
+ }
if (filter_match == 1) {
filter_end = sym->start;
@@ -340,12 +350,13 @@
{
struct rb_node *node;
struct symbol *sym;
+ int modules = vmlinux ? 1 : 0;
kernel_dso = dso__new("[kernel]", sizeof(struct sym_entry));
if (kernel_dso == NULL)
return -1;
- if (dso__load_kernel(kernel_dso, NULL, symbol_filter, 1) != 0)
+ if (dso__load_kernel(kernel_dso, vmlinux, symbol_filter, verbose, modules) <= 0)
goto out_delete_dso;
node = rb_first(&kernel_dso->syms);
@@ -407,7 +418,7 @@
struct mmap_data {
int counter;
void *base;
- unsigned int mask;
+ int mask;
unsigned int prev;
};
@@ -661,6 +672,7 @@
"system-wide collection from all CPUs"),
OPT_INTEGER('C', "CPU", &profile_cpu,
"CPU to profile on"),
+ OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
OPT_INTEGER('m', "mmap-pages", &mmap_pages,
"number of mmap data pages"),
OPT_INTEGER('r', "realtime", &realtime_prio,
@@ -675,7 +687,7 @@
"put the counters into a counter group"),
OPT_STRING('s', "sym-filter", &sym_filter, "pattern",
"only display symbols matchig this pattern"),
- OPT_BOOLEAN('z', "zero", &group,
+ OPT_BOOLEAN('z', "zero", &zero,
"zero history across updates"),
OPT_INTEGER('F', "freq", &freq,
"profile at this frequency"),
@@ -686,10 +698,12 @@
OPT_END()
};
-int cmd_top(int argc, const char **argv, const char *prefix)
+int cmd_top(int argc, const char **argv, const char *prefix __used)
{
int counter;
+ symbol__init();
+
page_size = sysconf(_SC_PAGE_SIZE);
argc = parse_options(argc, argv, options, top_usage, 0);
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 4eb7259..c565678 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -229,9 +229,6 @@
use_pager = 1;
commit_pager_choice();
- if (p->option & NEED_WORK_TREE)
- /* setup_work_tree() */;
-
status = p->fn(argc, argv, prefix);
if (status)
return status & 0xff;
@@ -266,7 +263,7 @@
{ "annotate", cmd_annotate, 0 },
{ "version", cmd_version, 0 },
};
- int i;
+ unsigned int i;
static const char ext[] = STRIP_EXTENSION;
if (sizeof(ext) > 1) {
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index d3042a6..63e67cc 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -68,6 +68,8 @@
#define __user
#define asmlinkage
+#define __used __attribute__((__unused__))
+
#define unlikely(x) __builtin_expect(!!(x), 0)
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
diff --git a/tools/perf/util/alias.c b/tools/perf/util/alias.c
index 9b3dd2b..b8144e8 100644
--- a/tools/perf/util/alias.c
+++ b/tools/perf/util/alias.c
@@ -3,7 +3,7 @@
static const char *alias_key;
static char *alias_val;
-static int alias_lookup_cb(const char *k, const char *v, void *cb)
+static int alias_lookup_cb(const char *k, const char *v, void *cb __used)
{
if (!prefixcmp(k, "alias.") && !strcmp(k+6, alias_key)) {
if (!v)
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 393d614..161d5f4 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -3,6 +3,7 @@
#include "util.h"
#include "strbuf.h"
+#include "../perf.h"
#define PERF_DIR_ENVIRONMENT "PERF_DIR"
#define PERF_WORK_TREE_ENVIRONMENT "PERF_WORK_TREE"
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index ad3c285..9d3c814 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -4,6 +4,9 @@
* Handle the callchains from the stream in an ad-hoc radix tree and then
* sort them in an rbtree.
*
+ * Using a radix for code path provides a fast retrieval and factorizes
+ * memory use. Also that lets us use the paths in a hierarchical graph view.
+ *
*/
#include <stdlib.h>
@@ -13,8 +16,12 @@
#include "callchain.h"
+#define chain_for_each_child(child, parent) \
+ list_for_each_entry(child, &parent->children, brothers)
-static void rb_insert_callchain(struct rb_root *root, struct callchain_node *chain)
+static void
+rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
+ enum chain_mode mode)
{
struct rb_node **p = &root->rb_node;
struct rb_node *parent = NULL;
@@ -24,32 +31,125 @@
parent = *p;
rnode = rb_entry(parent, struct callchain_node, rb_node);
- if (rnode->hit < chain->hit)
- p = &(*p)->rb_left;
- else
- p = &(*p)->rb_right;
+ switch (mode) {
+ case CHAIN_FLAT:
+ if (rnode->hit < chain->hit)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ break;
+ case CHAIN_GRAPH_ABS: /* Falldown */
+ case CHAIN_GRAPH_REL:
+ if (rnode->cumul_hit < chain->cumul_hit)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ break;
+ default:
+ break;
+ }
}
rb_link_node(&chain->rb_node, parent, p);
rb_insert_color(&chain->rb_node, root);
}
+static void
+__sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node,
+ u64 min_hit)
+{
+ struct callchain_node *child;
+
+ chain_for_each_child(child, node)
+ __sort_chain_flat(rb_root, child, min_hit);
+
+ if (node->hit && node->hit >= min_hit)
+ rb_insert_callchain(rb_root, node, CHAIN_FLAT);
+}
+
/*
* Once we get every callchains from the stream, we can now
* sort them by hit
*/
-void sort_chain_to_rbtree(struct rb_root *rb_root, struct callchain_node *node)
+static void
+sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node,
+ u64 min_hit, struct callchain_param *param __used)
+{
+ __sort_chain_flat(rb_root, node, min_hit);
+}
+
+static void __sort_chain_graph_abs(struct callchain_node *node,
+ u64 min_hit)
{
struct callchain_node *child;
- list_for_each_entry(child, &node->children, brothers)
- sort_chain_to_rbtree(rb_root, child);
+ node->rb_root = RB_ROOT;
- if (node->hit)
- rb_insert_callchain(rb_root, node);
+ chain_for_each_child(child, node) {
+ __sort_chain_graph_abs(child, min_hit);
+ if (child->cumul_hit >= min_hit)
+ rb_insert_callchain(&node->rb_root, child,
+ CHAIN_GRAPH_ABS);
+ }
}
-static struct callchain_node *create_child(struct callchain_node *parent)
+static void
+sort_chain_graph_abs(struct rb_root *rb_root, struct callchain_node *chain_root,
+ u64 min_hit, struct callchain_param *param __used)
+{
+ __sort_chain_graph_abs(chain_root, min_hit);
+ rb_root->rb_node = chain_root->rb_root.rb_node;
+}
+
+static void __sort_chain_graph_rel(struct callchain_node *node,
+ double min_percent)
+{
+ struct callchain_node *child;
+ u64 min_hit;
+
+ node->rb_root = RB_ROOT;
+ min_hit = node->cumul_hit * min_percent / 100.0;
+
+ chain_for_each_child(child, node) {
+ __sort_chain_graph_rel(child, min_percent);
+ if (child->cumul_hit >= min_hit)
+ rb_insert_callchain(&node->rb_root, child,
+ CHAIN_GRAPH_REL);
+ }
+}
+
+static void
+sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_node *chain_root,
+ u64 min_hit __used, struct callchain_param *param)
+{
+ __sort_chain_graph_rel(chain_root, param->min_percent);
+ rb_root->rb_node = chain_root->rb_root.rb_node;
+}
+
+int register_callchain_param(struct callchain_param *param)
+{
+ switch (param->mode) {
+ case CHAIN_GRAPH_ABS:
+ param->sort = sort_chain_graph_abs;
+ break;
+ case CHAIN_GRAPH_REL:
+ param->sort = sort_chain_graph_rel;
+ break;
+ case CHAIN_FLAT:
+ param->sort = sort_chain_flat;
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Create a child for a parent. If inherit_children, then the new child
+ * will become the new parent of it's parent children
+ */
+static struct callchain_node *
+create_child(struct callchain_node *parent, bool inherit_children)
{
struct callchain_node *new;
@@ -61,91 +161,147 @@
new->parent = parent;
INIT_LIST_HEAD(&new->children);
INIT_LIST_HEAD(&new->val);
+
+ if (inherit_children) {
+ struct callchain_node *next;
+
+ list_splice(&parent->children, &new->children);
+ INIT_LIST_HEAD(&parent->children);
+
+ chain_for_each_child(next, new)
+ next->parent = new;
+ }
list_add_tail(&new->brothers, &parent->children);
return new;
}
+/*
+ * Fill the node with callchain values
+ */
static void
-fill_node(struct callchain_node *node, struct ip_callchain *chain, int start)
+fill_node(struct callchain_node *node, struct ip_callchain *chain,
+ int start, struct symbol **syms)
{
- int i;
+ unsigned int i;
for (i = start; i < chain->nr; i++) {
struct callchain_list *call;
- call = malloc(sizeof(*chain));
+ call = malloc(sizeof(*call));
if (!call) {
perror("not enough memory for the code path tree");
return;
}
call->ip = chain->ips[i];
+ call->sym = syms[i];
list_add_tail(&call->list, &node->val);
}
- node->val_nr = i - start;
-}
-
-static void add_child(struct callchain_node *parent, struct ip_callchain *chain)
-{
- struct callchain_node *new;
-
- new = create_child(parent);
- fill_node(new, chain, parent->val_nr);
-
- new->hit = 1;
+ node->val_nr = chain->nr - start;
+ if (!node->val_nr)
+ printf("Warning: empty node in callchain tree\n");
}
static void
-split_add_child(struct callchain_node *parent, struct ip_callchain *chain,
- struct callchain_list *to_split, int idx)
+add_child(struct callchain_node *parent, struct ip_callchain *chain,
+ int start, struct symbol **syms)
{
struct callchain_node *new;
- /* split */
- new = create_child(parent);
- list_move_tail(&to_split->list, &new->val);
- new->hit = parent->hit;
- parent->hit = 0;
- parent->val_nr = idx;
+ new = create_child(parent, false);
+ fill_node(new, chain, start, syms);
- /* create the new one */
- add_child(parent, chain);
+ new->cumul_hit = new->hit = 1;
+}
+
+/*
+ * Split the parent in two parts (a new child is created) and
+ * give a part of its callchain to the created child.
+ * Then create another child to host the given callchain of new branch
+ */
+static void
+split_add_child(struct callchain_node *parent, struct ip_callchain *chain,
+ struct callchain_list *to_split, int idx_parents, int idx_local,
+ struct symbol **syms)
+{
+ struct callchain_node *new;
+ struct list_head *old_tail;
+ unsigned int idx_total = idx_parents + idx_local;
+
+ /* split */
+ new = create_child(parent, true);
+
+ /* split the callchain and move a part to the new child */
+ old_tail = parent->val.prev;
+ list_del_range(&to_split->list, old_tail);
+ new->val.next = &to_split->list;
+ new->val.prev = old_tail;
+ to_split->list.prev = &new->val;
+ old_tail->next = &new->val;
+
+ /* split the hits */
+ new->hit = parent->hit;
+ new->cumul_hit = parent->cumul_hit;
+ new->val_nr = parent->val_nr - idx_local;
+ parent->val_nr = idx_local;
+
+ /* create a new child for the new branch if any */
+ if (idx_total < chain->nr) {
+ parent->hit = 0;
+ add_child(parent, chain, idx_total, syms);
+ } else {
+ parent->hit = 1;
+ }
}
static int
__append_chain(struct callchain_node *root, struct ip_callchain *chain,
- int start);
+ unsigned int start, struct symbol **syms);
-static int
-__append_chain_children(struct callchain_node *root, struct ip_callchain *chain)
+static void
+__append_chain_children(struct callchain_node *root, struct ip_callchain *chain,
+ struct symbol **syms, unsigned int start)
{
struct callchain_node *rnode;
/* lookup in childrens */
- list_for_each_entry(rnode, &root->children, brothers) {
- int ret = __append_chain(rnode, chain, root->val_nr);
+ chain_for_each_child(rnode, root) {
+ unsigned int ret = __append_chain(rnode, chain, start, syms);
+
if (!ret)
- return 0;
+ goto cumul;
}
- return -1;
+ /* nothing in children, add to the current node */
+ add_child(root, chain, start, syms);
+
+cumul:
+ root->cumul_hit++;
}
static int
__append_chain(struct callchain_node *root, struct ip_callchain *chain,
- int start)
+ unsigned int start, struct symbol **syms)
{
struct callchain_list *cnode;
- int i = start;
+ unsigned int i = start;
bool found = false;
- /* lookup in the current node */
+ /*
+ * Lookup in the current node
+ * If we have a symbol, then compare the start to match
+ * anywhere inside a function.
+ */
list_for_each_entry(cnode, &root->val, list) {
- if (cnode->ip != chain->ips[i++])
+ if (i == chain->nr)
+ break;
+ if (cnode->sym && syms[i]) {
+ if (cnode->sym->start != syms[i]->start)
+ break;
+ } else if (cnode->ip != chain->ips[i])
break;
if (!found)
found = true;
- if (i == chain->nr)
- break;
+ i++;
}
/* matches not, relay on the parent */
@@ -153,22 +309,27 @@
return -1;
/* we match only a part of the node. Split it and add the new chain */
- if (i < root->val_nr) {
- split_add_child(root, chain, cnode, i);
+ if (i - start < root->val_nr) {
+ split_add_child(root, chain, cnode, start, i - start, syms);
return 0;
}
/* we match 100% of the path, increment the hit */
- if (i == root->val_nr) {
+ if (i - start == root->val_nr && i == chain->nr) {
root->hit++;
+ root->cumul_hit++;
+
return 0;
}
- return __append_chain_children(root, chain);
+ /* We match the node and still have a part remaining */
+ __append_chain_children(root, chain, syms, i);
+
+ return 0;
}
-void append_chain(struct callchain_node *root, struct ip_callchain *chain)
+void append_chain(struct callchain_node *root, struct ip_callchain *chain,
+ struct symbol **syms)
{
- if (__append_chain_children(root, chain) == -1)
- add_child(root, chain);
+ __append_chain_children(root, chain, syms, 0);
}
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index fa1cd2f..7812122 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -2,22 +2,42 @@
#define __PERF_CALLCHAIN_H
#include "../perf.h"
-#include "list.h"
-#include "rbtree.h"
+#include <linux/list.h>
+#include <linux/rbtree.h>
+#include "symbol.h"
+enum chain_mode {
+ CHAIN_FLAT,
+ CHAIN_GRAPH_ABS,
+ CHAIN_GRAPH_REL
+};
struct callchain_node {
struct callchain_node *parent;
struct list_head brothers;
- struct list_head children;
- struct list_head val;
- struct rb_node rb_node;
- int val_nr;
- int hit;
+ struct list_head children;
+ struct list_head val;
+ struct rb_node rb_node; /* to sort nodes in an rbtree */
+ struct rb_root rb_root; /* sorted tree of children */
+ unsigned int val_nr;
+ u64 hit;
+ u64 cumul_hit; /* hit + hits of children */
+};
+
+struct callchain_param;
+
+typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_node *,
+ u64, struct callchain_param *);
+
+struct callchain_param {
+ enum chain_mode mode;
+ double min_percent;
+ sort_chain_func_t sort;
};
struct callchain_list {
- unsigned long ip;
+ u64 ip;
+ struct symbol *sym;
struct list_head list;
};
@@ -28,6 +48,7 @@
INIT_LIST_HEAD(&node->val);
}
-void append_chain(struct callchain_node *root, struct ip_callchain *chain);
-void sort_chain_to_rbtree(struct rb_root *rb_root, struct callchain_node *node);
+int register_callchain_param(struct callchain_param *param);
+void append_chain(struct callchain_node *root, struct ip_callchain *chain,
+ struct symbol **syms);
#endif
diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c
index 9a8c20c..90a044d 100644
--- a/tools/perf/util/color.c
+++ b/tools/perf/util/color.c
@@ -11,7 +11,8 @@
};
char *end;
int i;
- for (i = 0; i < ARRAY_SIZE(color_names); i++) {
+
+ for (i = 0; i < (int)ARRAY_SIZE(color_names); i++) {
const char *str = color_names[i];
if (!strncasecmp(name, str, len) && !str[len])
return i - 1;
@@ -28,7 +29,8 @@
static const char * const attr_names[] = {
"bold", "dim", "ul", "blink", "reverse"
};
- int i;
+ unsigned int i;
+
for (i = 0; i < ARRAY_SIZE(attr_names); i++) {
const char *str = attr_names[i];
if (!strncasecmp(name, str, len) && !str[len])
@@ -222,10 +224,12 @@
{
if (!*color)
return fwrite(buf, count, 1, fp) != 1;
+
while (count) {
char *p = memchr(buf, '\n', count);
+
if (p != buf && (fputs(color, fp) < 0 ||
- fwrite(buf, p ? p - buf : count, 1, fp) != 1 ||
+ fwrite(buf, p ? (size_t)(p - buf) : count, 1, fp) != 1 ||
fputs(PERF_COLOR_RESET, fp) < 0))
return -1;
if (!p)
@@ -238,4 +242,31 @@
return 0;
}
+char *get_percent_color(double percent)
+{
+ char *color = PERF_COLOR_NORMAL;
+ /*
+ * We color high-overhead entries in red, mid-overhead
+ * entries in green - and keep the low overhead places
+ * normal:
+ */
+ if (percent >= MIN_RED)
+ color = PERF_COLOR_RED;
+ else {
+ if (percent > MIN_GREEN)
+ color = PERF_COLOR_GREEN;
+ }
+ return color;
+}
+
+int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
+{
+ int r;
+ char *color;
+
+ color = get_percent_color(percent);
+ r = color_fprintf(fp, color, fmt, percent);
+
+ return r;
+}
diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h
index 5abfd37..706cec5 100644
--- a/tools/perf/util/color.h
+++ b/tools/perf/util/color.h
@@ -15,6 +15,9 @@
#define PERF_COLOR_CYAN "\033[36m"
#define PERF_COLOR_BG_RED "\033[41m"
+#define MIN_GREEN 0.5
+#define MIN_RED 5.0
+
/*
* This variable stores the value of color.ui
*/
@@ -32,5 +35,7 @@
int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf);
+int percent_color_fprintf(FILE *fp, const char *fmt, double percent);
+char *get_percent_color(double percent);
#endif /* COLOR_H */
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 3dd13fa..780df54 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -47,10 +47,12 @@
static char *parse_value(void)
{
static char value[1024];
- int quote = 0, comment = 0, len = 0, space = 0;
+ int quote = 0, comment = 0, space = 0;
+ size_t len = 0;
for (;;) {
int c = get_next_char();
+
if (len >= sizeof(value) - 1)
return NULL;
if (c == '\n') {
@@ -353,13 +355,13 @@
return 0;
}
-static int perf_default_core_config(const char *var, const char *value)
+static int perf_default_core_config(const char *var __used, const char *value __used)
{
/* Add other config variables here and to Documentation/config.txt. */
return 0;
}
-int perf_default_config(const char *var, const char *value, void *dummy)
+int perf_default_config(const char *var, const char *value, void *dummy __used)
{
if (!prefixcmp(var, "core."))
return perf_default_core_config(var, value);
@@ -471,10 +473,10 @@
!regexec(store.value_regex, value, 0, NULL, 0)));
}
-static int store_aux(const char* key, const char* value, void *cb)
+static int store_aux(const char* key, const char* value, void *cb __used)
{
+ int section_len;
const char *ep;
- size_t section_len;
switch (store.state) {
case KEY_SEEN:
@@ -551,7 +553,7 @@
strbuf_addf(&sb, "[%.*s]\n", store.baselen, key);
}
- success = write_in_full(fd, sb.buf, sb.len) == sb.len;
+ success = (write_in_full(fd, sb.buf, sb.len) == (ssize_t)sb.len);
strbuf_release(&sb);
return success;
@@ -599,7 +601,7 @@
}
strbuf_addf(&sb, "%s\n", quote);
- success = write_in_full(fd, sb.buf, sb.len) == sb.len;
+ success = (write_in_full(fd, sb.buf, sb.len) == (ssize_t)sb.len);
strbuf_release(&sb);
return success;
@@ -741,7 +743,7 @@
} else {
struct stat st;
char* contents;
- size_t contents_sz, copy_begin, copy_end;
+ ssize_t contents_sz, copy_begin, copy_end;
int i, new_line = 0;
if (value_regex == NULL)
diff --git a/tools/perf/util/exec_cmd.c b/tools/perf/util/exec_cmd.c
index d392922..34a3528 100644
--- a/tools/perf/util/exec_cmd.c
+++ b/tools/perf/util/exec_cmd.c
@@ -1,6 +1,9 @@
#include "cache.h"
#include "exec_cmd.h"
#include "quote.h"
+
+#include <string.h>
+
#define MAX_ARGS 32
extern char **environ;
@@ -51,7 +54,7 @@
slash--;
if (slash >= argv0) {
- argv0_path = strndup(argv0, slash - argv0);
+ argv0_path = xstrndup(argv0, slash - argv0);
return slash + 1;
}
diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c
index 17a00e0..fbb0097 100644
--- a/tools/perf/util/help.c
+++ b/tools/perf/util/help.c
@@ -26,7 +26,7 @@
return 80;
}
-void add_cmdname(struct cmdnames *cmds, const char *name, int len)
+void add_cmdname(struct cmdnames *cmds, const char *name, size_t len)
{
struct cmdname *ent = malloc(sizeof(*ent) + len + 1);
@@ -40,7 +40,8 @@
static void clean_cmdnames(struct cmdnames *cmds)
{
- int i;
+ unsigned int i;
+
for (i = 0; i < cmds->cnt; ++i)
free(cmds->names[i]);
free(cmds->names);
@@ -57,7 +58,7 @@
static void uniq(struct cmdnames *cmds)
{
- int i, j;
+ unsigned int i, j;
if (!cmds->cnt)
return;
@@ -71,7 +72,7 @@
void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
{
- int ci, cj, ei;
+ size_t ci, cj, ei;
int cmp;
ci = cj = ei = 0;
@@ -106,8 +107,9 @@
printf(" ");
for (j = 0; j < cols; j++) {
- int n = j * rows + i;
- int size = space;
+ unsigned int n = j * rows + i;
+ unsigned int size = space;
+
if (n >= cmds->cnt)
break;
if (j == cols-1 || n + rows >= cmds->cnt)
@@ -208,7 +210,7 @@
void list_commands(const char *title, struct cmdnames *main_cmds,
struct cmdnames *other_cmds)
{
- int i, longest = 0;
+ unsigned int i, longest = 0;
for (i = 0; i < main_cmds->cnt; i++)
if (longest < main_cmds->names[i]->len)
@@ -239,7 +241,8 @@
int is_in_cmdlist(struct cmdnames *c, const char *s)
{
- int i;
+ unsigned int i;
+
for (i = 0; i < c->cnt; i++)
if (!strcmp(s, c->names[i]->name))
return 1;
@@ -271,7 +274,8 @@
static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old)
{
- int i;
+ unsigned int i;
+
ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc);
for (i = 0; i < old->cnt; i++)
@@ -283,7 +287,7 @@
const char *help_unknown_cmd(const char *cmd)
{
- int i, n = 0, best_similarity = 0;
+ unsigned int i, n = 0, best_similarity = 0;
struct cmdnames main_cmds, other_cmds;
memset(&main_cmds, 0, sizeof(main_cmds));
@@ -345,7 +349,7 @@
exit(1);
}
-int cmd_version(int argc, const char **argv, const char *prefix)
+int cmd_version(int argc __used, const char **argv __used, const char *prefix __used)
{
printf("perf version %s\n", perf_version_string);
return 0;
diff --git a/tools/perf/util/help.h b/tools/perf/util/help.h
index 56bc154..7128783 100644
--- a/tools/perf/util/help.h
+++ b/tools/perf/util/help.h
@@ -2,8 +2,8 @@
#define HELP_H
struct cmdnames {
- int alloc;
- int cnt;
+ size_t alloc;
+ size_t cnt;
struct cmdname {
size_t len; /* also used for similarity index in help.c */
char name[FLEX_ARRAY];
@@ -19,7 +19,7 @@
void load_command_list(const char *prefix,
struct cmdnames *main_cmds,
struct cmdnames *other_cmds);
-void add_cmdname(struct cmdnames *cmds, const char *name, int len);
+void add_cmdname(struct cmdnames *cmds, const char *name, size_t len);
/* Here we require that excludes is a sorted list. */
void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes);
int is_in_cmdlist(struct cmdnames *c, const char *s);
diff --git a/tools/perf/util/include/asm/system.h b/tools/perf/util/include/asm/system.h
new file mode 100644
index 0000000..710cecc
--- /dev/null
+++ b/tools/perf/util/include/asm/system.h
@@ -0,0 +1 @@
+/* Empty */
diff --git a/tools/perf/util/include/linux/kernel.h b/tools/perf/util/include/linux/kernel.h
new file mode 100644
index 0000000..99c1b3d
--- /dev/null
+++ b/tools/perf/util/include/linux/kernel.h
@@ -0,0 +1,21 @@
+#ifndef PERF_LINUX_KERNEL_H_
+#define PERF_LINUX_KERNEL_H_
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#ifndef container_of
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof(((type *)0)->member) * __mptr = (ptr); \
+ (type *)((char *)__mptr - offsetof(type, member)); })
+#endif
+
+#endif
diff --git a/tools/perf/util/include/linux/list.h b/tools/perf/util/include/linux/list.h
new file mode 100644
index 0000000..dbe4b81
--- /dev/null
+++ b/tools/perf/util/include/linux/list.h
@@ -0,0 +1,18 @@
+#include "../../../../include/linux/list.h"
+
+#ifndef PERF_LIST_H
+#define PERF_LIST_H
+/**
+ * list_del_range - deletes range of entries from list.
+ * @begin: first element in the range to delete from the list.
+ * @end: last element in the range to delete from the list.
+ * Note: list_empty on the range of entries does not return true after this,
+ * the entries is in an undefined state.
+ */
+static inline void list_del_range(struct list_head *begin,
+ struct list_head *end)
+{
+ begin->prev->next = end->next;
+ end->next->prev = begin->prev;
+}
+#endif
diff --git a/tools/perf/util/include/linux/module.h b/tools/perf/util/include/linux/module.h
new file mode 100644
index 0000000..b43e2dc
--- /dev/null
+++ b/tools/perf/util/include/linux/module.h
@@ -0,0 +1,6 @@
+#ifndef PERF_LINUX_MODULE_H
+#define PERF_LINUX_MODULE_H
+
+#define EXPORT_SYMBOL(name)
+
+#endif
diff --git a/tools/perf/util/include/linux/poison.h b/tools/perf/util/include/linux/poison.h
new file mode 100644
index 0000000..fef6dbc
--- /dev/null
+++ b/tools/perf/util/include/linux/poison.h
@@ -0,0 +1 @@
+#include "../../../../include/linux/poison.h"
diff --git a/tools/perf/util/include/linux/prefetch.h b/tools/perf/util/include/linux/prefetch.h
new file mode 100644
index 0000000..7841e48
--- /dev/null
+++ b/tools/perf/util/include/linux/prefetch.h
@@ -0,0 +1,6 @@
+#ifndef PERF_LINUX_PREFETCH_H
+#define PERF_LINUX_PREFETCH_H
+
+static inline void prefetch(void *a __attribute__((unused))) { }
+
+#endif
diff --git a/tools/perf/util/include/linux/rbtree.h b/tools/perf/util/include/linux/rbtree.h
new file mode 100644
index 0000000..7a243a1
--- /dev/null
+++ b/tools/perf/util/include/linux/rbtree.h
@@ -0,0 +1 @@
+#include "../../../../include/linux/rbtree.h"
diff --git a/tools/perf/util/list.h b/tools/perf/util/list.h
deleted file mode 100644
index e2548e8..0000000
--- a/tools/perf/util/list.h
+++ /dev/null
@@ -1,603 +0,0 @@
-#ifndef _LINUX_LIST_H
-#define _LINUX_LIST_H
-/*
- Copyright (C) Cast of dozens, comes from the Linux kernel
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation.
-*/
-
-#include <stddef.h>
-
-/*
- * These are non-NULL pointers that will result in page faults
- * under normal circumstances, used to verify that nobody uses
- * non-initialized list entries.
- */
-#define LIST_POISON1 ((void *)0x00100100)
-#define LIST_POISON2 ((void *)0x00200200)
-
-/**
- * container_of - cast a member of a structure out to the containing structure
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-
-/*
- * Simple doubly linked list implementation.
- *
- * Some of the internal functions ("__xxx") are useful when
- * manipulating whole lists rather than single entries, as
- * sometimes we already know the next/prev entries and we can
- * generate better code by using them directly rather than
- * using the generic single-entry routines.
- */
-
-struct list_head {
- struct list_head *next, *prev;
-};
-
-#define LIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LIST_HEAD(name) \
- struct list_head name = LIST_HEAD_INIT(name)
-
-static inline void INIT_LIST_HEAD(struct list_head *list)
-{
- list->next = list;
- list->prev = list;
-}
-
-/*
- * Insert a new entry between two known consecutive entries.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_add(struct list_head *new,
- struct list_head *prev,
- struct list_head *next)
-{
- next->prev = new;
- new->next = next;
- new->prev = prev;
- prev->next = new;
-}
-
-/**
- * list_add - add a new entry
- * @new: new entry to be added
- * @head: list head to add it after
- *
- * Insert a new entry after the specified head.
- * This is good for implementing stacks.
- */
-static inline void list_add(struct list_head *new, struct list_head *head)
-{
- __list_add(new, head, head->next);
-}
-
-/**
- * list_add_tail - add a new entry
- * @new: new entry to be added
- * @head: list head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- */
-static inline void list_add_tail(struct list_head *new, struct list_head *head)
-{
- __list_add(new, head->prev, head);
-}
-
-/*
- * Delete a list entry by making the prev/next entries
- * point to each other.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_del(struct list_head * prev, struct list_head * next)
-{
- next->prev = prev;
- prev->next = next;
-}
-
-/**
- * list_del - deletes entry from list.
- * @entry: the element to delete from the list.
- * Note: list_empty on entry does not return true after this, the entry is
- * in an undefined state.
- */
-static inline void list_del(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
- entry->next = LIST_POISON1;
- entry->prev = LIST_POISON2;
-}
-
-/**
- * list_del_range - deletes range of entries from list.
- * @beging: first element in the range to delete from the list.
- * @beging: first element in the range to delete from the list.
- * Note: list_empty on the range of entries does not return true after this,
- * the entries is in an undefined state.
- */
-static inline void list_del_range(struct list_head *begin,
- struct list_head *end)
-{
- begin->prev->next = end->next;
- end->next->prev = begin->prev;
-}
-
-/**
- * list_replace - replace old entry by new one
- * @old : the element to be replaced
- * @new : the new element to insert
- * Note: if 'old' was empty, it will be overwritten.
- */
-static inline void list_replace(struct list_head *old,
- struct list_head *new)
-{
- new->next = old->next;
- new->next->prev = new;
- new->prev = old->prev;
- new->prev->next = new;
-}
-
-static inline void list_replace_init(struct list_head *old,
- struct list_head *new)
-{
- list_replace(old, new);
- INIT_LIST_HEAD(old);
-}
-
-/**
- * list_del_init - deletes entry from list and reinitialize it.
- * @entry: the element to delete from the list.
- */
-static inline void list_del_init(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
- INIT_LIST_HEAD(entry);
-}
-
-/**
- * list_move - delete from one list and add as another's head
- * @list: the entry to move
- * @head: the head that will precede our entry
- */
-static inline void list_move(struct list_head *list, struct list_head *head)
-{
- __list_del(list->prev, list->next);
- list_add(list, head);
-}
-
-/**
- * list_move_tail - delete from one list and add as another's tail
- * @list: the entry to move
- * @head: the head that will follow our entry
- */
-static inline void list_move_tail(struct list_head *list,
- struct list_head *head)
-{
- __list_del(list->prev, list->next);
- list_add_tail(list, head);
-}
-
-/**
- * list_is_last - tests whether @list is the last entry in list @head
- * @list: the entry to test
- * @head: the head of the list
- */
-static inline int list_is_last(const struct list_head *list,
- const struct list_head *head)
-{
- return list->next == head;
-}
-
-/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static inline int list_empty(const struct list_head *head)
-{
- return head->next == head;
-}
-
-/**
- * list_empty_careful - tests whether a list is empty and not being modified
- * @head: the list to test
- *
- * Description:
- * tests whether a list is empty _and_ checks that no other CPU might be
- * in the process of modifying either member (next or prev)
- *
- * NOTE: using list_empty_careful() without synchronization
- * can only be safe if the only activity that can happen
- * to the list entry is list_del_init(). Eg. it cannot be used
- * if another CPU could re-list_add() it.
- */
-static inline int list_empty_careful(const struct list_head *head)
-{
- struct list_head *next = head->next;
- return (next == head) && (next == head->prev);
-}
-
-static inline void __list_splice(struct list_head *list,
- struct list_head *head)
-{
- struct list_head *first = list->next;
- struct list_head *last = list->prev;
- struct list_head *at = head->next;
-
- first->prev = head;
- head->next = first;
-
- last->next = at;
- at->prev = last;
-}
-
-/**
- * list_splice - join two lists
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- */
-static inline void list_splice(struct list_head *list, struct list_head *head)
-{
- if (!list_empty(list))
- __list_splice(list, head);
-}
-
-/**
- * list_splice_init - join two lists and reinitialise the emptied list.
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- *
- * The list at @list is reinitialised
- */
-static inline void list_splice_init(struct list_head *list,
- struct list_head *head)
-{
- if (!list_empty(list)) {
- __list_splice(list, head);
- INIT_LIST_HEAD(list);
- }
-}
-
-/**
- * list_entry - get the struct for this entry
- * @ptr: the &struct list_head pointer.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
- */
-#define list_entry(ptr, type, member) \
- container_of(ptr, type, member)
-
-/**
- * list_first_entry - get the first element from a list
- * @ptr: the list head to take the element from.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
- *
- * Note, that list is expected to be not empty.
- */
-#define list_first_entry(ptr, type, member) \
- list_entry((ptr)->next, type, member)
-
-/**
- * list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop cursor.
- * @head: the head for your list.
- */
-#define list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); \
- pos = pos->next)
-
-/**
- * __list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop cursor.
- * @head: the head for your list.
- *
- * This variant differs from list_for_each() in that it's the
- * simplest possible list iteration code, no prefetching is done.
- * Use this for code that knows the list to be very short (empty
- * or 1 entry) most of the time.
- */
-#define __list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * list_for_each_prev - iterate over a list backwards
- * @pos: the &struct list_head to use as a loop cursor.
- * @head: the head for your list.
- */
-#define list_for_each_prev(pos, head) \
- for (pos = (head)->prev; pos != (head); \
- pos = pos->prev)
-
-/**
- * list_for_each_safe - iterate over a list safe against removal of list entry
- * @pos: the &struct list_head to use as a loop cursor.
- * @n: another &struct list_head to use as temporary storage
- * @head: the head for your list.
- */
-#define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-
-/**
- * list_for_each_entry - iterate over list of given type
- * @pos: the type * to use as a loop cursor.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry(pos, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_reverse - iterate backwards over list of given type.
- * @pos: the type * to use as a loop cursor.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_reverse(pos, head, member) \
- for (pos = list_entry((head)->prev, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.prev, typeof(*pos), member))
-
-/**
- * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue
- * @pos: the type * to use as a start point
- * @head: the head of the list
- * @member: the name of the list_struct within the struct.
- *
- * Prepares a pos entry for use as a start point in list_for_each_entry_continue.
- */
-#define list_prepare_entry(pos, head, member) \
- ((pos) ? : list_entry(head, typeof(*pos), member))
-
-/**
- * list_for_each_entry_continue - continue iteration over list of given type
- * @pos: the type * to use as a loop cursor.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- *
- * Continue to iterate over list of given type, continuing after
- * the current position.
- */
-#define list_for_each_entry_continue(pos, head, member) \
- for (pos = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_from - iterate over list of given type from the current point
- * @pos: the type * to use as a loop cursor.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- *
- * Iterate over list of given type, continuing from current position.
- */
-#define list_for_each_entry_from(pos, head, member) \
- for (; &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @pos: the type * to use as a loop cursor.
- * @n: another type * to use as temporary storage
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_safe(pos, n, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member), \
- n = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-/**
- * list_for_each_entry_safe_continue
- * @pos: the type * to use as a loop cursor.
- * @n: another type * to use as temporary storage
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- *
- * Iterate over list of given type, continuing after current point,
- * safe against removal of list entry.
- */
-#define list_for_each_entry_safe_continue(pos, n, head, member) \
- for (pos = list_entry(pos->member.next, typeof(*pos), member), \
- n = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-/**
- * list_for_each_entry_safe_from
- * @pos: the type * to use as a loop cursor.
- * @n: another type * to use as temporary storage
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- *
- * Iterate over list of given type from current point, safe against
- * removal of list entry.
- */
-#define list_for_each_entry_safe_from(pos, n, head, member) \
- for (n = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-/**
- * list_for_each_entry_safe_reverse
- * @pos: the type * to use as a loop cursor.
- * @n: another type * to use as temporary storage
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- *
- * Iterate backwards over list of given type, safe against removal
- * of list entry.
- */
-#define list_for_each_entry_safe_reverse(pos, n, head, member) \
- for (pos = list_entry((head)->prev, typeof(*pos), member), \
- n = list_entry(pos->member.prev, typeof(*pos), member); \
- &pos->member != (head); \
- pos = n, n = list_entry(n->member.prev, typeof(*n), member))
-
-/*
- * Double linked lists with a single pointer list head.
- * Mostly useful for hash tables where the two pointer list head is
- * too wasteful.
- * You lose the ability to access the tail in O(1).
- */
-
-struct hlist_head {
- struct hlist_node *first;
-};
-
-struct hlist_node {
- struct hlist_node *next, **pprev;
-};
-
-#define HLIST_HEAD_INIT { .first = NULL }
-#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
-#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
-static inline void INIT_HLIST_NODE(struct hlist_node *h)
-{
- h->next = NULL;
- h->pprev = NULL;
-}
-
-static inline int hlist_unhashed(const struct hlist_node *h)
-{
- return !h->pprev;
-}
-
-static inline int hlist_empty(const struct hlist_head *h)
-{
- return !h->first;
-}
-
-static inline void __hlist_del(struct hlist_node *n)
-{
- struct hlist_node *next = n->next;
- struct hlist_node **pprev = n->pprev;
- *pprev = next;
- if (next)
- next->pprev = pprev;
-}
-
-static inline void hlist_del(struct hlist_node *n)
-{
- __hlist_del(n);
- n->next = LIST_POISON1;
- n->pprev = LIST_POISON2;
-}
-
-static inline void hlist_del_init(struct hlist_node *n)
-{
- if (!hlist_unhashed(n)) {
- __hlist_del(n);
- INIT_HLIST_NODE(n);
- }
-}
-
-static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
-{
- struct hlist_node *first = h->first;
- n->next = first;
- if (first)
- first->pprev = &n->next;
- h->first = n;
- n->pprev = &h->first;
-}
-
-/* next must be != NULL */
-static inline void hlist_add_before(struct hlist_node *n,
- struct hlist_node *next)
-{
- n->pprev = next->pprev;
- n->next = next;
- next->pprev = &n->next;
- *(n->pprev) = n;
-}
-
-static inline void hlist_add_after(struct hlist_node *n,
- struct hlist_node *next)
-{
- next->next = n->next;
- n->next = next;
- next->pprev = &n->next;
-
- if(next->next)
- next->next->pprev = &next->next;
-}
-
-#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
-
-#define hlist_for_each(pos, head) \
- for (pos = (head)->first; pos; \
- pos = pos->next)
-
-#define hlist_for_each_safe(pos, n, head) \
- for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
- pos = n)
-
-/**
- * hlist_for_each_entry - iterate over list of given type
- * @tpos: the type * to use as a loop cursor.
- * @pos: the &struct hlist_node to use as a loop cursor.
- * @head: the head for your list.
- * @member: the name of the hlist_node within the struct.
- */
-#define hlist_for_each_entry(tpos, pos, head, member) \
- for (pos = (head)->first; \
- pos && \
- ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = pos->next)
-
-/**
- * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
- * @tpos: the type * to use as a loop cursor.
- * @pos: the &struct hlist_node to use as a loop cursor.
- * @member: the name of the hlist_node within the struct.
- */
-#define hlist_for_each_entry_continue(tpos, pos, member) \
- for (pos = (pos)->next; \
- pos && \
- ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = pos->next)
-
-/**
- * hlist_for_each_entry_from - iterate over a hlist continuing from current point
- * @tpos: the type * to use as a loop cursor.
- * @pos: the &struct hlist_node to use as a loop cursor.
- * @member: the name of the hlist_node within the struct.
- */
-#define hlist_for_each_entry_from(tpos, pos, member) \
- for (; pos && \
- ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = pos->next)
-
-/**
- * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @tpos: the type * to use as a loop cursor.
- * @pos: the &struct hlist_node to use as a loop cursor.
- * @n: another &struct hlist_node to use as temporary storage
- * @head: the head for your list.
- * @member: the name of the hlist_node within the struct.
- */
-#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
- for (pos = (head)->first; \
- pos && ({ n = pos->next; 1; }) && \
- ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = n)
-
-#endif
diff --git a/tools/perf/util/module.c b/tools/perf/util/module.c
new file mode 100644
index 0000000..ddabe92
--- /dev/null
+++ b/tools/perf/util/module.c
@@ -0,0 +1,509 @@
+#include "util.h"
+#include "../perf.h"
+#include "string.h"
+#include "module.h"
+
+#include <libelf.h>
+#include <gelf.h>
+#include <elf.h>
+#include <dirent.h>
+#include <sys/utsname.h>
+
+static unsigned int crc32(const char *p, unsigned int len)
+{
+ int i;
+ unsigned int crc = 0;
+
+ while (len--) {
+ crc ^= *p++;
+ for (i = 0; i < 8; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
+ }
+ return crc;
+}
+
+/* module section methods */
+
+struct sec_dso *sec_dso__new_dso(const char *name)
+{
+ struct sec_dso *self = malloc(sizeof(*self) + strlen(name) + 1);
+
+ if (self != NULL) {
+ strcpy(self->name, name);
+ self->secs = RB_ROOT;
+ self->find_section = sec_dso__find_section;
+ }
+
+ return self;
+}
+
+static void sec_dso__delete_section(struct section *self)
+{
+ free(((void *)self));
+}
+
+void sec_dso__delete_sections(struct sec_dso *self)
+{
+ struct section *pos;
+ struct rb_node *next = rb_first(&self->secs);
+
+ while (next) {
+ pos = rb_entry(next, struct section, rb_node);
+ next = rb_next(&pos->rb_node);
+ rb_erase(&pos->rb_node, &self->secs);
+ sec_dso__delete_section(pos);
+ }
+}
+
+void sec_dso__delete_self(struct sec_dso *self)
+{
+ sec_dso__delete_sections(self);
+ free(self);
+}
+
+static void sec_dso__insert_section(struct sec_dso *self, struct section *sec)
+{
+ struct rb_node **p = &self->secs.rb_node;
+ struct rb_node *parent = NULL;
+ const u64 hash = sec->hash;
+ struct section *s;
+
+ while (*p != NULL) {
+ parent = *p;
+ s = rb_entry(parent, struct section, rb_node);
+ if (hash < s->hash)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+ rb_link_node(&sec->rb_node, parent, p);
+ rb_insert_color(&sec->rb_node, &self->secs);
+}
+
+struct section *sec_dso__find_section(struct sec_dso *self, const char *name)
+{
+ struct rb_node *n;
+ u64 hash;
+ int len;
+
+ if (self == NULL)
+ return NULL;
+
+ len = strlen(name);
+ hash = crc32(name, len);
+
+ n = self->secs.rb_node;
+
+ while (n) {
+ struct section *s = rb_entry(n, struct section, rb_node);
+
+ if (hash < s->hash)
+ n = n->rb_left;
+ else if (hash > s->hash)
+ n = n->rb_right;
+ else {
+ if (!strcmp(name, s->name))
+ return s;
+ else
+ n = rb_next(&s->rb_node);
+ }
+ }
+
+ return NULL;
+}
+
+static size_t sec_dso__fprintf_section(struct section *self, FILE *fp)
+{
+ return fprintf(fp, "name:%s vma:%llx path:%s\n",
+ self->name, self->vma, self->path);
+}
+
+size_t sec_dso__fprintf(struct sec_dso *self, FILE *fp)
+{
+ size_t ret = fprintf(fp, "dso: %s\n", self->name);
+
+ struct rb_node *nd;
+ for (nd = rb_first(&self->secs); nd; nd = rb_next(nd)) {
+ struct section *pos = rb_entry(nd, struct section, rb_node);
+ ret += sec_dso__fprintf_section(pos, fp);
+ }
+
+ return ret;
+}
+
+static struct section *section__new(const char *name, const char *path)
+{
+ struct section *self = calloc(1, sizeof(*self));
+
+ if (!self)
+ goto out_failure;
+
+ self->name = calloc(1, strlen(name) + 1);
+ if (!self->name)
+ goto out_failure;
+
+ self->path = calloc(1, strlen(path) + 1);
+ if (!self->path)
+ goto out_failure;
+
+ strcpy(self->name, name);
+ strcpy(self->path, path);
+ self->hash = crc32(self->name, strlen(name));
+
+ return self;
+
+out_failure:
+ if (self) {
+ if (self->name)
+ free(self->name);
+ if (self->path)
+ free(self->path);
+ free(self);
+ }
+
+ return NULL;
+}
+
+/* module methods */
+
+struct mod_dso *mod_dso__new_dso(const char *name)
+{
+ struct mod_dso *self = malloc(sizeof(*self) + strlen(name) + 1);
+
+ if (self != NULL) {
+ strcpy(self->name, name);
+ self->mods = RB_ROOT;
+ self->find_module = mod_dso__find_module;
+ }
+
+ return self;
+}
+
+static void mod_dso__delete_module(struct module *self)
+{
+ free(((void *)self));
+}
+
+void mod_dso__delete_modules(struct mod_dso *self)
+{
+ struct module *pos;
+ struct rb_node *next = rb_first(&self->mods);
+
+ while (next) {
+ pos = rb_entry(next, struct module, rb_node);
+ next = rb_next(&pos->rb_node);
+ rb_erase(&pos->rb_node, &self->mods);
+ mod_dso__delete_module(pos);
+ }
+}
+
+void mod_dso__delete_self(struct mod_dso *self)
+{
+ mod_dso__delete_modules(self);
+ free(self);
+}
+
+static void mod_dso__insert_module(struct mod_dso *self, struct module *mod)
+{
+ struct rb_node **p = &self->mods.rb_node;
+ struct rb_node *parent = NULL;
+ const u64 hash = mod->hash;
+ struct module *m;
+
+ while (*p != NULL) {
+ parent = *p;
+ m = rb_entry(parent, struct module, rb_node);
+ if (hash < m->hash)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+ rb_link_node(&mod->rb_node, parent, p);
+ rb_insert_color(&mod->rb_node, &self->mods);
+}
+
+struct module *mod_dso__find_module(struct mod_dso *self, const char *name)
+{
+ struct rb_node *n;
+ u64 hash;
+ int len;
+
+ if (self == NULL)
+ return NULL;
+
+ len = strlen(name);
+ hash = crc32(name, len);
+
+ n = self->mods.rb_node;
+
+ while (n) {
+ struct module *m = rb_entry(n, struct module, rb_node);
+
+ if (hash < m->hash)
+ n = n->rb_left;
+ else if (hash > m->hash)
+ n = n->rb_right;
+ else {
+ if (!strcmp(name, m->name))
+ return m;
+ else
+ n = rb_next(&m->rb_node);
+ }
+ }
+
+ return NULL;
+}
+
+static size_t mod_dso__fprintf_module(struct module *self, FILE *fp)
+{
+ return fprintf(fp, "name:%s path:%s\n", self->name, self->path);
+}
+
+size_t mod_dso__fprintf(struct mod_dso *self, FILE *fp)
+{
+ struct rb_node *nd;
+ size_t ret;
+
+ ret = fprintf(fp, "dso: %s\n", self->name);
+
+ for (nd = rb_first(&self->mods); nd; nd = rb_next(nd)) {
+ struct module *pos = rb_entry(nd, struct module, rb_node);
+
+ ret += mod_dso__fprintf_module(pos, fp);
+ }
+
+ return ret;
+}
+
+static struct module *module__new(const char *name, const char *path)
+{
+ struct module *self = calloc(1, sizeof(*self));
+
+ if (!self)
+ goto out_failure;
+
+ self->name = calloc(1, strlen(name) + 1);
+ if (!self->name)
+ goto out_failure;
+
+ self->path = calloc(1, strlen(path) + 1);
+ if (!self->path)
+ goto out_failure;
+
+ strcpy(self->name, name);
+ strcpy(self->path, path);
+ self->hash = crc32(self->name, strlen(name));
+
+ return self;
+
+out_failure:
+ if (self) {
+ if (self->name)
+ free(self->name);
+ if (self->path)
+ free(self->path);
+ free(self);
+ }
+
+ return NULL;
+}
+
+static int mod_dso__load_sections(struct module *mod)
+{
+ int count = 0, path_len;
+ struct dirent *entry;
+ char *line = NULL;
+ char *dir_path;
+ DIR *dir;
+ size_t n;
+
+ path_len = strlen("/sys/module/");
+ path_len += strlen(mod->name);
+ path_len += strlen("/sections/");
+
+ dir_path = calloc(1, path_len + 1);
+ if (dir_path == NULL)
+ goto out_failure;
+
+ strcat(dir_path, "/sys/module/");
+ strcat(dir_path, mod->name);
+ strcat(dir_path, "/sections/");
+
+ dir = opendir(dir_path);
+ if (dir == NULL)
+ goto out_free;
+
+ while ((entry = readdir(dir))) {
+ struct section *section;
+ char *path, *vma;
+ int line_len;
+ FILE *file;
+
+ if (!strcmp(".", entry->d_name) || !strcmp("..", entry->d_name))
+ continue;
+
+ path = calloc(1, path_len + strlen(entry->d_name) + 1);
+ if (path == NULL)
+ break;
+ strcat(path, dir_path);
+ strcat(path, entry->d_name);
+
+ file = fopen(path, "r");
+ if (file == NULL) {
+ free(path);
+ break;
+ }
+
+ line_len = getline(&line, &n, file);
+ if (line_len < 0) {
+ free(path);
+ fclose(file);
+ break;
+ }
+
+ if (!line) {
+ free(path);
+ fclose(file);
+ break;
+ }
+
+ line[--line_len] = '\0'; /* \n */
+
+ vma = strstr(line, "0x");
+ if (!vma) {
+ free(path);
+ fclose(file);
+ break;
+ }
+ vma += 2;
+
+ section = section__new(entry->d_name, path);
+ if (!section) {
+ fprintf(stderr, "load_sections: allocation error\n");
+ free(path);
+ fclose(file);
+ break;
+ }
+
+ hex2u64(vma, §ion->vma);
+ sec_dso__insert_section(mod->sections, section);
+
+ free(path);
+ fclose(file);
+ count++;
+ }
+
+ closedir(dir);
+ free(line);
+ free(dir_path);
+
+ return count;
+
+out_free:
+ free(dir_path);
+
+out_failure:
+ return count;
+}
+
+static int mod_dso__load_module_paths(struct mod_dso *self)
+{
+ struct utsname uts;
+ int count = 0, len;
+ char *line = NULL;
+ FILE *file;
+ char *path;
+ size_t n;
+
+ if (uname(&uts) < 0)
+ goto out_failure;
+
+ len = strlen("/lib/modules/");
+ len += strlen(uts.release);
+ len += strlen("/modules.dep");
+
+ path = calloc(1, len);
+ if (path == NULL)
+ goto out_failure;
+
+ strcat(path, "/lib/modules/");
+ strcat(path, uts.release);
+ strcat(path, "/modules.dep");
+
+ file = fopen(path, "r");
+ free(path);
+ if (file == NULL)
+ goto out_failure;
+
+ while (!feof(file)) {
+ char *path, *name, *tmp;
+ struct module *module;
+ int line_len, len;
+
+ line_len = getline(&line, &n, file);
+ if (line_len < 0)
+ break;
+
+ if (!line)
+ goto out_failure;
+
+ line[--line_len] = '\0'; /* \n */
+
+ path = strtok(line, ":");
+ if (!path)
+ goto out_failure;
+
+ name = strdup(path);
+ name = strtok(name, "/");
+
+ tmp = name;
+
+ while (tmp) {
+ tmp = strtok(NULL, "/");
+ if (tmp)
+ name = tmp;
+ }
+ name = strsep(&name, ".");
+
+ /* Quirk: replace '-' with '_' in sound modules */
+ for (len = strlen(name); len; len--) {
+ if (*(name+len) == '-')
+ *(name+len) = '_';
+ }
+
+ module = module__new(name, path);
+ if (!module) {
+ fprintf(stderr, "load_module_paths: allocation error\n");
+ goto out_failure;
+ }
+ mod_dso__insert_module(self, module);
+
+ module->sections = sec_dso__new_dso("sections");
+ if (!module->sections) {
+ fprintf(stderr, "load_module_paths: allocation error\n");
+ goto out_failure;
+ }
+
+ module->active = mod_dso__load_sections(module);
+
+ if (module->active > 0)
+ count++;
+ }
+
+ free(line);
+ fclose(file);
+
+ return count;
+
+out_failure:
+ return -1;
+}
+
+int mod_dso__load_modules(struct mod_dso *dso)
+{
+ int err;
+
+ err = mod_dso__load_module_paths(dso);
+
+ return err;
+}
diff --git a/tools/perf/util/module.h b/tools/perf/util/module.h
new file mode 100644
index 0000000..8a592ef
--- /dev/null
+++ b/tools/perf/util/module.h
@@ -0,0 +1,53 @@
+#ifndef _PERF_MODULE_
+#define _PERF_MODULE_ 1
+
+#include <linux/types.h>
+#include "../types.h"
+#include <linux/list.h>
+#include <linux/rbtree.h>
+
+struct section {
+ struct rb_node rb_node;
+ u64 hash;
+ u64 vma;
+ char *name;
+ char *path;
+};
+
+struct sec_dso {
+ struct list_head node;
+ struct rb_root secs;
+ struct section *(*find_section)(struct sec_dso *, const char *name);
+ char name[0];
+};
+
+struct module {
+ struct rb_node rb_node;
+ u64 hash;
+ char *name;
+ char *path;
+ struct sec_dso *sections;
+ int active;
+};
+
+struct mod_dso {
+ struct list_head node;
+ struct rb_root mods;
+ struct module *(*find_module)(struct mod_dso *, const char *name);
+ char name[0];
+};
+
+struct sec_dso *sec_dso__new_dso(const char *name);
+void sec_dso__delete_sections(struct sec_dso *self);
+void sec_dso__delete_self(struct sec_dso *self);
+size_t sec_dso__fprintf(struct sec_dso *self, FILE *fp);
+struct section *sec_dso__find_section(struct sec_dso *self, const char *name);
+
+struct mod_dso *mod_dso__new_dso(const char *name);
+void mod_dso__delete_modules(struct mod_dso *self);
+void mod_dso__delete_self(struct mod_dso *self);
+size_t mod_dso__fprintf(struct mod_dso *self, FILE *fp);
+struct module *mod_dso__find_module(struct mod_dso *self, const char *name);
+int mod_dso__load_modules(struct mod_dso *dso);
+
+#endif /* _PERF_MODULE_ */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 4d042f1..5184959 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -184,16 +184,20 @@
return "unknown";
}
-static int parse_aliases(const char *str, char *names[][MAX_ALIASES], int size)
+static int parse_aliases(const char **str, char *names[][MAX_ALIASES], int size)
{
int i, j;
+ int n, longest = -1;
for (i = 0; i < size; i++) {
- for (j = 0; j < MAX_ALIASES; j++) {
- if (!names[i][j])
- break;
- if (strcasestr(str, names[i][j]))
- return i;
+ for (j = 0; j < MAX_ALIASES && names[i][j]; j++) {
+ n = strlen(names[i][j]);
+ if (n > longest && !strncasecmp(*str, names[i][j], n))
+ longest = n;
+ }
+ if (longest > 0) {
+ *str += longest;
+ return i;
}
}
@@ -201,30 +205,53 @@
}
static int
-parse_generic_hw_symbols(const char *str, struct perf_counter_attr *attr)
+parse_generic_hw_event(const char **str, struct perf_counter_attr *attr)
{
- int cache_type = -1, cache_op = 0, cache_result = 0;
+ const char *s = *str;
+ int cache_type = -1, cache_op = -1, cache_result = -1;
- cache_type = parse_aliases(str, hw_cache, PERF_COUNT_HW_CACHE_MAX);
+ cache_type = parse_aliases(&s, hw_cache, PERF_COUNT_HW_CACHE_MAX);
/*
* No fallback - if we cannot get a clear cache type
* then bail out:
*/
if (cache_type == -1)
- return -EINVAL;
+ return 0;
- cache_op = parse_aliases(str, hw_cache_op, PERF_COUNT_HW_CACHE_OP_MAX);
+ while ((cache_op == -1 || cache_result == -1) && *s == '-') {
+ ++s;
+
+ if (cache_op == -1) {
+ cache_op = parse_aliases(&s, hw_cache_op,
+ PERF_COUNT_HW_CACHE_OP_MAX);
+ if (cache_op >= 0) {
+ if (!is_cache_op_valid(cache_type, cache_op))
+ return 0;
+ continue;
+ }
+ }
+
+ if (cache_result == -1) {
+ cache_result = parse_aliases(&s, hw_cache_result,
+ PERF_COUNT_HW_CACHE_RESULT_MAX);
+ if (cache_result >= 0)
+ continue;
+ }
+
+ /*
+ * Can't parse this as a cache op or result, so back up
+ * to the '-'.
+ */
+ --s;
+ break;
+ }
+
/*
* Fall back to reads:
*/
if (cache_op == -1)
cache_op = PERF_COUNT_HW_CACHE_OP_READ;
- if (!is_cache_op_valid(cache_type, cache_op))
- return -EINVAL;
-
- cache_result = parse_aliases(str, hw_cache_result,
- PERF_COUNT_HW_CACHE_RESULT_MAX);
/*
* Fall back to accesses:
*/
@@ -234,19 +261,110 @@
attr->config = cache_type | (cache_op << 8) | (cache_result << 16);
attr->type = PERF_TYPE_HW_CACHE;
- return 0;
+ *str = s;
+ return 1;
}
static int check_events(const char *str, unsigned int i)
{
- if (!strncmp(str, event_symbols[i].symbol,
- strlen(event_symbols[i].symbol)))
- return 1;
+ int n;
- if (strlen(event_symbols[i].alias))
- if (!strncmp(str, event_symbols[i].alias,
- strlen(event_symbols[i].alias)))
+ n = strlen(event_symbols[i].symbol);
+ if (!strncmp(str, event_symbols[i].symbol, n))
+ return n;
+
+ n = strlen(event_symbols[i].alias);
+ if (n)
+ if (!strncmp(str, event_symbols[i].alias, n))
+ return n;
+ return 0;
+}
+
+static int
+parse_symbolic_event(const char **strp, struct perf_counter_attr *attr)
+{
+ const char *str = *strp;
+ unsigned int i;
+ int n;
+
+ for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
+ n = check_events(str, i);
+ if (n > 0) {
+ attr->type = event_symbols[i].type;
+ attr->config = event_symbols[i].config;
+ *strp = str + n;
return 1;
+ }
+ }
+ return 0;
+}
+
+static int parse_raw_event(const char **strp, struct perf_counter_attr *attr)
+{
+ const char *str = *strp;
+ u64 config;
+ int n;
+
+ if (*str != 'r')
+ return 0;
+ n = hex2u64(str + 1, &config);
+ if (n > 0) {
+ *strp = str + n + 1;
+ attr->type = PERF_TYPE_RAW;
+ attr->config = config;
+ return 1;
+ }
+ return 0;
+}
+
+static int
+parse_numeric_event(const char **strp, struct perf_counter_attr *attr)
+{
+ const char *str = *strp;
+ char *endp;
+ unsigned long type;
+ u64 config;
+
+ type = strtoul(str, &endp, 0);
+ if (endp > str && type < PERF_TYPE_MAX && *endp == ':') {
+ str = endp + 1;
+ config = strtoul(str, &endp, 0);
+ if (endp > str) {
+ attr->type = type;
+ attr->config = config;
+ *strp = endp;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int
+parse_event_modifier(const char **strp, struct perf_counter_attr *attr)
+{
+ const char *str = *strp;
+ int eu = 1, ek = 1, eh = 1;
+
+ if (*str++ != ':')
+ return 0;
+ while (*str) {
+ if (*str == 'u')
+ eu = 0;
+ else if (*str == 'k')
+ ek = 0;
+ else if (*str == 'h')
+ eh = 0;
+ else
+ break;
+ ++str;
+ }
+ if (str >= *strp + 2) {
+ *strp = str;
+ attr->exclude_user = eu;
+ attr->exclude_kernel = ek;
+ attr->exclude_hv = eh;
+ return 1;
+ }
return 0;
}
@@ -254,73 +372,43 @@
* Each event can have multiple symbolic names.
* Symbolic names are (almost) exactly matched.
*/
-static int parse_event_symbols(const char *str, struct perf_counter_attr *attr)
+static int parse_event_symbols(const char **str, struct perf_counter_attr *attr)
{
- u64 config, id;
- int type;
- unsigned int i;
- const char *sep, *pstr;
-
- if (str[0] == 'r' && hex2u64(str + 1, &config) > 0) {
- attr->type = PERF_TYPE_RAW;
- attr->config = config;
-
+ if (!(parse_raw_event(str, attr) ||
+ parse_numeric_event(str, attr) ||
+ parse_symbolic_event(str, attr) ||
+ parse_generic_hw_event(str, attr)))
return 0;
- }
- pstr = str;
- sep = strchr(pstr, ':');
- if (sep) {
- type = atoi(pstr);
- pstr = sep + 1;
- id = atoi(pstr);
- sep = strchr(pstr, ':');
- if (sep) {
- pstr = sep + 1;
- if (strchr(pstr, 'k'))
- attr->exclude_user = 1;
- if (strchr(pstr, 'u'))
- attr->exclude_kernel = 1;
- }
- attr->type = type;
- attr->config = id;
+ parse_event_modifier(str, attr);
- return 0;
- }
-
- for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
- if (check_events(str, i)) {
- attr->type = event_symbols[i].type;
- attr->config = event_symbols[i].config;
-
- return 0;
- }
- }
-
- return parse_generic_hw_symbols(str, attr);
+ return 1;
}
-int parse_events(const struct option *opt, const char *str, int unset)
+int parse_events(const struct option *opt __used, const char *str, int unset __used)
{
struct perf_counter_attr attr;
- int ret;
- memset(&attr, 0, sizeof(attr));
-again:
- if (nr_counters == MAX_COUNTERS)
- return -1;
+ for (;;) {
+ if (nr_counters == MAX_COUNTERS)
+ return -1;
- ret = parse_event_symbols(str, &attr);
- if (ret < 0)
- return ret;
+ memset(&attr, 0, sizeof(attr));
+ if (!parse_event_symbols(&str, &attr))
+ return -1;
- attrs[nr_counters] = attr;
- nr_counters++;
+ if (!(*str == 0 || *str == ',' || isspace(*str)))
+ return -1;
- str = strstr(str, ",");
- if (str) {
- str++;
- goto again;
+ attrs[nr_counters] = attr;
+ nr_counters++;
+
+ if (*str == 0)
+ break;
+ if (*str == ',')
+ ++str;
+ while (isspace(*str))
+ ++str;
}
return 0;
@@ -340,7 +428,7 @@
void print_events(void)
{
struct event_symbol *syms = event_symbols;
- unsigned int i, type, prev_type = -1;
+ unsigned int i, type, op, prev_type = -1;
char name[40];
fprintf(stderr, "\n");
@@ -365,6 +453,21 @@
}
fprintf(stderr, "\n");
+ for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
+ for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
+ /* skip invalid cache type */
+ if (!is_cache_op_valid(type, op))
+ continue;
+
+ for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
+ fprintf(stderr, " %-40s [%s]\n",
+ event_cache_name(type, op, i),
+ event_type_descriptors[4]);
+ }
+ }
+ }
+
+ fprintf(stderr, "\n");
fprintf(stderr, " %-40s [raw hardware event descriptor]\n",
"rNNN");
fprintf(stderr, "\n");
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index b3affb1..1bf6719 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -20,7 +20,8 @@
if (p->opt) {
*arg = p->opt;
p->opt = NULL;
- } else if (p->argc == 1 && (opt->flags & PARSE_OPT_LASTARG_DEFAULT)) {
+ } else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 ||
+ **(p->argv + 1) == '-')) {
*arg = (const char *)opt->defval;
} else if (p->argc > 1) {
p->argc--;
@@ -485,7 +486,7 @@
}
-int parse_opt_verbosity_cb(const struct option *opt, const char *arg,
+int parse_opt_verbosity_cb(const struct option *opt, const char *arg __used,
int unset)
{
int *target = opt->value;
diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h
index a1039a6..8aa3464 100644
--- a/tools/perf/util/parse-options.h
+++ b/tools/perf/util/parse-options.h
@@ -90,21 +90,22 @@
intptr_t defval;
};
-#define OPT_END() { OPTION_END }
-#define OPT_ARGUMENT(l, h) { OPTION_ARGUMENT, 0, (l), NULL, NULL, (h) }
-#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
-#define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), 0, NULL, (b) }
-#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) }
-#define OPT_SET_INT(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, (h), 0, NULL, (i) }
-#define OPT_SET_PTR(s, l, v, h, p) { OPTION_SET_PTR, (s), (l), (v), NULL, (h), 0, NULL, (p) }
-#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), NULL, (h) }
-#define OPT_LONG(s, l, v, h) { OPTION_LONG, (s), (l), (v), NULL, (h) }
-#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) }
+#define OPT_END() { .type = OPTION_END }
+#define OPT_ARGUMENT(l, h) { .type = OPTION_ARGUMENT, .long_name = (l), .help = (h) }
+#define OPT_GROUP(h) { .type = OPTION_GROUP, .help = (h) }
+#define OPT_BIT(s, l, v, h, b) { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (b) }
+#define OPT_BOOLEAN(s, l, v, h) { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = (v), .help = (h) }
+#define OPT_SET_INT(s, l, v, h, i) { .type = OPTION_SET_INT, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (i) }
+#define OPT_SET_PTR(s, l, v, h, p) { .type = OPTION_SET_PTR, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (p) }
+#define OPT_INTEGER(s, l, v, h) { .type = OPTION_INTEGER, .short_name = (s), .long_name = (l), .value = (v), .help = (h) }
+#define OPT_LONG(s, l, v, h) { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = (v), .help = (h) }
+#define OPT_STRING(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h) }
#define OPT_DATE(s, l, v, h) \
- { OPTION_CALLBACK, (s), (l), (v), "time",(h), 0, \
- parse_opt_approxidate_cb }
+ { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb }
#define OPT_CALLBACK(s, l, v, a, h, f) \
- { OPTION_CALLBACK, (s), (l), (v), (a), (h), 0, (f) }
+ { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h), .callback = (f) }
+#define OPT_CALLBACK_DEFAULT(s, l, v, a, h, f, d) \
+ { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h), .callback = (f), .defval = (intptr_t)d, .flags = PARSE_OPT_LASTARG_DEFAULT }
/* parse_options() will filter out the processed options and leave the
* non-option argments in argv[].
diff --git a/tools/perf/util/quote.c b/tools/perf/util/quote.c
index f18c521..c6e5dc0 100644
--- a/tools/perf/util/quote.c
+++ b/tools/perf/util/quote.c
@@ -162,12 +162,16 @@
return sq_lookup[(unsigned char)c] + quote_path_fully > 0;
}
-/* returns the longest prefix not needing a quote up to maxlen if positive.
- This stops at the first \0 because it's marked as a character needing an
- escape */
-static size_t next_quote_pos(const char *s, ssize_t maxlen)
+/*
+ * Returns the longest prefix not needing a quote up to maxlen if
+ * positive.
+ * This stops at the first \0 because it's marked as a character
+ * needing an escape.
+ */
+static ssize_t next_quote_pos(const char *s, ssize_t maxlen)
{
- size_t len;
+ ssize_t len;
+
if (maxlen < 0) {
for (len = 0; !sq_must_quote(s[len]); len++);
} else {
@@ -192,22 +196,22 @@
static size_t quote_c_style_counted(const char *name, ssize_t maxlen,
struct strbuf *sb, FILE *fp, int no_dq)
{
-#undef EMIT
-#define EMIT(c) \
- do { \
- if (sb) strbuf_addch(sb, (c)); \
- if (fp) fputc((c), fp); \
- count++; \
- } while (0)
-#define EMITBUF(s, l) \
- do { \
- int __ret; \
- if (sb) strbuf_add(sb, (s), (l)); \
- if (fp) __ret = fwrite((s), (l), 1, fp); \
- count += (l); \
+#define EMIT(c) \
+ do { \
+ if (sb) strbuf_addch(sb, (c)); \
+ if (fp) fputc((c), fp); \
+ count++; \
} while (0)
- size_t len, count = 0;
+#define EMITBUF(s, l) \
+ do { \
+ int __ret; \
+ if (sb) strbuf_add(sb, (s), (l)); \
+ if (fp) __ret = fwrite((s), (l), 1, fp); \
+ count += (l); \
+ } while (0)
+
+ ssize_t len, count = 0;
const char *p = name;
for (;;) {
@@ -273,8 +277,8 @@
fputc(terminator, fp);
}
-extern void write_name_quotedpfx(const char *pfx, size_t pfxlen,
- const char *name, FILE *fp, int terminator)
+void write_name_quotedpfx(const char *pfx, ssize_t pfxlen,
+ const char *name, FILE *fp, int terminator)
{
int needquote = 0;
@@ -306,7 +310,7 @@
len = strlen(in);
/* "../" prefix itself does not need quoting, but "in" might. */
- needquote = next_quote_pos(in, len) < len;
+ needquote = (next_quote_pos(in, len) < len);
strbuf_setlen(out, 0);
strbuf_grow(out, len);
diff --git a/tools/perf/util/quote.h b/tools/perf/util/quote.h
index 5dfad89..a5454a1 100644
--- a/tools/perf/util/quote.h
+++ b/tools/perf/util/quote.h
@@ -53,7 +53,7 @@
extern void quote_two_c_style(struct strbuf *, const char *, const char *, int);
extern void write_name_quoted(const char *name, FILE *, int terminator);
-extern void write_name_quotedpfx(const char *pfx, size_t pfxlen,
+extern void write_name_quotedpfx(const char *pfx, ssize_t pfxlen,
const char *name, FILE *, int terminator);
/* quote path as relative to the given prefix */
diff --git a/tools/perf/util/rbtree.c b/tools/perf/util/rbtree.c
deleted file mode 100644
index b15ba9c..0000000
--- a/tools/perf/util/rbtree.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- Red Black Trees
- (C) 1999 Andrea Arcangeli <andrea@suse.de>
- (C) 2002 David Woodhouse <dwmw2@infradead.org>
-
- 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
-
- linux/lib/rbtree.c
-*/
-
-#include "rbtree.h"
-
-static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
-{
- struct rb_node *right = node->rb_right;
- struct rb_node *parent = rb_parent(node);
-
- if ((node->rb_right = right->rb_left))
- rb_set_parent(right->rb_left, node);
- right->rb_left = node;
-
- rb_set_parent(right, parent);
-
- if (parent)
- {
- if (node == parent->rb_left)
- parent->rb_left = right;
- else
- parent->rb_right = right;
- }
- else
- root->rb_node = right;
- rb_set_parent(node, right);
-}
-
-static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
-{
- struct rb_node *left = node->rb_left;
- struct rb_node *parent = rb_parent(node);
-
- if ((node->rb_left = left->rb_right))
- rb_set_parent(left->rb_right, node);
- left->rb_right = node;
-
- rb_set_parent(left, parent);
-
- if (parent)
- {
- if (node == parent->rb_right)
- parent->rb_right = left;
- else
- parent->rb_left = left;
- }
- else
- root->rb_node = left;
- rb_set_parent(node, left);
-}
-
-void rb_insert_color(struct rb_node *node, struct rb_root *root)
-{
- struct rb_node *parent, *gparent;
-
- while ((parent = rb_parent(node)) && rb_is_red(parent))
- {
- gparent = rb_parent(parent);
-
- if (parent == gparent->rb_left)
- {
- {
- register struct rb_node *uncle = gparent->rb_right;
- if (uncle && rb_is_red(uncle))
- {
- rb_set_black(uncle);
- rb_set_black(parent);
- rb_set_red(gparent);
- node = gparent;
- continue;
- }
- }
-
- if (parent->rb_right == node)
- {
- register struct rb_node *tmp;
- __rb_rotate_left(parent, root);
- tmp = parent;
- parent = node;
- node = tmp;
- }
-
- rb_set_black(parent);
- rb_set_red(gparent);
- __rb_rotate_right(gparent, root);
- } else {
- {
- register struct rb_node *uncle = gparent->rb_left;
- if (uncle && rb_is_red(uncle))
- {
- rb_set_black(uncle);
- rb_set_black(parent);
- rb_set_red(gparent);
- node = gparent;
- continue;
- }
- }
-
- if (parent->rb_left == node)
- {
- register struct rb_node *tmp;
- __rb_rotate_right(parent, root);
- tmp = parent;
- parent = node;
- node = tmp;
- }
-
- rb_set_black(parent);
- rb_set_red(gparent);
- __rb_rotate_left(gparent, root);
- }
- }
-
- rb_set_black(root->rb_node);
-}
-
-static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
- struct rb_root *root)
-{
- struct rb_node *other;
-
- while ((!node || rb_is_black(node)) && node != root->rb_node)
- {
- if (parent->rb_left == node)
- {
- other = parent->rb_right;
- if (rb_is_red(other))
- {
- rb_set_black(other);
- rb_set_red(parent);
- __rb_rotate_left(parent, root);
- other = parent->rb_right;
- }
- if ((!other->rb_left || rb_is_black(other->rb_left)) &&
- (!other->rb_right || rb_is_black(other->rb_right)))
- {
- rb_set_red(other);
- node = parent;
- parent = rb_parent(node);
- }
- else
- {
- if (!other->rb_right || rb_is_black(other->rb_right))
- {
- rb_set_black(other->rb_left);
- rb_set_red(other);
- __rb_rotate_right(other, root);
- other = parent->rb_right;
- }
- rb_set_color(other, rb_color(parent));
- rb_set_black(parent);
- rb_set_black(other->rb_right);
- __rb_rotate_left(parent, root);
- node = root->rb_node;
- break;
- }
- }
- else
- {
- other = parent->rb_left;
- if (rb_is_red(other))
- {
- rb_set_black(other);
- rb_set_red(parent);
- __rb_rotate_right(parent, root);
- other = parent->rb_left;
- }
- if ((!other->rb_left || rb_is_black(other->rb_left)) &&
- (!other->rb_right || rb_is_black(other->rb_right)))
- {
- rb_set_red(other);
- node = parent;
- parent = rb_parent(node);
- }
- else
- {
- if (!other->rb_left || rb_is_black(other->rb_left))
- {
- rb_set_black(other->rb_right);
- rb_set_red(other);
- __rb_rotate_left(other, root);
- other = parent->rb_left;
- }
- rb_set_color(other, rb_color(parent));
- rb_set_black(parent);
- rb_set_black(other->rb_left);
- __rb_rotate_right(parent, root);
- node = root->rb_node;
- break;
- }
- }
- }
- if (node)
- rb_set_black(node);
-}
-
-void rb_erase(struct rb_node *node, struct rb_root *root)
-{
- struct rb_node *child, *parent;
- int color;
-
- if (!node->rb_left)
- child = node->rb_right;
- else if (!node->rb_right)
- child = node->rb_left;
- else
- {
- struct rb_node *old = node, *left;
-
- node = node->rb_right;
- while ((left = node->rb_left) != NULL)
- node = left;
- child = node->rb_right;
- parent = rb_parent(node);
- color = rb_color(node);
-
- if (child)
- rb_set_parent(child, parent);
- if (parent == old) {
- parent->rb_right = child;
- parent = node;
- } else
- parent->rb_left = child;
-
- node->rb_parent_color = old->rb_parent_color;
- node->rb_right = old->rb_right;
- node->rb_left = old->rb_left;
-
- if (rb_parent(old))
- {
- if (rb_parent(old)->rb_left == old)
- rb_parent(old)->rb_left = node;
- else
- rb_parent(old)->rb_right = node;
- } else
- root->rb_node = node;
-
- rb_set_parent(old->rb_left, node);
- if (old->rb_right)
- rb_set_parent(old->rb_right, node);
- goto color;
- }
-
- parent = rb_parent(node);
- color = rb_color(node);
-
- if (child)
- rb_set_parent(child, parent);
- if (parent)
- {
- if (parent->rb_left == node)
- parent->rb_left = child;
- else
- parent->rb_right = child;
- }
- else
- root->rb_node = child;
-
- color:
- if (color == RB_BLACK)
- __rb_erase_color(child, parent, root);
-}
-
-/*
- * This function returns the first node (in sort order) of the tree.
- */
-struct rb_node *rb_first(const struct rb_root *root)
-{
- struct rb_node *n;
-
- n = root->rb_node;
- if (!n)
- return NULL;
- while (n->rb_left)
- n = n->rb_left;
- return n;
-}
-
-struct rb_node *rb_last(const struct rb_root *root)
-{
- struct rb_node *n;
-
- n = root->rb_node;
- if (!n)
- return NULL;
- while (n->rb_right)
- n = n->rb_right;
- return n;
-}
-
-struct rb_node *rb_next(const struct rb_node *node)
-{
- struct rb_node *parent;
-
- if (rb_parent(node) == node)
- return NULL;
-
- /* If we have a right-hand child, go down and then left as far
- as we can. */
- if (node->rb_right) {
- node = node->rb_right;
- while (node->rb_left)
- node=node->rb_left;
- return (struct rb_node *)node;
- }
-
- /* No right-hand children. Everything down and left is
- smaller than us, so any 'next' node must be in the general
- direction of our parent. Go up the tree; any time the
- ancestor is a right-hand child of its parent, keep going
- up. First time it's a left-hand child of its parent, said
- parent is our 'next' node. */
- while ((parent = rb_parent(node)) && node == parent->rb_right)
- node = parent;
-
- return parent;
-}
-
-struct rb_node *rb_prev(const struct rb_node *node)
-{
- struct rb_node *parent;
-
- if (rb_parent(node) == node)
- return NULL;
-
- /* If we have a left-hand child, go down and then right as far
- as we can. */
- if (node->rb_left) {
- node = node->rb_left;
- while (node->rb_right)
- node=node->rb_right;
- return (struct rb_node *)node;
- }
-
- /* No left-hand children. Go up till we find an ancestor which
- is a right-hand child of its parent */
- while ((parent = rb_parent(node)) && node == parent->rb_left)
- node = parent;
-
- return parent;
-}
-
-void rb_replace_node(struct rb_node *victim, struct rb_node *new,
- struct rb_root *root)
-{
- struct rb_node *parent = rb_parent(victim);
-
- /* Set the surrounding nodes to point to the replacement */
- if (parent) {
- if (victim == parent->rb_left)
- parent->rb_left = new;
- else
- parent->rb_right = new;
- } else {
- root->rb_node = new;
- }
- if (victim->rb_left)
- rb_set_parent(victim->rb_left, new);
- if (victim->rb_right)
- rb_set_parent(victim->rb_right, new);
-
- /* Copy the pointers/colour from the victim to the replacement */
- *new = *victim;
-}
diff --git a/tools/perf/util/rbtree.h b/tools/perf/util/rbtree.h
deleted file mode 100644
index 6bdc488..0000000
--- a/tools/perf/util/rbtree.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- Red Black Trees
- (C) 1999 Andrea Arcangeli <andrea@suse.de>
-
- 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
-
- linux/include/linux/rbtree.h
-
- To use rbtrees you'll have to implement your own insert and search cores.
- This will avoid us to use callbacks and to drop drammatically performances.
- I know it's not the cleaner way, but in C (not in C++) to get
- performances and genericity...
-
- Some example of insert and search follows here. The search is a plain
- normal search over an ordered tree. The insert instead must be implemented
- int two steps: as first thing the code must insert the element in
- order as a red leaf in the tree, then the support library function
- rb_insert_color() must be called. Such function will do the
- not trivial work to rebalance the rbtree if necessary.
-
------------------------------------------------------------------------
-static inline struct page * rb_search_page_cache(struct inode * inode,
- unsigned long offset)
-{
- struct rb_node * n = inode->i_rb_page_cache.rb_node;
- struct page * page;
-
- while (n)
- {
- page = rb_entry(n, struct page, rb_page_cache);
-
- if (offset < page->offset)
- n = n->rb_left;
- else if (offset > page->offset)
- n = n->rb_right;
- else
- return page;
- }
- return NULL;
-}
-
-static inline struct page * __rb_insert_page_cache(struct inode * inode,
- unsigned long offset,
- struct rb_node * node)
-{
- struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
- struct rb_node * parent = NULL;
- struct page * page;
-
- while (*p)
- {
- parent = *p;
- page = rb_entry(parent, struct page, rb_page_cache);
-
- if (offset < page->offset)
- p = &(*p)->rb_left;
- else if (offset > page->offset)
- p = &(*p)->rb_right;
- else
- return page;
- }
-
- rb_link_node(node, parent, p);
-
- return NULL;
-}
-
-static inline struct page * rb_insert_page_cache(struct inode * inode,
- unsigned long offset,
- struct rb_node * node)
-{
- struct page * ret;
- if ((ret = __rb_insert_page_cache(inode, offset, node)))
- goto out;
- rb_insert_color(node, &inode->i_rb_page_cache);
- out:
- return ret;
-}
------------------------------------------------------------------------
-*/
-
-#ifndef _LINUX_RBTREE_H
-#define _LINUX_RBTREE_H
-
-#include <stddef.h>
-
-/**
- * container_of - cast a member of a structure out to the containing structure
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-
-struct rb_node
-{
- unsigned long rb_parent_color;
-#define RB_RED 0
-#define RB_BLACK 1
- struct rb_node *rb_right;
- struct rb_node *rb_left;
-} __attribute__((aligned(sizeof(long))));
- /* The alignment might seem pointless, but allegedly CRIS needs it */
-
-struct rb_root
-{
- struct rb_node *rb_node;
-};
-
-
-#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3))
-#define rb_color(r) ((r)->rb_parent_color & 1)
-#define rb_is_red(r) (!rb_color(r))
-#define rb_is_black(r) rb_color(r)
-#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0)
-#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0)
-
-static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
-{
- rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
-}
-static inline void rb_set_color(struct rb_node *rb, int color)
-{
- rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
-}
-
-#define RB_ROOT (struct rb_root) { NULL, }
-#define rb_entry(ptr, type, member) container_of(ptr, type, member)
-
-#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
-#define RB_EMPTY_NODE(node) (rb_parent(node) == node)
-#define RB_CLEAR_NODE(node) (rb_set_parent(node, node))
-
-extern void rb_insert_color(struct rb_node *, struct rb_root *);
-extern void rb_erase(struct rb_node *, struct rb_root *);
-
-/* Find logical next and previous nodes in a tree */
-extern struct rb_node *rb_next(const struct rb_node *);
-extern struct rb_node *rb_prev(const struct rb_node *);
-extern struct rb_node *rb_first(const struct rb_root *);
-extern struct rb_node *rb_last(const struct rb_root *);
-
-/* Fast replacement of a single node without remove/rebalance/add/rebalance */
-extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
- struct rb_root *root);
-
-static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
- struct rb_node ** rb_link)
-{
- node->rb_parent_color = (unsigned long )parent;
- node->rb_left = node->rb_right = NULL;
-
- *rb_link = node;
-}
-
-#endif /* _LINUX_RBTREE_H */
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c
index 464e7ca..5249d5a 100644
--- a/tools/perf/util/strbuf.c
+++ b/tools/perf/util/strbuf.c
@@ -16,7 +16,7 @@
*/
char strbuf_slopbuf[1];
-void strbuf_init(struct strbuf *sb, size_t hint)
+void strbuf_init(struct strbuf *sb, ssize_t hint)
{
sb->alloc = sb->len = 0;
sb->buf = strbuf_slopbuf;
@@ -92,7 +92,8 @@
void strbuf_tolower(struct strbuf *sb)
{
- int i;
+ unsigned int i;
+
for (i = 0; i < sb->len; i++)
sb->buf[i] = tolower(sb->buf[i]);
}
@@ -264,7 +265,7 @@
return res;
}
-ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint)
+ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint)
{
size_t oldlen = sb->len;
size_t oldalloc = sb->alloc;
@@ -293,7 +294,7 @@
#define STRBUF_MAXLINK (2*PATH_MAX)
-int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint)
+int strbuf_readlink(struct strbuf *sb, const char *path, ssize_t hint)
{
size_t oldalloc = sb->alloc;
@@ -301,7 +302,7 @@
hint = 32;
while (hint < STRBUF_MAXLINK) {
- int len;
+ ssize_t len;
strbuf_grow(sb, hint);
len = readlink(path, sb->buf, hint);
@@ -343,7 +344,7 @@
return 0;
}
-int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
+int strbuf_read_file(struct strbuf *sb, const char *path, ssize_t hint)
{
int fd, len;
diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h
index 9ee908a..d2aa86c 100644
--- a/tools/perf/util/strbuf.h
+++ b/tools/perf/util/strbuf.h
@@ -50,7 +50,7 @@
#define STRBUF_INIT { 0, 0, strbuf_slopbuf }
/*----- strbuf life cycle -----*/
-extern void strbuf_init(struct strbuf *, size_t);
+extern void strbuf_init(struct strbuf *buf, ssize_t hint);
extern void strbuf_release(struct strbuf *);
extern char *strbuf_detach(struct strbuf *, size_t *);
extern void strbuf_attach(struct strbuf *, void *, size_t, size_t);
@@ -61,7 +61,7 @@
}
/*----- strbuf size related -----*/
-static inline size_t strbuf_avail(const struct strbuf *sb) {
+static inline ssize_t strbuf_avail(const struct strbuf *sb) {
return sb->alloc ? sb->alloc - sb->len - 1 : 0;
}
@@ -122,9 +122,9 @@
extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
/* XXX: if read fails, any partial read is undone */
-extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint);
-extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
-extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
+extern ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint);
+extern int strbuf_read_file(struct strbuf *sb, const char *path, ssize_t hint);
+extern int strbuf_readlink(struct strbuf *sb, const char *path, ssize_t hint);
extern int strbuf_getline(struct strbuf *, FILE *, int);
diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h
index 2fb117f..2fdcfee 100644
--- a/tools/perf/util/strlist.h
+++ b/tools/perf/util/strlist.h
@@ -1,7 +1,7 @@
#ifndef STRLIST_H_
#define STRLIST_H_
-#include "rbtree.h"
+#include <linux/rbtree.h>
#include <stdbool.h>
struct str_node {
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 78c2efd..4683b67 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -35,7 +35,7 @@
self = ((void *)self) + priv_size;
}
self->start = start;
- self->end = start + len - 1;
+ self->end = len ? start + len - 1 : start;
memcpy(self->name, name, namelen);
return self;
@@ -48,8 +48,12 @@
static size_t symbol__fprintf(struct symbol *self, FILE *fp)
{
- return fprintf(fp, " %llx-%llx %s\n",
+ if (!self->module)
+ return fprintf(fp, " %llx-%llx %s\n",
self->start, self->end, self->name);
+ else
+ return fprintf(fp, " %llx-%llx %s \t[%s]\n",
+ self->start, self->end, self->name, self->module->name);
}
struct dso *dso__new(const char *name, unsigned int sym_priv_size)
@@ -146,6 +150,7 @@
char *line = NULL;
size_t n;
FILE *file = fopen("/proc/kallsyms", "r");
+ int count = 0;
if (file == NULL)
goto out_failure;
@@ -188,8 +193,10 @@
if (filter && filter(self, sym))
symbol__delete(sym, self->sym_priv_size);
- else
+ else {
dso__insert_symbol(self, sym);
+ count++;
+ }
}
/*
@@ -212,7 +219,7 @@
free(line);
fclose(file);
- return 0;
+ return count;
out_delete_line:
free(line);
@@ -307,6 +314,26 @@
sym->st_size != 0;
}
+static inline int elf_sym__is_label(const GElf_Sym *sym)
+{
+ return elf_sym__type(sym) == STT_NOTYPE &&
+ sym->st_name != 0 &&
+ sym->st_shndx != SHN_UNDEF &&
+ sym->st_shndx != SHN_ABS;
+}
+
+static inline const char *elf_sec__name(const GElf_Shdr *shdr,
+ const Elf_Data *secstrs)
+{
+ return secstrs->d_buf + shdr->sh_name;
+}
+
+static inline int elf_sec__is_text(const GElf_Shdr *shdr,
+ const Elf_Data *secstrs)
+{
+ return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
+}
+
static inline const char *elf_sym__name(const GElf_Sym *sym,
const Elf_Data *symstrs)
{
@@ -448,9 +475,9 @@
}
static int dso__load_sym(struct dso *self, int fd, const char *name,
- symbol_filter_t filter, int verbose)
+ symbol_filter_t filter, int verbose, struct module *mod)
{
- Elf_Data *symstrs;
+ Elf_Data *symstrs, *secstrs;
uint32_t nr_syms;
int err = -1;
uint32_t index;
@@ -458,7 +485,7 @@
GElf_Shdr shdr;
Elf_Data *syms;
GElf_Sym sym;
- Elf_Scn *sec, *sec_dynsym;
+ Elf_Scn *sec, *sec_dynsym, *sec_strndx;
Elf *elf;
size_t dynsym_idx;
int nr = 0;
@@ -517,17 +544,29 @@
if (symstrs == NULL)
goto out_elf_end;
+ sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
+ if (sec_strndx == NULL)
+ goto out_elf_end;
+
+ secstrs = elf_getdata(sec_strndx, NULL);
+ if (symstrs == NULL)
+ goto out_elf_end;
+
nr_syms = shdr.sh_size / shdr.sh_entsize;
memset(&sym, 0, sizeof(sym));
- self->prelinked = elf_section_by_name(elf, &ehdr, &shdr,
- ".gnu.prelink_undo",
- NULL) != NULL;
+ self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
+ elf_section_by_name(elf, &ehdr, &shdr,
+ ".gnu.prelink_undo",
+ NULL) != NULL);
elf_symtab__for_each_symbol(syms, nr_syms, index, sym) {
struct symbol *f;
u64 obj_start;
+ struct section *section = NULL;
+ int is_label = elf_sym__is_label(&sym);
+ const char *section_name;
- if (!elf_sym__is_function(&sym))
+ if (!is_label && !elf_sym__is_function(&sym))
continue;
sec = elf_getscn(elf, sym.st_shndx);
@@ -535,9 +574,14 @@
goto out_elf_end;
gelf_getshdr(sec, &shdr);
+
+ if (is_label && !elf_sec__is_text(&shdr, secstrs))
+ continue;
+
+ section_name = elf_sec__name(&shdr, secstrs);
obj_start = sym.st_value;
- if (self->prelinked) {
+ if (self->adjust_symbols) {
if (verbose >= 2)
printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
(u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
@@ -545,6 +589,17 @@
sym.st_value -= shdr.sh_addr - shdr.sh_offset;
}
+ if (mod) {
+ section = mod->sections->find_section(mod->sections, section_name);
+ if (section)
+ sym.st_value += section->vma;
+ else {
+ fprintf(stderr, "dso__load_sym() module %s lookup of %s failed\n",
+ mod->name, section_name);
+ goto out_elf_end;
+ }
+ }
+
f = symbol__new(sym.st_value, sym.st_size,
elf_sym__name(&sym, symstrs),
self->sym_priv_size, obj_start, verbose);
@@ -554,6 +609,7 @@
if (filter && filter(self, f))
symbol__delete(f, self->sym_priv_size);
else {
+ f->module = mod;
dso__insert_symbol(self, f);
nr++;
}
@@ -577,7 +633,7 @@
if (!name)
return -1;
- self->prelinked = 0;
+ self->adjust_symbols = 0;
if (strncmp(self->name, "/tmp/perf-", 10) == 0)
return dso__load_perf_map(self, filter, verbose);
@@ -603,7 +659,7 @@
fd = open(name, O_RDONLY);
} while (fd < 0);
- ret = dso__load_sym(self, fd, name, filter, verbose);
+ ret = dso__load_sym(self, fd, name, filter, verbose, NULL);
close(fd);
/*
@@ -617,6 +673,86 @@
return ret;
}
+static int dso__load_module(struct dso *self, struct mod_dso *mods, const char *name,
+ symbol_filter_t filter, int verbose)
+{
+ struct module *mod = mod_dso__find_module(mods, name);
+ int err = 0, fd;
+
+ if (mod == NULL || !mod->active)
+ return err;
+
+ fd = open(mod->path, O_RDONLY);
+
+ if (fd < 0)
+ return err;
+
+ err = dso__load_sym(self, fd, name, filter, verbose, mod);
+ close(fd);
+
+ return err;
+}
+
+int dso__load_modules(struct dso *self, symbol_filter_t filter, int verbose)
+{
+ struct mod_dso *mods = mod_dso__new_dso("modules");
+ struct module *pos;
+ struct rb_node *next;
+ int err;
+
+ err = mod_dso__load_modules(mods);
+
+ if (err <= 0)
+ return err;
+
+ /*
+ * Iterate over modules, and load active symbols.
+ */
+ next = rb_first(&mods->mods);
+ while (next) {
+ pos = rb_entry(next, struct module, rb_node);
+ err = dso__load_module(self, mods, pos->name, filter, verbose);
+
+ if (err < 0)
+ break;
+
+ next = rb_next(&pos->rb_node);
+ }
+
+ if (err < 0) {
+ mod_dso__delete_modules(mods);
+ mod_dso__delete_self(mods);
+ }
+
+ return err;
+}
+
+static inline void dso__fill_symbol_holes(struct dso *self)
+{
+ struct symbol *prev = NULL;
+ struct rb_node *nd;
+
+ for (nd = rb_last(&self->syms); nd; nd = rb_prev(nd)) {
+ struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
+
+ if (prev) {
+ u64 hole = 0;
+ int alias = pos->start == prev->start;
+
+ if (!alias)
+ hole = prev->start - pos->end - 1;
+
+ if (hole || alias) {
+ if (alias)
+ pos->end = prev->end;
+ else if (hole)
+ pos->end = prev->start - 1;
+ }
+ }
+ prev = pos;
+ }
+}
+
static int dso__load_vmlinux(struct dso *self, const char *vmlinux,
symbol_filter_t filter, int verbose)
{
@@ -625,21 +761,28 @@
if (fd < 0)
return -1;
- err = dso__load_sym(self, fd, vmlinux, filter, verbose);
+ err = dso__load_sym(self, fd, vmlinux, filter, verbose, NULL);
+
+ if (err > 0)
+ dso__fill_symbol_holes(self);
+
close(fd);
return err;
}
int dso__load_kernel(struct dso *self, const char *vmlinux,
- symbol_filter_t filter, int verbose)
+ symbol_filter_t filter, int verbose, int modules)
{
int err = -1;
- if (vmlinux)
+ if (vmlinux) {
err = dso__load_vmlinux(self, vmlinux, filter, verbose);
+ if (err > 0 && modules)
+ err = dso__load_modules(self, filter, verbose);
+ }
- if (err < 0)
+ if (err <= 0)
err = dso__load_kallsyms(self, filter, verbose);
return err;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 2c48ace..7918cff 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -3,8 +3,9 @@
#include <linux/types.h>
#include "types.h"
-#include "list.h"
-#include "rbtree.h"
+#include <linux/list.h>
+#include <linux/rbtree.h>
+#include "module.h"
struct symbol {
struct rb_node rb_node;
@@ -13,6 +14,7 @@
u64 obj_start;
u64 hist_sum;
u64 *hist;
+ struct module *module;
void *priv;
char name[0];
};
@@ -22,7 +24,7 @@
struct rb_root syms;
struct symbol *(*find_symbol)(struct dso *, u64 ip);
unsigned int sym_priv_size;
- unsigned char prelinked;
+ unsigned char adjust_symbols;
char name[0];
};
@@ -41,7 +43,8 @@
struct symbol *dso__find_symbol(struct dso *self, u64 ip);
int dso__load_kernel(struct dso *self, const char *vmlinux,
- symbol_filter_t filter, int verbose);
+ symbol_filter_t filter, int verbose, int modules);
+int dso__load_modules(struct dso *self, symbol_filter_t filter, int verbose);
int dso__load(struct dso *self, symbol_filter_t filter, int verbose);
size_t dso__fprintf(struct dso *self, FILE *fp);
diff --git a/tools/perf/util/wrapper.c b/tools/perf/util/wrapper.c
index 6350d65..4574ac2 100644
--- a/tools/perf/util/wrapper.c
+++ b/tools/perf/util/wrapper.c
@@ -7,7 +7,7 @@
* There's no pack memory to release - but stay close to the Git
* version so wrap this away:
*/
-static inline void release_pack_memory(size_t size, int flag)
+static inline void release_pack_memory(size_t size __used, int flag __used)
{
}
@@ -59,7 +59,8 @@
char *xstrndup(const char *str, size_t len)
{
char *p = memchr(str, '\0', len);
- return xmemdupz(str, p ? p - str : len);
+
+ return xmemdupz(str, p ? (size_t)(p - str) : len);
}
void *xrealloc(void *ptr, size_t size)