summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.mailmap2
-rw-r--r--Documentation/ABI/obsolete/dv13949
-rw-r--r--Documentation/feature-removal-schedule.txt11
-rw-r--r--Documentation/gpio.txt31
-rw-r--r--Documentation/networking/ip-sysctl.txt9
-rw-r--r--Documentation/x86_64/boot-options.txt4
-rw-r--r--MAINTAINERS41
-rw-r--r--Makefile2
-rw-r--r--arch/alpha/kernel/core_mcpcia.c2
-rw-r--r--arch/alpha/kernel/err_titan.c1
-rw-r--r--arch/alpha/kernel/module.c8
-rw-r--r--arch/alpha/kernel/sys_nautilus.c6
-rw-r--r--arch/alpha/kernel/sys_noritake.c9
-rw-r--r--arch/alpha/kernel/sys_rawhide.c15
-rw-r--r--arch/alpha/kernel/sys_sio.c14
-rw-r--r--arch/alpha/kernel/sys_sx164.c2
-rw-r--r--arch/alpha/kernel/sys_titan.c3
-rw-r--r--arch/arm/configs/s3c2410_defconfig11
-rw-r--r--arch/arm/tools/mach-types99
-rw-r--r--arch/i386/kernel/alternative.c21
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c2
-rw-r--r--arch/i386/kernel/nmi.c17
-rw-r--r--arch/i386/kernel/vmi.c9
-rw-r--r--arch/i386/kernel/vmlinux.lds.S2
-rw-r--r--arch/ia64/kernel/msi_ia64.c4
-rw-r--r--arch/ia64/kernel/setup.c2
-rw-r--r--arch/ia64/sn/kernel/bte_error.c6
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_dma.c8
-rw-r--r--arch/mips/kernel/r2300_switch.S10
-rw-r--r--arch/mips/kernel/r4k_switch.S10
-rw-r--r--arch/mips/kernel/signal-common.h9
-rw-r--r--arch/mips/kernel/signal.c52
-rw-r--r--arch/mips/kernel/signal32.c52
-rw-r--r--arch/mips/kernel/traps.c25
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c2
-rw-r--r--arch/mips/sibyte/sb1250/setup.c12
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.c4
-rw-r--r--arch/ppc/8xx_io/commproc.c26
-rw-r--r--arch/ppc/configs/ads8272_defconfig592
-rw-r--r--arch/ppc/platforms/mpc8272ads_setup.c17
-rw-r--r--arch/ppc/platforms/mpc866ads_setup.c17
-rw-r--r--arch/ppc/platforms/mpc885ads_setup.c20
-rw-r--r--arch/sparc/kernel/pcic.c4
-rw-r--r--arch/sparc/kernel/sys_sunos.c4
-rw-r--r--arch/sparc64/kernel/pci.c4
-rw-r--r--arch/sparc64/kernel/pci_iommu.c2
-rw-r--r--arch/sparc64/kernel/sbus.c560
-rw-r--r--arch/sparc64/kernel/sys32.S1
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c4
-rw-r--r--arch/sparc64/kernel/systbls.S2
-rw-r--r--arch/sparc64/solaris/misc.c6
-rw-r--r--arch/x86_64/kernel/functionlist1
-rw-r--r--arch/x86_64/kernel/hpet.c9
-rw-r--r--arch/x86_64/kernel/k8.c4
-rw-r--r--arch/x86_64/kernel/nmi.c10
-rw-r--r--arch/x86_64/kernel/pci-gart.c6
-rw-r--r--arch/x86_64/kernel/vmlinux.lds.S2
-rw-r--r--arch/x86_64/mm/pageattr.c2
-rw-r--r--block/cfq-iosched.c46
-rw-r--r--drivers/acpi/thermal.c3
-rw-r--r--drivers/ata/pata_sis.c10
-rw-r--r--drivers/base/power/main.c6
-rw-r--r--drivers/block/cciss.c35
-rw-r--r--drivers/block/paride/pcd.c2
-rw-r--r--drivers/block/paride/pf.c2
-rw-r--r--drivers/block/pktcdvd.c3
-rw-r--r--drivers/char/agp/intel-agp.c3
-rw-r--r--drivers/char/mem.c2
-rw-r--r--drivers/char/mxser.c48
-rw-r--r--drivers/char/mxser_new.c45
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hwmon/w83627ehf.c20
-rw-r--r--drivers/i2c/busses/Kconfig3
-rw-r--r--drivers/i2c/busses/i2c-pasemi.c6
-rw-r--r--drivers/ide/Kconfig1
-rw-r--r--drivers/ide/ide-cd.c9
-rw-r--r--drivers/ide/ide-io.c6
-rw-r--r--drivers/ide/ide-iops.c2
-rw-r--r--drivers/ide/ide.c2
-rw-r--r--drivers/ide/pci/delkin_cb.c1
-rw-r--r--drivers/ide/pci/hpt366.c5
-rw-r--r--drivers/ieee1394/Kconfig6
-rw-r--r--drivers/ieee1394/dv1394.c4
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c12
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c2
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h1
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c40
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c1
-rw-r--r--drivers/kvm/mmu.c1
-rw-r--r--drivers/macintosh/smu.c4
-rw-r--r--drivers/md/bitmap.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c2
-rw-r--r--drivers/misc/asus-laptop.c151
-rw-r--r--drivers/net/Kconfig1
-rw-r--r--drivers/net/bnx2.c7
-rw-r--r--drivers/net/bnx2.h1
-rw-r--r--drivers/net/cxgb3/common.h7
-rw-r--r--drivers/net/cxgb3/cxgb3_defs.h5
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c16
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c83
-rw-r--r--drivers/net/cxgb3/regs.h6
-rw-r--r--drivers/net/cxgb3/t3_hw.c18
-rw-r--r--drivers/net/cxgb3/xgmac.c107
-rw-r--r--drivers/net/depca.c3
-rw-r--r--drivers/net/e1000/e1000_main.c13
-rw-r--r--drivers/net/hamradio/baycom_ser_fdx.c6
-rw-r--r--drivers/net/myri10ge/myri10ge.c37
-rw-r--r--drivers/net/ppp_async.c4
-rw-r--r--drivers/net/sc92031.c20
-rw-r--r--drivers/net/sis900.c44
-rw-r--r--drivers/net/skge.c93
-rw-r--r--drivers/net/sky2.c188
-rw-r--r--drivers/net/sky2.h11
-rw-r--r--drivers/net/spider_net.c2
-rw-r--r--drivers/net/sunhme.c2
-rw-r--r--drivers/net/sunlance.c4
-rw-r--r--drivers/net/sunqe.c4
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c20
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c57
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c12
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h4
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al2230.c6
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c1
-rw-r--r--drivers/parport/parport_sunbpp.c10
-rw-r--r--drivers/pci/probe.c45
-rw-r--r--drivers/sbus/char/openprom.c3
-rw-r--r--drivers/sbus/char/vfc_dev.c3
-rw-r--r--drivers/scsi/3w-xxxx.c11
-rw-r--r--drivers/scsi/qlogicpti.c2
-rw-r--r--drivers/serial/8250.c8
-rw-r--r--drivers/serial/icom.c9
-rw-r--r--drivers/serial/icom.h1
-rw-r--r--drivers/spi/spi_s3c24xx.c4
-rw-r--r--drivers/usb/host/ehci-hcd.c1
-rw-r--r--drivers/usb/net/pegasus.c17
-rw-r--r--drivers/usb/net/pegasus.h3
-rw-r--r--drivers/usb/storage/unusual_devs.h7
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--fs/9p/vfs_inode.c2
-rw-r--r--fs/autofs4/root.c6
-rw-r--r--fs/exec.c18
-rw-r--r--fs/nfs/dir.c3
-rw-r--r--fs/nfs/direct.c11
-rw-r--r--fs/nfs/inode.c6
-rw-r--r--fs/nfs/write.c197
-rw-r--r--fs/reiserfs/item_ops.c2
-rw-r--r--fs/reiserfs/xattr.c92
-rw-r--r--fs/ufs/inode.c29
-rw-r--r--include/asm-alpha/compiler.h47
-rw-r--r--include/asm-alpha/core_mcpcia.h2
-rw-r--r--include/asm-alpha/io.h1
-rw-r--r--include/asm-ia64/sn/pcibr_provider.h5
-rw-r--r--include/asm-mips/bug.h3
-rw-r--r--include/asm-mips/checksum.h2
-rw-r--r--include/asm-mips/fpu.h25
-rw-r--r--include/asm-mips/sibyte/sb1250_scd.h1
-rw-r--r--include/asm-mips/thread_info.h1
-rw-r--r--include/asm-powerpc/systbl.h2
-rw-r--r--include/linux/ide.h2
-rw-r--r--include/linux/io.h13
-rw-r--r--include/linux/ipv6.h3
-rw-r--r--include/linux/nfs_page.h31
-rw-r--r--include/linux/plist.h54
-rw-r--r--include/linux/skbuff.h10
-rw-r--r--include/linux/sysctl.h1
-rw-r--r--include/linux/taskstats.h13
-rw-r--r--kernel/params.c4
-rw-r--r--kernel/sysctl.c2
-rw-r--r--mm/migrate.c15
-rw-r--r--mm/nommu.c1
-rw-r--r--mm/oom_kill.c4
-rw-r--r--net/8021q/vlan_dev.c3
-rw-r--r--net/bridge/br_stp_if.c9
-rw-r--r--net/core/neighbour.c5
-rw-r--r--net/core/netpoll.c7
-rw-r--r--net/core/pktgen.c3
-rw-r--r--net/core/skbuff.c55
-rw-r--r--net/ipv4/fib_frontend.c8
-rw-r--r--net/ipv4/netfilter/arp_tables.c10
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c2
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c7
-rw-r--r--net/ipv4/tcp_cong.c23
-rw-r--r--net/ipv4/tcp_output.c3
-rw-r--r--net/ipv4/xfrm4_mode_beet.c4
-rw-r--r--net/ipv6/addrconf.c11
-rw-r--r--net/ipv6/exthdrs.c40
-rw-r--r--net/ipv6/route.c31
-rw-r--r--net/irda/af_irda.c3
-rw-r--r--net/key/af_key.c90
-rw-r--r--net/netlink/af_netlink.c6
-rw-r--r--net/sched/cls_tcindex.c4
-rw-r--r--net/sctp/socket.c54
-rw-r--r--net/sctp/ulpqueue.c9
-rw-r--r--net/sunrpc/clnt.c4
-rw-r--r--net/sunrpc/svcauth_unix.c21
-rw-r--r--net/sunrpc/svcsock.c16
-rw-r--r--net/sunrpc/xprt.c10
-rw-r--r--net/xfrm/xfrm_user.c7
199 files changed, 2615 insertions, 1656 deletions
diff --git a/.mailmap b/.mailmap
index bf62dbea88e..ebf9bf84da0 100644
--- a/.mailmap
+++ b/.mailmap
@@ -67,6 +67,8 @@ Koushik <raghavendra.koushik@neterion.com>
Leonid I Ananiev <leonid.i.ananiev@intel.com>
Linas Vepstas <linas@austin.ibm.com>
Matthieu CASTET <castet.matthieu@free.fr>
+Michael Buesch <mb@bu3sch.de>
+Michael Buesch <mbuesch@freenet.de>
Michel Dänzer <michel@tungstengraphics.com>
Mitesh shah <mshah@teja.com>
Morten Welinder <terra@gnome.org>
diff --git a/Documentation/ABI/obsolete/dv1394 b/Documentation/ABI/obsolete/dv1394
new file mode 100644
index 00000000000..2ee36864ca1
--- /dev/null
+++ b/Documentation/ABI/obsolete/dv1394
@@ -0,0 +1,9 @@
+What: dv1394 (a.k.a. "OHCI-DV I/O support" for FireWire)
+Contact: linux1394-devel@lists.sourceforge.net
+Description:
+ New application development should use raw1394 + userspace libraries
+ instead, notably libiec61883 which is functionally equivalent.
+
+Users:
+ ffmpeg/libavformat (used by a variety of media players)
+ dvgrab v1.x (replaced by dvgrab2 on top of raw1394 and resp. libraries)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 0bc8b0b2e10..19b4c96b2a4 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -39,17 +39,6 @@ Who: Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
---------------------------
-What: dv1394 driver (CONFIG_IEEE1394_DV1394)
-When: June 2007
-Why: Replaced by raw1394 + userspace libraries, notably libiec61883. This
- shift of application support has been indicated on www.linux1394.org
- and developers' mailinglists for quite some time. Major applications
- have been converted, with the exception of ffmpeg and hence xine.
- Piped output of dvgrab2 is a partial equivalent to dv1394.
-Who: Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
-
----------------------------
-
What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
When: December 2006
Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
index 989f1130f4f..f8528db967f 100644
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -27,7 +27,7 @@ The exact capabilities of GPIOs vary between systems. Common options:
- Output values are writable (high=1, low=0). Some chips also have
options about how that value is driven, so that for example only one
value might be driven ... supporting "wire-OR" and similar schemes
- for the other value.
+ for the other value (notably, "open drain" signaling).
- Input values are likewise readable (1, 0). Some chips support readback
of pins configured as "output", which is very useful in such "wire-OR"
@@ -247,6 +247,35 @@ with gpio_get_value(), for example to initialize or update driver state
when the IRQ is edge-triggered.
+Emulating Open Drain Signals
+----------------------------
+Sometimes shared signals need to use "open drain" signaling, where only the
+low signal level is actually driven. (That term applies to CMOS transistors;
+"open collector" is used for TTL.) A pullup resistor causes the high signal
+level. This is sometimes called a "wire-AND"; or more practically, from the
+negative logic (low=true) perspective this is a "wire-OR".
+
+One common example of an open drain signal is a shared active-low IRQ line.
+Also, bidirectional data bus signals sometimes use open drain signals.
+
+Some GPIO controllers directly support open drain outputs; many don't. When
+you need open drain signaling but your hardware doesn't directly support it,
+there's a common idiom you can use to emulate it with any GPIO pin that can
+be used as either an input or an output:
+
+ LOW: gpio_direction_output(gpio, 0) ... this drives the signal
+ and overrides the pullup.
+
+ HIGH: gpio_direction_input(gpio) ... this turns off the output,
+ so the pullup (or some other device) controls the signal.
+
+If you are "driving" the signal high but gpio_get_value(gpio) reports a low
+value (after the appropriate rise time passes), you know some other component
+is driving the shared signal low. That's not necessarily an error. As one
+common example, that's how I2C clocks are stretched: a slave that needs a
+slower clock delays the rising edge of SCK, and the I2C master adjusts its
+signaling rate accordingly.
+
What do these conventions omit?
===============================
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index d3aae1f9b4c..702d1d8dd04 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -851,6 +851,15 @@ accept_redirects - BOOLEAN
Functional default: enabled if local forwarding is disabled.
disabled if local forwarding is enabled.
+accept_source_route - INTEGER
+ Accept source routing (routing extension header).
+
+ > 0: Accept routing header.
+ = 0: Accept only routing header type 2.
+ < 0: Do not accept routing header.
+
+ Default: 0
+
autoconf - BOOLEAN
Autoconfigure addresses using Prefix Information in Router
Advertisements.
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt
index 625a21db0c2..85f51e5a749 100644
--- a/Documentation/x86_64/boot-options.txt
+++ b/Documentation/x86_64/boot-options.txt
@@ -293,7 +293,3 @@ Debugging
stuck (default)
Miscellaneous
-
- noreplacement Don't replace instructions with more appropriate ones
- for the CPU. This may be useful on asymmetric MP systems
- where some CPUs have less capabilities than others.
diff --git a/MAINTAINERS b/MAINTAINERS
index 829407ff41f..277877a34ef 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1318,7 +1318,7 @@ S: Maintained
ETHERNET BRIDGE
P: Stephen Hemminger
M: shemminger@linux-foundation.org
-L: bridge@lists.osdl.org
+L: bridge@lists.linux-foundation.org
W: http://bridge.sourceforge.net/
S: Maintained
@@ -1355,6 +1355,11 @@ M: kevin.curtis@farsite.co.uk
W: http://www.farsite.co.uk/
S: Supported
+FAULT INJECTION SUPPORT
+P: Akinobu Mita
+M: akinobu.mita@gmail.com
+S: Supported
+
FRAMEBUFFER LAYER
P: Antonino Daplas
M: adaplas@gmail.com
@@ -1404,7 +1409,7 @@ M: hch@infradead.org
W: ftp://ftp.openlinux.org/pub/people/hch/vxfs
S: Maintained
-FUJITSU FR-V PORT
+FUJITSU FR-V (FRV) PORT
P: David Howells
M: dhowells@redhat.com
S: Maintained
@@ -1690,7 +1695,7 @@ S: Maintained
IEEE 1394 SUBSYSTEM
P: Ben Collins
-M: bcollins@debian.org
+M: ben.collins@ubuntu.com
P: Stefan Richter
M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
@@ -1698,25 +1703,11 @@ W: http://www.linux1394.org/
T: git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
S: Maintained
-IEEE 1394 IPV4 DRIVER (eth1394)
-P: Stefan Richter
-M: stefanr@s5r6.in-berlin.de
-L: linux1394-devel@lists.sourceforge.net
-S: Odd Fixes
-
-IEEE 1394 PCILYNX DRIVER
-P: Jody McIntyre
-M: scjody@modernduck.com
-P: Stefan Richter
-M: stefanr@s5r6.in-berlin.de
-L: linux1394-devel@lists.sourceforge.net
-S: Odd Fixes
-
-IEEE 1394 RAW I/O DRIVER
-P: Ben Collins
-M: bcollins@debian.org
+IEEE 1394 RAW I/O DRIVER (raw1394)
P: Dan Dennedy
M: dan@dennedy.org
+P: Stefan Richter
+M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
S: Maintained
@@ -1951,7 +1942,7 @@ P: Vivek Goyal
M: vgoyal@in.ibm.com
P: Haren Myneni
M: hbabu@us.ibm.com
-L: fastboot@lists.osdl.org
+L: fastboot@lists.linux-foundation.org
L: linux-kernel@vger.kernel.org
W: http://lse.sourceforge.net/kdump/
S: Maintained
@@ -1978,7 +1969,7 @@ S: Maintained
KERNEL JANITORS
P: Several
-L: kernel-janitors@lists.osdl.org
+L: kernel-janitors@lists.linux-foundation.org
W: http://www.kerneljanitors.org/
S: Maintained
@@ -2001,7 +1992,7 @@ P: Eric Biederman
M: ebiederm@xmission.com
W: http://www.xmission.com/~ebiederm/files/kexec/
L: linux-kernel@vger.kernel.org
-L: fastboot@lists.osdl.org
+L: fastboot@lists.linux-foundation.org
S: Maintained
KPROBES
@@ -2339,7 +2330,7 @@ S: Maintained
NETEM NETWORK EMULATOR
P: Stephen Hemminger
M: shemminger@linux-foundation.org
-L: netem@lists.osdl.org
+L: netem@lists.linux-foundation.org
S: Maintained
NETFILTER/IPTABLES/IPCHAINS
@@ -3068,7 +3059,7 @@ S: Supported
SOFTWARE SUSPEND:
P: Pavel Machek
M: pavel@suse.cz
-L: linux-pm@lists.osdl.org
+L: linux-pm@lists.linux-foundation.org
S: Maintained
SONIC NETWORK DRIVER
diff --git a/Makefile b/Makefile
index 6486af1ae69..d970cb16545 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 21
-EXTRAVERSION = -rc6
+EXTRAVERSION =
NAME = Nocturnal Monster Puppy
# *DOCUMENTATION*
diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c
index 8d019071190..381fec0af52 100644
--- a/arch/alpha/kernel/core_mcpcia.c
+++ b/arch/alpha/kernel/core_mcpcia.c
@@ -40,8 +40,6 @@
# define DBG_CFG(args)
#endif
-#define MCPCIA_MAX_HOSES 4
-
/*
* Given a bus, device, and function number, compute resulting
* configuration space address and setup the MCPCIA_HAXR2 register
diff --git a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c
index febe71c6869..543d96d7fa2 100644
--- a/arch/alpha/kernel/err_titan.c
+++ b/arch/alpha/kernel/err_titan.c
@@ -16,6 +16,7 @@
#include <asm/smp.h>
#include <asm/err_common.h>
#include <asm/err_ev6.h>
+#include <asm/irq_regs.h>
#include "err_impl.h"
#include "proto.h"
diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
index aac6d4b22f7..bd03dc94c72 100644
--- a/arch/alpha/kernel/module.c
+++ b/arch/alpha/kernel/module.c
@@ -285,12 +285,12 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,
reloc_overflow:
if (ELF64_ST_TYPE (sym->st_info) == STT_SECTION)
printk(KERN_ERR
- "module %s: Relocation overflow vs section %d\n",
- me->name, sym->st_shndx);
+ "module %s: Relocation (type %lu) overflow vs section %d\n",
+ me->name, r_type, sym->st_shndx);
else
printk(KERN_ERR
- "module %s: Relocation overflow vs %s\n",
- me->name, strtab + sym->st_name);
+ "module %s: Relocation (type %lu) overflow vs %s\n",
+ me->name, r_type, strtab + sym->st_name);
return -ENOEXEC;
}
}
diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c
index e7594a7cf58..920196bcbb6 100644
--- a/arch/alpha/kernel/sys_nautilus.c
+++ b/arch/alpha/kernel/sys_nautilus.c
@@ -70,6 +70,12 @@ nautilus_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
/* Preserve the IRQ set up by the console. */
u8 irq;
+ /* UP1500: AGP INTA is actually routed to IRQ 5, not IRQ 10 as
+ console reports. Check the device id of AGP bridge to distinguish
+ UP1500 from UP1000/1100. Note: 'pin' is 2 due to bridge swizzle. */
+ if (slot == 1 && pin == 2 &&
+ dev->bus->self && dev->bus->self->device == 0x700f)
+ return 5;
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
return irq;
}
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c
index de6ba3432e8..eb2a1d63f48 100644
--- a/arch/alpha/kernel/sys_noritake.c
+++ b/arch/alpha/kernel/sys_noritake.c
@@ -66,6 +66,13 @@ noritake_startup_irq(unsigned int irq)
return 0;
}
+static void
+noritake_end_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ noritake_enable_irq(irq);
+}
+
static struct hw_interrupt_type noritake_irq_type = {
.typename = "NORITAKE",
.startup = noritake_startup_irq,
@@ -73,7 +80,7 @@ static struct hw_interrupt_type noritake_irq_type = {
.enable = noritake_enable_irq,
.disable = noritake_disable_irq,
.ack = noritake_disable_irq,
- .end = noritake_enable_irq,
+ .end = noritake_end_irq,
};
static void
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
index 581d08c70b9..672cb2df53d 100644
--- a/arch/alpha/kernel/sys_rawhide.c
+++ b/arch/alpha/kernel/sys_rawhide.c
@@ -52,6 +52,9 @@ rawhide_update_irq_hw(int hose, int mask)
*(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(hose));
}
+#define hose_exists(h) \
+ (((h) < MCPCIA_MAX_HOSES) && (cached_irq_masks[(h)] != 0))
+
static inline void
rawhide_enable_irq(unsigned int irq)
{
@@ -59,6 +62,9 @@ rawhide_enable_irq(unsigned int irq)
irq -= 16;
hose = irq / 24;
+ if (!hose_exists(hose)) /* if hose non-existent, exit */
+ return;
+
irq -= hose * 24;
mask = 1 << irq;
@@ -76,6 +82,9 @@ rawhide_disable_irq(unsigned int irq)
irq -= 16;
hose = irq / 24;
+ if (!hose_exists(hose)) /* if hose non-existent, exit */
+ return;
+
irq -= hose * 24;
mask = ~(1 << irq) | hose_irq_masks[hose];
@@ -93,6 +102,9 @@ rawhide_mask_and_ack_irq(unsigned int irq)
irq -= 16;
hose = irq / 24;
+ if (!hose_exists(hose)) /* if hose non-existent, exit */
+ return;
+
irq -= hose * 24;
mask1 = 1 << irq;
mask = ~mask1 | hose_irq_masks[hose];
@@ -169,6 +181,9 @@ rawhide_init_irq(void)
mcpcia_init_hoses();
+ /* Clear them all; only hoses that exist will be non-zero. */
+ for (i = 0; i < MCPCIA_MAX_HOSES; i++) cached_irq_masks[i] = 0;
+
for (hose = hose_head; hose; hose = hose->next) {
unsigned int h = hose->index;
unsigned int mask = hose_irq_masks[h];
diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c
index a654014d202..14b5a753aba 100644
--- a/arch/alpha/kernel/sys_sio.c
+++ b/arch/alpha/kernel/sys_sio.c
@@ -84,12 +84,16 @@ alphabook1_init_arch(void)
static void __init
sio_pci_route(void)
{
-#if defined(ALPHA_RESTORE_SRM_SETUP)
- /* First, read and save the original setting. */
+ unsigned int orig_route_tab;
+
+ /* First, ALWAYS read and print the original setting. */
pci_bus_read_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
- &saved_config.orig_route_tab);
+ &orig_route_tab);
printk("%s: PIRQ original 0x%x new 0x%x\n", __FUNCTION__,
- saved_config.orig_route_tab, alpha_mv.sys.sio.route_tab);
+ orig_route_tab, alpha_mv.sys.sio.route_tab);
+
+#if defined(ALPHA_RESTORE_SRM_SETUP)
+ saved_config.orig_route_tab = orig_route_tab;
#endif
/* Now override with desired setting. */
@@ -334,7 +338,7 @@ struct alpha_machine_vector avanti_mv __initmv = {
.pci_swizzle = common_swizzle,
.sys = { .sio = {
- .route_tab = 0x0b0a0e0f,
+ .route_tab = 0x0b0a050f, /* leave 14 for IDE, 9 for SND */
}}
};
ALIAS_MV(avanti)
diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c
index 94ad68b7c0a..41d4ad4c7c4 100644
--- a/arch/alpha/kernel/sys_sx164.c
+++ b/arch/alpha/kernel/sys_sx164.c
@@ -132,7 +132,7 @@ sx164_init_arch(void)
if (amask(AMASK_MAX) != 0
&& alpha_using_srm
- && (cpu->pal_revision & 0xffff) == 0x117) {
+ && (cpu->pal_revision & 0xffff) <= 0x117) {
__asm__ __volatile__(
"lda $16,8($31)\n"
"call_pal 9\n" /* Allow PALRES insns in kernel mode */
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
index 29ab7db81c3..f009b7bc094 100644
--- a/arch/alpha/kernel/sys_titan.c
+++ b/arch/alpha/kernel/sys_titan.c
@@ -257,8 +257,7 @@ titan_dispatch_irqs(u64 mask)
*/
while (mask) {
/* convert to SRM vector... priority is <63> -> <0> */
- __asm__("ctlz %1, %0" : "=r"(vector) : "r"(mask));
- vector = 63 - vector;
+ vector = 63 - __kernel_ctlz(mask);
mask &= ~(1UL << vector); /* clear it out */
vector = 0x900 + (vector << 4); /* convert to SRM vector */
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index d4ca0f06be5..a850da377a2 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21-rc1
-# Wed Feb 21 16:48:01 2007
+# Linux kernel version: 2.6.21-rc6
+# Mon Apr 9 10:12:58 2007
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
# CONFIG_GENERIC_TIME is not set
CONFIG_MMU=y
CONFIG_NO_IOPORT=y
@@ -45,6 +46,7 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_IKCONFIG is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
@@ -531,7 +533,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
CONFIG_ATA_OVER_ETH=m
@@ -560,7 +561,6 @@ CONFIG_IDE_GENERIC=y
CONFIG_BLK_DEV_IDE_BAST=y
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
#
@@ -941,6 +941,7 @@ CONFIG_LEDS_CLASS=m
# LED drivers
#
CONFIG_LEDS_S3C24XX=m
+CONFIG_LEDS_H1940=m
#
# LED Triggers
@@ -1125,6 +1126,7 @@ CONFIG_USB_MON=y
# 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
#
@@ -1169,7 +1171,6 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_DS1672 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_PCF8563 is not set
-# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_RS5C372 is not set
CONFIG_RTC_DRV_S3C=y
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index bd78058b717..b1142ce4ac4 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
#
# http://www.arm.linux.org.uk/developer/machines/?action=new
#
-# Last update: Tue Jan 16 16:52:56 2007
+# Last update: Mon Apr 16 21:01:04 2007
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -1190,13 +1190,12 @@ g500 MACH_G500 G500 1178
bug MACH_BUG BUG 1179
mx33ads MACH_MX33ADS MX33ADS 1180
chub MACH_CHUB CHUB 1181
-gta01 MACH_GTA01 GTA01 1182
+neo1973_gta01 MACH_NEO1973_GTA01 NEO1973_GTA01 1182
w90n740 MACH_W90N740 W90N740 1183
medallion_sa2410 MACH_MEDALLION_SA2410 MEDALLION_SA2410 1184
ia_cpu_9200_2 MACH_IA_CPU_9200_2 IA_CPU_9200_2 1185
dimmrm9200 MACH_DIMMRM9200 DIMMRM9200 1186
pm9261 MACH_PM9261 PM9261 1187
-mx21 MACH_MX21 MX21 1188
ml7304 MACH_ML7304 ML7304 1189
ucp250 MACH_UCP250 UCP250 1190
intboard MACH_INTBOARD INTBOARD 1191
@@ -1242,3 +1241,97 @@ xscale_treo680 MACH_XSCALE_TREO680 XSCALE_TREO680 1230
tecon_tmezon MACH_TECON_TMEZON TECON_TMEZON 1231
zylonite MACH_ZYLONITE ZYLONITE 1233
gene1270 MACH_GENE1270 GENE1270 1234
+zir2412 MACH_ZIR2412 ZIR2412 1235
+mx31lite MACH_MX31LITE MX31LITE 1236
+t700wx MACH_T700WX T700WX 1237
+vf100 MACH_VF100 VF100 1238
+nsb2 MACH_NSB2 NSB2 1239
+nxhmi_bb MACH_NXHMI_BB NXHMI_BB 1240
+nxhmi_re MACH_NXHMI_RE NXHMI_RE 1241
+n4100pro MACH_N4100PRO N4100PRO 1242
+sam9260 MACH_SAM9260 SAM9260 1243
+omap_treo600 MACH_OMAP_TREO600 OMAP_TREO600 1244
+indy2410 MACH_INDY2410 INDY2410 1245
+nelt_a MACH_NELT_A NELT_A 1246
+n311 MACH_N311 N311 1248
+at91sam9260vgk MACH_AT91SAM9260VGK AT91SAM9260VGK 1249
+at91leppe MACH_AT91LEPPE AT91LEPPE 1250
+at91lepccn MACH_AT91LEPCCN AT91LEPCCN 1251
+apc7100 MACH_APC7100 APC7100 1252
+stargazer MACH_STARGAZER STARGAZER 1253
+sonata MACH_SONATA SONATA 1254
+schmoogie MACH_SCHMOOGIE SCHMOOGIE 1255
+aztool MACH_AZTOOL AZTOOL 1256
+mioa701 MACH_MIOA701 MIOA701 1257
+sxni9260 MACH_SXNI9260 SXNI9260 1258
+mxc27520evb MACH_MXC27520EVB MXC27520EVB 1259
+armadillo5x0 MACH_ARMADILLO5X0 ARMADILLO5X0 1260
+mb9260 MACH_MB9260 MB9260 1261
+mb9263 MACH_MB9263 MB9263 1262
+ipac9302 MACH_IPAC9302 IPAC9302 1263
+cc9p9360js MACH_CC9P9360JS CC9P9360JS 1264
+gallium MACH_GALLIUM GALLIUM 1265
+msc2410 MACH_MSC2410 MSC2410 1266
+ghi270 MACH_GHI270 GHI270 1267
+davinci_leonardo MACH_DAVINCI_LEONARDO DAVINCI_LEONARDO 1268
+oiab MACH_OIAB OIAB 1269
+smdk6400 MACH_SMDK6400 SMDK6400 1270
+nokia_n800 MACH_NOKIA_N800 NOKIA_N800 1271
+greenphone MACH_GREENPHONE GREENPHONE 1272
+compex42x MACH_COMPEXWP18 COMPEXWP18 1273
+xmate MACH_XMATE XMATE 1274
+energizer MACH_ENERGIZER ENERGIZER 1275
+ime1 MACH_IME1 IME1 1276
+sweda_tms MACH_SWEDATMS SWEDATMS 1277
+ntnp435c MACH_NTNP435C NTNP435C 1278
+spectro2 MACH_SPECTRO2 SPECTRO2 1279
+h6039 MACH_H6039 H6039 1280
+ep80219 MACH_EP80219 EP80219 1281
+samoa_ii MACH_SAMOA_II SAMOA_II 1282
+cwmxl MACH_CWMXL CWMXL 1283
+as9200 MACH_AS9200 AS9200 1284
+sfx1149 MACH_SFX1149 SFX1149 1285
+navi010 MACH_NAVI010 NAVI010 1286
+multmdp MACH_MULTMDP MULTMDP 1287
+scb9520 MACH_SCB9520 SCB9520 1288
+htcathena MACH_HTCATHENA HTCATHENA 1289
+xp179 MACH_XP179 XP179 1290
+h4300 MACH_H4300 H4300 1291
+goramo_mlr MACH_GORAMO_MLR GORAMO_MLR 1292
+mxc30020evb MACH_MXC30020EVB MXC30020EVB 1293
+adsbitsymx MACH_ADSBITSIMX ADSBITSIMX 1294
+adsportalplus MACH_ADSPORTALPLUS ADSPORTALPLUS 1295
+mmsp2plus MACH_MMSP2PLUS MMSP2PLUS 1296
+em_x270 MACH_EM_X270 EM_X270 1297
+tpp302 MACH_TPP302 TPP302 1298
+tpp104 MACH_TPM104 TPM104 1299
+tpm102 MACH_TPM102 TPM102 1300
+tpm109 MACH_TPM109 TPM109 1301
+fbxo1 MACH_FBXO1 FBXO1 1302
+hxd8 MACH_HXD8 HXD8 1303
+neo1973_gta02 MACH_NEO1973_GTA02 NEO1973_GTA02 1304
+emtest MACH_EMTEST EMTEST 1305
+ad6900 MACH_AD6900 AD6900 1306
+europa MACH_EUROPA EUROPA 1307
+metroconnect MACH_METROCONNECT METROCONNECT 1308
+ez_s2410 MACH_EZ_S2410 EZ_S2410 1309
+ez_s2440 MACH_EZ_S2440 EZ_S2440 1310
+ez_ep9312 MACH_EZ_EP9312 EZ_EP9312 1311
+ez_ep9315 MACH_EZ_EP9315 EZ_EP9315 1312
+ez_x7 MACH_EZ_X7 EZ_X7 1313
+godotdb MACH_GODOTDB GODOTDB 1314
+mistral MACH_MISTRAL MISTRAL 1315
+msm MACH_MSM MSM 1316
+ct5910 MACH_CT5910 CT5910 1317
+ct5912 MACH_CT5912 CT5912 1318
+hynet_ine MACH_HYNET_INE HYNET_INE 1319
+hynet_app MACH_HYNET_APP HYNET_APP 1320
+msm7200 MACH_MSM7200 MSM7200 1321
+msm7600 MACH_MSM7600 MSM7600 1322
+ceb255 MACH_CEB255 CEB255 1323
+ciel MACH_CIEL CIEL 1324
+slm5650 MACH_SLM5650 SLM5650 1325
+at91sam9rlek MACH_AT91SAM9RLEK AT91SAM9RLEK 1326
+comtech_router MACH_COMTECH_ROUTER COMTECH_ROUTER 1327
+sbc2410x MACH_SBC2410X SBC2410X 1328
+at4x0bd MACH_AT4X0BD AT4X0BD 1329
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c
index 9eca21b49f6..426f59b0106 100644
--- a/arch/i386/kernel/alternative.c
+++ b/arch/i386/kernel/alternative.c
@@ -5,15 +5,9 @@
#include <asm/alternative.h>
#include <asm/sections.h>
-static int no_replacement = 0;
static int smp_alt_once = 0;
static int debug_alternative = 0;
-static int __init noreplacement_setup(char *s)
-{
- no_replacement = 1;
- return 1;
-}
static int __init bootonly(char *str)
{
smp_alt_once = 1;
@@ -25,7 +19,6 @@ static int __init debug_alt(char *str)
return 1;
}
-__setup("noreplacement", noreplacement_setup);
__setup("smp-alt-boot", bootonly);
__setup("debug-alternative", debug_alt);
@@ -252,9 +245,6 @@ void alternatives_smp_module_add(struct module *mod, char *name,
struct smp_alt_module *smp;
unsigned long flags;
- if (no_replacement)
- return;
-
if (smp_alt_once) {
if (boot_cpu_has(X86_FEATURE_UP))
alternatives_smp_unlock(locks, locks_end,
@@ -289,7 +279,7 @@ void alternatives_smp_module_del(struct module *mod)
struct smp_alt_module *item;
unsigned long flags;
- if (no_replacement || smp_alt_once)
+ if (smp_alt_once)
return;
spin_lock_irqsave(&smp_alt, flags);
@@ -320,7 +310,7 @@ void alternatives_smp_switch(int smp)
return;
#endif
- if (no_replacement || smp_alt_once)
+ if (smp_alt_once)
return;
BUG_ON(!smp && (num_online_cpus() > 1));
@@ -386,13 +376,6 @@ extern struct paravirt_patch __start_parainstructions[],
void __init alternative_instructions(void)
{
unsigned long flags;
- if (no_replacement) {
- printk(KERN_INFO "(SMP-)alternatives turned off\n");
- free_init_pages("SMP alternatives",
- (unsigned long)__smp_alt_begin,
- (unsigned long)__smp_alt_end);
- return;
- }
local_irq_save(flags);
apply_alternatives(__alt_instructions, __alt_instructions_end);
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index a1f1b715bcf..2b030d6ccbf 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -758,7 +758,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
NULL, (void *)&pr);
/* Check ACPI support for C3 state */
- if (pr != NULL && longhaul_version != TYPE_LONGHAUL_V1) {
+ if (pr != NULL && longhaul_version == TYPE_POWERSAVER) {
cx = &pr->power.states[ACPI_STATE_C3];
if (cx->address > 0 && cx->latency <= 1000) {
longhaul_flags |= USE_ACPI_C3;
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index a98ba88a8c0..84c3497efb6 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -41,16 +41,17 @@ int nmi_watchdog_enabled;
* different subsystems this reservation system just tries to coordinate
* things a little
*/
-static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner);
-static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[3]);
-
-static cpumask_t backtrace_mask = CPU_MASK_NONE;
/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's
* offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now)
*/
#define NMI_MAX_COUNTER_BITS 66
+#define NMI_MAX_COUNTER_LONGS BITS_TO_LONGS(NMI_MAX_COUNTER_BITS)
+static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner[NMI_MAX_COUNTER_LONGS]);
+static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[NMI_MAX_COUNTER_LONGS]);
+
+static cpumask_t backtrace_mask = CPU_MASK_NONE;
/* nmi_active:
* >0: the lapic NMI watchdog is active, but can be disabled
* <0: the lapic NMI watchdog has not been set up, and cannot
@@ -125,7 +126,7 @@ int avail_to_resrv_perfctr_nmi_bit(unsigned int counter)
int cpu;
BUG_ON(counter > NMI_MAX_COUNTER_BITS);
for_each_possible_cpu (cpu) {
- if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+ if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0]))
return 0;
}
return 1;
@@ -141,7 +142,7 @@ int avail_to_resrv_perfctr_nmi(unsigned int msr)
BUG_ON(counter > NMI_MAX_COUNTER_BITS);
for_each_possible_cpu (cpu) {
- if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+ if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0]))
return 0;
}
return 1;
@@ -156,7 +157,7 @@ static int __reserve_perfctr_nmi(int cpu, unsigned int msr)
counter = nmi_perfctr_msr_to_bit(msr);
BUG_ON(counter > NMI_MAX_COUNTER_BITS);
- if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+ if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0]))
return 1;
return 0;
}
@@ -170,7 +171,7 @@ static void __release_perfctr_nmi(int cpu, unsigned int msr)
counter = nmi_perfctr_msr_to_bit(msr);
BUG_ON(counter > NMI_MAX_COUNTER_BITS);
- clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu));
+ clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0]);
}
int reserve_perfctr_nmi(unsigned int msr)
diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c
index edc339fa503..697a70e8c0c 100644
--- a/arch/i386/kernel/vmi.c
+++ b/arch/i386/kernel/vmi.c
@@ -712,11 +712,14 @@ static void *vmi_get_function(int vmicall)
do { \
reloc = call_vrom_long_func(vmi_rom, get_reloc, \
VMI_CALL_##vmicall); \
- if (rel->type != VMI_RELOCATION_NONE) { \
- BUG_ON(rel->type != VMI_RELOCATION_CALL_REL); \
+ if (rel->type == VMI_RELOCATION_CALL_REL) \
paravirt_ops.opname = (void *)rel->eip; \
- } else if (rel->type == VMI_RELOCATION_NOP) \
+ else if (rel->type == VMI_RELOCATION_NOP) \
paravirt_ops.opname = (void *)vmi_nop; \
+ else if (rel->type != VMI_RELOCATION_NONE) \
+ printk(KERN_WARNING "VMI: Unknown relocation " \
+ "type %d for " #vmicall"\n",\
+ rel->type); \
} while (0)
/*
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index ca51610955d..6f38f818380 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -26,7 +26,7 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(phys_startup_32)
jiffies = jiffies_64;
-_proxy_pda = 0;
+_proxy_pda = 1;
PHDRS {
text PT_LOAD FLAGS(5); /* R_E */
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index ebbeadfee42..c81080df70d 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -76,7 +76,7 @@ int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
set_irq_msi(irq, desc);
dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
- vector = irq;
+ vector = irq_to_vector(irq);
msg.address_hi = 0;
msg.address_lo =
@@ -110,7 +110,7 @@ static void ia64_ack_msi_irq(unsigned int irq)
static int ia64_msi_retrigger_irq(unsigned int irq)
{
- unsigned int vector = irq;
+ unsigned int vector = irq_to_vector(irq);
ia64_resend_irq(vector);
return 1;
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 69b9bb3fd7c..dc7dd7648ec 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -640,7 +640,7 @@ show_cpuinfo (struct seq_file *m, void *v)
"features : %s\n"
"cpu number : %lu\n"
"cpu regs : %u\n"
- "cpu MHz : %lu.%06lu\n"
+ "cpu MHz : %lu.%03lu\n"
"itc MHz : %lu.%06lu\n"
"BogoMIPS : %lu.%02lu\n",
cpunum, c->vendor, c->family, c->model,
diff --git a/arch/ia64/sn/kernel/bte_error.c b/arch/ia64/sn/kernel/bte_error.c
index f1ec1370b3e..b6fcf8164f2 100644
--- a/arch/ia64/sn/kernel/bte_error.c
+++ b/arch/ia64/sn/kernel/bte_error.c
@@ -78,7 +78,7 @@ int shub1_bte_error_handler(unsigned long _nodepda)
* There are errors which still need to be cleaned up by
* hubiio_crb_error_handler
*/
- mod_timer(recovery_timer, HZ * 5);
+ mod_timer(recovery_timer, jiffies + (HZ * 5));
BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
smp_processor_id()));
return 1;
@@ -95,7 +95,7 @@ int shub1_bte_error_handler(unsigned long _nodepda)
icrbd.ii_icrb0_d_regval =
REMOTE_HUB_L(nasid, IIO_ICRB_D(i));
if (icrbd.d_bteop) {
- mod_timer(recovery_timer, HZ * 5);
+ mod_timer(recovery_timer, jiffies + (HZ * 5));
BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n",
err_nodepda, smp_processor_id(),
i));
@@ -150,7 +150,7 @@ int shub2_bte_error_handler(unsigned long _nodepda)
status = BTE_LNSTAT_LOAD(bte);
if ((status & IBLS_ERROR) || !(status & IBLS_BUSY))
continue;
- mod_timer(recovery_timer, HZ * 5);
+ mod_timer(recovery_timer, jiffies + (HZ * 5));
BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
smp_processor_id()));
return 1;
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
index 1ee977fb6eb..95af40cb22f 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
@@ -96,10 +96,14 @@ pcibr_dmamap_ate32(struct pcidev_info *info,
}
/*
- * If we're mapping for MSI, set the MSI bit in the ATE
+ * If we're mapping for MSI, set the MSI bit in the ATE. If it's a
+ * TIOCP based pci bus, we also need to set the PIO bit in the ATE.
*/
- if (dma_flags & SN_DMA_MSI)
+ if (dma_flags & SN_DMA_MSI) {
ate |= PCI32_ATE_MSI;
+ if (IS_TIOCP_SOFT(pcibus_info))
+ ate |= PCI32_ATE_PIO;
+ }
ate_write(pcibus_info, ate_index, ate_count, ate);
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
index 28c2e2e6af7..656bde2e11b 100644
--- a/arch/mips/kernel/r2300_switch.S
+++ b/arch/mips/kernel/r2300_switch.S
@@ -49,7 +49,8 @@ LEAF(resume)
#ifndef CONFIG_CPU_HAS_LLSC
sw zero, ll_bit
#endif
- mfc0 t2, CP0_STATUS
+ mfc0 t1, CP0_STATUS
+ sw t1, THREAD_STATUS(a0)
cpu_save_nonscratch a0
sw ra, THREAD_REG31(a0)
@@ -59,8 +60,8 @@ LEAF(resume)
lw t3, TASK_THREAD_INFO(a0)
lw t0, TI_FLAGS(t3)
li t1, _TIF_USEDFPU
- and t1, t0
- beqz t1, 1f
+ and t2, t0, t1
+ beqz t2, 1f
nor t1, zero, t1
and t0, t0, t1
@@ -73,13 +74,10 @@ LEAF(resume)
li t1, ~ST0_CU1
and t0, t0, t1
sw t0, ST_OFF(t3)
- /* clear thread_struct CU1 bit */
- and t2, t1
fpu_save_single a0, t0 # clobbers t0
1:
- sw t2, THREAD_STATUS(a0)
/*
* The order of restoring the registers takes care of the race
* updating $28, $29 and kernelsp without disabling ints.
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index c7698fd9955..cc566cf1224 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -48,7 +48,8 @@
#ifndef CONFIG_CPU_HAS_LLSC
sw zero, ll_bit
#endif
- mfc0 t2, CP0_STATUS
+ mfc0 t1, CP0_STATUS
+ LONG_S t1, THREAD_STATUS(a0)
cpu_save_nonscratch a0
LONG_S ra, THREAD_REG31(a0)
@@ -58,8 +59,8 @@
PTR_L t3, TASK_THREAD_INFO(a0)
LONG_L t0, TI_FLAGS(t3)
li t1, _TIF_USEDFPU
- and t1, t0
- beqz t1, 1f
+ and t2, t0, t1
+ beqz t2, 1f
nor t1, zero, t1
and t0, t0, t1
@@ -72,13 +73,10 @@
li t1, ~ST0_CU1
and t0, t0, t1
LONG_S t0, ST_OFF(t3)
- /* clear thread_struct CU1 bit */
- and t2, t1
fpu_save_double a0 t0 t1 # c0_status passed in t0
# clobbers t1
1:
- LONG_S t2, THREAD_STATUS(a0)
/*
* The order of restoring the registers takes care of the race
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index 297dfcb9752..c0faabd5201 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -34,4 +34,13 @@ extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
/* Check and clear pending FPU exceptions in saved CSR */
extern int fpcsr_pending(unsigned int __user *fpcsr);
+/* Make sure we will not lose FPU ownership */
+#ifdef CONFIG_PREEMPT
+#define lock_fpu_owner() preempt_disable()
+#define unlock_fpu_owner() preempt_enable()
+#else
+#define lock_fpu_owner() pagefault_disable()
+#define unlock_fpu_owner() pagefault_enable()
+#endif
+
#endif /* __SIGNAL_COMMON_H */
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 8c3c5a5789b..07d67309451 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -20,6 +20,7 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/compiler.h>
+#include <linux/uaccess.h>
#include <asm/abi.h>
#include <asm/asm.h>
@@ -27,7 +28,6 @@
#include <asm/cacheflush.h>
#include <asm/fpu.h>
#include <asm/sim.h>
-#include <asm/uaccess.h>
#include <asm/ucontext.h>
#include <asm/cpu-features.h>
#include <asm/war.h>
@@ -78,6 +78,46 @@ struct rt_sigframe {
/*
* Helper routines
*/
+static int protected_save_fp_context(struct sigcontext __user *sc)
+{
+ int err;
+ while (1) {
+ lock_fpu_owner();
+ own_fpu_inatomic(1);
+ err = save_fp_context(sc); /* this might fail */
+ unlock_fpu_owner();
+ if (likely(!err))
+ break;
+ /* touch the sigcontext and try again */
+ err = __put_user(0, &sc->sc_fpregs[0]) |
+ __put_user(0, &sc->sc_fpregs[31]) |
+ __put_user(0, &sc->sc_fpc_csr);
+ if (err)
+ break; /* really bad sigcontext */
+ }
+ return err;
+}
+
+static int protected_restore_fp_context(struct sigcontext __user *sc)
+{
+ int err, tmp;
+ while (1) {
+ lock_fpu_owner();
+ own_fpu_inatomic(0);
+ err = restore_fp_context(sc); /* this might fail */
+ unlock_fpu_owner();
+ if (likely(!err))
+ break;
+ /* touch the sigcontext and try again */
+ err = __get_user(tmp, &sc->sc_fpregs[0]) |
+ __get_user(tmp, &sc->sc_fpregs[31]) |
+ __get_user(tmp, &sc->sc_fpc_csr);
+ if (err)
+ break; /* really bad sigcontext */
+ }
+ return err;
+}
+
int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
{
int err = 0;
@@ -113,10 +153,7 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
* Save FPU state to signal context. Signal handler
* will "inherit" current FPU state.
*/
- own_fpu(1);
- enable_fp_in_kernel();
- err |= save_fp_context(sc);
- disable_fp_in_kernel();
+ err |= protected_save_fp_context(sc);
}
return err;
}
@@ -148,7 +185,7 @@ check_and_restore_fp_context(struct sigcontext __user *sc)
err = sig = fpcsr_pending(&sc->sc_fpc_csr);
if (err > 0)
err = 0;
- err |= restore_fp_context(sc);
+ err |= protected_restore_fp_context(sc);
return err ?: sig;
}
@@ -187,11 +224,8 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
if (used_math) {
/* restore fpu context if we have used it before */
- own_fpu(0);
- enable_fp_in_kernel();
if (!err)
err = check_and_restore_fp_context(sc);
- disable_fp_in_kernel();
} else {
/* signal handler may have used FPU. Give it up. */
lose_fpu(0);
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 151fd2f0893..b9a014411f8 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -22,6 +22,7 @@
#include <linux/compat.h>
#include <linux/suspend.h>
#include <linux/compiler.h>
+#include <linux/uaccess.h>
#include <asm/abi.h>
#include <asm/asm.h>
@@ -29,7 +30,6 @@
#include <linux/bitops.h>
#include <asm/cacheflush.h>
#include <asm/sim.h>
-#include <asm/uaccess.h>
#include <asm/ucontext.h>
#include <asm/system.h>
#include <asm/fpu.h>
@@ -176,6 +176,46 @@ struct rt_sigframe32 {
/*
* sigcontext handlers
*/
+static int protected_save_fp_context32(struct sigcontext32 __user *sc)
+{
+ int err;
+ while (1) {
+ lock_fpu_owner();
+ own_fpu_inatomic(1);
+ err = save_fp_context32(sc); /* this might fail */
+ unlock_fpu_owner();
+ if (likely(!err))
+ break;
+ /* touch the sigcontext and try again */
+ err = __put_user(0, &sc->sc_fpregs[0]) |
+ __put_user(0, &sc->sc_fpregs[31]) |
+ __put_user(0, &sc->sc_fpc_csr);
+ if (err)
+ break; /* really bad sigcontext */
+ }
+ return err;
+}
+
+static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
+{
+ int err, tmp;
+ while (1) {
+ lock_fpu_owner();
+ own_fpu_inatomic(0);
+ err = restore_fp_context32(sc); /* this might fail */
+ unlock_fpu_owner();
+ if (likely(!err))
+ break;
+ /* touch the sigcontext and try again */
+ err = __get_user(tmp, &sc->sc_fpregs[0]) |
+ __get_user(tmp, &sc->sc_fpregs[31]) |
+ __get_user(tmp, &sc->sc_fpc_csr);
+ if (err)
+ break; /* really bad sigcontext */
+ }
+ return err;
+}
+
static int setup_sigcontext32(struct pt_regs *regs,
struct sigcontext32 __user *sc)
{
@@ -209,10 +249,7 @@ static int setup_sigcontext32(struct pt_regs *regs,
* Save FPU state to signal context. Signal handler
* will "inherit" current FPU state.
*/
- own_fpu(1);
- enable_fp_in_kernel();
- err |= save_fp_context32(sc);
- disable_fp_in_kernel();
+ err |= protected_save_fp_context32(sc);
}
return err;
}
@@ -225,7 +262,7 @@ check_and_restore_fp_context32(struct sigcontext32 __user *sc)
err = sig = fpcsr_pending(&sc->sc_fpc_csr);
if (err > 0)
err = 0;
- err |= restore_fp_context32(sc);
+ err |= protected_restore_fp_context32(sc);
return err ?: sig;
}
@@ -261,11 +298,8 @@ static int restore_sigcontext32(struct pt_regs *regs,
if (used_math) {
/* restore fpu context if we have used it before */
- own_fpu(0);
- enable_fp_in_kernel();
if (!err)
err = check_and_restore_fp_context32(sc);
- disable_fp_in_kernel();
} else {
/* signal handler may have used FPU. Give it up. */
lose_fpu(0);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 7d76a85422b..493cb29b8a4 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -650,7 +650,7 @@ asmlinkage void do_bp(struct pt_regs *regs)
unsigned int opcode, bcode;
siginfo_t info;
- if (get_user(opcode, (unsigned int __user *) exception_epc(regs)))
+ if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
goto out_sigsegv;
/*
@@ -700,7 +700,7 @@ asmlinkage void do_tr(struct pt_regs *regs)
unsigned int opcode, tcode = 0;
siginfo_t info;
- if (get_user(opcode, (unsigned int __user *) exception_epc(regs)))
+ if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
goto out_sigsegv;
/* Immediate versions don't provide a code. */
@@ -757,11 +757,12 @@ asmlinkage void do_cpu(struct pt_regs *regs)
{
unsigned int cpid;
+ die_if_kernel("do_cpu invoked from kernel context!", regs);
+
cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
switch (cpid) {
case 0:
- die_if_kernel("do_cpu invoked from kernel context!", regs);
if (!cpu_has_llsc)
if (!simulate_llsc(regs))
return;
@@ -772,9 +773,6 @@ asmlinkage void do_cpu(struct pt_regs *regs)
break;
case 1:
- if (!test_thread_flag(TIF_ALLOW_FP_IN_KERNEL))
- die_if_kernel("do_cpu invoked from kernel context!",
- regs);
if (used_math()) /* Using the FPU again. */
own_fpu(1);
else { /* First time FPU user. */
@@ -782,19 +780,7 @@ asmlinkage void do_cpu(struct pt_regs *regs)
set_used_math();
}
- if (raw_cpu_has_fpu) {
- if (test_thread_flag(TIF_ALLOW_FP_IN_KERNEL)) {
- local_irq_disable();
- if (cpu_has_fpu)
- regs->cp0_status |= ST0_CU1;
- /*
- * We must return without enabling
- * interrupts to ensure keep FPU
- * ownership until resume.
- */
- return;
- }
- } else {
+ if (!raw_cpu_has_fpu) {
int sig;
sig = fpu_emulator_cop1Handler(regs,
&current->thread.fpu, 0);
@@ -836,7 +822,6 @@ asmlinkage void do_cpu(struct pt_regs *regs)
case 2:
case 3:
- die_if_kernel("do_cpu invoked from kernel context!", regs);
break;
}
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index 69a8bcfe72b..4f94fa261aa 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -35,7 +35,7 @@
#define vpe_id() smp_processor_id()
#else
#define WHAT 0
-#define vpe_id() smp_processor_id()
+#define vpe_id() 0
#endif
#define __define_perf_accessors(r, n, np) \
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c
index 87188f0f6fb..f4a6169aa0a 100644
--- a/arch/mips/sibyte/sb1250/setup.c
+++ b/arch/mips/sibyte/sb1250/setup.c
@@ -141,6 +141,18 @@ static int __init setup_bcm112x(void)
periph_rev = 3;
pass_str = "A2";
break;
+ case K_SYS_REVISION_BCM112x_A3:
+ periph_rev = 3;
+ pass_str = "A3";
+ break;
+ case K_SYS_REVISION_BCM112x_A4:
+ periph_rev = 3;
+ pass_str = "A4";
+ break;
+ case K_SYS_REVISION_BCM112x_B0:
+ periph_rev = 3;
+ pass_str = "B0";
+ break;
default:
printk("Unknown %s rev %x\n", soc_str, soc_pass);
ret = 1;
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index c75192567e5..fbfff95b443 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -128,7 +128,7 @@ static void mpc52xx_main_mask(unsigned int virq)
pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
- io_be_setbit(&intr->main_mask, 15 - l2irq);
+ io_be_setbit(&intr->main_mask, 16 - l2irq);
}
static void mpc52xx_main_unmask(unsigned int virq)
@@ -141,7 +141,7 @@ static void mpc52xx_main_unmask(unsigned int virq)
pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
- io_be_clrbit(&intr->main_mask, 15 - l2irq);
+ io_be_clrbit(&intr->main_mask, 16 - l2irq);
}
static struct irq_chip mpc52xx_main_irqchip = {
diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c
index 3b23bcb35b7..7a8722beac1 100644
--- a/arch/ppc/8xx_io/commproc.c
+++ b/arch/ppc/8xx_io/commproc.c
@@ -39,6 +39,21 @@
#include <asm/tlbflush.h>
#include <asm/rheap.h>
+#define immr_map(member) \
+({ \
+ u32 offset = offsetof(immap_t, member); \
+ void *addr = ioremap (IMAP_ADDR + offset, \
+ sizeof( ((immap_t*)0)->member)); \
+ addr; \
+})
+
+#define immr_map_size(member, size) \
+({ \
+ u32 offset = offsetof(immap_t, member); \
+ void *addr = ioremap (IMAP_ADDR + offset, size); \
+ addr; \
+})
+
static void m8xx_cpm_dpinit(void);
static uint host_buffer; /* One page of host buffer */
static uint host_end; /* end + 1 */
@@ -364,11 +379,16 @@ static rh_block_t cpm_boot_dpmem_rh_block[16];
static rh_info_t cpm_dpmem_info;
#define CPM_DPMEM_ALIGNMENT 8
+static u8* dpram_vbase;
+static uint dpram_pbase;
void m8xx_cpm_dpinit(void)
{
spin_lock_init(&cpm_dpmem_lock);
+ dpram_vbase = immr_map_size(im_cpm.cp_dpmem, CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE);
+ dpram_pbase = (uint)&((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem;
+
/* Initialize the info header */
rh_init(&cpm_dpmem_info, CPM_DPMEM_ALIGNMENT,
sizeof(cpm_boot_dpmem_rh_block) /
@@ -442,3 +462,9 @@ void *cpm_dpram_addr(uint offset)
return ((immap_t *)IMAP_ADDR)->im_cpm.cp_dpmem + offset;
}
EXPORT_SYMBOL(cpm_dpram_addr);
+
+uint cpm_dpram_phys(u8* addr)
+{
+ return (dpram_pbase + (uint)(addr - dpram_vbase));
+}
+EXPORT_SYMBOL(cpm_dpram_phys);
diff --git a/arch/ppc/configs/ads8272_defconfig b/arch/ppc/configs/ads8272_defconfig
index d1db7d14780..6619f9118b0 100644
--- a/arch/ppc/configs/ads8272_defconfig
+++ b/arch/ppc/configs/ads8272_defconfig
@@ -1,42 +1,69 @@
#
# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc5
+# Wed Apr 4 20:55:16 2007
#
CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_HAVE_DEC_LOCK=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_PPC=y
CONFIG_PPC32=y
CONFIG_GENERIC_NVRAM=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
#
# Loadable module support
@@ -44,66 +71,124 @@ CONFIG_IOSCHED_CFQ=y
# CONFIG_MODULES is not set
#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
# Processor
#
CONFIG_6xx=y
# CONFIG_40x is not set
# CONFIG_44x is not set
-# CONFIG_POWER3 is not set
-# CONFIG_POWER4 is not set
# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+# CONFIG_E500 is not set
+CONFIG_PPC_FPU=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_KEXEC is not set
# CONFIG_CPU_FREQ is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
CONFIG_EMBEDDEDBOOT=y
CONFIG_PPC_STD_MMU=y
#
# Platform options
#
-# CONFIG_PPC_MULTIPLATFORM is not set
+
+#
+# Freescale Ethernet driver platform-specific options
+#
+# CONFIG_PPC_PREP is not set
# CONFIG_APUS is not set
+# CONFIG_KATANA is not set
# CONFIG_WILLOW is not set
-# CONFIG_PCORE is not set
+# CONFIG_CPCI690 is not set
# CONFIG_POWERPMC250 is not set
-# CONFIG_EV64260 is not set
+# CONFIG_CHESTNUT is not set
# CONFIG_SPRUCE is not set
+# CONFIG_HDPU is not set
+# CONFIG_EV64260 is not set
# CONFIG_LOPEC is not set
-# CONFIG_MCPN765 is not set
# CONFIG_MVME5100 is not set
# CONFIG_PPLUS is not set
# CONFIG_PRPMC750 is not set
# CONFIG_PRPMC800 is not set
# CONFIG_SANDPOINT is not set
-# CONFIG_ADIR is not set
-# CONFIG_K2 is not set
+# CONFIG_RADSTONE_PPC7D is not set
# CONFIG_PAL4 is not set
-# CONFIG_GEMINI is not set
# CONFIG_EST8260 is not set
# CONFIG_SBC82xx is not set
# CONFIG_SBS8260 is not set
-# CONFIG_RPX6 is not set
+# CONFIG_RPX8260 is not set
# CONFIG_TQM8260 is not set
CONFIG_ADS8272=y
+# CONFIG_PQ2FADS is not set
+# CONFIG_LITE5200 is not set
+# CONFIG_MPC834x_SYS is not set
+# CONFIG_EV64360 is not set
CONFIG_PQ2ADS=y
CONFIG_8260=y
CONFIG_8272=y
CONFIG_CPM2=y
# CONFIG_PC_KEYBOARD is not set
-CONFIG_SERIAL_CONSOLE=y
# CONFIG_SMP is not set
-# CONFIG_PREEMPT is not set
# CONFIG_HIGHMEM is not set
-CONFIG_KERNEL_ELF=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
#
# Bus options
#
+CONFIG_ZONE_DMA=y
+# CONFIG_PPC_I8259 is not set
+CONFIG_PPC_INDIRECT_PCI=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
-# CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
+CONFIG_PCI_8260=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
#
# Advanced setup
@@ -120,12 +205,110 @@ CONFIG_TASK_SIZE=0x80000000
CONFIG_BOOT_LOAD=0x00400000
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_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=y
+# 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_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
# Device Drivers
#
#
# Generic Driver Options
#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
#
# Memory Technology Devices (MTD)
@@ -140,6 +323,7 @@ CONFIG_BOOT_LOAD=0x00400000
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -149,14 +333,23 @@ CONFIG_BOOT_LOAD=0x00400000
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_CARMEL is not set
+# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_LBD is not set
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -166,7 +359,14 @@ CONFIG_BLK_DEV_INITRD=y
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
@@ -176,6 +376,7 @@ CONFIG_BLK_DEV_INITRD=y
#
# Fusion MPT device support
#
+# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@@ -190,70 +391,12 @@ CONFIG_BLK_DEV_INITRD=y
#
# Macintosh device drivers
#
+# CONFIG_MAC_EMUMOUSEBTN is not set
+# CONFIG_WINDFARM is not set
#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV 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_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_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED 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_DUMMY is not set
# CONFIG_BONDING is not set
@@ -266,13 +409,31 @@ CONFIG_NETDEVICES=y
# CONFIG_ARCNET is not set
#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+CONFIG_DAVICOM_PHY=y
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_OAKNET is not set
+CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
#
@@ -281,6 +442,9 @@ CONFIG_NET_ETHERNET=y
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_NET_PCI is not set
+CONFIG_FS_ENET=y
+# CONFIG_FS_ENET_HAS_SCC is not set
+CONFIG_FS_ENET_HAS_FCC=y
#
# Ethernet (1000 Mbit)
@@ -292,14 +456,24 @@ CONFIG_NET_ETHERNET=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
#
# Token Ring devices
@@ -321,6 +495,8 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@@ -336,6 +512,7 @@ CONFIG_NET_ETHERNET=y
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
#
# Userland interfaces
@@ -347,14 +524,6 @@ CONFIG_INPUT=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -364,6 +533,12 @@ CONFIG_SOUND_GAMEPORT=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -377,10 +552,21 @@ CONFIG_SOUND_GAMEPORT=y
#
# Non-8250 serial port support
#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+CONFIG_SERIAL_CPM_SCC1=y
+# CONFIG_SERIAL_CPM_SCC2 is not set
+# CONFIG_SERIAL_CPM_SCC3 is not set
+CONFIG_SERIAL_CPM_SCC4=y
+# CONFIG_SERIAL_CPM_SMC1 is not set
+# CONFIG_SERIAL_CPM_SMC2 is not set
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_QIC02_TAPE is not set
#
# IPMI
@@ -391,29 +577,53 @@ CONFIG_LEGACY_PTY_COUNT=256
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
# CONFIG_NVRAM is not set
CONFIG_GEN_RTC=y
# CONFIG_GEN_RTC_X is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
# CONFIG_AGP is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
#
-# Misc devices
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
#
# Multimedia devices
@@ -428,7 +638,9 @@ CONFIG_GEN_RTC=y
#
# Graphics support
#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_FB is not set
+# CONFIG_FB_IBM_GXT4500 is not set
#
# Sound
@@ -436,35 +648,110 @@ CONFIG_GEN_RTC=y
# CONFIG_SOUND is not set
#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
# USB support
#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_USB is not set
#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_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=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -475,7 +762,8 @@ CONFIG_FS_MBCACHE=y
#
# DOS/FAT/NT Filesystems
#
-# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
# CONFIG_NTFS_FS is not set
#
@@ -483,12 +771,13 @@ CONFIG_FS_MBCACHE=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -511,20 +800,26 @@ CONFIG_RAMFS=y
# Network File Systems
#
CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
@@ -537,46 +832,99 @@ CONFIG_PARTITION_ADVANCED=y
# CONFIG_MAC_PARTITION is not set
# CONFIG_MSDOS_PARTITION is not set
# CONFIG_LDM_PARTITION is not set
-# CONFIG_NEC98_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
#
# Native Language Support
#
# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
# CONFIG_SCC_ENET is not set
-CONFIG_FEC_ENET=y
-# CONFIG_USE_MDIO is not set
+# CONFIG_FEC_ENET is not set
#
# CPM2 Options
#
-CONFIG_SCC_CONSOLE=y
-CONFIG_FCC1_ENET=y
-# CONFIG_FCC2_ENET is not set
-# CONFIG_FCC3_ENET is not set
#
# Library routines
#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
# CONFIG_CRC32 is not set
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+# CONFIG_PROFILING is not set
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_KGDB_CONSOLE is not set
#
# Security options
#
+# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c
index 0bc06768cf2..47f4b38edb5 100644
--- a/arch/ppc/platforms/mpc8272ads_setup.c
+++ b/arch/ppc/platforms/mpc8272ads_setup.c
@@ -18,6 +18,7 @@
#include <linux/ioport.h>
#include <linux/fs_enet_pd.h>
#include <linux/platform_device.h>
+#include <linux/phy.h>
#include <asm/io.h>
#include <asm/mpc8260.h>
@@ -30,10 +31,10 @@
#include "pq2ads_pd.h"
-static void init_fcc1_ioports(void);
-static void init_fcc2_ioports(void);
-static void init_scc1_uart_ioports(void);
-static void init_scc4_uart_ioports(void);
+static void init_fcc1_ioports(struct fs_platform_info*);
+static void init_fcc2_ioports(struct fs_platform_info*);
+static void init_scc1_uart_ioports(struct fs_uart_platform_info*);
+static void init_scc4_uart_ioports(struct fs_uart_platform_info*);
static struct fs_uart_platform_info mpc8272_uart_pdata[] = {
[fsid_scc1_uart] = {
@@ -103,7 +104,7 @@ static struct fs_platform_info mpc82xx_enet_pdata[] = {
},
};
-static void init_fcc1_ioports(struct fs_platform_info*)
+static void init_fcc1_ioports(struct fs_platform_info* pdata)
{
struct io_port *io;
u32 tempval;
@@ -144,7 +145,7 @@ static void init_fcc1_ioports(struct fs_platform_info*)
iounmap(immap);
}
-static void init_fcc2_ioports(struct fs_platform_info*)
+static void init_fcc2_ioports(struct fs_platform_info* pdata)
{
cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32));
@@ -229,7 +230,7 @@ static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev,
}
}
-static void init_scc1_uart_ioports(struct fs_uart_platform_info*)
+static void init_scc1_uart_ioports(struct fs_uart_platform_info* pdata)
{
cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
@@ -246,7 +247,7 @@ static void init_scc1_uart_ioports(struct fs_uart_platform_info*)
iounmap(immap);
}
-static void init_scc4_uart_ioports(struct fs_uart_platform_info*)
+static void init_scc4_uart_ioports(struct fs_uart_platform_info* pdata)
{
cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c
index 5b05d4bd0df..7ce5364fdb3 100644
--- a/arch/ppc/platforms/mpc866ads_setup.c
+++ b/arch/ppc/platforms/mpc866ads_setup.c
@@ -21,6 +21,7 @@
#include <linux/fs_enet_pd.h>
#include <linux/fs_uart_pd.h>
#include <linux/mii.h>
+#include <linux/phy.h>
#include <asm/delay.h>
#include <asm/io.h>
@@ -37,10 +38,10 @@
extern unsigned char __res[];
-static void setup_fec1_ioports(void);
-static void setup_scc1_ioports(void);
-static void setup_smc1_ioports(void);
-static void setup_smc2_ioports(void);
+static void setup_fec1_ioports(struct fs_platform_info*);
+static void setup_scc1_ioports(struct fs_platform_info*);
+static void setup_smc1_ioports(struct fs_uart_platform_info*);
+static void setup_smc2_ioports(struct fs_uart_platform_info*);
static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata;
@@ -137,7 +138,7 @@ void __init board_init(void)
iounmap(bcsr_io);
}
-static void setup_fec1_ioports(struct fs_platform_info*)
+static void setup_fec1_ioports(struct fs_platform_info* pdata)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
@@ -145,7 +146,7 @@ static void setup_fec1_ioports(struct fs_platform_info*)
setbits16(&immap->im_ioport.iop_pddir, 0x1fff);
}
-static void setup_scc1_ioports(struct fs_platform_info*)
+static void setup_scc1_ioports(struct fs_platform_info* pdata)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
@@ -194,7 +195,7 @@ static void setup_scc1_ioports(struct fs_platform_info*)
}
-static void setup_smc1_ioports(struct fs_uart_platform_info*)
+static void setup_smc1_ioports(struct fs_uart_platform_info* pdata)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
@@ -216,7 +217,7 @@ static void setup_smc1_ioports(struct fs_uart_platform_info*)
}
-static void setup_smc2_ioports(struct fs_uart_platform_info*)
+static void setup_smc2_ioports(struct fs_uart_platform_info* pdata)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c
index f8161f3557f..87deaefd6c5 100644
--- a/arch/ppc/platforms/mpc885ads_setup.c
+++ b/arch/ppc/platforms/mpc885ads_setup.c
@@ -35,13 +35,13 @@
#include <asm/ppc_sys.h>
extern unsigned char __res[];
-static void setup_smc1_ioports(void);
-static void setup_smc2_ioports(void);
+static void setup_smc1_ioports(struct fs_uart_platform_info*);
+static void setup_smc2_ioports(struct fs_uart_platform_info*);
static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata;
-static void setup_fec1_ioports(void);
-static void setup_fec2_ioports(void);
-static void setup_scc3_ioports(void);
+static void setup_fec1_ioports(struct fs_platform_info*);
+static void setup_fec2_ioports(struct fs_platform_info*);
+static void setup_scc3_ioports(struct fs_platform_info*);
static struct fs_uart_platform_info mpc885_uart_pdata[] = {
[fsid_smc1_uart] = {
@@ -161,7 +161,7 @@ void __init board_init(void)
#endif
}
-static void setup_fec1_ioports(struct fs_platform_info*)
+static void setup_fec1_ioports(struct fs_platform_info* pdata)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
@@ -181,7 +181,7 @@ static void setup_fec1_ioports(struct fs_platform_info*)
clrbits32(&immap->im_cpm.cp_cptr, 0x00000100);
}
-static void setup_fec2_ioports(struct fs_platform_info*)
+static void setup_fec2_ioports(struct fs_platform_info* pdata)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
@@ -193,7 +193,7 @@ static void setup_fec2_ioports(struct fs_platform_info*)
clrbits32(&immap->im_cpm.cp_cptr, 0x00000080);
}
-static void setup_scc3_ioports(struct fs_platform_info*)
+static void setup_scc3_ioports(struct fs_platform_info* pdata)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
@@ -315,7 +315,7 @@ static void __init mpc885ads_fixup_scc_enet_pdata(struct platform_device *pdev,
mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
}
-static void setup_smc1_ioports(struct fs_uart_platform_info*)
+static void setup_smc1_ioports(struct fs_uart_platform_info* pdata)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
@@ -335,7 +335,7 @@ static void setup_smc1_ioports(struct fs_uart_platform_info*)
clrbits16(&immap->im_cpm.cp_pbodr, iobits);
}
-static void setup_smc2_ioports(struct fs_uart_platform_info*)
+static void setup_smc2_ioports(struct fs_uart_platform_info* pdata)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
unsigned *bcsr_io;
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 3fa5f95c461..1c927c538b8 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -601,7 +601,7 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node)
/*
* Normally called from {do_}pci_scan_bus...
*/
-void __init pcibios_fixup_bus(struct pci_bus *bus)
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
{
struct pci_dev *dev;
int i, has_io, has_mem;
@@ -842,7 +842,7 @@ static void watchdog_reset() {
/*
* Other archs parse arguments here.
*/
-char * __init pcibios_setup(char *str)
+char * __devinit pcibios_setup(char *str)
{
return str;
}
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index da6606f0cff..f807172cab0 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -910,7 +910,7 @@ asmlinkage long sunos_sysconf (int name)
ret = ARG_MAX;
break;
case _SC_CHILD_MAX:
- ret = -1; /* no limit */
+ ret = current->signal->rlim[RLIMIT_NPROC].rlim_cur;
break;
case _SC_CLK_TCK:
ret = HZ;
@@ -919,7 +919,7 @@ asmlinkage long sunos_sysconf (int name)
ret = NGROUPS_MAX;
break;
case _SC_OPEN_MAX:
- ret = OPEN_MAX;
+ ret = current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
break;
case _SC_JOB_CONTROL:
ret = 1; /* yes, we do support job control */
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 196b4b72482..12109886bb1 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -327,7 +327,7 @@ static int __init pcibios_init(void)
subsys_initcall(pcibios_init);
-void pcibios_fixup_bus(struct pci_bus *pbus)
+void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
{
struct pci_pbm_info *pbm = pbus->sysdata;
@@ -405,7 +405,7 @@ void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res,
}
EXPORT_SYMBOL(pcibios_bus_to_resource);
-char * __init pcibios_setup(char *str)
+char * __devinit pcibios_setup(char *str)
{
return str;
}
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 2e7f1427088..7aca0f33f88 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -64,7 +64,7 @@ static void __iommu_flushall(struct pci_iommu *iommu)
#define IOPTE_IS_DUMMY(iommu, iopte) \
((iopte_val(*iopte) & IOPTE_PAGE) == (iommu)->dummy_page_pa)
-static void inline iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte)
+static inline void iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte)
{
unsigned long val = iopte_val(*iopte);
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index 01d6d869ea2..14f78fb5e89 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -24,48 +24,25 @@
#include "iommu_common.h"
-/* These should be allocated on an SMP_CACHE_BYTES
- * aligned boundary for optimal performance.
- *
- * On SYSIO, using an 8K page size we have 1GB of SBUS
- * DMA space mapped. We divide this space into equally
- * sized clusters. We allocate a DMA mapping from the
- * cluster that matches the order of the allocation, or
- * if the order is greater than the number of clusters,
- * we try to allocate from the last cluster.
- */
-
-#define NCLUSTERS 8UL
-#define ONE_GIG (1UL * 1024UL * 1024UL * 1024UL)
-#define CLUSTER_SIZE (ONE_GIG / NCLUSTERS)
-#define CLUSTER_MASK (CLUSTER_SIZE - 1)
-#define CLUSTER_NPAGES (CLUSTER_SIZE >> IO_PAGE_SHIFT)
#define MAP_BASE ((u32)0xc0000000)
+struct sbus_iommu_arena {
+ unsigned long *map;
+ unsigned int hint;
+ unsigned int limit;
+};
+
struct sbus_iommu {
-/*0x00*/spinlock_t lock;
+ spinlock_t lock;
-/*0x08*/iopte_t *page_table;
-/*0x10*/unsigned long strbuf_regs;
-/*0x18*/unsigned long iommu_regs;
-/*0x20*/unsigned long sbus_control_reg;
+ struct sbus_iommu_arena arena;
-/*0x28*/volatile unsigned long strbuf_flushflag;
+ iopte_t *page_table;
+ unsigned long strbuf_regs;
+ unsigned long iommu_regs;
+ unsigned long sbus_control_reg;
- /* If NCLUSTERS is ever decresed to 4 or lower,
- * you must increase the size of the type of
- * these counters. You have been duly warned. -DaveM
- */
-/*0x30*/struct {
- u16 next;
- u16 flush;
- } alloc_info[NCLUSTERS];
-
- /* The lowest used consistent mapping entry. Since
- * we allocate consistent maps out of cluster 0 this
- * is relative to the beginning of closter 0.
- */
-/*0x50*/u32 lowest_consistent_map;
+ volatile unsigned long strbuf_flushflag;
};
/* Offsets from iommu_regs */
@@ -91,19 +68,6 @@ static void __iommu_flushall(struct sbus_iommu *iommu)
tag += 8UL;
}
upa_readq(iommu->sbus_control_reg);
-
- for (entry = 0; entry < NCLUSTERS; entry++) {
- iommu->alloc_info[entry].flush =
- iommu->alloc_info[entry].next;
- }
-}
-
-static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages)
-{
- while (npages--)
- upa_writeq(base + (npages << IO_PAGE_SHIFT),
- iommu->iommu_regs + IOMMU_FLUSH);
- upa_readq(iommu->sbus_control_reg);
}
/* Offsets from strbuf_regs */
@@ -156,178 +120,115 @@ static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long
base, npages);
}
-static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages)
+/* Based largely upon the ppc64 iommu allocator. */
+static long sbus_arena_alloc(struct sbus_iommu *iommu, unsigned long npages)
{
- iopte_t *iopte, *limit, *first, *cluster;
- unsigned long cnum, ent, nent, flush_point, found;
-
- cnum = 0;
- nent = 1;
- while ((1UL << cnum) < npages)
- cnum++;
- if(cnum >= NCLUSTERS) {
- nent = 1UL << (cnum - NCLUSTERS);
- cnum = NCLUSTERS - 1;
- }
- iopte = iommu->page_table + (cnum * CLUSTER_NPAGES);
-
- if (cnum == 0)
- limit = (iommu->page_table +
- iommu->lowest_consistent_map);
- else
- limit = (iopte + CLUSTER_NPAGES);
-
- iopte += ((ent = iommu->alloc_info[cnum].next) << cnum);
- flush_point = iommu->alloc_info[cnum].flush;
-
- first = iopte;
- cluster = NULL;
- found = 0;
- for (;;) {
- if (iopte_val(*iopte) == 0UL) {
- found++;
- if (!cluster)
- cluster = iopte;
+ struct sbus_iommu_arena *arena = &iommu->arena;
+ unsigned long n, i, start, end, limit;
+ int pass;
+
+ limit = arena->limit;
+ start = arena->hint;
+ pass = 0;
+
+again:
+ n = find_next_zero_bit(arena->map, limit, start);
+ end = n + npages;
+ if (unlikely(end >= limit)) {
+ if (likely(pass < 1)) {
+ limit = start;
+ start = 0;
+ __iommu_flushall(iommu);
+ pass++;
+ goto again;
} else {
- /* Used cluster in the way */
- cluster = NULL;
- found = 0;
+ /* Scanned the whole thing, give up. */
+ return -1;
}
+ }
- if (found == nent)
- break;
-
- iopte += (1 << cnum);
- ent++;
- if (iopte >= limit) {
- iopte = (iommu->page_table + (cnum * CLUSTER_NPAGES));
- ent = 0;
-
- /* Multiple cluster allocations must not wrap */
- cluster = NULL;
- found = 0;
+ for (i = n; i < end; i++) {
+ if (test_bit(i, arena->map)) {
+ start = i + 1;
+ goto again;
}
- if (ent == flush_point)
- __iommu_flushall(iommu);
- if (iopte == first)
- goto bad;
}
- /* ent/iopte points to the last cluster entry we're going to use,
- * so save our place for the next allocation.
- */
- if ((iopte + (1 << cnum)) >= limit)
- ent = 0;
- else
- ent = ent + 1;
- iommu->alloc_info[cnum].next = ent;
- if (ent == flush_point)
- __iommu_flushall(iommu);
-
- /* I've got your streaming cluster right here buddy boy... */
- return cluster;
-
-bad:
- printk(KERN_EMERG "sbus: alloc_streaming_cluster of npages(%ld) failed!\n",
- npages);
- return NULL;
+ for (i = n; i < end; i++)
+ __set_bit(i, arena->map);
+
+ arena->hint = end;
+
+ return n;
}
-static void free_streaming_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages)
+static void sbus_arena_free(struct sbus_iommu_arena *arena, unsigned long base, unsigned long npages)
{
- unsigned long cnum, ent, nent;
- iopte_t *iopte;
+ unsigned long i;
- cnum = 0;
- nent = 1;
- while ((1UL << cnum) < npages)
- cnum++;
- if(cnum >= NCLUSTERS) {
- nent = 1UL << (cnum - NCLUSTERS);
- cnum = NCLUSTERS - 1;
- }
- ent = (base & CLUSTER_MASK) >> (IO_PAGE_SHIFT + cnum);
- iopte = iommu->page_table + ((base - MAP_BASE) >> IO_PAGE_SHIFT);
- do {
- iopte_val(*iopte) = 0UL;
- iopte += 1 << cnum;
- } while(--nent);
-
- /* If the global flush might not have caught this entry,
- * adjust the flush point such that we will flush before
- * ever trying to reuse it.
- */
-#define between(X,Y,Z) (((Z) - (Y)) >= ((X) - (Y)))
- if (between(ent, iommu->alloc_info[cnum].next, iommu->alloc_info[cnum].flush))
- iommu->alloc_info[cnum].flush = ent;
-#undef between
+ for (i = base; i < (base + npages); i++)
+ __clear_bit(i, arena->map);
}
-/* We allocate consistent mappings from the end of cluster zero. */
-static iopte_t *alloc_consistent_cluster(struct sbus_iommu *iommu, unsigned long npages)
+static void sbus_iommu_table_init(struct sbus_iommu *iommu, unsigned int tsbsize)
{
- iopte_t *iopte;
+ unsigned long tsbbase, order, sz, num_tsb_entries;
- iopte = iommu->page_table + (1 * CLUSTER_NPAGES);
- while (iopte > iommu->page_table) {
- iopte--;
- if (!(iopte_val(*iopte) & IOPTE_VALID)) {
- unsigned long tmp = npages;
+ num_tsb_entries = tsbsize / sizeof(iopte_t);
- while (--tmp) {
- iopte--;
- if (iopte_val(*iopte) & IOPTE_VALID)
- break;
- }
- if (tmp == 0) {
- u32 entry = (iopte - iommu->page_table);
+ /* Setup initial software IOMMU state. */
+ spin_lock_init(&iommu->lock);
- if (entry < iommu->lowest_consistent_map)
- iommu->lowest_consistent_map = entry;
- return iopte;
- }
- }
+ /* Allocate and initialize the free area map. */
+ sz = num_tsb_entries / 8;
+ sz = (sz + 7UL) & ~7UL;
+ iommu->arena.map = kzalloc(sz, GFP_KERNEL);
+ if (!iommu->arena.map) {
+ prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n");
+ prom_halt();
+ }
+ iommu->arena.limit = num_tsb_entries;
+
+ /* Now allocate and setup the IOMMU page table itself. */
+ order = get_order(tsbsize);
+ tsbbase = __get_free_pages(GFP_KERNEL, order);
+ if (!tsbbase) {
+ prom_printf("IOMMU: Error, gfp(tsb) failed.\n");
+ prom_halt();
}
- return NULL;
+ iommu->page_table = (iopte_t *)tsbbase;
+ memset(iommu->page_table, 0, tsbsize);
}
-static void free_consistent_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages)
+static inline iopte_t *alloc_npages(struct sbus_iommu *iommu, unsigned long npages)
{
- iopte_t *iopte = iommu->page_table + ((base - MAP_BASE) >> IO_PAGE_SHIFT);
+ long entry;
- if ((iopte - iommu->page_table) == iommu->lowest_consistent_map) {
- iopte_t *walk = iopte + npages;
- iopte_t *limit;
+ entry = sbus_arena_alloc(iommu, npages);
+ if (unlikely(entry < 0))
+ return NULL;
- limit = iommu->page_table + CLUSTER_NPAGES;
- while (walk < limit) {
- if (iopte_val(*walk) != 0UL)
- break;
- walk++;
- }
- iommu->lowest_consistent_map =
- (walk - iommu->page_table);
- }
+ return iommu->page_table + entry;
+}
- while (npages--)
- *iopte++ = __iopte(0UL);
+static inline void free_npages(struct sbus_iommu *iommu, dma_addr_t base, unsigned long npages)
+{
+ sbus_arena_free(&iommu->arena, base >> IO_PAGE_SHIFT, npages);
}
void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma_addr)
{
- unsigned long order, first_page, flags;
struct sbus_iommu *iommu;
iopte_t *iopte;
+ unsigned long flags, order, first_page;
void *ret;
int npages;
- if (size <= 0 || sdev == NULL || dvma_addr == NULL)
- return NULL;
-
size = IO_PAGE_ALIGN(size);
order = get_order(size);
if (order >= 10)
return NULL;
+
first_page = __get_free_pages(GFP_KERNEL|__GFP_COMP, order);
if (first_page == 0UL)
return NULL;
@@ -336,108 +237,121 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma
iommu = sdev->bus->iommu;
spin_lock_irqsave(&iommu->lock, flags);
- iopte = alloc_consistent_cluster(iommu, size >> IO_PAGE_SHIFT);
- if (iopte == NULL) {
- spin_unlock_irqrestore(&iommu->lock, flags);
+ iopte = alloc_npages(iommu, size >> IO_PAGE_SHIFT);
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
+ if (unlikely(iopte == NULL)) {
free_pages(first_page, order);
return NULL;
}
- /* Ok, we're committed at this point. */
- *dvma_addr = MAP_BASE + ((iopte - iommu->page_table) << IO_PAGE_SHIFT);
+ *dvma_addr = (MAP_BASE +
+ ((iopte - iommu->page_table) << IO_PAGE_SHIFT));
ret = (void *) first_page;
npages = size >> IO_PAGE_SHIFT;
+ first_page = __pa(first_page);
while (npages--) {
- *iopte++ = __iopte(IOPTE_VALID | IOPTE_CACHE | IOPTE_WRITE |
- (__pa(first_page) & IOPTE_PAGE));
+ iopte_val(*iopte) = (IOPTE_VALID | IOPTE_CACHE |
+ IOPTE_WRITE |
+ (first_page & IOPTE_PAGE));
+ iopte++;
first_page += IO_PAGE_SIZE;
}
- iommu_flush(iommu, *dvma_addr, size >> IO_PAGE_SHIFT);
- spin_unlock_irqrestore(&iommu->lock, flags);
return ret;
}
void sbus_free_consistent(struct sbus_dev *sdev, size_t size, void *cpu, dma_addr_t dvma)
{
- unsigned long order, npages;
struct sbus_iommu *iommu;
-
- if (size <= 0 || sdev == NULL || cpu == NULL)
- return;
+ iopte_t *iopte;
+ unsigned long flags, order, npages;
npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT;
iommu = sdev->bus->iommu;
+ iopte = iommu->page_table +
+ ((dvma - MAP_BASE) >> IO_PAGE_SHIFT);
+
+ spin_lock_irqsave(&iommu->lock, flags);
+
+ free_npages(iommu, dvma - MAP_BASE, npages);
- spin_lock_irq(&iommu->lock);
- free_consistent_cluster(iommu, dvma, npages);
- iommu_flush(iommu, dvma, npages);
- spin_unlock_irq(&iommu->lock);
+ spin_unlock_irqrestore(&iommu->lock, flags);
order = get_order(size);
if (order < 10)
free_pages((unsigned long)cpu, order);
}
-dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size, int dir)
+dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t sz, int direction)
{
- struct sbus_iommu *iommu = sdev->bus->iommu;
- unsigned long npages, pbase, flags;
- iopte_t *iopte;
- u32 dma_base, offset;
- unsigned long iopte_bits;
+ struct sbus_iommu *iommu;
+ iopte_t *base;
+ unsigned long flags, npages, oaddr;
+ unsigned long i, base_paddr;
+ u32 bus_addr, ret;
+ unsigned long iopte_protection;
+
+ iommu = sdev->bus->iommu;
- if (dir == SBUS_DMA_NONE)
+ if (unlikely(direction == SBUS_DMA_NONE))
BUG();
- pbase = (unsigned long) ptr;
- offset = (u32) (pbase & ~IO_PAGE_MASK);
- size = (IO_PAGE_ALIGN(pbase + size) - (pbase & IO_PAGE_MASK));
- pbase = (unsigned long) __pa(pbase & IO_PAGE_MASK);
+ oaddr = (unsigned long)ptr;
+ npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK);
+ npages >>= IO_PAGE_SHIFT;
spin_lock_irqsave(&iommu->lock, flags);
- npages = size >> IO_PAGE_SHIFT;
- iopte = alloc_streaming_cluster(iommu, npages);
- if (iopte == NULL)
- goto bad;
- dma_base = MAP_BASE + ((iopte - iommu->page_table) << IO_PAGE_SHIFT);
- npages = size >> IO_PAGE_SHIFT;
- iopte_bits = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE;
- if (dir != SBUS_DMA_TODEVICE)
- iopte_bits |= IOPTE_WRITE;
- while (npages--) {
- *iopte++ = __iopte(iopte_bits | (pbase & IOPTE_PAGE));
- pbase += IO_PAGE_SIZE;
- }
- npages = size >> IO_PAGE_SHIFT;
+ base = alloc_npages(iommu, npages);
spin_unlock_irqrestore(&iommu->lock, flags);
- return (dma_base | offset);
+ if (unlikely(!base))
+ BUG();
-bad:
- spin_unlock_irqrestore(&iommu->lock, flags);
- BUG();
- return 0;
+ bus_addr = (MAP_BASE +
+ ((base - iommu->page_table) << IO_PAGE_SHIFT));
+ ret = bus_addr | (oaddr & ~IO_PAGE_MASK);
+ base_paddr = __pa(oaddr & IO_PAGE_MASK);
+
+ iopte_protection = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE;
+ if (direction != SBUS_DMA_TODEVICE)
+ iopte_protection |= IOPTE_WRITE;
+
+ for (i = 0; i < npages; i++, base++, base_paddr += IO_PAGE_SIZE)
+ iopte_val(*base) = iopte_protection | base_paddr;
+
+ return ret;
}
-void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size, int direction)
+void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t bus_addr, size_t sz, int direction)
{
struct sbus_iommu *iommu = sdev->bus->iommu;
- u32 dma_base = dma_addr & IO_PAGE_MASK;
- unsigned long flags;
+ iopte_t *base;
+ unsigned long flags, npages, i;
+
+ if (unlikely(direction == SBUS_DMA_NONE))
+ BUG();
+
+ npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK);
+ npages >>= IO_PAGE_SHIFT;
+ base = iommu->page_table +
+ ((bus_addr - MAP_BASE) >> IO_PAGE_SHIFT);
- size = (IO_PAGE_ALIGN(dma_addr + size) - dma_base);
+ bus_addr &= IO_PAGE_MASK;
spin_lock_irqsave(&iommu->lock, flags);
- free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT);
- sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT, direction);
+ sbus_strbuf_flush(iommu, bus_addr, npages, direction);
+ for (i = 0; i < npages; i++)
+ iopte_val(base[i]) = 0UL;
+ free_npages(iommu, bus_addr - MAP_BASE, npages);
spin_unlock_irqrestore(&iommu->lock, flags);
}
#define SG_ENT_PHYS_ADDRESS(SG) \
(__pa(page_address((SG)->page)) + (SG)->offset)
-static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, int nelems, unsigned long iopte_bits)
+static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
+ int nused, int nelems, unsigned long iopte_protection)
{
struct scatterlist *dma_sg = sg;
struct scatterlist *sg_end = sg + nelems;
@@ -462,7 +376,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, in
for (;;) {
unsigned long tmp;
- tmp = (unsigned long) SG_ENT_PHYS_ADDRESS(sg);
+ tmp = SG_ENT_PHYS_ADDRESS(sg);
len = sg->length;
if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) {
pteval = tmp & IO_PAGE_MASK;
@@ -478,7 +392,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, in
sg++;
}
- pteval = ((pteval & IOPTE_PAGE) | iopte_bits);
+ pteval = iopte_protection | (pteval & IOPTE_PAGE);
while (len > 0) {
*iopte++ = __iopte(pteval);
pteval += IO_PAGE_SIZE;
@@ -509,103 +423,111 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, in
}
}
-int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int dir)
+int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction)
{
- struct sbus_iommu *iommu = sdev->bus->iommu;
- unsigned long flags, npages;
- iopte_t *iopte;
+ struct sbus_iommu *iommu;
+ unsigned long flags, npages, iopte_protection;
+ iopte_t *base;
u32 dma_base;
struct scatterlist *sgtmp;
int used;
- unsigned long iopte_bits;
-
- if (dir == SBUS_DMA_NONE)
- BUG();
/* Fast path single entry scatterlists. */
- if (nents == 1) {
- sg->dma_address =
+ if (nelems == 1) {
+ sglist->dma_address =
sbus_map_single(sdev,
- (page_address(sg->page) + sg->offset),
- sg->length, dir);
- sg->dma_length = sg->length;
+ (page_address(sglist->page) + sglist->offset),
+ sglist->length, direction);
+ sglist->dma_length = sglist->length;
return 1;
}
- npages = prepare_sg(sg, nents);
+ iommu = sdev->bus->iommu;
+
+ if (unlikely(direction == SBUS_DMA_NONE))
+ BUG();
+
+ npages = prepare_sg(sglist, nelems);
spin_lock_irqsave(&iommu->lock, flags);
- iopte = alloc_streaming_cluster(iommu, npages);
- if (iopte == NULL)
- goto bad;
- dma_base = MAP_BASE + ((iopte - iommu->page_table) << IO_PAGE_SHIFT);
+ base = alloc_npages(iommu, npages);
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
+ if (unlikely(base == NULL))
+ BUG();
+
+ dma_base = MAP_BASE +
+ ((base - iommu->page_table) << IO_PAGE_SHIFT);
/* Normalize DVMA addresses. */
- sgtmp = sg;
- used = nents;
+ used = nelems;
+ sgtmp = sglist;
while (used && sgtmp->dma_length) {
sgtmp->dma_address += dma_base;
sgtmp++;
used--;
}
- used = nents - used;
+ used = nelems - used;
- iopte_bits = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE;
- if (dir != SBUS_DMA_TODEVICE)
- iopte_bits |= IOPTE_WRITE;
+ iopte_protection = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE;
+ if (direction != SBUS_DMA_TODEVICE)
+ iopte_protection |= IOPTE_WRITE;
+
+ fill_sg(base, sglist, used, nelems, iopte_protection);
- fill_sg(iopte, sg, used, nents, iopte_bits);
#ifdef VERIFY_SG
- verify_sglist(sg, nents, iopte, npages);
+ verify_sglist(sglist, nelems, base, npages);
#endif
- spin_unlock_irqrestore(&iommu->lock, flags);
return used;
-
-bad:
- spin_unlock_irqrestore(&iommu->lock, flags);
- BUG();
- return 0;
}
-void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int direction)
+void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction)
{
- unsigned long size, flags;
struct sbus_iommu *iommu;
- u32 dvma_base;
- int i;
+ iopte_t *base;
+ unsigned long flags, i, npages;
+ u32 bus_addr;
- /* Fast path single entry scatterlists. */
- if (nents == 1) {
- sbus_unmap_single(sdev, sg->dma_address, sg->dma_length, direction);
- return;
- }
+ if (unlikely(direction == SBUS_DMA_NONE))
+ BUG();
+
+ iommu = sdev->bus->iommu;
+
+ bus_addr = sglist->dma_address & IO_PAGE_MASK;
- dvma_base = sg[0].dma_address & IO_PAGE_MASK;
- for (i = 0; i < nents; i++) {
- if (sg[i].dma_length == 0)
+ for (i = 1; i < nelems; i++)
+ if (sglist[i].dma_length == 0)
break;
- }
i--;
- size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - dvma_base;
+ npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) -
+ bus_addr) >> IO_PAGE_SHIFT;
+
+ base = iommu->page_table +
+ ((bus_addr - MAP_BASE) >> IO_PAGE_SHIFT);
- iommu = sdev->bus->iommu;
spin_lock_irqsave(&iommu->lock, flags);
- free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT);
- sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT, direction);
+ sbus_strbuf_flush(iommu, bus_addr, npages, direction);
+ for (i = 0; i < npages; i++)
+ iopte_val(base[i]) = 0UL;
+ free_npages(iommu, bus_addr - MAP_BASE, npages);
spin_unlock_irqrestore(&iommu->lock, flags);
}
-void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t size, int direction)
+void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t bus_addr, size_t sz, int direction)
{
- struct sbus_iommu *iommu = sdev->bus->iommu;
- unsigned long flags;
+ struct sbus_iommu *iommu;
+ unsigned long flags, npages;
+
+ iommu = sdev->bus->iommu;
- size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK));
+ npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK);
+ npages >>= IO_PAGE_SHIFT;
+ bus_addr &= IO_PAGE_MASK;
spin_lock_irqsave(&iommu->lock, flags);
- sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT, direction);
+ sbus_strbuf_flush(iommu, bus_addr, npages, direction);
spin_unlock_irqrestore(&iommu->lock, flags);
}
@@ -613,23 +535,25 @@ void sbus_dma_sync_single_for_device(struct sbus_dev *sdev, dma_addr_t base, siz
{
}
-void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int direction)
+void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction)
{
- struct sbus_iommu *iommu = sdev->bus->iommu;
- unsigned long flags, size;
- u32 base;
- int i;
+ struct sbus_iommu *iommu;
+ unsigned long flags, npages, i;
+ u32 bus_addr;
+
+ iommu = sdev->bus->iommu;
- base = sg[0].dma_address & IO_PAGE_MASK;
- for (i = 0; i < nents; i++) {
- if (sg[i].dma_length == 0)
+ bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
+ for (i = 0; i < nelems; i++) {
+ if (!sglist[i].dma_length)
break;
}
i--;
- size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base;
+ npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length)
+ - bus_addr) >> IO_PAGE_SHIFT;
spin_lock_irqsave(&iommu->lock, flags);
- sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT, direction);
+ sbus_strbuf_flush(iommu, bus_addr, npages, direction);
spin_unlock_irqrestore(&iommu->lock, flags);
}
@@ -1104,7 +1028,7 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus)
struct linux_prom64_registers *pr;
struct device_node *dp;
struct sbus_iommu *iommu;
- unsigned long regs, tsb_base;
+ unsigned long regs;
u64 control;
int i;
@@ -1132,14 +1056,6 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus)
memset(iommu, 0, sizeof(*iommu));
- /* We start with no consistent mappings. */
- iommu->lowest_consistent_map = CLUSTER_NPAGES;
-
- for (i = 0; i < NCLUSTERS; i++) {
- iommu->alloc_info[i].flush = 0;
- iommu->alloc_info[i].next = 0;
- }
-
/* Setup spinlock. */
spin_lock_init(&iommu->lock);
@@ -1159,25 +1075,13 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus)
sbus->portid, regs);
/* Setup for TSB_SIZE=7, TBW_SIZE=0, MMU_DE=1, MMU_EN=1 */
+ sbus_iommu_table_init(iommu, IO_TSB_SIZE);
+
control = upa_readq(iommu->iommu_regs + IOMMU_CONTROL);
control = ((7UL << 16UL) |
(0UL << 2UL) |
(1UL << 1UL) |
(1UL << 0UL));
-
- /* Using the above configuration we need 1MB iommu page
- * table (128K ioptes * 8 bytes per iopte). This is
- * page order 7 on UltraSparc.
- */
- tsb_base = __get_free_pages(GFP_ATOMIC, get_order(IO_TSB_SIZE));
- if (tsb_base == 0UL) {
- prom_printf("sbus_iommu_init: Fatal error, cannot alloc TSB table.\n");
- prom_halt();
- }
-
- iommu->page_table = (iopte_t *) tsb_base;
- memset(iommu->page_table, 0, IO_TSB_SIZE);
-
upa_writeq(control, iommu->iommu_regs + IOMMU_CONTROL);
/* Clean out any cruft in the IOMMU using
@@ -1195,7 +1099,7 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus)
upa_readq(iommu->sbus_control_reg);
/* Give the TSB to SYSIO. */
- upa_writeq(__pa(tsb_base), iommu->iommu_regs + IOMMU_TSBBASE);
+ upa_writeq(__pa(iommu->page_table), iommu->iommu_regs + IOMMU_TSBBASE);
/* Setup streaming buffer, DE=1 SB_EN=1 */
control = (1UL << 1UL) | (1UL << 0UL);
diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S
index c09ab4b9431..010a737908e 100644
--- a/arch/sparc64/kernel/sys32.S
+++ b/arch/sparc64/kernel/sys32.S
@@ -91,7 +91,6 @@ SIGN1(sys32_select, compat_sys_select, %o0)
SIGN1(sys32_mkdir, sys_mkdir, %o1)
SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
SIGN1(sys32_sysfs, compat_sys_sysfs, %o0)
-SIGN3(sys32_ipc, compat_sys_ipc, %o1, %o2, %o3)
SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1)
SIGN2(sys32_sendfile64, compat_sys_sendfile64, %o0, %o1)
SIGN1(sys32_prctl, sys_prctl, %o0)
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 4cff95b7b3a..8f7a06e2c7e 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -871,7 +871,7 @@ asmlinkage s32 sunos_sysconf (int name)
ret = ARG_MAX;
break;
case _SC_CHILD_MAX:
- ret = -1; /* no limit */
+ ret = current->signal->rlim[RLIMIT_NPROC].rlim_cur;
break;
case _SC_CLK_TCK:
ret = HZ;
@@ -880,7 +880,7 @@ asmlinkage s32 sunos_sysconf (int name)
ret = NGROUPS_MAX;
break;
case _SC_OPEN_MAX:
- ret = OPEN_MAX;
+ ret = current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
break;
case _SC_JOB_CONTROL:
ret = 1; /* yes, we do support job control */
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index aaeb5e06735..48c36fe6dc6 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -62,7 +62,7 @@ sys_call_table32:
/*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir
.word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64
/*210*/ .word sys32_fadvise64_64, sys32_tgkill, sys32_waitpid, sys_swapoff, compat_sys_sysinfo
- .word sys32_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, compat_sys_adjtimex
+ .word compat_sys_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, compat_sys_adjtimex
/*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid
.word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16
/*230*/ .word sys32_select, compat_sys_time, sys32_splice, compat_sys_stime, compat_sys_statfs64
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index bca16e8c95c..9fcaad6dd11 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -363,8 +363,10 @@ asmlinkage int solaris_sysconf(int id)
{
switch (id) {
case SOLARIS_CONFIG_NGROUPS: return NGROUPS_MAX;
- case SOLARIS_CONFIG_CHILD_MAX: return -1; /* no limit */
- case SOLARIS_CONFIG_OPEN_FILES: return OPEN_MAX;
+ case SOLARIS_CONFIG_CHILD_MAX:
+ return current->signal->rlim[RLIMIT_NPROC].rlim_cur;
+ case SOLARIS_CONFIG_OPEN_FILES:
+ return current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
case SOLARIS_CONFIG_POSIX_VER: return 199309;
case SOLARIS_CONFIG_PAGESIZE: return PAGE_SIZE;
case SOLARIS_CONFIG_XOPEN_VER: return 3;
diff --git a/arch/x86_64/kernel/functionlist b/arch/x86_64/kernel/functionlist
index 01fa23580c8..7ae18ec1245 100644
--- a/arch/x86_64/kernel/functionlist
+++ b/arch/x86_64/kernel/functionlist
@@ -514,7 +514,6 @@
*(.text.dentry_open)
*(.text.dentry_iput)
*(.text.bio_alloc)
-*(.text.alloc_skb_from_cache)
*(.text.wait_on_page_bit)
*(.text.vfs_readdir)
*(.text.vfs_lstat)
diff --git a/arch/x86_64/kernel/hpet.c b/arch/x86_64/kernel/hpet.c
index 8cf0b8a1377..b8286968662 100644
--- a/arch/x86_64/kernel/hpet.c
+++ b/arch/x86_64/kernel/hpet.c
@@ -191,6 +191,7 @@ int hpet_reenable(void)
#define TICK_COUNT 100000000
#define TICK_MIN 5000
+#define MAX_TRIES 5
/*
* Some platforms take periodic SMI interrupts with 5ms duration. Make sure none
@@ -198,13 +199,15 @@ int hpet_reenable(void)
*/
static void __init read_hpet_tsc(int *hpet, int *tsc)
{
- int tsc1, tsc2, hpet1;
+ int tsc1, tsc2, hpet1, i;
- do {
+ for (i = 0; i < MAX_TRIES; i++) {
tsc1 = get_cycles_sync();
hpet1 = hpet_readl(HPET_COUNTER);
tsc2 = get_cycles_sync();
- } while (tsc2 - tsc1 > TICK_MIN);
+ if (tsc2 - tsc1 > TICK_MIN)
+ break;
+ }
*hpet = hpet1;
*tsc = tsc2;
}
diff --git a/arch/x86_64/kernel/k8.c b/arch/x86_64/kernel/k8.c
index 6416682d33d..bc11b32e8b4 100644
--- a/arch/x86_64/kernel/k8.c
+++ b/arch/x86_64/kernel/k8.c
@@ -61,8 +61,8 @@ int cache_k8_northbridges(void)
dev = NULL;
i = 0;
while ((dev = next_k8_northbridge(dev)) != NULL) {
- k8_northbridges[i++] = dev;
- pci_read_config_dword(dev, 0x9c, &flush_words[i]);
+ k8_northbridges[i] = dev;
+ pci_read_config_dword(dev, 0x9c, &flush_words[i++]);
}
k8_northbridges[i] = NULL;
return 0;
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index a90996c27dc..dfab9f16736 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -39,15 +39,17 @@ int panic_on_unrecovered_nmi;
* different subsystems this reservation system just tries to coordinate
* things a little
*/
-static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner);
-static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[2]);
-
-static cpumask_t backtrace_mask = CPU_MASK_NONE;
/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's
* offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now)
*/
#define NMI_MAX_COUNTER_BITS 66
+#define NMI_MAX_COUNTER_LONGS BITS_TO_LONGS(NMI_MAX_COUNTER_BITS)
+
+static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner[NMI_MAX_COUNTER_LONGS]);
+static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[NMI_MAX_COUNTER_LONGS]);
+
+static cpumask_t backtrace_mask = CPU_MASK_NONE;
/* nmi_active:
* >0: the lapic NMI watchdog is active, but can be disabled
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 2bac8c60ad6..0bae862e9a5 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -519,7 +519,11 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
gatt_size = (aper_size >> PAGE_SHIFT) * sizeof(u32);
gatt = (void *)__get_free_pages(GFP_KERNEL, get_order(gatt_size));
if (!gatt)
- panic("Cannot allocate GATT table");
+ panic("Cannot allocate GATT table");
+ if (change_page_attr_addr((unsigned long)gatt, gatt_size >> PAGE_SHIFT, PAGE_KERNEL_NOCACHE))
+ panic("Could not set GART PTEs to uncacheable pages");
+ global_flush_tlb();
+
memset(gatt, 0, gatt_size);
agp_gatt_table = gatt;
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index b73212c0a55..5176ecf006e 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -13,7 +13,7 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(phys_startup_64)
jiffies_64 = jiffies;
-_proxy_pda = 0;
+_proxy_pda = 1;
PHDRS {
text PT_LOAD FLAGS(5); /* R_E */
data PT_LOAD FLAGS(7); /* RWE */
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index 65c5eaa5990..081409aa345 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -81,8 +81,8 @@ static void flush_kernel_map(void *arg)
void *adr = page_address(pg);
if (cpu_has_clflush)
cache_flush_page(adr);
- __flush_tlb_one(adr);
}
+ __flush_tlb_all();
}
static inline void flush_map(struct list_head *l)
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index b6491c020f2..f92ba2a869b 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -532,6 +532,12 @@ static void cfq_add_rq_rb(struct request *rq)
if (!cfq_cfqq_on_rr(cfqq))
cfq_add_cfqq_rr(cfqd, cfqq);
+
+ /*
+ * check if this request is a better next-serve candidate
+ */
+ cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq);
+ BUG_ON(!cfqq->next_rq);
}
static inline void
@@ -986,9 +992,9 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
* expire an async queue immediately if it has used up its slice. idle
* queue always expire after 1 dispatch round.
*/
- if ((!cfq_cfqq_sync(cfqq) &&
+ if (cfqd->busy_queues > 1 && ((!cfq_cfqq_sync(cfqq) &&
cfqd->dispatch_slice >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
- cfq_class_idle(cfqq)) {
+ cfq_class_idle(cfqq))) {
cfqq->slice_end = jiffies + 1;
cfq_slice_expired(cfqd, 0, 0);
}
@@ -1051,19 +1057,21 @@ cfq_dispatch_requests(request_queue_t *q, int force)
while ((cfqq = cfq_select_queue(cfqd)) != NULL) {
int max_dispatch;
- /*
- * Don't repeat dispatch from the previous queue.
- */
- if (prev_cfqq == cfqq)
- break;
+ if (cfqd->busy_queues > 1) {
+ /*
+ * Don't repeat dispatch from the previous queue.
+ */
+ if (prev_cfqq == cfqq)
+ break;
- /*
- * So we have dispatched before in this round, if the
- * next queue has idling enabled (must be sync), don't
- * allow it service until the previous have continued.
- */
- if (cfqd->rq_in_driver && cfq_cfqq_idle_window(cfqq))
- break;
+ /*
+ * So we have dispatched before in this round, if the
+ * next queue has idling enabled (must be sync), don't
+ * allow it service until the previous have continued.
+ */
+ if (cfqd->rq_in_driver && cfq_cfqq_idle_window(cfqq))
+ break;
+ }
cfq_clear_cfqq_must_dispatch(cfqq);
cfq_clear_cfqq_wait_request(cfqq);
@@ -1370,7 +1378,9 @@ retry:
atomic_set(&cfqq->ref, 0);
cfqq->cfqd = cfqd;
- cfq_mark_cfqq_idle_window(cfqq);
+ if (key != CFQ_KEY_ASYNC)
+ cfq_mark_cfqq_idle_window(cfqq);
+
cfq_mark_cfqq_prio_changed(cfqq);
cfq_mark_cfqq_queue_new(cfqq);
cfq_init_prio_data(cfqq);
@@ -1635,12 +1645,6 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
cfqq->meta_pending++;
/*
- * check if this request is a better next-serve candidate)) {
- */
- cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq);
- BUG_ON(!cfqq->next_rq);
-
- /*
* we never wait for an async request and we don't allow preemption
* of an async request. so just return early
*/
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 0ae8b9310cb..589b98b7b21 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -758,7 +758,8 @@ static void acpi_thermal_check(void *data)
del_timer(&(tz->timer));
} else {
if (timer_pending(&(tz->timer)))
- mod_timer(&(tz->timer), (HZ * sleep_time) / 1000);
+ mod_timer(&(tz->timer),
+ jiffies + (HZ * sleep_time) / 1000);
else {
tz->timer.data = (unsigned long)tz;
tz->timer.function = acpi_thermal_run;
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index f4820786593..8dc3bc4f586 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -878,6 +878,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
struct ata_port_info *port;
struct pci_dev *host = NULL;
struct sis_chipset *chipset = NULL;
+ struct sis_chipset *sets;
static struct sis_chipset sis_chipsets[] = {
@@ -932,10 +933,11 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
/* We have to find the bridge first */
- for (chipset = &sis_chipsets[0]; chipset->device; chipset++) {
- host = pci_get_device(PCI_VENDOR_ID_SI, chipset->device, NULL);
+ for (sets = &sis_chipsets[0]; sets->device; sets++) {
+ host = pci_get_device(PCI_VENDOR_ID_SI, sets->device, NULL);
if (host != NULL) {
- if (chipset->device == 0x630) { /* SIS630 */
+ chipset = sets; /* Match found */
+ if (sets->device == 0x630) { /* SIS630 */
u8 host_rev;
pci_read_config_byte(host, PCI_REVISION_ID, &host_rev);
if (host_rev >= 0x30) /* 630 ET */
@@ -946,7 +948,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
}
/* Look for concealed bridges */
- if (host == NULL) {
+ if (chipset == NULL) {
/* Second check */
u32 idemisc;
u16 trueid;
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index fdfa3d0cf6a..bbbb973a9d3 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -54,7 +54,8 @@ int device_pm_add(struct device * dev)
int error;
pr_debug("PM: Adding info for %s:%s\n",
- dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
+ dev->bus ? dev->bus->name : "No Bus",
+ kobject_name(&dev->kobj));
down(&dpm_list_sem);
list_add_tail(&dev->power.entry, &dpm_active);
device_pm_set_parent(dev, dev->parent);
@@ -67,7 +68,8 @@ int device_pm_add(struct device * dev)
void device_pm_remove(struct device * dev)
{
pr_debug("PM: Removing info for %s:%s\n",
- dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
+ dev->bus ? dev->bus->name : "No Bus",
+ kobject_name(&dev->kobj));
down(&dpm_list_sem);
dpm_sysfs_remove(dev);
put_device(dev->power.pm_parent);
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 14d780666c0..65a725cd342 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3423,6 +3423,25 @@ static void cciss_remove_one(struct pci_dev *pdev)
"already be removed \n");
return;
}
+
+ remove_proc_entry(hba[i]->devname, proc_cciss);
+ unregister_blkdev(hba[i]->major, hba[i]->devname);
+
+ /* remove it from the disk list */
+ for (j = 0; j < CISS_MAX_LUN; j++) {
+ struct gendisk *disk = hba[i]->gendisk[j];
+ if (disk) {
+ request_queue_t *q = disk->queue;
+
+ if (disk->flags & GENHD_FL_UP)
+ del_gendisk(disk);
+ if (q)
+ blk_cleanup_queue(q);
+ }
+ }
+
+ cciss_unregister_scsi(i); /* unhook from SCSI subsystem */
+
/* Turn board interrupts off and send the flush cache command */
/* sendcmd will turn off interrupt, and send the flush...
* To write all data in the battery backed cache to disks */
@@ -3444,22 +3463,6 @@ static void cciss_remove_one(struct pci_dev *pdev)
#endif /* CONFIG_PCI_MSI */
iounmap(hba[i]->vaddr);
- cciss_unregister_scsi(i); /* unhook from SCSI subsystem */
- unregister_blkdev(hba[i]->major, hba[i]->devname);
- remove_proc_entry(hba[i]->devname, proc_cciss);
-
- /* remove it from the disk list */
- for (j = 0; j < CISS_MAX_LUN; j++) {
- struct gendisk *disk = hba[i]->gendisk[j];
- if (disk) {
- request_queue_t *q = disk->queue;
-
- if (disk->flags & GENHD_FL_UP)
- del_gendisk(disk);
- if (q)
- blk_cleanup_queue(q);
- }
- }
pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(CommandList_struct),
hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index c852eed91e4..1eeb8f2cde7 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -140,7 +140,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
#include <linux/blkdev.h>
#include <asm/uaccess.h>
-static spinlock_t pcd_lock;
+static DEFINE_SPINLOCK(pcd_lock);
module_param(verbose, bool, 0644);
module_param(major, int, 0);
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index 7cdaa195126..5826508f673 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -154,7 +154,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_LUN, D_DLY};
#include <linux/blkpg.h>
#include <asm/uaccess.h>
-static spinlock_t pf_spin_lock;
+static DEFINE_SPINLOCK(pf_spin_lock);
module_param(verbose, bool, 0644);
module_param(major, int, 0);
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index a4fb7038318..f1b9dd7d47d 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -777,7 +777,8 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
rq->cmd_flags |= REQ_QUIET;
blk_execute_rq(rq->q, pd->bdev->bd_disk, rq, 0);
- ret = rq->errors;
+ if (rq->errors)
+ ret = -EIO;
out:
blk_put_request(rq);
return ret;
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index a9fdbf9126c..55392a45a14 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -431,9 +431,8 @@ static void intel_i830_init_gtt_entries(void)
if (IS_I965) {
u32 pgetbl_ctl;
+ pgetbl_ctl = readl(intel_i830_private.registers+I810_PGETBL_CTL);
- pci_read_config_dword(agp_bridge->dev, I810_PGETBL_CTL,
- &pgetbl_ctl);
/* The 965 has a field telling us the size of the GTT,
* which may be larger than what is necessary to map the
* aperture.
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index f5c160caf9f..5f066963f17 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -248,7 +248,7 @@ static unsigned long get_unmapped_area_mem(struct file *file,
{
if (!valid_mmap_phys_addr_range(pgoff, len))
return (unsigned long) -EINVAL;
- return pgoff;
+ return pgoff << PAGE_SHIFT;
}
/* can't do an in-place private mapping if there's no MMU */
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index a61fb6da5d0..80a01150b86 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -1338,43 +1338,23 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
* (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
* Caller should use TIOCGICOUNT to see which one it was
*/
- case TIOCMIWAIT: {
- DECLARE_WAITQUEUE(wait, current);
- int ret;
+ case TIOCMIWAIT:
+ spin_lock_irqsave(&info->slock, flags);
+ cnow = info->icount; /* note the counters on entry */
+ spin_unlock_irqrestore(&info->slock, flags);
+
+ wait_event_interruptible(info->delta_msr_wait, ({
+ cprev = cnow;
spin_lock_irqsave(&info->slock, flags);
- cprev = info->icount; /* note the counters on entry */
+ cnow = info->icount; /* atomic copy */
spin_unlock_irqrestore(&info->slock, flags);
- add_wait_queue(&info->delta_msr_wait, &wait);
- while (1) {
- spin_lock_irqsave(&info->slock, flags);
- cnow = info->icount; /* atomic copy */
- spin_unlock_irqrestore(&info->slock, flags);
-
- set_current_state(TASK_INTERRUPTIBLE);
- if (((arg & TIOCM_RNG) &&
- (cnow.rng != cprev.rng)) ||
- ((arg & TIOCM_DSR) &&
- (cnow.dsr != cprev.dsr)) ||
- ((arg & TIOCM_CD) &&
- (cnow.dcd != cprev.dcd)) ||
- ((arg & TIOCM_CTS) &&
- (cnow.cts != cprev.cts))) {
- ret = 0;
- break;
- }
- /* see if a signal did it */
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
- cprev = cnow;
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&info->delta_msr_wait, &wait);
- break;
- }
- /* NOTREACHED */
+ ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts));
+ }));
+ break;
/*
* Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
* Return: write counters to the user passed counter struct
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
index 9af07e4999d..f7603b6aeb8 100644
--- a/drivers/char/mxser_new.c
+++ b/drivers/char/mxser_new.c
@@ -1758,43 +1758,23 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
* (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
* Caller should use TIOCGICOUNT to see which one it was
*/
- case TIOCMIWAIT: {
- DECLARE_WAITQUEUE(wait, current);
- int ret;
+ case TIOCMIWAIT:
spin_lock_irqsave(&info->slock, flags);
- cprev = info->icount; /* note the counters on entry */
+ cnow = info->icount; /* note the counters on entry */
spin_unlock_irqrestore(&info->slock, flags);
- add_wait_queue(&info->delta_msr_wait, &wait);
- while (1) {
+ wait_event_interruptible(info->delta_msr_wait, ({
+ cprev = cnow;
spin_lock_irqsave(&info->slock, flags);
cnow = info->icount; /* atomic copy */
spin_unlock_irqrestore(&info->slock, flags);
- set_current_state(TASK_INTERRUPTIBLE);
- if (((arg & TIOCM_RNG) &&
- (cnow.rng != cprev.rng)) ||
- ((arg & TIOCM_DSR) &&
- (cnow.dsr != cprev.dsr)) ||
- ((arg & TIOCM_CD) &&
- (cnow.dcd != cprev.dcd)) ||
- ((arg & TIOCM_CTS) &&
- (cnow.cts != cprev.cts))) {
- ret = 0;
- break;
- }
- /* see if a signal did it */
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
- cprev = cnow;
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&info->delta_msr_wait, &wait);
+ ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts));
+ }));
break;
- }
- /* NOTREACHED */
/*
* Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
* Return: write counters to the user passed counter struct
@@ -2230,7 +2210,14 @@ end_intr:
port->mon_data.rxcnt += cnt;
port->mon_data.up_rxcnt += cnt;
+ /*
+ * We are called from an interrupt context with &port->slock
+ * being held. Drop it temporarily in order to prevent
+ * recursive locking.
+ */
+ spin_unlock(&port->slock);
tty_flip_buffer_push(tty);
+ spin_lock(&port->slock);
}
static void mxser_transmit_chars(struct mxser_port *port)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 67f3347afcf..1cca32f4694 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -969,7 +969,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
if (size < rsize) {
dbg("report %d is too short, (%d < %d)", report->id, size, rsize);
- return -1;
+ memset(data + size, 0, rsize - size);
}
if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index da5828f2dfc..30a76404f0a 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -121,9 +121,9 @@ superio_exit(void)
* ISA constants
*/
-#define REGION_ALIGNMENT ~7
-#define REGION_OFFSET 5
-#define REGION_LENGTH 2
+#define IOREGION_ALIGNMENT ~7
+#define IOREGION_OFFSET 5
+#define IOREGION_LENGTH 2
#define ADDR_REG_OFFSET 5
#define DATA_REG_OFFSET 6
@@ -407,7 +407,7 @@ static void w83627ehf_write_fan_div(struct i2c_client *client, int nr)
break;
case 4:
reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0x73)
- | ((data->fan_div[4] & 0x03) << 3)
+ | ((data->fan_div[4] & 0x03) << 2)
| ((data->fan_div[4] & 0x04) << 5);
w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg);
break;
@@ -471,9 +471,9 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
time */
if (data->fan[i] == 0xff
&& data->fan_div[i] < 0x07) {
- dev_dbg(&client->dev, "Increasing fan %d "
+ dev_dbg(&client->dev, "Increasing fan%d "
"clock divider from %u to %u\n",
- i, div_from_reg(data->fan_div[i]),
+ i + 1, div_from_reg(data->fan_div[i]),
div_from_reg(data->fan_div[i] + 1));
data->fan_div[i]++;
w83627ehf_write_fan_div(client, i);
@@ -1194,7 +1194,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
u8 fan4pin, fan5pin;
int i, err = 0;
- if (!request_region(address + REGION_OFFSET, REGION_LENGTH,
+ if (!request_region(address + IOREGION_OFFSET, IOREGION_LENGTH,
w83627ehf_driver.driver.name)) {
err = -EBUSY;
goto exit;
@@ -1322,7 +1322,7 @@ exit_remove:
exit_free:
kfree(data);
exit_release:
- release_region(address + REGION_OFFSET, REGION_LENGTH);
+ release_region(address + IOREGION_OFFSET, IOREGION_LENGTH);
exit:
return err;
}
@@ -1337,7 +1337,7 @@ static int w83627ehf_detach_client(struct i2c_client *client)
if ((err = i2c_detach_client(client)))
return err;
- release_region(client->addr + REGION_OFFSET, REGION_LENGTH);
+ release_region(client->addr + IOREGION_OFFSET, IOREGION_LENGTH);
kfree(data);
return 0;
@@ -1380,7 +1380,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr)
superio_select(W83627EHF_LD_HWM);
val = (superio_inb(SIO_REG_ADDR) << 8)
| superio_inb(SIO_REG_ADDR + 1);
- *addr = val & REGION_ALIGNMENT;
+ *addr = val & IOREGION_ALIGNMENT;
if (*addr == 0) {
superio_exit();
return -ENODEV;
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index fb19dbb31e4..ece31d2c6c6 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -344,8 +344,7 @@ config I2C_PARPORT_LIGHT
config I2C_PASEMI
tristate "PA Semi SMBus interface"
-# depends on PPC_PASEMI && I2C && PCI
- depends on I2C && PCI
+ depends on PPC_PASEMI && I2C && PCI
help
Supports the PA Semi PWRficient on-chip SMBus interfaces.
diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c
index f54fb5d65cc..bf89eeef74e 100644
--- a/drivers/i2c/busses/i2c-pasemi.c
+++ b/drivers/i2c/busses/i2c-pasemi.c
@@ -141,7 +141,7 @@ static int pasemi_i2c_xfer_msg(struct i2c_adapter *adapter,
for (i = 0; i < msg->len - 1; i++)
TXFIFO_WR(smbus, msg->buf[i]);
- TXFIFO_WR(smbus, msg->buf[msg->len] |
+ TXFIFO_WR(smbus, msg->buf[msg->len-1] |
(stop ? MTXFIFO_STOP : 0));
}
@@ -226,7 +226,7 @@ static int pasemi_smb_xfer(struct i2c_adapter *adapter,
rd = RXFIFO_RD(smbus);
len = min_t(u8, (rd & MRXFIFO_DATA_M),
I2C_SMBUS_BLOCK_MAX);
- TXFIFO_WR(smbus, (len + 1) | MTXFIFO_READ |
+ TXFIFO_WR(smbus, len | MTXFIFO_READ |
MTXFIFO_STOP);
} else {
len = min_t(u8, data->block[0], I2C_SMBUS_BLOCK_MAX);
@@ -258,7 +258,7 @@ static int pasemi_smb_xfer(struct i2c_adapter *adapter,
rd = RXFIFO_RD(smbus);
len = min_t(u8, (rd & MRXFIFO_DATA_M),
I2C_SMBUS_BLOCK_MAX - len);
- TXFIFO_WR(smbus, (len + 1) | MTXFIFO_READ | MTXFIFO_STOP);
+ TXFIFO_WR(smbus, len | MTXFIFO_READ | MTXFIFO_STOP);
break;
default:
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index ca2e4f830c3..5bdf64b7791 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -57,6 +57,7 @@ if IDE
config IDE_MAX_HWIFS
int "Max IDE interfaces"
depends on ALPHA || SUPERH || IA64 || EMBEDDED
+ range 1 10
default 4
help
This is the maximum number of IDE hardware interfaces that will
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 45a928c058c..638becda81c 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -735,6 +735,15 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
cdrom_saw_media_change (drive);
/*printk("%s: media changed\n",drive->name);*/
return 0;
+ } else if ((sense_key == ILLEGAL_REQUEST) &&
+ (rq->cmd[0] == GPCMD_START_STOP_UNIT)) {
+ /*
+ * Don't print error message for this condition--
+ * SFF8090i indicates that 5/24/00 is the correct
+ * response to a request to close the tray if the
+ * drive doesn't have that capability.
+ * cdrom_log_sense() knows this!
+ */
} else if (!(rq->cmd_flags & REQ_QUIET)) {
/* Otherwise, print an error. */
ide_dump_status(drive, "packet command error", stat);
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 0e0280076fc..8670112f1d3 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -1226,6 +1226,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
#endif
/* so that ide_timer_expiry knows what to do */
hwgroup->sleeping = 1;
+ hwgroup->req_gen_timer = hwgroup->req_gen;
mod_timer(&hwgroup->timer, sleep);
/* we purposely leave hwgroup->busy==1
* while sleeping */
@@ -1411,7 +1412,8 @@ void ide_timer_expiry (unsigned long data)
spin_lock_irqsave(&ide_lock, flags);
- if ((handler = hwgroup->handler) == NULL) {
+ if (((handler = hwgroup->handler) == NULL) ||
+ (hwgroup->req_gen != hwgroup->req_gen_timer)) {
/*
* Either a marginal timeout occurred
* (got the interrupt just as timer expired),
@@ -1439,6 +1441,7 @@ void ide_timer_expiry (unsigned long data)
if ((wait = expiry(drive)) > 0) {
/* reset timer */
hwgroup->timer.expires = jiffies + wait;
+ hwgroup->req_gen_timer = hwgroup->req_gen;
add_timer(&hwgroup->timer);
spin_unlock_irqrestore(&ide_lock, flags);
return;
@@ -1653,6 +1656,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
printk(KERN_ERR "%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name);
}
hwgroup->handler = NULL;
+ hwgroup->req_gen++;
del_timer(&hwgroup->timer);
spin_unlock(&ide_lock);
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 1ee53a551c3..3caa176b315 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -889,6 +889,7 @@ static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
hwgroup->handler = handler;
hwgroup->expiry = expiry;
hwgroup->timer.expires = jiffies + timeout;
+ hwgroup->req_gen_timer = hwgroup->req_gen;
add_timer(&hwgroup->timer);
}
@@ -929,6 +930,7 @@ void ide_execute_command(ide_drive_t *drive, task_ioreg_t cmd, ide_handler_t *ha
hwgroup->handler = handler;
hwgroup->expiry = expiry;
hwgroup->timer.expires = jiffies + timeout;
+ hwgroup->req_gen_timer = hwgroup->req_gen;
add_timer(&hwgroup->timer);
hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG);
/* Drive takes 400nS to respond, we must avoid the IRQ being
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index a6f098fda88..ae5bf2be6f5 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1962,6 +1962,8 @@ static char *media_string(ide_drive_t *drive)
return "tape";
case ide_floppy:
return "floppy";
+ case ide_optical:
+ return "optical";
default:
return "UNKNOWN";
}
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
index d4b753e7011..dd7ec37fdea 100644
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -108,6 +108,7 @@ delkin_cb_remove (struct pci_dev *dev)
static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = {
{ 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, delkin_cb_pci_tbl);
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 60ecdc258c7..ab6fa271aeb 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1,10 +1,10 @@
/*
- * linux/drivers/ide/pci/hpt366.c Version 1.01 Dec 23, 2006
+ * linux/drivers/ide/pci/hpt366.c Version 1.02 Apr 18, 2007
*
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc
- * Portions Copyright (C) 2005-2006 MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2007 MontaVista Software, Inc.
*
* Thanks to HighPoint Technologies for their assistance, and hardware.
* Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his
@@ -494,6 +494,7 @@ static struct hpt_info hpt302n __devinitdata = {
.chip_type = HPT302N,
.max_mode = HPT302_ALLOW_ATA133_6 ? 4 : 3,
.dpll_clk = 77,
+ .settings = hpt37x_settings
};
static struct hpt_info hpt371n __devinitdata = {
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
index b8a47342cd2..cd84a55ecf2 100644
--- a/drivers/ieee1394/Kconfig
+++ b/drivers/ieee1394/Kconfig
@@ -138,9 +138,9 @@ config IEEE1394_DV1394
tristate "OHCI-DV I/O support (deprecated)"
depends on IEEE1394 && IEEE1394_OHCI1394
help
- The dv1394 driver will be removed from Linux in a future release.
- Its functionality is now provided by raw1394 together with libraries
- such as libiec61883.
+ The dv1394 driver is unsupported and may be removed from Linux in a
+ future release. Its functionality is now provided by raw1394 together
+ with libraries such as libiec61883.
config IEEE1394_RAWIO
tristate "Raw IEEE1394 I/O support"
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index dee9529aa8e..026e38face5 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -2564,8 +2564,8 @@ static int __init dv1394_init_module(void)
int ret;
printk(KERN_WARNING
- "WARNING: The dv1394 driver is unsupported and will be removed "
- "from Linux soon. Use raw1394 instead.\n");
+ "NOTE: The dv1394 driver is unsupported and may be removed in a "
+ "future Linux release. Use raw1394 instead.\n");
cdev_init(&dv1394_cdev, &dv1394_fops);
dv1394_cdev.owner = THIS_MODULE;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index d0ed1d35ca3..2d2de9b8b72 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -2026,6 +2026,17 @@ static int sched(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
return 0;
}
+static int set_tcb_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
+{
+ struct cpl_set_tcb_rpl *rpl = cplhdr(skb);
+
+ if (rpl->status != CPL_ERR_NONE) {
+ printk(KERN_ERR MOD "Unexpected SET_TCB_RPL status %u "
+ "for tid %u\n", rpl->status, GET_TID(rpl));
+ }
+ return CPL_RET_BUF_DONE;
+}
+
int __init iwch_cm_init(void)
{
skb_queue_head_init(&rxq);
@@ -2053,6 +2064,7 @@ int __init iwch_cm_init(void)
t3c_handlers[CPL_ABORT_REQ_RSS] = sched;
t3c_handlers[CPL_RDMA_TERMINATE] = sched;
t3c_handlers[CPL_RDMA_EC_STATUS] = sched;
+ t3c_handlers[CPL_SET_TCB_RPL] = set_tcb_rpl;
/*
* These are the real handlers that are called from a
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index fdb576dcfaa..ee561c569d5 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -835,6 +835,7 @@ void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr)
key = arbel_key_to_hw_index(fmr->ibmr.lkey);
key &= dev->limits.num_mpts - 1;
+ key = adjust_key(dev, key);
fmr->ibmr.lkey = fmr->ibmr.rkey = arbel_hw_index_to_key(key);
fmr->maps = 0;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index e70492db74f..2b242a4823f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -131,7 +131,7 @@ static struct sk_buff *ipoib_cm_alloc_rx_skb(struct net_device *dev, int id, int
skb_fill_page_desc(skb, i, page, 0, PAGE_SIZE);
mapping[i + 1] = ib_dma_map_page(priv->ca, skb_shinfo(skb)->frags[i].page,
- 0, PAGE_SIZE, DMA_TO_DEVICE);
+ 0, PAGE_SIZE, DMA_FROM_DEVICE);
if (unlikely(ib_dma_mapping_error(priv->ca, mapping[i + 1])))
goto partial_error;
}
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index cae8c96a55f..8960196ffb0 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -245,7 +245,6 @@ struct iser_conn {
wait_queue_head_t wait; /* waitq for conn/disconn */
atomic_t post_recv_buf_count; /* posted rx count */
atomic_t post_send_buf_count; /* posted tx count */
- struct work_struct comperror_work; /* conn term sleepable ctx*/
char name[ISER_OBJECT_NAME_SIZE];
struct iser_page_vec *page_vec; /* represents SG to fmr maps*
* maps serialized as tx is*/
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 693b7700289..1fc967464a2 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -48,7 +48,6 @@
static void iser_cq_tasklet_fn(unsigned long data);
static void iser_cq_callback(struct ib_cq *cq, void *cq_context);
-static void iser_comp_error_worker(struct work_struct *work);
static void iser_cq_event_callback(struct ib_event *cause, void *context)
{
@@ -480,7 +479,6 @@ int iser_conn_init(struct iser_conn **ibconn)
init_waitqueue_head(&ib_conn->wait);
atomic_set(&ib_conn->post_recv_buf_count, 0);
atomic_set(&ib_conn->post_send_buf_count, 0);
- INIT_WORK(&ib_conn->comperror_work, iser_comp_error_worker);
INIT_LIST_HEAD(&ib_conn->conn_list);
spin_lock_init(&ib_conn->lock);
@@ -753,26 +751,6 @@ int iser_post_send(struct iser_desc *tx_desc)
return ret_val;
}
-static void iser_comp_error_worker(struct work_struct *work)
-{
- struct iser_conn *ib_conn =
- container_of(work, struct iser_conn, comperror_work);
-
- /* getting here when the state is UP means that the conn is being *
- * terminated asynchronously from the iSCSI layer's perspective. */
- if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP,
- ISER_CONN_TERMINATING))
- iscsi_conn_failure(ib_conn->iser_conn->iscsi_conn,
- ISCSI_ERR_CONN_FAILED);
-
- /* complete the termination process if disconnect event was delivered *
- * note there are no more non completed posts to the QP */
- if (ib_conn->disc_evt_flag) {
- ib_conn->state = ISER_CONN_DOWN;
- wake_up_interruptible(&ib_conn->wait);
- }
-}
-
static void iser_handle_comp_error(struct iser_desc *desc)
{
struct iser_dto *dto = &desc->dto;
@@ -791,8 +769,22 @@ static void iser_handle_comp_error(struct iser_desc *desc)
}
if (atomic_read(&ib_conn->post_recv_buf_count) == 0 &&
- atomic_read(&ib_conn->post_send_buf_count) == 0)
- schedule_work(&ib_conn->comperror_work);
+ atomic_read(&ib_conn->post_send_buf_count) == 0) {
+ /* getting here when the state is UP means that the conn is *
+ * being terminated asynchronously from the iSCSI layer's *
+ * perspective. */
+ if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP,
+ ISER_CONN_TERMINATING))
+ iscsi_conn_failure(ib_conn->iser_conn->iscsi_conn,
+ ISCSI_ERR_CONN_FAILED);
+
+ /* complete the termination process if disconnect event was delivered *
+ * note there are no more non completed posts to the QP */
+ if (ib_conn->disc_evt_flag) {
+ ib_conn->state = ISER_CONN_DOWN;
+ wake_up_interruptible(&ib_conn->wait);
+ }
+ }
}
static void iser_cq_tasklet_fn(unsigned long data)
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index c7db4032ef0..e8606c48c9c 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -553,6 +553,7 @@ static int ucb1400_ts_remove(struct device *dev)
}
static struct device_driver ucb1400_ts_driver = {
+ .name = "ucb1400_ts",
.owner = THIS_MODULE,
.bus = &ac97_bus_type,
.probe = ucb1400_ts_probe,
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index e85b4c7c36f..cab26f301ea 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -1171,6 +1171,7 @@ void kvm_mmu_pre_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes)
* and zap two pdes instead of one.
*/
if (level == PT32_ROOT_LEVEL) {
+ page_offset &= ~7; /* kill rounding error */
page_offset <<= 1;
npte = 2;
}
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 3096836d8bd..c9f3dc4fd3e 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -1259,9 +1259,9 @@ static int smu_release(struct inode *inode, struct file *file)
set_current_state(TASK_UNINTERRUPTIBLE);
if (pp->cmd.status != 1)
break;
- spin_lock_irqsave(&pp->lock, flags);
- schedule();
spin_unlock_irqrestore(&pp->lock, flags);
+ schedule();
+ spin_lock_irqsave(&pp->lock, flags);
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&pp->wait, &wait);
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 5554adaa58f..e61e0efe9ec 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -863,9 +863,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
/* We need 4 bits per page, rounded up to a multiple of sizeof(unsigned long) */
bitmap->filemap_attr = kzalloc(
- (((num_pages*4/8)+sizeof(unsigned long)-1)
- /sizeof(unsigned long))
- *sizeof(unsigned long),
+ roundup( DIV_ROUND_UP(num_pages*4, 8), sizeof(unsigned long)),
GFP_KERNEL);
if (!bitmap->filemap_attr)
goto out;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index 9511a31c8f5..68ed3a78808 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -107,8 +107,6 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
return -ENOMEM;
input_dev->evbit[0] = BIT(EV_KEY);
- input_dev->keycodesize = sizeof(unsigned char);
- input_dev->keycodemax = KEY_MAX;
input_dev->name = "IR-receiver inside an USB DVB receiver";
input_dev->phys = d->rc_phys;
usb_to_input_id(d->udev, &input_dev->id);
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index 4b232124a1a..65c32a95e12 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -3,7 +3,7 @@
*
*
* Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor
- * Copyright (C) 2006 Corentin Chary
+ * Copyright (C) 2006-2007 Corentin Chary
*
* 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
@@ -48,7 +48,7 @@
#include <acpi/acpi_bus.h>
#include <asm/uaccess.h>
-#define ASUS_LAPTOP_VERSION "0.40"
+#define ASUS_LAPTOP_VERSION "0.41"
#define ASUS_HOTK_NAME "Asus Laptop Support"
#define ASUS_HOTK_CLASS "hotkey"
@@ -81,7 +81,8 @@
#define TLED_ON 0x08 //touchpad LED
#define RLED_ON 0x10 //Record LED
#define PLED_ON 0x20 //Phone LED
-#define LCD_ON 0x40 //LCD backlight
+#define GLED_ON 0x40 //Gaming LED
+#define LCD_ON 0x80 //LCD backlight
#define ASUS_LOG ASUS_HOTK_FILE ": "
#define ASUS_ERR KERN_ERR ASUS_LOG
@@ -94,6 +95,19 @@ MODULE_AUTHOR("Julien Lerouge, Karol Kozimor, Corentin Chary");
MODULE_DESCRIPTION(ASUS_HOTK_NAME);
MODULE_LICENSE("GPL");
+/* WAPF defines the behavior of the Fn+Fx wlan key
+ * The significance of values is yet to be found, but
+ * most of the time:
+ * 0x0 will do nothing
+ * 0x1 will allow to control the device with Fn+Fx key.
+ * 0x4 will send an ACPI event (0x88) while pressing the Fn+Fx key
+ * 0x5 like 0x1 or 0x4
+ * So, if something doesn't work as you want, just try other values =)
+ */
+static uint wapf = 1;
+module_param(wapf, uint, 0644);
+MODULE_PARM_DESC(wapf, "WAPF value");
+
#define ASUS_HANDLE(object, paths...) \
static acpi_handle object##_handle = NULL; \
static char *object##_paths[] = { paths }
@@ -103,6 +117,7 @@ ASUS_HANDLE(mled_set, ASUS_HOTK_PREFIX "MLED");
ASUS_HANDLE(tled_set, ASUS_HOTK_PREFIX "TLED");
ASUS_HANDLE(rled_set, ASUS_HOTK_PREFIX "RLED"); /* W1JC */
ASUS_HANDLE(pled_set, ASUS_HOTK_PREFIX "PLED"); /* A7J */
+ASUS_HANDLE(gled_set, ASUS_HOTK_PREFIX "GLED"); /* G1, G2 (probably) */
/* LEDD */
ASUS_HANDLE(ledd_set, ASUS_HOTK_PREFIX "SLCM");
@@ -221,6 +236,7 @@ ASUS_LED(mled, "mail");
ASUS_LED(tled, "touchpad");
ASUS_LED(rled, "record");
ASUS_LED(pled, "phone");
+ASUS_LED(gled, "gaming");
/*
* This function evaluates an ACPI method, given an int as parameter, the
@@ -245,32 +261,19 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,
return (status == AE_OK);
}
-static int read_acpi_int(acpi_handle handle, const char *method, int *val,
- struct acpi_object_list *params)
-{
- struct acpi_buffer output;
- union acpi_object out_obj;
- acpi_status status;
-
- output.length = sizeof(out_obj);
- output.pointer = &out_obj;
-
- status = acpi_evaluate_object(handle, (char *)method, params, &output);
- *val = out_obj.integer.value;
- return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER);
-}
-
static int read_wireless_status(int mask)
{
- int status;
+ ulong status;
+ acpi_status rv = AE_OK;
if (!wireless_status_handle)
return (hotk->status & mask) ? 1 : 0;
- if (read_acpi_int(wireless_status_handle, NULL, &status, NULL)) {
- return (status & mask) ? 1 : 0;
- } else
+ rv = acpi_evaluate_integer(wireless_status_handle, NULL, NULL, &status);
+ if (ACPI_FAILURE(rv))
printk(ASUS_WARNING "Error reading Wireless status\n");
+ else
+ return (status & mask) ? 1 : 0;
return (hotk->status & mask) ? 1 : 0;
}
@@ -285,19 +288,28 @@ static int read_status(int mask)
return (hotk->status & mask) ? 1 : 0;
}
-static void write_status(acpi_handle handle, int out, int mask, int invert)
+static void write_status(acpi_handle handle, int out, int mask)
{
hotk->status = (out) ? (hotk->status | mask) : (hotk->status & ~mask);
- if (invert) /* invert target value */
+ switch (mask) {
+ case MLED_ON:
out = !out & 0x1;
+ break;
+ case GLED_ON:
+ out = (out & 0x1) + 1;
+ break;
+ default:
+ out &= 0x1;
+ break;
+ }
if (handle && !write_acpi_int(handle, NULL, out, NULL))
- printk(ASUS_WARNING " write failed\n");
+ printk(ASUS_WARNING " write failed %x\n", mask);
}
/* /sys/class/led handlers */
-#define ASUS_LED_HANDLER(object, mask, invert) \
+#define ASUS_LED_HANDLER(object, mask) \
static void object##_led_set(struct led_classdev *led_cdev, \
enum led_brightness value) \
{ \
@@ -307,13 +319,14 @@ static void write_status(acpi_handle handle, int out, int mask, int invert)
static void object##_led_update(struct work_struct *ignored) \
{ \
int value = object##_led_wk; \
- write_status(object##_set_handle, value, (mask), (invert)); \
+ write_status(object##_set_handle, value, (mask)); \
}
-ASUS_LED_HANDLER(mled, MLED_ON, 1);
-ASUS_LED_HANDLER(pled, PLED_ON, 0);
-ASUS_LED_HANDLER(rled, RLED_ON, 0);
-ASUS_LED_HANDLER(tled, TLED_ON, 0);
+ASUS_LED_HANDLER(mled, MLED_ON);
+ASUS_LED_HANDLER(pled, PLED_ON);
+ASUS_LED_HANDLER(rled, RLED_ON);
+ASUS_LED_HANDLER(tled, TLED_ON);
+ASUS_LED_HANDLER(gled, GLED_ON);
static int get_lcd_state(void)
{
@@ -338,7 +351,7 @@ static int set_lcd_state(int value)
printk(ASUS_WARNING "Error switching LCD\n");
}
- write_status(NULL, lcd, LCD_ON, 0);
+ write_status(NULL, lcd, LCD_ON);
return 0;
}
@@ -354,9 +367,11 @@ static void lcd_blank(int blank)
static int read_brightness(struct backlight_device *bd)
{
- int value;
+ ulong value;
+ acpi_status rv = AE_OK;
- if (!read_acpi_int(brightness_get_handle, NULL, &value, NULL))
+ rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value);
+ if (ACPI_FAILURE(rv))
printk(ASUS_WARNING "Error reading brightness\n");
return value;
@@ -403,8 +418,10 @@ static ssize_t show_infos(struct device *dev,
struct device_attribute *attr, char *page)
{
int len = 0;
- int temp;
+ ulong temp;
char buf[16]; //enough for all info
+ acpi_status rv = AE_OK;
+
/*
* We use the easy way, we don't care of off and count, so we don't set eof
* to 1
@@ -418,9 +435,10 @@ static ssize_t show_infos(struct device *dev,
* bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
* The significance of others is yet to be found.
*/
- if (read_acpi_int(hotk->handle, "SFUN", &temp, NULL))
- len +=
- sprintf(page + len, "SFUN value : 0x%04x\n", temp);
+ rv = acpi_evaluate_integer(hotk->handle, "SFUN", NULL, &temp);
+ if (!ACPI_FAILURE(rv))
+ len += sprintf(page + len, "SFUN value : 0x%04x\n",
+ (uint) temp);
/*
* Another value for userspace: the ASYM method returns 0x02 for
* battery low and 0x04 for battery critical, its readings tend to be
@@ -428,9 +446,10 @@ static ssize_t show_infos(struct device *dev,
* Note: since not all the laptops provide this method, errors are
* silently ignored.
*/
- if (read_acpi_int(hotk->handle, "ASYM", &temp, NULL))
- len +=
- sprintf(page + len, "ASYM value : 0x%04x\n", temp);
+ rv = acpi_evaluate_integer(hotk->handle, "ASYM", NULL, &temp);
+ if (!ACPI_FAILURE(rv))
+ len += sprintf(page + len, "ASYM value : 0x%04x\n",
+ (uint) temp);
if (asus_info) {
snprintf(buf, 16, "%d", asus_info->length);
len += sprintf(page + len, "DSDT length : %s\n", buf);
@@ -465,7 +484,7 @@ static int parse_arg(const char *buf, unsigned long count, int *val)
}
static ssize_t store_status(const char *buf, size_t count,
- acpi_handle handle, int mask, int invert)
+ acpi_handle handle, int mask)
{
int rv, value;
int out = 0;
@@ -474,7 +493,7 @@ static ssize_t store_status(const char *buf, size_t count,
if (rv > 0)
out = value ? 1 : 0;
- write_status(handle, out, mask, invert);
+ write_status(handle, out, mask);
return rv;
}
@@ -515,7 +534,7 @@ static ssize_t show_wlan(struct device *dev,
static ssize_t store_wlan(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- return store_status(buf, count, wl_switch_handle, WL_ON, 0);
+ return store_status(buf, count, wl_switch_handle, WL_ON);
}
/*
@@ -531,7 +550,7 @@ static ssize_t store_bluetooth(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
- return store_status(buf, count, bt_switch_handle, BT_ON, 0);
+ return store_status(buf, count, bt_switch_handle, BT_ON);
}
/*
@@ -547,12 +566,15 @@ static void set_display(int value)
static int read_display(void)
{
- int value = 0;
+ ulong value = 0;
+ acpi_status rv = AE_OK;
/* In most of the case, we know how to set the display, but sometime
we can't read it */
if (display_get_handle) {
- if (!read_acpi_int(display_get_handle, NULL, &value, NULL))
+ rv = acpi_evaluate_integer(display_get_handle, NULL,
+ NULL, &value);
+ if (ACPI_FAILURE(rv))
printk(ASUS_WARNING "Error reading display status\n");
}
@@ -656,10 +678,10 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
* switched
*/
if (event == ATKD_LCD_ON) {
- write_status(NULL, 1, LCD_ON, 0);
+ write_status(NULL, 1, LCD_ON);
lcd_blank(FB_BLANK_UNBLANK);
} else if (event == ATKD_LCD_OFF) {
- write_status(NULL, 0, LCD_ON, 0);
+ write_status(NULL, 0, LCD_ON);
lcd_blank(FB_BLANK_POWERDOWN);
}
@@ -771,7 +793,7 @@ static int asus_hotk_get_info(void)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *model = NULL;
- int bsts_result, hwrs_result;
+ ulong bsts_result, hwrs_result;
char *string = NULL;
acpi_status status;
@@ -794,11 +816,16 @@ static int asus_hotk_get_info(void)
}
/* This needs to be called for some laptops to init properly */
- if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result, NULL))
+ status =
+ acpi_evaluate_integer(hotk->handle, "BSTS", NULL, &bsts_result);
+ if (ACPI_FAILURE(status))
printk(ASUS_WARNING "Error calling BSTS\n");
else if (bsts_result)
printk(ASUS_NOTICE "BSTS called, 0x%02x returned\n",
- bsts_result);
+ (uint) bsts_result);
+
+ /* This too ... */
+ write_acpi_int(hotk->handle, "CWAP", wapf, NULL);
/*
* Try to match the object returned by INIT to the specific model.
@@ -831,6 +858,7 @@ static int asus_hotk_get_info(void)
ASUS_HANDLE_INIT(tled_set);
ASUS_HANDLE_INIT(rled_set);
ASUS_HANDLE_INIT(pled_set);
+ ASUS_HANDLE_INIT(gled_set);
ASUS_HANDLE_INIT(ledd_set);
@@ -840,7 +868,9 @@ static int asus_hotk_get_info(void)
* The significance of others is yet to be found.
* If we don't find the method, we assume the device are present.
*/
- if (!read_acpi_int(hotk->handle, "HRWS", &hwrs_result, NULL))
+ status =
+ acpi_evaluate_integer(hotk->handle, "HRWS", NULL, &hwrs_result);
+ if (ACPI_FAILURE(status))
hwrs_result = WL_HWRS | BT_HWRS;
if (hwrs_result & WL_HWRS)
@@ -928,11 +958,15 @@ static int asus_hotk_add(struct acpi_device *device)
asus_hotk_found = 1;
/* WLED and BLED are on by default */
- write_status(bt_switch_handle, 1, BT_ON, 0);
- write_status(wl_switch_handle, 1, WL_ON, 0);
+ write_status(bt_switch_handle, 1, BT_ON);
+ write_status(wl_switch_handle, 1, WL_ON);
+
+ /* If the h/w switch is off, we need to check the real status */
+ write_status(NULL, read_status(BT_ON), BT_ON);
+ write_status(NULL, read_status(WL_ON), WL_ON);
/* LCD Backlight is on by default */
- write_status(NULL, 1, LCD_ON, 0);
+ write_status(NULL, 1, LCD_ON);
/* LED display is off by default */
hotk->ledd_status = 0xFFF;
@@ -991,6 +1025,7 @@ static void asus_led_exit(void)
ASUS_LED_UNREGISTER(tled);
ASUS_LED_UNREGISTER(pled);
ASUS_LED_UNREGISTER(rled);
+ ASUS_LED_UNREGISTER(gled);
destroy_workqueue(led_workqueue);
}
@@ -1062,6 +1097,10 @@ static int asus_led_init(struct device *dev)
if (rv)
return rv;
+ rv = ASUS_LED_REGISTER(gled, dev);
+ if (rv)
+ return rv;
+
led_workqueue = create_singlethread_workqueue("led_workqueue");
if (!led_workqueue)
return -ENOMEM;
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c3f9f599f13..a3d46ea3712 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2263,6 +2263,7 @@ config GIANFAR
tristate "Gianfar Ethernet"
depends on 85xx || 83xx || PPC_86xx
select PHYLIB
+ select CRC32
help
This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
and MPC86xx family of chips, and the FEC on the 8540.
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 0b7aded8dcf..e85f5ec48f9 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -54,8 +54,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.5.7"
-#define DRV_MODULE_RELDATE "March 29, 2007"
+#define DRV_MODULE_VERSION "1.5.8"
+#define DRV_MODULE_RELDATE "April 24, 2007"
#define RUN_AT(x) (jiffies + (x))
@@ -3421,6 +3421,9 @@ bnx2_init_chip(struct bnx2 *bp)
val = REG_RD(bp, BNX2_MQ_CONFIG);
val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE;
val |= BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
+ if (CHIP_ID(bp) == CHIP_ID_5709_A0 || CHIP_ID(bp) == CHIP_ID_5709_A1)
+ val |= BNX2_MQ_CONFIG_HALT_DIS;
+
REG_WR(bp, BNX2_MQ_CONFIG, val);
val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index ccbdf81c659..878eee58f12 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -6518,6 +6518,7 @@ struct bnx2 {
#define CHIP_ID_5708_B0 0x57081000
#define CHIP_ID_5708_B1 0x57081010
#define CHIP_ID_5709_A0 0x57090000
+#define CHIP_ID_5709_A1 0x57090010
#define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0xf)
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index 97128d88eae..8d137963369 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -478,8 +478,11 @@ struct cmac {
struct adapter *adapter;
unsigned int offset;
unsigned int nucast; /* # of address filters for unicast MACs */
- unsigned int tcnt;
- unsigned int xcnt;
+ unsigned int tx_tcnt;
+ unsigned int tx_xcnt;
+ u64 tx_mcnt;
+ unsigned int rx_xcnt;
+ u64 rx_mcnt;
unsigned int toggle_cnt;
unsigned int txen;
struct mac_stats stats;
diff --git a/drivers/net/cxgb3/cxgb3_defs.h b/drivers/net/cxgb3/cxgb3_defs.h
index e14862b43d1..483a594210a 100644
--- a/drivers/net/cxgb3/cxgb3_defs.h
+++ b/drivers/net/cxgb3/cxgb3_defs.h
@@ -67,7 +67,10 @@ static inline union listen_entry *stid2entry(const struct tid_info *t,
static inline struct t3c_tid_entry *lookup_tid(const struct tid_info *t,
unsigned int tid)
{
- return tid < t->ntids ? &(t->tid_tab[tid]) : NULL;
+ struct t3c_tid_entry *t3c_tid = tid < t->ntids ?
+ &(t->tid_tab[tid]) : NULL;
+
+ return (t3c_tid && t3c_tid->client) ? t3c_tid : NULL;
}
/*
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 26240fd5e76..67b4b219d92 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -194,15 +194,13 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat,
if (link_stat != netif_carrier_ok(dev)) {
if (link_stat) {
- t3_set_reg_field(adapter,
- A_XGM_TXFIFO_CFG + mac->offset,
- F_ENDROPPKT, 0);
+ t3_mac_enable(mac, MAC_DIRECTION_RX);
netif_carrier_on(dev);
} else {
netif_carrier_off(dev);
- t3_set_reg_field(adapter,
- A_XGM_TXFIFO_CFG + mac->offset,
- F_ENDROPPKT, F_ENDROPPKT);
+ pi->phy.ops->power_down(&pi->phy, 1);
+ t3_mac_disable(mac, MAC_DIRECTION_RX);
+ t3_link_start(&pi->phy, mac, &pi->link_config);
}
link_report(dev);
@@ -772,6 +770,8 @@ static int cxgb_up(struct adapter *adap)
if (err)
goto out;
+ t3_write_reg(adap, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12));
+
err = setup_sge_qsets(adap);
if (err)
goto out;
@@ -2119,7 +2119,9 @@ static void check_t3b2_mac(struct adapter *adapter)
{
int i;
- rtnl_lock(); /* synchronize with ifdown */
+ if (!rtnl_trylock()) /* synchronize with ifdown */
+ return;
+
for_each_port(adapter, i) {
struct net_device *dev = adapter->port[i];
struct port_info *p = netdev_priv(dev);
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index eed7a48e311..199e5066acf 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -508,6 +508,7 @@ void cxgb3_queue_tid_release(struct t3cdev *tdev, unsigned int tid)
spin_lock_bh(&td->tid_release_lock);
p->ctx = (void *)td->tid_release_list;
+ p->client = NULL;
td->tid_release_list = p;
if (!p->ctx)
schedule_work(&td->tid_release_task);
@@ -623,7 +624,8 @@ static int do_act_open_rpl(struct t3cdev *dev, struct sk_buff *skb)
struct t3c_tid_entry *t3c_tid;
t3c_tid = lookup_atid(&(T3C_DATA(dev))->tid_maps, atid);
- if (t3c_tid->ctx && t3c_tid->client && t3c_tid->client->handlers &&
+ if (t3c_tid && t3c_tid->ctx && t3c_tid->client &&
+ t3c_tid->client->handlers &&
t3c_tid->client->handlers[CPL_ACT_OPEN_RPL]) {
return t3c_tid->client->handlers[CPL_ACT_OPEN_RPL] (dev, skb,
t3c_tid->
@@ -642,7 +644,7 @@ static int do_stid_rpl(struct t3cdev *dev, struct sk_buff *skb)
struct t3c_tid_entry *t3c_tid;
t3c_tid = lookup_stid(&(T3C_DATA(dev))->tid_maps, stid);
- if (t3c_tid->ctx && t3c_tid->client->handlers &&
+ if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers &&
t3c_tid->client->handlers[p->opcode]) {
return t3c_tid->client->handlers[p->opcode] (dev, skb,
t3c_tid->ctx);
@@ -660,7 +662,7 @@ static int do_hwtid_rpl(struct t3cdev *dev, struct sk_buff *skb)
struct t3c_tid_entry *t3c_tid;
t3c_tid = lookup_tid(&(T3C_DATA(dev))->tid_maps, hwtid);
- if (t3c_tid->ctx && t3c_tid->client->handlers &&
+ if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers &&
t3c_tid->client->handlers[p->opcode]) {
return t3c_tid->client->handlers[p->opcode]
(dev, skb, t3c_tid->ctx);
@@ -689,6 +691,28 @@ static int do_cr(struct t3cdev *dev, struct sk_buff *skb)
}
}
+/*
+ * Returns an sk_buff for a reply CPL message of size len. If the input
+ * sk_buff has no other users it is trimmed and reused, otherwise a new buffer
+ * is allocated. The input skb must be of size at least len. Note that this
+ * operation does not destroy the original skb data even if it decides to reuse
+ * the buffer.
+ */
+static struct sk_buff *cxgb3_get_cpl_reply_skb(struct sk_buff *skb, size_t len,
+ int gfp)
+{
+ if (likely(!skb_cloned(skb))) {
+ BUG_ON(skb->len < len);
+ __skb_trim(skb, len);
+ skb_get(skb);
+ } else {
+ skb = alloc_skb(len, gfp);
+ if (skb)
+ __skb_put(skb, len);
+ }
+ return skb;
+}
+
static int do_abort_req_rss(struct t3cdev *dev, struct sk_buff *skb)
{
union opcode_tid *p = cplhdr(skb);
@@ -696,30 +720,39 @@ static int do_abort_req_rss(struct t3cdev *dev, struct sk_buff *skb)
struct t3c_tid_entry *t3c_tid;
t3c_tid = lookup_tid(&(T3C_DATA(dev))->tid_maps, hwtid);
- if (t3c_tid->ctx && t3c_tid->client->handlers &&
+ if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers &&
t3c_tid->client->handlers[p->opcode]) {
return t3c_tid->client->handlers[p->opcode]
(dev, skb, t3c_tid->ctx);
} else {
struct cpl_abort_req_rss *req = cplhdr(skb);
struct cpl_abort_rpl *rpl;
+ struct sk_buff *reply_skb;
+ unsigned int tid = GET_TID(req);
+ u8 cmd = req->status;
+
+ if (req->status == CPL_ERR_RTX_NEG_ADVICE ||
+ req->status == CPL_ERR_PERSIST_NEG_ADVICE)
+ goto out;
- struct sk_buff *skb =
- alloc_skb(sizeof(struct cpl_abort_rpl), GFP_ATOMIC);
- if (!skb) {
+ reply_skb = cxgb3_get_cpl_reply_skb(skb,
+ sizeof(struct
+ cpl_abort_rpl),
+ GFP_ATOMIC);
+
+ if (!reply_skb) {
printk("do_abort_req_rss: couldn't get skb!\n");
goto out;
}
- skb->priority = CPL_PRIORITY_DATA;
- __skb_put(skb, sizeof(struct cpl_abort_rpl));
- rpl = cplhdr(skb);
+ reply_skb->priority = CPL_PRIORITY_DATA;
+ __skb_put(reply_skb, sizeof(struct cpl_abort_rpl));
+ rpl = cplhdr(reply_skb);
rpl->wr.wr_hi =
htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_RPL));
- rpl->wr.wr_lo = htonl(V_WR_TID(GET_TID(req)));
- OPCODE_TID(rpl) =
- htonl(MK_OPCODE_TID(CPL_ABORT_RPL, GET_TID(req)));
- rpl->cmd = req->status;
- cxgb3_ofld_send(dev, skb);
+ rpl->wr.wr_lo = htonl(V_WR_TID(tid));
+ OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, tid));
+ rpl->cmd = cmd;
+ cxgb3_ofld_send(dev, reply_skb);
out:
return CPL_RET_BUF_DONE;
}
@@ -732,7 +765,7 @@ static int do_act_establish(struct t3cdev *dev, struct sk_buff *skb)
struct t3c_tid_entry *t3c_tid;
t3c_tid = lookup_atid(&(T3C_DATA(dev))->tid_maps, atid);
- if (t3c_tid->ctx && t3c_tid->client->handlers &&
+ if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers &&
t3c_tid->client->handlers[CPL_ACT_ESTABLISH]) {
return t3c_tid->client->handlers[CPL_ACT_ESTABLISH]
(dev, skb, t3c_tid->ctx);
@@ -743,17 +776,6 @@ static int do_act_establish(struct t3cdev *dev, struct sk_buff *skb)
}
}
-static int do_set_tcb_rpl(struct t3cdev *dev, struct sk_buff *skb)
-{
- struct cpl_set_tcb_rpl *rpl = cplhdr(skb);
-
- if (rpl->status != CPL_ERR_NONE)
- printk(KERN_ERR
- "Unexpected SET_TCB_RPL status %u for tid %u\n",
- rpl->status, GET_TID(rpl));
- return CPL_RET_BUF_DONE;
-}
-
static int do_trace(struct t3cdev *dev, struct sk_buff *skb)
{
struct cpl_trace_pkt *p = cplhdr(skb);
@@ -773,7 +795,7 @@ static int do_term(struct t3cdev *dev, struct sk_buff *skb)
struct t3c_tid_entry *t3c_tid;
t3c_tid = lookup_tid(&(T3C_DATA(dev))->tid_maps, hwtid);
- if (t3c_tid->ctx && t3c_tid->client->handlers &&
+ if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers &&
t3c_tid->client->handlers[opcode]) {
return t3c_tid->client->handlers[opcode] (dev, skb,
t3c_tid->ctx);
@@ -972,7 +994,7 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
for (tid = 0; tid < ti->ntids; tid++) {
te = lookup_tid(ti, tid);
BUG_ON(!te);
- if (te->ctx && te->client && te->client->redirect) {
+ if (te && te->ctx && te->client && te->client->redirect) {
update_tcb = te->client->redirect(te->ctx, old, new, e);
if (update_tcb) {
l2t_hold(L2DATA(tdev), e);
@@ -1215,7 +1237,8 @@ void __init cxgb3_offload_init(void)
t3_register_cpl_handler(CPL_CLOSE_CON_RPL, do_hwtid_rpl);
t3_register_cpl_handler(CPL_ABORT_REQ_RSS, do_abort_req_rss);
t3_register_cpl_handler(CPL_ACT_ESTABLISH, do_act_establish);
- t3_register_cpl_handler(CPL_SET_TCB_RPL, do_set_tcb_rpl);
+ t3_register_cpl_handler(CPL_SET_TCB_RPL, do_hwtid_rpl);
+ t3_register_cpl_handler(CPL_GET_TCB_RPL, do_hwtid_rpl);
t3_register_cpl_handler(CPL_RDMA_TERMINATE, do_term);
t3_register_cpl_handler(CPL_RDMA_EC_STATUS, do_hwtid_rpl);
t3_register_cpl_handler(CPL_TRACE_PKT, do_trace);
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index f8be41c5a08..e5a553410e2 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -1234,9 +1234,15 @@
#define A_ULPRX_ISCSI_TAGMASK 0x514
+#define S_HPZ0 0
+#define M_HPZ0 0xf
+#define V_HPZ0(x) ((x) << S_HPZ0)
+#define G_HPZ0(x) (((x) >> S_HPZ0) & M_HPZ0)
+
#define A_ULPRX_TDDP_LLIMIT 0x51c
#define A_ULPRX_TDDP_ULIMIT 0x520
+#define A_ULPRX_TDDP_PSZ 0x528
#define A_ULPRX_STAG_LLIMIT 0x52c
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index d83f075ef2d..fb485d0a43d 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -1523,19 +1523,25 @@ static int mac_intr_handler(struct adapter *adap, unsigned int idx)
*/
int t3_phy_intr_handler(struct adapter *adapter)
{
- static const int intr_gpio_bits[] = { 8, 0x20 };
-
+ u32 mask, gpi = adapter_info(adapter)->gpio_intr;
u32 i, cause = t3_read_reg(adapter, A_T3DBG_INT_CAUSE);
for_each_port(adapter, i) {
- if (cause & intr_gpio_bits[i]) {
- struct cphy *phy = &adap2pinfo(adapter, i)->phy;
- int phy_cause = phy->ops->intr_handler(phy);
+ struct port_info *p = adap2pinfo(adapter, i);
+
+ mask = gpi - (gpi & (gpi - 1));
+ gpi -= mask;
+
+ if (!(p->port_type->caps & SUPPORTED_IRQ))
+ continue;
+
+ if (cause & mask) {
+ int phy_cause = p->phy.ops->intr_handler(&p->phy);
if (phy_cause & cphy_cause_link_change)
t3_link_changed(adapter, i);
if (phy_cause & cphy_cause_fifo_error)
- phy->fifo_errors++;
+ p->phy.fifo_errors++;
}
}
diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c
index 94aaff005a3..a506792f957 100644
--- a/drivers/net/cxgb3/xgmac.c
+++ b/drivers/net/cxgb3/xgmac.c
@@ -367,7 +367,8 @@ int t3_mac_enable(struct cmac *mac, int which)
int idx = macidx(mac);
struct adapter *adap = mac->adapter;
unsigned int oft = mac->offset;
-
+ struct mac_stats *s = &mac->stats;
+
if (which & MAC_DIRECTION_TX) {
t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
@@ -376,10 +377,16 @@ int t3_mac_enable(struct cmac *mac, int which)
t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx);
- mac->tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
- A_TP_PIO_DATA)));
- mac->xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
- A_XGM_TX_SPI4_SOP_EOP_CNT)));
+ mac->tx_mcnt = s->tx_frames;
+ mac->tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
+ A_TP_PIO_DATA)));
+ mac->tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
+ A_XGM_TX_SPI4_SOP_EOP_CNT +
+ oft)));
+ mac->rx_mcnt = s->rx_frames;
+ mac->rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
+ A_XGM_RX_SPI4_SOP_EOP_CNT +
+ oft)));
mac->txen = F_TXEN;
mac->toggle_cnt = 0;
}
@@ -392,6 +399,7 @@ int t3_mac_disable(struct cmac *mac, int which)
{
int idx = macidx(mac);
struct adapter *adap = mac->adapter;
+ int val;
if (which & MAC_DIRECTION_TX) {
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
@@ -401,44 +409,89 @@ int t3_mac_disable(struct cmac *mac, int which)
t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
mac->txen = 0;
}
- if (which & MAC_DIRECTION_RX)
+ if (which & MAC_DIRECTION_RX) {
+ t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset,
+ F_PCS_RESET_, 0);
+ msleep(100);
t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0);
+ val = F_MAC_RESET_;
+ if (is_10G(adap))
+ val |= F_PCS_RESET_;
+ else if (uses_xaui(adap))
+ val |= F_PCS_RESET_ | F_XG2G_RESET_;
+ else
+ val |= F_RGMII_RESET_ | F_XG2G_RESET_;
+ t3_write_reg(mac->adapter, A_XGM_RESET_CTRL + mac->offset, val);
+ }
return 0;
}
int t3b2_mac_watchdog_task(struct cmac *mac)
{
struct adapter *adap = mac->adapter;
- unsigned int tcnt, xcnt;
+ struct mac_stats *s = &mac->stats;
+ unsigned int tx_tcnt, tx_xcnt;
+ unsigned int tx_mcnt = s->tx_frames;
+ unsigned int rx_mcnt = s->rx_frames;
+ unsigned int rx_xcnt;
int status;
- t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + macidx(mac));
- tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, A_TP_PIO_DATA)));
- xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
- A_XGM_TX_SPI4_SOP_EOP_CNT +
- mac->offset)));
-
- if (tcnt != mac->tcnt && xcnt == 0 && mac->xcnt == 0) {
- if (mac->toggle_cnt > 4) {
- t3b2_mac_reset(mac);
+ if (tx_mcnt == mac->tx_mcnt) {
+ tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
+ A_XGM_TX_SPI4_SOP_EOP_CNT +
+ mac->offset)));
+ if (tx_xcnt == 0) {
+ t3_write_reg(adap, A_TP_PIO_ADDR,
+ A_TP_TX_DROP_CNT_CH0 + macidx(mac));
+ tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
+ A_TP_PIO_DATA)));
+ } else {
mac->toggle_cnt = 0;
+ return 0;
+ }
+ } else {
+ mac->toggle_cnt = 0;
+ return 0;
+ }
+
+ if (((tx_tcnt != mac->tx_tcnt) &&
+ (tx_xcnt == 0) && (mac->tx_xcnt == 0)) ||
+ ((mac->tx_mcnt == tx_mcnt) &&
+ (tx_xcnt != 0) && (mac->tx_xcnt != 0))) {
+ if (mac->toggle_cnt > 4)
status = 2;
- } else {
- t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
- t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset);
- t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset,
- mac->txen);
- t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset);
- mac->toggle_cnt++;
+ else
status = 1;
- }
} else {
mac->toggle_cnt = 0;
- status = 0;
+ return 0;
}
- mac->tcnt = tcnt;
- mac->xcnt = xcnt;
+ if (rx_mcnt != mac->rx_mcnt)
+ rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
+ A_XGM_RX_SPI4_SOP_EOP_CNT +
+ mac->offset)));
+ else
+ return 0;
+
+ if (mac->rx_mcnt != s->rx_frames && rx_xcnt == 0 && mac->rx_xcnt == 0)
+ status = 2;
+
+ mac->tx_tcnt = tx_tcnt;
+ mac->tx_xcnt = tx_xcnt;
+ mac->tx_mcnt = s->tx_frames;
+ mac->rx_xcnt = rx_xcnt;
+ mac->rx_mcnt = s->rx_frames;
+ if (status == 1) {
+ t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
+ t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */
+ t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, mac->txen);
+ t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */
+ mac->toggle_cnt++;
+ } else if (status == 2) {
+ t3b2_mac_reset(mac);
+ mac->toggle_cnt = 0;
+ }
return status;
}
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 5113eef755b..f3807aaf10a 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -1491,8 +1491,9 @@ static void __init depca_platform_probe (void)
depca_io_ports[i].device = pldev;
if (platform_device_add(pldev)) {
- platform_device_put(pldev);
depca_io_ports[i].device = NULL;
+ pldev->dev.platform_data = NULL;
+ platform_device_put(pldev);
continue;
}
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 1d08e937af8..b28a915bd98 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3796,7 +3796,7 @@ e1000_intr_msi(int irq, void *data)
for (i = 0; i < E1000_MAX_INTR; i++)
if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
- e1000_clean_tx_irq(adapter, adapter->tx_ring)))
+ !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
break;
if (likely(adapter->itr_setting & 3))
@@ -3899,7 +3899,7 @@ e1000_intr(int irq, void *data)
for (i = 0; i < E1000_MAX_INTR; i++)
if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
- e1000_clean_tx_irq(adapter, adapter->tx_ring)))
+ !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
break;
if (likely(adapter->itr_setting & 3))
@@ -3949,7 +3949,7 @@ e1000_clean(struct net_device *poll_dev, int *budget)
poll_dev->quota -= work_done;
/* If no Tx and not enough Rx work done, exit the polling mode */
- if ((tx_cleaned && (work_done < work_to_do)) ||
+ if ((!tx_cleaned && (work_done == 0)) ||
!netif_running(poll_dev)) {
quit_polling:
if (likely(adapter->itr_setting & 3))
@@ -3979,7 +3979,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
#ifdef CONFIG_E1000_NAPI
unsigned int count = 0;
#endif
- boolean_t cleaned = TRUE;
+ boolean_t cleaned = FALSE;
unsigned int total_tx_bytes=0, total_tx_packets=0;
i = tx_ring->next_to_clean;
@@ -4013,10 +4013,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
#ifdef CONFIG_E1000_NAPI
#define E1000_TX_WEIGHT 64
/* weight of a sort for tx, to avoid endless transmit cleanup */
- if (count++ == E1000_TX_WEIGHT) {
- cleaned = FALSE;
- break;
- }
+ if (count++ == E1000_TX_WEIGHT) break;
#endif
}
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
index 59214e74b9c..30baf6ecfc6 100644
--- a/drivers/net/hamradio/baycom_ser_fdx.c
+++ b/drivers/net/hamradio/baycom_ser_fdx.c
@@ -75,12 +75,14 @@
#include <linux/ioport.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
#include <linux/hdlcdrv.h>
#include <linux/baycom.h>
#include <linux/jiffies.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
/* --------------------------------------------------------------------- */
#define BAYCOM_DEBUG
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index c216e6a5d23..f8efe0e70a6 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -71,7 +71,7 @@
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
-#define MYRI10GE_VERSION_STR "1.3.0-1.227"
+#define MYRI10GE_VERSION_STR "1.3.0-1.233"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -900,19 +900,9 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
/* try to refill entire ring */
while (rx->fill_cnt != (rx->cnt + rx->mask + 1)) {
idx = rx->fill_cnt & rx->mask;
-
- if ((bytes < MYRI10GE_ALLOC_SIZE / 2) &&
- (rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE)) {
+ if (rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE) {
/* we can use part of previous page */
get_page(rx->page);
-#if MYRI10GE_ALLOC_SIZE > 4096
- /* Firmware cannot cross 4K boundary.. */
- if ((rx->page_offset >> 12) !=
- ((rx->page_offset + bytes - 1) >> 12)) {
- rx->page_offset =
- (rx->page_offset + bytes) & ~4095;
- }
-#endif
} else {
/* we need a new page */
page =
@@ -941,6 +931,13 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
/* start next packet on a cacheline boundary */
rx->page_offset += SKB_DATA_ALIGN(bytes);
+
+#if MYRI10GE_ALLOC_SIZE > 4096
+ /* don't cross a 4KB boundary */
+ if ((rx->page_offset >> 12) !=
+ ((rx->page_offset + bytes - 1) >> 12))
+ rx->page_offset = (rx->page_offset + 4096) & ~4095;
+#endif
rx->fill_cnt++;
/* copy 8 descriptors to the firmware at a time */
@@ -2490,6 +2487,10 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
#define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7
#define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
+#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1 0x3510
+#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4 0x351b
+#define PCI_DEVICE_ID_INTEL_E3000_PCIE 0x2779
+#define PCI_DEVICE_ID_INTEL_E3010_PCIE 0x277a
#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST 0x140
#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST 0x142
@@ -2529,6 +2530,18 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST
&& bridge->device <=
PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST)
+ /* All Intel E3000/E3010 PCIE ports */
+ || (bridge->vendor == PCI_VENDOR_ID_INTEL
+ && (bridge->device ==
+ PCI_DEVICE_ID_INTEL_E3000_PCIE
+ || bridge->device ==
+ PCI_DEVICE_ID_INTEL_E3010_PCIE))
+ /* All Intel 6310/6311/6321ESB PCIE ports */
+ || (bridge->vendor == PCI_VENDOR_ID_INTEL
+ && bridge->device >=
+ PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1
+ && bridge->device <=
+ PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4)
/* All Intel E5000 PCIE ports */
|| (bridge->vendor == PCI_VENDOR_ID_INTEL
&& bridge->device >=
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 933e2f3c77a..caabbc408c3 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -802,9 +802,9 @@ process_input_packet(struct asyncppp *ap)
/* check for address/control and protocol compression */
p = skb->data;
- if (p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {
+ if (p[0] == PPP_ALLSTATIONS) {
/* chop off address/control */
- if (skb->len < 3)
+ if (p[1] != PPP_UI || skb->len < 3)
goto err;
p = skb_pull(skb, 2);
}
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 4a926f20b6e..c32c21af3fd 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -964,7 +964,7 @@ static int sc92031_start_xmit(struct sk_buff *skb, struct net_device *dev)
goto out;
}
- spin_lock_bh(&priv->lock);
+ spin_lock(&priv->lock);
if (unlikely(!netif_carrier_ok(dev))) {
err = -ENOLINK;
@@ -1005,7 +1005,7 @@ static int sc92031_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
out_unlock:
- spin_unlock_bh(&priv->lock);
+ spin_unlock(&priv->lock);
out:
dev_kfree_skb(skb);
@@ -1042,12 +1042,12 @@ static int sc92031_open(struct net_device *dev)
priv->pm_config = 0;
/* Interrupts already disabled by sc92031_stop or sc92031_probe */
- spin_lock(&priv->lock);
+ spin_lock_bh(&priv->lock);
_sc92031_reset(dev);
mmiowb();
- spin_unlock(&priv->lock);
+ spin_unlock_bh(&priv->lock);
sc92031_enable_interrupts(dev);
if (netif_carrier_ok(dev))
@@ -1077,13 +1077,13 @@ static int sc92031_stop(struct net_device *dev)
/* Disable interrupts, stop Tx and Rx. */
sc92031_disable_interrupts(dev);
- spin_lock(&priv->lock);
+ spin_lock_bh(&priv->lock);
_sc92031_disable_tx_rx(dev);
_sc92031_tx_clear(dev);
mmiowb();
- spin_unlock(&priv->lock);
+ spin_unlock_bh(&priv->lock);
free_irq(pdev->irq, dev);
pci_free_consistent(pdev, TX_BUF_TOT_LEN, priv->tx_bufs,
@@ -1539,13 +1539,13 @@ static int sc92031_suspend(struct pci_dev *pdev, pm_message_t state)
/* Disable interrupts, stop Tx and Rx. */
sc92031_disable_interrupts(dev);
- spin_lock(&priv->lock);
+ spin_lock_bh(&priv->lock);
_sc92031_disable_tx_rx(dev);
_sc92031_tx_clear(dev);
mmiowb();
- spin_unlock(&priv->lock);
+ spin_unlock_bh(&priv->lock);
out:
pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -1565,12 +1565,12 @@ static int sc92031_resume(struct pci_dev *pdev)
goto out;
/* Interrupts already disabled by sc92031_suspend */
- spin_lock(&priv->lock);
+ spin_lock_bh(&priv->lock);
_sc92031_reset(dev);
mmiowb();
- spin_unlock(&priv->lock);
+ spin_unlock_bh(&priv->lock);
sc92031_enable_interrupts(dev);
netif_device_attach(dev);
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index b3750f28427..b2a3b19d773 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1755,6 +1755,24 @@ static int sis900_rx(struct net_device *net_dev)
} else {
struct sk_buff * skb;
+ pci_unmap_single(sis_priv->pci_dev,
+ sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE,
+ PCI_DMA_FROMDEVICE);
+
+ /* refill the Rx buffer, what if there is not enought
+ * memory for new socket buffer ?? */
+ if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
+ /*
+ * Not enough memory to refill the buffer
+ * so we need to recycle the old one so
+ * as to avoid creating a memory hole
+ * in the rx ring
+ */
+ skb = sis_priv->rx_skbuff[entry];
+ sis_priv->stats.rx_dropped++;
+ goto refill_rx_ring;
+ }
+
/* This situation should never happen, but due to
some unknow bugs, it is possible that
we are working on NULL sk_buff :-( */
@@ -1768,9 +1786,6 @@ static int sis900_rx(struct net_device *net_dev)
break;
}
- pci_unmap_single(sis_priv->pci_dev,
- sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE,
- PCI_DMA_FROMDEVICE);
/* give the socket buffer to upper layers */
skb = sis_priv->rx_skbuff[entry];
skb_put(skb, rx_size);
@@ -1783,33 +1798,14 @@ static int sis900_rx(struct net_device *net_dev)
net_dev->last_rx = jiffies;
sis_priv->stats.rx_bytes += rx_size;
sis_priv->stats.rx_packets++;
-
- /* refill the Rx buffer, what if there is not enought
- * memory for new socket buffer ?? */
- if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
- /* not enough memory for skbuff, this makes a
- * "hole" on the buffer ring, it is not clear
- * how the hardware will react to this kind
- * of degenerated buffer */
- if (netif_msg_rx_status(sis_priv))
- printk(KERN_INFO "%s: Memory squeeze,"
- "deferring packet.\n",
- net_dev->name);
- sis_priv->rx_skbuff[entry] = NULL;
- /* reset buffer descriptor state */
- sis_priv->rx_ring[entry].cmdsts = 0;
- sis_priv->rx_ring[entry].bufptr = 0;
- sis_priv->stats.rx_dropped++;
- sis_priv->cur_rx++;
- break;
- }
+ sis_priv->dirty_rx++;
+refill_rx_ring:
skb->dev = net_dev;
sis_priv->rx_skbuff[entry] = skb;
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
sis_priv->rx_ring[entry].bufptr =
pci_map_single(sis_priv->pci_dev, skb->data,
RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
- sis_priv->dirty_rx++;
}
sis_priv->cur_rx++;
entry = sis_priv->cur_rx % NUM_RX_DESC;
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 39c6677dff5..d476a3cc2e9 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -163,27 +163,46 @@ static void skge_wol_init(struct skge_port *skge)
{
struct skge_hw *hw = skge->hw;
int port = skge->port;
- enum pause_control save_mode;
- u32 ctrl;
+ u16 ctrl;
- /* Bring hardware out of reset */
skge_write16(hw, B0_CTST, CS_RST_CLR);
skge_write16(hw, SK_REG(port, GMAC_LINK_CTRL), GMLC_RST_CLR);
- skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
- skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
+ /* Turn on Vaux */
+ skge_write8(hw, B0_POWER_CTRL,
+ PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF);
- /* Force to 10/100 skge_reset will re-enable on resume */
- save_mode = skge->flow_control;
- skge->flow_control = FLOW_MODE_SYMMETRIC;
+ /* WA code for COMA mode -- clear PHY reset */
+ if (hw->chip_id == CHIP_ID_YUKON_LITE &&
+ hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+ u32 reg = skge_read32(hw, B2_GP_IO);
+ reg |= GP_DIR_9;
+ reg &= ~GP_IO_9;
+ skge_write32(hw, B2_GP_IO, reg);
+ }
- ctrl = skge->advertising;
- skge->advertising &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full);
+ skge_write32(hw, SK_REG(port, GPHY_CTRL),
+ GPC_DIS_SLEEP |
+ GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | GPC_HWCFG_M_1 | GPC_HWCFG_M_0 |
+ GPC_ANEG_1 | GPC_RST_SET);
- skge_phy_reset(skge);
+ skge_write32(hw, SK_REG(port, GPHY_CTRL),
+ GPC_DIS_SLEEP |
+ GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | GPC_HWCFG_M_1 | GPC_HWCFG_M_0 |
+ GPC_ANEG_1 | GPC_RST_CLR);
+
+ skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
+
+ /* Force to 10/100 skge_reset will re-enable on resume */
+ gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
+ PHY_AN_100FULL | PHY_AN_100HALF |
+ PHY_AN_10FULL | PHY_AN_10HALF| PHY_AN_CSMA);
+ /* no 1000 HD/FD */
+ gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, 0);
+ gm_phy_write(hw, port, PHY_MARV_CTRL,
+ PHY_CT_RESET | PHY_CT_SPS_LSB | PHY_CT_ANE |
+ PHY_CT_RE_CFG | PHY_CT_DUP_MD);
- skge->flow_control = save_mode;
- skge->advertising = ctrl;
/* Set GMAC to no flow control and auto update for speed/duplex */
gma_write16(hw, port, GM_GP_CTRL,
@@ -227,12 +246,10 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
struct skge_port *skge = netdev_priv(dev);
struct skge_hw *hw = skge->hw;
- if (wol->wolopts & wol_supported(hw))
+ if (wol->wolopts & ~wol_supported(hw))
return -EOPNOTSUPP;
skge->wol = wol->wolopts;
- if (!netif_running(dev))
- skge_wol_init(skge);
return 0;
}
@@ -2535,10 +2552,12 @@ static int skge_down(struct net_device *dev)
printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
netif_stop_queue(dev);
+
if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
del_timer_sync(&skge->link_timer);
netif_poll_disable(dev);
+ netif_carrier_off(dev);
spin_lock_irq(&hw->hw_lock);
hw->intr_mask &= ~portmask[port];
@@ -3765,21 +3784,6 @@ static void __devexit skge_remove(struct pci_dev *pdev)
}
#ifdef CONFIG_PM
-static int vaux_avail(struct pci_dev *pdev)
-{
- int pm_cap;
-
- pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
- if (pm_cap) {
- u16 ctl;
- pci_read_config_word(pdev, pm_cap + PCI_PM_PMC, &ctl);
- if (ctl & PCI_PM_CAP_AUX_POWER)
- return 1;
- }
- return 0;
-}
-
-
static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct skge_hw *hw = pci_get_drvdata(pdev);
@@ -3801,10 +3805,6 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
wol |= skge->wol;
}
- if (wol && vaux_avail(pdev))
- skge_write8(hw, B0_POWER_CTRL,
- PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF);
-
skge_write32(hw, B0_IMSK, 0);
pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -3850,6 +3850,28 @@ out:
}
#endif
+static void skge_shutdown(struct pci_dev *pdev)
+{
+ struct skge_hw *hw = pci_get_drvdata(pdev);
+ int i, wol = 0;
+
+ for (i = 0; i < hw->ports; i++) {
+ struct net_device *dev = hw->dev[i];
+ struct skge_port *skge = netdev_priv(dev);
+
+ if (skge->wol)
+ skge_wol_init(skge);
+ wol |= skge->wol;
+ }
+
+ pci_enable_wake(pdev, PCI_D3hot, wol);
+ pci_enable_wake(pdev, PCI_D3cold, wol);
+
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+}
+
static struct pci_driver skge_driver = {
.name = DRV_NAME,
.id_table = skge_id_table,
@@ -3859,6 +3881,7 @@ static struct pci_driver skge_driver = {
.suspend = skge_suspend,
.resume = skge_resume,
#endif
+ .shutdown = skge_shutdown,
};
static int __init skge_init_module(void)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index ab0ab92583f..ac36152c68b 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -49,7 +49,7 @@
#include "sky2.h"
#define DRV_NAME "sky2"
-#define DRV_VERSION "1.13"
+#define DRV_VERSION "1.14"
#define PFX DRV_NAME " "
/*
@@ -123,7 +123,10 @@ static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */
+#ifdef broken
+ /* This device causes data corruption problems that are not resolved */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */
+#endif
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
@@ -510,9 +513,9 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
ledover &= ~PHY_M_LED_MO_RX;
}
- if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_A1) {
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
+ hw->chip_rev == CHIP_REV_YU_EC_U_A1) {
/* apply fixes in PHY AFE */
- pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255);
/* increase differential signal amplitude in 10BASE-T */
@@ -524,7 +527,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
gm_phy_write(hw, port, 0x17, 0x2002);
/* set page register to 0 */
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
} else if (hw->chip_id != CHIP_ID_YUKON_EX) {
gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
@@ -740,12 +743,17 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) {
sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
- if (hw->dev[port]->mtu > ETH_DATA_LEN) {
- /* set Tx GMAC FIFO Almost Empty Threshold */
- sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), 0x180);
- /* Disable Store & Forward mode for TX */
- sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_DIS);
- }
+
+ /* set Tx GMAC FIFO Almost Empty Threshold */
+ sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
+ (ECU_JUMBO_WM << 16) | ECU_AE_THR);
+
+ if (hw->dev[port]->mtu > ETH_DATA_LEN)
+ sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+ TX_JUMBO_ENA | TX_STFW_DIS);
+ else
+ sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+ TX_JUMBO_DIS | TX_STFW_ENA);
}
}
@@ -1278,7 +1286,7 @@ static int sky2_up(struct net_device *dev)
/* Set almost empty threshold */
if (hw->chip_id == CHIP_ID_YUKON_EC_U
&& hw->chip_rev == CHIP_REV_YU_EC_U_A0)
- sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0);
+ sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV);
sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
TX_RING_SIZE - 1);
@@ -1561,6 +1569,7 @@ static int sky2_down(struct net_device *dev)
/* Stop more packets from being queued */
netif_stop_queue(dev);
+ netif_carrier_off(dev);
/* Disable port IRQ */
imask = sky2_read32(hw, B0_IMSK);
@@ -1583,13 +1592,6 @@ static int sky2_down(struct net_device *dev)
sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
RB_RST_SET | RB_DIS_OP_MD);
- /* WA for dev. #4.209 */
- if (hw->chip_id == CHIP_ID_YUKON_EC_U
- && (hw->chip_rev == CHIP_REV_YU_EC_U_A1 || hw->chip_rev == CHIP_REV_YU_EC_U_B0))
- sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
- sky2->speed != SPEED_1000 ?
- TX_STFW_ENA : TX_STFW_DIS);
-
ctrl = gma_read16(hw, port, GM_GP_CTRL);
ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
gma_write16(hw, port, GM_GP_CTRL, ctrl);
@@ -1889,6 +1891,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
{
struct sky2_port *sky2 = netdev_priv(dev);
struct sky2_hw *hw = sky2->hw;
+ unsigned port = sky2->port;
int err;
u16 ctl, mode;
u32 imask;
@@ -1896,9 +1899,8 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
return -EINVAL;
- /* TSO on Yukon Ultra and MTU > 1500 not supported */
- if (hw->chip_id == CHIP_ID_YUKON_EC_U && new_mtu > ETH_DATA_LEN)
- dev->features &= ~NETIF_F_TSO;
+ if (new_mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_FE)
+ return -EINVAL;
if (!netif_running(dev)) {
dev->mtu = new_mtu;
@@ -1914,8 +1916,18 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
synchronize_irq(hw->pdev->irq);
- ctl = gma_read16(hw, sky2->port, GM_GP_CTRL);
- gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) {
+ if (new_mtu > ETH_DATA_LEN) {
+ sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+ TX_JUMBO_ENA | TX_STFW_DIS);
+ dev->features &= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
+ } else
+ sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+ TX_JUMBO_DIS | TX_STFW_ENA);
+ }
+
+ ctl = gma_read16(hw, port, GM_GP_CTRL);
+ gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
sky2_rx_stop(sky2);
sky2_rx_clean(sky2);
@@ -1927,9 +1939,9 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
if (dev->mtu > ETH_DATA_LEN)
mode |= GM_SMOD_JUMBO_ENA;
- gma_write16(hw, sky2->port, GM_SERIAL_MODE, mode);
+ gma_write16(hw, port, GM_SERIAL_MODE, mode);
- sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD);
+ sky2_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_ENA_OP_MD);
err = sky2_rx_start(sky2);
sky2_write32(hw, B0_IMSK, imask);
@@ -1937,7 +1949,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
if (err)
dev_close(dev);
else {
- gma_write16(hw, sky2->port, GM_GP_CTRL, ctl);
+ gma_write16(hw, port, GM_GP_CTRL, ctl);
netif_poll_enable(hw->dev[0]);
netif_wake_queue(dev);
@@ -2339,26 +2351,22 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port)
}
}
-/* This should never happen it is a fatal situation */
-static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port,
- const char *rxtx, u32 mask)
+/* This should never happen it is a bug. */
+static void sky2_le_error(struct sky2_hw *hw, unsigned port,
+ u16 q, unsigned ring_size)
{
struct net_device *dev = hw->dev[port];
struct sky2_port *sky2 = netdev_priv(dev);
- u32 imask;
-
- printk(KERN_ERR PFX "%s: %s descriptor error (hardware problem)\n",
- dev ? dev->name : "<not registered>", rxtx);
+ unsigned idx;
+ const u64 *le = (q == Q_R1 || q == Q_R2)
+ ? (u64 *) sky2->rx_le : (u64 *) sky2->tx_le;
- imask = sky2_read32(hw, B0_IMSK);
- imask &= ~mask;
- sky2_write32(hw, B0_IMSK, imask);
+ idx = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
+ printk(KERN_ERR PFX "%s: descriptor error q=%#x get=%u [%llx] put=%u\n",
+ dev->name, (unsigned) q, idx, (unsigned long long) le[idx],
+ (unsigned) sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX)));
- if (dev) {
- spin_lock(&sky2->phy_lock);
- sky2_link_down(sky2);
- spin_unlock(&sky2->phy_lock);
- }
+ sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK);
}
/* If idle then force a fake soft NAPI poll once a second
@@ -2382,23 +2390,15 @@ static void sky2_idle(unsigned long arg)
mod_timer(&hw->idle_timer, jiffies + msecs_to_jiffies(idle_timeout));
}
-
-static int sky2_poll(struct net_device *dev0, int *budget)
+/* Hardware/software error handling */
+static void sky2_err_intr(struct sky2_hw *hw, u32 status)
{
- struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
- int work_limit = min(dev0->quota, *budget);
- int work_done = 0;
- u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
+ if (net_ratelimit())
+ dev_warn(&hw->pdev->dev, "error interrupt status=%#x\n", status);
if (status & Y2_IS_HW_ERR)
sky2_hw_intr(hw);
- if (status & Y2_IS_IRQ_PHY1)
- sky2_phy_intr(hw, 0);
-
- if (status & Y2_IS_IRQ_PHY2)
- sky2_phy_intr(hw, 1);
-
if (status & Y2_IS_IRQ_MAC1)
sky2_mac_intr(hw, 0);
@@ -2406,16 +2406,33 @@ static int sky2_poll(struct net_device *dev0, int *budget)
sky2_mac_intr(hw, 1);
if (status & Y2_IS_CHK_RX1)
- sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1);
+ sky2_le_error(hw, 0, Q_R1, RX_LE_SIZE);
if (status & Y2_IS_CHK_RX2)
- sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2);
+ sky2_le_error(hw, 1, Q_R2, RX_LE_SIZE);
if (status & Y2_IS_CHK_TXA1)
- sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1);
+ sky2_le_error(hw, 0, Q_XA1, TX_RING_SIZE);
if (status & Y2_IS_CHK_TXA2)
- sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
+ sky2_le_error(hw, 1, Q_XA2, TX_RING_SIZE);
+}
+
+static int sky2_poll(struct net_device *dev0, int *budget)
+{
+ struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
+ int work_limit = min(dev0->quota, *budget);
+ int work_done = 0;
+ u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
+
+ if (unlikely(status & Y2_IS_ERROR))
+ sky2_err_intr(hw, status);
+
+ if (status & Y2_IS_IRQ_PHY1)
+ sky2_phy_intr(hw, 0);
+
+ if (status & Y2_IS_IRQ_PHY2)
+ sky2_phy_intr(hw, 1);
work_done = sky2_status_intr(hw, work_limit);
if (work_done < work_limit) {
@@ -2533,16 +2550,14 @@ static void sky2_reset(struct sky2_hw *hw)
int i;
/* disable ASF */
- if (hw->chip_id <= CHIP_ID_YUKON_EC) {
- if (hw->chip_id == CHIP_ID_YUKON_EX) {
- status = sky2_read16(hw, HCU_CCSR);
- status &= ~(HCU_CCSR_AHB_RST | HCU_CCSR_CPU_RST_MODE |
- HCU_CCSR_UC_STATE_MSK);
- sky2_write16(hw, HCU_CCSR, status);
- } else
- sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
- sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE);
- }
+ if (hw->chip_id == CHIP_ID_YUKON_EX) {
+ status = sky2_read16(hw, HCU_CCSR);
+ status &= ~(HCU_CCSR_AHB_RST | HCU_CCSR_CPU_RST_MODE |
+ HCU_CCSR_UC_STATE_MSK);
+ sky2_write16(hw, HCU_CCSR, status);
+ } else
+ sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
+ sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE);
/* do a SW reset */
sky2_write8(hw, B0_CTST, CS_RST_SET);
@@ -3327,6 +3342,36 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
regs->len - B3_RI_WTO_R1);
}
+/* In order to do Jumbo packets on these chips, need to turn off the
+ * transmit store/forward. Therefore checksum offload won't work.
+ */
+static int no_tx_offload(struct net_device *dev)
+{
+ const struct sky2_port *sky2 = netdev_priv(dev);
+ const struct sky2_hw *hw = sky2->hw;
+
+ return dev->mtu > ETH_DATA_LEN &&
+ (hw->chip_id == CHIP_ID_YUKON_EX
+ || hw->chip_id == CHIP_ID_YUKON_EC_U);
+}
+
+static int sky2_set_tx_csum(struct net_device *dev, u32 data)
+{
+ if (data && no_tx_offload(dev))
+ return -EINVAL;
+
+ return ethtool_op_set_tx_csum(dev, data);
+}
+
+
+static int sky2_set_tso(struct net_device *dev, u32 data)
+{
+ if (data && no_tx_offload(dev))
+ return -EINVAL;
+
+ return ethtool_op_set_tso(dev, data);
+}
+
static const struct ethtool_ops sky2_ethtool_ops = {
.get_settings = sky2_get_settings,
.set_settings = sky2_set_settings,
@@ -3342,9 +3387,9 @@ static const struct ethtool_ops sky2_ethtool_ops = {
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
+ .set_tx_csum = sky2_set_tx_csum,
.get_tso = ethtool_op_get_tso,
- .set_tso = ethtool_op_set_tso,
+ .set_tso = sky2_set_tso,
.get_rx_csum = sky2_get_rx_csum,
.set_rx_csum = sky2_set_rx_csum,
.get_strings = sky2_get_strings,
@@ -3769,6 +3814,11 @@ static int sky2_resume(struct pci_dev *pdev)
goto out;
pci_enable_wake(pdev, PCI_D0, 0);
+
+ /* Re-enable all clocks */
+ if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U)
+ sky2_pci_write32(hw, PCI_DEV_REG3, 0);
+
sky2_reset(hw);
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index ac24bdc4297..5efb5afc45b 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -288,6 +288,9 @@ enum {
| Y2_IS_CHK_TXA1 | Y2_IS_CHK_RX1,
Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2
| Y2_IS_CHK_TXA2 | Y2_IS_CHK_RX2,
+ Y2_IS_ERROR = Y2_IS_HW_ERR |
+ Y2_IS_IRQ_MAC1 | Y2_IS_CHK_TXA1 | Y2_IS_CHK_RX1 |
+ Y2_IS_IRQ_MAC2 | Y2_IS_CHK_TXA2 | Y2_IS_CHK_RX2,
};
/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */
@@ -738,6 +741,11 @@ enum {
TX_GMF_RP = 0x0d70,/* 32 bit Tx GMAC FIFO Read Pointer */
TX_GMF_RSTP = 0x0d74,/* 32 bit Tx GMAC FIFO Restart Pointer */
TX_GMF_RLEV = 0x0d78,/* 32 bit Tx GMAC FIFO Read Level */
+
+ /* Threshold values for Yukon-EC Ultra and Extreme */
+ ECU_AE_THR = 0x0070, /* Almost Empty Threshold */
+ ECU_TXFF_LEV = 0x01a0, /* Tx BMU FIFO Level */
+ ECU_JUMBO_WM = 0x0080, /* Jumbo Mode Watermark */
};
/* Descriptor Poll Timer Registers */
@@ -1631,6 +1639,9 @@ enum {
TX_VLAN_TAG_ON = 1<<25,/* enable VLAN tagging */
TX_VLAN_TAG_OFF = 1<<24,/* disable VLAN tagging */
+ TX_JUMBO_ENA = 1<<23,/* PCI Jumbo Mode enable (Yukon-EC Ultra) */
+ TX_JUMBO_DIS = 1<<22,/* PCI Jumbo Mode enable (Yukon-EC Ultra) */
+
GMF_WSP_TST_ON = 1<<18,/* Write Shadow Pointer Test On */
GMF_WSP_TST_OFF = 1<<17,/* Write Shadow Pointer Test Off */
GMF_WSP_STEP = 1<<16,/* Write Shadow Pointer Step/Increment */
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 3b91af89e4c..e3019d52c30 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -719,7 +719,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS;
spin_unlock_irqrestore(&chain->lock, flags);
- if (skb->protocol == htons(ETH_P_IP))
+ if (skb->protocol == htons(ETH_P_IP) && skb->ip_summed == CHECKSUM_PARTIAL)
switch (skb->nh.iph->protocol) {
case IPPROTO_TCP:
hwdescr->dmac_cmd_status |= SPIDER_NET_DMAC_TCP;
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index ef671739cfe..192bbc91c73 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -3314,7 +3314,7 @@ static int __devexit hme_sbus_remove(struct of_device *dev)
struct happy_meal *hp = dev_get_drvdata(&dev->dev);
struct net_device *net_dev = hp->dev;
- unregister_netdevice(net_dev);
+ unregister_netdev(net_dev);
/* XXX qfe parent interrupt... */
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 5b00d79b557..b0929a457b6 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -1550,7 +1550,7 @@ static int __exit sunlance_sun4_remove(void)
struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev);
struct net_device *net_dev = lp->dev;
- unregister_netdevice(net_dev);
+ unregister_netdev(net_dev);
lance_free_hwresources(lp);
@@ -1590,7 +1590,7 @@ static int __devexit sunlance_sbus_remove(struct of_device *dev)
struct lance_private *lp = dev_get_drvdata(&dev->dev);
struct net_device *net_dev = lp->dev;
- unregister_netdevice(net_dev);
+ unregister_netdev(net_dev);
lance_free_hwresources(lp);
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index 7874eb1ef04..f3bad56d476 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -845,6 +845,8 @@ static int __init qec_ether_init(struct sbus_dev *sdev)
if (!dev)
return -ENOMEM;
+ memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
+
qe = netdev_priv(dev);
i = of_getintprop_default(sdev->ofdev.node, "channel#", -1);
@@ -960,7 +962,7 @@ static int __devexit qec_sbus_remove(struct of_device *dev)
struct sunqe *qp = dev_get_drvdata(&dev->dev);
struct net_device *net_dev = qp->dev;
- unregister_netdevice(net_dev);
+ unregister_netdev(net_dev);
sbus_iounmap(qp->qcregs, CREG_REG_SIZE);
sbus_iounmap(qp->mregs, MREGS_REG_SIZE);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index 80cb88eb98c..a38e7eec0e6 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -946,6 +946,7 @@ static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
u8 channel;
struct bcm43xx_phyinfo *phy;
const char *iso_country;
+ u8 max_bg_channel;
geo = kzalloc(sizeof(*geo), GFP_KERNEL);
if (!geo)
@@ -967,6 +968,23 @@ static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
}
iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
+/* set the maximum channel based on locale set in sprom or witle locale option */
+ switch (bcm->sprom.locale) {
+ case BCM43xx_LOCALE_THAILAND:
+ case BCM43xx_LOCALE_ISRAEL:
+ case BCM43xx_LOCALE_JORDAN:
+ case BCM43xx_LOCALE_USA_CANADA_ANZ:
+ case BCM43xx_LOCALE_USA_LOW:
+ max_bg_channel = 11;
+ break;
+ case BCM43xx_LOCALE_JAPAN:
+ case BCM43xx_LOCALE_JAPAN_HIGH:
+ max_bg_channel = 14;
+ break;
+ default:
+ max_bg_channel = 13;
+ }
+
if (have_a) {
for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL;
channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) {
@@ -978,7 +996,7 @@ static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
}
if (have_bg) {
for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL;
- channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) {
+ channel <= max_bg_channel; channel++) {
chan = &geo->bg[i++];
chan->freq = bcm43xx_channel_to_freq_bg(channel);
chan->channel = channel;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index d1e89be965c..72529a440f1 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -978,7 +978,7 @@ static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
{
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 backup_phy[15];
+ u16 backup_phy[15] = {0};
u16 backup_radio[3];
u16 backup_bband;
u16 i;
@@ -989,8 +989,10 @@ static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
backup_phy[1] = bcm43xx_phy_read(bcm, 0x0001);
backup_phy[2] = bcm43xx_phy_read(bcm, 0x0811);
backup_phy[3] = bcm43xx_phy_read(bcm, 0x0812);
- backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814);
- backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815);
+ if (phy->rev != 1) {
+ backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814);
+ backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815);
+ }
backup_phy[6] = bcm43xx_phy_read(bcm, 0x005A);
backup_phy[7] = bcm43xx_phy_read(bcm, 0x0059);
backup_phy[8] = bcm43xx_phy_read(bcm, 0x0058);
@@ -1018,14 +1020,16 @@ static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
bcm43xx_phy_read(bcm, 0x0811) | 0x0001);
bcm43xx_phy_write(bcm, 0x0812,
bcm43xx_phy_read(bcm, 0x0812) & 0xFFFE);
- bcm43xx_phy_write(bcm, 0x0814,
- bcm43xx_phy_read(bcm, 0x0814) | 0x0001);
- bcm43xx_phy_write(bcm, 0x0815,
- bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE);
- bcm43xx_phy_write(bcm, 0x0814,
- bcm43xx_phy_read(bcm, 0x0814) | 0x0002);
- bcm43xx_phy_write(bcm, 0x0815,
- bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD);
+ if (phy->rev != 1) {
+ bcm43xx_phy_write(bcm, 0x0814,
+ bcm43xx_phy_read(bcm, 0x0814) | 0x0001);
+ bcm43xx_phy_write(bcm, 0x0815,
+ bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE);
+ bcm43xx_phy_write(bcm, 0x0814,
+ bcm43xx_phy_read(bcm, 0x0814) | 0x0002);
+ bcm43xx_phy_write(bcm, 0x0815,
+ bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD);
+ }
bcm43xx_phy_write(bcm, 0x0811,
bcm43xx_phy_read(bcm, 0x0811) | 0x000C);
bcm43xx_phy_write(bcm, 0x0812,
@@ -1048,10 +1052,12 @@ static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
bcm43xx_phy_read(bcm, 0x000A)
| 0x2000);
}
- bcm43xx_phy_write(bcm, 0x0814,
- bcm43xx_phy_read(bcm, 0x0814) | 0x0004);
- bcm43xx_phy_write(bcm, 0x0815,
- bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB);
+ if (phy->rev != 1) {
+ bcm43xx_phy_write(bcm, 0x0814,
+ bcm43xx_phy_read(bcm, 0x0814) | 0x0004);
+ bcm43xx_phy_write(bcm, 0x0815,
+ bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB);
+ }
bcm43xx_phy_write(bcm, 0x0003,
(bcm43xx_phy_read(bcm, 0x0003)
& 0xFF9F) | 0x0040);
@@ -1138,8 +1144,10 @@ static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
}
}
- bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]);
- bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]);
+ if (phy->rev != 1) {
+ bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]);
+ bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]);
+ }
bcm43xx_phy_write(bcm, 0x005A, backup_phy[6]);
bcm43xx_phy_write(bcm, 0x0059, backup_phy[7]);
bcm43xx_phy_write(bcm, 0x0058, backup_phy[8]);
@@ -1188,24 +1196,23 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
bcm43xx_phy_write(bcm, 0x0811, 0x0000);
bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
}
- if (phy->rev >= 3) {
+ if (phy->rev > 5) {
bcm43xx_phy_write(bcm, 0x0811, 0x0400);
bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
}
if (phy->rev >= 2 && phy->connected) {
tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF;
- if (tmp < 6) {
+ if (tmp ==3 || tmp == 5) {
bcm43xx_phy_write(bcm, 0x04C2, 0x1816);
bcm43xx_phy_write(bcm, 0x04C3, 0x8006);
- if (tmp != 3) {
+ if (tmp == 5) {
bcm43xx_phy_write(bcm, 0x04CC,
(bcm43xx_phy_read(bcm, 0x04CC)
& 0x00FF) | 0x1F00);
}
}
- }
- if (phy->rev < 3 && phy->connected)
bcm43xx_phy_write(bcm, 0x047E, 0x0078);
+ }
if (radio->revision == 8) {
bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080);
bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004);
@@ -1232,7 +1239,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
if (phy->rev >= 6) {
bcm43xx_phy_write(bcm, 0x0036,
(bcm43xx_phy_read(bcm, 0x0036)
- & 0xF000) | (radio->txctl2 << 12));
+ & 0x0FFF) | (radio->txctl2 << 12));
}
if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
bcm43xx_phy_write(bcm, 0x002E, 0x8075);
@@ -1243,7 +1250,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
else
bcm43xx_phy_write(bcm, 0x002F, 0x0202);
}
- if (phy->connected) {
+ if (phy->connected || phy->rev >= 2) {
bcm43xx_phy_lo_adjust(bcm, 0);
bcm43xx_phy_write(bcm, 0x080F, 0x8078);
}
@@ -1257,7 +1264,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
*/
bcm43xx_nrssi_hw_update(bcm, 0xFFFF);
bcm43xx_calc_nrssi_threshold(bcm);
- } else if (phy->connected) {
+ } else if (phy->connected || phy->rev >= 2) {
if (radio->nrssi[0] == -1000) {
assert(radio->nrssi[1] == -1000);
bcm43xx_calc_nrssi_slope(bcm);
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 9c64f894b71..87ee3ee020f 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -337,6 +337,7 @@ static int read_pod(struct zd_chip *chip, u8 *rf_type)
chip->patch_cr157 = (value >> 13) & 0x1;
chip->patch_6m_band_edge = (value >> 21) & 0x1;
chip->new_phy_layout = (value >> 31) & 0x1;
+ chip->al2230s_bit = (value >> 7) & 0x1;
chip->link_led = ((value >> 4) & 1) ? LED1 : LED2;
chip->supports_tx_led = 1;
if (value & (1 << 24)) { /* LED scenario */
@@ -591,16 +592,16 @@ int zd_chip_unlock_phy_regs(struct zd_chip *chip)
return r;
}
-/* CR157 can be optionally patched by the EEPROM */
+/* CR157 can be optionally patched by the EEPROM for original ZD1211 */
static int patch_cr157(struct zd_chip *chip)
{
int r;
- u32 value;
+ u16 value;
if (!chip->patch_cr157)
return 0;
- r = zd_ioread32_locked(chip, &value, E2P_PHY_REG);
+ r = zd_ioread16_locked(chip, &value, E2P_PHY_REG);
if (r)
return r;
@@ -790,11 +791,6 @@ static int zd1211b_hw_reset_phy(struct zd_chip *chip)
goto out;
r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
- if (r)
- goto unlock;
-
- r = patch_cr157(chip);
-unlock:
t = zd_chip_unlock_phy_regs(chip);
if (t && !r)
r = t;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index b07569e391e..e57ed75d942 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -641,8 +641,8 @@ enum {
* also only 11 channels. */
#define E2P_ALLOWED_CHANNEL E2P_DATA(0x18)
-#define E2P_PHY_REG E2P_DATA(0x1a)
#define E2P_DEVICE_VER E2P_DATA(0x20)
+#define E2P_PHY_REG E2P_DATA(0x25)
#define E2P_36M_CAL_VALUE1 E2P_DATA(0x28)
#define E2P_36M_CAL_VALUE2 E2P_DATA(0x2a)
#define E2P_36M_CAL_VALUE3 E2P_DATA(0x2c)
@@ -711,7 +711,7 @@ struct zd_chip {
u16 link_led;
unsigned int pa_type:4,
patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1,
- new_phy_layout:1,
+ new_phy_layout:1, al2230s_bit:1,
is_zd1211b:1, supports_tx_led:1;
};
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index 25323a13a3d..5235a7827ac 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -358,6 +358,12 @@ int zd_rf_init_al2230(struct zd_rf *rf)
{
struct zd_chip *chip = zd_rf_to_chip(rf);
+ if (chip->al2230s_bit) {
+ dev_err(zd_chip_dev(chip), "AL2230S devices are not yet "
+ "supported by this driver.\n");
+ return -ENODEV;
+ }
+
rf->switch_radio_off = al2230_switch_radio_off;
if (chip->is_zd1211b) {
rf->init_hw = zd1211b_al2230_init_hw;
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index aac8a1c5ba0..edaaad2f648 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -62,6 +62,7 @@ static struct usb_device_id usb_ids[] = {
{ USB_DEVICE(0x0471, 0x1236), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x13b1, 0x0024), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x0586, 0x340f), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x0baf, 0x0121), .driver_info = DEVICE_ZD1211B },
/* "Driverless" devices that need ejecting */
{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
{}
diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c
index 9793533276e..400bb90084c 100644
--- a/drivers/parport/parport_sunbpp.c
+++ b/drivers/parport/parport_sunbpp.c
@@ -126,7 +126,7 @@ static unsigned char status_sunbpp_to_pc(struct parport *p)
if (!(value_tcr & P_TCR_BUSY))
bits |= PARPORT_STATUS_BUSY;
- dprintk((KERN_DEBUG "tcr 0x%x ir 0x%x\n", regs->p_tcr, regs->p_ir));
+ dprintk((KERN_DEBUG "tcr 0x%x ir 0x%x\n", value_tcr, value_ir));
dprintk((KERN_DEBUG "read status 0x%x\n", bits));
return bits;
}
@@ -147,7 +147,7 @@ static unsigned char control_sunbpp_to_pc(struct parport *p)
if (value_or & P_OR_SLCT_IN)
bits |= PARPORT_CONTROL_SELECT;
- dprintk((KERN_DEBUG "tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or));
+ dprintk((KERN_DEBUG "tcr 0x%x or 0x%x\n", value_tcr, value_or));
dprintk((KERN_DEBUG "read control 0x%x\n", bits));
return bits;
}
@@ -165,7 +165,8 @@ static unsigned char parport_sunbpp_frob_control(struct parport *p,
unsigned char value_tcr = sbus_readb(&regs->p_tcr);
unsigned char value_or = sbus_readb(&regs->p_or);
- dprintk((KERN_DEBUG "frob1: tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or));
+ dprintk((KERN_DEBUG "frob1: tcr 0x%x or 0x%x\n",
+ value_tcr, value_or));
if (mask & PARPORT_CONTROL_STROBE) {
if (val & PARPORT_CONTROL_STROBE) {
value_tcr &= ~P_TCR_DS;
@@ -197,7 +198,8 @@ static unsigned char parport_sunbpp_frob_control(struct parport *p,
sbus_writeb(value_or, &regs->p_or);
sbus_writeb(value_tcr, &regs->p_tcr);
- dprintk((KERN_DEBUG "frob2: tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or));
+ dprintk((KERN_DEBUG "frob2: tcr 0x%x or 0x%x\n",
+ value_tcr, value_or));
return parport_sunbpp_read_control(p);
}
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index a4a96826d9e..2fe1d690eb1 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -682,34 +682,7 @@ static void pci_read_irq(struct pci_dev *dev)
dev->irq = irq;
}
-static void change_legacy_io_resource(struct pci_dev * dev, unsigned index,
- unsigned start, unsigned end)
-{
- unsigned base = start & PCI_BASE_ADDRESS_IO_MASK;
- unsigned len = (end | ~PCI_BASE_ADDRESS_IO_MASK) - base + 1;
-
- /*
- * Some X versions get confused when the BARs reported through
- * /sys or /proc differ from those seen in config space, thus
- * try to update the config space values, too.
- */
- if (!(pci_resource_flags(dev, index) & IORESOURCE_IO))
- printk(KERN_WARNING "%s: cannot adjust BAR%u (not I/O)\n",
- pci_name(dev), index);
- else if (pci_resource_len(dev, index) != len)
- printk(KERN_WARNING "%s: cannot adjust BAR%u (size %04X)\n",
- pci_name(dev), index, (unsigned)pci_resource_len(dev, index));
- else {
- printk(KERN_INFO "%s: trying to change BAR%u from %04X to %04X\n",
- pci_name(dev), index,
- (unsigned)pci_resource_start(dev, index), base);
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + index * 4, base);
- }
- pci_resource_start(dev, index) = start;
- pci_resource_end(dev, index) = end;
- pci_resource_flags(dev, index) =
- IORESOURCE_IO | IORESOURCE_PCI_FIXED | PCI_BASE_ADDRESS_SPACE_IO;
-}
+#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
/**
* pci_setup_device - fill in class and map information of a device
@@ -762,12 +735,20 @@ static int pci_setup_device(struct pci_dev * dev)
u8 progif;
pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
if ((progif & 1) == 0) {
- change_legacy_io_resource(dev, 0, 0x1F0, 0x1F7);
- change_legacy_io_resource(dev, 1, 0x3F6, 0x3F6);
+ dev->resource[0].start = 0x1F0;
+ dev->resource[0].end = 0x1F7;
+ dev->resource[0].flags = LEGACY_IO_RESOURCE;
+ dev->resource[1].start = 0x3F6;
+ dev->resource[1].end = 0x3F6;
+ dev->resource[1].flags = LEGACY_IO_RESOURCE;
}
if ((progif & 4) == 0) {
- change_legacy_io_resource(dev, 2, 0x170, 0x177);
- change_legacy_io_resource(dev, 3, 0x376, 0x376);
+ dev->resource[2].start = 0x170;
+ dev->resource[2].end = 0x177;
+ dev->resource[2].flags = LEGACY_IO_RESOURCE;
+ dev->resource[3].start = 0x376;
+ dev->resource[3].end = 0x376;
+ dev->resource[3].flags = LEGACY_IO_RESOURCE;
}
}
break;
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index eec28c142a5..5041c9dfbe3 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -249,7 +249,7 @@ static int oprompci2node(void __user *argp, struct device_node *dp, struct openp
#ifdef CONFIG_PCI
struct pci_dev *pdev;
struct pcidev_cookie *pcp;
- pdev = pci_find_slot (((int *) op->oprom_array)[0],
+ pdev = pci_get_bus_and_slot (((int *) op->oprom_array)[0],
((int *) op->oprom_array)[1]);
pcp = pdev->sysdata;
@@ -260,6 +260,7 @@ static int oprompci2node(void __user *argp, struct device_node *dp, struct openp
op->oprom_size = sizeof(int);
err = copyout(argp, op, bufsize + sizeof(int));
}
+ pci_dev_put(pdev);
#endif
}
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index 8bfb67ccdcd..c3135e2fbd5 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -259,11 +259,10 @@ static int vfc_debug(struct vfc_dev *dev, int cmd, void __user *argp)
if (copy_from_user(&inout, argp, sizeof(inout)))
return -EFAULT;
- buffer = kmalloc(inout.len, GFP_KERNEL);
+ buffer = kzalloc(inout.len, GFP_KERNEL);
if (buffer == NULL)
return -ENOMEM;
- memset(buffer,0,inout.len);
vfc_lock_device(dev);
inout.ret=
vfc_i2c_recvbuf(dev,inout.addr & 0xff
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index bf5d63e1bee..656bdb1352d 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1864,10 +1864,17 @@ static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
/* This function will handle the request sense scsi command */
static int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
{
+ char request_buffer[18];
+
dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
- /* For now we just zero the request buffer */
- memset(tw_dev->srb[request_id]->request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
+ memset(request_buffer, 0, sizeof(request_buffer));
+ request_buffer[0] = 0x70; /* Immediate fixed format */
+ request_buffer[7] = 10; /* minimum size per SPC: 18 bytes */
+ /* leave all other fields zero, giving effectively NO_SENSE return */
+ tw_transfer_internal(tw_dev, request_id, request_buffer,
+ sizeof(request_buffer));
+
tw_dev->state[request_id] = TW_S_COMPLETED;
tw_state_request_finish(tw_dev, request_id);
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index 9b827ceec50..9f10689905a 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -1281,7 +1281,7 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti)
(struct scatterlist *)Cmnd->request_buffer,
Cmnd->use_sg,
Cmnd->sc_data_direction);
- } else {
+ } else if (Cmnd->request_bufflen) {
sbus_unmap_single(qpti->sdev,
(__u32)((unsigned long)Cmnd->SCp.ptr),
Cmnd->request_bufflen,
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index c129a0e8e80..90621c3312b 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1310,7 +1310,8 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
{
unsigned int status = serial_in(up, UART_MSR);
- if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI) {
+ if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
+ up->port.info != NULL) {
if (status & UART_MSR_TERI)
up->port.icount.rng++;
if (status & UART_MSR_DDSR)
@@ -1333,8 +1334,9 @@ static inline void
serial8250_handle_port(struct uart_8250_port *up)
{
unsigned int status;
+ unsigned long flags;
- spin_lock(&up->port.lock);
+ spin_lock_irqsave(&up->port.lock, flags);
status = serial_inp(up, UART_LSR);
@@ -1346,7 +1348,7 @@ serial8250_handle_port(struct uart_8250_port *up)
if (status & UART_LSR_THRE)
transmit_chars(up);
- spin_unlock(&up->port.lock);
+ spin_unlock_irqrestore(&up->port.lock, flags);
}
/*
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 41431d0d551..246c5572667 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -164,7 +164,7 @@ static void free_port_memory(struct icom_port *icom_port)
}
}
-static int __init get_port_memory(struct icom_port *icom_port)
+static int __devinit get_port_memory(struct icom_port *icom_port)
{
int index;
unsigned long stgAddr;
@@ -1380,7 +1380,7 @@ static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *i
0x8024 + 2 - 2 * (icom_port->port - 2);
}
}
-static int __init icom_load_ports(struct icom_adapter *icom_adapter)
+static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
{
struct icom_port *icom_port;
int port_num;
@@ -1473,7 +1473,7 @@ static void icom_remove_adapter(struct icom_adapter *icom_adapter)
}
}
- free_irq(icom_adapter->irq_number, (void *) icom_adapter);
+ free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter);
iounmap(icom_adapter->base_addr);
icom_free_adapter(icom_adapter);
pci_release_regions(icom_adapter->pci_dev);
@@ -1539,7 +1539,6 @@ static int __devinit icom_probe(struct pci_dev *dev,
}
icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
- icom_adapter->irq_number = dev->irq;
icom_adapter->pci_dev = dev;
icom_adapter->version = ent->driver_data;
icom_adapter->subsystem_id = ent->subdevice;
@@ -1570,7 +1569,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
icom_port = &icom_adapter->port_info[index];
if (icom_port->status == ICOM_PORT_ACTIVE) {
- icom_port->uart_port.irq = icom_port->adapter->irq_number;
+ icom_port->uart_port.irq = icom_port->adapter->pci_dev->irq;
icom_port->uart_port.type = PORT_ICOM;
icom_port->uart_port.iotype = UPIO_MEM;
icom_port->uart_port.membase =
diff --git a/drivers/serial/icom.h b/drivers/serial/icom.h
index 798f1ef2371..e8578d8cd35 100644
--- a/drivers/serial/icom.h
+++ b/drivers/serial/icom.h
@@ -258,7 +258,6 @@ struct icom_port {
struct icom_adapter {
void __iomem * base_addr;
unsigned long base_addr_pci;
- unsigned char irq_number;
struct pci_dev *pci_dev;
struct icom_port port_info[4];
int index;
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index 220abce63e4..b10211c420e 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -77,7 +77,7 @@ static void s3c24xx_spi_chipsel(struct spi_device *spi, int value)
switch (value) {
case BITBANG_CS_INACTIVE:
- hw->pdata->set_cs(hw->pdata, spi->chip_select, cspol^1);
+ hw->set_cs(hw->pdata, spi->chip_select, cspol^1);
break;
case BITBANG_CS_ACTIVE:
@@ -98,7 +98,7 @@ static void s3c24xx_spi_chipsel(struct spi_device *spi, int value)
/* write new configration */
writeb(spcon, hw->regs + S3C2410_SPCON);
- hw->pdata->set_cs(hw->pdata, spi->chip_select, cspol);
+ hw->set_cs(hw->pdata, spi->chip_select, cspol);
break;
}
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index a7405648823..c7458f7e56c 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -669,6 +669,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
*/
ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
+ mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
}
}
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
index d48c024cff5..6d12961cf9f 100644
--- a/drivers/usb/net/pegasus.c
+++ b/drivers/usb/net/pegasus.c
@@ -316,6 +316,7 @@ static int update_eth_regs_async(pegasus_t * pegasus)
return ret;
}
+/* Returns 0 on success, error on failure */
static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
{
int i;
@@ -847,10 +848,16 @@ static void intr_callback(struct urb *urb)
* d[0].NO_CARRIER kicks in only with failed TX.
* ... so monitoring with MII may be safest.
*/
- if (d[0] & NO_CARRIER)
- netif_carrier_off(net);
- else
- netif_carrier_on(net);
+ if (pegasus->features & TRUST_LINK_STATUS) {
+ if (d[5] & LINK_STATUS)
+ netif_carrier_on(net);
+ else
+ netif_carrier_off(net);
+ } else {
+ /* Never set carrier _on_ based on ! NO_CARRIER */
+ if (d[0] & NO_CARRIER)
+ netif_carrier_off(net);
+ }
/* bytes 3-4 == rx_lostpkt, reg 2E/2F */
pegasus->stats.rx_missed_errors += ((d[3] & 0x7f) << 8) | d[4];
@@ -950,7 +957,7 @@ static void set_carrier(struct net_device *net)
pegasus_t *pegasus = netdev_priv(net);
u16 tmp;
- if (!read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp))
+ if (read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp))
return;
if (tmp & BMSR_LSTATUS)
diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h
index c7467823cd1..c7aadb413e8 100644
--- a/drivers/usb/net/pegasus.h
+++ b/drivers/usb/net/pegasus.h
@@ -11,6 +11,7 @@
#define PEGASUS_II 0x80000000
#define HAS_HOME_PNA 0x40000000
+#define TRUST_LINK_STATUS 0x20000000
#define PEGASUS_MTU 1536
#define RX_SKBS 4
@@ -203,7 +204,7 @@ PEGASUS_DEV( "AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701,
PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121,
- DEFAULT_GPIO_RESET | PEGASUS_II )
+ DEFAULT_GPIO_RESET | PEGASUS_II | TRUST_LINK_STATUS )
PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index e13637dfb64..4a9d0d5c728 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -327,6 +327,13 @@ UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY),
+/* Reported by Emil Larsson <emil@swip.net> */
+UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0100,
+ "NIKON",
+ "NIKON DSC D80",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY),
+
/* BENQ DC5330
* Reported by Manuel Fombuena <mfombuena@ya.com> and
* Frank Copeland <fjc@thingy.apana.org.au> */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index e4f0dd00ae8..8372ace4a0d 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -139,7 +139,7 @@ config FB_TILEBLITTING
This is particularly important to one driver, matroxfb. If
unsure, say N.
-comment "Frambuffer hardware drivers"
+comment "Frame buffer hardware drivers"
depends on FB
config FB_CIRRUS
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 124a085d1f2..b01b0a45793 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -415,7 +415,7 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
file_inode = file->d_inode;
sb = file_inode->i_sb;
v9ses = v9fs_inode2v9ses(file_inode);
- v9fid = v9fs_fid_lookup(file);
+ v9fid = v9fs_fid_clone(file);
if(IS_ERR(v9fid))
return PTR_ERR(v9fid);
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index b4631046867..d0e9b3a3905 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -470,9 +470,6 @@ void autofs4_dentry_release(struct dentry *de)
if (inf) {
struct autofs_sb_info *sbi = autofs4_sbi(de->d_sb);
- inf->dentry = NULL;
- inf->inode = NULL;
-
if (sbi) {
spin_lock(&sbi->rehash_lock);
if (!list_empty(&inf->rehash))
@@ -480,6 +477,9 @@ void autofs4_dentry_release(struct dentry *de)
spin_unlock(&sbi->rehash_lock);
}
+ inf->dentry = NULL;
+ inf->inode = NULL;
+
autofs4_free_ino(inf);
}
}
diff --git a/fs/exec.c b/fs/exec.c
index 7e36c6f6f53..3155e915307 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1244,13 +1244,17 @@ EXPORT_SYMBOL(set_binfmt);
* name into corename, which must have space for at least
* CORENAME_MAX_SIZE bytes plus one byte for the zero terminator.
*/
-static void format_corename(char *corename, const char *pattern, long signr)
+static int format_corename(char *corename, const char *pattern, long signr)
{
const char *pat_ptr = pattern;
char *out_ptr = corename;
char *const out_end = corename + CORENAME_MAX_SIZE;
int rc;
int pid_in_pattern = 0;
+ int ispipe = 0;
+
+ if (*pattern == '|')
+ ispipe = 1;
/* Repeat as long as we have more pattern to process and more output
space */
@@ -1341,8 +1345,8 @@ static void format_corename(char *corename, const char *pattern, long signr)
*
* If core_pattern does not include a %p (as is the default)
* and core_uses_pid is set, then .%pid will be appended to
- * the filename */
- if (!pid_in_pattern
+ * the filename. Do not do this for piped commands. */
+ if (!ispipe && !pid_in_pattern
&& (core_uses_pid || atomic_read(&current->mm->mm_users) != 1)) {
rc = snprintf(out_ptr, out_end - out_ptr,
".%d", current->tgid);
@@ -1350,8 +1354,9 @@ static void format_corename(char *corename, const char *pattern, long signr)
goto out;
out_ptr += rc;
}
- out:
+out:
*out_ptr = 0;
+ return ispipe;
}
static void zap_process(struct task_struct *start)
@@ -1502,16 +1507,15 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
* uses lock_kernel()
*/
lock_kernel();
- format_corename(corename, core_pattern, signr);
+ ispipe = format_corename(corename, core_pattern, signr);
unlock_kernel();
- if (corename[0] == '|') {
+ if (ispipe) {
/* SIGPIPE can happen, but it's just never processed */
if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) {
printk(KERN_INFO "Core dump to %s pipe failed\n",
corename);
goto fail_unlock;
}
- ispipe = 1;
} else
file = filp_open(corename,
O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 92d8ec859e2..cd3469720cb 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1684,7 +1684,8 @@ go_ahead:
* ... prune child dentries and writebacks if needed.
*/
if (atomic_read(&old_dentry->d_count) > 1) {
- nfs_wb_all(old_inode);
+ if (S_ISREG(old_inode->i_mode))
+ nfs_wb_all(old_inode);
shrink_dcache_parent(old_dentry);
}
nfs_inode_return_delegation(old_inode);
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index b1c98ea39b7..2877744cb60 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -432,10 +432,10 @@ static void nfs_direct_commit_result(struct rpc_task *task, void *calldata)
if (NFS_PROTO(data->inode)->commit_done(task, data) != 0)
return;
if (unlikely(task->tk_status < 0)) {
- dreq->error = task->tk_status;
+ dprintk("NFS: %5u commit failed with error %d.\n",
+ task->tk_pid, task->tk_status);
dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
- }
- if (memcmp(&dreq->verf, &data->verf, sizeof(data->verf))) {
+ } else if (memcmp(&dreq->verf, &data->verf, sizeof(data->verf))) {
dprintk("NFS: %5u commit verify failed\n", task->tk_pid);
dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
}
@@ -531,9 +531,12 @@ static void nfs_direct_write_result(struct rpc_task *task, void *calldata)
spin_lock(&dreq->lock);
+ if (unlikely(dreq->error != 0))
+ goto out_unlock;
if (unlikely(status < 0)) {
+ /* An error has occured, so we should not commit */
+ dreq->flags = 0;
dreq->error = status;
- goto out_unlock;
}
dreq->count += data->res.count;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 93d046c85f5..44aa9b72657 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -341,8 +341,10 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
lock_kernel();
nfs_begin_data_update(inode);
/* Write all dirty data */
- filemap_write_and_wait(inode->i_mapping);
- nfs_wb_all(inode);
+ if (S_ISREG(inode->i_mode)) {
+ filemap_write_and_wait(inode->i_mapping);
+ nfs_wb_all(inode);
+ }
/*
* Return any delegations if we're going to change ACLs
*/
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 2867e6b7096..79755894174 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -38,7 +38,6 @@
static struct nfs_page * nfs_update_request(struct nfs_open_context*,
struct page *,
unsigned int, unsigned int);
-static void nfs_mark_request_dirty(struct nfs_page *req);
static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how);
static const struct rpc_call_ops nfs_write_partial_ops;
static const struct rpc_call_ops nfs_write_full_ops;
@@ -218,9 +217,11 @@ int nfs_congestion_kb;
#define NFS_CONGESTION_OFF_THRESH \
(NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2))
-static void nfs_set_page_writeback(struct page *page)
+static int nfs_set_page_writeback(struct page *page)
{
- if (!test_set_page_writeback(page)) {
+ int ret = test_set_page_writeback(page);
+
+ if (!ret) {
struct inode *inode = page->mapping->host;
struct nfs_server *nfss = NFS_SERVER(inode);
@@ -228,6 +229,7 @@ static void nfs_set_page_writeback(struct page *page)
NFS_CONGESTION_ON_THRESH)
set_bdi_congested(&nfss->backing_dev_info, WRITE);
}
+ return ret;
}
static void nfs_end_page_writeback(struct page *page)
@@ -252,7 +254,8 @@ static void nfs_end_page_writeback(struct page *page)
static int nfs_page_mark_flush(struct page *page)
{
struct nfs_page *req;
- spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock;
+ struct nfs_inode *nfsi = NFS_I(page->mapping->host);
+ spinlock_t *req_lock = &nfsi->req_lock;
int ret;
spin_lock(req_lock);
@@ -276,11 +279,23 @@ static int nfs_page_mark_flush(struct page *page)
return ret;
spin_lock(req_lock);
}
- spin_unlock(req_lock);
- if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) {
- nfs_mark_request_dirty(req);
- nfs_set_page_writeback(page);
+ if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
+ /* This request is marked for commit */
+ spin_unlock(req_lock);
+ nfs_unlock_request(req);
+ return 1;
}
+ if (nfs_set_page_writeback(page) == 0) {
+ nfs_list_remove_request(req);
+ /* add the request to the inode's dirty list. */
+ radix_tree_tag_set(&nfsi->nfs_page_tree,
+ req->wb_index, NFS_PAGE_TAG_DIRTY);
+ nfs_list_add_request(req, &nfsi->dirty);
+ nfsi->ndirty++;
+ spin_unlock(req_lock);
+ __mark_inode_dirty(page->mapping->host, I_DIRTY_PAGES);
+ } else
+ spin_unlock(req_lock);
ret = test_bit(PG_NEED_FLUSH, &req->wb_flags);
nfs_unlock_request(req);
return ret;
@@ -373,6 +388,8 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
}
SetPagePrivate(req->wb_page);
set_page_private(req->wb_page, (unsigned long)req);
+ if (PageDirty(req->wb_page))
+ set_bit(PG_NEED_FLUSH, &req->wb_flags);
nfsi->npages++;
atomic_inc(&req->wb_count);
return 0;
@@ -392,6 +409,8 @@ static void nfs_inode_remove_request(struct nfs_page *req)
set_page_private(req->wb_page, 0);
ClearPagePrivate(req->wb_page);
radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
+ if (test_and_clear_bit(PG_NEED_FLUSH, &req->wb_flags))
+ __set_page_dirty_nobuffers(req->wb_page);
nfsi->npages--;
if (!nfsi->npages) {
spin_unlock(&nfsi->req_lock);
@@ -403,28 +422,9 @@ static void nfs_inode_remove_request(struct nfs_page *req)
nfs_release_request(req);
}
-/*
- * Add a request to the inode's dirty list.
- */
-static void
-nfs_mark_request_dirty(struct nfs_page *req)
-{
- struct inode *inode = req->wb_context->dentry->d_inode;
- struct nfs_inode *nfsi = NFS_I(inode);
-
- spin_lock(&nfsi->req_lock);
- radix_tree_tag_set(&nfsi->nfs_page_tree,
- req->wb_index, NFS_PAGE_TAG_DIRTY);
- nfs_list_add_request(req, &nfsi->dirty);
- nfsi->ndirty++;
- spin_unlock(&nfsi->req_lock);
- __mark_inode_dirty(inode, I_DIRTY_PAGES);
-}
-
static void
nfs_redirty_request(struct nfs_page *req)
{
- clear_bit(PG_FLUSHING, &req->wb_flags);
__set_page_dirty_nobuffers(req->wb_page);
}
@@ -434,7 +434,11 @@ nfs_redirty_request(struct nfs_page *req)
static inline int
nfs_dirty_request(struct nfs_page *req)
{
- return test_bit(PG_FLUSHING, &req->wb_flags) == 0;
+ struct page *page = req->wb_page;
+
+ if (page == NULL || test_bit(PG_NEED_COMMIT, &req->wb_flags))
+ return 0;
+ return !PageWriteback(req->wb_page);
}
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
@@ -450,10 +454,48 @@ nfs_mark_request_commit(struct nfs_page *req)
spin_lock(&nfsi->req_lock);
nfs_list_add_request(req, &nfsi->commit);
nfsi->ncommit++;
+ set_bit(PG_NEED_COMMIT, &(req)->wb_flags);
spin_unlock(&nfsi->req_lock);
inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
}
+
+static inline
+int nfs_write_need_commit(struct nfs_write_data *data)
+{
+ return data->verf.committed != NFS_FILE_SYNC;
+}
+
+static inline
+int nfs_reschedule_unstable_write(struct nfs_page *req)
+{
+ if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
+ nfs_mark_request_commit(req);
+ return 1;
+ }
+ if (test_and_clear_bit(PG_NEED_RESCHED, &req->wb_flags)) {
+ nfs_redirty_request(req);
+ return 1;
+ }
+ return 0;
+}
+#else
+static inline void
+nfs_mark_request_commit(struct nfs_page *req)
+{
+}
+
+static inline
+int nfs_write_need_commit(struct nfs_write_data *data)
+{
+ return 0;
+}
+
+static inline
+int nfs_reschedule_unstable_write(struct nfs_page *req)
+{
+ return 0;
+}
#endif
/*
@@ -500,6 +542,7 @@ static void nfs_cancel_dirty_list(struct list_head *head)
while(!list_empty(head)) {
req = nfs_list_entry(head->next);
nfs_list_remove_request(req);
+ nfs_end_page_writeback(req->wb_page);
nfs_inode_remove_request(req);
nfs_clear_page_writeback(req);
}
@@ -513,6 +556,7 @@ static void nfs_cancel_commit_list(struct list_head *head)
req = nfs_list_entry(head->next);
dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
nfs_list_remove_request(req);
+ clear_bit(PG_NEED_COMMIT, &(req)->wb_flags);
nfs_inode_remove_request(req);
nfs_unlock_request(req);
}
@@ -739,26 +783,12 @@ int nfs_updatepage(struct file *file, struct page *page,
static void nfs_writepage_release(struct nfs_page *req)
{
- nfs_end_page_writeback(req->wb_page);
-
-#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
- if (!PageError(req->wb_page)) {
- if (NFS_NEED_RESCHED(req)) {
- nfs_redirty_request(req);
- goto out;
- } else if (NFS_NEED_COMMIT(req)) {
- nfs_mark_request_commit(req);
- goto out;
- }
- }
- nfs_inode_remove_request(req);
-out:
- nfs_clear_commit(req);
- nfs_clear_reschedule(req);
-#else
- nfs_inode_remove_request(req);
-#endif
+ if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) {
+ nfs_end_page_writeback(req->wb_page);
+ nfs_inode_remove_request(req);
+ } else
+ nfs_end_page_writeback(req->wb_page);
nfs_clear_page_writeback(req);
}
@@ -891,6 +921,7 @@ out_bad:
nfs_writedata_release(data);
}
nfs_redirty_request(req);
+ nfs_end_page_writeback(req->wb_page);
nfs_clear_page_writeback(req);
return -ENOMEM;
}
@@ -936,6 +967,7 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, int how)
struct nfs_page *req = nfs_list_entry(head->next);
nfs_list_remove_request(req);
nfs_redirty_request(req);
+ nfs_end_page_writeback(req->wb_page);
nfs_clear_page_writeback(req);
}
return -ENOMEM;
@@ -971,6 +1003,7 @@ out_err:
req = nfs_list_entry(head->next);
nfs_list_remove_request(req);
nfs_redirty_request(req);
+ nfs_end_page_writeback(req->wb_page);
nfs_clear_page_writeback(req);
}
return error;
@@ -998,22 +1031,28 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
nfs_set_pageerror(page);
req->wb_context->error = task->tk_status;
dprintk(", error = %d\n", task->tk_status);
- } else {
-#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
- if (data->verf.committed < NFS_FILE_SYNC) {
- if (!NFS_NEED_COMMIT(req)) {
- nfs_defer_commit(req);
- memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
- dprintk(" defer commit\n");
- } else if (memcmp(&req->wb_verf, &data->verf, sizeof(req->wb_verf))) {
- nfs_defer_reschedule(req);
- dprintk(" server reboot detected\n");
- }
- } else
-#endif
- dprintk(" OK\n");
+ goto out;
}
+ if (nfs_write_need_commit(data)) {
+ spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock;
+
+ spin_lock(req_lock);
+ if (test_bit(PG_NEED_RESCHED, &req->wb_flags)) {
+ /* Do nothing we need to resend the writes */
+ } else if (!test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags)) {
+ memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
+ dprintk(" defer commit\n");
+ } else if (memcmp(&req->wb_verf, &data->verf, sizeof(req->wb_verf))) {
+ set_bit(PG_NEED_RESCHED, &req->wb_flags);
+ clear_bit(PG_NEED_COMMIT, &req->wb_flags);
+ dprintk(" server reboot detected\n");
+ }
+ spin_unlock(req_lock);
+ } else
+ dprintk(" OK\n");
+
+out:
if (atomic_dec_and_test(&req->wb_complete))
nfs_writepage_release(req);
}
@@ -1054,25 +1093,21 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
if (task->tk_status < 0) {
nfs_set_pageerror(page);
req->wb_context->error = task->tk_status;
- nfs_end_page_writeback(page);
- nfs_inode_remove_request(req);
dprintk(", error = %d\n", task->tk_status);
- goto next;
+ goto remove_request;
}
- nfs_end_page_writeback(page);
-#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
- if (data->args.stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) {
- nfs_inode_remove_request(req);
- dprintk(" OK\n");
+ if (nfs_write_need_commit(data)) {
+ memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
+ nfs_mark_request_commit(req);
+ nfs_end_page_writeback(page);
+ dprintk(" marked for commit\n");
goto next;
}
- memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
- nfs_mark_request_commit(req);
- dprintk(" marked for commit\n");
-#else
+ dprintk(" OK\n");
+remove_request:
+ nfs_end_page_writeback(page);
nfs_inode_remove_request(req);
-#endif
next:
nfs_clear_page_writeback(req);
}
@@ -1260,6 +1295,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
while (!list_empty(&data->pages)) {
req = nfs_list_entry(data->pages.next);
nfs_list_remove_request(req);
+ clear_bit(PG_NEED_COMMIT, &(req)->wb_flags);
dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
dprintk("NFS: commit (%s/%Ld %d@%Ld)",
@@ -1495,15 +1531,22 @@ int nfs_wb_page(struct inode *inode, struct page* page)
int nfs_set_page_dirty(struct page *page)
{
+ spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock;
struct nfs_page *req;
+ int ret;
- req = nfs_page_find_request(page);
+ spin_lock(req_lock);
+ req = nfs_page_find_request_locked(page);
if (req != NULL) {
/* Mark any existing write requests for flushing */
- set_bit(PG_NEED_FLUSH, &req->wb_flags);
+ ret = !test_and_set_bit(PG_NEED_FLUSH, &req->wb_flags);
+ spin_unlock(req_lock);
nfs_release_request(req);
+ return ret;
}
- return __set_page_dirty_nobuffers(page);
+ ret = __set_page_dirty_nobuffers(page);
+ spin_unlock(req_lock);
+ return ret;
}
diff --git a/fs/reiserfs/item_ops.c b/fs/reiserfs/item_ops.c
index b9b423b22a8..9475557ab49 100644
--- a/fs/reiserfs/item_ops.c
+++ b/fs/reiserfs/item_ops.c
@@ -23,7 +23,7 @@ static void sd_decrement_key(struct cpu_key *key)
{
key->on_disk_key.k_objectid--;
set_cpu_key_k_type(key, TYPE_ANY);
- set_cpu_key_k_offset(key, (loff_t) (-1));
+ set_cpu_key_k_offset(key, (loff_t)(~0ULL >> 1));
}
static int sd_is_left_mergeable(struct reiserfs_key *key, unsigned long bsize)
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index f01389fd162..c8178b7b921 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -54,82 +54,48 @@
static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
*prefix);
-static struct dentry *create_xa_root(struct super_block *sb)
+/* Returns the dentry referring to the root of the extended attribute
+ * directory tree. If it has already been retrieved, it is used. If it
+ * hasn't been created and the flags indicate creation is allowed, we
+ * attempt to create it. On error, we return a pointer-encoded error.
+ */
+static struct dentry *get_xa_root(struct super_block *sb, int flags)
{
struct dentry *privroot = dget(REISERFS_SB(sb)->priv_root);
struct dentry *xaroot;
/* This needs to be created at mount-time */
if (!privroot)
- return ERR_PTR(-EOPNOTSUPP);
+ return ERR_PTR(-ENODATA);
- xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME));
- if (IS_ERR(xaroot)) {
+ mutex_lock(&privroot->d_inode->i_mutex);
+ if (REISERFS_SB(sb)->xattr_root) {
+ xaroot = dget(REISERFS_SB(sb)->xattr_root);
goto out;
- } else if (!xaroot->d_inode) {
- int err;
- mutex_lock(&privroot->d_inode->i_mutex);
- err =
- privroot->d_inode->i_op->mkdir(privroot->d_inode, xaroot,
- 0700);
- mutex_unlock(&privroot->d_inode->i_mutex);
-
- if (err) {
- dput(xaroot);
- dput(privroot);
- return ERR_PTR(err);
- }
- REISERFS_SB(sb)->xattr_root = dget(xaroot);
}
- out:
- dput(privroot);
- return xaroot;
-}
-
-/* This will return a dentry, or error, refering to the xa root directory.
- * If the xa root doesn't exist yet, the dentry will be returned without
- * an associated inode. This dentry can be used with ->mkdir to create
- * the xa directory. */
-static struct dentry *__get_xa_root(struct super_block *s)
-{
- struct dentry *privroot = dget(REISERFS_SB(s)->priv_root);
- struct dentry *xaroot = NULL;
-
- if (IS_ERR(privroot) || !privroot)
- return privroot;
-
xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME));
if (IS_ERR(xaroot)) {
goto out;
} else if (!xaroot->d_inode) {
- dput(xaroot);
- xaroot = NULL;
- goto out;
+ int err = -ENODATA;
+ if (flags == 0 || flags & XATTR_CREATE)
+ err = privroot->d_inode->i_op->mkdir(privroot->d_inode,
+ xaroot, 0700);
+ if (err) {
+ dput(xaroot);
+ xaroot = ERR_PTR(err);
+ goto out;
+ }
}
-
- REISERFS_SB(s)->xattr_root = dget(xaroot);
+ REISERFS_SB(sb)->xattr_root = dget(xaroot);
out:
+ mutex_unlock(&privroot->d_inode->i_mutex);
dput(privroot);
return xaroot;
}
-/* Returns the dentry (or NULL) referring to the root of the extended
- * attribute directory tree. If it has already been retrieved, it is used.
- * Otherwise, we attempt to retrieve it from disk. It may also return
- * a pointer-encoded error.
- */
-static inline struct dentry *get_xa_root(struct super_block *s)
-{
- struct dentry *dentry = dget(REISERFS_SB(s)->xattr_root);
-
- if (!dentry)
- dentry = __get_xa_root(s);
-
- return dentry;
-}
-
/* Opens the directory corresponding to the inode's extended attribute store.
* If flags allow, the tree to the directory may be created. If creation is
* prohibited, -ENODATA is returned. */
@@ -138,21 +104,11 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags)
struct dentry *xaroot, *xadir;
char namebuf[17];
- xaroot = get_xa_root(inode->i_sb);
- if (IS_ERR(xaroot)) {
+ xaroot = get_xa_root(inode->i_sb, flags);
+ if (IS_ERR(xaroot))
return xaroot;
- } else if (!xaroot) {
- if (flags == 0 || flags & XATTR_CREATE) {
- xaroot = create_xa_root(inode->i_sb);
- if (IS_ERR(xaroot))
- return xaroot;
- }
- if (!xaroot)
- return ERR_PTR(-ENODATA);
- }
/* ok, we have xaroot open */
-
snprintf(namebuf, sizeof(namebuf), "%X.%X",
le32_to_cpu(INODE_PKEY(inode)->k_objectid),
inode->i_generation);
@@ -821,7 +777,7 @@ int reiserfs_delete_xattrs(struct inode *inode)
/* Leftovers besides . and .. -- that's not good. */
if (dir->d_inode->i_nlink <= 2) {
- root = get_xa_root(inode->i_sb);
+ root = get_xa_root(inode->i_sb, XATTR_REPLACE);
reiserfs_write_lock_xattrs(inode->i_sb);
err = vfs_rmdir(root->d_inode, dir);
reiserfs_write_unlock_xattrs(inode->i_sb);
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 013d7afe7cd..f18b79122fa 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -601,7 +601,7 @@ static void ufs_set_inode_ops(struct inode *inode)
ufs_get_inode_dev(inode->i_sb, UFS_I(inode)));
}
-static void ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
+static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
{
struct ufs_inode_info *ufsi = UFS_I(inode);
struct super_block *sb = inode->i_sb;
@@ -613,8 +613,10 @@ static void ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
*/
inode->i_mode = mode = fs16_to_cpu(sb, ufs_inode->ui_mode);
inode->i_nlink = fs16_to_cpu(sb, ufs_inode->ui_nlink);
- if (inode->i_nlink == 0)
+ if (inode->i_nlink == 0) {
ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino);
+ return -1;
+ }
/*
* Linux now has 32-bit uid and gid, so we can support EFT.
@@ -643,9 +645,10 @@ static void ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++)
ufsi->i_u1.i_symlink[i] = ufs_inode->ui_u2.ui_symlink[i];
}
+ return 0;
}
-static void ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode)
+static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode)
{
struct ufs_inode_info *ufsi = UFS_I(inode);
struct super_block *sb = inode->i_sb;
@@ -658,8 +661,10 @@ static void ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode)
*/
inode->i_mode = mode = fs16_to_cpu(sb, ufs2_inode->ui_mode);
inode->i_nlink = fs16_to_cpu(sb, ufs2_inode->ui_nlink);
- if (inode->i_nlink == 0)
+ if (inode->i_nlink == 0) {
ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino);
+ return -1;
+ }
/*
* Linux now has 32-bit uid and gid, so we can support EFT.
@@ -690,6 +695,7 @@ static void ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode)
for (i = 0; i < (UFS_NDADDR + UFS_NINDIR) * 4; i++)
ufsi->i_u1.i_symlink[i] = ufs2_inode->ui_u2.ui_symlink[i];
}
+ return 0;
}
void ufs_read_inode(struct inode * inode)
@@ -698,6 +704,7 @@ void ufs_read_inode(struct inode * inode)
struct super_block * sb;
struct ufs_sb_private_info * uspi;
struct buffer_head * bh;
+ int err;
UFSD("ENTER, ino %lu\n", inode->i_ino);
@@ -720,14 +727,17 @@ void ufs_read_inode(struct inode * inode)
if ((UFS_SB(sb)->s_flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
struct ufs2_inode *ufs2_inode = (struct ufs2_inode *)bh->b_data;
- ufs2_read_inode(inode,
- ufs2_inode + ufs_inotofsbo(inode->i_ino));
+ err = ufs2_read_inode(inode,
+ ufs2_inode + ufs_inotofsbo(inode->i_ino));
} else {
struct ufs_inode *ufs_inode = (struct ufs_inode *)bh->b_data;
- ufs1_read_inode(inode, ufs_inode + ufs_inotofsbo(inode->i_ino));
+ err = ufs1_read_inode(inode,
+ ufs_inode + ufs_inotofsbo(inode->i_ino));
}
+ if (err)
+ goto bad_inode;
inode->i_version++;
ufsi->i_lastfrag =
(inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift;
@@ -888,6 +898,8 @@ void ufs_delete_inode (struct inode * inode)
loff_t old_i_size;
truncate_inode_pages(&inode->i_data, 0);
+ if (is_bad_inode(inode))
+ goto no_delete;
/*UFS_I(inode)->i_dtime = CURRENT_TIME;*/
lock_kernel();
mark_inode_dirty(inode);
@@ -898,4 +910,7 @@ void ufs_delete_inode (struct inode * inode)
ufs_warning(inode->i_sb, __FUNCTION__, "ufs_truncate failed\n");
ufs_free_inode (inode);
unlock_kernel();
+ return;
+no_delete:
+ clear_inode(inode); /* We must guarantee clearing of inode... */
}
diff --git a/include/asm-alpha/compiler.h b/include/asm-alpha/compiler.h
index d2768cc3d7a..da6bb199839 100644
--- a/include/asm-alpha/compiler.h
+++ b/include/asm-alpha/compiler.h
@@ -17,9 +17,6 @@
# define __kernel_extbl(val, shift) __builtin_alpha_extbl(val, shift)
# define __kernel_extwl(val, shift) __builtin_alpha_extwl(val, shift)
# define __kernel_cmpbge(a, b) __builtin_alpha_cmpbge(a, b)
-# define __kernel_cttz(x) __builtin_ctzl(x)
-# define __kernel_ctlz(x) __builtin_clzl(x)
-# define __kernel_ctpop(x) __builtin_popcountl(x)
#else
# define __kernel_insbl(val, shift) \
({ unsigned long __kir; \
@@ -49,17 +46,39 @@
({ unsigned long __kir; \
__asm__("cmpbge %r2,%1,%0" : "=r"(__kir) : "rI"(b), "rJ"(a)); \
__kir; })
+#endif
+
+#ifdef __alpha_cix__
+# if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 || __GNUC__ > 3
+# define __kernel_cttz(x) __builtin_ctzl(x)
+# define __kernel_ctlz(x) __builtin_clzl(x)
+# define __kernel_ctpop(x) __builtin_popcountl(x)
+# else
+# define __kernel_cttz(x) \
+ ({ unsigned long __kir; \
+ __asm__("cttz %1,%0" : "=r"(__kir) : "r"(x)); \
+ __kir; })
+# define __kernel_ctlz(x) \
+ ({ unsigned long __kir; \
+ __asm__("ctlz %1,%0" : "=r"(__kir) : "r"(x)); \
+ __kir; })
+# define __kernel_ctpop(x) \
+ ({ unsigned long __kir; \
+ __asm__("ctpop %1,%0" : "=r"(__kir) : "r"(x)); \
+ __kir; })
+# endif
+#else
# define __kernel_cttz(x) \
({ unsigned long __kir; \
- __asm__("cttz %1,%0" : "=r"(__kir) : "r"(x)); \
+ __asm__(".arch ev67; cttz %1,%0" : "=r"(__kir) : "r"(x)); \
__kir; })
# define __kernel_ctlz(x) \
({ unsigned long __kir; \
- __asm__("ctlz %1,%0" : "=r"(__kir) : "r"(x)); \
+ __asm__(".arch ev67; ctlz %1,%0" : "=r"(__kir) : "r"(x)); \
__kir; })
# define __kernel_ctpop(x) \
({ unsigned long __kir; \
- __asm__("ctpop %1,%0" : "=r"(__kir) : "r"(x)); \
+ __asm__(".arch ev67; ctpop %1,%0" : "=r"(__kir) : "r"(x)); \
__kir; })
#endif
@@ -78,16 +97,20 @@
#else
#define __kernel_ldbu(mem) \
({ unsigned char __kir; \
- __asm__("ldbu %0,%1" : "=r"(__kir) : "m"(mem)); \
+ __asm__(".arch ev56; \
+ ldbu %0,%1" : "=r"(__kir) : "m"(mem)); \
__kir; })
#define __kernel_ldwu(mem) \
({ unsigned short __kir; \
- __asm__("ldwu %0,%1" : "=r"(__kir) : "m"(mem)); \
+ __asm__(".arch ev56; \
+ ldwu %0,%1" : "=r"(__kir) : "m"(mem)); \
__kir; })
-#define __kernel_stb(val,mem) \
- __asm__("stb %1,%0" : "=m"(mem) : "r"(val))
-#define __kernel_stw(val,mem) \
- __asm__("stw %1,%0" : "=m"(mem) : "r"(val))
+#define __kernel_stb(val,mem) \
+ __asm__(".arch ev56; \
+ stb %1,%0" : "=m"(mem) : "r"(val))
+#define __kernel_stw(val,mem) \
+ __asm__(".arch ev56; \
+ stw %1,%0" : "=m"(mem) : "r"(val))
#endif
#ifdef __KERNEL__
diff --git a/include/asm-alpha/core_mcpcia.h b/include/asm-alpha/core_mcpcia.h
index 980a3c51b18..525b4f6a7ac 100644
--- a/include/asm-alpha/core_mcpcia.h
+++ b/include/asm-alpha/core_mcpcia.h
@@ -72,6 +72,8 @@
*
*/
+#define MCPCIA_MAX_HOSES 4
+
#define MCPCIA_MID(m) ((unsigned long)(m) << 33)
/* Dodge has PCI0 and PCI1 at MID 4 and 5 respectively.
diff --git a/include/asm-alpha/io.h b/include/asm-alpha/io.h
index 24bdcc8b63a..21a86f1a05b 100644
--- a/include/asm-alpha/io.h
+++ b/include/asm-alpha/io.h
@@ -113,6 +113,7 @@ static inline unsigned long virt_to_bus(void *address)
unsigned long bus = phys + __direct_map_base;
return phys <= __direct_map_size ? bus : 0;
}
+#define isa_virt_to_bus virt_to_bus
static inline void *bus_to_virt(unsigned long address)
{
diff --git a/include/asm-ia64/sn/pcibr_provider.h b/include/asm-ia64/sn/pcibr_provider.h
index 17cb6cc3f21..da205b7cdaa 100644
--- a/include/asm-ia64/sn/pcibr_provider.h
+++ b/include/asm-ia64/sn/pcibr_provider.h
@@ -21,6 +21,7 @@
#define IS_PCI_BRIDGE_ASIC(asic) (asic == PCIIO_ASIC_TYPE_PIC || \
asic == PCIIO_ASIC_TYPE_TIOCP)
#define IS_PIC_SOFT(ps) (ps->pbi_bridge_type == PCIBR_BRIDGETYPE_PIC)
+#define IS_TIOCP_SOFT(ps) (ps->pbi_bridge_type == PCIBR_BRIDGETYPE_TIOCP)
/*
@@ -53,8 +54,8 @@
* Bridge PMU Address Transaltion Entry Attibutes
*/
#define PCI32_ATE_V (0x1 << 0)
-#define PCI32_ATE_CO (0x1 << 1)
-#define PCI32_ATE_PREC (0x1 << 2)
+#define PCI32_ATE_CO (0x1 << 1) /* PIC ASIC ONLY */
+#define PCI32_ATE_PIO (0x1 << 1) /* TIOCP ASIC ONLY */
#define PCI32_ATE_MSI (0x1 << 2)
#define PCI32_ATE_PREF (0x1 << 3)
#define PCI32_ATE_BAR (0x1 << 4)
diff --git a/include/asm-mips/bug.h b/include/asm-mips/bug.h
index 4d560a53394..7eb63de808b 100644
--- a/include/asm-mips/bug.h
+++ b/include/asm-mips/bug.h
@@ -18,7 +18,8 @@ do { \
#define BUG_ON(condition) \
do { \
- __asm__ __volatile__("tne $0, %0" : : "r" (condition)); \
+ __asm__ __volatile__("tne $0, %0, %1" \
+ : : "r" (condition), "i" (BRK_BUG)); \
} while (0)
#define HAVE_ARCH_BUG_ON
diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h
index 20a81e1548f..290485ac540 100644
--- a/include/asm-mips/checksum.h
+++ b/include/asm-mips/checksum.h
@@ -166,7 +166,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr,
#else
"r" (proto + len),
#endif
- "r" (sum));
+ "r" ((__force unsigned long)sum));
return sum;
}
diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h
index 4e12d1f9534..b414a7d9db4 100644
--- a/include/asm-mips/fpu.h
+++ b/include/asm-mips/fpu.h
@@ -68,8 +68,6 @@ do { \
/* We don't care about the c0 hazard here */ \
} while (0)
-#define __fpu_enabled() (read_c0_status() & ST0_CU1)
-
#define enable_fpu() \
do { \
if (cpu_has_fpu) \
@@ -102,14 +100,19 @@ static inline void __own_fpu(void)
set_thread_flag(TIF_USEDFPU);
}
-static inline void own_fpu(int restore)
+static inline void own_fpu_inatomic(int restore)
{
- preempt_disable();
if (cpu_has_fpu && !__is_fpu_owner()) {
__own_fpu();
if (restore)
_restore_fp(current);
}
+}
+
+static inline void own_fpu(int restore)
+{
+ preempt_disable();
+ own_fpu_inatomic(restore);
preempt_enable();
}
@@ -162,18 +165,4 @@ static inline fpureg_t *get_fpu_regs(struct task_struct *tsk)
return tsk->thread.fpu.fpr;
}
-static inline void enable_fp_in_kernel(void)
-{
- set_thread_flag(TIF_ALLOW_FP_IN_KERNEL);
- /* make sure CU1 and FPU ownership are consistent */
- if (!__is_fpu_owner() && __fpu_enabled())
- __disable_fpu();
-}
-
-static inline void disable_fp_in_kernel(void)
-{
- BUG_ON(!__is_fpu_owner() && __fpu_enabled());
- clear_thread_flag(TIF_ALLOW_FP_IN_KERNEL);
-}
-
#endif /* _ASM_FPU_H */
diff --git a/include/asm-mips/sibyte/sb1250_scd.h b/include/asm-mips/sibyte/sb1250_scd.h
index 7ed0bb611e5..b6a7d8f6ced 100644
--- a/include/asm-mips/sibyte/sb1250_scd.h
+++ b/include/asm-mips/sibyte/sb1250_scd.h
@@ -84,6 +84,7 @@
#define K_SYS_REVISION_BCM112x_A2 0x21
#define K_SYS_REVISION_BCM112x_A3 0x22
#define K_SYS_REVISION_BCM112x_A4 0x23
+#define K_SYS_REVISION_BCM112x_B0 0x30
#define K_SYS_REVISION_BCM1480_S0 0x01
#define K_SYS_REVISION_BCM1480_A1 0x02
diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h
index 6cf05f4a4e7..fbcda820447 100644
--- a/include/asm-mips/thread_info.h
+++ b/include/asm-mips/thread_info.h
@@ -119,7 +119,6 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 18
#define TIF_FREEZE 19
-#define TIF_ALLOW_FP_IN_KERNEL 20
#define TIF_SYSCALL_TRACE 31 /* syscall trace active */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
diff --git a/include/asm-powerpc/systbl.h b/include/asm-powerpc/systbl.h
index 8d853c55463..0b00068313f 100644
--- a/include/asm-powerpc/systbl.h
+++ b/include/asm-powerpc/systbl.h
@@ -288,7 +288,7 @@ COMPAT_SYS(ppoll)
SYSCALL_SPU(unshare)
SYSCALL_SPU(splice)
SYSCALL_SPU(tee)
-SYSCALL_SPU(vmsplice)
+COMPAT_SYS_SPU(vmsplice)
COMPAT_SYS_SPU(openat)
SYSCALL_SPU(mkdirat)
SYSCALL_SPU(mknodat)
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 58564a19986..d3bbc7188b6 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -861,6 +861,8 @@ typedef struct hwgroup_s {
int (*expiry)(ide_drive_t *);
/* ide_system_bus_speed */
int pio_clock;
+ int req_gen;
+ int req_gen_timer;
unsigned char cmd_buf[4];
} ide_hwgroup_t;
diff --git a/include/linux/io.h b/include/linux/io.h
index c244a0cc931..09d35123637 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -33,9 +33,22 @@ int ioremap_page_range(unsigned long addr, unsigned long end,
/*
* Managed iomap interface
*/
+#ifdef CONFIG_HAS_IOPORT
void __iomem * devm_ioport_map(struct device *dev, unsigned long port,
unsigned int nr);
void devm_ioport_unmap(struct device *dev, void __iomem *addr);
+#else
+static inline void __iomem *devm_ioport_map(struct device *dev,
+ unsigned long port,
+ unsigned int nr)
+{
+ return NULL;
+}
+
+static inline void devm_ioport_unmap(struct device *dev, void __iomem *addr)
+{
+}
+#endif
void __iomem * devm_ioremap(struct device *dev, unsigned long offset,
unsigned long size);
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index f8241130f5e..713eb5eaa81 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -177,6 +177,7 @@ struct ipv6_devconf {
#endif
#endif
__s32 proxy_ndp;
+ __s32 accept_source_route;
void *sysctl;
};
@@ -205,6 +206,8 @@ enum {
DEVCONF_RTR_PROBE_INTERVAL,
DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
DEVCONF_PROXY_NDP,
+ __DEVCONF_OPTIMISTIC_DAD,
+ DEVCONF_ACCEPT_SOURCE_ROUTE,
DEVCONF_MAX
};
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 2e555d49c9b..16b0266b14f 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -31,7 +31,6 @@
#define PG_NEED_COMMIT 1
#define PG_NEED_RESCHED 2
#define PG_NEED_FLUSH 3
-#define PG_FLUSHING 4
struct nfs_inode;
struct nfs_page {
@@ -50,8 +49,6 @@ struct nfs_page {
};
#define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags))
-#define NFS_NEED_COMMIT(req) (test_bit(PG_NEED_COMMIT,&(req)->wb_flags))
-#define NFS_NEED_RESCHED(req) (test_bit(PG_NEED_RESCHED,&(req)->wb_flags))
extern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx,
struct inode *inode,
@@ -122,34 +119,6 @@ nfs_list_remove_request(struct nfs_page *req)
req->wb_list_head = NULL;
}
-static inline int
-nfs_defer_commit(struct nfs_page *req)
-{
- return !test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags);
-}
-
-static inline void
-nfs_clear_commit(struct nfs_page *req)
-{
- smp_mb__before_clear_bit();
- clear_bit(PG_NEED_COMMIT, &req->wb_flags);
- smp_mb__after_clear_bit();
-}
-
-static inline int
-nfs_defer_reschedule(struct nfs_page *req)
-{
- return !test_and_set_bit(PG_NEED_RESCHED, &req->wb_flags);
-}
-
-static inline void
-nfs_clear_reschedule(struct nfs_page *req)
-{
- smp_mb__before_clear_bit();
- clear_bit(PG_NEED_RESCHED, &req->wb_flags);
- smp_mb__after_clear_bit();
-}
-
static inline struct nfs_page *
nfs_list_entry(struct list_head *head)
{
diff --git a/include/linux/plist.h b/include/linux/plist.h
index b95818a037a..85de2f05587 100644
--- a/include/linux/plist.h
+++ b/include/linux/plist.h
@@ -97,9 +97,9 @@ struct plist_node {
#endif
/**
- * #PLIST_HEAD_INIT - static struct plist_head initializer
- *
+ * PLIST_HEAD_INIT - static struct plist_head initializer
* @head: struct plist_head variable name
+ * @_lock: lock to initialize for this list
*/
#define PLIST_HEAD_INIT(head, _lock) \
{ \
@@ -109,8 +109,7 @@ struct plist_node {
}
/**
- * #PLIST_NODE_INIT - static struct plist_node initializer
- *
+ * PLIST_NODE_INIT - static struct plist_node initializer
* @node: struct plist_node variable name
* @__prio: initial node priority
*/
@@ -122,8 +121,8 @@ struct plist_node {
/**
* plist_head_init - dynamic struct plist_head initializer
- *
* @head: &struct plist_head pointer
+ * @lock: list spinlock, remembered for debugging
*/
static inline void
plist_head_init(struct plist_head *head, spinlock_t *lock)
@@ -137,7 +136,6 @@ plist_head_init(struct plist_head *head, spinlock_t *lock)
/**
* plist_node_init - Dynamic struct plist_node initializer
- *
* @node: &struct plist_node pointer
* @prio: initial node priority
*/
@@ -152,49 +150,46 @@ extern void plist_del(struct plist_node *node, struct plist_head *head);
/**
* plist_for_each - iterate over the plist
- *
- * @pos1: the type * to use as a loop counter.
- * @head: the head for your list.
+ * @pos: the type * to use as a loop counter
+ * @head: the head for your list
*/
#define plist_for_each(pos, head) \
list_for_each_entry(pos, &(head)->node_list, plist.node_list)
/**
- * plist_for_each_entry_safe - iterate over a plist of given type safe
- * against removal of list entry
+ * plist_for_each_safe - iterate safely over a plist of given type
+ * @pos: the type * to use as a loop counter
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list
*
- * @pos1: the type * to use as a loop counter.
- * @n1: another type * to use as temporary storage
- * @head: the head for your list.
+ * Iterate over a plist of given type, safe against removal of list entry.
*/
#define plist_for_each_safe(pos, n, head) \
list_for_each_entry_safe(pos, n, &(head)->node_list, plist.node_list)
/**
* plist_for_each_entry - iterate over list of given type
- *
- * @pos: the type * to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
+ * @pos: the type * to use as a loop counter
+ * @head: the head for your list
+ * @mem: the name of the list_struct within the struct
*/
#define plist_for_each_entry(pos, head, mem) \
list_for_each_entry(pos, &(head)->node_list, mem.plist.node_list)
/**
- * plist_for_each_entry_safe - iterate over list of given type safe against
- * removal of list entry
- *
- * @pos: the type * to use as a loop counter.
+ * plist_for_each_entry_safe - iterate safely over list of given type
+ * @pos: the type * to use as a loop counter
* @n: another type * to use as temporary storage
- * @head: the head for your list.
- * @m: the name of the list_struct within the struct.
+ * @head: the head for your list
+ * @m: the name of the list_struct within the struct
+ *
+ * Iterate over list of given type, safe against removal of list entry.
*/
#define plist_for_each_entry_safe(pos, n, head, m) \
list_for_each_entry_safe(pos, n, &(head)->node_list, m.plist.node_list)
/**
* plist_head_empty - return !0 if a plist_head is empty
- *
* @head: &struct plist_head pointer
*/
static inline int plist_head_empty(const struct plist_head *head)
@@ -204,7 +199,6 @@ static inline int plist_head_empty(const struct plist_head *head)
/**
* plist_node_empty - return !0 if plist_node is not on a list
- *
* @node: &struct plist_node pointer
*/
static inline int plist_node_empty(const struct plist_node *node)
@@ -216,10 +210,9 @@ static inline int plist_node_empty(const struct plist_node *node)
/**
* plist_first_entry - get the struct for the first entry
- *
- * @ptr: the &struct plist_head pointer.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
+ * @head: the &struct plist_head pointer
+ * @type: the type of the struct this is embedded in
+ * @member: the name of the list_struct within the struct
*/
#ifdef CONFIG_DEBUG_PI_LIST
# define plist_first_entry(head, type, member) \
@@ -234,7 +227,6 @@ static inline int plist_node_empty(const struct plist_node *node)
/**
* plist_first - return the first node (and thus, highest priority)
- *
* @head: the &struct plist_head pointer
*
* Assumes the plist is _not_ empty.
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 82f43ad478c..5992f65b418 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -346,9 +346,6 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
return __alloc_skb(size, priority, 1, -1);
}
-extern struct sk_buff *alloc_skb_from_cache(struct kmem_cache *cp,
- unsigned int size,
- gfp_t priority);
extern void kfree_skbmem(struct sk_buff *skb);
extern struct sk_buff *skb_clone(struct sk_buff *skb,
gfp_t priority);
@@ -622,6 +619,13 @@ static inline void skb_queue_head_init(struct sk_buff_head *list)
list->qlen = 0;
}
+static inline void skb_queue_head_init_class(struct sk_buff_head *list,
+ struct lock_class_key *class)
+{
+ skb_queue_head_init(list);
+ lockdep_set_class(&list->lock, class);
+}
+
/*
* Insert an sk_buff at the start of a list.
*
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 2c5fb38d939..9a8970bf99a 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -580,6 +580,7 @@ enum {
NET_IPV6_RTR_PROBE_INTERVAL=21,
NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22,
NET_IPV6_PROXY_NDP=23,
+ NET_IPV6_ACCEPT_SOURCE_ROUTE=25,
__NET_IPV6_MAX
};
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h
index 3fced479825..a46104a28f6 100644
--- a/include/linux/taskstats.h
+++ b/include/linux/taskstats.h
@@ -31,7 +31,7 @@
*/
-#define TASKSTATS_VERSION 3
+#define TASKSTATS_VERSION 4
#define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN
* in linux/sched.h */
@@ -66,7 +66,7 @@ struct taskstats {
/* Delay waiting for cpu, while runnable
* count, delay_total NOT updated atomically
*/
- __u64 cpu_count;
+ __u64 cpu_count __attribute__((aligned(8)));
__u64 cpu_delay_total;
/* Following four fields atomically updated using task->delays->lock */
@@ -101,14 +101,17 @@ struct taskstats {
/* Basic Accounting Fields start */
char ac_comm[TS_COMM_LEN]; /* Command name */
- __u8 ac_sched; /* Scheduling discipline */
+ __u8 ac_sched __attribute__((aligned(8)));
+ /* Scheduling discipline */
__u8 ac_pad[3];
- __u32 ac_uid; /* User ID */
+ __u32 ac_uid __attribute__((aligned(8)));
+ /* User ID */
__u32 ac_gid; /* Group ID */
__u32 ac_pid; /* Process ID */
__u32 ac_ppid; /* Parent process ID */
__u32 ac_btime; /* Begin time [sec since 1970] */
- __u64 ac_etime; /* Elapsed time [usec] */
+ __u64 ac_etime __attribute__((aligned(8)));
+ /* Elapsed time [usec] */
__u64 ac_utime; /* User CPU time [usec] */
__u64 ac_stime; /* SYstem CPU time [usec] */
__u64 ac_minflt; /* Minor Page Fault Count */
diff --git a/kernel/params.c b/kernel/params.c
index e265b13195b..1fc4ac746cd 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -356,6 +356,10 @@ int param_set_copystring(const char *val, struct kernel_param *kp)
{
struct kparam_string *kps = kp->arg;
+ if (!val) {
+ printk(KERN_ERR "%s: missing param set value\n", kp->name);
+ return -EINVAL;
+ }
if (strlen(val)+1 > kps->maxlen) {
printk(KERN_ERR "%s: string doesn't fit in %u chars.\n",
kp->name, kps->maxlen-1);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 1b255df4fcd..c904748f229 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1676,7 +1676,7 @@ static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp,
{
int op;
- if (!capable(CAP_SYS_ADMIN))
+ if (write && !capable(CAP_SYS_ADMIN))
return -EPERM;
op = OP_OR;
diff --git a/mm/migrate.c b/mm/migrate.c
index 7a66ca25dc8..a91ca00abeb 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -297,7 +297,7 @@ static int migrate_page_move_mapping(struct address_space *mapping,
void **pslot;
if (!mapping) {
- /* Anonymous page */
+ /* Anonymous page without mapping */
if (page_count(page) != 1)
return -EAGAIN;
return 0;
@@ -333,6 +333,19 @@ static int migrate_page_move_mapping(struct address_space *mapping,
*/
__put_page(page);
+ /*
+ * If moved to a different zone then also account
+ * the page for that zone. Other VM counters will be
+ * taken care of when we establish references to the
+ * new page and drop references to the old page.
+ *
+ * Note that anonymous pages are accounted for
+ * via NR_FILE_PAGES and NR_ANON_PAGES if they
+ * are mapped to swap space.
+ */
+ __dec_zone_page_state(page, NR_FILE_PAGES);
+ __inc_zone_page_state(newpage, NR_FILE_PAGES);
+
write_unlock_irq(&mapping->tree_lock);
return 0;
diff --git a/mm/nommu.c b/mm/nommu.c
index cbbc1377481..1f60194d9b9 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -45,6 +45,7 @@ int heap_stack_gap = 0;
EXPORT_SYMBOL(mem_map);
EXPORT_SYMBOL(__vm_enough_memory);
+EXPORT_SYMBOL(num_physpages);
/* list of shareable VMAs */
struct rb_root nommu_vma_tree = RB_ROOT;
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 2f3916986ab..3791edfffee 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -176,6 +176,8 @@ static inline int constrained_alloc(struct zonelist *zonelist, gfp_t gfp_mask)
struct zone **z;
nodemask_t nodes;
int node;
+
+ nodes_clear(nodes);
/* node has memory ? */
for_each_online_node(node)
if (NODE_DATA(node)->node_present_pages)
@@ -333,7 +335,7 @@ static int oom_kill_task(struct task_struct *p)
*/
do_each_thread(g, q) {
if (q->mm == mm && q->tgid != p->tgid)
- force_sig(SIGKILL, p);
+ force_sig(SIGKILL, q);
} while_each_thread(g, q);
return 0;
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 2fc8fe2cb36..b6e0eea1e39 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -380,6 +380,9 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
} else {
vhdr->h_vlan_encapsulated_proto = htons(len);
}
+
+ skb->protocol = htons(ETH_P_8021Q);
+ skb->nh.raw = skb->data;
}
/* Before delegating work to the lower layer, enter our MAC-address */
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 58d13f2bd12..a285897a2fb 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -126,7 +126,9 @@ void br_stp_disable_port(struct net_bridge_port *p)
/* called under bridge lock */
void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr)
{
- unsigned char oldaddr[6];
+ /* should be aligned on 2 bytes for compare_ether_addr() */
+ unsigned short oldaddr_aligned[ETH_ALEN >> 1];
+ unsigned char *oldaddr = (unsigned char *)oldaddr_aligned;
struct net_bridge_port *p;
int wasroot;
@@ -151,11 +153,14 @@ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr)
br_become_root_bridge(br);
}
-static const unsigned char br_mac_zero[6];
+/* should be aligned on 2 bytes for compare_ether_addr() */
+static const unsigned short br_mac_zero_aligned[ETH_ALEN >> 1];
/* called under bridge lock */
void br_stp_recalculate_bridge_id(struct net_bridge *br)
{
+ const unsigned char *br_mac_zero =
+ (const unsigned char *)br_mac_zero_aligned;
const unsigned char *addr = br_mac_zero;
struct net_bridge_port *p;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index cfc60019cf9..841e3f32cab 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1331,6 +1331,8 @@ void neigh_parms_destroy(struct neigh_parms *parms)
kfree(parms);
}
+static struct lock_class_key neigh_table_proxy_queue_class;
+
void neigh_table_init_no_netlink(struct neigh_table *tbl)
{
unsigned long now = jiffies;
@@ -1379,7 +1381,8 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
init_timer(&tbl->proxy_timer);
tbl->proxy_timer.data = (unsigned long)tbl;
tbl->proxy_timer.function = neigh_proxy_process;
- skb_queue_head_init(&tbl->proxy_queue);
+ skb_queue_head_init_class(&tbl->proxy_queue,
+ &neigh_table_proxy_queue_class);
tbl->last_flush = now;
tbl->last_rand = now + tbl->parms.reachable_time * 20;
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index da1019451cc..4581ece48bb 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -471,6 +471,13 @@ int __netpoll_rx(struct sk_buff *skb)
if (skb->len < len || len < iph->ihl*4)
goto out;
+ /*
+ * Our transport medium may have padded the buffer out.
+ * Now We trim to the true length of the frame.
+ */
+ if (pskb_trim_rcsum(skb, len))
+ goto out;
+
if (iph->protocol != IPPROTO_UDP)
goto out;
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 74a9a32b906..4b01496dc33 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -129,6 +129,7 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/capability.h>
+#include <linux/freezer.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/list.h>
@@ -3333,6 +3334,8 @@ static int pktgen_thread_worker(void *arg)
t->control &= ~(T_REMDEV);
}
+ try_to_freeze();
+
set_current_state(TASK_INTERRUPTIBLE);
}
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 87573ae35b0..336958fbbcb 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -197,61 +197,6 @@ nodata:
}
/**
- * alloc_skb_from_cache - allocate a network buffer
- * @cp: kmem_cache from which to allocate the data area
- * (object size must be big enough for @size bytes + skb overheads)
- * @size: size to allocate
- * @gfp_mask: allocation mask
- *
- * Allocate a new &sk_buff. The returned buffer has no headroom and
- * tail room of size bytes. The object has a reference count of one.
- * The return is the buffer. On a failure the return is %NULL.
- *
- * Buffers may only be allocated from interrupts using a @gfp_mask of
- * %GFP_ATOMIC.
- */
-struct sk_buff *alloc_skb_from_cache(struct kmem_cache *cp,
- unsigned int size,
- gfp_t gfp_mask)
-{
- struct sk_buff *skb;
- u8 *data;
-
- /* Get the HEAD */
- skb = kmem_cache_alloc(skbuff_head_cache,
- gfp_mask & ~__GFP_DMA);
- if (!skb)
- goto out;
-
- /* Get the DATA. */
- size = SKB_DATA_ALIGN(size);
- data = kmem_cache_alloc(cp, gfp_mask);
- if (!data)
- goto nodata;
-
- memset(skb, 0, offsetof(struct sk_buff, truesize));
- skb->truesize = size + sizeof(struct sk_buff);
- atomic_set(&skb->users, 1);
- skb->head = data;
- skb->data = data;
- skb->tail = data;
- skb->end = data + size;
-
- atomic_set(&(skb_shinfo(skb)->dataref), 1);
- skb_shinfo(skb)->nr_frags = 0;
- skb_shinfo(skb)->gso_size = 0;
- skb_shinfo(skb)->gso_segs = 0;
- skb_shinfo(skb)->gso_type = 0;
- skb_shinfo(skb)->frag_list = NULL;
-out:
- return skb;
-nodata:
- kmem_cache_free(skbuff_head_cache, skb);
- skb = NULL;
- goto out;
-}
-
-/**
* __netdev_alloc_skb - allocate an skbuff for rx on a specific device
* @dev: network device to receive on
* @length: length to allocate
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index fc920f63452..cac06c43f00 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -776,6 +776,8 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
.nl_u = { .ip4_u = { .daddr = frn->fl_addr,
.tos = frn->fl_tos,
.scope = frn->fl_scope } } };
+
+ frn->err = -ENOENT;
if (tb) {
local_bh_disable();
@@ -787,6 +789,7 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
frn->nh_sel = res.nh_sel;
frn->type = res.type;
frn->scope = res.scope;
+ fib_res_put(&res);
}
local_bh_enable();
}
@@ -801,6 +804,9 @@ static void nl_fib_input(struct sock *sk, int len)
struct fib_table *tb;
skb = skb_dequeue(&sk->sk_receive_queue);
+ if (skb == NULL)
+ return;
+
nlh = (struct nlmsghdr *)skb->data;
if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len ||
nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) {
@@ -813,7 +819,7 @@ static void nl_fib_input(struct sock *sk, int len)
nl_fib_lookup(frn, tb);
- pid = nlh->nlmsg_pid; /*pid of sending process */
+ pid = NETLINK_CB(skb).pid; /* pid of sending process */
NETLINK_CB(skb).pid = 0; /* from kernel */
NETLINK_CB(skb).dst_group = 0; /* unicast */
netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 5170f5c75f9..57b0221f9e2 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -166,13 +166,9 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
return 0;
}
- for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
- unsigned long odev;
- memcpy(&odev, outdev + i*sizeof(unsigned long),
- sizeof(unsigned long));
- ret |= (odev
- ^ ((const unsigned long *)arpinfo->outiface)[i])
- & ((const unsigned long *)arpinfo->outiface_mask)[i];
+ for (i = 0, ret = 0; i < IFNAMSIZ; i++) {
+ ret |= (outdev[i] ^ arpinfo->outiface[i])
+ & arpinfo->outiface_mask[i];
}
if (FWINV(ret != 0, ARPT_INV_VIA_OUT)) {
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index e965b333c99..42b08029e86 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -411,12 +411,10 @@ checkentry(const char *tablename,
"has invalid config pointer!\n");
return 0;
}
- clusterip_config_entry_get(cipinfo->config);
} else {
/* Case B: This is a new rule referring to an existing
* clusterip config. */
cipinfo->config = config;
- clusterip_config_entry_get(cipinfo->config);
}
} else {
/* Case C: This is a completely new clusterip config */
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index a26404dbe21..9acc018766f 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -61,6 +61,7 @@
#include <linux/netfilter_ipv4/ipt_ULOG.h>
#include <net/sock.h>
#include <linux/bitops.h>
+#include <asm/unaligned.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
@@ -236,9 +237,9 @@ static void ipt_ulog_packet(unsigned int hooknum,
/* copy hook, prefix, timestamp, payload, etc. */
pm->data_len = copy_len;
- pm->timestamp_sec = skb->tstamp.off_sec;
- pm->timestamp_usec = skb->tstamp.off_usec;
- pm->mark = skb->mark;
+ put_unaligned(skb->tstamp.off_sec, &pm->timestamp_sec);
+ put_unaligned(skb->tstamp.off_usec, &pm->timestamp_usec);
+ put_unaligned(skb->mark, &pm->mark);
pm->hook = hooknum;
if (prefix != NULL)
strncpy(pm->prefix, prefix, sizeof(pm->prefix));
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 5c8caf4a124..34ae3f13483 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -77,18 +77,19 @@ void tcp_init_congestion_control(struct sock *sk)
struct inet_connection_sock *icsk = inet_csk(sk);
struct tcp_congestion_ops *ca;
- if (icsk->icsk_ca_ops != &tcp_init_congestion_ops)
- return;
+ /* if no choice made yet assign the current value set as default */
+ if (icsk->icsk_ca_ops == &tcp_init_congestion_ops) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
+ if (try_module_get(ca->owner)) {
+ icsk->icsk_ca_ops = ca;
+ break;
+ }
- rcu_read_lock();
- list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
- if (try_module_get(ca->owner)) {
- icsk->icsk_ca_ops = ca;
- break;
+ /* fallback to next available */
}
-
+ rcu_read_unlock();
}
- rcu_read_unlock();
if (icsk->icsk_ca_ops->init)
icsk->icsk_ca_ops->init(sk);
@@ -236,6 +237,7 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
rcu_read_lock();
ca = tcp_ca_find(name);
+
/* no change asking for existing value */
if (ca == icsk->icsk_ca_ops)
goto out;
@@ -261,7 +263,8 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
else {
tcp_cleanup_congestion_control(sk);
icsk->icsk_ca_ops = ca;
- if (icsk->icsk_ca_ops->init)
+
+ if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init)
icsk->icsk_ca_ops->init(sk);
}
out:
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 688b95594f2..3c24881f2a6 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -943,7 +943,8 @@ static void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
if (tp->packets_out > tp->snd_cwnd_used)
tp->snd_cwnd_used = tp->packets_out;
- if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= inet_csk(sk)->icsk_rto)
+ if (sysctl_tcp_slow_start_after_idle &&
+ (s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= inet_csk(sk)->icsk_rto)
tcp_cwnd_application_limited(sk);
}
}
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index f68dfd8a0f5..d419e15d980 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -52,7 +52,7 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
ph = (struct ip_beet_phdr *)skb->h.raw;
ph->padlen = 4 - (optlen & 4);
- ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8;
+ ph->hdrlen = optlen / 8;
ph->nexthdr = top_iph->protocol;
if (ph->padlen)
memset(ph + 1, IPOPT_NOP, ph->padlen);
@@ -85,7 +85,7 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
ph = (struct ip_beet_phdr *)(skb->h.ipiph + 1);
phlen = sizeof(*ph) + ph->padlen;
- optlen = ph->hdrlen * 8 - phlen;
+ optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen);
if (optlen < 0 || optlen & 3 || optlen > 250)
goto out;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7552663aa12..452a82ce479 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -172,6 +172,7 @@ struct ipv6_devconf ipv6_devconf __read_mostly = {
#endif
#endif
.proxy_ndp = 0,
+ .accept_source_route = 0, /* we do not accept RH0 by default. */
};
static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -203,6 +204,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
#endif
#endif
.proxy_ndp = 0,
+ .accept_source_route = 0, /* we do not accept RH0 by default. */
};
/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
@@ -3356,6 +3358,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
#endif
#endif
array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
+ array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route;
}
static inline size_t inet6_if_nlmsg_size(void)
@@ -3884,6 +3887,14 @@ static struct addrconf_sysctl_table
.proc_handler = &proc_dointvec,
},
{
+ .ctl_name = NET_IPV6_ACCEPT_SOURCE_ROUTE,
+ .procname = "accept_source_route",
+ .data = &ipv6_devconf.accept_source_route,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
.ctl_name = 0, /* sentinel */
}
},
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 28e0c656827..fb39604c3d0 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -362,10 +362,27 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
struct inet6_skb_parm *opt = IP6CB(skb);
struct in6_addr *addr = NULL;
struct in6_addr daddr;
+ struct inet6_dev *idev;
int n, i;
-
struct ipv6_rt_hdr *hdr;
struct rt0_hdr *rthdr;
+ int accept_source_route = ipv6_devconf.accept_source_route;
+
+ if (accept_source_route < 0 ||
+ ((idev = in6_dev_get(skb->dev)) == NULL)) {
+ kfree_skb(skb);
+ return -1;
+ }
+ if (idev->cnf.accept_source_route < 0) {
+ in6_dev_put(idev);
+ kfree_skb(skb);
+ return -1;
+ }
+
+ if (accept_source_route > idev->cnf.accept_source_route)
+ accept_source_route = idev->cnf.accept_source_route;
+
+ in6_dev_put(idev);
if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
!pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
@@ -377,6 +394,22 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
hdr = (struct ipv6_rt_hdr *) skb->h.raw;
+ switch (hdr->type) {
+#ifdef CONFIG_IPV6_MIP6
+ break;
+#endif
+ case IPV6_SRCRT_TYPE_0:
+ if (accept_source_route > 0)
+ break;
+ kfree_skb(skb);
+ return -1;
+ default:
+ IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
+ IPSTATS_MIB_INHDRERRORS);
+ icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
+ return -1;
+ }
+
if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
skb->pkt_type != PACKET_HOST) {
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
@@ -434,11 +467,6 @@ looped_back:
}
break;
#endif
- default:
- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
- IPSTATS_MIB_INHDRERRORS);
- icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
- return -1;
}
/*
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index ad9b285692b..aebb4e2d5ae 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1766,13 +1766,22 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
* Drop the packet on the floor
*/
-static inline int ip6_pkt_drop(struct sk_buff *skb, int code)
-{
- int type = ipv6_addr_type(&skb->nh.ipv6h->daddr);
- if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED)
- IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS);
-
- IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTNOROUTES);
+static inline int ip6_pkt_drop(struct sk_buff *skb, int code,
+ int ipstats_mib_noroutes)
+{
+ int type;
+ switch (ipstats_mib_noroutes) {
+ case IPSTATS_MIB_INNOROUTES:
+ type = ipv6_addr_type(&skb->nh.ipv6h->daddr);
+ if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) {
+ IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS);
+ break;
+ }
+ /* FALLTHROUGH */
+ case IPSTATS_MIB_OUTNOROUTES:
+ IP6_INC_STATS(ip6_dst_idev(skb->dst), ipstats_mib_noroutes);
+ break;
+ }
icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev);
kfree_skb(skb);
return 0;
@@ -1780,26 +1789,26 @@ static inline int ip6_pkt_drop(struct sk_buff *skb, int code)
static int ip6_pkt_discard(struct sk_buff *skb)
{
- return ip6_pkt_drop(skb, ICMPV6_NOROUTE);
+ return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES);
}
static int ip6_pkt_discard_out(struct sk_buff *skb)
{
skb->dev = skb->dst->dev;
- return ip6_pkt_discard(skb);
+ return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES);
}
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
static int ip6_pkt_prohibit(struct sk_buff *skb)
{
- return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED);
+ return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES);
}
static int ip6_pkt_prohibit_out(struct sk_buff *skb)
{
skb->dev = skb->dst->dev;
- return ip6_pkt_prohibit(skb);
+ return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
}
static int ip6_pkt_blk_hole(struct sk_buff *skb)
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index eabd6838f50..0eb7d596d47 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -138,7 +138,6 @@ static void irda_disconnect_indication(void *instance, void *sap,
sk->sk_shutdown |= SEND_SHUTDOWN;
sk->sk_state_change(sk);
- sock_orphan(sk);
release_sock(sk);
/* Close our TSAP.
@@ -1446,7 +1445,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
*/
ret = sock_error(sk);
if (ret)
- break;
+ ;
else if (sk->sk_shutdown & RCV_SHUTDOWN)
;
else if (noblock)
diff --git a/net/key/af_key.c b/net/key/af_key.c
index a4e7e2db0ff..345019345f0 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -630,6 +630,35 @@ pfkey_sockaddr_size(sa_family_t family)
/* NOTREACHED */
}
+static inline int pfkey_mode_from_xfrm(int mode)
+{
+ switch(mode) {
+ case XFRM_MODE_TRANSPORT:
+ return IPSEC_MODE_TRANSPORT;
+ case XFRM_MODE_TUNNEL:
+ return IPSEC_MODE_TUNNEL;
+ case XFRM_MODE_BEET:
+ return IPSEC_MODE_BEET;
+ default:
+ return -1;
+ }
+}
+
+static inline int pfkey_mode_to_xfrm(int mode)
+{
+ switch(mode) {
+ case IPSEC_MODE_ANY: /*XXX*/
+ case IPSEC_MODE_TRANSPORT:
+ return XFRM_MODE_TRANSPORT;
+ case IPSEC_MODE_TUNNEL:
+ return XFRM_MODE_TUNNEL;
+ case IPSEC_MODE_BEET:
+ return XFRM_MODE_BEET;
+ default:
+ return -1;
+ }
+}
+
static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, int hsc)
{
struct sk_buff *skb;
@@ -651,6 +680,7 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
int encrypt_key_size = 0;
int sockaddr_size;
struct xfrm_encap_tmpl *natt = NULL;
+ int mode;
/* address family check */
sockaddr_size = pfkey_sockaddr_size(x->props.family);
@@ -928,7 +958,11 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
sa2 = (struct sadb_x_sa2 *) skb_put(skb, sizeof(struct sadb_x_sa2));
sa2->sadb_x_sa2_len = sizeof(struct sadb_x_sa2)/sizeof(uint64_t);
sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- sa2->sadb_x_sa2_mode = x->props.mode + 1;
+ if ((mode = pfkey_mode_from_xfrm(x->props.mode)) < 0) {
+ kfree_skb(skb);
+ return ERR_PTR(-EINVAL);
+ }
+ sa2->sadb_x_sa2_mode = mode;
sa2->sadb_x_sa2_reserved1 = 0;
sa2->sadb_x_sa2_reserved2 = 0;
sa2->sadb_x_sa2_sequence = 0;
@@ -1155,9 +1189,12 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
if (ext_hdrs[SADB_X_EXT_SA2-1]) {
struct sadb_x_sa2 *sa2 = (void*)ext_hdrs[SADB_X_EXT_SA2-1];
- x->props.mode = sa2->sadb_x_sa2_mode;
- if (x->props.mode)
- x->props.mode--;
+ int mode = pfkey_mode_to_xfrm(sa2->sadb_x_sa2_mode);
+ if (mode < 0) {
+ err = -EINVAL;
+ goto out;
+ }
+ x->props.mode = mode;
x->props.reqid = sa2->sadb_x_sa2_reqid;
}
@@ -1218,7 +1255,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
struct sadb_address *saddr, *daddr;
struct sadb_msg *out_hdr;
struct xfrm_state *x = NULL;
- u8 mode;
+ int mode;
u32 reqid;
u8 proto;
unsigned short family;
@@ -1233,7 +1270,9 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
return -EINVAL;
if ((sa2 = ext_hdrs[SADB_X_EXT_SA2-1]) != NULL) {
- mode = sa2->sadb_x_sa2_mode - 1;
+ mode = pfkey_mode_to_xfrm(sa2->sadb_x_sa2_mode);
+ if (mode < 0)
+ return -EINVAL;
reqid = sa2->sadb_x_sa2_reqid;
} else {
mode = 0;
@@ -1756,6 +1795,7 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct sockaddr_in6 *sin6;
#endif
+ int mode;
if (xp->xfrm_nr >= XFRM_MAX_DEPTH)
return -ELOOP;
@@ -1764,7 +1804,9 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
return -EINVAL;
t->id.proto = rq->sadb_x_ipsecrequest_proto; /* XXX check proto */
- t->mode = rq->sadb_x_ipsecrequest_mode-1;
+ if ((mode = pfkey_mode_to_xfrm(rq->sadb_x_ipsecrequest_mode)) < 0)
+ return -EINVAL;
+ t->mode = mode;
if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE)
t->optional = 1;
else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) {
@@ -1877,7 +1919,7 @@ static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp)
return skb;
}
-static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, int dir)
+static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, int dir)
{
struct sadb_msg *hdr;
struct sadb_address *addr;
@@ -2014,6 +2056,7 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
struct sadb_x_ipsecrequest *rq;
struct xfrm_tmpl *t = xp->xfrm_vec + i;
int req_size;
+ int mode;
req_size = sizeof(struct sadb_x_ipsecrequest);
if (t->mode == XFRM_MODE_TUNNEL)
@@ -2027,7 +2070,9 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
memset(rq, 0, sizeof(*rq));
rq->sadb_x_ipsecrequest_len = req_size;
rq->sadb_x_ipsecrequest_proto = t->id.proto;
- rq->sadb_x_ipsecrequest_mode = t->mode+1;
+ if ((mode = pfkey_mode_from_xfrm(t->mode)) < 0)
+ return -EINVAL;
+ rq->sadb_x_ipsecrequest_mode = mode;
rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
if (t->reqid)
rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE;
@@ -2089,6 +2134,8 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
hdr->sadb_msg_len = size / sizeof(uint64_t);
hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
+
+ return 0;
}
static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c)
@@ -2102,7 +2149,9 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c
err = PTR_ERR(out_skb);
goto out;
}
- pfkey_xfrm_policy2msg(out_skb, xp, dir);
+ err = pfkey_xfrm_policy2msg(out_skb, xp, dir);
+ if (err < 0)
+ return err;
out_hdr = (struct sadb_msg *) out_skb->data;
out_hdr->sadb_msg_version = PF_KEY_V2;
@@ -2327,7 +2376,9 @@ static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, struct sadb
err = PTR_ERR(out_skb);
goto out;
}
- pfkey_xfrm_policy2msg(out_skb, xp, dir);
+ err = pfkey_xfrm_policy2msg(out_skb, xp, dir);
+ if (err < 0)
+ goto out;
out_hdr = (struct sadb_msg *) out_skb->data;
out_hdr->sadb_msg_version = hdr->sadb_msg_version;
@@ -2409,6 +2460,7 @@ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len,
{
int err;
struct sadb_x_ipsecrequest *rq2;
+ int mode;
if (len <= sizeof(struct sadb_x_ipsecrequest) ||
len < rq1->sadb_x_ipsecrequest_len)
@@ -2439,7 +2491,9 @@ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len,
return -EINVAL;
m->proto = rq1->sadb_x_ipsecrequest_proto;
- m->mode = rq1->sadb_x_ipsecrequest_mode - 1;
+ if ((mode = pfkey_mode_to_xfrm(rq1->sadb_x_ipsecrequest_mode)) < 0)
+ return -EINVAL;
+ m->mode = mode;
m->reqid = rq1->sadb_x_ipsecrequest_reqid;
return ((int)(rq1->sadb_x_ipsecrequest_len +
@@ -2579,12 +2633,15 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
struct pfkey_dump_data *data = ptr;
struct sk_buff *out_skb;
struct sadb_msg *out_hdr;
+ int err;
out_skb = pfkey_xfrm_policy2msg_prep(xp);
if (IS_ERR(out_skb))
return PTR_ERR(out_skb);
- pfkey_xfrm_policy2msg(out_skb, xp, dir);
+ err = pfkey_xfrm_policy2msg(out_skb, xp, dir);
+ if (err < 0)
+ return err;
out_hdr = (struct sadb_msg *) out_skb->data;
out_hdr->sadb_msg_version = data->hdr->sadb_msg_version;
@@ -3513,7 +3570,10 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
for (i = 0, mp = m; i < num_bundles; i++, mp++) {
/* old ipsecrequest */
- if (set_ipsecrequest(skb, mp->proto, mp->mode + 1,
+ int mode = pfkey_mode_from_xfrm(mp->mode);
+ if (mode < 0)
+ return -EINVAL;
+ if (set_ipsecrequest(skb, mp->proto, mode,
(mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE),
mp->reqid, mp->old_family,
&mp->old_saddr, &mp->old_daddr) < 0) {
@@ -3521,7 +3581,7 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
}
/* new ipsecrequest */
- if (set_ipsecrequest(skb, mp->proto, mp->mode + 1,
+ if (set_ipsecrequest(skb, mp->proto, mode,
(mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE),
mp->reqid, mp->new_family,
&mp->new_saddr, &mp->new_daddr) < 0) {
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index e73d8f546c6..c48b0f49f00 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -443,6 +443,7 @@ static int netlink_release(struct socket *sock)
return 0;
netlink_remove(sk);
+ sock_orphan(sk);
nlk = nlk_sk(sk);
spin_lock(&nlk->cb_lock);
@@ -457,7 +458,6 @@ static int netlink_release(struct socket *sock)
/* OK. Socket is unlinked, and, therefore,
no new packets will arrive */
- sock_orphan(sk);
sock->sk = NULL;
wake_up_interruptible_all(&nlk->wait);
@@ -1412,9 +1412,9 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
return -ECONNREFUSED;
}
nlk = nlk_sk(sk);
- /* A dump is in progress... */
+ /* A dump or destruction is in progress... */
spin_lock(&nlk->cb_lock);
- if (nlk->cb) {
+ if (nlk->cb || sock_flag(sk, SOCK_DEAD)) {
spin_unlock(&nlk->cb_lock);
netlink_destroy_callback(cb);
sock_put(sk);
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 040e2d2d281..7563fdcef4b 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -245,9 +245,9 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
}
if (tb[TCA_TCINDEX_SHIFT-1]) {
- if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT-1]) < sizeof(u16))
+ if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT-1]) < sizeof(int))
goto errout;
- cp.shift = *(u16 *) RTA_DATA(tb[TCA_TCINDEX_SHIFT-1]);
+ cp.shift = *(int *) RTA_DATA(tb[TCA_TCINDEX_SHIFT-1]);
}
err = -EBUSY;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 536298c2eda..a1d026f12b0 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -627,6 +627,12 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
retval = -EINVAL;
goto err_bindx_rem;
}
+
+ if (!af->addr_valid(sa_addr, sp, NULL)) {
+ retval = -EADDRNOTAVAIL;
+ goto err_bindx_rem;
+ }
+
if (sa_addr->v4.sin_port != htons(bp->port)) {
retval = -EINVAL;
goto err_bindx_rem;
@@ -5638,6 +5644,36 @@ void sctp_wait_for_close(struct sock *sk, long timeout)
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. */
+ for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next)
+ 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;
+
+ if (!skb->data_len)
+ goto done;
+
+ /* Don't forget the fragments. */
+ for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next)
+ sctp_skb_set_owner_r_frag(frag, sk);
+
+done:
+ sctp_skb_set_owner_r(skb, sk);
+}
+
/* Populate the fields of the newsk from the oldsk and migrate the assoc
* and its messages to the newsk.
*/
@@ -5692,10 +5728,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) {
event = sctp_skb2event(skb);
if (event->asoc == assoc) {
- sctp_sock_rfree(skb);
+ 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(skb, newsk);
+ sctp_skb_set_owner_r_frag(skb, newsk);
}
}
@@ -5723,10 +5759,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
event = sctp_skb2event(skb);
if (event->asoc == assoc) {
- sctp_sock_rfree(skb);
+ sctp_sock_rfree_frag(skb);
__skb_unlink(skb, &oldsp->pd_lobby);
__skb_queue_tail(queue, skb);
- sctp_skb_set_owner_r(skb, newsk);
+ sctp_skb_set_owner_r_frag(skb, newsk);
}
}
@@ -5738,6 +5774,16 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
}
+ sctp_skb_for_each(skb, &assoc->ulpq.reasm, tmp) {
+ sctp_sock_rfree_frag(skb);
+ sctp_skb_set_owner_r_frag(skb, newsk);
+ }
+
+ sctp_skb_for_each(skb, &assoc->ulpq.lobby, tmp) {
+ sctp_sock_rfree_frag(skb);
+ 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
* TCP-style socket..
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index bfb197e37da..b29e3e4b72c 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -190,7 +190,14 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event)
if (!sctp_sk(sk)->pd_mode) {
queue = &sk->sk_receive_queue;
} else if (ulpq->pd_mode) {
- if (event->msg_flags & MSG_NOTIFICATION)
+ /* If the association is in partial delivery, we
+ * need to finish delivering the partially processed
+ * packet before passing any other data. This is
+ * because we don't truly support stream interleaving.
+ */
+ if ((event->msg_flags & MSG_NOTIFICATION) ||
+ (SCTP_DATA_NOT_FRAG ==
+ (event->msg_flags & SCTP_DATA_FRAG_MASK)))
queue = &sctp_sk(sk)->pd_lobby;
else {
clear_pd = event->msg_flags & MSG_EOR;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 6d7221fe990..396cdbe249d 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1046,6 +1046,8 @@ call_status(struct rpc_task *task)
rpc_delay(task, 3*HZ);
case -ETIMEDOUT:
task->tk_action = call_timeout;
+ if (task->tk_client->cl_discrtry)
+ xprt_disconnect(task->tk_xprt);
break;
case -ECONNREFUSED:
case -ENOTCONN:
@@ -1169,6 +1171,8 @@ call_decode(struct rpc_task *task)
out_retry:
req->rq_received = req->rq_private_buf.len = 0;
task->tk_status = 0;
+ if (task->tk_client->cl_discrtry)
+ xprt_disconnect(task->tk_xprt);
}
/*
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 9bae4090254..2bd23ea2aa8 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -383,7 +383,10 @@ void svcauth_unix_purge(void)
static inline struct ip_map *
ip_map_cached_get(struct svc_rqst *rqstp)
{
- struct ip_map *ipm = rqstp->rq_sock->sk_info_authunix;
+ struct ip_map *ipm;
+ struct svc_sock *svsk = rqstp->rq_sock;
+ spin_lock_bh(&svsk->sk_defer_lock);
+ ipm = svsk->sk_info_authunix;
if (ipm != NULL) {
if (!cache_valid(&ipm->h)) {
/*
@@ -391,12 +394,14 @@ ip_map_cached_get(struct svc_rqst *rqstp)
* remembered, e.g. by a second mount from the
* same IP address.
*/
- rqstp->rq_sock->sk_info_authunix = NULL;
+ svsk->sk_info_authunix = NULL;
+ spin_unlock_bh(&svsk->sk_defer_lock);
cache_put(&ipm->h, &ip_map_cache);
return NULL;
}
cache_get(&ipm->h);
}
+ spin_unlock_bh(&svsk->sk_defer_lock);
return ipm;
}
@@ -405,9 +410,15 @@ ip_map_cached_put(struct svc_rqst *rqstp, struct ip_map *ipm)
{
struct svc_sock *svsk = rqstp->rq_sock;
- if (svsk->sk_sock->type == SOCK_STREAM && svsk->sk_info_authunix == NULL)
- svsk->sk_info_authunix = ipm; /* newly cached, keep the reference */
- else
+ spin_lock_bh(&svsk->sk_defer_lock);
+ if (svsk->sk_sock->type == SOCK_STREAM &&
+ svsk->sk_info_authunix == NULL) {
+ /* newly cached, keep the reference */
+ svsk->sk_info_authunix = ipm;
+ ipm = NULL;
+ }
+ spin_unlock_bh(&svsk->sk_defer_lock);
+ if (ipm)
cache_put(&ipm->h, &ip_map_cache);
}
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 593f62ff852..2772fee9388 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -452,6 +452,8 @@ union svc_pktinfo_u {
struct in_pktinfo pkti;
struct in6_pktinfo pkti6;
};
+#define SVC_PKTINFO_SPACE \
+ CMSG_SPACE(sizeof(union svc_pktinfo_u))
static void svc_set_cmsg_data(struct svc_rqst *rqstp, struct cmsghdr *cmh)
{
@@ -491,8 +493,11 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr)
struct svc_sock *svsk = rqstp->rq_sock;
struct socket *sock = svsk->sk_sock;
int slen;
- char buffer[CMSG_SPACE(sizeof(union svc_pktinfo_u))];
- struct cmsghdr *cmh = (struct cmsghdr *)buffer;
+ union {
+ struct cmsghdr hdr;
+ long all[SVC_PKTINFO_SPACE / sizeof(long)];
+ } buffer;
+ struct cmsghdr *cmh = &buffer.hdr;
int len = 0;
int result;
int size;
@@ -745,8 +750,11 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
struct svc_sock *svsk = rqstp->rq_sock;
struct svc_serv *serv = svsk->sk_server;
struct sk_buff *skb;
- char buffer[CMSG_SPACE(sizeof(union svc_pktinfo_u))];
- struct cmsghdr *cmh = (struct cmsghdr *)buffer;
+ union {
+ struct cmsghdr hdr;
+ long all[SVC_PKTINFO_SPACE / sizeof(long)];
+ } buffer;
+ struct cmsghdr *cmh = &buffer.hdr;
int err, len;
struct msghdr msg = {
.msg_name = svc_addr(rqstp),
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index ee6ffa01dfb..456a1451030 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -735,16 +735,6 @@ void xprt_transmit(struct rpc_task *task)
xprt_reset_majortimeo(req);
/* Turn off autodisconnect */
del_singleshot_timer_sync(&xprt->timer);
- } else {
- /* If all request bytes have been sent,
- * then we must be retransmitting this one */
- if (!req->rq_bytes_sent) {
- if (task->tk_client->cl_discrtry) {
- xprt_disconnect(xprt);
- task->tk_status = -ENOTCONN;
- return;
- }
- }
}
} else if (!req->rq_bytes_sent)
return;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index e81e2fb3d42..816e3690b60 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -272,9 +272,8 @@ static int attach_encap_tmpl(struct xfrm_encap_tmpl **encapp, struct rtattr *u_a
}
-static inline int xfrm_user_sec_ctx_size(struct xfrm_policy *xp)
+static inline int xfrm_user_sec_ctx_size(struct xfrm_sec_ctx *xfrm_ctx)
{
- struct xfrm_sec_ctx *xfrm_ctx = xp->security;
int len = 0;
if (xfrm_ctx) {
@@ -2170,7 +2169,7 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
- len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
+ len += RTA_SPACE(xfrm_user_sec_ctx_size(x->security));
#ifdef CONFIG_XFRM_SUB_POLICY
len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
#endif
@@ -2280,7 +2279,7 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve
len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
- len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
+ len += RTA_SPACE(xfrm_user_sec_ctx_size(xp->security));
#ifdef CONFIG_XFRM_SUB_POLICY
len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
#endif