Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6: (34 commits)
  PCI: Only build PCI syscalls on architectures that want them
  PCI: limit pci_get_bus_and_slot to domain 0
  PCI: hotplug: acpiphp: avoid acpiphp "cannot get bridge info" PCI hotplug failure
  PCI: hotplug: acpiphp: remove hot plug parameter write to PCI host bridge
  PCI: hotplug: acpiphp: fix slot poweroff problem on systems without _PS3
  PCI: hotplug: pciehp: wait for 1 second after power off slot
  PCI: pci_set_power_state(): check for PM capabilities earlier
  PCI: cpci_hotplug: Convert to use the kthread API
  PCI: add pci_try_set_mwi
  PCI: pcie: remove SPIN_LOCK_UNLOCKED
  PCI: ROUND_UP macro cleanup in drivers/pci
  PCI: remove pci_dac_dma_... APIs
  PCI: pci-x-pci-express-read-control-interfaces cleanups
  PCI: Fix typo in include/linux/pci.h
  PCI: pci_ids, remove double or more empty lines
  PCI: pci_ids, add atheros and 3com_2 vendors
  PCI: pci_ids, reorder some entries
  PCI: i386: traps, change VENDOR to DEVICE
  PCI: ATM: lanai, change VENDOR to DEVICE
  PCI: Change all drivers to use pci_device->revision
  ...
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 8c5698a..46bcff2 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -643,6 +643,60 @@
 !Edrivers/spi/spi.c
   </chapter>
 
+  <chapter id="i2c">
+     <title>I<superscript>2</superscript>C and SMBus Subsystem</title>
+
+     <para>
+	I<superscript>2</superscript>C (or without fancy typography, "I2C")
+	is an acronym for the "Inter-IC" bus, a simple bus protocol which is
+	widely used where low data rate communications suffice.
+	Since it's also a licensed trademark, some vendors use another
+	name (such as "Two-Wire Interface", TWI) for the same bus.
+	I2C only needs two signals (SCL for clock, SDA for data), conserving
+	board real estate and minimizing signal quality issues.
+	Most I2C devices use seven bit addresses, and bus speeds of up
+	to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet
+	found wide use.
+	I2C is a multi-master bus; open drain signaling is used to
+	arbitrate between masters, as well as to handshake and to
+	synchronize clocks from slower clients.
+     </para>
+
+     <para>
+	The Linux I2C programming interfaces support only the master
+	side of bus interactions, not the slave side.
+	The programming interface is structured around two kinds of driver,
+	and two kinds of device.
+	An I2C "Adapter Driver" abstracts the controller hardware; it binds
+	to a physical device (perhaps a PCI device or platform_device) and
+	exposes a <structname>struct i2c_adapter</structname> representing
+	each I2C bus segment it manages.
+	On each I2C bus segment will be I2C devices represented by a
+	<structname>struct i2c_client</structname>.  Those devices will
+	be bound to a <structname>struct i2c_driver</structname>,
+	which should follow the standard Linux driver model.
+	(At this writing, a legacy model is more widely used.)
+	There are functions to perform various I2C protocol operations; at
+	this writing all such functions are usable only from task context.
+     </para>
+
+     <para>
+	The System Management Bus (SMBus) is a sibling protocol.  Most SMBus
+	systems are also I2C conformant.  The electrical constraints are
+	tighter for SMBus, and it standardizes particular protocol messages
+	and idioms.  Controllers that support I2C can also support most
+	SMBus operations, but SMBus controllers don't support all the protocol
+	options that an I2C controller will.
+	There are functions to perform various SMBus protocol operations,
+	either using I2C primitives or by issuing SMBus commands to
+	i2c_adapter devices which don't support those I2C operations.
+     </para>
+
+!Iinclude/linux/i2c.h
+!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info
+!Edrivers/i2c/i2c-core.c
+  </chapter>
+
   <chapter id="splice">
       <title>splice API</title>
   <para>)
@@ -654,4 +708,5 @@
 !Ffs/splice.c
   </chapter>
 
+
 </book>
diff --git a/Documentation/blackfin/kgdb.txt b/Documentation/blackfin/kgdb.txt
new file mode 100644
index 0000000..84f6a484
--- /dev/null
+++ b/Documentation/blackfin/kgdb.txt
@@ -0,0 +1,155 @@
+			A Simple Guide to Configure KGDB
+
+			Sonic Zhang <sonic.zhang@analog.com>
+				Aug. 24th 2006
+
+
+This KGDB patch enables the kernel developer to do source level debugging on
+the kernel for the Blackfin architecture.  The debugging works over either the
+ethernet interface or one of the uarts.  Both software breakpoints and
+hardware breakpoints are supported in this version.
+http://docs.blackfin.uclinux.org/doku.php?id=kgdb
+
+
+2 known issues:
+1. This bug:
+       http://blackfin.uclinux.org/tracker/index.php?func=detail&aid=544&group_id=18&atid=145
+   The GDB client for Blackfin uClinux causes incorrect values of local
+   variables to be displayed when the user breaks the running of kernel in GDB.
+2. Because of a hardware bug in Blackfin 533 v1.0.3:
+       05000067 - Watchpoints (Hardware Breakpoints) are not supported
+   Hardware breakpoints cannot be set properly.
+
+
+Debug over Ethernet:
+ 
+1. Compile and install the cross platform version of gdb for blackfin, which
+   can be found at $(BINROOT)/bfin-elf-gdb.
+
+2. Apply this patch to the 2.6.x kernel.  Select the menuconfig option under
+   "Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb".
+   With this selected, option "Full Symbolic/Source Debugging support" and 
+   "Compile the kernel with frame pointers" are also selected.
+
+3. Select option "KGDB: connect over (Ethernet)".  Add "kgdboe=@target-IP/,@host-IP/" to
+   the option "Compiled-in Kernel Boot Parameter" under "Kernel hacking".
+
+4. Connect minicom to the serial port and boot the kernel image.
+
+5. Configure the IP "/> ifconfig eth0 target-IP"
+
+6. Start GDB client "bfin-elf-gdb vmlinux".
+
+7. Connect to the target "(gdb) target remote udp:target-IP:6443".
+
+8. Set software breakpoint "(gdb) break sys_open".
+
+9. Continue "(gdb) c".
+
+10. Run ls in the target console "/> ls".
+
+11. Breakpoint hits. "Breakpoint 1: sys_open(..."
+
+12. Display local variables and function paramters.
+    (*) This operation gives wrong results, see known issue 1.
+
+13. Single stepping "(gdb) si".
+
+14. Remove breakpoint 1. "(gdb) del 1"
+
+15. Set hardware breakpoint "(gdb) hbreak sys_open".
+
+16. Continue "(gdb) c".
+
+17. Run ls in the target console "/> ls".
+
+18. Hardware breakpoint hits. "Breakpoint 1: sys_open(...".
+    (*) This hardware breakpoint will not be hit, see known issue 2.
+
+19. Continue "(gdb) c".
+
+20. Interrupt the target in GDB "Ctrl+C".
+
+21. Detach from the target "(gdb) detach".
+
+22. Exit GDB "(gdb) quit".
+
+
+Debug over the UART:
+
+1. Compile and install the cross platform version of gdb for blackfin, which
+   can be found at $(BINROOT)/bfin-elf-gdb.
+
+2. Apply this patch to the 2.6.x kernel.  Select the menuconfig option under
+   "Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb".
+   With this selected, option "Full Symbolic/Source Debugging support" and 
+   "Compile the kernel with frame pointers" are also selected.
+
+3. Select option "KGDB: connect over (UART)".  Set "KGDB: UART port number" to be
+   a different one from the console.  Don't forget to change the mode of
+   blackfin serial driver to PIO.  Otherwise kgdb works incorrectly on UART.
+ 
+4. If you want connect to kgdb when the kernel boots, enable
+   "KGDB: Wait for gdb connection early" 
+
+5. Compile kernel.
+
+6. Connect minicom to the serial port of the console and boot the kernel image.
+
+7. Start GDB client "bfin-elf-gdb vmlinux".
+
+8. Set the baud rate in GDB "(gdb) set remotebaud 57600".
+
+9. Connect to the target on the second serial port "(gdb) target remote /dev/ttyS1".
+
+10. Set software breakpoint "(gdb) break sys_open".
+
+11. Continue "(gdb) c". 
+
+12. Run ls in the target console "/> ls". 
+
+13. A breakpoint is hit. "Breakpoint 1: sys_open(..."
+
+14. All other operations are the same as that in KGDB over Ethernet. 
+
+
+Debug over the same UART as console:
+
+1. Compile and install the cross platform version of gdb for blackfin, which
+   can be found at $(BINROOT)/bfin-elf-gdb.
+
+2. Apply this patch to the 2.6.x kernel.  Select the menuconfig option under
+   "Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb".
+   With this selected, option "Full Symbolic/Source Debugging support" and 
+   "Compile the kernel with frame pointers" are also selected.
+
+3. Select option "KGDB: connect over UART".  Set "KGDB: UART port number" to console.
+   Don't forget to change the mode of blackfin serial driver to PIO.
+   Otherwise kgdb works incorrectly on UART.
+ 
+4. If you want connect to kgdb when the kernel boots, enable
+   "KGDB: Wait for gdb connection early" 
+
+5. Connect minicom to the serial port and boot the kernel image. 
+
+6. (Optional) Ask target to wait for gdb connection by entering Ctrl+A. In minicom, you should enter Ctrl+A+A.
+
+7. Start GDB client "bfin-elf-gdb vmlinux".
+
+8. Set the baud rate in GDB "(gdb) set remotebaud 57600".
+
+9. Connect to the target "(gdb) target remote /dev/ttyS0".
+
+10. Set software breakpoint "(gdb) break sys_open".
+
+11. Continue "(gdb) c". Then enter Ctrl+C twice to stop GDB connection.
+
+12. Run ls in the target console "/> ls". Dummy string can be seen on the console.
+
+13. Then connect the gdb to target again. "(gdb) target remote /dev/ttyS0".
+    Now you will find a breakpoint is hit. "Breakpoint 1: sys_open(..."
+
+14. All other operations are the same as that in KGDB over Ethernet.  The only
+    difference is that after continue command in GDB, please stop GDB
+    connection by 2 "Ctrl+C"s and connect again after breakpoints are hit or
+    Ctrl+A is entered.
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 3a159da..0599a0c 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -262,25 +262,6 @@
 
 ---------------------------
 
-What:	Multipath cached routing support in ipv4
-When:	in 2.6.23
-Why:	Code was merged, then submitter immediately disappeared leaving
-	us with no maintainer and lots of bugs.  The code should not have
-	been merged in the first place, and many aspects of it's
-	implementation are blocking more critical core networking
-	development.  It's marked EXPERIMENTAL and no distribution
-	enables it because it cause obscure crashes due to unfixable bugs
-	(interfaces don't return errors so memory allocation can't be
-	handled, calling contexts of these interfaces make handling
-	errors impossible too because they get called after we've
-	totally commited to creating a route object, for example).
-	This problem has existed for years and no forward progress
-	has ever been made, and nobody steps up to try and salvage
-	this code, so we're going to finally just get rid of it.
-Who:	David S. Miller <davem@davemloft.net>
-
----------------------------
-
 What:	read_dev_chars(), read_conf_data{,_lpm}() (s390 common I/O layer)
 When:	December 2007
 Why:	These functions are a leftover from 2.4 times. They have several
@@ -330,3 +311,18 @@
 
 ---------------------------
 
+What:	Legacy RTC drivers (under drivers/i2c/chips)
+When:	November 2007
+Why:	Obsolete. We have a RTC subsystem with better drivers.
+Who:	Jean Delvare <khali@linux-fr.org>
+
+---------------------------
+
+What:	iptables SAME target
+When:	1.1. 2008
+Files:	net/ipv4/netfilter/ipt_SAME.c, include/linux/netfilter_ipv4/ipt_SAME.h
+Why:	Obsolete for multiple years now, NAT core provides the same behaviour.
+	Unfixable broken wrt. 32/64 bit cleanness.
+Who:	Patrick McHardy <kaber@trash.net>
+
+---------------------------
diff --git a/Documentation/firmware_class/firmware_sample_firmware_class.c b/Documentation/firmware_class/firmware_sample_firmware_class.c
index 4994f1f..fba943a 100644
--- a/Documentation/firmware_class/firmware_sample_firmware_class.c
+++ b/Documentation/firmware_class/firmware_sample_firmware_class.c
@@ -78,6 +78,7 @@
 			 firmware_loading_show, firmware_loading_store);
 
 static ssize_t firmware_data_read(struct kobject *kobj,
+				  struct bin_attribute *bin_attr,
 				  char *buffer, loff_t offset, size_t count)
 {
 	struct class_device *class_dev = to_class_dev(kobj);
@@ -88,6 +89,7 @@
 	return count;
 }
 static ssize_t firmware_data_write(struct kobject *kobj,
+				   struct bin_attribute *bin_attr,
 				   char *buffer, loff_t offset, size_t count)
 {
 	struct class_device *class_dev = to_class_dev(kobj);
diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801
index c34f0db..fe6406f 100644
--- a/Documentation/i2c/busses/i2c-i801
+++ b/Documentation/i2c/busses/i2c-i801
@@ -5,8 +5,8 @@
     '810' and '810E' chipsets)
   * Intel 82801BA (ICH2 - part of the '815E' chipset)
   * Intel 82801CA/CAM (ICH3)
-  * Intel 82801DB (ICH4) (HW PEC supported, 32 byte buffer not supported)
-  * Intel 82801EB/ER (ICH5) (HW PEC supported, 32 byte buffer not supported)
+  * Intel 82801DB (ICH4) (HW PEC supported)
+  * Intel 82801EB/ER (ICH5) (HW PEC supported)
   * Intel 6300ESB
   * Intel 82801FB/FR/FW/FRW (ICH6)
   * Intel 82801G (ICH7)
diff --git a/Documentation/i2c/busses/i2c-piix4 b/Documentation/i2c/busses/i2c-piix4
index 7cbe43f..fa0c786 100644
--- a/Documentation/i2c/busses/i2c-piix4
+++ b/Documentation/i2c/busses/i2c-piix4
@@ -6,7 +6,7 @@
     Datasheet: Publicly available at the Intel website
   * ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges
     Datasheet: Only available via NDA from ServerWorks
-  * ATI IXP200, IXP300, IXP400 and SB600 southbridges
+  * ATI IXP200, IXP300, IXP400, SB600 and SB700 southbridges
     Datasheet: Not publicly available
   * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
     Datasheet: Publicly available at the SMSC website http://www.smsc.com
diff --git a/Documentation/i2c/busses/i2c-taos-evm b/Documentation/i2c/busses/i2c-taos-evm
new file mode 100644
index 0000000..9146e33
--- /dev/null
+++ b/Documentation/i2c/busses/i2c-taos-evm
@@ -0,0 +1,46 @@
+Kernel driver i2c-taos-evm
+
+Author: Jean Delvare <khali@linux-fr.org>
+
+This is a driver for the evaluation modules for TAOS I2C/SMBus chips.
+The modules include an SMBus master with limited capabilities, which can
+be controlled over the serial port. Virtually all evaluation modules
+are supported, but a few lines of code need to be added for each new
+module to instantiate the right I2C chip on the bus. Obviously, a driver
+for the chip in question is also needed.
+
+Currently supported devices are:
+
+* TAOS TSL2550 EVM
+
+For addtional information on TAOS products, please see
+  http://www.taosinc.com/
+
+
+Using this driver
+-----------------
+
+In order to use this driver, you'll need the serport driver, and the
+inputattach tool, which is part of the input-utils package. The following
+commands will tell the kernel that you have a TAOS EVM on the first
+serial port:
+
+# modprobe serport
+# inputattach --taos-evm /dev/ttyS0
+
+
+Technical details
+-----------------
+
+Only 4 SMBus transaction types are supported by the TAOS evaluation
+modules:
+* Receive Byte
+* Send Byte
+* Read Byte
+* Write Byte
+
+The communication protocol is text-based and pretty simple. It is
+described in a PDF document on the CD which comes with the evaluation
+module. The communication is rather slow, because the serial port has
+to operate at 1200 bps. However, I don't think this is a big concern in
+practice, as these modules are meant for evaluation and testing only.
diff --git a/Documentation/i2c/chips/max6875 b/Documentation/i2c/chips/max6875
index 96fec56..a0cd8af 100644
--- a/Documentation/i2c/chips/max6875
+++ b/Documentation/i2c/chips/max6875
@@ -99,7 +99,7 @@
 
   or
 
-  count = i2c_smbus_read_i2c_block_data(fd, 0x84, buffer);
+  count = i2c_smbus_read_i2c_block_data(fd, 0x84, 16, buffer);
 
 The block read should read 16 bytes.
 0x84 is the block read command.
diff --git a/Documentation/i2c/chips/x1205 b/Documentation/i2c/chips/x1205
deleted file mode 100644
index 09407c9..0000000
--- a/Documentation/i2c/chips/x1205
+++ /dev/null
@@ -1,38 +0,0 @@
-Kernel driver x1205
-===================
-
-Supported chips:
-  * Xicor X1205 RTC
-    Prefix: 'x1205'
-    Addresses scanned: none
-    Datasheet: http://www.intersil.com/cda/deviceinfo/0,1477,X1205,00.html
-
-Authors:
-	Karen Spearel <kas11@tampabay.rr.com>,
-	Alessandro Zummo <a.zummo@towertech.it>
-
-Description
------------
-
-This module aims to provide complete access to the Xicor X1205 RTC.
-Recently Xicor has merged with Intersil, but the chip is
-still sold under the Xicor brand.
-
-This chip is located at address 0x6f and uses a 2-byte register addressing.
-Two bytes need to be written to read a single register, while most
-other chips just require one and take the second one as the data
-to be written. To prevent corrupting unknown chips, the user must
-explicitely set the probe parameter.
-
-example:
-
-modprobe x1205 probe=0,0x6f
-
-The module supports one more option, hctosys, which is used to set the
-software clock from the x1205. On systems where the x1205 is the
-only hardware rtc, this parameter could be used to achieve a correct
-date/time earlier in the system boot sequence.
-
-example:
-
-modprobe x1205 probe=0,0x6f hctosys=1
diff --git a/Documentation/i2c/summary b/Documentation/i2c/summary
index aea60bf..003c731 100644
--- a/Documentation/i2c/summary
+++ b/Documentation/i2c/summary
@@ -67,7 +67,6 @@
 Algorithm drivers
 -----------------
 
-i2c-algo-8xx:    An algorithm for CPM's I2C device in Motorola 8xx processors (NOT BUILT BY DEFAULT)
 i2c-algo-bit:    A bit-banging algorithm
 i2c-algo-pcf:    A PCF 8584 style algorithm
 i2c-algo-ibm_ocp: An algorithm for the I2C device in IBM 4xx processors (NOT BUILT BY DEFAULT)
@@ -81,6 +80,5 @@
 i2c-philips-par: Philips style parallel port adapter (uses i2c-algo-bit)
 i2c-adap-ibm_ocp: IBM 4xx processor I2C device (uses i2c-algo-ibm_ocp) (NOT BUILT BY DEFAULT)
 i2c-pport:       Primitive parallel port adapter (uses i2c-algo-bit)
-i2c-rpx:         RPX board Motorola 8xx I2C device (uses i2c-algo-8xx) (NOT BUILT BY DEFAULT)
 i2c-velleman:    Velleman K8000 parallel port adapter (uses i2c-algo-bit)
 
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
index 3d8d36b..2c17003 100644
--- a/Documentation/i2c/writing-clients
+++ b/Documentation/i2c/writing-clients
@@ -571,7 +571,7 @@
                                         u8 command, u8 length,
                                         u8 *values);
   extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
-                                           u8 command, u8 *values);
+                                           u8 command, u8 length, u8 *values);
 
 These ones were removed in Linux 2.6.10 because they had no users, but could
 be added back later if needed:
diff --git a/Documentation/i386/zero-page.txt b/Documentation/i386/zero-page.txt
index c04a421..75b3680 100644
--- a/Documentation/i386/zero-page.txt
+++ b/Documentation/i386/zero-page.txt
@@ -37,6 +37,7 @@
 0x1d0	unsigned long	EFI memory descriptor map pointer
 0x1d4	unsigned long	EFI memory descriptor map size
 0x1e0	unsigned long	ALT_MEM_K, alternative mem check, in Kb
+0x1e4	unsigned long	Scratch field for the kernel setup code
 0x1e8	char		number of entries in E820MAP (below)
 0x1e9	unsigned char	number of entries in EDDBUF (below)
 0x1ea	unsigned char	number of entries in EDD_MBR_SIG_BUFFER (below)
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index af6a63a..09c184e 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -874,8 +874,7 @@
 accept_source_route - INTEGER
 	Accept source routing (routing extension header).
 
-	> 0: Accept routing header.
-	= 0: Accept only routing header type 2.
+	>= 0: Accept only routing header type 2.
 	< 0: Do not accept routing header.
 
 	Default: 0
diff --git a/Documentation/networking/l2tp.txt b/Documentation/networking/l2tp.txt
new file mode 100644
index 0000000..2451f55
--- /dev/null
+++ b/Documentation/networking/l2tp.txt
@@ -0,0 +1,169 @@
+This brief document describes how to use the kernel's PPPoL2TP driver
+to provide L2TP functionality. L2TP is a protocol that tunnels one or
+more PPP sessions over a UDP tunnel. It is commonly used for VPNs
+(L2TP/IPSec) and by ISPs to tunnel subscriber PPP sessions over an IP
+network infrastructure.
+
+Design
+======
+
+The PPPoL2TP driver, drivers/net/pppol2tp.c, provides a mechanism by
+which PPP frames carried through an L2TP session are passed through
+the kernel's PPP subsystem. The standard PPP daemon, pppd, handles all
+PPP interaction with the peer. PPP network interfaces are created for
+each local PPP endpoint.
+
+The L2TP protocol http://www.faqs.org/rfcs/rfc2661.html defines L2TP
+control and data frames. L2TP control frames carry messages between
+L2TP clients/servers and are used to setup / teardown tunnels and
+sessions. An L2TP client or server is implemented in userspace and
+will use a regular UDP socket per tunnel. L2TP data frames carry PPP
+frames, which may be PPP control or PPP data. The kernel's PPP
+subsystem arranges for PPP control frames to be delivered to pppd,
+while data frames are forwarded as usual.
+
+Each tunnel and session within a tunnel is assigned a unique tunnel_id
+and session_id. These ids are carried in the L2TP header of every
+control and data packet. The pppol2tp driver uses them to lookup
+internal tunnel and/or session contexts. Zero tunnel / session ids are
+treated specially - zero ids are never assigned to tunnels or sessions
+in the network. In the driver, the tunnel context keeps a pointer to
+the tunnel UDP socket. The session context keeps a pointer to the
+PPPoL2TP socket, as well as other data that lets the driver interface
+to the kernel PPP subsystem.
+
+Note that the pppol2tp kernel driver handles only L2TP data frames;
+L2TP control frames are simply passed up to userspace in the UDP
+tunnel socket. The kernel handles all datapath aspects of the
+protocol, including data packet resequencing (if enabled).
+
+There are a number of requirements on the userspace L2TP daemon in
+order to use the pppol2tp driver.
+
+1. Use a UDP socket per tunnel.
+
+2. Create a single PPPoL2TP socket per tunnel bound to a special null
+   session id. This is used only for communicating with the driver but
+   must remain open while the tunnel is active. Opening this tunnel
+   management socket causes the driver to mark the tunnel socket as an
+   L2TP UDP encapsulation socket and flags it for use by the
+   referenced tunnel id. This hooks up the UDP receive path via
+   udp_encap_rcv() in net/ipv4/udp.c. PPP data frames are never passed
+   in this special PPPoX socket.
+
+3. Create a PPPoL2TP socket per L2TP session. This is typically done
+   by starting pppd with the pppol2tp plugin and appropriate
+   arguments. A PPPoL2TP tunnel management socket (Step 2) must be
+   created before the first PPPoL2TP session socket is created.
+
+When creating PPPoL2TP sockets, the application provides information
+to the driver about the socket in a socket connect() call. Source and
+destination tunnel and session ids are provided, as well as the file
+descriptor of a UDP socket. See struct pppol2tp_addr in
+include/linux/if_ppp.h. Note that zero tunnel / session ids are
+treated specially. When creating the per-tunnel PPPoL2TP management
+socket in Step 2 above, zero source and destination session ids are
+specified, which tells the driver to prepare the supplied UDP file
+descriptor for use as an L2TP tunnel socket.
+
+Userspace may control behavior of the tunnel or session using
+setsockopt and ioctl on the PPPoX socket. The following socket
+options are supported:-
+
+DEBUG     - bitmask of debug message categories. See below.
+SENDSEQ   - 0 => don't send packets with sequence numbers
+            1 => send packets with sequence numbers
+RECVSEQ   - 0 => receive packet sequence numbers are optional
+            1 => drop receive packets without sequence numbers
+LNSMODE   - 0 => act as LAC.
+            1 => act as LNS.
+REORDERTO - reorder timeout (in millisecs). If 0, don't try to reorder.
+
+Only the DEBUG option is supported by the special tunnel management
+PPPoX socket.
+
+In addition to the standard PPP ioctls, a PPPIOCGL2TPSTATS is provided
+to retrieve tunnel and session statistics from the kernel using the
+PPPoX socket of the appropriate tunnel or session.
+
+Debugging
+=========
+
+The driver supports a flexible debug scheme where kernel trace
+messages may be optionally enabled per tunnel and per session. Care is
+needed when debugging a live system since the messages are not
+rate-limited and a busy system could be swamped. Userspace uses
+setsockopt on the PPPoX socket to set a debug mask.
+
+The following debug mask bits are available:
+
+PPPOL2TP_MSG_DEBUG    verbose debug (if compiled in)
+PPPOL2TP_MSG_CONTROL  userspace - kernel interface
+PPPOL2TP_MSG_SEQ      sequence numbers handling
+PPPOL2TP_MSG_DATA     data packets
+
+Sample Userspace Code
+=====================
+
+1. Create tunnel management PPPoX socket
+
+        kernel_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
+        if (kernel_fd >= 0) {
+                struct sockaddr_pppol2tp sax;
+                struct sockaddr_in const *peer_addr;
+
+                peer_addr = l2tp_tunnel_get_peer_addr(tunnel);
+                memset(&sax, 0, sizeof(sax));
+                sax.sa_family = AF_PPPOX;
+                sax.sa_protocol = PX_PROTO_OL2TP;
+                sax.pppol2tp.fd = udp_fd;       /* fd of tunnel UDP socket */
+                sax.pppol2tp.addr.sin_addr.s_addr = peer_addr->sin_addr.s_addr;
+                sax.pppol2tp.addr.sin_port = peer_addr->sin_port;
+                sax.pppol2tp.addr.sin_family = AF_INET;
+                sax.pppol2tp.s_tunnel = tunnel_id;
+                sax.pppol2tp.s_session = 0;     /* special case: mgmt socket */
+                sax.pppol2tp.d_tunnel = 0;
+                sax.pppol2tp.d_session = 0;     /* special case: mgmt socket */
+
+                if(connect(kernel_fd, (struct sockaddr *)&sax, sizeof(sax) ) < 0 ) {
+                        perror("connect failed");
+                        result = -errno;
+                        goto err;
+                }
+        }
+
+2. Create session PPPoX data socket
+
+        struct sockaddr_pppol2tp sax;
+        int fd;
+
+        /* Note, the target socket must be bound already, else it will not be ready */
+        sax.sa_family = AF_PPPOX;
+        sax.sa_protocol = PX_PROTO_OL2TP;
+        sax.pppol2tp.fd = tunnel_fd;
+        sax.pppol2tp.addr.sin_addr.s_addr = addr->sin_addr.s_addr;
+        sax.pppol2tp.addr.sin_port = addr->sin_port;
+        sax.pppol2tp.addr.sin_family = AF_INET;
+        sax.pppol2tp.s_tunnel  = tunnel_id;
+        sax.pppol2tp.s_session = session_id;
+        sax.pppol2tp.d_tunnel  = peer_tunnel_id;
+        sax.pppol2tp.d_session = peer_session_id;
+
+        /* session_fd is the fd of the session's PPPoL2TP socket.
+         * tunnel_fd is the fd of the tunnel UDP socket.
+         */
+        fd = connect(session_fd, (struct sockaddr *)&sax, sizeof(sax));
+        if (fd < 0 )    {
+                return -errno;
+        }
+        return 0;
+
+Miscellanous
+============
+
+The PPPoL2TP driver was developed as part of the OpenL2TP project by
+Katalix Systems Ltd. OpenL2TP is a full-featured L2TP client / server,
+designed from the ground up to have the L2TP datapath in the
+kernel. The project also implemented the pppol2tp plugin for pppd
+which allows pppd to use the kernel driver. Details can be found at
+http://openl2tp.sourceforge.net.
diff --git a/Documentation/networking/multiqueue.txt b/Documentation/networking/multiqueue.txt
new file mode 100644
index 0000000..00b60cc
--- /dev/null
+++ b/Documentation/networking/multiqueue.txt
@@ -0,0 +1,111 @@
+
+		HOWTO for multiqueue network device support
+		===========================================
+
+Section 1: Base driver requirements for implementing multiqueue support
+Section 2: Qdisc support for multiqueue devices
+Section 3: Brief howto using PRIO or RR for multiqueue devices
+
+
+Intro: Kernel support for multiqueue devices
+---------------------------------------------------------
+
+Kernel support for multiqueue devices is only an API that is presented to the
+netdevice layer for base drivers to implement.  This feature is part of the
+core networking stack, and all network devices will be running on the
+multiqueue-aware stack.  If a base driver only has one queue, then these
+changes are transparent to that driver.
+
+
+Section 1: Base driver requirements for implementing multiqueue support
+-----------------------------------------------------------------------
+
+Base drivers are required to use the new alloc_etherdev_mq() or
+alloc_netdev_mq() functions to allocate the subqueues for the device.  The
+underlying kernel API will take care of the allocation and deallocation of
+the subqueue memory, as well as netdev configuration of where the queues
+exist in memory.
+
+The base driver will also need to manage the queues as it does the global
+netdev->queue_lock today.  Therefore base drivers should use the
+netif_{start|stop|wake}_subqueue() functions to manage each queue while the
+device is still operational.  netdev->queue_lock is still used when the device
+comes online or when it's completely shut down (unregister_netdev(), etc.).
+
+Finally, the base driver should indicate that it is a multiqueue device.  The
+feature flag NETIF_F_MULTI_QUEUE should be added to the netdev->features
+bitmap on device initialization.  Below is an example from e1000:
+
+#ifdef CONFIG_E1000_MQ
+	if ( (adapter->hw.mac.type == e1000_82571) ||
+	     (adapter->hw.mac.type == e1000_82572) ||
+	     (adapter->hw.mac.type == e1000_80003es2lan))
+		netdev->features |= NETIF_F_MULTI_QUEUE;
+#endif
+
+
+Section 2: Qdisc support for multiqueue devices
+-----------------------------------------------
+
+Currently two qdiscs support multiqueue devices.  A new round-robin qdisc,
+sch_rr, and sch_prio. The qdisc is responsible for classifying the skb's to
+bands and queues, and will store the queue mapping into skb->queue_mapping.
+Use this field in the base driver to determine which queue to send the skb
+to.
+
+sch_rr has been added for hardware that doesn't want scheduling policies from
+software, so it's a straight round-robin qdisc.  It uses the same syntax and
+classification priomap that sch_prio uses, so it should be intuitive to
+configure for people who've used sch_prio.
+
+The PRIO qdisc naturally plugs into a multiqueue device.  If PRIO has been
+built with NET_SCH_PRIO_MQ, then upon load, it will make sure the number of
+bands requested is equal to the number of queues on the hardware.  If they
+are equal, it sets a one-to-one mapping up between the queues and bands.  If
+they're not equal, it will not load the qdisc.  This is the same behavior
+for RR.  Once the association is made, any skb that is classified will have
+skb->queue_mapping set, which will allow the driver to properly queue skb's
+to multiple queues.
+
+
+Section 3: Brief howto using PRIO and RR for multiqueue devices
+---------------------------------------------------------------
+
+The userspace command 'tc,' part of the iproute2 package, is used to configure
+qdiscs.  To add the PRIO qdisc to your network device, assuming the device is
+called eth0, run the following command:
+
+# tc qdisc add dev eth0 root handle 1: prio bands 4 multiqueue
+
+This will create 4 bands, 0 being highest priority, and associate those bands
+to the queues on your NIC.  Assuming eth0 has 4 Tx queues, the band mapping
+would look like:
+
+band 0 => queue 0
+band 1 => queue 1
+band 2 => queue 2
+band 3 => queue 3
+
+Traffic will begin flowing through each queue if your TOS values are assigning
+traffic across the various bands.  For example, ssh traffic will always try to
+go out band 0 based on TOS -> Linux priority conversion (realtime traffic),
+so it will be sent out queue 0.  ICMP traffic (pings) fall into the "normal"
+traffic classification, which is band 1.  Therefore pings will be send out
+queue 1 on the NIC.
+
+Note the use of the multiqueue keyword.  This is only in versions of iproute2
+that support multiqueue networking devices; if this is omitted when loading
+a qdisc onto a multiqueue device, the qdisc will load and operate the same
+if it were loaded onto a single-queue device (i.e. - sends all traffic to
+queue 0).
+
+Another alternative to multiqueue band allocation can be done by using the
+multiqueue option and specify 0 bands.  If this is the case, the qdisc will
+allocate the number of bands to equal the number of queues that the device
+reports, and bring the qdisc online.
+
+The behavior of tc filters remains the same, where it will override TOS priority
+classification.
+
+
+Author: Peter P. Waskiewicz Jr. <peter.p.waskiewicz.jr@intel.com>
diff --git a/Documentation/networking/netdevices.txt b/Documentation/networking/netdevices.txt
index ce1361f..3786929 100644
--- a/Documentation/networking/netdevices.txt
+++ b/Documentation/networking/netdevices.txt
@@ -20,6 +20,30 @@
 separately allocated data is attached to the network device
 (dev->priv) then it is up to the module exit handler to free that.
 
+MTU
+===
+Each network device has a Maximum Transfer Unit. The MTU does not
+include any link layer protocol overhead. Upper layer protocols must
+not pass a socket buffer (skb) to a device to transmit with more data
+than the mtu. The MTU does not include link layer header overhead, so
+for example on Ethernet if the standard MTU is 1500 bytes used, the
+actual skb will contain up to 1514 bytes because of the Ethernet
+header. Devices should allow for the 4 byte VLAN header as well.
+
+Segmentation Offload (GSO, TSO) is an exception to this rule.  The
+upper layer protocol may pass a large socket buffer to the device
+transmit routine, and the device will break that up into separate
+packets based on the current MTU.
+
+MTU is symmetrical and applies both to receive and transmit. A device
+must be able to receive at least the maximum size packet allowed by
+the MTU. A network device may use the MTU as mechanism to size receive
+buffers, but the device should allow packets with VLAN header. With
+standard Ethernet mtu of 1500 bytes, the device should allow up to
+1518 byte packets (1500 + 14 header + 4 tag).  The device may either:
+drop, truncate, or pass up oversize packets, but dropping oversize
+packets is preferred.
+
 
 struct net_device synchronization rules
 =======================================
@@ -43,16 +67,17 @@
 
 dev->hard_start_xmit:
 	Synchronization: netif_tx_lock spinlock.
+
 	When the driver sets NETIF_F_LLTX in dev->features this will be
 	called without holding netif_tx_lock. In this case the driver
 	has to lock by itself when needed. It is recommended to use a try lock
-	for this and return -1 when the spin lock fails. 
+	for this and return NETDEV_TX_LOCKED when the spin lock fails.
 	The locking there should also properly protect against 
-	set_multicast_list
-	Context: Process with BHs disabled or BH (timer).
-	Notes: netif_queue_stopped() is guaranteed false
-               Interrupts must be enabled when calling hard_start_xmit.
-                (Interrupts must also be enabled when enabling the BH handler.)
+	set_multicast_list.
+
+	Context: Process with BHs disabled or BH (timer),
+	         will be called with interrupts disabled by netconsole.
+
 	Return codes: 
 	o NETDEV_TX_OK everything ok. 
 	o NETDEV_TX_BUSY Cannot transmit packet, try later 
@@ -74,4 +99,5 @@
 	Synchronization: __LINK_STATE_RX_SCHED bit in dev->state.  See
 		dev_close code and comments in net/core/dev.c for more info.
 	Context: softirq
+	         will be called with interrupts disabled by netconsole.
 
diff --git a/Documentation/sysfs-rules.txt b/Documentation/sysfs-rules.txt
new file mode 100644
index 0000000..42861bb
--- /dev/null
+++ b/Documentation/sysfs-rules.txt
@@ -0,0 +1,166 @@
+Rules on how to access information in the Linux kernel sysfs
+
+The kernel exported sysfs exports internal kernel implementation-details
+and depends on internal kernel structures and layout. It is agreed upon
+by the kernel developers that the Linux kernel does not provide a stable
+internal API. As sysfs is a direct export of kernel internal
+structures, the sysfs interface can not provide a stable interface eighter,
+it may always change along with internal kernel changes.
+
+To minimize the risk of breaking users of sysfs, which are in most cases
+low-level userspace applications, with a new kernel release, the users
+of sysfs must follow some rules to use an as abstract-as-possible way to
+access this filesystem. The current udev and HAL programs already
+implement this and users are encouraged to plug, if possible, into the
+abstractions these programs provide instead of accessing sysfs
+directly.
+
+But if you really do want or need to access sysfs directly, please follow
+the following rules and then your programs should work with future
+versions of the sysfs interface.
+
+- Do not use libsysfs
+  It makes assumptions about sysfs which are not true. Its API does not
+  offer any abstraction, it exposes all the kernel driver-core
+  implementation details in its own API. Therefore it is not better than
+  reading directories and opening the files yourself.
+  Also, it is not actively maintained, in the sense of reflecting the
+  current kernel-development. The goal of providing a stable interface
+  to sysfs has failed, it causes more problems, than it solves. It
+  violates many of the rules in this document.
+
+- sysfs is always at /sys
+  Parsing /proc/mounts is a waste of time. Other mount points are a
+  system configuration bug you should not try to solve. For test cases,
+  possibly support a SYSFS_PATH environment variable to overwrite the
+  applications behavior, but never try to search for sysfs. Never try
+  to mount it, if you are not an early boot script.
+
+- devices are only "devices"
+  There is no such thing like class-, bus-, physical devices,
+  interfaces, and such that you can rely on in userspace. Everything is
+  just simply a "device". Class-, bus-, physical, ... types are just
+  kernel implementation details, which should not be expected by
+  applications that look for devices in sysfs.
+
+  The properties of a device are:
+    o devpath (/devices/pci0000:00/0000:00:1d.1/usb2/2-2/2-2:1.0)
+      - identical to the DEVPATH value in the event sent from the kernel
+        at device creation and removal
+      - the unique key to the device at that point in time
+      - the kernels path to the device-directory without the leading
+        /sys, and always starting with with a slash
+      - all elements of a devpath must be real directories. Symlinks
+        pointing to /sys/devices must always be resolved to their real
+        target, and the target path must be used to access the device.
+        That way the devpath to the device matches the devpath of the
+        kernel used at event time.
+      - using or exposing symlink values as elements in a devpath string
+        is a bug in the application
+
+    o kernel name (sda, tty, 0000:00:1f.2, ...)
+      - a directory name, identical to the last element of the devpath
+      - applications need to handle spaces and characters like '!' in
+        the name
+
+    o subsystem (block, tty, pci, ...)
+      - simple string, never a path or a link
+      - retrieved by reading the "subsystem"-link and using only the
+        last element of the target path
+
+    o driver (tg3, ata_piix, uhci_hcd)
+      - a simple string, which may contain spaces, never a path or a
+        link
+      - it is retrieved by reading the "driver"-link and using only the
+        last element of the target path
+      - devices which do not have "driver"-link, just do not have a
+        driver; copying the driver value in a child device context, is a
+        bug in the application
+
+    o attributes
+      - the files in the device directory or files below a subdirectories
+        of the same device directory
+      - accessing attributes reached by a symlink pointing to another device,
+        like the "device"-link, is a bug in the application
+
+  Everything else is just a kernel driver-core implementation detail,
+  that should not be assumed to be stable across kernel releases.
+
+- Properties of parent devices never belong into a child device.
+  Always look at the parent devices themselves for determining device
+  context properties. If the device 'eth0' or 'sda' does not have a
+  "driver"-link, then this device does not have a driver. Its value is empty.
+  Never copy any property of the parent-device into a child-device. Parent
+  device-properties may change dynamically without any notice to the
+  child device.
+
+- Hierarchy in a single device-tree
+  There is only one valid place in sysfs where hierarchy can be examined
+  and this is below: /sys/devices.
+  It is planned, that all device directories will end up in the tree
+  below this directory.
+
+- Classification by subsystem
+  There are currently three places for classification of devices:
+  /sys/block, /sys/class and /sys/bus. It is planned that these will
+  not contain any device-directories themselves, but only flat lists of
+  symlinks pointing to the unified /sys/devices tree.
+  All three places have completely different rules on how to access
+  device information. It is planned to merge all three
+  classification-directories into one place at /sys/subsystem,
+  following the layout of the bus-directories. All buses and
+  classes, including the converted block-subsystem, will show up
+  there.
+  The devices belonging to a subsystem will create a symlink in the
+  "devices" directory at /sys/subsystem/<name>/devices.
+
+  If /sys/subsystem exists, /sys/bus, /sys/class and /sys/block can be
+  ignored. If it does not exist, you have always to scan all three
+  places, as the kernel is free to move a subsystem from one place to
+  the other, as long as the devices are still reachable by the same
+  subsystem name.
+
+  Assuming /sys/class/<subsystem> and /sys/bus/<subsystem>, or
+  /sys/block and /sys/class/block are not interchangeable, is a bug in
+  the application.
+
+- Block
+  The converted block-subsystem at /sys/class/block, or
+  /sys/subsystem/block will contain the links for disks and partitions
+  at the same level, never in a hierarchy. Assuming the block-subsytem to
+  contain only disks and not partition-devices in the same flat list is
+  a bug in the application.
+
+- "device"-link and <subsystem>:<kernel name>-links
+  Never depend on the "device"-link. The "device"-link is a workaround
+  for the old layout, where class-devices are not created in
+  /sys/devices/ like the bus-devices. If the link-resolving of a
+  device-directory does not end in /sys/devices/, you can use the
+  "device"-link to find the parent devices in /sys/devices/. That is the
+  single valid use of the "device"-link, it must never appear in any
+  path as an element. Assuming the existence of the "device"-link for
+  a device in /sys/devices/ is a bug in the application.
+  Accessing /sys/class/net/eth0/device is a bug in the application.
+
+  Never depend on the class-specific links back to the /sys/class
+  directory.  These links are also a workaround for the design mistake
+  that class-devices are not created in /sys/devices. If a device
+  directory does not contain directories for child devices, these links
+  may be used to find the child devices in /sys/class. That is the single
+  valid use of these links, they must never appear in any path as an
+  element. Assuming the existence of these links for devices which are
+  real child device directories in the /sys/devices tree, is a bug in
+  the application.
+
+  It is planned to remove all these links when when all class-device
+  directories live in /sys/devices.
+
+- Position of devices along device chain can change.
+  Never depend on a specific parent device position in the devpath,
+  or the chain of parent devices. The kernel is free to insert devices into
+  the chain. You must always request the parent device you are looking for
+  by its subsystem value. You need to walk up the chain until you find
+  the device that matches the expected subsystem. Depending on a specific
+  position of a parent device, or exposing relative paths, using "../" to
+  access the chain of parents, is a bug in the application.
+
diff --git a/MAINTAINERS b/MAINTAINERS
index 0e3f350..b2c5415 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1750,8 +1750,8 @@
 S:	Maintained
 
 i386 BOOT CODE
-P:	Riley H. Williams
-M:	Riley@Williams.Name
+P:	H. Peter Anvin
+M:	hpa@zytor.com
 L:	Linux-Kernel@vger.kernel.org
 S:	Maintained
 
@@ -2898,6 +2898,11 @@
 M:	mostrows@speakeasy.net
 S:	Maintained
 
+PPP OVER L2TP
+P:	James Chapman
+M:	jchapman@katalix.com
+S:	Maintained
+
 PREEMPTIBLE KERNEL
 P:	Robert Love
 M:	rml@tech9.net
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index cfe6f46..ae21755 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -60,6 +60,9 @@
 	unsigned int irq;
 	spinlock_t lock;
 	void __iomem *base;
+#ifdef CONFIG_PM
+	void *saved_state;
+#endif
 };
 
 struct locomo_dev_info {
@@ -565,7 +568,7 @@
 	if (!save)
 		return -ENOMEM;
 
-	dev->dev.power.saved_state = (void *) save;
+	lchip->saved_state = save;
 
 	spin_lock_irqsave(&lchip->lock, flags);
 
@@ -605,8 +608,8 @@
 	struct locomo_save_data *save;
 	unsigned long r;
 	unsigned long flags;
-	
-	save = (struct locomo_save_data *) dev->dev.power.saved_state;
+
+	save = lchip->saved_state;
 	if (!save)
 		return 0;
 
@@ -628,6 +631,8 @@
 	locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
 
 	spin_unlock_irqrestore(&lchip->lock, flags);
+
+	lchip->saved_state = NULL;
 	kfree(save);
 
 	return 0;
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 798bbfc..eb06d0b 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -51,6 +51,9 @@
 	int		irq;
 	spinlock_t	lock;
 	void __iomem	*base;
+#ifdef CONFIG_PM
+	void		*saved_state;
+#endif
 };
 
 /*
@@ -822,7 +825,7 @@
 	save = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL);
 	if (!save)
 		return -ENOMEM;
-	dev->dev.power.saved_state = save;
+	sachip->saved_state = save;
 
 	spin_lock_irqsave(&sachip->lock, flags);
 
@@ -878,7 +881,7 @@
 	unsigned long flags, id;
 	void __iomem *base;
 
-	save = (struct sa1111_save_data *)dev->dev.power.saved_state;
+	save = sachip->saved_state;
 	if (!save)
 		return 0;
 
@@ -923,7 +926,7 @@
 
 	spin_unlock_irqrestore(&sachip->lock, flags);
 
-	dev->dev.power.saved_state = NULL;
+	sachip->saved_state = NULL;
 	kfree(save);
 
 	return 0;
@@ -958,8 +961,8 @@
 		platform_set_drvdata(pdev, NULL);
 
 #ifdef CONFIG_PM
-		kfree(pdev->dev.power.saved_state);
-		pdev->dev.power.saved_state = NULL;
+		kfree(sachip->saved_state);
+		sachip->saved_state = NULL;
 #endif
 	}
 
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 4cbf946..3a0a1ee 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -185,28 +185,21 @@
 /*
  * LDM power management.
  */
+static unsigned int neponset_saved_state;
+
 static int neponset_suspend(struct platform_device *dev, pm_message_t state)
 {
 	/*
 	 * Save state.
 	 */
-	if (!dev->dev.power.saved_state)
-		dev->dev.power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
-	if (!dev->dev.power.saved_state)
-		return -ENOMEM;
-
-	*(unsigned int *)dev->dev.power.saved_state = NCR_0;
+	neponset_saved_state = NCR_0;
 
 	return 0;
 }
 
 static int neponset_resume(struct platform_device *dev)
 {
-	if (dev->dev.power.saved_state) {
-		NCR_0 = *(unsigned int *)dev->dev.power.saved_state;
-		kfree(dev->dev.power.saved_state);
-		dev->dev.power.saved_state = NULL;
-	}
+	NCR_0 = neponset_saved_state;
 
 	return 0;
 }
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index d98bafc..017defa 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -71,6 +71,7 @@
 
 config IRQCHIP_DEMUX_GPIO
 	bool
+	depends on (BF53x || BF561 || BF54x)
 	default y
 
 source "init/Kconfig"
@@ -114,6 +115,26 @@
 	help
 	  BF537 Processor Support.
 
+config BF542
+	bool "BF542"
+	help
+	  BF542 Processor Support.
+
+config BF544
+	bool "BF544"
+	help
+	  BF544 Processor Support.
+
+config BF548
+	bool "BF548"
+	help
+	  BF548 Processor Support.
+
+config BF549
+	bool "BF549"
+	help
+	  BF549 Processor Support.
+
 config BF561
 	bool "BF561"
 	help
@@ -125,6 +146,11 @@
 	prompt "Silicon Rev"
 	default BF_REV_0_2 if BF537
 	default BF_REV_0_3 if BF533
+	default BF_REV_0_0 if BF549
+
+config BF_REV_0_0
+	bool "0.0"
+	depends on (BF549)
 
 config BF_REV_0_2
 	bool "0.2"
@@ -150,6 +176,16 @@
 
 endchoice
 
+config BF53x
+	bool
+	depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537)
+	default y
+
+config BF54x
+	bool
+	depends on (BF542 || BF544 || BF548 || BF549)
+	default y
+
 config BFIN_DUAL_CORE
 	bool
 	depends on (BF561)
@@ -198,6 +234,12 @@
 	help
 	  CM-BF537 support for EVAL- and DEV-Board.
 
+config BFIN548_EZKIT
+	bool "BF548-EZKIT"
+	depends on (BF548 || BF549)
+	  help
+	  BFIN548-EZKIT board Support.
+
 config BFIN561_BLUETECHNIX_CM
 	bool "Bluetechnix CM-BF561"
 	depends on (BF561)
@@ -265,6 +307,7 @@
 source "arch/blackfin/mach-bf533/Kconfig"
 source "arch/blackfin/mach-bf561/Kconfig"
 source "arch/blackfin/mach-bf537/Kconfig"
+source "arch/blackfin/mach-bf548/Kconfig"
 
 menu "Board customizations"
 
@@ -497,7 +540,8 @@
 
 config CACHELINE_ALIGNED_L1
 	bool "Locate cacheline_aligned data to L1 Data Memory"
-	default y
+	default y if !BF54x
+	default n if BF54x
 	depends on !BF531
 	help
 	  If enabled cacheline_anligned data is linked
@@ -541,9 +585,17 @@
 
 source "mm/Kconfig"
 
+config LARGE_ALLOCS
+	bool "Allow allocating large blocks (> 1MB) of memory"
+	help
+	  Allow the slab memory allocator to keep chains for very large
+	  memory sizes - upto 32MB. You may need this if your system has
+	  a lot of RAM, and you need to able to allocate very large
+	  contiguous chunks. If unsure, say N.
+
 config BFIN_DMA_5XX
 	bool "Enable DMA Support"
-	depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561)
+	depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561 || BF54x)
 	default y
 	help
 	  DMA driver for BF5xx.
@@ -686,6 +738,7 @@
 
 config C_CDPRIO
 	bool "DMA has priority over core for ext. accesses"
+	depends on !BF54x
 	default n
 
 config C_B0PEN
@@ -839,7 +892,7 @@
 
 endmenu
 
-if (BF537 || BF533)
+if (BF537 || BF533 || BF54x)
 
 menu "CPU Frequency scaling"
 
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
index 6971a44..1b75672 100644
--- a/arch/blackfin/Makefile
+++ b/arch/blackfin/Makefile
@@ -24,6 +24,8 @@
 machine-$(CONFIG_BF534) := bf537
 machine-$(CONFIG_BF536) := bf537
 machine-$(CONFIG_BF537) := bf537
+machine-$(CONFIG_BF548) := bf548
+machine-$(CONFIG_BF549) := bf548
 machine-$(CONFIG_BF561) := bf561
 MACHINE := $(machine-y)
 export MACHINE
diff --git a/arch/blackfin/boot/Makefile b/arch/blackfin/boot/Makefile
index 49e8098..8cd3356 100644
--- a/arch/blackfin/boot/Makefile
+++ b/arch/blackfin/boot/Makefile
@@ -13,7 +13,8 @@
 
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \
-                   -C gzip -a $(CONFIG_BOOT_LOAD) -e $(CONFIG_BOOT_LOAD) -n 'Linux-$(KERNELRELEASE)' \
+                   -C gzip -n 'Linux-$(KERNELRELEASE)' -a $(CONFIG_BOOT_LOAD) \
+                   -e $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}') \
                    -d $< $@
 
 $(obj)/vmlinux.bin: vmlinux FORCE
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
new file mode 100644
index 0000000..ac8390f
--- /dev/null
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -0,0 +1,1100 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21.5
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BLACKFIN=y
+CONFIG_ZONE_DMA=y
+CONFIG_BFIN=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_IRQCHIP_DEMUX_GPIO=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=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_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT 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_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
+# CONFIG_NP2 is not set
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# 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 is not set
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF536 is not set
+# CONFIG_BF537 is not set
+# CONFIG_BF542 is not set
+# CONFIG_BF544 is not set
+# CONFIG_BF548 is not set
+CONFIG_BF549=y
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_0_0=y
+# CONFIG_BF_REV_0_2 is not set
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+# CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_ANY is not set
+# CONFIG_BF_REV_NONE is not set
+CONFIG_BF54x=y
+CONFIG_BFIN_SINGLE_CORE=y
+# CONFIG_BFIN533_EZKIT is not set
+# CONFIG_BFIN533_STAMP is not set
+# CONFIG_BFIN537_STAMP is not set
+# CONFIG_BFIN533_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+CONFIG_BFIN548_EZKIT=y
+# CONFIG_BFIN561_BLUETECHNIX_CM is not set
+# CONFIG_BFIN561_EZKIT is not set
+# CONFIG_BFIN561_TEPLA is not set
+# CONFIG_PNAV10 is not set
+# CONFIG_GENERIC_BOARD is not set
+CONFIG_IRQ_PLL_WAKEUP=7
+CONFIG_IRQ_TIMER0=11
+CONFIG_IRQ_TIMER1=11
+CONFIG_IRQ_TIMER2=11
+CONFIG_IRQ_TIMER3=11
+CONFIG_IRQ_TIMER4=11
+CONFIG_IRQ_TIMER5=11
+CONFIG_IRQ_TIMER6=11
+CONFIG_IRQ_TIMER7=11
+CONFIG_IRQ_TIMER8=11
+CONFIG_IRQ_TIMER9=11
+CONFIG_IRQ_TIMER10=11
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+
+#
+# BF548 Specific Configuration
+#
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_DMAC0_ERR=7
+CONFIG_IRQ_EPPI0_ERR=7
+CONFIG_IRQ_SPORT0_ERR=7
+CONFIG_IRQ_SPORT1_ERR=7
+CONFIG_IRQ_SPI0_ERR=7
+CONFIG_IRQ_UART0_ERR=7
+CONFIG_IRQ_EPPI0=8
+CONFIG_IRQ_SPI0=10
+CONFIG_IRQ_PINT0=12
+CONFIG_IRQ_PINT1=12
+CONFIG_IRQ_MDMAS0=13
+CONFIG_IRQ_MDMAS1=13
+CONFIG_IRQ_WATCHDOG=13
+CONFIG_IRQ_DMAC1_ERR=7
+CONFIG_IRQ_SPORT2_ERR=7
+CONFIG_IRQ_SPORT3_ERR=7
+CONFIG_IRQ_MXVR_DATA=7
+CONFIG_IRQ_SPI1_ERR=7
+CONFIG_IRQ_SPI2_ERR=7
+CONFIG_IRQ_UART1_ERR=7
+CONFIG_IRQ_UART2_ERR=7
+CONFIG_IRQ_CAN0_ERR=7
+CONFIG_IRQ_SPORT2_RX=9
+CONFIG_IRQ_SPORT2_TX=9
+CONFIG_IRQ_SPORT3_RX=9
+CONFIG_IRQ_SPORT3_TX=9
+CONFIG_IRQ_EPPI1=9
+CONFIG_IRQ_EPPI2=9
+CONFIG_IRQ_SPI1=10
+CONFIG_IRQ_SPI2=10
+CONFIG_IRQ_ATAPI_RX=10
+CONFIG_IRQ_ATAPI_TX=10
+CONFIG_IRQ_TWI0=11
+CONFIG_IRQ_TWI1=11
+CONFIG_IRQ_CAN0_RX=11
+CONFIG_IRQ_CAN0_TX=11
+CONFIG_IRQ_MDMAS2=13
+CONFIG_IRQ_MDMAS3=13
+CONFIG_IRQ_MXVR_ERR=11
+CONFIG_IRQ_MXVR_MSG=11
+CONFIG_IRQ_MXVR_PKT=11
+CONFIG_IRQ_EPPI1_ERR=7
+CONFIG_IRQ_EPPI2_ERR=7
+CONFIG_IRQ_UART3_ERR=7
+CONFIG_IRQ_HOST_ERR=7
+CONFIG_IRQ_PIXC_ERR=7
+CONFIG_IRQ_NFC_ERR=7
+CONFIG_IRQ_ATAPI_ERR=7
+CONFIG_IRQ_CAN1_ERR=7
+CONFIG_IRQ_HS_DMA_ERR=7
+CONFIG_IRQ_PIXC_IN0=8
+CONFIG_IRQ_PIXC_IN1=8
+CONFIG_IRQ_PIXC_OUT=8
+CONFIG_IRQ_SDH=8
+CONFIG_IRQ_CNT=8
+CONFIG_IRQ_KEY=8
+CONFIG_IRQ_CAN1_RX=11
+CONFIG_IRQ_CAN1_TX=11
+CONFIG_IRQ_SDH_MASK0=11
+CONFIG_IRQ_SDH_MASK1=11
+CONFIG_IRQ_USB_INT0=11
+CONFIG_IRQ_USB_INT1=11
+CONFIG_IRQ_USB_INT2=11
+CONFIG_IRQ_USB_DMA=11
+CONFIG_IRQ_OTPSEC=11
+CONFIG_IRQ_PINT2=11
+CONFIG_IRQ_PINT3=11
+
+#
+# Board customizations
+#
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Board Setup
+#
+CONFIG_CLKIN_HZ=25000000
+CONFIG_MEM_SIZE=64
+CONFIG_MEM_ADD_WIDTH=10
+CONFIG_BOOT_LOAD=0x1000
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Timer Tick
+#
+# 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
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_EXCPT_IRQ_SYSC_L1=y
+CONFIG_DO_IRQ_L1=y
+CONFIG_CORE_TIMER_IRQ_L1=y
+CONFIG_IDLE_L1=y
+CONFIG_SCHEDULE_L1=y
+CONFIG_ARITHMETIC_OPS_L1=y
+CONFIG_ACCESS_OK_L1=y
+CONFIG_MEMSET_L1=y
+CONFIG_MEMCPY_L1=y
+CONFIG_SYS_BFIN_SPINLOCK_L1=y
+# CONFIG_IP_CHECKSUM_L1 is not set
+CONFIG_CACHELINE_ALIGNED_L1=y
+# CONFIG_SYSCALL_TAB_L1 is not set
+# CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL 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_LARGE_ALLOCS=y
+CONFIG_BFIN_DMA_5XX=y
+# CONFIG_DMA_UNCACHED_2M is not set
+CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BLKFIN_CACHE=y
+CONFIG_BLKFIN_DCACHE=y
+# CONFIG_BLKFIN_DCACHE_BANKA is not set
+# CONFIG_BLKFIN_CACHE_LOCK is not set
+# CONFIG_BLKFIN_WB is not set
+CONFIG_BLKFIN_WT=y
+CONFIG_L1_MAX_PIECE=16
+
+#
+# Clock Settings
+#
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+
+#
+# Asynchonous Memory Configuration
+#
+
+#
+# EBIU_AMBCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x7BB0
+CONFIG_BANK_1=0x7BB0
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0x99B3
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# 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 is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_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_NETLABEL 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_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_BF5xx is not set
+CONFIG_MTD_UCLINUX=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# 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)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_SMC91X is not set
+# CONFIG_SMSC911X is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_BF53X_PFBUTTONS is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_AD9960 is not set
+# CONFIG_SPI_ADC_BF533 is not set
+# CONFIG_BF5xx_PFLAGS is not set
+# CONFIG_BF5xx_PPIFCD is not set
+# CONFIG_BF5xx_TIMERS is not set
+# CONFIG_BF5xx_PPI is not set
+# CONFIG_BFIN_SPORT is not set
+# CONFIG_BFIN_TIMER_LATENCY is not set
+# CONFIG_BF5xx_FBDMA is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+# CONFIG_SERIAL_BFIN_DMA is not set
+CONFIG_SERIAL_BFIN_PIO=y
+# CONFIG_SERIAL_BFIN_UART0 is not set
+CONFIG_SERIAL_BFIN_UART1=y
+# CONFIG_BFIN_UART1_CTSRTS is not set
+# CONFIG_SERIAL_BFIN_UART2 is not set
+# CONFIG_SERIAL_BFIN_UART3 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# CAN, the car bus and industrial fieldbus
+#
+# CONFIG_CAN4LINUX is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# 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
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# 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 is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# 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
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+CONFIG_RTC_DRV_BFIN=y
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# PBX support
+#
+# CONFIG_PBX is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_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
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_YAFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD 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
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_DEBUG_HWERR=y
+# CONFIG_DEBUG_ICACHE_CHECK is not set
+# CONFIG_DEBUG_KERNEL_START is not set
+# CONFIG_DEBUG_SERIAL_EARLY_INIT is not set
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+CONFIG_CPLB_INFO=y
+CONFIG_ACCESS_CHECK=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITY_NETWORK is not set
+CONFIG_SECURITY_CAPABILITIES=y
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index f3b7d2f..f429ebc 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -6,9 +6,12 @@
 
 obj-y := \
 	entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
-	sys_bfin.o time.o traps.o irqchip.o dma-mapping.o bfin_gpio.o \
-	flat.o
+	sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
+	fixed_code.o cplbinit.o cacheinit.o
 
+obj-$(CONFIG_BF53x)		     += bfin_gpio.o
+obj-$(CONFIG_BF561)		     += bfin_gpio.o
 obj-$(CONFIG_MODULES)                += module.o
 obj-$(CONFIG_BFIN_DMA_5XX)           += bfin_dma_5xx.o
 obj-$(CONFIG_DUAL_CORE_TEST_MODULE)  += dualcore_test.o
+obj-$(CONFIG_KGDB)                   += kgdb.o
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
index e455f45..b56b274 100644
--- a/arch/blackfin/kernel/asm-offsets.c
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -32,11 +32,10 @@
 #include <linux/kernel_stat.h>
 #include <linux/ptrace.h>
 #include <linux/hardirq.h>
-#include <asm/irq.h>
-#include <asm/thread_info.h>
+#include <linux/irq.h>
+#include <linux/thread_info.h>
 
-#define DEFINE(sym, val) \
-        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
 
 int main(void)
 {
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 069a896..7cf02f0 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -34,6 +34,7 @@
 #include <linux/kernel.h>
 #include <linux/param.h>
 
+#include <asm/blackfin.h>
 #include <asm/dma.h>
 #include <asm/cacheflush.h>
 
@@ -45,67 +46,6 @@
 ***************************************************************************/
 
 static struct dma_channel dma_ch[MAX_BLACKFIN_DMA_CHANNEL];
-#if defined (CONFIG_BF561)
-static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
-	(struct dma_register *) DMA1_0_NEXT_DESC_PTR,
-	(struct dma_register *) DMA1_1_NEXT_DESC_PTR,
-	(struct dma_register *) DMA1_2_NEXT_DESC_PTR,
-	(struct dma_register *) DMA1_3_NEXT_DESC_PTR,
-	(struct dma_register *) DMA1_4_NEXT_DESC_PTR,
-	(struct dma_register *) DMA1_5_NEXT_DESC_PTR,
-	(struct dma_register *) DMA1_6_NEXT_DESC_PTR,
-	(struct dma_register *) DMA1_7_NEXT_DESC_PTR,
-	(struct dma_register *) DMA1_8_NEXT_DESC_PTR,
-	(struct dma_register *) DMA1_9_NEXT_DESC_PTR,
-	(struct dma_register *) DMA1_10_NEXT_DESC_PTR,
-	(struct dma_register *) DMA1_11_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_0_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_1_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_2_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_3_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_4_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_5_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_6_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_7_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_8_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_9_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_10_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_11_NEXT_DESC_PTR,
-	(struct dma_register *) MDMA1_D0_NEXT_DESC_PTR,
-	(struct dma_register *) MDMA1_S0_NEXT_DESC_PTR,
-	(struct dma_register *) MDMA1_D1_NEXT_DESC_PTR,
-	(struct dma_register *) MDMA1_S1_NEXT_DESC_PTR,
-	(struct dma_register *) MDMA2_D0_NEXT_DESC_PTR,
-	(struct dma_register *) MDMA2_S0_NEXT_DESC_PTR,
-	(struct dma_register *) MDMA2_D1_NEXT_DESC_PTR,
-	(struct dma_register *) MDMA2_S1_NEXT_DESC_PTR,
-	(struct dma_register *) IMDMA_D0_NEXT_DESC_PTR,
-	(struct dma_register *) IMDMA_S0_NEXT_DESC_PTR,
-	(struct dma_register *) IMDMA_D1_NEXT_DESC_PTR,
-	(struct dma_register *) IMDMA_S1_NEXT_DESC_PTR,
-};
-#else
-static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
-	(struct dma_register *) DMA0_NEXT_DESC_PTR,
-	(struct dma_register *) DMA1_NEXT_DESC_PTR,
-	(struct dma_register *) DMA2_NEXT_DESC_PTR,
-	(struct dma_register *) DMA3_NEXT_DESC_PTR,
-	(struct dma_register *) DMA4_NEXT_DESC_PTR,
-	(struct dma_register *) DMA5_NEXT_DESC_PTR,
-	(struct dma_register *) DMA6_NEXT_DESC_PTR,
-	(struct dma_register *) DMA7_NEXT_DESC_PTR,
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536))
-	(struct dma_register *) DMA8_NEXT_DESC_PTR,
-	(struct dma_register *) DMA9_NEXT_DESC_PTR,
-	(struct dma_register *) DMA10_NEXT_DESC_PTR,
-	(struct dma_register *) DMA11_NEXT_DESC_PTR,
-#endif
-	(struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
-	(struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
-	(struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
-	(struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
-};
-#endif
 
 /*------------------------------------------------------------------------------
  *       Set the Buffer Clear bit in the Configuration register of specific DMA
@@ -138,149 +78,6 @@
 
 arch_initcall(blackfin_dma_init);
 
-/*
- *	Form the channel find the irq number for that channel.
- */
-#if !defined(CONFIG_BF561)
-
-static int bf533_channel2irq(unsigned int channel)
-{
-	int ret_irq = -1;
-
-	switch (channel) {
-	case CH_PPI:
-		ret_irq = IRQ_PPI;
-		break;
-
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536))
-	case CH_EMAC_RX:
-		ret_irq = IRQ_MAC_RX;
-		break;
-
-	case CH_EMAC_TX:
-		ret_irq = IRQ_MAC_TX;
-		break;
-
-	case CH_UART1_RX:
-		ret_irq = IRQ_UART1_RX;
-		break;
-
-	case CH_UART1_TX:
-		ret_irq = IRQ_UART1_TX;
-		break;
-#endif
-
-	case CH_SPORT0_RX:
-		ret_irq = IRQ_SPORT0_RX;
-		break;
-
-	case CH_SPORT0_TX:
-		ret_irq = IRQ_SPORT0_TX;
-		break;
-
-	case CH_SPORT1_RX:
-		ret_irq = IRQ_SPORT1_RX;
-		break;
-
-	case CH_SPORT1_TX:
-		ret_irq = IRQ_SPORT1_TX;
-		break;
-
-	case CH_SPI:
-		ret_irq = IRQ_SPI;
-		break;
-
-	case CH_UART_RX:
-		ret_irq = IRQ_UART_RX;
-		break;
-
-	case CH_UART_TX:
-		ret_irq = IRQ_UART_TX;
-		break;
-
-	case CH_MEM_STREAM0_SRC:
-	case CH_MEM_STREAM0_DEST:
-		ret_irq = IRQ_MEM_DMA0;
-		break;
-
-	case CH_MEM_STREAM1_SRC:
-	case CH_MEM_STREAM1_DEST:
-		ret_irq = IRQ_MEM_DMA1;
-		break;
-	}
-	return ret_irq;
-}
-
-# define channel2irq(channel) bf533_channel2irq(channel)
-
-#else
-
-static int bf561_channel2irq(unsigned int channel)
-{
-	int ret_irq = -1;
-
-	switch (channel) {
-	case CH_PPI0:
-		ret_irq = IRQ_PPI0;
-		break;
-	case CH_PPI1:
-		ret_irq = IRQ_PPI1;
-		break;
-	case CH_SPORT0_RX:
-		ret_irq = IRQ_SPORT0_RX;
-		break;
-	case CH_SPORT0_TX:
-		ret_irq = IRQ_SPORT0_TX;
-		break;
-	case CH_SPORT1_RX:
-		ret_irq = IRQ_SPORT1_RX;
-		break;
-	case CH_SPORT1_TX:
-		ret_irq = IRQ_SPORT1_TX;
-		break;
-	case CH_SPI:
-		ret_irq = IRQ_SPI;
-		break;
-	case CH_UART_RX:
-		ret_irq = IRQ_UART_RX;
-		break;
-	case CH_UART_TX:
-		ret_irq = IRQ_UART_TX;
-		break;
-
-	case CH_MEM_STREAM0_SRC:
-	case CH_MEM_STREAM0_DEST:
-		ret_irq = IRQ_MEM_DMA0;
-		break;
-	case CH_MEM_STREAM1_SRC:
-	case CH_MEM_STREAM1_DEST:
-		ret_irq = IRQ_MEM_DMA1;
-		break;
-	case CH_MEM_STREAM2_SRC:
-	case CH_MEM_STREAM2_DEST:
-		ret_irq = IRQ_MEM_DMA2;
-		break;
-	case CH_MEM_STREAM3_SRC:
-	case CH_MEM_STREAM3_DEST:
-		ret_irq = IRQ_MEM_DMA3;
-		break;
-
-	case CH_IMEM_STREAM0_SRC:
-	case CH_IMEM_STREAM0_DEST:
-		ret_irq = IRQ_IMEM_DMA0;
-		break;
-	case CH_IMEM_STREAM1_SRC:
-	case CH_IMEM_STREAM1_DEST:
-		ret_irq = IRQ_IMEM_DMA1;
-		break;
-	}
-	return ret_irq;
-}
-
-# define channel2irq(channel) bf561_channel2irq(channel)
-
-#endif
-
 /*------------------------------------------------------------------------------
  *	Request the specific DMA channel from the system.
  *-----------------------------------------------------------------------------*/
@@ -535,7 +332,7 @@
 }
 EXPORT_SYMBOL(set_bfin_dma_config);
 
-void set_dma_sg(unsigned int channel, struct dmasg * sg, int nr_sg)
+void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg)
 {
 	BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
 	       && channel < MAX_BLACKFIN_DMA_CHANNEL));
@@ -604,7 +401,7 @@
 
 	if (size <= 0)
 		return NULL;
-	
+
 	local_irq_save(flags);
 
 	if ((unsigned long)src < memory_end)
@@ -748,7 +545,6 @@
 	addr = __dma_memcpy(dest+bulk, src+bulk, rest);
 	return addr;
 }
-
 EXPORT_SYMBOL(dma_memcpy);
 
 void *safe_dma_memcpy(void *dest, const void *src, size_t size)
@@ -761,14 +557,13 @@
 
 void dma_outsb(void __iomem *addr, const void *buf, unsigned short len)
 {
-
 	unsigned long flags;
-	
-	local_irq_save(flags);
-	
-	blackfin_dcache_flush_range((unsigned int)buf,(unsigned int)(buf) + len);
 
-   	bfin_write_MDMA_D0_START_ADDR(addr);
+	local_irq_save(flags);
+
+	blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
+
+	bfin_write_MDMA_D0_START_ADDR(addr);
 	bfin_write_MDMA_D0_X_COUNT(len);
 	bfin_write_MDMA_D0_X_MODIFY(0);
 	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -796,9 +591,9 @@
 void dma_insb(const void __iomem *addr, void *buf, unsigned short len)
 {
 	unsigned long flags;
-		
+
 	local_irq_save(flags);
-   	bfin_write_MDMA_D0_START_ADDR(buf);
+	bfin_write_MDMA_D0_START_ADDR(buf);
 	bfin_write_MDMA_D0_X_COUNT(len);
 	bfin_write_MDMA_D0_X_MODIFY(1);
 	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -827,12 +622,12 @@
 void dma_outsw(void __iomem *addr, const void  *buf, unsigned short len)
 {
 	unsigned long flags;
-	
-	local_irq_save(flags);
-		
-	blackfin_dcache_flush_range((unsigned int)buf,(unsigned int)(buf) + len);
 
-   	bfin_write_MDMA_D0_START_ADDR(addr);
+	local_irq_save(flags);
+
+	blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
+
+	bfin_write_MDMA_D0_START_ADDR(addr);
 	bfin_write_MDMA_D0_X_COUNT(len);
 	bfin_write_MDMA_D0_X_MODIFY(0);
 	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -859,10 +654,10 @@
 void dma_insw(const void __iomem *addr, void *buf, unsigned short len)
 {
 	unsigned long flags;
-		
+
 	local_irq_save(flags);
-	
-   	bfin_write_MDMA_D0_START_ADDR(buf);
+
+	bfin_write_MDMA_D0_START_ADDR(buf);
 	bfin_write_MDMA_D0_X_COUNT(len);
 	bfin_write_MDMA_D0_X_MODIFY(2);
 	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -891,12 +686,12 @@
 void dma_outsl(void __iomem *addr, const void *buf, unsigned short len)
 {
 	unsigned long flags;
-	
-	local_irq_save(flags);
-	
-	blackfin_dcache_flush_range((unsigned int)buf,(unsigned int)(buf) + len);
 
-   	bfin_write_MDMA_D0_START_ADDR(addr);
+	local_irq_save(flags);
+
+	blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
+
+	bfin_write_MDMA_D0_START_ADDR(addr);
 	bfin_write_MDMA_D0_X_COUNT(len);
 	bfin_write_MDMA_D0_X_MODIFY(0);
 	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -923,10 +718,10 @@
 void dma_insl(const void __iomem *addr, void *buf, unsigned short len)
 {
 	unsigned long flags;
-	
+
 	local_irq_save(flags);
-	
-   	bfin_write_MDMA_D0_START_ADDR(buf);
+
+	bfin_write_MDMA_D0_START_ADDR(buf);
 	bfin_write_MDMA_D0_X_COUNT(len);
 	bfin_write_MDMA_D0_X_MODIFY(4);
 	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index bb1f4fb..bafcfa5 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -162,7 +162,7 @@
 
 static void default_gpio(unsigned short gpio)
 {
-	unsigned short bank,bitmask;
+	unsigned short bank, bitmask;
 
 	bank = gpio_bank(gpio);
 	bitmask = gpio_bit(gpio);
@@ -183,7 +183,7 @@
 
 	printk(KERN_INFO "Blackfin GPIO Controller\n");
 
-	for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE)
+	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE)
 		reserved_map[gpio_bank(i)] = 0;
 
 #if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
@@ -478,7 +478,7 @@
 	u32 sic_iwr = 0;
 	u16 bank, mask, i, gpio;
 
-	for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) {
+	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
 		mask = wakeup_map[gpio_bank(i)];
 		bank = gpio_bank(i);
 
@@ -522,12 +522,11 @@
 		return IWR_ENABLE_ALL;
 }
 
-
 void gpio_pm_restore(void)
 {
 	u16 bank, mask, i;
 
-	for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) {
+	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
 		mask = wakeup_map[gpio_bank(i)];
 		bank = gpio_bank(i);
 
@@ -591,7 +590,6 @@
 }
 EXPORT_SYMBOL(gpio_request);
 
-
 void gpio_free(unsigned short gpio)
 {
 	unsigned long flags;
@@ -616,7 +614,6 @@
 }
 EXPORT_SYMBOL(gpio_free);
 
-
 void gpio_direction_input(unsigned short gpio)
 {
 	unsigned long flags;
diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c
index f64ecb6..7045594 100644
--- a/arch/blackfin/kernel/bfin_ksyms.c
+++ b/arch/blackfin/kernel/bfin_ksyms.c
@@ -28,10 +28,11 @@
  */
 
 #include <linux/module.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
+#include <linux/uaccess.h>
+
 #include <asm/checksum.h>
 #include <asm/cacheflush.h>
-#include <asm/uaccess.h>
 
 /* platform dependent support */
 
diff --git a/arch/blackfin/kernel/cacheinit.c b/arch/blackfin/kernel/cacheinit.c
new file mode 100644
index 0000000..4d41a40
--- /dev/null
+++ b/arch/blackfin/kernel/cacheinit.c
@@ -0,0 +1,66 @@
+/*
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/cpu.h>
+
+#include <asm/cacheflush.h>
+#include <asm/blackfin.h>
+#include <asm/cplbinit.h>
+
+#if defined(CONFIG_BLKFIN_CACHE)
+void bfin_icache_init(void)
+{
+	unsigned long *table = icplb_table;
+	unsigned long ctrl;
+	int i;
+
+	for (i = 0; i < MAX_CPLBS; i++) {
+		unsigned long addr = *table++;
+		unsigned long data = *table++;
+		if (addr == (unsigned long)-1)
+			break;
+		bfin_write32(ICPLB_ADDR0 + i * 4, addr);
+		bfin_write32(ICPLB_DATA0 + i * 4, data);
+	}
+	ctrl = bfin_read_IMEM_CONTROL();
+	ctrl |= IMC | ENICPLB;
+	bfin_write_IMEM_CONTROL(ctrl);
+}
+#endif
+
+#if defined(CONFIG_BLKFIN_DCACHE)
+void bfin_dcache_init(void)
+{
+	unsigned long *table = dcplb_table;
+	unsigned long ctrl;
+	int i;
+
+	for (i = 0; i < MAX_CPLBS; i++) {
+		unsigned long addr = *table++;
+		unsigned long data = *table++;
+		if (addr == (unsigned long)-1)
+			break;
+		bfin_write32(DCPLB_ADDR0 + i * 4, addr);
+		bfin_write32(DCPLB_DATA0 + i * 4, data);
+	}
+	ctrl = bfin_read_DMEM_CONTROL();
+	ctrl |= DMEM_CNTR;
+	bfin_write_DMEM_CONTROL(ctrl);
+}
+#endif
diff --git a/arch/blackfin/kernel/cplbinit.c b/arch/blackfin/kernel/cplbinit.c
new file mode 100644
index 0000000..bbdb403
--- /dev/null
+++ b/arch/blackfin/kernel/cplbinit.c
@@ -0,0 +1,433 @@
+/*
+ * Blackfin CPLB initialization
+ *
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/module.h>
+
+#include <asm/blackfin.h>
+#include <asm/cplbinit.h>
+
+u_long icplb_table[MAX_CPLBS+1];
+u_long dcplb_table[MAX_CPLBS+1];
+
+#ifdef CONFIG_CPLB_SWITCH_TAB_L1
+u_long ipdt_table[MAX_SWITCH_I_CPLBS+1]__attribute__((l1_data));
+u_long dpdt_table[MAX_SWITCH_D_CPLBS+1]__attribute__((l1_data));
+
+#ifdef CONFIG_CPLB_INFO
+u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS]__attribute__((l1_data));
+u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS]__attribute__((l1_data));
+#endif /* CONFIG_CPLB_INFO */
+
+#else
+
+u_long ipdt_table[MAX_SWITCH_I_CPLBS+1];
+u_long dpdt_table[MAX_SWITCH_D_CPLBS+1];
+
+#ifdef CONFIG_CPLB_INFO
+u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS];
+u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS];
+#endif /* CONFIG_CPLB_INFO */
+
+#endif /*CONFIG_CPLB_SWITCH_TAB_L1*/
+
+struct s_cplb {
+	struct cplb_tab init_i;
+	struct cplb_tab init_d;
+	struct cplb_tab switch_i;
+	struct cplb_tab switch_d;
+};
+
+#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
+static struct cplb_desc cplb_data[] = {
+	{
+		.start = 0,
+		.end = SIZE_1K,
+		.psize = SIZE_1K,
+		.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
+		.i_conf = SDRAM_OOPS,
+		.d_conf = SDRAM_OOPS,
+#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO)
+		.valid = 1,
+#else
+		.valid = 0,
+#endif
+		.name = "ZERO Pointer Saveguard",
+	},
+	{
+		.start = L1_CODE_START,
+		.end = L1_CODE_START + L1_CODE_LENGTH,
+		.psize = SIZE_4M,
+		.attr = INITIAL_T | SWITCH_T | I_CPLB,
+		.i_conf = L1_IMEMORY,
+		.d_conf = 0,
+		.valid = 1,
+		.name = "L1 I-Memory",
+	},
+	{
+		.start = L1_DATA_A_START,
+		.end = L1_DATA_B_START + L1_DATA_B_LENGTH,
+		.psize = SIZE_4M,
+		.attr = INITIAL_T | SWITCH_T | D_CPLB,
+		.i_conf = 0,
+		.d_conf = L1_DMEMORY,
+#if ((L1_DATA_A_LENGTH > 0) || (L1_DATA_B_LENGTH > 0))
+		.valid = 1,
+#else
+		.valid = 0,
+#endif
+		.name = "L1 D-Memory",
+	},
+	{
+		.start = 0,
+		.end = 0,  /* dynamic */
+		.psize = 0,
+		.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
+		.i_conf =  SDRAM_IGENERIC,
+		.d_conf =  SDRAM_DGENERIC,
+		.valid = 1,
+		.name = "SDRAM Kernel",
+	},
+	{
+		.start = 0, /* dynamic */
+		.end = 0, /* dynamic */
+		.psize = 0,
+		.attr = INITIAL_T | SWITCH_T | D_CPLB,
+		.i_conf =  SDRAM_IGENERIC,
+		.d_conf =  SDRAM_DNON_CHBL,
+		.valid = 1,
+		.name = "SDRAM RAM MTD",
+	},
+	{
+		.start = 0, /* dynamic */
+		.end = 0,   /* dynamic */
+		.psize = SIZE_1M,
+		.attr = INITIAL_T | SWITCH_T | D_CPLB,
+		.d_conf = SDRAM_DNON_CHBL,
+		.valid = 1,
+		.name = "SDRAM Uncached DMA ZONE",
+	},
+	{
+		.start = 0, /* dynamic */
+		.end = 0, /* dynamic */
+		.psize = 0,
+		.attr = SWITCH_T | D_CPLB,
+		.i_conf = 0, /* dynamic */
+		.d_conf = 0, /* dynamic */
+		.valid = 1,
+		.name = "SDRAM Reserved Memory",
+	},
+	{
+		.start = ASYNC_BANK0_BASE,
+		.end = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE,
+		.psize = 0,
+		.attr = SWITCH_T | D_CPLB,
+		.d_conf = SDRAM_EBIU,
+		.valid = 1,
+		.name = "ASYNC Memory",
+	},
+	{
+#if defined(CONFIG_BF561)
+		.start = L2_SRAM,
+		.end = L2_SRAM_END,
+		.psize = SIZE_1M,
+		.attr = SWITCH_T | D_CPLB,
+		.i_conf = L2_MEMORY,
+		.d_conf = L2_MEMORY,
+		.valid = 1,
+#else
+		.valid = 0,
+#endif
+		.name = "L2 Memory",
+	}
+};
+
+static u16 __init lock_kernel_check(u32 start, u32 end)
+{
+	if ((start <= (u32) _stext && end >= (u32) _end)
+	    || (start >= (u32) _stext && end <= (u32) _end))
+		return IN_KERNEL;
+	return 0;
+}
+
+static unsigned short __init
+fill_cplbtab(struct cplb_tab *table,
+	     unsigned long start, unsigned long end,
+	     unsigned long block_size, unsigned long cplb_data)
+{
+	int i;
+
+	switch (block_size) {
+	case SIZE_4M:
+		i = 3;
+		break;
+	case SIZE_1M:
+		i = 2;
+		break;
+	case SIZE_4K:
+		i = 1;
+		break;
+	case SIZE_1K:
+	default:
+		i = 0;
+		break;
+	}
+
+	cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
+
+	while ((start < end) && (table->pos < table->size)) {
+
+		table->tab[table->pos++] = start;
+
+		if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
+			table->tab[table->pos++] =
+			    cplb_data | CPLB_LOCK | CPLB_DIRTY;
+		else
+			table->tab[table->pos++] = cplb_data;
+
+		start += block_size;
+	}
+	return 0;
+}
+
+static unsigned short __init
+close_cplbtab(struct cplb_tab *table)
+{
+
+	while (table->pos < table->size) {
+
+		table->tab[table->pos++] = 0;
+		table->tab[table->pos++] = 0; /* !CPLB_VALID */
+	}
+	return 0;
+}
+
+/* helper function */
+static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
+{
+	if (cplb_data[i].psize) {
+		fill_cplbtab(t,
+				cplb_data[i].start,
+				cplb_data[i].end,
+				cplb_data[i].psize,
+				cplb_data[i].i_conf);
+	} else {
+#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
+		if (i == SDRAM_KERN) {
+			fill_cplbtab(t,
+					cplb_data[i].start,
+					cplb_data[i].end,
+					SIZE_4M,
+					cplb_data[i].i_conf);
+		} else
+#endif
+		{
+			fill_cplbtab(t,
+					cplb_data[i].start,
+					a_start,
+					SIZE_1M,
+					cplb_data[i].i_conf);
+			fill_cplbtab(t,
+					a_start,
+					a_end,
+					SIZE_4M,
+					cplb_data[i].i_conf);
+			fill_cplbtab(t, a_end,
+					cplb_data[i].end,
+					SIZE_1M,
+					cplb_data[i].i_conf);
+		}
+	}
+}
+
+static void __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
+{
+	if (cplb_data[i].psize) {
+		fill_cplbtab(t,
+				cplb_data[i].start,
+				cplb_data[i].end,
+				cplb_data[i].psize,
+				cplb_data[i].d_conf);
+	} else {
+		fill_cplbtab(t,
+				cplb_data[i].start,
+				a_start, SIZE_1M,
+				cplb_data[i].d_conf);
+		fill_cplbtab(t, a_start,
+				a_end, SIZE_4M,
+				cplb_data[i].d_conf);
+		fill_cplbtab(t, a_end,
+				cplb_data[i].end,
+				SIZE_1M,
+				cplb_data[i].d_conf);
+	}
+}
+
+void __init generate_cpl_tables(void)
+{
+
+	u16 i, j, process;
+	u32 a_start, a_end, as, ae, as_1m;
+
+	struct cplb_tab *t_i = NULL;
+	struct cplb_tab *t_d = NULL;
+	struct s_cplb cplb;
+
+	cplb.init_i.size = MAX_CPLBS;
+	cplb.init_d.size = MAX_CPLBS;
+	cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
+	cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
+
+	cplb.init_i.pos = 0;
+	cplb.init_d.pos = 0;
+	cplb.switch_i.pos = 0;
+	cplb.switch_d.pos = 0;
+
+	cplb.init_i.tab = icplb_table;
+	cplb.init_d.tab = dcplb_table;
+	cplb.switch_i.tab = ipdt_table;
+	cplb.switch_d.tab = dpdt_table;
+
+	cplb_data[SDRAM_KERN].end = memory_end;
+
+#ifdef CONFIG_MTD_UCLINUX
+	cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
+	cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
+	cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
+# if defined(CONFIG_ROMFS_FS)
+	cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
+
+	/*
+	 * The ROMFS_FS size is often not multiple of 1MB.
+	 * This can cause multiple CPLB sets covering the same memory area.
+	 * This will then cause multiple CPLB hit exceptions.
+	 * Workaround: We ensure a contiguous memory area by extending the kernel
+	 * memory section over the mtd section.
+	 * For ROMFS_FS memory must be covered with ICPLBs anyways.
+	 * So there is no difference between kernel and mtd memory setup.
+	 */
+
+	cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
+	cplb_data[SDRAM_RAM_MTD].valid = 0;
+
+# endif
+#else
+	cplb_data[SDRAM_RAM_MTD].valid = 0;
+#endif
+
+	cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
+	cplb_data[SDRAM_DMAZ].end = _ramend;
+
+	cplb_data[RES_MEM].start = _ramend;
+	cplb_data[RES_MEM].end = physical_mem_end;
+
+	if (reserved_mem_dcache_on)
+		cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
+	else
+		cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
+
+	if (reserved_mem_icache_on)
+		cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
+	else
+		cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
+
+	for (i = ZERO_P; i <= L2_MEM; i++) {
+		if (!cplb_data[i].valid)
+			continue;
+
+		as_1m = cplb_data[i].start % SIZE_1M;
+
+		/* We need to make sure all sections are properly 1M aligned
+		 * However between Kernel Memory and the Kernel mtd section, depending on the
+		 * rootfs size, there can be overlapping memory areas.
+		 */
+
+		if (as_1m && i != L1I_MEM && i != L1D_MEM) {
+#ifdef CONFIG_MTD_UCLINUX
+			if (i == SDRAM_RAM_MTD) {
+				if ((cplb_data[SDRAM_KERN].end + 1) > cplb_data[SDRAM_RAM_MTD].start)
+					cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M)) + SIZE_1M;
+				else
+					cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M));
+			} else
+#endif
+				printk(KERN_WARNING "Unaligned Start of %s at 0x%X\n",
+				       cplb_data[i].name, cplb_data[i].start);
+		}
+
+		as = cplb_data[i].start % SIZE_4M;
+		ae = cplb_data[i].end % SIZE_4M;
+
+		if (as)
+			a_start = cplb_data[i].start + (SIZE_4M - (as));
+		else
+			a_start = cplb_data[i].start;
+
+		a_end = cplb_data[i].end - ae;
+
+		for (j = INITIAL_T; j <= SWITCH_T; j++) {
+
+			switch (j) {
+			case INITIAL_T:
+				if (cplb_data[i].attr & INITIAL_T) {
+					t_i = &cplb.init_i;
+					t_d = &cplb.init_d;
+					process = 1;
+				} else
+					process = 0;
+				break;
+			case SWITCH_T:
+				if (cplb_data[i].attr & SWITCH_T) {
+					t_i = &cplb.switch_i;
+					t_d = &cplb.switch_d;
+					process = 1;
+				} else
+					process = 0;
+				break;
+			default:
+					process = 0;
+				break;
+			}
+
+			if (!process)
+				continue;
+			if (cplb_data[i].attr & I_CPLB)
+				__fill_code_cplbtab(t_i, i, a_start, a_end);
+
+			if (cplb_data[i].attr & D_CPLB)
+				__fill_data_cplbtab(t_d, i, a_start, a_end);
+		}
+	}
+
+/* close tables */
+
+	close_cplbtab(&cplb.init_i);
+	close_cplbtab(&cplb.init_d);
+
+	cplb.init_i.tab[cplb.init_i.pos] = -1;
+	cplb.init_d.tab[cplb.init_d.pos] = -1;
+	cplb.switch_i.tab[cplb.switch_i.pos] = -1;
+	cplb.switch_d.tab[cplb.switch_d.pos] = -1;
+
+}
+
+#endif
+
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index 539eb24..ea48d5b1 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -34,8 +34,8 @@
 #include <linux/spinlock.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <linux/io.h>
 #include <asm/cacheflush.h>
-#include <asm/io.h>
 #include <asm/bfin-global.h>
 
 static spinlock_t dma_page_lock;
@@ -159,10 +159,13 @@
 
 	BUG_ON(direction == DMA_NONE);
 
-	for (i = 0; i < nents; i++)
-		invalidate_dcache_range(sg_dma_address(&sg[i]),
-					sg_dma_address(&sg[i]) +
-					sg_dma_len(&sg[i]));
+	for (i = 0; i < nents; i++, sg++) {
+		sg->dma_address = page_address(sg->page) + sg->offset;
+
+		invalidate_dcache_range(sg_dma_address(sg),
+					sg_dma_address(sg) +
+					sg_dma_len(sg));
+	}
 
 	return nents;
 }
diff --git a/arch/blackfin/kernel/dualcore_test.c b/arch/blackfin/kernel/dualcore_test.c
index 8b89c99..0fcba74 100644
--- a/arch/blackfin/kernel/dualcore_test.c
+++ b/arch/blackfin/kernel/dualcore_test.c
@@ -30,19 +30,19 @@
 #include <linux/init.h>
 #include <linux/module.h>
 
-static int *testarg = (int*)0xfeb00000;
+static int *testarg = (int *)0xfeb00000;
 
 static int test_init(void)
 {
 	*testarg = 1;
-	printk("Dual core test module inserted: set testarg = [%d]\n @ [%p]\n",
+	printk(KERN_INFO "Dual core test module inserted: set testarg = [%d]\n @ [%p]\n",
 	       *testarg, testarg);
 	return 0;
 }
 
 static void test_exit(void)
 {
-	printk("Dual core test module removed: testarg = [%d]\n", *testarg);
+	printk(KERN_INFO "Dual core test module removed: testarg = [%d]\n", *testarg);
 }
 
 module_init(test_init);
diff --git a/arch/blackfin/kernel/fixed_code.S b/arch/blackfin/kernel/fixed_code.S
new file mode 100644
index 0000000..d8b1ebc
--- /dev/null
+++ b/arch/blackfin/kernel/fixed_code.S
@@ -0,0 +1,132 @@
+/*
+ * This file contains sequences of code that will be copied to a
+ * fixed location, defined in <asm/atomic_seq.h>.  The interrupt
+ * handlers ensure that these sequences appear to be atomic when
+ * executed from userspace.
+ * These are aligned to 16 bytes, so that we have some space to replace
+ * these sequences with something else (e.g. kernel traps if we ever do
+ * BF561 SMP).
+ */
+#include <linux/linkage.h>
+#include <linux/unistd.h>
+#include <asm/entry.h>
+
+.text
+ENTRY(_fixed_code_start)
+
+.align 16
+ENTRY(_sigreturn_stub)
+	P0 = __NR_rt_sigreturn;
+	EXCPT 0;
+	/* Speculative execution paranoia.  */
+0:	JUMP.S 0b;
+ENDPROC (_sigreturn_stub)
+
+.align 16
+	/*
+	 * Atomic swap, 8 bit.
+	 * Inputs:	P0: memory address to use
+	 *		R1: value to store
+	 * Output:	R0: old contents of the memory address, zero extended.
+	 */
+ENTRY(_atomic_xchg32)
+	R0 = [P0];
+	[P0] = R1;
+	rts;
+ENDPROC (_atomic_xchg32)
+
+.align 16
+	/*
+	 * Compare and swap, 32 bit.
+	 * Inputs:	P0: memory address to use
+	 *		R1: compare value
+	 *		R2: new value to store
+	 * The new value is stored if the contents of the memory
+	 * address is equal to the compare value.
+	 * Output:	R0: old contents of the memory address.
+	 */
+ENTRY(_atomic_cas32)
+	R0 = [P0];
+	CC = R0 == R1;
+	IF !CC JUMP 1f;
+	[P0] = R2;
+1:
+	rts;
+ENDPROC (_atomic_cas32)
+
+.align 16
+	/*
+	 * Atomic add, 32 bit.
+	 * Inputs:	P0: memory address to use
+	 *		R0: value to add
+	 * Outputs:	R0: new contents of the memory address.
+	 *		R1: previous contents of the memory address.
+	 */
+ENTRY(_atomic_add32)
+	R1 = [P0];
+	R0 = R1 + R0;
+	[P0] = R0;
+	rts;
+ENDPROC (_atomic_add32)
+
+.align 16
+	/*
+	 * Atomic sub, 32 bit.
+	 * Inputs:	P0: memory address to use
+	 *		R0: value to subtract
+	 * Outputs:	R0: new contents of the memory address.
+	 *		R1: previous contents of the memory address.
+	 */
+ENTRY(_atomic_sub32)
+	R1 = [P0];
+	R0 = R1 - R0;
+	[P0] = R0;
+	rts;
+ENDPROC (_atomic_sub32)
+
+.align 16
+	/*
+	 * Atomic ior, 32 bit.
+	 * Inputs:	P0: memory address to use
+	 *		R0: value to ior
+	 * Outputs:	R0: new contents of the memory address.
+	 *		R1: previous contents of the memory address.
+	 */
+ENTRY(_atomic_ior32)
+	R1 = [P0];
+	R0 = R1 | R0;
+	[P0] = R0;
+	rts;
+ENDPROC (_atomic_ior32)
+
+.align 16
+	/*
+	 * Atomic ior, 32 bit.
+	 * Inputs:	P0: memory address to use
+	 *		R0: value to ior
+	 * Outputs:	R0: new contents of the memory address.
+	 *		R1: previous contents of the memory address.
+	 */
+ENTRY(_atomic_and32)
+	R1 = [P0];
+	R0 = R1 & R0;
+	[P0] = R0;
+	rts;
+ENDPROC (_atomic_ior32)
+
+.align 16
+	/*
+	 * Atomic ior, 32 bit.
+	 * Inputs:	P0: memory address to use
+	 *		R0: value to ior
+	 * Outputs:	R0: new contents of the memory address.
+	 *		R1: previous contents of the memory address.
+	 */
+ENTRY(_atomic_xor32)
+	R1 = [P0];
+	R0 = R1 ^ R0;
+	[P0] = R0;
+	rts;
+ENDPROC (_atomic_ior32)
+
+ENTRY(_fixed_code_end)
diff --git a/arch/blackfin/kernel/flat.c b/arch/blackfin/kernel/flat.c
index a92587b..d188b24 100644
--- a/arch/blackfin/kernel/flat.c
+++ b/arch/blackfin/kernel/flat.c
@@ -36,24 +36,22 @@
 	unsigned long val;
 
 	switch (type) {
-		case FLAT_BFIN_RELOC_TYPE_16_BIT:
-		case FLAT_BFIN_RELOC_TYPE_16H_BIT:
-			usptr = (unsigned short *)ptr;
-			pr_debug("*usptr = %x", get_unaligned(usptr));
-			val = get_unaligned(usptr);
-			val += *persistent;
-			break;
+	case FLAT_BFIN_RELOC_TYPE_16_BIT:
+	case FLAT_BFIN_RELOC_TYPE_16H_BIT:
+		usptr = (unsigned short *)ptr;
+		pr_debug("*usptr = %x", get_unaligned(usptr));
+		val = get_unaligned(usptr);
+		val += *persistent;
+		break;
 
-		case FLAT_BFIN_RELOC_TYPE_32_BIT:
-			pr_debug("*ptr = %lx", get_unaligned(ptr));
-			val = get_unaligned(ptr);
-			break;
+	case FLAT_BFIN_RELOC_TYPE_32_BIT:
+		pr_debug("*ptr = %lx", get_unaligned(ptr));
+		val = get_unaligned(ptr);
+		break;
 
-		default:
-			pr_debug("BINFMT_FLAT: Unknown relocation type %x\n",
-				type);
-
-			return 0;
+	default:
+		pr_debug("BINFMT_FLAT: Unknown relocation type %x\n", type);
+		return 0;
 	}
 
 	/*
@@ -81,21 +79,20 @@
 	int type = (relval >> 26) & 7;
 
 	switch (type) {
-		case FLAT_BFIN_RELOC_TYPE_16_BIT:
-			put_unaligned(addr, usptr);
-			pr_debug("new value %x at %p", get_unaligned(usptr),
-				usptr);
-			break;
+	case FLAT_BFIN_RELOC_TYPE_16_BIT:
+		put_unaligned(addr, usptr);
+		pr_debug("new value %x at %p", get_unaligned(usptr), usptr);
+		break;
 
-		case FLAT_BFIN_RELOC_TYPE_16H_BIT:
-			put_unaligned(addr >> 16, usptr);
-			pr_debug("new value %x", get_unaligned(usptr));
-			break;
+	case FLAT_BFIN_RELOC_TYPE_16H_BIT:
+		put_unaligned(addr >> 16, usptr);
+		pr_debug("new value %x", get_unaligned(usptr));
+		break;
 
-		case FLAT_BFIN_RELOC_TYPE_32_BIT:
-			put_unaligned(addr, ptr);
-			pr_debug("new ptr =%lx", get_unaligned(ptr));
-			break;
+	case FLAT_BFIN_RELOC_TYPE_32_BIT:
+		put_unaligned(addr, ptr);
+		pr_debug("new ptr =%lx", get_unaligned(ptr));
+		break;
 	}
 }
 EXPORT_SYMBOL(bfin_put_addr_at_rp);
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 80996a1..1fc001c7 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -82,7 +82,7 @@
 			seq_printf(p, ", %s", action->name);
 
 		seq_putc(p, '\n');
-	      unlock:
+ unlock:
 		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	} else if (i == NR_IRQS) {
 		seq_printf(p, "Err: %10lu\n", irq_err_count);
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c
new file mode 100644
index 0000000..a9c1551
--- /dev/null
+++ b/arch/blackfin/kernel/kgdb.c
@@ -0,0 +1,421 @@
+/*
+ * File:         arch/blackfin/kernel/kgdb.c
+ * Based on:
+ * Author:       Sonic Zhang
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:          $Id: kgdb_bfin_linux-2.6.x.patch 4934 2007-02-13 09:32:11Z sonicz $
+ *
+ * Modified:
+ *               Copyright 2005-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/ptrace.h>		/* for linux pt_regs struct */
+#include <linux/kgdb.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/debugger.h>
+#include <linux/errno.h>
+#include <linux/irq.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/blackfin.h>
+
+/* Put the error code here just in case the user cares.  */
+int gdb_bf533errcode;
+/* Likewise, the vector number here (since GDB only gets the signal
+   number through the usual means, and that's not very specific).  */
+int gdb_bf533vector = -1;
+
+#if KGDB_MAX_NO_CPUS != 8
+#error change the definition of slavecpulocks
+#endif
+
+void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+	gdb_regs[BFIN_R0] = regs->r0;
+	gdb_regs[BFIN_R1] = regs->r1;
+	gdb_regs[BFIN_R2] = regs->r2;
+	gdb_regs[BFIN_R3] = regs->r3;
+	gdb_regs[BFIN_R4] = regs->r4;
+	gdb_regs[BFIN_R5] = regs->r5;
+	gdb_regs[BFIN_R6] = regs->r6;
+	gdb_regs[BFIN_R7] = regs->r7;
+	gdb_regs[BFIN_P0] = regs->p0;
+	gdb_regs[BFIN_P1] = regs->p1;
+	gdb_regs[BFIN_P2] = regs->p2;
+	gdb_regs[BFIN_P3] = regs->p3;
+	gdb_regs[BFIN_P4] = regs->p4;
+	gdb_regs[BFIN_P5] = regs->p5;
+	gdb_regs[BFIN_SP] = regs->reserved;
+	gdb_regs[BFIN_FP] = regs->fp;
+	gdb_regs[BFIN_I0] = regs->i0;
+	gdb_regs[BFIN_I1] = regs->i1;
+	gdb_regs[BFIN_I2] = regs->i2;
+	gdb_regs[BFIN_I3] = regs->i3;
+	gdb_regs[BFIN_M0] = regs->m0;
+	gdb_regs[BFIN_M1] = regs->m1;
+	gdb_regs[BFIN_M2] = regs->m2;
+	gdb_regs[BFIN_M3] = regs->m3;
+	gdb_regs[BFIN_B0] = regs->b0;
+	gdb_regs[BFIN_B1] = regs->b1;
+	gdb_regs[BFIN_B2] = regs->b2;
+	gdb_regs[BFIN_B3] = regs->b3;
+	gdb_regs[BFIN_L0] = regs->l0;
+	gdb_regs[BFIN_L1] = regs->l1;
+	gdb_regs[BFIN_L2] = regs->l2;
+	gdb_regs[BFIN_L3] = regs->l3;
+	gdb_regs[BFIN_A0_DOT_X] = regs->a0x;
+	gdb_regs[BFIN_A0_DOT_W] = regs->a0w;
+	gdb_regs[BFIN_A1_DOT_X] = regs->a1x;
+	gdb_regs[BFIN_A1_DOT_W] = regs->a1w;
+	gdb_regs[BFIN_ASTAT] = regs->astat;
+	gdb_regs[BFIN_RETS] = regs->rets;
+	gdb_regs[BFIN_LC0] = regs->lc0;
+	gdb_regs[BFIN_LT0] = regs->lt0;
+	gdb_regs[BFIN_LB0] = regs->lb0;
+	gdb_regs[BFIN_LC1] = regs->lc1;
+	gdb_regs[BFIN_LT1] = regs->lt1;
+	gdb_regs[BFIN_LB1] = regs->lb1;
+	gdb_regs[BFIN_CYCLES] = 0;
+	gdb_regs[BFIN_CYCLES2] = 0;
+	gdb_regs[BFIN_USP] = regs->usp;
+	gdb_regs[BFIN_SEQSTAT] = regs->seqstat;
+	gdb_regs[BFIN_SYSCFG] = regs->syscfg;
+	gdb_regs[BFIN_RETI] = regs->pc;
+	gdb_regs[BFIN_RETX] = regs->retx;
+	gdb_regs[BFIN_RETN] = regs->retn;
+	gdb_regs[BFIN_RETE] = regs->rete;
+	gdb_regs[BFIN_PC] = regs->pc;
+	gdb_regs[BFIN_CC] = 0;
+	gdb_regs[BFIN_EXTRA1] = 0;
+	gdb_regs[BFIN_EXTRA2] = 0;
+	gdb_regs[BFIN_EXTRA3] = 0;
+	gdb_regs[BFIN_IPEND] = regs->ipend;
+}
+
+/*
+ * Extracts ebp, esp and eip values understandable by gdb from the values
+ * saved by switch_to.
+ * thread.esp points to ebp. flags and ebp are pushed in switch_to hence esp
+ * prior to entering switch_to is 8 greater then the value that is saved.
+ * If switch_to changes, change following code appropriately.
+ */
+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
+{
+	gdb_regs[BFIN_SP] = p->thread.ksp;
+	gdb_regs[BFIN_PC] = p->thread.pc;
+	gdb_regs[BFIN_SEQSTAT] = p->thread.seqstat;
+}
+
+void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+	regs->r0 = gdb_regs[BFIN_R0];
+	regs->r1 = gdb_regs[BFIN_R1];
+	regs->r2 = gdb_regs[BFIN_R2];
+	regs->r3 = gdb_regs[BFIN_R3];
+	regs->r4 = gdb_regs[BFIN_R4];
+	regs->r5 = gdb_regs[BFIN_R5];
+	regs->r6 = gdb_regs[BFIN_R6];
+	regs->r7 = gdb_regs[BFIN_R7];
+	regs->p0 = gdb_regs[BFIN_P0];
+	regs->p1 = gdb_regs[BFIN_P1];
+	regs->p2 = gdb_regs[BFIN_P2];
+	regs->p3 = gdb_regs[BFIN_P3];
+	regs->p4 = gdb_regs[BFIN_P4];
+	regs->p5 = gdb_regs[BFIN_P5];
+	regs->fp = gdb_regs[BFIN_FP];
+	regs->i0 = gdb_regs[BFIN_I0];
+	regs->i1 = gdb_regs[BFIN_I1];
+	regs->i2 = gdb_regs[BFIN_I2];
+	regs->i3 = gdb_regs[BFIN_I3];
+	regs->m0 = gdb_regs[BFIN_M0];
+	regs->m1 = gdb_regs[BFIN_M1];
+	regs->m2 = gdb_regs[BFIN_M2];
+	regs->m3 = gdb_regs[BFIN_M3];
+	regs->b0 = gdb_regs[BFIN_B0];
+	regs->b1 = gdb_regs[BFIN_B1];
+	regs->b2 = gdb_regs[BFIN_B2];
+	regs->b3 = gdb_regs[BFIN_B3];
+	regs->l0 = gdb_regs[BFIN_L0];
+	regs->l1 = gdb_regs[BFIN_L1];
+	regs->l2 = gdb_regs[BFIN_L2];
+	regs->l3 = gdb_regs[BFIN_L3];
+	regs->a0x = gdb_regs[BFIN_A0_DOT_X];
+	regs->a0w = gdb_regs[BFIN_A0_DOT_W];
+	regs->a1x = gdb_regs[BFIN_A1_DOT_X];
+	regs->a1w = gdb_regs[BFIN_A1_DOT_W];
+	regs->rets = gdb_regs[BFIN_RETS];
+	regs->lc0 = gdb_regs[BFIN_LC0];
+	regs->lt0 = gdb_regs[BFIN_LT0];
+	regs->lb0 = gdb_regs[BFIN_LB0];
+	regs->lc1 = gdb_regs[BFIN_LC1];
+	regs->lt1 = gdb_regs[BFIN_LT1];
+	regs->lb1 = gdb_regs[BFIN_LB1];
+	regs->usp = gdb_regs[BFIN_USP];
+	regs->syscfg = gdb_regs[BFIN_SYSCFG];
+	regs->retx = gdb_regs[BFIN_PC];
+	regs->retn = gdb_regs[BFIN_RETN];
+	regs->rete = gdb_regs[BFIN_RETE];
+	regs->pc = gdb_regs[BFIN_PC];
+
+#if 0				/* can't change these */
+	regs->astat = gdb_regs[BFIN_ASTAT];
+	regs->seqstat = gdb_regs[BFIN_SEQSTAT];
+	regs->ipend = gdb_regs[BFIN_IPEND];
+#endif
+}
+
+struct hw_breakpoint {
+	unsigned int occupied:1;
+	unsigned int skip:1;
+	unsigned int enabled:1;
+	unsigned int type:1;
+	unsigned int dataacc:2;
+	unsigned short count;
+	unsigned int addr;
+} breakinfo[HW_BREAKPOINT_NUM];
+
+int kgdb_arch_init(void)
+{
+	kgdb_remove_all_hw_break();
+	return 0;
+}
+
+int kgdb_set_hw_break(unsigned long addr)
+{
+	int breakno;
+	for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++)
+		if (!breakinfo[breakno].occupied) {
+			breakinfo[breakno].occupied = 1;
+			breakinfo[breakno].enabled = 1;
+			breakinfo[breakno].type = 1;
+			breakinfo[breakno].addr = addr;
+			return 0;
+		}
+
+	return -ENOSPC;
+}
+
+int kgdb_remove_hw_break(unsigned long addr)
+{
+	int breakno;
+	for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++)
+		if (breakinfo[breakno].addr == addr)
+			memset(&(breakinfo[breakno]), 0, sizeof(struct hw_breakpoint));
+
+	return 0;
+}
+
+void kgdb_remove_all_hw_break(void)
+{
+	memset(breakinfo, 0, sizeof(struct hw_breakpoint)*8);
+}
+
+/*
+void kgdb_show_info(void)
+{
+	printk(KERN_DEBUG "hwd: wpia0=0x%x, wpiacnt0=%d, wpiactl=0x%x, wpstat=0x%x\n",
+		bfin_read_WPIA0(), bfin_read_WPIACNT0(),
+		bfin_read_WPIACTL(), bfin_read_WPSTAT());
+}
+*/
+
+void kgdb_correct_hw_break(void)
+{
+	int breakno;
+	int correctit;
+	uint32_t wpdactl = bfin_read_WPDACTL();
+
+	correctit = 0;
+	for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++) {
+		if (breakinfo[breakno].type == 1) {
+			switch (breakno) {
+			case 0:
+				if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN0)) {
+					correctit = 1;
+					wpdactl &= ~(WPIREN01|EMUSW0);
+					wpdactl |= WPIAEN0|WPICNTEN0;
+					bfin_write_WPIA0(breakinfo[breakno].addr);
+					bfin_write_WPIACNT0(breakinfo[breakno].skip);
+				} else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN0)) {
+					correctit = 1;
+					wpdactl &= ~WPIAEN0;
+				}
+				break;
+
+			case 1:
+				if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN1)) {
+					correctit = 1;
+					wpdactl &= ~(WPIREN01|EMUSW1);
+					wpdactl |= WPIAEN1|WPICNTEN1;
+					bfin_write_WPIA1(breakinfo[breakno].addr);
+					bfin_write_WPIACNT1(breakinfo[breakno].skip);
+				} else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN1)) {
+					correctit = 1;
+					wpdactl &= ~WPIAEN1;
+				}
+				break;
+
+			case 2:
+				if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN2)) {
+					correctit = 1;
+					wpdactl &= ~(WPIREN23|EMUSW2);
+					wpdactl |= WPIAEN2|WPICNTEN2;
+					bfin_write_WPIA2(breakinfo[breakno].addr);
+					bfin_write_WPIACNT2(breakinfo[breakno].skip);
+				} else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN2)) {
+					correctit = 1;
+					wpdactl &= ~WPIAEN2;
+				}
+				break;
+
+			case 3:
+				if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN3)) {
+					correctit = 1;
+					wpdactl &= ~(WPIREN23|EMUSW3);
+					wpdactl |= WPIAEN3|WPICNTEN3;
+					bfin_write_WPIA3(breakinfo[breakno].addr);
+					bfin_write_WPIACNT3(breakinfo[breakno].skip);
+				} else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN3)) {
+					correctit = 1;
+					wpdactl &= ~WPIAEN3;
+				}
+				break;
+			case 4:
+				if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN4)) {
+					correctit = 1;
+					wpdactl &= ~(WPIREN45|EMUSW4);
+					wpdactl |= WPIAEN4|WPICNTEN4;
+					bfin_write_WPIA4(breakinfo[breakno].addr);
+					bfin_write_WPIACNT4(breakinfo[breakno].skip);
+				} else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN4)) {
+					correctit = 1;
+					wpdactl &= ~WPIAEN4;
+				}
+				break;
+			case 5:
+				if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN5)) {
+					correctit = 1;
+					wpdactl &= ~(WPIREN45|EMUSW5);
+					wpdactl |= WPIAEN5|WPICNTEN5;
+					bfin_write_WPIA5(breakinfo[breakno].addr);
+					bfin_write_WPIACNT5(breakinfo[breakno].skip);
+				} else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN5)) {
+					correctit = 1;
+					wpdactl &= ~WPIAEN5;
+				}
+				break;
+			}
+		}
+	}
+	if (correctit) {
+		wpdactl &= ~WPAND;
+		wpdactl |= WPPWR;
+		/*printk("correct_hw_break: wpdactl=0x%x\n", wpdactl);*/
+		bfin_write_WPDACTL(wpdactl);
+		CSYNC();
+		/*kgdb_show_info();*/
+	}
+}
+
+void kgdb_disable_hw_debug(struct pt_regs *regs)
+{
+	/* Disable hardware debugging while we are in kgdb */
+	bfin_write_WPIACTL(bfin_read_WPIACTL() & ~0x1);
+	CSYNC();
+}
+
+void kgdb_post_master_code(struct pt_regs *regs, int eVector, int err_code)
+{
+	/* Master processor is completely in the debugger */
+	gdb_bf533vector = eVector;
+	gdb_bf533errcode = err_code;
+}
+
+int kgdb_arch_handle_exception(int exceptionVector, int signo,
+			       int err_code, char *remcom_in_buffer,
+			       char *remcom_out_buffer,
+			       struct pt_regs *linux_regs)
+{
+	long addr;
+	long breakno;
+	char *ptr;
+	int newPC;
+	int wp_status;
+
+	switch (remcom_in_buffer[0]) {
+	case 'c':
+	case 's':
+		if (kgdb_contthread && kgdb_contthread != current) {
+			strcpy(remcom_out_buffer, "E00");
+			break;
+		}
+
+		kgdb_contthread = NULL;
+
+		/* try to read optional parameter, pc unchanged if no parm */
+		ptr = &remcom_in_buffer[1];
+		if (kgdb_hex2long(&ptr, &addr)) {
+			linux_regs->retx = addr;
+		}
+		newPC = linux_regs->retx;
+
+		/* clear the trace bit */
+		linux_regs->syscfg &= 0xfffffffe;
+
+		/* set the trace bit if we're stepping */
+		if (remcom_in_buffer[0] == 's') {
+			linux_regs->syscfg |= 0x1;
+			debugger_step = 1;
+		}
+
+		wp_status = bfin_read_WPSTAT();
+		CSYNC();
+
+		if (exceptionVector == VEC_WATCH) {
+			for (breakno = 0; breakno < 6; ++breakno) {
+				if (wp_status & (1 << breakno)) {
+					breakinfo->skip = 1;
+					break;
+				}
+			}
+		}
+		kgdb_correct_hw_break();
+
+		bfin_write_WPSTAT(0);
+
+		return 0;
+	}			/* switch */
+	return -1;		/* this means that we do not want to exit from the handler */
+}
+
+struct kgdb_arch arch_kgdb_ops = {
+	.gdb_bpt_instr = {0xa1},
+	.flags = KGDB_HW_BREAKPOINT,
+};
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c
index 372f756..8b9fe29 100644
--- a/arch/blackfin/kernel/module.c
+++ b/arch/blackfin/kernel/module.c
@@ -165,8 +165,8 @@
 
 	for (s = sechdrs; s < sechdrs_end; ++s) {
 		if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
-			((strcmp(".text", secstrings + s->sh_name)==0) &&
-			 (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
+		    ((strcmp(".text", secstrings + s->sh_name) == 0) &&
+		     (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
 			mod->arch.text_l1 = s;
 			dest = l1_inst_sram_alloc(s->sh_size);
 			if (dest == NULL) {
@@ -179,9 +179,9 @@
 			s->sh_flags &= ~SHF_ALLOC;
 			s->sh_addr = (unsigned long)dest;
 		}
-		if ((strcmp(".l1.data", secstrings + s->sh_name) == 0)||
-			((strcmp(".data", secstrings + s->sh_name)==0) &&
-			 (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
+		if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) ||
+		    ((strcmp(".data", secstrings + s->sh_name) == 0) &&
+		     (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
 			mod->arch.data_a_l1 = s;
 			dest = l1_data_sram_alloc(s->sh_size);
 			if (dest == NULL) {
@@ -195,8 +195,8 @@
 			s->sh_addr = (unsigned long)dest;
 		}
 		if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
-			((strcmp(".bss", secstrings + s->sh_name)==0) &&
-			 (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
+		    ((strcmp(".bss", secstrings + s->sh_name) == 0) &&
+		     (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
 			mod->arch.bss_a_l1 = s;
 			dest = l1_data_sram_alloc(s->sh_size);
 			if (dest == NULL) {
@@ -326,7 +326,7 @@
 			pr_debug("before %x after %x\n", *location16,
 				       (value & 0xffff));
 			tmp = (value & 0xffff);
-			if((unsigned long)location16 >= L1_CODE_START) {
+			if ((unsigned long)location16 >= L1_CODE_START) {
 				dma_memcpy(location16, &tmp, 2);
 			} else
 				*location16 = tmp;
@@ -335,7 +335,7 @@
 			pr_debug("before %x after %x\n", *location16,
 				       ((value >> 16) & 0xffff));
 			tmp = ((value >> 16) & 0xffff);
-			if((unsigned long)location16 >= L1_CODE_START) {
+			if ((unsigned long)location16 >= L1_CODE_START) {
 				dma_memcpy(location16, &tmp, 2);
 			} else
 				*location16 = tmp;
@@ -404,8 +404,8 @@
 			continue;
 
 		if ((sechdrs[i].sh_type == SHT_RELA) &&
-		    ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0)||
-			((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) &&
+		    ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) ||
+		    ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) &&
 			 (hdr->e_flags & FLG_CODE_IN_L1)))) {
 			apply_relocate_add((Elf_Shdr *) sechdrs, strtab,
 					   symindex, i, mod);
@@ -417,13 +417,13 @@
 void module_arch_cleanup(struct module *mod)
 {
 	if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr))
-		l1_inst_sram_free((void*)mod->arch.text_l1->sh_addr);
+		l1_inst_sram_free((void *)mod->arch.text_l1->sh_addr);
 	if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr))
-		l1_data_sram_free((void*)mod->arch.data_a_l1->sh_addr);
+		l1_data_sram_free((void *)mod->arch.data_a_l1->sh_addr);
 	if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr))
-		l1_data_sram_free((void*)mod->arch.bss_a_l1->sh_addr);
+		l1_data_sram_free((void *)mod->arch.bss_a_l1->sh_addr);
 	if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr))
-		l1_data_B_sram_free((void*)mod->arch.data_b_l1->sh_addr);
+		l1_data_B_sram_free((void *)mod->arch.data_b_l1->sh_addr);
 	if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr))
-		l1_data_B_sram_free((void*)mod->arch.bss_b_l1->sh_addr);
+		l1_data_B_sram_free((void *)mod->arch.bss_b_l1->sh_addr);
 }
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 3eff743..5a51dd6 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -32,9 +32,10 @@
 #include <linux/unistd.h>
 #include <linux/user.h>
 #include <linux/a.out.h>
+#include <linux/uaccess.h>
 
 #include <asm/blackfin.h>
-#include <asm/uaccess.h>
+#include <asm/fixed_code.h>
 
 #define	LED_ON	0
 #define	LED_OFF	1
@@ -173,8 +174,8 @@
 	printk(KERN_NOTICE "R4: %08lx  R5: %08lx  R6: %08lx  R7: %08lx\n",
 	       regs->r4, regs->r5, regs->r6, regs->r7);
 
-	if (!(regs->ipend))
-		printk("USP: %08lx\n", rdusp());
+	if (!regs->ipend)
+		printk(KERN_NOTICE "USP: %08lx\n", rdusp());
 }
 
 /* Fill in the fpu structure for a core dump.  */
@@ -322,7 +323,7 @@
 		goto out;
 	error = do_execve(filename, argv, envp, regs);
 	putname(filename);
-      out:
+ out:
 	unlock_kernel();
 	return error;
 }
@@ -350,13 +351,77 @@
 	return 0;
 }
 
+void finish_atomic_sections (struct pt_regs *regs)
+{
+	if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END)
+		return;
+
+	switch (regs->pc) {
+	case ATOMIC_XCHG32 + 2:
+		put_user(regs->r1, (int *)regs->p0);
+		regs->pc += 2;
+		break;
+
+	case ATOMIC_CAS32 + 2:
+	case ATOMIC_CAS32 + 4:
+		if (regs->r0 == regs->r1)
+			put_user(regs->r2, (int *)regs->p0);
+		regs->pc = ATOMIC_CAS32 + 8;
+		break;
+	case ATOMIC_CAS32 + 6:
+		put_user(regs->r2, (int *)regs->p0);
+		regs->pc += 2;
+		break;
+
+	case ATOMIC_ADD32 + 2:
+		regs->r0 = regs->r1 + regs->r0;
+		/* fall through */
+	case ATOMIC_ADD32 + 4:
+		put_user(regs->r0, (int *)regs->p0);
+		regs->pc = ATOMIC_ADD32 + 6;
+		break;
+
+	case ATOMIC_SUB32 + 2:
+		regs->r0 = regs->r1 - regs->r0;
+		/* fall through */
+	case ATOMIC_SUB32 + 4:
+		put_user(regs->r0, (int *)regs->p0);
+		regs->pc = ATOMIC_SUB32 + 6;
+		break;
+
+	case ATOMIC_IOR32 + 2:
+		regs->r0 = regs->r1 | regs->r0;
+		/* fall through */
+	case ATOMIC_IOR32 + 4:
+		put_user(regs->r0, (int *)regs->p0);
+		regs->pc = ATOMIC_IOR32 + 6;
+		break;
+
+	case ATOMIC_AND32 + 2:
+		regs->r0 = regs->r1 & regs->r0;
+		/* fall through */
+	case ATOMIC_AND32 + 4:
+		put_user(regs->r0, (int *)regs->p0);
+		regs->pc = ATOMIC_AND32 + 6;
+		break;
+
+	case ATOMIC_XOR32 + 2:
+		regs->r0 = regs->r1 ^ regs->r0;
+		/* fall through */
+	case ATOMIC_XOR32 + 4:
+		put_user(regs->r0, (int *)regs->p0);
+		regs->pc = ATOMIC_XOR32 + 6;
+		break;
+	}
+}
+
 #if defined(CONFIG_ACCESS_CHECK)
 int _access_ok(unsigned long addr, unsigned long size)
 {
 
 	if (addr > (addr + size))
 		return 0;
-	if (segment_eq(get_fs(),KERNEL_DS))
+	if (segment_eq(get_fs(), KERNEL_DS))
 		return 1;
 #ifdef CONFIG_MTD_UCLINUX
 	if (addr >= memory_start && (addr + size) <= memory_end)
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index e718bb4..ed800c7 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -36,8 +36,8 @@
 #include <linux/ptrace.h>
 #include <linux/user.h>
 #include <linux/signal.h>
+#include <linux/uaccess.h>
 
-#include <asm/uaccess.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -122,7 +122,7 @@
 static inline int
 put_reg(struct task_struct *task, int regno, unsigned long data)
 {
-	char * reg_ptr;
+	char *reg_ptr;
 
 	struct pt_regs *regs =
 	    (struct pt_regs *)((unsigned long)task_stack_page(task) +
@@ -146,7 +146,7 @@
 		break;
 	default:
 		if (regno <= 216)
-		        *(long *)(reg_ptr + regno) = data;
+			*(long *)(reg_ptr + regno) = data;
 	}
 	return 0;
 }
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 83060f9..f59dcee 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -42,6 +42,7 @@
 #include <asm/cacheflush.h>
 #include <asm/blackfin.h>
 #include <asm/cplbinit.h>
+#include <asm/fixed_code.h>
 
 u16 _bfin_swrst;
 
@@ -63,10 +64,6 @@
 
 char __initdata command_line[COMMAND_LINE_SIZE];
 
-#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
-static void generate_cpl_tables(void);
-#endif
-
 void __init bf53x_cache_init(void)
 {
 #if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
@@ -197,6 +194,17 @@
 	/* this give a chance to get printk() working before crash. */
 #endif
 
+	printk(KERN_INFO "Hardware Trace ");
+	if (bfin_read_TBUFCTL() & 0x1 )
+		printk("Active ");
+	else
+		printk("Off ");
+	if (bfin_read_TBUFCTL() & 0x2)
+		printk("and Enabled\n");
+	else
+	printk("and Disabled\n");
+
+
 #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
 	/* we need to initialize the Flashrom device here since we might
 	 * do things with flash early on in the boot
@@ -354,15 +362,15 @@
 	       , _stext, _etext,
 	       __start_rodata, __end_rodata,
 	       _sdata, _edata,
-	       (void*)&init_thread_union, (void*)((int)(&init_thread_union) + 0x2000),
+	       (void *)&init_thread_union, (void *)((int)(&init_thread_union) + 0x2000),
 	       __init_begin, __init_end,
 	       __bss_start, __bss_stop,
-	       (void*)_ramstart, (void*)memory_end
+	       (void *)_ramstart, (void *)memory_end
 #ifdef CONFIG_MTD_UCLINUX
-	       , (void*)memory_mtd_start, (void*)(memory_mtd_start + mtd_size)
+	       , (void *)memory_mtd_start, (void *)(memory_mtd_start + mtd_size)
 #endif
 #if DMA_UNCACHED_REGION > 0
-	       , (void*)(_ramend - DMA_UNCACHED_REGION), (void*)(_ramend)
+	       , (void *)(_ramend - DMA_UNCACHED_REGION), (void *)(_ramend)
 #endif
 	       );
 
@@ -388,11 +396,11 @@
 	/* check the size of the l1 area */
 	l1_length = _etext_l1 - _stext_l1;
 	if (l1_length > L1_CODE_LENGTH)
-		panic("L1 memory overflow\n");
+		panic("L1 code memory overflow\n");
 
 	l1_length = _ebss_l1 - _sdata_l1;
 	if (l1_length > L1_DATA_A_LENGTH)
-		panic("L1 memory overflow\n");
+		panic("L1 data memory overflow\n");
 
 #ifdef BF561_FAMILY
 	_bfin_swrst = bfin_read_SICA_SWRST();
@@ -400,10 +408,28 @@
 	_bfin_swrst = bfin_read_SWRST();
 #endif
 
-	bf53x_cache_init();
+	/* Copy atomic sequences to their fixed location, and sanity check that
+	   these locations are the ones that we advertise to userspace.  */
+	memcpy((void *)FIXED_CODE_START, &fixed_code_start,
+	       FIXED_CODE_END - FIXED_CODE_START);
+	BUG_ON((char *)&sigreturn_stub - (char *)&fixed_code_start
+	       != SIGRETURN_STUB - FIXED_CODE_START);
+	BUG_ON((char *)&atomic_xchg32 - (char *)&fixed_code_start
+	       != ATOMIC_XCHG32 - FIXED_CODE_START);
+	BUG_ON((char *)&atomic_cas32 - (char *)&fixed_code_start
+	       != ATOMIC_CAS32 - FIXED_CODE_START);
+	BUG_ON((char *)&atomic_add32 - (char *)&fixed_code_start
+	       != ATOMIC_ADD32 - FIXED_CODE_START);
+	BUG_ON((char *)&atomic_sub32 - (char *)&fixed_code_start
+	       != ATOMIC_SUB32 - FIXED_CODE_START);
+	BUG_ON((char *)&atomic_ior32 - (char *)&fixed_code_start
+	       != ATOMIC_IOR32 - FIXED_CODE_START);
+	BUG_ON((char *)&atomic_and32 - (char *)&fixed_code_start
+	       != ATOMIC_AND32 - FIXED_CODE_START);
+	BUG_ON((char *)&atomic_xor32 - (char *)&fixed_code_start
+	       != ATOMIC_XOR32 - FIXED_CODE_START);
 
-	printk(KERN_INFO "Hardware Trace Enabled\n");
-	bfin_write_TBUFCTL(0x03);
+	bf53x_cache_init();
 }
 
 static int __init topology_init(void)
@@ -421,286 +447,6 @@
 
 subsys_initcall(topology_init);
 
-#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
-static u16 __init lock_kernel_check(u32 start, u32 end)
-{
-	if ((start <= (u32) _stext && end >= (u32) _end)
-	    || (start >= (u32) _stext && end <= (u32) _end))
-		return IN_KERNEL;
-	return 0;
-}
-
-static unsigned short __init
-fill_cplbtab(struct cplb_tab *table,
-	     unsigned long start, unsigned long end,
-	     unsigned long block_size, unsigned long cplb_data)
-{
-	int i;
-
-	switch (block_size) {
-	case SIZE_4M:
-		i = 3;
-		break;
-	case SIZE_1M:
-		i = 2;
-		break;
-	case SIZE_4K:
-		i = 1;
-		break;
-	case SIZE_1K:
-	default:
-		i = 0;
-		break;
-	}
-
-	cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
-
-	while ((start < end) && (table->pos < table->size)) {
-
-		table->tab[table->pos++] = start;
-
-		if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
-			table->tab[table->pos++] =
-			    cplb_data | CPLB_LOCK | CPLB_DIRTY;
-		else
-			table->tab[table->pos++] = cplb_data;
-
-		start += block_size;
-	}
-	return 0;
-}
-
-static unsigned short __init
-close_cplbtab(struct cplb_tab *table)
-{
-
-	while (table->pos < table->size) {
-
-		table->tab[table->pos++] = 0;
-		table->tab[table->pos++] = 0; /* !CPLB_VALID */
-	}
-	return 0;
-}
-
-/* helper function */
-static void __fill_code_cplbtab(struct cplb_tab *t, int i,
-				u32 a_start, u32 a_end)
-{
-	if (cplb_data[i].psize) {
-		fill_cplbtab(t,
-				cplb_data[i].start,
-				cplb_data[i].end,
-				cplb_data[i].psize,
-				cplb_data[i].i_conf);
-	} else {
-#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
-		if (i == SDRAM_KERN) {
-			fill_cplbtab(t,
-					cplb_data[i].start,
-					cplb_data[i].end,
-					SIZE_4M,
-					cplb_data[i].i_conf);
-		} else {
-#endif
-			fill_cplbtab(t,
-					cplb_data[i].start,
-					a_start,
-					SIZE_1M,
-					cplb_data[i].i_conf);
-			fill_cplbtab(t,
-					a_start,
-					a_end,
-					SIZE_4M,
-					cplb_data[i].i_conf);
-			fill_cplbtab(t, a_end,
-					cplb_data[i].end,
-					SIZE_1M,
-					cplb_data[i].i_conf);
-		}
-	}
-}
-
-static void __fill_data_cplbtab(struct cplb_tab *t, int i,
-				u32 a_start, u32 a_end)
-{
-	if (cplb_data[i].psize) {
-		fill_cplbtab(t,
-				cplb_data[i].start,
-				cplb_data[i].end,
-				cplb_data[i].psize,
-				cplb_data[i].d_conf);
-	} else {
-		fill_cplbtab(t,
-				cplb_data[i].start,
-				a_start, SIZE_1M,
-				cplb_data[i].d_conf);
-		fill_cplbtab(t, a_start,
-				a_end, SIZE_4M,
-				cplb_data[i].d_conf);
-		fill_cplbtab(t, a_end,
-				cplb_data[i].end,
-				SIZE_1M,
-				cplb_data[i].d_conf);
-	}
-}
-static void __init generate_cpl_tables(void)
-{
-
-	u16 i, j, process;
-	u32 a_start, a_end, as, ae, as_1m;
-
-	struct cplb_tab *t_i = NULL;
-	struct cplb_tab *t_d = NULL;
-	struct s_cplb cplb;
-
-	cplb.init_i.size = MAX_CPLBS;
-	cplb.init_d.size = MAX_CPLBS;
-	cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
-	cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
-
-	cplb.init_i.pos = 0;
-	cplb.init_d.pos = 0;
-	cplb.switch_i.pos = 0;
-	cplb.switch_d.pos = 0;
-
-	cplb.init_i.tab = icplb_table;
-	cplb.init_d.tab = dcplb_table;
-	cplb.switch_i.tab = ipdt_table;
-	cplb.switch_d.tab = dpdt_table;
-
-	cplb_data[SDRAM_KERN].end = memory_end;
-
-#ifdef CONFIG_MTD_UCLINUX
-	cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
-	cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
-	cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
-# if defined(CONFIG_ROMFS_FS)
-	cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
-
-	/*
-	 * The ROMFS_FS size is often not multiple of 1MB.
-	 * This can cause multiple CPLB sets covering the same memory area.
-	 * This will then cause multiple CPLB hit exceptions.
-	 * Workaround: We ensure a contiguous memory area by extending the kernel
-	 * memory section over the mtd section.
-	 * For ROMFS_FS memory must be covered with ICPLBs anyways.
-	 * So there is no difference between kernel and mtd memory setup.
-	 */
-
-	cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
-	cplb_data[SDRAM_RAM_MTD].valid = 0;
-
-# endif
-#else
-	cplb_data[SDRAM_RAM_MTD].valid = 0;
-#endif
-
-	cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
-	cplb_data[SDRAM_DMAZ].end = _ramend;
-
-	cplb_data[RES_MEM].start = _ramend;
-	cplb_data[RES_MEM].end = physical_mem_end;
-
-	if (reserved_mem_dcache_on)
-		cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
-	else
-		cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
-
-	if (reserved_mem_icache_on)
-		cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
-	else
-		cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
-
-	for (i = ZERO_P; i <= L2_MEM; i++) {
-		if (!cplb_data[i].valid)
-			continue;
-
-		as_1m = cplb_data[i].start % SIZE_1M;
-
-		/*
-		 * We need to make sure all sections are properly 1M aligned
-		 * However between Kernel Memory and the Kernel mtd section,
-		 * depending on the rootfs size, there can be overlapping
-		 * memory areas.
-		 */
-
-		if (as_1m && i != L1I_MEM && i != L1D_MEM) {
-#ifdef CONFIG_MTD_UCLINUX
-			if (i == SDRAM_RAM_MTD) {
-				if ((cplb_data[SDRAM_KERN].end + 1) >
-						cplb_data[SDRAM_RAM_MTD].start)
-					cplb_data[SDRAM_RAM_MTD].start =
-						(cplb_data[i].start &
-						 (-2*SIZE_1M)) + SIZE_1M;
-				else
-					cplb_data[SDRAM_RAM_MTD].start =
-						(cplb_data[i].start &
-						 (-2*SIZE_1M));
-			} else
-#endif
-				printk(KERN_WARNING
-					"Unaligned Start of %s at 0x%X\n",
-					cplb_data[i].name, cplb_data[i].start);
-		}
-
-		as = cplb_data[i].start % SIZE_4M;
-		ae = cplb_data[i].end % SIZE_4M;
-
-		if (as)
-			a_start = cplb_data[i].start + (SIZE_4M - (as));
-		else
-			a_start = cplb_data[i].start;
-
-		a_end = cplb_data[i].end - ae;
-
-		for (j = INITIAL_T; j <= SWITCH_T; j++) {
-
-			switch (j) {
-			case INITIAL_T:
-				if (cplb_data[i].attr & INITIAL_T) {
-					t_i = &cplb.init_i;
-					t_d = &cplb.init_d;
-					process = 1;
-				} else
-					process = 0;
-				break;
-			case SWITCH_T:
-				if (cplb_data[i].attr & SWITCH_T) {
-					t_i = &cplb.switch_i;
-					t_d = &cplb.switch_d;
-					process = 1;
-				} else
-					process = 0;
-				break;
-			default:
-					process = 0;
-				break;
-			}
-
-			if (!process)
-				continue;
-			if (cplb_data[i].attr & I_CPLB)
-				__fill_code_cplbtab(t_i, i, a_start, a_end);
-
-			if (cplb_data[i].attr & D_CPLB)
-				__fill_data_cplbtab(t_d, i, a_start, a_end);
-		}
-	}
-
-/* close tables */
-
-	close_cplbtab(&cplb.init_i);
-	close_cplbtab(&cplb.init_d);
-
-	cplb.init_i.tab[cplb.init_i.pos] = -1;
-	cplb.init_d.tab[cplb.init_d.pos] = -1;
-	cplb.switch_i.tab[cplb.switch_i.pos] = -1;
-	cplb.switch_d.tab[cplb.switch_d.pos] = -1;
-
-}
-
-#endif
-
 static u_long get_vco(void)
 {
 	u_long msel;
@@ -730,7 +476,6 @@
 		return get_vco() / ssel;
 	return get_vco() >> csel;
 }
-
 EXPORT_SYMBOL(get_cclk);
 
 /* Get the System clock */
@@ -749,7 +494,6 @@
 
 	return get_vco() / ssel;
 }
-
 EXPORT_SYMBOL(get_sclk);
 
 /*
@@ -804,23 +548,23 @@
 		seq_printf(m, "D-CACHE:\tOFF\n");
 
 
-	switch(bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) {
-		case ACACHE_BSRAM:
-			seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n");
-			dcache_size = 16;
-			dsup_banks = 1;
-			break;
-		case ACACHE_BCACHE:
-			seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
-			dcache_size = 32;
-			dsup_banks = 2;
-			break;
-		case ASRAM_BSRAM:
-			seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
-			dcache_size = 0;
-			dsup_banks = 0;
-			break;
-		default:
+	switch (bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) {
+	case ACACHE_BSRAM:
+		seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n");
+		dcache_size = 16;
+		dsup_banks = 1;
+		break;
+	case ACACHE_BCACHE:
+		seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
+		dcache_size = 32;
+		dsup_banks = 2;
+		break;
+	case ASRAM_BSRAM:
+		seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
+		dcache_size = 0;
+		dsup_banks = 0;
+		break;
+	default:
 		break;
 	}
 
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index 316e65c..5564c95 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -34,8 +34,8 @@
 #include <linux/personality.h>
 #include <linux/binfmts.h>
 #include <linux/freezer.h>
+#include <linux/uaccess.h>
 
-#include <asm/uaccess.h>
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
 
@@ -124,7 +124,7 @@
 
 	return r0;
 
-      badframe:
+ badframe:
 	force_sig(SIGSEGV, current);
 	return 0;
 }
@@ -239,7 +239,7 @@
 
 	return 0;
 
-      give_sigsegv:
+ give_sigsegv:
 	if (sig == SIGSEGV)
 		ka->sa.sa_handler = SIG_DFL;
 	force_sig(SIGSEGV, current);
@@ -263,7 +263,7 @@
 		}
 		/* fallthrough */
 	case -ERESTARTNOINTR:
-	      do_restart:
+ do_restart:
 		regs->p0 = regs->orig_p0;
 		regs->r0 = regs->orig_r0;
 		regs->pc -= 2;
@@ -341,7 +341,7 @@
 		return;
 	}
 
-no_signal:
+ no_signal:
 	/* Did we come from a system call? */
 	if (regs->orig_p0 >= 0)
 		/* Restart the system call - no handlers present */
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c
index f436e67..f5e1ae3 100644
--- a/arch/blackfin/kernel/sys_bfin.c
+++ b/arch/blackfin/kernel/sys_bfin.c
@@ -37,12 +37,12 @@
 #include <linux/syscalls.h>
 #include <linux/mman.h>
 #include <linux/file.h>
+#include <linux/uaccess.h>
+#include <linux/ipc.h>
+#include <linux/unistd.h>
 
 #include <asm/cacheflush.h>
-#include <asm/uaccess.h>
-#include <asm/ipc.h>
 #include <asm/dma.h>
-#include <asm/unistd.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -83,7 +83,7 @@
 
 	if (file)
 		fput(file);
-      out:
+ out:
 	return error;
 }
 
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c
index f578176..beef057 100644
--- a/arch/blackfin/kernel/time.c
+++ b/arch/blackfin/kernel/time.c
@@ -87,7 +87,7 @@
 static inline void do_leds(void)
 {
 	static unsigned int count = 50;
-	static int flag = 0;
+	static int flag;
 	unsigned short tmp = 0;
 
 	if (--count == 0) {
@@ -200,7 +200,7 @@
 irqreturn_t timer_interrupt(int irq, void *dummy)
 {
 	/* last time the cmos clock got updated */
-	static long last_rtc_update = 0;
+	static long last_rtc_update;
 
 	write_seqlock(&xtime_lock);
 
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 56058b0..3909f5b 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -27,15 +27,15 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <asm/uaccess.h>
-#include <asm/traps.h>
-#include <asm/cacheflush.h>
-#include <asm/blackfin.h>
-#include <asm/uaccess.h>
-#include <asm/irq_handler.h>
+#include <linux/uaccess.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/kallsyms.h>
+#include <asm/traps.h>
+#include <asm/cacheflush.h>
+#include <asm/blackfin.h>
+#include <asm/irq_handler.h>
+#include <asm/trace.h>
 
 #ifdef CONFIG_KGDB
 # include <linux/debugger.h>
@@ -76,7 +76,7 @@
 		if (!modname)
 			modname = delim = "";
 		return printk("<0x%p> { %s%s%s%s + 0x%lx }",
-		              (void*)address, delim, modname, delim, symname,
+		              (void *)address, delim, modname, delim, symname,
 		              (unsigned long)offset);
 
 	}
@@ -119,7 +119,7 @@
 
 				write_unlock_irq(&tasklist_lock);
 				return printk("<0x%p> [ %s + 0x%lx ]",
-				              (void*)address, name, offset);
+				              (void *)address, name, offset);
 			}
 
 			vml = vml->next;
@@ -128,19 +128,9 @@
 	write_unlock_irq(&tasklist_lock);
 
 	/* we were unable to find this address anywhere */
-	return printk("[<0x%p>]", (void*)address);
+	return printk("[<0x%p>]", (void *)address);
 }
 
-#define trace_buffer_save(x) \
-	do { \
-		(x) = bfin_read_TBUFCTL(); \
-		bfin_write_TBUFCTL((x) & ~TBUFEN); \
-	} while (0)
-#define trace_buffer_restore(x) \
-	do { \
-		bfin_write_TBUFCTL((x));	\
-	} while (0)
-
 asmlinkage void trap_c(struct pt_regs *fp)
 {
 	int j, sig = 0;
@@ -203,15 +193,14 @@
 #else
 	/* 0x02 - User Defined, Caught by default */
 #endif
-	/* 0x03  - Atomic test and set */
+	/* 0x03 - User Defined, userspace stack overflow */
 	case VEC_EXCPT03:
 		info.si_code = SEGV_STACKFLOW;
 		sig = SIGSEGV;
 		printk(KERN_EMERG EXC_0x03);
 		CHK_DEBUGGER_TRAP();
 		break;
-	/* 0x04 - spinlock - handled by _ex_spinlock,
-		getting here is an error */
+	/* 0x04 - User Defined, Caught by default */
 	/* 0x05 - User Defined, Caught by default */
 	/* 0x06 - User Defined, Caught by default */
 	/* 0x07 - User Defined, Caught by default */
@@ -547,29 +536,28 @@
 		printk(KERN_EMERG "TEXT = 0x%p-0x%p  DATA = 0x%p-0x%p\n"
 		       KERN_EMERG "BSS = 0x%p-0x%p   USER-STACK = 0x%p\n"
 		       KERN_EMERG "\n",
-		       (void*)current->mm->start_code,
-		       (void*)current->mm->end_code,
-		       (void*)current->mm->start_data,
-		       (void*)current->mm->end_data,
-		       (void*)current->mm->end_data,
-		       (void*)current->mm->brk,
-		       (void*)current->mm->start_stack);
+		       (void *)current->mm->start_code,
+		       (void *)current->mm->end_code,
+		       (void *)current->mm->start_data,
+		       (void *)current->mm->end_data,
+		       (void *)current->mm->end_data,
+		       (void *)current->mm->brk,
+		       (void *)current->mm->start_stack);
 	}
 
 	printk(KERN_EMERG "return address: [0x%p]; contents of:", retaddr);
-	if (retaddr != 0 && retaddr <= (void*)physical_mem_end
+	if (retaddr != 0 && retaddr <= (void *)physical_mem_end
 #if L1_CODE_LENGTH != 0
 	    /* FIXME: Copy the code out of L1 Instruction SRAM through dma
 	       memcpy.  */
-	    && !(retaddr >= (void*)L1_CODE_START
-	         && retaddr < (void*)(L1_CODE_START + L1_CODE_LENGTH))
+	    && !(retaddr >= (void *)L1_CODE_START
+	         && retaddr < (void *)(L1_CODE_START + L1_CODE_LENGTH))
 #endif
 	) {
 		int i = ((unsigned int)retaddr & 0xFFFFFFF0) - 32;
 		unsigned short x = 0;
-		for (; i < ((unsigned int)retaddr & 0xFFFFFFF0 ) + 32 ;
-			i += 2) {
-			if ( !(i & 0xF) )
+		for (; i < ((unsigned int)retaddr & 0xFFFFFFF0) + 32; i += 2) {
+			if (!(i & 0xF))
 				printk(KERN_EMERG "\n" KERN_EMERG
 					"0x%08x: ", i);
 
@@ -588,7 +576,7 @@
 					" The rest of this error"
 					" is meanless\n");
 #endif
-			if ( i == (unsigned int)retaddr )
+			if (i == (unsigned int)retaddr)
 				printk("[%04x]", x);
 			else
 				printk(" %04x ", x);
@@ -681,8 +669,8 @@
 		break;
 	}
 
-	printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR());
-	printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR());
+	printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR());
+	printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR());
 	dump_bfin_regs(fp, (void *)fp->retx);
 	dump_stack();
 	panic("Unrecoverable event\n");
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index 1ef1e36..d06f860 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -31,6 +31,7 @@
 
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/mem_map.h>
+#include <asm/page.h>
 
 OUTPUT_FORMAT("elf32-bfin")
 ENTRY(__start)
@@ -63,8 +64,8 @@
 
 	.data :
 	{
+		. = ALIGN(PAGE_SIZE);
 		__sdata = .;
-		. = ALIGN(0x2000);
 		*(.data.init_task)
 		DATA_DATA
 		CONSTRUCTORS
@@ -72,14 +73,14 @@
 		. = ALIGN(32);
 		*(.data.cacheline_aligned)
 
-		. = ALIGN(0x2000);
+		. = ALIGN(PAGE_SIZE);
 		__edata = .;
 	}
 
+	. = ALIGN(PAGE_SIZE);
 	___init_begin = .;
 	.init :
 	{
-		. = ALIGN(4096);
 		__sinittext = .;
 		*(.init.text)
 		__einittext = .;
@@ -152,9 +153,10 @@
 		__ebss_b_l1 = .;
 	}
 
-	___init_end = LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1);
+	. = LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1);
+	___init_end = ALIGN(PAGE_SIZE);
 
-	.bss LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1) :
+	.bss ___init_end :
 	{
 		. = ALIGN(4);
 		___bss_start = .;
diff --git a/arch/blackfin/lib/strcmp.c b/arch/blackfin/lib/strcmp.c
index 2ad47c4..4eeefd8 100644
--- a/arch/blackfin/lib/strcmp.c
+++ b/arch/blackfin/lib/strcmp.c
@@ -6,6 +6,5 @@
 
 int strcmp(const char *dest, const char *src)
 {
-	        return __inline_strcmp(dest, src);
+	return __inline_strcmp(dest, src);
 }
-
diff --git a/arch/blackfin/lib/strcpy.c b/arch/blackfin/lib/strcpy.c
index 4dc835a..534589d 100644
--- a/arch/blackfin/lib/strcpy.c
+++ b/arch/blackfin/lib/strcpy.c
@@ -6,6 +6,5 @@
 
 char *strcpy(char *dest, const char *src)
 {
-	        return __inline_strcpy(dest, src);
+	return __inline_strcpy(dest, src);
 }
-
diff --git a/arch/blackfin/lib/strncmp.c b/arch/blackfin/lib/strncmp.c
index 947bcfe..d791f12 100644
--- a/arch/blackfin/lib/strncmp.c
+++ b/arch/blackfin/lib/strncmp.c
@@ -6,6 +6,5 @@
 
 int strncmp(const char *cs, const char *ct, size_t count)
 {
-	        return __inline_strncmp(cs, ct, count);
+	return __inline_strncmp(cs, ct, count);
 }
-
diff --git a/arch/blackfin/lib/strncpy.c b/arch/blackfin/lib/strncpy.c
index 77a9b2e..1fecb5c 100644
--- a/arch/blackfin/lib/strncpy.c
+++ b/arch/blackfin/lib/strncpy.c
@@ -6,6 +6,5 @@
 
 char *strncpy(char *dest, const char *src, size_t n)
 {
-	        return __inline_strncpy(dest, src, n);
+	return __inline_strncpy(dest, src, n);
 }
-
diff --git a/arch/blackfin/mach-bf533/Makefile b/arch/blackfin/mach-bf533/Makefile
index 76d2c2b..8cce173 100644
--- a/arch/blackfin/mach-bf533/Makefile
+++ b/arch/blackfin/mach-bf533/Makefile
@@ -4,6 +4,6 @@
 
 extra-y := head.o
 
-obj-y := ints-priority.o
+obj-y := ints-priority.o dma.o
 
-obj-$(CONFIG_CPU_FREQ_BF533) += cpu.o
+obj-$(CONFIG_CPU_FREQ)   += cpu.o
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
index edd31ce..4545f36 100644
--- a/arch/blackfin/mach-bf533/boards/cm_bf533.c
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -34,7 +34,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -51,11 +51,11 @@
 		.size = 0x00020000,
 		.offset = 0,
 		.mask_flags = MTD_CAP_ROM
-	},{
+	}, {
 		.name = "kernel",
 		.size = 0xe0000,
 		.offset = 0x20000
-	},{
+	}, {
 		.name = "file system",
 		.size = 0x700000,
 		.offset = 0x00100000,
@@ -98,7 +98,7 @@
 		.platform_data = &bfin_spi_flash_data,
 		.controller_data = &spi_flash_chip_info,
 		.mode = SPI_MODE_3,
-	},{
+	}, {
 		.modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
 		.max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 1,               /* Framework bus number */
@@ -145,7 +145,7 @@
 		.start = 0x20200300,
 		.end = 0x20200300 + 16,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF0,
 		.end = IRQ_PF0,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -194,11 +194,11 @@
 		.start = 0x20308000,
 		.end = 0x20308000,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0x20308004,
 		.end = 0x20308004,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF4,
 		.end = IRQ_PF4,
 		.flags = IORESOURCE_IRQ,
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index 0b522d9..0000b8f 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -35,7 +35,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -61,7 +61,7 @@
 		.start = 0x20310300,
 		.end = 0x20310300 + 16,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF9,
 		.end = IRQ_PF9,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -85,11 +85,11 @@
 		.size = 0x00020000,
 		.offset = 0,
 		.mask_flags = MTD_CAP_ROM
-	},{
+	}, {
 		.name = "kernel",
 		.size = 0xe0000,
 		.offset = 0x20000
-	},{
+	}, {
 		.name = "file system",
 		.size = 0x700000,
 		.offset = 0x00100000,
diff --git a/arch/blackfin/mach-bf533/boards/generic_board.c b/arch/blackfin/mach-bf533/boards/generic_board.c
index c0f43cc..9bc1f0d 100644
--- a/arch/blackfin/mach-bf533/boards/generic_board.c
+++ b/arch/blackfin/mach-bf533/boards/generic_board.c
@@ -30,7 +30,7 @@
 
 #include <linux/device.h>
 #include <linux/platform_device.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -53,11 +53,11 @@
 		.start = 0x20300300,
 		.end = 0x20300300 + 16,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PROG_INTB,
 		.end = IRQ_PROG_INTB,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},{
+	}, {
 		/*
 		 *  denotes the flag pin and is used directly if
 		 *  CONFIG_IRQCHIP_DEMUX_GPIO is defined.
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 9a472fe..a9143c4 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -37,7 +37,7 @@
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb_isp1362.h>
 #endif
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -62,7 +62,7 @@
 		.start = 0x20300300,
 		.end = 0x20300300 + 16,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF7,
 		.end = IRQ_PF7,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -83,7 +83,7 @@
 		.start = 0x20300000,
 		.end = 0x20300000 + 0x100,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF10,
 		.end = IRQ_PF10,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -108,11 +108,11 @@
 		.size = 0x00020000,
 		.offset = 0,
 		.mask_flags = MTD_CAP_ROM
-	},{
+	}, {
 		.name = "kernel",
 		.size = 0xe0000,
 		.offset = 0x20000
-	},{
+	}, {
 		.name = "file system",
 		.size = 0x700000,
 		.offset = 0x00100000,
@@ -229,19 +229,19 @@
 
 #if defined(CONFIG_PBX)
 	{
-		.modalias	= "fxs-spi",
-		.max_speed_hz	= 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num	= 1,
-		.chip_select	= 3,
-		.controller_data= &spi_si3xxx_chip_info,
+		.modalias = "fxs-spi",
+		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 1,
+		.chip_select = 3,
+		.controller_data = &spi_si3xxx_chip_info,
 		.mode = SPI_MODE_3,
 	},
 	{
-		.modalias	= "fxo-spi",
-		.max_speed_hz	= 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num	= 1,
-		.chip_select	= 2,
-		.controller_data= &spi_si3xxx_chip_info,
+		.modalias = "fxo-spi",
+		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 1,
+		.chip_select = 2,
+		.controller_data = &spi_si3xxx_chip_info,
 		.mode = SPI_MODE_3,
 	},
 #endif
diff --git a/arch/blackfin/mach-bf533/cpu.c b/arch/blackfin/mach-bf533/cpu.c
index 99547c4..6fd9cfd 100644
--- a/arch/blackfin/mach-bf533/cpu.c
+++ b/arch/blackfin/mach-bf533/cpu.c
@@ -79,8 +79,7 @@
 	int i;
 
 	struct cpufreq_freqs freqs;
-	if (cpufreq_frequency_table_target
-	    (policy, bf533_freq_table, target_freq, relation, &index))
+	if (cpufreq_frequency_table_target(policy, bf533_freq_table, target_freq, relation, &index))
 		return -EINVAL;
 	cclk_mhz = bf533_freq_table[index].frequency;
 	vco_mhz = bf533_freq_table[index].index;
diff --git a/arch/blackfin/mach-bf533/dma.c b/arch/blackfin/mach-bf533/dma.c
new file mode 100644
index 0000000..6c909cf
--- /dev/null
+++ b/arch/blackfin/mach-bf533/dma.c
@@ -0,0 +1,95 @@
+/*
+ * File:         arch/blackfin/mach-bf533/dma.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ *               Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <asm/blackfin.h>
+#include <asm/dma.h>
+
+struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+	(struct dma_register *) DMA0_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_NEXT_DESC_PTR,
+	(struct dma_register *) DMA3_NEXT_DESC_PTR,
+	(struct dma_register *) DMA4_NEXT_DESC_PTR,
+	(struct dma_register *) DMA5_NEXT_DESC_PTR,
+	(struct dma_register *) DMA6_NEXT_DESC_PTR,
+	(struct dma_register *) DMA7_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
+};
+
+int channel2irq(unsigned int channel)
+{
+	int ret_irq = -1;
+
+	switch (channel) {
+	case CH_PPI:
+		ret_irq = IRQ_PPI;
+		break;
+
+	case CH_SPORT0_RX:
+		ret_irq = IRQ_SPORT0_RX;
+		break;
+
+	case CH_SPORT0_TX:
+		ret_irq = IRQ_SPORT0_TX;
+		break;
+
+	case CH_SPORT1_RX:
+		ret_irq = IRQ_SPORT1_RX;
+		break;
+
+	case CH_SPORT1_TX:
+		ret_irq = IRQ_SPORT1_TX;
+		break;
+
+	case CH_SPI:
+		ret_irq = IRQ_SPI;
+		break;
+
+	case CH_UART_RX:
+		ret_irq = IRQ_UART_RX;
+		break;
+
+	case CH_UART_TX:
+		ret_irq = IRQ_UART_TX;
+		break;
+
+	case CH_MEM_STREAM0_SRC:
+	case CH_MEM_STREAM0_DEST:
+		ret_irq = IRQ_MEM_DMA0;
+		break;
+
+	case CH_MEM_STREAM1_SRC:
+	case CH_MEM_STREAM1_DEST:
+		ret_irq = IRQ_MEM_DMA1;
+		break;
+	}
+	return ret_irq;
+}
diff --git a/arch/blackfin/mach-bf533/head.S b/arch/blackfin/mach-bf533/head.S
index 7e2aa8d..7dd0e9c 100644
--- a/arch/blackfin/mach-bf533/head.S
+++ b/arch/blackfin/mach-bf533/head.S
@@ -30,6 +30,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/blackfin.h>
+#include <asm/trace.h>
 #if CONFIG_BFIN_KERNEL_CLOCK
 #include <asm/mach/mem_init.h>
 #endif
@@ -96,6 +97,10 @@
 	M2 = r0;
 	M3 = r0;
 
+	trace_buffer_start(p0,r0);
+	P0 = R1;
+	R0 = R1;
+
 #if CONFIG_DEBUG_KERNEL_START
 
 /*
diff --git a/arch/blackfin/mach-bf533/ints-priority.c b/arch/blackfin/mach-bf533/ints-priority.c
index a3e1789..7d79e0f 100644
--- a/arch/blackfin/mach-bf533/ints-priority.c
+++ b/arch/blackfin/mach-bf533/ints-priority.c
@@ -28,8 +28,8 @@
  */
 
 #include <linux/module.h>
+#include <linux/irq.h>
 #include <asm/blackfin.h>
-#include <asm/irq.h>
 
 void program_IAR(void)
 {
diff --git a/arch/blackfin/mach-bf537/Makefile b/arch/blackfin/mach-bf537/Makefile
index f32d442..7e7c9c8 100644
--- a/arch/blackfin/mach-bf537/Makefile
+++ b/arch/blackfin/mach-bf537/Makefile
@@ -4,6 +4,6 @@
 
 extra-y := head.o
 
-obj-y := ints-priority.o
+obj-y := ints-priority.o dma.o
 
 obj-$(CONFIG_CPU_FREQ)   += cpu.o
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c
index 6a60618..a8f947b 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c
@@ -35,7 +35,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -53,11 +53,11 @@
 		.size = 0x00020000,
 		.offset = 0,
 		.mask_flags = MTD_CAP_ROM
-	},{
+	}, {
 		.name = "kernel",
 		.size = 0xe0000,
 		.offset = 0x20000
-	},{
+	}, {
 		.name = "file system",
 		.size = 0x700000,
 		.offset = 0x00100000,
@@ -202,7 +202,7 @@
 		.start = 0x20200300,
 		.end = 0x20200300 + 16,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF14,
 		.end = IRQ_PF14,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -223,11 +223,11 @@
 		.start = 0x20308000,
 		.end = 0x20308000,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0x20308004,
 		.end = 0x20308004,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PG15,
 		.end = IRQ_PG15,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -262,7 +262,7 @@
 		.start = 0x20200000,
 		.end = 0x20200000 + 0x100,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF7,
 		.end = IRQ_PF7,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -283,7 +283,7 @@
 		.start = 0xFFC00400,
 		.end = 0xFFC004FF,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0xFFC02000,
 		.end = 0xFFC020FF,
 		.flags = IORESOURCE_MEM,
diff --git a/arch/blackfin/mach-bf537/boards/eth_mac.c b/arch/blackfin/mach-bf537/boards/eth_mac.c
index e129a08..a725cc8 100644
--- a/arch/blackfin/mach-bf537/boards/eth_mac.c
+++ b/arch/blackfin/mach-bf537/boards/eth_mac.c
@@ -20,8 +20,7 @@
 #include <linux/module.h>
 #include <asm/blackfin.h>
 
-#if	defined(CONFIG_GENERIC_BOARD) \
-	|| defined(CONFIG_BFIN537_STAMP)
+#if	defined(CONFIG_GENERIC_BOARD) || defined(CONFIG_BFIN537_STAMP)
 
 /*
  * Currently the MAC address is saved in Flash by U-Boot
@@ -43,7 +42,7 @@
  */
 void get_bf537_ether_addr(char *addr)
 {
-	printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n",__FILE__);
+	printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n", __FILE__);
 }
 
 #endif
diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c
index fd57e74..648d984 100644
--- a/arch/blackfin/mach-bf537/boards/generic_board.c
+++ b/arch/blackfin/mach-bf537/boards/generic_board.c
@@ -35,9 +35,9 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
-#include <asm/irq.h>
-#include <asm/bfin5xx_spi.h>
+#include <linux/irq.h>
 #include <linux/usb_sl811.h>
+#include <asm/bfin5xx_spi.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -54,19 +54,19 @@
 		.start = 0x20310000, /* IO PORT */
 		.end = 0x20312000,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0x20311000, /* Attribute Memory */
 		.end = 0x20311FFF,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PROG_INTA,
 		.end = IRQ_PROG_INTA,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},{
+	}, {
 		.start = IRQ_PF4,
 		.end = IRQ_PF4,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},{
+	}, {
 		.start = 6, /* Card Detect PF6 */
 		.end = 6,
 		.flags = IORESOURCE_IRQ,
@@ -95,11 +95,11 @@
 		.start = 0x20300300,
 		.end = 0x20300300 + 16,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PROG_INTB,
 		.end = IRQ_PROG_INTB,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},{
+	}, {
 		/*
 		 *  denotes the flag pin and is used directly if
 		 *  CONFIG_IRQCHIP_DEMUX_GPIO is defined.
@@ -123,15 +123,15 @@
 		.start = 0x20340000,
 		.end = 0x20340000,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0x20340004,
 		.end = 0x20340004,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PROG_INTA,
 		.end = IRQ_PROG_INTA,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},{
+	}, {
 		.start = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO,
 		.end = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -179,15 +179,15 @@
 		.start = 0x20360000,
 		.end = 0x20360000,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0x20360004,
 		.end = 0x20360004,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PROG_INTA,
 		.end = IRQ_PROG_INTA,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},{
+	}, {
 		.start = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO,
 		.end = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO,
 		.flags = IORESOURCE_IRQ,
@@ -228,7 +228,7 @@
 		.start = 0x20300000,
 		.end = 0x20300000 + 0x100,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF7,
 		.end = IRQ_PF7,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -253,11 +253,11 @@
 		.size = 0x00020000,
 		.offset = 0,
 		.mask_flags = MTD_CAP_ROM
-	},{
+	}, {
 		.name = "kernel",
 		.size = 0xe0000,
 		.offset = 0x20000
-	},{
+	}, {
 		.name = "file system",
 		.size = 0x700000,
 		.offset = 0x00100000,
@@ -375,7 +375,7 @@
 		.start = 0xFFC00400,
 		.end = 0xFFC004FF,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0xFFC02000,
 		.end = 0xFFC020FF,
 		.flags = IORESOURCE_MEM,
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index 8aaf76d..8806f12 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -37,7 +37,7 @@
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb_isp1362.h>
 #endif
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <asm/bfin5xx_spi.h>
 #include <linux/usb_sl811.h>
 
@@ -58,15 +58,15 @@
 		.start = 0x20310000, /* IO PORT */
 		.end = 0x20312000,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0x20311000, /* Attribute Memory */
 		.end = 0x20311FFF,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF4,
 		.end = IRQ_PF4,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},{
+	}, {
 		.start = 6, /* Card Detect PF6 */
 		.end = 6,
 		.flags = IORESOURCE_IRQ,
@@ -95,7 +95,7 @@
 		.start = 0x20300300,
 		.end = 0x20300300 + 16,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 
 		.start = IRQ_PF7,
 		.end = IRQ_PF7,
@@ -116,11 +116,11 @@
 		.start = 0x20340000,
 		.end = 0x20340000,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0x20340004,
 		.end = 0x20340004,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = CONFIG_USB_SL811_BFIN_IRQ,
 		.end = CONFIG_USB_SL811_BFIN_IRQ,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -167,11 +167,11 @@
 		.start = 0x20360000,
 		.end = 0x20360000,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0x20360004,
 		.end = 0x20360004,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
 		.end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -212,7 +212,7 @@
 		.start = 0x20300000,
 		.end = 0x20300000 + 0x100,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF7,
 		.end = IRQ_PF7,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -238,11 +238,11 @@
 		.size = 0x00020000,
 		.offset = 0,
 		.mask_flags = MTD_CAP_ROM
-	},{
+	}, {
 		.name = "kernel",
 		.size = 0xe0000,
 		.offset = 0x20000
-	},{
+	}, {
 		.name = "file system",
 		.size = 0x700000,
 		.offset = 0x00100000,
@@ -294,16 +294,6 @@
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-	.ctl_reg	= 0x4, /* send zero */
-	.enable_dma	= 0,
-	.bits_per_word	= 8,
-	.cs_change_per_word = 1,
-};
-#endif
-
-
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
 	.cs_change_per_word = 1,
@@ -392,24 +382,6 @@
 		.mode = SPI_MODE_3,
 	},
 #endif
-#if defined(CONFIG_PBX)
-	{
-		.modalias	= "fxs-spi",
-		.max_speed_hz	= 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num	= 1,
-		.chip_select	= 3,
-		.controller_data= &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-	{
-		.modalias	= "fxo-spi",
-		.max_speed_hz	= 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num	= 1,
-		.chip_select	= 2,
-		.controller_data= &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-#endif
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 {
 	.modalias		= "ad7877",
@@ -451,7 +423,7 @@
 		.start = 0xFFC00400,
 		.end = 0xFFC004FF,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0xFFC02000,
 		.end = 0xFFC020FF,
 		.flags = IORESOURCE_MEM,
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 3a29b4d1..9c43d77 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -37,12 +37,10 @@
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb_isp1362.h>
 #endif
-#include <asm/irq.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <asm/bfin5xx_spi.h>
 #include <linux/usb_sl811.h>
-
+#include <asm/bfin5xx_spi.h>
 #include <linux/spi/ad7877.h>
 
 /*
@@ -85,7 +83,7 @@
 
 int __init bfin_isp1761_init(void)
 {
-	unsigned int num_devices=ARRAY_SIZE(bfin_isp1761_devices);
+	unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices);
 
 	printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
 	set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING);
@@ -107,15 +105,15 @@
 		.start = 0x20310000, /* IO PORT */
 		.end = 0x20312000,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0x20311000, /* Attribute Memory */
 		.end = 0x20311FFF,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF4,
 		.end = IRQ_PF4,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},{
+	}, {
 		.start = 6, /* Card Detect PF6 */
 		.end = 6,
 		.flags = IORESOURCE_IRQ,
@@ -144,7 +142,7 @@
 		.start = 0x20300300,
 		.end = 0x20300300 + 16,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 
 		.start = IRQ_PF7,
 		.end = IRQ_PF7,
@@ -159,17 +157,39 @@
 };
 #endif
 
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource dm9000_resources[] = {
+	[0] = {
+		.start	= 0x203FB800,
+		.end	= 0x203FB800 + 8,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_PF9,
+		.end	= IRQ_PF9,
+		.flags	= (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
+	},
+};
+
+static struct platform_device dm9000_device = {
+	.name		= "dm9000",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(dm9000_resources),
+	.resource	= dm9000_resources,
+};
+#endif
+
 #if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
 static struct resource sl811_hcd_resources[] = {
 	{
 		.start = 0x20340000,
 		.end = 0x20340000,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0x20340004,
 		.end = 0x20340004,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = CONFIG_USB_SL811_BFIN_IRQ,
 		.end = CONFIG_USB_SL811_BFIN_IRQ,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -216,11 +236,11 @@
 		.start = 0x20360000,
 		.end = 0x20360000,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0x20360004,
 		.end = 0x20360004,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
 		.end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -261,7 +281,7 @@
 		.start = 0x20300000,
 		.end = 0x20300000 + 0x100,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF7,
 		.end = IRQ_PF7,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -287,11 +307,11 @@
 		.size = 0x00020000,
 		.offset = 0,
 		.mask_flags = MTD_CAP_ROM
-	},{
+	}, {
 		.name = "kernel",
 		.size = 0xe0000,
 		.offset = 0x20000
-	},{
+	}, {
 		.name = "file system",
 		.size = 0x700000,
 		.offset = 0x00100000,
@@ -361,7 +381,6 @@
 
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
-//	.cs_change_per_word = 1,
 	.enable_dma = 0,
 	.bits_per_word = 16,
 };
@@ -449,19 +468,19 @@
 #endif
 #if defined(CONFIG_PBX)
 	{
-		.modalias	= "fxs-spi",
-		.max_speed_hz	= 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num	= 1,
-		.chip_select	= 3,
-		.controller_data= &spi_si3xxx_chip_info,
+		.modalias = "fxs-spi",
+		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 1,
+		.chip_select = 3,
+		.controller_data = &spi_si3xxx_chip_info,
 		.mode = SPI_MODE_3,
 	},
 	{
-		.modalias	= "fxo-spi",
-		.max_speed_hz	= 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num	= 1,
-		.chip_select	= 2,
-		.controller_data= &spi_si3xxx_chip_info,
+		.modalias = "fxo-spi",
+		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 1,
+		.chip_select = 2,
+		.controller_data = &spi_si3xxx_chip_info,
 		.mode = SPI_MODE_3,
 	},
 #endif
@@ -516,7 +535,7 @@
 		.start = 0xFFC00400,
 		.end = 0xFFC004FF,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0xFFC02000,
 		.end = 0xFFC020FF,
 		.flags = IORESOURCE_MEM,
@@ -571,6 +590,10 @@
 	&smc91x_device,
 #endif
 
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+	&dm9000_device,
+#endif
+
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 	&bfin_mac_device,
 #endif
diff --git a/arch/blackfin/mach-bf537/dma.c b/arch/blackfin/mach-bf537/dma.c
new file mode 100644
index 0000000..706cb97
--- /dev/null
+++ b/arch/blackfin/mach-bf537/dma.c
@@ -0,0 +1,115 @@
+/*
+ * File:         arch/blackfin/mach-bf537/dma.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <asm/blackfin.h>
+#include <asm/dma.h>
+
+struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+	(struct dma_register *) DMA0_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_NEXT_DESC_PTR,
+	(struct dma_register *) DMA3_NEXT_DESC_PTR,
+	(struct dma_register *) DMA4_NEXT_DESC_PTR,
+	(struct dma_register *) DMA5_NEXT_DESC_PTR,
+	(struct dma_register *) DMA6_NEXT_DESC_PTR,
+	(struct dma_register *) DMA7_NEXT_DESC_PTR,
+	(struct dma_register *) DMA8_NEXT_DESC_PTR,
+	(struct dma_register *) DMA9_NEXT_DESC_PTR,
+	(struct dma_register *) DMA10_NEXT_DESC_PTR,
+	(struct dma_register *) DMA11_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
+};
+
+int channel2irq(unsigned int channel)
+{
+	int ret_irq = -1;
+
+	switch (channel) {
+	case CH_PPI:
+		ret_irq = IRQ_PPI;
+		break;
+
+	case CH_EMAC_RX:
+		ret_irq = IRQ_MAC_RX;
+		break;
+
+	case CH_EMAC_TX:
+		ret_irq = IRQ_MAC_TX;
+		break;
+
+	case CH_UART1_RX:
+		ret_irq = IRQ_UART1_RX;
+		break;
+
+	case CH_UART1_TX:
+		ret_irq = IRQ_UART1_TX;
+		break;
+
+	case CH_SPORT0_RX:
+		ret_irq = IRQ_SPORT0_RX;
+		break;
+
+	case CH_SPORT0_TX:
+		ret_irq = IRQ_SPORT0_TX;
+		break;
+
+	case CH_SPORT1_RX:
+		ret_irq = IRQ_SPORT1_RX;
+		break;
+
+	case CH_SPORT1_TX:
+		ret_irq = IRQ_SPORT1_TX;
+		break;
+
+	case CH_SPI:
+		ret_irq = IRQ_SPI;
+		break;
+
+	case CH_UART_RX:
+		ret_irq = IRQ_UART_RX;
+		break;
+
+	case CH_UART_TX:
+		ret_irq = IRQ_UART_TX;
+		break;
+
+	case CH_MEM_STREAM0_SRC:
+	case CH_MEM_STREAM0_DEST:
+		ret_irq = IRQ_MEM_DMA0;
+		break;
+
+	case CH_MEM_STREAM1_SRC:
+	case CH_MEM_STREAM1_DEST:
+		ret_irq = IRQ_MEM_DMA1;
+		break;
+	}
+	return ret_irq;
+}
diff --git a/arch/blackfin/mach-bf537/head.S b/arch/blackfin/mach-bf537/head.S
index 7d902bb..429c8a1 100644
--- a/arch/blackfin/mach-bf537/head.S
+++ b/arch/blackfin/mach-bf537/head.S
@@ -30,6 +30,8 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/blackfin.h>
+#include <asm/trace.h>
+
 #if CONFIG_BFIN_KERNEL_CLOCK
 #include <asm/mach/mem_init.h>
 #endif
@@ -93,6 +95,10 @@
 	M2 = r0;
 	M3 = r0;
 
+	trace_buffer_start(p0,r0);
+	P0 = R1;
+	R0 = R1;
+
 	/* Turn off the icache */
 	p0.l = (IMEM_CONTROL & 0xFFFF);
 	p0.h = (IMEM_CONTROL >> 16);
diff --git a/arch/blackfin/mach-bf537/ints-priority.c b/arch/blackfin/mach-bf537/ints-priority.c
index 2dbf3df..a8b915f 100644
--- a/arch/blackfin/mach-bf537/ints-priority.c
+++ b/arch/blackfin/mach-bf537/ints-priority.c
@@ -28,8 +28,8 @@
  */
 
 #include <linux/module.h>
+#include <linux/irq.h>
 #include <asm/blackfin.h>
-#include <asm/irq.h>
 
 void program_IAR(void)
 {
diff --git a/arch/blackfin/mach-bf548/Kconfig b/arch/blackfin/mach-bf548/Kconfig
new file mode 100644
index 0000000..e78b03d
--- /dev/null
+++ b/arch/blackfin/mach-bf548/Kconfig
@@ -0,0 +1,316 @@
+if (BF54x)
+
+menu "BF548 Specific Configuration"
+
+comment "Interrupt Priority Assignment"
+menu "Priority"
+
+config IRQ_PLL_WAKEUP
+	int "IRQ_PLL_WAKEUP"
+	default 7
+config IRQ_DMAC0_ERR
+	int "IRQ_DMAC0_ERR"
+	default 7
+config IRQ_EPPI0_ERR
+	int "IRQ_EPPI0_ERR"
+	default 7
+config IRQ_SPORT0_ERR
+	int "IRQ_SPORT0_ERR"
+	default 7
+config IRQ_SPORT1_ERR
+	int "IRQ_SPORT1_ERR"
+	default 7
+config IRQ_SPI0_ERR
+	int "IRQ_SPI0_ERR"
+	default 7
+config IRQ_UART0_ERR
+	int "IRQ_UART0_ERR"
+	default 7
+config IRQ_RTC
+	int "IRQ_RTC"
+	default 8
+config IRQ_EPPI0
+	int "IRQ_EPPI0"
+	default 8
+config IRQ_SPORT0_RX
+	int "IRQ_SPORT0_RX"
+	default 9
+config IRQ_SPORT0_TX
+	int "IRQ_SPORT0_TX"
+	default 9
+config IRQ_SPORT1_RX
+	int "IRQ_SPORT1_RX"
+	default 9
+config IRQ_SPORT1_TX
+	int "IRQ_SPORT1_TX"
+	default 9
+config IRQ_SPI0
+	int "IRQ_SPI0"
+	default 10
+config IRQ_UART0_RX
+	int "IRQ_UART0_RX"
+	default 10
+config IRQ_UART0_TX
+	int "IRQ_UART0_TX"
+	default 10
+config IRQ_TIMER8
+	int "IRQ_TIMER8"
+	default 11
+config IRQ_TIMER9
+	int "IRQ_TIMER9"
+	default 11
+config IRQ_TIMER10
+	int "IRQ_TIMER10"
+	default 11
+config IRQ_PINT0
+	int "IRQ_PINT0"
+	default 12
+config IRQ_PINT1
+	int "IRQ_PINT0"
+	default 12
+config IRQ_MDMAS0
+	int "IRQ_MDMAS0"
+	default 13
+config IRQ_MDMAS1
+	int "IRQ_DMDMAS1"
+	default 13
+config IRQ_WATCHDOG
+	int "IRQ_WATCHDOG"
+	default 13
+config IRQ_DMAC1_ERR
+	int "IRQ_DMAC1_ERR"
+	default 7
+config IRQ_SPORT2_ERR
+	int "IRQ_SPORT2_ERR"
+	default 7
+config IRQ_SPORT3_ERR
+	int "IRQ_SPORT3_ERR"
+	default 7
+config IRQ_MXVR_DATA
+	int "IRQ MXVR Data"
+	default 7
+config IRQ_SPI1_ERR
+	int "IRQ_SPI1_ERR"
+	default 7
+config IRQ_SPI2_ERR
+	int "IRQ_SPI2_ERR"
+	default 7
+config IRQ_UART1_ERR
+	int "IRQ_UART1_ERR"
+	default 7
+config IRQ_UART2_ERR
+	int "IRQ_UART2_ERR"
+	default 7
+config IRQ_CAN0_ERR
+	int "IRQ_CAN0_ERR"
+	default 7
+config IRQ_SPORT2_RX
+	int "IRQ_SPORT2_RX"
+	default 9
+config IRQ_SPORT2_TX
+	int "IRQ_SPORT2_TX"
+	default 9
+config IRQ_SPORT3_RX
+	int "IRQ_SPORT3_RX"
+	default 9
+config IRQ_SPORT3_TX
+	int "IRQ_SPORT3_TX"
+	default 9
+config IRQ_EPPI1
+	int "IRQ_EPPI1"
+	default 9
+config IRQ_EPPI2
+	int "IRQ_EPPI2"
+	default 9
+config IRQ_SPI1
+	int "IRQ_SPI1"
+	default 10
+config IRQ_SPI2
+	int "IRQ_SPI2"
+	default 10
+config IRQ_UART1_RX
+	int "IRQ_UART1_RX"
+	default 10
+config IRQ_UART1_TX
+	int "IRQ_UART1_TX"
+	default 10
+config IRQ_ATAPI_RX
+	int "IRQ_ATAPI_RX"
+	default 10
+config IRQ_ATAPI_TX
+	int "IRQ_ATAPI_TX"
+	default 10
+config IRQ_TWI0
+	int "IRQ_TWI0"
+	default 11
+config IRQ_TWI1
+	int "IRQ_TWI1"
+	default 11
+config IRQ_CAN0_RX
+	int "IRQ_CAN_RX"
+	default 11
+config IRQ_CAN0_TX
+	int "IRQ_CAN_TX"
+	default 11
+config IRQ_MDMAS2
+	int "IRQ_MDMAS2"
+	default 13
+config IRQ_MDMAS3
+	int "IRQ_DMMAS3"
+	default 13
+config IRQ_MXVR_ERR
+	int "IRQ_MXVR_ERR"
+	default 11
+config IRQ_MXVR_MSG
+	int "IRQ_MXVR_MSG"
+	default 11
+config IRQ_MXVR_PKT
+	int "IRQ_MXVR_PKT"
+	default 11
+config IRQ_EPPI1_ERR
+	int "IRQ_EPPI1_ERR"
+	default 7
+config IRQ_EPPI2_ERR
+	int "IRQ_EPPI2_ERR"
+	default 7
+config IRQ_UART3_ERR
+	int "IRQ_UART3_ERR"
+	default 7
+config IRQ_HOST_ERR
+	int "IRQ_HOST_ERR"
+	default 7
+config IRQ_PIXC_ERR
+	int "IRQ_PIXC_ERR"
+	default 7
+config IRQ_NFC_ERR
+	int "IRQ_NFC_ERR"
+	default 7
+config IRQ_ATAPI_ERR
+	int "IRQ_ATAPI_ERR"
+	default 7
+config IRQ_CAN1_ERR
+	int "IRQ_CAN1_ERR"
+	default 7
+config IRQ_HS_DMA_ERR
+	int "IRQ Handshake DMA Status"
+	default 7
+config IRQ_PIXC_IN0
+	int "IRQ PIXC IN0"
+	default 8
+config IRQ_PIXC_IN1
+	int "IRQ PIXC IN1"
+	default 8
+config IRQ_PIXC_OUT
+	int "IRQ PIXC OUT"
+	default 8
+config IRQ_SDH
+	int "IRQ SDH"
+	default 8
+config IRQ_CNT
+	int "IRQ CNT"
+	default 8
+config IRQ_KEY
+	int "IRQ KEY"
+	default 8
+config IRQ_CAN1_RX
+	int "IRQ CAN1 RX"
+	default 11
+config IRQ_CAN1_TX
+	int "IRQ_CAN1_TX"
+	default 11
+config IRQ_SDH_MASK0
+	int "IRQ_SDH_MASK0"
+	default 11
+config IRQ_SDH_MASK1
+	int "IRQ_SDH_MASK1"
+	default 11
+config IRQ_USB_INT0
+	int "IRQ USB INT0"
+	default 11
+config IRQ_USB_INT1
+	int "IRQ USB INT1"
+	default 11
+config IRQ_USB_INT2
+	int "IRQ USB INT2"
+	default 11
+config IRQ_USB_DMA
+	int "IRQ USB DMA"
+	default 11
+config IRQ_OTPSEC
+	int "IRQ OPTSEC"
+	default 11
+config IRQ_TIMER0
+	int "IRQ_TIMER0"
+	default 11
+config IRQ_TIMER1
+	int "IRQ_TIMER1"
+	default 11
+config IRQ_TIMER2
+	int "IRQ_TIMER2"
+	default 11
+config IRQ_TIMER3
+	int "IRQ_TIMER3"
+	default 11
+config IRQ_TIMER4
+	int "IRQ_TIMER4"
+	default 11
+config IRQ_TIMER5
+	int "IRQ_TIMER5"
+	default 11
+config IRQ_TIMER6
+	int "IRQ_TIMER6"
+	default 11
+config IRQ_TIMER7
+	int "IRQ_TIMER7"
+	default 11
+config IRQ_PINT2
+	int "IRQ_PIN2"
+	default 11
+config IRQ_PINT3
+	int "IRQ_PIN3"
+	default 11
+
+	help
+	  Enter the priority numbers between 7-13 ONLY.  Others are Reserved.
+	  This applies to all the above.  It is not recommended to assign the
+	  highest priority number 7 to UART or any other device.
+
+endmenu
+
+comment "Pin Interrupt to Port Assignment"
+menu "Assignment"
+
+config PINTx_REASSIGN
+	bool "Reprogram PINT Assignment"
+	default n
+	help
+	  The interrupt assignment registers controls the pin-to-interrupt
+	  assignment in a byte-wide manner. Each option allows you to select
+	  a set of pins (High/Low Byte) of an specific Port being mapped
+	  to one of the four PIN Interrupts IRQ_PINTx.
+
+	  You shouldn't change any of these unless you know exactly what you're doing.
+	  Please consult the Blackfin BF54x Processor Hardware Reference Manual.
+
+config PINT0_ASSIGN
+	hex "PINT0_ASSIGN"
+	depends on PINTx_REASSIGN
+	default 0x00000101
+config PINT1_ASSIGN
+	hex "PINT1_ASSIGN"
+	depends on PINTx_REASSIGN
+	default 0x01010000
+config PINT2_ASSIGN
+	hex "PINT2_ASSIGN"
+	depends on PINTx_REASSIGN
+	default 0x00000101
+config PINT3_ASSIGN
+	hex "PINT3_ASSIGN"
+	depends on PINTx_REASSIGN
+	default 0x02020303
+
+endmenu
+
+endmenu
+
+endif
diff --git a/arch/blackfin/mach-bf548/Makefile b/arch/blackfin/mach-bf548/Makefile
new file mode 100644
index 0000000..060ad78
--- /dev/null
+++ b/arch/blackfin/mach-bf548/Makefile
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf537/Makefile
+#
+
+extra-y := head.o
+
+obj-y := ints-priority.o dma.o gpio.o
+
+obj-$(CONFIG_CPU_FREQ)   += cpu.o
diff --git a/arch/blackfin/mach-bf548/boards/Makefile b/arch/blackfin/mach-bf548/boards/Makefile
new file mode 100644
index 0000000..486e07c
--- /dev/null
+++ b/arch/blackfin/mach-bf548/boards/Makefile
@@ -0,0 +1,5 @@
+#
+# arch/blackfin/mach-bf548/boards/Makefile
+#
+
+obj-$(CONFIG_BFIN548_EZKIT)		+= ezkit.o led.o
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
new file mode 100644
index 0000000..96ad95f
--- /dev/null
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -0,0 +1,114 @@
+/*
+ * File:         arch/blackfin/mach-bf548/boards/ezkit.c
+ * Based on:     arch/blackfin/mach-bf537/boards/ezkit.c
+ * Author:       Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ *               Copyright 2005 National ICT Australia (NICTA)
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/irq.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "ADSP-BF548-EZKIT";
+
+/*
+ *  Driver needs to know address, irq and flag pin.
+ */
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+	.name = "rtc-bfin",
+	.id   = -1,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	{
+		.start = 0xFFC00400,
+		.end = 0xFFC004FF,
+		.flags = IORESOURCE_MEM,
+	},
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	{
+		.start = 0xFFC02000,
+		.end = 0xFFC020FF,
+		.flags = IORESOURCE_MEM,
+	},
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+	{
+		.start = 0xFFC02100,
+		.end = 0xFFC021FF,
+		.flags = IORESOURCE_MEM,
+	},
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+	{
+		.start = 0xFFC03100,
+		.end = 0xFFC031FF,
+	},
+#endif
+};
+
+static struct platform_device bfin_uart_device = {
+	.name = "bfin-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_uart_resources),
+	.resource = bfin_uart_resources,
+};
+#endif
+
+static struct platform_device *ezkit_devices[] __initdata = {
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+	&rtc_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+	&bfin_uart_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+	printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+	platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices));
+	return 0;
+}
+
+arch_initcall(stamp_init);
diff --git a/arch/blackfin/mach-bf548/boards/led.S b/arch/blackfin/mach-bf548/boards/led.S
new file mode 100644
index 0000000..f47daf3
--- /dev/null
+++ b/arch/blackfin/mach-bf548/boards/led.S
@@ -0,0 +1,172 @@
+/****************************************************
+ * LED1 ---- PG6        LED2 ---- PG7               *
+ * LED3 ---- PG8        LED4 ---- PG9               *
+ * LED5 ---- PG10       LED6 ---- PG11              *
+ ****************************************************/
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+
+/* All functions in this file save the registers they uses.
+   So there is no need to save any registers before calling them.  */
+
+	.text;
+
+/* Initialize LEDs.  */
+
+ENTRY(_led_init)
+	LINK 0;
+	[--SP] = P0;
+	[--SP] = R0;
+	[--SP] = R1;
+	[--SP] = R2;
+	R1 = (PG6|PG7|PG8|PG9|PG10|PG11)(Z);
+	R2 = ~R1;
+
+	P0.H = hi(PORTG_FER);
+	P0.L = lo(PORTG_FER);
+	R0 = W[P0](Z);
+	SSYNC;
+	R0 = R0 & R2;
+	W[P0] = R0.L;
+	SSYNC;
+
+	P0.H = hi(PORTG_DIR_SET);
+	P0.L = lo(PORTG_DIR_SET);
+	W[P0] = R1.L;
+	SSYNC;
+
+	P0.H = hi(PORTG_INEN);
+	P0.L = lo(PORTG_INEN);
+	R0 = W[P0](Z);
+	SSYNC;
+	R0 = R0 & R2;
+	W[P0] = R0.L;
+	SSYNC;
+
+	R2 = [SP++];
+	R1 = [SP++];
+	R0 = [SP++];
+	P0 = [SP++];
+	RTS;
+	.size	_led_init, .-_led_init
+
+/* Set one LED on. Leave other LEDs unchanged.
+   It expects the LED number passed through R0.  */
+
+ENTRY(_led_on)
+	LINK 0;
+	[--SP] = P0;
+	[--SP] = R1;
+	CALL _led_init;
+	R1 = 1;
+	R0 += 5;
+	R1 <<= R0;
+	P0.H = hi(PORTG_SET);
+	P0.L = lo(PORTG_SET);
+	W[P0] = R1.L;
+	SSYNC;
+	R1 = [SP++];
+	P0 = [SP++];
+	UNLINK;
+	RTS;
+	.size	_led_on, .-_led_on
+
+/* Set one LED off. Leave other LEDs unchanged.  */
+
+ENTRY(_led_off)
+	LINK 0;
+	[--SP] = P0;
+	[--SP] = R1;
+	CALL _led_init;
+	R1 = 1;
+	R0 += 5;
+	R1 <<= R0;
+	P0.H = hi(PORTG_CLEAR);
+	P0.L = lo(PORTG_CLEAR);
+	W[P0] = R1.L;
+	SSYNC;
+	R1 = [SP++];
+	P0 = [SP++];
+	UNLINK;
+	RTS;
+	.size	_led_off, .-_led_off
+
+/* Toggle one LED. Leave other LEDs unchanged.  */
+
+ENTRY(_led_toggle)
+	LINK 0;
+	[--SP] = P0;
+	[--SP] = R1;
+	CALL _led_init;
+	R1 = 1;
+	R0 += 5;
+	R1 <<= R0;
+	P0.H = hi(PORTG);
+	P0.L = lo(PORTG);
+	R0 = W[P0](Z);
+	SSYNC;
+	R0 = R0 ^ R1;
+	W[P0] = R0.L;
+	SSYNC;
+	R1 = [SP++];
+	P0 = [SP++];
+	UNLINK;
+	RTS;
+	.size	_led_toggle, .-_led_toggle
+
+/* Display the number using LEDs in binary format.  */
+
+ENTRY(_led_disp_num)
+	LINK 0;
+	[--SP] = P0;
+	[--SP] = R1;
+	[--SP] = R2;
+	CALL _led_init;
+	R1 = 0x3f(X);
+	R0 = R0 & R1;
+	R2 = 6(X);
+	R0 <<= R2;
+	R1 <<= R2;
+	P0.H = hi(PORTG);
+	P0.L = lo(PORTG);
+	R2 = W[P0](Z);
+	SSYNC;
+	R1 = ~R1;
+	R2 = R2 & R1;
+	R2 = R2 | R0;
+	W[P0] = R2.L;
+	SSYNC;
+	R2 = [SP++];
+	R1 = [SP++];
+	P0 = [SP++];
+	UNLINK;
+	RTS;
+	.size	_led_disp_num, .-_led_disp_num
+
+/* Toggle the number using LEDs in binary format.  */
+
+ENTRY(_led_toggle_num)
+	LINK 0;
+	[--SP] = P0;
+	[--SP] = R1;
+	[--SP] = R2;
+	CALL _led_init;
+	R1 = 0x3f(X);
+	R0 = R0 & R1;
+	R1 = 6(X);
+	R0 <<= R1;
+	P0.H = hi(PORTG);
+	P0.L = lo(PORTG);
+	R1 = W[P0](Z);
+	SSYNC;
+	R1 = R1 ^ R0;
+	W[P0] = R1.L;
+	SSYNC;
+	R2 = [SP++];
+	R1 = [SP++];
+	P0 = [SP++];
+	UNLINK;
+	RTS;
+	.size	_led_toggle_num, .-_led_toggle_num
+
diff --git a/arch/blackfin/mach-bf548/cpu.c b/arch/blackfin/mach-bf548/cpu.c
new file mode 100644
index 0000000..4298a3c
--- /dev/null
+++ b/arch/blackfin/mach-bf548/cpu.c
@@ -0,0 +1,159 @@
+/*
+ * File:         arch/blackfin/mach-bf548/cpu.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  clock scaling for the bf54x
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <asm/dpmc.h>
+#include <linux/fs.h>
+#include <asm/bfin-global.h>
+
+/* CONFIG_CLKIN_HZ=25000000 */
+#define VCO5 (CONFIG_CLKIN_HZ*45)
+#define VCO4 (CONFIG_CLKIN_HZ*36)
+#define VCO3 (CONFIG_CLKIN_HZ*27)
+#define VCO2 (CONFIG_CLKIN_HZ*18)
+#define VCO1 (CONFIG_CLKIN_HZ*9)
+#define VCO(x) VCO##x
+
+#define MFREQ(x) {VCO(x),VCO(x)/4},{VCO(x),VCO(x)/2},{VCO(x),VCO(x)}
+/* frequency */
+static struct cpufreq_frequency_table bf548_freq_table[] = {
+	MFREQ(1),
+	MFREQ(3),
+	{VCO4, VCO4 / 2}, {VCO4, VCO4},
+	MFREQ(5),
+	{0, CPUFREQ_TABLE_END},
+};
+
+/*
+ * dpmc_fops->ioctl()
+ * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+ */
+static int bf548_getfreq(unsigned int cpu)
+{
+	unsigned long cclk_mhz;
+
+	/* The driver only support single cpu */
+	if (cpu == 0)
+		dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz);
+	else
+		cclk_mhz = -1;
+
+	return cclk_mhz;
+}
+
+static int bf548_target(struct cpufreq_policy *policy,
+			    unsigned int target_freq, unsigned int relation)
+{
+	unsigned long cclk_mhz;
+	unsigned long vco_mhz;
+	unsigned long flags;
+	unsigned int index;
+	struct cpufreq_freqs freqs;
+
+	if (cpufreq_frequency_table_target(policy, bf548_freq_table, target_freq, relation, &index))
+		return -EINVAL;
+
+	cclk_mhz = bf548_freq_table[index].frequency;
+	vco_mhz = bf548_freq_table[index].index;
+
+	dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz);
+	freqs.old = bf548_getfreq(0);
+	freqs.new = cclk_mhz;
+	freqs.cpu = 0;
+
+	pr_debug("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n",
+	         cclk_mhz, vco_mhz, index, target_freq, freqs.old);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	local_irq_save(flags);
+	dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz);
+	local_irq_restore(flags);
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	vco_mhz = get_vco();
+	cclk_mhz = get_cclk();
+	return 0;
+}
+
+/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on
+ * this platform, anyway.
+ */
+static int bf548_verify_speed(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, &bf548_freq_table);
+}
+
+static int __init __bf548_cpu_init(struct cpufreq_policy *policy)
+{
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	/*Now ,only support one cpu */
+	policy->cur = bf548_getfreq(0);
+	cpufreq_frequency_table_get_attr(bf548_freq_table, policy->cpu);
+	return cpufreq_frequency_table_cpuinfo(policy, bf548_freq_table);
+}
+
+static struct freq_attr *bf548_freq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver bf548_driver = {
+	.verify = bf548_verify_speed,
+	.target = bf548_target,
+	.get = bf548_getfreq,
+	.init = __bf548_cpu_init,
+	.name = "bf548",
+	.owner = THIS_MODULE,
+	.attr = bf548_freq_attr,
+};
+
+static int __init bf548_cpu_init(void)
+{
+	return cpufreq_register_driver(&bf548_driver);
+}
+
+static void __exit bf548_cpu_exit(void)
+{
+	cpufreq_unregister_driver(&bf548_driver);
+}
+
+MODULE_AUTHOR("Mickael Kang");
+MODULE_DESCRIPTION("cpufreq driver for BF548 CPU");
+MODULE_LICENSE("GPL");
+
+module_init(bf548_cpu_init);
+module_exit(bf548_cpu_exit);
diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c
new file mode 100644
index 0000000..a818411
--- /dev/null
+++ b/arch/blackfin/mach-bf548/dma.c
@@ -0,0 +1,156 @@
+/*
+ * File:         arch/blackfin/mach-bf561/dma.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <asm/blackfin.h>
+#include <asm/dma.h>
+
+ struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+	(struct dma_register *) DMA0_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_NEXT_DESC_PTR,
+	(struct dma_register *) DMA3_NEXT_DESC_PTR,
+	(struct dma_register *) DMA4_NEXT_DESC_PTR,
+	(struct dma_register *) DMA5_NEXT_DESC_PTR,
+	(struct dma_register *) DMA6_NEXT_DESC_PTR,
+	(struct dma_register *) DMA7_NEXT_DESC_PTR,
+	(struct dma_register *) DMA8_NEXT_DESC_PTR,
+	(struct dma_register *) DMA9_NEXT_DESC_PTR,
+	(struct dma_register *) DMA10_NEXT_DESC_PTR,
+	(struct dma_register *) DMA11_NEXT_DESC_PTR,
+	(struct dma_register *) DMA12_NEXT_DESC_PTR,
+	(struct dma_register *) DMA13_NEXT_DESC_PTR,
+	(struct dma_register *) DMA14_NEXT_DESC_PTR,
+	(struct dma_register *) DMA15_NEXT_DESC_PTR,
+	(struct dma_register *) DMA16_NEXT_DESC_PTR,
+	(struct dma_register *) DMA17_NEXT_DESC_PTR,
+	(struct dma_register *) DMA18_NEXT_DESC_PTR,
+	(struct dma_register *) DMA19_NEXT_DESC_PTR,
+	(struct dma_register *) DMA20_NEXT_DESC_PTR,
+	(struct dma_register *) DMA21_NEXT_DESC_PTR,
+	(struct dma_register *) DMA22_NEXT_DESC_PTR,
+	(struct dma_register *) DMA23_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_D2_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_S2_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_D3_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA_S3_NEXT_DESC_PTR,
+};
+
+int channel2irq(unsigned int channel)
+{
+	int ret_irq = -1;
+
+	switch (channel) {
+	case CH_SPORT0_RX:
+		ret_irq = IRQ_SPORT0_RX;
+		break;
+	case CH_SPORT0_TX:
+		ret_irq = IRQ_SPORT0_TX;
+		break;
+	case CH_SPORT1_RX:
+		ret_irq = IRQ_SPORT1_RX;
+		break;
+	case CH_SPORT1_TX:
+		ret_irq = IRQ_SPORT1_TX;
+	case CH_SPI0:
+		ret_irq = IRQ_SPI0;
+		break;
+	case CH_SPI1:
+		ret_irq = IRQ_SPI1;
+		break;
+	case CH_UART0_RX:
+		ret_irq = IRQ_UART_RX;
+		break;
+	case CH_UART0_TX:
+		ret_irq = IRQ_UART_TX;
+		break;
+	case CH_UART1_RX:
+		ret_irq = IRQ_UART_RX;
+		break;
+	case CH_UART1_TX:
+		ret_irq = IRQ_UART_TX;
+		break;
+	case CH_EPPI0:
+		ret_irq = IRQ_EPPI0;
+		break;
+	case CH_EPPI1:
+		ret_irq = IRQ_EPPI1;
+		break;
+	case CH_EPPI2:
+		ret_irq = IRQ_EPPI2;
+		break;
+	case CH_PIXC_IMAGE:
+		ret_irq = IRQ_PIXC_IN0;
+		break;
+	case CH_PIXC_OVERLAY:
+		ret_irq = IRQ_PIXC_IN1;
+		break;
+	case CH_PIXC_OUTPUT:
+		ret_irq = IRQ_PIXC_OUT;
+		break;
+	case CH_SPORT2_RX:
+		ret_irq = IRQ_SPORT2_RX;
+		break;
+	case CH_SPORT2_TX:
+		ret_irq = IRQ_SPORT2_TX;
+		break;
+	case CH_SPORT3_RX:
+		ret_irq = IRQ_SPORT3_RX;
+		break;
+	case CH_SPORT3_TX:
+		ret_irq = IRQ_SPORT3_TX;
+		break;
+	case CH_SDH:
+		ret_irq = IRQ_SDH;
+		break;
+	case CH_SPI2:
+		ret_irq = IRQ_SPI2;
+		break;
+	case CH_MEM_STREAM0_SRC:
+	case CH_MEM_STREAM0_DEST:
+		ret_irq = IRQ_MDMAS0;
+		break;
+	case CH_MEM_STREAM1_SRC:
+	case CH_MEM_STREAM1_DEST:
+		ret_irq = IRQ_MDMAS1;
+		break;
+	case CH_MEM_STREAM2_SRC:
+	case CH_MEM_STREAM2_DEST:
+		ret_irq = IRQ_MDMAS2;
+		break;
+	case CH_MEM_STREAM3_SRC:
+	case CH_MEM_STREAM3_DEST:
+		ret_irq = IRQ_MDMAS3;
+		break;
+	}
+	return ret_irq;
+}
diff --git a/arch/blackfin/mach-bf548/gpio.c b/arch/blackfin/mach-bf548/gpio.c
new file mode 100644
index 0000000..0da5f00
--- /dev/null
+++ b/arch/blackfin/mach-bf548/gpio.c
@@ -0,0 +1,323 @@
+/*
+ * File:         arch/blackfin/mach-bf548/gpio.c
+ * Based on:
+ * Author:       Michael Hennerich (hennerich@blackfin.uclinux.org)
+ *
+ * Created:
+ * Description:  GPIO Abstraction Layer
+ *
+ * Modified:
+ *               Copyright 2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <asm/blackfin.h>
+#include <asm/gpio.h>
+#include <asm/portmux.h>
+#include <linux/irq.h>
+
+static struct gpio_port_t *gpio_array[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+	(struct gpio_port_t *)PORTA_FER,
+	(struct gpio_port_t *)PORTB_FER,
+	(struct gpio_port_t *)PORTC_FER,
+	(struct gpio_port_t *)PORTD_FER,
+	(struct gpio_port_t *)PORTE_FER,
+	(struct gpio_port_t *)PORTF_FER,
+	(struct gpio_port_t *)PORTG_FER,
+	(struct gpio_port_t *)PORTH_FER,
+	(struct gpio_port_t *)PORTI_FER,
+	(struct gpio_port_t *)PORTJ_FER,
+};
+
+static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
+static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+inline int check_gpio(unsigned short gpio)
+{
+	if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
+	    || gpio == GPIO_PH14 || gpio == GPIO_PH15
+	    || gpio == GPIO_PJ14 || gpio == GPIO_PJ15
+	    || gpio > MAX_BLACKFIN_GPIOS)
+		return -EINVAL;
+	return 0;
+}
+
+inline void portmux_setup(unsigned short portno, unsigned short function)
+{
+	u32 pmux;
+
+	pmux = gpio_array[gpio_bank(portno)]->port_mux;
+
+	pmux &= ~(0x3 << (2 * gpio_sub_n(portno)));
+	pmux |= (function & 0x3) << (2 * gpio_sub_n(portno));
+
+	gpio_array[gpio_bank(portno)]->port_mux = pmux;
+
+}
+
+inline u16 get_portmux(unsigned short portno)
+{
+	u32 pmux;
+
+	pmux = gpio_array[gpio_bank(portno)]->port_mux;
+
+	return (pmux >> (2 * gpio_sub_n(portno)) & 0x3);
+
+}
+
+static void port_setup(unsigned short gpio, unsigned short usage)
+{
+	if (usage == GPIO_USAGE) {
+		if (gpio_array[gpio_bank(gpio)]->port_fer & gpio_bit(gpio))
+			printk(KERN_WARNING
+			       "bfin-gpio: Possible Conflict with Peripheral "
+			       "usage and GPIO %d detected!\n", gpio);
+		gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
+	} else
+		gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
+	SSYNC();
+}
+
+static int __init bfin_gpio_init(void)
+{
+	printk(KERN_INFO "Blackfin GPIO Controller\n");
+
+	return 0;
+}
+
+arch_initcall(bfin_gpio_init);
+
+int peripheral_request(unsigned short per, const char *label)
+{
+	unsigned long flags;
+	unsigned short ident = P_IDENT(per);
+
+	if (!(per & P_DEFINED))
+		return -ENODEV;
+
+	if (check_gpio(ident) < 0)
+		return -EINVAL;
+
+	local_irq_save(flags);
+
+	if (unlikely(reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) {
+		printk(KERN_ERR
+		       "%s: Peripheral %d is already reserved as GPIO!\n",
+		       __FUNCTION__, per);
+		dump_stack();
+		local_irq_restore(flags);
+		return -EBUSY;
+	}
+
+	if (unlikely(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident))) {
+
+		u16 funct = get_portmux(ident);
+
+		if (!((per & P_MAYSHARE) && (funct == P_FUNCT2MUX(per)))) {
+			printk(KERN_ERR
+			       "%s: Peripheral %d is already reserved!\n",
+			       __FUNCTION__, per);
+			dump_stack();
+			local_irq_restore(flags);
+			return -EBUSY;
+		}
+	}
+
+	reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident);
+
+	portmux_setup(ident, P_FUNCT2MUX(per));
+	port_setup(ident, PERIPHERAL_USAGE);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(peripheral_request);
+
+int peripheral_request_list(unsigned short per[], const char *label)
+{
+
+	u16 cnt;
+	int ret;
+
+	for (cnt = 0; per[cnt] != 0; cnt++) {
+		ret = peripheral_request(per[cnt], label);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(peripheral_request_list);
+
+void peripheral_free(unsigned short per)
+{
+	unsigned long flags;
+	unsigned short ident = P_IDENT(per);
+
+	if (!(per & P_DEFINED))
+		return;
+
+	if (check_gpio(ident) < 0)
+		return;
+
+	local_irq_save(flags);
+
+	if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) {
+		printk(KERN_ERR "bfin-gpio: Peripheral %d wasn't reserved!\n", per);
+		dump_stack();
+		local_irq_restore(flags);
+		return;
+	}
+
+	if (!(per & P_MAYSHARE)) {
+		port_setup(ident, GPIO_USAGE);
+	}
+
+	reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident);
+
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(peripheral_free);
+
+void peripheral_free_list(unsigned short per[])
+{
+	u16 cnt;
+
+	for (cnt = 0; per[cnt] != 0; cnt++) {
+		peripheral_free(per[cnt]);
+	}
+
+}
+EXPORT_SYMBOL(peripheral_free_list);
+
+/***********************************************************
+*
+* FUNCTIONS: Blackfin GPIO Driver
+*
+* INPUTS/OUTPUTS:
+* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
+*
+*
+* DESCRIPTION: Blackfin GPIO Driver API
+*
+* CAUTION:
+*************************************************************
+* MODIFICATION HISTORY :
+**************************************************************/
+
+int gpio_request(unsigned short gpio, const char *label)
+{
+	unsigned long flags;
+
+	if (check_gpio(gpio) < 0)
+		return -EINVAL;
+
+	local_irq_save(flags);
+
+	if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+		printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio);
+		dump_stack();
+		local_irq_restore(flags);
+		return -EBUSY;
+	}
+
+	if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+		printk(KERN_ERR
+		       "bfin-gpio: GPIO %d is already reserved as Peripheral!\n", gpio);
+		dump_stack();
+		local_irq_restore(flags);
+		return -EBUSY;
+	}
+
+	reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
+
+	local_irq_restore(flags);
+
+	port_setup(gpio, GPIO_USAGE);
+
+	return 0;
+}
+EXPORT_SYMBOL(gpio_request);
+
+void gpio_free(unsigned short gpio)
+{
+	unsigned long flags;
+
+	if (check_gpio(gpio) < 0)
+		return;
+
+	local_irq_save(flags);
+
+	if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
+		printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio);
+		dump_stack();
+		local_irq_restore(flags);
+		return;
+	}
+
+	reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_free);
+
+void gpio_direction_input(unsigned short gpio)
+{
+	unsigned long flags;
+
+	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+
+	local_irq_save(flags);
+	gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
+	gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+void gpio_direction_output(unsigned short gpio)
+{
+	unsigned long flags;
+
+	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+
+	local_irq_save(flags);
+	gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio);
+	gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+void gpio_set_value(unsigned short gpio, unsigned short arg)
+{
+	if (arg)
+		gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio);
+	else
+		gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio);
+
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+unsigned short gpio_get_value(unsigned short gpio)
+{
+	return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio)));
+}
+EXPORT_SYMBOL(gpio_get_value);
diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S
new file mode 100644
index 0000000..06751ae
--- /dev/null
+++ b/arch/blackfin/mach-bf548/head.S
@@ -0,0 +1,512 @@
+/*
+ * File:         arch/blackfin/mach-bf548/head.S
+ * Based on:     arch/blackfin/mach-bf537/head.S
+ * Author:       Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
+ *
+ * Created:      1998
+ * Description:  Startup code for Blackfin BF548
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#include <asm/trace.h>
+#if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach/mem_init.h>
+#endif
+
+.global __rambase
+.global __ramstart
+.global __ramend
+.extern ___bss_stop
+.extern ___bss_start
+.extern _bf53x_relocate_l1_mem
+
+#define INITIAL_STACK   0xFFB01000
+
+.text
+
+ENTRY(__start)
+ENTRY(__stext)
+	/* R0: argument of command line string, passed from uboot, save it */
+	R7 = R0;
+	/* Set the SYSCFG register */
+	R0 = 0x36;
+	SYSCFG = R0;   /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
+	R0 = 0;
+
+	/* Clear Out All the data and pointer  Registers*/
+	R1 = R0;
+	R2 = R0;
+	R3 = R0;
+	R4 = R0;
+	R5 = R0;
+	R6 = R0;
+
+	P0 = R0;
+	P1 = R0;
+	P2 = R0;
+	P3 = R0;
+	P4 = R0;
+	P5 = R0;
+
+	LC0 = r0;
+	LC1 = r0;
+	L0 = r0;
+	L1 = r0;
+	L2 = r0;
+	L3 = r0;
+
+	/* Clear Out All the DAG Registers*/
+	B0 = r0;
+	B1 = r0;
+	B2 = r0;
+	B3 = r0;
+
+	I0 = r0;
+	I1 = r0;
+	I2 = r0;
+	I3 = r0;
+
+	M0 = r0;
+	M1 = r0;
+	M2 = r0;
+	M3 = r0;
+
+	trace_buffer_start(p0,r0);
+	P0 = R1;
+	R0 = R1;
+
+	/* Turn off the icache */
+	p0.l = (IMEM_CONTROL & 0xFFFF);
+	p0.h = (IMEM_CONTROL >> 16);
+	R1 = [p0];
+	R0 = ~ENICPLB;
+	R0 = R0 & R1;
+	[p0] = R0;
+	SSYNC;
+
+	/* Turn off the dcache */
+	p0.l = (DMEM_CONTROL & 0xFFFF);
+	p0.h = (DMEM_CONTROL >> 16);
+	R1 = [p0];
+	R0 = ~ENDCPLB;
+	R0 = R0 & R1;
+	[p0] = R0;
+	SSYNC;
+
+	/* Initialize stack pointer */
+	SP.L = LO(INITIAL_STACK);
+	SP.H = HI(INITIAL_STACK);
+	FP = SP;
+	USP = SP;
+
+	/* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
+	call _bf53x_relocate_l1_mem;
+#if CONFIG_BFIN_KERNEL_CLOCK
+	call _start_dma_code;
+#endif
+	/* Code for initializing Async memory banks */
+
+	p2.h = hi(EBIU_AMBCTL1);
+	p2.l = lo(EBIU_AMBCTL1);
+	r0.h = hi(AMBCTL1VAL);
+	r0.l = lo(AMBCTL1VAL);
+	[p2] = r0;
+	ssync;
+
+	p2.h = hi(EBIU_AMBCTL0);
+	p2.l = lo(EBIU_AMBCTL0);
+	r0.h = hi(AMBCTL0VAL);
+	r0.l = lo(AMBCTL0VAL);
+	[p2] = r0;
+	ssync;
+
+	p2.h = hi(EBIU_AMGCTL);
+	p2.l = lo(EBIU_AMGCTL);
+	r0 = AMGCTLVAL;
+	w[p2] = r0;
+	ssync;
+
+	/* This section keeps the processor in supervisor mode
+	 * during kernel boot.  Switches to user mode at end of boot.
+	 * See page 3-9 of Hardware Reference manual for documentation.
+	 */
+
+	/* EVT15 = _real_start */
+
+	p0.l = lo(EVT15);
+	p0.h = hi(EVT15);
+	p1.l = _real_start;
+	p1.h = _real_start;
+	[p0] = p1;
+	csync;
+
+	p0.l = lo(IMASK);
+	p0.h = hi(IMASK);
+	p1.l = IMASK_IVG15;
+	p1.h = 0x0;
+	[p0] = p1;
+	csync;
+
+	raise 15;
+	p0.l = .LWAIT_HERE;
+	p0.h = .LWAIT_HERE;
+	reti = p0;
+#if defined (ANOMALY_05000281)
+	nop;
+	nop;
+	nop;
+#endif
+	rti;
+
+.LWAIT_HERE:
+	jump .LWAIT_HERE;
+
+ENTRY(_real_start)
+	[ -- sp ] = reti;
+	p0.l = lo(WDOG_CTL);
+	p0.h = hi(WDOG_CTL);
+	r0 = 0xAD6(z);
+	w[p0] = r0;	/* watchdog off for now */
+	ssync;
+
+	/* Code update for BSS size == 0
+	 * Zero out the bss region.
+	 */
+
+	p1.l = ___bss_start;
+	p1.h = ___bss_start;
+	p2.l = ___bss_stop;
+	p2.h = ___bss_stop;
+	r0 = 0;
+	p2 -= p1;
+	lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2;
+.L_clear_bss:
+	B[p1++] = r0;
+
+	/* In case there is a NULL pointer reference
+	 * Zero out region before stext
+	 */
+
+	p1.l = 0x0;
+	p1.h = 0x0;
+	r0.l = __stext;
+	r0.h = __stext;
+	r0 = r0 >> 1;
+	p2 = r0;
+	r0 = 0;
+	lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2;
+.L_clear_zero:
+	W[p1++] = r0;
+
+	/* pass the uboot arguments to the global value command line */
+	R0 = R7;
+	call _cmdline_init;
+
+	p1.l = __rambase;
+	p1.h = __rambase;
+	r0.l = __sdata;
+	r0.h = __sdata;
+	[p1] = r0;
+
+	p1.l = __ramstart;
+	p1.h = __ramstart;
+	p3.l = ___bss_stop;
+	p3.h = ___bss_stop;
+
+	r1 = p3;
+	[p1] = r1;
+
+
+	/*
+	 *  load the current thread pointer and stack
+	 */
+	r1.l = _init_thread_union;
+	r1.h = _init_thread_union;
+
+	r2.l = 0x2000;
+	r2.h = 0x0000;
+	r1 = r1 + r2;
+	sp = r1;
+	usp = sp;
+	fp = sp;
+	call _start_kernel;
+.L_exit:
+	jump.s	.L_exit;
+
+.section .l1.text
+#if CONFIG_BFIN_KERNEL_CLOCK
+ENTRY(_start_dma_code)
+
+	/* Enable PHY CLK buffer output */
+	p0.h = hi(VR_CTL);
+	p0.l = lo(VR_CTL);
+	r0.l = w[p0];
+	bitset(r0, 14);
+	w[p0] = r0.l;
+	ssync;
+
+	p0.h = hi(SIC_IWR);
+	p0.l = lo(SIC_IWR);
+	r0.l = 0x1;
+	r0.h = 0x0;
+	[p0] = r0;
+	SSYNC;
+
+	/*
+	 *  Set PLL_CTL
+	 *   - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
+	 *   - [8]     = BYPASS    : BYPASS the PLL, run CLKIN into CCLK/SCLK
+	 *   - [7]     = output delay (add 200ps of delay to mem signals)
+	 *   - [6]     = input delay (add 200ps of input delay to mem signals)
+	 *   - [5]     = PDWN      : 1=All Clocks off
+	 *   - [3]     = STOPCK    : 1=Core Clock off
+	 *   - [1]     = PLL_OFF   : 1=Disable Power to PLL
+	 *   - [0]     = DF        : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
+	 *   all other bits set to zero
+	 */
+
+	p0.h = hi(PLL_LOCKCNT);
+	p0.l = lo(PLL_LOCKCNT);
+	r0 = 0x300(Z);
+	w[p0] = r0.l;
+	ssync;
+
+	P2.H = hi(EBIU_SDGCTL);
+	P2.L = lo(EBIU_SDGCTL);
+	R0 = [P2];
+	BITSET (R0, 24);
+	[P2] = R0;
+	SSYNC;
+
+	r0 = CONFIG_VCO_MULT & 63;       /* Load the VCO multiplier         */
+	r0 = r0 << 9;                    /* Shift it over,                  */
+	r1 = CLKIN_HALF;                 /* Do we need to divide CLKIN by 2?*/
+	r0 = r1 | r0;
+	r1 = PLL_BYPASS;                 /* Bypass the PLL?                 */
+	r1 = r1 << 8;                    /* Shift it over                   */
+	r0 = r1 | r0;                    /* add them all together           */
+
+	p0.h = hi(PLL_CTL);
+	p0.l = lo(PLL_CTL);              /* Load the address                */
+	cli r2;                          /* Disable interrupts              */
+	ssync;
+	w[p0] = r0.l;                    /* Set the value                   */
+	idle;                            /* Wait for the PLL to stablize    */
+	sti r2;                          /* Enable interrupts               */
+
+.Lcheck_again:
+	p0.h = hi(PLL_STAT);
+	p0.l = lo(PLL_STAT);
+	R0 = W[P0](Z);
+	CC = BITTST(R0,5);
+	if ! CC jump .Lcheck_again;
+
+	/* Configure SCLK & CCLK Dividers */
+	r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
+	p0.h = hi(PLL_DIV);
+	p0.l = lo(PLL_DIV);
+	w[p0] = r0.l;
+	ssync;
+
+	p0.l = lo(EBIU_SDRRC);
+	p0.h = hi(EBIU_SDRRC);
+	r0 = mem_SDRRC;
+	w[p0] = r0.l;
+	ssync;
+
+	p0.l = (EBIU_SDBCTL & 0xFFFF);
+	p0.h = (EBIU_SDBCTL >> 16);     /* SDRAM Memory Bank Control Register */
+	r0 = mem_SDBCTL;
+	w[p0] = r0.l;
+	ssync;
+
+	P2.H = hi(EBIU_SDGCTL);
+	P2.L = lo(EBIU_SDGCTL);
+	R0 = [P2];
+	BITCLR (R0, 24);
+	p0.h = hi(EBIU_SDSTAT);
+	p0.l = lo(EBIU_SDSTAT);
+	r2.l = w[p0];
+	cc = bittst(r2,3);
+	if !cc jump .Lskip;
+	NOP;
+	BITSET (R0, 23);
+.Lskip:
+	[P2] = R0;
+	SSYNC;
+
+	R0.L = lo(mem_SDGCTL);
+	R0.H = hi(mem_SDGCTL);
+	R1 = [p2];
+	R1 = R1 | R0;
+	[P2] = R1;
+	SSYNC;
+
+	p0.h = hi(SIC_IWR);
+	p0.l = lo(SIC_IWR);
+	r0.l = lo(IWR_ENABLE_ALL);
+	r0.h = hi(IWR_ENABLE_ALL);
+	[p0] = r0;
+	SSYNC;
+
+	RTS;
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+ENTRY(_bfin_reset)
+	/* No more interrupts to be handled*/
+	CLI R6;
+	SSYNC;
+
+#if defined(CONFIG_MTD_M25P80)
+/*
+ * The following code fix the SPI flash reboot issue,
+ * /CS signal of the chip which is using PF10 return to GPIO mode
+ */
+	p0.h = hi(PORTF_FER);
+	p0.l = lo(PORTF_FER);
+	r0.l = 0x0000;
+	w[p0] = r0.l;
+	SSYNC;
+
+/* /CS return to high */
+	p0.h = hi(PORTFIO);
+	p0.l = lo(PORTFIO);
+	r0.l = 0xFFFF;
+	w[p0] = r0.l;
+	SSYNC;
+
+/* Delay some time, This is necessary */
+	r1.h = 0;
+	r1.l = 0x400;
+	p1   = r1;
+	lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1;
+_delay_lab1:
+	r0.h = 0;
+	r0.l = 0x8000;
+	p0   = r0;
+	lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0;
+_delay_lab0:
+	nop;
+_delay_lab0_end:
+	nop;
+_delay_lab1_end:
+	nop;
+#endif
+
+	/* Clear the bits 13-15 in SWRST if they werent cleared */
+	p0.h = hi(SWRST);
+	p0.l = lo(SWRST);
+	csync;
+	r0.l = w[p0];
+
+	/* Clear the IMASK register */
+	p0.h = hi(IMASK);
+	p0.l = lo(IMASK);
+	r0 = 0x0;
+	[p0] = r0;
+
+	/* Clear the ILAT register */
+	p0.h = hi(ILAT);
+	p0.l = lo(ILAT);
+	r0 = [p0];
+	[p0] = r0;
+	SSYNC;
+
+	/* Disable the WDOG TIMER */
+	p0.h = hi(WDOG_CTL);
+	p0.l = lo(WDOG_CTL);
+	r0.l = 0xAD6;
+	w[p0] = r0.l;
+	SSYNC;
+
+	/* Clear the sticky bit incase it is already set */
+	p0.h = hi(WDOG_CTL);
+	p0.l = lo(WDOG_CTL);
+	r0.l = 0x8AD6;
+	w[p0] = r0.l;
+	SSYNC;
+
+	/* Program the count value */
+	R0.l = 0x100;
+	R0.h = 0x0;
+	P0.h = hi(WDOG_CNT);
+	P0.l = lo(WDOG_CNT);
+	[P0] = R0;
+	SSYNC;
+
+	/* Program WDOG_STAT if necessary */
+	P0.h = hi(WDOG_CTL);
+	P0.l = lo(WDOG_CTL);
+	R0 = W[P0](Z);
+	CC = BITTST(R0,1);
+	if !CC JUMP .LWRITESTAT;
+	CC = BITTST(R0,2);
+	if !CC JUMP .LWRITESTAT;
+	JUMP .LSKIP_WRITE;
+
+.LWRITESTAT:
+	/* When watch dog timer is enabled,
+	 * a write to STAT will load the contents of CNT to STAT
+	 */
+	R0 = 0x0000(z);
+	P0.h = hi(WDOG_STAT);
+	P0.l = lo(WDOG_STAT)
+	[P0] = R0;
+	SSYNC;
+
+.LSKIP_WRITE:
+	/* Enable the reset event */
+	P0.h = hi(WDOG_CTL);
+	P0.l = lo(WDOG_CTL);
+	R0 = W[P0](Z);
+	BITCLR(R0,1);
+	BITCLR(R0,2);
+	W[P0] = R0.L;
+	SSYNC;
+	NOP;
+
+	/* Enable the wdog counter */
+	R0 = W[P0](Z);
+	BITCLR(R0,4);
+	W[P0] = R0.L;
+	SSYNC;
+
+	IDLE;
+
+	RTS;
+
+.data
+
+/*
+ * Set up the usable of RAM stuff. Size of RAM is determined then
+ * an initial stack set up at the end.
+ */
+
+.align 4
+__rambase:
+.long   0
+__ramstart:
+.long   0
+__ramend:
+.long   0
diff --git a/arch/blackfin/mach-bf548/ints-priority.c b/arch/blackfin/mach-bf548/ints-priority.c
new file mode 100644
index 0000000..cb0ebac
--- /dev/null
+++ b/arch/blackfin/mach-bf548/ints-priority.c
@@ -0,0 +1,137 @@
+/*
+ * File:         arch/blackfin/mach-bf537/ints-priority.c
+ * Based on:     arch/blackfin/mach-bf533/ints-priority.c
+ * Author:       Michael Hennerich
+ *
+ * Created:
+ * Description:  Set up the interupt priorities
+ *
+ * Modified:
+ *               Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <asm/blackfin.h>
+
+void program_IAR(void)
+{
+	/* Program the IAR0 Register with the configured priority */
+	bfin_write_SIC_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) |
+			    ((CONFIG_IRQ_DMAC0_ERR - 7) << IRQ_DMAC0_ERR_POS) |
+			    ((CONFIG_IRQ_EPPI0_ERR - 7) << IRQ_EPPI0_ERR_POS) |
+			    ((CONFIG_IRQ_SPORT0_ERR - 7) << IRQ_SPORT0_ERR_POS) |
+			    ((CONFIG_IRQ_SPORT1_ERR - 7) << IRQ_SPORT1_ERR_POS) |
+			    ((CONFIG_IRQ_SPI0_ERR - 7) << IRQ_SPI0_ERR_POS) |
+			    ((CONFIG_IRQ_UART0_ERR - 7) << IRQ_UART0_ERR_POS) |
+			    ((CONFIG_IRQ_RTC - 7) << IRQ_RTC_POS));
+
+	bfin_write_SIC_IAR1(((CONFIG_IRQ_EPPI0 - 7) << IRQ_EPPI0_POS) |
+			    ((CONFIG_IRQ_SPORT0_RX - 7) << IRQ_SPORT0_RX_POS) |
+			    ((CONFIG_IRQ_SPORT0_TX - 7) << IRQ_SPORT0_TX_POS) |
+			    ((CONFIG_IRQ_SPORT1_RX - 7) << IRQ_SPORT1_RX_POS) |
+			    ((CONFIG_IRQ_SPORT1_TX - 7) << IRQ_SPORT1_TX_POS) |
+			    ((CONFIG_IRQ_SPI0 - 7) << IRQ_SPI0_POS) |
+			    ((CONFIG_IRQ_UART0_RX - 7) << IRQ_UART0_RX_POS) |
+			    ((CONFIG_IRQ_UART0_TX - 7) << IRQ_UART0_TX_POS));
+
+	bfin_write_SIC_IAR2(((CONFIG_IRQ_TIMER8 - 7) << IRQ_TIMER8_POS) |
+			    ((CONFIG_IRQ_TIMER9 - 7) << IRQ_TIMER9_POS) |
+			    ((CONFIG_IRQ_PINT0 - 7) << IRQ_PINT0_POS) |
+			    ((CONFIG_IRQ_PINT1 - 7) << IRQ_PINT1_POS) |
+			    ((CONFIG_IRQ_MDMAS0 - 7) << IRQ_MDMAS0_POS) |
+			    ((CONFIG_IRQ_MDMAS1 - 7) << IRQ_MDMAS1_POS) |
+			    ((CONFIG_IRQ_WATCHDOG - 7) << IRQ_WATCHDOG_POS));
+
+	bfin_write_SIC_IAR3(((CONFIG_IRQ_DMAC1_ERR - 7) << IRQ_DMAC1_ERR_POS) |
+			    ((CONFIG_IRQ_SPORT2_ERR - 7) << IRQ_SPORT2_ERR_POS) |
+			    ((CONFIG_IRQ_SPORT3_ERR - 7) << IRQ_SPORT3_ERR_POS) |
+			    ((CONFIG_IRQ_MXVR_DATA - 7) << IRQ_MXVR_DATA_POS) |
+			    ((CONFIG_IRQ_SPI1_ERR - 7) << IRQ_SPI1_ERR_POS) |
+			    ((CONFIG_IRQ_SPI2_ERR - 7) << IRQ_SPI2_ERR_POS) |
+			    ((CONFIG_IRQ_UART1_ERR - 7) << IRQ_UART1_ERR_POS) |
+			    ((CONFIG_IRQ_UART2_ERR - 7) << IRQ_UART2_ERR_POS));
+
+	bfin_write_SIC_IAR4(((CONFIG_IRQ_CAN0_ERR - 7) << IRQ_CAN0_ERR_POS) |
+			    ((CONFIG_IRQ_SPORT2_RX - 7) << IRQ_SPORT2_RX_POS) |
+			    ((CONFIG_IRQ_SPORT2_TX - 7) << IRQ_SPORT2_TX_POS) |
+			    ((CONFIG_IRQ_SPORT3_RX - 7) << IRQ_SPORT3_RX_POS) |
+			    ((CONFIG_IRQ_SPORT3_TX - 7) << IRQ_SPORT3_TX_POS) |
+			    ((CONFIG_IRQ_EPPI1 - 7) << IRQ_EPPI1_POS) |
+			    ((CONFIG_IRQ_EPPI2 - 7) << IRQ_EPPI2_POS) |
+			    ((CONFIG_IRQ_SPI1 - 7) << IRQ_SPI1_POS));
+
+	bfin_write_SIC_IAR5(((CONFIG_IRQ_SPI2 - 7) << IRQ_SPI2_POS) |
+			    ((CONFIG_IRQ_UART1_RX - 7) << IRQ_UART1_RX_POS) |
+			    ((CONFIG_IRQ_UART1_TX - 7) << IRQ_UART1_TX_POS) |
+			    ((CONFIG_IRQ_ATAPI_RX - 7) << IRQ_ATAPI_RX_POS) |
+			    ((CONFIG_IRQ_ATAPI_TX - 7) << IRQ_ATAPI_TX_POS) |
+			    ((CONFIG_IRQ_TWI0 - 7) << IRQ_TWI0_POS) |
+			    ((CONFIG_IRQ_TWI1 - 7) << IRQ_TWI1_POS) |
+			    ((CONFIG_IRQ_CAN0_RX - 7) << IRQ_CAN0_RX_POS));
+
+	bfin_write_SIC_IAR6(((CONFIG_IRQ_CAN0_TX - 7) << IRQ_CAN0_TX_POS) |
+			    ((CONFIG_IRQ_MDMAS2 - 7) << IRQ_MDMAS2_POS) |
+			    ((CONFIG_IRQ_MDMAS3 - 7) << IRQ_MDMAS3_POS) |
+			    ((CONFIG_IRQ_MXVR_ERR - 7) << IRQ_MXVR_ERR_POS) |
+			    ((CONFIG_IRQ_MXVR_MSG - 7) << IRQ_MXVR_MSG_POS) |
+			    ((CONFIG_IRQ_MXVR_PKT - 7) << IRQ_MXVR_PKT_POS) |
+			    ((CONFIG_IRQ_EPPI1_ERR - 7) << IRQ_EPPI1_ERR_POS) |
+			    ((CONFIG_IRQ_EPPI2_ERR - 7) << IRQ_EPPI2_ERR_POS));
+
+	bfin_write_SIC_IAR7(((CONFIG_IRQ_UART3_ERR - 7) << IRQ_UART3_ERR_POS) |
+			    ((CONFIG_IRQ_HOST_ERR - 7) << IRQ_HOST_ERR_POS) |
+			    ((CONFIG_IRQ_PIXC_ERR - 7) << IRQ_PIXC_ERR_POS) |
+			    ((CONFIG_IRQ_NFC_ERR - 7) << IRQ_NFC_ERR_POS) |
+			    ((CONFIG_IRQ_ATAPI_ERR - 7) << IRQ_ATAPI_ERR_POS) |
+			    ((CONFIG_IRQ_CAN1_ERR - 7) << IRQ_CAN1_ERR_POS) |
+			    ((CONFIG_IRQ_HS_DMA_ERR - 7) << IRQ_HS_DMA_ERR_POS));
+
+	bfin_write_SIC_IAR8(((CONFIG_IRQ_PIXC_IN0 - 7) << IRQ_PIXC_IN1_POS) |
+			    ((CONFIG_IRQ_PIXC_IN1 - 7) << IRQ_PIXC_IN1_POS) |
+			    ((CONFIG_IRQ_PIXC_OUT - 7) << IRQ_PIXC_OUT_POS) |
+			    ((CONFIG_IRQ_SDH - 7) << IRQ_SDH_POS) |
+			    ((CONFIG_IRQ_CNT - 7) << IRQ_CNT_POS) |
+			    ((CONFIG_IRQ_KEY - 7) << IRQ_KEY_POS) |
+			    ((CONFIG_IRQ_CAN1_RX - 7) << IRQ_CAN1_RX_POS) |
+			    ((CONFIG_IRQ_CAN1_TX - 7) << IRQ_CAN1_TX_POS));
+
+	bfin_write_SIC_IAR9(((CONFIG_IRQ_SDH_MASK0 - 7) << IRQ_SDH_MASK0_POS) |
+			    ((CONFIG_IRQ_SDH_MASK1 - 7) << IRQ_SDH_MASK1_POS) |
+			    ((CONFIG_IRQ_USB_INT0 - 7) << IRQ_USB_INT0_POS) |
+			    ((CONFIG_IRQ_USB_INT1 - 7) << IRQ_USB_INT1_POS) |
+			    ((CONFIG_IRQ_USB_INT2 - 7) << IRQ_USB_INT2_POS) |
+			    ((CONFIG_IRQ_USB_DMA - 7) << IRQ_USB_DMA_POS) |
+			    ((CONFIG_IRQ_OTPSEC - 7) << IRQ_OTPSEC_POS));
+
+	bfin_write_SIC_IAR10(((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) |
+			     ((CONFIG_IRQ_TIMER1 - 7) << IRQ_TIMER1_POS));
+
+	bfin_write_SIC_IAR11(((CONFIG_IRQ_TIMER2 - 7) << IRQ_TIMER2_POS) |
+			     ((CONFIG_IRQ_TIMER3 - 7) << IRQ_TIMER3_POS) |
+			     ((CONFIG_IRQ_TIMER4 - 7) << IRQ_TIMER4_POS) |
+			     ((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) |
+			     ((CONFIG_IRQ_TIMER6 - 7) << IRQ_TIMER6_POS) |
+			     ((CONFIG_IRQ_TIMER7 - 7) << IRQ_TIMER7_POS) |
+			     ((CONFIG_IRQ_PINT2 - 7) << IRQ_PINT2_POS) |
+			     ((CONFIG_IRQ_PINT3 - 7) << IRQ_PINT3_POS));
+
+	SSYNC();
+}
diff --git a/arch/blackfin/mach-bf561/Makefile b/arch/blackfin/mach-bf561/Makefile
index 57f475a..f39235a 100644
--- a/arch/blackfin/mach-bf561/Makefile
+++ b/arch/blackfin/mach-bf561/Makefile
@@ -4,6 +4,6 @@
 
 extra-y := head.o
 
-obj-y := ints-priority.o
+obj-y := ints-priority.o dma.o
 
 obj-$(CONFIG_BF561_COREB) += coreb.o
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
index 3dc5c04..5b2b544 100644
--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -34,7 +34,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -52,11 +52,11 @@
 		.size = 0x00020000,
 		.offset = 0,
 		.mask_flags = MTD_CAP_ROM
-	},{
+	}, {
 		.name = "kernel",
 		.size = 0xe0000,
 		.offset = 0x20000
-	},{
+	}, {
 		.name = "file system",
 		.size = 0x700000,
 		.offset = 0x00100000,
@@ -186,7 +186,7 @@
 		.start = 0x28000300,
 		.end = 0x28000300 + 16,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF0,
 		.end = IRQ_PF0,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -206,11 +206,11 @@
 		.start = 0x24008000,
 		.end = 0x24008000,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = 0x24008004,
 		.end = 0x24008004,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PF47,
 		.end = IRQ_PF47,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -241,25 +241,25 @@
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
 static struct resource bfin_uart_resources[] = {
-        {
-                .start = 0xFFC00400,
-                .end = 0xFFC004FF,
-                .flags = IORESOURCE_MEM,
-        },
+	{
+		.start = 0xFFC00400,
+		.end = 0xFFC004FF,
+		.flags = IORESOURCE_MEM,
+	},
 };
 
 static struct platform_device bfin_uart_device = {
-        .name = "bfin-uart",
-        .id = 1,
-        .num_resources = ARRAY_SIZE(bfin_uart_resources),
-        .resource = bfin_uart_resources,
+	.name = "bfin-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_uart_resources),
+	.resource = bfin_uart_resources,
 };
 #endif
 
 static struct platform_device *cm_bf561_devices[] __initdata = {
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-        &bfin_uart_device,
+	&bfin_uart_device,
 #endif
 
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 9720b5c..724191d 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -30,10 +30,9 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
-#include <asm/irq.h>
-#include <asm/bfin5xx_spi.h>
-#include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/bfin5xx_spi.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -45,13 +44,13 @@
 
 #if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
 static struct resource bfin_isp1761_resources[] = {
-	[0] = {
+	{
 		.name	= "isp1761-regs",
 		.start  = ISP1761_BASE + 0x00000000,
 		.end    = ISP1761_BASE + 0x000fffff,
 		.flags  = IORESOURCE_MEM,
 	},
-	[1] = {
+	{
 		.start  = ISP1761_IRQ,
 		.end    = ISP1761_IRQ,
 		.flags  = IORESOURCE_IRQ,
@@ -71,7 +70,7 @@
 
 int __init bfin_isp1761_init(void)
 {
-	unsigned int num_devices=ARRAY_SIZE(bfin_isp1761_devices);
+	unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices);
 
 	printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
 	set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING);
@@ -98,7 +97,7 @@
 		.start = 0x2C010300,
 		.end = 0x2C010300 + 16,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 
 		.start = IRQ_PF9,
 		.end = IRQ_PF9,
@@ -116,18 +115,18 @@
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
 static struct resource bfin_uart_resources[] = {
-        {
-                .start = 0xFFC00400,
-                .end = 0xFFC004FF,
-                .flags = IORESOURCE_MEM,
-        },
+	{
+		.start = 0xFFC00400,
+		.end = 0xFFC004FF,
+		.flags = IORESOURCE_MEM,
+	},
 };
 
 static struct platform_device bfin_uart_device = {
-        .name = "bfin-uart",
-        .id = 1,
-        .num_resources = ARRAY_SIZE(bfin_uart_resources),
-        .resource = bfin_uart_resources,
+	.name = "bfin-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_uart_resources),
+	.resource = bfin_uart_resources,
 };
 #endif
 
@@ -176,7 +175,7 @@
 	&spi_bfin_master_device,
 #endif
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-        &bfin_uart_device,
+	&bfin_uart_device,
 #endif
 };
 
diff --git a/arch/blackfin/mach-bf561/boards/generic_board.c b/arch/blackfin/mach-bf561/boards/generic_board.c
index 585ecdd..4dfea5d 100644
--- a/arch/blackfin/mach-bf561/boards/generic_board.c
+++ b/arch/blackfin/mach-bf561/boards/generic_board.c
@@ -30,7 +30,7 @@
 
 #include <linux/device.h>
 #include <linux/platform_device.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 
 char *bfin_board_name = "UNKNOWN BOARD";
 
@@ -43,11 +43,11 @@
 		.start = 0x2C010300,
 		.end = 0x2C010300 + 16,
 		.flags = IORESOURCE_MEM,
-	},{
+	}, {
 		.start = IRQ_PROG_INTB,
 		.end = IRQ_PROG_INTB,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},{
+	}, {
 		/*
 		 *  denotes the flag pin and is used directly if
 		 *  CONFIG_IRQCHIP_DEMUX_GPIO is defined.
diff --git a/arch/blackfin/mach-bf561/boards/tepla.c b/arch/blackfin/mach-bf561/boards/tepla.c
index db308c7..c442eb2 100644
--- a/arch/blackfin/mach-bf561/boards/tepla.c
+++ b/arch/blackfin/mach-bf561/boards/tepla.c
@@ -14,7 +14,7 @@
 
 #include <linux/device.h>
 #include <linux/platform_device.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
 
 char *bfin_board_name = "Tepla-BF561";
 
@@ -26,11 +26,11 @@
 		.start	= 0x2C000300,
 		.end	= 0x2C000320,
 		.flags	= IORESOURCE_MEM,
-	},{
+	}, {
 		.start	= IRQ_PROG_INTB,
 		.end	= IRQ_PROG_INTB,
 		.flags	= IORESOURCE_IRQ|IORESOURCE_IRQ_HIGHLEVEL,
-	},{
+	}, {
 		/*
 		 *  denotes the flag pin and is used directly if
 		 *  CONFIG_IRQCHIP_DEMUX_GPIO is defined.
diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c
index b28582f..5d1d21b 100644
--- a/arch/blackfin/mach-bf561/coreb.c
+++ b/arch/blackfin/mach-bf561/coreb.c
@@ -32,8 +32,8 @@
 #include <linux/device.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
+#include <linux/uaccess.h>
 #include <asm/dma.h>
-#include <asm/uaccess.h>
 
 #define MODULE_VER		"v0.1"
 
@@ -202,7 +202,7 @@
 	spin_unlock_irq(&coreb_lock);
 	return 0;
 
-      out_busy:
+ out_busy:
 	spin_unlock_irq(&coreb_lock);
 	return -EBUSY;
 }
@@ -365,19 +365,19 @@
 	printk(KERN_INFO "BF561 Core B driver %s initialized.\n", MODULE_VER);
 	return 0;
 
-      release_dma_src:
+ release_dma_src:
 	free_dma(CH_MEM_STREAM2_SRC);
-      release_dma_dest:
+ release_dma_dest:
 	free_dma(CH_MEM_STREAM2_DEST);
-      release_data_a_sram:
+ release_data_a_sram:
 	release_mem_region(0xff400000, 0x8000);
-      release_data_b_sram:
+ release_data_b_sram:
 	release_mem_region(0xff500000, 0x8000);
-      release_instruction_b_sram:
+ release_instruction_b_sram:
 	release_mem_region(0xff610000, 0x4000);
-      release_instruction_a_sram:
+ release_instruction_a_sram:
 	release_mem_region(0xff600000, 0x4000);
-      exit:
+ exit:
 	return -ENOMEM;
 }
 
diff --git a/arch/blackfin/mach-bf561/dma.c b/arch/blackfin/mach-bf561/dma.c
new file mode 100644
index 0000000..89c65bb
--- /dev/null
+++ b/arch/blackfin/mach-bf561/dma.c
@@ -0,0 +1,131 @@
+/*
+ * File:         arch/blackfin/mach-bf561/dma.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <asm/blackfin.h>
+#include <asm/dma.h>
+
+struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+	(struct dma_register *) DMA1_0_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_1_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_2_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_3_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_4_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_5_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_6_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_7_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_8_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_9_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_10_NEXT_DESC_PTR,
+	(struct dma_register *) DMA1_11_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_0_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_1_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_2_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_3_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_4_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_5_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_6_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_7_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_8_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_9_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_10_NEXT_DESC_PTR,
+	(struct dma_register *) DMA2_11_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA1_D0_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA1_S0_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA1_D1_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA1_S1_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA2_D0_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA2_S0_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA2_D1_NEXT_DESC_PTR,
+	(struct dma_register *) MDMA2_S1_NEXT_DESC_PTR,
+	(struct dma_register *) IMDMA_D0_NEXT_DESC_PTR,
+	(struct dma_register *) IMDMA_S0_NEXT_DESC_PTR,
+	(struct dma_register *) IMDMA_D1_NEXT_DESC_PTR,
+	(struct dma_register *) IMDMA_S1_NEXT_DESC_PTR,
+};
+
+int channel2irq(unsigned int channel)
+{
+	int ret_irq = -1;
+
+	switch (channel) {
+	case CH_PPI0:
+		ret_irq = IRQ_PPI0;
+		break;
+	case CH_PPI1:
+		ret_irq = IRQ_PPI1;
+		break;
+	case CH_SPORT0_RX:
+		ret_irq = IRQ_SPORT0_RX;
+		break;
+	case CH_SPORT0_TX:
+		ret_irq = IRQ_SPORT0_TX;
+		break;
+	case CH_SPORT1_RX:
+		ret_irq = IRQ_SPORT1_RX;
+		break;
+	case CH_SPORT1_TX:
+		ret_irq = IRQ_SPORT1_TX;
+		break;
+	case CH_SPI:
+		ret_irq = IRQ_SPI;
+		break;
+	case CH_UART_RX:
+		ret_irq = IRQ_UART_RX;
+		break;
+	case CH_UART_TX:
+		ret_irq = IRQ_UART_TX;
+		break;
+
+	case CH_MEM_STREAM0_SRC:
+	case CH_MEM_STREAM0_DEST:
+		ret_irq = IRQ_MEM_DMA0;
+		break;
+	case CH_MEM_STREAM1_SRC:
+	case CH_MEM_STREAM1_DEST:
+		ret_irq = IRQ_MEM_DMA1;
+		break;
+	case CH_MEM_STREAM2_SRC:
+	case CH_MEM_STREAM2_DEST:
+		ret_irq = IRQ_MEM_DMA2;
+		break;
+	case CH_MEM_STREAM3_SRC:
+	case CH_MEM_STREAM3_DEST:
+		ret_irq = IRQ_MEM_DMA3;
+		break;
+
+	case CH_IMEM_STREAM0_SRC:
+	case CH_IMEM_STREAM0_DEST:
+		ret_irq = IRQ_IMEM_DMA0;
+		break;
+	case CH_IMEM_STREAM1_SRC:
+	case CH_IMEM_STREAM1_DEST:
+		ret_irq = IRQ_IMEM_DMA1;
+		break;
+	}
+	return ret_irq;
+}
diff --git a/arch/blackfin/mach-bf561/head.S b/arch/blackfin/mach-bf561/head.S
index 31cbc75..2f08bcb 100644
--- a/arch/blackfin/mach-bf561/head.S
+++ b/arch/blackfin/mach-bf561/head.S
@@ -30,6 +30,8 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/blackfin.h>
+#include <asm/trace.h>
+
 #if CONFIG_BFIN_KERNEL_CLOCK
 #include <asm/mach/mem_init.h>
 #endif
@@ -93,6 +95,10 @@
 	M2 = r0;
 	M3 = r0;
 
+	trace_buffer_start(p0,r0);
+	P0 = R1;
+	R0 = R1;
+
 	/* Turn off the icache */
 	p0.l = (IMEM_CONTROL & 0xFFFF);
 	p0.h = (IMEM_CONTROL >> 16);
diff --git a/arch/blackfin/mach-bf561/ints-priority.c b/arch/blackfin/mach-bf561/ints-priority.c
index 86e3b0e..09b541b 100644
--- a/arch/blackfin/mach-bf561/ints-priority.c
+++ b/arch/blackfin/mach-bf561/ints-priority.c
@@ -28,8 +28,8 @@
  */
 
 #include <linux/module.h>
+#include <linux/irq.h>
 #include <asm/blackfin.h>
-#include <asm/irq.h>
 
 void program_IAR(void)
 {
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile
index d3a4907..0279ede 100644
--- a/arch/blackfin/mach-common/Makefile
+++ b/arch/blackfin/mach-common/Makefile
@@ -4,9 +4,9 @@
 
 obj-y := \
 	cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \
-	interrupt.o lock.o dpmc.o irqpanic.o
+	interrupt.o lock.o irqpanic.o
 
 obj-$(CONFIG_CPLB_INFO)          += cplbinfo.o
 obj-$(CONFIG_BFIN_SINGLE_CORE)   += ints-priority-sc.o
 obj-$(CONFIG_BFIN_DUAL_CORE)     += ints-priority-dc.o
-obj-$(CONFIG_PM)                 += pm.o
+obj-$(CONFIG_PM)                 += pm.o dpmc.o
diff --git a/arch/blackfin/mach-common/cacheinit.S b/arch/blackfin/mach-common/cacheinit.S
index 7924a90..9d47562 100644
--- a/arch/blackfin/mach-common/cacheinit.S
+++ b/arch/blackfin/mach-common/cacheinit.S
@@ -38,104 +38,37 @@
 
 .text
 
+#ifdef ANOMALY_05000125
 #if defined(CONFIG_BLKFIN_CACHE)
-ENTRY(_bfin_icache_init)
+ENTRY(_bfin_write_IMEM_CONTROL)
 
-	/* Initialize Instruction CPLBS */
-
-	I0.L = (ICPLB_ADDR0 & 0xFFFF);
-	I0.H = (ICPLB_ADDR0 >> 16);
-
-	I1.L = (ICPLB_DATA0 & 0xFFFF);
-	I1.H = (ICPLB_DATA0 >> 16);
-
-	I2.L = _icplb_table;
-	I2.H = _icplb_table;
-
-	r1 = -1;	/* end point comparison */
-	r3 = 15;	/* max counter */
-
-/* read entries from table */
-
-.Lread_iaddr:
-	R0 = [I2++];
-	CC = R0 == R1;
-	IF CC JUMP .Lidone;
-	[I0++] = R0;
-
-.Lread_idata:
-	R2 = [I2++];
-	[I1++] = R2;
-	R3 = R3 + R1;
-	CC = R3 == R1;
-	IF !CC JUMP .Lread_iaddr;
-
-.Lidone:
 	/* Enable Instruction Cache */
 	P0.l = (IMEM_CONTROL & 0xFFFF);
 	P0.h = (IMEM_CONTROL >> 16);
-	R1 = [P0];
-	R0 = (IMC | ENICPLB);
-	R0 = R0 | R1;
 
 	/* Anomaly 05000125 */
-	CLI R2;
+	CLI R1;
 	SSYNC;		/* SSYNC required before writing to IMEM_CONTROL. */
 	.align 8;
 	[P0] = R0;
 	SSYNC;
-	STI R2;
+	STI R1;
 	RTS;
 
-ENDPROC(_bfin_icache_init)
+ENDPROC(_bfin_write_IMEM_CONTROL)
 #endif
 
 #if defined(CONFIG_BLKFIN_DCACHE)
-ENTRY(_bfin_dcache_init)
-
-	/* Initialize Data CPLBS */
-
-	I0.L = (DCPLB_ADDR0 & 0xFFFF);
-	I0.H = (DCPLB_ADDR0 >> 16);
-
-	I1.L = (DCPLB_DATA0 & 0xFFFF);
-	I1.H = (DCPLB_DATA0 >> 16);
-
-	I2.L = _dcplb_table;
-	I2.H = _dcplb_table;
-
-	R1 = -1;	/* end point comparison */
-	R3 = 15;	/* max counter */
-
-	/* read entries from table */
-.Lread_daddr:
-	R0 = [I2++];
-	cc = R0 == R1;
-	IF CC JUMP .Lddone;
-	[I0++] = R0;
-
-.Lread_ddata:
-	R2 = [I2++];
-	[I1++] = R2;
-	R3 = R3 + R1;
-	CC = R3 == R1;
-	IF !CC JUMP .Lread_daddr;
-.Lddone:
-	P0.L = (DMEM_CONTROL & 0xFFFF);
-	P0.H = (DMEM_CONTROL >> 16);
-	R1 = [P0];
-
-	R0 = DMEM_CNTR;
-
-	R0 = R0 | R1;
-	/* Anomaly 05000125 */
-	CLI R2;
+ENTRY(_bfin_write_DMEM_CONTROL)
+	CLI R1;
 	SSYNC;		/* SSYNC required before writing to DMEM_CONTROL. */
 	.align 8;
 	[P0] = R0;
 	SSYNC;
-	STI R2;
+	STI R1;
 	RTS;
 
-ENDPROC(_bfin_dcache_init)
+ENDPROC(_bfin_write_DMEM_CONTROL)
+#endif
+
 #endif
diff --git a/arch/blackfin/mach-common/cplbinfo.c b/arch/blackfin/mach-common/cplbinfo.c
index caa9623..785ca98 100644
--- a/arch/blackfin/mach-common/cplbinfo.c
+++ b/arch/blackfin/mach-common/cplbinfo.c
@@ -31,11 +31,10 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/uaccess.h>
 
 #include <asm/current.h>
-#include <asm/uaccess.h>
 #include <asm/system.h>
-
 #include <asm/cplb.h>
 #include <asm/blackfin.h>
 
@@ -92,8 +91,7 @@
 	} else
 		buf += sprintf(buf, "Data CPLB entry:\n");
 
-	buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\
-\tiCount\toCount\n");
+	buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\n\tiCount\toCount\n");
 
 	while (*p_addr != 0xffffffff) {
 		entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data);
@@ -144,8 +142,7 @@
 
 	p = buf;
 
-	p += sprintf(p,
-		     "------------------ CPLB Information ------------------\n\n");
+	p += sprintf(p, "------------------ CPLB Information ------------------\n\n");
 
 	if (bfin_read_IMEM_CONTROL() & ENICPLB)
 		p = cplb_print_entry(p, CPLB_I);
@@ -191,9 +188,9 @@
 {
 	struct proc_dir_entry *entry;
 
-	if ((entry = create_proc_entry("cplbinfo", 0, NULL)) == NULL) {
+	entry = create_proc_entry("cplbinfo", 0, NULL);
+	if (!entry)
 		return -ENOMEM;
-	}
 
 	entry->read_proc = cplbinfo_read_proc;
 	entry->write_proc = cplbinfo_write_proc;
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 40045b1..d61bba98 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -49,34 +49,15 @@
 
 
 #include <linux/linkage.h>
+#include <linux/unistd.h>
 #include <asm/blackfin.h>
-#include <asm/unistd.h>
 #include <asm/errno.h>
 #include <asm/thread_info.h>  /* TIF_NEED_RESCHED */
 #include <asm/asm-offsets.h>
+#include <asm/trace.h>
 
 #include <asm/mach-common/context.S>
 
-#ifdef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE
-	/*
-	 * TODO: this should be proper save/restore, but for now
-	 * we'll just cheat and use 0x1/0x13
-	 */
-# define DEBUG_START_HWTRACE \
-	P5.l = LO(TBUFCTL); \
-	P5.h = HI(TBUFCTL); \
-	R7 = 0x13; \
-	[P5] = R7;
-# define DEBUG_STOP_HWTRACE \
-	P5.l = LO(TBUFCTL); \
-	P5.h = HI(TBUFCTL); \
-	R7 = 0x01; \
-	[P5] = R7;
-#else
-# define DEBUG_START_HWTRACE
-# define DEBUG_STOP_HWTRACE
-#endif
-
 #ifdef CONFIG_EXCPT_IRQ_SYSC_L1
 .section .l1.text
 #else
@@ -110,25 +91,14 @@
 	ASTAT = [sp++];
 	SAVE_ALL_SYS
 	call __cplb_hdr;
-	DEBUG_START_HWTRACE
+	DEBUG_START_HWTRACE(p5, r7)
 	RESTORE_ALL_SYS
 	SP = RETN;
 	rtx;
 ENDPROC(_ex_icplb)
 
-ENTRY(_ex_spinlock)
-	/* Transform this into a syscall - twiddle the syscall vector.  */
-	p5.l = lo(EVT15);
-	p5.h = hi(EVT15);
-	r7.l = _spinlock_bh;
-	r7.h = _spinlock_bh;
-	[p5] = r7;
-	csync;
-	/* Fall through.  */
-ENDPROC(_ex_spinlock)
-
 ENTRY(_ex_syscall)
-	DEBUG_START_HWTRACE
+	DEBUG_START_HWTRACE(p5, r7)
 	(R7:6,P5:4) = [sp++];
 	ASTAT = [sp++];
 	raise 15;		/* invoked by TRAP #0, for sys call */
@@ -136,26 +106,6 @@
 	rtx
 ENDPROC(_ex_syscall)
 
-ENTRY(_spinlock_bh)
-	SAVE_ALL_SYS
-	/* To end up here, vector 15 was changed - so we have to change it
-	 * back.
-	 */
-	p0.l = lo(EVT15);
-	p0.h = hi(EVT15);
-	p1.l = _evt_system_call;
-	p1.h = _evt_system_call;
-	[p0] = p1;
-	csync;
-	r0 = [sp + PT_R0];
-	sp += -12;
-	call _sys_bfin_spinlock;
-	sp += 12;
-	[SP + PT_R0] = R0;
-	RESTORE_ALL_SYS
-	rti;
-ENDPROC(_spinlock_bh)
-
 ENTRY(_ex_soft_bp)
 	r7 = retx;
 	r7 += -2;
@@ -186,7 +136,7 @@
 	if !cc jump _ex_trap_c;
 
 _return_from_exception:
-	DEBUG_START_HWTRACE
+	DEBUG_START_HWTRACE(p5, r7)
 #ifdef ANOMALY_05000257
 	R7=LC0;
 	LC0=R7;
@@ -208,7 +158,7 @@
 	 * need to make a CPLB exception look like a normal exception
 	 */
 
-	DEBUG_START_HWTRACE
+	DEBUG_START_HWTRACE(p5, r7)
 	RESTORE_ALL_SYS
 	[--sp] = ASTAT;
 	[--sp] = (R7:6, P5:4);
@@ -251,7 +201,7 @@
 	R6 = SEQSTAT;
 	[P5] = R6;
 
-	DEBUG_START_HWTRACE
+	DEBUG_START_HWTRACE(p5, r7)
 	(R7:6,P5:4) = [sp++];
 	ASTAT = [sp++];
 	SP = RETN;
@@ -335,7 +285,7 @@
 	/* Try to deal with syscalls quickly.  */
 	[--sp] = ASTAT;
 	[--sp] = (R7:6, P5:4);
-	DEBUG_STOP_HWTRACE
+	DEBUG_STOP_HWTRACE(p5, r7)
 	r7 = SEQSTAT;		/* reason code is in bit 5:0 */
 	r6.l = lo(SEQSTAT_EXCAUSE);
 	r6.h = hi(SEQSTAT_EXCAUSE);
@@ -741,6 +691,10 @@
 	r0 = [p0];
 	sti r0;
 
+	r0 = sp;
+	sp += -12;
+	call _finish_atomic_sections;
+	sp += 12;
 	jump.s .Lresume_userspace;
 
 _schedule_and_signal:
@@ -790,14 +744,14 @@
 ALIGN
 _extable:
 	/* entry for each EXCAUSE[5:0]
-	 * This table bmust be in sync with the table in ./kernel/traps.c
+	 * This table must be in sync with the table in ./kernel/traps.c
 	 * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined
 	 */
 	.long _ex_syscall;      /* 0x00 - User Defined - Linux Syscall */
 	.long _ex_soft_bp       /* 0x01 - User Defined - Software breakpoint */
 	.long _ex_trap_c        /* 0x02 - User Defined */
-	.long _ex_trap_c        /* 0x03 - User Defined  - Atomic test and set service */
-	.long _ex_spinlock      /* 0x04 - User Defined */
+	.long _ex_trap_c        /* 0x03 - User Defined - userspace stack overflow */
+	.long _ex_trap_c        /* 0x04 - User Defined */
 	.long _ex_trap_c        /* 0x05 - User Defined */
 	.long _ex_trap_c        /* 0x06 - User Defined */
 	.long _ex_trap_c        /* 0x07 - User Defined */
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
index 8be548e..203e207 100644
--- a/arch/blackfin/mach-common/interrupt.S
+++ b/arch/blackfin/mach-common/interrupt.S
@@ -34,6 +34,7 @@
 #include <linux/linkage.h>
 #include <asm/entry.h>
 #include <asm/asm-offsets.h>
+#include <asm/trace.h>
 
 #include <asm/mach-common/context.S>
 
@@ -170,10 +171,9 @@
 	r7.l = W[p5];
 1:
 #endif
-	p0.l = lo(TBUFCTL);
-	p0.h = hi(TBUFCTL);
-	r0 = 1;
-	[p0] = r0;
+
+	trace_buffer_stop(p0, r0);
+
 	r0 = IRQ_HWERR;
 	r1 = sp;
 
diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c
index 80943bb..6b9fd03 100644
--- a/arch/blackfin/mach-common/ints-priority-dc.c
+++ b/arch/blackfin/mach-common/ints-priority-dc.c
@@ -183,7 +183,7 @@
 {
 	u16 gpionr = irq - IRQ_PF0;
 
-	if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
+	if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
 		set_gpio_data(gpionr, 0);
 		SSYNC();
 	}
@@ -193,7 +193,7 @@
 {
 	u16 gpionr = irq - IRQ_PF0;
 
-	if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
+	if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
 		set_gpio_data(gpionr, 0);
 		SSYNC();
 	}
@@ -222,7 +222,7 @@
 	if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
 
 		ret = gpio_request(gpionr, NULL);
-		if(ret)
+		if (ret)
 			return ret;
 
 	}
@@ -262,7 +262,7 @@
 		if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
 
 			ret = gpio_request(gpionr, NULL);
-			if(ret)
+			if (ret)
 				return ret;
 
 		}
@@ -371,6 +371,9 @@
 	bfin_write_SICA_IMASK1(SIC_UNMASK_ALL);
 	SSYNC();
 
+	bfin_write_SICA_IWR0(IWR_ENABLE_ALL);
+	bfin_write_SICA_IWR1(IWR_ENABLE_ALL);
+
 	local_irq_disable();
 
 	init_exception_buff();
@@ -393,7 +396,7 @@
 	bfin_write_EVT15(evt_system_call);
 	CSYNC();
 
-	for (irq = 0; irq < SYS_IRQS; irq++) {
+	for (irq = 0; irq <= SYS_IRQS; irq++) {
 		if (irq <= IRQ_CORETMR)
 			set_irq_chip(irq, &bf561_core_irqchip);
 		else
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c
index 2cfc7d5..28a878c 100644
--- a/arch/blackfin/mach-common/ints-priority-sc.c
+++ b/arch/blackfin/mach-common/ints-priority-sc.c
@@ -13,7 +13,7 @@
  *               2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
  *               2003 Metrowerks/Motorola
  *               2003 Bas Vermeulen <bas@buyways.nl>
- *               Copyright 2004-2006 Analog Devices Inc.
+ *               Copyright 2004-2007 Analog Devices Inc.
  *
  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
  *
@@ -65,9 +65,9 @@
 
 struct ivgx {
 	/* irq number for request_irq, available in mach-bf533/irq.h */
-	int irqno;
+	unsigned int irqno;
 	/* corresponding bit in the SIC_ISR register */
-	int isrflag;
+	unsigned int isrflag;
 } ivg_table[NR_PERI_INTS];
 
 struct ivg_slice {
@@ -88,17 +88,16 @@
 	for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) {
 		int irqn;
 
-		ivg7_13[ivg].istop = ivg7_13[ivg].ifirst =
-		    &ivg_table[irq_pos];
+		ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = &ivg_table[irq_pos];
 
 		for (irqn = 0; irqn < NR_PERI_INTS; irqn++) {
 			int iar_shift = (irqn & 7) * 4;
 			if (ivg ==
 			    (0xf &
-			     bfin_read32((unsigned long *) SIC_IAR0 +
+			     bfin_read32((unsigned long *)SIC_IAR0 +
 					 (irqn >> 3)) >> iar_shift)) {
 				ivg_table[irq_pos].irqno = IVG7 + irqn;
-				ivg_table[irq_pos].isrflag = 1 << irqn;
+				ivg_table[irq_pos].isrflag = 1 << (irqn % 32);
 				ivg7_13[ivg].istop++;
 				irq_pos++;
 			}
@@ -141,15 +140,31 @@
 
 static void bfin_internal_mask_irq(unsigned int irq)
 {
+#ifndef CONFIG_BF54x
 	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
 			     ~(1 << (irq - (IRQ_CORETMR + 1))));
+#else
+	unsigned mask_bank, mask_bit;
+	mask_bank = (irq - (IRQ_CORETMR + 1)) / 32;
+	mask_bit = (irq - (IRQ_CORETMR + 1)) % 32;
+	bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
+			     ~(1 << mask_bit));
+#endif
 	SSYNC();
 }
 
 static void bfin_internal_unmask_irq(unsigned int irq)
 {
+#ifndef CONFIG_BF54x
 	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
 			     (1 << (irq - (IRQ_CORETMR + 1))));
+#else
+	unsigned mask_bank, mask_bit;
+	mask_bank = (irq - (IRQ_CORETMR + 1)) / 32;
+	mask_bit = (irq - (IRQ_CORETMR + 1)) % 32;
+	bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) |
+			     (1 << mask_bit));
+#endif
 	SSYNC();
 }
 
@@ -206,7 +221,7 @@
 };
 
 static void bfin_demux_error_irq(unsigned int int_err_irq,
-				  struct irq_desc *intb_desc)
+				 struct irq_desc *intb_desc)
 {
 	int irq = 0;
 
@@ -270,8 +285,8 @@
 			}
 
 			pr_debug("IRQ %d:"
-				" MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n",
-				irq);
+				 " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n",
+				 irq);
 		}
 	} else
 		printk(KERN_ERR
@@ -279,11 +294,10 @@
 		       " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
 		       __FUNCTION__, __FILE__, __LINE__);
 
-
 }
 #endif				/* BF537_GENERIC_ERROR_INT_DEMUX */
 
-#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+#if defined(CONFIG_IRQCHIP_DEMUX_GPIO) && !defined(CONFIG_BF54x)
 
 static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
 static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)];
@@ -361,8 +375,7 @@
 	}
 
 	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
-	            IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
-	{
+		    IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
 		if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
 			ret = gpio_request(gpionr, NULL);
 			if (ret)
@@ -407,6 +420,247 @@
 	return 0;
 }
 
+static struct irq_chip bfin_gpio_irqchip = {
+	.ack = bfin_gpio_ack_irq,
+	.mask = bfin_gpio_mask_irq,
+	.mask_ack = bfin_gpio_mask_ack_irq,
+	.unmask = bfin_gpio_unmask_irq,
+	.set_type = bfin_gpio_irq_type,
+	.startup = bfin_gpio_irq_startup,
+	.shutdown = bfin_gpio_irq_shutdown
+};
+
+static void bfin_demux_gpio_irq(unsigned int intb_irq,
+				struct irq_desc *intb_desc)
+{
+	u16 i;
+	struct irq_desc *desc;
+
+	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += 16) {
+		int irq = IRQ_PF0 + i;
+		int flag_d = get_gpiop_data(i);
+		int mask =
+		    flag_d & (gpio_enabled[gpio_bank(i)] & get_gpiop_maska(i));
+
+		while (mask) {
+			if (mask & 1) {
+				desc = irq_desc + irq;
+				desc->handle_irq(irq, desc);
+			}
+			irq++;
+			mask >>= 1;
+		}
+	}
+}
+
+#else				/* CONFIG_IRQCHIP_DEMUX_GPIO */
+
+#define NR_PINT_SYS_IRQS	4
+#define NR_PINT_BITS		32
+#define NR_PINTS		160
+#define IRQ_NOT_AVAIL		0xFF
+
+#define PINT_2_BANK(x)		((x) >> 5)
+#define PINT_2_BIT(x)		((x) & 0x1F)
+#define PINT_BIT(x)		(1 << (PINT_2_BIT(x)))
+
+static unsigned char irq2pint_lut[NR_PINTS];
+static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS];
+
+struct pin_int_t {
+	unsigned int mask_set;
+	unsigned int mask_clear;
+	unsigned int request;
+	unsigned int assign;
+	unsigned int edge_set;
+	unsigned int edge_clear;
+	unsigned int invert_set;
+	unsigned int invert_clear;
+	unsigned int pinstate;
+	unsigned int latch;
+};
+
+static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = {
+	(struct pin_int_t *)PINT0_MASK_SET,
+	(struct pin_int_t *)PINT1_MASK_SET,
+	(struct pin_int_t *)PINT2_MASK_SET,
+	(struct pin_int_t *)PINT3_MASK_SET,
+};
+
+unsigned short get_irq_base(u8 bank, u8 bmap)
+{
+
+	u16 irq_base;
+
+	if (bank < 2) {		/*PA-PB */
+		irq_base = IRQ_PA0 + bmap * 16;
+	} else {		/*PC-PJ */
+		irq_base = IRQ_PC0 + bmap * 16;
+	}
+
+	return irq_base;
+
+}
+
+	/* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */
+void init_pint_lut(void)
+{
+	u16 bank, bit, irq_base, bit_pos;
+	u32 pint_assign;
+	u8 bmap;
+
+	memset(irq2pint_lut, IRQ_NOT_AVAIL, sizeof(irq2pint_lut));
+
+	for (bank = 0; bank < NR_PINT_SYS_IRQS; bank++) {
+
+		pint_assign = pint[bank]->assign;
+
+		for (bit = 0; bit < NR_PINT_BITS; bit++) {
+
+			bmap = (pint_assign >> ((bit / 8) * 8)) & 0xFF;
+
+			irq_base = get_irq_base(bank, bmap);
+
+			irq_base += (bit % 8) + ((bit / 8) & 1 ? 8 : 0);
+			bit_pos = bit + bank * NR_PINT_BITS;
+
+			pint2irq_lut[bit_pos] = irq_base - SYS_IRQS;
+			irq2pint_lut[irq_base - SYS_IRQS] = bit_pos;
+
+		}
+
+	}
+
+}
+
+static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+static void bfin_gpio_ack_irq(unsigned int irq)
+{
+	u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+
+	pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val);
+	SSYNC();
+}
+
+static void bfin_gpio_mask_ack_irq(unsigned int irq)
+{
+	u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+	u32 pintbit = PINT_BIT(pint_val);
+	u8 bank = PINT_2_BANK(pint_val);
+
+	pint[bank]->request = pintbit;
+	pint[bank]->mask_clear = pintbit;
+	SSYNC();
+}
+
+static void bfin_gpio_mask_irq(unsigned int irq)
+{
+	u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+
+	pint[PINT_2_BANK(pint_val)]->mask_clear = PINT_BIT(pint_val);
+	SSYNC();
+}
+
+static void bfin_gpio_unmask_irq(unsigned int irq)
+{
+	u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+	u32 pintbit = PINT_BIT(pint_val);
+	u8 bank = PINT_2_BANK(pint_val);
+
+	pint[bank]->request = pintbit;
+	pint[bank]->mask_set = pintbit;
+	SSYNC();
+}
+
+static unsigned int bfin_gpio_irq_startup(unsigned int irq)
+{
+	unsigned int ret;
+	u16 gpionr = irq - IRQ_PA0;
+	u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+
+	if (pint_val == IRQ_NOT_AVAIL)
+		return -ENODEV;
+
+	if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+		ret = gpio_request(gpionr, NULL);
+		if (ret)
+			return ret;
+	}
+
+	gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+	bfin_gpio_unmask_irq(irq);
+
+	return ret;
+}
+
+static void bfin_gpio_irq_shutdown(unsigned int irq)
+{
+	bfin_gpio_mask_irq(irq);
+	gpio_free(irq - IRQ_PA0);
+	gpio_enabled[gpio_bank(irq - IRQ_PA0)] &= ~gpio_bit(irq - IRQ_PA0);
+}
+
+static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+{
+
+	unsigned int ret;
+	u16 gpionr = irq - IRQ_PA0;
+	u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+	u32 pintbit = PINT_BIT(pint_val);
+	u8 bank = PINT_2_BANK(pint_val);
+
+	if (pint_val == IRQ_NOT_AVAIL)
+		return -ENODEV;
+
+	if (type == IRQ_TYPE_PROBE) {
+		/* only probe unenabled GPIO interrupt lines */
+		if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))
+			return 0;
+		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+	}
+
+	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
+		    IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+		if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+			ret = gpio_request(gpionr, NULL);
+			if (ret)
+				return ret;
+		}
+
+		gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+	} else {
+		gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
+		return 0;
+	}
+
+	gpio_direction_input(gpionr);
+
+	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
+		pint[bank]->edge_set = pintbit;
+	} else {
+		pint[bank]->edge_clear = pintbit;
+	}
+
+	if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
+		pint[bank]->invert_set = pintbit;	/* low or falling edge denoted by one */
+	else
+		pint[bank]->invert_set = pintbit;	/* high or rising edge denoted by zero */
+
+	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+		pint[bank]->invert_set = pintbit;
+	else
+		pint[bank]->invert_set = pintbit;
+
+	SSYNC();
+
+	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+		set_irq_handler(irq, handle_edge_irq);
+	else
+		set_irq_handler(irq, handle_level_irq);
+
+	return 0;
+}
 
 static struct irq_chip bfin_gpio_irqchip = {
 	.ack = bfin_gpio_ack_irq,
@@ -419,28 +673,44 @@
 };
 
 static void bfin_demux_gpio_irq(unsigned int intb_irq,
-				 struct irq_desc *intb_desc)
+				struct irq_desc *intb_desc)
 {
-	u16 i;
+	u8 bank, pint_val;
+	u32 request, irq;
+	struct irq_desc *desc;
 
-	for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=16) {
-		int irq = IRQ_PF0 + i;
-		int flag_d = get_gpiop_data(i);
-		int mask =
-			flag_d & (gpio_enabled[gpio_bank(i)] &
-			      get_gpiop_maska(i));
-
-		while (mask) {
-			if (mask & 1) {
-				struct irq_desc *desc = irq_desc + irq;
-				desc->handle_irq(irq, desc);
-			}
-			irq++;
-			mask >>= 1;
-		}
+	switch (intb_irq) {
+	case IRQ_PINT0:
+		bank = 0;
+		break;
+	case IRQ_PINT2:
+		bank = 2;
+		break;
+	case IRQ_PINT3:
+		bank = 3;
+		break;
+	case IRQ_PINT1:
+		bank = 1;
+		break;
+	default:
+		return;
 	}
-}
 
+	pint_val = bank * NR_PINT_BITS;
+
+	request = pint[bank]->request;
+
+	while (request) {
+		if (request & 1) {
+			irq = pint2irq_lut[pint_val] + SYS_IRQS;
+			desc = irq_desc + irq;
+			desc->handle_irq(irq, desc);
+		}
+		pint_val++;
+		request >>= 1;
+	}
+
+}
 #endif				/* CONFIG_IRQCHIP_DEMUX_GPIO */
 
 /*
@@ -452,7 +722,18 @@
 	int irq;
 	unsigned long ilat = 0;
 	/*  Disable all the peripheral intrs  - page 4-29 HW Ref manual */
+#ifdef CONFIG_BF54x
+	bfin_write_SIC_IMASK0(SIC_UNMASK_ALL);
+	bfin_write_SIC_IMASK1(SIC_UNMASK_ALL);
+	bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
+	bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
+	bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
+	bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
+#else
 	bfin_write_SIC_IMASK(SIC_UNMASK_ALL);
+	bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+#endif
+
 	SSYNC();
 
 	local_irq_disable();
@@ -475,7 +756,18 @@
 	bfin_write_EVT15(evt_system_call);
 	CSYNC();
 
-	for (irq = 0; irq < SYS_IRQS; irq++) {
+#if defined(CONFIG_IRQCHIP_DEMUX_GPIO) && defined(CONFIG_BF54x)
+#ifdef CONFIG_PINTx_REASSIGN
+	pint[0]->assign = CONFIG_PINT0_ASSIGN;
+	pint[1]->assign = CONFIG_PINT1_ASSIGN;
+	pint[2]->assign = CONFIG_PINT2_ASSIGN;
+	pint[3]->assign = CONFIG_PINT3_ASSIGN;
+#endif
+	/* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */
+	init_pint_lut();
+#endif
+
+	for (irq = 0; irq <= SYS_IRQS; irq++) {
 		if (irq <= IRQ_CORETMR)
 			set_irq_chip(irq, &bfin_core_irqchip);
 		else
@@ -484,20 +776,42 @@
 		if (irq != IRQ_GENERIC_ERROR) {
 #endif
 
+			switch (irq) {
 #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
-			if ((irq != IRQ_PROG_INTA) /*PORT F & G MASK_A Interrupt*/
-# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
-				&& (irq != IRQ_MAC_RX) /*PORT H MASK_A Interrupt*/
-# endif
-			    ) {
-#endif
-				set_irq_handler(irq, handle_simple_irq);
-#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
-			} else {
+#ifndef CONFIG_BF54x
+			case IRQ_PROG_INTA:
 				set_irq_chained_handler(irq,
 							bfin_demux_gpio_irq);
-			}
+				break;
+#if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
+			case IRQ_MAC_RX:
+				set_irq_chained_handler(irq,
+							bfin_demux_gpio_irq);
+				break;
 #endif
+#else
+			case IRQ_PINT0:
+				set_irq_chained_handler(irq,
+							bfin_demux_gpio_irq);
+				break;
+			case IRQ_PINT1:
+				set_irq_chained_handler(irq,
+							bfin_demux_gpio_irq);
+				break;
+			case IRQ_PINT2:
+				set_irq_chained_handler(irq,
+							bfin_demux_gpio_irq);
+				break;
+			case IRQ_PINT3:
+				set_irq_chained_handler(irq,
+							bfin_demux_gpio_irq);
+				break;
+#endif				/*CONFIG_BF54x */
+#endif
+			default:
+				set_irq_handler(irq, handle_simple_irq);
+				break;
+			}
 
 #ifdef BF537_GENERIC_ERROR_INT_DEMUX
 		} else {
@@ -513,7 +827,11 @@
 #endif
 
 #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+#ifndef CONFIG_BF54x
 	for (irq = IRQ_PF0; irq < NR_IRQS; irq++) {
+#else
+	for (irq = IRQ_PA0; irq < NR_IRQS; irq++) {
+#endif
 		set_irq_chip(irq, &bfin_gpio_irqchip);
 		/* if configured as edge, then will be changed to do_edge_IRQ */
 		set_irq_handler(irq, handle_level_irq);
@@ -526,8 +844,7 @@
 	bfin_write_ILAT(ilat);
 	CSYNC();
 
-	printk(KERN_INFO
-	       "Configuring Blackfin Priority Driven Interrupts\n");
+	printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n");
 	/* IMASK=xxx is equivalent to STI xx or irq_flags=xx,
 	 * local_irq_enable()
 	 */
@@ -538,14 +855,13 @@
 	/* Enable interrupts IVG7-15 */
 	irq_flags = irq_flags | IMASK_IVG15 |
 	    IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
-	    IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 |
-	    IMASK_IVGHW;
+	    IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
 
 	return 0;
 }
 
 #ifdef CONFIG_DO_IRQ_L1
-void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text));
+void do_irq(int vec, struct pt_regs *fp) __attribute__((l1_text));
 #endif
 
 void do_irq(int vec, struct pt_regs *fp)
@@ -555,9 +871,25 @@
 	} else {
 		struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
 		struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
-		unsigned long sic_status;
+#ifdef CONFIG_BF54x
+		unsigned long sic_status[3];
 
 		SSYNC();
+		sic_status[0] = bfin_read_SIC_ISR(0) & bfin_read_SIC_IMASK(0);
+		sic_status[1] = bfin_read_SIC_ISR(1) & bfin_read_SIC_IMASK(1);
+		sic_status[2] = bfin_read_SIC_ISR(2) & bfin_read_SIC_IMASK(2);
+
+		for (;; ivg++) {
+			if (ivg >= ivg_stop) {
+				atomic_inc(&num_spurious);
+				return;
+			}
+			if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
+				break;
+		}
+#else
+		unsigned long sic_status;
+		SSYNC();
 		sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
 
 		for (;; ivg++) {
@@ -567,6 +899,7 @@
 			} else if (sic_status & ivg->isrflag)
 				break;
 		}
+#endif
 		vec = ivg->irqno;
 	}
 	asm_do_IRQ(vec, fp);
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index 150ef5d..1772d8d 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -35,10 +35,10 @@
 #include <linux/pm.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
+#include <linux/io.h>
+#include <linux/irq.h>
 
-#include <asm/io.h>
 #include <asm/dpmc.h>
-#include <asm/irq.h>
 #include <asm/gpio.h>
 
 #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H
diff --git a/arch/blackfin/mm/blackfin_sram.c b/arch/blackfin/mm/blackfin_sram.c
index 6810792..16c6169 100644
--- a/arch/blackfin/mm/blackfin_sram.c
+++ b/arch/blackfin/mm/blackfin_sram.c
@@ -87,7 +87,7 @@
 	       L1_SCRATCH_LENGTH >> 10);
 
 	memset(&l1_ssram, 0x00, sizeof(l1_ssram));
-	l1_ssram[0].paddr = (void*)L1_SCRATCH_START;
+	l1_ssram[0].paddr = (void *)L1_SCRATCH_START;
 	l1_ssram[0].size = L1_SCRATCH_LENGTH;
 	l1_ssram[0].flag = SRAM_SLT_FREE;
 
@@ -126,7 +126,7 @@
 {
 #if L1_CODE_LENGTH != 0
 	memset(&l1_inst_sram, 0x00, sizeof(l1_inst_sram));
-	l1_inst_sram[0].paddr = (void*)L1_CODE_START + (_etext_l1 - _stext_l1);
+	l1_inst_sram[0].paddr = (void *)L1_CODE_START + (_etext_l1 - _stext_l1);
 	l1_inst_sram[0].size = L1_CODE_LENGTH - (_etext_l1 - _stext_l1);
 	l1_inst_sram[0].flag = SRAM_SLT_FREE;
 
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c
index 570356d..68459cc 100644
--- a/arch/blackfin/mm/init.c
+++ b/arch/blackfin/mm/init.c
@@ -29,8 +29,8 @@
 
 #include <linux/swap.h>
 #include <linux/bootmem.h>
+#include <linux/uaccess.h>
 #include <asm/bfin-global.h>
-#include <asm/uaccess.h>
 #include <asm/l1layout.h>
 #include "blackfin_sram.h"
 
@@ -168,42 +168,31 @@
 	}
 }
 
+static __init void free_init_pages(const char *what, unsigned long begin, unsigned long end)
+{
+	unsigned long addr;
+	/* next to check that the page we free is not a partial page */
+	for (addr = begin; addr + PAGE_SIZE <= end; addr += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(addr));
+		init_page_count(virt_to_page(addr));
+		free_page(addr);
+		totalram_pages++;
+	}
+	printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
+}
+
 #ifdef CONFIG_BLK_DEV_INITRD
 void __init free_initrd_mem(unsigned long start, unsigned long end)
 {
-	int pages = 0;
-	for (; start < end; start += PAGE_SIZE) {
-		ClearPageReserved(virt_to_page(start));
-		init_page_count(virt_to_page(start));
-		free_page(start);
-		totalram_pages++;
-		pages++;
-	}
-	printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
+	free_init_pages("initrd memory", start, end);
 }
 #endif
 
 void __init free_initmem(void)
 {
 #ifdef CONFIG_RAMKERNEL
-	unsigned long addr;
-	/*
-	 *	the following code should be cool even if these sections
-	 *	are not page aligned.
-	 */
-	addr = PAGE_ALIGN((unsigned long)(__init_begin));
-	/* next to check that the page we free is not a partial page */
-	for (; addr + PAGE_SIZE < (unsigned long)(__init_end);
-	     addr += PAGE_SIZE) {
-		ClearPageReserved(virt_to_page(addr));
-		init_page_count(virt_to_page(addr));
-		free_page(addr);
-		totalram_pages++;
-	}
-	printk(KERN_NOTICE
-	       "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
-	       (addr - PAGE_ALIGN((long)__init_begin)) >> 10,
-	       (int)(PAGE_ALIGN((unsigned long)(__init_begin))),
-	       (int)(addr - PAGE_SIZE));
+	free_init_pages("unused kernel memory",
+			(unsigned long)(&__init_begin),
+			(unsigned long)(&__init_end));
 #endif
 }
diff --git a/arch/blackfin/oprofile/common.c b/arch/blackfin/oprofile/common.c
index 009a170..cb8b8d5 100644
--- a/arch/blackfin/oprofile/common.c
+++ b/arch/blackfin/oprofile/common.c
@@ -33,12 +33,12 @@
 #include <linux/smp.h>
 #include <linux/errno.h>
 #include <linux/mutex.h>
+#include <linux/ptrace.h>
+#include <linux/irq.h>
+#include <linux/io.h>
 
-#include <asm/ptrace.h>
 #include <asm/system.h>
 #include <asm/blackfin.h>
-#include <asm/irq.h>
-#include <asm/io.h>
 
 #include "op_blackfin.h"
 
diff --git a/arch/blackfin/oprofile/op_model_bf533.c b/arch/blackfin/oprofile/op_model_bf533.c
index b7a20a0..872dffe 100644
--- a/arch/blackfin/oprofile/op_model_bf533.c
+++ b/arch/blackfin/oprofile/op_model_bf533.c
@@ -32,12 +32,12 @@
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
-#include <asm/ptrace.h>
+#include <linux/ptrace.h>
+#include <linux/irq.h>
+#include <linux/io.h>
 #include <asm/system.h>
 #include <asm/processor.h>
 #include <asm/blackfin.h>
-#include <asm/irq.h>
-#include <asm/io.h>
 
 #include "op_blackfin.h"
 
diff --git a/arch/blackfin/oprofile/timer_int.c b/arch/blackfin/oprofile/timer_int.c
index 8fba16c..6c6f860 100644
--- a/arch/blackfin/oprofile/timer_int.c
+++ b/arch/blackfin/oprofile/timer_int.c
@@ -31,8 +31,7 @@
 #include <linux/smp.h>
 #include <linux/irq.h>
 #include <linux/oprofile.h>
-
-#include <asm/ptrace.h>
+#include <linux/ptrace.h>
 
 static void enable_sys_timer0()
 {
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu
index 5c95ceb..9cbe76c 100644
--- a/arch/i386/Kconfig.cpu
+++ b/arch/i386/Kconfig.cpu
@@ -344,8 +344,8 @@
 	depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
 	default y
 
-config X86_MINIMUM_CPU_MODEL
+config X86_MINIMUM_CPU_FAMILY
 	int
-	default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP
-	default "0"
+	default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK
+	default "3"
 
diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile
index bfbc320..08678a0a 100644
--- a/arch/i386/boot/Makefile
+++ b/arch/i386/boot/Makefile
@@ -25,27 +25,56 @@
 
 #RAMDISK := -DRAMDISK=512
 
-targets		:= vmlinux.bin bootsect bootsect.o \
-		   setup setup.o zImage bzImage
+targets		:= vmlinux.bin setup.bin setup.elf zImage bzImage
 subdir- 	:= compressed
 
+setup-y		+= a20.o apm.o cmdline.o copy.o cpu.o cpucheck.o edd.o
+setup-y		+= header.o main.o mca.o memory.o pm.o pmjump.o
+setup-y		+= printf.o string.o tty.o video.o version.o voyager.o
+
+# The link order of the video-*.o modules can matter.  In particular,
+# video-vga.o *must* be listed first, followed by video-vesa.o.
+# Hardware-specific drivers should follow in the order they should be
+# probed, and video-bios.o should typically be last.
+setup-y		+= video-vga.o
+setup-y		+= video-vesa.o
+setup-y		+= video-bios.o
+
 hostprogs-y	:= tools/build
 
 HOSTCFLAGS_build.o := $(LINUXINCLUDE)
 
 # ---------------------------------------------------------------------------
 
+# How to compile the 16-bit code.  Note we always compile for -march=i386,
+# that way we can complain to the user if the CPU is insufficient.
+cflags-i386   := 
+cflags-x86_64 := -m32
+CFLAGS		:= $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
+		   $(cflags-$(ARCH)) \
+		   -Wall -Wstrict-prototypes \
+		   -march=i386 -mregparm=3 \
+		   -include $(srctree)/$(src)/code16gcc.h \
+		   -fno-strict-aliasing -fomit-frame-pointer \
+		   $(call cc-option, -ffreestanding) \
+		   $(call cc-option, -fno-toplevel-reorder,\
+			$(call cc-option, -fno-unit-at-a-time)) \
+		   $(call cc-option, -fno-stack-protector) \
+		   $(call cc-option, -mpreferred-stack-boundary=2)
+AFLAGS		:= $(CFLAGS) -D__ASSEMBLY__
+
 $(obj)/zImage:  IMAGE_OFFSET := 0x1000
 $(obj)/zImage:  EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK)
 $(obj)/bzImage: IMAGE_OFFSET := 0x100000
+$(obj)/bzImage: EXTRA_CFLAGS := -D__BIG_KERNEL__
 $(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
 $(obj)/bzImage: BUILDFLAGS   := -b
 
 quiet_cmd_image = BUILD   $@
-cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
+cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \
 	    $(obj)/vmlinux.bin $(ROOT_DEV) > $@
 
-$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
+$(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \
 			      $(obj)/vmlinux.bin $(obj)/tools/build FORCE
 	$(call if_changed,image)
 	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
@@ -53,12 +82,17 @@
 $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
 	$(call if_changed,objcopy)
 
-LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
-LDFLAGS_setup	 := -Ttext 0x0 -s --oformat binary -e begtext
+SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
 
-$(obj)/setup $(obj)/bootsect: %: %.o FORCE
+LDFLAGS_setup.elf	:= -T
+$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
 	$(call if_changed,ld)
 
+OBJCOPYFLAGS_setup.bin	:= -O binary
+
+$(obj)/setup.bin: $(obj)/setup.elf FORCE
+	$(call if_changed,objcopy)
+
 $(obj)/compressed/vmlinux: FORCE
 	$(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
 
diff --git a/arch/i386/boot/a20.c b/arch/i386/boot/a20.c
new file mode 100644
index 0000000..31348d0
--- /dev/null
+++ b/arch/i386/boot/a20.c
@@ -0,0 +1,161 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/a20.c
+ *
+ * Enable A20 gate (return -1 on failure)
+ */
+
+#include "boot.h"
+
+#define MAX_8042_LOOPS	100000
+
+static int empty_8042(void)
+{
+	u8 status;
+	int loops = MAX_8042_LOOPS;
+
+	while (loops--) {
+		io_delay();
+
+		status = inb(0x64);
+		if (status & 1) {
+			/* Read and discard input data */
+			io_delay();
+			(void)inb(0x60);
+		} else if (!(status & 2)) {
+			/* Buffers empty, finished! */
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+/* Returns nonzero if the A20 line is enabled.  The memory address
+   used as a test is the int $0x80 vector, which should be safe. */
+
+#define A20_TEST_ADDR	(4*0x80)
+#define A20_TEST_SHORT  32
+#define A20_TEST_LONG	2097152	/* 2^21 */
+
+static int a20_test(int loops)
+{
+	int ok = 0;
+	int saved, ctr;
+
+	set_fs(0x0000);
+	set_gs(0xffff);
+
+	saved = ctr = rdfs32(A20_TEST_ADDR);
+
+	while (loops--) {
+		wrfs32(++ctr, A20_TEST_ADDR);
+		io_delay();	/* Serialize and make delay constant */
+		ok = rdgs32(A20_TEST_ADDR+0x10) ^ ctr;
+		if (ok)
+			break;
+	}
+
+	wrfs32(saved, A20_TEST_ADDR);
+	return ok;
+}
+
+/* Quick test to see if A20 is already enabled */
+static int a20_test_short(void)
+{
+	return a20_test(A20_TEST_SHORT);
+}
+
+/* Longer test that actually waits for A20 to come on line; this
+   is useful when dealing with the KBC or other slow external circuitry. */
+static int a20_test_long(void)
+{
+	return a20_test(A20_TEST_LONG);
+}
+
+static void enable_a20_bios(void)
+{
+	asm volatile("pushfl; int $0x15; popfl"
+		     : : "a" ((u16)0x2401));
+}
+
+static void enable_a20_kbc(void)
+{
+	empty_8042();
+
+	outb(0xd1, 0x64);	/* Command write */
+	empty_8042();
+
+	outb(0xdf, 0x60);	/* A20 on */
+	empty_8042();
+}
+
+static void enable_a20_fast(void)
+{
+	u8 port_a;
+
+	port_a = inb(0x92);	/* Configuration port A */
+	port_a |=  0x02;	/* Enable A20 */
+	port_a &= ~0x01;	/* Do not reset machine */
+	outb(port_a, 0x92);
+}
+
+/*
+ * Actual routine to enable A20; return 0 on ok, -1 on failure
+ */
+
+#define A20_ENABLE_LOOPS 255	/* Number of times to try */
+
+int enable_a20(void)
+{
+	int loops = A20_ENABLE_LOOPS;
+
+#if defined(CONFIG_X86_ELAN)
+	/* Elan croaks if we try to touch the KBC */
+	enable_a20_fast();
+	while (!a20_test_long())
+		;
+	return 0;
+#elif defined(CONFIG_X86_VOYAGER)
+	/* On Voyager, a20_test() is unsafe? */
+	enable_a20_kbc();
+	return 0;
+#else
+	while (loops--) {
+		/* First, check to see if A20 is already enabled
+		   (legacy free, etc.) */
+		if (a20_test_short())
+			return 0;
+
+		/* Next, try the BIOS (INT 0x15, AX=0x2401) */
+		enable_a20_bios();
+		if (a20_test_short())
+			return 0;
+
+		/* Try enabling A20 through the keyboard controller */
+		empty_8042();
+		if (a20_test_short())
+			return 0; /* BIOS worked, but with delayed reaction */
+
+		enable_a20_kbc();
+		if (a20_test_long())
+			return 0;
+
+		/* Finally, try enabling the "fast A20 gate" */
+		enable_a20_fast();
+		if (a20_test_long())
+			return 0;
+	}
+
+	return -1;
+#endif
+}
diff --git a/arch/i386/boot/apm.c b/arch/i386/boot/apm.c
new file mode 100644
index 0000000..a34087c
--- /dev/null
+++ b/arch/i386/boot/apm.c
@@ -0,0 +1,97 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   Original APM BIOS checking by Stephen Rothwell, May 1994
+ *   (sfr@canb.auug.org.au)
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/apm.c
+ *
+ * Get APM BIOS information
+ */
+
+#include "boot.h"
+
+#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
+
+int query_apm_bios(void)
+{
+	u16 ax, bx, cx, dx, di;
+	u32 ebx, esi;
+	u8 err;
+
+	/* APM BIOS installation check */
+	ax = 0x5300;
+	bx = cx = 0;
+	asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
+		     : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
+		     : : "esi", "edi");
+
+	if (err)
+		return -1;		/* No APM BIOS */
+
+	if (bx != 0x504d)	/* "PM" signature */
+		return -1;
+
+	if (cx & 0x02)		/* 32 bits supported? */
+		return -1;
+
+	/* Disconnect first, just in case */
+	ax = 0x5304;
+	asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
+		     : "+a" (ax)
+		     : : "ebx", "ecx", "edx", "esi", "edi");
+
+	/* Paranoia */
+	ebx = esi = 0;
+	cx = dx = di = 0;
+
+	/* 32-bit connect */
+	asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6"
+		     : "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx),
+		       "+S" (esi), "+D" (di), "=m" (err)
+		     : "a" (0x5303));
+
+	boot_params.apm_bios_info.cseg = ax;
+	boot_params.apm_bios_info.offset = ebx;
+	boot_params.apm_bios_info.cseg_16 = cx;
+	boot_params.apm_bios_info.dseg = dx;
+	boot_params.apm_bios_info.cseg_len = (u16)esi;
+	boot_params.apm_bios_info.cseg_16_len = esi >> 16;
+	boot_params.apm_bios_info.dseg_len = di;
+
+	if (err)
+		return -1;
+
+	/* Redo the installation check as the 32-bit connect;
+	   some BIOSes return different flags this way... */
+
+	ax = 0x5300;
+	bx = cx = 0;
+	asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
+		     : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
+		     : : "esi", "edi");
+
+	if (err || bx != 0x504d) {
+		/* Failure with 32-bit connect, try to disconect and ignore */
+		ax = 0x5304;
+		bx = 0;
+		asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
+			     : "+a" (ax), "+b" (bx)
+			     : : "ecx", "edx", "esi", "edi");
+		return -1;
+	}
+
+	boot_params.apm_bios_info.version = ax;
+	boot_params.apm_bios_info.flags = cx;
+	return 0;
+}
+
+#endif
diff --git a/arch/i386/boot/bitops.h b/arch/i386/boot/bitops.h
new file mode 100644
index 0000000..8dcc8dc
--- /dev/null
+++ b/arch/i386/boot/bitops.h
@@ -0,0 +1,45 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/bitops.h
+ *
+ * Very simple bitops for the boot code.
+ */
+
+#ifndef BOOT_BITOPS_H
+#define BOOT_BITOPS_H
+#define _LINUX_BITOPS_H		/* Inhibit inclusion of <linux/bitops.h> */
+
+static inline int constant_test_bit(int nr, const void *addr)
+{
+	const u32 *p = (const u32 *)addr;
+	return ((1UL << (nr & 31)) & (p[nr >> 5])) != 0;
+}
+static inline int variable_test_bit(int nr, const void *addr)
+{
+	u8 v;
+	const u32 *p = (const u32 *)addr;
+
+	asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
+	return v;
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ constant_test_bit((nr),(addr)) : \
+ variable_test_bit((nr),(addr)))
+
+static inline void set_bit(int nr, void *addr)
+{
+	asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
+}
+
+#endif /* BOOT_BITOPS_H */
diff --git a/arch/i386/boot/boot.h b/arch/i386/boot/boot.h
new file mode 100644
index 0000000..0329c4f
--- /dev/null
+++ b/arch/i386/boot/boot.h
@@ -0,0 +1,296 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/boot.h
+ *
+ * Header file for the real-mode kernel code
+ */
+
+#ifndef BOOT_BOOT_H
+#define BOOT_BOOT_H
+
+#ifndef __ASSEMBLY__
+
+#include <stdarg.h>
+#include <linux/types.h>
+#include <linux/edd.h>
+#include <asm/boot.h>
+#include <asm/bootparam.h>
+
+/* Useful macros */
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+
+extern struct setup_header hdr;
+extern struct boot_params boot_params;
+
+/* Basic port I/O */
+static inline void outb(u8 v, u16 port)
+{
+	asm volatile("outb %0,%1" : : "a" (v), "dN" (port));
+}
+static inline u8 inb(u16 port)
+{
+	u8 v;
+	asm volatile("inb %1,%0" : "=a" (v) : "dN" (port));
+	return v;
+}
+
+static inline void outw(u16 v, u16 port)
+{
+	asm volatile("outw %0,%1" : : "a" (v), "dN" (port));
+}
+static inline u16 inw(u16 port)
+{
+	u16 v;
+	asm volatile("inw %1,%0" : "=a" (v) : "dN" (port));
+	return v;
+}
+
+static inline void outl(u32 v, u16 port)
+{
+	asm volatile("outl %0,%1" : : "a" (v), "dn" (port));
+}
+static inline u32 inl(u32 port)
+{
+	u32 v;
+	asm volatile("inl %1,%0" : "=a" (v) : "dN" (port));
+	return v;
+}
+
+static inline void io_delay(void)
+{
+	const u16 DELAY_PORT = 0x80;
+	asm volatile("outb %%al,%0" : : "dN" (DELAY_PORT));
+}
+
+/* These functions are used to reference data in other segments. */
+
+static inline u16 ds(void)
+{
+	u16 seg;
+	asm("movw %%ds,%0" : "=rm" (seg));
+	return seg;
+}
+
+static inline void set_fs(u16 seg)
+{
+	asm volatile("movw %0,%%fs" : : "rm" (seg));
+}
+static inline u16 fs(void)
+{
+	u16 seg;
+	asm("movw %%fs,%0" : "=rm" (seg));
+	return seg;
+}
+
+static inline void set_gs(u16 seg)
+{
+	asm volatile("movw %0,%%gs" : : "rm" (seg));
+}
+static inline u16 gs(void)
+{
+	u16 seg;
+	asm("movw %%gs,%0" : "=rm" (seg));
+	return seg;
+}
+
+typedef unsigned int addr_t;
+
+static inline u8 rdfs8(addr_t addr)
+{
+	u8 v;
+	asm("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
+	return v;
+}
+static inline u16 rdfs16(addr_t addr)
+{
+	u16 v;
+	asm("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
+	return v;
+}
+static inline u32 rdfs32(addr_t addr)
+{
+	u32 v;
+	asm("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
+	return v;
+}
+
+static inline void wrfs8(u8 v, addr_t addr)
+{
+	asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "r" (v));
+}
+static inline void wrfs16(u16 v, addr_t addr)
+{
+	asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "r" (v));
+}
+static inline void wrfs32(u32 v, addr_t addr)
+{
+	asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "r" (v));
+}
+
+static inline u8 rdgs8(addr_t addr)
+{
+	u8 v;
+	asm("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
+	return v;
+}
+static inline u16 rdgs16(addr_t addr)
+{
+	u16 v;
+	asm("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
+	return v;
+}
+static inline u32 rdgs32(addr_t addr)
+{
+	u32 v;
+	asm("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
+	return v;
+}
+
+static inline void wrgs8(u8 v, addr_t addr)
+{
+	asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "r" (v));
+}
+static inline void wrgs16(u16 v, addr_t addr)
+{
+	asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "r" (v));
+}
+static inline void wrgs32(u32 v, addr_t addr)
+{
+	asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "r" (v));
+}
+
+/* Note: these only return true/false, not a signed return value! */
+static inline int memcmp(const void *s1, const void *s2, size_t len)
+{
+	u8 diff;
+	asm("repe; cmpsb; setnz %0"
+	    : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+	return diff;
+}
+
+static inline int memcmp_fs(const void *s1, addr_t s2, size_t len)
+{
+	u8 diff;
+	asm("fs; repe; cmpsb; setnz %0"
+	    : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+	return diff;
+}
+static inline int memcmp_gs(const void *s1, addr_t s2, size_t len)
+{
+	u8 diff;
+	asm("gs; repe; cmpsb; setnz %0"
+	    : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+	return diff;
+}
+
+static inline int isdigit(int ch)
+{
+	return (ch >= '0') && (ch <= '9');
+}
+
+/* Heap -- available for dynamic lists. */
+#define STACK_SIZE	512	/* Minimum number of bytes for stack */
+
+extern char _end[];
+extern char *HEAP;
+extern char *heap_end;
+#define RESET_HEAP() ((void *)( HEAP = _end ))
+static inline char *__get_heap(size_t s, size_t a, size_t n)
+{
+	char *tmp;
+
+	HEAP = (char *)(((size_t)HEAP+(a-1)) & ~(a-1));
+	tmp = HEAP;
+	HEAP += s*n;
+	return tmp;
+}
+#define GET_HEAP(type, n) \
+	((type *)__get_heap(sizeof(type),__alignof__(type),(n)))
+
+static inline int heap_free(void)
+{
+	return heap_end-HEAP;
+}
+
+/* copy.S */
+
+void copy_to_fs(addr_t dst, void *src, size_t len);
+void *copy_from_fs(void *dst, addr_t src, size_t len);
+void copy_to_gs(addr_t dst, void *src, size_t len);
+void *copy_from_gs(void *dst, addr_t src, size_t len);
+void *memcpy(void *dst, void *src, size_t len);
+void *memset(void *dst, int c, size_t len);
+
+#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
+#define memset(d,c,l) __builtin_memset(d,c,l)
+
+/* a20.c */
+int enable_a20(void);
+
+/* apm.c */
+int query_apm_bios(void);
+
+/* cmdline.c */
+int cmdline_find_option(const char *option, char *buffer, int bufsize);
+
+/* cpu.c, cpucheck.c */
+int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
+int validate_cpu(void);
+
+/* edd.c */
+void query_edd(void);
+
+/* header.S */
+void __attribute__((noreturn)) die(void);
+
+/* mca.c */
+int query_mca(void);
+
+/* memory.c */
+int detect_memory(void);
+
+/* pm.c */
+void __attribute__((noreturn)) go_to_protected_mode(void);
+
+/* pmjump.S */
+void __attribute__((noreturn))
+	protected_mode_jump(u32 entrypoint, u32 bootparams);
+
+/* printf.c */
+int sprintf(char *buf, const char *fmt, ...);
+int vsprintf(char *buf, const char *fmt, va_list args);
+int printf(const char *fmt, ...);
+
+/* string.c */
+int strcmp(const char *str1, const char *str2);
+size_t strnlen(const char *s, size_t maxlen);
+unsigned int atou(const char *s);
+
+/* tty.c */
+void puts(const char *);
+void putchar(int);
+int getchar(void);
+void kbd_flush(void);
+int getchar_timeout(void);
+
+/* video.c */
+void set_video(void);
+
+/* video-vesa.c */
+void vesa_store_edid(void);
+
+/* voyager.c */
+int query_voyager(void);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* BOOT_BOOT_H */
diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S
deleted file mode 100644
index 011b7a4..0000000
--- a/arch/i386/boot/bootsect.S
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *	bootsect.S		Copyright (C) 1991, 1992 Linus Torvalds
- *
- *	modified by Drew Eckhardt
- *	modified by Bruce Evans (bde)
- *	modified by Chris Noe (May 1999) (as86 -> gas)
- *	gutted by H. Peter Anvin (Jan 2003)
- *
- * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
- * addresses must be multiplied by 16 to obtain their respective linear
- * addresses. To avoid confusion, linear addresses are written using leading
- * hex while segment addresses are written as segment:offset.
- *
- */
-
-#include <asm/boot.h>
-
-SETUPSECTS	= 4			/* default nr of setup-sectors */
-BOOTSEG		= 0x07C0		/* original address of boot-sector */
-INITSEG		= DEF_INITSEG		/* we move boot here - out of the way */
-SETUPSEG	= DEF_SETUPSEG		/* setup starts here */
-SYSSEG		= DEF_SYSSEG		/* system loaded at 0x10000 (65536) */
-SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
-					/* to be loaded */
-ROOT_DEV	= 0 			/* ROOT_DEV is now written by "build" */
-SWAP_DEV	= 0			/* SWAP_DEV is now written by "build" */
-
-#ifndef SVGA_MODE
-#define SVGA_MODE ASK_VGA
-#endif
-
-#ifndef RAMDISK
-#define RAMDISK 0
-#endif
-
-#ifndef ROOT_RDONLY
-#define ROOT_RDONLY 1
-#endif
-
-.code16
-.text
-
-.global _start
-_start:
-
-	# Normalize the start address
-	jmpl	$BOOTSEG, $start2
-
-start2:
-	movw	%cs, %ax
-	movw	%ax, %ds
-	movw	%ax, %es
-	movw	%ax, %ss
-	movw	$0x7c00, %sp
-	sti
-	cld
-
-	movw	$bugger_off_msg, %si
-
-msg_loop:
-	lodsb
-	andb	%al, %al
-	jz	die
-	movb	$0xe, %ah
-	movw	$7, %bx
-	int	$0x10
-	jmp	msg_loop
-
-die:
-	# Allow the user to press a key, then reboot
-	xorw	%ax, %ax
-	int	$0x16
-	int	$0x19
-
-	# int 0x19 should never return.  In case it does anyway,
-	# invoke the BIOS reset code...
-	ljmp	$0xf000,$0xfff0
-
-
-bugger_off_msg:
-	.ascii	"Direct booting from floppy is no longer supported.\r\n"
-	.ascii	"Please use a boot loader program instead.\r\n"
-	.ascii	"\n"
-	.ascii	"Remove disk and press any key to reboot . . .\r\n"
-	.byte	0
-
-
-	# Kernel attributes; used by setup
-
-	.org 497
-setup_sects:	.byte SETUPSECTS
-root_flags:	.word ROOT_RDONLY
-syssize:	.word SYSSIZE
-swap_dev:	.word SWAP_DEV
-ram_size:	.word RAMDISK
-vid_mode:	.word SVGA_MODE
-root_dev:	.word ROOT_DEV
-boot_flag:	.word 0xAA55
diff --git a/arch/i386/boot/cmdline.c b/arch/i386/boot/cmdline.c
new file mode 100644
index 0000000..34bb778
--- /dev/null
+++ b/arch/i386/boot/cmdline.c
@@ -0,0 +1,97 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/cmdline.c
+ *
+ * Simple command-line parser for early boot.
+ */
+
+#include "boot.h"
+
+static inline int myisspace(u8 c)
+{
+	return c <= ' ';	/* Close enough approximation */
+}
+
+/*
+ * Find a non-boolean option, that is, "option=argument".  In accordance
+ * with standard Linux practice, if this option is repeated, this returns
+ * the last instance on the command line.
+ *
+ * Returns the length of the argument (regardless of if it was
+ * truncated to fit in the buffer), or -1 on not found.
+ */
+int cmdline_find_option(const char *option, char *buffer, int bufsize)
+{
+	u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
+	addr_t cptr;
+	char c;
+	int len = -1;
+	const char *opptr = NULL;
+	char *bufptr = buffer;
+	enum {
+		st_wordstart,	/* Start of word/after whitespace */
+		st_wordcmp,	/* Comparing this word */
+		st_wordskip,	/* Miscompare, skip */
+		st_bufcpy	/* Copying this to buffer */
+	} state = st_wordstart;
+
+	if (!cmdline_ptr || cmdline_ptr >= 0x100000)
+		return -1;	/* No command line, or inaccessible */
+
+	cptr = cmdline_ptr & 0xf;
+	set_fs(cmdline_ptr >> 4);
+
+	while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
+		switch (state) {
+		case st_wordstart:
+			if (myisspace(c))
+				break;
+
+			/* else */
+			state = st_wordcmp;
+			opptr = option;
+			/* fall through */
+
+		case st_wordcmp:
+			if (c == '=' && !*opptr) {
+				len = 0;
+				bufptr = buffer;
+				state = st_bufcpy;
+			} else if (myisspace(c)) {
+				state = st_wordstart;
+			} else if (c != *opptr++) {
+				state = st_wordskip;
+			}
+			break;
+
+		case st_wordskip:
+			if (myisspace(c))
+				state = st_wordstart;
+			break;
+
+		case st_bufcpy:
+			if (myisspace(c)) {
+				state = st_wordstart;
+			} else {
+				if (len < bufsize-1)
+					*bufptr++ = c;
+				len++;
+			}
+			break;
+		}
+	}
+
+	if (bufsize)
+		*bufptr = '\0';
+
+	return len;
+}
diff --git a/arch/i386/boot/code16gcc.h b/arch/i386/boot/code16gcc.h
new file mode 100644
index 0000000..3bd8480
--- /dev/null
+++ b/arch/i386/boot/code16gcc.h
@@ -0,0 +1,15 @@
+/*
+ * code16gcc.h
+ *
+ * This file is -include'd when compiling 16-bit C code.
+ * Note: this asm() needs to be emitted before gcc omits any code.
+ * Depending on gcc version, this requires -fno-unit-at-a-time or
+ * -fno-toplevel-reorder.
+ *
+ * Hopefully gcc will eventually have a real -m16 option so we can
+ * drop this hack long term.
+ */
+
+#ifndef __ASSEMBLY__
+asm(".code16gcc");
+#endif
diff --git a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile
index a661217..189fa1d 100644
--- a/arch/i386/boot/compressed/Makefile
+++ b/arch/i386/boot/compressed/Makefile
@@ -9,9 +9,14 @@
 EXTRA_AFLAGS	:= -traditional
 
 LDFLAGS_vmlinux := -T
-CFLAGS_misc.o += -fPIC
 hostprogs-y	:= relocs
 
+CFLAGS  := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
+	   -fno-strict-aliasing -fPIC \
+	   $(call cc-option,-ffreestanding) \
+	   $(call cc-option,-fno-stack-protector)
+LDFLAGS := -m elf_i386
+
 $(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
 	$(call if_changed,ld)
 	@:
diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S
index 3517a32..f35ea22 100644
--- a/arch/i386/boot/compressed/head.S
+++ b/arch/i386/boot/compressed/head.S
@@ -45,10 +45,10 @@
  * at and where we were actually loaded at.  This can only be done
  * with a short local call on x86.  Nothing  else will tell us what
  * address we are running at.  The reserved chunk of the real-mode
- * data at 0x34-0x3f are used as the stack for this calculation.
- * Only 4 bytes are needed.
+ * data at 0x1e4 (defined as a scratch field) are used as the stack
+ * for this calculation. Only 4 bytes are needed.
  */
-	leal 0x40(%esi), %esp
+	leal (0x1e4+4)(%esi), %esp
 	call 1f
 1:	popl %ebp
 	subl $1b, %ebp
diff --git a/arch/i386/boot/copy.S b/arch/i386/boot/copy.S
new file mode 100644
index 0000000..ef127e5
--- /dev/null
+++ b/arch/i386/boot/copy.S
@@ -0,0 +1,101 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/copy.S
+ *
+ * Memory copy routines
+ */
+
+	.code16gcc
+	.text
+
+	.globl	memcpy
+	.type	memcpy, @function
+memcpy:
+	pushw	%si
+	pushw	%di
+	movw	%ax, %di
+	movw	%dx, %si
+	pushw	%cx
+	shrw	$2, %cx
+	rep; movsl
+	popw	%cx
+	andw	$3, %cx
+	rep; movsb
+	popw	%di
+	popw	%si
+	ret
+	.size	memcpy, .-memcpy
+
+	.globl	memset
+	.type	memset, @function
+memset:
+	pushw	%di
+	movw	%ax, %di
+	movzbl	%dl, %eax
+	imull	$0x01010101,%eax
+	pushw	%cx
+	shrw	$2, %cx
+	rep; stosl
+	popw	%cx
+	andw	$3, %cx
+	rep; stosb
+	popw	%di
+	ret
+	.size	memset, .-memset
+
+	.globl	copy_from_fs
+	.type	copy_from_fs, @function
+copy_from_fs:
+	pushw	%ds
+	pushw	%fs
+	popw	%ds
+	call	memcpy
+	popw	%ds
+	ret
+	.size	copy_from_fs, .-copy_from_fs
+
+	.globl	copy_to_fs
+	.type	copy_to_fs, @function
+copy_to_fs:
+	pushw	%es
+	pushw	%fs
+	popw	%es
+	call	memcpy
+	popw	%es
+	ret
+	.size	copy_to_fs, .-copy_to_fs
+
+#if 0 /* Not currently used, but can be enabled as needed */
+
+	.globl	copy_from_gs
+	.type	copy_from_gs, @function
+copy_from_gs:
+	pushw	%ds
+	pushw	%gs
+	popw	%ds
+	call	memcpy
+	popw	%ds
+	ret
+	.size	copy_from_gs, .-copy_from_gs
+	.globl	copy_to_gs
+
+	.type	copy_to_gs, @function
+copy_to_gs:
+	pushw	%es
+	pushw	%gs
+	popw	%es
+	call	memcpy
+	popw	%es
+	ret
+	.size	copy_to_gs, .-copy_to_gs
+
+#endif
diff --git a/arch/i386/boot/cpu.c b/arch/i386/boot/cpu.c
new file mode 100644
index 0000000..2a5c32d
--- /dev/null
+++ b/arch/i386/boot/cpu.c
@@ -0,0 +1,69 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/cpu.c
+ *
+ * Check for obligatory CPU features and abort if the features are not
+ * present.
+ */
+
+#include "boot.h"
+#include "bitops.h"
+#include <asm/cpufeature.h>
+
+static char *cpu_name(int level)
+{
+	static char buf[6];
+
+	if (level == 64) {
+		return "x86-64";
+	} else {
+		sprintf(buf, "i%d86", level);
+		return buf;
+	}
+}
+
+int validate_cpu(void)
+{
+	u32 *err_flags;
+	int cpu_level, req_level;
+
+	check_cpu(&cpu_level, &req_level, &err_flags);
+
+	if (cpu_level < req_level) {
+		printf("This kernel requires an %s CPU, ",
+		       cpu_name(req_level));
+		printf("but only detected an %s CPU.\n",
+		       cpu_name(cpu_level));
+		return -1;
+	}
+
+	if (err_flags) {
+		int i, j;
+		puts("This kernel requires the following features "
+		     "not present on the CPU:\n");
+
+		for (i = 0; i < NCAPINTS; i++) {
+			u32 e = err_flags[i];
+
+			for (j = 0; j < 32; j++) {
+				if (e & 1)
+					printf("%d:%d ", i, j);
+
+				e >>= 1;
+			}
+		}
+		putchar('\n');
+		return -1;
+	} else {
+		return 0;
+	}
+}
diff --git a/arch/i386/boot/cpucheck.c b/arch/i386/boot/cpucheck.c
new file mode 100644
index 0000000..8b0f447
--- /dev/null
+++ b/arch/i386/boot/cpucheck.c
@@ -0,0 +1,267 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/cpucheck.c
+ *
+ * Check for obligatory CPU features and abort if the features are not
+ * present.  This code should be compilable as 16-, 32- or 64-bit
+ * code, so be very careful with types and inline assembly.
+ *
+ * This code should not contain any messages; that requires an
+ * additional wrapper.
+ *
+ * As written, this code is not safe for inclusion into the kernel
+ * proper (after FPU initialization, in particular).
+ */
+
+#ifdef _SETUP
+# include "boot.h"
+# include "bitops.h"
+#endif
+#include <linux/types.h>
+#include <asm/cpufeature.h>
+#include <asm/processor-flags.h>
+#include <asm/required-features.h>
+#include <asm/msr-index.h>
+
+struct cpu_features {
+	int level;		/* Family, or 64 for x86-64 */
+	int model;
+	u32 flags[NCAPINTS];
+};
+
+static struct cpu_features cpu;
+static u32 cpu_vendor[3];
+static u32 err_flags[NCAPINTS];
+
+#ifdef CONFIG_X86_64
+static const int req_level = 64;
+#elif defined(CONFIG_X86_MINIMUM_CPU_FAMILY)
+static const int req_level = CONFIG_X86_MINIMUM_CPU_FAMILY;
+#else
+static const int req_level = 3;
+#endif
+
+static const u32 req_flags[NCAPINTS] =
+{
+	REQUIRED_MASK0,
+	REQUIRED_MASK1,
+	REQUIRED_MASK2,
+	REQUIRED_MASK3,
+	REQUIRED_MASK4,
+	REQUIRED_MASK5,
+	REQUIRED_MASK6,
+	REQUIRED_MASK7,
+};
+
+#define A32(a,b,c,d) (((d) << 24)+((c) << 16)+((b) << 8)+(a))
+
+static int is_amd(void)
+{
+	return cpu_vendor[0] == A32('A','u','t','h') &&
+	       cpu_vendor[1] == A32('e','n','t','i') &&
+	       cpu_vendor[2] == A32('c','A','M','D');
+}
+
+static int is_centaur(void)
+{
+	return cpu_vendor[0] == A32('C','e','n','t') &&
+	       cpu_vendor[1] == A32('a','u','r','H') &&
+	       cpu_vendor[2] == A32('a','u','l','s');
+}
+
+static int is_transmeta(void)
+{
+	return cpu_vendor[0] == A32('G','e','n','u') &&
+	       cpu_vendor[1] == A32('i','n','e','T') &&
+	       cpu_vendor[2] == A32('M','x','8','6');
+}
+
+static int has_fpu(void)
+{
+	u16 fcw = -1, fsw = -1;
+	u32 cr0;
+
+	asm("movl %%cr0,%0" : "=r" (cr0));
+	if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
+		cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
+		asm volatile("movl %0,%%cr0" : : "r" (cr0));
+	}
+
+	asm("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw));
+
+	return fsw == 0 && (fcw & 0x103f) == 0x003f;
+}
+
+static int has_eflag(u32 mask)
+{
+	u32 f0, f1;
+
+	asm("pushfl ; "
+	    "pushfl ; "
+	    "popl %0 ; "
+	    "movl %0,%1 ; "
+	    "xorl %2,%1 ; "
+	    "pushl %1 ; "
+	    "popfl ; "
+	    "pushfl ; "
+	    "popl %1 ; "
+	    "popfl"
+	    : "=r" (f0), "=r" (f1)
+	    : "g" (mask));
+
+	return !!((f0^f1) & mask);
+}
+
+static void get_flags(void)
+{
+	u32 max_intel_level, max_amd_level;
+	u32 tfms;
+
+	if (has_fpu())
+		set_bit(X86_FEATURE_FPU, cpu.flags);
+
+	if (has_eflag(X86_EFLAGS_ID)) {
+		asm("cpuid"
+		    : "=a" (max_intel_level),
+		      "=b" (cpu_vendor[0]),
+		      "=d" (cpu_vendor[1]),
+		      "=c" (cpu_vendor[2])
+		    : "a" (0));
+
+		if (max_intel_level >= 0x00000001 &&
+		    max_intel_level <= 0x0000ffff) {
+			asm("cpuid"
+			    : "=a" (tfms),
+			      "=c" (cpu.flags[4]),
+			      "=d" (cpu.flags[0])
+			    : "a" (0x00000001)
+			    : "ebx");
+			cpu.level = (tfms >> 8) & 15;
+			cpu.model = (tfms >> 4) & 15;
+			if (cpu.level >= 6)
+				cpu.model += ((tfms >> 16) & 0xf) << 4;
+		}
+
+		asm("cpuid"
+		    : "=a" (max_amd_level)
+		    : "a" (0x80000000)
+		    : "ebx", "ecx", "edx");
+
+		if (max_amd_level >= 0x80000001 &&
+		    max_amd_level <= 0x8000ffff) {
+			u32 eax = 0x80000001;
+			asm("cpuid"
+			    : "+a" (eax),
+			      "=c" (cpu.flags[6]),
+			      "=d" (cpu.flags[1])
+			    : : "ebx");
+		}
+	}
+}
+
+/* Returns a bitmask of which words we have error bits in */
+static int check_flags(void)
+{
+	u32 err;
+	int i;
+
+	err = 0;
+	for (i = 0; i < NCAPINTS; i++) {
+		err_flags[i] = req_flags[i] & ~cpu.flags[i];
+		if (err_flags[i])
+			err |= 1 << i;
+	}
+
+	return err;
+}
+
+/*
+ * Returns -1 on error.
+ *
+ * *cpu_level is set to the current CPU level; *req_level to the required
+ * level.  x86-64 is considered level 64 for this purpose.
+ *
+ * *err_flags_ptr is set to the flags error array if there are flags missing.
+ */
+int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
+{
+	int err;
+
+	memset(&cpu.flags, 0, sizeof cpu.flags);
+	cpu.level = 3;
+
+	if (has_eflag(X86_EFLAGS_AC))
+		cpu.level = 4;
+
+	get_flags();
+	err = check_flags();
+
+	if (test_bit(X86_FEATURE_LM, cpu.flags))
+		cpu.level = 64;
+
+	if (err == 0x01 &&
+	    !(err_flags[0] &
+	      ~((1 << X86_FEATURE_XMM)|(1 << X86_FEATURE_XMM2))) &&
+	    is_amd()) {
+		/* If this is an AMD and we're only missing SSE+SSE2, try to
+		   turn them on */
+
+		u32 ecx = MSR_K7_HWCR;
+		u32 eax, edx;
+
+		asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
+		eax &= ~(1 << 15);
+		asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
+
+		get_flags();	/* Make sure it really did something */
+		err = check_flags();
+	} else if (err == 0x01 &&
+		   !(err_flags[0] & ~(1 << X86_FEATURE_CX8)) &&
+		   is_centaur() && cpu.model >= 6) {
+		/* If this is a VIA C3, we might have to enable CX8
+		   explicitly */
+
+		u32 ecx = MSR_VIA_FCR;
+		u32 eax, edx;
+
+		asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
+		eax |= (1<<1)|(1<<7);
+		asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
+
+		set_bit(X86_FEATURE_CX8, cpu.flags);
+		err = check_flags();
+	} else if (err == 0x01 && is_transmeta()) {
+		/* Transmeta might have masked feature bits in word 0 */
+
+		u32 ecx = 0x80860004;
+		u32 eax, edx;
+		u32 level = 1;
+
+		asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
+		asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
+		asm("cpuid"
+		    : "+a" (level), "=d" (cpu.flags[0])
+		    : : "ecx", "ebx");
+		asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
+
+		err = check_flags();
+	}
+
+	if (err_flags_ptr)
+		*err_flags_ptr = err ? err_flags : NULL;
+	if (cpu_level_ptr)
+		*cpu_level_ptr = cpu.level;
+	if (req_level_ptr)
+		*req_level_ptr = req_level;
+
+	return (cpu.level < req_level || err) ? -1 : 0;
+}
diff --git a/arch/i386/boot/edd.S b/arch/i386/boot/edd.S
deleted file mode 100644
index 3432136..0000000
--- a/arch/i386/boot/edd.S
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * BIOS Enhanced Disk Drive support
- * Copyright (C) 2002, 2003, 2004 Dell, Inc.
- * by Matt Domsch <Matt_Domsch@dell.com> October 2002
- * conformant to T13 Committee www.t13.org
- *   projects 1572D, 1484D, 1386D, 1226DT
- * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
- *	and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
- * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net>
- *      March 2004
- * Command line option parsing, Matt Domsch, November 2004
- */
-
-#include <linux/edd.h>
-#include <asm/setup.h>
-
-#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-
-# It is assumed that %ds == INITSEG here
-
-	movb	$0, (EDD_MBR_SIG_NR_BUF)
-	movb	$0, (EDDNR)
-
-# Check the command line for options:
-# edd=of  disables EDD completely  (edd=off)
-# edd=sk  skips the MBR test    (edd=skipmbr)
-# edd=on  re-enables EDD (edd=on)
-
-	pushl	%esi
-	movw	$edd_mbr_sig_start, %di	# Default to edd=on
-
-	movl	%cs:(cmd_line_ptr), %esi
-	andl	%esi, %esi
-	jz	old_cl			# Old boot protocol?
-
-# Convert to a real-mode pointer in fs:si
-	movl	%esi, %eax
-	shrl	$4, %eax
-	movw	%ax, %fs
-	andw	$0xf, %si
-	jmp	have_cl_pointer
-
-# Old-style boot protocol?
-old_cl:
-	push	%ds			# aka INITSEG
-	pop	%fs
-
-	cmpw	$0xa33f, (0x20)
-	jne	done_cl			# No command line at all?
-	movw	(0x22), %si		# Pointer relative to INITSEG
-
-# fs:si has the pointer to the command line now
-have_cl_pointer:
-
-# Loop through kernel command line one byte at a time.  Just in
-# case the loader is buggy and failed to null-terminate the command line
-# terminate if we get close enough to the end of the segment that we
-# cannot fit "edd=XX"...
-cl_atspace:
-	cmpw	$-5, %si		# Watch for segment wraparound
-	jae	done_cl
-	movl	%fs:(%si), %eax
-	andb	%al, %al		# End of line?
-	jz	done_cl
-	cmpl	$EDD_CL_EQUALS, %eax
-	jz	found_edd_equals
-	cmpb	$0x20, %al		# <= space consider whitespace
-	ja	cl_skipword
-	incw	%si
-	jmp	cl_atspace
-
-cl_skipword:
-	cmpw	$-5, %si		# Watch for segment wraparound
-	jae	done_cl
-	movb	%fs:(%si), %al		# End of string?
-	andb	%al, %al
-	jz	done_cl
-	cmpb	$0x20, %al
-	jbe	cl_atspace
-	incw	%si
-	jmp	cl_skipword
-
-found_edd_equals:
-# only looking at first two characters after equals
-# late overrides early on the command line, so keep going after finding something
-	movw	%fs:4(%si), %ax
-	cmpw	$EDD_CL_OFF, %ax	# edd=of
-	je	do_edd_off
-	cmpw	$EDD_CL_SKIP, %ax	# edd=sk
-	je	do_edd_skipmbr
-	cmpw	$EDD_CL_ON, %ax		# edd=on
-	je	do_edd_on
-	jmp	cl_skipword
-do_edd_skipmbr:
-	movw	$edd_start, %di
-	jmp	cl_skipword
-do_edd_off:
-	movw	$edd_done, %di
-	jmp	cl_skipword
-do_edd_on:
-	movw	$edd_mbr_sig_start, %di
-	jmp	cl_skipword
-
-done_cl:
-	popl	%esi
-	jmpw	*%di
-
-# Read the first sector of each BIOS disk device and store the 4-byte signature
-edd_mbr_sig_start:
-	movb	$0x80, %dl			# from device 80
-	movw	$EDD_MBR_SIG_BUF, %bx		# store buffer ptr in bx
-edd_mbr_sig_read:
-	movl	$0xFFFFFFFF, %eax
-	movl	%eax, (%bx)			# assume failure
-	pushw	%bx
-	movb	$READ_SECTORS, %ah
-	movb	$1, %al				# read 1 sector
-	movb	$0, %dh				# at head 0
-	movw	$1, %cx				# cylinder 0, sector 0
-	pushw	%es
-	pushw	%ds
-	popw	%es
-    	movw	$EDDBUF, %bx			# disk's data goes into EDDBUF
-	pushw	%dx             # work around buggy BIOSes
-	stc                     # work around buggy BIOSes
-	int	$0x13
-	sti                     # work around buggy BIOSes
-	popw	%dx
-	popw	%es
-	popw	%bx
-	jc	edd_mbr_sig_done		# on failure, we're done.
-	cmpb	$0, %ah		# some BIOSes do not set CF
-	jne	edd_mbr_sig_done		# on failure, we're done.
-	movl	(EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR
-	movl	%eax, (%bx)			# store success
-	incb	(EDD_MBR_SIG_NR_BUF)		# note that we stored something
-	incb	%dl				# increment to next device
-	addw	$4, %bx				# increment sig buffer ptr
-	cmpb	$EDD_MBR_SIG_MAX, (EDD_MBR_SIG_NR_BUF)	# Out of space?
-	jb	edd_mbr_sig_read		# keep looping
-edd_mbr_sig_done:
-
-# Do the BIOS Enhanced Disk Drive calls
-# This consists of two calls:
-#    int 13h ah=41h "Check Extensions Present"
-#    int 13h ah=48h "Get Device Parameters"
-#    int 13h ah=08h "Legacy Get Device Parameters"
-#
-# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use
-# in the boot_params at EDDBUF.  The first four bytes of which are
-# used to store the device number, interface support map and version
-# results from fn41.  The next four bytes are used to store the legacy
-# cylinders, heads, and sectors from fn08. The following 74 bytes are used to
-# store the results from fn48.  Starting from device 80h, fn41, then fn48
-# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE).
-# Then the pointer is incremented to store the data for the next call.
-# This repeats until either a device doesn't exist, or until EDDMAXNR
-# devices have been stored.
-# The one tricky part is that ds:si always points EDDEXTSIZE bytes into
-# the structure, and the fn41 and fn08 results are stored at offsets
-# from there.  This removes the need to increment the pointer for
-# every store, and leaves it ready for the fn48 call.
-# A second one-byte buffer, EDDNR, in the boot_params stores
-# the number of BIOS devices which exist, up to EDDMAXNR.
-# In setup.c, copy_edd() stores both boot_params buffers away
-# for later use, as they would get overwritten otherwise.
-# This code is sensitive to the size of the structs in edd.h
-edd_start:
-						# %ds points to the bootsector
-       						# result buffer for fn48
-	movw	$EDDBUF+EDDEXTSIZE, %si		# in ds:si, fn41 results
-						# kept just before that
-	movb	$0x80, %dl			# BIOS device 0x80
-
-edd_check_ext:
-	movb	$CHECKEXTENSIONSPRESENT, %ah    # Function 41
-	movw	$EDDMAGIC1, %bx			# magic
-	int	$0x13				# make the call
-	jc	edd_done			# no more BIOS devices
-
-	cmpw	$EDDMAGIC2, %bx			# is magic right?
-	jne	edd_next			# nope, next...
-
-	movb	%dl, %ds:-8(%si)		# store device number
-	movb	%ah, %ds:-7(%si)		# store version
-	movw	%cx, %ds:-6(%si)		# store extensions
-	incb	(EDDNR)				# note that we stored something
-
-edd_get_device_params:
-	movw	$EDDPARMSIZE, %ds:(%si)		# put size
-	movw	$0x0, %ds:2(%si)		# work around buggy BIOSes
-	movb	$GETDEVICEPARAMETERS, %ah	# Function 48
-	int	$0x13				# make the call
-						# Don't check for fail return
-						# it doesn't matter.
-edd_get_legacy_chs:
-	xorw    %ax, %ax
-	movw    %ax, %ds:-4(%si)
-	movw    %ax, %ds:-2(%si)
-        # Ralf Brown's Interrupt List says to set ES:DI to
-	# 0000h:0000h "to guard against BIOS bugs"
-	pushw   %es
-	movw    %ax, %es
-	movw    %ax, %di
-	pushw   %dx                             # legacy call clobbers %dl
-	movb    $LEGACYGETDEVICEPARAMETERS, %ah # Function 08
-	int     $0x13                           # make the call
-	jc      edd_legacy_done                 # failed
-	movb    %cl, %al                        # Low 6 bits are max
-	andb    $0x3F, %al                      #   sector number
-	movb	%al, %ds:-1(%si)                # Record max sect
-	movb    %dh, %ds:-2(%si)                # Record max head number
-	movb    %ch, %al                        # Low 8 bits of max cyl
-	shr     $6, %cl
-	movb    %cl, %ah                        # High 2 bits of max cyl
-	movw    %ax, %ds:-4(%si)
-
-edd_legacy_done:
-	popw    %dx
-	popw    %es
-	movw	%si, %ax			# increment si
-	addw	$EDDPARMSIZE+EDDEXTSIZE, %ax
-	movw	%ax, %si
-
-edd_next:
-	incb	%dl				# increment to next device
-	cmpb	$EDDMAXNR, (EDDNR) 		# Out of space?
-	jb	edd_check_ext			# keep looping
-
-edd_done:
-#endif
diff --git a/arch/i386/boot/edd.c b/arch/i386/boot/edd.c
new file mode 100644
index 0000000..25a2824
--- /dev/null
+++ b/arch/i386/boot/edd.c
@@ -0,0 +1,196 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/edd.c
+ *
+ * Get EDD BIOS disk information
+ */
+
+#include "boot.h"
+#include <linux/edd.h>
+
+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+
+struct edd_dapa {
+	u8	pkt_size;
+	u8	rsvd;
+	u16	sector_cnt;
+	u16	buf_off, buf_seg;
+	u64	lba;
+	u64	buf_lin_addr;
+};
+
+/*
+ * Read the MBR (first sector) from a specific device.
+ */
+static int read_mbr(u8 devno, void *buf)
+{
+	struct edd_dapa dapa;
+	u16 ax, bx, cx, dx, si;
+
+	memset(&dapa, 0, sizeof dapa);
+	dapa.pkt_size = sizeof(dapa);
+	dapa.sector_cnt = 1;
+	dapa.buf_off = (size_t)buf;
+	dapa.buf_seg = ds();
+	/* dapa.lba = 0; */
+
+	ax = 0x4200;		/* Extended Read */
+	si = (size_t)&dapa;
+	dx = devno;
+	asm("pushfl; stc; int $0x13; setc %%al; popfl"
+	    : "+a" (ax), "+S" (si), "+d" (dx)
+	    : "m" (dapa)
+	    : "ebx", "ecx", "edi", "memory");
+
+	if (!(u8)ax)
+		return 0;	/* OK */
+
+	ax = 0x0201;		/* Legacy Read, one sector */
+	cx = 0x0001;		/* Sector 0-0-1 */
+	dx = devno;
+	bx = (size_t)buf;
+	asm("pushfl; stc; int $0x13; setc %%al; popfl"
+	    : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
+	    : : "esi", "edi", "memory");
+
+	return -(u8)ax;		/* 0 or -1 */
+}
+
+static u32 read_mbr_sig(u8 devno, struct edd_info *ei)
+{
+	int sector_size;
+	char *mbrbuf_ptr, *mbrbuf_end;
+	u32 mbrsig;
+	u32 buf_base, mbr_base;
+	extern char _end[];
+	static char mbr_buf[1024];
+
+	sector_size = ei->params.bytes_per_sector;
+	if (!sector_size)
+		sector_size = 512; /* Best available guess */
+
+	buf_base = (ds() << 4) + (u32)&_end;
+	mbr_base = (buf_base+sector_size-1) & ~(sector_size-1);
+	mbrbuf_ptr = mbr_buf + (mbr_base-buf_base);
+	mbrbuf_end = mbrbuf_ptr + sector_size;
+
+	if (!(boot_params.hdr.loadflags & CAN_USE_HEAP))
+		return 0;
+	if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr)
+		return 0;
+
+	if (read_mbr(devno, mbrbuf_ptr))
+		return 0;
+
+	mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET];
+	return mbrsig;
+}
+
+static int get_edd_info(u8 devno, struct edd_info *ei)
+{
+	u16 ax, bx, cx, dx, di;
+
+	memset(ei, 0, sizeof *ei);
+
+	/* Check Extensions Present */
+
+	ax = 0x4100;
+	bx = EDDMAGIC1;
+	dx = devno;
+	asm("pushfl; stc; int $0x13; setc %%al; popfl"
+	    : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
+	    : : "esi", "edi");
+
+	if ((u8)ax)
+		return -1;	/* No extended information */
+
+	if (bx != EDDMAGIC2)
+		return -1;
+
+	ei->device  = devno;
+	ei->version = ax >> 8;	/* EDD version number */
+	ei->interface_support = cx; /* EDD functionality subsets */
+
+	/* Extended Get Device Parameters */
+
+	ei->params.length = sizeof(ei->params);
+	ax = 0x4800;
+	dx = devno;
+	asm("pushfl; int $0x13; popfl"
+	    : "+a" (ax), "+d" (dx)
+	    : "S" (&ei->params)
+	    : "ebx", "ecx", "edi");
+
+	/* Get legacy CHS parameters */
+
+	/* Ralf Brown recommends setting ES:DI to 0:0 */
+	ax = 0x0800;
+	dx = devno;
+	di = 0;
+	asm("pushw %%es; "
+	    "movw %%di,%%es; "
+	    "pushfl; stc; int $0x13; setc %%al; popfl; "
+	    "popw %%es"
+	    : "+a" (ax), "=b" (bx), "=c" (cx), "+d" (dx), "+D" (di)
+	    : : "esi");
+
+	if ((u8)ax == 0) {
+		ei->legacy_max_cylinder = (cx >> 8) + ((cx & 0xc0) << 2);
+		ei->legacy_max_head = dx >> 8;
+		ei->legacy_sectors_per_track = cx & 0x3f;
+	}
+
+	return 0;
+}
+
+void query_edd(void)
+{
+	char eddarg[8];
+	int do_mbr = 1;
+	int do_edd = 1;
+	int devno;
+	struct edd_info ei, *edp;
+
+	if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) {
+		if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip"))
+			do_mbr = 0;
+		else if (!strcmp(eddarg, "off"))
+			do_edd = 0;
+	}
+
+	edp = (struct edd_info *)boot_params.eddbuf;
+
+	if (!do_edd)
+		return;
+
+	for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
+		/*
+		 * Scan the BIOS-supported hard disks and query EDD
+		 * information...
+		 */
+		get_edd_info(devno, &ei);
+
+		if (boot_params.eddbuf_entries < EDDMAXNR) {
+			memcpy(edp, &ei, sizeof ei);
+			edp++;
+			boot_params.eddbuf_entries++;
+		}
+
+		if (do_mbr) {
+			u32 mbr_sig;
+			mbr_sig = read_mbr_sig(devno, &ei);
+			boot_params.edd_mbr_sig_buffer[devno-0x80] = mbr_sig;
+		}
+	}
+}
+
+#endif
diff --git a/arch/i386/boot/header.S b/arch/i386/boot/header.S
new file mode 100644
index 0000000..6b9923fb
--- /dev/null
+++ b/arch/i386/boot/header.S
@@ -0,0 +1,283 @@
+/*
+ *	header.S
+ *
+ *	Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ *	Based on bootsect.S and setup.S
+ *	modified by more people than can be counted
+ *
+ *	Rewritten as a common file by H. Peter Anvin (Apr 2007)
+ *
+ * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
+ * addresses must be multiplied by 16 to obtain their respective linear
+ * addresses. To avoid confusion, linear addresses are written using leading
+ * hex while segment addresses are written as segment:offset.
+ *
+ */
+
+#include <asm/segment.h>
+#include <linux/utsrelease.h>
+#include <asm/boot.h>
+#include <asm/e820.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include "boot.h"
+
+SETUPSECTS	= 4			/* default nr of setup-sectors */
+BOOTSEG		= 0x07C0		/* original address of boot-sector */
+SYSSEG		= DEF_SYSSEG		/* system loaded at 0x10000 (65536) */
+SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
+					/* to be loaded */
+ROOT_DEV	= 0			/* ROOT_DEV is now written by "build" */
+SWAP_DEV	= 0			/* SWAP_DEV is now written by "build" */
+
+#ifndef SVGA_MODE
+#define SVGA_MODE ASK_VGA
+#endif
+
+#ifndef RAMDISK
+#define RAMDISK 0
+#endif
+
+#ifndef ROOT_RDONLY
+#define ROOT_RDONLY 1
+#endif
+
+	.code16
+	.section ".bstext", "ax"
+
+	.global bootsect_start
+bootsect_start:
+
+	# Normalize the start address
+	ljmp	$BOOTSEG, $start2
+
+start2:
+	movw	%cs, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %ss
+	xorw	%sp, %sp
+	sti
+	cld
+
+	movw	$bugger_off_msg, %si
+
+msg_loop:
+	lodsb
+	andb	%al, %al
+	jz	bs_die
+	movb	$0xe, %ah
+	movw	$7, %bx
+	int	$0x10
+	jmp	msg_loop
+
+bs_die:
+	# Allow the user to press a key, then reboot
+	xorw	%ax, %ax
+	int	$0x16
+	int	$0x19
+
+	# int 0x19 should never return.  In case it does anyway,
+	# invoke the BIOS reset code...
+	ljmp	$0xf000,$0xfff0
+
+	.section ".bsdata", "a"
+bugger_off_msg:
+	.ascii	"Direct booting from floppy is no longer supported.\r\n"
+	.ascii	"Please use a boot loader program instead.\r\n"
+	.ascii	"\n"
+	.ascii	"Remove disk and press any key to reboot . . .\r\n"
+	.byte	0
+
+
+	# Kernel attributes; used by setup.  This is part 1 of the
+	# header, from the old boot sector.
+
+	.section ".header", "a"
+	.globl	hdr
+hdr:
+setup_sects:	.byte SETUPSECTS
+root_flags:	.word ROOT_RDONLY
+syssize:	.long SYSSIZE
+ram_size:	.word RAMDISK
+vid_mode:	.word SVGA_MODE
+root_dev:	.word ROOT_DEV
+boot_flag:	.word 0xAA55
+
+	# offset 512, entry point
+
+	.globl	_start
+_start:
+		# Explicitly enter this as bytes, or the assembler
+		# tries to generate a 3-byte jump here, which causes
+		# everything else to push off to the wrong offset.
+		.byte	0xeb		# short (2-byte) jump
+		.byte	start_of_setup-1f
+1:
+
+	# Part 2 of the header, from the old setup.S
+
+		.ascii	"HdrS"		# header signature
+		.word	0x0206		# header version number (>= 0x0105)
+					# or else old loadlin-1.5 will fail)
+		.globl realmode_swtch
+realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
+start_sys_seg:	.word	SYSSEG
+		.word	kernel_version-512 # pointing to kernel version string
+					# above section of header is compatible
+					# with loadlin-1.5 (header v1.5). Don't
+					# change it.
+
+type_of_loader:	.byte	0		# = 0, old one (LILO, Loadlin,
+					#      Bootlin, SYSLX, bootsect...)
+					# See Documentation/i386/boot.txt for
+					# assigned ids
+
+# flags, unused bits must be zero (RFU) bit within loadflags
+loadflags:
+LOADED_HIGH	= 1			# If set, the kernel is loaded high
+CAN_USE_HEAP	= 0x80			# If set, the loader also has set
+					# heap_end_ptr to tell how much
+					# space behind setup.S can be used for
+					# heap purposes.
+					# Only the loader knows what is free
+#ifndef __BIG_KERNEL__
+		.byte	0
+#else
+		.byte	LOADED_HIGH
+#endif
+
+setup_move_size: .word  0x8000		# size to move, when setup is not
+					# loaded at 0x90000. We will move setup
+					# to 0x90000 then just before jumping
+					# into the kernel. However, only the
+					# loader knows how much data behind
+					# us also needs to be loaded.
+
+code32_start:				# here loaders can put a different
+					# start address for 32-bit code.
+#ifndef __BIG_KERNEL__
+		.long	0x1000		#   0x1000 = default for zImage
+#else
+		.long	0x100000	# 0x100000 = default for big kernel
+#endif
+
+ramdisk_image:	.long	0		# address of loaded ramdisk image
+					# Here the loader puts the 32-bit
+					# address where it loaded the image.
+					# This only will be read by the kernel.
+
+ramdisk_size:	.long	0		# its size in bytes
+
+bootsect_kludge:
+		.long	0		# obsolete
+
+heap_end_ptr:	.word	_end+1024	# (Header version 0x0201 or later)
+					# space from here (exclusive) down to
+					# end of setup code can be used by setup
+					# for local heap purposes.
+
+pad1:		.word	0
+cmd_line_ptr:	.long	0		# (Header version 0x0202 or later)
+					# If nonzero, a 32-bit pointer
+					# to the kernel command line.
+					# The command line should be
+					# located between the start of
+					# setup and the end of low
+					# memory (0xa0000), or it may
+					# get overwritten before it
+					# gets read.  If this field is
+					# used, there is no longer
+					# anything magical about the
+					# 0x90000 segment; the setup
+					# can be located anywhere in
+					# low memory 0x10000 or higher.
+
+ramdisk_max:	.long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
+					# (Header version 0x0203 or later)
+					# The highest safe address for
+					# the contents of an initrd
+
+kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN	#physical addr alignment
+						#required for protected mode
+						#kernel
+#ifdef CONFIG_RELOCATABLE
+relocatable_kernel:    .byte 1
+#else
+relocatable_kernel:    .byte 0
+#endif
+pad2:			.byte 0
+pad3:			.word 0
+
+cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
+                                                #added with boot protocol
+                                                #version 2.06
+
+# End of setup header #####################################################
+
+	.section ".inittext", "ax"
+start_of_setup:
+#ifdef SAFE_RESET_DISK_CONTROLLER
+# Reset the disk controller.
+	movw	$0x0000, %ax		# Reset disk controller
+	movb	$0x80, %dl		# All disks
+	int	$0x13
+#endif
+
+# We will have entired with %cs = %ds+0x20, normalize %cs so
+# it is on par with the other segments.
+	pushw	%ds
+	pushw	$setup2
+	lretw
+
+setup2:
+# Force %es = %ds
+	movw	%ds, %ax
+	movw	%ax, %es
+	cld
+
+# Stack paranoia: align the stack and make sure it is good
+# for both 16- and 32-bit references.  In particular, if we
+# were meant to have been using the full 16-bit segment, the
+# caller might have set %sp to zero, which breaks %esp-based
+# references.
+	andw	$~3, %sp	# dword align (might as well...)
+	jnz	1f
+	movw	$0xfffc, %sp	# Make sure we're not zero
+1:	movzwl	%sp, %esp	# Clear upper half of %esp
+	sti
+
+# Check signature at end of setup
+	cmpl	$0x5a5aaa55, setup_sig
+	jne	setup_bad
+
+# Zero the bss
+	movw	$__bss_start, %di
+	movw	$_end+3, %cx
+	xorl	%eax, %eax
+	subw	%di, %cx
+	shrw	$2, %cx
+	rep; stosl
+
+# Jump to C code (should not return)
+	calll	main
+
+# Setup corrupt somehow...
+setup_bad:
+	movl	$setup_corrupt, %eax
+	calll	puts
+	# Fall through...
+
+	.globl	die
+	.type	die, @function
+die:
+	hlt
+	jmp	die
+
+	.size	die, .-due
+
+	.section ".initdata", "a"
+setup_corrupt:
+	.byte	7
+	.string	"No setup signature found..."
diff --git a/arch/i386/boot/main.c b/arch/i386/boot/main.c
new file mode 100644
index 0000000..7f01f96
--- /dev/null
+++ b/arch/i386/boot/main.c
@@ -0,0 +1,161 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/main.c
+ *
+ * Main module for the real-mode kernel code
+ */
+
+#include "boot.h"
+
+struct boot_params boot_params __attribute__((aligned(16)));
+
+char *HEAP = _end;
+char *heap_end = _end;		/* Default end of heap = no heap */
+
+/*
+ * Copy the header into the boot parameter block.  Since this
+ * screws up the old-style command line protocol, adjust by
+ * filling in the new-style command line pointer instead.
+ */
+#define OLD_CL_MAGIC	0xA33F
+#define OLD_CL_ADDRESS	0x20
+
+static void copy_boot_params(void)
+{
+	struct old_cmdline {
+		u16 cl_magic;
+		u16 cl_offset;
+	};
+	const struct old_cmdline * const oldcmd =
+		(const struct old_cmdline *)OLD_CL_ADDRESS;
+
+	BUILD_BUG_ON(sizeof boot_params != 4096);
+	memcpy(&boot_params.hdr, &hdr, sizeof hdr);
+
+	if (!boot_params.hdr.cmd_line_ptr &&
+	    oldcmd->cl_magic == OLD_CL_MAGIC) {
+		/* Old-style command line protocol. */
+		u16 cmdline_seg;
+
+		/* Figure out if the command line falls in the region
+		   of memory that an old kernel would have copied up
+		   to 0x90000... */
+		if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
+			cmdline_seg = ds();
+		else
+			cmdline_seg = 0x9000;
+
+		boot_params.hdr.cmd_line_ptr =
+			(cmdline_seg << 4) + oldcmd->cl_offset;
+	}
+}
+
+/*
+ * Set the keyboard repeat rate to maximum.  Unclear why this
+ * is done here; this might be possible to kill off as stale code.
+ */
+static void keyboard_set_repeat(void)
+{
+	u16 ax = 0x0305;
+	u16 bx = 0;
+	asm volatile("int $0x16"
+		     : "+a" (ax), "+b" (bx)
+		     : : "ecx", "edx", "esi", "edi");
+}
+
+/*
+ * Get Intel SpeedStep IST information.
+ */
+static void query_speedstep_ist(void)
+{
+	asm("int $0x15"
+	    : "=a" (boot_params.speedstep_info[0]),
+	      "=b" (boot_params.speedstep_info[1]),
+	      "=c" (boot_params.speedstep_info[2]),
+	      "=d" (boot_params.speedstep_info[3])
+	    : "a" (0x0000e980),	 /* IST Support */
+	      "d" (0x47534943)); /* Request value */
+}
+
+/*
+ * Tell the BIOS what CPU mode we intend to run in.
+ */
+static void set_bios_mode(void)
+{
+#ifdef CONFIG_X86_64
+	u32 eax, ebx;
+
+	eax = 0xec00;
+	ebx = 2;
+	asm volatile("int $0x15"
+		     : "+a" (eax), "+b" (ebx)
+		     : : "ecx", "edx", "esi", "edi");
+#endif
+}
+
+void main(void)
+{
+	/* First, copy the boot header into the "zeropage" */
+	copy_boot_params();
+
+	/* End of heap check */
+	if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
+		heap_end = (char *)(boot_params.hdr.heap_end_ptr
+				    +0x200-STACK_SIZE);
+	} else {
+		/* Boot protocol 2.00 only, no heap available */
+		puts("WARNING: Ancient bootloader, some functionality "
+		     "may be limited!\n");
+	}
+
+	/* Make sure we have all the proper CPU support */
+	if (validate_cpu()) {
+		puts("Unable to boot - please use a kernel appropriate "
+		     "for your CPU.\n");
+		die();
+	}
+
+	/* Tell the BIOS what CPU mode we intend to run in. */
+	set_bios_mode();
+
+	/* Detect memory layout */
+	detect_memory();
+
+	/* Set keyboard repeat rate (why?) */
+	keyboard_set_repeat();
+
+	/* Set the video mode */
+	set_video();
+
+	/* Query MCA information */
+	query_mca();
+
+	/* Voyager */
+#ifdef CONFIG_X86_VOYAGER
+	query_voyager();
+#endif
+
+	/* Query SpeedStep IST information */
+	query_speedstep_ist();
+
+	/* Query APM information */
+#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
+	query_apm_bios();
+#endif
+
+	/* Query EDD information */
+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+	query_edd();
+#endif
+	/* Do the last things and invoke protected mode */
+	go_to_protected_mode();
+}
diff --git a/arch/i386/boot/mca.c b/arch/i386/boot/mca.c
new file mode 100644
index 0000000..9b68bd1
--- /dev/null
+++ b/arch/i386/boot/mca.c
@@ -0,0 +1,43 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/mca.c
+ *
+ * Get the MCA system description table
+ */
+
+#include "boot.h"
+
+int query_mca(void)
+{
+	u8 err;
+	u16 es, bx, len;
+
+	asm("pushw %%es ; "
+	    "int $0x15 ; "
+	    "setc %0 ; "
+	    "movw %%es, %1 ; "
+	    "popw %%es"
+	    : "=acdSDm" (err), "=acdSDm" (es), "=b" (bx)
+	    : "a" (0xc000));
+
+	if (err)
+		return -1;	/* No MCA present */
+
+	set_fs(es);
+	len = rdfs16(bx);
+
+	if (len > sizeof(boot_params.sys_desc_table))
+		len = sizeof(boot_params.sys_desc_table);
+
+	copy_from_fs(&boot_params.sys_desc_table, bx, len);
+	return 0;
+}
diff --git a/arch/i386/boot/memory.c b/arch/i386/boot/memory.c
new file mode 100644
index 0000000..1a2e62d
--- /dev/null
+++ b/arch/i386/boot/memory.c
@@ -0,0 +1,99 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/memory.c
+ *
+ * Memory detection code
+ */
+
+#include "boot.h"
+
+#define SMAP	0x534d4150	/* ASCII "SMAP" */
+
+static int detect_memory_e820(void)
+{
+	u32 next = 0;
+	u32 size, id;
+	u8 err;
+	struct e820entry *desc = boot_params.e820_map;
+
+	do {
+		size = sizeof(struct e820entry);
+		id = SMAP;
+		asm("int $0x15; setc %0"
+		    : "=am" (err), "+b" (next), "+d" (id), "+c" (size),
+		      "=m" (*desc)
+		    : "D" (desc), "a" (0xe820));
+
+		if (err || id != SMAP)
+			break;
+
+		boot_params.e820_entries++;
+		desc++;
+	} while (next && boot_params.e820_entries < E820MAX);
+
+	return boot_params.e820_entries;
+}
+
+static int detect_memory_e801(void)
+{
+	u16 ax, bx, cx, dx;
+	u8 err;
+
+	bx = cx = dx = 0;
+	ax = 0xe801;
+	asm("stc; int $0x15; setc %0"
+	    : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
+
+	if (err)
+		return -1;
+
+	/* Do we really need to do this? */
+	if (cx || dx) {
+		ax = cx;
+		bx = dx;
+	}
+
+	if (ax > 15*1024)
+		return -1;	/* Bogus! */
+
+	/* This ignores memory above 16MB if we have a memory hole
+	   there.  If someone actually finds a machine with a memory
+	   hole at 16MB and no support for 0E820h they should probably
+	   generate a fake e820 map. */
+	boot_params.alt_mem_k = (ax == 15*1024) ? (dx << 6)+ax : ax;
+
+	return 0;
+}
+
+static int detect_memory_88(void)
+{
+	u16 ax;
+	u8 err;
+
+	ax = 0x8800;
+	asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
+
+	boot_params.screen_info.ext_mem_k = ax;
+
+	return -err;
+}
+
+int detect_memory(void)
+{
+	if (detect_memory_e820() > 0)
+		return 0;
+
+	if (!detect_memory_e801())
+		return 0;
+
+	return detect_memory_88();
+}
diff --git a/arch/i386/boot/pm.c b/arch/i386/boot/pm.c
new file mode 100644
index 0000000..3fa53e1
--- /dev/null
+++ b/arch/i386/boot/pm.c
@@ -0,0 +1,170 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/pm.c
+ *
+ * Prepare the machine for transition to protected mode.
+ */
+
+#include "boot.h"
+#include <asm/segment.h>
+
+/*
+ * Invoke the realmode switch hook if present; otherwise
+ * disable all interrupts.
+ */
+static void realmode_switch_hook(void)
+{
+	if (boot_params.hdr.realmode_swtch) {
+		asm volatile("lcallw *%0"
+			     : : "m" (boot_params.hdr.realmode_swtch)
+			     : "eax", "ebx", "ecx", "edx");
+	} else {
+		asm volatile("cli");
+		outb(0x80, 0x70); /* Disable NMI */
+		io_delay();
+	}
+}
+
+/*
+ * A zImage kernel is loaded at 0x10000 but wants to run at 0x1000.
+ * A bzImage kernel is loaded and runs at 0x100000.
+ */
+static void move_kernel_around(void)
+{
+	/* Note: rely on the compile-time option here rather than
+	   the LOADED_HIGH flag.  The Qemu kernel loader unconditionally
+	   sets the loadflags to zero. */
+#ifndef __BIG_KERNEL__
+	u16 dst_seg, src_seg;
+	u32 syssize;
+
+	dst_seg =  0x1000 >> 4;
+	src_seg = 0x10000 >> 4;
+	syssize = boot_params.hdr.syssize; /* Size in 16-byte paragraphs */
+
+	while (syssize) {
+		int paras  = (syssize >= 0x1000) ? 0x1000 : syssize;
+		int dwords = paras << 2;
+
+		asm volatile("pushw %%es ; "
+			     "pushw %%ds ; "
+			     "movw %1,%%es ; "
+			     "movw %2,%%ds ; "
+			     "xorw %%di,%%di ; "
+			     "xorw %%si,%%si ; "
+			     "rep;movsl ; "
+			     "popw %%ds ; "
+			     "popw %%es"
+			     : "+c" (dwords)
+			     : "rm" (dst_seg), "rm" (src_seg)
+			     : "esi", "edi");
+
+		syssize -= paras;
+		dst_seg += paras;
+		src_seg += paras;
+	}
+#endif
+}
+
+/*
+ * Disable all interrupts at the legacy PIC.
+ */
+static void mask_all_interrupts(void)
+{
+	outb(0xff, 0xa1);	/* Mask all interrupts on the seconday PIC */
+	io_delay();
+	outb(0xfb, 0x21);	/* Mask all but cascade on the primary PIC */
+	io_delay();
+}
+
+/*
+ * Reset IGNNE# if asserted in the FPU.
+ */
+static void reset_coprocessor(void)
+{
+	outb(0, 0xf0);
+	io_delay();
+	outb(0, 0xf1);
+	io_delay();
+}
+
+/*
+ * Set up the GDT
+ */
+#define GDT_ENTRY(flags,base,limit)		\
+	(((u64)(base & 0xff000000) << 32) |	\
+	 ((u64)flags << 40) |			\
+	 ((u64)(limit & 0x00ff0000) << 32) |	\
+	 ((u64)(base & 0x00ffff00) << 16) |	\
+	 ((u64)(limit & 0x0000ffff)))
+
+struct gdt_ptr {
+	u16 len;
+	u32 ptr;
+} __attribute__((packed));
+
+static void setup_gdt(void)
+{
+	/* There are machines which are known to not boot with the GDT
+	   being 8-byte unaligned.  Intel recommends 16 byte alignment. */
+	static const u64 boot_gdt[] __attribute__((aligned(16))) = {
+		/* CS: code, read/execute, 4 GB, base 0 */
+		[GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
+		/* DS: data, read/write, 4 GB, base 0 */
+		[GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
+	};
+	struct gdt_ptr gdt;
+
+	gdt.len = sizeof(boot_gdt)-1;
+	gdt.ptr = (u32)&boot_gdt + (ds() << 4);
+
+	asm volatile("lgdtl %0" : : "m" (gdt));
+}
+
+/*
+ * Set up the IDT
+ */
+static void setup_idt(void)
+{
+	static const struct gdt_ptr null_idt = {0, 0};
+	asm volatile("lidtl %0" : : "m" (null_idt));
+}
+
+/*
+ * Actual invocation sequence
+ */
+void go_to_protected_mode(void)
+{
+	/* Hook before leaving real mode, also disables interrupts */
+	realmode_switch_hook();
+
+	/* Move the kernel/setup to their final resting places */
+	move_kernel_around();
+
+	/* Enable the A20 gate */
+	if (enable_a20()) {
+		puts("A20 gate not responding, unable to boot...\n");
+		die();
+	}
+
+	/* Reset coprocessor (IGNNE#) */
+	reset_coprocessor();
+
+	/* Mask all interrupts in the PIC */
+	mask_all_interrupts();
+
+	/* Actual transition to protected mode... */
+	setup_idt();
+	setup_gdt();
+	protected_mode_jump(boot_params.hdr.code32_start,
+			    (u32)&boot_params + (ds() << 4));
+}
diff --git a/arch/i386/boot/pmjump.S b/arch/i386/boot/pmjump.S
new file mode 100644
index 0000000..2e55923
--- /dev/null
+++ b/arch/i386/boot/pmjump.S
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/pmjump.S
+ *
+ * The actual transition into protected mode
+ */
+
+#include <asm/boot.h>
+#include <asm/segment.h>
+
+	.text
+
+	.globl	protected_mode_jump
+	.type	protected_mode_jump, @function
+
+	.code16
+
+/*
+ * void protected_mode_jump(u32 entrypoint, u32 bootparams);
+ */
+protected_mode_jump:
+	xorl	%ebx, %ebx		# Flag to indicate this is a boot
+	movl	%edx, %esi		# Pointer to boot_params table
+	movl	%eax, 2f		# Patch ljmpl instruction
+	jmp	1f			# Short jump to flush instruction q.
+
+1:
+	movw	$__BOOT_DS, %cx
+
+	movl	%cr0, %edx
+	orb	$1, %dl			# Protected mode (PE) bit
+	movl	%edx, %cr0
+
+	movw	%cx, %ds
+	movw	%cx, %es
+	movw	%cx, %fs
+	movw	%cx, %gs
+	movw	%cx, %ss
+
+	# Jump to the 32-bit entrypoint
+	.byte	0x66, 0xea		# ljmpl opcode
+2:	.long	0			# offset
+	.word	__BOOT_CS		# segment
+
+	.size	protected_mode_jump, .-protected_mode_jump
diff --git a/arch/i386/boot/printf.c b/arch/i386/boot/printf.c
new file mode 100644
index 0000000..1a09f93
--- /dev/null
+++ b/arch/i386/boot/printf.c
@@ -0,0 +1,307 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/printf.c
+ *
+ * Oh, it's a waste of space, but oh-so-yummy for debugging.  This
+ * version of printf() does not include 64-bit support.  "Live with
+ * it."
+ *
+ */
+
+#include "boot.h"
+
+static int skip_atoi(const char **s)
+{
+	int i = 0;
+
+	while (isdigit(**s))
+		i = i * 10 + *((*s)++) - '0';
+	return i;
+}
+
+#define ZEROPAD	1		/* pad with zero */
+#define SIGN	2		/* unsigned/signed long */
+#define PLUS	4		/* show plus */
+#define SPACE	8		/* space if plus */
+#define LEFT	16		/* left justified */
+#define SPECIAL	32		/* 0x */
+#define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
+
+#define do_div(n,base) ({ \
+int __res; \
+__res = ((unsigned long) n) % (unsigned) base; \
+n = ((unsigned long) n) / (unsigned) base; \
+__res; })
+
+static char *number(char *str, long num, int base, int size, int precision,
+		    int type)
+{
+	char c, sign, tmp[66];
+	const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
+	int i;
+
+	if (type & LARGE)
+		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+	if (type & LEFT)
+		type &= ~ZEROPAD;
+	if (base < 2 || base > 36)
+		return 0;
+	c = (type & ZEROPAD) ? '0' : ' ';
+	sign = 0;
+	if (type & SIGN) {
+		if (num < 0) {
+			sign = '-';
+			num = -num;
+			size--;
+		} else if (type & PLUS) {
+			sign = '+';
+			size--;
+		} else if (type & SPACE) {
+			sign = ' ';
+			size--;
+		}
+	}
+	if (type & SPECIAL) {
+		if (base == 16)
+			size -= 2;
+		else if (base == 8)
+			size--;
+	}
+	i = 0;
+	if (num == 0)
+		tmp[i++] = '0';
+	else
+		while (num != 0)
+			tmp[i++] = digits[do_div(num, base)];
+	if (i > precision)
+		precision = i;
+	size -= precision;
+	if (!(type & (ZEROPAD + LEFT)))
+		while (size-- > 0)
+			*str++ = ' ';
+	if (sign)
+		*str++ = sign;
+	if (type & SPECIAL) {
+		if (base == 8)
+			*str++ = '0';
+		else if (base == 16) {
+			*str++ = '0';
+			*str++ = digits[33];
+		}
+	}
+	if (!(type & LEFT))
+		while (size-- > 0)
+			*str++ = c;
+	while (i < precision--)
+		*str++ = '0';
+	while (i-- > 0)
+		*str++ = tmp[i];
+	while (size-- > 0)
+		*str++ = ' ';
+	return str;
+}
+
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+	int len;
+	unsigned long num;
+	int i, base;
+	char *str;
+	const char *s;
+
+	int flags;		/* flags to number() */
+
+	int field_width;	/* width of output field */
+	int precision;		/* min. # of digits for integers; max
+				   number of chars for from string */
+	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
+
+	for (str = buf; *fmt; ++fmt) {
+		if (*fmt != '%') {
+			*str++ = *fmt;
+			continue;
+		}
+
+		/* process flags */
+		flags = 0;
+	      repeat:
+		++fmt;		/* this also skips first '%' */
+		switch (*fmt) {
+		case '-':
+			flags |= LEFT;
+			goto repeat;
+		case '+':
+			flags |= PLUS;
+			goto repeat;
+		case ' ':
+			flags |= SPACE;
+			goto repeat;
+		case '#':
+			flags |= SPECIAL;
+			goto repeat;
+		case '0':
+			flags |= ZEROPAD;
+			goto repeat;
+		}
+
+		/* get field width */
+		field_width = -1;
+		if (isdigit(*fmt))
+			field_width = skip_atoi(&fmt);
+		else if (*fmt == '*') {
+			++fmt;
+			/* it's the next argument */
+			field_width = va_arg(args, int);
+			if (field_width < 0) {
+				field_width = -field_width;
+				flags |= LEFT;
+			}
+		}
+
+		/* get the precision */
+		precision = -1;
+		if (*fmt == '.') {
+			++fmt;
+			if (isdigit(*fmt))
+				precision = skip_atoi(&fmt);
+			else if (*fmt == '*') {
+				++fmt;
+				/* it's the next argument */
+				precision = va_arg(args, int);
+			}
+			if (precision < 0)
+				precision = 0;
+		}
+
+		/* get the conversion qualifier */
+		qualifier = -1;
+		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
+			qualifier = *fmt;
+			++fmt;
+		}
+
+		/* default base */
+		base = 10;
+
+		switch (*fmt) {
+		case 'c':
+			if (!(flags & LEFT))
+				while (--field_width > 0)
+					*str++ = ' ';
+			*str++ = (unsigned char)va_arg(args, int);
+			while (--field_width > 0)
+				*str++ = ' ';
+			continue;
+
+		case 's':
+			s = va_arg(args, char *);
+			len = strnlen(s, precision);
+
+			if (!(flags & LEFT))
+				while (len < field_width--)
+					*str++ = ' ';
+			for (i = 0; i < len; ++i)
+				*str++ = *s++;
+			while (len < field_width--)
+				*str++ = ' ';
+			continue;
+
+		case 'p':
+			if (field_width == -1) {
+				field_width = 2 * sizeof(void *);
+				flags |= ZEROPAD;
+			}
+			str = number(str,
+				     (unsigned long)va_arg(args, void *), 16,
+				     field_width, precision, flags);
+			continue;
+
+		case 'n':
+			if (qualifier == 'l') {
+				long *ip = va_arg(args, long *);
+				*ip = (str - buf);
+			} else {
+				int *ip = va_arg(args, int *);
+				*ip = (str - buf);
+			}
+			continue;
+
+		case '%':
+			*str++ = '%';
+			continue;
+
+			/* integer number formats - set up the flags and "break" */
+		case 'o':
+			base = 8;
+			break;
+
+		case 'X':
+			flags |= LARGE;
+		case 'x':
+			base = 16;
+			break;
+
+		case 'd':
+		case 'i':
+			flags |= SIGN;
+		case 'u':
+			break;
+
+		default:
+			*str++ = '%';
+			if (*fmt)
+				*str++ = *fmt;
+			else
+				--fmt;
+			continue;
+		}
+		if (qualifier == 'l')
+			num = va_arg(args, unsigned long);
+		else if (qualifier == 'h') {
+			num = (unsigned short)va_arg(args, int);
+			if (flags & SIGN)
+				num = (short)num;
+		} else if (flags & SIGN)
+			num = va_arg(args, int);
+		else
+			num = va_arg(args, unsigned int);
+		str = number(str, num, base, field_width, precision, flags);
+	}
+	*str = '\0';
+	return str - buf;
+}
+
+int sprintf(char *buf, const char *fmt, ...)
+{
+	va_list args;
+	int i;
+
+	va_start(args, fmt);
+	i = vsprintf(buf, fmt, args);
+	va_end(args);
+	return i;
+}
+
+int printf(const char *fmt, ...)
+{
+	char printf_buf[1024];
+	va_list args;
+	int printed;
+
+	va_start(args, fmt);
+	printed = vsprintf(printf_buf, fmt, args);
+	va_end(args);
+
+	puts(printf_buf);
+
+	return printed;
+}
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
deleted file mode 100644
index 6dbcc95..0000000
--- a/arch/i386/boot/setup.S
+++ /dev/null
@@ -1,1075 +0,0 @@
-/*
- *	setup.S		Copyright (C) 1991, 1992 Linus Torvalds
- *
- * setup.s is responsible for getting the system data from the BIOS,
- * and putting them into the appropriate places in system memory.
- * both setup.s and system has been loaded by the bootblock.
- *
- * This code asks the bios for memory/disk/other parameters, and
- * puts them in a "safe" place: 0x90000-0x901FF, ie where the
- * boot-block used to be. It is then up to the protected mode
- * system to read them from there before the area is overwritten
- * for buffer-blocks.
- *
- * Move PS/2 aux init code to psaux.c
- * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
- *
- * some changes and additional features by Christoph Niemann,
- * March 1993/June 1994 (Christoph.Niemann@linux.org)
- *
- * add APM BIOS checking by Stephen Rothwell, May 1994
- * (sfr@canb.auug.org.au)
- *
- * High load stuff, initrd support and position independency
- * by Hans Lermen & Werner Almesberger, February 1996
- * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
- *
- * Video handling moved to video.S by Martin Mares, March 1996
- * <mj@k332.feld.cvut.cz>
- *
- * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
- * parsons) to avoid loadlin confusion, July 1997
- *
- * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
- * <stiker@northlink.com>
- *
- * Fix to work around buggy BIOSes which don't use carry bit correctly
- * and/or report extended memory in CX/DX for e801h memory size detection 
- * call.  As a result the kernel got wrong figures.  The int15/e801h docs
- * from Ralf Brown interrupt list seem to indicate AX/BX should be used
- * anyway.  So to avoid breaking many machines (presumably there was a reason
- * to orginally use CX/DX instead of AX/BX), we do a kludge to see
- * if CX/DX have been changed in the e801 call and if so use AX/BX .
- * Michael Miller, April 2001 <michaelm@mjmm.org>
- *
- * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes
- * by Robert Schwebel, December 2001 <robert@schwebel.de>
- */
-
-#include <asm/segment.h>
-#include <linux/utsrelease.h>
-#include <linux/compile.h>
-#include <asm/boot.h>
-#include <asm/e820.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-	
-/* Signature words to ensure LILO loaded us right */
-#define SIG1	0xAA55
-#define SIG2	0x5A5A
-
-INITSEG  = DEF_INITSEG		# 0x9000, we move boot here, out of the way
-SYSSEG   = DEF_SYSSEG		# 0x1000, system loaded at 0x10000 (65536).
-SETUPSEG = DEF_SETUPSEG		# 0x9020, this is the current segment
-				# ... and the former contents of CS
-
-DELTA_INITSEG = SETUPSEG - INITSEG	# 0x0020
-
-.code16
-.globl begtext, begdata, begbss, endtext, enddata, endbss
-
-.text
-begtext:
-.data
-begdata:
-.bss
-begbss:
-.text
-
-start:
-	jmp	trampoline
-
-# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
-
-		.ascii	"HdrS"		# header signature
-		.word	0x0206		# header version number (>= 0x0105)
-					# or else old loadlin-1.5 will fail)
-realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
-start_sys_seg:	.word	SYSSEG
-		.word	kernel_version	# pointing to kernel version string
-					# above section of header is compatible
-					# with loadlin-1.5 (header v1.5). Don't
-					# change it.
-
-type_of_loader:	.byte	0		# = 0, old one (LILO, Loadlin,
-					#      Bootlin, SYSLX, bootsect...)
-					# See Documentation/i386/boot.txt for
-					# assigned ids
-	
-# flags, unused bits must be zero (RFU) bit within loadflags
-loadflags:
-LOADED_HIGH	= 1			# If set, the kernel is loaded high
-CAN_USE_HEAP	= 0x80			# If set, the loader also has set
-					# heap_end_ptr to tell how much
-					# space behind setup.S can be used for
-					# heap purposes.
-					# Only the loader knows what is free
-#ifndef __BIG_KERNEL__
-		.byte	0
-#else
-		.byte	LOADED_HIGH
-#endif
-
-setup_move_size: .word  0x8000		# size to move, when setup is not
-					# loaded at 0x90000. We will move setup 
-					# to 0x90000 then just before jumping
-					# into the kernel. However, only the
-					# loader knows how much data behind
-					# us also needs to be loaded.
-
-code32_start:				# here loaders can put a different
-					# start address for 32-bit code.
-#ifndef __BIG_KERNEL__
-		.long	0x1000		#   0x1000 = default for zImage
-#else
-		.long	0x100000	# 0x100000 = default for big kernel
-#endif
-
-ramdisk_image:	.long	0		# address of loaded ramdisk image
-					# Here the loader puts the 32-bit
-					# address where it loaded the image.
-					# This only will be read by the kernel.
-
-ramdisk_size:	.long	0		# its size in bytes
-
-bootsect_kludge:
-		.long	0		# obsolete
-
-heap_end_ptr:	.word	modelist+1024	# (Header version 0x0201 or later)
-					# space from here (exclusive) down to
-					# end of setup code can be used by setup
-					# for local heap purposes.
-
-pad1:		.word	0
-cmd_line_ptr:	.long 0			# (Header version 0x0202 or later)
-					# If nonzero, a 32-bit pointer
-					# to the kernel command line.
-					# The command line should be
-					# located between the start of
-					# setup and the end of low
-					# memory (0xa0000), or it may
-					# get overwritten before it
-					# gets read.  If this field is
-					# used, there is no longer
-					# anything magical about the
-					# 0x90000 segment; the setup
-					# can be located anywhere in
-					# low memory 0x10000 or higher.
-
-ramdisk_max:	.long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
-					# (Header version 0x0203 or later)
-					# The highest safe address for
-					# the contents of an initrd
-
-kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN 	#physical addr alignment
-						#required for protected mode
-						#kernel
-#ifdef CONFIG_RELOCATABLE
-relocatable_kernel:    .byte 1
-#else
-relocatable_kernel:    .byte 0
-#endif
-pad2:			.byte 0
-pad3:			.word 0
-
-cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
-                                                #added with boot protocol
-                                                #version 2.06
-
-trampoline:	call	start_of_setup
-		.align 16
-					# The offset at this point is 0x240
-		.space	(0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
-# End of setup header #####################################################
-
-start_of_setup:
-# Bootlin depends on this being done early
-	movw	$0x01500, %ax
-	movb	$0x81, %dl
-	int	$0x13
-
-#ifdef SAFE_RESET_DISK_CONTROLLER
-# Reset the disk controller.
-	movw	$0x0000, %ax
-	movb	$0x80, %dl
-	int	$0x13
-#endif
-
-# Set %ds = %cs, we know that SETUPSEG = %cs at this point
-	movw	%cs, %ax		# aka SETUPSEG
-	movw	%ax, %ds
-# Check signature at end of setup
-	cmpw	$SIG1, setup_sig1
-	jne	bad_sig
-
-	cmpw	$SIG2, setup_sig2
-	jne	bad_sig
-
-	jmp	good_sig1
-
-# Routine to print asciiz string at ds:si
-prtstr:
-	lodsb
-	andb	%al, %al
-	jz	fin
-
-	call	prtchr
-	jmp	prtstr
-
-fin:	ret
-
-# Space printing
-prtsp2:	call	prtspc		# Print double space
-prtspc:	movb	$0x20, %al	# Print single space (note: fall-thru)
-
-# Part of above routine, this one just prints ascii al
-prtchr:	pushw	%ax
-	pushw	%cx
-	movw	$7,%bx
-	movw	$0x01, %cx
-	movb	$0x0e, %ah
-	int	$0x10
-	popw	%cx
-	popw	%ax
-	ret
-
-beep:	movb	$0x07, %al
-	jmp	prtchr
-	
-no_sig_mess: .string	"No setup signature found ..."
-
-good_sig1:
-	jmp	good_sig
-
-# We now have to find the rest of the setup code/data
-bad_sig:
-	movw	%cs, %ax			# SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# INITSEG
-	movw	%ax, %ds
-	xorb	%bh, %bh
-	movb	(497), %bl			# get setup sect from bootsect
-	subw	$4, %bx				# LILO loads 4 sectors of setup
-	shlw	$8, %bx				# convert to words (1sect=2^8 words)
-	movw	%bx, %cx
-	shrw	$3, %bx				# convert to segment
-	addw	$SYSSEG, %bx
-	movw	%bx, %cs:start_sys_seg
-# Move rest of setup code/data to here
-	movw	$2048, %di			# four sectors loaded by LILO
-	subw	%si, %si
-	pushw	%cs
-	popw	%es
-	movw	$SYSSEG, %ax
-	movw	%ax, %ds
-	rep
-	movsw
-	movw	%cs, %ax			# aka SETUPSEG
-	movw	%ax, %ds
-	cmpw	$SIG1, setup_sig1
-	jne	no_sig
-
-	cmpw	$SIG2, setup_sig2
-	jne	no_sig
-
-	jmp	good_sig
-
-no_sig:
-	lea	no_sig_mess, %si
-	call	prtstr
-
-no_sig_loop:
-	hlt
-	jmp	no_sig_loop
-
-good_sig:
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax 		# aka INITSEG
-	movw	%ax, %ds
-# Check if an old loader tries to load a big-kernel
-	testb	$LOADED_HIGH, %cs:loadflags	# Do we have a big kernel?
-	jz	loader_ok			# No, no danger for old loaders.
-
-	cmpb	$0, %cs:type_of_loader 		# Do we have a loader that
-						# can deal with us?
-	jnz	loader_ok			# Yes, continue.
-
-	pushw	%cs				# No, we have an old loader,
-	popw	%ds				# die. 
-	lea	loader_panic_mess, %si
-	call	prtstr
-
-	jmp	no_sig_loop
-
-loader_panic_mess: .string "Wrong loader, giving up..."
-
-# check minimum cpuid
-# we do this here because it is the last place we can actually
-# show a user visible error message. Later the video modus
-# might be already messed up.
-loader_ok:
-	call verify_cpu
-	testl  %eax,%eax
-	jz	cpu_ok
-	movw	%cs,%ax		# aka SETUPSEG
-	movw	%ax,%ds
-	lea	cpu_panic_mess,%si
-	call	prtstr
-1:	jmp	1b
-
-cpu_panic_mess:
-	.asciz  "PANIC: CPU too old for this kernel."
-
-#include "../kernel/verify_cpu.S"
-
-cpu_ok:
-# Get memory size (extended mem, kB)
-
-	xorl	%eax, %eax
-	movl	%eax, (0x1e0)
-#ifndef STANDARD_MEMORY_BIOS_CALL
-	movb	%al, (E820NR)
-# Try three different memory detection schemes.  First, try
-# e820h, which lets us assemble a memory map, then try e801h,
-# which returns a 32-bit memory size, and finally 88h, which
-# returns 0-64m
-
-# method E820H:
-# the memory map from hell.  e820h returns memory classified into
-# a whole bunch of different types, and allows memory holes and
-# everything.  We scan through this memory map and build a list
-# of the first 32 memory areas, which we return at [E820MAP].
-# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
-
-#define SMAP  0x534d4150
-
-meme820:
-	xorl	%ebx, %ebx			# continuation counter
-	movw	$E820MAP, %di			# point into the whitelist
-						# so we can have the bios
-						# directly write into it.
-
-jmpe820:
-	movl	$0x0000e820, %eax		# e820, upper word zeroed
-	movl	$SMAP, %edx			# ascii 'SMAP'
-	movl	$20, %ecx			# size of the e820rec
-	pushw	%ds				# data record.
-	popw	%es
-	int	$0x15				# make the call
-	jc	bail820				# fall to e801 if it fails
-
-	cmpl	$SMAP, %eax			# check the return is `SMAP'
-	jne	bail820				# fall to e801 if it fails
-
-#	cmpl	$1, 16(%di)			# is this usable memory?
-#	jne	again820
-
-	# If this is usable memory, we save it by simply advancing %di by
-	# sizeof(e820rec).
-	#
-good820:
-	movb	(E820NR), %al			# up to 128 entries
-	cmpb	$E820MAX, %al
-	jae	bail820
-
-	incb	(E820NR)
-	movw	%di, %ax
-	addw	$20, %ax
-	movw	%ax, %di
-again820:
-	cmpl	$0, %ebx			# check to see if
-	jne	jmpe820				# %ebx is set to EOF
-bail820:
-
-
-# method E801H:
-# memory size is in 1k chunksizes, to avoid confusing loadlin.
-# we store the 0xe801 memory size in a completely different place,
-# because it will most likely be longer than 16 bits.
-# (use 1e0 because that's what Larry Augustine uses in his
-# alternative new memory detection scheme, and it's sensible
-# to write everything into the same place.)
-
-meme801:
-	stc					# fix to work around buggy
-	xorw	%cx,%cx				# BIOSes which don't clear/set
-	xorw	%dx,%dx				# carry on pass/error of
-						# e801h memory size call
-						# or merely pass cx,dx though
-						# without changing them.
-	movw	$0xe801, %ax
-	int	$0x15
-	jc	mem88
-
-	cmpw	$0x0, %cx			# Kludge to handle BIOSes
-	jne	e801usecxdx			# which report their extended
-	cmpw	$0x0, %dx			# memory in AX/BX rather than
-	jne	e801usecxdx			# CX/DX.  The spec I have read
-	movw	%ax, %cx			# seems to indicate AX/BX 
-	movw	%bx, %dx			# are more reasonable anyway...
-
-e801usecxdx:
-	andl	$0xffff, %edx			# clear sign extend
-	shll	$6, %edx			# and go from 64k to 1k chunks
-	movl	%edx, (0x1e0)			# store extended memory size
-	andl	$0xffff, %ecx			# clear sign extend
- 	addl	%ecx, (0x1e0)			# and add lower memory into
-						# total size.
-
-# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
-# 64mb, depending on the bios) in ax.
-mem88:
-
-#endif
-	movb	$0x88, %ah
-	int	$0x15
-	movw	%ax, (2)
-
-# Set the keyboard repeat rate to the max
-	movw	$0x0305, %ax
-	xorw	%bx, %bx
-	int	$0x16
-
-# Check for video adapter and its parameters and allow the
-# user to browse video modes.
-	call	video				# NOTE: we need %ds pointing
-						# to bootsector
-
-# Get hd0 data...
-	xorw	%ax, %ax
-	movw	%ax, %ds
-	ldsw	(4 * 0x41), %si
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	pushw	%ax
-	movw	%ax, %es
-	movw	$0x0080, %di
-	movw	$0x10, %cx
-	pushw	%cx
-	cld
-	rep
- 	movsb
-# Get hd1 data...
-	xorw	%ax, %ax
-	movw	%ax, %ds
-	ldsw	(4 * 0x46), %si
-	popw	%cx
-	popw	%es
-	movw	$0x0090, %di
-	rep
-	movsb
-# Check that there IS a hd1 :-)
-	movw	$0x01500, %ax
-	movb	$0x81, %dl
-	int	$0x13
-	jc	no_disk1
-	
-	cmpb	$3, %ah
-	je	is_disk1
-
-no_disk1:
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax 		# aka INITSEG
-	movw	%ax, %es
-	movw	$0x0090, %di
-	movw	$0x10, %cx
-	xorw	%ax, %ax
-	cld
-	rep
-	stosb
-is_disk1:
-# check for Micro Channel (MCA) bus
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	movw	%ax, %ds
-	xorw	%ax, %ax
-	movw	%ax, (0xa0)			# set table length to 0
-	movb	$0xc0, %ah
-	stc
-	int	$0x15				# moves feature table to es:bx
-	jc	no_mca
-
-	pushw	%ds
-	movw	%es, %ax
-	movw	%ax, %ds
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	movw	%ax, %es
-	movw	%bx, %si
-	movw	$0xa0, %di
-	movw	(%si), %cx
-	addw	$2, %cx				# table length is a short
-	cmpw	$0x10, %cx
-	jc	sysdesc_ok
-
-	movw	$0x10, %cx			# we keep only first 16 bytes
-sysdesc_ok:
-	rep
-	movsb
-	popw	%ds
-no_mca:
-#ifdef CONFIG_X86_VOYAGER
-	movb	$0xff, 0x40	# flag on config found
-	movb	$0xc0, %al
-	mov	$0xff, %ah
-	int	$0x15		# put voyager config info at es:di
-	jc	no_voyager
-	movw	$0x40, %si	# place voyager info in apm table
-	cld
-	movw	$7, %cx
-voyager_rep:
-	movb	%es:(%di), %al
-	movb	%al,(%si)
-	incw	%di
-	incw	%si
-	decw	%cx
-	jnz	voyager_rep
-no_voyager:	
-#endif
-# Check for PS/2 pointing device
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	movw	%ax, %ds
-	movb	$0, (0x1ff)			# default is no pointing device
-	int	$0x11				# int 0x11: equipment list
-	testb	$0x04, %al			# check if mouse installed
-	jz	no_psmouse
-
-	movb	$0xAA, (0x1ff)			# device present
-no_psmouse:
-
-#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
-	movl	$0x0000E980, %eax		# IST Support 
-	movl	$0x47534943, %edx		# Request value
-	int	$0x15
-
-	movl	%eax, (96)
-	movl	%ebx, (100)
-	movl	%ecx, (104)
-	movl	%edx, (108)
-#endif
-
-#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
-# Then check for an APM BIOS...
-						# %ds points to the bootsector
-	movw	$0, 0x40			# version = 0 means no APM BIOS
-	movw	$0x05300, %ax			# APM BIOS installation check
-	xorw	%bx, %bx
-	int	$0x15
-	jc	done_apm_bios			# Nope, no APM BIOS
-	
-	cmpw	$0x0504d, %bx			# Check for "PM" signature
-	jne	done_apm_bios			# No signature, no APM BIOS
-
-	andw	$0x02, %cx			# Is 32 bit supported?
-	je	done_apm_bios			# No 32-bit, no (good) APM BIOS
-
-	movw	$0x05304, %ax			# Disconnect first just in case
-	xorw	%bx, %bx
-	int	$0x15				# ignore return code
-	movw	$0x05303, %ax			# 32 bit connect
-	xorl	%ebx, %ebx
-	xorw	%cx, %cx			# paranoia :-)
-	xorw	%dx, %dx			#   ...
-	xorl	%esi, %esi			#   ...
-	xorw	%di, %di			#   ...
-	int	$0x15
-	jc	no_32_apm_bios			# Ack, error. 
-
-	movw	%ax,  (66)			# BIOS code segment
-	movl	%ebx, (68)			# BIOS entry point offset
-	movw	%cx,  (72)			# BIOS 16 bit code segment
-	movw	%dx,  (74)			# BIOS data segment
-	movl	%esi, (78)			# BIOS code segment lengths
-	movw	%di,  (82)			# BIOS data segment length
-# Redo the installation check as the 32 bit connect
-# modifies the flags returned on some BIOSs
-	movw	$0x05300, %ax			# APM BIOS installation check
-	xorw	%bx, %bx
-	xorw	%cx, %cx			# paranoia
-	int	$0x15
-	jc	apm_disconnect			# error -> shouldn't happen
-
-	cmpw	$0x0504d, %bx			# check for "PM" signature
-	jne	apm_disconnect			# no sig -> shouldn't happen
-
-	movw	%ax, (64)			# record the APM BIOS version
-	movw	%cx, (76)			# and flags
-	jmp	done_apm_bios
-
-apm_disconnect:					# Tidy up
-	movw	$0x05304, %ax			# Disconnect
-	xorw	%bx, %bx
-	int	$0x15				# ignore return code
-
-	jmp	done_apm_bios
-
-no_32_apm_bios:
-	andw	$0xfffd, (76)			# remove 32 bit support bit
-done_apm_bios:
-#endif
-
-#include "edd.S"
-
-# Now we want to move to protected mode ...
-	cmpw	$0, %cs:realmode_swtch
-	jz	rmodeswtch_normal
-
-	lcall	*%cs:realmode_swtch
-
-	jmp	rmodeswtch_end
-
-rmodeswtch_normal:
-        pushw	%cs
-	call	default_switch
-
-rmodeswtch_end:
-# Now we move the system to its rightful place ... but we check if we have a
-# big-kernel. In that case we *must* not move it ...
-	testb	$LOADED_HIGH, %cs:loadflags
-	jz	do_move0			# .. then we have a normal low
-						# loaded zImage
-						# .. or else we have a high
-						# loaded bzImage
-	jmp	end_move			# ... and we skip moving
-
-do_move0:
-	movw	$0x100, %ax			# start of destination segment
-	movw	%cs, %bp			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %bp		# aka INITSEG
-	movw	%cs:start_sys_seg, %bx		# start of source segment
-	cld
-do_move:
-	movw	%ax, %es			# destination segment
-	incb	%ah				# instead of add ax,#0x100
-	movw	%bx, %ds			# source segment
-	addw	$0x100, %bx
-	subw	%di, %di
-	subw	%si, %si
-	movw 	$0x800, %cx
-	rep
-	movsw
-	cmpw	%bp, %bx			# assume start_sys_seg > 0x200,
-						# so we will perhaps read one
-						# page more than needed, but
-						# never overwrite INITSEG
-						# because destination is a
-						# minimum one page below source
-	jb	do_move
-
-end_move:
-# then we load the segment descriptors
-	movw	%cs, %ax			# aka SETUPSEG
-	movw	%ax, %ds
-		
-# Check whether we need to be downward compatible with version <=201
-	cmpl	$0, cmd_line_ptr
-	jne	end_move_self		# loader uses version >=202 features
-	cmpb	$0x20, type_of_loader
-	je	end_move_self		# bootsect loader, we know of it
-
-# Boot loader doesnt support boot protocol version 2.02.
-# If we have our code not at 0x90000, we need to move it there now.
-# We also then need to move the params behind it (commandline)
-# Because we would overwrite the code on the current IP, we move
-# it in two steps, jumping high after the first one.
-	movw	%cs, %ax
-	cmpw	$SETUPSEG, %ax
-	je	end_move_self
-
-	cli					# make sure we really have
-						# interrupts disabled !
-						# because after this the stack
-						# should not be used
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	movw	%ss, %dx
-	cmpw	%ax, %dx
-	jb	move_self_1
-
-	addw	$INITSEG, %dx
-	subw	%ax, %dx			# this will go into %ss after
-						# the move
-move_self_1:
-	movw	%ax, %ds
-	movw	$INITSEG, %ax			# real INITSEG
-	movw	%ax, %es
-	movw	%cs:setup_move_size, %cx
-	std					# we have to move up, so we use
-						# direction down because the
-						# areas may overlap
-	movw	%cx, %di
-	decw	%di
-	movw	%di, %si
-	subw	$move_self_here+0x200, %cx
-	rep
-	movsb
-	ljmp	$SETUPSEG, $move_self_here
-
-move_self_here:
-	movw	$move_self_here+0x200, %cx
-	rep
-	movsb
-	movw	$SETUPSEG, %ax
-	movw	%ax, %ds
-	movw	%dx, %ss
-end_move_self:					# now we are at the right place
-
-#
-# Enable A20.  This is at the very best an annoying procedure.
-# A20 code ported from SYSLINUX 1.52-1.63 by H. Peter Anvin.
-# AMD Elan bug fix by Robert Schwebel.
-#
-
-#if defined(CONFIG_X86_ELAN)
-	movb $0x02, %al			# alternate A20 gate
-	outb %al, $0x92			# this works on SC410/SC520
-a20_elan_wait:
-	call a20_test
-	jz a20_elan_wait
-	jmp a20_done
-#endif
-
-
-A20_TEST_LOOPS		=  32		# Iterations per wait
-A20_ENABLE_LOOPS	= 255		# Total loops to try		
-
-
-#ifndef CONFIG_X86_VOYAGER
-a20_try_loop:
-
-	# First, see if we are on a system with no A20 gate.
-a20_none:
-	call	a20_test
-	jnz	a20_done
-
-	# Next, try the BIOS (INT 0x15, AX=0x2401)
-a20_bios:
-	movw	$0x2401, %ax
-	pushfl					# Be paranoid about flags
-	int	$0x15
-	popfl
-
-	call	a20_test
-	jnz	a20_done
-
-	# Try enabling A20 through the keyboard controller
-#endif /* CONFIG_X86_VOYAGER */
-a20_kbc:
-	call	empty_8042
-
-#ifndef CONFIG_X86_VOYAGER
-	call	a20_test			# Just in case the BIOS worked
-	jnz	a20_done			# but had a delayed reaction.
-#endif
-
-	movb	$0xD1, %al			# command write
-	outb	%al, $0x64
-	call	empty_8042
-
-	movb	$0xDF, %al			# A20 on
-	outb	%al, $0x60
-	call	empty_8042
-
-#ifndef CONFIG_X86_VOYAGER
-	# Wait until a20 really *is* enabled; it can take a fair amount of
-	# time on certain systems; Toshiba Tecras are known to have this
-	# problem.
-a20_kbc_wait:
-	xorw	%cx, %cx
-a20_kbc_wait_loop:
-	call	a20_test
-	jnz	a20_done
-	loop	a20_kbc_wait_loop
-
-	# Final attempt: use "configuration port A"
-a20_fast:
-	inb	$0x92, %al			# Configuration Port A
-	orb	$0x02, %al			# "fast A20" version
-	andb	$0xFE, %al			# don't accidentally reset
-	outb	%al, $0x92
-
-	# Wait for configuration port A to take effect
-a20_fast_wait:
-	xorw	%cx, %cx
-a20_fast_wait_loop:
-	call	a20_test
-	jnz	a20_done
-	loop	a20_fast_wait_loop
-
-	# A20 is still not responding.  Try frobbing it again.
-	# 
-	decb	(a20_tries)
-	jnz	a20_try_loop
-	
-	movw	$a20_err_msg, %si
-	call	prtstr
-
-a20_die:
-	hlt
-	jmp	a20_die
-
-a20_tries:
-	.byte	A20_ENABLE_LOOPS
-
-a20_err_msg:
-	.ascii	"linux: fatal error: A20 gate not responding!"
-	.byte	13, 10, 0
-
-	# If we get here, all is good
-a20_done:
-
-#endif /* CONFIG_X86_VOYAGER */
-# set up gdt and idt and 32bit start address
-	lidt	idt_48				# load idt with 0,0
-	xorl	%eax, %eax			# Compute gdt_base
-	movw	%ds, %ax			# (Convert %ds:gdt to a linear ptr)
-	shll	$4, %eax
-	addl	%eax, code32
-	addl	$gdt, %eax
-	movl	%eax, (gdt_48+2)
-	lgdt	gdt_48				# load gdt with whatever is
-						# appropriate
-
-# make sure any possible coprocessor is properly reset..
-	xorw	%ax, %ax
-	outb	%al, $0xf0
-	call	delay
-
-	outb	%al, $0xf1
-	call	delay
-
-# well, that went ok, I hope. Now we mask all interrupts - the rest
-# is done in init_IRQ().
-	movb	$0xFF, %al			# mask all interrupts for now
-	outb	%al, $0xA1
-	call	delay
-	
-	movb	$0xFB, %al			# mask all irq's but irq2 which
-	outb	%al, $0x21			# is cascaded
-
-# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
-# need no steenking BIOS anyway (except for the initial loading :-).
-# The BIOS-routine wants lots of unnecessary data, and it's less
-# "interesting" anyway. This is how REAL programmers do it.
-#
-# Well, now's the time to actually move into protected mode. To make
-# things as simple as possible, we do no register set-up or anything,
-# we let the gnu-compiled 32-bit programs do that. We just jump to
-# absolute address 0x1000 (or the loader supplied one),
-# in 32-bit protected mode.
-#
-# Note that the short jump isn't strictly needed, although there are
-# reasons why it might be a good idea. It won't hurt in any case.
-	movw	$1, %ax				# protected mode (PE) bit
-	lmsw	%ax				# This is it!
-	jmp	flush_instr
-
-flush_instr:
-	xorw	%bx, %bx			# Flag to indicate a boot
-	xorl	%esi, %esi			# Pointer to real-mode code
-	movw	%cs, %si
-	subw	$DELTA_INITSEG, %si
-	shll	$4, %esi			# Convert to 32-bit pointer
-
-# jump to startup_32 in arch/i386/boot/compressed/head.S
-#	
-# NOTE: For high loaded big kernels we need a
-#	jmpi    0x100000,__BOOT_CS
-#
-#	but we yet haven't reloaded the CS register, so the default size 
-#	of the target offset still is 16 bit.
-#	However, using an operand prefix (0x66), the CPU will properly
-#	take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
-#	Manual, Mixing 16-bit and 32-bit code, page 16-6)
-
-	.byte 0x66, 0xea			# prefix + jmpi-opcode
-code32:	.long	startup_32			# will be set to %cs+startup_32
-	.word	__BOOT_CS
-.code32
-startup_32:
-	movl $(__BOOT_DS), %eax
-	movl %eax, %ds
-	movl %eax, %es
-	movl %eax, %fs
-	movl %eax, %gs
-	movl %eax, %ss
-
-	xorl %eax, %eax
-1:	incl %eax				# check that A20 really IS enabled
-	movl %eax, 0x00000000			# loop forever if it isn't
-	cmpl %eax, 0x00100000
-	je 1b
-
-	# Jump to the 32bit entry point
-	jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
-.code16
-
-# Here's a bunch of information about your current kernel..
-kernel_version:	.ascii	UTS_RELEASE
-		.ascii	" ("
-		.ascii	LINUX_COMPILE_BY
-		.ascii	"@"
-		.ascii	LINUX_COMPILE_HOST
-		.ascii	") "
-		.ascii	UTS_VERSION
-		.byte	0
-
-# This is the default real mode switch routine.
-# to be called just before protected mode transition
-default_switch:
-	cli					# no interrupts allowed !
-	movb	$0x80, %al			# disable NMI for bootup
-						# sequence
-	outb	%al, $0x70
-	lret
-
-
-#ifndef CONFIG_X86_VOYAGER
-# This routine tests whether or not A20 is enabled.  If so, it
-# exits with zf = 0.
-#
-# The memory address used, 0x200, is the int $0x80 vector, which
-# should be safe.
-
-A20_TEST_ADDR = 4*0x80
-
-a20_test:
-	pushw	%cx
-	pushw	%ax
-	xorw	%cx, %cx
-	movw	%cx, %fs			# Low memory
-	decw	%cx
-	movw	%cx, %gs			# High memory area
-	movw	$A20_TEST_LOOPS, %cx
-	movw	%fs:(A20_TEST_ADDR), %ax
-	pushw	%ax
-a20_test_wait:
-	incw	%ax
-	movw	%ax, %fs:(A20_TEST_ADDR)
-	call	delay				# Serialize and make delay constant
-	cmpw	%gs:(A20_TEST_ADDR+0x10), %ax
-	loope	a20_test_wait
-
-	popw	%fs:(A20_TEST_ADDR)
-	popw	%ax
-	popw	%cx
-	ret	
-
-#endif /* CONFIG_X86_VOYAGER */
-
-# This routine checks that the keyboard command queue is empty
-# (after emptying the output buffers)
-#
-# Some machines have delusions that the keyboard buffer is always full
-# with no keyboard attached...
-#
-# If there is no keyboard controller, we will usually get 0xff
-# to all the reads.  With each IO taking a microsecond and
-# a timeout of 100,000 iterations, this can take about half a
-# second ("delay" == outb to port 0x80). That should be ok,
-# and should also be plenty of time for a real keyboard controller
-# to empty.
-#
-
-empty_8042:
-	pushl	%ecx
-	movl	$100000, %ecx
-
-empty_8042_loop:
-	decl	%ecx
-	jz	empty_8042_end_loop
-
-	call	delay
-
-	inb	$0x64, %al			# 8042 status port
-	testb	$1, %al				# output buffer?
-	jz	no_output
-
-	call	delay
-	inb	$0x60, %al			# read it
-	jmp	empty_8042_loop
-
-no_output:
-	testb	$2, %al				# is input buffer full?
-	jnz	empty_8042_loop			# yes - loop
-empty_8042_end_loop:
-	popl	%ecx
-	ret
-
-# Read the cmos clock. Return the seconds in al
-gettime:
-	pushw	%cx
-	movb	$0x02, %ah
-	int	$0x1a
-	movb	%dh, %al			# %dh contains the seconds
-	andb	$0x0f, %al
-	movb	%dh, %ah
-	movb	$0x04, %cl
-	shrb	%cl, %ah
-	aad
-	popw	%cx
-	ret
-
-# Delay is needed after doing I/O
-delay:
-	outb	%al,$0x80
-	ret
-
-# Descriptor tables
-#
-# NOTE: The intel manual says gdt should be sixteen bytes aligned for
-# efficiency reasons.  However, there are machines which are known not
-# to boot with misaligned GDTs, so alter this at your peril!  If you alter
-# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two
-# empty GDT entries (one for NULL and one reserved).
-#
-# NOTE:	On some CPUs, the GDT must be 8 byte aligned.  This is
-# true for the Voyager Quad CPU card which will not boot without
-# This directive.  16 byte aligment is recommended by intel.
-#
-	.align 16
-gdt:
-	.fill GDT_ENTRY_BOOT_CS,8,0
-
-	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
-	.word	0				# base address = 0
-	.word	0x9A00				# code read/exec
-	.word	0x00CF				# granularity = 4096, 386
-						#  (+5th nibble of limit)
-
-	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
-	.word	0				# base address = 0
-	.word	0x9200				# data read/write
-	.word	0x00CF				# granularity = 4096, 386
-						#  (+5th nibble of limit)
-gdt_end:
-	.align	4
-	
-	.word	0				# alignment byte
-idt_48:
-	.word	0				# idt limit = 0
-	.word	0, 0				# idt base = 0L
-
-	.word	0				# alignment byte
-gdt_48:
-	.word	gdt_end - gdt - 1		# gdt limit
-	.word	0, 0				# gdt base (filled in later)
-
-# Include video setup & detection code
-
-#include "video.S"
-
-# Setup signature -- must be last
-setup_sig1:	.word	SIG1
-setup_sig2:	.word	SIG2
-
-# After this point, there is some free space which is used by the video mode
-# handling code to store the temporary mode table (not used by the kernel).
-
-modelist:
-
-.text
-endtext:
-.data
-enddata:
-.bss
-endbss:
diff --git a/arch/i386/boot/setup.ld b/arch/i386/boot/setup.ld
new file mode 100644
index 0000000..df9234b
--- /dev/null
+++ b/arch/i386/boot/setup.ld
@@ -0,0 +1,54 @@
+/*
+ * setup.ld
+ *
+ * Linker script for the i386 setup code
+ */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+
+SECTIONS
+{
+	. = 0;
+	.bstext		: { *(.bstext) }
+	.bsdata		: { *(.bsdata) }
+
+	. = 497;
+	.header		: { *(.header) }
+	.inittext	: { *(.inittext) }
+	.initdata	: { *(.initdata) }
+	.text		: { *(.text*) }
+
+	. = ALIGN(16);
+	.rodata		: { *(.rodata*) }
+
+	.videocards	: {
+		video_cards = .;
+		*(.videocards)
+		video_cards_end = .;
+	}
+
+	. = ALIGN(16);
+	.data		: { *(.data*) }
+
+	.signature	: {
+		setup_sig = .;
+		LONG(0x5a5aaa55)
+	}
+
+
+	. = ALIGN(16);
+	.bss		:
+	{
+		__bss_start = .;
+		*(.bss)
+		__bss_end = .;
+	}
+	. = ALIGN(16);
+	_end = .;
+
+	/DISCARD/ : { *(.note*) }
+
+	. = ASSERT(_end <= 0x8000, "Setup too big!");
+	. = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
+}
diff --git a/arch/i386/boot/string.c b/arch/i386/boot/string.c
new file mode 100644
index 0000000..481a220
--- /dev/null
+++ b/arch/i386/boot/string.c
@@ -0,0 +1,52 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/string.c
+ *
+ * Very basic string functions
+ */
+
+#include "boot.h"
+
+int strcmp(const char *str1, const char *str2)
+{
+	const unsigned char *s1 = (const unsigned char *)str1;
+	const unsigned char *s2 = (const unsigned char *)str2;
+	int delta = 0;
+
+	while (*s1 || *s2) {
+		delta = *s2 - *s1;
+		if (delta)
+			return delta;
+		s1++;
+		s2++;
+	}
+	return 0;
+}
+
+size_t strnlen(const char *s, size_t maxlen)
+{
+	const char *es = s;
+	while (*es && maxlen) {
+		es++;
+		maxlen--;
+	}
+
+	return (es - s);
+}
+
+unsigned int atou(const char *s)
+{
+	unsigned int i = 0;
+	while (isdigit(*s))
+		i = i * 10 + (*s++ - '0');
+	return i;
+}
diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c
index 0579841..886f47d8 100644
--- a/arch/i386/boot/tools/build.c
+++ b/arch/i386/boot/tools/build.c
@@ -1,13 +1,12 @@
 /*
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *  Copyright (C) 1997 Martin Mares
+ *  Copyright (C) 2007 H. Peter Anvin
  */
 
 /*
  * This file builds a disk-image from three different files:
  *
- * - bootsect: compatibility mbr which prints an error message if
- *             someone tries to boot the kernel directly.
  * - setup: 8086 machine code, sets up system parm
  * - system: 80386 code for actual system
  *
@@ -21,6 +20,7 @@
  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  * Cross compiling fixes by Gertjan van Wingerde, July 1996
  * Rewritten by Martin Mares, April 1997
+ * Substantially overhauled by H. Peter Anvin, April 2007
  */
 
 #include <stdio.h>
@@ -32,23 +32,25 @@
 #include <sys/sysmacros.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <sys/mman.h>
 #include <asm/boot.h>
 
-typedef unsigned char byte;
-typedef unsigned short word;
-typedef unsigned long u32;
+typedef unsigned char  u8;
+typedef unsigned short u16;
+typedef unsigned long  u32;
 
 #define DEFAULT_MAJOR_ROOT 0
 #define DEFAULT_MINOR_ROOT 0
 
-/* Minimal number of setup sectors (see also bootsect.S) */
-#define SETUP_SECTS 4
+/* Minimal number of setup sectors */
+#define SETUP_SECT_MIN 5
+#define SETUP_SECT_MAX 64
 
-byte buf[1024];
-int fd;
+/* This must be large enough to hold the entire setup */
+u8 buf[SETUP_SECT_MAX*512];
 int is_big_kernel;
 
-void die(const char * str, ...)
+static void die(const char * str, ...)
 {
 	va_list args;
 	va_start(args, str);
@@ -57,15 +59,9 @@
 	exit(1);
 }
 
-void file_open(const char *name)
+static void usage(void)
 {
-	if ((fd = open(name, O_RDONLY, 0)) < 0)
-		die("Unable to open `%s': %m", name);
-}
-
-void usage(void)
-{
-	die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
+	die("Usage: build [-b] setup system [rootdev] [> image]");
 }
 
 int main(int argc, char ** argv)
@@ -73,27 +69,30 @@
 	unsigned int i, sz, setup_sectors;
 	int c;
 	u32 sys_size;
-	byte major_root, minor_root;
+	u8 major_root, minor_root;
 	struct stat sb;
+	FILE *file;
+	int fd;
+	void *kernel;
 
 	if (argc > 2 && !strcmp(argv[1], "-b"))
 	  {
 	    is_big_kernel = 1;
 	    argc--, argv++;
 	  }
-	if ((argc < 4) || (argc > 5))
+	if ((argc < 3) || (argc > 4))
 		usage();
-	if (argc > 4) {
-		if (!strcmp(argv[4], "CURRENT")) {
+	if (argc > 3) {
+		if (!strcmp(argv[3], "CURRENT")) {
 			if (stat("/", &sb)) {
 				perror("/");
 				die("Couldn't stat /");
 			}
 			major_root = major(sb.st_dev);
 			minor_root = minor(sb.st_dev);
-		} else if (strcmp(argv[4], "FLOPPY")) {
-			if (stat(argv[4], &sb)) {
-				perror(argv[4]);
+		} else if (strcmp(argv[3], "FLOPPY")) {
+			if (stat(argv[3], &sb)) {
+				perror(argv[3]);
 				die("Couldn't stat root device.");
 			}
 			major_root = major(sb.st_rdev);
@@ -108,79 +107,62 @@
 	}
 	fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
 
-	file_open(argv[1]);
-	i = read(fd, buf, sizeof(buf));
-	fprintf(stderr,"Boot sector %d bytes.\n",i);
-	if (i != 512)
-		die("Boot block must be exactly 512 bytes");
+	/* Copy the setup code */
+	file = fopen(argv[1], "r");
+	if (!file)
+		die("Unable to open `%s': %m", argv[1]);
+	c = fread(buf, 1, sizeof(buf), file);
+	if (ferror(file))
+		die("read-error on `setup'");
+	if (c < 1024)
+		die("The setup must be at least 1024 bytes");
 	if (buf[510] != 0x55 || buf[511] != 0xaa)
 		die("Boot block hasn't got boot flag (0xAA55)");
+	fclose(file);
+
+	/* Pad unused space with zeros */
+	setup_sectors = (c + 511) / 512;
+	if (setup_sectors < SETUP_SECT_MIN)
+		setup_sectors = SETUP_SECT_MIN;
+	i = setup_sectors*512;
+	memset(buf+c, 0, i-c);
+
+	/* Set the default root device */
 	buf[508] = minor_root;
 	buf[509] = major_root;
-	if (write(1, buf, 512) != 512)
-		die("Write call failed");
-	close (fd);
 
-	file_open(argv[2]);				    /* Copy the setup code */
-	for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
-		if (write(1, buf, c) != c)
-			die("Write call failed");
-	if (c != 0)
-		die("read-error on `setup'");
-	close (fd);
+	fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
 
-	setup_sectors = (i + 511) / 512;	/* Pad unused space with zeros */
-	/* for compatibility with ancient versions of LILO. */
-	if (setup_sectors < SETUP_SECTS)
-		setup_sectors = SETUP_SECTS;
-	fprintf(stderr, "Setup is %d bytes.\n", i);
-	memset(buf, 0, sizeof(buf));
-	while (i < setup_sectors * 512) {
-		c = setup_sectors * 512 - i;
-		if (c > sizeof(buf))
-			c = sizeof(buf);
-		if (write(1, buf, c) != c)
-			die("Write call failed");
-		i += c;
-	}
-
-	file_open(argv[3]);
-	if (fstat (fd, &sb))
-		die("Unable to stat `%s': %m", argv[3]);
+	/* Open and stat the kernel file */
+	fd = open(argv[2], O_RDONLY);
+	if (fd < 0)
+		die("Unable to open `%s': %m", argv[2]);
+	if (fstat(fd, &sb))
+		die("Unable to stat `%s': %m", argv[2]);
 	sz = sb.st_size;
-	fprintf (stderr, "System is %d kB\n", sz/1024);
+	fprintf (stderr, "System is %d kB\n", (sz+1023)/1024);
+	kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
+	if (kernel == MAP_FAILED)
+		die("Unable to mmap '%s': %m", argv[2]);
 	sys_size = (sz + 15) / 16;
 	if (!is_big_kernel && sys_size > DEF_SYSSIZE)
 		die("System is too big. Try using bzImage or modules.");
-	while (sz > 0) {
-		int l, n;
 
-		l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
-		if ((n=read(fd, buf, l)) != l) {
-			if (n < 0)
-				die("Error reading %s: %m", argv[3]);
-			else
-				die("%s: Unexpected EOF", argv[3]);
-		}
-		if (write(1, buf, l) != l)
-			die("Write failed");
-		sz -= l;
-	}
+	/* Patch the setup code with the appropriate size parameters */
+	buf[0x1f1] = setup_sectors-1;
+	buf[0x1f4] = sys_size;
+	buf[0x1f5] = sys_size >> 8;
+	buf[0x1f6] = sys_size >> 16;
+	buf[0x1f7] = sys_size >> 24;
+
+	if (fwrite(buf, 1, i, stdout) != i)
+		die("Writing setup failed");
+
+	/* Copy the kernel code */
+	if (fwrite(kernel, 1, sz, stdout) != sz)
+		die("Writing kernel failed");
 	close(fd);
 
-	if (lseek(1, 497, SEEK_SET) != 497)		    /* Write sizes to the bootsector */
-		die("Output: seek failed");
-	buf[0] = setup_sectors;
-	if (write(1, buf, 1) != 1)
-		die("Write of setup sector count failed");
-	if (lseek(1, 500, SEEK_SET) != 500)
-		die("Output: seek failed");
-	buf[0] = (sys_size & 0xff);
-	buf[1] = ((sys_size >> 8) & 0xff);
-	buf[2] = ((sys_size >> 16) & 0xff);
-	buf[3] = ((sys_size >> 24) & 0xff);
-	if (write(1, buf, 4) != 4)
-		die("Write of image length failed");
-
-	return 0;					    /* Everything is OK */
+	/* Everything is OK */
+	return 0;
 }
diff --git a/arch/i386/boot/tty.c b/arch/i386/boot/tty.c
new file mode 100644
index 0000000..a8db787
--- /dev/null
+++ b/arch/i386/boot/tty.c
@@ -0,0 +1,112 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/tty.c
+ *
+ * Very simple screen I/O
+ * XXX: Probably should add very simple serial I/O?
+ */
+
+#include "boot.h"
+
+/*
+ * These functions are in .inittext so they can be used to signal
+ * error during initialization.
+ */
+
+void __attribute__((section(".inittext"))) putchar(int ch)
+{
+	unsigned char c = ch;
+
+	if (c == '\n')
+		putchar('\r');	/* \n -> \r\n */
+
+	/* int $0x10 is known to have bugs involving touching registers
+	   it shouldn't.  Be extra conservative... */
+	asm volatile("pushal; int $0x10; popal"
+		     : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
+}
+
+void __attribute__((section(".inittext"))) puts(const char *str)
+{
+	int n = 0;
+	while (*str) {
+		putchar(*str++);
+		n++;
+	}
+}
+
+/*
+ * Read the CMOS clock through the BIOS, and return the
+ * seconds in BCD.
+ */
+
+static u8 gettime(void)
+{
+	u16 ax = 0x0200;
+	u16 cx, dx;
+
+	asm("int $0x1a"
+	    : "+a" (ax), "=c" (cx), "=d" (dx)
+	    : : "ebx", "esi", "edi");
+
+	return dx >> 8;
+}
+
+/*
+ * Read from the keyboard
+ */
+int getchar(void)
+{
+	u16 ax = 0;
+	asm("int $0x16" : "+a" (ax));
+
+	return ax & 0xff;
+}
+
+static int kbd_pending(void)
+{
+	u8 pending;
+	asm("int $0x16; setnz %0"
+	    : "=rm" (pending)
+	    : "a" (0x0100));
+	return pending;
+}
+
+void kbd_flush(void)
+{
+	for (;;) {
+		if (!kbd_pending())
+			break;
+		getchar();
+	}
+}
+
+int getchar_timeout(void)
+{
+	int cnt = 30;
+	int t0, t1;
+
+	t0 = gettime();
+
+	while (cnt) {
+		if (kbd_pending())
+			return getchar();
+
+		t1 = gettime();
+		if (t0 != t1) {
+			cnt--;
+			t0 = t1;
+		}
+	}
+
+	return 0;		/* Timeout! */
+}
diff --git a/arch/i386/boot/version.c b/arch/i386/boot/version.c
new file mode 100644
index 0000000..c61462f
--- /dev/null
+++ b/arch/i386/boot/version.c
@@ -0,0 +1,23 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/version.c
+ *
+ * Kernel version string
+ */
+
+#include "boot.h"
+#include <linux/utsrelease.h>
+#include <linux/compile.h>
+
+const char kernel_version[] =
+	UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") "
+	UTS_VERSION;
diff --git a/arch/i386/boot/vesa.h b/arch/i386/boot/vesa.h
new file mode 100644
index 0000000..ff5b73c
--- /dev/null
+++ b/arch/i386/boot/vesa.h
@@ -0,0 +1,79 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1999-2007 H. Peter Anvin - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef BOOT_VESA_H
+#define BOOT_VESA_H
+
+typedef struct {
+	u16 off, seg;
+} far_ptr;
+
+/* VESA General Information table */
+struct vesa_general_info {
+	u32 signature;		/* 0 Magic number = "VESA" */
+	u16 version;		/* 4 */
+	far_ptr vendor_string;	/* 6 */
+	u32 capabilities;	/* 10 */
+	far_ptr video_mode_ptr;	/* 14 */
+	u16 total_memory;	/* 18 */
+
+	u16 oem_software_rev;	/* 20 */
+	far_ptr oem_vendor_name_ptr;	/* 22 */
+	far_ptr oem_product_name_ptr;	/* 26 */
+	far_ptr oem_product_rev_ptr;	/* 30 */
+
+	u8 reserved[222];	/* 34 */
+	u8 oem_data[256];	/* 256 */
+} __attribute__ ((packed));
+
+#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
+#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
+
+struct vesa_mode_info {
+	u16 mode_attr;		/* 0 */
+	u8 win_attr[2];		/* 2 */
+	u16 win_grain;		/* 4 */
+	u16 win_size;		/* 6 */
+	u16 win_seg[2];		/* 8 */
+	far_ptr win_scheme;	/* 12 */
+	u16 logical_scan;	/* 16 */
+
+	u16 h_res;		/* 18 */
+	u16 v_res;		/* 20 */
+	u8 char_width;		/* 22 */
+	u8 char_height;		/* 23 */
+	u8 memory_planes;	/* 24 */
+	u8 bpp;			/* 25 */
+	u8 banks;		/* 26 */
+	u8 memory_layout;	/* 27 */
+	u8 bank_size;		/* 28 */
+	u8 image_planes;	/* 29 */
+	u8 page_function;	/* 30 */
+
+	u8 rmask;		/* 31 */
+	u8 rpos;		/* 32 */
+	u8 gmask;		/* 33 */
+	u8 gpos;		/* 34 */
+	u8 bmask;		/* 35 */
+	u8 bpos;		/* 36 */
+	u8 resv_mask;		/* 37 */
+	u8 resv_pos;		/* 38 */
+	u8 dcm_info;		/* 39 */
+
+	u32 lfb_ptr;		/* 40 Linear frame buffer address */
+	u32 offscreen_ptr;	/* 44 Offscreen memory address */
+	u16 offscreen_size;	/* 48 */
+
+	u8 reserved[206];	/* 50 */
+} __attribute__ ((packed));
+
+#endif				/* LIB_SYS_VESA_H */
diff --git a/arch/i386/boot/video-bios.c b/arch/i386/boot/video-bios.c
new file mode 100644
index 0000000..afea46c
--- /dev/null
+++ b/arch/i386/boot/video-bios.c
@@ -0,0 +1,125 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video-bios.c
+ *
+ * Standard video BIOS modes
+ *
+ * We have two options for this; silent and scanned.
+ */
+
+#include "boot.h"
+#include "video.h"
+
+__videocard video_bios;
+
+/* Set a conventional BIOS mode */
+static int set_bios_mode(u8 mode);
+
+static int bios_set_mode(struct mode_info *mi)
+{
+	return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS);
+}
+
+static int set_bios_mode(u8 mode)
+{
+	u16 ax;
+	u8 new_mode;
+
+	ax = mode;		/* AH=0x00 Set Video Mode */
+	asm volatile(INT10
+		     : "+a" (ax)
+		     : : "ebx", "ecx", "edx", "esi", "edi");
+
+	ax = 0x0f00;		/* Get Current Video Mode */
+	asm volatile(INT10
+		     : "+a" (ax)
+		     : : "ebx", "ecx", "edx", "esi", "edi");
+
+	do_restore = 1;		/* Assume video contents was lost */
+	new_mode = ax & 0x7f;	/* Not all BIOSes are clean with the top bit */
+
+	if (new_mode == mode)
+		return 0;	/* Mode change OK */
+
+	if (new_mode != boot_params.screen_info.orig_video_mode) {
+		/* Mode setting failed, but we didn't end up where we
+		   started.  That's bad.  Try to revert to the original
+		   video mode. */
+		ax = boot_params.screen_info.orig_video_mode;
+		asm volatile(INT10
+			     : "+a" (ax)
+			     : : "ebx", "ecx", "edx", "esi", "edi");
+	}
+	return -1;
+}
+
+static int bios_probe(void)
+{
+	u8 mode;
+	u8 saved_mode = boot_params.screen_info.orig_video_mode;
+	u16 crtc;
+	struct mode_info *mi;
+	int nmodes = 0;
+
+	if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA)
+		return 0;
+
+	set_fs(0);
+	crtc = vga_crtc();
+
+	video_bios.modes = GET_HEAP(struct mode_info, 0);
+
+	for (mode = 0x14; mode <= 0x7f; mode++) {
+		if (heap_free() < sizeof(struct mode_info))
+			break;
+
+		if (mode_defined(VIDEO_FIRST_BIOS+mode))
+			continue;
+
+		if (set_bios_mode(mode))
+			continue;
+
+		/* Try to verify that it's a text mode. */
+
+		/* Attribute Controller: make graphics controller disabled */
+		if (in_idx(0x3c0, 0x10) & 0x01)
+			continue;
+
+		/* Graphics Controller: verify Alpha addressing enabled */
+		if (in_idx(0x3ce, 0x06) & 0x01)
+			continue;
+
+		/* CRTC cursor location low should be zero(?) */
+		if (in_idx(crtc, 0x0f))
+			continue;
+
+		mi = GET_HEAP(struct mode_info, 1);
+		mi->mode = VIDEO_FIRST_BIOS+mode;
+		mi->x = rdfs16(0x44a);
+		mi->y = rdfs8(0x484)+1;
+		nmodes++;
+	}
+
+	set_bios_mode(saved_mode);
+
+	return nmodes;
+}
+
+__videocard video_bios =
+{
+	.card_name	= "BIOS (scanned)",
+	.probe		= bios_probe,
+	.set_mode	= bios_set_mode,
+	.unsafe		= 1,
+	.xmode_first	= VIDEO_FIRST_BIOS,
+	.xmode_n	= 0x80,
+};
diff --git a/arch/i386/boot/video-vesa.c b/arch/i386/boot/video-vesa.c
new file mode 100644
index 0000000..e6aa9eb
--- /dev/null
+++ b/arch/i386/boot/video-vesa.c
@@ -0,0 +1,284 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video-vesa.c
+ *
+ * VESA text modes
+ */
+
+#include "boot.h"
+#include "video.h"
+#include "vesa.h"
+
+/* VESA information */
+static struct vesa_general_info vginfo;
+static struct vesa_mode_info vminfo;
+
+__videocard video_vesa;
+
+static void vesa_store_mode_params_graphics(void);
+
+static int vesa_probe(void)
+{
+#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID)
+	u16 ax;
+	u16 mode;
+	addr_t mode_ptr;
+	struct mode_info *mi;
+	int nmodes = 0;
+
+	video_vesa.modes = GET_HEAP(struct mode_info, 0);
+
+	vginfo.signature = VBE2_MAGIC;
+
+	/* Optimistically assume a VESA BIOS is register-clean... */
+	ax = 0x4f00;
+	asm("int $0x10" : "+a" (ax), "=m" (vginfo) : "D" (&vginfo));
+
+	if (ax != 0x004f ||
+	    vginfo.signature != VESA_MAGIC ||
+	    vginfo.version < 0x0102)
+		return 0;	/* Not present */
+#endif /* CONFIG_VIDEO_VESA || CONFIG_FIRMWARE_EDID */
+#ifdef CONFIG_VIDEO_VESA
+	set_fs(vginfo.video_mode_ptr.seg);
+	mode_ptr = vginfo.video_mode_ptr.off;
+
+	while ((mode = rdfs16(mode_ptr)) != 0xffff) {
+		mode_ptr += 2;
+
+		if (heap_free() < sizeof(struct mode_info))
+			break;	/* Heap full, can't save mode info */
+
+		if (mode & ~0x1ff)
+			continue;
+
+		memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
+
+		ax = 0x4f01;
+		asm("int $0x10"
+		    : "+a" (ax), "=m" (vminfo)
+		    : "c" (mode), "D" (&vminfo));
+
+		if (ax != 0x004f)
+			continue;
+
+		if ((vminfo.mode_attr & 0x15) == 0x05) {
+			/* Text Mode, TTY BIOS supported,
+			   supported by hardware */
+			mi = GET_HEAP(struct mode_info, 1);
+			mi->mode = mode + VIDEO_FIRST_VESA;
+			mi->x    = vminfo.h_res;
+			mi->y    = vminfo.v_res;
+			nmodes++;
+		} else if ((vminfo.mode_attr & 0x99) == 0x99) {
+#ifdef CONFIG_FB
+			/* Graphics mode, color, linear frame buffer
+			   supported -- register the mode but hide from
+			   the menu.  Only do this if framebuffer is
+			   configured, however, otherwise the user will
+			   be left without a screen. */
+			mi = GET_HEAP(struct mode_info, 1);
+			mi->mode = mode + VIDEO_FIRST_VESA;
+			mi->x = mi->y = 0;
+			nmodes++;
+#endif
+		}
+	}
+
+	return nmodes;
+#else
+	return 0;
+#endif /* CONFIG_VIDEO_VESA */
+}
+
+static int vesa_set_mode(struct mode_info *mode)
+{
+	u16 ax;
+	int is_graphic;
+	u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
+
+	memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
+
+	ax = 0x4f01;
+	asm("int $0x10"
+	    : "+a" (ax), "=m" (vminfo)
+	    : "c" (vesa_mode), "D" (&vminfo));
+
+	if (ax != 0x004f)
+		return -1;
+
+	if ((vminfo.mode_attr & 0x15) == 0x05) {
+		/* It's a supported text mode */
+		is_graphic = 0;
+	} else if ((vminfo.mode_attr & 0x99) == 0x99) {
+		/* It's a graphics mode with linear frame buffer */
+		is_graphic = 1;
+		vesa_mode |= 0x4000; /* Request linear frame buffer */
+	} else {
+		return -1;	/* Invalid mode */
+	}
+
+
+	ax = 0x4f02;
+	asm volatile("int $0x10"
+		     : "+a" (ax)
+		     : "b" (vesa_mode), "D" (0));
+
+	if (ax != 0x004f)
+		return -1;
+
+	graphic_mode = is_graphic;
+	if (!is_graphic) {
+		/* Text mode */
+		force_x = mode->x;
+		force_y = mode->y;
+		do_restore = 1;
+	} else {
+		/* Graphics mode */
+		vesa_store_mode_params_graphics();
+	}
+
+	return 0;
+}
+
+
+/* Switch DAC to 8-bit mode */
+static void vesa_dac_set_8bits(void)
+{
+	u8 dac_size = 6;
+
+	/* If possible, switch the DAC to 8-bit mode */
+	if (vginfo.capabilities & 1) {
+		u16 ax, bx;
+
+		ax = 0x4f08;
+		bx = 0x0800;
+		asm volatile(INT10
+			     : "+a" (ax), "+b" (bx)
+			     : : "ecx", "edx", "esi", "edi");
+
+		if (ax == 0x004f)
+			dac_size = bx >> 8;
+	}
+
+	/* Set the color sizes to the DAC size, and offsets to 0 */
+	boot_params.screen_info.red_size = dac_size;
+	boot_params.screen_info.green_size = dac_size;
+	boot_params.screen_info.blue_size = dac_size;
+	boot_params.screen_info.rsvd_size = dac_size;
+
+	boot_params.screen_info.red_pos = 0;
+	boot_params.screen_info.green_pos = 0;
+	boot_params.screen_info.blue_pos = 0;
+	boot_params.screen_info.rsvd_pos = 0;
+}
+
+/* Save the VESA protected mode info */
+static void vesa_store_pm_info(void)
+{
+	u16 ax, bx, di, es;
+
+	ax = 0x4f0a;
+	bx = di = 0;
+	asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
+	    : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
+	    : : "ecx", "esi");
+
+	if (ax != 0x004f)
+		return;
+
+	boot_params.screen_info.vesapm_seg = es;
+	boot_params.screen_info.vesapm_off = di;
+}
+
+/*
+ * Save video mode parameters for graphics mode
+ */
+static void vesa_store_mode_params_graphics(void)
+{
+	/* Tell the kernel we're in VESA graphics mode */
+	boot_params.screen_info.orig_video_isVGA = 0x23;
+
+	/* Mode parameters */
+	boot_params.screen_info.vesa_attributes = vminfo.mode_attr;
+	boot_params.screen_info.lfb_linelength = vminfo.logical_scan;
+	boot_params.screen_info.lfb_width = vminfo.h_res;
+	boot_params.screen_info.lfb_height = vminfo.v_res;
+	boot_params.screen_info.lfb_depth = vminfo.bpp;
+	boot_params.screen_info.pages = vminfo.image_planes;
+	boot_params.screen_info.lfb_base = vminfo.lfb_ptr;
+	memcpy(&boot_params.screen_info.red_size,
+	       &vminfo.rmask, 8);
+
+	/* General parameters */
+	boot_params.screen_info.lfb_size = vginfo.total_memory;
+
+	if (vminfo.bpp <= 8)
+		vesa_dac_set_8bits();
+
+	vesa_store_pm_info();
+}
+
+/*
+ * Save EDID information for the kernel; this is invoked, separately,
+ * after mode-setting.
+ */
+void vesa_store_edid(void)
+{
+#ifdef CONFIG_FIRMWARE_EDID
+	u16 ax, bx, cx, dx, di;
+
+	/* Apparently used as a nonsense token... */
+	memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);
+
+	if (vginfo.version < 0x0200)
+		return;		/* EDID requires VBE 2.0+ */
+
+	ax = 0x4f15;		/* VBE DDC */
+	bx = 0x0000;		/* Report DDC capabilities */
+	cx = 0;			/* Controller 0 */
+	di = 0;			/* ES:DI must be 0 by spec */
+
+	/* Note: The VBE DDC spec is different from the main VESA spec;
+	   we genuinely have to assume all registers are destroyed here. */
+
+	asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
+	    : "+a" (ax), "+b" (bx)
+	    :  "c" (cx), "D" (di)
+	    : "esi");
+
+	if (ax != 0x004f)
+		return;		/* No EDID */
+
+	/* BH = time in seconds to transfer EDD information */
+	/* BL = DDC level supported */
+
+	ax = 0x4f15;		/* VBE DDC */
+	bx = 0x0001;		/* Read EDID */
+	cx = 0;			/* Controller 0 */
+	dx = 0;			/* EDID block number */
+	di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
+	asm(INT10
+	    : "+a" (ax), "+b" (bx), "+d" (dx)
+	    : "c" (cx), "D" (di)
+	    : "esi");
+#endif /* CONFIG_FIRMWARE_EDID */
+}
+
+__videocard video_vesa =
+{
+	.card_name	= "VESA",
+	.probe		= vesa_probe,
+	.set_mode	= vesa_set_mode,
+	.xmode_first	= VIDEO_FIRST_VESA,
+	.xmode_n	= 0x200,
+};
diff --git a/arch/i386/boot/video-vga.c b/arch/i386/boot/video-vga.c
new file mode 100644
index 0000000..700d09a
--- /dev/null
+++ b/arch/i386/boot/video-vga.c
@@ -0,0 +1,260 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video-vga.c
+ *
+ * Common all-VGA modes
+ */
+
+#include "boot.h"
+#include "video.h"
+
+static struct mode_info vga_modes[] = {
+	{ VIDEO_80x25,  80, 25 },
+	{ VIDEO_8POINT, 80, 50 },
+	{ VIDEO_80x43,  80, 43 },
+	{ VIDEO_80x28,  80, 28 },
+	{ VIDEO_80x30,  80, 30 },
+	{ VIDEO_80x34,  80, 34 },
+	{ VIDEO_80x60,  80, 60 },
+};
+
+static struct mode_info ega_modes[] = {
+	{ VIDEO_80x25,  80, 25 },
+	{ VIDEO_8POINT, 80, 43 },
+};
+
+static struct mode_info cga_modes[] = {
+	{ VIDEO_80x25,  80, 25 },
+};
+
+__videocard video_vga;
+
+/* Set basic 80x25 mode */
+static u8 vga_set_basic_mode(void)
+{
+	u16 ax;
+	u8 rows;
+	u8 mode;
+
+#ifdef CONFIG_VIDEO_400_HACK
+	if (adapter >= ADAPTER_VGA) {
+		asm(INT10
+		    : : "a" (0x1202), "b" (0x0030)
+		    : "ecx", "edx", "esi", "edi");
+	}
+#endif
+
+	ax = 0x0f00;
+	asm(INT10
+	    : "+a" (ax)
+	    : : "ebx", "ecx", "edx", "esi", "edi");
+
+	mode = (u8)ax;
+
+	set_fs(0);
+	rows = rdfs8(0x484);	/* rows minus one */
+
+#ifndef CONFIG_VIDEO_400_HACK
+	if ((ax == 0x5003 || ax == 0x5007) &&
+	    (rows == 0 || rows == 24))
+		return mode;
+#endif
+
+	if (mode != 3 && mode != 7)
+		mode = 3;
+
+	/* Set the mode */
+	asm volatile(INT10
+		     : : "a" (mode)
+		     : "ebx", "ecx", "edx", "esi", "edi");
+	do_restore = 1;
+	return mode;
+}
+
+static void vga_set_8font(void)
+{
+	/* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
+
+	/* Set 8x8 font */
+	asm volatile(INT10 : : "a" (0x1112), "b" (0));
+
+	/* Use alternate print screen */
+	asm volatile(INT10 : : "a" (0x1200), "b" (0x20));
+
+	/* Turn off cursor emulation */
+	asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
+
+	/* Cursor is scan lines 6-7 */
+	asm volatile(INT10 : : "a" (0x0100), "c" (0x0607));
+}
+
+static void vga_set_14font(void)
+{
+	/* Set 9x14 font - 80x28 on VGA */
+
+	/* Set 9x14 font */
+	asm volatile(INT10 : : "a" (0x1111), "b" (0));
+
+	/* Turn off cursor emulation */
+	asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
+
+	/* Cursor is scan lines 11-12 */
+	asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c));
+}
+
+static void vga_set_80x43(void)
+{
+	/* Set 80x43 mode on VGA (not EGA) */
+
+	/* Set 350 scans */
+	asm volatile(INT10 : : "a" (0x1201), "b" (0x30));
+
+	/* Reset video mode */
+	asm volatile(INT10 : : "a" (0x0003));
+
+	vga_set_8font();
+}
+
+/* I/O address of the VGA CRTC */
+u16 vga_crtc(void)
+{
+	return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
+}
+
+static void vga_set_480_scanlines(int end)
+{
+	u16 crtc;
+	u8  csel;
+
+	crtc = vga_crtc();
+
+	out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */
+	out_idx(0x0b, crtc, 0x06); /* Vertical total */
+	out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
+	out_idx(0xea, crtc, 0x10); /* Vertical sync start */
+	out_idx(end, crtc, 0x12); /* Vertical display end */
+	out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
+	out_idx(0x04, crtc, 0x16); /* Vertical blank end */
+	csel = inb(0x3cc);
+	csel &= 0x0d;
+	csel |= 0xe2;
+	outb(csel, 0x3cc);
+}
+
+static void vga_set_80x30(void)
+{
+	vga_set_480_scanlines(0xdf);
+}
+
+static void vga_set_80x34(void)
+{
+	vga_set_14font();
+	vga_set_480_scanlines(0xdb);
+}
+
+static void vga_set_80x60(void)
+{
+	vga_set_8font();
+	vga_set_480_scanlines(0xdf);
+}
+
+static int vga_set_mode(struct mode_info *mode)
+{
+	/* Set the basic mode */
+	vga_set_basic_mode();
+
+	/* Override a possibly broken BIOS */
+	force_x = mode->x;
+	force_y = mode->y;
+
+	switch (mode->mode) {
+	case VIDEO_80x25:
+		break;
+	case VIDEO_8POINT:
+		vga_set_8font();
+		break;
+	case VIDEO_80x43:
+		vga_set_80x43();
+		break;
+	case VIDEO_80x28:
+		vga_set_14font();
+		break;
+	case VIDEO_80x30:
+		vga_set_80x30();
+		break;
+	case VIDEO_80x34:
+		vga_set_80x34();
+		break;
+	case VIDEO_80x60:
+		vga_set_80x60();
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * Note: this probe includes basic information required by all
+ * systems.  It should be executed first, by making sure
+ * video-vga.c is listed first in the Makefile.
+ */
+static int vga_probe(void)
+{
+	static const char *card_name[] = {
+		"CGA/MDA/HGC", "EGA", "VGA"
+	};
+	static struct mode_info *mode_lists[] = {
+		cga_modes,
+		ega_modes,
+		vga_modes,
+	};
+	static int mode_count[] = {
+		sizeof(cga_modes)/sizeof(struct mode_info),
+		sizeof(ega_modes)/sizeof(struct mode_info),
+		sizeof(vga_modes)/sizeof(struct mode_info),
+	};
+	u8 vga_flag;
+
+	asm(INT10
+	    : "=b" (boot_params.screen_info.orig_video_ega_bx)
+	    : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
+	    : "ecx", "edx", "esi", "edi");
+
+	/* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
+	if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
+		/* EGA/VGA */
+		asm(INT10
+		    : "=a" (vga_flag)
+		    : "a" (0x1a00)
+		    : "ebx", "ecx", "edx", "esi", "edi");
+
+		if (vga_flag == 0x1a) {
+			adapter = ADAPTER_VGA;
+			boot_params.screen_info.orig_video_isVGA = 1;
+		} else {
+			adapter = ADAPTER_EGA;
+		}
+	} else {
+		adapter = ADAPTER_CGA;
+	}
+
+	video_vga.modes = mode_lists[adapter];
+	video_vga.card_name = card_name[adapter];
+	return mode_count[adapter];
+}
+
+__videocard video_vga =
+{
+	.card_name	= "VGA",
+	.probe		= vga_probe,
+	.set_mode	= vga_set_mode,
+};
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
deleted file mode 100644
index 8143c95..0000000
--- a/arch/i386/boot/video.S
+++ /dev/null
@@ -1,2043 +0,0 @@
-/*	video.S
- *
- *	Display adapter & video mode setup, version 2.13 (14-May-99)
- *
- *	Copyright (C) 1995 -- 1998 Martin Mares <mj@ucw.cz>
- *	Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
- *
- *	Rewritten to use GNU 'as' by Chris Noe <stiker@northlink.com> May 1999
- *
- *	For further information, look at Documentation/svga.txt.
- *
- */
-
-/* Enable autodetection of SVGA adapters and modes. */
-#undef CONFIG_VIDEO_SVGA
-
-/* Enable autodetection of VESA modes */
-#define CONFIG_VIDEO_VESA
-
-/* Enable compacting of mode table */
-#define CONFIG_VIDEO_COMPACT
-
-/* Retain screen contents when switching modes */
-#define CONFIG_VIDEO_RETAIN
-
-/* Enable local mode list */
-#undef CONFIG_VIDEO_LOCAL
-
-/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
-#undef CONFIG_VIDEO_400_HACK
-
-/* Hack that lets you force specific BIOS mode ID and specific dimensions */
-#undef CONFIG_VIDEO_GFX_HACK
-#define VIDEO_GFX_BIOS_AX 0x4f02	/* 800x600 on ThinkPad */
-#define VIDEO_GFX_BIOS_BX 0x0102
-#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425	/* 100x37 */
-
-/* This code uses an extended set of video mode numbers. These include:
- * Aliases for standard modes
- *	NORMAL_VGA (-1)
- *	EXTENDED_VGA (-2)
- *	ASK_VGA (-3)
- * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
- * of compatibility when extending the table. These are between 0x00 and 0xff.
- */
-#define VIDEO_FIRST_MENU 0x0000
-
-/* Standard BIOS video modes (BIOS number + 0x0100) */
-#define VIDEO_FIRST_BIOS 0x0100
-
-/* VESA BIOS video modes (VESA number + 0x0200) */
-#define VIDEO_FIRST_VESA 0x0200
-
-/* Video7 special modes (BIOS number + 0x0900) */
-#define VIDEO_FIRST_V7 0x0900
-
-/* Special video modes */
-#define VIDEO_FIRST_SPECIAL 0x0f00
-#define VIDEO_80x25 0x0f00
-#define VIDEO_8POINT 0x0f01
-#define VIDEO_80x43 0x0f02
-#define VIDEO_80x28 0x0f03
-#define VIDEO_CURRENT_MODE 0x0f04
-#define VIDEO_80x30 0x0f05
-#define VIDEO_80x34 0x0f06
-#define VIDEO_80x60 0x0f07
-#define VIDEO_GFX_HACK 0x0f08
-#define VIDEO_LAST_SPECIAL 0x0f09
-
-/* Video modes given by resolution */
-#define VIDEO_FIRST_RESOLUTION 0x1000
-
-/* The "recalculate timings" flag */
-#define VIDEO_RECALC 0x8000
-
-/* Positions of various video parameters passed to the kernel */
-/* (see also include/linux/tty.h) */
-#define PARAM_CURSOR_POS	0x00
-#define PARAM_VIDEO_PAGE	0x04
-#define PARAM_VIDEO_MODE	0x06
-#define PARAM_VIDEO_COLS	0x07
-#define PARAM_VIDEO_EGA_BX	0x0a
-#define PARAM_VIDEO_LINES	0x0e
-#define PARAM_HAVE_VGA		0x0f
-#define PARAM_FONT_POINTS	0x10
-
-#define PARAM_LFB_WIDTH		0x12
-#define PARAM_LFB_HEIGHT	0x14
-#define PARAM_LFB_DEPTH		0x16
-#define PARAM_LFB_BASE		0x18
-#define PARAM_LFB_SIZE		0x1c
-#define PARAM_LFB_LINELENGTH	0x24
-#define PARAM_LFB_COLORS	0x26
-#define PARAM_VESAPM_SEG	0x2e
-#define PARAM_VESAPM_OFF	0x30
-#define PARAM_LFB_PAGES		0x32
-#define PARAM_VESA_ATTRIB	0x34
-#define PARAM_CAPABILITIES	0x36
-
-/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
-#ifdef CONFIG_VIDEO_RETAIN
-#define DO_STORE call store_screen
-#else
-#define DO_STORE
-#endif /* CONFIG_VIDEO_RETAIN */
-
-# This is the main entry point called by setup.S
-# %ds *must* be pointing to the bootsector
-video:	pushw	%ds		# We use different segments
-	pushw	%ds		# FS contains original DS
-	popw	%fs
-	pushw	%cs		# DS is equal to CS
-	popw	%ds
-	pushw	%cs		# ES is equal to CS
-	popw	%es
-	xorw	%ax, %ax
-	movw	%ax, %gs	# GS is zero
-	cld
-	call	basic_detect	# Basic adapter type testing (EGA/VGA/MDA/CGA)
-#ifdef CONFIG_VIDEO_SELECT
-	movw	%fs:(0x01fa), %ax		# User selected video mode
-	cmpw	$ASK_VGA, %ax			# Bring up the menu
-	jz	vid2
-
-	call	mode_set			# Set the mode
-	jc	vid1
-
-	leaw	badmdt, %si			# Invalid mode ID
-	call	prtstr
-vid2:	call	mode_menu
-vid1:
-#ifdef CONFIG_VIDEO_RETAIN
-	call	restore_screen			# Restore screen contents
-#endif /* CONFIG_VIDEO_RETAIN */
-	call	store_edid
-#endif /* CONFIG_VIDEO_SELECT */
-	call	mode_params			# Store mode parameters
-	popw	%ds				# Restore original DS
-	ret
-
-# Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel.
-basic_detect:
-	movb	$0, %fs:(PARAM_HAVE_VGA)
-	movb	$0x12, %ah	# Check EGA/VGA
-	movb	$0x10, %bl
-	int	$0x10
-	movw	%bx, %fs:(PARAM_VIDEO_EGA_BX)	# Identifies EGA to the kernel
-	cmpb	$0x10, %bl			# No, it's a CGA/MDA/HGA card.
-	je	basret
-
-	incb	adapter
-	movw	$0x1a00, %ax			# Check EGA or VGA?
-	int	$0x10
-	cmpb	$0x1a, %al			# 1a means VGA...
-	jne	basret				# anything else is EGA.
-	
-	incb	%fs:(PARAM_HAVE_VGA)		# We've detected a VGA
-	incb	adapter
-basret:	ret
-
-# Store the video mode parameters for later usage by the kernel.
-# This is done by asking the BIOS except for the rows/columns
-# parameters in the default 80x25 mode -- these are set directly,
-# because some very obscure BIOSes supply insane values.
-mode_params:
-#ifdef CONFIG_VIDEO_SELECT
-	cmpb	$0, graphic_mode
-	jnz	mopar_gr
-#endif
-	movb	$0x03, %ah			# Read cursor position
-	xorb	%bh, %bh
-	int	$0x10
-	movw	%dx, %fs:(PARAM_CURSOR_POS)
-	movb	$0x0f, %ah			# Read page/mode/width
-	int	$0x10
-	movw	%bx, %fs:(PARAM_VIDEO_PAGE)
-	movw	%ax, %fs:(PARAM_VIDEO_MODE)	# Video mode and screen width
-	cmpb	$0x7, %al			# MDA/HGA => segment differs
-	jnz	mopar0
-
-	movw	$0xb000, video_segment
-mopar0: movw	%gs:(0x485), %ax		# Font size
-	movw	%ax, %fs:(PARAM_FONT_POINTS)	# (valid only on EGA/VGA)
-	movw	force_size, %ax			# Forced size?
-	orw	%ax, %ax
-	jz	mopar1
-
-	movb	%ah, %fs:(PARAM_VIDEO_COLS)
-	movb	%al, %fs:(PARAM_VIDEO_LINES)
-	ret
-
-mopar1:	movb	$25, %al
-	cmpb	$0, adapter			# If we are on CGA/MDA/HGA, the
-	jz	mopar2				# screen must have 25 lines.
-
-	movb	%gs:(0x484), %al		# On EGA/VGA, use the EGA+ BIOS
-	incb	%al				# location of max lines.
-mopar2: movb	%al, %fs:(PARAM_VIDEO_LINES)
-	ret
-
-#ifdef CONFIG_VIDEO_SELECT
-# Fetching of VESA frame buffer parameters
-mopar_gr:
-	leaw	modelist+1024, %di
-	movb	$0x23, %fs:(PARAM_HAVE_VGA)
-	movw	16(%di), %ax
-	movw	%ax, %fs:(PARAM_LFB_LINELENGTH)
-	movw	18(%di), %ax
-	movw	%ax, %fs:(PARAM_LFB_WIDTH)
-	movw	20(%di), %ax
-	movw	%ax, %fs:(PARAM_LFB_HEIGHT)
-	movb	25(%di), %al
-	movb	$0, %ah
-	movw	%ax, %fs:(PARAM_LFB_DEPTH)
-	movb	29(%di), %al	
-	movb	$0, %ah
-	movw	%ax, %fs:(PARAM_LFB_PAGES)
-	movl	40(%di), %eax
-	movl	%eax, %fs:(PARAM_LFB_BASE)
-	movl	31(%di), %eax
-	movl	%eax, %fs:(PARAM_LFB_COLORS)
-	movl	35(%di), %eax
-	movl	%eax, %fs:(PARAM_LFB_COLORS+4)
-	movw	0(%di), %ax
-	movw	%ax, %fs:(PARAM_VESA_ATTRIB)
-
-# get video mem size
-	leaw	modelist+1024, %di
-	movw	$0x4f00, %ax
-	int	$0x10
-	xorl	%eax, %eax
-	movw	18(%di), %ax
-	movl	%eax, %fs:(PARAM_LFB_SIZE)
-
-# store mode capabilities
-	movl 10(%di), %eax
-	movl %eax, %fs:(PARAM_CAPABILITIES)
-
-# switching the DAC to 8-bit is for <= 8 bpp only
-	movw	%fs:(PARAM_LFB_DEPTH), %ax
-	cmpw	$8, %ax
-	jg	dac_done
-
-# get DAC switching capability
-	xorl	%eax, %eax
-	movb	10(%di), %al
-	testb	$1, %al
-	jz	dac_set
-
-# attempt to switch DAC to 8-bit
-	movw	$0x4f08, %ax
-	movw	$0x0800, %bx
-	int	$0x10
-	cmpw	$0x004f, %ax
-	jne     dac_set
-	movb    %bh, dac_size		# store actual DAC size
-
-dac_set:
-# set color size to DAC size
-	movb	dac_size, %al
-	movb	%al, %fs:(PARAM_LFB_COLORS+0)
-	movb	%al, %fs:(PARAM_LFB_COLORS+2)
-	movb	%al, %fs:(PARAM_LFB_COLORS+4)
-	movb	%al, %fs:(PARAM_LFB_COLORS+6)
-
-# set color offsets to 0
-	movb	$0, %fs:(PARAM_LFB_COLORS+1)
-	movb	$0, %fs:(PARAM_LFB_COLORS+3)
-	movb	$0, %fs:(PARAM_LFB_COLORS+5)
-	movb	$0, %fs:(PARAM_LFB_COLORS+7)
-
-dac_done:
-# get protected mode interface informations
-	movw	$0x4f0a, %ax
-	xorw	%bx, %bx
-	xorw	%di, %di
-	int	$0x10
-	cmp	$0x004f, %ax
-	jnz	no_pm
-
-	movw	%es, %fs:(PARAM_VESAPM_SEG)
-	movw	%di, %fs:(PARAM_VESAPM_OFF)
-no_pm:	ret
-
-# The video mode menu
-mode_menu:
-	leaw	keymsg, %si			# "Return/Space/Timeout" message
-	call	prtstr
-	call	flush
-nokey:	call	getkt
-
-	cmpb	$0x0d, %al			# ENTER ?
-	je	listm				# yes - manual mode selection
-
-	cmpb	$0x20, %al			# SPACE ?
-	je	defmd1				# no - repeat
-
-	call 	beep
-	jmp	nokey
-
-defmd1:	ret					# No mode chosen? Default 80x25
-
-listm:	call	mode_table			# List mode table
-listm0:	leaw	name_bann, %si			# Print adapter name
-	call	prtstr
-	movw	card_name, %si
-	orw	%si, %si
-	jnz	an2
-
-	movb	adapter, %al
-	leaw	old_name, %si
-	orb	%al, %al
-	jz	an1
-
-	leaw	ega_name, %si
-	decb	%al
-	jz	an1
-
-	leaw	vga_name, %si
-	jmp	an1
-
-an2:	call	prtstr
-	leaw	svga_name, %si
-an1:	call	prtstr
-	leaw	listhdr, %si			# Table header
-	call	prtstr
-	movb	$0x30, %dl			# DL holds mode number
-	leaw	modelist, %si
-lm1:	cmpw	$ASK_VGA, (%si)			# End?
-	jz	lm2
-
-	movb	%dl, %al			# Menu selection number
-	call	prtchr
-	call	prtsp2
-	lodsw
-	call	prthw				# Mode ID
-	call	prtsp2
-	movb	0x1(%si), %al
-	call	prtdec				# Rows
-	movb	$0x78, %al			# the letter 'x'
-	call	prtchr
-	lodsw
-	call	prtdec				# Columns
-	movb	$0x0d, %al			# New line
-	call	prtchr
-	movb	$0x0a, %al
-	call	prtchr
-	incb	%dl				# Next character
-	cmpb	$0x3a, %dl
-	jnz	lm1
-
-	movb	$0x61, %dl
-	jmp	lm1
-
-lm2:	leaw	prompt, %si			# Mode prompt
-	call	prtstr
-	leaw	edit_buf, %di			# Editor buffer
-lm3:	call	getkey
-	cmpb	$0x0d, %al			# Enter?
-	jz	lment
-
-	cmpb	$0x08, %al			# Backspace?
-	jz	lmbs
-
-	cmpb	$0x20, %al			# Printable?
-	jc	lm3
-
-	cmpw	$edit_buf+4, %di		# Enough space?
-	jz	lm3
-
-	stosb
-	call	prtchr
-	jmp	lm3
-
-lmbs:	cmpw	$edit_buf, %di			# Backspace
-	jz	lm3
-
-	decw	%di
-	movb	$0x08, %al
-	call	prtchr
-	call	prtspc
-	movb	$0x08, %al
-	call	prtchr
-	jmp	lm3
-	
-lment:	movb	$0, (%di)
-	leaw	crlft, %si
-	call	prtstr
-	leaw	edit_buf, %si
-	cmpb	$0, (%si)			# Empty string = default mode
-	jz	lmdef
-
-	cmpb	$0, 1(%si)			# One character = menu selection
-	jz	mnusel
-
-	cmpw	$0x6373, (%si)			# "scan" => mode scanning
-	jnz	lmhx
-
-	cmpw	$0x6e61, 2(%si)
-	jz	lmscan
-
-lmhx:	xorw	%bx, %bx			# Else => mode ID in hex
-lmhex:	lodsb
-	orb	%al, %al
-	jz	lmuse1
-
-	subb	$0x30, %al
-	jc	lmbad
-
-	cmpb	$10, %al
-	jc	lmhx1
-
-	subb	$7, %al
-	andb	$0xdf, %al
-	cmpb	$10, %al
-	jc	lmbad
-
-	cmpb	$16, %al
-	jnc	lmbad
-
-lmhx1:	shlw	$4, %bx
-	orb	%al, %bl
-	jmp	lmhex
-
-lmuse1:	movw	%bx, %ax
-	jmp	lmuse
-
-mnusel:	lodsb					# Menu selection
-	xorb	%ah, %ah
-	subb	$0x30, %al
-	jc	lmbad
-
-	cmpb	$10, %al
-	jc	lmuse
-	
-	cmpb	$0x61-0x30, %al
-	jc	lmbad
-	
-	subb	$0x61-0x30-10, %al
-	cmpb	$36, %al
-	jnc	lmbad
-
-lmuse:	call	mode_set
-	jc	lmdef
-
-lmbad:	leaw	unknt, %si
-	call	prtstr
-	jmp	lm2
-lmscan:	cmpb	$0, adapter			# Scanning only on EGA/VGA
-	jz	lmbad
-
-	movw	$0, mt_end			# Scanning of modes is
-	movb	$1, scanning			# done as new autodetection.
-	call	mode_table
-	jmp	listm0
-lmdef:	ret
-
-# Additional parts of mode_set... (relative jumps, you know)
-setv7:						# Video7 extended modes
-	DO_STORE
-	subb	$VIDEO_FIRST_V7>>8, %bh
-	movw	$0x6f05, %ax
-	int	$0x10
-	stc
-	ret
-
-_setrec:	jmp	setrec			# Ugly...
-_set_80x25:	jmp	set_80x25
-
-# Aliases for backward compatibility.
-setalias:
-	movw	$VIDEO_80x25, %ax
-	incw	%bx
-	jz	mode_set
-
-	movb	$VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al
-	incw	%bx
-	jnz	setbad				# Fall-through!
-
-# Setting of user mode (AX=mode ID) => CF=success
-mode_set:
-	movw	%ax, %fs:(0x01fa)		# Store mode for use in acpi_wakeup.S
-	movw	%ax, %bx
-	cmpb	$0xff, %ah
-	jz	setalias
-
-	testb	$VIDEO_RECALC>>8, %ah
-	jnz	_setrec
-
-	cmpb	$VIDEO_FIRST_RESOLUTION>>8, %ah
-	jnc	setres
-	
-	cmpb	$VIDEO_FIRST_SPECIAL>>8, %ah
-	jz	setspc
-	
-	cmpb	$VIDEO_FIRST_V7>>8, %ah
-	jz	setv7
-	
-	cmpb	$VIDEO_FIRST_VESA>>8, %ah
-	jnc	check_vesa
-	
-	orb	%ah, %ah
-	jz	setmenu
-	
-	decb	%ah
-	jz	setbios
-
-setbad:	clc
-	movb	$0, do_restore			# The screen needn't be restored
-	ret
-
-setvesa:
-	DO_STORE
-	subb	$VIDEO_FIRST_VESA>>8, %bh
-	movw	$0x4f02, %ax			# VESA BIOS mode set call
-	int	$0x10
-	cmpw	$0x004f, %ax			# AL=4f if implemented
-	jnz	setbad				# AH=0 if OK
-
-	stc
-	ret
-
-setbios:
-	DO_STORE
-	int	$0x10				# Standard BIOS mode set call
-	pushw	%bx
-	movb	$0x0f, %ah			# Check if really set
-	int	$0x10
-	popw	%bx
-	cmpb	%bl, %al
-	jnz	setbad
-	
-	stc
-	ret
-
-setspc:	xorb	%bh, %bh			# Set special mode
-	cmpb	$VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl
-	jnc	setbad
-	
-	addw	%bx, %bx
-	jmp	*spec_inits(%bx)
-
-setmenu:
-	orb	%al, %al			# 80x25 is an exception
-	jz	_set_80x25
-	
-	pushw	%bx				# Set mode chosen from menu
-	call	mode_table			# Build the mode table
-	popw	%ax
-	shlw	$2, %ax
-	addw	%ax, %si
-	cmpw	%di, %si
-	jnc	setbad
-	
-	movw	(%si), %ax			# Fetch mode ID
-_m_s:	jmp	mode_set
-
-setres:	pushw	%bx				# Set mode chosen by resolution
-	call	mode_table
-	popw	%bx
-	xchgb	%bl, %bh
-setr1:	lodsw
-	cmpw	$ASK_VGA, %ax			# End of the list?
-	jz	setbad
-	
-	lodsw
-	cmpw	%bx, %ax
-	jnz	setr1
-	
-	movw	-4(%si), %ax			# Fetch mode ID
-	jmp	_m_s
-
-check_vesa:
-#ifdef CONFIG_FIRMWARE_EDID
-	leaw	modelist+1024, %di
-	movw	$0x4f00, %ax
-	int	$0x10
-	cmpw	$0x004f, %ax
-	jnz	setbad
-
-	movw	4(%di), %ax
-	movw	%ax, vbe_version
-#endif
-	leaw	modelist+1024, %di
-	subb	$VIDEO_FIRST_VESA>>8, %bh
-	movw	%bx, %cx			# Get mode information structure
-	movw	$0x4f01, %ax
-	int	$0x10
-	addb	$VIDEO_FIRST_VESA>>8, %bh
-	cmpw	$0x004f, %ax
-	jnz	setbad
-
-	movb	(%di), %al			# Check capabilities.
-	andb	$0x19, %al
-	cmpb	$0x09, %al
-	jz	setvesa				# This is a text mode
-
-	movb	(%di), %al			# Check capabilities.
-	andb	$0x99, %al
-	cmpb	$0x99, %al
-	jnz	_setbad				# Doh! No linear frame buffer.
-
-	subb	$VIDEO_FIRST_VESA>>8, %bh
-	orw	$0x4000, %bx			# Use linear frame buffer
-	movw	$0x4f02, %ax			# VESA BIOS mode set call
-	int	$0x10
-	cmpw	$0x004f, %ax			# AL=4f if implemented
-	jnz	_setbad				# AH=0 if OK
-
-	movb	$1, graphic_mode		# flag graphic mode
-	movb	$0, do_restore			# no screen restore
-	stc
-	ret
-
-_setbad:	jmp	setbad          	# Ugly...
-
-# Recalculate vertical display end registers -- this fixes various
-# inconsistencies of extended modes on many adapters. Called when
-# the VIDEO_RECALC flag is set in the mode ID.
-
-setrec:	subb	$VIDEO_RECALC>>8, %ah		# Set the base mode
-	call	mode_set
-	jnc	rct3
-
-	movw	%gs:(0x485), %ax		# Font size in pixels
-	movb	%gs:(0x484), %bl		# Number of rows
-	incb	%bl
-	mulb	%bl				# Number of visible
-	decw	%ax				# scan lines - 1
-	movw	$0x3d4, %dx
-	movw	%ax, %bx
-	movb	$0x12, %al			# Lower 8 bits
-	movb	%bl, %ah
-	outw	%ax, %dx
-	movb	$0x07, %al		# Bits 8 and 9 in the overflow register
-	call	inidx
-	xchgb	%al, %ah
-	andb	$0xbd, %ah
-	shrb	%bh
-	jnc	rct1
-	orb	$0x02, %ah
-rct1:	shrb	%bh
-	jnc	rct2
-	orb	$0x40, %ah
-rct2:	movb	$0x07, %al
-	outw	%ax, %dx
-	stc
-rct3:	ret
-
-# Table of routines for setting of the special modes.
-spec_inits:
-	.word	set_80x25
-	.word	set_8pixel
-	.word	set_80x43
-	.word	set_80x28
-	.word	set_current
-	.word	set_80x30
-	.word	set_80x34
-	.word	set_80x60
-	.word	set_gfx
-
-# Set the 80x25 mode. If already set, do nothing.
-set_80x25:
-	movw	$0x5019, force_size		# Override possibly broken BIOS
-use_80x25:
-#ifdef CONFIG_VIDEO_400_HACK
-	movw	$0x1202, %ax			# Force 400 scan lines
-	movb	$0x30, %bl
-	int	$0x10
-#else
-	movb	$0x0f, %ah			# Get current mode ID
-	int	$0x10
-	cmpw	$0x5007, %ax	# Mode 7 (80x25 mono) is the only one available
-	jz	st80		# on CGA/MDA/HGA and is also available on EGAM
-
-	cmpw	$0x5003, %ax	# Unknown mode, force 80x25 color
-	jnz	force3
-
-st80:	cmpb	$0, adapter	# CGA/MDA/HGA => mode 3/7 is always 80x25
-	jz	set80
-
-	movb	%gs:(0x0484), %al	# This is EGA+ -- beware of 80x50 etc.
-	orb	%al, %al		# Some buggy BIOS'es set 0 rows
-	jz	set80
-	
-	cmpb	$24, %al		# It's hopefully correct
-	jz	set80
-#endif /* CONFIG_VIDEO_400_HACK */
-force3:	DO_STORE
-	movw	$0x0003, %ax			# Forced set
-	int	$0x10
-set80:	stc
-	ret
-
-# Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.
-set_8pixel:
-	DO_STORE
-	call	use_80x25			# The base is 80x25
-set_8pt:
-	movw	$0x1112, %ax			# Use 8x8 font
-	xorb	%bl, %bl
-	int	$0x10
-	movw	$0x1200, %ax			# Use alternate print screen
-	movb	$0x20, %bl
-	int	$0x10
-	movw	$0x1201, %ax			# Turn off cursor emulation
-	movb	$0x34, %bl
-	int	$0x10
-	movb	$0x01, %ah			# Define cursor scan lines 6-7
-	movw	$0x0607, %cx
-	int	$0x10
-set_current:
-	stc
-	ret
-
-# Set the 80x28 mode. This mode works on all VGA's, because it's a standard
-# 80x25 mode with 14-point fonts instead of 16-point.
-set_80x28:
-	DO_STORE
-	call	use_80x25			# The base is 80x25
-set14:	movw	$0x1111, %ax			# Use 9x14 font
-	xorb	%bl, %bl
-	int	$0x10
-	movb	$0x01, %ah			# Define cursor scan lines 11-12
-	movw	$0x0b0c, %cx
-	int	$0x10
-	stc
-	ret
-
-# Set the 80x43 mode. This mode is works on all VGA's.
-# It's a 350-scanline mode with 8-pixel font.
-set_80x43:
-	DO_STORE
-	movw	$0x1201, %ax			# Set 350 scans
-	movb	$0x30, %bl
-	int	$0x10
-	movw	$0x0003, %ax			# Reset video mode
-	int	$0x10
-	jmp	set_8pt				# Use 8-pixel font
-
-# Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font.
-set_80x30:
-	call	use_80x25			# Start with real 80x25
-	DO_STORE
-	movw	$0x3cc, %dx			# Get CRTC port
-	inb	%dx, %al
-	movb	$0xd4, %dl
-	rorb	%al				# Mono or color?
-	jc	set48a
-
-	movb	$0xb4, %dl
-set48a:	movw	$0x0c11, %ax		# Vertical sync end (also unlocks CR0-7)
- 	call	outidx
-	movw	$0x0b06, %ax			# Vertical total
- 	call	outidx
-	movw	$0x3e07, %ax			# (Vertical) overflow
- 	call	outidx
-	movw	$0xea10, %ax			# Vertical sync start
- 	call	outidx
-	movw	$0xdf12, %ax			# Vertical display end
-	call	outidx
-	movw	$0xe715, %ax			# Vertical blank start
- 	call	outidx
-	movw	$0x0416, %ax			# Vertical blank end
- 	call	outidx
-	pushw	%dx
-	movb	$0xcc, %dl			# Misc output register (read)
- 	inb	%dx, %al
- 	movb	$0xc2, %dl			# (write)
- 	andb	$0x0d, %al	# Preserve clock select bits and color bit
- 	orb	$0xe2, %al			# Set correct sync polarity
- 	outb	%al, %dx
-	popw	%dx
-	movw	$0x501e, force_size
-	stc					# That's all.
-	ret
-
-# Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font.
-set_80x34:
-	call	set_80x30			# Set 480 scans
-	call	set14				# And 14-pt font
-	movw	$0xdb12, %ax			# VGA vertical display end
-	movw	$0x5022, force_size
-setvde:	call	outidx
-	stc
-	ret
-
-# Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font.
-set_80x60:
-	call	set_80x30			# Set 480 scans
-	call	set_8pt				# And 8-pt font
-	movw	$0xdf12, %ax			# VGA vertical display end
-	movw	$0x503c, force_size
-	jmp	setvde
-
-# Special hack for ThinkPad graphics
-set_gfx:
-#ifdef CONFIG_VIDEO_GFX_HACK
-	movw	$VIDEO_GFX_BIOS_AX, %ax
-	movw	$VIDEO_GFX_BIOS_BX, %bx
-	int	$0x10
-	movw	$VIDEO_GFX_DUMMY_RESOLUTION, force_size
-	stc
-#endif
-	ret
-
-#ifdef CONFIG_VIDEO_RETAIN
-
-# Store screen contents to temporary buffer.
-store_screen:
-	cmpb	$0, do_restore			# Already stored?
-	jnz	stsr
-
-	testb	$CAN_USE_HEAP, loadflags	# Have we space for storing?
-	jz	stsr
-	
-	pushw	%ax
-	pushw	%bx
-	pushw	force_size			# Don't force specific size
-	movw	$0, force_size
-	call	mode_params			# Obtain params of current mode
-	popw	force_size
-	movb	%fs:(PARAM_VIDEO_LINES), %ah
-	movb	%fs:(PARAM_VIDEO_COLS), %al
-	movw	%ax, %bx			# BX=dimensions
-	mulb	%ah
-	movw	%ax, %cx			# CX=number of characters
-	addw	%ax, %ax			# Calculate image size
-	addw	$modelist+1024+4, %ax
-	cmpw	heap_end_ptr, %ax
-	jnc	sts1				# Unfortunately, out of memory
-
-	movw	%fs:(PARAM_CURSOR_POS), %ax	# Store mode params
-	leaw	modelist+1024, %di
-	stosw
-	movw	%bx, %ax
-	stosw
-	pushw	%ds				# Store the screen
-	movw	video_segment, %ds
-	xorw	%si, %si
-	rep
-	movsw
-	popw	%ds
-	incb	do_restore			# Screen will be restored later
-sts1:	popw	%bx
-	popw	%ax
-stsr:	ret
-
-# Restore screen contents from temporary buffer.
-restore_screen:
-	cmpb	$0, do_restore			# Has the screen been stored?
-	jz	res1
-
-	call	mode_params			# Get parameters of current mode
-	movb	%fs:(PARAM_VIDEO_LINES), %cl
-	movb	%fs:(PARAM_VIDEO_COLS), %ch
-	leaw	modelist+1024, %si		# Screen buffer
-	lodsw					# Set cursor position
-	movw	%ax, %dx
-	cmpb	%cl, %dh
-	jc	res2
-	
-	movb	%cl, %dh
-	decb	%dh
-res2:	cmpb	%ch, %dl
-	jc	res3
-	
-	movb	%ch, %dl
-	decb	%dl
-res3:	movb	$0x02, %ah
-	movb	$0x00, %bh
-	int	$0x10
-	lodsw					# Display size
-	movb	%ah, %dl			# DL=number of lines
-	movb	$0, %ah				# BX=phys. length of orig. line
-	movw	%ax, %bx
-	cmpb	%cl, %dl			# Too many?
-	jc	res4
-
-	pushw	%ax
-	movb	%dl, %al
-	subb	%cl, %al
-	mulb	%bl
-	addw	%ax, %si
-	addw	%ax, %si
-	popw	%ax
-	movb	%cl, %dl
-res4:	cmpb	%ch, %al			# Too wide?
-	jc	res5
-	
-	movb	%ch, %al			# AX=width of src. line
-res5:	movb	$0, %cl
-	xchgb	%ch, %cl
-	movw	%cx, %bp			# BP=width of dest. line
-	pushw	%es
-	movw	video_segment, %es
-	xorw	%di, %di			# Move the data
-	addw	%bx, %bx			# Convert BX and BP to _bytes_
-	addw	%bp, %bp
-res6:	pushw	%si
-	pushw	%di
-	movw	%ax, %cx
-	rep
-	movsw
-	popw	%di
-	popw	%si
-	addw	%bp, %di
-	addw	%bx, %si
-	decb	%dl
-	jnz	res6
-	
-	popw	%es				# Done
-res1:	ret
-#endif /* CONFIG_VIDEO_RETAIN */
-
-# Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
-outidx:	outb	%al, %dx
-	pushw	%ax
-	movb	%ah, %al
-	incw	%dx
-	outb	%al, %dx
-	decw	%dx
-	popw	%ax
-	ret
-
-# Build the table of video modes (stored after the setup.S code at the
-# `modelist' label. Each video mode record looks like:
-#	.word	MODE-ID		(our special mode ID (see above))
-#	.byte	rows		(number of rows)
-#	.byte	columns		(number of columns)
-# Returns address of the end of the table in DI, the end is marked
-# with a ASK_VGA ID.
-mode_table:
-	movw	mt_end, %di			# Already filled?
-	orw	%di, %di
-	jnz	mtab1x
-	
-	leaw	modelist, %di			# Store standard modes:
-	movl	$VIDEO_80x25 + 0x50190000, %eax	# The 80x25 mode (ALL)
-	stosl
-	movb	adapter, %al			# CGA/MDA/HGA -- no more modes
-	orb	%al, %al
-	jz	mtabe
-	
-	decb	%al
-	jnz	mtabv
-	
-	movl	$VIDEO_8POINT + 0x502b0000, %eax	# The 80x43 EGA mode
-	stosl
-	jmp	mtabe
-
-mtab1x:	jmp	mtab1
-
-mtabv:	leaw	vga_modes, %si			# All modes for std VGA
-	movw	$vga_modes_end-vga_modes, %cx
-	rep	# I'm unable to use movsw as I don't know how to store a half
-	movsb	# of the expression above to cx without using explicit shr.
-
-	cmpb	$0, scanning			# Mode scan requested?
-	jz	mscan1
-	
-	call	mode_scan
-mscan1:
-
-#ifdef CONFIG_VIDEO_LOCAL
-	call	local_modes
-#endif /* CONFIG_VIDEO_LOCAL */
-
-#ifdef CONFIG_VIDEO_VESA
-	call	vesa_modes			# Detect VESA VGA modes
-#endif /* CONFIG_VIDEO_VESA */
-
-#ifdef CONFIG_VIDEO_SVGA
-	cmpb	$0, scanning			# Bypass when scanning
-	jnz	mscan2
-	
-	call	svga_modes			# Detect SVGA cards & modes
-mscan2:
-#endif /* CONFIG_VIDEO_SVGA */
-
-mtabe:
-
-#ifdef CONFIG_VIDEO_COMPACT
-	leaw	modelist, %si
-	movw	%di, %dx
-	movw	%si, %di
-cmt1:	cmpw	%dx, %si			# Scan all modes
-	jz	cmt2
-
-	leaw	modelist, %bx			# Find in previous entries
-	movw	2(%si), %cx
-cmt3:	cmpw	%bx, %si
-	jz	cmt4
-
-	cmpw	2(%bx), %cx			# Found => don't copy this entry
-	jz	cmt5
-
-	addw	$4, %bx
-	jmp	cmt3
-
-cmt4:	movsl					# Copy entry
-	jmp	cmt1
-
-cmt5:	addw	$4, %si				# Skip entry
-	jmp	cmt1
-
-cmt2:
-#endif	/* CONFIG_VIDEO_COMPACT */
-
-	movw	$ASK_VGA, (%di)			# End marker
-	movw	%di, mt_end
-mtab1:	leaw	modelist, %si			# SI=mode list, DI=list end
-ret0:	ret
-
-# Modes usable on all standard VGAs
-vga_modes:
-	.word	VIDEO_8POINT
-	.word	0x5032				# 80x50
-	.word	VIDEO_80x43
-	.word	0x502b				# 80x43
-	.word	VIDEO_80x28
-	.word	0x501c				# 80x28
-	.word	VIDEO_80x30
-	.word	0x501e				# 80x30
-	.word	VIDEO_80x34
-	.word	0x5022				# 80x34
-	.word	VIDEO_80x60
-	.word	0x503c				# 80x60
-#ifdef CONFIG_VIDEO_GFX_HACK
-	.word	VIDEO_GFX_HACK
-	.word	VIDEO_GFX_DUMMY_RESOLUTION
-#endif
-
-vga_modes_end:
-# Detect VESA modes.
-
-#ifdef CONFIG_VIDEO_VESA
-vesa_modes:
-	cmpb	$2, adapter			# VGA only
-	jnz	ret0
-
-	movw	%di, %bp			# BP=original mode table end
-	addw	$0x200, %di			# Buffer space
-	movw	$0x4f00, %ax			# VESA Get card info call
-	int	$0x10
-	movw	%bp, %di
-	cmpw	$0x004f, %ax			# Successful?
-	jnz	ret0
-	
-	cmpw	$0x4556, 0x200(%di)
-	jnz	ret0
-	
-	cmpw	$0x4153, 0x202(%di)
-	jnz	ret0
-	
-	movw	$vesa_name, card_name		# Set name to "VESA VGA"
-	pushw	%gs
-	lgsw	0x20e(%di), %si			# GS:SI=mode list
-	movw	$128, %cx			# Iteration limit
-vesa1:
-# gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst.
-# XXX:	lodsw	%gs:(%si), %ax			# Get next mode in the list
-	gs; lodsw
-	cmpw	$0xffff, %ax			# End of the table?
-	jz	vesar
-	
-	cmpw	$0x0080, %ax			# Check validity of mode ID
-	jc	vesa2
-	
-	orb	%ah, %ah		# Valid IDs: 0x0000-0x007f/0x0100-0x07ff
-	jz	vesan			# Certain BIOSes report 0x80-0xff!
-
-	cmpw	$0x0800, %ax
-	jnc	vesae
-
-vesa2:	pushw	%cx
-	movw	%ax, %cx			# Get mode information structure
-	movw	$0x4f01, %ax
-	int	$0x10
-	movw	%cx, %bx			# BX=mode number
-	addb	$VIDEO_FIRST_VESA>>8, %bh
-	popw	%cx
-	cmpw	$0x004f, %ax
-	jnz	vesan			# Don't report errors (buggy BIOSES)
-
-	movb	(%di), %al			# Check capabilities. We require
-	andb	$0x19, %al			# a color text mode.
-	cmpb	$0x09, %al
-	jnz	vesan
-	
-	cmpw	$0xb800, 8(%di)		# Standard video memory address required
-	jnz	vesan
-
-	testb	$2, (%di)			# Mode characteristics supplied?
-	movw	%bx, (%di)			# Store mode number
-	jz	vesa3
-	
-	xorw	%dx, %dx
-	movw	0x12(%di), %bx			# Width
-	orb	%bh, %bh
-	jnz	vesan
-	
-	movb	%bl, 0x3(%di)
-	movw	0x14(%di), %ax			# Height
-	orb	%ah, %ah
-	jnz	vesan
-	
-	movb	%al, 2(%di)
-	mulb	%bl
-	cmpw	$8193, %ax		# Small enough for Linux console driver?
-	jnc	vesan
-
-	jmp	vesaok
-
-vesa3:	subw	$0x8108, %bx	# This mode has no detailed info specified,
-	jc	vesan		# so it must be a standard VESA mode.
-
-	cmpw	$5, %bx
-	jnc	vesan
-
-	movw	vesa_text_mode_table(%bx), %ax
-	movw	%ax, 2(%di)
-vesaok:	addw	$4, %di				# The mode is valid. Store it.
-vesan:	loop	vesa1			# Next mode. Limit exceeded => error
-vesae:	leaw	vesaer, %si
-	call	prtstr
-	movw	%bp, %di			# Discard already found modes.
-vesar:	popw	%gs
-	ret
-
-# Dimensions of standard VESA text modes
-vesa_text_mode_table:
-	.byte	60, 80				# 0108
-	.byte	25, 132				# 0109
-	.byte	43, 132				# 010A
-	.byte	50, 132				# 010B
-	.byte	60, 132				# 010C
-#endif	/* CONFIG_VIDEO_VESA */
-
-# Scan for video modes. A bit dirty, but should work.
-mode_scan:
-	movw	$0x0100, %cx			# Start with mode 0
-scm1:	movb	$0, %ah				# Test the mode
-	movb	%cl, %al
-	int	$0x10
-	movb	$0x0f, %ah
-	int	$0x10
-	cmpb	%cl, %al
-	jnz	scm2				# Mode not set
-
-	movw	$0x3c0, %dx			# Test if it's a text mode
-	movb	$0x10, %al			# Mode bits
-	call	inidx
-	andb	$0x03, %al
-	jnz	scm2
-	
-	movb	$0xce, %dl			# Another set of mode bits
-	movb	$0x06, %al
-	call	inidx
-	shrb	%al
-	jc	scm2
-	
-	movb	$0xd4, %dl			# Cursor location
-	movb	$0x0f, %al
-	call	inidx
-	orb	%al, %al
-	jnz	scm2
-	
-	movw	%cx, %ax			# Ok, store the mode
-	stosw
-	movb	%gs:(0x484), %al		# Number of rows
-	incb	%al
-	stosb
-	movw	%gs:(0x44a), %ax		# Number of columns
-	stosb
-scm2:	incb	%cl
-	jns	scm1
-	
-	movw	$0x0003, %ax			# Return back to mode 3
-	int	$0x10
-	ret
-
-tstidx:	outw	%ax, %dx			# OUT DX,AX and inidx
-inidx:	outb	%al, %dx			# Read from indexed VGA register
-	incw	%dx			# AL=index, DX=index reg port -> AL=data
-	inb	%dx, %al
-	decw	%dx
-	ret
-
-# Try to detect type of SVGA card and supply (usually approximate) video
-# mode table for it.
-
-#ifdef CONFIG_VIDEO_SVGA
-svga_modes:
-	leaw	svga_table, %si			# Test all known SVGA adapters
-dosvga:	lodsw
-	movw	%ax, %bp			# Default mode table
-	orw	%ax, %ax
-	jz	didsv1
-
-	lodsw					# Pointer to test routine
-	pushw	%si
-	pushw	%di
-	pushw	%es
-	movw	$0xc000, %bx
-	movw	%bx, %es
-	call	*%ax				# Call test routine
-	popw	%es
-	popw	%di
-	popw	%si
-	orw	%bp, %bp
-	jz	dosvga
-	
-	movw	%bp, %si			# Found, copy the modes
-	movb	svga_prefix, %ah
-cpsvga:	lodsb
-	orb	%al, %al
-	jz	didsv
-	
-	stosw
-	movsw
-	jmp	cpsvga
-
-didsv:	movw	%si, card_name			# Store pointer to card name
-didsv1:	ret
-
-# Table of all known SVGA cards. For each card, we store a pointer to
-# a table of video modes supported by the card and a pointer to a routine
-# used for testing of presence of the card. The video mode table is always
-# followed by the name of the card or the chipset.
-svga_table:
-	.word	ati_md, ati_test
-	.word	oak_md, oak_test
-	.word	paradise_md, paradise_test
-	.word	realtek_md, realtek_test
-	.word	s3_md, s3_test
-	.word	chips_md, chips_test
-	.word	video7_md, video7_test
-	.word	cirrus5_md, cirrus5_test
-	.word	cirrus6_md, cirrus6_test
-	.word	cirrus1_md, cirrus1_test
-	.word	ahead_md, ahead_test
-	.word	everex_md, everex_test
-	.word	genoa_md, genoa_test
-	.word	trident_md, trident_test
-	.word	tseng_md, tseng_test
-	.word	0
-
-# Test routines and mode tables:
-
-# S3 - The test algorithm was taken from the SuperProbe package
-# for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org
-s3_test:
-	movw	$0x0f35, %cx	# we store some constants in cl/ch
-	movw	$0x03d4, %dx
-	movb	$0x38, %al
-	call	inidx
-	movb	%al, %bh	# store current CRT-register 0x38
-	movw	$0x0038, %ax
-	call	outidx		# disable writing to special regs
-	movb	%cl, %al	# check whether we can write special reg 0x35
-	call	inidx
-	movb	%al, %bl	# save the current value of CRT reg 0x35
-	andb	$0xf0, %al	# clear bits 0-3
-	movb	%al, %ah
-	movb	%cl, %al	# and write it to CRT reg 0x35
-	call	outidx
-	call	inidx		# now read it back
-	andb	%ch, %al	# clear the upper 4 bits
-	jz	s3_2		# the first test failed. But we have a
-
-	movb	%bl, %ah	# second chance
-	movb	%cl, %al
-	call	outidx
-	jmp	s3_1		# do the other tests
-
-s3_2:	movw	%cx, %ax	# load ah with 0xf and al with 0x35
-	orb	%bl, %ah	# set the upper 4 bits of ah with the orig value
-	call	outidx		# write ...
-	call	inidx		# ... and reread 
-	andb	%cl, %al	# turn off the upper 4 bits
-	pushw	%ax
-	movb	%bl, %ah	# restore old value in register 0x35
-	movb	%cl, %al
-	call	outidx
-	popw	%ax
-	cmpb	%ch, %al	# setting lower 4 bits was successful => bad
-	je	no_s3		# writing is allowed => this is not an S3
-
-s3_1:	movw	$0x4838, %ax	# allow writing to special regs by putting
-	call	outidx		# magic number into CRT-register 0x38
-	movb	%cl, %al	# check whether we can write special reg 0x35
-	call	inidx
-	movb	%al, %bl
-	andb	$0xf0, %al
-	movb	%al, %ah
-	movb	%cl, %al
-	call	outidx
-	call	inidx
-	andb	%ch, %al
-	jnz	no_s3		# no, we can't write => no S3
-
-	movw	%cx, %ax
-	orb	%bl, %ah
-	call	outidx
-	call	inidx
-	andb	%ch, %al
-	pushw	%ax
-	movb	%bl, %ah	# restore old value in register 0x35
-	movb	%cl, %al
-	call	outidx
-	popw	%ax
-	cmpb	%ch, %al
-	jne	no_s31		# writing not possible => no S3
-	movb	$0x30, %al
-	call	inidx		# now get the S3 id ...
-	leaw	idS3, %di
-	movw	$0x10, %cx
-	repne
-	scasb
-	je	no_s31
-
-	movb	%bh, %ah
-	movb	$0x38, %al
-	jmp	s3rest
-
-no_s3:	movb	$0x35, %al	# restore CRT register 0x35
-	movb	%bl, %ah
-	call	outidx
-no_s31:	xorw	%bp, %bp	# Detection failed
-s3rest:	movb	%bh, %ah
-	movb	$0x38, %al	# restore old value of CRT register 0x38
-	jmp	outidx
-
-idS3:	.byte	0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
-	.byte	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
-
-s3_md:	.byte	0x54, 0x2b, 0x84
-	.byte	0x55, 0x19, 0x84
-	.byte	0
-	.ascii	"S3"
-	.byte	0
-
-# ATI cards.
-ati_test:
-	leaw 	idati, %si
-	movw	$0x31, %di
-	movw	$0x09, %cx
-	repe
-	cmpsb
-	je	atiok
-
-	xorw	%bp, %bp
-atiok:	ret
-
-idati:	.ascii	"761295520"
-
-ati_md:	.byte	0x23, 0x19, 0x84
-	.byte	0x33, 0x2c, 0x84
-	.byte	0x22, 0x1e, 0x64
-	.byte	0x21, 0x19, 0x64
-	.byte	0x58, 0x21, 0x50
-	.byte	0x5b, 0x1e, 0x50
-	.byte	0
-	.ascii	"ATI"
-	.byte	0
-
-# AHEAD
-ahead_test:
-	movw	$0x200f, %ax
-	movw	$0x3ce, %dx
-	outw	%ax, %dx
-	incw	%dx
-	inb	%dx, %al
-	cmpb	$0x20, %al
-	je	isahed
-
-	cmpb	$0x21, %al
-	je	isahed
-	
-	xorw	%bp, %bp
-isahed:	ret
-
-ahead_md:
-	.byte	0x22, 0x2c, 0x84
-	.byte	0x23, 0x19, 0x84
-	.byte	0x24, 0x1c, 0x84
-	.byte	0x2f, 0x32, 0xa0
-	.byte	0x32, 0x22, 0x50
-	.byte	0x34, 0x42, 0x50
-	.byte	0
-	.ascii	"Ahead"
-	.byte	0
-
-# Chips & Tech.
-chips_test:
-	movw	$0x3c3, %dx
-	inb	%dx, %al
-	orb	$0x10, %al
-	outb	%al, %dx
-	movw	$0x104, %dx
-	inb	%dx, %al
-	movb	%al, %bl
-	movw	$0x3c3, %dx
-	inb	%dx, %al
-	andb	$0xef, %al
-	outb	%al, %dx
-	cmpb	$0xa5, %bl
-	je	cantok
-	
-	xorw	%bp, %bp
-cantok:	ret
-
-chips_md:
-	.byte	0x60, 0x19, 0x84
-	.byte	0x61, 0x32, 0x84
-	.byte	0
-	.ascii	"Chips & Technologies"
-	.byte	0
-
-# Cirrus Logic 5X0
-cirrus1_test:
-	movw	$0x3d4, %dx
-	movb	$0x0c, %al
-	outb	%al, %dx
-	incw	%dx
-	inb	%dx, %al
-	movb	%al, %bl
-	xorb	%al, %al
-	outb	%al, %dx
-	decw	%dx
-	movb	$0x1f, %al
-	outb	%al, %dx
-	incw	%dx
-	inb	%dx, %al
-	movb	%al, %bh
-	xorb	%ah, %ah
-	shlb	$4, %al
-	movw	%ax, %cx
-	movb	%bh, %al
-	shrb	$4, %al
-	addw	%ax, %cx
-	shlw	$8, %cx
-	addw	$6, %cx
-	movw	%cx, %ax
-	movw	$0x3c4, %dx
-	outw	%ax, %dx
-	incw	%dx
-	inb	%dx, %al
-	andb	%al, %al
-	jnz	nocirr
-	
-	movb	%bh, %al
-	outb	%al, %dx
-	inb	%dx, %al
-	cmpb	$0x01, %al
-	je	iscirr
-
-nocirr:	xorw	%bp, %bp
-iscirr: movw	$0x3d4, %dx
-	movb	%bl, %al
-	xorb	%ah, %ah
-	shlw	$8, %ax
-	addw	$0x0c, %ax
-	outw	%ax, %dx
-	ret
-
-cirrus1_md:
-	.byte	0x1f, 0x19, 0x84
-	.byte	0x20, 0x2c, 0x84
-	.byte	0x22, 0x1e, 0x84
-	.byte	0x31, 0x25, 0x64
-	.byte	0
-	.ascii	"Cirrus Logic 5X0"
-	.byte	0
-
-# Cirrus Logic 54XX
-cirrus5_test:
-	movw	$0x3c4, %dx
-	movb	$6, %al
-	call	inidx
-	movb	%al, %bl			# BL=backup
-	movw	$6, %ax
-	call	tstidx
-	cmpb	$0x0f, %al
-	jne	c5fail
-	
-	movw	$0x1206, %ax
-	call	tstidx
-	cmpb	$0x12, %al
-	jne	c5fail
-	
-	movb	$0x1e, %al
-	call	inidx
-	movb	%al, %bh
-	movb	%bh, %ah
-	andb	$0xc0, %ah
-	movb	$0x1e, %al
-	call	tstidx
-	andb	$0x3f, %al
-	jne	c5xx
-	
-	movb	$0x1e, %al
-	movb	%bh, %ah
-	orb	$0x3f, %ah
-	call	tstidx
-	xorb	$0x3f, %al
-	andb	$0x3f, %al
-c5xx:	pushf
-	movb	$0x1e, %al
-	movb	%bh, %ah
-	outw	%ax, %dx
-	popf
-	je	c5done
-
-c5fail:	xorw	%bp, %bp
-c5done:	movb	$6, %al
-	movb	%bl, %ah
-	outw	%ax, %dx
-	ret
-
-cirrus5_md:
-	.byte	0x14, 0x19, 0x84
-	.byte	0x54, 0x2b, 0x84
-	.byte	0
-	.ascii	"Cirrus Logic 54XX"
-	.byte	0
-
-# Cirrus Logic 64XX -- no known extra modes, but must be identified, because
-# it's misidentified by the Ahead test.
-cirrus6_test:
-	movw	$0x3ce, %dx
-	movb	$0x0a, %al
-	call	inidx
-	movb	%al, %bl	# BL=backup
-	movw	$0xce0a, %ax
-	call	tstidx
-	orb	%al, %al
-	jne	c2fail
-	
-	movw	$0xec0a, %ax
-	call	tstidx
-	cmpb	$0x01, %al
-	jne	c2fail
-	
-	movb	$0xaa, %al
-	call	inidx		# 4X, 5X, 7X and 8X are valid 64XX chip ID's. 
-	shrb	$4, %al
-	subb	$4, %al
-	jz	c6done
-	
-	decb	%al
-	jz	c6done
-	
-	subb	$2, %al
-	jz	c6done
-	
-	decb	%al
-	jz	c6done
-	
-c2fail:	xorw	%bp, %bp
-c6done:	movb	$0x0a, %al
-	movb	%bl, %ah
-	outw	%ax, %dx
-	ret
-
-cirrus6_md:
-	.byte	0
-	.ascii	"Cirrus Logic 64XX"
-	.byte	0
-
-# Everex / Trident
-everex_test:
-	movw	$0x7000, %ax
-	xorw	%bx, %bx
-	int	$0x10
-	cmpb	$0x70, %al
-	jne	noevrx
-	
-	shrw	$4, %dx
-	cmpw	$0x678, %dx
-	je	evtrid
-	
-	cmpw	$0x236, %dx
-	jne	evrxok
-
-evtrid:	leaw	trident_md, %bp
-evrxok:	ret
-
-noevrx:	xorw	%bp, %bp
-	ret
-
-everex_md:
-	.byte	0x03, 0x22, 0x50
-	.byte	0x04, 0x3c, 0x50
-	.byte	0x07, 0x2b, 0x64
-	.byte	0x08, 0x4b, 0x64
-	.byte	0x0a, 0x19, 0x84
-	.byte	0x0b, 0x2c, 0x84
-	.byte	0x16, 0x1e, 0x50
-	.byte	0x18, 0x1b, 0x64
-	.byte	0x21, 0x40, 0xa0
-	.byte	0x40, 0x1e, 0x84
-	.byte	0
-	.ascii	"Everex/Trident"
-	.byte	0
-
-# Genoa.
-genoa_test:
-	leaw	idgenoa, %si			# Check Genoa 'clues'
-	xorw	%ax, %ax
-	movb	%es:(0x37), %al
-	movw	%ax, %di
-	movw	$0x04, %cx
-	decw	%si
-	decw	%di
-l1:	incw	%si
-	incw	%di
-	movb	(%si), %al
-	testb	%al, %al
-	jz	l2
-
-	cmpb	%es:(%di), %al
-l2:	loope 	l1
-	orw	%cx, %cx
-	je	isgen
-	
-	xorw	%bp, %bp
-isgen:	ret
-
-idgenoa: .byte	0x77, 0x00, 0x99, 0x66
-
-genoa_md:
-	.byte	0x58, 0x20, 0x50
-	.byte	0x5a, 0x2a, 0x64
-	.byte	0x60, 0x19, 0x84
-	.byte	0x61, 0x1d, 0x84
-	.byte	0x62, 0x20, 0x84
-	.byte	0x63, 0x2c, 0x84
-	.byte	0x64, 0x3c, 0x84
-	.byte	0x6b, 0x4f, 0x64
-	.byte	0x72, 0x3c, 0x50
-	.byte	0x74, 0x42, 0x50
-	.byte	0x78, 0x4b, 0x64
-	.byte	0
-	.ascii	"Genoa"
-	.byte	0
-
-# OAK
-oak_test:
-	leaw	idoakvga, %si
-	movw	$0x08, %di
-	movw	$0x08, %cx
-	repe
-	cmpsb
-	je	isoak
-	
-	xorw	%bp, %bp
-isoak:	ret
-
-idoakvga: .ascii  "OAK VGA "
-
-oak_md: .byte	0x4e, 0x3c, 0x50
-	.byte	0x4f, 0x3c, 0x84
-	.byte	0x50, 0x19, 0x84
-	.byte	0x51, 0x2b, 0x84
-	.byte	0
-	.ascii	"OAK"
-	.byte	0
-
-# WD Paradise.
-paradise_test:
-	leaw	idparadise, %si
-	movw	$0x7d, %di
-	movw	$0x04, %cx
-	repe
-	cmpsb
-	je	ispara
-	
-	xorw	%bp, %bp
-ispara:	ret
-
-idparadise:	.ascii	"VGA="
-
-paradise_md:
-	.byte	0x41, 0x22, 0x50
-	.byte	0x47, 0x1c, 0x84
-	.byte	0x55, 0x19, 0x84
-	.byte	0x54, 0x2c, 0x84
-	.byte	0
-	.ascii	"Paradise"
-	.byte	0
-
-# Trident.
-trident_test:
-	movw	$0x3c4, %dx
-	movb	$0x0e, %al
-	outb	%al, %dx
-	incw	%dx
-	inb	%dx, %al
-	xchgb	%al, %ah
-	xorb	%al, %al
-	outb	%al, %dx
-	inb	%dx, %al
-	xchgb	%ah, %al
-	movb	%al, %bl	# Strange thing ... in the book this wasn't
-	andb	$0x02, %bl	# necessary but it worked on my card which
-	jz	setb2		# is a trident. Without it the screen goes
-				# blurred ...
-	andb	$0xfd, %al
-	jmp	clrb2		
-
-setb2:	orb	$0x02, %al	
-clrb2:	outb	%al, %dx
-	andb	$0x0f, %ah
-	cmpb	$0x02, %ah
-	je	istrid
-
-	xorw	%bp, %bp
-istrid:	ret
-
-trident_md:
-	.byte	0x50, 0x1e, 0x50
-	.byte	0x51, 0x2b, 0x50
-	.byte	0x52, 0x3c, 0x50
-	.byte	0x57, 0x19, 0x84
-	.byte	0x58, 0x1e, 0x84
-	.byte	0x59, 0x2b, 0x84
-	.byte	0x5a, 0x3c, 0x84
-	.byte	0
-	.ascii	"Trident"
-	.byte	0
-
-# Tseng.
-tseng_test:
-	movw	$0x3cd, %dx
-	inb	%dx, %al	# Could things be this simple ! :-)
-	movb	%al, %bl
-	movb	$0x55, %al
-	outb	%al, %dx
-	inb	%dx, %al
-	movb	%al, %ah
-	movb	%bl, %al
-	outb	%al, %dx
-	cmpb	$0x55, %ah
- 	je	istsen
-
-isnot:	xorw	%bp, %bp
-istsen:	ret
-
-tseng_md:
-	.byte	0x26, 0x3c, 0x50
-	.byte	0x2a, 0x28, 0x64
-	.byte	0x23, 0x19, 0x84
-	.byte	0x24, 0x1c, 0x84
-	.byte	0x22, 0x2c, 0x84
-	.byte	0x21, 0x3c, 0x84
-	.byte	0
-	.ascii	"Tseng"
-	.byte	0
-
-# Video7.
-video7_test:
-	movw	$0x3cc, %dx
-	inb	%dx, %al
-	movw	$0x3b4, %dx
-	andb	$0x01, %al
-	jz	even7
-
-	movw	$0x3d4, %dx
-even7:	movb	$0x0c, %al
-	outb	%al, %dx
-	incw	%dx
-	inb	%dx, %al
-	movb	%al, %bl
-	movb	$0x55, %al
-	outb	%al, %dx
-	inb	%dx, %al
-	decw	%dx
-	movb	$0x1f, %al
-	outb	%al, %dx
-	incw	%dx
-	inb	%dx, %al
-	movb	%al, %bh
-	decw	%dx
-	movb	$0x0c, %al
-	outb	%al, %dx
-	incw	%dx
-	movb	%bl, %al
-	outb	%al, %dx
-	movb	$0x55, %al
-	xorb	$0xea, %al
-	cmpb	%bh, %al
-	jne	isnot
-	
-	movb	$VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching
-	ret
-
-video7_md:
-	.byte	0x40, 0x2b, 0x50
-	.byte	0x43, 0x3c, 0x50
-	.byte	0x44, 0x3c, 0x64
-	.byte	0x41, 0x19, 0x84
-	.byte	0x42, 0x2c, 0x84
-	.byte	0x45, 0x1c, 0x84
-	.byte	0
-	.ascii	"Video 7"
-	.byte	0
-
-# Realtek VGA
-realtek_test:
-	leaw	idrtvga, %si
-	movw	$0x45, %di
-	movw	$0x0b, %cx
-	repe
-	cmpsb
-	je	isrt
-	
-	xorw	%bp, %bp
-isrt:	ret
-
-idrtvga:	.ascii	"REALTEK VGA"
-
-realtek_md:
-	.byte	0x1a, 0x3c, 0x50
-	.byte	0x1b, 0x19, 0x84
-	.byte	0x1c, 0x1e, 0x84
-	.byte	0x1d, 0x2b, 0x84
-	.byte	0x1e, 0x3c, 0x84
-	.byte	0
-	.ascii	"REALTEK"
-	.byte	0
-
-#endif	/* CONFIG_VIDEO_SVGA */
-
-# User-defined local mode table (VGA only)
-#ifdef CONFIG_VIDEO_LOCAL
-local_modes:
-	leaw	local_mode_table, %si
-locm1:	lodsw
-	orw	%ax, %ax
-	jz	locm2
-	
-	stosw
-	movsw
-	jmp	locm1
-
-locm2:	ret
-
-# This is the table of local video modes which can be supplied manually
-# by the user. Each entry consists of mode ID (word) and dimensions
-# (byte for column count and another byte for row count). These modes
-# are placed before all SVGA and VESA modes and override them if table
-# compacting is enabled. The table must end with a zero word followed
-# by NUL-terminated video adapter name.
-local_mode_table:
-	.word	0x0100				# Example: 40x25
-	.byte	25,40
-	.word	0
-	.ascii	"Local"
-	.byte	0
-#endif	/* CONFIG_VIDEO_LOCAL */
-
-# Read a key and return the ASCII code in al, scan code in ah
-getkey:	xorb	%ah, %ah
-	int	$0x16
-	ret
-
-# Read a key with a timeout of 30 seconds.
-# The hardware clock is used to get the time.
-getkt:	call	gettime
-	addb	$30, %al			# Wait 30 seconds
-	cmpb	$60, %al
-	jl	lminute
-
-	subb	$60, %al
-lminute:
-	movb	%al, %cl
-again:	movb	$0x01, %ah
-	int	$0x16
-	jnz	getkey				# key pressed, so get it
-
-	call	gettime
-	cmpb	%cl, %al
-	jne	again
-
-	movb	$0x20, %al			# timeout, return `space'
-	ret
-
-# Flush the keyboard buffer
-flush:	movb	$0x01, %ah
-	int	$0x16
-	jz	empty
-	
-	xorb	%ah, %ah
-	int	$0x16
-	jmp	flush
-
-empty:	ret
-
-# Print hexadecimal number.
-prthw:	pushw	%ax
-	movb	%ah, %al
-	call	prthb
-	popw	%ax
-prthb:	pushw	%ax
-	shrb	$4, %al
-	call	prthn
-	popw	%ax
-	andb	$0x0f, %al
-prthn:	cmpb	$0x0a, %al
-	jc	prth1
-
-	addb	$0x07, %al
-prth1:	addb	$0x30, %al
-	jmp	prtchr
-
-# Print decimal number in al
-prtdec:	pushw	%ax
-	pushw	%cx
-	xorb	%ah, %ah
-	movb	$0x0a, %cl
-	idivb	%cl
-	cmpb	$0x09, %al
-	jbe	lt100
-
-	call	prtdec
-	jmp	skip10
-
-lt100:	addb	$0x30, %al
-	call	prtchr
-skip10:	movb	%ah, %al
-	addb	$0x30, %al
-	call	prtchr	
-	popw	%cx
-	popw	%ax
-	ret
-
-store_edid:
-#ifdef CONFIG_FIRMWARE_EDID
-	pushw	%es				# just save all registers
-	pushw	%ax
-	pushw	%bx
-	pushw   %cx
-	pushw	%dx
-	pushw   %di
-
-	pushw	%fs
-	popw    %es
-
-	movl	$0x13131313, %eax		# memset block with 0x13
-	movw    $32, %cx
-	movw	$0x140, %di
-	cld
-	rep
-	stosl
-
-	cmpw	$0x0200, vbe_version		# only do EDID on >= VBE2.0
-	jl	no_edid
-
-	pushw   %es				# save ES
-	xorw    %di, %di                        # Report Capability
-	pushw   %di
-	popw    %es                             # ES:DI must be 0:0
-	movw	$0x4f15, %ax
-	xorw	%bx, %bx
-	xorw	%cx, %cx
-	int	$0x10
-	popw    %es                             # restore ES
-
-	cmpb    $0x00, %ah                      # call successful
-	jne     no_edid
-
-	cmpb    $0x4f, %al                      # function supported
-	jne     no_edid
-
-	movw	$0x4f15, %ax                    # do VBE/DDC
-	movw	$0x01, %bx
-	movw	$0x00, %cx
-	movw    $0x00, %dx
-	movw	$0x140, %di
-	int	$0x10
-
-no_edid:
-	popw	%di				# restore all registers
-	popw	%dx
-	popw	%cx
-	popw	%bx
-	popw	%ax
-	popw	%es
-#endif
-	ret
-
-# VIDEO_SELECT-only variables
-mt_end:		.word	0	# End of video mode table if built
-edit_buf:	.space	6	# Line editor buffer
-card_name:	.word	0	# Pointer to adapter name
-scanning:	.byte	0	# Performing mode scan
-do_restore:	.byte	0	# Screen contents altered during mode change
-svga_prefix:	.byte	VIDEO_FIRST_BIOS>>8	# Default prefix for BIOS modes
-graphic_mode:	.byte	0	# Graphic mode with a linear frame buffer
-dac_size:	.byte	6	# DAC bit depth
-vbe_version:	.word	0	# VBE bios version
-
-# Status messages
-keymsg:		.ascii	"Press <RETURN> to see video modes available, "
-		.ascii	"<SPACE> to continue or wait 30 secs"
-		.byte	0x0d, 0x0a, 0
-
-listhdr:	.byte	0x0d, 0x0a
-		.ascii	"Mode:    COLSxROWS:"
-
-crlft:		.byte	0x0d, 0x0a, 0
-
-prompt:		.byte	0x0d, 0x0a
-		.asciz	"Enter mode number or `scan': "
-
-unknt:		.asciz	"Unknown mode ID. Try again."
-
-badmdt:		.ascii	"You passed an undefined mode number."
-		.byte	0x0d, 0x0a, 0
-
-vesaer:		.ascii	"Error: Scanning of VESA modes failed. Please "
-		.ascii	"report to <mj@ucw.cz>."
-		.byte	0x0d, 0x0a, 0
-
-old_name:	.asciz	"CGA/MDA/HGA"
-
-ega_name:	.asciz	"EGA"
-
-svga_name:	.ascii	" "
-
-vga_name:	.asciz	"VGA"
-
-vesa_name:	.asciz	"VESA"
-
-name_bann:	.asciz	"Video adapter: "
-#endif /* CONFIG_VIDEO_SELECT */
-
-# Other variables:
-adapter:	.byte	0	# Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
-video_segment:	.word	0xb800	# Video memory segment
-force_size:	.word	0	# Use this size instead of the one in BIOS vars
diff --git a/arch/i386/boot/video.c b/arch/i386/boot/video.c
new file mode 100644
index 0000000..3bb3573
--- /dev/null
+++ b/arch/i386/boot/video.c
@@ -0,0 +1,456 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video.c
+ *
+ * Select video mode
+ */
+
+#include "boot.h"
+#include "video.h"
+#include "vesa.h"
+
+/*
+ * Mode list variables
+ */
+static struct card_info cards[];    /* List of cards to probe for */
+
+/*
+ * Common variables
+ */
+int adapter;			/* 0=CGA/MDA/HGC, 1=EGA, 2=VGA+ */
+u16 video_segment;
+int force_x, force_y;	/* Don't query the BIOS for cols/rows */
+
+int do_restore = 0;	/* Screen contents changed during mode flip */
+int graphic_mode;	/* Graphic mode with linear frame buffer */
+
+static void store_cursor_position(void)
+{
+	u16 curpos;
+	u16 ax, bx;
+
+	ax = 0x0300;
+	bx = 0;
+	asm(INT10
+	    : "=d" (curpos), "+a" (ax), "+b" (bx)
+	    : : "ecx", "esi", "edi");
+
+	boot_params.screen_info.orig_x = curpos;
+	boot_params.screen_info.orig_y = curpos >> 8;
+}
+
+static void store_video_mode(void)
+{
+	u16 ax, page;
+
+	/* N.B.: the saving of the video page here is a bit silly,
+	   since we pretty much assume page 0 everywhere. */
+	ax = 0x0f00;
+	asm(INT10
+	    : "+a" (ax), "=b" (page)
+	    : : "ecx", "edx", "esi", "edi");
+
+	/* Not all BIOSes are clean with respect to the top bit */
+	boot_params.screen_info.orig_video_mode = ax & 0x7f;
+	boot_params.screen_info.orig_video_page = page;
+}
+
+/*
+ * Store the video mode parameters for later usage by the kernel.
+ * This is done by asking the BIOS except for the rows/columns
+ * parameters in the default 80x25 mode -- these are set directly,
+ * because some very obscure BIOSes supply insane values.
+ */
+static void store_mode_params(void)
+{
+	u16 font_size;
+	int x, y;
+
+	/* For graphics mode, it is up to the mode-setting driver
+	   (currently only video-vesa.c) to store the parameters */
+	if (graphic_mode)
+		return;
+
+	store_cursor_position();
+	store_video_mode();
+
+	if (boot_params.screen_info.orig_video_mode == 0x07) {
+		/* MDA, HGC, or VGA in monochrome mode */
+		video_segment = 0xb000;
+	} else {
+		/* CGA, EGA, VGA and so forth */
+		video_segment = 0xb800;
+	}
+
+	set_fs(0);
+	font_size = rdfs16(0x485); /* Font size, BIOS area */
+	boot_params.screen_info.orig_video_points = font_size;
+
+	x = rdfs16(0x44a);
+	y = (adapter == ADAPTER_CGA) ? 25 : rdfs8(0x484)+1;
+
+	if (force_x)
+		x = force_x;
+	if (force_y)
+		y = force_y;
+
+	boot_params.screen_info.orig_video_cols  = x;
+	boot_params.screen_info.orig_video_lines = y;
+}
+
+/* Probe the video drivers and have them generate their mode lists. */
+static void probe_cards(int unsafe)
+{
+	struct card_info *card;
+	static u8 probed[2];
+
+	if (probed[unsafe])
+		return;
+
+	probed[unsafe] = 1;
+
+	for (card = video_cards; card < video_cards_end; card++) {
+		if (card->unsafe == unsafe) {
+			if (card->probe)
+				card->nmodes = card->probe();
+			else
+				card->nmodes = 0;
+		}
+	}
+}
+
+/* Test if a mode is defined */
+int mode_defined(u16 mode)
+{
+	struct card_info *card;
+	struct mode_info *mi;
+	int i;
+
+	for (card = video_cards; card < video_cards_end; card++) {
+		mi = card->modes;
+		for (i = 0; i < card->nmodes; i++, mi++) {
+			if (mi->mode == mode)
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+/* Set mode (without recalc) */
+static int raw_set_mode(u16 mode)
+{
+	int nmode, i;
+	struct card_info *card;
+	struct mode_info *mi;
+
+	/* Drop the recalc bit if set */
+	mode &= ~VIDEO_RECALC;
+
+	/* Scan for mode based on fixed ID, position, or resolution */
+	nmode = 0;
+	for (card = video_cards; card < video_cards_end; card++) {
+		mi = card->modes;
+		for (i = 0; i < card->nmodes; i++, mi++) {
+			int visible = mi->x || mi->y;
+
+			if ((mode == nmode && visible) ||
+			    mode == mi->mode ||
+			    mode == (mi->y << 8)+mi->x)
+				return card->set_mode(mi);
+
+			if (visible)
+				nmode++;
+		}
+	}
+
+	/* Nothing found?  Is it an "exceptional" (unprobed) mode? */
+	for (card = video_cards; card < video_cards_end; card++) {
+		if (mode >= card->xmode_first &&
+		    mode < card->xmode_first+card->xmode_n) {
+			struct mode_info mix;
+			mix.mode = mode;
+			mix.x = mix.y = 0;
+			return card->set_mode(&mix);
+		}
+	}
+
+	/* Otherwise, failure... */
+	return -1;
+}
+
+/*
+ * Recalculate the vertical video cutoff (hack!)
+ */
+static void vga_recalc_vertical(void)
+{
+	unsigned int font_size, rows;
+	u16 crtc;
+	u8 ov;
+
+	set_fs(0);
+	font_size = rdfs8(0x485); /* BIOS: font size (pixels) */
+	rows = force_y ? force_y : rdfs8(0x484)+1; /* Text rows */
+
+	rows *= font_size;	/* Visible scan lines */
+	rows--;			/* ... minus one */
+
+	crtc = vga_crtc();
+
+	out_idx((u8)rows, crtc, 0x12); /* Lower height register */
+	ov = in_idx(crtc, 0x07); /* Overflow register */
+	ov &= 0xbd;
+	ov |= (rows >> (8-1)) & 0x02;
+	ov |= (rows >> (9-6)) & 0x40;
+	out_idx(ov, crtc, 0x07);
+}
+
+/* Set mode (with recalc if specified) */
+static int set_mode(u16 mode)
+{
+	int rv;
+
+	/* Very special mode numbers... */
+	if (mode == VIDEO_CURRENT_MODE)
+		return 0;	/* Nothing to do... */
+	else if (mode == NORMAL_VGA)
+		mode = VIDEO_80x25;
+	else if (mode == EXTENDED_VGA)
+		mode = VIDEO_8POINT;
+
+	rv = raw_set_mode(mode);
+	if (rv)
+		return rv;
+
+	if (mode & VIDEO_RECALC)
+		vga_recalc_vertical();
+
+	return 0;
+}
+
+static unsigned int get_entry(void)
+{
+	char entry_buf[4];
+	int i, len = 0;
+	int key;
+	unsigned int v;
+
+	do {
+		key = getchar();
+
+		if (key == '\b') {
+			if (len > 0) {
+				puts("\b \b");
+				len--;
+			}
+		} else if ((key >= '0' && key <= '9') ||
+			   (key >= 'A' && key <= 'Z') ||
+			   (key >= 'a' && key <= 'z')) {
+			if (len < sizeof entry_buf) {
+				entry_buf[len++] = key;
+				putchar(key);
+			}
+		}
+	} while (key != '\r');
+	putchar('\n');
+
+	if (len == 0)
+		return VIDEO_CURRENT_MODE; /* Default */
+
+	v = 0;
+	for (i = 0; i < len; i++) {
+		v <<= 4;
+		key = entry_buf[i] | 0x20;
+		v += (key > '9') ? key-'a'+10 : key-'0';
+	}
+
+	return v;
+}
+
+static void display_menu(void)
+{
+	struct card_info *card;
+	struct mode_info *mi;
+	char ch;
+	int i;
+
+	puts("Mode:    COLSxROWS:\n");
+
+	ch = '0';
+	for (card = video_cards; card < video_cards_end; card++) {
+		mi = card->modes;
+		for (i = 0; i < card->nmodes; i++, mi++) {
+			int visible = mi->x && mi->y;
+			u16 mode_id = mi->mode ? mi->mode :
+				(mi->y << 8)+mi->x;
+
+			if (!visible)
+				continue; /* Hidden mode */
+
+			printf("%c  %04X  %3dx%-3d  %s\n",
+			       ch, mode_id, mi->x, mi->y, card->card_name);
+
+			if (ch == '9')
+				ch = 'a';
+			else if (ch == 'z' || ch == ' ')
+				ch = ' '; /* Out of keys... */
+			else
+				ch++;
+		}
+	}
+}
+
+#define H(x)	((x)-'a'+10)
+#define SCAN	((H('s')<<12)+(H('c')<<8)+(H('a')<<4)+H('n'))
+
+static unsigned int mode_menu(void)
+{
+	int key;
+	unsigned int sel;
+
+	puts("Press <ENTER> to see video modes available, "
+	     "<SPACE> to continue, or wait 30 sec\n");
+
+	kbd_flush();
+	while (1) {
+		key = getchar_timeout();
+		if (key == ' ' || key == 0)
+			return VIDEO_CURRENT_MODE; /* Default */
+		if (key == '\r')
+			break;
+		putchar('\a');	/* Beep! */
+	}
+
+
+	for (;;) {
+		display_menu();
+
+		puts("Enter a video mode or \"scan\" to scan for "
+		     "additional modes: ");
+		sel = get_entry();
+		if (sel != SCAN)
+			return sel;
+
+		probe_cards(1);
+	}
+}
+
+#ifdef CONFIG_VIDEO_RETAIN
+/* Save screen content to the heap */
+struct saved_screen {
+	int x, y;
+	int curx, cury;
+	u16 *data;
+} saved;
+
+static void save_screen(void)
+{
+	/* Should be called after store_mode_params() */
+	saved.x = boot_params.screen_info.orig_video_cols;
+	saved.y = boot_params.screen_info.orig_video_lines;
+	saved.curx = boot_params.screen_info.orig_x;
+	saved.cury = boot_params.screen_info.orig_y;
+
+	if (heap_free() < saved.x*saved.y*sizeof(u16)+512)
+		return;		/* Not enough heap to save the screen */
+
+	saved.data = GET_HEAP(u16, saved.x*saved.y);
+
+	set_fs(video_segment);
+	copy_from_fs(saved.data, 0, saved.x*saved.y*sizeof(u16));
+}
+
+static void restore_screen(void)
+{
+	/* Should be called after store_mode_params() */
+	int xs = boot_params.screen_info.orig_video_cols;
+	int ys = boot_params.screen_info.orig_video_lines;
+	int y;
+	addr_t dst = 0;
+	u16 *src = saved.data;
+	u16 ax, bx, dx;
+
+	if (graphic_mode)
+		return;		/* Can't restore onto a graphic mode */
+
+	if (!src)
+		return;		/* No saved screen contents */
+
+	/* Restore screen contents */
+
+	set_fs(video_segment);
+	for (y = 0; y < ys; y++) {
+		int npad;
+
+		if (y < saved.y) {
+			int copy = (xs < saved.x) ? xs : saved.x;
+			copy_to_fs(dst, src, copy*sizeof(u16));
+			dst += copy*sizeof(u16);
+			src += saved.x;
+			npad = (xs < saved.x) ? 0 : xs-saved.x;
+		} else {
+			npad = xs;
+		}
+
+		/* Writes "npad" blank characters to
+		   video_segment:dst and advances dst */
+		asm volatile("pushw %%es ; "
+			     "movw %2,%%es ; "
+			     "shrw %%cx ; "
+			     "jnc 1f ; "
+			     "stosw \n\t"
+			     "1: rep;stosl ; "
+			     "popw %%es"
+			     : "+D" (dst), "+c" (npad)
+			     : "bdSm" (video_segment),
+			       "a" (0x07200720));
+	}
+
+	/* Restore cursor position */
+	ax = 0x0200;		/* Set cursor position */
+	bx = 0;			/* Page number (<< 8) */
+	dx = (saved.cury << 8)+saved.curx;
+	asm volatile(INT10
+		     : "+a" (ax), "+b" (bx), "+d" (dx)
+		     : : "ecx", "esi", "edi");
+}
+#else
+#define save_screen()		((void)0)
+#define restore_screen()	((void)0)
+#endif
+
+void set_video(void)
+{
+	u16 mode = boot_params.hdr.vid_mode;
+
+	RESET_HEAP();
+
+	store_mode_params();
+	save_screen();
+	probe_cards(0);
+
+	for (;;) {
+		if (mode == ASK_VGA)
+			mode = mode_menu();
+
+		if (!set_mode(mode))
+			break;
+
+		printf("Undefined video mode number: %x\n", mode);
+		mode = ASK_VGA;
+	}
+	vesa_store_edid();
+	store_mode_params();
+
+	if (do_restore)
+		restore_screen();
+}
diff --git a/arch/i386/boot/video.h b/arch/i386/boot/video.h
new file mode 100644
index 0000000..29eca17
--- /dev/null
+++ b/arch/i386/boot/video.h
@@ -0,0 +1,145 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/video.h
+ *
+ * Header file for the real-mode video probing code
+ */
+
+#ifndef BOOT_VIDEO_H
+#define BOOT_VIDEO_H
+
+#include <linux/types.h>
+
+/* Enable autodetection of SVGA adapters and modes. */
+#undef CONFIG_VIDEO_SVGA
+
+/* Enable autodetection of VESA modes */
+#define CONFIG_VIDEO_VESA
+
+/* Retain screen contents when switching modes */
+#define CONFIG_VIDEO_RETAIN
+
+/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
+#undef CONFIG_VIDEO_400_HACK
+
+/* This code uses an extended set of video mode numbers. These include:
+ * Aliases for standard modes
+ *      NORMAL_VGA (-1)
+ *      EXTENDED_VGA (-2)
+ *      ASK_VGA (-3)
+ * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
+ * of compatibility when extending the table. These are between 0x00 and 0xff.
+ */
+#define VIDEO_FIRST_MENU 0x0000
+
+/* Standard BIOS video modes (BIOS number + 0x0100) */
+#define VIDEO_FIRST_BIOS 0x0100
+
+/* VESA BIOS video modes (VESA number + 0x0200) */
+#define VIDEO_FIRST_VESA 0x0200
+
+/* Video7 special modes (BIOS number + 0x0900) */
+#define VIDEO_FIRST_V7 0x0900
+
+/* Special video modes */
+#define VIDEO_FIRST_SPECIAL 0x0f00
+#define VIDEO_80x25 0x0f00
+#define VIDEO_8POINT 0x0f01
+#define VIDEO_80x43 0x0f02
+#define VIDEO_80x28 0x0f03
+#define VIDEO_CURRENT_MODE 0x0f04
+#define VIDEO_80x30 0x0f05
+#define VIDEO_80x34 0x0f06
+#define VIDEO_80x60 0x0f07
+#define VIDEO_GFX_HACK 0x0f08
+#define VIDEO_LAST_SPECIAL 0x0f09
+
+/* Video modes given by resolution */
+#define VIDEO_FIRST_RESOLUTION 0x1000
+
+/* The "recalculate timings" flag */
+#define VIDEO_RECALC 0x8000
+
+/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
+#ifdef CONFIG_VIDEO_RETAIN
+void store_screen(void);
+#define DO_STORE() store_screen()
+#else
+#define DO_STORE() ((void)0)
+#endif /* CONFIG_VIDEO_RETAIN */
+
+/*
+ * Mode table structures
+ */
+
+struct mode_info {
+	u16 mode;		/* Mode number (vga= style) */
+	u8  x, y;		/* Width, height */
+};
+
+struct card_info {
+	const char *card_name;
+	int (*set_mode)(struct mode_info *mode);
+	int (*probe)(void);
+	struct mode_info *modes;
+	int nmodes;		/* Number of probed modes so far */
+	int unsafe;		/* Probing is unsafe, only do after "scan" */
+	u16 xmode_first;	/* Unprobed modes to try to call anyway */
+	u16 xmode_n;		/* Size of unprobed mode range */
+};
+
+#define __videocard struct card_info __attribute__((section(".videocards")))
+extern struct card_info video_cards[], video_cards_end[];
+
+int mode_defined(u16 mode);	/* video.c */
+
+/* Basic video information */
+#define ADAPTER_CGA	0	/* CGA/MDA/HGC */
+#define ADAPTER_EGA	1
+#define ADAPTER_VGA	2
+
+extern int adapter;
+extern u16 video_segment;
+extern int force_x, force_y;	/* Don't query the BIOS for cols/rows */
+extern int do_restore;		/* Restore screen contents */
+extern int graphic_mode;	/* Graphics mode with linear frame buffer */
+
+/*
+ * int $0x10 is notorious for touching registers it shouldn't.
+ * gcc doesn't like %ebp being clobbered, so define it as a push/pop
+ * sequence here.
+ */
+#define INT10 "pushl %%ebp; int $0x10; popl %%ebp"
+
+/* Accessing VGA indexed registers */
+static inline u8 in_idx(u16 port, u8 index)
+{
+	outb(index, port);
+	return inb(port+1);
+}
+
+static inline void out_idx(u8 v, u16 port, u8 index)
+{
+	outw(index+(v << 8), port);
+}
+
+/* Writes a value to an indexed port and then reads the port again */
+static inline u8 tst_idx(u8 v, u16 port, u8 index)
+{
+	out_idx(port, index, v);
+	return in_idx(port, index);
+}
+
+/* Get the I/O port of the VGA CRTC */
+u16 vga_crtc(void);		/* video-vga.c */
+
+#endif /* BOOT_VIDEO_H */
diff --git a/arch/i386/boot/voyager.c b/arch/i386/boot/voyager.c
new file mode 100644
index 0000000..9221614
--- /dev/null
+++ b/arch/i386/boot/voyager.c
@@ -0,0 +1,46 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/voyager.c
+ *
+ * Get the Voyager config information
+ */
+
+#include "boot.h"
+
+#ifdef CONFIG_X86_VOYAGER
+
+int query_voyager(void)
+{
+	u8 err;
+	u16 es, di;
+	/* Abuse the apm_bios_info area for this */
+	u8 *data_ptr = (u8 *)&boot_params.apm_bios_info;
+
+	data_ptr[0] = 0xff;	/* Flag on config not found(?) */
+
+	asm("pushw %%es ; "
+	    "int $0x15 ; "
+	    "setc %0 ; "
+	    "movw %%es, %1 ; "
+	    "popw %%es"
+	    : "=qm" (err), "=rm" (es), "=D" (di)
+	    : "a" (0xffc0));
+
+	if (err)
+		return -1;	/* Not Voyager */
+
+	set_fs(es);
+	copy_from_fs(data_ptr, di, 7);	/* Table is 7 bytes apparently */
+	return 0;
+}
+
+#endif /* CONFIG_X86_VOYAGER */
diff --git a/arch/i386/kernel/cpu/Makefile b/arch/i386/kernel/cpu/Makefile
index 74f27a4..0b6a855 100644
--- a/arch/i386/kernel/cpu/Makefile
+++ b/arch/i386/kernel/cpu/Makefile
@@ -8,7 +8,7 @@
 obj-y	+=	cyrix.o
 obj-y	+=	centaur.o
 obj-y	+=	transmeta.o
-obj-y	+=	intel.o intel_cacheinfo.o
+obj-y	+=	intel.o intel_cacheinfo.o addon_cpuid_features.o
 obj-y	+=	rise.o
 obj-y	+=	nexgen.o
 obj-y	+=	umc.o
diff --git a/arch/i386/kernel/cpu/addon_cpuid_features.c b/arch/i386/kernel/cpu/addon_cpuid_features.c
new file mode 100644
index 0000000..3e91d3ee
--- /dev/null
+++ b/arch/i386/kernel/cpu/addon_cpuid_features.c
@@ -0,0 +1,50 @@
+
+/*
+ *	Routines to indentify additional cpu features that are scattered in
+ *	cpuid space.
+ */
+
+#include <linux/cpu.h>
+
+#include <asm/processor.h>
+
+struct cpuid_bit {
+	u16 feature;
+	u8 reg;
+	u8 bit;
+	u32 level;
+};
+
+enum cpuid_regs {
+	CR_EAX = 0,
+	CR_ECX,
+	CR_EDX,
+	CR_EBX
+};
+
+void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
+{
+	u32 max_level;
+	u32 regs[4];
+	const struct cpuid_bit *cb;
+
+	static const struct cpuid_bit cpuid_bits[] = {
+		{ X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
+		{ 0, 0, 0, 0 }
+	};
+
+	for (cb = cpuid_bits; cb->feature; cb++) {
+
+		/* Verify that the level is valid */
+		max_level = cpuid_eax(cb->level & 0xffff0000);
+		if (max_level < cb->level ||
+		    max_level > (cb->level | 0xffff))
+			continue;
+
+		cpuid(cb->level, &regs[CR_EAX], &regs[CR_EBX],
+			&regs[CR_ECX], &regs[CR_EDX]);
+
+		if (regs[cb->reg] & (1 << cb->bit))
+			set_bit(cb->feature, c->x86_capability);
+	}
+}
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 794d593..e5419a9 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -353,6 +353,8 @@
 			if ( xlvl >= 0x80000004 )
 				get_model_name(c); /* Default name */
 		}
+
+		init_scattered_cpuid_features(c);
 	}
 
 	early_intel_workaround(c);
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 89d91e6..1e31b6c 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -29,7 +29,8 @@
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
-		NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext", "3dnow",
+		NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm",
+		"3dnowext", "3dnow",
 
 		/* Transmeta-defined */
 		"recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
@@ -40,8 +41,9 @@
 		/* Other (Linux-defined) */
 		"cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
 		NULL, NULL, NULL, NULL,
-		"constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL,
-		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		"constant_tsc", "up", NULL, "arch_perfmon",
+		"pebs", "bts", NULL, "sync_rdtsc",
+		"rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
 		/* Intel-defined (#2) */
@@ -57,9 +59,16 @@
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
 		/* AMD-defined (#2) */
-		"lahf_lm", "cmp_legacy", "svm", "extapic", "cr8legacy", "abm",
-		"sse4a", "misalignsse",
-		"3dnowprefetch", "osvw", "ibs", NULL, NULL, NULL, NULL, NULL,
+		"lahf_lm", "cmp_legacy", "svm", "extapic", "cr8_legacy",
+		"altmovcr8", "abm", "sse4a",
+		"misalignsse", "3dnowprefetch",
+		"osvw", "ibs", NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+		/* Auxiliary (Linux-defined) */
+		"ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	};
diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c
index 9645bb51..fc822a4 100644
--- a/arch/i386/kernel/e820.c
+++ b/arch/i386/kernel/e820.c
@@ -734,7 +734,7 @@
 		case E820_NVS:
 				printk("(ACPI NVS)\n");
 				break;
-		default:	printk("type %lu\n", e820.map[i].type);
+		default:	printk("type %u\n", e820.map[i].type);
 				break;
 		}
 	}
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 698c24f..2d61e65 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -102,19 +102,10 @@
 /*
  * Setup options
  */
-struct drive_info_struct { char dummy[32]; } drive_info;
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
-    defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-EXPORT_SYMBOL(drive_info);
-#endif
 struct screen_info screen_info;
 EXPORT_SYMBOL(screen_info);
 struct apm_info apm_info;
 EXPORT_SYMBOL(apm_info);
-struct sys_desc_table_struct {
-	unsigned short length;
-	unsigned char table[0];
-};
 struct edid_info edid_info;
 EXPORT_SYMBOL_GPL(edid_info);
 struct ist_info ist_info;
@@ -134,7 +125,7 @@
 
 static char __initdata command_line[COMMAND_LINE_SIZE];
 
-unsigned char __initdata boot_params[PARAM_SIZE];
+struct boot_params __initdata boot_params;
 
 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
 struct edd edd;
@@ -528,7 +519,6 @@
 #endif
 
  	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
- 	drive_info = DRIVE_INFO;
  	screen_info = SCREEN_INFO;
 	edid_info = EDID_INFO;
 	apm_info.bios = APM_BIOS_INFO;
diff --git a/arch/i386/kernel/verify_cpu.S b/arch/i386/kernel/verify_cpu.S
deleted file mode 100644
index f1d1eacf..0000000
--- a/arch/i386/kernel/verify_cpu.S
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Check if CPU has some minimum CPUID bits
-   This runs in 16bit mode so that the caller can still use the BIOS
-   to output errors on the screen */
-#include <asm/cpufeature.h>
-#include <asm/msr.h>
-
-verify_cpu:
-	pushfl				# Save caller passed flags
-	pushl	$0			# Kill any dangerous flags
-	popfl
-
-#if CONFIG_X86_MINIMUM_CPU_MODEL >= 4
-	pushfl
-	pop	%eax
-	orl	$(1<<18),%eax		# try setting AC
-	push	%eax
-	popfl
-	pushfl
-	popl    %eax
-	testl	$(1<<18),%eax
-	jz	bad
-#endif
-#if REQUIRED_MASK1 != 0
-	pushfl				# standard way to check for cpuid
-	popl	%eax
-	movl	%eax,%ebx
-	xorl	$0x200000,%eax
-	pushl	%eax
-	popfl
-	pushfl
-	popl	%eax
-	cmpl	%eax,%ebx
-	pushfl				# standard way to check for cpuid
-	popl	%eax
-	movl	%eax,%ebx
-	xorl	$0x200000,%eax
-	pushl	%eax
-	popfl
-	pushfl
-	popl	%eax
-	cmpl	%eax,%ebx
-	jz	bad			# REQUIRED_MASK1 != 0 requires CPUID
-
-	movl	$0x0,%eax		# See if cpuid 1 is implemented
-	cpuid
-	cmpl	$0x1,%eax
-	jb	bad			# no cpuid 1
-
-#if REQUIRED_MASK1 & NEED_CMPXCHG64
-	/* Some VIA C3s need magic MSRs to enable CX64. Do this here */
-	cmpl	$0x746e6543,%ebx	# Cent
-	jne	1f
-	cmpl 	$0x48727561,%edx	# aurH
-	jne	1f
-	cmpl	$0x736c7561,%ecx	# auls
-	jne	1f
-	movl	$1,%eax			# check model
-	cpuid
-	movl	%eax,%ebx
-	shr	$8,%ebx
-	andl	$0xf,%ebx
-	cmp	$6,%ebx			# check family == 6
-	jne	1f
-	shr	$4,%eax
-	andl	$0xf,%eax
-	cmpl	$6,%eax			# check model >= 6
-	jb	1f
-	# assume models >= 6 all support this MSR
-	movl	$MSR_VIA_FCR,%ecx
-	rdmsr
-	orl	$((1<<1)|(1<<7)),%eax	# enable CMPXCHG64 and PGE
-	wrmsr
-1:
-#endif
-	movl    $0x1,%eax		# Does the cpu have what it takes
-	cpuid
-
-#if CONFIG_X86_MINIMUM_CPU_MODEL > 4
-#error	add proper model checking here
-#endif
-
-	andl	$REQUIRED_MASK1,%edx
-	xorl	$REQUIRED_MASK1,%edx
-	jnz	bad
-#endif /* REQUIRED_MASK1 */
-
-	popfl
-	xor	%eax,%eax
-	ret
-
-bad:
-	popfl
-	movl	$1,%eax
-	ret
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index a00fabe..5c863bc 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -117,9 +117,9 @@
 	select ARC32
 	select ARCH_MAY_HAVE_PC_FDC
 	select GENERIC_ISA_DMA
-	select I8253
 	select I8259
 	select ISA
+	select PCSPEAKER
 	select SYS_HAS_CPU_R4X00
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
@@ -347,9 +347,9 @@
 	select DMA_COHERENT
 	select GENERIC_ISA_DMA
 	select HAVE_STD_PC_SERIAL_PORT
-	select I8253
 	select I8259
 	select ISA
+	select PCSPEAKER
 	select SWAP_IO_SPACE
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_SUPPORTS_32BIT_KERNEL
@@ -562,9 +562,9 @@
 	select HW_HAS_EISA
 	select HW_HAS_PCI
 	select IRQ_CPU
-	select I8253
 	select I8259
 	select ISA
+	select PCSPEAKER
 	select SWAP_IO_SPACE if CPU_BIG_ENDIAN
 	select SYS_HAS_CPU_R4X00
 	select SYS_HAS_CPU_R5000
@@ -1404,6 +1404,19 @@
 	  it off), but ensures that IPIs are handled promptly even under
 	  heavy I/O interrupt load.
 
+config MIPS_MT_SMTC_IM_BACKSTOP
+	bool "Use per-TC register bits as backstop for inhibited IM bits"
+	depends on MIPS_MT_SMTC
+	default y
+	help
+	  To support multiple TC microthreads acting as "CPUs" within
+	  a VPE, VPE-wide interrupt mask bits must be specially manipulated
+	  during interrupt handling. To support legacy drivers and interrupt
+	  controller management code, SMTC has a "backstop" to track and
+	  if necessary restore the interrupt mask. This has some performance
+	  impact on interrupt service overhead. Disable it only if you know
+	  what you are doing.
+
 config MIPS_VPE_LOADER_TOM
 	bool "Load VPE program into memory hidden from linux"
 	depends on MIPS_VPE_LOADER
@@ -1851,7 +1864,7 @@
 	bool
 	default y
 
-config I8253
+config PCSPEAKER
 	bool
 
 source "drivers/pcmcia/Kconfig"
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index 13fe187..fdf2b85 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -100,9 +100,6 @@
         argptr = prom_getcmdline();
         /* default panel */
         /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
-#ifdef CONFIG_MIPS_HYDROGEN3
-         strcat(argptr, " video=au1100fb:panel:Hydrogen_3_NEC_panel_320x240,nohwcursor");
-#endif
     }
 #endif
 
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
index dd04eece..8a0b4ac 100644
--- a/arch/mips/configs/jazz_defconfig
+++ b/arch/mips/configs/jazz_defconfig
@@ -241,7 +241,7 @@
 #
 CONFIG_ISA=y
 CONFIG_MMU=y
-CONFIG_I8253=y
+CONFIG_PCSPEAKER=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index 6cca105..703de00 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -221,7 +221,7 @@
 #
 CONFIG_ISA=y
 CONFIG_MMU=y
-CONFIG_I8253=y
+CONFIG_PCSPEAKER=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 1a67a85..a5dc5cb 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -251,7 +251,7 @@
 CONFIG_ISA=y
 # CONFIG_EISA is not set
 CONFIG_MMU=y
-CONFIG_I8253=y
+CONFIG_PCSPEAKER=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index f1cdb12..f342d8c 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -592,8 +592,6 @@
 # CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_RTC is not set
-CONFIG_GEN_RTC=y
-CONFIG_GEN_RTC_X=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 961594c..5c8085b 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -63,7 +63,7 @@
 
 obj-$(CONFIG_64BIT)		+= cpu-bugs64.o
 
-obj-$(CONFIG_I8253)		+= i8253.o
+obj-$(CONFIG_PCSPEAKER)		+= pcspeaker.o
 
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 686249c..e29598a 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -84,6 +84,7 @@
 	LONG_S	sp, TI_REGS($28)
 	jal	deferred_smtc_ipi
 	LONG_S	s0, TI_REGS($28)
+#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
 /* Re-arm any temporarily masked interrupts not explicitly "acked" */
 	mfc0	v0, CP0_TCSTATUS
 	ori	v1, v0, TCSTATUS_IXMT
@@ -110,6 +111,7 @@
 	_ehb
 	xor	t0, t0, t3
 	mtc0	t0, CP0_TCCONTEXT
+#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
 #endif /* CONFIG_MIPS_MT_SMTC */
 	.set	noat
 	RESTORE_TEMP
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 297bd56..c0f19d6 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -243,9 +243,11 @@
 	 */
 	mfc0	t1, CP0_STATUS
 	and	t0, a0, t1
+#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
 	mfc0	t2, CP0_TCCONTEXT
 	or	t0, t0, t2
 	mtc0	t0, CP0_TCCONTEXT
+#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
 	xor	t1, t1, t0
 	mtc0	t1, CP0_STATUS
 	_ehb
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/pcspeaker.c
similarity index 100%
rename from arch/mips/kernel/i8253.c
rename to arch/mips/kernel/pcspeaker.c
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index 0672959..d9bfae5 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -85,12 +85,7 @@
 	move	$28, a2
 	cpu_restore_nonscratch a1
 
-#if (_THREAD_SIZE - 32) < 0x10000
-	PTR_ADDIU	t0, $28, _THREAD_SIZE - 32
-#else
-	PTR_LI		t0, _THREAD_SIZE - 32
-	PTR_ADDU	t0, $28
-#endif
+	PTR_ADDU	t0, $28, _THREAD_SIZE - 32
 	set_saved_sp	t0, t1, t2
 #ifdef CONFIG_MIPS_MT_SMTC
 	/* Read-modify-writes of Status must be atomic on a VPE */
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 80ea4fa..5e9fa83 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -373,7 +373,7 @@
 		action = MIPS_BE_FIXUP;
 
 	if (board_be_handler)
-		action = board_be_handler(regs, fixup != 0);
+		action = board_be_handler(regs, fixup != NULL);
 
 	switch (action) {
 	case MIPS_BE_DISCARD:
diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 1a4db7d..465ff0e 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -10,6 +10,7 @@
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <asm/tlbdebug.h>
 
 static inline const char *msk2str(unsigned int mask)
 {
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c
index 52f8779..9cee907 100644
--- a/arch/mips/lib/r3k_dump_tlb.c
+++ b/arch/mips/lib/r3k_dump_tlb.c
@@ -11,6 +11,7 @@
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <asm/tlbdebug.h>
 
 extern int r3k_have_wired_reg;	/* defined in tlb-r3k.c */
 
diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c
index 2388f7f..58d14f4 100644
--- a/arch/mips/lib/uncached.c
+++ b/arch/mips/lib/uncached.c
@@ -12,6 +12,7 @@
 
 #include <asm/addrspace.h>
 #include <asm/bug.h>
+#include <asm/cacheflush.h>
 
 #ifndef CKSEG2
 #define CKSEG2 CKSSEG
diff --git a/arch/mips/mipssim/sim_int.c b/arch/mips/mipssim/sim_int.c
index d86b372..5cbc350 100644
--- a/arch/mips/mipssim/sim_int.c
+++ b/arch/mips/mipssim/sim_int.c
@@ -77,7 +77,7 @@
 	irq = irq_ffs(pending);
 
 	if (irq > 0)
-		do_IRQ(MIPSCPU_INT_BASE + irq);
+		do_IRQ(MIPS_CPU_IRQ_BASE + irq);
 	else
 		spurious_interrupt();
 }
diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c
index 3643582..60e6690 100644
--- a/arch/mips/mipssim/sim_setup.c
+++ b/arch/mips/mipssim/sim_setup.c
@@ -84,7 +84,7 @@
 	/* hardware int 4 - the serial int, is CPU int 6
 	 but poll for now */
 	s.irq =  0;
-	s.uartclk = BASE_BAUD * 16;
+	s.uartclk = 1843200;
 	s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
 	s.iotype = UPIO_PORT;
 	s.regshift = 0;
diff --git a/arch/mips/mipssim/sim_time.c b/arch/mips/mipssim/sim_time.c
index 874a18e..a0f5a5d 100644
--- a/arch/mips/mipssim/sim_time.c
+++ b/arch/mips/mipssim/sim_time.c
@@ -5,7 +5,6 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
-#include <linux/mipsregs.h>
 #include <linux/smp.h>
 #include <linux/timex.h>
 
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 8108231..99d8f4f 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -269,7 +269,7 @@
 	}
 
 	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
-		struct pci_dev *dev = pci_dev_b(ln);
+		dev = pci_dev_b(ln);
 
 		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
 			pcibios_fixup_device_resources(dev, bus);
diff --git a/arch/mips/sibyte/swarm/time.c b/arch/mips/sibyte/swarm/time.c
deleted file mode 100644
index 97c73c7..0000000
--- a/arch/mips/sibyte/swarm/time.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*
- * Time routines for the swarm board.  We pass all the hard stuff
- * through to the sb1250 handling code.  Only thing we really keep
- * track of here is what time of day we think it is.  And we don't
- * really even do a good job of that...
- */
-
-
-#include <linux/bcd.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <asm/system.h>
-#include <asm/addrspace.h>
-#include <asm/io.h>
-
-#include <asm/sibyte/sb1250.h>
-#include <asm/sibyte/sb1250_regs.h>
-#include <asm/sibyte/sb1250_smbus.h>
-
-static unsigned long long sec_bias = 0;
-static unsigned int usec_bias = 0;
-
-/* Xicor 1241 definitions */
-
-/*
- * Register bits
- */
-
-#define X1241REG_SR_BAT	0x80		/* currently on battery power */
-#define X1241REG_SR_RWEL 0x04		/* r/w latch is enabled, can write RTC */
-#define X1241REG_SR_WEL 0x02		/* r/w latch is unlocked, can enable r/w now */
-#define X1241REG_SR_RTCF 0x01		/* clock failed */
-#define X1241REG_BL_BP2 0x80		/* block protect 2 */
-#define X1241REG_BL_BP1 0x40		/* block protect 1 */
-#define X1241REG_BL_BP0 0x20		/* block protect 0 */
-#define X1241REG_BL_WD1	0x10
-#define X1241REG_BL_WD0	0x08
-#define X1241REG_HR_MIL 0x80		/* military time format */
-
-/*
- * Register numbers
- */
-
-#define X1241REG_BL	0x10		/* block protect bits */
-#define X1241REG_INT	0x11		/*  */
-#define X1241REG_SC	0x30		/* Seconds */
-#define X1241REG_MN	0x31		/* Minutes */
-#define X1241REG_HR	0x32		/* Hours */
-#define X1241REG_DT	0x33		/* Day of month */
-#define X1241REG_MO	0x34		/* Month */
-#define X1241REG_YR	0x35		/* Year */
-#define X1241REG_DW	0x36		/* Day of Week */
-#define X1241REG_Y2K	0x37		/* Year 2K */
-#define X1241REG_SR	0x3F		/* Status register */
-
-#define X1241_CCR_ADDRESS	0x6F
-
-#define SMB_CSR(reg) (IOADDR(A_SMB_REGISTER(1, reg)))
-
-static int xicor_read(uint8_t addr)
-{
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-	__raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
-	__raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA));
-	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
-		     SMB_CSR(R_SMB_START));
-
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
-		     SMB_CSR(R_SMB_START));
-
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
-                /* Clear error bit by writing a 1 */
-                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
-                return -1;
-        }
-
-	return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
-}
-
-static int xicor_write(uint8_t addr, int b)
-{
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-	__raw_writeq(addr, SMB_CSR(R_SMB_CMD));
-	__raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
-	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
-		     SMB_CSR(R_SMB_START));
-
-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
-                ;
-
-        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
-                /* Clear error bit by writing a 1 */
-                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
-                return -1;
-        } else {
-		return 0;
-	}
-}
-
-/*
- * In order to set the CMOS clock precisely, set_rtc_mmss has to be
- * called 500 ms after the second nowtime has started, because when
- * nowtime is written into the registers of the CMOS clock, it will
- * jump to the next second precisely 500 ms later. Check the Motorola
- * MC146818A or Dallas DS12887 data sheet for details.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- *      sets the minutes. Usually you'll only notice that after reboot!
- */
-int set_rtc_mmss(unsigned long nowtime)
-{
-	int retval = 0;
-	int real_seconds, real_minutes, cmos_minutes;
-
-	cmos_minutes = xicor_read(X1241REG_MN);
-	cmos_minutes = BCD2BIN(cmos_minutes);
-
-	/*
-	 * since we're only adjusting minutes and seconds,
-	 * don't interfere with hour overflow. This avoids
-	 * messing with unknown time zones but requires your
-	 * RTC not to be off by more than 15 minutes
-	 */
-	real_seconds = nowtime % 60;
-	real_minutes = nowtime / 60;
-	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-		real_minutes += 30;		/* correct for half hour time zone */
-	real_minutes %= 60;
-
-	/* unlock writes to the CCR */
-	xicor_write(X1241REG_SR, X1241REG_SR_WEL);
-	xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
-
-	if (abs(real_minutes - cmos_minutes) < 30) {
-		real_seconds = BIN2BCD(real_seconds);
-		real_minutes = BIN2BCD(real_minutes);
-		xicor_write(X1241REG_SC, real_seconds);
-		xicor_write(X1241REG_MN, real_minutes);
-	} else {
-		printk(KERN_WARNING
-		       "set_rtc_mmss: can't update from %d to %d\n",
-		       cmos_minutes, real_minutes);
-		retval = -1;
-	}
-
-	xicor_write(X1241REG_SR, 0);
-
-	printk("set_rtc_mmss: %02d:%02d\n", real_minutes, real_seconds);
-
-	return retval;
-}
-
-static unsigned long __init get_swarm_time(void)
-{
-	unsigned int year, mon, day, hour, min, sec, y2k;
-
-	sec = xicor_read(X1241REG_SC);
-	min = xicor_read(X1241REG_MN);
-	hour = xicor_read(X1241REG_HR);
-
-	if (hour & X1241REG_HR_MIL) {
-		hour &= 0x3f;
-	} else {
-		if (hour & 0x20)
-			hour = (hour & 0xf) + 0x12;
-	}
-
-	sec = BCD2BIN(sec);
-	min = BCD2BIN(min);
-	hour = BCD2BIN(hour);
-
-	day = xicor_read(X1241REG_DT);
-	mon = xicor_read(X1241REG_MO);
-	year = xicor_read(X1241REG_YR);
-	y2k = xicor_read(X1241REG_Y2K);
-
-	day = BCD2BIN(day);
-	mon = BCD2BIN(mon);
-	year = BCD2BIN(year);
-	y2k = BCD2BIN(y2k);
-
-	year += (y2k * 100);
-
-	return mktime(year, mon, day, hour, min, sec);
-}
-
-/*
- *  Bring up the timer at 100 Hz.
- */
-void __init swarm_time_init(void)
-{
-	unsigned int flags;
-	int status;
-
-	/* Set up the scd general purpose timer 0 to cpu 0 */
-	sb1250_time_init();
-
-	/* Establish communication with the Xicor 1241 RTC */
-	/* XXXKW how do I share the SMBus with the I2C subsystem? */
-
-	__raw_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
-	__raw_writeq(0, SMB_CSR(R_SMB_CONTROL));
-
-	if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) {
-		printk("x1241: couldn't detect on SWARM SMBus 1\n");
-	} else {
-		if (status & X1241REG_SR_RTCF)
-			printk("x1241: battery failed -- time is probably wrong\n");
-		write_seqlock_irqsave(&xtime_lock, flags);
-		xtime.tv_sec = get_swarm_time();
-		xtime.tv_nsec = 0;
-		write_sequnlock_irqrestore(&xtime_lock, flags);
-	}
-}
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
index 6850a29..acc9ba7 100644
--- a/arch/mips/sni/a20r.c
+++ b/arch/mips/sni/a20r.c
@@ -87,8 +87,8 @@
 
 static struct resource snirm_53c710_rsrc[] = {
 	{
-		.start = 0xb9000000,
-		.end   = 0xb90fffff,
+		.start = 0x19000000,
+		.end   = 0x190fffff,
 		.flags = IORESOURCE_MEM
 	},
 	{
@@ -106,8 +106,8 @@
 
 static struct resource sc26xx_rsrc[] = {
 	{
-		.start = 0xbc070000,
-		.end   = 0xbc0700ff,
+		.start = 0x1c070000,
+		.end   = 0x1c0700ff,
 		.flags = IORESOURCE_MEM
 	},
 	{
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
index 4bfda02..28a11d8 100644
--- a/arch/mips/sni/rm200.c
+++ b/arch/mips/sni/rm200.c
@@ -88,8 +88,8 @@
 
 static struct resource snirm_53c710_rm200_rsrc[] = {
 	{
-		.start = 0xb9000000,
-		.end   = 0xb90fffff,
+		.start = 0x19000000,
+		.end   = 0x190fffff,
 		.flags = IORESOURCE_MEM
 	},
 	{
diff --git a/arch/mips/vr41xx/common/Makefile b/arch/mips/vr41xx/common/Makefile
index f842783..d0d84ec 100644
--- a/arch/mips/vr41xx/common/Makefile
+++ b/arch/mips/vr41xx/common/Makefile
@@ -2,4 +2,4 @@
 # Makefile for common code of the NEC VR4100 series.
 #
 
-obj-y	+= bcu.o cmu.o icu.o init.o irq.o pmu.o type.o
+obj-y	+= bcu.o cmu.o giu.o icu.o init.o irq.o pmu.o rtc.o siu.o type.o
diff --git a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c
new file mode 100644
index 0000000..d21f6f2
--- /dev/null
+++ b/arch/mips/vr41xx/common/giu.c
@@ -0,0 +1,122 @@
+/*
+ *  NEC VR4100 series GIU platform device.
+ *
+ *  Copyright (C) 2007  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+#include <asm/cpu.h>
+#include <asm/vr41xx/giu.h>
+#include <asm/vr41xx/irq.h>
+
+static struct resource giu_50pins_pullupdown_resource[] __initdata = {
+	{
+		.start	= 0x0b000100,
+		.end	= 0x0b00011f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 0x0b0002e0,
+		.end	= 0x0b0002e3,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= GIUINT_IRQ,
+		.end	= GIUINT_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource giu_36pins_resource[] __initdata = {
+	{
+		.start	= 0x0f000140,
+		.end	= 0x0f00015f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= GIUINT_IRQ,
+		.end	= GIUINT_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource giu_48pins_resource[] __initdata = {
+	{
+		.start	= 0x0f000140,
+		.end	= 0x0f000167,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= GIUINT_IRQ,
+		.end	= GIUINT_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static int __init vr41xx_giu_add(void)
+{
+	struct platform_device *pdev;
+	struct resource *res;
+	unsigned int num;
+	int retval;
+
+	pdev = platform_device_alloc("GIU", -1);
+	if (!pdev)
+		return -ENOMEM;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		pdev->id = GPIO_50PINS_PULLUPDOWN;
+		res = giu_50pins_pullupdown_resource;
+		num = ARRAY_SIZE(giu_50pins_pullupdown_resource);
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+		pdev->id = GPIO_36PINS;
+		res = giu_36pins_resource;
+		num = ARRAY_SIZE(giu_36pins_resource);
+		break;
+	case CPU_VR4133:
+		pdev->id = GPIO_48PINS_EDGE_SELECT;
+		res = giu_48pins_resource;
+		num = ARRAY_SIZE(giu_48pins_resource);
+		break;
+	default:
+		retval = -ENODEV;
+		goto err_free_device;
+	}
+
+	retval = platform_device_add_resources(pdev, res, num);
+	if (retval)
+		goto err_free_device;
+
+	retval = platform_device_add(pdev);
+	if (retval)
+		goto err_free_device;
+
+	return 0;
+
+err_free_device:
+	platform_device_put(pdev);
+
+	return retval;
+}
+device_initcall(vr41xx_giu_add);
diff --git a/arch/mips/vr41xx/common/rtc.c b/arch/mips/vr41xx/common/rtc.c
new file mode 100644
index 0000000..cce605b
--- /dev/null
+++ b/arch/mips/vr41xx/common/rtc.c
@@ -0,0 +1,117 @@
+/*
+ *  NEC VR4100 series RTC platform device.
+ *
+ *  Copyright (C) 2007  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+#include <asm/cpu.h>
+#include <asm/vr41xx/irq.h>
+
+static struct resource rtc_type1_resource[] __initdata = {
+	{
+		.start	= 0x0b0000c0,
+		.end	= 0x0b0000df,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 0x0b0001c0,
+		.end	= 0x0b0001df,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= ELAPSEDTIME_IRQ,
+		.end	= ELAPSEDTIME_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= RTCLONG1_IRQ,
+		.end	= RTCLONG1_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource rtc_type2_resource[] __initdata = {
+	{
+		.start	= 0x0f000100,
+		.end	= 0x0f00011f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 0x0f000120,
+		.end	= 0x0f00013f,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= ELAPSEDTIME_IRQ,
+		.end	= ELAPSEDTIME_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= RTCLONG1_IRQ,
+		.end	= RTCLONG1_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static int __init vr41xx_rtc_add(void)
+{
+	struct platform_device *pdev;
+	struct resource *res;
+	unsigned int num;
+	int retval;
+
+	pdev = platform_device_alloc("RTC", -1);
+	if (!pdev)
+		return -ENOMEM;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		res = rtc_type1_resource;
+		num = ARRAY_SIZE(rtc_type1_resource);
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+	case CPU_VR4133:
+		res = rtc_type2_resource;
+		num = ARRAY_SIZE(rtc_type2_resource);
+		break;
+	default:
+		retval = -ENODEV;
+		goto err_free_device;
+	}
+
+	retval = platform_device_add_resources(pdev, res, num);
+	if (retval)
+		goto err_free_device;
+
+	retval = platform_device_add(pdev);
+	if (retval)
+		goto err_free_device;
+
+	return 0;
+
+err_free_device:
+	platform_device_put(pdev);
+
+	return retval;
+}
+device_initcall(vr41xx_rtc_add);
diff --git a/arch/mips/vr41xx/common/siu.c b/arch/mips/vr41xx/common/siu.c
new file mode 100644
index 0000000..a1e7741
--- /dev/null
+++ b/arch/mips/vr41xx/common/siu.c
@@ -0,0 +1,120 @@
+/*
+ *  NEC VR4100 series SIU platform device.
+ *
+ *  Copyright (C) 2007  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+
+#include <asm/cpu.h>
+#include <asm/vr41xx/siu.h>
+
+static unsigned int siu_type1_ports[SIU_PORTS_MAX] __initdata = {
+	PORT_VR41XX_SIU,
+	PORT_UNKNOWN,
+};
+
+static struct resource siu_type1_resource[] __initdata = {
+	{
+		.start	= 0x0c000000,
+		.end	= 0x0c00000a,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= SIU_IRQ,
+		.end	= SIU_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static unsigned int siu_type2_ports[SIU_PORTS_MAX] __initdata = {
+	PORT_VR41XX_SIU,
+	PORT_VR41XX_DSIU,
+};
+
+static struct resource siu_type2_resource[] __initdata = {
+	{
+		.start	= 0x0f000800,
+		.end	= 0x0f00080a,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 0x0f000820,
+		.end	= 0x0f000829,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= SIU_IRQ,
+		.end	= SIU_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= DSIU_IRQ,
+		.end	= DSIU_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static int __init vr41xx_siu_add(void)
+{
+	struct platform_device *pdev;
+	struct resource *res;
+	unsigned int num;
+	int retval;
+
+	pdev = platform_device_alloc("SIU", -1);
+	if (!pdev)
+		return -ENOMEM;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		pdev->dev.platform_data = siu_type1_ports;
+		res = siu_type1_resource;
+		num = ARRAY_SIZE(siu_type1_resource);
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+	case CPU_VR4133:
+		pdev->dev.platform_data = siu_type2_ports;
+		res = siu_type2_resource;
+		num = ARRAY_SIZE(siu_type2_resource);
+		break;
+	default:
+		retval = -ENODEV;
+		goto err_free_device;
+	}
+
+	retval = platform_device_add_resources(pdev, res, num);
+	if (retval)
+		goto err_free_device;
+
+	retval = platform_device_add(pdev);
+	if (retval)
+		goto err_free_device;
+
+	return 0;
+
+err_free_device:
+	platform_device_put(pdev);
+
+	return retval;
+}
+device_initcall(vr41xx_siu_add);
diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c
index 4c0a7d7..615b658 100644
--- a/arch/ppc/8260_io/enet.c
+++ b/arch/ppc/8260_io/enet.c
@@ -477,9 +477,9 @@
 		}
 		else {
 			skb_put(skb,pkt_len-4);	/* Make room */
-			eth_copy_and_sum(skb,
+			skb_copy_to_linear_data(skb,
 				(unsigned char *)__va(bdp->cbd_bufaddr),
-				pkt_len-4, 0);
+				pkt_len-4);
 			skb->protocol=eth_type_trans(skb,dev);
 			netif_rx(skb);
 		}
diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c
index cab395d..6f3ed6a 100644
--- a/arch/ppc/8260_io/fcc_enet.c
+++ b/arch/ppc/8260_io/fcc_enet.c
@@ -734,9 +734,9 @@
 		}
 		else {
 			skb_put(skb,pkt_len);	/* Make room */
-			eth_copy_and_sum(skb,
+			skb_copy_to_linear_data(skb,
 				(unsigned char *)__va(bdp->cbd_bufaddr),
-				pkt_len, 0);
+				pkt_len);
 			skb->protocol=eth_type_trans(skb,dev);
 			netif_rx(skb);
 		}
diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c
index e58288e..703d47e 100644
--- a/arch/ppc/8xx_io/enet.c
+++ b/arch/ppc/8xx_io/enet.c
@@ -506,9 +506,9 @@
 		}
 		else {
 			skb_put(skb,pkt_len-4);	/* Make room */
-			eth_copy_and_sum(skb,
+			skb_copy_to_linear_data(skb,
 				cep->rx_vaddr[bdp - cep->rx_bd_base],
-				pkt_len-4, 0);
+				pkt_len-4);
 			skb->protocol=eth_type_trans(skb,dev);
 			netif_rx(skb);
 		}
diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c
index d38335d..0288279 100644
--- a/arch/ppc/8xx_io/fec.c
+++ b/arch/ppc/8xx_io/fec.c
@@ -725,7 +725,7 @@
 		fep->stats.rx_dropped++;
 	} else {
 		skb_put(skb,pkt_len-4);	/* Make room */
-		eth_copy_and_sum(skb, data, pkt_len-4, 0);
+		skb_copy_to_linear_data(skb, data, pkt_len-4);
 		skb->protocol=eth_type_trans(skb,dev);
 		netif_rx(skb);
 	}
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 8485a68..032f4b7 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -2415,7 +2415,6 @@
 	.attr = {
 		.name = "hs_reg",
 		.mode = S_IRUGO | S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size  = VAL_LEN_MAX,
 	.read  = mv64xxx_hs_reg_read,
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 82b131d..9a13b24 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -312,7 +312,6 @@
 	.attr = {
 		.name = "binary_parameter",
 		.mode = S_IRUGO,
-		.owner = THIS_MODULE,
 	},
 	.size = PAGE_SIZE,
 	.read = &ipl_parameter_read,
@@ -336,7 +335,6 @@
 	.attr = {
 		.name = "scp_data",
 		.mode = S_IRUGO,
-		.owner = THIS_MODULE,
 	},
 	.size = PAGE_SIZE,
 	.read = &ipl_scp_data_read,
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 5ce9443..8bdd25a 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -427,6 +427,10 @@
 	  This is purely to save memory - each supported CPU requires
 	  memory in the static kernel configuration.
 
+config PHYSICAL_ALIGN
+	hex
+	default "0x200000"
+
 config HOTPLUG_CPU
 	bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
 	depends on SMP && HOTPLUG && EXPERIMENTAL
diff --git a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile
index ee6f650..6709638 100644
--- a/arch/x86_64/boot/Makefile
+++ b/arch/x86_64/boot/Makefile
@@ -1,135 +1,9 @@
 #
 # arch/x86_64/boot/Makefile
 #
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1994 by Linus Torvalds
-#
+# The actual boot code is shared with i386 including the Makefile.
+# So tell kbuild that we fetch the code from i386 and include the
+# Makefile from i386 too.
 
-# ROOT_DEV specifies the default root-device when making the image.
-# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
-# the default of FLOPPY is used by 'build'.
-
-ROOT_DEV := CURRENT
-
-# If you want to preset the SVGA mode, uncomment the next line and
-# set SVGA_MODE to whatever number you want.
-# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
-# The number is the same as you would ordinarily press at bootup.
-
-SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
-
-# If you want the RAM disk device, define this to be the size in blocks.
-
-#RAMDISK := -DRAMDISK=512
-
-targets		:= vmlinux.bin bootsect bootsect.o \
-		   setup setup.o bzImage mtools.conf
-
-EXTRA_CFLAGS := -m32
-
-hostprogs-y	:= tools/build
-HOST_EXTRACFLAGS += $(LINUXINCLUDE)
-subdir-		:= compressed/	#Let make clean descend in compressed/
-# ---------------------------------------------------------------------------
-
-$(obj)/bzImage: IMAGE_OFFSET := 0x100000
-$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
-$(obj)/bzImage: BUILDFLAGS   := -b
-
-quiet_cmd_image = BUILD   $@
-cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
-	    $(obj)/vmlinux.bin $(ROOT_DEV) > $@
-
-$(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
-			      $(obj)/vmlinux.bin $(obj)/tools/build FORCE
-	$(call if_changed,image)
-	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
-
-$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
-	$(call if_changed,objcopy)
-
-LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
-LDFLAGS_setup	 := -Ttext 0x0 -s --oformat binary -e begtext
-
-$(obj)/setup $(obj)/bootsect: %: %.o FORCE
-	$(call if_changed,ld)
-
-$(obj)/compressed/vmlinux: FORCE
-	$(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
-
-# Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel
-FDARGS = 
-# Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel
-FDINITRD =
-
-image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,)
-
-$(obj)/mtools.conf: $(src)/mtools.conf.in
-	sed -e 's|@OBJ@|$(obj)|g' < $< > $@
-
-# This requires write access to /dev/fd0
-zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
-	MTOOLSRC=$(obj)/mtools.conf mformat a:			; sync
-	syslinux /dev/fd0					; sync
-	echo '$(image_cmdline)' | \
-		MTOOLSRC=$(obj)/mtools.conf mcopy - a:syslinux.cfg
-	if [ -f '$(FDINITRD)' ] ; then \
-		MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \
-	fi
-	MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux	; sync
-
-# These require being root or having syslinux 2.02 or higher installed
-fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
-	dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
-	MTOOLSRC=$(obj)/mtools.conf mformat v:			; sync
-	syslinux $(obj)/fdimage					; sync
-	echo '$(image_cmdline)' | \
-		MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg
-	if [ -f '$(FDINITRD)' ] ; then \
-		MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \
-	fi
-	MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux	; sync
-
-fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
-	dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
-	MTOOLSRC=$(obj)/mtools.conf mformat w:			; sync
-	syslinux $(obj)/fdimage					; sync
-	echo '$(image_cmdline)' | \
-		MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg
-	if [ -f '$(FDINITRD)' ] ; then \
-		MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \
-	fi
-	MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux	; sync
-
-isoimage: $(BOOTIMAGE)
-	-rm -rf $(obj)/isoimage
-	mkdir $(obj)/isoimage
-	for i in lib lib64 share end ; do \
-		if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
-			cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
-			break ; \
-		fi ; \
-		if [ $$i = end ] ; then exit 1 ; fi ; \
-	done
-	cp $(BOOTIMAGE) $(obj)/isoimage/linux
-	echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg
-	if [ -f '$(FDINITRD)' ] ; then \
-		cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \
-	fi
-	mkisofs -J -r -o $(obj)/image.iso -b isolinux.bin -c boot.cat \
-		-no-emul-boot -boot-load-size 4 -boot-info-table \
-		$(obj)/isoimage
-	rm -rf $(obj)/isoimage
-
-zlilo: $(BOOTIMAGE)
-	if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
-	if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
-	cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
-	cp System.map $(INSTALL_PATH)/
-	if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
-
-install:
-	sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
+src := arch/i386/boot
+include $(src)/Makefile
diff --git a/arch/x86_64/boot/bootsect.S b/arch/x86_64/boot/bootsect.S
deleted file mode 100644
index 011b7a4..0000000
--- a/arch/x86_64/boot/bootsect.S
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *	bootsect.S		Copyright (C) 1991, 1992 Linus Torvalds
- *
- *	modified by Drew Eckhardt
- *	modified by Bruce Evans (bde)
- *	modified by Chris Noe (May 1999) (as86 -> gas)
- *	gutted by H. Peter Anvin (Jan 2003)
- *
- * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
- * addresses must be multiplied by 16 to obtain their respective linear
- * addresses. To avoid confusion, linear addresses are written using leading
- * hex while segment addresses are written as segment:offset.
- *
- */
-
-#include <asm/boot.h>
-
-SETUPSECTS	= 4			/* default nr of setup-sectors */
-BOOTSEG		= 0x07C0		/* original address of boot-sector */
-INITSEG		= DEF_INITSEG		/* we move boot here - out of the way */
-SETUPSEG	= DEF_SETUPSEG		/* setup starts here */
-SYSSEG		= DEF_SYSSEG		/* system loaded at 0x10000 (65536) */
-SYSSIZE		= DEF_SYSSIZE		/* system size: # of 16-byte clicks */
-					/* to be loaded */
-ROOT_DEV	= 0 			/* ROOT_DEV is now written by "build" */
-SWAP_DEV	= 0			/* SWAP_DEV is now written by "build" */
-
-#ifndef SVGA_MODE
-#define SVGA_MODE ASK_VGA
-#endif
-
-#ifndef RAMDISK
-#define RAMDISK 0
-#endif
-
-#ifndef ROOT_RDONLY
-#define ROOT_RDONLY 1
-#endif
-
-.code16
-.text
-
-.global _start
-_start:
-
-	# Normalize the start address
-	jmpl	$BOOTSEG, $start2
-
-start2:
-	movw	%cs, %ax
-	movw	%ax, %ds
-	movw	%ax, %es
-	movw	%ax, %ss
-	movw	$0x7c00, %sp
-	sti
-	cld
-
-	movw	$bugger_off_msg, %si
-
-msg_loop:
-	lodsb
-	andb	%al, %al
-	jz	die
-	movb	$0xe, %ah
-	movw	$7, %bx
-	int	$0x10
-	jmp	msg_loop
-
-die:
-	# Allow the user to press a key, then reboot
-	xorw	%ax, %ax
-	int	$0x16
-	int	$0x19
-
-	# int 0x19 should never return.  In case it does anyway,
-	# invoke the BIOS reset code...
-	ljmp	$0xf000,$0xfff0
-
-
-bugger_off_msg:
-	.ascii	"Direct booting from floppy is no longer supported.\r\n"
-	.ascii	"Please use a boot loader program instead.\r\n"
-	.ascii	"\n"
-	.ascii	"Remove disk and press any key to reboot . . .\r\n"
-	.byte	0
-
-
-	# Kernel attributes; used by setup
-
-	.org 497
-setup_sects:	.byte SETUPSECTS
-root_flags:	.word ROOT_RDONLY
-syssize:	.word SYSSIZE
-swap_dev:	.word SWAP_DEV
-ram_size:	.word RAMDISK
-vid_mode:	.word SVGA_MODE
-root_dev:	.word ROOT_DEV
-boot_flag:	.word 0xAA55
diff --git a/arch/x86_64/boot/compressed/Makefile b/arch/x86_64/boot/compressed/Makefile
index 705a3e3..c9f2da7 100644
--- a/arch/x86_64/boot/compressed/Makefile
+++ b/arch/x86_64/boot/compressed/Makefile
@@ -7,11 +7,12 @@
 #
 
 targets		:= vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
-EXTRA_AFLAGS	:= -traditional
 
-# cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with
-# -m32
-CFLAGS := -m64 -D__KERNEL__ -Iinclude -O2  -fno-strict-aliasing -fPIC -mcmodel=small -fno-builtin
+CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2  \
+	  -fno-strict-aliasing -fPIC -mcmodel=small \
+	   $(call cc-option, -ffreestanding) \
+	   $(call cc-option, -fno-stack-protector)
+AFLAGS  := $(CFLAGS) -D__ASSEMBLY__
 LDFLAGS := -m elf_x86_64
 
 LDFLAGS_vmlinux := -T
diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S
index f9d5692..1312bfa 100644
--- a/arch/x86_64/boot/compressed/head.S
+++ b/arch/x86_64/boot/compressed/head.S
@@ -46,10 +46,10 @@
  * at and where we were actually loaded at.  This can only be done
  * with a short local call on x86.  Nothing  else will tell us what
  * address we are running at.  The reserved chunk of the real-mode
- * data at 0x34-0x3f are used as the stack for this calculation.
- * Only 4 bytes are needed.
+ * data at 0x1e4 (defined as a scratch field) are used as the stack
+ * for this calculation. Only 4 bytes are needed.
  */
-	leal	0x40(%esi), %esp
+	leal	(0x1e4+4)(%esi), %esp
 	call	1f
 1:	popl	%ebp
 	subl	$1b, %ebp
diff --git a/arch/x86_64/boot/install.sh b/arch/x86_64/boot/install.sh
deleted file mode 100644
index baaa236..0000000
--- a/arch/x86_64/boot/install.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-. $srctree/arch/i386/boot/install.sh
diff --git a/arch/x86_64/boot/mtools.conf.in b/arch/x86_64/boot/mtools.conf.in
deleted file mode 100644
index efd6d24..0000000
--- a/arch/x86_64/boot/mtools.conf.in
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# mtools configuration file for "make (b)zdisk"
-#
-
-# Actual floppy drive
-drive a:
-  file="/dev/fd0"
-
-# 1.44 MB floppy disk image
-drive v:
-  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter
-
-# 2.88 MB floppy disk image (mostly for virtual uses)
-drive w:
-  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter
-
-
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S
deleted file mode 100644
index e9e33f9..0000000
--- a/arch/x86_64/boot/setup.S
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
- *	setup.S		Copyright (C) 1991, 1992 Linus Torvalds
- *
- * setup.s is responsible for getting the system data from the BIOS,
- * and putting them into the appropriate places in system memory.
- * both setup.s and system has been loaded by the bootblock.
- *
- * This code asks the bios for memory/disk/other parameters, and
- * puts them in a "safe" place: 0x90000-0x901FF, ie where the
- * boot-block used to be. It is then up to the protected mode
- * system to read them from there before the area is overwritten
- * for buffer-blocks.
- *
- * Move PS/2 aux init code to psaux.c
- * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
- *
- * some changes and additional features by Christoph Niemann,
- * March 1993/June 1994 (Christoph.Niemann@linux.org)
- *
- * add APM BIOS checking by Stephen Rothwell, May 1994
- * (sfr@canb.auug.org.au)
- *
- * High load stuff, initrd support and position independency
- * by Hans Lermen & Werner Almesberger, February 1996
- * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
- *
- * Video handling moved to video.S by Martin Mares, March 1996
- * <mj@k332.feld.cvut.cz>
- *
- * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
- * parsons) to avoid loadlin confusion, July 1997
- *
- * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
- * <stiker@northlink.com>
- *
- * Fix to work around buggy BIOSes which don't use carry bit correctly
- * and/or report extended memory in CX/DX for e801h memory size detection 
- * call.  As a result the kernel got wrong figures.  The int15/e801h docs
- * from Ralf Brown interrupt list seem to indicate AX/BX should be used
- * anyway.  So to avoid breaking many machines (presumably there was a reason
- * to orginally use CX/DX instead of AX/BX), we do a kludge to see
- * if CX/DX have been changed in the e801 call and if so use AX/BX .
- * Michael Miller, April 2001 <michaelm@mjmm.org>
- *
- * Added long mode checking and SSE force. March 2003, Andi Kleen.		
- */
-
-#include <asm/segment.h>
-#include <linux/utsrelease.h>
-#include <linux/compile.h>
-#include <asm/boot.h>
-#include <asm/e820.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-
-/* Signature words to ensure LILO loaded us right */
-#define SIG1	0xAA55
-#define SIG2	0x5A5A
-
-INITSEG  = DEF_INITSEG		# 0x9000, we move boot here, out of the way
-SYSSEG   = DEF_SYSSEG		# 0x1000, system loaded at 0x10000 (65536).
-SETUPSEG = DEF_SETUPSEG		# 0x9020, this is the current segment
-				# ... and the former contents of CS
-
-DELTA_INITSEG = SETUPSEG - INITSEG	# 0x0020
-
-.code16
-.globl begtext, begdata, begbss, endtext, enddata, endbss
-
-.text
-begtext:
-.data
-begdata:
-.bss
-begbss:
-.text
-
-start:
-	jmp	trampoline
-
-# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
-
-		.ascii	"HdrS"		# header signature
-		.word	0x0206		# header version number (>= 0x0105)
-					# or else old loadlin-1.5 will fail)
-realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
-start_sys_seg:	.word	SYSSEG
-		.word	kernel_version	# pointing to kernel version string
-					# above section of header is compatible
-					# with loadlin-1.5 (header v1.5). Don't
-					# change it.
-
-type_of_loader:	.byte	0		# = 0, old one (LILO, Loadlin,
-					#      Bootlin, SYSLX, bootsect...)
-					# See Documentation/i386/boot.txt for
-					# assigned ids
-	
-# flags, unused bits must be zero (RFU) bit within loadflags
-loadflags:
-LOADED_HIGH	= 1			# If set, the kernel is loaded high
-CAN_USE_HEAP	= 0x80			# If set, the loader also has set
-					# heap_end_ptr to tell how much
-					# space behind setup.S can be used for
-					# heap purposes.
-					# Only the loader knows what is free
-#ifndef __BIG_KERNEL__
-		.byte	0
-#else
-		.byte	LOADED_HIGH
-#endif
-
-setup_move_size: .word  0x8000		# size to move, when setup is not
-					# loaded at 0x90000. We will move setup 
-					# to 0x90000 then just before jumping
-					# into the kernel. However, only the
-					# loader knows how much data behind
-					# us also needs to be loaded.
-
-code32_start:				# here loaders can put a different
-					# start address for 32-bit code.
-#ifndef __BIG_KERNEL__
-		.long	0x1000		#   0x1000 = default for zImage
-#else
-		.long	0x100000	# 0x100000 = default for big kernel
-#endif
-
-ramdisk_image:	.long	0		# address of loaded ramdisk image
-					# Here the loader puts the 32-bit
-					# address where it loaded the image.
-					# This only will be read by the kernel.
-
-ramdisk_size:	.long	0		# its size in bytes
-
-bootsect_kludge:
-		.long	0		# obsolete
-
-heap_end_ptr:	.word	modelist+1024	# (Header version 0x0201 or later)
-					# space from here (exclusive) down to
-					# end of setup code can be used by setup
-					# for local heap purposes.
-
-pad1:		.word	0
-cmd_line_ptr:	.long 0			# (Header version 0x0202 or later)
-					# If nonzero, a 32-bit pointer
-					# to the kernel command line.
-					# The command line should be
-					# located between the start of
-					# setup and the end of low
-					# memory (0xa0000), or it may
-					# get overwritten before it
-					# gets read.  If this field is
-					# used, there is no longer
-					# anything magical about the
-					# 0x90000 segment; the setup
-					# can be located anywhere in
-					# low memory 0x10000 or higher.
-
-ramdisk_max:	.long 0xffffffff
-kernel_alignment:  .long 0x200000       # physical addr alignment required for
-					# protected mode relocatable kernel
-#ifdef CONFIG_RELOCATABLE
-relocatable_kernel:    .byte 1
-#else
-relocatable_kernel:    .byte 0
-#endif
-pad2:                  .byte 0
-pad3:                  .word 0
-
-cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
-                                                #added with boot protocol
-                                                #version 2.06
-
-trampoline:	call	start_of_setup
-		.align 16
-					# The offset at this point is 0x240
-		.space  (0xeff-0x240+1)	# E820 & EDD space (ending at 0xeff)
-# End of setup header #####################################################
-
-start_of_setup:
-# Bootlin depends on this being done early
-	movw	$0x01500, %ax
-	movb	$0x81, %dl
-	int	$0x13
-
-#ifdef SAFE_RESET_DISK_CONTROLLER
-# Reset the disk controller.
-	movw	$0x0000, %ax
-	movb	$0x80, %dl
-	int	$0x13
-#endif
-
-# Set %ds = %cs, we know that SETUPSEG = %cs at this point
-	movw	%cs, %ax		# aka SETUPSEG
-	movw	%ax, %ds
-# Check signature at end of setup
-	cmpw	$SIG1, setup_sig1
-	jne	bad_sig
-
-	cmpw	$SIG2, setup_sig2
-	jne	bad_sig
-
-	jmp	good_sig1
-
-# Routine to print asciiz string at ds:si
-prtstr:
-	lodsb
-	andb	%al, %al
-	jz	fin
-
-	call	prtchr
-	jmp	prtstr
-
-fin:	ret
-
-# Space printing
-prtsp2:	call	prtspc		# Print double space
-prtspc:	movb	$0x20, %al	# Print single space (note: fall-thru)
-
-prtchr:	
-	pushw	%ax
-	pushw	%cx
-	movw	$0007,%bx
-	movw	$0x01, %cx
-	movb	$0x0e, %ah
-	int	$0x10
-	popw	%cx
-	popw	%ax
-	ret
-
-beep:	movb	$0x07, %al
-	jmp	prtchr
-	
-no_sig_mess: .string	"No setup signature found ..."
-
-good_sig1:
-	jmp	good_sig
-
-# We now have to find the rest of the setup code/data
-bad_sig:
-	movw	%cs, %ax			# SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# INITSEG
-	movw	%ax, %ds
-	xorb	%bh, %bh
-	movb	(497), %bl			# get setup sect from bootsect
-	subw	$4, %bx				# LILO loads 4 sectors of setup
-	shlw	$8, %bx				# convert to words (1sect=2^8 words)
-	movw	%bx, %cx
-	shrw	$3, %bx				# convert to segment
-	addw	$SYSSEG, %bx
-	movw	%bx, %cs:start_sys_seg
-# Move rest of setup code/data to here
-	movw	$2048, %di			# four sectors loaded by LILO
-	subw	%si, %si
-	movw	%cs, %ax			# aka SETUPSEG
-	movw	%ax, %es
-	movw	$SYSSEG, %ax
-	movw	%ax, %ds
-	rep
-	movsw
-	movw	%cs, %ax			# aka SETUPSEG
-	movw	%ax, %ds
-	cmpw	$SIG1, setup_sig1
-	jne	no_sig
-
-	cmpw	$SIG2, setup_sig2
-	jne	no_sig
-
-	jmp	good_sig
-
-no_sig:
-	lea	no_sig_mess, %si
-	call	prtstr
-
-no_sig_loop:
-	jmp	no_sig_loop
-
-good_sig:
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax 		# aka INITSEG
-	movw	%ax, %ds
-# Check if an old loader tries to load a big-kernel
-	testb	$LOADED_HIGH, %cs:loadflags	# Do we have a big kernel?
-	jz	loader_ok			# No, no danger for old loaders.
-
-	cmpb	$0, %cs:type_of_loader 		# Do we have a loader that
-						# can deal with us?
-	jnz	loader_ok			# Yes, continue.
-
-	pushw	%cs				# No, we have an old loader,
-	popw	%ds				# die. 
-	lea	loader_panic_mess, %si
-	call	prtstr
-
-	jmp	no_sig_loop
-
-loader_panic_mess: .string "Wrong loader, giving up..."
-
-loader_ok:
-	/* check for long mode. */
-	/* we have to do this before the VESA setup, otherwise the user
-	   can't see the error message. */
-	
-	pushw	%ds
-	movw	%cs,%ax
-	movw	%ax,%ds
-	
-	call verify_cpu
-	testl %eax,%eax
-	jz sse_ok
-
-no_longmode:
-	call	beep
-	lea	long_mode_panic,%si
-	call	prtstr
-no_longmode_loop:		
-	jmp	no_longmode_loop
-long_mode_panic:
-	.string "Your CPU does not support long mode. Use a 32bit distribution."
-	.byte 0
-
-#include "../kernel/verify_cpu.S"
-sse_ok:
-	popw	%ds
-	
-# tell BIOS we want to go to long mode
-	movl  $0xec00,%eax	# declare target operating mode
-	movl  $2,%ebx		# long mode
-	int $0x15			
-	
-# Get memory size (extended mem, kB)
-
-	xorl	%eax, %eax
-	movl	%eax, (0x1e0)
-#ifndef STANDARD_MEMORY_BIOS_CALL
-	movb	%al, (E820NR)
-# Try three different memory detection schemes.  First, try
-# e820h, which lets us assemble a memory map, then try e801h,
-# which returns a 32-bit memory size, and finally 88h, which
-# returns 0-64m
-
-# method E820H:
-# the memory map from hell.  e820h returns memory classified into
-# a whole bunch of different types, and allows memory holes and
-# everything.  We scan through this memory map and build a list
-# of the first 32 memory areas, which we return at [E820MAP].
-# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
-
-#define SMAP  0x534d4150
-
-meme820:
-	xorl	%ebx, %ebx			# continuation counter
-	movw	$E820MAP, %di			# point into the whitelist
-						# so we can have the bios
-						# directly write into it.
-
-jmpe820:
-	movl	$0x0000e820, %eax		# e820, upper word zeroed
-	movl	$SMAP, %edx			# ascii 'SMAP'
-	movl	$20, %ecx			# size of the e820rec
-	pushw	%ds				# data record.
-	popw	%es
-	int	$0x15				# make the call
-	jc	bail820				# fall to e801 if it fails
-
-	cmpl	$SMAP, %eax			# check the return is `SMAP'
-	jne	bail820				# fall to e801 if it fails
-
-#	cmpl	$1, 16(%di)			# is this usable memory?
-#	jne	again820
-
-	# If this is usable memory, we save it by simply advancing %di by
-	# sizeof(e820rec).
-	#
-good820:
-	movb	(E820NR), %al			# up to 128 entries
-	cmpb	$E820MAX, %al
-	jae	bail820
-
-	incb	(E820NR)
-	movw	%di, %ax
-	addw	$20, %ax
-	movw	%ax, %di
-again820:
-	cmpl	$0, %ebx			# check to see if
-	jne	jmpe820				# %ebx is set to EOF
-bail820:
-
-
-# method E801H:
-# memory size is in 1k chunksizes, to avoid confusing loadlin.
-# we store the 0xe801 memory size in a completely different place,
-# because it will most likely be longer than 16 bits.
-# (use 1e0 because that's what Larry Augustine uses in his
-# alternative new memory detection scheme, and it's sensible
-# to write everything into the same place.)
-
-meme801:
-	stc					# fix to work around buggy
-	xorw	%cx,%cx				# BIOSes which don't clear/set
-	xorw	%dx,%dx				# carry on pass/error of
-						# e801h memory size call
-						# or merely pass cx,dx though
-						# without changing them.
-	movw	$0xe801, %ax
-	int	$0x15
-	jc	mem88
-
-	cmpw	$0x0, %cx			# Kludge to handle BIOSes
-	jne	e801usecxdx			# which report their extended
-	cmpw	$0x0, %dx			# memory in AX/BX rather than
-	jne	e801usecxdx			# CX/DX.  The spec I have read
-	movw	%ax, %cx			# seems to indicate AX/BX 
-	movw	%bx, %dx			# are more reasonable anyway...
-
-e801usecxdx:
-	andl	$0xffff, %edx			# clear sign extend
-	shll	$6, %edx			# and go from 64k to 1k chunks
-	movl	%edx, (0x1e0)			# store extended memory size
-	andl	$0xffff, %ecx			# clear sign extend
- 	addl	%ecx, (0x1e0)			# and add lower memory into
-						# total size.
-
-# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
-# 64mb, depending on the bios) in ax.
-mem88:
-
-#endif
-	movb	$0x88, %ah
-	int	$0x15
-	movw	%ax, (2)
-
-# Set the keyboard repeat rate to the max
-	movw	$0x0305, %ax
-	xorw	%bx, %bx
-	int	$0x16
-
-# Check for video adapter and its parameters and allow the
-# user to browse video modes.
-	call	video				# NOTE: we need %ds pointing
-						# to bootsector
-
-# Get hd0 data...
-	xorw	%ax, %ax
-	movw	%ax, %ds
-	ldsw	(4 * 0x41), %si
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	pushw	%ax
-	movw	%ax, %es
-	movw	$0x0080, %di
-	movw	$0x10, %cx
-	pushw	%cx
-	cld
-	rep
- 	movsb
-# Get hd1 data...
-	xorw	%ax, %ax
-	movw	%ax, %ds
-	ldsw	(4 * 0x46), %si
-	popw	%cx
-	popw	%es
-	movw	$0x0090, %di
-	rep
-	movsb
-# Check that there IS a hd1 :-)
-	movw	$0x01500, %ax
-	movb	$0x81, %dl
-	int	$0x13
-	jc	no_disk1
-	
-	cmpb	$3, %ah
-	je	is_disk1
-
-no_disk1:
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax 		# aka INITSEG
-	movw	%ax, %es
-	movw	$0x0090, %di
-	movw	$0x10, %cx
-	xorw	%ax, %ax
-	cld
-	rep
-	stosb
-is_disk1:
-
-# Check for PS/2 pointing device
-	movw	%cs, %ax			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	movw	%ax, %ds
-	movb	$0, (0x1ff)			# default is no pointing device
-	int	$0x11				# int 0x11: equipment list
-	testb	$0x04, %al			# check if mouse installed
-	jz	no_psmouse
-
-	movb	$0xAA, (0x1ff)			# device present
-no_psmouse:
-
-#include "../../i386/boot/edd.S"
-
-# Now we want to move to protected mode ...
-	cmpw	$0, %cs:realmode_swtch
-	jz	rmodeswtch_normal
-
-	lcall	*%cs:realmode_swtch
-
-	jmp	rmodeswtch_end
-
-rmodeswtch_normal:
-        pushw	%cs
-	call	default_switch
-
-rmodeswtch_end:
-# we get the code32 start address and modify the below 'jmpi'
-# (loader may have changed it)
-	movl	%cs:code32_start, %eax
-	movl	%eax, %cs:code32
-
-# Now we move the system to its rightful place ... but we check if we have a
-# big-kernel. In that case we *must* not move it ...
-	testb	$LOADED_HIGH, %cs:loadflags
-	jz	do_move0			# .. then we have a normal low
-						# loaded zImage
-						# .. or else we have a high
-						# loaded bzImage
-	jmp	end_move			# ... and we skip moving
-
-do_move0:
-	movw	$0x100, %ax			# start of destination segment
-	movw	%cs, %bp			# aka SETUPSEG
-	subw	$DELTA_INITSEG, %bp		# aka INITSEG
-	movw	%cs:start_sys_seg, %bx		# start of source segment
-	cld
-do_move:
-	movw	%ax, %es			# destination segment
-	incb	%ah				# instead of add ax,#0x100
-	movw	%bx, %ds			# source segment
-	addw	$0x100, %bx
-	subw	%di, %di
-	subw	%si, %si
-	movw 	$0x800, %cx
-	rep
-	movsw
-	cmpw	%bp, %bx			# assume start_sys_seg > 0x200,
-						# so we will perhaps read one
-						# page more than needed, but
-						# never overwrite INITSEG
-						# because destination is a
-						# minimum one page below source
-	jb	do_move
-
-end_move:
-# then we load the segment descriptors
-	movw	%cs, %ax			# aka SETUPSEG
-	movw	%ax, %ds
-		
-# Check whether we need to be downward compatible with version <=201
-	cmpl	$0, cmd_line_ptr
-	jne	end_move_self		# loader uses version >=202 features
-	cmpb	$0x20, type_of_loader
-	je	end_move_self		# bootsect loader, we know of it
-
-# Boot loader doesnt support boot protocol version 2.02.
-# If we have our code not at 0x90000, we need to move it there now.
-# We also then need to move the params behind it (commandline)
-# Because we would overwrite the code on the current IP, we move
-# it in two steps, jumping high after the first one.
-	movw	%cs, %ax
-	cmpw	$SETUPSEG, %ax
-	je	end_move_self
-
-	cli					# make sure we really have
-						# interrupts disabled !
-						# because after this the stack
-						# should not be used
-	subw	$DELTA_INITSEG, %ax		# aka INITSEG
-	movw	%ss, %dx
-	cmpw	%ax, %dx
-	jb	move_self_1
-
-	addw	$INITSEG, %dx
-	subw	%ax, %dx			# this will go into %ss after
-						# the move
-move_self_1:
-	movw	%ax, %ds
-	movw	$INITSEG, %ax			# real INITSEG
-	movw	%ax, %es
-	movw	%cs:setup_move_size, %cx
-	std					# we have to move up, so we use
-						# direction down because the
-						# areas may overlap
-	movw	%cx, %di
-	decw	%di
-	movw	%di, %si
-	subw	$move_self_here+0x200, %cx
-	rep
-	movsb
-	ljmp	$SETUPSEG, $move_self_here
-
-move_self_here:
-	movw	$move_self_here+0x200, %cx
-	rep
-	movsb
-	movw	$SETUPSEG, %ax
-	movw	%ax, %ds
-	movw	%dx, %ss
-end_move_self:					# now we are at the right place
-	lidt	idt_48				# load idt with 0,0
-	xorl	%eax, %eax			# Compute gdt_base
-	movw	%ds, %ax			# (Convert %ds:gdt to a linear ptr)
-	shll	$4, %eax
-	addl	$gdt, %eax
-	movl	%eax, (gdt_48+2)
-	lgdt	gdt_48				# load gdt with whatever is
-						# appropriate
-
-# that was painless, now we enable a20
-	call	empty_8042
-
-	movb	$0xD1, %al			# command write
-	outb	%al, $0x64
-	call	empty_8042
-
-	movb	$0xDF, %al			# A20 on
-	outb	%al, $0x60
-	call	empty_8042
-
-#
-#	You must preserve the other bits here. Otherwise embarrasing things
-#	like laptops powering off on boot happen. Corrected version by Kira
-#	Brown from Linux 2.2
-#
-	inb	$0x92, %al			# 
-	orb	$02, %al			# "fast A20" version
-	outb	%al, $0x92			# some chips have only this
-
-# wait until a20 really *is* enabled; it can take a fair amount of
-# time on certain systems; Toshiba Tecras are known to have this
-# problem.  The memory location used here (0x200) is the int 0x80
-# vector, which should be safe to use.
-
-	xorw	%ax, %ax			# segment 0x0000
-	movw	%ax, %fs
-	decw	%ax				# segment 0xffff (HMA)
-	movw	%ax, %gs
-a20_wait:
-	incw	%ax				# unused memory location <0xfff0
-	movw	%ax, %fs:(0x200)		# we use the "int 0x80" vector
-	cmpw	%gs:(0x210), %ax		# and its corresponding HMA addr
-	je	a20_wait			# loop until no longer aliased
-
-# make sure any possible coprocessor is properly reset..
-	xorw	%ax, %ax
-	outb	%al, $0xf0
-	call	delay
-
-	outb	%al, $0xf1
-	call	delay
-
-# well, that went ok, I hope. Now we mask all interrupts - the rest
-# is done in init_IRQ().
-	movb	$0xFF, %al			# mask all interrupts for now
-	outb	%al, $0xA1
-	call	delay
-	
-	movb	$0xFB, %al			# mask all irq's but irq2 which
-	outb	%al, $0x21			# is cascaded
-
-# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
-# need no steenking BIOS anyway (except for the initial loading :-).
-# The BIOS-routine wants lots of unnecessary data, and it's less
-# "interesting" anyway. This is how REAL programmers do it.
-#
-# Well, now's the time to actually move into protected mode. To make
-# things as simple as possible, we do no register set-up or anything,
-# we let the gnu-compiled 32-bit programs do that. We just jump to
-# absolute address 0x1000 (or the loader supplied one),
-# in 32-bit protected mode.
-#
-# Note that the short jump isn't strictly needed, although there are
-# reasons why it might be a good idea. It won't hurt in any case.
-	movw	$1, %ax				# protected mode (PE) bit
-	lmsw	%ax				# This is it!
-	jmp	flush_instr
-
-flush_instr:
-	xorw	%bx, %bx			# Flag to indicate a boot
-	xorl	%esi, %esi			# Pointer to real-mode code
-	movw	%cs, %si
-	subw	$DELTA_INITSEG, %si
-	shll	$4, %esi			# Convert to 32-bit pointer
-# NOTE: For high loaded big kernels we need a
-#	jmpi    0x100000,__KERNEL_CS
-#
-#	but we yet haven't reloaded the CS register, so the default size 
-#	of the target offset still is 16 bit.
-#	However, using an operand prefix (0x66), the CPU will properly
-#	take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
-#	Manual, Mixing 16-bit and 32-bit code, page 16-6)
-
-	.byte 0x66, 0xea			# prefix + jmpi-opcode
-code32:	.long	0x1000				# will be set to 0x100000
-						# for big kernels
-	.word	__KERNEL_CS
-
-# Here's a bunch of information about your current kernel..
-kernel_version:	.ascii	UTS_RELEASE
-		.ascii	" ("
-		.ascii	LINUX_COMPILE_BY
-		.ascii	"@"
-		.ascii	LINUX_COMPILE_HOST
-		.ascii	") "
-		.ascii	UTS_VERSION
-		.byte	0
-
-# This is the default real mode switch routine.
-# to be called just before protected mode transition
-default_switch:
-	cli					# no interrupts allowed !
-	movb	$0x80, %al			# disable NMI for bootup
-						# sequence
-	outb	%al, $0x70
-	lret
-
-
-# This routine checks that the keyboard command queue is empty
-# (after emptying the output buffers)
-#
-# Some machines have delusions that the keyboard buffer is always full
-# with no keyboard attached...
-#
-# If there is no keyboard controller, we will usually get 0xff
-# to all the reads.  With each IO taking a microsecond and
-# a timeout of 100,000 iterations, this can take about half a
-# second ("delay" == outb to port 0x80). That should be ok,
-# and should also be plenty of time for a real keyboard controller
-# to empty.
-#
-
-empty_8042:
-	pushl	%ecx
-	movl	$100000, %ecx
-
-empty_8042_loop:
-	decl	%ecx
-	jz	empty_8042_end_loop
-
-	call	delay
-
-	inb	$0x64, %al			# 8042 status port
-	testb	$1, %al				# output buffer?
-	jz	no_output
-
-	call	delay
-	inb	$0x60, %al			# read it
-	jmp	empty_8042_loop
-
-no_output:
-	testb	$2, %al				# is input buffer full?
-	jnz	empty_8042_loop			# yes - loop
-empty_8042_end_loop:
-	popl	%ecx
-	ret
-
-# Read the cmos clock. Return the seconds in al
-gettime:
-	pushw	%cx
-	movb	$0x02, %ah
-	int	$0x1a
-	movb	%dh, %al			# %dh contains the seconds
-	andb	$0x0f, %al
-	movb	%dh, %ah
-	movb	$0x04, %cl
-	shrb	%cl, %ah
-	aad
-	popw	%cx
-	ret
-
-# Delay is needed after doing I/O
-delay:
-	outb	%al,$0x80
-	ret
-
-# Descriptor tables
-gdt:
-	.word	0, 0, 0, 0			# dummy
-
-	.word	0, 0, 0, 0			# unused
-
-	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
-	.word	0				# base address = 0
-	.word	0x9A00				# code read/exec
-	.word	0x00CF				# granularity = 4096, 386
-						#  (+5th nibble of limit)
-
-	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
-	.word	0				# base address = 0
-	.word	0x9200				# data read/write
-	.word	0x00CF				# granularity = 4096, 386
-						#  (+5th nibble of limit)
-gdt_end:
-idt_48:
-	.word	0				# idt limit = 0
-	.word	0, 0				# idt base = 0L
-gdt_48:
-	.word	gdt_end-gdt-1			# gdt limit
-	.word	0, 0				# gdt base (filled in later)
-
-# Include video setup & detection code
-
-#include "../../i386/boot/video.S"
-
-# Setup signature -- must be last
-setup_sig1:	.word	SIG1
-setup_sig2:	.word	SIG2
-
-# After this point, there is some free space which is used by the video mode
-# handling code to store the temporary mode table (not used by the kernel).
-
-modelist:
-
-.text
-endtext:
-.data
-enddata:
-.bss
-endbss:
diff --git a/arch/x86_64/boot/tools/build.c b/arch/x86_64/boot/tools/build.c
deleted file mode 100644
index eae8669..0000000
--- a/arch/x86_64/boot/tools/build.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *  Copyright (C) 1997 Martin Mares
- */
-
-/*
- * This file builds a disk-image from three different files:
- *
- * - bootsect: compatibility mbr which prints an error message if
- *             someone tries to boot the kernel directly.
- * - setup: 8086 machine code, sets up system parm
- * - system: 80386 code for actual system
- *
- * It does some checking that all files are of the correct type, and
- * just writes the result to stdout, removing headers and padding to
- * the right amount. It also writes some system data to stderr.
- */
-
-/*
- * Changes by tytso to allow root device specification
- * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
- * Cross compiling fixes by Gertjan van Wingerde, July 1996
- * Rewritten by Martin Mares, April 1997
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <asm/boot.h>
-
-typedef unsigned char byte;
-typedef unsigned short word;
-typedef unsigned long u32;
-
-#define DEFAULT_MAJOR_ROOT 0
-#define DEFAULT_MINOR_ROOT 0
-
-/* Minimal number of setup sectors (see also bootsect.S) */
-#define SETUP_SECTS 4
-
-byte buf[1024];
-int fd;
-int is_big_kernel;
-
-void die(const char * str, ...)
-{
-	va_list args;
-	va_start(args, str);
-	vfprintf(stderr, str, args);
-	fputc('\n', stderr);
-	exit(1);
-}
-
-void file_open(const char *name)
-{
-	if ((fd = open(name, O_RDONLY, 0)) < 0)
-		die("Unable to open `%s': %m", name);
-}
-
-void usage(void)
-{
-	die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
-}
-
-int main(int argc, char ** argv)
-{
-	unsigned int i, c, sz, setup_sectors;
-	u32 sys_size;
-	byte major_root, minor_root;
-	struct stat sb;
-
-	if (argc > 2 && !strcmp(argv[1], "-b"))
-	  {
-	    is_big_kernel = 1;
-	    argc--, argv++;
-	  }
-	if ((argc < 4) || (argc > 5))
-		usage();
-	if (argc > 4) {
-		if (!strcmp(argv[4], "CURRENT")) {
-			if (stat("/", &sb)) {
-				perror("/");
-				die("Couldn't stat /");
-			}
-			major_root = major(sb.st_dev);
-			minor_root = minor(sb.st_dev);
-		} else if (strcmp(argv[4], "FLOPPY")) {
-			if (stat(argv[4], &sb)) {
-				perror(argv[4]);
-				die("Couldn't stat root device.");
-			}
-			major_root = major(sb.st_rdev);
-			minor_root = minor(sb.st_rdev);
-		} else {
-			major_root = 0;
-			minor_root = 0;
-		}
-	} else {
-		major_root = DEFAULT_MAJOR_ROOT;
-		minor_root = DEFAULT_MINOR_ROOT;
-	}
-	fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
-
-	file_open(argv[1]);
-	i = read(fd, buf, sizeof(buf));
-	fprintf(stderr,"Boot sector %d bytes.\n",i);
-	if (i != 512)
-		die("Boot block must be exactly 512 bytes");
-	if (buf[510] != 0x55 || buf[511] != 0xaa)
-		die("Boot block hasn't got boot flag (0xAA55)");
-	buf[508] = minor_root;
-	buf[509] = major_root;
-	if (write(1, buf, 512) != 512)
-		die("Write call failed");
-	close (fd);
-
-	file_open(argv[2]);				    /* Copy the setup code */
-	for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
-		if (write(1, buf, c) != c)
-			die("Write call failed");
-	if (c != 0)
-		die("read-error on `setup'");
-	close (fd);
-
-	setup_sectors = (i + 511) / 512;	/* Pad unused space with zeros */
-	/* for compatibility with ancient versions of LILO. */
-	if (setup_sectors < SETUP_SECTS)
-		setup_sectors = SETUP_SECTS;
-	fprintf(stderr, "Setup is %d bytes.\n", i);
-	memset(buf, 0, sizeof(buf));
-	while (i < setup_sectors * 512) {
-		c = setup_sectors * 512 - i;
-		if (c > sizeof(buf))
-			c = sizeof(buf);
-		if (write(1, buf, c) != c)
-			die("Write call failed");
-		i += c;
-	}
-
-	file_open(argv[3]);
-	if (fstat (fd, &sb))
-		die("Unable to stat `%s': %m", argv[3]);
-	sz = sb.st_size;
-	fprintf (stderr, "System is %d kB\n", sz/1024);
-	sys_size = (sz + 15) / 16;
-	if (!is_big_kernel && sys_size > DEF_SYSSIZE)
-		die("System is too big. Try using bzImage or modules.");
-	while (sz > 0) {
-		int l, n;
-
-		l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
-		if ((n=read(fd, buf, l)) != l) {
-			if (n < 0)
-				die("Error reading %s: %m", argv[3]);
-			else
-				die("%s: Unexpected EOF", argv[3]);
-		}
-		if (write(1, buf, l) != l)
-			die("Write failed");
-		sz -= l;
-	}
-	close(fd);
-
-	if (lseek(1, 497, SEEK_SET) != 497)		    /* Write sizes to the bootsector */
-		die("Output: seek failed");
-	buf[0] = setup_sectors;
-	if (write(1, buf, 1) != 1)
-		die("Write of setup sector count failed");
-	if (lseek(1, 500, SEEK_SET) != 500)
-		die("Output: seek failed");
-	buf[0] = (sys_size & 0xff);
-	buf[1] = ((sys_size >> 8) & 0xff);
-	buf[2] = ((sys_size >> 16) & 0xff);
-	buf[3] = ((sys_size >> 24) & 0xff);
-	if (write(1, buf, 4) != 4)
-		die("Write of image length failed");
-
-	return 0;					    /* Everything is OK */
-}
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index de1de8a..47f1dc3 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -44,6 +44,7 @@
 
 obj-y				+= topology.o
 obj-y				+= intel_cacheinfo.o
+obj-y				+= addon_cpuid_features.o
 obj-y				+= pcspeaker.o
 
 CFLAGS_vsyscall.o		:= $(PROFILING) -g0
@@ -55,6 +56,7 @@
 topology-y                     += ../../i386/kernel/topology.o
 microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../i386/kernel/microcode.o
 intel_cacheinfo-y		+= ../../i386/kernel/cpu/intel_cacheinfo.o
+addon_cpuid_features-y		+= ../../i386/kernel/cpu/addon_cpuid_features.o
 quirks-y			+= ../../i386/kernel/quirks.o
 i8237-y				+= ../../i386/kernel/i8237.o
 msr-$(subst m,y,$(CONFIG_X86_MSR))  += ../../i386/kernel/msr.o
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index eb6524f..33ef718 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -846,6 +846,8 @@
 			c->x86_capability[2] = cpuid_edx(0x80860001);
 	}
 
+	init_scattered_cpuid_features(c);
+
 	c->apicid = phys_pkg_id(0);
 
 	/*
@@ -931,7 +933,7 @@
 	        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
 	        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
 	        "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
-	        "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
+	        "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
 
 		/* AMD-defined */
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -947,10 +949,11 @@
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
 		/* Other (Linux-defined) */
-		"cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL,
-		"constant_tsc", NULL, NULL,
-		"up", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		"cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
+		NULL, NULL, NULL, NULL,
+		"constant_tsc", "up", NULL, "arch_perfmon",
+		"pebs", "bts", NULL, "sync_rdtsc",
+		"rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
 		/* Intel-defined (#2) */
@@ -961,7 +964,7 @@
 
 		/* VIA/Cyrix/Centaur-defined */
 		NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
-		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		"ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
@@ -972,6 +975,12 @@
 		"osvw", "ibs", NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+		/* Auxiliary (Linux-defined) */
+		"ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	};
 	static char *x86_power_flags[] = { 
 		"ts",	/* temperature sensor */
diff --git a/arch/x86_64/kernel/verify_cpu.S b/arch/x86_64/kernel/verify_cpu.S
index e035f59..45b6f8a 100644
--- a/arch/x86_64/kernel/verify_cpu.S
+++ b/arch/x86_64/kernel/verify_cpu.S
@@ -37,20 +37,6 @@
 	pushl	$0			# Kill any dangerous flags
 	popfl
 
-	/* minimum CPUID flags for x86-64 as defined by AMD */
-#define M(x) (1<<(x))
-#define M2(a,b) M(a)|M(b)
-#define M4(a,b,c,d) M(a)|M(b)|M(c)|M(d)
-
-#define SSE_MASK \
-	(M2(X86_FEATURE_XMM,X86_FEATURE_XMM2))
-#define REQUIRED_MASK1 \
-	(M4(X86_FEATURE_FPU,X86_FEATURE_PSE,X86_FEATURE_TSC,X86_FEATURE_MSR)|\
-	 M4(X86_FEATURE_PAE,X86_FEATURE_CX8,X86_FEATURE_PGE,X86_FEATURE_CMOV)|\
-	 M(X86_FEATURE_FXSR))
-#define REQUIRED_MASK2 \
-	(M(X86_FEATURE_LM - 32))
-
 	pushfl				# standard way to check for cpuid
 	popl	%eax
 	movl	%eax,%ebx
@@ -79,8 +65,8 @@
 verify_cpu_noamd:
 	movl    $0x1,%eax		# Does the cpu have what it takes
 	cpuid
-	andl	$REQUIRED_MASK1,%edx
-	xorl	$REQUIRED_MASK1,%edx
+	andl	$REQUIRED_MASK0,%edx
+	xorl	$REQUIRED_MASK0,%edx
 	jnz	verify_cpu_no_longmode
 
 	movl    $0x80000000,%eax	# See if extended cpuid is implemented
@@ -90,8 +76,8 @@
 
 	movl    $0x80000001,%eax	# Does the cpu have what it takes
 	cpuid
-	andl    $REQUIRED_MASK2,%edx
-	xorl    $REQUIRED_MASK2,%edx
+	andl    $REQUIRED_MASK1,%edx
+	xorl    $REQUIRED_MASK1,%edx
 	jnz     verify_cpu_no_longmode
 
 verify_cpu_sse_test:
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 4ad8675..d8046a1 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -309,7 +309,7 @@
 	  If unsure, say N.
 
 config PATA_HPT3X3
-	tristate "HPT 343/363 PATA support (Experimental)"
+	tristate "HPT 343/363 PATA support"
 	depends on PCI
 	help
 	  This option enables support for the HPT 343/363
@@ -317,6 +317,14 @@
 
 	  If unsure, say N.
 
+config PATA_HPT3X3_DMA
+	bool "HPT 343/363 DMA support (Experimental)"
+	depends on PATA_HPT3X3
+	help
+	  This option enables DMA support for the HPT343/363
+	  controllers. Enable with care as there are still some
+	  problems with DMA on this chipset.
+
 config PATA_ISAPNP
 	tristate "ISA Plug and Play PATA support (Experimental)"
 	depends on EXPERIMENTAL && ISAPNP
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 2610db7..d9fa329 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -414,7 +414,7 @@
 	 */
 	.map = {
 		/* PM   PS   SM   SS       MAP */
-		{  P0,  P2,  RV,  RV }, /* 00b */
+		{  P0,  P2,  NA,  NA }, /* 00b */
 		{ IDE, IDE,  P1,  P3 }, /* 01b */
 		{  P0,  P2, IDE, IDE }, /* 10b */
 		{  RV,  RV,  RV,  RV },
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 5b25311..88e2dd0 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -71,6 +71,7 @@
 					u16 heads, u16 sectors);
 static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
 static void ata_dev_xfermask(struct ata_device *dev);
+static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
 
 unsigned int ata_print_id = 1;
 static struct workqueue_struct *ata_wq;
@@ -1283,18 +1284,11 @@
 void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data,
 			 unsigned long delay)
 {
-	int rc;
-
-	if (ap->pflags & ATA_PFLAG_FLUSH_PORT_TASK)
-		return;
-
 	PREPARE_DELAYED_WORK(&ap->port_task, fn);
 	ap->port_task_data = data;
 
-	rc = queue_delayed_work(ata_wq, &ap->port_task, delay);
-
-	/* rc == 0 means that another user is using port task */
-	WARN_ON(rc == 0);
+	/* may fail if ata_port_flush_task() in progress */
+	queue_delayed_work(ata_wq, &ap->port_task, delay);
 }
 
 /**
@@ -1309,32 +1303,9 @@
  */
 void ata_port_flush_task(struct ata_port *ap)
 {
-	unsigned long flags;
-
 	DPRINTK("ENTER\n");
 
-	spin_lock_irqsave(ap->lock, flags);
-	ap->pflags |= ATA_PFLAG_FLUSH_PORT_TASK;
-	spin_unlock_irqrestore(ap->lock, flags);
-
-	DPRINTK("flush #1\n");
-	cancel_work_sync(&ap->port_task.work); /* akpm: seems unneeded */
-
-	/*
-	 * At this point, if a task is running, it's guaranteed to see
-	 * the FLUSH flag; thus, it will never queue pio tasks again.
-	 * Cancel and flush.
-	 */
-	if (!cancel_delayed_work(&ap->port_task)) {
-		if (ata_msg_ctl(ap))
-			ata_port_printk(ap, KERN_DEBUG, "%s: flush #2\n",
-					__FUNCTION__);
-		cancel_work_sync(&ap->port_task.work);
-	}
-
-	spin_lock_irqsave(ap->lock, flags);
-	ap->pflags &= ~ATA_PFLAG_FLUSH_PORT_TASK;
-	spin_unlock_irqrestore(ap->lock, flags);
+	cancel_rearming_delayed_work(&ap->port_task);
 
 	if (ata_msg_ctl(ap))
 		ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__);
@@ -1814,7 +1785,7 @@
 		desc[0] = '\0';
 		return;
 	}
-	if (ata_device_blacklisted(dev) & ATA_HORKAGE_NONCQ) {
+	if (dev->horkage & ATA_HORKAGE_NONCQ) {
 		snprintf(desc, desc_sz, "NCQ (not used)");
 		return;
 	}
@@ -1863,6 +1834,9 @@
 	if (ata_msg_probe(ap))
 		ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
 
+	/* set horkage */
+	dev->horkage |= ata_dev_blacklisted(dev);
+
 	/* let ACPI work its magic */
 	rc = ata_acpi_on_devcfg(dev);
 	if (rc)
@@ -2038,7 +2012,7 @@
 		dev->max_sectors = ATA_MAX_SECTORS;
 	}
 
-	if (ata_device_blacklisted(dev) & ATA_HORKAGE_MAX_SEC_128)
+	if (dev->horkage & ATA_HORKAGE_MAX_SEC_128)
 		dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
 					 dev->max_sectors);
 
@@ -3190,9 +3164,6 @@
 	if ((slave_possible) && (err != 0x81))
 		ap->device[1].class = ata_dev_try_classify(ap, 1, &err);
 
-	/* re-enable interrupts */
-	ap->ops->irq_on(ap);
-
 	/* is double-select really necessary? */
 	if (ap->device[1].class != ATA_DEV_NONE)
 		ap->ops->dev_select(ap, 1);
@@ -3577,10 +3548,6 @@
 	if (sata_scr_read(ap, SCR_ERROR, &serror) == 0)
 		sata_scr_write(ap, SCR_ERROR, serror);
 
-	/* re-enable interrupts */
-	if (!ap->ops->error_handler)
-		ap->ops->irq_on(ap);
-
 	/* is double-select really necessary? */
 	if (classes[0] != ATA_DEV_NONE)
 		ap->ops->dev_select(ap, 1);
@@ -3770,6 +3737,8 @@
 	{ "SAMSUNG CD-ROM SN-124","N001",	ATA_HORKAGE_NODMA },
 	{ "Seagate STT20000A", NULL,		ATA_HORKAGE_NODMA },
 	{ "IOMEGA  ZIP 250       ATAPI", NULL,	ATA_HORKAGE_NODMA }, /* temporary fix */
+	{ "IOMEGA  ZIP 250       ATAPI       Floppy",
+				NULL,		ATA_HORKAGE_NODMA },
 
 	/* Weird ATAPI devices */
 	{ "TORiSAN DVD-ROM DRD-N216", NULL,	ATA_HORKAGE_MAX_SEC_128 },
@@ -3783,7 +3752,10 @@
 	{ "FUJITSU MHT2060BH",	NULL,		ATA_HORKAGE_NONCQ },
 	/* NCQ is broken */
 	{ "Maxtor 6L250S0",     "BANC1G10",     ATA_HORKAGE_NONCQ },
+	{ "Maxtor 6B200M0",	"BANC1BM0",	ATA_HORKAGE_NONCQ },
 	{ "Maxtor 6B200M0",	"BANC1B10",	ATA_HORKAGE_NONCQ },
+	{ "HITACHI HDS7250SASUN500G 0621KTAWSD", "K2AOAJ0AHITACHI",
+	 ATA_HORKAGE_NONCQ },
 	/* NCQ hard hangs device under heavier load, needs hard power cycle */
 	{ "Maxtor 6B250S0",	"BANC1B70",	ATA_HORKAGE_NONCQ },
 	/* Blacklist entries taken from Silicon Image 3124/3132
@@ -3796,6 +3768,7 @@
 	{ "HTS541612J9SA00",	"SBDIC7JP",	ATA_HORKAGE_NONCQ, },
 	{ "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, },
 	{ "WDC WD740ADFD-00NLR1", NULL,		ATA_HORKAGE_NONCQ, },
+	{ "FUJITSU MHV2080BH",	"00840028",	ATA_HORKAGE_NONCQ, },
 
 	/* Devices with NCQ limits */
 
@@ -3803,7 +3776,7 @@
 	{ }
 };
 
-unsigned long ata_device_blacklisted(const struct ata_device *dev)
+static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
 {
 	unsigned char model_num[ATA_ID_PROD_LEN + 1];
 	unsigned char model_rev[ATA_ID_FW_REV_LEN + 1];
@@ -3833,7 +3806,7 @@
 	if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
 	    (dev->flags & ATA_DFLAG_CDB_INTR))
 		return 1;
-	return (ata_device_blacklisted(dev) & ATA_HORKAGE_NODMA) ? 1 : 0;
+	return (dev->horkage & ATA_HORKAGE_NODMA) ? 1 : 0;
 }
 
 /**
@@ -6557,13 +6530,7 @@
 	spin_unlock_irqrestore(ap->lock, flags);
 
 	ata_port_wait_eh(ap);
-
-	/* Flush hotplug task.  The sequence is similar to
-	 * ata_port_flush_task().
-	 */
-	cancel_work_sync(&ap->hotplug_task.work); /* akpm: why? */
-	cancel_delayed_work(&ap->hotplug_task);
-	cancel_work_sync(&ap->hotplug_task.work);
+	cancel_rearming_delayed_work(&ap->hotplug_task);
 
  skip_eh:
 	/* remove the associated SCSI host */
@@ -6952,7 +6919,6 @@
 EXPORT_SYMBOL_GPL(ata_id_string);
 EXPORT_SYMBOL_GPL(ata_id_c_string);
 EXPORT_SYMBOL_GPL(ata_id_to_dma_mode);
-EXPORT_SYMBOL_GPL(ata_device_blacklisted);
 EXPORT_SYMBOL_GPL(ata_scsi_simulate);
 
 EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
@@ -6961,9 +6927,9 @@
 
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL_GPL(pci_test_config_bits);
-EXPORT_SYMBOL_GPL(ata_pci_init_native_host);
+EXPORT_SYMBOL_GPL(ata_pci_init_sff_host);
 EXPORT_SYMBOL_GPL(ata_pci_init_bmdma);
-EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host);
+EXPORT_SYMBOL_GPL(ata_pci_prepare_sff_host);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
 #ifdef CONFIG_PM
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 9ee0a8c..9aa62a0 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1897,6 +1897,57 @@
 	return 1;
 }
 
+static void ata_eh_handle_dev_fail(struct ata_device *dev, int err)
+{
+	struct ata_port *ap = dev->ap;
+	struct ata_eh_context *ehc = &ap->eh_context;
+
+	ehc->tries[dev->devno]--;
+
+	switch (err) {
+	case -ENODEV:
+		/* device missing or wrong IDENTIFY data, schedule probing */
+		ehc->i.probe_mask |= (1 << dev->devno);
+	case -EINVAL:
+		/* give it just one more chance */
+		ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
+	case -EIO:
+		if (ehc->tries[dev->devno] == 1) {
+			/* This is the last chance, better to slow
+			 * down than lose it.
+			 */
+			sata_down_spd_limit(ap);
+			ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
+		}
+	}
+
+	if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
+		/* disable device if it has used up all its chances */
+		ata_dev_disable(dev);
+
+		/* detach if offline */
+		if (ata_port_offline(ap))
+			ata_eh_detach_dev(dev);
+
+		/* probe if requested */
+		if ((ehc->i.probe_mask & (1 << dev->devno)) &&
+		    !(ehc->did_probe_mask & (1 << dev->devno))) {
+			ata_eh_detach_dev(dev);
+			ata_dev_init(dev);
+
+			ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
+			ehc->did_probe_mask |= (1 << dev->devno);
+			ehc->i.action |= ATA_EH_SOFTRESET;
+		}
+	} else {
+		/* soft didn't work?  be haaaaard */
+		if (ehc->i.flags & ATA_EHI_DID_RESET)
+			ehc->i.action |= ATA_EH_HARDRESET;
+		else
+			ehc->i.action |= ATA_EH_SOFTRESET;
+	}
+}
+
 /**
  *	ata_eh_recover - recover host port after error
  *	@ap: host port to recover
@@ -1997,50 +2048,7 @@
 	goto out;
 
  dev_fail:
-	ehc->tries[dev->devno]--;
-
-	switch (rc) {
-	case -ENODEV:
-		/* device missing or wrong IDENTIFY data, schedule probing */
-		ehc->i.probe_mask |= (1 << dev->devno);
-	case -EINVAL:
-		/* give it just one more chance */
-		ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
-	case -EIO:
-		if (ehc->tries[dev->devno] == 1) {
-			/* This is the last chance, better to slow
-			 * down than lose it.
-			 */
-			sata_down_spd_limit(ap);
-			ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
-		}
-	}
-
-	if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
-		/* disable device if it has used up all its chances */
-		ata_dev_disable(dev);
-
-		/* detach if offline */
-		if (ata_port_offline(ap))
-			ata_eh_detach_dev(dev);
-
-		/* probe if requested */
-		if ((ehc->i.probe_mask & (1 << dev->devno)) &&
-		    !(ehc->did_probe_mask & (1 << dev->devno))) {
-			ata_eh_detach_dev(dev);
-			ata_dev_init(dev);
-
-			ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
-			ehc->did_probe_mask |= (1 << dev->devno);
-			ehc->i.action |= ATA_EH_SOFTRESET;
-		}
-	} else {
-		/* soft didn't work?  be haaaaard */
-		if (ehc->i.flags & ATA_EHI_DID_RESET)
-			ehc->i.action |= ATA_EH_HARDRESET;
-		else
-			ehc->i.action |= ATA_EH_SOFTRESET;
-	}
+	ata_eh_handle_dev_fail(dev, rc);
 
 	if (ata_port_nr_enabled(ap)) {
 		ata_port_printk(ap, KERN_WARNING, "failed to recover some "
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index fa1c22c..ca7d224 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -604,13 +604,17 @@
 }
 
 /**
- *	ata_pci_init_native_host - acquire native ATA resources and init host
+ *	ata_pci_init_sff_host - acquire native PCI ATA resources and init host
  *	@host: target ATA host
  *
  *	Acquire native PCI ATA resources for @host and initialize the
  *	first two ports of @host accordingly.  Ports marked dummy are
  *	skipped and allocation failure makes the port dummy.
  *
+ *	Note that native PCI resources are valid even for legacy hosts
+ *	as we fix up pdev resources array early in boot, so this
+ *	function can be used for both native and legacy SFF hosts.
+ *
  *	LOCKING:
  *	Inherited from calling layer (may sleep).
  *
@@ -618,7 +622,7 @@
  *	0 if at least one port is initialized, -ENODEV if no port is
  *	available.
  */
-int ata_pci_init_native_host(struct ata_host *host)
+int ata_pci_init_sff_host(struct ata_host *host)
 {
 	struct device *gdev = host->dev;
 	struct pci_dev *pdev = to_pci_dev(gdev);
@@ -673,7 +677,7 @@
 }
 
 /**
- *	ata_pci_prepare_native_host - helper to prepare native PCI ATA host
+ *	ata_pci_prepare_sff_host - helper to prepare native PCI ATA host
  *	@pdev: target PCI device
  *	@ppi: array of port_info, must be enough for two ports
  *	@r_host: out argument for the initialized ATA host
@@ -687,9 +691,9 @@
  *	RETURNS:
  *	0 on success, -errno otherwise.
  */
-int ata_pci_prepare_native_host(struct pci_dev *pdev,
-				const struct ata_port_info * const * ppi,
-				struct ata_host **r_host)
+int ata_pci_prepare_sff_host(struct pci_dev *pdev,
+			     const struct ata_port_info * const * ppi,
+			     struct ata_host **r_host)
 {
 	struct ata_host *host;
 	int rc;
@@ -705,7 +709,7 @@
 		goto err_out;
 	}
 
-	rc = ata_pci_init_native_host(host);
+	rc = ata_pci_init_sff_host(host);
 	if (rc)
 		goto err_out;
 
@@ -730,221 +734,6 @@
 	return rc;
 }
 
-struct ata_legacy_devres {
-	unsigned int	mask;
-	unsigned long	cmd_port[2];
-	void __iomem *	cmd_addr[2];
-	void __iomem *	ctl_addr[2];
-	unsigned int	irq[2];
-	void *		irq_dev_id[2];
-};
-
-static void ata_legacy_free_irqs(struct ata_legacy_devres *legacy_dr)
-{
-	int i;
-
-	for (i = 0; i < 2; i++) {
-		if (!legacy_dr->irq[i])
-			continue;
-
-		free_irq(legacy_dr->irq[i], legacy_dr->irq_dev_id[i]);
-		legacy_dr->irq[i] = 0;
-		legacy_dr->irq_dev_id[i] = NULL;
-	}
-}
-
-static void ata_legacy_release(struct device *gdev, void *res)
-{
-	struct ata_legacy_devres *this = res;
-	int i;
-
-	ata_legacy_free_irqs(this);
-
-	for (i = 0; i < 2; i++) {
-		if (this->cmd_addr[i])
-			ioport_unmap(this->cmd_addr[i]);
-		if (this->ctl_addr[i])
-			ioport_unmap(this->ctl_addr[i]);
-		if (this->cmd_port[i])
-			release_region(this->cmd_port[i], 8);
-	}
-}
-
-static int ata_init_legacy_port(struct ata_port *ap,
-				struct ata_legacy_devres *legacy_dr)
-{
-	struct ata_host *host = ap->host;
-	int port_no = ap->port_no;
-	unsigned long cmd_port, ctl_port;
-
-	if (port_no == 0) {
-		cmd_port = ATA_PRIMARY_CMD;
-		ctl_port = ATA_PRIMARY_CTL;
-	} else {
-		cmd_port = ATA_SECONDARY_CMD;
-		ctl_port = ATA_SECONDARY_CTL;
-	}
-
-	/* request cmd_port */
-	if (request_region(cmd_port, 8, "libata"))
-		legacy_dr->cmd_port[port_no] = cmd_port;
-	else {
-		dev_printk(KERN_WARNING, host->dev,
-			   "0x%0lX IDE port busy\n", cmd_port);
-		return -EBUSY;
-	}
-
-	/* iomap cmd and ctl ports */
-	legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8);
-	legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1);
-	if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no]) {
-		dev_printk(KERN_WARNING, host->dev,
-			   "failed to map cmd/ctl ports\n");
-		return -ENOMEM;
-	}
-
-	/* init IO addresses */
-	ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no];
-	ap->ioaddr.altstatus_addr = legacy_dr->ctl_addr[port_no];
-	ap->ioaddr.ctl_addr = legacy_dr->ctl_addr[port_no];
-	ata_std_ports(&ap->ioaddr);
-
-	return 0;
-}
-
-/**
- *	ata_init_legacy_host - acquire legacy ATA resources and init ATA host
- *	@host: target ATA host
- *	@was_busy: out parameter, indicates whether any port was busy
- *
- *	Acquire legacy ATA resources for the first two ports of @host
- *	and initialize it accordingly.  Ports marked dummy are skipped
- *	and resource acquistion failure makes the port dummy.
- *
- *	LOCKING:
- *	Inherited from calling layer (may sleep).
- *
- *	RETURNS:
- *	0 if at least one port is initialized, -ENODEV if no port is
- *	available.
- */
-static int ata_init_legacy_host(struct ata_host *host, int *was_busy)
-{
-	struct device *gdev = host->dev;
-	struct ata_legacy_devres *legacy_dr;
-	int i, rc;
-
-	if (!devres_open_group(gdev, NULL, GFP_KERNEL))
-		return -ENOMEM;
-
-	rc = -ENOMEM;
-	legacy_dr = devres_alloc(ata_legacy_release, sizeof(*legacy_dr),
-				 GFP_KERNEL);
-	if (!legacy_dr)
-		goto err_out;
-	devres_add(gdev, legacy_dr);
-
-	for (i = 0; i < 2; i++) {
-		if (ata_port_is_dummy(host->ports[i]))
-			continue;
-
-		rc = ata_init_legacy_port(host->ports[i], legacy_dr);
-		if (rc == 0)
-			legacy_dr->mask |= 1 << i;
-		else {
-			if (rc == -EBUSY)
-				(*was_busy)++;
-			host->ports[i]->ops = &ata_dummy_port_ops;
-		}
-	}
-
-	if (!legacy_dr->mask) {
-		dev_printk(KERN_ERR, gdev, "no available legacy port\n");
-		return -ENODEV;
-	}
-
-	devres_remove_group(gdev, NULL);
-	return 0;
-
- err_out:
-	devres_release_group(gdev, NULL);
-	return rc;
-}
-
-/**
- *	ata_request_legacy_irqs - request legacy ATA IRQs
- *	@host: target ATA host
- *	@handler: array of IRQ handlers
- *	@irq_flags: array of IRQ flags
- *	@dev_id: array of IRQ dev_ids
- *
- *	Request legacy IRQs for non-dummy legacy ports in @host.  All
- *	IRQ parameters are passed as array to allow ports to have
- *	separate IRQ handlers.
- *
- *	LOCKING:
- *	Inherited from calling layer (may sleep).
- *
- *	RETURNS:
- *	0 on success, -errno otherwise.
- */
-static int ata_request_legacy_irqs(struct ata_host *host,
-				   irq_handler_t const *handler,
-				   const unsigned int *irq_flags,
-				   void * const *dev_id)
-{
-	struct device *gdev = host->dev;
-	struct ata_legacy_devres *legacy_dr;
-	int i, rc;
-
-	legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL);
-	BUG_ON(!legacy_dr);
-
-	for (i = 0; i < 2; i++) {
-		unsigned int irq;
-
-		/* FIXME: ATA_*_IRQ() should take generic device not pci_dev */
-		if (i == 0)
-			irq = ATA_PRIMARY_IRQ(to_pci_dev(gdev));
-		else
-			irq = ATA_SECONDARY_IRQ(to_pci_dev(gdev));
-
-		if (!(legacy_dr->mask & (1 << i)))
-			continue;
-
-		if (!handler[i]) {
-			dev_printk(KERN_ERR, gdev,
-				   "NULL handler specified for port %d\n", i);
-			rc = -EINVAL;
-			goto err_out;
-		}
-
-		rc = request_irq(irq, handler[i], irq_flags[i], DRV_NAME,
-				 dev_id[i]);
-		if (rc) {
-			dev_printk(KERN_ERR, gdev,
-				"irq %u request failed (errno=%d)\n", irq, rc);
-			goto err_out;
-		}
-
-		/* record irq allocation in legacy_dr */
-		legacy_dr->irq[i] = irq;
-		legacy_dr->irq_dev_id[i] = dev_id[i];
-
-		/* only used to print info */
-		if (i == 0)
-			host->irq = irq;
-		else
-			host->irq2 = irq;
-	}
-
-	return 0;
-
- err_out:
-	ata_legacy_free_irqs(legacy_dr);
-	return rc;
-}
-
 /**
  *	ata_pci_init_one - Initialize/register PCI IDE host controller
  *	@pdev: Controller to be initialized
@@ -1029,35 +818,11 @@
 #endif
 	}
 
-	/* alloc and init host */
-	host = ata_host_alloc_pinfo(dev, ppi, 2);
-	if (!host) {
-		dev_printk(KERN_ERR, &pdev->dev,
-			   "failed to allocate ATA host\n");
-		rc = -ENOMEM;
+	/* prepare host */
+	rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
+	if (rc)
 		goto err_out;
-	}
 
-	if (!legacy_mode) {
-		rc = ata_pci_init_native_host(host);
-		if (rc)
-			goto err_out;
-	} else {
-		int was_busy = 0;
-
-		rc = ata_init_legacy_host(host, &was_busy);
-		if (was_busy)
-			pcim_pin_device(pdev);
-		if (rc)
-			goto err_out;
-
-		/* request respective PCI regions, may fail */
-		rc = pci_request_region(pdev, 1, DRV_NAME);
-		rc = pci_request_region(pdev, 3, DRV_NAME);
-	}
-
-	/* init BMDMA, may fail */
-	ata_pci_init_bmdma(host);
 	pci_set_master(pdev);
 
 	/* start host and request IRQ */
@@ -1068,17 +833,28 @@
 	if (!legacy_mode) {
 		rc = devm_request_irq(dev, pdev->irq, pi->port_ops->irq_handler,
 				      IRQF_SHARED, DRV_NAME, host);
+		if (rc)
+			goto err_out;
 		host->irq = pdev->irq;
 	} else {
-		irq_handler_t handler[2] = { host->ops->irq_handler,
-					     host->ops->irq_handler };
-		unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED };
-		void *dev_id[2] = { host, host };
+		if (!ata_port_is_dummy(host->ports[0])) {
+			host->irq = ATA_PRIMARY_IRQ(pdev);
+			rc = devm_request_irq(dev, host->irq,
+					      pi->port_ops->irq_handler,
+					      IRQF_SHARED, DRV_NAME, host);
+			if (rc)
+				goto err_out;
+		}
 
-		rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id);
+		if (!ata_port_is_dummy(host->ports[1])) {
+			host->irq2 = ATA_SECONDARY_IRQ(pdev);
+			rc = devm_request_irq(dev, host->irq2,
+					      pi->port_ops->irq_handler,
+					      IRQF_SHARED, DRV_NAME, host);
+			if (rc)
+				goto err_out;
+		}
 	}
-	if (rc)
-		goto err_out;
 
 	/* register */
 	rc = ata_host_register(host, pi->sht);
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index d928c91..be0f05e 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -23,7 +23,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"pata_hpt3x3"
-#define DRV_VERSION	"0.4.3"
+#define DRV_VERSION	"0.5.3"
 
 /**
  *	hpt3x3_set_piomode		-	PIO setup
@@ -52,6 +52,7 @@
 	pci_write_config_dword(pdev, 0x48, r2);
 }
 
+#if defined(CONFIG_PATA_HPT3X3_DMA)
 /**
  *	hpt3x3_set_dmamode		-	DMA timing setup
  *	@ap: ATA interface
@@ -59,6 +60,9 @@
  *
  *	Set up the channel for MWDMA or UDMA modes. Much the same as with
  *	PIO, load the mode number and then set MWDMA or UDMA flag.
+ *
+ *	0x44 : bit 0-2 master mode, 3-5 slave mode, etc
+ *	0x48 : bit 4/0 DMA/UDMA bit 5/1 for slave etc
  */
 
 static void hpt3x3_set_dmamode(struct ata_port *ap, struct ata_device *adev)
@@ -76,13 +80,26 @@
 	r2 &= ~(0x11 << dn);	/* Clear MWDMA and UDMA bits */
 
 	if (adev->dma_mode >= XFER_UDMA_0)
-		r2 |= 0x01 << dn;	/* Ultra mode */
+		r2 |= (0x10 << dn);	/* Ultra mode */
 	else
-		r2 |= 0x10 << dn;	/* MWDMA */
+		r2 |= (0x01 << dn);	/* MWDMA */
 
 	pci_write_config_dword(pdev, 0x44, r1);
 	pci_write_config_dword(pdev, 0x48, r2);
 }
+#endif /* CONFIG_PATA_HPT3X3_DMA */
+
+/**
+ *	hpt3x3_atapi_dma	-	ATAPI DMA check
+ *	@qc: Queued command
+ *
+ *	Just say no - we don't do ATAPI DMA
+ */
+
+static int hpt3x3_atapi_dma(struct ata_queued_cmd *qc)
+{
+	return 1;
+}
 
 static struct scsi_host_template hpt3x3_sht = {
 	.module			= THIS_MODULE,
@@ -105,7 +122,9 @@
 static struct ata_port_operations hpt3x3_port_ops = {
 	.port_disable	= ata_port_disable,
 	.set_piomode	= hpt3x3_set_piomode,
+#if defined(CONFIG_PATA_HPT3X3_DMA)
 	.set_dmamode	= hpt3x3_set_dmamode,
+#endif
 	.mode_filter	= ata_pci_default_filter,
 
 	.tf_load	= ata_tf_load,
@@ -124,6 +143,7 @@
 	.bmdma_start 	= ata_bmdma_start,
 	.bmdma_stop	= ata_bmdma_stop,
 	.bmdma_status 	= ata_bmdma_status,
+	.check_atapi_dma= hpt3x3_atapi_dma,
 
 	.qc_prep 	= ata_qc_prep,
 	.qc_issue	= ata_qc_issue_prot,
@@ -158,32 +178,79 @@
 		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
 }
 
-
 /**
  *	hpt3x3_init_one		-	Initialise an HPT343/363
- *	@dev: PCI device
+ *	@pdev: PCI device
  *	@id: Entry in match table
  *
- *	Perform basic initialisation. The chip has a quirk that it won't
- *	function unless it is at XX00. The old ATA driver touched this up
- *	but we leave it for pci quirks to do properly.
+ *	Perform basic initialisation. We set the device up so we access all
+ *	ports via BAR4. This is neccessary to work around errata.
  */
 
-static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
+	static int printed_version;
 	static const struct ata_port_info info = {
 		.sht = &hpt3x3_sht,
 		.flags = ATA_FLAG_SLAVE_POSS,
 		.pio_mask = 0x1f,
+#if defined(CONFIG_PATA_HPT3X3_DMA)
+		/* Further debug needed */
 		.mwdma_mask = 0x07,
 		.udma_mask = 0x07,
+#endif
 		.port_ops = &hpt3x3_port_ops
 	};
+	/* Register offsets of taskfiles in BAR4 area */
+	static const u8 offset_cmd[2] = { 0x20, 0x28 };
+	static const u8 offset_ctl[2] = { 0x36, 0x3E };
 	const struct ata_port_info *ppi[] = { &info, NULL };
+	struct ata_host *host;
+	int i, rc;
+	void __iomem *base;
 
-	hpt3x3_init_chipset(dev);
-	/* Now kick off ATA set up */
-	return ata_pci_init_one(dev, ppi);
+	hpt3x3_init_chipset(pdev);
+
+	if (!printed_version++)
+		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+
+	host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
+	if (!host)
+		return -ENOMEM;
+	/* acquire resources and fill host */
+	rc = pcim_enable_device(pdev);
+	if (rc)
+		return rc;
+
+	/* Everything is relative to BAR4 if we set up this way */
+	rc = pcim_iomap_regions(pdev, 1 << 4, DRV_NAME);
+	if (rc == -EBUSY)
+		pcim_pin_device(pdev);
+	if (rc)
+		return rc;
+	host->iomap = pcim_iomap_table(pdev);
+	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+	if (rc)
+		return rc;
+	rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+	if (rc)
+		return rc;
+
+	base = host->iomap[4];	/* Bus mastering base */
+
+	for (i = 0; i < host->n_ports; i++) {
+		struct ata_ioports *ioaddr = &host->ports[i]->ioaddr;
+
+		ioaddr->cmd_addr = base + offset_cmd[i];
+		ioaddr->altstatus_addr =
+		ioaddr->ctl_addr = base + offset_ctl[i];
+		ioaddr->scr_addr = NULL;
+		ata_std_ports(ioaddr);
+		ioaddr->bmdma_addr = base + 8 * i;
+	}
+	pci_set_master(pdev);
+	return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+				 &hpt3x3_sht);
 }
 
 #ifdef CONFIG_PM
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index 368fac7..182e83c 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -467,13 +467,27 @@
 static int
 mpc52xx_ata_suspend(struct of_device *op, pm_message_t state)
 {
-	return 0;	/* FIXME : What to do here ? */
+	struct ata_host *host = dev_get_drvdata(&op->dev);
+
+	return ata_host_suspend(host, state);
 }
 
 static int
 mpc52xx_ata_resume(struct of_device *op)
 {
-	return 0;	/* FIXME : What to do here ? */
+	struct ata_host *host = dev_get_drvdata(&op->dev);
+	struct mpc52xx_ata_priv *priv = host->private_data;
+	int rv;
+
+	rv = mpc52xx_ata_hw_init(priv);
+	if (rv) {
+		printk(KERN_ERR DRV_NAME ": Error during HW init\n");
+		return rv;
+	}
+
+	ata_host_resume(host);
+
+	return 0;
 }
 
 #endif
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index 61502bc..c55667e 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -238,6 +238,12 @@
 	else
 		offset = 0;	/* 100MHz */
 
+	/* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */
+	if (adev->class == ATA_DEV_ATAPI && speed > XFER_UDMA_4) {
+		printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME);
+		speed = XFER_UDMA_4;
+	}
+
 	if (speed >= XFER_UDMA_0)
 		idx = speed - XFER_UDMA_0;
 	else
@@ -724,22 +730,36 @@
 
 static u8 scc_bmdma_status (struct ata_port *ap)
 {
-	u8 host_stat;
 	void __iomem *mmio = ap->ioaddr.bmdma_addr;
+	u8 host_stat = in_be32(mmio + SCC_DMA_STATUS);
+	u32 int_status = in_be32(mmio + SCC_DMA_INTST);
+	struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
+	static int retry = 0;
 
-	host_stat = in_be32(mmio + SCC_DMA_STATUS);
+	/* return if IOS_SS is cleared */
+	if (!(in_be32(mmio + SCC_DMA_CMD) & ATA_DMA_START))
+		return host_stat;
 
-	/* Workaround for PTERADD: emulate DMA_INTR when
-	 * - IDE_STATUS[ERR] = 1
-	 * - INT_STATUS[INTRQ] = 1
-	 * - DMA_STATUS[IORACTA] = 1
-	 */
-	if (!(host_stat & ATA_DMA_INTR)) {
-		u32 int_status = in_be32(mmio + SCC_DMA_INTST);
-		if (ata_altstatus(ap) & ATA_ERR &&
-		    int_status & INTSTS_INTRQ &&
-		    host_stat & ATA_DMA_ACTIVE)
-			host_stat |= ATA_DMA_INTR;
+	/* errata A252,A308 workaround: Step4 */
+	if (ata_altstatus(ap) & ATA_ERR && int_status & INTSTS_INTRQ)
+		return (host_stat | ATA_DMA_INTR);
+
+	/* errata A308 workaround Step5 */
+	if (int_status & INTSTS_IOIRQS) {
+		host_stat |= ATA_DMA_INTR;
+
+		/* We don't check ATAPI DMA because it is limited to UDMA4 */
+		if ((qc->tf.protocol == ATA_PROT_DMA &&
+		     qc->dev->xfer_mode > XFER_UDMA_4)) {
+			if (!(int_status & INTSTS_ACTEINT)) {
+				printk(KERN_WARNING "ata%u: data lost occurred. (ACTEINT==0, retry:%d)\n",
+				       ap->print_id, retry);
+				host_stat |= ATA_DMA_ERR;
+				if (retry++)
+					ap->udma_mask >>= 1;
+			} else
+				retry = 0;
+		}
 	}
 
 	return host_stat;
@@ -892,10 +912,6 @@
 {
 	DPRINTK("ENTER\n");
 
-	/* re-enable interrupts */
-	if (!ap->ops->error_handler)
-		ap->ops->irq_on(ap);
-
 	/* is double-select really necessary? */
 	if (classes[0] != ATA_DEV_NONE)
 		ap->ops->dev_select(ap, 1);
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index 74a0211..9a829a7 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -149,6 +149,9 @@
 	if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
 		return -ENOENT;
 
+	/* Clear the FIFO settings. We can't enable the FIFO until
+	   we know we are poking at a disk */
+	pci_write_config_byte(pdev, 0x4B, 0);
 	return ata_std_prereset(ap, deadline);
 }
 
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 6dcfc62..5d57643 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -29,11 +29,6 @@
   I distinctly remember a couple workarounds (one related to PCI-X)
   are still needed.
 
-  2) Convert to LibATA new EH.  Required for hotplug, NCQ, and sane
-  probing/error handling in general.  MUST HAVE.
-
-  3) Add hotplug support (easy, once new-EH support appears)
-
   4) Add NCQ support (easy to intermediate, once new-EH support appears)
 
   5) Investigate problems with PCI Message Signalled Interrupts (MSI).
@@ -108,8 +103,6 @@
 	MV_SATAHC_ARBTR_REG_SZ	= MV_MINOR_REG_AREA_SZ,		/* arbiter */
 	MV_PORT_REG_SZ		= MV_MINOR_REG_AREA_SZ,
 
-	MV_USE_Q_DEPTH		= ATA_DEF_QUEUE,
-
 	MV_MAX_Q_DEPTH		= 32,
 	MV_MAX_Q_DEPTH_MASK	= MV_MAX_Q_DEPTH - 1,
 
@@ -133,18 +126,22 @@
 	/* Host Flags */
 	MV_FLAG_DUAL_HC		= (1 << 30),  /* two SATA Host Controllers */
 	MV_FLAG_IRQ_COALESCE	= (1 << 29),  /* IRQ coalescing capability */
-	MV_COMMON_FLAGS		= (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				   ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
-				   ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING),
+	MV_COMMON_FLAGS		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+				  ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
+				  ATA_FLAG_PIO_POLLING,
 	MV_6XXX_FLAGS		= MV_FLAG_IRQ_COALESCE,
 
 	CRQB_FLAG_READ		= (1 << 0),
 	CRQB_TAG_SHIFT		= 1,
+	CRQB_IOID_SHIFT		= 6,	/* CRQB Gen-II/IIE IO Id shift */
+	CRQB_HOSTQ_SHIFT	= 17,	/* CRQB Gen-II/IIE HostQueTag shift */
 	CRQB_CMD_ADDR_SHIFT	= 8,
 	CRQB_CMD_CS		= (0x2 << 11),
 	CRQB_CMD_LAST		= (1 << 15),
 
 	CRPB_FLAG_STATUS_SHIFT	= 8,
+	CRPB_IOID_SHIFT_6	= 5,	/* CRPB Gen-II IO Id shift */
+	CRPB_IOID_SHIFT_7	= 7,	/* CRPB Gen-IIE IO Id shift */
 
 	EPRD_FLAG_END_OF_TBL	= (1 << 31),
 
@@ -236,8 +233,10 @@
 	EDMA_ERR_DEV_DCON	= (1 << 3),
 	EDMA_ERR_DEV_CON	= (1 << 4),
 	EDMA_ERR_SERR		= (1 << 5),
-	EDMA_ERR_SELF_DIS	= (1 << 7),
+	EDMA_ERR_SELF_DIS	= (1 << 7),	/* Gen II/IIE self-disable */
+	EDMA_ERR_SELF_DIS_5	= (1 << 8),	/* Gen I self-disable */
 	EDMA_ERR_BIST_ASYNC	= (1 << 8),
+	EDMA_ERR_TRANS_IRQ_7	= (1 << 8),	/* Gen IIE transprt layer irq */
 	EDMA_ERR_CRBQ_PAR	= (1 << 9),
 	EDMA_ERR_CRPB_PAR	= (1 << 10),
 	EDMA_ERR_INTRL_PAR	= (1 << 11),
@@ -248,13 +247,33 @@
 	EDMA_ERR_LNK_CTRL_TX	= (0x1f << 21),
 	EDMA_ERR_LNK_DATA_TX	= (0x1f << 26),
 	EDMA_ERR_TRANS_PROTO	= (1 << 31),
-	EDMA_ERR_FATAL		= (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR |
-				   EDMA_ERR_DEV_DCON | EDMA_ERR_CRBQ_PAR |
-				   EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR |
-				   EDMA_ERR_IORDY | EDMA_ERR_LNK_CTRL_RX_2 |
-				   EDMA_ERR_LNK_DATA_RX |
-				   EDMA_ERR_LNK_DATA_TX |
-				   EDMA_ERR_TRANS_PROTO),
+	EDMA_ERR_OVERRUN_5	= (1 << 5),
+	EDMA_ERR_UNDERRUN_5	= (1 << 6),
+	EDMA_EH_FREEZE		= EDMA_ERR_D_PAR |
+				  EDMA_ERR_PRD_PAR |
+				  EDMA_ERR_DEV_DCON |
+				  EDMA_ERR_DEV_CON |
+				  EDMA_ERR_SERR |
+				  EDMA_ERR_SELF_DIS |
+				  EDMA_ERR_CRBQ_PAR |
+				  EDMA_ERR_CRPB_PAR |
+				  EDMA_ERR_INTRL_PAR |
+				  EDMA_ERR_IORDY |
+				  EDMA_ERR_LNK_CTRL_RX_2 |
+				  EDMA_ERR_LNK_DATA_RX |
+				  EDMA_ERR_LNK_DATA_TX |
+				  EDMA_ERR_TRANS_PROTO,
+	EDMA_EH_FREEZE_5	= EDMA_ERR_D_PAR |
+				  EDMA_ERR_PRD_PAR |
+				  EDMA_ERR_DEV_DCON |
+				  EDMA_ERR_DEV_CON |
+				  EDMA_ERR_OVERRUN_5 |
+				  EDMA_ERR_UNDERRUN_5 |
+				  EDMA_ERR_SELF_DIS_5 |
+				  EDMA_ERR_CRBQ_PAR |
+				  EDMA_ERR_CRPB_PAR |
+				  EDMA_ERR_INTRL_PAR |
+				  EDMA_ERR_IORDY,
 
 	EDMA_REQ_Q_BASE_HI_OFS	= 0x10,
 	EDMA_REQ_Q_IN_PTR_OFS	= 0x14,		/* also contains BASE_LO */
@@ -282,18 +301,18 @@
 	MV_HP_ERRATA_60X1B2	= (1 << 3),
 	MV_HP_ERRATA_60X1C0	= (1 << 4),
 	MV_HP_ERRATA_XX42A0	= (1 << 5),
-	MV_HP_50XX		= (1 << 6),
-	MV_HP_GEN_IIE		= (1 << 7),
+	MV_HP_GEN_I		= (1 << 6),
+	MV_HP_GEN_II		= (1 << 7),
+	MV_HP_GEN_IIE		= (1 << 8),
 
 	/* Port private flags (pp_flags) */
 	MV_PP_FLAG_EDMA_EN	= (1 << 0),
 	MV_PP_FLAG_EDMA_DS_ACT	= (1 << 1),
+	MV_PP_FLAG_HAD_A_RESET	= (1 << 2),
 };
 
-#define IS_50XX(hpriv) ((hpriv)->hp_flags & MV_HP_50XX)
-#define IS_60XX(hpriv) (((hpriv)->hp_flags & MV_HP_50XX) == 0)
-#define IS_GEN_I(hpriv) IS_50XX(hpriv)
-#define IS_GEN_II(hpriv) IS_60XX(hpriv)
+#define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I)
+#define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II)
 #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
 
 enum {
@@ -352,6 +371,10 @@
 	dma_addr_t		crpb_dma;
 	struct mv_sg		*sg_tbl;
 	dma_addr_t		sg_tbl_dma;
+
+	unsigned int		req_idx;
+	unsigned int		resp_idx;
+
 	u32			pp_flags;
 };
 
@@ -384,14 +407,15 @@
 static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
 static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
 static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
-static void mv_phy_reset(struct ata_port *ap);
-static void __mv_phy_reset(struct ata_port *ap, int can_sleep);
 static int mv_port_start(struct ata_port *ap);
 static void mv_port_stop(struct ata_port *ap);
 static void mv_qc_prep(struct ata_queued_cmd *qc);
 static void mv_qc_prep_iie(struct ata_queued_cmd *qc);
 static unsigned int mv_qc_issue(struct ata_queued_cmd *qc);
-static void mv_eng_timeout(struct ata_port *ap);
+static void mv_error_handler(struct ata_port *ap);
+static void mv_post_int_cmd(struct ata_queued_cmd *qc);
+static void mv_eh_freeze(struct ata_port *ap);
+static void mv_eh_thaw(struct ata_port *ap);
 static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 
 static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -415,14 +439,31 @@
 static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio);
 static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
 			     unsigned int port_no);
-static void mv_stop_and_reset(struct ata_port *ap);
 
-static struct scsi_host_template mv_sht = {
+static struct scsi_host_template mv5_sht = {
 	.module			= THIS_MODULE,
 	.name			= DRV_NAME,
 	.ioctl			= ata_scsi_ioctl,
 	.queuecommand		= ata_scsi_queuecmd,
-	.can_queue		= MV_USE_Q_DEPTH,
+	.can_queue		= ATA_DEF_QUEUE,
+	.this_id		= ATA_SHT_THIS_ID,
+	.sg_tablesize		= MV_MAX_SG_CT,
+	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
+	.emulated		= ATA_SHT_EMULATED,
+	.use_clustering		= 1,
+	.proc_name		= DRV_NAME,
+	.dma_boundary		= MV_DMA_BOUNDARY,
+	.slave_configure	= ata_scsi_slave_config,
+	.slave_destroy		= ata_scsi_slave_destroy,
+	.bios_param		= ata_std_bios_param,
+};
+
+static struct scsi_host_template mv6_sht = {
+	.module			= THIS_MODULE,
+	.name			= DRV_NAME,
+	.ioctl			= ata_scsi_ioctl,
+	.queuecommand		= ata_scsi_queuecmd,
+	.can_queue		= ATA_DEF_QUEUE,
 	.this_id		= ATA_SHT_THIS_ID,
 	.sg_tablesize		= MV_MAX_SG_CT,
 	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
@@ -444,19 +485,21 @@
 	.exec_command		= ata_exec_command,
 	.dev_select		= ata_std_dev_select,
 
-	.phy_reset		= mv_phy_reset,
 	.cable_detect		= ata_cable_sata,
 
 	.qc_prep		= mv_qc_prep,
 	.qc_issue		= mv_qc_issue,
 	.data_xfer		= ata_data_xfer,
 
-	.eng_timeout		= mv_eng_timeout,
-
 	.irq_clear		= mv_irq_clear,
 	.irq_on			= ata_irq_on,
 	.irq_ack		= ata_irq_ack,
 
+	.error_handler		= mv_error_handler,
+	.post_internal_cmd	= mv_post_int_cmd,
+	.freeze			= mv_eh_freeze,
+	.thaw			= mv_eh_thaw,
+
 	.scr_read		= mv5_scr_read,
 	.scr_write		= mv5_scr_write,
 
@@ -473,19 +516,21 @@
 	.exec_command		= ata_exec_command,
 	.dev_select		= ata_std_dev_select,
 
-	.phy_reset		= mv_phy_reset,
 	.cable_detect		= ata_cable_sata,
 
 	.qc_prep		= mv_qc_prep,
 	.qc_issue		= mv_qc_issue,
 	.data_xfer		= ata_data_xfer,
 
-	.eng_timeout		= mv_eng_timeout,
-
 	.irq_clear		= mv_irq_clear,
 	.irq_on			= ata_irq_on,
 	.irq_ack		= ata_irq_ack,
 
+	.error_handler		= mv_error_handler,
+	.post_internal_cmd	= mv_post_int_cmd,
+	.freeze			= mv_eh_freeze,
+	.thaw			= mv_eh_thaw,
+
 	.scr_read		= mv_scr_read,
 	.scr_write		= mv_scr_write,
 
@@ -502,19 +547,21 @@
 	.exec_command		= ata_exec_command,
 	.dev_select		= ata_std_dev_select,
 
-	.phy_reset		= mv_phy_reset,
 	.cable_detect		= ata_cable_sata,
 
 	.qc_prep		= mv_qc_prep_iie,
 	.qc_issue		= mv_qc_issue,
 	.data_xfer		= ata_data_xfer,
 
-	.eng_timeout		= mv_eng_timeout,
-
 	.irq_clear		= mv_irq_clear,
 	.irq_on			= ata_irq_on,
 	.irq_ack		= ata_irq_ack,
 
+	.error_handler		= mv_error_handler,
+	.post_internal_cmd	= mv_post_int_cmd,
+	.freeze			= mv_eh_freeze,
+	.thaw			= mv_eh_thaw,
+
 	.scr_read		= mv_scr_read,
 	.scr_write		= mv_scr_write,
 
@@ -530,38 +577,38 @@
 		.port_ops	= &mv5_ops,
 	},
 	{  /* chip_508x */
-		.flags		= (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
+		.flags		= MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
 		.pio_mask	= 0x1f,	/* pio0-4 */
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv5_ops,
 	},
 	{  /* chip_5080 */
-		.flags		= (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
+		.flags		= MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
 		.pio_mask	= 0x1f,	/* pio0-4 */
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv5_ops,
 	},
 	{  /* chip_604x */
-		.flags		= (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
+		.flags		= MV_COMMON_FLAGS | MV_6XXX_FLAGS,
 		.pio_mask	= 0x1f,	/* pio0-4 */
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv6_ops,
 	},
 	{  /* chip_608x */
-		.flags		= (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
-				   MV_FLAG_DUAL_HC),
+		.flags		= MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+				  MV_FLAG_DUAL_HC,
 		.pio_mask	= 0x1f,	/* pio0-4 */
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv6_ops,
 	},
 	{  /* chip_6042 */
-		.flags		= (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
+		.flags		= MV_COMMON_FLAGS | MV_6XXX_FLAGS,
 		.pio_mask	= 0x1f,	/* pio0-4 */
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv_iie_ops,
 	},
 	{  /* chip_7042 */
-		.flags		= (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
+		.flags		= MV_COMMON_FLAGS | MV_6XXX_FLAGS,
 		.pio_mask	= 0x1f,	/* pio0-4 */
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &mv_iie_ops,
@@ -709,6 +756,46 @@
 {
 }
 
+static void mv_set_edma_ptrs(void __iomem *port_mmio,
+			     struct mv_host_priv *hpriv,
+			     struct mv_port_priv *pp)
+{
+	u32 index;
+
+	/*
+	 * initialize request queue
+	 */
+	index = (pp->req_idx & MV_MAX_Q_DEPTH_MASK) << EDMA_REQ_Q_PTR_SHIFT;
+
+	WARN_ON(pp->crqb_dma & 0x3ff);
+	writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
+	writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | index,
+		 port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+
+	if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
+		writelfl((pp->crqb_dma & 0xffffffff) | index,
+			 port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
+	else
+		writelfl(index, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
+
+	/*
+	 * initialize response queue
+	 */
+	index = (pp->resp_idx & MV_MAX_Q_DEPTH_MASK) << EDMA_RSP_Q_PTR_SHIFT;
+
+	WARN_ON(pp->crpb_dma & 0xff);
+	writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
+
+	if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
+		writelfl((pp->crpb_dma & 0xffffffff) | index,
+			 port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+	else
+		writelfl(index, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
+
+	writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | index,
+		 port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+}
+
 /**
  *      mv_start_dma - Enable eDMA engine
  *      @base: port base address
@@ -720,9 +807,15 @@
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_start_dma(void __iomem *base, struct mv_port_priv *pp)
+static void mv_start_dma(void __iomem *base, struct mv_host_priv *hpriv,
+			 struct mv_port_priv *pp)
 {
-	if (!(MV_PP_FLAG_EDMA_EN & pp->pp_flags)) {
+	if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
+		/* clear EDMA event indicators, if any */
+		writelfl(0, base + EDMA_ERR_IRQ_CAUSE_OFS);
+
+		mv_set_edma_ptrs(base, hpriv, pp);
+
 		writelfl(EDMA_EN, base + EDMA_CMD_OFS);
 		pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
 	}
@@ -739,14 +832,14 @@
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_stop_dma(struct ata_port *ap)
+static int mv_stop_dma(struct ata_port *ap)
 {
 	void __iomem *port_mmio = mv_ap_base(ap);
 	struct mv_port_priv *pp	= ap->private_data;
 	u32 reg;
-	int i;
+	int i, err = 0;
 
-	if (MV_PP_FLAG_EDMA_EN & pp->pp_flags) {
+	if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
 		/* Disable EDMA if active.   The disable bit auto clears.
 		 */
 		writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
@@ -758,16 +851,18 @@
 	/* now properly wait for the eDMA to stop */
 	for (i = 1000; i > 0; i--) {
 		reg = readl(port_mmio + EDMA_CMD_OFS);
-		if (!(EDMA_EN & reg)) {
+		if (!(reg & EDMA_EN))
 			break;
-		}
+
 		udelay(100);
 	}
 
-	if (EDMA_EN & reg) {
+	if (reg & EDMA_EN) {
 		ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
-		/* FIXME: Consider doing a reset here to recover */
+		err = -EIO;
 	}
+
+	return err;
 }
 
 #ifdef ATA_DEBUG
@@ -884,12 +979,13 @@
 		writelfl(val, mv_ap_base(ap) + ofs);
 }
 
-static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio)
+static void mv_edma_cfg(struct ata_port *ap, struct mv_host_priv *hpriv,
+			void __iomem *port_mmio)
 {
 	u32 cfg = readl(port_mmio + EDMA_CFG_OFS);
 
 	/* set up non-NCQ EDMA configuration */
-	cfg &= ~(1 << 9);	/* disable equeue */
+	cfg &= ~(1 << 9);	/* disable eQue */
 
 	if (IS_GEN_I(hpriv)) {
 		cfg &= ~0x1f;		/* clear queue depth */
@@ -909,7 +1005,7 @@
 		cfg |= (1 << 18);	/* enab early completion */
 		cfg |= (1 << 17);	/* enab cut-through (dis stor&forwrd) */
 		cfg &= ~(1 << 16);	/* dis FIS-based switching (for now) */
-		cfg &= ~(EDMA_CFG_NCQ | EDMA_CFG_NCQ_GO_ON_ERR); /* clear NCQ */
+		cfg &= ~(EDMA_CFG_NCQ);	/* clear NCQ */
 	}
 
 	writelfl(cfg, port_mmio + EDMA_CFG_OFS);
@@ -971,28 +1067,9 @@
 	pp->sg_tbl = mem;
 	pp->sg_tbl_dma = mem_dma;
 
-	mv_edma_cfg(hpriv, port_mmio);
+	mv_edma_cfg(ap, hpriv, port_mmio);
 
-	writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS);
-	writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK,
-		 port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
-
-	if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
-		writelfl(pp->crqb_dma & 0xffffffff,
-			 port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
-	else
-		writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS);
-
-	writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS);
-
-	if (hpriv->hp_flags & MV_HP_ERRATA_XX42A0)
-		writelfl(pp->crpb_dma & 0xffffffff,
-			 port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
-	else
-		writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS);
-
-	writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK,
-		 port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+	mv_set_edma_ptrs(port_mmio, hpriv, pp);
 
 	/* Don't turn on EDMA here...do it before DMA commands only.  Else
 	 * we'll be unable to send non-data, PIO, etc due to restricted access
@@ -1055,11 +1132,6 @@
 	return n_sg;
 }
 
-static inline unsigned mv_inc_q_index(unsigned index)
-{
-	return (index + 1) & MV_MAX_Q_DEPTH_MASK;
-}
-
 static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
 {
 	u16 tmp = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS |
@@ -1088,7 +1160,7 @@
 	u16 flags = 0;
 	unsigned in_index;
 
- 	if (ATA_PROT_DMA != qc->tf.protocol)
+ 	if (qc->tf.protocol != ATA_PROT_DMA)
 		return;
 
 	/* Fill in command request block
@@ -1097,10 +1169,10 @@
 		flags |= CRQB_FLAG_READ;
 	WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
 	flags |= qc->tag << CRQB_TAG_SHIFT;
+	flags |= qc->tag << CRQB_IOID_SHIFT;	/* 50xx appears to ignore this*/
 
-	/* get current queue index from hardware */
-	in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS)
-			>> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
+	/* get current queue index from software */
+	in_index = pp->req_idx & MV_MAX_Q_DEPTH_MASK;
 
 	pp->crqb[in_index].sg_addr =
 		cpu_to_le32(pp->sg_tbl_dma & 0xffffffff);
@@ -1180,7 +1252,7 @@
 	unsigned in_index;
 	u32 flags = 0;
 
- 	if (ATA_PROT_DMA != qc->tf.protocol)
+ 	if (qc->tf.protocol != ATA_PROT_DMA)
 		return;
 
 	/* Fill in Gen IIE command request block
@@ -1190,10 +1262,11 @@
 
 	WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
 	flags |= qc->tag << CRQB_TAG_SHIFT;
+	flags |= qc->tag << CRQB_IOID_SHIFT;	/* "I/O Id" is -really-
+						   what we use as our tag */
 
-	/* get current queue index from hardware */
-	in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS)
-			>> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
+	/* get current queue index from software */
+	in_index = pp->req_idx & MV_MAX_Q_DEPTH_MASK;
 
 	crqb = (struct mv_crqb_iie *) &pp->crqb[in_index];
 	crqb->addr = cpu_to_le32(pp->sg_tbl_dma & 0xffffffff);
@@ -1241,83 +1314,41 @@
  */
 static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
 {
-	void __iomem *port_mmio = mv_ap_base(qc->ap);
-	struct mv_port_priv *pp = qc->ap->private_data;
-	unsigned in_index;
-	u32 in_ptr;
+	struct ata_port *ap = qc->ap;
+	void __iomem *port_mmio = mv_ap_base(ap);
+	struct mv_port_priv *pp = ap->private_data;
+	struct mv_host_priv *hpriv = ap->host->private_data;
+	u32 in_index;
 
-	if (ATA_PROT_DMA != qc->tf.protocol) {
+	if (qc->tf.protocol != ATA_PROT_DMA) {
 		/* We're about to send a non-EDMA capable command to the
 		 * port.  Turn off EDMA so there won't be problems accessing
 		 * shadow block, etc registers.
 		 */
-		mv_stop_dma(qc->ap);
+		mv_stop_dma(ap);
 		return ata_qc_issue_prot(qc);
 	}
 
-	in_ptr   = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
-	in_index = (in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
+	mv_start_dma(port_mmio, hpriv, pp);
+
+	in_index = pp->req_idx & MV_MAX_Q_DEPTH_MASK;
 
 	/* until we do queuing, the queue should be empty at this point */
 	WARN_ON(in_index != ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS)
 		>> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
 
-	in_index = mv_inc_q_index(in_index);	/* now incr producer index */
+	pp->req_idx++;
 
-	mv_start_dma(port_mmio, pp);
+	in_index = (pp->req_idx & MV_MAX_Q_DEPTH_MASK) << EDMA_REQ_Q_PTR_SHIFT;
 
 	/* and write the request in pointer to kick the EDMA to life */
-	in_ptr &= EDMA_REQ_Q_BASE_LO_MASK;
-	in_ptr |= in_index << EDMA_REQ_Q_PTR_SHIFT;
-	writelfl(in_ptr, port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+	writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
+		 port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
 
 	return 0;
 }
 
 /**
- *      mv_get_crpb_status - get status from most recently completed cmd
- *      @ap: ATA channel to manipulate
- *
- *      This routine is for use when the port is in DMA mode, when it
- *      will be using the CRPB (command response block) method of
- *      returning command completion information.  We check indices
- *      are good, grab status, and bump the response consumer index to
- *      prove that we're up to date.
- *
- *      LOCKING:
- *      Inherited from caller.
- */
-static u8 mv_get_crpb_status(struct ata_port *ap)
-{
-	void __iomem *port_mmio = mv_ap_base(ap);
-	struct mv_port_priv *pp = ap->private_data;
-	unsigned out_index;
-	u32 out_ptr;
-	u8 ata_status;
-
-	out_ptr   = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
-	out_index = (out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
-
-	ata_status = le16_to_cpu(pp->crpb[out_index].flags)
-					>> CRPB_FLAG_STATUS_SHIFT;
-
-	/* increment our consumer index... */
-	out_index = mv_inc_q_index(out_index);
-
-	/* and, until we do NCQ, there should only be 1 CRPB waiting */
-	WARN_ON(out_index != ((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS)
-		>> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
-
-	/* write out our inc'd consumer index so EDMA knows we're caught up */
-	out_ptr &= EDMA_RSP_Q_BASE_LO_MASK;
-	out_ptr |= out_index << EDMA_RSP_Q_PTR_SHIFT;
-	writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
-
-	/* Return ATA status register for completed CRPB */
-	return ata_status;
-}
-
-/**
  *      mv_err_intr - Handle error interrupts on the port
  *      @ap: ATA channel to manipulate
  *      @reset_allowed: bool: 0 == don't trigger from reset here
@@ -1331,30 +1362,191 @@
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_err_intr(struct ata_port *ap, int reset_allowed)
+static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
 {
 	void __iomem *port_mmio = mv_ap_base(ap);
-	u32 edma_err_cause, serr = 0;
+	u32 edma_err_cause, eh_freeze_mask, serr = 0;
+	struct mv_port_priv *pp = ap->private_data;
+	struct mv_host_priv *hpriv = ap->host->private_data;
+	unsigned int edma_enabled = (pp->pp_flags & MV_PP_FLAG_EDMA_EN);
+	unsigned int action = 0, err_mask = 0;
+	struct ata_eh_info *ehi = &ap->eh_info;
 
-	edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+	ata_ehi_clear_desc(ehi);
 
-	if (EDMA_ERR_SERR & edma_err_cause) {
+	if (!edma_enabled) {
+		/* just a guess: do we need to do this? should we
+		 * expand this, and do it in all cases?
+		 */
 		sata_scr_read(ap, SCR_ERROR, &serr);
 		sata_scr_write_flush(ap, SCR_ERROR, serr);
 	}
-	if (EDMA_ERR_SELF_DIS & edma_err_cause) {
-		struct mv_port_priv *pp	= ap->private_data;
-		pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+
+	edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+
+	ata_ehi_push_desc(ehi, "edma_err 0x%08x", edma_err_cause);
+
+	/*
+	 * all generations share these EDMA error cause bits
+	 */
+
+	if (edma_err_cause & EDMA_ERR_DEV)
+		err_mask |= AC_ERR_DEV;
+	if (edma_err_cause & (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR |
+			EDMA_ERR_CRBQ_PAR | EDMA_ERR_CRPB_PAR |
+			EDMA_ERR_INTRL_PAR)) {
+		err_mask |= AC_ERR_ATA_BUS;
+		action |= ATA_EH_HARDRESET;
+		ata_ehi_push_desc(ehi, ", parity error");
 	}
-	DPRINTK(KERN_ERR "ata%u: port error; EDMA err cause: 0x%08x "
-		"SERR: 0x%08x\n", ap->print_id, edma_err_cause, serr);
+	if (edma_err_cause & (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON)) {
+		ata_ehi_hotplugged(ehi);
+		ata_ehi_push_desc(ehi, edma_err_cause & EDMA_ERR_DEV_DCON ?
+			", dev disconnect" : ", dev connect");
+	}
+
+	if (IS_GEN_I(hpriv)) {
+		eh_freeze_mask = EDMA_EH_FREEZE_5;
+
+		if (edma_err_cause & EDMA_ERR_SELF_DIS_5) {
+			struct mv_port_priv *pp	= ap->private_data;
+			pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+			ata_ehi_push_desc(ehi, ", EDMA self-disable");
+		}
+	} else {
+		eh_freeze_mask = EDMA_EH_FREEZE;
+
+		if (edma_err_cause & EDMA_ERR_SELF_DIS) {
+			struct mv_port_priv *pp	= ap->private_data;
+			pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+			ata_ehi_push_desc(ehi, ", EDMA self-disable");
+		}
+
+		if (edma_err_cause & EDMA_ERR_SERR) {
+			sata_scr_read(ap, SCR_ERROR, &serr);
+			sata_scr_write_flush(ap, SCR_ERROR, serr);
+			err_mask = AC_ERR_ATA_BUS;
+			action |= ATA_EH_HARDRESET;
+		}
+	}
 
 	/* Clear EDMA now that SERR cleanup done */
 	writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
 
-	/* check for fatal here and recover if needed */
-	if (reset_allowed && (EDMA_ERR_FATAL & edma_err_cause))
-		mv_stop_and_reset(ap);
+	if (!err_mask) {
+		err_mask = AC_ERR_OTHER;
+		action |= ATA_EH_HARDRESET;
+	}
+
+	ehi->serror |= serr;
+	ehi->action |= action;
+
+	if (qc)
+		qc->err_mask |= err_mask;
+	else
+		ehi->err_mask |= err_mask;
+
+	if (edma_err_cause & eh_freeze_mask)
+		ata_port_freeze(ap);
+	else
+		ata_port_abort(ap);
+}
+
+static void mv_intr_pio(struct ata_port *ap)
+{
+	struct ata_queued_cmd *qc;
+	u8 ata_status;
+
+	/* ignore spurious intr if drive still BUSY */
+	ata_status = readb(ap->ioaddr.status_addr);
+	if (unlikely(ata_status & ATA_BUSY))
+		return;
+
+	/* get active ATA command */
+	qc = ata_qc_from_tag(ap, ap->active_tag);
+	if (unlikely(!qc))			/* no active tag */
+		return;
+	if (qc->tf.flags & ATA_TFLAG_POLLING)	/* polling; we don't own qc */
+		return;
+
+	/* and finally, complete the ATA command */
+	qc->err_mask |= ac_err_mask(ata_status);
+	ata_qc_complete(qc);
+}
+
+static void mv_intr_edma(struct ata_port *ap)
+{
+	void __iomem *port_mmio = mv_ap_base(ap);
+	struct mv_host_priv *hpriv = ap->host->private_data;
+	struct mv_port_priv *pp = ap->private_data;
+	struct ata_queued_cmd *qc;
+	u32 out_index, in_index;
+	bool work_done = false;
+
+	/* get h/w response queue pointer */
+	in_index = (readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS)
+			>> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
+
+	while (1) {
+		u16 status;
+
+		/* get s/w response queue last-read pointer, and compare */
+		out_index = pp->resp_idx & MV_MAX_Q_DEPTH_MASK;
+		if (in_index == out_index)
+			break;
+
+		 
+		/* 50xx: get active ATA command */
+		if (IS_GEN_I(hpriv)) 
+			qc = ata_qc_from_tag(ap, ap->active_tag);
+
+		/* 60xx: get active ATA command via tag, to enable support
+		 * for queueing.  this works transparently for queued and
+		 * non-queued modes.
+		 */
+		else {
+			unsigned int tag;
+
+			if (IS_GEN_II(hpriv))
+				tag = (le16_to_cpu(pp->crpb[out_index].id)
+					>> CRPB_IOID_SHIFT_6) & 0x3f;
+			else
+				tag = (le16_to_cpu(pp->crpb[out_index].id)
+					>> CRPB_IOID_SHIFT_7) & 0x3f;
+
+			qc = ata_qc_from_tag(ap, tag);
+		}
+
+		/* lower 8 bits of status are EDMA_ERR_IRQ_CAUSE_OFS
+		 * bits (WARNING: might not necessarily be associated
+		 * with this command), which -should- be clear
+		 * if all is well
+		 */
+		status = le16_to_cpu(pp->crpb[out_index].flags);
+		if (unlikely(status & 0xff)) {
+			mv_err_intr(ap, qc);
+			return;
+		}
+
+		/* and finally, complete the ATA command */
+		if (qc) {
+			qc->err_mask |=
+				ac_err_mask(status >> CRPB_FLAG_STATUS_SHIFT);
+			ata_qc_complete(qc);
+		}
+
+		/* advance software response queue pointer, to 
+		 * indicate (after the loop completes) to hardware
+		 * that we have consumed a response queue entry.
+		 */
+		work_done = true;
+		pp->resp_idx++;
+	}
+
+	if (work_done)
+		writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) |
+			 (out_index << EDMA_RSP_Q_PTR_SHIFT),
+			 port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
 }
 
 /**
@@ -1377,10 +1569,8 @@
 {
 	void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
 	void __iomem *hc_mmio = mv_hc_base(mmio, hc);
-	struct ata_queued_cmd *qc;
 	u32 hc_irq_cause;
-	int shift, port, port0, hard_port, handled;
-	unsigned int err_mask;
+	int port, port0;
 
 	if (hc == 0)
 		port0 = 0;
@@ -1389,79 +1579,95 @@
 
 	/* we'll need the HC success int register in most cases */
 	hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
-	if (hc_irq_cause)
-		writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+	if (!hc_irq_cause)
+		return;
+
+	writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
 
 	VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n",
 		hc,relevant,hc_irq_cause);
 
 	for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) {
-		u8 ata_status = 0;
 		struct ata_port *ap = host->ports[port];
 		struct mv_port_priv *pp = ap->private_data;
+		int have_err_bits, hard_port, shift;
 
-		hard_port = mv_hardport_from_port(port); /* range 0..3 */
-		handled = 0;	/* ensure ata_status is set if handled++ */
-
-		/* Note that DEV_IRQ might happen spuriously during EDMA,
-		 * and should be ignored in such cases.
-		 * The cause of this is still under investigation.
-		 */
-		if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
-			/* EDMA: check for response queue interrupt */
-			if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) {
-				ata_status = mv_get_crpb_status(ap);
-				handled = 1;
-			}
-		} else {
-			/* PIO: check for device (drive) interrupt */
-			if ((DEV_IRQ << hard_port) & hc_irq_cause) {
-				ata_status = readb(ap->ioaddr.status_addr);
-				handled = 1;
-				/* ignore spurious intr if drive still BUSY */
-				if (ata_status & ATA_BUSY) {
-					ata_status = 0;
-					handled = 0;
-				}
-			}
-		}
-
-		if (ap && (ap->flags & ATA_FLAG_DISABLED))
+		if ((!ap) || (ap->flags & ATA_FLAG_DISABLED))
 			continue;
 
-		err_mask = ac_err_mask(ata_status);
-
 		shift = port << 1;		/* (port * 2) */
 		if (port >= MV_PORTS_PER_HC) {
 			shift++;	/* skip bit 8 in the HC Main IRQ reg */
 		}
-		if ((PORT0_ERR << shift) & relevant) {
-			mv_err_intr(ap, 1);
-			err_mask |= AC_ERR_OTHER;
-			handled = 1;
+		have_err_bits = ((PORT0_ERR << shift) & relevant);
+
+		if (unlikely(have_err_bits)) {
+			struct ata_queued_cmd *qc;
+
+			qc = ata_qc_from_tag(ap, ap->active_tag);
+			if (qc && (qc->tf.flags & ATA_TFLAG_POLLING))
+				continue;
+
+			mv_err_intr(ap, qc);
+			continue;
 		}
 
-		if (handled) {
-			qc = ata_qc_from_tag(ap, ap->active_tag);
-			if (qc && (qc->flags & ATA_QCFLAG_ACTIVE)) {
-				VPRINTK("port %u IRQ found for qc, "
-					"ata_status 0x%x\n", port,ata_status);
-				/* mark qc status appropriately */
-				if (!(qc->tf.flags & ATA_TFLAG_POLLING)) {
-					qc->err_mask |= err_mask;
-					ata_qc_complete(qc);
-				}
-			}
+		hard_port = mv_hardport_from_port(port); /* range 0..3 */
+
+		if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
+			if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause)
+				mv_intr_edma(ap);
+		} else {
+			if ((DEV_IRQ << hard_port) & hc_irq_cause)
+				mv_intr_pio(ap);
 		}
 	}
 	VPRINTK("EXIT\n");
 }
 
+static void mv_pci_error(struct ata_host *host, void __iomem *mmio)
+{
+	struct ata_port *ap;
+	struct ata_queued_cmd *qc;
+	struct ata_eh_info *ehi;
+	unsigned int i, err_mask, printed = 0;
+	u32 err_cause;
+
+	err_cause = readl(mmio + PCI_IRQ_CAUSE_OFS);
+
+	dev_printk(KERN_ERR, host->dev, "PCI ERROR; PCI IRQ cause=0x%08x\n",
+		   err_cause);
+
+	DPRINTK("All regs @ PCI error\n");
+	mv_dump_all_regs(mmio, -1, to_pci_dev(host->dev));
+
+	writelfl(0, mmio + PCI_IRQ_CAUSE_OFS);
+
+	for (i = 0; i < host->n_ports; i++) {
+		ap = host->ports[i];
+		if (!ata_port_offline(ap)) {
+			ehi = &ap->eh_info;
+			ata_ehi_clear_desc(ehi);
+			if (!printed++)
+				ata_ehi_push_desc(ehi,
+					"PCI err cause 0x%08x", err_cause);
+			err_mask = AC_ERR_HOST_BUS;
+			ehi->action = ATA_EH_HARDRESET;
+			qc = ata_qc_from_tag(ap, ap->active_tag);
+			if (qc)
+				qc->err_mask |= err_mask;
+			else
+				ehi->err_mask |= err_mask;
+
+			ata_port_freeze(ap);
+		}
+	}
+}
+
 /**
- *      mv_interrupt -
+ *      mv_interrupt - Main interrupt event handler
  *      @irq: unused
  *      @dev_instance: private data; in this case the host structure
- *      @regs: unused
  *
  *      Read the read only register to determine if any host
  *      controllers have pending interrupts.  If so, call lower level
@@ -1477,7 +1683,6 @@
 	struct ata_host *host = dev_instance;
 	unsigned int hc, handled = 0, n_hcs;
 	void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
-	struct mv_host_priv *hpriv;
 	u32 irq_stat;
 
 	irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS);
@@ -1491,34 +1696,21 @@
 	n_hcs = mv_get_hc_count(host->ports[0]->flags);
 	spin_lock(&host->lock);
 
+	if (unlikely(irq_stat & PCI_ERR)) {
+		mv_pci_error(host, mmio);
+		handled = 1;
+		goto out_unlock;	/* skip all other HC irq handling */
+	}
+
 	for (hc = 0; hc < n_hcs; hc++) {
 		u32 relevant = irq_stat & (HC0_IRQ_PEND << (hc * HC_SHIFT));
 		if (relevant) {
 			mv_host_intr(host, relevant, hc);
-			handled++;
+			handled = 1;
 		}
 	}
 
-	hpriv = host->private_data;
-	if (IS_60XX(hpriv)) {
-		/* deal with the interrupt coalescing bits */
-		if (irq_stat & (TRAN_LO_DONE | TRAN_HI_DONE | PORTS_0_7_COAL_DONE)) {
-			writelfl(0, mmio + MV_IRQ_COAL_CAUSE_LO);
-			writelfl(0, mmio + MV_IRQ_COAL_CAUSE_HI);
-			writelfl(0, mmio + MV_IRQ_COAL_CAUSE);
-		}
-	}
-
-	if (PCI_ERR & irq_stat) {
-		printk(KERN_ERR DRV_NAME ": PCI ERROR; PCI IRQ cause=0x%08x\n",
-		       readl(mmio + PCI_IRQ_CAUSE_OFS));
-
-		DPRINTK("All regs @ PCI error\n");
-		mv_dump_all_regs(mmio, -1, to_pci_dev(host->dev));
-
-		writelfl(0, mmio + PCI_IRQ_CAUSE_OFS);
-		handled++;
-	}
+out_unlock:
 	spin_unlock(&host->lock);
 
 	return IRQ_RETVAL(handled);
@@ -1904,7 +2096,7 @@
 
 	writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
 
-	if (IS_60XX(hpriv)) {
+	if (IS_GEN_II(hpriv)) {
 		u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL);
 		ifctl |= (1 << 7);		/* enable gen2i speed */
 		ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */
@@ -1920,32 +2112,12 @@
 
 	hpriv->ops->phy_errata(hpriv, mmio, port_no);
 
-	if (IS_50XX(hpriv))
+	if (IS_GEN_I(hpriv))
 		mdelay(1);
 }
 
-static void mv_stop_and_reset(struct ata_port *ap)
-{
-	struct mv_host_priv *hpriv = ap->host->private_data;
-	void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
-
-	mv_stop_dma(ap);
-
-	mv_channel_reset(hpriv, mmio, ap->port_no);
-
-	__mv_phy_reset(ap, 0);
-}
-
-static inline void __msleep(unsigned int msec, int can_sleep)
-{
-	if (can_sleep)
-		msleep(msec);
-	else
-		mdelay(msec);
-}
-
 /**
- *      __mv_phy_reset - Perform eDMA reset followed by COMRESET
+ *      mv_phy_reset - Perform eDMA reset followed by COMRESET
  *      @ap: ATA channel to manipulate
  *
  *      Part of this is taken from __sata_phy_reset and modified to
@@ -1955,14 +2127,12 @@
  *      Inherited from caller.  This is coded to safe to call at
  *      interrupt level, i.e. it does not sleep.
  */
-static void __mv_phy_reset(struct ata_port *ap, int can_sleep)
+static void mv_phy_reset(struct ata_port *ap, unsigned int *class,
+			 unsigned long deadline)
 {
 	struct mv_port_priv *pp	= ap->private_data;
 	struct mv_host_priv *hpriv = ap->host->private_data;
 	void __iomem *port_mmio = mv_ap_base(ap);
-	struct ata_taskfile tf;
-	struct ata_device *dev = &ap->device[0];
-	unsigned long timeout;
 	int retry = 5;
 	u32 sstatus;
 
@@ -1975,22 +2145,21 @@
 	/* Issue COMRESET via SControl */
 comreset_retry:
 	sata_scr_write_flush(ap, SCR_CONTROL, 0x301);
-	__msleep(1, can_sleep);
+	msleep(1);
 
 	sata_scr_write_flush(ap, SCR_CONTROL, 0x300);
-	__msleep(20, can_sleep);
+	msleep(20);
 
-	timeout = jiffies + msecs_to_jiffies(200);
 	do {
 		sata_scr_read(ap, SCR_STATUS, &sstatus);
 		if (((sstatus & 0x3) == 3) || ((sstatus & 0x3) == 0))
 			break;
 
-		__msleep(1, can_sleep);
-	} while (time_before(jiffies, timeout));
+		msleep(1);
+	} while (time_before(jiffies, deadline));
 
 	/* work around errata */
-	if (IS_60XX(hpriv) &&
+	if (IS_GEN_II(hpriv) &&
 	    (sstatus != 0x0) && (sstatus != 0x113) && (sstatus != 0x123) &&
 	    (retry-- > 0))
 		goto comreset_retry;
@@ -1999,13 +2168,8 @@
 		"SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
 		mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
 
-	if (ata_port_online(ap)) {
-		ata_port_probe(ap);
-	} else {
-		sata_scr_read(ap, SCR_STATUS, &sstatus);
-		ata_port_printk(ap, KERN_INFO,
-				"no device found (phy stat %08x)\n", sstatus);
-		ata_port_disable(ap);
+	if (ata_port_offline(ap)) {
+		*class = ATA_DEV_NONE;
 		return;
 	}
 
@@ -2019,68 +2183,152 @@
 		u8 drv_stat = ata_check_status(ap);
 		if ((drv_stat != 0x80) && (drv_stat != 0x7f))
 			break;
-		__msleep(500, can_sleep);
+		msleep(500);
 		if (retry-- <= 0)
 			break;
+		if (time_after(jiffies, deadline))
+			break;
 	}
 
-	tf.lbah = readb(ap->ioaddr.lbah_addr);
-	tf.lbam = readb(ap->ioaddr.lbam_addr);
-	tf.lbal = readb(ap->ioaddr.lbal_addr);
-	tf.nsect = readb(ap->ioaddr.nsect_addr);
+	/* FIXME: if we passed the deadline, the following
+	 * code probably produces an invalid result
+	 */
 
-	dev->class = ata_dev_classify(&tf);
-	if (!ata_dev_enabled(dev)) {
-		VPRINTK("Port disabled post-sig: No device present.\n");
-		ata_port_disable(ap);
-	}
+	/* finally, read device signature from TF registers */
+	*class = ata_dev_try_classify(ap, 0, NULL);
 
 	writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
 
-	pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+	WARN_ON(pp->pp_flags & MV_PP_FLAG_EDMA_EN);
 
 	VPRINTK("EXIT\n");
 }
 
-static void mv_phy_reset(struct ata_port *ap)
+static int mv_prereset(struct ata_port *ap, unsigned long deadline)
 {
-	__mv_phy_reset(ap, 1);
+	struct mv_port_priv *pp	= ap->private_data;
+	struct ata_eh_context *ehc = &ap->eh_context;
+	int rc;
+	
+	rc = mv_stop_dma(ap);
+	if (rc)
+		ehc->i.action |= ATA_EH_HARDRESET;
+
+	if (!(pp->pp_flags & MV_PP_FLAG_HAD_A_RESET)) {
+		pp->pp_flags |= MV_PP_FLAG_HAD_A_RESET;
+		ehc->i.action |= ATA_EH_HARDRESET;
+	}
+
+	/* if we're about to do hardreset, nothing more to do */
+	if (ehc->i.action & ATA_EH_HARDRESET)
+		return 0;
+
+	if (ata_port_online(ap))
+		rc = ata_wait_ready(ap, deadline);
+	else
+		rc = -ENODEV;
+
+	return rc;
 }
 
-/**
- *      mv_eng_timeout - Routine called by libata when SCSI times out I/O
- *      @ap: ATA channel to manipulate
- *
- *      Intent is to clear all pending error conditions, reset the
- *      chip/bus, fail the command, and move on.
- *
- *      LOCKING:
- *      This routine holds the host lock while failing the command.
- */
-static void mv_eng_timeout(struct ata_port *ap)
+static int mv_hardreset(struct ata_port *ap, unsigned int *class,
+			unsigned long deadline)
+{
+	struct mv_host_priv *hpriv = ap->host->private_data;
+	void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
+
+	mv_stop_dma(ap);
+
+	mv_channel_reset(hpriv, mmio, ap->port_no);
+
+	mv_phy_reset(ap, class, deadline);
+
+	return 0;
+}
+
+static void mv_postreset(struct ata_port *ap, unsigned int *classes)
+{
+	u32 serr;
+
+	/* print link status */
+	sata_print_link_status(ap);
+
+	/* clear SError */
+	sata_scr_read(ap, SCR_ERROR, &serr);
+	sata_scr_write_flush(ap, SCR_ERROR, serr);
+
+	/* bail out if no device is present */
+	if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
+		DPRINTK("EXIT, no device\n");
+		return;
+	}
+
+	/* set up device control */
+	iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
+}
+
+static void mv_error_handler(struct ata_port *ap)
+{
+	ata_do_eh(ap, mv_prereset, ata_std_softreset,
+		  mv_hardreset, mv_postreset);
+}
+
+static void mv_post_int_cmd(struct ata_queued_cmd *qc)
+{
+	mv_stop_dma(qc->ap);
+}
+
+static void mv_eh_freeze(struct ata_port *ap)
 {
 	void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
-	struct ata_queued_cmd *qc;
-	unsigned long flags;
+	unsigned int hc = (ap->port_no > 3) ? 1 : 0;
+	u32 tmp, mask;
+	unsigned int shift;
 
-	ata_port_printk(ap, KERN_ERR, "Entering mv_eng_timeout\n");
-	DPRINTK("All regs @ start of eng_timeout\n");
-	mv_dump_all_regs(mmio, ap->port_no, to_pci_dev(ap->host->dev));
+	/* FIXME: handle coalescing completion events properly */
 
-	qc = ata_qc_from_tag(ap, ap->active_tag);
-        printk(KERN_ERR "mmio_base %p ap %p qc %p scsi_cmnd %p &cmnd %p\n",
-	       mmio, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd);
+	shift = ap->port_no * 2;
+	if (hc > 0)
+		shift++;
 
-	spin_lock_irqsave(&ap->host->lock, flags);
-	mv_err_intr(ap, 0);
-	mv_stop_and_reset(ap);
-	spin_unlock_irqrestore(&ap->host->lock, flags);
+	mask = 0x3 << shift;
 
-	WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
-	if (qc->flags & ATA_QCFLAG_ACTIVE) {
-		qc->err_mask |= AC_ERR_TIMEOUT;
-		ata_eh_qc_complete(qc);
+	/* disable assertion of portN err, done events */
+	tmp = readl(mmio + HC_MAIN_IRQ_MASK_OFS);
+	writelfl(tmp & ~mask, mmio + HC_MAIN_IRQ_MASK_OFS);
+}
+
+static void mv_eh_thaw(struct ata_port *ap)
+{
+	void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
+	unsigned int hc = (ap->port_no > 3) ? 1 : 0;
+	void __iomem *hc_mmio = mv_hc_base(mmio, hc);
+	void __iomem *port_mmio = mv_ap_base(ap);
+	u32 tmp, mask, hc_irq_cause;
+	unsigned int shift, hc_port_no = ap->port_no;
+
+	/* FIXME: handle coalescing completion events properly */
+
+	shift = ap->port_no * 2;
+	if (hc > 0) {
+		shift++;
+		hc_port_no -= 4;
 	}
+
+	mask = 0x3 << shift;
+
+	/* clear EDMA errors on this port */
+	writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+
+	/* clear pending irq events */
+	hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
+	hc_irq_cause &= ~(1 << hc_port_no);	/* clear CRPB-done */
+	hc_irq_cause &= ~(1 << (hc_port_no + 8)); /* clear Device int */
+	writel(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+
+	/* enable assertion of portN err, done events */
+	tmp = readl(mmio + HC_MAIN_IRQ_MASK_OFS);
+	writelfl(tmp | mask, mmio + HC_MAIN_IRQ_MASK_OFS);
 }
 
 /**
@@ -2141,7 +2389,7 @@
 	switch(board_idx) {
 	case chip_5080:
 		hpriv->ops = &mv5xxx_ops;
-		hp_flags |= MV_HP_50XX;
+		hp_flags |= MV_HP_GEN_I;
 
 		switch (pdev->revision) {
 		case 0x1:
@@ -2161,7 +2409,7 @@
 	case chip_504x:
 	case chip_508x:
 		hpriv->ops = &mv5xxx_ops;
-		hp_flags |= MV_HP_50XX;
+		hp_flags |= MV_HP_GEN_I;
 
 		switch (pdev->revision) {
 		case 0x0:
@@ -2181,6 +2429,7 @@
 	case chip_604x:
 	case chip_608x:
 		hpriv->ops = &mv6xxx_ops;
+		hp_flags |= MV_HP_GEN_II;
 
 		switch (pdev->revision) {
 		case 0x7:
@@ -2200,7 +2449,6 @@
 	case chip_7042:
 	case chip_6042:
 		hpriv->ops = &mv6xxx_ops;
-
 		hp_flags |= MV_HP_GEN_IIE;
 
 		switch (pdev->revision) {
@@ -2267,7 +2515,7 @@
 	hpriv->ops->enable_leds(hpriv, mmio);
 
 	for (port = 0; port < host->n_ports; port++) {
-		if (IS_60XX(hpriv)) {
+		if (IS_GEN_II(hpriv)) {
 			void __iomem *port_mmio = mv_port_base(mmio, port);
 
 			u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL);
@@ -2302,7 +2550,7 @@
 	/* and unmask interrupt generation for host regs */
 	writelfl(PCI_UNMASK_ALL_IRQS, mmio + PCI_IRQ_MASK_OFS);
 
-	if (IS_50XX(hpriv))
+	if (IS_GEN_I(hpriv))
 		writelfl(~HC_MAIN_MASKED_IRQS_5, mmio + HC_MAIN_IRQ_MASK_OFS);
 	else
 		writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS);
@@ -2418,8 +2666,9 @@
 	mv_print_info(host);
 
 	pci_set_master(pdev);
+	pci_set_mwi(pdev);
 	return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
-				 &mv_sht);
+				 IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht);
 }
 
 static int __init mv_init(void)
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index b265686..db81e3e 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1560,7 +1560,7 @@
 	}
 
 	ppi[0] = &nv_port_info[type];
-	rc = ata_pci_prepare_native_host(pdev, ppi, &host);
+	rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
 	if (rc)
 		return rc;
 
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 2ad5872..d2fcb9a 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -45,7 +45,7 @@
 #include "sata_promise.h"
 
 #define DRV_NAME	"sata_promise"
-#define DRV_VERSION	"2.08"
+#define DRV_VERSION	"2.09"
 
 enum {
 	PDC_MAX_PORTS		= 4,
@@ -716,6 +716,9 @@
 	unsigned int i, tmp;
 	unsigned int handled = 0;
 	void __iomem *mmio_base;
+	unsigned int hotplug_offset, ata_no;
+	u32 hotplug_status;
+	int is_sataii_tx4;
 
 	VPRINTK("ENTER\n");
 
@@ -726,10 +729,20 @@
 
 	mmio_base = host->iomap[PDC_MMIO_BAR];
 
+	/* read and clear hotplug flags for all ports */
+	if (host->ports[0]->flags & PDC_FLAG_GEN_II)
+		hotplug_offset = PDC2_SATA_PLUG_CSR;
+	else
+		hotplug_offset = PDC_SATA_PLUG_CSR;
+	hotplug_status = readl(mmio_base + hotplug_offset);
+	if (hotplug_status & 0xff)
+		writel(hotplug_status | 0xff, mmio_base + hotplug_offset);
+	hotplug_status &= 0xff;	/* clear uninteresting bits */
+
 	/* reading should also clear interrupts */
 	mask = readl(mmio_base + PDC_INT_SEQMASK);
 
-	if (mask == 0xffffffff) {
+	if (mask == 0xffffffff && hotplug_status == 0) {
 		VPRINTK("QUICK EXIT 2\n");
 		return IRQ_NONE;
 	}
@@ -737,16 +750,34 @@
 	spin_lock(&host->lock);
 
 	mask &= 0xffff;		/* only 16 tags possible */
-	if (!mask) {
+	if (mask == 0 && hotplug_status == 0) {
 		VPRINTK("QUICK EXIT 3\n");
 		goto done_irq;
 	}
 
 	writel(mask, mmio_base + PDC_INT_SEQMASK);
 
+	is_sataii_tx4 = pdc_is_sataii_tx4(host->ports[0]->flags);
+
 	for (i = 0; i < host->n_ports; i++) {
 		VPRINTK("port %u\n", i);
 		ap = host->ports[i];
+
+		/* check for a plug or unplug event */
+		ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4);
+		tmp = hotplug_status & (0x11 << ata_no);
+		if (tmp && ap &&
+		    !(ap->flags & ATA_FLAG_DISABLED)) {
+			struct ata_eh_info *ehi = &ap->eh_info;
+			ata_ehi_clear_desc(ehi);
+			ata_ehi_hotplugged(ehi);
+			ata_ehi_push_desc(ehi, "hotplug_status %#x", tmp);
+			ata_port_freeze(ap);
+			++handled;
+			continue;
+		}
+
+		/* check for a packet interrupt */
 		tmp = mask & (1 << (i + 1));
 		if (tmp && ap &&
 		    !(ap->flags & ATA_FLAG_DISABLED)) {
@@ -902,9 +933,9 @@
 	tmp = readl(mmio + hotplug_offset);
 	writel(tmp | 0xff, mmio + hotplug_offset);
 
-	/* mask plug/unplug ints */
+	/* unmask plug/unplug ints */
 	tmp = readl(mmio + hotplug_offset);
-	writel(tmp | 0xff0000, mmio + hotplug_offset);
+	writel(tmp & ~0xff0000, mmio + hotplug_offset);
 
 	/* don't initialise TBG or SLEW on 2nd generation chips */
 	if (is_gen2)
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index fd80bcf..33716b0 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -334,7 +334,7 @@
 		break;
 	}
 
-	rc = ata_pci_prepare_native_host(pdev, ppi, &host);
+	rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
 	if (rc)
 		return rc;
 
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index aca7181..b52f83a 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -213,7 +213,7 @@
 	host->private_data = hpriv;
 
 	/* the first two ports are standard SFF */
-	rc = ata_pci_init_native_host(host);
+	rc = ata_pci_init_sff_host(host);
 	if (rc)
 		return rc;
 
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index a4c0832..c412447 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -412,7 +412,7 @@
 	struct ata_host *host;
 	int rc;
 
-	rc = ata_pci_prepare_native_host(pdev, ppi, &host);
+	rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
 	if (rc)
 		return rc;
 	*r_host = host;
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index 1ec0654..7370d7c 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 
 #include "base.h"
 
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 5512d84..47eb02d 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -44,6 +44,6 @@
 
 extern char *make_class_name(const char *name, struct kobject *kobj);
 
-extern void devres_release_all(struct device *dev);
+extern int devres_release_all(struct device *dev);
 
 extern struct kset devices_subsys;
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index dca7348..61c6752 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -138,12 +138,24 @@
 	}
 }
 
-static struct kobj_type ktype_bus = {
+static struct kobj_type bus_ktype = {
 	.sysfs_ops	= &bus_sysfs_ops,
-
 };
 
-static decl_subsys(bus, &ktype_bus, NULL);
+static int bus_uevent_filter(struct kset *kset, struct kobject *kobj)
+{
+	struct kobj_type *ktype = get_ktype(kobj);
+
+	if (ktype == &bus_ktype)
+		return 1;
+	return 0;
+}
+
+static struct kset_uevent_ops bus_uevent_ops = {
+	.filter = bus_uevent_filter,
+};
+
+static decl_subsys(bus, &bus_ktype, &bus_uevent_ops);
 
 
 #ifdef CONFIG_HOTPLUG
@@ -562,7 +574,6 @@
 
 	bus->drivers_probe_attr.attr.name = "drivers_probe";
 	bus->drivers_probe_attr.attr.mode = S_IWUSR;
-	bus->drivers_probe_attr.attr.owner = bus->owner;
 	bus->drivers_probe_attr.store = store_drivers_probe;
 	retval = bus_create_file(bus, &bus->drivers_probe_attr);
 	if (retval)
@@ -570,7 +581,6 @@
 
 	bus->drivers_autoprobe_attr.attr.name = "drivers_autoprobe";
 	bus->drivers_autoprobe_attr.attr.mode = S_IWUSR | S_IRUGO;
-	bus->drivers_autoprobe_attr.attr.owner = bus->owner;
 	bus->drivers_autoprobe_attr.show = show_drivers_autoprobe;
 	bus->drivers_autoprobe_attr.store = store_drivers_autoprobe;
 	retval = bus_create_file(bus, &bus->drivers_autoprobe_attr);
@@ -610,7 +620,8 @@
 	if (error)
 		goto out_put_bus;
 	drv->kobj.kset = &bus->drivers;
-	if ((error = kobject_register(&drv->kobj)))
+	error = kobject_register(&drv->kobj);
+	if (error)
 		goto out_put_bus;
 
 	if (drv->bus->drivers_autoprobe) {
@@ -760,7 +771,8 @@
 
 	if (bus->bus_attrs) {
 		for (i = 0; attr_name(bus->bus_attrs[i]); i++) {
-			if ((error = bus_create_file(bus,&bus->bus_attrs[i])))
+			error = bus_create_file(bus,&bus->bus_attrs[i]);
+			if (error)
 				goto Err;
 		}
 	}
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 8c506db..4d22226 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -312,9 +312,6 @@
 
 	pr_debug("device class '%s': release.\n", cd->class_id);
 
-	kfree(cd->devt_attr);
-	cd->devt_attr = NULL;
-
 	if (cd->release)
 		cd->release(cd);
 	else if (cls->release)
@@ -547,6 +544,9 @@
 	return print_dev_t(buf, class_dev->devt);
 }
 
+static struct class_device_attribute class_devt_attr =
+	__ATTR(dev, S_IRUGO, show_dev, NULL);
+
 static ssize_t store_uevent(struct class_device *class_dev,
 			    const char *buf, size_t count)
 {
@@ -554,6 +554,9 @@
 	return count;
 }
 
+static struct class_device_attribute class_uevent_attr =
+	__ATTR(uevent, S_IWUSR, NULL, store_uevent);
+
 void class_device_initialize(struct class_device *class_dev)
 {
 	kobj_set_kset_s(class_dev, class_obj_subsys);
@@ -603,32 +606,15 @@
 				  &parent_class->subsys.kobj, "subsystem");
 	if (error)
 		goto out3;
-	class_dev->uevent_attr.attr.name = "uevent";
-	class_dev->uevent_attr.attr.mode = S_IWUSR;
-	class_dev->uevent_attr.attr.owner = parent_class->owner;
-	class_dev->uevent_attr.store = store_uevent;
-	error = class_device_create_file(class_dev, &class_dev->uevent_attr);
+
+	error = class_device_create_file(class_dev, &class_uevent_attr);
 	if (error)
 		goto out3;
 
 	if (MAJOR(class_dev->devt)) {
-		struct class_device_attribute *attr;
-		attr = kzalloc(sizeof(*attr), GFP_KERNEL);
-		if (!attr) {
-			error = -ENOMEM;
+		error = class_device_create_file(class_dev, &class_devt_attr);
+		if (error)
 			goto out4;
-		}
-		attr->attr.name = "dev";
-		attr->attr.mode = S_IRUGO;
-		attr->attr.owner = parent_class->owner;
-		attr->show = show_dev;
-		error = class_device_create_file(class_dev, attr);
-		if (error) {
-			kfree(attr);
-			goto out4;
-		}
-
-		class_dev->devt_attr = attr;
 	}
 
 	error = class_device_add_attrs(class_dev);
@@ -671,10 +657,10 @@
  out6:
 	class_device_remove_attrs(class_dev);
  out5:
-	if (class_dev->devt_attr)
-		class_device_remove_file(class_dev, class_dev->devt_attr);
+	if (MAJOR(class_dev->devt))
+		class_device_remove_file(class_dev, &class_devt_attr);
  out4:
-	class_device_remove_file(class_dev, &class_dev->uevent_attr);
+	class_device_remove_file(class_dev, &class_uevent_attr);
  out3:
 	kobject_del(&class_dev->kobj);
  out2:
@@ -774,9 +760,9 @@
 		sysfs_remove_link(&class_dev->kobj, "device");
 	}
 	sysfs_remove_link(&class_dev->kobj, "subsystem");
-	class_device_remove_file(class_dev, &class_dev->uevent_attr);
-	if (class_dev->devt_attr)
-		class_device_remove_file(class_dev, class_dev->devt_attr);
+	class_device_remove_file(class_dev, &class_uevent_attr);
+	if (MAJOR(class_dev->devt))
+		class_device_remove_file(class_dev, &class_devt_attr);
 	class_device_remove_attrs(class_dev);
 	class_device_remove_groups(class_dev);
 
diff --git a/drivers/base/core.c b/drivers/base/core.c
index dd40d78..0455aa7 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -310,6 +310,9 @@
 	return count;
 }
 
+static struct device_attribute uevent_attr =
+	__ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);
+
 static int device_add_attributes(struct device *dev,
 				 struct device_attribute *attrs)
 {
@@ -423,6 +426,9 @@
 	return print_dev_t(buf, dev->devt);
 }
 
+static struct device_attribute devt_attr =
+	__ATTR(dev, S_IRUGO, show_dev, NULL);
+
 /*
  *	devices_subsys - structure to be registered with kobject core.
  */
@@ -681,35 +687,14 @@
 		blocking_notifier_call_chain(&dev->bus->bus_notifier,
 					     BUS_NOTIFY_ADD_DEVICE, dev);
 
-	dev->uevent_attr.attr.name = "uevent";
-	dev->uevent_attr.attr.mode = S_IRUGO | S_IWUSR;
-	if (dev->driver)
-		dev->uevent_attr.attr.owner = dev->driver->owner;
-	dev->uevent_attr.store = store_uevent;
-	dev->uevent_attr.show = show_uevent;
-	error = device_create_file(dev, &dev->uevent_attr);
+	error = device_create_file(dev, &uevent_attr);
 	if (error)
 		goto attrError;
 
 	if (MAJOR(dev->devt)) {
-		struct device_attribute *attr;
-		attr = kzalloc(sizeof(*attr), GFP_KERNEL);
-		if (!attr) {
-			error = -ENOMEM;
+		error = device_create_file(dev, &devt_attr);
+		if (error)
 			goto ueventattrError;
-		}
-		attr->attr.name = "dev";
-		attr->attr.mode = S_IRUGO;
-		if (dev->driver)
-			attr->attr.owner = dev->driver->owner;
-		attr->show = show_dev;
-		error = device_create_file(dev, attr);
-		if (error) {
-			kfree(attr);
-			goto ueventattrError;
-		}
-
-		dev->devt_attr = attr;
 	}
 
 	if (dev->class) {
@@ -733,11 +718,14 @@
 		}
 	}
 
-	if ((error = device_add_attrs(dev)))
+	error = device_add_attrs(dev);
+	if (error)
 		goto AttrsError;
-	if ((error = device_pm_add(dev)))
+	error = device_pm_add(dev);
+	if (error)
 		goto PMError;
-	if ((error = bus_add_device(dev)))
+	error = bus_add_device(dev);
+	if (error)
 		goto BusError;
 	kobject_uevent(&dev->kobj, KOBJ_ADD);
 	bus_attach_device(dev);
@@ -767,10 +755,8 @@
 					     BUS_NOTIFY_DEL_DEVICE, dev);
 	device_remove_attrs(dev);
  AttrsError:
-	if (dev->devt_attr) {
-		device_remove_file(dev, dev->devt_attr);
-		kfree(dev->devt_attr);
-	}
+	if (MAJOR(dev->devt))
+		device_remove_file(dev, &devt_attr);
 
 	if (dev->class) {
 		sysfs_remove_link(&dev->kobj, "subsystem");
@@ -792,7 +778,7 @@
 		}
 	}
  ueventattrError:
-	device_remove_file(dev, &dev->uevent_attr);
+	device_remove_file(dev, &uevent_attr);
  attrError:
 	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
 	kobject_del(&dev->kobj);
@@ -869,10 +855,8 @@
 
 	if (parent)
 		klist_del(&dev->knode_parent);
-	if (dev->devt_attr) {
-		device_remove_file(dev, dev->devt_attr);
-		kfree(dev->devt_attr);
-	}
+	if (MAJOR(dev->devt))
+		device_remove_file(dev, &devt_attr);
 	if (dev->class) {
 		sysfs_remove_link(&dev->kobj, "subsystem");
 		/* If this is not a "fake" compatible device, remove the
@@ -926,7 +910,7 @@
 			up(&dev->class->sem);
 		}
 	}
-	device_remove_file(dev, &dev->uevent_attr);
+	device_remove_file(dev, &uevent_attr);
 	device_remove_attrs(dev);
 	bus_remove_device(dev);
 
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index b0088b0..7ac474d 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -281,24 +281,16 @@
 	return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
 }
 
-/**
- *	device_release_driver - manually detach device from driver.
- *	@dev:	device.
- *
- *	Manually detach device from driver.
- *
+/*
  *	__device_release_driver() must be called with @dev->sem held.
- *	When called for a USB interface, @dev->parent->sem must be held
- *	as well.
+ *	When called for a USB interface, @dev->parent->sem must be held as well.
  */
-
 static void __device_release_driver(struct device * dev)
 {
 	struct device_driver * drv;
 
-	drv = dev->driver;
+	drv = get_driver(dev->driver);
 	if (drv) {
-		get_driver(drv);
 		driver_sysfs_remove(dev);
 		sysfs_remove_link(&dev->kobj, "driver");
 		klist_remove(&dev->knode_driver);
@@ -318,6 +310,13 @@
 	}
 }
 
+/**
+ *	device_release_driver - manually detach device from driver.
+ *	@dev:	device.
+ *
+ *	Manually detach device from driver.
+ *	When called for a USB interface, @dev->parent->sem must be held.
+ */
 void device_release_driver(struct device * dev)
 {
 	/*
diff --git a/drivers/base/devres.c b/drivers/base/devres.c
index e1c0730..e8beb8e 100644
--- a/drivers/base/devres.c
+++ b/drivers/base/devres.c
@@ -10,6 +10,8 @@
 #include <linux/device.h>
 #include <linux/module.h>
 
+#include "base.h"
+
 struct devres_node {
 	struct list_head		entry;
 	dr_release_t			release;
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 89a5f4a..53f0ee6 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -175,7 +175,7 @@
 static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
 
 static ssize_t
-firmware_data_read(struct kobject *kobj,
+firmware_data_read(struct kobject *kobj, struct bin_attribute *bin_attr,
 		   char *buffer, loff_t offset, size_t count)
 {
 	struct device *dev = to_dev(kobj);
@@ -240,7 +240,7 @@
  *	the driver as a firmware image.
  **/
 static ssize_t
-firmware_data_write(struct kobject *kobj,
+firmware_data_write(struct kobject *kobj, struct bin_attribute *bin_attr,
 		    char *buffer, loff_t offset, size_t count)
 {
 	struct device *dev = to_dev(kobj);
@@ -271,7 +271,7 @@
 }
 
 static struct bin_attribute firmware_attr_data_tmpl = {
-	.attr = {.name = "data", .mode = 0644, .owner = THIS_MODULE},
+	.attr = {.name = "data", .mode = 0644},
 	.size = 0,
 	.read = firmware_data_read,
 	.write = firmware_data_write,
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 05dc876..eb9f38d 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -20,64 +20,44 @@
  */
 
 #include <linux/device.h>
+#include <linux/mutex.h>
+
 #include "power.h"
 
 LIST_HEAD(dpm_active);
 LIST_HEAD(dpm_off);
 LIST_HEAD(dpm_off_irq);
 
-DECLARE_MUTEX(dpm_sem);
-DECLARE_MUTEX(dpm_list_sem);
+DEFINE_MUTEX(dpm_mtx);
+DEFINE_MUTEX(dpm_list_mtx);
 
 int (*platform_enable_wakeup)(struct device *dev, int is_on);
 
-
-/**
- *	device_pm_set_parent - Specify power dependency.
- *	@dev:		Device who needs power.
- *	@parent:	Device that supplies power.
- *
- *	This function is used to manually describe a power-dependency
- *	relationship. It may be used to specify a transversal relationship
- *	(where the power supplier is not the physical (or electrical)
- *	ancestor of a specific device.
- *	The effect of this is that the supplier will not be powered down
- *	before the power dependent.
- */
-
-void device_pm_set_parent(struct device * dev, struct device * parent)
-{
-	put_device(dev->power.pm_parent);
-	dev->power.pm_parent = get_device(parent);
-}
-EXPORT_SYMBOL_GPL(device_pm_set_parent);
-
-int device_pm_add(struct device * dev)
+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",
 		 kobject_name(&dev->kobj));
-	down(&dpm_list_sem);
+	mutex_lock(&dpm_list_mtx);
 	list_add_tail(&dev->power.entry, &dpm_active);
-	device_pm_set_parent(dev, dev->parent);
-	if ((error = dpm_sysfs_add(dev)))
+	error = dpm_sysfs_add(dev);
+	if (error)
 		list_del(&dev->power.entry);
-	up(&dpm_list_sem);
+	mutex_unlock(&dpm_list_mtx);
 	return error;
 }
 
-void device_pm_remove(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",
 		 kobject_name(&dev->kobj));
-	down(&dpm_list_sem);
+	mutex_lock(&dpm_list_mtx);
 	dpm_sysfs_remove(dev);
-	put_device(dev->power.pm_parent);
 	list_del_init(&dev->power.entry);
-	up(&dpm_list_sem);
+	mutex_unlock(&dpm_list_mtx);
 }
 
 
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index fb3d35a..2760f25 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -14,12 +14,12 @@
 /*
  * Used to synchronize global power management operations.
  */
-extern struct semaphore dpm_sem;
+extern struct mutex dpm_mtx;
 
 /*
  * Used to serialize changes to the dpm_* lists.
  */
-extern struct semaphore dpm_list_sem;
+extern struct mutex dpm_list_mtx;
 
 /*
  * The PM lists.
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index a2c6418..00fd84a 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -29,14 +29,6 @@
 
 	down(&dev->sem);
 
-	if (dev->power.pm_parent
-			&& dev->power.pm_parent->power.power_state.event) {
-		dev_err(dev, "PM: resume from %d, parent %s still %d\n",
-			dev->power.power_state.event,
-			dev->power.pm_parent->bus_id,
-			dev->power.pm_parent->power.power_state.event);
-	}
-
 	if (dev->bus && dev->bus->resume) {
 		dev_dbg(dev,"resuming\n");
 		error = dev->bus->resume(dev);
@@ -80,7 +72,7 @@
  */
 void dpm_resume(void)
 {
-	down(&dpm_list_sem);
+	mutex_lock(&dpm_list_mtx);
 	while(!list_empty(&dpm_off)) {
 		struct list_head * entry = dpm_off.next;
 		struct device * dev = to_device(entry);
@@ -88,13 +80,12 @@
 		get_device(dev);
 		list_move_tail(entry, &dpm_active);
 
-		up(&dpm_list_sem);
-		if (!dev->power.prev_state.event)
-			resume_device(dev);
-		down(&dpm_list_sem);
+		mutex_unlock(&dpm_list_mtx);
+		resume_device(dev);
+		mutex_lock(&dpm_list_mtx);
 		put_device(dev);
 	}
-	up(&dpm_list_sem);
+	mutex_unlock(&dpm_list_mtx);
 }
 
 
@@ -108,9 +99,9 @@
 void device_resume(void)
 {
 	might_sleep();
-	down(&dpm_sem);
+	mutex_lock(&dpm_mtx);
 	dpm_resume();
-	up(&dpm_sem);
+	mutex_unlock(&dpm_mtx);
 }
 
 EXPORT_SYMBOL_GPL(device_resume);
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 96370ec..df6174d 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -32,9 +32,9 @@
 
 void dpm_runtime_resume(struct device * dev)
 {
-	down(&dpm_sem);
+	mutex_lock(&dpm_mtx);
 	runtime_resume(dev);
-	up(&dpm_sem);
+	mutex_unlock(&dpm_mtx);
 }
 EXPORT_SYMBOL(dpm_runtime_resume);
 
@@ -49,7 +49,7 @@
 {
 	int error = 0;
 
-	down(&dpm_sem);
+	mutex_lock(&dpm_mtx);
 	if (dev->power.power_state.event == state.event)
 		goto Done;
 
@@ -59,7 +59,7 @@
 	if (!(error = suspend_device(dev, state)))
 		dev->power.power_state = state;
  Done:
-	up(&dpm_sem);
+	mutex_unlock(&dpm_mtx);
 	return error;
 }
 EXPORT_SYMBOL(dpm_runtime_suspend);
@@ -78,8 +78,8 @@
  */
 void dpm_set_power_state(struct device * dev, pm_message_t state)
 {
-	down(&dpm_sem);
+	mutex_lock(&dpm_mtx);
 	dev->power.power_state = state;
-	up(&dpm_sem);
+	mutex_unlock(&dpm_mtx);
 }
 #endif  /*  0  */
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index 42d2b86..26df9b2 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -40,6 +40,14 @@
 }
 
 
+static void
+suspend_device_dbg(struct device *dev, pm_message_t state, char *info)
+{
+	dev_dbg(dev, "%s%s%s\n", info, suspend_verb(state.event),
+		((state.event == PM_EVENT_SUSPEND) && device_may_wakeup(dev)) ?
+		", may wakeup" : "");
+}
+
 /**
  *	suspend_device - Save state of one device.
  *	@dev:	Device.
@@ -55,49 +63,21 @@
 		dev_dbg(dev, "PM: suspend %d-->%d\n",
 			dev->power.power_state.event, state.event);
 	}
-	if (dev->power.pm_parent
-			&& dev->power.pm_parent->power.power_state.event) {
-		dev_err(dev,
-			"PM: suspend %d->%d, parent %s already %d\n",
-			dev->power.power_state.event, state.event,
-			dev->power.pm_parent->bus_id,
-			dev->power.pm_parent->power.power_state.event);
-	}
 
-	dev->power.prev_state = dev->power.power_state;
-
-	if (dev->class && dev->class->suspend && !dev->power.power_state.event) {
-		dev_dbg(dev, "class %s%s\n",
-			suspend_verb(state.event),
-			((state.event == PM_EVENT_SUSPEND)
-					&& device_may_wakeup(dev))
-				? ", may wakeup"
-				: ""
-			);
+	if (dev->class && dev->class->suspend) {
+		suspend_device_dbg(dev, state, "class ");
 		error = dev->class->suspend(dev, state);
 		suspend_report_result(dev->class->suspend, error);
 	}
 
-	if (!error && dev->type && dev->type->suspend && !dev->power.power_state.event) {
-		dev_dbg(dev, "%s%s\n",
-			suspend_verb(state.event),
-			((state.event == PM_EVENT_SUSPEND)
-					&& device_may_wakeup(dev))
-				? ", may wakeup"
-				: ""
-			);
+	if (!error && dev->type && dev->type->suspend) {
+		suspend_device_dbg(dev, state, "type ");
 		error = dev->type->suspend(dev, state);
 		suspend_report_result(dev->type->suspend, error);
 	}
 
-	if (!error && dev->bus && dev->bus->suspend && !dev->power.power_state.event) {
-		dev_dbg(dev, "%s%s\n",
-			suspend_verb(state.event),
-			((state.event == PM_EVENT_SUSPEND)
-					&& device_may_wakeup(dev))
-				? ", may wakeup"
-				: ""
-			);
+	if (!error && dev->bus && dev->bus->suspend) {
+		suspend_device_dbg(dev, state, "");
 		error = dev->bus->suspend(dev, state);
 		suspend_report_result(dev->bus->suspend, error);
 	}
@@ -108,21 +88,15 @@
 
 /*
  * This is called with interrupts off, only a single CPU
- * running. We can't do down() on a semaphore (and we don't
+ * running. We can't acquire a mutex or semaphore (and we don't
  * need the protection)
  */
 static int suspend_device_late(struct device *dev, pm_message_t state)
 {
 	int error = 0;
 
-	if (dev->bus && dev->bus->suspend_late && !dev->power.power_state.event) {
-		dev_dbg(dev, "LATE %s%s\n",
-			suspend_verb(state.event),
-			((state.event == PM_EVENT_SUSPEND)
-					&& device_may_wakeup(dev))
-				? ", may wakeup"
-				: ""
-			);
+	if (dev->bus && dev->bus->suspend_late) {
+		suspend_device_dbg(dev, state, "LATE ");
 		error = dev->bus->suspend_late(dev, state);
 		suspend_report_result(dev->bus->suspend_late, error);
 	}
@@ -153,18 +127,18 @@
 	int error = 0;
 
 	might_sleep();
-	down(&dpm_sem);
-	down(&dpm_list_sem);
+	mutex_lock(&dpm_mtx);
+	mutex_lock(&dpm_list_mtx);
 	while (!list_empty(&dpm_active) && error == 0) {
 		struct list_head * entry = dpm_active.prev;
 		struct device * dev = to_device(entry);
 
 		get_device(dev);
-		up(&dpm_list_sem);
+		mutex_unlock(&dpm_list_mtx);
 
 		error = suspend_device(dev, state);
 
-		down(&dpm_list_sem);
+		mutex_lock(&dpm_list_mtx);
 
 		/* Check if the device got removed */
 		if (!list_empty(&dev->power.entry)) {
@@ -179,11 +153,11 @@
 				error == -EAGAIN ? " (please convert to suspend_late)" : "");
 		put_device(dev);
 	}
-	up(&dpm_list_sem);
+	mutex_unlock(&dpm_list_mtx);
 	if (error)
 		dpm_resume();
 
-	up(&dpm_sem);
+	mutex_unlock(&dpm_mtx);
 	return error;
 }
 
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 29f1291..18febe2 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -21,7 +21,7 @@
 #include <linux/string.h>
 #include <linux/pm.h>
 #include <linux/device.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #include "base.h"
 
@@ -155,7 +155,7 @@
 
 
 static LIST_HEAD(sysdev_drivers);
-static DECLARE_MUTEX(sysdev_drivers_lock);
+static DEFINE_MUTEX(sysdev_drivers_lock);
 
 /**
  *	sysdev_driver_register - Register auxillary driver
@@ -172,7 +172,7 @@
 int sysdev_driver_register(struct sysdev_class * cls,
 			   struct sysdev_driver * drv)
 {
-	down(&sysdev_drivers_lock);
+	mutex_lock(&sysdev_drivers_lock);
 	if (cls && kset_get(&cls->kset)) {
 		list_add_tail(&drv->entry, &cls->drivers);
 
@@ -184,7 +184,7 @@
 		}
 	} else
 		list_add_tail(&drv->entry, &sysdev_drivers);
-	up(&sysdev_drivers_lock);
+	mutex_unlock(&sysdev_drivers_lock);
 	return 0;
 }
 
@@ -197,7 +197,7 @@
 void sysdev_driver_unregister(struct sysdev_class * cls,
 			      struct sysdev_driver * drv)
 {
-	down(&sysdev_drivers_lock);
+	mutex_lock(&sysdev_drivers_lock);
 	list_del_init(&drv->entry);
 	if (cls) {
 		if (drv->remove) {
@@ -207,7 +207,7 @@
 		}
 		kset_put(&cls->kset);
 	}
-	up(&sysdev_drivers_lock);
+	mutex_unlock(&sysdev_drivers_lock);
 }
 
 EXPORT_SYMBOL_GPL(sysdev_driver_register);
@@ -246,7 +246,7 @@
 	if (!error) {
 		struct sysdev_driver * drv;
 
-		down(&sysdev_drivers_lock);
+		mutex_lock(&sysdev_drivers_lock);
 		/* Generic notification is implicit, because it's that
 		 * code that should have called us.
 		 */
@@ -262,7 +262,7 @@
 			if (drv->add)
 				drv->add(sysdev);
 		}
-		up(&sysdev_drivers_lock);
+		mutex_unlock(&sysdev_drivers_lock);
 	}
 	return error;
 }
@@ -271,7 +271,7 @@
 {
 	struct sysdev_driver * drv;
 
-	down(&sysdev_drivers_lock);
+	mutex_lock(&sysdev_drivers_lock);
 	list_for_each_entry(drv, &sysdev_drivers, entry) {
 		if (drv->remove)
 			drv->remove(sysdev);
@@ -281,7 +281,7 @@
 		if (drv->remove)
 			drv->remove(sysdev);
 	}
-	up(&sysdev_drivers_lock);
+	mutex_unlock(&sysdev_drivers_lock);
 
 	kobject_unregister(&sysdev->kobj);
 }
@@ -308,7 +308,7 @@
 
 	pr_debug("Shutting Down System Devices\n");
 
-	down(&sysdev_drivers_lock);
+	mutex_lock(&sysdev_drivers_lock);
 	list_for_each_entry_reverse(cls, &system_subsys.list,
 				    kset.kobj.entry) {
 		struct sys_device * sysdev;
@@ -337,7 +337,7 @@
 				cls->shutdown(sysdev);
 		}
 	}
-	up(&sysdev_drivers_lock);
+	mutex_unlock(&sysdev_drivers_lock);
 }
 
 static void __sysdev_resume(struct sys_device *dev)
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index f1b9dd7..ce64e86 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -146,8 +146,7 @@
  **********************************************************/
 
 #define DEF_ATTR(_obj,_name,_mode) \
-	static struct attribute _obj = { \
-		.name = _name, .owner = THIS_MODULE, .mode = _mode }
+	static struct attribute _obj = { .name = _name, .mode = _mode }
 
 /**********************************************************
   /sys/class/pktcdvd/pktcdvd[0-7]/
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 7e04dd6..59b0548 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -199,7 +199,6 @@
 #define __pending_q(husb, type)   (&husb->pending_q[type-1])
 #define __completed_q(husb, type) (&husb->completed_q[type-1])
 #define __transmit_q(husb, type)  (&husb->transmit_q[type-1])
-#define __reassembly(husb, type)  (husb->reassembly[type-1])
 
 static inline struct _urb *__get_completed(struct hci_usb *husb, int type)
 {
@@ -429,12 +428,6 @@
 			kfree(urb->transfer_buffer);
 			_urb_free(_urb);
 		}
-
-		/* Release reassembly buffers */
-		if (husb->reassembly[i]) {
-			kfree_skb(husb->reassembly[i]);
-			husb->reassembly[i] = NULL;
-		}
 	}
 }
 
@@ -671,83 +664,6 @@
 	return 0;
 }
 
-static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int count)
-{
-	BT_DBG("%s type %d data %p count %d", husb->hdev->name, type, data, count);
-
-	husb->hdev->stat.byte_rx += count;
-
-	while (count) {
-		struct sk_buff *skb = __reassembly(husb, type);
-		struct { int expect; } *scb;
-		int len = 0;
-	
-		if (!skb) {
-			/* Start of the frame */
-
-			switch (type) {
-			case HCI_EVENT_PKT:
-				if (count >= HCI_EVENT_HDR_SIZE) {
-					struct hci_event_hdr *h = data;
-					len = HCI_EVENT_HDR_SIZE + h->plen;
-				} else
-					return -EILSEQ;
-				break;
-
-			case HCI_ACLDATA_PKT:
-				if (count >= HCI_ACL_HDR_SIZE) {
-					struct hci_acl_hdr *h = data;
-					len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
-				} else
-					return -EILSEQ;
-				break;
-#ifdef CONFIG_BT_HCIUSB_SCO
-			case HCI_SCODATA_PKT:
-				if (count >= HCI_SCO_HDR_SIZE) {
-					struct hci_sco_hdr *h = data;
-					len = HCI_SCO_HDR_SIZE + h->dlen;
-				} else
-					return -EILSEQ;
-				break;
-#endif
-			}
-			BT_DBG("new packet len %d", len);
-
-			skb = bt_skb_alloc(len, GFP_ATOMIC);
-			if (!skb) {
-				BT_ERR("%s no memory for the packet", husb->hdev->name);
-				return -ENOMEM;
-			}
-			skb->dev = (void *) husb->hdev;
-			bt_cb(skb)->pkt_type = type;
-	
-			__reassembly(husb, type) = skb;
-
-			scb = (void *) skb->cb;
-			scb->expect = len;
-		} else {
-			/* Continuation */
-			scb = (void *) skb->cb;
-			len = scb->expect;
-		}
-
-		len = min(len, count);
-		
-		memcpy(skb_put(skb, len), data, len);
-
-		scb->expect -= len;
-		if (!scb->expect) {
-			/* Complete frame */
-			__reassembly(husb, type) = NULL;
-			bt_cb(skb)->pkt_type = type;
-			hci_recv_frame(skb);
-		}
-
-		count -= len; data += len;
-	}
-	return 0;
-}
-
 static void hci_usb_rx_complete(struct urb *urb)
 {
 	struct _urb *_urb = container_of(urb, struct _urb, urb);
@@ -776,7 +692,7 @@
 					urb->iso_frame_desc[i].actual_length);
 	
 			if (!urb->iso_frame_desc[i].status)
-				__recv_frame(husb, _urb->type, 
+				hci_recv_fragment(husb->hdev, _urb->type, 
 					urb->transfer_buffer + urb->iso_frame_desc[i].offset,
 					urb->iso_frame_desc[i].actual_length);
 		}
@@ -784,7 +700,7 @@
 		;
 #endif
 	} else {
-		err = __recv_frame(husb, _urb->type, urb->transfer_buffer, count);
+		err = hci_recv_fragment(husb->hdev, _urb->type, urb->transfer_buffer, count);
 		if (err < 0) { 
 			BT_ERR("%s corrupted packet: type %d count %d",
 					husb->hdev->name, _urb->type, count);
diff --git a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h
index 963fc55..56cd3a9 100644
--- a/drivers/bluetooth/hci_usb.h
+++ b/drivers/bluetooth/hci_usb.h
@@ -102,9 +102,9 @@
 	struct hci_dev		*hdev;
 
 	unsigned long		state;
-	
+
 	struct usb_device	*udev;
-	
+
 	struct usb_host_endpoint	*bulk_in_ep;
 	struct usb_host_endpoint	*bulk_out_ep;
 	struct usb_host_endpoint	*intr_in_ep;
@@ -116,7 +116,6 @@
 	__u8			ctrl_req;
 
 	struct sk_buff_head	transmit_q[4];
-	struct sk_buff		*reassembly[4];		/* Reassembly buffers */
 
 	rwlock_t		completion_lock;
 
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index b71a5cc..0638730 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -180,11 +180,6 @@
 	return total;
 }
 
-static loff_t vhci_llseek(struct file *file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
 static ssize_t vhci_read(struct file *file,
 				char __user *buf, size_t count, loff_t *pos)
 {
@@ -334,7 +329,6 @@
 
 static const struct file_operations vhci_fops = {
 	.owner		= THIS_MODULE,
-	.llseek		= vhci_llseek,
 	.read		= vhci_read,
 	.write		= vhci_write,
 	.poll		= vhci_poll,
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index ef683eb..a31c6d2 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -815,7 +815,7 @@
 
 config GEN_RTC
 	tristate "Generic /dev/rtc emulation"
-	depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV && !S390 && !SUPERH
+	depends on RTC!=y && !IA64 && !ARM && !M32R && !MIPS && !SPARC && !FRV && !S390 && !SUPERH
 	---help---
 	  If you say Y here and create a character special file /dev/rtc with
 	  major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 8e222f2..b5df7e6 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -2171,52 +2171,42 @@
 	int err;
 
 	bmc->device_id_attr.attr.name = "device_id";
-	bmc->device_id_attr.attr.owner = THIS_MODULE;
 	bmc->device_id_attr.attr.mode = S_IRUGO;
 	bmc->device_id_attr.show = device_id_show;
 
 	bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
-	bmc->provides_dev_sdrs_attr.attr.owner = THIS_MODULE;
 	bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
 	bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
 
 	bmc->revision_attr.attr.name = "revision";
-	bmc->revision_attr.attr.owner = THIS_MODULE;
 	bmc->revision_attr.attr.mode = S_IRUGO;
 	bmc->revision_attr.show = revision_show;
 
 	bmc->firmware_rev_attr.attr.name = "firmware_revision";
-	bmc->firmware_rev_attr.attr.owner = THIS_MODULE;
 	bmc->firmware_rev_attr.attr.mode = S_IRUGO;
 	bmc->firmware_rev_attr.show = firmware_rev_show;
 
 	bmc->version_attr.attr.name = "ipmi_version";
-	bmc->version_attr.attr.owner = THIS_MODULE;
 	bmc->version_attr.attr.mode = S_IRUGO;
 	bmc->version_attr.show = ipmi_version_show;
 
 	bmc->add_dev_support_attr.attr.name = "additional_device_support";
-	bmc->add_dev_support_attr.attr.owner = THIS_MODULE;
 	bmc->add_dev_support_attr.attr.mode = S_IRUGO;
 	bmc->add_dev_support_attr.show = add_dev_support_show;
 
 	bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
-	bmc->manufacturer_id_attr.attr.owner = THIS_MODULE;
 	bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
 	bmc->manufacturer_id_attr.show = manufacturer_id_show;
 
 	bmc->product_id_attr.attr.name = "product_id";
-	bmc->product_id_attr.attr.owner = THIS_MODULE;
 	bmc->product_id_attr.attr.mode = S_IRUGO;
 	bmc->product_id_attr.show = product_id_show;
 
 	bmc->guid_attr.attr.name = "guid";
-	bmc->guid_attr.attr.owner = THIS_MODULE;
 	bmc->guid_attr.attr.mode = S_IRUGO;
 	bmc->guid_attr.show = guid_show;
 
 	bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
-	bmc->aux_firmware_rev_attr.attr.owner = THIS_MODULE;
 	bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
 	bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
 
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index 0cea8d4..e5ed091 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -19,18 +19,17 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <linux/platform_device.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/init.h>
-#include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 
-#include <asm/cpu.h>
 #include <asm/io.h>
 #include <asm/vr41xx/giu.h>
 #include <asm/vr41xx/irq.h>
@@ -44,18 +43,6 @@
 module_param(major, int, 0);
 MODULE_PARM_DESC(major, "Major device number");
 
-#define GIU_TYPE1_START		0x0b000100UL
-#define GIU_TYPE1_SIZE		0x20UL
-
-#define GIU_TYPE2_START		0x0f000140UL
-#define GIU_TYPE2_SIZE		0x20UL
-
-#define GIU_TYPE3_START		0x0f000140UL
-#define GIU_TYPE3_SIZE		0x28UL
-
-#define GIU_PULLUPDOWN_START	0x0b0002e0UL
-#define GIU_PULLUPDOWN_SIZE	0x04UL
-
 #define GIUIOSELL	0x00
 #define GIUIOSELH	0x02
 #define GIUPIODL	0x04
@@ -89,8 +76,6 @@
 #define GPIO_HAS_INTERRUPT_EDGE_SELECT	0x0100
 
 static spinlock_t giu_lock;
-static struct resource *giu_resource1;
-static struct resource *giu_resource2;
 static unsigned long giu_flags;
 static unsigned int giu_nr_pins;
 
@@ -234,7 +219,7 @@
 				giu_set(GIUINTHTSELL, mask);
 			else
 				giu_clear(GIUINTHTSELL, mask);
-			if (current_cpu_data.cputype == CPU_VR4133) {
+			if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) {
 				switch (trigger) {
 				case IRQ_TRIGGER_EDGE_FALLING:
 					giu_set(GIUFEDGEINHL, mask);
@@ -269,7 +254,7 @@
 				giu_set(GIUINTHTSELH, mask);
 			else
 				giu_clear(GIUINTHTSELH, mask);
-			if (current_cpu_data.cputype == CPU_VR4133) {
+			if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) {
 				switch (trigger) {
 				case IRQ_TRIGGER_EDGE_FALLING:
 					giu_set(GIUFEDGEINHH, mask);
@@ -298,7 +283,6 @@
 		giu_write(GIUINTSTATH, mask);
 	}
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger);
 
 void vr41xx_set_irq_level(unsigned int pin, irq_level_t level)
@@ -321,7 +305,6 @@
 		giu_write(GIUINTSTATH, mask);
 	}
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_set_irq_level);
 
 gpio_data_t vr41xx_gpio_get_pin(unsigned int pin)
@@ -350,7 +333,6 @@
 
 	return GPIO_DATA_LOW;
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_gpio_get_pin);
 
 int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data)
@@ -388,7 +370,6 @@
 
 	return 0;
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_gpio_set_pin);
 
 int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir)
@@ -438,7 +419,6 @@
 
 	return 0;
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_gpio_set_direction);
 
 int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull)
@@ -477,7 +457,6 @@
 
 	return 0;
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown);
 
 static ssize_t gpio_read(struct file *file, char __user *buf, size_t len,
@@ -596,61 +575,40 @@
 
 static int __devinit giu_probe(struct platform_device *dev)
 {
-	unsigned long start, size, flags = 0;
-	unsigned int nr_pins = 0, trigger, i, pin;
-	struct resource *res1, *res2 = NULL;
-	void *base;
+	struct resource *res;
+	unsigned int trigger, i, pin;
 	struct irq_chip *chip;
-	int retval;
+	int irq, retval;
 
-	switch (current_cpu_data.cputype) {
-	case CPU_VR4111:
-	case CPU_VR4121:
-		start = GIU_TYPE1_START;
-		size = GIU_TYPE1_SIZE;
-		flags = GPIO_HAS_PULLUPDOWN_IO;
-		nr_pins = 50;
+	switch (dev->id) {
+	case GPIO_50PINS_PULLUPDOWN:
+		giu_flags = GPIO_HAS_PULLUPDOWN_IO;
+		giu_nr_pins = 50;
 		break;
-	case CPU_VR4122:
-	case CPU_VR4131:
-		start = GIU_TYPE2_START;
-		size = GIU_TYPE2_SIZE;
-		nr_pins = 36;
+	case GPIO_36PINS:
+		giu_nr_pins = 36;
 		break;
-	case CPU_VR4133:
-		start = GIU_TYPE3_START;
-		size = GIU_TYPE3_SIZE;
-		flags = GPIO_HAS_INTERRUPT_EDGE_SELECT;
-		nr_pins = 48;
+	case GPIO_48PINS_EDGE_SELECT:
+		giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT;
+		giu_nr_pins = 48;
 		break;
 	default:
+		printk(KERN_ERR "GIU: unknown ID %d\n", dev->id);
 		return -ENODEV;
 	}
 
-	res1 = request_mem_region(start, size, "GIU");
-	if (res1 == NULL)
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
 		return -EBUSY;
 
-	base = ioremap(start, size);
-	if (base == NULL) {
-		release_resource(res1);
+	giu_base = ioremap(res->start, res->end - res->start + 1);
+	if (!giu_base)
 		return -ENOMEM;
-	}
-
-	if (flags & GPIO_HAS_PULLUPDOWN_IO) {
-		res2 = request_mem_region(GIU_PULLUPDOWN_START, GIU_PULLUPDOWN_SIZE, "GIU");
-		if (res2 == NULL) {
-			iounmap(base);
-			release_resource(res1);
-			return -EBUSY;
-		}
-	}
 
 	retval = register_chrdev(major, "GIU", &gpio_fops);
 	if (retval < 0) {
-		iounmap(base);
-		release_resource(res1);
-		release_resource(res2);
+		iounmap(giu_base);
+		giu_base = NULL;
 		return retval;
 	}
 
@@ -660,11 +618,6 @@
 	}
 
 	spin_lock_init(&giu_lock);
-	giu_base = base;
-	giu_resource1 = res1;
-	giu_resource2 = res2;
-	giu_flags = flags;
-	giu_nr_pins = nr_pins;
 
 	giu_write(GIUINTENL, 0);
 	giu_write(GIUINTENH, 0);
@@ -685,22 +638,23 @@
 
 	}
 
-	return cascade_irq(GIUINT_IRQ, giu_get_irq);
+	irq = platform_get_irq(dev, 0);
+	if (irq < 0 || irq >= NR_IRQS)
+		return -EBUSY;
+
+	return cascade_irq(irq, giu_get_irq);
 }
 
 static int __devexit giu_remove(struct platform_device *dev)
 {
-	iounmap(giu_base);
-
-	release_resource(giu_resource1);
-	if (giu_flags & GPIO_HAS_PULLUPDOWN_IO)
-		release_resource(giu_resource2);
+	if (giu_base) {
+		iounmap(giu_base);
+		giu_base = NULL;
+	}
 
 	return 0;
 }
 
-static struct platform_device *giu_platform_device;
-
 static struct platform_driver giu_device_driver = {
 	.probe		= giu_probe,
 	.remove		= __devexit_p(giu_remove),
@@ -712,30 +666,12 @@
 
 static int __init vr41xx_giu_init(void)
 {
-	int retval;
-
-	giu_platform_device = platform_device_alloc("GIU", -1);
-	if (!giu_platform_device)
-		return -ENOMEM;
-
-	retval = platform_device_add(giu_platform_device);
-	if (retval < 0) {
-		platform_device_put(giu_platform_device);
-		return retval;
-	}
-
-	retval = platform_driver_register(&giu_device_driver);
-	if (retval < 0)
-		platform_device_unregister(giu_platform_device);
-
-	return retval;
+	return platform_driver_register(&giu_device_driver);
 }
 
 static void __exit vr41xx_giu_exit(void)
 {
 	platform_driver_unregister(&giu_device_driver);
-
-	platform_device_unregister(giu_platform_device);
 }
 
 module_init(vr41xx_giu_init);
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index d2f0cbd..917b9ba 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -25,8 +25,7 @@
 
 #define CPUFREQ_STATDEVICE_ATTR(_name,_mode,_show) \
 static struct freq_attr _attr_##_name = {\
-	.attr = {.name = __stringify(_name), .owner = THIS_MODULE, \
-		.mode = _mode, }, \
+	.attr = {.name = __stringify(_name), .mode = _mode, }, \
 	.show = _show,\
 };
 
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
index 860345c..a648970 100644
--- a/drivers/cpufreq/cpufreq_userspace.c
+++ b/drivers/cpufreq/cpufreq_userspace.c
@@ -120,7 +120,7 @@
 
 static struct freq_attr freq_attr_scaling_setspeed =
 {
-	.attr = { .name = "scaling_setspeed", .mode = 0644, .owner = THIS_MODULE },
+	.attr = { .name = "scaling_setspeed", .mode = 0644 },
 	.show = show_speed,
 	.store = store_speed,
 };
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index e749092..5409f3a 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -199,7 +199,6 @@
 struct freq_attr cpufreq_freq_attr_scaling_available_freqs = {
 	.attr = { .name = "scaling_available_frequencies",
 		  .mode = 0444,
-		  .owner=THIS_MODULE
 		},
 	.show = show_available_freqs,
 };
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 88f4621..05f02a3 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -84,4 +84,13 @@
 	  Say Y or M here to enable the driver for use by Dell systems
 	  management software such as Dell OpenManage.
 
+config DMIID
+    bool "Export DMI identification via sysfs to userspace"
+    depends on DMI
+    default y
+	help
+	  Say Y here if you want to query SMBIOS/DMI system identification
+	  information from userspace through /sys/class/dmi/id/ or if you want
+	  DMI-based module auto-loading.
+
 endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 98e395f..8d4ebc8 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -7,3 +7,4 @@
 obj-$(CONFIG_EFI_PCDP)		+= pcdp.o
 obj-$(CONFIG_DELL_RBU)          += dell_rbu.o
 obj-$(CONFIG_DCDBAS)		+= dcdbas.o
+obj-$(CONFIG_DMIID)		+= dmi-id.o
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 1865b56..18cdcb3 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -149,8 +149,9 @@
 	return count;
 }
 
-static ssize_t smi_data_read(struct kobject *kobj, char *buf, loff_t pos,
-			     size_t count)
+static ssize_t smi_data_read(struct kobject *kobj,
+			     struct bin_attribute *bin_attr,
+			     char *buf, loff_t pos, size_t count)
 {
 	size_t max_read;
 	ssize_t ret;
@@ -170,8 +171,9 @@
 	return ret;
 }
 
-static ssize_t smi_data_write(struct kobject *kobj, char *buf, loff_t pos,
-			      size_t count)
+static ssize_t smi_data_write(struct kobject *kobj,
+			      struct bin_attribute *bin_attr,
+			      char *buf, loff_t pos, size_t count)
 {
 	ssize_t ret;
 
diff --git a/drivers/firmware/dcdbas.h b/drivers/firmware/dcdbas.h
index 58a8518..dcdba0f 100644
--- a/drivers/firmware/dcdbas.h
+++ b/drivers/firmware/dcdbas.h
@@ -67,8 +67,7 @@
 #define DCDBAS_BIN_ATTR_RW(_name) \
 struct bin_attribute bin_attr_##_name = { \
 	.attr =  { .name = __stringify(_name), \
-		   .mode = 0600, \
-		   .owner = THIS_MODULE }, \
+		   .mode = 0600 }, \
 	.read =  _name##_read, \
 	.write = _name##_write, \
 }
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index fc702e4..477a3d0 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -543,8 +543,9 @@
 	return ret_count;
 }
 
-static ssize_t read_rbu_data(struct kobject *kobj, char *buffer,
-	loff_t pos, size_t count)
+static ssize_t read_rbu_data(struct kobject *kobj,
+			     struct bin_attribute *bin_attr,
+			     char *buffer, loff_t pos, size_t count)
 {
 	ssize_t ret_count = 0;
 
@@ -591,8 +592,9 @@
 	spin_unlock(&rbu_data.lock);
 }
 
-static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer,
-	loff_t pos, size_t count)
+static ssize_t read_rbu_image_type(struct kobject *kobj,
+				   struct bin_attribute *bin_attr,
+				   char *buffer, loff_t pos, size_t count)
 {
 	int size = 0;
 	if (!pos)
@@ -600,8 +602,9 @@
 	return size;
 }
 
-static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer,
-	loff_t pos, size_t count)
+static ssize_t write_rbu_image_type(struct kobject *kobj,
+				    struct bin_attribute *bin_attr,
+				    char *buffer, loff_t pos, size_t count)
 {
 	int rc = count;
 	int req_firm_rc = 0;
@@ -660,8 +663,9 @@
 	return rc;
 }
 
-static ssize_t read_rbu_packet_size(struct kobject *kobj, char *buffer,
-	loff_t pos, size_t count)
+static ssize_t read_rbu_packet_size(struct kobject *kobj,
+				    struct bin_attribute *bin_attr,
+				    char *buffer, loff_t pos, size_t count)
 {
 	int size = 0;
 	if (!pos) {
@@ -672,8 +676,9 @@
 	return size;
 }
 
-static ssize_t write_rbu_packet_size(struct kobject *kobj, char *buffer,
-	loff_t pos, size_t count)
+static ssize_t write_rbu_packet_size(struct kobject *kobj,
+				     struct bin_attribute *bin_attr,
+				     char *buffer, loff_t pos, size_t count)
 {
 	unsigned long temp;
 	spin_lock(&rbu_data.lock);
@@ -687,18 +692,18 @@
 }
 
 static struct bin_attribute rbu_data_attr = {
-	.attr = {.name = "data",.owner = THIS_MODULE,.mode = 0444},
+	.attr = {.name = "data", .mode = 0444},
 	.read = read_rbu_data,
 };
 
 static struct bin_attribute rbu_image_type_attr = {
-	.attr = {.name = "image_type",.owner = THIS_MODULE,.mode = 0644},
+	.attr = {.name = "image_type", .mode = 0644},
 	.read = read_rbu_image_type,
 	.write = write_rbu_image_type,
 };
 
 static struct bin_attribute rbu_packet_size_attr = {
-	.attr = {.name = "packet_size",.owner = THIS_MODULE,.mode = 0644},
+	.attr = {.name = "packet_size", .mode = 0644},
 	.read = read_rbu_packet_size,
 	.write = write_rbu_packet_size,
 };
diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c
new file mode 100644
index 0000000..59c3b5a
--- /dev/null
+++ b/drivers/firmware/dmi-id.c
@@ -0,0 +1,222 @@
+/*
+ * Export SMBIOS/DMI info via sysfs to userspace
+ *
+ * Copyright 2007, Lennart Poettering
+ *
+ * Licensed under GPLv2
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/dmi.h>
+#include <linux/device.h>
+#include <linux/autoconf.h>
+
+#define DEFINE_DMI_ATTR(_name, _mode, _show)		\
+static struct device_attribute sys_dmi_##_name##_attr =	\
+	__ATTR(_name, _mode, _show, NULL);
+
+#define DEFINE_DMI_ATTR_WITH_SHOW(_name, _mode, _field)			\
+static ssize_t sys_dmi_##_name##_show(struct device *dev,		\
+				      struct device_attribute *attr,	\
+				      char *page)			\
+{									\
+	ssize_t len;							\
+	len = scnprintf(page, PAGE_SIZE, "%s\n", dmi_get_system_info(_field)); \
+	page[len-1] = '\n';						\
+	return len;							\
+}									\
+DEFINE_DMI_ATTR(_name, _mode, sys_dmi_##_name##_show);
+
+DEFINE_DMI_ATTR_WITH_SHOW(bios_vendor,		0444, DMI_BIOS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(bios_version,		0444, DMI_BIOS_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(bios_date,		0444, DMI_BIOS_DATE);
+DEFINE_DMI_ATTR_WITH_SHOW(sys_vendor,		0444, DMI_SYS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(product_name,		0444, DMI_PRODUCT_NAME);
+DEFINE_DMI_ATTR_WITH_SHOW(product_version,	0444, DMI_PRODUCT_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(product_serial,	0400, DMI_PRODUCT_SERIAL);
+DEFINE_DMI_ATTR_WITH_SHOW(product_uuid,		0400, DMI_PRODUCT_UUID);
+DEFINE_DMI_ATTR_WITH_SHOW(board_vendor,		0444, DMI_BOARD_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(board_name,		0444, DMI_BOARD_NAME);
+DEFINE_DMI_ATTR_WITH_SHOW(board_version,	0444, DMI_BOARD_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(board_serial,		0400, DMI_BOARD_SERIAL);
+DEFINE_DMI_ATTR_WITH_SHOW(board_asset_tag,	0444, DMI_BOARD_ASSET_TAG);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_vendor,	0444, DMI_CHASSIS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_type,		0444, DMI_CHASSIS_TYPE);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_version,	0444, DMI_CHASSIS_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_serial,	0400, DMI_CHASSIS_SERIAL);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_asset_tag,	0444, DMI_CHASSIS_ASSET_TAG);
+
+static void ascii_filter(char *d, const char *s)
+{
+	/* Filter out characters we don't want to see in the modalias string */
+	for (; *s; s++)
+		if (*s > ' ' && *s < 127 && *s != ':')
+			*(d++) = *s;
+
+	*d = 0;
+}
+
+static ssize_t get_modalias(char *buffer, size_t buffer_size)
+{
+	static const struct mafield {
+		const char *prefix;
+		int field;
+	} fields[] = {
+		{ "bvn", DMI_BIOS_VENDOR },
+		{ "bvr", DMI_BIOS_VERSION },
+		{ "bd",  DMI_BIOS_DATE },
+		{ "svn", DMI_SYS_VENDOR },
+		{ "pn",  DMI_PRODUCT_NAME },
+		{ "pvr", DMI_PRODUCT_VERSION },
+		{ "rvn", DMI_BOARD_VENDOR },
+		{ "rn",  DMI_BOARD_NAME },
+		{ "rvr", DMI_BOARD_VERSION },
+		{ "cvn", DMI_CHASSIS_VENDOR },
+		{ "ct",  DMI_CHASSIS_TYPE },
+		{ "cvr", DMI_CHASSIS_VERSION },
+		{ NULL,  DMI_NONE }
+	};
+
+	ssize_t l, left;
+	char *p;
+	const struct mafield *f;
+
+	strcpy(buffer, "dmi");
+	p = buffer + 3; left = buffer_size - 4;
+
+	for (f = fields; f->prefix && left > 0; f++) {
+		const char *c;
+		char *t;
+
+		c = dmi_get_system_info(f->field);
+		if (!c)
+			continue;
+
+		t = kmalloc(strlen(c) + 1, GFP_KERNEL);
+		if (!t)
+			break;
+		ascii_filter(t, c);
+		l = scnprintf(p, left, ":%s%s", f->prefix, t);
+		kfree(t);
+
+		p += l;
+		left -= l;
+	}
+
+	p[0] = ':';
+	p[1] = 0;
+
+	return p - buffer + 1;
+}
+
+static ssize_t sys_dmi_modalias_show(struct device *dev,
+				     struct device_attribute *attr, char *page)
+{
+	ssize_t r;
+	r = get_modalias(page, PAGE_SIZE-1);
+	page[r] = '\n';
+	page[r+1] = 0;
+	return r+1;
+}
+
+DEFINE_DMI_ATTR(modalias, 0444, sys_dmi_modalias_show);
+
+static struct attribute *sys_dmi_attributes[DMI_STRING_MAX+2];
+
+static struct attribute_group sys_dmi_attribute_group = {
+	.attrs = sys_dmi_attributes,
+};
+
+static struct attribute_group* sys_dmi_attribute_groups[] = {
+	&sys_dmi_attribute_group,
+	NULL
+};
+
+static int dmi_dev_uevent(struct device *dev, char **envp,
+			    int num_envp, char *buffer, int buffer_size)
+{
+	strcpy(buffer, "MODALIAS=");
+	get_modalias(buffer+9, buffer_size-9);
+	envp[0] = buffer;
+	envp[1] = NULL;
+
+	return 0;
+}
+
+static struct class dmi_class = {
+	.name = "dmi",
+	.dev_release = (void(*)(struct device *)) kfree,
+	.dev_uevent = dmi_dev_uevent,
+};
+
+static struct device *dmi_dev;
+
+/* Initialization */
+
+#define ADD_DMI_ATTR(_name, _field) \
+	if (dmi_get_system_info(_field)) \
+		sys_dmi_attributes[i++] = & sys_dmi_##_name##_attr.attr;
+
+extern int dmi_available;
+
+static int __init dmi_id_init(void)
+{
+	int ret, i;
+
+	if (!dmi_available)
+		return -ENODEV;
+
+	/* Not necessarily all DMI fields are available on all
+	 * systems, hence let's built an attribute table of just
+	 * what's available */
+	i = 0;
+	ADD_DMI_ATTR(bios_vendor,       DMI_BIOS_VENDOR);
+	ADD_DMI_ATTR(bios_version,      DMI_BIOS_VERSION);
+	ADD_DMI_ATTR(bios_date,         DMI_BIOS_DATE);
+	ADD_DMI_ATTR(sys_vendor,        DMI_SYS_VENDOR);
+	ADD_DMI_ATTR(product_name,      DMI_PRODUCT_NAME);
+	ADD_DMI_ATTR(product_version,   DMI_PRODUCT_VERSION);
+	ADD_DMI_ATTR(product_serial,    DMI_PRODUCT_SERIAL);
+	ADD_DMI_ATTR(product_uuid,      DMI_PRODUCT_UUID);
+	ADD_DMI_ATTR(board_vendor,      DMI_BOARD_VENDOR);
+	ADD_DMI_ATTR(board_name,        DMI_BOARD_NAME);
+	ADD_DMI_ATTR(board_version,     DMI_BOARD_VERSION);
+	ADD_DMI_ATTR(board_serial,      DMI_BOARD_SERIAL);
+	ADD_DMI_ATTR(board_asset_tag,   DMI_BOARD_ASSET_TAG);
+	ADD_DMI_ATTR(chassis_vendor,    DMI_CHASSIS_VENDOR);
+	ADD_DMI_ATTR(chassis_type,      DMI_CHASSIS_TYPE);
+	ADD_DMI_ATTR(chassis_version,   DMI_CHASSIS_VERSION);
+	ADD_DMI_ATTR(chassis_serial,    DMI_CHASSIS_SERIAL);
+	ADD_DMI_ATTR(chassis_asset_tag, DMI_CHASSIS_ASSET_TAG);
+	sys_dmi_attributes[i++] = &sys_dmi_modalias_attr.attr;
+
+	ret = class_register(&dmi_class);
+	if (ret)
+		return ret;
+
+	dmi_dev = kzalloc(sizeof(*dmi_dev), GFP_KERNEL);
+	if (!dmi_dev) {
+		ret = -ENOMEM;
+		goto fail_class_unregister;
+	}
+
+	dmi_dev->class = &dmi_class;
+	strcpy(dmi_dev->bus_id, "id");
+	dmi_dev->groups = sys_dmi_attribute_groups;
+
+	ret = device_register(dmi_dev);
+	if (ret)
+		goto fail_class_unregister;
+
+	return 0;
+
+fail_class_unregister:
+
+	class_unregister(&dmi_class);
+
+	return ret;
+}
+
+arch_initcall(dmi_id_init);
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 37deee6..f7318b3 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -84,6 +84,7 @@
 
 static char *dmi_ident[DMI_STRING_MAX];
 static LIST_HEAD(dmi_devices);
+int dmi_available;
 
 /*
  *	Save a DMI string
@@ -102,6 +103,51 @@
 	dmi_ident[slot] = p;
 }
 
+static void __init dmi_save_uuid(struct dmi_header *dm, int slot, int index)
+{
+	u8 *d = (u8*) dm + index;
+	char *s;
+	int is_ff = 1, is_00 = 1, i;
+
+	if (dmi_ident[slot])
+		return;
+
+	for (i = 0; i < 16 && (is_ff || is_00); i++) {
+		if(d[i] != 0x00) is_ff = 0;
+		if(d[i] != 0xFF) is_00 = 0;
+	}
+
+	if (is_ff || is_00)
+		return;
+
+	s = dmi_alloc(16*2+4+1);
+	if (!s)
+		return;
+
+	sprintf(s,
+		"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+		d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
+		d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+
+        dmi_ident[slot] = s;
+}
+
+static void __init dmi_save_type(struct dmi_header *dm, int slot, int index)
+{
+	u8 *d = (u8*) dm + index;
+	char *s;
+
+	if (dmi_ident[slot])
+		return;
+
+	s = dmi_alloc(4);
+	if (!s)
+		return;
+
+	sprintf(s, "%u", *d & 0x7F);
+	dmi_ident[slot] = s;
+}
+
 static void __init dmi_save_devices(struct dmi_header *dm)
 {
 	int i, count = (dm->length - sizeof(struct dmi_header)) / 2;
@@ -192,11 +238,21 @@
 		dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
 		dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
 		dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
+		dmi_save_uuid(dm, DMI_PRODUCT_UUID, 8);
 		break;
 	case 2:		/* Base Board Information */
 		dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
 		dmi_save_ident(dm, DMI_BOARD_NAME, 5);
 		dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
+		dmi_save_ident(dm, DMI_BOARD_SERIAL, 7);
+		dmi_save_ident(dm, DMI_BOARD_ASSET_TAG, 8);
+		break;
+	case 3:		/* Chassis Information */
+		dmi_save_ident(dm, DMI_CHASSIS_VENDOR, 4);
+		dmi_save_type(dm, DMI_CHASSIS_TYPE, 5);
+		dmi_save_ident(dm, DMI_CHASSIS_VERSION, 6);
+		dmi_save_ident(dm, DMI_CHASSIS_SERIAL, 7);
+		dmi_save_ident(dm, DMI_CHASSIS_ASSET_TAG, 8);
 		break;
 	case 10:	/* Onboard Devices Information */
 		dmi_save_devices(dm);
@@ -243,18 +299,20 @@
 		if (efi.smbios == EFI_INVALID_TABLE_ADDR)
 			goto out;
 
-               /* This is called as a core_initcall() because it isn't
-                * needed during early boot.  This also means we can
-                * iounmap the space when we're done with it.
-		*/
+		/* This is called as a core_initcall() because it isn't
+		 * needed during early boot.  This also means we can
+		 * iounmap the space when we're done with it.
+		 */
 		p = dmi_ioremap(efi.smbios, 32);
 		if (p == NULL)
 			goto out;
 
 		rc = dmi_present(p + 0x10); /* offset of _DMI_ string */
 		dmi_iounmap(p, 32);
-		if (!rc)
+		if (!rc) {
+			dmi_available = 1;
 			return;
+		}
 	}
 	else {
 		/*
@@ -268,8 +326,10 @@
 
 		for (q = p; q < p + 0x10000; q += 16) {
 			rc = dmi_present(q);
-			if (!rc)
+			if (!rc) {
+				dmi_available = 1;
 				return;
+			}
 		}
 	}
  out:	printk(KERN_INFO "DMI not present or invalid.\n");
@@ -404,3 +464,4 @@
 
 	return year;
 }
+
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index d8806e4..1523227 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -74,7 +74,7 @@
 
 #define EDD_DEVICE_ATTR(_name,_mode,_show,_test) \
 struct edd_attribute edd_attr_##_name = { 	\
-	.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },	\
+	.attr = {.name = __stringify(_name), .mode = _mode },	\
 	.show	= _show,				\
 	.test	= _test,				\
 };
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 1324984..bfd2d67 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -131,21 +131,21 @@
 
 #define EFI_ATTR(_name, _mode, _show, _store) \
 struct subsys_attribute efi_attr_##_name = { \
-	.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+	.attr = {.name = __stringify(_name), .mode = _mode}, \
 	.show = _show, \
 	.store = _store, \
 };
 
 #define EFIVAR_ATTR(_name, _mode, _show, _store) \
 struct efivar_attribute efivar_attr_##_name = { \
-	.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+	.attr = {.name = __stringify(_name), .mode = _mode}, \
 	.show = _show, \
 	.store = _store, \
 };
 
 #define VAR_SUBSYS_ATTR(_name, _mode, _show, _store) \
 struct subsys_attribute var_subsys_attr_##_name = { \
-	.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+	.attr = {.name = __stringify(_name), .mode = _mode}, \
 	.show = _show, \
 	.store = _store, \
 };
diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig
index 5889907..014dfa5 100644
--- a/drivers/i2c/algos/Kconfig
+++ b/drivers/i2c/algos/Kconfig
@@ -34,10 +34,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-pca.
 
-config I2C_ALGO8XX
-	tristate "MPC8xx CPM I2C interface"
-	depends on 8xx
-
 config I2C_ALGO_SGI
 	tristate "I2C SGI interfaces"
 	depends on SGI_IP22 || SGI_IP32 || X86_VISWS
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 838dc1c..fcde9ba 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -207,6 +207,7 @@
 	    ATI IXP300
 	    ATI IXP400
 	    ATI SB600
+	    ATI SB700
 	    Serverworks OSB4
 	    Serverworks CSB5
 	    Serverworks CSB6
@@ -390,11 +391,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-prosavage.
 
-config I2C_RPXLITE
-	tristate "Embedded Planet RPX Lite/Classic support"
-	depends on RPXLITE || RPXCLASSIC
-	select I2C_ALGO8XX
-
 config I2C_S3C2410
 	tristate "S3C2410 I2C Driver"
 	depends on ARCH_S3C2410
@@ -512,6 +508,22 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-sis96x.
 
+config I2C_TAOS_EVM
+	tristate "TAOS evaluation module"
+	depends on EXPERIMENTAL
+	select SERIO
+	select SERIO_SERPORT
+	default n
+	help
+	  This supports TAOS evaluation modules on serial port. In order to
+	  use this driver, you will need the inputattach tool, which is part
+	  of the input-utils package.
+
+	  If unsure, say N.
+
+	  This support is also available as a module.  If so, the module
+	  will be called i2c-taos-evm.
+
 config I2C_STUB
 	tristate "I2C/SMBus Test Stub"
 	depends on EXPERIMENTAL && m
@@ -635,4 +647,13 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-pnx.
 
+config I2C_PMCMSP
+	tristate "PMC MSP I2C TWI Controller"
+	depends on PMC_MSP
+	help
+	  This driver supports the PMC TWI controller on MSP devices.
+
+	  This driver can also be built as module. If so, the module
+	  will be called i2c-pmcmsp.
+
 endmenu
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 14d1432..a6db4e3 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -32,10 +32,10 @@
 obj-$(CONFIG_I2C_PASEMI)	+= i2c-pasemi.o
 obj-$(CONFIG_I2C_PCA_ISA)	+= i2c-pca-isa.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
+obj-$(CONFIG_I2C_PMCMSP)	+= i2c-pmcmsp.o
 obj-$(CONFIG_I2C_PNX)		+= i2c-pnx.o
 obj-$(CONFIG_I2C_PROSAVAGE)	+= i2c-prosavage.o
 obj-$(CONFIG_I2C_PXA)		+= i2c-pxa.o
-obj-$(CONFIG_I2C_RPXLITE)	+= i2c-rpx.o
 obj-$(CONFIG_I2C_S3C2410)	+= i2c-s3c2410.o
 obj-$(CONFIG_I2C_SAVAGE4)	+= i2c-savage4.o
 obj-$(CONFIG_I2C_SIBYTE)	+= i2c-sibyte.o
@@ -44,6 +44,7 @@
 obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
 obj-$(CONFIG_I2C_STUB)		+= i2c-stub.o
+obj-$(CONFIG_I2C_TAOS_EVM)	+= i2c-taos-evm.o
 obj-$(CONFIG_I2C_TINY_USB)	+= i2c-tiny-usb.o
 obj-$(CONFIG_I2C_VERSATILE)	+= i2c-versatile.o
 obj-$(CONFIG_I2C_ACORN)		+= i2c-acorn.o
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index a7dd546..025f194 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -63,14 +63,14 @@
 	gpio_set_value(pdata->scl_pin, state);
 }
 
-int i2c_gpio_getsda(void *data)
+static int i2c_gpio_getsda(void *data)
 {
 	struct i2c_gpio_platform_data *pdata = data;
 
 	return gpio_get_value(pdata->sda_pin);
 }
 
-int i2c_gpio_getscl(void *data)
+static int i2c_gpio_getscl(void *data)
 {
 	struct i2c_gpio_platform_data *pdata = data;
 
@@ -142,7 +142,13 @@
 	adap->algo_data = bit_data;
 	adap->dev.parent = &pdev->dev;
 
-	ret = i2c_bit_add_bus(adap);
+	/*
+	 * If "dev->id" is negative we consider it as zero.
+	 * The reason to do so is to avoid sysfs names that only make
+	 * sense when there are multiple adapters.
+	 */
+	adap->nr = pdev->id >= 0 ? pdev->id : 0;
+	ret = i2c_bit_add_numbered_bus(adap);
 	if (ret)
 		goto err_add_bus;
 
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 611b571..8f5c686 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -22,12 +22,12 @@
 
 /*
     SUPPORTED DEVICES	PCI ID
-    82801AA		2413           
-    82801AB		2423           
-    82801BA		2443           
-    82801CA/CAM		2483           
-    82801DB		24C3   (HW PEC supported, 32 byte buffer not supported)
-    82801EB		24D3   (HW PEC supported, 32 byte buffer not supported)
+    82801AA		2413
+    82801AB		2423
+    82801BA		2443
+    82801CA/CAM		2483
+    82801DB		24C3   (HW PEC supported)
+    82801EB		24D3   (HW PEC supported)
     6300ESB		25A4
     ICH6		266A
     ICH7		27DA
@@ -74,6 +74,13 @@
 #define SMBHSTCFG_SMB_SMI_EN	2
 #define SMBHSTCFG_I2C_EN	4
 
+/* Auxillary control register bits, ICH4+ only */
+#define SMBAUXCTL_CRC		1
+#define SMBAUXCTL_E32B		2
+
+/* kill bit for SMBHSTCNT */
+#define SMBHSTCNT_KILL		2
+
 /* Other settings */
 #define MAX_TIMEOUT		100
 #define ENABLE_INT9		0	/* set to 0x01 to enable - untested */
@@ -91,10 +98,15 @@
 #define I801_START		0x40
 #define I801_PEC_EN		0x80	/* ICH4 only */
 
-
-static int i801_transaction(void);
-static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
-				  int command, int hwpec);
+/* I801 Hosts Status register bits */
+#define SMBHSTSTS_BYTE_DONE	0x80
+#define SMBHSTSTS_INUSE_STS	0x40
+#define SMBHSTSTS_SMBALERT_STS	0x20
+#define SMBHSTSTS_FAILED	0x10
+#define SMBHSTSTS_BUS_ERR	0x08
+#define SMBHSTSTS_DEV_ERR	0x04
+#define SMBHSTSTS_INTR		0x02
+#define SMBHSTSTS_HOST_BUSY	0x01
 
 static unsigned long i801_smba;
 static unsigned char i801_original_hstcfg;
@@ -102,7 +114,7 @@
 static struct pci_dev *I801_dev;
 static int isich4;
 
-static int i801_transaction(void)
+static int i801_transaction(int xact)
 {
 	int temp;
 	int result = 0;
@@ -127,33 +139,40 @@
 		}
 	}
 
-	outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
+	/* the current contents of SMBHSTCNT can be overwritten, since PEC,
+	 * INTREN, SMBSCMD are passed in xact */
+	outb_p(xact | I801_START, SMBHSTCNT);
 
 	/* We will always wait for a fraction of a second! */
 	do {
 		msleep(1);
 		temp = inb_p(SMBHSTSTS);
-	} while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
+	} while ((temp & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT));
 
 	/* If the SMBus is still busy, we give up */
 	if (timeout >= MAX_TIMEOUT) {
 		dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
 		result = -1;
+		/* try to stop the current command */
+		dev_dbg(&I801_dev->dev, "Terminating the current operation\n");
+		outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
+		msleep(1);
+		outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), SMBHSTCNT);
 	}
 
-	if (temp & 0x10) {
+	if (temp & SMBHSTSTS_FAILED) {
 		result = -1;
 		dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n");
 	}
 
-	if (temp & 0x08) {
+	if (temp & SMBHSTSTS_BUS_ERR) {
 		result = -1;
 		dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked "
 			"until next hard reset. (sorry!)\n");
 		/* Clock stops and slave is stuck in mid-transmission */
 	}
 
-	if (temp & 0x04) {
+	if (temp & SMBHSTSTS_DEV_ERR) {
 		result = -1;
 		dev_dbg(&I801_dev->dev, "Error: no response!\n");
 	}
@@ -172,44 +191,70 @@
 	return result;
 }
 
-/* All-inclusive block transaction function */
-static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
-				  int command, int hwpec)
+/* wait for INTR bit as advised by Intel */
+static void i801_wait_hwpec(void)
+{
+	int timeout = 0;
+	int temp;
+
+	do {
+		msleep(1);
+		temp = inb_p(SMBHSTSTS);
+	} while ((!(temp & SMBHSTSTS_INTR))
+		 && (timeout++ < MAX_TIMEOUT));
+
+	if (timeout >= MAX_TIMEOUT) {
+		dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
+	}
+	outb_p(temp, SMBHSTSTS);
+}
+
+static int i801_block_transaction_by_block(union i2c_smbus_data *data,
+					   char read_write, int hwpec)
+{
+	int i, len;
+
+	inb_p(SMBHSTCNT); /* reset the data buffer index */
+
+	/* Use 32-byte buffer to process this transaction */
+	if (read_write == I2C_SMBUS_WRITE) {
+		len = data->block[0];
+		outb_p(len, SMBHSTDAT0);
+		for (i = 0; i < len; i++)
+			outb_p(data->block[i+1], SMBBLKDAT);
+	}
+
+	if (i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 |
+			     I801_PEC_EN * hwpec))
+		return -1;
+
+	if (read_write == I2C_SMBUS_READ) {
+		len = inb_p(SMBHSTDAT0);
+		if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
+			return -1;
+
+		data->block[0] = len;
+		for (i = 0; i < len; i++)
+			data->block[i + 1] = inb_p(SMBBLKDAT);
+	}
+	return 0;
+}
+
+static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
+					       char read_write, int hwpec)
 {
 	int i, len;
 	int smbcmd;
 	int temp;
 	int result = 0;
 	int timeout;
-	unsigned char hostc, errmask;
+	unsigned char errmask;
 
-	if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
-		if (read_write == I2C_SMBUS_WRITE) {
-			/* set I2C_EN bit in configuration register */
-			pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
-			pci_write_config_byte(I801_dev, SMBHSTCFG,
-					      hostc | SMBHSTCFG_I2C_EN);
-		} else {
-			dev_err(&I801_dev->dev,
-				"I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
-			return -1;
-		}
-	}
+	len = data->block[0];
 
 	if (read_write == I2C_SMBUS_WRITE) {
-		len = data->block[0];
-		if (len < 1)
-			len = 1;
-		if (len > 32)
-			len = 32;
 		outb_p(len, SMBHSTDAT0);
 		outb_p(data->block[1], SMBBLKDAT);
-	} else {
-		len = 32;	/* max for reads */
-	}
-
-	if(isich4 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
-		/* set 32 byte buffer */
 	}
 
 	for (i = 1; i <= len; i++) {
@@ -227,13 +272,13 @@
 		/* Make sure the SMBus host is ready to start transmitting */
 		temp = inb_p(SMBHSTSTS);
 		if (i == 1) {
-			/* Erronenous conditions before transaction: 
+			/* Erronenous conditions before transaction:
 			 * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
-			errmask=0x9f; 
+			errmask = 0x9f;
 		} else {
-			/* Erronenous conditions during transaction: 
+			/* Erronenous conditions during transaction:
 			 * Failed, Bus_Err, Dev_Err, Intr */
-			errmask=0x1e; 
+			errmask = 0x1e;
 		}
 		if (temp & errmask) {
 			dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
@@ -242,14 +287,11 @@
 			if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
 				dev_err(&I801_dev->dev,
 					"Reset failed! (%02x)\n", temp);
-				result = -1;
-                                goto END;
+				return -1;
 			}
-			if (i != 1) {
+			if (i != 1)
 				/* if die in middle of block transaction, fail */
-				result = -1;
-				goto END;
-			}
+				return -1;
 		}
 
 		if (i == 1)
@@ -261,33 +303,38 @@
 			msleep(1);
 			temp = inb_p(SMBHSTSTS);
 		}
-		    while ((!(temp & 0x80))
-			   && (timeout++ < MAX_TIMEOUT));
+		while ((!(temp & SMBHSTSTS_BYTE_DONE))
+		       && (timeout++ < MAX_TIMEOUT));
 
 		/* If the SMBus is still busy, we give up */
 		if (timeout >= MAX_TIMEOUT) {
+			/* try to stop the current command */
+			dev_dbg(&I801_dev->dev, "Terminating the current "
+						"operation\n");
+			outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
+			msleep(1);
+			outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL),
+				SMBHSTCNT);
 			result = -1;
 			dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
 		}
 
-		if (temp & 0x10) {
+		if (temp & SMBHSTSTS_FAILED) {
 			result = -1;
 			dev_dbg(&I801_dev->dev,
 				"Error: Failed bus transaction\n");
-		} else if (temp & 0x08) {
+		} else if (temp & SMBHSTSTS_BUS_ERR) {
 			result = -1;
 			dev_err(&I801_dev->dev, "Bus collision!\n");
-		} else if (temp & 0x04) {
+		} else if (temp & SMBHSTSTS_DEV_ERR) {
 			result = -1;
 			dev_dbg(&I801_dev->dev, "Error: no response!\n");
 		}
 
 		if (i == 1 && read_write == I2C_SMBUS_READ) {
 			len = inb_p(SMBHSTDAT0);
-			if (len < 1)
-				len = 1;
-			if (len > 32)
-				len = 32;
+			if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
+				return -1;
 			data->block[0] = len;
 		}
 
@@ -310,25 +357,58 @@
 			inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
 
 		if (result < 0)
-			goto END;
+			return result;
 	}
+	return result;
+}
 
-	if (hwpec) {
-		/* wait for INTR bit as advised by Intel */
-		timeout = 0;
-		do {
-			msleep(1);
-			temp = inb_p(SMBHSTSTS);
-		} while ((!(temp & 0x02))
-			   && (timeout++ < MAX_TIMEOUT));
+static int i801_set_block_buffer_mode(void)
+{
+	outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_E32B, SMBAUXCTL);
+	if ((inb_p(SMBAUXCTL) & SMBAUXCTL_E32B) == 0)
+		return -1;
+	return 0;
+}
 
-		if (timeout >= MAX_TIMEOUT) {
-			dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
+/* Block transaction function */
+static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
+				  int command, int hwpec)
+{
+	int result = 0;
+	unsigned char hostc;
+
+	if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
+		if (read_write == I2C_SMBUS_WRITE) {
+			/* set I2C_EN bit in configuration register */
+			pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
+			pci_write_config_byte(I801_dev, SMBHSTCFG,
+					      hostc | SMBHSTCFG_I2C_EN);
+		} else {
+			dev_err(&I801_dev->dev,
+				"I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
+			return -1;
 		}
-		outb_p(temp, SMBHSTSTS); 
 	}
-	result = 0;
-END:
+
+	if (read_write == I2C_SMBUS_WRITE) {
+		if (data->block[0] < 1)
+			data->block[0] = 1;
+		if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
+			data->block[0] = I2C_SMBUS_BLOCK_MAX;
+	} else {
+		data->block[0] = 32;	/* max for reads */
+	}
+
+	if (isich4 && i801_set_block_buffer_mode() == 0 )
+		result = i801_block_transaction_by_block(data, read_write,
+							 hwpec);
+	else
+		result = i801_block_transaction_byte_by_byte(data, read_write,
+							     hwpec);
+
+	if (result == 0 && hwpec)
+		i801_wait_hwpec();
+
 	if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
 		/* restore saved configuration register value */
 		pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
@@ -393,19 +473,22 @@
 		return -1;
 	}
 
-	outb_p(hwpec, SMBAUXCTL);	/* enable/disable hardware PEC */
+	if (hwpec)	/* enable/disable hardware PEC */
+		outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_CRC, SMBAUXCTL);
+	else
+		outb_p(inb_p(SMBAUXCTL) & (~SMBAUXCTL_CRC), SMBAUXCTL);
 
 	if(block)
 		ret = i801_block_transaction(data, read_write, size, hwpec);
-	else {
-		outb_p(xact | ENABLE_INT9, SMBHSTCNT);
-		ret = i801_transaction();
-	}
+	else
+		ret = i801_transaction(xact | ENABLE_INT9);
 
 	/* Some BIOSes don't like it when PEC is enabled at reboot or resume
-	   time, so we forcibly disable it after every transaction. */
+	   time, so we forcibly disable it after every transaction. Turn off
+	   E32B for the same reason. */
 	if (hwpec)
-		outb_p(0, SMBAUXCTL);
+		outb_p(inb_p(SMBAUXCTL) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B),
+		       SMBAUXCTL);
 
 	if(block)
 		return ret;
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index 90e2d93..440342b 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -491,6 +491,7 @@
 	new_adapter->id = I2C_HW_IOP3XX;
 	new_adapter->owner = THIS_MODULE;
 	new_adapter->dev.parent = &pdev->dev;
+	new_adapter->nr = pdev->id;
 
 	/*
 	 * Default values...should these come in from board code?
@@ -508,7 +509,7 @@
 	platform_set_drvdata(pdev, new_adapter);
 	new_adapter->algo_data = adapter_data;
 
-	i2c_add_adapter(new_adapter);
+	i2c_add_numbered_adapter(new_adapter);
 
 	return 0;
 
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index c6b6898..851c3ed 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -74,6 +74,25 @@
 	return IRQ_HANDLED;
 }
 
+/* Sometimes 9th clock pulse isn't generated, and slave doesn't release
+ * the bus, because it wants to send ACK.
+ * Following sequence of enabling/disabling and sending start/stop generates
+ * the pulse, so it's all OK.
+ */
+static void mpc_i2c_fixup(struct mpc_i2c *i2c)
+{
+	writeccr(i2c, 0);
+	udelay(30);
+	writeccr(i2c, CCR_MEN);
+	udelay(30);
+	writeccr(i2c, CCR_MSTA | CCR_MTX);
+	udelay(30);
+	writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
+	udelay(30);
+	writeccr(i2c, CCR_MEN);
+	udelay(30);
+}
+
 static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
 {
 	unsigned long orig_jiffies = jiffies;
@@ -153,6 +172,7 @@
 static void mpc_i2c_stop(struct mpc_i2c *i2c)
 {
 	writeccr(i2c, CCR_MEN);
+	writeccr(i2c, 0);
 }
 
 static int mpc_write(struct mpc_i2c *i2c, int target,
@@ -245,6 +265,9 @@
 		}
 		if (time_after(jiffies, orig_jiffies + HZ)) {
 			pr_debug("I2C: timeout\n");
+			if (readb(i2c->base + MPC_I2C_SR) ==
+			    (CSR_MCF | CSR_MBB | CSR_RXAK))
+				mpc_i2c_fixup(i2c);
 			return -EIO;
 		}
 		schedule();
@@ -327,9 +350,10 @@
 	platform_set_drvdata(pdev, i2c);
 
 	i2c->adap = mpc_ops;
+	i2c->adap.nr = pdev->id;
 	i2c_set_adapdata(&i2c->adap, i2c);
 	i2c->adap.dev.parent = &pdev->dev;
-	if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
+	if ((result = i2c_add_numbered_adapter(&i2c->adap)) < 0) {
 		printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
 		goto fail_add;
 	}
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index a55b333..251154a 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -527,6 +527,7 @@
 	drv_data->adapter.class = I2C_CLASS_HWMON;
 	drv_data->adapter.timeout = pdata->timeout;
 	drv_data->adapter.retries = pdata->retries;
+	drv_data->adapter.nr = pd->id;
 	platform_set_drvdata(pd, drv_data);
 	i2c_set_adapdata(&drv_data->adapter, drv_data);
 
@@ -539,7 +540,7 @@
 			drv_data->irq);
 		rc = -EINVAL;
 		goto exit_unmap_regs;
-	} else if ((rc = i2c_add_adapter(&drv_data->adapter)) != 0) {
+	} else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
 		dev_err(&drv_data->adapter.dev,
 			"mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
 		goto exit_free_irq;
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index 3cd0d63..c48140f 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -61,6 +61,7 @@
 	struct i2c_adapter adapter;
 	int base;
 	int size;
+	int blockops;
 };
 
 
@@ -80,6 +81,8 @@
 #define NVIDIA_SMB_ADDR		(smbus->base + 0x02)	/* address */
 #define NVIDIA_SMB_CMD		(smbus->base + 0x03)	/* command */
 #define NVIDIA_SMB_DATA		(smbus->base + 0x04)	/* 32 data registers */
+#define NVIDIA_SMB_BCNT		(smbus->base + 0x24)	/* number of data
+							   bytes */
 
 #define NVIDIA_SMB_STS_DONE	0x80
 #define NVIDIA_SMB_STS_ALRM	0x40
@@ -92,6 +95,7 @@
 #define NVIDIA_SMB_PRTCL_BYTE			0x04
 #define NVIDIA_SMB_PRTCL_BYTE_DATA		0x06
 #define NVIDIA_SMB_PRTCL_WORD_DATA		0x08
+#define NVIDIA_SMB_PRTCL_BLOCK_DATA		0x0a
 #define NVIDIA_SMB_PRTCL_PEC			0x80
 
 static struct pci_driver nforce2_driver;
@@ -103,6 +107,8 @@
 {
 	struct nforce2_smbus *smbus = adap->algo_data;
 	unsigned char protocol, pec, temp;
+	u8 len;
+	int i;
 
 	protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
 		NVIDIA_SMB_PRTCL_WRITE;
@@ -137,6 +143,25 @@
 			protocol |= NVIDIA_SMB_PRTCL_WORD_DATA | pec;
 			break;
 
+		case I2C_SMBUS_BLOCK_DATA:
+			outb_p(command, NVIDIA_SMB_CMD);
+			if (read_write == I2C_SMBUS_WRITE) {
+				len = data->block[0];
+				if ((len == 0) || (len > I2C_SMBUS_BLOCK_MAX)) {
+					dev_err(&adap->dev,
+						"Transaction failed "
+						"(requested block size: %d)\n",
+						len);
+					return -1;
+				}
+				outb_p(len, NVIDIA_SMB_BCNT);
+				for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
+					outb_p(data->block[i + 1],
+					       NVIDIA_SMB_DATA+i);
+			}
+			protocol |= NVIDIA_SMB_PRTCL_BLOCK_DATA | pec;
+			break;
+
 		default:
 			dev_err(&adap->dev, "Unsupported transaction %d\n", size);
 			return -1;
@@ -174,6 +199,14 @@
 		case I2C_SMBUS_WORD_DATA:
 			data->word = inb_p(NVIDIA_SMB_DATA) | (inb_p(NVIDIA_SMB_DATA+1) << 8);
 			break;
+
+		case I2C_SMBUS_BLOCK_DATA:
+			len = inb_p(NVIDIA_SMB_BCNT);
+			len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
+			for (i = 0; i < len; i++)
+				data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i);
+			data->block[0] = len;
+			break;
 	}
 
 	return 0;
@@ -184,7 +217,9 @@
 {
 	/* other functionality might be possible, but is not tested */
 	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
-	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
+	       I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+	       (((struct nforce2_smbus*)adapter->algo_data)->blockops ?
+		I2C_FUNC_SMBUS_BLOCK_DATA : 0);
 }
 
 static struct i2c_algorithm smbus_algorithm = {
@@ -268,6 +303,13 @@
 		return -ENOMEM;
 	pci_set_drvdata(dev, smbuses);
 
+	switch(dev->device) {
+	case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS:
+	case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS:
+		smbuses[0].blockops = 1;
+		smbuses[1].blockops = 1;
+	}
+
 	/* SMBus adapter 1 */
 	res1 = nforce2_probe_smb(dev, 4, NFORCE_PCI_SMB1, &smbuses[0], "SMB1");
 	if (res1 < 0) {
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 5a52bf5e..debc76c 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -23,7 +23,7 @@
    Supports:
 	Intel PIIX4, 440MX
 	Serverworks OSB4, CSB5, CSB6, HT-1000
-	ATI IXP200, IXP300, IXP400, SB600
+	ATI IXP200, IXP300, IXP400, SB600, SB700
 	SMSC Victory66
 
    Note: we assume there can only be one device, with one SMBus interface.
@@ -399,6 +399,8 @@
 	  .driver_data = 0 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SMBUS),
 	  .driver_data = 0 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SMBUS),
+	  .driver_data = 0 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4),
 	  .driver_data = 0 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5),
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c
new file mode 100644
index 0000000..03188d2
--- /dev/null
+++ b/drivers/i2c/busses/i2c-pmcmsp.c
@@ -0,0 +1,653 @@
+/*
+ * Specific bus support for PMC-TWI compliant implementation on MSP71xx.
+ *
+ * Copyright 2005-2007 PMC-Sierra, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#define DRV_NAME	"pmcmsptwi"
+
+#define MSP_TWI_SF_CLK_REG_OFFSET	0x00
+#define MSP_TWI_HS_CLK_REG_OFFSET	0x04
+#define MSP_TWI_CFG_REG_OFFSET		0x08
+#define MSP_TWI_CMD_REG_OFFSET		0x0c
+#define MSP_TWI_ADD_REG_OFFSET		0x10
+#define MSP_TWI_DAT_0_REG_OFFSET	0x14
+#define MSP_TWI_DAT_1_REG_OFFSET	0x18
+#define MSP_TWI_INT_STS_REG_OFFSET	0x1c
+#define MSP_TWI_INT_MSK_REG_OFFSET	0x20
+#define MSP_TWI_BUSY_REG_OFFSET		0x24
+
+#define MSP_TWI_INT_STS_DONE			(1 << 0)
+#define MSP_TWI_INT_STS_LOST_ARBITRATION	(1 << 1)
+#define MSP_TWI_INT_STS_NO_RESPONSE		(1 << 2)
+#define MSP_TWI_INT_STS_DATA_COLLISION		(1 << 3)
+#define MSP_TWI_INT_STS_BUSY			(1 << 4)
+#define MSP_TWI_INT_STS_ALL			0x1f
+
+#define MSP_MAX_BYTES_PER_RW		8
+#define MSP_MAX_POLL			5
+#define MSP_POLL_DELAY			10
+#define MSP_IRQ_TIMEOUT			(MSP_MAX_POLL * MSP_POLL_DELAY)
+
+/* IO Operation macros */
+#define pmcmsptwi_readl		__raw_readl
+#define pmcmsptwi_writel	__raw_writel
+
+/* TWI command type */
+enum pmcmsptwi_cmd_type {
+	MSP_TWI_CMD_WRITE	= 0,	/* Write only */
+	MSP_TWI_CMD_READ	= 1,	/* Read only */
+	MSP_TWI_CMD_WRITE_READ	= 2,	/* Write then Read */
+};
+
+/* The possible results of the xferCmd */
+enum pmcmsptwi_xfer_result {
+	MSP_TWI_XFER_OK	= 0,
+	MSP_TWI_XFER_TIMEOUT,
+	MSP_TWI_XFER_BUSY,
+	MSP_TWI_XFER_DATA_COLLISION,
+	MSP_TWI_XFER_NO_RESPONSE,
+	MSP_TWI_XFER_LOST_ARBITRATION,
+};
+
+/* Corresponds to a PMCTWI clock configuration register */
+struct pmcmsptwi_clock {
+	u8 filter;	/* Bits 15:12,	default = 0x03 */
+	u16 clock;	/* Bits 9:0,	default = 0x001f */
+};
+
+struct pmcmsptwi_clockcfg {
+	struct pmcmsptwi_clock standard;  /* The standard/fast clock config */
+	struct pmcmsptwi_clock highspeed; /* The highspeed clock config */
+};
+
+/* Corresponds to the main TWI configuration register */
+struct pmcmsptwi_cfg {
+	u8 arbf;	/* Bits 15:12,	default=0x03 */
+	u8 nak;		/* Bits 11:8,	default=0x03 */
+	u8 add10;	/* Bit 7,	default=0x00 */
+	u8 mst_code;	/* Bits 6:4,	default=0x00 */
+	u8 arb;		/* Bit 1,	default=0x01 */
+	u8 highspeed;	/* Bit 0,	default=0x00 */
+};
+
+/* A single pmctwi command to issue */
+struct pmcmsptwi_cmd {
+	u16 addr;	/* The slave address (7 or 10 bits) */
+	enum pmcmsptwi_cmd_type type;	/* The command type */
+	u8 write_len;	/* Number of bytes in the write buffer */
+	u8 read_len;	/* Number of bytes in the read buffer */
+	u8 *write_data;	/* Buffer of characters to send */
+	u8 *read_data;	/* Buffer to fill with incoming data */
+};
+
+/* The private data */
+struct pmcmsptwi_data {
+	void __iomem *iobase;			/* iomapped base for IO */
+	int irq;				/* IRQ to use (0 disables) */
+	struct completion wait;			/* Completion for xfer */
+	struct mutex lock;			/* Used for threadsafeness */
+	enum pmcmsptwi_xfer_result last_result;	/* result of last xfer */
+};
+
+/* The default settings */
+const static struct pmcmsptwi_clockcfg pmcmsptwi_defclockcfg = {
+	.standard = {
+		.filter	= 0x3,
+		.clock	= 0x1f,
+	},
+	.highspeed = {
+		.filter	= 0x3,
+		.clock	= 0x1f,
+	},
+};
+
+const static struct pmcmsptwi_cfg pmcmsptwi_defcfg = {
+	.arbf		= 0x03,
+	.nak		= 0x03,
+	.add10		= 0x00,
+	.mst_code	= 0x00,
+	.arb		= 0x01,
+	.highspeed	= 0x00,
+};
+
+static struct pmcmsptwi_data pmcmsptwi_data;
+
+static struct i2c_adapter pmcmsptwi_adapter;
+
+/* inline helper functions */
+static inline u32 pmcmsptwi_clock_to_reg(
+			const struct pmcmsptwi_clock *clock)
+{
+	return ((clock->filter & 0xf) << 12) | (clock->clock & 0x03ff);
+}
+
+static inline void pmcmsptwi_reg_to_clock(
+			u32 reg, struct pmcmsptwi_clock *clock)
+{
+	clock->filter = (reg >> 12) & 0xf;
+	clock->clock = reg & 0x03ff;
+}
+
+static inline u32 pmcmsptwi_cfg_to_reg(const struct pmcmsptwi_cfg *cfg)
+{
+	return ((cfg->arbf & 0xf) << 12) |
+		((cfg->nak & 0xf) << 8) |
+		((cfg->add10 & 0x1) << 7) |
+		((cfg->mst_code & 0x7) << 4) |
+		((cfg->arb & 0x1) << 1) |
+		(cfg->highspeed & 0x1);
+}
+
+static inline void pmcmsptwi_reg_to_cfg(u32 reg, struct pmcmsptwi_cfg *cfg)
+{
+	cfg->arbf = (reg >> 12) & 0xf;
+	cfg->nak = (reg >> 8) & 0xf;
+	cfg->add10 = (reg >> 7) & 0x1;
+	cfg->mst_code = (reg >> 4) & 0x7;
+	cfg->arb = (reg >> 1) & 0x1;
+	cfg->highspeed = reg & 0x1;
+}
+
+/*
+ * Sets the current clock configuration
+ */
+static void pmcmsptwi_set_clock_config(const struct pmcmsptwi_clockcfg *cfg,
+					struct pmcmsptwi_data *data)
+{
+	mutex_lock(&data->lock);
+	pmcmsptwi_writel(pmcmsptwi_clock_to_reg(&cfg->standard),
+				data->iobase + MSP_TWI_SF_CLK_REG_OFFSET);
+	pmcmsptwi_writel(pmcmsptwi_clock_to_reg(&cfg->highspeed),
+				data->iobase + MSP_TWI_HS_CLK_REG_OFFSET);
+	mutex_unlock(&data->lock);
+}
+
+/*
+ * Gets the current TWI bus configuration
+ */
+static void pmcmsptwi_get_twi_config(struct pmcmsptwi_cfg *cfg,
+					struct pmcmsptwi_data *data)
+{
+	mutex_lock(&data->lock);
+	pmcmsptwi_reg_to_cfg(pmcmsptwi_readl(
+				data->iobase + MSP_TWI_CFG_REG_OFFSET), cfg);
+	mutex_unlock(&data->lock);
+}
+
+/*
+ * Sets the current TWI bus configuration
+ */
+static void pmcmsptwi_set_twi_config(const struct pmcmsptwi_cfg *cfg,
+					struct pmcmsptwi_data *data)
+{
+	mutex_lock(&data->lock);
+	pmcmsptwi_writel(pmcmsptwi_cfg_to_reg(cfg),
+				data->iobase + MSP_TWI_CFG_REG_OFFSET);
+	mutex_unlock(&data->lock);
+}
+
+/*
+ * Parses the 'int_sts' register and returns a well-defined error code
+ */
+static enum pmcmsptwi_xfer_result pmcmsptwi_get_result(u32 reg)
+{
+	if (reg & MSP_TWI_INT_STS_LOST_ARBITRATION) {
+		dev_dbg(&pmcmsptwi_adapter.dev,
+			"Result: Lost arbitration\n");
+		return MSP_TWI_XFER_LOST_ARBITRATION;
+	} else if (reg & MSP_TWI_INT_STS_NO_RESPONSE) {
+		dev_dbg(&pmcmsptwi_adapter.dev,
+			"Result: No response\n");
+		return MSP_TWI_XFER_NO_RESPONSE;
+	} else if (reg & MSP_TWI_INT_STS_DATA_COLLISION) {
+		dev_dbg(&pmcmsptwi_adapter.dev,
+			"Result: Data collision\n");
+		return MSP_TWI_XFER_DATA_COLLISION;
+	} else if (reg & MSP_TWI_INT_STS_BUSY) {
+		dev_dbg(&pmcmsptwi_adapter.dev,
+			"Result: Bus busy\n");
+		return MSP_TWI_XFER_BUSY;
+	}
+
+	dev_dbg(&pmcmsptwi_adapter.dev, "Result: Operation succeeded\n");
+	return MSP_TWI_XFER_OK;
+}
+
+/*
+ * In interrupt mode, handle the interrupt.
+ * NOTE: Assumes data->lock is held.
+ */
+static irqreturn_t pmcmsptwi_interrupt(int irq, void *ptr)
+{
+	struct pmcmsptwi_data *data = ptr;
+
+	u32 reason = pmcmsptwi_readl(data->iobase +
+					MSP_TWI_INT_STS_REG_OFFSET);
+	pmcmsptwi_writel(reason, data->iobase + MSP_TWI_INT_STS_REG_OFFSET);
+
+	dev_dbg(&pmcmsptwi_adapter.dev, "Got interrupt 0x%08x\n", reason);
+	if (!(reason & MSP_TWI_INT_STS_DONE))
+		return IRQ_NONE;
+
+	data->last_result = pmcmsptwi_get_result(reason);
+	complete(&data->wait);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Probe for and register the device and return 0 if there is one.
+ */
+static int __devinit pmcmsptwi_probe(struct platform_device *pldev)
+{
+	struct resource *res;
+	int rc = -ENODEV;
+
+	/* get the static platform resources */
+	res = platform_get_resource(pldev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pldev->dev, "IOMEM resource not found\n");
+		goto ret_err;
+	}
+
+	/* reserve the memory region */
+	if (!request_mem_region(res->start, res->end - res->start + 1,
+				pldev->name)) {
+		dev_err(&pldev->dev,
+			"Unable to get memory/io address region 0x%08x\n",
+			res->start);
+		rc = -EBUSY;
+		goto ret_err;
+	}
+
+	/* remap the memory */
+	pmcmsptwi_data.iobase = ioremap_nocache(res->start,
+						res->end - res->start + 1);
+	if (!pmcmsptwi_data.iobase) {
+		dev_err(&pldev->dev,
+			"Unable to ioremap address 0x%08x\n", res->start);
+		rc = -EIO;
+		goto ret_unreserve;
+	}
+
+	/* request the irq */
+	pmcmsptwi_data.irq = platform_get_irq(pldev, 0);
+	if (pmcmsptwi_data.irq) {
+		rc = request_irq(pmcmsptwi_data.irq, &pmcmsptwi_interrupt,
+			IRQF_SHARED | IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
+			pldev->name, &pmcmsptwi_data);
+		if (rc == 0) {
+			/*
+			 * Enable 'DONE' interrupt only.
+			 *
+			 * If you enable all interrupts, you will get one on
+			 * error and another when the operation completes.
+			 * This way you only have to handle one interrupt,
+			 * but you can still check all result flags.
+			 */
+			pmcmsptwi_writel(MSP_TWI_INT_STS_DONE,
+					pmcmsptwi_data.iobase +
+					MSP_TWI_INT_MSK_REG_OFFSET);
+		} else {
+			dev_warn(&pldev->dev,
+				"Could not assign TWI IRQ handler "
+				"to irq %d (continuing with poll)\n",
+				pmcmsptwi_data.irq);
+			pmcmsptwi_data.irq = 0;
+		}
+	}
+
+	init_completion(&pmcmsptwi_data.wait);
+	mutex_init(&pmcmsptwi_data.lock);
+
+	pmcmsptwi_set_clock_config(&pmcmsptwi_defclockcfg, &pmcmsptwi_data);
+	pmcmsptwi_set_twi_config(&pmcmsptwi_defcfg, &pmcmsptwi_data);
+
+	printk(KERN_INFO DRV_NAME ": Registering MSP71xx I2C adapter\n");
+
+	pmcmsptwi_adapter.dev.parent = &pldev->dev;
+	platform_set_drvdata(pldev, &pmcmsptwi_adapter);
+	i2c_set_adapdata(&pmcmsptwi_adapter, &pmcmsptwi_data);
+
+	rc = i2c_add_adapter(&pmcmsptwi_adapter);
+	if (rc) {
+		dev_err(&pldev->dev, "Unable to register I2C adapter\n");
+		goto ret_unmap;
+	}
+
+	return 0;
+
+ret_unmap:
+	platform_set_drvdata(pldev, NULL);
+	if (pmcmsptwi_data.irq) {
+		pmcmsptwi_writel(0,
+			pmcmsptwi_data.iobase + MSP_TWI_INT_MSK_REG_OFFSET);
+		free_irq(pmcmsptwi_data.irq, &pmcmsptwi_data);
+	}
+
+	iounmap(pmcmsptwi_data.iobase);
+
+ret_unreserve:
+	release_mem_region(res->start, res->end - res->start + 1);
+
+ret_err:
+	return rc;
+}
+
+/*
+ * Release the device and return 0 if there is one.
+ */
+static int __devexit pmcmsptwi_remove(struct platform_device *pldev)
+{
+	struct resource *res;
+
+	i2c_del_adapter(&pmcmsptwi_adapter);
+
+	platform_set_drvdata(pldev, NULL);
+	if (pmcmsptwi_data.irq) {
+		pmcmsptwi_writel(0,
+			pmcmsptwi_data.iobase + MSP_TWI_INT_MSK_REG_OFFSET);
+		free_irq(pmcmsptwi_data.irq, &pmcmsptwi_data);
+	}
+
+	iounmap(pmcmsptwi_data.iobase);
+
+	res = platform_get_resource(pldev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, res->end - res->start + 1);
+
+	return 0;
+}
+
+/*
+ * Polls the 'busy' register until the command is complete.
+ * NOTE: Assumes data->lock is held.
+ */
+static void pmcmsptwi_poll_complete(struct pmcmsptwi_data *data)
+{
+	int i;
+
+	for (i = 0; i < MSP_MAX_POLL; i++) {
+		u32 val = pmcmsptwi_readl(data->iobase +
+						MSP_TWI_BUSY_REG_OFFSET);
+		if (val == 0) {
+			u32 reason = pmcmsptwi_readl(data->iobase +
+						MSP_TWI_INT_STS_REG_OFFSET);
+			pmcmsptwi_writel(reason, data->iobase +
+						MSP_TWI_INT_STS_REG_OFFSET);
+			data->last_result = pmcmsptwi_get_result(reason);
+			return;
+		}
+		udelay(MSP_POLL_DELAY);
+	}
+
+	dev_dbg(&pmcmsptwi_adapter.dev, "Result: Poll timeout\n");
+	data->last_result = MSP_TWI_XFER_TIMEOUT;
+}
+
+/*
+ * Do the transfer (low level):
+ *   May use interrupt-driven or polling, depending on if an IRQ is
+ *   presently registered.
+ * NOTE: Assumes data->lock is held.
+ */
+static enum pmcmsptwi_xfer_result pmcmsptwi_do_xfer(
+			u32 reg, struct pmcmsptwi_data *data)
+{
+	dev_dbg(&pmcmsptwi_adapter.dev, "Writing cmd reg 0x%08x\n", reg);
+	pmcmsptwi_writel(reg, data->iobase + MSP_TWI_CMD_REG_OFFSET);
+	if (data->irq) {
+		unsigned long timeleft = wait_for_completion_timeout(
+						&data->wait, MSP_IRQ_TIMEOUT);
+		if (timeleft == 0) {
+			dev_dbg(&pmcmsptwi_adapter.dev,
+				"Result: IRQ timeout\n");
+			complete(&data->wait);
+			data->last_result = MSP_TWI_XFER_TIMEOUT;
+		}
+	} else
+		pmcmsptwi_poll_complete(data);
+
+	return data->last_result;
+}
+
+/*
+ * Helper routine, converts 'pmctwi_cmd' struct to register format
+ */
+static inline u32 pmcmsptwi_cmd_to_reg(const struct pmcmsptwi_cmd *cmd)
+{
+	return ((cmd->type & 0x3) << 8) |
+		(((cmd->write_len - 1) & 0x7) << 4) |
+		((cmd->read_len - 1) & 0x7);
+}
+
+/*
+ * Do the transfer (high level)
+ */
+static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd(
+			struct pmcmsptwi_cmd *cmd,
+			struct pmcmsptwi_data *data)
+{
+	enum pmcmsptwi_xfer_result retval;
+
+	if ((cmd->type == MSP_TWI_CMD_WRITE && cmd->write_len == 0) ||
+	    (cmd->type == MSP_TWI_CMD_READ && cmd->read_len == 0) ||
+	    (cmd->type == MSP_TWI_CMD_WRITE_READ &&
+	    (cmd->read_len == 0 || cmd->write_len == 0))) {
+		dev_err(&pmcmsptwi_adapter.dev,
+			"%s: Cannot transfer less than 1 byte\n",
+			__FUNCTION__);
+		return -EINVAL;
+	}
+
+	if (cmd->read_len > MSP_MAX_BYTES_PER_RW ||
+	    cmd->write_len > MSP_MAX_BYTES_PER_RW) {
+		dev_err(&pmcmsptwi_adapter.dev,
+			"%s: Cannot transfer more than %d bytes\n",
+			__FUNCTION__, MSP_MAX_BYTES_PER_RW);
+		return -EINVAL;
+	}
+
+	mutex_lock(&data->lock);
+	dev_dbg(&pmcmsptwi_adapter.dev,
+		"Setting address to 0x%04x\n", cmd->addr);
+	pmcmsptwi_writel(cmd->addr, data->iobase + MSP_TWI_ADD_REG_OFFSET);
+
+	if (cmd->type == MSP_TWI_CMD_WRITE ||
+	    cmd->type == MSP_TWI_CMD_WRITE_READ) {
+		__be64 tmp = cpu_to_be64p((u64 *)cmd->write_data);
+		tmp >>= (MSP_MAX_BYTES_PER_RW - cmd->write_len) * 8;
+		dev_dbg(&pmcmsptwi_adapter.dev, "Writing 0x%016llx\n", tmp);
+		pmcmsptwi_writel(tmp & 0x00000000ffffffffLL,
+				data->iobase + MSP_TWI_DAT_0_REG_OFFSET);
+		if (cmd->write_len > 4)
+			pmcmsptwi_writel(tmp >> 32,
+				data->iobase + MSP_TWI_DAT_1_REG_OFFSET);
+	}
+
+	retval = pmcmsptwi_do_xfer(pmcmsptwi_cmd_to_reg(cmd), data);
+	if (retval != MSP_TWI_XFER_OK)
+		goto xfer_err;
+
+	if (cmd->type == MSP_TWI_CMD_READ ||
+	    cmd->type == MSP_TWI_CMD_WRITE_READ) {
+		int i;
+		u64 rmsk = ~(0xffffffffffffffffLL << (cmd->read_len * 8));
+		u64 tmp = (u64)pmcmsptwi_readl(data->iobase +
+					MSP_TWI_DAT_0_REG_OFFSET);
+		if (cmd->read_len > 4)
+			tmp |= (u64)pmcmsptwi_readl(data->iobase +
+					MSP_TWI_DAT_1_REG_OFFSET) << 32;
+		tmp &= rmsk;
+		dev_dbg(&pmcmsptwi_adapter.dev, "Read 0x%016llx\n", tmp);
+
+		for (i = 0; i < cmd->read_len; i++)
+			cmd->read_data[i] = tmp >> i;
+	}
+
+xfer_err:
+	mutex_unlock(&data->lock);
+
+	return retval;
+}
+
+/* -- Algorithm functions -- */
+
+/*
+ * Sends an i2c command out on the adapter
+ */
+static int pmcmsptwi_master_xfer(struct i2c_adapter *adap,
+				struct i2c_msg *msg, int num)
+{
+	struct pmcmsptwi_data *data = i2c_get_adapdata(adap);
+	struct pmcmsptwi_cmd cmd;
+	struct pmcmsptwi_cfg oldcfg, newcfg;
+	int ret;
+
+	if (num > 2) {
+		dev_dbg(&adap->dev, "%d messages unsupported\n", num);
+		return -EINVAL;
+	} else if (num == 2) {
+		/* Check for a dual write-then-read command */
+		struct i2c_msg *nextmsg = msg + 1;
+		if (!(msg->flags & I2C_M_RD) &&
+		    (nextmsg->flags & I2C_M_RD) &&
+		    msg->addr == nextmsg->addr) {
+			cmd.type = MSP_TWI_CMD_WRITE_READ;
+			cmd.write_len = msg->len;
+			cmd.write_data = msg->buf;
+			cmd.read_len = nextmsg->len;
+			cmd.read_data = nextmsg->buf;
+		} else {
+			dev_dbg(&adap->dev,
+				"Non write-read dual messages unsupported\n");
+			return -EINVAL;
+		}
+	} else if (msg->flags & I2C_M_RD) {
+		cmd.type = MSP_TWI_CMD_READ;
+		cmd.read_len = msg->len;
+		cmd.read_data = msg->buf;
+		cmd.write_len = 0;
+		cmd.write_data = NULL;
+	} else {
+		cmd.type = MSP_TWI_CMD_WRITE;
+		cmd.read_len = 0;
+		cmd.read_data = NULL;
+		cmd.write_len = msg->len;
+		cmd.write_data = msg->buf;
+	}
+
+	if (msg->len == 0) {
+		dev_err(&adap->dev, "Zero-byte messages unsupported\n");
+		return -EINVAL;
+	}
+
+	cmd.addr = msg->addr;
+
+	if (msg->flags & I2C_M_TEN) {
+		pmcmsptwi_get_twi_config(&newcfg, data);
+		memcpy(&oldcfg, &newcfg, sizeof(oldcfg));
+
+		/* Set the special 10-bit address flag */
+		newcfg.add10 = 1;
+
+		pmcmsptwi_set_twi_config(&newcfg, data);
+	}
+
+	/* Execute the command */
+	ret = pmcmsptwi_xfer_cmd(&cmd, data);
+
+	if (msg->flags & I2C_M_TEN)
+		pmcmsptwi_set_twi_config(&oldcfg, data);
+
+	dev_dbg(&adap->dev, "I2C %s of %d bytes ",
+		(msg->flags & I2C_M_RD) ? "read" : "write", msg->len);
+	if (ret != MSP_TWI_XFER_OK) {
+		/*
+		 * TODO: We could potentially loop and retry in the case
+		 * of MSP_TWI_XFER_TIMEOUT.
+		 */
+		dev_dbg(&adap->dev, "failed\n");
+		return -1;
+	}
+
+	dev_dbg(&adap->dev, "succeeded\n");
+	return 0;
+}
+
+static u32 pmcmsptwi_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
+		I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
+		I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL;
+}
+
+/* -- Initialization -- */
+
+static struct i2c_algorithm pmcmsptwi_algo = {
+	.master_xfer	= pmcmsptwi_master_xfer,
+	.functionality	= pmcmsptwi_i2c_func,
+};
+
+static struct i2c_adapter pmcmsptwi_adapter = {
+	.owner		= THIS_MODULE,
+	.class		= I2C_CLASS_HWMON,
+	.algo		= &pmcmsptwi_algo,
+	.name		= DRV_NAME,
+};
+
+static struct platform_driver pmcmsptwi_driver = {
+	.probe  = pmcmsptwi_probe,
+	.remove	= __devexit_p(pmcmsptwi_remove),
+	.driver {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init pmcmsptwi_init(void)
+{
+	return platform_driver_register(&pmcmsptwi_driver);
+}
+
+static void __exit pmcmsptwi_exit(void)
+{
+	platform_driver_unregister(&pmcmsptwi_driver);
+}
+
+MODULE_DESCRIPTION("PMC MSP TWI/SMBus/I2C driver");
+MODULE_LICENSE("GPL");
+
+module_init(pmcmsptwi_init);
+module_exit(pmcmsptwi_exit);
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index 1425d224..0ab4f26 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -121,8 +121,7 @@
 		if (rc)
 			goto bail;
 		rc = pmac_i2c_xfer(bus, addrdir, 1, command,
-				   read ? data->block : &data->block[1],
-				   data->block[0]);
+				   &data->block[1], data->block[0]);
 		break;
 
         default:
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 28e7b91..9d6b790 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -921,7 +921,14 @@
 		i2c->adap.class = plat->class;
 	}
 
-	ret = i2c_add_adapter(&i2c->adap);
+	/*
+	 * If "dev->id" is negative we consider it as zero.
+	 * The reason to do so is to avoid sysfs names that only make
+	 * sense when there are multiple adapters.
+	 */
+	i2c->adap.nr = dev->id >= 0 ? dev->id : 0;
+
+	ret = i2c_add_numbered_adapter(&i2c->adap);
 	if (ret < 0) {
 		printk(KERN_INFO "I2C: Failed to add bus\n");
 		goto eadapt;
diff --git a/drivers/i2c/busses/i2c-rpx.c b/drivers/i2c/busses/i2c-rpx.c
deleted file mode 100644
index 8764df0..0000000
--- a/drivers/i2c/busses/i2c-rpx.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Embedded Planet RPX Lite MPC8xx CPM I2C interface.
- * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
- *
- * moved into proper i2c interface;
- * Brad Parker (brad@heeltoe.com)
- *
- * RPX lite specific parts of the i2c interface
- * Update:  There actually isn't anything RPXLite-specific about this module.
- * This should work for most any 8xx board.  The console messages have been 
- * changed to eliminate RPXLite references.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/stddef.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-8xx.h>
-#include <asm/mpc8xx.h>
-#include <asm/commproc.h>
-
-
-static void
-rpx_iic_init(struct i2c_algo_8xx_data *data)
-{
-	volatile cpm8xx_t *cp;
-	volatile immap_t *immap;
-
-	cp = cpmp;	/* Get pointer to Communication Processor */
-	immap = (immap_t *)IMAP_ADDR;	/* and to internal registers */
-
-	data->iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
-
-	/* Check for and use a microcode relocation patch.
-	*/
-	if ((data->reloc = data->iip->iic_rpbase))
-		data->iip = (iic_t *)&cp->cp_dpmem[data->iip->iic_rpbase];
-		
-	data->i2c = (i2c8xx_t *)&(immap->im_i2c);
-	data->cp = cp;
-
-	/* Initialize Port B IIC pins.
-	*/
-	cp->cp_pbpar |= 0x00000030;
-	cp->cp_pbdir |= 0x00000030;
-	cp->cp_pbodr |= 0x00000030;
-
-	/* Allocate space for two transmit and two receive buffer
-	 * descriptors in the DP ram.
-	 */
-	data->dp_addr = cpm_dpalloc(sizeof(cbd_t) * 4, 8);
-		
-	/* ptr to i2c area */
-	data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c);
-}
-
-static int rpx_install_isr(int irq, void (*func)(void *), void *data)
-{
-	/* install interrupt handler */
-	cpm_install_handler(irq, func, data);
-
-	return 0;
-}
-
-static struct i2c_algo_8xx_data rpx_data = {
-	.setisr = rpx_install_isr
-};
-
-static struct i2c_adapter rpx_ops = {
-	.owner		= THIS_MODULE,
-	.name		= "m8xx",
-	.id		= I2C_HW_MPC8XX_EPON,
-	.algo_data	= &rpx_data,
-};
-
-int __init i2c_rpx_init(void)
-{
-	printk(KERN_INFO "i2c-rpx: i2c MPC8xx driver\n");
-
-	/* reset hardware to sane state */
-	rpx_iic_init(&rpx_data);
-
-	if (i2c_8xx_add_bus(&rpx_ops) < 0) {
-		printk(KERN_ERR "i2c-rpx: Unable to register with I2C\n");
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-void __exit i2c_rpx_exit(void)
-{
-	i2c_8xx_del_bus(&rpx_ops);
-}
-
-MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for MPC8xx boards");
-
-module_init(i2c_rpx_init);
-module_exit(i2c_rpx_exit);
diff --git a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c
index b7fb65c..8adf4ab 100644
--- a/drivers/i2c/busses/i2c-savage4.c
+++ b/drivers/i2c/busses/i2c-savage4.c
@@ -25,8 +25,6 @@
 /* This interfaces to the I2C bus of the Savage4 to gain access to
    the BT869 and possibly other I2C devices. The DDC bus is not
    yet supported because its register is not memory-mapped.
-   However we leave the DDC code here, commented out, to make
-   it easier to add later.
 */
 
 #include <linux/kernel.h>
@@ -37,36 +35,19 @@
 #include <linux/i2c-algo-bit.h>
 #include <asm/io.h>
 
-/* 3DFX defines */
-#define PCI_CHIP_SAVAGE3D	0x8A20
-#define PCI_CHIP_SAVAGE3D_MV	0x8A21
+/* device IDs */
 #define PCI_CHIP_SAVAGE4	0x8A22
 #define PCI_CHIP_SAVAGE2000	0x9102
-#define PCI_CHIP_PROSAVAGE_PM	0x8A25
-#define PCI_CHIP_PROSAVAGE_KM	0x8A26
-#define PCI_CHIP_SAVAGE_MX_MV	0x8c10
-#define PCI_CHIP_SAVAGE_MX	0x8c11
-#define PCI_CHIP_SAVAGE_IX_MV	0x8c12
-#define PCI_CHIP_SAVAGE_IX	0x8c13
 
 #define REG			0xff20	/* Serial Port 1 Register */
 
 /* bit locations in the register */
-#define DDC_ENAB		0x00040000
-#define DDC_SCL_OUT		0x00080000
-#define DDC_SDA_OUT		0x00100000
-#define DDC_SCL_IN		0x00200000
-#define DDC_SDA_IN		0x00400000
 #define I2C_ENAB		0x00000020
 #define I2C_SCL_OUT		0x00000001
 #define I2C_SDA_OUT		0x00000002
 #define I2C_SCL_IN		0x00000008
 #define I2C_SDA_IN		0x00000010
 
-/* initialization states */
-#define INIT2			0x20
-#define INIT3			0x04
-
 /* delays */
 #define CYCLE_DELAY		10
 #define TIMEOUT			(HZ / 2)
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index a6feed4..283769c 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -129,6 +129,7 @@
 
 static struct pci_driver sis5595_driver;
 static unsigned short sis5595_base;
+static struct pci_dev *sis5595_pdev;
 
 static u8 sis5595_read(u8 reg)
 {
@@ -379,6 +380,8 @@
 
 static int __devinit sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
+	int err;
+
 	if (sis5595_setup(dev)) {
 		dev_err(&dev->dev, "SIS5595 not detected, module not inserted.\n");
 		return -ENODEV;
@@ -389,20 +392,24 @@
 
 	sprintf(sis5595_adapter.name, "SMBus SIS5595 adapter at %04x",
 		sis5595_base + SMB_INDEX);
-	return i2c_add_adapter(&sis5595_adapter);
-}
+	err = i2c_add_adapter(&sis5595_adapter);
+	if (err) {
+		release_region(sis5595_base + SMB_INDEX, 2);
+		return err;
+	}
 
-static void __devexit sis5595_remove(struct pci_dev *dev)
-{
-	i2c_del_adapter(&sis5595_adapter);
-	release_region(sis5595_base + SMB_INDEX, 2);
+	/* Always return failure here.  This is to allow other drivers to bind
+	 * to this pci device.  We don't really want to have control over the
+	 * pci device, we only wanted to read as few register values from it.
+	 */
+	sis5595_pdev =  pci_dev_get(dev);
+	return -ENODEV;
 }
 
 static struct pci_driver sis5595_driver = {
 	.name		= "sis5595_smbus",
 	.id_table	= sis5595_ids,
 	.probe		= sis5595_probe,
-	.remove		= __devexit_p(sis5595_remove),
 };
 
 static int __init i2c_sis5595_init(void)
@@ -413,6 +420,12 @@
 static void __exit i2c_sis5595_exit(void)
 {
 	pci_unregister_driver(&sis5595_driver);
+	if (sis5595_pdev) {
+		i2c_del_adapter(&sis5595_adapter);
+		release_region(sis5595_base + SMB_INDEX, 2);
+		pci_dev_put(sis5595_pdev);
+		sis5595_pdev = NULL;
+	}
 }
 
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c
new file mode 100644
index 0000000..1b0cfd5
--- /dev/null
+++ b/drivers/i2c/busses/i2c-taos-evm.c
@@ -0,0 +1,330 @@
+/*
+ * Driver for the TAOS evaluation modules
+ * These devices include an I2C master which can be controlled over the
+ * serial port.
+ *
+ * Copyright (C) 2007 Jean Delvare <khali@linux-fr.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+
+#define TAOS_BUFFER_SIZE	63
+
+#define TAOS_STATE_INIT		0
+#define TAOS_STATE_IDLE		1
+#define TAOS_STATE_SEND		2
+#define TAOS_STATE_RECV		3
+
+#define TAOS_CMD_RESET		0x12
+
+static DECLARE_WAIT_QUEUE_HEAD(wq);
+
+struct taos_data {
+	struct i2c_adapter adapter;
+	struct i2c_client *client;
+	int state;
+	u8 addr;		/* last used address */
+	unsigned char buffer[TAOS_BUFFER_SIZE];
+	unsigned int pos;	/* position inside the buffer */
+};
+
+/* TAOS TSL2550 EVM */
+static struct i2c_board_info tsl2550_info = {
+	I2C_BOARD_INFO("tsl2550", 0x39),
+	.type	= "tsl2550",
+};
+
+/* Instantiate i2c devices based on the adapter name */
+static struct i2c_client *taos_instantiate_device(struct i2c_adapter *adapter)
+{
+	if (!strncmp(adapter->name, "TAOS TSL2550 EVM", 16)) {
+		dev_info(&adapter->dev, "Instantiating device %s at 0x%02x\n",
+			tsl2550_info.driver_name, tsl2550_info.addr);
+		return i2c_new_device(adapter, &tsl2550_info);
+	}
+
+	return NULL;
+}
+
+static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
+			   unsigned short flags, char read_write, u8 command,
+			   int size, union i2c_smbus_data *data)
+{
+	struct serio *serio = adapter->algo_data;
+	struct taos_data *taos = serio_get_drvdata(serio);
+	char *p;
+
+	/* Encode our transaction. "@" is for the device address, "$" for the
+	   SMBus command and "#" for the data. */
+	p = taos->buffer;
+
+	/* The device remembers the last used address, no need to send it
+	   again if it's the same */
+	if (addr != taos->addr)
+		p += sprintf(p, "@%02X", addr);
+
+	switch (size) {
+	case I2C_SMBUS_BYTE:
+		if (read_write == I2C_SMBUS_WRITE)
+			sprintf(p, "$#%02X", command);
+		else
+			sprintf(p, "$");
+		break;
+	case I2C_SMBUS_BYTE_DATA:
+		if (read_write == I2C_SMBUS_WRITE)
+			sprintf(p, "$%02X#%02X", command, data->byte);
+		else
+			sprintf(p, "$%02X", command);
+		break;
+	default:
+		dev_dbg(&adapter->dev, "Unsupported transaction size %d\n",
+			size);
+		return -EINVAL;
+	}
+
+	/* Send the transaction to the TAOS EVM */
+	dev_dbg(&adapter->dev, "Command buffer: %s\n", taos->buffer);
+	taos->pos = 0;
+	taos->state = TAOS_STATE_SEND;
+	serio_write(serio, taos->buffer[0]);
+	wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
+					 msecs_to_jiffies(250));
+	if (taos->state != TAOS_STATE_IDLE) {
+		dev_err(&adapter->dev, "Transaction failed "
+			"(state=%d, pos=%d)\n", taos->state, taos->pos);
+		taos->addr = 0;
+		return -EIO;
+	}
+	taos->addr = addr;
+
+	/* Start the transaction and read the answer */
+	taos->pos = 0;
+	taos->state = TAOS_STATE_RECV;
+	serio_write(serio, read_write == I2C_SMBUS_WRITE ? '>' : '<');
+	wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
+					 msecs_to_jiffies(150));
+	if (taos->state != TAOS_STATE_IDLE
+	 || taos->pos != 6) {
+		dev_err(&adapter->dev, "Transaction timeout (pos=%d)\n",
+			taos->pos);
+		return -EIO;
+	}
+	dev_dbg(&adapter->dev, "Answer buffer: %s\n", taos->buffer);
+
+	/* Interpret the returned string */
+	p = taos->buffer + 2;
+	p[3] = '\0';
+	if (!strcmp(p, "NAK"))
+		return -ENODEV;
+
+	if (read_write == I2C_SMBUS_WRITE) {
+		if (!strcmp(p, "ACK"))
+			return 0;
+	} else {
+		if (p[0] == 'x') {
+			data->byte = simple_strtol(p + 1, NULL, 16);
+			return 0;
+		}
+	}
+
+	return -EIO;
+}
+
+static u32 taos_smbus_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA;
+}
+
+static const struct i2c_algorithm taos_algorithm = {
+	.smbus_xfer	= taos_smbus_xfer,
+	.functionality	= taos_smbus_func,
+};
+
+static irqreturn_t taos_interrupt(struct serio *serio, unsigned char data,
+				  unsigned int flags)
+{
+	struct taos_data *taos = serio_get_drvdata(serio);
+
+	switch (taos->state) {
+	case TAOS_STATE_INIT:
+		taos->buffer[taos->pos++] = data;
+		if (data == ':'
+		 || taos->pos == TAOS_BUFFER_SIZE - 1) {
+			taos->buffer[taos->pos] = '\0';
+			taos->state = TAOS_STATE_IDLE;
+			wake_up_interruptible(&wq);
+		}
+		break;
+	case TAOS_STATE_SEND:
+		if (taos->buffer[++taos->pos])
+			serio_write(serio, taos->buffer[taos->pos]);
+		else {
+			taos->state = TAOS_STATE_IDLE;
+			wake_up_interruptible(&wq);
+		}
+		break;
+	case TAOS_STATE_RECV:
+		taos->buffer[taos->pos++] = data;
+		if (data == ']') {
+			taos->buffer[taos->pos] = '\0';
+			taos->state = TAOS_STATE_IDLE;
+			wake_up_interruptible(&wq);
+		}
+		break;
+	}
+
+	return IRQ_HANDLED;
+}
+
+/* Extract the adapter name from the buffer received after reset.
+   The buffer is modified and a pointer inside the buffer is returned. */
+static char *taos_adapter_name(char *buffer)
+{
+	char *start, *end;
+
+	start = strstr(buffer, "TAOS ");
+	if (!start)
+		return NULL;
+
+	end = strchr(start, '\r');
+	if (!end)
+		return NULL;
+	*end = '\0';
+
+	return start;
+}
+
+static int taos_connect(struct serio *serio, struct serio_driver *drv)
+{
+	struct taos_data *taos;
+	struct i2c_adapter *adapter;
+	char *name;
+	int err;
+
+	taos = kzalloc(sizeof(struct taos_data), GFP_KERNEL);
+	if (!taos) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	taos->state = TAOS_STATE_INIT;
+	serio_set_drvdata(serio, taos);
+
+	err = serio_open(serio, drv);
+	if (err)
+		goto exit_kfree;
+
+	adapter = &taos->adapter;
+	adapter->owner = THIS_MODULE;
+	adapter->algo = &taos_algorithm;
+	adapter->algo_data = serio;
+	adapter->dev.parent = &serio->dev;
+
+	/* Reset the TAOS evaluation module to identify it */
+	serio_write(serio, TAOS_CMD_RESET);
+	wait_event_interruptible_timeout(wq, taos->state == TAOS_STATE_IDLE,
+					 msecs_to_jiffies(2000));
+
+	if (taos->state != TAOS_STATE_IDLE) {
+		err = -ENODEV;
+		dev_dbg(&serio->dev, "TAOS EVM reset failed (state=%d, "
+			"pos=%d)\n", taos->state, taos->pos);
+		goto exit_close;
+	}
+
+	name = taos_adapter_name(taos->buffer);
+	if (!name) {
+		err = -ENODEV;
+		dev_err(&serio->dev, "TAOS EVM identification failed\n");
+		goto exit_close;
+	}
+	strlcpy(adapter->name, name, sizeof(adapter->name));
+
+	err = i2c_add_adapter(adapter);
+	if (err)
+		goto exit_close;
+	dev_dbg(&serio->dev, "Connected to TAOS EVM\n");
+
+	taos->client = taos_instantiate_device(adapter);
+	return 0;
+
+ exit_close:
+	serio_close(serio);
+ exit_kfree:
+	serio_set_drvdata(serio, NULL);
+	kfree(taos);
+ exit:
+	return err;
+}
+
+static void taos_disconnect(struct serio *serio)
+{
+	struct taos_data *taos = serio_get_drvdata(serio);
+
+	if (taos->client)
+		i2c_unregister_device(taos->client);
+	i2c_del_adapter(&taos->adapter);
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	kfree(taos);
+
+	dev_dbg(&serio->dev, "Disconnected from TAOS EVM\n");
+}
+
+static struct serio_device_id taos_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_TAOSEVM,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(serio, taos_serio_ids);
+
+static struct serio_driver taos_drv = {
+	.driver		= {
+		.name	= "taos-evm",
+	},
+	.description	= "TAOS evaluation module driver",
+	.id_table	= taos_serio_ids,
+	.connect	= taos_connect,
+	.disconnect	= taos_disconnect,
+	.interrupt	= taos_interrupt,
+};
+
+static int __init taos_init(void)
+{
+	return serio_register_driver(&taos_drv);
+}
+
+static void __exit taos_exit(void)
+{
+	serio_unregister_driver(&taos_drv);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("TAOS evaluation module driver");
+MODULE_LICENSE("GPL");
+
+module_init(taos_init);
+module_exit(taos_exit);
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 1d76b9e..edc2750 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -235,7 +235,7 @@
 		if (!(vt596_features & FEATURE_I2CBLOCK))
 			goto exit_unsupported;
 		if (read_write == I2C_SMBUS_READ)
-			outb_p(I2C_SMBUS_BLOCK_MAX, SMBHSTDAT0);
+			outb_p(data->block[0], SMBHSTDAT0);
 		/* Fall through */
 	case I2C_SMBUS_BLOCK_DATA:
 		outb_p(command, SMBHSTCMD);
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index 0d6bd4f..e6c4a2b 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -310,8 +310,6 @@
 		break;
 
 	case I2C_SMBUS_I2C_BLOCK_DATA:
-		if (rw == I2C_SMBUS_READ)
-			data->block[0] = I2C_SMBUS_BLOCK_MAX; /* For now */
 		len = data->block[0];
 		if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
 			return -EINVAL;
@@ -388,7 +386,7 @@
 };
 
 static struct scx200_acb_iface *scx200_acb_list;
-static DECLARE_MUTEX(scx200_acb_list_mutex);
+static DEFINE_MUTEX(scx200_acb_list_mutex);
 
 static __init int scx200_acb_probe(struct scx200_acb_iface *iface)
 {
@@ -472,10 +470,10 @@
 		return -ENODEV;
 	}
 
-	down(&scx200_acb_list_mutex);
+	mutex_lock(&scx200_acb_list_mutex);
 	iface->next = scx200_acb_list;
 	scx200_acb_list = iface;
-	up(&scx200_acb_list_mutex);
+	mutex_unlock(&scx200_acb_list_mutex);
 
 	return 0;
 }
@@ -633,10 +631,10 @@
 {
 	struct scx200_acb_iface *iface;
 
-	down(&scx200_acb_list_mutex);
+	mutex_lock(&scx200_acb_list_mutex);
 	while ((iface = scx200_acb_list) != NULL) {
 		scx200_acb_list = iface->next;
-		up(&scx200_acb_list_mutex);
+		mutex_unlock(&scx200_acb_list_mutex);
 
 		i2c_del_adapter(&iface->adapter);
 
@@ -648,9 +646,9 @@
 			release_region(iface->base, 8);
 
 		kfree(iface);
-		down(&scx200_acb_list_mutex);
+		mutex_lock(&scx200_acb_list_mutex);
 	}
-	up(&scx200_acb_list_mutex);
+	mutex_unlock(&scx200_acb_list_mutex);
 }
 
 module_init(scx200_acb_init);
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index ea085a0..3944e88 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -5,7 +5,7 @@
 menu "Miscellaneous I2C Chip support"
 
 config SENSORS_DS1337
-	tristate "Dallas Semiconductor DS1337 and DS1339 Real Time Clock"
+	tristate "Dallas DS1337 and DS1339 Real Time Clock (DEPRECATED)"
 	depends on EXPERIMENTAL
 	help
 	  If you say yes here you get support for Dallas Semiconductor
@@ -14,8 +14,11 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called ds1337.
 
+	  This driver is deprecated and will be dropped soon. Use
+	  rtc-ds1307 instead.
+
 config SENSORS_DS1374
-	tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock"
+	tristate "Dallas DS1374 Real Time Clock (DEPRECATED)"
 	depends on EXPERIMENTAL
 	help
 	  If you say yes here you get support for Dallas Semiconductor
@@ -24,6 +27,19 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called ds1374.
 
+	  This driver is deprecated and will be dropped soon. Use
+	  rtc-ds1374 instead.
+
+config DS1682
+	tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
+	depends on EXPERIMENTAL
+	help
+	  If you say yes here you get support for Dallas Semiconductor
+	  DS1682 Total Elapsed Time Recorder.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called ds1682.
+
 config SENSORS_EEPROM
 	tristate "EEPROM reader"
 	depends on EXPERIMENTAL
@@ -101,7 +117,7 @@
 	  will be called tps65010.
 
 config SENSORS_M41T00
-	tristate "ST M41T00 RTC chip"
+	tristate "ST M41T00 RTC chip (DEPRECATED)"
 	depends on PPC32
 	help
 	  If you say yes here you get support for the ST M41T00 RTC chip.
@@ -109,6 +125,9 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called m41t00.
 
+	  This driver is deprecated and will be dropped soon. Use
+	  rtc-ds1307 or rtc-m41t80 instead.
+
 config SENSORS_MAX6875
 	tristate "Maxim MAX6875 Power supply supervisor"
 	depends on EXPERIMENTAL
@@ -124,4 +143,14 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called max6875.
 
+config SENSORS_TSL2550
+	tristate "Taos TSL2550 ambient light sensor"
+	depends on EXPERIMENTAL
+	help
+	  If you say yes here you get support for the Taos TSL2550
+	  ambient light sensor.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called tsl2550.
+
 endmenu
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index 779868e..d8cbeb3 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_SENSORS_DS1337)	+= ds1337.o
 obj-$(CONFIG_SENSORS_DS1374)	+= ds1374.o
+obj-$(CONFIG_DS1682)		+= ds1682.o
 obj-$(CONFIG_SENSORS_EEPROM)	+= eeprom.o
 obj-$(CONFIG_SENSORS_MAX6875)	+= max6875.o
 obj-$(CONFIG_SENSORS_M41T00)	+= m41t00.o
@@ -12,6 +13,7 @@
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
 obj-$(CONFIG_ISP1301_OMAP)	+= isp1301_omap.o
 obj-$(CONFIG_TPS65010)		+= tps65010.o
+obj-$(CONFIG_SENSORS_TSL2550)	+= tsl2550.o
 
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/chips/ds1682.c b/drivers/i2c/chips/ds1682.c
new file mode 100644
index 0000000..25fd467
--- /dev/null
+++ b/drivers/i2c/chips/ds1682.c
@@ -0,0 +1,259 @@
+/*
+ * Dallas Semiconductor DS1682 Elapsed Time Recorder device driver
+ *
+ * Written by: Grant Likely <grant.likely@secretlab.ca>
+ *
+ * Copyright (C) 2007 Secret Lab Technologies Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * The DS1682 elapsed timer recorder is a simple device that implements
+ * one elapsed time counter, one event counter, an alarm signal and 10
+ * bytes of general purpose EEPROM.
+ *
+ * This driver provides access to the DS1682 counters and user data via
+ * the sysfs.  The following attributes are added to the device node:
+ *     elapsed_time (u32): Total elapsed event time in ms resolution
+ *     alarm_time (u32): When elapsed time exceeds the value in alarm_time,
+ *                       then the alarm pin is asserted.
+ *     event_count (u16): number of times the event pin has gone low.
+ *     eeprom (u8[10]): general purpose EEPROM
+ *
+ * Counter registers and user data are both read/write unless the device
+ * has been write protected.  This driver does not support turning off write
+ * protection.  Once write protection is turned on, it is impossible to
+ * turn it off again, so I have left the feature out of this driver to avoid
+ * accidental enabling, but it is trivial to add write protect support.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <linux/sysfs.h>
+#include <linux/ctype.h>
+#include <linux/hwmon-sysfs.h>
+
+/* Device registers */
+#define DS1682_REG_CONFIG		0x00
+#define DS1682_REG_ALARM		0x01
+#define DS1682_REG_ELAPSED		0x05
+#define DS1682_REG_EVT_CNTR		0x09
+#define DS1682_REG_EEPROM		0x0b
+#define DS1682_REG_RESET		0x1d
+#define DS1682_REG_WRITE_DISABLE	0x1e
+#define DS1682_REG_WRITE_MEM_DISABLE	0x1f
+
+#define DS1682_EEPROM_SIZE		10
+
+/*
+ * Generic counter attributes
+ */
+static ssize_t ds1682_show(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	__le32 val = 0;
+	int rc;
+
+	dev_dbg(dev, "ds1682_show() called on %s\n", attr->attr.name);
+
+	/* Read the register */
+	rc = i2c_smbus_read_i2c_block_data(client, sattr->index, sattr->nr,
+					   (u8 *) & val);
+	if (rc < 0)
+		return -EIO;
+
+	/* Special case: the 32 bit regs are time values with 1/4s
+	 * resolution, scale them up to milliseconds */
+	if (sattr->nr == 4)
+		return sprintf(buf, "%llu\n", ((u64) le32_to_cpu(val)) * 250);
+
+	/* Format the output string and return # of bytes */
+	return sprintf(buf, "%li\n", (long)le32_to_cpu(val));
+}
+
+static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	char *endp;
+	u64 val;
+	__le32 val_le;
+	int rc;
+
+	dev_dbg(dev, "ds1682_store() called on %s\n", attr->attr.name);
+
+	/* Decode input */
+	val = simple_strtoull(buf, &endp, 0);
+	if (buf == endp) {
+		dev_dbg(dev, "input string not a number\n");
+		return -EINVAL;
+	}
+
+	/* Special case: the 32 bit regs are time values with 1/4s
+	 * resolution, scale input down to quarter-seconds */
+	if (sattr->nr == 4)
+		do_div(val, 250);
+
+	/* write out the value */
+	val_le = cpu_to_le32(val);
+	rc = i2c_smbus_write_i2c_block_data(client, sattr->index, sattr->nr,
+					    (u8 *) & val_le);
+	if (rc < 0) {
+		dev_err(dev, "register write failed; reg=0x%x, size=%i\n",
+			sattr->index, sattr->nr);
+		return -EIO;
+	}
+
+	return count;
+}
+
+/*
+ * Simple register attributes
+ */
+static SENSOR_DEVICE_ATTR_2(elapsed_time, S_IRUGO | S_IWUSR, ds1682_show,
+			    ds1682_store, 4, DS1682_REG_ELAPSED);
+static SENSOR_DEVICE_ATTR_2(alarm_time, S_IRUGO | S_IWUSR, ds1682_show,
+			    ds1682_store, 4, DS1682_REG_ALARM);
+static SENSOR_DEVICE_ATTR_2(event_count, S_IRUGO | S_IWUSR, ds1682_show,
+			    ds1682_store, 2, DS1682_REG_EVT_CNTR);
+
+static const struct attribute_group ds1682_group = {
+	.attrs = (struct attribute *[]) {
+		&sensor_dev_attr_elapsed_time.dev_attr.attr,
+		&sensor_dev_attr_alarm_time.dev_attr.attr,
+		&sensor_dev_attr_event_count.dev_attr.attr,
+		NULL,
+	},
+};
+
+/*
+ * User data attribute
+ */
+static ssize_t ds1682_eeprom_read(struct kobject *kobj, char *buf, loff_t off,
+				  size_t count)
+{
+	struct i2c_client *client = kobj_to_i2c_client(kobj);
+	int rc;
+
+	dev_dbg(&client->dev, "ds1682_eeprom_read(p=%p, off=%lli, c=%zi)\n",
+		buf, off, count);
+
+	if (off >= DS1682_EEPROM_SIZE)
+		return 0;
+
+	if (off + count > DS1682_EEPROM_SIZE)
+		count = DS1682_EEPROM_SIZE - off;
+
+	rc = i2c_smbus_read_i2c_block_data(client, DS1682_REG_EEPROM + off,
+					   count, buf);
+	if (rc < 0)
+		return -EIO;
+
+	return count;
+}
+
+static ssize_t ds1682_eeprom_write(struct kobject *kobj, char *buf, loff_t off,
+				   size_t count)
+{
+	struct i2c_client *client = kobj_to_i2c_client(kobj);
+
+	dev_dbg(&client->dev, "ds1682_eeprom_write(p=%p, off=%lli, c=%zi)\n",
+		buf, off, count);
+
+	if (off >= DS1682_EEPROM_SIZE)
+		return -ENOSPC;
+
+	if (off + count > DS1682_EEPROM_SIZE)
+		count = DS1682_EEPROM_SIZE - off;
+
+	/* Write out to the device */
+	if (i2c_smbus_write_i2c_block_data(client, DS1682_REG_EEPROM + off,
+					   count, buf) < 0)
+		return -EIO;
+
+	return count;
+}
+
+static struct bin_attribute ds1682_eeprom_attr = {
+	.attr = {
+		.name = "eeprom",
+		.mode = S_IRUGO | S_IWUSR,
+		.owner = THIS_MODULE,
+	},
+	.size = DS1682_EEPROM_SIZE,
+	.read = ds1682_eeprom_read,
+	.write = ds1682_eeprom_write,
+};
+
+/*
+ * Called when a ds1682 device is matched with this driver
+ */
+static int ds1682_probe(struct i2c_client *client)
+{
+	int rc;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_I2C_BLOCK)) {
+		dev_err(&client->dev, "i2c bus does not support the ds1682\n");
+		rc = -ENODEV;
+		goto exit;
+	}
+
+	rc = sysfs_create_group(&client->dev.kobj, &ds1682_group);
+	if (rc)
+		goto exit;
+
+	rc = sysfs_create_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
+	if (rc)
+		goto exit_bin_attr;
+
+	return 0;
+
+ exit_bin_attr:
+	sysfs_remove_group(&client->dev.kobj, &ds1682_group);
+ exit:
+	return rc;
+}
+
+static int ds1682_remove(struct i2c_client *client)
+{
+	sysfs_remove_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
+	sysfs_remove_group(&client->dev.kobj, &ds1682_group);
+	return 0;
+}
+
+static struct i2c_driver ds1682_driver = {
+	.driver = {
+		.name = "ds1682",
+	},
+	.probe = ds1682_probe,
+	.remove = ds1682_remove,
+};
+
+static int __init ds1682_init(void)
+{
+	return i2c_add_driver(&ds1682_driver);
+}
+
+static void __exit ds1682_exit(void)
+{
+	i2c_del_driver(&ds1682_driver);
+}
+
+MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
+MODULE_DESCRIPTION("DS1682 Elapsed Time Indicator driver");
+MODULE_LICENSE("GPL");
+
+module_init(ds1682_init);
+module_exit(ds1682_exit);
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
index bfce13c..d3da1fb 100644
--- a/drivers/i2c/chips/eeprom.c
+++ b/drivers/i2c/chips/eeprom.c
@@ -88,8 +88,10 @@
 		dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice);
 
 		if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
-			for (i = slice << 5; i < (slice + 1) << 5; i += I2C_SMBUS_BLOCK_MAX)
-				if (i2c_smbus_read_i2c_block_data(client, i, data->data + i) != I2C_SMBUS_BLOCK_MAX)
+			for (i = slice << 5; i < (slice + 1) << 5; i += 32)
+				if (i2c_smbus_read_i2c_block_data(client, i,
+							32, data->data + i)
+							!= 32)
 					goto exit;
 		} else {
 			if (i2c_smbus_write_byte(client, slice << 5)) {
@@ -110,7 +112,8 @@
 	mutex_unlock(&data->update_lock);
 }
 
-static ssize_t eeprom_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t eeprom_read(struct kobject *kobj, struct bin_attribute *bin_attr,
+			   char *buf, loff_t off, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj));
 	struct eeprom_data *data = i2c_get_clientdata(client);
@@ -143,7 +146,6 @@
 	.attr = {
 		.name = "eeprom",
 		.mode = S_IRUGO,
-		.owner = THIS_MODULE,
 	},
 	.size = EEPROM_SIZE,
 	.read = eeprom_read,
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c
index 76645c1..64692f6 100644
--- a/drivers/i2c/chips/max6875.c
+++ b/drivers/i2c/chips/max6875.c
@@ -106,6 +106,7 @@
 					    I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
 			if (i2c_smbus_read_i2c_block_data(client,
 							  MAX6875_CMD_BLK_READ,
+							  SLICE_SIZE,
 							  buf) != SLICE_SIZE) {
 				goto exit_up;
 			}
@@ -125,8 +126,9 @@
 	mutex_unlock(&data->update_lock);
 }
 
-static ssize_t max6875_read(struct kobject *kobj, char *buf, loff_t off,
-			    size_t count)
+static ssize_t max6875_read(struct kobject *kobj,
+			    struct bin_attribute *bin_attr,
+			    char *buf, loff_t off, size_t count)
 {
 	struct i2c_client *client = kobj_to_i2c_client(kobj);
 	struct max6875_data *data = i2c_get_clientdata(client);
@@ -152,7 +154,6 @@
 	.attr = {
 		.name = "eeprom",
 		.mode = S_IRUGO,
-		.owner = THIS_MODULE,
 	},
 	.size = USER_EEPROM_SIZE,
 	.read = max6875_read,
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
new file mode 100644
index 0000000..3de4b19
--- /dev/null
+++ b/drivers/i2c/chips/tsl2550.c
@@ -0,0 +1,460 @@
+/*
+ *  tsl2550.c - Linux kernel modules for ambient light sensor
+ *
+ *  Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
+ *  Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#define TSL2550_DRV_NAME	"tsl2550"
+#define DRIVER_VERSION		"1.1.1"
+
+/*
+ * Defines
+ */
+
+#define TSL2550_POWER_DOWN		0x00
+#define TSL2550_POWER_UP		0x03
+#define TSL2550_STANDARD_RANGE		0x18
+#define TSL2550_EXTENDED_RANGE		0x1d
+#define TSL2550_READ_ADC0		0x43
+#define TSL2550_READ_ADC1		0x83
+
+/*
+ * Structs
+ */
+
+struct tsl2550_data {
+	struct i2c_client *client;
+	struct mutex update_lock;
+
+	unsigned int power_state : 1;
+	unsigned int operating_mode : 1;
+};
+
+/*
+ * Global data
+ */
+
+static const u8 TSL2550_MODE_RANGE[2] = {
+	TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
+};
+
+/*
+ * Management functions
+ */
+
+static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
+{
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+
+	int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
+
+	data->operating_mode = mode;
+
+	return ret;
+}
+
+static int tsl2550_set_power_state(struct i2c_client *client, int state)
+{
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+	int ret;
+
+	if (state == 0)
+		ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
+	else {
+		ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
+
+		/* On power up we should reset operating mode also... */
+		tsl2550_set_operating_mode(client, data->operating_mode);
+	}
+
+	data->power_state = state;
+
+	return ret;
+}
+
+static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
+{
+	unsigned long end;
+	int loop = 0, ret = 0;
+
+	/*
+	 * Read ADC channel waiting at most 400ms (see data sheet for further
+	 * info).
+	 * To avoid long busy wait we spin for few milliseconds then
+	 * start sleeping.
+	 */
+	end = jiffies + msecs_to_jiffies(400);
+	while (time_before(jiffies, end)) {
+		i2c_smbus_write_byte(client, cmd);
+
+		if (loop++ < 5)
+			mdelay(1);
+		else
+			msleep(1);
+
+		ret = i2c_smbus_read_byte(client);
+		if (ret < 0)
+			return ret;
+		else if (ret & 0x0080)
+			break;
+	}
+	if (!(ret & 0x80))
+		return -EIO;
+	return ret & 0x7f;	/* remove the "valid" bit */
+}
+
+/*
+ * LUX calculation
+ */
+
+#define	TSL2550_MAX_LUX		1846
+
+static const u8 ratio_lut[] = {
+	100, 100, 100, 100, 100, 100, 100, 100,
+	100, 100, 100, 100, 100, 100, 99, 99,
+	99, 99, 99, 99, 99, 99, 99, 99,
+	99, 99, 99, 98, 98, 98, 98, 98,
+	98, 98, 97, 97, 97, 97, 97, 96,
+	96, 96, 96, 95, 95, 95, 94, 94,
+	93, 93, 93, 92, 92, 91, 91, 90,
+	89, 89, 88, 87, 87, 86, 85, 84,
+	83, 82, 81, 80, 79, 78, 77, 75,
+	74, 73, 71, 69, 68, 66, 64, 62,
+	60, 58, 56, 54, 52, 49, 47, 44,
+	42, 41, 40, 40, 39, 39, 38, 38,
+	37, 37, 37, 36, 36, 36, 35, 35,
+	35, 35, 34, 34, 34, 34, 33, 33,
+	33, 33, 32, 32, 32, 32, 32, 31,
+	31, 31, 31, 31, 30, 30, 30, 30,
+	30,
+};
+
+static const u16 count_lut[] = {
+	0, 1, 2, 3, 4, 5, 6, 7,
+	8, 9, 10, 11, 12, 13, 14, 15,
+	16, 18, 20, 22, 24, 26, 28, 30,
+	32, 34, 36, 38, 40, 42, 44, 46,
+	49, 53, 57, 61, 65, 69, 73, 77,
+	81, 85, 89, 93, 97, 101, 105, 109,
+	115, 123, 131, 139, 147, 155, 163, 171,
+	179, 187, 195, 203, 211, 219, 227, 235,
+	247, 263, 279, 295, 311, 327, 343, 359,
+	375, 391, 407, 423, 439, 455, 471, 487,
+	511, 543, 575, 607, 639, 671, 703, 735,
+	767, 799, 831, 863, 895, 927, 959, 991,
+	1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
+	1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
+	2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
+	3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
+};
+
+/*
+ * This function is described into Taos TSL2550 Designer's Notebook
+ * pages 2, 3.
+ */
+static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
+{
+	unsigned int lux;
+
+	/* Look up count from channel values */
+	u16 c0 = count_lut[ch0];
+	u16 c1 = count_lut[ch1];
+
+	/*
+	 * Calculate ratio.
+	 * Note: the "128" is a scaling factor
+	 */
+	u8 r = 128;
+
+	/* Avoid division by 0 and count 1 cannot be greater than count 0 */
+	if (c0 && (c1 <= c0))
+		r = c1 * 128 / c0;
+	else
+		return -1;
+
+	/* Calculate LUX */
+	lux = ((c0 - c1) * ratio_lut[r]) / 256;
+
+	/* LUX range check */
+	return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
+}
+
+/*
+ * SysFS support
+ */
+
+static ssize_t tsl2550_show_power_state(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+	return sprintf(buf, "%u\n", data->power_state);
+}
+
+static ssize_t tsl2550_store_power_state(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	int ret;
+
+	if (val < 0 || val > 1)
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	ret = tsl2550_set_power_state(client, val);
+	mutex_unlock(&data->update_lock);
+
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
+		   tsl2550_show_power_state, tsl2550_store_power_state);
+
+static ssize_t tsl2550_show_operating_mode(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+	return sprintf(buf, "%u\n", data->operating_mode);
+}
+
+static ssize_t tsl2550_store_operating_mode(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	int ret;
+
+	if (val < 0 || val > 1)
+		return -EINVAL;
+
+	if (data->power_state == 0)
+		return -EBUSY;
+
+	mutex_lock(&data->update_lock);
+	ret = tsl2550_set_operating_mode(client, val);
+	mutex_unlock(&data->update_lock);
+
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
+		   tsl2550_show_operating_mode, tsl2550_store_operating_mode);
+
+static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
+{
+	u8 ch0, ch1;
+	int ret;
+
+	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
+	if (ret < 0)
+		return ret;
+	ch0 = ret;
+
+	mdelay(1);
+
+	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
+	if (ret < 0)
+		return ret;
+	ch1 = ret;
+
+	/* Do the job */
+	ret = tsl2550_calculate_lux(ch0, ch1);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%d\n", ret);
+}
+
+static ssize_t tsl2550_show_lux1_input(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+	int ret;
+
+	/* No LUX data if not operational */
+	if (!data->power_state)
+		return -EBUSY;
+
+	mutex_lock(&data->update_lock);
+	ret = __tsl2550_show_lux(client, buf);
+	mutex_unlock(&data->update_lock);
+
+	return ret;
+}
+
+static DEVICE_ATTR(lux1_input, S_IRUGO,
+		   tsl2550_show_lux1_input, NULL);
+
+static struct attribute *tsl2550_attributes[] = {
+	&dev_attr_power_state.attr,
+	&dev_attr_operating_mode.attr,
+	&dev_attr_lux1_input.attr,
+	NULL
+};
+
+static const struct attribute_group tsl2550_attr_group = {
+	.attrs = tsl2550_attributes,
+};
+
+/*
+ * Initialization function
+ */
+
+static int tsl2550_init_client(struct i2c_client *client)
+{
+	struct tsl2550_data *data = i2c_get_clientdata(client);
+	int err;
+
+	/*
+	 * Probe the chip. To do so we try to power up the device and then to
+	 * read back the 0x03 code
+	 */
+	err = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
+	if (err < 0)
+		return err;
+	mdelay(1);
+	if (i2c_smbus_read_byte(client) != TSL2550_POWER_UP)
+		return -ENODEV;
+	data->power_state = 1;
+
+	/* Set the default operating mode */
+	err = i2c_smbus_write_byte(client,
+				   TSL2550_MODE_RANGE[data->operating_mode]);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+/*
+ * I2C init/probing/exit functions
+ */
+
+static struct i2c_driver tsl2550_driver;
+static int __devinit tsl2550_probe(struct i2c_client *client)
+{
+	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+	struct tsl2550_data *data;
+	int *opmode, err = 0;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) {
+		err = -EIO;
+		goto exit;
+	}
+
+	data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	data->client = client;
+	i2c_set_clientdata(client, data);
+
+	/* Check platform data */
+	opmode = client->dev.platform_data;
+	if (opmode) {
+		if (*opmode < 0 || *opmode > 1) {
+			dev_err(&client->dev, "invalid operating_mode (%d)\n",
+					*opmode);
+			err = -EINVAL;
+			goto exit_kfree;
+		}
+		data->operating_mode = *opmode;
+	} else
+		data->operating_mode = 0;	/* default mode is standard */
+	dev_info(&client->dev, "%s operating mode\n",
+			data->operating_mode ? "extended" : "standard");
+
+	mutex_init(&data->update_lock);
+
+	/* Initialize the TSL2550 chip */
+	err = tsl2550_init_client(client);
+	if (err)
+		goto exit_kfree;
+
+	/* Register sysfs hooks */
+	err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
+	if (err)
+		goto exit_kfree;
+
+	dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
+
+	return 0;
+
+exit_kfree:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int __devexit tsl2550_remove(struct i2c_client *client)
+{
+	sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
+
+	/* Power down the device */
+	tsl2550_set_power_state(client, 0);
+
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+static struct i2c_driver tsl2550_driver = {
+	.driver = {
+		.name	= TSL2550_DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe	= tsl2550_probe,
+	.remove	= __devexit_p(tsl2550_remove),
+};
+
+static int __init tsl2550_init(void)
+{
+	return i2c_add_driver(&tsl2550_driver);
+}
+
+static void __exit tsl2550_exit(void)
+{
+	i2c_del_driver(&tsl2550_driver);
+}
+
+MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
+MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(tsl2550_init);
+module_exit(tsl2550_exit);
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 435925e..6971a62 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -207,6 +207,7 @@
  * i2c_new_device - instantiate an i2c device for use with a new style driver
  * @adap: the adapter managing the device
  * @info: describes one I2C device; bus_num is ignored
+ * Context: can sleep
  *
  * Create a device to work with a new style i2c driver, where binding is
  * handled through driver model probe()/remove() methods.  This call is not
@@ -255,6 +256,7 @@
 /**
  * i2c_unregister_device - reverse effect of i2c_new_device()
  * @client: value returned from i2c_new_device()
+ * Context: can sleep
  */
 void i2c_unregister_device(struct i2c_client *client)
 {
@@ -379,6 +381,7 @@
 /**
  * i2c_add_adapter - declare i2c adapter, use dynamic bus number
  * @adapter: the adapter to add
+ * Context: can sleep
  *
  * This routine is used to declare an I2C adapter when its bus number
  * doesn't matter.  Examples: for I2C adapters dynamically added by
@@ -416,6 +419,7 @@
 /**
  * i2c_add_numbered_adapter - declare i2c adapter, use static bus number
  * @adap: the adapter to register (with adap->nr initialized)
+ * Context: can sleep
  *
  * This routine is used to declare an I2C adapter when its bus number
  * matters.  Example: for I2C adapters from system-on-chip CPUs, or
@@ -463,6 +467,14 @@
 }
 EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
 
+/**
+ * i2c_del_adapter - unregister I2C adapter
+ * @adap: the adapter being unregistered
+ * Context: can sleep
+ *
+ * This unregisters an I2C adapter which was previously registered
+ * by @i2c_add_adapter or @i2c_add_numbered_adapter.
+ */
 int i2c_del_adapter(struct i2c_adapter *adap)
 {
 	struct list_head  *item, *_n;
@@ -598,6 +610,7 @@
 /**
  * i2c_del_driver - unregister I2C driver
  * @driver: the driver being unregistered
+ * Context: can sleep
  */
 void i2c_del_driver(struct i2c_driver *driver)
 {
@@ -1331,10 +1344,14 @@
 EXPORT_SYMBOL(i2c_smbus_write_block_data);
 
 /* Returns the number of read bytes */
-s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *values)
+s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command,
+				  u8 length, u8 *values)
 {
 	union i2c_smbus_data data;
 
+	if (length > I2C_SMBUS_BLOCK_MAX)
+		length = I2C_SMBUS_BLOCK_MAX;
+	data.block[0] = length;
 	if (i2c_smbus_xfer(client->adapter,client->addr,client->flags,
 	                      I2C_SMBUS_READ,command,
 	                      I2C_SMBUS_I2C_BLOCK_DATA,&data))
@@ -1455,7 +1472,7 @@
 		break;
 	case I2C_SMBUS_I2C_BLOCK_DATA:
 		if (read_write == I2C_SMBUS_READ) {
-			msg[1].len = I2C_SMBUS_BLOCK_MAX;
+			msg[1].len = data->block[0];
 		} else {
 			msg[0].len = data->block[0] + 1;
 			if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) {
@@ -1511,9 +1528,7 @@
 				data->word = msgbuf1[0] | (msgbuf1[1] << 8);
 				break;
 			case I2C_SMBUS_I2C_BLOCK_DATA:
-				/* fixed at 32 for now */
-				data->block[0] = I2C_SMBUS_BLOCK_MAX;
-				for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
+				for (i = 0; i < data->block[0]; i++)
 					data->block[i+1] = msgbuf1[i];
 				break;
 			case I2C_SMBUS_BLOCK_DATA:
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index e7a7097..64eee95 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -283,6 +283,7 @@
 		    (data_arg.size != I2C_SMBUS_WORD_DATA) &&
 		    (data_arg.size != I2C_SMBUS_PROC_CALL) &&
 		    (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
+		    (data_arg.size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
 		    (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
 		    (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
 			dev_dbg(&client->adapter->dev,
@@ -329,10 +330,18 @@
 
 		if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
 		    (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
+		    (data_arg.size == I2C_SMBUS_I2C_BLOCK_DATA) ||
 		    (data_arg.read_write == I2C_SMBUS_WRITE)) {
 			if (copy_from_user(&temp, data_arg.data, datasize))
 				return -EFAULT;
 		}
+		if (data_arg.size == I2C_SMBUS_I2C_BLOCK_BROKEN) {
+			/* Convert old I2C block commands to the new
+			   convention. This preserves binary compatibility. */
+			data_arg.size = I2C_SMBUS_I2C_BLOCK_DATA;
+			if (data_arg.read_write == I2C_SMBUS_READ)
+				temp.block[0] = I2C_SMBUS_BLOCK_MAX;
+		}
 		res = i2c_smbus_xfer(client->adapter,client->addr,client->flags,
 		      data_arg.read_write,
 		      data_arg.command,data_arg.size,&temp);
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index 7f4c0a5..8f2db8d 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -719,74 +719,25 @@
 	device_timer.function = hd_times_out;
 	blk_queue_hardsect_size(hd_queue, 512);
 
-#ifdef __i386__
 	if (!NR_HD) {
-		extern struct drive_info drive_info;
-		unsigned char *BIOS = (unsigned char *) &drive_info;
-		unsigned long flags;
-		int cmos_disks;
-
-		for (drive=0 ; drive<2 ; drive++) {
-			hd_info[drive].cyl = *(unsigned short *) BIOS;
-			hd_info[drive].head = *(2+BIOS);
-			hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
-			hd_info[drive].ctl = *(8+BIOS);
-			hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
-			hd_info[drive].sect = *(14+BIOS);
-#ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
-			if (hd_info[drive].cyl && NR_HD == drive)
-				NR_HD++;
-#endif
-			BIOS += 16;
-		}
-
-	/*
-		We query CMOS about hard disks : it could be that 
-		we have a SCSI/ESDI/etc controller that is BIOS
-		compatible with ST-506, and thus showing up in our
-		BIOS table, but not register compatible, and therefore
-		not present in CMOS.
-
-		Furthermore, we will assume that our ST-506 drives
-		<if any> are the primary drives in the system, and 
-		the ones reflected as drive 1 or 2.
-
-		The first drive is stored in the high nibble of CMOS
-		byte 0x12, the second in the low nibble.  This will be
-		either a 4 bit drive type or 0xf indicating use byte 0x19 
-		for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
-
-		Needless to say, a non-zero value means we have 
-		an AT controller hard disk for that drive.
-
-		Currently the rtc_lock is a bit academic since this
-		driver is non-modular, but someday... ?         Paul G.
-	*/
-
-		spin_lock_irqsave(&rtc_lock, flags);
-		cmos_disks = CMOS_READ(0x12);
-		spin_unlock_irqrestore(&rtc_lock, flags);
-
-		if (cmos_disks & 0xf0) {
-			if (cmos_disks & 0x0f)
-				NR_HD = 2;
-			else
-				NR_HD = 1;
-		}
-	}
-#endif /* __i386__ */
-#ifdef __arm__
-	if (!NR_HD) {
-		/* We don't know anything about the drive.  This means
+		/*
+		 * We don't know anything about the drive.  This means
 		 * that you *MUST* specify the drive parameters to the
 		 * kernel yourself.
+		 *
+		 * If we were on an i386, we used to read this info from
+		 * the BIOS or CMOS.  This doesn't work all that well,
+		 * since this assumes that this is a primary or secondary
+		 * drive, and if we're using this legacy driver, it's
+		 * probably an auxilliary controller added to recover
+		 * legacy data off an ST-506 drive.  Either way, it's
+		 * definitely safest to have the user explicitly specify
+		 * the information.
 		 */
 		printk("hd: no drives specified - use hd=cyl,head,sectors"
 			" on kernel command line\n");
-	}
-#endif
-	if (!NR_HD)
 		goto out;
+	}
 
 	for (drive=0 ; drive < NR_HD ; drive++) {
 		struct gendisk *disk = alloc_disk(64);
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 08c299e..bf9b992 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -479,7 +479,6 @@
 
 		element->attr.attr.name  = element->name;
 		element->attr.attr.mode  = S_IRUGO;
-		element->attr.attr.owner = THIS_MODULE;
 		element->attr.show       = show;
 		element->index		 = i;
 
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 27a6883..1317bdd 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -119,7 +119,6 @@
 		.attr	= {							\
 			.name	= __stringify(_name),				\
 			.mode	= _mode,					\
-			.owner	= THIS_MODULE,					\
 		},								\
 		.show	= psmouse_attr_show_helper,				\
 		.store	= psmouse_attr_set_helper,				\
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index 11ced17..4fcb245 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -212,7 +212,6 @@
 	list_add(&new_ct->link, &wf_controls);
 
 	new_ct->attr.attr.name = new_ct->name;
-	new_ct->attr.attr.owner = THIS_MODULE;
 	new_ct->attr.attr.mode = 0644;
 	new_ct->attr.show = wf_show_control;
 	new_ct->attr.store = wf_store_control;
@@ -325,7 +324,6 @@
 	list_add(&new_sr->link, &wf_sensors);
 
 	new_sr->attr.attr.name = new_sr->name;
-	new_sr->attr.attr.owner = THIS_MODULE;
 	new_sr->attr.attr.mode = 0444;
 	new_sr->attr.show = wf_show_sensor;
 	new_sr->attr.store = NULL;
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index 1043b39..351982b 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -67,26 +67,6 @@
 	.detach_client	= wf_sat_detach,
 };
 
-/*
- * XXX i2c_smbus_read_i2c_block_data doesn't pass the requested
- * length down to the low-level driver, so we use this, which
- * works well enough with the SMU i2c driver code...
- */
-static int sat_read_block(struct i2c_client *client, u8 command,
-			  u8 *values, int len)
-{
-	union i2c_smbus_data data;
-	int err;
-
-	data.block[0] = len;
-	err = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
-			     I2C_SMBUS_READ, command, I2C_SMBUS_I2C_BLOCK_DATA,
-			     &data);
-	if (!err)
-		memcpy(values, data.block, len);
-	return err;
-}
-
 struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
 						  unsigned int *size)
 {
@@ -124,8 +104,8 @@
 		return NULL;
 
 	for (i = 0; i < len; i += 4) {
-		err = sat_read_block(&sat->i2c, 0xa, data, 4);
-		if (err) {
+		err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0xa, 4, data);
+		if (err < 0) {
 			printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n",
 			       err);
 			goto fail;
@@ -157,8 +137,8 @@
 {
 	int err;
 
-	err = sat_read_block(&sat->i2c, 0x3f, sat->cache, 16);
-	if (err)
+	err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0x3f, 16, sat->cache);
+	if (err < 0)
 		return err;
 	sat->last_read = jiffies;
 #ifdef LOTSA_DEBUG
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index 4f9060a..7798f590e 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -737,8 +737,7 @@
 	struct device_attribute dev_attr_##_name = {			\
 		.attr = {						\
 			.name = __stringify(_name),			\
-			.mode = 0,					\
-			.owner = THIS_MODULE },				\
+			.mode = 0 },					\
 		.show   = NULL,						\
 		.store  = NULL,						\
 	}
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c
index 41e901f..932a415 100644
--- a/drivers/misc/msi-laptop.c
+++ b/drivers/misc/msi-laptop.c
@@ -23,6 +23,8 @@
  * msi-laptop.c - MSI S270 laptop support. This laptop is sold under
  * various brands, including "Cytron/TCM/Medion/Tchibo MD96100".
  *
+ * Driver also supports S271, S420 models.
+ *
  * This driver exports a few files in /sys/devices/platform/msi-laptop-pf/:
  *
  *   lcd_level - Screen brightness: contains a single integer in the
@@ -281,25 +283,56 @@
 
 /* Initialization */
 
+static int dmi_check_cb(struct dmi_system_id *id)
+{
+        printk("msi-laptop: Identified laptop model '%s'.\n", id->ident);
+        return 0;
+}
+
 static struct dmi_system_id __initdata msi_dmi_table[] = {
 	{
 		.ident = "MSI S270",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"),
-		}
+			DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
+			DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT'L CO.,LTD")
+		},
+		.callback = dmi_check_cb
+	},
+	{
+		.ident = "MSI S271",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MS-1058"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "0581"),
+			DMI_MATCH(DMI_BOARD_NAME, "MS-1058")
+		},
+		.callback = dmi_check_cb
+	},
+	{
+		.ident = "MSI S420",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MS-1412"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
+			DMI_MATCH(DMI_BOARD_NAME, "MS-1412")
+		},
+		.callback = dmi_check_cb
 	},
 	{
 		.ident = "Medion MD96100",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"),
-		}
+			DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
+			DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT'L CO.,LTD")
+		},
+		.callback = dmi_check_cb
 	},
 	{ }
 };
 
-
 static int __init msi_init(void)
 {
 	int ret;
@@ -394,3 +427,8 @@
 MODULE_DESCRIPTION("MSI Laptop Support");
 MODULE_VERSION(MSI_DRIVER_VERSION);
 MODULE_LICENSE("GPL");
+
+MODULE_ALIAS("dmi:*:svnMICRO-STARINT'LCO.,LTD:pnMS-1013:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
+MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1058:pvr0581:rvnMSI:rnMS-1058:*:ct10:*");
+MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
+MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*");
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index da1a22c..ab18343 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -990,7 +990,7 @@
 				if (skb != NULL) {
 					skb_reserve(skb, 2);	/* 16 byte alignment */
 					skb_put(skb,totlen);
-					eth_copy_and_sum(skb, (char *) p->base+(unsigned long) rbd->buffer,totlen,0);
+					skb_copy_to_linear_data(skb, (char *) p->base+(unsigned long) rbd->buffer,totlen);
 					skb->protocol = eth_type_trans(skb, dev);
 					netif_rx(skb);
 					dev->last_rx = jiffies;
diff --git a/drivers/net/7990.c b/drivers/net/7990.c
index 0877fc3..e89ace1 100644
--- a/drivers/net/7990.c
+++ b/drivers/net/7990.c
@@ -333,9 +333,9 @@
 
                         skb_reserve (skb, 2);           /* 16 byte align */
                         skb_put (skb, len);             /* make room */
-                        eth_copy_and_sum(skb,
+                        skb_copy_to_linear_data(skb,
                                          (unsigned char *)&(ib->rx_buf [lp->rx_new][0]),
-                                         len, 0);
+                                         len);
                         skb->protocol = eth_type_trans (skb, dev);
 			netif_rx (skb);
 			dev->last_rx = jiffies;
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 77457c7..327eaa7 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -2014,7 +2014,7 @@
 #if RX_BUF_IDX == 3
 			wrap_copy(skb, rx_ring, ring_offset+4, pkt_size);
 #else
-			eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0);
+			skb_copy_to_linear_data (skb, &rx_ring[ring_offset + 4], pkt_size);
 #endif
 			skb_put (skb, pkt_size);
 
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index b941c74..ba314ad 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -25,6 +25,14 @@
 # that for each of the symbols.
 if NETDEVICES
 
+config NETDEVICES_MULTIQUEUE
+	bool "Netdevice multiple hardware queue support"
+	---help---
+	  Say Y here if you want to allow the network stack to use multiple
+	  hardware TX queues on an ethernet device.
+
+	  Most people will say N here.
+
 config IFB
 	tristate "Intermediate Functional Block support"
 	depends on NET_CLS_ACT
@@ -877,7 +885,7 @@
 
 config DM9000
 	tristate "DM9000 support"
-	depends on ARM || MIPS
+	depends on ARM || BLACKFIN || MIPS
 	select CRC32
 	select MII
 	---help---
@@ -2784,6 +2792,19 @@
 	  which can lead to bad results if the ATM peer loses state and
 	  changes its encapsulation unilaterally.
 
+config PPPOL2TP
+	tristate "PPP over L2TP (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && PPP
+	help
+	  Support for PPP-over-L2TP socket family. L2TP is a protocol
+	  used by ISPs and enterprises to tunnel PPP traffic over UDP
+	  tunnels. L2TP is replacing PPTP for VPN uses.
+
+	  This kernel component handles only L2TP data packets: a
+	  userland daemon handles L2TP the control protocol (tunnel
+	  and session setup). One such daemon is OpenL2TP
+	  (http://openl2tp.sourceforge.net/).
+
 config SLIP
 	tristate "SLIP (serial line) support"
 	---help---
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1bbcbed..a2241e6 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -121,6 +121,7 @@
 obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
 obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
 obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
+obj-$(CONFIG_PPPOL2TP) += pppox.o pppol2tp.o
 
 obj-$(CONFIG_SLIP) += slip.o
 obj-$(CONFIG_SLHC) += slhc.o
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index 81d5a37..a45de69 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -322,9 +322,9 @@
 
 			skb_reserve (skb, 2);		/* 16 byte align */
 			skb_put (skb, len);		/* make room */
-			eth_copy_and_sum(skb,
+			skb_copy_to_linear_data(skb,
 					 (unsigned char *)&(ib->rx_buf [lp->rx_new][0]),
-					 len, 0);
+					 len);
 			skb->protocol = eth_type_trans (skb, dev);
 			netif_rx (skb);
 			dev->last_rx = jiffies;
diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c
index a241ae7..bc5a38a 100644
--- a/drivers/net/ariadne.c
+++ b/drivers/net/ariadne.c
@@ -746,7 +746,7 @@
 
 	    skb_reserve(skb,2);		/* 16 byte align */
 	    skb_put(skb,pkt_len);	/* Make room */
-	    eth_copy_and_sum(skb, (char *)priv->rx_buff[entry], pkt_len,0);
+	    skb_copy_to_linear_data(skb, (char *)priv->rx_buff[entry], pkt_len);
 	    skb->protocol=eth_type_trans(skb,dev);
 #if 0
 	    printk(KERN_DEBUG "RX pkt type 0x%04x from ",
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 2438c5b..f6ece1d 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -258,7 +258,7 @@
 			skb_reserve(skb, 2);
 			dma_sync_single(NULL, ep->descs->rdesc[entry].buf_addr,
 						length, DMA_FROM_DEVICE);
-			eth_copy_and_sum(skb, ep->rx_buf[entry], length, 0);
+			skb_copy_to_linear_data(skb, ep->rx_buf[entry], length);
 			skb_put(skb, length);
 			skb->protocol = eth_type_trans(skb, dev);
 
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index c27cfce..e86b369 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -1205,8 +1205,8 @@
 				continue;
 			}
 			skb_reserve(skb, 2);	/* 16 byte IP header align */
-			eth_copy_and_sum(skb,
-				(unsigned char *)pDB->vaddr, frmlen, 0);
+			skb_copy_to_linear_data(skb,
+				(unsigned char *)pDB->vaddr, frmlen);
 			skb_put(skb, frmlen);
 			skb->protocol = eth_type_trans(skb, dev);
 			netif_rx(skb);	/* pass the packet to upper layers */
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 23958f7..02e994b 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -40,7 +40,6 @@
 #define BCM_VLAN 1
 #endif
 #include <net/ip.h>
-#include <net/tcp.h>
 #include <net/checksum.h>
 #include <linux/workqueue.h>
 #include <linux/crc32.h>
@@ -54,8 +53,8 @@
 
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.5.11"
-#define DRV_MODULE_RELDATE	"June 4, 2007"
+#define DRV_MODULE_VERSION	"1.6.2"
+#define DRV_MODULE_RELDATE	"July 6, 2007"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -550,6 +549,9 @@
 {
 	u32 fw_link_status = 0;
 
+	if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+		return;
+
 	if (bp->link_up) {
 		u32 bmsr;
 
@@ -601,12 +603,21 @@
 	REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status);
 }
 
+static char *
+bnx2_xceiver_str(struct bnx2 *bp)
+{
+	return ((bp->phy_port == PORT_FIBRE) ? "SerDes" :
+		((bp->phy_flags & PHY_SERDES_FLAG) ? "Remote Copper" :
+		 "Copper"));
+}
+
 static void
 bnx2_report_link(struct bnx2 *bp)
 {
 	if (bp->link_up) {
 		netif_carrier_on(bp->dev);
-		printk(KERN_INFO PFX "%s NIC Link is Up, ", bp->dev->name);
+		printk(KERN_INFO PFX "%s NIC %s Link is Up, ", bp->dev->name,
+		       bnx2_xceiver_str(bp));
 
 		printk("%d Mbps ", bp->line_speed);
 
@@ -630,7 +641,8 @@
 	}
 	else {
 		netif_carrier_off(bp->dev);
-		printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
+		printk(KERN_ERR PFX "%s NIC %s Link is Down\n", bp->dev->name,
+		       bnx2_xceiver_str(bp));
 	}
 
 	bnx2_report_fw_link(bp);
@@ -1100,6 +1112,9 @@
 		return 0;
 	}
 
+	if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+		return 0;
+
 	link_up = bp->link_up;
 
 	bnx2_enable_bmsr1(bp);
@@ -1210,12 +1225,74 @@
 	return adv;
 }
 
+static int bnx2_fw_sync(struct bnx2 *, u32, int);
+
 static int
-bnx2_setup_serdes_phy(struct bnx2 *bp)
+bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
+{
+	u32 speed_arg = 0, pause_adv;
+
+	pause_adv = bnx2_phy_get_pause_adv(bp);
+
+	if (bp->autoneg & AUTONEG_SPEED) {
+		speed_arg |= BNX2_NETLINK_SET_LINK_ENABLE_AUTONEG;
+		if (bp->advertising & ADVERTISED_10baseT_Half)
+			speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_10HALF;
+		if (bp->advertising & ADVERTISED_10baseT_Full)
+			speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_10FULL;
+		if (bp->advertising & ADVERTISED_100baseT_Half)
+			speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_100HALF;
+		if (bp->advertising & ADVERTISED_100baseT_Full)
+			speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_100FULL;
+		if (bp->advertising & ADVERTISED_1000baseT_Full)
+			speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_1GFULL;
+		if (bp->advertising & ADVERTISED_2500baseX_Full)
+			speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_2G5FULL;
+	} else {
+		if (bp->req_line_speed == SPEED_2500)
+			speed_arg = BNX2_NETLINK_SET_LINK_SPEED_2G5FULL;
+		else if (bp->req_line_speed == SPEED_1000)
+			speed_arg = BNX2_NETLINK_SET_LINK_SPEED_1GFULL;
+		else if (bp->req_line_speed == SPEED_100) {
+			if (bp->req_duplex == DUPLEX_FULL)
+				speed_arg = BNX2_NETLINK_SET_LINK_SPEED_100FULL;
+			else
+				speed_arg = BNX2_NETLINK_SET_LINK_SPEED_100HALF;
+		} else if (bp->req_line_speed == SPEED_10) {
+			if (bp->req_duplex == DUPLEX_FULL)
+				speed_arg = BNX2_NETLINK_SET_LINK_SPEED_10FULL;
+			else
+				speed_arg = BNX2_NETLINK_SET_LINK_SPEED_10HALF;
+		}
+	}
+
+	if (pause_adv & (ADVERTISE_1000XPAUSE | ADVERTISE_PAUSE_CAP))
+		speed_arg |= BNX2_NETLINK_SET_LINK_FC_SYM_PAUSE;
+	if (pause_adv & (ADVERTISE_1000XPSE_ASYM | ADVERTISE_1000XPSE_ASYM))
+		speed_arg |= BNX2_NETLINK_SET_LINK_FC_ASYM_PAUSE;
+
+	if (port == PORT_TP)
+		speed_arg |= BNX2_NETLINK_SET_LINK_PHY_APP_REMOTE |
+			     BNX2_NETLINK_SET_LINK_ETH_AT_WIRESPEED;
+
+	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB_ARG0, speed_arg);
+
+	spin_unlock_bh(&bp->phy_lock);
+	bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_CMD_SET_LINK, 0);
+	spin_lock_bh(&bp->phy_lock);
+
+	return 0;
+}
+
+static int
+bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
 {
 	u32 adv, bmcr;
 	u32 new_adv = 0;
 
+	if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+		return (bnx2_setup_remote_phy(bp, port));
+
 	if (!(bp->autoneg & AUTONEG_SPEED)) {
 		u32 new_bmcr;
 		int force_link_down = 0;
@@ -1323,7 +1400,9 @@
 }
 
 #define ETHTOOL_ALL_FIBRE_SPEED						\
-	(ADVERTISED_1000baseT_Full)
+	(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) ?			\
+		(ADVERTISED_2500baseX_Full | ADVERTISED_1000baseT_Full) :\
+		(ADVERTISED_1000baseT_Full)
 
 #define ETHTOOL_ALL_COPPER_SPEED					\
 	(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |		\
@@ -1335,6 +1414,188 @@
 
 #define PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL)
 
+static void
+bnx2_set_default_remote_link(struct bnx2 *bp)
+{
+	u32 link;
+
+	if (bp->phy_port == PORT_TP)
+		link = REG_RD_IND(bp, bp->shmem_base + BNX2_RPHY_COPPER_LINK);
+	else
+		link = REG_RD_IND(bp, bp->shmem_base + BNX2_RPHY_SERDES_LINK);
+
+	if (link & BNX2_NETLINK_SET_LINK_ENABLE_AUTONEG) {
+		bp->req_line_speed = 0;
+		bp->autoneg |= AUTONEG_SPEED;
+		bp->advertising = ADVERTISED_Autoneg;
+		if (link & BNX2_NETLINK_SET_LINK_SPEED_10HALF)
+			bp->advertising |= ADVERTISED_10baseT_Half;
+		if (link & BNX2_NETLINK_SET_LINK_SPEED_10FULL)
+			bp->advertising |= ADVERTISED_10baseT_Full;
+		if (link & BNX2_NETLINK_SET_LINK_SPEED_100HALF)
+			bp->advertising |= ADVERTISED_100baseT_Half;
+		if (link & BNX2_NETLINK_SET_LINK_SPEED_100FULL)
+			bp->advertising |= ADVERTISED_100baseT_Full;
+		if (link & BNX2_NETLINK_SET_LINK_SPEED_1GFULL)
+			bp->advertising |= ADVERTISED_1000baseT_Full;
+		if (link & BNX2_NETLINK_SET_LINK_SPEED_2G5FULL)
+			bp->advertising |= ADVERTISED_2500baseX_Full;
+	} else {
+		bp->autoneg = 0;
+		bp->advertising = 0;
+		bp->req_duplex = DUPLEX_FULL;
+		if (link & BNX2_NETLINK_SET_LINK_SPEED_10) {
+			bp->req_line_speed = SPEED_10;
+			if (link & BNX2_NETLINK_SET_LINK_SPEED_10HALF)
+				bp->req_duplex = DUPLEX_HALF;
+		}
+		if (link & BNX2_NETLINK_SET_LINK_SPEED_100) {
+			bp->req_line_speed = SPEED_100;
+			if (link & BNX2_NETLINK_SET_LINK_SPEED_100HALF)
+				bp->req_duplex = DUPLEX_HALF;
+		}
+		if (link & BNX2_NETLINK_SET_LINK_SPEED_1GFULL)
+			bp->req_line_speed = SPEED_1000;
+		if (link & BNX2_NETLINK_SET_LINK_SPEED_2G5FULL)
+			bp->req_line_speed = SPEED_2500;
+	}
+}
+
+static void
+bnx2_set_default_link(struct bnx2 *bp)
+{
+	if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+		return bnx2_set_default_remote_link(bp);
+
+	bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL;
+	bp->req_line_speed = 0;
+	if (bp->phy_flags & PHY_SERDES_FLAG) {
+		u32 reg;
+
+		bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
+
+		reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
+		reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
+		if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
+			bp->autoneg = 0;
+			bp->req_line_speed = bp->line_speed = SPEED_1000;
+			bp->req_duplex = DUPLEX_FULL;
+		}
+	} else
+		bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg;
+}
+
+static void
+bnx2_send_heart_beat(struct bnx2 *bp)
+{
+	u32 msg;
+	u32 addr;
+
+	spin_lock(&bp->indirect_lock);
+	msg = (u32) (++bp->fw_drv_pulse_wr_seq & BNX2_DRV_PULSE_SEQ_MASK);
+	addr = bp->shmem_base + BNX2_DRV_PULSE_MB;
+	REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, addr);
+	REG_WR(bp, BNX2_PCICFG_REG_WINDOW, msg);
+	spin_unlock(&bp->indirect_lock);
+}
+
+static void
+bnx2_remote_phy_event(struct bnx2 *bp)
+{
+	u32 msg;
+	u8 link_up = bp->link_up;
+	u8 old_port;
+
+	msg = REG_RD_IND(bp, bp->shmem_base + BNX2_LINK_STATUS);
+
+	if (msg & BNX2_LINK_STATUS_HEART_BEAT_EXPIRED)
+		bnx2_send_heart_beat(bp);
+
+	msg &= ~BNX2_LINK_STATUS_HEART_BEAT_EXPIRED;
+
+	if ((msg & BNX2_LINK_STATUS_LINK_UP) == BNX2_LINK_STATUS_LINK_DOWN)
+		bp->link_up = 0;
+	else {
+		u32 speed;
+
+		bp->link_up = 1;
+		speed = msg & BNX2_LINK_STATUS_SPEED_MASK;
+		bp->duplex = DUPLEX_FULL;
+		switch (speed) {
+			case BNX2_LINK_STATUS_10HALF:
+				bp->duplex = DUPLEX_HALF;
+			case BNX2_LINK_STATUS_10FULL:
+				bp->line_speed = SPEED_10;
+				break;
+			case BNX2_LINK_STATUS_100HALF:
+				bp->duplex = DUPLEX_HALF;
+			case BNX2_LINK_STATUS_100BASE_T4:
+			case BNX2_LINK_STATUS_100FULL:
+				bp->line_speed = SPEED_100;
+				break;
+			case BNX2_LINK_STATUS_1000HALF:
+				bp->duplex = DUPLEX_HALF;
+			case BNX2_LINK_STATUS_1000FULL:
+				bp->line_speed = SPEED_1000;
+				break;
+			case BNX2_LINK_STATUS_2500HALF:
+				bp->duplex = DUPLEX_HALF;
+			case BNX2_LINK_STATUS_2500FULL:
+				bp->line_speed = SPEED_2500;
+				break;
+			default:
+				bp->line_speed = 0;
+				break;
+		}
+
+		spin_lock(&bp->phy_lock);
+		bp->flow_ctrl = 0;
+		if ((bp->autoneg & (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) !=
+		    (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) {
+			if (bp->duplex == DUPLEX_FULL)
+				bp->flow_ctrl = bp->req_flow_ctrl;
+		} else {
+			if (msg & BNX2_LINK_STATUS_TX_FC_ENABLED)
+				bp->flow_ctrl |= FLOW_CTRL_TX;
+			if (msg & BNX2_LINK_STATUS_RX_FC_ENABLED)
+				bp->flow_ctrl |= FLOW_CTRL_RX;
+		}
+
+		old_port = bp->phy_port;
+		if (msg & BNX2_LINK_STATUS_SERDES_LINK)
+			bp->phy_port = PORT_FIBRE;
+		else
+			bp->phy_port = PORT_TP;
+
+		if (old_port != bp->phy_port)
+			bnx2_set_default_link(bp);
+
+		spin_unlock(&bp->phy_lock);
+	}
+	if (bp->link_up != link_up)
+		bnx2_report_link(bp);
+
+	bnx2_set_mac_link(bp);
+}
+
+static int
+bnx2_set_remote_link(struct bnx2 *bp)
+{
+	u32 evt_code;
+
+	evt_code = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_EVT_CODE_MB);
+	switch (evt_code) {
+		case BNX2_FW_EVT_CODE_LINK_EVENT:
+			bnx2_remote_phy_event(bp);
+			break;
+		case BNX2_FW_EVT_CODE_SW_TIMER_EXPIRATION_EVENT:
+		default:
+			bnx2_send_heart_beat(bp);
+			break;
+	}
+	return 0;
+}
+
 static int
 bnx2_setup_copper_phy(struct bnx2 *bp)
 {
@@ -1433,13 +1694,13 @@
 }
 
 static int
-bnx2_setup_phy(struct bnx2 *bp)
+bnx2_setup_phy(struct bnx2 *bp, u8 port)
 {
 	if (bp->loopback == MAC_LOOPBACK)
 		return 0;
 
 	if (bp->phy_flags & PHY_SERDES_FLAG) {
-		return (bnx2_setup_serdes_phy(bp));
+		return (bnx2_setup_serdes_phy(bp, port));
 	}
 	else {
 		return (bnx2_setup_copper_phy(bp));
@@ -1659,6 +1920,9 @@
 
         REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
 
+	if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+		goto setup_phy;
+
 	bnx2_read_phy(bp, MII_PHYSID1, &val);
 	bp->phy_id = val << 16;
 	bnx2_read_phy(bp, MII_PHYSID2, &val);
@@ -1676,7 +1940,9 @@
 		rc = bnx2_init_copper_phy(bp);
 	}
 
-	bnx2_setup_phy(bp);
+setup_phy:
+	if (!rc)
+		rc = bnx2_setup_phy(bp, bp->phy_port);
 
 	return rc;
 }
@@ -1984,6 +2250,9 @@
 		bnx2_set_link(bp);
 		spin_unlock(&bp->phy_lock);
 	}
+	if (bnx2_phy_event_is_set(bp, STATUS_ATTN_BITS_TIMER_ABORT))
+		bnx2_set_remote_link(bp);
+
 }
 
 static void
@@ -2297,6 +2566,7 @@
 {
 	struct net_device *dev = dev_instance;
 	struct bnx2 *bp = netdev_priv(dev);
+	struct status_block *sblk = bp->status_blk;
 
 	/* When using INTx, it is possible for the interrupt to arrive
 	 * at the CPU before the status block posted prior to the
@@ -2304,7 +2574,7 @@
 	 * When using MSI, the MSI message will always complete after
 	 * the status block write.
 	 */
-	if ((bp->status_blk->status_idx == bp->last_status_idx) &&
+	if ((sblk->status_idx == bp->last_status_idx) &&
 	    (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) &
 	     BNX2_PCICFG_MISC_STATUS_INTA_VALUE))
 		return IRQ_NONE;
@@ -2313,16 +2583,25 @@
 		BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
 		BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
 
+	/* Read back to deassert IRQ immediately to avoid too many
+	 * spurious interrupts.
+	 */
+	REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD);
+
 	/* Return here if interrupt is shared and is disabled. */
 	if (unlikely(atomic_read(&bp->intr_sem) != 0))
 		return IRQ_HANDLED;
 
-	netif_rx_schedule(dev);
+	if (netif_rx_schedule_prep(dev)) {
+		bp->last_status_idx = sblk->status_idx;
+		__netif_rx_schedule(dev);
+	}
 
 	return IRQ_HANDLED;
 }
 
-#define STATUS_ATTN_EVENTS	STATUS_ATTN_BITS_LINK_STATE
+#define STATUS_ATTN_EVENTS	(STATUS_ATTN_BITS_LINK_STATE | \
+				 STATUS_ATTN_BITS_TIMER_ABORT)
 
 static inline int
 bnx2_has_work(struct bnx2 *bp)
@@ -3562,6 +3841,36 @@
 	return rc;
 }
 
+static void
+bnx2_init_remote_phy(struct bnx2 *bp)
+{
+	u32 val;
+
+	bp->phy_flags &= ~REMOTE_PHY_CAP_FLAG;
+	if (!(bp->phy_flags & PHY_SERDES_FLAG))
+		return;
+
+	val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_CAP_MB);
+	if ((val & BNX2_FW_CAP_SIGNATURE_MASK) != BNX2_FW_CAP_SIGNATURE)
+		return;
+
+	if (val & BNX2_FW_CAP_REMOTE_PHY_CAPABLE) {
+		if (netif_running(bp->dev)) {
+			val = BNX2_DRV_ACK_CAP_SIGNATURE |
+			      BNX2_FW_CAP_REMOTE_PHY_CAPABLE;
+			REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_ACK_CAP_MB,
+				   val);
+		}
+		bp->phy_flags |= REMOTE_PHY_CAP_FLAG;
+
+		val = REG_RD_IND(bp, bp->shmem_base + BNX2_LINK_STATUS);
+		if (val & BNX2_LINK_STATUS_SERDES_LINK)
+			bp->phy_port = PORT_FIBRE;
+		else
+			bp->phy_port = PORT_TP;
+	}
+}
+
 static int
 bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
 {
@@ -3642,6 +3951,12 @@
 	if (rc)
 		return rc;
 
+	spin_lock_bh(&bp->phy_lock);
+	bnx2_init_remote_phy(bp);
+	if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+		bnx2_set_default_remote_link(bp);
+	spin_unlock_bh(&bp->phy_lock);
+
 	if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
 		/* Adjust the voltage regular to two steps lower.  The default
 		 * of this register is 0x0000000e. */
@@ -3826,7 +4141,7 @@
 	rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
 			  0);
 
-	REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 0x5ffffff);
+	REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_DEFAULT);
 	REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS);
 
 	udelay(20);
@@ -4069,8 +4384,8 @@
 
 	spin_lock_bh(&bp->phy_lock);
 	bnx2_init_phy(bp);
-	spin_unlock_bh(&bp->phy_lock);
 	bnx2_set_link(bp);
+	spin_unlock_bh(&bp->phy_lock);
 	return 0;
 }
 
@@ -4600,6 +4915,9 @@
 static void
 bnx2_5708_serdes_timer(struct bnx2 *bp)
 {
+	if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+		return;
+
 	if ((bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) == 0) {
 		bp->serdes_an_pending = 0;
 		return;
@@ -4631,7 +4949,6 @@
 bnx2_timer(unsigned long data)
 {
 	struct bnx2 *bp = (struct bnx2 *) data;
-	u32 msg;
 
 	if (!netif_running(bp->dev))
 		return;
@@ -4639,8 +4956,7 @@
 	if (atomic_read(&bp->intr_sem) != 0)
 		goto bnx2_restart_timer;
 
-	msg = (u32) ++bp->fw_drv_pulse_wr_seq;
-	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg);
+	bnx2_send_heart_beat(bp);
 
 	bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT);
 
@@ -5083,17 +5399,25 @@
 bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct bnx2 *bp = netdev_priv(dev);
+	int support_serdes = 0, support_copper = 0;
 
 	cmd->supported = SUPPORTED_Autoneg;
-	if (bp->phy_flags & PHY_SERDES_FLAG) {
+	if (bp->phy_flags & REMOTE_PHY_CAP_FLAG) {
+		support_serdes = 1;
+		support_copper = 1;
+	} else if (bp->phy_port == PORT_FIBRE)
+		support_serdes = 1;
+	else
+		support_copper = 1;
+
+	if (support_serdes) {
 		cmd->supported |= SUPPORTED_1000baseT_Full |
 			SUPPORTED_FIBRE;
 		if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG)
 			cmd->supported |= SUPPORTED_2500baseX_Full;
 
-		cmd->port = PORT_FIBRE;
 	}
-	else {
+	if (support_copper) {
 		cmd->supported |= SUPPORTED_10baseT_Half |
 			SUPPORTED_10baseT_Full |
 			SUPPORTED_100baseT_Half |
@@ -5101,9 +5425,10 @@
 			SUPPORTED_1000baseT_Full |
 			SUPPORTED_TP;
 
-		cmd->port = PORT_TP;
 	}
 
+	spin_lock_bh(&bp->phy_lock);
+	cmd->port = bp->phy_port;
 	cmd->advertising = bp->advertising;
 
 	if (bp->autoneg & AUTONEG_SPEED) {
@@ -5121,6 +5446,7 @@
 		cmd->speed = -1;
 		cmd->duplex = -1;
 	}
+	spin_unlock_bh(&bp->phy_lock);
 
 	cmd->transceiver = XCVR_INTERNAL;
 	cmd->phy_address = bp->phy_addr;
@@ -5136,6 +5462,15 @@
 	u8 req_duplex = bp->req_duplex;
 	u16 req_line_speed = bp->req_line_speed;
 	u32 advertising = bp->advertising;
+	int err = -EINVAL;
+
+	spin_lock_bh(&bp->phy_lock);
+
+	if (cmd->port != PORT_TP && cmd->port != PORT_FIBRE)
+		goto err_out_unlock;
+
+	if (cmd->port != bp->phy_port && !(bp->phy_flags & REMOTE_PHY_CAP_FLAG))
+		goto err_out_unlock;
 
 	if (cmd->autoneg == AUTONEG_ENABLE) {
 		autoneg |= AUTONEG_SPEED;
@@ -5148,44 +5483,41 @@
 			(cmd->advertising == ADVERTISED_100baseT_Half) ||
 			(cmd->advertising == ADVERTISED_100baseT_Full)) {
 
-			if (bp->phy_flags & PHY_SERDES_FLAG)
-				return -EINVAL;
+			if (cmd->port == PORT_FIBRE)
+				goto err_out_unlock;
 
 			advertising = cmd->advertising;
 
 		} else if (cmd->advertising == ADVERTISED_2500baseX_Full) {
-			if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG))
-				return -EINVAL;
-		} else if (cmd->advertising == ADVERTISED_1000baseT_Full) {
+			if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) ||
+			    (cmd->port == PORT_TP))
+				goto err_out_unlock;
+		} else if (cmd->advertising == ADVERTISED_1000baseT_Full)
 			advertising = cmd->advertising;
-		}
-		else if (cmd->advertising == ADVERTISED_1000baseT_Half) {
-			return -EINVAL;
-		}
+		else if (cmd->advertising == ADVERTISED_1000baseT_Half)
+			goto err_out_unlock;
 		else {
-			if (bp->phy_flags & PHY_SERDES_FLAG) {
+			if (cmd->port == PORT_FIBRE)
 				advertising = ETHTOOL_ALL_FIBRE_SPEED;
-			}
-			else {
+			else
 				advertising = ETHTOOL_ALL_COPPER_SPEED;
-			}
 		}
 		advertising |= ADVERTISED_Autoneg;
 	}
 	else {
-		if (bp->phy_flags & PHY_SERDES_FLAG) {
+		if (cmd->port == PORT_FIBRE) {
 			if ((cmd->speed != SPEED_1000 &&
 			     cmd->speed != SPEED_2500) ||
 			    (cmd->duplex != DUPLEX_FULL))
-				return -EINVAL;
+				goto err_out_unlock;
 
 			if (cmd->speed == SPEED_2500 &&
 			    !(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG))
-				return -EINVAL;
+				goto err_out_unlock;
 		}
-		else if (cmd->speed == SPEED_1000) {
-			return -EINVAL;
-		}
+		else if (cmd->speed == SPEED_1000 || cmd->speed == SPEED_2500)
+			goto err_out_unlock;
+
 		autoneg &= ~AUTONEG_SPEED;
 		req_line_speed = cmd->speed;
 		req_duplex = cmd->duplex;
@@ -5197,13 +5529,12 @@
 	bp->req_line_speed = req_line_speed;
 	bp->req_duplex = req_duplex;
 
-	spin_lock_bh(&bp->phy_lock);
+	err = bnx2_setup_phy(bp, cmd->port);
 
-	bnx2_setup_phy(bp);
-
+err_out_unlock:
 	spin_unlock_bh(&bp->phy_lock);
 
-	return 0;
+	return err;
 }
 
 static void
@@ -5214,11 +5545,7 @@
 	strcpy(info->driver, DRV_MODULE_NAME);
 	strcpy(info->version, DRV_MODULE_VERSION);
 	strcpy(info->bus_info, pci_name(bp->pdev));
-	info->fw_version[0] = ((bp->fw_ver & 0xff000000) >> 24) + '0';
-	info->fw_version[2] = ((bp->fw_ver & 0xff0000) >> 16) + '0';
-	info->fw_version[4] = ((bp->fw_ver & 0xff00) >> 8) + '0';
-	info->fw_version[1] = info->fw_version[3] = '.';
-	info->fw_version[5] = 0;
+	strcpy(info->fw_version, bp->fw_version);
 }
 
 #define BNX2_REGDUMP_LEN		(32 * 1024)
@@ -5330,6 +5657,14 @@
 
 	spin_lock_bh(&bp->phy_lock);
 
+	if (bp->phy_flags & REMOTE_PHY_CAP_FLAG) {
+		int rc;
+
+		rc = bnx2_setup_remote_phy(bp, bp->phy_port);
+		spin_unlock_bh(&bp->phy_lock);
+		return rc;
+	}
+
 	/* Force a link down visible on the other side */
 	if (bp->phy_flags & PHY_SERDES_FLAG) {
 		bnx2_write_phy(bp, bp->mii_bmcr, BMCR_LOOPBACK);
@@ -5543,7 +5878,7 @@
 
 	spin_lock_bh(&bp->phy_lock);
 
-	bnx2_setup_phy(bp);
+	bnx2_setup_phy(bp, bp->phy_port);
 
 	spin_unlock_bh(&bp->phy_lock);
 
@@ -5939,6 +6274,9 @@
 	case SIOCGMIIREG: {
 		u32 mii_regval;
 
+		if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+			return -EOPNOTSUPP;
+
 		if (!netif_running(dev))
 			return -EAGAIN;
 
@@ -5955,6 +6293,9 @@
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 
+		if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+			return -EOPNOTSUPP;
+
 		if (!netif_running(dev))
 			return -EAGAIN;
 
@@ -6116,7 +6457,7 @@
 {
 	struct bnx2 *bp;
 	unsigned long mem_len;
-	int rc;
+	int rc, i, j;
 	u32 reg;
 	u64 dma_mask, persist_dma_mask;
 
@@ -6273,7 +6614,35 @@
 		goto err_out_unmap;
 	}
 
-	bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
+	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
+	for (i = 0, j = 0; i < 3; i++) {
+		u8 num, k, skip0;
+
+		num = (u8) (reg >> (24 - (i * 8)));
+		for (k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
+			if (num >= k || !skip0 || k == 1) {
+				bp->fw_version[j++] = (num / k) + '0';
+				skip0 = 0;
+			}
+		}
+		if (i != 2)
+			bp->fw_version[j++] = '.';
+	}
+	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_BC_STATE_CONDITION);
+	reg &= BNX2_CONDITION_MFW_RUN_MASK;
+	if (reg != BNX2_CONDITION_MFW_RUN_UNKNOWN &&
+	    reg != BNX2_CONDITION_MFW_RUN_NONE) {
+		int i;
+		u32 addr = REG_RD_IND(bp, bp->shmem_base + BNX2_MFW_VER_PTR);
+
+		bp->fw_version[j++] = ' ';
+		for (i = 0; i < 3; i++) {
+			reg = REG_RD_IND(bp, addr + i * 4);
+			reg = swab32(reg);
+			memcpy(&bp->fw_version[j], &reg, 4);
+			j += 4;
+		}
+	}
 
 	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER);
 	bp->mac_addr[0] = (u8) (reg >> 8);
@@ -6315,7 +6684,9 @@
 	else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT)
 		bp->phy_flags |= PHY_SERDES_FLAG;
 
+	bp->phy_port = PORT_TP;
 	if (bp->phy_flags & PHY_SERDES_FLAG) {
+		bp->phy_port = PORT_FIBRE;
 		bp->flags |= NO_WOL_FLAG;
 		if (CHIP_NUM(bp) != CHIP_NUM_5706) {
 			bp->phy_addr = 2;
@@ -6324,6 +6695,8 @@
 			if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
 				bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
 		}
+		bnx2_init_remote_phy(bp);
+
 	} else if (CHIP_NUM(bp) == CHIP_NUM_5706 ||
 		   CHIP_NUM(bp) == CHIP_NUM_5708)
 		bp->phy_flags |= PHY_CRC_FIX_FLAG;
@@ -6373,23 +6746,7 @@
 		}
 	}
 
-	bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL;
-	bp->req_line_speed = 0;
-	if (bp->phy_flags & PHY_SERDES_FLAG) {
-		bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
-
-		reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
-		reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
-		if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
-			bp->autoneg = 0;
-			bp->req_line_speed = bp->line_speed = SPEED_1000;
-			bp->req_duplex = DUPLEX_FULL;
-		}
-	}
-	else {
-		bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg;
-	}
-
+	bnx2_set_default_link(bp);
 	bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX;
 
 	init_timer(&bp->timer);
@@ -6489,10 +6846,10 @@
 	memcpy(dev->perm_addr, bp->mac_addr, 6);
 	bp->name = board_info[ent->driver_data].name;
 
+	dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
 	if (CHIP_NUM(bp) == CHIP_NUM_5709)
-		dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
-	else
-		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+		dev->features |= NETIF_F_IPV6_CSUM;
+
 #ifdef BCM_VLAN
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 #endif
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 49a5de2..d8cd1af 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -6338,6 +6338,8 @@
 
 #define RX_COPY_THRESH			92
 
+#define BNX2_MISC_ENABLE_DEFAULT	0x7ffffff
+
 #define DMA_READ_CHANS	5
 #define DMA_WRITE_CHANS	3
 
@@ -6537,6 +6539,7 @@
 #define PHY_INT_MODE_AUTO_POLLING_FLAG	0x100
 #define PHY_INT_MODE_LINK_READY_FLAG	0x200
 #define PHY_DIS_EARLY_DAC_FLAG		0x400
+#define REMOTE_PHY_CAP_FLAG		0x800
 
 	u32			mii_bmcr;
 	u32			mii_bmsr;
@@ -6625,6 +6628,7 @@
 	u16			req_line_speed;
 	u8			req_duplex;
 
+	u8			phy_port;
 	u8			link_up;
 
 	u16			line_speed;
@@ -6656,7 +6660,7 @@
 
 	u32			shmem_base;
 
-	u32			fw_ver;
+	char			fw_version[32];
 
 	int			pm_cap;
 	int			pcix_cap;
@@ -6770,7 +6774,7 @@
  * the firmware has timed out, the driver will assume there is no firmware
  * running and there won't be any firmware-driver synchronization during a
  * driver reset. */
-#define FW_ACK_TIME_OUT_MS                  100
+#define FW_ACK_TIME_OUT_MS                  1000
 
 
 #define BNX2_DRV_RESET_SIGNATURE		0x00000000
@@ -6788,6 +6792,7 @@
 #define BNX2_DRV_MSG_CODE_DIAG			 0x07000000
 #define BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL	 0x09000000
 #define BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN		 0x0b000000
+#define BNX2_DRV_MSG_CODE_CMD_SET_LINK		 0x10000000
 
 #define BNX2_DRV_MSG_DATA			 0x00ff0000
 #define BNX2_DRV_MSG_DATA_WAIT0			 0x00010000
@@ -6836,6 +6841,7 @@
 #define BNX2_LINK_STATUS_SERDES_LINK		 (1<<20)
 #define BNX2_LINK_STATUS_PARTNER_AD_2500FULL	 (1<<21)
 #define BNX2_LINK_STATUS_PARTNER_AD_2500HALF	 (1<<22)
+#define BNX2_LINK_STATUS_HEART_BEAT_EXPIRED	 (1<<31)
 
 #define BNX2_DRV_PULSE_MB			0x00000010
 #define BNX2_DRV_PULSE_SEQ_MASK			 0x00007fff
@@ -6845,6 +6851,30 @@
  * This is used for debugging. */
 #define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE	 0x00080000
 
+#define BNX2_DRV_MB_ARG0			0x00000014
+#define BNX2_NETLINK_SET_LINK_SPEED_10HALF	 (1<<0)
+#define BNX2_NETLINK_SET_LINK_SPEED_10FULL	 (1<<1)
+#define BNX2_NETLINK_SET_LINK_SPEED_10		 \
+	(BNX2_NETLINK_SET_LINK_SPEED_10HALF |	 \
+	 BNX2_NETLINK_SET_LINK_SPEED_10FULL)
+#define BNX2_NETLINK_SET_LINK_SPEED_100HALF	 (1<<2)
+#define BNX2_NETLINK_SET_LINK_SPEED_100FULL	 (1<<3)
+#define BNX2_NETLINK_SET_LINK_SPEED_100		 \
+	(BNX2_NETLINK_SET_LINK_SPEED_100HALF |	 \
+	 BNX2_NETLINK_SET_LINK_SPEED_100FULL)
+#define BNX2_NETLINK_SET_LINK_SPEED_1GHALF	 (1<<4)
+#define BNX2_NETLINK_SET_LINK_SPEED_1GFULL	 (1<<5)
+#define BNX2_NETLINK_SET_LINK_SPEED_2G5HALF	 (1<<6)
+#define BNX2_NETLINK_SET_LINK_SPEED_2G5FULL	 (1<<7)
+#define BNX2_NETLINK_SET_LINK_SPEED_10GHALF	 (1<<8)
+#define BNX2_NETLINK_SET_LINK_SPEED_10GFULL	 (1<<9)
+#define BNX2_NETLINK_SET_LINK_ENABLE_AUTONEG	 (1<<10)
+#define BNX2_NETLINK_SET_LINK_PHY_APP_REMOTE	 (1<<11)
+#define BNX2_NETLINK_SET_LINK_FC_SYM_PAUSE	 (1<<12)
+#define BNX2_NETLINK_SET_LINK_FC_ASYM_PAUSE	 (1<<13)
+#define BNX2_NETLINK_SET_LINK_ETH_AT_WIRESPEED	 (1<<14)
+#define BNX2_NETLINK_SET_LINK_PHY_RESET		 (1<<15)
+
 #define BNX2_DEV_INFO_SIGNATURE			0x00000020
 #define BNX2_DEV_INFO_SIGNATURE_MAGIC		 0x44564900
 #define BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK	 0xffffff00
@@ -7006,6 +7036,8 @@
 #define BNX2_PORT_FEATURE_MBA_VLAN_TAG_MASK	 0xffff
 #define BNX2_PORT_FEATURE_MBA_VLAN_ENABLE	 0x10000
 
+#define BNX2_MFW_VER_PTR			0x00000014c
+
 #define BNX2_BC_STATE_RESET_TYPE		0x000001c0
 #define BNX2_BC_STATE_RESET_TYPE_SIG		 0x00005254
 #define BNX2_BC_STATE_RESET_TYPE_SIG_MASK	 0x0000ffff
@@ -7059,12 +7091,42 @@
 #define BNX2_BC_STATE_ERR_NO_RXP		 (BNX2_BC_STATE_SIGN | 0x0600)
 #define BNX2_BC_STATE_ERR_TOO_MANY_RBUF		 (BNX2_BC_STATE_SIGN | 0x0700)
 
+#define BNX2_BC_STATE_CONDITION			0x000001c8
+#define BNX2_CONDITION_MFW_RUN_UNKNOWN		 0x00000000
+#define BNX2_CONDITION_MFW_RUN_IPMI		 0x00002000
+#define BNX2_CONDITION_MFW_RUN_UMP		 0x00004000
+#define BNX2_CONDITION_MFW_RUN_NCSI		 0x00006000
+#define BNX2_CONDITION_MFW_RUN_NONE		 0x0000e000
+#define BNX2_CONDITION_MFW_RUN_MASK		 0x0000e000
+
 #define BNX2_BC_STATE_DEBUG_CMD			0x1dc
 #define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE	 0x42440000
 #define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE_MASK	 0xffff0000
 #define BNX2_BC_STATE_BC_DBG_CMD_LOOP_CNT_MASK	 0xffff
 #define BNX2_BC_STATE_BC_DBG_CMD_LOOP_INFINITE	 0xffff
 
+#define BNX2_FW_EVT_CODE_MB			0x354
+#define BNX2_FW_EVT_CODE_SW_TIMER_EXPIRATION_EVENT 0x00000000
+#define BNX2_FW_EVT_CODE_LINK_EVENT		 0x00000001
+
+#define BNX2_DRV_ACK_CAP_MB			0x364
+#define BNX2_DRV_ACK_CAP_SIGNATURE		 0x35450000
+#define BNX2_CAPABILITY_SIGNATURE_MASK		 0xFFFF0000
+
+#define BNX2_FW_CAP_MB				0x368
+#define BNX2_FW_CAP_SIGNATURE			 0xaa550000
+#define BNX2_FW_ACK_DRV_SIGNATURE		 0x52500000
+#define BNX2_FW_CAP_SIGNATURE_MASK		 0xffff0000
+#define BNX2_FW_CAP_REMOTE_PHY_CAPABLE		 0x00000001
+#define BNX2_FW_CAP_REMOTE_PHY_PRESENT		 0x00000002
+
+#define BNX2_RPHY_SIGNATURE			0x36c
+#define BNX2_RPHY_LOAD_SIGNATURE		 0x5a5a5a5a
+
+#define BNX2_RPHY_FLAGS				0x370
+#define BNX2_RPHY_SERDES_LINK			0x374
+#define BNX2_RPHY_COPPER_LINK			0x378
+
 #define HOST_VIEW_SHMEM_BASE			0x167c00
 
 #endif
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index fab4fc9f..04e3710 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -865,9 +865,9 @@
 							    PCI_DMA_FROMDEVICE);
 				/* 16 byte align the IP header */
 				skb_reserve (skb, 2);
-				eth_copy_and_sum (skb,
+				skb_copy_to_linear_data (skb,
 						  np->rx_skbuff[entry]->data,
-						  pkt_len, 0);
+						  pkt_len);
 				skb_put (skb, pkt_len);
 				pci_dma_sync_single_for_device(np->pdev,
 				  			       desc->fraginfo &
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 264fa0e..c3de81b 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -104,6 +104,18 @@
 #define PRINTK(args...)   printk(KERN_DEBUG args)
 #endif
 
+#ifdef CONFIG_BLACKFIN
+#define readsb	insb
+#define readsw	insw
+#define readsl	insl
+#define writesb	outsb
+#define writesw	outsw
+#define writesl	outsl
+#define DM9000_IRQ_FLAGS	(IRQF_SHARED | IRQF_TRIGGER_HIGH)
+#else
+#define DM9000_IRQ_FLAGS	IRQF_SHARED
+#endif
+
 /*
  * Transmit timeout, default 5 seconds.
  */
@@ -431,6 +443,9 @@
 		db->io_addr = (void __iomem *)base;
 		db->io_data = (void __iomem *)(base + 4);
 
+		/* ensure at least we have a default set of IO routines */
+		dm9000_set_io(db, 2);
+
 	} else {
 		db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 		db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -614,7 +629,7 @@
 
 	PRINTK2("entering dm9000_open\n");
 
-	if (request_irq(dev->irq, &dm9000_interrupt, IRQF_SHARED, dev->name, dev))
+	if (request_irq(dev->irq, &dm9000_interrupt, DM9000_IRQ_FLAGS, dev->name, dev))
 		return -EAGAIN;
 
 	/* Initialize DM9000 board */
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 60673bc..756a6bc 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -34,11 +34,12 @@
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/moduleparam.h>
+#include <linux/rtnetlink.h>
+#include <net/rtnetlink.h>
 
 static int numdummies = 1;
 
 static int dummy_xmit(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *dummy_get_stats(struct net_device *dev);
 
 static int dummy_set_address(struct net_device *dev, void *p)
 {
@@ -56,13 +57,13 @@
 {
 }
 
-static void __init dummy_setup(struct net_device *dev)
+static void dummy_setup(struct net_device *dev)
 {
 	/* Initialize the device structure. */
-	dev->get_stats = dummy_get_stats;
 	dev->hard_start_xmit = dummy_xmit;
 	dev->set_multicast_list = set_multicast_list;
 	dev->set_mac_address = dummy_set_address;
+	dev->destructor = free_netdev;
 
 	/* Fill in device structure with ethernet-generic values. */
 	ether_setup(dev);
@@ -76,77 +77,80 @@
 
 static int dummy_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct net_device_stats *stats = netdev_priv(dev);
-
-	stats->tx_packets++;
-	stats->tx_bytes+=skb->len;
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += skb->len;
 
 	dev_kfree_skb(skb);
 	return 0;
 }
 
-static struct net_device_stats *dummy_get_stats(struct net_device *dev)
+static int dummy_validate(struct nlattr *tb[], struct nlattr *data[])
 {
-	return netdev_priv(dev);
+	if (tb[IFLA_ADDRESS]) {
+		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+			return -EINVAL;
+		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
+			return -EADDRNOTAVAIL;
+	}
+	return 0;
 }
 
-static struct net_device **dummies;
+static struct rtnl_link_ops dummy_link_ops __read_mostly = {
+	.kind		= "dummy",
+	.setup		= dummy_setup,
+	.validate	= dummy_validate,
+};
 
 /* Number of dummy devices to be set up by this module. */
 module_param(numdummies, int, 0);
 MODULE_PARM_DESC(numdummies, "Number of dummy pseudo devices");
 
-static int __init dummy_init_one(int index)
+static int __init dummy_init_one(void)
 {
 	struct net_device *dev_dummy;
 	int err;
 
-	dev_dummy = alloc_netdev(sizeof(struct net_device_stats),
-				 "dummy%d", dummy_setup);
-
+	dev_dummy = alloc_netdev(0, "dummy%d", dummy_setup);
 	if (!dev_dummy)
 		return -ENOMEM;
 
-	if ((err = register_netdev(dev_dummy))) {
-		free_netdev(dev_dummy);
-		dev_dummy = NULL;
-	} else {
-		dummies[index] = dev_dummy;
-	}
+	err = dev_alloc_name(dev_dummy, dev_dummy->name);
+	if (err < 0)
+		goto err;
 
+	dev_dummy->rtnl_link_ops = &dummy_link_ops;
+	err = register_netdevice(dev_dummy);
+	if (err < 0)
+		goto err;
+	return 0;
+
+err:
+	free_netdev(dev_dummy);
 	return err;
 }
 
-static void dummy_free_one(int index)
-{
-	unregister_netdev(dummies[index]);
-	free_netdev(dummies[index]);
-}
-
 static int __init dummy_init_module(void)
 {
 	int i, err = 0;
-	dummies = kmalloc(numdummies * sizeof(void *), GFP_KERNEL);
-	if (!dummies)
-		return -ENOMEM;
+
+	rtnl_lock();
+	err = __rtnl_link_register(&dummy_link_ops);
+
 	for (i = 0; i < numdummies && !err; i++)
-		err = dummy_init_one(i);
-	if (err) {
-		i--;
-		while (--i >= 0)
-			dummy_free_one(i);
-	}
+		err = dummy_init_one();
+	if (err < 0)
+		__rtnl_link_unregister(&dummy_link_ops);
+	rtnl_unlock();
+
 	return err;
 }
 
 static void __exit dummy_cleanup_module(void)
 {
-	int i;
-	for (i = 0; i < numdummies; i++)
-		dummy_free_one(i);
-	kfree(dummies);
+	rtnl_link_unregister(&dummy_link_ops);
 }
 
 module_init(dummy_init_module);
 module_exit(dummy_cleanup_module);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_RTNL_LINK("dummy");
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index 98003419..9afa47e 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -1801,7 +1801,7 @@
 
 #if 1 || USE_IP_CSUM
 				/* Packet is in one chunk -- we can copy + cksum. */
-				eth_copy_and_sum(skb, sp->rx_skbuff[entry]->data, pkt_len, 0);
+				skb_copy_to_linear_data(skb, sp->rx_skbuff[entry]->data, pkt_len);
 				skb_put(skb, pkt_len);
 #else
 				skb_copy_from_linear_data(sp->rx_skbuff[entry],
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 5e51794..1197784 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -1201,7 +1201,7 @@
 							    ep->rx_ring[entry].bufaddr,
 							    ep->rx_buf_sz,
 							    PCI_DMA_FROMDEVICE);
-				eth_copy_and_sum(skb, ep->rx_skbuff[entry]->data, pkt_len, 0);
+				skb_copy_to_linear_data(skb, ep->rx_skbuff[entry]->data, pkt_len);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(ep->pci_dev,
 							       ep->rx_ring[entry].bufaddr,
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index abe9b08..ff9f177 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -1727,8 +1727,8 @@
 				/* Call copy + cksum if available. */
 
 #if ! defined(__alpha__)
-				eth_copy_and_sum(skb,
-					np->cur_rx->skbuff->data, pkt_len, 0);
+				skb_copy_to_linear_data(skb,
+					np->cur_rx->skbuff->data, pkt_len);
 				skb_put(skb, pkt_len);
 #else
 				memcpy(skb_put(skb, pkt_len),
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 255b091..03023dd 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -648,7 +648,7 @@
 		fep->stats.rx_dropped++;
 	} else {
 		skb_put(skb,pkt_len-4);	/* Make room */
-		eth_copy_and_sum(skb, data, pkt_len-4, 0);
+		skb_copy_to_linear_data(skb, data, pkt_len-4);
 		skb->protocol=eth_type_trans(skb,dev);
 		netif_rx(skb);
 	}
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 2521b11..15254dc 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -1575,8 +1575,8 @@
 							    PCI_DMA_FROMDEVICE);
 				/* Call copy + cksum if available. */
 #if 1 || USE_IP_COPYSUM
-				eth_copy_and_sum(skb,
-					hmp->rx_skbuff[entry]->data, pkt_len, 0);
+				skb_copy_to_linear_data(skb,
+					hmp->rx_skbuff[entry]->data, pkt_len);
 				skb_put(skb, pkt_len);
 #else
 				memcpy(skb_put(skb, pkt_len), hmp->rx_ring_dma
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 6ec3d50..d96eb72 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -1337,7 +1337,7 @@
 
 #define ATTR(_name, _mode)      \
         struct attribute veth_##_name##_attr = {               \
-        .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE \
+        .name = __stringify(_name), .mode = _mode, \
         };
 
 static ATTR(active, 0644);
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 07b4c0d..f5c3598 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -136,13 +136,14 @@
 
 }
 
-static void __init ifb_setup(struct net_device *dev)
+static void ifb_setup(struct net_device *dev)
 {
 	/* Initialize the device structure. */
 	dev->get_stats = ifb_get_stats;
 	dev->hard_start_xmit = ifb_xmit;
 	dev->open = &ifb_open;
 	dev->stop = &ifb_close;
+	dev->destructor = free_netdev;
 
 	/* Fill in device structure with ethernet-generic values. */
 	ether_setup(dev);
@@ -197,12 +198,6 @@
 	return stats;
 }
 
-static struct net_device **ifbs;
-
-/* Number of ifb devices to be set up by this module. */
-module_param(numifbs, int, 0);
-MODULE_PARM_DESC(numifbs, "Number of ifb devices");
-
 static int ifb_close(struct net_device *dev)
 {
 	struct ifb_private *dp = netdev_priv(dev);
@@ -226,6 +221,28 @@
 	return 0;
 }
 
+static int ifb_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+	if (tb[IFLA_ADDRESS]) {
+		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+			return -EINVAL;
+		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
+			return -EADDRNOTAVAIL;
+	}
+	return 0;
+}
+
+static struct rtnl_link_ops ifb_link_ops __read_mostly = {
+	.kind		= "ifb",
+	.priv_size	= sizeof(struct ifb_private),
+	.setup		= ifb_setup,
+	.validate	= ifb_validate,
+};
+
+/* Number of ifb devices to be set up by this module. */
+module_param(numifbs, int, 0);
+MODULE_PARM_DESC(numifbs, "Number of ifb devices");
+
 static int __init ifb_init_one(int index)
 {
 	struct net_device *dev_ifb;
@@ -237,49 +254,44 @@
 	if (!dev_ifb)
 		return -ENOMEM;
 
-	if ((err = register_netdev(dev_ifb))) {
-		free_netdev(dev_ifb);
-		dev_ifb = NULL;
-	} else {
-		ifbs[index] = dev_ifb;
-	}
+	err = dev_alloc_name(dev_ifb, dev_ifb->name);
+	if (err < 0)
+		goto err;
 
+	dev_ifb->rtnl_link_ops = &ifb_link_ops;
+	err = register_netdevice(dev_ifb);
+	if (err < 0)
+		goto err;
+	return 0;
+
+err:
+	free_netdev(dev_ifb);
 	return err;
 }
 
-static void ifb_free_one(int index)
-{
-	unregister_netdev(ifbs[index]);
-	free_netdev(ifbs[index]);
-}
-
 static int __init ifb_init_module(void)
 {
-	int i, err = 0;
-	ifbs = kmalloc(numifbs * sizeof(void *), GFP_KERNEL);
-	if (!ifbs)
-		return -ENOMEM;
+	int i, err;
+
+	rtnl_lock();
+	err = __rtnl_link_register(&ifb_link_ops);
+
 	for (i = 0; i < numifbs && !err; i++)
 		err = ifb_init_one(i);
-	if (err) {
-		i--;
-		while (--i >= 0)
-			ifb_free_one(i);
-	}
+	if (err)
+		__rtnl_link_unregister(&ifb_link_ops);
+	rtnl_unlock();
 
 	return err;
 }
 
 static void __exit ifb_cleanup_module(void)
 {
-	int i;
-
-	for (i = 0; i < numifbs; i++)
-		ifb_free_one(i);
-	kfree(ifbs);
+	rtnl_link_unregister(&ifb_link_ops);
 }
 
 module_init(ifb_init_module);
 module_exit(ifb_cleanup_module);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jamal Hadi Salim");
+MODULE_ALIAS_RTNL_LINK("ifb");
diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c
index 2174291..bdd5c97 100644
--- a/drivers/net/irda/kingsun-sir.c
+++ b/drivers/net/irda/kingsun-sir.c
@@ -4,7 +4,7 @@
 * Version:       0.1.1
 * Description:   Irda KingSun/DonShine USB Dongle
 * Status:        Experimental
-* Author:        Alex Villac�s Lasso <a_villacis@palosanto.com>
+* Author:        Alex Villacís Lasso <a_villacis@palosanto.com>
 *
 *  	Based on stir4200 and mcs7780 drivers, with (strange?) differences
 *
@@ -652,6 +652,6 @@
 }
 module_exit(kingsun_cleanup);
 
-MODULE_AUTHOR("Alex Villac�s Lasso <a_villacis@palosanto.com>");
+MODULE_AUTHOR("Alex Villacís Lasso <a_villacis@palosanto.com>");
 MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun/DonShine");
 MODULE_LICENSE("GPL");
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index bf78ef1..0538ca9 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -44,6 +44,7 @@
 #include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/mutex.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 
@@ -1660,8 +1661,8 @@
 	idev = ndev->priv;
 
 	spin_lock_init(&idev->lock);
-	init_MUTEX(&idev->sem);
-	down(&idev->sem);
+	mutex_init(&idev->mtx);
+	mutex_lock(&idev->mtx);
 	idev->pdev = pdev;
 
 	if (vlsi_irda_init(ndev) < 0)
@@ -1689,12 +1690,12 @@
 	IRDA_MESSAGE("%s: registered device %s\n", drivername, ndev->name);
 
 	pci_set_drvdata(pdev, ndev);
-	up(&idev->sem);
+	mutex_unlock(&idev->mtx);
 
 	return 0;
 
 out_freedev:
-	up(&idev->sem);
+	mutex_unlock(&idev->mtx);
 	free_netdev(ndev);
 out_disable:
 	pci_disable_device(pdev);
@@ -1716,12 +1717,12 @@
 	unregister_netdev(ndev);
 
 	idev = ndev->priv;
-	down(&idev->sem);
+	mutex_lock(&idev->mtx);
 	if (idev->proc_entry) {
 		remove_proc_entry(ndev->name, vlsi_proc_root);
 		idev->proc_entry = NULL;
 	}
-	up(&idev->sem);
+	mutex_unlock(&idev->mtx);
 
 	free_netdev(ndev);
 
@@ -1751,7 +1752,7 @@
 		return 0;
 	}
 	idev = ndev->priv;	
-	down(&idev->sem);
+	mutex_lock(&idev->mtx);
 	if (pdev->current_state != 0) {			/* already suspended */
 		if (state.event > pdev->current_state) {	/* simply go deeper */
 			pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -1759,7 +1760,7 @@
 		}
 		else
 			IRDA_ERROR("%s - %s: invalid suspend request %u -> %u\n", __FUNCTION__, pci_name(pdev), pdev->current_state, state.event);
-		up(&idev->sem);
+		mutex_unlock(&idev->mtx);
 		return 0;
 	}
 
@@ -1775,7 +1776,7 @@
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 	pdev->current_state = state.event;
 	idev->resume_ok = 1;
-	up(&idev->sem);
+	mutex_unlock(&idev->mtx);
 	return 0;
 }
 
@@ -1790,9 +1791,9 @@
 		return 0;
 	}
 	idev = ndev->priv;	
-	down(&idev->sem);
+	mutex_lock(&idev->mtx);
 	if (pdev->current_state == 0) {
-		up(&idev->sem);
+		mutex_unlock(&idev->mtx);
 		IRDA_WARNING("%s - %s: already resumed\n",
 			     __FUNCTION__, pci_name(pdev));
 		return 0;
@@ -1814,7 +1815,7 @@
 		 * device and independently resume_ok should catch any garbage config.
 		 */
 		IRDA_WARNING("%s - hm, nothing to resume?\n", __FUNCTION__);
-		up(&idev->sem);
+		mutex_unlock(&idev->mtx);
 		return 0;
 	}
 
@@ -1824,7 +1825,7 @@
 		netif_device_attach(ndev);
 	}
 	idev->resume_ok = 0;
-	up(&idev->sem);
+	mutex_unlock(&idev->mtx);
 	return 0;
 }
 
diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h
index 2d3b773..ca12a60 100644
--- a/drivers/net/irda/vlsi_ir.h
+++ b/drivers/net/irda/vlsi_ir.h
@@ -728,7 +728,7 @@
 	struct timeval		last_rx;
 
 	spinlock_t		lock;
-	struct semaphore	sem;
+	struct mutex		mtx;
 
 	u8			resume_ok;	
 	struct proc_dir_entry	*proc_entry;
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index d5f694f..d9ce1ae 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -111,7 +111,7 @@
 		skb = dev_alloc_skb(desc->pkt_length + 2);
 		if (likely(skb != NULL)) {
 			skb_reserve(skb, 2);
-			eth_copy_and_sum(skb, buf, desc->pkt_length, 0);
+			skb_copy_to_linear_data(skb, buf, desc->pkt_length);
 			skb_put(skb, desc->pkt_length);
 			skb->protocol = eth_type_trans(skb, nds[desc->channel]);
 
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index 0fe96c8..a2f37e5 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -1186,9 +1186,9 @@
 				}
 				skb_reserve(skb,2);	/* 16 byte align */
 				skb_put(skb,pkt_len);	/* Make room */
-				eth_copy_and_sum(skb,
+				skb_copy_to_linear_data(skb,
 					(unsigned char *)isa_bus_to_virt((lp->rx_ring[entry].base & 0x00ffffff)),
-					pkt_len,0);
+					pkt_len);
 				skb->protocol=eth_type_trans(skb,dev);
 				netif_rx(skb);
 				dev->last_rx = jiffies;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 460a0871..3450051 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -2357,8 +2357,8 @@
 					np->rx_dma[entry],
 					buflen,
 					PCI_DMA_FROMDEVICE);
-				eth_copy_and_sum(skb,
-					np->rx_skbuff[entry]->data, pkt_len, 0);
+				skb_copy_to_linear_data(skb,
+					np->rx_skbuff[entry]->data, pkt_len);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(np->pci_dev,
 					np->rx_dma[entry],
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index 8dbd6d1..5e7999d 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -936,7 +936,7 @@
 					{
 						skb_reserve(skb,2);
 						skb_put(skb,totlen);
-						eth_copy_and_sum(skb,(char *) p->base+(unsigned long) rbd->buffer,totlen,0);
+						skb_copy_to_linear_data(skb,(char *) p->base+(unsigned long) rbd->buffer,totlen);
 						skb->protocol=eth_type_trans(skb,dev);
 						netif_rx(skb);
 						dev->last_rx = jiffies;
diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
index 3818edf..4ef5fe3 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ni65.c
@@ -1096,7 +1096,7 @@
 #ifdef RCV_VIA_SKB
 				if( (unsigned long) (skb->data + R_BUF_SIZE) > 0x1000000) {
 					skb_put(skb,len);
-					eth_copy_and_sum(skb, (unsigned char *)(p->recv_skb[p->rmdnum]->data),len,0);
+					skb_copy_to_linear_data(skb, (unsigned char *)(p->recv_skb[p->rmdnum]->data),len);
 				}
 				else {
 					struct sk_buff *skb1 = p->recv_skb[p->rmdnum];
@@ -1108,7 +1108,7 @@
 				}
 #else
 				skb_put(skb,len);
-				eth_copy_and_sum(skb, (unsigned char *) p->recvbounce[p->rmdnum],len,0);
+				skb_copy_to_linear_data(skb, (unsigned char *) p->recvbounce[p->rmdnum],len);
 #endif
 				p->stats.rx_packets++;
 				p->stats.rx_bytes += len;
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index df8998b..3cdbe118 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -1567,7 +1567,7 @@
 		if (skb) {
 			skb_reserve (skb, 2);	/* 16 byte align the IP fields. */
 
-			eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0);
+			skb_copy_to_linear_data (skb, &rx_ring[ring_offset + 4], pkt_size);
 			skb_put (skb, pkt_size);
 
 			skb->protocol = eth_type_trans (skb, dev);
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 9c171a7..465485a 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1235,9 +1235,9 @@
 					    lp->rx_dma_addr[entry],
 					    pkt_len,
 					    PCI_DMA_FROMDEVICE);
-		eth_copy_and_sum(skb,
+		skb_copy_to_linear_data(skb,
 				 (unsigned char *)(lp->rx_skbuff[entry]->data),
-				 pkt_len, 0);
+				 pkt_len);
 		pci_dma_sync_single_for_device(lp->pci_dev,
 					       lp->rx_dma_addr[entry],
 					       pkt_len,
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
new file mode 100644
index 0000000..5891a0f
--- /dev/null
+++ b/drivers/net/pppol2tp.c
@@ -0,0 +1,2486 @@
+/*****************************************************************************
+ * Linux PPP over L2TP (PPPoX/PPPoL2TP) Sockets
+ *
+ * PPPoX    --- Generic PPP encapsulation socket family
+ * PPPoL2TP --- PPP over L2TP (RFC 2661)
+ *
+ * Version:	1.0.0
+ *
+ * Authors:	Martijn van Oosterhout <kleptog@svana.org>
+ *		James Chapman (jchapman@katalix.com)
+ * Contributors:
+ *		Michal Ostrowski <mostrows@speakeasy.net>
+ *		Arnaldo Carvalho de Melo <acme@xconectiva.com.br>
+ *		David S. Miller (davem@redhat.com)
+ *
+ * License:
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ */
+
+/* This driver handles only L2TP data frames; control frames are handled by a
+ * userspace application.
+ *
+ * To send data in an L2TP session, userspace opens a PPPoL2TP socket and
+ * attaches it to a bound UDP socket with local tunnel_id / session_id and
+ * peer tunnel_id / session_id set. Data can then be sent or received using
+ * regular socket sendmsg() / recvmsg() calls. Kernel parameters of the socket
+ * can be read or modified using ioctl() or [gs]etsockopt() calls.
+ *
+ * When a PPPoL2TP socket is connected with local and peer session_id values
+ * zero, the socket is treated as a special tunnel management socket.
+ *
+ * Here's example userspace code to create a socket for sending/receiving data
+ * over an L2TP session:-
+ *
+ *	struct sockaddr_pppol2tp sax;
+ *	int fd;
+ *	int session_fd;
+ *
+ *	fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
+ *
+ *	sax.sa_family = AF_PPPOX;
+ *	sax.sa_protocol = PX_PROTO_OL2TP;
+ *	sax.pppol2tp.fd = tunnel_fd;	// bound UDP socket
+ *	sax.pppol2tp.addr.sin_addr.s_addr = addr->sin_addr.s_addr;
+ *	sax.pppol2tp.addr.sin_port = addr->sin_port;
+ *	sax.pppol2tp.addr.sin_family = AF_INET;
+ *	sax.pppol2tp.s_tunnel  = tunnel_id;
+ *	sax.pppol2tp.s_session = session_id;
+ *	sax.pppol2tp.d_tunnel  = peer_tunnel_id;
+ *	sax.pppol2tp.d_session = peer_session_id;
+ *
+ *	session_fd = connect(fd, (struct sockaddr *)&sax, sizeof(sax));
+ *
+ * A pppd plugin that allows PPP traffic to be carried over L2TP using
+ * this driver is available from the OpenL2TP project at
+ * http://openl2tp.sourceforge.net.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/jiffies.h>
+
+#include <linux/netdevice.h>
+#include <linux/net.h>
+#include <linux/inetdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <linux/if_pppox.h>
+#include <linux/if_pppol2tp.h>
+#include <net/sock.h>
+#include <linux/ppp_channel.h>
+#include <linux/ppp_defs.h>
+#include <linux/if_ppp.h>
+#include <linux/file.h>
+#include <linux/hash.h>
+#include <linux/sort.h>
+#include <linux/proc_fs.h>
+#include <net/dst.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <net/xfrm.h>
+
+#include <asm/byteorder.h>
+#include <asm/atomic.h>
+
+
+#define PPPOL2TP_DRV_VERSION	"V1.0"
+
+/* L2TP header constants */
+#define L2TP_HDRFLAG_T	   0x8000
+#define L2TP_HDRFLAG_L	   0x4000
+#define L2TP_HDRFLAG_S	   0x0800
+#define L2TP_HDRFLAG_O	   0x0200
+#define L2TP_HDRFLAG_P	   0x0100
+
+#define L2TP_HDR_VER_MASK  0x000F
+#define L2TP_HDR_VER	   0x0002
+
+/* Space for UDP, L2TP and PPP headers */
+#define PPPOL2TP_HEADER_OVERHEAD	40
+
+/* Just some random numbers */
+#define L2TP_TUNNEL_MAGIC	0x42114DDA
+#define L2TP_SESSION_MAGIC	0x0C04EB7D
+
+#define PPPOL2TP_HASH_BITS	4
+#define PPPOL2TP_HASH_SIZE	(1 << PPPOL2TP_HASH_BITS)
+
+/* Default trace flags */
+#define PPPOL2TP_DEFAULT_DEBUG_FLAGS	0
+
+#define PRINTK(_mask, _type, _lvl, _fmt, args...)			\
+	do {								\
+		if ((_mask) & (_type))					\
+			printk(_lvl "PPPOL2TP: " _fmt, ##args);		\
+	} while(0)
+
+/* Number of bytes to build transmit L2TP headers.
+ * Unfortunately the size is different depending on whether sequence numbers
+ * are enabled.
+ */
+#define PPPOL2TP_L2TP_HDR_SIZE_SEQ		10
+#define PPPOL2TP_L2TP_HDR_SIZE_NOSEQ		6
+
+struct pppol2tp_tunnel;
+
+/* Describes a session. It is the sk_user_data field in the PPPoL2TP
+ * socket. Contains information to determine incoming packets and transmit
+ * outgoing ones.
+ */
+struct pppol2tp_session
+{
+	int			magic;		/* should be
+						 * L2TP_SESSION_MAGIC */
+	int			owner;		/* pid that opened the socket */
+
+	struct sock		*sock;		/* Pointer to the session
+						 * PPPoX socket */
+	struct sock		*tunnel_sock;	/* Pointer to the tunnel UDP
+						 * socket */
+
+	struct pppol2tp_addr	tunnel_addr;	/* Description of tunnel */
+
+	struct pppol2tp_tunnel	*tunnel;	/* back pointer to tunnel
+						 * context */
+
+	char			name[20];	/* "sess xxxxx/yyyyy", where
+						 * x=tunnel_id, y=session_id */
+	int			mtu;
+	int			mru;
+	int			flags;		/* accessed by PPPIOCGFLAGS.
+						 * Unused. */
+	unsigned		recv_seq:1;	/* expect receive packets with
+						 * sequence numbers? */
+	unsigned		send_seq:1;	/* send packets with sequence
+						 * numbers? */
+	unsigned		lns_mode:1;	/* behave as LNS? LAC enables
+						 * sequence numbers under
+						 * control of LNS. */
+	int			debug;		/* bitmask of debug message
+						 * categories */
+	int			reorder_timeout; /* configured reorder timeout
+						  * (in jiffies) */
+	u16			nr;		/* session NR state (receive) */
+	u16			ns;		/* session NR state (send) */
+	struct sk_buff_head	reorder_q;	/* receive reorder queue */
+	struct pppol2tp_ioc_stats stats;
+	struct hlist_node	hlist;		/* Hash list node */
+};
+
+/* The sk_user_data field of the tunnel's UDP socket. It contains info to track
+ * all the associated sessions so incoming packets can be sorted out
+ */
+struct pppol2tp_tunnel
+{
+	int			magic;		/* Should be L2TP_TUNNEL_MAGIC */
+	rwlock_t		hlist_lock;	/* protect session_hlist */
+	struct hlist_head	session_hlist[PPPOL2TP_HASH_SIZE];
+						/* hashed list of sessions,
+						 * hashed by id */
+	int			debug;		/* bitmask of debug message
+						 * categories */
+	char			name[12];	/* "tunl xxxxx" */
+	struct pppol2tp_ioc_stats stats;
+
+	void (*old_sk_destruct)(struct sock *);
+
+	struct sock		*sock;		/* Parent socket */
+	struct list_head	list;		/* Keep a list of all open
+						 * prepared sockets */
+
+	atomic_t		ref_count;
+};
+
+/* Private data stored for received packets in the skb.
+ */
+struct pppol2tp_skb_cb {
+	u16			ns;
+	u16			nr;
+	u16			has_seq;
+	u16			length;
+	unsigned long		expires;
+};
+
+#define PPPOL2TP_SKB_CB(skb)	((struct pppol2tp_skb_cb *) &skb->cb[sizeof(struct inet_skb_parm)])
+
+static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb);
+static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel);
+
+static atomic_t pppol2tp_tunnel_count;
+static atomic_t pppol2tp_session_count;
+static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL };
+static struct proto_ops pppol2tp_ops;
+static LIST_HEAD(pppol2tp_tunnel_list);
+static DEFINE_RWLOCK(pppol2tp_tunnel_list_lock);
+
+/* Helpers to obtain tunnel/session contexts from sockets.
+ */
+static inline struct pppol2tp_session *pppol2tp_sock_to_session(struct sock *sk)
+{
+	struct pppol2tp_session *session;
+
+	if (sk == NULL)
+		return NULL;
+
+	session = (struct pppol2tp_session *)(sk->sk_user_data);
+	if (session == NULL)
+		return NULL;
+
+	BUG_ON(session->magic != L2TP_SESSION_MAGIC);
+
+	return session;
+}
+
+static inline struct pppol2tp_tunnel *pppol2tp_sock_to_tunnel(struct sock *sk)
+{
+	struct pppol2tp_tunnel *tunnel;
+
+	if (sk == NULL)
+		return NULL;
+
+	tunnel = (struct pppol2tp_tunnel *)(sk->sk_user_data);
+	if (tunnel == NULL)
+		return NULL;
+
+	BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
+
+	return tunnel;
+}
+
+/* Tunnel reference counts. Incremented per session that is added to
+ * the tunnel.
+ */
+static inline void pppol2tp_tunnel_inc_refcount(struct pppol2tp_tunnel *tunnel)
+{
+	atomic_inc(&tunnel->ref_count);
+}
+
+static inline void pppol2tp_tunnel_dec_refcount(struct pppol2tp_tunnel *tunnel)
+{
+	if (atomic_dec_and_test(&tunnel->ref_count))
+		pppol2tp_tunnel_free(tunnel);
+}
+
+/* Session hash list.
+ * The session_id SHOULD be random according to RFC2661, but several
+ * L2TP implementations (Cisco and Microsoft) use incrementing
+ * session_ids.  So we do a real hash on the session_id, rather than a
+ * simple bitmask.
+ */
+static inline struct hlist_head *
+pppol2tp_session_id_hash(struct pppol2tp_tunnel *tunnel, u16 session_id)
+{
+	unsigned long hash_val = (unsigned long) session_id;
+	return &tunnel->session_hlist[hash_long(hash_val, PPPOL2TP_HASH_BITS)];
+}
+
+/* Lookup a session by id
+ */
+static struct pppol2tp_session *
+pppol2tp_session_find(struct pppol2tp_tunnel *tunnel, u16 session_id)
+{
+	struct hlist_head *session_list =
+		pppol2tp_session_id_hash(tunnel, session_id);
+	struct pppol2tp_session *session;
+	struct hlist_node *walk;
+
+	read_lock(&tunnel->hlist_lock);
+	hlist_for_each_entry(session, walk, session_list, hlist) {
+		if (session->tunnel_addr.s_session == session_id) {
+			read_unlock(&tunnel->hlist_lock);
+			return session;
+		}
+	}
+	read_unlock(&tunnel->hlist_lock);
+
+	return NULL;
+}
+
+/* Lookup a tunnel by id
+ */
+static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
+{
+	struct pppol2tp_tunnel *tunnel = NULL;
+
+	read_lock(&pppol2tp_tunnel_list_lock);
+	list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) {
+		if (tunnel->stats.tunnel_id == tunnel_id) {
+			read_unlock(&pppol2tp_tunnel_list_lock);
+			return tunnel;
+		}
+	}
+	read_unlock(&pppol2tp_tunnel_list_lock);
+
+	return NULL;
+}
+
+/*****************************************************************************
+ * Receive data handling
+ *****************************************************************************/
+
+/* Queue a skb in order. We come here only if the skb has an L2TP sequence
+ * number.
+ */
+static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_buff *skb)
+{
+	struct sk_buff *skbp;
+	u16 ns = PPPOL2TP_SKB_CB(skb)->ns;
+
+	spin_lock(&session->reorder_q.lock);
+	skb_queue_walk(&session->reorder_q, skbp) {
+		if (PPPOL2TP_SKB_CB(skbp)->ns > ns) {
+			__skb_insert(skb, skbp->prev, skbp, &session->reorder_q);
+			PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+			       "%s: pkt %hu, inserted before %hu, reorder_q len=%d\n",
+			       session->name, ns, PPPOL2TP_SKB_CB(skbp)->ns,
+			       skb_queue_len(&session->reorder_q));
+			session->stats.rx_oos_packets++;
+			goto out;
+		}
+	}
+
+	__skb_queue_tail(&session->reorder_q, skb);
+
+out:
+	spin_unlock(&session->reorder_q.lock);
+}
+
+/* Dequeue a single skb.
+ */
+static void pppol2tp_recv_dequeue_skb(struct pppol2tp_session *session, struct sk_buff *skb)
+{
+	struct pppol2tp_tunnel *tunnel = session->tunnel;
+	int length = PPPOL2TP_SKB_CB(skb)->length;
+	struct sock *session_sock = NULL;
+
+	/* We're about to requeue the skb, so unlink it and return resources
+	 * to its current owner (a socket receive buffer).
+	 */
+	skb_unlink(skb, &session->reorder_q);
+	skb_orphan(skb);
+
+	tunnel->stats.rx_packets++;
+	tunnel->stats.rx_bytes += length;
+	session->stats.rx_packets++;
+	session->stats.rx_bytes += length;
+
+	if (PPPOL2TP_SKB_CB(skb)->has_seq) {
+		/* Bump our Nr */
+		session->nr++;
+		PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+		       "%s: updated nr to %hu\n", session->name, session->nr);
+	}
+
+	/* If the socket is bound, send it in to PPP's input queue. Otherwise
+	 * queue it on the session socket.
+	 */
+	session_sock = session->sock;
+	if (session_sock->sk_state & PPPOX_BOUND) {
+		struct pppox_sock *po;
+		PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+		       "%s: recv %d byte data frame, passing to ppp\n",
+		       session->name, length);
+
+		/* We need to forget all info related to the L2TP packet
+		 * gathered in the skb as we are going to reuse the same
+		 * skb for the inner packet.
+		 * Namely we need to:
+		 * - reset xfrm (IPSec) information as it applies to
+		 *   the outer L2TP packet and not to the inner one
+		 * - release the dst to force a route lookup on the inner
+		 *   IP packet since skb->dst currently points to the dst
+		 *   of the UDP tunnel
+		 * - reset netfilter information as it doesn't apply
+		 *   to the inner packet either
+		 */
+		secpath_reset(skb);
+		dst_release(skb->dst);
+		skb->dst = NULL;
+		nf_reset(skb);
+
+		po = pppox_sk(session_sock);
+		ppp_input(&po->chan, skb);
+	} else {
+		PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_INFO,
+		       "%s: socket not bound\n", session->name);
+
+		/* Not bound. Nothing we can do, so discard. */
+		session->stats.rx_errors++;
+		kfree_skb(skb);
+	}
+
+	sock_put(session->sock);
+}
+
+/* Dequeue skbs from the session's reorder_q, subject to packet order.
+ * Skbs that have been in the queue for too long are simply discarded.
+ */
+static void pppol2tp_recv_dequeue(struct pppol2tp_session *session)
+{
+	struct sk_buff *skb;
+	struct sk_buff *tmp;
+
+	/* If the pkt at the head of the queue has the nr that we
+	 * expect to send up next, dequeue it and any other
+	 * in-sequence packets behind it.
+	 */
+	spin_lock(&session->reorder_q.lock);
+	skb_queue_walk_safe(&session->reorder_q, skb, tmp) {
+		if (time_after(jiffies, PPPOL2TP_SKB_CB(skb)->expires)) {
+			session->stats.rx_seq_discards++;
+			session->stats.rx_errors++;
+			PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+			       "%s: oos pkt %hu len %d discarded (too old), "
+			       "waiting for %hu, reorder_q_len=%d\n",
+			       session->name, PPPOL2TP_SKB_CB(skb)->ns,
+			       PPPOL2TP_SKB_CB(skb)->length, session->nr,
+			       skb_queue_len(&session->reorder_q));
+			__skb_unlink(skb, &session->reorder_q);
+			kfree_skb(skb);
+			continue;
+		}
+
+		if (PPPOL2TP_SKB_CB(skb)->has_seq) {
+			if (PPPOL2TP_SKB_CB(skb)->ns != session->nr) {
+				PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+				       "%s: holding oos pkt %hu len %d, "
+				       "waiting for %hu, reorder_q_len=%d\n",
+				       session->name, PPPOL2TP_SKB_CB(skb)->ns,
+				       PPPOL2TP_SKB_CB(skb)->length, session->nr,
+				       skb_queue_len(&session->reorder_q));
+				goto out;
+			}
+		}
+		spin_unlock(&session->reorder_q.lock);
+		pppol2tp_recv_dequeue_skb(session, skb);
+		spin_lock(&session->reorder_q.lock);
+	}
+
+out:
+	spin_unlock(&session->reorder_q.lock);
+}
+
+/* Internal receive frame. Do the real work of receiving an L2TP data frame
+ * here. The skb is not on a list when we get here.
+ * Returns 0 if the packet was a data packet and was successfully passed on.
+ * Returns 1 if the packet was not a good data packet and could not be
+ * forwarded.  All such packets are passed up to userspace to deal with.
+ */
+static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
+{
+	struct pppol2tp_session *session = NULL;
+	struct pppol2tp_tunnel *tunnel;
+	unsigned char *ptr;
+	u16 hdrflags;
+	u16 tunnel_id, session_id;
+	int length;
+	struct udphdr *uh;
+
+	tunnel = pppol2tp_sock_to_tunnel(sock);
+	if (tunnel == NULL)
+		goto error;
+
+	/* Short packet? */
+	if (skb->len < sizeof(struct udphdr)) {
+		PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_INFO,
+		       "%s: recv short packet (len=%d)\n", tunnel->name, skb->len);
+		goto error;
+	}
+
+	/* Point to L2TP header */
+	ptr = skb->data + sizeof(struct udphdr);
+
+	/* Get L2TP header flags */
+	hdrflags = ntohs(*(__be16*)ptr);
+
+	/* Trace packet contents, if enabled */
+	if (tunnel->debug & PPPOL2TP_MSG_DATA) {
+		printk(KERN_DEBUG "%s: recv: ", tunnel->name);
+
+		for (length = 0; length < 16; length++)
+			printk(" %02X", ptr[length]);
+		printk("\n");
+	}
+
+	/* Get length of L2TP packet */
+	uh = (struct udphdr *) skb_transport_header(skb);
+	length = ntohs(uh->len) - sizeof(struct udphdr);
+
+	/* Too short? */
+	if (length < 12) {
+		PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_INFO,
+		       "%s: recv short L2TP packet (len=%d)\n", tunnel->name, length);
+		goto error;
+	}
+
+	/* If type is control packet, it is handled by userspace. */
+	if (hdrflags & L2TP_HDRFLAG_T) {
+		PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+		       "%s: recv control packet, len=%d\n", tunnel->name, length);
+		goto error;
+	}
+
+	/* Skip flags */
+	ptr += 2;
+
+	/* If length is present, skip it */
+	if (hdrflags & L2TP_HDRFLAG_L)
+		ptr += 2;
+
+	/* Extract tunnel and session ID */
+	tunnel_id = ntohs(*(__be16 *) ptr);
+	ptr += 2;
+	session_id = ntohs(*(__be16 *) ptr);
+	ptr += 2;
+
+	/* Find the session context */
+	session = pppol2tp_session_find(tunnel, session_id);
+	if (!session) {
+		/* Not found? Pass to userspace to deal with */
+		PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_INFO,
+		       "%s: no socket found (%hu/%hu). Passing up.\n",
+		       tunnel->name, tunnel_id, session_id);
+		goto error;
+	}
+	sock_hold(session->sock);
+
+	/* The ref count on the socket was increased by the above call since
+	 * we now hold a pointer to the session. Take care to do sock_put()
+	 * when exiting this function from now on...
+	 */
+
+	/* Handle the optional sequence numbers.  If we are the LAC,
+	 * enable/disable sequence numbers under the control of the LNS.  If
+	 * no sequence numbers present but we were expecting them, discard
+	 * frame.
+	 */
+	if (hdrflags & L2TP_HDRFLAG_S) {
+		u16 ns, nr;
+		ns = ntohs(*(__be16 *) ptr);
+		ptr += 2;
+		nr = ntohs(*(__be16 *) ptr);
+		ptr += 2;
+
+		/* Received a packet with sequence numbers. If we're the LNS,
+		 * check if we sre sending sequence numbers and if not,
+		 * configure it so.
+		 */
+		if ((!session->lns_mode) && (!session->send_seq)) {
+			PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_INFO,
+			       "%s: requested to enable seq numbers by LNS\n",
+			       session->name);
+			session->send_seq = -1;
+		}
+
+		/* Store L2TP info in the skb */
+		PPPOL2TP_SKB_CB(skb)->ns = ns;
+		PPPOL2TP_SKB_CB(skb)->nr = nr;
+		PPPOL2TP_SKB_CB(skb)->has_seq = 1;
+
+		PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+		       "%s: recv data ns=%hu, nr=%hu, session nr=%hu\n",
+		       session->name, ns, nr, session->nr);
+	} else {
+		/* No sequence numbers.
+		 * If user has configured mandatory sequence numbers, discard.
+		 */
+		if (session->recv_seq) {
+			PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_WARNING,
+			       "%s: recv data has no seq numbers when required. "
+			       "Discarding\n", session->name);
+			session->stats.rx_seq_discards++;
+			session->stats.rx_errors++;
+			goto discard;
+		}
+
+		/* If we're the LAC and we're sending sequence numbers, the
+		 * LNS has requested that we no longer send sequence numbers.
+		 * If we're the LNS and we're sending sequence numbers, the
+		 * LAC is broken. Discard the frame.
+		 */
+		if ((!session->lns_mode) && (session->send_seq)) {
+			PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_INFO,
+			       "%s: requested to disable seq numbers by LNS\n",
+			       session->name);
+			session->send_seq = 0;
+		} else if (session->send_seq) {
+			PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_WARNING,
+			       "%s: recv data has no seq numbers when required. "
+			       "Discarding\n", session->name);
+			session->stats.rx_seq_discards++;
+			session->stats.rx_errors++;
+			goto discard;
+		}
+
+		/* Store L2TP info in the skb */
+		PPPOL2TP_SKB_CB(skb)->has_seq = 0;
+	}
+
+	/* If offset bit set, skip it. */
+	if (hdrflags & L2TP_HDRFLAG_O)
+		ptr += 2 + ntohs(*(__be16 *) ptr);
+
+	skb_pull(skb, ptr - skb->data);
+
+	/* Skip PPP header, if present.	 In testing, Microsoft L2TP clients
+	 * don't send the PPP header (PPP header compression enabled), but
+	 * other clients can include the header. So we cope with both cases
+	 * here. The PPP header is always FF03 when using L2TP.
+	 *
+	 * Note that skb->data[] isn't dereferenced from a u16 ptr here since
+	 * the field may be unaligned.
+	 */
+	if ((skb->data[0] == 0xff) && (skb->data[1] == 0x03))
+		skb_pull(skb, 2);
+
+	/* Prepare skb for adding to the session's reorder_q.  Hold
+	 * packets for max reorder_timeout or 1 second if not
+	 * reordering.
+	 */
+	PPPOL2TP_SKB_CB(skb)->length = length;
+	PPPOL2TP_SKB_CB(skb)->expires = jiffies +
+		(session->reorder_timeout ? session->reorder_timeout : HZ);
+
+	/* Add packet to the session's receive queue. Reordering is done here, if
+	 * enabled. Saved L2TP protocol info is stored in skb->sb[].
+	 */
+	if (PPPOL2TP_SKB_CB(skb)->has_seq) {
+		if (session->reorder_timeout != 0) {
+			/* Packet reordering enabled. Add skb to session's
+			 * reorder queue, in order of ns.
+			 */
+			pppol2tp_recv_queue_skb(session, skb);
+		} else {
+			/* Packet reordering disabled. Discard out-of-sequence
+			 * packets
+			 */
+			if (PPPOL2TP_SKB_CB(skb)->ns != session->nr) {
+				session->stats.rx_seq_discards++;
+				session->stats.rx_errors++;
+				PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+				       "%s: oos pkt %hu len %d discarded, "
+				       "waiting for %hu, reorder_q_len=%d\n",
+				       session->name, PPPOL2TP_SKB_CB(skb)->ns,
+				       PPPOL2TP_SKB_CB(skb)->length, session->nr,
+				       skb_queue_len(&session->reorder_q));
+				goto discard;
+			}
+			skb_queue_tail(&session->reorder_q, skb);
+		}
+	} else {
+		/* No sequence numbers. Add the skb to the tail of the
+		 * reorder queue. This ensures that it will be
+		 * delivered after all previous sequenced skbs.
+		 */
+		skb_queue_tail(&session->reorder_q, skb);
+	}
+
+	/* Try to dequeue as many skbs from reorder_q as we can. */
+	pppol2tp_recv_dequeue(session);
+
+	return 0;
+
+discard:
+	kfree_skb(skb);
+	sock_put(session->sock);
+
+	return 0;
+
+error:
+	return 1;
+}
+
+/* UDP encapsulation receive handler. See net/ipv4/udp.c.
+ * Return codes:
+ * 0 : success.
+ * <0: error
+ * >0: skb should be passed up to userspace as UDP.
+ */
+static int pppol2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
+{
+	struct pppol2tp_tunnel *tunnel;
+
+	tunnel = pppol2tp_sock_to_tunnel(sk);
+	if (tunnel == NULL)
+		goto pass_up;
+
+	PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+	       "%s: received %d bytes\n", tunnel->name, skb->len);
+
+	if (pppol2tp_recv_core(sk, skb))
+		goto pass_up;
+
+	return 0;
+
+pass_up:
+	return 1;
+}
+
+/* Receive message. This is the recvmsg for the PPPoL2TP socket.
+ */
+static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock,
+			    struct msghdr *msg, size_t len,
+			    int flags)
+{
+	int err;
+	struct sk_buff *skb;
+	struct sock *sk = sock->sk;
+
+	err = -EIO;
+	if (sk->sk_state & PPPOX_BOUND)
+		goto end;
+
+	msg->msg_namelen = 0;
+
+	err = 0;
+	skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
+				flags & MSG_DONTWAIT, &err);
+	if (skb) {
+		err = memcpy_toiovec(msg->msg_iov, (unsigned char *) skb->data,
+				     skb->len);
+		if (err < 0)
+			goto do_skb_free;
+		err = skb->len;
+	}
+do_skb_free:
+	kfree_skb(skb);
+end:
+	return err;
+}
+
+/************************************************************************
+ * Transmit handling
+ ***********************************************************************/
+
+/* Tell how big L2TP headers are for a particular session. This
+ * depends on whether sequence numbers are being used.
+ */
+static inline int pppol2tp_l2tp_header_len(struct pppol2tp_session *session)
+{
+	if (session->send_seq)
+		return PPPOL2TP_L2TP_HDR_SIZE_SEQ;
+
+	return PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
+}
+
+/* Build an L2TP header for the session into the buffer provided.
+ */
+static void pppol2tp_build_l2tp_header(struct pppol2tp_session *session,
+				       void *buf)
+{
+	__be16 *bufp = buf;
+	u16 flags = L2TP_HDR_VER;
+
+	if (session->send_seq)
+		flags |= L2TP_HDRFLAG_S;
+
+	/* Setup L2TP header.
+	 * FIXME: Can this ever be unaligned? Is direct dereferencing of
+	 * 16-bit header fields safe here for all architectures?
+	 */
+	*bufp++ = htons(flags);
+	*bufp++ = htons(session->tunnel_addr.d_tunnel);
+	*bufp++ = htons(session->tunnel_addr.d_session);
+	if (session->send_seq) {
+		*bufp++ = htons(session->ns);
+		*bufp++ = 0;
+		session->ns++;
+		PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
+		       "%s: updated ns to %hu\n", session->name, session->ns);
+	}
+}
+
+/* This is the sendmsg for the PPPoL2TP pppol2tp_session socket.  We come here
+ * when a user application does a sendmsg() on the session socket. L2TP and
+ * PPP headers must be inserted into the user's data.
+ */
+static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
+			    size_t total_len)
+{
+	static const unsigned char ppph[2] = { 0xff, 0x03 };
+	struct sock *sk = sock->sk;
+	struct inet_sock *inet;
+	__wsum csum = 0;
+	struct sk_buff *skb;
+	int error;
+	int hdr_len;
+	struct pppol2tp_session *session;
+	struct pppol2tp_tunnel *tunnel;
+	struct udphdr *uh;
+
+	error = -ENOTCONN;
+	if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
+		goto error;
+
+	/* Get session and tunnel contexts */
+	error = -EBADF;
+	session = pppol2tp_sock_to_session(sk);
+	if (session == NULL)
+		goto error;
+
+	tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock);
+	if (tunnel == NULL)
+		goto error;
+
+	/* What header length is configured for this session? */
+	hdr_len = pppol2tp_l2tp_header_len(session);
+
+	/* Allocate a socket buffer */
+	error = -ENOMEM;
+	skb = sock_wmalloc(sk, NET_SKB_PAD + sizeof(struct iphdr) +
+			   sizeof(struct udphdr) + hdr_len +
+			   sizeof(ppph) + total_len,
+			   0, GFP_KERNEL);
+	if (!skb)
+		goto error;
+
+	/* Reserve space for headers. */
+	skb_reserve(skb, NET_SKB_PAD);
+	skb_reset_network_header(skb);
+	skb_reserve(skb, sizeof(struct iphdr));
+	skb_reset_transport_header(skb);
+
+	/* Build UDP header */
+	inet = inet_sk(session->tunnel_sock);
+	uh = (struct udphdr *) skb->data;
+	uh->source = inet->sport;
+	uh->dest = inet->dport;
+	uh->len = htons(hdr_len + sizeof(ppph) + total_len);
+	uh->check = 0;
+	skb_put(skb, sizeof(struct udphdr));
+
+	/* Build L2TP header */
+	pppol2tp_build_l2tp_header(session, skb->data);
+	skb_put(skb, hdr_len);
+
+	/* Add PPP header */
+	skb->data[0] = ppph[0];
+	skb->data[1] = ppph[1];
+	skb_put(skb, 2);
+
+	/* Copy user data into skb */
+	error = memcpy_fromiovec(skb->data, m->msg_iov, total_len);
+	if (error < 0) {
+		kfree_skb(skb);
+		goto error;
+	}
+	skb_put(skb, total_len);
+
+	/* Calculate UDP checksum if configured to do so */
+	if (session->tunnel_sock->sk_no_check != UDP_CSUM_NOXMIT)
+		csum = udp_csum_outgoing(sk, skb);
+
+	/* Debug */
+	if (session->send_seq)
+		PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+		       "%s: send %Zd bytes, ns=%hu\n", session->name,
+		       total_len, session->ns - 1);
+	else
+		PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+		       "%s: send %Zd bytes\n", session->name, total_len);
+
+	if (session->debug & PPPOL2TP_MSG_DATA) {
+		int i;
+		unsigned char *datap = skb->data;
+
+		printk(KERN_DEBUG "%s: xmit:", session->name);
+		for (i = 0; i < total_len; i++) {
+			printk(" %02X", *datap++);
+			if (i == 15) {
+				printk(" ...");
+				break;
+			}
+		}
+		printk("\n");
+	}
+
+	/* Queue the packet to IP for output */
+	error = ip_queue_xmit(skb, 1);
+
+	/* Update stats */
+	if (error >= 0) {
+		tunnel->stats.tx_packets++;
+		tunnel->stats.tx_bytes += skb->len;
+		session->stats.tx_packets++;
+		session->stats.tx_bytes += skb->len;
+	} else {
+		tunnel->stats.tx_errors++;
+		session->stats.tx_errors++;
+	}
+
+error:
+	return error;
+}
+
+/* Transmit function called by generic PPP driver.  Sends PPP frame
+ * over PPPoL2TP socket.
+ *
+ * This is almost the same as pppol2tp_sendmsg(), but rather than
+ * being called with a msghdr from userspace, it is called with a skb
+ * from the kernel.
+ *
+ * The supplied skb from ppp doesn't have enough headroom for the
+ * insertion of L2TP, UDP and IP headers so we need to allocate more
+ * headroom in the skb. This will create a cloned skb. But we must be
+ * careful in the error case because the caller will expect to free
+ * the skb it supplied, not our cloned skb. So we take care to always
+ * leave the original skb unfreed if we return an error.
+ */
+static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
+{
+	static const u8 ppph[2] = { 0xff, 0x03 };
+	struct sock *sk = (struct sock *) chan->private;
+	struct sock *sk_tun;
+	int hdr_len;
+	struct pppol2tp_session *session;
+	struct pppol2tp_tunnel *tunnel;
+	int rc;
+	int headroom;
+	int data_len = skb->len;
+	struct inet_sock *inet;
+	__wsum csum = 0;
+	struct sk_buff *skb2 = NULL;
+	struct udphdr *uh;
+
+	if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
+		goto abort;
+
+	/* Get session and tunnel contexts from the socket */
+	session = pppol2tp_sock_to_session(sk);
+	if (session == NULL)
+		goto abort;
+
+	sk_tun = session->tunnel_sock;
+	if (sk_tun == NULL)
+		goto abort;
+	tunnel = pppol2tp_sock_to_tunnel(sk_tun);
+	if (tunnel == NULL)
+		goto abort;
+
+	/* What header length is configured for this session? */
+	hdr_len = pppol2tp_l2tp_header_len(session);
+
+	/* Check that there's enough headroom in the skb to insert IP,
+	 * UDP and L2TP and PPP headers. If not enough, expand it to
+	 * make room. Note that a new skb (or a clone) is
+	 * allocated. If we return an error from this point on, make
+	 * sure we free the new skb but do not free the original skb
+	 * since that is done by the caller for the error case.
+	 */
+	headroom = NET_SKB_PAD + sizeof(struct iphdr) +
+		sizeof(struct udphdr) + hdr_len + sizeof(ppph);
+	if (skb_headroom(skb) < headroom) {
+		skb2 = skb_realloc_headroom(skb, headroom);
+		if (skb2 == NULL)
+			goto abort;
+	} else
+		skb2 = skb;
+
+	/* Check that the socket has room */
+	if (atomic_read(&sk_tun->sk_wmem_alloc) < sk_tun->sk_sndbuf)
+		skb_set_owner_w(skb2, sk_tun);
+	else
+		goto discard;
+
+	/* Setup PPP header */
+	skb_push(skb2, sizeof(ppph));
+	skb2->data[0] = ppph[0];
+	skb2->data[1] = ppph[1];
+
+	/* Setup L2TP header */
+	skb_push(skb2, hdr_len);
+	pppol2tp_build_l2tp_header(session, skb2->data);
+
+	/* Setup UDP header */
+	inet = inet_sk(sk_tun);
+	skb_push(skb2, sizeof(struct udphdr));
+	skb_reset_transport_header(skb2);
+	uh = (struct udphdr *) skb2->data;
+	uh->source = inet->sport;
+	uh->dest = inet->dport;
+	uh->len = htons(sizeof(struct udphdr) + hdr_len + sizeof(ppph) + data_len);
+	uh->check = 0;
+
+	/* Calculate UDP checksum if configured to do so */
+	if (sk_tun->sk_no_check != UDP_CSUM_NOXMIT)
+		csum = udp_csum_outgoing(sk_tun, skb2);
+
+	/* Debug */
+	if (session->send_seq)
+		PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+		       "%s: send %d bytes, ns=%hu\n", session->name,
+		       data_len, session->ns - 1);
+	else
+		PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
+		       "%s: send %d bytes\n", session->name, data_len);
+
+	if (session->debug & PPPOL2TP_MSG_DATA) {
+		int i;
+		unsigned char *datap = skb2->data;
+
+		printk(KERN_DEBUG "%s: xmit:", session->name);
+		for (i = 0; i < data_len; i++) {
+			printk(" %02X", *datap++);
+			if (i == 31) {
+				printk(" ...");
+				break;
+			}
+		}
+		printk("\n");
+	}
+
+	/* Get routing info from the tunnel socket */
+	skb2->dst = sk_dst_get(sk_tun);
+
+	/* Queue the packet to IP for output */
+	rc = ip_queue_xmit(skb2, 1);
+
+	/* Update stats */
+	if (rc >= 0) {
+		tunnel->stats.tx_packets++;
+		tunnel->stats.tx_bytes += skb2->len;
+		session->stats.tx_packets++;
+		session->stats.tx_bytes += skb2->len;
+	} else {
+		tunnel->stats.tx_errors++;
+		session->stats.tx_errors++;
+	}
+
+	/* Free the original skb */
+	kfree_skb(skb);
+
+	return 1;
+
+discard:
+	/* Free the new skb. Caller will free original skb. */
+	if (skb2 != skb)
+		kfree_skb(skb2);
+abort:
+	return 0;
+}
+
+/*****************************************************************************
+ * Session (and tunnel control) socket create/destroy.
+ *****************************************************************************/
+
+/* When the tunnel UDP socket is closed, all the attached sockets need to go
+ * too.
+ */
+static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel)
+{
+	int hash;
+	struct hlist_node *walk;
+	struct hlist_node *tmp;
+	struct pppol2tp_session *session;
+	struct sock *sk;
+
+	if (tunnel == NULL)
+		BUG();
+
+	PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+	       "%s: closing all sessions...\n", tunnel->name);
+
+	write_lock(&tunnel->hlist_lock);
+	for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) {
+again:
+		hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
+			session = hlist_entry(walk, struct pppol2tp_session, hlist);
+
+			sk = session->sock;
+
+			PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+			       "%s: closing session\n", session->name);
+
+			hlist_del_init(&session->hlist);
+
+			/* Since we should hold the sock lock while
+			 * doing any unbinding, we need to release the
+			 * lock we're holding before taking that lock.
+			 * Hold a reference to the sock so it doesn't
+			 * disappear as we're jumping between locks.
+			 */
+			sock_hold(sk);
+			write_unlock(&tunnel->hlist_lock);
+			lock_sock(sk);
+
+			if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+				pppox_unbind_sock(sk);
+				sk->sk_state = PPPOX_DEAD;
+				sk->sk_state_change(sk);
+			}
+
+			/* Purge any queued data */
+			skb_queue_purge(&sk->sk_receive_queue);
+			skb_queue_purge(&sk->sk_write_queue);
+			skb_queue_purge(&session->reorder_q);
+
+			release_sock(sk);
+			sock_put(sk);
+
+			/* Now restart from the beginning of this hash
+			 * chain.  We always remove a session from the
+			 * list so we are guaranteed to make forward
+			 * progress.
+			 */
+			write_lock(&tunnel->hlist_lock);
+			goto again;
+		}
+	}
+	write_unlock(&tunnel->hlist_lock);
+}
+
+/* Really kill the tunnel.
+ * Come here only when all sessions have been cleared from the tunnel.
+ */
+static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel)
+{
+	/* Remove from socket list */
+	write_lock(&pppol2tp_tunnel_list_lock);
+	list_del_init(&tunnel->list);
+	write_unlock(&pppol2tp_tunnel_list_lock);
+
+	atomic_dec(&pppol2tp_tunnel_count);
+	kfree(tunnel);
+}
+
+/* Tunnel UDP socket destruct hook.
+ * The tunnel context is deleted only when all session sockets have been
+ * closed.
+ */
+static void pppol2tp_tunnel_destruct(struct sock *sk)
+{
+	struct pppol2tp_tunnel *tunnel;
+
+	tunnel = pppol2tp_sock_to_tunnel(sk);
+	if (tunnel == NULL)
+		goto end;
+
+	PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+	       "%s: closing...\n", tunnel->name);
+
+	/* Close all sessions */
+	pppol2tp_tunnel_closeall(tunnel);
+
+	/* No longer an encapsulation socket. See net/ipv4/udp.c */
+	(udp_sk(sk))->encap_type = 0;
+	(udp_sk(sk))->encap_rcv = NULL;
+
+	/* Remove hooks into tunnel socket */
+	tunnel->sock = NULL;
+	sk->sk_destruct = tunnel->old_sk_destruct;
+	sk->sk_user_data = NULL;
+
+	/* Call original (UDP) socket descructor */
+	if (sk->sk_destruct != NULL)
+		(*sk->sk_destruct)(sk);
+
+	pppol2tp_tunnel_dec_refcount(tunnel);
+
+end:
+	return;
+}
+
+/* Really kill the session socket. (Called from sock_put() if
+ * refcnt == 0.)
+ */
+static void pppol2tp_session_destruct(struct sock *sk)
+{
+	struct pppol2tp_session *session = NULL;
+
+	if (sk->sk_user_data != NULL) {
+		struct pppol2tp_tunnel *tunnel;
+
+		session = pppol2tp_sock_to_session(sk);
+		if (session == NULL)
+			goto out;
+
+		/* Don't use pppol2tp_sock_to_tunnel() here to
+		 * get the tunnel context because the tunnel
+		 * socket might have already been closed (its
+		 * sk->sk_user_data will be NULL) so use the
+		 * session's private tunnel ptr instead.
+		 */
+		tunnel = session->tunnel;
+		if (tunnel != NULL) {
+			BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
+
+			/* If session_id is zero, this is a null
+			 * session context, which was created for a
+			 * socket that is being used only to manage
+			 * tunnels.
+			 */
+			if (session->tunnel_addr.s_session != 0) {
+				/* Delete the session socket from the
+				 * hash
+				 */
+				write_lock(&tunnel->hlist_lock);
+				hlist_del_init(&session->hlist);
+				write_unlock(&tunnel->hlist_lock);
+
+				atomic_dec(&pppol2tp_session_count);
+			}
+
+			/* This will delete the tunnel context if this
+			 * is the last session on the tunnel.
+			 */
+			session->tunnel = NULL;
+			session->tunnel_sock = NULL;
+			pppol2tp_tunnel_dec_refcount(tunnel);
+		}
+	}
+
+	kfree(session);
+out:
+	return;
+}
+
+/* Called when the PPPoX socket (session) is closed.
+ */
+static int pppol2tp_release(struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+	int error;
+
+	if (!sk)
+		return 0;
+
+	error = -EBADF;
+	lock_sock(sk);
+	if (sock_flag(sk, SOCK_DEAD) != 0)
+		goto error;
+
+	pppox_unbind_sock(sk);
+
+	/* Signal the death of the socket. */
+	sk->sk_state = PPPOX_DEAD;
+	sock_orphan(sk);
+	sock->sk = NULL;
+
+	/* Purge any queued data */
+	skb_queue_purge(&sk->sk_receive_queue);
+	skb_queue_purge(&sk->sk_write_queue);
+
+	release_sock(sk);
+
+	/* This will delete the session context via
+	 * pppol2tp_session_destruct() if the socket's refcnt drops to
+	 * zero.
+	 */
+	sock_put(sk);
+
+	return 0;
+
+error:
+	release_sock(sk);
+	return error;
+}
+
+/* Internal function to prepare a tunnel (UDP) socket to have PPPoX
+ * sockets attached to it.
+ */
+static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
+						   int *error)
+{
+	int err;
+	struct socket *sock = NULL;
+	struct sock *sk;
+	struct pppol2tp_tunnel *tunnel;
+	struct sock *ret = NULL;
+
+	/* Get the tunnel UDP socket from the fd, which was opened by
+	 * the userspace L2TP daemon.
+	 */
+	err = -EBADF;
+	sock = sockfd_lookup(fd, &err);
+	if (!sock) {
+		PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_ERR,
+		       "tunl %hu: sockfd_lookup(fd=%d) returned %d\n",
+		       tunnel_id, fd, err);
+		goto err;
+	}
+
+	/* Quick sanity checks */
+	err = -ESOCKTNOSUPPORT;
+	if (sock->type != SOCK_DGRAM) {
+		PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_ERR,
+		       "tunl %hu: fd %d wrong type, got %d, expected %d\n",
+		       tunnel_id, fd, sock->type, SOCK_DGRAM);
+		goto err;
+	}
+	err = -EAFNOSUPPORT;
+	if (sock->ops->family != AF_INET) {
+		PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_ERR,
+		       "tunl %hu: fd %d wrong family, got %d, expected %d\n",
+		       tunnel_id, fd, sock->ops->family, AF_INET);
+		goto err;
+	}
+
+	err = -ENOTCONN;
+	sk = sock->sk;
+
+	/* Check if this socket has already been prepped */
+	tunnel = (struct pppol2tp_tunnel *)sk->sk_user_data;
+	if (tunnel != NULL) {
+		/* User-data field already set */
+		err = -EBUSY;
+		BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
+
+		/* This socket has already been prepped */
+		ret = tunnel->sock;
+		goto out;
+	}
+
+	/* This socket is available and needs prepping. Create a new tunnel
+	 * context and init it.
+	 */
+	sk->sk_user_data = tunnel = kzalloc(sizeof(struct pppol2tp_tunnel), GFP_KERNEL);
+	if (sk->sk_user_data == NULL) {
+		err = -ENOMEM;
+		goto err;
+	}
+
+	tunnel->magic = L2TP_TUNNEL_MAGIC;
+	sprintf(&tunnel->name[0], "tunl %hu", tunnel_id);
+
+	tunnel->stats.tunnel_id = tunnel_id;
+	tunnel->debug = PPPOL2TP_DEFAULT_DEBUG_FLAGS;
+
+	/* Hook on the tunnel socket destructor so that we can cleanup
+	 * if the tunnel socket goes away.
+	 */
+	tunnel->old_sk_destruct = sk->sk_destruct;
+	sk->sk_destruct = &pppol2tp_tunnel_destruct;
+
+	tunnel->sock = sk;
+	sk->sk_allocation = GFP_ATOMIC;
+
+	/* Misc init */
+	rwlock_init(&tunnel->hlist_lock);
+
+	/* Add tunnel to our list */
+	INIT_LIST_HEAD(&tunnel->list);
+	write_lock(&pppol2tp_tunnel_list_lock);
+	list_add(&tunnel->list, &pppol2tp_tunnel_list);
+	write_unlock(&pppol2tp_tunnel_list_lock);
+	atomic_inc(&pppol2tp_tunnel_count);
+
+	/* Bump the reference count. The tunnel context is deleted
+	 * only when this drops to zero.
+	 */
+	pppol2tp_tunnel_inc_refcount(tunnel);
+
+	/* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
+	(udp_sk(sk))->encap_type = UDP_ENCAP_L2TPINUDP;
+	(udp_sk(sk))->encap_rcv = pppol2tp_udp_encap_recv;
+
+	ret = tunnel->sock;
+
+	*error = 0;
+out:
+	if (sock)
+		sockfd_put(sock);
+
+	return ret;
+
+err:
+	*error = err;
+	goto out;
+}
+
+static struct proto pppol2tp_sk_proto = {
+	.name	  = "PPPOL2TP",
+	.owner	  = THIS_MODULE,
+	.obj_size = sizeof(struct pppox_sock),
+};
+
+/* socket() handler. Initialize a new struct sock.
+ */
+static int pppol2tp_create(struct socket *sock)
+{
+	int error = -ENOMEM;
+	struct sock *sk;
+
+	sk = sk_alloc(PF_PPPOX, GFP_KERNEL, &pppol2tp_sk_proto, 1);
+	if (!sk)
+		goto out;
+
+	sock_init_data(sock, sk);
+
+	sock->state  = SS_UNCONNECTED;
+	sock->ops    = &pppol2tp_ops;
+
+	sk->sk_backlog_rcv = pppol2tp_recv_core;
+	sk->sk_protocol	   = PX_PROTO_OL2TP;
+	sk->sk_family	   = PF_PPPOX;
+	sk->sk_state	   = PPPOX_NONE;
+	sk->sk_type	   = SOCK_STREAM;
+	sk->sk_destruct	   = pppol2tp_session_destruct;
+
+	error = 0;
+
+out:
+	return error;
+}
+
+/* connect() handler. Attach a PPPoX socket to a tunnel UDP socket
+ */
+static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
+			    int sockaddr_len, int flags)
+{
+	struct sock *sk = sock->sk;
+	struct sockaddr_pppol2tp *sp = (struct sockaddr_pppol2tp *) uservaddr;
+	struct pppox_sock *po = pppox_sk(sk);
+	struct sock *tunnel_sock = NULL;
+	struct pppol2tp_session *session = NULL;
+	struct pppol2tp_tunnel *tunnel;
+	struct dst_entry *dst;
+	int error = 0;
+
+	lock_sock(sk);
+
+	error = -EINVAL;
+	if (sp->sa_protocol != PX_PROTO_OL2TP)
+		goto end;
+
+	/* Check for already bound sockets */
+	error = -EBUSY;
+	if (sk->sk_state & PPPOX_CONNECTED)
+		goto end;
+
+	/* We don't supporting rebinding anyway */
+	error = -EALREADY;
+	if (sk->sk_user_data)
+		goto end; /* socket is already attached */
+
+	/* Don't bind if s_tunnel is 0 */
+	error = -EINVAL;
+	if (sp->pppol2tp.s_tunnel == 0)
+		goto end;
+
+	/* Special case: prepare tunnel socket if s_session and
+	 * d_session is 0. Otherwise look up tunnel using supplied
+	 * tunnel id.
+	 */
+	if ((sp->pppol2tp.s_session == 0) && (sp->pppol2tp.d_session == 0)) {
+		tunnel_sock = pppol2tp_prepare_tunnel_socket(sp->pppol2tp.fd,
+							     sp->pppol2tp.s_tunnel,
+							     &error);
+		if (tunnel_sock == NULL)
+			goto end;
+
+		tunnel = tunnel_sock->sk_user_data;
+	} else {
+		tunnel = pppol2tp_tunnel_find(sp->pppol2tp.s_tunnel);
+
+		/* Error if we can't find the tunnel */
+		error = -ENOENT;
+		if (tunnel == NULL)
+			goto end;
+
+		tunnel_sock = tunnel->sock;
+	}
+
+	/* Check that this session doesn't already exist */
+	error = -EEXIST;
+	session = pppol2tp_session_find(tunnel, sp->pppol2tp.s_session);
+	if (session != NULL)
+		goto end;
+
+	/* Allocate and initialize a new session context. */
+	session = kzalloc(sizeof(struct pppol2tp_session), GFP_KERNEL);
+	if (session == NULL) {
+		error = -ENOMEM;
+		goto end;
+	}
+
+	skb_queue_head_init(&session->reorder_q);
+
+	session->magic	     = L2TP_SESSION_MAGIC;
+	session->owner	     = current->pid;
+	session->sock	     = sk;
+	session->tunnel	     = tunnel;
+	session->tunnel_sock = tunnel_sock;
+	session->tunnel_addr = sp->pppol2tp;
+	sprintf(&session->name[0], "sess %hu/%hu",
+		session->tunnel_addr.s_tunnel,
+		session->tunnel_addr.s_session);
+
+	session->stats.tunnel_id  = session->tunnel_addr.s_tunnel;
+	session->stats.session_id = session->tunnel_addr.s_session;
+
+	INIT_HLIST_NODE(&session->hlist);
+
+	/* Inherit debug options from tunnel */
+	session->debug = tunnel->debug;
+
+	/* Default MTU must allow space for UDP/L2TP/PPP
+	 * headers.
+	 */
+	session->mtu = session->mru = 1500 - PPPOL2TP_HEADER_OVERHEAD;
+
+	/* If PMTU discovery was enabled, use the MTU that was discovered */
+	dst = sk_dst_get(sk);
+	if (dst != NULL) {
+		u32 pmtu = dst_mtu(__sk_dst_get(sk));
+		if (pmtu != 0)
+			session->mtu = session->mru = pmtu -
+				PPPOL2TP_HEADER_OVERHEAD;
+		dst_release(dst);
+	}
+
+	/* Special case: if source & dest session_id == 0x0000, this socket is
+	 * being created to manage the tunnel. Don't add the session to the
+	 * session hash list, just set up the internal context for use by
+	 * ioctl() and sockopt() handlers.
+	 */
+	if ((session->tunnel_addr.s_session == 0) &&
+	    (session->tunnel_addr.d_session == 0)) {
+		error = 0;
+		sk->sk_user_data = session;
+		goto out_no_ppp;
+	}
+
+	/* Get tunnel context from the tunnel socket */
+	tunnel = pppol2tp_sock_to_tunnel(tunnel_sock);
+	if (tunnel == NULL) {
+		error = -EBADF;
+		goto end;
+	}
+
+	/* Right now, because we don't have a way to push the incoming skb's
+	 * straight through the UDP layer, the only header we need to worry
+	 * about is the L2TP header. This size is different depending on
+	 * whether sequence numbers are enabled for the data channel.
+	 */
+	po->chan.hdrlen = PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
+
+	po->chan.private = sk;
+	po->chan.ops	 = &pppol2tp_chan_ops;
+	po->chan.mtu	 = session->mtu;
+
+	error = ppp_register_channel(&po->chan);
+	if (error)
+		goto end;
+
+	/* This is how we get the session context from the socket. */
+	sk->sk_user_data = session;
+
+	/* Add session to the tunnel's hash list */
+	write_lock(&tunnel->hlist_lock);
+	hlist_add_head(&session->hlist,
+		       pppol2tp_session_id_hash(tunnel,
+						session->tunnel_addr.s_session));
+	write_unlock(&tunnel->hlist_lock);
+
+	atomic_inc(&pppol2tp_session_count);
+
+out_no_ppp:
+	pppol2tp_tunnel_inc_refcount(tunnel);
+	sk->sk_state = PPPOX_CONNECTED;
+	PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+	       "%s: created\n", session->name);
+
+end:
+	release_sock(sk);
+
+	if (error != 0)
+		PRINTK(session ? session->debug : -1, PPPOL2TP_MSG_CONTROL, KERN_WARNING,
+		       "%s: connect failed: %d\n", session->name, error);
+
+	return error;
+}
+
+/* getname() support.
+ */
+static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
+			    int *usockaddr_len, int peer)
+{
+	int len = sizeof(struct sockaddr_pppol2tp);
+	struct sockaddr_pppol2tp sp;
+	int error = 0;
+	struct pppol2tp_session *session;
+
+	error = -ENOTCONN;
+	if (sock->sk->sk_state != PPPOX_CONNECTED)
+		goto end;
+
+	session = pppol2tp_sock_to_session(sock->sk);
+	if (session == NULL) {
+		error = -EBADF;
+		goto end;
+	}
+
+	sp.sa_family	= AF_PPPOX;
+	sp.sa_protocol	= PX_PROTO_OL2TP;
+	memcpy(&sp.pppol2tp, &session->tunnel_addr,
+	       sizeof(struct pppol2tp_addr));
+
+	memcpy(uaddr, &sp, len);
+
+	*usockaddr_len = len;
+
+	error = 0;
+
+end:
+	return error;
+}
+
+/****************************************************************************
+ * ioctl() handlers.
+ *
+ * The PPPoX socket is created for L2TP sessions: tunnels have their own UDP
+ * sockets. However, in order to control kernel tunnel features, we allow
+ * userspace to create a special "tunnel" PPPoX socket which is used for
+ * control only.  Tunnel PPPoX sockets have session_id == 0 and simply allow
+ * the user application to issue L2TP setsockopt(), getsockopt() and ioctl()
+ * calls.
+ ****************************************************************************/
+
+/* Session ioctl helper.
+ */
+static int pppol2tp_session_ioctl(struct pppol2tp_session *session,
+				  unsigned int cmd, unsigned long arg)
+{
+	struct ifreq ifr;
+	int err = 0;
+	struct sock *sk = session->sock;
+	int val = (int) arg;
+
+	PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_DEBUG,
+	       "%s: pppol2tp_session_ioctl(cmd=%#x, arg=%#lx)\n",
+	       session->name, cmd, arg);
+
+	sock_hold(sk);
+
+	switch (cmd) {
+	case SIOCGIFMTU:
+		err = -ENXIO;
+		if (!(sk->sk_state & PPPOX_CONNECTED))
+			break;
+
+		err = -EFAULT;
+		if (copy_from_user(&ifr, (void __user *) arg, sizeof(struct ifreq)))
+			break;
+		ifr.ifr_mtu = session->mtu;
+		if (copy_to_user((void __user *) arg, &ifr, sizeof(struct ifreq)))
+			break;
+
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: get mtu=%d\n", session->name, session->mtu);
+		err = 0;
+		break;
+
+	case SIOCSIFMTU:
+		err = -ENXIO;
+		if (!(sk->sk_state & PPPOX_CONNECTED))
+			break;
+
+		err = -EFAULT;
+		if (copy_from_user(&ifr, (void __user *) arg, sizeof(struct ifreq)))
+			break;
+
+		session->mtu = ifr.ifr_mtu;
+
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: set mtu=%d\n", session->name, session->mtu);
+		err = 0;
+		break;
+
+	case PPPIOCGMRU:
+		err = -ENXIO;
+		if (!(sk->sk_state & PPPOX_CONNECTED))
+			break;
+
+		err = -EFAULT;
+		if (put_user(session->mru, (int __user *) arg))
+			break;
+
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: get mru=%d\n", session->name, session->mru);
+		err = 0;
+		break;
+
+	case PPPIOCSMRU:
+		err = -ENXIO;
+		if (!(sk->sk_state & PPPOX_CONNECTED))
+			break;
+
+		err = -EFAULT;
+		if (get_user(val,(int __user *) arg))
+			break;
+
+		session->mru = val;
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: set mru=%d\n", session->name, session->mru);
+		err = 0;
+		break;
+
+	case PPPIOCGFLAGS:
+		err = -EFAULT;
+		if (put_user(session->flags, (int __user *) arg))
+			break;
+
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: get flags=%d\n", session->name, session->flags);
+		err = 0;
+		break;
+
+	case PPPIOCSFLAGS:
+		err = -EFAULT;
+		if (get_user(val, (int __user *) arg))
+			break;
+		session->flags = val;
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: set flags=%d\n", session->name, session->flags);
+		err = 0;
+		break;
+
+	case PPPIOCGL2TPSTATS:
+		err = -ENXIO;
+		if (!(sk->sk_state & PPPOX_CONNECTED))
+			break;
+
+		if (copy_to_user((void __user *) arg, &session->stats,
+				 sizeof(session->stats)))
+			break;
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: get L2TP stats\n", session->name);
+		err = 0;
+		break;
+
+	default:
+		err = -ENOSYS;
+		break;
+	}
+
+	sock_put(sk);
+
+	return err;
+}
+
+/* Tunnel ioctl helper.
+ *
+ * Note the special handling for PPPIOCGL2TPSTATS below. If the ioctl data
+ * specifies a session_id, the session ioctl handler is called. This allows an
+ * application to retrieve session stats via a tunnel socket.
+ */
+static int pppol2tp_tunnel_ioctl(struct pppol2tp_tunnel *tunnel,
+				 unsigned int cmd, unsigned long arg)
+{
+	int err = 0;
+	struct sock *sk = tunnel->sock;
+	struct pppol2tp_ioc_stats stats_req;
+
+	PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_DEBUG,
+	       "%s: pppol2tp_tunnel_ioctl(cmd=%#x, arg=%#lx)\n", tunnel->name,
+	       cmd, arg);
+
+	sock_hold(sk);
+
+	switch (cmd) {
+	case PPPIOCGL2TPSTATS:
+		err = -ENXIO;
+		if (!(sk->sk_state & PPPOX_CONNECTED))
+			break;
+
+		if (copy_from_user(&stats_req, (void __user *) arg,
+				   sizeof(stats_req))) {
+			err = -EFAULT;
+			break;
+		}
+		if (stats_req.session_id != 0) {
+			/* resend to session ioctl handler */
+			struct pppol2tp_session *session =
+				pppol2tp_session_find(tunnel, stats_req.session_id);
+			if (session != NULL)
+				err = pppol2tp_session_ioctl(session, cmd, arg);
+			else
+				err = -EBADR;
+			break;
+		}
+#ifdef CONFIG_XFRM
+		tunnel->stats.using_ipsec = (sk->sk_policy[0] || sk->sk_policy[1]) ? 1 : 0;
+#endif
+		if (copy_to_user((void __user *) arg, &tunnel->stats,
+				 sizeof(tunnel->stats))) {
+			err = -EFAULT;
+			break;
+		}
+		PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: get L2TP stats\n", tunnel->name);
+		err = 0;
+		break;
+
+	default:
+		err = -ENOSYS;
+		break;
+	}
+
+	sock_put(sk);
+
+	return err;
+}
+
+/* Main ioctl() handler.
+ * Dispatch to tunnel or session helpers depending on the socket.
+ */
+static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd,
+			  unsigned long arg)
+{
+	struct sock *sk = sock->sk;
+	struct pppol2tp_session *session;
+	struct pppol2tp_tunnel *tunnel;
+	int err;
+
+	if (!sk)
+		return 0;
+
+	err = -EBADF;
+	if (sock_flag(sk, SOCK_DEAD) != 0)
+		goto end;
+
+	err = -ENOTCONN;
+	if ((sk->sk_user_data == NULL) ||
+	    (!(sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND))))
+		goto end;
+
+	/* Get session context from the socket */
+	err = -EBADF;
+	session = pppol2tp_sock_to_session(sk);
+	if (session == NULL)
+		goto end;
+
+	/* Special case: if session's session_id is zero, treat ioctl as a
+	 * tunnel ioctl
+	 */
+	if ((session->tunnel_addr.s_session == 0) &&
+	    (session->tunnel_addr.d_session == 0)) {
+		err = -EBADF;
+		tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock);
+		if (tunnel == NULL)
+			goto end;
+
+		err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg);
+		goto end;
+	}
+
+	err = pppol2tp_session_ioctl(session, cmd, arg);
+
+end:
+	return err;
+}
+
+/*****************************************************************************
+ * setsockopt() / getsockopt() support.
+ *
+ * The PPPoX socket is created for L2TP sessions: tunnels have their own UDP
+ * sockets. In order to control kernel tunnel features, we allow userspace to
+ * create a special "tunnel" PPPoX socket which is used for control only.
+ * Tunnel PPPoX sockets have session_id == 0 and simply allow the user
+ * application to issue L2TP setsockopt(), getsockopt() and ioctl() calls.
+ *****************************************************************************/
+
+/* Tunnel setsockopt() helper.
+ */
+static int pppol2tp_tunnel_setsockopt(struct sock *sk,
+				      struct pppol2tp_tunnel *tunnel,
+				      int optname, int val)
+{
+	int err = 0;
+
+	switch (optname) {
+	case PPPOL2TP_SO_DEBUG:
+		tunnel->debug = val;
+		PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: set debug=%x\n", tunnel->name, tunnel->debug);
+		break;
+
+	default:
+		err = -ENOPROTOOPT;
+		break;
+	}
+
+	return err;
+}
+
+/* Session setsockopt helper.
+ */
+static int pppol2tp_session_setsockopt(struct sock *sk,
+				       struct pppol2tp_session *session,
+				       int optname, int val)
+{
+	int err = 0;
+
+	switch (optname) {
+	case PPPOL2TP_SO_RECVSEQ:
+		if ((val != 0) && (val != 1)) {
+			err = -EINVAL;
+			break;
+		}
+		session->recv_seq = val ? -1 : 0;
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: set recv_seq=%d\n", session->name,
+		       session->recv_seq);
+		break;
+
+	case PPPOL2TP_SO_SENDSEQ:
+		if ((val != 0) && (val != 1)) {
+			err = -EINVAL;
+			break;
+		}
+		session->send_seq = val ? -1 : 0;
+		{
+			struct sock *ssk      = session->sock;
+			struct pppox_sock *po = pppox_sk(ssk);
+			po->chan.hdrlen = val ? PPPOL2TP_L2TP_HDR_SIZE_SEQ :
+				PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
+		}
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: set send_seq=%d\n", session->name, session->send_seq);
+		break;
+
+	case PPPOL2TP_SO_LNSMODE:
+		if ((val != 0) && (val != 1)) {
+			err = -EINVAL;
+			break;
+		}
+		session->lns_mode = val ? -1 : 0;
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: set lns_mode=%d\n", session->name,
+		       session->lns_mode);
+		break;
+
+	case PPPOL2TP_SO_DEBUG:
+		session->debug = val;
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: set debug=%x\n", session->name, session->debug);
+		break;
+
+	case PPPOL2TP_SO_REORDERTO:
+		session->reorder_timeout = msecs_to_jiffies(val);
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: set reorder_timeout=%d\n", session->name,
+		       session->reorder_timeout);
+		break;
+
+	default:
+		err = -ENOPROTOOPT;
+		break;
+	}
+
+	return err;
+}
+
+/* Main setsockopt() entry point.
+ * Does API checks, then calls either the tunnel or session setsockopt
+ * handler, according to whether the PPPoL2TP socket is a for a regular
+ * session or the special tunnel type.
+ */
+static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
+			       char __user *optval, int optlen)
+{
+	struct sock *sk = sock->sk;
+	struct pppol2tp_session *session = sk->sk_user_data;
+	struct pppol2tp_tunnel *tunnel;
+	int val;
+	int err;
+
+	if (level != SOL_PPPOL2TP)
+		return udp_prot.setsockopt(sk, level, optname, optval, optlen);
+
+	if (optlen < sizeof(int))
+		return -EINVAL;
+
+	if (get_user(val, (int __user *)optval))
+		return -EFAULT;
+
+	err = -ENOTCONN;
+	if (sk->sk_user_data == NULL)
+		goto end;
+
+	/* Get session context from the socket */
+	err = -EBADF;
+	session = pppol2tp_sock_to_session(sk);
+	if (session == NULL)
+		goto end;
+
+	/* Special case: if session_id == 0x0000, treat as operation on tunnel
+	 */
+	if ((session->tunnel_addr.s_session == 0) &&
+	    (session->tunnel_addr.d_session == 0)) {
+		err = -EBADF;
+		tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock);
+		if (tunnel == NULL)
+			goto end;
+
+		err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val);
+	} else
+		err = pppol2tp_session_setsockopt(sk, session, optname, val);
+
+	err = 0;
+
+end:
+	return err;
+}
+
+/* Tunnel getsockopt helper. Called with sock locked.
+ */
+static int pppol2tp_tunnel_getsockopt(struct sock *sk,
+				      struct pppol2tp_tunnel *tunnel,
+				      int optname, int __user *val)
+{
+	int err = 0;
+
+	switch (optname) {
+	case PPPOL2TP_SO_DEBUG:
+		*val = tunnel->debug;
+		PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: get debug=%x\n", tunnel->name, tunnel->debug);
+		break;
+
+	default:
+		err = -ENOPROTOOPT;
+		break;
+	}
+
+	return err;
+}
+
+/* Session getsockopt helper. Called with sock locked.
+ */
+static int pppol2tp_session_getsockopt(struct sock *sk,
+				       struct pppol2tp_session *session,
+				       int optname, int __user *val)
+{
+	int err = 0;
+
+	switch (optname) {
+	case PPPOL2TP_SO_RECVSEQ:
+		*val = session->recv_seq;
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: get recv_seq=%d\n", session->name, *val);
+		break;
+
+	case PPPOL2TP_SO_SENDSEQ:
+		*val = session->send_seq;
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: get send_seq=%d\n", session->name, *val);
+		break;
+
+	case PPPOL2TP_SO_LNSMODE:
+		*val = session->lns_mode;
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: get lns_mode=%d\n", session->name, *val);
+		break;
+
+	case PPPOL2TP_SO_DEBUG:
+		*val = session->debug;
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: get debug=%d\n", session->name, *val);
+		break;
+
+	case PPPOL2TP_SO_REORDERTO:
+		*val = (int) jiffies_to_msecs(session->reorder_timeout);
+		PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
+		       "%s: get reorder_timeout=%d\n", session->name, *val);
+		break;
+
+	default:
+		err = -ENOPROTOOPT;
+	}
+
+	return err;
+}
+
+/* Main getsockopt() entry point.
+ * Does API checks, then calls either the tunnel or session getsockopt
+ * handler, according to whether the PPPoX socket is a for a regular session
+ * or the special tunnel type.
+ */
+static int pppol2tp_getsockopt(struct socket *sock, int level,
+			       int optname, char __user *optval, int __user *optlen)
+{
+	struct sock *sk = sock->sk;
+	struct pppol2tp_session *session = sk->sk_user_data;
+	struct pppol2tp_tunnel *tunnel;
+	int val, len;
+	int err;
+
+	if (level != SOL_PPPOL2TP)
+		return udp_prot.getsockopt(sk, level, optname, optval, optlen);
+
+	if (get_user(len, (int __user *) optlen))
+		return -EFAULT;
+
+	len = min_t(unsigned int, len, sizeof(int));
+
+	if (len < 0)
+		return -EINVAL;
+
+	err = -ENOTCONN;
+	if (sk->sk_user_data == NULL)
+		goto end;
+
+	/* Get the session context */
+	err = -EBADF;
+	session = pppol2tp_sock_to_session(sk);
+	if (session == NULL)
+		goto end;
+
+	/* Special case: if session_id == 0x0000, treat as operation on tunnel */
+	if ((session->tunnel_addr.s_session == 0) &&
+	    (session->tunnel_addr.d_session == 0)) {
+		err = -EBADF;
+		tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock);
+		if (tunnel == NULL)
+			goto end;
+
+		err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val);
+	} else
+		err = pppol2tp_session_getsockopt(sk, session, optname, &val);
+
+	err = -EFAULT;
+	if (put_user(len, (int __user *) optlen))
+		goto end;
+
+	if (copy_to_user((void __user *) optval, &val, len))
+		goto end;
+
+	err = 0;
+end:
+	return err;
+}
+
+/*****************************************************************************
+ * /proc filesystem for debug
+ *****************************************************************************/
+
+#ifdef CONFIG_PROC_FS
+
+#include <linux/seq_file.h>
+
+struct pppol2tp_seq_data {
+	struct pppol2tp_tunnel *tunnel; /* current tunnel */
+	struct pppol2tp_session *session; /* NULL means get first session in tunnel */
+};
+
+static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, struct pppol2tp_session *curr)
+{
+	struct pppol2tp_session *session = NULL;
+	struct hlist_node *walk;
+	int found = 0;
+	int next = 0;
+	int i;
+
+	read_lock(&tunnel->hlist_lock);
+	for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) {
+		hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) {
+			if (curr == NULL) {
+				found = 1;
+				goto out;
+			}
+			if (session == curr) {
+				next = 1;
+				continue;
+			}
+			if (next) {
+				found = 1;
+				goto out;
+			}
+		}
+	}
+out:
+	read_unlock(&tunnel->hlist_lock);
+	if (!found)
+		session = NULL;
+
+	return session;
+}
+
+static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr)
+{
+	struct pppol2tp_tunnel *tunnel = NULL;
+
+	read_lock(&pppol2tp_tunnel_list_lock);
+	if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) {
+		goto out;
+	}
+	tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list);
+out:
+	read_unlock(&pppol2tp_tunnel_list_lock);
+
+	return tunnel;
+}
+
+static void *pppol2tp_seq_start(struct seq_file *m, loff_t *offs)
+{
+	struct pppol2tp_seq_data *pd = SEQ_START_TOKEN;
+	loff_t pos = *offs;
+
+	if (!pos)
+		goto out;
+
+	BUG_ON(m->private == NULL);
+	pd = m->private;
+
+	if (pd->tunnel == NULL) {
+		if (!list_empty(&pppol2tp_tunnel_list))
+			pd->tunnel = list_entry(pppol2tp_tunnel_list.next, struct pppol2tp_tunnel, list);
+	} else {
+		pd->session = next_session(pd->tunnel, pd->session);
+		if (pd->session == NULL) {
+			pd->tunnel = next_tunnel(pd->tunnel);
+		}
+	}
+
+	/* NULL tunnel and session indicates end of list */
+	if ((pd->tunnel == NULL) && (pd->session == NULL))
+		pd = NULL;
+
+out:
+	return pd;
+}
+
+static void *pppol2tp_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	(*pos)++;
+	return NULL;
+}
+
+static void pppol2tp_seq_stop(struct seq_file *p, void *v)
+{
+	/* nothing to do */
+}
+
+static void pppol2tp_seq_tunnel_show(struct seq_file *m, void *v)
+{
+	struct pppol2tp_tunnel *tunnel = v;
+
+	seq_printf(m, "\nTUNNEL '%s', %c %d\n",
+		   tunnel->name,
+		   (tunnel == tunnel->sock->sk_user_data) ? 'Y':'N',
+		   atomic_read(&tunnel->ref_count) - 1);
+	seq_printf(m, " %08x %llu/%llu/%llu %llu/%llu/%llu\n",
+		   tunnel->debug,
+		   tunnel->stats.tx_packets, tunnel->stats.tx_bytes,
+		   tunnel->stats.tx_errors,
+		   tunnel->stats.rx_packets, tunnel->stats.rx_bytes,
+		   tunnel->stats.rx_errors);
+}
+
+static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
+{
+	struct pppol2tp_session *session = v;
+
+	seq_printf(m, "  SESSION '%s' %08X/%d %04X/%04X -> "
+		   "%04X/%04X %d %c\n",
+		   session->name,
+		   ntohl(session->tunnel_addr.addr.sin_addr.s_addr),
+		   ntohs(session->tunnel_addr.addr.sin_port),
+		   session->tunnel_addr.s_tunnel,
+		   session->tunnel_addr.s_session,
+		   session->tunnel_addr.d_tunnel,
+		   session->tunnel_addr.d_session,
+		   session->sock->sk_state,
+		   (session == session->sock->sk_user_data) ?
+		   'Y' : 'N');
+	seq_printf(m, "   %d/%d/%c/%c/%s %08x %u\n",
+		   session->mtu, session->mru,
+		   session->recv_seq ? 'R' : '-',
+		   session->send_seq ? 'S' : '-',
+		   session->lns_mode ? "LNS" : "LAC",
+		   session->debug,
+		   jiffies_to_msecs(session->reorder_timeout));
+	seq_printf(m, "   %hu/%hu %llu/%llu/%llu %llu/%llu/%llu\n",
+		   session->nr, session->ns,
+		   session->stats.tx_packets,
+		   session->stats.tx_bytes,
+		   session->stats.tx_errors,
+		   session->stats.rx_packets,
+		   session->stats.rx_bytes,
+		   session->stats.rx_errors);
+}
+
+static int pppol2tp_seq_show(struct seq_file *m, void *v)
+{
+	struct pppol2tp_seq_data *pd = v;
+
+	/* display header on line 1 */
+	if (v == SEQ_START_TOKEN) {
+		seq_puts(m, "PPPoL2TP driver info, " PPPOL2TP_DRV_VERSION "\n");
+		seq_puts(m, "TUNNEL name, user-data-ok session-count\n");
+		seq_puts(m, " debug tx-pkts/bytes/errs rx-pkts/bytes/errs\n");
+		seq_puts(m, "  SESSION name, addr/port src-tid/sid "
+			 "dest-tid/sid state user-data-ok\n");
+		seq_puts(m, "   mtu/mru/rcvseq/sendseq/lns debug reorderto\n");
+		seq_puts(m, "   nr/ns tx-pkts/bytes/errs rx-pkts/bytes/errs\n");
+		goto out;
+	}
+
+	/* Show the tunnel or session context.
+	 */
+	if (pd->session == NULL)
+		pppol2tp_seq_tunnel_show(m, pd->tunnel);
+	else
+		pppol2tp_seq_session_show(m, pd->session);
+
+out:
+	return 0;
+}
+
+static struct seq_operations pppol2tp_seq_ops = {
+	.start		= pppol2tp_seq_start,
+	.next		= pppol2tp_seq_next,
+	.stop		= pppol2tp_seq_stop,
+	.show		= pppol2tp_seq_show,
+};
+
+/* Called when our /proc file is opened. We allocate data for use when
+ * iterating our tunnel / session contexts and store it in the private
+ * data of the seq_file.
+ */
+static int pppol2tp_proc_open(struct inode *inode, struct file *file)
+{
+	struct seq_file *m;
+	struct pppol2tp_seq_data *pd;
+	int ret = 0;
+
+	ret = seq_open(file, &pppol2tp_seq_ops);
+	if (ret < 0)
+		goto out;
+
+	m = file->private_data;
+
+	/* Allocate and fill our proc_data for access later */
+	ret = -ENOMEM;
+	m->private = kzalloc(sizeof(struct pppol2tp_seq_data), GFP_KERNEL);
+	if (m->private == NULL)
+		goto out;
+
+	pd = m->private;
+	ret = 0;
+
+out:
+	return ret;
+}
+
+/* Called when /proc file access completes.
+ */
+static int pppol2tp_proc_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *m = (struct seq_file *)file->private_data;
+
+	kfree(m->private);
+	m->private = NULL;
+
+	return seq_release(inode, file);
+}
+
+static struct file_operations pppol2tp_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= pppol2tp_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= pppol2tp_proc_release,
+};
+
+static struct proc_dir_entry *pppol2tp_proc;
+
+#endif /* CONFIG_PROC_FS */
+
+/*****************************************************************************
+ * Init and cleanup
+ *****************************************************************************/
+
+static struct proto_ops pppol2tp_ops = {
+	.family		= AF_PPPOX,
+	.owner		= THIS_MODULE,
+	.release	= pppol2tp_release,
+	.bind		= sock_no_bind,
+	.connect	= pppol2tp_connect,
+	.socketpair	= sock_no_socketpair,
+	.accept		= sock_no_accept,
+	.getname	= pppol2tp_getname,
+	.poll		= datagram_poll,
+	.listen		= sock_no_listen,
+	.shutdown	= sock_no_shutdown,
+	.setsockopt	= pppol2tp_setsockopt,
+	.getsockopt	= pppol2tp_getsockopt,
+	.sendmsg	= pppol2tp_sendmsg,
+	.recvmsg	= pppol2tp_recvmsg,
+	.mmap		= sock_no_mmap,
+	.ioctl		= pppox_ioctl,
+};
+
+static struct pppox_proto pppol2tp_proto = {
+	.create		= pppol2tp_create,
+	.ioctl		= pppol2tp_ioctl
+};
+
+static int __init pppol2tp_init(void)
+{
+	int err;
+
+	err = proto_register(&pppol2tp_sk_proto, 0);
+	if (err)
+		goto out;
+	err = register_pppox_proto(PX_PROTO_OL2TP, &pppol2tp_proto);
+	if (err)
+		goto out_unregister_pppol2tp_proto;
+
+#ifdef CONFIG_PROC_FS
+	pppol2tp_proc = create_proc_entry("pppol2tp", 0, proc_net);
+	if (!pppol2tp_proc) {
+		err = -ENOMEM;
+		goto out_unregister_pppox_proto;
+	}
+	pppol2tp_proc->proc_fops = &pppol2tp_proc_fops;
+#endif /* CONFIG_PROC_FS */
+	printk(KERN_INFO "PPPoL2TP kernel driver, %s\n",
+	       PPPOL2TP_DRV_VERSION);
+
+out:
+	return err;
+
+out_unregister_pppox_proto:
+	unregister_pppox_proto(PX_PROTO_OL2TP);
+out_unregister_pppol2tp_proto:
+	proto_unregister(&pppol2tp_sk_proto);
+	goto out;
+}
+
+static void __exit pppol2tp_exit(void)
+{
+	unregister_pppox_proto(PX_PROTO_OL2TP);
+
+#ifdef CONFIG_PROC_FS
+	remove_proc_entry("pppol2tp", proc_net);
+#endif
+	proto_unregister(&pppol2tp_sk_proto);
+}
+
+module_init(pppol2tp_init);
+module_exit(pppol2tp_exit);
+
+MODULE_AUTHOR("Martijn van Oosterhout <kleptog@svana.org>,"
+	      "James Chapman <jchapman@katalix.com>");
+MODULE_DESCRIPTION("PPP over L2TP over UDP");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(PPPOL2TP_DRV_VERSION);
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
index ad94358..451486b 100644
--- a/drivers/net/saa9730.c
+++ b/drivers/net/saa9730.c
@@ -690,9 +690,9 @@
 				lp->stats.rx_packets++;
 				skb_reserve(skb, 2);	/* 16 byte align */
 				skb_put(skb, len);	/* make room */
-				eth_copy_and_sum(skb,
+				skb_copy_to_linear_data(skb,
 						 (unsigned char *) pData,
-						 len, 0);
+						 len);
 				skb->protocol = eth_type_trans(skb, dev);
 				netif_rx(skb);
 				dev->last_rx = jiffies;
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 2106bec..384b468 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -320,7 +320,7 @@
 				skb_put(skb, len);
 
 				/* Copy out of kseg1 to avoid silly cache flush. */
-				eth_copy_and_sum(skb, pkt_pointer + 2, len, 0);
+				skb_copy_to_linear_data(skb, pkt_pointer + 2, len);
 				skb->protocol = eth_type_trans(skb, dev);
 
 				/* We don't want to receive our own packets */
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index bc8de48..ec2ad9f 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -548,7 +548,7 @@
 		skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
 		if (skb) {
 			skb_reserve(skb, NET_IP_ALIGN);
-			eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
+			skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size);
 			*sk_buff = skb;
 			sis190_give_to_asic(desc, rx_buf_sz);
 			ret = 0;
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 2f69d5c..8b64786 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -1456,7 +1456,7 @@
 			pci_dma_sync_single_for_cpu(np->pci_dev,
 						    np->rx_info[entry].mapping,
 						    pkt_len, PCI_DMA_FROMDEVICE);
-			eth_copy_and_sum(skb, np->rx_info[entry].skb->data, pkt_len, 0);
+			skb_copy_to_linear_data(skb, np->rx_info[entry].skb->data, pkt_len);
 			pci_dma_sync_single_for_device(np->pci_dev,
 						       np->rx_info[entry].mapping,
 						       pkt_len, PCI_DMA_FROMDEVICE);
diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c
index a123ea8..b77ab6e 100644
--- a/drivers/net/sun3_82586.c
+++ b/drivers/net/sun3_82586.c
@@ -777,7 +777,7 @@
 					{
 						skb_reserve(skb,2);
 						skb_put(skb,totlen);
-						eth_copy_and_sum(skb,(char *) p->base+swab32((unsigned long) rbd->buffer),totlen,0);
+						skb_copy_to_linear_data(skb,(char *) p->base+swab32((unsigned long) rbd->buffer),totlen);
 						skb->protocol=eth_type_trans(skb,dev);
 						netif_rx(skb);
 						p->stats.rx_packets++;
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index 791e081..f1548c0 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -853,10 +853,9 @@
 
 				skb_reserve( skb, 2 );	/* 16 byte align */
 				skb_put( skb, pkt_len );	/* Make room */
-//			        skb_copy_to_linear_data(skb, PKTBUF_ADDR(head), pkt_len);
-				eth_copy_and_sum(skb,
+				skb_copy_to_linear_data(skb,
 						 PKTBUF_ADDR(head),
-						 pkt_len, 0);
+						 pkt_len);
 
 				skb->protocol = eth_type_trans( skb, dev );
 				netif_rx( skb );
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index 2ad8d58..b3e0158 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -860,7 +860,7 @@
 			sbus_dma_sync_single_for_cpu(bp->bigmac_sdev,
 						     this->rx_addr, len,
 						     SBUS_DMA_FROMDEVICE);
-			eth_copy_and_sum(copy_skb, (unsigned char *)skb->data, len, 0);
+			skb_copy_to_linear_data(copy_skb, (unsigned char *)skb->data, len);
 			sbus_dma_sync_single_for_device(bp->bigmac_sdev,
 							this->rx_addr, len,
 							SBUS_DMA_FROMDEVICE);
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index c9f7b7a..af0c983 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -1310,7 +1310,7 @@
 							    np->rx_buf_sz,
 							    PCI_DMA_FROMDEVICE);
 
-				eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0);
+				skb_copy_to_linear_data(skb, np->rx_skbuff[entry]->data, pkt_len);
 				pci_dma_sync_single_for_device(np->pci_dev,
 							       desc->frag[0].addr,
 							       np->rx_buf_sz,
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 4272253..053b7cb 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -549,9 +549,9 @@
 
 			skb_reserve(skb, 2);		/* 16 byte align */
 			skb_put(skb, len);		/* make room */
-			eth_copy_and_sum(skb,
+			skb_copy_to_linear_data(skb,
 					 (unsigned char *)&(ib->rx_buf [entry][0]),
-					 len, 0);
+					 len);
 			skb->protocol = eth_type_trans(skb, dev);
 			netif_rx(skb);
 			dev->last_rx = jiffies;
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index fa70e0b..1b65ae8 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -439,8 +439,8 @@
 			} else {
 				skb_reserve(skb, 2);
 				skb_put(skb, len);
-				eth_copy_and_sum(skb, (unsigned char *) this_qbuf,
-						 len, 0);
+				skb_copy_to_linear_data(skb, (unsigned char *) this_qbuf,
+						 len);
 				skb->protocol = eth_type_trans(skb, qep->dev);
 				netif_rx(skb);
 				qep->dev->last_rx = jiffies;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index b148d57..32e4037 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -64,8 +64,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.77"
-#define DRV_MODULE_RELDATE	"May 31, 2007"
+#define DRV_MODULE_VERSION	"3.78"
+#define DRV_MODULE_RELDATE	"July 11, 2007"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -721,6 +721,44 @@
 	return ret;
 }
 
+static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
+{
+	u32 phy;
+
+	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
+	    (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+		return;
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+		u32 ephy;
+
+		if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &ephy)) {
+			tg3_writephy(tp, MII_TG3_EPHY_TEST,
+				     ephy | MII_TG3_EPHY_SHADOW_EN);
+			if (!tg3_readphy(tp, MII_TG3_EPHYTST_MISCCTRL, &phy)) {
+				if (enable)
+					phy |= MII_TG3_EPHYTST_MISCCTRL_MDIX;
+				else
+					phy &= ~MII_TG3_EPHYTST_MISCCTRL_MDIX;
+				tg3_writephy(tp, MII_TG3_EPHYTST_MISCCTRL, phy);
+			}
+			tg3_writephy(tp, MII_TG3_EPHY_TEST, ephy);
+		}
+	} else {
+		phy = MII_TG3_AUXCTL_MISC_RDSEL_MISC |
+		      MII_TG3_AUXCTL_SHDWSEL_MISC;
+		if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, phy) &&
+		    !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy)) {
+			if (enable)
+				phy |= MII_TG3_AUXCTL_MISC_FORCE_AMDIX;
+			else
+				phy &= ~MII_TG3_AUXCTL_MISC_FORCE_AMDIX;
+			phy |= MII_TG3_AUXCTL_MISC_WREN;
+			tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
+		}
+	}
+}
+
 static void tg3_phy_set_wirespeed(struct tg3 *tp)
 {
 	u32 val;
@@ -1045,23 +1083,11 @@
 	}
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-		u32 phy_reg;
-
 		/* adjust output voltage */
 		tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x12);
-
-		if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phy_reg)) {
-			u32 phy_reg2;
-
-			tg3_writephy(tp, MII_TG3_EPHY_TEST,
-				     phy_reg | MII_TG3_EPHY_SHADOW_EN);
-			/* Enable auto-MDIX */
-			if (!tg3_readphy(tp, 0x10, &phy_reg2))
-				tg3_writephy(tp, 0x10, phy_reg2 | 0x4000);
-			tg3_writephy(tp, MII_TG3_EPHY_TEST, phy_reg);
-		}
 	}
 
+	tg3_phy_toggle_automdix(tp, 1);
 	tg3_phy_set_wirespeed(tp);
 	return 0;
 }
@@ -1162,6 +1188,19 @@
 	}
 }
 
+static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed)
+{
+	if (tp->led_ctrl == LED_CTRL_MODE_PHY_2)
+		return 1;
+	else if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411) {
+		if (speed != SPEED_10)
+			return 1;
+	} else if (speed == SPEED_10)
+		return 1;
+
+	return 0;
+}
+
 static int tg3_setup_phy(struct tg3 *, int);
 
 #define RESET_KIND_SHUTDOWN	0
@@ -1320,9 +1359,17 @@
 			else
 				mac_mode = MAC_MODE_PORT_MODE_MII;
 
-			if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 ||
-			    !(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB))
-				mac_mode |= MAC_MODE_LINK_POLARITY;
+			mac_mode |= tp->mac_mode & MAC_MODE_LINK_POLARITY;
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+			    ASIC_REV_5700) {
+				u32 speed = (tp->tg3_flags &
+					     TG3_FLAG_WOL_SPEED_100MB) ?
+					     SPEED_100 : SPEED_10;
+				if (tg3_5700_link_polarity(tp, speed))
+					mac_mode |= MAC_MODE_LINK_POLARITY;
+				else
+					mac_mode &= ~MAC_MODE_LINK_POLARITY;
+			}
 		} else {
 			mac_mode = MAC_MODE_PORT_MODE_TBI;
 		}
@@ -1990,15 +2037,12 @@
 	if (tp->link_config.active_duplex == DUPLEX_HALF)
 		tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
 
-	tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
-		if ((tp->led_ctrl == LED_CTRL_MODE_PHY_2) ||
-		    (current_link_up == 1 &&
-		     tp->link_config.active_speed == SPEED_10))
+		if (current_link_up == 1 &&
+		    tg3_5700_link_polarity(tp, tp->link_config.active_speed))
 			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
-	} else {
-		if (current_link_up == 1)
-			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
+		else
+			tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
 	}
 
 	/* ??? Without this setting Netgear GA302T PHY does not
@@ -2639,6 +2683,9 @@
 
 		tw32_f(MAC_MODE, (tp->mac_mode | MAC_MODE_SEND_CONFIGS));
 		udelay(40);
+
+		tw32_f(MAC_MODE, tp->mac_mode);
+		udelay(40);
 	}
 
 out:
@@ -2698,10 +2745,6 @@
 	else
 		current_link_up = tg3_setup_fiber_by_hand(tp, mac_status);
 
-	tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
-	tw32_f(MAC_MODE, tp->mac_mode);
-	udelay(40);
-
 	tp->hw_status->status =
 		(SD_STATUS_UPDATED |
 		 (tp->hw_status->status & ~SD_STATUS_LINK_CHG));
@@ -3512,9 +3555,9 @@
  */
 static inline void tg3_full_lock(struct tg3 *tp, int irq_sync)
 {
+	spin_lock_bh(&tp->lock);
 	if (irq_sync)
 		tg3_irq_quiesce(tp);
-	spin_lock_bh(&tp->lock);
 }
 
 static inline void tg3_full_unlock(struct tg3 *tp)
@@ -6444,6 +6487,10 @@
 
 	tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
 		MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
+	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+	    !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)
+		tp->mac_mode |= MAC_MODE_LINK_POLARITY;
 	tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR);
 	udelay(40);
 
@@ -8805,7 +8852,9 @@
 			return 0;
 
 		mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
-			   MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY;
+			   MAC_MODE_PORT_INT_LPBACK;
+		if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+			mac_mode |= MAC_MODE_LINK_POLARITY;
 		if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
 			mac_mode |= MAC_MODE_PORT_MODE_MII;
 		else
@@ -8824,19 +8873,18 @@
 					     phytest | MII_TG3_EPHY_SHADOW_EN);
 				if (!tg3_readphy(tp, 0x1b, &phy))
 					tg3_writephy(tp, 0x1b, phy & ~0x20);
-				if (!tg3_readphy(tp, 0x10, &phy))
-					tg3_writephy(tp, 0x10, phy & ~0x4000);
 				tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest);
 			}
 			val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100;
 		} else
 			val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000;
 
+		tg3_phy_toggle_automdix(tp, 0);
+
 		tg3_writephy(tp, MII_BMCR, val);
 		udelay(40);
 
-		mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
-			   MAC_MODE_LINK_POLARITY;
+		mac_mode = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
 			tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x1800);
 			mac_mode |= MAC_MODE_PORT_MODE_MII;
@@ -8849,8 +8897,11 @@
 			udelay(10);
 			tw32_f(MAC_RX_MODE, tp->rx_mode);
 		}
-		if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
-			mac_mode &= ~MAC_MODE_LINK_POLARITY;
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
+			if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)
+				mac_mode &= ~MAC_MODE_LINK_POLARITY;
+			else if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411)
+				mac_mode |= MAC_MODE_LINK_POLARITY;
 			tg3_writephy(tp, MII_TG3_EXT_CTRL,
 				     MII_TG3_EXT_CTRL_LNK3_LED_MODE);
 		}
@@ -9116,10 +9167,10 @@
 	/* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */
 	__tg3_set_rx_mode(dev);
 
-	tg3_full_unlock(tp);
-
 	if (netif_running(dev))
 		tg3_netif_start(tp);
+
+	tg3_full_unlock(tp);
 }
 #endif
 
@@ -9410,11 +9461,13 @@
 		case FLASH_5755VENDOR_ATMEL_FLASH_1:
 		case FLASH_5755VENDOR_ATMEL_FLASH_2:
 		case FLASH_5755VENDOR_ATMEL_FLASH_3:
+		case FLASH_5755VENDOR_ATMEL_FLASH_5:
 			tp->nvram_jedecnum = JEDEC_ATMEL;
 			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
 			tp->tg3_flags2 |= TG3_FLG2_FLASH;
 			tp->nvram_pagesize = 264;
-			if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1)
+			if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
+			    nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
 				tp->nvram_size = (protect ? 0x3e200 : 0x80000);
 			else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2)
 				tp->nvram_size = (protect ? 0x1f200 : 0x40000);
@@ -11940,12 +11993,11 @@
 	 * checksumming.
 	 */
 	if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) {
+		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
-			dev->features |= NETIF_F_HW_CSUM;
-		else
-			dev->features |= NETIF_F_IP_CSUM;
-		dev->features |= NETIF_F_SG;
+			dev->features |= NETIF_F_IPV6_CSUM;
+
 		tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
 	} else
 		tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index bd9f4f4..d84e75e 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1467,6 +1467,7 @@
 #define  FLASH_5755VENDOR_ATMEL_FLASH_2	 0x03400002
 #define  FLASH_5755VENDOR_ATMEL_FLASH_3	 0x03400000
 #define  FLASH_5755VENDOR_ATMEL_FLASH_4	 0x00000003
+#define  FLASH_5755VENDOR_ATMEL_FLASH_5	 0x02000003
 #define  FLASH_5755VENDOR_ATMEL_EEPROM_64KHZ	 0x03c00003
 #define  FLASH_5755VENDOR_ATMEL_EEPROM_376KHZ	 0x03c00002
 #define  FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ	 0x03000003
@@ -1642,6 +1643,11 @@
 
 #define MII_TG3_AUX_CTRL		0x18 /* auxilliary control register */
 
+#define MII_TG3_AUXCTL_MISC_WREN	0x8000
+#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX	0x0200
+#define MII_TG3_AUXCTL_MISC_RDSEL_MISC	0x7000
+#define MII_TG3_AUXCTL_SHDWSEL_MISC		0x0007
+
 #define MII_TG3_AUX_STAT		0x19 /* auxilliary status register */
 #define MII_TG3_AUX_STAT_LPASS		0x0004
 #define MII_TG3_AUX_STAT_SPDMASK	0x0700
@@ -1667,6 +1673,9 @@
 #define MII_TG3_EPHY_TEST		0x1f /* 5906 PHY register */
 #define MII_TG3_EPHY_SHADOW_EN		0x80
 
+#define MII_TG3_EPHYTST_MISCCTRL	0x10 /* 5906 EPHY misc ctrl shadow register */
+#define MII_TG3_EPHYTST_MISCCTRL_MDIX	0x4000
+
 #define MII_TG3_TEST1			0x1e
 #define MII_TG3_TEST1_TRIM_EN		0x0010
 #define MII_TG3_TEST1_CRC_EN		0x8000
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index ea89677..53efd66 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -197,8 +197,8 @@
 								   tp->rx_buffers[entry].mapping,
 								   pkt_len, PCI_DMA_FROMDEVICE);
 #if ! defined(__alpha__)
-                                       eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data,
-                                                        pkt_len, 0);
+                                       skb_copy_to_linear_data(skb, tp->rx_buffers[entry].skb->data,
+                                                        pkt_len);
                                        skb_put(skb, pkt_len);
 #else
                                        memcpy(skb_put(skb, pkt_len),
@@ -420,8 +420,8 @@
 							    tp->rx_buffers[entry].mapping,
 							    pkt_len, PCI_DMA_FROMDEVICE);
 #if ! defined(__alpha__)
-				eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data,
-						 pkt_len, 0);
+				skb_copy_to_linear_data(skb, tp->rx_buffers[entry].skb->data,
+						 pkt_len);
 				skb_put(skb, pkt_len);
 #else
 				memcpy(skb_put(skb, pkt_len),
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 38f3b99..5824f6a 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -1232,7 +1232,7 @@
 				pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry],
 							    np->rx_skbuff[entry]->len,
 							    PCI_DMA_FROMDEVICE);
-				eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0);
+				skb_copy_to_linear_data(skb, np->rx_skbuff[entry]->data, pkt_len);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry],
 							       np->rx_skbuff[entry]->len,
diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
index 79943cd..16a54e6 100644
--- a/drivers/net/tulip/xircom_cb.c
+++ b/drivers/net/tulip/xircom_cb.c
@@ -1205,7 +1205,7 @@
 				goto out;
 			}
 			skb_reserve(skb, 2);
-			eth_copy_and_sum(skb, (unsigned char*)&card->rx_buffer[bufferoffset / 4], pkt_len, 0);
+			skb_copy_to_linear_data(skb, (unsigned char*)&card->rx_buffer[bufferoffset / 4], pkt_len);
 			skb_put(skb, pkt_len);
 			skb->protocol = eth_type_trans(skb, dev);
 			netif_rx(skb);
diff --git a/drivers/net/tulip/xircom_tulip_cb.c b/drivers/net/tulip/xircom_tulip_cb.c
index 83d69f1..fc439f3 100644
--- a/drivers/net/tulip/xircom_tulip_cb.c
+++ b/drivers/net/tulip/xircom_tulip_cb.c
@@ -1240,8 +1240,8 @@
 				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
 #if ! defined(__alpha__)
-				eth_copy_and_sum(skb, bus_to_virt(tp->rx_ring[entry].buffer1),
-								 pkt_len, 0);
+				skb_copy_to_linear_data(skb, bus_to_virt(tp->rx_ring[entry].buffer1),
+								 pkt_len);
 				skb_put(skb, pkt_len);
 #else
 				memcpy(skb_put(skb, pkt_len),
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index a2c6caa..62b2b30 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -432,6 +432,7 @@
 	init_waitqueue_head(&tun->read_wait);
 
 	tun->owner = -1;
+	tun->group = -1;
 
 	SET_MODULE_OWNER(dev);
 	dev->open = tun_net_open;
@@ -467,8 +468,11 @@
 			return -EBUSY;
 
 		/* Check permissions */
-		if (tun->owner != -1 &&
-		    current->euid != tun->owner && !capable(CAP_NET_ADMIN))
+		if (((tun->owner != -1 &&
+		      current->euid != tun->owner) ||
+		     (tun->group != -1 &&
+		      current->egid != tun->group)) &&
+		     !capable(CAP_NET_ADMIN))
 			return -EPERM;
 	}
 	else if (__dev_get_by_name(ifr->ifr_name))
@@ -610,6 +614,13 @@
 		DBG(KERN_INFO "%s: owner set to %d\n", tun->dev->name, tun->owner);
 		break;
 
+	case TUNSETGROUP:
+		/* Set group of the device */
+		tun->group= (gid_t) arg;
+
+		DBG(KERN_INFO "%s: group set to %d\n", tun->dev->name, tun->group);
+		break;
+
 	case TUNSETLINK:
 		/* Only allow setting the type when the interface is down */
 		if (tun->dev->flags & IFF_UP) {
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 0f2c061..0358720 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -1703,7 +1703,7 @@
 			pci_dma_sync_single_for_cpu(tp->pdev, dma_addr,
 						    PKT_BUF_SZ,
 						    PCI_DMA_FROMDEVICE);
-			eth_copy_and_sum(new_skb, skb->data, pkt_len, 0);
+			skb_copy_to_linear_data(new_skb, skb->data, pkt_len);
 			pci_dma_sync_single_for_device(tp->pdev, dma_addr,
 						       PKT_BUF_SZ,
 						       PCI_DMA_FROMDEVICE);
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 86e90c5..76752d84 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -255,7 +255,7 @@
 		if (!(skb = dev_alloc_skb(pkt_len)))
 			return;
 
-		eth_copy_and_sum(skb, pkt_start + pkt_offset, pkt_len, 0);
+		skb_copy_to_linear_data(skb, pkt_start + pkt_offset, pkt_len);
 		skb_put(skb, pkt_len);
 
 		skb->protocol = eth_type_trans(skb, catc->netdev);
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index 60d2944..524dc5f 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -635,7 +635,7 @@
 
 		skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
 
-		eth_copy_and_sum(skb, kaweth->rx_buf + 2, pkt_len, 0);
+		skb_copy_to_linear_data(skb, kaweth->rx_buf + 2, pkt_len);
 
 		skb_put(skb, pkt_len);
 
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 73e9c3d..f51c2c1 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -1489,9 +1489,9 @@
 							    rp->rx_buf_sz,
 							    PCI_DMA_FROMDEVICE);
 
-				eth_copy_and_sum(skb,
+				skb_copy_to_linear_data(skb,
 						 rp->rx_skbuff[entry]->data,
-						 pkt_len, 0);
+						 pkt_len);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(rp->pdev,
 							       rp->rx_skbuff_dma[entry],
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index ce9230b..c8b5c22 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1011,7 +1011,7 @@
 	} else {
 		skb->dev = dev;
 		skb_reserve(skb, 2); /* IP headers on 16 bytes boundaries */
-		eth_copy_and_sum(skb, (unsigned char *)&sig.daddr, 12, 0);
+		skb_copy_to_linear_data(skb, (unsigned char *)&sig.daddr, 12);
 		wl3501_receive(this, skb->data, pkt_len);
 		skb_put(skb, pkt_len);
 		skb->protocol	= eth_type_trans(skb, dev);
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index f2a90a7..870c539 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -1137,7 +1137,7 @@
 				if (skb == NULL)
 					break;
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
-				eth_copy_and_sum(skb, rx_skb->data, pkt_len, 0);
+				skb_copy_to_linear_data(skb, rx_skb->data, pkt_len);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(yp->pci_dev, desc->addr,
 											   yp->rx_buf_sz,
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
index 924ef06..fc4bde2 100644
--- a/drivers/parisc/pdc_stable.c
+++ b/drivers/parisc/pdc_stable.c
@@ -121,14 +121,14 @@
 
 #define PDCS_ATTR(_name, _mode, _show, _store) \
 struct subsys_attribute pdcs_attr_##_name = { \
-	.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+	.attr = {.name = __stringify(_name), .mode = _mode}, \
 	.show = _show, \
 	.store = _store, \
 };
 
 #define PATHS_ATTR(_name, _mode, _show, _store) \
 struct pdcspath_attribute paths_attr_##_name = { \
-	.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+	.attr = {.name = __stringify(_name), .mode = _mode}, \
 	.show = _show, \
 	.store = _store, \
 };
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index e7322c2..70db38c 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -106,7 +106,8 @@
 static void ibm_handle_events(acpi_handle handle, u32 event, void *context);
 static int ibm_get_table_from_acpi(char **bufp);
 static ssize_t ibm_read_apci_table(struct kobject *kobj,
-		char *buffer, loff_t pos, size_t size);
+				   struct bin_attribute *bin_attr,
+				   char *buffer, loff_t pos, size_t size);
 static acpi_status __init ibm_find_acpi_device(acpi_handle handle,
 		u32 lvl, void *context, void **rv);
 static int __init ibm_acpiphp_init(void);
@@ -117,7 +118,6 @@
 static struct bin_attribute ibm_apci_table_attr = {
 	    .attr = {
 		    .name = "apci_table",
-		    .owner = THIS_MODULE,
 		    .mode = S_IRUGO,
 	    },
 	    .read = ibm_read_apci_table,
@@ -358,7 +358,8 @@
  * our solution is to only allow reading the table in all at once
  **/
 static ssize_t ibm_read_apci_table(struct kobject *kobj,
-		char *buffer, loff_t pos, size_t size)
+				   struct bin_attribute *bin_attr,
+				   char *buffer, loff_t pos, size_t size)
 {
 	int bytes_read = -EINVAL;
 	char *table = NULL;
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 9c4a123..10dbdec 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -213,7 +213,8 @@
 };
 
 static ssize_t
-pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+pci_read_config(struct kobject *kobj, struct bin_attribute *bin_attr,
+		char *buf, loff_t off, size_t count)
 {
 	struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
 	unsigned int size = 64;
@@ -285,7 +286,8 @@
 }
 
 static ssize_t
-pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+pci_write_config(struct kobject *kobj, struct bin_attribute *bin_attr,
+		 char *buf, loff_t off, size_t count)
 {
 	struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
 	unsigned int size = count;
@@ -352,7 +354,8 @@
  * callback routine (pci_legacy_read).
  */
 ssize_t
-pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
+pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
+		   char *buf, loff_t off, size_t count)
 {
         struct pci_bus *bus = to_pci_bus(container_of(kobj,
                                                       struct class_device,
@@ -376,7 +379,8 @@
  * callback routine (pci_legacy_write).
  */
 ssize_t
-pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count)
+pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
+		    char *buf, loff_t off, size_t count)
 {
         struct pci_bus *bus = to_pci_bus(container_of(kobj,
 						      struct class_device,
@@ -499,7 +503,6 @@
 			sprintf(res_attr_name, "resource%d", i);
 			res_attr->attr.name = res_attr_name;
 			res_attr->attr.mode = S_IRUSR | S_IWUSR;
-			res_attr->attr.owner = THIS_MODULE;
 			res_attr->size = pci_resource_len(pdev, i);
 			res_attr->mmap = pci_mmap_resource;
 			res_attr->private = &pdev->resource[i];
@@ -529,7 +532,8 @@
  * writing anything except 0 enables it
  */
 static ssize_t
-pci_write_rom(struct kobject *kobj, char *buf, loff_t off, size_t count)
+pci_write_rom(struct kobject *kobj, struct bin_attribute *bin_attr,
+	      char *buf, loff_t off, size_t count)
 {
 	struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
 
@@ -552,7 +556,8 @@
  * device corresponding to @kobj.
  */
 static ssize_t
-pci_read_rom(struct kobject *kobj, char *buf, loff_t off, size_t count)
+pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr,
+	     char *buf, loff_t off, size_t count)
 {
 	struct pci_dev *pdev = to_pci_dev(container_of(kobj, struct device, kobj));
 	void __iomem *rom;
@@ -582,7 +587,6 @@
 	.attr =	{
 		.name = "config",
 		.mode = S_IRUGO | S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = 256,
 	.read = pci_read_config,
@@ -593,7 +597,6 @@
 	.attr =	{
 		.name = "config",
 		.mode = S_IRUGO | S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = 4096,
 	.read = pci_read_config,
@@ -633,7 +636,6 @@
 			rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
 			rom_attr->attr.name = "rom";
 			rom_attr->attr.mode = S_IRUSR;
-			rom_attr->attr.owner = THIS_MODULE;
 			rom_attr->read = pci_read_rom;
 			rom_attr->write = pci_write_rom;
 			retval = sysfs_create_bin_file(&pdev->dev.kobj, rom_attr);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 8802fcb..a7bce75 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -39,7 +39,6 @@
 		b->legacy_io->attr.name = "legacy_io";
 		b->legacy_io->size = 0xffff;
 		b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
-		b->legacy_io->attr.owner = THIS_MODULE;
 		b->legacy_io->read = pci_read_legacy_io;
 		b->legacy_io->write = pci_write_legacy_io;
 		class_device_create_bin_file(&b->class_dev, b->legacy_io);
@@ -49,7 +48,6 @@
 		b->legacy_mem->attr.name = "legacy_mem";
 		b->legacy_mem->size = 1024*1024;
 		b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
-		b->legacy_mem->attr.owner = THIS_MODULE;
 		b->legacy_mem->mmap = pci_mmap_legacy_mem;
 		class_device_create_bin_file(&b->class_dev, b->legacy_mem);
 	}
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index a2bb465..b440900 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -283,7 +283,9 @@
 	return (ret);
 }
 
-static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t pccard_show_cis(struct kobject *kobj,
+			       struct bin_attribute *bin_attr,
+			       char *buf, loff_t off, size_t count)
 {
 	unsigned int size = 0x200;
 
@@ -311,7 +313,9 @@
 	return (count);
 }
 
-static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t pccard_store_cis(struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
 {
 	struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj));
 	cisdump_t *cis;
@@ -366,7 +370,7 @@
 };
 
 static struct bin_attribute pccard_cis_attr = {
-	.attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR, .owner = THIS_MODULE},
+	.attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR },
 	.size = 0x200,
 	.read = pccard_show_cis,
 	.write = pccard_store_cis,
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index eed9143..659e311 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -67,7 +67,8 @@
 };
 
 static ssize_t
-rio_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+rio_read_config(struct kobject *kobj, struct bin_attribute *bin_attr,
+		char *buf, loff_t off, size_t count)
 {
 	struct rio_dev *dev =
 	    to_rio_dev(container_of(kobj, struct device, kobj));
@@ -137,7 +138,8 @@
 }
 
 static ssize_t
-rio_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+rio_write_config(struct kobject *kobj, struct bin_attribute *bin_attr,
+		 char *buf, loff_t off, size_t count)
 {
 	struct rio_dev *dev =
 	    to_rio_dev(container_of(kobj, struct device, kobj));
@@ -197,7 +199,6 @@
 	.attr = {
 		 .name = "config",
 		 .mode = S_IRUGO | S_IWUSR,
-		 .owner = THIS_MODULE,
 		 },
 	.size = 0x200000,
 	.read = rio_read_config,
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index afa64c7..f98a83a1 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -258,8 +258,9 @@
 	.ioctl		= ds1553_rtc_ioctl,
 };
 
-static ssize_t ds1553_nvram_read(struct kobject *kobj, char *buf,
-				 loff_t pos, size_t size)
+static ssize_t ds1553_nvram_read(struct kobject *kobj,
+				 struct bin_attribute *bin_attr,
+				 char *buf, loff_t pos, size_t size)
 {
 	struct platform_device *pdev =
 		to_platform_device(container_of(kobj, struct device, kobj));
@@ -272,8 +273,9 @@
 	return count;
 }
 
-static ssize_t ds1553_nvram_write(struct kobject *kobj, char *buf,
-				  loff_t pos, size_t size)
+static ssize_t ds1553_nvram_write(struct kobject *kobj,
+				  struct bin_attribute *bin_attr,
+				  char *buf, loff_t pos, size_t size)
 {
 	struct platform_device *pdev =
 		to_platform_device(container_of(kobj, struct device, kobj));
@@ -290,7 +292,6 @@
 	.attr = {
 		.name = "nvram",
 		.mode = S_IRUGO | S_IWUGO,
-		.owner = THIS_MODULE,
 	},
 	.size = RTC_OFFSET,
 	.read = ds1553_nvram_read,
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index d68288b..d1778ae 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -127,8 +127,9 @@
 	.set_time	= ds1742_rtc_set_time,
 };
 
-static ssize_t ds1742_nvram_read(struct kobject *kobj, char *buf,
-				 loff_t pos, size_t size)
+static ssize_t ds1742_nvram_read(struct kobject *kobj,
+				 struct bin_attribute *bin_attr,
+				 char *buf, loff_t pos, size_t size)
 {
 	struct platform_device *pdev =
 		to_platform_device(container_of(kobj, struct device, kobj));
@@ -141,8 +142,9 @@
 	return count;
 }
 
-static ssize_t ds1742_nvram_write(struct kobject *kobj, char *buf,
-				  loff_t pos, size_t size)
+static ssize_t ds1742_nvram_write(struct kobject *kobj,
+				  struct bin_attribute *bin_attr,
+				  char *buf, loff_t pos, size_t size)
 {
 	struct platform_device *pdev =
 		to_platform_device(container_of(kobj, struct device, kobj));
@@ -159,7 +161,6 @@
 	.attr = {
 		.name = "nvram",
 		.mode = S_IRUGO | S_IWUGO,
-		.owner = THIS_MODULE,
 	},
 	.read = ds1742_nvram_read,
 	.write = ds1742_nvram_write,
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index af7596e..ce2f78d 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -17,10 +17,11 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include <linux/err.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
@@ -30,25 +31,11 @@
 #include <asm/div64.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <asm/vr41xx/irq.h>
 
 MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>");
 MODULE_DESCRIPTION("NEC VR4100 series RTC driver");
 MODULE_LICENSE("GPL");
 
-#define RTC1_TYPE1_START	0x0b0000c0UL
-#define RTC1_TYPE1_END		0x0b0000dfUL
-#define RTC2_TYPE1_START	0x0b0001c0UL
-#define RTC2_TYPE1_END		0x0b0001dfUL
-
-#define RTC1_TYPE2_START	0x0f000100UL
-#define RTC1_TYPE2_END		0x0f00011fUL
-#define RTC2_TYPE2_START	0x0f000120UL
-#define RTC2_TYPE2_END		0x0f00013fUL
-
-#define RTC1_SIZE		0x20
-#define RTC2_SIZE		0x20
-
 /* RTC 1 registers */
 #define ETIMELREG		0x00
 #define ETIMEMREG		0x02
@@ -98,13 +85,8 @@
 static unsigned long periodic_frequency;
 static unsigned long periodic_count;
 static unsigned int alarm_enabled;
-
-struct resource rtc_resource[2] = {
-	{	.name	= rtc_name,
-		.flags	= IORESOURCE_MEM,	},
-	{	.name	= rtc_name,
-		.flags	= IORESOURCE_MEM,	},
-};
+static int aie_irq = -1;
+static int pie_irq = -1;
 
 static inline unsigned long read_elapsed_second(void)
 {
@@ -150,8 +132,8 @@
 
 	spin_unlock_irq(&rtc_lock);
 
-	disable_irq(ELAPSEDTIME_IRQ);
-	disable_irq(RTCLONG1_IRQ);
+	disable_irq(aie_irq);
+	disable_irq(pie_irq);
 }
 
 static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time)
@@ -209,14 +191,14 @@
 	spin_lock_irq(&rtc_lock);
 
 	if (alarm_enabled)
-		disable_irq(ELAPSEDTIME_IRQ);
+		disable_irq(aie_irq);
 
 	rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15));
 	rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1));
 	rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17));
 
 	if (wkalrm->enabled)
-		enable_irq(ELAPSEDTIME_IRQ);
+		enable_irq(aie_irq);
 
 	alarm_enabled = wkalrm->enabled;
 
@@ -234,7 +216,7 @@
 		spin_lock_irq(&rtc_lock);
 
 		if (!alarm_enabled) {
-			enable_irq(ELAPSEDTIME_IRQ);
+			enable_irq(aie_irq);
 			alarm_enabled = 1;
 		}
 
@@ -244,17 +226,17 @@
 		spin_lock_irq(&rtc_lock);
 
 		if (alarm_enabled) {
-			disable_irq(ELAPSEDTIME_IRQ);
+			disable_irq(aie_irq);
 			alarm_enabled = 0;
 		}
 
 		spin_unlock_irq(&rtc_lock);
 		break;
 	case RTC_PIE_ON:
-		enable_irq(RTCLONG1_IRQ);
+		enable_irq(pie_irq);
 		break;
 	case RTC_PIE_OFF:
-		disable_irq(RTCLONG1_IRQ);
+		disable_irq(pie_irq);
 		break;
 	case RTC_IRQP_READ:
 		return put_user(periodic_frequency, (unsigned long __user *)arg);
@@ -331,31 +313,37 @@
 
 static int __devinit rtc_probe(struct platform_device *pdev)
 {
+	struct resource *res;
 	struct rtc_device *rtc;
-	unsigned int irq;
 	int retval;
 
-	if (pdev->num_resources != 2)
+	if (pdev->num_resources != 4)
 		return -EBUSY;
 
-	rtc1_base = ioremap(pdev->resource[0].start, RTC1_SIZE);
-	if (rtc1_base == NULL)
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
 		return -EBUSY;
 
-	rtc2_base = ioremap(pdev->resource[1].start, RTC2_SIZE);
-	if (rtc2_base == NULL) {
-		iounmap(rtc1_base);
-		rtc1_base = NULL;
+	rtc1_base = ioremap(res->start, res->end - res->start + 1);
+	if (!rtc1_base)
 		return -EBUSY;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		retval = -EBUSY;
+		goto err_rtc1_iounmap;
+	}
+
+	rtc2_base = ioremap(res->start, res->end - res->start + 1);
+	if (!rtc2_base) {
+		retval = -EBUSY;
+		goto err_rtc1_iounmap;
 	}
 
 	rtc = rtc_device_register(rtc_name, &pdev->dev, &vr41xx_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc)) {
-		iounmap(rtc1_base);
-		iounmap(rtc2_base);
-		rtc1_base = NULL;
-		rtc2_base = NULL;
-		return PTR_ERR(rtc);
+		retval = PTR_ERR(rtc);
+		goto err_iounmap_all;
 	}
 
 	spin_lock_irq(&rtc_lock);
@@ -368,35 +356,50 @@
 
 	spin_unlock_irq(&rtc_lock);
 
-	irq = ELAPSEDTIME_IRQ;
-	retval = request_irq(irq, elapsedtime_interrupt, IRQF_DISABLED,
-	                     "elapsed_time", pdev);
-	if (retval == 0) {
-		irq = RTCLONG1_IRQ;
-		retval = request_irq(irq, rtclong1_interrupt, IRQF_DISABLED,
-		                     "rtclong1", pdev);
+	aie_irq = platform_get_irq(pdev, 0);
+	if (aie_irq < 0 || aie_irq >= NR_IRQS) {
+		retval = -EBUSY;
+		goto err_device_unregister;
 	}
 
-	if (retval < 0) {
-		printk(KERN_ERR "rtc: IRQ%d is busy\n", irq);
-		rtc_device_unregister(rtc);
-		if (irq == RTCLONG1_IRQ)
-			free_irq(ELAPSEDTIME_IRQ, NULL);
-		iounmap(rtc1_base);
-		iounmap(rtc2_base);
-		rtc1_base = NULL;
-		rtc2_base = NULL;
-		return retval;
-	}
+	retval = request_irq(aie_irq, elapsedtime_interrupt, IRQF_DISABLED,
+	                     "elapsed_time", pdev);
+	if (retval < 0)
+		goto err_device_unregister;
+
+	pie_irq = platform_get_irq(pdev, 1);
+	if (pie_irq < 0 || pie_irq >= NR_IRQS)
+		goto err_free_irq;
+
+	retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED,
+		             "rtclong1", pdev);
+	if (retval < 0)
+		goto err_free_irq;
 
 	platform_set_drvdata(pdev, rtc);
 
-	disable_irq(ELAPSEDTIME_IRQ);
-	disable_irq(RTCLONG1_IRQ);
+	disable_irq(aie_irq);
+	disable_irq(pie_irq);
 
 	printk(KERN_INFO "rtc: Real Time Clock of NEC VR4100 series\n");
 
 	return 0;
+
+err_free_irq:
+	free_irq(aie_irq, pdev);
+
+err_device_unregister:
+	rtc_device_unregister(rtc);
+
+err_iounmap_all:
+	iounmap(rtc2_base);
+	rtc2_base = NULL;
+
+err_rtc1_iounmap:
+	iounmap(rtc1_base);
+	rtc1_base = NULL;
+
+	return retval;
 }
 
 static int __devexit rtc_remove(struct platform_device *pdev)
@@ -404,23 +407,21 @@
 	struct rtc_device *rtc;
 
 	rtc = platform_get_drvdata(pdev);
-	if (rtc != NULL)
+	if (rtc)
 		rtc_device_unregister(rtc);
 
 	platform_set_drvdata(pdev, NULL);
 
-	free_irq(ELAPSEDTIME_IRQ, NULL);
-	free_irq(RTCLONG1_IRQ, NULL);
-	if (rtc1_base != NULL)
+	free_irq(aie_irq, pdev);
+	free_irq(pie_irq, pdev);
+	if (rtc1_base)
 		iounmap(rtc1_base);
-	if (rtc2_base != NULL)
+	if (rtc2_base)
 		iounmap(rtc2_base);
 
 	return 0;
 }
 
-static struct platform_device *rtc_platform_device;
-
 static struct platform_driver rtc_platform_driver = {
 	.probe		= rtc_probe,
 	.remove		= __devexit_p(rtc_remove),
@@ -432,55 +433,12 @@
 
 static int __init vr41xx_rtc_init(void)
 {
-	int retval;
-
-	switch (current_cpu_data.cputype) {
-	case CPU_VR4111:
-	case CPU_VR4121:
-		rtc_resource[0].start = RTC1_TYPE1_START;
-		rtc_resource[0].end = RTC1_TYPE1_END;
-		rtc_resource[1].start = RTC2_TYPE1_START;
-		rtc_resource[1].end = RTC2_TYPE1_END;
-		break;
-	case CPU_VR4122:
-	case CPU_VR4131:
-	case CPU_VR4133:
-		rtc_resource[0].start = RTC1_TYPE2_START;
-		rtc_resource[0].end = RTC1_TYPE2_END;
-		rtc_resource[1].start = RTC2_TYPE2_START;
-		rtc_resource[1].end = RTC2_TYPE2_END;
-		break;
-	default:
-		return -ENODEV;
-		break;
-	}
-
-	rtc_platform_device = platform_device_alloc("RTC", -1);
-	if (rtc_platform_device == NULL)
-		return -ENOMEM;
-
-	retval = platform_device_add_resources(rtc_platform_device,
-				rtc_resource, ARRAY_SIZE(rtc_resource));
-
-	if (retval == 0)
-		retval = platform_device_add(rtc_platform_device);
-
-	if (retval < 0) {
-		platform_device_put(rtc_platform_device);
-		return retval;
-	}
-
-	retval = platform_driver_register(&rtc_platform_driver);
-	if (retval < 0)
-		platform_device_unregister(rtc_platform_device);
-
-	return retval;
+	return platform_driver_register(&rtc_platform_driver);
 }
 
 static void __exit vr41xx_rtc_exit(void)
 {
 	platform_driver_unregister(&rtc_platform_driver);
-	platform_device_unregister(rtc_platform_device);
 }
 
 module_init(vr41xx_rtc_init);
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c
index 513d1a6..b3fae35 100644
--- a/drivers/rtc/rtc-x1205.c
+++ b/drivers/rtc/rtc-x1205.c
@@ -9,6 +9,9 @@
  *
  * based on a lot of other RTC drivers.
  *
+ * Information and datasheet:
+ * http://www.intersil.com/cda/deviceinfo/0,1477,X1205,00.html
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
@@ -26,7 +29,7 @@
  * Two bytes need to be written to read a single register,
  * while most other chips just require one and take the second
  * one as the data to be written. To prevent corrupting
- * unknown chips, the user must explicitely set the probe parameter.
+ * unknown chips, the user must explicitly set the probe parameter.
  */
 
 static unsigned short normal_i2c[] = { I2C_CLIENT_END };
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index ac289e6..b57d93d 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -141,8 +141,9 @@
 /*
  * Channel measurement related functions
  */
-static ssize_t chp_measurement_chars_read(struct kobject *kobj, char *buf,
-					  loff_t off, size_t count)
+static ssize_t chp_measurement_chars_read(struct kobject *kobj,
+					  struct bin_attribute *bin_attr,
+					  char *buf, loff_t off, size_t count)
 {
 	struct channel_path *chp;
 	unsigned int size;
@@ -165,7 +166,6 @@
 	.attr = {
 		.name = "measurement_chars",
 		.mode = S_IRUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = sizeof(struct cmg_chars),
 	.read = chp_measurement_chars_read,
@@ -193,8 +193,9 @@
 	} while (reference_buf.values[0] != buf->values[0]);
 }
 
-static ssize_t chp_measurement_read(struct kobject *kobj, char *buf,
-				    loff_t off, size_t count)
+static ssize_t chp_measurement_read(struct kobject *kobj,
+				    struct bin_attribute *bin_attr,
+				    char *buf, loff_t off, size_t count)
 {
 	struct channel_path *chp;
 	struct channel_subsystem *css;
@@ -217,7 +218,6 @@
 	.attr = {
 		.name = "measurement",
 		.mode = S_IRUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = sizeof(struct cmg_entry),
 	.read = chp_measurement_read,
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index 65ffc21..bb0287a 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -991,7 +991,7 @@
 
 #define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store)			     \
 struct device_attribute dev_attr_##_id = {				     \
-	.attr = {.name=__stringify(_name), .mode=_mode, .owner=THIS_MODULE },\
+	.attr = {.name=__stringify(_name), .mode=_mode, },\
 	.show	= _show,						     \
 	.store	= _store,						     \
 };
diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c
index 03bfed6..06c0dce 100644
--- a/drivers/scsi/arcmsr/arcmsr_attr.c
+++ b/drivers/scsi/arcmsr/arcmsr_attr.c
@@ -59,8 +59,9 @@
 struct class_device_attribute *arcmsr_host_attrs[];
 
 static ssize_t
-arcmsr_sysfs_iop_message_read(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+arcmsr_sysfs_iop_message_read(struct kobject *kobj,
+			      struct bin_attribute *bin_attr,
+			      char *buf, loff_t off, size_t count)
 {
 	struct class_device *cdev = container_of(kobj,struct class_device,kobj);
 	struct Scsi_Host *host = class_to_shost(cdev);
@@ -105,8 +106,9 @@
 }
 
 static ssize_t
-arcmsr_sysfs_iop_message_write(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+arcmsr_sysfs_iop_message_write(struct kobject *kobj,
+			       struct bin_attribute *bin_attr,
+			       char *buf, loff_t off, size_t count)
 {
 	struct class_device *cdev = container_of(kobj,struct class_device,kobj);
 	struct Scsi_Host *host = class_to_shost(cdev);
@@ -152,8 +154,9 @@
 }
 
 static ssize_t
-arcmsr_sysfs_iop_message_clear(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+arcmsr_sysfs_iop_message_clear(struct kobject *kobj,
+			       struct bin_attribute *bin_attr,
+			       char *buf, loff_t off, size_t count)
 {
 	struct class_device *cdev = container_of(kobj,struct class_device,kobj);
 	struct Scsi_Host *host = class_to_shost(cdev);
@@ -188,7 +191,6 @@
 	.attr = {
 		.name = "mu_read",
 		.mode = S_IRUSR ,
-		.owner = THIS_MODULE,
 	},
 	.size = 1032,
 	.read = arcmsr_sysfs_iop_message_read,
@@ -198,7 +200,6 @@
 	.attr = {
 		.name = "mu_write",
 		.mode = S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = 1032,
 	.write = arcmsr_sysfs_iop_message_write,
@@ -208,7 +209,6 @@
 	.attr = {
 		.name = "mu_clear",
 		.mode = S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = 1,
 	.write = arcmsr_sysfs_iop_message_clear,
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 8133071..b3bf77f 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2465,6 +2465,7 @@
 /**
  * ipr_read_trace - Dump the adapter trace
  * @kobj:		kobject struct
+ * @bin_attr:		bin_attribute struct
  * @buf:		buffer
  * @off:		offset
  * @count:		buffer size
@@ -2472,8 +2473,9 @@
  * Return value:
  *	number of bytes printed to buffer
  **/
-static ssize_t ipr_read_trace(struct kobject *kobj, char *buf,
-			      loff_t off, size_t count)
+static ssize_t ipr_read_trace(struct kobject *kobj,
+			      struct bin_attribute *bin_attr,
+			      char *buf, loff_t off, size_t count)
 {
 	struct class_device *cdev = container_of(kobj,struct class_device,kobj);
 	struct Scsi_Host *shost = class_to_shost(cdev);
@@ -3166,6 +3168,7 @@
 /**
  * ipr_read_dump - Dump the adapter
  * @kobj:		kobject struct
+ * @bin_attr:		bin_attribute struct
  * @buf:		buffer
  * @off:		offset
  * @count:		buffer size
@@ -3173,8 +3176,9 @@
  * Return value:
  *	number of bytes printed to buffer
  **/
-static ssize_t ipr_read_dump(struct kobject *kobj, char *buf,
-			      loff_t off, size_t count)
+static ssize_t ipr_read_dump(struct kobject *kobj,
+			     struct bin_attribute *bin_attr,
+			     char *buf, loff_t off, size_t count)
 {
 	struct class_device *cdev = container_of(kobj,struct class_device,kobj);
 	struct Scsi_Host *shost = class_to_shost(cdev);
@@ -3327,6 +3331,7 @@
 /**
  * ipr_write_dump - Setup dump state of adapter
  * @kobj:		kobject struct
+ * @bin_attr:		bin_attribute struct
  * @buf:		buffer
  * @off:		offset
  * @count:		buffer size
@@ -3334,8 +3339,9 @@
  * Return value:
  *	number of bytes printed to buffer
  **/
-static ssize_t ipr_write_dump(struct kobject *kobj, char *buf,
-			      loff_t off, size_t count)
+static ssize_t ipr_write_dump(struct kobject *kobj,
+			      struct bin_attribute *bin_attr,
+			      char *buf, loff_t off, size_t count)
 {
 	struct class_device *cdev = container_of(kobj,struct class_device,kobj);
 	struct Scsi_Host *shost = class_to_shost(cdev);
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index e34442e..23e90c5 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -38,8 +38,10 @@
 
 #if 0
 /* FIXME: smp needs to migrate into the sas class */
-static ssize_t smp_portal_read(struct kobject *, char *, loff_t, size_t);
-static ssize_t smp_portal_write(struct kobject *, char *, loff_t, size_t);
+static ssize_t smp_portal_read(struct kobject *, struct bin_attribute *,
+			       char *, loff_t, size_t);
+static ssize_t smp_portal_write(struct kobject *, struct bin_attribute *,
+				char *, loff_t, size_t);
 #endif
 
 /* ---------- SMP task management ---------- */
@@ -1368,7 +1370,6 @@
 	memset(bin_attr, 0, sizeof(*bin_attr));
 
 	bin_attr->attr.name = SMP_BIN_ATTR_NAME;
-	bin_attr->attr.owner = THIS_MODULE;
 	bin_attr->attr.mode = 0600;
 
 	bin_attr->size = 0;
@@ -1846,8 +1847,9 @@
 #if 0
 /* ---------- SMP portal ---------- */
 
-static ssize_t smp_portal_write(struct kobject *kobj, char *buf, loff_t offs,
-				size_t size)
+static ssize_t smp_portal_write(struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t offs, size_t size)
 {
 	struct domain_device *dev = to_dom_device(kobj);
 	struct expander_device *ex = &dev->ex_dev;
@@ -1873,8 +1875,9 @@
 	return size;
 }
 
-static ssize_t smp_portal_read(struct kobject *kobj, char *buf, loff_t offs,
-			       size_t size)
+static ssize_t smp_portal_read(struct kobject *kobj,
+			       struct bin_attribute *bin_attr,
+			       char *buf, loff_t offs, size_t size)
 {
 	struct domain_device *dev = to_dom_device(kobj);
 	struct expander_device *ex = &dev->ex_dev;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 95fe77e..5dfda97 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1133,7 +1133,8 @@
 };
 
 static ssize_t
-sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr,
+		   char *buf, loff_t off, size_t count)
 {
 	size_t buf_off;
 	struct Scsi_Host *host = class_to_shost(container_of(kobj,
@@ -1165,7 +1166,8 @@
 }
 
 static ssize_t
-sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+sysfs_ctlreg_read(struct kobject *kobj, struct bin_attribute *bin_attr,
+		  char *buf, loff_t off, size_t count)
 {
 	size_t buf_off;
 	uint32_t * tmp_ptr;
@@ -1200,7 +1202,6 @@
 	.attr = {
 		.name = "ctlreg",
 		.mode = S_IRUSR | S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = 256,
 	.read = sysfs_ctlreg_read,
@@ -1222,7 +1223,8 @@
 }
 
 static ssize_t
-sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr,
+		 char *buf, loff_t off, size_t count)
 {
 	struct Scsi_Host * host =
 		class_to_shost(container_of(kobj, struct class_device, kobj));
@@ -1274,7 +1276,8 @@
 }
 
 static ssize_t
-sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
+		char *buf, loff_t off, size_t count)
 {
 	struct Scsi_Host *host =
 		class_to_shost(container_of(kobj, struct class_device,
@@ -1422,7 +1425,6 @@
 	.attr = {
 		.name = "mbox",
 		.mode = S_IRUSR | S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = MAILBOX_CMD_SIZE,
 	.read = sysfs_mbox_read,
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 8081b63..942db9d 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -11,8 +11,9 @@
 /* SYSFS attributes --------------------------------------------------------- */
 
 static ssize_t
-qla2x00_sysfs_read_fw_dump(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_read_fw_dump(struct kobject *kobj,
+			   struct bin_attribute *bin_attr,
+			   char *buf, loff_t off, size_t count)
 {
 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
@@ -31,8 +32,9 @@
 }
 
 static ssize_t
-qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_write_fw_dump(struct kobject *kobj,
+			    struct bin_attribute *bin_attr,
+			    char *buf, loff_t off, size_t count)
 {
 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
@@ -73,7 +75,6 @@
 	.attr = {
 		.name = "fw_dump",
 		.mode = S_IRUSR | S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = 0,
 	.read = qla2x00_sysfs_read_fw_dump,
@@ -81,8 +82,9 @@
 };
 
 static ssize_t
-qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_read_nvram(struct kobject *kobj,
+			 struct bin_attribute *bin_attr,
+			 char *buf, loff_t off, size_t count)
 {
 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
@@ -101,8 +103,9 @@
 }
 
 static ssize_t
-qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_write_nvram(struct kobject *kobj,
+			  struct bin_attribute *bin_attr,
+			  char *buf, loff_t off, size_t count)
 {
 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
@@ -149,7 +152,6 @@
 	.attr = {
 		.name = "nvram",
 		.mode = S_IRUSR | S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = 512,
 	.read = qla2x00_sysfs_read_nvram,
@@ -157,8 +159,9 @@
 };
 
 static ssize_t
-qla2x00_sysfs_read_optrom(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_read_optrom(struct kobject *kobj,
+			  struct bin_attribute *bin_attr,
+			  char *buf, loff_t off, size_t count)
 {
 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
@@ -176,8 +179,9 @@
 }
 
 static ssize_t
-qla2x00_sysfs_write_optrom(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_write_optrom(struct kobject *kobj,
+			   struct bin_attribute *bin_attr,
+			   char *buf, loff_t off, size_t count)
 {
 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
@@ -198,7 +202,6 @@
 	.attr = {
 		.name = "optrom",
 		.mode = S_IRUSR | S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = OPTROM_SIZE_24XX,
 	.read = qla2x00_sysfs_read_optrom,
@@ -206,8 +209,9 @@
 };
 
 static ssize_t
-qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
+			       struct bin_attribute *bin_attr,
+			       char *buf, loff_t off, size_t count)
 {
 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
@@ -279,15 +283,15 @@
 	.attr = {
 		.name = "optrom_ctl",
 		.mode = S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = 0,
 	.write = qla2x00_sysfs_write_optrom_ctl,
 };
 
 static ssize_t
-qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_read_vpd(struct kobject *kobj,
+		       struct bin_attribute *bin_attr,
+		       char *buf, loff_t off, size_t count)
 {
 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
@@ -305,8 +309,9 @@
 }
 
 static ssize_t
-qla2x00_sysfs_write_vpd(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_write_vpd(struct kobject *kobj,
+			struct bin_attribute *bin_attr,
+			char *buf, loff_t off, size_t count)
 {
 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
@@ -327,7 +332,6 @@
 	.attr = {
 		.name = "vpd",
 		.mode = S_IRUSR | S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = 0,
 	.read = qla2x00_sysfs_read_vpd,
@@ -335,8 +339,9 @@
 };
 
 static ssize_t
-qla2x00_sysfs_read_sfp(struct kobject *kobj, char *buf, loff_t off,
-    size_t count)
+qla2x00_sysfs_read_sfp(struct kobject *kobj,
+		       struct bin_attribute *bin_attr,
+		       char *buf, loff_t off, size_t count)
 {
 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
@@ -375,7 +380,6 @@
 	.attr = {
 		.name = "sfp",
 		.mode = S_IRUSR | S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = SFP_DEV_SIZE * 2,
 	.read = qla2x00_sysfs_read_sfp,
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 315ea99..2adbed4 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -556,7 +556,7 @@
 
 config SERIAL_BFIN_DMA
 	bool "DMA mode"
-	depends on DMA_UNCACHED_1M
+	depends on DMA_UNCACHED_1M && !KGDB_UART
 	help
 	  This driver works under DMA mode. If this option is selected, the
 	  blackfin simple dma driver is also enabled.
@@ -599,7 +599,7 @@
 
 config SERIAL_BFIN_UART1
 	bool "Enable UART1"
-	depends on SERIAL_BFIN && (BF534 || BF536 || BF537)
+	depends on SERIAL_BFIN && (BF534 || BF536 || BF537 || BF54x)
 	help
 	  Enable UART1
 
@@ -612,18 +612,58 @@
 
 config UART1_CTS_PIN
 	int "UART1 CTS pin"
-	depends on BFIN_UART1_CTSRTS
+	depends on BFIN_UART1_CTSRTS && (BF53x || BF561)
 	default -1
 	help
 	  Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
 
 config UART1_RTS_PIN
 	int "UART1 RTS pin"
-	depends on BFIN_UART1_CTSRTS
+	depends on BFIN_UART1_CTSRTS && (BF53x || BF561)
 	default -1
 	help
 	  Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
 
+config SERIAL_BFIN_UART2
+	bool "Enable UART2"
+	depends on SERIAL_BFIN && (BF54x)
+	help
+	  Enable UART2
+
+config BFIN_UART2_CTSRTS
+	bool "Enable UART2 hardware flow control"
+	depends on SERIAL_BFIN_UART2
+	help
+	  Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
+	  signal.
+
+config UART2_CTS_PIN
+	int "UART2 CTS pin"
+	depends on BFIN_UART2_CTSRTS
+	default -1
+	help
+	  Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+
+config UART2_RTS_PIN
+	int "UART2 RTS pin"
+	depends on BFIN_UART2_CTSRTS
+	default -1
+	help
+	  Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+
+config SERIAL_BFIN_UART3
+	bool "Enable UART3"
+	depends on SERIAL_BFIN && (BF54x)
+	help
+	  Enable UART3
+
+config BFIN_UART3_CTSRTS
+	bool "Enable UART3 hardware flow control"
+	depends on SERIAL_BFIN_UART3
+	help
+	  Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
+	  signal.
+
 config SERIAL_IMX
 	bool "IMX serial port support"
 	depends on ARM && ARCH_IMX
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 22569bd..66c92bc 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -41,6 +41,11 @@
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
 
+#ifdef CONFIG_KGDB_UART
+#include <linux/kgdb.h>
+#include <asm/irq_regs.h>
+#endif
+
 #include <asm/gpio.h>
 #include <asm/mach/bfin_serial_5xx.h>
 
@@ -81,15 +86,29 @@
 {
 	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
 
+#ifdef CONFIG_BF54x
+	while (!(UART_GET_LSR(uart) & TEMT))
+		continue;
+#endif
+
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	disable_dma(uart->tx_dma_channel);
 #else
+#ifdef CONFIG_BF54x
+	/* Waiting for Transmission Finished */
+	while (!(UART_GET_LSR(uart) & TFI))
+		continue;
+	/* Clear TFI bit */
+	UART_PUT_LSR(uart, TFI);
+	UART_CLEAR_IER(uart, ETBEI);
+#else
 	unsigned short ier;
 
 	ier = UART_GET_IER(uart);
 	ier &= ~ETBEI;
 	UART_PUT_IER(uart, ier);
 #endif
+#endif
 }
 
 /*
@@ -102,12 +121,16 @@
 #ifdef CONFIG_SERIAL_BFIN_DMA
 	bfin_serial_dma_tx_chars(uart);
 #else
+#ifdef CONFIG_BF54x
+	UART_SET_IER(uart, ETBEI);
+#else
 	unsigned short ier;
 	ier = UART_GET_IER(uart);
 	ier |= ETBEI;
 	UART_PUT_IER(uart, ier);
 	bfin_serial_tx_chars(uart);
 #endif
+#endif
 }
 
 /*
@@ -116,11 +139,18 @@
 static void bfin_serial_stop_rx(struct uart_port *port)
 {
 	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+#ifdef CONFIG_BF54x
+	UART_CLEAR_IER(uart, ERBFI);
+#else
 	unsigned short ier;
 
 	ier = UART_GET_IER(uart);
+#ifdef	CONFIG_KGDB_UART
+	if (uart->port.line != CONFIG_KGDB_UART_PORT)
+#endif
 	ier &= ~ERBFI;
 	UART_PUT_IER(uart, ier);
+#endif
 }
 
 /*
@@ -130,6 +160,49 @@
 {
 }
 
+#ifdef CONFIG_KGDB_UART
+static int kgdb_entry_state;
+
+void kgdb_put_debug_char(int chr)
+{
+	struct bfin_serial_port *uart;
+	
+	if (CONFIG_KGDB_UART_PORT<0 || CONFIG_KGDB_UART_PORT>=NR_PORTS)
+		uart = &bfin_serial_ports[0];
+	else
+		uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
+	
+	while (!(UART_GET_LSR(uart) & THRE)) {
+		__builtin_bfin_ssync();
+	}
+	UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
+	__builtin_bfin_ssync();
+	UART_PUT_CHAR(uart, (unsigned char)chr);
+	__builtin_bfin_ssync();
+}
+
+int kgdb_get_debug_char(void)
+{
+	struct bfin_serial_port *uart;
+	unsigned char chr;
+
+	if (CONFIG_KGDB_UART_PORT<0 || CONFIG_KGDB_UART_PORT>=NR_PORTS)
+		uart = &bfin_serial_ports[0];
+	else
+		uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
+	
+	while(!(UART_GET_LSR(uart) & DR)) {
+		__builtin_bfin_ssync();
+	}
+	UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
+	__builtin_bfin_ssync();
+	chr = UART_GET_CHAR(uart);
+	__builtin_bfin_ssync();
+
+	return chr;
+}
+#endif
+
 #ifdef CONFIG_SERIAL_BFIN_PIO
 static void local_put_char(struct bfin_serial_port *uart, char ch)
 {
@@ -152,6 +225,9 @@
 {
 	struct tty_struct *tty = uart->port.info->tty;
 	unsigned int status, ch, flg;
+#ifdef CONFIG_KGDB_UART
+	struct pt_regs *regs = get_irq_regs();
+#endif
 #ifdef BF533_FAMILY
 	static int in_break = 0;
 #endif
@@ -160,6 +236,27 @@
  	ch = UART_GET_CHAR(uart);
  	uart->port.icount.rx++;
 
+#ifdef CONFIG_KGDB_UART
+	if (uart->port.line == CONFIG_KGDB_UART_PORT) {
+		if (uart->port.cons->index == CONFIG_KGDB_UART_PORT && ch == 0x1) { /* Ctrl + A */
+			kgdb_breakkey_pressed(regs);
+			return;
+		} else if (kgdb_entry_state == 0 && ch == '$') {/* connection from KGDB */
+			kgdb_entry_state = 1;
+		} else if (kgdb_entry_state == 1 && ch == 'q') {
+			kgdb_entry_state = 0;
+			kgdb_breakkey_pressed(regs);
+			return;
+		} else if (ch == 0x3) {/* Ctrl + C */
+			kgdb_entry_state = 0;
+			kgdb_breakkey_pressed(regs);
+			return;
+		} else {
+			kgdb_entry_state = 0;
+		}
+	}
+#endif
+ 
 #ifdef BF533_FAMILY
 	/* The BF533 family of processors have a nice misbehavior where
 	 * they continuously generate characters for a "single" break.
@@ -250,10 +347,21 @@
 {
 	struct bfin_serial_port *uart = dev_id;
 
+#ifdef CONFIG_BF54x
+	unsigned short status;
+	spin_lock(&uart->port.lock);
+	status = UART_GET_LSR(uart);
+	while ((UART_GET_IER(uart) & ERBFI) && (status & DR)) {
+		bfin_serial_rx_chars(uart);
+		status = UART_GET_LSR(uart);
+	}
+	spin_unlock(&uart->port.lock);
+#else
 	spin_lock(&uart->port.lock);
 	while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY)
 		bfin_serial_rx_chars(uart);
 	spin_unlock(&uart->port.lock);
+#endif
 	return IRQ_HANDLED;
 }
 
@@ -261,10 +369,21 @@
 {
 	struct bfin_serial_port *uart = dev_id;
 
+#ifdef CONFIG_BF54x
+	unsigned short status;
+	spin_lock(&uart->port.lock);
+	status = UART_GET_LSR(uart);
+	while ((UART_GET_IER(uart) & ETBEI) && (status & THRE)) {
+		bfin_serial_tx_chars(uart);
+		status = UART_GET_LSR(uart);
+	}
+	spin_unlock(&uart->port.lock);
+#else
 	spin_lock(&uart->port.lock);
 	while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY)
 		bfin_serial_tx_chars(uart);
 	spin_unlock(&uart->port.lock);
+#endif
 	return IRQ_HANDLED;
 }
 
@@ -275,7 +394,6 @@
 
 	bfin_serial_mctrl_check(uart);
 }
-
 #endif
 
 #ifdef CONFIG_SERIAL_BFIN_DMA
@@ -324,9 +442,13 @@
 	set_dma_x_count(uart->tx_dma_channel, uart->tx_count);
 	set_dma_x_modify(uart->tx_dma_channel, 1);
 	enable_dma(uart->tx_dma_channel);
+#ifdef CONFIG_BF54x
+	UART_SET_IER(uart, ETBEI);
+#else
 	ier = UART_GET_IER(uart);
 	ier |= ETBEI;
 	UART_PUT_IER(uart, ier);
+#endif
 	spin_unlock_irqrestore(&uart->port.lock, flags);
 }
 
@@ -406,9 +528,13 @@
 	if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) {
 		clear_dma_irqstat(uart->tx_dma_channel);
 		disable_dma(uart->tx_dma_channel);
+#ifdef CONFIG_BF54x
+		UART_CLEAR_IER(uart, ETBEI);
+#else
 		ier = UART_GET_IER(uart);
 		ier &= ~ETBEI;
 		UART_PUT_IER(uart, ier);
+#endif
 		xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1);
 		uart->port.icount.tx+=uart->tx_count;
 
@@ -571,7 +697,11 @@
 	uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES;
 	add_timer(&(uart->rx_dma_timer));
 #else
+# ifdef	CONFIG_KGDB_UART
+	if (uart->port.line != CONFIG_KGDB_UART_PORT && request_irq
+# else
 	if (request_irq
+# endif
 	    (uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED,
 	     "BFIN_UART_RX", uart)) {
 		printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n");
@@ -586,7 +716,11 @@
 		return -EBUSY;
 	}
 #endif
+#ifdef CONFIG_BF54x
+	UART_SET_IER(uart, ERBFI);
+#else
 	UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
+#endif
 	return 0;
 }
 
@@ -601,6 +735,9 @@
 	free_dma(uart->rx_dma_channel);
 	del_timer(&(uart->rx_dma_timer));
 #else
+#ifdef	CONFIG_KGDB_UART
+	if (uart->port.line != CONFIG_KGDB_UART_PORT)
+#endif
 	free_irq(uart->port.irq, uart);
 	free_irq(uart->port.irq+1, uart);
 #endif
@@ -674,29 +811,41 @@
 
 	/* Disable UART */
 	ier = UART_GET_IER(uart);
+#ifdef CONFIG_BF54x
+	UART_CLEAR_IER(uart, 0xF);
+#else
 	UART_PUT_IER(uart, 0);
+#endif
 
+#ifndef CONFIG_BF54x
 	/* Set DLAB in LCR to Access DLL and DLH */
 	val = UART_GET_LCR(uart);
 	val |= DLAB;
 	UART_PUT_LCR(uart, val);
 	SSYNC();
+#endif
 
 	UART_PUT_DLL(uart, quot & 0xFF);
 	SSYNC();
 	UART_PUT_DLH(uart, (quot >> 8) & 0xFF);
 	SSYNC();
 
+#ifndef CONFIG_BF54x
 	/* Clear DLAB in LCR to Access THR RBR IER */
 	val = UART_GET_LCR(uart);
 	val &= ~DLAB;
 	UART_PUT_LCR(uart, val);
 	SSYNC();
+#endif
 
 	UART_PUT_LCR(uart, lcr);
 
 	/* Enable UART */
+#ifdef CONFIG_BF54x
+	UART_SET_IER(uart, ier);
+#else
 	UART_PUT_IER(uart, ier);
+#endif
 
 	val = UART_GET_GCTL(uart);
 	val |= UCEN;
@@ -808,15 +957,15 @@
 			bfin_serial_resource[i].uart_rts_pin;
 #endif
 		bfin_serial_hw_init(&bfin_serial_ports[i]);
-
 	}
+
 }
 
 #ifdef CONFIG_SERIAL_BFIN_CONSOLE
 static void bfin_serial_console_putchar(struct uart_port *port, int ch)
 {
 	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
-	while (!(UART_GET_LSR(uart)))
+	while (!(UART_GET_LSR(uart) & THRE))
 		barrier();
 	UART_PUT_CHAR(uart, ch);
 	SSYNC();
@@ -868,18 +1017,22 @@
 			case 2:	*bits = 7; break;
 			case 3:	*bits = 8; break;
 		}
+#ifndef CONFIG_BF54x
 		/* Set DLAB in LCR to Access DLL and DLH */
 		val = UART_GET_LCR(uart);
 		val |= DLAB;
 		UART_PUT_LCR(uart, val);
+#endif
 
 		dll = UART_GET_DLL(uart);
 		dlh = UART_GET_DLH(uart);
 
+#ifndef CONFIG_BF54x
 		/* Clear DLAB in LCR to Access THR RBR IER */
 		val = UART_GET_LCR(uart);
 		val &= ~DLAB;
 		UART_PUT_LCR(uart, val);
+#endif
 
 		*baud = get_sclk() / (16*(dll | dlh << 8));
 	}
@@ -931,6 +1084,10 @@
 {
 	bfin_serial_init_ports();
 	register_console(&bfin_serial_console);
+#ifdef CONFIG_KGDB_UART
+	kgdb_entry_state = 0;
+	init_kgdb_uart();
+#endif
 	return 0;
 }
 console_initcall(bfin_serial_rs_console_init);
@@ -1023,6 +1180,10 @@
 static int __init bfin_serial_init(void)
 {
 	int ret;
+#ifdef CONFIG_KGDB_UART
+	struct bfin_serial_port *uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
+	struct termios t;
+#endif
 
 	pr_info("Serial: Blackfin serial driver\n");
 
@@ -1036,6 +1197,21 @@
 			uart_unregister_driver(&bfin_serial_reg);
 		}
 	}
+#ifdef CONFIG_KGDB_UART
+	if (uart->port.cons->index != CONFIG_KGDB_UART_PORT) {
+		request_irq(uart->port.irq, bfin_serial_int,
+			IRQF_DISABLED, "BFIN_UART_RX", uart);
+		pr_info("Request irq for kgdb uart port\n");
+		UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
+		__builtin_bfin_ssync();
+		t.c_cflag = CS8|B57600;
+		t.c_iflag = 0;
+		t.c_oflag = 0;
+		t.c_lflag = ICANON;
+		t.c_line = CONFIG_KGDB_UART_PORT;
+		bfin_serial_set_termios(&uart->port, &t, &t);
+	}
+#endif
 	return ret;
 }
 
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index cf0e663..85309ac 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for NEC VR4100 series Serial Interface Unit.
  *
- *  Copyright (C) 2004-2005  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *  Copyright (C) 2004-2007  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
  *
  *  Based on drivers/serial/8250.c, by Russell King.
  *
@@ -25,12 +25,12 @@
 #endif
 
 #include <linux/console.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/ioport.h>
+#include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/ioport.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 #include <linux/serial_reg.h>
@@ -38,11 +38,9 @@
 #include <linux/tty_flip.h>
 
 #include <asm/io.h>
-#include <asm/vr41xx/irq.h>
 #include <asm/vr41xx/siu.h>
 #include <asm/vr41xx/vr41xx.h>
 
-#define SIU_PORTS_MAX	2
 #define SIU_BAUD_BASE	1152000
 #define SIU_MAJOR	204
 #define SIU_MINOR_BASE	82
@@ -60,32 +58,13 @@
  #define IRUSESEL	0x02
  #define SIRSEL		0x01
 
-struct siu_port {
-	unsigned int type;
-	unsigned int irq;
-	unsigned long start;
+static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = {
+	[0 ... SIU_PORTS_MAX-1] = {
+		.lock	= __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock),
+		.irq	= -1,
+	},
 };
 
-static const struct siu_port siu_type1_ports[] = {
-	{	.type		= PORT_VR41XX_SIU,
-		.irq		= SIU_IRQ,
-		.start		= 0x0c000000UL,		},
-};
-
-#define SIU_TYPE1_NR_PORTS	(sizeof(siu_type1_ports) / sizeof(struct siu_port))
-
-static const struct siu_port siu_type2_ports[] = {
-	{	.type		= PORT_VR41XX_SIU,
-		.irq		= SIU_IRQ,
-		.start		= 0x0f000800UL,		},
-	{	.type		= PORT_VR41XX_DSIU,
-		.irq		= DSIU_IRQ,
-		.start		= 0x0f000820UL,		},
-};
-
-#define SIU_TYPE2_NR_PORTS	(sizeof(siu_type2_ports) / sizeof(struct siu_port))
-
-static struct uart_port siu_uart_ports[SIU_PORTS_MAX];
 static uint8_t lsr_break_flag[SIU_PORTS_MAX];
 
 #define siu_read(port, offset)		readb((port)->membase + (offset))
@@ -110,7 +89,6 @@
 
 	spin_unlock_irqrestore(&port->lock, flags);
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_select_siu_interface);
 
 void vr41xx_use_irda(irda_use_t use)
@@ -132,7 +110,6 @@
 
 	spin_unlock_irqrestore(&port->lock, flags);
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_use_irda);
 
 void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed)
@@ -166,7 +143,6 @@
 
 	spin_unlock_irqrestore(&port->lock, flags);
 }
-
 EXPORT_SYMBOL_GPL(vr41xx_select_irda_module);
 
 static inline void siu_clear_fifo(struct uart_port *port)
@@ -177,21 +153,6 @@
 	siu_write(port, UART_FCR, 0);
 }
 
-static inline int siu_probe_ports(void)
-{
-	switch (current_cpu_data.cputype) {
-	case CPU_VR4111:
-	case CPU_VR4121:
-		return SIU_TYPE1_NR_PORTS;
-	case CPU_VR4122:
-	case CPU_VR4131:
-	case CPU_VR4133:
-		return SIU_TYPE2_NR_PORTS;
-	}
-
-	return 0;
-}
-
 static inline unsigned long siu_port_size(struct uart_port *port)
 {
 	switch (port->type) {
@@ -206,21 +167,10 @@
 
 static inline unsigned int siu_check_type(struct uart_port *port)
 {
-	switch (current_cpu_data.cputype) {
-	case CPU_VR4111:
-	case CPU_VR4121:
-		if (port->line == 0)
-			return PORT_VR41XX_SIU;
-		break;
-	case CPU_VR4122:
-	case CPU_VR4131:
-	case CPU_VR4133:
-		if (port->line == 0)
-			return PORT_VR41XX_SIU;
-		else if (port->line == 1)
-			return PORT_VR41XX_DSIU;
-		break;
-	}
+	if (port->line == 0)
+		return PORT_VR41XX_SIU;
+	if (port->line == 1 && port->irq != -1)
+		return PORT_VR41XX_DSIU;
 
 	return PORT_UNKNOWN;
 }
@@ -751,44 +701,34 @@
 	.verify_port	= siu_verify_port,
 };
 
-static int siu_init_ports(void)
+static int siu_init_ports(struct platform_device *pdev)
 {
-	const struct siu_port *siu;
 	struct uart_port *port;
-	int i, num;
+	struct resource *res;
+	int *type = pdev->dev.platform_data;
+	int i;
 
-	switch (current_cpu_data.cputype) {
-	case CPU_VR4111:
-	case CPU_VR4121:
-		siu = siu_type1_ports;
-		break;
-	case CPU_VR4122:
-	case CPU_VR4131:
-	case CPU_VR4133:
-		siu = siu_type2_ports;
-		break;
-	default:
+	if (!type)
 		return 0;
-	}
 
 	port = siu_uart_ports;
-	num = siu_probe_ports();
-	for (i = 0; i < num; i++) {
-		spin_lock_init(&port->lock);
-		port->irq = siu->irq;
+	for (i = 0; i < SIU_PORTS_MAX; i++) {
+		port->type = type[i];
+		if (port->type == PORT_UNKNOWN)
+			continue;
+		port->irq = platform_get_irq(pdev, i);
 		port->uartclk = SIU_BAUD_BASE * 16;
 		port->fifosize = 16;
 		port->regshift = 0;
 		port->iotype = UPIO_MEM;
 		port->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
-		port->type = siu->type;
 		port->line = i;
-		port->mapbase = siu->start;
-		siu++;
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		port->mapbase = res->start;
 		port++;
 	}
 
-	return num;
+	return i;
 }
 
 #ifdef CONFIG_SERIAL_VR41XX_CONSOLE
@@ -883,13 +823,9 @@
 static int __devinit siu_console_init(void)
 {
 	struct uart_port *port;
-	int num, i;
+	int i;
 
-	num = siu_init_ports();
-	if (num <= 0)
-		return -ENODEV;
-
-	for (i = 0; i < num; i++) {
+	for (i = 0; i < SIU_PORTS_MAX; i++) {
 		port = &siu_uart_ports[i];
 		port->ops = &siu_uart_ops;
 	}
@@ -920,7 +856,7 @@
 	struct uart_port *port;
 	int num, i, retval;
 
-	num = siu_init_ports();
+	num = siu_init_ports(dev);
 	if (num <= 0)
 		return -ENODEV;
 
@@ -998,8 +934,6 @@
 	return 0;
 }
 
-static struct platform_device *siu_platform_device;
-
 static struct platform_driver siu_device_driver = {
 	.probe		= siu_probe,
 	.remove		= __devexit_p(siu_remove),
@@ -1013,29 +947,12 @@
 
 static int __init vr41xx_siu_init(void)
 {
-	int retval;
-
-	siu_platform_device = platform_device_alloc("SIU", -1);
-	if (!siu_platform_device)
-		return -ENOMEM;
-
-	retval = platform_device_add(siu_platform_device);
-	if (retval < 0) {
-		platform_device_put(siu_platform_device);
-		return retval;
-	}
-
-	retval = platform_driver_register(&siu_device_driver);
-	if (retval < 0)
-		platform_device_unregister(siu_platform_device);
-
-	return retval;
+	return platform_driver_register(&siu_device_driver);
 }
 
 static void __exit vr41xx_siu_exit(void)
 {
 	platform_driver_unregister(&siu_device_driver);
-	platform_device_unregister(siu_platform_device);
 }
 
 module_init(vr41xx_siu_init);
diff --git a/drivers/spi/at25.c b/drivers/spi/at25.c
index 8efa07e..e007833 100644
--- a/drivers/spi/at25.c
+++ b/drivers/spi/at25.c
@@ -111,7 +111,8 @@
 }
 
 static ssize_t
-at25_bin_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+at25_bin_read(struct kobject *kobj, struct bin_attribute *bin_attr,
+	      char *buf, loff_t off, size_t count)
 {
 	struct device		*dev;
 	struct at25_data	*at25;
@@ -236,7 +237,8 @@
 }
 
 static ssize_t
-at25_bin_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+at25_bin_write(struct kobject *kobj, struct bin_attribute *bin_attr,
+	       char *buf, loff_t off, size_t count)
 {
 	struct device		*dev;
 	struct at25_data	*at25;
@@ -314,7 +316,6 @@
 	 */
 	at25->bin.attr.name = "eeprom";
 	at25->bin.attr.mode = S_IRUSR;
-	at25->bin.attr.owner = THIS_MODULE;
 	at25->bin.read = at25_bin_read;
 
 	at25->bin.size = at25->chip.byte_len;
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 4fff61b..ed979f1 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -136,14 +136,14 @@
 struct tty_struct zs_ttys[NUM_CHANNELS];
 
 #ifdef CONFIG_SERIAL_DEC_CONSOLE
-static struct console sercons;
+static struct console zs_console;
 #endif
 #if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \
    !defined(MODULE)
 static unsigned long break_pressed; /* break, really ... */
 #endif
 
-static unsigned char zs_init_regs[16] = {
+static unsigned char zs_init_regs[16] __initdata = {
 	0,				/* write 0 */
 	0,				/* write 1 */
 	0,				/* write 2 */
@@ -383,7 +383,7 @@
 
 #if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \
    !defined(MODULE)
-		if (break_pressed && info->line == sercons.index) {
+		if (break_pressed && info->line == zs_console.index) {
 			/* Ignore the null char got when BREAK is removed.  */
 			if (ch == 0)
 				continue;
@@ -446,7 +446,7 @@
 	if ((stat & BRK_ABRT) && !(info->read_reg_zero & BRK_ABRT)) {
 #if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \
    !defined(MODULE)
-		if (info->line == sercons.index) {
+		if (info->line == zs_console.index) {
 			if (!break_pressed)
 				break_pressed = jiffies;
 		} else
@@ -1557,9 +1557,9 @@
 	}
 
 #ifdef CONFIG_SERIAL_DEC_CONSOLE
-	if (sercons.cflag && sercons.index == line) {
-		tty->termios->c_cflag = sercons.cflag;
-		sercons.cflag = 0;
+	if (zs_console.cflag && zs_console.index == line) {
+		tty->termios->c_cflag = zs_console.cflag;
+		zs_console.cflag = 0;
 		change_speed(info);
 	}
 #endif
@@ -1581,7 +1581,7 @@
 /*  Initialize Z8530s zs_channels
  */
 
-static void probe_sccs(void)
+static void __init probe_sccs(void)
 {
 	struct dec_serial **pp;
 	int i, n, n_chips = 0, n_channels, chip, channel;
@@ -1923,7 +1923,7 @@
  *	- initialize the serial port
  *	Return non-zero if we didn't find a serial port.
  */
-static int serial_console_setup(struct console *co, char *options)
+static int __init serial_console_setup(struct console *co, char *options)
 {
 	struct dec_serial *info;
 	int baud = 9600;
@@ -2069,7 +2069,7 @@
 	return 0;
 }
 
-static struct console sercons = {
+static struct console zs_console = {
 	.name		= "ttyS",
 	.write		= serial_console_write,
 	.device		= serial_console_device,
@@ -2083,7 +2083,7 @@
  */
 void __init zs_serial_console_init(void)
 {
-	register_console(&sercons);
+	register_console(&zs_console);
 }
 #endif /* ifdef CONFIG_SERIAL_DEC_CONSOLE */
 
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 24f10a1..a9cf8b3 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1109,11 +1109,6 @@
 
 	dev_warn(&rhdev->dev, "root hub lost power or was reset\n");
 
-	/* Make sure no potential wakeup events get lost,
-	 * by forcing the root hub to be resumed.
-	 */
-	rhdev->dev.power.prev_state.event = PM_EVENT_ON;
-
 	spin_lock_irqsave(&device_state_lock, flags);
 	hub = hdev_to_hub(rhdev);
 	for (port1 = 1; port1 <= rhdev->maxchild; ++port1) {
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 2ce0501..2349e71 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -2102,7 +2102,9 @@
 }
 
 
-static ssize_t radeon_show_edid1(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t radeon_show_edid1(struct kobject *kobj,
+				 struct bin_attribute *bin_attr,
+				 char *buf, loff_t off, size_t count)
 {
 	struct device *dev = container_of(kobj, struct device, kobj);
 	struct pci_dev *pdev = to_pci_dev(dev);
@@ -2113,7 +2115,9 @@
 }
 
 
-static ssize_t radeon_show_edid2(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t radeon_show_edid2(struct kobject *kobj,
+				 struct bin_attribute *bin_attr,
+				 char *buf, loff_t off, size_t count)
 {
 	struct device *dev = container_of(kobj, struct device, kobj);
 	struct pci_dev *pdev = to_pci_dev(dev);
@@ -2126,7 +2130,6 @@
 static struct bin_attribute edid1_attr = {
 	.attr   = {
 		.name	= "edid1",
-		.owner	= THIS_MODULE,
 		.mode	= 0444,
 	},
 	.size	= EDID_LENGTH,
@@ -2136,7 +2139,6 @@
 static struct bin_attribute edid2_attr = {
 	.attr   = {
 		.name	= "edid2",
-		.owner	= THIS_MODULE,
 		.mode	= 0444,
 	},
 	.size	= EDID_LENGTH,
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index c65e81f..7e06223 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -172,7 +172,7 @@
 
 #define DECLARE_ATTR(_name,_mode,_show,_store)			\
 {							 	\
-	.attr	= { .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },	\
+	.attr	= { .name = __stringify(_name), .mode = _mode }, \
 	.show	= _show,					\
 	.store	= _store,					\
 }
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 6ef8f0a..648b53c 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -157,7 +157,7 @@
 
 #define DECLARE_ATTR(_name,_mode,_show,_store)			\
 {							 	\
-	.attr	= { .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },	\
+	.attr	= { .name = __stringify(_name), .mode = _mode }, \
 	.show	= _show,					\
 	.store	= _store,					\
 }
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 63b85bf..d3b8a6b 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -6,7 +6,7 @@
 
 config VGA_CONSOLE
 	bool "VGA text console" if EMBEDDED || !X86
-	depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE && !SUPERH
+	depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE && !SUPERH && !BFIN
 	default y
 	help
 	  Saying Y here will allow you to use Linux in text mode through a
diff --git a/drivers/video/matrox/matroxfb_crtc2.h b/drivers/video/matrox/matroxfb_crtc2.h
index 608e40b..1771776 100644
--- a/drivers/video/matrox/matroxfb_crtc2.h
+++ b/drivers/video/matrox/matroxfb_crtc2.h
@@ -2,8 +2,6 @@
 #define __MATROXFB_CRTC2_H__
 
 #include <linux/ioctl.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
 #include "matroxfb_base.h"
 
 struct matroxfb_dh_fb_info {
diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c
index 8ea17a5..cab5600 100644
--- a/drivers/w1/slaves/w1_ds2433.c
+++ b/drivers/w1/slaves/w1_ds2433.c
@@ -91,8 +91,9 @@
 }
 #endif	/* CONFIG_W1_SLAVE_DS2433_CRC */
 
-static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off,
-			       size_t count)
+static ssize_t w1_f23_read_bin(struct kobject *kobj,
+			       struct bin_attribute *bin_attr,
+			       char *buf, loff_t off, size_t count)
 {
 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
 #ifdef CONFIG_W1_SLAVE_DS2433_CRC
@@ -199,8 +200,9 @@
 	return 0;
 }
 
-static ssize_t w1_f23_write_bin(struct kobject *kobj, char *buf, loff_t off,
-				size_t count)
+static ssize_t w1_f23_write_bin(struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
 {
 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
 	int addr, len, idx;
@@ -252,7 +254,6 @@
 	.attr = {
 		.name = "eeprom",
 		.mode = S_IRUGO | S_IWUSR,
-		.owner = THIS_MODULE,
 	},
 	.size = W1_EEPROM_SIZE,
 	.read = w1_f23_read_bin,
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index 1a6937dc..4318935 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -42,13 +42,13 @@
 				{}
 			};
 
-static ssize_t w1_therm_read_bin(struct kobject *, char *, loff_t, size_t);
+static ssize_t w1_therm_read_bin(struct kobject *, struct bin_attribute *,
+				 char *, loff_t, size_t);
 
 static struct bin_attribute w1_therm_bin_attr = {
 	.attr = {
 		.name = "w1_slave",
 		.mode = S_IRUGO,
-		.owner = THIS_MODULE,
 	},
 	.size = W1_SLAVE_DATA_SIZE,
 	.read = w1_therm_read_bin,
@@ -159,7 +159,9 @@
 	return 0;
 }
 
-static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t w1_therm_read_bin(struct kobject *kobj,
+				 struct bin_attribute *bin_attr,
+				 char *buf, loff_t off, size_t count)
 {
 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
 	struct w1_master *dev = sl->master;
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 7d6876d..f5c5b76 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -105,7 +105,9 @@
 	return sprintf(buf, "%s\n", sl->name);
 }
 
-static ssize_t w1_slave_read_id(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t w1_slave_read_id(struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
 {
 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
 
@@ -128,7 +130,6 @@
       .attr = {
               .name = "id",
               .mode = S_IRUGO,
-              .owner = THIS_MODULE,
       },
       .size = 8,
       .read = w1_slave_read_id,
@@ -136,7 +137,9 @@
 
 /* Default family */
 
-static ssize_t w1_default_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t w1_default_write(struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
 {
 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
 
@@ -153,7 +156,9 @@
 	return count;
 }
 
-static ssize_t w1_default_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+static ssize_t w1_default_read(struct kobject *kobj,
+			       struct bin_attribute *bin_attr,
+			       char *buf, loff_t off, size_t count)
 {
 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
 
@@ -167,7 +172,6 @@
       .attr = {
               .name = "rw",
               .mode = S_IRUGO | S_IWUSR,
-              .owner = THIS_MODULE,
       },
       .size = PAGE_SIZE,
       .read = w1_default_read,
diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c
index c3ba0ec..9130f1c 100644
--- a/drivers/zorro/zorro-sysfs.c
+++ b/drivers/zorro/zorro-sysfs.c
@@ -49,8 +49,9 @@
 
 static DEVICE_ATTR(resource, S_IRUGO, zorro_show_resource, NULL);
 
-static ssize_t zorro_read_config(struct kobject *kobj, char *buf, loff_t off,
-				 size_t count)
+static ssize_t zorro_read_config(struct kobject *kobj,
+				 struct bin_attribute *bin_attr,
+				 char *buf, loff_t off, size_t count)
 {
 	struct zorro_dev *z = to_zorro_dev(container_of(kobj, struct device,
 					   kobj));
@@ -78,7 +79,6 @@
 	.attr =	{
 		.name = "config",
 		.mode = S_IRUGO | S_IWUSR,
-		.owner = THIS_MODULE
 	},
 	.size = sizeof(struct ConfigDev),
 	.read = zorro_read_config,
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index ec8896b..1d533a2 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -368,6 +368,69 @@
 }
 EXPORT_SYMBOL_GPL(debugfs_remove);
 
+/**
+ * debugfs_rename - rename a file/directory in the debugfs filesystem
+ * @old_dir: a pointer to the parent dentry for the renamed object. This
+ *          should be a directory dentry.
+ * @old_dentry: dentry of an object to be renamed.
+ * @new_dir: a pointer to the parent dentry where the object should be
+ *          moved. This should be a directory dentry.
+ * @new_name: a pointer to a string containing the target name.
+ *
+ * This function renames a file/directory in debugfs.  The target must not
+ * exist for rename to succeed.
+ *
+ * This function will return a pointer to old_dentry (which is updated to
+ * reflect renaming) if it succeeds. If an error occurs, %NULL will be
+ * returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be
+ * returned.
+ */
+struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+		struct dentry *new_dir, const char *new_name)
+{
+	int error;
+	struct dentry *dentry = NULL, *trap;
+	const char *old_name;
+
+	trap = lock_rename(new_dir, old_dir);
+	/* Source or destination directories don't exist? */
+	if (!old_dir->d_inode || !new_dir->d_inode)
+		goto exit;
+	/* Source does not exist, cyclic rename, or mountpoint? */
+	if (!old_dentry->d_inode || old_dentry == trap ||
+	    d_mountpoint(old_dentry))
+		goto exit;
+	dentry = lookup_one_len(new_name, new_dir, strlen(new_name));
+	/* Lookup failed, cyclic rename or target exists? */
+	if (IS_ERR(dentry) || dentry == trap || dentry->d_inode)
+		goto exit;
+
+	old_name = fsnotify_oldname_init(old_dentry->d_name.name);
+
+	error = simple_rename(old_dir->d_inode, old_dentry, new_dir->d_inode,
+		dentry);
+	if (error) {
+		fsnotify_oldname_free(old_name);
+		goto exit;
+	}
+	d_move(old_dentry, dentry);
+	fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
+		old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode),
+		NULL, old_dentry->d_inode);
+	fsnotify_oldname_free(old_name);
+	unlock_rename(new_dir, old_dir);
+	dput(dentry);
+	return old_dentry;
+exit:
+	if (dentry && !IS_ERR(dentry))
+		dput(dentry);
+	unlock_rename(new_dir, old_dir);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(debugfs_rename);
+
 static decl_subsys(debug, NULL, NULL);
 
 static int __init debugfs_init(void)
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 606128f..02ca6f1 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -840,8 +840,6 @@
 		goto out;
 	}
 	kobj_set_kset_s(&ecryptfs_subsys, fs_subsys);
-	sysfs_attr_version.attr.owner = THIS_MODULE;
-	sysfs_attr_version_str.attr.owner = THIS_MODULE;
 	rc = do_sysfs_registration();
 	if (rc) {
 		printk(KERN_ERR "sysfs registration failed\n");
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
index 2b205f5..e9e042b 100644
--- a/fs/ocfs2/cluster/masklog.c
+++ b/fs/ocfs2/cluster/masklog.c
@@ -74,7 +74,6 @@
 #define define_mask(_name) {			\
 	.attr = {				\
 		.name = #_name,			\
-		.owner = THIS_MODULE,		\
 		.mode = S_IRUGO | S_IWUSR,	\
 	},					\
 	.mask = ML_##_name,			\
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 9a3a058..98e0b85 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -397,7 +397,6 @@
 		static struct attribute addpartattr = {
 			.name = "whole_disk",
 			.mode = S_IRUSR | S_IRGRP | S_IROTH,
-			.owner = THIS_MODULE,
 		};
 
 		sysfs_create_file(&p->kobj, &addpartattr);
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index d3b9f5f..135353f 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -20,29 +20,41 @@
 
 #include "sysfs.h"
 
+struct bin_buffer {
+	struct mutex	mutex;
+	void		*buffer;
+	int		mmapped;
+};
+
 static int
 fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count)
 {
-	struct bin_attribute * attr = to_bin_attr(dentry);
-	struct kobject * kobj = to_kobj(dentry->d_parent);
+	struct sysfs_dirent *attr_sd = dentry->d_fsdata;
+	struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
+	struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
+	int rc;
 
-	if (!attr->read)
-		return -EIO;
+	/* need attr_sd for attr, its parent for kobj */
+	if (!sysfs_get_active_two(attr_sd))
+		return -ENODEV;
 
-	return attr->read(kobj, buffer, off, count);
+	rc = -EIO;
+	if (attr->read)
+		rc = attr->read(kobj, attr, buffer, off, count);
+
+	sysfs_put_active_two(attr_sd);
+
+	return rc;
 }
 
 static ssize_t
-read(struct file * file, char __user * userbuf, size_t count, loff_t * off)
+read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
 {
-	char *buffer = file->private_data;
+	struct bin_buffer *bb = file->private_data;
 	struct dentry *dentry = file->f_path.dentry;
 	int size = dentry->d_inode->i_size;
 	loff_t offs = *off;
-	int ret;
-
-	if (count > PAGE_SIZE)
-		count = PAGE_SIZE;
+	int count = min_t(size_t, bytes, PAGE_SIZE);
 
 	if (size) {
 		if (offs > size)
@@ -51,43 +63,56 @@
 			count = size - offs;
 	}
 
-	ret = fill_read(dentry, buffer, offs, count);
-	if (ret < 0) 
-		return ret;
-	count = ret;
+	mutex_lock(&bb->mutex);
 
-	if (copy_to_user(userbuf, buffer, count))
-		return -EFAULT;
+	count = fill_read(dentry, bb->buffer, offs, count);
+	if (count < 0)
+		goto out_unlock;
 
-	pr_debug("offs = %lld, *off = %lld, count = %zd\n", offs, *off, count);
+	if (copy_to_user(userbuf, bb->buffer, count)) {
+		count = -EFAULT;
+		goto out_unlock;
+	}
+
+	pr_debug("offs = %lld, *off = %lld, count = %d\n", offs, *off, count);
 
 	*off = offs + count;
 
+ out_unlock:
+	mutex_unlock(&bb->mutex);
 	return count;
 }
 
 static int
 flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count)
 {
-	struct bin_attribute *attr = to_bin_attr(dentry);
-	struct kobject *kobj = to_kobj(dentry->d_parent);
+	struct sysfs_dirent *attr_sd = dentry->d_fsdata;
+	struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
+	struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
+	int rc;
 
-	if (!attr->write)
-		return -EIO;
+	/* need attr_sd for attr, its parent for kobj */
+	if (!sysfs_get_active_two(attr_sd))
+		return -ENODEV;
 
-	return attr->write(kobj, buffer, offset, count);
+	rc = -EIO;
+	if (attr->write)
+		rc = attr->write(kobj, attr, buffer, offset, count);
+
+	sysfs_put_active_two(attr_sd);
+
+	return rc;
 }
 
-static ssize_t write(struct file * file, const char __user * userbuf,
-		     size_t count, loff_t * off)
+static ssize_t write(struct file *file, const char __user *userbuf,
+		     size_t bytes, loff_t *off)
 {
-	char *buffer = file->private_data;
+	struct bin_buffer *bb = file->private_data;
 	struct dentry *dentry = file->f_path.dentry;
 	int size = dentry->d_inode->i_size;
 	loff_t offs = *off;
+	int count = min_t(size_t, bytes, PAGE_SIZE);
 
-	if (count > PAGE_SIZE)
-		count = PAGE_SIZE;
 	if (size) {
 		if (offs > size)
 			return 0;
@@ -95,72 +120,100 @@
 			count = size - offs;
 	}
 
-	if (copy_from_user(buffer, userbuf, count))
-		return -EFAULT;
+	mutex_lock(&bb->mutex);
 
-	count = flush_write(dentry, buffer, offs, count);
+	if (copy_from_user(bb->buffer, userbuf, count)) {
+		count = -EFAULT;
+		goto out_unlock;
+	}
+
+	count = flush_write(dentry, bb->buffer, offs, count);
 	if (count > 0)
 		*off = offs + count;
+
+ out_unlock:
+	mutex_unlock(&bb->mutex);
 	return count;
 }
 
 static int mmap(struct file *file, struct vm_area_struct *vma)
 {
-	struct dentry *dentry = file->f_path.dentry;
-	struct bin_attribute *attr = to_bin_attr(dentry);
-	struct kobject *kobj = to_kobj(dentry->d_parent);
+	struct bin_buffer *bb = file->private_data;
+	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+	struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
+	struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
+	int rc;
 
-	if (!attr->mmap)
-		return -EINVAL;
+	mutex_lock(&bb->mutex);
 
-	return attr->mmap(kobj, attr, vma);
+	/* need attr_sd for attr, its parent for kobj */
+	if (!sysfs_get_active_two(attr_sd))
+		return -ENODEV;
+
+	rc = -EINVAL;
+	if (attr->mmap)
+		rc = attr->mmap(kobj, attr, vma);
+
+	if (rc == 0 && !bb->mmapped)
+		bb->mmapped = 1;
+	else
+		sysfs_put_active_two(attr_sd);
+
+	mutex_unlock(&bb->mutex);
+
+	return rc;
 }
 
 static int open(struct inode * inode, struct file * file)
 {
-	struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent);
-	struct bin_attribute * attr = to_bin_attr(file->f_path.dentry);
-	int error = -EINVAL;
+	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+	struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
+	struct bin_buffer *bb = NULL;
+	int error;
 
-	if (!kobj || !attr)
-		goto Done;
-
-	/* Grab the module reference for this attribute if we have one */
-	error = -ENODEV;
-	if (!try_module_get(attr->attr.owner)) 
-		goto Done;
+	/* need attr_sd for attr */
+	if (!sysfs_get_active(attr_sd))
+		return -ENODEV;
 
 	error = -EACCES;
 	if ((file->f_mode & FMODE_WRITE) && !(attr->write || attr->mmap))
-		goto Error;
+		goto err_out;
 	if ((file->f_mode & FMODE_READ) && !(attr->read || attr->mmap))
-		goto Error;
+		goto err_out;
 
 	error = -ENOMEM;
-	file->private_data = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!file->private_data)
-		goto Error;
+	bb = kzalloc(sizeof(*bb), GFP_KERNEL);
+	if (!bb)
+		goto err_out;
 
-	error = 0;
-    goto Done;
+	bb->buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!bb->buffer)
+		goto err_out;
 
- Error:
-	module_put(attr->attr.owner);
- Done:
-	if (error)
-		kobject_put(kobj);
+	mutex_init(&bb->mutex);
+	file->private_data = bb;
+
+	/* open succeeded, put active reference and pin attr_sd */
+	sysfs_put_active(attr_sd);
+	sysfs_get(attr_sd);
+	return 0;
+
+ err_out:
+	sysfs_put_active(attr_sd);
+	kfree(bb);
 	return error;
 }
 
 static int release(struct inode * inode, struct file * file)
 {
-	struct kobject * kobj = to_kobj(file->f_path.dentry->d_parent);
-	struct bin_attribute * attr = to_bin_attr(file->f_path.dentry);
-	u8 * buffer = file->private_data;
+	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+	struct bin_buffer *bb = file->private_data;
 
-	kobject_put(kobj);
-	module_put(attr->attr.owner);
-	kfree(buffer);
+	if (bb->mmapped)
+		sysfs_put_active_two(attr_sd);
+	sysfs_put(attr_sd);
+	kfree(bb->buffer);
+	kfree(bb);
 	return 0;
 }
 
@@ -181,9 +234,9 @@
 
 int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr)
 {
-	BUG_ON(!kobj || !kobj->dentry || !attr);
+	BUG_ON(!kobj || !kobj->sd || !attr);
 
-	return sysfs_add_file(kobj->dentry, &attr->attr, SYSFS_KOBJ_BIN_ATTR);
+	return sysfs_add_file(kobj->sd, &attr->attr, SYSFS_KOBJ_BIN_ATTR);
 }
 
 
@@ -195,7 +248,7 @@
 
 void sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr)
 {
-	if (sysfs_hash_and_remove(kobj->dentry, attr->attr.name) < 0) {
+	if (sysfs_hash_and_remove(kobj->sd, attr->attr.name) < 0) {
 		printk(KERN_ERR "%s: "
 			"bad dentry or inode or no such file: \"%s\"\n",
 			__FUNCTION__, attr->attr.name);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index c4342a0..aee966c 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -9,21 +9,337 @@
 #include <linux/module.h>
 #include <linux/kobject.h>
 #include <linux/namei.h>
+#include <linux/idr.h>
+#include <linux/completion.h>
 #include <asm/semaphore.h>
 #include "sysfs.h"
 
-DECLARE_RWSEM(sysfs_rename_sem);
-spinlock_t sysfs_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_MUTEX(sysfs_mutex);
+spinlock_t sysfs_assoc_lock = SPIN_LOCK_UNLOCKED;
+
+static spinlock_t sysfs_ino_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_IDA(sysfs_ino_ida);
+
+/**
+ *	sysfs_link_sibling - link sysfs_dirent into sibling list
+ *	@sd: sysfs_dirent of interest
+ *
+ *	Link @sd into its sibling list which starts from
+ *	sd->s_parent->s_children.
+ *
+ *	Locking:
+ *	mutex_lock(sysfs_mutex)
+ */
+void sysfs_link_sibling(struct sysfs_dirent *sd)
+{
+	struct sysfs_dirent *parent_sd = sd->s_parent;
+
+	BUG_ON(sd->s_sibling);
+	sd->s_sibling = parent_sd->s_children;
+	parent_sd->s_children = sd;
+}
+
+/**
+ *	sysfs_unlink_sibling - unlink sysfs_dirent from sibling list
+ *	@sd: sysfs_dirent of interest
+ *
+ *	Unlink @sd from its sibling list which starts from
+ *	sd->s_parent->s_children.
+ *
+ *	Locking:
+ *	mutex_lock(sysfs_mutex)
+ */
+void sysfs_unlink_sibling(struct sysfs_dirent *sd)
+{
+	struct sysfs_dirent **pos;
+
+	for (pos = &sd->s_parent->s_children; *pos; pos = &(*pos)->s_sibling) {
+		if (*pos == sd) {
+			*pos = sd->s_sibling;
+			sd->s_sibling = NULL;
+			break;
+		}
+	}
+}
+
+/**
+ *	sysfs_get_dentry - get dentry for the given sysfs_dirent
+ *	@sd: sysfs_dirent of interest
+ *
+ *	Get dentry for @sd.  Dentry is looked up if currently not
+ *	present.  This function climbs sysfs_dirent tree till it
+ *	reaches a sysfs_dirent with valid dentry attached and descends
+ *	down from there looking up dentry for each step.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep)
+ *
+ *	RETURNS:
+ *	Pointer to found dentry on success, ERR_PTR() value on error.
+ */
+struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd)
+{
+	struct sysfs_dirent *cur;
+	struct dentry *parent_dentry, *dentry;
+	int i, depth;
+
+	/* Find the first parent which has valid s_dentry and get the
+	 * dentry.
+	 */
+	mutex_lock(&sysfs_mutex);
+ restart0:
+	spin_lock(&sysfs_assoc_lock);
+ restart1:
+	spin_lock(&dcache_lock);
+
+	dentry = NULL;
+	depth = 0;
+	cur = sd;
+	while (!cur->s_dentry || !cur->s_dentry->d_inode) {
+		if (cur->s_flags & SYSFS_FLAG_REMOVED) {
+			dentry = ERR_PTR(-ENOENT);
+			depth = 0;
+			break;
+		}
+		cur = cur->s_parent;
+		depth++;
+	}
+	if (!IS_ERR(dentry))
+		dentry = dget_locked(cur->s_dentry);
+
+	spin_unlock(&dcache_lock);
+	spin_unlock(&sysfs_assoc_lock);
+
+	/* from the found dentry, look up depth times */
+	while (depth--) {
+		/* find and get depth'th ancestor */
+		for (cur = sd, i = 0; cur && i < depth; i++)
+			cur = cur->s_parent;
+
+		/* This can happen if tree structure was modified due
+		 * to move/rename.  Restart.
+		 */
+		if (i != depth) {
+			dput(dentry);
+			goto restart0;
+		}
+
+		sysfs_get(cur);
+
+		mutex_unlock(&sysfs_mutex);
+
+		/* look it up */
+		parent_dentry = dentry;
+		dentry = lookup_one_len_kern(cur->s_name, parent_dentry,
+					     strlen(cur->s_name));
+		dput(parent_dentry);
+
+		if (IS_ERR(dentry)) {
+			sysfs_put(cur);
+			return dentry;
+		}
+
+		mutex_lock(&sysfs_mutex);
+		spin_lock(&sysfs_assoc_lock);
+
+		/* This, again, can happen if tree structure has
+		 * changed and we looked up the wrong thing.  Restart.
+		 */
+		if (cur->s_dentry != dentry) {
+			dput(dentry);
+			sysfs_put(cur);
+			goto restart1;
+		}
+
+		spin_unlock(&sysfs_assoc_lock);
+
+		sysfs_put(cur);
+	}
+
+	mutex_unlock(&sysfs_mutex);
+	return dentry;
+}
+
+/**
+ *	sysfs_get_active - get an active reference to sysfs_dirent
+ *	@sd: sysfs_dirent to get an active reference to
+ *
+ *	Get an active reference of @sd.  This function is noop if @sd
+ *	is NULL.
+ *
+ *	RETURNS:
+ *	Pointer to @sd on success, NULL on failure.
+ */
+struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
+{
+	if (unlikely(!sd))
+		return NULL;
+
+	while (1) {
+		int v, t;
+
+		v = atomic_read(&sd->s_active);
+		if (unlikely(v < 0))
+			return NULL;
+
+		t = atomic_cmpxchg(&sd->s_active, v, v + 1);
+		if (likely(t == v))
+			return sd;
+		if (t < 0)
+			return NULL;
+
+		cpu_relax();
+	}
+}
+
+/**
+ *	sysfs_put_active - put an active reference to sysfs_dirent
+ *	@sd: sysfs_dirent to put an active reference to
+ *
+ *	Put an active reference to @sd.  This function is noop if @sd
+ *	is NULL.
+ */
+void sysfs_put_active(struct sysfs_dirent *sd)
+{
+	struct completion *cmpl;
+	int v;
+
+	if (unlikely(!sd))
+		return;
+
+	v = atomic_dec_return(&sd->s_active);
+	if (likely(v != SD_DEACTIVATED_BIAS))
+		return;
+
+	/* atomic_dec_return() is a mb(), we'll always see the updated
+	 * sd->s_sibling.
+	 */
+	cmpl = (void *)sd->s_sibling;
+	complete(cmpl);
+}
+
+/**
+ *	sysfs_get_active_two - get active references to sysfs_dirent and parent
+ *	@sd: sysfs_dirent of interest
+ *
+ *	Get active reference to @sd and its parent.  Parent's active
+ *	reference is grabbed first.  This function is noop if @sd is
+ *	NULL.
+ *
+ *	RETURNS:
+ *	Pointer to @sd on success, NULL on failure.
+ */
+struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd)
+{
+	if (sd) {
+		if (sd->s_parent && unlikely(!sysfs_get_active(sd->s_parent)))
+			return NULL;
+		if (unlikely(!sysfs_get_active(sd))) {
+			sysfs_put_active(sd->s_parent);
+			return NULL;
+		}
+	}
+	return sd;
+}
+
+/**
+ *	sysfs_put_active_two - put active references to sysfs_dirent and parent
+ *	@sd: sysfs_dirent of interest
+ *
+ *	Put active references to @sd and its parent.  This function is
+ *	noop if @sd is NULL.
+ */
+void sysfs_put_active_two(struct sysfs_dirent *sd)
+{
+	if (sd) {
+		sysfs_put_active(sd);
+		sysfs_put_active(sd->s_parent);
+	}
+}
+
+/**
+ *	sysfs_deactivate - deactivate sysfs_dirent
+ *	@sd: sysfs_dirent to deactivate
+ *
+ *	Deny new active references and drain existing ones.
+ */
+static void sysfs_deactivate(struct sysfs_dirent *sd)
+{
+	DECLARE_COMPLETION_ONSTACK(wait);
+	int v;
+
+	BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED));
+	sd->s_sibling = (void *)&wait;
+
+	/* atomic_add_return() is a mb(), put_active() will always see
+	 * the updated sd->s_sibling.
+	 */
+	v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active);
+
+	if (v != SD_DEACTIVATED_BIAS)
+		wait_for_completion(&wait);
+
+	sd->s_sibling = NULL;
+}
+
+static int sysfs_alloc_ino(ino_t *pino)
+{
+	int ino, rc;
+
+ retry:
+	spin_lock(&sysfs_ino_lock);
+	rc = ida_get_new_above(&sysfs_ino_ida, 2, &ino);
+	spin_unlock(&sysfs_ino_lock);
+
+	if (rc == -EAGAIN) {
+		if (ida_pre_get(&sysfs_ino_ida, GFP_KERNEL))
+			goto retry;
+		rc = -ENOMEM;
+	}
+
+	*pino = ino;
+	return rc;
+}
+
+static void sysfs_free_ino(ino_t ino)
+{
+	spin_lock(&sysfs_ino_lock);
+	ida_remove(&sysfs_ino_ida, ino);
+	spin_unlock(&sysfs_ino_lock);
+}
+
+void release_sysfs_dirent(struct sysfs_dirent * sd)
+{
+	struct sysfs_dirent *parent_sd;
+
+ repeat:
+	/* Moving/renaming is always done while holding reference.
+	 * sd->s_parent won't change beneath us.
+	 */
+	parent_sd = sd->s_parent;
+
+	if (sysfs_type(sd) == SYSFS_KOBJ_LINK)
+		sysfs_put(sd->s_elem.symlink.target_sd);
+	if (sysfs_type(sd) & SYSFS_COPY_NAME)
+		kfree(sd->s_name);
+	kfree(sd->s_iattr);
+	sysfs_free_ino(sd->s_ino);
+	kmem_cache_free(sysfs_dir_cachep, sd);
+
+	sd = parent_sd;
+	if (sd && atomic_dec_and_test(&sd->s_count))
+		goto repeat;
+}
 
 static void sysfs_d_iput(struct dentry * dentry, struct inode * inode)
 {
 	struct sysfs_dirent * sd = dentry->d_fsdata;
 
 	if (sd) {
-		/* sd->s_dentry is protected with sysfs_lock.  This
-		 * allows sysfs_drop_dentry() to dereference it.
+		/* sd->s_dentry is protected with sysfs_assoc_lock.
+		 * This allows sysfs_drop_dentry() to dereference it.
 		 */
-		spin_lock(&sysfs_lock);
+		spin_lock(&sysfs_assoc_lock);
 
 		/* The dentry might have been deleted or another
 		 * lookup could have happened updating sd->s_dentry to
@@ -32,7 +348,7 @@
 		 */
 		if (sd->s_dentry == dentry)
 			sd->s_dentry = NULL;
-		spin_unlock(&sysfs_lock);
+		spin_unlock(&sysfs_assoc_lock);
 		sysfs_put(sd);
 	}
 	iput(inode);
@@ -42,260 +358,402 @@
 	.d_iput		= sysfs_d_iput,
 };
 
-static unsigned int sysfs_inode_counter;
-ino_t sysfs_get_inum(void)
+struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
 {
-	if (unlikely(sysfs_inode_counter < 3))
-		sysfs_inode_counter = 3;
-	return sysfs_inode_counter++;
-}
+	char *dup_name = NULL;
+	struct sysfs_dirent *sd = NULL;
 
-/*
- * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent
- */
-static struct sysfs_dirent * __sysfs_new_dirent(void * element)
-{
-	struct sysfs_dirent * sd;
+	if (type & SYSFS_COPY_NAME) {
+		name = dup_name = kstrdup(name, GFP_KERNEL);
+		if (!name)
+			goto err_out;
+	}
 
 	sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL);
 	if (!sd)
-		return NULL;
+		goto err_out;
 
-	sd->s_ino = sysfs_get_inum();
+	if (sysfs_alloc_ino(&sd->s_ino))
+		goto err_out;
+
 	atomic_set(&sd->s_count, 1);
+	atomic_set(&sd->s_active, 0);
 	atomic_set(&sd->s_event, 1);
-	INIT_LIST_HEAD(&sd->s_children);
-	INIT_LIST_HEAD(&sd->s_sibling);
-	sd->s_element = element;
 
-	return sd;
-}
-
-static void __sysfs_list_dirent(struct sysfs_dirent *parent_sd,
-			      struct sysfs_dirent *sd)
-{
-	if (sd)
-		list_add(&sd->s_sibling, &parent_sd->s_children);
-}
-
-static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent *parent_sd,
-						void * element)
-{
-	struct sysfs_dirent *sd;
-	sd = __sysfs_new_dirent(element);
-	__sysfs_list_dirent(parent_sd, sd);
-	return sd;
-}
-
-/*
- *
- * Return -EEXIST if there is already a sysfs element with the same name for
- * the same parent.
- *
- * called with parent inode's i_mutex held
- */
-int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
-			  const unsigned char *new)
-{
-	struct sysfs_dirent * sd;
-
-	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
-		if (sd->s_element) {
-			const unsigned char *existing = sysfs_get_name(sd);
-			if (strcmp(existing, new))
-				continue;
-			else
-				return -EEXIST;
-		}
-	}
-
-	return 0;
-}
-
-
-static struct sysfs_dirent *
-__sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type)
-{
-	struct sysfs_dirent * sd;
-
-	sd = __sysfs_new_dirent(element);
-	if (!sd)
-		goto out;
-
+	sd->s_name = name;
 	sd->s_mode = mode;
-	sd->s_type = type;
-	sd->s_dentry = dentry;
-	if (dentry) {
-		dentry->d_fsdata = sysfs_get(sd);
-		dentry->d_op = &sysfs_dentry_ops;
-	}
+	sd->s_flags = type;
 
-out:
 	return sd;
+
+ err_out:
+	kfree(dup_name);
+	kmem_cache_free(sysfs_dir_cachep, sd);
+	return NULL;
 }
 
-int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
-			void * element, umode_t mode, int type)
+/**
+ *	sysfs_attach_dentry - associate sysfs_dirent with dentry
+ *	@sd: target sysfs_dirent
+ *	@dentry: dentry to associate
+ *
+ *	Associate @sd with @dentry.  This is protected by
+ *	sysfs_assoc_lock to avoid race with sysfs_d_iput().
+ *
+ *	LOCKING:
+ *	mutex_lock(sysfs_mutex)
+ */
+static void sysfs_attach_dentry(struct sysfs_dirent *sd, struct dentry *dentry)
+{
+	dentry->d_op = &sysfs_dentry_ops;
+	dentry->d_fsdata = sysfs_get(sd);
+
+	/* protect sd->s_dentry against sysfs_d_iput */
+	spin_lock(&sysfs_assoc_lock);
+	sd->s_dentry = dentry;
+	spin_unlock(&sysfs_assoc_lock);
+
+	d_rehash(dentry);
+}
+
+static int sysfs_ilookup_test(struct inode *inode, void *arg)
+{
+	struct sysfs_dirent *sd = arg;
+	return inode->i_ino == sd->s_ino;
+}
+
+/**
+ *	sysfs_addrm_start - prepare for sysfs_dirent add/remove
+ *	@acxt: pointer to sysfs_addrm_cxt to be used
+ *	@parent_sd: parent sysfs_dirent
+ *
+ *	This function is called when the caller is about to add or
+ *	remove sysfs_dirent under @parent_sd.  This function acquires
+ *	sysfs_mutex, grabs inode for @parent_sd if available and lock
+ *	i_mutex of it.  @acxt is used to keep and pass context to
+ *	other addrm functions.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).  sysfs_mutex is locked on
+ *	return.  i_mutex of parent inode is locked on return if
+ *	available.
+ */
+void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
+		       struct sysfs_dirent *parent_sd)
+{
+	struct inode *inode;
+
+	memset(acxt, 0, sizeof(*acxt));
+	acxt->parent_sd = parent_sd;
+
+	/* Lookup parent inode.  inode initialization and I_NEW
+	 * clearing are protected by sysfs_mutex.  By grabbing it and
+	 * looking up with _nowait variant, inode state can be
+	 * determined reliably.
+	 */
+	mutex_lock(&sysfs_mutex);
+
+	inode = ilookup5_nowait(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
+				parent_sd);
+
+	if (inode && !(inode->i_state & I_NEW)) {
+		/* parent inode available */
+		acxt->parent_inode = inode;
+
+		/* sysfs_mutex is below i_mutex in lock hierarchy.
+		 * First, trylock i_mutex.  If fails, unlock
+		 * sysfs_mutex and lock them in order.
+		 */
+		if (!mutex_trylock(&inode->i_mutex)) {
+			mutex_unlock(&sysfs_mutex);
+			mutex_lock(&inode->i_mutex);
+			mutex_lock(&sysfs_mutex);
+		}
+	} else
+		iput(inode);
+}
+
+/**
+ *	sysfs_add_one - add sysfs_dirent to parent
+ *	@acxt: addrm context to use
+ *	@sd: sysfs_dirent to be added
+ *
+ *	Get @acxt->parent_sd and set sd->s_parent to it and increment
+ *	nlink of parent inode if @sd is a directory.  @sd is NOT
+ *	linked into the children list of the parent.  The caller
+ *	should invoke sysfs_link_sibling() after this function
+ *	completes if @sd needs to be on the children list.
+ *
+ *	This function should be called between calls to
+ *	sysfs_addrm_start() and sysfs_addrm_finish() and should be
+ *	passed the same @acxt as passed to sysfs_addrm_start().
+ *
+ *	LOCKING:
+ *	Determined by sysfs_addrm_start().
+ */
+void sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
+{
+	sd->s_parent = sysfs_get(acxt->parent_sd);
+
+	if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode)
+		inc_nlink(acxt->parent_inode);
+
+	acxt->cnt++;
+}
+
+/**
+ *	sysfs_remove_one - remove sysfs_dirent from parent
+ *	@acxt: addrm context to use
+ *	@sd: sysfs_dirent to be added
+ *
+ *	Mark @sd removed and drop nlink of parent inode if @sd is a
+ *	directory.  @sd is NOT unlinked from the children list of the
+ *	parent.  The caller is repsonsible for removing @sd from the
+ *	children list before calling this function.
+ *
+ *	This function should be called between calls to
+ *	sysfs_addrm_start() and sysfs_addrm_finish() and should be
+ *	passed the same @acxt as passed to sysfs_addrm_start().
+ *
+ *	LOCKING:
+ *	Determined by sysfs_addrm_start().
+ */
+void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
+{
+	BUG_ON(sd->s_sibling || (sd->s_flags & SYSFS_FLAG_REMOVED));
+
+	sd->s_flags |= SYSFS_FLAG_REMOVED;
+	sd->s_sibling = acxt->removed;
+	acxt->removed = sd;
+
+	if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode)
+		drop_nlink(acxt->parent_inode);
+
+	acxt->cnt++;
+}
+
+/**
+ *	sysfs_drop_dentry - drop dentry for the specified sysfs_dirent
+ *	@sd: target sysfs_dirent
+ *
+ *	Drop dentry for @sd.  @sd must have been unlinked from its
+ *	parent on entry to this function such that it can't be looked
+ *	up anymore.
+ *
+ *	@sd->s_dentry which is protected with sysfs_assoc_lock points
+ *	to the currently associated dentry but we're not holding a
+ *	reference to it and racing with dput().  Grab dcache_lock and
+ *	verify dentry before dropping it.  If @sd->s_dentry is NULL or
+ *	dput() beats us, no need to bother.
+ */
+static void sysfs_drop_dentry(struct sysfs_dirent *sd)
+{
+	struct dentry *dentry = NULL;
+	struct inode *inode;
+
+	/* We're not holding a reference to ->s_dentry dentry but the
+	 * field will stay valid as long as sysfs_assoc_lock is held.
+	 */
+	spin_lock(&sysfs_assoc_lock);
+	spin_lock(&dcache_lock);
+
+	/* drop dentry if it's there and dput() didn't kill it yet */
+	if (sd->s_dentry && sd->s_dentry->d_inode) {
+		dentry = dget_locked(sd->s_dentry);
+		spin_lock(&dentry->d_lock);
+		__d_drop(dentry);
+		spin_unlock(&dentry->d_lock);
+	}
+
+	spin_unlock(&dcache_lock);
+	spin_unlock(&sysfs_assoc_lock);
+
+	/* dentries for shadowed inodes are pinned, unpin */
+	if (dentry && sysfs_is_shadowed_inode(dentry->d_inode))
+		dput(dentry);
+	dput(dentry);
+
+	/* adjust nlink and update timestamp */
+	inode = ilookup(sysfs_sb, sd->s_ino);
+	if (inode) {
+		mutex_lock(&inode->i_mutex);
+
+		inode->i_ctime = CURRENT_TIME;
+		drop_nlink(inode);
+		if (sysfs_type(sd) == SYSFS_DIR)
+			drop_nlink(inode);
+
+		mutex_unlock(&inode->i_mutex);
+		iput(inode);
+	}
+}
+
+/**
+ *	sysfs_addrm_finish - finish up sysfs_dirent add/remove
+ *	@acxt: addrm context to finish up
+ *
+ *	Finish up sysfs_dirent add/remove.  Resources acquired by
+ *	sysfs_addrm_start() are released and removed sysfs_dirents are
+ *	cleaned up.  Timestamps on the parent inode are updated.
+ *
+ *	LOCKING:
+ *	All mutexes acquired by sysfs_addrm_start() are released.
+ *
+ *	RETURNS:
+ *	Number of added/removed sysfs_dirents since sysfs_addrm_start().
+ */
+int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
+{
+	/* release resources acquired by sysfs_addrm_start() */
+	mutex_unlock(&sysfs_mutex);
+	if (acxt->parent_inode) {
+		struct inode *inode = acxt->parent_inode;
+
+		/* if added/removed, update timestamps on the parent */
+		if (acxt->cnt)
+			inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+
+		mutex_unlock(&inode->i_mutex);
+		iput(inode);
+	}
+
+	/* kill removed sysfs_dirents */
+	while (acxt->removed) {
+		struct sysfs_dirent *sd = acxt->removed;
+
+		acxt->removed = sd->s_sibling;
+		sd->s_sibling = NULL;
+
+		sysfs_drop_dentry(sd);
+		sysfs_deactivate(sd);
+		sysfs_put(sd);
+	}
+
+	return acxt->cnt;
+}
+
+/**
+ *	sysfs_find_dirent - find sysfs_dirent with the given name
+ *	@parent_sd: sysfs_dirent to search under
+ *	@name: name to look for
+ *
+ *	Look for sysfs_dirent with name @name under @parent_sd.
+ *
+ *	LOCKING:
+ *	mutex_lock(sysfs_mutex)
+ *
+ *	RETURNS:
+ *	Pointer to sysfs_dirent if found, NULL if not.
+ */
+struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
+				       const unsigned char *name)
 {
 	struct sysfs_dirent *sd;
 
-	sd = __sysfs_make_dirent(dentry, element, mode, type);
-	__sysfs_list_dirent(parent_sd, sd);
-
-	return sd ? 0 : -ENOMEM;
+	for (sd = parent_sd->s_children; sd; sd = sd->s_sibling)
+		if (sysfs_type(sd) && !strcmp(sd->s_name, name))
+			return sd;
+	return NULL;
 }
 
-static int init_dir(struct inode * inode)
+/**
+ *	sysfs_get_dirent - find and get sysfs_dirent with the given name
+ *	@parent_sd: sysfs_dirent to search under
+ *	@name: name to look for
+ *
+ *	Look for sysfs_dirent with name @name under @parent_sd and get
+ *	it if found.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).  Grabs sysfs_mutex.
+ *
+ *	RETURNS:
+ *	Pointer to sysfs_dirent if found, NULL if not.
+ */
+struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+				      const unsigned char *name)
 {
-	inode->i_op = &sysfs_dir_inode_operations;
-	inode->i_fop = &sysfs_dir_operations;
+	struct sysfs_dirent *sd;
 
-	/* directory inodes start off with i_nlink == 2 (for "." entry) */
-	inc_nlink(inode);
-	return 0;
+	mutex_lock(&sysfs_mutex);
+	sd = sysfs_find_dirent(parent_sd, name);
+	sysfs_get(sd);
+	mutex_unlock(&sysfs_mutex);
+
+	return sd;
 }
 
-static int init_file(struct inode * inode)
+static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
+		      const char *name, struct sysfs_dirent **p_sd)
 {
-	inode->i_size = PAGE_SIZE;
-	inode->i_fop = &sysfs_file_operations;
-	return 0;
-}
-
-static int init_symlink(struct inode * inode)
-{
-	inode->i_op = &sysfs_symlink_inode_operations;
-	return 0;
-}
-
-static int create_dir(struct kobject * k, struct dentry * p,
-		      const char * n, struct dentry ** d)
-{
-	int error;
 	umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
+	struct sysfs_addrm_cxt acxt;
+	struct sysfs_dirent *sd;
 
-	mutex_lock(&p->d_inode->i_mutex);
-	*d = lookup_one_len(n, p, strlen(n));
-	if (!IS_ERR(*d)) {
- 		if (sysfs_dirent_exist(p->d_fsdata, n))
-  			error = -EEXIST;
-  		else
-			error = sysfs_make_dirent(p->d_fsdata, *d, k, mode,
-								SYSFS_DIR);
-		if (!error) {
-			error = sysfs_create(*d, mode, init_dir);
-			if (!error) {
-				inc_nlink(p->d_inode);
-				(*d)->d_op = &sysfs_dentry_ops;
-				d_rehash(*d);
-			}
-		}
-		if (error && (error != -EEXIST)) {
-			struct sysfs_dirent *sd = (*d)->d_fsdata;
-			if (sd) {
- 				list_del_init(&sd->s_sibling);
-				sysfs_put(sd);
-			}
-			d_drop(*d);
-		}
-		dput(*d);
-	} else
-		error = PTR_ERR(*d);
-	mutex_unlock(&p->d_inode->i_mutex);
-	return error;
+	/* allocate */
+	sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
+	if (!sd)
+		return -ENOMEM;
+	sd->s_elem.dir.kobj = kobj;
+
+	/* link in */
+	sysfs_addrm_start(&acxt, parent_sd);
+	if (!sysfs_find_dirent(parent_sd, name)) {
+		sysfs_add_one(&acxt, sd);
+		sysfs_link_sibling(sd);
+	}
+	if (sysfs_addrm_finish(&acxt)) {
+		*p_sd = sd;
+		return 0;
+	}
+
+	sysfs_put(sd);
+	return -EEXIST;
 }
 
-
-int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d)
+int sysfs_create_subdir(struct kobject *kobj, const char *name,
+			struct sysfs_dirent **p_sd)
 {
-	return create_dir(k,k->dentry,n,d);
+	return create_dir(kobj, kobj->sd, name, p_sd);
 }
 
 /**
  *	sysfs_create_dir - create a directory for an object.
  *	@kobj:		object we're creating directory for. 
- *	@shadow_parent:	parent parent object.
+ *	@shadow_parent:	parent object.
  */
-
-int sysfs_create_dir(struct kobject * kobj, struct dentry *shadow_parent)
+int sysfs_create_dir(struct kobject *kobj,
+		     struct sysfs_dirent *shadow_parent_sd)
 {
-	struct dentry * dentry = NULL;
-	struct dentry * parent;
+	struct sysfs_dirent *parent_sd, *sd;
 	int error = 0;
 
 	BUG_ON(!kobj);
 
-	if (shadow_parent)
-		parent = shadow_parent;
+	if (shadow_parent_sd)
+		parent_sd = shadow_parent_sd;
 	else if (kobj->parent)
-		parent = kobj->parent->dentry;
+		parent_sd = kobj->parent->sd;
 	else if (sysfs_mount && sysfs_mount->mnt_sb)
-		parent = sysfs_mount->mnt_sb->s_root;
+		parent_sd = sysfs_mount->mnt_sb->s_root->d_fsdata;
 	else
 		return -EFAULT;
 
-	error = create_dir(kobj,parent,kobject_name(kobj),&dentry);
+	error = create_dir(kobj, parent_sd, kobject_name(kobj), &sd);
 	if (!error)
-		kobj->dentry = dentry;
+		kobj->sd = sd;
 	return error;
 }
 
-/* attaches attribute's sysfs_dirent to the dentry corresponding to the
- * attribute file
- */
-static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry)
+static int sysfs_count_nlink(struct sysfs_dirent *sd)
 {
-	struct attribute * attr = NULL;
-	struct bin_attribute * bin_attr = NULL;
-	int (* init) (struct inode *) = NULL;
-	int error = 0;
+	struct sysfs_dirent *child;
+	int nr = 0;
 
-        if (sd->s_type & SYSFS_KOBJ_BIN_ATTR) {
-                bin_attr = sd->s_element;
-                attr = &bin_attr->attr;
-        } else {
-                attr = sd->s_element;
-                init = init_file;
-        }
-
-	dentry->d_fsdata = sysfs_get(sd);
-	/* protect sd->s_dentry against sysfs_d_iput */
-	spin_lock(&sysfs_lock);
-	sd->s_dentry = dentry;
-	spin_unlock(&sysfs_lock);
-	error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init);
-	if (error) {
-		sysfs_put(sd);
-		return error;
-	}
-
-        if (bin_attr) {
-		dentry->d_inode->i_size = bin_attr->size;
-		dentry->d_inode->i_fop = &bin_fops;
-	}
-	dentry->d_op = &sysfs_dentry_ops;
-	d_rehash(dentry);
-
-	return 0;
-}
-
-static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry)
-{
-	int err = 0;
-
-	dentry->d_fsdata = sysfs_get(sd);
-	/* protect sd->s_dentry against sysfs_d_iput */
-	spin_lock(&sysfs_lock);
-	sd->s_dentry = dentry;
-	spin_unlock(&sysfs_lock);
-	err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink);
-	if (!err) {
-		dentry->d_op = &sysfs_dentry_ops;
-		d_rehash(dentry);
-	} else
-		sysfs_put(sd);
-
-	return err;
+	for (child = sd->s_children; child; child = child->s_sibling)
+		if (sysfs_type(child) == SYSFS_DIR)
+			nr++;
+	return nr + 2;
 }
 
 static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
@@ -303,24 +761,60 @@
 {
 	struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
 	struct sysfs_dirent * sd;
-	int err = 0;
+	struct bin_attribute *bin_attr;
+	struct inode *inode;
+	int found = 0;
 
-	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
-		if (sd->s_type & SYSFS_NOT_PINNED) {
-			const unsigned char * name = sysfs_get_name(sd);
-
-			if (strcmp(name, dentry->d_name.name))
-				continue;
-
-			if (sd->s_type & SYSFS_KOBJ_LINK)
-				err = sysfs_attach_link(sd, dentry);
-			else
-				err = sysfs_attach_attr(sd, dentry);
+	for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) {
+		if (sysfs_type(sd) &&
+		    !strcmp(sd->s_name, dentry->d_name.name)) {
+			found = 1;
 			break;
 		}
 	}
 
-	return ERR_PTR(err);
+	/* no such entry */
+	if (!found)
+		return NULL;
+
+	/* attach dentry and inode */
+	inode = sysfs_get_inode(sd);
+	if (!inode)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_lock(&sysfs_mutex);
+
+	if (inode->i_state & I_NEW) {
+		/* initialize inode according to type */
+		switch (sysfs_type(sd)) {
+		case SYSFS_DIR:
+			inode->i_op = &sysfs_dir_inode_operations;
+			inode->i_fop = &sysfs_dir_operations;
+			inode->i_nlink = sysfs_count_nlink(sd);
+			break;
+		case SYSFS_KOBJ_ATTR:
+			inode->i_size = PAGE_SIZE;
+			inode->i_fop = &sysfs_file_operations;
+			break;
+		case SYSFS_KOBJ_BIN_ATTR:
+			bin_attr = sd->s_elem.bin_attr.bin_attr;
+			inode->i_size = bin_attr->size;
+			inode->i_fop = &bin_fops;
+			break;
+		case SYSFS_KOBJ_LINK:
+			inode->i_op = &sysfs_symlink_inode_operations;
+			break;
+		default:
+			BUG();
+		}
+	}
+
+	sysfs_instantiate(dentry, inode);
+	sysfs_attach_dentry(sd, dentry);
+
+	mutex_unlock(&sysfs_mutex);
+
+	return NULL;
 }
 
 const struct inode_operations sysfs_dir_inode_operations = {
@@ -328,58 +822,46 @@
 	.setattr	= sysfs_setattr,
 };
 
-static void remove_dir(struct dentry * d)
+static void remove_dir(struct sysfs_dirent *sd)
 {
-	struct dentry * parent = dget(d->d_parent);
-	struct sysfs_dirent * sd;
+	struct sysfs_addrm_cxt acxt;
 
-	mutex_lock(&parent->d_inode->i_mutex);
-	d_delete(d);
-	sd = d->d_fsdata;
- 	list_del_init(&sd->s_sibling);
-	sysfs_put(sd);
-	if (d->d_inode)
-		simple_rmdir(parent->d_inode,d);
-
-	pr_debug(" o %s removing done (%d)\n",d->d_name.name,
-		 atomic_read(&d->d_count));
-
-	mutex_unlock(&parent->d_inode->i_mutex);
-	dput(parent);
+	sysfs_addrm_start(&acxt, sd->s_parent);
+	sysfs_unlink_sibling(sd);
+	sysfs_remove_one(&acxt, sd);
+	sysfs_addrm_finish(&acxt);
 }
 
-void sysfs_remove_subdir(struct dentry * d)
+void sysfs_remove_subdir(struct sysfs_dirent *sd)
 {
-	remove_dir(d);
+	remove_dir(sd);
 }
 
 
-static void __sysfs_remove_dir(struct dentry *dentry)
+static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
 {
-	struct sysfs_dirent * parent_sd;
-	struct sysfs_dirent * sd, * tmp;
+	struct sysfs_addrm_cxt acxt;
+	struct sysfs_dirent **pos;
 
-	dget(dentry);
-	if (!dentry)
+	if (!dir_sd)
 		return;
 
-	pr_debug("sysfs %s: removing dir\n",dentry->d_name.name);
-	mutex_lock(&dentry->d_inode->i_mutex);
-	parent_sd = dentry->d_fsdata;
-	list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
-		if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED))
-			continue;
-		list_del_init(&sd->s_sibling);
-		sysfs_drop_dentry(sd, dentry);
-		sysfs_put(sd);
-	}
-	mutex_unlock(&dentry->d_inode->i_mutex);
+	pr_debug("sysfs %s: removing dir\n", dir_sd->s_name);
+	sysfs_addrm_start(&acxt, dir_sd);
+	pos = &dir_sd->s_children;
+	while (*pos) {
+		struct sysfs_dirent *sd = *pos;
 
-	remove_dir(dentry);
-	/**
-	 * Drop reference from dget() on entrance.
-	 */
-	dput(dentry);
+		if (sysfs_type(sd) && sysfs_type(sd) != SYSFS_DIR) {
+			*pos = sd->s_sibling;
+			sd->s_sibling = NULL;
+			sysfs_remove_one(&acxt, sd);
+		} else
+			pos = &(*pos)->s_sibling;
+	}
+	sysfs_addrm_finish(&acxt);
+
+	remove_dir(dir_sd);
 }
 
 /**
@@ -393,102 +875,166 @@
 
 void sysfs_remove_dir(struct kobject * kobj)
 {
-	__sysfs_remove_dir(kobj->dentry);
-	kobj->dentry = NULL;
+	struct sysfs_dirent *sd = kobj->sd;
+
+	spin_lock(&sysfs_assoc_lock);
+	kobj->sd = NULL;
+	spin_unlock(&sysfs_assoc_lock);
+
+	__sysfs_remove_dir(sd);
 }
 
-int sysfs_rename_dir(struct kobject * kobj, struct dentry *new_parent,
+int sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd,
 		     const char *new_name)
 {
-	int error = 0;
-	struct dentry * new_dentry;
+	struct sysfs_dirent *sd = kobj->sd;
+	struct dentry *new_parent = NULL;
+	struct dentry *old_dentry = NULL, *new_dentry = NULL;
+	const char *dup_name = NULL;
+	int error;
 
-	if (!new_parent)
-		return -EFAULT;
+	/* get dentries */
+	old_dentry = sysfs_get_dentry(sd);
+	if (IS_ERR(old_dentry)) {
+		error = PTR_ERR(old_dentry);
+		goto out_dput;
+	}
 
-	down_write(&sysfs_rename_sem);
+	new_parent = sysfs_get_dentry(new_parent_sd);
+	if (IS_ERR(new_parent)) {
+		error = PTR_ERR(new_parent);
+		goto out_dput;
+	}
+
+	/* lock new_parent and get dentry for new name */
 	mutex_lock(&new_parent->d_inode->i_mutex);
 
 	new_dentry = lookup_one_len(new_name, new_parent, strlen(new_name));
-	if (!IS_ERR(new_dentry)) {
-		/* By allowing two different directories with the
-		 * same d_parent we allow this routine to move
-		 * between different shadows of the same directory
-		 */
-		if (kobj->dentry->d_parent->d_inode != new_parent->d_inode)
-			return -EINVAL;
-		else if (new_dentry->d_parent->d_inode != new_parent->d_inode)
-			error = -EINVAL;
-		else if (new_dentry == kobj->dentry)
-			error = -EINVAL;
-		else if (!new_dentry->d_inode) {
-			error = kobject_set_name(kobj, "%s", new_name);
-			if (!error) {
-				struct sysfs_dirent *sd, *parent_sd;
-
-				d_add(new_dentry, NULL);
-				d_move(kobj->dentry, new_dentry);
-
-				sd = kobj->dentry->d_fsdata;
-				parent_sd = new_parent->d_fsdata;
-
-				list_del_init(&sd->s_sibling);
-				list_add(&sd->s_sibling, &parent_sd->s_children);
-			}
-			else
-				d_drop(new_dentry);
-		} else
-			error = -EEXIST;
-		dput(new_dentry);
+	if (IS_ERR(new_dentry)) {
+		error = PTR_ERR(new_dentry);
+		goto out_unlock;
 	}
-	mutex_unlock(&new_parent->d_inode->i_mutex);
-	up_write(&sysfs_rename_sem);
 
+	/* By allowing two different directories with the same
+	 * d_parent we allow this routine to move between different
+	 * shadows of the same directory
+	 */
+	error = -EINVAL;
+	if (old_dentry->d_parent->d_inode != new_parent->d_inode ||
+	    new_dentry->d_parent->d_inode != new_parent->d_inode ||
+	    old_dentry == new_dentry)
+		goto out_unlock;
+
+	error = -EEXIST;
+	if (new_dentry->d_inode)
+		goto out_unlock;
+
+	/* rename kobject and sysfs_dirent */
+	error = -ENOMEM;
+	new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
+	if (!new_name)
+		goto out_drop;
+
+	error = kobject_set_name(kobj, "%s", new_name);
+	if (error)
+		goto out_drop;
+
+	dup_name = sd->s_name;
+	sd->s_name = new_name;
+
+	/* move under the new parent */
+	d_add(new_dentry, NULL);
+	d_move(sd->s_dentry, new_dentry);
+
+	mutex_lock(&sysfs_mutex);
+
+	sysfs_unlink_sibling(sd);
+	sysfs_get(new_parent_sd);
+	sysfs_put(sd->s_parent);
+	sd->s_parent = new_parent_sd;
+	sysfs_link_sibling(sd);
+
+	mutex_unlock(&sysfs_mutex);
+
+	error = 0;
+	goto out_unlock;
+
+ out_drop:
+	d_drop(new_dentry);
+ out_unlock:
+	mutex_unlock(&new_parent->d_inode->i_mutex);
+ out_dput:
+	kfree(dup_name);
+	dput(new_parent);
+	dput(old_dentry);
+	dput(new_dentry);
 	return error;
 }
 
-int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent)
+int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
 {
-	struct dentry *old_parent_dentry, *new_parent_dentry, *new_dentry;
-	struct sysfs_dirent *new_parent_sd, *sd;
+	struct sysfs_dirent *sd = kobj->sd;
+	struct sysfs_dirent *new_parent_sd;
+	struct dentry *old_parent, *new_parent = NULL;
+	struct dentry *old_dentry = NULL, *new_dentry = NULL;
 	int error;
 
-	old_parent_dentry = kobj->parent ?
-		kobj->parent->dentry : sysfs_mount->mnt_sb->s_root;
-	new_parent_dentry = new_parent ?
-		new_parent->dentry : sysfs_mount->mnt_sb->s_root;
+	BUG_ON(!sd->s_parent);
+	new_parent_sd = new_parent_kobj->sd ? new_parent_kobj->sd : &sysfs_root;
 
-	if (old_parent_dentry->d_inode == new_parent_dentry->d_inode)
-		return 0;	/* nothing to move */
+	/* get dentries */
+	old_dentry = sysfs_get_dentry(sd);
+	if (IS_ERR(old_dentry)) {
+		error = PTR_ERR(old_dentry);
+		goto out_dput;
+	}
+	old_parent = sd->s_parent->s_dentry;
+
+	new_parent = sysfs_get_dentry(new_parent_sd);
+	if (IS_ERR(new_parent)) {
+		error = PTR_ERR(new_parent);
+		goto out_dput;
+	}
+
+	if (old_parent->d_inode == new_parent->d_inode) {
+		error = 0;
+		goto out_dput;	/* nothing to move */
+	}
 again:
-	mutex_lock(&old_parent_dentry->d_inode->i_mutex);
-	if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) {
-		mutex_unlock(&old_parent_dentry->d_inode->i_mutex);
+	mutex_lock(&old_parent->d_inode->i_mutex);
+	if (!mutex_trylock(&new_parent->d_inode->i_mutex)) {
+		mutex_unlock(&old_parent->d_inode->i_mutex);
 		goto again;
 	}
 
-	new_parent_sd = new_parent_dentry->d_fsdata;
-	sd = kobj->dentry->d_fsdata;
-
-	new_dentry = lookup_one_len(kobj->name, new_parent_dentry,
-				    strlen(kobj->name));
+	new_dentry = lookup_one_len(kobj->name, new_parent, strlen(kobj->name));
 	if (IS_ERR(new_dentry)) {
 		error = PTR_ERR(new_dentry);
-		goto out;
+		goto out_unlock;
 	} else
 		error = 0;
 	d_add(new_dentry, NULL);
-	d_move(kobj->dentry, new_dentry);
+	d_move(sd->s_dentry, new_dentry);
 	dput(new_dentry);
 
 	/* Remove from old parent's list and insert into new parent's list. */
-	list_del_init(&sd->s_sibling);
-	list_add(&sd->s_sibling, &new_parent_sd->s_children);
+	mutex_lock(&sysfs_mutex);
 
-out:
-	mutex_unlock(&new_parent_dentry->d_inode->i_mutex);
-	mutex_unlock(&old_parent_dentry->d_inode->i_mutex);
+	sysfs_unlink_sibling(sd);
+	sysfs_get(new_parent_sd);
+	sysfs_put(sd->s_parent);
+	sd->s_parent = new_parent_sd;
+	sysfs_link_sibling(sd);
 
+	mutex_unlock(&sysfs_mutex);
+
+ out_unlock:
+	mutex_unlock(&new_parent->d_inode->i_mutex);
+	mutex_unlock(&old_parent->d_inode->i_mutex);
+ out_dput:
+	dput(new_parent);
+	dput(old_dentry);
+	dput(new_dentry);
 	return error;
 }
 
@@ -496,23 +1042,27 @@
 {
 	struct dentry * dentry = file->f_path.dentry;
 	struct sysfs_dirent * parent_sd = dentry->d_fsdata;
+	struct sysfs_dirent * sd;
 
-	mutex_lock(&dentry->d_inode->i_mutex);
-	file->private_data = sysfs_new_dirent(parent_sd, NULL);
-	mutex_unlock(&dentry->d_inode->i_mutex);
+	sd = sysfs_new_dirent("_DIR_", 0, 0);
+	if (sd) {
+		mutex_lock(&sysfs_mutex);
+		sd->s_parent = sysfs_get(parent_sd);
+		sysfs_link_sibling(sd);
+		mutex_unlock(&sysfs_mutex);
+	}
 
-	return file->private_data ? 0 : -ENOMEM;
-
+	file->private_data = sd;
+	return sd ? 0 : -ENOMEM;
 }
 
 static int sysfs_dir_close(struct inode *inode, struct file *file)
 {
-	struct dentry * dentry = file->f_path.dentry;
 	struct sysfs_dirent * cursor = file->private_data;
 
-	mutex_lock(&dentry->d_inode->i_mutex);
-	list_del_init(&cursor->s_sibling);
-	mutex_unlock(&dentry->d_inode->i_mutex);
+	mutex_lock(&sysfs_mutex);
+	sysfs_unlink_sibling(cursor);
+	mutex_unlock(&sysfs_mutex);
 
 	release_sysfs_dirent(cursor);
 
@@ -530,7 +1080,7 @@
 	struct dentry *dentry = filp->f_path.dentry;
 	struct sysfs_dirent * parent_sd = dentry->d_fsdata;
 	struct sysfs_dirent *cursor = filp->private_data;
-	struct list_head *p, *q = &cursor->s_sibling;
+	struct sysfs_dirent **pos;
 	ino_t ino;
 	int i = filp->f_pos;
 
@@ -543,38 +1093,52 @@
 			i++;
 			/* fallthrough */
 		case 1:
-			ino = parent_ino(dentry);
+			if (parent_sd->s_parent)
+				ino = parent_sd->s_parent->s_ino;
+			else
+				ino = parent_sd->s_ino;
 			if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
 				break;
 			filp->f_pos++;
 			i++;
 			/* fallthrough */
 		default:
-			if (filp->f_pos == 2)
-				list_move(q, &parent_sd->s_children);
+			mutex_lock(&sysfs_mutex);
 
-			for (p=q->next; p!= &parent_sd->s_children; p=p->next) {
-				struct sysfs_dirent *next;
+			pos = &parent_sd->s_children;
+			while (*pos != cursor)
+				pos = &(*pos)->s_sibling;
+
+			/* unlink cursor */
+			*pos = cursor->s_sibling;
+
+			if (filp->f_pos == 2)
+				pos = &parent_sd->s_children;
+
+			for ( ; *pos; pos = &(*pos)->s_sibling) {
+				struct sysfs_dirent *next = *pos;
 				const char * name;
 				int len;
 
-				next = list_entry(p, struct sysfs_dirent,
-						   s_sibling);
-				if (!next->s_element)
+				if (!sysfs_type(next))
 					continue;
 
-				name = sysfs_get_name(next);
+				name = next->s_name;
 				len = strlen(name);
 				ino = next->s_ino;
 
 				if (filldir(dirent, name, len, filp->f_pos, ino,
 						 dt_type(next)) < 0)
-					return 0;
+					break;
 
-				list_move(q, p);
-				p = q;
 				filp->f_pos++;
 			}
+
+			/* put cursor back in */
+			cursor->s_sibling = *pos;
+			*pos = cursor;
+
+			mutex_unlock(&sysfs_mutex);
 	}
 	return 0;
 }
@@ -583,7 +1147,6 @@
 {
 	struct dentry * dentry = file->f_path.dentry;
 
-	mutex_lock(&dentry->d_inode->i_mutex);
 	switch (origin) {
 		case 1:
 			offset += file->f_pos;
@@ -591,31 +1154,35 @@
 			if (offset >= 0)
 				break;
 		default:
-			mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
 			return -EINVAL;
 	}
 	if (offset != file->f_pos) {
+		mutex_lock(&sysfs_mutex);
+
 		file->f_pos = offset;
 		if (file->f_pos >= 2) {
 			struct sysfs_dirent *sd = dentry->d_fsdata;
 			struct sysfs_dirent *cursor = file->private_data;
-			struct list_head *p;
+			struct sysfs_dirent **pos;
 			loff_t n = file->f_pos - 2;
 
-			list_del(&cursor->s_sibling);
-			p = sd->s_children.next;
-			while (n && p != &sd->s_children) {
-				struct sysfs_dirent *next;
-				next = list_entry(p, struct sysfs_dirent,
-						   s_sibling);
-				if (next->s_element)
+			sysfs_unlink_sibling(cursor);
+
+			pos = &sd->s_children;
+			while (n && *pos) {
+				struct sysfs_dirent *next = *pos;
+				if (sysfs_type(next))
 					n--;
-				p = p->next;
+				pos = &(*pos)->s_sibling;
 			}
-			list_add_tail(&cursor->s_sibling, p);
+
+			cursor->s_sibling = *pos;
+			*pos = cursor;
 		}
+
+		mutex_unlock(&sysfs_mutex);
 	}
-	mutex_unlock(&dentry->d_inode->i_mutex);
+
 	return offset;
 }
 
@@ -628,12 +1195,20 @@
 int sysfs_make_shadowed_dir(struct kobject *kobj,
 	void * (*follow_link)(struct dentry *, struct nameidata *))
 {
+	struct dentry *dentry;
 	struct inode *inode;
 	struct inode_operations *i_op;
 
-	inode = kobj->dentry->d_inode;
-	if (inode->i_op != &sysfs_dir_inode_operations)
+	/* get dentry for @kobj->sd, dentry of a shadowed dir is pinned */
+	dentry = sysfs_get_dentry(kobj->sd);
+	if (IS_ERR(dentry))
+		return PTR_ERR(dentry);
+
+	inode = dentry->d_inode;
+	if (inode->i_op != &sysfs_dir_inode_operations) {
+		dput(dentry);
 		return -EINVAL;
+	}
 
 	i_op = kmalloc(sizeof(*i_op), GFP_KERNEL);
 	if (!i_op)
@@ -658,54 +1233,72 @@
  *	directory.
  */
 
-struct dentry *sysfs_create_shadow_dir(struct kobject *kobj)
+struct sysfs_dirent *sysfs_create_shadow_dir(struct kobject *kobj)
 {
-	struct sysfs_dirent *sd;
-	struct dentry *parent, *dir, *shadow;
+	struct sysfs_dirent *parent_sd = kobj->sd->s_parent;
+	struct dentry *dir, *parent, *shadow;
 	struct inode *inode;
+	struct sysfs_dirent *sd;
+	struct sysfs_addrm_cxt acxt;
 
-	dir = kobj->dentry;
-	inode = dir->d_inode;
-	parent = dir->d_parent;
-	shadow = ERR_PTR(-EINVAL);
-	if (!sysfs_is_shadowed_inode(inode))
+	dir = sysfs_get_dentry(kobj->sd);
+	if (IS_ERR(dir)) {
+		sd = (void *)dir;
 		goto out;
+	}
+	parent = dir->d_parent;
+
+	inode = dir->d_inode;
+	sd = ERR_PTR(-EINVAL);
+	if (!sysfs_is_shadowed_inode(inode))
+		goto out_dput;
 
 	shadow = d_alloc(parent, &dir->d_name);
 	if (!shadow)
 		goto nomem;
 
-	sd = __sysfs_make_dirent(shadow, kobj, inode->i_mode, SYSFS_DIR);
+	sd = sysfs_new_dirent("_SHADOW_", inode->i_mode, SYSFS_DIR);
 	if (!sd)
 		goto nomem;
+	sd->s_elem.dir.kobj = kobj;
 
+	sysfs_addrm_start(&acxt, parent_sd);
+
+	/* add but don't link into children list */
+	sysfs_add_one(&acxt, sd);
+
+	/* attach and instantiate dentry */
+	sysfs_attach_dentry(sd, shadow);
 	d_instantiate(shadow, igrab(inode));
-	inc_nlink(inode);
-	inc_nlink(parent->d_inode);
-	shadow->d_op = &sysfs_dentry_ops;
+	inc_nlink(inode);	/* tj: synchronization? */
+
+	sysfs_addrm_finish(&acxt);
 
 	dget(shadow);		/* Extra count - pin the dentry in core */
 
-out:
-	return shadow;
-nomem:
+	goto out_dput;
+
+ nomem:
 	dput(shadow);
-	shadow = ERR_PTR(-ENOMEM);
-	goto out;
+	sd = ERR_PTR(-ENOMEM);
+ out_dput:
+	dput(dir);
+ out:
+	return sd;
 }
 
 /**
  *	sysfs_remove_shadow_dir - remove an object's directory.
- *	@shadow: dentry of shadow directory
+ *	@shadow_sd: sysfs_dirent of shadow directory
  *
  *	The only thing special about this is that we remove any files in
  *	the directory before we remove the directory, and we've inlined
  *	what used to be sysfs_rmdir() below, instead of calling separately.
  */
 
-void sysfs_remove_shadow_dir(struct dentry *shadow)
+void sysfs_remove_shadow_dir(struct sysfs_dirent *shadow_sd)
 {
-	__sysfs_remove_dir(shadow);
+	__sysfs_remove_dir(shadow_sd);
 }
 
 const struct file_operations sysfs_dir_operations = {
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index b502c71..cc49799 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -50,29 +50,15 @@
 	.store	= subsys_attr_store,
 };
 
-/**
- *	add_to_collection - add buffer to a collection
- *	@buffer:	buffer to be added
- *	@node:		inode of set to add to
- */
-
-static inline void
-add_to_collection(struct sysfs_buffer *buffer, struct inode *node)
-{
-	struct sysfs_buffer_collection *set = node->i_private;
-
-	mutex_lock(&node->i_mutex);
-	list_add(&buffer->associates, &set->associates);
-	mutex_unlock(&node->i_mutex);
-}
-
-static inline void
-remove_from_collection(struct sysfs_buffer *buffer, struct inode *node)
-{
-	mutex_lock(&node->i_mutex);
-	list_del(&buffer->associates);
-	mutex_unlock(&node->i_mutex);
-}
+struct sysfs_buffer {
+	size_t			count;
+	loff_t			pos;
+	char			* page;
+	struct sysfs_ops	* ops;
+	struct semaphore	sem;
+	int			needs_read_fill;
+	int			event;
+};
 
 /**
  *	fill_read_buffer - allocate and fill buffer from object.
@@ -87,9 +73,8 @@
  */
 static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer)
 {
-	struct sysfs_dirent * sd = dentry->d_fsdata;
-	struct attribute * attr = to_attr(dentry);
-	struct kobject * kobj = to_kobj(dentry->d_parent);
+	struct sysfs_dirent *attr_sd = dentry->d_fsdata;
+	struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
 	struct sysfs_ops * ops = buffer->ops;
 	int ret = 0;
 	ssize_t count;
@@ -99,8 +84,15 @@
 	if (!buffer->page)
 		return -ENOMEM;
 
-	buffer->event = atomic_read(&sd->s_event);
-	count = ops->show(kobj,attr,buffer->page);
+	/* need attr_sd for attr and ops, its parent for kobj */
+	if (!sysfs_get_active_two(attr_sd))
+		return -ENODEV;
+
+	buffer->event = atomic_read(&attr_sd->s_event);
+	count = ops->show(kobj, attr_sd->s_elem.attr.attr, buffer->page);
+
+	sysfs_put_active_two(attr_sd);
+
 	BUG_ON(count > (ssize_t)PAGE_SIZE);
 	if (count >= 0) {
 		buffer->needs_read_fill = 0;
@@ -138,10 +130,7 @@
 
 	down(&buffer->sem);
 	if (buffer->needs_read_fill) {
-		if (buffer->orphaned)
-			retval = -ENODEV;
-		else
-			retval = fill_read_buffer(file->f_path.dentry,buffer);
+		retval = fill_read_buffer(file->f_path.dentry,buffer);
 		if (retval)
 			goto out;
 	}
@@ -196,14 +185,23 @@
  *	passing the buffer that we acquired in fill_write_buffer().
  */
 
-static int 
+static int
 flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t count)
 {
-	struct attribute * attr = to_attr(dentry);
-	struct kobject * kobj = to_kobj(dentry->d_parent);
+	struct sysfs_dirent *attr_sd = dentry->d_fsdata;
+	struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
 	struct sysfs_ops * ops = buffer->ops;
+	int rc;
 
-	return ops->store(kobj,attr,buffer->page,count);
+	/* need attr_sd for attr and ops, its parent for kobj */
+	if (!sysfs_get_active_two(attr_sd))
+		return -ENODEV;
+
+	rc = ops->store(kobj, attr_sd->s_elem.attr.attr, buffer->page, count);
+
+	sysfs_put_active_two(attr_sd);
+
+	return rc;
 }
 
 
@@ -231,37 +229,26 @@
 	ssize_t len;
 
 	down(&buffer->sem);
-	if (buffer->orphaned) {
-		len = -ENODEV;
-		goto out;
-	}
 	len = fill_write_buffer(buffer, buf, count);
 	if (len > 0)
 		len = flush_write_buffer(file->f_path.dentry, buffer, len);
 	if (len > 0)
 		*ppos += len;
-out:
 	up(&buffer->sem);
 	return len;
 }
 
 static int sysfs_open_file(struct inode *inode, struct file *file)
 {
-	struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent);
-	struct attribute * attr = to_attr(file->f_path.dentry);
-	struct sysfs_buffer_collection *set;
+	struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+	struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
 	struct sysfs_buffer * buffer;
 	struct sysfs_ops * ops = NULL;
-	int error = 0;
+	int error;
 
-	if (!kobj || !attr)
-		goto Einval;
-
-	/* Grab the module reference for this attribute if we have one */
-	if (!try_module_get(attr->owner)) {
-		error = -ENODEV;
-		goto Done;
-	}
+	/* need attr_sd for attr and ops, its parent for kobj */
+	if (!sysfs_get_active_two(attr_sd))
+		return -ENODEV;
 
 	/* if the kobject has no ktype, then we assume that it is a subsystem
 	 * itself, and use ops for it.
@@ -273,33 +260,21 @@
 	else
 		ops = &subsys_sysfs_ops;
 
+	error = -EACCES;
+
 	/* No sysfs operations, either from having no subsystem,
 	 * or the subsystem have no operations.
 	 */
 	if (!ops)
-		goto Eaccess;
-
-	/* make sure we have a collection to add our buffers to */
-	mutex_lock(&inode->i_mutex);
-	if (!(set = inode->i_private)) {
-		if (!(set = inode->i_private = kmalloc(sizeof(struct sysfs_buffer_collection), GFP_KERNEL))) {
-			error = -ENOMEM;
-			goto Done;
-		} else {
-			INIT_LIST_HEAD(&set->associates);
-		}
-	}
-	mutex_unlock(&inode->i_mutex);
+		goto err_out;
 
 	/* File needs write support.
 	 * The inode's perms must say it's ok, 
 	 * and we must have a store method.
 	 */
 	if (file->f_mode & FMODE_WRITE) {
-
 		if (!(inode->i_mode & S_IWUGO) || !ops->store)
-			goto Eaccess;
-
+			goto err_out;
 	}
 
 	/* File needs read support.
@@ -308,48 +283,38 @@
 	 */
 	if (file->f_mode & FMODE_READ) {
 		if (!(inode->i_mode & S_IRUGO) || !ops->show)
-			goto Eaccess;
+			goto err_out;
 	}
 
 	/* No error? Great, allocate a buffer for the file, and store it
 	 * it in file->private_data for easy access.
 	 */
+	error = -ENOMEM;
 	buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
-	if (buffer) {
-		INIT_LIST_HEAD(&buffer->associates);
-		init_MUTEX(&buffer->sem);
-		buffer->needs_read_fill = 1;
-		buffer->ops = ops;
-		add_to_collection(buffer, inode);
-		file->private_data = buffer;
-	} else
-		error = -ENOMEM;
-	goto Done;
+	if (!buffer)
+		goto err_out;
 
- Einval:
-	error = -EINVAL;
-	goto Done;
- Eaccess:
-	error = -EACCES;
-	module_put(attr->owner);
- Done:
-	if (error)
-		kobject_put(kobj);
+	init_MUTEX(&buffer->sem);
+	buffer->needs_read_fill = 1;
+	buffer->ops = ops;
+	file->private_data = buffer;
+
+	/* open succeeded, put active references and pin attr_sd */
+	sysfs_put_active_two(attr_sd);
+	sysfs_get(attr_sd);
+	return 0;
+
+ err_out:
+	sysfs_put_active_two(attr_sd);
 	return error;
 }
 
 static int sysfs_release(struct inode * inode, struct file * filp)
 {
-	struct kobject * kobj = to_kobj(filp->f_path.dentry->d_parent);
-	struct attribute * attr = to_attr(filp->f_path.dentry);
-	struct module * owner = attr->owner;
-	struct sysfs_buffer * buffer = filp->private_data;
+	struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
+	struct sysfs_buffer *buffer = filp->private_data;
 
-	if (buffer)
-		remove_from_collection(buffer, inode);
-	kobject_put(kobj);
-	/* After this point, attr should not be accessed. */
-	module_put(owner);
+	sysfs_put(attr_sd);
 
 	if (buffer) {
 		if (buffer->page)
@@ -376,57 +341,43 @@
 static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
 {
 	struct sysfs_buffer * buffer = filp->private_data;
-	struct kobject * kobj = to_kobj(filp->f_path.dentry->d_parent);
-	struct sysfs_dirent * sd = filp->f_path.dentry->d_fsdata;
-	int res = 0;
+	struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
+	struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
+
+	/* need parent for the kobj, grab both */
+	if (!sysfs_get_active_two(attr_sd))
+		goto trigger;
 
 	poll_wait(filp, &kobj->poll, wait);
 
-	if (buffer->event != atomic_read(&sd->s_event)) {
-		res = POLLERR|POLLPRI;
-		buffer->needs_read_fill = 1;
-	}
+	sysfs_put_active_two(attr_sd);
 
-	return res;
+	if (buffer->event != atomic_read(&attr_sd->s_event))
+		goto trigger;
+
+	return 0;
+
+ trigger:
+	buffer->needs_read_fill = 1;
+	return POLLERR|POLLPRI;
 }
 
-
-static struct dentry *step_down(struct dentry *dir, const char * name)
+void sysfs_notify(struct kobject *k, char *dir, char *attr)
 {
-	struct dentry * de;
+	struct sysfs_dirent *sd = k->sd;
 
-	if (dir == NULL || dir->d_inode == NULL)
-		return NULL;
+	mutex_lock(&sysfs_mutex);
 
-	mutex_lock(&dir->d_inode->i_mutex);
-	de = lookup_one_len(name, dir, strlen(name));
-	mutex_unlock(&dir->d_inode->i_mutex);
-	dput(dir);
-	if (IS_ERR(de))
-		return NULL;
-	if (de->d_inode == NULL) {
-		dput(de);
-		return NULL;
-	}
-	return de;
-}
-
-void sysfs_notify(struct kobject * k, char *dir, char *attr)
-{
-	struct dentry *de = k->dentry;
-	if (de)
-		dget(de);
-	if (de && dir)
-		de = step_down(de, dir);
-	if (de && attr)
-		de = step_down(de, attr);
-	if (de) {
-		struct sysfs_dirent * sd = de->d_fsdata;
-		if (sd)
-			atomic_inc(&sd->s_event);
+	if (sd && dir)
+		sd = sysfs_find_dirent(sd, dir);
+	if (sd && attr)
+		sd = sysfs_find_dirent(sd, attr);
+	if (sd) {
+		atomic_inc(&sd->s_event);
 		wake_up_interruptible(&k->poll);
-		dput(de);
 	}
+
+	mutex_unlock(&sysfs_mutex);
 }
 EXPORT_SYMBOL_GPL(sysfs_notify);
 
@@ -440,19 +391,30 @@
 };
 
 
-int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type)
+int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
+		   int type)
 {
-	struct sysfs_dirent * parent_sd = dir->d_fsdata;
 	umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG;
-	int error = -EEXIST;
+	struct sysfs_addrm_cxt acxt;
+	struct sysfs_dirent *sd;
 
-	mutex_lock(&dir->d_inode->i_mutex);
-	if (!sysfs_dirent_exist(parent_sd, attr->name))
-		error = sysfs_make_dirent(parent_sd, NULL, (void *)attr,
-					  mode, type);
-	mutex_unlock(&dir->d_inode->i_mutex);
+	sd = sysfs_new_dirent(attr->name, mode, type);
+	if (!sd)
+		return -ENOMEM;
+	sd->s_elem.attr.attr = (void *)attr;
 
-	return error;
+	sysfs_addrm_start(&acxt, dir_sd);
+
+	if (!sysfs_find_dirent(dir_sd, attr->name)) {
+		sysfs_add_one(&acxt, sd);
+		sysfs_link_sibling(sd);
+	}
+
+	if (sysfs_addrm_finish(&acxt))
+		return 0;
+
+	sysfs_put(sd);
+	return -EEXIST;
 }
 
 
@@ -464,9 +426,9 @@
 
 int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
 {
-	BUG_ON(!kobj || !kobj->dentry || !attr);
+	BUG_ON(!kobj || !kobj->sd || !attr);
 
-	return sysfs_add_file(kobj->dentry, attr, SYSFS_KOBJ_ATTR);
+	return sysfs_add_file(kobj->sd, attr, SYSFS_KOBJ_ATTR);
 
 }
 
@@ -480,16 +442,16 @@
 int sysfs_add_file_to_group(struct kobject *kobj,
 		const struct attribute *attr, const char *group)
 {
-	struct dentry *dir;
+	struct sysfs_dirent *dir_sd;
 	int error;
 
-	dir = lookup_one_len(group, kobj->dentry, strlen(group));
-	if (IS_ERR(dir))
-		error = PTR_ERR(dir);
-	else {
-		error = sysfs_add_file(dir, attr, SYSFS_KOBJ_ATTR);
-		dput(dir);
-	}
+	dir_sd = sysfs_get_dirent(kobj->sd, group);
+	if (!dir_sd)
+		return -ENOENT;
+
+	error = sysfs_add_file(dir_sd, attr, SYSFS_KOBJ_ATTR);
+	sysfs_put(dir_sd);
+
 	return error;
 }
 EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
@@ -502,30 +464,31 @@
  */
 int sysfs_update_file(struct kobject * kobj, const struct attribute * attr)
 {
-	struct dentry * dir = kobj->dentry;
-	struct dentry * victim;
-	int res = -ENOENT;
+	struct sysfs_dirent *victim_sd = NULL;
+	struct dentry *victim = NULL;
+	int rc;
 
-	mutex_lock(&dir->d_inode->i_mutex);
-	victim = lookup_one_len(attr->name, dir, strlen(attr->name));
-	if (!IS_ERR(victim)) {
-		/* make sure dentry is really there */
-		if (victim->d_inode && 
-		    (victim->d_parent->d_inode == dir->d_inode)) {
-			victim->d_inode->i_mtime = CURRENT_TIME;
-			fsnotify_modify(victim);
-			res = 0;
-		} else
-			d_drop(victim);
-		
-		/**
-		 * Drop the reference acquired from lookup_one_len() above.
-		 */
-		dput(victim);
+	rc = -ENOENT;
+	victim_sd = sysfs_get_dirent(kobj->sd, attr->name);
+	if (!victim_sd)
+		goto out;
+
+	victim = sysfs_get_dentry(victim_sd);
+	if (IS_ERR(victim)) {
+		rc = PTR_ERR(victim);
+		victim = NULL;
+		goto out;
 	}
-	mutex_unlock(&dir->d_inode->i_mutex);
 
-	return res;
+	mutex_lock(&victim->d_inode->i_mutex);
+	victim->d_inode->i_mtime = CURRENT_TIME;
+	fsnotify_modify(victim);
+	mutex_unlock(&victim->d_inode->i_mutex);
+	rc = 0;
+ out:
+	dput(victim);
+	sysfs_put(victim_sd);
+	return rc;
 }
 
 
@@ -538,30 +501,34 @@
  */
 int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
 {
-	struct dentry *dir = kobj->dentry;
-	struct dentry *victim;
+	struct sysfs_dirent *victim_sd = NULL;
+	struct dentry *victim = NULL;
 	struct inode * inode;
 	struct iattr newattrs;
-	int res = -ENOENT;
+	int rc;
 
-	mutex_lock(&dir->d_inode->i_mutex);
-	victim = lookup_one_len(attr->name, dir, strlen(attr->name));
-	if (!IS_ERR(victim)) {
-		if (victim->d_inode &&
-		    (victim->d_parent->d_inode == dir->d_inode)) {
-			inode = victim->d_inode;
-			mutex_lock(&inode->i_mutex);
-			newattrs.ia_mode = (mode & S_IALLUGO) |
-						(inode->i_mode & ~S_IALLUGO);
-			newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-			res = notify_change(victim, &newattrs);
-			mutex_unlock(&inode->i_mutex);
-		}
-		dput(victim);
+	rc = -ENOENT;
+	victim_sd = sysfs_get_dirent(kobj->sd, attr->name);
+	if (!victim_sd)
+		goto out;
+
+	victim = sysfs_get_dentry(victim_sd);
+	if (IS_ERR(victim)) {
+		rc = PTR_ERR(victim);
+		victim = NULL;
+		goto out;
 	}
-	mutex_unlock(&dir->d_inode->i_mutex);
 
-	return res;
+	inode = victim->d_inode;
+	mutex_lock(&inode->i_mutex);
+	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
+	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+	rc = notify_change(victim, &newattrs);
+	mutex_unlock(&inode->i_mutex);
+ out:
+	dput(victim);
+	sysfs_put(victim_sd);
+	return rc;
 }
 EXPORT_SYMBOL_GPL(sysfs_chmod_file);
 
@@ -576,7 +543,7 @@
 
 void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
 {
-	sysfs_hash_and_remove(kobj->dentry, attr->name);
+	sysfs_hash_and_remove(kobj->sd, attr->name);
 }
 
 
@@ -589,12 +556,12 @@
 void sysfs_remove_file_from_group(struct kobject *kobj,
 		const struct attribute *attr, const char *group)
 {
-	struct dentry *dir;
+	struct sysfs_dirent *dir_sd;
 
-	dir = lookup_one_len(group, kobj->dentry, strlen(group));
-	if (!IS_ERR(dir)) {
-		sysfs_hash_and_remove(dir, attr->name);
-		dput(dir);
+	dir_sd = sysfs_get_dirent(kobj->sd, group);
+	if (dir_sd) {
+		sysfs_hash_and_remove(dir_sd, attr->name);
+		sysfs_put(dir_sd);
 	}
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index 52eed2a..f318b73 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -18,26 +18,25 @@
 #include "sysfs.h"
 
 
-static void remove_files(struct dentry * dir, 
-			 const struct attribute_group * grp)
+static void remove_files(struct sysfs_dirent *dir_sd,
+			 const struct attribute_group *grp)
 {
 	struct attribute *const* attr;
 
 	for (attr = grp->attrs; *attr; attr++)
-		sysfs_hash_and_remove(dir,(*attr)->name);
+		sysfs_hash_and_remove(dir_sd, (*attr)->name);
 }
 
-static int create_files(struct dentry * dir,
-			const struct attribute_group * grp)
+static int create_files(struct sysfs_dirent *dir_sd,
+			const struct attribute_group *grp)
 {
 	struct attribute *const* attr;
 	int error = 0;
 
-	for (attr = grp->attrs; *attr && !error; attr++) {
-		error = sysfs_add_file(dir, *attr, SYSFS_KOBJ_ATTR);
-	}
+	for (attr = grp->attrs; *attr && !error; attr++)
+		error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
 	if (error)
-		remove_files(dir,grp);
+		remove_files(dir_sd, grp);
 	return error;
 }
 
@@ -45,44 +44,44 @@
 int sysfs_create_group(struct kobject * kobj, 
 		       const struct attribute_group * grp)
 {
-	struct dentry * dir;
+	struct sysfs_dirent *sd;
 	int error;
 
-	BUG_ON(!kobj || !kobj->dentry);
+	BUG_ON(!kobj || !kobj->sd);
 
 	if (grp->name) {
-		error = sysfs_create_subdir(kobj,grp->name,&dir);
+		error = sysfs_create_subdir(kobj, grp->name, &sd);
 		if (error)
 			return error;
 	} else
-		dir = kobj->dentry;
-	dir = dget(dir);
-	if ((error = create_files(dir,grp))) {
+		sd = kobj->sd;
+	sysfs_get(sd);
+	error = create_files(sd, grp);
+	if (error) {
 		if (grp->name)
-			sysfs_remove_subdir(dir);
+			sysfs_remove_subdir(sd);
 	}
-	dput(dir);
+	sysfs_put(sd);
 	return error;
 }
 
 void sysfs_remove_group(struct kobject * kobj, 
 			const struct attribute_group * grp)
 {
-	struct dentry * dir;
+	struct sysfs_dirent *dir_sd = kobj->sd;
+	struct sysfs_dirent *sd;
 
 	if (grp->name) {
-		dir = lookup_one_len_kern(grp->name, kobj->dentry,
-				strlen(grp->name));
-		BUG_ON(IS_ERR(dir));
-	}
-	else
-		dir = dget(kobj->dentry);
+		sd = sysfs_get_dirent(dir_sd, grp->name);
+		BUG_ON(!sd);
+	} else
+		sd = sysfs_get(dir_sd);
 
-	remove_files(dir,grp);
+	remove_files(sd, grp);
 	if (grp->name)
-		sysfs_remove_subdir(dir);
-	/* release the ref. taken in this routine */
-	dput(dir);
+		sysfs_remove_subdir(sd);
+
+	sysfs_put(sd);
 }
 
 
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 5266eec..3756e15 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -133,187 +133,94 @@
  */
 static struct lock_class_key sysfs_inode_imutex_key;
 
-struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd)
+void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
 {
-	struct inode * inode = new_inode(sysfs_sb);
-	if (inode) {
-		inode->i_blocks = 0;
-		inode->i_mapping->a_ops = &sysfs_aops;
-		inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
-		inode->i_op = &sysfs_inode_operations;
-		inode->i_ino = sd->s_ino;
-		lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
+	inode->i_blocks = 0;
+	inode->i_mapping->a_ops = &sysfs_aops;
+	inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
+	inode->i_op = &sysfs_inode_operations;
+	inode->i_ino = sd->s_ino;
+	lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
 
-		if (sd->s_iattr) {
-			/* sysfs_dirent has non-default attributes
-			 * get them for the new inode from persistent copy
-			 * in sysfs_dirent
-			 */
-			set_inode_attr(inode, sd->s_iattr);
-		} else
-			set_default_inode_attr(inode, mode);
-	}
+	if (sd->s_iattr) {
+		/* sysfs_dirent has non-default attributes
+		 * get them for the new inode from persistent copy
+		 * in sysfs_dirent
+		 */
+		set_inode_attr(inode, sd->s_iattr);
+	} else
+		set_default_inode_attr(inode, sd->s_mode);
+}
+
+/**
+ *	sysfs_get_inode - get inode for sysfs_dirent
+ *	@sd: sysfs_dirent to allocate inode for
+ *
+ *	Get inode for @sd.  If such inode doesn't exist, a new inode
+ *	is allocated and basics are initialized.  New inode is
+ *	returned locked.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ *
+ *	RETURNS:
+ *	Pointer to allocated inode on success, NULL on failure.
+ */
+struct inode * sysfs_get_inode(struct sysfs_dirent *sd)
+{
+	struct inode *inode;
+
+	inode = iget_locked(sysfs_sb, sd->s_ino);
+	if (inode && (inode->i_state & I_NEW))
+		sysfs_init_inode(sd, inode);
+
 	return inode;
 }
 
-int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
-{
-	int error = 0;
-	struct inode * inode = NULL;
-	if (dentry) {
-		if (!dentry->d_inode) {
-			struct sysfs_dirent * sd = dentry->d_fsdata;
-			if ((inode = sysfs_new_inode(mode, sd))) {
-				if (dentry->d_parent && dentry->d_parent->d_inode) {
-					struct inode *p_inode = dentry->d_parent->d_inode;
-					p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
-				}
-				goto Proceed;
-			}
-			else 
-				error = -ENOMEM;
-		} else
-			error = -EEXIST;
-	} else 
-		error = -ENOENT;
-	goto Done;
-
- Proceed:
-	if (init)
-		error = init(inode);
-	if (!error) {
-		d_instantiate(dentry, inode);
-		if (S_ISDIR(mode))
-			dget(dentry);  /* pin only directory dentry in core */
-	} else
-		iput(inode);
- Done:
-	return error;
-}
-
-/*
- * Get the name for corresponding element represented by the given sysfs_dirent
+/**
+ *	sysfs_instantiate - instantiate dentry
+ *	@dentry: dentry to be instantiated
+ *	@inode: inode associated with @sd
+ *
+ *	Unlock @inode if locked and instantiate @dentry with @inode.
+ *
+ *	LOCKING:
+ *	None.
  */
-const unsigned char * sysfs_get_name(struct sysfs_dirent *sd)
+void sysfs_instantiate(struct dentry *dentry, struct inode *inode)
 {
-	struct attribute * attr;
-	struct bin_attribute * bin_attr;
-	struct sysfs_symlink  * sl;
+	BUG_ON(!dentry || dentry->d_inode);
 
-	BUG_ON(!sd || !sd->s_element);
+	if (inode->i_state & I_NEW)
+		unlock_new_inode(inode);
 
-	switch (sd->s_type) {
-		case SYSFS_DIR:
-			/* Always have a dentry so use that */
-			return sd->s_dentry->d_name.name;
-
-		case SYSFS_KOBJ_ATTR:
-			attr = sd->s_element;
-			return attr->name;
-
-		case SYSFS_KOBJ_BIN_ATTR:
-			bin_attr = sd->s_element;
-			return bin_attr->attr.name;
-
-		case SYSFS_KOBJ_LINK:
-			sl = sd->s_element;
-			return sl->link_name;
-	}
-	return NULL;
+	d_instantiate(dentry, inode);
 }
 
-static inline void orphan_all_buffers(struct inode *node)
+int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name)
 {
-	struct sysfs_buffer_collection *set;
-	struct sysfs_buffer *buf;
+	struct sysfs_addrm_cxt acxt;
+	struct sysfs_dirent **pos, *sd;
 
-	mutex_lock_nested(&node->i_mutex, I_MUTEX_CHILD);
-	set = node->i_private;
-	if (set) {
-		list_for_each_entry(buf, &set->associates, associates) {
-			down(&buf->sem);
-			buf->orphaned = 1;
-			up(&buf->sem);
-		}
-	}
-	mutex_unlock(&node->i_mutex);
-}
-
-
-/*
- * Unhashes the dentry corresponding to given sysfs_dirent
- * Called with parent inode's i_mutex held.
- */
-void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
-{
-	struct dentry *dentry = NULL;
-	struct inode *inode;
-
-	/* We're not holding a reference to ->s_dentry dentry but the
-	 * field will stay valid as long as sysfs_lock is held.
-	 */
-	spin_lock(&sysfs_lock);
-	spin_lock(&dcache_lock);
-
-	/* dget dentry if it's still alive */
-	if (sd->s_dentry && sd->s_dentry->d_inode)
-		dentry = dget_locked(sd->s_dentry);
-
-	spin_unlock(&dcache_lock);
-	spin_unlock(&sysfs_lock);
-
-	/* drop dentry */
-	if (dentry) {
-		spin_lock(&dcache_lock);
-		spin_lock(&dentry->d_lock);
-		if (!d_unhashed(dentry) && dentry->d_inode) {
-			inode = dentry->d_inode;
-			spin_lock(&inode->i_lock);
-			__iget(inode);
-			spin_unlock(&inode->i_lock);
-			dget_locked(dentry);
-			__d_drop(dentry);
-			spin_unlock(&dentry->d_lock);
-			spin_unlock(&dcache_lock);
-			simple_unlink(parent->d_inode, dentry);
-			orphan_all_buffers(inode);
-			iput(inode);
-		} else {
-			spin_unlock(&dentry->d_lock);
-			spin_unlock(&dcache_lock);
-		}
-
-		dput(dentry);
-	}
-}
-
-int sysfs_hash_and_remove(struct dentry * dir, const char * name)
-{
-	struct sysfs_dirent * sd;
-	struct sysfs_dirent * parent_sd;
-	int found = 0;
-
-	if (!dir)
+	if (!dir_sd)
 		return -ENOENT;
 
-	if (dir->d_inode == NULL)
-		/* no inode means this hasn't been made visible yet */
-		return -ENOENT;
+	sysfs_addrm_start(&acxt, dir_sd);
 
-	parent_sd = dir->d_fsdata;
-	mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
-	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
-		if (!sd->s_element)
+	for (pos = &dir_sd->s_children; *pos; pos = &(*pos)->s_sibling) {
+		sd = *pos;
+
+		if (!sysfs_type(sd))
 			continue;
-		if (!strcmp(sysfs_get_name(sd), name)) {
-			list_del_init(&sd->s_sibling);
-			sysfs_drop_dentry(sd, dir);
-			sysfs_put(sd);
-			found = 1;
+		if (!strcmp(sd->s_name, name)) {
+			*pos = sd->s_sibling;
+			sd->s_sibling = NULL;
+			sysfs_remove_one(&acxt, sd);
 			break;
 		}
 	}
-	mutex_unlock(&dir->d_inode->i_mutex);
 
-	return found ? 0 : -ENOENT;
+	if (sysfs_addrm_finish(&acxt))
+		return 0;
+	return -ENOENT;
 }
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 00ab912..402cc35 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -19,28 +19,18 @@
 struct super_block * sysfs_sb = NULL;
 struct kmem_cache *sysfs_dir_cachep;
 
-static void sysfs_clear_inode(struct inode *inode);
-
 static const struct super_operations sysfs_ops = {
 	.statfs		= simple_statfs,
 	.drop_inode	= sysfs_delete_inode,
-	.clear_inode	= sysfs_clear_inode,
 };
 
-static struct sysfs_dirent sysfs_root = {
-	.s_sibling	= LIST_HEAD_INIT(sysfs_root.s_sibling),
-	.s_children	= LIST_HEAD_INIT(sysfs_root.s_children),
-	.s_element	= NULL,
-	.s_type		= SYSFS_ROOT,
-	.s_iattr	= NULL,
+struct sysfs_dirent sysfs_root = {
+	.s_count	= ATOMIC_INIT(1),
+	.s_flags	= SYSFS_ROOT,
+	.s_mode		= S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
 	.s_ino		= 1,
 };
 
-static void sysfs_clear_inode(struct inode *inode)
-{
-	kfree(inode->i_private);
-}
-
 static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
@@ -53,24 +43,26 @@
 	sb->s_time_gran = 1;
 	sysfs_sb = sb;
 
-	inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
-				 &sysfs_root);
-	if (inode) {
-		inode->i_op = &sysfs_dir_inode_operations;
-		inode->i_fop = &sysfs_dir_operations;
-		/* directory inodes start off with i_nlink == 2 (for "." entry) */
-		inc_nlink(inode);
-	} else {
+	inode = new_inode(sysfs_sb);
+	if (!inode) {
 		pr_debug("sysfs: could not get root inode\n");
 		return -ENOMEM;
 	}
 
+	sysfs_init_inode(&sysfs_root, inode);
+
+	inode->i_op = &sysfs_dir_inode_operations;
+	inode->i_fop = &sysfs_dir_operations;
+	/* directory inodes start off with i_nlink == 2 (for "." entry) */
+	inc_nlink(inode);
+
 	root = d_alloc_root(inode);
 	if (!root) {
 		pr_debug("%s: could not get root dentry!\n",__FUNCTION__);
 		iput(inode);
 		return -ENOMEM;
 	}
+	sysfs_root.s_dentry = root;
 	root->d_fsdata = &sysfs_root;
 	sb->s_root = root;
 	return 0;
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index 7b9c5bf..2f86e04 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -11,71 +11,39 @@
 
 #include "sysfs.h"
 
-static int object_depth(struct kobject * kobj)
+static int object_depth(struct sysfs_dirent *sd)
 {
-	struct kobject * p = kobj;
 	int depth = 0;
-	do { depth++; } while ((p = p->parent));
+
+	for (; sd->s_parent; sd = sd->s_parent)
+		depth++;
+
 	return depth;
 }
 
-static int object_path_length(struct kobject * kobj)
+static int object_path_length(struct sysfs_dirent * sd)
 {
-	struct kobject * p = kobj;
 	int length = 1;
-	do {
-		length += strlen(kobject_name(p)) + 1;
-		p = p->parent;
-	} while (p);
+
+	for (; sd->s_parent; sd = sd->s_parent)
+		length += strlen(sd->s_name) + 1;
+
 	return length;
 }
 
-static void fill_object_path(struct kobject * kobj, char * buffer, int length)
+static void fill_object_path(struct sysfs_dirent *sd, char *buffer, int length)
 {
-	struct kobject * p;
-
 	--length;
-	for (p = kobj; p; p = p->parent) {
-		int cur = strlen(kobject_name(p));
+	for (; sd->s_parent; sd = sd->s_parent) {
+		int cur = strlen(sd->s_name);
 
 		/* back up enough to print this bus id with '/' */
 		length -= cur;
-		strncpy(buffer + length,kobject_name(p),cur);
+		strncpy(buffer + length, sd->s_name, cur);
 		*(buffer + --length) = '/';
 	}
 }
 
-static int sysfs_add_link(struct dentry * parent, const char * name, struct kobject * target)
-{
-	struct sysfs_dirent * parent_sd = parent->d_fsdata;
-	struct sysfs_symlink * sl;
-	int error = 0;
-
-	error = -ENOMEM;
-	sl = kmalloc(sizeof(*sl), GFP_KERNEL);
-	if (!sl)
-		goto exit1;
-
-	sl->link_name = kmalloc(strlen(name) + 1, GFP_KERNEL);
-	if (!sl->link_name)
-		goto exit2;
-
-	strcpy(sl->link_name, name);
-	sl->target_kobj = kobject_get(target);
-
-	error = sysfs_make_dirent(parent_sd, NULL, sl, S_IFLNK|S_IRWXUGO,
-				SYSFS_KOBJ_LINK);
-	if (!error)
-		return 0;
-
-	kobject_put(target);
-	kfree(sl->link_name);
-exit2:
-	kfree(sl);
-exit1:
-	return error;
-}
-
 /**
  *	sysfs_create_link - create symlink between two objects.
  *	@kobj:	object whose directory we're creating the link in.
@@ -84,24 +52,57 @@
  */
 int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
 {
-	struct dentry *dentry = NULL;
-	int error = -EEXIST;
+	struct sysfs_dirent *parent_sd = NULL;
+	struct sysfs_dirent *target_sd = NULL;
+	struct sysfs_dirent *sd = NULL;
+	struct sysfs_addrm_cxt acxt;
+	int error;
 
 	BUG_ON(!name);
 
 	if (!kobj) {
 		if (sysfs_mount && sysfs_mount->mnt_sb)
-			dentry = sysfs_mount->mnt_sb->s_root;
+			parent_sd = sysfs_mount->mnt_sb->s_root->d_fsdata;
 	} else
-		dentry = kobj->dentry;
+		parent_sd = kobj->sd;
 
-	if (!dentry)
-		return -EFAULT;
+	error = -EFAULT;
+	if (!parent_sd)
+		goto out_put;
 
-	mutex_lock(&dentry->d_inode->i_mutex);
-	if (!sysfs_dirent_exist(dentry->d_fsdata, name))
-		error = sysfs_add_link(dentry, name, target);
-	mutex_unlock(&dentry->d_inode->i_mutex);
+	/* target->sd can go away beneath us but is protected with
+	 * sysfs_assoc_lock.  Fetch target_sd from it.
+	 */
+	spin_lock(&sysfs_assoc_lock);
+	if (target->sd)
+		target_sd = sysfs_get(target->sd);
+	spin_unlock(&sysfs_assoc_lock);
+
+	error = -ENOENT;
+	if (!target_sd)
+		goto out_put;
+
+	error = -ENOMEM;
+	sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);
+	if (!sd)
+		goto out_put;
+	sd->s_elem.symlink.target_sd = target_sd;
+
+	sysfs_addrm_start(&acxt, parent_sd);
+
+	if (!sysfs_find_dirent(parent_sd, name)) {
+		sysfs_add_one(&acxt, sd);
+		sysfs_link_sibling(sd);
+	}
+
+	if (sysfs_addrm_finish(&acxt))
+		return 0;
+
+	error = -EEXIST;
+	/* fall through */
+ out_put:
+	sysfs_put(target_sd);
+	sysfs_put(sd);
 	return error;
 }
 
@@ -114,17 +115,17 @@
 
 void sysfs_remove_link(struct kobject * kobj, const char * name)
 {
-	sysfs_hash_and_remove(kobj->dentry,name);
+	sysfs_hash_and_remove(kobj->sd, name);
 }
 
-static int sysfs_get_target_path(struct kobject * kobj, struct kobject * target,
-				 char *path)
+static int sysfs_get_target_path(struct sysfs_dirent * parent_sd,
+				 struct sysfs_dirent * target_sd, char *path)
 {
 	char * s;
 	int depth, size;
 
-	depth = object_depth(kobj);
-	size = object_path_length(target) + depth * 3 - 1;
+	depth = object_depth(parent_sd);
+	size = object_path_length(target_sd) + depth * 3 - 1;
 	if (size > PATH_MAX)
 		return -ENAMETOOLONG;
 
@@ -133,7 +134,7 @@
 	for (s = path; depth--; s += 3)
 		strcpy(s,"../");
 
-	fill_object_path(target, path, size);
+	fill_object_path(target_sd, path, size);
 	pr_debug("%s: path = '%s'\n", __FUNCTION__, path);
 
 	return 0;
@@ -141,27 +142,16 @@
 
 static int sysfs_getlink(struct dentry *dentry, char * path)
 {
-	struct kobject *kobj, *target_kobj;
-	int error = 0;
+	struct sysfs_dirent *sd = dentry->d_fsdata;
+	struct sysfs_dirent *parent_sd = sd->s_parent;
+	struct sysfs_dirent *target_sd = sd->s_elem.symlink.target_sd;
+	int error;
 
-	kobj = sysfs_get_kobject(dentry->d_parent);
-	if (!kobj)
-		return -EINVAL;
+	mutex_lock(&sysfs_mutex);
+	error = sysfs_get_target_path(parent_sd, target_sd, path);
+	mutex_unlock(&sysfs_mutex);
 
-	target_kobj = sysfs_get_kobject(dentry);
-	if (!target_kobj) {
-		kobject_put(kobj);
-		return -EINVAL;
-	}
-
-	down_read(&sysfs_rename_sem);
-	error = sysfs_get_target_path(kobj, target_kobj, path);
-	up_read(&sysfs_rename_sem);
-	
-	kobject_put(kobj);
-	kobject_put(target_kobj);
 	return error;
-
 }
 
 static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd)
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 502c949..6a37f23 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -1,9 +1,40 @@
+struct sysfs_elem_dir {
+	struct kobject		* kobj;
+};
+
+struct sysfs_elem_symlink {
+	struct sysfs_dirent	* target_sd;
+};
+
+struct sysfs_elem_attr {
+	struct attribute	* attr;
+};
+
+struct sysfs_elem_bin_attr {
+	struct bin_attribute	* bin_attr;
+};
+
+/*
+ * As long as s_count reference is held, the sysfs_dirent itself is
+ * accessible.  Dereferencing s_elem or any other outer entity
+ * requires s_active reference.
+ */
 struct sysfs_dirent {
 	atomic_t		s_count;
-	struct list_head	s_sibling;
-	struct list_head	s_children;
-	void 			* s_element;
-	int			s_type;
+	atomic_t		s_active;
+	struct sysfs_dirent	* s_parent;
+	struct sysfs_dirent	* s_sibling;
+	struct sysfs_dirent	* s_children;
+	const char		* s_name;
+
+	union {
+		struct sysfs_elem_dir		dir;
+		struct sysfs_elem_symlink	symlink;
+		struct sysfs_elem_attr		attr;
+		struct sysfs_elem_bin_attr	bin_attr;
+	}			s_elem;
+
+	unsigned int		s_flags;
 	umode_t			s_mode;
 	ino_t			s_ino;
 	struct dentry		* s_dentry;
@@ -11,30 +42,60 @@
 	atomic_t		s_event;
 };
 
+#define SD_DEACTIVATED_BIAS	INT_MIN
+
+struct sysfs_addrm_cxt {
+	struct sysfs_dirent	*parent_sd;
+	struct inode		*parent_inode;
+	struct sysfs_dirent	*removed;
+	int			cnt;
+};
+
 extern struct vfsmount * sysfs_mount;
+extern struct sysfs_dirent sysfs_root;
 extern struct kmem_cache *sysfs_dir_cachep;
 
+extern struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd);
+extern void sysfs_link_sibling(struct sysfs_dirent *sd);
+extern void sysfs_unlink_sibling(struct sysfs_dirent *sd);
+extern struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
+extern void sysfs_put_active(struct sysfs_dirent *sd);
+extern struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd);
+extern void sysfs_put_active_two(struct sysfs_dirent *sd);
+extern void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
+			      struct sysfs_dirent *parent_sd);
+extern void sysfs_add_one(struct sysfs_addrm_cxt *acxt,
+			  struct sysfs_dirent *sd);
+extern void sysfs_remove_one(struct sysfs_addrm_cxt *acxt,
+			     struct sysfs_dirent *sd);
+extern int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
+
 extern void sysfs_delete_inode(struct inode *inode);
-extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
-extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
+extern void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode);
+extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd);
+extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode);
 
-extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *);
-extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
-				umode_t, int);
+extern void release_sysfs_dirent(struct sysfs_dirent * sd);
+extern struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
+					      const unsigned char *name);
+extern struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+					     const unsigned char *name);
+extern struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode,
+					     int type);
 
-extern int sysfs_add_file(struct dentry *, const struct attribute *, int);
-extern int sysfs_hash_and_remove(struct dentry * dir, const char * name);
+extern int sysfs_add_file(struct sysfs_dirent *dir_sd,
+			  const struct attribute *attr, int type);
+extern int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name);
 extern struct sysfs_dirent *sysfs_find(struct sysfs_dirent *dir, const char * name);
 
-extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **);
-extern void sysfs_remove_subdir(struct dentry *);
+extern int sysfs_create_subdir(struct kobject *kobj, const char *name,
+			       struct sysfs_dirent **p_sd);
+extern void sysfs_remove_subdir(struct sysfs_dirent *sd);
 
-extern const unsigned char * sysfs_get_name(struct sysfs_dirent *sd);
-extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent);
 extern int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
 
-extern spinlock_t sysfs_lock;
-extern struct rw_semaphore sysfs_rename_sem;
+extern spinlock_t sysfs_assoc_lock;
+extern struct mutex sysfs_mutex;
 extern struct super_block * sysfs_sb;
 extern const struct file_operations sysfs_dir_operations;
 extern const struct file_operations sysfs_file_operations;
@@ -42,73 +103,9 @@
 extern const struct inode_operations sysfs_dir_inode_operations;
 extern const struct inode_operations sysfs_symlink_inode_operations;
 
-struct sysfs_symlink {
-	char * link_name;
-	struct kobject * target_kobj;
-};
-
-struct sysfs_buffer {
-	struct list_head		associates;
-	size_t				count;
-	loff_t				pos;
-	char				* page;
-	struct sysfs_ops		* ops;
-	struct semaphore		sem;
-	int				orphaned;
-	int				needs_read_fill;
-	int				event;
-};
-
-struct sysfs_buffer_collection {
-	struct list_head	associates;
-};
-
-static inline struct kobject * to_kobj(struct dentry * dentry)
+static inline unsigned int sysfs_type(struct sysfs_dirent *sd)
 {
-	struct sysfs_dirent * sd = dentry->d_fsdata;
-	return ((struct kobject *) sd->s_element);
-}
-
-static inline struct attribute * to_attr(struct dentry * dentry)
-{
-	struct sysfs_dirent * sd = dentry->d_fsdata;
-	return ((struct attribute *) sd->s_element);
-}
-
-static inline struct bin_attribute * to_bin_attr(struct dentry * dentry)
-{
-	struct sysfs_dirent * sd = dentry->d_fsdata;
-	return ((struct bin_attribute *) sd->s_element);
-}
-
-static inline struct kobject *sysfs_get_kobject(struct dentry *dentry)
-{
-	struct kobject * kobj = NULL;
-
-	spin_lock(&dcache_lock);
-	if (!d_unhashed(dentry)) {
-		struct sysfs_dirent * sd = dentry->d_fsdata;
-		if (sd->s_type & SYSFS_KOBJ_LINK) {
-			struct sysfs_symlink * sl = sd->s_element;
-			kobj = kobject_get(sl->target_kobj);
-		} else
-			kobj = kobject_get(sd->s_element);
-	}
-	spin_unlock(&dcache_lock);
-
-	return kobj;
-}
-
-static inline void release_sysfs_dirent(struct sysfs_dirent * sd)
-{
-	if (sd->s_type & SYSFS_KOBJ_LINK) {
-		struct sysfs_symlink * sl = sd->s_element;
-		kfree(sl->link_name);
-		kobject_put(sl->target_kobj);
-		kfree(sl);
-	}
-	kfree(sd->s_iattr);
-	kmem_cache_free(sysfs_dir_cachep, sd);
+	return sd->s_flags & SYSFS_TYPE_MASK;
 }
 
 static inline struct sysfs_dirent * sysfs_get(struct sysfs_dirent * sd)
@@ -122,7 +119,7 @@
 
 static inline void sysfs_put(struct sysfs_dirent * sd)
 {
-	if (atomic_dec_and_test(&sd->s_count))
+	if (sd && atomic_dec_and_test(&sd->s_count))
 		release_sysfs_dirent(sd);
 }
 
diff --git a/include/asm-blackfin/Kbuild b/include/asm-blackfin/Kbuild
index c68e168..71f8fe7 100644
--- a/include/asm-blackfin/Kbuild
+++ b/include/asm-blackfin/Kbuild
@@ -1 +1,3 @@
 include include/asm-generic/Kbuild.asm
+
+header-y += fixed_code.h
diff --git a/include/asm-blackfin/bfin-global.h b/include/asm-blackfin/bfin-global.h
index 57f37cc..c4d6cbb 100644
--- a/include/asm-blackfin/bfin-global.h
+++ b/include/asm-blackfin/bfin-global.h
@@ -67,6 +67,18 @@
 extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
 extern void bfin_gpio_interrupt_setup(int irq, int irq_pfx, int type);
 
+extern asmlinkage void finish_atomic_sections (struct pt_regs *regs);
+extern char fixed_code_start;
+extern char fixed_code_end;
+extern int atomic_xchg32(void);
+extern int atomic_cas32(void);
+extern int atomic_add32(void);
+extern int atomic_sub32(void);
+extern int atomic_ior32(void);
+extern int atomic_and32(void);
+extern int atomic_xor32(void);
+extern void sigreturn_stub(void);
+
 extern void *l1_data_A_sram_alloc(size_t);
 extern void *l1_data_B_sram_alloc(size_t);
 extern void *l1_inst_sram_alloc(size_t);
diff --git a/include/asm-blackfin/cplbinit.h b/include/asm-blackfin/cplbinit.h
index 3bad2d1..bec6ecd 100644
--- a/include/asm-blackfin/cplbinit.h
+++ b/include/asm-blackfin/cplbinit.h
@@ -57,8 +57,8 @@
 	u16 size;
 };
 
-u_long icplb_table[MAX_CPLBS+1];
-u_long dcplb_table[MAX_CPLBS+1];
+extern u_long icplb_table[MAX_CPLBS+1];
+extern u_long dcplb_table[MAX_CPLBS+1];
 
 /* Till here we are discussing about the static memory management model.
  * However, the operating envoronments commonly define more CPLB
@@ -70,134 +70,27 @@
  */
 
 #ifdef CONFIG_CPLB_SWITCH_TAB_L1
-u_long ipdt_table[MAX_SWITCH_I_CPLBS+1]__attribute__((l1_data));
-u_long dpdt_table[MAX_SWITCH_D_CPLBS+1]__attribute__((l1_data));
+extern u_long ipdt_table[MAX_SWITCH_I_CPLBS+1]__attribute__((l1_data));
+extern u_long dpdt_table[MAX_SWITCH_D_CPLBS+1]__attribute__((l1_data));
 
 #ifdef CONFIG_CPLB_INFO
-u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS]__attribute__((l1_data));
-u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS]__attribute__((l1_data));
+extern u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS]__attribute__((l1_data));
+extern u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS]__attribute__((l1_data));
 #endif /* CONFIG_CPLB_INFO */
 
 #else
 
-u_long ipdt_table[MAX_SWITCH_I_CPLBS+1];
-u_long dpdt_table[MAX_SWITCH_D_CPLBS+1];
+extern u_long ipdt_table[MAX_SWITCH_I_CPLBS+1];
+extern u_long dpdt_table[MAX_SWITCH_D_CPLBS+1];
 
 #ifdef CONFIG_CPLB_INFO
-u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS];
-u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS];
+extern u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS];
+extern u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS];
 #endif /* CONFIG_CPLB_INFO */
 
 #endif /*CONFIG_CPLB_SWITCH_TAB_L1*/
 
-struct s_cplb {
-	struct cplb_tab init_i;
-	struct cplb_tab init_d;
-	struct cplb_tab switch_i;
-	struct cplb_tab switch_d;
-};
+extern unsigned long reserved_mem_dcache_on;
+extern unsigned long reserved_mem_icache_on;
 
-#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
-static struct cplb_desc cplb_data[] = {
-	{
-		.start = 0,
-		.end = SIZE_4K,
-		.psize = SIZE_4K,
-		.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
-		.i_conf = SDRAM_OOPS,
-		.d_conf = SDRAM_OOPS,
-#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO)
-		.valid = 1,
-#else
-		.valid = 0,
-#endif
-		.name = "ZERO Pointer Saveguard",
-	},
-	{
-		.start = L1_CODE_START,
-		.end = L1_CODE_START + L1_CODE_LENGTH,
-		.psize = SIZE_4M,
-		.attr = INITIAL_T | SWITCH_T | I_CPLB,
-		.i_conf = L1_IMEMORY,
-		.d_conf = 0,
-		.valid = 1,
-		.name = "L1 I-Memory",
-	},
-	{
-		.start = L1_DATA_A_START,
-		.end = L1_DATA_B_START + L1_DATA_B_LENGTH,
-		.psize = SIZE_4M,
-		.attr = INITIAL_T | SWITCH_T | D_CPLB,
-		.i_conf = 0,
-		.d_conf = L1_DMEMORY,
-#if ((L1_DATA_A_LENGTH > 0) || (L1_DATA_B_LENGTH > 0))
-		.valid = 1,
-#else
-		.valid = 0,
-#endif
-		.name = "L1 D-Memory",
-	},
-	{
-		.start = 0,
-		.end = 0,  /* dynamic */
-		.psize = 0,
-		.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
-		.i_conf =  SDRAM_IGENERIC,
-		.d_conf =  SDRAM_DGENERIC,
-		.valid = 1,
-		.name = "SDRAM Kernel",
-	},
-	{
-		.start = 0, /* dynamic */
-		.end = 0, /* dynamic */
-		.psize = 0,
-		.attr = INITIAL_T | SWITCH_T | D_CPLB,
-		.i_conf =  SDRAM_IGENERIC,
-		.d_conf =  SDRAM_DNON_CHBL,
-		.valid = 1,
-		.name = "SDRAM RAM MTD",
-	},
-	{
-		.start = 0, /* dynamic */
-		.end = 0,   /* dynamic */
-		.psize = SIZE_1M,
-		.attr = INITIAL_T | SWITCH_T | D_CPLB,
-		.d_conf = SDRAM_DNON_CHBL,
-		.valid = 1,//(DMA_UNCACHED_REGION > 0),
-		.name = "SDRAM Uncached DMA ZONE",
-	},
-	{
-		.start = 0, /* dynamic */
-		.end = 0, /* dynamic */
-		.psize = 0,
-		.attr = SWITCH_T | D_CPLB,
-		.i_conf = 0, /* dynamic */
-		.d_conf = 0, /* dynamic */
-		.valid = 1,
-		.name = "SDRAM Reserved Memory",
-	},
-	{
-		.start = ASYNC_BANK0_BASE,
-		.end = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE,
-		.psize = 0,
-		.attr = SWITCH_T | D_CPLB,
-		.d_conf = SDRAM_EBIU,
-		.valid = 1,
-		.name = "ASYNC Memory",
-	},
-	{
-#if defined(CONFIG_BF561)
-		.start = L2_SRAM,
-		.end = L2_SRAM_END,
-		.psize = SIZE_1M,
-		.attr = SWITCH_T | D_CPLB,
-		.i_conf = L2_MEMORY,
-		.d_conf = L2_MEMORY,
-		.valid = 1,
-#else
-		.valid = 0,
-#endif
-		.name = "L2 Memory",
-	}
-};
-#endif
+extern void generate_cpl_tables(void);
diff --git a/include/asm-blackfin/fixed_code.h b/include/asm-blackfin/fixed_code.h
new file mode 100644
index 0000000..e6df84e
--- /dev/null
+++ b/include/asm-blackfin/fixed_code.h
@@ -0,0 +1,20 @@
+/* This file defines the fixed addresses where userspace programs can find
+   atomic code sequences.  */
+
+#define FIXED_CODE_START	0x400
+
+#define SIGRETURN_STUB		0x400
+
+#define ATOMIC_SEQS_START	0x410
+
+#define ATOMIC_XCHG32		0x410
+#define ATOMIC_CAS32		0x420
+#define ATOMIC_ADD32		0x430
+#define ATOMIC_SUB32		0x440
+#define ATOMIC_IOR32		0x450
+#define ATOMIC_AND32		0x460
+#define ATOMIC_XOR32		0x470
+
+#define ATOMIC_SEQS_END		0x480
+
+#define FIXED_CODE_END		0x480
diff --git a/include/asm-blackfin/gpio.h b/include/asm-blackfin/gpio.h
index d98d77a..7480cfa 100644
--- a/include/asm-blackfin/gpio.h
+++ b/include/asm-blackfin/gpio.h
@@ -204,8 +204,62 @@
 
 #endif
 
+#ifdef BF548_FAMILY
+#include <asm-blackfin/mach-bf548/gpio.h>
+#endif
+
 #ifdef BF561_FAMILY
 #define MAX_BLACKFIN_GPIOS 48
+
+#define	GPIO_PF0	0
+#define	GPIO_PF1	1
+#define	GPIO_PF2	2
+#define	GPIO_PF3	3
+#define	GPIO_PF4	4
+#define	GPIO_PF5	5
+#define	GPIO_PF6	6
+#define	GPIO_PF7	7
+#define	GPIO_PF8	8
+#define	GPIO_PF9	9
+#define	GPIO_PF10	10
+#define	GPIO_PF11	11
+#define	GPIO_PF12	12
+#define	GPIO_PF13	13
+#define	GPIO_PF14	14
+#define	GPIO_PF15	15
+#define	GPIO_PF16	16
+#define	GPIO_PF17	17
+#define	GPIO_PF18	18
+#define	GPIO_PF19	19
+#define	GPIO_PF20	20
+#define	GPIO_PF21	21
+#define	GPIO_PF22	22
+#define	GPIO_PF23	23
+#define	GPIO_PF24	24
+#define	GPIO_PF25	25
+#define	GPIO_PF26	26
+#define	GPIO_PF27	27
+#define	GPIO_PF28	28
+#define	GPIO_PF29	29
+#define	GPIO_PF30	30
+#define	GPIO_PF31	31
+#define	GPIO_PF32	32
+#define	GPIO_PF33	33
+#define	GPIO_PF34	34
+#define	GPIO_PF35	35
+#define	GPIO_PF36	36
+#define	GPIO_PF37	37
+#define	GPIO_PF38	38
+#define	GPIO_PF39	39
+#define	GPIO_PF40	40
+#define	GPIO_PF41	41
+#define	GPIO_PF42	42
+#define	GPIO_PF43	43
+#define	GPIO_PF44	44
+#define	GPIO_PF45	45
+#define	GPIO_PF46	46
+#define	GPIO_PF47	47
+
 #define PORT_FIO0 GPIO_0
 #define PORT_FIO1 GPIO_16
 #define PORT_FIO2 GPIO_32
@@ -230,6 +284,7 @@
 * MODIFICATION HISTORY :
 **************************************************************/
 
+#ifndef BF548_FAMILY
 void set_gpio_dir(unsigned short, unsigned short);
 void set_gpio_inen(unsigned short, unsigned short);
 void set_gpio_polar(unsigned short, unsigned short);
@@ -299,6 +354,7 @@
 	unsigned short dummy16;
 	unsigned short inen;
 };
+#endif
 
 #ifdef CONFIG_PM
 #define PM_WAKE_RISING	0x1
@@ -357,8 +413,10 @@
 void gpio_set_value(unsigned short gpio, unsigned short arg);
 unsigned short gpio_get_value(unsigned short gpio);
 
+#ifndef BF548_FAMILY
 #define gpio_get_value(gpio) 		get_gpio_data(gpio)
 #define gpio_set_value(gpio, value)	set_gpio_data(gpio, value)
+#endif
 
 void gpio_direction_input(unsigned short gpio);
 void gpio_direction_output(unsigned short gpio);
diff --git a/include/asm-blackfin/hardirq.h b/include/asm-blackfin/hardirq.h
index 0cab0d3..b6b19f1 100644
--- a/include/asm-blackfin/hardirq.h
+++ b/include/asm-blackfin/hardirq.h
@@ -28,7 +28,11 @@
  * SOFTIRQ_MASK: 0x00ff0000
  */
 
+#if NR_IRQS > 256
+#define HARDIRQ_BITS	9
+#else
 #define HARDIRQ_BITS	8
+#endif
 
 #ifdef NR_IRQS
 # if (1 << HARDIRQ_BITS) < NR_IRQS
diff --git a/include/asm-blackfin/kgdb.h b/include/asm-blackfin/kgdb.h
new file mode 100644
index 0000000..532bd90
--- /dev/null
+++ b/include/asm-blackfin/kgdb.h
@@ -0,0 +1,183 @@
+/*
+ * File:         include/asm-blackfin/kgdb.h
+ * Based on:
+ * Author:       Sonic Zhang
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:          $Id: kgdb_bfin_linux-2.6.x.patch 4934 2007-02-13 09:32:11Z sonicz $
+ *
+ * Modified:
+ *               Copyright 2005-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __ASM_BLACKFIN_KGDB_H__
+#define __ASM_BLACKFIN_KGDB_H__
+
+#include <linux/ptrace.h>
+
+/* gdb locks */
+#define KGDB_MAX_NO_CPUS 8
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+/* Longer buffer is needed to list all threads */
+#define BUFMAX 2048
+
+/*
+ *  Note that this register image is different from
+ *  the register image that Linux produces at interrupt time.
+ *  
+ *  Linux's register image is defined by struct pt_regs in ptrace.h.
+ */
+enum regnames {
+  /* Core Registers */
+  BFIN_R0 = 0,
+  BFIN_R1,
+  BFIN_R2,
+  BFIN_R3,
+  BFIN_R4,
+  BFIN_R5,
+  BFIN_R6,
+  BFIN_R7,
+  BFIN_P0,
+  BFIN_P1,
+  BFIN_P2,
+  BFIN_P3,
+  BFIN_P4,
+  BFIN_P5,
+  BFIN_SP,
+  BFIN_FP,
+  BFIN_I0,
+  BFIN_I1,
+  BFIN_I2,
+  BFIN_I3,
+  BFIN_M0,
+  BFIN_M1,
+  BFIN_M2,
+  BFIN_M3,
+  BFIN_B0,
+  BFIN_B1,
+  BFIN_B2,
+  BFIN_B3,
+  BFIN_L0,
+  BFIN_L1,
+  BFIN_L2,
+  BFIN_L3,
+  BFIN_A0_DOT_X,
+  BFIN_A0_DOT_W,
+  BFIN_A1_DOT_X,
+  BFIN_A1_DOT_W,
+  BFIN_ASTAT,
+  BFIN_RETS,
+  BFIN_LC0,
+  BFIN_LT0,
+  BFIN_LB0,
+  BFIN_LC1,
+  BFIN_LT1,
+  BFIN_LB1,
+  BFIN_CYCLES,
+  BFIN_CYCLES2,
+  BFIN_USP,
+  BFIN_SEQSTAT,
+  BFIN_SYSCFG,
+  BFIN_RETI,
+  BFIN_RETX,
+  BFIN_RETN,
+  BFIN_RETE,
+  
+  /* Pseudo Registers */
+  BFIN_PC,
+  BFIN_CC,
+  BFIN_EXTRA1,		/* Address of .text section.  */
+  BFIN_EXTRA2,		/* Address of .data section.  */
+  BFIN_EXTRA3,		/* Address of .bss section.  */
+  BFIN_FDPIC_EXEC, 
+  BFIN_FDPIC_INTERP,
+
+  /* MMRs */
+  BFIN_IPEND,
+
+  /* LAST ENTRY SHOULD NOT BE CHANGED.  */
+  BFIN_NUM_REGS		/* The number of all registers.  */
+};
+
+/* Number of bytes of registers.  */
+#define NUMREGBYTES BFIN_NUM_REGS*4
+
+#define BREAKPOINT() asm("   EXCPT 2;");
+#define BREAK_INSTR_SIZE       2
+#define HW_BREAKPOINT_NUM		6
+
+/* Instruction watchpoint address control register bits mask */
+#define WPPWR		0x1
+#define WPIREN01	0x2
+#define WPIRINV01	0x4
+#define WPIAEN0		0x8
+#define WPIAEN1		0x10
+#define WPICNTEN0	0x20
+#define WPICNTEN1	0x40
+#define EMUSW0		0x80
+#define EMUSW1		0x100
+#define WPIREN23	0x200
+#define WPIRINV23	0x400
+#define WPIAEN2		0x800
+#define WPIAEN3		0x1000
+#define WPICNTEN2	0x2000
+#define WPICNTEN3	0x4000
+#define EMUSW2		0x8000
+#define EMUSW3		0x10000
+#define WPIREN45	0x20000
+#define WPIRINV45	0x40000
+#define WPIAEN4		0x80000
+#define WPIAEN5		0x100000
+#define WPICNTEN4	0x200000
+#define WPICNTEN5	0x400000
+#define EMUSW4		0x800000
+#define EMUSW5		0x1000000
+#define WPAND		0x2000000
+
+/* Data watchpoint address control register bits mask */
+#define WPDREN01	0x1
+#define WPDRINV01	0x2
+#define WPDAEN0		0x4
+#define WPDAEN1		0x8
+#define WPDCNTEN0	0x10
+#define WPDCNTEN1	0x20
+#define WPDSRC0		0xc0
+#define WPDACC0		0x300
+#define WPDSRC1		0xc00
+#define WPDACC1		0x3000
+
+/* Watchpoint status register bits mask */
+#define STATIA0		0x1
+#define STATIA1		0x2
+#define STATIA2		0x4
+#define STATIA3		0x8
+#define STATIA4		0x10
+#define STATIA5		0x20
+#define STATDA0		0x40
+#define STATDA1		0x80
+
+extern void kgdb_print(const char *fmt, ...);
+
+#endif
diff --git a/include/asm-blackfin/mach-bf533/dma.h b/include/asm-blackfin/mach-bf533/dma.h
index bd9d5e9..16c672c 100644
--- a/include/asm-blackfin/mach-bf533/dma.h
+++ b/include/asm-blackfin/mach-bf533/dma.h
@@ -51,4 +51,7 @@
 #define CH_MEM_STREAM1_DEST     10	 /* TX */
 #define CH_MEM_STREAM1_SRC      11	 /* RX */
 
+extern int channel2irq(unsigned int channel);
+extern struct dma_register *base_addr[];
+
 #endif
diff --git a/include/asm-blackfin/mach-bf533/portmux.h b/include/asm-blackfin/mach-bf533/portmux.h
new file mode 100644
index 0000000..b88d7a0
--- /dev/null
+++ b/include/asm-blackfin/mach-bf533/portmux.h
@@ -0,0 +1,65 @@
+#ifndef _MACH_PORTMUX_H_
+#define _MACH_PORTMUX_H_
+
+#define P_PPI0_CLK	(P_DONTCARE)
+#define P_PPI0_FS1	(P_DONTCARE)
+#define P_PPI0_FS2	(P_DONTCARE)
+#define P_PPI0_FS3	(P_DEFINED | P_IDENT(GPIO_PF3))
+#define P_PPI0_D15	(P_DEFINED | P_IDENT(GPIO_PF4))
+#define P_PPI0_D14	(P_DEFINED | P_IDENT(GPIO_PF5))
+#define P_PPI0_D13	(P_DEFINED | P_IDENT(GPIO_PF6))
+#define P_PPI0_D12	(P_DEFINED | P_IDENT(GPIO_PF7))
+#define P_PPI0_D11	(P_DEFINED | P_IDENT(GPIO_PF8))
+#define P_PPI0_D10	(P_DEFINED | P_IDENT(GPIO_PF9))
+#define P_PPI0_D9	(P_DEFINED | P_IDENT(GPIO_PF10))
+#define P_PPI0_D8	(P_DEFINED | P_IDENT(GPIO_PF11))
+#define P_PPI0_D0	(P_DONTCARE)
+#define P_PPI0_D1	(P_DONTCARE)
+#define P_PPI0_D2	(P_DONTCARE)
+#define P_PPI0_D3	(P_DONTCARE)
+#define P_PPI0_D4	(P_DEFINED | P_IDENT(GPIO_PF15))
+#define P_PPI0_D5	(P_DEFINED | P_IDENT(GPIO_PF14))
+#define P_PPI0_D6	(P_DEFINED | P_IDENT(GPIO_PF13))
+#define P_PPI0_D7	(P_DEFINED | P_IDENT(GPIO_PF12))
+
+#define P_SPORT1_TSCLK	(P_DONTCARE)
+#define P_SPORT1_RSCLK	(P_DONTCARE)
+#define P_SPORT0_TSCLK	(P_DONTCARE)
+#define P_SPORT0_RSCLK	(P_DONTCARE)
+#define P_UART0_RX	(P_DONTCARE)
+#define P_UART0_TX	(P_DONTCARE)
+#define P_SPORT1_DRSEC	(P_DONTCARE)
+#define P_SPORT1_RFS	(P_DONTCARE)
+#define P_SPORT1_DTPRI	(P_DONTCARE)
+#define P_SPORT1_DTSEC	(P_DONTCARE)
+#define P_SPORT1_TFS	(P_DONTCARE)
+#define P_SPORT1_DRPRI	(P_DONTCARE)
+#define P_SPORT0_DRSEC	(P_DONTCARE)
+#define P_SPORT0_RFS	(P_DONTCARE)
+#define P_SPORT0_DTPRI	(P_DONTCARE)
+#define P_SPORT0_DTSEC	(P_DONTCARE)
+#define P_SPORT0_TFS	(P_DONTCARE)
+#define P_SPORT0_DRPRI	(P_DONTCARE)
+
+#define P_SPI0_MOSI	(P_DONTCARE)
+#define P_SPI0_MIS0	(P_DONTCARE)
+#define P_SPI0_SCK	(P_DONTCARE)
+#define P_SPI0_SSEL7	(P_DEFINED | P_IDENT(GPIO_PF7))
+#define P_SPI0_SSEL6	(P_DEFINED | P_IDENT(GPIO_PF6))
+#define P_SPI0_SSEL5	(P_DEFINED | P_IDENT(GPIO_PF5))
+#define P_SPI0_SSEL4	(P_DEFINED | P_IDENT(GPIO_PF4))
+#define P_SPI0_SSEL3	(P_DEFINED | P_IDENT(GPIO_PF3))
+#define P_SPI0_SSEL2	(P_DEFINED | P_IDENT(GPIO_PF2))
+#define P_SPI0_SSEL1	(P_DEFINED | P_IDENT(GPIO_PF1))
+#define P_SPI0_SS	(P_DEFINED | P_IDENT(GPIO_PF0))
+
+#define P_TMR2		(P_DONTCARE)
+#define P_TMR1		(P_DONTCARE)
+#define P_TMR0		(P_DONTCARE)
+#define P_TMRCLK	(P_DEFINED | P_IDENT(GPIO_PF1))
+
+
+
+
+
+#endif /* _MACH_PORTMUX_H_ */
diff --git a/include/asm-blackfin/mach-bf537/dma.h b/include/asm-blackfin/mach-bf537/dma.h
index 7a96404..0219919 100644
--- a/include/asm-blackfin/mach-bf537/dma.h
+++ b/include/asm-blackfin/mach-bf537/dma.h
@@ -52,4 +52,7 @@
 #define CH_MEM_STREAM1_DEST	14	 /* TX */
 #define CH_MEM_STREAM1_SRC 	15	 /* RX */
 
+extern int channel2irq(unsigned int channel);
+extern struct dma_register *base_addr[];
+
 #endif
diff --git a/include/asm-blackfin/mach-bf537/portmux.h b/include/asm-blackfin/mach-bf537/portmux.h
new file mode 100644
index 0000000..23e13c5
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/portmux.h
@@ -0,0 +1,109 @@
+#ifndef _MACH_PORTMUX_H_
+#define _MACH_PORTMUX_H_
+
+#define P_UART0_TX	(P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(0))
+#define P_UART0_RX	(P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(0))
+#define P_UART1_TX	(P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(0))
+#define P_UART1_RX	(P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(0))
+#define P_TMR5		(P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(0))
+#define P_TMR4		(P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(0))
+#define P_TMR3		(P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(0))
+#define P_TMR2		(P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(0))
+#define P_TMR1		(P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(0))
+#define P_TMR0		(P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(0))
+#define P_SPI0_SSEL1	(P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(0))
+#define P_SPI0_MOSI	(P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(0))
+#define P_SPI0_MISO	(P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(0))
+#define P_SPI0_SCK	(P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(0))
+#define P_SPI0_SS	(P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(0))
+#define P_PPI0_CLK	(P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(0))
+#define P_DMAR0		(P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(1))
+#define P_DMAR1		(P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(1))
+#define P_TMR7		(P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(1))
+#define P_TMR6		(P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(1))
+#define P_SPI0_SSEL6	(P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(1))
+#define P_SPI0_SSEL5	(P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(1))
+#define P_SPI0_SSEL4	(P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(1))
+#define P_PPI0_FS3	(P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(1))
+#define P_PPI0_FS2	(P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(1))
+#define P_PPI0_FS1	(P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(1))
+#define P_TACLK0	(P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(1))
+#define P_TMRCLK	(P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(1))
+
+#define P_PPI0_D0	(P_DEFINED | P_IDENT(GPIO_PG0) | P_FUNCT(0))
+#define P_PPI0_D1	(P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0))
+#define P_PPI0_D2	(P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(0))
+#define P_PPI0_D3	(P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(0))
+#define P_PPI0_D4	(P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(0))
+#define P_PPI0_D5	(P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(0))
+#define P_PPI0_D6	(P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(0))
+#define P_PPI0_D7	(P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(0))
+#define P_PPI0_D8	(P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(0))
+#define P_PPI0_D9	(P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(0))
+#define P_PPI0_D10	(P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(0))
+#define P_PPI0_D11	(P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(0))
+#define P_PPI0_D12	(P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(0))
+#define P_PPI0_D13	(P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(0))
+#define P_PPI0_D14	(P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(0))
+#define P_PPI0_D15	(P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(0))
+#define P_SPORT1_DRSEC	(P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(1))
+#define P_SPORT1_DTSEC	(P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(1))
+#define P_SPORT1_RSCLK	(P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(1))
+#define P_SPORT1_RFS	(P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(1))
+#define P_SPORT1_DRPRI	(P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(1))
+#define P_SPORT1_TSCLK	(P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(1))
+#define P_SPORT1_TFS	(P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(1))
+#define P_SPORT1_DTPRI	(P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(1))
+
+#define P_MII0_ETxD0	(P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(0))
+#define P_MII0_ETxD1	(P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(0))
+#define P_MII0_ETxD2	(P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(0))
+#define P_MII0_ETxD3	(P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(0))
+#define P_MII0_ETxEN	(P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(0))
+#define P_MII0_TxCLK	(P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(0))
+#define P_MII0_PHYINT	(P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(0))
+#define P_MII0_COL	(P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(0))
+#define P_MII0_ERxD0	(P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(0))
+#define P_MII0_ERxD1	(P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(0))
+#define P_MII0_ERxD2	(P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(0))
+#define P_MII0_ERxD3	(P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(0))
+#define P_MII0_ERxDV	(P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(0))
+#define P_MII0_ERxCLK	(P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(0))
+#define P_MII0_ERxER	(P_DEFINED | P_IDENT(GPIO_PH14) | P_FUNCT(0))
+#define P_MII0_CRS	(P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(0))
+#define P_RMII0_REF_CLK	(P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(1))
+#define P_RMII0_MDINT	(P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(1))
+#define P_RMII0_CRS_DV	(P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(1))
+
+#define PORT_PJ0	(GPIO_PH15 + 1)
+#define PORT_PJ1	(GPIO_PH15 + 2)
+#define PORT_PJ2	(GPIO_PH15 + 3)
+#define PORT_PJ3	(GPIO_PH15 + 4)
+#define PORT_PJ4	(GPIO_PH15 + 5)
+#define PORT_PJ5	(GPIO_PH15 + 6)
+#define PORT_PJ6	(GPIO_PH15 + 7)
+#define PORT_PJ7	(GPIO_PH15 + 8)
+#define PORT_PJ8	(GPIO_PH15 + 9)
+#define PORT_PJ9	(GPIO_PH15 + 10)
+#define PORT_PJ10	(GPIO_PH15 + 11)
+#define PORT_PJ11	(GPIO_PH15 + 12)
+
+#define P_MDC		(P_DEFINED | P_IDENT(PORT_PJ0) | P_FUNCT(0))
+#define P_MDIO		(P_DEFINED | P_IDENT(PORT_PJ1) | P_FUNCT(0))
+#define P_TWI0_SCL	(P_DEFINED | P_IDENT(PORT_PJ2) | P_FUNCT(0))
+#define P_TWI0_SDA	(P_DEFINED | P_IDENT(PORT_PJ3) | P_FUNCT(0))
+#define P_SPORT0_DRSEC	(P_DEFINED | P_IDENT(PORT_PJ4) | P_FUNCT(0))
+#define P_SPORT0_DTSEC	(P_DEFINED | P_IDENT(PORT_PJ5) | P_FUNCT(0))
+#define P_SPORT0_RSCLK	(P_DEFINED | P_IDENT(PORT_PJ6) | P_FUNCT(0))
+#define P_SPORT0_RFS	(P_DEFINED | P_IDENT(PORT_PJ7) | P_FUNCT(0))
+#define P_SPORT0_DRPRI	(P_DEFINED | P_IDENT(PORT_PJ8) | P_FUNCT(0))
+#define P_SPORT0_TSCLK	(P_DEFINED | P_IDENT(PORT_PJ9) | P_FUNCT(0))
+#define P_SPORT0_TFS	(P_DEFINED | P_IDENT(PORT_PJ10) | P_FUNCT(0))
+#define P_SPORT0_DTPRI	(P_DEFINED | P_IDENT(PORT_PJ11) | P_FUNCT(1))
+#define P_CAN0_RX	(P_DEFINED | P_IDENT(PORT_PJ4) | P_FUNCT(1))
+#define P_CAN0_TX	(P_DEFINED | P_IDENT(PORT_PJ5) | P_FUNCT(1))
+#define P_SPI0_SSEL3	(P_DEFINED | P_IDENT(PORT_PJ10) | P_FUNCT(1))
+#define P_SPI0_SSEL2	(P_DEFINED | P_IDENT(PORT_PJ11) | P_FUNCT(1))
+#define P_SPI0_SSEL7	(P_DEFINED | P_IDENT(PORT_PJ5) | P_FUNCT(2))
+
+#endif /* _MACH_PORTMUX_H_ */
diff --git a/include/asm-blackfin/mach-bf548/anomaly.h b/include/asm-blackfin/mach-bf548/anomaly.h
new file mode 100644
index 0000000..aca1d4b
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/anomaly.h
@@ -0,0 +1,74 @@
+
+/*
+ * File:         include/asm-blackfin/mach-bf548/anomaly.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MACH_ANOMALY_H_
+#define _MACH_ANOMALY_H_
+#define ANOMALY_05000074 /* A multi issue instruction with dsp32shiftimm in
+			    slot1 and store of a P register in slot 2 is not
+			    supported */
+#define ANOMALY_05000119 /* DMA_RUN bit is not valid after a Peripheral Receive
+			    Channel DMA stops */
+#define ANOMALY_05000122 /* Rx.H can not be used to access 16-bit System MMR
+			    registers. */
+#define ANOMALY_05000245 /* Spurious Hardware Error from an Access in the
+			    Shadow of a Conditional Branch */
+#define ANOMALY_05000255 /* Entering Hibernate Mode with RTC Seconds event
+			    interrupt not functional */
+#define ANOMALY_05000265 /* Sensitivity to noise with slow input edge rates on
+			    SPORT external receive and transmit clocks. */
+#define ANOMALY_05000272 /* Certain data cache write through modes fail for
+			    VDDint <=0.9V */
+#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context is
+			    not restored */
+#define ANOMALY_05000310 /* False Hardware Errors Caused by Fetches at the
+			    Boundary of Reserved Memory */
+#define ANOMALY_05000312 /* Errors When SSYNC, CSYNC, or Loads to LT, LB and
+			    LC Registers Are Interrupted */
+#define ANOMALY_05000324 /* TWI Slave Boot Mode Is Not Functional */
+#define ANOMALY_05000325 /* External FIFO Boot Mode Is Not Functional */
+#define ANOMALY_05000327 /* Data Lost When Core and DMA Accesses Are Made to
+			    the USB FIFO Simultaneously */
+#define ANOMALY_05000328 /* Incorrect Access of OTP_STATUS During otp_write()
+			    function */
+#define ANOMALY_05000329 /* Synchronous Burst Flash Boot Mode Is Not Functional
+			    */
+#define ANOMALY_05000330 /* Host DMA Boot Mode Is Not Functional */
+#define ANOMALY_05000334 /* Inadequate Timing Margins on DDR DQS to DQ and DQM
+			    Skew */
+#define ANOMALY_05000335 /* Inadequate Rotary Debounce Logic Duration */
+#define ANOMALY_05000336 /* Phantom Interrupt Occurs After First Configuration
+			    of Host DMA Port */
+#define ANOMALY_05000337 /* Disallowed Configuration Prevents Subsequent
+			    Allowed Configuration on Host DMA Port */
+#define ANOMALY_05000338 /* Slave-Mode SPI0 MISO Failure With CPHA = 0 */
+
+#endif /* _MACH_ANOMALY_H_ */
diff --git a/include/asm-blackfin/mach-bf548/bf548.h b/include/asm-blackfin/mach-bf548/bf548.h
new file mode 100644
index 0000000..9498313
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/bf548.h
@@ -0,0 +1,271 @@
+/*
+ * File:         include/asm-blackfin/mach-bf548/bf548.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:  System MMR register and memory map for ADSP-BF548
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __MACH_BF548_H__
+#define __MACH_BF548_H__
+
+#define SUPPORTED_REVID 0
+
+#define OFFSET_(x) ((x) & 0x0000FFFF)
+
+/*some misc defines*/
+#define IMASK_IVG15		0x8000
+#define IMASK_IVG14		0x4000
+#define IMASK_IVG13		0x2000
+#define IMASK_IVG12		0x1000
+
+#define IMASK_IVG11		0x0800
+#define IMASK_IVG10		0x0400
+#define IMASK_IVG9		0x0200
+#define IMASK_IVG8		0x0100
+
+#define IMASK_IVG7		0x0080
+#define IMASK_IVGTMR	0x0040
+#define IMASK_IVGHW		0x0020
+
+/***************************/
+
+
+#define BLKFIN_DSUBBANKS	4
+#define BLKFIN_DWAYS		2
+#define BLKFIN_DLINES		64
+#define BLKFIN_ISUBBANKS	4
+#define BLKFIN_IWAYS		4
+#define BLKFIN_ILINES		32
+
+#define WAY0_L			0x1
+#define WAY1_L			0x2
+#define WAY01_L			0x3
+#define WAY2_L			0x4
+#define WAY02_L			0x5
+#define	WAY12_L			0x6
+#define	WAY012_L		0x7
+
+#define	WAY3_L			0x8
+#define	WAY03_L			0x9
+#define	WAY13_L			0xA
+#define	WAY013_L		0xB
+
+#define	WAY32_L			0xC
+#define	WAY320_L		0xD
+#define	WAY321_L		0xE
+#define	WAYALL_L		0xF
+
+#define DMC_ENABLE (2<<2)	/*yes, 2, not 1 */
+
+/********************************* EBIU Settings ************************************/
+#define AMBCTL0VAL	((CONFIG_BANK_1 << 16) | CONFIG_BANK_0)
+#define AMBCTL1VAL	((CONFIG_BANK_3 << 16) | CONFIG_BANK_2)
+
+#ifdef CONFIG_C_AMBEN_ALL
+#define V_AMBEN AMBEN_ALL
+#endif
+#ifdef CONFIG_C_AMBEN
+#define V_AMBEN 0x0
+#endif
+#ifdef CONFIG_C_AMBEN_B0
+#define V_AMBEN AMBEN_B0
+#endif
+#ifdef CONFIG_C_AMBEN_B0_B1
+#define V_AMBEN AMBEN_B0_B1
+#endif
+#ifdef CONFIG_C_AMBEN_B0_B1_B2
+#define V_AMBEN AMBEN_B0_B1_B2
+#endif
+#ifdef CONFIG_C_AMCKEN
+#define V_AMCKEN AMCKEN
+#else
+#define V_AMCKEN 0x0
+#endif
+
+#define AMGCTLVAL	(V_AMBEN | V_AMCKEN)
+
+#define MAX_VC	650000000
+#define MIN_VC	50000000
+
+/********************************PLL Settings **************************************/
+#ifdef CONFIG_BFIN_KERNEL_CLOCK
+#if (CONFIG_VCO_MULT < 0)
+#error "VCO Multiplier is less than 0. Please select a different value"
+#endif
+
+#if (CONFIG_VCO_MULT == 0)
+#error "VCO Multiplier should be greater than 0. Please select a different value"
+#endif
+
+#if (CONFIG_VCO_MULT > 64)
+#error "VCO Multiplier is more than 64. Please select a different value"
+#endif
+
+#ifndef CONFIG_CLKIN_HALF
+#define CONFIG_VCO_HZ	(CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)
+#else
+#define CONFIG_VCO_HZ	((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2)
+#endif
+
+#ifndef CONFIG_PLL_BYPASS
+#define CONFIG_CCLK_HZ	(CONFIG_VCO_HZ/CONFIG_CCLK_DIV)
+#define CONFIG_SCLK_HZ	(CONFIG_VCO_HZ/CONFIG_SCLK_DIV)
+#else
+#define CONFIG_CCLK_HZ	CONFIG_CLKIN_HZ
+#define CONFIG_SCLK_HZ	CONFIG_CLKIN_HZ
+#endif
+
+#if (CONFIG_SCLK_DIV < 1)
+#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
+#endif
+
+#if (CONFIG_SCLK_DIV > 15)
+#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
+#endif
+
+#if (CONFIG_CCLK_DIV != 1)
+#if (CONFIG_CCLK_DIV != 2)
+#if (CONFIG_CCLK_DIV != 4)
+#if (CONFIG_CCLK_DIV != 8)
+#error "CCLK DIV can be 1,2,4 or 8 only. Please select a proper value"
+#endif
+#endif
+#endif
+#endif
+
+#if (CONFIG_VCO_HZ > MAX_VC)
+#error "VCO selected is more than maximum value. Please change the VCO multipler"
+#endif
+
+#if (CONFIG_SCLK_HZ > 133000000)
+#error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier"
+#endif
+
+#if (CONFIG_SCLK_HZ < 27000000)
+#error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier"
+#endif
+
+#if (CONFIG_SCLK_HZ >= CONFIG_CCLK_HZ)
+#if (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ)
+#if (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ)
+#error "Please select sclk less than cclk"
+#endif
+#endif
+#endif
+
+#if (CONFIG_CCLK_DIV == 1)
+#define CONFIG_CCLK_ACT_DIV   CCLK_DIV1
+#endif
+#if (CONFIG_CCLK_DIV == 2)
+#define CONFIG_CCLK_ACT_DIV   CCLK_DIV2
+#endif
+#if (CONFIG_CCLK_DIV == 4)
+#define CONFIG_CCLK_ACT_DIV   CCLK_DIV4
+#endif
+#if (CONFIG_CCLK_DIV == 8)
+#define CONFIG_CCLK_ACT_DIV   CCLK_DIV8
+#endif
+#ifndef CONFIG_CCLK_ACT_DIV
+#define CONFIG_CCLK_ACT_DIV   CONFIG_CCLK_DIV_not_defined_properly
+#endif
+
+#endif	/* CONFIG_BFIN_KERNEL_CLOCK */
+
+#ifdef CONFIG_BF542
+#define CPU "BF542"
+#define CPUID 0x027c8000
+#endif
+#ifdef CONFIG_BF544
+#define CPU "BF544"
+#define CPUID 0x027c8000
+#endif
+#ifdef CONFIG_BF548
+#define CPU "BF548"
+#define CPUID 0x027c6000
+#endif
+#ifdef CONFIG_BF549
+#define CPU "BF549"
+#endif
+#ifndef CPU
+#define	CPU "UNKNOWN"
+#define CPUID 0x0
+#endif
+
+#if (CONFIG_MEM_SIZE % 4)
+#error "SDRAM mem size must be multible of 4MB"
+#endif
+
+#define SDRAM_IGENERIC    (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)
+#define SDRAM_IKERNEL     (SDRAM_IGENERIC | CPLB_LOCK)
+#define L1_IMEMORY        (               CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
+#define SDRAM_INON_CHBL   (               CPLB_USER_RD | CPLB_VALID)
+
+/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/
+
+#define ANOMALY_05000158_WORKAROUND		0x200
+#ifdef CONFIG_BLKFIN_WB		/*Write Back Policy */
+#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_DIRTY \
+			| CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
+#else				/*Write Through */
+#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW \
+			| CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
+#endif
+
+
+#define L1_DMEMORY       (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY )
+#define SDRAM_DNON_CHBL  (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
+#define SDRAM_EBIU       (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
+#define SDRAM_OOPS  	 (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY )
+
+#define SIZE_1K 0x00000400	/* 1K */
+#define SIZE_4K 0x00001000	/* 4K */
+#define SIZE_1M 0x00100000	/* 1M */
+#define SIZE_4M 0x00400000	/* 4M */
+
+#define MAX_CPLBS (16 * 2)
+
+/*
+* Number of required data CPLB switchtable entries
+* MEMSIZE / 4 (we mostly install 4M page size CPLBs
+* approx 16 for smaller 1MB page size CPLBs for allignment purposes
+* 1 for L1 Data Memory
+* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
+* 1 for ASYNC Memory
+*/
+
+
+#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1) * 2)
+
+/*
+* Number of required instruction CPLB switchtable entries
+* MEMSIZE / 4 (we mostly install 4M page size CPLBs
+* approx 12 for smaller 1MB page size CPLBs for allignment purposes
+* 1 for L1 Instruction Memory
+* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
+*/
+
+#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1) * 2)
+
+#endif	/* __MACH_BF48_H__  */
diff --git a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
new file mode 100644
index 0000000..2f4afc9
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
@@ -0,0 +1,193 @@
+#include <linux/serial.h>
+#include <asm/dma.h>
+
+#define NR_PORTS		4
+
+#define OFFSET_DLL              0x00	/* Divisor Latch (Low-Byte)             */
+#define OFFSET_DLH              0x04	/* Divisor Latch (High-Byte)            */
+#define OFFSET_GCTL             0x08	/* Global Control Register              */
+#define OFFSET_LCR              0x0C	/* Line Control Register                */
+#define OFFSET_MCR              0x10	/* Modem Control Register               */
+#define OFFSET_LSR              0x14	/* Line Status Register                 */
+#define OFFSET_MSR              0x18	/* Modem Status Register                */
+#define OFFSET_SCR              0x1C	/* SCR Scratch Register                 */
+#define OFFSET_IER_SET          0x20	/* Set Interrupt Enable Register        */
+#define OFFSET_IER_CLEAR        0x24	/* Clear Interrupt Enable Register      */
+#define OFFSET_THR              0x28	/* Transmit Holding register            */
+#define OFFSET_RBR              0x2C	/* Receive Buffer register              */
+
+#define UART_GET_CHAR(uart)     bfin_read16(((uart)->port.membase + OFFSET_RBR))
+#define UART_GET_DLL(uart)	bfin_read16(((uart)->port.membase + OFFSET_DLL))
+#define UART_GET_DLH(uart)	bfin_read16(((uart)->port.membase + OFFSET_DLH))
+#define UART_GET_IER(uart)      bfin_read16(((uart)->port.membase + OFFSET_IER_SET))
+#define UART_GET_LCR(uart)      bfin_read16(((uart)->port.membase + OFFSET_LCR))
+#define UART_GET_LSR(uart)      bfin_read16(((uart)->port.membase + OFFSET_LSR))
+#define UART_GET_GCTL(uart)     bfin_read16(((uart)->port.membase + OFFSET_GCTL))
+
+#define UART_PUT_CHAR(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_THR),v)
+#define UART_PUT_DLL(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
+#define UART_SET_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER_SET),v)
+#define UART_CLEAR_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER_CLEAR),v)
+#define UART_PUT_DLH(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
+#define UART_PUT_LSR(uart,v)	bfin_write16(((uart)->port.membase + OFFSET_LSR),v)
+#define UART_PUT_LCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
+#define UART_PUT_GCTL(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
+
+#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
+# define CONFIG_SERIAL_BFIN_CTSRTS
+
+# ifndef CONFIG_UART0_CTS_PIN
+#  define CONFIG_UART0_CTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART0_RTS_PIN
+#  define CONFIG_UART0_RTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART1_CTS_PIN
+#  define CONFIG_UART1_CTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART1_RTS_PIN
+#  define CONFIG_UART1_RTS_PIN -1
+# endif
+#endif
+/*
+ * The pin configuration is different from schematic
+ */
+struct bfin_serial_port {
+        struct uart_port        port;
+        unsigned int            old_status;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+	int			tx_done;
+	int			tx_count;
+	struct circ_buf		rx_dma_buf;
+	struct timer_list       rx_dma_timer;
+	int			rx_dma_nrows;
+	unsigned int		tx_dma_channel;
+	unsigned int		rx_dma_channel;
+	struct work_struct	tx_dma_workqueue;
+#else
+	struct work_struct 	cts_workqueue;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+	int		cts_pin;
+	int 		rts_pin;
+#endif
+};
+
+struct bfin_serial_port bfin_serial_ports[NR_PORTS];
+struct bfin_serial_res {
+	unsigned long	uart_base_addr;
+	int		uart_irq;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+	unsigned int	uart_tx_dma_channel;
+	unsigned int	uart_rx_dma_channel;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+	int	uart_cts_pin;
+	int	uart_rts_pin;
+#endif
+};
+
+struct bfin_serial_res bfin_serial_resource[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	{
+	0xFFC00400,
+	IRQ_UART0_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+	CH_UART0_TX,
+	CH_UART0_RX,
+#endif
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+	CONFIG_UART0_CTS_PIN,
+	CONFIG_UART0_RTS_PIN,
+#endif
+	},
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	{
+	0xFFC02000,
+	IRQ_UART1_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+	CH_UART1_TX,
+	CH_UART1_RX,
+#endif
+	},
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART2
+	{
+	0xFFC02100,
+	IRQ_UART2_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+	CH_UART2_TX,
+	CH_UART2_RX,
+#endif
+#ifdef CONFIG_BFIN_UART2_CTSRTS
+	CONFIG_UART2_CTS_PIN,
+	CONFIG_UART2_RTS_PIN,
+#endif
+	},
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART3
+	{
+	0xFFC03100,
+	IRQ_UART3_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+	CH_UART3_TX,
+	CH_UART3_RX,
+#endif
+	},
+#endif
+};
+
+int nr_ports = ARRAY_SIZE(bfin_serial_resource);
+
+static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+{
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	/* Enable UART0 RX and TX on pin 7 & 8 of PORT E */
+	bfin_write_PORTE_FER(0x180 | bfin_read_PORTE_FER());
+	bfin_write_PORTE_MUX(0x3C000 | bfin_read_PORTE_MUX());
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	/* Enable UART1 RX and TX on pin 0 & 1 of PORT H */
+	bfin_write_PORTH_FER(0x3 | bfin_read_PORTH_FER());
+	bfin_write_PORTH_MUX(~0xF & bfin_read_PORTH_MUX());
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+	/* Enable UART1 RTS and CTS on pin 9 & 10 of PORT E */
+	bfin_write_PORTE_FER(0x600 | bfin_read_PORTE_FER());
+	bfin_write_PORTE_MUX(~0x3C0000 & bfin_read_PORTE_MUX());
+#endif
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART2
+	/* Enable UART2 RX and TX on pin 4 & 5 of PORT B */
+	bfin_write_PORTB_FER(0x30 | bfin_read_PORTB_FER());
+	bfin_write_PORTB_MUX(~0xF00 & bfin_read_PORTB_MUX());
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART3
+	/* Enable UART3 RX and TX on pin 6 & 7 of PORT B */
+	bfin_write_PORTB_FER(0xC0 | bfin_read_PORTB_FER());
+	bfin_write_PORTB_MUX(~0xF000 | bfin_read_PORTB_MUX());
+#ifdef CONFIG_BFIN_UART3_CTSRTS
+	/* Enable UART3 RTS and CTS on pin 2 & 3 of PORT B */
+	bfin_write_PORTB_FER(0xC | bfin_read_PORTB_FER());
+	bfin_write_PORTB_MUX(~0xF0 | bfin_read_PORTB_MUX());
+#endif
+#endif
+	SSYNC();
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+	if (uart->cts_pin >= 0) {
+		gpio_request(uart->cts_pin, NULL);
+		gpio_direction_input(uart->cts_pin);
+	}
+
+	if (uart->rts_pin >= 0) {
+		gpio_request(uart->rts_pin, NULL);
+		gpio_direction_output(uart->rts_pin);
+	}
+#endif
+}
diff --git a/include/asm-blackfin/mach-bf548/blackfin.h b/include/asm-blackfin/mach-bf548/blackfin.h
new file mode 100644
index 0000000..791218f
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/blackfin.h
@@ -0,0 +1,168 @@
+/*
+ * File:         include/asm-blackfin/mach-bf548/blackfin.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MACH_BLACKFIN_H_
+#define _MACH_BLACKFIN_H_
+
+#define BF548_FAMILY
+
+#include "bf548.h"
+#include "mem_map.h"
+#include "anomaly.h"
+
+#ifdef CONFIG_BF542
+#include "defBF542.h"
+#endif
+
+#ifdef CONFIG_BF544
+#include "defBF544.h"
+#endif
+
+#ifdef CONFIG_BF548
+#include "defBF548.h"
+#endif
+
+#ifdef CONFIG_BF549
+#include "defBF549.h"
+#endif
+
+#if !(defined(__ASSEMBLY__) || defined(ASSEMBLY))
+#ifdef CONFIG_BF542
+#include "cdefBF542.h"
+#endif
+
+#ifdef CONFIG_BF544
+#include "cdefBF544.h"
+#endif
+#ifdef CONFIG_BF548
+#include "cdefBF548.h"
+#endif
+#ifdef CONFIG_BF549
+#include "cdefBF549.h"
+#endif
+
+/* UART 1*/
+#define bfin_read_UART_THR()		bfin_read_UART1_THR()
+#define bfin_write_UART_THR(val)	bfin_write_UART1_THR(val)
+#define bfin_read_UART_RBR()		bfin_read_UART1_RBR()
+#define bfin_write_UART_RBR(val)	bfin_write_UART1_RBR(val)
+#define bfin_read_UART_DLL()		bfin_read_UART1_DLL()
+#define bfin_write_UART_DLL(val)	bfin_write_UART1_DLL(val)
+#define bfin_read_UART_IER()		bfin_read_UART1_IER()
+#define bfin_write_UART_IER(val)	bfin_write_UART1_IER(val)
+#define bfin_read_UART_DLH()		bfin_read_UART1_DLH()
+#define bfin_write_UART_DLH(val)	bfin_write_UART1_DLH(val)
+#define bfin_read_UART_IIR()		bfin_read_UART1_IIR()
+#define bfin_write_UART_IIR(val)	bfin_write_UART1_IIR(val)
+#define bfin_read_UART_LCR()		bfin_read_UART1_LCR()
+#define bfin_write_UART_LCR(val)	bfin_write_UART1_LCR(val)
+#define bfin_read_UART_MCR()		bfin_read_UART1_MCR()
+#define bfin_write_UART_MCR(val)	bfin_write_UART1_MCR(val)
+#define bfin_read_UART_LSR()		bfin_read_UART1_LSR()
+#define bfin_write_UART_LSR(val)	bfin_write_UART1_LSR(val)
+#define bfin_read_UART_SCR()		bfin_read_UART1_SCR()
+#define bfin_write_UART_SCR(val)	bfin_write_UART1_SCR(val)
+#define bfin_read_UART_GCTL()		bfin_read_UART1_GCTL()
+#define bfin_write_UART_GCTL(val)	bfin_write_UART1_GCTL(val)
+
+#endif
+
+/* MAP used DEFINES from BF533 to BF54x - so we don't need to change 
+ * them in the driver, kernel, etc. */
+
+/* UART_IIR Register */
+#define STATUS(x)	((x << 1) & 0x06)
+#define STATUS_P1	0x02
+#define STATUS_P0	0x01
+
+/* UART 0*/
+
+/* DMA Channnel */
+#define bfin_read_CH_UART_RX()		bfin_read_CH_UART1_RX()
+#define bfin_write_CH_UART_RX(val)	bfin_write_CH_UART1_RX(val)
+#define bfin_read_CH_UART_TX()		bfin_read_CH_UART1_TX()
+#define bfin_write_CH_UART_TX(val)	bfin_write_CH_UART1_TX(val)
+#define CH_UART_RX			CH_UART1_RX
+#define CH_UART_TX			CH_UART1_TX
+
+/* System Interrupt Controller */
+#define bfin_read_IRQ_UART_RX()		bfin_read_IRQ_UART1_RX()
+#define bfin_write_IRQ_UART_RX(val)	bfin_write_IRQ_UART1_RX(val)
+#define bfin_read_IRQ_UART_TX()		bfin_read_IRQ_UART1_TX()
+#define bfin_write_IRQ_UART_TX(val)	bfin_write_IRQ_UART1_TX(val)
+#define bfin_read_IRQ_UART_ERROR()	bfin_read_IRQ_UART1_ERROR()
+#define bfin_write_IRQ_UART_ERROR(val)	bfin_write_IRQ_UART1_ERROR(val)
+#define IRQ_UART_RX			IRQ_UART1_RX
+#define	IRQ_UART_TX			IRQ_UART1_TX
+#define	IRQ_UART_ERROR			IRQ_UART1_ERROR
+
+/* MMR Registers*/
+#define bfin_read_UART_THR()		bfin_read_UART1_THR()
+#define bfin_write_UART_THR(val)	bfin_write_UART1_THR(val)
+#define bfin_read_UART_RBR()		bfin_read_UART1_RBR()
+#define bfin_write_UART_RBR(val)	bfin_write_UART1_RBR(val)
+#define bfin_read_UART_DLL()		bfin_read_UART1_DLL()
+#define bfin_write_UART_DLL(val)	bfin_write_UART1_DLL(val)
+#define bfin_read_UART_IER()		bfin_read_UART1_IER()
+#define bfin_write_UART_IER(val)	bfin_write_UART1_IER(val)
+#define bfin_read_UART_DLH()		bfin_read_UART1_DLH()
+#define bfin_write_UART_DLH(val)	bfin_write_UART1_DLH(val)
+#define bfin_read_UART_IIR()		bfin_read_UART1_IIR()
+#define bfin_write_UART_IIR(val)	bfin_write_UART1_IIR(val)
+#define bfin_read_UART_LCR()		bfin_read_UART1_LCR()
+#define bfin_write_UART_LCR(val)	bfin_write_UART1_LCR(val)
+#define bfin_read_UART_MCR()		bfin_read_UART1_MCR()
+#define bfin_write_UART_MCR(val)	bfin_write_UART1_MCR(val)
+#define bfin_read_UART_LSR()		bfin_read_UART1_LSR()
+#define bfin_write_UART_LSR(val)	bfin_write_UART1_LSR(val)
+#define bfin_read_UART_SCR()		bfin_read_UART1_SCR()
+#define bfin_write_UART_SCR(val)	bfin_write_UART1_SCR(val)
+#define bfin_read_UART_GCTL()		bfin_read_UART1_GCTL()
+#define bfin_write_UART_GCTL(val)	bfin_write_UART1_GCTL(val)
+#define UART_THR			UART1_THR
+#define UART_RBR			UART1_RBR
+#define UART_DLL			UART1_DLL
+#define UART_IER			UART1_IER
+#define UART_DLH			UART1_DLH
+#define UART_IIR			UART1_IIR
+#define UART_LCR			UART1_LCR
+#define UART_MCR			UART1_MCR
+#define UART_LSR			UART1_LSR
+#define UART_SCR			UART1_SCR
+#define UART_GCTL			UART1_GCTL
+
+/* PLL_DIV Masks */
+#define CCLK_DIV1 CSEL_DIV1	/* CCLK = VCO / 1 */
+#define CCLK_DIV2 CSEL_DIV2	/* CCLK = VCO / 2 */
+#define CCLK_DIV4 CSEL_DIV4	/* CCLK = VCO / 4 */
+#define CCLK_DIV8 CSEL_DIV8	/* CCLK = VCO / 8 */
+
+#endif
diff --git a/include/asm-blackfin/mach-bf548/cdefBF54x_base.h b/include/asm-blackfin/mach-bf548/cdefBF54x_base.h
index 6bbcefe..98d35a9 100644
--- a/include/asm-blackfin/mach-bf548/cdefBF54x_base.h
+++ b/include/asm-blackfin/mach-bf548/cdefBF54x_base.h
@@ -31,7 +31,8 @@
 #ifndef _CDEF_BF54X_H
 #define _CDEF_BF54X_H
 
-#include <defBF54x_base.h>
+#include "defBF54x_base.h"
+#include <asm/system.h>
 
 /* ************************************************************** */
 /* SYSTEM & MMR ADDRESS DEFINITIONS COMMON TO ALL ADSP-BF54x    */
@@ -44,7 +45,30 @@
 #define bfin_read_PLL_DIV()		bfin_read16(PLL_DIV)
 #define bfin_write_PLL_DIV(val)		bfin_write16(PLL_DIV, val)
 #define bfin_read_VR_CTL()		bfin_read16(VR_CTL)
-#define bfin_write_VR_CTL(val)		bfin_write16(VR_CTL, val)
+/* Writing to VR_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_VR_CTL(unsigned int val)
+{
+	unsigned long flags, iwr0, iwr1, iwr2;
+
+	/* Enable the PLL Wakeup bit in SIC IWR */
+	iwr0 = bfin_read32(SIC_IWR0);
+	iwr1 = bfin_read32(SIC_IWR1);
+	iwr2 = bfin_read32(SIC_IWR2);
+	/* Only allow PPL Wakeup) */
+	bfin_write32(SIC_IWR0, IWR_ENABLE(0));
+	bfin_write32(SIC_IWR1, 0);
+	bfin_write32(SIC_IWR2, 0);
+
+	bfin_write16(VR_CTL, val);
+	__builtin_bfin_ssync();
+
+	local_irq_save(flags);
+	asm("IDLE;");
+	local_irq_restore(flags);
+	bfin_write32(SIC_IWR0, iwr0);
+	bfin_write32(SIC_IWR1, iwr1);
+	bfin_write32(SIC_IWR2, iwr2);
+}
 #define bfin_read_PLL_STAT()		bfin_read16(PLL_STAT)
 #define bfin_write_PLL_STAT(val)	bfin_write16(PLL_STAT, val)
 #define bfin_read_PLL_LOCKCNT()		bfin_read16(PLL_LOCKCNT)
@@ -70,12 +94,18 @@
 #define bfin_write_SIC_IMASK1(val)	bfin_write32(SIC_IMASK1, val)
 #define bfin_read_SIC_IMASK2()		bfin_read32(SIC_IMASK2)
 #define bfin_write_SIC_IMASK2(val)	bfin_write32(SIC_IMASK2, val)
+#define bfin_read_SIC_IMASK(x)		bfin_read32(SIC_IMASK0 + (x << 2))
+#define bfin_write_SIC_IMASK(x, val)	bfin_write32((SIC_IMASK0 + (x << 2)), val)
+
 #define bfin_read_SIC_ISR0()		bfin_read32(SIC_ISR0)
 #define bfin_write_SIC_ISR0(val)	bfin_write32(SIC_ISR0, val)
 #define bfin_read_SIC_ISR1()		bfin_read32(SIC_ISR1)
 #define bfin_write_SIC_ISR1(val)	bfin_write32(SIC_ISR1, val)
 #define bfin_read_SIC_ISR2()		bfin_read32(SIC_ISR2)
 #define bfin_write_SIC_ISR2(val)	bfin_write32(SIC_ISR2, val)
+#define bfin_read_SIC_ISR(x)		bfin_read32(SIC_ISR0 + (x << 2))
+#define bfin_write_SIC_ISR(x, val)	bfin_write32((SIC_ISR0 + (x << 2)), val)
+
 #define bfin_read_SIC_IWR0()		bfin_read32(SIC_IWR0)
 #define bfin_write_SIC_IWR0(val)	bfin_write32(SIC_IWR0, val)
 #define bfin_read_SIC_IWR1()		bfin_read32(SIC_IWR1)
@@ -710,21 +740,21 @@
 #define bfin_read_MDMA_D0_NEXT_DESC_PTR() 	bfin_read32(MDMA_D0_NEXT_DESC_PTR)
 #define bfin_write_MDMA_D0_NEXT_DESC_PTR(val) 	bfin_write32(MDMA_D0_NEXT_DESC_PTR)
 #define bfin_read_MDMA_D0_START_ADDR() 		bfin_read32(MDMA_D0_START_ADDR)
-#define bfin_write_MDMA_D0_START_ADDR(val) 	bfin_write32(MDMA_D0_START_ADDR)
+#define bfin_write_MDMA_D0_START_ADDR(val) 	bfin_write32(MDMA_D0_START_ADDR, val)
 #define bfin_read_MDMA_D0_CONFIG()		bfin_read16(MDMA_D0_CONFIG)
 #define bfin_write_MDMA_D0_CONFIG(val)		bfin_write16(MDMA_D0_CONFIG, val)
 #define bfin_read_MDMA_D0_X_COUNT()		bfin_read16(MDMA_D0_X_COUNT)
 #define bfin_write_MDMA_D0_X_COUNT(val)		bfin_write16(MDMA_D0_X_COUNT, val)
 #define bfin_read_MDMA_D0_X_MODIFY()		bfin_read16(MDMA_D0_X_MODIFY)
-#define bfin_write_MDMA_D0_X_MODIFY(val) 	bfin_write16(MDMA_D0_X_MODIFY)
+#define bfin_write_MDMA_D0_X_MODIFY(val) 	bfin_write16(MDMA_D0_X_MODIFY, val)
 #define bfin_read_MDMA_D0_Y_COUNT()		bfin_read16(MDMA_D0_Y_COUNT)
 #define bfin_write_MDMA_D0_Y_COUNT(val)		bfin_write16(MDMA_D0_Y_COUNT, val)
 #define bfin_read_MDMA_D0_Y_MODIFY()		bfin_read16(MDMA_D0_Y_MODIFY)
-#define bfin_write_MDMA_D0_Y_MODIFY(val) 	bfin_write16(MDMA_D0_Y_MODIFY)
+#define bfin_write_MDMA_D0_Y_MODIFY(val) 	bfin_write16(MDMA_D0_Y_MODIFY, val)
 #define bfin_read_MDMA_D0_CURR_DESC_PTR() 	bfin_read32(MDMA_D0_CURR_DESC_PTR)
-#define bfin_write_MDMA_D0_CURR_DESC_PTR(val) 	bfin_write32(MDMA_D0_CURR_DESC_PTR)
+#define bfin_write_MDMA_D0_CURR_DESC_PTR(val) 	bfin_write32(MDMA_D0_CURR_DESC_PTR, val)
 #define bfin_read_MDMA_D0_CURR_ADDR() 		bfin_read32(MDMA_D0_CURR_ADDR)
-#define bfin_write_MDMA_D0_CURR_ADDR(val) 	bfin_write32(MDMA_D0_CURR_ADDR)
+#define bfin_write_MDMA_D0_CURR_ADDR(val) 	bfin_write32(MDMA_D0_CURR_ADDR, val)
 #define bfin_read_MDMA_D0_IRQ_STATUS()		bfin_read16(MDMA_D0_IRQ_STATUS)
 #define bfin_write_MDMA_D0_IRQ_STATUS(val)	bfin_write16(MDMA_D0_IRQ_STATUS, val)
 #define bfin_read_MDMA_D0_PERIPHERAL_MAP()	bfin_read16(MDMA_D0_PERIPHERAL_MAP)
@@ -734,23 +764,23 @@
 #define bfin_read_MDMA_D0_CURR_Y_COUNT()	bfin_read16(MDMA_D0_CURR_Y_COUNT)
 #define bfin_write_MDMA_D0_CURR_Y_COUNT(val)	bfin_write16(MDMA_D0_CURR_Y_COUNT, val)
 #define bfin_read_MDMA_S0_NEXT_DESC_PTR() 	bfin_read32(MDMA_S0_NEXT_DESC_PTR)
-#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val) 	bfin_write32(MDMA_S0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val) 	bfin_write32(MDMA_S0_NEXT_DESC_PTR, val)
 #define bfin_read_MDMA_S0_START_ADDR() 		bfin_read32(MDMA_S0_START_ADDR)
-#define bfin_write_MDMA_S0_START_ADDR(val) 	bfin_write32(MDMA_S0_START_ADDR)
+#define bfin_write_MDMA_S0_START_ADDR(val) 	bfin_write32(MDMA_S0_START_ADDR, val)
 #define bfin_read_MDMA_S0_CONFIG()		bfin_read16(MDMA_S0_CONFIG)
 #define bfin_write_MDMA_S0_CONFIG(val)		bfin_write16(MDMA_S0_CONFIG, val)
 #define bfin_read_MDMA_S0_X_COUNT()		bfin_read16(MDMA_S0_X_COUNT)
 #define bfin_write_MDMA_S0_X_COUNT(val)		bfin_write16(MDMA_S0_X_COUNT, val)
 #define bfin_read_MDMA_S0_X_MODIFY()		bfin_read16(MDMA_S0_X_MODIFY)
-#define bfin_write_MDMA_S0_X_MODIFY(val) 	bfin_write16(MDMA_S0_X_MODIFY)
+#define bfin_write_MDMA_S0_X_MODIFY(val) 	bfin_write16(MDMA_S0_X_MODIFY, val)
 #define bfin_read_MDMA_S0_Y_COUNT()		bfin_read16(MDMA_S0_Y_COUNT)
 #define bfin_write_MDMA_S0_Y_COUNT(val)		bfin_write16(MDMA_S0_Y_COUNT, val)
 #define bfin_read_MDMA_S0_Y_MODIFY()		bfin_read16(MDMA_S0_Y_MODIFY)
-#define bfin_write_MDMA_S0_Y_MODIFY(val) 	bfin_write16(MDMA_S0_Y_MODIFY)
+#define bfin_write_MDMA_S0_Y_MODIFY(val) 	bfin_write16(MDMA_S0_Y_MODIFY, val)
 #define bfin_read_MDMA_S0_CURR_DESC_PTR() 	bfin_read32(MDMA_S0_CURR_DESC_PTR)
-#define bfin_write_MDMA_S0_CURR_DESC_PTR(val) 	bfin_write32(MDMA_S0_CURR_DESC_PTR)
+#define bfin_write_MDMA_S0_CURR_DESC_PTR(val) 	bfin_write32(MDMA_S0_CURR_DESC_PTR, val)
 #define bfin_read_MDMA_S0_CURR_ADDR() 		bfin_read32(MDMA_S0_CURR_ADDR)
-#define bfin_write_MDMA_S0_CURR_ADDR(val) 	bfin_write32(MDMA_S0_CURR_ADDR)
+#define bfin_write_MDMA_S0_CURR_ADDR(val) 	bfin_write32(MDMA_S0_CURR_ADDR, val)
 #define bfin_read_MDMA_S0_IRQ_STATUS()		bfin_read16(MDMA_S0_IRQ_STATUS)
 #define bfin_write_MDMA_S0_IRQ_STATUS(val)	bfin_write16(MDMA_S0_IRQ_STATUS, val)
 #define bfin_read_MDMA_S0_PERIPHERAL_MAP()	bfin_read16(MDMA_S0_PERIPHERAL_MAP)
@@ -763,9 +793,9 @@
 /* MDMA Stream 1 Registers */
 
 #define bfin_read_MDMA_D1_NEXT_DESC_PTR() 	bfin_read32(MDMA_D1_NEXT_DESC_PTR)
-#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val) 	bfin_write32(MDMA_D1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val) 	bfin_write32(MDMA_D1_NEXT_DESC_PTR, val)
 #define bfin_read_MDMA_D1_START_ADDR() 		bfin_read32(MDMA_D1_START_ADDR)
-#define bfin_write_MDMA_D1_START_ADDR(val) 	bfin_write32(MDMA_D1_START_ADDR)
+#define bfin_write_MDMA_D1_START_ADDR(val) 	bfin_write32(MDMA_D1_START_ADDR, val)
 #define bfin_read_MDMA_D1_CONFIG()		bfin_read16(MDMA_D1_CONFIG)
 #define bfin_write_MDMA_D1_CONFIG(val)		bfin_write16(MDMA_D1_CONFIG, val)
 #define bfin_read_MDMA_D1_X_COUNT()		bfin_read16(MDMA_D1_X_COUNT)
@@ -777,9 +807,9 @@
 #define bfin_read_MDMA_D1_Y_MODIFY()		bfin_read16(MDMA_D1_Y_MODIFY)
 #define bfin_write_MDMA_D1_Y_MODIFY(val) 	bfin_write16(MDMA_D1_Y_MODIFY)
 #define bfin_read_MDMA_D1_CURR_DESC_PTR() 	bfin_read32(MDMA_D1_CURR_DESC_PTR)
-#define bfin_write_MDMA_D1_CURR_DESC_PTR(val) 	bfin_write32(MDMA_D1_CURR_DESC_PTR)
+#define bfin_write_MDMA_D1_CURR_DESC_PTR(val) 	bfin_write32(MDMA_D1_CURR_DESC_PTR, val)
 #define bfin_read_MDMA_D1_CURR_ADDR() 		bfin_read32(MDMA_D1_CURR_ADDR)
-#define bfin_write_MDMA_D1_CURR_ADDR(val) 	bfin_write32(MDMA_D1_CURR_ADDR)
+#define bfin_write_MDMA_D1_CURR_ADDR(val) 	bfin_write32(MDMA_D1_CURR_ADDR, val)
 #define bfin_read_MDMA_D1_IRQ_STATUS()		bfin_read16(MDMA_D1_IRQ_STATUS)
 #define bfin_write_MDMA_D1_IRQ_STATUS(val)	bfin_write16(MDMA_D1_IRQ_STATUS, val)
 #define bfin_read_MDMA_D1_PERIPHERAL_MAP()	bfin_read16(MDMA_D1_PERIPHERAL_MAP)
@@ -789,9 +819,9 @@
 #define bfin_read_MDMA_D1_CURR_Y_COUNT()	bfin_read16(MDMA_D1_CURR_Y_COUNT)
 #define bfin_write_MDMA_D1_CURR_Y_COUNT(val)	bfin_write16(MDMA_D1_CURR_Y_COUNT, val)
 #define bfin_read_MDMA_S1_NEXT_DESC_PTR() 	bfin_read32(MDMA_S1_NEXT_DESC_PTR)
-#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val) 	bfin_write32(MDMA_S1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val) 	bfin_write32(MDMA_S1_NEXT_DESC_PTR, val)
 #define bfin_read_MDMA_S1_START_ADDR() 		bfin_read32(MDMA_S1_START_ADDR)
-#define bfin_write_MDMA_S1_START_ADDR(val) 	bfin_write32(MDMA_S1_START_ADDR)
+#define bfin_write_MDMA_S1_START_ADDR(val) 	bfin_write32(MDMA_S1_START_ADDR, val)
 #define bfin_read_MDMA_S1_CONFIG()		bfin_read16(MDMA_S1_CONFIG)
 #define bfin_write_MDMA_S1_CONFIG(val)		bfin_write16(MDMA_S1_CONFIG, val)
 #define bfin_read_MDMA_S1_X_COUNT()		bfin_read16(MDMA_S1_X_COUNT)
@@ -803,9 +833,9 @@
 #define bfin_read_MDMA_S1_Y_MODIFY()		bfin_read16(MDMA_S1_Y_MODIFY)
 #define bfin_write_MDMA_S1_Y_MODIFY(val) 	bfin_write16(MDMA_S1_Y_MODIFY)
 #define bfin_read_MDMA_S1_CURR_DESC_PTR() 	bfin_read32(MDMA_S1_CURR_DESC_PTR)
-#define bfin_write_MDMA_S1_CURR_DESC_PTR(val) 	bfin_write32(MDMA_S1_CURR_DESC_PTR)
+#define bfin_write_MDMA_S1_CURR_DESC_PTR(val) 	bfin_write32(MDMA_S1_CURR_DESC_PTR, val)
 #define bfin_read_MDMA_S1_CURR_ADDR() 		bfin_read32(MDMA_S1_CURR_ADDR)
-#define bfin_write_MDMA_S1_CURR_ADDR(val) 	bfin_write32(MDMA_S1_CURR_ADDR)
+#define bfin_write_MDMA_S1_CURR_ADDR(val) 	bfin_write32(MDMA_S1_CURR_ADDR, val)
 #define bfin_read_MDMA_S1_IRQ_STATUS()		bfin_read16(MDMA_S1_IRQ_STATUS)
 #define bfin_write_MDMA_S1_IRQ_STATUS(val)	bfin_write16(MDMA_S1_IRQ_STATUS, val)
 #define bfin_read_MDMA_S1_PERIPHERAL_MAP()	bfin_read16(MDMA_S1_PERIPHERAL_MAP)
diff --git a/include/asm-blackfin/mach-bf548/defBF542.h b/include/asm-blackfin/mach-bf548/defBF542.h
index ac968fc..32d0713 100644
--- a/include/asm-blackfin/mach-bf548/defBF542.h
+++ b/include/asm-blackfin/mach-bf548/defBF542.h
@@ -362,7 +362,6 @@
 /* Bit masks for KPAD_CTL */
 
 #define                   KPAD_EN  0x1        /* Keypad Enable */
-#define                  nKPAD_EN  0x0       
 #define              KPAD_IRQMODE  0x6        /* Key Press Interrupt Enable */
 #define                KPAD_ROWEN  0x1c00     /* Row Enable Width */
 #define                KPAD_COLEN  0xe000     /* Column Enable Width */
@@ -384,29 +383,21 @@
 /* Bit masks for KPAD_STAT */
 
 #define                  KPAD_IRQ  0x1        /* Keypad Interrupt Status */
-#define                 nKPAD_IRQ  0x0       
 #define              KPAD_MROWCOL  0x6        /* Multiple Row/Column Keypress Status */
 #define              KPAD_PRESSED  0x8        /* Key press current status */
-#define             nKPAD_PRESSED  0x0       
 
 /* Bit masks for KPAD_SOFTEVAL */
 
 #define           KPAD_SOFTEVAL_E  0x2        /* Software Programmable Force Evaluate */
-#define          nKPAD_SOFTEVAL_E  0x0       
 
 /* Bit masks for SDH_COMMAND */
 
 #define                   CMD_IDX  0x3f       /* Command Index */
 #define                   CMD_RSP  0x40       /* Response */
-#define                  nCMD_RSP  0x0       
 #define                 CMD_L_RSP  0x80       /* Long Response */
-#define                nCMD_L_RSP  0x0       
 #define                 CMD_INT_E  0x100      /* Command Interrupt */
-#define                nCMD_INT_E  0x0       
 #define                CMD_PEND_E  0x200      /* Command Pending */
-#define               nCMD_PEND_E  0x0       
 #define                     CMD_E  0x400      /* Command Enable */
-#define                    nCMD_E  0x0       
 
 /* Bit masks for SDH_PWR_CTL */
 
@@ -415,21 +406,15 @@
 #define                       TBD  0x3c       /* TBD */
 #endif
 #define                 SD_CMD_OD  0x40       /* Open Drain Output */
-#define                nSD_CMD_OD  0x0       
 #define                   ROD_CTL  0x80       /* Rod Control */
-#define                  nROD_CTL  0x0       
 
 /* Bit masks for SDH_CLK_CTL */
 
 #define                    CLKDIV  0xff       /* MC_CLK Divisor */
 #define                     CLK_E  0x100      /* MC_CLK Bus Clock Enable */
-#define                    nCLK_E  0x0       
 #define                  PWR_SV_E  0x200      /* Power Save Enable */
-#define                 nPWR_SV_E  0x0       
 #define             CLKDIV_BYPASS  0x400      /* Bypass Divisor */
-#define            nCLKDIV_BYPASS  0x0       
 #define                  WIDE_BUS  0x800      /* Wide Bus Mode Enable */
-#define                 nWIDE_BUS  0x0       
 
 /* Bit masks for SDH_RESP_CMD */
 
@@ -438,133 +423,74 @@
 /* Bit masks for SDH_DATA_CTL */
 
 #define                     DTX_E  0x1        /* Data Transfer Enable */
-#define                    nDTX_E  0x0       
 #define                   DTX_DIR  0x2        /* Data Transfer Direction */
-#define                  nDTX_DIR  0x0       
 #define                  DTX_MODE  0x4        /* Data Transfer Mode */
-#define                 nDTX_MODE  0x0       
 #define                 DTX_DMA_E  0x8        /* Data Transfer DMA Enable */
-#define                nDTX_DMA_E  0x0       
 #define              DTX_BLK_LGTH  0xf0       /* Data Transfer Block Length */
 
 /* Bit masks for SDH_STATUS */
 
 #define              CMD_CRC_FAIL  0x1        /* CMD CRC Fail */
-#define             nCMD_CRC_FAIL  0x0       
 #define              DAT_CRC_FAIL  0x2        /* Data CRC Fail */
-#define             nDAT_CRC_FAIL  0x0       
 #define               CMD_TIMEOUT  0x4        /* CMD Time Out */
-#define              nCMD_TIMEOUT  0x0       
 #define               DAT_TIMEOUT  0x8        /* Data Time Out */
-#define              nDAT_TIMEOUT  0x0       
 #define               TX_UNDERRUN  0x10       /* Transmit Underrun */
-#define              nTX_UNDERRUN  0x0       
 #define                RX_OVERRUN  0x20       /* Receive Overrun */
-#define               nRX_OVERRUN  0x0       
 #define              CMD_RESP_END  0x40       /* CMD Response End */
-#define             nCMD_RESP_END  0x0       
 #define                  CMD_SENT  0x80       /* CMD Sent */
-#define                 nCMD_SENT  0x0       
 #define                   DAT_END  0x100      /* Data End */
-#define                  nDAT_END  0x0       
 #define             START_BIT_ERR  0x200      /* Start Bit Error */
-#define            nSTART_BIT_ERR  0x0       
 #define               DAT_BLK_END  0x400      /* Data Block End */
-#define              nDAT_BLK_END  0x0       
 #define                   CMD_ACT  0x800      /* CMD Active */
-#define                  nCMD_ACT  0x0       
 #define                    TX_ACT  0x1000     /* Transmit Active */
-#define                   nTX_ACT  0x0       
 #define                    RX_ACT  0x2000     /* Receive Active */
-#define                   nRX_ACT  0x0       
 #define              TX_FIFO_STAT  0x4000     /* Transmit FIFO Status */
-#define             nTX_FIFO_STAT  0x0       
 #define              RX_FIFO_STAT  0x8000     /* Receive FIFO Status */
-#define             nRX_FIFO_STAT  0x0       
 #define              TX_FIFO_FULL  0x10000    /* Transmit FIFO Full */
-#define             nTX_FIFO_FULL  0x0       
 #define              RX_FIFO_FULL  0x20000    /* Receive FIFO Full */
-#define             nRX_FIFO_FULL  0x0       
 #define              TX_FIFO_ZERO  0x40000    /* Transmit FIFO Empty */
-#define             nTX_FIFO_ZERO  0x0       
 #define               RX_DAT_ZERO  0x80000    /* Receive FIFO Empty */
-#define              nRX_DAT_ZERO  0x0       
 #define                TX_DAT_RDY  0x100000   /* Transmit Data Available */
-#define               nTX_DAT_RDY  0x0       
 #define               RX_FIFO_RDY  0x200000   /* Receive Data Available */
-#define              nRX_FIFO_RDY  0x0       
 
 /* Bit masks for SDH_STATUS_CLR */
 
 #define         CMD_CRC_FAIL_STAT  0x1        /* CMD CRC Fail Status */
-#define        nCMD_CRC_FAIL_STAT  0x0       
 #define         DAT_CRC_FAIL_STAT  0x2        /* Data CRC Fail Status */
-#define        nDAT_CRC_FAIL_STAT  0x0       
 #define          CMD_TIMEOUT_STAT  0x4        /* CMD Time Out Status */
-#define         nCMD_TIMEOUT_STAT  0x0       
 #define          DAT_TIMEOUT_STAT  0x8        /* Data Time Out status */
-#define         nDAT_TIMEOUT_STAT  0x0       
 #define          TX_UNDERRUN_STAT  0x10       /* Transmit Underrun Status */
-#define         nTX_UNDERRUN_STAT  0x0       
 #define           RX_OVERRUN_STAT  0x20       /* Receive Overrun Status */
-#define          nRX_OVERRUN_STAT  0x0       
 #define         CMD_RESP_END_STAT  0x40       /* CMD Response End Status */
-#define        nCMD_RESP_END_STAT  0x0       
 #define             CMD_SENT_STAT  0x80       /* CMD Sent Status */
-#define            nCMD_SENT_STAT  0x0       
 #define              DAT_END_STAT  0x100      /* Data End Status */
-#define             nDAT_END_STAT  0x0       
 #define        START_BIT_ERR_STAT  0x200      /* Start Bit Error Status */
-#define       nSTART_BIT_ERR_STAT  0x0       
 #define          DAT_BLK_END_STAT  0x400      /* Data Block End Status */
-#define         nDAT_BLK_END_STAT  0x0       
 
 /* Bit masks for SDH_MASK0 */
 
 #define         CMD_CRC_FAIL_MASK  0x1        /* CMD CRC Fail Mask */
-#define        nCMD_CRC_FAIL_MASK  0x0       
 #define         DAT_CRC_FAIL_MASK  0x2        /* Data CRC Fail Mask */
-#define        nDAT_CRC_FAIL_MASK  0x0       
 #define          CMD_TIMEOUT_MASK  0x4        /* CMD Time Out Mask */
-#define         nCMD_TIMEOUT_MASK  0x0       
 #define          DAT_TIMEOUT_MASK  0x8        /* Data Time Out Mask */
-#define         nDAT_TIMEOUT_MASK  0x0       
 #define          TX_UNDERRUN_MASK  0x10       /* Transmit Underrun Mask */
-#define         nTX_UNDERRUN_MASK  0x0       
 #define           RX_OVERRUN_MASK  0x20       /* Receive Overrun Mask */
-#define          nRX_OVERRUN_MASK  0x0       
 #define         CMD_RESP_END_MASK  0x40       /* CMD Response End Mask */
-#define        nCMD_RESP_END_MASK  0x0       
 #define             CMD_SENT_MASK  0x80       /* CMD Sent Mask */
-#define            nCMD_SENT_MASK  0x0       
 #define              DAT_END_MASK  0x100      /* Data End Mask */
-#define             nDAT_END_MASK  0x0       
 #define        START_BIT_ERR_MASK  0x200      /* Start Bit Error Mask */
-#define       nSTART_BIT_ERR_MASK  0x0       
 #define          DAT_BLK_END_MASK  0x400      /* Data Block End Mask */
-#define         nDAT_BLK_END_MASK  0x0       
 #define              CMD_ACT_MASK  0x800      /* CMD Active Mask */
-#define             nCMD_ACT_MASK  0x0       
 #define               TX_ACT_MASK  0x1000     /* Transmit Active Mask */
-#define              nTX_ACT_MASK  0x0       
 #define               RX_ACT_MASK  0x2000     /* Receive Active Mask */
-#define              nRX_ACT_MASK  0x0       
 #define         TX_FIFO_STAT_MASK  0x4000     /* Transmit FIFO Status Mask */
-#define        nTX_FIFO_STAT_MASK  0x0       
 #define         RX_FIFO_STAT_MASK  0x8000     /* Receive FIFO Status Mask */
-#define        nRX_FIFO_STAT_MASK  0x0       
 #define         TX_FIFO_FULL_MASK  0x10000    /* Transmit FIFO Full Mask */
-#define        nTX_FIFO_FULL_MASK  0x0       
 #define         RX_FIFO_FULL_MASK  0x20000    /* Receive FIFO Full Mask */
-#define        nRX_FIFO_FULL_MASK  0x0       
 #define         TX_FIFO_ZERO_MASK  0x40000    /* Transmit FIFO Empty Mask */
-#define        nTX_FIFO_ZERO_MASK  0x0       
 #define          RX_DAT_ZERO_MASK  0x80000    /* Receive FIFO Empty Mask */
-#define         nRX_DAT_ZERO_MASK  0x0       
 #define           TX_DAT_RDY_MASK  0x100000   /* Transmit Data Available Mask */
-#define          nTX_DAT_RDY_MASK  0x0       
 #define          RX_FIFO_RDY_MASK  0x200000   /* Receive Data Available Mask */
-#define         nRX_FIFO_RDY_MASK  0x0       
 
 /* Bit masks for SDH_FIFO_CNT */
 
@@ -573,73 +499,47 @@
 /* Bit masks for SDH_E_STATUS */
 
 #define              SDIO_INT_DET  0x2        /* SDIO Int Detected */
-#define             nSDIO_INT_DET  0x0       
 #define               SD_CARD_DET  0x10       /* SD Card Detect */
-#define              nSD_CARD_DET  0x0       
 
 /* Bit masks for SDH_E_MASK */
 
 #define                  SDIO_MSK  0x2        /* Mask SDIO Int Detected */
-#define                 nSDIO_MSK  0x0       
 #define                   SCD_MSK  0x40       /* Mask Card Detect */
-#define                  nSCD_MSK  0x0       
 
 /* Bit masks for SDH_CFG */
 
 #define                   CLKS_EN  0x1        /* Clocks Enable */
-#define                  nCLKS_EN  0x0       
 #define                      SD4E  0x4        /* SDIO 4-Bit Enable */
-#define                     nSD4E  0x0       
 #define                       MWE  0x8        /* Moving Window Enable */
-#define                      nMWE  0x0       
 #define                    SD_RST  0x10       /* SDMMC Reset */
-#define                   nSD_RST  0x0       
 #define                 PUP_SDDAT  0x20       /* Pull-up SD_DAT */
-#define                nPUP_SDDAT  0x0       
 #define                PUP_SDDAT3  0x40       /* Pull-up SD_DAT3 */
-#define               nPUP_SDDAT3  0x0       
 #define                 PD_SDDAT3  0x80       /* Pull-down SD_DAT3 */
-#define                nPD_SDDAT3  0x0       
 
 /* Bit masks for SDH_RD_WAIT_EN */
 
 #define                       RWR  0x1        /* Read Wait Request */
-#define                      nRWR  0x0       
 
 /* Bit masks for ATAPI_CONTROL */
 
 #define                 PIO_START  0x1        /* Start PIO/Reg Op */
-#define                nPIO_START  0x0       
 #define               MULTI_START  0x2        /* Start Multi-DMA Op */
-#define              nMULTI_START  0x0       
 #define               ULTRA_START  0x4        /* Start Ultra-DMA Op */
-#define              nULTRA_START  0x0       
 #define                  XFER_DIR  0x8        /* Transfer Direction */
-#define                 nXFER_DIR  0x0       
 #define                  IORDY_EN  0x10       /* IORDY Enable */
-#define                 nIORDY_EN  0x0       
 #define                FIFO_FLUSH  0x20       /* Flush FIFOs */
-#define               nFIFO_FLUSH  0x0       
 #define                  SOFT_RST  0x40       /* Soft Reset */
-#define                 nSOFT_RST  0x0       
 #define                   DEV_RST  0x80       /* Device Reset */
-#define                  nDEV_RST  0x0       
 #define                TFRCNT_RST  0x100      /* Trans Count Reset */
-#define               nTFRCNT_RST  0x0       
 #define               END_ON_TERM  0x200      /* End/Terminate Select */
-#define              nEND_ON_TERM  0x0       
 #define               PIO_USE_DMA  0x400      /* PIO-DMA Enable */
-#define              nPIO_USE_DMA  0x0       
 #define          UDMAIN_FIFO_THRS  0xf000     /* Ultra DMA-IN FIFO Threshold */
 
 /* Bit masks for ATAPI_STATUS */
 
 #define               PIO_XFER_ON  0x1        /* PIO transfer in progress */
-#define              nPIO_XFER_ON  0x0       
 #define             MULTI_XFER_ON  0x2        /* Multi-word DMA transfer in progress */
-#define            nMULTI_XFER_ON  0x0       
 #define             ULTRA_XFER_ON  0x4        /* Ultra DMA transfer in progress */
-#define            nULTRA_XFER_ON  0x0       
 #define               ULTRA_IN_FL  0xf0       /* Ultra DMA Input FIFO Level */
 
 /* Bit masks for ATAPI_DEV_ADDR */
@@ -649,66 +549,39 @@
 /* Bit masks for ATAPI_INT_MASK */
 
 #define        ATAPI_DEV_INT_MASK  0x1        /* Device interrupt mask */
-#define       nATAPI_DEV_INT_MASK  0x0       
 #define             PIO_DONE_MASK  0x2        /* PIO transfer done interrupt mask */
-#define            nPIO_DONE_MASK  0x0       
 #define           MULTI_DONE_MASK  0x4        /* Multi-DMA transfer done interrupt mask */
-#define          nMULTI_DONE_MASK  0x0       
 #define          UDMAIN_DONE_MASK  0x8        /* Ultra-DMA in transfer done interrupt mask */
-#define         nUDMAIN_DONE_MASK  0x0       
 #define         UDMAOUT_DONE_MASK  0x10       /* Ultra-DMA out transfer done interrupt mask */
-#define        nUDMAOUT_DONE_MASK  0x0       
 #define       HOST_TERM_XFER_MASK  0x20       /* Host terminate current transfer interrupt mask */
-#define      nHOST_TERM_XFER_MASK  0x0       
 #define           MULTI_TERM_MASK  0x40       /* Device terminate Multi-DMA transfer interrupt mask */
-#define          nMULTI_TERM_MASK  0x0       
 #define          UDMAIN_TERM_MASK  0x80       /* Device terminate Ultra-DMA-in transfer interrupt mask */
-#define         nUDMAIN_TERM_MASK  0x0       
 #define         UDMAOUT_TERM_MASK  0x100      /* Device terminate Ultra-DMA-out transfer interrupt mask */
-#define        nUDMAOUT_TERM_MASK  0x0       
 
 /* Bit masks for ATAPI_INT_STATUS */
 
 #define             ATAPI_DEV_INT  0x1        /* Device interrupt status */
-#define            nATAPI_DEV_INT  0x0       
 #define              PIO_DONE_INT  0x2        /* PIO transfer done interrupt status */
-#define             nPIO_DONE_INT  0x0       
 #define            MULTI_DONE_INT  0x4        /* Multi-DMA transfer done interrupt status */
-#define           nMULTI_DONE_INT  0x0       
 #define           UDMAIN_DONE_INT  0x8        /* Ultra-DMA in transfer done interrupt status */
-#define          nUDMAIN_DONE_INT  0x0       
 #define          UDMAOUT_DONE_INT  0x10       /* Ultra-DMA out transfer done interrupt status */
-#define         nUDMAOUT_DONE_INT  0x0       
 #define        HOST_TERM_XFER_INT  0x20       /* Host terminate current transfer interrupt status */
-#define       nHOST_TERM_XFER_INT  0x0       
 #define            MULTI_TERM_INT  0x40       /* Device terminate Multi-DMA transfer interrupt status */
-#define           nMULTI_TERM_INT  0x0       
 #define           UDMAIN_TERM_INT  0x80       /* Device terminate Ultra-DMA-in transfer interrupt status */
-#define          nUDMAIN_TERM_INT  0x0       
 #define          UDMAOUT_TERM_INT  0x100      /* Device terminate Ultra-DMA-out transfer interrupt status */
-#define         nUDMAOUT_TERM_INT  0x0       
 
 /* Bit masks for ATAPI_LINE_STATUS */
 
 #define                ATAPI_INTR  0x1        /* Device interrupt to host line status */
-#define               nATAPI_INTR  0x0       
 #define                ATAPI_DASP  0x2        /* Device dasp to host line status */
-#define               nATAPI_DASP  0x0       
 #define                ATAPI_CS0N  0x4        /* ATAPI chip select 0 line status */
-#define               nATAPI_CS0N  0x0       
 #define                ATAPI_CS1N  0x8        /* ATAPI chip select 1 line status */
-#define               nATAPI_CS1N  0x0       
 #define                ATAPI_ADDR  0x70       /* ATAPI address line status */
 #define              ATAPI_DMAREQ  0x80       /* ATAPI DMA request line status */
-#define             nATAPI_DMAREQ  0x0       
 #define             ATAPI_DMAACKN  0x100      /* ATAPI DMA acknowledge line status */
-#define            nATAPI_DMAACKN  0x0       
 #define               ATAPI_DIOWN  0x200      /* ATAPI write line status */
-#define              nATAPI_DIOWN  0x0       
 #define               ATAPI_DIORN  0x400      /* ATAPI read line status */
-#define              nATAPI_DIORN  0x0       
 #define               ATAPI_IORDY  0x800      /* ATAPI IORDY line status */
-#define              nATAPI_IORDY  0x0       
 
 /* Bit masks for ATAPI_SM_STATE */
 
@@ -720,7 +593,6 @@
 /* Bit masks for ATAPI_TERMINATE */
 
 #define           ATAPI_HOST_TERM  0x1        /* Host terminationation */
-#define          nATAPI_HOST_TERM  0x0       
 
 /* Bit masks for ATAPI_REG_TIM_0 */
 
@@ -779,131 +651,77 @@
 /* Bit masks for USB_POWER */
 
 #define           ENABLE_SUSPENDM  0x1        /* enable SuspendM output */
-#define          nENABLE_SUSPENDM  0x0       
 #define              SUSPEND_MODE  0x2        /* Suspend Mode indicator */
-#define             nSUSPEND_MODE  0x0       
 #define               RESUME_MODE  0x4        /* DMA Mode */
-#define              nRESUME_MODE  0x0       
 #define                     RESET  0x8        /* Reset indicator */
-#define                    nRESET  0x0       
 #define                   HS_MODE  0x10       /* High Speed mode indicator */
-#define                  nHS_MODE  0x0       
 #define                 HS_ENABLE  0x20       /* high Speed Enable */
-#define                nHS_ENABLE  0x0       
 #define                 SOFT_CONN  0x40       /* Soft connect */
-#define                nSOFT_CONN  0x0       
 #define                ISO_UPDATE  0x80       /* Isochronous update */
-#define               nISO_UPDATE  0x0       
 
 /* Bit masks for USB_INTRTX */
 
 #define                    EP0_TX  0x1        /* Tx Endpoint 0 interrupt */
-#define                   nEP0_TX  0x0       
 #define                    EP1_TX  0x2        /* Tx Endpoint 1 interrupt */
-#define                   nEP1_TX  0x0       
 #define                    EP2_TX  0x4        /* Tx Endpoint 2 interrupt */
-#define                   nEP2_TX  0x0       
 #define                    EP3_TX  0x8        /* Tx Endpoint 3 interrupt */
-#define                   nEP3_TX  0x0       
 #define                    EP4_TX  0x10       /* Tx Endpoint 4 interrupt */
-#define                   nEP4_TX  0x0       
 #define                    EP5_TX  0x20       /* Tx Endpoint 5 interrupt */
-#define                   nEP5_TX  0x0       
 #define                    EP6_TX  0x40       /* Tx Endpoint 6 interrupt */
-#define                   nEP6_TX  0x0       
 #define                    EP7_TX  0x80       /* Tx Endpoint 7 interrupt */
-#define                   nEP7_TX  0x0       
 
 /* Bit masks for USB_INTRRX */
 
 #define                    EP1_RX  0x2        /* Rx Endpoint 1 interrupt */
-#define                   nEP1_RX  0x0       
 #define                    EP2_RX  0x4        /* Rx Endpoint 2 interrupt */
-#define                   nEP2_RX  0x0       
 #define                    EP3_RX  0x8        /* Rx Endpoint 3 interrupt */
-#define                   nEP3_RX  0x0       
 #define                    EP4_RX  0x10       /* Rx Endpoint 4 interrupt */
-#define                   nEP4_RX  0x0       
 #define                    EP5_RX  0x20       /* Rx Endpoint 5 interrupt */
-#define                   nEP5_RX  0x0       
 #define                    EP6_RX  0x40       /* Rx Endpoint 6 interrupt */
-#define                   nEP6_RX  0x0       
 #define                    EP7_RX  0x80       /* Rx Endpoint 7 interrupt */
-#define                   nEP7_RX  0x0       
 
 /* Bit masks for USB_INTRTXE */
 
 #define                  EP0_TX_E  0x1        /* Endpoint 0 interrupt Enable */
-#define                 nEP0_TX_E  0x0       
 #define                  EP1_TX_E  0x2        /* Tx Endpoint 1 interrupt  Enable */
-#define                 nEP1_TX_E  0x0       
 #define                  EP2_TX_E  0x4        /* Tx Endpoint 2 interrupt  Enable */
-#define                 nEP2_TX_E  0x0       
 #define                  EP3_TX_E  0x8        /* Tx Endpoint 3 interrupt  Enable */
-#define                 nEP3_TX_E  0x0       
 #define                  EP4_TX_E  0x10       /* Tx Endpoint 4 interrupt  Enable */
-#define                 nEP4_TX_E  0x0       
 #define                  EP5_TX_E  0x20       /* Tx Endpoint 5 interrupt  Enable */
-#define                 nEP5_TX_E  0x0       
 #define                  EP6_TX_E  0x40       /* Tx Endpoint 6 interrupt  Enable */
-#define                 nEP6_TX_E  0x0       
 #define                  EP7_TX_E  0x80       /* Tx Endpoint 7 interrupt  Enable */
-#define                 nEP7_TX_E  0x0       
 
 /* Bit masks for USB_INTRRXE */
 
 #define                  EP1_RX_E  0x2        /* Rx Endpoint 1 interrupt  Enable */
-#define                 nEP1_RX_E  0x0       
 #define                  EP2_RX_E  0x4        /* Rx Endpoint 2 interrupt  Enable */
-#define                 nEP2_RX_E  0x0       
 #define                  EP3_RX_E  0x8        /* Rx Endpoint 3 interrupt  Enable */
-#define                 nEP3_RX_E  0x0       
 #define                  EP4_RX_E  0x10       /* Rx Endpoint 4 interrupt  Enable */
-#define                 nEP4_RX_E  0x0       
 #define                  EP5_RX_E  0x20       /* Rx Endpoint 5 interrupt  Enable */
-#define                 nEP5_RX_E  0x0       
 #define                  EP6_RX_E  0x40       /* Rx Endpoint 6 interrupt  Enable */
-#define                 nEP6_RX_E  0x0       
 #define                  EP7_RX_E  0x80       /* Rx Endpoint 7 interrupt  Enable */
-#define                 nEP7_RX_E  0x0       
 
 /* Bit masks for USB_INTRUSB */
 
 #define                 SUSPEND_B  0x1        /* Suspend indicator */
-#define                nSUSPEND_B  0x0       
 #define                  RESUME_B  0x2        /* Resume indicator */
-#define                 nRESUME_B  0x0       
 #define          RESET_OR_BABLE_B  0x4        /* Reset/babble indicator */
-#define         nRESET_OR_BABLE_B  0x0       
 #define                     SOF_B  0x8        /* Start of frame */
-#define                    nSOF_B  0x0       
 #define                    CONN_B  0x10       /* Connection indicator */
-#define                   nCONN_B  0x0       
 #define                  DISCON_B  0x20       /* Disconnect indicator */
-#define                 nDISCON_B  0x0       
 #define             SESSION_REQ_B  0x40       /* Session Request */
-#define            nSESSION_REQ_B  0x0       
 #define              VBUS_ERROR_B  0x80       /* Vbus threshold indicator */
-#define             nVBUS_ERROR_B  0x0       
 
 /* Bit masks for USB_INTRUSBE */
 
 #define                SUSPEND_BE  0x1        /* Suspend indicator int enable */
-#define               nSUSPEND_BE  0x0       
 #define                 RESUME_BE  0x2        /* Resume indicator int enable */
-#define                nRESUME_BE  0x0       
 #define         RESET_OR_BABLE_BE  0x4        /* Reset/babble indicator int enable */
-#define        nRESET_OR_BABLE_BE  0x0       
 #define                    SOF_BE  0x8        /* Start of frame int enable */
-#define                   nSOF_BE  0x0       
 #define                   CONN_BE  0x10       /* Connection indicator int enable */
-#define                  nCONN_BE  0x0       
 #define                 DISCON_BE  0x20       /* Disconnect indicator int enable */
-#define                nDISCON_BE  0x0       
 #define            SESSION_REQ_BE  0x40       /* Session Request int enable */
-#define           nSESSION_REQ_BE  0x0       
 #define             VBUS_ERROR_BE  0x80       /* Vbus threshold indicator int enable */
-#define            nVBUS_ERROR_BE  0x0       
 
 /* Bit masks for USB_FRAME */
 
@@ -916,117 +734,67 @@
 /* Bit masks for USB_GLOBAL_CTL */
 
 #define                GLOBAL_ENA  0x1        /* enables USB module */
-#define               nGLOBAL_ENA  0x0       
 #define                EP1_TX_ENA  0x2        /* Transmit endpoint 1 enable */
-#define               nEP1_TX_ENA  0x0       
 #define                EP2_TX_ENA  0x4        /* Transmit endpoint 2 enable */
-#define               nEP2_TX_ENA  0x0       
 #define                EP3_TX_ENA  0x8        /* Transmit endpoint 3 enable */
-#define               nEP3_TX_ENA  0x0       
 #define                EP4_TX_ENA  0x10       /* Transmit endpoint 4 enable */
-#define               nEP4_TX_ENA  0x0       
 #define                EP5_TX_ENA  0x20       /* Transmit endpoint 5 enable */
-#define               nEP5_TX_ENA  0x0       
 #define                EP6_TX_ENA  0x40       /* Transmit endpoint 6 enable */
-#define               nEP6_TX_ENA  0x0       
 #define                EP7_TX_ENA  0x80       /* Transmit endpoint 7 enable */
-#define               nEP7_TX_ENA  0x0       
 #define                EP1_RX_ENA  0x100      /* Receive endpoint 1 enable */
-#define               nEP1_RX_ENA  0x0       
 #define                EP2_RX_ENA  0x200      /* Receive endpoint 2 enable */
-#define               nEP2_RX_ENA  0x0       
 #define                EP3_RX_ENA  0x400      /* Receive endpoint 3 enable */
-#define               nEP3_RX_ENA  0x0       
 #define                EP4_RX_ENA  0x800      /* Receive endpoint 4 enable */
-#define               nEP4_RX_ENA  0x0       
 #define                EP5_RX_ENA  0x1000     /* Receive endpoint 5 enable */
-#define               nEP5_RX_ENA  0x0       
 #define                EP6_RX_ENA  0x2000     /* Receive endpoint 6 enable */
-#define               nEP6_RX_ENA  0x0       
 #define                EP7_RX_ENA  0x4000     /* Receive endpoint 7 enable */
-#define               nEP7_RX_ENA  0x0       
 
 /* Bit masks for USB_OTG_DEV_CTL */
 
 #define                   SESSION  0x1        /* session indicator */
-#define                  nSESSION  0x0       
 #define                  HOST_REQ  0x2        /* Host negotiation request */
-#define                 nHOST_REQ  0x0       
 #define                 HOST_MODE  0x4        /* indicates USBDRC is a host */
-#define                nHOST_MODE  0x0       
 #define                     VBUS0  0x8        /* Vbus level indicator[0] */
-#define                    nVBUS0  0x0       
 #define                     VBUS1  0x10       /* Vbus level indicator[1] */
-#define                    nVBUS1  0x0       
 #define                     LSDEV  0x20       /* Low-speed indicator */
-#define                    nLSDEV  0x0       
 #define                     FSDEV  0x40       /* Full or High-speed indicator */
-#define                    nFSDEV  0x0       
 #define                  B_DEVICE  0x80       /* A' or 'B' device indicator */
-#define                 nB_DEVICE  0x0       
 
 /* Bit masks for USB_OTG_VBUS_IRQ */
 
 #define             DRIVE_VBUS_ON  0x1        /* indicator to drive VBUS control circuit */
-#define            nDRIVE_VBUS_ON  0x0       
 #define            DRIVE_VBUS_OFF  0x2        /* indicator to shut off charge pump */
-#define           nDRIVE_VBUS_OFF  0x0       
 #define           CHRG_VBUS_START  0x4        /* indicator for external circuit to start charging VBUS */
-#define          nCHRG_VBUS_START  0x0       
 #define             CHRG_VBUS_END  0x8        /* indicator for external circuit to end charging VBUS */
-#define            nCHRG_VBUS_END  0x0       
 #define        DISCHRG_VBUS_START  0x10       /* indicator to start discharging VBUS */
-#define       nDISCHRG_VBUS_START  0x0       
 #define          DISCHRG_VBUS_END  0x20       /* indicator to stop discharging VBUS */
-#define         nDISCHRG_VBUS_END  0x0       
 
 /* Bit masks for USB_OTG_VBUS_MASK */
 
 #define         DRIVE_VBUS_ON_ENA  0x1        /* enable DRIVE_VBUS_ON interrupt */
-#define        nDRIVE_VBUS_ON_ENA  0x0       
 #define        DRIVE_VBUS_OFF_ENA  0x2        /* enable DRIVE_VBUS_OFF interrupt */
-#define       nDRIVE_VBUS_OFF_ENA  0x0       
 #define       CHRG_VBUS_START_ENA  0x4        /* enable CHRG_VBUS_START interrupt */
-#define      nCHRG_VBUS_START_ENA  0x0       
 #define         CHRG_VBUS_END_ENA  0x8        /* enable CHRG_VBUS_END interrupt */
-#define        nCHRG_VBUS_END_ENA  0x0       
 #define    DISCHRG_VBUS_START_ENA  0x10       /* enable DISCHRG_VBUS_START interrupt */
-#define   nDISCHRG_VBUS_START_ENA  0x0       
 #define      DISCHRG_VBUS_END_ENA  0x20       /* enable DISCHRG_VBUS_END interrupt */
-#define     nDISCHRG_VBUS_END_ENA  0x0       
 
 /* Bit masks for USB_CSR0 */
 
 #define                  RXPKTRDY  0x1        /* data packet receive indicator */
-#define                 nRXPKTRDY  0x0       
 #define                  TXPKTRDY  0x2        /* data packet in FIFO indicator */
-#define                 nTXPKTRDY  0x0       
 #define                STALL_SENT  0x4        /* STALL handshake sent */
-#define               nSTALL_SENT  0x0       
 #define                   DATAEND  0x8        /* Data end indicator */
-#define                  nDATAEND  0x0       
 #define                  SETUPEND  0x10       /* Setup end */
-#define                 nSETUPEND  0x0       
 #define                 SENDSTALL  0x20       /* Send STALL handshake */
-#define                nSENDSTALL  0x0       
 #define         SERVICED_RXPKTRDY  0x40       /* used to clear the RxPktRdy bit */
-#define        nSERVICED_RXPKTRDY  0x0       
 #define         SERVICED_SETUPEND  0x80       /* used to clear the SetupEnd bit */
-#define        nSERVICED_SETUPEND  0x0       
 #define                 FLUSHFIFO  0x100      /* flush endpoint FIFO */
-#define                nFLUSHFIFO  0x0       
 #define          STALL_RECEIVED_H  0x4        /* STALL handshake received host mode */
-#define         nSTALL_RECEIVED_H  0x0       
 #define                SETUPPKT_H  0x8        /* send Setup token host mode */
-#define               nSETUPPKT_H  0x0       
 #define                   ERROR_H  0x10       /* timeout error indicator host mode */
-#define                  nERROR_H  0x0       
 #define                  REQPKT_H  0x20       /* Request an IN transaction host mode */
-#define                 nREQPKT_H  0x0       
 #define               STATUSPKT_H  0x40       /* Status stage transaction host mode */
-#define              nSTATUSPKT_H  0x0       
 #define             NAK_TIMEOUT_H  0x80       /* EP0 halted after a NAK host mode */
-#define            nNAK_TIMEOUT_H  0x0       
 
 /* Bit masks for USB_COUNT0 */
 
@@ -1047,37 +815,21 @@
 /* Bit masks for USB_TXCSR */
 
 #define                TXPKTRDY_T  0x1        /* data packet in FIFO indicator */
-#define               nTXPKTRDY_T  0x0       
 #define          FIFO_NOT_EMPTY_T  0x2        /* FIFO not empty */
-#define         nFIFO_NOT_EMPTY_T  0x0       
 #define                UNDERRUN_T  0x4        /* TxPktRdy not set  for an IN token */
-#define               nUNDERRUN_T  0x0       
 #define               FLUSHFIFO_T  0x8        /* flush endpoint FIFO */
-#define              nFLUSHFIFO_T  0x0       
 #define              STALL_SEND_T  0x10       /* issue a Stall handshake */
-#define             nSTALL_SEND_T  0x0       
 #define              STALL_SENT_T  0x20       /* Stall handshake transmitted */
-#define             nSTALL_SENT_T  0x0       
 #define        CLEAR_DATATOGGLE_T  0x40       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_T  0x0       
 #define                INCOMPTX_T  0x80       /* indicates that a large packet is split */
-#define               nINCOMPTX_T  0x0       
 #define              DMAREQMODE_T  0x400      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_T  0x0       
 #define        FORCE_DATATOGGLE_T  0x800      /* Force data toggle */
-#define       nFORCE_DATATOGGLE_T  0x0       
 #define              DMAREQ_ENA_T  0x1000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_T  0x0       
 #define                     ISO_T  0x4000     /* enable Isochronous transfers */
-#define                    nISO_T  0x0       
 #define                 AUTOSET_T  0x8000     /* allows TxPktRdy to be set automatically */
-#define                nAUTOSET_T  0x0       
 #define                  ERROR_TH  0x4        /* error condition host mode */
-#define                 nERROR_TH  0x0       
 #define         STALL_RECEIVED_TH  0x20       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_TH  0x0       
 #define            NAK_TIMEOUT_TH  0x80       /* NAK timeout host mode */
-#define           nNAK_TIMEOUT_TH  0x0       
 
 /* Bit masks for USB_TXCOUNT */
 
@@ -1086,45 +838,25 @@
 /* Bit masks for USB_RXCSR */
 
 #define                RXPKTRDY_R  0x1        /* data packet in FIFO indicator */
-#define               nRXPKTRDY_R  0x0       
 #define               FIFO_FULL_R  0x2        /* FIFO not empty */
-#define              nFIFO_FULL_R  0x0       
 #define                 OVERRUN_R  0x4        /* TxPktRdy not set  for an IN token */
-#define                nOVERRUN_R  0x0       
 #define               DATAERROR_R  0x8        /* Out packet cannot be loaded into Rx  FIFO */
-#define              nDATAERROR_R  0x0       
 #define               FLUSHFIFO_R  0x10       /* flush endpoint FIFO */
-#define              nFLUSHFIFO_R  0x0       
 #define              STALL_SEND_R  0x20       /* issue a Stall handshake */
-#define             nSTALL_SEND_R  0x0       
 #define              STALL_SENT_R  0x40       /* Stall handshake transmitted */
-#define             nSTALL_SENT_R  0x0       
 #define        CLEAR_DATATOGGLE_R  0x80       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_R  0x0       
 #define                INCOMPRX_R  0x100      /* indicates that a large packet is split */
-#define               nINCOMPRX_R  0x0       
 #define              DMAREQMODE_R  0x800      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_R  0x0       
 #define                 DISNYET_R  0x1000     /* disable Nyet handshakes */
-#define                nDISNYET_R  0x0       
 #define              DMAREQ_ENA_R  0x2000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_R  0x0       
 #define                     ISO_R  0x4000     /* enable Isochronous transfers */
-#define                    nISO_R  0x0       
 #define               AUTOCLEAR_R  0x8000     /* allows TxPktRdy to be set automatically */
-#define              nAUTOCLEAR_R  0x0       
 #define                  ERROR_RH  0x4        /* TxPktRdy not set  for an IN token host mode */
-#define                 nERROR_RH  0x0       
 #define                 REQPKT_RH  0x20       /* request an IN transaction host mode */
-#define                nREQPKT_RH  0x0       
 #define         STALL_RECEIVED_RH  0x40       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_RH  0x0       
 #define               INCOMPRX_RH  0x100      /* indicates that a large packet is split host mode */
-#define              nINCOMPRX_RH  0x0       
 #define             DMAREQMODE_RH  0x800      /* DMA mode (0 or 1) selection host mode */
-#define            nDMAREQMODE_RH  0x0       
 #define                AUTOREQ_RH  0x4000     /* sets ReqPkt automatically host mode */
-#define               nAUTOREQ_RH  0x0       
 
 /* Bit masks for USB_RXCOUNT */
 
@@ -1151,35 +883,22 @@
 /* Bit masks for USB_DMA_INTERRUPT */
 
 #define                  DMA0_INT  0x1        /* DMA0 pending interrupt */
-#define                 nDMA0_INT  0x0       
 #define                  DMA1_INT  0x2        /* DMA1 pending interrupt */
-#define                 nDMA1_INT  0x0       
 #define                  DMA2_INT  0x4        /* DMA2 pending interrupt */
-#define                 nDMA2_INT  0x0       
 #define                  DMA3_INT  0x8        /* DMA3 pending interrupt */
-#define                 nDMA3_INT  0x0       
 #define                  DMA4_INT  0x10       /* DMA4 pending interrupt */
-#define                 nDMA4_INT  0x0       
 #define                  DMA5_INT  0x20       /* DMA5 pending interrupt */
-#define                 nDMA5_INT  0x0       
 #define                  DMA6_INT  0x40       /* DMA6 pending interrupt */
-#define                 nDMA6_INT  0x0       
 #define                  DMA7_INT  0x80       /* DMA7 pending interrupt */
-#define                 nDMA7_INT  0x0       
 
 /* Bit masks for USB_DMAxCONTROL */
 
 #define                   DMA_ENA  0x1        /* DMA enable */
-#define                  nDMA_ENA  0x0       
 #define                 DIRECTION  0x2        /* direction of DMA transfer */
-#define                nDIRECTION  0x0       
 #define                      MODE  0x4        /* DMA Bus error */
-#define                     nMODE  0x0       
 #define                   INT_ENA  0x8        /* Interrupt enable */
-#define                  nINT_ENA  0x0       
 #define                     EPNUM  0xf0       /* EP number */
 #define                  BUSERROR  0x100      /* DMA Bus error */
-#define                 nBUSERROR  0x0       
 
 /* Bit masks for USB_DMAxADDRHIGH */
 
diff --git a/include/asm-blackfin/mach-bf548/defBF544.h b/include/asm-blackfin/mach-bf548/defBF544.h
index 8fc77ea..dd955dc 100644
--- a/include/asm-blackfin/mach-bf548/defBF544.h
+++ b/include/asm-blackfin/mach-bf548/defBF544.h
@@ -538,21 +538,13 @@
 /* Bit masks for PIXC_CTL */
 
 #define                   PIXC_EN  0x1        /* Pixel Compositor Enable */
-#define                  nPIXC_EN  0x0       
 #define                  OVR_A_EN  0x2        /* Overlay A Enable */
-#define                 nOVR_A_EN  0x0       
 #define                  OVR_B_EN  0x4        /* Overlay B Enable */
-#define                 nOVR_B_EN  0x0       
 #define                  IMG_FORM  0x8        /* Image Data Format */
-#define                 nIMG_FORM  0x0       
 #define                  OVR_FORM  0x10       /* Overlay Data Format */
-#define                 nOVR_FORM  0x0       
 #define                  OUT_FORM  0x20       /* Output Data Format */
-#define                 nOUT_FORM  0x0       
 #define                   UDS_MOD  0x40       /* Resampling Mode */
-#define                  nUDS_MOD  0x0       
 #define                     TC_EN  0x80       /* Transparent Color Enable */
-#define                    nTC_EN  0x0       
 #define                  IMG_STAT  0x300      /* Image FIFO Status */
 #define                  OVR_STAT  0xc00      /* Overlay FIFO Status */
 #define                    WM_LVL  0x3000     /* FIFO Watermark Level */
@@ -600,13 +592,9 @@
 /* Bit masks for PIXC_INTRSTAT */
 
 #define                OVR_INT_EN  0x1        /* Interrupt at End of Last Valid Overlay */
-#define               nOVR_INT_EN  0x0       
 #define                FRM_INT_EN  0x2        /* Interrupt at End of Frame */
-#define               nFRM_INT_EN  0x0       
 #define              OVR_INT_STAT  0x4        /* Overlay Interrupt Status */
-#define             nOVR_INT_STAT  0x0       
 #define              FRM_INT_STAT  0x8        /* Frame Interrupt Status */
-#define             nFRM_INT_STAT  0x0       
 
 /* Bit masks for PIXC_RYCON */
 
@@ -614,7 +602,6 @@
 #define                       A12  0xffc00    /* A12 in the Coefficient Matrix */
 #define                       A13  0x3ff00000 /* A13 in the Coefficient Matrix */
 #define                  RY_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nRY_MULT4  0x0       
 
 /* Bit masks for PIXC_GUCON */
 
@@ -622,7 +609,6 @@
 #define                       A22  0xffc00    /* A22 in the Coefficient Matrix */
 #define                       A23  0x3ff00000 /* A23 in the Coefficient Matrix */
 #define                  GU_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nGU_MULT4  0x0       
 
 /* Bit masks for PIXC_BVCON */
 
@@ -630,7 +616,6 @@
 #define                       A32  0xffc00    /* A32 in the Coefficient Matrix */
 #define                       A33  0x3ff00000 /* A33 in the Coefficient Matrix */
 #define                  BV_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nBV_MULT4  0x0       
 
 /* Bit masks for PIXC_CCBIAS */
 
@@ -647,48 +632,28 @@
 /* Bit masks for HOST_CONTROL */
 
 #define                   HOST_EN  0x1        /* Host Enable */
-#define                  nHOST_EN  0x0       
 #define                  HOST_END  0x2        /* Host Endianess */
-#define                 nHOST_END  0x0       
 #define                 DATA_SIZE  0x4        /* Data Size */
-#define                nDATA_SIZE  0x0       
 #define                  HOST_RST  0x8        /* Host Reset */
-#define                 nHOST_RST  0x0       
 #define                  HRDY_OVR  0x20       /* Host Ready Override */
-#define                 nHRDY_OVR  0x0       
 #define                  INT_MODE  0x40       /* Interrupt Mode */
-#define                 nINT_MODE  0x0       
 #define                     BT_EN  0x80       /* Bus Timeout Enable */
-#define                    nBT_EN  0x0       
 #define                       EHW  0x100      /* Enable Host Write */
-#define                      nEHW  0x0       
 #define                       EHR  0x200      /* Enable Host Read */
-#define                      nEHR  0x0       
 #define                       BDR  0x400      /* Burst DMA Requests */
-#define                      nBDR  0x0       
 
 /* Bit masks for HOST_STATUS */
 
 #define                     READY  0x1        /* DMA Ready */
-#define                    nREADY  0x0       
 #define                  FIFOFULL  0x2        /* FIFO Full */
-#define                 nFIFOFULL  0x0       
 #define                 FIFOEMPTY  0x4        /* FIFO Empty */
-#define                nFIFOEMPTY  0x0       
 #define                  COMPLETE  0x8        /* DMA Complete */
-#define                 nCOMPLETE  0x0       
 #define                      HSHK  0x10       /* Host Handshake */
-#define                     nHSHK  0x0       
 #define                   TIMEOUT  0x20       /* Host Timeout */
-#define                  nTIMEOUT  0x0       
 #define                      HIRQ  0x40       /* Host Interrupt Request */
-#define                     nHIRQ  0x0       
 #define                ALLOW_CNFG  0x80       /* Allow New Configuration */
-#define               nALLOW_CNFG  0x0       
 #define                   DMA_DIR  0x100      /* DMA Direction */
-#define                  nDMA_DIR  0x0       
 #define                       BTE  0x200      /* Bus Timeout Enabled */
-#define                      nBTE  0x0       
 
 /* Bit masks for HOST_TIMEOUT */
 
@@ -697,67 +662,42 @@
 /* Bit masks for TIMER_ENABLE1 */
 
 #define                    TIMEN8  0x1        /* Timer 8 Enable */
-#define                   nTIMEN8  0x0       
 #define                    TIMEN9  0x2        /* Timer 9 Enable */
-#define                   nTIMEN9  0x0       
 #define                   TIMEN10  0x4        /* Timer 10 Enable */
-#define                  nTIMEN10  0x0       
 
 /* Bit masks for TIMER_DISABLE1 */
 
 #define                   TIMDIS8  0x1        /* Timer 8 Disable */
-#define                  nTIMDIS8  0x0       
 #define                   TIMDIS9  0x2        /* Timer 9 Disable */
-#define                  nTIMDIS9  0x0       
 #define                  TIMDIS10  0x4        /* Timer 10 Disable */
-#define                 nTIMDIS10  0x0       
 
 /* Bit masks for TIMER_STATUS1 */
 
 #define                    TIMIL8  0x1        /* Timer 8 Interrupt */
-#define                   nTIMIL8  0x0       
 #define                    TIMIL9  0x2        /* Timer 9 Interrupt */
-#define                   nTIMIL9  0x0       
 #define                   TIMIL10  0x4        /* Timer 10 Interrupt */
-#define                  nTIMIL10  0x0       
 #define                 TOVF_ERR8  0x10       /* Timer 8 Counter Overflow */
-#define                nTOVF_ERR8  0x0       
 #define                 TOVF_ERR9  0x20       /* Timer 9 Counter Overflow */
-#define                nTOVF_ERR9  0x0       
 #define                TOVF_ERR10  0x40       /* Timer 10 Counter Overflow */
-#define               nTOVF_ERR10  0x0       
 #define                     TRUN8  0x1000     /* Timer 8 Slave Enable Status */
-#define                    nTRUN8  0x0       
 #define                     TRUN9  0x2000     /* Timer 9 Slave Enable Status */
-#define                    nTRUN9  0x0       
 #define                    TRUN10  0x4000     /* Timer 10 Slave Enable Status */
-#define                   nTRUN10  0x0       
 
 /* Bit masks for EPPI0 are obtained from common base header for EPPIx (EPPI1 and EPPI2) */
 
 /* Bit masks for HMDMAx_CONTROL */
 
 #define                   HMDMAEN  0x1        /* Handshake MDMA Enable */
-#define                  nHMDMAEN  0x0       
 #define                       REP  0x2        /* Handshake MDMA Request Polarity */
-#define                      nREP  0x0       
 #define                       UTE  0x8        /* Urgency Threshold Enable */
-#define                      nUTE  0x0       
 #define                       OIE  0x10       /* Overflow Interrupt Enable */
-#define                      nOIE  0x0       
 #define                      BDIE  0x20       /* Block Done Interrupt Enable */
-#define                     nBDIE  0x0       
 #define                      MBDI  0x40       /* Mask Block Done Interrupt */
-#define                     nMBDI  0x0       
 #define                       DRQ  0x300      /* Handshake MDMA Request Type */
 #define                       RBC  0x1000     /* Force Reload of BCOUNT */
-#define                      nRBC  0x0       
 #define                        PS  0x2000     /* Pin Status */
-#define                       nPS  0x0       
 #define                        OI  0x4000     /* Overflow Interrupt Generated */
-#define                       nOI  0x0       
 #define                       BDI  0x8000     /* Block Done Interrupt Generated */
-#define                      nBDI  0x0       
 
 /* ******************************************* */
 /*     MULTI BIT MACRO ENUMERATIONS            */
diff --git a/include/asm-blackfin/mach-bf548/defBF548.h b/include/asm-blackfin/mach-bf548/defBF548.h
index d9e3062..8d4214e 100644
--- a/include/asm-blackfin/mach-bf548/defBF548.h
+++ b/include/asm-blackfin/mach-bf548/defBF548.h
@@ -899,21 +899,13 @@
 /* Bit masks for PIXC_CTL */
 
 #define                   PIXC_EN  0x1        /* Pixel Compositor Enable */
-#define                  nPIXC_EN  0x0       
 #define                  OVR_A_EN  0x2        /* Overlay A Enable */
-#define                 nOVR_A_EN  0x0       
 #define                  OVR_B_EN  0x4        /* Overlay B Enable */
-#define                 nOVR_B_EN  0x0       
 #define                  IMG_FORM  0x8        /* Image Data Format */
-#define                 nIMG_FORM  0x0       
 #define                  OVR_FORM  0x10       /* Overlay Data Format */
-#define                 nOVR_FORM  0x0       
 #define                  OUT_FORM  0x20       /* Output Data Format */
-#define                 nOUT_FORM  0x0       
 #define                   UDS_MOD  0x40       /* Resampling Mode */
-#define                  nUDS_MOD  0x0       
 #define                     TC_EN  0x80       /* Transparent Color Enable */
-#define                    nTC_EN  0x0       
 #define                  IMG_STAT  0x300      /* Image FIFO Status */
 #define                  OVR_STAT  0xc00      /* Overlay FIFO Status */
 #define                    WM_LVL  0x3000     /* FIFO Watermark Level */
@@ -961,13 +953,9 @@
 /* Bit masks for PIXC_INTRSTAT */
 
 #define                OVR_INT_EN  0x1        /* Interrupt at End of Last Valid Overlay */
-#define               nOVR_INT_EN  0x0       
 #define                FRM_INT_EN  0x2        /* Interrupt at End of Frame */
-#define               nFRM_INT_EN  0x0       
 #define              OVR_INT_STAT  0x4        /* Overlay Interrupt Status */
-#define             nOVR_INT_STAT  0x0       
 #define              FRM_INT_STAT  0x8        /* Frame Interrupt Status */
-#define             nFRM_INT_STAT  0x0       
 
 /* Bit masks for PIXC_RYCON */
 
@@ -975,7 +963,6 @@
 #define                       A12  0xffc00    /* A12 in the Coefficient Matrix */
 #define                       A13  0x3ff00000 /* A13 in the Coefficient Matrix */
 #define                  RY_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nRY_MULT4  0x0       
 
 /* Bit masks for PIXC_GUCON */
 
@@ -983,7 +970,6 @@
 #define                       A22  0xffc00    /* A22 in the Coefficient Matrix */
 #define                       A23  0x3ff00000 /* A23 in the Coefficient Matrix */
 #define                  GU_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nGU_MULT4  0x0       
 
 /* Bit masks for PIXC_BVCON */
 
@@ -991,7 +977,6 @@
 #define                       A32  0xffc00    /* A32 in the Coefficient Matrix */
 #define                       A33  0x3ff00000 /* A33 in the Coefficient Matrix */
 #define                  BV_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nBV_MULT4  0x0       
 
 /* Bit masks for PIXC_CCBIAS */
 
@@ -1008,48 +993,28 @@
 /* Bit masks for HOST_CONTROL */
 
 #define                   HOST_EN  0x1        /* Host Enable */
-#define                  nHOST_EN  0x0       
 #define                  HOST_END  0x2        /* Host Endianess */
-#define                 nHOST_END  0x0       
 #define                 DATA_SIZE  0x4        /* Data Size */
-#define                nDATA_SIZE  0x0       
 #define                  HOST_RST  0x8        /* Host Reset */
-#define                 nHOST_RST  0x0       
 #define                  HRDY_OVR  0x20       /* Host Ready Override */
-#define                 nHRDY_OVR  0x0       
 #define                  INT_MODE  0x40       /* Interrupt Mode */
-#define                 nINT_MODE  0x0       
 #define                     BT_EN  0x80       /* Bus Timeout Enable */
-#define                    nBT_EN  0x0       
 #define                       EHW  0x100      /* Enable Host Write */
-#define                      nEHW  0x0       
 #define                       EHR  0x200      /* Enable Host Read */
-#define                      nEHR  0x0       
 #define                       BDR  0x400      /* Burst DMA Requests */
-#define                      nBDR  0x0       
 
 /* Bit masks for HOST_STATUS */
 
 #define                     READY  0x1        /* DMA Ready */
-#define                    nREADY  0x0       
 #define                  FIFOFULL  0x2        /* FIFO Full */
-#define                 nFIFOFULL  0x0       
 #define                 FIFOEMPTY  0x4        /* FIFO Empty */
-#define                nFIFOEMPTY  0x0       
 #define                  COMPLETE  0x8        /* DMA Complete */
-#define                 nCOMPLETE  0x0       
 #define                      HSHK  0x10       /* Host Handshake */
-#define                     nHSHK  0x0       
 #define                   TIMEOUT  0x20       /* Host Timeout */
-#define                  nTIMEOUT  0x0       
 #define                      HIRQ  0x40       /* Host Interrupt Request */
-#define                     nHIRQ  0x0       
 #define                ALLOW_CNFG  0x80       /* Allow New Configuration */
-#define               nALLOW_CNFG  0x0       
 #define                   DMA_DIR  0x100      /* DMA Direction */
-#define                  nDMA_DIR  0x0       
 #define                       BTE  0x200      /* Bus Timeout Enabled */
-#define                      nBTE  0x0       
 
 /* Bit masks for HOST_TIMEOUT */
 
@@ -1058,7 +1023,6 @@
 /* Bit masks for KPAD_CTL */
 
 #define                   KPAD_EN  0x1        /* Keypad Enable */
-#define                  nKPAD_EN  0x0       
 #define              KPAD_IRQMODE  0x6        /* Key Press Interrupt Enable */
 #define                KPAD_ROWEN  0x1c00     /* Row Enable Width */
 #define                KPAD_COLEN  0xe000     /* Column Enable Width */
@@ -1080,29 +1044,21 @@
 /* Bit masks for KPAD_STAT */
 
 #define                  KPAD_IRQ  0x1        /* Keypad Interrupt Status */
-#define                 nKPAD_IRQ  0x0       
 #define              KPAD_MROWCOL  0x6        /* Multiple Row/Column Keypress Status */
 #define              KPAD_PRESSED  0x8        /* Key press current status */
-#define             nKPAD_PRESSED  0x0       
 
 /* Bit masks for KPAD_SOFTEVAL */
 
 #define           KPAD_SOFTEVAL_E  0x2        /* Software Programmable Force Evaluate */
-#define          nKPAD_SOFTEVAL_E  0x0       
 
 /* Bit masks for SDH_COMMAND */
 
 #define                   CMD_IDX  0x3f       /* Command Index */
 #define                   CMD_RSP  0x40       /* Response */
-#define                  nCMD_RSP  0x0       
 #define                 CMD_L_RSP  0x80       /* Long Response */
-#define                nCMD_L_RSP  0x0       
 #define                 CMD_INT_E  0x100      /* Command Interrupt */
-#define                nCMD_INT_E  0x0       
 #define                CMD_PEND_E  0x200      /* Command Pending */
-#define               nCMD_PEND_E  0x0       
 #define                     CMD_E  0x400      /* Command Enable */
-#define                    nCMD_E  0x0       
 
 /* Bit masks for SDH_PWR_CTL */
 
@@ -1111,21 +1067,15 @@
 #define                       TBD  0x3c       /* TBD */
 #endif
 #define                 SD_CMD_OD  0x40       /* Open Drain Output */
-#define                nSD_CMD_OD  0x0       
 #define                   ROD_CTL  0x80       /* Rod Control */
-#define                  nROD_CTL  0x0       
 
 /* Bit masks for SDH_CLK_CTL */
 
 #define                    CLKDIV  0xff       /* MC_CLK Divisor */
 #define                     CLK_E  0x100      /* MC_CLK Bus Clock Enable */
-#define                    nCLK_E  0x0       
 #define                  PWR_SV_E  0x200      /* Power Save Enable */
-#define                 nPWR_SV_E  0x0       
 #define             CLKDIV_BYPASS  0x400      /* Bypass Divisor */
-#define            nCLKDIV_BYPASS  0x0       
 #define                  WIDE_BUS  0x800      /* Wide Bus Mode Enable */
-#define                 nWIDE_BUS  0x0       
 
 /* Bit masks for SDH_RESP_CMD */
 
@@ -1134,133 +1084,74 @@
 /* Bit masks for SDH_DATA_CTL */
 
 #define                     DTX_E  0x1        /* Data Transfer Enable */
-#define                    nDTX_E  0x0       
 #define                   DTX_DIR  0x2        /* Data Transfer Direction */
-#define                  nDTX_DIR  0x0       
 #define                  DTX_MODE  0x4        /* Data Transfer Mode */
-#define                 nDTX_MODE  0x0       
 #define                 DTX_DMA_E  0x8        /* Data Transfer DMA Enable */
-#define                nDTX_DMA_E  0x0       
 #define              DTX_BLK_LGTH  0xf0       /* Data Transfer Block Length */
 
 /* Bit masks for SDH_STATUS */
 
 #define              CMD_CRC_FAIL  0x1        /* CMD CRC Fail */
-#define             nCMD_CRC_FAIL  0x0       
 #define              DAT_CRC_FAIL  0x2        /* Data CRC Fail */
-#define             nDAT_CRC_FAIL  0x0       
 #define               CMD_TIMEOUT  0x4        /* CMD Time Out */
-#define              nCMD_TIMEOUT  0x0       
 #define               DAT_TIMEOUT  0x8        /* Data Time Out */
-#define              nDAT_TIMEOUT  0x0       
 #define               TX_UNDERRUN  0x10       /* Transmit Underrun */
-#define              nTX_UNDERRUN  0x0       
 #define                RX_OVERRUN  0x20       /* Receive Overrun */
-#define               nRX_OVERRUN  0x0       
 #define              CMD_RESP_END  0x40       /* CMD Response End */
-#define             nCMD_RESP_END  0x0       
 #define                  CMD_SENT  0x80       /* CMD Sent */
-#define                 nCMD_SENT  0x0       
 #define                   DAT_END  0x100      /* Data End */
-#define                  nDAT_END  0x0       
 #define             START_BIT_ERR  0x200      /* Start Bit Error */
-#define            nSTART_BIT_ERR  0x0       
 #define               DAT_BLK_END  0x400      /* Data Block End */
-#define              nDAT_BLK_END  0x0       
 #define                   CMD_ACT  0x800      /* CMD Active */
-#define                  nCMD_ACT  0x0       
 #define                    TX_ACT  0x1000     /* Transmit Active */
-#define                   nTX_ACT  0x0       
 #define                    RX_ACT  0x2000     /* Receive Active */
-#define                   nRX_ACT  0x0       
 #define              TX_FIFO_STAT  0x4000     /* Transmit FIFO Status */
-#define             nTX_FIFO_STAT  0x0       
 #define              RX_FIFO_STAT  0x8000     /* Receive FIFO Status */
-#define             nRX_FIFO_STAT  0x0       
 #define              TX_FIFO_FULL  0x10000    /* Transmit FIFO Full */
-#define             nTX_FIFO_FULL  0x0       
 #define              RX_FIFO_FULL  0x20000    /* Receive FIFO Full */
-#define             nRX_FIFO_FULL  0x0       
 #define              TX_FIFO_ZERO  0x40000    /* Transmit FIFO Empty */
-#define             nTX_FIFO_ZERO  0x0       
 #define               RX_DAT_ZERO  0x80000    /* Receive FIFO Empty */
-#define              nRX_DAT_ZERO  0x0       
 #define                TX_DAT_RDY  0x100000   /* Transmit Data Available */
-#define               nTX_DAT_RDY  0x0       
 #define               RX_FIFO_RDY  0x200000   /* Receive Data Available */
-#define              nRX_FIFO_RDY  0x0       
 
 /* Bit masks for SDH_STATUS_CLR */
 
 #define         CMD_CRC_FAIL_STAT  0x1        /* CMD CRC Fail Status */
-#define        nCMD_CRC_FAIL_STAT  0x0       
 #define         DAT_CRC_FAIL_STAT  0x2        /* Data CRC Fail Status */
-#define        nDAT_CRC_FAIL_STAT  0x0       
 #define          CMD_TIMEOUT_STAT  0x4        /* CMD Time Out Status */
-#define         nCMD_TIMEOUT_STAT  0x0       
 #define          DAT_TIMEOUT_STAT  0x8        /* Data Time Out status */
-#define         nDAT_TIMEOUT_STAT  0x0       
 #define          TX_UNDERRUN_STAT  0x10       /* Transmit Underrun Status */
-#define         nTX_UNDERRUN_STAT  0x0       
 #define           RX_OVERRUN_STAT  0x20       /* Receive Overrun Status */
-#define          nRX_OVERRUN_STAT  0x0       
 #define         CMD_RESP_END_STAT  0x40       /* CMD Response End Status */
-#define        nCMD_RESP_END_STAT  0x0       
 #define             CMD_SENT_STAT  0x80       /* CMD Sent Status */
-#define            nCMD_SENT_STAT  0x0       
 #define              DAT_END_STAT  0x100      /* Data End Status */
-#define             nDAT_END_STAT  0x0       
 #define        START_BIT_ERR_STAT  0x200      /* Start Bit Error Status */
-#define       nSTART_BIT_ERR_STAT  0x0       
 #define          DAT_BLK_END_STAT  0x400      /* Data Block End Status */
-#define         nDAT_BLK_END_STAT  0x0       
 
 /* Bit masks for SDH_MASK0 */
 
 #define         CMD_CRC_FAIL_MASK  0x1        /* CMD CRC Fail Mask */
-#define        nCMD_CRC_FAIL_MASK  0x0       
 #define         DAT_CRC_FAIL_MASK  0x2        /* Data CRC Fail Mask */
-#define        nDAT_CRC_FAIL_MASK  0x0       
 #define          CMD_TIMEOUT_MASK  0x4        /* CMD Time Out Mask */
-#define         nCMD_TIMEOUT_MASK  0x0       
 #define          DAT_TIMEOUT_MASK  0x8        /* Data Time Out Mask */
-#define         nDAT_TIMEOUT_MASK  0x0       
 #define          TX_UNDERRUN_MASK  0x10       /* Transmit Underrun Mask */
-#define         nTX_UNDERRUN_MASK  0x0       
 #define           RX_OVERRUN_MASK  0x20       /* Receive Overrun Mask */
-#define          nRX_OVERRUN_MASK  0x0       
 #define         CMD_RESP_END_MASK  0x40       /* CMD Response End Mask */
-#define        nCMD_RESP_END_MASK  0x0       
 #define             CMD_SENT_MASK  0x80       /* CMD Sent Mask */
-#define            nCMD_SENT_MASK  0x0       
 #define              DAT_END_MASK  0x100      /* Data End Mask */
-#define             nDAT_END_MASK  0x0       
 #define        START_BIT_ERR_MASK  0x200      /* Start Bit Error Mask */
-#define       nSTART_BIT_ERR_MASK  0x0       
 #define          DAT_BLK_END_MASK  0x400      /* Data Block End Mask */
-#define         nDAT_BLK_END_MASK  0x0       
 #define              CMD_ACT_MASK  0x800      /* CMD Active Mask */
-#define             nCMD_ACT_MASK  0x0       
 #define               TX_ACT_MASK  0x1000     /* Transmit Active Mask */
-#define              nTX_ACT_MASK  0x0       
 #define               RX_ACT_MASK  0x2000     /* Receive Active Mask */
-#define              nRX_ACT_MASK  0x0       
 #define         TX_FIFO_STAT_MASK  0x4000     /* Transmit FIFO Status Mask */
-#define        nTX_FIFO_STAT_MASK  0x0       
 #define         RX_FIFO_STAT_MASK  0x8000     /* Receive FIFO Status Mask */
-#define        nRX_FIFO_STAT_MASK  0x0       
 #define         TX_FIFO_FULL_MASK  0x10000    /* Transmit FIFO Full Mask */
-#define        nTX_FIFO_FULL_MASK  0x0       
 #define         RX_FIFO_FULL_MASK  0x20000    /* Receive FIFO Full Mask */
-#define        nRX_FIFO_FULL_MASK  0x0       
 #define         TX_FIFO_ZERO_MASK  0x40000    /* Transmit FIFO Empty Mask */
-#define        nTX_FIFO_ZERO_MASK  0x0       
 #define          RX_DAT_ZERO_MASK  0x80000    /* Receive FIFO Empty Mask */
-#define         nRX_DAT_ZERO_MASK  0x0       
 #define           TX_DAT_RDY_MASK  0x100000   /* Transmit Data Available Mask */
-#define          nTX_DAT_RDY_MASK  0x0       
 #define          RX_FIFO_RDY_MASK  0x200000   /* Receive Data Available Mask */
-#define         nRX_FIFO_RDY_MASK  0x0       
 
 /* Bit masks for SDH_FIFO_CNT */
 
@@ -1269,73 +1160,47 @@
 /* Bit masks for SDH_E_STATUS */
 
 #define              SDIO_INT_DET  0x2        /* SDIO Int Detected */
-#define             nSDIO_INT_DET  0x0       
 #define               SD_CARD_DET  0x10       /* SD Card Detect */
-#define              nSD_CARD_DET  0x0       
 
 /* Bit masks for SDH_E_MASK */
 
 #define                  SDIO_MSK  0x2        /* Mask SDIO Int Detected */
-#define                 nSDIO_MSK  0x0       
 #define                   SCD_MSK  0x40       /* Mask Card Detect */
-#define                  nSCD_MSK  0x0       
 
 /* Bit masks for SDH_CFG */
 
 #define                   CLKS_EN  0x1        /* Clocks Enable */
-#define                  nCLKS_EN  0x0       
 #define                      SD4E  0x4        /* SDIO 4-Bit Enable */
-#define                     nSD4E  0x0       
 #define                       MWE  0x8        /* Moving Window Enable */
-#define                      nMWE  0x0       
 #define                    SD_RST  0x10       /* SDMMC Reset */
-#define                   nSD_RST  0x0       
 #define                 PUP_SDDAT  0x20       /* Pull-up SD_DAT */
-#define                nPUP_SDDAT  0x0       
 #define                PUP_SDDAT3  0x40       /* Pull-up SD_DAT3 */
-#define               nPUP_SDDAT3  0x0       
 #define                 PD_SDDAT3  0x80       /* Pull-down SD_DAT3 */
-#define                nPD_SDDAT3  0x0       
 
 /* Bit masks for SDH_RD_WAIT_EN */
 
 #define                       RWR  0x1        /* Read Wait Request */
-#define                      nRWR  0x0       
 
 /* Bit masks for ATAPI_CONTROL */
 
 #define                 PIO_START  0x1        /* Start PIO/Reg Op */
-#define                nPIO_START  0x0       
 #define               MULTI_START  0x2        /* Start Multi-DMA Op */
-#define              nMULTI_START  0x0       
 #define               ULTRA_START  0x4        /* Start Ultra-DMA Op */
-#define              nULTRA_START  0x0       
 #define                  XFER_DIR  0x8        /* Transfer Direction */
-#define                 nXFER_DIR  0x0       
 #define                  IORDY_EN  0x10       /* IORDY Enable */
-#define                 nIORDY_EN  0x0       
 #define                FIFO_FLUSH  0x20       /* Flush FIFOs */
-#define               nFIFO_FLUSH  0x0       
 #define                  SOFT_RST  0x40       /* Soft Reset */
-#define                 nSOFT_RST  0x0       
 #define                   DEV_RST  0x80       /* Device Reset */
-#define                  nDEV_RST  0x0       
 #define                TFRCNT_RST  0x100      /* Trans Count Reset */
-#define               nTFRCNT_RST  0x0       
 #define               END_ON_TERM  0x200      /* End/Terminate Select */
-#define              nEND_ON_TERM  0x0       
 #define               PIO_USE_DMA  0x400      /* PIO-DMA Enable */
-#define              nPIO_USE_DMA  0x0       
 #define          UDMAIN_FIFO_THRS  0xf000     /* Ultra DMA-IN FIFO Threshold */
 
 /* Bit masks for ATAPI_STATUS */
 
 #define               PIO_XFER_ON  0x1        /* PIO transfer in progress */
-#define              nPIO_XFER_ON  0x0       
 #define             MULTI_XFER_ON  0x2        /* Multi-word DMA transfer in progress */
-#define            nMULTI_XFER_ON  0x0       
 #define             ULTRA_XFER_ON  0x4        /* Ultra DMA transfer in progress */
-#define            nULTRA_XFER_ON  0x0       
 #define               ULTRA_IN_FL  0xf0       /* Ultra DMA Input FIFO Level */
 
 /* Bit masks for ATAPI_DEV_ADDR */
@@ -1345,66 +1210,39 @@
 /* Bit masks for ATAPI_INT_MASK */
 
 #define        ATAPI_DEV_INT_MASK  0x1        /* Device interrupt mask */
-#define       nATAPI_DEV_INT_MASK  0x0       
 #define             PIO_DONE_MASK  0x2        /* PIO transfer done interrupt mask */
-#define            nPIO_DONE_MASK  0x0       
 #define           MULTI_DONE_MASK  0x4        /* Multi-DMA transfer done interrupt mask */
-#define          nMULTI_DONE_MASK  0x0       
 #define          UDMAIN_DONE_MASK  0x8        /* Ultra-DMA in transfer done interrupt mask */
-#define         nUDMAIN_DONE_MASK  0x0       
 #define         UDMAOUT_DONE_MASK  0x10       /* Ultra-DMA out transfer done interrupt mask */
-#define        nUDMAOUT_DONE_MASK  0x0       
 #define       HOST_TERM_XFER_MASK  0x20       /* Host terminate current transfer interrupt mask */
-#define      nHOST_TERM_XFER_MASK  0x0       
 #define           MULTI_TERM_MASK  0x40       /* Device terminate Multi-DMA transfer interrupt mask */
-#define          nMULTI_TERM_MASK  0x0       
 #define          UDMAIN_TERM_MASK  0x80       /* Device terminate Ultra-DMA-in transfer interrupt mask */
-#define         nUDMAIN_TERM_MASK  0x0       
 #define         UDMAOUT_TERM_MASK  0x100      /* Device terminate Ultra-DMA-out transfer interrupt mask */
-#define        nUDMAOUT_TERM_MASK  0x0       
 
 /* Bit masks for ATAPI_INT_STATUS */
 
 #define             ATAPI_DEV_INT  0x1        /* Device interrupt status */
-#define            nATAPI_DEV_INT  0x0       
 #define              PIO_DONE_INT  0x2        /* PIO transfer done interrupt status */
-#define             nPIO_DONE_INT  0x0       
 #define            MULTI_DONE_INT  0x4        /* Multi-DMA transfer done interrupt status */
-#define           nMULTI_DONE_INT  0x0       
 #define           UDMAIN_DONE_INT  0x8        /* Ultra-DMA in transfer done interrupt status */
-#define          nUDMAIN_DONE_INT  0x0       
 #define          UDMAOUT_DONE_INT  0x10       /* Ultra-DMA out transfer done interrupt status */
-#define         nUDMAOUT_DONE_INT  0x0       
 #define        HOST_TERM_XFER_INT  0x20       /* Host terminate current transfer interrupt status */
-#define       nHOST_TERM_XFER_INT  0x0       
 #define            MULTI_TERM_INT  0x40       /* Device terminate Multi-DMA transfer interrupt status */
-#define           nMULTI_TERM_INT  0x0       
 #define           UDMAIN_TERM_INT  0x80       /* Device terminate Ultra-DMA-in transfer interrupt status */
-#define          nUDMAIN_TERM_INT  0x0       
 #define          UDMAOUT_TERM_INT  0x100      /* Device terminate Ultra-DMA-out transfer interrupt status */
-#define         nUDMAOUT_TERM_INT  0x0       
 
 /* Bit masks for ATAPI_LINE_STATUS */
 
 #define                ATAPI_INTR  0x1        /* Device interrupt to host line status */
-#define               nATAPI_INTR  0x0       
 #define                ATAPI_DASP  0x2        /* Device dasp to host line status */
-#define               nATAPI_DASP  0x0       
 #define                ATAPI_CS0N  0x4        /* ATAPI chip select 0 line status */
-#define               nATAPI_CS0N  0x0       
 #define                ATAPI_CS1N  0x8        /* ATAPI chip select 1 line status */
-#define               nATAPI_CS1N  0x0       
 #define                ATAPI_ADDR  0x70       /* ATAPI address line status */
 #define              ATAPI_DMAREQ  0x80       /* ATAPI DMA request line status */
-#define             nATAPI_DMAREQ  0x0       
 #define             ATAPI_DMAACKN  0x100      /* ATAPI DMA acknowledge line status */
-#define            nATAPI_DMAACKN  0x0       
 #define               ATAPI_DIOWN  0x200      /* ATAPI write line status */
-#define              nATAPI_DIOWN  0x0       
 #define               ATAPI_DIORN  0x400      /* ATAPI read line status */
-#define              nATAPI_DIORN  0x0       
 #define               ATAPI_IORDY  0x800      /* ATAPI IORDY line status */
-#define              nATAPI_IORDY  0x0       
 
 /* Bit masks for ATAPI_SM_STATE */
 
@@ -1416,7 +1254,6 @@
 /* Bit masks for ATAPI_TERMINATE */
 
 #define           ATAPI_HOST_TERM  0x1        /* Host terminationation */
-#define          nATAPI_HOST_TERM  0x0       
 
 /* Bit masks for ATAPI_REG_TIM_0 */
 
@@ -1471,41 +1308,26 @@
 /* Bit masks for TIMER_ENABLE1 */
 
 #define                    TIMEN8  0x1        /* Timer 8 Enable */
-#define                   nTIMEN8  0x0       
 #define                    TIMEN9  0x2        /* Timer 9 Enable */
-#define                   nTIMEN9  0x0       
 #define                   TIMEN10  0x4        /* Timer 10 Enable */
-#define                  nTIMEN10  0x0       
 
 /* Bit masks for TIMER_DISABLE1 */
 
 #define                   TIMDIS8  0x1        /* Timer 8 Disable */
-#define                  nTIMDIS8  0x0       
 #define                   TIMDIS9  0x2        /* Timer 9 Disable */
-#define                  nTIMDIS9  0x0       
 #define                  TIMDIS10  0x4        /* Timer 10 Disable */
-#define                 nTIMDIS10  0x0       
 
 /* Bit masks for TIMER_STATUS1 */
 
 #define                    TIMIL8  0x1        /* Timer 8 Interrupt */
-#define                   nTIMIL8  0x0       
 #define                    TIMIL9  0x2        /* Timer 9 Interrupt */
-#define                   nTIMIL9  0x0       
 #define                   TIMIL10  0x4        /* Timer 10 Interrupt */
-#define                  nTIMIL10  0x0       
 #define                 TOVF_ERR8  0x10       /* Timer 8 Counter Overflow */
-#define                nTOVF_ERR8  0x0       
 #define                 TOVF_ERR9  0x20       /* Timer 9 Counter Overflow */
-#define                nTOVF_ERR9  0x0       
 #define                TOVF_ERR10  0x40       /* Timer 10 Counter Overflow */
-#define               nTOVF_ERR10  0x0       
 #define                     TRUN8  0x1000     /* Timer 8 Slave Enable Status */
-#define                    nTRUN8  0x0       
 #define                     TRUN9  0x2000     /* Timer 9 Slave Enable Status */
-#define                    nTRUN9  0x0       
 #define                    TRUN10  0x4000     /* Timer 10 Slave Enable Status */
-#define                   nTRUN10  0x0       
 
 /* Bit masks for EPPI0 are obtained from common base header for EPPIx (EPPI1 and EPPI2) */
 
@@ -1516,131 +1338,77 @@
 /* Bit masks for USB_POWER */
 
 #define           ENABLE_SUSPENDM  0x1        /* enable SuspendM output */
-#define          nENABLE_SUSPENDM  0x0       
 #define              SUSPEND_MODE  0x2        /* Suspend Mode indicator */
-#define             nSUSPEND_MODE  0x0       
 #define               RESUME_MODE  0x4        /* DMA Mode */
-#define              nRESUME_MODE  0x0       
 #define                     RESET  0x8        /* Reset indicator */
-#define                    nRESET  0x0       
 #define                   HS_MODE  0x10       /* High Speed mode indicator */
-#define                  nHS_MODE  0x0       
 #define                 HS_ENABLE  0x20       /* high Speed Enable */
-#define                nHS_ENABLE  0x0       
 #define                 SOFT_CONN  0x40       /* Soft connect */
-#define                nSOFT_CONN  0x0       
 #define                ISO_UPDATE  0x80       /* Isochronous update */
-#define               nISO_UPDATE  0x0       
 
 /* Bit masks for USB_INTRTX */
 
 #define                    EP0_TX  0x1        /* Tx Endpoint 0 interrupt */
-#define                   nEP0_TX  0x0       
 #define                    EP1_TX  0x2        /* Tx Endpoint 1 interrupt */
-#define                   nEP1_TX  0x0       
 #define                    EP2_TX  0x4        /* Tx Endpoint 2 interrupt */
-#define                   nEP2_TX  0x0       
 #define                    EP3_TX  0x8        /* Tx Endpoint 3 interrupt */
-#define                   nEP3_TX  0x0       
 #define                    EP4_TX  0x10       /* Tx Endpoint 4 interrupt */
-#define                   nEP4_TX  0x0       
 #define                    EP5_TX  0x20       /* Tx Endpoint 5 interrupt */
-#define                   nEP5_TX  0x0       
 #define                    EP6_TX  0x40       /* Tx Endpoint 6 interrupt */
-#define                   nEP6_TX  0x0       
 #define                    EP7_TX  0x80       /* Tx Endpoint 7 interrupt */
-#define                   nEP7_TX  0x0       
 
 /* Bit masks for USB_INTRRX */
 
 #define                    EP1_RX  0x2        /* Rx Endpoint 1 interrupt */
-#define                   nEP1_RX  0x0       
 #define                    EP2_RX  0x4        /* Rx Endpoint 2 interrupt */
-#define                   nEP2_RX  0x0       
 #define                    EP3_RX  0x8        /* Rx Endpoint 3 interrupt */
-#define                   nEP3_RX  0x0       
 #define                    EP4_RX  0x10       /* Rx Endpoint 4 interrupt */
-#define                   nEP4_RX  0x0       
 #define                    EP5_RX  0x20       /* Rx Endpoint 5 interrupt */
-#define                   nEP5_RX  0x0       
 #define                    EP6_RX  0x40       /* Rx Endpoint 6 interrupt */
-#define                   nEP6_RX  0x0       
 #define                    EP7_RX  0x80       /* Rx Endpoint 7 interrupt */
-#define                   nEP7_RX  0x0       
 
 /* Bit masks for USB_INTRTXE */
 
 #define                  EP0_TX_E  0x1        /* Endpoint 0 interrupt Enable */
-#define                 nEP0_TX_E  0x0       
 #define                  EP1_TX_E  0x2        /* Tx Endpoint 1 interrupt  Enable */
-#define                 nEP1_TX_E  0x0       
 #define                  EP2_TX_E  0x4        /* Tx Endpoint 2 interrupt  Enable */
-#define                 nEP2_TX_E  0x0       
 #define                  EP3_TX_E  0x8        /* Tx Endpoint 3 interrupt  Enable */
-#define                 nEP3_TX_E  0x0       
 #define                  EP4_TX_E  0x10       /* Tx Endpoint 4 interrupt  Enable */
-#define                 nEP4_TX_E  0x0       
 #define                  EP5_TX_E  0x20       /* Tx Endpoint 5 interrupt  Enable */
-#define                 nEP5_TX_E  0x0       
 #define                  EP6_TX_E  0x40       /* Tx Endpoint 6 interrupt  Enable */
-#define                 nEP6_TX_E  0x0       
 #define                  EP7_TX_E  0x80       /* Tx Endpoint 7 interrupt  Enable */
-#define                 nEP7_TX_E  0x0       
 
 /* Bit masks for USB_INTRRXE */
 
 #define                  EP1_RX_E  0x2        /* Rx Endpoint 1 interrupt  Enable */
-#define                 nEP1_RX_E  0x0       
 #define                  EP2_RX_E  0x4        /* Rx Endpoint 2 interrupt  Enable */
-#define                 nEP2_RX_E  0x0       
 #define                  EP3_RX_E  0x8        /* Rx Endpoint 3 interrupt  Enable */
-#define                 nEP3_RX_E  0x0       
 #define                  EP4_RX_E  0x10       /* Rx Endpoint 4 interrupt  Enable */
-#define                 nEP4_RX_E  0x0       
 #define                  EP5_RX_E  0x20       /* Rx Endpoint 5 interrupt  Enable */
-#define                 nEP5_RX_E  0x0       
 #define                  EP6_RX_E  0x40       /* Rx Endpoint 6 interrupt  Enable */
-#define                 nEP6_RX_E  0x0       
 #define                  EP7_RX_E  0x80       /* Rx Endpoint 7 interrupt  Enable */
-#define                 nEP7_RX_E  0x0       
 
 /* Bit masks for USB_INTRUSB */
 
 #define                 SUSPEND_B  0x1        /* Suspend indicator */
-#define                nSUSPEND_B  0x0       
 #define                  RESUME_B  0x2        /* Resume indicator */
-#define                 nRESUME_B  0x0       
 #define          RESET_OR_BABLE_B  0x4        /* Reset/babble indicator */
-#define         nRESET_OR_BABLE_B  0x0       
 #define                     SOF_B  0x8        /* Start of frame */
-#define                    nSOF_B  0x0       
 #define                    CONN_B  0x10       /* Connection indicator */
-#define                   nCONN_B  0x0       
 #define                  DISCON_B  0x20       /* Disconnect indicator */
-#define                 nDISCON_B  0x0       
 #define             SESSION_REQ_B  0x40       /* Session Request */
-#define            nSESSION_REQ_B  0x0       
 #define              VBUS_ERROR_B  0x80       /* Vbus threshold indicator */
-#define             nVBUS_ERROR_B  0x0       
 
 /* Bit masks for USB_INTRUSBE */
 
 #define                SUSPEND_BE  0x1        /* Suspend indicator int enable */
-#define               nSUSPEND_BE  0x0       
 #define                 RESUME_BE  0x2        /* Resume indicator int enable */
-#define                nRESUME_BE  0x0       
 #define         RESET_OR_BABLE_BE  0x4        /* Reset/babble indicator int enable */
-#define        nRESET_OR_BABLE_BE  0x0       
 #define                    SOF_BE  0x8        /* Start of frame int enable */
-#define                   nSOF_BE  0x0       
 #define                   CONN_BE  0x10       /* Connection indicator int enable */
-#define                  nCONN_BE  0x0       
 #define                 DISCON_BE  0x20       /* Disconnect indicator int enable */
-#define                nDISCON_BE  0x0       
 #define            SESSION_REQ_BE  0x40       /* Session Request int enable */
-#define           nSESSION_REQ_BE  0x0       
 #define             VBUS_ERROR_BE  0x80       /* Vbus threshold indicator int enable */
-#define            nVBUS_ERROR_BE  0x0       
 
 /* Bit masks for USB_FRAME */
 
@@ -1653,117 +1421,67 @@
 /* Bit masks for USB_GLOBAL_CTL */
 
 #define                GLOBAL_ENA  0x1        /* enables USB module */
-#define               nGLOBAL_ENA  0x0       
 #define                EP1_TX_ENA  0x2        /* Transmit endpoint 1 enable */
-#define               nEP1_TX_ENA  0x0       
 #define                EP2_TX_ENA  0x4        /* Transmit endpoint 2 enable */
-#define               nEP2_TX_ENA  0x0       
 #define                EP3_TX_ENA  0x8        /* Transmit endpoint 3 enable */
-#define               nEP3_TX_ENA  0x0       
 #define                EP4_TX_ENA  0x10       /* Transmit endpoint 4 enable */
-#define               nEP4_TX_ENA  0x0       
 #define                EP5_TX_ENA  0x20       /* Transmit endpoint 5 enable */
-#define               nEP5_TX_ENA  0x0       
 #define                EP6_TX_ENA  0x40       /* Transmit endpoint 6 enable */
-#define               nEP6_TX_ENA  0x0       
 #define                EP7_TX_ENA  0x80       /* Transmit endpoint 7 enable */
-#define               nEP7_TX_ENA  0x0       
 #define                EP1_RX_ENA  0x100      /* Receive endpoint 1 enable */
-#define               nEP1_RX_ENA  0x0       
 #define                EP2_RX_ENA  0x200      /* Receive endpoint 2 enable */
-#define               nEP2_RX_ENA  0x0       
 #define                EP3_RX_ENA  0x400      /* Receive endpoint 3 enable */
-#define               nEP3_RX_ENA  0x0       
 #define                EP4_RX_ENA  0x800      /* Receive endpoint 4 enable */
-#define               nEP4_RX_ENA  0x0       
 #define                EP5_RX_ENA  0x1000     /* Receive endpoint 5 enable */
-#define               nEP5_RX_ENA  0x0       
 #define                EP6_RX_ENA  0x2000     /* Receive endpoint 6 enable */
-#define               nEP6_RX_ENA  0x0       
 #define                EP7_RX_ENA  0x4000     /* Receive endpoint 7 enable */
-#define               nEP7_RX_ENA  0x0       
 
 /* Bit masks for USB_OTG_DEV_CTL */
 
 #define                   SESSION  0x1        /* session indicator */
-#define                  nSESSION  0x0       
 #define                  HOST_REQ  0x2        /* Host negotiation request */
-#define                 nHOST_REQ  0x0       
 #define                 HOST_MODE  0x4        /* indicates USBDRC is a host */
-#define                nHOST_MODE  0x0       
 #define                     VBUS0  0x8        /* Vbus level indicator[0] */
-#define                    nVBUS0  0x0       
 #define                     VBUS1  0x10       /* Vbus level indicator[1] */
-#define                    nVBUS1  0x0       
 #define                     LSDEV  0x20       /* Low-speed indicator */
-#define                    nLSDEV  0x0       
 #define                     FSDEV  0x40       /* Full or High-speed indicator */
-#define                    nFSDEV  0x0       
 #define                  B_DEVICE  0x80       /* A' or 'B' device indicator */
-#define                 nB_DEVICE  0x0       
 
 /* Bit masks for USB_OTG_VBUS_IRQ */
 
 #define             DRIVE_VBUS_ON  0x1        /* indicator to drive VBUS control circuit */
-#define            nDRIVE_VBUS_ON  0x0       
 #define            DRIVE_VBUS_OFF  0x2        /* indicator to shut off charge pump */
-#define           nDRIVE_VBUS_OFF  0x0       
 #define           CHRG_VBUS_START  0x4        /* indicator for external circuit to start charging VBUS */
-#define          nCHRG_VBUS_START  0x0       
 #define             CHRG_VBUS_END  0x8        /* indicator for external circuit to end charging VBUS */
-#define            nCHRG_VBUS_END  0x0       
 #define        DISCHRG_VBUS_START  0x10       /* indicator to start discharging VBUS */
-#define       nDISCHRG_VBUS_START  0x0       
 #define          DISCHRG_VBUS_END  0x20       /* indicator to stop discharging VBUS */
-#define         nDISCHRG_VBUS_END  0x0       
 
 /* Bit masks for USB_OTG_VBUS_MASK */
 
 #define         DRIVE_VBUS_ON_ENA  0x1        /* enable DRIVE_VBUS_ON interrupt */
-#define        nDRIVE_VBUS_ON_ENA  0x0       
 #define        DRIVE_VBUS_OFF_ENA  0x2        /* enable DRIVE_VBUS_OFF interrupt */
-#define       nDRIVE_VBUS_OFF_ENA  0x0       
 #define       CHRG_VBUS_START_ENA  0x4        /* enable CHRG_VBUS_START interrupt */
-#define      nCHRG_VBUS_START_ENA  0x0       
 #define         CHRG_VBUS_END_ENA  0x8        /* enable CHRG_VBUS_END interrupt */
-#define        nCHRG_VBUS_END_ENA  0x0       
 #define    DISCHRG_VBUS_START_ENA  0x10       /* enable DISCHRG_VBUS_START interrupt */
-#define   nDISCHRG_VBUS_START_ENA  0x0       
 #define      DISCHRG_VBUS_END_ENA  0x20       /* enable DISCHRG_VBUS_END interrupt */
-#define     nDISCHRG_VBUS_END_ENA  0x0       
 
 /* Bit masks for USB_CSR0 */
 
 #define                  RXPKTRDY  0x1        /* data packet receive indicator */
-#define                 nRXPKTRDY  0x0       
 #define                  TXPKTRDY  0x2        /* data packet in FIFO indicator */
-#define                 nTXPKTRDY  0x0       
 #define                STALL_SENT  0x4        /* STALL handshake sent */
-#define               nSTALL_SENT  0x0       
 #define                   DATAEND  0x8        /* Data end indicator */
-#define                  nDATAEND  0x0       
 #define                  SETUPEND  0x10       /* Setup end */
-#define                 nSETUPEND  0x0       
 #define                 SENDSTALL  0x20       /* Send STALL handshake */
-#define                nSENDSTALL  0x0       
 #define         SERVICED_RXPKTRDY  0x40       /* used to clear the RxPktRdy bit */
-#define        nSERVICED_RXPKTRDY  0x0       
 #define         SERVICED_SETUPEND  0x80       /* used to clear the SetupEnd bit */
-#define        nSERVICED_SETUPEND  0x0       
 #define                 FLUSHFIFO  0x100      /* flush endpoint FIFO */
-#define                nFLUSHFIFO  0x0       
 #define          STALL_RECEIVED_H  0x4        /* STALL handshake received host mode */
-#define         nSTALL_RECEIVED_H  0x0       
 #define                SETUPPKT_H  0x8        /* send Setup token host mode */
-#define               nSETUPPKT_H  0x0       
 #define                   ERROR_H  0x10       /* timeout error indicator host mode */
-#define                  nERROR_H  0x0       
 #define                  REQPKT_H  0x20       /* Request an IN transaction host mode */
-#define                 nREQPKT_H  0x0       
 #define               STATUSPKT_H  0x40       /* Status stage transaction host mode */
-#define              nSTATUSPKT_H  0x0       
 #define             NAK_TIMEOUT_H  0x80       /* EP0 halted after a NAK host mode */
-#define            nNAK_TIMEOUT_H  0x0       
 
 /* Bit masks for USB_COUNT0 */
 
@@ -1784,37 +1502,21 @@
 /* Bit masks for USB_TXCSR */
 
 #define                TXPKTRDY_T  0x1        /* data packet in FIFO indicator */
-#define               nTXPKTRDY_T  0x0       
 #define          FIFO_NOT_EMPTY_T  0x2        /* FIFO not empty */
-#define         nFIFO_NOT_EMPTY_T  0x0       
 #define                UNDERRUN_T  0x4        /* TxPktRdy not set  for an IN token */
-#define               nUNDERRUN_T  0x0       
 #define               FLUSHFIFO_T  0x8        /* flush endpoint FIFO */
-#define              nFLUSHFIFO_T  0x0       
 #define              STALL_SEND_T  0x10       /* issue a Stall handshake */
-#define             nSTALL_SEND_T  0x0       
 #define              STALL_SENT_T  0x20       /* Stall handshake transmitted */
-#define             nSTALL_SENT_T  0x0       
 #define        CLEAR_DATATOGGLE_T  0x40       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_T  0x0       
 #define                INCOMPTX_T  0x80       /* indicates that a large packet is split */
-#define               nINCOMPTX_T  0x0       
 #define              DMAREQMODE_T  0x400      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_T  0x0       
 #define        FORCE_DATATOGGLE_T  0x800      /* Force data toggle */
-#define       nFORCE_DATATOGGLE_T  0x0       
 #define              DMAREQ_ENA_T  0x1000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_T  0x0       
 #define                     ISO_T  0x4000     /* enable Isochronous transfers */
-#define                    nISO_T  0x0       
 #define                 AUTOSET_T  0x8000     /* allows TxPktRdy to be set automatically */
-#define                nAUTOSET_T  0x0       
 #define                  ERROR_TH  0x4        /* error condition host mode */
-#define                 nERROR_TH  0x0       
 #define         STALL_RECEIVED_TH  0x20       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_TH  0x0       
 #define            NAK_TIMEOUT_TH  0x80       /* NAK timeout host mode */
-#define           nNAK_TIMEOUT_TH  0x0       
 
 /* Bit masks for USB_TXCOUNT */
 
@@ -1823,45 +1525,25 @@
 /* Bit masks for USB_RXCSR */
 
 #define                RXPKTRDY_R  0x1        /* data packet in FIFO indicator */
-#define               nRXPKTRDY_R  0x0       
 #define               FIFO_FULL_R  0x2        /* FIFO not empty */
-#define              nFIFO_FULL_R  0x0       
 #define                 OVERRUN_R  0x4        /* TxPktRdy not set  for an IN token */
-#define                nOVERRUN_R  0x0       
 #define               DATAERROR_R  0x8        /* Out packet cannot be loaded into Rx  FIFO */
-#define              nDATAERROR_R  0x0       
 #define               FLUSHFIFO_R  0x10       /* flush endpoint FIFO */
-#define              nFLUSHFIFO_R  0x0       
 #define              STALL_SEND_R  0x20       /* issue a Stall handshake */
-#define             nSTALL_SEND_R  0x0       
 #define              STALL_SENT_R  0x40       /* Stall handshake transmitted */
-#define             nSTALL_SENT_R  0x0       
 #define        CLEAR_DATATOGGLE_R  0x80       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_R  0x0       
 #define                INCOMPRX_R  0x100      /* indicates that a large packet is split */
-#define               nINCOMPRX_R  0x0       
 #define              DMAREQMODE_R  0x800      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_R  0x0       
 #define                 DISNYET_R  0x1000     /* disable Nyet handshakes */
-#define                nDISNYET_R  0x0       
 #define              DMAREQ_ENA_R  0x2000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_R  0x0       
 #define                     ISO_R  0x4000     /* enable Isochronous transfers */
-#define                    nISO_R  0x0       
 #define               AUTOCLEAR_R  0x8000     /* allows TxPktRdy to be set automatically */
-#define              nAUTOCLEAR_R  0x0       
 #define                  ERROR_RH  0x4        /* TxPktRdy not set  for an IN token host mode */
-#define                 nERROR_RH  0x0       
 #define                 REQPKT_RH  0x20       /* request an IN transaction host mode */
-#define                nREQPKT_RH  0x0       
 #define         STALL_RECEIVED_RH  0x40       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_RH  0x0       
 #define               INCOMPRX_RH  0x100      /* indicates that a large packet is split host mode */
-#define              nINCOMPRX_RH  0x0       
 #define             DMAREQMODE_RH  0x800      /* DMA mode (0 or 1) selection host mode */
-#define            nDMAREQMODE_RH  0x0       
 #define                AUTOREQ_RH  0x4000     /* sets ReqPkt automatically host mode */
-#define               nAUTOREQ_RH  0x0       
 
 /* Bit masks for USB_RXCOUNT */
 
@@ -1888,35 +1570,22 @@
 /* Bit masks for USB_DMA_INTERRUPT */
 
 #define                  DMA0_INT  0x1        /* DMA0 pending interrupt */
-#define                 nDMA0_INT  0x0       
 #define                  DMA1_INT  0x2        /* DMA1 pending interrupt */
-#define                 nDMA1_INT  0x0       
 #define                  DMA2_INT  0x4        /* DMA2 pending interrupt */
-#define                 nDMA2_INT  0x0       
 #define                  DMA3_INT  0x8        /* DMA3 pending interrupt */
-#define                 nDMA3_INT  0x0       
 #define                  DMA4_INT  0x10       /* DMA4 pending interrupt */
-#define                 nDMA4_INT  0x0       
 #define                  DMA5_INT  0x20       /* DMA5 pending interrupt */
-#define                 nDMA5_INT  0x0       
 #define                  DMA6_INT  0x40       /* DMA6 pending interrupt */
-#define                 nDMA6_INT  0x0       
 #define                  DMA7_INT  0x80       /* DMA7 pending interrupt */
-#define                 nDMA7_INT  0x0       
 
 /* Bit masks for USB_DMAxCONTROL */
 
 #define                   DMA_ENA  0x1        /* DMA enable */
-#define                  nDMA_ENA  0x0       
 #define                 DIRECTION  0x2        /* direction of DMA transfer */
-#define                nDIRECTION  0x0       
 #define                      MODE  0x4        /* DMA Bus error */
-#define                     nMODE  0x0       
 #define                   INT_ENA  0x8        /* Interrupt enable */
-#define                  nINT_ENA  0x0       
 #define                     EPNUM  0xf0       /* EP number */
 #define                  BUSERROR  0x100      /* DMA Bus error */
-#define                 nBUSERROR  0x0       
 
 /* Bit masks for USB_DMAxADDRHIGH */
 
@@ -1937,26 +1606,16 @@
 /* Bit masks for HMDMAx_CONTROL */
 
 #define                   HMDMAEN  0x1        /* Handshake MDMA Enable */
-#define                  nHMDMAEN  0x0       
 #define                       REP  0x2        /* Handshake MDMA Request Polarity */
-#define                      nREP  0x0       
 #define                       UTE  0x8        /* Urgency Threshold Enable */
-#define                      nUTE  0x0       
 #define                       OIE  0x10       /* Overflow Interrupt Enable */
-#define                      nOIE  0x0       
 #define                      BDIE  0x20       /* Block Done Interrupt Enable */
-#define                     nBDIE  0x0       
 #define                      MBDI  0x40       /* Mask Block Done Interrupt */
-#define                     nMBDI  0x0       
 #define                       DRQ  0x300      /* Handshake MDMA Request Type */
 #define                       RBC  0x1000     /* Force Reload of BCOUNT */
-#define                      nRBC  0x0       
 #define                        PS  0x2000     /* Pin Status */
-#define                       nPS  0x0       
 #define                        OI  0x4000     /* Overflow Interrupt Generated */
-#define                       nOI  0x0       
 #define                       BDI  0x8000     /* Block Done Interrupt Generated */
-#define                      nBDI  0x0       
 
 /* ******************************************* */
 /*     MULTI BIT MACRO ENUMERATIONS            */
diff --git a/include/asm-blackfin/mach-bf548/defBF549.h b/include/asm-blackfin/mach-bf548/defBF549.h
index b1cc1c0..c2f4734 100644
--- a/include/asm-blackfin/mach-bf548/defBF549.h
+++ b/include/asm-blackfin/mach-bf548/defBF549.h
@@ -1070,21 +1070,13 @@
 /* Bit masks for PIXC_CTL */
 
 #define                   PIXC_EN  0x1        /* Pixel Compositor Enable */
-#define                  nPIXC_EN  0x0       
 #define                  OVR_A_EN  0x2        /* Overlay A Enable */
-#define                 nOVR_A_EN  0x0       
 #define                  OVR_B_EN  0x4        /* Overlay B Enable */
-#define                 nOVR_B_EN  0x0       
 #define                  IMG_FORM  0x8        /* Image Data Format */
-#define                 nIMG_FORM  0x0       
 #define                  OVR_FORM  0x10       /* Overlay Data Format */
-#define                 nOVR_FORM  0x0       
 #define                  OUT_FORM  0x20       /* Output Data Format */
-#define                 nOUT_FORM  0x0       
 #define                   UDS_MOD  0x40       /* Resampling Mode */
-#define                  nUDS_MOD  0x0       
 #define                     TC_EN  0x80       /* Transparent Color Enable */
-#define                    nTC_EN  0x0       
 #define                  IMG_STAT  0x300      /* Image FIFO Status */
 #define                  OVR_STAT  0xc00      /* Overlay FIFO Status */
 #define                    WM_LVL  0x3000     /* FIFO Watermark Level */
@@ -1132,13 +1124,9 @@
 /* Bit masks for PIXC_INTRSTAT */
 
 #define                OVR_INT_EN  0x1        /* Interrupt at End of Last Valid Overlay */
-#define               nOVR_INT_EN  0x0       
 #define                FRM_INT_EN  0x2        /* Interrupt at End of Frame */
-#define               nFRM_INT_EN  0x0       
 #define              OVR_INT_STAT  0x4        /* Overlay Interrupt Status */
-#define             nOVR_INT_STAT  0x0       
 #define              FRM_INT_STAT  0x8        /* Frame Interrupt Status */
-#define             nFRM_INT_STAT  0x0       
 
 /* Bit masks for PIXC_RYCON */
 
@@ -1146,7 +1134,6 @@
 #define                       A12  0xffc00    /* A12 in the Coefficient Matrix */
 #define                       A13  0x3ff00000 /* A13 in the Coefficient Matrix */
 #define                  RY_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nRY_MULT4  0x0       
 
 /* Bit masks for PIXC_GUCON */
 
@@ -1154,7 +1141,6 @@
 #define                       A22  0xffc00    /* A22 in the Coefficient Matrix */
 #define                       A23  0x3ff00000 /* A23 in the Coefficient Matrix */
 #define                  GU_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nGU_MULT4  0x0       
 
 /* Bit masks for PIXC_BVCON */
 
@@ -1162,7 +1148,6 @@
 #define                       A32  0xffc00    /* A32 in the Coefficient Matrix */
 #define                       A33  0x3ff00000 /* A33 in the Coefficient Matrix */
 #define                  BV_MULT4  0x40000000 /* Multiply Row by 4 */
-#define                 nBV_MULT4  0x0       
 
 /* Bit masks for PIXC_CCBIAS */
 
@@ -1179,48 +1164,28 @@
 /* Bit masks for HOST_CONTROL */
 
 #define                   HOST_EN  0x1        /* Host Enable */
-#define                  nHOST_EN  0x0       
 #define                  HOST_END  0x2        /* Host Endianess */
-#define                 nHOST_END  0x0       
 #define                 DATA_SIZE  0x4        /* Data Size */
-#define                nDATA_SIZE  0x0       
 #define                  HOST_RST  0x8        /* Host Reset */
-#define                 nHOST_RST  0x0       
 #define                  HRDY_OVR  0x20       /* Host Ready Override */
-#define                 nHRDY_OVR  0x0       
 #define                  INT_MODE  0x40       /* Interrupt Mode */
-#define                 nINT_MODE  0x0       
 #define                     BT_EN  0x80       /* Bus Timeout Enable */
-#define                    nBT_EN  0x0       
 #define                       EHW  0x100      /* Enable Host Write */
-#define                      nEHW  0x0       
 #define                       EHR  0x200      /* Enable Host Read */
-#define                      nEHR  0x0       
 #define                       BDR  0x400      /* Burst DMA Requests */
-#define                      nBDR  0x0       
 
 /* Bit masks for HOST_STATUS */
 
 #define                     READY  0x1        /* DMA Ready */
-#define                    nREADY  0x0       
 #define                  FIFOFULL  0x2        /* FIFO Full */
-#define                 nFIFOFULL  0x0       
 #define                 FIFOEMPTY  0x4        /* FIFO Empty */
-#define                nFIFOEMPTY  0x0       
-#define                  COMPLETE  0x8        /* DMA Complete */
-#define                 nCOMPLETE  0x0       
+#define              DMA_COMPLETE  0x8        /* DMA Complete */
 #define                      HSHK  0x10       /* Host Handshake */
-#define                     nHSHK  0x0       
 #define                   TIMEOUT  0x20       /* Host Timeout */
-#define                  nTIMEOUT  0x0       
 #define                      HIRQ  0x40       /* Host Interrupt Request */
-#define                     nHIRQ  0x0       
 #define                ALLOW_CNFG  0x80       /* Allow New Configuration */
-#define               nALLOW_CNFG  0x0       
 #define                   DMA_DIR  0x100      /* DMA Direction */
-#define                  nDMA_DIR  0x0       
 #define                       BTE  0x200      /* Bus Timeout Enabled */
-#define                      nBTE  0x0       
 
 /* Bit masks for HOST_TIMEOUT */
 
@@ -1229,71 +1194,41 @@
 /* Bit masks for MXVR_CONFIG */
 
 #define                    MXVREN  0x1        /* MXVR Enable */
-#define                   nMXVREN  0x0       
 #define                      MMSM  0x2        /* MXVR Master/Slave Mode Select */
-#define                     nMMSM  0x0       
 #define                    ACTIVE  0x4        /* Active Mode */
-#define                   nACTIVE  0x0       
 #define                    SDELAY  0x8        /* Synchronous Data Delay */
-#define                   nSDELAY  0x0       
 #define                   NCMRXEN  0x10       /* Normal Control Message Receive Enable */
-#define                  nNCMRXEN  0x0       
 #define                   RWRRXEN  0x20       /* Remote Write Receive Enable */
-#define                  nRWRRXEN  0x0       
 #define                     MTXEN  0x40       /* MXVR Transmit Data Enable */
-#define                    nMTXEN  0x0       
 #define                    MTXONB  0x80       /* MXVR Phy Transmitter On */
-#define                   nMTXONB  0x0       
 #define                   EPARITY  0x100      /* Even Parity Select */
-#define                  nEPARITY  0x0       
 #define                       MSB  0x1e00     /* Master Synchronous Boundary */
 #define                    APRXEN  0x2000     /* Asynchronous Packet Receive Enable */
-#define                   nAPRXEN  0x0       
 #define                    WAKEUP  0x4000     /* Wake-Up */
-#define                   nWAKEUP  0x0       
 #define                     LMECH  0x8000     /* Lock Mechanism Select */
-#define                    nLMECH  0x0       
 
 /* Bit masks for MXVR_STATE_0 */
 
 #define                      NACT  0x1        /* Network Activity */
-#define                     nNACT  0x0       
 #define                    SBLOCK  0x2        /* Super Block Lock */
-#define                   nSBLOCK  0x0       
 #define                   FMPLLST  0xc        /* Frequency Multiply PLL SM State */
 #define                  CDRPLLST  0xe0       /* Clock/Data Recovery PLL SM State */
 #define                     APBSY  0x100      /* Asynchronous Packet Transmit Buffer Busy */
-#define                    nAPBSY  0x0       
 #define                     APARB  0x200      /* Asynchronous Packet Arbitrating */
-#define                    nAPARB  0x0       
 #define                      APTX  0x400      /* Asynchronous Packet Transmitting */
-#define                     nAPTX  0x0       
 #define                      APRX  0x800      /* Receiving Asynchronous Packet */
-#define                     nAPRX  0x0       
 #define                     CMBSY  0x1000     /* Control Message Transmit Buffer Busy */
-#define                    nCMBSY  0x0       
 #define                     CMARB  0x2000     /* Control Message Arbitrating */
-#define                    nCMARB  0x0       
 #define                      CMTX  0x4000     /* Control Message Transmitting */
-#define                     nCMTX  0x0       
 #define                      CMRX  0x8000     /* Receiving Control Message */
-#define                     nCMRX  0x0       
 #define                    MRXONB  0x10000    /* MRXONB Pin State */
-#define                   nMRXONB  0x0       
 #define                     RGSIP  0x20000    /* Remote Get Source In Progress */
-#define                    nRGSIP  0x0       
 #define                     DALIP  0x40000    /* Resource Deallocate In Progress */
-#define                    nDALIP  0x0       
 #define                      ALIP  0x80000    /* Resource Allocate In Progress */
-#define                     nALIP  0x0       
 #define                     RRDIP  0x100000   /* Remote Read In Progress */
-#define                    nRRDIP  0x0       
 #define                     RWRIP  0x200000   /* Remote Write In Progress */
-#define                    nRWRIP  0x0       
 #define                     FLOCK  0x400000   /* Frame Lock */
-#define                    nFLOCK  0x0       
 #define                     BLOCK  0x800000   /* Block Lock */
-#define                    nBLOCK  0x0       
 #define                       RSB  0xf000000  /* Received Synchronous Boundary */
 #define                   DERRNUM  0xf0000000 /* DMA Error Channel Number */
 
@@ -1302,535 +1237,343 @@
 #define                   SRXNUMB  0xf        /* Synchronous Receive FIFO Number of Bytes */
 #define                   STXNUMB  0xf0       /* Synchronous Transmit FIFO Number of Bytes */
 #define                    APCONT  0x100      /* Asynchronous Packet Continuation */
-#define                   nAPCONT  0x0       
 #define                  OBERRNUM  0xe00      /* DMA Out of Bounds Error Channel Number */
 #define                DMAACTIVE0  0x10000    /* DMA0 Active */
-#define               nDMAACTIVE0  0x0       
 #define                DMAACTIVE1  0x20000    /* DMA1 Active */
-#define               nDMAACTIVE1  0x0       
 #define                DMAACTIVE2  0x40000    /* DMA2 Active */
-#define               nDMAACTIVE2  0x0       
 #define                DMAACTIVE3  0x80000    /* DMA3 Active */
-#define               nDMAACTIVE3  0x0       
 #define                DMAACTIVE4  0x100000   /* DMA4 Active */
-#define               nDMAACTIVE4  0x0       
 #define                DMAACTIVE5  0x200000   /* DMA5 Active */
-#define               nDMAACTIVE5  0x0       
 #define                DMAACTIVE6  0x400000   /* DMA6 Active */
-#define               nDMAACTIVE6  0x0       
 #define                DMAACTIVE7  0x800000   /* DMA7 Active */
-#define               nDMAACTIVE7  0x0       
 #define                  DMAPMEN0  0x1000000  /* DMA0 Pattern Matching Enabled */
-#define                 nDMAPMEN0  0x0       
 #define                  DMAPMEN1  0x2000000  /* DMA1 Pattern Matching Enabled */
-#define                 nDMAPMEN1  0x0       
 #define                  DMAPMEN2  0x4000000  /* DMA2 Pattern Matching Enabled */
-#define                 nDMAPMEN2  0x0       
 #define                  DMAPMEN3  0x8000000  /* DMA3 Pattern Matching Enabled */
-#define                 nDMAPMEN3  0x0       
 #define                  DMAPMEN4  0x10000000 /* DMA4 Pattern Matching Enabled */
-#define                 nDMAPMEN4  0x0       
 #define                  DMAPMEN5  0x20000000 /* DMA5 Pattern Matching Enabled */
-#define                 nDMAPMEN5  0x0       
 #define                  DMAPMEN6  0x40000000 /* DMA6 Pattern Matching Enabled */
-#define                 nDMAPMEN6  0x0       
 #define                  DMAPMEN7  0x80000000 /* DMA7 Pattern Matching Enabled */
-#define                 nDMAPMEN7  0x0       
 
 /* Bit masks for MXVR_INT_STAT_0 */
 
 #define                      NI2A  0x1        /* Network Inactive to Active */
-#define                     nNI2A  0x0       
 #define                      NA2I  0x2        /* Network Active to Inactive */
-#define                     nNA2I  0x0       
 #define                     SBU2L  0x4        /* Super Block Unlock to Lock */
-#define                    nSBU2L  0x0       
 #define                     SBL2U  0x8        /* Super Block Lock to Unlock */
-#define                    nSBL2U  0x0       
 #define                       PRU  0x10       /* Position Register Updated */
-#define                      nPRU  0x0       
 #define                      MPRU  0x20       /* Maximum Position Register Updated */
-#define                     nMPRU  0x0       
 #define                       DRU  0x40       /* Delay Register Updated */
-#define                      nDRU  0x0       
 #define                      MDRU  0x80       /* Maximum Delay Register Updated */
-#define                     nMDRU  0x0       
 #define                       SBU  0x100      /* Synchronous Boundary Updated */
-#define                      nSBU  0x0       
 #define                       ATU  0x200      /* Allocation Table Updated */
-#define                      nATU  0x0       
 #define                      FCZ0  0x400      /* Frame Counter 0 Zero */
-#define                     nFCZ0  0x0       
 #define                      FCZ1  0x800      /* Frame Counter 1 Zero */
-#define                     nFCZ1  0x0       
 #define                      PERR  0x1000     /* Parity Error */
-#define                     nPERR  0x0       
 #define                      MH2L  0x2000     /* MRXONB High to Low */
-#define                     nMH2L  0x0       
 #define                      ML2H  0x4000     /* MRXONB Low to High */
-#define                     nML2H  0x0       
 #define                       WUP  0x8000     /* Wake-Up Preamble Received */
-#define                      nWUP  0x0       
 #define                      FU2L  0x10000    /* Frame Unlock to Lock */
-#define                     nFU2L  0x0       
 #define                      FL2U  0x20000    /* Frame Lock to Unlock */
-#define                     nFL2U  0x0       
 #define                      BU2L  0x40000    /* Block Unlock to Lock */
-#define                     nBU2L  0x0       
 #define                      BL2U  0x80000    /* Block Lock to Unlock */
-#define                     nBL2U  0x0       
 #define                     OBERR  0x100000   /* DMA Out of Bounds Error */
-#define                    nOBERR  0x0       
 #define                       PFL  0x200000   /* PLL Frequency Locked */
-#define                      nPFL  0x0       
 #define                       SCZ  0x400000   /* System Clock Counter Zero */
-#define                      nSCZ  0x0       
 #define                      FERR  0x800000   /* FIFO Error */
-#define                     nFERR  0x0       
 #define                       CMR  0x1000000  /* Control Message Received */
-#define                      nCMR  0x0       
 #define                     CMROF  0x2000000  /* Control Message Receive Buffer Overflow */
-#define                    nCMROF  0x0       
 #define                      CMTS  0x4000000  /* Control Message Transmit Buffer Successfully Sent */
-#define                     nCMTS  0x0       
 #define                      CMTC  0x8000000  /* Control Message Transmit Buffer Successfully Cancelled */
-#define                     nCMTC  0x0       
 #define                      RWRC  0x10000000 /* Remote Write Control Message Completed */
-#define                     nRWRC  0x0       
 #define                       BCZ  0x20000000 /* Block Counter Zero */
-#define                      nBCZ  0x0       
 #define                     BMERR  0x40000000 /* Biphase Mark Coding Error */
-#define                    nBMERR  0x0       
 #define                      DERR  0x80000000 /* DMA Error */
-#define                     nDERR  0x0       
 
 /* Bit masks for MXVR_INT_STAT_1 */
 
 #define                    HDONE0  0x1        /* DMA0 Half Done */
-#define                   nHDONE0  0x0       
 #define                     DONE0  0x2        /* DMA0 Done */
-#define                    nDONE0  0x0       
 #define                       APR  0x4        /* Asynchronous Packet Received */
-#define                      nAPR  0x0       
 #define                     APROF  0x8        /* Asynchronous Packet Receive Buffer Overflow */
-#define                    nAPROF  0x0       
 #define                    HDONE1  0x10       /* DMA1 Half Done */
-#define                   nHDONE1  0x0       
 #define                     DONE1  0x20       /* DMA1 Done */
-#define                    nDONE1  0x0       
 #define                      APTS  0x40       /* Asynchronous Packet Transmit Buffer Successfully Sent */
-#define                     nAPTS  0x0       
 #define                      APTC  0x80       /* Asynchronous Packet Transmit Buffer Successfully Cancelled */
-#define                     nAPTC  0x0       
 #define                    HDONE2  0x100      /* DMA2 Half Done */
-#define                   nHDONE2  0x0       
 #define                     DONE2  0x200      /* DMA2 Done */
-#define                    nDONE2  0x0       
 #define                     APRCE  0x400      /* Asynchronous Packet Receive CRC Error */
-#define                    nAPRCE  0x0       
 #define                     APRPE  0x800      /* Asynchronous Packet Receive Packet Error */
-#define                    nAPRPE  0x0       
 #define                    HDONE3  0x1000     /* DMA3 Half Done */
-#define                   nHDONE3  0x0       
 #define                     DONE3  0x2000     /* DMA3 Done */
-#define                    nDONE3  0x0       
 #define                    HDONE4  0x10000    /* DMA4 Half Done */
-#define                   nHDONE4  0x0       
 #define                     DONE4  0x20000    /* DMA4 Done */
-#define                    nDONE4  0x0       
 #define                    HDONE5  0x100000   /* DMA5 Half Done */
-#define                   nHDONE5  0x0       
 #define                     DONE5  0x200000   /* DMA5 Done */
-#define                    nDONE5  0x0       
 #define                    HDONE6  0x1000000  /* DMA6 Half Done */
-#define                   nHDONE6  0x0       
 #define                     DONE6  0x2000000  /* DMA6 Done */
-#define                    nDONE6  0x0       
 #define                    HDONE7  0x10000000 /* DMA7 Half Done */
-#define                   nHDONE7  0x0       
 #define                     DONE7  0x20000000 /* DMA7 Done */
-#define                    nDONE7  0x0       
 
 /* Bit masks for MXVR_INT_EN_0 */
 
 #define                    NI2AEN  0x1        /* Network Inactive to Active Interrupt Enable */
-#define                   nNI2AEN  0x0       
 #define                    NA2IEN  0x2        /* Network Active to Inactive Interrupt Enable */
-#define                   nNA2IEN  0x0       
 #define                   SBU2LEN  0x4        /* Super Block Unlock to Lock Interrupt Enable */
-#define                  nSBU2LEN  0x0       
 #define                   SBL2UEN  0x8        /* Super Block Lock to Unlock Interrupt Enable */
-#define                  nSBL2UEN  0x0       
 #define                     PRUEN  0x10       /* Position Register Updated Interrupt Enable */
-#define                    nPRUEN  0x0       
 #define                    MPRUEN  0x20       /* Maximum Position Register Updated Interrupt Enable */
-#define                   nMPRUEN  0x0       
 #define                     DRUEN  0x40       /* Delay Register Updated Interrupt Enable */
-#define                    nDRUEN  0x0       
 #define                    MDRUEN  0x80       /* Maximum Delay Register Updated Interrupt Enable */
-#define                   nMDRUEN  0x0       
 #define                     SBUEN  0x100      /* Synchronous Boundary Updated Interrupt Enable */
-#define                    nSBUEN  0x0       
 #define                     ATUEN  0x200      /* Allocation Table Updated Interrupt Enable */
-#define                    nATUEN  0x0       
 #define                    FCZ0EN  0x400      /* Frame Counter 0 Zero Interrupt Enable */
-#define                   nFCZ0EN  0x0       
 #define                    FCZ1EN  0x800      /* Frame Counter 1 Zero Interrupt Enable */
-#define                   nFCZ1EN  0x0       
 #define                    PERREN  0x1000     /* Parity Error Interrupt Enable */
-#define                   nPERREN  0x0       
 #define                    MH2LEN  0x2000     /* MRXONB High to Low Interrupt Enable */
-#define                   nMH2LEN  0x0       
 #define                    ML2HEN  0x4000     /* MRXONB Low to High Interrupt Enable */
-#define                   nML2HEN  0x0       
 #define                     WUPEN  0x8000     /* Wake-Up Preamble Received Interrupt Enable */
-#define                    nWUPEN  0x0       
 #define                    FU2LEN  0x10000    /* Frame Unlock to Lock Interrupt Enable */
-#define                   nFU2LEN  0x0       
 #define                    FL2UEN  0x20000    /* Frame Lock to Unlock Interrupt Enable */
-#define                   nFL2UEN  0x0       
 #define                    BU2LEN  0x40000    /* Block Unlock to Lock Interrupt Enable */
-#define                   nBU2LEN  0x0       
 #define                    BL2UEN  0x80000    /* Block Lock to Unlock Interrupt Enable */
-#define                   nBL2UEN  0x0       
 #define                   OBERREN  0x100000   /* DMA Out of Bounds Error Interrupt Enable */
-#define                  nOBERREN  0x0       
 #define                     PFLEN  0x200000   /* PLL Frequency Locked Interrupt Enable */
-#define                    nPFLEN  0x0       
 #define                     SCZEN  0x400000   /* System Clock Counter Zero Interrupt Enable */
-#define                    nSCZEN  0x0       
 #define                    FERREN  0x800000   /* FIFO Error Interrupt Enable */
-#define                   nFERREN  0x0       
 #define                     CMREN  0x1000000  /* Control Message Received Interrupt Enable */
-#define                    nCMREN  0x0       
 #define                   CMROFEN  0x2000000  /* Control Message Receive Buffer Overflow Interrupt Enable */
-#define                  nCMROFEN  0x0       
 #define                    CMTSEN  0x4000000  /* Control Message Transmit Buffer Successfully Sent Interrupt Enable */
-#define                   nCMTSEN  0x0       
 #define                    CMTCEN  0x8000000  /* Control Message Transmit Buffer Successfully Cancelled Interrupt Enable */
-#define                   nCMTCEN  0x0       
 #define                    RWRCEN  0x10000000 /* Remote Write Control Message Completed Interrupt Enable */
-#define                   nRWRCEN  0x0       
 #define                     BCZEN  0x20000000 /* Block Counter Zero Interrupt Enable */
-#define                    nBCZEN  0x0       
 #define                   BMERREN  0x40000000 /* Biphase Mark Coding Error Interrupt Enable */
-#define                  nBMERREN  0x0       
 #define                    DERREN  0x80000000 /* DMA Error Interrupt Enable */
-#define                   nDERREN  0x0       
 
 /* Bit masks for MXVR_INT_EN_1 */
 
 #define                  HDONEEN0  0x1        /* DMA0 Half Done Interrupt Enable */
-#define                 nHDONEEN0  0x0       
 #define                   DONEEN0  0x2        /* DMA0 Done Interrupt Enable */
-#define                  nDONEEN0  0x0       
 #define                     APREN  0x4        /* Asynchronous Packet Received Interrupt Enable */
-#define                    nAPREN  0x0       
 #define                   APROFEN  0x8        /* Asynchronous Packet Receive Buffer Overflow Interrupt Enable */
-#define                  nAPROFEN  0x0       
 #define                  HDONEEN1  0x10       /* DMA1 Half Done Interrupt Enable */
-#define                 nHDONEEN1  0x0       
 #define                   DONEEN1  0x20       /* DMA1 Done Interrupt Enable */
-#define                  nDONEEN1  0x0       
 #define                    APTSEN  0x40       /* Asynchronous Packet Transmit Buffer Successfully Sent Interrupt Enable */
-#define                   nAPTSEN  0x0       
 #define                    APTCEN  0x80       /* Asynchronous Packet Transmit Buffer Successfully Cancelled Interrupt Enable */
-#define                   nAPTCEN  0x0       
 #define                  HDONEEN2  0x100      /* DMA2 Half Done Interrupt Enable */
-#define                 nHDONEEN2  0x0       
 #define                   DONEEN2  0x200      /* DMA2 Done Interrupt Enable */
-#define                  nDONEEN2  0x0       
 #define                   APRCEEN  0x400      /* Asynchronous Packet Receive CRC Error Interrupt Enable */
-#define                  nAPRCEEN  0x0       
 #define                   APRPEEN  0x800      /* Asynchronous Packet Receive Packet Error Interrupt Enable */
-#define                  nAPRPEEN  0x0       
 #define                  HDONEEN3  0x1000     /* DMA3 Half Done Interrupt Enable */
-#define                 nHDONEEN3  0x0       
 #define                   DONEEN3  0x2000     /* DMA3 Done Interrupt Enable */
-#define                  nDONEEN3  0x0       
 #define                  HDONEEN4  0x10000    /* DMA4 Half Done Interrupt Enable */
-#define                 nHDONEEN4  0x0       
 #define                   DONEEN4  0x20000    /* DMA4 Done Interrupt Enable */
-#define                  nDONEEN4  0x0       
 #define                  HDONEEN5  0x100000   /* DMA5 Half Done Interrupt Enable */
-#define                 nHDONEEN5  0x0       
 #define                   DONEEN5  0x200000   /* DMA5 Done Interrupt Enable */
-#define                  nDONEEN5  0x0       
 #define                  HDONEEN6  0x1000000  /* DMA6 Half Done Interrupt Enable */
-#define                 nHDONEEN6  0x0       
 #define                   DONEEN6  0x2000000  /* DMA6 Done Interrupt Enable */
-#define                  nDONEEN6  0x0       
 #define                  HDONEEN7  0x10000000 /* DMA7 Half Done Interrupt Enable */
-#define                 nHDONEEN7  0x0       
 #define                   DONEEN7  0x20000000 /* DMA7 Done Interrupt Enable */
-#define                  nDONEEN7  0x0       
 
 /* Bit masks for MXVR_POSITION */
 
 #define                  POSITION  0x3f       /* Node Position */
 #define                    PVALID  0x8000     /* Node Position Valid */
-#define                   nPVALID  0x0       
 
 /* Bit masks for MXVR_MAX_POSITION */
 
 #define                 MPOSITION  0x3f       /* Maximum Node Position */
 #define                   MPVALID  0x8000     /* Maximum Node Position Valid */
-#define                  nMPVALID  0x0       
 
 /* Bit masks for MXVR_DELAY */
 
 #define                     DELAY  0x3f       /* Node Frame Delay */
 #define                    DVALID  0x8000     /* Node Frame Delay Valid */
-#define                   nDVALID  0x0       
 
 /* Bit masks for MXVR_MAX_DELAY */
 
 #define                    MDELAY  0x3f       /* Maximum Node Frame Delay */
 #define                   MDVALID  0x8000     /* Maximum Node Frame Delay Valid */
-#define                  nMDVALID  0x0       
 
 /* Bit masks for MXVR_LADDR */
 
 #define                     LADDR  0xffff     /* Logical Address */
 #define                    LVALID  0x80000000 /* Logical Address Valid */
-#define                   nLVALID  0x0       
 
 /* Bit masks for MXVR_GADDR */
 
 #define                    GADDRL  0xff       /* Group Address Lower Byte */
 #define                    GVALID  0x8000     /* Group Address Valid */
-#define                   nGVALID  0x0       
 
 /* Bit masks for MXVR_AADDR */
 
 #define                     AADDR  0xffff     /* Alternate Address */
 #define                    AVALID  0x80000000 /* Alternate Address Valid */
-#define                   nAVALID  0x0       
 
 /* Bit masks for MXVR_ALLOC_0 */
 
 #define                       CL0  0x7f       /* Channel 0 Connection Label */
 #define                      CIU0  0x80       /* Channel 0 In Use */
-#define                     nCIU0  0x0       
 #define                       CL1  0x7f00     /* Channel 0 Connection Label */
 #define                      CIU1  0x8000     /* Channel 0 In Use */
-#define                     nCIU1  0x0       
 #define                       CL2  0x7f0000   /* Channel 0 Connection Label */
 #define                      CIU2  0x800000   /* Channel 0 In Use */
-#define                     nCIU2  0x0       
 #define                       CL3  0x7f000000 /* Channel 0 Connection Label */
 #define                      CIU3  0x80000000 /* Channel 0 In Use */
-#define                     nCIU3  0x0       
 
 /* Bit masks for MXVR_ALLOC_1 */
 
 #define                       CL4  0x7f       /* Channel 4 Connection Label */
 #define                      CIU4  0x80       /* Channel 4 In Use */
-#define                     nCIU4  0x0       
 #define                       CL5  0x7f00     /* Channel 5 Connection Label */
 #define                      CIU5  0x8000     /* Channel 5 In Use */
-#define                     nCIU5  0x0       
 #define                       CL6  0x7f0000   /* Channel 6 Connection Label */
 #define                      CIU6  0x800000   /* Channel 6 In Use */
-#define                     nCIU6  0x0       
 #define                       CL7  0x7f000000 /* Channel 7 Connection Label */
 #define                      CIU7  0x80000000 /* Channel 7 In Use */
-#define                     nCIU7  0x0       
 
 /* Bit masks for MXVR_ALLOC_2 */
 
 #define                       CL8  0x7f       /* Channel 8 Connection Label */
 #define                      CIU8  0x80       /* Channel 8 In Use */
-#define                     nCIU8  0x0       
 #define                       CL9  0x7f00     /* Channel 9 Connection Label */
 #define                      CIU9  0x8000     /* Channel 9 In Use */
-#define                     nCIU9  0x0       
 #define                      CL10  0x7f0000   /* Channel 10 Connection Label */
 #define                     CIU10  0x800000   /* Channel 10 In Use */
-#define                    nCIU10  0x0       
 #define                      CL11  0x7f000000 /* Channel 11 Connection Label */
 #define                     CIU11  0x80000000 /* Channel 11 In Use */
-#define                    nCIU11  0x0       
 
 /* Bit masks for MXVR_ALLOC_3 */
 
 #define                      CL12  0x7f       /* Channel 12 Connection Label */
 #define                     CIU12  0x80       /* Channel 12 In Use */
-#define                    nCIU12  0x0       
 #define                      CL13  0x7f00     /* Channel 13 Connection Label */
 #define                     CIU13  0x8000     /* Channel 13 In Use */
-#define                    nCIU13  0x0       
 #define                      CL14  0x7f0000   /* Channel 14 Connection Label */
 #define                     CIU14  0x800000   /* Channel 14 In Use */
-#define                    nCIU14  0x0       
 #define                      CL15  0x7f000000 /* Channel 15 Connection Label */
 #define                     CIU15  0x80000000 /* Channel 15 In Use */
-#define                    nCIU15  0x0       
 
 /* Bit masks for MXVR_ALLOC_4 */
 
 #define                      CL16  0x7f       /* Channel 16 Connection Label */
 #define                     CIU16  0x80       /* Channel 16 In Use */
-#define                    nCIU16  0x0       
 #define                      CL17  0x7f00     /* Channel 17 Connection Label */
 #define                     CIU17  0x8000     /* Channel 17 In Use */
-#define                    nCIU17  0x0       
 #define                      CL18  0x7f0000   /* Channel 18 Connection Label */
 #define                     CIU18  0x800000   /* Channel 18 In Use */
-#define                    nCIU18  0x0       
 #define                      CL19  0x7f000000 /* Channel 19 Connection Label */
 #define                     CIU19  0x80000000 /* Channel 19 In Use */
-#define                    nCIU19  0x0       
 
 /* Bit masks for MXVR_ALLOC_5 */
 
 #define                      CL20  0x7f       /* Channel 20 Connection Label */
 #define                     CIU20  0x80       /* Channel 20 In Use */
-#define                    nCIU20  0x0       
 #define                      CL21  0x7f00     /* Channel 21 Connection Label */
 #define                     CIU21  0x8000     /* Channel 21 In Use */
-#define                    nCIU21  0x0       
 #define                      CL22  0x7f0000   /* Channel 22 Connection Label */
 #define                     CIU22  0x800000   /* Channel 22 In Use */
-#define                    nCIU22  0x0       
 #define                      CL23  0x7f000000 /* Channel 23 Connection Label */
 #define                     CIU23  0x80000000 /* Channel 23 In Use */
-#define                    nCIU23  0x0       
 
 /* Bit masks for MXVR_ALLOC_6 */
 
 #define                      CL24  0x7f       /* Channel 24 Connection Label */
 #define                     CIU24  0x80       /* Channel 24 In Use */
-#define                    nCIU24  0x0       
 #define                      CL25  0x7f00     /* Channel 25 Connection Label */
 #define                     CIU25  0x8000     /* Channel 25 In Use */
-#define                    nCIU25  0x0       
 #define                      CL26  0x7f0000   /* Channel 26 Connection Label */
 #define                     CIU26  0x800000   /* Channel 26 In Use */
-#define                    nCIU26  0x0       
 #define                      CL27  0x7f000000 /* Channel 27 Connection Label */
 #define                     CIU27  0x80000000 /* Channel 27 In Use */
-#define                    nCIU27  0x0       
 
 /* Bit masks for MXVR_ALLOC_7 */
 
 #define                      CL28  0x7f       /* Channel 28 Connection Label */
 #define                     CIU28  0x80       /* Channel 28 In Use */
-#define                    nCIU28  0x0       
 #define                      CL29  0x7f00     /* Channel 29 Connection Label */
 #define                     CIU29  0x8000     /* Channel 29 In Use */
-#define                    nCIU29  0x0       
 #define                      CL30  0x7f0000   /* Channel 30 Connection Label */
 #define                     CIU30  0x800000   /* Channel 30 In Use */
-#define                    nCIU30  0x0       
 #define                      CL31  0x7f000000 /* Channel 31 Connection Label */
 #define                     CIU31  0x80000000 /* Channel 31 In Use */
-#define                    nCIU31  0x0       
 
 /* Bit masks for MXVR_ALLOC_8 */
 
 #define                      CL32  0x7f       /* Channel 32 Connection Label */
 #define                     CIU32  0x80       /* Channel 32 In Use */
-#define                    nCIU32  0x0       
 #define                      CL33  0x7f00     /* Channel 33 Connection Label */
 #define                     CIU33  0x8000     /* Channel 33 In Use */
-#define                    nCIU33  0x0       
 #define                      CL34  0x7f0000   /* Channel 34 Connection Label */
 #define                     CIU34  0x800000   /* Channel 34 In Use */
-#define                    nCIU34  0x0       
 #define                      CL35  0x7f000000 /* Channel 35 Connection Label */
 #define                     CIU35  0x80000000 /* Channel 35 In Use */
-#define                    nCIU35  0x0       
 
 /* Bit masks for MXVR_ALLOC_9 */
 
 #define                      CL36  0x7f       /* Channel 36 Connection Label */
 #define                     CIU36  0x80       /* Channel 36 In Use */
-#define                    nCIU36  0x0       
 #define                      CL37  0x7f00     /* Channel 37 Connection Label */
 #define                     CIU37  0x8000     /* Channel 37 In Use */
-#define                    nCIU37  0x0       
 #define                      CL38  0x7f0000   /* Channel 38 Connection Label */
 #define                     CIU38  0x800000   /* Channel 38 In Use */
-#define                    nCIU38  0x0       
 #define                      CL39  0x7f000000 /* Channel 39 Connection Label */
 #define                     CIU39  0x80000000 /* Channel 39 In Use */
-#define                    nCIU39  0x0       
 
 /* Bit masks for MXVR_ALLOC_10 */
 
 #define                      CL40  0x7f       /* Channel 40 Connection Label */
 #define                     CIU40  0x80       /* Channel 40 In Use */
-#define                    nCIU40  0x0       
 #define                      CL41  0x7f00     /* Channel 41 Connection Label */
 #define                     CIU41  0x8000     /* Channel 41 In Use */
-#define                    nCIU41  0x0       
 #define                      CL42  0x7f0000   /* Channel 42 Connection Label */
 #define                     CIU42  0x800000   /* Channel 42 In Use */
-#define                    nCIU42  0x0       
 #define                      CL43  0x7f000000 /* Channel 43 Connection Label */
 #define                     CIU43  0x80000000 /* Channel 43 In Use */
-#define                    nCIU43  0x0       
 
 /* Bit masks for MXVR_ALLOC_11 */
 
 #define                      CL44  0x7f       /* Channel 44 Connection Label */
 #define                     CIU44  0x80       /* Channel 44 In Use */
-#define                    nCIU44  0x0       
 #define                      CL45  0x7f00     /* Channel 45 Connection Label */
 #define                     CIU45  0x8000     /* Channel 45 In Use */
-#define                    nCIU45  0x0       
 #define                      CL46  0x7f0000   /* Channel 46 Connection Label */
 #define                     CIU46  0x800000   /* Channel 46 In Use */
-#define                    nCIU46  0x0       
 #define                      CL47  0x7f000000 /* Channel 47 Connection Label */
 #define                     CIU47  0x80000000 /* Channel 47 In Use */
-#define                    nCIU47  0x0       
 
 /* Bit masks for MXVR_ALLOC_12 */
 
 #define                      CL48  0x7f       /* Channel 48 Connection Label */
 #define                     CIU48  0x80       /* Channel 48 In Use */
-#define                    nCIU48  0x0       
 #define                      CL49  0x7f00     /* Channel 49 Connection Label */
 #define                     CIU49  0x8000     /* Channel 49 In Use */
-#define                    nCIU49  0x0       
 #define                      CL50  0x7f0000   /* Channel 50 Connection Label */
 #define                     CIU50  0x800000   /* Channel 50 In Use */
-#define                    nCIU50  0x0       
 #define                      CL51  0x7f000000 /* Channel 51 Connection Label */
 #define                     CIU51  0x80000000 /* Channel 51 In Use */
-#define                    nCIU51  0x0       
 
 /* Bit masks for MXVR_ALLOC_13 */
 
 #define                      CL52  0x7f       /* Channel 52 Connection Label */
 #define                     CIU52  0x80       /* Channel 52 In Use */
-#define                    nCIU52  0x0       
 #define                      CL53  0x7f00     /* Channel 53 Connection Label */
 #define                     CIU53  0x8000     /* Channel 53 In Use */
-#define                    nCIU53  0x0       
 #define                      CL54  0x7f0000   /* Channel 54 Connection Label */
 #define                     CIU54  0x800000   /* Channel 54 In Use */
-#define                    nCIU54  0x0       
 #define                      CL55  0x7f000000 /* Channel 55 Connection Label */
 #define                     CIU55  0x80000000 /* Channel 55 In Use */
-#define                    nCIU55  0x0       
 
 /* Bit masks for MXVR_ALLOC_14 */
 
 #define                      CL56  0x7f       /* Channel 56 Connection Label */
 #define                     CIU56  0x80       /* Channel 56 In Use */
-#define                    nCIU56  0x0       
 #define                      CL57  0x7f00     /* Channel 57 Connection Label */
 #define                     CIU57  0x8000     /* Channel 57 In Use */
-#define                    nCIU57  0x0       
 #define                      CL58  0x7f0000   /* Channel 58 Connection Label */
 #define                     CIU58  0x800000   /* Channel 58 In Use */
-#define                    nCIU58  0x0       
 #define                      CL59  0x7f000000 /* Channel 59 Connection Label */
 #define                     CIU59  0x80000000 /* Channel 59 In Use */
-#define                    nCIU59  0x0       
 
 /* MXVR_SYNC_LCHAN_0 Masks */
 
@@ -1926,19 +1669,13 @@
 /* Bit masks for MXVR_DMAx_CONFIG */
 
 #define                    MDMAEN  0x1        /* DMA Channel Enable */
-#define                   nMDMAEN  0x0       
 #define                        DD  0x2        /* DMA Channel Direction */
-#define                       nDD  0x0       
 #define                 BY4SWAPEN  0x20       /* DMA Channel Four Byte Swap Enable */
-#define                nBY4SWAPEN  0x0       
 #define                     LCHAN  0x3c0      /* DMA Channel Logical Channel */
 #define                 BITSWAPEN  0x400      /* DMA Channel Bit Swap Enable */
-#define                nBITSWAPEN  0x0       
 #define                 BY2SWAPEN  0x800      /* DMA Channel Two Byte Swap Enable */
-#define                nBY2SWAPEN  0x0       
 #define                     MFLOW  0x7000     /* DMA Channel Operation Flow */
 #define                   FIXEDPM  0x80000    /* DMA Channel Fixed Pattern Matching Select */
-#define                  nFIXEDPM  0x0       
 #define                  STARTPAT  0x300000   /* DMA Channel Start Pattern Select */
 #define                   STOPPAT  0xc00000   /* DMA Channel Stop Pattern Select */
 #define                  COUNTPOS  0x1c000000 /* DMA Channel Count Position */
@@ -1946,94 +1683,71 @@
 /* Bit masks for MXVR_AP_CTL */
 
 #define                   STARTAP  0x1        /* Start Asynchronous Packet Transmission */
-#define                  nSTARTAP  0x0       
 #define                  CANCELAP  0x2        /* Cancel Asynchronous Packet Transmission */
-#define                 nCANCELAP  0x0       
 #define                   RESETAP  0x4        /* Reset Asynchronous Packet Arbitration */
-#define                  nRESETAP  0x0       
 #define                    APRBE0  0x4000     /* Asynchronous Packet Receive Buffer Entry 0 */
-#define                   nAPRBE0  0x0       
 #define                    APRBE1  0x8000     /* Asynchronous Packet Receive Buffer Entry 1 */
-#define                   nAPRBE1  0x0       
 
 /* Bit masks for MXVR_APRB_START_ADDR */
 
-#define      MXVR_APRB_START_ADDR  0x1fffffe  /* Asynchronous Packet Receive Buffer Start Address */
+#define      MXVR_APRB_START_ADDR_MASK  0x1fffffe  /* Asynchronous Packet Receive Buffer Start Address */
 
 /* Bit masks for MXVR_APRB_CURR_ADDR */
 
-#define       MXVR_APRB_CURR_ADDR  0xffffffff /* Asynchronous Packet Receive Buffer Current Address */
+#define       MXVR_APRB_CURR_ADDR_MASK  0xffffffff /* Asynchronous Packet Receive Buffer Current Address */
 
 /* Bit masks for MXVR_APTB_START_ADDR */
 
-#define       MXVR_APTB_START_ADDR  0x1fffffe  /* Asynchronous Packet Transmit Buffer Start Address */
+#define       MXVR_APTB_START_ADDR_MASK  0x1fffffe  /* Asynchronous Packet Transmit Buffer Start Address */
 
 /* Bit masks for MXVR_APTB_CURR_ADDR */
 
-#define        MXVR_APTB_CURR_ADDR  0xffffffff /* Asynchronous Packet Transmit Buffer Current Address */
+#define        MXVR_APTB_CURR_ADDR_MASK  0xffffffff /* Asynchronous Packet Transmit Buffer Current Address */
 
 /* Bit masks for MXVR_CM_CTL */
 
 #define                   STARTCM  0x1        /* Start Control Message Transmission */
-#define                  nSTARTCM  0x0       
 #define                  CANCELCM  0x2        /* Cancel Control Message Transmission */
-#define                 nCANCELCM  0x0       
 #define                    CMRBE0  0x10000    /* Control Message Receive Buffer Entry 0 */
-#define                   nCMRBE0  0x0       
 #define                    CMRBE1  0x20000    /* Control Message Receive Buffer Entry 1 */
-#define                   nCMRBE1  0x0       
 #define                    CMRBE2  0x40000    /* Control Message Receive Buffer Entry 2 */
-#define                   nCMRBE2  0x0       
 #define                    CMRBE3  0x80000    /* Control Message Receive Buffer Entry 3 */
-#define                   nCMRBE3  0x0       
 #define                    CMRBE4  0x100000   /* Control Message Receive Buffer Entry 4 */
-#define                   nCMRBE4  0x0       
 #define                    CMRBE5  0x200000   /* Control Message Receive Buffer Entry 5 */
-#define                   nCMRBE5  0x0       
 #define                    CMRBE6  0x400000   /* Control Message Receive Buffer Entry 6 */
-#define                   nCMRBE6  0x0       
 #define                    CMRBE7  0x800000   /* Control Message Receive Buffer Entry 7 */
-#define                   nCMRBE7  0x0       
 #define                    CMRBE8  0x1000000  /* Control Message Receive Buffer Entry 8 */
-#define                   nCMRBE8  0x0       
 #define                    CMRBE9  0x2000000  /* Control Message Receive Buffer Entry 9 */
-#define                   nCMRBE9  0x0       
 #define                   CMRBE10  0x4000000  /* Control Message Receive Buffer Entry 10 */
-#define                  nCMRBE10  0x0       
 #define                   CMRBE11  0x8000000  /* Control Message Receive Buffer Entry 11 */
-#define                  nCMRBE11  0x0       
 #define                   CMRBE12  0x10000000 /* Control Message Receive Buffer Entry 12 */
-#define                  nCMRBE12  0x0       
 #define                   CMRBE13  0x20000000 /* Control Message Receive Buffer Entry 13 */
-#define                  nCMRBE13  0x0       
 #define                   CMRBE14  0x40000000 /* Control Message Receive Buffer Entry 14 */
-#define                  nCMRBE14  0x0       
 #define                   CMRBE15  0x80000000 /* Control Message Receive Buffer Entry 15 */
-#define                  nCMRBE15  0x0       
 
 /* Bit masks for MXVR_CMRB_START_ADDR */
 
-#define      MXVR_CMRB_START_ADDR  0x1fffffe  /* Control Message Receive Buffer Start Address */
+#define      MXVR_CMRB_START_ADDR_MASK  0x1fffffe  /* Control Message Receive Buffer Start Address */
 
 /* Bit masks for MXVR_CMRB_CURR_ADDR */
 
-#define       MXVR_CMRB_CURR_ADDR  0xffffffff /* Control Message Receive Buffer Current Address */
+#define       MXVR_CMRB_CURR_ADDR_MASK  0xffffffff /* Control Message Receive Buffer Current Address */
 
 /* Bit masks for MXVR_CMTB_START_ADDR */
 
-#define      MXVR_CMTB_START_ADDR  0x1fffffe  /* Control Message Transmit Buffer Start Address */
+#define      MXVR_CMTB_START_ADDR_MASK  0x1fffffe  /* Control Message Transmit Buffer Start Address */
 
 /* Bit masks for MXVR_CMTB_CURR_ADDR */
 
-#define       MXVR_CMTB_CURR_ADDR  0xffffffff /* Control Message Transmit Buffer Current Address */
+#define       MXVR_CMTB_CURR_ADDR_MASK  0xffffffff /* Control Message Transmit Buffer Current Address */
 
 /* Bit masks for MXVR_RRDB_START_ADDR */
 
-#define      MXVR_RRDB_START_ADDR  0x1fffffe  /* Remote Read Buffer Start Address */
+#define      MXVR_RRDB_START_ADDR_MASK  0x1fffffe  /* Remote Read Buffer Start Address */
 
 /* Bit masks for MXVR_RRDB_CURR_ADDR */
 
-#define       MXVR_RRDB_CURR_ADDR  0xffffffff /* Remote Read Buffer Current Address */
+#define       MXVR_RRDB_CURR_ADDR_MASK  0xffffffff /* Remote Read Buffer Current Address */
 
 /* Bit masks for MXVR_PAT_DATAx */
 
@@ -2045,136 +1759,72 @@
 /* Bit masks for MXVR_PAT_EN_0 */
 
 #define              MATCH_EN_0_0  0x1        /* Pattern Match Enable Byte 0 Bit 0 */
-#define             nMATCH_EN_0_0  0x0       
 #define              MATCH_EN_0_1  0x2        /* Pattern Match Enable Byte 0 Bit 1 */
-#define             nMATCH_EN_0_1  0x0       
 #define              MATCH_EN_0_2  0x4        /* Pattern Match Enable Byte 0 Bit 2 */
-#define             nMATCH_EN_0_2  0x0       
 #define              MATCH_EN_0_3  0x8        /* Pattern Match Enable Byte 0 Bit 3 */
-#define             nMATCH_EN_0_3  0x0       
 #define              MATCH_EN_0_4  0x10       /* Pattern Match Enable Byte 0 Bit 4 */
-#define             nMATCH_EN_0_4  0x0       
 #define              MATCH_EN_0_5  0x20       /* Pattern Match Enable Byte 0 Bit 5 */
-#define             nMATCH_EN_0_5  0x0       
 #define              MATCH_EN_0_6  0x40       /* Pattern Match Enable Byte 0 Bit 6 */
-#define             nMATCH_EN_0_6  0x0       
 #define              MATCH_EN_0_7  0x80       /* Pattern Match Enable Byte 0 Bit 7 */
-#define             nMATCH_EN_0_7  0x0       
 #define              MATCH_EN_1_0  0x100      /* Pattern Match Enable Byte 1 Bit 0 */
-#define             nMATCH_EN_1_0  0x0       
 #define              MATCH_EN_1_1  0x200      /* Pattern Match Enable Byte 1 Bit 1 */
-#define             nMATCH_EN_1_1  0x0       
 #define              MATCH_EN_1_2  0x400      /* Pattern Match Enable Byte 1 Bit 2 */
-#define             nMATCH_EN_1_2  0x0       
 #define              MATCH_EN_1_3  0x800      /* Pattern Match Enable Byte 1 Bit 3 */
-#define             nMATCH_EN_1_3  0x0       
 #define              MATCH_EN_1_4  0x1000     /* Pattern Match Enable Byte 1 Bit 4 */
-#define             nMATCH_EN_1_4  0x0       
 #define              MATCH_EN_1_5  0x2000     /* Pattern Match Enable Byte 1 Bit 5 */
-#define             nMATCH_EN_1_5  0x0       
 #define              MATCH_EN_1_6  0x4000     /* Pattern Match Enable Byte 1 Bit 6 */
-#define             nMATCH_EN_1_6  0x0       
 #define              MATCH_EN_1_7  0x8000     /* Pattern Match Enable Byte 1 Bit 7 */
-#define             nMATCH_EN_1_7  0x0       
 #define              MATCH_EN_2_0  0x10000    /* Pattern Match Enable Byte 2 Bit 0 */
-#define             nMATCH_EN_2_0  0x0       
 #define              MATCH_EN_2_1  0x20000    /* Pattern Match Enable Byte 2 Bit 1 */
-#define             nMATCH_EN_2_1  0x0       
 #define              MATCH_EN_2_2  0x40000    /* Pattern Match Enable Byte 2 Bit 2 */
-#define             nMATCH_EN_2_2  0x0       
 #define              MATCH_EN_2_3  0x80000    /* Pattern Match Enable Byte 2 Bit 3 */
-#define             nMATCH_EN_2_3  0x0       
 #define              MATCH_EN_2_4  0x100000   /* Pattern Match Enable Byte 2 Bit 4 */
-#define             nMATCH_EN_2_4  0x0       
 #define              MATCH_EN_2_5  0x200000   /* Pattern Match Enable Byte 2 Bit 5 */
-#define             nMATCH_EN_2_5  0x0       
 #define              MATCH_EN_2_6  0x400000   /* Pattern Match Enable Byte 2 Bit 6 */
-#define             nMATCH_EN_2_6  0x0       
 #define              MATCH_EN_2_7  0x800000   /* Pattern Match Enable Byte 2 Bit 7 */
-#define             nMATCH_EN_2_7  0x0       
 #define              MATCH_EN_3_0  0x1000000  /* Pattern Match Enable Byte 3 Bit 0 */
-#define             nMATCH_EN_3_0  0x0       
 #define              MATCH_EN_3_1  0x2000000  /* Pattern Match Enable Byte 3 Bit 1 */
-#define             nMATCH_EN_3_1  0x0       
 #define              MATCH_EN_3_2  0x4000000  /* Pattern Match Enable Byte 3 Bit 2 */
-#define             nMATCH_EN_3_2  0x0       
 #define              MATCH_EN_3_3  0x8000000  /* Pattern Match Enable Byte 3 Bit 3 */
-#define             nMATCH_EN_3_3  0x0       
 #define              MATCH_EN_3_4  0x10000000 /* Pattern Match Enable Byte 3 Bit 4 */
-#define             nMATCH_EN_3_4  0x0       
 #define              MATCH_EN_3_5  0x20000000 /* Pattern Match Enable Byte 3 Bit 5 */
-#define             nMATCH_EN_3_5  0x0       
 #define              MATCH_EN_3_6  0x40000000 /* Pattern Match Enable Byte 3 Bit 6 */
-#define             nMATCH_EN_3_6  0x0       
 #define              MATCH_EN_3_7  0x80000000 /* Pattern Match Enable Byte 3 Bit 7 */
-#define             nMATCH_EN_3_7  0x0       
 
 /* Bit masks for MXVR_PAT_EN_1 */
 
 #define              MATCH_EN_0_0  0x1        /* Pattern Match Enable Byte 0 Bit 0 */
-#define             nMATCH_EN_0_0  0x0       
 #define              MATCH_EN_0_1  0x2        /* Pattern Match Enable Byte 0 Bit 1 */
-#define             nMATCH_EN_0_1  0x0       
 #define              MATCH_EN_0_2  0x4        /* Pattern Match Enable Byte 0 Bit 2 */
-#define             nMATCH_EN_0_2  0x0       
 #define              MATCH_EN_0_3  0x8        /* Pattern Match Enable Byte 0 Bit 3 */
-#define             nMATCH_EN_0_3  0x0       
 #define              MATCH_EN_0_4  0x10       /* Pattern Match Enable Byte 0 Bit 4 */
-#define             nMATCH_EN_0_4  0x0       
 #define              MATCH_EN_0_5  0x20       /* Pattern Match Enable Byte 0 Bit 5 */
-#define             nMATCH_EN_0_5  0x0       
 #define              MATCH_EN_0_6  0x40       /* Pattern Match Enable Byte 0 Bit 6 */
-#define             nMATCH_EN_0_6  0x0       
 #define              MATCH_EN_0_7  0x80       /* Pattern Match Enable Byte 0 Bit 7 */
-#define             nMATCH_EN_0_7  0x0       
 #define              MATCH_EN_1_0  0x100      /* Pattern Match Enable Byte 1 Bit 0 */
-#define             nMATCH_EN_1_0  0x0       
 #define              MATCH_EN_1_1  0x200      /* Pattern Match Enable Byte 1 Bit 1 */
-#define             nMATCH_EN_1_1  0x0       
 #define              MATCH_EN_1_2  0x400      /* Pattern Match Enable Byte 1 Bit 2 */
-#define             nMATCH_EN_1_2  0x0       
 #define              MATCH_EN_1_3  0x800      /* Pattern Match Enable Byte 1 Bit 3 */
-#define             nMATCH_EN_1_3  0x0       
 #define              MATCH_EN_1_4  0x1000     /* Pattern Match Enable Byte 1 Bit 4 */
-#define             nMATCH_EN_1_4  0x0       
 #define              MATCH_EN_1_5  0x2000     /* Pattern Match Enable Byte 1 Bit 5 */
-#define             nMATCH_EN_1_5  0x0       
 #define              MATCH_EN_1_6  0x4000     /* Pattern Match Enable Byte 1 Bit 6 */
-#define             nMATCH_EN_1_6  0x0       
 #define              MATCH_EN_1_7  0x8000     /* Pattern Match Enable Byte 1 Bit 7 */
-#define             nMATCH_EN_1_7  0x0       
 #define              MATCH_EN_2_0  0x10000    /* Pattern Match Enable Byte 2 Bit 0 */
-#define             nMATCH_EN_2_0  0x0       
 #define              MATCH_EN_2_1  0x20000    /* Pattern Match Enable Byte 2 Bit 1 */
-#define             nMATCH_EN_2_1  0x0       
 #define              MATCH_EN_2_2  0x40000    /* Pattern Match Enable Byte 2 Bit 2 */
-#define             nMATCH_EN_2_2  0x0       
 #define              MATCH_EN_2_3  0x80000    /* Pattern Match Enable Byte 2 Bit 3 */
-#define             nMATCH_EN_2_3  0x0       
 #define              MATCH_EN_2_4  0x100000   /* Pattern Match Enable Byte 2 Bit 4 */
-#define             nMATCH_EN_2_4  0x0       
 #define              MATCH_EN_2_5  0x200000   /* Pattern Match Enable Byte 2 Bit 5 */
-#define             nMATCH_EN_2_5  0x0       
 #define              MATCH_EN_2_6  0x400000   /* Pattern Match Enable Byte 2 Bit 6 */
-#define             nMATCH_EN_2_6  0x0       
 #define              MATCH_EN_2_7  0x800000   /* Pattern Match Enable Byte 2 Bit 7 */
-#define             nMATCH_EN_2_7  0x0       
 #define              MATCH_EN_3_0  0x1000000  /* Pattern Match Enable Byte 3 Bit 0 */
-#define             nMATCH_EN_3_0  0x0       
 #define              MATCH_EN_3_1  0x2000000  /* Pattern Match Enable Byte 3 Bit 1 */
-#define             nMATCH_EN_3_1  0x0       
 #define              MATCH_EN_3_2  0x4000000  /* Pattern Match Enable Byte 3 Bit 2 */
-#define             nMATCH_EN_3_2  0x0       
 #define              MATCH_EN_3_3  0x8000000  /* Pattern Match Enable Byte 3 Bit 3 */
-#define             nMATCH_EN_3_3  0x0       
 #define              MATCH_EN_3_4  0x10000000 /* Pattern Match Enable Byte 3 Bit 4 */
-#define             nMATCH_EN_3_4  0x0       
 #define              MATCH_EN_3_5  0x20000000 /* Pattern Match Enable Byte 3 Bit 5 */
-#define             nMATCH_EN_3_5  0x0       
 #define              MATCH_EN_3_6  0x40000000 /* Pattern Match Enable Byte 3 Bit 6 */
-#define             nMATCH_EN_3_6  0x0       
 #define              MATCH_EN_3_7  0x80000000 /* Pattern Match Enable Byte 3 Bit 7 */
-#define             nMATCH_EN_3_7  0x0       
 
 /* Bit masks for MXVR_FRAME_CNT_0 */
 
@@ -2188,226 +1838,166 @@
 
 #define                    TX_CH0  0x3f       /* Transmit Channel 0 */
 #define                  MUTE_CH0  0x80       /* Mute Channel 0 */
-#define                 nMUTE_CH0  0x0       
 #define                    TX_CH1  0x3f00     /* Transmit Channel 0 */
 #define                  MUTE_CH1  0x8000     /* Mute Channel 0 */
-#define                 nMUTE_CH1  0x0       
 #define                    TX_CH2  0x3f0000   /* Transmit Channel 0 */
 #define                  MUTE_CH2  0x800000   /* Mute Channel 0 */
-#define                 nMUTE_CH2  0x0       
 #define                    TX_CH3  0x3f000000 /* Transmit Channel 0 */
 #define                  MUTE_CH3  0x80000000 /* Mute Channel 0 */
-#define                 nMUTE_CH3  0x0       
 
 /* Bit masks for MXVR_ROUTING_1 */
 
 #define                    TX_CH4  0x3f       /* Transmit Channel 4 */
 #define                  MUTE_CH4  0x80       /* Mute Channel 4 */
-#define                 nMUTE_CH4  0x0       
 #define                    TX_CH5  0x3f00     /* Transmit Channel 5 */
 #define                  MUTE_CH5  0x8000     /* Mute Channel 5 */
-#define                 nMUTE_CH5  0x0       
 #define                    TX_CH6  0x3f0000   /* Transmit Channel 6 */
 #define                  MUTE_CH6  0x800000   /* Mute Channel 6 */
-#define                 nMUTE_CH6  0x0       
 #define                    TX_CH7  0x3f000000 /* Transmit Channel 7 */
 #define                  MUTE_CH7  0x80000000 /* Mute Channel 7 */
-#define                 nMUTE_CH7  0x0       
 
 /* Bit masks for MXVR_ROUTING_2 */
 
 #define                    TX_CH8  0x3f       /* Transmit Channel 8 */
 #define                  MUTE_CH8  0x80       /* Mute Channel 8 */
-#define                 nMUTE_CH8  0x0       
 #define                    TX_CH9  0x3f00     /* Transmit Channel 9 */
 #define                  MUTE_CH9  0x8000     /* Mute Channel 9 */
-#define                 nMUTE_CH9  0x0       
 #define                   TX_CH10  0x3f0000   /* Transmit Channel 10 */
 #define                 MUTE_CH10  0x800000   /* Mute Channel 10 */
-#define                nMUTE_CH10  0x0       
 #define                   TX_CH11  0x3f000000 /* Transmit Channel 11 */
 #define                 MUTE_CH11  0x80000000 /* Mute Channel 11 */
-#define                nMUTE_CH11  0x0       
 
 /* Bit masks for MXVR_ROUTING_3 */
 
 #define                   TX_CH12  0x3f       /* Transmit Channel 12 */
 #define                 MUTE_CH12  0x80       /* Mute Channel 12 */
-#define                nMUTE_CH12  0x0       
 #define                   TX_CH13  0x3f00     /* Transmit Channel 13 */
 #define                 MUTE_CH13  0x8000     /* Mute Channel 13 */
-#define                nMUTE_CH13  0x0       
 #define                   TX_CH14  0x3f0000   /* Transmit Channel 14 */
 #define                 MUTE_CH14  0x800000   /* Mute Channel 14 */
-#define                nMUTE_CH14  0x0       
 #define                   TX_CH15  0x3f000000 /* Transmit Channel 15 */
 #define                 MUTE_CH15  0x80000000 /* Mute Channel 15 */
-#define                nMUTE_CH15  0x0       
 
 /* Bit masks for MXVR_ROUTING_4 */
 
 #define                   TX_CH16  0x3f       /* Transmit Channel 16 */
 #define                 MUTE_CH16  0x80       /* Mute Channel 16 */
-#define                nMUTE_CH16  0x0       
 #define                   TX_CH17  0x3f00     /* Transmit Channel 17 */
 #define                 MUTE_CH17  0x8000     /* Mute Channel 17 */
-#define                nMUTE_CH17  0x0       
 #define                   TX_CH18  0x3f0000   /* Transmit Channel 18 */
 #define                 MUTE_CH18  0x800000   /* Mute Channel 18 */
-#define                nMUTE_CH18  0x0       
 #define                   TX_CH19  0x3f000000 /* Transmit Channel 19 */
 #define                 MUTE_CH19  0x80000000 /* Mute Channel 19 */
-#define                nMUTE_CH19  0x0       
 
 /* Bit masks for MXVR_ROUTING_5 */
 
 #define                   TX_CH20  0x3f       /* Transmit Channel 20 */
 #define                 MUTE_CH20  0x80       /* Mute Channel 20 */
-#define                nMUTE_CH20  0x0       
 #define                   TX_CH21  0x3f00     /* Transmit Channel 21 */
 #define                 MUTE_CH21  0x8000     /* Mute Channel 21 */
-#define                nMUTE_CH21  0x0       
 #define                   TX_CH22  0x3f0000   /* Transmit Channel 22 */
 #define                 MUTE_CH22  0x800000   /* Mute Channel 22 */
-#define                nMUTE_CH22  0x0       
 #define                   TX_CH23  0x3f000000 /* Transmit Channel 23 */
 #define                 MUTE_CH23  0x80000000 /* Mute Channel 23 */
-#define                nMUTE_CH23  0x0       
 
 /* Bit masks for MXVR_ROUTING_6 */
 
 #define                   TX_CH24  0x3f       /* Transmit Channel 24 */
 #define                 MUTE_CH24  0x80       /* Mute Channel 24 */
-#define                nMUTE_CH24  0x0       
 #define                   TX_CH25  0x3f00     /* Transmit Channel 25 */
 #define                 MUTE_CH25  0x8000     /* Mute Channel 25 */
-#define                nMUTE_CH25  0x0       
 #define                   TX_CH26  0x3f0000   /* Transmit Channel 26 */
 #define                 MUTE_CH26  0x800000   /* Mute Channel 26 */
-#define                nMUTE_CH26  0x0       
 #define                   TX_CH27  0x3f000000 /* Transmit Channel 27 */
 #define                 MUTE_CH27  0x80000000 /* Mute Channel 27 */
-#define                nMUTE_CH27  0x0       
 
 /* Bit masks for MXVR_ROUTING_7 */
 
 #define                   TX_CH28  0x3f       /* Transmit Channel 28 */
 #define                 MUTE_CH28  0x80       /* Mute Channel 28 */
-#define                nMUTE_CH28  0x0       
 #define                   TX_CH29  0x3f00     /* Transmit Channel 29 */
 #define                 MUTE_CH29  0x8000     /* Mute Channel 29 */
-#define                nMUTE_CH29  0x0       
 #define                   TX_CH30  0x3f0000   /* Transmit Channel 30 */
 #define                 MUTE_CH30  0x800000   /* Mute Channel 30 */
-#define                nMUTE_CH30  0x0       
 #define                   TX_CH31  0x3f000000 /* Transmit Channel 31 */
 #define                 MUTE_CH31  0x80000000 /* Mute Channel 31 */
-#define                nMUTE_CH31  0x0       
 
 /* Bit masks for MXVR_ROUTING_8 */
 
 #define                   TX_CH32  0x3f       /* Transmit Channel 32 */
 #define                 MUTE_CH32  0x80       /* Mute Channel 32 */
-#define                nMUTE_CH32  0x0       
 #define                   TX_CH33  0x3f00     /* Transmit Channel 33 */
 #define                 MUTE_CH33  0x8000     /* Mute Channel 33 */
-#define                nMUTE_CH33  0x0       
 #define                   TX_CH34  0x3f0000   /* Transmit Channel 34 */
 #define                 MUTE_CH34  0x800000   /* Mute Channel 34 */
-#define                nMUTE_CH34  0x0       
 #define                   TX_CH35  0x3f000000 /* Transmit Channel 35 */
 #define                 MUTE_CH35  0x80000000 /* Mute Channel 35 */
-#define                nMUTE_CH35  0x0       
 
 /* Bit masks for MXVR_ROUTING_9 */
 
 #define                   TX_CH36  0x3f       /* Transmit Channel 36 */
 #define                 MUTE_CH36  0x80       /* Mute Channel 36 */
-#define                nMUTE_CH36  0x0       
 #define                   TX_CH37  0x3f00     /* Transmit Channel 37 */
 #define                 MUTE_CH37  0x8000     /* Mute Channel 37 */
-#define                nMUTE_CH37  0x0       
 #define                   TX_CH38  0x3f0000   /* Transmit Channel 38 */
 #define                 MUTE_CH38  0x800000   /* Mute Channel 38 */
-#define                nMUTE_CH38  0x0       
 #define                   TX_CH39  0x3f000000 /* Transmit Channel 39 */
 #define                 MUTE_CH39  0x80000000 /* Mute Channel 39 */
-#define                nMUTE_CH39  0x0       
 
 /* Bit masks for MXVR_ROUTING_10 */
 
 #define                   TX_CH40  0x3f       /* Transmit Channel 40 */
 #define                 MUTE_CH40  0x80       /* Mute Channel 40 */
-#define                nMUTE_CH40  0x0       
 #define                   TX_CH41  0x3f00     /* Transmit Channel 41 */
 #define                 MUTE_CH41  0x8000     /* Mute Channel 41 */
-#define                nMUTE_CH41  0x0       
 #define                   TX_CH42  0x3f0000   /* Transmit Channel 42 */
 #define                 MUTE_CH42  0x800000   /* Mute Channel 42 */
-#define                nMUTE_CH42  0x0       
 #define                   TX_CH43  0x3f000000 /* Transmit Channel 43 */
 #define                 MUTE_CH43  0x80000000 /* Mute Channel 43 */
-#define                nMUTE_CH43  0x0       
 
 /* Bit masks for MXVR_ROUTING_11 */
 
 #define                   TX_CH44  0x3f       /* Transmit Channel 44 */
 #define                 MUTE_CH44  0x80       /* Mute Channel 44 */
-#define                nMUTE_CH44  0x0       
 #define                   TX_CH45  0x3f00     /* Transmit Channel 45 */
 #define                 MUTE_CH45  0x8000     /* Mute Channel 45 */
-#define                nMUTE_CH45  0x0       
 #define                   TX_CH46  0x3f0000   /* Transmit Channel 46 */
 #define                 MUTE_CH46  0x800000   /* Mute Channel 46 */
-#define                nMUTE_CH46  0x0       
 #define                   TX_CH47  0x3f000000 /* Transmit Channel 47 */
 #define                 MUTE_CH47  0x80000000 /* Mute Channel 47 */
-#define                nMUTE_CH47  0x0       
 
 /* Bit masks for MXVR_ROUTING_12 */
 
 #define                   TX_CH48  0x3f       /* Transmit Channel 48 */
 #define                 MUTE_CH48  0x80       /* Mute Channel 48 */
-#define                nMUTE_CH48  0x0       
 #define                   TX_CH49  0x3f00     /* Transmit Channel 49 */
 #define                 MUTE_CH49  0x8000     /* Mute Channel 49 */
-#define                nMUTE_CH49  0x0       
 #define                   TX_CH50  0x3f0000   /* Transmit Channel 50 */
 #define                 MUTE_CH50  0x800000   /* Mute Channel 50 */
-#define                nMUTE_CH50  0x0       
 #define                   TX_CH51  0x3f000000 /* Transmit Channel 51 */
 #define                 MUTE_CH51  0x80000000 /* Mute Channel 51 */
-#define                nMUTE_CH51  0x0       
 
 /* Bit masks for MXVR_ROUTING_13 */
 
 #define                   TX_CH52  0x3f       /* Transmit Channel 52 */
 #define                 MUTE_CH52  0x80       /* Mute Channel 52 */
-#define                nMUTE_CH52  0x0       
 #define                   TX_CH53  0x3f00     /* Transmit Channel 53 */
 #define                 MUTE_CH53  0x8000     /* Mute Channel 53 */
-#define                nMUTE_CH53  0x0       
 #define                   TX_CH54  0x3f0000   /* Transmit Channel 54 */
 #define                 MUTE_CH54  0x800000   /* Mute Channel 54 */
-#define                nMUTE_CH54  0x0       
 #define                   TX_CH55  0x3f000000 /* Transmit Channel 55 */
 #define                 MUTE_CH55  0x80000000 /* Mute Channel 55 */
-#define                nMUTE_CH55  0x0       
 
 /* Bit masks for MXVR_ROUTING_14 */
 
 #define                   TX_CH56  0x3f       /* Transmit Channel 56 */
 #define                 MUTE_CH56  0x80       /* Mute Channel 56 */
-#define                nMUTE_CH56  0x0       
 #define                   TX_CH57  0x3f00     /* Transmit Channel 57 */
 #define                 MUTE_CH57  0x8000     /* Mute Channel 57 */
-#define                nMUTE_CH57  0x0       
 #define                   TX_CH58  0x3f0000   /* Transmit Channel 58 */
 #define                 MUTE_CH58  0x800000   /* Mute Channel 58 */
-#define                nMUTE_CH58  0x0       
 #define                   TX_CH59  0x3f000000 /* Transmit Channel 59 */
 #define                 MUTE_CH59  0x80000000 /* Mute Channel 59 */
-#define                nMUTE_CH59  0x0       
 
 /* Bit masks for MXVR_BLOCK_CNT */
 
@@ -2416,53 +2006,37 @@
 /* Bit masks for MXVR_CLK_CTL */
 
 #define                  MXTALCEN  0x1        /* MXVR Crystal Oscillator Clock Enable */
-#define                 nMXTALCEN  0x0       
 #define                  MXTALFEN  0x2        /* MXVR Crystal Oscillator Feedback Enable */
-#define                 nMXTALFEN  0x0       
 #define                  MXTALMUL  0x30       /* MXVR Crystal Multiplier */
 #define                  CLKX3SEL  0x80       /* Clock Generation Source Select */
-#define                 nCLKX3SEL  0x0       
 #define                   MMCLKEN  0x100      /* Master Clock Enable */
-#define                  nMMCLKEN  0x0       
 #define                  MMCLKMUL  0x1e00     /* Master Clock Multiplication Factor */
 #define                   PLLSMPS  0xe000     /* MXVR PLL State Machine Prescaler */
 #define                   MBCLKEN  0x10000    /* Bit Clock Enable */
-#define                  nMBCLKEN  0x0       
 #define                  MBCLKDIV  0x1e0000   /* Bit Clock Divide Factor */
 #define                     INVRX  0x800000   /* Invert Receive Data */
-#define                    nINVRX  0x0       
 #define                     MFSEN  0x1000000  /* Frame Sync Enable */
-#define                    nMFSEN  0x0       
 #define                    MFSDIV  0x1e000000 /* Frame Sync Divide Factor */
 #define                    MFSSEL  0x60000000 /* Frame Sync Select */
 #define                   MFSSYNC  0x80000000 /* Frame Sync Synchronization Select */
-#define                  nMFSSYNC  0x0       
 
 /* Bit masks for MXVR_CDRPLL_CTL */
 
 #define                   CDRSMEN  0x1        /* MXVR CDRPLL State Machine Enable */
-#define                  nCDRSMEN  0x0       
 #define                   CDRRSTB  0x2        /* MXVR CDRPLL Reset */
-#define                  nCDRRSTB  0x0       
 #define                   CDRSVCO  0x4        /* MXVR CDRPLL Start VCO */
-#define                  nCDRSVCO  0x0       
 #define                   CDRMODE  0x8        /* MXVR CDRPLL CDR Mode Select */
-#define                  nCDRMODE  0x0       
 #define                   CDRSCNT  0x3f0      /* MXVR CDRPLL Start Counter */
 #define                   CDRLCNT  0xfc00     /* MXVR CDRPLL Lock Counter */
 #define                 CDRSHPSEL  0x3f0000   /* MXVR CDRPLL Shaper Select */
 #define                  CDRSHPEN  0x800000   /* MXVR CDRPLL Shaper Enable */
-#define                 nCDRSHPEN  0x0       
 #define                  CDRCPSEL  0xff000000 /* MXVR CDRPLL Charge Pump Current Select */
 
 /* Bit masks for MXVR_FMPLL_CTL */
 
 #define                    FMSMEN  0x1        /* MXVR FMPLL State Machine Enable */
-#define                   nFMSMEN  0x0       
 #define                    FMRSTB  0x2        /* MXVR FMPLL Reset */
-#define                   nFMRSTB  0x0       
 #define                    FMSVCO  0x4        /* MXVR FMPLL Start VCO */
-#define                   nFMSVCO  0x0       
 #define                    FMSCNT  0x3f0      /* MXVR FMPLL Start Counter */
 #define                    FMLCNT  0xfc00     /* MXVR FMPLL Lock Counter */
 #define                   FMCPSEL  0xff000000 /* MXVR FMPLL Charge Pump Current Select */
@@ -2470,15 +2044,10 @@
 /* Bit masks for MXVR_PIN_CTL */
 
 #define                  MTXONBOD  0x1        /* MTXONB Open Drain Select */
-#define                 nMTXONBOD  0x0       
 #define                   MTXONBG  0x2        /* MTXONB Gates MTX Select */
-#define                  nMTXONBG  0x0       
 #define                     MFSOE  0x10       /* MFS Output Enable */
-#define                    nMFSOE  0x0       
 #define                  MFSGPSEL  0x20       /* MFS General Purpose Output Select */
-#define                 nMFSGPSEL  0x0       
 #define                  MFSGPDAT  0x40       /* MFS General Purpose Output Data */
-#define                 nMFSGPDAT  0x0       
 
 /* Bit masks for MXVR_SCLK_CNT */
 
@@ -2487,7 +2056,6 @@
 /* Bit masks for KPAD_CTL */
 
 #define                   KPAD_EN  0x1        /* Keypad Enable */
-#define                  nKPAD_EN  0x0       
 #define              KPAD_IRQMODE  0x6        /* Key Press Interrupt Enable */
 #define                KPAD_ROWEN  0x1c00     /* Row Enable Width */
 #define                KPAD_COLEN  0xe000     /* Column Enable Width */
@@ -2509,29 +2077,21 @@
 /* Bit masks for KPAD_STAT */
 
 #define                  KPAD_IRQ  0x1        /* Keypad Interrupt Status */
-#define                 nKPAD_IRQ  0x0       
 #define              KPAD_MROWCOL  0x6        /* Multiple Row/Column Keypress Status */
 #define              KPAD_PRESSED  0x8        /* Key press current status */
-#define             nKPAD_PRESSED  0x0       
 
 /* Bit masks for KPAD_SOFTEVAL */
 
 #define           KPAD_SOFTEVAL_E  0x2        /* Software Programmable Force Evaluate */
-#define          nKPAD_SOFTEVAL_E  0x0       
 
 /* Bit masks for SDH_COMMAND */
 
 #define                   CMD_IDX  0x3f       /* Command Index */
 #define                   CMD_RSP  0x40       /* Response */
-#define                  nCMD_RSP  0x0       
 #define                 CMD_L_RSP  0x80       /* Long Response */
-#define                nCMD_L_RSP  0x0       
 #define                 CMD_INT_E  0x100      /* Command Interrupt */
-#define                nCMD_INT_E  0x0       
 #define                CMD_PEND_E  0x200      /* Command Pending */
-#define               nCMD_PEND_E  0x0       
 #define                     CMD_E  0x400      /* Command Enable */
-#define                    nCMD_E  0x0       
 
 /* Bit masks for SDH_PWR_CTL */
 
@@ -2540,21 +2100,15 @@
 #define                       TBD  0x3c       /* TBD */
 #endif
 #define                 SD_CMD_OD  0x40       /* Open Drain Output */
-#define                nSD_CMD_OD  0x0       
 #define                   ROD_CTL  0x80       /* Rod Control */
-#define                  nROD_CTL  0x0       
 
 /* Bit masks for SDH_CLK_CTL */
 
 #define                    CLKDIV  0xff       /* MC_CLK Divisor */
 #define                     CLK_E  0x100      /* MC_CLK Bus Clock Enable */
-#define                    nCLK_E  0x0       
 #define                  PWR_SV_E  0x200      /* Power Save Enable */
-#define                 nPWR_SV_E  0x0       
 #define             CLKDIV_BYPASS  0x400      /* Bypass Divisor */
-#define            nCLKDIV_BYPASS  0x0       
 #define                  WIDE_BUS  0x800      /* Wide Bus Mode Enable */
-#define                 nWIDE_BUS  0x0       
 
 /* Bit masks for SDH_RESP_CMD */
 
@@ -2563,133 +2117,74 @@
 /* Bit masks for SDH_DATA_CTL */
 
 #define                     DTX_E  0x1        /* Data Transfer Enable */
-#define                    nDTX_E  0x0       
 #define                   DTX_DIR  0x2        /* Data Transfer Direction */
-#define                  nDTX_DIR  0x0       
 #define                  DTX_MODE  0x4        /* Data Transfer Mode */
-#define                 nDTX_MODE  0x0       
 #define                 DTX_DMA_E  0x8        /* Data Transfer DMA Enable */
-#define                nDTX_DMA_E  0x0       
 #define              DTX_BLK_LGTH  0xf0       /* Data Transfer Block Length */
 
 /* Bit masks for SDH_STATUS */
 
 #define              CMD_CRC_FAIL  0x1        /* CMD CRC Fail */
-#define             nCMD_CRC_FAIL  0x0       
 #define              DAT_CRC_FAIL  0x2        /* Data CRC Fail */
-#define             nDAT_CRC_FAIL  0x0       
-#define               CMD_TIMEOUT  0x4        /* CMD Time Out */
-#define              nCMD_TIMEOUT  0x0       
-#define               DAT_TIMEOUT  0x8        /* Data Time Out */
-#define              nDAT_TIMEOUT  0x0       
+#define               CMD_TIME_OUT  0x4        /* CMD Time Out */
+#define               DAT_TIME_OUT  0x8        /* Data Time Out */
 #define               TX_UNDERRUN  0x10       /* Transmit Underrun */
-#define              nTX_UNDERRUN  0x0       
 #define                RX_OVERRUN  0x20       /* Receive Overrun */
-#define               nRX_OVERRUN  0x0       
 #define              CMD_RESP_END  0x40       /* CMD Response End */
-#define             nCMD_RESP_END  0x0       
 #define                  CMD_SENT  0x80       /* CMD Sent */
-#define                 nCMD_SENT  0x0       
 #define                   DAT_END  0x100      /* Data End */
-#define                  nDAT_END  0x0       
 #define             START_BIT_ERR  0x200      /* Start Bit Error */
-#define            nSTART_BIT_ERR  0x0       
 #define               DAT_BLK_END  0x400      /* Data Block End */
-#define              nDAT_BLK_END  0x0       
 #define                   CMD_ACT  0x800      /* CMD Active */
-#define                  nCMD_ACT  0x0       
 #define                    TX_ACT  0x1000     /* Transmit Active */
-#define                   nTX_ACT  0x0       
 #define                    RX_ACT  0x2000     /* Receive Active */
-#define                   nRX_ACT  0x0       
 #define              TX_FIFO_STAT  0x4000     /* Transmit FIFO Status */
-#define             nTX_FIFO_STAT  0x0       
 #define              RX_FIFO_STAT  0x8000     /* Receive FIFO Status */
-#define             nRX_FIFO_STAT  0x0       
 #define              TX_FIFO_FULL  0x10000    /* Transmit FIFO Full */
-#define             nTX_FIFO_FULL  0x0       
 #define              RX_FIFO_FULL  0x20000    /* Receive FIFO Full */
-#define             nRX_FIFO_FULL  0x0       
 #define              TX_FIFO_ZERO  0x40000    /* Transmit FIFO Empty */
-#define             nTX_FIFO_ZERO  0x0       
 #define               RX_DAT_ZERO  0x80000    /* Receive FIFO Empty */
-#define              nRX_DAT_ZERO  0x0       
 #define                TX_DAT_RDY  0x100000   /* Transmit Data Available */
-#define               nTX_DAT_RDY  0x0       
 #define               RX_FIFO_RDY  0x200000   /* Receive Data Available */
-#define              nRX_FIFO_RDY  0x0       
 
 /* Bit masks for SDH_STATUS_CLR */
 
 #define         CMD_CRC_FAIL_STAT  0x1        /* CMD CRC Fail Status */
-#define        nCMD_CRC_FAIL_STAT  0x0       
 #define         DAT_CRC_FAIL_STAT  0x2        /* Data CRC Fail Status */
-#define        nDAT_CRC_FAIL_STAT  0x0       
 #define          CMD_TIMEOUT_STAT  0x4        /* CMD Time Out Status */
-#define         nCMD_TIMEOUT_STAT  0x0       
 #define          DAT_TIMEOUT_STAT  0x8        /* Data Time Out status */
-#define         nDAT_TIMEOUT_STAT  0x0       
 #define          TX_UNDERRUN_STAT  0x10       /* Transmit Underrun Status */
-#define         nTX_UNDERRUN_STAT  0x0       
 #define           RX_OVERRUN_STAT  0x20       /* Receive Overrun Status */
-#define          nRX_OVERRUN_STAT  0x0       
 #define         CMD_RESP_END_STAT  0x40       /* CMD Response End Status */
-#define        nCMD_RESP_END_STAT  0x0       
 #define             CMD_SENT_STAT  0x80       /* CMD Sent Status */
-#define            nCMD_SENT_STAT  0x0       
 #define              DAT_END_STAT  0x100      /* Data End Status */
-#define             nDAT_END_STAT  0x0       
 #define        START_BIT_ERR_STAT  0x200      /* Start Bit Error Status */
-#define       nSTART_BIT_ERR_STAT  0x0       
 #define          DAT_BLK_END_STAT  0x400      /* Data Block End Status */
-#define         nDAT_BLK_END_STAT  0x0       
 
 /* Bit masks for SDH_MASK0 */
 
 #define         CMD_CRC_FAIL_MASK  0x1        /* CMD CRC Fail Mask */
-#define        nCMD_CRC_FAIL_MASK  0x0       
 #define         DAT_CRC_FAIL_MASK  0x2        /* Data CRC Fail Mask */
-#define        nDAT_CRC_FAIL_MASK  0x0       
 #define          CMD_TIMEOUT_MASK  0x4        /* CMD Time Out Mask */
-#define         nCMD_TIMEOUT_MASK  0x0       
 #define          DAT_TIMEOUT_MASK  0x8        /* Data Time Out Mask */
-#define         nDAT_TIMEOUT_MASK  0x0       
 #define          TX_UNDERRUN_MASK  0x10       /* Transmit Underrun Mask */
-#define         nTX_UNDERRUN_MASK  0x0       
 #define           RX_OVERRUN_MASK  0x20       /* Receive Overrun Mask */
-#define          nRX_OVERRUN_MASK  0x0       
 #define         CMD_RESP_END_MASK  0x40       /* CMD Response End Mask */
-#define        nCMD_RESP_END_MASK  0x0       
 #define             CMD_SENT_MASK  0x80       /* CMD Sent Mask */
-#define            nCMD_SENT_MASK  0x0       
 #define              DAT_END_MASK  0x100      /* Data End Mask */
-#define             nDAT_END_MASK  0x0       
 #define        START_BIT_ERR_MASK  0x200      /* Start Bit Error Mask */
-#define       nSTART_BIT_ERR_MASK  0x0       
 #define          DAT_BLK_END_MASK  0x400      /* Data Block End Mask */
-#define         nDAT_BLK_END_MASK  0x0       
 #define              CMD_ACT_MASK  0x800      /* CMD Active Mask */
-#define             nCMD_ACT_MASK  0x0       
 #define               TX_ACT_MASK  0x1000     /* Transmit Active Mask */
-#define              nTX_ACT_MASK  0x0       
 #define               RX_ACT_MASK  0x2000     /* Receive Active Mask */
-#define              nRX_ACT_MASK  0x0       
 #define         TX_FIFO_STAT_MASK  0x4000     /* Transmit FIFO Status Mask */
-#define        nTX_FIFO_STAT_MASK  0x0       
 #define         RX_FIFO_STAT_MASK  0x8000     /* Receive FIFO Status Mask */
-#define        nRX_FIFO_STAT_MASK  0x0       
 #define         TX_FIFO_FULL_MASK  0x10000    /* Transmit FIFO Full Mask */
-#define        nTX_FIFO_FULL_MASK  0x0       
 #define         RX_FIFO_FULL_MASK  0x20000    /* Receive FIFO Full Mask */
-#define        nRX_FIFO_FULL_MASK  0x0       
 #define         TX_FIFO_ZERO_MASK  0x40000    /* Transmit FIFO Empty Mask */
-#define        nTX_FIFO_ZERO_MASK  0x0       
 #define          RX_DAT_ZERO_MASK  0x80000    /* Receive FIFO Empty Mask */
-#define         nRX_DAT_ZERO_MASK  0x0       
 #define           TX_DAT_RDY_MASK  0x100000   /* Transmit Data Available Mask */
-#define          nTX_DAT_RDY_MASK  0x0       
 #define          RX_FIFO_RDY_MASK  0x200000   /* Receive Data Available Mask */
-#define         nRX_FIFO_RDY_MASK  0x0       
 
 /* Bit masks for SDH_FIFO_CNT */
 
@@ -2698,73 +2193,47 @@
 /* Bit masks for SDH_E_STATUS */
 
 #define              SDIO_INT_DET  0x2        /* SDIO Int Detected */
-#define             nSDIO_INT_DET  0x0       
 #define               SD_CARD_DET  0x10       /* SD Card Detect */
-#define              nSD_CARD_DET  0x0       
 
 /* Bit masks for SDH_E_MASK */
 
 #define                  SDIO_MSK  0x2        /* Mask SDIO Int Detected */
-#define                 nSDIO_MSK  0x0       
 #define                   SCD_MSK  0x40       /* Mask Card Detect */
-#define                  nSCD_MSK  0x0       
 
 /* Bit masks for SDH_CFG */
 
 #define                   CLKS_EN  0x1        /* Clocks Enable */
-#define                  nCLKS_EN  0x0       
 #define                      SD4E  0x4        /* SDIO 4-Bit Enable */
-#define                     nSD4E  0x0       
 #define                       MWE  0x8        /* Moving Window Enable */
-#define                      nMWE  0x0       
 #define                    SD_RST  0x10       /* SDMMC Reset */
-#define                   nSD_RST  0x0       
 #define                 PUP_SDDAT  0x20       /* Pull-up SD_DAT */
-#define                nPUP_SDDAT  0x0       
 #define                PUP_SDDAT3  0x40       /* Pull-up SD_DAT3 */
-#define               nPUP_SDDAT3  0x0       
 #define                 PD_SDDAT3  0x80       /* Pull-down SD_DAT3 */
-#define                nPD_SDDAT3  0x0       
 
 /* Bit masks for SDH_RD_WAIT_EN */
 
 #define                       RWR  0x1        /* Read Wait Request */
-#define                      nRWR  0x0       
 
 /* Bit masks for ATAPI_CONTROL */
 
 #define                 PIO_START  0x1        /* Start PIO/Reg Op */
-#define                nPIO_START  0x0       
 #define               MULTI_START  0x2        /* Start Multi-DMA Op */
-#define              nMULTI_START  0x0       
 #define               ULTRA_START  0x4        /* Start Ultra-DMA Op */
-#define              nULTRA_START  0x0       
 #define                  XFER_DIR  0x8        /* Transfer Direction */
-#define                 nXFER_DIR  0x0       
 #define                  IORDY_EN  0x10       /* IORDY Enable */
-#define                 nIORDY_EN  0x0       
 #define                FIFO_FLUSH  0x20       /* Flush FIFOs */
-#define               nFIFO_FLUSH  0x0       
 #define                  SOFT_RST  0x40       /* Soft Reset */
-#define                 nSOFT_RST  0x0       
 #define                   DEV_RST  0x80       /* Device Reset */
-#define                  nDEV_RST  0x0       
 #define                TFRCNT_RST  0x100      /* Trans Count Reset */
-#define               nTFRCNT_RST  0x0       
 #define               END_ON_TERM  0x200      /* End/Terminate Select */
-#define              nEND_ON_TERM  0x0       
 #define               PIO_USE_DMA  0x400      /* PIO-DMA Enable */
-#define              nPIO_USE_DMA  0x0       
 #define          UDMAIN_FIFO_THRS  0xf000     /* Ultra DMA-IN FIFO Threshold */
 
 /* Bit masks for ATAPI_STATUS */
 
 #define               PIO_XFER_ON  0x1        /* PIO transfer in progress */
-#define              nPIO_XFER_ON  0x0       
 #define             MULTI_XFER_ON  0x2        /* Multi-word DMA transfer in progress */
-#define            nMULTI_XFER_ON  0x0       
 #define             ULTRA_XFER_ON  0x4        /* Ultra DMA transfer in progress */
-#define            nULTRA_XFER_ON  0x0       
 #define               ULTRA_IN_FL  0xf0       /* Ultra DMA Input FIFO Level */
 
 /* Bit masks for ATAPI_DEV_ADDR */
@@ -2774,66 +2243,39 @@
 /* Bit masks for ATAPI_INT_MASK */
 
 #define        ATAPI_DEV_INT_MASK  0x1        /* Device interrupt mask */
-#define       nATAPI_DEV_INT_MASK  0x0       
 #define             PIO_DONE_MASK  0x2        /* PIO transfer done interrupt mask */
-#define            nPIO_DONE_MASK  0x0       
 #define           MULTI_DONE_MASK  0x4        /* Multi-DMA transfer done interrupt mask */
-#define          nMULTI_DONE_MASK  0x0       
 #define          UDMAIN_DONE_MASK  0x8        /* Ultra-DMA in transfer done interrupt mask */
-#define         nUDMAIN_DONE_MASK  0x0       
 #define         UDMAOUT_DONE_MASK  0x10       /* Ultra-DMA out transfer done interrupt mask */
-#define        nUDMAOUT_DONE_MASK  0x0       
 #define       HOST_TERM_XFER_MASK  0x20       /* Host terminate current transfer interrupt mask */
-#define      nHOST_TERM_XFER_MASK  0x0       
 #define           MULTI_TERM_MASK  0x40       /* Device terminate Multi-DMA transfer interrupt mask */
-#define          nMULTI_TERM_MASK  0x0       
 #define          UDMAIN_TERM_MASK  0x80       /* Device terminate Ultra-DMA-in transfer interrupt mask */
-#define         nUDMAIN_TERM_MASK  0x0       
 #define         UDMAOUT_TERM_MASK  0x100      /* Device terminate Ultra-DMA-out transfer interrupt mask */
-#define        nUDMAOUT_TERM_MASK  0x0       
 
 /* Bit masks for ATAPI_INT_STATUS */
 
 #define             ATAPI_DEV_INT  0x1        /* Device interrupt status */
-#define            nATAPI_DEV_INT  0x0       
 #define              PIO_DONE_INT  0x2        /* PIO transfer done interrupt status */
-#define             nPIO_DONE_INT  0x0       
 #define            MULTI_DONE_INT  0x4        /* Multi-DMA transfer done interrupt status */
-#define           nMULTI_DONE_INT  0x0       
 #define           UDMAIN_DONE_INT  0x8        /* Ultra-DMA in transfer done interrupt status */
-#define          nUDMAIN_DONE_INT  0x0       
 #define          UDMAOUT_DONE_INT  0x10       /* Ultra-DMA out transfer done interrupt status */
-#define         nUDMAOUT_DONE_INT  0x0       
 #define        HOST_TERM_XFER_INT  0x20       /* Host terminate current transfer interrupt status */
-#define       nHOST_TERM_XFER_INT  0x0       
 #define            MULTI_TERM_INT  0x40       /* Device terminate Multi-DMA transfer interrupt status */
-#define           nMULTI_TERM_INT  0x0       
 #define           UDMAIN_TERM_INT  0x80       /* Device terminate Ultra-DMA-in transfer interrupt status */
-#define          nUDMAIN_TERM_INT  0x0       
 #define          UDMAOUT_TERM_INT  0x100      /* Device terminate Ultra-DMA-out transfer interrupt status */
-#define         nUDMAOUT_TERM_INT  0x0       
 
 /* Bit masks for ATAPI_LINE_STATUS */
 
 #define                ATAPI_INTR  0x1        /* Device interrupt to host line status */
-#define               nATAPI_INTR  0x0       
 #define                ATAPI_DASP  0x2        /* Device dasp to host line status */
-#define               nATAPI_DASP  0x0       
 #define                ATAPI_CS0N  0x4        /* ATAPI chip select 0 line status */
-#define               nATAPI_CS0N  0x0       
 #define                ATAPI_CS1N  0x8        /* ATAPI chip select 1 line status */
-#define               nATAPI_CS1N  0x0       
 #define                ATAPI_ADDR  0x70       /* ATAPI address line status */
 #define              ATAPI_DMAREQ  0x80       /* ATAPI DMA request line status */
-#define             nATAPI_DMAREQ  0x0       
 #define             ATAPI_DMAACKN  0x100      /* ATAPI DMA acknowledge line status */
-#define            nATAPI_DMAACKN  0x0       
 #define               ATAPI_DIOWN  0x200      /* ATAPI write line status */
-#define              nATAPI_DIOWN  0x0       
 #define               ATAPI_DIORN  0x400      /* ATAPI read line status */
-#define              nATAPI_DIORN  0x0       
 #define               ATAPI_IORDY  0x800      /* ATAPI IORDY line status */
-#define              nATAPI_IORDY  0x0       
 
 /* Bit masks for ATAPI_SM_STATE */
 
@@ -2845,7 +2287,6 @@
 /* Bit masks for ATAPI_TERMINATE */
 
 #define           ATAPI_HOST_TERM  0x1        /* Host terminationation */
-#define          nATAPI_HOST_TERM  0x0       
 
 /* Bit masks for ATAPI_REG_TIM_0 */
 
@@ -2900,41 +2341,26 @@
 /* Bit masks for TIMER_ENABLE1 */
 
 #define                    TIMEN8  0x1        /* Timer 8 Enable */
-#define                   nTIMEN8  0x0       
 #define                    TIMEN9  0x2        /* Timer 9 Enable */
-#define                   nTIMEN9  0x0       
 #define                   TIMEN10  0x4        /* Timer 10 Enable */
-#define                  nTIMEN10  0x0       
 
 /* Bit masks for TIMER_DISABLE1 */
 
 #define                   TIMDIS8  0x1        /* Timer 8 Disable */
-#define                  nTIMDIS8  0x0       
 #define                   TIMDIS9  0x2        /* Timer 9 Disable */
-#define                  nTIMDIS9  0x0       
 #define                  TIMDIS10  0x4        /* Timer 10 Disable */
-#define                 nTIMDIS10  0x0       
 
 /* Bit masks for TIMER_STATUS1 */
 
 #define                    TIMIL8  0x1        /* Timer 8 Interrupt */
-#define                   nTIMIL8  0x0       
 #define                    TIMIL9  0x2        /* Timer 9 Interrupt */
-#define                   nTIMIL9  0x0       
 #define                   TIMIL10  0x4        /* Timer 10 Interrupt */
-#define                  nTIMIL10  0x0       
 #define                 TOVF_ERR8  0x10       /* Timer 8 Counter Overflow */
-#define                nTOVF_ERR8  0x0       
 #define                 TOVF_ERR9  0x20       /* Timer 9 Counter Overflow */
-#define                nTOVF_ERR9  0x0       
 #define                TOVF_ERR10  0x40       /* Timer 10 Counter Overflow */
-#define               nTOVF_ERR10  0x0       
 #define                     TRUN8  0x1000     /* Timer 8 Slave Enable Status */
-#define                    nTRUN8  0x0       
 #define                     TRUN9  0x2000     /* Timer 9 Slave Enable Status */
-#define                    nTRUN9  0x0       
 #define                    TRUN10  0x4000     /* Timer 10 Slave Enable Status */
-#define                   nTRUN10  0x0       
 
 /* Bit masks for EPPI0 are obtained from common base header for EPPIx (EPPI1 and EPPI2) */
 
@@ -2945,131 +2371,77 @@
 /* Bit masks for USB_POWER */
 
 #define           ENABLE_SUSPENDM  0x1        /* enable SuspendM output */
-#define          nENABLE_SUSPENDM  0x0       
 #define              SUSPEND_MODE  0x2        /* Suspend Mode indicator */
-#define             nSUSPEND_MODE  0x0       
 #define               RESUME_MODE  0x4        /* DMA Mode */
-#define              nRESUME_MODE  0x0       
 #define                     RESET  0x8        /* Reset indicator */
-#define                    nRESET  0x0       
 #define                   HS_MODE  0x10       /* High Speed mode indicator */
-#define                  nHS_MODE  0x0       
 #define                 HS_ENABLE  0x20       /* high Speed Enable */
-#define                nHS_ENABLE  0x0       
 #define                 SOFT_CONN  0x40       /* Soft connect */
-#define                nSOFT_CONN  0x0       
 #define                ISO_UPDATE  0x80       /* Isochronous update */
-#define               nISO_UPDATE  0x0       
 
 /* Bit masks for USB_INTRTX */
 
 #define                    EP0_TX  0x1        /* Tx Endpoint 0 interrupt */
-#define                   nEP0_TX  0x0       
 #define                    EP1_TX  0x2        /* Tx Endpoint 1 interrupt */
-#define                   nEP1_TX  0x0       
 #define                    EP2_TX  0x4        /* Tx Endpoint 2 interrupt */
-#define                   nEP2_TX  0x0       
 #define                    EP3_TX  0x8        /* Tx Endpoint 3 interrupt */
-#define                   nEP3_TX  0x0       
 #define                    EP4_TX  0x10       /* Tx Endpoint 4 interrupt */
-#define                   nEP4_TX  0x0       
 #define                    EP5_TX  0x20       /* Tx Endpoint 5 interrupt */
-#define                   nEP5_TX  0x0       
 #define                    EP6_TX  0x40       /* Tx Endpoint 6 interrupt */
-#define                   nEP6_TX  0x0       
 #define                    EP7_TX  0x80       /* Tx Endpoint 7 interrupt */
-#define                   nEP7_TX  0x0       
 
 /* Bit masks for USB_INTRRX */
 
 #define                    EP1_RX  0x2        /* Rx Endpoint 1 interrupt */
-#define                   nEP1_RX  0x0       
 #define                    EP2_RX  0x4        /* Rx Endpoint 2 interrupt */
-#define                   nEP2_RX  0x0       
 #define                    EP3_RX  0x8        /* Rx Endpoint 3 interrupt */
-#define                   nEP3_RX  0x0       
 #define                    EP4_RX  0x10       /* Rx Endpoint 4 interrupt */
-#define                   nEP4_RX  0x0       
 #define                    EP5_RX  0x20       /* Rx Endpoint 5 interrupt */
-#define                   nEP5_RX  0x0       
 #define                    EP6_RX  0x40       /* Rx Endpoint 6 interrupt */
-#define                   nEP6_RX  0x0       
 #define                    EP7_RX  0x80       /* Rx Endpoint 7 interrupt */
-#define                   nEP7_RX  0x0       
 
 /* Bit masks for USB_INTRTXE */
 
 #define                  EP0_TX_E  0x1        /* Endpoint 0 interrupt Enable */
-#define                 nEP0_TX_E  0x0       
 #define                  EP1_TX_E  0x2        /* Tx Endpoint 1 interrupt  Enable */
-#define                 nEP1_TX_E  0x0       
 #define                  EP2_TX_E  0x4        /* Tx Endpoint 2 interrupt  Enable */
-#define                 nEP2_TX_E  0x0       
 #define                  EP3_TX_E  0x8        /* Tx Endpoint 3 interrupt  Enable */
-#define                 nEP3_TX_E  0x0       
 #define                  EP4_TX_E  0x10       /* Tx Endpoint 4 interrupt  Enable */
-#define                 nEP4_TX_E  0x0       
 #define                  EP5_TX_E  0x20       /* Tx Endpoint 5 interrupt  Enable */
-#define                 nEP5_TX_E  0x0       
 #define                  EP6_TX_E  0x40       /* Tx Endpoint 6 interrupt  Enable */
-#define                 nEP6_TX_E  0x0       
 #define                  EP7_TX_E  0x80       /* Tx Endpoint 7 interrupt  Enable */
-#define                 nEP7_TX_E  0x0       
 
 /* Bit masks for USB_INTRRXE */
 
 #define                  EP1_RX_E  0x2        /* Rx Endpoint 1 interrupt  Enable */
-#define                 nEP1_RX_E  0x0       
 #define                  EP2_RX_E  0x4        /* Rx Endpoint 2 interrupt  Enable */
-#define                 nEP2_RX_E  0x0       
 #define                  EP3_RX_E  0x8        /* Rx Endpoint 3 interrupt  Enable */
-#define                 nEP3_RX_E  0x0       
 #define                  EP4_RX_E  0x10       /* Rx Endpoint 4 interrupt  Enable */
-#define                 nEP4_RX_E  0x0       
 #define                  EP5_RX_E  0x20       /* Rx Endpoint 5 interrupt  Enable */
-#define                 nEP5_RX_E  0x0       
 #define                  EP6_RX_E  0x40       /* Rx Endpoint 6 interrupt  Enable */
-#define                 nEP6_RX_E  0x0       
 #define                  EP7_RX_E  0x80       /* Rx Endpoint 7 interrupt  Enable */
-#define                 nEP7_RX_E  0x0       
 
 /* Bit masks for USB_INTRUSB */
 
 #define                 SUSPEND_B  0x1        /* Suspend indicator */
-#define                nSUSPEND_B  0x0       
 #define                  RESUME_B  0x2        /* Resume indicator */
-#define                 nRESUME_B  0x0       
 #define          RESET_OR_BABLE_B  0x4        /* Reset/babble indicator */
-#define         nRESET_OR_BABLE_B  0x0       
 #define                     SOF_B  0x8        /* Start of frame */
-#define                    nSOF_B  0x0       
 #define                    CONN_B  0x10       /* Connection indicator */
-#define                   nCONN_B  0x0       
 #define                  DISCON_B  0x20       /* Disconnect indicator */
-#define                 nDISCON_B  0x0       
 #define             SESSION_REQ_B  0x40       /* Session Request */
-#define            nSESSION_REQ_B  0x0       
 #define              VBUS_ERROR_B  0x80       /* Vbus threshold indicator */
-#define             nVBUS_ERROR_B  0x0       
 
 /* Bit masks for USB_INTRUSBE */
 
 #define                SUSPEND_BE  0x1        /* Suspend indicator int enable */
-#define               nSUSPEND_BE  0x0       
 #define                 RESUME_BE  0x2        /* Resume indicator int enable */
-#define                nRESUME_BE  0x0       
 #define         RESET_OR_BABLE_BE  0x4        /* Reset/babble indicator int enable */
-#define        nRESET_OR_BABLE_BE  0x0       
 #define                    SOF_BE  0x8        /* Start of frame int enable */
-#define                   nSOF_BE  0x0       
 #define                   CONN_BE  0x10       /* Connection indicator int enable */
-#define                  nCONN_BE  0x0       
 #define                 DISCON_BE  0x20       /* Disconnect indicator int enable */
-#define                nDISCON_BE  0x0       
 #define            SESSION_REQ_BE  0x40       /* Session Request int enable */
-#define           nSESSION_REQ_BE  0x0       
 #define             VBUS_ERROR_BE  0x80       /* Vbus threshold indicator int enable */
-#define            nVBUS_ERROR_BE  0x0       
 
 /* Bit masks for USB_FRAME */
 
@@ -3082,117 +2454,67 @@
 /* Bit masks for USB_GLOBAL_CTL */
 
 #define                GLOBAL_ENA  0x1        /* enables USB module */
-#define               nGLOBAL_ENA  0x0       
 #define                EP1_TX_ENA  0x2        /* Transmit endpoint 1 enable */
-#define               nEP1_TX_ENA  0x0       
 #define                EP2_TX_ENA  0x4        /* Transmit endpoint 2 enable */
-#define               nEP2_TX_ENA  0x0       
 #define                EP3_TX_ENA  0x8        /* Transmit endpoint 3 enable */
-#define               nEP3_TX_ENA  0x0       
 #define                EP4_TX_ENA  0x10       /* Transmit endpoint 4 enable */
-#define               nEP4_TX_ENA  0x0       
 #define                EP5_TX_ENA  0x20       /* Transmit endpoint 5 enable */
-#define               nEP5_TX_ENA  0x0       
 #define                EP6_TX_ENA  0x40       /* Transmit endpoint 6 enable */
-#define               nEP6_TX_ENA  0x0       
 #define                EP7_TX_ENA  0x80       /* Transmit endpoint 7 enable */
-#define               nEP7_TX_ENA  0x0       
 #define                EP1_RX_ENA  0x100      /* Receive endpoint 1 enable */
-#define               nEP1_RX_ENA  0x0       
 #define                EP2_RX_ENA  0x200      /* Receive endpoint 2 enable */
-#define               nEP2_RX_ENA  0x0       
 #define                EP3_RX_ENA  0x400      /* Receive endpoint 3 enable */
-#define               nEP3_RX_ENA  0x0       
 #define                EP4_RX_ENA  0x800      /* Receive endpoint 4 enable */
-#define               nEP4_RX_ENA  0x0       
 #define                EP5_RX_ENA  0x1000     /* Receive endpoint 5 enable */
-#define               nEP5_RX_ENA  0x0       
 #define                EP6_RX_ENA  0x2000     /* Receive endpoint 6 enable */
-#define               nEP6_RX_ENA  0x0       
 #define                EP7_RX_ENA  0x4000     /* Receive endpoint 7 enable */
-#define               nEP7_RX_ENA  0x0       
 
 /* Bit masks for USB_OTG_DEV_CTL */
 
 #define                   SESSION  0x1        /* session indicator */
-#define                  nSESSION  0x0       
 #define                  HOST_REQ  0x2        /* Host negotiation request */
-#define                 nHOST_REQ  0x0       
 #define                 HOST_MODE  0x4        /* indicates USBDRC is a host */
-#define                nHOST_MODE  0x0       
 #define                     VBUS0  0x8        /* Vbus level indicator[0] */
-#define                    nVBUS0  0x0       
 #define                     VBUS1  0x10       /* Vbus level indicator[1] */
-#define                    nVBUS1  0x0       
 #define                     LSDEV  0x20       /* Low-speed indicator */
-#define                    nLSDEV  0x0       
 #define                     FSDEV  0x40       /* Full or High-speed indicator */
-#define                    nFSDEV  0x0       
 #define                  B_DEVICE  0x80       /* A' or 'B' device indicator */
-#define                 nB_DEVICE  0x0       
 
 /* Bit masks for USB_OTG_VBUS_IRQ */
 
 #define             DRIVE_VBUS_ON  0x1        /* indicator to drive VBUS control circuit */
-#define            nDRIVE_VBUS_ON  0x0       
 #define            DRIVE_VBUS_OFF  0x2        /* indicator to shut off charge pump */
-#define           nDRIVE_VBUS_OFF  0x0       
 #define           CHRG_VBUS_START  0x4        /* indicator for external circuit to start charging VBUS */
-#define          nCHRG_VBUS_START  0x0       
 #define             CHRG_VBUS_END  0x8        /* indicator for external circuit to end charging VBUS */
-#define            nCHRG_VBUS_END  0x0       
 #define        DISCHRG_VBUS_START  0x10       /* indicator to start discharging VBUS */
-#define       nDISCHRG_VBUS_START  0x0       
 #define          DISCHRG_VBUS_END  0x20       /* indicator to stop discharging VBUS */
-#define         nDISCHRG_VBUS_END  0x0       
 
 /* Bit masks for USB_OTG_VBUS_MASK */
 
 #define         DRIVE_VBUS_ON_ENA  0x1        /* enable DRIVE_VBUS_ON interrupt */
-#define        nDRIVE_VBUS_ON_ENA  0x0       
 #define        DRIVE_VBUS_OFF_ENA  0x2        /* enable DRIVE_VBUS_OFF interrupt */
-#define       nDRIVE_VBUS_OFF_ENA  0x0       
 #define       CHRG_VBUS_START_ENA  0x4        /* enable CHRG_VBUS_START interrupt */
-#define      nCHRG_VBUS_START_ENA  0x0       
 #define         CHRG_VBUS_END_ENA  0x8        /* enable CHRG_VBUS_END interrupt */
-#define        nCHRG_VBUS_END_ENA  0x0       
 #define    DISCHRG_VBUS_START_ENA  0x10       /* enable DISCHRG_VBUS_START interrupt */
-#define   nDISCHRG_VBUS_START_ENA  0x0       
 #define      DISCHRG_VBUS_END_ENA  0x20       /* enable DISCHRG_VBUS_END interrupt */
-#define     nDISCHRG_VBUS_END_ENA  0x0       
 
 /* Bit masks for USB_CSR0 */
 
 #define                  RXPKTRDY  0x1        /* data packet receive indicator */
-#define                 nRXPKTRDY  0x0       
 #define                  TXPKTRDY  0x2        /* data packet in FIFO indicator */
-#define                 nTXPKTRDY  0x0       
 #define                STALL_SENT  0x4        /* STALL handshake sent */
-#define               nSTALL_SENT  0x0       
 #define                   DATAEND  0x8        /* Data end indicator */
-#define                  nDATAEND  0x0       
 #define                  SETUPEND  0x10       /* Setup end */
-#define                 nSETUPEND  0x0       
 #define                 SENDSTALL  0x20       /* Send STALL handshake */
-#define                nSENDSTALL  0x0       
 #define         SERVICED_RXPKTRDY  0x40       /* used to clear the RxPktRdy bit */
-#define        nSERVICED_RXPKTRDY  0x0       
 #define         SERVICED_SETUPEND  0x80       /* used to clear the SetupEnd bit */
-#define        nSERVICED_SETUPEND  0x0       
 #define                 FLUSHFIFO  0x100      /* flush endpoint FIFO */
-#define                nFLUSHFIFO  0x0       
 #define          STALL_RECEIVED_H  0x4        /* STALL handshake received host mode */
-#define         nSTALL_RECEIVED_H  0x0       
 #define                SETUPPKT_H  0x8        /* send Setup token host mode */
-#define               nSETUPPKT_H  0x0       
 #define                   ERROR_H  0x10       /* timeout error indicator host mode */
-#define                  nERROR_H  0x0       
 #define                  REQPKT_H  0x20       /* Request an IN transaction host mode */
-#define                 nREQPKT_H  0x0       
 #define               STATUSPKT_H  0x40       /* Status stage transaction host mode */
-#define              nSTATUSPKT_H  0x0       
 #define             NAK_TIMEOUT_H  0x80       /* EP0 halted after a NAK host mode */
-#define            nNAK_TIMEOUT_H  0x0       
 
 /* Bit masks for USB_COUNT0 */
 
@@ -3213,37 +2535,21 @@
 /* Bit masks for USB_TXCSR */
 
 #define                TXPKTRDY_T  0x1        /* data packet in FIFO indicator */
-#define               nTXPKTRDY_T  0x0       
 #define          FIFO_NOT_EMPTY_T  0x2        /* FIFO not empty */
-#define         nFIFO_NOT_EMPTY_T  0x0       
 #define                UNDERRUN_T  0x4        /* TxPktRdy not set  for an IN token */
-#define               nUNDERRUN_T  0x0       
 #define               FLUSHFIFO_T  0x8        /* flush endpoint FIFO */
-#define              nFLUSHFIFO_T  0x0       
 #define              STALL_SEND_T  0x10       /* issue a Stall handshake */
-#define             nSTALL_SEND_T  0x0       
 #define              STALL_SENT_T  0x20       /* Stall handshake transmitted */
-#define             nSTALL_SENT_T  0x0       
 #define        CLEAR_DATATOGGLE_T  0x40       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_T  0x0       
 #define                INCOMPTX_T  0x80       /* indicates that a large packet is split */
-#define               nINCOMPTX_T  0x0       
 #define              DMAREQMODE_T  0x400      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_T  0x0       
 #define        FORCE_DATATOGGLE_T  0x800      /* Force data toggle */
-#define       nFORCE_DATATOGGLE_T  0x0       
 #define              DMAREQ_ENA_T  0x1000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_T  0x0       
 #define                     ISO_T  0x4000     /* enable Isochronous transfers */
-#define                    nISO_T  0x0       
 #define                 AUTOSET_T  0x8000     /* allows TxPktRdy to be set automatically */
-#define                nAUTOSET_T  0x0       
 #define                  ERROR_TH  0x4        /* error condition host mode */
-#define                 nERROR_TH  0x0       
 #define         STALL_RECEIVED_TH  0x20       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_TH  0x0       
 #define            NAK_TIMEOUT_TH  0x80       /* NAK timeout host mode */
-#define           nNAK_TIMEOUT_TH  0x0       
 
 /* Bit masks for USB_TXCOUNT */
 
@@ -3252,45 +2558,25 @@
 /* Bit masks for USB_RXCSR */
 
 #define                RXPKTRDY_R  0x1        /* data packet in FIFO indicator */
-#define               nRXPKTRDY_R  0x0       
 #define               FIFO_FULL_R  0x2        /* FIFO not empty */
-#define              nFIFO_FULL_R  0x0       
 #define                 OVERRUN_R  0x4        /* TxPktRdy not set  for an IN token */
-#define                nOVERRUN_R  0x0       
 #define               DATAERROR_R  0x8        /* Out packet cannot be loaded into Rx  FIFO */
-#define              nDATAERROR_R  0x0       
 #define               FLUSHFIFO_R  0x10       /* flush endpoint FIFO */
-#define              nFLUSHFIFO_R  0x0       
 #define              STALL_SEND_R  0x20       /* issue a Stall handshake */
-#define             nSTALL_SEND_R  0x0       
 #define              STALL_SENT_R  0x40       /* Stall handshake transmitted */
-#define             nSTALL_SENT_R  0x0       
 #define        CLEAR_DATATOGGLE_R  0x80       /* clear endpoint data toggle */
-#define       nCLEAR_DATATOGGLE_R  0x0       
 #define                INCOMPRX_R  0x100      /* indicates that a large packet is split */
-#define               nINCOMPRX_R  0x0       
 #define              DMAREQMODE_R  0x800      /* DMA mode (0 or 1) selection */
-#define             nDMAREQMODE_R  0x0       
 #define                 DISNYET_R  0x1000     /* disable Nyet handshakes */
-#define                nDISNYET_R  0x0       
 #define              DMAREQ_ENA_R  0x2000     /* Enable DMA request for Tx EP */
-#define             nDMAREQ_ENA_R  0x0       
 #define                     ISO_R  0x4000     /* enable Isochronous transfers */
-#define                    nISO_R  0x0       
 #define               AUTOCLEAR_R  0x8000     /* allows TxPktRdy to be set automatically */
-#define              nAUTOCLEAR_R  0x0       
 #define                  ERROR_RH  0x4        /* TxPktRdy not set  for an IN token host mode */
-#define                 nERROR_RH  0x0       
 #define                 REQPKT_RH  0x20       /* request an IN transaction host mode */
-#define                nREQPKT_RH  0x0       
 #define         STALL_RECEIVED_RH  0x40       /* Stall handshake received host mode */
-#define        nSTALL_RECEIVED_RH  0x0       
 #define               INCOMPRX_RH  0x100      /* indicates that a large packet is split host mode */
-#define              nINCOMPRX_RH  0x0       
 #define             DMAREQMODE_RH  0x800      /* DMA mode (0 or 1) selection host mode */
-#define            nDMAREQMODE_RH  0x0       
 #define                AUTOREQ_RH  0x4000     /* sets ReqPkt automatically host mode */
-#define               nAUTOREQ_RH  0x0       
 
 /* Bit masks for USB_RXCOUNT */
 
@@ -3317,35 +2603,22 @@
 /* Bit masks for USB_DMA_INTERRUPT */
 
 #define                  DMA0_INT  0x1        /* DMA0 pending interrupt */
-#define                 nDMA0_INT  0x0       
 #define                  DMA1_INT  0x2        /* DMA1 pending interrupt */
-#define                 nDMA1_INT  0x0       
 #define                  DMA2_INT  0x4        /* DMA2 pending interrupt */
-#define                 nDMA2_INT  0x0       
 #define                  DMA3_INT  0x8        /* DMA3 pending interrupt */
-#define                 nDMA3_INT  0x0       
 #define                  DMA4_INT  0x10       /* DMA4 pending interrupt */
-#define                 nDMA4_INT  0x0       
 #define                  DMA5_INT  0x20       /* DMA5 pending interrupt */
-#define                 nDMA5_INT  0x0       
 #define                  DMA6_INT  0x40       /* DMA6 pending interrupt */
-#define                 nDMA6_INT  0x0       
 #define                  DMA7_INT  0x80       /* DMA7 pending interrupt */
-#define                 nDMA7_INT  0x0       
 
 /* Bit masks for USB_DMAxCONTROL */
 
 #define                   DMA_ENA  0x1        /* DMA enable */
-#define                  nDMA_ENA  0x0       
 #define                 DIRECTION  0x2        /* direction of DMA transfer */
-#define                nDIRECTION  0x0       
 #define                      MODE  0x4        /* DMA Bus error */
-#define                     nMODE  0x0       
 #define                   INT_ENA  0x8        /* Interrupt enable */
-#define                  nINT_ENA  0x0       
 #define                     EPNUM  0xf0       /* EP number */
 #define                  BUSERROR  0x100      /* DMA Bus error */
-#define                 nBUSERROR  0x0       
 
 /* Bit masks for USB_DMAxADDRHIGH */
 
@@ -3366,26 +2639,16 @@
 /* Bit masks for HMDMAx_CONTROL */
 
 #define                   HMDMAEN  0x1        /* Handshake MDMA Enable */
-#define                  nHMDMAEN  0x0       
 #define                       REP  0x2        /* Handshake MDMA Request Polarity */
-#define                      nREP  0x0       
 #define                       UTE  0x8        /* Urgency Threshold Enable */
-#define                      nUTE  0x0       
 #define                       OIE  0x10       /* Overflow Interrupt Enable */
-#define                      nOIE  0x0       
 #define                      BDIE  0x20       /* Block Done Interrupt Enable */
-#define                     nBDIE  0x0       
 #define                      MBDI  0x40       /* Mask Block Done Interrupt */
-#define                     nMBDI  0x0       
 #define                       DRQ  0x300      /* Handshake MDMA Request Type */
 #define                       RBC  0x1000     /* Force Reload of BCOUNT */
-#define                      nRBC  0x0       
 #define                        PS  0x2000     /* Pin Status */
-#define                       nPS  0x0       
 #define                        OI  0x4000     /* Overflow Interrupt Generated */
-#define                       nOI  0x0       
 #define                       BDI  0x8000     /* Block Done Interrupt Generated */
-#define                      nBDI  0x0       
 
 /* ******************************************* */
 /*     MULTI BIT MACRO ENUMERATIONS            */
diff --git a/include/asm-blackfin/mach-bf548/defBF54x_base.h b/include/asm-blackfin/mach-bf548/defBF54x_base.h
index a1b200f..895ddd4 100644
--- a/include/asm-blackfin/mach-bf548/defBF54x_base.h
+++ b/include/asm-blackfin/mach-bf548/defBF54x_base.h
@@ -46,7 +46,7 @@
 
 /* Debug/MP/Emulation Registers (0xFFC00014 - 0xFFC00014) */
 
-#define                           CHIPID  0xffc00014   
+#define                           CHIPID  0xffc00014
 
 /* System Reset and Interrupt Controller (0xFFC00100 - 0xFFC00104) */
 
@@ -1512,231 +1512,144 @@
 /*     and MULTI BIT READ MACROS                              */
 /* ********************************************************** */
 
+/* SIC_IMASK Masks */
+#define SIC_UNMASK_ALL         0x00000000	/* Unmask all peripheral interrupts */
+#define SIC_MASK_ALL           0xFFFFFFFF	/* Mask all peripheral interrupts */
+#define SIC_MASK(x)	       (1 << (x))	/* Mask Peripheral #x interrupt */
+#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << (x)))	/* Unmask Peripheral #x interrupt */
+
+/* SIC_IWR Masks */
+#define IWR_DISABLE_ALL        0x00000000	/* Wakeup Disable all peripherals */
+#define IWR_ENABLE_ALL         0xFFFFFFFF	/* Wakeup Enable all peripherals */
+#define IWR_ENABLE(x)	       (1 << (x))	/* Wakeup Enable Peripheral #x */
+#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << (x)))	/* Wakeup Disable Peripheral #x */
+
 /* Bit masks for SIC_IAR0 */
 
-#define            IRQ_PLL_WAKEUP  0x1        /* PLL Wakeup */
-#define           nIRQ_PLL_WAKEUP  0x0       
+#define            PLL_WAKEUP  0x1        /* PLL Wakeup */
 
 /* Bit masks for SIC_IWR0, SIC_IMASK0, SIC_ISR0 */
 
-#define              IRQ_DMA0_ERR  0x2        /* DMA Controller 0 Error */
-#define             nIRQ_DMA0_ERR  0x0       
-#define             IRQ_EPPI0_ERR  0x4        /* EPPI0 Error */
-#define            nIRQ_EPPI0_ERR  0x0       
-#define            IRQ_SPORT0_ERR  0x8        /* SPORT0 Error */
-#define           nIRQ_SPORT0_ERR  0x0       
-#define            IRQ_SPORT1_ERR  0x10       /* SPORT1 Error */
-#define           nIRQ_SPORT1_ERR  0x0       
-#define              IRQ_SPI0_ERR  0x20       /* SPI0 Error */
-#define             nIRQ_SPI0_ERR  0x0       
-#define             IRQ_UART0_ERR  0x40       /* UART0 Error */
-#define            nIRQ_UART0_ERR  0x0       
-#define                   IRQ_RTC  0x80       /* Real-Time Clock */
-#define                  nIRQ_RTC  0x0       
-#define                 IRQ_DMA12  0x100      /* DMA Channel 12 */
-#define                nIRQ_DMA12  0x0       
-#define                  IRQ_DMA0  0x200      /* DMA Channel 0 */
-#define                 nIRQ_DMA0  0x0       
-#define                  IRQ_DMA1  0x400      /* DMA Channel 1 */
-#define                 nIRQ_DMA1  0x0       
-#define                  IRQ_DMA2  0x800      /* DMA Channel 2 */
-#define                 nIRQ_DMA2  0x0       
-#define                  IRQ_DMA3  0x1000     /* DMA Channel 3 */
-#define                 nIRQ_DMA3  0x0       
-#define                  IRQ_DMA4  0x2000     /* DMA Channel 4 */
-#define                 nIRQ_DMA4  0x0       
-#define                  IRQ_DMA6  0x4000     /* DMA Channel 6 */
-#define                 nIRQ_DMA6  0x0       
-#define                  IRQ_DMA7  0x8000     /* DMA Channel 7 */
-#define                 nIRQ_DMA7  0x0       
-#define                 IRQ_PINT0  0x80000    /* Pin Interrupt 0 */
-#define                nIRQ_PINT0  0x0       
-#define                 IRQ_PINT1  0x100000   /* Pin Interrupt 1 */
-#define                nIRQ_PINT1  0x0       
-#define                 IRQ_MDMA0  0x200000   /* Memory DMA Stream 0 */
-#define                nIRQ_MDMA0  0x0       
-#define                 IRQ_MDMA1  0x400000   /* Memory DMA Stream 1 */
-#define                nIRQ_MDMA1  0x0       
-#define                  IRQ_WDOG  0x800000   /* Watchdog Timer */
-#define                 nIRQ_WDOG  0x0       
-#define              IRQ_DMA1_ERR  0x1000000  /* DMA Controller 1 Error */
-#define             nIRQ_DMA1_ERR  0x0       
-#define            IRQ_SPORT2_ERR  0x2000000  /* SPORT2 Error */
-#define           nIRQ_SPORT2_ERR  0x0       
-#define            IRQ_SPORT3_ERR  0x4000000  /* SPORT3 Error */
-#define           nIRQ_SPORT3_ERR  0x0       
-#define               IRQ_MXVR_SD  0x8000000  /* MXVR Synchronous Data */
-#define              nIRQ_MXVR_SD  0x0       
-#define              IRQ_SPI1_ERR  0x10000000 /* SPI1 Error */
-#define             nIRQ_SPI1_ERR  0x0       
-#define              IRQ_SPI2_ERR  0x20000000 /* SPI2 Error */
-#define             nIRQ_SPI2_ERR  0x0       
-#define             IRQ_UART1_ERR  0x40000000 /* UART1 Error */
-#define            nIRQ_UART1_ERR  0x0       
-#define             IRQ_UART2_ERR  0x80000000 /* UART2 Error */
-#define            nIRQ_UART2_ERR  0x0       
+#define              DMA0_ERR  0x2        /* DMA Controller 0 Error */
+#define             EPPI0_ERR  0x4        /* EPPI0 Error */
+#define            SPORT0_ERR  0x8        /* SPORT0 Error */
+#define            SPORT1_ERR  0x10       /* SPORT1 Error */
+#define              SPI0_ERR  0x20       /* SPI0 Error */
+#define             UART0_ERR  0x40       /* UART0 Error */
+#define                   RTC  0x80       /* Real-Time Clock */
+#define                 DMA12  0x100      /* DMA Channel 12 */
+#define                  DMA0  0x200      /* DMA Channel 0 */
+#define                  DMA1  0x400      /* DMA Channel 1 */
+#define                  DMA2  0x800      /* DMA Channel 2 */
+#define                  DMA3  0x1000     /* DMA Channel 3 */
+#define                  DMA4  0x2000     /* DMA Channel 4 */
+#define                  DMA6  0x4000     /* DMA Channel 6 */
+#define                  DMA7  0x8000     /* DMA Channel 7 */
+#define                 PINT0  0x80000    /* Pin Interrupt 0 */
+#define                 PINT1  0x100000   /* Pin Interrupt 1 */
+#define                 MDMA0  0x200000   /* Memory DMA Stream 0 */
+#define                 MDMA1  0x400000   /* Memory DMA Stream 1 */
+#define                  WDOG  0x800000   /* Watchdog Timer */
+#define              DMA1_ERR  0x1000000  /* DMA Controller 1 Error */
+#define            SPORT2_ERR  0x2000000  /* SPORT2 Error */
+#define            SPORT3_ERR  0x4000000  /* SPORT3 Error */
+#define               MXVR_SD  0x8000000  /* MXVR Synchronous Data */
+#define              SPI1_ERR  0x10000000 /* SPI1 Error */
+#define              SPI2_ERR  0x20000000 /* SPI2 Error */
+#define             UART1_ERR  0x40000000 /* UART1 Error */
+#define             UART2_ERR  0x80000000 /* UART2 Error */
 
 /* Bit masks for SIC_IWR1, SIC_IMASK1, SIC_ISR1 */
 
-#define              IRQ_CAN0_ERR  0x1        /* CAN0 Error */
-#define             nIRQ_CAN0_ERR  0x0       
-#define                 IRQ_DMA18  0x2        /* DMA Channel 18 */
-#define                nIRQ_DMA18  0x0       
-#define                 IRQ_DMA19  0x4        /* DMA Channel 19 */
-#define                nIRQ_DMA19  0x0       
-#define                 IRQ_DMA20  0x8        /* DMA Channel 20 */
-#define                nIRQ_DMA20  0x0       
-#define                 IRQ_DMA21  0x10       /* DMA Channel 21 */
-#define                nIRQ_DMA21  0x0       
-#define                 IRQ_DMA13  0x20       /* DMA Channel 13 */
-#define                nIRQ_DMA13  0x0       
-#define                 IRQ_DMA14  0x40       /* DMA Channel 14 */
-#define                nIRQ_DMA14  0x0       
-#define                  IRQ_DMA5  0x80       /* DMA Channel 5 */
-#define                 nIRQ_DMA5  0x0       
-#define                 IRQ_DMA23  0x100      /* DMA Channel 23 */
-#define                nIRQ_DMA23  0x0       
-#define                  IRQ_DMA8  0x200      /* DMA Channel 8 */
-#define                 nIRQ_DMA8  0x0       
-#define                  IRQ_DMA9  0x400      /* DMA Channel 9 */
-#define                 nIRQ_DMA9  0x0       
-#define                 IRQ_DMA10  0x800      /* DMA Channel 10 */
-#define                nIRQ_DMA10  0x0       
-#define                 IRQ_DMA11  0x1000     /* DMA Channel 11 */
-#define                nIRQ_DMA11  0x0       
-#define                  IRQ_TWI0  0x2000     /* TWI0 */
-#define                 nIRQ_TWI0  0x0       
-#define                  IRQ_TWI1  0x4000     /* TWI1 */
-#define                 nIRQ_TWI1  0x0       
-#define               IRQ_CAN0_RX  0x8000     /* CAN0 Receive */
-#define              nIRQ_CAN0_RX  0x0       
-#define               IRQ_CAN0_TX  0x10000    /* CAN0 Transmit */
-#define              nIRQ_CAN0_TX  0x0       
-#define                 IRQ_MDMA2  0x20000    /* Memory DMA Stream 0 */
-#define                nIRQ_MDMA2  0x0       
-#define                 IRQ_MDMA3  0x40000    /* Memory DMA Stream 1 */
-#define                nIRQ_MDMA3  0x0       
-#define             IRQ_MXVR_STAT  0x80000    /* MXVR Status */
-#define            nIRQ_MXVR_STAT  0x0       
-#define               IRQ_MXVR_CM  0x100000   /* MXVR Control Message */
-#define              nIRQ_MXVR_CM  0x0       
-#define               IRQ_MXVR_AP  0x200000   /* MXVR Asynchronous Packet */
-#define              nIRQ_MXVR_AP  0x0       
-#define             IRQ_EPPI1_ERR  0x400000   /* EPPI1 Error */
-#define            nIRQ_EPPI1_ERR  0x0       
-#define             IRQ_EPPI2_ERR  0x800000   /* EPPI2 Error */
-#define            nIRQ_EPPI2_ERR  0x0       
-#define             IRQ_UART3_ERR  0x1000000  /* UART3 Error */
-#define            nIRQ_UART3_ERR  0x0       
-#define              IRQ_HOST_ERR  0x2000000  /* Host DMA Port Error */
-#define             nIRQ_HOST_ERR  0x0       
-#define               IRQ_USB_ERR  0x4000000  /* USB Error */
-#define              nIRQ_USB_ERR  0x0       
-#define              IRQ_PIXC_ERR  0x8000000  /* Pixel Compositor Error */
-#define             nIRQ_PIXC_ERR  0x0       
-#define               IRQ_NFC_ERR  0x10000000 /* Nand Flash Controller Error */
-#define              nIRQ_NFC_ERR  0x0       
-#define             IRQ_ATAPI_ERR  0x20000000 /* ATAPI Error */
-#define            nIRQ_ATAPI_ERR  0x0       
-#define              IRQ_CAN1_ERR  0x40000000 /* CAN1 Error */
-#define             nIRQ_CAN1_ERR  0x0       
-#define             IRQ_DMAR0_ERR  0x80000000 /* DMAR0 Overflow Error */
-#define            nIRQ_DMAR0_ERR  0x0       
-#define             IRQ_DMAR1_ERR  0x80000000 /* DMAR1 Overflow Error */
-#define            nIRQ_DMAR1_ERR  0x0       
-#define                 IRQ_DMAR0  0x80000000 /* DMAR0 Block */
-#define                nIRQ_DMAR0  0x0       
-#define                 IRQ_DMAR1  0x80000000 /* DMAR1 Block */
-#define                nIRQ_DMAR1  0x0       
+#define              CAN0_ERR  0x1        /* CAN0 Error */
+#define                 DMA18  0x2        /* DMA Channel 18 */
+#define                 DMA19  0x4        /* DMA Channel 19 */
+#define                 DMA20  0x8        /* DMA Channel 20 */
+#define                 DMA21  0x10       /* DMA Channel 21 */
+#define                 DMA13  0x20       /* DMA Channel 13 */
+#define                 DMA14  0x40       /* DMA Channel 14 */
+#define                  DMA5  0x80       /* DMA Channel 5 */
+#define                 DMA23  0x100      /* DMA Channel 23 */
+#define                  DMA8  0x200      /* DMA Channel 8 */
+#define                  DMA9  0x400      /* DMA Channel 9 */
+#define                 DMA10  0x800      /* DMA Channel 10 */
+#define                 DMA11  0x1000     /* DMA Channel 11 */
+#define                  TWI0  0x2000     /* TWI0 */
+#define                  TWI1  0x4000     /* TWI1 */
+#define               CAN0_RX  0x8000     /* CAN0 Receive */
+#define               CAN0_TX  0x10000    /* CAN0 Transmit */
+#define                 MDMA2  0x20000    /* Memory DMA Stream 0 */
+#define                 MDMA3  0x40000    /* Memory DMA Stream 1 */
+#define             MXVR_STAT  0x80000    /* MXVR Status */
+#define               MXVR_CM  0x100000   /* MXVR Control Message */
+#define               MXVR_AP  0x200000   /* MXVR Asynchronous Packet */
+#define             EPPI1_ERR  0x400000   /* EPPI1 Error */
+#define             EPPI2_ERR  0x800000   /* EPPI2 Error */
+#define             UART3_ERR  0x1000000  /* UART3 Error */
+#define              HOST_ERR  0x2000000  /* Host DMA Port Error */
+#define               USB_ERR  0x4000000  /* USB Error */
+#define              PIXC_ERR  0x8000000  /* Pixel Compositor Error */
+#define               NFC_ERR  0x10000000 /* Nand Flash Controller Error */
+#define             ATAPI_ERR  0x20000000 /* ATAPI Error */
+#define              CAN1_ERR  0x40000000 /* CAN1 Error */
+#define             DMAR0_ERR  0x80000000 /* DMAR0 Overflow Error */
+#define             DMAR1_ERR  0x80000000 /* DMAR1 Overflow Error */
+#define                 DMAR0  0x80000000 /* DMAR0 Block */
+#define                 DMAR1  0x80000000 /* DMAR1 Block */
 
 /* Bit masks for SIC_IWR2, SIC_IMASK2, SIC_ISR2 */
 
-#define                 IRQ_DMA15  0x1        /* DMA Channel 15 */
-#define                nIRQ_DMA15  0x0       
-#define                 IRQ_DMA16  0x2        /* DMA Channel 16 */
-#define                nIRQ_DMA16  0x0       
-#define                 IRQ_DMA17  0x4        /* DMA Channel 17 */
-#define                nIRQ_DMA17  0x0       
-#define                 IRQ_DMA22  0x8        /* DMA Channel 22 */
-#define                nIRQ_DMA22  0x0       
-#define                   IRQ_CNT  0x10       /* Counter */
-#define                  nIRQ_CNT  0x0       
-#define                   IRQ_KEY  0x20       /* Keypad */
-#define                  nIRQ_KEY  0x0       
-#define               IRQ_CAN1_RX  0x40       /* CAN1 Receive */
-#define              nIRQ_CAN1_RX  0x0       
-#define               IRQ_CAN1_TX  0x80       /* CAN1 Transmit */
-#define              nIRQ_CAN1_TX  0x0       
-#define             IRQ_SDH_MASK0  0x100      /* SDH Mask 0 */
-#define            nIRQ_SDH_MASK0  0x0       
-#define             IRQ_SDH_MASK1  0x200      /* SDH Mask 1 */
-#define            nIRQ_SDH_MASK1  0x0       
-#define              IRQ_USB_EINT  0x400      /* USB Exception */
-#define             nIRQ_USB_EINT  0x0       
-#define              IRQ_USB_INT0  0x800      /* USB Interrupt 0 */
-#define             nIRQ_USB_INT0  0x0       
-#define              IRQ_USB_INT1  0x1000     /* USB Interrupt 1 */
-#define             nIRQ_USB_INT1  0x0       
-#define              IRQ_USB_INT2  0x2000     /* USB Interrupt 2 */
-#define             nIRQ_USB_INT2  0x0       
-#define            IRQ_USB_DMAINT  0x4000     /* USB DMA */
-#define           nIRQ_USB_DMAINT  0x0       
-#define                IRQ_OTPSEC  0x8000     /* OTP Access Complete */
-#define               nIRQ_OTPSEC  0x0       
-#define                IRQ_TIMER0  0x400000   /* Timer 0 */
-#define               nIRQ_TIMER0  0x0       
-#define                IRQ_TIMER1  0x800000   /* Timer 1 */
-#define               nIRQ_TIMER1  0x0       
-#define                IRQ_TIMER2  0x1000000  /* Timer 2 */
-#define               nIRQ_TIMER2  0x0       
-#define                IRQ_TIMER3  0x2000000  /* Timer 3 */
-#define               nIRQ_TIMER3  0x0       
-#define                IRQ_TIMER4  0x4000000  /* Timer 4 */
-#define               nIRQ_TIMER4  0x0       
-#define                IRQ_TIMER5  0x8000000  /* Timer 5 */
-#define               nIRQ_TIMER5  0x0       
-#define                IRQ_TIMER6  0x10000000 /* Timer 6 */
-#define               nIRQ_TIMER6  0x0       
-#define                IRQ_TIMER7  0x20000000 /* Timer 7 */
-#define               nIRQ_TIMER7  0x0       
-#define                 IRQ_PINT2  0x40000000 /* Pin Interrupt 2 */
-#define                nIRQ_PINT2  0x0       
-#define                 IRQ_PINT3  0x80000000 /* Pin Interrupt 3 */
-#define                nIRQ_PINT3  0x0       
+#define                 DMA15  0x1        /* DMA Channel 15 */
+#define                 DMA16  0x2        /* DMA Channel 16 */
+#define                 DMA17  0x4        /* DMA Channel 17 */
+#define                 DMA22  0x8        /* DMA Channel 22 */
+#define                   CNT  0x10       /* Counter */
+#define                   KEY  0x20       /* Keypad */
+#define               CAN1_RX  0x40       /* CAN1 Receive */
+#define               CAN1_TX  0x80       /* CAN1 Transmit */
+#define             SDH_INT_MASK0  0x100      /* SDH Mask 0 */
+#define             SDH_INT_MASK1  0x200      /* SDH Mask 1 */
+#define              USB_EINT  0x400      /* USB Exception */
+#define              USB_INT0  0x800      /* USB Interrupt 0 */
+#define              USB_INT1  0x1000     /* USB Interrupt 1 */
+#define              USB_INT2  0x2000     /* USB Interrupt 2 */
+#define            USB_DMAINT  0x4000     /* USB DMA */
+#define                OTPSEC  0x8000     /* OTP Access Complete */
+#define                TIMER0  0x400000   /* Timer 0 */
+#define                TIMER1  0x800000   /* Timer 1 */
+#define                TIMER2  0x1000000  /* Timer 2 */
+#define                TIMER3  0x2000000  /* Timer 3 */
+#define                TIMER4  0x4000000  /* Timer 4 */
+#define                TIMER5  0x8000000  /* Timer 5 */
+#define                TIMER6  0x10000000 /* Timer 6 */
+#define                TIMER7  0x20000000 /* Timer 7 */
+#define                 PINT2  0x40000000 /* Pin Interrupt 2 */
+#define                 PINT3  0x80000000 /* Pin Interrupt 3 */
 
 /* Bit masks for DMAx_CONFIG, MDMA_Sx_CONFIG, MDMA_Dx_CONFIG */
 
 #define                     DMAEN  0x1        /* DMA Channel Enable */
-#define                    nDMAEN  0x0       
 #define                       WNR  0x2        /* DMA Direction */
-#define                      nWNR  0x0       
-#define                    WDSIZE  0xc        /* Transfer Word Size */
+#define                  WDSIZE_8  0x0        /* Transfer Word Size = 8 */
+#define                 WDSIZE_16  0x4        /* Transfer Word Size = 16 */
+#define                 WDSIZE_32  0x8        /* Transfer Word Size = 32 */
 #define                     DMA2D  0x10       /* DMA Mode */
-#define                    nDMA2D  0x0       
 #define                   RESTART  0x20       /* Work Unit Transitions */
-#define                  nRESTART  0x0       
 #define                    DI_SEL  0x40       /* Data Interrupt Timing Select */
-#define                   nDI_SEL  0x0       
 #define                     DI_EN  0x80       /* Data Interrupt Enable */
-#define                    nDI_EN  0x0       
 #define                    NDSIZE  0xf00      /* Flex Descriptor Size */
 #define                   DMAFLOW  0xf000     /* Next Operation */
 
 /* Bit masks for DMAx_IRQ_STATUS, MDMA_Sx_IRQ_STATUS, MDMA_Dx_IRQ_STATUS */
 
 #define                  DMA_DONE  0x1        /* DMA Completion Interrupt Status */
-#define                 nDMA_DONE  0x0       
 #define                   DMA_ERR  0x2        /* DMA Error Interrupt Status */
-#define                  nDMA_ERR  0x0       
 #define                    DFETCH  0x4        /* DMA Descriptor Fetch */
-#define                   nDFETCH  0x0       
 #define                   DMA_RUN  0x8        /* DMA Channel Running */
-#define                  nDMA_RUN  0x0       
 
 /* Bit masks for DMAx_PERIPHERAL_MAP, MDMA_Sx_IRQ_STATUS, MDMA_Dx_IRQ_STATUS */
 
 #define                     CTYPE  0x40       /* DMA Channel Type */
-#define                    nCTYPE  0x0       
 #define                      PMAP  0xf000     /* Peripheral Mapped To This Channel */
 
 /* Bit masks for DMACx_TCPER */
@@ -1756,29 +1669,28 @@
 /* Bit masks for DMAC1_PERIMUX */
 
 #define                   PMUXSDH  0x1        /* Peripheral Select for DMA22 channel */
-#define                  nPMUXSDH  0x0       
 
-/* Bit masks for EBIU_AMGCTL */
+/* *********************  ASYNCHRONOUS MEMORY CONTROLLER MASKS  *************************/
+/* EBIU_AMGCTL Masks																	*/
+#define AMCKEN			0x0001		/* Enable CLKOUT									*/
+#define	AMBEN_NONE		0x0000		/* All Banks Disabled								*/
+#define AMBEN_B0		0x0002		/* Enable Async Memory Bank 0 only					*/
+#define AMBEN_B0_B1		0x0004		/* Enable Async Memory Banks 0 & 1 only				*/
+#define AMBEN_B0_B1_B2	0x0006		/* Enable Async Memory Banks 0, 1, and 2			*/
+#define AMBEN_ALL		0x0008		/* Enable Async Memory Banks (all) 0, 1, 2, and 3	*/
 
-#define                    AMCKEN  0x1        /* Async Memory Enable */
-#define                   nAMCKEN  0x0       
-#define                     AMBEN  0xe        /* Async bank enable */
 
 /* Bit masks for EBIU_AMBCTL0 */
 
 #define                   B0RDYEN  0x1        /* Bank 0 ARDY Enable */
-#define                  nB0RDYEN  0x0       
 #define                  B0RDYPOL  0x2        /* Bank 0 ARDY Polarity */
-#define                 nB0RDYPOL  0x0       
 #define                      B0TT  0xc        /* Bank 0 transition time */
 #define                      B0ST  0x30       /* Bank 0 Setup time */
 #define                      B0HT  0xc0       /* Bank 0 Hold time */
 #define                     B0RAT  0xf00      /* Bank 0 Read access time */
 #define                     B0WAT  0xf000     /* Bank 0 write access time */
 #define                   B1RDYEN  0x10000    /* Bank 1 ARDY Enable */
-#define                  nB1RDYEN  0x0       
 #define                  B1RDYPOL  0x20000    /* Bank 1 ARDY Polarity */
-#define                 nB1RDYPOL  0x0       
 #define                      B1TT  0xc0000    /* Bank 1 transition time */
 #define                      B1ST  0x300000   /* Bank 1 Setup time */
 #define                      B1HT  0xc00000   /* Bank 1 Hold time */
@@ -1788,18 +1700,14 @@
 /* Bit masks for EBIU_AMBCTL1 */
 
 #define                   B2RDYEN  0x1        /* Bank 2 ARDY Enable */
-#define                  nB2RDYEN  0x0       
 #define                  B2RDYPOL  0x2        /* Bank 2 ARDY Polarity */
-#define                 nB2RDYPOL  0x0       
 #define                      B2TT  0xc        /* Bank 2 transition time */
 #define                      B2ST  0x30       /* Bank 2 Setup time */
 #define                      B2HT  0xc0       /* Bank 2 Hold time */
 #define                     B2RAT  0xf00      /* Bank 2 Read access time */
 #define                     B2WAT  0xf000     /* Bank 2 write access time */
 #define                   B3RDYEN  0x10000    /* Bank 3 ARDY Enable */
-#define                  nB3RDYEN  0x0       
 #define                  B3RDYPOL  0x20000    /* Bank 3 ARDY Polarity */
-#define                 nB3RDYPOL  0x0       
 #define                      B3TT  0xc0000    /* Bank 3 transition time */
 #define                      B3ST  0x300000   /* Bank 3 Setup time */
 #define                      B3HT  0xc00000   /* Bank 3 Hold time */
@@ -1823,19 +1731,15 @@
 /* Bit masks for EBIU_FCTL */
 
 #define               TESTSETLOCK  0x1        /* Test set lock */
-#define              nTESTSETLOCK  0x0       
 #define                      BCLK  0x6        /* Burst clock frequency */
 #define                      PGWS  0x38       /* Page wait states */
 #define                      PGSZ  0x40       /* Page size */
-#define                     nPGSZ  0x0       
 #define                      RDDL  0x380      /* Read data delay */
 
 /* Bit masks for EBIU_ARBSTAT */
 
 #define                   ARBSTAT  0x1        /* Arbitration status */
-#define                  nARBSTAT  0x0       
 #define                    BGSTAT  0x2        /* Bus grant status */
-#define                   nBGSTAT  0x0       
 
 /* Bit masks for EBIU_DDRCTL0 */
 
@@ -1861,9 +1765,7 @@
 #define               BURSTLENGTH  0x7        /* Burst length */
 #define                CASLATENCY  0x70       /* CAS latency */
 #define                  DLLRESET  0x100      /* DLL Reset */
-#define                 nDLLRESET  0x0       
 #define                      REGE  0x1000     /* Register mode enable */
-#define                     nREGE  0x0       
 
 /* Bit masks for EBIU_DDRCTL3 */
 
@@ -1876,30 +1778,19 @@
 #define                DEB3_PFLEN  0x30       /* Pre fetch length for DEB3 accesses */
 #define          DEB_ARB_PRIORITY  0x700      /* Arbitration between DEB busses */
 #define               DEB1_URGENT  0x1000     /* DEB1 Urgent */
-#define              nDEB1_URGENT  0x0       
 #define               DEB2_URGENT  0x2000     /* DEB2 Urgent */
-#define              nDEB2_URGENT  0x0       
 #define               DEB3_URGENT  0x4000     /* DEB3 Urgent */
-#define              nDEB3_URGENT  0x0       
 
 /* Bit masks for EBIU_ERRMST */
 
 #define                DEB1_ERROR  0x1        /* DEB1 Error */
-#define               nDEB1_ERROR  0x0       
 #define                DEB2_ERROR  0x2        /* DEB2 Error */
-#define               nDEB2_ERROR  0x0       
 #define                DEB3_ERROR  0x4        /* DEB3 Error */
-#define               nDEB3_ERROR  0x0       
 #define                CORE_ERROR  0x8        /* Core error */
-#define               nCORE_ERROR  0x0       
 #define                DEB_MERROR  0x10       /* DEB1 Error (2nd) */
-#define               nDEB_MERROR  0x0       
 #define               DEB2_MERROR  0x20       /* DEB2 Error (2nd) */
-#define              nDEB2_MERROR  0x0       
 #define               DEB3_MERROR  0x40       /* DEB3 Error (2nd) */
-#define              nDEB3_MERROR  0x0       
 #define               CORE_MERROR  0x80       /* Core Error (2nd) */
-#define              nCORE_MERROR  0x0       
 
 /* Bit masks for EBIU_ERRADD */
 
@@ -1908,15 +1799,10 @@
 /* Bit masks for EBIU_RSTCTL */
 
 #define                 DDRSRESET  0x1        /* DDR soft reset */
-#define                nDDRSRESET  0x0       
 #define               PFTCHSRESET  0x4        /* DDR prefetch reset */
-#define              nPFTCHSRESET  0x0       
 #define                     SRREQ  0x8        /* Self-refresh request */
-#define                    nSRREQ  0x0       
 #define                     SRACK  0x10       /* Self-refresh acknowledge */
-#define                    nSRACK  0x0       
 #define                MDDRENABLE  0x20       /* Mobile DDR enable */
-#define               nMDDRENABLE  0x0       
 
 /* Bit masks for EBIU_DDRBRC0 */
 
@@ -2013,136 +1899,74 @@
 /* Bit masks for EBIU_DDRMCEN */
 
 #define                B0WCENABLE  0x1        /* Bank 0 write count enable */
-#define               nB0WCENABLE  0x0       
 #define                B1WCENABLE  0x2        /* Bank 1 write count enable */
-#define               nB1WCENABLE  0x0       
 #define                B2WCENABLE  0x4        /* Bank 2 write count enable */
-#define               nB2WCENABLE  0x0       
 #define                B3WCENABLE  0x8        /* Bank 3 write count enable */
-#define               nB3WCENABLE  0x0       
 #define                B4WCENABLE  0x10       /* Bank 4 write count enable */
-#define               nB4WCENABLE  0x0       
 #define                B5WCENABLE  0x20       /* Bank 5 write count enable */
-#define               nB5WCENABLE  0x0       
 #define                B6WCENABLE  0x40       /* Bank 6 write count enable */
-#define               nB6WCENABLE  0x0       
 #define                B7WCENABLE  0x80       /* Bank 7 write count enable */
-#define               nB7WCENABLE  0x0       
 #define                B0RCENABLE  0x100      /* Bank 0 read count enable */
-#define               nB0RCENABLE  0x0       
 #define                B1RCENABLE  0x200      /* Bank 1 read count enable */
-#define               nB1RCENABLE  0x0       
 #define                B2RCENABLE  0x400      /* Bank 2 read count enable */
-#define               nB2RCENABLE  0x0       
 #define                B3RCENABLE  0x800      /* Bank 3 read count enable */
-#define               nB3RCENABLE  0x0       
 #define                B4RCENABLE  0x1000     /* Bank 4 read count enable */
-#define               nB4RCENABLE  0x0       
 #define                B5RCENABLE  0x2000     /* Bank 5 read count enable */
-#define               nB5RCENABLE  0x0       
 #define                B6RCENABLE  0x4000     /* Bank 6 read count enable */
-#define               nB6RCENABLE  0x0       
 #define                B7RCENABLE  0x8000     /* Bank 7 read count enable */
-#define               nB7RCENABLE  0x0       
 #define             ROWACTCENABLE  0x10000    /* DDR Row activate count enable */
-#define            nROWACTCENABLE  0x0       
 #define                RWTCENABLE  0x20000    /* DDR R/W Turn around count enable */
-#define               nRWTCENABLE  0x0       
 #define                 ARCENABLE  0x40000    /* DDR Auto-refresh count enable */
-#define                nARCENABLE  0x0       
 #define                 GC0ENABLE  0x100000   /* DDR Grant count 0 enable */
-#define                nGC0ENABLE  0x0       
 #define                 GC1ENABLE  0x200000   /* DDR Grant count 1 enable */
-#define                nGC1ENABLE  0x0       
 #define                 GC2ENABLE  0x400000   /* DDR Grant count 2 enable */
-#define                nGC2ENABLE  0x0       
 #define                 GC3ENABLE  0x800000   /* DDR Grant count 3 enable */
-#define                nGC3ENABLE  0x0       
 #define                 GCCONTROL  0x3000000  /* DDR Grant Count Control */
 
 /* Bit masks for EBIU_DDRMCCL */
 
 #define                 CB0WCOUNT  0x1        /* Clear write count 0 */
-#define                nCB0WCOUNT  0x0       
 #define                 CB1WCOUNT  0x2        /* Clear write count 1 */
-#define                nCB1WCOUNT  0x0       
 #define                 CB2WCOUNT  0x4        /* Clear write count 2 */
-#define                nCB2WCOUNT  0x0       
 #define                 CB3WCOUNT  0x8        /* Clear write count 3 */
-#define                nCB3WCOUNT  0x0       
 #define                 CB4WCOUNT  0x10       /* Clear write count 4 */
-#define                nCB4WCOUNT  0x0       
 #define                 CB5WCOUNT  0x20       /* Clear write count 5 */
-#define                nCB5WCOUNT  0x0       
 #define                 CB6WCOUNT  0x40       /* Clear write count 6 */
-#define                nCB6WCOUNT  0x0       
 #define                 CB7WCOUNT  0x80       /* Clear write count 7 */
-#define                nCB7WCOUNT  0x0       
 #define                  CBRCOUNT  0x100      /* Clear read count 0 */
-#define                 nCBRCOUNT  0x0       
 #define                 CB1RCOUNT  0x200      /* Clear read count 1 */
-#define                nCB1RCOUNT  0x0       
 #define                 CB2RCOUNT  0x400      /* Clear read count 2 */
-#define                nCB2RCOUNT  0x0       
 #define                 CB3RCOUNT  0x800      /* Clear read count 3 */
-#define                nCB3RCOUNT  0x0       
 #define                 CB4RCOUNT  0x1000     /* Clear read count 4 */
-#define                nCB4RCOUNT  0x0       
 #define                 CB5RCOUNT  0x2000     /* Clear read count 5 */
-#define                nCB5RCOUNT  0x0       
 #define                 CB6RCOUNT  0x4000     /* Clear read count 6 */
-#define                nCB6RCOUNT  0x0       
 #define                 CB7RCOUNT  0x8000     /* Clear read count 7 */
-#define                nCB7RCOUNT  0x0       
 #define                  CRACOUNT  0x10000    /* Clear row activation count */
-#define                 nCRACOUNT  0x0       
 #define                CRWTACOUNT  0x20000    /* Clear R/W turn-around count */
-#define               nCRWTACOUNT  0x0       
 #define                  CARCOUNT  0x40000    /* Clear auto-refresh count */
-#define                 nCARCOUNT  0x0       
 #define                  CG0COUNT  0x100000   /* Clear grant count 0 */
-#define                 nCG0COUNT  0x0       
 #define                  CG1COUNT  0x200000   /* Clear grant count 1 */
-#define                 nCG1COUNT  0x0       
 #define                  CG2COUNT  0x400000   /* Clear grant count 2 */
-#define                 nCG2COUNT  0x0       
 #define                  CG3COUNT  0x800000   /* Clear grant count 3 */
-#define                 nCG3COUNT  0x0       
 
 /* Bit masks for (PORTx is PORTA - PORTJ) includes PORTx_FER, PORTx_SET, PORTx_CLEAR, PORTx_DIR_SET, PORTx_DIR_CLEAR, PORTx_INEN */
 
 #define                       Px0  0x1        /* GPIO 0 */
-#define                      nPx0  0x0       
 #define                       Px1  0x2        /* GPIO 1 */
-#define                      nPx1  0x0       
 #define                       Px2  0x4        /* GPIO 2 */
-#define                      nPx2  0x0       
 #define                       Px3  0x8        /* GPIO 3 */
-#define                      nPx3  0x0       
 #define                       Px4  0x10       /* GPIO 4 */
-#define                      nPx4  0x0       
 #define                       Px5  0x20       /* GPIO 5 */
-#define                      nPx5  0x0       
 #define                       Px6  0x40       /* GPIO 6 */
-#define                      nPx6  0x0       
 #define                       Px7  0x80       /* GPIO 7 */
-#define                      nPx7  0x0       
 #define                       Px8  0x100      /* GPIO 8 */
-#define                      nPx8  0x0       
 #define                       Px9  0x200      /* GPIO 9 */
-#define                      nPx9  0x0       
 #define                      Px10  0x400      /* GPIO 10 */
-#define                     nPx10  0x0       
 #define                      Px11  0x800      /* GPIO 11 */
-#define                     nPx11  0x0       
 #define                      Px12  0x1000     /* GPIO 12 */
-#define                     nPx12  0x0       
 #define                      Px13  0x2000     /* GPIO 13 */
-#define                     nPx13  0x0       
 #define                      Px14  0x4000     /* GPIO 14 */
-#define                     nPx14  0x0       
 #define                      Px15  0x8000     /* GPIO 15 */
-#define                     nPx15  0x0       
 
 /* Bit masks for PORTA_MUX - PORTJ_MUX */
 
@@ -2167,223 +1991,129 @@
 /* Bit masks for PINTx_MASK_SET/CLEAR, PINTx_REQUEST, PINTx_LATCH, PINTx_EDGE_SET/CLEAR, PINTx_INVERT_SET/CLEAR, PINTx_PINTSTATE */
 
 #define                       IB0  0x1        /* Interrupt Bit 0 */
-#define                      nIB0  0x0       
 #define                       IB1  0x2        /* Interrupt Bit 1 */
-#define                      nIB1  0x0       
 #define                       IB2  0x4        /* Interrupt Bit 2 */
-#define                      nIB2  0x0       
 #define                       IB3  0x8        /* Interrupt Bit 3 */
-#define                      nIB3  0x0       
 #define                       IB4  0x10       /* Interrupt Bit 4 */
-#define                      nIB4  0x0       
 #define                       IB5  0x20       /* Interrupt Bit 5 */
-#define                      nIB5  0x0       
 #define                       IB6  0x40       /* Interrupt Bit 6 */
-#define                      nIB6  0x0       
 #define                       IB7  0x80       /* Interrupt Bit 7 */
-#define                      nIB7  0x0       
 #define                       IB8  0x100      /* Interrupt Bit 8 */
-#define                      nIB8  0x0       
 #define                       IB9  0x200      /* Interrupt Bit 9 */
-#define                      nIB9  0x0       
 #define                      IB10  0x400      /* Interrupt Bit 10 */
-#define                     nIB10  0x0       
 #define                      IB11  0x800      /* Interrupt Bit 11 */
-#define                     nIB11  0x0       
 #define                      IB12  0x1000     /* Interrupt Bit 12 */
-#define                     nIB12  0x0       
 #define                      IB13  0x2000     /* Interrupt Bit 13 */
-#define                     nIB13  0x0       
 #define                      IB14  0x4000     /* Interrupt Bit 14 */
-#define                     nIB14  0x0       
 #define                      IB15  0x8000     /* Interrupt Bit 15 */
-#define                     nIB15  0x0       
 
 /* Bit masks for TIMERx_CONFIG */
 
 #define                     TMODE  0x3        /* Timer Mode */
 #define                  PULSE_HI  0x4        /* Pulse Polarity */
-#define                 nPULSE_HI  0x0       
 #define                PERIOD_CNT  0x8        /* Period Count */
-#define               nPERIOD_CNT  0x0       
 #define                   IRQ_ENA  0x10       /* Interrupt Request Enable */
-#define                  nIRQ_ENA  0x0       
 #define                   TIN_SEL  0x20       /* Timer Input Select */
-#define                  nTIN_SEL  0x0       
 #define                   OUT_DIS  0x40       /* Output Pad Disable */
-#define                  nOUT_DIS  0x0       
 #define                   CLK_SEL  0x80       /* Timer Clock Select */
-#define                  nCLK_SEL  0x0       
 #define                 TOGGLE_HI  0x100      /* Toggle Mode */
-#define                nTOGGLE_HI  0x0       
 #define                   EMU_RUN  0x200      /* Emulation Behavior Select */
-#define                  nEMU_RUN  0x0       
 #define                   ERR_TYP  0xc000     /* Error Type */
 
 /* Bit masks for TIMER_ENABLE0 */
 
 #define                    TIMEN0  0x1        /* Timer 0 Enable */
-#define                   nTIMEN0  0x0       
 #define                    TIMEN1  0x2        /* Timer 1 Enable */
-#define                   nTIMEN1  0x0       
 #define                    TIMEN2  0x4        /* Timer 2 Enable */
-#define                   nTIMEN2  0x0       
 #define                    TIMEN3  0x8        /* Timer 3 Enable */
-#define                   nTIMEN3  0x0       
 #define                    TIMEN4  0x10       /* Timer 4 Enable */
-#define                   nTIMEN4  0x0       
 #define                    TIMEN5  0x20       /* Timer 5 Enable */
-#define                   nTIMEN5  0x0       
 #define                    TIMEN6  0x40       /* Timer 6 Enable */
-#define                   nTIMEN6  0x0       
 #define                    TIMEN7  0x80       /* Timer 7 Enable */
-#define                   nTIMEN7  0x0       
 
 /* Bit masks for TIMER_DISABLE0 */
 
 #define                   TIMDIS0  0x1        /* Timer 0 Disable */
-#define                  nTIMDIS0  0x0       
 #define                   TIMDIS1  0x2        /* Timer 1 Disable */
-#define                  nTIMDIS1  0x0       
 #define                   TIMDIS2  0x4        /* Timer 2 Disable */
-#define                  nTIMDIS2  0x0       
 #define                   TIMDIS3  0x8        /* Timer 3 Disable */
-#define                  nTIMDIS3  0x0       
 #define                   TIMDIS4  0x10       /* Timer 4 Disable */
-#define                  nTIMDIS4  0x0       
 #define                   TIMDIS5  0x20       /* Timer 5 Disable */
-#define                  nTIMDIS5  0x0       
 #define                   TIMDIS6  0x40       /* Timer 6 Disable */
-#define                  nTIMDIS6  0x0       
 #define                   TIMDIS7  0x80       /* Timer 7 Disable */
-#define                  nTIMDIS7  0x0       
 
 /* Bit masks for TIMER_STATUS0 */
 
 #define                    TIMIL0  0x1        /* Timer 0 Interrupt */
-#define                   nTIMIL0  0x0       
 #define                    TIMIL1  0x2        /* Timer 1 Interrupt */
-#define                   nTIMIL1  0x0       
 #define                    TIMIL2  0x4        /* Timer 2 Interrupt */
-#define                   nTIMIL2  0x0       
 #define                    TIMIL3  0x8        /* Timer 3 Interrupt */
-#define                   nTIMIL3  0x0       
 #define                 TOVF_ERR0  0x10       /* Timer 0 Counter Overflow */
-#define                nTOVF_ERR0  0x0       
 #define                 TOVF_ERR1  0x20       /* Timer 1 Counter Overflow */
-#define                nTOVF_ERR1  0x0       
 #define                 TOVF_ERR2  0x40       /* Timer 2 Counter Overflow */
-#define                nTOVF_ERR2  0x0       
 #define                 TOVF_ERR3  0x80       /* Timer 3 Counter Overflow */
-#define                nTOVF_ERR3  0x0       
 #define                     TRUN0  0x1000     /* Timer 0 Slave Enable Status */
-#define                    nTRUN0  0x0       
 #define                     TRUN1  0x2000     /* Timer 1 Slave Enable Status */
-#define                    nTRUN1  0x0       
 #define                     TRUN2  0x4000     /* Timer 2 Slave Enable Status */
-#define                    nTRUN2  0x0       
 #define                     TRUN3  0x8000     /* Timer 3 Slave Enable Status */
-#define                    nTRUN3  0x0       
 #define                    TIMIL4  0x10000    /* Timer 4 Interrupt */
-#define                   nTIMIL4  0x0       
 #define                    TIMIL5  0x20000    /* Timer 5 Interrupt */
-#define                   nTIMIL5  0x0       
 #define                    TIMIL6  0x40000    /* Timer 6 Interrupt */
-#define                   nTIMIL6  0x0       
 #define                    TIMIL7  0x80000    /* Timer 7 Interrupt */
-#define                   nTIMIL7  0x0       
 #define                 TOVF_ERR4  0x100000   /* Timer 4 Counter Overflow */
-#define                nTOVF_ERR4  0x0       
 #define                 TOVF_ERR5  0x200000   /* Timer 5 Counter Overflow */
-#define                nTOVF_ERR5  0x0       
 #define                 TOVF_ERR6  0x400000   /* Timer 6 Counter Overflow */
-#define                nTOVF_ERR6  0x0       
 #define                 TOVF_ERR7  0x800000   /* Timer 7 Counter Overflow */
-#define                nTOVF_ERR7  0x0       
 #define                     TRUN4  0x10000000 /* Timer 4 Slave Enable Status */
-#define                    nTRUN4  0x0       
 #define                     TRUN5  0x20000000 /* Timer 5 Slave Enable Status */
-#define                    nTRUN5  0x0       
 #define                     TRUN6  0x40000000 /* Timer 6 Slave Enable Status */
-#define                    nTRUN6  0x0       
 #define                     TRUN7  0x80000000 /* Timer 7 Slave Enable Status */
-#define                    nTRUN7  0x0       
 
 /* Bit masks for WDOG_CTL */
 
 #define                      WDEV  0x6        /* Watchdog Event */
 #define                      WDEN  0xff0      /* Watchdog Enable */
 #define                      WDRO  0x8000     /* Watchdog Rolled Over */
-#define                     nWDRO  0x0       
 
 /* Bit masks for CNT_CONFIG */
 
 #define                      CNTE  0x1        /* Counter Enable */
-#define                     nCNTE  0x0       
 #define                      DEBE  0x2        /* Debounce Enable */
-#define                     nDEBE  0x0       
 #define                    CDGINV  0x10       /* CDG Pin Polarity Invert */
-#define                   nCDGINV  0x0       
 #define                    CUDINV  0x20       /* CUD Pin Polarity Invert */
-#define                   nCUDINV  0x0       
 #define                    CZMINV  0x40       /* CZM Pin Polarity Invert */
-#define                   nCZMINV  0x0       
 #define                   CNTMODE  0x700      /* Counter Operating Mode */
 #define                      ZMZC  0x800      /* CZM Zeroes Counter Enable */
-#define                     nZMZC  0x0       
 #define                   BNDMODE  0x3000     /* Boundary register Mode */
 #define                    INPDIS  0x8000     /* CUG and CDG Input Disable */
-#define                   nINPDIS  0x0       
 
 /* Bit masks for CNT_IMASK */
 
 #define                      ICIE  0x1        /* Illegal Gray/Binary Code Interrupt Enable */
-#define                     nICIE  0x0       
 #define                      UCIE  0x2        /* Up count Interrupt Enable */
-#define                     nUCIE  0x0       
 #define                      DCIE  0x4        /* Down count Interrupt Enable */
-#define                     nDCIE  0x0       
 #define                    MINCIE  0x8        /* Min Count Interrupt Enable */
-#define                   nMINCIE  0x0       
 #define                    MAXCIE  0x10       /* Max Count Interrupt Enable */
-#define                   nMAXCIE  0x0       
 #define                   COV31IE  0x20       /* Bit 31 Overflow Interrupt Enable */
-#define                  nCOV31IE  0x0       
 #define                   COV15IE  0x40       /* Bit 15 Overflow Interrupt Enable */
-#define                  nCOV15IE  0x0       
 #define                   CZEROIE  0x80       /* Count to Zero Interrupt Enable */
-#define                  nCZEROIE  0x0       
 #define                     CZMIE  0x100      /* CZM Pin Interrupt Enable */
-#define                    nCZMIE  0x0       
 #define                    CZMEIE  0x200      /* CZM Error Interrupt Enable */
-#define                   nCZMEIE  0x0       
 #define                    CZMZIE  0x400      /* CZM Zeroes Counter Interrupt Enable */
-#define                   nCZMZIE  0x0       
 
 /* Bit masks for CNT_STATUS */
 
 #define                      ICII  0x1        /* Illegal Gray/Binary Code Interrupt Identifier */
-#define                     nICII  0x0       
 #define                      UCII  0x2        /* Up count Interrupt Identifier */
-#define                     nUCII  0x0       
 #define                      DCII  0x4        /* Down count Interrupt Identifier */
-#define                     nDCII  0x0       
 #define                    MINCII  0x8        /* Min Count Interrupt Identifier */
-#define                   nMINCII  0x0       
 #define                    MAXCII  0x10       /* Max Count Interrupt Identifier */
-#define                   nMAXCII  0x0       
 #define                   COV31II  0x20       /* Bit 31 Overflow Interrupt Identifier */
-#define                  nCOV31II  0x0       
 #define                   COV15II  0x40       /* Bit 15 Overflow Interrupt Identifier */
-#define                  nCOV15II  0x0       
 #define                   CZEROII  0x80       /* Count to Zero Interrupt Identifier */
-#define                  nCZEROII  0x0       
 #define                     CZMII  0x100      /* CZM Pin Interrupt Identifier */
-#define                    nCZMII  0x0       
 #define                    CZMEII  0x200      /* CZM Error Interrupt Identifier */
-#define                   nCZMEII  0x0       
 #define                    CZMZII  0x400      /* CZM Zeroes Counter Interrupt Identifier */
-#define                   nCZMZII  0x0       
 
 /* Bit masks for CNT_COMMAND */
 
@@ -2391,7 +2121,6 @@
 #define                    W1LMIN  0xf0       /* Load Min Register */
 #define                    W1LMAX  0xf00      /* Load Max Register */
 #define                  W1ZMONCE  0x1000     /* Enable CZM Clear Counter Once */
-#define                 nW1ZMONCE  0x0       
 
 /* Bit masks for CNT_DEBOUNCE */
 
@@ -2407,42 +2136,25 @@
 /* Bit masks for RTC_ICTL */
 
 #define STOPWATCH_INTERRUPT_ENABLE  0x1        /* Stopwatch Interrupt Enable */
-#define nSTOPWATCH_INTERRUPT_ENABLE  0x0       
 #define    ALARM_INTERRUPT_ENABLE  0x2        /* Alarm Interrupt Enable */
-#define   nALARM_INTERRUPT_ENABLE  0x0       
 #define  SECONDS_INTERRUPT_ENABLE  0x4        /* Seconds Interrupt Enable */
-#define nSECONDS_INTERRUPT_ENABLE  0x0       
 #define  MINUTES_INTERRUPT_ENABLE  0x8        /* Minutes Interrupt Enable */
-#define nMINUTES_INTERRUPT_ENABLE  0x0       
 #define    HOURS_INTERRUPT_ENABLE  0x10       /* Hours Interrupt Enable */
-#define   nHOURS_INTERRUPT_ENABLE  0x0       
 #define TWENTY_FOUR_HOURS_INTERRUPT_ENABLE  0x20       /* 24 Hours Interrupt Enable */
-#define nTWENTY_FOUR_HOURS_INTERRUPT_ENABLE  0x0       
 #define DAY_ALARM_INTERRUPT_ENABLE  0x40       /* Day Alarm Interrupt Enable */
-#define nDAY_ALARM_INTERRUPT_ENABLE  0x0       
 #define WRITE_COMPLETE_INTERRUPT_ENABLE  0x8000     /* Write Complete Interrupt Enable */
-#define nWRITE_COMPLETE_INTERRUPT_ENABLE  0x0       
 
 /* Bit masks for RTC_ISTAT */
 
 #define      STOPWATCH_EVENT_FLAG  0x1        /* Stopwatch Event Flag */
-#define     nSTOPWATCH_EVENT_FLAG  0x0       
 #define          ALARM_EVENT_FLAG  0x2        /* Alarm Event Flag */
-#define         nALARM_EVENT_FLAG  0x0       
 #define        SECONDS_EVENT_FLAG  0x4        /* Seconds Event Flag */
-#define       nSECONDS_EVENT_FLAG  0x0       
 #define        MINUTES_EVENT_FLAG  0x8        /* Minutes Event Flag */
-#define       nMINUTES_EVENT_FLAG  0x0       
 #define          HOURS_EVENT_FLAG  0x10       /* Hours Event Flag */
-#define         nHOURS_EVENT_FLAG  0x0       
 #define TWENTY_FOUR_HOURS_EVENT_FLAG  0x20       /* 24 Hours Event Flag */
-#define nTWENTY_FOUR_HOURS_EVENT_FLAG  0x0       
 #define      DAY_ALARM_EVENT_FLAG  0x40       /* Day Alarm Event Flag */
-#define     nDAY_ALARM_EVENT_FLAG  0x0       
 #define     WRITE_PENDING__STATUS  0x4000     /* Write Pending  Status */
-#define    nWRITE_PENDING__STATUS  0x0       
 #define            WRITE_COMPLETE  0x8000     /* Write Complete */
-#define           nWRITE_COMPLETE  0x0       
 
 /* Bit masks for RTC_SWCNT */
 
@@ -2458,21 +2170,15 @@
 /* Bit masks for RTC_PREN */
 
 #define                      PREN  0x1        /* Prescaler Enable */
-#define                     nPREN  0x0       
 
 /* Bit masks for OTP_CONTROL */
 
 #define                FUSE_FADDR  0x1ff      /* OTP/Fuse Address */
 #define                      FIEN  0x800      /* OTP/Fuse Interrupt Enable */
-#define                     nFIEN  0x0       
 #define                  FTESTDEC  0x1000     /* OTP/Fuse Test Decoder */
-#define                 nFTESTDEC  0x0       
 #define                   FWRTEST  0x2000     /* OTP/Fuse Write Test */
-#define                  nFWRTEST  0x0       
 #define                     FRDEN  0x4000     /* OTP/Fuse Read Enable */
-#define                    nFRDEN  0x0       
 #define                     FWREN  0x8000     /* OTP/Fuse Write Enable */
-#define                    nFWREN  0x0       
 
 /* Bit masks for OTP_BEN */
 
@@ -2481,15 +2187,10 @@
 /* Bit masks for OTP_STATUS */
 
 #define                     FCOMP  0x1        /* OTP/Fuse Access Complete */
-#define                    nFCOMP  0x0       
 #define                    FERROR  0x2        /* OTP/Fuse Access Error */
-#define                   nFERROR  0x0       
 #define                  MMRGLOAD  0x10       /* Memory Mapped Register Gasket Load */
-#define                 nMMRGLOAD  0x0       
 #define                  MMRGLOCK  0x20       /* Memory Mapped Register Gasket Lock */
-#define                 nMMRGLOCK  0x0       
 #define                    FPGMEN  0x40       /* OTP/Fuse Program Enable */
-#define                   nFPGMEN  0x0       
 
 /* Bit masks for OTP_TIMING */
 
@@ -2503,42 +2204,29 @@
 /* Bit masks for SECURE_SYSSWT */
 
 #define                   EMUDABL  0x1        /* Emulation Disable. */
-#define                  nEMUDABL  0x0       
 #define                   RSTDABL  0x2        /* Reset Disable */
-#define                  nRSTDABL  0x0       
 #define                   L1IDABL  0x1c       /* L1 Instruction Memory Disable. */
 #define                  L1DADABL  0xe0       /* L1 Data Bank A Memory Disable. */
 #define                  L1DBDABL  0x700      /* L1 Data Bank B Memory Disable. */
 #define                   DMA0OVR  0x800      /* DMA0 Memory Access Override */
-#define                  nDMA0OVR  0x0       
 #define                   DMA1OVR  0x1000     /* DMA1 Memory Access Override */
-#define                  nDMA1OVR  0x0       
 #define                    EMUOVR  0x4000     /* Emulation Override */
-#define                   nEMUOVR  0x0       
 #define                    OTPSEN  0x8000     /* OTP Secrets Enable. */
-#define                   nOTPSEN  0x0       
 #define                    L2DABL  0x70000    /* L2 Memory Disable. */
 
 /* Bit masks for SECURE_CONTROL */
 
 #define                   SECURE0  0x1        /* SECURE 0 */
-#define                  nSECURE0  0x0       
 #define                   SECURE1  0x2        /* SECURE 1 */
-#define                  nSECURE1  0x0       
 #define                   SECURE2  0x4        /* SECURE 2 */
-#define                  nSECURE2  0x0       
 #define                   SECURE3  0x8        /* SECURE 3 */
-#define                  nSECURE3  0x0       
 
 /* Bit masks for SECURE_STATUS */
 
 #define                   SECMODE  0x3        /* Secured Mode Control State */
 #define                       NMI  0x4        /* Non Maskable Interrupt */
-#define                      nNMI  0x0       
 #define                   AFVALID  0x8        /* Authentication Firmware Valid */
-#define                  nAFVALID  0x0       
 #define                    AFEXIT  0x10       /* Authentication Firmware Exit */
-#define                   nAFEXIT  0x0       
 #define                   SECSTAT  0xe0       /* Secure Status */
 
 /* Bit masks for PLL_DIV */
@@ -2550,42 +2238,25 @@
 
 #define                      MSEL  0x7e00     /* Multiplier Select */
 #define                    BYPASS  0x100      /* PLL Bypass Enable */
-#define                   nBYPASS  0x0       
 #define              OUTPUT_DELAY  0x80       /* External Memory Output Delay Enable */
-#define             nOUTPUT_DELAY  0x0       
 #define               INPUT_DELAY  0x40       /* External Memory Input Delay Enable */
-#define              nINPUT_DELAY  0x0       
 #define                      PDWN  0x20       /* Power Down */
-#define                     nPDWN  0x0       
 #define                    STOPCK  0x8        /* Stop Clock */
-#define                   nSTOPCK  0x0       
 #define                   PLL_OFF  0x2        /* Disable PLL */
-#define                  nPLL_OFF  0x0       
 #define                        DF  0x1        /* Divide Frequency */
-#define                       nDF  0x0       
 
 /* Bit masks for PLL_STAT */
 
 #define                PLL_LOCKED  0x20       /* PLL Locked Status */
-#define               nPLL_LOCKED  0x0       
 #define        ACTIVE_PLLDISABLED  0x4        /* Active Mode With PLL Disabled */
-#define       nACTIVE_PLLDISABLED  0x0       
 #define                   FULL_ON  0x2        /* Full-On Mode */
-#define                  nFULL_ON  0x0       
 #define         ACTIVE_PLLENABLED  0x1        /* Active Mode With PLL Enabled */
-#define        nACTIVE_PLLENABLED  0x0       
 #define                     RTCWS  0x400      /* RTC/Reset Wake-Up Status */
-#define                    nRTCWS  0x0       
 #define                     CANWS  0x800      /* CAN Wake-Up Status */
-#define                    nCANWS  0x0       
 #define                     USBWS  0x2000     /* USB Wake-Up Status */
-#define                    nUSBWS  0x0       
 #define                    KPADWS  0x4000     /* Keypad Wake-Up Status */
-#define                   nKPADWS  0x0       
 #define                     ROTWS  0x8000     /* Rotary Wake-Up Status */
-#define                    nROTWS  0x0       
 #define                      GPWS  0x1000     /* General-Purpose Wake-Up Status */
-#define                     nGPWS  0x0       
 
 /* Bit masks for VR_CTL */
 
@@ -2593,79 +2264,52 @@
 #define                      GAIN  0xc        /* Voltage Output Level Gain */
 #define                      VLEV  0xf0       /* Internal Voltage Level */
 #define                   SCKELOW  0x8000     /* Drive SCKE Low During Reset Enable */
-#define                  nSCKELOW  0x0       
 #define                      WAKE  0x100      /* RTC/Reset Wake-Up Enable */
-#define                     nWAKE  0x0       
 #define                     CANWE  0x200      /* CAN0/1 Wake-Up Enable */
-#define                    nCANWE  0x0       
 #define                      GPWE  0x400      /* General-Purpose Wake-Up Enable */
-#define                     nGPWE  0x0       
 #define                     USBWE  0x800      /* USB Wake-Up Enable */
-#define                    nUSBWE  0x0       
 #define                    KPADWE  0x1000     /* Keypad Wake-Up Enable */
-#define                   nKPADWE  0x0       
 #define                     ROTWE  0x2000     /* Rotary Wake-Up Enable */
-#define                    nROTWE  0x0       
 
 /* Bit masks for NFC_CTL */
 
 #define                    WR_DLY  0xf        /* Write Strobe Delay */
 #define                    RD_DLY  0xf0       /* Read Strobe Delay */
 #define                    NWIDTH  0x100      /* NAND Data Width */
-#define                   nNWIDTH  0x0       
 #define                   PG_SIZE  0x200      /* Page Size */
-#define                  nPG_SIZE  0x0       
 
 /* Bit masks for NFC_STAT */
 
 #define                     NBUSY  0x1        /* Not Busy */
-#define                    nNBUSY  0x0       
 #define                   WB_FULL  0x2        /* Write Buffer Full */
-#define                  nWB_FULL  0x0       
 #define                PG_WR_STAT  0x4        /* Page Write Pending */
-#define               nPG_WR_STAT  0x0       
 #define                PG_RD_STAT  0x8        /* Page Read Pending */
-#define               nPG_RD_STAT  0x0       
 #define                  WB_EMPTY  0x10       /* Write Buffer Empty */
-#define                 nWB_EMPTY  0x0       
 
 /* Bit masks for NFC_IRQSTAT */
 
 #define                  NBUSYIRQ  0x1        /* Not Busy IRQ */
-#define                 nNBUSYIRQ  0x0       
 #define                    WB_OVF  0x2        /* Write Buffer Overflow */
-#define                   nWB_OVF  0x0       
 #define                   WB_EDGE  0x4        /* Write Buffer Edge Detect */
-#define                  nWB_EDGE  0x0       
 #define                    RD_RDY  0x8        /* Read Data Ready */
-#define                   nRD_RDY  0x0       
 #define                   WR_DONE  0x10       /* Page Write Done */
-#define                  nWR_DONE  0x0       
 
 /* Bit masks for NFC_IRQMASK */
 
 #define              MASK_BUSYIRQ  0x1        /* Mask Not Busy IRQ */
-#define             nMASK_BUSYIRQ  0x0       
 #define                MASK_WBOVF  0x2        /* Mask Write Buffer Overflow */
-#define               nMASK_WBOVF  0x0       
 #define              MASK_WBEMPTY  0x4        /* Mask Write Buffer Empty */
-#define             nMASK_WBEMPTY  0x0       
 #define                MASK_RDRDY  0x8        /* Mask Read Data Ready */
-#define               nMASK_RDRDY  0x0       
 #define               MASK_WRDONE  0x10       /* Mask Write Done */
-#define              nMASK_WRDONE  0x0       
 
 /* Bit masks for NFC_RST */
 
 #define                   ECC_RST  0x1        /* ECC (and NFC counters) Reset */
-#define                  nECC_RST  0x0       
 
 /* Bit masks for NFC_PGCTL */
 
 #define               PG_RD_START  0x1        /* Page Read Start */
-#define              nPG_RD_START  0x0       
 #define               PG_WR_START  0x2        /* Page Write Start */
-#define              nPG_WR_START  0x0       
 
 /* Bit masks for NFC_ECC0 */
 
@@ -2690,56 +2334,34 @@
 /* Bit masks for CAN0_CONTROL */
 
 #define                       SRS  0x1        /* Software Reset */
-#define                      nSRS  0x0       
 #define                       DNM  0x2        /* DeviceNet Mode */
-#define                      nDNM  0x0       
 #define                       ABO  0x4        /* Auto Bus On */
-#define                      nABO  0x0       
 #define                       WBA  0x10       /* Wakeup On CAN Bus Activity */
-#define                      nWBA  0x0       
 #define                       SMR  0x20       /* Sleep Mode Request */
-#define                      nSMR  0x0       
 #define                       CSR  0x40       /* CAN Suspend Mode Request */
-#define                      nCSR  0x0       
 #define                       CCR  0x80       /* CAN Configuration Mode Request */
-#define                      nCCR  0x0       
 
 /* Bit masks for CAN0_STATUS */
 
 #define                        WT  0x1        /* CAN Transmit Warning Flag */
-#define                       nWT  0x0       
 #define                        WR  0x2        /* CAN Receive Warning Flag */
-#define                       nWR  0x0       
 #define                        EP  0x4        /* CAN Error Passive Mode */
-#define                       nEP  0x0       
 #define                       EBO  0x8        /* CAN Error Bus Off Mode */
-#define                      nEBO  0x0       
 #define                       CSA  0x40       /* CAN Suspend Mode Acknowledge */
-#define                      nCSA  0x0       
 #define                       CCA  0x80       /* CAN Configuration Mode Acknowledge */
-#define                      nCCA  0x0       
 #define                     MBPTR  0x1f00     /* Mailbox Pointer */
 #define                       TRM  0x4000     /* Transmit Mode Status */
-#define                      nTRM  0x0       
 #define                       REC  0x8000     /* Receive Mode Status */
-#define                      nREC  0x0       
 
 /* Bit masks for CAN0_DEBUG */
 
 #define                       DEC  0x1        /* Disable Transmit/Receive Error Counters */
-#define                      nDEC  0x0       
 #define                       DRI  0x2        /* Disable CANRX Input Pin */
-#define                      nDRI  0x0       
 #define                       DTO  0x4        /* Disable CANTX Output Pin */
-#define                      nDTO  0x0       
 #define                       DIL  0x8        /* Disable Internal Loop */
-#define                      nDIL  0x0       
 #define                       MAA  0x10       /* Mode Auto-Acknowledge */
-#define                      nMAA  0x0       
 #define                       MRB  0x20       /* Mode Read Back */
-#define                      nMRB  0x0       
 #define                       CDE  0x8000     /* CAN Debug Mode Enable */
-#define                      nCDE  0x0       
 
 /* Bit masks for CAN0_CLOCK */
 
@@ -2749,111 +2371,69 @@
 
 #define                       SJW  0x300      /* Synchronization Jump Width */
 #define                       SAM  0x80       /* Sampling */
-#define                      nSAM  0x0       
 #define                     TSEG2  0x70       /* Time Segment 2 */
 #define                     TSEG1  0xf        /* Time Segment 1 */
 
 /* Bit masks for CAN0_INTR */
 
 #define                     CANRX  0x80       /* Serial Input From Transceiver */
-#define                    nCANRX  0x0       
 #define                     CANTX  0x40       /* Serial Output To Transceiver */
-#define                    nCANTX  0x0       
 #define                     SMACK  0x8        /* Sleep Mode Acknowledge */
-#define                    nSMACK  0x0       
 #define                      GIRQ  0x4        /* Global Interrupt Request Status */
-#define                     nGIRQ  0x0       
 #define                    MBTIRQ  0x2        /* Mailbox Transmit Interrupt Request */
-#define                   nMBTIRQ  0x0       
 #define                    MBRIRQ  0x1        /* Mailbox Receive Interrupt Request */
-#define                   nMBRIRQ  0x0       
 
 /* Bit masks for CAN0_GIM */
 
 #define                     EWTIM  0x1        /* Error Warning Transmit Interrupt Mask */
-#define                    nEWTIM  0x0       
 #define                     EWRIM  0x2        /* Error Warning Receive Interrupt Mask */
-#define                    nEWRIM  0x0       
 #define                      EPIM  0x4        /* Error Passive Interrupt Mask */
-#define                     nEPIM  0x0       
 #define                      BOIM  0x8        /* Bus Off Interrupt Mask */
-#define                     nBOIM  0x0       
 #define                      WUIM  0x10       /* Wakeup Interrupt Mask */
-#define                     nWUIM  0x0       
 #define                     UIAIM  0x20       /* Unimplemented Address Interrupt Mask */
-#define                    nUIAIM  0x0       
 #define                      AAIM  0x40       /* Abort Acknowledge Interrupt Mask */
-#define                     nAAIM  0x0       
 #define                     RMLIM  0x80       /* Receive Message Lost Interrupt Mask */
-#define                    nRMLIM  0x0       
 #define                     UCEIM  0x100      /* Universal Counter Exceeded Interrupt Mask */
-#define                    nUCEIM  0x0       
 #define                      ADIM  0x400      /* Access Denied Interrupt Mask */
-#define                     nADIM  0x0       
 
 /* Bit masks for CAN0_GIS */
 
 #define                     EWTIS  0x1        /* Error Warning Transmit Interrupt Status */
-#define                    nEWTIS  0x0       
 #define                     EWRIS  0x2        /* Error Warning Receive Interrupt Status */
-#define                    nEWRIS  0x0       
 #define                      EPIS  0x4        /* Error Passive Interrupt Status */
-#define                     nEPIS  0x0       
 #define                      BOIS  0x8        /* Bus Off Interrupt Status */
-#define                     nBOIS  0x0       
 #define                      WUIS  0x10       /* Wakeup Interrupt Status */
-#define                     nWUIS  0x0       
 #define                     UIAIS  0x20       /* Unimplemented Address Interrupt Status */
-#define                    nUIAIS  0x0       
 #define                      AAIS  0x40       /* Abort Acknowledge Interrupt Status */
-#define                     nAAIS  0x0       
 #define                     RMLIS  0x80       /* Receive Message Lost Interrupt Status */
-#define                    nRMLIS  0x0       
 #define                     UCEIS  0x100      /* Universal Counter Exceeded Interrupt Status */
-#define                    nUCEIS  0x0       
 #define                      ADIS  0x400      /* Access Denied Interrupt Status */
-#define                     nADIS  0x0       
 
 /* Bit masks for CAN0_GIF */
 
 #define                     EWTIF  0x1        /* Error Warning Transmit Interrupt Flag */
-#define                    nEWTIF  0x0       
 #define                     EWRIF  0x2        /* Error Warning Receive Interrupt Flag */
-#define                    nEWRIF  0x0       
 #define                      EPIF  0x4        /* Error Passive Interrupt Flag */
-#define                     nEPIF  0x0       
 #define                      BOIF  0x8        /* Bus Off Interrupt Flag */
-#define                     nBOIF  0x0       
 #define                      WUIF  0x10       /* Wakeup Interrupt Flag */
-#define                     nWUIF  0x0       
 #define                     UIAIF  0x20       /* Unimplemented Address Interrupt Flag */
-#define                    nUIAIF  0x0       
 #define                      AAIF  0x40       /* Abort Acknowledge Interrupt Flag */
-#define                     nAAIF  0x0       
 #define                     RMLIF  0x80       /* Receive Message Lost Interrupt Flag */
-#define                    nRMLIF  0x0       
 #define                     UCEIF  0x100      /* Universal Counter Exceeded Interrupt Flag */
-#define                    nUCEIF  0x0       
 #define                      ADIF  0x400      /* Access Denied Interrupt Flag */
-#define                     nADIF  0x0       
 
 /* Bit masks for CAN0_MBTD */
 
 #define                       TDR  0x80       /* Temporary Disable Request */
-#define                      nTDR  0x0       
 #define                       TDA  0x40       /* Temporary Disable Acknowledge */
-#define                      nTDA  0x0       
 #define                     TDPTR  0x1f       /* Temporary Disable Pointer */
 
 /* Bit masks for CAN0_UCCNF */
 
 #define                     UCCNF  0xf        /* Universal Counter Configuration */
 #define                      UCRC  0x20       /* Universal Counter Reload/Clear */
-#define                     nUCRC  0x0       
 #define                      UCCT  0x40       /* Universal Counter CAN Trigger */
-#define                     nUCCT  0x0       
 #define                       UCE  0x80       /* Universal Counter Enable */
-#define                      nUCE  0x0       
 
 /* Bit masks for CAN0_UCCNT */
 
@@ -2871,17 +2451,11 @@
 /* Bit masks for CAN0_ESR */
 
 #define                       FER  0x80       /* Form Error */
-#define                      nFER  0x0       
 #define                       BEF  0x40       /* Bit Error Flag */
-#define                      nBEF  0x0       
 #define                       SA0  0x20       /* Stuck At Dominant */
-#define                      nSA0  0x0       
 #define                      CRCE  0x10       /* CRC Error */
-#define                     nCRCE  0x0       
 #define                       SER  0x8        /* Stuff Bit Error */
-#define                      nSER  0x0       
 #define                      ACKE  0x4        /* Acknowledge Error */
-#define                     nACKE  0x0       
 
 /* Bit masks for CAN0_EWR */
 
@@ -2891,11 +2465,8 @@
 /* Bit masks for CAN0_AMxx_H */
 
 #define                       FDF  0x8000     /* Filter On Data Field */
-#define                      nFDF  0x0       
 #define                       FMD  0x4000     /* Full Mask Data */
-#define                      nFMD  0x0       
 #define                     AMIDE  0x2000     /* Acceptance Mask Identifier Extension */
-#define                    nAMIDE  0x0       
 #define                    BASEID  0x1ffc     /* Base Identifier */
 #define                  EXTID_HI  0x3        /* Extended Identifier High Bits */
 
@@ -2907,11 +2478,8 @@
 /* Bit masks for CAN0_MBxx_ID1 */
 
 #define                       AME  0x8000     /* Acceptance Mask Enable */
-#define                      nAME  0x0       
 #define                       RTR  0x4000     /* Remote Transmission Request */
-#define                      nRTR  0x0       
 #define                       IDE  0x2000     /* Identifier Extension */
-#define                      nIDE  0x0       
 #define                    BASEID  0x1ffc     /* Base Identifier */
 #define                  EXTID_HI  0x3        /* Extended Identifier High Bits */
 
@@ -2951,980 +2519,546 @@
 /* Bit masks for CAN0_MC1 */
 
 #define                       MC0  0x1        /* Mailbox 0 Enable */
-#define                      nMC0  0x0       
 #define                       MC1  0x2        /* Mailbox 1 Enable */
-#define                      nMC1  0x0       
 #define                       MC2  0x4        /* Mailbox 2 Enable */
-#define                      nMC2  0x0       
 #define                       MC3  0x8        /* Mailbox 3 Enable */
-#define                      nMC3  0x0       
 #define                       MC4  0x10       /* Mailbox 4 Enable */
-#define                      nMC4  0x0       
 #define                       MC5  0x20       /* Mailbox 5 Enable */
-#define                      nMC5  0x0       
 #define                       MC6  0x40       /* Mailbox 6 Enable */
-#define                      nMC6  0x0       
 #define                       MC7  0x80       /* Mailbox 7 Enable */
-#define                      nMC7  0x0       
 #define                       MC8  0x100      /* Mailbox 8 Enable */
-#define                      nMC8  0x0       
 #define                       MC9  0x200      /* Mailbox 9 Enable */
-#define                      nMC9  0x0       
 #define                      MC10  0x400      /* Mailbox 10 Enable */
-#define                     nMC10  0x0       
 #define                      MC11  0x800      /* Mailbox 11 Enable */
-#define                     nMC11  0x0       
 #define                      MC12  0x1000     /* Mailbox 12 Enable */
-#define                     nMC12  0x0       
 #define                      MC13  0x2000     /* Mailbox 13 Enable */
-#define                     nMC13  0x0       
 #define                      MC14  0x4000     /* Mailbox 14 Enable */
-#define                     nMC14  0x0       
 #define                      MC15  0x8000     /* Mailbox 15 Enable */
-#define                     nMC15  0x0       
 
 /* Bit masks for CAN0_MC2 */
 
 #define                      MC16  0x1        /* Mailbox 16 Enable */
-#define                     nMC16  0x0       
 #define                      MC17  0x2        /* Mailbox 17 Enable */
-#define                     nMC17  0x0       
 #define                      MC18  0x4        /* Mailbox 18 Enable */
-#define                     nMC18  0x0       
 #define                      MC19  0x8        /* Mailbox 19 Enable */
-#define                     nMC19  0x0       
 #define                      MC20  0x10       /* Mailbox 20 Enable */
-#define                     nMC20  0x0       
 #define                      MC21  0x20       /* Mailbox 21 Enable */
-#define                     nMC21  0x0       
 #define                      MC22  0x40       /* Mailbox 22 Enable */
-#define                     nMC22  0x0       
 #define                      MC23  0x80       /* Mailbox 23 Enable */
-#define                     nMC23  0x0       
 #define                      MC24  0x100      /* Mailbox 24 Enable */
-#define                     nMC24  0x0       
 #define                      MC25  0x200      /* Mailbox 25 Enable */
-#define                     nMC25  0x0       
 #define                      MC26  0x400      /* Mailbox 26 Enable */
-#define                     nMC26  0x0       
 #define                      MC27  0x800      /* Mailbox 27 Enable */
-#define                     nMC27  0x0       
 #define                      MC28  0x1000     /* Mailbox 28 Enable */
-#define                     nMC28  0x0       
 #define                      MC29  0x2000     /* Mailbox 29 Enable */
-#define                     nMC29  0x0       
 #define                      MC30  0x4000     /* Mailbox 30 Enable */
-#define                     nMC30  0x0       
 #define                      MC31  0x8000     /* Mailbox 31 Enable */
-#define                     nMC31  0x0       
 
 /* Bit masks for CAN0_MD1 */
 
 #define                       MD0  0x1        /* Mailbox 0 Receive Enable */
-#define                      nMD0  0x0       
 #define                       MD1  0x2        /* Mailbox 1 Receive Enable */
-#define                      nMD1  0x0       
 #define                       MD2  0x4        /* Mailbox 2 Receive Enable */
-#define                      nMD2  0x0       
 #define                       MD3  0x8        /* Mailbox 3 Receive Enable */
-#define                      nMD3  0x0       
 #define                       MD4  0x10       /* Mailbox 4 Receive Enable */
-#define                      nMD4  0x0       
 #define                       MD5  0x20       /* Mailbox 5 Receive Enable */
-#define                      nMD5  0x0       
 #define                       MD6  0x40       /* Mailbox 6 Receive Enable */
-#define                      nMD6  0x0       
 #define                       MD7  0x80       /* Mailbox 7 Receive Enable */
-#define                      nMD7  0x0       
 #define                       MD8  0x100      /* Mailbox 8 Receive Enable */
-#define                      nMD8  0x0       
 #define                       MD9  0x200      /* Mailbox 9 Receive Enable */
-#define                      nMD9  0x0       
 #define                      MD10  0x400      /* Mailbox 10 Receive Enable */
-#define                     nMD10  0x0       
 #define                      MD11  0x800      /* Mailbox 11 Receive Enable */
-#define                     nMD11  0x0       
 #define                      MD12  0x1000     /* Mailbox 12 Receive Enable */
-#define                     nMD12  0x0       
 #define                      MD13  0x2000     /* Mailbox 13 Receive Enable */
-#define                     nMD13  0x0       
 #define                      MD14  0x4000     /* Mailbox 14 Receive Enable */
-#define                     nMD14  0x0       
 #define                      MD15  0x8000     /* Mailbox 15 Receive Enable */
-#define                     nMD15  0x0       
 
 /* Bit masks for CAN0_MD2 */
 
 #define                      MD16  0x1        /* Mailbox 16 Receive Enable */
-#define                     nMD16  0x0       
 #define                      MD17  0x2        /* Mailbox 17 Receive Enable */
-#define                     nMD17  0x0       
 #define                      MD18  0x4        /* Mailbox 18 Receive Enable */
-#define                     nMD18  0x0       
 #define                      MD19  0x8        /* Mailbox 19 Receive Enable */
-#define                     nMD19  0x0       
 #define                      MD20  0x10       /* Mailbox 20 Receive Enable */
-#define                     nMD20  0x0       
 #define                      MD21  0x20       /* Mailbox 21 Receive Enable */
-#define                     nMD21  0x0       
 #define                      MD22  0x40       /* Mailbox 22 Receive Enable */
-#define                     nMD22  0x0       
 #define                      MD23  0x80       /* Mailbox 23 Receive Enable */
-#define                     nMD23  0x0       
 #define                      MD24  0x100      /* Mailbox 24 Receive Enable */
-#define                     nMD24  0x0       
 #define                      MD25  0x200      /* Mailbox 25 Receive Enable */
-#define                     nMD25  0x0       
 #define                      MD26  0x400      /* Mailbox 26 Receive Enable */
-#define                     nMD26  0x0       
 #define                      MD27  0x800      /* Mailbox 27 Receive Enable */
-#define                     nMD27  0x0       
 #define                      MD28  0x1000     /* Mailbox 28 Receive Enable */
-#define                     nMD28  0x0       
 #define                      MD29  0x2000     /* Mailbox 29 Receive Enable */
-#define                     nMD29  0x0       
 #define                      MD30  0x4000     /* Mailbox 30 Receive Enable */
-#define                     nMD30  0x0       
 #define                      MD31  0x8000     /* Mailbox 31 Receive Enable */
-#define                     nMD31  0x0       
 
 /* Bit masks for CAN0_RMP1 */
 
 #define                      RMP0  0x1        /* Mailbox 0 Receive Message Pending */
-#define                     nRMP0  0x0       
 #define                      RMP1  0x2        /* Mailbox 1 Receive Message Pending */
-#define                     nRMP1  0x0       
 #define                      RMP2  0x4        /* Mailbox 2 Receive Message Pending */
-#define                     nRMP2  0x0       
 #define                      RMP3  0x8        /* Mailbox 3 Receive Message Pending */
-#define                     nRMP3  0x0       
 #define                      RMP4  0x10       /* Mailbox 4 Receive Message Pending */
-#define                     nRMP4  0x0       
 #define                      RMP5  0x20       /* Mailbox 5 Receive Message Pending */
-#define                     nRMP5  0x0       
 #define                      RMP6  0x40       /* Mailbox 6 Receive Message Pending */
-#define                     nRMP6  0x0       
 #define                      RMP7  0x80       /* Mailbox 7 Receive Message Pending */
-#define                     nRMP7  0x0       
 #define                      RMP8  0x100      /* Mailbox 8 Receive Message Pending */
-#define                     nRMP8  0x0       
 #define                      RMP9  0x200      /* Mailbox 9 Receive Message Pending */
-#define                     nRMP9  0x0       
 #define                     RMP10  0x400      /* Mailbox 10 Receive Message Pending */
-#define                    nRMP10  0x0       
 #define                     RMP11  0x800      /* Mailbox 11 Receive Message Pending */
-#define                    nRMP11  0x0       
 #define                     RMP12  0x1000     /* Mailbox 12 Receive Message Pending */
-#define                    nRMP12  0x0       
 #define                     RMP13  0x2000     /* Mailbox 13 Receive Message Pending */
-#define                    nRMP13  0x0       
 #define                     RMP14  0x4000     /* Mailbox 14 Receive Message Pending */
-#define                    nRMP14  0x0       
 #define                     RMP15  0x8000     /* Mailbox 15 Receive Message Pending */
-#define                    nRMP15  0x0       
 
 /* Bit masks for CAN0_RMP2 */
 
 #define                     RMP16  0x1        /* Mailbox 16 Receive Message Pending */
-#define                    nRMP16  0x0       
 #define                     RMP17  0x2        /* Mailbox 17 Receive Message Pending */
-#define                    nRMP17  0x0       
 #define                     RMP18  0x4        /* Mailbox 18 Receive Message Pending */
-#define                    nRMP18  0x0       
 #define                     RMP19  0x8        /* Mailbox 19 Receive Message Pending */
-#define                    nRMP19  0x0       
 #define                     RMP20  0x10       /* Mailbox 20 Receive Message Pending */
-#define                    nRMP20  0x0       
 #define                     RMP21  0x20       /* Mailbox 21 Receive Message Pending */
-#define                    nRMP21  0x0       
 #define                     RMP22  0x40       /* Mailbox 22 Receive Message Pending */
-#define                    nRMP22  0x0       
 #define                     RMP23  0x80       /* Mailbox 23 Receive Message Pending */
-#define                    nRMP23  0x0       
 #define                     RMP24  0x100      /* Mailbox 24 Receive Message Pending */
-#define                    nRMP24  0x0       
 #define                     RMP25  0x200      /* Mailbox 25 Receive Message Pending */
-#define                    nRMP25  0x0       
 #define                     RMP26  0x400      /* Mailbox 26 Receive Message Pending */
-#define                    nRMP26  0x0       
 #define                     RMP27  0x800      /* Mailbox 27 Receive Message Pending */
-#define                    nRMP27  0x0       
 #define                     RMP28  0x1000     /* Mailbox 28 Receive Message Pending */
-#define                    nRMP28  0x0       
 #define                     RMP29  0x2000     /* Mailbox 29 Receive Message Pending */
-#define                    nRMP29  0x0       
 #define                     RMP30  0x4000     /* Mailbox 30 Receive Message Pending */
-#define                    nRMP30  0x0       
 #define                     RMP31  0x8000     /* Mailbox 31 Receive Message Pending */
-#define                    nRMP31  0x0       
 
 /* Bit masks for CAN0_RML1 */
 
 #define                      RML0  0x1        /* Mailbox 0 Receive Message Lost */
-#define                     nRML0  0x0       
 #define                      RML1  0x2        /* Mailbox 1 Receive Message Lost */
-#define                     nRML1  0x0       
 #define                      RML2  0x4        /* Mailbox 2 Receive Message Lost */
-#define                     nRML2  0x0       
 #define                      RML3  0x8        /* Mailbox 3 Receive Message Lost */
-#define                     nRML3  0x0       
 #define                      RML4  0x10       /* Mailbox 4 Receive Message Lost */
-#define                     nRML4  0x0       
 #define                      RML5  0x20       /* Mailbox 5 Receive Message Lost */
-#define                     nRML5  0x0       
 #define                      RML6  0x40       /* Mailbox 6 Receive Message Lost */
-#define                     nRML6  0x0       
 #define                      RML7  0x80       /* Mailbox 7 Receive Message Lost */
-#define                     nRML7  0x0       
 #define                      RML8  0x100      /* Mailbox 8 Receive Message Lost */
-#define                     nRML8  0x0       
 #define                      RML9  0x200      /* Mailbox 9 Receive Message Lost */
-#define                     nRML9  0x0       
 #define                     RML10  0x400      /* Mailbox 10 Receive Message Lost */
-#define                    nRML10  0x0       
 #define                     RML11  0x800      /* Mailbox 11 Receive Message Lost */
-#define                    nRML11  0x0       
 #define                     RML12  0x1000     /* Mailbox 12 Receive Message Lost */
-#define                    nRML12  0x0       
 #define                     RML13  0x2000     /* Mailbox 13 Receive Message Lost */
-#define                    nRML13  0x0       
 #define                     RML14  0x4000     /* Mailbox 14 Receive Message Lost */
-#define                    nRML14  0x0       
 #define                     RML15  0x8000     /* Mailbox 15 Receive Message Lost */
-#define                    nRML15  0x0       
 
 /* Bit masks for CAN0_RML2 */
 
 #define                     RML16  0x1        /* Mailbox 16 Receive Message Lost */
-#define                    nRML16  0x0       
 #define                     RML17  0x2        /* Mailbox 17 Receive Message Lost */
-#define                    nRML17  0x0       
 #define                     RML18  0x4        /* Mailbox 18 Receive Message Lost */
-#define                    nRML18  0x0       
 #define                     RML19  0x8        /* Mailbox 19 Receive Message Lost */
-#define                    nRML19  0x0       
 #define                     RML20  0x10       /* Mailbox 20 Receive Message Lost */
-#define                    nRML20  0x0       
 #define                     RML21  0x20       /* Mailbox 21 Receive Message Lost */
-#define                    nRML21  0x0       
 #define                     RML22  0x40       /* Mailbox 22 Receive Message Lost */
-#define                    nRML22  0x0       
 #define                     RML23  0x80       /* Mailbox 23 Receive Message Lost */
-#define                    nRML23  0x0       
 #define                     RML24  0x100      /* Mailbox 24 Receive Message Lost */
-#define                    nRML24  0x0       
 #define                     RML25  0x200      /* Mailbox 25 Receive Message Lost */
-#define                    nRML25  0x0       
 #define                     RML26  0x400      /* Mailbox 26 Receive Message Lost */
-#define                    nRML26  0x0       
 #define                     RML27  0x800      /* Mailbox 27 Receive Message Lost */
-#define                    nRML27  0x0       
 #define                     RML28  0x1000     /* Mailbox 28 Receive Message Lost */
-#define                    nRML28  0x0       
 #define                     RML29  0x2000     /* Mailbox 29 Receive Message Lost */
-#define                    nRML29  0x0       
 #define                     RML30  0x4000     /* Mailbox 30 Receive Message Lost */
-#define                    nRML30  0x0       
 #define                     RML31  0x8000     /* Mailbox 31 Receive Message Lost */
-#define                    nRML31  0x0       
 
 /* Bit masks for CAN0_OPSS1 */
 
 #define                     OPSS0  0x1        /* Mailbox 0 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS0  0x0       
 #define                     OPSS1  0x2        /* Mailbox 1 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS1  0x0       
 #define                     OPSS2  0x4        /* Mailbox 2 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS2  0x0       
 #define                     OPSS3  0x8        /* Mailbox 3 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS3  0x0       
 #define                     OPSS4  0x10       /* Mailbox 4 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS4  0x0       
 #define                     OPSS5  0x20       /* Mailbox 5 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS5  0x0       
 #define                     OPSS6  0x40       /* Mailbox 6 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS6  0x0       
 #define                     OPSS7  0x80       /* Mailbox 7 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS7  0x0       
 #define                     OPSS8  0x100      /* Mailbox 8 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS8  0x0       
 #define                     OPSS9  0x200      /* Mailbox 9 Overwrite Protection/Single-Shot Transmission Enable */
-#define                    nOPSS9  0x0       
 #define                    OPSS10  0x400      /* Mailbox 10 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS10  0x0       
 #define                    OPSS11  0x800      /* Mailbox 11 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS11  0x0       
 #define                    OPSS12  0x1000     /* Mailbox 12 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS12  0x0       
 #define                    OPSS13  0x2000     /* Mailbox 13 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS13  0x0       
 #define                    OPSS14  0x4000     /* Mailbox 14 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS14  0x0       
 #define                    OPSS15  0x8000     /* Mailbox 15 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS15  0x0       
 
 /* Bit masks for CAN0_OPSS2 */
 
 #define                    OPSS16  0x1        /* Mailbox 16 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS16  0x0       
 #define                    OPSS17  0x2        /* Mailbox 17 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS17  0x0       
 #define                    OPSS18  0x4        /* Mailbox 18 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS18  0x0       
 #define                    OPSS19  0x8        /* Mailbox 19 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS19  0x0       
 #define                    OPSS20  0x10       /* Mailbox 20 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS20  0x0       
 #define                    OPSS21  0x20       /* Mailbox 21 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS21  0x0       
 #define                    OPSS22  0x40       /* Mailbox 22 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS22  0x0       
 #define                    OPSS23  0x80       /* Mailbox 23 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS23  0x0       
 #define                    OPSS24  0x100      /* Mailbox 24 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS24  0x0       
 #define                    OPSS25  0x200      /* Mailbox 25 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS25  0x0       
 #define                    OPSS26  0x400      /* Mailbox 26 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS26  0x0       
 #define                    OPSS27  0x800      /* Mailbox 27 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS27  0x0       
 #define                    OPSS28  0x1000     /* Mailbox 28 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS28  0x0       
 #define                    OPSS29  0x2000     /* Mailbox 29 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS29  0x0       
 #define                    OPSS30  0x4000     /* Mailbox 30 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS30  0x0       
 #define                    OPSS31  0x8000     /* Mailbox 31 Overwrite Protection/Single-Shot Transmission Enable */
-#define                   nOPSS31  0x0       
 
 /* Bit masks for CAN0_TRS1 */
 
 #define                      TRS0  0x1        /* Mailbox 0 Transmit Request Set */
-#define                     nTRS0  0x0       
 #define                      TRS1  0x2        /* Mailbox 1 Transmit Request Set */
-#define                     nTRS1  0x0       
 #define                      TRS2  0x4        /* Mailbox 2 Transmit Request Set */
-#define                     nTRS2  0x0       
 #define                      TRS3  0x8        /* Mailbox 3 Transmit Request Set */
-#define                     nTRS3  0x0       
 #define                      TRS4  0x10       /* Mailbox 4 Transmit Request Set */
-#define                     nTRS4  0x0       
 #define                      TRS5  0x20       /* Mailbox 5 Transmit Request Set */
-#define                     nTRS5  0x0       
 #define                      TRS6  0x40       /* Mailbox 6 Transmit Request Set */
-#define                     nTRS6  0x0       
 #define                      TRS7  0x80       /* Mailbox 7 Transmit Request Set */
-#define                     nTRS7  0x0       
 #define                      TRS8  0x100      /* Mailbox 8 Transmit Request Set */
-#define                     nTRS8  0x0       
 #define                      TRS9  0x200      /* Mailbox 9 Transmit Request Set */
-#define                     nTRS9  0x0       
 #define                     TRS10  0x400      /* Mailbox 10 Transmit Request Set */
-#define                    nTRS10  0x0       
 #define                     TRS11  0x800      /* Mailbox 11 Transmit Request Set */
-#define                    nTRS11  0x0       
 #define                     TRS12  0x1000     /* Mailbox 12 Transmit Request Set */
-#define                    nTRS12  0x0       
 #define                     TRS13  0x2000     /* Mailbox 13 Transmit Request Set */
-#define                    nTRS13  0x0       
 #define                     TRS14  0x4000     /* Mailbox 14 Transmit Request Set */
-#define                    nTRS14  0x0       
 #define                     TRS15  0x8000     /* Mailbox 15 Transmit Request Set */
-#define                    nTRS15  0x0       
 
 /* Bit masks for CAN0_TRS2 */
 
 #define                     TRS16  0x1        /* Mailbox 16 Transmit Request Set */
-#define                    nTRS16  0x0       
 #define                     TRS17  0x2        /* Mailbox 17 Transmit Request Set */
-#define                    nTRS17  0x0       
 #define                     TRS18  0x4        /* Mailbox 18 Transmit Request Set */
-#define                    nTRS18  0x0       
 #define                     TRS19  0x8        /* Mailbox 19 Transmit Request Set */
-#define                    nTRS19  0x0       
 #define                     TRS20  0x10       /* Mailbox 20 Transmit Request Set */
-#define                    nTRS20  0x0       
 #define                     TRS21  0x20       /* Mailbox 21 Transmit Request Set */
-#define                    nTRS21  0x0       
 #define                     TRS22  0x40       /* Mailbox 22 Transmit Request Set */
-#define                    nTRS22  0x0       
 #define                     TRS23  0x80       /* Mailbox 23 Transmit Request Set */
-#define                    nTRS23  0x0       
 #define                     TRS24  0x100      /* Mailbox 24 Transmit Request Set */
-#define                    nTRS24  0x0       
 #define                     TRS25  0x200      /* Mailbox 25 Transmit Request Set */
-#define                    nTRS25  0x0       
 #define                     TRS26  0x400      /* Mailbox 26 Transmit Request Set */
-#define                    nTRS26  0x0       
 #define                     TRS27  0x800      /* Mailbox 27 Transmit Request Set */
-#define                    nTRS27  0x0       
 #define                     TRS28  0x1000     /* Mailbox 28 Transmit Request Set */
-#define                    nTRS28  0x0       
 #define                     TRS29  0x2000     /* Mailbox 29 Transmit Request Set */
-#define                    nTRS29  0x0       
 #define                     TRS30  0x4000     /* Mailbox 30 Transmit Request Set */
-#define                    nTRS30  0x0       
 #define                     TRS31  0x8000     /* Mailbox 31 Transmit Request Set */
-#define                    nTRS31  0x0       
 
 /* Bit masks for CAN0_TRR1 */
 
 #define                      TRR0  0x1        /* Mailbox 0 Transmit Request Reset */
-#define                     nTRR0  0x0       
 #define                      TRR1  0x2        /* Mailbox 1 Transmit Request Reset */
-#define                     nTRR1  0x0       
 #define                      TRR2  0x4        /* Mailbox 2 Transmit Request Reset */
-#define                     nTRR2  0x0       
 #define                      TRR3  0x8        /* Mailbox 3 Transmit Request Reset */
-#define                     nTRR3  0x0       
 #define                      TRR4  0x10       /* Mailbox 4 Transmit Request Reset */
-#define                     nTRR4  0x0       
 #define                      TRR5  0x20       /* Mailbox 5 Transmit Request Reset */
-#define                     nTRR5  0x0       
 #define                      TRR6  0x40       /* Mailbox 6 Transmit Request Reset */
-#define                     nTRR6  0x0       
 #define                      TRR7  0x80       /* Mailbox 7 Transmit Request Reset */
-#define                     nTRR7  0x0       
 #define                      TRR8  0x100      /* Mailbox 8 Transmit Request Reset */
-#define                     nTRR8  0x0       
 #define                      TRR9  0x200      /* Mailbox 9 Transmit Request Reset */
-#define                     nTRR9  0x0       
 #define                     TRR10  0x400      /* Mailbox 10 Transmit Request Reset */
-#define                    nTRR10  0x0       
 #define                     TRR11  0x800      /* Mailbox 11 Transmit Request Reset */
-#define                    nTRR11  0x0       
 #define                     TRR12  0x1000     /* Mailbox 12 Transmit Request Reset */
-#define                    nTRR12  0x0       
 #define                     TRR13  0x2000     /* Mailbox 13 Transmit Request Reset */
-#define                    nTRR13  0x0       
 #define                     TRR14  0x4000     /* Mailbox 14 Transmit Request Reset */
-#define                    nTRR14  0x0       
 #define                     TRR15  0x8000     /* Mailbox 15 Transmit Request Reset */
-#define                    nTRR15  0x0       
 
 /* Bit masks for CAN0_TRR2 */
 
 #define                     TRR16  0x1        /* Mailbox 16 Transmit Request Reset */
-#define                    nTRR16  0x0       
 #define                     TRR17  0x2        /* Mailbox 17 Transmit Request Reset */
-#define                    nTRR17  0x0       
 #define                     TRR18  0x4        /* Mailbox 18 Transmit Request Reset */
-#define                    nTRR18  0x0       
 #define                     TRR19  0x8        /* Mailbox 19 Transmit Request Reset */
-#define                    nTRR19  0x0       
 #define                     TRR20  0x10       /* Mailbox 20 Transmit Request Reset */
-#define                    nTRR20  0x0       
 #define                     TRR21  0x20       /* Mailbox 21 Transmit Request Reset */
-#define                    nTRR21  0x0       
 #define                     TRR22  0x40       /* Mailbox 22 Transmit Request Reset */
-#define                    nTRR22  0x0       
 #define                     TRR23  0x80       /* Mailbox 23 Transmit Request Reset */
-#define                    nTRR23  0x0       
 #define                     TRR24  0x100      /* Mailbox 24 Transmit Request Reset */
-#define                    nTRR24  0x0       
 #define                     TRR25  0x200      /* Mailbox 25 Transmit Request Reset */
-#define                    nTRR25  0x0       
 #define                     TRR26  0x400      /* Mailbox 26 Transmit Request Reset */
-#define                    nTRR26  0x0       
 #define                     TRR27  0x800      /* Mailbox 27 Transmit Request Reset */
-#define                    nTRR27  0x0       
 #define                     TRR28  0x1000     /* Mailbox 28 Transmit Request Reset */
-#define                    nTRR28  0x0       
 #define                     TRR29  0x2000     /* Mailbox 29 Transmit Request Reset */
-#define                    nTRR29  0x0       
 #define                     TRR30  0x4000     /* Mailbox 30 Transmit Request Reset */
-#define                    nTRR30  0x0       
 #define                     TRR31  0x8000     /* Mailbox 31 Transmit Request Reset */
-#define                    nTRR31  0x0       
 
 /* Bit masks for CAN0_AA1 */
 
 #define                       AA0  0x1        /* Mailbox 0 Abort Acknowledge */
-#define                      nAA0  0x0       
 #define                       AA1  0x2        /* Mailbox 1 Abort Acknowledge */
-#define                      nAA1  0x0       
 #define                       AA2  0x4        /* Mailbox 2 Abort Acknowledge */
-#define                      nAA2  0x0       
 #define                       AA3  0x8        /* Mailbox 3 Abort Acknowledge */
-#define                      nAA3  0x0       
 #define                       AA4  0x10       /* Mailbox 4 Abort Acknowledge */
-#define                      nAA4  0x0       
 #define                       AA5  0x20       /* Mailbox 5 Abort Acknowledge */
-#define                      nAA5  0x0       
 #define                       AA6  0x40       /* Mailbox 6 Abort Acknowledge */
-#define                      nAA6  0x0       
 #define                       AA7  0x80       /* Mailbox 7 Abort Acknowledge */
-#define                      nAA7  0x0       
 #define                       AA8  0x100      /* Mailbox 8 Abort Acknowledge */
-#define                      nAA8  0x0       
 #define                       AA9  0x200      /* Mailbox 9 Abort Acknowledge */
-#define                      nAA9  0x0       
 #define                      AA10  0x400      /* Mailbox 10 Abort Acknowledge */
-#define                     nAA10  0x0       
 #define                      AA11  0x800      /* Mailbox 11 Abort Acknowledge */
-#define                     nAA11  0x0       
 #define                      AA12  0x1000     /* Mailbox 12 Abort Acknowledge */
-#define                     nAA12  0x0       
 #define                      AA13  0x2000     /* Mailbox 13 Abort Acknowledge */
-#define                     nAA13  0x0       
 #define                      AA14  0x4000     /* Mailbox 14 Abort Acknowledge */
-#define                     nAA14  0x0       
 #define                      AA15  0x8000     /* Mailbox 15 Abort Acknowledge */
-#define                     nAA15  0x0       
 
 /* Bit masks for CAN0_AA2 */
 
 #define                      AA16  0x1        /* Mailbox 16 Abort Acknowledge */
-#define                     nAA16  0x0       
 #define                      AA17  0x2        /* Mailbox 17 Abort Acknowledge */
-#define                     nAA17  0x0       
 #define                      AA18  0x4        /* Mailbox 18 Abort Acknowledge */
-#define                     nAA18  0x0       
 #define                      AA19  0x8        /* Mailbox 19 Abort Acknowledge */
-#define                     nAA19  0x0       
 #define                      AA20  0x10       /* Mailbox 20 Abort Acknowledge */
-#define                     nAA20  0x0       
 #define                      AA21  0x20       /* Mailbox 21 Abort Acknowledge */
-#define                     nAA21  0x0       
 #define                      AA22  0x40       /* Mailbox 22 Abort Acknowledge */
-#define                     nAA22  0x0       
 #define                      AA23  0x80       /* Mailbox 23 Abort Acknowledge */
-#define                     nAA23  0x0       
 #define                      AA24  0x100      /* Mailbox 24 Abort Acknowledge */
-#define                     nAA24  0x0       
 #define                      AA25  0x200      /* Mailbox 25 Abort Acknowledge */
-#define                     nAA25  0x0       
 #define                      AA26  0x400      /* Mailbox 26 Abort Acknowledge */
-#define                     nAA26  0x0       
 #define                      AA27  0x800      /* Mailbox 27 Abort Acknowledge */
-#define                     nAA27  0x0       
 #define                      AA28  0x1000     /* Mailbox 28 Abort Acknowledge */
-#define                     nAA28  0x0       
 #define                      AA29  0x2000     /* Mailbox 29 Abort Acknowledge */
-#define                     nAA29  0x0       
 #define                      AA30  0x4000     /* Mailbox 30 Abort Acknowledge */
-#define                     nAA30  0x0       
 #define                      AA31  0x8000     /* Mailbox 31 Abort Acknowledge */
-#define                     nAA31  0x0       
 
 /* Bit masks for CAN0_TA1 */
 
 #define                       TA0  0x1        /* Mailbox 0 Transmit Acknowledge */
-#define                      nTA0  0x0       
 #define                       TA1  0x2        /* Mailbox 1 Transmit Acknowledge */
-#define                      nTA1  0x0       
 #define                       TA2  0x4        /* Mailbox 2 Transmit Acknowledge */
-#define                      nTA2  0x0       
 #define                       TA3  0x8        /* Mailbox 3 Transmit Acknowledge */
-#define                      nTA3  0x0       
 #define                       TA4  0x10       /* Mailbox 4 Transmit Acknowledge */
-#define                      nTA4  0x0       
 #define                       TA5  0x20       /* Mailbox 5 Transmit Acknowledge */
-#define                      nTA5  0x0       
 #define                       TA6  0x40       /* Mailbox 6 Transmit Acknowledge */
-#define                      nTA6  0x0       
 #define                       TA7  0x80       /* Mailbox 7 Transmit Acknowledge */
-#define                      nTA7  0x0       
 #define                       TA8  0x100      /* Mailbox 8 Transmit Acknowledge */
-#define                      nTA8  0x0       
 #define                       TA9  0x200      /* Mailbox 9 Transmit Acknowledge */
-#define                      nTA9  0x0       
 #define                      TA10  0x400      /* Mailbox 10 Transmit Acknowledge */
-#define                     nTA10  0x0       
 #define                      TA11  0x800      /* Mailbox 11 Transmit Acknowledge */
-#define                     nTA11  0x0       
 #define                      TA12  0x1000     /* Mailbox 12 Transmit Acknowledge */
-#define                     nTA12  0x0       
 #define                      TA13  0x2000     /* Mailbox 13 Transmit Acknowledge */
-#define                     nTA13  0x0       
 #define                      TA14  0x4000     /* Mailbox 14 Transmit Acknowledge */
-#define                     nTA14  0x0       
 #define                      TA15  0x8000     /* Mailbox 15 Transmit Acknowledge */
-#define                     nTA15  0x0       
 
 /* Bit masks for CAN0_TA2 */
 
 #define                      TA16  0x1        /* Mailbox 16 Transmit Acknowledge */
-#define                     nTA16  0x0       
 #define                      TA17  0x2        /* Mailbox 17 Transmit Acknowledge */
-#define                     nTA17  0x0       
 #define                      TA18  0x4        /* Mailbox 18 Transmit Acknowledge */
-#define                     nTA18  0x0       
 #define                      TA19  0x8        /* Mailbox 19 Transmit Acknowledge */
-#define                     nTA19  0x0       
 #define                      TA20  0x10       /* Mailbox 20 Transmit Acknowledge */
-#define                     nTA20  0x0       
 #define                      TA21  0x20       /* Mailbox 21 Transmit Acknowledge */
-#define                     nTA21  0x0       
 #define                      TA22  0x40       /* Mailbox 22 Transmit Acknowledge */
-#define                     nTA22  0x0       
 #define                      TA23  0x80       /* Mailbox 23 Transmit Acknowledge */
-#define                     nTA23  0x0       
 #define                      TA24  0x100      /* Mailbox 24 Transmit Acknowledge */
-#define                     nTA24  0x0       
 #define                      TA25  0x200      /* Mailbox 25 Transmit Acknowledge */
-#define                     nTA25  0x0       
 #define                      TA26  0x400      /* Mailbox 26 Transmit Acknowledge */
-#define                     nTA26  0x0       
 #define                      TA27  0x800      /* Mailbox 27 Transmit Acknowledge */
-#define                     nTA27  0x0       
 #define                      TA28  0x1000     /* Mailbox 28 Transmit Acknowledge */
-#define                     nTA28  0x0       
 #define                      TA29  0x2000     /* Mailbox 29 Transmit Acknowledge */
-#define                     nTA29  0x0       
 #define                      TA30  0x4000     /* Mailbox 30 Transmit Acknowledge */
-#define                     nTA30  0x0       
 #define                      TA31  0x8000     /* Mailbox 31 Transmit Acknowledge */
-#define                     nTA31  0x0       
 
 /* Bit masks for CAN0_RFH1 */
 
 #define                      RFH0  0x1        /* Mailbox 0 Remote Frame Handling Enable */
-#define                     nRFH0  0x0       
 #define                      RFH1  0x2        /* Mailbox 1 Remote Frame Handling Enable */
-#define                     nRFH1  0x0       
 #define                      RFH2  0x4        /* Mailbox 2 Remote Frame Handling Enable */
-#define                     nRFH2  0x0       
 #define                      RFH3  0x8        /* Mailbox 3 Remote Frame Handling Enable */
-#define                     nRFH3  0x0       
 #define                      RFH4  0x10       /* Mailbox 4 Remote Frame Handling Enable */
-#define                     nRFH4  0x0       
 #define                      RFH5  0x20       /* Mailbox 5 Remote Frame Handling Enable */
-#define                     nRFH5  0x0       
 #define                      RFH6  0x40       /* Mailbox 6 Remote Frame Handling Enable */
-#define                     nRFH6  0x0       
 #define                      RFH7  0x80       /* Mailbox 7 Remote Frame Handling Enable */
-#define                     nRFH7  0x0       
 #define                      RFH8  0x100      /* Mailbox 8 Remote Frame Handling Enable */
-#define                     nRFH8  0x0       
 #define                      RFH9  0x200      /* Mailbox 9 Remote Frame Handling Enable */
-#define                     nRFH9  0x0       
 #define                     RFH10  0x400      /* Mailbox 10 Remote Frame Handling Enable */
-#define                    nRFH10  0x0       
 #define                     RFH11  0x800      /* Mailbox 11 Remote Frame Handling Enable */
-#define                    nRFH11  0x0       
 #define                     RFH12  0x1000     /* Mailbox 12 Remote Frame Handling Enable */
-#define                    nRFH12  0x0       
 #define                     RFH13  0x2000     /* Mailbox 13 Remote Frame Handling Enable */
-#define                    nRFH13  0x0       
 #define                     RFH14  0x4000     /* Mailbox 14 Remote Frame Handling Enable */
-#define                    nRFH14  0x0       
 #define                     RFH15  0x8000     /* Mailbox 15 Remote Frame Handling Enable */
-#define                    nRFH15  0x0       
 
 /* Bit masks for CAN0_RFH2 */
 
 #define                     RFH16  0x1        /* Mailbox 16 Remote Frame Handling Enable */
-#define                    nRFH16  0x0       
 #define                     RFH17  0x2        /* Mailbox 17 Remote Frame Handling Enable */
-#define                    nRFH17  0x0       
 #define                     RFH18  0x4        /* Mailbox 18 Remote Frame Handling Enable */
-#define                    nRFH18  0x0       
 #define                     RFH19  0x8        /* Mailbox 19 Remote Frame Handling Enable */
-#define                    nRFH19  0x0       
 #define                     RFH20  0x10       /* Mailbox 20 Remote Frame Handling Enable */
-#define                    nRFH20  0x0       
 #define                     RFH21  0x20       /* Mailbox 21 Remote Frame Handling Enable */
-#define                    nRFH21  0x0       
 #define                     RFH22  0x40       /* Mailbox 22 Remote Frame Handling Enable */
-#define                    nRFH22  0x0       
 #define                     RFH23  0x80       /* Mailbox 23 Remote Frame Handling Enable */
-#define                    nRFH23  0x0       
 #define                     RFH24  0x100      /* Mailbox 24 Remote Frame Handling Enable */
-#define                    nRFH24  0x0       
 #define                     RFH25  0x200      /* Mailbox 25 Remote Frame Handling Enable */
-#define                    nRFH25  0x0       
 #define                     RFH26  0x400      /* Mailbox 26 Remote Frame Handling Enable */
-#define                    nRFH26  0x0       
 #define                     RFH27  0x800      /* Mailbox 27 Remote Frame Handling Enable */
-#define                    nRFH27  0x0       
 #define                     RFH28  0x1000     /* Mailbox 28 Remote Frame Handling Enable */
-#define                    nRFH28  0x0       
 #define                     RFH29  0x2000     /* Mailbox 29 Remote Frame Handling Enable */
-#define                    nRFH29  0x0       
 #define                     RFH30  0x4000     /* Mailbox 30 Remote Frame Handling Enable */
-#define                    nRFH30  0x0       
 #define                     RFH31  0x8000     /* Mailbox 31 Remote Frame Handling Enable */
-#define                    nRFH31  0x0       
 
 /* Bit masks for CAN0_MBIM1 */
 
 #define                     MBIM0  0x1        /* Mailbox 0 Mailbox Interrupt Mask */
-#define                    nMBIM0  0x0       
 #define                     MBIM1  0x2        /* Mailbox 1 Mailbox Interrupt Mask */
-#define                    nMBIM1  0x0       
 #define                     MBIM2  0x4        /* Mailbox 2 Mailbox Interrupt Mask */
-#define                    nMBIM2  0x0       
 #define                     MBIM3  0x8        /* Mailbox 3 Mailbox Interrupt Mask */
-#define                    nMBIM3  0x0       
 #define                     MBIM4  0x10       /* Mailbox 4 Mailbox Interrupt Mask */
-#define                    nMBIM4  0x0       
 #define                     MBIM5  0x20       /* Mailbox 5 Mailbox Interrupt Mask */
-#define                    nMBIM5  0x0       
 #define                     MBIM6  0x40       /* Mailbox 6 Mailbox Interrupt Mask */
-#define                    nMBIM6  0x0       
 #define                     MBIM7  0x80       /* Mailbox 7 Mailbox Interrupt Mask */
-#define                    nMBIM7  0x0       
 #define                     MBIM8  0x100      /* Mailbox 8 Mailbox Interrupt Mask */
-#define                    nMBIM8  0x0       
 #define                     MBIM9  0x200      /* Mailbox 9 Mailbox Interrupt Mask */
-#define                    nMBIM9  0x0       
 #define                    MBIM10  0x400      /* Mailbox 10 Mailbox Interrupt Mask */
-#define                   nMBIM10  0x0       
 #define                    MBIM11  0x800      /* Mailbox 11 Mailbox Interrupt Mask */
-#define                   nMBIM11  0x0       
 #define                    MBIM12  0x1000     /* Mailbox 12 Mailbox Interrupt Mask */
-#define                   nMBIM12  0x0       
 #define                    MBIM13  0x2000     /* Mailbox 13 Mailbox Interrupt Mask */
-#define                   nMBIM13  0x0       
 #define                    MBIM14  0x4000     /* Mailbox 14 Mailbox Interrupt Mask */
-#define                   nMBIM14  0x0       
 #define                    MBIM15  0x8000     /* Mailbox 15 Mailbox Interrupt Mask */
-#define                   nMBIM15  0x0       
 
 /* Bit masks for CAN0_MBIM2 */
 
 #define                    MBIM16  0x1        /* Mailbox 16 Mailbox Interrupt Mask */
-#define                   nMBIM16  0x0       
 #define                    MBIM17  0x2        /* Mailbox 17 Mailbox Interrupt Mask */
-#define                   nMBIM17  0x0       
 #define                    MBIM18  0x4        /* Mailbox 18 Mailbox Interrupt Mask */
-#define                   nMBIM18  0x0       
 #define                    MBIM19  0x8        /* Mailbox 19 Mailbox Interrupt Mask */
-#define                   nMBIM19  0x0       
 #define                    MBIM20  0x10       /* Mailbox 20 Mailbox Interrupt Mask */
-#define                   nMBIM20  0x0       
 #define                    MBIM21  0x20       /* Mailbox 21 Mailbox Interrupt Mask */
-#define                   nMBIM21  0x0       
 #define                    MBIM22  0x40       /* Mailbox 22 Mailbox Interrupt Mask */
-#define                   nMBIM22  0x0       
 #define                    MBIM23  0x80       /* Mailbox 23 Mailbox Interrupt Mask */
-#define                   nMBIM23  0x0       
 #define                    MBIM24  0x100      /* Mailbox 24 Mailbox Interrupt Mask */
-#define                   nMBIM24  0x0       
 #define                    MBIM25  0x200      /* Mailbox 25 Mailbox Interrupt Mask */
-#define                   nMBIM25  0x0       
 #define                    MBIM26  0x400      /* Mailbox 26 Mailbox Interrupt Mask */
-#define                   nMBIM26  0x0       
 #define                    MBIM27  0x800      /* Mailbox 27 Mailbox Interrupt Mask */
-#define                   nMBIM27  0x0       
 #define                    MBIM28  0x1000     /* Mailbox 28 Mailbox Interrupt Mask */
-#define                   nMBIM28  0x0       
 #define                    MBIM29  0x2000     /* Mailbox 29 Mailbox Interrupt Mask */
-#define                   nMBIM29  0x0       
 #define                    MBIM30  0x4000     /* Mailbox 30 Mailbox Interrupt Mask */
-#define                   nMBIM30  0x0       
 #define                    MBIM31  0x8000     /* Mailbox 31 Mailbox Interrupt Mask */
-#define                   nMBIM31  0x0       
 
 /* Bit masks for CAN0_MBTIF1 */
 
 #define                    MBTIF0  0x1        /* Mailbox 0 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF0  0x0       
 #define                    MBTIF1  0x2        /* Mailbox 1 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF1  0x0       
 #define                    MBTIF2  0x4        /* Mailbox 2 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF2  0x0       
 #define                    MBTIF3  0x8        /* Mailbox 3 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF3  0x0       
 #define                    MBTIF4  0x10       /* Mailbox 4 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF4  0x0       
 #define                    MBTIF5  0x20       /* Mailbox 5 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF5  0x0       
 #define                    MBTIF6  0x40       /* Mailbox 6 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF6  0x0       
 #define                    MBTIF7  0x80       /* Mailbox 7 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF7  0x0       
 #define                    MBTIF8  0x100      /* Mailbox 8 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF8  0x0       
 #define                    MBTIF9  0x200      /* Mailbox 9 Mailbox Transmit Interrupt Flag */
-#define                   nMBTIF9  0x0       
 #define                   MBTIF10  0x400      /* Mailbox 10 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF10  0x0       
 #define                   MBTIF11  0x800      /* Mailbox 11 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF11  0x0       
 #define                   MBTIF12  0x1000     /* Mailbox 12 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF12  0x0       
 #define                   MBTIF13  0x2000     /* Mailbox 13 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF13  0x0       
 #define                   MBTIF14  0x4000     /* Mailbox 14 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF14  0x0       
 #define                   MBTIF15  0x8000     /* Mailbox 15 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF15  0x0       
 
 /* Bit masks for CAN0_MBTIF2 */
 
 #define                   MBTIF16  0x1        /* Mailbox 16 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF16  0x0       
 #define                   MBTIF17  0x2        /* Mailbox 17 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF17  0x0       
 #define                   MBTIF18  0x4        /* Mailbox 18 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF18  0x0       
 #define                   MBTIF19  0x8        /* Mailbox 19 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF19  0x0       
 #define                   MBTIF20  0x10       /* Mailbox 20 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF20  0x0       
 #define                   MBTIF21  0x20       /* Mailbox 21 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF21  0x0       
 #define                   MBTIF22  0x40       /* Mailbox 22 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF22  0x0       
 #define                   MBTIF23  0x80       /* Mailbox 23 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF23  0x0       
 #define                   MBTIF24  0x100      /* Mailbox 24 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF24  0x0       
 #define                   MBTIF25  0x200      /* Mailbox 25 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF25  0x0       
 #define                   MBTIF26  0x400      /* Mailbox 26 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF26  0x0       
 #define                   MBTIF27  0x800      /* Mailbox 27 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF27  0x0       
 #define                   MBTIF28  0x1000     /* Mailbox 28 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF28  0x0       
 #define                   MBTIF29  0x2000     /* Mailbox 29 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF29  0x0       
 #define                   MBTIF30  0x4000     /* Mailbox 30 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF30  0x0       
 #define                   MBTIF31  0x8000     /* Mailbox 31 Mailbox Transmit Interrupt Flag */
-#define                  nMBTIF31  0x0       
 
 /* Bit masks for CAN0_MBRIF1 */
 
 #define                    MBRIF0  0x1        /* Mailbox 0 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF0  0x0       
 #define                    MBRIF1  0x2        /* Mailbox 1 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF1  0x0       
 #define                    MBRIF2  0x4        /* Mailbox 2 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF2  0x0       
 #define                    MBRIF3  0x8        /* Mailbox 3 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF3  0x0       
 #define                    MBRIF4  0x10       /* Mailbox 4 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF4  0x0       
 #define                    MBRIF5  0x20       /* Mailbox 5 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF5  0x0       
 #define                    MBRIF6  0x40       /* Mailbox 6 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF6  0x0       
 #define                    MBRIF7  0x80       /* Mailbox 7 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF7  0x0       
 #define                    MBRIF8  0x100      /* Mailbox 8 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF8  0x0       
 #define                    MBRIF9  0x200      /* Mailbox 9 Mailbox Receive Interrupt Flag */
-#define                   nMBRIF9  0x0       
 #define                   MBRIF10  0x400      /* Mailbox 10 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF10  0x0       
 #define                   MBRIF11  0x800      /* Mailbox 11 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF11  0x0       
 #define                   MBRIF12  0x1000     /* Mailbox 12 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF12  0x0       
 #define                   MBRIF13  0x2000     /* Mailbox 13 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF13  0x0       
 #define                   MBRIF14  0x4000     /* Mailbox 14 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF14  0x0       
 #define                   MBRIF15  0x8000     /* Mailbox 15 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF15  0x0       
 
 /* Bit masks for CAN0_MBRIF2 */
 
 #define                   MBRIF16  0x1        /* Mailbox 16 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF16  0x0       
 #define                   MBRIF17  0x2        /* Mailbox 17 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF17  0x0       
 #define                   MBRIF18  0x4        /* Mailbox 18 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF18  0x0       
 #define                   MBRIF19  0x8        /* Mailbox 19 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF19  0x0       
 #define                   MBRIF20  0x10       /* Mailbox 20 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF20  0x0       
 #define                   MBRIF21  0x20       /* Mailbox 21 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF21  0x0       
 #define                   MBRIF22  0x40       /* Mailbox 22 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF22  0x0       
 #define                   MBRIF23  0x80       /* Mailbox 23 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF23  0x0       
 #define                   MBRIF24  0x100      /* Mailbox 24 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF24  0x0       
 #define                   MBRIF25  0x200      /* Mailbox 25 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF25  0x0       
 #define                   MBRIF26  0x400      /* Mailbox 26 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF26  0x0       
 #define                   MBRIF27  0x800      /* Mailbox 27 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF27  0x0       
 #define                   MBRIF28  0x1000     /* Mailbox 28 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF28  0x0       
 #define                   MBRIF29  0x2000     /* Mailbox 29 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF29  0x0       
 #define                   MBRIF30  0x4000     /* Mailbox 30 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF30  0x0       
 #define                   MBRIF31  0x8000     /* Mailbox 31 Mailbox Receive Interrupt Flag */
-#define                  nMBRIF31  0x0       
 
 /* Bit masks for EPPIx_STATUS */
 
 #define                 CFIFO_ERR  0x1        /* Chroma FIFO Error */
-#define                nCFIFO_ERR  0x0       
 #define                 YFIFO_ERR  0x2        /* Luma FIFO Error */
-#define                nYFIFO_ERR  0x0       
 #define                 LTERR_OVR  0x4        /* Line Track Overflow */
-#define                nLTERR_OVR  0x0       
 #define                LTERR_UNDR  0x8        /* Line Track Underflow */
-#define               nLTERR_UNDR  0x0       
 #define                 FTERR_OVR  0x10       /* Frame Track Overflow */
-#define                nFTERR_OVR  0x0       
 #define                FTERR_UNDR  0x20       /* Frame Track Underflow */
-#define               nFTERR_UNDR  0x0       
 #define                  ERR_NCOR  0x40       /* Preamble Error Not Corrected */
-#define                 nERR_NCOR  0x0       
 #define                   DMA1URQ  0x80       /* DMA1 Urgent Request */
-#define                  nDMA1URQ  0x0       
 #define                   DMA0URQ  0x100      /* DMA0 Urgent Request */
-#define                  nDMA0URQ  0x0       
 #define                   ERR_DET  0x4000     /* Preamble Error Detected */
-#define                  nERR_DET  0x0       
 #define                       FLD  0x8000     /* Field */
-#define                      nFLD  0x0       
 
 /* Bit masks for EPPIx_CONTROL */
 
 #define                   EPPI_EN  0x1        /* Enable */
-#define                  nEPPI_EN  0x0       
 #define                  EPPI_DIR  0x2        /* Direction */
-#define                 nEPPI_DIR  0x0       
 #define                  XFR_TYPE  0xc        /* Operating Mode */
 #define                    FS_CFG  0x30       /* Frame Sync Configuration */
 #define                   FLD_SEL  0x40       /* Field Select/Trigger */
-#define                  nFLD_SEL  0x0       
 #define                  ITU_TYPE  0x80       /* ITU Interlaced or Progressive */
-#define                 nITU_TYPE  0x0       
 #define                  BLANKGEN  0x100      /* ITU Output Mode with Internal Blanking Generation */
-#define                 nBLANKGEN  0x0       
 #define                   ICLKGEN  0x200      /* Internal Clock Generation */
-#define                  nICLKGEN  0x0       
 #define                    IFSGEN  0x400      /* Internal Frame Sync Generation */
-#define                   nIFSGEN  0x0       
 #define                      POLC  0x1800     /* Frame Sync and Data Driving/Sampling Edges */
 #define                      POLS  0x6000     /* Frame Sync Polarity */
 #define                   DLENGTH  0x38000    /* Data Length */
 #define                   SKIP_EN  0x40000    /* Skip Enable */
-#define                  nSKIP_EN  0x0       
 #define                   SKIP_EO  0x80000    /* Skip Even or Odd */
-#define                  nSKIP_EO  0x0       
 #define                    PACKEN  0x100000   /* Packing/Unpacking Enable */
-#define                   nPACKEN  0x0       
 #define                    SWAPEN  0x200000   /* Swap Enable */
-#define                   nSWAPEN  0x0       
 #define                  SIGN_EXT  0x400000   /* Sign Extension or Zero-filled / Data Split Format */
-#define                 nSIGN_EXT  0x0       
 #define             SPLT_EVEN_ODD  0x800000   /* Split Even and Odd Data Samples */
-#define            nSPLT_EVEN_ODD  0x0       
 #define               SUBSPLT_ODD  0x1000000  /* Sub-split Odd Samples */
-#define              nSUBSPLT_ODD  0x0       
 #define                    DMACFG  0x2000000  /* One or Two DMA Channels Mode */
-#define                   nDMACFG  0x0       
 #define                RGB_FMT_EN  0x4000000  /* RGB Formatting Enable */
-#define               nRGB_FMT_EN  0x0       
 #define                  FIFO_RWM  0x18000000 /* FIFO Regular Watermarks */
 #define                  FIFO_UWM  0x60000000 /* FIFO Urgent Watermarks */
 
+#define DLEN_8		(0 << 15) /* 000 - 8 bits */
+#define DLEN_10		(1 << 15) /* 001 - 10 bits */
+#define DLEN_12		(2 << 15) /* 010 - 12 bits */
+#define DLEN_14		(3 << 15) /* 011 - 14 bits */
+#define DLEN_16		(4 << 15) /* 100 - 16 bits */
+#define DLEN_18		(5 << 15) /* 101 - 18 bits */
+#define DLEN_24		(6 << 15) /* 110 - 24 bits */
+
+
 /* Bit masks for EPPIx_FS2W_LVB */
 
 #define                   F1VB_BD  0xff       /* Vertical Blanking before Field 1 Active Data */
@@ -3951,60 +3085,36 @@
 /* Bit masks for SPIx_CTL */
 
 #define                       SPE  0x4000     /* SPI Enable */
-#define                      nSPE  0x0       
 #define                       WOM  0x2000     /* Write Open Drain Master */
-#define                      nWOM  0x0       
 #define                      MSTR  0x1000     /* Master Mode */
-#define                     nMSTR  0x0       
 #define                      CPOL  0x800      /* Clock Polarity */
-#define                     nCPOL  0x0       
 #define                      CPHA  0x400      /* Clock Phase */
-#define                     nCPHA  0x0       
 #define                      LSBF  0x200      /* LSB First */
-#define                     nLSBF  0x0       
 #define                      SIZE  0x100      /* Size of Words */
-#define                     nSIZE  0x0       
 #define                     EMISO  0x20       /* Enable MISO Output */
-#define                    nEMISO  0x0       
 #define                      PSSE  0x10       /* Slave-Select Enable */
-#define                     nPSSE  0x0       
 #define                        GM  0x8        /* Get More Data */
-#define                       nGM  0x0       
 #define                        SZ  0x4        /* Send Zero */
-#define                       nSZ  0x0       
 #define                     TIMOD  0x3        /* Transfer Initiation Mode */
 
 /* Bit masks for SPIx_FLG */
 
 #define                      FLS1  0x2        /* Slave Select Enable 1 */
-#define                     nFLS1  0x0       
 #define                      FLS2  0x4        /* Slave Select Enable 2 */
-#define                     nFLS2  0x0       
 #define                      FLS3  0x8        /* Slave Select Enable 3 */
-#define                     nFLS3  0x0       
 #define                      FLG1  0x200      /* Slave Select Value 1 */
-#define                     nFLG1  0x0       
 #define                      FLG2  0x400      /* Slave Select Value 2 */
-#define                     nFLG2  0x0       
 #define                      FLG3  0x800      /* Slave Select Value 3 */
-#define                     nFLG3  0x0       
 
 /* Bit masks for SPIx_STAT */
 
 #define                     TXCOL  0x40       /* Transmit Collision Error */
-#define                    nTXCOL  0x0       
 #define                       RXS  0x20       /* RDBR Data Buffer Status */
-#define                      nRXS  0x0       
 #define                      RBSY  0x10       /* Receive Error */
-#define                     nRBSY  0x0       
 #define                       TXS  0x8        /* TDBR Data Buffer Status */
-#define                      nTXS  0x0       
 #define                       TXE  0x4        /* Transmission Error */
-#define                      nTXE  0x0       
 #define                      MODF  0x2        /* Mode Fault Error */
-#define                     nMODF  0x0       
 #define                      SPIF  0x1        /* SPI Finished */
-#define                     nSPIF  0x0       
 
 /* Bit masks for SPIx_TDBR */
 
@@ -4028,9 +3138,7 @@
 
 #define                  PRESCALE  0x7f       /* Prescale Value */
 #define                   TWI_ENA  0x80       /* TWI Enable */
-#define                  nTWI_ENA  0x0       
 #define                      SCCB  0x200      /* Serial Camera Control Bus */
-#define                     nSCCB  0x0       
 
 /* Bit maskes for TWIx_CLKDIV */
 
@@ -4040,13 +3148,9 @@
 /* Bit maskes for TWIx_SLAVE_CTL */
 
 #define                       SEN  0x1        /* Slave Enable */
-#define                      nSEN  0x0       
 #define                    STDVAL  0x4        /* Slave Transmit Data Valid */
-#define                   nSTDVAL  0x0       
 #define                       NAK  0x8        /* Not Acknowledge */
-#define                      nNAK  0x0       
 #define                       GEN  0x10       /* General Call Enable */
-#define                      nGEN  0x0       
 
 /* Bit maskes for TWIx_SLAVE_ADDR */
 
@@ -4055,27 +3159,18 @@
 /* Bit maskes for TWIx_SLAVE_STAT */
 
 #define                      SDIR  0x1        /* Slave Transfer Direction */
-#define                     nSDIR  0x0       
 #define                     GCALL  0x2        /* General Call */
-#define                    nGCALL  0x0       
 
 /* Bit maskes for TWIx_MASTER_CTL */
 
 #define                       MEN  0x1        /* Master Mode Enable */
-#define                      nMEN  0x0       
 #define                      MDIR  0x4        /* Master Transfer Direction */
-#define                     nMDIR  0x0       
 #define                      FAST  0x8        /* Fast Mode */
-#define                     nFAST  0x0       
 #define                      STOP  0x10       /* Issue Stop Condition */
-#define                     nSTOP  0x0       
 #define                    RSTART  0x20       /* Repeat Start */
-#define                   nRSTART  0x0       
 #define                      DCNT  0x3fc0     /* Data Transfer Count */
 #define                    SDAOVR  0x4000     /* Serial Data Override */
-#define                   nSDAOVR  0x0       
 #define                    SCLOVR  0x8000     /* Serial Clock Override */
-#define                   nSCLOVR  0x0       
 
 /* Bit maskes for TWIx_MASTER_ADDR */
 
@@ -4084,34 +3179,21 @@
 /* Bit maskes for TWIx_MASTER_STAT */
 
 #define                     MPROG  0x1        /* Master Transfer in Progress */
-#define                    nMPROG  0x0       
 #define                   LOSTARB  0x2        /* Lost Arbitration */
-#define                  nLOSTARB  0x0       
 #define                      ANAK  0x4        /* Address Not Acknowledged */
-#define                     nANAK  0x0       
 #define                      DNAK  0x8        /* Data Not Acknowledged */
-#define                     nDNAK  0x0       
 #define                  BUFRDERR  0x10       /* Buffer Read Error */
-#define                 nBUFRDERR  0x0       
 #define                  BUFWRERR  0x20       /* Buffer Write Error */
-#define                 nBUFWRERR  0x0       
 #define                    SDASEN  0x40       /* Serial Data Sense */
-#define                   nSDASEN  0x0       
 #define                    SCLSEN  0x80       /* Serial Clock Sense */
-#define                   nSCLSEN  0x0       
 #define                   BUSBUSY  0x100      /* Bus Busy */
-#define                  nBUSBUSY  0x0       
 
 /* Bit maskes for TWIx_FIFO_CTL */
 
 #define                  XMTFLUSH  0x1        /* Transmit Buffer Flush */
-#define                 nXMTFLUSH  0x0       
 #define                  RCVFLUSH  0x2        /* Receive Buffer Flush */
-#define                 nRCVFLUSH  0x0       
 #define                 XMTINTLEN  0x4        /* Transmit Buffer Interrupt Length */
-#define                nXMTINTLEN  0x0       
 #define                 RCVINTLEN  0x8        /* Receive Buffer Interrupt Length */
-#define                nRCVINTLEN  0x0       
 
 /* Bit maskes for TWIx_FIFO_STAT */
 
@@ -4121,40 +3203,24 @@
 /* Bit maskes for TWIx_INT_MASK */
 
 #define                    SINITM  0x1        /* Slave Transfer Initiated Interrupt Mask */
-#define                   nSINITM  0x0       
 #define                    SCOMPM  0x2        /* Slave Transfer Complete Interrupt Mask */
-#define                   nSCOMPM  0x0       
 #define                     SERRM  0x4        /* Slave Transfer Error Interrupt Mask */
-#define                    nSERRM  0x0       
 #define                     SOVFM  0x8        /* Slave Overflow Interrupt Mask */
-#define                    nSOVFM  0x0       
 #define                    MCOMPM  0x10       /* Master Transfer Complete Interrupt Mask */
-#define                   nMCOMPM  0x0       
 #define                     MERRM  0x20       /* Master Transfer Error Interrupt Mask */
-#define                    nMERRM  0x0       
 #define                  XMTSERVM  0x40       /* Transmit FIFO Service Interrupt Mask */
-#define                 nXMTSERVM  0x0       
 #define                  RCVSERVM  0x80       /* Receive FIFO Service Interrupt Mask */
-#define                 nRCVSERVM  0x0       
 
 /* Bit maskes for TWIx_INT_STAT */
 
 #define                     SINIT  0x1        /* Slave Transfer Initiated */
-#define                    nSINIT  0x0       
 #define                     SCOMP  0x2        /* Slave Transfer Complete */
-#define                    nSCOMP  0x0       
 #define                      SERR  0x4        /* Slave Transfer Error */
-#define                     nSERR  0x0       
 #define                      SOVF  0x8        /* Slave Overflow */
-#define                     nSOVF  0x0       
 #define                     MCOMP  0x10       /* Master Transfer Complete */
-#define                    nMCOMP  0x0       
 #define                      MERR  0x20       /* Master Transfer Error */
-#define                     nMERR  0x0       
 #define                   XMTSERV  0x40       /* Transmit FIFO Service */
-#define                  nXMTSERV  0x0       
 #define                   RCVSERV  0x80       /* Receive FIFO Service */
-#define                  nRCVSERV  0x0       
 
 /* Bit maskes for TWIx_XMT_DATA8 */
 
@@ -4175,81 +3241,51 @@
 /* Bit masks for SPORTx_TCR1 */
 
 #define                     TCKFE  0x4000     /* Clock Falling Edge Select */
-#define                    nTCKFE  0x0       
 #define                     LATFS  0x2000     /* Late Transmit Frame Sync */
-#define                    nLATFS  0x0       
 #define                      LTFS  0x1000     /* Low Transmit Frame Sync Select */
-#define                     nLTFS  0x0       
 #define                     DITFS  0x800      /* Data-Independent Transmit Frame Sync Select */
-#define                    nDITFS  0x0       
 #define                      TFSR  0x400      /* Transmit Frame Sync Required Select */
-#define                     nTFSR  0x0       
 #define                      ITFS  0x200      /* Internal Transmit Frame Sync Select */
-#define                     nITFS  0x0       
 #define                    TLSBIT  0x10       /* Transmit Bit Order */
-#define                   nTLSBIT  0x0       
 #define                    TDTYPE  0xc        /* Data Formatting Type Select */
 #define                     ITCLK  0x2        /* Internal Transmit Clock Select */
-#define                    nITCLK  0x0       
 #define                     TSPEN  0x1        /* Transmit Enable */
-#define                    nTSPEN  0x0       
 
 /* Bit masks for SPORTx_TCR2 */
 
 #define                     TRFST  0x400      /* Left/Right Order */
-#define                    nTRFST  0x0       
 #define                     TSFSE  0x200      /* Transmit Stereo Frame Sync Enable */
-#define                    nTSFSE  0x0       
 #define                      TXSE  0x100      /* TxSEC Enable */
-#define                     nTXSE  0x0       
 #define                    SLEN_T  0x1f       /* SPORT Word Length */
 
 /* Bit masks for SPORTx_RCR1 */
 
 #define                     RCKFE  0x4000     /* Clock Falling Edge Select */
-#define                    nRCKFE  0x0       
 #define                     LARFS  0x2000     /* Late Receive Frame Sync */
-#define                    nLARFS  0x0       
 #define                      LRFS  0x1000     /* Low Receive Frame Sync Select */
-#define                     nLRFS  0x0       
 #define                      RFSR  0x400      /* Receive Frame Sync Required Select */
-#define                     nRFSR  0x0       
 #define                      IRFS  0x200      /* Internal Receive Frame Sync Select */
-#define                     nIRFS  0x0       
 #define                    RLSBIT  0x10       /* Receive Bit Order */
-#define                   nRLSBIT  0x0       
 #define                    RDTYPE  0xc        /* Data Formatting Type Select */
 #define                     IRCLK  0x2        /* Internal Receive Clock Select */
-#define                    nIRCLK  0x0       
 #define                     RSPEN  0x1        /* Receive Enable */
-#define                    nRSPEN  0x0       
 
 /* Bit masks for SPORTx_RCR2 */
 
 #define                     RRFST  0x400      /* Left/Right Order */
-#define                    nRRFST  0x0       
 #define                     RSFSE  0x200      /* Receive Stereo Frame Sync Enable */
-#define                    nRSFSE  0x0       
 #define                      RXSE  0x100      /* RxSEC Enable */
-#define                     nRXSE  0x0       
 #define                    SLEN_R  0x1f       /* SPORT Word Length */
 
 /* Bit masks for SPORTx_STAT */
 
 #define                     TXHRE  0x40       /* Transmit Hold Register Empty */
-#define                    nTXHRE  0x0       
 #define                      TOVF  0x20       /* Sticky Transmit Overflow Status */
-#define                     nTOVF  0x0       
 #define                      TUVF  0x10       /* Sticky Transmit Underflow Status */
-#define                     nTUVF  0x0       
 #define                       TXF  0x8        /* Transmit FIFO Full Status */
-#define                      nTXF  0x0       
 #define                      ROVF  0x4        /* Sticky Receive Overflow Status */
-#define                     nROVF  0x0       
 #define                      RUVF  0x2        /* Sticky Receive Underflow Status */
-#define                     nRUVF  0x0       
 #define                      RXNE  0x1        /* Receive FIFO Not Empty Status */
-#define                     nRXNE  0x0       
 
 /* Bit masks for SPORTx_MCMC1 */
 
@@ -4260,13 +3296,9 @@
 
 #define                       MFD  0xf000     /* Multi channel Frame Delay */
 #define                      FSDR  0x80       /* Frame Sync to Data Relationship */
-#define                     nFSDR  0x0       
 #define                     MCMEM  0x10       /* Multi channel Frame Mode Enable */
-#define                    nMCMEM  0x0       
 #define                   MCDRXPE  0x8        /* Multi channel DMA Receive Packing */
-#define                  nMCDRXPE  0x0       
 #define                   MCDTXPE  0x4        /* Multi channel DMA Transmit Packing */
-#define                  nMCDTXPE  0x0       
 #define                     MCCRM  0x3        /* 2X Clock Recovery Mode */
 
 /* Bit masks for SPORTx_CHNL */
@@ -4280,115 +3312,59 @@
 #define                       WLS  0x3        /* Word Length Select */
 #endif
 #define                       STB  0x4        /* Stop Bits */
-#define                      nSTB  0x0       
 #define                       PEN  0x8        /* Parity Enable */
-#define                      nPEN  0x0       
 #define                       EPS  0x10       /* Even Parity Select */
-#define                      nEPS  0x0       
 #define                       STP  0x20       /* Sticky Parity */
-#define                      nSTP  0x0       
 #define                        SB  0x40       /* Set Break */
-#define                       nSB  0x0       
 
 /* Bit masks for UARTx_MCR */
 
 #define                      XOFF  0x1        /* Transmitter Off */
-#define                     nXOFF  0x0       
 #define                      MRTS  0x2        /* Manual Request To Send */
-#define                     nMRTS  0x0       
 #define                      RFIT  0x4        /* Receive FIFO IRQ Threshold */
-#define                     nRFIT  0x0       
 #define                      RFRT  0x8        /* Receive FIFO RTS Threshold */
-#define                     nRFRT  0x0       
 #define                  LOOP_ENA  0x10       /* Loopback Mode Enable */
-#define                 nLOOP_ENA  0x0       
 #define                     FCPOL  0x20       /* Flow Control Pin Polarity */
-#define                    nFCPOL  0x0       
 #define                      ARTS  0x40       /* Automatic Request To Send */
-#define                     nARTS  0x0       
 #define                      ACTS  0x80       /* Automatic Clear To Send */
-#define                     nACTS  0x0       
 
 /* Bit masks for UARTx_LSR */
 
 #define                        DR  0x1        /* Data Ready */
-#define                       nDR  0x0       
 #define                        OE  0x2        /* Overrun Error */
-#define                       nOE  0x0       
 #define                        PE  0x4        /* Parity Error */
-#define                       nPE  0x0       
 #define                        FE  0x8        /* Framing Error */
-#define                       nFE  0x0       
 #define                        BI  0x10       /* Break Interrupt */
-#define                       nBI  0x0       
 #define                      THRE  0x20       /* THR Empty */
-#define                     nTHRE  0x0       
 #define                      TEMT  0x40       /* Transmitter Empty */
-#define                     nTEMT  0x0       
 #define                       TFI  0x80       /* Transmission Finished Indicator */
-#define                      nTFI  0x0       
 
 /* Bit masks for UARTx_MSR */
 
 #define                      SCTS  0x1        /* Sticky CTS */
-#define                     nSCTS  0x0       
 #define                       CTS  0x10       /* Clear To Send */
-#define                      nCTS  0x0       
 #define                      RFCS  0x20       /* Receive FIFO Count Status */
-#define                     nRFCS  0x0       
 
-/* Bit masks for UARTx_IER_SET */
+/* Bit masks for UARTx_IER_SET & UARTx_IER_CLEAR */
 
-#define                   ERBFI_S  0x1        /* Enable Receive Buffer Full Interrupt */
-#define                  nERBFI_S  0x0       
-#define                   ETBEI_S  0x2        /* Enable Transmit Buffer Empty Interrupt */
-#define                  nETBEI_S  0x0       
-#define                    ELSI_S  0x4        /* Enable Receive Status Interrupt */
-#define                   nELSI_S  0x0       
-#define                   EDSSI_S  0x8        /* Enable Modem Status Interrupt */
-#define                  nEDSSI_S  0x0       
-#define                  EDTPTI_S  0x10       /* Enable DMA Transmit PIRQ Interrupt */
-#define                 nEDTPTI_S  0x0       
-#define                    ETFI_S  0x20       /* Enable Transmission Finished Interrupt */
-#define                   nETFI_S  0x0       
-#define                   ERFCI_S  0x40       /* Enable Receive FIFO Count Interrupt */
-#define                  nERFCI_S  0x0       
-
-/* Bit masks for UARTx_IER_CLEAR */
-
-#define                   ERBFI_C  0x1        /* Enable Receive Buffer Full Interrupt */
-#define                  nERBFI_C  0x0       
-#define                   ETBEI_C  0x2        /* Enable Transmit Buffer Empty Interrupt */
-#define                  nETBEI_C  0x0       
-#define                    ELSI_C  0x4        /* Enable Receive Status Interrupt */
-#define                   nELSI_C  0x0       
-#define                   EDSSI_C  0x8        /* Enable Modem Status Interrupt */
-#define                  nEDSSI_C  0x0       
-#define                  EDTPTI_C  0x10       /* Enable DMA Transmit PIRQ Interrupt */
-#define                 nEDTPTI_C  0x0       
-#define                    ETFI_C  0x20       /* Enable Transmission Finished Interrupt */
-#define                   nETFI_C  0x0       
-#define                   ERFCI_C  0x40       /* Enable Receive FIFO Count Interrupt */
-#define                  nERFCI_C  0x0       
+#define                   ERBFI  0x1        /* Enable Receive Buffer Full Interrupt */
+#define                   ETBEI  0x2        /* Enable Transmit Buffer Empty Interrupt */
+#define                    ELSI  0x4        /* Enable Receive Status Interrupt */
+#define                   EDSSI  0x8        /* Enable Modem Status Interrupt */
+#define                  EDTPTI  0x10       /* Enable DMA Transmit PIRQ Interrupt */
+#define                    ETFI  0x20       /* Enable Transmission Finished Interrupt */
+#define                   ERFCI  0x40       /* Enable Receive FIFO Count Interrupt */
 
 /* Bit masks for UARTx_GCTL */
 
 #define                      UCEN  0x1        /* UART Enable */
-#define                     nUCEN  0x0       
 #define                      IREN  0x2        /* IrDA Mode Enable */
-#define                     nIREN  0x0       
 #define                     TPOLC  0x4        /* IrDA TX Polarity Change */
-#define                    nTPOLC  0x0       
 #define                     RPOLC  0x8        /* IrDA RX Polarity Change */
-#define                    nRPOLC  0x0       
 #define                       FPE  0x10       /* Force Parity Error */
-#define                      nFPE  0x0       
 #define                       FFE  0x20       /* Force Framing Error */
-#define                      nFFE  0x0       
 #define                      EDBO  0x40       /* Enable Divide-by-One */
-#define                     nEDBO  0x0       
 #define                     EGLSI  0x80       /* Enable Global LS Interrupt */
-#define                    nEGLSI  0x0       
 
 
 /* ******************************************* */
@@ -4398,32 +3374,32 @@
 /* BCODE bit field options (SYSCFG register) */
 
 #define BCODE_WAKEUP    0x0000  /* boot according to wake-up condition */
-#define BCODE_FULLBOOT  0x0010  /* always perform full boot */ 
+#define BCODE_FULLBOOT  0x0010  /* always perform full boot */
 #define BCODE_QUICKBOOT 0x0020  /* always perform quick boot */
 #define BCODE_NOBOOT    0x0030  /* always perform full boot */
 
 /* CNT_COMMAND bit field options */
- 
+
 #define W1LCNT_ZERO   0x0001   /* write 1 to load CNT_COUNTER with zero */
 #define W1LCNT_MIN    0x0004   /* write 1 to load CNT_COUNTER from CNT_MIN */
 #define W1LCNT_MAX    0x0008   /* write 1 to load CNT_COUNTER from CNT_MAX */
- 
+
 #define W1LMIN_ZERO   0x0010   /* write 1 to load CNT_MIN with zero */
 #define W1LMIN_CNT    0x0020   /* write 1 to load CNT_MIN from CNT_COUNTER */
 #define W1LMIN_MAX    0x0080   /* write 1 to load CNT_MIN from CNT_MAX */
- 
+
 #define W1LMAX_ZERO   0x0100   /* write 1 to load CNT_MAX with zero */
 #define W1LMAX_CNT    0x0200   /* write 1 to load CNT_MAX from CNT_COUNTER */
 #define W1LMAX_MIN    0x0400   /* write 1 to load CNT_MAX from CNT_MIN */
- 
+
 /* CNT_CONFIG bit field options */
- 
+
 #define CNTMODE_QUADENC  0x0000  /* quadrature encoder mode */
 #define CNTMODE_BINENC   0x0100  /* binary encoder mode */
 #define CNTMODE_UDCNT    0x0200  /* up/down counter mode */
 #define CNTMODE_DIRCNT   0x0400  /* direction counter mode */
 #define CNTMODE_DIRTMR   0x0500  /* direction timer mode */
- 
+
 #define BNDMODE_COMP     0x0000  /* boundary compare mode */
 #define BNDMODE_ZERO     0x1000  /* boundary compare and zero mode */
 #define BNDMODE_CAPT     0x2000  /* boundary capture mode */
@@ -4436,7 +3412,7 @@
 #define EXT_CLK  0x0003
 
 /* UARTx_LCR bit field options */
- 
+
 #define WLS_5   0x0000    /* 5 data bits */
 #define WLS_6   0x0001    /* 6 data bits */
 #define WLS_7   0x0002    /* 7 data bits */
@@ -4484,7 +3460,7 @@
 #define PIQ30 0x40000000
 #define PIQ31 0x80000000
 
-/* PORT A Bit Definitions for the registers 
+/* PORT A Bit Definitions for the registers
 PORTA, PORTA_SET, PORTA_CLEAR,
 PORTA_DIR_SET, PORTA_DIR_CLEAR, PORTA_INEN,
 PORTA_FER registers
@@ -4507,7 +3483,7 @@
 #define PA14 0x4000
 #define PA15 0x8000
 
-/* PORT B Bit Definitions for the registers 
+/* PORT B Bit Definitions for the registers
 PORTB, PORTB_SET, PORTB_CLEAR,
 PORTB_DIR_SET, PORTB_DIR_CLEAR, PORTB_INEN,
 PORTB_FER registers
@@ -4530,7 +3506,7 @@
 #define PB14 0x4000
 
 
-/* PORT C Bit Definitions for the registers 
+/* PORT C Bit Definitions for the registers
 PORTC, PORTC_SET, PORTC_CLEAR,
 PORTC_DIR_SET, PORTC_DIR_CLEAR, PORTC_INEN,
 PORTC_FER registers
@@ -4553,7 +3529,7 @@
 #define PC13 0x2000
 
 
-/* PORT D Bit Definitions for the registers 
+/* PORT D Bit Definitions for the registers
 PORTD, PORTD_SET, PORTD_CLEAR,
 PORTD_DIR_SET, PORTD_DIR_CLEAR, PORTD_INEN,
 PORTD_FER registers
@@ -4576,7 +3552,7 @@
 #define PD14 0x4000
 #define PD15 0x8000
 
-/* PORT E Bit Definitions for the registers 
+/* PORT E Bit Definitions for the registers
 PORTE, PORTE_SET, PORTE_CLEAR,
 PORTE_DIR_SET, PORTE_DIR_CLEAR, PORTE_INEN,
 PORTE_FER registers
@@ -4600,7 +3576,7 @@
 #define PE14 0x4000
 #define PE15 0x8000
 
-/* PORT F Bit Definitions for the registers 
+/* PORT F Bit Definitions for the registers
 PORTF, PORTF_SET, PORTF_CLEAR,
 PORTF_DIR_SET, PORTF_DIR_CLEAR, PORTF_INEN,
 PORTF_FER registers
@@ -4624,7 +3600,7 @@
 #define PF14 0x4000
 #define PF15 0x8000
 
-/* PORT G Bit Definitions for the registers 
+/* PORT G Bit Definitions for the registers
 PORTG, PORTG_SET, PORTG_CLEAR,
 PORTG_DIR_SET, PORTG_DIR_CLEAR, PORTG_INEN,
 PORTG_FER registers
@@ -4648,7 +3624,7 @@
 #define PG14 0x4000
 #define PG15 0x8000
 
-/* PORT H Bit Definitions for the registers 
+/* PORT H Bit Definitions for the registers
 PORTH, PORTH_SET, PORTH_CLEAR,
 PORTH_DIR_SET, PORTH_DIR_CLEAR, PORTH_INEN,
 PORTH_FER registers
@@ -4671,7 +3647,7 @@
 #define PH13 0x2000
 
 
-/* PORT I Bit Definitions for the registers 
+/* PORT I Bit Definitions for the registers
 PORTI, PORTI_SET, PORTI_CLEAR,
 PORTI_DIR_SET, PORTI_DIR_CLEAR, PORTI_INEN,
 PORTI_FER registers
@@ -4695,7 +3671,7 @@
 #define PI14 0x4000
 #define PI15 0x8000
 
-/* PORT J Bit Definitions for the registers 
+/* PORT J Bit Definitions for the registers
 PORTJ, PORTJ_SET, PORTJ_CLEAR,
 PORTJ_DIR_SET, PORTJ_DIR_CLEAR, PORTJ_INEN,
 PORTJ_FER registers
@@ -4716,7 +3692,7 @@
 #define PJ11 0x0800
 #define PJ12 0x1000
 #define PJ13 0x2000
- 
+
 
 /* Port Muxing Bit Fields for PORTx_MUX Registers */
 
@@ -4860,7 +3836,7 @@
 #define B0MAP_PIL 0x00000006 /* Map Port I Low to Byte 0 */
 #define B0MAP_PJL 0x00000007 /* Map Port J Low to Byte 0 */
 
-#define B1MAP_PCH 0x00000000 /* Map Port C High to Byte 1 */ 
+#define B1MAP_PCH 0x00000000 /* Map Port C High to Byte 1 */
 #define B1MAP_PDH 0x00000100 /* Map Port D High to Byte 1 */
 #define B1MAP_PEH 0x00000200 /* Map Port E High to Byte 1 */
 #define B1MAP_PFH 0x00000300 /* Map Port F High to Byte 1 */
@@ -4869,27 +3845,27 @@
 #define B1MAP_PIH 0x00000600 /* Map Port I High to Byte 1 */
 #define B1MAP_PJH 0x00000700 /* Map Port J High to Byte 1 */
 
-#define B2MAP_PCL 0x00000000 /* Map Port C Low to Byte 2 */ 
-#define B2MAP_PDL 0x00010000 /* Map Port D Low to Byte 2 */ 
-#define B2MAP_PEL 0x00020000 /* Map Port E Low to Byte 2 */ 
-#define B2MAP_PFL 0x00030000 /* Map Port F Low to Byte 2 */ 
-#define B2MAP_PGL 0x00040000 /* Map Port G Low to Byte 2 */ 
-#define B2MAP_PHL 0x00050000 /* Map Port H Low to Byte 2 */ 
-#define B2MAP_PIL 0x00060000 /* Map Port I Low to Byte 2 */ 
-#define B2MAP_PJL 0x00070000 /* Map Port J Low to Byte 2 */ 
+#define B2MAP_PCL 0x00000000 /* Map Port C Low to Byte 2 */
+#define B2MAP_PDL 0x00010000 /* Map Port D Low to Byte 2 */
+#define B2MAP_PEL 0x00020000 /* Map Port E Low to Byte 2 */
+#define B2MAP_PFL 0x00030000 /* Map Port F Low to Byte 2 */
+#define B2MAP_PGL 0x00040000 /* Map Port G Low to Byte 2 */
+#define B2MAP_PHL 0x00050000 /* Map Port H Low to Byte 2 */
+#define B2MAP_PIL 0x00060000 /* Map Port I Low to Byte 2 */
+#define B2MAP_PJL 0x00070000 /* Map Port J Low to Byte 2 */
 
-#define B3MAP_PCH 0x00000000 /* Map Port C High to Byte 3 */ 
-#define B3MAP_PDH 0x01000000 /* Map Port D High to Byte 3 */ 
-#define B3MAP_PEH 0x02000000 /* Map Port E High to Byte 3 */ 
-#define B3MAP_PFH 0x03000000 /* Map Port F High to Byte 3 */ 
-#define B3MAP_PGH 0x04000000 /* Map Port G High to Byte 3 */ 
-#define B3MAP_PHH 0x05000000 /* Map Port H High to Byte 3 */ 
-#define B3MAP_PIH 0x06000000 /* Map Port I High to Byte 3 */ 
-#define B3MAP_PJH 0x07000000 /* Map Port J High to Byte 3 */ 
+#define B3MAP_PCH 0x00000000 /* Map Port C High to Byte 3 */
+#define B3MAP_PDH 0x01000000 /* Map Port D High to Byte 3 */
+#define B3MAP_PEH 0x02000000 /* Map Port E High to Byte 3 */
+#define B3MAP_PFH 0x03000000 /* Map Port F High to Byte 3 */
+#define B3MAP_PGH 0x04000000 /* Map Port G High to Byte 3 */
+#define B3MAP_PHH 0x05000000 /* Map Port H High to Byte 3 */
+#define B3MAP_PIH 0x06000000 /* Map Port I High to Byte 3 */
+#define B3MAP_PJH 0x07000000 /* Map Port J High to Byte 3 */
 
 
 /* for legacy compatibility */
- 
+
 #define WLS(x)  (((x)-5) & 0x03) /* Word Length Select */
 #define W1LMAX_MAX W1LMAX_MIN
 #define EBIU_AMCBCTL0 EBIU_AMBCTL0
diff --git a/include/asm-blackfin/mach-bf548/dma.h b/include/asm-blackfin/mach-bf548/dma.h
new file mode 100644
index 0000000..fcc8b4c
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/dma.h
@@ -0,0 +1,73 @@
+/*
+ * file:         include/asm-blackfin/mach-bf548/dma.h
+ * based on:
+ * author:
+ *
+ * created:
+ * description:
+ *	system mmr register map
+ * rev:
+ *
+ * modified:
+ *
+ *
+ * bugs:         enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose.  see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _MACH_DMA_H_
+#define _MACH_DMA_H_
+
+#define CH_SPORT0_RX		0
+#define CH_SPORT0_TX		1
+#define CH_SPORT1_RX		2
+#define CH_SPORT1_TX		3
+#define CH_SPI0			4
+#define CH_SPI1			5
+#define CH_UART0_RX 		6
+#define CH_UART0_TX 		7
+#define CH_UART1_RX 		8
+#define CH_UART1_TX 		9
+#define CH_ATAPI_RX		10
+#define CH_ATAPI_TX		11
+#define CH_EPPI0		12
+#define CH_EPPI1		13
+#define CH_EPPI2		14
+#define CH_PIXC_IMAGE		15
+#define CH_PIXC_OVERLAY		16
+#define CH_PIXC_OUTPUT		17
+#define CH_SPORT2_RX		18
+#define CH_SPORT2_TX		19
+#define CH_SPORT3_RX		20
+#define CH_SPORT3_TX		21
+#define CH_SDH			22
+#define CH_SPI2			23
+
+#define CH_MEM_STREAM0_DEST	24
+#define CH_MEM_STREAM0_SRC	25
+#define CH_MEM_STREAM1_DEST	26
+#define CH_MEM_STREAM1_SRC	27
+#define CH_MEM_STREAM2_DEST	28
+#define CH_MEM_STREAM2_SRC	29
+#define CH_MEM_STREAM3_DEST	30
+#define CH_MEM_STREAM3_SRC	31
+
+#define MAX_BLACKFIN_DMA_CHANNEL 32
+
+extern int channel2irq(unsigned int channel);
+extern struct dma_register *base_addr[];
+#endif
diff --git a/include/asm-blackfin/mach-bf548/gpio.h b/include/asm-blackfin/mach-bf548/gpio.h
new file mode 100644
index 0000000..dbf66bc
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/gpio.h
@@ -0,0 +1,216 @@
+/*
+ * File:         include/asm-blackfin/mach-bf548/gpio.h
+ * Based on:
+ * Author:	 Michael Hennerich (hennerich@blackfin.uclinux.org)
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+
+#define GPIO_PA0	0
+#define GPIO_PA1	1
+#define GPIO_PA2	2
+#define GPIO_PA3	3
+#define GPIO_PA4	4
+#define GPIO_PA5	5
+#define GPIO_PA6	6
+#define GPIO_PA7	7
+#define GPIO_PA8	8
+#define GPIO_PA9	9
+#define GPIO_PA10	10
+#define GPIO_PA11	11
+#define GPIO_PA12	12
+#define GPIO_PA13	13
+#define GPIO_PA14	14
+#define GPIO_PA15	15
+#define GPIO_PB0	16
+#define GPIO_PB1	17
+#define GPIO_PB2	18
+#define GPIO_PB3	19
+#define GPIO_PB4	20
+#define GPIO_PB5	21
+#define GPIO_PB6	22
+#define GPIO_PB7	23
+#define GPIO_PB8	24
+#define GPIO_PB9	25
+#define GPIO_PB10	26
+#define GPIO_PB11	27
+#define GPIO_PB12	28
+#define GPIO_PB13	29
+#define GPIO_PB14	30
+#define GPIO_PB15	31	/* N/A */
+#define GPIO_PC0	32
+#define GPIO_PC1	33
+#define GPIO_PC2	34
+#define GPIO_PC3	35
+#define GPIO_PC4	36
+#define GPIO_PC5	37
+#define GPIO_PC6	38
+#define GPIO_PC7	39
+#define GPIO_PC8	40
+#define GPIO_PC9	41
+#define GPIO_PC10	42
+#define GPIO_PC11	43
+#define GPIO_PC12	44
+#define GPIO_PC13	45
+#define GPIO_PC14	46	/* N/A */
+#define GPIO_PC15	47	/* N/A */
+#define GPIO_PD0	48
+#define GPIO_PD1	49
+#define GPIO_PD2	50
+#define GPIO_PD3	51
+#define GPIO_PD4	52
+#define GPIO_PD5	53
+#define GPIO_PD6	54
+#define GPIO_PD7	55
+#define GPIO_PD8	56
+#define GPIO_PD9	57
+#define GPIO_PD10	58
+#define GPIO_PD11	59
+#define GPIO_PD12	60
+#define GPIO_PD13	61
+#define GPIO_PD14	62
+#define GPIO_PD15	63
+#define GPIO_PE0	64
+#define GPIO_PE1	65
+#define GPIO_PE2	66
+#define GPIO_PE3	67
+#define GPIO_PE4	68
+#define GPIO_PE5	69
+#define GPIO_PE6	70
+#define GPIO_PE7	71
+#define GPIO_PE8	72
+#define GPIO_PE9	73
+#define GPIO_PE10	74
+#define GPIO_PE11	75
+#define GPIO_PE12	76
+#define GPIO_PE13	77
+#define GPIO_PE14	78
+#define GPIO_PE15	79
+#define GPIO_PF0	80
+#define GPIO_PF1	81
+#define GPIO_PF2	82
+#define GPIO_PF3	83
+#define GPIO_PF4	84
+#define GPIO_PF5	85
+#define GPIO_PF6	86
+#define GPIO_PF7	87
+#define GPIO_PF8	88
+#define GPIO_PF9	89
+#define GPIO_PF10	90
+#define GPIO_PF11	91
+#define GPIO_PF12	92
+#define GPIO_PF13	93
+#define GPIO_PF14	94
+#define GPIO_PF15	95
+#define GPIO_PG0	96
+#define GPIO_PG1	97
+#define GPIO_PG2	98
+#define GPIO_PG3	99
+#define GPIO_PG4	100
+#define GPIO_PG5	101
+#define GPIO_PG6	102
+#define GPIO_PG7	103
+#define GPIO_PG8	104
+#define GPIO_PG9	105
+#define GPIO_PG10	106
+#define GPIO_PG11	107
+#define GPIO_PG12	108
+#define GPIO_PG13	109
+#define GPIO_PG14	110
+#define GPIO_PG15	111
+#define GPIO_PH0	112
+#define GPIO_PH1	113
+#define GPIO_PH2	114
+#define GPIO_PH3	115
+#define GPIO_PH4	116
+#define GPIO_PH5	117
+#define GPIO_PH6	118
+#define GPIO_PH7	119
+#define GPIO_PH8	120
+#define GPIO_PH9	121
+#define GPIO_PH10	122
+#define GPIO_PH11	123
+#define GPIO_PH12	124
+#define GPIO_PH13	125
+#define GPIO_PH14	126	/* N/A */
+#define GPIO_PH15	127	/* N/A */
+#define GPIO_PI0	128
+#define GPIO_PI1	129
+#define GPIO_PI2	130
+#define GPIO_PI3	131
+#define GPIO_PI4	132
+#define GPIO_PI5	133
+#define GPIO_PI6	134
+#define GPIO_PI7	135
+#define GPIO_PI8	136
+#define GPIO_PI9	137
+#define GPIO_PI10	138
+#define GPIO_PI11	139
+#define GPIO_PI12	140
+#define GPIO_PI13	141
+#define GPIO_PI14	142
+#define GPIO_PI15	143
+#define GPIO_PJ0	144
+#define GPIO_PJ1	145
+#define GPIO_PJ2	146
+#define GPIO_PJ3	147
+#define GPIO_PJ4	148
+#define GPIO_PJ5	149
+#define GPIO_PJ6	150
+#define GPIO_PJ7	151
+#define GPIO_PJ8	152
+#define GPIO_PJ9	153
+#define GPIO_PJ10	154
+#define GPIO_PJ11	155
+#define GPIO_PJ12	156
+#define GPIO_PJ13	157
+#define GPIO_PJ14	158	/* N/A */
+#define GPIO_PJ15	159	/* N/A */
+
+#define MAX_BLACKFIN_GPIOS 160
+
+struct gpio_port_t {
+	unsigned short port_fer;
+	unsigned short dummy1;
+	unsigned short port_data;
+	unsigned short dummy2;
+	unsigned short port_set;
+	unsigned short dummy3;
+	unsigned short port_clear;
+	unsigned short dummy4;
+	unsigned short port_dir_set;
+	unsigned short dummy5;
+	unsigned short port_dir_clear;
+	unsigned short dummy6;
+	unsigned short port_inen;
+	unsigned short dummy7;
+	unsigned int port_mux;
+};
+
+int gpio_request(unsigned short gpio, const char *label);
+void peripheral_free(unsigned short per);
+int peripheral_request_list(unsigned short per[], const char *label);
+void peripheral_free_list(unsigned short per[]);
diff --git a/include/asm-blackfin/mach-bf548/irq.h b/include/asm-blackfin/mach-bf548/irq.h
new file mode 100644
index 0000000..0b3325b
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/irq.h
@@ -0,0 +1,467 @@
+/*
+ * file:	include/asm-blackfin/mach-bf548/irq.h
+ * based on:	include/asm-blackfin/mach-bf537/irq.h
+ * author:	Roy Huang (roy.huang@analog.com)
+ *
+ * created:
+ * description:
+ *	system mmr register map
+ * rev:
+ *
+ * modified:
+ *
+ *
+ * bugs:         enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose.  see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _BF548_IRQ_H_
+#define _BF548_IRQ_H_
+
+/*
+ * Interrupt source definitions
+            Event Source    Core Event Name
+Core        Emulation               **
+Events         (highest priority)  EMU         0
+            Reset                   RST         1
+            NMI                     NMI         2
+            Exception               EVX         3
+            Reserved                --          4
+            Hardware Error          IVHW        5
+            Core Timer              IVTMR       6 *
+
+.....
+
+            Software Interrupt 1    IVG14       31
+            Software Interrupt 2    --
+                 (lowest priority)  IVG15       32 *
+ */
+
+#define NR_PERI_INTS    (32 * 3)
+
+/* The ABSTRACT IRQ definitions */
+/** the first seven of the following are fixed, the rest you change if you need to **/
+#define IRQ_EMU		0	/* Emulation */
+#define IRQ_RST		1	/* reset */
+#define IRQ_NMI		2	/* Non Maskable */
+#define IRQ_EVX		3	/* Exception */
+#define IRQ_UNUSED	4	/* - unused interrupt*/
+#define IRQ_HWERR	5	/* Hardware Error */
+#define IRQ_CORETMR	6	/* Core timer */
+
+#define BFIN_IRQ(x)	((x) + 7)
+
+#define IRQ_PLL_WAKEUP	BFIN_IRQ(0)	/* PLL Wakeup Interrupt */
+#define IRQ_DMAC0_ERR	BFIN_IRQ(1)	/* DMAC0 Status Interrupt */
+#define IRQ_EPPI0_ERR	BFIN_IRQ(2)	/* EPPI0 Error Interrupt */
+#define IRQ_SPORT0_ERR	BFIN_IRQ(3)	/* SPORT0 Error Interrupt */
+#define IRQ_SPORT1_ERR	BFIN_IRQ(4)	/* SPORT1 Error Interrupt */
+#define IRQ_SPI0_ERR	BFIN_IRQ(5)	/* SPI0 Status(Error) Interrupt */
+#define IRQ_UART0_ERR	BFIN_IRQ(6)	/* UART0 Status(Error) Interrupt */
+#define IRQ_RTC		BFIN_IRQ(7)	/* RTC Interrupt */
+#define IRQ_EPPI0	BFIN_IRQ(8)	/* EPPI0 Interrupt (DMA12) */
+#define IRQ_SPORT0_RX	BFIN_IRQ(9)	/* SPORT0 RX Interrupt (DMA0) */
+#define IRQ_SPORT0_TX	BFIN_IRQ(10)	/* SPORT0 TX Interrupt (DMA1) */
+#define IRQ_SPORT1_RX	BFIN_IRQ(11)	/* SPORT1 RX Interrupt (DMA2) */
+#define IRQ_SPORT1_TX	BFIN_IRQ(12)	/* SPORT1 TX Interrupt (DMA3) */
+#define IRQ_SPI0	BFIN_IRQ(13)	/* SPI0 Interrupt (DMA4) */
+#define IRQ_UART0_RX	BFIN_IRQ(14)	/* UART0 RX Interrupt (DMA6) */
+#define IRQ_UART0_TX	BFIN_IRQ(15)	/* UART0 TX Interrupt (DMA7) */
+#define IRQ_TIMER8	BFIN_IRQ(16)	/* TIMER 8 Interrupt */
+#define IRQ_TIMER9	BFIN_IRQ(17)	/* TIMER 9 Interrupt */
+#define IRQ_TIMER10	BFIN_IRQ(18)	/* TIMER 10 Interrupt */
+#define IRQ_PINT0	BFIN_IRQ(19)	/* PINT0 Interrupt */
+#define IRQ_PINT1	BFIN_IRQ(20)	/* PINT1 Interrupt */
+#define IRQ_MDMAS0	BFIN_IRQ(21)	/* MDMA Stream 0 Interrupt */
+#define IRQ_MDMAS1	BFIN_IRQ(22)	/* MDMA Stream 1 Interrupt */
+#define IRQ_WATCHDOG	BFIN_IRQ(23)	/* Watchdog Interrupt */
+#define IRQ_DMAC1_ERR	BFIN_IRQ(24)	/* DMAC1 Status (Error) Interrupt */
+#define IRQ_SPORT2_ERR	BFIN_IRQ(25)	/* SPORT2 Error Interrupt */
+#define IRQ_SPORT3_ERR	BFIN_IRQ(26)	/* SPORT3 Error Interrupt */
+#define IRQ_MXVR_DATA	BFIN_IRQ(27)	/* MXVR Data Interrupt */
+#define IRQ_SPI1_ERR	BFIN_IRQ(28)	/* SPI1 Status (Error) Interrupt */
+#define IRQ_SPI2_ERR	BFIN_IRQ(29)	/* SPI2 Status (Error) Interrupt */
+#define IRQ_UART1_ERR	BFIN_IRQ(30)	/* UART1 Status (Error) Interrupt */
+#define IRQ_UART2_ERR	BFIN_IRQ(31)	/* UART2 Status (Error) Interrupt */
+#define IRQ_CAN0_ERR	BFIN_IRQ(32)	/* CAN0 Status (Error) Interrupt */
+#define IRQ_SPORT2_RX	BFIN_IRQ(33)	/* SPORT2 RX (DMA18) Interrupt */
+#define IRQ_SPORT2_TX	BFIN_IRQ(34)	/* SPORT2 TX (DMA19) Interrupt */
+#define IRQ_SPORT3_RX	BFIN_IRQ(35)	/* SPORT3 RX (DMA20) Interrupt */
+#define IRQ_SPORT3_TX	BFIN_IRQ(36)	/* SPORT3 TX (DMA21) Interrupt */
+#define IRQ_EPPI1	BFIN_IRQ(37)	/* EPP1 (DMA13) Interrupt */
+#define IRQ_EPPI2	BFIN_IRQ(38)	/* EPP2 (DMA14) Interrupt */
+#define IRQ_SPI1	BFIN_IRQ(39)	/* SPI1 (DMA5) Interrupt */
+#define IRQ_SPI2	BFIN_IRQ(40)	/* SPI2 (DMA23) Interrupt */
+#define IRQ_UART1_RX	BFIN_IRQ(41)	/* UART1 RX (DMA8) Interrupt */
+#define IRQ_UART1_TX	BFIN_IRQ(42)	/* UART1 TX (DMA9) Interrupt */
+#define IRQ_ATAPI_RX	BFIN_IRQ(43)	/* ATAPI RX (DMA10) Interrupt */
+#define IRQ_ATAPI_TX	BFIN_IRQ(44)	/* ATAPI TX (DMA11) Interrupt */
+#define IRQ_TWI0	BFIN_IRQ(45)	/* TWI0 Interrupt */
+#define IRQ_TWI1	BFIN_IRQ(46)	/* TWI1 Interrupt */
+#define IRQ_CAN0_RX	BFIN_IRQ(47)	/* CAN0 Receive Interrupt */
+#define IRQ_CAN0_TX	BFIN_IRQ(48)	/* CAN0 Transmit Interrupt */
+#define IRQ_MDMAS2	BFIN_IRQ(49)	/* MDMA Stream 2 Interrupt */
+#define IRQ_MDMAS3	BFIN_IRQ(50)	/* MDMA Stream 3 Interrupt */
+#define IRQ_MXVR_ERR	BFIN_IRQ(51)	/* MXVR Status (Error) Interrupt */
+#define IRQ_MXVR_MSG	BFIN_IRQ(52)	/* MXVR Message Interrupt */
+#define IRQ_MXVR_PKT	BFIN_IRQ(53)	/* MXVR Packet Interrupt */
+#define IRQ_EPP1_ERR	BFIN_IRQ(54)	/* EPPI1 Error Interrupt */
+#define IRQ_EPP2_ERR	BFIN_IRQ(55)	/* EPPI2 Error Interrupt */
+#define IRQ_UART3_ERR	BFIN_IRQ(56)	/* UART3 Status (Error) Interrupt */
+#define IRQ_HOST_ERR	BFIN_IRQ(57)	/* HOST Status (Error) Interrupt */
+#define IRQ_PIXC_ERR	BFIN_IRQ(59)	/* PIXC Status (Error) Interrupt */
+#define IRQ_NFC_ERR	BFIN_IRQ(60)	/* NFC Error Interrupt */
+#define IRQ_ATAPI_ERR	BFIN_IRQ(61)	/* ATAPI Error Interrupt */
+#define IRQ_CAN1_ERR	BFIN_IRQ(62)	/* CAN1 Status (Error) Interrupt */
+#define IRQ_HS_DMA_ERR	BFIN_IRQ(63)	/* Handshake DMA Status Interrupt */
+#define IRQ_PIXC_IN0	BFIN_IRQ(64)	/* PIXC IN0 (DMA15) Interrupt */
+#define IRQ_PIXC_IN1	BFIN_IRQ(65)	/* PIXC IN1 (DMA16) Interrupt */
+#define IRQ_PIXC_OUT	BFIN_IRQ(66)	/* PIXC OUT (DMA17) Interrupt */
+#define IRQ_SDH		BFIN_IRQ(67)	/* SDH/NFC (DMA22) Interrupt */
+#define IRQ_CNT		BFIN_IRQ(68)	/* CNT Interrupt */
+#define IRQ_KEY		BFIN_IRQ(69)	/* KEY Interrupt */
+#define IRQ_CAN1_RX	BFIN_IRQ(70)	/* CAN1 RX Interrupt */
+#define IRQ_CAN1_TX	BFIN_IRQ(71)	/* CAN1 TX Interrupt */
+#define IRQ_SDH_MASK0	BFIN_IRQ(72)	/* SDH Mask 0 Interrupt */
+#define IRQ_SDH_MASK1	BFIN_IRQ(73)	/* SDH Mask 1 Interrupt */
+#define IRQ_USB_INT0	BFIN_IRQ(75)	/* USB INT0 Interrupt */
+#define IRQ_USB_INT1	BFIN_IRQ(76)	/* USB INT1 Interrupt */
+#define IRQ_USB_INT2	BFIN_IRQ(77)	/* USB INT2 Interrupt */
+#define IRQ_USB_DMA	BFIN_IRQ(78)	/* USB DMA Interrupt */
+#define IRQ_OPTSEC	BFIN_IRQ(79)	/* OTPSEC Interrupt */
+#define IRQ_TIMER0	BFIN_IRQ(86)	/* Timer 0 Interrupt */
+#define IRQ_TIMER1	BFIN_IRQ(87)	/* Timer 1 Interrupt */
+#define IRQ_TIMER2	BFIN_IRQ(88)	/* Timer 2 Interrupt */
+#define IRQ_TIMER3	BFIN_IRQ(89)	/* Timer 3 Interrupt */
+#define IRQ_TIMER4	BFIN_IRQ(90)	/* Timer 4 Interrupt */
+#define IRQ_TIMER5	BFIN_IRQ(91)	/* Timer 5 Interrupt */
+#define IRQ_TIMER6	BFIN_IRQ(92)	/* Timer 6 Interrupt */
+#define IRQ_TIMER7	BFIN_IRQ(93)	/* Timer 7 Interrupt */
+#define IRQ_PINT2	BFIN_IRQ(94)	/* PINT2 Interrupt */
+#define IRQ_PINT3	BFIN_IRQ(95)	/* PINT3 Interrupt */
+
+#define SYS_IRQS        IRQ_PINT3
+
+#define BFIN_PA_IRQ(x)	((x) + SYS_IRQS + 1)
+#define IRQ_PA0		BFIN_PA_IRQ(0)
+#define IRQ_PA1		BFIN_PA_IRQ(1)
+#define IRQ_PA2		BFIN_PA_IRQ(2)
+#define IRQ_PA3		BFIN_PA_IRQ(3)
+#define IRQ_PA4		BFIN_PA_IRQ(4)
+#define IRQ_PA5		BFIN_PA_IRQ(5)
+#define IRQ_PA6		BFIN_PA_IRQ(6)
+#define IRQ_PA7		BFIN_PA_IRQ(7)
+#define IRQ_PA8		BFIN_PA_IRQ(8)
+#define IRQ_PA9		BFIN_PA_IRQ(9)
+#define IRQ_PA10	BFIN_PA_IRQ(10)
+#define IRQ_PA11	BFIN_PA_IRQ(11)
+#define IRQ_PA12	BFIN_PA_IRQ(12)
+#define IRQ_PA13	BFIN_PA_IRQ(13)
+#define IRQ_PA14	BFIN_PA_IRQ(14)
+#define IRQ_PA15	BFIN_PA_IRQ(15)
+
+#define BFIN_PB_IRQ(x)	((x) + IRQ_PA15 + 1)
+#define IRQ_PB0		BFIN_PB_IRQ(0)
+#define IRQ_PB1		BFIN_PB_IRQ(1)
+#define IRQ_PB2		BFIN_PB_IRQ(2)
+#define IRQ_PB3		BFIN_PB_IRQ(3)
+#define IRQ_PB4		BFIN_PB_IRQ(4)
+#define IRQ_PB5		BFIN_PB_IRQ(5)
+#define IRQ_PB6		BFIN_PB_IRQ(6)
+#define IRQ_PB7		BFIN_PB_IRQ(7)
+#define IRQ_PB8		BFIN_PB_IRQ(8)
+#define IRQ_PB9		BFIN_PB_IRQ(9)
+#define IRQ_PB10	BFIN_PB_IRQ(10)
+#define IRQ_PB11	BFIN_PB_IRQ(11)
+#define IRQ_PB12	BFIN_PB_IRQ(12)
+#define IRQ_PB13	BFIN_PB_IRQ(13)
+#define IRQ_PB14	BFIN_PB_IRQ(14)
+#define IRQ_PB15	BFIN_PB_IRQ(15)		/* N/A */
+
+#define BFIN_PC_IRQ(x)	((x) + IRQ_PB15 + 1)
+#define IRQ_PC0		BFIN_PC_IRQ(0)
+#define IRQ_PC1		BFIN_PC_IRQ(1)
+#define IRQ_PC2		BFIN_PC_IRQ(2)
+#define IRQ_PC3		BFIN_PC_IRQ(3)
+#define IRQ_PC4		BFIN_PC_IRQ(4)
+#define IRQ_PC5		BFIN_PC_IRQ(5)
+#define IRQ_PC6		BFIN_PC_IRQ(6)
+#define IRQ_PC7		BFIN_PC_IRQ(7)
+#define IRQ_PC8		BFIN_PC_IRQ(8)
+#define IRQ_PC9		BFIN_PC_IRQ(9)
+#define IRQ_PC10	BFIN_PC_IRQ(10)
+#define IRQ_PC11	BFIN_PC_IRQ(11)
+#define IRQ_PC12	BFIN_PC_IRQ(12)
+#define IRQ_PC13	BFIN_PC_IRQ(13)
+#define IRQ_PC14	BFIN_PC_IRQ(14)		/* N/A */
+#define IRQ_PC15	BFIN_PC_IRQ(15)		/* N/A */
+
+#define BFIN_PD_IRQ(x)	((x) + IRQ_PC15 + 1)
+#define IRQ_PD0		BFIN_PD_IRQ(0)
+#define IRQ_PD1		BFIN_PD_IRQ(1)
+#define IRQ_PD2		BFIN_PD_IRQ(2)
+#define IRQ_PD3		BFIN_PD_IRQ(3)
+#define IRQ_PD4		BFIN_PD_IRQ(4)
+#define IRQ_PD5		BFIN_PD_IRQ(5)
+#define IRQ_PD6		BFIN_PD_IRQ(6)
+#define IRQ_PD7		BFIN_PD_IRQ(7)
+#define IRQ_PD8		BFIN_PD_IRQ(8)
+#define IRQ_PD9		BFIN_PD_IRQ(9)
+#define IRQ_PD10	BFIN_PD_IRQ(10)
+#define IRQ_PD11	BFIN_PD_IRQ(11)
+#define IRQ_PD12	BFIN_PD_IRQ(12)
+#define IRQ_PD13	BFIN_PD_IRQ(13)
+#define IRQ_PD14	BFIN_PD_IRQ(14)
+#define IRQ_PD15	BFIN_PD_IRQ(15)
+
+#define BFIN_PE_IRQ(x)	((x) + IRQ_PD15 + 1)
+#define IRQ_PE0		BFIN_PE_IRQ(0)
+#define IRQ_PE1		BFIN_PE_IRQ(1)
+#define IRQ_PE2		BFIN_PE_IRQ(2)
+#define IRQ_PE3		BFIN_PE_IRQ(3)
+#define IRQ_PE4		BFIN_PE_IRQ(4)
+#define IRQ_PE5		BFIN_PE_IRQ(5)
+#define IRQ_PE6		BFIN_PE_IRQ(6)
+#define IRQ_PE7		BFIN_PE_IRQ(7)
+#define IRQ_PE8		BFIN_PE_IRQ(8)
+#define IRQ_PE9		BFIN_PE_IRQ(9)
+#define IRQ_PE10	BFIN_PE_IRQ(10)
+#define IRQ_PE11	BFIN_PE_IRQ(11)
+#define IRQ_PE12	BFIN_PE_IRQ(12)
+#define IRQ_PE13	BFIN_PE_IRQ(13)
+#define IRQ_PE14	BFIN_PE_IRQ(14)
+#define IRQ_PE15	BFIN_PE_IRQ(15)
+
+#define BFIN_PF_IRQ(x)	((x) + IRQ_PE15 + 1)
+#define IRQ_PF0		BFIN_PF_IRQ(0)
+#define IRQ_PF1		BFIN_PF_IRQ(1)
+#define IRQ_PF2		BFIN_PF_IRQ(2)
+#define IRQ_PF3		BFIN_PF_IRQ(3)
+#define IRQ_PF4		BFIN_PF_IRQ(4)
+#define IRQ_PF5		BFIN_PF_IRQ(5)
+#define IRQ_PF6		BFIN_PF_IRQ(6)
+#define IRQ_PF7		BFIN_PF_IRQ(7)
+#define IRQ_PF8		BFIN_PF_IRQ(8)
+#define IRQ_PF9		BFIN_PF_IRQ(9)
+#define IRQ_PF10	BFIN_PF_IRQ(10)
+#define IRQ_PF11	BFIN_PF_IRQ(11)
+#define IRQ_PF12	BFIN_PF_IRQ(12)
+#define IRQ_PF13	BFIN_PF_IRQ(13)
+#define IRQ_PF14	BFIN_PF_IRQ(14)
+#define IRQ_PF15	BFIN_PF_IRQ(15)
+
+#define BFIN_PG_IRQ(x)	((x) + IRQ_PF15 + 1)
+#define IRQ_PG0		BFIN_PG_IRQ(0)
+#define IRQ_PG1		BFIN_PG_IRQ(1)
+#define IRQ_PG2		BFIN_PG_IRQ(2)
+#define IRQ_PG3		BFIN_PG_IRQ(3)
+#define IRQ_PG4		BFIN_PG_IRQ(4)
+#define IRQ_PG5		BFIN_PG_IRQ(5)
+#define IRQ_PG6		BFIN_PG_IRQ(6)
+#define IRQ_PG7		BFIN_PG_IRQ(7)
+#define IRQ_PG8		BFIN_PG_IRQ(8)
+#define IRQ_PG9		BFIN_PG_IRQ(9)
+#define IRQ_PG10	BFIN_PG_IRQ(10)
+#define IRQ_PG11	BFIN_PG_IRQ(11)
+#define IRQ_PG12	BFIN_PG_IRQ(12)
+#define IRQ_PG13	BFIN_PG_IRQ(13)
+#define IRQ_PG14	BFIN_PG_IRQ(14)
+#define IRQ_PG15	BFIN_PG_IRQ(15)
+
+#define BFIN_PH_IRQ(x)	((x) + IRQ_PG15 + 1)
+#define IRQ_PH0		BFIN_PH_IRQ(0)
+#define IRQ_PH1		BFIN_PH_IRQ(1)
+#define IRQ_PH2		BFIN_PH_IRQ(2)
+#define IRQ_PH3		BFIN_PH_IRQ(3)
+#define IRQ_PH4		BFIN_PH_IRQ(4)
+#define IRQ_PH5		BFIN_PH_IRQ(5)
+#define IRQ_PH6		BFIN_PH_IRQ(6)
+#define IRQ_PH7		BFIN_PH_IRQ(7)
+#define IRQ_PH8		BFIN_PH_IRQ(8)
+#define IRQ_PH9		BFIN_PH_IRQ(9)
+#define IRQ_PH10	BFIN_PH_IRQ(10)
+#define IRQ_PH11	BFIN_PH_IRQ(11)
+#define IRQ_PH12	BFIN_PH_IRQ(12)
+#define IRQ_PH13	BFIN_PH_IRQ(13)
+#define IRQ_PH14	BFIN_PH_IRQ(14)		/* N/A */
+#define IRQ_PH15	BFIN_PH_IRQ(15)		/* N/A */
+
+#define BFIN_PI_IRQ(x)	((x) + IRQ_PH15 + 1)
+#define IRQ_PI0		BFIN_PI_IRQ(0)
+#define IRQ_PI1		BFIN_PI_IRQ(1)
+#define IRQ_PI2		BFIN_PI_IRQ(2)
+#define IRQ_PI3		BFIN_PI_IRQ(3)
+#define IRQ_PI4		BFIN_PI_IRQ(4)
+#define IRQ_PI5		BFIN_PI_IRQ(5)
+#define IRQ_PI6		BFIN_PI_IRQ(6)
+#define IRQ_PI7		BFIN_PI_IRQ(7)
+#define IRQ_PI8		BFIN_PI_IRQ(8)
+#define IRQ_PI9		BFIN_PI_IRQ(9)
+#define IRQ_PI10	BFIN_PI_IRQ(10)
+#define IRQ_PI11	BFIN_PI_IRQ(11)
+#define IRQ_PI12	BFIN_PI_IRQ(12)
+#define IRQ_PI13	BFIN_PI_IRQ(13)
+#define IRQ_PI14	BFIN_PI_IRQ(14)
+#define IRQ_PI15	BFIN_PI_IRQ(15)
+
+#define BFIN_PJ_IRQ(x)	((x) + IRQ_PI15 + 1)
+#define IRQ_PJ0		BFIN_PJ_IRQ(0)
+#define IRQ_PJ1		BFIN_PJ_IRQ(1)
+#define IRQ_PJ2		BFIN_PJ_IRQ(2)
+#define IRQ_PJ3		BFIN_PJ_IRQ(3)
+#define IRQ_PJ4		BFIN_PJ_IRQ(4)
+#define IRQ_PJ5		BFIN_PJ_IRQ(5)
+#define IRQ_PJ6		BFIN_PJ_IRQ(6)
+#define IRQ_PJ7		BFIN_PJ_IRQ(7)
+#define IRQ_PJ8		BFIN_PJ_IRQ(8)
+#define IRQ_PJ9		BFIN_PJ_IRQ(9)
+#define IRQ_PJ10	BFIN_PJ_IRQ(10)
+#define IRQ_PJ11	BFIN_PJ_IRQ(11)
+#define IRQ_PJ12	BFIN_PJ_IRQ(12)
+#define IRQ_PJ13	BFIN_PJ_IRQ(13)
+#define IRQ_PJ14	BFIN_PJ_IRQ(14)		/* N/A */
+#define IRQ_PJ15	BFIN_PJ_IRQ(15)		/* N/A */
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+#define NR_IRQS     (IRQ_PJ15+1)
+#else
+#define NR_IRQS     (SYS_IRQS+1)
+#endif
+
+#define IVG7            7
+#define IVG8            8
+#define IVG9            9
+#define IVG10           10
+#define IVG11           11
+#define IVG12           12
+#define IVG13           13
+#define IVG14           14
+#define IVG15           15
+
+/* IAR0 BIT FIELDS */
+#define IRQ_PLL_WAKEUP_POS	0
+#define IRQ_DMAC0_ERR_POS	4
+#define IRQ_EPPI0_ERR_POS	8
+#define IRQ_SPORT0_ERR_POS	12
+#define IRQ_SPORT1_ERR_POS	16
+#define IRQ_SPI0_ERR_POS	20
+#define IRQ_UART0_ERR_POS	24
+#define IRQ_RTC_POS		28
+
+/* IAR1 BIT FIELDS */
+#define IRQ_EPPI0_POS		0
+#define IRQ_SPORT0_RX_POS	4
+#define IRQ_SPORT0_TX_POS	8
+#define IRQ_SPORT1_RX_POS	12
+#define IRQ_SPORT1_TX_POS	16
+#define IRQ_SPI0_POS		20
+#define IRQ_UART0_RX_POS	24
+#define IRQ_UART0_TX_POS	28
+
+/* IAR2 BIT FIELDS */
+#define IRQ_TIMER8_POS		0
+#define IRQ_TIMER9_POS		4
+#define IRQ_TIMER10_POS		8
+#define IRQ_PINT0_POS		12
+#define IRQ_PINT1_POS		16
+#define IRQ_MDMAS0_POS		20
+#define IRQ_MDMAS1_POS		24
+#define IRQ_WATCHDOG_POS	28
+
+/* IAR3 BIT FIELDS */
+#define IRQ_DMAC1_ERR_POS	0
+#define IRQ_SPORT2_ERR_POS	4
+#define IRQ_SPORT3_ERR_POS	8
+#define IRQ_MXVR_DATA_POS	12
+#define IRQ_SPI1_ERR_POS	16
+#define IRQ_SPI2_ERR_POS	20
+#define IRQ_UART1_ERR_POS	24
+#define IRQ_UART2_ERR_POS	28
+
+/* IAR4 BIT FILEDS */
+#define IRQ_CAN0_ERR_POS	0
+#define IRQ_SPORT2_RX_POS	4
+#define IRQ_SPORT2_TX_POS	8
+#define IRQ_SPORT3_RX_POS	12
+#define IRQ_SPORT3_TX_POS	16
+#define IRQ_EPPI1_POS		20
+#define IRQ_EPPI2_POS		24
+#define IRQ_SPI1_POS		28
+
+/* IAR5 BIT FIELDS */
+#define IRQ_SPI2_POS		0
+#define IRQ_UART1_RX_POS	4
+#define IRQ_UART1_TX_POS	8
+#define IRQ_ATAPI_RX_POS	12
+#define IRQ_ATAPI_TX_POS	16
+#define IRQ_TWI0_POS		20
+#define IRQ_TWI1_POS		24
+#define IRQ_CAN0_RX_POS		28
+
+/* IAR6 BIT FIELDS */
+#define IRQ_CAN0_TX_POS		0
+#define IRQ_MDMAS2_POS		4
+#define IRQ_MDMAS3_POS		8
+#define IRQ_MXVR_ERR_POS	12
+#define IRQ_MXVR_MSG_POS	16
+#define IRQ_MXVR_PKT_POS	20
+#define IRQ_EPPI1_ERR_POS	24
+#define IRQ_EPPI2_ERR_POS	28
+
+/* IAR7 BIT FIELDS */
+#define IRQ_UART3_ERR_POS	0
+#define IRQ_HOST_ERR_POS	4
+#define IRQ_PIXC_ERR_POS	12
+#define IRQ_NFC_ERR_POS		16
+#define IRQ_ATAPI_ERR_POS	20
+#define IRQ_CAN1_ERR_POS	24
+#define IRQ_HS_DMA_ERR_POS	28
+
+/* IAR8 BIT FIELDS */
+#define IRQ_PIXC_IN0_POS	0
+#define IRQ_PIXC_IN1_POS	4
+#define IRQ_PIXC_OUT_POS	8
+#define IRQ_SDH_POS		12
+#define IRQ_CNT_POS		16
+#define IRQ_KEY_POS		20
+#define IRQ_CAN1_RX_POS		24
+#define IRQ_CAN1_TX_POS		28
+
+/* IAR9 BIT FIELDS */
+#define IRQ_SDH_MASK0_POS	0
+#define IRQ_SDH_MASK1_POS	4
+#define IRQ_USB_INT0_POS	12
+#define IRQ_USB_INT1_POS	16
+#define IRQ_USB_INT2_POS	20
+#define IRQ_USB_DMA_POS		24
+#define IRQ_OTPSEC_POS		28
+
+/* IAR10 BIT FIELDS */
+#define IRQ_TIMER0_POS		24
+#define IRQ_TIMER1_POS		28
+
+/* IAR11 BIT FIELDS */
+#define IRQ_TIMER2_POS		0
+#define IRQ_TIMER3_POS		4
+#define IRQ_TIMER4_POS		8
+#define IRQ_TIMER5_POS		12
+#define IRQ_TIMER6_POS		16
+#define IRQ_TIMER7_POS		20
+#define IRQ_PINT2_POS		24
+#define IRQ_PINT3_POS		28
+
+#endif /* _BF548_IRQ_H_ */
diff --git a/include/asm-blackfin/mach-bf548/mem_init.h b/include/asm-blackfin/mach-bf548/mem_init.h
new file mode 100644
index 0000000..0cb279e
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/mem_init.h
@@ -0,0 +1,189 @@
+/*
+ * File:         include/asm-blackfin/mach-bf548/mem_init.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *               Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#if (CONFIG_MEM_MT46V32M16)
+
+#if defined CONFIG_CLKIN_HALF
+#define CLKIN_HALF       1
+#else
+#define CLKIN_HALF       0
+#endif
+
+#if defined CONFIG_PLL_BYPASS
+#define PLL_BYPASS      1
+#else
+#define PLL_BYPASS       0
+#endif
+
+/***************************************Currently Not Being Used *********************************/
+#define flash_EBIU_AMBCTL_WAT  ((CONFIG_FLASH_SPEED_BWAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_RAT  ((CONFIG_FLASH_SPEED_BRAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_HT   ((CONFIG_FLASH_SPEED_BHT  * 4) / (4000000000 / CONFIG_SCLK_HZ))
+#define flash_EBIU_AMBCTL_ST   ((CONFIG_FLASH_SPEED_BST  * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_TT   ((CONFIG_FLASH_SPEED_BTT  * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+
+#if (flash_EBIU_AMBCTL_TT > 3)
+#define flash_EBIU_AMBCTL0_TT   B0TT_4
+#endif
+#if (flash_EBIU_AMBCTL_TT == 3)
+#define flash_EBIU_AMBCTL0_TT   B0TT_3
+#endif
+#if (flash_EBIU_AMBCTL_TT == 2)
+#define flash_EBIU_AMBCTL0_TT   B0TT_2
+#endif
+#if (flash_EBIU_AMBCTL_TT < 2)
+#define flash_EBIU_AMBCTL0_TT   B0TT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_ST > 3)
+#define flash_EBIU_AMBCTL0_ST   B0ST_4
+#endif
+#if (flash_EBIU_AMBCTL_ST == 3)
+#define flash_EBIU_AMBCTL0_ST   B0ST_3
+#endif
+#if (flash_EBIU_AMBCTL_ST == 2)
+#define flash_EBIU_AMBCTL0_ST   B0ST_2
+#endif
+#if (flash_EBIU_AMBCTL_ST < 2)
+#define flash_EBIU_AMBCTL0_ST   B0ST_1
+#endif
+
+#if (flash_EBIU_AMBCTL_HT > 2)
+#define flash_EBIU_AMBCTL0_HT   B0HT_3
+#endif
+#if (flash_EBIU_AMBCTL_HT == 2)
+#define flash_EBIU_AMBCTL0_HT   B0HT_2
+#endif
+#if (flash_EBIU_AMBCTL_HT == 1)
+#define flash_EBIU_AMBCTL0_HT   B0HT_1
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0)
+#define flash_EBIU_AMBCTL0_HT   B0HT_0
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0)
+#define flash_EBIU_AMBCTL0_HT   B0HT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_WAT > 14)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_15
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 14)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_14
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 13)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_13
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 12)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_12
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 11)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_11
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 10)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_10
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 9)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_9
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 8)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_8
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 7)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_7
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 6)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_6
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 5)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_5
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 4)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_4
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 3)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_3
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 2)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_2
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 1)
+#define flash_EBIU_AMBCTL0_WAT  B0WAT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_RAT > 14)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_15
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 14)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_14
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 13)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_13
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 12)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_12
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 11)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_11
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 10)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_10
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 9)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_9
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 8)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_8
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 7)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_7
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 6)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_6
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 5)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_5
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 4)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_4
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 3)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_3
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 2)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_2
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 1)
+#define flash_EBIU_AMBCTL0_RAT  B0RAT_1
+#endif
+
+#define flash_EBIU_AMBCTL0  \
+	(flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | \
+	 flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN)
diff --git a/include/asm-blackfin/mach-bf548/mem_map.h b/include/asm-blackfin/mach-bf548/mem_map.h
new file mode 100644
index 0000000..72d80e8a
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/mem_map.h
@@ -0,0 +1,97 @@
+/*
+ * file:         include/asm-blackfin/mach-bf548/mem_map.h
+ * based on:
+ * author:
+ *
+ * created:
+ * description:
+ *	Memory MAP Common header file for blackfin BF537/6/4 of processors.
+ * rev:
+ *
+ * modified:
+ *
+ * bugs:         enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose.  see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _MEM_MAP_548_H_
+#define _MEM_MAP_548_H_
+
+#define COREMMR_BASE           0xFFE00000	 /* Core MMRs */
+#define SYSMMR_BASE            0xFFC00000	 /* System MMRs */
+
+/* Async Memory Banks */
+#define ASYNC_BANK3_BASE	0x2C000000	 /* Async Bank 3 */
+#define ASYNC_BANK3_SIZE	0x04000000	/* 64M */
+#define ASYNC_BANK2_BASE	0x28000000	 /* Async Bank 2 */
+#define ASYNC_BANK2_SIZE	0x04000000	/* 64M */
+#define ASYNC_BANK1_BASE	0x24000000	 /* Async Bank 1 */
+#define ASYNC_BANK1_SIZE	0x04000000	/* 64M */
+#define ASYNC_BANK0_BASE	0x20000000	 /* Async Bank 0 */
+#define ASYNC_BANK0_SIZE	0x04000000	/* 64M */
+
+/* Boot ROM Memory */
+
+#define BOOT_ROM_START		0xEF000000
+
+/* Level 1 Memory */
+
+/* Memory Map for ADSP-BF548 processors */
+#ifdef CONFIG_BLKFIN_ICACHE
+#define BLKFIN_ICACHESIZE	(16*1024)
+#else
+#define BLKFIN_ICACHESIZE	(0*1024)
+#endif
+
+#define L1_CODE_START       0xFFA00000
+#define L1_DATA_A_START     0xFF800000
+#define L1_DATA_B_START     0xFF900000
+
+#define L1_CODE_LENGTH      0xC000
+
+#ifdef CONFIG_BLKFIN_DCACHE
+
+#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH      0x8000
+#define BLKFIN_DCACHESIZE	(16*1024)
+#define BLKFIN_DSUPBANKS	1
+#else
+#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH      (0x8000 - 0x4000)
+#define BLKFIN_DCACHESIZE	(32*1024)
+#define BLKFIN_DSUPBANKS	2
+#endif
+
+#else
+#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH      0x8000
+#define L1_DATA_B_LENGTH      0x8000
+#define BLKFIN_DCACHESIZE	(0*1024)
+#define BLKFIN_DSUPBANKS	0
+#endif /*CONFIG_BLKFIN_DCACHE*/
+
+/* Scratch Pad Memory */
+
+#if defined(CONFIG_BF54x)
+#define L1_SCRATCH_START	0xFFB00000
+#define L1_SCRATCH_LENGTH	0x1000
+#endif
+
+#endif/* _MEM_MAP_548_H_ */
diff --git a/include/asm-blackfin/mach-bf548/portmux.h b/include/asm-blackfin/mach-bf548/portmux.h
new file mode 100644
index 0000000..b382deb
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/portmux.h
@@ -0,0 +1,270 @@
+#ifndef _MACH_PORTMUX_H_
+#define _MACH_PORTMUX_H_
+
+#define P_SPORT2_TFS	(P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(0))
+#define P_SPORT2_DTSEC	(P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(0))
+#define P_SPORT2_DTPRI	(P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(0))
+#define P_SPORT2_TSCLK	(P_DEFINED | P_IDENT(GPIO_PA3) | P_FUNCT(0))
+#define P_SPORT2_RFS	(P_DEFINED | P_IDENT(GPIO_PA4) | P_FUNCT(0))
+#define P_SPORT2_DRSEC	(P_DEFINED | P_IDENT(GPIO_PA5) | P_FUNCT(0))
+#define P_SPORT2_DRPRI	(P_DEFINED | P_IDENT(GPIO_PA6) | P_FUNCT(0))
+#define P_SPORT2_RSCLK	(P_DEFINED | P_IDENT(GPIO_PA7) | P_FUNCT(0))
+#define P_SPORT3_TFS	(P_DEFINED | P_IDENT(GPIO_PA8) | P_FUNCT(0))
+#define P_SPORT3_DTSEC	(P_DEFINED | P_IDENT(GPIO_PA9) | P_FUNCT(0))
+#define P_SPORT3_DTPRI	(P_DEFINED | P_IDENT(GPIO_PA10) | P_FUNCT(0))
+#define P_SPORT3_TSCLK	(P_DEFINED | P_IDENT(GPIO_PA11) | P_FUNCT(0))
+#define P_SPORT3_RFS	(P_DEFINED | P_IDENT(GPIO_PA12) | P_FUNCT(0))
+#define P_SPORT3_DRSEC	(P_DEFINED | P_IDENT(GPIO_PA13) | P_FUNCT(0))
+#define P_SPORT3_DRPRI	(P_DEFINED | P_IDENT(GPIO_PA14) | P_FUNCT(0))
+#define P_SPORT3_RSCLK	(P_DEFINED | P_IDENT(GPIO_PA15) | P_FUNCT(0))
+#define P_TMR4	(P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(1))
+#define P_TMR5	(P_DEFINED | P_IDENT(GPIO_PA5) | P_FUNCT(1))
+#define P_TMR6	(P_DEFINED | P_IDENT(GPIO_PA9) | P_FUNCT(1))
+#define P_TMR7	(P_DEFINED | P_IDENT(GPIO_PA13) | P_FUNCT(1))
+
+#define P_TWI1_SCL	(P_DEFINED | P_IDENT(GPIO_PB0) | P_FUNCT(0))
+#define P_TWI1_SDA	(P_DEFINED | P_IDENT(GPIO_PB1) | P_FUNCT(0))
+#define P_UART3_RTS	(P_DEFINED | P_IDENT(GPIO_PB2) | P_FUNCT(0))
+#define P_UART3_CTS	(P_DEFINED | P_IDENT(GPIO_PB3) | P_FUNCT(0))
+#define P_UART2_TX	(P_DEFINED | P_IDENT(GPIO_PB4) | P_FUNCT(0))
+#define P_UART2_RX	(P_DEFINED | P_IDENT(GPIO_PB5) | P_FUNCT(0))
+#define P_UART3_TX	(P_DEFINED | P_IDENT(GPIO_PB6) | P_FUNCT(0))
+#define P_UART3_RX	(P_DEFINED | P_IDENT(GPIO_PB7) | P_FUNCT(0))
+#define P_SPI2_SS	(P_DEFINED | P_IDENT(GPIO_PB8) | P_FUNCT(0))
+#define P_SPI2_SSEL1	(P_DEFINED | P_IDENT(GPIO_PB9) | P_FUNCT(0))
+#define P_SPI2_SSEL2	(P_DEFINED | P_IDENT(GPIO_PB10) | P_FUNCT(0))
+#define P_SPI2_SSEL3	(P_DEFINED | P_IDENT(GPIO_PB11) | P_FUNCT(0))
+#define P_SPI2_SCK	(P_DEFINED | P_IDENT(GPIO_PB12) | P_FUNCT(0))
+#define P_SPI2_MOSI	(P_DEFINED | P_IDENT(GPIO_PB13) | P_FUNCT(0))
+#define P_SPI2_MISO	(P_DEFINED | P_IDENT(GPIO_PB14) | P_FUNCT(0))
+#define P_TMR0	(P_DEFINED | P_IDENT(GPIO_PB8) | P_FUNCT(1))
+#define P_TMR1	(P_DEFINED | P_IDENT(GPIO_PB9) | P_FUNCT(1))
+#define P_TMR2	(P_DEFINED | P_IDENT(GPIO_PB10) | P_FUNCT(1))
+#define P_TMR3	(P_DEFINED | P_IDENT(GPIO_PB11) | P_FUNCT(1))
+
+#define P_SPORT0_TFS	(P_DEFINED | P_IDENT(GPIO_PC0) | P_FUNCT(0))
+#define P_SPORT0_DTSEC	(P_DEFINED | P_IDENT(GPIO_PC1) | P_FUNCT(0))
+#define P_SPORT0_DTPRI	(P_DEFINED | P_IDENT(GPIO_PC2) | P_FUNCT(0))
+#define P_SPORT0_TSCLK	(P_DEFINED | P_IDENT(GPIO_PC3) | P_FUNCT(0))
+#define P_SPORT0_RFS	(P_DEFINED | P_IDENT(GPIO_PC4) | P_FUNCT(0))
+#define P_SPORT0_DRSEC	(P_DEFINED | P_IDENT(GPIO_PC5) | P_FUNCT(0))
+#define P_SPORT0_DRPRI	(P_DEFINED | P_IDENT(GPIO_PC6) | P_FUNCT(0))
+#define P_SPORT0_RSCLK	(P_DEFINED | P_IDENT(GPIO_PC7) | P_FUNCT(0))
+#define P_SD_D0	(P_DEFINED | P_IDENT(GPIO_PC8) | P_FUNCT(0))
+#define P_SD_D1	(P_DEFINED | P_IDENT(GPIO_PC9) | P_FUNCT(0))
+#define P_SD_D2	(P_DEFINED | P_IDENT(GPIO_PC10) | P_FUNCT(0))
+#define P_SD_D3	(P_DEFINED | P_IDENT(GPIO_PC11) | P_FUNCT(0))
+#define P_SD_CLK	(P_DEFINED | P_IDENT(GPIO_PC12) | P_FUNCT(0))
+#define P_SD_CMD	(P_DEFINED | P_IDENT(GPIO_PC13) | P_FUNCT(0))
+#define P_MMCLK	(P_DEFINED | P_IDENT(GPIO_PC1) | P_FUNCT(1))
+#define P_MBCLK	(P_DEFINED | P_IDENT(GPIO_PC5) | P_FUNCT(1))
+
+#define P_PPI1_D0	(P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(0))
+#define P_PPI1_D1	(P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(0))
+#define P_PPI1_D2	(P_DEFINED | P_IDENT(GPIO_PD2) | P_FUNCT(0))
+#define P_PPI1_D3	(P_DEFINED | P_IDENT(GPIO_PD3) | P_FUNCT(0))
+#define P_PPI1_D4	(P_DEFINED | P_IDENT(GPIO_PD4) | P_FUNCT(0))
+#define P_PPI1_D5	(P_DEFINED | P_IDENT(GPIO_PD5) | P_FUNCT(0))
+#define P_PPI1_D6	(P_DEFINED | P_IDENT(GPIO_PD6) | P_FUNCT(0))
+#define P_PPI1_D7	(P_DEFINED | P_IDENT(GPIO_PD7) | P_FUNCT(0))
+#define P_PPI1_D8	(P_DEFINED | P_IDENT(GPIO_PD8) | P_FUNCT(0))
+#define P_PPI1_D9	(P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(0))
+#define P_PPI1_D10	(P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(0))
+#define P_PPI1_D11	(P_DEFINED | P_IDENT(GPIO_PD11) | P_FUNCT(0))
+#define P_PPI1_D12	(P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(0))
+#define P_PPI1_D13	(P_DEFINED | P_IDENT(GPIO_PD13) | P_FUNCT(0))
+#define P_PPI1_D14	(P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(0))
+#define P_PPI1_D15	(P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(0))
+
+#define P_HOST_D8	(P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(1))
+#define P_HOST_D9	(P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(1))
+#define P_HOST_D10	(P_DEFINED | P_IDENT(GPIO_PD2) | P_FUNCT(1))
+#define P_HOST_D11	(P_DEFINED | P_IDENT(GPIO_PD3) | P_FUNCT(1))
+#define P_HOST_D12	(P_DEFINED | P_IDENT(GPIO_PD4) | P_FUNCT(1))
+#define P_HOST_D13	(P_DEFINED | P_IDENT(GPIO_PD5) | P_FUNCT(1))
+#define P_HOST_D14	(P_DEFINED | P_IDENT(GPIO_PD6) | P_FUNCT(1))
+#define P_HOST_D15	(P_DEFINED | P_IDENT(GPIO_PD7) | P_FUNCT(1))
+#define P_HOST_D0	(P_DEFINED | P_IDENT(GPIO_PD8) | P_FUNCT(1))
+#define P_HOST_D1	(P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(1))
+#define P_HOST_D2	(P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(1))
+#define P_HOST_D3	(P_DEFINED | P_IDENT(GPIO_PD11) | P_FUNCT(1))
+#define P_HOST_D4	(P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(1))
+#define P_HOST_D5	(P_DEFINED | P_IDENT(GPIO_PD13) | P_FUNCT(1))
+#define P_HOST_D6	(P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(1))
+#define P_HOST_D7	(P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(1))
+#define P_SPORT1_TFS	(P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(2))
+#define P_SPORT1_DTSEC	(P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(2))
+#define P_SPORT1_DTPRI	(P_DEFINED | P_IDENT(GPIO_PD2) | P_FUNCT(2))
+#define P_SPORT1_TSCLK	(P_DEFINED | P_IDENT(GPIO_PD3) | P_FUNCT(2))
+#define P_SPORT1_RFS	(P_DEFINED | P_IDENT(GPIO_PD4) | P_FUNCT(2))
+#define P_SPORT1_DRSEC	(P_DEFINED | P_IDENT(GPIO_PD5) | P_FUNCT(2))
+#define P_SPORT1_DRPRI	(P_DEFINED | P_IDENT(GPIO_PD6) | P_FUNCT(2))
+#define P_SPORT1_RSCLK	(P_DEFINED | P_IDENT(GPIO_PD7) | P_FUNCT(2))
+#define P_PPI2_D0	(P_DEFINED | P_IDENT(GPIO_PD8) | P_FUNCT(2))
+#define P_PPI2_D1	(P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(2))
+#define P_PPI2_D2	(P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(2))
+#define P_PPI2_D3	(P_DEFINED | P_IDENT(GPIO_PD11) | P_FUNCT(2))
+#define P_PPI2_D4	(P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(2))
+#define P_PPI2_D5	(P_DEFINED | P_IDENT(GPIO_PD13) | P_FUNCT(2))
+#define P_PPI2_D6	(P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(2))
+#define P_PPI2_D7	(P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(2))
+#define P_PPI0_D18	(P_DEFINED | P_IDENT(GPIO_PD0) | P_FUNCT(3))
+#define P_PPI0_D19	(P_DEFINED | P_IDENT(GPIO_PD1) | P_FUNCT(3))
+#define P_PPI0_D20	(P_DEFINED | P_IDENT(GPIO_PD2) | P_FUNCT(3))
+#define P_PPI0_D21	(P_DEFINED | P_IDENT(GPIO_PD3) | P_FUNCT(3))
+#define P_PPI0_D22	(P_DEFINED | P_IDENT(GPIO_PD4) | P_FUNCT(3))
+#define P_PPI0_D23	(P_DEFINED | P_IDENT(GPIO_PD5) | P_FUNCT(3))
+#define P_KEY_ROW0	(P_DEFINED | P_IDENT(GPIO_PD8) | P_FUNCT(3))
+#define P_KEY_ROW1	(P_DEFINED | P_IDENT(GPIO_PD9) | P_FUNCT(3))
+#define P_KEY_ROW2	(P_DEFINED | P_IDENT(GPIO_PD10) | P_FUNCT(3))
+#define P_KEY_ROW3	(P_DEFINED | P_IDENT(GPIO_PD11) | P_FUNCT(3))
+#define P_KEY_COL0	(P_DEFINED | P_IDENT(GPIO_PD12) | P_FUNCT(3))
+#define P_KEY_COL1	(P_DEFINED | P_IDENT(GPIO_PD13) | P_FUNCT(3))
+#define P_KEY_COL2	(P_DEFINED | P_IDENT(GPIO_PD14) | P_FUNCT(3))
+#define P_KEY_COL3	(P_DEFINED | P_IDENT(GPIO_PD15) | P_FUNCT(3))
+
+#define P_SPI0_SCK	(P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(0))
+#define P_SPI0_MISO	(P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(0))
+#define P_SPI0_MOSI	(P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(0))
+#define P_SPI0_SS	(P_DEFINED | P_IDENT(GPIO_PE3) | P_FUNCT(0))
+#define P_SPI0_SSEL1	(P_DEFINED | P_IDENT(GPIO_PE4) | P_FUNCT(0))
+#define P_SPI0_SSEL2	(P_DEFINED | P_IDENT(GPIO_PE5) | P_FUNCT(0))
+#define P_SPI0_SSEL3	(P_DEFINED | P_IDENT(GPIO_PE6) | P_FUNCT(0))
+#define P_UART0_TX	(P_DEFINED | P_IDENT(GPIO_PE7) | P_FUNCT(0))
+#define P_UART0_RX	(P_DEFINED | P_IDENT(GPIO_PE8) | P_FUNCT(0))
+#define P_UART1_RTS	(P_DEFINED | P_IDENT(GPIO_PE9) | P_FUNCT(0))
+#define P_UART1_CTS	(P_DEFINED | P_IDENT(GPIO_PE10) | P_FUNCT(0))
+#define P_PPI1_CLK	(P_DEFINED | P_IDENT(GPIO_PE11) | P_FUNCT(0))
+#define P_PPI1_FS1	(P_DEFINED | P_IDENT(GPIO_PE12) | P_FUNCT(0))
+#define P_PPI1_FS2	(P_DEFINED | P_IDENT(GPIO_PE13) | P_FUNCT(0))
+#define P_TWI0_SCL	(P_DEFINED | P_IDENT(GPIO_PE14) | P_FUNCT(0))
+#define P_TWI0_SDA	(P_DEFINED | P_IDENT(GPIO_PE15) | P_FUNCT(0))
+#define P_KEY_COL7	(P_DEFINED | P_IDENT(GPIO_PE0) | P_FUNCT(1))
+#define P_KEY_ROW6	(P_DEFINED | P_IDENT(GPIO_PE1) | P_FUNCT(1))
+#define P_KEY_COL6	(P_DEFINED | P_IDENT(GPIO_PE2) | P_FUNCT(1))
+#define P_KEY_ROW5	(P_DEFINED | P_IDENT(GPIO_PE3) | P_FUNCT(1))
+#define P_KEY_COL5	(P_DEFINED | P_IDENT(GPIO_PE4) | P_FUNCT(1))
+#define P_KEY_ROW4	(P_DEFINED | P_IDENT(GPIO_PE5) | P_FUNCT(1))
+#define P_KEY_COL4	(P_DEFINED | P_IDENT(GPIO_PE6) | P_FUNCT(1))
+#define P_KEY_ROW7	(P_DEFINED | P_IDENT(GPIO_PE7) | P_FUNCT(1))
+
+#define P_PPI0_D0	(P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(0))
+#define P_PPI0_D1	(P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(0))
+#define P_PPI0_D2	(P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(0))
+#define P_PPI0_D3	(P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(0))
+#define P_PPI0_D4	(P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(0))
+#define P_PPI0_D5	(P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(0))
+#define P_PPI0_D6	(P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(0))
+#define P_PPI0_D7	(P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(0))
+#define P_PPI0_D8	(P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(0))
+#define P_PPI0_D9	(P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(0))
+#define P_PPI0_D10	(P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(0))
+#define P_PPI0_D11	(P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(0))
+#define P_PPI0_D12	(P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(0))
+#define P_PPI0_D13	(P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(0))
+#define P_PPI0_D14	(P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(0))
+#define P_PPI0_D15	(P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(0))
+#define P_ATAPI_D0A	(P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(1))
+#define P_ATAPI_D1A	(P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(1))
+#define P_ATAPI_D2A	(P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(1))
+#define P_ATAPI_D3A	(P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(1))
+#define P_ATAPI_D4A	(P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(1))
+#define P_ATAPI_D5A	(P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(1))
+#define P_ATAPI_D6A	(P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(1))
+#define P_ATAPI_D7A	(P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(1))
+#define P_ATAPI_D8A	(P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(1))
+#define P_ATAPI_D9A	(P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(1))
+#define P_ATAPI_D10A	(P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(1))
+#define P_ATAPI_D11A	(P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(1))
+#define P_ATAPI_D12A	(P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(1))
+#define P_ATAPI_D13A	(P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(1))
+#define P_ATAPI_D14A	(P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(1))
+#define P_ATAPI_D15A	(P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(1))
+
+#define P_PPI0_CLK	(P_DEFINED | P_IDENT(GPIO_PG0) | P_FUNCT(0))
+#define P_PPI0_FS1	(P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0))
+#define P_PPI0_FS2	(P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(0))
+#define P_PPI0_D16	(P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(0))
+#define P_PPI0_D17	(P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(0))
+#define P_SPI1_SSEL1	(P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(0))
+#define P_SPI1_SSEL2	(P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(0))
+#define P_SPI1_SSEL3	(P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(0))
+#define P_SPI1_SCK	(P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(0))
+#define P_SPI1_MISO	(P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(0))
+#define P_SPI1_MOSI	(P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(0))
+#define P_SPI1_SS	(P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(0))
+#define P_CAN0_TX	(P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(0))
+#define P_CAN0_RX	(P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(0))
+#define P_CAN1_TX	(P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(0))
+#define P_CAN1_RX	(P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(0))
+#define P_ATAPI_A0A	(P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(1))
+#define P_ATAPI_A1A	(P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(1))
+#define P_ATAPI_A2A	(P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(1))
+#define P_HOST_CE	(P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(1))
+#define P_HOST_RD	(P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(1))
+#define P_HOST_WR	(P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(1))
+#define P_MTXONB	(P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(1))
+#define P_PPI2_FS2	(P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(2))
+#define P_PPI2_FS1	(P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(2))
+#define P_PPI2_CLK	(P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(2))
+#define P_CNT_CZM	(P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(3))
+
+#define P_UART1_TX	(P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(0))
+#define P_UART1_RX	(P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(0))
+#define P_ATAPI_RESET	(P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(0))
+#define P_HOST_ADDR	(P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(0))
+#define P_HOST_ACK	(P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(0))
+#define P_MTX	(P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(0))
+#define P_MRX	(P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(0))
+#define P_MRXONB	(P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(0))
+#define P_A4	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(0))
+#define P_A5	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(0))
+#define P_A6	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(0))
+#define P_A7	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(0))
+#define P_A8	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(0))
+#define P_A9	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(0))
+#define P_PPI1_FS3	(P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(1))
+#define P_PPI2_FS3	(P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(1))
+#define P_TMR8	(P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(1))
+#define P_TMR9	(P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(1))
+#define P_TMR10	(P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(1))
+#define P_DMAR0	(P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(1))
+#define P_DMAR1	(P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(1))
+#define P_PPI0_FS3	(P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(2))
+#define P_CNT_CDG	(P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(2))
+#define P_CNT_CUD	(P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(2))
+
+#define P_A10	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI0) | P_FUNCT(0))
+#define P_A11	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI1) | P_FUNCT(0))
+#define P_A12	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI2) | P_FUNCT(0))
+#define P_A13	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI3) | P_FUNCT(0))
+#define P_A14	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI4) | P_FUNCT(0))
+#define P_A15	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI5) | P_FUNCT(0))
+#define P_A16	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI6) | P_FUNCT(0))
+#define P_A17	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI7) | P_FUNCT(0))
+#define P_A18	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI8) | P_FUNCT(0))
+#define P_A19	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI9) | P_FUNCT(0))
+#define P_A20	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI10) | P_FUNCT(0))
+#define P_A21	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI11) | P_FUNCT(0))
+#define P_A22	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI12) | P_FUNCT(0))
+#define P_A23	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI13) | P_FUNCT(0))
+#define P_A24	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI14) | P_FUNCT(0))
+#define P_A25	(P_MAYSHARE | P_DEFINED | P_IDENT(GPIO_PI15) | P_FUNCT(0))
+#define P_NOR_CLK	(P_DEFINED | P_IDENT(GPIO_PI15) | P_FUNCT(1))
+
+#define P_AMC_ARDY_NOR_WAIT	(P_DEFINED | P_IDENT(GPIO_PJ0) | P_FUNCT(0))
+#define P_NAND_CE	(P_DEFINED | P_IDENT(GPIO_PJ1) | P_FUNCT(0))
+#define P_NAND_RB	(P_DEFINED | P_IDENT(GPIO_PJ2) | P_FUNCT(0))
+#define P_ATAPI_DIOR	(P_DEFINED | P_IDENT(GPIO_PJ3) | P_FUNCT(0))
+#define P_ATAPI_DIOW	(P_DEFINED | P_IDENT(GPIO_PJ4) | P_FUNCT(0))
+#define P_ATAPI_CS0	(P_DEFINED | P_IDENT(GPIO_PJ5) | P_FUNCT(0))
+#define P_ATAPI_CS1	(P_DEFINED | P_IDENT(GPIO_PJ6) | P_FUNCT(0))
+#define P_ATAPI_DMACK	(P_DEFINED | P_IDENT(GPIO_PJ7) | P_FUNCT(0))
+#define P_ATAPI_DMARQ	(P_DEFINED | P_IDENT(GPIO_PJ8) | P_FUNCT(0))
+#define P_ATAPI_INTRQ	(P_DEFINED | P_IDENT(GPIO_PJ9) | P_FUNCT(0))
+#define P_ATAPI_IORDY	(P_DEFINED | P_IDENT(GPIO_PJ10) | P_FUNCT(0))
+#define P_AMC_BR	(P_DEFINED | P_IDENT(GPIO_PJ11) | P_FUNCT(0))
+#define P_AMC_BG	(P_DEFINED | P_IDENT(GPIO_PJ12) | P_FUNCT(0))
+#define P_AMC_BGH	(P_DEFINED | P_IDENT(GPIO_PJ13) | P_FUNCT(0))
+
+#endif /* _MACH_PORTMUX_H_ */
diff --git a/include/asm-blackfin/mach-bf561/cdefBF561.h b/include/asm-blackfin/mach-bf561/cdefBF561.h
index b14f872..1a8ec9e 100644
--- a/include/asm-blackfin/mach-bf561/cdefBF561.h
+++ b/include/asm-blackfin/mach-bf561/cdefBF561.h
@@ -57,12 +57,14 @@
 /* Writing to VR_CTL initiates a PLL relock sequence. */
 static __inline__ void bfin_write_VR_CTL(unsigned int val)
 {
-	unsigned long flags, iwr;
+	unsigned long flags, iwr0, iwr1;
 
 	/* Enable the PLL Wakeup bit in SIC IWR */
-	iwr = bfin_read32(SICA_IWR0);
+	iwr0 = bfin_read32(SICA_IWR0);
+	iwr1 = bfin_read32(SICA_IWR1);
 	/* Only allow PPL Wakeup) */
 	bfin_write32(SICA_IWR0, IWR_ENABLE(0));
+	bfin_write32(SICA_IWR1, 0);
 
 	bfin_write16(VR_CTL, val);
 	__builtin_bfin_ssync();
@@ -70,7 +72,8 @@
 	local_irq_save(flags);
 	asm("IDLE;");
 	local_irq_restore(flags);
-	bfin_write32(SICA_IWR0, iwr);
+	bfin_write32(SICA_IWR0, iwr0);
+	bfin_write32(SICA_IWR1, iwr1);
 }
 #define bfin_read_PLL_STAT()                 bfin_read16(PLL_STAT)
 #define bfin_write_PLL_STAT(val)             bfin_write16(PLL_STAT,val)
diff --git a/include/asm-blackfin/mach-bf561/dma.h b/include/asm-blackfin/mach-bf561/dma.h
index 21d9820..766334b 100644
--- a/include/asm-blackfin/mach-bf561/dma.h
+++ b/include/asm-blackfin/mach-bf561/dma.h
@@ -32,4 +32,7 @@
 #define CH_IMEM_STREAM1_SRC	34
 #define CH_IMEM_STREAM1_DEST	35
 
+extern int channel2irq(unsigned int channel);
+extern struct dma_register *base_addr[];
+
 #endif
diff --git a/include/asm-blackfin/mach-bf561/portmux.h b/include/asm-blackfin/mach-bf561/portmux.h
new file mode 100644
index 0000000..10d11d5
--- /dev/null
+++ b/include/asm-blackfin/mach-bf561/portmux.h
@@ -0,0 +1,87 @@
+#ifndef _MACH_PORTMUX_H_
+#define _MACH_PORTMUX_H_
+
+#define P_PPI0_CLK	(P_DONTCARE)
+#define P_PPI0_FS1	(P_DONTCARE)
+#define P_PPI0_FS2	(P_DONTCARE)
+#define P_PPI0_FS3	(P_DONTCARE)
+#define P_PPI0_D15	(P_DEFINED | P_IDENT(GPIO_PF47))
+#define P_PPI0_D14	(P_DEFINED | P_IDENT(GPIO_PF46))
+#define P_PPI0_D13	(P_DEFINED | P_IDENT(GPIO_PF45))
+#define P_PPI0_D12	(P_DEFINED | P_IDENT(GPIO_PF44))
+#define P_PPI0_D11	(P_DEFINED | P_IDENT(GPIO_PF43))
+#define P_PPI0_D10	(P_DEFINED | P_IDENT(GPIO_PF42))
+#define P_PPI0_D9	(P_DEFINED | P_IDENT(GPIO_PF41))
+#define P_PPI0_D8	(P_DEFINED | P_IDENT(GPIO_PF40))
+#define P_PPI0_D0	(P_DONTCARE)
+#define P_PPI0_D1	(P_DONTCARE)
+#define P_PPI0_D2	(P_DONTCARE)
+#define P_PPI0_D3	(P_DONTCARE)
+#define P_PPI0_D4	(P_DONTCARE)
+#define P_PPI0_D5	(P_DONTCARE)
+#define P_PPI0_D6	(P_DONTCARE)
+#define P_PPI0_D7	(P_DONTCARE)
+#define P_PPI1_CLK	(P_DONTCARE)
+#define P_PPI1_FS1	(P_DONTCARE)
+#define P_PPI1_FS2	(P_DONTCARE)
+#define P_PPI1_FS3	(P_DONTCARE)
+#define P_PPI1_D15	(P_DEFINED | P_IDENT(GPIO_PF39))
+#define P_PPI1_D14	(P_DEFINED | P_IDENT(GPIO_PF38))
+#define P_PPI1_D13	(P_DEFINED | P_IDENT(GPIO_PF37))
+#define P_PPI1_D12	(P_DEFINED | P_IDENT(GPIO_PF36))
+#define P_PPI1_D11	(P_DEFINED | P_IDENT(GPIO_PF35))
+#define P_PPI1_D10	(P_DEFINED | P_IDENT(GPIO_PF34))
+#define P_PPI1_D9	(P_DEFINED | P_IDENT(GPIO_PF33))
+#define P_PPI1_D8	(P_DEFINED | P_IDENT(GPIO_PF32))
+#define P_PPI1_D0	(P_DONTCARE)
+#define P_PPI1_D1	(P_DONTCARE)
+#define P_PPI1_D2	(P_DONTCARE)
+#define P_PPI1_D3	(P_DONTCARE)
+#define P_PPI1_D4	(P_DONTCARE)
+#define P_PPI1_D5	(P_DONTCARE)
+#define P_PPI1_D6	(P_DONTCARE)
+#define P_PPI1_D7	(P_DONTCARE)
+#define P_SPORT1_TSCLK	(P_DEFINED | P_IDENT(GPIO_PF31))
+#define P_SPORT1_RSCLK	(P_DEFINED | P_IDENT(GPIO_PF30))
+#define P_SPORT0_TSCLK	(P_DEFINED | P_IDENT(GPIO_PF29))
+#define P_SPORT0_RSCLK	(P_DEFINED | P_IDENT(GPIO_PF28))
+#define P_UART0_RX	(P_DEFINED | P_IDENT(GPIO_PF27))
+#define P_UART0_TX	(P_DEFINED | P_IDENT(GPIO_PF26))
+#define P_SPORT1_DRSEC	(P_DEFINED | P_IDENT(GPIO_PF25))
+#define P_SPORT1_RFS	(P_DEFINED | P_IDENT(GPIO_PF24))
+#define P_SPORT1_DTPRI	(P_DEFINED | P_IDENT(GPIO_PF23))
+#define P_SPORT1_DTSEC	(P_DEFINED | P_IDENT(GPIO_PF22))
+#define P_SPORT1_TFS	(P_DEFINED | P_IDENT(GPIO_PF21))
+#define P_SPORT1_DRPRI	(P_DONTCARE)
+#define P_SPORT0_DRSEC	(P_DEFINED | P_IDENT(GPIO_PF20))
+#define P_SPORT0_RFS	(P_DEFINED | P_IDENT(GPIO_PF19))
+#define P_SPORT0_DTPRI	(P_DEFINED | P_IDENT(GPIO_PF18))
+#define P_SPORT0_DTSEC	(P_DEFINED | P_IDENT(GPIO_PF17))
+#define P_SPORT0_TFS	(P_DEFINED | P_IDENT(GPIO_PF16))
+#define P_SPORT0_DRPRI	(P_DONTCARE)
+#define P_TMRCLK	(P_DEFINED | P_IDENT(GPIO_PF15))
+#define P_SPI0_SSEL7	(P_DEFINED | P_IDENT(GPIO_PF7))
+#define P_SPI0_SSEL6	(P_DEFINED | P_IDENT(GPIO_PF6))
+#define P_SPI0_SSEL5	(P_DEFINED | P_IDENT(GPIO_PF5))
+#define P_SPI0_SSEL4	(P_DEFINED | P_IDENT(GPIO_PF4))
+#define P_SPI0_SSEL3	(P_DEFINED | P_IDENT(GPIO_PF3))
+#define P_SPI0_SSEL2	(P_DEFINED | P_IDENT(GPIO_PF2))
+#define P_SPI0_SSEL1	(P_DEFINED | P_IDENT(GPIO_PF1))
+#define P_SPI0_SS	(P_DEFINED | P_IDENT(GPIO_PF0))
+#define P_TMR11		(P_DONTCARE)
+#define P_TMR10		(P_DONTCARE)
+#define P_TMR9		(P_DONTCARE)
+#define P_TMR8		(P_DONTCARE)
+#define P_TMR7		(P_DEFINED | P_IDENT(GPIO_PF7))
+#define P_TMR6		(P_DEFINED | P_IDENT(GPIO_PF6))
+#define P_TMR5		(P_DEFINED | P_IDENT(GPIO_PF5))
+#define P_TMR4		(P_DEFINED | P_IDENT(GPIO_PF4))
+#define P_TMR3		(P_DEFINED | P_IDENT(GPIO_PF3))
+#define P_TMR2		(P_DEFINED | P_IDENT(GPIO_PF2))
+#define P_TMR1		(P_DEFINED | P_IDENT(GPIO_PF1))
+#define P_TMR0		(P_DEFINED | P_IDENT(GPIO_PF0))
+#define P_SPI0_MOSI	(P_DONTCARE)
+#define P_SPI0_MIS0	(P_DONTCARE)
+#define P_SPI0_SCK	(P_DONTCARE)
+
+#endif /* _MACH_PORTMUX_H_ */
diff --git a/include/asm-blackfin/mach-common/cdef_LPBlackfin.h b/include/asm-blackfin/mach-common/cdef_LPBlackfin.h
index 58f8789..94ed381 100644
--- a/include/asm-blackfin/mach-common/cdef_LPBlackfin.h
+++ b/include/asm-blackfin/mach-common/cdef_LPBlackfin.h
@@ -40,16 +40,7 @@
 #define bfin_write_SRAM_BASE_ADDRESS(val)    bfin_write32(SRAM_BASE_ADDRESS,val)
 #define bfin_read_DMEM_CONTROL()             bfin_read32(DMEM_CONTROL)
 #ifdef ANOMALY_05000125
-static __inline__ void bfin_write_DMEM_CONTROL(unsigned int val)
-{
-	unsigned long flags, iwr;
-
-	local_irq_save(flags);
-	__asm__(".align 8\n");
-	bfin_write32(IMEM_CONTROL, val);
-	__builtin_bfin_ssync();
-	local_irq_restore(flags);
-}
+extern void bfin_write_DMEM_CONTROL(unsigned int val);
 #else
 #define bfin_write_DMEM_CONTROL(val)         bfin_write32(DMEM_CONTROL,val)
 #endif
@@ -139,17 +130,7 @@
 */
 #define bfin_read_IMEM_CONTROL()             bfin_read32(IMEM_CONTROL)
 #ifdef ANOMALY_05000125
-static __inline__ void bfin_write_IMEM_CONTROL(unsigned int val)
-{
-	unsigned long flags, iwr;
-
-	local_irq_save(flags);
-	__asm__(".align 8\n");
-	bfin_write32(IMEM_CONTROL, val);
-	__builtin_bfin_ssync();
-	local_irq_restore(flags);
-
-}
+extern void bfin_write_IMEM_CONTROL(unsigned int val);
 #else
 #define bfin_write_IMEM_CONTROL(val)         bfin_write32(IMEM_CONTROL,val)
 #endif
diff --git a/include/asm-blackfin/mman.h b/include/asm-blackfin/mman.h
index 4d504f9..b58f5ad 100644
--- a/include/asm-blackfin/mman.h
+++ b/include/asm-blackfin/mman.h
@@ -22,8 +22,6 @@
 #define MAP_NORESERVE	0x4000	/* don't check for reservations */
 #define MAP_POPULATE	0x8000	/* populate (prefault) pagetables */
 #define MAP_NONBLOCK	0x10000	/* do not block on IO */
-#define MAP_UNINITIALIZE 0x4000000  /* For anonymous mmap, memory could
-                                    be uninitialized. */
 
 #define MS_ASYNC	1	/* sync memory asynchronously */
 #define MS_INVALIDATE	2	/* invalidate the caches */
diff --git a/include/asm-blackfin/page.h b/include/asm-blackfin/page.h
index ffad947..8bc8671 100644
--- a/include/asm-blackfin/page.h
+++ b/include/asm-blackfin/page.h
@@ -4,7 +4,11 @@
 /* PAGE_SHIFT determines the page size */
 
 #define PAGE_SHIFT	12
+#ifdef __ASSEMBLY__
+#define PAGE_SIZE	(1 << PAGE_SHIFT)
+#else
 #define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#endif
 #define PAGE_MASK	(~(PAGE_SIZE-1))
 
 #ifdef __KERNEL__
diff --git a/include/asm-blackfin/portmux.h b/include/asm-blackfin/portmux.h
new file mode 100644
index 0000000..9d3681e
--- /dev/null
+++ b/include/asm-blackfin/portmux.h
@@ -0,0 +1,1133 @@
+/*
+ * Common header file for blackfin family of processors.
+ *
+ */
+
+#ifndef _PORTMUX_H_
+#define _PORTMUX_H_
+
+#define P_IDENT(x)	((x) & 0x1FF)
+#define P_FUNCT(x)	(((x) & 0x3) << 9)
+#define P_FUNCT2MUX(x)	(((x) >> 9) & 0x3)
+#define P_DEFINED	0x8000
+#define P_UNDEF		0x4000
+#define P_MAYSHARE	0x2000
+#define P_DONTCARE	0x1000
+
+#include <asm/gpio.h>
+#include <asm/mach/portmux.h>
+
+#ifndef P_SPORT2_TFS
+#define P_SPORT2_TFS P_UNDEF
+#endif
+
+#ifndef P_SPORT2_DTSEC
+#define P_SPORT2_DTSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT2_DTPRI
+#define P_SPORT2_DTPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT2_TSCLK
+#define P_SPORT2_TSCLK P_UNDEF
+#endif
+
+#ifndef P_SPORT2_RFS
+#define P_SPORT2_RFS P_UNDEF
+#endif
+
+#ifndef P_SPORT2_DRSEC
+#define P_SPORT2_DRSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT2_DRPRI
+#define P_SPORT2_DRPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT2_RSCLK
+#define P_SPORT2_RSCLK P_UNDEF
+#endif
+
+#ifndef P_SPORT3_TFS
+#define P_SPORT3_TFS P_UNDEF
+#endif
+
+#ifndef P_SPORT3_DTSEC
+#define P_SPORT3_DTSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT3_DTPRI
+#define P_SPORT3_DTPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT3_TSCLK
+#define P_SPORT3_TSCLK P_UNDEF
+#endif
+
+#ifndef P_SPORT3_RFS
+#define P_SPORT3_RFS P_UNDEF
+#endif
+
+#ifndef P_SPORT3_DRSEC
+#define P_SPORT3_DRSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT3_DRPRI
+#define P_SPORT3_DRPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT3_RSCLK
+#define P_SPORT3_RSCLK P_UNDEF
+#endif
+
+#ifndef P_TMR4
+#define P_TMR4 P_UNDEF
+#endif
+
+#ifndef P_TMR5
+#define P_TMR5 P_UNDEF
+#endif
+
+#ifndef P_TMR6
+#define P_TMR6 P_UNDEF
+#endif
+
+#ifndef P_TMR7
+#define P_TMR7 P_UNDEF
+#endif
+
+#ifndef P_TWI1_SCL
+#define P_TWI1_SCL P_UNDEF
+#endif
+
+#ifndef P_TWI1_SDA
+#define P_TWI1_SDA P_UNDEF
+#endif
+
+#ifndef P_UART3_RTS
+#define P_UART3_RTS P_UNDEF
+#endif
+
+#ifndef P_UART3_CTS
+#define P_UART3_CTS P_UNDEF
+#endif
+
+#ifndef P_UART2_TX
+#define P_UART2_TX P_UNDEF
+#endif
+
+#ifndef P_UART2_RX
+#define P_UART2_RX P_UNDEF
+#endif
+
+#ifndef P_UART3_TX
+#define P_UART3_TX P_UNDEF
+#endif
+
+#ifndef P_UART3_RX
+#define P_UART3_RX P_UNDEF
+#endif
+
+#ifndef P_SPI2_SS
+#define P_SPI2_SS P_UNDEF
+#endif
+
+#ifndef P_SPI2_SSEL1
+#define P_SPI2_SSEL1 P_UNDEF
+#endif
+
+#ifndef P_SPI2_SSEL2
+#define P_SPI2_SSEL2 P_UNDEF
+#endif
+
+#ifndef P_SPI2_SSEL3
+#define P_SPI2_SSEL3 P_UNDEF
+#endif
+
+#ifndef P_SPI2_SCK
+#define P_SPI2_SCK P_UNDEF
+#endif
+
+#ifndef P_SPI2_MOSI
+#define P_SPI2_MOSI P_UNDEF
+#endif
+
+#ifndef P_SPI2_MISO
+#define P_SPI2_MISO P_UNDEF
+#endif
+
+#ifndef P_TMR0
+#define P_TMR0 P_UNDEF
+#endif
+
+#ifndef P_TMR1
+#define P_TMR1 P_UNDEF
+#endif
+
+#ifndef P_TMR2
+#define P_TMR2 P_UNDEF
+#endif
+
+#ifndef P_TMR3
+#define P_TMR3 P_UNDEF
+#endif
+
+#ifndef P_SPORT0_TFS
+#define P_SPORT0_TFS P_UNDEF
+#endif
+
+#ifndef P_SPORT0_DTSEC
+#define P_SPORT0_DTSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT0_DTPRI
+#define P_SPORT0_DTPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT0_TSCLK
+#define P_SPORT0_TSCLK P_UNDEF
+#endif
+
+#ifndef P_SPORT0_RFS
+#define P_SPORT0_RFS P_UNDEF
+#endif
+
+#ifndef P_SPORT0_DRSEC
+#define P_SPORT0_DRSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT0_DRPRI
+#define P_SPORT0_DRPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT0_RSCLK
+#define P_SPORT0_RSCLK P_UNDEF
+#endif
+
+#ifndef P_SD_D0
+#define P_SD_D0 P_UNDEF
+#endif
+
+#ifndef P_SD_D1
+#define P_SD_D1 P_UNDEF
+#endif
+
+#ifndef P_SD_D2
+#define P_SD_D2 P_UNDEF
+#endif
+
+#ifndef P_SD_D3
+#define P_SD_D3 P_UNDEF
+#endif
+
+#ifndef P_SD_CLK
+#define P_SD_CLK P_UNDEF
+#endif
+
+#ifndef P_SD_CMD
+#define P_SD_CMD P_UNDEF
+#endif
+
+#ifndef P_MMCLK
+#define P_MMCLK P_UNDEF
+#endif
+
+#ifndef P_MBCLK
+#define P_MBCLK P_UNDEF
+#endif
+
+#ifndef P_PPI1_D0
+#define P_PPI1_D0 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D1
+#define P_PPI1_D1 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D2
+#define P_PPI1_D2 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D3
+#define P_PPI1_D3 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D4
+#define P_PPI1_D4 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D5
+#define P_PPI1_D5 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D6
+#define P_PPI1_D6 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D7
+#define P_PPI1_D7 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D8
+#define P_PPI1_D8 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D9
+#define P_PPI1_D9 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D10
+#define P_PPI1_D10 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D11
+#define P_PPI1_D11 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D12
+#define P_PPI1_D12 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D13
+#define P_PPI1_D13 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D14
+#define P_PPI1_D14 P_UNDEF
+#endif
+
+#ifndef P_PPI1_D15
+#define P_PPI1_D15 P_UNDEF
+#endif
+
+#ifndef P_HOST_D8
+#define P_HOST_D8 P_UNDEF
+#endif
+
+#ifndef P_HOST_D9
+#define P_HOST_D9 P_UNDEF
+#endif
+
+#ifndef P_HOST_D10
+#define P_HOST_D10 P_UNDEF
+#endif
+
+#ifndef P_HOST_D11
+#define P_HOST_D11 P_UNDEF
+#endif
+
+#ifndef P_HOST_D12
+#define P_HOST_D12 P_UNDEF
+#endif
+
+#ifndef P_HOST_D13
+#define P_HOST_D13 P_UNDEF
+#endif
+
+#ifndef P_HOST_D14
+#define P_HOST_D14 P_UNDEF
+#endif
+
+#ifndef P_HOST_D15
+#define P_HOST_D15 P_UNDEF
+#endif
+
+#ifndef P_HOST_D0
+#define P_HOST_D0 P_UNDEF
+#endif
+
+#ifndef P_HOST_D1
+#define P_HOST_D1 P_UNDEF
+#endif
+
+#ifndef P_HOST_D2
+#define P_HOST_D2 P_UNDEF
+#endif
+
+#ifndef P_HOST_D3
+#define P_HOST_D3 P_UNDEF
+#endif
+
+#ifndef P_HOST_D4
+#define P_HOST_D4 P_UNDEF
+#endif
+
+#ifndef P_HOST_D5
+#define P_HOST_D5 P_UNDEF
+#endif
+
+#ifndef P_HOST_D6
+#define P_HOST_D6 P_UNDEF
+#endif
+
+#ifndef P_HOST_D7
+#define P_HOST_D7 P_UNDEF
+#endif
+
+#ifndef P_SPORT1_TFS
+#define P_SPORT1_TFS P_UNDEF
+#endif
+
+#ifndef P_SPORT1_DTSEC
+#define P_SPORT1_DTSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT1_DTPRI
+#define P_SPORT1_DTPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT1_TSCLK
+#define P_SPORT1_TSCLK P_UNDEF
+#endif
+
+#ifndef P_SPORT1_RFS
+#define P_SPORT1_RFS P_UNDEF
+#endif
+
+#ifndef P_SPORT1_DRSEC
+#define P_SPORT1_DRSEC P_UNDEF
+#endif
+
+#ifndef P_SPORT1_DRPRI
+#define P_SPORT1_DRPRI P_UNDEF
+#endif
+
+#ifndef P_SPORT1_RSCLK
+#define P_SPORT1_RSCLK P_UNDEF
+#endif
+
+#ifndef P_PPI2_D0
+#define P_PPI2_D0 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D1
+#define P_PPI2_D1 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D2
+#define P_PPI2_D2 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D3
+#define P_PPI2_D3 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D4
+#define P_PPI2_D4 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D5
+#define P_PPI2_D5 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D6
+#define P_PPI2_D6 P_UNDEF
+#endif
+
+#ifndef P_PPI2_D7
+#define P_PPI2_D7 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D18
+#define P_PPI0_D18 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D19
+#define P_PPI0_D19 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D20
+#define P_PPI0_D20 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D21
+#define P_PPI0_D21 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D22
+#define P_PPI0_D22 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D23
+#define P_PPI0_D23 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW0
+#define P_KEY_ROW0 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW1
+#define P_KEY_ROW1 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW2
+#define P_KEY_ROW2 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW3
+#define P_KEY_ROW3 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL0
+#define P_KEY_COL0 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL1
+#define P_KEY_COL1 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL2
+#define P_KEY_COL2 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL3
+#define P_KEY_COL3 P_UNDEF
+#endif
+
+#ifndef P_SPI0_SCK
+#define P_SPI0_SCK P_UNDEF
+#endif
+
+#ifndef P_SPI0_MISO
+#define P_SPI0_MISO P_UNDEF
+#endif
+
+#ifndef P_SPI0_MOSI
+#define P_SPI0_MOSI P_UNDEF
+#endif
+
+#ifndef P_SPI0_SS
+#define P_SPI0_SS P_UNDEF
+#endif
+
+#ifndef P_SPI0_SSEL1
+#define P_SPI0_SSEL1 P_UNDEF
+#endif
+
+#ifndef P_SPI0_SSEL2
+#define P_SPI0_SSEL2 P_UNDEF
+#endif
+
+#ifndef P_SPI0_SSEL3
+#define P_SPI0_SSEL3 P_UNDEF
+#endif
+
+#ifndef P_UART0_TX
+#define P_UART0_TX P_UNDEF
+#endif
+
+#ifndef P_UART0_RX
+#define P_UART0_RX P_UNDEF
+#endif
+
+#ifndef P_UART1_RTS
+#define P_UART1_RTS P_UNDEF
+#endif
+
+#ifndef P_UART1_CTS
+#define P_UART1_CTS P_UNDEF
+#endif
+
+#ifndef P_PPI1_CLK
+#define P_PPI1_CLK P_UNDEF
+#endif
+
+#ifndef P_PPI1_FS1
+#define P_PPI1_FS1 P_UNDEF
+#endif
+
+#ifndef P_PPI1_FS2
+#define P_PPI1_FS2 P_UNDEF
+#endif
+
+#ifndef P_TWI0_SCL
+#define P_TWI0_SCL P_UNDEF
+#endif
+
+#ifndef P_TWI0_SDA
+#define P_TWI0_SDA P_UNDEF
+#endif
+
+#ifndef P_KEY_COL7
+#define P_KEY_COL7 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW6
+#define P_KEY_ROW6 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL6
+#define P_KEY_COL6 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW5
+#define P_KEY_ROW5 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL5
+#define P_KEY_COL5 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW4
+#define P_KEY_ROW4 P_UNDEF
+#endif
+
+#ifndef P_KEY_COL4
+#define P_KEY_COL4 P_UNDEF
+#endif
+
+#ifndef P_KEY_ROW7
+#define P_KEY_ROW7 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D0
+#define P_PPI0_D0 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D1
+#define P_PPI0_D1 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D2
+#define P_PPI0_D2 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D3
+#define P_PPI0_D3 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D4
+#define P_PPI0_D4 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D5
+#define P_PPI0_D5 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D6
+#define P_PPI0_D6 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D7
+#define P_PPI0_D7 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D8
+#define P_PPI0_D8 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D9
+#define P_PPI0_D9 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D10
+#define P_PPI0_D10 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D11
+#define P_PPI0_D11 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D12
+#define P_PPI0_D12 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D13
+#define P_PPI0_D13 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D14
+#define P_PPI0_D14 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D15
+#define P_PPI0_D15 P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D0A
+#define P_ATAPI_D0A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D1A
+#define P_ATAPI_D1A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D2A
+#define P_ATAPI_D2A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D3A
+#define P_ATAPI_D3A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D4A
+#define P_ATAPI_D4A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D5A
+#define P_ATAPI_D5A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D6A
+#define P_ATAPI_D6A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D7A
+#define P_ATAPI_D7A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D8A
+#define P_ATAPI_D8A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D9A
+#define P_ATAPI_D9A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D10A
+#define P_ATAPI_D10A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D11A
+#define P_ATAPI_D11A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D12A
+#define P_ATAPI_D12A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D13A
+#define P_ATAPI_D13A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D14A
+#define P_ATAPI_D14A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_D15A
+#define P_ATAPI_D15A P_UNDEF
+#endif
+
+#ifndef P_PPI0_CLK
+#define P_PPI0_CLK P_UNDEF
+#endif
+
+#ifndef P_PPI0_FS1
+#define P_PPI0_FS1 P_UNDEF
+#endif
+
+#ifndef P_PPI0_FS2
+#define P_PPI0_FS2 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D16
+#define P_PPI0_D16 P_UNDEF
+#endif
+
+#ifndef P_PPI0_D17
+#define P_PPI0_D17 P_UNDEF
+#endif
+
+#ifndef P_SPI1_SSEL1
+#define P_SPI1_SSEL1 P_UNDEF
+#endif
+
+#ifndef P_SPI1_SSEL2
+#define P_SPI1_SSEL2 P_UNDEF
+#endif
+
+#ifndef P_SPI1_SSEL3
+#define P_SPI1_SSEL3 P_UNDEF
+#endif
+
+#ifndef P_SPI1_SCK
+#define P_SPI1_SCK P_UNDEF
+#endif
+
+#ifndef P_SPI1_MISO
+#define P_SPI1_MISO P_UNDEF
+#endif
+
+#ifndef P_SPI1_MOSI
+#define P_SPI1_MOSI P_UNDEF
+#endif
+
+#ifndef P_SPI1_SS
+#define P_SPI1_SS P_UNDEF
+#endif
+
+#ifndef P_CAN0_TX
+#define P_CAN0_TX P_UNDEF
+#endif
+
+#ifndef P_CAN0_RX
+#define P_CAN0_RX P_UNDEF
+#endif
+
+#ifndef P_CAN1_TX
+#define P_CAN1_TX P_UNDEF
+#endif
+
+#ifndef P_CAN1_RX
+#define P_CAN1_RX P_UNDEF
+#endif
+
+#ifndef P_ATAPI_A0A
+#define P_ATAPI_A0A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_A1A
+#define P_ATAPI_A1A P_UNDEF
+#endif
+
+#ifndef P_ATAPI_A2A
+#define P_ATAPI_A2A P_UNDEF
+#endif
+
+#ifndef P_HOST_CE
+#define P_HOST_CE P_UNDEF
+#endif
+
+#ifndef P_HOST_RD
+#define P_HOST_RD P_UNDEF
+#endif
+
+#ifndef P_HOST_WR
+#define P_HOST_WR P_UNDEF
+#endif
+
+#ifndef P_MTXONB
+#define P_MTXONB P_UNDEF
+#endif
+
+#ifndef P_PPI2_FS2
+#define P_PPI2_FS2 P_UNDEF
+#endif
+
+#ifndef P_PPI2_FS1
+#define P_PPI2_FS1 P_UNDEF
+#endif
+
+#ifndef P_PPI2_CLK
+#define P_PPI2_CLK P_UNDEF
+#endif
+
+#ifndef P_CNT_CZM
+#define P_CNT_CZM P_UNDEF
+#endif
+
+#ifndef P_UART1_TX
+#define P_UART1_TX P_UNDEF
+#endif
+
+#ifndef P_UART1_RX
+#define P_UART1_RX P_UNDEF
+#endif
+
+#ifndef P_ATAPI_RESET
+#define P_ATAPI_RESET P_UNDEF
+#endif
+
+#ifndef P_HOST_ADDR
+#define P_HOST_ADDR P_UNDEF
+#endif
+
+#ifndef P_HOST_ACK
+#define P_HOST_ACK P_UNDEF
+#endif
+
+#ifndef P_MTX
+#define P_MTX P_UNDEF
+#endif
+
+#ifndef P_MRX
+#define P_MRX P_UNDEF
+#endif
+
+#ifndef P_MRXONB
+#define P_MRXONB P_UNDEF
+#endif
+
+#ifndef P_A4
+#define P_A4 P_UNDEF
+#endif
+
+#ifndef P_A5
+#define P_A5 P_UNDEF
+#endif
+
+#ifndef P_A6
+#define P_A6 P_UNDEF
+#endif
+
+#ifndef P_A7
+#define P_A7 P_UNDEF
+#endif
+
+#ifndef P_A8
+#define P_A8 P_UNDEF
+#endif
+
+#ifndef P_A9
+#define P_A9 P_UNDEF
+#endif
+
+#ifndef P_PPI1_FS3
+#define P_PPI1_FS3 P_UNDEF
+#endif
+
+#ifndef P_PPI2_FS3
+#define P_PPI2_FS3 P_UNDEF
+#endif
+
+#ifndef P_TMR8
+#define P_TMR8 P_UNDEF
+#endif
+
+#ifndef P_TMR9
+#define P_TMR9 P_UNDEF
+#endif
+
+#ifndef P_TMR10
+#define P_TMR10 P_UNDEF
+#endif
+#ifndef P_TMR11
+#define P_TMR11 P_UNDEF
+#endif
+
+#ifndef P_DMAR0
+#define P_DMAR0 P_UNDEF
+#endif
+
+#ifndef P_DMAR1
+#define P_DMAR1 P_UNDEF
+#endif
+
+#ifndef P_PPI0_FS3
+#define P_PPI0_FS3 P_UNDEF
+#endif
+
+#ifndef P_CNT_CDG
+#define P_CNT_CDG P_UNDEF
+#endif
+
+#ifndef P_CNT_CUD
+#define P_CNT_CUD P_UNDEF
+#endif
+
+#ifndef P_A10
+#define P_A10 P_UNDEF
+#endif
+
+#ifndef P_A11
+#define P_A11 P_UNDEF
+#endif
+
+#ifndef P_A12
+#define P_A12 P_UNDEF
+#endif
+
+#ifndef P_A13
+#define P_A13 P_UNDEF
+#endif
+
+#ifndef P_A14
+#define P_A14 P_UNDEF
+#endif
+
+#ifndef P_A15
+#define P_A15 P_UNDEF
+#endif
+
+#ifndef P_A16
+#define P_A16 P_UNDEF
+#endif
+
+#ifndef P_A17
+#define P_A17 P_UNDEF
+#endif
+
+#ifndef P_A18
+#define P_A18 P_UNDEF
+#endif
+
+#ifndef P_A19
+#define P_A19 P_UNDEF
+#endif
+
+#ifndef P_A20
+#define P_A20 P_UNDEF
+#endif
+
+#ifndef P_A21
+#define P_A21 P_UNDEF
+#endif
+
+#ifndef P_A22
+#define P_A22 P_UNDEF
+#endif
+
+#ifndef P_A23
+#define P_A23 P_UNDEF
+#endif
+
+#ifndef P_A24
+#define P_A24 P_UNDEF
+#endif
+
+#ifndef P_A25
+#define P_A25 P_UNDEF
+#endif
+
+#ifndef P_NOR_CLK
+#define P_NOR_CLK P_UNDEF
+#endif
+
+#ifndef  P_TMRCLK
+#define  P_TMRCLK P_UNDEF
+#endif
+
+#ifndef P_AMC_ARDY_NOR_WAIT
+#define P_AMC_ARDY_NOR_WAIT P_UNDEF
+#endif
+
+#ifndef P_NAND_CE
+#define P_NAND_CE P_UNDEF
+#endif
+
+#ifndef P_NAND_RB
+#define P_NAND_RB P_UNDEF
+#endif
+
+#ifndef P_ATAPI_DIOR
+#define P_ATAPI_DIOR P_UNDEF
+#endif
+
+#ifndef P_ATAPI_DIOW
+#define P_ATAPI_DIOW P_UNDEF
+#endif
+
+#ifndef P_ATAPI_CS0
+#define P_ATAPI_CS0 P_UNDEF
+#endif
+
+#ifndef P_ATAPI_CS1
+#define P_ATAPI_CS1 P_UNDEF
+#endif
+
+#ifndef P_ATAPI_DMACK
+#define P_ATAPI_DMACK P_UNDEF
+#endif
+
+#ifndef P_ATAPI_DMARQ
+#define P_ATAPI_DMARQ P_UNDEF
+#endif
+
+#ifndef P_ATAPI_INTRQ
+#define P_ATAPI_INTRQ P_UNDEF
+#endif
+
+#ifndef P_ATAPI_IORDY
+#define P_ATAPI_IORDY P_UNDEF
+#endif
+
+#ifndef P_AMC_BR
+#define P_AMC_BR P_UNDEF
+#endif
+
+#ifndef P_AMC_BG
+#define P_AMC_BG P_UNDEF
+#endif
+
+#ifndef P_AMC_BGH
+#define P_AMC_BGH P_UNDEF
+#endif
+
+/* EMAC */
+
+#ifndef P_MII0_ETxD0
+#define P_MII0_ETxD0 P_UNDEF
+#endif
+
+#ifndef P_MII0_ETxD1
+#define P_MII0_ETxD1 P_UNDEF
+#endif
+
+#ifndef P_MII0_ETxD2
+#define P_MII0_ETxD2 P_UNDEF
+#endif
+
+#ifndef P_MII0_ETxD3
+#define P_MII0_ETxD3 P_UNDEF
+#endif
+
+#ifndef P_MII0_ETxEN
+#define P_MII0_ETxEN P_UNDEF
+#endif
+
+#ifndef P_MII0_TxCLK
+#define P_MII0_TxCLK P_UNDEF
+#endif
+
+#ifndef P_MII0_PHYINT
+#define P_MII0_PHYINT P_UNDEF
+#endif
+
+#ifndef P_MII0_COL
+#define P_MII0_COL P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxD0
+#define P_MII0_ERxD0 P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxD1
+#define P_MII0_ERxD1 P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxD2
+#define P_MII0_ERxD2 P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxD3
+#define P_MII0_ERxD3 P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxDV
+#define P_MII0_ERxDV P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxCLK
+#define P_MII0_ERxCLK P_UNDEF
+#endif
+
+#ifndef P_MII0_ERxER
+#define P_MII0_ERxER P_UNDEF
+#endif
+
+#ifndef P_MII0_CRS
+#define P_MII0_CRS P_UNDEF
+#endif
+
+#ifndef P_RMII0_REF_CLK
+#define P_RMII0_REF_CLK P_UNDEF
+#endif
+
+#ifndef P_RMII0_MDINT
+#define P_RMII0_MDINT P_UNDEF
+#endif
+
+#ifndef P_RMII0_CRS_DV
+#define P_RMII0_CRS_DV P_UNDEF
+#endif
+
+#ifndef P_MDC
+#define P_MDC P_UNDEF
+#endif
+
+#ifndef P_MDIO
+#define P_MDIO P_UNDEF
+#endif
+
+#endif				/* _PORTMUX_H_ */
diff --git a/include/asm-blackfin/trace.h b/include/asm-blackfin/trace.h
new file mode 100644
index 0000000..9c2474c
--- /dev/null
+++ b/include/asm-blackfin/trace.h
@@ -0,0 +1,52 @@
+/*
+ * Common header file for blackfin family of processors.
+ *
+ */
+
+#ifndef _BLACKFIN_TRACE_
+#define _BLACKFIN_TRACE_
+
+#ifndef __ASSEMBLY__
+/* Trace Macros for C files */
+
+#define trace_buffer_save(x) \
+        do { \
+                (x) = bfin_read_TBUFCTL(); \
+                bfin_write_TBUFCTL((x) & ~TBUFEN); \
+        } while (0)
+
+#define trace_buffer_restore(x) \
+        do { \
+                bfin_write_TBUFCTL((x));        \
+        } while (0)
+
+#else
+/* Trace Macros for Assembly files */
+
+#define TRACE_BUFFER_START(preg, dreg) trace_buffer_start(preg, dreg)
+#define TRACE_BUFFER_STOP(preg, dreg)  trace_buffer_stop(preg, dreg)
+
+#define trace_buffer_stop(preg, dreg)	\
+	preg.L = LO(TBUFCTL);		\
+	preg.H = HI(TBUFCTL);		\
+	dreg = 0x1;			\
+	[preg] = dreg;
+
+#define trace_buffer_start(preg, dreg) \
+	preg.L = LO(TBUFCTL);		\
+	preg.H = HI(TBUFCTL);		\
+	dreg = 0x13;			\
+	[preg] = dreg;
+
+#ifdef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE
+# define DEBUG_START_HWTRACE(preg, dreg) trace_buffer_start(preg, dreg)
+# define DEBUG_STOP_HWTRACE(preg, dreg) trace_buffer_stop(preg, dreg)
+
+#else
+# define DEBUG_START_HWTRACE(preg, dreg)
+# define DEBUG_STOP_HWTRACE(preg, dreg)
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif				/* _BLACKFIN_TRACE_ */
diff --git a/include/asm-i386/boot.h b/include/asm-i386/boot.h
index bd024ab..ed8affb 100644
--- a/include/asm-i386/boot.h
+++ b/include/asm-i386/boot.h
@@ -1,5 +1,5 @@
-#ifndef _LINUX_BOOT_H
-#define _LINUX_BOOT_H
+#ifndef _ASM_BOOT_H
+#define _ASM_BOOT_H
 
 /* Don't touch these, unless you really know what you're doing. */
 #define DEF_INITSEG	0x9000
@@ -17,4 +17,4 @@
 				+ (CONFIG_PHYSICAL_ALIGN - 1)) \
 				& ~(CONFIG_PHYSICAL_ALIGN - 1))
 
-#endif /* _LINUX_BOOT_H */
+#endif /* _ASM_BOOT_H */
diff --git a/include/asm-i386/bootparam.h b/include/asm-i386/bootparam.h
new file mode 100644
index 0000000..427d865
--- /dev/null
+++ b/include/asm-i386/bootparam.h
@@ -0,0 +1,85 @@
+#ifndef _ASM_BOOTPARAM_H
+#define _ASM_BOOTPARAM_H
+
+#include <linux/types.h>
+#include <linux/screen_info.h>
+#include <linux/apm_bios.h>
+#include <asm/e820.h>
+#include <linux/edd.h>
+#include <video/edid.h>
+
+struct setup_header {
+	u8	setup_sects;
+	u16	root_flags;
+	u32	syssize;
+	u16	ram_size;
+	u16	vid_mode;
+	u16	root_dev;
+	u16	boot_flag;
+	u16	jump;
+	u32	header;
+	u16	version;
+	u32	realmode_swtch;
+	u16	start_sys;
+	u16	kernel_version;
+	u8	type_of_loader;
+	u8	loadflags;
+#define LOADED_HIGH	0x01
+#define CAN_USE_HEAP	0x80
+	u16	setup_move_size;
+	u32	code32_start;
+	u32	ramdisk_image;
+	u32	ramdisk_size;
+	u32	bootsect_kludge;
+	u16	heap_end_ptr;
+	u16	_pad1;
+	u32	cmd_line_ptr;
+	u32	initrd_addr_max;
+	u32	kernel_alignment;
+	u8	relocatable_kernel;
+} __attribute__((packed));
+
+struct sys_desc_table {
+	u16 length;
+	u8  table[14];
+};
+
+struct efi_info {
+	u32 _pad1;
+	u32 efi_systab;
+	u32 efi_memdesc_size;
+	u32 efi_memdec_version;
+	u32 efi_memmap;
+	u32 fi_memmap_size;
+	u32 _pad2[2];
+};
+
+/* The so-called "zeropage" */
+struct boot_params {
+	struct screen_info screen_info;			/* 0x000 */
+	struct apm_bios_info apm_bios_info;		/* 0x040 */
+	u8  _pad2[12];					/* 0x054 */
+	u32 speedstep_info[4];				/* 0x060 */
+	u8  _pad3[16];					/* 0x070 */
+	u8  hd0_info[16];	/* obsolete! */		/* 0x080 */
+	u8  hd1_info[16];	/* obsolete! */		/* 0x090 */
+	struct sys_desc_table sys_desc_table;		/* 0x0a0 */
+	u8  _pad4[144];					/* 0x0b0 */
+	struct edid_info edid_info;			/* 0x140 */
+	struct efi_info efi_info;			/* 0x1c0 */
+	u32 alt_mem_k;					/* 0x1e0 */
+	u32 scratch;		/* Scratch field! */	/* 0x1e4 */
+	u8  e820_entries;				/* 0x1e8 */
+	u8  eddbuf_entries;				/* 0x1e9 */
+	u8  edd_mbr_sig_buf_entries;			/* 0x1ea */
+	u8  _pad6[6];					/* 0x1eb */
+	struct setup_header hdr;    /* setup header */	/* 0x1f1 */
+	u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
+	u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];	/* 0x290 */
+	struct e820entry e820_map[E820MAX];		/* 0x2d0 */
+	u8  _pad8[48];					/* 0xcd0 */
+	struct edd_info eddbuf[EDDMAXNR];		/* 0xd00 */
+	u8  _pad9[276];					/* 0xeec */
+} __attribute__((packed));
+
+#endif /* _ASM_BOOTPARAM_H */
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
index f514e90..c961c03 100644
--- a/include/asm-i386/cpufeature.h
+++ b/include/asm-i386/cpufeature.h
@@ -12,7 +12,7 @@
 #endif
 #include <asm/required-features.h>
 
-#define NCAPINTS	7	/* N 32-bit words worth of info */
+#define NCAPINTS	8	/* N 32-bit words worth of info */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
 #define X86_FEATURE_FPU		(0*32+ 0) /* Onboard FPU */
@@ -81,6 +81,7 @@
 #define X86_FEATURE_BTS		(3*32+13)  /* Branch Trace Store */
 #define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */
 #define X86_FEATURE_SYNC_RDTSC	(3*32+15)  /* RDTSC synchronizes the CPU */
+#define X86_FEATURE_REP_GOOD   (3*32+16) /* rep microcode works well on this CPU */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
@@ -108,11 +109,24 @@
 #define X86_FEATURE_LAHF_LM	(6*32+ 0) /* LAHF/SAHF in long mode */
 #define X86_FEATURE_CMP_LEGACY	(6*32+ 1) /* If yes HyperThreading not valid */
 
-#define cpu_has(c, bit)					\
-	((__builtin_constant_p(bit) && (bit) < 32 && 	\
-		(1UL << (bit)) & REQUIRED_MASK1) ?	\
-		1 : 					\
-	test_bit(bit, (c)->x86_capability))
+/*
+ * Auxiliary flags: Linux defined - For features scattered in various
+ * CPUID levels like 0x6, 0xA etc
+ */
+#define X86_FEATURE_IDA		(7*32+ 0) /* Intel Dynamic Acceleration */
+
+#define cpu_has(c, bit)							\
+	(__builtin_constant_p(bit) &&					\
+	 ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) ||	\
+	   (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) ||	\
+	   (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) ||	\
+	   (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) ||	\
+	   (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) ||	\
+	   (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) ||	\
+	   (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) ||	\
+	   (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) )	\
+	  ? 1 :								\
+	  test_bit(bit, (c)->x86_capability))
 #define boot_cpu_has(bit)	cpu_has(&boot_cpu_data, bit)
 
 #define cpu_has_fpu		boot_cpu_has(X86_FEATURE_FPU)
diff --git a/include/asm-i386/e820.h b/include/asm-i386/e820.h
index 096a2a8..c03290c 100644
--- a/include/asm-i386/e820.h
+++ b/include/asm-i386/e820.h
@@ -25,13 +25,15 @@
 
 #ifndef __ASSEMBLY__
 
+struct e820entry {
+	u64 addr;	/* start of memory segment */
+	u64 size;	/* size of memory segment */
+	u32 type;	/* type of memory segment */
+} __attribute__((packed));
+
 struct e820map {
-    int nr_map;
-    struct e820entry {
-	unsigned long long addr;	/* start of memory segment */
-	unsigned long long size;	/* size of memory segment */
-	unsigned long type;		/* type of memory segment */
-    } map[E820MAX];
+	u32 nr_map;
+	struct e820entry map[E820MAX];
 };
 
 extern struct e820map e820;
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 338668b..94e0c14 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -119,6 +119,7 @@
 extern void identify_boot_cpu(void);
 extern void identify_secondary_cpu(struct cpuinfo_x86 *);
 extern void print_cpu_info(struct cpuinfo_x86 *);
+extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern unsigned short num_cache_leaves;
 
diff --git a/include/asm-i386/required-features.h b/include/asm-i386/required-features.h
index 9db866c..65848a0 100644
--- a/include/asm-i386/required-features.h
+++ b/include/asm-i386/required-features.h
@@ -3,32 +3,53 @@
 
 /* Define minimum CPUID feature set for kernel These bits are checked
    really early to actually display a visible error message before the
-   kernel dies.  Only add word 0 bits here
+   kernel dies.  Make sure to assign features to the proper mask!
 
    Some requirements that are not in CPUID yet are also in the
-   CONFIG_X86_MINIMUM_CPU mode which is checked too.
+   CONFIG_X86_MINIMUM_CPU_FAMILY which is checked too.
 
    The real information is in arch/i386/Kconfig.cpu, this just converts
    the CONFIGs into a bitmask */
 
-#ifdef CONFIG_X86_PAE
-#define NEED_PAE	(1<<X86_FEATURE_PAE)
+#ifndef CONFIG_MATH_EMULATION
+# define NEED_FPU	(1<<(X86_FEATURE_FPU & 31))
 #else
-#define NEED_PAE	0
+# define NEED_FPU	0
+#endif
+
+#ifdef CONFIG_X86_PAE
+# define NEED_PAE	(1<<(X86_FEATURE_PAE & 31))
+#else
+# define NEED_PAE	0
 #endif
 
 #ifdef CONFIG_X86_CMOV
-#define NEED_CMOV	(1<<X86_FEATURE_CMOV)
+# define NEED_CMOV	(1<<(X86_FEATURE_CMOV & 31))
 #else
-#define NEED_CMOV	0
+# define NEED_CMOV	0
 #endif
 
 #ifdef CONFIG_X86_CMPXCHG64
-#define NEED_CMPXCHG64  (1<<X86_FEATURE_CX8)
+# define NEED_CX8	(1<<(X86_FEATURE_CX8 & 31))
 #else
-#define NEED_CMPXCHG64  0
+# define NEED_CX8	0
 #endif
 
-#define REQUIRED_MASK1	(NEED_PAE|NEED_CMOV|NEED_CMPXCHG64)
+#define REQUIRED_MASK0	(NEED_FPU|NEED_PAE|NEED_CMOV|NEED_CX8)
+
+#ifdef CONFIG_X86_USE_3DNOW
+# define NEED_3DNOW	(1<<(X86_FEATURE_3DNOW & 31))
+#else
+# define NEED_3DNOW	0
+#endif
+
+#define REQUIRED_MASK1	(NEED_3DNOW)
+
+#define REQUIRED_MASK2	0
+#define REQUIRED_MASK3	0
+#define REQUIRED_MASK4	0
+#define REQUIRED_MASK5	0
+#define REQUIRED_MASK6	0
+#define REQUIRED_MASK7	0
 
 #endif
diff --git a/include/asm-i386/setup.h b/include/asm-i386/setup.h
index 0e8077c..0d5bff9 100644
--- a/include/asm-i386/setup.h
+++ b/include/asm-i386/setup.h
@@ -26,12 +26,15 @@
 #define NEW_CL_POINTER		0x228	/* Relative to real mode data */
 
 #ifndef __ASSEMBLY__
+
+#include <asm/bootparam.h>
+
 /*
  * This is set up by the setup-routine at boot-time
  */
-extern unsigned char boot_params[PARAM_SIZE];
+extern struct boot_params boot_params;
 
-#define PARAM	(boot_params)
+#define PARAM	((char *)&boot_params)
 #define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
 #define EXT_MEM_K (*(unsigned short *) (PARAM+2))
 #define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
@@ -39,8 +42,7 @@
 #define E820_MAP    ((struct e820entry *) (PARAM+E820MAP))
 #define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
 #define IST_INFO   (*(struct ist_info *) (PARAM+0x60))
-#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
-#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
+#define SYS_DESC_TABLE (*(struct sys_desc_table *)(PARAM+0xa0))
 #define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4)))
 #define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8)))
 #define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc)))
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index 12bcc1f..7ba9289 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -212,7 +212,8 @@
 		 */
 		if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) &&
 		    flags == _CACHE_UNCACHED)
-			return (void __iomem *)CKSEG1ADDR(phys_addr);
+			return (void __iomem *)
+				(unsigned long)CKSEG1ADDR(phys_addr);
 	}
 
 	return __ioremap(offset, size, flags);
diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h
index 3ca6a07..97102eb 100644
--- a/include/asm-mips/irq.h
+++ b/include/asm-mips/irq.h
@@ -24,7 +24,7 @@
 #define irq_canonicalize(irq) (irq)	/* Sane hardware, sane code ... */
 #endif
 
-#ifdef CONFIG_MIPS_MT_SMTC
+#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
 /*
  * Clear interrupt mask handling "backstop" if irq_hwmask
  * entry so indicates. This implies that the ack() or end()
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 706b369..18f47f1 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -707,10 +707,10 @@
  */
 #define __read_64bit_c0_split(source, sel)				\
 ({									\
-	unsigned long long val;						\
-	unsigned long flags;						\
+	unsigned long long __val;					\
+	unsigned long __flags;						\
 									\
-	local_irq_save(flags);						\
+	local_irq_save(__flags);					\
 	if (sel == 0)							\
 		__asm__ __volatile__(					\
 			".set\tmips64\n\t"				\
@@ -719,7 +719,7 @@
 			"dsrl\t%M0, %M0, 32\n\t"			\
 			"dsrl\t%L0, %L0, 32\n\t"			\
 			".set\tmips0"					\
-			: "=r" (val));					\
+			: "=r" (__val));				\
 	else								\
 		__asm__ __volatile__(					\
 			".set\tmips64\n\t"				\
@@ -728,17 +728,17 @@
 			"dsrl\t%M0, %M0, 32\n\t"			\
 			"dsrl\t%L0, %L0, 32\n\t"			\
 			".set\tmips0"					\
-			: "=r" (val));					\
-	local_irq_restore(flags);					\
+			: "=r" (__val));				\
+	local_irq_restore(__flags);					\
 									\
-	val;								\
+	__val;								\
 })
 
 #define __write_64bit_c0_split(source, sel, val)			\
 do {									\
-	unsigned long flags;						\
+	unsigned long __flags;						\
 									\
-	local_irq_save(flags);						\
+	local_irq_save(__flags);					\
 	if (sel == 0)							\
 		__asm__ __volatile__(					\
 			".set\tmips64\n\t"				\
@@ -759,7 +759,7 @@
 			"dmtc0\t%L0, " #source ", " #sel "\n\t"		\
 			".set\tmips0"					\
 			: : "r" (val));					\
-	local_irq_restore(flags);					\
+	local_irq_restore(__flags);					\
 } while (0)
 
 #define read_c0_index()		__read_32bit_c0_register($0, 0)
diff --git a/include/asm-mips/rtc.h b/include/asm-mips/rtc.h
deleted file mode 100644
index 82ad401..0000000
--- a/include/asm-mips/rtc.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * include/asm-mips/rtc.h
- *
- * (Really an interface for drivers/char/genrtc.c)
- *
- * Copyright (C) 2004 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- *
- * Please read the COPYING file for all license details.
- */
-
-#ifndef _MIPS_RTC_H
-#define _MIPS_RTC_H
-
-#ifdef __KERNEL__
-
-#include <linux/rtc.h>
-#include <asm/time.h>
-
-#define RTC_PIE 0x40            /* periodic interrupt enable */
-#define RTC_AIE 0x20            /* alarm interrupt enable */
-#define RTC_UIE 0x10            /* update-finished interrupt enable */
-
-/* some dummy definitions */
-#define RTC_BATT_BAD 0x100      /* battery bad */
-#define RTC_SQWE 0x08           /* enable square-wave output */
-#define RTC_DM_BINARY 0x04      /* all time/date values are BCD if clear */
-#define RTC_24H 0x02            /* 24 hour mode - else hours bit 7 means pm */
-#define RTC_DST_EN 0x01         /* auto switch DST - works f. USA only */
-
-static inline unsigned int get_rtc_time(struct rtc_time *time)
-{
-	unsigned long nowtime;
-
-	nowtime = rtc_mips_get_time();
-	to_tm(nowtime, time);
-	time->tm_year -= 1900;
-
-	return RTC_24H;
-}
-
-static inline int set_rtc_time(struct rtc_time *time)
-{
-	unsigned long nowtime;
-	int ret;
-
-	nowtime = mktime(time->tm_year+1900, time->tm_mon+1,
-			time->tm_mday, time->tm_hour, time->tm_min,
-			time->tm_sec);
-	ret = rtc_mips_set_time(nowtime);
-
-	return ret;
-}
-
-static inline unsigned int get_rtc_ss(void)
-{
-	struct rtc_time h;
-
-	get_rtc_time(&h);
-	return h.tm_sec;
-}
-
-static inline int get_rtc_pll(struct rtc_pll_info *pll)
-{
-	return -EINVAL;
-}
-
-static inline int set_rtc_pll(struct rtc_pll_info *pll)
-{
-	return -EINVAL;
-}
-#endif
-#endif
diff --git a/include/asm-mips/tlbdebug.h b/include/asm-mips/tlbdebug.h
index fff7a73..bb8f5c2 100644
--- a/include/asm-mips/tlbdebug.h
+++ b/include/asm-mips/tlbdebug.h
@@ -11,10 +11,6 @@
 /*
  * TLB debugging functions:
  */
-extern void dump_tlb(int first, int last);
 extern void dump_tlb_all(void);
-extern void dump_tlb_wired(void);
-extern void dump_tlb_addr(unsigned long addr);
-extern void dump_tlb_nonwired(void);
 
 #endif /* __ASM_TLBDEBUG_H */
diff --git a/include/asm-mips/vr41xx/giu.h b/include/asm-mips/vr41xx/giu.h
index 8109cda..0bcdd3a 100644
--- a/include/asm-mips/vr41xx/giu.h
+++ b/include/asm-mips/vr41xx/giu.h
@@ -20,6 +20,15 @@
 #ifndef __NEC_VR41XX_GIU_H
 #define __NEC_VR41XX_GIU_H
 
+/*
+ * NEC VR4100 series GIU platform device IDs.
+ */
+enum {
+	GPIO_50PINS_PULLUPDOWN,
+	GPIO_36PINS,
+	GPIO_48PINS_EDGE_SELECT,
+};
+
 typedef enum {
 	IRQ_TRIGGER_LEVEL,
 	IRQ_TRIGGER_EDGE,
diff --git a/include/asm-mips/vr41xx/siu.h b/include/asm-mips/vr41xx/siu.h
index 1fcf6e8..98cdb40 100644
--- a/include/asm-mips/vr41xx/siu.h
+++ b/include/asm-mips/vr41xx/siu.h
@@ -20,6 +20,8 @@
 #ifndef __NEC_VR41XX_SIU_H
 #define __NEC_VR41XX_SIU_H
 
+#define SIU_PORTS_MAX 2
+
 typedef enum {
 	SIU_INTERFACE_RS232C,
 	SIU_INTERFACE_IRDA,
diff --git a/include/asm-x86_64/alternative.h b/include/asm-x86_64/alternative.h
index a094276..eea7aec 100644
--- a/include/asm-x86_64/alternative.h
+++ b/include/asm-x86_64/alternative.h
@@ -5,6 +5,41 @@
 
 #include <linux/types.h>
 #include <linux/stddef.h>
+
+/*
+ * Alternative inline assembly for SMP.
+ *
+ * The LOCK_PREFIX macro defined here replaces the LOCK and
+ * LOCK_PREFIX macros used everywhere in the source tree.
+ *
+ * SMP alternatives use the same data structures as the other
+ * alternatives and the X86_FEATURE_UP flag to indicate the case of a
+ * UP system running a SMP kernel.  The existing apply_alternatives()
+ * works fine for patching a SMP kernel for UP.
+ *
+ * The SMP alternative tables can be kept after boot and contain both
+ * UP and SMP versions of the instructions to allow switching back to
+ * SMP at runtime, when hotplugging in a new CPU, which is especially
+ * useful in virtualized environments.
+ *
+ * The very common lock prefix is handled as special case in a
+ * separate table which is a pure address list without replacement ptr
+ * and size information.  That keeps the table sizes small.
+ */
+
+#ifdef CONFIG_SMP
+#define LOCK_PREFIX \
+		".section .smp_locks,\"a\"\n"	\
+		"  .align 8\n"			\
+		"  .quad 661f\n" /* address */	\
+		".previous\n"			\
+	       	"661:\n\tlock; "
+
+#else /* ! CONFIG_SMP */
+#define LOCK_PREFIX ""
+#endif
+
+/* This must be included *after* the definition of LOCK_PREFIX */
 #include <asm/cpufeature.h>
 
 struct alt_instr {
@@ -108,39 +143,6 @@
  */
 #define ASM_OUTPUT2(a, b) a, b
 
-/*
- * Alternative inline assembly for SMP.
- *
- * The LOCK_PREFIX macro defined here replaces the LOCK and
- * LOCK_PREFIX macros used everywhere in the source tree.
- *
- * SMP alternatives use the same data structures as the other
- * alternatives and the X86_FEATURE_UP flag to indicate the case of a
- * UP system running a SMP kernel.  The existing apply_alternatives()
- * works fine for patching a SMP kernel for UP.
- *
- * The SMP alternative tables can be kept after boot and contain both
- * UP and SMP versions of the instructions to allow switching back to
- * SMP at runtime, when hotplugging in a new CPU, which is especially
- * useful in virtualized environments.
- *
- * The very common lock prefix is handled as special case in a
- * separate table which is a pure address list without replacement ptr
- * and size information.  That keeps the table sizes small.
- */
-
-#ifdef CONFIG_SMP
-#define LOCK_PREFIX \
-		".section .smp_locks,\"a\"\n"	\
-		"  .align 8\n"			\
-		"  .quad 661f\n" /* address */	\
-		".previous\n"			\
-	       	"661:\n\tlock; "
-
-#else /* ! CONFIG_SMP */
-#define LOCK_PREFIX ""
-#endif
-
 struct paravirt_patch;
 #ifdef CONFIG_PARAVIRT
 void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end);
diff --git a/include/asm-x86_64/boot.h b/include/asm-x86_64/boot.h
index 96b228e..3c46cea 100644
--- a/include/asm-x86_64/boot.h
+++ b/include/asm-x86_64/boot.h
@@ -1,15 +1 @@
-#ifndef _LINUX_BOOT_H
-#define _LINUX_BOOT_H
-
-/* Don't touch these, unless you really know what you're doing. */
-#define DEF_INITSEG	0x9000
-#define DEF_SYSSEG	0x1000
-#define DEF_SETUPSEG	0x9020
-#define DEF_SYSSIZE	0x7F00
-
-/* Internal svga startup constants */
-#define NORMAL_VGA	0xffff		/* 80x25 mode */
-#define EXTENDED_VGA	0xfffe		/* 80x50 mode */
-#define ASK_VGA		0xfffd		/* ask for it at bootup */
-
-#endif
+#include <asm-i386/boot.h>
diff --git a/include/asm-x86_64/bootparam.h b/include/asm-x86_64/bootparam.h
new file mode 100644
index 0000000..aa82e52
--- /dev/null
+++ b/include/asm-x86_64/bootparam.h
@@ -0,0 +1 @@
+#include <asm-i386/bootparam.h>
diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h
index 0b3c686..8baefc3 100644
--- a/include/asm-x86_64/cpufeature.h
+++ b/include/asm-x86_64/cpufeature.h
@@ -7,115 +7,24 @@
 #ifndef __ASM_X8664_CPUFEATURE_H
 #define __ASM_X8664_CPUFEATURE_H
 
-#define NCAPINTS	7	/* N 32-bit words worth of info */
+#include <asm-i386/cpufeature.h>
 
-/* Intel-defined CPU features, CPUID level 0x00000001, word 0 */
-#define X86_FEATURE_FPU		(0*32+ 0) /* Onboard FPU */
-#define X86_FEATURE_VME		(0*32+ 1) /* Virtual Mode Extensions */
-#define X86_FEATURE_DE		(0*32+ 2) /* Debugging Extensions */
-#define X86_FEATURE_PSE 	(0*32+ 3) /* Page Size Extensions */
-#define X86_FEATURE_TSC		(0*32+ 4) /* Time Stamp Counter */
-#define X86_FEATURE_MSR		(0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
-#define X86_FEATURE_PAE		(0*32+ 6) /* Physical Address Extensions */
-#define X86_FEATURE_MCE		(0*32+ 7) /* Machine Check Architecture */
-#define X86_FEATURE_CX8		(0*32+ 8) /* CMPXCHG8 instruction */
-#define X86_FEATURE_APIC	(0*32+ 9) /* Onboard APIC */
-#define X86_FEATURE_SEP		(0*32+11) /* SYSENTER/SYSEXIT */
-#define X86_FEATURE_MTRR	(0*32+12) /* Memory Type Range Registers */
-#define X86_FEATURE_PGE		(0*32+13) /* Page Global Enable */
-#define X86_FEATURE_MCA		(0*32+14) /* Machine Check Architecture */
-#define X86_FEATURE_CMOV	(0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
-#define X86_FEATURE_PAT		(0*32+16) /* Page Attribute Table */
-#define X86_FEATURE_PSE36	(0*32+17) /* 36-bit PSEs */
-#define X86_FEATURE_PN		(0*32+18) /* Processor serial number */
-#define X86_FEATURE_CLFLSH	(0*32+19) /* Supports the CLFLUSH instruction */
-#define X86_FEATURE_DS		(0*32+21) /* Debug Store */
-#define X86_FEATURE_ACPI	(0*32+22) /* ACPI via MSR */
-#define X86_FEATURE_MMX		(0*32+23) /* Multimedia Extensions */
-#define X86_FEATURE_FXSR	(0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
-				          /* of FPU context), and CR4.OSFXSR available */
-#define X86_FEATURE_XMM		(0*32+25) /* Streaming SIMD Extensions */
-#define X86_FEATURE_XMM2	(0*32+26) /* Streaming SIMD Extensions-2 */
-#define X86_FEATURE_SELFSNOOP	(0*32+27) /* CPU self snoop */
-#define X86_FEATURE_HT		(0*32+28) /* Hyper-Threading */
-#define X86_FEATURE_ACC		(0*32+29) /* Automatic clock control */
-#define X86_FEATURE_IA64	(0*32+30) /* IA-64 processor */
-
-/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
-/* Don't duplicate feature flags which are redundant with Intel! */
-#define X86_FEATURE_SYSCALL	(1*32+11) /* SYSCALL/SYSRET */
-#define X86_FEATURE_MMXEXT	(1*32+22) /* AMD MMX extensions */
-#define X86_FEATURE_FXSR_OPT	(1*32+25) /* FXSR optimizations */
-#define X86_FEATURE_RDTSCP	(1*32+27) /* RDTSCP */
-#define X86_FEATURE_LM		(1*32+29) /* Long Mode (x86-64) */
-#define X86_FEATURE_3DNOWEXT	(1*32+30) /* AMD 3DNow! extensions */
-#define X86_FEATURE_3DNOW	(1*32+31) /* 3DNow! */
-
-/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
-#define X86_FEATURE_RECOVERY	(2*32+ 0) /* CPU in recovery mode */
-#define X86_FEATURE_LONGRUN	(2*32+ 1) /* Longrun power control */
-#define X86_FEATURE_LRTI	(2*32+ 3) /* LongRun table interface */
-
-/* Other features, Linux-defined mapping, word 3 */
-/* This range is used for feature bits which conflict or are synthesized */
-#define X86_FEATURE_CXMMX	(3*32+ 0) /* Cyrix MMX extensions */
-#define X86_FEATURE_K6_MTRR	(3*32+ 1) /* AMD K6 nonstandard MTRRs */
-#define X86_FEATURE_CYRIX_ARR	(3*32+ 2) /* Cyrix ARRs (= MTRRs) */
-#define X86_FEATURE_CENTAUR_MCR	(3*32+ 3) /* Centaur MCRs (= MTRRs) */
-#define X86_FEATURE_REP_GOOD	(3*32+ 4) /* rep microcode works well on this CPU */
-#define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
-#define X86_FEATURE_SYNC_RDTSC  (3*32+6)  /* RDTSC syncs CPU core */
-#define X86_FEATURE_FXSAVE_LEAK (3*32+7)  /* FIP/FOP/FDP leaks through FXSAVE */
-#define X86_FEATURE_UP		(3*32+8) /* SMP kernel running on UP */
-#define X86_FEATURE_ARCH_PERFMON (3*32+9) /* Intel Architectural PerfMon */
-#define X86_FEATURE_PEBS	(3*32+10) /* Precise-Event Based Sampling */
-#define X86_FEATURE_BTS		(3*32+11) /* Branch Trace Store */
-
-/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
-#define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
-#define X86_FEATURE_MWAIT	(4*32+ 3) /* Monitor/Mwait support */
-#define X86_FEATURE_DSCPL	(4*32+ 4) /* CPL Qualified Debug Store */
-#define X86_FEATURE_EST		(4*32+ 7) /* Enhanced SpeedStep */
-#define X86_FEATURE_TM2		(4*32+ 8) /* Thermal Monitor 2 */
-#define X86_FEATURE_CID		(4*32+10) /* Context ID */
-#define X86_FEATURE_CX16	(4*32+13) /* CMPXCHG16B */
-#define X86_FEATURE_XTPR	(4*32+14) /* Send Task Priority Messages */
-
-/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
-#define X86_FEATURE_XSTORE	(5*32+ 2) /* on-CPU RNG present (xstore insn) */
-#define X86_FEATURE_XSTORE_EN	(5*32+ 3) /* on-CPU RNG enabled */
-#define X86_FEATURE_XCRYPT	(5*32+ 6) /* on-CPU crypto (xcrypt insn) */
-#define X86_FEATURE_XCRYPT_EN	(5*32+ 7) /* on-CPU crypto enabled */
-
-/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
-#define X86_FEATURE_LAHF_LM	(6*32+ 0) /* LAHF/SAHF in long mode */
-#define X86_FEATURE_CMP_LEGACY	(6*32+ 1) /* If yes HyperThreading not valid */
-
-#define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
-#define boot_cpu_has(bit)      test_bit(bit, boot_cpu_data.x86_capability)
-
-#define cpu_has_fpu            1
+#undef  cpu_has_vme
 #define cpu_has_vme            0
-#define cpu_has_de             1
-#define cpu_has_pse            1
-#define cpu_has_tsc            1
+
+#undef  cpu_has_pae
 #define cpu_has_pae            ___BUG___
-#define cpu_has_pge            1
-#define cpu_has_apic           boot_cpu_has(X86_FEATURE_APIC)
-#define cpu_has_mtrr           1
-#define cpu_has_mmx            1
-#define cpu_has_fxsr           1
-#define cpu_has_xmm            1
-#define cpu_has_xmm2           1
-#define cpu_has_xmm3           boot_cpu_has(X86_FEATURE_XMM3)
-#define cpu_has_ht             boot_cpu_has(X86_FEATURE_HT)
+
+#undef  cpu_has_mp
 #define cpu_has_mp             1 /* XXX */
+
+#undef  cpu_has_k6_mtrr
 #define cpu_has_k6_mtrr        0
+
+#undef  cpu_has_cyrix_arr
 #define cpu_has_cyrix_arr      0
+
+#undef  cpu_has_centaur_mcr
 #define cpu_has_centaur_mcr    0
-#define cpu_has_clflush	       boot_cpu_has(X86_FEATURE_CLFLSH)
-#define cpu_has_ds 	       boot_cpu_has(X86_FEATURE_DS)
-#define cpu_has_pebs 	       boot_cpu_has(X86_FEATURE_PEBS)
-#define cpu_has_bts 	       boot_cpu_has(X86_FEATURE_BTS)
 
 #endif /* __ASM_X8664_CPUFEATURE_H */
diff --git a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h
index 6216fa3..3486e70 100644
--- a/include/asm-x86_64/e820.h
+++ b/include/asm-x86_64/e820.h
@@ -11,8 +11,6 @@
 #ifndef __E820_HEADER
 #define __E820_HEADER
 
-#include <linux/mmzone.h>
-
 #define E820MAP	0x2d0		/* our map */
 #define E820MAX	128		/* number of entries in E820MAP */
 #define E820NR	0x1e8		/* # entries in E820MAP */
@@ -30,7 +28,7 @@
 } __attribute__((packed));
 
 struct e820map {
-    int nr_map;
+	u32 nr_map;
 	struct e820entry map[E820MAX];
 };
 
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index 461ffe4..efc87a5 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -100,6 +100,7 @@
 
 extern void identify_cpu(struct cpuinfo_x86 *);
 extern void print_cpu_info(struct cpuinfo_x86 *);
+extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern unsigned short num_cache_leaves;
 
@@ -368,8 +369,6 @@
 	asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
 } 
 
-#define cpu_has_fpu 1
-
 #define ARCH_HAS_PREFETCH
 static inline void prefetch(void *x) 
 { 
diff --git a/include/asm-x86_64/required-features.h b/include/asm-x86_64/required-features.h
new file mode 100644
index 0000000..e80d576
--- /dev/null
+++ b/include/asm-x86_64/required-features.h
@@ -0,0 +1,46 @@
+#ifndef _ASM_REQUIRED_FEATURES_H
+#define _ASM_REQUIRED_FEATURES_H 1
+
+/* Define minimum CPUID feature set for kernel These bits are checked
+   really early to actually display a visible error message before the
+   kernel dies.  Make sure to assign features to the proper mask!
+
+   The real information is in arch/x86_64/Kconfig.cpu, this just converts
+   the CONFIGs into a bitmask */
+
+/* x86-64 baseline features */
+#define NEED_FPU	(1<<(X86_FEATURE_FPU & 31))
+#define NEED_PSE	(1<<(X86_FEATURE_PSE & 31))
+#define NEED_MSR	(1<<(X86_FEATURE_MSR & 31))
+#define NEED_PAE	(1<<(X86_FEATURE_PAE & 31))
+#define NEED_CX8	(1<<(X86_FEATURE_CX8 & 31))
+#define NEED_PGE	(1<<(X86_FEATURE_PGE & 31))
+#define NEED_FXSR	(1<<(X86_FEATURE_FXSR & 31))
+#define NEED_CMOV	(1<<(X86_FEATURE_CMOV & 31))
+#define NEED_XMM	(1<<(X86_FEATURE_XMM & 31))
+#define NEED_XMM2	(1<<(X86_FEATURE_XMM2 & 31))
+
+#define REQUIRED_MASK0	(NEED_FPU|NEED_PSE|NEED_MSR|NEED_PAE|\
+			 NEED_CX8|NEED_PGE|NEED_FXSR|NEED_CMOV|\
+			 NEED_XMM|NEED_XMM2)
+#define SSE_MASK	(NEED_XMM|NEED_XMM2)
+
+/* x86-64 baseline features */
+#define NEED_LM		(1<<(X86_FEATURE_LM & 31))
+
+#ifdef CONFIG_X86_USE_3DNOW
+# define NEED_3DNOW	(1<<(X86_FEATURE_3DNOW & 31))
+#else
+# define NEED_3DNOW	0
+#endif
+
+#define REQUIRED_MASK1	(NEED_LM|NEED_3DNOW)
+
+#define REQUIRED_MASK2	0
+#define REQUIRED_MASK3	0
+#define REQUIRED_MASK4	0
+#define REQUIRED_MASK5	0
+#define REQUIRED_MASK6	0
+#define REQUIRED_MASK7	0
+
+#endif
diff --git a/include/asm-x86_64/segment.h b/include/asm-x86_64/segment.h
index adf2bf1..04b8ab2 100644
--- a/include/asm-x86_64/segment.h
+++ b/include/asm-x86_64/segment.h
@@ -3,6 +3,14 @@
 
 #include <asm/cache.h>
 
+/* Simple and small GDT entries for booting only */
+
+#define GDT_ENTRY_BOOT_CS		2
+#define __BOOT_CS	(GDT_ENTRY_BOOT_CS * 8)
+
+#define GDT_ENTRY_BOOT_DS		(GDT_ENTRY_BOOT_CS + 1)
+#define __BOOT_DS	(GDT_ENTRY_BOOT_DS * 8)
+
 #define __KERNEL_CS	0x10
 #define __KERNEL_DS	0x18
 
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index afae306..127d2d1 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -91,7 +91,6 @@
 header-y += in_route.h
 header-y += ioctl.h
 header-y += ipmi_msgdefs.h
-header-y += ip_mp_alg.h
 header-y += ipsec.h
 header-y += ipx.h
 header-y += irda.h
@@ -226,6 +225,7 @@
 unifdef-y += if_frad.h
 unifdef-y += if_ltalk.h
 unifdef-y += if_link.h
+unifdef-y += if_pppol2tp.h
 unifdef-y += if_pppox.h
 unifdef-y += if_shaper.h
 unifdef-y += if_tr.h
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 407dc7e..b5a2016 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -164,6 +164,8 @@
 	ATA_CMD_SET_MAX		= 0xF9,
 	ATA_CMD_SET_MAX_EXT	= 0x37,
 	ATA_CMD_READ_LOG_EXT	= 0x2f,
+	ATA_CMD_PMP_READ	= 0xE4,
+	ATA_CMD_PMP_WRITE	= 0xE8,
 
 	/* READ_LOG_EXT pages */
 	ATA_LOG_SATA_NCQ	= 0x10,
@@ -212,6 +214,28 @@
 						   0=to device, 1=to host */
 	ATAPI_CDB_LEN		= 16,
 
+	/* PMP stuff */
+	SATA_PMP_MAX_PORTS	= 15,
+	SATA_PMP_CTRL_PORT	= 15,
+
+	SATA_PMP_GSCR_DWORDS	= 128,
+	SATA_PMP_GSCR_PROD_ID	= 0,
+	SATA_PMP_GSCR_REV	= 1,
+	SATA_PMP_GSCR_PORT_INFO	= 2,
+	SATA_PMP_GSCR_ERROR	= 32,
+	SATA_PMP_GSCR_ERROR_EN	= 33,
+	SATA_PMP_GSCR_FEAT	= 64,
+	SATA_PMP_GSCR_FEAT_EN	= 96,
+
+	SATA_PMP_PSCR_STATUS	= 0,
+	SATA_PMP_PSCR_ERROR	= 1,
+	SATA_PMP_PSCR_CONTROL	= 2,
+
+	SATA_PMP_FEAT_BIST	= (1 << 0),
+	SATA_PMP_FEAT_PMREQ	= (1 << 1),
+	SATA_PMP_FEAT_DYNSSC	= (1 << 2),
+	SATA_PMP_FEAT_NOTIFY	= (1 << 3),
+
 	/* cable types */
 	ATA_CBL_NONE		= 0,
 	ATA_CBL_PATA40		= 1,
@@ -418,4 +442,9 @@
 	return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536);
 }
 
+#define sata_pmp_gscr_vendor(gscr)	((gscr)[SATA_PMP_GSCR_PROD_ID] & 0xffff)
+#define sata_pmp_gscr_devid(gscr)	((gscr)[SATA_PMP_GSCR_PROD_ID] >> 16)
+#define sata_pmp_gscr_rev(gscr)		(((gscr)[SATA_PMP_GSCR_REV] >> 8) & 0xff)
+#define sata_pmp_gscr_ports(gscr)	((gscr)[SATA_PMP_GSCR_PORT_INFO] & 0xf)
+
 #endif /* __LINUX_ATA_H__ */
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index 5a9c495..104e51e 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -38,6 +38,9 @@
 
 void debugfs_remove(struct dentry *dentry);
 
+struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+                struct dentry *new_dir, const char *new_name);
+
 struct dentry *debugfs_create_u8(const char *name, mode_t mode,
 				 struct dentry *parent, u8 *value);
 struct dentry *debugfs_create_u16(const char *name, mode_t mode,
@@ -85,6 +88,12 @@
 static inline void debugfs_remove(struct dentry *dentry)
 { }
 
+static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+                struct dentry *new_dir, char *new_name)
+{
+	return ERR_PTR(-ENODEV);
+}
+
 static inline struct dentry *debugfs_create_u8(const char *name, mode_t mode,
 					       struct dentry *parent,
 					       u8 *value)
diff --git a/include/linux/device.h b/include/linux/device.h
index 2e1a298..be2debe 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -238,7 +238,6 @@
  * @devt: for internal use by the driver core only.
  * @node: for internal use by the driver core only.
  * @kobj: for internal use by the driver core only.
- * @devt_attr: for internal use by the driver core only.
  * @groups: optional additional groups to be created
  * @dev: if set, a symlink to the struct device is created in the sysfs
  * directory for this struct class device.
@@ -263,8 +262,6 @@
 	struct kobject		kobj;
 	struct class		* class;	/* required */
 	dev_t			devt;		/* dev_t, creates the sysfs "dev" */
-	struct class_device_attribute *devt_attr;
-	struct class_device_attribute uevent_attr;
 	struct device		* dev;		/* not necessary, but nice to have */
 	void			* class_data;	/* class-specific data */
 	struct class_device	*parent;	/* parent of this child device, if there is one */
@@ -419,8 +416,6 @@
 	struct device_type	*type;
 	unsigned		is_registered:1;
 	unsigned		uevent_suppress:1;
-	struct device_attribute uevent_attr;
-	struct device_attribute *devt_attr;
 
 	struct semaphore	sem;	/* semaphore to synchronize calls to
 					 * its driver.
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index 904bf3d..b8ac7b0 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -12,9 +12,17 @@
 	DMI_PRODUCT_NAME,
 	DMI_PRODUCT_VERSION,
 	DMI_PRODUCT_SERIAL,
+	DMI_PRODUCT_UUID,
 	DMI_BOARD_VENDOR,
 	DMI_BOARD_NAME,
 	DMI_BOARD_VERSION,
+	DMI_BOARD_SERIAL,
+	DMI_BOARD_ASSET_TAG,
+	DMI_CHASSIS_VENDOR,
+	DMI_CHASSIS_TYPE,
+	DMI_CHASSIS_VERSION,
+	DMI_CHASSIS_SERIAL,
+	DMI_CHASSIS_ASSET_TAG,
 	DMI_STRING_MAX,
 };
 
diff --git a/include/linux/edd.h b/include/linux/edd.h
index b2b3e68..7b64782 100644
--- a/include/linux/edd.h
+++ b/include/linux/edd.h
@@ -49,10 +49,6 @@
 #define EDD_MBR_SIG_MAX 16        /* max number of signatures to store */
 #define EDD_MBR_SIG_NR_BUF 0x1ea  /* addr of number of MBR signtaures at EDD_MBR_SIG_BUF
 				     in boot_params - treat this as 1 byte  */
-#define EDD_CL_EQUALS   0x3d646465     /* "edd=" */
-#define EDD_CL_OFF      0x666f         /* "of" for off  */
-#define EDD_CL_SKIP     0x6b73         /* "sk" for skipmbr */
-#define EDD_CL_ON       0x6e6f	       /* "on" for on */
 
 #ifndef __ASSEMBLY__
 
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 071c67a..6cdb973 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -39,13 +39,8 @@
 extern int		eth_header_cache(struct neighbour *neigh,
 					 struct hh_cache *hh);
 
-extern struct net_device *alloc_etherdev(int sizeof_priv);
-static inline void eth_copy_and_sum (struct sk_buff *dest, 
-				     const unsigned char *src, 
-				     int len, int base)
-{
-	memcpy (dest->data, src, len);
-}
+extern struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count);
+#define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1)
 
 /**
  * is_zero_ether_addr - Determine if give Ethernet address is all zeros.
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index cae7d61..2eaba21 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -90,7 +90,7 @@
 				      const u8 *values);
 /* Returns the number of read bytes */
 extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
-					 u8 command, u8 *values);
+					 u8 command, u8 length, u8 *values);
 extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
 					  u8 command, u8 length,
 					  const u8 *values);
@@ -150,15 +150,20 @@
 
 /**
  * struct i2c_client - represent an I2C slave device
+ * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;
+ *	I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking
  * @addr: Address used on the I2C bus connected to the parent adapter.
  * @name: Indicates the type of the device, usually a chip name that's
  *	generic enough to hide second-sourcing and compatible revisions.
+ * @adapter: manages the bus segment hosting this I2C device
  * @dev: Driver model device node for the slave.
+ * @irq: indicates the IRQ generated by this device (if any)
  * @driver_name: Identifies new-style driver used with this device; also
  *	used as the module name for hotplug/coldplug modprobe support.
  *
  * An i2c_client identifies a single device (i.e. chip) connected to an
- * i2c bus. The behaviour is defined by the routines of the driver.
+ * i2c bus. The behaviour exposed to Linux is defined by the driver
+ * managing the device.
  */
 struct i2c_client {
 	unsigned short flags;		/* div., see below		*/
@@ -180,7 +185,8 @@
 
 static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj)
 {
-	return to_i2c_client(container_of(kobj, struct device, kobj));
+	struct device * const dev = container_of(kobj, struct device, kobj);
+	return to_i2c_client(dev);
 }
 
 static inline void *i2c_get_clientdata (struct i2c_client *dev)
@@ -201,7 +207,7 @@
  * @addr: stored in i2c_client.addr
  * @platform_data: stored in i2c_client.dev.platform_data
  * @irq: stored in i2c_client.irq
-
+ *
  * I2C doesn't actually support hardware probing, although controllers and
  * devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's
  * a device at a given address.  Drivers commonly need more information than
@@ -210,7 +216,7 @@
  * i2c_board_info is used to build tables of information listing I2C devices
  * that are present.  This information is used to grow the driver model tree
  * for "new style" I2C drivers.  For mainboards this is done statically using
- * i2c_register_board_info(), where @bus_num represents an adapter that isn't
+ * i2c_register_board_info(); bus numbers identify adapters that aren't
  * yet available.  For add-on boards, i2c_new_device() does this dynamically
  * with the adapter already known.
  */
@@ -518,8 +524,9 @@
 #define I2C_SMBUS_WORD_DATA	    3
 #define I2C_SMBUS_PROC_CALL	    4
 #define I2C_SMBUS_BLOCK_DATA	    5
-#define I2C_SMBUS_I2C_BLOCK_DATA    6
+#define I2C_SMBUS_I2C_BLOCK_BROKEN  6
 #define I2C_SMBUS_BLOCK_PROC_CALL   7		/* SMBus 2.0 */
+#define I2C_SMBUS_I2C_BLOCK_DATA    8
 
 
 /* ----- commands for the ioctl like i2c_command call:
diff --git a/include/linux/idr.h b/include/linux/idr.h
index 8268034..915572f 100644
--- a/include/linux/idr.h
+++ b/include/linux/idr.h
@@ -83,4 +83,33 @@
 void idr_destroy(struct idr *idp);
 void idr_init(struct idr *idp);
 
+
+/*
+ * IDA - IDR based id allocator, use when translation from id to
+ * pointer isn't necessary.
+ */
+#define IDA_CHUNK_SIZE		128	/* 128 bytes per chunk */
+#define IDA_BITMAP_LONGS	(128 / sizeof(long) - 1)
+#define IDA_BITMAP_BITS		(IDA_BITMAP_LONGS * sizeof(long) * 8)
+
+struct ida_bitmap {
+	long			nr_busy;
+	unsigned long		bitmap[IDA_BITMAP_LONGS];
+};
+
+struct ida {
+	struct idr		idr;
+	struct ida_bitmap	*free_bitmap;
+};
+
+#define IDA_INIT(name)		{ .idr = IDR_INIT(name), .free_bitmap = NULL, }
+#define DEFINE_IDA(name)	struct ida name = IDA_INIT(name)
+
+int ida_pre_get(struct ida *ida, gfp_t gfp_mask);
+int ida_get_new_above(struct ida *ida, int starting_id, int *p_id);
+int ida_get_new(struct ida *ida, int *p_id);
+void ida_remove(struct ida *ida, int id);
+void ida_destroy(struct ida *ida);
+void ida_init(struct ida *ida);
+
 #endif /* __IDR_H__ */
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 604c243..422084d 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -76,6 +76,8 @@
 #define IFLA_WEIGHT IFLA_WEIGHT
 	IFLA_OPERSTATE,
 	IFLA_LINKMODE,
+	IFLA_LINKINFO,
+#define IFLA_LINKINFO IFLA_LINKINFO
 	__IFLA_MAX
 };
 
@@ -140,4 +142,49 @@
 	__u32	retrans_time;
 };
 
+enum
+{
+	IFLA_INFO_UNSPEC,
+	IFLA_INFO_KIND,
+	IFLA_INFO_DATA,
+	IFLA_INFO_XSTATS,
+	__IFLA_INFO_MAX,
+};
+
+#define IFLA_INFO_MAX	(__IFLA_INFO_MAX - 1)
+
+/* VLAN section */
+
+enum
+{
+	IFLA_VLAN_UNSPEC,
+	IFLA_VLAN_ID,
+	IFLA_VLAN_FLAGS,
+	IFLA_VLAN_EGRESS_QOS,
+	IFLA_VLAN_INGRESS_QOS,
+	__IFLA_VLAN_MAX,
+};
+
+#define IFLA_VLAN_MAX	(__IFLA_VLAN_MAX - 1)
+
+struct ifla_vlan_flags {
+	__u32	flags;
+	__u32	mask;
+};
+
+enum
+{
+	IFLA_VLAN_QOS_UNSPEC,
+	IFLA_VLAN_QOS_MAPPING,
+	__IFLA_VLAN_QOS_MAX
+};
+
+#define IFLA_VLAN_QOS_MAX	(__IFLA_VLAN_QOS_MAX - 1)
+
+struct ifla_vlan_qos_mapping
+{
+	__u32 from;
+	__u32 to;
+};
+
 #endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/if_ppp.h b/include/linux/if_ppp.h
index 768372f..0f2f70d 100644
--- a/include/linux/if_ppp.h
+++ b/include/linux/if_ppp.h
@@ -110,6 +110,21 @@
 	struct ppp_comp_stats stats;
 };
 
+/* For PPPIOCGL2TPSTATS */
+struct pppol2tp_ioc_stats {
+	__u16		tunnel_id;	/* redundant */
+	__u16		session_id;	/* if zero, get tunnel stats */
+	__u32		using_ipsec:1;	/* valid only for session_id == 0 */
+	aligned_u64	tx_packets;
+	aligned_u64	tx_bytes;
+	aligned_u64	tx_errors;
+	aligned_u64	rx_packets;
+	aligned_u64	rx_bytes;
+	aligned_u64	rx_seq_discards;
+	aligned_u64	rx_oos_packets;
+	aligned_u64	rx_errors;
+};
+
 #define ifr__name       b.ifr_ifrn.ifrn_name
 #define stats_ptr       b.ifr_ifru.ifru_data
 
@@ -146,6 +161,7 @@
 #define PPPIOCDISCONN	_IO('t', 57)		/* disconnect channel */
 #define PPPIOCATTCHAN	_IOW('t', 56, int)	/* attach to ppp channel */
 #define PPPIOCGCHAN	_IOR('t', 55, int)	/* get ppp channel number */
+#define PPPIOCGL2TPSTATS _IOR('t', 54, struct pppol2tp_ioc_stats)
 
 #define SIOCGPPPSTATS   (SIOCDEVPRIVATE + 0)
 #define SIOCGPPPVER     (SIOCDEVPRIVATE + 1)	/* NEVER change this!! */
diff --git a/include/linux/if_pppol2tp.h b/include/linux/if_pppol2tp.h
new file mode 100644
index 0000000..516203b
--- /dev/null
+++ b/include/linux/if_pppol2tp.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * Linux PPP over L2TP (PPPoL2TP) Socket Implementation (RFC 2661)
+ *
+ * This file supplies definitions required by the PPP over L2TP driver
+ * (pppol2tp.c).  All version information wrt this file is located in pppol2tp.c
+ *
+ * License:
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef __LINUX_IF_PPPOL2TP_H
+#define __LINUX_IF_PPPOL2TP_H
+
+#include <asm/types.h>
+
+#ifdef __KERNEL__
+#include <linux/in.h>
+#endif
+
+/* Structure used to connect() the socket to a particular tunnel UDP
+ * socket.
+ */
+struct pppol2tp_addr
+{
+	pid_t	pid;			/* pid that owns the fd.
+					 * 0 => current */
+	int	fd;			/* FD of UDP socket to use */
+
+	struct sockaddr_in addr;	/* IP address and port to send to */
+
+	__be16 s_tunnel, s_session;	/* For matching incoming packets */
+	__be16 d_tunnel, d_session;	/* For sending outgoing packets */
+};
+
+/* Socket options:
+ * DEBUG	- bitmask of debug message categories
+ * SENDSEQ	- 0 => don't send packets with sequence numbers
+ *		  1 => send packets with sequence numbers
+ * RECVSEQ	- 0 => receive packet sequence numbers are optional
+ *		  1 => drop receive packets without sequence numbers
+ * LNSMODE	- 0 => act as LAC.
+ *		  1 => act as LNS.
+ * REORDERTO	- reorder timeout (in millisecs). If 0, don't try to reorder.
+ */
+enum {
+	PPPOL2TP_SO_DEBUG	= 1,
+	PPPOL2TP_SO_RECVSEQ	= 2,
+	PPPOL2TP_SO_SENDSEQ	= 3,
+	PPPOL2TP_SO_LNSMODE	= 4,
+	PPPOL2TP_SO_REORDERTO	= 5,
+};
+
+/* Debug message categories for the DEBUG socket option */
+enum {
+	PPPOL2TP_MSG_DEBUG	= (1 << 0),	/* verbose debug (if
+						 * compiled in) */
+	PPPOL2TP_MSG_CONTROL	= (1 << 1),	/* userspace - kernel
+						 * interface */
+	PPPOL2TP_MSG_SEQ	= (1 << 2),	/* sequence numbers */
+	PPPOL2TP_MSG_DATA	= (1 << 3),	/* data packets */
+};
+
+
+
+#endif
diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h
index 6f987be..2565254 100644
--- a/include/linux/if_pppox.h
+++ b/include/linux/if_pppox.h
@@ -27,6 +27,7 @@
 #include <asm/semaphore.h>
 #include <linux/ppp_channel.h>
 #endif /* __KERNEL__ */
+#include <linux/if_pppol2tp.h>
 
 /* For user-space programs to pick up these definitions
  * which they wouldn't get otherwise without defining __KERNEL__
@@ -50,8 +51,9 @@
  * Protocols supported by AF_PPPOX 
  */ 
 #define PX_PROTO_OE    0 /* Currently just PPPoE */
-#define PX_MAX_PROTO   1	
- 
+#define PX_PROTO_OL2TP 1 /* Now L2TP also */
+#define PX_MAX_PROTO   2
+
 struct sockaddr_pppox { 
        sa_family_t     sa_family;            /* address family, AF_PPPOX */ 
        unsigned int    sa_protocol;          /* protocol identifier */ 
@@ -60,6 +62,16 @@
        }sa_addr; 
 }__attribute__ ((packed)); 
 
+/* The use of the above union isn't viable because the size of this
+ * struct must stay fixed over time -- applications use sizeof(struct
+ * sockaddr_pppox) to fill it. We use a protocol specific sockaddr
+ * type instead.
+ */
+struct sockaddr_pppol2tp {
+	sa_family_t     sa_family;      /* address family, AF_PPPOX */
+	unsigned int    sa_protocol;    /* protocol identifier */
+	struct pppol2tp_addr pppol2tp;
+}__attribute__ ((packed));
 
 /*********************************************************************
  *
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h
index 88aef7b..42eb694 100644
--- a/include/linux/if_tun.h
+++ b/include/linux/if_tun.h
@@ -36,6 +36,7 @@
 	unsigned long 		flags;
 	int			attached;
 	uid_t			owner;
+	gid_t			group;
 
 	wait_queue_head_t	read_wait;
 	struct sk_buff_head	readq;
@@ -78,6 +79,7 @@
 #define TUNSETPERSIST _IOW('T', 203, int) 
 #define TUNSETOWNER   _IOW('T', 204, int)
 #define TUNSETLINK    _IOW('T', 205, int)
+#define TUNSETGROUP   _IOW('T', 206, int)
 
 /* TUNSETIFF ifr flags */
 #define IFF_TUN		0x0001
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 81e9bc9..61a57dc 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -99,7 +99,7 @@
 }
 
 struct vlan_priority_tci_mapping {
-	unsigned long priority;
+	u32 priority;
 	unsigned short vlan_qos; /* This should be shifted when first set, so we only do it
 				  * at provisioning time.
 				  * ((skb->priority << 13) & 0xE000)
@@ -112,7 +112,10 @@
 	/** This will be the mapping that correlates skb->priority to
 	 * 3 bits of VLAN QOS tags...
 	 */
-	unsigned long ingress_priority_map[8];
+	unsigned int nr_ingress_mappings;
+	u32 ingress_priority_map[8];
+
+	unsigned int nr_egress_mappings;
 	struct vlan_priority_tci_mapping *egress_priority_map[16]; /* hash table */
 
 	unsigned short vlan_id;        /*  The VLAN Identifier for this interface. */
@@ -132,6 +135,7 @@
 	int old_allmulti;               /* similar to above. */
 	int old_promiscuity;            /* similar to above. */
 	struct net_device *real_dev;    /* the underlying device/interface */
+	unsigned char real_dev_addr[ETH_ALEN];
 	struct proc_dir_entry *dent;    /* Holds the proc data */
 	unsigned long cnt_inc_headroom_on_tx; /* How many times did we have to grow the skb on TX. */
 	unsigned long cnt_encap_on_xmit;      /* How many times did we have to encapsulate the skb on TX. */
@@ -395,6 +399,10 @@
 	GET_VLAN_VID_CMD /* Get the VID of this VLAN (specified by name) */
 };
 
+enum vlan_flags {
+	VLAN_FLAG_REORDER_HDR	= 0x1,
+};
+
 enum vlan_name_types {
 	VLAN_NAME_TYPE_PLUS_VID, /* Name will look like:  vlan0005 */
 	VLAN_NAME_TYPE_RAW_PLUS_VID, /* name will look like:  eth1.0005 */
diff --git a/include/linux/ip_mp_alg.h b/include/linux/ip_mp_alg.h
deleted file mode 100644
index e234e20..0000000
--- a/include/linux/ip_mp_alg.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* ip_mp_alg.h: IPV4 multipath algorithm support, user-visible values.
- *
- * Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com>
- * Copyright (C) 2005 David S. Miller <davem@davemloft.net>
- */
-
-#ifndef _LINUX_IP_MP_ALG_H
-#define _LINUX_IP_MP_ALG_H
-
-enum ip_mp_alg {
-	IP_MP_ALG_NONE,
-	IP_MP_ALG_RR,
-	IP_MP_ALG_DRR,
-	IP_MP_ALG_RANDOM,
-	IP_MP_ALG_WRANDOM,
-	__IP_MP_ALG_MAX
-};
-
-#define IP_MP_ALG_MAX (__IP_MP_ALG_MAX - 1)
-
-#endif /* _LINUX_IP_MP_ALG_H */
-
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 648bd1f..97983dc9 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -27,8 +27,8 @@
 	int		ifr6_ifindex; 
 };
 
-#define IPV6_SRCRT_STRICT	0x01	/* this hop must be a neighbor	*/
-#define IPV6_SRCRT_TYPE_0	0	/* IPv6 type 0 Routing Header	*/
+#define IPV6_SRCRT_STRICT	0x01	/* Deprecated; will be removed */
+#define IPV6_SRCRT_TYPE_0	0	/* Deprecated; will be removed */
 #define IPV6_SRCRT_TYPE_2	2	/* IPv6 type 2 Routing Header	*/
 
 /*
@@ -247,7 +247,7 @@
 	__u16			lastopt;
 	__u32			nhoff;
 	__u16			flags;
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 	__u16			dsthao;
 #endif
 
@@ -299,8 +299,8 @@
 	/* pktoption flags */
 	union {
 		struct {
-			__u16	srcrt:2,
-				osrcrt:2,
+			__u16	srcrt:1,
+				osrcrt:1,
 			        rxinfo:1,
 			        rxoinfo:1,
 				rxhlim:1,
diff --git a/include/linux/irda.h b/include/linux/irda.h
index 945ba31..8e37357 100644
--- a/include/linux/irda.h
+++ b/include/linux/irda.h
@@ -216,6 +216,34 @@
 #define ifr_dtr       ifr_ifru.ifru_line.dtr
 #define ifr_rts       ifr_ifru.ifru_line.rts
 
+
+/* IrDA netlink definitions */
+#define IRDA_NL_NAME "irda"
+#define IRDA_NL_VERSION 1
+
+enum irda_nl_commands {
+	IRDA_NL_CMD_UNSPEC,
+	IRDA_NL_CMD_SET_MODE,
+	IRDA_NL_CMD_GET_MODE,
+
+	__IRDA_NL_CMD_AFTER_LAST
+};
+#define IRDA_NL_CMD_MAX (__IRDA_NL_CMD_AFTER_LAST - 1)
+
+enum nl80211_attrs {
+	IRDA_NL_ATTR_UNSPEC,
+	IRDA_NL_ATTR_IFNAME,
+	IRDA_NL_ATTR_MODE,
+
+	__IRDA_NL_ATTR_AFTER_LAST
+};
+#define IRDA_NL_ATTR_MAX (__IRDA_NL_ATTR_AFTER_LAST - 1)
+
+/* IrDA modes */
+#define IRDA_MODE_PRIMARY   0x1
+#define IRDA_MODE_SECONDARY 0x2
+#define IRDA_MODE_MONITOR   0x4
+
 #endif /* KERNEL_IRDA_H */
 
 
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index c288e41..06cbf41 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -55,7 +55,7 @@
 	struct kobject		* parent;
 	struct kset		* kset;
 	struct kobj_type	* ktype;
-	struct dentry		* dentry;
+	struct sysfs_dirent	* sd;
 	wait_queue_head_t	poll;
 };
 
@@ -71,13 +71,14 @@
 extern void kobject_cleanup(struct kobject *);
 
 extern int __must_check kobject_add(struct kobject *);
-extern int __must_check kobject_shadow_add(struct kobject *, struct dentry *);
+extern int __must_check kobject_shadow_add(struct kobject *kobj,
+					   struct sysfs_dirent *shadow_parent);
 extern void kobject_del(struct kobject *);
 
 extern int __must_check kobject_rename(struct kobject *, const char *new_name);
 extern int __must_check kobject_shadow_rename(struct kobject *kobj,
-						struct dentry *new_parent,
-						const char *new_name);
+					      struct sysfs_dirent *new_parent,
+					      const char *new_name);
 extern int __must_check kobject_move(struct kobject *, struct kobject *);
 
 extern int __must_check kobject_register(struct kobject *);
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index 2b139f6..dae7143 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -279,6 +279,16 @@
 	return (s64) tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
 }
 
+static inline s64 ktime_us_delta(const ktime_t later, const ktime_t earlier)
+{
+       return ktime_to_us(ktime_sub(later, earlier));
+}
+
+static inline ktime_t ktime_add_us(const ktime_t kt, const u64 usec)
+{
+	return ktime_add_ns(kt, usec * 1000);
+}
+
 /*
  * The resolution of the clocks. The resolution value is returned in
  * the clock_getres() system call to give application programmers an
diff --git a/include/linux/libata.h b/include/linux/libata.h
index a3df646..47cd2a1 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -196,7 +196,6 @@
 	ATA_PFLAG_SCSI_HOTPLUG	= (1 << 6), /* SCSI hotplug scheduled */
 	ATA_PFLAG_INITIALIZING	= (1 << 7), /* being initialized, don't touch */
 
-	ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */
 	ATA_PFLAG_SUSPENDED	= (1 << 17), /* port is suspended (power) */
 	ATA_PFLAG_PM_PENDING	= (1 << 18), /* PM operation pending */
 	ATA_PFLAG_GTM_VALID	= (1 << 19), /* acpi_gtm data valid */
@@ -435,6 +434,7 @@
 	struct ata_port		*ap;
 	unsigned int		devno;		/* 0 or 1 */
 	unsigned long		flags;		/* ATA_DFLAG_xxx */
+	unsigned int		horkage;	/* List of broken features */
 	struct scsi_device	*sdev;		/* attached SCSI device */
 #ifdef CONFIG_ATA_ACPI
 	acpi_handle		acpi_handle;
@@ -466,7 +466,6 @@
 	/* error history */
 	struct ata_ering	ering;
 	int			spdn_cnt;
-	unsigned int		horkage;	/* List of broken features */
 };
 
 /* Offset into struct ata_device.  Fields above it are maintained
@@ -794,7 +793,6 @@
 extern void ata_id_c_string(const u16 *id, unsigned char *s,
 			    unsigned int ofs, unsigned int len);
 extern void ata_id_to_dma_mode(struct ata_device *dev, u8 unknown);
-extern unsigned long ata_device_blacklisted(const struct ata_device *dev);
 extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
 extern void ata_bmdma_start (struct ata_queued_cmd *qc);
 extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
@@ -871,11 +869,11 @@
 	unsigned long		val;
 };
 
-extern int ata_pci_init_native_host(struct ata_host *host);
+extern int ata_pci_init_sff_host(struct ata_host *host);
 extern int ata_pci_init_bmdma(struct ata_host *host);
-extern int ata_pci_prepare_native_host(struct pci_dev *pdev,
-				const struct ata_port_info * const * ppi,
-				struct ata_host **r_host);
+extern int ata_pci_prepare_sff_host(struct pci_dev *pdev,
+				    const struct ata_port_info * const * ppi,
+				    struct ata_host **r_host);
 extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
 extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long);
 #endif /* CONFIG_PCI */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 3a70f55..79cc3da 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -108,6 +108,14 @@
 #define MAX_HEADER (LL_MAX_HEADER + 48)
 #endif
 
+struct net_device_subqueue
+{
+	/* Give a control state for each queue.  This struct may contain
+	 * per-queue locks in the future.
+	 */
+	unsigned long   state;
+};
+
 /*
  *	Network device statistics. Akin to the 2.0 ether stats but
  *	with byte counters.
@@ -177,19 +185,24 @@
 
 DECLARE_PER_CPU(struct netif_rx_stats, netdev_rx_stat);
 
+struct dev_addr_list
+{
+	struct dev_addr_list	*next;
+	u8			da_addr[MAX_ADDR_LEN];
+	u8			da_addrlen;
+	int			da_users;
+	int			da_gusers;
+};
 
 /*
  *	We tag multicasts with these structures.
  */
- 
-struct dev_mc_list
-{	
-	struct dev_mc_list	*next;
-	__u8			dmi_addr[MAX_ADDR_LEN];
-	unsigned char		dmi_addrlen;
-	int			dmi_users;
-	int			dmi_gusers;
-};
+
+#define dev_mc_list	dev_addr_list
+#define dmi_addr	da_addr
+#define dmi_addrlen	da_addrlen
+#define dmi_users	da_users
+#define dmi_gusers	da_gusers
 
 struct hh_cache
 {
@@ -248,6 +261,8 @@
 	__LINK_STATE_LINKWATCH_PENDING,
 	__LINK_STATE_DORMANT,
 	__LINK_STATE_QDISC_RUNNING,
+	/* Set by the netpoll NAPI code */
+	__LINK_STATE_POLL_LIST_FROZEN,
 };
 
 
@@ -314,9 +329,10 @@
 	/* Net device features */
 	unsigned long		features;
 #define NETIF_F_SG		1	/* Scatter/gather IO. */
-#define NETIF_F_IP_CSUM		2	/* Can checksum only TCP/UDP over IPv4. */
+#define NETIF_F_IP_CSUM		2	/* Can checksum TCP/UDP over IPv4. */
 #define NETIF_F_NO_CSUM		4	/* Does not require checksum. F.e. loopack. */
 #define NETIF_F_HW_CSUM		8	/* Can checksum all the packets. */
+#define NETIF_F_IPV6_CSUM	16	/* Can checksum TCP/UDP over IPV6 */
 #define NETIF_F_HIGHDMA		32	/* Can DMA to high memory. */
 #define NETIF_F_FRAGLIST	64	/* Scatter/gather IO. */
 #define NETIF_F_HW_VLAN_TX	128	/* Transmit VLAN hw acceleration */
@@ -325,6 +341,7 @@
 #define NETIF_F_VLAN_CHALLENGED	1024	/* Device cannot handle VLAN packets */
 #define NETIF_F_GSO		2048	/* Enable software GSO. */
 #define NETIF_F_LLTX		4096	/* LockLess TX */
+#define NETIF_F_MULTI_QUEUE	16384	/* Has multiple TX/RX queues */
 
 	/* Segmentation offload features */
 #define NETIF_F_GSO_SHIFT	16
@@ -338,8 +355,11 @@
 	/* List of features with software fallbacks. */
 #define NETIF_F_GSO_SOFTWARE	(NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6)
 
+
 #define NETIF_F_GEN_CSUM	(NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
-#define NETIF_F_ALL_CSUM	(NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
+#define NETIF_F_V4_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)
+#define NETIF_F_V6_CSUM		(NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
+#define NETIF_F_ALL_CSUM	(NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)
 
 	struct net_device	*next_sched;
 
@@ -388,7 +408,10 @@
 	unsigned char		addr_len;	/* hardware address length	*/
 	unsigned short          dev_id;		/* for shared network cards */
 
-	struct dev_mc_list	*mc_list;	/* Multicast mac addresses	*/
+	struct dev_addr_list	*uc_list;	/* Secondary unicast mac addresses */
+	int			uc_count;	/* Number of installed ucasts	*/
+	int			uc_promisc;
+	struct dev_addr_list	*mc_list;	/* Multicast mac addresses	*/
 	int			mc_count;	/* Number of installed mcasts	*/
 	int			promiscuity;
 	int			allmulti;
@@ -493,6 +516,8 @@
 						void *saddr,
 						unsigned len);
 	int			(*rebuild_header)(struct sk_buff *skb);
+#define HAVE_SET_RX_MODE
+	void			(*set_rx_mode)(struct net_device *dev);
 #define HAVE_MULTICAST			 
 	void			(*set_multicast_list)(struct net_device *dev);
 #define HAVE_SET_MAC_ADDR  		 
@@ -540,17 +565,22 @@
 	struct device		dev;
 	/* space for optional statistics and wireless sysfs groups */
 	struct attribute_group  *sysfs_groups[3];
+
+	/* rtnetlink link ops */
+	const struct rtnl_link_ops *rtnl_link_ops;
+
+	/* The TX queue control structures */
+	unsigned int			egress_subqueue_count;
+	struct net_device_subqueue	egress_subqueue[0];
 };
 #define to_net_dev(d) container_of(d, struct net_device, dev)
 
 #define	NETDEV_ALIGN		32
 #define	NETDEV_ALIGN_CONST	(NETDEV_ALIGN - 1)
 
-static inline void *netdev_priv(struct net_device *dev)
+static inline void *netdev_priv(const struct net_device *dev)
 {
-	return (char *)dev + ((sizeof(struct net_device)
-					+ NETDEV_ALIGN_CONST)
-				& ~NETDEV_ALIGN_CONST);
+	return dev->priv;
 }
 
 #define SET_MODULE_OWNER(dev) do { } while (0)
@@ -702,6 +732,62 @@
 	return test_bit(__LINK_STATE_START, &dev->state);
 }
 
+/*
+ * Routines to manage the subqueues on a device.  We only need start
+ * stop, and a check if it's stopped.  All other device management is
+ * done at the overall netdevice level.
+ * Also test the device if we're multiqueue.
+ */
+static inline void netif_start_subqueue(struct net_device *dev, u16 queue_index)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	clear_bit(__LINK_STATE_XOFF, &dev->egress_subqueue[queue_index].state);
+#endif
+}
+
+static inline void netif_stop_subqueue(struct net_device *dev, u16 queue_index)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+#ifdef CONFIG_NETPOLL_TRAP
+	if (netpoll_trap())
+		return;
+#endif
+	set_bit(__LINK_STATE_XOFF, &dev->egress_subqueue[queue_index].state);
+#endif
+}
+
+static inline int netif_subqueue_stopped(const struct net_device *dev,
+					 u16 queue_index)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	return test_bit(__LINK_STATE_XOFF,
+			&dev->egress_subqueue[queue_index].state);
+#else
+	return 0;
+#endif
+}
+
+static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+#ifdef CONFIG_NETPOLL_TRAP
+	if (netpoll_trap())
+		return;
+#endif
+	if (test_and_clear_bit(__LINK_STATE_XOFF,
+			       &dev->egress_subqueue[queue_index].state))
+		__netif_schedule(dev);
+#endif
+}
+
+static inline int netif_is_multiqueue(const struct net_device *dev)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	return (!!(NETIF_F_MULTI_QUEUE & dev->features));
+#else
+	return 0;
+#endif
+}
 
 /* Use this variant when it is known for sure that it
  * is executing from interrupt context.
@@ -930,6 +1016,14 @@
 {
 	unsigned long flags;
 
+#ifdef CONFIG_NETPOLL
+	/* Prevent race with netpoll - yes, this is a kludge.
+	 * But at least it doesn't penalize the non-netpoll
+	 * code path. */
+	if (test_bit(__LINK_STATE_POLL_LIST_FROZEN, &dev->state))
+		return;
+#endif
+
 	local_irq_save(flags);
 	__netif_rx_complete(dev);
 	local_irq_restore(flags);
@@ -992,15 +1086,24 @@
 extern void		ether_setup(struct net_device *dev);
 
 /* Support for loadable net-drivers */
-extern struct net_device *alloc_netdev(int sizeof_priv, const char *name,
-				       void (*setup)(struct net_device *));
+extern struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
+				       void (*setup)(struct net_device *),
+				       unsigned int queue_count);
+#define alloc_netdev(sizeof_priv, name, setup) \
+	alloc_netdev_mq(sizeof_priv, name, setup, 1)
 extern int		register_netdev(struct net_device *dev);
 extern void		unregister_netdev(struct net_device *dev);
-/* Functions used for multicast support */
-extern void		dev_mc_upload(struct net_device *dev);
+/* Functions used for secondary unicast and multicast support */
+extern void		dev_set_rx_mode(struct net_device *dev);
+extern void		__dev_set_rx_mode(struct net_device *dev);
+extern int		dev_unicast_delete(struct net_device *dev, void *addr, int alen);
+extern int		dev_unicast_add(struct net_device *dev, void *addr, int alen);
 extern int 		dev_mc_delete(struct net_device *dev, void *addr, int alen, int all);
 extern int		dev_mc_add(struct net_device *dev, void *addr, int alen, int newonly);
 extern void		dev_mc_discard(struct net_device *dev);
+extern int 		__dev_addr_delete(struct dev_addr_list **list, int *count, void *addr, int alen, int all);
+extern int		__dev_addr_add(struct dev_addr_list **list, int *count, void *addr, int alen, int newonly);
+extern void		__dev_addr_discard(struct dev_addr_list **list);
 extern void		dev_set_promiscuity(struct net_device *dev, int inc);
 extern void		dev_set_allmulti(struct net_device *dev, int inc);
 extern void		netdev_state_change(struct net_device *dev);
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 10b5c62..0eed0b7 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -275,7 +275,8 @@
 };
 extern int nf_register_queue_handler(int pf, 
                                      struct nf_queue_handler *qh);
-extern int nf_unregister_queue_handler(int pf);
+extern int nf_unregister_queue_handler(int pf,
+				       struct nf_queue_handler *qh);
 extern void nf_unregister_queue_handlers(struct nf_queue_handler *qh);
 extern void nf_reinject(struct sk_buff *skb,
 			struct nf_info *info,
diff --git a/include/linux/netfilter/nf_conntrack_pptp.h b/include/linux/netfilter/nf_conntrack_pptp.h
index 9d8144a..c93061f 100644
--- a/include/linux/netfilter/nf_conntrack_pptp.h
+++ b/include/linux/netfilter/nf_conntrack_pptp.h
@@ -4,6 +4,8 @@
 
 #include <linux/netfilter/nf_conntrack_common.h>
 
+extern const char *pptp_msg_name[];
+
 /* state of the control session */
 enum pptp_ctrlsess_state {
 	PPTP_SESSION_NONE,			/* no session present */
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 7e733a6..64f425a8 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -141,22 +141,22 @@
 	/* Arguments changed since 2.6.9, as this must now handle
 	   non-linear skb, using skb_header_pointer and
 	   skb_ip_make_writable. */
-	int (*match)(const struct sk_buff *skb,
-		     const struct net_device *in,
-		     const struct net_device *out,
-		     const struct xt_match *match,
-		     const void *matchinfo,
-		     int offset,
-		     unsigned int protoff,
-		     int *hotdrop);
+	bool (*match)(const struct sk_buff *skb,
+		      const struct net_device *in,
+		      const struct net_device *out,
+		      const struct xt_match *match,
+		      const void *matchinfo,
+		      int offset,
+		      unsigned int protoff,
+		      bool *hotdrop);
 
 	/* Called when user tries to insert an entry of this type. */
 	/* Should return true or false. */
-	int (*checkentry)(const char *tablename,
-			  const void *ip,
-			  const struct xt_match *match,
-			  void *matchinfo,
-			  unsigned int hook_mask);
+	bool (*checkentry)(const char *tablename,
+			   const void *ip,
+			   const struct xt_match *match,
+			   void *matchinfo,
+			   unsigned int hook_mask);
 
 	/* Called when entry of this type deleted. */
 	void (*destroy)(const struct xt_match *match, void *matchinfo);
@@ -202,11 +202,11 @@
            hook_mask is a bitmask of hooks from which it can be
            called. */
 	/* Should return true or false. */
-	int (*checkentry)(const char *tablename,
-			  const void *entry,
-			  const struct xt_target *target,
-			  void *targinfo,
-			  unsigned int hook_mask);
+	bool (*checkentry)(const char *tablename,
+			   const void *entry,
+			   const struct xt_target *target,
+			   void *targinfo,
+			   unsigned int hook_mask);
 
 	/* Called when entry of this type deleted. */
 	void (*destroy)(const struct xt_target *target, void *targinfo);
diff --git a/include/linux/netfilter/xt_u32.h b/include/linux/netfilter/xt_u32.h
new file mode 100644
index 0000000..9947f56
--- /dev/null
+++ b/include/linux/netfilter/xt_u32.h
@@ -0,0 +1,40 @@
+#ifndef _XT_U32_H
+#define _XT_U32_H 1
+
+enum xt_u32_ops {
+	XT_U32_AND,
+	XT_U32_LEFTSH,
+	XT_U32_RIGHTSH,
+	XT_U32_AT,
+};
+
+struct xt_u32_location_element {
+	u_int32_t number;
+	u_int8_t nextop;
+};
+
+struct xt_u32_value_element {
+	u_int32_t min;
+	u_int32_t max;
+};
+
+/*
+ * Any way to allow for an arbitrary number of elements?
+ * For now, I settle with a limit of 10 each.
+ */
+#define XT_U32_MAXSIZE 10
+
+struct xt_u32_test {
+	struct xt_u32_location_element location[XT_U32_MAXSIZE+1];
+	struct xt_u32_value_element value[XT_U32_MAXSIZE+1];
+	u_int8_t nnums;
+	u_int8_t nvalues;
+};
+
+struct xt_u32 {
+	struct xt_u32_test tests[XT_U32_MAXSIZE+1];
+	u_int8_t ntests;
+	u_int8_t invert;
+};
+
+#endif /* _XT_U32_H */
diff --git a/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h b/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h
index d9bceed..daf50be 100644
--- a/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h
+++ b/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h
@@ -18,13 +18,13 @@
 struct ipt_clusterip_tgt_info {
 
 	u_int32_t flags;
-	
+
 	/* only relevant for new ones */
 	u_int8_t clustermac[6];
 	u_int16_t num_total_nodes;
 	u_int16_t num_local_nodes;
 	u_int16_t local_nodes[CLUSTERIP_MAX_NODES];
-	enum clusterip_hashmode hash_mode;
+	u_int32_t hash_mode;
 	u_int32_t hash_initval;
 
 	struct clusterip_config *config;
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 4686f83..9a720f0 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -44,8 +44,14 @@
 	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
 	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
 
-	/* ARGH, HopByHop uses 0, so can't do 0 = ANY,
-	   instead IP6T_F_NOPROTO must be set */
+	/* Upper protocol number
+	 * - The allowed value is 0 (any) or protocol number of last parsable
+	 *   header, which is 50 (ESP), 59 (No Next Header), 135 (MH), or
+	 *   the non IPv6 extension headers.
+	 * - The protocol numbers of IPv6 extension headers except of ESP and
+	 *   MH do not match any packets.
+	 * - You also need to set IP6T_FLAGS_PROTO to "flags" to check protocol.
+	 */
 	u_int16_t proto;
 	/* TOS to match iff flags & IP6T_F_TOS */
 	u_int8_t tos;
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 93961e9..9366182 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -374,6 +374,7 @@
 #define PCI_DEVICE_ID_ATI_IXP600_SMBUS	0x4385
 #define PCI_DEVICE_ID_ATI_IXP600_IDE	0x438c
 #define PCI_DEVICE_ID_ATI_IXP700_SATA	0x4390
+#define PCI_DEVICE_ID_ATI_IXP700_SMBUS	0x4395
 #define PCI_DEVICE_ID_ATI_IXP700_IDE	0x439c
 
 #define PCI_VENDOR_ID_VLSI		0x1004
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index c3f01b3..30b8571 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -403,16 +403,13 @@
  *   1..32767		Reserved for ematches inside kernel tree
  *   32768..65535	Free to use, not reliable
  */
-enum
-{
-	TCF_EM_CONTAINER,
-	TCF_EM_CMP,
-	TCF_EM_NBYTE,
-	TCF_EM_U32,
-	TCF_EM_META,
-	TCF_EM_TEXT,
-	__TCF_EM_MAX
-};
+#define	TCF_EM_CONTAINER	0
+#define	TCF_EM_CMP		1
+#define	TCF_EM_NBYTE		2
+#define	TCF_EM_U32		3
+#define	TCF_EM_META		4
+#define	TCF_EM_TEXT		5
+#define	TCF_EM_MAX		5
 
 enum
 {
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index d10f353..268c515 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -101,6 +101,15 @@
 	__u8	priomap[TC_PRIO_MAX+1];	/* Map: logical priority -> PRIO band */
 };
 
+enum
+{
+	TCA_PRIO_UNSPEC,
+	TCA_PRIO_MQ,
+	__TCA_PRIO_MAX
+};
+
+#define TCA_PRIO_MAX    (__TCA_PRIO_MAX - 1)
+
 /* TBF section */
 
 struct tc_tbf_qopt
diff --git a/include/linux/pm.h b/include/linux/pm.h
index b2c4fde..273781c 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -267,15 +267,10 @@
 	unsigned		can_wakeup:1;
 #ifdef	CONFIG_PM
 	unsigned		should_wakeup:1;
-	pm_message_t		prev_state;
-	void			* saved_state;
-	struct device		* pm_parent;
 	struct list_head	entry;
 #endif
 };
 
-extern void device_pm_set_parent(struct device * dev, struct device * parent);
-
 extern int device_power_down(pm_message_t state);
 extern void device_power_up(void);
 extern void device_resume(void);
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 1fae30a..c91476c 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -261,7 +261,7 @@
 	RTA_FLOW,
 	RTA_CACHEINFO,
 	RTA_SESSION,
-	RTA_MP_ALGO,
+	RTA_MP_ALGO, /* no longer used */
 	RTA_TABLE,
 	__RTA_MAX
 };
@@ -570,10 +570,16 @@
 }
 
 extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
+extern int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+				        struct rtattr *rta, int len);
 
 #define rtattr_parse_nested(tb, max, rta) \
 	rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta)))
 
+#define rtattr_parse_nested_compat(tb, max, rta, data, len) \
+({	data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
+	__rtattr_parse_nested_compat(tb, max, rta, len); })
+
 extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
 extern int rtnl_unicast(struct sk_buff *skb, u32 pid);
 extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
@@ -638,6 +644,18 @@
 ({	(start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
 	(skb)->len; })
 
+#define RTA_NEST_COMPAT(skb, type, attrlen, data) \
+({	struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \
+	RTA_PUT(skb, type, attrlen, data); \
+	RTA_NEST(skb, type); \
+	__start; })
+
+#define RTA_NEST_COMPAT_END(skb, start) \
+({	struct rtattr *__nest = (void *)(start) + NLMSG_ALIGN((start)->rta_len); \
+	(start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
+	RTA_NEST_END(skb, __nest); \
+	(skb)->len; })
+
 #define RTA_NEST_CANCEL(skb, start) \
 ({	if (start) \
 		skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
index b02308e..3ee412b 100644
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -10,7 +10,7 @@
 struct screen_info {
 	u8  orig_x;		/* 0x00 */
 	u8  orig_y;		/* 0x01 */
-	u16 dontuse1;		/* 0x02 -- EXT_MEM_K sits here */
+	u16 ext_mem_k;		/* 0x02 */
 	u16 orig_video_page;	/* 0x04 */
 	u8  orig_video_mode;	/* 0x06 */
 	u8  orig_video_cols;	/* 0x07 */
@@ -27,7 +27,7 @@
 	u16 lfb_depth;		/* 0x16 */
 	u32 lfb_base;		/* 0x18 */
 	u32 lfb_size;		/* 0x1c */
-	u16 dontuse2, dontuse3;	/* 0x20 -- CL_MAGIC and CL_OFFSET here */
+	u16 cl_magic, cl_offset; /* 0x20 */
 	u16 lfb_linelength;	/* 0x24 */
 	u8  red_size;		/* 0x26 */
 	u8  red_pos;		/* 0x27 */
@@ -42,9 +42,8 @@
 	u16 pages;		/* 0x32 */
 	u16 vesa_attributes;	/* 0x34 */
 	u32 capabilities;       /* 0x36 */
-				/* 0x3a -- 0x3b reserved for future expansion */
-				/* 0x3c -- 0x3f micro stack for relocatable kernels */
-};
+	u8  _reserved[6];	/* 0x3a */
+} __attribute__((packed));
 
 extern struct screen_info screen_info;
 
diff --git a/include/linux/serio.h b/include/linux/serio.h
index 1ebf045..d9377ce 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -209,5 +209,6 @@
 #define SERIO_PENMOUNT	0x31
 #define SERIO_TOUCHRIGHT	0x32
 #define SERIO_TOUCHWIN	0x33
+#define SERIO_TAOSEVM	0x34
 
 #endif
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 6f0b2f7..9391e4a 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -65,13 +65,20 @@
  *	    is able to produce some skb->csum, it MUST use COMPLETE,
  *	    not UNNECESSARY.
  *
+ *	PARTIAL: identical to the case for output below.  This may occur
+ *	    on a packet received directly from another Linux OS, e.g.,
+ *	    a virtualised Linux kernel on the same host.  The packet can
+ *	    be treated in the same way as UNNECESSARY except that on
+ *	    output (i.e., forwarding) the checksum must be filled in
+ *	    by the OS or the hardware.
+ *
  * B. Checksumming on output.
  *
  *	NONE: skb is checksummed by protocol or csum is not required.
  *
  *	PARTIAL: device is required to csum packet as seen by hard_start_xmit
- *	from skb->transport_header to the end and to record the checksum
- *	at skb->transport_header + skb->csum.
+ *	from skb->csum_start to the end and to record the checksum
+ *	at skb->csum_start + skb->csum_offset.
  *
  *	Device must show its capabilities in dev->features, set
  *	at device setup time.
@@ -82,6 +89,7 @@
  *			  TCP/UDP over IPv4. Sigh. Vendors like this
  *			  way by an unknown reason. Though, see comment above
  *			  about CHECKSUM_UNNECESSARY. 8)
+ *	NETIF_F_IPV6_CSUM about as dumb as the last one but does IPv6 instead.
  *
  *	Any questions? No questions, good. 		--ANK
  */
@@ -147,8 +155,8 @@
 
 /* We divide dataref into two halves.  The higher 16 bits hold references
  * to the payload part of skb->data.  The lower 16 bits hold references to
- * the entire skb->data.  It is up to the users of the skb to agree on
- * where the payload starts.
+ * the entire skb->data.  A clone of a headerless skb holds the length of
+ * the header in skb->hdr_len.
  *
  * All users must obey the rule that the skb->data reference count must be
  * greater than or equal to the payload reference count.
@@ -196,7 +204,6 @@
  *	@sk: Socket we are owned by
  *	@tstamp: Time we arrived
  *	@dev: Device we arrived on/are leaving by
- *	@iif: ifindex of device we arrived on
  *	@transport_header: Transport layer header
  *	@network_header: Network layer header
  *	@mac_header: Link layer header
@@ -206,6 +213,7 @@
  *	@len: Length of actual data
  *	@data_len: Data length
  *	@mac_len: Length of link layer header
+ *	@hdr_len: writable header length of cloned skb
  *	@csum: Checksum (must include start/offset pair)
  *	@csum_start: Offset from skb->head where checksumming should start
  *	@csum_offset: Offset from csum_start where checksum should be stored
@@ -227,9 +235,12 @@
  *	@mark: Generic packet mark
  *	@nfct: Associated connection, if any
  *	@ipvs_property: skbuff is owned by ipvs
+ *	@nf_trace: netfilter packet trace flag
  *	@nfctinfo: Relationship of this skb to the connection
  *	@nfct_reasm: netfilter conntrack re-assembly pointer
  *	@nf_bridge: Saved data about a bridged frame - see br_netfilter.c
+ *	@iif: ifindex of device we arrived on
+ *	@queue_mapping: Queue mapping for multiqueue devices
  *	@tc_index: Traffic control index
  *	@tc_verd: traffic control verdict
  *	@dma_cookie: a cookie to one of several possible DMA operations
@@ -245,8 +256,6 @@
 	struct sock		*sk;
 	ktime_t			tstamp;
 	struct net_device	*dev;
-	int			iif;
-	/* 4 byte hole on 64 bit*/
 
 	struct  dst_entry	*dst;
 	struct	sec_path	*sp;
@@ -260,8 +269,9 @@
 	char			cb[48];
 
 	unsigned int		len,
-				data_len,
-				mac_len;
+				data_len;
+	__u16			mac_len,
+				hdr_len;
 	union {
 		__wsum		csum;
 		struct {
@@ -277,7 +287,8 @@
 				nfctinfo:3;
 	__u8			pkt_type:3,
 				fclone:2,
-				ipvs_property:1;
+				ipvs_property:1,
+				nf_trace:1;
 	__be16			protocol;
 
 	void			(*destructor)(struct sk_buff *skb);
@@ -288,12 +299,18 @@
 #ifdef CONFIG_BRIDGE_NETFILTER
 	struct nf_bridge_info	*nf_bridge;
 #endif
+
+	int			iif;
+	__u16			queue_mapping;
+
 #ifdef CONFIG_NET_SCHED
 	__u16			tc_index;	/* traffic control index */
 #ifdef CONFIG_NET_CLS_ACT
 	__u16			tc_verd;	/* traffic control verdict */
 #endif
 #endif
+	/* 2 byte hole */
+
 #ifdef CONFIG_NET_DMA
 	dma_cookie_t		dma_cookie;
 #endif
@@ -1322,6 +1339,20 @@
 }
 
 /**
+ *	skb_clone_writable - is the header of a clone writable
+ *	@skb: buffer to check
+ *	@len: length up to which to write
+ *
+ *	Returns true if modifying the header part of the cloned buffer
+ *	does not requires the data to be copied.
+ */
+static inline int skb_clone_writable(struct sk_buff *skb, int len)
+{
+	return !skb_header_cloned(skb) &&
+	       skb_headroom(skb) + len <= skb->hdr_len;
+}
+
+/**
  *	skb_cow - copy header of skb when it is required
  *	@skb: buffer to cow
  *	@headroom: needed headroom
@@ -1709,6 +1740,20 @@
 { }
 #endif
 
+static inline void skb_set_queue_mapping(struct sk_buff *skb, u16 queue_mapping)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	skb->queue_mapping = queue_mapping;
+#endif
+}
+
+static inline void skb_copy_queue_mapping(struct sk_buff *to, const struct sk_buff *from)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	to->queue_mapping = from->queue_mapping;
+#endif
+}
+
 static inline int skb_is_gso(const struct sk_buff *skb)
 {
 	return skb_shinfo(skb)->gso_size;
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 6e7c948..fe195c9 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -287,6 +287,7 @@
 #define SOL_NETLINK	270
 #define SOL_TIPC	271
 #define SOL_RXRPC	272
+#define SOL_PPPOL2TP	273
 
 /* IPX options */
 #define IPX_TYPE	1
diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h
index e699ab2..e2857465 100644
--- a/include/linux/sysdev.h
+++ b/include/linux/sysdev.h
@@ -101,8 +101,7 @@
 
 #define _SYSDEV_ATTR(_name,_mode,_show,_store)			\
 {								\
-	.attr = { .name = __stringify(_name), .mode = _mode,	\
-		 .owner = THIS_MODULE },			\
+	.attr = { .name = __stringify(_name), .mode = _mode },	\
 	.show	= _show,					\
 	.store	= _store,					\
 }
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 7d5d1ec..be8228e 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -19,10 +19,15 @@
 struct module;
 struct nameidata;
 struct dentry;
+struct sysfs_dirent;
 
+/* FIXME
+ * The *owner field is no longer used, but leave around
+ * until the tree gets cleaned up fully.
+ */
 struct attribute {
 	const char		* name;
-	struct module 		* owner;
+	struct module		* owner;
 	mode_t			mode;
 };
 
@@ -39,14 +44,14 @@
  */
 
 #define __ATTR(_name,_mode,_show,_store) { \
-	.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },	\
+	.attr = {.name = __stringify(_name), .mode = _mode },	\
 	.show	= _show,					\
 	.store	= _store,					\
 }
 
 #define __ATTR_RO(_name) { \
-	.attr	= { .name = __stringify(_name), .mode = 0444, .owner = THIS_MODULE },	\
-	.show	= _name##_show,	\
+	.attr	= { .name = __stringify(_name), .mode = 0444 },	\
+	.show	= _name##_show,					\
 }
 
 #define __ATTR_NULL { .attr = { .name = NULL } }
@@ -59,8 +64,10 @@
 	struct attribute	attr;
 	size_t			size;
 	void			*private;
-	ssize_t (*read)(struct kobject *, char *, loff_t, size_t);
-	ssize_t (*write)(struct kobject *, char *, loff_t, size_t);
+	ssize_t (*read)(struct kobject *, struct bin_attribute *,
+			char *, loff_t, size_t);
+	ssize_t (*write)(struct kobject *, struct bin_attribute *,
+			 char *, loff_t, size_t);
 	int (*mmap)(struct kobject *, struct bin_attribute *attr,
 		    struct vm_area_struct *vma);
 };
@@ -70,12 +77,16 @@
 	ssize_t	(*store)(struct kobject *,struct attribute *,const char *, size_t);
 };
 
+#define SYSFS_TYPE_MASK		0x00ff
 #define SYSFS_ROOT		0x0001
 #define SYSFS_DIR		0x0002
 #define SYSFS_KOBJ_ATTR 	0x0004
 #define SYSFS_KOBJ_BIN_ATTR	0x0008
 #define SYSFS_KOBJ_LINK 	0x0020
-#define SYSFS_NOT_PINNED	(SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR | SYSFS_KOBJ_LINK)
+#define SYSFS_COPY_NAME		(SYSFS_DIR | SYSFS_KOBJ_LINK)
+
+#define SYSFS_FLAG_MASK		~SYSFS_TYPE_MASK
+#define SYSFS_FLAG_REMOVED	0x0100
 
 #ifdef CONFIG_SYSFS
 
@@ -83,13 +94,14 @@
 		void (*func)(void *), void *data, struct module *owner);
 
 extern int __must_check
-sysfs_create_dir(struct kobject *, struct dentry *);
+sysfs_create_dir(struct kobject *kobj, struct sysfs_dirent *shadow_parent_sd);
 
 extern void
 sysfs_remove_dir(struct kobject *);
 
 extern int __must_check
-sysfs_rename_dir(struct kobject *, struct dentry *, const char *new_name);
+sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd,
+		 const char *new_name);
 
 extern int __must_check
 sysfs_move_dir(struct kobject *, struct kobject *);
@@ -129,8 +141,8 @@
 
 extern int sysfs_make_shadowed_dir(struct kobject *kobj,
 	void * (*follow_link)(struct dentry *, struct nameidata *));
-extern struct dentry *sysfs_create_shadow_dir(struct kobject *kobj);
-extern void sysfs_remove_shadow_dir(struct dentry *dir);
+extern struct sysfs_dirent *sysfs_create_shadow_dir(struct kobject *kobj);
+extern void sysfs_remove_shadow_dir(struct sysfs_dirent *shadow_sd);
 
 extern int __must_check sysfs_init(void);
 
@@ -142,7 +154,8 @@
 	return -ENOSYS;
 }
 
-static inline int sysfs_create_dir(struct kobject * k, struct dentry *shadow)
+static inline int sysfs_create_dir(struct kobject *kobj,
+				   struct sysfs_dirent *shadow_parent_sd)
 {
 	return 0;
 }
@@ -152,9 +165,9 @@
 	;
 }
 
-static inline int sysfs_rename_dir(struct kobject * k,
-					struct dentry *new_parent,
-					const char *new_name)
+static inline int sysfs_rename_dir(struct kobject *kobj,
+				   struct sysfs_dirent *new_parent_sd,
+				   const char *new_name)
 {
 	return 0;
 }
diff --git a/include/linux/udp.h b/include/linux/udp.h
index 6de445c..8ec703f 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -42,6 +42,7 @@
 /* UDP encapsulation types */
 #define UDP_ENCAP_ESPINUDP_NON_IKE	1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
 #define UDP_ENCAP_ESPINUDP	2 /* draft-ietf-ipsec-udp-encaps-06 */
+#define UDP_ENCAP_L2TPINUDP	3 /* rfc2661 */
 
 #ifdef __KERNEL__
 #include <linux/types.h>
@@ -70,6 +71,11 @@
 #define UDPLITE_SEND_CC  0x2  		/* set via udplite setsockopt         */
 #define UDPLITE_RECV_CC  0x4		/* set via udplite setsocktopt        */
 	__u8		 pcflag;        /* marks socket as UDP-Lite if > 0    */
+	__u8		 unused[3];
+	/*
+	 * For encapsulation sockets.
+	 */
+	int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
 };
 
 static inline struct udp_sock *udp_sk(const struct sock *sk)
diff --git a/include/net/act_api.h b/include/net/act_api.h
index 8b06c2f..2f0273f 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -19,7 +19,6 @@
 	struct gnet_stats_basic		tcfc_bstats;
 	struct gnet_stats_queue		tcfc_qstats;
 	struct gnet_stats_rate_est	tcfc_rate_est;
-	spinlock_t			*tcfc_stats_lock;
 	spinlock_t			tcfc_lock;
 };
 #define tcf_next	common.tcfc_next
@@ -32,7 +31,6 @@
 #define tcf_bstats	common.tcfc_bstats
 #define tcf_qstats	common.tcfc_qstats
 #define tcf_rate_est	common.tcfc_rate_est
-#define tcf_stats_lock	common.tcfc_stats_lock
 #define tcf_lock	common.tcfc_lock
 
 struct tcf_police {
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index f3531d0..33b593e 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -61,7 +61,7 @@
 extern int			ipv6_chk_addr(struct in6_addr *addr,
 					      struct net_device *dev,
 					      int strict);
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 extern int			ipv6_chk_home_addr(struct in6_addr *addr);
 #endif
 extern struct inet6_ifaddr *	ipv6_get_ifaddr(struct in6_addr *addr,
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 65f49fd..6de1e9e 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -79,9 +79,10 @@
 	struct mutex		readlock;
         struct sock		*peer;
         struct sock		*other;
-        struct sock		*gc_tree;
+	struct list_head	link;
         atomic_t                inflight;
         spinlock_t		lock;
+	unsigned int		gc_candidate : 1;
         wait_queue_head_t       peer_wait;
 };
 #define unix_sk(__sk) ((struct unix_sock *)__sk)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 93ce272..ebfb96b 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -107,14 +107,14 @@
 #define HCI_IDLE_TIMEOUT	(6000)	/* 6 seconds */
 #define HCI_INIT_TIMEOUT	(10000)	/* 10 seconds */
 
-/* HCI Packet types */
+/* HCI data types */
 #define HCI_COMMAND_PKT		0x01
 #define HCI_ACLDATA_PKT		0x02
 #define HCI_SCODATA_PKT		0x03
 #define HCI_EVENT_PKT		0x04
 #define HCI_VENDOR_PKT		0xff
 
-/* HCI Packet types */
+/* HCI packet types */
 #define HCI_DM1		0x0008
 #define HCI_DM3		0x0400
 #define HCI_DM5		0x4000
@@ -129,6 +129,14 @@
 #define SCO_PTYPE_MASK	(HCI_HV1 | HCI_HV2 | HCI_HV3)
 #define ACL_PTYPE_MASK	(~SCO_PTYPE_MASK)
 
+/* eSCO packet types */
+#define ESCO_HV1	0x0001
+#define ESCO_HV2	0x0002
+#define ESCO_HV3	0x0004
+#define ESCO_EV3	0x0008
+#define ESCO_EV4	0x0010
+#define ESCO_EV5	0x0020
+
 /* ACL flags */
 #define ACL_CONT		0x01
 #define ACL_START		0x02
@@ -138,6 +146,7 @@
 /* Baseband links */
 #define SCO_LINK	0x00
 #define ACL_LINK	0x01
+#define ESCO_LINK	0x02
 
 /* LMP features */
 #define LMP_3SLOT	0x01
@@ -162,6 +171,11 @@
 #define LMP_PSCHEME	0x02
 #define LMP_PCONTROL	0x04
 
+#define LMP_ESCO	0x80
+
+#define LMP_EV4		0x01
+#define LMP_EV5		0x02
+
 #define LMP_SNIFF_SUBR	0x02
 
 /* Connection modes */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index c0fc396..8f67c8a 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -78,6 +78,7 @@
 	__u16		voice_setting;
 
 	__u16		pkt_type;
+	__u16		esco_type;
 	__u16		link_policy;
 	__u16		link_mode;
 
@@ -109,6 +110,7 @@
 	struct sk_buff_head	cmd_q;
 
 	struct sk_buff		*sent_cmd;
+	struct sk_buff		*reassembly[3];
 
 	struct semaphore	req_lock;
 	wait_queue_head_t	req_wait_q;
@@ -437,6 +439,8 @@
 	return 0;
 }
 
+int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);
+
 int hci_register_sysfs(struct hci_dev *hdev);
 void hci_unregister_sysfs(struct hci_dev *hdev);
 void hci_conn_add_sysfs(struct hci_conn *conn);
@@ -449,6 +453,7 @@
 #define lmp_encrypt_capable(dev)   ((dev)->features[0] & LMP_ENCRYPT)
 #define lmp_sniff_capable(dev)     ((dev)->features[0] & LMP_SNIFF)
 #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
+#define lmp_esco_capable(dev)      ((dev)->features[3] & LMP_ESCO)
 
 /* ----- HCI protocols ----- */
 struct hci_proto {
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 3c563f0..25aa575 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -323,6 +323,7 @@
 #define RFCOMM_RELEASE_ONHUP  1
 #define RFCOMM_HANGUP_NOW     2
 #define RFCOMM_TTY_ATTACHED   3
+#define RFCOMM_TTY_RELEASED   4
 
 struct rfcomm_dev_req {
 	s16      dev_id;
diff --git a/include/net/dn.h b/include/net/dn.h
index ac4ce90..6277783 100644
--- a/include/net/dn.h
+++ b/include/net/dn.h
@@ -3,7 +3,6 @@
 
 #include <linux/dn.h>
 #include <net/sock.h>
-#include <net/tcp.h>
 #include <asm/byteorder.h>
 
 #define dn_ntohs(x) le16_to_cpu(x)
diff --git a/include/net/dst.h b/include/net/dst.h
index 82270f9..e9ff4a4 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -47,7 +47,6 @@
 #define DST_NOXFRM		2
 #define DST_NOPOLICY		4
 #define DST_NOHASH		8
-#define DST_BALANCED            0x10
 	unsigned long		expires;
 
 	unsigned short		header_len;	/* more space at head required */
diff --git a/include/net/flow.h b/include/net/flow.h
index f3cc1f8..af59fa5 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -67,20 +67,16 @@
 
 		__be32		spi;
 
-#ifdef CONFIG_IPV6_MIP6
 		struct {
 			__u8	type;
 		} mht;
-#endif
 	} uli_u;
 #define fl_ip_sport	uli_u.ports.sport
 #define fl_ip_dport	uli_u.ports.dport
 #define fl_icmp_type	uli_u.icmpt.type
 #define fl_icmp_code	uli_u.icmpt.code
 #define fl_ipsec_spi	uli_u.spi
-#ifdef CONFIG_IPV6_MIP6
 #define fl_mh_type	uli_u.mht.type
-#endif
 	__u32           secid;	/* used by xfrm; see secid.txt */
 } __attribute__((__aligned__(BITS_PER_LONG/8)));
 
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 69252cb..8cadc77 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -39,7 +39,6 @@
 	int			fc_mx_len;
 	int			fc_mp_len;
 	u32			fc_flow;
-	u32			fc_mp_alg;
 	u32			fc_nlflags;
 	struct nl_info		fc_nlinfo;
  };
@@ -86,9 +85,6 @@
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 	int			fib_power;
 #endif
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	u32			fib_mp_alg;
-#endif
 	struct fib_nh		fib_nh[0];
 #define fib_dev		fib_nh[0].nh_dev
 };
@@ -103,10 +99,6 @@
 	unsigned char	nh_sel;
 	unsigned char	type;
 	unsigned char	scope;
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	__be32          network;
-	__be32          netmask;
-#endif
 	struct fib_info *fi;
 #ifdef CONFIG_IP_MULTIPLE_TABLES
 	struct fib_rule	*r;
@@ -145,14 +137,6 @@
 #define FIB_RES_DEV(res)		(FIB_RES_NH(res).nh_dev)
 #define FIB_RES_OIF(res)		(FIB_RES_NH(res).nh_oif)
 
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-#define FIB_RES_NETWORK(res)		((res).network)
-#define FIB_RES_NETMASK(res)	        ((res).netmask)
-#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
-#define FIB_RES_NETWORK(res)		(0)
-#define FIB_RES_NETMASK(res)	        (0)
-#endif /* CONFIG_IP_ROUTE_MULTIPATH_WRANDOM */
-
 struct fib_table {
 	struct hlist_node tb_hlist;
 	u32		tb_id;
diff --git a/include/net/ip_mp_alg.h b/include/net/ip_mp_alg.h
deleted file mode 100644
index 25b5657..0000000
--- a/include/net/ip_mp_alg.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* ip_mp_alg.h: IPV4 multipath algorithm support.
- *
- * Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com>
- * Copyright (C) 2005 David S. Miller <davem@davemloft.net>
- */
-
-#ifndef _NET_IP_MP_ALG_H
-#define _NET_IP_MP_ALG_H
-
-#include <linux/ip_mp_alg.h>
-#include <net/flow.h>
-#include <net/route.h>
-
-struct fib_nh;
-
-struct ip_mp_alg_ops {
-	void	(*mp_alg_select_route)(const struct flowi *flp,
-				       struct rtable *rth, struct rtable **rp);
-	void	(*mp_alg_flush)(void);
-	void	(*mp_alg_set_nhinfo)(__be32 network, __be32 netmask,
-				     unsigned char prefixlen,
-				     const struct fib_nh *nh);
-	void	(*mp_alg_remove)(struct rtable *rth);
-};
-
-extern int multipath_alg_register(struct ip_mp_alg_ops *, enum ip_mp_alg);
-extern void multipath_alg_unregister(struct ip_mp_alg_ops *, enum ip_mp_alg);
-
-extern struct ip_mp_alg_ops *ip_mp_alg_table[];
-
-static inline int multipath_select_route(const struct flowi *flp,
-					 struct rtable *rth,
-					 struct rtable **rp)
-{
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
-
-	/* mp_alg_select_route _MUST_ be implemented */
-	if (ops && (rth->u.dst.flags & DST_BALANCED)) {
-		ops->mp_alg_select_route(flp, rth, rp);
-		return 1;
-	}
-#endif
-	return 0;
-}
-
-static inline void multipath_flush(void)
-{
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	int i;
-
-	for (i = IP_MP_ALG_NONE; i <= IP_MP_ALG_MAX; i++) {
-		struct ip_mp_alg_ops *ops = ip_mp_alg_table[i];
-
-		if (ops && ops->mp_alg_flush)
-			ops->mp_alg_flush();
-	}
-#endif
-}
-
-static inline void multipath_set_nhinfo(struct rtable *rth,
-					__be32 network, __be32 netmask,
-					unsigned char prefixlen,
-					const struct fib_nh *nh)
-{
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
-
-	if (ops && ops->mp_alg_set_nhinfo)
-		ops->mp_alg_set_nhinfo(network, netmask, prefixlen, nh);
-#endif
-}
-
-static inline void multipath_remove(struct rtable *rth)
-{
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	struct ip_mp_alg_ops *ops = ip_mp_alg_table[rth->rt_multipath_alg];
-
-	if (ops && ops->mp_alg_remove &&
-	    (rth->u.dst.flags & DST_BALANCED))
-		ops->mp_alg_remove(rth);
-#endif
-}
-
-static inline int multipath_comparekeys(const struct flowi *flp1,
-					const struct flowi *flp2)
-{
-	return flp1->fl4_dst == flp2->fl4_dst &&
-		flp1->fl4_src == flp2->fl4_src &&
-		flp1->oif == flp2->oif &&
-		flp1->mark == flp2->mark &&
-		!((flp1->fl4_tos ^ flp2->fl4_tos) &
-		  (IPTOS_RT_MASK | RTO_ONLINK));
-}
-
-#endif /* _NET_IP_MP_ALG_H */
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 78a0d06..46b9dce 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -512,10 +512,6 @@
 
 extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
 
-extern struct ipv6_txoptions *	ipv6_invert_rthdr(struct sock *sk,
-						  struct ipv6_rt_hdr *hdr);
-
-
 /*
  *	socket options (ipv6_sockglue.c)
  */
diff --git a/include/net/irda/irda.h b/include/net/irda/irda.h
index 36bee44..0838755 100644
--- a/include/net/irda/irda.h
+++ b/include/net/irda/irda.h
@@ -125,6 +125,9 @@
 extern int irsock_init(void);
 extern void irsock_cleanup(void);
 
+extern int irda_nl_register(void);
+extern void irda_nl_unregister(void);
+
 extern int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
 			    struct packet_type *ptype,
 			    struct net_device *orig_dev);
diff --git a/include/net/irda/irlap.h b/include/net/irda/irlap.h
index a3d370e..9d0c78ea 100644
--- a/include/net/irda/irlap.h
+++ b/include/net/irda/irlap.h
@@ -208,6 +208,8 @@
 	int    xbofs_delay;   /* Nr of XBOF's used to MTT */
 	int    bofs_count;    /* Negotiated extra BOFs */
 	int    next_bofs;     /* Negotiated extra BOFs after next frame */
+
+	int    mode;     /* IrLAP mode (primary, secondary or monitor) */
 };
 
 /* 
diff --git a/include/net/mip6.h b/include/net/mip6.h
index 68263c6..6327261 100644
--- a/include/net/mip6.h
+++ b/include/net/mip6.h
@@ -54,8 +54,4 @@
 #define IP6_MH_TYPE_BERROR	7   /* Binding Error */
 #define IP6_MH_TYPE_MAX		IP6_MH_TYPE_BERROR
 
-extern int mip6_init(void);
-extern void mip6_fini(void);
-extern int mip6_mh_filter(struct sock *sk, struct sk_buff *skb);
-
 #endif
diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
index 1401ccc..3ed4e14 100644
--- a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
+++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
@@ -9,29 +9,8 @@
 #ifndef _NF_CONNTRACK_IPV4_H
 #define _NF_CONNTRACK_IPV4_H
 
-#ifdef CONFIG_NF_NAT_NEEDED
-#include <net/netfilter/nf_nat.h>
-#include <linux/netfilter/nf_conntrack_pptp.h>
-
-/* per conntrack: nat application helper private data */
-union nf_conntrack_nat_help {
-        /* insert nat helper private data here */
-	struct nf_nat_pptp nat_pptp_info;
-};
-
-struct nf_conn_nat {
-	struct nf_nat_info info;
-	union nf_conntrack_nat_help help;
-#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
-	defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
-	int masq_index;
-#endif
-};
-#endif /* CONFIG_NF_NAT_NEEDED */
-
 /* Returns new sk_buff, or NULL */
-struct sk_buff *
-nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb);
+struct sk_buff *nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb);
 
 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4;
 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4;
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 4732432..d4f02eb 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -82,6 +82,8 @@
 
 	union nf_conntrack_help help;
 
+	struct hlist_head expectations;
+
 	/* Current number of expected connections */
 	unsigned int expecting;
 };
@@ -117,9 +119,6 @@
 	/* Unique ID that identifies this conntrack*/
 	unsigned int id;
 
-	/* features - nat, helper, ... used by allocating system */
-	u_int32_t features;
-
 #if defined(CONFIG_NF_CONNTRACK_MARK)
 	u_int32_t mark;
 #endif
@@ -131,8 +130,8 @@
 	/* Storage reserved for other modules: */
 	union nf_conntrack_proto proto;
 
-	/* features dynamically at the end: helper, nat (both optional) */
-	char data[0];
+	/* Extensions */
+	struct nf_ct_ext *ext;
 };
 
 static inline struct nf_conn *
@@ -175,6 +174,10 @@
 extern int nf_ct_l3proto_try_module_get(unsigned short l3proto);
 extern void nf_ct_l3proto_module_put(unsigned short l3proto);
 
+extern struct hlist_head *nf_ct_alloc_hashtable(int *sizep, int *vmalloced);
+extern void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced,
+				 int size);
+
 extern struct nf_conntrack_tuple_hash *
 __nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
 		    const struct nf_conn *ignored_conntrack);
@@ -216,9 +219,6 @@
 				    struct nf_conn *conntrack,
 				    int dir);
 
-/* Call me when a conntrack is destroyed. */
-extern void (*nf_conntrack_destroyed)(struct nf_conn *conntrack);
-
 /* Fake conntrack entry for untracked connections */
 extern struct nf_conn nf_conntrack_untracked;
 
@@ -262,60 +262,10 @@
 	local_bh_enable();				\
 } while (0)
 
-/* no helper, no nat */
-#define	NF_CT_F_BASIC	0
-/* for helper */
-#define	NF_CT_F_HELP	1
-/* for nat. */
-#define	NF_CT_F_NAT	2
-#define NF_CT_F_NUM	4
-
 extern int
 nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size);
 extern void
 nf_conntrack_unregister_cache(u_int32_t features);
 
-/* valid combinations:
- * basic: nf_conn, nf_conn .. nf_conn_help
- * nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat .. nf_conn help
- */
-#ifdef CONFIG_NF_NAT_NEEDED
-static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct)
-{
-	unsigned int offset = sizeof(struct nf_conn);
-
-	if (!(ct->features & NF_CT_F_NAT))
-		return NULL;
-
-	offset = ALIGN(offset, __alignof__(struct nf_conn_nat));
-	return (struct nf_conn_nat *) ((void *)ct + offset);
-}
-
-static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
-{
-	unsigned int offset = sizeof(struct nf_conn);
-
-	if (!(ct->features & NF_CT_F_HELP))
-		return NULL;
-	if (ct->features & NF_CT_F_NAT) {
-		offset = ALIGN(offset, __alignof__(struct nf_conn_nat));
-		offset += sizeof(struct nf_conn_nat);
-	}
-
-	offset = ALIGN(offset, __alignof__(struct nf_conn_help));
-	return (struct nf_conn_help *) ((void *)ct + offset);
-}
-#else /* No NAT */
-static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
-{
-	unsigned int offset = sizeof(struct nf_conn);
-
-	if (!(ct->features & NF_CT_F_HELP))
-		return NULL;
-
-	offset = ALIGN(offset, __alignof__(struct nf_conn_help));
-	return (struct nf_conn_help *) ((void *)ct + offset);
-}
-#endif /* CONFIG_NF_NAT_NEEDED */
 #endif /* __KERNEL__ */
 #endif /* _NF_CONNTRACK_H */
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index 9fb9066..4056f5f 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -30,6 +30,9 @@
 extern int nf_conntrack_proto_init(void);
 extern void nf_conntrack_proto_fini(void);
 
+extern int nf_conntrack_helper_init(void);
+extern void nf_conntrack_helper_fini(void);
+
 struct nf_conntrack_l3proto;
 extern struct nf_conntrack_l3proto *nf_ct_find_l3proto(u_int16_t pf);
 /* Like above, but you already have conntrack read lock. */
@@ -55,8 +58,7 @@
 
 /* Find a connection corresponding to a tuple. */
 extern struct nf_conntrack_tuple_hash *
-nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
-		      const struct nf_conn *ignored_conntrack);
+nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple);
 
 extern int __nf_conntrack_confirm(struct sk_buff **pskb);
 
@@ -81,9 +83,8 @@
 	    struct nf_conntrack_l3proto *l3proto,
 	    struct nf_conntrack_l4proto *proto);
 
-extern struct list_head *nf_conntrack_hash;
-extern struct list_head nf_conntrack_expect_list;
+extern struct hlist_head *nf_conntrack_hash;
 extern rwlock_t nf_conntrack_lock ;
-extern struct list_head unconfirmed;
+extern struct hlist_head unconfirmed;
 
 #endif /* _NF_CONNTRACK_CORE_H */
diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h
index 811c907..f0b9078 100644
--- a/include/net/netfilter/nf_conntrack_ecache.h
+++ b/include/net/netfilter/nf_conntrack_ecache.h
@@ -49,15 +49,15 @@
 		atomic_notifier_call_chain(&nf_conntrack_chain, event, ct);
 }
 
-extern struct atomic_notifier_head nf_conntrack_expect_chain;
-extern int nf_conntrack_expect_register_notifier(struct notifier_block *nb);
-extern int nf_conntrack_expect_unregister_notifier(struct notifier_block *nb);
+extern struct atomic_notifier_head nf_ct_expect_chain;
+extern int nf_ct_expect_register_notifier(struct notifier_block *nb);
+extern int nf_ct_expect_unregister_notifier(struct notifier_block *nb);
 
 static inline void
-nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
-			  struct nf_conntrack_expect *exp)
+nf_ct_expect_event(enum ip_conntrack_expect_events event,
+		   struct nf_conntrack_expect *exp)
 {
-	atomic_notifier_call_chain(&nf_conntrack_expect_chain, event, exp);
+	atomic_notifier_call_chain(&nf_ct_expect_chain, event, exp);
 }
 
 #else /* CONFIG_NF_CONNTRACK_EVENTS */
@@ -67,9 +67,8 @@
 static inline void nf_conntrack_event(enum ip_conntrack_events event,
 				      struct nf_conn *ct) {}
 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
-static inline void
-nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
-			  struct nf_conntrack_expect *exp) {}
+static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
+				      struct nf_conntrack_expect *exp) {}
 static inline void nf_ct_event_cache_flush(void) {}
 #endif /* CONFIG_NF_CONNTRACK_EVENTS */
 
diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h
index 173c7c1..cae1a0d 100644
--- a/include/net/netfilter/nf_conntrack_expect.h
+++ b/include/net/netfilter/nf_conntrack_expect.h
@@ -6,17 +6,21 @@
 #define _NF_CONNTRACK_EXPECT_H
 #include <net/netfilter/nf_conntrack.h>
 
-extern struct list_head nf_conntrack_expect_list;
-extern struct kmem_cache *nf_conntrack_expect_cachep;
-extern const struct file_operations exp_file_ops;
+extern struct hlist_head *nf_ct_expect_hash;
+extern unsigned int nf_ct_expect_hsize;
+extern unsigned int nf_ct_expect_max;
 
 struct nf_conntrack_expect
 {
-	/* Internal linked list (global expectation list) */
-	struct list_head list;
+	/* Conntrack expectation list member */
+	struct hlist_node lnode;
+
+	/* Hash member */
+	struct hlist_node hnode;
 
 	/* We expect this tuple, with the following mask */
-	struct nf_conntrack_tuple tuple, mask;
+	struct nf_conntrack_tuple tuple;
+	struct nf_conntrack_tuple_mask mask;
 
 	/* Function to call after setup and insertion */
 	void (*expectfn)(struct nf_conn *new,
@@ -52,29 +56,31 @@
 
 #define NF_CT_EXPECT_PERMANENT 0x1
 
+int nf_conntrack_expect_init(void);
+void nf_conntrack_expect_fini(void);
 
 struct nf_conntrack_expect *
-__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple);
+__nf_ct_expect_find(const struct nf_conntrack_tuple *tuple);
 
 struct nf_conntrack_expect *
-nf_conntrack_expect_find_get(const struct nf_conntrack_tuple *tuple);
+nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple);
 
 struct nf_conntrack_expect *
-find_expectation(const struct nf_conntrack_tuple *tuple);
+nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple);
 
 void nf_ct_unlink_expect(struct nf_conntrack_expect *exp);
 void nf_ct_remove_expectations(struct nf_conn *ct);
-void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp);
+void nf_ct_unexpect_related(struct nf_conntrack_expect *exp);
 
 /* Allocate space for an expectation: this is mandatory before calling
-   nf_conntrack_expect_related.  You will have to call put afterwards. */
-struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me);
-void nf_conntrack_expect_init(struct nf_conntrack_expect *, int,
-			      union nf_conntrack_address *,
-			      union nf_conntrack_address *,
-			      u_int8_t, __be16 *, __be16 *);
-void nf_conntrack_expect_put(struct nf_conntrack_expect *exp);
-int nf_conntrack_expect_related(struct nf_conntrack_expect *expect);
+   nf_ct_expect_related.  You will have to call put afterwards. */
+struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me);
+void nf_ct_expect_init(struct nf_conntrack_expect *, int,
+		       union nf_conntrack_address *,
+		       union nf_conntrack_address *,
+		       u_int8_t, __be16 *, __be16 *);
+void nf_ct_expect_put(struct nf_conntrack_expect *exp);
+int nf_ct_expect_related(struct nf_conntrack_expect *expect);
 
 #endif /*_NF_CONNTRACK_EXPECT_H*/
 
diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h
new file mode 100644
index 0000000..73b5711
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_extend.h
@@ -0,0 +1,85 @@
+#ifndef _NF_CONNTRACK_EXTEND_H
+#define _NF_CONNTRACK_EXTEND_H
+
+#include <net/netfilter/nf_conntrack.h>
+
+enum nf_ct_ext_id
+{
+	NF_CT_EXT_HELPER,
+	NF_CT_EXT_NAT,
+	NF_CT_EXT_NUM,
+};
+
+#define NF_CT_EXT_HELPER_TYPE struct nf_conn_help
+#define NF_CT_EXT_NAT_TYPE struct nf_conn_nat
+
+/* Extensions: optional stuff which isn't permanently in struct. */
+struct nf_ct_ext {
+	u8 offset[NF_CT_EXT_NUM];
+	u8 len;
+	u8 real_len;
+	char data[0];
+};
+
+static inline int nf_ct_ext_exist(const struct nf_conn *ct, u8 id)
+{
+	return (ct->ext && ct->ext->offset[id]);
+}
+
+static inline void *__nf_ct_ext_find(const struct nf_conn *ct, u8 id)
+{
+	if (!nf_ct_ext_exist(ct, id))
+		return NULL;
+
+	return (void *)ct->ext + ct->ext->offset[id];
+}
+#define nf_ct_ext_find(ext, id)	\
+	((id##_TYPE *)__nf_ct_ext_find((ext), (id)))
+
+/* Destroy all relationships */
+extern void __nf_ct_ext_destroy(struct nf_conn *ct);
+static inline void nf_ct_ext_destroy(struct nf_conn *ct)
+{
+	if (ct->ext)
+		__nf_ct_ext_destroy(ct);
+}
+
+/* Free operation. If you want to free a object referred from private area,
+ * please implement __nf_ct_ext_free() and call it.
+ */
+static inline void nf_ct_ext_free(struct nf_conn *ct)
+{
+	if (ct->ext)
+		kfree(ct->ext);
+}
+
+/* Add this type, returns pointer to data or NULL. */
+void *
+__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp);
+#define nf_ct_ext_add(ct, id, gfp) \
+	((id##_TYPE *)__nf_ct_ext_add((ct), (id), (gfp)))
+
+#define NF_CT_EXT_F_PREALLOC	0x0001
+
+struct nf_ct_ext_type
+{
+	/* Destroys relationships (can be NULL). */
+	void (*destroy)(struct nf_conn *ct);
+	/* Called when realloacted (can be NULL).
+	   Contents has already been moved. */
+	void (*move)(struct nf_conn *ct, void *old);
+
+	enum nf_ct_ext_id id;
+
+	unsigned int flags;
+
+	/* Length and min alignment. */
+	u8 len;
+	u8 align;
+	/* initial size of nf_ct_ext. */
+	u8 alloc_size;
+};
+
+int nf_ct_extend_register(struct nf_ct_ext_type *type);
+void nf_ct_extend_unregister(struct nf_ct_ext_type *type);
+#endif /* _NF_CONNTRACK_EXTEND_H */
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index 8c72ac9..d04f999 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -10,12 +10,13 @@
 #ifndef _NF_CONNTRACK_HELPER_H
 #define _NF_CONNTRACK_HELPER_H
 #include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_extend.h>
 
 struct module;
 
 struct nf_conntrack_helper
-{	
-	struct list_head list; 		/* Internal use. */
+{
+	struct hlist_node hnode;	/* Internal use. */
 
 	const char *name;		/* name of the module */
 	struct module *me;		/* pointer to self */
@@ -23,10 +24,9 @@
 					 * expected connections */
 	unsigned int timeout;		/* timeout for expecteds */
 
-	/* Mask of things we will help (compared against server response) */
+	/* Tuple of things we will help (compared against server response) */
 	struct nf_conntrack_tuple tuple;
-	struct nf_conntrack_tuple mask;
-	
+
 	/* Function to call when data passes; return verdict, or -1 to
            invalidate. */
 	int (*help)(struct sk_buff **pskb,
@@ -52,4 +52,10 @@
 extern int nf_conntrack_helper_register(struct nf_conntrack_helper *);
 extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);
 
+extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp);
+
+static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
+{
+	return nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
+}
 #endif /*_NF_CONNTRACK_HELPER_H*/
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 96a58d8..890752d 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -64,8 +64,6 @@
 	int (*prepare)(struct sk_buff **pskb, unsigned int hooknum,
 		       unsigned int *dataoff, u_int8_t *protonum);
 
-	u_int32_t (*get_features)(const struct nf_conntrack_tuple *tuple);
-
 	int (*tuple_to_nfattr)(struct sk_buff *skb,
 			       const struct nf_conntrack_tuple *t);
 
diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
index 5d72b16..040dae5 100644
--- a/include/net/netfilter/nf_conntrack_tuple.h
+++ b/include/net/netfilter/nf_conntrack_tuple.h
@@ -100,6 +100,14 @@
 	} dst;
 };
 
+struct nf_conntrack_tuple_mask
+{
+	struct {
+		union nf_conntrack_address u3;
+		union nf_conntrack_man_proto u;
+	} src;
+};
+
 /* This is optimized opposed to a memset of the whole structure.  Everything we
  * really care about is the  source/destination unions */
 #define NF_CT_TUPLE_U_BLANK(tuple)                              	\
@@ -112,11 +120,11 @@
 
 #ifdef __KERNEL__
 
-#define NF_CT_DUMP_TUPLE(tp)						    \
-DEBUGP("tuple %p: %u %u " NIP6_FMT " %hu -> " NIP6_FMT " %hu\n",	    \
-	(tp), (tp)->src.l3num, (tp)->dst.protonum,			    \
-	NIP6(*(struct in6_addr *)(tp)->src.u3.all), ntohs((tp)->src.u.all), \
-	NIP6(*(struct in6_addr *)(tp)->dst.u3.all), ntohs((tp)->dst.u.all))
+#define NF_CT_DUMP_TUPLE(tp)						     \
+pr_debug("tuple %p: %u %u " NIP6_FMT " %hu -> " NIP6_FMT " %hu\n",	     \
+	 (tp), (tp)->src.l3num, (tp)->dst.protonum,			     \
+	 NIP6(*(struct in6_addr *)(tp)->src.u3.all), ntohs((tp)->src.u.all), \
+	 NIP6(*(struct in6_addr *)(tp)->dst.u3.all), ntohs((tp)->dst.u.all))
 
 /* If we're the first tuple, it's the original dir. */
 #define NF_CT_DIRECTION(h)						\
@@ -125,8 +133,7 @@
 /* Connections have two entries in the hash table: one for each way */
 struct nf_conntrack_tuple_hash
 {
-	struct list_head list;
-
+	struct hlist_node hnode;
 	struct nf_conntrack_tuple tuple;
 };
 
@@ -162,31 +169,44 @@
 	return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2);
 }
 
+static inline int nf_ct_tuple_mask_equal(const struct nf_conntrack_tuple_mask *m1,
+					 const struct nf_conntrack_tuple_mask *m2)
+{
+	return (m1->src.u3.all[0] == m2->src.u3.all[0] &&
+		m1->src.u3.all[1] == m2->src.u3.all[1] &&
+		m1->src.u3.all[2] == m2->src.u3.all[2] &&
+		m1->src.u3.all[3] == m2->src.u3.all[3] &&
+		m1->src.u.all == m2->src.u.all);
+}
+
+static inline int nf_ct_tuple_src_mask_cmp(const struct nf_conntrack_tuple *t1,
+					   const struct nf_conntrack_tuple *t2,
+					   const struct nf_conntrack_tuple_mask *mask)
+{
+	int count;
+
+	for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++) {
+		if ((t1->src.u3.all[count] ^ t2->src.u3.all[count]) &
+		    mask->src.u3.all[count])
+			return 0;
+	}
+
+	if ((t1->src.u.all ^ t2->src.u.all) & mask->src.u.all)
+		return 0;
+
+	if (t1->src.l3num != t2->src.l3num ||
+	    t1->dst.protonum != t2->dst.protonum)
+		return 0;
+
+	return 1;
+}
+
 static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
 				       const struct nf_conntrack_tuple *tuple,
-				       const struct nf_conntrack_tuple *mask)
+				       const struct nf_conntrack_tuple_mask *mask)
 {
-	int count = 0;
-
-        for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
-                if ((t->src.u3.all[count] ^ tuple->src.u3.all[count]) &
-                    mask->src.u3.all[count])
-                        return 0;
-        }
-
-        for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
-                if ((t->dst.u3.all[count] ^ tuple->dst.u3.all[count]) &
-                    mask->dst.u3.all[count])
-                        return 0;
-        }
-
-        if ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all ||
-            (t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all ||
-            (t->src.l3num ^ tuple->src.l3num) & mask->src.l3num ||
-            (t->dst.protonum ^ tuple->dst.protonum) & mask->dst.protonum)
-                return 0;
-
-        return 1;
+	return nf_ct_tuple_src_mask_cmp(t, tuple, mask) &&
+	       nf_ct_tuple_dst_equal(t, tuple);
 }
 
 #endif /* _NF_CONNTRACK_TUPLE_H */
diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
index bc57dd7..6ae52f7 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -51,16 +51,31 @@
 
 #ifdef __KERNEL__
 #include <linux/list.h>
+#include <linux/netfilter/nf_conntrack_pptp.h>
+#include <net/netfilter/nf_conntrack_extend.h>
 
-/* The structure embedded in the conntrack structure. */
-struct nf_nat_info
+/* per conntrack: nat application helper private data */
+union nf_conntrack_nat_help
 {
-	struct list_head bysource;
-	struct nf_nat_seq seq[IP_CT_DIR_MAX];
+	/* insert nat helper private data here */
+	struct nf_nat_pptp nat_pptp_info;
 };
 
 struct nf_conn;
 
+/* The structure embedded in the conntrack structure. */
+struct nf_conn_nat
+{
+	struct hlist_node bysource;
+	struct nf_nat_seq seq[IP_CT_DIR_MAX];
+	struct nf_conn *ct;
+	union nf_conntrack_nat_help help;
+#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
+    defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
+	int masq_index;
+#endif
+};
+
 /* Set up the info structure to map into this range. */
 extern unsigned int nf_nat_setup_info(struct nf_conn *ct,
 				      const struct nf_nat_range *range,
@@ -70,7 +85,10 @@
 extern int nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple,
 			     const struct nf_conn *ignored_conntrack);
 
-extern int nf_nat_module_is_loaded;
+static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct)
+{
+	return nf_ct_ext_find(ct, NF_CT_EXT_NAT);
+}
 
 #else  /* !__KERNEL__: iptables wants this to compile. */
 #define nf_nat_multi_range nf_nat_multi_range_compat
diff --git a/include/net/netfilter/nf_nat_core.h b/include/net/netfilter/nf_nat_core.h
index 9778ffa..c3cd127 100644
--- a/include/net/netfilter/nf_nat_core.h
+++ b/include/net/netfilter/nf_nat_core.h
@@ -2,6 +2,7 @@
 #define _NF_NAT_CORE_H
 #include <linux/list.h>
 #include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_nat.h>
 
 /* This header used to share core functionality between the standalone
    NAT module, and the compatibility layer's use of NAT for masquerading. */
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 7b510a9..d7b824b 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -118,6 +118,9 @@
  * Nested Attributes Construction:
  *   nla_nest_start(skb, type)		start a nested attribute
  *   nla_nest_end(skb, nla)		finalize a nested attribute
+ *   nla_nest_compat_start(skb, type,	start a nested compat attribute
+ *			   len, data)
+ *   nla_nest_compat_end(skb, type)	finalize a nested compat attribute
  *   nla_nest_cancel(skb, nla)		cancel nested attribute construction
  *
  * Attribute Length Calculations:
@@ -152,6 +155,7 @@
  *   nla_find_nested()			find attribute in nested attributes
  *   nla_parse()			parse and validate stream of attrs
  *   nla_parse_nested()			parse nested attribuets
+ *   nla_parse_nested_compat()		parse nested compat attributes
  *   nla_for_each_attr()		loop over all attributes
  *   nla_for_each_nested()		loop over the nested attributes
  *=========================================================================
@@ -170,6 +174,7 @@
 	NLA_FLAG,
 	NLA_MSECS,
 	NLA_NESTED,
+	NLA_NESTED_COMPAT,
 	NLA_NUL_STRING,
 	NLA_BINARY,
 	__NLA_TYPE_MAX,
@@ -190,6 +195,7 @@
  *    NLA_NUL_STRING       Maximum length of string (excluding NUL)
  *    NLA_FLAG             Unused
  *    NLA_BINARY           Maximum length of attribute payload
+ *    NLA_NESTED_COMPAT    Exact length of structure payload
  *    All other            Exact length of attribute payload
  *
  * Example:
@@ -733,6 +739,39 @@
 {
 	return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
 }
+
+/**
+ * nla_parse_nested_compat - parse nested compat attributes
+ * @tb: destination array with maxtype+1 elements
+ * @maxtype: maximum attribute type to be expected
+ * @nla: attribute containing the nested attributes
+ * @data: pointer to point to contained structure
+ * @len: length of contained structure
+ * @policy: validation policy
+ *
+ * Parse a nested compat attribute. The compat attribute contains a structure
+ * and optionally a set of nested attributes. On success the data pointer
+ * points to the nested data and tb contains the parsed attributes
+ * (see nla_parse).
+ */
+static inline int __nla_parse_nested_compat(struct nlattr *tb[], int maxtype,
+					    struct nlattr *nla,
+					    const struct nla_policy *policy,
+					    int len)
+{
+	if (nla_len(nla) < len)
+		return -1;
+	if (nla_len(nla) >= NLA_ALIGN(len) + sizeof(struct nlattr))
+		return nla_parse_nested(tb, maxtype,
+					nla_data(nla) + NLA_ALIGN(len),
+					policy);
+	memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
+	return 0;
+}
+
+#define nla_parse_nested_compat(tb, maxtype, nla, policy, data, len) \
+({	data = nla_len(nla) >= len ? nla_data(nla) : NULL; \
+	__nla_parse_nested_compat(tb, maxtype, nla, policy, len); })
 /**
  * nla_put_u8 - Add a u16 netlink attribute to a socket buffer
  * @skb: socket buffer to add attribute to
@@ -965,6 +1004,51 @@
 }
 
 /**
+ * nla_nest_compat_start - Start a new level of nested compat attributes
+ * @skb: socket buffer to add attributes to
+ * @attrtype: attribute type of container
+ * @attrlen: length of structure
+ * @data: pointer to structure
+ *
+ * Start a nested compat attribute that contains both a structure and
+ * a set of nested attributes.
+ *
+ * Returns the container attribute
+ */
+static inline struct nlattr *nla_nest_compat_start(struct sk_buff *skb,
+						   int attrtype, int attrlen,
+						   const void *data)
+{
+	struct nlattr *start = (struct nlattr *)skb_tail_pointer(skb);
+
+	if (nla_put(skb, attrtype, attrlen, data) < 0)
+		return NULL;
+	if (nla_nest_start(skb, attrtype) == NULL) {
+		nlmsg_trim(skb, start);
+		return NULL;
+	}
+	return start;
+}
+
+/**
+ * nla_nest_compat_end - Finalize nesting of compat attributes
+ * @skb: socket buffer the attribtues are stored in
+ * @start: container attribute
+ *
+ * Corrects the container attribute header to include the all
+ * appeneded attributes.
+ *
+ * Returns the total data length of the skb.
+ */
+static inline int nla_nest_compat_end(struct sk_buff *skb, struct nlattr *start)
+{
+	struct nlattr *nest = (void *)start + NLMSG_ALIGN(start->nla_len);
+
+	start->nla_len = skb_tail_pointer(skb) - (unsigned char *)start;
+	return nla_nest_end(skb, nest);
+}
+
+/**
  * nla_nest_cancel - Cancel nesting of attributes
  * @skb: socket buffer the message is stored in
  * @start: container attribute
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 4129df7..6c29920 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -306,6 +306,8 @@
 		return 1;
 }
 
+#define MODULE_ALIAS_TCF_EMATCH(kind)	MODULE_ALIAS("ematch-kind-" __stringify(kind))
+
 #else /* CONFIG_NET_EMATCH */
 
 struct tcf_ematch_tree
diff --git a/include/net/rawv6.h b/include/net/rawv6.h
index af89608..a581989 100644
--- a/include/net/rawv6.h
+++ b/include/net/rawv6.h
@@ -3,6 +3,8 @@
 
 #ifdef __KERNEL__
 
+#include <net/protocol.h>
+
 #define RAWV6_HTABLE_SIZE	MAX_INET_PROTOS
 extern struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE];
 extern rwlock_t raw_v6_lock;
@@ -23,6 +25,13 @@
 					  int type, int code, 
 					  int offset, __be32 info);
 
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
+					   struct sk_buff *skb));
+int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock,
+					     struct sk_buff *skb));
+#endif
+
 #endif
 
 #endif
diff --git a/include/net/route.h b/include/net/route.h
index 749e4df..f7ce625 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -62,7 +62,6 @@
 	
 	unsigned		rt_flags;
 	__u16			rt_type;
-	__u16			rt_multipath_alg;
 
 	__be32			rt_dst;	/* Path destination	*/
 	__be32			rt_src;	/* Path source		*/
@@ -136,7 +135,7 @@
 
 #define IPTOS_RT_MASK	(IPTOS_TOS_MASK & ~3)
 
-extern __u8 ip_tos2prio[16];
+extern const __u8 ip_tos2prio[16];
 
 static inline char rt_tos2priority(u8 tos)
 {
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 3b3d474..3861c05 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -22,4 +22,62 @@
 		return AF_UNSPEC;
 }
 
+/**
+ *	struct rtnl_link_ops - rtnetlink link operations
+ *
+ *	@list: Used internally
+ *	@kind: Identifier
+ *	@maxtype: Highest device specific netlink attribute number
+ *	@policy: Netlink policy for device specific attribute validation
+ *	@validate: Optional validation function for netlink/changelink parameters
+ *	@priv_size: sizeof net_device private space
+ *	@setup: net_device setup function
+ *	@newlink: Function for configuring and registering a new device
+ *	@changelink: Function for changing parameters of an existing device
+ *	@dellink: Function to remove a device
+ *	@get_size: Function to calculate required room for dumping device
+ *		   specific netlink attributes
+ *	@fill_info: Function to dump device specific netlink attributes
+ *	@get_xstats_size: Function to calculate required room for dumping devic
+ *			  specific statistics
+ *	@fill_xstats: Function to dump device specific statistics
+ */
+struct rtnl_link_ops {
+	struct list_head	list;
+
+	const char		*kind;
+
+	size_t			priv_size;
+	void			(*setup)(struct net_device *dev);
+
+	int			maxtype;
+	const struct nla_policy	*policy;
+	int			(*validate)(struct nlattr *tb[],
+					    struct nlattr *data[]);
+
+	int			(*newlink)(struct net_device *dev,
+					   struct nlattr *tb[],
+					   struct nlattr *data[]);
+	int			(*changelink)(struct net_device *dev,
+					      struct nlattr *tb[],
+					      struct nlattr *data[]);
+	void			(*dellink)(struct net_device *dev);
+
+	size_t			(*get_size)(const struct net_device *dev);
+	int			(*fill_info)(struct sk_buff *skb,
+					     const struct net_device *dev);
+
+	size_t			(*get_xstats_size)(const struct net_device *dev);
+	int			(*fill_xstats)(struct sk_buff *skb,
+					       const struct net_device *dev);
+};
+
+extern int	__rtnl_link_register(struct rtnl_link_ops *ops);
+extern void	__rtnl_link_unregister(struct rtnl_link_ops *ops);
+
+extern int	rtnl_link_register(struct rtnl_link_ops *ops);
+extern void	rtnl_link_unregister(struct rtnl_link_ops *ops);
+
+#define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind)
+
 #endif
diff --git a/include/net/tipc/tipc_port.h b/include/net/tipc/tipc_port.h
index 333bba6..cfc4ba4 100644
--- a/include/net/tipc/tipc_port.h
+++ b/include/net/tipc/tipc_port.h
@@ -1,8 +1,8 @@
 /*
  * include/net/tipc/tipc_port.h: Include file for privileged access to TIPC ports
  * 
- * Copyright (c) 1994-2006, Ericsson AB
- * Copyright (c) 2005, Wind River Systems
+ * Copyright (c) 1994-2007, Ericsson AB
+ * Copyright (c) 2005-2007, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -55,6 +55,7 @@
  * @conn_unacked: number of unacknowledged messages received from peer port
  * @published: non-zero if port has one or more associated names
  * @congested: non-zero if cannot send because of link or port congestion
+ * @max_pkt: maximum packet size "hint" used when building messages sent by port
  * @ref: unique reference to port in TIPC object registry
  * @phdr: preformatted message header used when sending messages
  */
@@ -68,6 +69,7 @@
 	u32 conn_unacked;
 	int published;
 	u32 congested;
+	u32 max_pkt;
 	u32 ref;
 	struct tipc_msg phdr;
 };
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 311f25a..ae959e9 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -19,9 +19,19 @@
 #include <net/ipv6.h>
 #include <net/ip6_fib.h>
 
+#define XFRM_PROTO_ESP		50
+#define XFRM_PROTO_AH		51
+#define XFRM_PROTO_COMP		108
+#define XFRM_PROTO_IPIP		4
+#define XFRM_PROTO_IPV6		41
+#define XFRM_PROTO_ROUTING	IPPROTO_ROUTING
+#define XFRM_PROTO_DSTOPTS	IPPROTO_DSTOPTS
+
 #define XFRM_ALIGN8(len)	(((len) + 7) & ~7)
 #define MODULE_ALIAS_XFRM_MODE(family, encap) \
 	MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap))
+#define MODULE_ALIAS_XFRM_TYPE(family, proto) \
+	MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
 
 extern struct sock *xfrm_nl;
 extern u32 sysctl_xfrm_aevent_etime;
@@ -509,11 +519,9 @@
 	case IPPROTO_ICMPV6:
 		port = htons(fl->fl_icmp_type);
 		break;
-#ifdef CONFIG_IPV6_MIP6
 	case IPPROTO_MH:
 		port = htons(fl->fl_mh_type);
 		break;
-#endif
 	default:
 		port = 0;	/*XXX*/
 	}
@@ -920,6 +928,10 @@
 					  struct flowi *fl, struct xfrm_tmpl *tmpl,
 					  struct xfrm_policy *pol, int *err,
 					  unsigned short family);
+extern struct xfrm_state * xfrm_stateonly_find(xfrm_address_t *daddr,
+					       xfrm_address_t *saddr,
+					       unsigned short family,
+					       u8 mode, u8 proto, u32 reqid);
 extern int xfrm_state_check_expire(struct xfrm_state *x);
 extern void xfrm_state_insert(struct xfrm_state *x);
 extern int xfrm_state_add(struct xfrm_state *x);
@@ -991,7 +1003,7 @@
 				 u8 **prevhdr);
 
 #ifdef CONFIG_XFRM
-extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type);
+extern int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
 extern int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen);
 extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family);
 #else
@@ -1000,12 +1012,13 @@
  	return -ENOPROTOOPT;
 } 
 
-static inline int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
+static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
 {
  	/* should not happen */
  	kfree_skb(skb);
 	return 0;
 }
+
 static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family)
 {
 	return -EINVAL;
diff --git a/kernel/module.c b/kernel/module.c
index 9bd93de..015d60c 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -488,8 +488,7 @@
         mod->field = NULL;                                            \
 }                                                                     \
 static struct module_attribute modinfo_##field = {                    \
-	.attr = { .name = __stringify(field), .mode = 0444,           \
-		  .owner = THIS_MODULE },                             \
+	.attr = { .name = __stringify(field), .mode = 0444 },         \
 	.show = show_modinfo_##field,                                 \
 	.setup = setup_modinfo_##field,                               \
 	.test = modinfo_##field##_exists,                             \
@@ -793,7 +792,7 @@
 }
 
 static struct module_attribute refcnt = {
-	.attr = { .name = "refcnt", .mode = 0444, .owner = THIS_MODULE },
+	.attr = { .name = "refcnt", .mode = 0444 },
 	.show = show_refcnt,
 };
 
@@ -851,7 +850,7 @@
 }
 
 static struct module_attribute initstate = {
-	.attr = { .name = "initstate", .mode = 0444, .owner = THIS_MODULE },
+	.attr = { .name = "initstate", .mode = 0444 },
 	.show = show_initstate,
 };
 
@@ -1032,7 +1031,6 @@
 		sattr->mattr.show = module_sect_show;
 		sattr->mattr.store = NULL;
 		sattr->mattr.attr.name = sattr->name;
-		sattr->mattr.attr.owner = mod;
 		sattr->mattr.attr.mode = S_IRUGO;
 		*(gattr++) = &(sattr++)->mattr.attr;
 	}
@@ -1090,7 +1088,6 @@
 		if (!attr->test ||
 		    (attr->test && attr->test(mod))) {
 			memcpy(temp_attr, attr, sizeof(*temp_attr));
-			temp_attr->attr.owner = mod;
 			error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr);
 			++temp_attr;
 		}
diff --git a/kernel/params.c b/kernel/params.c
index e61c46c..effbaae 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -491,7 +491,6 @@
 			pattr->mattr.show = param_attr_show;
 			pattr->mattr.store = param_attr_store;
 			pattr->mattr.attr.name = (char *)&kp->name[name_skip];
-			pattr->mattr.attr.owner = mk->mod;
 			pattr->mattr.attr.mode = kp->perm;
 			*(gattr++) = &(pattr++)->mattr.attr;
 		}
diff --git a/lib/idr.c b/lib/idr.c
index 305117c..b98f01a 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -70,6 +70,26 @@
 	spin_unlock_irqrestore(&idp->lock, flags);
 }
 
+static void idr_mark_full(struct idr_layer **pa, int id)
+{
+	struct idr_layer *p = pa[0];
+	int l = 0;
+
+	__set_bit(id & IDR_MASK, &p->bitmap);
+	/*
+	 * If this layer is full mark the bit in the layer above to
+	 * show that this part of the radix tree is full.  This may
+	 * complete the layer above and require walking up the radix
+	 * tree.
+	 */
+	while (p->bitmap == IDR_FULL) {
+		if (!(p = pa[++l]))
+			break;
+		id = id >> IDR_BITS;
+		__set_bit((id & IDR_MASK), &p->bitmap);
+	}
+}
+
 /**
  * idr_pre_get - reserver resources for idr allocation
  * @idp:	idr handle
@@ -95,15 +115,15 @@
 }
 EXPORT_SYMBOL(idr_pre_get);
 
-static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
+static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
 {
 	int n, m, sh;
 	struct idr_layer *p, *new;
-	struct idr_layer *pa[MAX_LEVEL];
-	int l, id;
+	int l, id, oid;
 	long bm;
 
 	id = *starting_id;
+ restart:
 	p = idp->top;
 	l = idp->layers;
 	pa[l--] = NULL;
@@ -117,12 +137,23 @@
 		if (m == IDR_SIZE) {
 			/* no space available go back to previous layer. */
 			l++;
+			oid = id;
 			id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1;
+
+			/* if already at the top layer, we need to grow */
 			if (!(p = pa[l])) {
 				*starting_id = id;
 				return -2;
 			}
-			continue;
+
+			/* If we need to go up one layer, continue the
+			 * loop; otherwise, restart from the top.
+			 */
+			sh = IDR_BITS * (l + 1);
+			if (oid >> sh == id >> sh)
+				continue;
+			else
+				goto restart;
 		}
 		if (m != n) {
 			sh = IDR_BITS*l;
@@ -144,30 +175,13 @@
 		pa[l--] = p;
 		p = p->ary[m];
 	}
-	/*
-	 * We have reached the leaf node, plant the
-	 * users pointer and return the raw id.
-	 */
-	p->ary[m] = (struct idr_layer *)ptr;
-	__set_bit(m, &p->bitmap);
-	p->count++;
-	/*
-	 * If this layer is full mark the bit in the layer above
-	 * to show that this part of the radix tree is full.
-	 * This may complete the layer above and require walking
-	 * up the radix tree.
-	 */
-	n = id;
-	while (p->bitmap == IDR_FULL) {
-		if (!(p = pa[++l]))
-			break;
-		n = n >> IDR_BITS;
-		__set_bit((n & IDR_MASK), &p->bitmap);
-	}
-	return(id);
+
+	pa[l] = p;
+	return id;
 }
 
-static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
+static int idr_get_empty_slot(struct idr *idp, int starting_id,
+			      struct idr_layer **pa)
 {
 	struct idr_layer *p, *new;
 	int layers, v, id;
@@ -213,12 +227,31 @@
 	}
 	idp->top = p;
 	idp->layers = layers;
-	v = sub_alloc(idp, ptr, &id);
+	v = sub_alloc(idp, &id, pa);
 	if (v == -2)
 		goto build_up;
 	return(v);
 }
 
+static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
+{
+	struct idr_layer *pa[MAX_LEVEL];
+	int id;
+
+	id = idr_get_empty_slot(idp, starting_id, pa);
+	if (id >= 0) {
+		/*
+		 * Successfully found an empty slot.  Install the user
+		 * pointer and mark the slot full.
+		 */
+		pa[0]->ary[id & IDR_MASK] = (struct idr_layer *)ptr;
+		pa[0]->count++;
+		idr_mark_full(pa, id);
+	}
+
+	return id;
+}
+
 /**
  * idr_get_new_above - allocate new idr entry above or equal to a start id
  * @idp: idr handle
@@ -473,3 +506,248 @@
 	spin_lock_init(&idp->lock);
 }
 EXPORT_SYMBOL(idr_init);
+
+
+/*
+ * IDA - IDR based ID allocator
+ *
+ * this is id allocator without id -> pointer translation.  Memory
+ * usage is much lower than full blown idr because each id only
+ * occupies a bit.  ida uses a custom leaf node which contains
+ * IDA_BITMAP_BITS slots.
+ *
+ * 2007-04-25  written by Tejun Heo <htejun@gmail.com>
+ */
+
+static void free_bitmap(struct ida *ida, struct ida_bitmap *bitmap)
+{
+	unsigned long flags;
+
+	if (!ida->free_bitmap) {
+		spin_lock_irqsave(&ida->idr.lock, flags);
+		if (!ida->free_bitmap) {
+			ida->free_bitmap = bitmap;
+			bitmap = NULL;
+		}
+		spin_unlock_irqrestore(&ida->idr.lock, flags);
+	}
+
+	kfree(bitmap);
+}
+
+/**
+ * ida_pre_get - reserve resources for ida allocation
+ * @ida:	ida handle
+ * @gfp_mask:	memory allocation flag
+ *
+ * This function should be called prior to locking and calling the
+ * following function.  It preallocates enough memory to satisfy the
+ * worst possible allocation.
+ *
+ * If the system is REALLY out of memory this function returns 0,
+ * otherwise 1.
+ */
+int ida_pre_get(struct ida *ida, gfp_t gfp_mask)
+{
+	/* allocate idr_layers */
+	if (!idr_pre_get(&ida->idr, gfp_mask))
+		return 0;
+
+	/* allocate free_bitmap */
+	if (!ida->free_bitmap) {
+		struct ida_bitmap *bitmap;
+
+		bitmap = kmalloc(sizeof(struct ida_bitmap), gfp_mask);
+		if (!bitmap)
+			return 0;
+
+		free_bitmap(ida, bitmap);
+	}
+
+	return 1;
+}
+EXPORT_SYMBOL(ida_pre_get);
+
+/**
+ * ida_get_new_above - allocate new ID above or equal to a start id
+ * @ida:	ida handle
+ * @staring_id:	id to start search at
+ * @p_id:	pointer to the allocated handle
+ *
+ * Allocate new ID above or equal to @ida.  It should be called with
+ * any required locks.
+ *
+ * If memory is required, it will return -EAGAIN, you should unlock
+ * and go back to the ida_pre_get() call.  If the ida is full, it will
+ * return -ENOSPC.
+ *
+ * @p_id returns a value in the range 0 ... 0x7fffffff.
+ */
+int ida_get_new_above(struct ida *ida, int starting_id, int *p_id)
+{
+	struct idr_layer *pa[MAX_LEVEL];
+	struct ida_bitmap *bitmap;
+	unsigned long flags;
+	int idr_id = starting_id / IDA_BITMAP_BITS;
+	int offset = starting_id % IDA_BITMAP_BITS;
+	int t, id;
+
+ restart:
+	/* get vacant slot */
+	t = idr_get_empty_slot(&ida->idr, idr_id, pa);
+	if (t < 0) {
+		if (t == -1)
+			return -EAGAIN;
+		else /* will be -3 */
+			return -ENOSPC;
+	}
+
+	if (t * IDA_BITMAP_BITS >= MAX_ID_BIT)
+		return -ENOSPC;
+
+	if (t != idr_id)
+		offset = 0;
+	idr_id = t;
+
+	/* if bitmap isn't there, create a new one */
+	bitmap = (void *)pa[0]->ary[idr_id & IDR_MASK];
+	if (!bitmap) {
+		spin_lock_irqsave(&ida->idr.lock, flags);
+		bitmap = ida->free_bitmap;
+		ida->free_bitmap = NULL;
+		spin_unlock_irqrestore(&ida->idr.lock, flags);
+
+		if (!bitmap)
+			return -EAGAIN;
+
+		memset(bitmap, 0, sizeof(struct ida_bitmap));
+		pa[0]->ary[idr_id & IDR_MASK] = (void *)bitmap;
+		pa[0]->count++;
+	}
+
+	/* lookup for empty slot */
+	t = find_next_zero_bit(bitmap->bitmap, IDA_BITMAP_BITS, offset);
+	if (t == IDA_BITMAP_BITS) {
+		/* no empty slot after offset, continue to the next chunk */
+		idr_id++;
+		offset = 0;
+		goto restart;
+	}
+
+	id = idr_id * IDA_BITMAP_BITS + t;
+	if (id >= MAX_ID_BIT)
+		return -ENOSPC;
+
+	__set_bit(t, bitmap->bitmap);
+	if (++bitmap->nr_busy == IDA_BITMAP_BITS)
+		idr_mark_full(pa, idr_id);
+
+	*p_id = id;
+
+	/* Each leaf node can handle nearly a thousand slots and the
+	 * whole idea of ida is to have small memory foot print.
+	 * Throw away extra resources one by one after each successful
+	 * allocation.
+	 */
+	if (ida->idr.id_free_cnt || ida->free_bitmap) {
+		struct idr_layer *p = alloc_layer(&ida->idr);
+		if (p)
+			kmem_cache_free(idr_layer_cache, p);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(ida_get_new_above);
+
+/**
+ * ida_get_new - allocate new ID
+ * @ida:	idr handle
+ * @p_id:	pointer to the allocated handle
+ *
+ * Allocate new ID.  It should be called with any required locks.
+ *
+ * If memory is required, it will return -EAGAIN, you should unlock
+ * and go back to the idr_pre_get() call.  If the idr is full, it will
+ * return -ENOSPC.
+ *
+ * @id returns a value in the range 0 ... 0x7fffffff.
+ */
+int ida_get_new(struct ida *ida, int *p_id)
+{
+	return ida_get_new_above(ida, 0, p_id);
+}
+EXPORT_SYMBOL(ida_get_new);
+
+/**
+ * ida_remove - remove the given ID
+ * @ida:	ida handle
+ * @id:		ID to free
+ */
+void ida_remove(struct ida *ida, int id)
+{
+	struct idr_layer *p = ida->idr.top;
+	int shift = (ida->idr.layers - 1) * IDR_BITS;
+	int idr_id = id / IDA_BITMAP_BITS;
+	int offset = id % IDA_BITMAP_BITS;
+	int n;
+	struct ida_bitmap *bitmap;
+
+	/* clear full bits while looking up the leaf idr_layer */
+	while ((shift > 0) && p) {
+		n = (idr_id >> shift) & IDR_MASK;
+		__clear_bit(n, &p->bitmap);
+		p = p->ary[n];
+		shift -= IDR_BITS;
+	}
+
+	if (p == NULL)
+		goto err;
+
+	n = idr_id & IDR_MASK;
+	__clear_bit(n, &p->bitmap);
+
+	bitmap = (void *)p->ary[n];
+	if (!test_bit(offset, bitmap->bitmap))
+		goto err;
+
+	/* update bitmap and remove it if empty */
+	__clear_bit(offset, bitmap->bitmap);
+	if (--bitmap->nr_busy == 0) {
+		__set_bit(n, &p->bitmap);	/* to please idr_remove() */
+		idr_remove(&ida->idr, idr_id);
+		free_bitmap(ida, bitmap);
+	}
+
+	return;
+
+ err:
+	printk(KERN_WARNING
+	       "ida_remove called for id=%d which is not allocated.\n", id);
+}
+EXPORT_SYMBOL(ida_remove);
+
+/**
+ * ida_destroy - release all cached layers within an ida tree
+ * ida:		ida handle
+ */
+void ida_destroy(struct ida *ida)
+{
+	idr_destroy(&ida->idr);
+	kfree(ida->free_bitmap);
+}
+EXPORT_SYMBOL(ida_destroy);
+
+/**
+ * ida_init - initialize ida handle
+ * @ida:	ida handle
+ *
+ * This function is use to set up the handle (@ida) that you will pass
+ * to the rest of the functions.
+ */
+void ida_init(struct ida *ida)
+{
+	memset(ida, 0, sizeof(struct ida));
+	idr_init(&ida->idr);
+
+}
+EXPORT_SYMBOL(ida_init);
diff --git a/lib/kobject.c b/lib/kobject.c
index ac15206..4b08e0f 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -44,7 +44,7 @@
 	return error;
 }
 
-static int create_dir(struct kobject * kobj, struct dentry *shadow_parent)
+static int create_dir(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
 {
 	int error = 0;
 	if (kobject_name(kobj)) {
@@ -162,7 +162,7 @@
  *	@shadow_parent: sysfs directory to add to.
  */
 
-int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
+int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
 {
 	int error = 0;
 	struct kobject * parent;
@@ -338,7 +338,7 @@
 	/* Note : if we want to send the new name alone, not the full path,
 	 * we could probably use kobject_name(kobj); */
 
-	error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name);
+	error = sysfs_rename_dir(kobj, kobj->parent->sd, new_name);
 
 	/* This function is mostly/only used for network interface.
 	 * Some hotplug package track interfaces by their name and
@@ -361,8 +361,8 @@
  *	@new_name: object's new name
  */
 
-int kobject_shadow_rename(struct kobject * kobj, struct dentry *new_parent,
-			  const char *new_name)
+int kobject_shadow_rename(struct kobject *kobj,
+			  struct sysfs_dirent *new_parent, const char *new_name)
 {
 	int error = 0;
 
@@ -597,10 +597,17 @@
 
 int kset_register(struct kset * k)
 {
+	int err;
+
 	if (!k)
 		return -EINVAL;
+
 	kset_init(k);
-	return kset_add(k);
+	err = kset_add(k);
+	if (err)
+		return err;
+	kobject_uevent(&k->kobj, KOBJ_ADD);
+	return 0;
 }
 
 
diff --git a/net/802/tr.c b/net/802/tr.c
index 0ba1946..e56e61a 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -567,7 +567,7 @@
 }
 
 
-static struct seq_operations rif_seq_ops = {
+static const struct seq_operations rif_seq_ops = {
 	.start = rif_seq_start,
 	.next  = rif_seq_next,
 	.stop  = rif_seq_stop,
diff --git a/net/8021q/Makefile b/net/8021q/Makefile
index 97feb44..10ca7f4 100644
--- a/net/8021q/Makefile
+++ b/net/8021q/Makefile
@@ -4,7 +4,7 @@
 
 obj-$(CONFIG_VLAN_8021Q) += 8021q.o
 
-8021q-objs := vlan.o vlan_dev.o
+8021q-objs := vlan.o vlan_dev.o vlan_netlink.o
 
 ifeq ($(CONFIG_PROC_FS),y)
 8021q-objs += vlanproc.o
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index de78c9d..abb9900 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -97,35 +97,22 @@
 
 	/* Register us to receive netdevice events */
 	err = register_netdevice_notifier(&vlan_notifier_block);
-	if (err < 0) {
-		dev_remove_pack(&vlan_packet_type);
-		vlan_proc_cleanup();
-		return err;
-	}
+	if (err < 0)
+		goto err1;
+
+	err = vlan_netlink_init();
+	if (err < 0)
+		goto err2;
 
 	vlan_ioctl_set(vlan_ioctl_handler);
-
 	return 0;
-}
 
-/* Cleanup all vlan devices
- * Note: devices that have been registered that but not
- * brought up will exist but have no module ref count.
- */
-static void __exit vlan_cleanup_devices(void)
-{
-	struct net_device *dev, *nxt;
-
-	rtnl_lock();
-	for_each_netdev_safe(dev, nxt) {
-		if (dev->priv_flags & IFF_802_1Q_VLAN) {
-			unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
-					    VLAN_DEV_INFO(dev)->vlan_id);
-
-			unregister_netdevice(dev);
-		}
-	}
-	rtnl_unlock();
+err2:
+	unregister_netdevice_notifier(&vlan_notifier_block);
+err1:
+	vlan_proc_cleanup();
+	dev_remove_pack(&vlan_packet_type);
+	return err;
 }
 
 /*
@@ -136,13 +123,13 @@
 {
 	int i;
 
+	vlan_netlink_fini();
 	vlan_ioctl_set(NULL);
 
 	/* Un-register us from receiving netdevice events */
 	unregister_netdevice_notifier(&vlan_notifier_block);
 
 	dev_remove_pack(&vlan_packet_type);
-	vlan_cleanup_devices();
 
 	/* This table must be empty if there are no module
 	 * references left.
@@ -197,6 +184,34 @@
 	kfree(grp);
 }
 
+static struct vlan_group *vlan_group_alloc(int ifindex)
+{
+	struct vlan_group *grp;
+	unsigned int size;
+	unsigned int i;
+
+	grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL);
+	if (!grp)
+		return NULL;
+
+	size = sizeof(struct net_device *) * VLAN_GROUP_ARRAY_PART_LEN;
+
+	for (i = 0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) {
+		grp->vlan_devices_arrays[i] = kzalloc(size, GFP_KERNEL);
+		if (!grp->vlan_devices_arrays[i])
+			goto err;
+	}
+
+	grp->real_dev_ifindex = ifindex;
+	hlist_add_head_rcu(&grp->hlist,
+			   &vlan_group_hash[vlan_grp_hashfn(ifindex)]);
+	return grp;
+
+err:
+	vlan_group_free(grp);
+	return NULL;
+}
+
 static void vlan_rcu_free(struct rcu_head *rcu)
 {
 	vlan_group_free(container_of(rcu, struct vlan_group, rcu));
@@ -278,50 +293,66 @@
 	return ret;
 }
 
-static int unregister_vlan_device(const char *vlan_IF_name)
+int unregister_vlan_device(struct net_device *dev)
 {
-	struct net_device *dev = NULL;
 	int ret;
 
+	ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
+				  VLAN_DEV_INFO(dev)->vlan_id);
+	unregister_netdevice(dev);
 
-	dev = dev_get_by_name(vlan_IF_name);
-	ret = -EINVAL;
-	if (dev) {
-		if (dev->priv_flags & IFF_802_1Q_VLAN) {
-			rtnl_lock();
-
-			ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
-						  VLAN_DEV_INFO(dev)->vlan_id);
-
-			dev_put(dev);
-			unregister_netdevice(dev);
-
-			rtnl_unlock();
-
-			if (ret == 1)
-				ret = 0;
-		} else {
-			printk(VLAN_ERR
-			       "%s: ERROR:	Tried to remove a non-vlan device "
-			       "with VLAN code, name: %s  priv_flags: %hX\n",
-			       __FUNCTION__, dev->name, dev->priv_flags);
-			dev_put(dev);
-			ret = -EPERM;
-		}
-	} else {
-#ifdef VLAN_DEBUG
-		printk(VLAN_DBG "%s: WARNING: Could not find dev.\n", __FUNCTION__);
-#endif
-		ret = -EINVAL;
-	}
-
+	if (ret == 1)
+		ret = 0;
 	return ret;
 }
 
-static void vlan_setup(struct net_device *new_dev)
+/*
+ * vlan network devices have devices nesting below it, and are a special
+ * "super class" of normal network devices; split their locks off into a
+ * separate class since they always nest.
+ */
+static struct lock_class_key vlan_netdev_xmit_lock_key;
+
+static int vlan_dev_init(struct net_device *dev)
+{
+	struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
+
+	/* IFF_BROADCAST|IFF_MULTICAST; ??? */
+	dev->flags  = real_dev->flags & ~IFF_UP;
+	dev->iflink = real_dev->ifindex;
+	dev->state  = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
+					  (1<<__LINK_STATE_DORMANT))) |
+		      (1<<__LINK_STATE_PRESENT);
+
+	if (is_zero_ether_addr(dev->dev_addr))
+		memcpy(dev->dev_addr, real_dev->dev_addr, dev->addr_len);
+	if (is_zero_ether_addr(dev->broadcast))
+		memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);
+
+	if (real_dev->features & NETIF_F_HW_VLAN_TX) {
+		dev->hard_header     = real_dev->hard_header;
+		dev->hard_header_len = real_dev->hard_header_len;
+		dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
+		dev->rebuild_header  = real_dev->rebuild_header;
+	} else {
+		dev->hard_header     = vlan_dev_hard_header;
+		dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
+		dev->hard_start_xmit = vlan_dev_hard_start_xmit;
+		dev->rebuild_header  = vlan_dev_rebuild_header;
+	}
+	dev->hard_header_parse = real_dev->hard_header_parse;
+	dev->hard_header_cache = NULL;
+
+	lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key);
+	return 0;
+}
+
+void vlan_setup(struct net_device *new_dev)
 {
 	SET_MODULE_OWNER(new_dev);
 
+	ether_setup(new_dev);
+
 	/* new_dev->ifindex = 0;  it will be set when added to
 	 * the global list.
 	 * iflink is set as well.
@@ -338,12 +369,14 @@
 
 	/* set up method calls */
 	new_dev->change_mtu = vlan_dev_change_mtu;
+	new_dev->init = vlan_dev_init;
 	new_dev->open = vlan_dev_open;
 	new_dev->stop = vlan_dev_stop;
-	new_dev->set_mac_address = vlan_dev_set_mac_address;
 	new_dev->set_multicast_list = vlan_dev_set_multicast_list;
 	new_dev->destructor = free_netdev;
 	new_dev->do_ioctl = vlan_dev_ioctl;
+
+	memset(new_dev->broadcast, 0, sizeof(ETH_ALEN));
 }
 
 static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev)
@@ -366,26 +399,97 @@
 	}
 }
 
-/*
- * vlan network devices have devices nesting below it, and are a special
- * "super class" of normal network devices; split their locks off into a
- * separate class since they always nest.
- */
-static struct lock_class_key vlan_netdev_xmit_lock_key;
+int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_id)
+{
+	if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
+		printk(VLAN_DBG "%s: VLANs not supported on %s.\n",
+			__FUNCTION__, real_dev->name);
+		return -EOPNOTSUPP;
+	}
 
+	if ((real_dev->features & NETIF_F_HW_VLAN_RX) &&
+	    !real_dev->vlan_rx_register) {
+		printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
+			__FUNCTION__, real_dev->name);
+		return -EOPNOTSUPP;
+	}
+
+	if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
+	    (!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) {
+		printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
+			__FUNCTION__, real_dev->name);
+		return -EOPNOTSUPP;
+	}
+
+	/* The real device must be up and operating in order to
+	 * assosciate a VLAN device with it.
+	 */
+	if (!(real_dev->flags & IFF_UP))
+		return -ENETDOWN;
+
+	if (__find_vlan_dev(real_dev, vlan_id) != NULL) {
+		/* was already registered. */
+		printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__);
+		return -EEXIST;
+	}
+
+	return 0;
+}
+
+int register_vlan_dev(struct net_device *dev)
+{
+	struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+	struct net_device *real_dev = vlan->real_dev;
+	unsigned short vlan_id = vlan->vlan_id;
+	struct vlan_group *grp, *ngrp = NULL;
+	int err;
+
+	grp = __vlan_find_group(real_dev->ifindex);
+	if (!grp) {
+		ngrp = grp = vlan_group_alloc(real_dev->ifindex);
+		if (!grp)
+			return -ENOBUFS;
+	}
+
+	err = register_netdevice(dev);
+	if (err < 0)
+		goto out_free_group;
+
+	/* Account for reference in struct vlan_dev_info */
+	dev_hold(real_dev);
+
+	vlan_transfer_operstate(real_dev, dev);
+	linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */
+
+	/* So, got the sucker initialized, now lets place
+	 * it into our local structure.
+	 */
+	vlan_group_set_device(grp, vlan_id, dev);
+	if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX)
+		real_dev->vlan_rx_register(real_dev, ngrp);
+	if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
+		real_dev->vlan_rx_add_vid(real_dev, vlan_id);
+
+	if (vlan_proc_add_dev(dev) < 0)
+		printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n",
+		       dev->name);
+	return 0;
+
+out_free_group:
+	if (ngrp)
+		vlan_group_free(ngrp);
+	return err;
+}
 
 /*  Attach a VLAN device to a mac address (ie Ethernet Card).
- *  Returns the device that was created, or NULL if there was
- *  an error of some kind.
+ *  Returns 0 if the device was created or a negative error code otherwise.
  */
-static struct net_device *register_vlan_device(const char *eth_IF_name,
-					       unsigned short VLAN_ID)
+static int register_vlan_device(struct net_device *real_dev,
+				unsigned short VLAN_ID)
 {
-	struct vlan_group *grp;
 	struct net_device *new_dev;
-	struct net_device *real_dev; /* the ethernet device */
 	char name[IFNAMSIZ];
-	int i;
+	int err;
 
 #ifdef VLAN_DEBUG
 	printk(VLAN_DBG "%s: if_name -:%s:-	vid: %i\n",
@@ -393,49 +497,11 @@
 #endif
 
 	if (VLAN_ID >= VLAN_VID_MASK)
-		goto out_ret_null;
+		return -ERANGE;
 
-	/* find the device relating to eth_IF_name. */
-	real_dev = dev_get_by_name(eth_IF_name);
-	if (!real_dev)
-		goto out_ret_null;
-
-	if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
-		printk(VLAN_DBG "%s: VLANs not supported on %s.\n",
-			__FUNCTION__, real_dev->name);
-		goto out_put_dev;
-	}
-
-	if ((real_dev->features & NETIF_F_HW_VLAN_RX) &&
-	    !real_dev->vlan_rx_register) {
-		printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
-			__FUNCTION__, real_dev->name);
-		goto out_put_dev;
-	}
-
-	if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
-	    (!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) {
-		printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
-			__FUNCTION__, real_dev->name);
-		goto out_put_dev;
-	}
-
-	/* From this point on, all the data structures must remain
-	 * consistent.
-	 */
-	rtnl_lock();
-
-	/* The real device must be up and operating in order to
-	 * assosciate a VLAN device with it.
-	 */
-	if (!(real_dev->flags & IFF_UP))
-		goto out_unlock;
-
-	if (__find_vlan_dev(real_dev, VLAN_ID) != NULL) {
-		/* was already registered. */
-		printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__);
-		goto out_unlock;
-	}
+	err = vlan_check_real_dev(real_dev, VLAN_ID);
+	if (err < 0)
+		return err;
 
 	/* Gotta set up the fields for the device. */
 #ifdef VLAN_DEBUG
@@ -471,138 +537,64 @@
 			       vlan_setup);
 
 	if (new_dev == NULL)
-		goto out_unlock;
-
-#ifdef VLAN_DEBUG
-	printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name);
-#endif
-	/* IFF_BROADCAST|IFF_MULTICAST; ??? */
-	new_dev->flags = real_dev->flags;
-	new_dev->flags &= ~IFF_UP;
-
-	new_dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
-					     (1<<__LINK_STATE_DORMANT))) |
-			 (1<<__LINK_STATE_PRESENT);
+		return -ENOBUFS;
 
 	/* need 4 bytes for extra VLAN header info,
 	 * hope the underlying device can handle it.
 	 */
 	new_dev->mtu = real_dev->mtu;
 
-	/* TODO: maybe just assign it to be ETHERNET? */
-	new_dev->type = real_dev->type;
-
-	new_dev->hard_header_len = real_dev->hard_header_len;
-	if (!(real_dev->features & NETIF_F_HW_VLAN_TX)) {
-		/* Regular ethernet + 4 bytes (18 total). */
-		new_dev->hard_header_len += VLAN_HLEN;
-	}
-
+#ifdef VLAN_DEBUG
+	printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name);
 	VLAN_MEM_DBG("new_dev->priv malloc, addr: %p  size: %i\n",
 		     new_dev->priv,
 		     sizeof(struct vlan_dev_info));
-
-	memcpy(new_dev->broadcast, real_dev->broadcast, real_dev->addr_len);
-	memcpy(new_dev->dev_addr, real_dev->dev_addr, real_dev->addr_len);
-	new_dev->addr_len = real_dev->addr_len;
-
-	if (real_dev->features & NETIF_F_HW_VLAN_TX) {
-		new_dev->hard_header = real_dev->hard_header;
-		new_dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
-		new_dev->rebuild_header = real_dev->rebuild_header;
-	} else {
-		new_dev->hard_header = vlan_dev_hard_header;
-		new_dev->hard_start_xmit = vlan_dev_hard_start_xmit;
-		new_dev->rebuild_header = vlan_dev_rebuild_header;
-	}
-	new_dev->hard_header_parse = real_dev->hard_header_parse;
+#endif
 
 	VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */
 	VLAN_DEV_INFO(new_dev)->real_dev = real_dev;
 	VLAN_DEV_INFO(new_dev)->dent = NULL;
-	VLAN_DEV_INFO(new_dev)->flags = 1;
+	VLAN_DEV_INFO(new_dev)->flags = VLAN_FLAG_REORDER_HDR;
 
-#ifdef VLAN_DEBUG
-	printk(VLAN_DBG "About to go find the group for idx: %i\n",
-	       real_dev->ifindex);
-#endif
-
-	if (register_netdevice(new_dev))
+	new_dev->rtnl_link_ops = &vlan_link_ops;
+	err = register_vlan_dev(new_dev);
+	if (err < 0)
 		goto out_free_newdev;
 
-	lockdep_set_class(&new_dev->_xmit_lock, &vlan_netdev_xmit_lock_key);
-
-	new_dev->iflink = real_dev->ifindex;
-	vlan_transfer_operstate(real_dev, new_dev);
-	linkwatch_fire_event(new_dev); /* _MUST_ call rfc2863_policy() */
-
-	/* So, got the sucker initialized, now lets place
-	 * it into our local structure.
-	 */
-	grp = __vlan_find_group(real_dev->ifindex);
-
-	/* Note, we are running under the RTNL semaphore
-	 * so it cannot "appear" on us.
-	 */
-	if (!grp) { /* need to add a new group */
-		grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL);
-		if (!grp)
-			goto out_free_unregister;
-
-		for (i=0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) {
-			grp->vlan_devices_arrays[i] = kzalloc(
-				sizeof(struct net_device *)*VLAN_GROUP_ARRAY_PART_LEN,
-				GFP_KERNEL);
-
-			if (!grp->vlan_devices_arrays[i])
-				goto out_free_arrays;
-		}
-
-		/* printk(KERN_ALERT "VLAN REGISTER:  Allocated new group.\n"); */
-		grp->real_dev_ifindex = real_dev->ifindex;
-
-		hlist_add_head_rcu(&grp->hlist,
-				   &vlan_group_hash[vlan_grp_hashfn(real_dev->ifindex)]);
-
-		if (real_dev->features & NETIF_F_HW_VLAN_RX)
-			real_dev->vlan_rx_register(real_dev, grp);
-	}
-
-	vlan_group_set_device(grp, VLAN_ID, new_dev);
-
-	if (vlan_proc_add_dev(new_dev)<0)/* create it's proc entry */
-		printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n",
-							 new_dev->name);
-
-	if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
-		real_dev->vlan_rx_add_vid(real_dev, VLAN_ID);
-
-	rtnl_unlock();
-
-
+	/* Account for reference in struct vlan_dev_info */
+	dev_hold(real_dev);
 #ifdef VLAN_DEBUG
 	printk(VLAN_DBG "Allocated new device successfully, returning.\n");
 #endif
-	return new_dev;
-
-out_free_arrays:
-	vlan_group_free(grp);
-
-out_free_unregister:
-	unregister_netdev(new_dev);
-	goto out_unlock;
+	return 0;
 
 out_free_newdev:
 	free_netdev(new_dev);
+	return err;
+}
 
-out_unlock:
-	rtnl_unlock();
+static void vlan_sync_address(struct net_device *dev,
+			      struct net_device *vlandev)
+{
+	struct vlan_dev_info *vlan = VLAN_DEV_INFO(vlandev);
 
-out_put_dev:
-	dev_put(real_dev);
+	/* May be called without an actual change */
+	if (!compare_ether_addr(vlan->real_dev_addr, dev->dev_addr))
+		return;
 
-out_ret_null:
-	return NULL;
+	/* vlan address was different from the old address and is equal to
+	 * the new address */
+	if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) &&
+	    !compare_ether_addr(vlandev->dev_addr, dev->dev_addr))
+		dev_unicast_delete(dev, vlandev->dev_addr, ETH_ALEN);
+
+	/* vlan address was equal to the old address and is different from
+	 * the new address */
+	if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) &&
+	    compare_ether_addr(vlandev->dev_addr, dev->dev_addr))
+		dev_unicast_add(dev, vlandev->dev_addr, ETH_ALEN);
+
+	memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN);
 }
 
 static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
@@ -631,6 +623,17 @@
 		}
 		break;
 
+	case NETDEV_CHANGEADDR:
+		/* Adjust unicast filters on underlying device */
+		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+			vlandev = vlan_group_get_device(grp, i);
+			if (!vlandev)
+				continue;
+
+			vlan_sync_address(dev, vlandev);
+		}
+		break;
+
 	case NETDEV_DOWN:
 		/* Put all VLANs for this dev in the down state too.  */
 		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
@@ -693,9 +696,10 @@
  */
 static int vlan_ioctl_handler(void __user *arg)
 {
-	int err = 0;
+	int err;
 	unsigned short vid = 0;
 	struct vlan_ioctl_args args;
+	struct net_device *dev = NULL;
 
 	if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args)))
 		return -EFAULT;
@@ -708,35 +712,61 @@
 	printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd);
 #endif
 
+	rtnl_lock();
+
 	switch (args.cmd) {
 	case SET_VLAN_INGRESS_PRIORITY_CMD:
+	case SET_VLAN_EGRESS_PRIORITY_CMD:
+	case SET_VLAN_FLAG_CMD:
+	case ADD_VLAN_CMD:
+	case DEL_VLAN_CMD:
+	case GET_VLAN_REALDEV_NAME_CMD:
+	case GET_VLAN_VID_CMD:
+		err = -ENODEV;
+		dev = __dev_get_by_name(args.device1);
+		if (!dev)
+			goto out;
+
+		err = -EINVAL;
+		if (args.cmd != ADD_VLAN_CMD &&
+		    !(dev->priv_flags & IFF_802_1Q_VLAN))
+			goto out;
+	}
+
+	switch (args.cmd) {
+	case SET_VLAN_INGRESS_PRIORITY_CMD:
+		err = -EPERM;
 		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		err = vlan_dev_set_ingress_priority(args.device1,
-						    args.u.skb_priority,
-						    args.vlan_qos);
+			break;
+		vlan_dev_set_ingress_priority(dev,
+					      args.u.skb_priority,
+					      args.vlan_qos);
 		break;
 
 	case SET_VLAN_EGRESS_PRIORITY_CMD:
+		err = -EPERM;
 		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		err = vlan_dev_set_egress_priority(args.device1,
+			break;
+		err = vlan_dev_set_egress_priority(dev,
 						   args.u.skb_priority,
 						   args.vlan_qos);
 		break;
 
 	case SET_VLAN_FLAG_CMD:
+		err = -EPERM;
 		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		err = vlan_dev_set_vlan_flag(args.device1,
+			break;
+		err = vlan_dev_set_vlan_flag(dev,
 					     args.u.flag,
 					     args.vlan_qos);
 		break;
 
 	case SET_VLAN_NAME_TYPE_CMD:
+		err = -EPERM;
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
-		if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) {
+		if ((args.u.name_type >= 0) &&
+		    (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) {
 			vlan_name_type = args.u.name_type;
 			err = 0;
 		} else {
@@ -745,26 +775,17 @@
 		break;
 
 	case ADD_VLAN_CMD:
+		err = -EPERM;
 		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		/* we have been given the name of the Ethernet Device we want to
-		 * talk to:  args.dev1	 We also have the
-		 * VLAN ID:  args.u.VID
-		 */
-		if (register_vlan_device(args.device1, args.u.VID)) {
-			err = 0;
-		} else {
-			err = -EINVAL;
-		}
+			break;
+		err = register_vlan_device(dev, args.u.VID);
 		break;
 
 	case DEL_VLAN_CMD:
+		err = -EPERM;
 		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		/* Here, the args.dev1 is the actual VLAN we want
-		 * to get rid of.
-		 */
-		err = unregister_vlan_device(args.device1);
+			break;
+		err = unregister_vlan_device(dev);
 		break;
 
 	case GET_VLAN_INGRESS_PRIORITY_CMD:
@@ -788,9 +809,7 @@
 		err = -EINVAL;
 		break;
 	case GET_VLAN_REALDEV_NAME_CMD:
-		err = vlan_dev_get_realdev_name(args.device1, args.u.device2);
-		if (err)
-			goto out;
+		vlan_dev_get_realdev_name(dev, args.u.device2);
 		if (copy_to_user(arg, &args,
 				 sizeof(struct vlan_ioctl_args))) {
 			err = -EFAULT;
@@ -798,9 +817,7 @@
 		break;
 
 	case GET_VLAN_VID_CMD:
-		err = vlan_dev_get_vid(args.device1, &vid);
-		if (err)
-			goto out;
+		vlan_dev_get_vid(dev, &vid);
 		args.u.VID = vid;
 		if (copy_to_user(arg, &args,
 				 sizeof(struct vlan_ioctl_args))) {
@@ -812,9 +829,11 @@
 		/* pass on to underlying device instead?? */
 		printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n",
 			__FUNCTION__, args.cmd);
-		return -EINVAL;
+		err = -EINVAL;
+		break;
 	}
 out:
+	rtnl_unlock();
 	return err;
 }
 
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index 1976cdb..62ce1c5 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -58,15 +58,27 @@
 int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
 int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
 int vlan_dev_change_mtu(struct net_device *dev, int new_mtu);
-int vlan_dev_set_mac_address(struct net_device *dev, void* addr);
 int vlan_dev_open(struct net_device* dev);
 int vlan_dev_stop(struct net_device* dev);
 int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd);
-int vlan_dev_set_ingress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
-int vlan_dev_set_egress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
-int vlan_dev_set_vlan_flag(char* dev_name, __u32 flag, short flag_val);
-int vlan_dev_get_realdev_name(const char* dev_name, char* result);
-int vlan_dev_get_vid(const char* dev_name, unsigned short* result);
+void vlan_dev_set_ingress_priority(const struct net_device *dev,
+				   u32 skb_prio, short vlan_prio);
+int vlan_dev_set_egress_priority(const struct net_device *dev,
+				 u32 skb_prio, short vlan_prio);
+int vlan_dev_set_vlan_flag(const struct net_device *dev,
+			   u32 flag, short flag_val);
+void vlan_dev_get_realdev_name(const struct net_device *dev, char *result);
+void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result);
 void vlan_dev_set_multicast_list(struct net_device *vlan_dev);
 
+int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_id);
+void vlan_setup(struct net_device *dev);
+int register_vlan_dev(struct net_device *dev);
+int unregister_vlan_device(struct net_device *dev);
+
+int vlan_netlink_init(void);
+void vlan_netlink_fini(void);
+
+extern struct rtnl_link_ops vlan_link_ops;
+
 #endif /* !(__BEN_VLAN_802_1Q_INC__) */
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index ec46084..d4a62d1 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -73,7 +73,7 @@
 
 static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
 {
-	if (VLAN_DEV_INFO(skb->dev)->flags & 1) {
+	if (VLAN_DEV_INFO(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) {
 		if (skb_shared(skb) || skb_cloned(skb)) {
 			struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
 			kfree_skb(skb);
@@ -350,7 +350,8 @@
 	 * header shuffling in the hard_start_xmit.  Users can turn off this
 	 * REORDER behaviour with the vconfig tool.
 	 */
-	build_vlan_header = ((VLAN_DEV_INFO(dev)->flags & 1) == 0);
+	if (!(VLAN_DEV_INFO(dev)->flags & VLAN_FLAG_REORDER_HDR))
+		build_vlan_header = 1;
 
 	if (build_vlan_header) {
 		vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN);
@@ -534,174 +535,83 @@
 	return 0;
 }
 
-int vlan_dev_set_ingress_priority(char *dev_name, __u32 skb_prio, short vlan_prio)
+void vlan_dev_set_ingress_priority(const struct net_device *dev,
+				   u32 skb_prio, short vlan_prio)
 {
-	struct net_device *dev = dev_get_by_name(dev_name);
+	struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
 
-	if (dev) {
-		if (dev->priv_flags & IFF_802_1Q_VLAN) {
-			/* see if a priority mapping exists.. */
-			VLAN_DEV_INFO(dev)->ingress_priority_map[vlan_prio & 0x7] = skb_prio;
-			dev_put(dev);
-			return 0;
-		}
+	if (vlan->ingress_priority_map[vlan_prio & 0x7] && !skb_prio)
+		vlan->nr_ingress_mappings--;
+	else if (!vlan->ingress_priority_map[vlan_prio & 0x7] && skb_prio)
+		vlan->nr_ingress_mappings++;
 
-		dev_put(dev);
-	}
-	return -EINVAL;
+	vlan->ingress_priority_map[vlan_prio & 0x7] = skb_prio;
 }
 
-int vlan_dev_set_egress_priority(char *dev_name, __u32 skb_prio, short vlan_prio)
+int vlan_dev_set_egress_priority(const struct net_device *dev,
+				 u32 skb_prio, short vlan_prio)
 {
-	struct net_device *dev = dev_get_by_name(dev_name);
+	struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
 	struct vlan_priority_tci_mapping *mp = NULL;
 	struct vlan_priority_tci_mapping *np;
+	u32 vlan_qos = (vlan_prio << 13) & 0xE000;
 
-	if (dev) {
-		if (dev->priv_flags & IFF_802_1Q_VLAN) {
-			/* See if a priority mapping exists.. */
-			mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF];
-			while (mp) {
-				if (mp->priority == skb_prio) {
-					mp->vlan_qos = ((vlan_prio << 13) & 0xE000);
-					dev_put(dev);
-					return 0;
-				}
-				mp = mp->next;
-			}
-
-			/* Create a new mapping then. */
-			mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF];
-			np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL);
-			if (np) {
-				np->next = mp;
-				np->priority = skb_prio;
-				np->vlan_qos = ((vlan_prio << 13) & 0xE000);
-				VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF] = np;
-				dev_put(dev);
-				return 0;
-			} else {
-				dev_put(dev);
-				return -ENOBUFS;
-			}
+	/* See if a priority mapping exists.. */
+	mp = vlan->egress_priority_map[skb_prio & 0xF];
+	while (mp) {
+		if (mp->priority == skb_prio) {
+			if (mp->vlan_qos && !vlan_qos)
+				vlan->nr_egress_mappings--;
+			else if (!mp->vlan_qos && vlan_qos)
+				vlan->nr_egress_mappings++;
+			mp->vlan_qos = vlan_qos;
+			return 0;
 		}
-		dev_put(dev);
-	}
-	return -EINVAL;
-}
-
-/* Flags are defined in the vlan_dev_info class in include/linux/if_vlan.h file. */
-int vlan_dev_set_vlan_flag(char *dev_name, __u32 flag, short flag_val)
-{
-	struct net_device *dev = dev_get_by_name(dev_name);
-
-	if (dev) {
-		if (dev->priv_flags & IFF_802_1Q_VLAN) {
-			/* verify flag is supported */
-			if (flag == 1) {
-				if (flag_val) {
-					VLAN_DEV_INFO(dev)->flags |= 1;
-				} else {
-					VLAN_DEV_INFO(dev)->flags &= ~1;
-				}
-				dev_put(dev);
-				return 0;
-			} else {
-				printk(KERN_ERR  "%s: flag %i is not valid.\n",
-					__FUNCTION__, (int)(flag));
-				dev_put(dev);
-				return -EINVAL;
-			}
-		} else {
-			printk(KERN_ERR
-			       "%s: %s is not a vlan device, priv_flags: %hX.\n",
-			       __FUNCTION__, dev->name, dev->priv_flags);
-			dev_put(dev);
-		}
-	} else {
-		printk(KERN_ERR  "%s: Could not find device: %s\n",
-			__FUNCTION__, dev_name);
+		mp = mp->next;
 	}
 
-	return -EINVAL;
-}
+	/* Create a new mapping then. */
+	mp = vlan->egress_priority_map[skb_prio & 0xF];
+	np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL);
+	if (!np)
+		return -ENOBUFS;
 
-
-int vlan_dev_get_realdev_name(const char *dev_name, char* result)
-{
-	struct net_device *dev = dev_get_by_name(dev_name);
-	int rv = 0;
-	if (dev) {
-		if (dev->priv_flags & IFF_802_1Q_VLAN) {
-			strncpy(result, VLAN_DEV_INFO(dev)->real_dev->name, 23);
-			rv = 0;
-		} else {
-			rv = -EINVAL;
-		}
-		dev_put(dev);
-	} else {
-		rv = -ENODEV;
-	}
-	return rv;
-}
-
-int vlan_dev_get_vid(const char *dev_name, unsigned short* result)
-{
-	struct net_device *dev = dev_get_by_name(dev_name);
-	int rv = 0;
-	if (dev) {
-		if (dev->priv_flags & IFF_802_1Q_VLAN) {
-			*result = VLAN_DEV_INFO(dev)->vlan_id;
-			rv = 0;
-		} else {
-			rv = -EINVAL;
-		}
-		dev_put(dev);
-	} else {
-		rv = -ENODEV;
-	}
-	return rv;
-}
-
-
-int vlan_dev_set_mac_address(struct net_device *dev, void *addr_struct_p)
-{
-	struct sockaddr *addr = (struct sockaddr *)(addr_struct_p);
-	int i;
-
-	if (netif_running(dev))
-		return -EBUSY;
-
-	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-
-	printk("%s: Setting MAC address to ", dev->name);
-	for (i = 0; i < 6; i++)
-		printk(" %2.2x", dev->dev_addr[i]);
-	printk(".\n");
-
-	if (memcmp(VLAN_DEV_INFO(dev)->real_dev->dev_addr,
-		   dev->dev_addr,
-		   dev->addr_len) != 0) {
-		if (!(VLAN_DEV_INFO(dev)->real_dev->flags & IFF_PROMISC)) {
-			int flgs = VLAN_DEV_INFO(dev)->real_dev->flags;
-
-			/* Increment our in-use promiscuity counter */
-			dev_set_promiscuity(VLAN_DEV_INFO(dev)->real_dev, 1);
-
-			/* Make PROMISC visible to the user. */
-			flgs |= IFF_PROMISC;
-			printk("VLAN (%s):  Setting underlying device (%s) to promiscious mode.\n",
-			       dev->name, VLAN_DEV_INFO(dev)->real_dev->name);
-			dev_change_flags(VLAN_DEV_INFO(dev)->real_dev, flgs);
-		}
-	} else {
-		printk("VLAN (%s):  Underlying device (%s) has same MAC, not checking promiscious mode.\n",
-		       dev->name, VLAN_DEV_INFO(dev)->real_dev->name);
-	}
-
+	np->next = mp;
+	np->priority = skb_prio;
+	np->vlan_qos = vlan_qos;
+	vlan->egress_priority_map[skb_prio & 0xF] = np;
+	if (vlan_qos)
+		vlan->nr_egress_mappings++;
 	return 0;
 }
 
+/* Flags are defined in the vlan_flags enum in include/linux/if_vlan.h file. */
+int vlan_dev_set_vlan_flag(const struct net_device *dev,
+			   u32 flag, short flag_val)
+{
+	/* verify flag is supported */
+	if (flag == VLAN_FLAG_REORDER_HDR) {
+		if (flag_val) {
+			VLAN_DEV_INFO(dev)->flags |= VLAN_FLAG_REORDER_HDR;
+		} else {
+			VLAN_DEV_INFO(dev)->flags &= ~VLAN_FLAG_REORDER_HDR;
+		}
+		return 0;
+	}
+	printk(KERN_ERR "%s: flag %i is not valid.\n", __FUNCTION__, flag);
+	return -EINVAL;
+}
+
+void vlan_dev_get_realdev_name(const struct net_device *dev, char *result)
+{
+	strncpy(result, VLAN_DEV_INFO(dev)->real_dev->name, 23);
+}
+
+void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result)
+{
+	*result = VLAN_DEV_INFO(dev)->vlan_id;
+}
+
 static inline int vlan_dmi_equals(struct dev_mc_list *dmi1,
 				  struct dev_mc_list *dmi2)
 {
@@ -788,15 +698,32 @@
 
 int vlan_dev_open(struct net_device *dev)
 {
-	if (!(VLAN_DEV_INFO(dev)->real_dev->flags & IFF_UP))
+	struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+	struct net_device *real_dev = vlan->real_dev;
+	int err;
+
+	if (!(real_dev->flags & IFF_UP))
 		return -ENETDOWN;
 
+	if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) {
+		err = dev_unicast_add(real_dev, dev->dev_addr, ETH_ALEN);
+		if (err < 0)
+			return err;
+	}
+	memcpy(vlan->real_dev_addr, real_dev->dev_addr, ETH_ALEN);
+
 	return 0;
 }
 
 int vlan_dev_stop(struct net_device *dev)
 {
+	struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
+
 	vlan_flush_mc_list(dev);
+
+	if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr))
+		dev_unicast_delete(real_dev, dev->dev_addr, dev->addr_len);
+
 	return 0;
 }
 
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
new file mode 100644
index 0000000..6cdd1e0
--- /dev/null
+++ b/net/8021q/vlan_netlink.c
@@ -0,0 +1,243 @@
+/*
+ *	VLAN netlink control interface
+ *
+ * 	Copyright (c) 2007 Patrick McHardy <kaber@trash.net>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	version 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/if_vlan.h>
+#include <net/netlink.h>
+#include <net/rtnetlink.h>
+#include "vlan.h"
+
+
+static const struct nla_policy vlan_policy[IFLA_VLAN_MAX + 1] = {
+	[IFLA_VLAN_ID]		= { .type = NLA_U16 },
+	[IFLA_VLAN_FLAGS]	= { .len = sizeof(struct ifla_vlan_flags) },
+	[IFLA_VLAN_EGRESS_QOS]	= { .type = NLA_NESTED },
+	[IFLA_VLAN_INGRESS_QOS] = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy vlan_map_policy[IFLA_VLAN_QOS_MAX + 1] = {
+	[IFLA_VLAN_QOS_MAPPING] = { .len = sizeof(struct ifla_vlan_qos_mapping) },
+};
+
+
+static inline int vlan_validate_qos_map(struct nlattr *attr)
+{
+	if (!attr)
+		return 0;
+	return nla_validate_nested(attr, IFLA_VLAN_QOS_MAX, vlan_map_policy);
+}
+
+static int vlan_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+	struct ifla_vlan_flags *flags;
+	u16 id;
+	int err;
+
+	if (tb[IFLA_ADDRESS]) {
+		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+			return -EINVAL;
+		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
+			return -EADDRNOTAVAIL;
+	}
+
+	if (!data)
+		return -EINVAL;
+
+	if (data[IFLA_VLAN_ID]) {
+		id = nla_get_u16(data[IFLA_VLAN_ID]);
+		if (id >= VLAN_VID_MASK)
+			return -ERANGE;
+	}
+	if (data[IFLA_VLAN_FLAGS]) {
+		flags = nla_data(data[IFLA_VLAN_FLAGS]);
+		if ((flags->flags & flags->mask) & ~VLAN_FLAG_REORDER_HDR)
+			return -EINVAL;
+	}
+
+	err = vlan_validate_qos_map(data[IFLA_VLAN_INGRESS_QOS]);
+	if (err < 0)
+		return err;
+	err = vlan_validate_qos_map(data[IFLA_VLAN_EGRESS_QOS]);
+	if (err < 0)
+		return err;
+	return 0;
+}
+
+static int vlan_changelink(struct net_device *dev,
+			   struct nlattr *tb[], struct nlattr *data[])
+{
+	struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+	struct ifla_vlan_flags *flags;
+	struct ifla_vlan_qos_mapping *m;
+	struct nlattr *attr;
+	int rem;
+
+	if (data[IFLA_VLAN_FLAGS]) {
+		flags = nla_data(data[IFLA_VLAN_FLAGS]);
+		vlan->flags = (vlan->flags & ~flags->mask) |
+			      (flags->flags & flags->mask);
+	}
+	if (data[IFLA_VLAN_INGRESS_QOS]) {
+		nla_for_each_nested(attr, data[IFLA_VLAN_INGRESS_QOS], rem) {
+			m = nla_data(attr);
+			vlan_dev_set_ingress_priority(dev, m->to, m->from);
+		}
+	}
+	if (data[IFLA_VLAN_EGRESS_QOS]) {
+		nla_for_each_nested(attr, data[IFLA_VLAN_EGRESS_QOS], rem) {
+			m = nla_data(attr);
+			vlan_dev_set_egress_priority(dev, m->from, m->to);
+		}
+	}
+	return 0;
+}
+
+static int vlan_newlink(struct net_device *dev,
+			struct nlattr *tb[], struct nlattr *data[])
+{
+	struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+	struct net_device *real_dev;
+	int err;
+
+	if (!data[IFLA_VLAN_ID])
+		return -EINVAL;
+
+	if (!tb[IFLA_LINK])
+		return -EINVAL;
+	real_dev = __dev_get_by_index(nla_get_u32(tb[IFLA_LINK]));
+	if (!real_dev)
+		return -ENODEV;
+
+	vlan->vlan_id  = nla_get_u16(data[IFLA_VLAN_ID]);
+	vlan->real_dev = real_dev;
+	vlan->flags    = VLAN_FLAG_REORDER_HDR;
+
+	err = vlan_check_real_dev(real_dev, vlan->vlan_id);
+	if (err < 0)
+		return err;
+
+	if (!tb[IFLA_MTU])
+		dev->mtu = real_dev->mtu;
+	else if (dev->mtu > real_dev->mtu)
+		return -EINVAL;
+
+	err = vlan_changelink(dev, tb, data);
+	if (err < 0)
+		return err;
+
+	return register_vlan_dev(dev);
+}
+
+static void vlan_dellink(struct net_device *dev)
+{
+	unregister_vlan_device(dev);
+}
+
+static inline size_t vlan_qos_map_size(unsigned int n)
+{
+	if (n == 0)
+		return 0;
+	/* IFLA_VLAN_{EGRESS,INGRESS}_QOS + n * IFLA_VLAN_QOS_MAPPING */
+	return nla_total_size(sizeof(struct nlattr)) +
+	       nla_total_size(sizeof(struct ifla_vlan_qos_mapping)) * n;
+}
+
+static size_t vlan_get_size(const struct net_device *dev)
+{
+	struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+
+	return nla_total_size(2) +	/* IFLA_VLAN_ID */
+	       vlan_qos_map_size(vlan->nr_ingress_mappings) +
+	       vlan_qos_map_size(vlan->nr_egress_mappings);
+}
+
+static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
+{
+	struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+	struct vlan_priority_tci_mapping *pm;
+	struct ifla_vlan_flags f;
+	struct ifla_vlan_qos_mapping m;
+	struct nlattr *nest;
+	unsigned int i;
+
+	NLA_PUT_U16(skb, IFLA_VLAN_ID, VLAN_DEV_INFO(dev)->vlan_id);
+	if (vlan->flags) {
+		f.flags = vlan->flags;
+		f.mask  = ~0;
+		NLA_PUT(skb, IFLA_VLAN_FLAGS, sizeof(f), &f);
+	}
+	if (vlan->nr_ingress_mappings) {
+		nest = nla_nest_start(skb, IFLA_VLAN_INGRESS_QOS);
+		if (nest == NULL)
+			goto nla_put_failure;
+
+		for (i = 0; i < ARRAY_SIZE(vlan->ingress_priority_map); i++) {
+			if (!vlan->ingress_priority_map[i])
+				continue;
+
+			m.from = i;
+			m.to   = vlan->ingress_priority_map[i];
+			NLA_PUT(skb, IFLA_VLAN_QOS_MAPPING,
+				sizeof(m), &m);
+		}
+		nla_nest_end(skb, nest);
+	}
+
+	if (vlan->nr_egress_mappings) {
+		nest = nla_nest_start(skb, IFLA_VLAN_EGRESS_QOS);
+		if (nest == NULL)
+			goto nla_put_failure;
+
+		for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) {
+			for (pm = vlan->egress_priority_map[i]; pm;
+			     pm = pm->next) {
+				if (!pm->vlan_qos)
+					continue;
+
+				m.from = pm->priority;
+				m.to   = (pm->vlan_qos >> 13) & 0x7;
+				NLA_PUT(skb, IFLA_VLAN_QOS_MAPPING,
+					sizeof(m), &m);
+			}
+		}
+		nla_nest_end(skb, nest);
+	}
+	return 0;
+
+nla_put_failure:
+	return -EMSGSIZE;
+}
+
+struct rtnl_link_ops vlan_link_ops __read_mostly = {
+	.kind		= "vlan",
+	.maxtype	= IFLA_VLAN_MAX,
+	.policy		= vlan_policy,
+	.priv_size	= sizeof(struct vlan_dev_info),
+	.setup		= vlan_setup,
+	.validate	= vlan_validate,
+	.newlink	= vlan_newlink,
+	.changelink	= vlan_changelink,
+	.dellink	= vlan_dellink,
+	.get_size	= vlan_get_size,
+	.fill_info	= vlan_fill_info,
+};
+
+int __init vlan_netlink_init(void)
+{
+	return rtnl_link_register(&vlan_link_ops);
+}
+
+void __exit vlan_netlink_fini(void)
+{
+	rtnl_link_unregister(&vlan_link_ops);
+}
+
+MODULE_ALIAS_RTNL_LINK("vlan");
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index d216a64..c0040c9 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -69,7 +69,7 @@
  *	Generic /proc/net/vlan/<file> file and inode operations
  */
 
-static struct seq_operations vlan_seq_ops = {
+static const struct seq_operations vlan_seq_ops = {
 	.start = vlan_seq_start,
 	.next = vlan_seq_next,
 	.stop = vlan_seq_stop,
@@ -342,7 +342,7 @@
 	seq_printf(seq, "Device: %s", dev_info->real_dev->name);
 	/* now show all PRIORITY mappings relating to this VLAN */
 	seq_printf(seq,
-		       "\nINGRESS priority mappings: 0:%lu  1:%lu  2:%lu  3:%lu  4:%lu  5:%lu  6:%lu 7:%lu\n",
+		       "\nINGRESS priority mappings: 0:%u  1:%u  2:%u  3:%u  4:%u  5:%u  6:%u 7:%u\n",
 		       dev_info->ingress_priority_map[0],
 		       dev_info->ingress_priority_map[1],
 		       dev_info->ingress_priority_map[2],
@@ -357,7 +357,7 @@
 		const struct vlan_priority_tci_mapping *mp
 			= dev_info->egress_priority_map[i];
 		while (mp) {
-			seq_printf(seq, "%lu:%hu ",
+			seq_printf(seq, "%u:%hu ",
 				   mp->priority, ((mp->vlan_qos >> 13) & 0x7));
 			mp = mp->next;
 		}
diff --git a/net/Makefile b/net/Makefile
index 34e5b2d..a87a889 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -37,7 +37,6 @@
 obj-$(CONFIG_IRDA)		+= irda/
 obj-$(CONFIG_BT)		+= bluetooth/
 obj-$(CONFIG_SUNRPC)		+= sunrpc/
-obj-$(CONFIG_RXRPC)		+= rxrpc/
 obj-$(CONFIG_AF_RXRPC)		+= rxrpc/
 obj-$(CONFIG_ATM)		+= atm/
 obj-$(CONFIG_DECNET)		+= decnet/
diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c
index 5ef6a23..3d1655f 100644
--- a/net/appletalk/aarp.c
+++ b/net/appletalk/aarp.c
@@ -1024,7 +1024,7 @@
 	return 0;
 }
 
-static struct seq_operations aarp_seq_ops = {
+static const struct seq_operations aarp_seq_ops = {
 	.start  = aarp_seq_start,
 	.next   = aarp_seq_next,
 	.stop   = aarp_seq_stop,
diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c
index 57ff812..87a582c 100644
--- a/net/appletalk/atalk_proc.c
+++ b/net/appletalk/atalk_proc.c
@@ -204,21 +204,21 @@
 	return 0;
 }
 
-static struct seq_operations atalk_seq_interface_ops = {
+static const struct seq_operations atalk_seq_interface_ops = {
 	.start  = atalk_seq_interface_start,
 	.next   = atalk_seq_interface_next,
 	.stop   = atalk_seq_interface_stop,
 	.show   = atalk_seq_interface_show,
 };
 
-static struct seq_operations atalk_seq_route_ops = {
+static const struct seq_operations atalk_seq_route_ops = {
 	.start  = atalk_seq_route_start,
 	.next   = atalk_seq_route_next,
 	.stop   = atalk_seq_route_stop,
 	.show   = atalk_seq_route_show,
 };
 
-static struct seq_operations atalk_seq_socket_ops = {
+static const struct seq_operations atalk_seq_socket_ops = {
 	.start  = atalk_seq_socket_start,
 	.next   = atalk_seq_socket_next,
 	.stop   = atalk_seq_socket_stop,
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 0e9f00c..faa6aaf 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -699,28 +699,13 @@
 #ifdef CONFIG_PROC_FS
 static void *br2684_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	loff_t offs = 0;
-	struct br2684_dev *brd;
-
 	read_lock(&devs_lock);
-
-	list_for_each_entry(brd, &br2684_devs, br2684_devs) {
-		if (offs == *pos)
-			return brd;
-		++offs;
-	}
-	return NULL;
+	return seq_list_start(&br2684_devs, *pos);
 }
 
 static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	struct br2684_dev *brd = v;
-
-	++*pos;
-
-	brd = list_entry(brd->br2684_devs.next,
-			 struct br2684_dev, br2684_devs);
-	return (&brd->br2684_devs != &br2684_devs) ? brd : NULL;
+	return seq_list_next(v, &br2684_devs, pos);
 }
 
 static void br2684_seq_stop(struct seq_file *seq, void *v)
@@ -730,7 +715,8 @@
 
 static int br2684_seq_show(struct seq_file *seq, void *v)
 {
-	const struct br2684_dev *brdev = v;
+	const struct br2684_dev *brdev = list_entry(v, struct br2684_dev,
+			br2684_devs);
 	const struct net_device *net_dev = brdev->net_dev;
 	const struct br2684_vcc *brvcc;
 
@@ -772,7 +758,7 @@
 	return 0;
 }
 
-static struct seq_operations br2684_seq_ops = {
+static const struct seq_operations br2684_seq_ops = {
 	.start = br2684_seq_start,
 	.next  = br2684_seq_next,
 	.stop  = br2684_seq_stop,
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 876b77f..ecf0f79 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -928,7 +928,7 @@
 	return 0;
 }
 
-static struct seq_operations arp_seq_ops = {
+static const struct seq_operations arp_seq_ops = {
 	.start	= clip_seq_start,
 	.next	= neigh_seq_next,
 	.stop	= neigh_seq_stop,
diff --git a/net/atm/lec.c b/net/atm/lec.c
index 4dc5f2b..2770fb4 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -1174,7 +1174,7 @@
 	return 0;
 }
 
-static struct seq_operations lec_seq_ops = {
+static const struct seq_operations lec_seq_ops = {
 	.start = lec_seq_start,
 	.next = lec_seq_next,
 	.stop = lec_seq_stop,
diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c
index 4b05cbe..91f3ffc 100644
--- a/net/atm/mpoa_proc.c
+++ b/net/atm/mpoa_proc.c
@@ -177,7 +177,7 @@
 	return 0;
 }
 
-static struct seq_operations mpc_op = {
+static const struct seq_operations mpc_op = {
 	.start =	mpc_start,
 	.next =		mpc_next,
 	.stop =		mpc_stop,
diff --git a/net/atm/proc.c b/net/atm/proc.c
index 9e61e51..88154da 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -260,7 +260,7 @@
 	return 0;
 }
 
-static struct seq_operations atm_dev_seq_ops = {
+static const struct seq_operations atm_dev_seq_ops = {
 	.start	= atm_dev_seq_start,
 	.next	= atm_dev_seq_next,
 	.stop	= atm_dev_seq_stop,
@@ -295,7 +295,7 @@
 	return 0;
 }
 
-static struct seq_operations pvc_seq_ops = {
+static const struct seq_operations pvc_seq_ops = {
 	.start	= vcc_seq_start,
 	.next	= vcc_seq_next,
 	.stop	= vcc_seq_stop,
@@ -329,7 +329,7 @@
 	return 0;
 }
 
-static struct seq_operations vcc_seq_ops = {
+static const struct seq_operations vcc_seq_ops = {
 	.start	= vcc_seq_start,
 	.next	= vcc_seq_next,
 	.stop	= vcc_seq_stop,
@@ -364,7 +364,7 @@
 	return 0;
 }
 
-static struct seq_operations svc_seq_ops = {
+static const struct seq_operations svc_seq_ops = {
 	.start	= vcc_seq_start,
 	.next	= vcc_seq_next,
 	.stop	= vcc_seq_stop,
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 429e13a..c83cf843 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1924,7 +1924,7 @@
 	return 0;
 }
 
-static struct seq_operations ax25_info_seqops = {
+static const struct seq_operations ax25_info_seqops = {
 	.start = ax25_info_start,
 	.next = ax25_info_next,
 	.stop = ax25_info_stop,
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index d65b8e2..9ecf6f1 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -320,7 +320,7 @@
 	return 0;
 }
 
-static struct seq_operations ax25_rt_seqops = {
+static const struct seq_operations ax25_rt_seqops = {
 	.start = ax25_rt_seq_start,
 	.next = ax25_rt_seq_next,
 	.stop = ax25_rt_seq_stop,
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
index 75c7664..ce0b13d 100644
--- a/net/ax25/ax25_uid.c
+++ b/net/ax25/ax25_uid.c
@@ -185,7 +185,7 @@
 	return 0;
 }
 
-static struct seq_operations ax25_uid_seqops = {
+static const struct seq_operations ax25_uid_seqops = {
 	.start = ax25_uid_seq_start,
 	.next = ax25_uid_seq_next,
 	.stop = ax25_uid_seq_stop,
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 63980bd..5fdfc9a6 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -123,8 +123,8 @@
 	conn->state = BT_CONNECT;
 	conn->out = 1;
 
-	cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
 	cp.handle   = cpu_to_le16(handle);
+	cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
 
 	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp);
 }
@@ -220,19 +220,19 @@
 
 	del_timer(&conn->disc_timer);
 
-	if (conn->type == SCO_LINK) {
-		struct hci_conn *acl = conn->link;
-		if (acl) {
-			acl->link = NULL;
-			hci_conn_put(acl);
-		}
-	} else {
+	if (conn->type == ACL_LINK) {
 		struct hci_conn *sco = conn->link;
 		if (sco)
 			sco->link = NULL;
 
 		/* Unacked frames */
 		hdev->acl_cnt += conn->sent;
+	} else {
+		struct hci_conn *acl = conn->link;
+		if (acl) {
+			acl->link = NULL;
+			hci_conn_put(acl);
+		}
 	}
 
 	tasklet_disable(&hdev->tx_task);
@@ -297,9 +297,10 @@
 
 /* Create SCO or ACL connection.
  * Device _must_ be locked */
-struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
 {
 	struct hci_conn *acl;
+	struct hci_conn *sco;
 
 	BT_DBG("%s dst %s", hdev->name, batostr(dst));
 
@@ -313,28 +314,26 @@
 	if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
 		hci_acl_connect(acl);
 
-	if (type == SCO_LINK) {
-		struct hci_conn *sco;
-
-		if (!(sco = hci_conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
-			if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
-				hci_conn_put(acl);
-				return NULL;
-			}
-		}
-		acl->link = sco;
-		sco->link = acl;
-
-		hci_conn_hold(sco);
-
-		if (acl->state == BT_CONNECTED &&
-				(sco->state == BT_OPEN || sco->state == BT_CLOSED))
-			hci_add_sco(sco, acl->handle);
-
-		return sco;
-	} else {
+	if (type == ACL_LINK)
 		return acl;
+
+	if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) {
+		if (!(sco = hci_conn_add(hdev, type, dst))) {
+			hci_conn_put(acl);
+			return NULL;
+		}
 	}
+
+	acl->link = sco;
+	sco->link = acl;
+
+	hci_conn_hold(sco);
+
+	if (acl->state == BT_CONNECTED &&
+			(sco->state == BT_OPEN || sco->state == BT_CLOSED))
+		hci_add_sco(sco, acl->handle);
+
+	return sco;
 }
 EXPORT_SYMBOL(hci_connect);
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index aa4b56a..f6d867e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -826,7 +826,7 @@
 int hci_register_dev(struct hci_dev *hdev)
 {
 	struct list_head *head = &hci_dev_list, *p;
-	int id = 0;
+	int i, id = 0;
 
 	BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner);
 
@@ -851,6 +851,7 @@
 
 	hdev->flags = 0;
 	hdev->pkt_type  = (HCI_DM1 | HCI_DH1 | HCI_HV1);
+	hdev->esco_type = (ESCO_HV1);
 	hdev->link_mode = (HCI_LM_ACCEPT);
 
 	hdev->idle_timeout = 0;
@@ -865,6 +866,9 @@
 	skb_queue_head_init(&hdev->cmd_q);
 	skb_queue_head_init(&hdev->raw_q);
 
+	for (i = 0; i < 3; i++)
+		hdev->reassembly[i] = NULL;
+
 	init_waitqueue_head(&hdev->req_wait_q);
 	init_MUTEX(&hdev->req_lock);
 
@@ -889,6 +893,8 @@
 /* Unregister HCI device */
 int hci_unregister_dev(struct hci_dev *hdev)
 {
+	int i;
+
 	BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
 	hci_unregister_sysfs(hdev);
@@ -899,9 +905,13 @@
 
 	hci_dev_do_close(hdev);
 
+	for (i = 0; i < 3; i++)
+		kfree_skb(hdev->reassembly[i]);
+
 	hci_notify(hdev, HCI_DEV_UNREG);
 
 	__hci_dev_put(hdev);
+
 	return 0;
 }
 EXPORT_SYMBOL(hci_unregister_dev);
@@ -922,6 +932,90 @@
 }
 EXPORT_SYMBOL(hci_resume_dev);
 
+/* Receive packet type fragment */
+#define __reassembly(hdev, type)  ((hdev)->reassembly[(type) - 2])
+
+int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
+{
+	if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
+		return -EILSEQ;
+
+	while (count) {
+		struct sk_buff *skb = __reassembly(hdev, type);
+		struct { int expect; } *scb;
+		int len = 0;
+
+		if (!skb) {
+			/* Start of the frame */
+
+			switch (type) {
+			case HCI_EVENT_PKT:
+				if (count >= HCI_EVENT_HDR_SIZE) {
+					struct hci_event_hdr *h = data;
+					len = HCI_EVENT_HDR_SIZE + h->plen;
+				} else
+					return -EILSEQ;
+				break;
+
+			case HCI_ACLDATA_PKT:
+				if (count >= HCI_ACL_HDR_SIZE) {
+					struct hci_acl_hdr *h = data;
+					len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
+				} else
+					return -EILSEQ;
+				break;
+
+			case HCI_SCODATA_PKT:
+				if (count >= HCI_SCO_HDR_SIZE) {
+					struct hci_sco_hdr *h = data;
+					len = HCI_SCO_HDR_SIZE + h->dlen;
+				} else
+					return -EILSEQ;
+				break;
+			}
+
+			skb = bt_skb_alloc(len, GFP_ATOMIC);
+			if (!skb) {
+				BT_ERR("%s no memory for packet", hdev->name);
+				return -ENOMEM;
+			}
+
+			skb->dev = (void *) hdev;
+			bt_cb(skb)->pkt_type = type;
+	
+			__reassembly(hdev, type) = skb;
+
+			scb = (void *) skb->cb;
+			scb->expect = len;
+		} else {
+			/* Continuation */
+
+			scb = (void *) skb->cb;
+			len = scb->expect;
+		}
+
+		len = min(len, count);
+
+		memcpy(skb_put(skb, len), data, len);
+
+		scb->expect -= len;
+
+		if (scb->expect == 0) {
+			/* Complete frame */
+
+			__reassembly(hdev, type) = NULL;
+
+			bt_cb(skb)->pkt_type = type;
+			hci_recv_frame(skb);
+		}
+
+		count -= len; data += len;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(hci_recv_fragment);
+
 /* ---- Interface to upper protocols ---- */
 
 /* Register/Unregister protocols.
@@ -1029,7 +1123,7 @@
 
 	skb = bt_skb_alloc(len, GFP_ATOMIC);
 	if (!skb) {
-		BT_ERR("%s Can't allocate memory for HCI command", hdev->name);
+		BT_ERR("%s no memory for command", hdev->name);
 		return -ENOMEM;
 	}
 
@@ -1161,7 +1255,7 @@
 static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
 {
 	struct hci_conn_hash *h = &hdev->conn_hash;
-	struct hci_conn  *conn = NULL;
+	struct hci_conn *conn = NULL;
 	int num = 0, min = ~0;
 	struct list_head *p;
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 447ba71..4baea1e 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -350,11 +350,24 @@
 		if (hdev->features[0] & LMP_5SLOT)
 			hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
 
-		if (hdev->features[1] & LMP_HV2)
-			hdev->pkt_type |= (HCI_HV2);
+		if (hdev->features[1] & LMP_HV2) {
+			hdev->pkt_type  |= (HCI_HV2);
+			hdev->esco_type |= (ESCO_HV2);
+		}
 
-		if (hdev->features[1] & LMP_HV3)
-			hdev->pkt_type |= (HCI_HV3);
+		if (hdev->features[1] & LMP_HV3) {
+			hdev->pkt_type  |= (HCI_HV3);
+			hdev->esco_type |= (ESCO_HV3);
+		}
+
+		if (hdev->features[3] & LMP_ESCO)
+			hdev->esco_type |= (ESCO_EV3);
+
+		if (hdev->features[4] & LMP_EV4)
+			hdev->esco_type |= (ESCO_EV4);
+
+		if (hdev->features[4] & LMP_EV5)
+			hdev->esco_type |= (ESCO_EV5);
 
 		BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
 				lf->features[0], lf->features[1], lf->features[2]);
@@ -881,12 +894,12 @@
 		if (conn) {
 			conn->sent -= count;
 
-			if (conn->type == SCO_LINK) {
-				if ((hdev->sco_cnt += count) > hdev->sco_pkts)
-					hdev->sco_cnt = hdev->sco_pkts;
-			} else {
+			if (conn->type == ACL_LINK) {
 				if ((hdev->acl_cnt += count) > hdev->acl_pkts)
 					hdev->acl_cnt = hdev->acl_pkts;
+			} else {
+				if ((hdev->sco_cnt += count) > hdev->sco_pkts)
+					hdev->sco_cnt = hdev->sco_pkts;
 			}
 		}
 	}
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index b2b1cce..23ba61a 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -95,6 +95,10 @@
 
 	BT_DBG("dev %p dlc %p", dev, dlc);
 
+	write_lock_bh(&rfcomm_dev_lock);
+	list_del_init(&dev->list);
+	write_unlock_bh(&rfcomm_dev_lock);
+
 	rfcomm_dlc_lock(dlc);
 	/* Detach DLC if it's owned by this dev */
 	if (dlc->owner == dev)
@@ -156,8 +160,13 @@
 	read_lock(&rfcomm_dev_lock);
 
 	dev = __rfcomm_dev_get(id);
-	if (dev)
-		rfcomm_dev_hold(dev);
+
+	if (dev) {
+		if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
+			dev = NULL;
+		else
+			rfcomm_dev_hold(dev);
+	}
 
 	read_unlock(&rfcomm_dev_lock);
 
@@ -265,6 +274,12 @@
 
 	dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
 
+	if (IS_ERR(dev->tty_dev)) {
+		list_del(&dev->list);
+		kfree(dev);
+		return PTR_ERR(dev->tty_dev);
+	}
+
 	return dev->id;
 }
 
@@ -272,10 +287,7 @@
 {
 	BT_DBG("dev %p", dev);
 
-	write_lock_bh(&rfcomm_dev_lock);
-	list_del_init(&dev->list);
-	write_unlock_bh(&rfcomm_dev_lock);
-
+	set_bit(RFCOMM_TTY_RELEASED, &dev->flags);
 	rfcomm_dev_put(dev);
 }
 
@@ -329,7 +341,7 @@
 	if (copy_from_user(&req, arg, sizeof(req)))
 		return -EFAULT;
 
-	BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags);
+	BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
 
 	if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -370,7 +382,7 @@
 	if (copy_from_user(&req, arg, sizeof(req)))
 		return -EFAULT;
 
-	BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags);
+	BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
 
 	if (!(dev = rfcomm_dev_get(req.dev_id)))
 		return -ENODEV;
@@ -383,6 +395,10 @@
 	if (req.flags & (1 << RFCOMM_HANGUP_NOW))
 		rfcomm_dlc_close(dev->dlc, 0);
 
+	/* Shut down TTY synchronously before freeing rfcomm_dev */
+	if (dev->tty)
+		tty_vhangup(dev->tty);
+
 	rfcomm_dev_del(dev);
 	rfcomm_dev_put(dev);
 	return 0;
@@ -415,6 +431,8 @@
 
 	list_for_each(p, &rfcomm_dev_list) {
 		struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
+		if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
+			continue;
 		(di + n)->id      = dev->id;
 		(di + n)->flags   = dev->flags;
 		(di + n)->state   = dev->dlc->state;
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 849deaf..7b4ce91 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -368,10 +368,18 @@
 	list_for_each_entry(p, &br->port_list, list) {
 		unsigned long feature = p->dev->features;
 
+		/* if device needs checksumming, downgrade to hw checksumming */
 		if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
 			checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
+
+		/* if device can't do all checksum, downgrade to ipv4/ipv6 */
 		if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
-			checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM;
+			checksum ^= NETIF_F_HW_CSUM
+				| NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
+		if (checksum & NETIF_F_IPV6_CSUM && !(feature & NETIF_F_IPV6_CSUM))
+			checksum &= ~NETIF_F_IPV6_CSUM;
+
 		if (!(feature & NETIF_F_IP_CSUM))
 			checksum = 0;
 
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 33c6c4a..4f42263 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -360,8 +360,9 @@
  *
  * Returns the number of bytes read.
  */
-static ssize_t brforward_read(struct kobject *kobj, char *buf,
-			   loff_t off, size_t count)
+static ssize_t brforward_read(struct kobject *kobj,
+			      struct bin_attribute *bin_attr,
+			      char *buf, loff_t off, size_t count)
 {
 	struct device *dev = to_dev(kobj);
 	struct net_bridge *br = to_bridge(dev);
@@ -383,8 +384,7 @@
 
 static struct bin_attribute bridge_forward = {
 	.attr = { .name = SYSFS_BRIDGE_FDB,
-		  .mode = S_IRUGO,
-		  .owner = THIS_MODULE, },
+		  .mode = S_IRUGO, },
 	.read = brforward_read,
 };
 
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index 2da2292..79db51f 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -29,8 +29,7 @@
 #define BRPORT_ATTR(_name,_mode,_show,_store)		        \
 struct brport_attribute brport_attr_##_name = { 	        \
 	.attr = {.name = __stringify(_name), 			\
-		 .mode = _mode, 				\
-		 .owner = THIS_MODULE, },			\
+		 .mode = _mode },				\
 	.show	= _show,					\
 	.store	= _store,					\
 };
diff --git a/net/core/dev.c b/net/core/dev.c
index ee051bb..4221dcd 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -942,7 +942,7 @@
 		/*
 		 *	Initialize multicasting status
 		 */
-		dev_mc_upload(dev);
+		dev_set_rx_mode(dev);
 
 		/*
 		 *	Wakeup transmit queue engine
@@ -1429,7 +1429,9 @@
 			skb->next = nskb;
 			return rc;
 		}
-		if (unlikely(netif_queue_stopped(dev) && skb->next))
+		if (unlikely((netif_queue_stopped(dev) ||
+			     netif_subqueue_stopped(dev, skb->queue_mapping)) &&
+			     skb->next))
 			return NETDEV_TX_BUSY;
 	} while (skb->next);
 
@@ -1510,8 +1512,10 @@
 					      skb_headroom(skb));
 
 		if (!(dev->features & NETIF_F_GEN_CSUM) &&
-		    (!(dev->features & NETIF_F_IP_CSUM) ||
-		     skb->protocol != htons(ETH_P_IP)))
+		    !((dev->features & NETIF_F_IP_CSUM) &&
+		      skb->protocol == htons(ETH_P_IP)) &&
+		    !((dev->features & NETIF_F_IPV6_CSUM) &&
+		      skb->protocol == htons(ETH_P_IPV6)))
 			if (skb_checksum_help(skb))
 				goto out_kfree_skb;
 	}
@@ -1545,6 +1549,8 @@
 		spin_lock(&dev->queue_lock);
 		q = dev->qdisc;
 		if (q->enqueue) {
+			/* reset queue_mapping to zero */
+			skb->queue_mapping = 0;
 			rc = q->enqueue(skb, q);
 			qdisc_run(dev);
 			spin_unlock(&dev->queue_lock);
@@ -1574,7 +1580,8 @@
 
 			HARD_TX_LOCK(dev, cpu);
 
-			if (!netif_queue_stopped(dev)) {
+			if (!netif_queue_stopped(dev) &&
+			    !netif_subqueue_stopped(dev, skb->queue_mapping)) {
 				rc = 0;
 				if (!dev_hard_start_xmit(skb, dev)) {
 					HARD_TX_UNLOCK(dev);
@@ -2496,6 +2503,27 @@
 	return 0;
 }
 
+static void __dev_set_promiscuity(struct net_device *dev, int inc)
+{
+	unsigned short old_flags = dev->flags;
+
+	if ((dev->promiscuity += inc) == 0)
+		dev->flags &= ~IFF_PROMISC;
+	else
+		dev->flags |= IFF_PROMISC;
+	if (dev->flags != old_flags) {
+		printk(KERN_INFO "device %s %s promiscuous mode\n",
+		       dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
+							       "left");
+		audit_log(current->audit_context, GFP_ATOMIC,
+			AUDIT_ANOM_PROMISCUOUS,
+			"dev=%s prom=%d old_prom=%d auid=%u",
+			dev->name, (dev->flags & IFF_PROMISC),
+			(old_flags & IFF_PROMISC),
+			audit_get_loginuid(current->audit_context));
+	}
+}
+
 /**
  *	dev_set_promiscuity	- update promiscuity count on a device
  *	@dev: device
@@ -2510,22 +2538,9 @@
 {
 	unsigned short old_flags = dev->flags;
 
-	if ((dev->promiscuity += inc) == 0)
-		dev->flags &= ~IFF_PROMISC;
-	else
-		dev->flags |= IFF_PROMISC;
-	if (dev->flags != old_flags) {
-		dev_mc_upload(dev);
-		printk(KERN_INFO "device %s %s promiscuous mode\n",
-		       dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
-							       "left");
-		audit_log(current->audit_context, GFP_ATOMIC,
-			AUDIT_ANOM_PROMISCUOUS,
-			"dev=%s prom=%d old_prom=%d auid=%u",
-			dev->name, (dev->flags & IFF_PROMISC),
-			(old_flags & IFF_PROMISC),
-			audit_get_loginuid(current->audit_context));
-	}
+	__dev_set_promiscuity(dev, inc);
+	if (dev->flags != old_flags)
+		dev_set_rx_mode(dev);
 }
 
 /**
@@ -2548,7 +2563,176 @@
 	if ((dev->allmulti += inc) == 0)
 		dev->flags &= ~IFF_ALLMULTI;
 	if (dev->flags ^ old_flags)
-		dev_mc_upload(dev);
+		dev_set_rx_mode(dev);
+}
+
+/*
+ *	Upload unicast and multicast address lists to device and
+ *	configure RX filtering. When the device doesn't support unicast
+ *	filtering it is put in promiscous mode while unicast addresses
+ *	are present.
+ */
+void __dev_set_rx_mode(struct net_device *dev)
+{
+	/* dev_open will call this function so the list will stay sane. */
+	if (!(dev->flags&IFF_UP))
+		return;
+
+	if (!netif_device_present(dev))
+	        return;
+
+	if (dev->set_rx_mode)
+		dev->set_rx_mode(dev);
+	else {
+		/* Unicast addresses changes may only happen under the rtnl,
+		 * therefore calling __dev_set_promiscuity here is safe.
+		 */
+		if (dev->uc_count > 0 && !dev->uc_promisc) {
+			__dev_set_promiscuity(dev, 1);
+			dev->uc_promisc = 1;
+		} else if (dev->uc_count == 0 && dev->uc_promisc) {
+			__dev_set_promiscuity(dev, -1);
+			dev->uc_promisc = 0;
+		}
+
+		if (dev->set_multicast_list)
+			dev->set_multicast_list(dev);
+	}
+}
+
+void dev_set_rx_mode(struct net_device *dev)
+{
+	netif_tx_lock_bh(dev);
+	__dev_set_rx_mode(dev);
+	netif_tx_unlock_bh(dev);
+}
+
+int __dev_addr_delete(struct dev_addr_list **list, int *count,
+		      void *addr, int alen, int glbl)
+{
+	struct dev_addr_list *da;
+
+	for (; (da = *list) != NULL; list = &da->next) {
+		if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
+		    alen == da->da_addrlen) {
+			if (glbl) {
+				int old_glbl = da->da_gusers;
+				da->da_gusers = 0;
+				if (old_glbl == 0)
+					break;
+			}
+			if (--da->da_users)
+				return 0;
+
+			*list = da->next;
+			kfree(da);
+			(*count)--;
+			return 0;
+		}
+	}
+	return -ENOENT;
+}
+
+int __dev_addr_add(struct dev_addr_list **list, int *count,
+		   void *addr, int alen, int glbl)
+{
+	struct dev_addr_list *da;
+
+	for (da = *list; da != NULL; da = da->next) {
+		if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
+		    da->da_addrlen == alen) {
+			if (glbl) {
+				int old_glbl = da->da_gusers;
+				da->da_gusers = 1;
+				if (old_glbl)
+					return 0;
+			}
+			da->da_users++;
+			return 0;
+		}
+	}
+
+	da = kmalloc(sizeof(*da), GFP_ATOMIC);
+	if (da == NULL)
+		return -ENOMEM;
+	memcpy(da->da_addr, addr, alen);
+	da->da_addrlen = alen;
+	da->da_users = 1;
+	da->da_gusers = glbl ? 1 : 0;
+	da->next = *list;
+	*list = da;
+	(*count)++;
+	return 0;
+}
+
+void __dev_addr_discard(struct dev_addr_list **list)
+{
+	struct dev_addr_list *tmp;
+
+	while (*list != NULL) {
+		tmp = *list;
+		*list = tmp->next;
+		if (tmp->da_users > tmp->da_gusers)
+			printk("__dev_addr_discard: address leakage! "
+			       "da_users=%d\n", tmp->da_users);
+		kfree(tmp);
+	}
+}
+
+/**
+ *	dev_unicast_delete	- Release secondary unicast address.
+ *	@dev: device
+ *
+ *	Release reference to a secondary unicast address and remove it
+ *	from the device if the reference count drop to zero.
+ *
+ * 	The caller must hold the rtnl_mutex.
+ */
+int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
+{
+	int err;
+
+	ASSERT_RTNL();
+
+	netif_tx_lock_bh(dev);
+	err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
+	if (!err)
+		__dev_set_rx_mode(dev);
+	netif_tx_unlock_bh(dev);
+	return err;
+}
+EXPORT_SYMBOL(dev_unicast_delete);
+
+/**
+ *	dev_unicast_add		- add a secondary unicast address
+ *	@dev: device
+ *
+ *	Add a secondary unicast address to the device or increase
+ *	the reference count if it already exists.
+ *
+ *	The caller must hold the rtnl_mutex.
+ */
+int dev_unicast_add(struct net_device *dev, void *addr, int alen)
+{
+	int err;
+
+	ASSERT_RTNL();
+
+	netif_tx_lock_bh(dev);
+	err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
+	if (!err)
+		__dev_set_rx_mode(dev);
+	netif_tx_unlock_bh(dev);
+	return err;
+}
+EXPORT_SYMBOL(dev_unicast_add);
+
+static void dev_unicast_discard(struct net_device *dev)
+{
+	netif_tx_lock_bh(dev);
+	__dev_addr_discard(&dev->uc_list);
+	dev->uc_count = 0;
+	netif_tx_unlock_bh(dev);
 }
 
 unsigned dev_get_flags(const struct net_device *dev)
@@ -2594,7 +2778,7 @@
 	 *	Load in the correct multicast list now the flags have changed.
 	 */
 
-	dev_mc_upload(dev);
+	dev_set_rx_mode(dev);
 
 	/*
 	 *	Have we downed the interface. We handle IFF_UP ourselves
@@ -2607,7 +2791,7 @@
 		ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev);
 
 		if (!ret)
-			dev_mc_upload(dev);
+			dev_set_rx_mode(dev);
 	}
 
 	if (dev->flags & IFF_UP &&
@@ -3107,6 +3291,22 @@
 		}
 	}
 
+	/* Fix illegal checksum combinations */
+	if ((dev->features & NETIF_F_HW_CSUM) &&
+	    (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
+		printk(KERN_NOTICE "%s: mixed HW and IP checksum settings.\n",
+		       dev->name);
+		dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM);
+	}
+
+	if ((dev->features & NETIF_F_NO_CSUM) &&
+	    (dev->features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
+		printk(KERN_NOTICE "%s: mixed no checksumming and other settings.\n",
+		       dev->name);
+		dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM);
+	}
+
+
 	/* Fix illegal SG+CSUM combinations. */
 	if ((dev->features & NETIF_F_SG) &&
 	    !(dev->features & NETIF_F_ALL_CSUM)) {
@@ -3343,16 +3543,18 @@
 }
 
 /**
- *	alloc_netdev - allocate network device
+ *	alloc_netdev_mq - allocate network device
  *	@sizeof_priv:	size of private data to allocate space for
  *	@name:		device name format string
  *	@setup:		callback to initialize device
+ *	@queue_count:	the number of subqueues to allocate
  *
  *	Allocates a struct net_device with private data area for driver use
- *	and performs basic initialization.
+ *	and performs basic initialization.  Also allocates subquue structs
+ *	for each queue on the device at the end of the netdevice.
  */
-struct net_device *alloc_netdev(int sizeof_priv, const char *name,
-		void (*setup)(struct net_device *))
+struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
+		void (*setup)(struct net_device *), unsigned int queue_count)
 {
 	void *p;
 	struct net_device *dev;
@@ -3361,7 +3563,9 @@
 	BUG_ON(strlen(name) >= sizeof(dev->name));
 
 	/* ensure 32-byte alignment of both the device and private area */
-	alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST;
+	alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST +
+		     (sizeof(struct net_device_subqueue) * queue_count)) &
+		     ~NETDEV_ALIGN_CONST;
 	alloc_size += sizeof_priv + NETDEV_ALIGN_CONST;
 
 	p = kzalloc(alloc_size, GFP_KERNEL);
@@ -3374,15 +3578,22 @@
 		(((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
 	dev->padded = (char *)dev - (char *)p;
 
-	if (sizeof_priv)
-		dev->priv = netdev_priv(dev);
+	if (sizeof_priv) {
+		dev->priv = ((char *)dev +
+			     ((sizeof(struct net_device) +
+			       (sizeof(struct net_device_subqueue) *
+				queue_count) + NETDEV_ALIGN_CONST)
+			      & ~NETDEV_ALIGN_CONST));
+	}
+
+	dev->egress_subqueue_count = queue_count;
 
 	dev->get_stats = internal_stats;
 	setup(dev);
 	strcpy(dev->name, name);
 	return dev;
 }
-EXPORT_SYMBOL(alloc_netdev);
+EXPORT_SYMBOL(alloc_netdev_mq);
 
 /**
  *	free_netdev - free network device
@@ -3471,8 +3682,9 @@
 	raw_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
 
 	/*
-	 *	Flush the multicast chain
+	 *	Flush the unicast and multicast chains
 	 */
+	dev_unicast_discard(dev);
 	dev_mc_discard(dev);
 
 	if (dev->uninit)
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index 5a54053..aa38100 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -64,85 +64,24 @@
  */
 
 /*
- *	Update the multicast list into the physical NIC controller.
- */
-
-static void __dev_mc_upload(struct net_device *dev)
-{
-	/* Don't do anything till we up the interface
-	 * [dev_open will call this function so the list will
-	 * stay sane]
-	 */
-
-	if (!(dev->flags&IFF_UP))
-		return;
-
-	/*
-	 *	Devices with no set multicast or which have been
-	 *	detached don't get set.
-	 */
-
-	if (dev->set_multicast_list == NULL ||
-	    !netif_device_present(dev))
-		return;
-
-	dev->set_multicast_list(dev);
-}
-
-void dev_mc_upload(struct net_device *dev)
-{
-	netif_tx_lock_bh(dev);
-	__dev_mc_upload(dev);
-	netif_tx_unlock_bh(dev);
-}
-
-/*
  *	Delete a device level multicast
  */
 
 int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
 {
-	int err = 0;
-	struct dev_mc_list *dmi, **dmip;
+	int err;
 
 	netif_tx_lock_bh(dev);
-
-	for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) {
+	err = __dev_addr_delete(&dev->mc_list, &dev->mc_count,
+				addr, alen, glbl);
+	if (!err) {
 		/*
-		 *	Find the entry we want to delete. The device could
-		 *	have variable length entries so check these too.
+		 *	We have altered the list, so the card
+		 *	loaded filter is now wrong. Fix it
 		 */
-		if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
-		    alen == dmi->dmi_addrlen) {
-			if (glbl) {
-				int old_glbl = dmi->dmi_gusers;
-				dmi->dmi_gusers = 0;
-				if (old_glbl == 0)
-					break;
-			}
-			if (--dmi->dmi_users)
-				goto done;
 
-			/*
-			 *	Last user. So delete the entry.
-			 */
-			*dmip = dmi->next;
-			dev->mc_count--;
-
-			kfree(dmi);
-
-			/*
-			 *	We have altered the list, so the card
-			 *	loaded filter is now wrong. Fix it
-			 */
-			__dev_mc_upload(dev);
-
-			netif_tx_unlock_bh(dev);
-			return 0;
-		}
+		__dev_set_rx_mode(dev);
 	}
-	err = -ENOENT;
-done:
 	netif_tx_unlock_bh(dev);
 	return err;
 }
@@ -153,46 +92,13 @@
 
 int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
 {
-	int err = 0;
-	struct dev_mc_list *dmi, *dmi1;
-
-	dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC);
+	int err;
 
 	netif_tx_lock_bh(dev);
-	for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) {
-		if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
-		    dmi->dmi_addrlen == alen) {
-			if (glbl) {
-				int old_glbl = dmi->dmi_gusers;
-				dmi->dmi_gusers = 1;
-				if (old_glbl)
-					goto done;
-			}
-			dmi->dmi_users++;
-			goto done;
-		}
-	}
-
-	if ((dmi = dmi1) == NULL) {
-		netif_tx_unlock_bh(dev);
-		return -ENOMEM;
-	}
-	memcpy(dmi->dmi_addr, addr, alen);
-	dmi->dmi_addrlen = alen;
-	dmi->next = dev->mc_list;
-	dmi->dmi_users = 1;
-	dmi->dmi_gusers = glbl ? 1 : 0;
-	dev->mc_list = dmi;
-	dev->mc_count++;
-
-	__dev_mc_upload(dev);
-
+	err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
+	if (!err)
+		__dev_set_rx_mode(dev);
 	netif_tx_unlock_bh(dev);
-	return 0;
-
-done:
-	netif_tx_unlock_bh(dev);
-	kfree(dmi1);
 	return err;
 }
 
@@ -203,16 +109,8 @@
 void dev_mc_discard(struct net_device *dev)
 {
 	netif_tx_lock_bh(dev);
-
-	while (dev->mc_list != NULL) {
-		struct dev_mc_list *tmp = dev->mc_list;
-		dev->mc_list = tmp->next;
-		if (tmp->dmi_users > tmp->dmi_gusers)
-			printk("dev_mc_discard: multicast leakage! dmi_users=%d\n", tmp->dmi_users);
-		kfree(tmp);
-	}
+	__dev_addr_discard(&dev->mc_list);
 	dev->mc_count = 0;
-
 	netif_tx_unlock_bh(dev);
 }
 
@@ -244,7 +142,7 @@
 
 static int dev_mc_seq_show(struct seq_file *seq, void *v)
 {
-	struct dev_mc_list *m;
+	struct dev_addr_list *m;
 	struct net_device *dev = v;
 
 	netif_tx_lock_bh(dev);
@@ -292,4 +190,3 @@
 
 EXPORT_SYMBOL(dev_mc_add);
 EXPORT_SYMBOL(dev_mc_delete);
-EXPORT_SYMBOL(dev_mc_upload);
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
index 17daf4c..cc84d8d 100644
--- a/net/core/gen_estimator.c
+++ b/net/core/gen_estimator.c
@@ -128,7 +128,8 @@
 		spin_unlock(e->stats_lock);
 	}
 
-	mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
+	if (elist[idx].list != NULL)
+		mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
 	read_unlock(&est_lock);
 }
 
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a0efdd7..d1264e9 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -66,8 +66,9 @@
 
 		local_irq_save(flags);
 		netif_tx_lock(dev);
-		if (netif_queue_stopped(dev) ||
-		    dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
+		if ((netif_queue_stopped(dev) ||
+		     netif_subqueue_stopped(dev, skb->queue_mapping)) ||
+		     dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
 			skb_queue_head(&npinfo->txq, skb);
 			netif_tx_unlock(dev);
 			local_irq_restore(flags);
@@ -123,6 +124,13 @@
 	if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) &&
 	    npinfo->poll_owner != smp_processor_id() &&
 	    spin_trylock(&npinfo->poll_lock)) {
+		/* When calling dev->poll from poll_napi, we may end up in
+		 * netif_rx_complete. However, only the CPU to which the
+		 * device was queued is allowed to remove it from poll_list.
+		 * Setting POLL_LIST_FROZEN tells netif_rx_complete
+		 * to leave the NAPI state alone.
+		 */
+		set_bit(__LINK_STATE_POLL_LIST_FROZEN, &np->dev->state);
 		npinfo->rx_flags |= NETPOLL_RX_DROP;
 		atomic_inc(&trapped);
 
@@ -130,6 +138,7 @@
 
 		atomic_dec(&trapped);
 		npinfo->rx_flags &= ~NETPOLL_RX_DROP;
+		clear_bit(__LINK_STATE_POLL_LIST_FROZEN, &np->dev->state);
 		spin_unlock(&npinfo->poll_lock);
 	}
 }
@@ -254,7 +263,8 @@
 		for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
 		     tries > 0; --tries) {
 			if (netif_tx_trylock(dev)) {
-				if (!netif_queue_stopped(dev))
+				if (!netif_queue_stopped(dev) &&
+				    !netif_subqueue_stopped(dev, skb->queue_mapping))
 					status = dev->hard_start_xmit(skb, dev);
 				netif_tx_unlock(dev);
 
@@ -781,7 +791,6 @@
 				spin_unlock_irqrestore(&npinfo->rx_lock, flags);
 			}
 
-			np->dev->npinfo = NULL;
 			if (atomic_dec_and_test(&npinfo->refcnt)) {
 				skb_queue_purge(&npinfo->arp_tx);
 				skb_queue_purge(&npinfo->txq);
@@ -794,6 +803,7 @@
 					kfree_skb(skb);
 				}
 				kfree(npinfo);
+				np->dev->npinfo = NULL;
 			}
 		}
 
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 9cd3a1c..7521533 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -152,6 +152,9 @@
 #include <net/checksum.h>
 #include <net/ipv6.h>
 #include <net/addrconf.h>
+#ifdef CONFIG_XFRM
+#include <net/xfrm.h>
+#endif
 #include <asm/byteorder.h>
 #include <linux/rcupdate.h>
 #include <asm/bitops.h>
@@ -181,6 +184,8 @@
 #define F_MPLS_RND    (1<<8)	/* Random MPLS labels */
 #define F_VID_RND     (1<<9)	/* Random VLAN ID */
 #define F_SVID_RND    (1<<10)	/* Random SVLAN ID */
+#define F_FLOW_SEQ    (1<<11)	/* Sequential flows */
+#define F_IPSEC_ON    (1<<12)	/* ipsec on for flows */
 
 /* Thread control flag bits */
 #define T_TERMINATE   (1<<0)
@@ -207,8 +212,15 @@
 struct flow_state {
 	__be32 cur_daddr;
 	int count;
+#ifdef CONFIG_XFRM
+	struct xfrm_state *x;
+#endif
+	__u32 flags;
 };
 
+/* flow flag bits */
+#define F_INIT   (1<<0)		/* flow has been initialized */
+
 struct pktgen_dev {
 	/*
 	 * Try to keep frequent/infrequent used vars. separated.
@@ -228,6 +240,7 @@
 
 	int min_pkt_size;	/* = ETH_ZLEN; */
 	int max_pkt_size;	/* = ETH_ZLEN; */
+	int pkt_overhead;	/* overhead for MPLS, VLANs, IPSEC etc */
 	int nfrags;
 	__u32 delay_us;		/* Default delay */
 	__u32 delay_ns;
@@ -341,7 +354,11 @@
 	unsigned cflows;	/* Concurrent flows (config) */
 	unsigned lflow;		/* Flow length  (config) */
 	unsigned nflows;	/* accumulated flows (stats) */
-
+	unsigned curfl;		/* current sequenced flow (state)*/
+#ifdef CONFIG_XFRM
+	__u8	ipsmode;		/* IPSEC mode (config) */
+	__u8	ipsproto;		/* IPSEC type (config) */
+#endif
 	char result[512];
 };
 
@@ -690,6 +707,18 @@
 	if (pkt_dev->flags & F_MPLS_RND)
 		seq_printf(seq,  "MPLS_RND  ");
 
+	if (pkt_dev->cflows) {
+		if (pkt_dev->flags & F_FLOW_SEQ)
+			seq_printf(seq,  "FLOW_SEQ  "); /*in sequence flows*/
+		else
+			seq_printf(seq,  "FLOW_RND  ");
+	}
+
+#ifdef CONFIG_XFRM
+	if (pkt_dev->flags & F_IPSEC_ON)
+		seq_printf(seq,  "IPSEC  ");
+#endif
+
 	if (pkt_dev->flags & F_MACSRC_RND)
 		seq_printf(seq, "MACSRC_RND  ");
 
@@ -1181,6 +1210,14 @@
 		else if (strcmp(f, "!SVID_RND") == 0)
 			pkt_dev->flags &= ~F_SVID_RND;
 
+		else if (strcmp(f, "FLOW_SEQ") == 0)
+			pkt_dev->flags |= F_FLOW_SEQ;
+
+#ifdef CONFIG_XFRM
+		else if (strcmp(f, "IPSEC") == 0)
+			pkt_dev->flags |= F_IPSEC_ON;
+#endif
+
 		else if (strcmp(f, "!IPV6") == 0)
 			pkt_dev->flags &= ~F_IPV6;
 
@@ -1189,7 +1226,7 @@
 				"Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
 				f,
 				"IPSRC_RND, IPDST_RND, UDPSRC_RND, UDPDST_RND, "
-				"MACSRC_RND, MACDST_RND, TXSIZE_RND, IPV6, MPLS_RND, VID_RND, SVID_RND\n");
+				"MACSRC_RND, MACDST_RND, TXSIZE_RND, IPV6, MPLS_RND, VID_RND, SVID_RND, FLOW_SEQ, IPSEC\n");
 			return count;
 		}
 		sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags);
@@ -2075,6 +2112,70 @@
 	pkt_dev->idle_acc += now - start;
 }
 
+static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
+{
+	pkt_dev->pkt_overhead = 0;
+	pkt_dev->pkt_overhead += pkt_dev->nr_labels*sizeof(u32);
+	pkt_dev->pkt_overhead += VLAN_TAG_SIZE(pkt_dev);
+	pkt_dev->pkt_overhead += SVLAN_TAG_SIZE(pkt_dev);
+}
+
+static inline int f_seen(struct pktgen_dev *pkt_dev, int flow)
+{
+
+	if (pkt_dev->flows[flow].flags & F_INIT)
+		return 1;
+	else
+		return 0;
+}
+
+static inline int f_pick(struct pktgen_dev *pkt_dev)
+{
+	int flow = pkt_dev->curfl;
+
+	if (pkt_dev->flags & F_FLOW_SEQ) {
+		if (pkt_dev->flows[flow].count >= pkt_dev->lflow) {
+			/* reset time */
+			pkt_dev->flows[flow].count = 0;
+			pkt_dev->curfl += 1;
+			if (pkt_dev->curfl >= pkt_dev->cflows)
+				pkt_dev->curfl = 0; /*reset */
+		}
+	} else {
+		flow = random32() % pkt_dev->cflows;
+
+		if (pkt_dev->flows[flow].count > pkt_dev->lflow)
+			pkt_dev->flows[flow].count = 0;
+	}
+
+	return pkt_dev->curfl;
+}
+
+
+#ifdef CONFIG_XFRM
+/* If there was already an IPSEC SA, we keep it as is, else
+ * we go look for it ...
+*/
+inline
+void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
+{
+	struct xfrm_state *x = pkt_dev->flows[flow].x;
+	if (!x) {
+		/*slow path: we dont already have xfrm_state*/
+		x = xfrm_stateonly_find((xfrm_address_t *)&pkt_dev->cur_daddr,
+					(xfrm_address_t *)&pkt_dev->cur_saddr,
+					AF_INET,
+					pkt_dev->ipsmode,
+					pkt_dev->ipsproto, 0);
+		if (x) {
+			pkt_dev->flows[flow].x = x;
+			set_pkt_overhead(pkt_dev);
+			pkt_dev->pkt_overhead+=x->props.header_len;
+		}
+
+	}
+}
+#endif
 /* Increment/randomize headers according to flags and current values
  * for IP src/dest, UDP src/dst port, MAC-Addr src/dst
  */
@@ -2084,12 +2185,8 @@
 	__u32 imx;
 	int flow = 0;
 
-	if (pkt_dev->cflows) {
-		flow = random32() % pkt_dev->cflows;
-
-		if (pkt_dev->flows[flow].count > pkt_dev->lflow)
-			pkt_dev->flows[flow].count = 0;
-	}
+	if (pkt_dev->cflows)
+		flow = f_pick(pkt_dev);
 
 	/*  Deal with source MAC */
 	if (pkt_dev->src_mac_count > 1) {
@@ -2205,7 +2302,7 @@
 			pkt_dev->cur_saddr = htonl(t);
 		}
 
-		if (pkt_dev->cflows && pkt_dev->flows[flow].count != 0) {
+		if (pkt_dev->cflows && f_seen(pkt_dev, flow)) {
 			pkt_dev->cur_daddr = pkt_dev->flows[flow].cur_daddr;
 		} else {
 			imn = ntohl(pkt_dev->daddr_min);
@@ -2235,8 +2332,13 @@
 				}
 			}
 			if (pkt_dev->cflows) {
+				pkt_dev->flows[flow].flags |= F_INIT;
 				pkt_dev->flows[flow].cur_daddr =
 				    pkt_dev->cur_daddr;
+#ifdef CONFIG_XFRM
+				if (pkt_dev->flags & F_IPSEC_ON)
+					get_ipsec_sa(pkt_dev, flow);
+#endif
 				pkt_dev->nflows++;
 			}
 		}
@@ -2277,6 +2379,91 @@
 	pkt_dev->flows[flow].count++;
 }
 
+
+#ifdef CONFIG_XFRM
+static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
+{
+	struct xfrm_state *x = pkt_dev->flows[pkt_dev->curfl].x;
+	int err = 0;
+	struct iphdr *iph;
+
+	if (!x)
+		return 0;
+	/* XXX: we dont support tunnel mode for now until
+	 * we resolve the dst issue */
+	if (x->props.mode != XFRM_MODE_TRANSPORT)
+		return 0;
+
+	spin_lock(&x->lock);
+	iph = ip_hdr(skb);
+
+	err = x->mode->output(x, skb);
+	if (err)
+		goto error;
+	err = x->type->output(x, skb);
+	if (err)
+		goto error;
+
+	x->curlft.bytes +=skb->len;
+	x->curlft.packets++;
+	spin_unlock(&x->lock);
+
+error:
+	spin_unlock(&x->lock);
+	return err;
+}
+
+static inline void free_SAs(struct pktgen_dev *pkt_dev)
+{
+	if (pkt_dev->cflows) {
+		/* let go of the SAs if we have them */
+		int i = 0;
+		for (;  i < pkt_dev->nflows; i++){
+			struct xfrm_state *x = pkt_dev->flows[i].x;
+			if (x) {
+				xfrm_state_put(x);
+				pkt_dev->flows[i].x = NULL;
+			}
+		}
+	}
+}
+
+static inline int process_ipsec(struct pktgen_dev *pkt_dev,
+			      struct sk_buff *skb, __be16 protocol)
+{
+	if (pkt_dev->flags & F_IPSEC_ON) {
+		struct xfrm_state *x = pkt_dev->flows[pkt_dev->curfl].x;
+		int nhead = 0;
+		if (x) {
+			int ret;
+			__u8 *eth;
+			nhead = x->props.header_len - skb_headroom(skb);
+			if (nhead >0) {
+				ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
+				if (ret < 0) {
+					printk("Error expanding ipsec packet %d\n",ret);
+					return 0;
+				}
+			}
+
+			/* ipsec is not expecting ll header */
+			skb_pull(skb, ETH_HLEN);
+			ret = pktgen_output_ipsec(skb, pkt_dev);
+			if (ret) {
+				printk("Error creating ipsec packet %d\n",ret);
+				kfree_skb(skb);
+				return 0;
+			}
+			/* restore ll */
+			eth = (__u8 *) skb_push(skb, ETH_HLEN);
+			memcpy(eth, pkt_dev->hh, 12);
+			*(u16 *) & eth[12] = protocol;
+		}
+	}
+	return 1;
+}
+#endif
+
 static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev)
 {
 	unsigned i;
@@ -2323,9 +2510,7 @@
 
 	datalen = (odev->hard_header_len + 16) & ~0xf;
 	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen +
-			pkt_dev->nr_labels*sizeof(u32) +
-			VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
-			GFP_ATOMIC);
+			pkt_dev->pkt_overhead, GFP_ATOMIC);
 	if (!skb) {
 		sprintf(pkt_dev->result, "No memory");
 		return NULL;
@@ -2368,7 +2553,7 @@
 
 	/* Eth + IPh + UDPh + mpls */
 	datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -
-		  pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
+		  pkt_dev->pkt_overhead;
 	if (datalen < sizeof(struct pktgen_hdr))
 		datalen = sizeof(struct pktgen_hdr);
 
@@ -2391,8 +2576,7 @@
 	iph->check = ip_fast_csum((void *)iph, iph->ihl);
 	skb->protocol = protocol;
 	skb->mac_header = (skb->network_header - ETH_HLEN -
-			   pkt_dev->nr_labels * sizeof(u32) -
-			   VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev));
+			   pkt_dev->pkt_overhead);
 	skb->dev = odev;
 	skb->pkt_type = PACKET_HOST;
 
@@ -2463,6 +2647,11 @@
 		pgh->tv_usec = htonl(timestamp.tv_usec);
 	}
 
+#ifdef CONFIG_XFRM
+	if (!process_ipsec(pkt_dev, skb, protocol))
+		return NULL;
+#endif
+
 	return skb;
 }
 
@@ -2662,9 +2851,7 @@
 	mod_cur_headers(pkt_dev);
 
 	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
-			pkt_dev->nr_labels*sizeof(u32) +
-			VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
-			GFP_ATOMIC);
+			pkt_dev->pkt_overhead, GFP_ATOMIC);
 	if (!skb) {
 		sprintf(pkt_dev->result, "No memory");
 		return NULL;
@@ -2708,7 +2895,7 @@
 	/* Eth + IPh + UDPh + mpls */
 	datalen = pkt_dev->cur_pkt_size - 14 -
 		  sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
-		  pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev);
+		  pkt_dev->pkt_overhead;
 
 	if (datalen < sizeof(struct pktgen_hdr)) {
 		datalen = sizeof(struct pktgen_hdr);
@@ -2738,8 +2925,7 @@
 	ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
 
 	skb->mac_header = (skb->network_header - ETH_HLEN -
-			   pkt_dev->nr_labels * sizeof(u32) -
-			   VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev));
+			   pkt_dev->pkt_overhead);
 	skb->protocol = protocol;
 	skb->dev = odev;
 	skb->pkt_type = PACKET_HOST;
@@ -2857,6 +3043,7 @@
 			pkt_dev->started_at = getCurUs();
 			pkt_dev->next_tx_us = getCurUs();	/* Transmit immediately */
 			pkt_dev->next_tx_ns = 0;
+			set_pkt_overhead(pkt_dev);
 
 			strcpy(pkt_dev->result, "Starting");
 			started++;
@@ -3139,7 +3326,9 @@
 		}
 	}
 
-	if (netif_queue_stopped(odev) || need_resched()) {
+	if ((netif_queue_stopped(odev) ||
+	     netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) ||
+	     need_resched()) {
 		idle_start = getCurUs();
 
 		if (!netif_running(odev)) {
@@ -3154,7 +3343,8 @@
 
 		pkt_dev->idle_acc += getCurUs() - idle_start;
 
-		if (netif_queue_stopped(odev)) {
+		if (netif_queue_stopped(odev) ||
+		    netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) {
 			pkt_dev->next_tx_us = getCurUs();	/* TODO */
 			pkt_dev->next_tx_ns = 0;
 			goto out;	/* Try the next interface */
@@ -3181,7 +3371,8 @@
 	}
 
 	netif_tx_lock_bh(odev);
-	if (!netif_queue_stopped(odev)) {
+	if (!netif_queue_stopped(odev) &&
+	    !netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) {
 
 		atomic_inc(&(pkt_dev->skb->users));
 	      retry_now:
@@ -3446,11 +3637,18 @@
 	}
 	pkt_dev->entry->proc_fops = &pktgen_if_fops;
 	pkt_dev->entry->data = pkt_dev;
+#ifdef CONFIG_XFRM
+	pkt_dev->ipsmode = XFRM_MODE_TRANSPORT;
+	pkt_dev->ipsproto = IPPROTO_ESP;
+#endif
 
 	return add_dev_to_thread(t, pkt_dev);
 out2:
 	dev_put(pkt_dev->odev);
 out1:
+#ifdef CONFIG_XFRM
+	free_SAs(pkt_dev);
+#endif
 	if (pkt_dev->flows)
 		vfree(pkt_dev->flows);
 	kfree(pkt_dev);
@@ -3545,6 +3743,9 @@
 	if (pkt_dev->entry)
 		remove_proc_entry(pkt_dev->entry->name, pg_proc_dir);
 
+#ifdef CONFIG_XFRM
+	free_SAs(pkt_dev);
+#endif
 	if (pkt_dev->flows)
 		vfree(pkt_dev->flows);
 	kfree(pkt_dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 02e8bf0..864cbdf 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -97,6 +97,19 @@
 	return 0;
 }
 
+int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+			         struct rtattr *rta, int len)
+{
+	if (RTA_PAYLOAD(rta) < len)
+		return -1;
+	if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
+		rta = RTA_DATA(rta) + RTA_ALIGN(len);
+		return rtattr_parse_nested(tb, maxattr, rta);
+	}
+	memset(tb, 0, sizeof(struct rtattr *) * maxattr);
+	return 0;
+}
+
 static struct rtnl_link *rtnl_msg_handlers[NPROTO];
 
 static inline int rtm_msgindex(int msgtype)
@@ -243,6 +256,150 @@
 
 EXPORT_SYMBOL_GPL(rtnl_unregister_all);
 
+static LIST_HEAD(link_ops);
+
+/**
+ * __rtnl_link_register - Register rtnl_link_ops with rtnetlink.
+ * @ops: struct rtnl_link_ops * to register
+ *
+ * The caller must hold the rtnl_mutex. This function should be used
+ * by drivers that create devices during module initialization. It
+ * must be called before registering the devices.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int __rtnl_link_register(struct rtnl_link_ops *ops)
+{
+	if (!ops->dellink)
+		ops->dellink = unregister_netdevice;
+
+	list_add_tail(&ops->list, &link_ops);
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(__rtnl_link_register);
+
+/**
+ * rtnl_link_register - Register rtnl_link_ops with rtnetlink.
+ * @ops: struct rtnl_link_ops * to register
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int rtnl_link_register(struct rtnl_link_ops *ops)
+{
+	int err;
+
+	rtnl_lock();
+	err = __rtnl_link_register(ops);
+	rtnl_unlock();
+	return err;
+}
+
+EXPORT_SYMBOL_GPL(rtnl_link_register);
+
+/**
+ * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
+ * @ops: struct rtnl_link_ops * to unregister
+ *
+ * The caller must hold the rtnl_mutex.
+ */
+void __rtnl_link_unregister(struct rtnl_link_ops *ops)
+{
+	struct net_device *dev, *n;
+
+	for_each_netdev_safe(dev, n) {
+		if (dev->rtnl_link_ops == ops)
+			ops->dellink(dev);
+	}
+	list_del(&ops->list);
+}
+
+EXPORT_SYMBOL_GPL(__rtnl_link_unregister);
+
+/**
+ * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
+ * @ops: struct rtnl_link_ops * to unregister
+ */
+void rtnl_link_unregister(struct rtnl_link_ops *ops)
+{
+	rtnl_lock();
+	__rtnl_link_unregister(ops);
+	rtnl_unlock();
+}
+
+EXPORT_SYMBOL_GPL(rtnl_link_unregister);
+
+static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind)
+{
+	const struct rtnl_link_ops *ops;
+
+	list_for_each_entry(ops, &link_ops, list) {
+		if (!strcmp(ops->kind, kind))
+			return ops;
+	}
+	return NULL;
+}
+
+static size_t rtnl_link_get_size(const struct net_device *dev)
+{
+	const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
+	size_t size;
+
+	if (!ops)
+		return 0;
+
+	size = nlmsg_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */
+	       nlmsg_total_size(strlen(ops->kind) + 1);	 /* IFLA_INFO_KIND */
+
+	if (ops->get_size)
+		/* IFLA_INFO_DATA + nested data */
+		size += nlmsg_total_size(sizeof(struct nlattr)) +
+			ops->get_size(dev);
+
+	if (ops->get_xstats_size)
+		size += ops->get_xstats_size(dev);	/* IFLA_INFO_XSTATS */
+
+	return size;
+}
+
+static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev)
+{
+	const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
+	struct nlattr *linkinfo, *data;
+	int err = -EMSGSIZE;
+
+	linkinfo = nla_nest_start(skb, IFLA_LINKINFO);
+	if (linkinfo == NULL)
+		goto out;
+
+	if (nla_put_string(skb, IFLA_INFO_KIND, ops->kind) < 0)
+		goto err_cancel_link;
+	if (ops->fill_xstats) {
+		err = ops->fill_xstats(skb, dev);
+		if (err < 0)
+			goto err_cancel_link;
+	}
+	if (ops->fill_info) {
+		data = nla_nest_start(skb, IFLA_INFO_DATA);
+		if (data == NULL)
+			goto err_cancel_link;
+		err = ops->fill_info(skb, dev);
+		if (err < 0)
+			goto err_cancel_data;
+		nla_nest_end(skb, data);
+	}
+
+	nla_nest_end(skb, linkinfo);
+	return 0;
+
+err_cancel_data:
+	nla_nest_cancel(skb, data);
+err_cancel_link:
+	nla_nest_cancel(skb, linkinfo);
+out:
+	return err;
+}
+
 static const int rtm_min[RTM_NR_FAMILIES] =
 {
 	[RTM_FAM(RTM_NEWLINK)]      = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
@@ -437,7 +594,7 @@
 	a->tx_compressed = b->tx_compressed;
 };
 
-static inline size_t if_nlmsg_size(void)
+static inline size_t if_nlmsg_size(const struct net_device *dev)
 {
 	return NLMSG_ALIGN(sizeof(struct ifinfomsg))
 	       + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
@@ -452,7 +609,8 @@
 	       + nla_total_size(4) /* IFLA_LINK */
 	       + nla_total_size(4) /* IFLA_MASTER */
 	       + nla_total_size(1) /* IFLA_OPERSTATE */
-	       + nla_total_size(1); /* IFLA_LINKMODE */
+	       + nla_total_size(1) /* IFLA_LINKMODE */
+	       + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
 }
 
 static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
@@ -522,6 +680,11 @@
 		}
 	}
 
+	if (dev->rtnl_link_ops) {
+		if (rtnl_link_fill(skb, dev) < 0)
+			goto nla_put_failure;
+	}
+
 	return nlmsg_end(skb, nlh);
 
 nla_put_failure:
@@ -553,6 +716,8 @@
 
 static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
 	[IFLA_IFNAME]		= { .type = NLA_STRING, .len = IFNAMSIZ-1 },
+	[IFLA_ADDRESS]		= { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
+	[IFLA_BROADCAST]	= { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
 	[IFLA_MAP]		= { .len = sizeof(struct rtnl_link_ifmap) },
 	[IFLA_MTU]		= { .type = NLA_U32 },
 	[IFLA_TXQLEN]		= { .type = NLA_U32 },
@@ -561,11 +726,145 @@
 	[IFLA_LINKMODE]		= { .type = NLA_U8 },
 };
 
+static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
+	[IFLA_INFO_KIND]	= { .type = NLA_STRING },
+	[IFLA_INFO_DATA]	= { .type = NLA_NESTED },
+};
+
+static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
+		      struct nlattr **tb, char *ifname, int modified)
+{
+	int send_addr_notify = 0;
+	int err;
+
+	if (tb[IFLA_MAP]) {
+		struct rtnl_link_ifmap *u_map;
+		struct ifmap k_map;
+
+		if (!dev->set_config) {
+			err = -EOPNOTSUPP;
+			goto errout;
+		}
+
+		if (!netif_device_present(dev)) {
+			err = -ENODEV;
+			goto errout;
+		}
+
+		u_map = nla_data(tb[IFLA_MAP]);
+		k_map.mem_start = (unsigned long) u_map->mem_start;
+		k_map.mem_end = (unsigned long) u_map->mem_end;
+		k_map.base_addr = (unsigned short) u_map->base_addr;
+		k_map.irq = (unsigned char) u_map->irq;
+		k_map.dma = (unsigned char) u_map->dma;
+		k_map.port = (unsigned char) u_map->port;
+
+		err = dev->set_config(dev, &k_map);
+		if (err < 0)
+			goto errout;
+
+		modified = 1;
+	}
+
+	if (tb[IFLA_ADDRESS]) {
+		struct sockaddr *sa;
+		int len;
+
+		if (!dev->set_mac_address) {
+			err = -EOPNOTSUPP;
+			goto errout;
+		}
+
+		if (!netif_device_present(dev)) {
+			err = -ENODEV;
+			goto errout;
+		}
+
+		len = sizeof(sa_family_t) + dev->addr_len;
+		sa = kmalloc(len, GFP_KERNEL);
+		if (!sa) {
+			err = -ENOMEM;
+			goto errout;
+		}
+		sa->sa_family = dev->type;
+		memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
+		       dev->addr_len);
+		err = dev->set_mac_address(dev, sa);
+		kfree(sa);
+		if (err)
+			goto errout;
+		send_addr_notify = 1;
+		modified = 1;
+	}
+
+	if (tb[IFLA_MTU]) {
+		err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
+		if (err < 0)
+			goto errout;
+		modified = 1;
+	}
+
+	/*
+	 * Interface selected by interface index but interface
+	 * name provided implies that a name change has been
+	 * requested.
+	 */
+	if (ifm->ifi_index > 0 && ifname[0]) {
+		err = dev_change_name(dev, ifname);
+		if (err < 0)
+			goto errout;
+		modified = 1;
+	}
+
+	if (tb[IFLA_BROADCAST]) {
+		nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len);
+		send_addr_notify = 1;
+	}
+
+	if (ifm->ifi_flags || ifm->ifi_change) {
+		unsigned int flags = ifm->ifi_flags;
+
+		/* bugwards compatibility: ifi_change == 0 is treated as ~0 */
+		if (ifm->ifi_change)
+			flags = (flags & ifm->ifi_change) |
+				(dev->flags & ~ifm->ifi_change);
+		dev_change_flags(dev, flags);
+	}
+
+	if (tb[IFLA_TXQLEN])
+		dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
+
+	if (tb[IFLA_WEIGHT])
+		dev->weight = nla_get_u32(tb[IFLA_WEIGHT]);
+
+	if (tb[IFLA_OPERSTATE])
+		set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
+
+	if (tb[IFLA_LINKMODE]) {
+		write_lock_bh(&dev_base_lock);
+		dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
+		write_unlock_bh(&dev_base_lock);
+	}
+
+	err = 0;
+
+errout:
+	if (err < 0 && modified && net_ratelimit())
+		printk(KERN_WARNING "A link change request failed with "
+		       "some changes comitted already. Interface %s may "
+		       "have been left with an inconsistent configuration, "
+		       "please check.\n", dev->name);
+
+	if (send_addr_notify)
+		call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+	return err;
+}
+
 static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
 	struct ifinfomsg *ifm;
 	struct net_device *dev;
-	int err, send_addr_notify = 0, modified = 0;
+	int err;
 	struct nlattr *tb[IFLA_MAX+1];
 	char ifname[IFNAMSIZ];
 
@@ -600,133 +899,197 @@
 	    nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
 		goto errout_dev;
 
-	if (tb[IFLA_MAP]) {
-		struct rtnl_link_ifmap *u_map;
-		struct ifmap k_map;
-
-		if (!dev->set_config) {
-			err = -EOPNOTSUPP;
-			goto errout_dev;
-		}
-
-		if (!netif_device_present(dev)) {
-			err = -ENODEV;
-			goto errout_dev;
-		}
-
-		u_map = nla_data(tb[IFLA_MAP]);
-		k_map.mem_start = (unsigned long) u_map->mem_start;
-		k_map.mem_end = (unsigned long) u_map->mem_end;
-		k_map.base_addr = (unsigned short) u_map->base_addr;
-		k_map.irq = (unsigned char) u_map->irq;
-		k_map.dma = (unsigned char) u_map->dma;
-		k_map.port = (unsigned char) u_map->port;
-
-		err = dev->set_config(dev, &k_map);
-		if (err < 0)
-			goto errout_dev;
-
-		modified = 1;
-	}
-
-	if (tb[IFLA_ADDRESS]) {
-		struct sockaddr *sa;
-		int len;
-
-		if (!dev->set_mac_address) {
-			err = -EOPNOTSUPP;
-			goto errout_dev;
-		}
-
-		if (!netif_device_present(dev)) {
-			err = -ENODEV;
-			goto errout_dev;
-		}
-
-		len = sizeof(sa_family_t) + dev->addr_len;
-		sa = kmalloc(len, GFP_KERNEL);
-		if (!sa) {
-			err = -ENOMEM;
-			goto errout_dev;
-		}
-		sa->sa_family = dev->type;
-		memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
-		       dev->addr_len);
-		err = dev->set_mac_address(dev, sa);
-		kfree(sa);
-		if (err)
-			goto errout_dev;
-		send_addr_notify = 1;
-		modified = 1;
-	}
-
-	if (tb[IFLA_MTU]) {
-		err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
-		if (err < 0)
-			goto errout_dev;
-		modified = 1;
-	}
-
-	/*
-	 * Interface selected by interface index but interface
-	 * name provided implies that a name change has been
-	 * requested.
-	 */
-	if (ifm->ifi_index > 0 && ifname[0]) {
-		err = dev_change_name(dev, ifname);
-		if (err < 0)
-			goto errout_dev;
-		modified = 1;
-	}
-
-	if (tb[IFLA_BROADCAST]) {
-		nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len);
-		send_addr_notify = 1;
-	}
-
-
-	if (ifm->ifi_flags || ifm->ifi_change) {
-		unsigned int flags = ifm->ifi_flags;
-
-		/* bugwards compatibility: ifi_change == 0 is treated as ~0 */
-		if (ifm->ifi_change)
-			flags = (flags & ifm->ifi_change) |
-				(dev->flags & ~ifm->ifi_change);
-		dev_change_flags(dev, flags);
-	}
-
-	if (tb[IFLA_TXQLEN])
-		dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
-
-	if (tb[IFLA_WEIGHT])
-		dev->weight = nla_get_u32(tb[IFLA_WEIGHT]);
-
-	if (tb[IFLA_OPERSTATE])
-		set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
-
-	if (tb[IFLA_LINKMODE]) {
-		write_lock_bh(&dev_base_lock);
-		dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
-		write_unlock_bh(&dev_base_lock);
-	}
-
-	err = 0;
-
+	err = do_setlink(dev, ifm, tb, ifname, 0);
 errout_dev:
-	if (err < 0 && modified && net_ratelimit())
-		printk(KERN_WARNING "A link change request failed with "
-		       "some changes comitted already. Interface %s may "
-		       "have been left with an inconsistent configuration, "
-		       "please check.\n", dev->name);
-
-	if (send_addr_notify)
-		call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
-
 	dev_put(dev);
 errout:
 	return err;
 }
 
+static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
+	const struct rtnl_link_ops *ops;
+	struct net_device *dev;
+	struct ifinfomsg *ifm;
+	char ifname[IFNAMSIZ];
+	struct nlattr *tb[IFLA_MAX+1];
+	int err;
+
+	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
+	if (err < 0)
+		return err;
+
+	if (tb[IFLA_IFNAME])
+		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
+
+	ifm = nlmsg_data(nlh);
+	if (ifm->ifi_index > 0)
+		dev = __dev_get_by_index(ifm->ifi_index);
+	else if (tb[IFLA_IFNAME])
+		dev = __dev_get_by_name(ifname);
+	else
+		return -EINVAL;
+
+	if (!dev)
+		return -ENODEV;
+
+	ops = dev->rtnl_link_ops;
+	if (!ops)
+		return -EOPNOTSUPP;
+
+	ops->dellink(dev);
+	return 0;
+}
+
+static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
+	const struct rtnl_link_ops *ops;
+	struct net_device *dev;
+	struct ifinfomsg *ifm;
+	char kind[MODULE_NAME_LEN];
+	char ifname[IFNAMSIZ];
+	struct nlattr *tb[IFLA_MAX+1];
+	struct nlattr *linkinfo[IFLA_INFO_MAX+1];
+	int err;
+
+replay:
+	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
+	if (err < 0)
+		return err;
+
+	if (tb[IFLA_IFNAME])
+		nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
+	else
+		ifname[0] = '\0';
+
+	ifm = nlmsg_data(nlh);
+	if (ifm->ifi_index > 0)
+		dev = __dev_get_by_index(ifm->ifi_index);
+	else if (ifname[0])
+		dev = __dev_get_by_name(ifname);
+	else
+		dev = NULL;
+
+	if (tb[IFLA_LINKINFO]) {
+		err = nla_parse_nested(linkinfo, IFLA_INFO_MAX,
+				       tb[IFLA_LINKINFO], ifla_info_policy);
+		if (err < 0)
+			return err;
+	} else
+		memset(linkinfo, 0, sizeof(linkinfo));
+
+	if (linkinfo[IFLA_INFO_KIND]) {
+		nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
+		ops = rtnl_link_ops_get(kind);
+	} else {
+		kind[0] = '\0';
+		ops = NULL;
+	}
+
+	if (1) {
+		struct nlattr *attr[ops ? ops->maxtype + 1 : 0], **data = NULL;
+
+		if (ops) {
+			if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
+				err = nla_parse_nested(attr, ops->maxtype,
+						       linkinfo[IFLA_INFO_DATA],
+						       ops->policy);
+				if (err < 0)
+					return err;
+				data = attr;
+			}
+			if (ops->validate) {
+				err = ops->validate(tb, data);
+				if (err < 0)
+					return err;
+			}
+		}
+
+		if (dev) {
+			int modified = 0;
+
+			if (nlh->nlmsg_flags & NLM_F_EXCL)
+				return -EEXIST;
+			if (nlh->nlmsg_flags & NLM_F_REPLACE)
+				return -EOPNOTSUPP;
+
+			if (linkinfo[IFLA_INFO_DATA]) {
+				if (!ops || ops != dev->rtnl_link_ops ||
+				    !ops->changelink)
+					return -EOPNOTSUPP;
+
+				err = ops->changelink(dev, tb, data);
+				if (err < 0)
+					return err;
+				modified = 1;
+			}
+
+			return do_setlink(dev, ifm, tb, ifname, modified);
+		}
+
+		if (!(nlh->nlmsg_flags & NLM_F_CREATE))
+			return -ENODEV;
+
+		if (ifm->ifi_index || ifm->ifi_flags || ifm->ifi_change)
+			return -EOPNOTSUPP;
+		if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO])
+			return -EOPNOTSUPP;
+
+		if (!ops) {
+#ifdef CONFIG_KMOD
+			if (kind[0]) {
+				__rtnl_unlock();
+				request_module("rtnl-link-%s", kind);
+				rtnl_lock();
+				ops = rtnl_link_ops_get(kind);
+				if (ops)
+					goto replay;
+			}
+#endif
+			return -EOPNOTSUPP;
+		}
+
+		if (!ifname[0])
+			snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
+		dev = alloc_netdev(ops->priv_size, ifname, ops->setup);
+		if (!dev)
+			return -ENOMEM;
+
+		if (strchr(dev->name, '%')) {
+			err = dev_alloc_name(dev, dev->name);
+			if (err < 0)
+				goto err_free;
+		}
+		dev->rtnl_link_ops = ops;
+
+		if (tb[IFLA_MTU])
+			dev->mtu = nla_get_u32(tb[IFLA_MTU]);
+		if (tb[IFLA_ADDRESS])
+			memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]),
+			       nla_len(tb[IFLA_ADDRESS]));
+		if (tb[IFLA_BROADCAST])
+			memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]),
+			       nla_len(tb[IFLA_BROADCAST]));
+		if (tb[IFLA_TXQLEN])
+			dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
+		if (tb[IFLA_WEIGHT])
+			dev->weight = nla_get_u32(tb[IFLA_WEIGHT]);
+		if (tb[IFLA_OPERSTATE])
+			set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
+		if (tb[IFLA_LINKMODE])
+			dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
+
+		if (ops->newlink)
+			err = ops->newlink(dev, tb, data);
+		else
+			err = register_netdevice(dev);
+err_free:
+		if (err < 0)
+			free_netdev(dev);
+		return err;
+	}
+}
+
 static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
 	struct ifinfomsg *ifm;
@@ -747,7 +1110,7 @@
 	} else
 		return -EINVAL;
 
-	nskb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL);
+	nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
 	if (nskb == NULL) {
 		err = -ENOBUFS;
 		goto errout;
@@ -797,7 +1160,7 @@
 	struct sk_buff *skb;
 	int err = -ENOBUFS;
 
-	skb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL);
+	skb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
 	if (skb == NULL)
 		goto errout;
 
@@ -952,6 +1315,8 @@
 
 	rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, rtnl_dump_ifinfo);
 	rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL);
+	rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL);
+	rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL);
 
 	rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all);
 	rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all);
@@ -960,6 +1325,7 @@
 EXPORT_SYMBOL(__rta_fill);
 EXPORT_SYMBOL(rtattr_strlcpy);
 EXPORT_SYMBOL(rtattr_parse);
+EXPORT_SYMBOL(__rtattr_parse_nested_compat);
 EXPORT_SYMBOL(rtnetlink_put_metrics);
 EXPORT_SYMBOL(rtnl_lock);
 EXPORT_SYMBOL(rtnl_trylock);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 3943c3a..0583e84 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -415,9 +415,11 @@
 	C(csum);
 	C(local_df);
 	n->cloned = 1;
+	n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
 	n->nohdr = 0;
 	C(pkt_type);
 	C(ip_summed);
+	skb_copy_queue_mapping(n, skb);
 	C(priority);
 #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
 	C(ipvs_property);
@@ -426,6 +428,10 @@
 	n->destructor = NULL;
 	C(mark);
 	__nf_copy(n, skb);
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+	C(nf_trace);
+#endif
 #ifdef CONFIG_NET_SCHED
 	C(tc_index);
 #ifdef CONFIG_NET_CLS_ACT
@@ -459,6 +465,7 @@
 #endif
 	new->sk		= NULL;
 	new->dev	= old->dev;
+	skb_copy_queue_mapping(new, old);
 	new->priority	= old->priority;
 	new->protocol	= old->protocol;
 	new->dst	= dst_clone(old->dst);
@@ -482,6 +489,10 @@
 	new->destructor = NULL;
 	new->mark	= old->mark;
 	__nf_copy(new, old);
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+	new->nf_trace	= old->nf_trace;
+#endif
 #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
 	new->ipvs_property = old->ipvs_property;
 #endif
@@ -676,6 +687,7 @@
 	skb->network_header   += off;
 	skb->mac_header	      += off;
 	skb->cloned   = 0;
+	skb->hdr_len  = 0;
 	skb->nohdr    = 0;
 	atomic_set(&skb_shinfo(skb)->dataref, 1);
 	return 0;
@@ -1930,6 +1942,7 @@
 		tail = nskb;
 
 		nskb->dev = skb->dev;
+		skb_copy_queue_mapping(nskb, skb);
 		nskb->priority = skb->priority;
 		nskb->protocol = skb->protocol;
 		nskb->dst = dst_clone(skb->dst);
diff --git a/net/core/sock.c b/net/core/sock.c
index c14ce01..091032a 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -210,7 +210,8 @@
 		return -EDOM;
 
 	if (tv.tv_sec < 0) {
-		static int warned = 0;
+		static int warned __read_mostly;
+
 		*timeo_p = 0;
 		if (warned < 10 && net_ratelimit())
 			warned++;
@@ -1851,46 +1852,15 @@
 EXPORT_SYMBOL(proto_unregister);
 
 #ifdef CONFIG_PROC_FS
-static inline struct proto *__proto_head(void)
-{
-	return list_entry(proto_list.next, struct proto, node);
-}
-
-static inline struct proto *proto_head(void)
-{
-	return list_empty(&proto_list) ? NULL : __proto_head();
-}
-
-static inline struct proto *proto_next(struct proto *proto)
-{
-	return proto->node.next == &proto_list ? NULL :
-		list_entry(proto->node.next, struct proto, node);
-}
-
-static inline struct proto *proto_get_idx(loff_t pos)
-{
-	struct proto *proto;
-	loff_t i = 0;
-
-	list_for_each_entry(proto, &proto_list, node)
-		if (i++ == pos)
-			goto out;
-
-	proto = NULL;
-out:
-	return proto;
-}
-
 static void *proto_seq_start(struct seq_file *seq, loff_t *pos)
 {
 	read_lock(&proto_list_lock);
-	return *pos ? proto_get_idx(*pos - 1) : SEQ_START_TOKEN;
+	return seq_list_start_head(&proto_list, *pos);
 }
 
 static void *proto_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	++*pos;
-	return v == SEQ_START_TOKEN ? proto_head() : proto_next(v);
+	return seq_list_next(v, &proto_list, pos);
 }
 
 static void proto_seq_stop(struct seq_file *seq, void *v)
@@ -1938,7 +1908,7 @@
 
 static int proto_seq_show(struct seq_file *seq, void *v)
 {
-	if (v == SEQ_START_TOKEN)
+	if (v == &proto_list)
 		seq_printf(seq, "%-9s %-4s %-8s %-6s %-5s %-7s %-4s %-10s %s",
 			   "protocol",
 			   "size",
@@ -1950,7 +1920,7 @@
 			   "module",
 			   "cl co di ac io in de sh ss gs se re sp bi br ha uh gp em\n");
 	else
-		proto_seq_printf(seq, v);
+		proto_seq_printf(seq, list_entry(v, struct proto, node));
 	return 0;
 }
 
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index ec7fa4d..e91c2b9 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -1,8 +1,8 @@
 /*
  *  net/dccp/ccids/ccid3.c
  *
- *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
- *  Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz>
+ *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
+ *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
  *
  *  An implementation of the DCCP protocol
  *
@@ -49,7 +49,6 @@
 
 static struct dccp_tx_hist *ccid3_tx_hist;
 static struct dccp_rx_hist *ccid3_rx_hist;
-static struct dccp_li_hist *ccid3_li_hist;
 
 /*
  *	Transmitter Half-Connection Routines
@@ -194,25 +193,20 @@
  *	The algorithm is not applicable if RTT < 4 microseconds.
  */
 static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hctx,
-						struct timeval *now)
+						ktime_t now)
 {
-	suseconds_t delta;
 	u32 quarter_rtts;
 
 	if (unlikely(hctx->ccid3hctx_rtt < 4))	/* avoid divide-by-zero */
 		return;
 
-	delta = timeval_delta(now, &hctx->ccid3hctx_t_last_win_count);
-	DCCP_BUG_ON(delta < 0);
-
-	quarter_rtts = (u32)delta / (hctx->ccid3hctx_rtt / 4);
+	quarter_rtts = ktime_us_delta(now, hctx->ccid3hctx_t_last_win_count);
+	quarter_rtts /= hctx->ccid3hctx_rtt / 4;
 
 	if (quarter_rtts > 0) {
-		hctx->ccid3hctx_t_last_win_count = *now;
+		hctx->ccid3hctx_t_last_win_count = now;
 		hctx->ccid3hctx_last_win_count	+= min_t(u32, quarter_rtts, 5);
 		hctx->ccid3hctx_last_win_count	&= 0xF;		/* mod 16 */
-
-		ccid3_pr_debug("now at %#X\n", hctx->ccid3hctx_last_win_count);
 	}
 }
 
@@ -312,8 +306,8 @@
 {
 	struct dccp_sock *dp = dccp_sk(sk);
 	struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
-	struct timeval now;
-	suseconds_t delay;
+	ktime_t now = ktime_get_real();
+	s64 delay;
 
 	BUG_ON(hctx == NULL);
 
@@ -325,8 +319,6 @@
 	if (unlikely(skb->len == 0))
 		return -EBADMSG;
 
-	dccp_timestamp(sk, &now);
-
 	switch (hctx->ccid3hctx_state) {
 	case TFRC_SSTATE_NO_SENT:
 		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
@@ -349,7 +341,7 @@
 			ccid3_pr_debug("SYN RTT = %uus\n", dp->dccps_syn_rtt);
 			hctx->ccid3hctx_rtt  = dp->dccps_syn_rtt;
 			hctx->ccid3hctx_x    = rfc3390_initial_rate(sk);
-			hctx->ccid3hctx_t_ld = now;
+			hctx->ccid3hctx_t_ld = ktime_to_timeval(now);
 		} else {
 			/* Sender does not have RTT sample: X = MSS/second */
 			hctx->ccid3hctx_x = dp->dccps_mss_cache;
@@ -361,7 +353,7 @@
 		break;
 	case TFRC_SSTATE_NO_FBACK:
 	case TFRC_SSTATE_FBACK:
-		delay = timeval_delta(&hctx->ccid3hctx_t_nom, &now);
+		delay = ktime_us_delta(hctx->ccid3hctx_t_nom, now);
 		ccid3_pr_debug("delay=%ld\n", (long)delay);
 		/*
 		 *	Scheduling of packet transmissions [RFC 3448, 4.6]
@@ -371,10 +363,10 @@
 		 * else
 		 *       // send the packet in (t_nom - t_now) milliseconds.
 		 */
-		if (delay - (suseconds_t)hctx->ccid3hctx_delta >= 0)
-			return delay / 1000L;
+		if (delay - (s64)hctx->ccid3hctx_delta >= 1000)
+			return (u32)delay / 1000L;
 
-		ccid3_hc_tx_update_win_count(hctx, &now);
+		ccid3_hc_tx_update_win_count(hctx, now);
 		break;
 	case TFRC_SSTATE_TERM:
 		DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
@@ -387,8 +379,8 @@
 	hctx->ccid3hctx_idle = 0;
 
 	/* set the nominal send time for the next following packet */
-	timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);
-
+	hctx->ccid3hctx_t_nom = ktime_add_us(hctx->ccid3hctx_t_nom,
+					     hctx->ccid3hctx_t_ipi);
 	return 0;
 }
 
@@ -819,154 +811,6 @@
 	return 0;
 }
 
-/* calculate first loss interval
- *
- * returns estimated loss interval in usecs */
-
-static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
-{
-	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
-	struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
-	u32 x_recv, p;
-	suseconds_t rtt, delta;
-	struct timeval tstamp = { 0, };
-	int interval = 0;
-	int win_count = 0;
-	int step = 0;
-	u64 fval;
-
-	list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
-				 dccphrx_node) {
-		if (dccp_rx_hist_entry_data_packet(entry)) {
-			tail = entry;
-
-			switch (step) {
-			case 0:
-				tstamp	  = entry->dccphrx_tstamp;
-				win_count = entry->dccphrx_ccval;
-				step = 1;
-				break;
-			case 1:
-				interval = win_count - entry->dccphrx_ccval;
-				if (interval < 0)
-					interval += TFRC_WIN_COUNT_LIMIT;
-				if (interval > 4)
-					goto found;
-				break;
-			}
-		}
-	}
-
-	if (unlikely(step == 0)) {
-		DCCP_WARN("%s(%p), packet history has no data packets!\n",
-			  dccp_role(sk), sk);
-		return ~0;
-	}
-
-	if (unlikely(interval == 0)) {
-		DCCP_WARN("%s(%p), Could not find a win_count interval > 0."
-			  "Defaulting to 1\n", dccp_role(sk), sk);
-		interval = 1;
-	}
-found:
-	if (!tail) {
-		DCCP_CRIT("tail is null\n");
-		return ~0;
-	}
-
-	delta = timeval_delta(&tstamp, &tail->dccphrx_tstamp);
-	DCCP_BUG_ON(delta < 0);
-
-	rtt = delta * 4 / interval;
-	ccid3_pr_debug("%s(%p), approximated RTT to %dus\n",
-		       dccp_role(sk), sk, (int)rtt);
-
-	/*
-	 * Determine the length of the first loss interval via inverse lookup.
-	 * Assume that X_recv can be computed by the throughput equation
-	 *		    s
-	 *	X_recv = --------
-	 *		 R * fval
-	 * Find some p such that f(p) = fval; return 1/p [RFC 3448, 6.3.1].
-	 */
-	if (rtt == 0) {			/* would result in divide-by-zero */
-		DCCP_WARN("RTT==0\n");
-		return ~0;
-	}
-
-	dccp_timestamp(sk, &tstamp);
-	delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
-	DCCP_BUG_ON(delta <= 0);
-
-	x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
-	if (x_recv == 0) {		/* would also trigger divide-by-zero */
-		DCCP_WARN("X_recv==0\n");
-		if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
-			DCCP_BUG("stored value of X_recv is zero");
-			return ~0;
-		}
-	}
-
-	fval = scaled_div(hcrx->ccid3hcrx_s, rtt);
-	fval = scaled_div32(fval, x_recv);
-	p = tfrc_calc_x_reverse_lookup(fval);
-
-	ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
-		       "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
-
-	if (p == 0)
-		return ~0;
-	else
-		return 1000000 / p;
-}
-
-static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
-{
-	struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
-	struct dccp_li_hist_entry *head;
-	u64 seq_temp;
-
-	if (list_empty(&hcrx->ccid3hcrx_li_hist)) {
-		if (!dccp_li_hist_interval_new(ccid3_li_hist,
-		   &hcrx->ccid3hcrx_li_hist, seq_loss, win_loss))
-			return;
-
-		head = list_entry(hcrx->ccid3hcrx_li_hist.next,
-		   struct dccp_li_hist_entry, dccplih_node);
-		head->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
-	} else {
-		struct dccp_li_hist_entry *entry;
-		struct list_head *tail;
-
-		head = list_entry(hcrx->ccid3hcrx_li_hist.next,
-		   struct dccp_li_hist_entry, dccplih_node);
-		/* FIXME win count check removed as was wrong */
-		/* should make this check with receive history */
-		/* and compare there as per section 10.2 of RFC4342 */
-
-		/* new loss event detected */
-		/* calculate last interval length */
-		seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss);
-		entry = dccp_li_hist_entry_new(ccid3_li_hist, GFP_ATOMIC);
-
-		if (entry == NULL) {
-			DCCP_BUG("out of memory - can not allocate entry");
-			return;
-		}
-
-		list_add(&entry->dccplih_node, &hcrx->ccid3hcrx_li_hist);
-
-		tail = hcrx->ccid3hcrx_li_hist.prev;
-		list_del(tail);
-		kmem_cache_free(ccid3_li_hist->dccplih_slab, tail);
-
-		/* Create the newest interval */
-		entry->dccplih_seqno = seq_loss;
-		entry->dccplih_interval = seq_temp;
-		entry->dccplih_win_count = win_loss;
-	}
-}
-
 static int ccid3_hc_rx_detect_loss(struct sock *sk,
 				    struct dccp_rx_hist_entry *packet)
 {
@@ -992,8 +836,15 @@
 	while (dccp_delta_seqno(hcrx->ccid3hcrx_seqno_nonloss, seqno)
 	   > TFRC_RECV_NUM_LATE_LOSS) {
 		loss = 1;
-		ccid3_hc_rx_update_li(sk, hcrx->ccid3hcrx_seqno_nonloss,
-		   hcrx->ccid3hcrx_ccval_nonloss);
+		dccp_li_update_li(sk,
+				  &hcrx->ccid3hcrx_li_hist,
+				  &hcrx->ccid3hcrx_hist,
+				  &hcrx->ccid3hcrx_tstamp_last_feedback,
+				  hcrx->ccid3hcrx_s,
+				  hcrx->ccid3hcrx_bytes_recv,
+				  hcrx->ccid3hcrx_x_recv,
+				  hcrx->ccid3hcrx_seqno_nonloss,
+				  hcrx->ccid3hcrx_ccval_nonloss);
 		tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss;
 		dccp_inc_seqno(&tmp_seqno);
 		hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno;
@@ -1152,7 +1003,7 @@
 	dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
 
 	/* Empty loss interval history */
-	dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist);
+	dccp_li_hist_purge(&hcrx->ccid3hcrx_li_hist);
 }
 
 static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
@@ -1236,19 +1087,12 @@
 	if (ccid3_tx_hist == NULL)
 		goto out_free_rx;
 
-	ccid3_li_hist = dccp_li_hist_new("ccid3");
-	if (ccid3_li_hist == NULL)
-		goto out_free_tx;
-
 	rc = ccid_register(&ccid3);
 	if (rc != 0)
-		goto out_free_loss_interval_history;
+		goto out_free_tx;
 out:
 	return rc;
 
-out_free_loss_interval_history:
-	dccp_li_hist_delete(ccid3_li_hist);
-	ccid3_li_hist = NULL;
 out_free_tx:
 	dccp_tx_hist_delete(ccid3_tx_hist);
 	ccid3_tx_hist = NULL;
@@ -1271,10 +1115,6 @@
 		dccp_rx_hist_delete(ccid3_rx_hist);
 		ccid3_rx_hist = NULL;
 	}
-	if (ccid3_li_hist != NULL) {
-		dccp_li_hist_delete(ccid3_li_hist);
-		ccid3_li_hist = NULL;
-	}
 }
 module_exit(ccid3_module_exit);
 
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index 8d31b38..51d4b80 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -36,6 +36,7 @@
 #ifndef _DCCP_CCID3_H_
 #define _DCCP_CCID3_H_
 
+#include <linux/ktime.h>
 #include <linux/list.h>
 #include <linux/time.h>
 #include <linux/types.h>
@@ -108,10 +109,10 @@
 	enum ccid3_hc_tx_states		ccid3hctx_state:8;
 	u8				ccid3hctx_last_win_count;
 	u8				ccid3hctx_idle;
-	struct timeval			ccid3hctx_t_last_win_count;
+	ktime_t				ccid3hctx_t_last_win_count;
 	struct timer_list		ccid3hctx_no_feedback_timer;
 	struct timeval			ccid3hctx_t_ld;
-	struct timeval			ccid3hctx_t_nom;
+	ktime_t				ccid3hctx_t_nom;
 	u32				ccid3hctx_delta;
 	struct list_head		ccid3hctx_hist;
 	struct ccid3_options_received	ccid3hctx_options_received;
diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c
index 372d7e7..515225f 100644
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -1,8 +1,8 @@
 /*
  *  net/dccp/ccids/lib/loss_interval.c
  *
- *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
- *  Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz>
+ *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
+ *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -15,58 +15,38 @@
 #include <net/sock.h>
 #include "../../dccp.h"
 #include "loss_interval.h"
+#include "packet_history.h"
+#include "tfrc.h"
 
-struct dccp_li_hist *dccp_li_hist_new(const char *name)
+#define DCCP_LI_HIST_IVAL_F_LENGTH  8
+
+struct dccp_li_hist_entry {
+	struct list_head dccplih_node;
+	u64		 dccplih_seqno:48,
+			 dccplih_win_count:4;
+	u32		 dccplih_interval;
+};
+
+static struct kmem_cache *dccp_li_cachep __read_mostly;
+
+static inline struct dccp_li_hist_entry *dccp_li_hist_entry_new(const gfp_t prio)
 {
-	struct dccp_li_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
-	static const char dccp_li_hist_mask[] = "li_hist_%s";
-	char *slab_name;
-
-	if (hist == NULL)
-		goto out;
-
-	slab_name = kmalloc(strlen(name) + sizeof(dccp_li_hist_mask) - 1,
-			    GFP_ATOMIC);
-	if (slab_name == NULL)
-		goto out_free_hist;
-
-	sprintf(slab_name, dccp_li_hist_mask, name);
-	hist->dccplih_slab = kmem_cache_create(slab_name,
-					     sizeof(struct dccp_li_hist_entry),
-					       0, SLAB_HWCACHE_ALIGN,
-					       NULL, NULL);
-	if (hist->dccplih_slab == NULL)
-		goto out_free_slab_name;
-out:
-	return hist;
-out_free_slab_name:
-	kfree(slab_name);
-out_free_hist:
-	kfree(hist);
-	hist = NULL;
-	goto out;
+	return kmem_cache_alloc(dccp_li_cachep, prio);
 }
 
-EXPORT_SYMBOL_GPL(dccp_li_hist_new);
-
-void dccp_li_hist_delete(struct dccp_li_hist *hist)
+static inline void dccp_li_hist_entry_delete(struct dccp_li_hist_entry *entry)
 {
-	const char* name = kmem_cache_name(hist->dccplih_slab);
-
-	kmem_cache_destroy(hist->dccplih_slab);
-	kfree(name);
-	kfree(hist);
+	if (entry != NULL)
+		kmem_cache_free(dccp_li_cachep, entry);
 }
 
-EXPORT_SYMBOL_GPL(dccp_li_hist_delete);
-
-void dccp_li_hist_purge(struct dccp_li_hist *hist, struct list_head *list)
+void dccp_li_hist_purge(struct list_head *list)
 {
 	struct dccp_li_hist_entry *entry, *next;
 
 	list_for_each_entry_safe(entry, next, list, dccplih_node) {
 		list_del_init(&entry->dccplih_node);
-		kmem_cache_free(hist->dccplih_slab, entry);
+		kmem_cache_free(dccp_li_cachep, entry);
 	}
 }
 
@@ -118,16 +98,16 @@
 
 EXPORT_SYMBOL_GPL(dccp_li_hist_calc_i_mean);
 
-int dccp_li_hist_interval_new(struct dccp_li_hist *hist,
-   struct list_head *list, const u64 seq_loss, const u8 win_loss)
+static int dccp_li_hist_interval_new(struct list_head *list,
+				     const u64 seq_loss, const u8 win_loss)
 {
 	struct dccp_li_hist_entry *entry;
 	int i;
 
 	for (i = 0; i < DCCP_LI_HIST_IVAL_F_LENGTH; i++) {
-		entry = dccp_li_hist_entry_new(hist, GFP_ATOMIC);
+		entry = dccp_li_hist_entry_new(GFP_ATOMIC);
 		if (entry == NULL) {
-			dccp_li_hist_purge(hist, list);
+			dccp_li_hist_purge(list);
 			DCCP_BUG("loss interval list entry is NULL");
 			return 0;
 		}
@@ -140,4 +120,176 @@
 	return 1;
 }
 
-EXPORT_SYMBOL_GPL(dccp_li_hist_interval_new);
+/* calculate first loss interval
+ *
+ * returns estimated loss interval in usecs */
+static u32 dccp_li_calc_first_li(struct sock *sk,
+				 struct list_head *hist_list,
+				 struct timeval *last_feedback,
+				 u16 s, u32 bytes_recv,
+				 u32 previous_x_recv)
+{
+	struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
+	u32 x_recv, p;
+	suseconds_t rtt, delta;
+	struct timeval tstamp = { 0, 0 };
+	int interval = 0;
+	int win_count = 0;
+	int step = 0;
+	u64 fval;
+
+	list_for_each_entry_safe(entry, next, hist_list, dccphrx_node) {
+		if (dccp_rx_hist_entry_data_packet(entry)) {
+			tail = entry;
+
+			switch (step) {
+			case 0:
+				tstamp	  = entry->dccphrx_tstamp;
+				win_count = entry->dccphrx_ccval;
+				step = 1;
+				break;
+			case 1:
+				interval = win_count - entry->dccphrx_ccval;
+				if (interval < 0)
+					interval += TFRC_WIN_COUNT_LIMIT;
+				if (interval > 4)
+					goto found;
+				break;
+			}
+		}
+	}
+
+	if (unlikely(step == 0)) {
+		DCCP_WARN("%s(%p), packet history has no data packets!\n",
+			  dccp_role(sk), sk);
+		return ~0;
+	}
+
+	if (unlikely(interval == 0)) {
+		DCCP_WARN("%s(%p), Could not find a win_count interval > 0."
+			  "Defaulting to 1\n", dccp_role(sk), sk);
+		interval = 1;
+	}
+found:
+	if (!tail) {
+		DCCP_CRIT("tail is null\n");
+		return ~0;
+	}
+
+	delta = timeval_delta(&tstamp, &tail->dccphrx_tstamp);
+	DCCP_BUG_ON(delta < 0);
+
+	rtt = delta * 4 / interval;
+	dccp_pr_debug("%s(%p), approximated RTT to %dus\n",
+		      dccp_role(sk), sk, (int)rtt);
+
+	/*
+	 * Determine the length of the first loss interval via inverse lookup.
+	 * Assume that X_recv can be computed by the throughput equation
+	 *		    s
+	 *	X_recv = --------
+	 *		 R * fval
+	 * Find some p such that f(p) = fval; return 1/p [RFC 3448, 6.3.1].
+	 */
+	if (rtt == 0) {			/* would result in divide-by-zero */
+		DCCP_WARN("RTT==0\n");
+		return ~0;
+	}
+
+	dccp_timestamp(sk, &tstamp);
+	delta = timeval_delta(&tstamp, last_feedback);
+	DCCP_BUG_ON(delta <= 0);
+
+	x_recv = scaled_div32(bytes_recv, delta);
+	if (x_recv == 0) {		/* would also trigger divide-by-zero */
+		DCCP_WARN("X_recv==0\n");
+		if (previous_x_recv == 0) {
+			DCCP_BUG("stored value of X_recv is zero");
+			return ~0;
+		}
+		x_recv = previous_x_recv;
+	}
+
+	fval = scaled_div(s, rtt);
+	fval = scaled_div32(fval, x_recv);
+	p = tfrc_calc_x_reverse_lookup(fval);
+
+	dccp_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
+		      "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
+
+	if (p == 0)
+		return ~0;
+	else
+		return 1000000 / p;
+}
+
+void dccp_li_update_li(struct sock *sk,
+		       struct list_head *li_hist_list,
+		       struct list_head *hist_list,
+		       struct timeval *last_feedback, u16 s, u32 bytes_recv,
+                       u32 previous_x_recv, u64 seq_loss, u8 win_loss)
+{
+	struct dccp_li_hist_entry *head;
+	u64 seq_temp;
+
+	if (list_empty(li_hist_list)) {
+		if (!dccp_li_hist_interval_new(li_hist_list, seq_loss,
+					       win_loss))
+			return;
+
+		head = list_entry(li_hist_list->next, struct dccp_li_hist_entry,
+				  dccplih_node);
+		head->dccplih_interval = dccp_li_calc_first_li(sk, hist_list,
+							       last_feedback,
+							       s, bytes_recv,
+							       previous_x_recv);
+	} else {
+		struct dccp_li_hist_entry *entry;
+		struct list_head *tail;
+
+		head = list_entry(li_hist_list->next, struct dccp_li_hist_entry,
+				  dccplih_node);
+		/* FIXME win count check removed as was wrong */
+		/* should make this check with receive history */
+		/* and compare there as per section 10.2 of RFC4342 */
+
+		/* new loss event detected */
+		/* calculate last interval length */
+		seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss);
+		entry = dccp_li_hist_entry_new(GFP_ATOMIC);
+
+		if (entry == NULL) {
+			DCCP_BUG("out of memory - can not allocate entry");
+			return;
+		}
+
+		list_add(&entry->dccplih_node, li_hist_list);
+
+		tail = li_hist_list->prev;
+		list_del(tail);
+		kmem_cache_free(dccp_li_cachep, tail);
+
+		/* Create the newest interval */
+		entry->dccplih_seqno = seq_loss;
+		entry->dccplih_interval = seq_temp;
+		entry->dccplih_win_count = win_loss;
+	}
+}
+
+EXPORT_SYMBOL_GPL(dccp_li_update_li);
+
+static __init int dccp_li_init(void)
+{
+	dccp_li_cachep = kmem_cache_create("dccp_li_hist",
+					   sizeof(struct dccp_li_hist_entry),
+					   0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+	return dccp_li_cachep == NULL ? -ENOBUFS : 0;
+}
+
+static __exit void dccp_li_exit(void)
+{
+	kmem_cache_destroy(dccp_li_cachep);
+}
+
+module_init(dccp_li_init);
+module_exit(dccp_li_exit);
diff --git a/net/dccp/ccids/lib/loss_interval.h b/net/dccp/ccids/lib/loss_interval.h
index eb25701..906c806 100644
--- a/net/dccp/ccids/lib/loss_interval.h
+++ b/net/dccp/ccids/lib/loss_interval.h
@@ -3,8 +3,8 @@
 /*
  *  net/dccp/ccids/lib/loss_interval.h
  *
- *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
- *  Copyright (c) 2005 Ian McDonald <ian.mcdonald@jandi.co.nz>
+ *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
+ *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  *
  *  This program is free software; you can redistribute it and/or modify it
@@ -14,44 +14,16 @@
  */
 
 #include <linux/list.h>
-#include <linux/slab.h>
 #include <linux/time.h>
 
-#define DCCP_LI_HIST_IVAL_F_LENGTH  8
-
-struct dccp_li_hist {
-	struct kmem_cache *dccplih_slab;
-};
-
-extern struct dccp_li_hist *dccp_li_hist_new(const char *name);
-extern void dccp_li_hist_delete(struct dccp_li_hist *hist);
-
-struct dccp_li_hist_entry {
-	struct list_head dccplih_node;
-	u64		 dccplih_seqno:48,
-			 dccplih_win_count:4;
-	u32		 dccplih_interval;
-};
-
-static inline struct dccp_li_hist_entry *
-		dccp_li_hist_entry_new(struct dccp_li_hist *hist,
-				       const gfp_t prio)
-{
-	return kmem_cache_alloc(hist->dccplih_slab, prio);
-}
-
-static inline void dccp_li_hist_entry_delete(struct dccp_li_hist *hist,
-					     struct dccp_li_hist_entry *entry)
-{
-	if (entry != NULL)
-		kmem_cache_free(hist->dccplih_slab, entry);
-}
-
-extern void dccp_li_hist_purge(struct dccp_li_hist *hist,
-			       struct list_head *list);
+extern void dccp_li_hist_purge(struct list_head *list);
 
 extern u32 dccp_li_hist_calc_i_mean(struct list_head *list);
 
-extern int dccp_li_hist_interval_new(struct dccp_li_hist *hist,
-   struct list_head *list, const u64 seq_loss, const u8 win_loss);
+extern void dccp_li_update_li(struct sock *sk,
+			      struct list_head *li_hist_list,
+			      struct list_head *hist_list,
+			      struct timeval *last_feedback, u16 s,
+			      u32 bytes_recv, u32 previous_x_recv,
+			      u64 seq_loss, u8 win_loss);
 #endif /* _DCCP_LI_HIST_ */
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index d8ad27b..e2d74cd 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -184,7 +184,7 @@
 /*
  * 	Checksumming routines
  */
-static inline int dccp_csum_coverage(const struct sk_buff *skb)
+static inline unsigned int dccp_csum_coverage(const struct sk_buff *skb)
 {
 	const struct dccp_hdr* dh = dccp_hdr(skb);
 
@@ -195,7 +195,7 @@
 
 static inline void dccp_csum_outgoing(struct sk_buff *skb)
 {
-	int cov = dccp_csum_coverage(skb);
+	unsigned int cov = dccp_csum_coverage(skb);
 
 	if (cov >= skb->len)
 		dccp_hdr(skb)->dccph_cscov = 0;
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 31737cd..b158c66 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -253,17 +253,6 @@
 
 	if (dst == NULL) {
 		opt = np->opt;
-		if (opt == NULL &&
-		    np->rxopt.bits.osrcrt == 2 &&
-		    ireq6->pktopts) {
-			struct sk_buff *pktopts = ireq6->pktopts;
-			struct inet6_skb_parm *rxopt = IP6CB(pktopts);
-
-			if (rxopt->srcrt)
-				opt = ipv6_invert_rthdr(sk,
-			  (struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
-						 rxopt->srcrt));
-		}
 
 		if (opt != NULL && opt->srcrt != NULL) {
 			const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt;
@@ -570,15 +559,6 @@
 	if (sk_acceptq_is_full(sk))
 		goto out_overflow;
 
-	if (np->rxopt.bits.osrcrt == 2 && opt == NULL && ireq6->pktopts) {
-		const struct inet6_skb_parm *rxopt = IP6CB(ireq6->pktopts);
-
-		if (rxopt->srcrt)
-			opt = ipv6_invert_rthdr(sk,
-		   (struct ipv6_rt_hdr *)(skb_network_header(ireq6->pktopts) +
-					  rxopt->srcrt));
-	}
-
 	if (dst == NULL) {
 		struct in6_addr *final_p = NULL, final;
 		struct flowi fl;
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index bfa910b..ed76d4a 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -2304,7 +2304,7 @@
 	return 0;
 }
 
-static struct seq_operations dn_socket_seq_ops = {
+static const struct seq_operations dn_socket_seq_ops = {
 	.start	= dn_socket_seq_start,
 	.next	= dn_socket_seq_next,
 	.stop	= dn_socket_seq_stop,
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index ab41c18..fa6604f 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -461,7 +461,6 @@
 		if (ifa->ifa_local != dn_eth2dn(dev->dev_addr)) {
 			dn_dn2eth(mac_addr, ifa->ifa_local);
 			dev_mc_add(dev, mac_addr, ETH_ALEN, 0);
-			dev_mc_upload(dev);
 		}
 	}
 
@@ -1064,8 +1063,6 @@
 	else
 		dev_mc_add(dev, dn_rt_all_rt_mcast, ETH_ALEN, 0);
 
-	dev_mc_upload(dev);
-
 	dn_db->use_long = 1;
 
 	return 0;
@@ -1419,7 +1416,7 @@
 	return 0;
 }
 
-static struct seq_operations dn_dev_seq_ops = {
+static const struct seq_operations dn_dev_seq_ops = {
 	.start	= dn_dev_seq_start,
 	.next	= dn_dev_seq_next,
 	.stop	= dn_dev_seq_stop,
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index 4bf066c..174d8a7 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -569,7 +569,7 @@
 			       NEIGH_SEQ_NEIGH_ONLY);
 }
 
-static struct seq_operations dn_neigh_seq_ops = {
+static const struct seq_operations dn_neigh_seq_ops = {
 	.start = dn_neigh_seq_start,
 	.next  = neigh_seq_next,
 	.stop  = neigh_seq_stop,
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index a8bf106..82622fb 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1726,7 +1726,7 @@
 	return 0;
 }
 
-static struct seq_operations dn_rt_cache_seq_ops = {
+static const struct seq_operations dn_rt_cache_seq_ops = {
 	.start	= dn_rt_cache_seq_start,
 	.next	= dn_rt_cache_seq_next,
 	.stop	= dn_rt_cache_seq_stop,
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 0ac2524..12c7657 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -266,8 +266,11 @@
 static int eth_mac_addr(struct net_device *dev, void *p)
 {
 	struct sockaddr *addr = p;
+
 	if (netif_running(dev))
 		return -EBUSY;
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 	return 0;
 }
@@ -316,9 +319,10 @@
 EXPORT_SYMBOL(ether_setup);
 
 /**
- * alloc_etherdev - Allocates and sets up an Ethernet device
+ * alloc_etherdev_mq - Allocates and sets up an Ethernet device
  * @sizeof_priv: Size of additional driver-private structure to be allocated
  *	for this Ethernet device
+ * @queue_count: The number of queues this device has.
  *
  * Fill in the fields of the device structure with Ethernet-generic
  * values. Basically does everything except registering the device.
@@ -328,8 +332,8 @@
  * this private data area.
  */
 
-struct net_device *alloc_etherdev(int sizeof_priv)
+struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count)
 {
-	return alloc_netdev(sizeof_priv, "eth%d", ether_setup);
+	return alloc_netdev_mq(sizeof_priv, "eth%d", ether_setup, queue_count);
 }
-EXPORT_SYMBOL(alloc_etherdev);
+EXPORT_SYMBOL(alloc_etherdev_mq);
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 010fbb2..fb79097 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -116,48 +116,6 @@
 	  equal "cost" and chooses one of them in a non-deterministic fashion
 	  if a matching packet arrives.
 
-config IP_ROUTE_MULTIPATH_CACHED
-	bool "IP: equal cost multipath with caching support (EXPERIMENTAL)"
-	depends on IP_ROUTE_MULTIPATH
-	help
-	  Normally, equal cost multipath routing is not supported by the
-	  routing cache. If you say Y here, alternative routes are cached
-	  and on cache lookup a route is chosen in a configurable fashion.
-
-	  If unsure, say N.
-
-config IP_ROUTE_MULTIPATH_RR
-	tristate "MULTIPATH: round robin algorithm"
-	depends on IP_ROUTE_MULTIPATH_CACHED
-	help
-	  Multipath routes are chosen according to Round Robin
-
-config IP_ROUTE_MULTIPATH_RANDOM
-	tristate "MULTIPATH: random algorithm"
-	depends on IP_ROUTE_MULTIPATH_CACHED
-	help
-	  Multipath routes are chosen in a random fashion. Actually,
-	  there is no weight for a route. The advantage of this policy
-	  is that it is implemented stateless and therefore introduces only
-	  a very small delay.
-
-config IP_ROUTE_MULTIPATH_WRANDOM
-	tristate "MULTIPATH: weighted random algorithm"
-	depends on IP_ROUTE_MULTIPATH_CACHED
-	help
-	  Multipath routes are chosen in a weighted random fashion. 
-	  The per route weights are the weights visible via ip route 2. As the
-	  corresponding state management introduces some overhead routing delay
-	  is increased.
-
-config IP_ROUTE_MULTIPATH_DRR
-	tristate "MULTIPATH: interface round robin algorithm"
-	depends on IP_ROUTE_MULTIPATH_CACHED
-	help
-	  Connections are distributed in a round robin fashion over the
-	  available interfaces. This policy makes sense if the connections 
-	  should be primarily distributed on interfaces and not on routes. 
-
 config IP_ROUTE_VERBOSE
 	bool "IP: verbose route monitoring"
 	depends on IP_ADVANCED_ROUTER
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 4ff6c15..fbf1674 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -29,14 +29,9 @@
 obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o
 obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o
 obj-$(CONFIG_IP_PNP) += ipconfig.o
-obj-$(CONFIG_IP_ROUTE_MULTIPATH_RR) += multipath_rr.o
-obj-$(CONFIG_IP_ROUTE_MULTIPATH_RANDOM) += multipath_random.o
-obj-$(CONFIG_IP_ROUTE_MULTIPATH_WRANDOM) += multipath_wrandom.o
-obj-$(CONFIG_IP_ROUTE_MULTIPATH_DRR) += multipath_drr.o
 obj-$(CONFIG_NETFILTER)	+= netfilter.o netfilter/
 obj-$(CONFIG_IP_VS) += ipvs/
 obj-$(CONFIG_INET_DIAG) += inet_diag.o 
-obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o
 obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
 obj-$(CONFIG_NET_TCPPROBE) += tcp_probe.o
 obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 041fba3..06c08e5 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1170,6 +1170,9 @@
 	int ihl;
 	int id;
 
+	if (!(features & NETIF_F_V4_CSUM))
+		features &= ~NETIF_F_SG;
+
 	if (unlikely(skb_shinfo(skb)->gso_type &
 		     ~(SKB_GSO_TCPV4 |
 		       SKB_GSO_UDP |
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 6da8ff5..7a23e59 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -339,3 +339,4 @@
 module_init(ah4_init);
 module_exit(ah4_fini);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_AH);
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 47c95e8..98767a4 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -481,3 +481,4 @@
 module_init(esp4_init);
 module_exit(esp4_fini);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_ESP);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 311d633..2eb909b 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -453,7 +453,6 @@
 	[RTA_MULTIPATH]		= { .len = sizeof(struct rtnexthop) },
 	[RTA_PROTOINFO]		= { .type = NLA_U32 },
 	[RTA_FLOW]		= { .type = NLA_U32 },
-	[RTA_MP_ALGO]		= { .type = NLA_U32 },
 };
 
 static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -515,9 +514,6 @@
 		case RTA_FLOW:
 			cfg->fc_flow = nla_get_u32(attr);
 			break;
-		case RTA_MP_ALGO:
-			cfg->fc_mp_alg = nla_get_u32(attr);
-			break;
 		case RTA_TABLE:
 			cfg->fc_table = nla_get_u32(attr);
 			break;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index bb94550..c434119 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -42,7 +42,6 @@
 #include <net/tcp.h>
 #include <net/sock.h>
 #include <net/ip_fib.h>
-#include <net/ip_mp_alg.h>
 #include <net/netlink.h>
 #include <net/nexthop.h>
 
@@ -697,13 +696,6 @@
 			goto err_inval;
 	}
 #endif
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	if (cfg->fc_mp_alg) {
-		if (cfg->fc_mp_alg < IP_MP_ALG_NONE ||
-		    cfg->fc_mp_alg > IP_MP_ALG_MAX)
-			goto err_inval;
-	}
-#endif
 
 	err = -ENOBUFS;
 	if (fib_info_cnt >= fib_hash_size) {
@@ -791,10 +783,6 @@
 #endif
 	}
 
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	fi->fib_mp_alg = cfg->fc_mp_alg;
-#endif
-
 	if (fib_props[cfg->fc_type].error) {
 		if (cfg->fc_gw || cfg->fc_oif || cfg->fc_mp)
 			goto err_inval;
@@ -940,10 +928,6 @@
 	res->type = fa->fa_type;
 	res->scope = fa->fa_scope;
 	res->fi = fa->fa_info;
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	res->netmask = mask;
-	res->network = zone & inet_make_mask(prefixlen);
-#endif
 	atomic_inc(&res->fi->fib_clntref);
 	return 0;
 }
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 6328293..5c14ed6 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -809,7 +809,8 @@
 
 	max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;
 
-	if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
+	if (skb_headroom(skb) < max_headroom || skb_shared(skb)||
+	    (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
 		struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
 		if (!new_skb) {
 			ip_rt_put(rt);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 34ea454..c9e2b5e 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -399,6 +399,10 @@
 	to->tc_index = from->tc_index;
 #endif
 	nf_copy(to, from);
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+	to->nf_trace = from->nf_trace;
+#endif
 #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
 	to->ipvs_property = from->ipvs_property;
 #endif
@@ -837,7 +841,7 @@
 	 */
 	if (transhdrlen &&
 	    length + fragheaderlen <= mtu &&
-	    rt->u.dst.dev->features & NETIF_F_ALL_CSUM &&
+	    rt->u.dst.dev->features & NETIF_F_V4_CSUM &&
 	    !exthdrlen)
 		csummode = CHECKSUM_PARTIAL;
 
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index ab86137..e787044 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -485,3 +485,4 @@
 MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) - RFC3173");
 MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
 
+MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_COMP);
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index ebd2f2d..3964372 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -595,7 +595,8 @@
 	 */
 	max_headroom = (LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr));
 
-	if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
+	if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
+	    (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
 		struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
 		if (!new_skb) {
 			ip_rt_put(rt);
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
index 15ad5dd..8d6901d 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/ipv4/ipvs/ip_vs_app.c
@@ -549,7 +549,7 @@
 	return 0;
 }
 
-static struct seq_operations ip_vs_app_seq_ops = {
+static const struct seq_operations ip_vs_app_seq_ops = {
 	.start = ip_vs_app_seq_start,
 	.next  = ip_vs_app_seq_next,
 	.stop  = ip_vs_app_seq_stop,
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index 7018f97..3b446b1 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -745,7 +745,7 @@
 	return 0;
 }
 
-static struct seq_operations ip_vs_conn_seq_ops = {
+static const struct seq_operations ip_vs_conn_seq_ops = {
 	.start = ip_vs_conn_seq_start,
 	.next  = ip_vs_conn_seq_next,
 	.stop  = ip_vs_conn_seq_stop,
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index 68fe1d4..e1052bc 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -1783,7 +1783,7 @@
 	return 0;
 }
 
-static struct seq_operations ip_vs_info_seq_ops = {
+static const struct seq_operations ip_vs_info_seq_ops = {
 	.start = ip_vs_info_seq_start,
 	.next  = ip_vs_info_seq_next,
 	.stop  = ip_vs_info_seq_stop,
diff --git a/net/ipv4/multipath.c b/net/ipv4/multipath.c
deleted file mode 100644
index 4e9ca7c..0000000
--- a/net/ipv4/multipath.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* multipath.c: IPV4 multipath algorithm support.
- *
- * Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com>
- * Copyright (C) 2005 David S. Miller <davem@davemloft.net>
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/spinlock.h>
-
-#include <net/ip_mp_alg.h>
-
-static DEFINE_SPINLOCK(alg_table_lock);
-struct ip_mp_alg_ops *ip_mp_alg_table[IP_MP_ALG_MAX + 1];
-
-int multipath_alg_register(struct ip_mp_alg_ops *ops, enum ip_mp_alg n)
-{
-	struct ip_mp_alg_ops **slot;
-	int err;
-
-	if (n < IP_MP_ALG_NONE || n > IP_MP_ALG_MAX ||
-	    !ops->mp_alg_select_route)
-		return -EINVAL;
-
-	spin_lock(&alg_table_lock);
-	slot = &ip_mp_alg_table[n];
-	if (*slot != NULL) {
-		err = -EBUSY;
-	} else {
-		*slot = ops;
-		err = 0;
-	}
-	spin_unlock(&alg_table_lock);
-
-	return err;
-}
-EXPORT_SYMBOL(multipath_alg_register);
-
-void multipath_alg_unregister(struct ip_mp_alg_ops *ops, enum ip_mp_alg n)
-{
-	struct ip_mp_alg_ops **slot;
-
-	if (n < IP_MP_ALG_NONE || n > IP_MP_ALG_MAX)
-		return;
-
-	spin_lock(&alg_table_lock);
-	slot = &ip_mp_alg_table[n];
-	if (*slot == ops)
-		*slot = NULL;
-	spin_unlock(&alg_table_lock);
-
-	synchronize_net();
-}
-EXPORT_SYMBOL(multipath_alg_unregister);
diff --git a/net/ipv4/multipath_drr.c b/net/ipv4/multipath_drr.c
deleted file mode 100644
index b03c5ca..0000000
--- a/net/ipv4/multipath_drr.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- *              Device round robin policy for multipath.
- *
- *
- * Version:	$Id: multipath_drr.c,v 1.1.2.1 2004/09/16 07:42:34 elueck Exp $
- *
- * Authors:	Einar Lueck <elueck@de.ibm.com><lkml@einar-lueck.de>
- *
- *		This program is free software; you can redistribute it and/or
- *		modify it under the terms of the GNU General Public License
- *		as published by the Free Software Foundation; either version
- *		2 of the License, or (at your option) any later version.
- */
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/igmp.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/module.h>
-#include <linux/mroute.h>
-#include <linux/init.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <net/udp.h>
-#include <net/raw.h>
-#include <linux/notifier.h>
-#include <linux/if_arp.h>
-#include <linux/netfilter_ipv4.h>
-#include <net/ipip.h>
-#include <net/checksum.h>
-#include <net/ip_mp_alg.h>
-
-struct multipath_device {
-	int		ifi; /* interface index of device */
-	atomic_t	usecount;
-	int 		allocated;
-};
-
-#define MULTIPATH_MAX_DEVICECANDIDATES 10
-
-static struct multipath_device state[MULTIPATH_MAX_DEVICECANDIDATES];
-static DEFINE_SPINLOCK(state_lock);
-
-static int inline __multipath_findslot(void)
-{
-	int i;
-
-	for (i = 0; i < MULTIPATH_MAX_DEVICECANDIDATES; i++) {
-		if (state[i].allocated == 0)
-			return i;
-	}
-	return -1;
-}
-
-static int inline __multipath_finddev(int ifindex)
-{
-	int i;
-
-	for (i = 0; i < MULTIPATH_MAX_DEVICECANDIDATES; i++) {
-		if (state[i].allocated != 0 &&
-		    state[i].ifi == ifindex)
-			return i;
-	}
-	return -1;
-}
-
-static int drr_dev_event(struct notifier_block *this,
-			 unsigned long event, void *ptr)
-{
-	struct net_device *dev = ptr;
-	int devidx;
-
-	switch (event) {
-	case NETDEV_UNREGISTER:
-	case NETDEV_DOWN:
-		spin_lock_bh(&state_lock);
-
-		devidx = __multipath_finddev(dev->ifindex);
-		if (devidx != -1) {
-			state[devidx].allocated = 0;
-			state[devidx].ifi = 0;
-			atomic_set(&state[devidx].usecount, 0);
-		}
-
-		spin_unlock_bh(&state_lock);
-		break;
-	}
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block drr_dev_notifier = {
-	.notifier_call	= drr_dev_event,
-};
-
-
-static void drr_safe_inc(atomic_t *usecount)
-{
-	int n;
-
-	atomic_inc(usecount);
-
-	n = atomic_read(usecount);
-	if (n <= 0) {
-		int i;
-
-		spin_lock_bh(&state_lock);
-
-		for (i = 0; i < MULTIPATH_MAX_DEVICECANDIDATES; i++)
-			atomic_set(&state[i].usecount, 0);
-
-		spin_unlock_bh(&state_lock);
-	}
-}
-
-static void drr_select_route(const struct flowi *flp,
-			     struct rtable *first, struct rtable **rp)
-{
-	struct rtable *nh, *result, *cur_min;
-	int min_usecount = -1;
-	int devidx = -1;
-	int cur_min_devidx = -1;
-
-	/* 1. make sure all alt. nexthops have the same GC related data */
-	/* 2. determine the new candidate to be returned */
-	result = NULL;
-	cur_min = NULL;
-	for (nh = rcu_dereference(first); nh;
-	     nh = rcu_dereference(nh->u.dst.rt_next)) {
-		if ((nh->u.dst.flags & DST_BALANCED) != 0 &&
-		    multipath_comparekeys(&nh->fl, flp)) {
-			int nh_ifidx = nh->u.dst.dev->ifindex;
-
-			nh->u.dst.lastuse = jiffies;
-			nh->u.dst.__use++;
-			if (result != NULL)
-				continue;
-
-			/* search for the output interface */
-
-			/* this is not SMP safe, only add/remove are
-			 * SMP safe as wrong usecount updates have no big
-			 * impact
-			 */
-			devidx = __multipath_finddev(nh_ifidx);
-			if (devidx == -1) {
-				/* add the interface to the array
-				 * SMP safe
-				 */
-				spin_lock_bh(&state_lock);
-
-				/* due to SMP: search again */
-				devidx = __multipath_finddev(nh_ifidx);
-				if (devidx == -1) {
-					/* add entry for device */
-					devidx = __multipath_findslot();
-					if (devidx == -1) {
-						/* unlikely but possible */
-						continue;
-					}
-
-					state[devidx].allocated = 1;
-					state[devidx].ifi = nh_ifidx;
-					atomic_set(&state[devidx].usecount, 0);
-					min_usecount = 0;
-				}
-
-				spin_unlock_bh(&state_lock);
-			}
-
-			if (min_usecount == 0) {
-				/* if the device has not been used it is
-				 * the primary target
-				 */
-				drr_safe_inc(&state[devidx].usecount);
-				result = nh;
-			} else {
-				int count =
-					atomic_read(&state[devidx].usecount);
-
-				if (min_usecount == -1 ||
-				    count < min_usecount) {
-					cur_min = nh;
-					cur_min_devidx = devidx;
-					min_usecount = count;
-				}
-			}
-		}
-	}
-
-	if (!result) {
-		if (cur_min) {
-			drr_safe_inc(&state[cur_min_devidx].usecount);
-			result = cur_min;
-		} else {
-			result = first;
-		}
-	}
-
-	*rp = result;
-}
-
-static struct ip_mp_alg_ops drr_ops = {
-	.mp_alg_select_route	=	drr_select_route,
-};
-
-static int __init drr_init(void)
-{
-	int err = register_netdevice_notifier(&drr_dev_notifier);
-
-	if (err)
-		return err;
-
-	err = multipath_alg_register(&drr_ops, IP_MP_ALG_DRR);
-	if (err)
-		goto fail;
-
-	return 0;
-
-fail:
-	unregister_netdevice_notifier(&drr_dev_notifier);
-	return err;
-}
-
-static void __exit drr_exit(void)
-{
-	unregister_netdevice_notifier(&drr_dev_notifier);
-	multipath_alg_unregister(&drr_ops, IP_MP_ALG_DRR);
-}
-
-module_init(drr_init);
-module_exit(drr_exit);
-MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_random.c b/net/ipv4/multipath_random.c
deleted file mode 100644
index c312785..0000000
--- a/net/ipv4/multipath_random.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- *              Random policy for multipath.
- *
- *
- * Version:	$Id: multipath_random.c,v 1.1.2.3 2004/09/21 08:42:11 elueck Exp $
- *
- * Authors:	Einar Lueck <elueck@de.ibm.com><lkml@einar-lueck.de>
- *
- *		This program is free software; you can redistribute it and/or
- *		modify it under the terms of the GNU General Public License
- *		as published by the Free Software Foundation; either version
- *		2 of the License, or (at your option) any later version.
- */
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/igmp.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/module.h>
-#include <linux/mroute.h>
-#include <linux/init.h>
-#include <linux/random.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <net/udp.h>
-#include <net/raw.h>
-#include <linux/notifier.h>
-#include <linux/if_arp.h>
-#include <linux/netfilter_ipv4.h>
-#include <net/ipip.h>
-#include <net/checksum.h>
-#include <net/ip_mp_alg.h>
-
-#define MULTIPATH_MAX_CANDIDATES 40
-
-static void random_select_route(const struct flowi *flp,
-				struct rtable *first,
-				struct rtable **rp)
-{
-	struct rtable *rt;
-	struct rtable *decision;
-	unsigned char candidate_count = 0;
-
-	/* count all candidate */
-	for (rt = rcu_dereference(first); rt;
-	     rt = rcu_dereference(rt->u.dst.rt_next)) {
-		if ((rt->u.dst.flags & DST_BALANCED) != 0 &&
-		    multipath_comparekeys(&rt->fl, flp))
-			++candidate_count;
-	}
-
-	/* choose a random candidate */
-	decision = first;
-	if (candidate_count > 1) {
-		unsigned char i = 0;
-		unsigned char candidate_no = (unsigned char)
-			(random32() % candidate_count);
-
-		/* find chosen candidate and adjust GC data for all candidates
-		 * to ensure they stay in cache
-		 */
-		for (rt = first; rt; rt = rt->u.dst.rt_next) {
-			if ((rt->u.dst.flags & DST_BALANCED) != 0 &&
-			    multipath_comparekeys(&rt->fl, flp)) {
-				rt->u.dst.lastuse = jiffies;
-
-				if (i == candidate_no)
-					decision = rt;
-
-				if (i >= candidate_count)
-					break;
-
-				i++;
-			}
-		}
-	}
-
-	decision->u.dst.__use++;
-	*rp = decision;
-}
-
-static struct ip_mp_alg_ops random_ops = {
-	.mp_alg_select_route	=	random_select_route,
-};
-
-static int __init random_init(void)
-{
-	return multipath_alg_register(&random_ops, IP_MP_ALG_RANDOM);
-}
-
-static void __exit random_exit(void)
-{
-	multipath_alg_unregister(&random_ops, IP_MP_ALG_RANDOM);
-}
-
-module_init(random_init);
-module_exit(random_exit);
-MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_rr.c b/net/ipv4/multipath_rr.c
deleted file mode 100644
index 0ad2252..0000000
--- a/net/ipv4/multipath_rr.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- *              Round robin policy for multipath.
- *
- *
- * Version:	$Id: multipath_rr.c,v 1.1.2.2 2004/09/16 07:42:34 elueck Exp $
- *
- * Authors:	Einar Lueck <elueck@de.ibm.com><lkml@einar-lueck.de>
- *
- *		This program is free software; you can redistribute it and/or
- *		modify it under the terms of the GNU General Public License
- *		as published by the Free Software Foundation; either version
- *		2 of the License, or (at your option) any later version.
- */
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/igmp.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/module.h>
-#include <linux/mroute.h>
-#include <linux/init.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <net/udp.h>
-#include <net/raw.h>
-#include <linux/notifier.h>
-#include <linux/if_arp.h>
-#include <linux/netfilter_ipv4.h>
-#include <net/ipip.h>
-#include <net/checksum.h>
-#include <net/ip_mp_alg.h>
-
-static void rr_select_route(const struct flowi *flp,
-			    struct rtable *first, struct rtable **rp)
-{
-	struct rtable *nh, *result, *min_use_cand = NULL;
-	int min_use = -1;
-
-	/* 1. make sure all alt. nexthops have the same GC related data
-	 * 2. determine the new candidate to be returned
-	 */
-	result = NULL;
-	for (nh = rcu_dereference(first); nh;
-	     nh = rcu_dereference(nh->u.dst.rt_next)) {
-		if ((nh->u.dst.flags & DST_BALANCED) != 0 &&
-		    multipath_comparekeys(&nh->fl, flp)) {
-			nh->u.dst.lastuse = jiffies;
-
-			if (min_use == -1 || nh->u.dst.__use < min_use) {
-				min_use = nh->u.dst.__use;
-				min_use_cand = nh;
-			}
-		}
-	}
-	result = min_use_cand;
-	if (!result)
-		result = first;
-
-	result->u.dst.__use++;
-	*rp = result;
-}
-
-static struct ip_mp_alg_ops rr_ops = {
-	.mp_alg_select_route	=	rr_select_route,
-};
-
-static int __init rr_init(void)
-{
-	return multipath_alg_register(&rr_ops, IP_MP_ALG_RR);
-}
-
-static void __exit rr_exit(void)
-{
-	multipath_alg_unregister(&rr_ops, IP_MP_ALG_RR);
-}
-
-module_init(rr_init);
-module_exit(rr_exit);
-MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
deleted file mode 100644
index 57c5036..0000000
--- a/net/ipv4/multipath_wrandom.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- *              Weighted random policy for multipath.
- *
- *
- * Version:	$Id: multipath_wrandom.c,v 1.1.2.3 2004/09/22 07:51:40 elueck Exp $
- *
- * Authors:	Einar Lueck <elueck@de.ibm.com><lkml@einar-lueck.de>
- *
- *		This program is free software; you can redistribute it and/or
- *		modify it under the terms of the GNU General Public License
- *		as published by the Free Software Foundation; either version
- *		2 of the License, or (at your option) any later version.
- */
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/igmp.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/module.h>
-#include <linux/mroute.h>
-#include <linux/init.h>
-#include <linux/random.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <net/udp.h>
-#include <net/raw.h>
-#include <linux/notifier.h>
-#include <linux/if_arp.h>
-#include <linux/netfilter_ipv4.h>
-#include <net/ipip.h>
-#include <net/checksum.h>
-#include <net/ip_fib.h>
-#include <net/ip_mp_alg.h>
-
-#define MULTIPATH_STATE_SIZE 15
-
-struct multipath_candidate {
-	struct multipath_candidate	*next;
-	int				power;
-	struct rtable			*rt;
-};
-
-struct multipath_dest {
-	struct list_head	list;
-
-	const struct fib_nh	*nh_info;
-	__be32			netmask;
-	__be32			network;
-	unsigned char		prefixlen;
-
-	struct rcu_head		rcu;
-};
-
-struct multipath_bucket {
-	struct list_head	head;
-	spinlock_t		lock;
-};
-
-struct multipath_route {
-	struct list_head	list;
-
-	int			oif;
-	__be32			gw;
-	struct list_head	dests;
-
-	struct rcu_head		rcu;
-};
-
-/* state: primarily weight per route information */
-static struct multipath_bucket state[MULTIPATH_STATE_SIZE];
-
-static unsigned char __multipath_lookup_weight(const struct flowi *fl,
-					       const struct rtable *rt)
-{
-	const int state_idx = rt->idev->dev->ifindex % MULTIPATH_STATE_SIZE;
-	struct multipath_route *r;
-	struct multipath_route *target_route = NULL;
-	struct multipath_dest *d;
-	int weight = 1;
-
-	/* lookup the weight information for a certain route */
-	rcu_read_lock();
-
-	/* find state entry for gateway or add one if necessary */
-	list_for_each_entry_rcu(r, &state[state_idx].head, list) {
-		if (r->gw == rt->rt_gateway &&
-		    r->oif == rt->idev->dev->ifindex) {
-			target_route = r;
-			break;
-		}
-	}
-
-	if (!target_route) {
-		/* this should not happen... but we are prepared */
-		printk( KERN_CRIT"%s: missing state for gateway: %u and " \
-			"device %d\n", __FUNCTION__, rt->rt_gateway,
-			rt->idev->dev->ifindex);
-		goto out;
-	}
-
-	/* find state entry for destination */
-	list_for_each_entry_rcu(d, &target_route->dests, list) {
-		__be32 targetnetwork = fl->fl4_dst &
-			inet_make_mask(d->prefixlen);
-
-		if ((targetnetwork & d->netmask) == d->network) {
-			weight = d->nh_info->nh_weight;
-			goto out;
-		}
-	}
-
-out:
-	rcu_read_unlock();
-	return weight;
-}
-
-static void wrandom_init_state(void)
-{
-	int i;
-
-	for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) {
-		INIT_LIST_HEAD(&state[i].head);
-		spin_lock_init(&state[i].lock);
-	}
-}
-
-static void wrandom_select_route(const struct flowi *flp,
-				 struct rtable *first,
-				 struct rtable **rp)
-{
-	struct rtable *rt;
-	struct rtable *decision;
-	struct multipath_candidate *first_mpc = NULL;
-	struct multipath_candidate *mpc, *last_mpc = NULL;
-	int power = 0;
-	int last_power;
-	int selector;
-	const size_t size_mpc = sizeof(struct multipath_candidate);
-
-	/* collect all candidates and identify their weights */
-	for (rt = rcu_dereference(first); rt;
-	     rt = rcu_dereference(rt->u.dst.rt_next)) {
-		if ((rt->u.dst.flags & DST_BALANCED) != 0 &&
-		    multipath_comparekeys(&rt->fl, flp)) {
-			struct multipath_candidate* mpc =
-				(struct multipath_candidate*)
-				kmalloc(size_mpc, GFP_ATOMIC);
-
-			if (!mpc)
-				return;
-
-			power += __multipath_lookup_weight(flp, rt) * 10000;
-
-			mpc->power = power;
-			mpc->rt = rt;
-			mpc->next = NULL;
-
-			if (!first_mpc)
-				first_mpc = mpc;
-			else
-				last_mpc->next = mpc;
-
-			last_mpc = mpc;
-		}
-	}
-
-	/* choose a weighted random candidate */
-	decision = first;
-	selector = random32() % power;
-	last_power = 0;
-
-	/* select candidate, adjust GC data and cleanup local state */
-	decision = first;
-	last_mpc = NULL;
-	for (mpc = first_mpc; mpc; mpc = mpc->next) {
-		mpc->rt->u.dst.lastuse = jiffies;
-		if (last_power <= selector && selector < mpc->power)
-			decision = mpc->rt;
-
-		last_power = mpc->power;
-		kfree(last_mpc);
-		last_mpc = mpc;
-	}
-
-	/* concurrent __multipath_flush may lead to !last_mpc */
-	kfree(last_mpc);
-
-	decision->u.dst.__use++;
-	*rp = decision;
-}
-
-static void wrandom_set_nhinfo(__be32 network,
-			       __be32 netmask,
-			       unsigned char prefixlen,
-			       const struct fib_nh *nh)
-{
-	const int state_idx = nh->nh_oif % MULTIPATH_STATE_SIZE;
-	struct multipath_route *r, *target_route = NULL;
-	struct multipath_dest *d, *target_dest = NULL;
-
-	/* store the weight information for a certain route */
-	spin_lock_bh(&state[state_idx].lock);
-
-	/* find state entry for gateway or add one if necessary */
-	list_for_each_entry_rcu(r, &state[state_idx].head, list) {
-		if (r->gw == nh->nh_gw && r->oif == nh->nh_oif) {
-			target_route = r;
-			break;
-		}
-	}
-
-	if (!target_route) {
-		const size_t size_rt = sizeof(struct multipath_route);
-		target_route = (struct multipath_route *)
-			kmalloc(size_rt, GFP_ATOMIC);
-
-		target_route->gw = nh->nh_gw;
-		target_route->oif = nh->nh_oif;
-		memset(&target_route->rcu, 0, sizeof(struct rcu_head));
-		INIT_LIST_HEAD(&target_route->dests);
-
-		list_add_rcu(&target_route->list, &state[state_idx].head);
-	}
-
-	/* find state entry for destination or add one if necessary */
-	list_for_each_entry_rcu(d, &target_route->dests, list) {
-		if (d->nh_info == nh) {
-			target_dest = d;
-			break;
-		}
-	}
-
-	if (!target_dest) {
-		const size_t size_dst = sizeof(struct multipath_dest);
-		target_dest = (struct multipath_dest*)
-			kmalloc(size_dst, GFP_ATOMIC);
-
-		target_dest->nh_info = nh;
-		target_dest->network = network;
-		target_dest->netmask = netmask;
-		target_dest->prefixlen = prefixlen;
-		memset(&target_dest->rcu, 0, sizeof(struct rcu_head));
-
-		list_add_rcu(&target_dest->list, &target_route->dests);
-	}
-	/* else: we already stored this info for another destination =>
-	 * we are finished
-	 */
-
-	spin_unlock_bh(&state[state_idx].lock);
-}
-
-static void __multipath_free(struct rcu_head *head)
-{
-	struct multipath_route *rt = container_of(head, struct multipath_route,
-						  rcu);
-	kfree(rt);
-}
-
-static void __multipath_free_dst(struct rcu_head *head)
-{
-	struct multipath_dest *dst = container_of(head,
-						  struct multipath_dest,
-						  rcu);
-	kfree(dst);
-}
-
-static void wrandom_flush(void)
-{
-	int i;
-
-	/* defere delete to all entries */
-	for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) {
-		struct multipath_route *r;
-
-		spin_lock_bh(&state[i].lock);
-		list_for_each_entry_rcu(r, &state[i].head, list) {
-			struct multipath_dest *d;
-			list_for_each_entry_rcu(d, &r->dests, list) {
-				list_del_rcu(&d->list);
-				call_rcu(&d->rcu,
-					 __multipath_free_dst);
-			}
-			list_del_rcu(&r->list);
-			call_rcu(&r->rcu,
-				 __multipath_free);
-		}
-
-		spin_unlock_bh(&state[i].lock);
-	}
-}
-
-static struct ip_mp_alg_ops wrandom_ops = {
-	.mp_alg_select_route	=	wrandom_select_route,
-	.mp_alg_flush		=	wrandom_flush,
-	.mp_alg_set_nhinfo	=	wrandom_set_nhinfo,
-};
-
-static int __init wrandom_init(void)
-{
-	wrandom_init_state();
-
-	return multipath_alg_register(&wrandom_ops, IP_MP_ALG_WRANDOM);
-}
-
-static void __exit wrandom_exit(void)
-{
-	multipath_alg_unregister(&wrandom_ops, IP_MP_ALG_WRANDOM);
-}
-
-module_init(wrandom_init);
-module_exit(wrandom_exit);
-MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 46509fa..fa97947 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -230,7 +230,7 @@
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 config IP_NF_TARGET_SAME
-	tristate "SAME target support"
+	tristate "SAME target support (OBSOLETE)"
 	depends on NF_NAT
 	help
 	  This option adds a `SAME' target, which works like the standard SNAT
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index cae4121..e981232 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -224,7 +224,7 @@
 	static const char nulldevname[IFNAMSIZ];
 	unsigned int verdict = NF_DROP;
 	struct arphdr *arp;
-	int hotdrop = 0;
+	bool hotdrop = false;
 	struct arpt_entry *e, *back;
 	const char *indev, *outdev;
 	void *table_base;
@@ -1140,13 +1140,13 @@
 }
 
 /* The built-in targets: standard (NULL) and error. */
-static struct arpt_target arpt_standard_target = {
+static struct arpt_target arpt_standard_target __read_mostly = {
 	.name		= ARPT_STANDARD_TARGET,
 	.targetsize	= sizeof(int),
 	.family		= NF_ARP,
 };
 
-static struct arpt_target arpt_error_target = {
+static struct arpt_target arpt_error_target __read_mostly = {
 	.name		= ARPT_ERROR_TARGET,
 	.target		= arpt_error,
 	.targetsize	= ARPT_FUNCTION_MAXNAMELEN,
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c
index 6298d40..c4bdab4 100644
--- a/net/ipv4/netfilter/arpt_mangle.c
+++ b/net/ipv4/netfilter/arpt_mangle.c
@@ -65,7 +65,7 @@
 	return mangle->target;
 }
 
-static int
+static bool
 checkentry(const char *tablename, const void *e, const struct xt_target *target,
 	   void *targinfo, unsigned int hook_mask)
 {
@@ -73,15 +73,15 @@
 
 	if (mangle->flags & ~ARPT_MANGLE_MASK ||
 	    !(mangle->flags & ARPT_MANGLE_MASK))
-		return 0;
+		return false;
 
 	if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT &&
 	   mangle->target != ARPT_CONTINUE)
-		return 0;
-	return 1;
+		return false;
+	return true;
 }
 
-static struct arpt_target arpt_mangle_reg = {
+static struct arpt_target arpt_mangle_reg __read_mostly = {
 	.name		= "mangle",
 	.target		= target,
 	.targetsize	= sizeof(struct arpt_mangle),
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 9bacf1a0..e1b402c 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -152,20 +152,20 @@
 	return 1;
 }
 
-static inline int
+static inline bool
 ip_checkentry(const struct ipt_ip *ip)
 {
 	if (ip->flags & ~IPT_F_MASK) {
 		duprintf("Unknown flag bits set: %08X\n",
 			 ip->flags & ~IPT_F_MASK);
-		return 0;
+		return false;
 	}
 	if (ip->invflags & ~IPT_INV_MASK) {
 		duprintf("Unknown invflag bits set: %08X\n",
 			 ip->invflags & ~IPT_INV_MASK);
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
 static unsigned int
@@ -183,19 +183,19 @@
 }
 
 static inline
-int do_match(struct ipt_entry_match *m,
-	     const struct sk_buff *skb,
-	     const struct net_device *in,
-	     const struct net_device *out,
-	     int offset,
-	     int *hotdrop)
+bool do_match(struct ipt_entry_match *m,
+	      const struct sk_buff *skb,
+	      const struct net_device *in,
+	      const struct net_device *out,
+	      int offset,
+	      bool *hotdrop)
 {
 	/* Stop iteration if it doesn't match */
 	if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data,
 				      offset, ip_hdrlen(skb), hotdrop))
-		return 1;
+		return true;
 	else
-		return 0;
+		return false;
 }
 
 static inline struct ipt_entry *
@@ -204,6 +204,112 @@
 	return (struct ipt_entry *)(base + offset);
 }
 
+/* All zeroes == unconditional rule. */
+static inline int
+unconditional(const struct ipt_ip *ip)
+{
+	unsigned int i;
+
+	for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++)
+		if (((__u32 *)ip)[i])
+			return 0;
+
+	return 1;
+}
+
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+static const char *hooknames[] = {
+	[NF_IP_PRE_ROUTING]		= "PREROUTING",
+	[NF_IP_LOCAL_IN]		= "INPUT",
+	[NF_IP_FORWARD]			= "FORWARD",
+	[NF_IP_LOCAL_OUT]		= "OUTPUT",
+	[NF_IP_POST_ROUTING]		= "POSTROUTING",
+};
+
+enum nf_ip_trace_comments {
+	NF_IP_TRACE_COMMENT_RULE,
+	NF_IP_TRACE_COMMENT_RETURN,
+	NF_IP_TRACE_COMMENT_POLICY,
+};
+
+static const char *comments[] = {
+	[NF_IP_TRACE_COMMENT_RULE]	= "rule",
+	[NF_IP_TRACE_COMMENT_RETURN]	= "return",
+	[NF_IP_TRACE_COMMENT_POLICY]	= "policy",
+};
+
+static struct nf_loginfo trace_loginfo = {
+	.type = NF_LOG_TYPE_LOG,
+	.u = {
+		.log = {
+			.level = 4,
+			.logflags = NF_LOG_MASK,
+		},
+	},
+};
+
+static inline int
+get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e,
+		      char *hookname, char **chainname,
+		      char **comment, unsigned int *rulenum)
+{
+	struct ipt_standard_target *t = (void *)ipt_get_target(s);
+
+	if (strcmp(t->target.u.kernel.target->name, IPT_ERROR_TARGET) == 0) {
+		/* Head of user chain: ERROR target with chainname */
+		*chainname = t->target.data;
+		(*rulenum) = 0;
+	} else if (s == e) {
+		(*rulenum)++;
+
+		if (s->target_offset == sizeof(struct ipt_entry)
+		   && strcmp(t->target.u.kernel.target->name,
+			     IPT_STANDARD_TARGET) == 0
+		   && t->verdict < 0
+		   && unconditional(&s->ip)) {
+			/* Tail of chains: STANDARD target (return/policy) */
+			*comment = *chainname == hookname
+				? (char *)comments[NF_IP_TRACE_COMMENT_POLICY]
+				: (char *)comments[NF_IP_TRACE_COMMENT_RETURN];
+		}
+		return 1;
+	} else
+		(*rulenum)++;
+
+	return 0;
+}
+
+static void trace_packet(struct sk_buff *skb,
+			 unsigned int hook,
+			 const struct net_device *in,
+			 const struct net_device *out,
+			 char *tablename,
+			 struct xt_table_info *private,
+			 struct ipt_entry *e)
+{
+	void *table_base;
+	struct ipt_entry *root;
+	char *hookname, *chainname, *comment;
+	unsigned int rulenum = 0;
+
+	table_base = (void *)private->entries[smp_processor_id()];
+	root = get_entry(table_base, private->hook_entry[hook]);
+
+	hookname = chainname = (char *)hooknames[hook];
+	comment = (char *)comments[NF_IP_TRACE_COMMENT_RULE];
+
+	IPT_ENTRY_ITERATE(root,
+			  private->size - private->hook_entry[hook],
+			  get_chainname_rulenum,
+			  e, hookname, &chainname, &comment, &rulenum);
+
+	nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo,
+		      "TRACE: %s:%s:%s:%u ",
+		      tablename, chainname, comment, rulenum);
+}
+#endif
+
 /* Returns one of the generic firewall policies, like NF_ACCEPT. */
 unsigned int
 ipt_do_table(struct sk_buff **pskb,
@@ -216,7 +322,7 @@
 	u_int16_t offset;
 	struct iphdr *ip;
 	u_int16_t datalen;
-	int hotdrop = 0;
+	bool hotdrop = false;
 	/* Initializing verdict to NF_DROP keeps gcc happy. */
 	unsigned int verdict = NF_DROP;
 	const char *indev, *outdev;
@@ -261,6 +367,14 @@
 
 			t = ipt_get_target(e);
 			IP_NF_ASSERT(t->u.kernel.target);
+
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+			/* The packet is traced: log it */
+			if (unlikely((*pskb)->nf_trace))
+				trace_packet(*pskb, hook, in, out,
+					     table->name, private, e);
+#endif
 			/* Standard target? */
 			if (!t->u.kernel.target->target) {
 				int v;
@@ -341,19 +455,6 @@
 #endif
 }
 
-/* All zeroes == unconditional rule. */
-static inline int
-unconditional(const struct ipt_ip *ip)
-{
-	unsigned int i;
-
-	for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++)
-		if (((__u32 *)ip)[i])
-			return 0;
-
-	return 1;
-}
-
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
@@ -2105,16 +2206,16 @@
 }
 
 /* Returns 1 if the type and code is matched by the range, 0 otherwise */
-static inline int
+static inline bool
 icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
 		     u_int8_t type, u_int8_t code,
-		     int invert)
+		     bool invert)
 {
 	return ((test_type == 0xFF) || (type == test_type && code >= min_code && code <= max_code))
 		^ invert;
 }
 
-static int
+static bool
 icmp_match(const struct sk_buff *skb,
 	   const struct net_device *in,
 	   const struct net_device *out,
@@ -2122,14 +2223,14 @@
 	   const void *matchinfo,
 	   int offset,
 	   unsigned int protoff,
-	   int *hotdrop)
+	   bool *hotdrop)
 {
 	struct icmphdr _icmph, *ic;
 	const struct ipt_icmp *icmpinfo = matchinfo;
 
 	/* Must not be a fragment. */
 	if (offset)
-		return 0;
+		return false;
 
 	ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph);
 	if (ic == NULL) {
@@ -2137,8 +2238,8 @@
 		 * can't.  Hence, no choice but to drop.
 		 */
 		duprintf("Dropping evil ICMP tinygram.\n");
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	return icmp_type_code_match(icmpinfo->type,
@@ -2149,7 +2250,7 @@
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 icmp_checkentry(const char *tablename,
 	   const void *info,
 	   const struct xt_match *match,
@@ -2163,7 +2264,7 @@
 }
 
 /* The built-in targets: standard (NULL) and error. */
-static struct xt_target ipt_standard_target = {
+static struct xt_target ipt_standard_target __read_mostly = {
 	.name		= IPT_STANDARD_TARGET,
 	.targetsize	= sizeof(int),
 	.family		= AF_INET,
@@ -2174,7 +2275,7 @@
 #endif
 };
 
-static struct xt_target ipt_error_target = {
+static struct xt_target ipt_error_target __read_mostly = {
 	.name		= IPT_ERROR_TARGET,
 	.target		= ipt_error,
 	.targetsize	= IPT_FUNCTION_MAXNAMELEN,
@@ -2197,7 +2298,7 @@
 #endif
 };
 
-static struct xt_match icmp_matchstruct = {
+static struct xt_match icmp_matchstruct __read_mostly = {
 	.name		= "icmp",
 	.match		= icmp_match,
 	.matchsize	= sizeof(struct ipt_icmp),
@@ -2230,7 +2331,7 @@
 	if (ret < 0)
 		goto err5;
 
-	printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n");
+	printk(KERN_INFO "ip_tables: (C) 2000-2006 Netfilter Core Team\n");
 	return 0;
 
 err5:
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 40e2734..dcc12b1 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -30,14 +30,6 @@
 
 #define CLUSTERIP_VERSION "0.8"
 
-#define DEBUG_CLUSTERIP
-
-#ifdef DEBUG_CLUSTERIP
-#define DEBUGP	printk
-#else
-#define DEBUGP
-#endif
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("iptables target for CLUSTERIP");
@@ -122,9 +114,8 @@
 	list_for_each(pos, &clusterip_configs) {
 		struct clusterip_config *c = list_entry(pos,
 					struct clusterip_config, list);
-		if (c->clusterip == clusterip) {
+		if (c->clusterip == clusterip)
 			return c;
-		}
 	}
 
 	return NULL;
@@ -155,9 +146,8 @@
 {
 	int n;
 
-	for (n = 0; n < i->num_local_nodes; n++) {
+	for (n = 0; n < i->num_local_nodes; n++)
 		set_bit(i->local_nodes[n] - 1, &c->local_nodes);
-	}
 }
 
 static struct clusterip_config *
@@ -220,27 +210,28 @@
 	return 0;
 }
 
-static int
+static bool
 clusterip_del_node(struct clusterip_config *c, u_int16_t nodenum)
 {
 	if (nodenum == 0 ||
 	    nodenum > c->num_total_nodes)
-		return 1;
+		return true;
 
 	if (test_and_clear_bit(nodenum - 1, &c->local_nodes))
-		return 0;
+		return false;
 
-	return 1;
+	return true;
 }
 #endif
 
 static inline u_int32_t
-clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config)
+clusterip_hashfn(const struct sk_buff *skb,
+		 const struct clusterip_config *config)
 {
-	struct iphdr *iph = ip_hdr(skb);
+	const struct iphdr *iph = ip_hdr(skb);
 	unsigned long hashval;
 	u_int16_t sport, dport;
-	u_int16_t *ports;
+	const u_int16_t *ports;
 
 	switch (iph->protocol) {
 	case IPPROTO_TCP:
@@ -249,15 +240,14 @@
 	case IPPROTO_SCTP:
 	case IPPROTO_DCCP:
 	case IPPROTO_ICMP:
-		ports = (void *)iph+iph->ihl*4;
+		ports = (const void *)iph+iph->ihl*4;
 		sport = ports[0];
 		dport = ports[1];
 		break;
 	default:
-		if (net_ratelimit()) {
+		if (net_ratelimit())
 			printk(KERN_NOTICE "CLUSTERIP: unknown protocol `%u'\n",
 				iph->protocol);
-		}
 		sport = dport = 0;
 	}
 
@@ -285,11 +275,11 @@
 	}
 
 	/* node numbers are 1..n, not 0..n */
-	return ((hashval % config->num_total_nodes)+1);
+	return (hashval % config->num_total_nodes) + 1;
 }
 
 static inline int
-clusterip_responsible(struct clusterip_config *config, u_int32_t hash)
+clusterip_responsible(const struct clusterip_config *config, u_int32_t hash)
 {
 	return test_bit(hash - 1, &config->local_nodes);
 }
@@ -353,15 +343,15 @@
 			break;
 	}
 
-#ifdef DEBUG_CLUSTERP
+#ifdef DEBUG
 	DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
 #endif
-	DEBUGP("hash=%u ct_hash=%u ", hash, ct->mark);
+	pr_debug("hash=%u ct_hash=%u ", hash, ct->mark);
 	if (!clusterip_responsible(cipinfo->config, hash)) {
-		DEBUGP("not responsible\n");
+		pr_debug("not responsible\n");
 		return NF_DROP;
 	}
-	DEBUGP("responsible\n");
+	pr_debug("responsible\n");
 
 	/* despite being received via linklayer multicast, this is
 	 * actually a unicast IP packet. TCP doesn't like PACKET_MULTICAST */
@@ -370,7 +360,7 @@
 	return XT_CONTINUE;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *e_void,
 	   const struct xt_target *target,
@@ -387,50 +377,34 @@
 	    cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) {
 		printk(KERN_WARNING "CLUSTERIP: unknown mode `%u'\n",
 			cipinfo->hash_mode);
-		return 0;
+		return false;
 
 	}
 	if (e->ip.dmsk.s_addr != htonl(0xffffffff)
 	    || e->ip.dst.s_addr == 0) {
 		printk(KERN_ERR "CLUSTERIP: Please specify destination IP\n");
-		return 0;
+		return false;
 	}
 
 	/* FIXME: further sanity checks */
 
 	config = clusterip_config_find_get(e->ip.dst.s_addr, 1);
-	if (config) {
-		if (cipinfo->config != NULL) {
-			/* Case A: This is an entry that gets reloaded, since
-			 * it still has a cipinfo->config pointer. Simply
-			 * increase the entry refcount and return */
-			if (cipinfo->config != config) {
-				printk(KERN_ERR "CLUSTERIP: Reloaded entry "
-				       "has invalid config pointer!\n");
-				return 0;
-			}
-		} else {
-			/* Case B: This is a new rule referring to an existing
-			 * clusterip config. */
-			cipinfo->config = config;
-		}
-	} else {
-		/* Case C: This is a completely new clusterip config */
+	if (!config) {
 		if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) {
 			printk(KERN_WARNING "CLUSTERIP: no config found for %u.%u.%u.%u, need 'new'\n", NIPQUAD(e->ip.dst.s_addr));
-			return 0;
+			return false;
 		} else {
 			struct net_device *dev;
 
 			if (e->ip.iniface[0] == '\0') {
 				printk(KERN_WARNING "CLUSTERIP: Please specify an interface name\n");
-				return 0;
+				return false;
 			}
 
 			dev = dev_get_by_name(e->ip.iniface);
 			if (!dev) {
 				printk(KERN_WARNING "CLUSTERIP: no such interface %s\n", e->ip.iniface);
-				return 0;
+				return false;
 			}
 
 			config = clusterip_config_init(cipinfo,
@@ -438,20 +412,20 @@
 			if (!config) {
 				printk(KERN_WARNING "CLUSTERIP: cannot allocate config\n");
 				dev_put(dev);
-				return 0;
+				return false;
 			}
 			dev_mc_add(config->dev,config->clustermac, ETH_ALEN, 0);
 		}
-		cipinfo->config = config;
 	}
+	cipinfo->config = config;
 
 	if (nf_ct_l3proto_try_module_get(target->family) < 0) {
 		printk(KERN_WARNING "can't load conntrack support for "
 				    "proto=%d\n", target->family);
-		return 0;
+		return false;
 	}
 
-	return 1;
+	return true;
 }
 
 /* drop reference count of cluster config when rule is deleted */
@@ -468,13 +442,30 @@
 	nf_ct_l3proto_module_put(target->family);
 }
 
-static struct xt_target clusterip_tgt = {
+#ifdef CONFIG_COMPAT
+struct compat_ipt_clusterip_tgt_info
+{
+	u_int32_t	flags;
+	u_int8_t	clustermac[6];
+	u_int16_t	num_total_nodes;
+	u_int16_t	num_local_nodes;
+	u_int16_t	local_nodes[CLUSTERIP_MAX_NODES];
+	u_int32_t	hash_mode;
+	u_int32_t	hash_initval;
+	compat_uptr_t	config;
+};
+#endif /* CONFIG_COMPAT */
+
+static struct xt_target clusterip_tgt __read_mostly = {
 	.name		= "CLUSTERIP",
 	.family		= AF_INET,
 	.target		= target,
-	.targetsize	= sizeof(struct ipt_clusterip_tgt_info),
 	.checkentry	= checkentry,
 	.destroy	= destroy,
+	.targetsize	= sizeof(struct ipt_clusterip_tgt_info),
+#ifdef CONFIG_COMPAT
+	.compatsize	= sizeof(struct compat_ipt_clusterip_tgt_info),
+#endif /* CONFIG_COMPAT */
 	.me		= THIS_MODULE
 };
 
@@ -491,7 +482,7 @@
 	__be32 dst_ip;
 } __attribute__ ((packed));
 
-#ifdef CLUSTERIP_DEBUG
+#ifdef DEBUG
 static void arp_print(struct arp_payload *payload)
 {
 #define HBUFFERLEN 30
@@ -547,8 +538,9 @@
 	 * this wouldn't work, since we didn't subscribe the mcast group on
 	 * other interfaces */
 	if (c->dev != out) {
-		DEBUGP("CLUSTERIP: not mangling arp reply on different "
-		       "interface: cip'%s'-skb'%s'\n", c->dev->name, out->name);
+		pr_debug("CLUSTERIP: not mangling arp reply on different "
+			 "interface: cip'%s'-skb'%s'\n",
+			 c->dev->name, out->name);
 		clusterip_config_put(c);
 		return NF_ACCEPT;
 	}
@@ -556,8 +548,8 @@
 	/* mangle reply hardware address */
 	memcpy(payload->src_hw, c->clustermac, arp->ar_hln);
 
-#ifdef CLUSTERIP_DEBUG
-	DEBUGP(KERN_DEBUG "CLUSTERIP mangled arp reply: ");
+#ifdef DEBUG
+	pr_debug(KERN_DEBUG "CLUSTERIP mangled arp reply: ");
 	arp_print(payload);
 #endif
 
@@ -647,7 +639,7 @@
 	return 0;
 }
 
-static struct seq_operations clusterip_seq_ops = {
+static const struct seq_operations clusterip_seq_ops = {
 	.start	= clusterip_seq_start,
 	.next	= clusterip_seq_next,
 	.stop	= clusterip_seq_stop,
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
index 918ca92..f1253bd 100644
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -24,8 +24,8 @@
 MODULE_DESCRIPTION("iptables ECN modification module");
 
 /* set ECT codepoint from IP header.
- * 	return 0 if there was an error. */
-static inline int
+ * 	return false if there was an error. */
+static inline bool
 set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
 {
 	struct iphdr *iph = ip_hdr(*pskb);
@@ -33,18 +33,18 @@
 	if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
 		__u8 oldtos;
 		if (!skb_make_writable(pskb, sizeof(struct iphdr)))
-			return 0;
+			return false;
 		iph = ip_hdr(*pskb);
 		oldtos = iph->tos;
 		iph->tos &= ~IPT_ECN_IP_MASK;
 		iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
 		nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
 	}
-	return 1;
+	return true;
 }
 
-/* Return 0 if there was an error. */
-static inline int
+/* Return false if there was an error. */
+static inline bool
 set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
 {
 	struct tcphdr _tcph, *tcph;
@@ -54,16 +54,16 @@
 	tcph = skb_header_pointer(*pskb, ip_hdrlen(*pskb),
 				  sizeof(_tcph), &_tcph);
 	if (!tcph)
-		return 0;
+		return false;
 
 	if ((!(einfo->operation & IPT_ECN_OP_SET_ECE) ||
 	     tcph->ece == einfo->proto.tcp.ece) &&
-	    ((!(einfo->operation & IPT_ECN_OP_SET_CWR) ||
-	     tcph->cwr == einfo->proto.tcp.cwr)))
-		return 1;
+	    (!(einfo->operation & IPT_ECN_OP_SET_CWR) ||
+	     tcph->cwr == einfo->proto.tcp.cwr))
+		return true;
 
 	if (!skb_make_writable(pskb, ip_hdrlen(*pskb) + sizeof(*tcph)))
-		return 0;
+		return false;
 	tcph = (void *)ip_hdr(*pskb) + ip_hdrlen(*pskb);
 
 	oldval = ((__be16 *)tcph)[6];
@@ -74,7 +74,7 @@
 
 	nf_proto_csum_replace2(&tcph->check, *pskb,
 				oldval, ((__be16 *)tcph)[6], 0);
-	return 1;
+	return true;
 }
 
 static unsigned int
@@ -99,7 +99,7 @@
 	return XT_CONTINUE;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *e_void,
 	   const struct xt_target *target,
@@ -112,23 +112,23 @@
 	if (einfo->operation & IPT_ECN_OP_MASK) {
 		printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
 			einfo->operation);
-		return 0;
+		return false;
 	}
 	if (einfo->ip_ect & ~IPT_ECN_IP_MASK) {
 		printk(KERN_WARNING "ECN: new ECT codepoint %x out of mask\n",
 			einfo->ip_ect);
-		return 0;
+		return false;
 	}
 	if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR))
 	    && (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) {
 		printk(KERN_WARNING "ECN: cannot use TCP operations on a "
 		       "non-tcp rule\n");
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_target ipt_ecn_reg = {
+static struct xt_target ipt_ecn_reg __read_mostly = {
 	.name		= "ECN",
 	.family		= AF_INET,
 	.target		= target,
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index a42c5cd..5937ad1 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -27,12 +27,6 @@
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("iptables syslog logging module");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Use lock to serialize, so printks don't overlap */
 static DEFINE_SPINLOCK(log_lock);
 
@@ -41,7 +35,8 @@
 			const struct sk_buff *skb,
 			unsigned int iphoff)
 {
-	struct iphdr _iph, *ih;
+	struct iphdr _iph;
+	const struct iphdr *ih;
 	unsigned int logflags;
 
 	if (info->type == NF_LOG_TYPE_LOG)
@@ -100,7 +95,8 @@
 
 	switch (ih->protocol) {
 	case IPPROTO_TCP: {
-		struct tcphdr _tcph, *th;
+		struct tcphdr _tcph;
+		const struct tcphdr *th;
 
 		/* Max length: 10 "PROTO=TCP " */
 		printk("PROTO=TCP ");
@@ -151,7 +147,7 @@
 		if ((logflags & IPT_LOG_TCPOPT)
 		    && th->doff * 4 > sizeof(struct tcphdr)) {
 			unsigned char _opt[4 * 15 - sizeof(struct tcphdr)];
-			unsigned char *op;
+			const unsigned char *op;
 			unsigned int i, optsize;
 
 			optsize = th->doff * 4 - sizeof(struct tcphdr);
@@ -173,7 +169,8 @@
 	}
 	case IPPROTO_UDP:
 	case IPPROTO_UDPLITE: {
-		struct udphdr _udph, *uh;
+		struct udphdr _udph;
+		const struct udphdr *uh;
 
 		if (ih->protocol == IPPROTO_UDP)
 			/* Max length: 10 "PROTO=UDP "     */
@@ -200,7 +197,8 @@
 		break;
 	}
 	case IPPROTO_ICMP: {
-		struct icmphdr _icmph, *ich;
+		struct icmphdr _icmph;
+		const struct icmphdr *ich;
 		static const size_t required_len[NR_ICMP_TYPES+1]
 			= { [ICMP_ECHOREPLY] = 4,
 			    [ICMP_DEST_UNREACH]
@@ -285,7 +283,8 @@
 	}
 	/* Max Length */
 	case IPPROTO_AH: {
-		struct ip_auth_hdr _ahdr, *ah;
+		struct ip_auth_hdr _ahdr;
+		const struct ip_auth_hdr *ah;
 
 		if (ntohs(ih->frag_off) & IP_OFFSET)
 			break;
@@ -307,7 +306,8 @@
 		break;
 	}
 	case IPPROTO_ESP: {
-		struct ip_esp_hdr _esph, *eh;
+		struct ip_esp_hdr _esph;
+		const struct ip_esp_hdr *eh;
 
 		/* Max length: 10 "PROTO=ESP " */
 		printk("PROTO=ESP ");
@@ -385,11 +385,13 @@
 	       out ? out->name : "");
 #ifdef CONFIG_BRIDGE_NETFILTER
 	if (skb->nf_bridge) {
-		struct net_device *physindev = skb->nf_bridge->physindev;
-		struct net_device *physoutdev = skb->nf_bridge->physoutdev;
+		const struct net_device *physindev;
+		const struct net_device *physoutdev;
 
+		physindev = skb->nf_bridge->physindev;
 		if (physindev && in != physindev)
 			printk("PHYSIN=%s ", physindev->name);
+		physoutdev = skb->nf_bridge->physoutdev;
 		if (physoutdev && out != physoutdev)
 			printk("PHYSOUT=%s ", physoutdev->name);
 	}
@@ -435,27 +437,27 @@
 	return XT_CONTINUE;
 }
 
-static int ipt_log_checkentry(const char *tablename,
-			      const void *e,
-			      const struct xt_target *target,
-			      void *targinfo,
-			      unsigned int hook_mask)
+static bool ipt_log_checkentry(const char *tablename,
+			       const void *e,
+			       const struct xt_target *target,
+			       void *targinfo,
+			       unsigned int hook_mask)
 {
 	const struct ipt_log_info *loginfo = targinfo;
 
 	if (loginfo->level >= 8) {
-		DEBUGP("LOG: level %u >= 8\n", loginfo->level);
-		return 0;
+		pr_debug("LOG: level %u >= 8\n", loginfo->level);
+		return false;
 	}
 	if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
-		DEBUGP("LOG: prefix term %i\n",
-		       loginfo->prefix[sizeof(loginfo->prefix)-1]);
-		return 0;
+		pr_debug("LOG: prefix term %i\n",
+			 loginfo->prefix[sizeof(loginfo->prefix)-1]);
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_target ipt_log_reg = {
+static struct xt_target ipt_log_reg __read_mostly = {
 	.name		= "LOG",
 	.family		= AF_INET,
 	.target		= ipt_log_target,
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index d4f2d77..7c4e4be 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -27,17 +27,11 @@
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("iptables MASQUERADE target module");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Lock protects masq region inside conntrack */
 static DEFINE_RWLOCK(masq_lock);
 
 /* FIXME: Multiple targets. --RR */
-static int
+static bool
 masquerade_check(const char *tablename,
 		 const void *e,
 		 const struct xt_target *target,
@@ -47,14 +41,14 @@
 	const struct nf_nat_multi_range_compat *mr = targinfo;
 
 	if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
-		DEBUGP("masquerade_check: bad MAP_IPS.\n");
-		return 0;
+		pr_debug("masquerade_check: bad MAP_IPS.\n");
+		return false;
 	}
 	if (mr->rangesize != 1) {
-		DEBUGP("masquerade_check: bad rangesize %u.\n", mr->rangesize);
-		return 0;
+		pr_debug("masquerade_check: bad rangesize %u\n", mr->rangesize);
+		return false;
 	}
-	return 1;
+	return true;
 }
 
 static unsigned int
@@ -70,7 +64,7 @@
 	enum ip_conntrack_info ctinfo;
 	struct nf_nat_range newrange;
 	const struct nf_nat_multi_range_compat *mr;
-	struct rtable *rt;
+	const struct rtable *rt;
 	__be32 newsrc;
 
 	NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING);
@@ -109,10 +103,10 @@
 	return nf_nat_setup_info(ct, &newrange, hooknum);
 }
 
-static inline int
+static int
 device_cmp(struct nf_conn *i, void *ifindex)
 {
-	struct nf_conn_nat *nat = nfct_nat(i);
+	const struct nf_conn_nat *nat = nfct_nat(i);
 	int ret;
 
 	if (!nat)
@@ -129,7 +123,7 @@
 			     unsigned long event,
 			     void *ptr)
 {
-	struct net_device *dev = ptr;
+	const struct net_device *dev = ptr;
 
 	if (event == NETDEV_DOWN) {
 		/* Device was downed.  Search entire table for
@@ -147,7 +141,7 @@
 			   unsigned long event,
 			   void *ptr)
 {
-	struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
+	const struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
 
 	if (event == NETDEV_DOWN) {
 		/* IP address was deleted.  Search entire table for
@@ -169,7 +163,7 @@
 	.notifier_call	= masq_inet_event,
 };
 
-static struct xt_target masquerade = {
+static struct xt_target masquerade __read_mostly = {
 	.name		= "MASQUERADE",
 	.family		= AF_INET,
 	.target		= masquerade_target,
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c
index 068c69b..41a011d 100644
--- a/net/ipv4/netfilter/ipt_NETMAP.c
+++ b/net/ipv4/netfilter/ipt_NETMAP.c
@@ -18,18 +18,11 @@
 #include <linux/netfilter/x_tables.h>
 #include <net/netfilter/nf_nat_rule.h>
 
-#define MODULENAME "NETMAP"
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
 MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-static int
+static bool
 check(const char *tablename,
       const void *e,
       const struct xt_target *target,
@@ -39,14 +32,14 @@
 	const struct nf_nat_multi_range_compat *mr = targinfo;
 
 	if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
-		DEBUGP(MODULENAME":check: bad MAP_IPS.\n");
-		return 0;
+		pr_debug("NETMAP:check: bad MAP_IPS.\n");
+		return false;
 	}
 	if (mr->rangesize != 1) {
-		DEBUGP(MODULENAME":check: bad rangesize %u.\n", mr->rangesize);
-		return 0;
+		pr_debug("NETMAP:check: bad rangesize %u.\n", mr->rangesize);
+		return false;
 	}
-	return 1;
+	return true;
 }
 
 static unsigned int
@@ -85,8 +78,8 @@
 	return nf_nat_setup_info(ct, &newrange, hooknum);
 }
 
-static struct xt_target target_module = {
-	.name 		= MODULENAME,
+static struct xt_target target_module __read_mostly = {
+	.name 		= "NETMAP",
 	.family		= AF_INET,
 	.target 	= target,
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
index 68cc76a1..6ac7a23 100644
--- a/net/ipv4/netfilter/ipt_REDIRECT.c
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c
@@ -25,14 +25,8 @@
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("iptables REDIRECT target module");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* FIXME: Take multiple ranges --RR */
-static int
+static bool
 redirect_check(const char *tablename,
 	       const void *e,
 	       const struct xt_target *target,
@@ -42,14 +36,14 @@
 	const struct nf_nat_multi_range_compat *mr = targinfo;
 
 	if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
-		DEBUGP("redirect_check: bad MAP_IPS.\n");
-		return 0;
+		pr_debug("redirect_check: bad MAP_IPS.\n");
+		return false;
 	}
 	if (mr->rangesize != 1) {
-		DEBUGP("redirect_check: bad rangesize %u.\n", mr->rangesize);
-		return 0;
+		pr_debug("redirect_check: bad rangesize %u.\n", mr->rangesize);
+		return false;
 	}
-	return 1;
+	return true;
 }
 
 static unsigned int
@@ -101,7 +95,7 @@
 	return nf_nat_setup_info(ct, &newrange, hooknum);
 }
 
-static struct xt_target redirect_reg = {
+static struct xt_target redirect_reg __read_mostly = {
 	.name		= "REDIRECT",
 	.family		= AF_INET,
 	.target		= redirect_target,
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 9041e07..cb038c8 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -31,12 +31,6 @@
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("iptables REJECT target module");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Send RST reply */
 static void send_reset(struct sk_buff *oldskb, int hook)
 {
@@ -122,7 +116,7 @@
 	tcph->check = 0;
 	tcph->check = tcp_v4_check(sizeof(struct tcphdr),
 				   niph->saddr, niph->daddr,
-				   csum_partial((char *)tcph,
+				   csum_partial(tcph,
 						sizeof(struct tcphdr), 0));
 
 	/* Set DF, id = 0 */
@@ -217,30 +211,30 @@
 	return NF_DROP;
 }
 
-static int check(const char *tablename,
-		 const void *e_void,
-		 const struct xt_target *target,
-		 void *targinfo,
-		 unsigned int hook_mask)
+static bool check(const char *tablename,
+		  const void *e_void,
+		  const struct xt_target *target,
+		  void *targinfo,
+		  unsigned int hook_mask)
 {
 	const struct ipt_reject_info *rejinfo = targinfo;
 	const struct ipt_entry *e = e_void;
 
 	if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
-		printk("REJECT: ECHOREPLY no longer supported.\n");
-		return 0;
+		printk("ipt_REJECT: ECHOREPLY no longer supported.\n");
+		return false;
 	} else if (rejinfo->with == IPT_TCP_RESET) {
 		/* Must specify that it's a TCP packet */
 		if (e->ip.proto != IPPROTO_TCP
 		    || (e->ip.invflags & XT_INV_PROTO)) {
-			DEBUGP("REJECT: TCP_RESET invalid for non-tcp\n");
-			return 0;
+			printk("ipt_REJECT: TCP_RESET invalid for non-tcp\n");
+			return false;
 		}
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_target ipt_reject_reg = {
+static struct xt_target ipt_reject_reg __read_mostly = {
 	.name		= "REJECT",
 	.family		= AF_INET,
 	.target		= reject,
diff --git a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c
index 511e5ff..97641f1 100644
--- a/net/ipv4/netfilter/ipt_SAME.c
+++ b/net/ipv4/netfilter/ipt_SAME.c
@@ -27,13 +27,7 @@
 MODULE_AUTHOR("Martin Josefsson <gandalf@wlug.westbo.se>");
 MODULE_DESCRIPTION("iptables special SNAT module for consistent sourceip");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-static int
+static bool
 same_check(const char *tablename,
 	      const void *e,
 	      const struct xt_target *target,
@@ -46,58 +40,56 @@
 	mr->ipnum = 0;
 
 	if (mr->rangesize < 1) {
-		DEBUGP("same_check: need at least one dest range.\n");
-		return 0;
+		pr_debug("same_check: need at least one dest range.\n");
+		return false;
 	}
 	if (mr->rangesize > IPT_SAME_MAX_RANGE) {
-		DEBUGP("same_check: too many ranges specified, maximum "
-				"is %u ranges\n",
-				IPT_SAME_MAX_RANGE);
-		return 0;
+		pr_debug("same_check: too many ranges specified, maximum "
+			 "is %u ranges\n", IPT_SAME_MAX_RANGE);
+		return false;
 	}
 	for (count = 0; count < mr->rangesize; count++) {
 		if (ntohl(mr->range[count].min_ip) >
 				ntohl(mr->range[count].max_ip)) {
-			DEBUGP("same_check: min_ip is larger than max_ip in "
-				"range `%u.%u.%u.%u-%u.%u.%u.%u'.\n",
-				NIPQUAD(mr->range[count].min_ip),
-				NIPQUAD(mr->range[count].max_ip));
-			return 0;
+			pr_debug("same_check: min_ip is larger than max_ip in "
+				 "range `%u.%u.%u.%u-%u.%u.%u.%u'.\n",
+				 NIPQUAD(mr->range[count].min_ip),
+				 NIPQUAD(mr->range[count].max_ip));
+			return false;
 		}
 		if (!(mr->range[count].flags & IP_NAT_RANGE_MAP_IPS)) {
-			DEBUGP("same_check: bad MAP_IPS.\n");
-			return 0;
+			pr_debug("same_check: bad MAP_IPS.\n");
+			return false;
 		}
 		rangeip = (ntohl(mr->range[count].max_ip) -
 					ntohl(mr->range[count].min_ip) + 1);
 		mr->ipnum += rangeip;
 
-		DEBUGP("same_check: range %u, ipnum = %u\n", count, rangeip);
+		pr_debug("same_check: range %u, ipnum = %u\n", count, rangeip);
 	}
-	DEBUGP("same_check: total ipaddresses = %u\n", mr->ipnum);
+	pr_debug("same_check: total ipaddresses = %u\n", mr->ipnum);
 
 	mr->iparray = kmalloc((sizeof(u_int32_t) * mr->ipnum), GFP_KERNEL);
 	if (!mr->iparray) {
-		DEBUGP("same_check: Couldn't allocate %u bytes "
-			"for %u ipaddresses!\n",
-			(sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
-		return 0;
+		pr_debug("same_check: Couldn't allocate %Zu bytes "
+			 "for %u ipaddresses!\n",
+			 (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
+		return false;
 	}
-	DEBUGP("same_check: Allocated %u bytes for %u ipaddresses.\n",
-			(sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
+	pr_debug("same_check: Allocated %Zu bytes for %u ipaddresses.\n",
+		 (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
 
 	for (count = 0; count < mr->rangesize; count++) {
 		for (countess = ntohl(mr->range[count].min_ip);
 				countess <= ntohl(mr->range[count].max_ip);
 					countess++) {
 			mr->iparray[index] = countess;
-			DEBUGP("same_check: Added ipaddress `%u.%u.%u.%u' "
-				"in index %u.\n",
-				HIPQUAD(countess), index);
+			pr_debug("same_check: Added ipaddress `%u.%u.%u.%u' "
+				 "in index %u.\n", HIPQUAD(countess), index);
 			index++;
 		}
 	}
-	return 1;
+	return true;
 }
 
 static void
@@ -107,8 +99,8 @@
 
 	kfree(mr->iparray);
 
-	DEBUGP("same_destroy: Deallocated %u bytes for %u ipaddresses.\n",
-			(sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
+	pr_debug("same_destroy: Deallocated %Zu bytes for %u ipaddresses.\n",
+		 (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
 }
 
 static unsigned int
@@ -146,10 +138,9 @@
 
 	new_ip = htonl(same->iparray[aindex]);
 
-	DEBUGP("ipt_SAME: src=%u.%u.%u.%u dst=%u.%u.%u.%u, "
-			"new src=%u.%u.%u.%u\n",
-			NIPQUAD(t->src.ip), NIPQUAD(t->dst.ip),
-			NIPQUAD(new_ip));
+	pr_debug("ipt_SAME: src=%u.%u.%u.%u dst=%u.%u.%u.%u, "
+		 "new src=%u.%u.%u.%u\n",
+		 NIPQUAD(t->src.u3.ip), NIPQUAD(t->dst.u3.ip), NIPQUAD(new_ip));
 
 	/* Transfer from original range. */
 	newrange = ((struct nf_nat_range)
@@ -161,7 +152,7 @@
 	return nf_nat_setup_info(ct, &newrange, hooknum);
 }
 
-static struct xt_target same_reg = {
+static struct xt_target same_reg __read_mostly = {
 	.name		= "SAME",
 	.family		= AF_INET,
 	.target		= same_target,
diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c
index 0ad02f2..25f5d0b 100644
--- a/net/ipv4/netfilter/ipt_TOS.c
+++ b/net/ipv4/netfilter/ipt_TOS.c
@@ -43,7 +43,7 @@
 	return XT_CONTINUE;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *e_void,
 	   const struct xt_target *target,
@@ -58,12 +58,12 @@
 	    && tos != IPTOS_MINCOST
 	    && tos != IPTOS_NORMALSVC) {
 		printk(KERN_WARNING "TOS: bad tos value %#x\n", tos);
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_target ipt_tos_reg = {
+static struct xt_target ipt_tos_reg __read_mostly = {
 	.name		= "TOS",
 	.family		= AF_INET,
 	.target		= target,
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c
index a991ec7..2b54e7b 100644
--- a/net/ipv4/netfilter/ipt_TTL.c
+++ b/net/ipv4/netfilter/ipt_TTL.c
@@ -62,25 +62,25 @@
 	return XT_CONTINUE;
 }
 
-static int ipt_ttl_checkentry(const char *tablename,
+static bool ipt_ttl_checkentry(const char *tablename,
 		const void *e,
 		const struct xt_target *target,
 		void *targinfo,
 		unsigned int hook_mask)
 {
-	struct ipt_TTL_info *info = targinfo;
+	const struct ipt_TTL_info *info = targinfo;
 
 	if (info->mode > IPT_TTL_MAXMODE) {
 		printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n",
 			info->mode);
-		return 0;
+		return false;
 	}
-	if ((info->mode != IPT_TTL_SET) && (info->ttl == 0))
-		return 0;
-	return 1;
+	if (info->mode != IPT_TTL_SET && info->ttl == 0)
+		return false;
+	return true;
 }
 
-static struct xt_target ipt_TTL = {
+static struct xt_target ipt_TTL __read_mostly = {
 	.name 		= "TTL",
 	.family		= AF_INET,
 	.target 	= ipt_ttl_target,
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 23b607b..6ca43e4 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -55,13 +55,6 @@
 #define ULOG_NL_EVENT		111		/* Harald's favorite number */
 #define ULOG_MAXNLGROUPS	32		/* numer of nlgroups */
 
-#if 0
-#define DEBUGP(format, args...) printk("%s:%s:" format, \
-				       __FILE__, __FUNCTION__ , ## args)
-#else
-#define DEBUGP(format, args...)
-#endif
-
 #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0)
 
 static unsigned int nlbufsiz = NLMSG_GOODSIZE;
@@ -96,12 +89,12 @@
 	ulog_buff_t *ub = &ulog_buffers[nlgroupnum];
 
 	if (timer_pending(&ub->timer)) {
-		DEBUGP("ipt_ULOG: ulog_send: timer was pending, deleting\n");
+		pr_debug("ipt_ULOG: ulog_send: timer was pending, deleting\n");
 		del_timer(&ub->timer);
 	}
 
 	if (!ub->skb) {
-		DEBUGP("ipt_ULOG: ulog_send: nothing to send\n");
+		pr_debug("ipt_ULOG: ulog_send: nothing to send\n");
 		return;
 	}
 
@@ -110,8 +103,8 @@
 		ub->lastnlh->nlmsg_type = NLMSG_DONE;
 
 	NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1;
-	DEBUGP("ipt_ULOG: throwing %d packets to netlink group %u\n",
-		ub->qlen, nlgroupnum + 1);
+	pr_debug("ipt_ULOG: throwing %d packets to netlink group %u\n",
+		 ub->qlen, nlgroupnum + 1);
 	netlink_broadcast(nflognl, ub->skb, 0, nlgroupnum + 1, GFP_ATOMIC);
 
 	ub->qlen = 0;
@@ -123,7 +116,7 @@
 /* timer function to flush queue in flushtimeout time */
 static void ulog_timer(unsigned long data)
 {
-	DEBUGP("ipt_ULOG: timer function called, calling ulog_send\n");
+	pr_debug("ipt_ULOG: timer function called, calling ulog_send\n");
 
 	/* lock to protect against somebody modifying our structure
 	 * from ipt_ulog_target at the same time */
@@ -179,12 +172,10 @@
 	unsigned int groupnum = ffs(loginfo->nl_group) - 1;
 
 	/* calculate the size of the skb needed */
-	if ((loginfo->copy_range == 0) ||
-	    (loginfo->copy_range > skb->len)) {
+	if (loginfo->copy_range == 0 || loginfo->copy_range > skb->len)
 		copy_len = skb->len;
-	} else {
+	else
 		copy_len = loginfo->copy_range;
-	}
 
 	size = NLMSG_SPACE(sizeof(*pm) + copy_len);
 
@@ -206,8 +197,8 @@
 			goto alloc_failure;
 	}
 
-	DEBUGP("ipt_ULOG: qlen %d, qthreshold %d\n", ub->qlen,
-		loginfo->qthreshold);
+	pr_debug("ipt_ULOG: qlen %d, qthreshold %Zu\n", ub->qlen,
+		 loginfo->qthreshold);
 
 	/* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */
 	nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT,
@@ -257,9 +248,8 @@
 		BUG();
 
 	/* check if we are building multi-part messages */
-	if (ub->qlen > 1) {
+	if (ub->qlen > 1)
 		ub->lastnlh->nlmsg_flags |= NLM_F_MULTI;
-	}
 
 	ub->lastnlh = nlh;
 
@@ -328,25 +318,25 @@
 	ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
 }
 
-static int ipt_ulog_checkentry(const char *tablename,
-			       const void *e,
-			       const struct xt_target *target,
-			       void *targinfo,
-			       unsigned int hookmask)
+static bool ipt_ulog_checkentry(const char *tablename,
+				const void *e,
+				const struct xt_target *target,
+				void *targinfo,
+				unsigned int hookmask)
 {
-	struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
+	const struct ipt_ulog_info *loginfo = targinfo;
 
 	if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
-		DEBUGP("ipt_ULOG: prefix term %i\n",
-		       loginfo->prefix[sizeof(loginfo->prefix) - 1]);
-		return 0;
+		pr_debug("ipt_ULOG: prefix term %i\n",
+			 loginfo->prefix[sizeof(loginfo->prefix) - 1]);
+		return false;
 	}
 	if (loginfo->qthreshold > ULOG_MAX_QLEN) {
-		DEBUGP("ipt_ULOG: queue threshold %i > MAX_QLEN\n",
-			loginfo->qthreshold);
-		return 0;
+		pr_debug("ipt_ULOG: queue threshold %Zu > MAX_QLEN\n",
+			 loginfo->qthreshold);
+		return false;
 	}
-	return 1;
+	return true;
 }
 
 #ifdef CONFIG_COMPAT
@@ -359,7 +349,7 @@
 
 static void compat_from_user(void *dst, void *src)
 {
-	struct compat_ipt_ulog_info *cl = src;
+	const struct compat_ipt_ulog_info *cl = src;
 	struct ipt_ulog_info l = {
 		.nl_group	= cl->nl_group,
 		.copy_range	= cl->copy_range,
@@ -372,7 +362,7 @@
 
 static int compat_to_user(void __user *dst, void *src)
 {
-	struct ipt_ulog_info *l = src;
+	const struct ipt_ulog_info *l = src;
 	struct compat_ipt_ulog_info cl = {
 		.nl_group	= l->nl_group,
 		.copy_range	= l->copy_range,
@@ -384,7 +374,7 @@
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_target ipt_ulog_reg = {
+static struct xt_target ipt_ulog_reg __read_mostly = {
 	.name		= "ULOG",
 	.family		= AF_INET,
 	.target		= ipt_ulog_target,
@@ -408,7 +398,7 @@
 {
 	int ret, i;
 
-	DEBUGP("ipt_ULOG: init module\n");
+	pr_debug("ipt_ULOG: init module\n");
 
 	if (nlbufsiz > 128*1024) {
 		printk("Netlink buffer has to be <= 128kB\n");
@@ -440,7 +430,7 @@
 	ulog_buff_t *ub;
 	int i;
 
-	DEBUGP("ipt_ULOG: cleanup_module\n");
+	pr_debug("ipt_ULOG: cleanup_module\n");
 
 	if (nflog)
 		nf_log_unregister(&ipt_ulog_logger);
@@ -451,7 +441,7 @@
 	for (i = 0; i < ULOG_MAXNLGROUPS; i++) {
 		ub = &ulog_buffers[i];
 		if (timer_pending(&ub->timer)) {
-			DEBUGP("timer was pending, deleting\n");
+			pr_debug("timer was pending, deleting\n");
 			del_timer(&ub->timer);
 		}
 
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
index a652a14..59f01f7 100644
--- a/net/ipv4/netfilter/ipt_addrtype.c
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -22,19 +22,19 @@
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 MODULE_DESCRIPTION("iptables addrtype match");
 
-static inline int match_type(__be32 addr, u_int16_t mask)
+static inline bool match_type(__be32 addr, u_int16_t mask)
 {
 	return !!(mask & (1 << inet_addr_type(addr)));
 }
 
-static int match(const struct sk_buff *skb,
-		 const struct net_device *in, const struct net_device *out,
-		 const struct xt_match *match, const void *matchinfo,
-		 int offset, unsigned int protoff, int *hotdrop)
+static bool match(const struct sk_buff *skb,
+		  const struct net_device *in, const struct net_device *out,
+		  const struct xt_match *match, const void *matchinfo,
+		  int offset, unsigned int protoff, bool *hotdrop)
 {
 	const struct ipt_addrtype_info *info = matchinfo;
 	const struct iphdr *iph = ip_hdr(skb);
-	int ret = 1;
+	bool ret = true;
 
 	if (info->source)
 		ret &= match_type(iph->saddr, info->source)^info->invert_source;
@@ -44,7 +44,7 @@
 	return ret;
 }
 
-static struct xt_match addrtype_match = {
+static struct xt_match addrtype_match __read_mostly = {
 	.name		= "addrtype",
 	.family		= AF_INET,
 	.match		= match,
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c
index 18a1678..61b017f 100644
--- a/net/ipv4/netfilter/ipt_ah.c
+++ b/net/ipv4/netfilter/ipt_ah.c
@@ -25,10 +25,10 @@
 #endif
 
 /* Returns 1 if the spi is matched by the range, 0 otherwise */
-static inline int
-spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
+static inline bool
+spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 {
-	int r=0;
+	bool r;
 	duprintf("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
 		min,spi,max);
 	r=(spi >= min && spi <= max) ^ invert;
@@ -36,7 +36,7 @@
 	return r;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -44,14 +44,15 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
-	struct ip_auth_hdr _ahdr, *ah;
+	struct ip_auth_hdr _ahdr;
+	const struct ip_auth_hdr *ah;
 	const struct ipt_ah *ahinfo = matchinfo;
 
 	/* Must not be a fragment. */
 	if (offset)
-		return 0;
+		return false;
 
 	ah = skb_header_pointer(skb, protoff,
 				sizeof(_ahdr), &_ahdr);
@@ -60,7 +61,7 @@
 		 * can't.  Hence, no choice but to drop.
 		 */
 		duprintf("Dropping evil AH tinygram.\n");
-		*hotdrop = 1;
+		*hotdrop = true;
 		return 0;
 	}
 
@@ -70,7 +71,7 @@
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *ip_void,
 	   const struct xt_match *match,
@@ -82,12 +83,12 @@
 	/* Must specify no unknown invflags */
 	if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
 		duprintf("ipt_ah: unknown flags %X\n", ahinfo->invflags);
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_match ah_match = {
+static struct xt_match ah_match __read_mostly = {
 	.name		= "ah",
 	.family		= AF_INET,
 	.match		= match,
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c
index 2621812..d6925c6 100644
--- a/net/ipv4/netfilter/ipt_ecn.c
+++ b/net/ipv4/netfilter/ipt_ecn.c
@@ -22,95 +22,96 @@
 MODULE_DESCRIPTION("iptables ECN matching module");
 MODULE_LICENSE("GPL");
 
-static inline int match_ip(const struct sk_buff *skb,
-			   const struct ipt_ecn_info *einfo)
+static inline bool match_ip(const struct sk_buff *skb,
+			    const struct ipt_ecn_info *einfo)
 {
 	return (ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect;
 }
 
-static inline int match_tcp(const struct sk_buff *skb,
-			    const struct ipt_ecn_info *einfo,
-			    int *hotdrop)
+static inline bool match_tcp(const struct sk_buff *skb,
+			     const struct ipt_ecn_info *einfo,
+			     bool *hotdrop)
 {
-	struct tcphdr _tcph, *th;
+	struct tcphdr _tcph;
+	const struct tcphdr *th;
 
 	/* In practice, TCP match does this, so can't fail.  But let's
 	 * be good citizens.
 	 */
 	th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph);
 	if (th == NULL) {
-		*hotdrop = 0;
-		return 0;
+		*hotdrop = false;
+		return false;
 	}
 
 	if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
 		if (einfo->invert & IPT_ECN_OP_MATCH_ECE) {
 			if (th->ece == 1)
-				return 0;
+				return false;
 		} else {
 			if (th->ece == 0)
-				return 0;
+				return false;
 		}
 	}
 
 	if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
 		if (einfo->invert & IPT_ECN_OP_MATCH_CWR) {
 			if (th->cwr == 1)
-				return 0;
+				return false;
 		} else {
 			if (th->cwr == 0)
-				return 0;
+				return false;
 		}
 	}
 
-	return 1;
+	return true;
 }
 
-static int match(const struct sk_buff *skb,
-		 const struct net_device *in, const struct net_device *out,
-		 const struct xt_match *match, const void *matchinfo,
-		 int offset, unsigned int protoff, int *hotdrop)
+static bool match(const struct sk_buff *skb,
+		  const struct net_device *in, const struct net_device *out,
+		  const struct xt_match *match, const void *matchinfo,
+		  int offset, unsigned int protoff, bool *hotdrop)
 {
 	const struct ipt_ecn_info *info = matchinfo;
 
 	if (info->operation & IPT_ECN_OP_MATCH_IP)
 		if (!match_ip(skb, info))
-			return 0;
+			return false;
 
 	if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
 		if (ip_hdr(skb)->protocol != IPPROTO_TCP)
-			return 0;
+			return false;
 		if (!match_tcp(skb, info, hotdrop))
-			return 0;
+			return false;
 	}
 
-	return 1;
+	return true;
 }
 
-static int checkentry(const char *tablename, const void *ip_void,
-		      const struct xt_match *match,
-		      void *matchinfo, unsigned int hook_mask)
+static bool checkentry(const char *tablename, const void *ip_void,
+		       const struct xt_match *match,
+		       void *matchinfo, unsigned int hook_mask)
 {
 	const struct ipt_ecn_info *info = matchinfo;
 	const struct ipt_ip *ip = ip_void;
 
 	if (info->operation & IPT_ECN_OP_MATCH_MASK)
-		return 0;
+		return false;
 
 	if (info->invert & IPT_ECN_OP_MATCH_MASK)
-		return 0;
+		return false;
 
 	if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)
 	    && ip->proto != IPPROTO_TCP) {
 		printk(KERN_WARNING "ipt_ecn: can't match TCP bits in rule for"
 		       " non-tcp packets\n");
-		return 0;
+		return false;
 	}
 
-	return 1;
+	return true;
 }
 
-static struct xt_match ecn_match = {
+static struct xt_match ecn_match __read_mostly = {
 	.name		= "ecn",
 	.family		= AF_INET,
 	.match		= match,
diff --git a/net/ipv4/netfilter/ipt_iprange.c b/net/ipv4/netfilter/ipt_iprange.c
index 33af9e9..0106dc9 100644
--- a/net/ipv4/netfilter/ipt_iprange.c
+++ b/net/ipv4/netfilter/ipt_iprange.c
@@ -17,53 +17,47 @@
 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
 MODULE_DESCRIPTION("iptables arbitrary IP range match module");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const struct xt_match *match,
       const void *matchinfo,
-      int offset, unsigned int protoff, int *hotdrop)
+      int offset, unsigned int protoff, bool *hotdrop)
 {
 	const struct ipt_iprange_info *info = matchinfo;
 	const struct iphdr *iph = ip_hdr(skb);
 
 	if (info->flags & IPRANGE_SRC) {
-		if (((ntohl(iph->saddr) < ntohl(info->src.min_ip))
-			  || (ntohl(iph->saddr) > ntohl(info->src.max_ip)))
+		if ((ntohl(iph->saddr) < ntohl(info->src.min_ip)
+			  || ntohl(iph->saddr) > ntohl(info->src.max_ip))
 			 ^ !!(info->flags & IPRANGE_SRC_INV)) {
-			DEBUGP("src IP %u.%u.%u.%u NOT in range %s"
-			       "%u.%u.%u.%u-%u.%u.%u.%u\n",
-				NIPQUAD(iph->saddr),
-				info->flags & IPRANGE_SRC_INV ? "(INV) " : "",
-				NIPQUAD(info->src.min_ip),
-				NIPQUAD(info->src.max_ip));
-			return 0;
+			pr_debug("src IP %u.%u.%u.%u NOT in range %s"
+				 "%u.%u.%u.%u-%u.%u.%u.%u\n",
+				 NIPQUAD(iph->saddr),
+				 info->flags & IPRANGE_SRC_INV ? "(INV) " : "",
+				 NIPQUAD(info->src.min_ip),
+				 NIPQUAD(info->src.max_ip));
+			return false;
 		}
 	}
 	if (info->flags & IPRANGE_DST) {
-		if (((ntohl(iph->daddr) < ntohl(info->dst.min_ip))
-			  || (ntohl(iph->daddr) > ntohl(info->dst.max_ip)))
+		if ((ntohl(iph->daddr) < ntohl(info->dst.min_ip)
+			  || ntohl(iph->daddr) > ntohl(info->dst.max_ip))
 			 ^ !!(info->flags & IPRANGE_DST_INV)) {
-			DEBUGP("dst IP %u.%u.%u.%u NOT in range %s"
-			       "%u.%u.%u.%u-%u.%u.%u.%u\n",
-				NIPQUAD(iph->daddr),
-				info->flags & IPRANGE_DST_INV ? "(INV) " : "",
-				NIPQUAD(info->dst.min_ip),
-				NIPQUAD(info->dst.max_ip));
-			return 0;
+			pr_debug("dst IP %u.%u.%u.%u NOT in range %s"
+				 "%u.%u.%u.%u-%u.%u.%u.%u\n",
+				 NIPQUAD(iph->daddr),
+				 info->flags & IPRANGE_DST_INV ? "(INV) " : "",
+				 NIPQUAD(info->dst.min_ip),
+				 NIPQUAD(info->dst.max_ip));
+			return false;
 		}
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_match iprange_match = {
+static struct xt_match iprange_match __read_mostly = {
 	.name		= "iprange",
 	.family		= AF_INET,
 	.match		= match,
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c
index 7fae9aa..b14e77d 100644
--- a/net/ipv4/netfilter/ipt_owner.c
+++ b/net/ipv4/netfilter/ipt_owner.c
@@ -21,7 +21,7 @@
 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
 MODULE_DESCRIPTION("iptables owner match");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -29,29 +29,29 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct ipt_owner_info *info = matchinfo;
 
 	if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
-		return 0;
+		return false;
 
 	if(info->match & IPT_OWNER_UID) {
 		if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
 		    !!(info->invert & IPT_OWNER_UID))
-			return 0;
+			return false;
 	}
 
 	if(info->match & IPT_OWNER_GID) {
 		if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
 		    !!(info->invert & IPT_OWNER_GID))
-			return 0;
+			return false;
 	}
 
-	return 1;
+	return true;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *ip,
 	   const struct xt_match *match,
@@ -63,12 +63,12 @@
 	if (info->match & (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) {
 		printk("ipt_owner: pid, sid and command matching "
 		       "not supported anymore\n");
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_match owner_match = {
+static struct xt_match owner_match __read_mostly = {
 	.name		= "owner",
 	.family		= AF_INET,
 	.match		= match,
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 15a9e8b..3218043 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -163,24 +163,23 @@
 	struct recent_entry *e, *next;
 	unsigned int i;
 
-	for (i = 0; i < ip_list_hash_size; i++) {
+	for (i = 0; i < ip_list_hash_size; i++)
 		list_for_each_entry_safe(e, next, &t->iphash[i], list)
 			recent_entry_remove(t, e);
-	}
 }
 
-static int
+static bool
 ipt_recent_match(const struct sk_buff *skb,
 		 const struct net_device *in, const struct net_device *out,
 		 const struct xt_match *match, const void *matchinfo,
-		 int offset, unsigned int protoff, int *hotdrop)
+		 int offset, unsigned int protoff, bool *hotdrop)
 {
 	const struct ipt_recent_info *info = matchinfo;
 	struct recent_table *t;
 	struct recent_entry *e;
 	__be32 addr;
 	u_int8_t ttl;
-	int ret = info->invert;
+	bool ret = info->invert;
 
 	if (info->side == IPT_RECENT_DEST)
 		addr = ip_hdr(skb)->daddr;
@@ -201,16 +200,16 @@
 			goto out;
 		e = recent_entry_init(t, addr, ttl);
 		if (e == NULL)
-			*hotdrop = 1;
-		ret ^= 1;
+			*hotdrop = true;
+		ret = !ret;
 		goto out;
 	}
 
 	if (info->check_set & IPT_RECENT_SET)
-		ret ^= 1;
+		ret = !ret;
 	else if (info->check_set & IPT_RECENT_REMOVE) {
 		recent_entry_remove(t, e);
-		ret ^= 1;
+		ret = !ret;
 	} else if (info->check_set & (IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) {
 		unsigned long t = jiffies - info->seconds * HZ;
 		unsigned int i, hits = 0;
@@ -219,7 +218,7 @@
 			if (info->seconds && time_after(t, e->stamps[i]))
 				continue;
 			if (++hits >= info->hit_count) {
-				ret ^= 1;
+				ret = !ret;
 				break;
 			}
 		}
@@ -235,7 +234,7 @@
 	return ret;
 }
 
-static int
+static bool
 ipt_recent_checkentry(const char *tablename, const void *ip,
 		      const struct xt_match *match, void *matchinfo,
 		      unsigned int hook_mask)
@@ -243,24 +242,24 @@
 	const struct ipt_recent_info *info = matchinfo;
 	struct recent_table *t;
 	unsigned i;
-	int ret = 0;
+	bool ret = false;
 
 	if (hweight8(info->check_set &
 		     (IPT_RECENT_SET | IPT_RECENT_REMOVE |
 		      IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) != 1)
-		return 0;
+		return false;
 	if ((info->check_set & (IPT_RECENT_SET | IPT_RECENT_REMOVE)) &&
 	    (info->seconds || info->hit_count))
-		return 0;
+		return false;
 	if (info->name[0] == '\0' ||
 	    strnlen(info->name, IPT_RECENT_NAME_LEN) == IPT_RECENT_NAME_LEN)
-		return 0;
+		return false;
 
 	mutex_lock(&recent_mutex);
 	t = recent_table_lookup(info->name);
 	if (t != NULL) {
 		t->refcnt++;
-		ret = 1;
+		ret = true;
 		goto out;
 	}
 
@@ -287,7 +286,7 @@
 	spin_lock_bh(&recent_lock);
 	list_add_tail(&t->list, &tables);
 	spin_unlock_bh(&recent_lock);
-	ret = 1;
+	ret = true;
 out:
 	mutex_unlock(&recent_mutex);
 	return ret;
@@ -323,18 +322,16 @@
 static void *recent_seq_start(struct seq_file *seq, loff_t *pos)
 {
 	struct recent_iter_state *st = seq->private;
-	struct recent_table *t = st->table;
+	const struct recent_table *t = st->table;
 	struct recent_entry *e;
 	loff_t p = *pos;
 
 	spin_lock_bh(&recent_lock);
 
-	for (st->bucket = 0; st->bucket < ip_list_hash_size; st->bucket++) {
-		list_for_each_entry(e, &t->iphash[st->bucket], list) {
+	for (st->bucket = 0; st->bucket < ip_list_hash_size; st->bucket++)
+		list_for_each_entry(e, &t->iphash[st->bucket], list)
 			if (p-- == 0)
 				return e;
-		}
-	}
 	return NULL;
 }
 
@@ -373,7 +370,7 @@
 	return 0;
 }
 
-static struct seq_operations recent_seq_ops = {
+static const struct seq_operations recent_seq_ops = {
 	.start		= recent_seq_start,
 	.next		= recent_seq_next,
 	.stop		= recent_seq_stop,
@@ -463,7 +460,7 @@
 };
 #endif /* CONFIG_PROC_FS */
 
-static struct xt_match recent_match = {
+static struct xt_match recent_match __read_mostly = {
 	.name		= "recent",
 	.family		= AF_INET,
 	.match		= ipt_recent_match,
diff --git a/net/ipv4/netfilter/ipt_tos.c b/net/ipv4/netfilter/ipt_tos.c
index d314844..e740441 100644
--- a/net/ipv4/netfilter/ipt_tos.c
+++ b/net/ipv4/netfilter/ipt_tos.c
@@ -18,7 +18,7 @@
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("iptables TOS match module");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -26,14 +26,14 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct ipt_tos_info *info = matchinfo;
 
 	return (ip_hdr(skb)->tos == info->tos) ^ info->invert;
 }
 
-static struct xt_match tos_match = {
+static struct xt_match tos_match __read_mostly = {
 	.name		= "tos",
 	.family		= AF_INET,
 	.match		= match,
diff --git a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c
index ab02d9e..a439900 100644
--- a/net/ipv4/netfilter/ipt_ttl.c
+++ b/net/ipv4/netfilter/ipt_ttl.c
@@ -18,37 +18,33 @@
 MODULE_DESCRIPTION("IP tables TTL matching module");
 MODULE_LICENSE("GPL");
 
-static int match(const struct sk_buff *skb,
-		 const struct net_device *in, const struct net_device *out,
-		 const struct xt_match *match, const void *matchinfo,
-		 int offset, unsigned int protoff, int *hotdrop)
+static bool match(const struct sk_buff *skb,
+		  const struct net_device *in, const struct net_device *out,
+		  const struct xt_match *match, const void *matchinfo,
+		  int offset, unsigned int protoff, bool *hotdrop)
 {
 	const struct ipt_ttl_info *info = matchinfo;
 	const u8 ttl = ip_hdr(skb)->ttl;
 
 	switch (info->mode) {
 		case IPT_TTL_EQ:
-			return (ttl == info->ttl);
-			break;
+			return ttl == info->ttl;
 		case IPT_TTL_NE:
-			return (!(ttl == info->ttl));
-			break;
+			return ttl != info->ttl;
 		case IPT_TTL_LT:
-			return (ttl < info->ttl);
-			break;
+			return ttl < info->ttl;
 		case IPT_TTL_GT:
-			return (ttl > info->ttl);
-			break;
+			return ttl > info->ttl;
 		default:
 			printk(KERN_WARNING "ipt_ttl: unknown mode %d\n",
 				info->mode);
-			return 0;
+			return false;
 	}
 
-	return 0;
+	return false;
 }
 
-static struct xt_match ttl_match = {
+static struct xt_match ttl_match __read_mostly = {
 	.name		= "ttl",
 	.family		= AF_INET,
 	.match		= match,
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 6dc72a8..3c56299 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -24,12 +24,6 @@
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
 			     struct nf_conntrack_tuple *tuple)
 {
@@ -103,17 +97,6 @@
 	return NF_ACCEPT;
 }
 
-int nf_nat_module_is_loaded = 0;
-EXPORT_SYMBOL_GPL(nf_nat_module_is_loaded);
-
-static u_int32_t ipv4_get_features(const struct nf_conntrack_tuple *tuple)
-{
-	if (nf_nat_module_is_loaded)
-		return NF_CT_F_NAT;
-
-	return NF_CT_F_BASIC;
-}
-
 static unsigned int ipv4_confirm(unsigned int hooknum,
 				 struct sk_buff **pskb,
 				 const struct net_device *in,
@@ -335,17 +318,17 @@
 
 	/* We only do TCP at the moment: is there a better way? */
 	if (strcmp(sk->sk_prot->name, "TCP")) {
-		DEBUGP("SO_ORIGINAL_DST: Not a TCP socket\n");
+		pr_debug("SO_ORIGINAL_DST: Not a TCP socket\n");
 		return -ENOPROTOOPT;
 	}
 
 	if ((unsigned int) *len < sizeof(struct sockaddr_in)) {
-		DEBUGP("SO_ORIGINAL_DST: len %u not %u\n",
-		       *len, sizeof(struct sockaddr_in));
+		pr_debug("SO_ORIGINAL_DST: len %d not %Zu\n",
+			 *len, sizeof(struct sockaddr_in));
 		return -EINVAL;
 	}
 
-	h = nf_conntrack_find_get(&tuple, NULL);
+	h = nf_conntrack_find_get(&tuple);
 	if (h) {
 		struct sockaddr_in sin;
 		struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
@@ -357,17 +340,17 @@
 			.tuple.dst.u3.ip;
 		memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
 
-		DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
-		       NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
+		pr_debug("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
+			 NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
 		nf_ct_put(ct);
 		if (copy_to_user(user, &sin, sizeof(sin)) != 0)
 			return -EFAULT;
 		else
 			return 0;
 	}
-	DEBUGP("SO_ORIGINAL_DST: Can't find %u.%u.%u.%u/%u-%u.%u.%u.%u/%u.\n",
-	       NIPQUAD(tuple.src.u3.ip), ntohs(tuple.src.u.tcp.port),
-	       NIPQUAD(tuple.dst.u3.ip), ntohs(tuple.dst.u.tcp.port));
+	pr_debug("SO_ORIGINAL_DST: Can't find %u.%u.%u.%u/%u-%u.%u.%u.%u/%u.\n",
+		 NIPQUAD(tuple.src.u3.ip), ntohs(tuple.src.u.tcp.port),
+		 NIPQUAD(tuple.dst.u3.ip), ntohs(tuple.dst.u.tcp.port));
 	return -ENOENT;
 }
 
@@ -425,7 +408,6 @@
 	.print_tuple	 = ipv4_print_tuple,
 	.print_conntrack = ipv4_print_conntrack,
 	.prepare	 = ipv4_prepare,
-	.get_features	 = ipv4_get_features,
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
 	.tuple_to_nfattr = ipv4_tuple_to_nfattr,
 	.nfattr_to_tuple = ipv4_nfattr_to_tuple,
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index 89f933e..3da9d73 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -18,12 +18,6 @@
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_expect.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 #ifdef CONFIG_NF_CT_ACCT
 static unsigned int
 seq_print_counters(struct seq_file *s,
@@ -41,35 +35,36 @@
 	unsigned int bucket;
 };
 
-static struct list_head *ct_get_first(struct seq_file *seq)
+static struct hlist_node *ct_get_first(struct seq_file *seq)
 {
 	struct ct_iter_state *st = seq->private;
 
 	for (st->bucket = 0;
 	     st->bucket < nf_conntrack_htable_size;
 	     st->bucket++) {
-		if (!list_empty(&nf_conntrack_hash[st->bucket]))
-			return nf_conntrack_hash[st->bucket].next;
+		if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
+			return nf_conntrack_hash[st->bucket].first;
 	}
 	return NULL;
 }
 
-static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head)
+static struct hlist_node *ct_get_next(struct seq_file *seq,
+				      struct hlist_node *head)
 {
 	struct ct_iter_state *st = seq->private;
 
 	head = head->next;
-	while (head == &nf_conntrack_hash[st->bucket]) {
+	while (head == NULL) {
 		if (++st->bucket >= nf_conntrack_htable_size)
 			return NULL;
-		head = nf_conntrack_hash[st->bucket].next;
+		head = nf_conntrack_hash[st->bucket].first;
 	}
 	return head;
 }
 
-static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos)
+static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
 {
-	struct list_head *head = ct_get_first(seq);
+	struct hlist_node *head = ct_get_first(seq);
 
 	if (head)
 		while (pos && (head = ct_get_next(seq, head)))
@@ -169,7 +164,7 @@
 	return 0;
 }
 
-static struct seq_operations ct_seq_ops = {
+static const struct seq_operations ct_seq_ops = {
 	.start = ct_seq_start,
 	.next  = ct_seq_next,
 	.stop  = ct_seq_stop,
@@ -206,47 +201,68 @@
 };
 
 /* expects */
-static void *exp_seq_start(struct seq_file *s, loff_t *pos)
+struct ct_expect_iter_state {
+	unsigned int bucket;
+};
+
+static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
 {
-	struct list_head *e = &nf_conntrack_expect_list;
-	loff_t i;
+	struct ct_expect_iter_state *st = seq->private;
 
-	/* strange seq_file api calls stop even if we fail,
-	 * thus we need to grab lock since stop unlocks */
-	read_lock_bh(&nf_conntrack_lock);
-
-	if (list_empty(e))
-		return NULL;
-
-	for (i = 0; i <= *pos; i++) {
-		e = e->next;
-		if (e == &nf_conntrack_expect_list)
-			return NULL;
+	for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
+		if (!hlist_empty(&nf_ct_expect_hash[st->bucket]))
+			return nf_ct_expect_hash[st->bucket].first;
 	}
-	return e;
+	return NULL;
 }
 
-static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
+static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
+					     struct hlist_node *head)
 {
-	struct list_head *e = v;
+	struct ct_expect_iter_state *st = seq->private;
 
-	++*pos;
-	e = e->next;
-
-	if (e == &nf_conntrack_expect_list)
-		return NULL;
-
-	return e;
+	head = head->next;
+	while (head == NULL) {
+		if (++st->bucket >= nf_ct_expect_hsize)
+			return NULL;
+		head = nf_ct_expect_hash[st->bucket].first;
+	}
+	return head;
 }
 
-static void exp_seq_stop(struct seq_file *s, void *v)
+static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
+{
+	struct hlist_node *head = ct_expect_get_first(seq);
+
+	if (head)
+		while (pos && (head = ct_expect_get_next(seq, head)))
+			pos--;
+	return pos ? NULL : head;
+}
+
+static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	read_lock_bh(&nf_conntrack_lock);
+	return ct_expect_get_idx(seq, *pos);
+}
+
+static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	(*pos)++;
+	return ct_expect_get_next(seq, v);
+}
+
+static void exp_seq_stop(struct seq_file *seq, void *v)
 {
 	read_unlock_bh(&nf_conntrack_lock);
 }
 
 static int exp_seq_show(struct seq_file *s, void *v)
 {
-	struct nf_conntrack_expect *exp = v;
+	struct nf_conntrack_expect *exp;
+	struct hlist_node *n = v;
+
+	exp = hlist_entry(n, struct nf_conntrack_expect, hnode);
 
 	if (exp->tuple.src.l3num != AF_INET)
 		return 0;
@@ -266,7 +282,7 @@
 	return seq_putc(s, '\n');
 }
 
-static struct seq_operations exp_seq_ops = {
+static const struct seq_operations exp_seq_ops = {
 	.start = exp_seq_start,
 	.next = exp_seq_next,
 	.stop = exp_seq_stop,
@@ -275,7 +291,23 @@
 
 static int exp_open(struct inode *inode, struct file *file)
 {
-	return seq_open(file, &exp_seq_ops);
+	struct seq_file *seq;
+	struct ct_expect_iter_state *st;
+	int ret;
+
+	st = kmalloc(sizeof(struct ct_expect_iter_state), GFP_KERNEL);
+	if (st == NULL)
+		return -ENOMEM;
+	ret = seq_open(file, &exp_seq_ops);
+	if (ret)
+		goto out_free;
+	seq          = file->private_data;
+	seq->private = st;
+	memset(st, 0, sizeof(struct ct_expect_iter_state));
+	return ret;
+out_free:
+	kfree(st);
+	return ret;
 }
 
 static const struct file_operations ip_exp_file_ops = {
@@ -283,7 +315,7 @@
 	.open    = exp_open,
 	.read    = seq_read,
 	.llseek  = seq_lseek,
-	.release = seq_release
+	.release = seq_release_private,
 };
 
 static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
@@ -354,7 +386,7 @@
 	return 0;
 }
 
-static struct seq_operations ct_cpu_seq_ops = {
+static const struct seq_operations ct_cpu_seq_ops = {
 	.start  = ct_cpu_seq_start,
 	.next   = ct_cpu_seq_next,
 	.stop   = ct_cpu_seq_stop,
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index f4fc657..0fe8fb0 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -21,12 +21,6 @@
 
 static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ;
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static int icmp_pkt_to_tuple(const struct sk_buff *skb,
 			     unsigned int dataoff,
 			     struct nf_conntrack_tuple *tuple)
@@ -125,8 +119,8 @@
 	if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
 	    || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
 		/* Can't create a new ICMP `conn' with this. */
-		DEBUGP("icmp: can't create new conn with type %u\n",
-		       conntrack->tuplehash[0].tuple.dst.u.icmp.type);
+		pr_debug("icmp: can't create new conn with type %u\n",
+			 conntrack->tuplehash[0].tuple.dst.u.icmp.type);
 		NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
 		return 0;
 	}
@@ -159,8 +153,8 @@
 
 	/* Ignore ICMP's containing fragments (shouldn't happen) */
 	if (inside->ip.frag_off & htons(IP_OFFSET)) {
-		DEBUGP("icmp_error_message: fragment of proto %u\n",
-		       inside->ip.protocol);
+		pr_debug("icmp_error_message: fragment of proto %u\n",
+			 inside->ip.protocol);
 		return -NF_ACCEPT;
 	}
 
@@ -172,8 +166,8 @@
 	if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET,
 			     inside->ip.protocol, &origtuple,
 			     &nf_conntrack_l3proto_ipv4, innerproto)) {
-		DEBUGP("icmp_error_message: ! get_tuple p=%u",
-		       inside->ip.protocol);
+		pr_debug("icmp_error_message: ! get_tuple p=%u",
+			 inside->ip.protocol);
 		return -NF_ACCEPT;
 	}
 
@@ -181,22 +175,22 @@
 	   been preserved inside the ICMP. */
 	if (!nf_ct_invert_tuple(&innertuple, &origtuple,
 				&nf_conntrack_l3proto_ipv4, innerproto)) {
-		DEBUGP("icmp_error_message: no match\n");
+		pr_debug("icmp_error_message: no match\n");
 		return -NF_ACCEPT;
 	}
 
 	*ctinfo = IP_CT_RELATED;
 
-	h = nf_conntrack_find_get(&innertuple, NULL);
+	h = nf_conntrack_find_get(&innertuple);
 	if (!h) {
 		/* Locally generated ICMPs will match inverted if they
 		   haven't been SNAT'ed yet */
 		/* FIXME: NAT code has to handle half-done double NAT --RR */
 		if (hooknum == NF_IP_LOCAL_OUT)
-			h = nf_conntrack_find_get(&origtuple, NULL);
+			h = nf_conntrack_find_get(&origtuple);
 
 		if (!h) {
-			DEBUGP("icmp_error_message: no match\n");
+			pr_debug("icmp_error_message: no match\n");
 			return -NF_ACCEPT;
 		}
 
diff --git a/net/ipv4/netfilter/nf_nat_amanda.c b/net/ipv4/netfilter/nf_nat_amanda.c
index 0f17098..bd93a1d 100644
--- a/net/ipv4/netfilter/nf_nat_amanda.c
+++ b/net/ipv4/netfilter/nf_nat_amanda.c
@@ -45,7 +45,7 @@
 	/* Try to get same port: if not, try to change it. */
 	for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
 		exp->tuple.dst.u.tcp.port = htons(port);
-		if (nf_conntrack_expect_related(exp) == 0)
+		if (nf_ct_expect_related(exp) == 0)
 			break;
 	}
 
@@ -57,7 +57,7 @@
 				       matchoff, matchlen,
 				       buffer, strlen(buffer));
 	if (ret != NF_ACCEPT)
-		nf_conntrack_unexpect_related(exp);
+		nf_ct_unexpect_related(exp);
 	return ret;
 }
 
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index ea02f00..e848d8d 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -12,7 +12,6 @@
 #include <linux/types.h>
 #include <linux/timer.h>
 #include <linux/skbuff.h>
-#include <linux/vmalloc.h>
 #include <net/checksum.h>
 #include <net/icmp.h>
 #include <net/ip.h>
@@ -32,20 +31,15 @@
 #include <net/netfilter/nf_conntrack_l3proto.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static DEFINE_RWLOCK(nf_nat_lock);
 
 static struct nf_conntrack_l3proto *l3proto = NULL;
 
 /* Calculated at init based on memory size */
 static unsigned int nf_nat_htable_size;
+static int nf_nat_vmalloced;
 
-static struct list_head *bysource;
+static struct hlist_head *bysource;
 
 #define MAX_IP_NAT_PROTO 256
 static struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO];
@@ -87,19 +81,6 @@
 			    tuple->dst.protonum, 0) % nf_nat_htable_size;
 }
 
-/* Noone using conntrack by the time this called. */
-static void nf_nat_cleanup_conntrack(struct nf_conn *conn)
-{
-	struct nf_conn_nat *nat;
-	if (!(conn->status & IPS_NAT_DONE_MASK))
-		return;
-
-	nat = nfct_nat(conn);
-	write_lock_bh(&nf_nat_lock);
-	list_del(&nat->info.bysource);
-	write_unlock_bh(&nf_nat_lock);
-}
-
 /* Is this tuple already taken? (not by us) */
 int
 nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple,
@@ -166,10 +147,11 @@
 	unsigned int h = hash_by_src(tuple);
 	struct nf_conn_nat *nat;
 	struct nf_conn *ct;
+	struct hlist_node *n;
 
 	read_lock_bh(&nf_nat_lock);
-	list_for_each_entry(nat, &bysource[h], info.bysource) {
-		ct = (struct nf_conn *)((char *)nat - offsetof(struct nf_conn, data));
+	hlist_for_each_entry(nat, n, &bysource[h], bysource) {
+		ct = nat->ct;
 		if (same_src(ct, tuple)) {
 			/* Copy source part from reply tuple. */
 			nf_ct_invert_tuplepr(result,
@@ -254,7 +236,7 @@
 	   manips not an issue.  */
 	if (maniptype == IP_NAT_MANIP_SRC) {
 		if (find_appropriate_src(orig_tuple, tuple, range)) {
-			DEBUGP("get_unique_tuple: Found current src map\n");
+			pr_debug("get_unique_tuple: Found current src map\n");
 			if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
 				if (!nf_nat_used_tuple(tuple, ct))
 					return;
@@ -296,11 +278,20 @@
 		  unsigned int hooknum)
 {
 	struct nf_conntrack_tuple curr_tuple, new_tuple;
-	struct nf_conn_nat *nat = nfct_nat(ct);
-	struct nf_nat_info *info = &nat->info;
+	struct nf_conn_nat *nat;
 	int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK);
 	enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum);
 
+	/* nat helper or nfctnetlink also setup binding */
+	nat = nfct_nat(ct);
+	if (!nat) {
+		nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
+		if (nat == NULL) {
+			pr_debug("failed to add NAT extension\n");
+			return NF_ACCEPT;
+		}
+	}
+
 	NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
 		     hooknum == NF_IP_POST_ROUTING ||
 		     hooknum == NF_IP_LOCAL_IN ||
@@ -337,7 +328,10 @@
 
 		srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
 		write_lock_bh(&nf_nat_lock);
-		list_add(&info->bysource, &bysource[srchash]);
+		/* nf_conntrack_alter_reply might re-allocate exntension aera */
+		nat = nfct_nat(ct);
+		nat->ct = ct;
+		hlist_add_head(&nat->bysource, &bysource[srchash]);
 		write_unlock_bh(&nf_nat_lock);
 	}
 
@@ -462,8 +456,9 @@
 			return 0;
 	}
 
-	DEBUGP("icmp_reply_translation: translating error %p manp %u dir %s\n",
-	       *pskb, manip, dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
+	pr_debug("icmp_reply_translation: translating error %p manip %u "
+		 "dir %s\n", *pskb, manip,
+		 dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
 
 	/* rcu_read_lock()ed by nf_hook_slow */
 	l4proto = __nf_ct_l4proto_find(PF_INET, inside->ip.protocol);
@@ -590,17 +585,69 @@
 EXPORT_SYMBOL_GPL(nf_nat_port_range_to_nfattr);
 #endif
 
+/* Noone using conntrack by the time this called. */
+static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
+{
+	struct nf_conn_nat *nat = nf_ct_ext_find(ct, NF_CT_EXT_NAT);
+
+	if (nat == NULL || nat->ct == NULL)
+		return;
+
+	NF_CT_ASSERT(nat->ct->status & IPS_NAT_DONE_MASK);
+
+	write_lock_bh(&nf_nat_lock);
+	hlist_del(&nat->bysource);
+	nat->ct = NULL;
+	write_unlock_bh(&nf_nat_lock);
+}
+
+static void nf_nat_move_storage(struct nf_conn *conntrack, void *old)
+{
+	struct nf_conn_nat *new_nat = nf_ct_ext_find(conntrack, NF_CT_EXT_NAT);
+	struct nf_conn_nat *old_nat = (struct nf_conn_nat *)old;
+	struct nf_conn *ct = old_nat->ct;
+	unsigned int srchash;
+
+	if (!(ct->status & IPS_NAT_DONE_MASK))
+		return;
+
+	srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+
+	write_lock_bh(&nf_nat_lock);
+	hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource);
+	new_nat->ct = ct;
+	write_unlock_bh(&nf_nat_lock);
+}
+
+static struct nf_ct_ext_type nat_extend __read_mostly = {
+	.len		= sizeof(struct nf_conn_nat),
+	.align		= __alignof__(struct nf_conn_nat),
+	.destroy	= nf_nat_cleanup_conntrack,
+	.move		= nf_nat_move_storage,
+	.id		= NF_CT_EXT_NAT,
+	.flags		= NF_CT_EXT_F_PREALLOC,
+};
+
 static int __init nf_nat_init(void)
 {
 	size_t i;
+	int ret;
+
+	ret = nf_ct_extend_register(&nat_extend);
+	if (ret < 0) {
+		printk(KERN_ERR "nf_nat_core: Unable to register extension\n");
+		return ret;
+	}
 
 	/* Leave them the same for the moment. */
 	nf_nat_htable_size = nf_conntrack_htable_size;
 
-	/* One vmalloc for both hash tables */
-	bysource = vmalloc(sizeof(struct list_head) * nf_nat_htable_size);
-	if (!bysource)
-		return -ENOMEM;
+	bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
+					 &nf_nat_vmalloced);
+	if (!bysource) {
+		ret = -ENOMEM;
+		goto cleanup_extend;
+	}
 
 	/* Sew in builtin protocols. */
 	write_lock_bh(&nf_nat_lock);
@@ -612,18 +659,18 @@
 	write_unlock_bh(&nf_nat_lock);
 
 	for (i = 0; i < nf_nat_htable_size; i++) {
-		INIT_LIST_HEAD(&bysource[i]);
+		INIT_HLIST_HEAD(&bysource[i]);
 	}
 
-	/* FIXME: Man, this is a hack.  <SIGH> */
-	NF_CT_ASSERT(rcu_dereference(nf_conntrack_destroyed) == NULL);
-	rcu_assign_pointer(nf_conntrack_destroyed, nf_nat_cleanup_conntrack);
-
 	/* Initialize fake conntrack so that NAT will skip it */
 	nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
 
 	l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET);
 	return 0;
+
+ cleanup_extend:
+	nf_ct_extend_unregister(&nat_extend);
+	return ret;
 }
 
 /* Clear NAT section of all conntracks, in case we're loaded again. */
@@ -641,10 +688,10 @@
 static void __exit nf_nat_cleanup(void)
 {
 	nf_ct_iterate_cleanup(&clean_nat, NULL);
-	rcu_assign_pointer(nf_conntrack_destroyed, NULL);
 	synchronize_rcu();
-	vfree(bysource);
+	nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size);
 	nf_ct_l3proto_put(l3proto);
+	nf_ct_extend_unregister(&nat_extend);
 }
 
 MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/nf_nat_ftp.c b/net/ipv4/netfilter/nf_nat_ftp.c
index e6bc8e5..3663bd8 100644
--- a/net/ipv4/netfilter/nf_nat_ftp.c
+++ b/net/ipv4/netfilter/nf_nat_ftp.c
@@ -25,12 +25,6 @@
 MODULE_DESCRIPTION("ftp NAT helper");
 MODULE_ALIAS("ip_nat_ftp");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* FIXME: Time out? --RR */
 
 static int
@@ -47,7 +41,7 @@
 	sprintf(buffer, "%u,%u,%u,%u,%u,%u",
 		NIPQUAD(newip), port>>8, port&0xFF);
 
-	DEBUGP("calling nf_nat_mangle_tcp_packet\n");
+	pr_debug("calling nf_nat_mangle_tcp_packet\n");
 
 	return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
 					matchlen, buffer, strlen(buffer));
@@ -67,7 +61,7 @@
 
 	sprintf(buffer, "|1|%u.%u.%u.%u|%u|", NIPQUAD(newip), port);
 
-	DEBUGP("calling nf_nat_mangle_tcp_packet\n");
+	pr_debug("calling nf_nat_mangle_tcp_packet\n");
 
 	return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
 					matchlen, buffer, strlen(buffer));
@@ -87,7 +81,7 @@
 
 	sprintf(buffer, "|||%u|", port);
 
-	DEBUGP("calling nf_nat_mangle_tcp_packet\n");
+	pr_debug("calling nf_nat_mangle_tcp_packet\n");
 
 	return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
 					matchlen, buffer, strlen(buffer));
@@ -117,7 +111,7 @@
 	int dir = CTINFO2DIR(ctinfo);
 	struct nf_conn *ct = exp->master;
 
-	DEBUGP("FTP_NAT: type %i, off %u len %u\n", type, matchoff, matchlen);
+	pr_debug("FTP_NAT: type %i, off %u len %u\n", type, matchoff, matchlen);
 
 	/* Connection will come from wherever this packet goes, hence !dir */
 	newip = ct->tuplehash[!dir].tuple.dst.u3.ip;
@@ -131,7 +125,7 @@
 	/* Try to get same port: if not, try to change it. */
 	for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
 		exp->tuple.dst.u.tcp.port = htons(port);
-		if (nf_conntrack_expect_related(exp) == 0)
+		if (nf_ct_expect_related(exp) == 0)
 			break;
 	}
 
@@ -139,7 +133,7 @@
 		return NF_DROP;
 
 	if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo)) {
-		nf_conntrack_unexpect_related(exp);
+		nf_ct_unexpect_related(exp);
 		return NF_DROP;
 	}
 	return NF_ACCEPT;
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
index c5d2a2d..c1b059a 100644
--- a/net/ipv4/netfilter/nf_nat_h323.c
+++ b/net/ipv4/netfilter/nf_nat_h323.c
@@ -21,12 +21,6 @@
 #include <net/netfilter/nf_conntrack_expect.h>
 #include <linux/netfilter/nf_conntrack_h323.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /****************************************************************************/
 static int set_addr(struct sk_buff **pskb,
 		    unsigned char **data, int dataoff,
@@ -126,12 +120,11 @@
 				    (ntohl(addr.ip) & 0xff000000) == 0x7f000000)
 					i = 0;
 
-				DEBUGP
-				    ("nf_nat_ras: set signal address "
-				     "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-				     NIPQUAD(ip), port,
-				     NIPQUAD(ct->tuplehash[!dir].tuple.dst.
-					     ip), info->sig_port[!dir]);
+				pr_debug("nf_nat_ras: set signal address "
+					 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+					 NIPQUAD(addr.ip), port,
+					 NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
+					 info->sig_port[!dir]);
 				return set_h225_addr(pskb, data, 0, &taddr[i],
 						     &ct->tuplehash[!dir].
 						     tuple.dst.u3,
@@ -139,12 +132,11 @@
 			} else if (addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
 				   port == info->sig_port[dir]) {
 				/* GK->GW */
-				DEBUGP
-				    ("nf_nat_ras: set signal address "
-				     "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-				     NIPQUAD(ip), port,
-				     NIPQUAD(ct->tuplehash[!dir].tuple.src.
-					     ip), info->sig_port[!dir]);
+				pr_debug("nf_nat_ras: set signal address "
+					 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+					 NIPQUAD(addr.ip), port,
+					 NIPQUAD(ct->tuplehash[!dir].tuple.src.u3.ip),
+					 info->sig_port[!dir]);
 				return set_h225_addr(pskb, data, 0, &taddr[i],
 						     &ct->tuplehash[!dir].
 						     tuple.src.u3,
@@ -171,12 +163,11 @@
 		if (get_h225_addr(ct, *data, &taddr[i], &addr, &port) &&
 		    addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
 		    port == ct->tuplehash[dir].tuple.src.u.udp.port) {
-			DEBUGP("nf_nat_ras: set rasAddress "
-			       "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-			       NIPQUAD(ip), ntohs(port),
-			       NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
-			       ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.
-				     port));
+			pr_debug("nf_nat_ras: set rasAddress "
+				 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+				 NIPQUAD(addr.ip), ntohs(port),
+				 NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
+				 ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port));
 			return set_h225_addr(pskb, data, 0, &taddr[i],
 					     &ct->tuplehash[!dir].tuple.dst.u3,
 					     ct->tuplehash[!dir].tuple.
@@ -237,12 +228,12 @@
 	for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port);
 	     nated_port != 0; nated_port += 2) {
 		rtp_exp->tuple.dst.u.udp.port = htons(nated_port);
-		if (nf_conntrack_expect_related(rtp_exp) == 0) {
+		if (nf_ct_expect_related(rtp_exp) == 0) {
 			rtcp_exp->tuple.dst.u.udp.port =
 			    htons(nated_port + 1);
-			if (nf_conntrack_expect_related(rtcp_exp) == 0)
+			if (nf_ct_expect_related(rtcp_exp) == 0)
 				break;
-			nf_conntrack_unexpect_related(rtp_exp);
+			nf_ct_unexpect_related(rtp_exp);
 		}
 	}
 
@@ -261,22 +252,22 @@
 		info->rtp_port[i][dir] = rtp_port;
 		info->rtp_port[i][!dir] = htons(nated_port);
 	} else {
-		nf_conntrack_unexpect_related(rtp_exp);
-		nf_conntrack_unexpect_related(rtcp_exp);
+		nf_ct_unexpect_related(rtp_exp);
+		nf_ct_unexpect_related(rtcp_exp);
 		return -1;
 	}
 
 	/* Success */
-	DEBUGP("nf_nat_h323: expect RTP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-	       NIPQUAD(rtp_exp->tuple.src.ip),
-	       ntohs(rtp_exp->tuple.src.u.udp.port),
-	       NIPQUAD(rtp_exp->tuple.dst.ip),
-	       ntohs(rtp_exp->tuple.dst.u.udp.port));
-	DEBUGP("nf_nat_h323: expect RTCP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-	       NIPQUAD(rtcp_exp->tuple.src.ip),
-	       ntohs(rtcp_exp->tuple.src.u.udp.port),
-	       NIPQUAD(rtcp_exp->tuple.dst.ip),
-	       ntohs(rtcp_exp->tuple.dst.u.udp.port));
+	pr_debug("nf_nat_h323: expect RTP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+		 NIPQUAD(rtp_exp->tuple.src.u3.ip),
+		 ntohs(rtp_exp->tuple.src.u.udp.port),
+		 NIPQUAD(rtp_exp->tuple.dst.u3.ip),
+		 ntohs(rtp_exp->tuple.dst.u.udp.port));
+	pr_debug("nf_nat_h323: expect RTCP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+		 NIPQUAD(rtcp_exp->tuple.src.u3.ip),
+		 ntohs(rtcp_exp->tuple.src.u.udp.port),
+		 NIPQUAD(rtcp_exp->tuple.dst.u3.ip),
+		 ntohs(rtcp_exp->tuple.dst.u.udp.port));
 
 	return 0;
 }
@@ -299,7 +290,7 @@
 	/* Try to get same port: if not, try to change it. */
 	for (; nated_port != 0; nated_port++) {
 		exp->tuple.dst.u.tcp.port = htons(nated_port);
-		if (nf_conntrack_expect_related(exp) == 0)
+		if (nf_ct_expect_related(exp) == 0)
 			break;
 	}
 
@@ -313,13 +304,15 @@
 	if (set_h245_addr(pskb, data, dataoff, taddr,
 			  &ct->tuplehash[!dir].tuple.dst.u3,
 			  htons(nated_port)) < 0) {
-		nf_conntrack_unexpect_related(exp);
+		nf_ct_unexpect_related(exp);
 		return -1;
 	}
 
-	DEBUGP("nf_nat_h323: expect T.120 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-	       NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
-	       NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
+	pr_debug("nf_nat_h323: expect T.120 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+		 NIPQUAD(exp->tuple.src.u3.ip),
+		 ntohs(exp->tuple.src.u.tcp.port),
+		 NIPQUAD(exp->tuple.dst.u3.ip),
+		 ntohs(exp->tuple.dst.u.tcp.port));
 
 	return 0;
 }
@@ -347,7 +340,7 @@
 	/* Try to get same port: if not, try to change it. */
 	for (; nated_port != 0; nated_port++) {
 		exp->tuple.dst.u.tcp.port = htons(nated_port);
-		if (nf_conntrack_expect_related(exp) == 0)
+		if (nf_ct_expect_related(exp) == 0)
 			break;
 	}
 
@@ -365,13 +358,15 @@
 		info->sig_port[dir] = port;
 		info->sig_port[!dir] = htons(nated_port);
 	} else {
-		nf_conntrack_unexpect_related(exp);
+		nf_ct_unexpect_related(exp);
 		return -1;
 	}
 
-	DEBUGP("nf_nat_q931: expect H.245 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-	       NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
-	       NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
+	pr_debug("nf_nat_q931: expect H.245 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+		 NIPQUAD(exp->tuple.src.u3.ip),
+		 ntohs(exp->tuple.src.u.tcp.port),
+		 NIPQUAD(exp->tuple.dst.u3.ip),
+		 ntohs(exp->tuple.dst.u.tcp.port));
 
 	return 0;
 }
@@ -433,7 +428,7 @@
 	/* Try to get same port: if not, try to change it. */
 	for (; nated_port != 0; nated_port++) {
 		exp->tuple.dst.u.tcp.port = htons(nated_port);
-		if (nf_conntrack_expect_related(exp) == 0)
+		if (nf_ct_expect_related(exp) == 0)
 			break;
 	}
 
@@ -460,14 +455,16 @@
 				      info->sig_port[!dir]);
 		}
 	} else {
-		nf_conntrack_unexpect_related(exp);
+		nf_ct_unexpect_related(exp);
 		return -1;
 	}
 
 	/* Success */
-	DEBUGP("nf_nat_ras: expect Q.931 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-	       NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
-	       NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
+	pr_debug("nf_nat_ras: expect Q.931 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+		 NIPQUAD(exp->tuple.src.u3.ip),
+		 ntohs(exp->tuple.src.u.tcp.port),
+		 NIPQUAD(exp->tuple.dst.u3.ip),
+		 ntohs(exp->tuple.dst.u.tcp.port));
 
 	return 0;
 }
@@ -517,7 +514,7 @@
 	/* Try to get same port: if not, try to change it. */
 	for (nated_port = ntohs(port); nated_port != 0; nated_port++) {
 		exp->tuple.dst.u.tcp.port = htons(nated_port);
-		if (nf_conntrack_expect_related(exp) == 0)
+		if (nf_ct_expect_related(exp) == 0)
 			break;
 	}
 
@@ -531,15 +528,17 @@
 	if (!set_h225_addr(pskb, data, dataoff, taddr,
 			   &ct->tuplehash[!dir].tuple.dst.u3,
 			   htons(nated_port)) == 0) {
-		nf_conntrack_unexpect_related(exp);
+		nf_ct_unexpect_related(exp);
 		return -1;
 	}
 
 	/* Success */
-	DEBUGP("nf_nat_q931: expect Call Forwarding "
-	       "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-	       NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
-	       NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
+	pr_debug("nf_nat_q931: expect Call Forwarding "
+		 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
+		 NIPQUAD(exp->tuple.src.u3.ip),
+		 ntohs(exp->tuple.src.u.tcp.port),
+		 NIPQUAD(exp->tuple.dst.u3.ip),
+		 ntohs(exp->tuple.dst.u.tcp.port));
 
 	return 0;
 }
@@ -566,8 +565,6 @@
 	rcu_assign_pointer(nat_h245_hook, nat_h245);
 	rcu_assign_pointer(nat_callforwarding_hook, nat_callforwarding);
 	rcu_assign_pointer(nat_q931_hook, nat_q931);
-
-	DEBUGP("nf_nat_h323: init success\n");
 	return 0;
 }
 
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 15b6e5c..93d8a0a 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -26,13 +26,9 @@
 #include <net/netfilter/nf_nat_core.h>
 #include <net/netfilter/nf_nat_helper.h>
 
-#if 0
-#define DEBUGP printk
-#define DUMP_OFFSET(x)	printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos);
-#else
-#define DEBUGP(format, args...)
-#define DUMP_OFFSET(x)
-#endif
+#define DUMP_OFFSET(x) \
+	pr_debug("offset_before=%d, offset_after=%d, correction_pos=%u\n", \
+		 x->offset_before, x->offset_after, x->correction_pos);
 
 static DEFINE_SPINLOCK(nf_nat_seqofs_lock);
 
@@ -47,15 +43,15 @@
 	struct nf_nat_seq *this_way, *other_way;
 	struct nf_conn_nat *nat = nfct_nat(ct);
 
-	DEBUGP("nf_nat_resize_packet: old_size = %u, new_size = %u\n",
-		(*skb)->len, new_size);
+	pr_debug("adjust_tcp_sequence: seq = %u, sizediff = %d\n",
+		 ntohl(seq), seq);
 
 	dir = CTINFO2DIR(ctinfo);
 
-	this_way = &nat->info.seq[dir];
-	other_way = &nat->info.seq[!dir];
+	this_way = &nat->seq[dir];
+	other_way = &nat->seq[!dir];
 
-	DEBUGP("nf_nat_resize_packet: Seq_offset before: ");
+	pr_debug("nf_nat_resize_packet: Seq_offset before: ");
 	DUMP_OFFSET(this_way);
 
 	spin_lock_bh(&nf_nat_seqofs_lock);
@@ -72,7 +68,7 @@
 	}
 	spin_unlock_bh(&nf_nat_seqofs_lock);
 
-	DEBUGP("nf_nat_resize_packet: Seq_offset after: ");
+	pr_debug("nf_nat_resize_packet: Seq_offset after: ");
 	DUMP_OFFSET(this_way);
 }
 
@@ -100,14 +96,12 @@
 
 	/* update skb info */
 	if (rep_len > match_len) {
-		DEBUGP("nf_nat_mangle_packet: Extending packet by "
-		       "%u from %u bytes\n", rep_len - match_len,
-		       skb->len);
+		pr_debug("nf_nat_mangle_packet: Extending packet by "
+			 "%u from %u bytes\n", rep_len - match_len, skb->len);
 		skb_put(skb, rep_len - match_len);
 	} else {
-		DEBUGP("nf_nat_mangle_packet: Shrinking packet from "
-		       "%u from %u bytes\n", match_len - rep_len,
-		       skb->len);
+		pr_debug("nf_nat_mangle_packet: Shrinking packet from "
+			 "%u from %u bytes\n", match_len - rep_len, skb->len);
 		__skb_trim(skb, skb->len + rep_len - match_len);
 	}
 
@@ -178,7 +172,7 @@
 	datalen = (*pskb)->len - iph->ihl*4;
 	if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
 		if (!(rt->rt_flags & RTCF_LOCAL) &&
-		    (*pskb)->dev->features & NETIF_F_ALL_CSUM) {
+		    (*pskb)->dev->features & NETIF_F_V4_CSUM) {
 			(*pskb)->ip_summed = CHECKSUM_PARTIAL;
 			(*pskb)->csum_start = skb_headroom(*pskb) +
 					      skb_network_offset(*pskb) +
@@ -190,7 +184,7 @@
 			tcph->check = 0;
 			tcph->check = tcp_v4_check(datalen,
 						   iph->saddr, iph->daddr,
-						   csum_partial((char *)tcph,
+						   csum_partial(tcph,
 								datalen, 0));
 		}
 	} else
@@ -265,7 +259,7 @@
 
 	if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
 		if (!(rt->rt_flags & RTCF_LOCAL) &&
-		    (*pskb)->dev->features & NETIF_F_ALL_CSUM) {
+		    (*pskb)->dev->features & NETIF_F_V4_CSUM) {
 			(*pskb)->ip_summed = CHECKSUM_PARTIAL;
 			(*pskb)->csum_start = skb_headroom(*pskb) +
 					      skb_network_offset(*pskb) +
@@ -278,7 +272,7 @@
 			udph->check = 0;
 			udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
 							datalen, IPPROTO_UDP,
-							csum_partial((char *)udph,
+							csum_partial(udph,
 								     datalen, 0));
 			if (!udph->check)
 				udph->check = CSUM_MANGLED_0;
@@ -320,9 +314,9 @@
 			new_end_seq = htonl(ntohl(sack->end_seq)
 				      - natseq->offset_before);
 
-		DEBUGP("sack_adjust: start_seq: %d->%d, end_seq: %d->%d\n",
-			ntohl(sack->start_seq), new_start_seq,
-			ntohl(sack->end_seq), new_end_seq);
+		pr_debug("sack_adjust: start_seq: %d->%d, end_seq: %d->%d\n",
+			 ntohl(sack->start_seq), new_start_seq,
+			 ntohl(sack->end_seq), new_end_seq);
 
 		nf_proto_csum_replace4(&tcph->check, skb,
 				       sack->start_seq, new_start_seq, 0);
@@ -372,8 +366,7 @@
 			    op[1] >= 2+TCPOLEN_SACK_PERBLOCK &&
 			    ((op[1] - 2) % TCPOLEN_SACK_PERBLOCK) == 0)
 				sack_adjust(*pskb, tcph, optoff+2,
-					    optoff+op[1],
-					    &nat->info.seq[!dir]);
+					    optoff+op[1], &nat->seq[!dir]);
 			optoff += op[1];
 		}
 	}
@@ -394,8 +387,8 @@
 
 	dir = CTINFO2DIR(ctinfo);
 
-	this_way = &nat->info.seq[dir];
-	other_way = &nat->info.seq[!dir];
+	this_way = &nat->seq[dir];
+	other_way = &nat->seq[!dir];
 
 	if (!skb_make_writable(pskb, ip_hdrlen(*pskb) + sizeof(*tcph)))
 		return 0;
@@ -415,9 +408,9 @@
 	nf_proto_csum_replace4(&tcph->check, *pskb, tcph->seq, newseq, 0);
 	nf_proto_csum_replace4(&tcph->check, *pskb, tcph->ack_seq, newack, 0);
 
-	DEBUGP("Adjusting sequence number from %u->%u, ack from %u->%u\n",
-		ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
-		ntohl(newack));
+	pr_debug("Adjusting sequence number from %u->%u, ack from %u->%u\n",
+		 ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
+		 ntohl(newack));
 
 	tcph->seq = newseq;
 	tcph->ack_seq = newack;
diff --git a/net/ipv4/netfilter/nf_nat_irc.c b/net/ipv4/netfilter/nf_nat_irc.c
index 9b8c0da..bcf274b 100644
--- a/net/ipv4/netfilter/nf_nat_irc.c
+++ b/net/ipv4/netfilter/nf_nat_irc.c
@@ -22,12 +22,6 @@
 #include <net/netfilter/nf_conntrack_expect.h>
 #include <linux/netfilter/nf_conntrack_irc.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
 MODULE_DESCRIPTION("IRC (DCC) NAT helper");
 MODULE_LICENSE("GPL");
@@ -44,9 +38,6 @@
 	u_int16_t port;
 	unsigned int ret;
 
-	DEBUGP("IRC_NAT: info (seq %u + %u) in %u\n",
-	       expect->seq, exp_irc_info->len, ntohl(tcph->seq));
-
 	/* Reply comes from server. */
 	exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
 	exp->dir = IP_CT_DIR_REPLY;
@@ -55,7 +46,7 @@
 	/* Try to get same port: if not, try to change it. */
 	for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
 		exp->tuple.dst.u.tcp.port = htons(port);
-		if (nf_conntrack_expect_related(exp) == 0)
+		if (nf_ct_expect_related(exp) == 0)
 			break;
 	}
 
@@ -64,14 +55,14 @@
 
 	ip = ntohl(exp->master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip);
 	sprintf(buffer, "%u %u", ip, port);
-	DEBUGP("nf_nat_irc: inserting '%s' == %u.%u.%u.%u, port %u\n",
-	       buffer, NIPQUAD(ip), port);
+	pr_debug("nf_nat_irc: inserting '%s' == %u.%u.%u.%u, port %u\n",
+		 buffer, NIPQUAD(ip), port);
 
 	ret = nf_nat_mangle_tcp_packet(pskb, exp->master, ctinfo,
 				       matchoff, matchlen, buffer,
 				       strlen(buffer));
 	if (ret != NF_ACCEPT)
-		nf_conntrack_unexpect_related(exp);
+		nf_ct_unexpect_related(exp);
 	return ret;
 }
 
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c
index a668887..984ec83 100644
--- a/net/ipv4/netfilter/nf_nat_pptp.c
+++ b/net/ipv4/netfilter/nf_nat_pptp.c
@@ -37,14 +37,6 @@
 MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP");
 MODULE_ALIAS("ip_nat_pptp");
 
-#if 0
-extern const char *pptp_msg_name[];
-#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
-				       __FUNCTION__, ## args)
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static void pptp_nat_expected(struct nf_conn *ct,
 			      struct nf_conntrack_expect *exp)
 {
@@ -60,7 +52,7 @@
 
 	/* And here goes the grand finale of corrosion... */
 	if (exp->dir == IP_CT_DIR_ORIGINAL) {
-		DEBUGP("we are PNS->PAC\n");
+		pr_debug("we are PNS->PAC\n");
 		/* therefore, build tuple for PAC->PNS */
 		t.src.l3num = AF_INET;
 		t.src.u3.ip = master->tuplehash[!exp->dir].tuple.src.u3.ip;
@@ -69,7 +61,7 @@
 		t.dst.u.gre.key = ct_pptp_info->pns_call_id;
 		t.dst.protonum = IPPROTO_GRE;
 	} else {
-		DEBUGP("we are PAC->PNS\n");
+		pr_debug("we are PAC->PNS\n");
 		/* build tuple for PNS->PAC */
 		t.src.l3num = AF_INET;
 		t.src.u3.ip = master->tuplehash[!exp->dir].tuple.src.u3.ip;
@@ -79,15 +71,15 @@
 		t.dst.protonum = IPPROTO_GRE;
 	}
 
-	DEBUGP("trying to unexpect other dir: ");
+	pr_debug("trying to unexpect other dir: ");
 	NF_CT_DUMP_TUPLE(&t);
-	other_exp = nf_conntrack_expect_find_get(&t);
+	other_exp = nf_ct_expect_find_get(&t);
 	if (other_exp) {
-		nf_conntrack_unexpect_related(other_exp);
-		nf_conntrack_expect_put(other_exp);
-		DEBUGP("success\n");
+		nf_ct_unexpect_related(other_exp);
+		nf_ct_expect_put(other_exp);
+		pr_debug("success\n");
 	} else {
-		DEBUGP("not found!\n");
+		pr_debug("not found!\n");
 	}
 
 	/* This must be a fresh one. */
@@ -161,9 +153,9 @@
 		cid_off = offsetof(union pptp_ctrl_union, clrreq.callID);
 		break;
 	default:
-		DEBUGP("unknown outbound packet 0x%04x:%s\n", msg,
-		      (msg <= PPTP_MSG_MAX)?
-		      pptp_msg_name[msg]:pptp_msg_name[0]);
+		pr_debug("unknown outbound packet 0x%04x:%s\n", msg,
+			 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] :
+					       pptp_msg_name[0]);
 		/* fall through */
 	case PPTP_SET_LINK_INFO:
 		/* only need to NAT in case PAC is behind NAT box */
@@ -179,8 +171,8 @@
 
 	/* only OUT_CALL_REQUEST, IN_CALL_REPLY, CALL_CLEAR_REQUEST pass
 	 * down to here */
-	DEBUGP("altering call id from 0x%04x to 0x%04x\n",
-		ntohs(REQ_CID(pptpReq, cid_off)), ntohs(new_callid));
+	pr_debug("altering call id from 0x%04x to 0x%04x\n",
+		 ntohs(REQ_CID(pptpReq, cid_off)), ntohs(new_callid));
 
 	/* mangle packet */
 	if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
@@ -255,8 +247,9 @@
 		pcid_off = offsetof(union pptp_ctrl_union, setlink.peersCallID);
 		break;
 	default:
-		DEBUGP("unknown inbound packet %s\n", (msg <= PPTP_MSG_MAX)?
-			pptp_msg_name[msg]:pptp_msg_name[0]);
+		pr_debug("unknown inbound packet %s\n",
+			 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] :
+					       pptp_msg_name[0]);
 		/* fall through */
 	case PPTP_START_SESSION_REQUEST:
 	case PPTP_START_SESSION_REPLY:
@@ -272,8 +265,8 @@
 	 * WAN_ERROR_NOTIFY, CALL_DISCONNECT_NOTIFY pass down here */
 
 	/* mangle packet */
-	DEBUGP("altering peer call id from 0x%04x to 0x%04x\n",
-		ntohs(REQ_CID(pptpReq, pcid_off)), ntohs(new_pcid));
+	pr_debug("altering peer call id from 0x%04x to 0x%04x\n",
+		 ntohs(REQ_CID(pptpReq, pcid_off)), ntohs(new_pcid));
 
 	if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
 				     pcid_off + sizeof(struct pptp_pkt_hdr) +
diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c
index c3908bc..2e40cc8 100644
--- a/net/ipv4/netfilter/nf_nat_proto_gre.c
+++ b/net/ipv4/netfilter/nf_nat_proto_gre.c
@@ -36,13 +36,6 @@
 MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
 MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");
 
-#if 0
-#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
-				       __FUNCTION__, ## args)
-#else
-#define DEBUGP(x, args...)
-#endif
-
 /* is key in given range between min and max */
 static int
 gre_in_range(const struct nf_conntrack_tuple *tuple,
@@ -83,7 +76,7 @@
 		keyptr = &tuple->dst.u.gre.key;
 
 	if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
-		DEBUGP("%p: NATing GRE PPTP\n", conntrack);
+		pr_debug("%p: NATing GRE PPTP\n", conntrack);
 		min = 1;
 		range_size = 0xffff;
 	} else {
@@ -91,7 +84,7 @@
 		range_size = ntohs(range->max.gre.key) - min + 1;
 	}
 
-	DEBUGP("min = %u, range_size = %u\n", min, range_size);
+	pr_debug("min = %u, range_size = %u\n", min, range_size);
 
 	for (i = 0; i < range_size; i++, key++) {
 		*keyptr = htons(min + key % range_size);
@@ -99,7 +92,7 @@
 			return 1;
 	}
 
-	DEBUGP("%p: no NAT mapping\n", conntrack);
+	pr_debug("%p: no NAT mapping\n", conntrack);
 	return 0;
 }
 
@@ -132,11 +125,11 @@
 		 * Try to behave like "nf_nat_proto_unknown" */
 		break;
 	case GRE_VERSION_PPTP:
-		DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));
+		pr_debug("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));
 		pgreh->call_id = tuple->dst.u.gre.key;
 		break;
 	default:
-		DEBUGP("can't nat unknown GRE version\n");
+		pr_debug("can't nat unknown GRE version\n");
 		return 0;
 	}
 	return 1;
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index 6740736..0f45427 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -24,12 +24,6 @@
 #include <net/netfilter/nf_nat_core.h>
 #include <net/netfilter/nf_nat_rule.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 #define NAT_VALID_HOOKS ((1<<NF_IP_PRE_ROUTING) | (1<<NF_IP_POST_ROUTING) | (1<<NF_IP_LOCAL_OUT))
 
 static struct
@@ -140,39 +134,39 @@
 	return nf_nat_setup_info(ct, &mr->range[0], hooknum);
 }
 
-static int ipt_snat_checkentry(const char *tablename,
-			       const void *entry,
-			       const struct xt_target *target,
-			       void *targinfo,
-			       unsigned int hook_mask)
+static bool ipt_snat_checkentry(const char *tablename,
+				const void *entry,
+				const struct xt_target *target,
+				void *targinfo,
+				unsigned int hook_mask)
 {
 	struct nf_nat_multi_range_compat *mr = targinfo;
 
 	/* Must be a valid range */
 	if (mr->rangesize != 1) {
 		printk("SNAT: multiple ranges no longer supported\n");
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static int ipt_dnat_checkentry(const char *tablename,
-			       const void *entry,
-			       const struct xt_target *target,
-			       void *targinfo,
-			       unsigned int hook_mask)
+static bool ipt_dnat_checkentry(const char *tablename,
+				const void *entry,
+				const struct xt_target *target,
+				void *targinfo,
+				unsigned int hook_mask)
 {
 	struct nf_nat_multi_range_compat *mr = targinfo;
 
 	/* Must be a valid range */
 	if (mr->rangesize != 1) {
 		printk("DNAT: multiple ranges no longer supported\n");
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-inline unsigned int
+unsigned int
 alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
 {
 	/* Force range to this IP; let proto decide mapping for
@@ -186,8 +180,8 @@
 	struct nf_nat_range range
 		= { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } };
 
-	DEBUGP("Allocating NULL binding for %p (%u.%u.%u.%u)\n",
-	       ct, NIPQUAD(ip));
+	pr_debug("Allocating NULL binding for %p (%u.%u.%u.%u)\n",
+		 ct, NIPQUAD(ip));
 	return nf_nat_setup_info(ct, &range, hooknum);
 }
 
@@ -205,8 +199,8 @@
 	struct nf_nat_range range
 		= { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } };
 
-	DEBUGP("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
-	       ct, NIPQUAD(ip));
+	pr_debug("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
+		 ct, NIPQUAD(ip));
 	return nf_nat_setup_info(ct, &range, hooknum);
 }
 
@@ -228,7 +222,7 @@
 	return ret;
 }
 
-static struct xt_target ipt_snat_reg = {
+static struct xt_target ipt_snat_reg __read_mostly = {
 	.name		= "SNAT",
 	.target		= ipt_snat_target,
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
@@ -238,7 +232,7 @@
 	.family		= AF_INET,
 };
 
-static struct xt_target ipt_dnat_reg = {
+static struct xt_target ipt_dnat_reg __read_mostly = {
 	.name		= "DNAT",
 	.target		= ipt_dnat_target,
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index fac97cf..a889ec3 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -26,12 +26,6 @@
 MODULE_DESCRIPTION("SIP NAT helper");
 MODULE_ALIAS("ip_nat_sip");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 struct addr_map {
 	struct {
 		char		src[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
@@ -257,10 +251,12 @@
 	__be32 newip;
 	u_int16_t port;
 
-	DEBUGP("ip_nat_sdp():\n");
-
 	/* Connection will come from reply */
-	newip = ct->tuplehash[!dir].tuple.dst.u3.ip;
+	if (ct->tuplehash[dir].tuple.src.u3.ip ==
+	    ct->tuplehash[!dir].tuple.dst.u3.ip)
+		newip = exp->tuple.dst.u3.ip;
+	else
+		newip = ct->tuplehash[!dir].tuple.dst.u3.ip;
 
 	exp->saved_ip = exp->tuple.dst.u3.ip;
 	exp->tuple.dst.u3.ip = newip;
@@ -274,7 +270,7 @@
 	/* Try to get same port: if not, try to change it. */
 	for (port = ntohs(exp->saved_proto.udp.port); port != 0; port++) {
 		exp->tuple.dst.u.udp.port = htons(port);
-		if (nf_conntrack_expect_related(exp) == 0)
+		if (nf_ct_expect_related(exp) == 0)
 			break;
 	}
 
@@ -282,7 +278,7 @@
 		return NF_DROP;
 
 	if (!mangle_sdp(pskb, ctinfo, ct, newip, port, dptr)) {
-		nf_conntrack_unexpect_related(exp);
+		nf_ct_unexpect_related(exp);
 		return NF_DROP;
 	}
 	return NF_ACCEPT;
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index 6e88505..6bfcd3a 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -1276,9 +1276,6 @@
 	.tuple.src.l3num	= AF_INET,
 	.tuple.src.u.udp.port	= __constant_htons(SNMP_PORT),
 	.tuple.dst.protonum	= IPPROTO_UDP,
-	.mask.src.l3num		= 0xFFFF,
-	.mask.src.u.udp.port	= __constant_htons(0xFFFF),
-	.mask.dst.protonum	= 0xFF,
 };
 
 static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
@@ -1290,9 +1287,6 @@
 	.tuple.src.l3num	= AF_INET,
 	.tuple.src.u.udp.port	= __constant_htons(SNMP_TRAP_PORT),
 	.tuple.dst.protonum	= IPPROTO_UDP,
-	.mask.src.l3num		= 0xFFFF,
-	.mask.src.u.udp.port	= __constant_htons(0xFFFF),
-	.mask.dst.protonum	= 0xFF,
 };
 
 /*****************************************************************************
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 55dac36..332814d 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -19,6 +19,7 @@
 
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_extend.h>
 #include <net/netfilter/nf_nat.h>
 #include <net/netfilter/nf_nat_rule.h>
 #include <net/netfilter/nf_nat_protocol.h>
@@ -26,12 +27,6 @@
 #include <net/netfilter/nf_nat_helper.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 #ifdef CONFIG_XFRM
 static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
 {
@@ -113,8 +108,13 @@
 		return NF_ACCEPT;
 
 	nat = nfct_nat(ct);
-	if (!nat)
-		return NF_ACCEPT;
+	if (!nat) {
+		nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
+		if (nat == NULL) {
+			pr_debug("failed to add NAT extension\n");
+			return NF_ACCEPT;
+		}
+	}
 
 	switch (ctinfo) {
 	case IP_CT_RELATED:
@@ -148,9 +148,9 @@
 				return ret;
 			}
 		} else
-			DEBUGP("Already setup manip %s for ct %p\n",
-			       maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",
-			       ct);
+			pr_debug("Already setup manip %s for ct %p\n",
+				 maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",
+				 ct);
 		break;
 
 	default:
@@ -264,7 +264,7 @@
 
 	ct = nf_ct_get(*pskb, &ctinfo);
 	if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
-		DEBUGP("nf_nat_standalone: adjusting sequence number\n");
+		pr_debug("nf_nat_standalone: adjusting sequence number\n");
 		if (!nf_nat_seq_adjust(pskb, ct, ctinfo))
 			return NF_DROP;
 	}
@@ -326,26 +326,10 @@
 
 static int __init nf_nat_standalone_init(void)
 {
-	int size, ret = 0;
+	int ret = 0;
 
 	need_conntrack();
 
-	size = ALIGN(sizeof(struct nf_conn), __alignof__(struct nf_conn_nat)) +
-	       sizeof(struct nf_conn_nat);
-	ret = nf_conntrack_register_cache(NF_CT_F_NAT, "nf_nat:base", size);
-	if (ret < 0) {
-		printk(KERN_ERR "nf_nat_init: Unable to create slab cache\n");
-		return ret;
-	}
-
-	size = ALIGN(size, __alignof__(struct nf_conn_help)) +
-	       sizeof(struct nf_conn_help);
-	ret = nf_conntrack_register_cache(NF_CT_F_NAT|NF_CT_F_HELP,
-					  "nf_nat:help", size);
-	if (ret < 0) {
-		printk(KERN_ERR "nf_nat_init: Unable to create slab cache\n");
-		goto cleanup_register_cache;
-	}
 #ifdef CONFIG_XFRM
 	BUG_ON(ip_nat_decode_session != NULL);
 	ip_nat_decode_session = nat_decode_session;
@@ -360,7 +344,6 @@
 		printk("nf_nat_init: can't register hooks.\n");
 		goto cleanup_rule_init;
 	}
-	nf_nat_module_is_loaded = 1;
 	return ret;
 
  cleanup_rule_init:
@@ -370,9 +353,6 @@
 	ip_nat_decode_session = NULL;
 	synchronize_net();
 #endif
-	nf_conntrack_unregister_cache(NF_CT_F_NAT|NF_CT_F_HELP);
- cleanup_register_cache:
-	nf_conntrack_unregister_cache(NF_CT_F_NAT);
 	return ret;
 }
 
@@ -380,7 +360,6 @@
 {
 	nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
 	nf_nat_rule_cleanup();
-	nf_nat_module_is_loaded = 0;
 #ifdef CONFIG_XFRM
 	ip_nat_decode_session = NULL;
 	synchronize_net();
diff --git a/net/ipv4/netfilter/nf_nat_tftp.c b/net/ipv4/netfilter/nf_nat_tftp.c
index 2566b79..04dfeae 100644
--- a/net/ipv4/netfilter/nf_nat_tftp.c
+++ b/net/ipv4/netfilter/nf_nat_tftp.c
@@ -30,7 +30,7 @@
 		= ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
 	exp->dir = IP_CT_DIR_REPLY;
 	exp->expectfn = nf_nat_follow_master;
-	if (nf_conntrack_expect_related(exp) != 0)
+	if (nf_ct_expect_related(exp) != 0)
 		return NF_DROP;
 	return NF_ACCEPT;
 }
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 29ca63e..88fa648 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -101,7 +101,6 @@
 #include <net/tcp.h>
 #include <net/icmp.h>
 #include <net/xfrm.h>
-#include <net/ip_mp_alg.h>
 #include <net/netevent.h>
 #include <net/rtnetlink.h>
 #ifdef CONFIG_SYSCTL
@@ -168,7 +167,7 @@
 
 #define ECN_OR_COST(class)	TC_PRIO_##class
 
-__u8 ip_tos2prio[16] = {
+const __u8 ip_tos2prio[16] = {
 	TC_PRIO_BESTEFFORT,
 	ECN_OR_COST(FILLER),
 	TC_PRIO_BESTEFFORT,
@@ -495,13 +494,11 @@
 
 static __inline__ void rt_free(struct rtable *rt)
 {
-	multipath_remove(rt);
 	call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free);
 }
 
 static __inline__ void rt_drop(struct rtable *rt)
 {
-	multipath_remove(rt);
 	ip_rt_put(rt);
 	call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free);
 }
@@ -574,52 +571,6 @@
 		(fl1->iif ^ fl2->iif)) == 0;
 }
 
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-static struct rtable **rt_remove_balanced_route(struct rtable **chain_head,
-						struct rtable *expentry,
-						int *removed_count)
-{
-	int passedexpired = 0;
-	struct rtable **nextstep = NULL;
-	struct rtable **rthp = chain_head;
-	struct rtable *rth;
-
-	if (removed_count)
-		*removed_count = 0;
-
-	while ((rth = *rthp) != NULL) {
-		if (rth == expentry)
-			passedexpired = 1;
-
-		if (((*rthp)->u.dst.flags & DST_BALANCED) != 0  &&
-		    compare_keys(&(*rthp)->fl, &expentry->fl)) {
-			if (*rthp == expentry) {
-				*rthp = rth->u.dst.rt_next;
-				continue;
-			} else {
-				*rthp = rth->u.dst.rt_next;
-				rt_free(rth);
-				if (removed_count)
-					++(*removed_count);
-			}
-		} else {
-			if (!((*rthp)->u.dst.flags & DST_BALANCED) &&
-			    passedexpired && !nextstep)
-				nextstep = &rth->u.dst.rt_next;
-
-			rthp = &rth->u.dst.rt_next;
-		}
-	}
-
-	rt_free(expentry);
-	if (removed_count)
-		++(*removed_count);
-
-	return nextstep;
-}
-#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
-
-
 /* This runs via a timer and thus is always in BH context. */
 static void rt_check_expire(unsigned long dummy)
 {
@@ -658,22 +609,8 @@
 			}
 
 			/* Cleanup aged off entries. */
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-			/* remove all related balanced entries if necessary */
-			if (rth->u.dst.flags & DST_BALANCED) {
-				rthp = rt_remove_balanced_route(
-					&rt_hash_table[i].chain,
-					rth, NULL);
-				if (!rthp)
-					break;
-			} else {
-				*rthp = rth->u.dst.rt_next;
-				rt_free(rth);
-			}
-#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
 			*rthp = rth->u.dst.rt_next;
 			rt_free(rth);
-#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
 		}
 		spin_unlock(rt_hash_lock_addr(i));
 
@@ -721,9 +658,6 @@
 	if (delay < 0)
 		delay = ip_rt_min_delay;
 
-	/* flush existing multipath state*/
-	multipath_flush();
-
 	spin_lock_bh(&rt_flush_lock);
 
 	if (del_timer(&rt_flush_timer) && delay > 0 && rt_deadline) {
@@ -842,30 +776,9 @@
 					rthp = &rth->u.dst.rt_next;
 					continue;
 				}
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-				/* remove all related balanced entries
-				 * if necessary
-				 */
-				if (rth->u.dst.flags & DST_BALANCED) {
-					int r;
-
-					rthp = rt_remove_balanced_route(
-						&rt_hash_table[k].chain,
-						rth,
-						&r);
-					goal -= r;
-					if (!rthp)
-						break;
-				} else {
-					*rthp = rth->u.dst.rt_next;
-					rt_free(rth);
-					goal--;
-				}
-#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
 				*rthp = rth->u.dst.rt_next;
 				rt_free(rth);
 				goal--;
-#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
 			}
 			spin_unlock_bh(rt_hash_lock_addr(k));
 			if (goal <= 0)
@@ -939,12 +852,7 @@
 
 	spin_lock_bh(rt_hash_lock_addr(hash));
 	while ((rth = *rthp) != NULL) {
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-		if (!(rth->u.dst.flags & DST_BALANCED) &&
-		    compare_keys(&rth->fl, &rt->fl)) {
-#else
 		if (compare_keys(&rth->fl, &rt->fl)) {
-#endif
 			/* Put it first */
 			*rthp = rth->u.dst.rt_next;
 			/*
@@ -1774,10 +1682,6 @@
 
 	atomic_set(&rth->u.dst.__refcnt, 1);
 	rth->u.dst.flags= DST_HOST;
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	if (res->fi->fib_nhs > 1)
-		rth->u.dst.flags |= DST_BALANCED;
-#endif
 	if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
 		rth->u.dst.flags |= DST_NOPOLICY;
 	if (IN_DEV_CONF_GET(out_dev, NOXFRM))
@@ -1812,11 +1716,11 @@
 	return err;
 }
 
-static inline int ip_mkroute_input_def(struct sk_buff *skb,
-				       struct fib_result* res,
-				       const struct flowi *fl,
-				       struct in_device *in_dev,
-				       __be32 daddr, __be32 saddr, u32 tos)
+static inline int ip_mkroute_input(struct sk_buff *skb,
+				   struct fib_result* res,
+				   const struct flowi *fl,
+				   struct in_device *in_dev,
+				   __be32 daddr, __be32 saddr, u32 tos)
 {
 	struct rtable* rth = NULL;
 	int err;
@@ -1837,63 +1741,6 @@
 	return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
 }
 
-static inline int ip_mkroute_input(struct sk_buff *skb,
-				   struct fib_result* res,
-				   const struct flowi *fl,
-				   struct in_device *in_dev,
-				   __be32 daddr, __be32 saddr, u32 tos)
-{
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	struct rtable* rth = NULL, *rtres;
-	unsigned char hop, hopcount;
-	int err = -EINVAL;
-	unsigned int hash;
-
-	if (res->fi)
-		hopcount = res->fi->fib_nhs;
-	else
-		hopcount = 1;
-
-	/* distinguish between multipath and singlepath */
-	if (hopcount < 2)
-		return ip_mkroute_input_def(skb, res, fl, in_dev, daddr,
-					    saddr, tos);
-
-	/* add all alternatives to the routing cache */
-	for (hop = 0; hop < hopcount; hop++) {
-		res->nh_sel = hop;
-
-		/* put reference to previous result */
-		if (hop)
-			ip_rt_put(rtres);
-
-		/* create a routing cache entry */
-		err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos,
-				      &rth);
-		if (err)
-			return err;
-
-		/* put it into the cache */
-		hash = rt_hash(daddr, saddr, fl->iif);
-		err = rt_intern_hash(hash, rth, &rtres);
-		if (err)
-			return err;
-
-		/* forward hop information to multipath impl. */
-		multipath_set_nhinfo(rth,
-				     FIB_RES_NETWORK(*res),
-				     FIB_RES_NETMASK(*res),
-				     res->prefixlen,
-				     &FIB_RES_NH(*res));
-	}
-	skb->dst = &rtres->u.dst;
-	return err;
-#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED  */
-	return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos);
-#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED  */
-}
-
-
 /*
  *	NOTE. We drop all the packets that has local source
  *	addresses, because every properly looped back packet
@@ -2211,13 +2058,6 @@
 
 	atomic_set(&rth->u.dst.__refcnt, 1);
 	rth->u.dst.flags= DST_HOST;
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	if (res->fi) {
-		rth->rt_multipath_alg = res->fi->fib_mp_alg;
-		if (res->fi->fib_nhs > 1)
-			rth->u.dst.flags |= DST_BALANCED;
-	}
-#endif
 	if (IN_DEV_CONF_GET(in_dev, NOXFRM))
 		rth->u.dst.flags |= DST_NOXFRM;
 	if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
@@ -2277,12 +2117,12 @@
 	return err;
 }
 
-static inline int ip_mkroute_output_def(struct rtable **rp,
-					struct fib_result* res,
-					const struct flowi *fl,
-					const struct flowi *oldflp,
-					struct net_device *dev_out,
-					unsigned flags)
+static inline int ip_mkroute_output(struct rtable **rp,
+				    struct fib_result* res,
+				    const struct flowi *fl,
+				    const struct flowi *oldflp,
+				    struct net_device *dev_out,
+				    unsigned flags)
 {
 	struct rtable *rth = NULL;
 	int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags);
@@ -2295,68 +2135,6 @@
 	return err;
 }
 
-static inline int ip_mkroute_output(struct rtable** rp,
-				    struct fib_result* res,
-				    const struct flowi *fl,
-				    const struct flowi *oldflp,
-				    struct net_device *dev_out,
-				    unsigned flags)
-{
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	unsigned char hop;
-	unsigned hash;
-	int err = -EINVAL;
-	struct rtable *rth = NULL;
-
-	if (res->fi && res->fi->fib_nhs > 1) {
-		unsigned char hopcount = res->fi->fib_nhs;
-
-		for (hop = 0; hop < hopcount; hop++) {
-			struct net_device *dev2nexthop;
-
-			res->nh_sel = hop;
-
-			/* hold a work reference to the output device */
-			dev2nexthop = FIB_RES_DEV(*res);
-			dev_hold(dev2nexthop);
-
-			/* put reference to previous result */
-			if (hop)
-				ip_rt_put(*rp);
-
-			err = __mkroute_output(&rth, res, fl, oldflp,
-					       dev2nexthop, flags);
-
-			if (err != 0)
-				goto cleanup;
-
-			hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src,
-					oldflp->oif);
-			err = rt_intern_hash(hash, rth, rp);
-
-			/* forward hop information to multipath impl. */
-			multipath_set_nhinfo(rth,
-					     FIB_RES_NETWORK(*res),
-					     FIB_RES_NETMASK(*res),
-					     res->prefixlen,
-					     &FIB_RES_NH(*res));
-		cleanup:
-			/* release work reference to output device */
-			dev_put(dev2nexthop);
-
-			if (err != 0)
-				return err;
-		}
-		return err;
-	} else {
-		return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out,
-					     flags);
-	}
-#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
-	return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out, flags);
-#endif
-}
-
 /*
  * Major route resolver routine.
  */
@@ -2570,17 +2348,6 @@
 		    rth->fl.mark == flp->mark &&
 		    !((rth->fl.fl4_tos ^ flp->fl4_tos) &
 			    (IPTOS_RT_MASK | RTO_ONLINK))) {
-
-			/* check for multipath routes and choose one if
-			 * necessary
-			 */
-			if (multipath_select_route(flp, rth, rp)) {
-				dst_hold(&(*rp)->u.dst);
-				RT_CACHE_STAT_INC(out_hit);
-				rcu_read_unlock_bh();
-				return 0;
-			}
-
 			rth->u.dst.lastuse = jiffies;
 			dst_hold(&rth->u.dst);
 			rth->u.dst.__use++;
@@ -2729,10 +2496,6 @@
 	if (rt->u.dst.tclassid)
 		NLA_PUT_U32(skb, RTA_FLOW, rt->u.dst.tclassid);
 #endif
-#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	if (rt->rt_multipath_alg != IP_MP_ALG_NONE)
-		NLA_PUT_U32(skb, RTA_MP_ALGO, rt->rt_multipath_alg);
-#endif
 	if (rt->fl.iif)
 		NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
 	else if (rt->rt_src != rt->fl.fl4_src)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 354721d..3f5f742 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2045,10 +2045,7 @@
 		struct hlist_node *node;
 		struct inet_timewait_sock *tw;
 
-		/* We can reschedule _before_ having picked the target: */
-		cond_resched_softirq();
-
-		read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
+		read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
 		sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
 			if (sk->sk_family != st->family) {
 				continue;
@@ -2065,7 +2062,7 @@
 			rc = tw;
 			goto out;
 		}
-		read_unlock(&tcp_hashinfo.ehash[st->bucket].lock);
+		read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
 		st->state = TCP_SEQ_STATE_ESTABLISHED;
 	}
 out:
@@ -2092,14 +2089,11 @@
 			cur = tw;
 			goto out;
 		}
-		read_unlock(&tcp_hashinfo.ehash[st->bucket].lock);
+		read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
 		st->state = TCP_SEQ_STATE_ESTABLISHED;
 
-		/* We can reschedule between buckets: */
-		cond_resched_softirq();
-
 		if (++st->bucket < tcp_hashinfo.ehash_size) {
-			read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
+			read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
 			sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain);
 		} else {
 			cur = NULL;
@@ -2144,7 +2138,6 @@
 
 	if (!rc) {
 		inet_listen_unlock(&tcp_hashinfo);
-		local_bh_disable();
 		st->state = TCP_SEQ_STATE_ESTABLISHED;
 		rc	  = established_get_idx(seq, pos);
 	}
@@ -2177,7 +2170,6 @@
 		rc = listening_get_next(seq, v);
 		if (!rc) {
 			inet_listen_unlock(&tcp_hashinfo);
-			local_bh_disable();
 			st->state = TCP_SEQ_STATE_ESTABLISHED;
 			rc	  = established_get_first(seq);
 		}
@@ -2209,8 +2201,7 @@
 	case TCP_SEQ_STATE_TIME_WAIT:
 	case TCP_SEQ_STATE_ESTABLISHED:
 		if (v)
-			read_unlock(&tcp_hashinfo.ehash[st->bucket].lock);
-		local_bh_enable();
+			read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
 		break;
 	}
 }
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 53232dd..20aea15 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -699,6 +699,14 @@
 			tp->fackets_out -= diff;
 			if ((int)tp->fackets_out < 0)
 				tp->fackets_out = 0;
+			/* SACK fastpath might overwrite it unless dealt with */
+			if (tp->fastpath_skb_hint != NULL &&
+			    after(TCP_SKB_CB(tp->fastpath_skb_hint)->seq,
+				  TCP_SKB_CB(skb)->seq)) {
+				tp->fastpath_cnt_hint -= diff;
+				if ((int)tp->fastpath_cnt_hint < 0)
+					tp->fastpath_cnt_hint = 0;
+			}
 		}
 	}
 
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index d9323df..86624fa 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -6,8 +6,7 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation; either version 2 of the License.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -25,23 +24,22 @@
 #include <linux/tcp.h>
 #include <linux/proc_fs.h>
 #include <linux/module.h>
-#include <linux/kfifo.h>
 #include <linux/ktime.h>
 #include <linux/time.h>
-#include <linux/vmalloc.h>
 
 #include <net/tcp.h>
 
 MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>");
 MODULE_DESCRIPTION("TCP cwnd snooper");
 MODULE_LICENSE("GPL");
+MODULE_VERSION("1.1");
 
 static int port __read_mostly = 0;
 MODULE_PARM_DESC(port, "Port to match (0=all)");
 module_param(port, int, 0);
 
-static int bufsize __read_mostly = 64*1024;
-MODULE_PARM_DESC(bufsize, "Log buffer size (default 64k)");
+static int bufsize __read_mostly = 4096;
+MODULE_PARM_DESC(bufsize, "Log buffer size in packets (4096)");
 module_param(bufsize, int, 0);
 
 static int full __read_mostly;
@@ -50,39 +48,38 @@
 
 static const char procname[] = "tcpprobe";
 
-struct {
-	struct kfifo	*fifo;
+struct tcp_log {
+	ktime_t tstamp;
+	__be32	saddr, daddr;
+	__be16	sport, dport;
+	u16	length;
+	u32	snd_nxt;
+	u32	snd_una;
+	u32	snd_wnd;
+	u32	snd_cwnd;
+	u32	ssthresh;
+	u32	srtt;
+};
+
+static struct {
 	spinlock_t	lock;
 	wait_queue_head_t wait;
 	ktime_t		start;
 	u32		lastcwnd;
-} tcpw;
 
-/*
- * Print to log with timestamps.
- * FIXME: causes an extra copy
- */
-static void printl(const char *fmt, ...)
-	__attribute__ ((format (printf, 1, 2)));
+	unsigned long	head, tail;
+	struct tcp_log	*log;
+} tcp_probe;
 
-static void printl(const char *fmt, ...)
+
+static inline int tcp_probe_used(void)
 {
-	va_list args;
-	int len;
-	struct timespec tv;
-	char tbuf[256];
+	return (tcp_probe.head - tcp_probe.tail) % bufsize;
+}
 
-	va_start(args, fmt);
-	/* want monotonic time since start of tcp_probe */
-	tv = ktime_to_timespec(ktime_sub(ktime_get(), tcpw.start));
-
-	len = sprintf(tbuf, "%lu.%09lu ",
-		      (unsigned long) tv.tv_sec, (unsigned long) tv.tv_nsec);
-	len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args);
-	va_end(args);
-
-	kfifo_put(tcpw.fifo, tbuf, len);
-	wake_up(&tcpw.wait);
+static inline int tcp_probe_avail(void)
+{
+	return bufsize - tcp_probe_used();
 }
 
 /*
@@ -97,63 +94,117 @@
 
 	/* Only update if port matches */
 	if ((port == 0 || ntohs(inet->dport) == port || ntohs(inet->sport) == port)
-	    && (full || tp->snd_cwnd != tcpw.lastcwnd)) {
-		printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d %#x %#x %u %u %u %u\n",
-		       NIPQUAD(inet->saddr), ntohs(inet->sport),
-		       NIPQUAD(inet->daddr), ntohs(inet->dport),
-		       skb->len, tp->snd_nxt, tp->snd_una,
-		       tp->snd_cwnd, tcp_current_ssthresh(sk),
-		       tp->snd_wnd, tp->srtt >> 3);
-		tcpw.lastcwnd = tp->snd_cwnd;
+	    && (full || tp->snd_cwnd != tcp_probe.lastcwnd)) {
+
+		spin_lock(&tcp_probe.lock);
+		/* If log fills, just silently drop */
+		if (tcp_probe_avail() > 1) {
+			struct tcp_log *p = tcp_probe.log + tcp_probe.head;
+
+			p->tstamp = ktime_get();
+			p->saddr = inet->saddr;
+			p->sport = inet->sport;
+			p->daddr = inet->daddr;
+			p->dport = inet->dport;
+			p->length = skb->len;
+			p->snd_nxt = tp->snd_nxt;
+			p->snd_una = tp->snd_una;
+			p->snd_cwnd = tp->snd_cwnd;
+			p->snd_wnd = tp->snd_wnd;
+			p->srtt = tp->srtt >> 3;
+
+			tcp_probe.head = (tcp_probe.head + 1) % bufsize;
+		}
+		tcp_probe.lastcwnd = tp->snd_cwnd;
+		spin_unlock(&tcp_probe.lock);
+
+		wake_up(&tcp_probe.wait);
 	}
 
 	jprobe_return();
 	return 0;
 }
 
-static struct jprobe tcp_probe = {
+static struct jprobe tcp_jprobe = {
 	.kp = {
 		.symbol_name	= "tcp_rcv_established",
 	},
 	.entry	= JPROBE_ENTRY(jtcp_rcv_established),
 };
 
-
 static int tcpprobe_open(struct inode * inode, struct file * file)
 {
-	kfifo_reset(tcpw.fifo);
-	tcpw.start = ktime_get();
+	/* Reset (empty) log */
+	spin_lock_bh(&tcp_probe.lock);
+	tcp_probe.head = tcp_probe.tail = 0;
+	tcp_probe.start = ktime_get();
+	spin_unlock_bh(&tcp_probe.lock);
+
 	return 0;
 }
 
+static int tcpprobe_sprint(char *tbuf, int n)
+{
+	const struct tcp_log *p
+		= tcp_probe.log + tcp_probe.tail % bufsize;
+	struct timespec tv
+		= ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start));
+
+	return snprintf(tbuf, n,
+			"%lu.%09lu %d.%d.%d.%d:%u %d.%d.%d.%d:%u"
+			" %d %#x %#x %u %u %u %u\n",
+			(unsigned long) tv.tv_sec,
+			(unsigned long) tv.tv_nsec,
+			NIPQUAD(p->saddr), ntohs(p->sport),
+			NIPQUAD(p->daddr), ntohs(p->dport),
+			p->length, p->snd_nxt, p->snd_una,
+			p->snd_cwnd, p->ssthresh, p->snd_wnd, p->srtt);
+}
+
 static ssize_t tcpprobe_read(struct file *file, char __user *buf,
 			     size_t len, loff_t *ppos)
 {
 	int error = 0, cnt = 0;
-	unsigned char *tbuf;
 
 	if (!buf || len < 0)
 		return -EINVAL;
 
-	if (len == 0)
-		return 0;
+	while (cnt < len) {
+		char tbuf[128];
+		int width;
 
-	tbuf = vmalloc(len);
-	if (!tbuf)
-		return -ENOMEM;
+		/* Wait for data in buffer */
+		error = wait_event_interruptible(tcp_probe.wait,
+						 tcp_probe_used() > 0);
+		if (error)
+			break;
 
-	error = wait_event_interruptible(tcpw.wait,
-					 __kfifo_len(tcpw.fifo) != 0);
-	if (error)
-		goto out_free;
+		spin_lock_bh(&tcp_probe.lock);
+		if (tcp_probe.head == tcp_probe.tail) {
+			/* multiple readers race? */
+			spin_unlock_bh(&tcp_probe.lock);
+			continue;
+		}
 
-	cnt = kfifo_get(tcpw.fifo, tbuf, len);
-	error = copy_to_user(buf, tbuf, cnt);
+		width = tcpprobe_sprint(tbuf, sizeof(tbuf));
 
-out_free:
-	vfree(tbuf);
+		if (width < len)
+			tcp_probe.tail = (tcp_probe.tail + 1) % bufsize;
 
-	return error ? error : cnt;
+		spin_unlock_bh(&tcp_probe.lock);
+
+		/* if record greater than space available
+		   return partial buffer (so far) */
+		if (width >= len)
+			break;
+
+		error = copy_to_user(buf + cnt, tbuf, width);
+		if (error)
+			break;
+		cnt += width;
+	}
+
+	return cnt == 0 ? error : cnt;
 }
 
 static const struct file_operations tcpprobe_fops = {
@@ -166,34 +217,37 @@
 {
 	int ret = -ENOMEM;
 
-	init_waitqueue_head(&tcpw.wait);
-	spin_lock_init(&tcpw.lock);
-	tcpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &tcpw.lock);
-	if (IS_ERR(tcpw.fifo))
-		return PTR_ERR(tcpw.fifo);
+	init_waitqueue_head(&tcp_probe.wait);
+	spin_lock_init(&tcp_probe.lock);
+
+	if (bufsize < 0)
+		return -EINVAL;
+
+	tcp_probe.log = kcalloc(sizeof(struct tcp_log), bufsize, GFP_KERNEL);
+	if (!tcp_probe.log)
+		goto err0;
 
 	if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops))
 		goto err0;
 
-	ret = register_jprobe(&tcp_probe);
+	ret = register_jprobe(&tcp_jprobe);
 	if (ret)
 		goto err1;
 
-	pr_info("TCP watch registered (port=%d)\n", port);
+	pr_info("TCP probe registered (port=%d)\n", port);
 	return 0;
  err1:
 	proc_net_remove(procname);
  err0:
-	kfifo_free(tcpw.fifo);
+	kfree(tcp_probe.log);
 	return ret;
 }
 module_init(tcpprobe_init);
 
 static __exit void tcpprobe_exit(void)
 {
-	kfifo_free(tcpw.fifo);
 	proc_net_remove(procname);
-	unregister_jprobe(&tcp_probe);
-
+	unregister_jprobe(&tcp_jprobe);
+	kfree(tcp_probe.log);
 }
 module_exit(tcpprobe_exit);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index facb7e2..2835535 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -70,6 +70,7 @@
  *	Alexey Kuznetsov:		allow both IPv4 and IPv6 sockets to bind
  *					a single port at the same time.
  *	Derek Atkins <derek@ihtfp.com>: Add Encapulation Support
+ *	James Chapman		:	Add L2TP encapsulation type.
  *
  *
  *		This program is free software; you can redistribute it and/or
@@ -919,104 +920,6 @@
 	return 0;
 }
 
-/* return:
- * 	1  if the UDP system should process it
- *	0  if we should drop this packet
- * 	-1 if it should get processed by xfrm4_rcv_encap
- */
-static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
-{
-#ifndef CONFIG_XFRM
-	return 1;
-#else
-	struct udp_sock *up = udp_sk(sk);
-	struct udphdr *uh;
-	struct iphdr *iph;
-	int iphlen, len;
-
-	__u8 *udpdata;
-	__be32 *udpdata32;
-	__u16 encap_type = up->encap_type;
-
-	/* if we're overly short, let UDP handle it */
-	len = skb->len - sizeof(struct udphdr);
-	if (len <= 0)
-		return 1;
-
-	/* if this is not encapsulated socket, then just return now */
-	if (!encap_type)
-		return 1;
-
-	/* If this is a paged skb, make sure we pull up
-	 * whatever data we need to look at. */
-	if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
-		return 1;
-
-	/* Now we can get the pointers */
-	uh = udp_hdr(skb);
-	udpdata = (__u8 *)uh + sizeof(struct udphdr);
-	udpdata32 = (__be32 *)udpdata;
-
-	switch (encap_type) {
-	default:
-	case UDP_ENCAP_ESPINUDP:
-		/* Check if this is a keepalive packet.  If so, eat it. */
-		if (len == 1 && udpdata[0] == 0xff) {
-			return 0;
-		} else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
-			/* ESP Packet without Non-ESP header */
-			len = sizeof(struct udphdr);
-		} else
-			/* Must be an IKE packet.. pass it through */
-			return 1;
-		break;
-	case UDP_ENCAP_ESPINUDP_NON_IKE:
-		/* Check if this is a keepalive packet.  If so, eat it. */
-		if (len == 1 && udpdata[0] == 0xff) {
-			return 0;
-		} else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
-			   udpdata32[0] == 0 && udpdata32[1] == 0) {
-
-			/* ESP Packet with Non-IKE marker */
-			len = sizeof(struct udphdr) + 2 * sizeof(u32);
-		} else
-			/* Must be an IKE packet.. pass it through */
-			return 1;
-		break;
-	}
-
-	/* At this point we are sure that this is an ESPinUDP packet,
-	 * so we need to remove 'len' bytes from the packet (the UDP
-	 * header and optional ESP marker bytes) and then modify the
-	 * protocol to ESP, and then call into the transform receiver.
-	 */
-	if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
-		return 0;
-
-	/* Now we can update and verify the packet length... */
-	iph = ip_hdr(skb);
-	iphlen = iph->ihl << 2;
-	iph->tot_len = htons(ntohs(iph->tot_len) - len);
-	if (skb->len < iphlen + len) {
-		/* packet is too small!?! */
-		return 0;
-	}
-
-	/* pull the data buffer up to the ESP header and set the
-	 * transport header to point to ESP.  Keep UDP on the stack
-	 * for later.
-	 */
-	__skb_pull(skb, len);
-	skb_reset_transport_header(skb);
-
-	/* modify the protocol (it's ESP!) */
-	iph->protocol = IPPROTO_ESP;
-
-	/* and let the caller know to send this into the ESP processor... */
-	return -1;
-#endif
-}
-
 /* returns:
  *  -1: error
  *   0: success
@@ -1039,28 +942,28 @@
 
 	if (up->encap_type) {
 		/*
-		 * This is an encapsulation socket, so let's see if this is
-		 * an encapsulated packet.
-		 * If it's a keepalive packet, then just eat it.
-		 * If it's an encapsulateed packet, then pass it to the
-		 * IPsec xfrm input and return the response
-		 * appropriately.  Otherwise, just fall through and
-		 * pass this up the UDP socket.
+		 * This is an encapsulation socket so pass the skb to
+		 * the socket's udp_encap_rcv() hook. Otherwise, just
+		 * fall through and pass this up the UDP socket.
+		 * up->encap_rcv() returns the following value:
+		 * =0 if skb was successfully passed to the encap
+		 *    handler or was discarded by it.
+		 * >0 if skb should be passed on to UDP.
+		 * <0 if skb should be resubmitted as proto -N
 		 */
-		int ret;
 
-		ret = udp_encap_rcv(sk, skb);
-		if (ret == 0) {
-			/* Eat the packet .. */
-			kfree_skb(skb);
-			return 0;
+		/* if we're overly short, let UDP handle it */
+		if (skb->len > sizeof(struct udphdr) &&
+		    up->encap_rcv != NULL) {
+			int ret;
+
+			ret = (*up->encap_rcv)(sk, skb);
+			if (ret <= 0) {
+				UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
+				return -ret;
+			}
 		}
-		if (ret < 0) {
-			/* process the ESP packet */
-			ret = xfrm4_rcv_encap(skb, up->encap_type);
-			UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
-			return -ret;
-		}
+
 		/* FALLTHROUGH -- it's a UDP Packet */
 	}
 
@@ -1349,6 +1252,9 @@
 		case 0:
 		case UDP_ENCAP_ESPINUDP:
 		case UDP_ENCAP_ESPINUDP_NON_IKE:
+			up->encap_rcv = xfrm4_udp_encap_rcv;
+			/* FALLTHROUGH */
+		case UDP_ENCAP_L2TPINUDP:
 			up->encap_type = val;
 			break;
 		default:
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index fa1902d..2fa1082 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -16,13 +16,6 @@
 #include <net/ip.h>
 #include <net/xfrm.h>
 
-int xfrm4_rcv(struct sk_buff *skb)
-{
-	return xfrm4_rcv_encap(skb, 0);
-}
-
-EXPORT_SYMBOL(xfrm4_rcv);
-
 static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
 {
 	switch (nexthdr) {
@@ -53,7 +46,7 @@
 }
 #endif
 
-int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
+static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
 {
 	__be32 spi, seq;
 	struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
@@ -167,3 +160,108 @@
 	kfree_skb(skb);
 	return 0;
 }
+
+/* If it's a keepalive packet, then just eat it.
+ * If it's an encapsulated packet, then pass it to the
+ * IPsec xfrm input.
+ * Returns 0 if skb passed to xfrm or was dropped.
+ * Returns >0 if skb should be passed to UDP.
+ * Returns <0 if skb should be resubmitted (-ret is protocol)
+ */
+int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
+{
+	struct udp_sock *up = udp_sk(sk);
+	struct udphdr *uh;
+	struct iphdr *iph;
+	int iphlen, len;
+	int ret;
+
+	__u8 *udpdata;
+	__be32 *udpdata32;
+	__u16 encap_type = up->encap_type;
+
+	/* if this is not encapsulated socket, then just return now */
+	if (!encap_type)
+		return 1;
+
+	/* If this is a paged skb, make sure we pull up
+	 * whatever data we need to look at. */
+	len = skb->len - sizeof(struct udphdr);
+	if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
+		return 1;
+
+	/* Now we can get the pointers */
+	uh = udp_hdr(skb);
+	udpdata = (__u8 *)uh + sizeof(struct udphdr);
+	udpdata32 = (__be32 *)udpdata;
+
+	switch (encap_type) {
+	default:
+	case UDP_ENCAP_ESPINUDP:
+		/* Check if this is a keepalive packet.  If so, eat it. */
+		if (len == 1 && udpdata[0] == 0xff) {
+			goto drop;
+		} else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
+			/* ESP Packet without Non-ESP header */
+			len = sizeof(struct udphdr);
+		} else
+			/* Must be an IKE packet.. pass it through */
+			return 1;
+		break;
+	case UDP_ENCAP_ESPINUDP_NON_IKE:
+		/* Check if this is a keepalive packet.  If so, eat it. */
+		if (len == 1 && udpdata[0] == 0xff) {
+			goto drop;
+		} else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
+			   udpdata32[0] == 0 && udpdata32[1] == 0) {
+
+			/* ESP Packet with Non-IKE marker */
+			len = sizeof(struct udphdr) + 2 * sizeof(u32);
+		} else
+			/* Must be an IKE packet.. pass it through */
+			return 1;
+		break;
+	}
+
+	/* At this point we are sure that this is an ESPinUDP packet,
+	 * so we need to remove 'len' bytes from the packet (the UDP
+	 * header and optional ESP marker bytes) and then modify the
+	 * protocol to ESP, and then call into the transform receiver.
+	 */
+	if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+		goto drop;
+
+	/* Now we can update and verify the packet length... */
+	iph = ip_hdr(skb);
+	iphlen = iph->ihl << 2;
+	iph->tot_len = htons(ntohs(iph->tot_len) - len);
+	if (skb->len < iphlen + len) {
+		/* packet is too small!?! */
+		goto drop;
+	}
+
+	/* pull the data buffer up to the ESP header and set the
+	 * transport header to point to ESP.  Keep UDP on the stack
+	 * for later.
+	 */
+	__skb_pull(skb, len);
+	skb_reset_transport_header(skb);
+
+	/* modify the protocol (it's ESP!) */
+	iph->protocol = IPPROTO_ESP;
+
+	/* process ESP */
+	ret = xfrm4_rcv_encap(skb, encap_type);
+	return ret;
+
+drop:
+	kfree_skb(skb);
+	return 0;
+}
+
+int xfrm4_rcv(struct sk_buff *skb)
+{
+	return xfrm4_rcv_encap(skb, 0);
+}
+
+EXPORT_SYMBOL(xfrm4_rcv);
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 5685103..9275c79 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -109,3 +109,4 @@
 module_init(ipip_init);
 module_exit(ipip_fini);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_IPIP);
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 8e5d54f..eb0b808 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -109,7 +109,7 @@
 	  If unsure, say Y.
 
 config IPV6_MIP6
-	bool "IPv6: Mobility (EXPERIMENTAL)"
+	tristate "IPv6: Mobility (EXPERIMENTAL)"
 	depends on IPV6 && EXPERIMENTAL
 	select XFRM
 	---help---
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index bb3330904..87c23a7 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -14,7 +14,6 @@
 	xfrm6_output.o
 ipv6-$(CONFIG_NETFILTER) += netfilter.o
 ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
-ipv6-$(CONFIG_IPV6_MIP6) += mip6.o
 ipv6-$(CONFIG_PROC_FS) += proc.o
 
 ipv6-objs += $(ipv6-y)
@@ -28,6 +27,7 @@
 obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o
 obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
 obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
+obj-$(CONFIG_IPV6_MIP6) += mip6.o
 obj-$(CONFIG_NETFILTER)	+= netfilter/
 
 obj-$(CONFIG_IPV6_SIT) += sit.o
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 79b79f3..24424c3 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1034,7 +1034,7 @@
 			}
 
 			/* Rule 4: Prefer home address */
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 			if (hiscore.rule < 4) {
 				if (ifa_result->flags & IFA_F_HOMEADDRESS)
 					hiscore.attrs |= IPV6_SADDR_SCORE_HOA;
@@ -2785,7 +2785,7 @@
 	return 0;
 }
 
-static struct seq_operations if6_seq_ops = {
+static const struct seq_operations if6_seq_ops = {
 	.start	= if6_seq_start,
 	.next	= if6_seq_next,
 	.show	= if6_seq_show,
@@ -2835,7 +2835,7 @@
 }
 #endif	/* CONFIG_PROC_FS */
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 /* Check if address is a home address configured on any interface. */
 int ipv6_chk_home_addr(struct in6_addr *addr)
 {
@@ -4243,7 +4243,6 @@
 void __exit addrconf_cleanup(void)
 {
 	struct net_device *dev;
-	struct inet6_dev *idev;
 	struct inet6_ifaddr *ifa;
 	int i;
 
@@ -4261,7 +4260,7 @@
 	 */
 
 	for_each_netdev(dev) {
-		if ((idev = __in6_dev_get(dev)) == NULL)
+		if (__in6_dev_get(dev) == NULL)
 			continue;
 		addrconf_ifdown(dev, 1);
 	}
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 6dd3772..eed0937 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -58,9 +58,6 @@
 #ifdef CONFIG_IPV6_TUNNEL
 #include <net/ip6_tunnel.h>
 #endif
-#ifdef CONFIG_IPV6_MIP6
-#include <net/mip6.h>
-#endif
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -853,9 +850,6 @@
 	ipv6_frag_init();
 	ipv6_nodata_init();
 	ipv6_destopt_init();
-#ifdef CONFIG_IPV6_MIP6
-	mip6_init();
-#endif
 
 	/* Init v6 transport protocols. */
 	udpv6_init();
@@ -921,9 +915,7 @@
 
 	/* Cleanup code parts. */
 	ipv6_packet_cleanup();
-#ifdef CONFIG_IPV6_MIP6
-	mip6_fini();
-#endif
+
 	addrconf_cleanup();
 	ip6_flowlabel_cleanup();
 	ip6_route_cleanup();
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 128f94c..53f46ab 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -74,7 +74,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 /**
  *	ipv6_rearrange_destopt - rearrange IPv6 destination options header
  *	@iph: IPv6 header
@@ -132,6 +132,8 @@
 bad:
 	return;
 }
+#else
+static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *destopt) {}
 #endif
 
 /**
@@ -189,10 +191,8 @@
 	while (exthdr.raw < end) {
 		switch (nexthdr) {
 		case NEXTHDR_DEST:
-#ifdef CONFIG_IPV6_MIP6
 			if (dir == XFRM_POLICY_OUT)
 				ipv6_rearrange_destopt(iph, exthdr.opth);
-#endif
 		case NEXTHDR_HOP:
 			if (!zero_out_mutable_opts(exthdr.opth)) {
 				LIMIT_NETDEBUG(
@@ -228,7 +228,7 @@
 	u8 nexthdr;
 	char tmp_base[8];
 	struct {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 		struct in6_addr saddr;
 #endif
 		struct in6_addr daddr;
@@ -255,7 +255,7 @@
 			err = -ENOMEM;
 			goto error;
 		}
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 		memcpy(tmp_ext, &top_iph->saddr, extlen);
 #else
 		memcpy(tmp_ext, &top_iph->daddr, extlen);
@@ -294,7 +294,7 @@
 
 	memcpy(top_iph, tmp_base, sizeof(tmp_base));
 	if (tmp_ext) {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 		memcpy(&top_iph->saddr, tmp_ext, extlen);
 #else
 		memcpy(&top_iph->daddr, tmp_ext, extlen);
@@ -554,3 +554,4 @@
 module_exit(ah6_fini);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_AH);
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 9b81264..b8c533f 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -539,7 +539,7 @@
 	return 0;
 }
 
-static struct seq_operations ac6_seq_ops = {
+static const struct seq_operations ac6_seq_ops = {
 	.start	=	ac6_seq_start,
 	.next	=	ac6_seq_next,
 	.stop	=	ac6_seq_stop,
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index b1fe7ac..fe0f490 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -657,11 +657,10 @@
 			rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg);
 
 			switch (rthdr->type) {
-			case IPV6_SRCRT_TYPE_0:
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 			case IPV6_SRCRT_TYPE_2:
-#endif
 				break;
+#endif
 			default:
 				err = -EINVAL;
 				goto exit_f;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 7107bb7..2db31ce 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -421,3 +421,4 @@
 module_exit(esp6_fini);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_ESP);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 14be0b9..c82d4d4 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -42,7 +42,7 @@
 #include <net/ndisc.h>
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 #include <net/xfrm.h>
 #endif
 
@@ -90,6 +90,7 @@
  bad:
 	return -1;
 }
+EXPORT_SYMBOL_GPL(ipv6_find_tlv);
 
 /*
  *	Parsing tlv encoded headers.
@@ -196,7 +197,7 @@
   Destination options header.
  *****************************/
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
 {
 	struct sk_buff *skb = *skbp;
@@ -270,7 +271,7 @@
 #endif
 
 static struct tlvtype_proc tlvprocdestopt_lst[] = {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 	{
 		.type	= IPV6_TLV_HAO,
 		.func	= ipv6_dest_hao,
@@ -283,7 +284,7 @@
 {
 	struct sk_buff *skb = *skbp;
 	struct inet6_skb_parm *opt = IP6CB(skb);
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 	__u16 dstbuf;
 #endif
 	struct dst_entry *dst;
@@ -298,7 +299,7 @@
 	}
 
 	opt->lastopt = opt->dst1 = skb_network_header_len(skb);
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 	dstbuf = opt->dst1;
 #endif
 
@@ -308,7 +309,7 @@
 		skb = *skbp;
 		skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
 		opt = IP6CB(skb);
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 		opt->nhoff = dstbuf;
 #else
 		opt->nhoff = opt->dst1;
@@ -371,22 +372,13 @@
 	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) {
+	idev = in6_dev_get(skb->dev);
+	if (idev) {
+		if (accept_source_route > idev->cnf.accept_source_route)
+			accept_source_route = idev->cnf.accept_source_route;
 		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_transport_offset(skb) + 8) ||
 	    !pskb_may_pull(skb, (skb_transport_offset(skb) +
 				 ((skb_transport_header(skb)[1] + 1) << 3)))) {
@@ -398,24 +390,6 @@
 
 	hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
 
-	switch (hdr->type) {
-#ifdef CONFIG_IPV6_MIP6
-	case IPV6_SRCRT_TYPE_2:
-		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_network_header(skb));
-		return -1;
-	}
-
 	if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
 	    skb->pkt_type != PACKET_HOST) {
 		IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
@@ -427,7 +401,7 @@
 looped_back:
 	if (hdr->segments_left == 0) {
 		switch (hdr->type) {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 		case IPV6_SRCRT_TYPE_2:
 			/* Silently discard type 2 header unless it was
 			 * processed by own
@@ -453,18 +427,10 @@
 	}
 
 	switch (hdr->type) {
-	case IPV6_SRCRT_TYPE_0:
-		if (hdr->hdrlen & 0x01) {
-			IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
-					 IPSTATS_MIB_INHDRERRORS);
-			icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
-					  ((&hdr->hdrlen) -
-					   skb_network_header(skb)));
-			return -1;
-		}
-		break;
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 	case IPV6_SRCRT_TYPE_2:
+		if (accept_source_route < 0)
+			goto unknown_rh;
 		/* Silently discard invalid RTH type 2 */
 		if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
 			IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
@@ -474,6 +440,8 @@
 		}
 		break;
 #endif
+	default:
+		goto unknown_rh;
 	}
 
 	/*
@@ -520,7 +488,7 @@
 	addr += i - 1;
 
 	switch (hdr->type) {
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 	case IPV6_SRCRT_TYPE_2:
 		if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
 				     (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
@@ -577,6 +545,12 @@
 	skb_push(skb, skb->data - skb_network_header(skb));
 	dst_input(skb);
 	return -1;
+
+unknown_rh:
+	IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
+	icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
+			  (&hdr->type) - skb_network_header(skb));
+	return -1;
 }
 
 static struct inet6_protocol rthdr_protocol = {
@@ -590,72 +564,6 @@
 		printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
 };
 
-/*
-   This function inverts received rthdr.
-   NOTE: specs allow to make it automatically only if
-   packet authenticated.
-
-   I will not discuss it here (though, I am really pissed off at
-   this stupid requirement making rthdr idea useless)
-
-   Actually, it creates severe problems  for us.
-   Embryonic requests has no associated sockets,
-   so that user have no control over it and
-   cannot not only to set reply options, but
-   even to know, that someone wants to connect
-   without success. :-(
-
-   For now we need to test the engine, so that I created
-   temporary (or permanent) backdoor.
-   If listening socket set IPV6_RTHDR to 2, then we invert header.
-						   --ANK (980729)
- */
-
-struct ipv6_txoptions *
-ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
-{
-	/* Received rthdr:
-
-	   [ H1 -> H2 -> ... H_prev ]  daddr=ME
-
-	   Inverted result:
-	   [ H_prev -> ... -> H1 ] daddr =sender
-
-	   Note, that IP output engine will rewrite this rthdr
-	   by rotating it left by one addr.
-	 */
-
-	int n, i;
-	struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr;
-	struct rt0_hdr *irthdr;
-	struct ipv6_txoptions *opt;
-	int hdrlen = ipv6_optlen(hdr);
-
-	if (hdr->segments_left ||
-	    hdr->type != IPV6_SRCRT_TYPE_0 ||
-	    hdr->hdrlen & 0x01)
-		return NULL;
-
-	n = hdr->hdrlen >> 1;
-	opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
-	if (opt == NULL)
-		return NULL;
-	memset(opt, 0, sizeof(*opt));
-	opt->tot_len = sizeof(*opt) + hdrlen;
-	opt->srcrt = (void*)(opt+1);
-	opt->opt_nflen = hdrlen;
-
-	memcpy(opt->srcrt, hdr, sizeof(*hdr));
-	irthdr = (struct rt0_hdr*)opt->srcrt;
-	irthdr->reserved = 0;
-	opt->srcrt->segments_left = n;
-	for (i=0; i<n; i++)
-		memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
-	return opt;
-}
-
-EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
-
 /**********************************
   Hop-by-hop options.
  **********************************/
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index e9bcce9..4765a29 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -272,7 +272,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 static void mip6_addr_swap(struct sk_buff *skb)
 {
 	struct ipv6hdr *iph = ipv6_hdr(skb);
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index c206a15..413a4eb 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -648,7 +648,7 @@
 	return 0;
 }
 
-static struct seq_operations ip6fl_seq_ops = {
+static const struct seq_operations ip6fl_seq_ops = {
 	.start	=	ip6fl_seq_start,
 	.next	=	ip6fl_seq_next,
 	.stop	=	ip6fl_seq_stop,
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 4704b5f..50d86e9 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -521,6 +521,10 @@
 	to->tc_index = from->tc_index;
 #endif
 	nf_copy(to, from);
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+	to->nf_trace = from->nf_trace;
+#endif
 	skb_copy_secmark(to, from);
 }
 
@@ -543,7 +547,7 @@
 			found_rhdr = 1;
 			break;
 		case NEXTHDR_DEST:
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 			if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0)
 				break;
 #endif
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index a0902fb..281aee4 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -883,8 +883,8 @@
 	 */
 	max_headroom += LL_RESERVED_SPACE(tdev);
 
-	if (skb_headroom(skb) < max_headroom ||
-	    skb_cloned(skb) || skb_shared(skb)) {
+	if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
+	    (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
 		struct sk_buff *new_skb;
 
 		if (!(new_skb = skb_realloc_headroom(skb, max_headroom)))
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 1ee50b5..473f165 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -500,4 +500,4 @@
 MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) for IPv6 - RFC3173");
 MODULE_AUTHOR("Mitsuru KANDA <mk@linux-ipv6.org>");
 
-
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_COMP);
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index aa3d07c..d684639 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -123,7 +123,7 @@
 	struct ipv6hdr *ipv6h;
 	struct inet6_protocol *ops;
 
-	if (!(features & NETIF_F_HW_CSUM))
+	if (!(features & NETIF_F_V6_CSUM))
 		features &= ~NETIF_F_SG;
 
 	if (unlikely(skb_shinfo(skb)->gso_type &
@@ -336,16 +336,12 @@
 		break;
 
 	case IPV6_RECVRTHDR:
-		if (val < 0 || val > 2)
-			goto e_inval;
-		np->rxopt.bits.srcrt = val;
+		np->rxopt.bits.srcrt = valbool;
 		retv = 0;
 		break;
 
 	case IPV6_2292RTHDR:
-		if (val < 0 || val > 2)
-			goto e_inval;
-		np->rxopt.bits.osrcrt = val;
+		np->rxopt.bits.osrcrt = valbool;
 		retv = 0;
 		break;
 
@@ -416,11 +412,10 @@
 		if (optname == IPV6_RTHDR && opt && opt->srcrt) {
 			struct ipv6_rt_hdr *rthdr = opt->srcrt;
 			switch (rthdr->type) {
-			case IPV6_SRCRT_TYPE_0:
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 			case IPV6_SRCRT_TYPE_2:
-#endif
 				break;
+#endif
 			default:
 				goto sticky_done;
 			}
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 3e308fb..ae98818 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -2423,7 +2423,7 @@
 	return 0;
 }
 
-static struct seq_operations igmp6_mc_seq_ops = {
+static const struct seq_operations igmp6_mc_seq_ops = {
 	.start	=	igmp6_mc_seq_start,
 	.next	=	igmp6_mc_seq_next,
 	.stop	=	igmp6_mc_seq_stop,
@@ -2597,7 +2597,7 @@
 	return 0;
 }
 
-static struct seq_operations igmp6_mcf_seq_ops = {
+static const struct seq_operations igmp6_mcf_seq_ops = {
 	.start	=	igmp6_mcf_seq_start,
 	.next	=	igmp6_mcf_seq_next,
 	.stop	=	igmp6_mcf_seq_stop,
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 13b7160..8a1399c 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -30,6 +30,7 @@
 #include <net/sock.h>
 #include <net/ipv6.h>
 #include <net/ip6_checksum.h>
+#include <net/rawv6.h>
 #include <net/xfrm.h>
 #include <net/mip6.h>
 
@@ -86,7 +87,7 @@
 	return len;
 }
 
-int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
+static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
 {
 	struct ip6_mh *mh;
 
@@ -471,7 +472,7 @@
 	.remote_addr	= mip6_xfrm_addr,
 };
 
-int __init mip6_init(void)
+static int __init mip6_init(void)
 {
 	printk(KERN_INFO "Mobile IPv6\n");
 
@@ -483,18 +484,35 @@
 		printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __FUNCTION__);
 		goto mip6_rthdr_xfrm_fail;
 	}
+	if (rawv6_mh_filter_register(mip6_mh_filter) < 0) {
+		printk(KERN_INFO "%s: can't add rawv6 mh filter\n", __FUNCTION__);
+		goto mip6_rawv6_mh_fail;
+	}
+
+
 	return 0;
 
+ mip6_rawv6_mh_fail:
+	xfrm_unregister_type(&mip6_rthdr_type, AF_INET6);
  mip6_rthdr_xfrm_fail:
 	xfrm_unregister_type(&mip6_destopt_type, AF_INET6);
  mip6_destopt_xfrm_fail:
 	return -EAGAIN;
 }
 
-void __exit mip6_fini(void)
+static void __exit mip6_fini(void)
 {
+	if (rawv6_mh_filter_unregister(mip6_mh_filter) < 0)
+		printk(KERN_INFO "%s: can't remove rawv6 mh filter\n", __FUNCTION__);
 	if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0)
 		printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __FUNCTION__);
 	if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0)
 		printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __FUNCTION__);
 }
+
+module_init(mip6_init);
+module_exit(mip6_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_DSTOPTS);
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_ROUTING);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 9aa6240..254c769 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -96,13 +96,13 @@
 }
 
 /* Returns whether matches rule or not. */
-static inline int
+static inline bool
 ip6_packet_match(const struct sk_buff *skb,
 		 const char *indev,
 		 const char *outdev,
 		 const struct ip6t_ip6 *ip6info,
 		 unsigned int *protoff,
-		 int *fragoff, int *hotdrop)
+		 int *fragoff, bool *hotdrop)
 {
 	size_t i;
 	unsigned long ret;
@@ -122,7 +122,7 @@
 		dprintf("DST: %u. Mask: %u. Target: %u.%s\n", ip->daddr,
 			ipinfo->dmsk.s_addr, ipinfo->dst.s_addr,
 			ipinfo->invflags & IP6T_INV_DSTIP ? " (INV)" : "");*/
-		return 0;
+		return false;
 	}
 
 	/* Look for ifname matches; this should unroll nicely. */
@@ -136,7 +136,7 @@
 		dprintf("VIA in mismatch (%s vs %s).%s\n",
 			indev, ip6info->iniface,
 			ip6info->invflags&IP6T_INV_VIA_IN ?" (INV)":"");
-		return 0;
+		return false;
 	}
 
 	for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
@@ -149,7 +149,7 @@
 		dprintf("VIA out mismatch (%s vs %s).%s\n",
 			outdev, ip6info->outiface,
 			ip6info->invflags&IP6T_INV_VIA_OUT ?" (INV)":"");
-		return 0;
+		return false;
 	}
 
 /* ... might want to do something with class and flowlabel here ... */
@@ -162,8 +162,8 @@
 		protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off);
 		if (protohdr < 0) {
 			if (_frag_off == 0)
-				*hotdrop = 1;
-			return 0;
+				*hotdrop = true;
+			return false;
 		}
 		*fragoff = _frag_off;
 
@@ -174,34 +174,34 @@
 
 		if (ip6info->proto == protohdr) {
 			if(ip6info->invflags & IP6T_INV_PROTO) {
-				return 0;
+				return false;
 			}
-			return 1;
+			return true;
 		}
 
 		/* We need match for the '-p all', too! */
 		if ((ip6info->proto != 0) &&
 			!(ip6info->invflags & IP6T_INV_PROTO))
-			return 0;
+			return false;
 	}
-	return 1;
+	return true;
 }
 
 /* should be ip6 safe */
-static inline int
+static inline bool
 ip6_checkentry(const struct ip6t_ip6 *ipv6)
 {
 	if (ipv6->flags & ~IP6T_F_MASK) {
 		duprintf("Unknown flag bits set: %08X\n",
 			 ipv6->flags & ~IP6T_F_MASK);
-		return 0;
+		return false;
 	}
 	if (ipv6->invflags & ~IP6T_INV_MASK) {
 		duprintf("Unknown invflag bits set: %08X\n",
 			 ipv6->invflags & ~IP6T_INV_MASK);
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
 static unsigned int
@@ -219,20 +219,20 @@
 }
 
 static inline
-int do_match(struct ip6t_entry_match *m,
-	     const struct sk_buff *skb,
-	     const struct net_device *in,
-	     const struct net_device *out,
-	     int offset,
-	     unsigned int protoff,
-	     int *hotdrop)
+bool do_match(struct ip6t_entry_match *m,
+	      const struct sk_buff *skb,
+	      const struct net_device *in,
+	      const struct net_device *out,
+	      int offset,
+	      unsigned int protoff,
+	      bool *hotdrop)
 {
 	/* Stop iteration if it doesn't match */
 	if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data,
 				      offset, protoff, hotdrop))
-		return 1;
+		return true;
 	else
-		return 0;
+		return false;
 }
 
 static inline struct ip6t_entry *
@@ -241,6 +241,113 @@
 	return (struct ip6t_entry *)(base + offset);
 }
 
+/* All zeroes == unconditional rule. */
+static inline int
+unconditional(const struct ip6t_ip6 *ipv6)
+{
+	unsigned int i;
+
+	for (i = 0; i < sizeof(*ipv6); i++)
+		if (((char *)ipv6)[i])
+			break;
+
+	return (i == sizeof(*ipv6));
+}
+
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+/* This cries for unification! */
+static const char *hooknames[] = {
+	[NF_IP6_PRE_ROUTING]		= "PREROUTING",
+	[NF_IP6_LOCAL_IN]		= "INPUT",
+	[NF_IP6_FORWARD]		= "FORWARD",
+	[NF_IP6_LOCAL_OUT]		= "OUTPUT",
+	[NF_IP6_POST_ROUTING]		= "POSTROUTING",
+};
+
+enum nf_ip_trace_comments {
+	NF_IP6_TRACE_COMMENT_RULE,
+	NF_IP6_TRACE_COMMENT_RETURN,
+	NF_IP6_TRACE_COMMENT_POLICY,
+};
+
+static const char *comments[] = {
+	[NF_IP6_TRACE_COMMENT_RULE]	= "rule",
+	[NF_IP6_TRACE_COMMENT_RETURN]	= "return",
+	[NF_IP6_TRACE_COMMENT_POLICY]	= "policy",
+};
+
+static struct nf_loginfo trace_loginfo = {
+	.type = NF_LOG_TYPE_LOG,
+	.u = {
+		.log = {
+			.level = 4,
+			.logflags = NF_LOG_MASK,
+		},
+	},
+};
+
+static inline int
+get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
+		      char *hookname, char **chainname,
+		      char **comment, unsigned int *rulenum)
+{
+	struct ip6t_standard_target *t = (void *)ip6t_get_target(s);
+
+	if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) {
+		/* Head of user chain: ERROR target with chainname */
+		*chainname = t->target.data;
+		(*rulenum) = 0;
+	} else if (s == e) {
+		(*rulenum)++;
+
+		if (s->target_offset == sizeof(struct ip6t_entry)
+		   && strcmp(t->target.u.kernel.target->name,
+			     IP6T_STANDARD_TARGET) == 0
+		   && t->verdict < 0
+		   && unconditional(&s->ipv6)) {
+			/* Tail of chains: STANDARD target (return/policy) */
+			*comment = *chainname == hookname
+				? (char *)comments[NF_IP6_TRACE_COMMENT_POLICY]
+				: (char *)comments[NF_IP6_TRACE_COMMENT_RETURN];
+		}
+		return 1;
+	} else
+		(*rulenum)++;
+
+	return 0;
+}
+
+static void trace_packet(struct sk_buff *skb,
+			 unsigned int hook,
+			 const struct net_device *in,
+			 const struct net_device *out,
+			 char *tablename,
+			 struct xt_table_info *private,
+			 struct ip6t_entry *e)
+{
+	void *table_base;
+	struct ip6t_entry *root;
+	char *hookname, *chainname, *comment;
+	unsigned int rulenum = 0;
+
+	table_base = (void *)private->entries[smp_processor_id()];
+	root = get_entry(table_base, private->hook_entry[hook]);
+
+	hookname = chainname = (char *)hooknames[hook];
+	comment = (char *)comments[NF_IP6_TRACE_COMMENT_RULE];
+
+	IP6T_ENTRY_ITERATE(root,
+			   private->size - private->hook_entry[hook],
+			   get_chainname_rulenum,
+			   e, hookname, &chainname, &comment, &rulenum);
+
+	nf_log_packet(AF_INET6, hook, skb, in, out, &trace_loginfo,
+		      "TRACE: %s:%s:%s:%u ",
+		      tablename, chainname, comment, rulenum);
+}
+#endif
+
 /* Returns one of the generic firewall policies, like NF_ACCEPT. */
 unsigned int
 ip6t_do_table(struct sk_buff **pskb,
@@ -252,7 +359,7 @@
 	static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
 	int offset = 0;
 	unsigned int protoff = 0;
-	int hotdrop = 0;
+	bool hotdrop = false;
 	/* Initializing verdict to NF_DROP keeps gcc happy. */
 	unsigned int verdict = NF_DROP;
 	const char *indev, *outdev;
@@ -298,6 +405,14 @@
 
 			t = ip6t_get_target(e);
 			IP_NF_ASSERT(t->u.kernel.target);
+
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+    defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+			/* The packet is traced: log it */
+			if (unlikely((*pskb)->nf_trace))
+				trace_packet(*pskb, hook, in, out,
+					     table->name, private, e);
+#endif
 			/* Standard target? */
 			if (!t->u.kernel.target->target) {
 				int v;
@@ -377,19 +492,6 @@
 #endif
 }
 
-/* All zeroes == unconditional rule. */
-static inline int
-unconditional(const struct ip6t_ip6 *ipv6)
-{
-	unsigned int i;
-
-	for (i = 0; i < sizeof(*ipv6); i++)
-		if (((char *)ipv6)[i])
-			break;
-
-	return (i == sizeof(*ipv6));
-}
-
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
@@ -1282,16 +1384,16 @@
 }
 
 /* Returns 1 if the type and code is matched by the range, 0 otherwise */
-static inline int
+static inline bool
 icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
 		     u_int8_t type, u_int8_t code,
-		     int invert)
+		     bool invert)
 {
 	return (type == test_type && code >= min_code && code <= max_code)
 		^ invert;
 }
 
-static int
+static bool
 icmp6_match(const struct sk_buff *skb,
 	   const struct net_device *in,
 	   const struct net_device *out,
@@ -1299,22 +1401,22 @@
 	   const void *matchinfo,
 	   int offset,
 	   unsigned int protoff,
-	   int *hotdrop)
+	   bool *hotdrop)
 {
 	struct icmp6hdr _icmp, *ic;
 	const struct ip6t_icmp *icmpinfo = matchinfo;
 
 	/* Must not be a fragment. */
 	if (offset)
-		return 0;
+		return false;
 
 	ic = skb_header_pointer(skb, protoff, sizeof(_icmp), &_icmp);
 	if (ic == NULL) {
 		/* We've been asked to examine this packet, and we
 		   can't.  Hence, no choice but to drop. */
 		duprintf("Dropping evil ICMP tinygram.\n");
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	return icmp6_type_code_match(icmpinfo->type,
@@ -1325,7 +1427,7 @@
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 icmp6_checkentry(const char *tablename,
 	   const void *entry,
 	   const struct xt_match *match,
@@ -1339,13 +1441,13 @@
 }
 
 /* The built-in targets: standard (NULL) and error. */
-static struct xt_target ip6t_standard_target = {
+static struct xt_target ip6t_standard_target __read_mostly = {
 	.name		= IP6T_STANDARD_TARGET,
 	.targetsize	= sizeof(int),
 	.family		= AF_INET6,
 };
 
-static struct xt_target ip6t_error_target = {
+static struct xt_target ip6t_error_target __read_mostly = {
 	.name		= IP6T_ERROR_TARGET,
 	.target		= ip6t_error,
 	.targetsize	= IP6T_FUNCTION_MAXNAMELEN,
@@ -1362,7 +1464,7 @@
 	.get		= do_ip6t_get_ctl,
 };
 
-static struct xt_match icmp6_matchstruct = {
+static struct xt_match icmp6_matchstruct __read_mostly = {
 	.name		= "icmp6",
 	.match		= &icmp6_match,
 	.matchsize	= sizeof(struct ip6t_icmp),
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c
index 4115a57..ad4d943 100644
--- a/net/ipv6/netfilter/ip6t_HL.c
+++ b/net/ipv6/netfilter/ip6t_HL.c
@@ -58,28 +58,28 @@
 	return XT_CONTINUE;
 }
 
-static int ip6t_hl_checkentry(const char *tablename,
+static bool ip6t_hl_checkentry(const char *tablename,
 		const void *entry,
 		const struct xt_target *target,
 		void *targinfo,
 		unsigned int hook_mask)
 {
-	struct ip6t_HL_info *info = targinfo;
+	const struct ip6t_HL_info *info = targinfo;
 
 	if (info->mode > IP6T_HL_MAXMODE) {
 		printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
 			info->mode);
-		return 0;
+		return false;
 	}
-	if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) {
+	if (info->mode != IP6T_HL_SET && info->hop_limit == 0) {
 		printk(KERN_WARNING "ip6t_HL: increment/decrement doesn't "
 			"make sense with value 0\n");
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_target ip6t_HL = {
+static struct xt_target ip6t_HL __read_mostly = {
 	.name 		= "HL",
 	.family		= AF_INET6,
 	.target		= ip6t_hl_target,
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 5bb9cd3..b05327e 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -32,12 +32,6 @@
 #include <net/route.h>
 #include <linux/netfilter_ipv6/ip6t_LOG.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Use lock to serialize, so printks don't overlap */
 static DEFINE_SPINLOCK(log_lock);
 
@@ -48,7 +42,8 @@
 {
 	u_int8_t currenthdr;
 	int fragment;
-	struct ipv6hdr _ip6h, *ih;
+	struct ipv6hdr _ip6h;
+	const struct ipv6hdr *ih;
 	unsigned int ptr;
 	unsigned int hdrlen = 0;
 	unsigned int logflags;
@@ -78,7 +73,8 @@
 	ptr = ip6hoff + sizeof(struct ipv6hdr);
 	currenthdr = ih->nexthdr;
 	while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) {
-		struct ipv6_opt_hdr _hdr, *hp;
+		struct ipv6_opt_hdr _hdr;
+		const struct ipv6_opt_hdr *hp;
 
 		hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
 		if (hp == NULL) {
@@ -92,7 +88,8 @@
 
 		switch (currenthdr) {
 		case IPPROTO_FRAGMENT: {
-			struct frag_hdr _fhdr, *fh;
+			struct frag_hdr _fhdr;
+			const struct frag_hdr *fh;
 
 			printk("FRAG:");
 			fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
@@ -131,7 +128,8 @@
 		/* Max Length */
 		case IPPROTO_AH:
 			if (logflags & IP6T_LOG_IPOPT) {
-				struct ip_auth_hdr _ahdr, *ah;
+				struct ip_auth_hdr _ahdr;
+				const struct ip_auth_hdr *ah;
 
 				/* Max length: 3 "AH " */
 				printk("AH ");
@@ -162,7 +160,8 @@
 			break;
 		case IPPROTO_ESP:
 			if (logflags & IP6T_LOG_IPOPT) {
-				struct ip_esp_hdr _esph, *eh;
+				struct ip_esp_hdr _esph;
+				const struct ip_esp_hdr *eh;
 
 				/* Max length: 4 "ESP " */
 				printk("ESP ");
@@ -202,7 +201,8 @@
 
 	switch (currenthdr) {
 	case IPPROTO_TCP: {
-		struct tcphdr _tcph, *th;
+		struct tcphdr _tcph;
+		const struct tcphdr *th;
 
 		/* Max length: 10 "PROTO=TCP " */
 		printk("PROTO=TCP ");
@@ -250,7 +250,8 @@
 
 		if ((logflags & IP6T_LOG_TCPOPT)
 		    && th->doff * 4 > sizeof(struct tcphdr)) {
-			u_int8_t _opt[60 - sizeof(struct tcphdr)], *op;
+			u_int8_t _opt[60 - sizeof(struct tcphdr)];
+			const u_int8_t *op;
 			unsigned int i;
 			unsigned int optsize = th->doff * 4
 					       - sizeof(struct tcphdr);
@@ -273,7 +274,8 @@
 	}
 	case IPPROTO_UDP:
 	case IPPROTO_UDPLITE: {
-		struct udphdr _udph, *uh;
+		struct udphdr _udph;
+		const struct udphdr *uh;
 
 		if (currenthdr == IPPROTO_UDP)
 			/* Max length: 10 "PROTO=UDP "     */
@@ -298,7 +300,8 @@
 		break;
 	}
 	case IPPROTO_ICMPV6: {
-		struct icmp6hdr _icmp6h, *ic;
+		struct icmp6hdr _icmp6h;
+		const struct icmp6hdr *ic;
 
 		/* Max length: 13 "PROTO=ICMPv6 " */
 		printk("PROTO=ICMPv6 ");
@@ -448,27 +451,27 @@
 }
 
 
-static int ip6t_log_checkentry(const char *tablename,
-			       const void *entry,
-			       const struct xt_target *target,
-			       void *targinfo,
-			       unsigned int hook_mask)
+static bool ip6t_log_checkentry(const char *tablename,
+				const void *entry,
+				const struct xt_target *target,
+				void *targinfo,
+				unsigned int hook_mask)
 {
 	const struct ip6t_log_info *loginfo = targinfo;
 
 	if (loginfo->level >= 8) {
-		DEBUGP("LOG: level %u >= 8\n", loginfo->level);
-		return 0;
+		pr_debug("LOG: level %u >= 8\n", loginfo->level);
+		return false;
 	}
 	if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
-		DEBUGP("LOG: prefix term %i\n",
-		       loginfo->prefix[sizeof(loginfo->prefix)-1]);
-		return 0;
+		pr_debug("LOG: prefix term %i\n",
+			 loginfo->prefix[sizeof(loginfo->prefix)-1]);
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_target ip6t_log_reg = {
+static struct xt_target ip6t_log_reg __read_mostly = {
 	.name 		= "LOG",
 	.family		= AF_INET6,
 	.target 	= ip6t_log_target,
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index cb3d241..2f487cd 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -34,12 +34,6 @@
 MODULE_DESCRIPTION("IP6 tables REJECT target module");
 MODULE_LICENSE("GPL");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Send RST reply */
 static void send_reset(struct sk_buff *oldskb)
 {
@@ -54,7 +48,7 @@
 
 	if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
 	    (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
-		DEBUGP("ip6t_REJECT: addr is not unicast.\n");
+		pr_debug("ip6t_REJECT: addr is not unicast.\n");
 		return;
 	}
 
@@ -62,16 +56,17 @@
 	tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data), &proto);
 
 	if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
-		DEBUGP("ip6t_REJECT: Can't get TCP header.\n");
+		pr_debug("ip6t_REJECT: Can't get TCP header.\n");
 		return;
 	}
 
 	otcplen = oldskb->len - tcphoff;
 
 	/* IP header checks: fragment, too short. */
-	if ((proto != IPPROTO_TCP) || (otcplen < sizeof(struct tcphdr))) {
-		DEBUGP("ip6t_REJECT: proto(%d) != IPPROTO_TCP, or too short. otcplen = %d\n",
-			proto, otcplen);
+	if (proto != IPPROTO_TCP || otcplen < sizeof(struct tcphdr)) {
+		pr_debug("ip6t_REJECT: proto(%d) != IPPROTO_TCP, "
+			 "or too short. otcplen = %d\n",
+			 proto, otcplen);
 		return;
 	}
 
@@ -80,14 +75,14 @@
 
 	/* No RST for RST. */
 	if (otcph.rst) {
-		DEBUGP("ip6t_REJECT: RST is set\n");
+		pr_debug("ip6t_REJECT: RST is set\n");
 		return;
 	}
 
 	/* Check checksum. */
 	if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP,
 			    skb_checksum(oldskb, tcphoff, otcplen, 0))) {
-		DEBUGP("ip6t_REJECT: TCP checksum is invalid\n");
+		pr_debug("ip6t_REJECT: TCP checksum is invalid\n");
 		return;
 	}
 
@@ -159,7 +154,7 @@
 	tcph->check = csum_ipv6_magic(&ipv6_hdr(nskb)->saddr,
 				      &ipv6_hdr(nskb)->daddr,
 				      sizeof(struct tcphdr), IPPROTO_TCP,
-				      csum_partial((char *)tcph,
+				      csum_partial(tcph,
 						   sizeof(struct tcphdr), 0));
 
 	nf_ct_attach(nskb, oldskb);
@@ -186,7 +181,7 @@
 {
 	const struct ip6t_reject_info *reject = targinfo;
 
-	DEBUGP(KERN_DEBUG "%s: medium point\n", __FUNCTION__);
+	pr_debug("%s: medium point\n", __FUNCTION__);
 	/* WARNING: This code causes reentry within ip6tables.
 	   This means that the ip6tables jump stack is now crap.  We
 	   must return an absolute verdict. --RR */
@@ -221,30 +216,30 @@
 	return NF_DROP;
 }
 
-static int check(const char *tablename,
-		 const void *entry,
-		 const struct xt_target *target,
-		 void *targinfo,
-		 unsigned int hook_mask)
+static bool check(const char *tablename,
+		  const void *entry,
+		  const struct xt_target *target,
+		  void *targinfo,
+		  unsigned int hook_mask)
 {
 	const struct ip6t_reject_info *rejinfo = targinfo;
 	const struct ip6t_entry *e = entry;
 
 	if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
 		printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
-		return 0;
+		return false;
 	} else if (rejinfo->with == IP6T_TCP_RESET) {
 		/* Must specify that it's a TCP packet */
 		if (e->ipv6.proto != IPPROTO_TCP
 		    || (e->ipv6.invflags & XT_INV_PROTO)) {
-			DEBUGP("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
-			return 0;
+			printk("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
+			return false;
 		}
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_target ip6t_reject_reg = {
+static struct xt_target ip6t_reject_reg __read_mostly = {
 	.name		= "REJECT",
 	.family		= AF_INET6,
 	.target		= reject6_target,
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index d3c1543..2a25fe25 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -23,25 +23,20 @@
 MODULE_DESCRIPTION("IPv6 AH match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Returns 1 if the spi is matched by the range, 0 otherwise */
-static inline int
-spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
+static inline bool
+spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 {
-	int r=0;
-	DEBUGP("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
-	       min,spi,max);
+	bool r;
+
+	pr_debug("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",
+		 invert ? '!' : ' ', min, spi, max);
 	r = (spi >= min && spi <= max) ^ invert;
-	DEBUGP(" result %s\n",r? "PASS\n" : "FAILED\n");
+	pr_debug(" result %s\n", r ? "PASS" : "FAILED");
 	return r;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -49,9 +44,10 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
-	struct ip_auth_hdr *ah, _ah;
+	struct ip_auth_hdr _ah;
+	const struct ip_auth_hdr *ah;
 	const struct ip6t_ah *ahinfo = matchinfo;
 	unsigned int ptr;
 	unsigned int hdrlen = 0;
@@ -60,40 +56,40 @@
 	err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
 	if (err < 0) {
 		if (err != -ENOENT)
-			*hotdrop = 1;
-		return 0;
+			*hotdrop = true;
+		return false;
 	}
 
 	ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
 	if (ah == NULL) {
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	hdrlen = (ah->hdrlen + 2) << 2;
 
-	DEBUGP("IPv6 AH LEN %u %u ", hdrlen, ah->hdrlen);
-	DEBUGP("RES %04X ", ah->reserved);
-	DEBUGP("SPI %u %08X\n", ntohl(ah->spi), ntohl(ah->spi));
+	pr_debug("IPv6 AH LEN %u %u ", hdrlen, ah->hdrlen);
+	pr_debug("RES %04X ", ah->reserved);
+	pr_debug("SPI %u %08X\n", ntohl(ah->spi), ntohl(ah->spi));
 
-	DEBUGP("IPv6 AH spi %02X ",
-	       (spi_match(ahinfo->spis[0], ahinfo->spis[1],
-			  ntohl(ah->spi),
-			  !!(ahinfo->invflags & IP6T_AH_INV_SPI))));
-	DEBUGP("len %02X %04X %02X ",
-	       ahinfo->hdrlen, hdrlen,
-	       (!ahinfo->hdrlen ||
-		(ahinfo->hdrlen == hdrlen) ^
-		!!(ahinfo->invflags & IP6T_AH_INV_LEN)));
-	DEBUGP("res %02X %04X %02X\n",
-	       ahinfo->hdrres, ah->reserved,
-	       !(ahinfo->hdrres && ah->reserved));
+	pr_debug("IPv6 AH spi %02X ",
+		 spi_match(ahinfo->spis[0], ahinfo->spis[1],
+			   ntohl(ah->spi),
+			   !!(ahinfo->invflags & IP6T_AH_INV_SPI)));
+	pr_debug("len %02X %04X %02X ",
+		 ahinfo->hdrlen, hdrlen,
+		 (!ahinfo->hdrlen ||
+		  (ahinfo->hdrlen == hdrlen) ^
+		  !!(ahinfo->invflags & IP6T_AH_INV_LEN)));
+	pr_debug("res %02X %04X %02X\n",
+		 ahinfo->hdrres, ah->reserved,
+		 !(ahinfo->hdrres && ah->reserved));
 
 	return (ah != NULL)
 	       &&
-	       (spi_match(ahinfo->spis[0], ahinfo->spis[1],
-			  ntohl(ah->spi),
-			  !!(ahinfo->invflags & IP6T_AH_INV_SPI)))
+	       spi_match(ahinfo->spis[0], ahinfo->spis[1],
+			 ntohl(ah->spi),
+			 !!(ahinfo->invflags & IP6T_AH_INV_SPI))
 	       &&
 	       (!ahinfo->hdrlen ||
 		(ahinfo->hdrlen == hdrlen) ^
@@ -103,7 +99,7 @@
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
 	  const void *entry,
 	  const struct xt_match *match,
@@ -113,13 +109,13 @@
 	const struct ip6t_ah *ahinfo = matchinfo;
 
 	if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
-		DEBUGP("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
-		return 0;
+		pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_match ah_match = {
+static struct xt_match ah_match __read_mostly = {
 	.name		= "ah",
 	.family		= AF_INET6,
 	.match		= match,
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index 0f3dd93..34ba150 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -19,7 +19,7 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -27,16 +27,16 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	unsigned char eui64[8];
 	int i = 0;
 
 	if (!(skb_mac_header(skb) >= skb->head &&
-	      (skb_mac_header(skb) + ETH_HLEN) <= skb->data) &&
+	      skb_mac_header(skb) + ETH_HLEN <= skb->data) &&
 	    offset != 0) {
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	memset(eui64, 0, sizeof(eui64));
@@ -50,19 +50,19 @@
 			eui64[0] |= 0x02;
 
 			i = 0;
-			while ((ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i])
-			       && (i < 8))
+			while (ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i]
+			       && i < 8)
 				i++;
 
 			if (i == 8)
-				return 1;
+				return true;
 		}
 	}
 
-	return 0;
+	return false;
 }
 
-static struct xt_match eui64_match = {
+static struct xt_match eui64_match __read_mostly = {
 	.name		= "eui64",
 	.family		= AF_INET6,
 	.match		= match,
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index 5a5da71..968aeba 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -22,25 +22,19 @@
 MODULE_DESCRIPTION("IPv6 FRAG match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Returns 1 if the id is matched by the range, 0 otherwise */
-static inline int
-id_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
+static inline bool
+id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
 {
-	int r = 0;
-	DEBUGP("frag id_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
-	       min, id, max);
+	bool r;
+	pr_debug("frag id_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
+		 min, id, max);
 	r = (id >= min && id <= max) ^ invert;
-	DEBUGP(" result %s\n", r ? "PASS" : "FAILED");
+	pr_debug(" result %s\n", r ? "PASS" : "FAILED");
 	return r;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -48,9 +42,10 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
-	struct frag_hdr _frag, *fh;
+	struct frag_hdr _frag;
+	const struct frag_hdr *fh;
 	const struct ip6t_frag *fraginfo = matchinfo;
 	unsigned int ptr;
 	int err;
@@ -58,53 +53,53 @@
 	err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
 	if (err < 0) {
 		if (err != -ENOENT)
-			*hotdrop = 1;
-		return 0;
+			*hotdrop = true;
+		return false;
 	}
 
 	fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
 	if (fh == NULL) {
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
-	DEBUGP("INFO %04X ", fh->frag_off);
-	DEBUGP("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7);
-	DEBUGP("RES %02X %04X", fh->reserved, ntohs(fh->frag_off) & 0x6);
-	DEBUGP("MF %04X ", fh->frag_off & htons(IP6_MF));
-	DEBUGP("ID %u %08X\n", ntohl(fh->identification),
-	       ntohl(fh->identification));
+	pr_debug("INFO %04X ", fh->frag_off);
+	pr_debug("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7);
+	pr_debug("RES %02X %04X", fh->reserved, ntohs(fh->frag_off) & 0x6);
+	pr_debug("MF %04X ", fh->frag_off & htons(IP6_MF));
+	pr_debug("ID %u %08X\n", ntohl(fh->identification),
+		 ntohl(fh->identification));
 
-	DEBUGP("IPv6 FRAG id %02X ",
-	       (id_match(fraginfo->ids[0], fraginfo->ids[1],
-			 ntohl(fh->identification),
-			 !!(fraginfo->invflags & IP6T_FRAG_INV_IDS))));
-	DEBUGP("res %02X %02X%04X %02X ",
-	       (fraginfo->flags & IP6T_FRAG_RES), fh->reserved,
-	       ntohs(fh->frag_off) & 0x6,
-	       !((fraginfo->flags & IP6T_FRAG_RES)
-		 && (fh->reserved || (ntohs(fh->frag_off) & 0x06))));
-	DEBUGP("first %02X %02X %02X ",
-	       (fraginfo->flags & IP6T_FRAG_FST),
-	       ntohs(fh->frag_off) & ~0x7,
-	       !((fraginfo->flags & IP6T_FRAG_FST)
-		 && (ntohs(fh->frag_off) & ~0x7)));
-	DEBUGP("mf %02X %02X %02X ",
-	       (fraginfo->flags & IP6T_FRAG_MF),
-	       ntohs(fh->frag_off) & IP6_MF,
-	       !((fraginfo->flags & IP6T_FRAG_MF)
-		 && !((ntohs(fh->frag_off) & IP6_MF))));
-	DEBUGP("last %02X %02X %02X\n",
-	       (fraginfo->flags & IP6T_FRAG_NMF),
-	       ntohs(fh->frag_off) & IP6_MF,
-	       !((fraginfo->flags & IP6T_FRAG_NMF)
-		 && (ntohs(fh->frag_off) & IP6_MF)));
+	pr_debug("IPv6 FRAG id %02X ",
+		 id_match(fraginfo->ids[0], fraginfo->ids[1],
+			  ntohl(fh->identification),
+			  !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)));
+	pr_debug("res %02X %02X%04X %02X ",
+		 fraginfo->flags & IP6T_FRAG_RES, fh->reserved,
+		 ntohs(fh->frag_off) & 0x6,
+		 !((fraginfo->flags & IP6T_FRAG_RES)
+		   && (fh->reserved || (ntohs(fh->frag_off) & 0x06))));
+	pr_debug("first %02X %02X %02X ",
+		 fraginfo->flags & IP6T_FRAG_FST,
+		 ntohs(fh->frag_off) & ~0x7,
+		 !((fraginfo->flags & IP6T_FRAG_FST)
+		   && (ntohs(fh->frag_off) & ~0x7)));
+	pr_debug("mf %02X %02X %02X ",
+		 fraginfo->flags & IP6T_FRAG_MF,
+		 ntohs(fh->frag_off) & IP6_MF,
+		 !((fraginfo->flags & IP6T_FRAG_MF)
+		   && !((ntohs(fh->frag_off) & IP6_MF))));
+	pr_debug("last %02X %02X %02X\n",
+		 fraginfo->flags & IP6T_FRAG_NMF,
+		 ntohs(fh->frag_off) & IP6_MF,
+		 !((fraginfo->flags & IP6T_FRAG_NMF)
+		   && (ntohs(fh->frag_off) & IP6_MF)));
 
 	return (fh != NULL)
 	       &&
-	       (id_match(fraginfo->ids[0], fraginfo->ids[1],
-			 ntohl(fh->identification),
-			 !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)))
+	       id_match(fraginfo->ids[0], fraginfo->ids[1],
+			ntohl(fh->identification),
+			!!(fraginfo->invflags & IP6T_FRAG_INV_IDS))
 	       &&
 	       !((fraginfo->flags & IP6T_FRAG_RES)
 		 && (fh->reserved || (ntohs(fh->frag_off) & 0x6)))
@@ -120,7 +115,7 @@
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *ip,
 	   const struct xt_match *match,
@@ -130,13 +125,13 @@
 	const struct ip6t_frag *fraginfo = matchinfo;
 
 	if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
-		DEBUGP("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
-		return 0;
+		pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_match frag_match = {
+static struct xt_match frag_match __read_mostly = {
 	.name		= "frag",
 	.family		= AF_INET6,
 	.match		= match,
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index d2373c7..e6ca601 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -25,12 +25,6 @@
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 MODULE_ALIAS("ip6t_dst");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /*
  *  (Type & 0xC0) >> 6
  *	0	-> ignorable
@@ -47,7 +41,7 @@
  *	5	-> RTALERT 2 x x
  */
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -55,45 +49,48 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
-	struct ipv6_opt_hdr _optsh, *oh;
+	struct ipv6_opt_hdr _optsh;
+	const struct ipv6_opt_hdr *oh;
 	const struct ip6t_opts *optinfo = matchinfo;
 	unsigned int temp;
 	unsigned int ptr;
 	unsigned int hdrlen = 0;
-	unsigned int ret = 0;
-	u8 _opttype, *tp = NULL;
-	u8 _optlen, *lp = NULL;
+	bool ret = false;
+	u8 _opttype;
+	u8 _optlen;
+	const u_int8_t *tp = NULL;
+	const u_int8_t *lp = NULL;
 	unsigned int optlen;
 	int err;
 
 	err = ipv6_find_hdr(skb, &ptr, match->data, NULL);
 	if (err < 0) {
 		if (err != -ENOENT)
-			*hotdrop = 1;
-		return 0;
+			*hotdrop = true;
+		return false;
 	}
 
 	oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
 	if (oh == NULL) {
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	hdrlen = ipv6_optlen(oh);
 	if (skb->len - ptr < hdrlen) {
 		/* Packet smaller than it's length field */
-		return 0;
+		return false;
 	}
 
-	DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
+	pr_debug("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
 
-	DEBUGP("len %02X %04X %02X ",
-	       optinfo->hdrlen, hdrlen,
-	       (!(optinfo->flags & IP6T_OPTS_LEN) ||
-		((optinfo->hdrlen == hdrlen) ^
-		 !!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
+	pr_debug("len %02X %04X %02X ",
+		 optinfo->hdrlen, hdrlen,
+		 (!(optinfo->flags & IP6T_OPTS_LEN) ||
+		  ((optinfo->hdrlen == hdrlen) ^
+		   !!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
 
 	ret = (oh != NULL) &&
 	      (!(optinfo->flags & IP6T_OPTS_LEN) ||
@@ -105,10 +102,10 @@
 	if (!(optinfo->flags & IP6T_OPTS_OPTS)) {
 		return ret;
 	} else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
-		DEBUGP("Not strict - not implemented");
+		pr_debug("Not strict - not implemented");
 	} else {
-		DEBUGP("Strict ");
-		DEBUGP("#%d ", optinfo->optsnr);
+		pr_debug("Strict ");
+		pr_debug("#%d ", optinfo->optsnr);
 		for (temp = 0; temp < optinfo->optsnr; temp++) {
 			/* type field exists ? */
 			if (hdrlen < 1)
@@ -120,12 +117,11 @@
 
 			/* Type check */
 			if (*tp != (optinfo->opts[temp] & 0xFF00) >> 8) {
-				DEBUGP("Tbad %02X %02X\n",
-				       *tp,
-				       (optinfo->opts[temp] & 0xFF00) >> 8);
-				return 0;
+				pr_debug("Tbad %02X %02X\n", *tp,
+					 (optinfo->opts[temp] & 0xFF00) >> 8);
+				return false;
 			} else {
-				DEBUGP("Tok ");
+				pr_debug("Tok ");
 			}
 			/* Length check */
 			if (*tp) {
@@ -142,23 +138,23 @@
 				spec_len = optinfo->opts[temp] & 0x00FF;
 
 				if (spec_len != 0x00FF && spec_len != *lp) {
-					DEBUGP("Lbad %02X %04X\n", *lp,
-					       spec_len);
-					return 0;
+					pr_debug("Lbad %02X %04X\n", *lp,
+						 spec_len);
+					return false;
 				}
-				DEBUGP("Lok ");
+				pr_debug("Lok ");
 				optlen = *lp + 2;
 			} else {
-				DEBUGP("Pad1\n");
+				pr_debug("Pad1\n");
 				optlen = 1;
 			}
 
 			/* Step to the next */
-			DEBUGP("len%04X \n", optlen);
+			pr_debug("len%04X \n", optlen);
 
 			if ((ptr > skb->len - optlen || hdrlen < optlen) &&
-			    (temp < optinfo->optsnr - 1)) {
-				DEBUGP("new pointer is too large! \n");
+			    temp < optinfo->optsnr - 1) {
+				pr_debug("new pointer is too large! \n");
 				break;
 			}
 			ptr += optlen;
@@ -167,14 +163,14 @@
 		if (temp == optinfo->optsnr)
 			return ret;
 		else
-			return 0;
+			return false;
 	}
 
-	return 0;
+	return false;
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *entry,
 	   const struct xt_match *match,
@@ -184,13 +180,13 @@
 	const struct ip6t_opts *optsinfo = matchinfo;
 
 	if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
-		DEBUGP("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
-		return 0;
+		pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_match opts_match[] = {
+static struct xt_match opts_match[] __read_mostly = {
 	{
 		.name		= "hbh",
 		.family		= AF_INET6,
diff --git a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c
index d606c0e..ca29ec0 100644
--- a/net/ipv6/netfilter/ip6t_hl.c
+++ b/net/ipv6/netfilter/ip6t_hl.c
@@ -19,37 +19,37 @@
 MODULE_DESCRIPTION("IP tables Hop Limit matching module");
 MODULE_LICENSE("GPL");
 
-static int match(const struct sk_buff *skb,
-		 const struct net_device *in, const struct net_device *out,
-		 const struct xt_match *match, const void *matchinfo,
-		 int offset, unsigned int protoff, int *hotdrop)
+static bool match(const struct sk_buff *skb,
+		  const struct net_device *in, const struct net_device *out,
+		  const struct xt_match *match, const void *matchinfo,
+		  int offset, unsigned int protoff, bool *hotdrop)
 {
 	const struct ip6t_hl_info *info = matchinfo;
 	const struct ipv6hdr *ip6h = ipv6_hdr(skb);
 
 	switch (info->mode) {
 		case IP6T_HL_EQ:
-			return (ip6h->hop_limit == info->hop_limit);
+			return ip6h->hop_limit == info->hop_limit;
 			break;
 		case IP6T_HL_NE:
-			return (!(ip6h->hop_limit == info->hop_limit));
+			return ip6h->hop_limit != info->hop_limit;
 			break;
 		case IP6T_HL_LT:
-			return (ip6h->hop_limit < info->hop_limit);
+			return ip6h->hop_limit < info->hop_limit;
 			break;
 		case IP6T_HL_GT:
-			return (ip6h->hop_limit > info->hop_limit);
+			return ip6h->hop_limit > info->hop_limit;
 			break;
 		default:
 			printk(KERN_WARNING "ip6t_hl: unknown mode %d\n",
 				info->mode);
-			return 0;
+			return false;
 	}
 
-	return 0;
+	return false;
 }
 
-static struct xt_match hl_match = {
+static struct xt_match hl_match __read_mostly = {
 	.name		= "hl",
 	.family		= AF_INET6,
 	.match		= match,
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c
index fd6a086..2c65c2f 100644
--- a/net/ipv6/netfilter/ip6t_ipv6header.c
+++ b/net/ipv6/netfilter/ip6t_ipv6header.c
@@ -26,7 +26,7 @@
 MODULE_DESCRIPTION("IPv6 headers match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
-static int
+static bool
 ipv6header_match(const struct sk_buff *skb,
 		 const struct net_device *in,
 		 const struct net_device *out,
@@ -34,7 +34,7 @@
 		 const void *matchinfo,
 		 int offset,
 		 unsigned int protoff,
-		 int *hotdrop)
+		 bool *hotdrop)
 {
 	const struct ip6t_ipv6header_info *info = matchinfo;
 	unsigned int temp;
@@ -58,7 +58,7 @@
 
 		/* Is there enough space for the next ext header? */
 		if (len < (int)sizeof(struct ipv6_opt_hdr))
-			return 0;
+			return false;
 		/* No more exthdr -> evaluate */
 		if (nexthdr == NEXTHDR_NONE) {
 			temp |= MASK_NONE;
@@ -74,9 +74,9 @@
 		BUG_ON(hp == NULL);
 
 		/* Calculate the header length */
-		if (nexthdr == NEXTHDR_FRAGMENT) {
+		if (nexthdr == NEXTHDR_FRAGMENT)
 			hdrlen = 8;
-		} else if (nexthdr == NEXTHDR_AUTH)
+		else if (nexthdr == NEXTHDR_AUTH)
 			hdrlen = (hp->hdrlen + 2) << 2;
 		else
 			hdrlen = ipv6_optlen(hp);
@@ -99,7 +99,7 @@
 			temp |= MASK_DSTOPTS;
 			break;
 		default:
-			return 0;
+			return false;
 			break;
 		}
 
@@ -110,7 +110,7 @@
 			break;
 	}
 
-	if ((nexthdr != NEXTHDR_NONE) && (nexthdr != NEXTHDR_ESP))
+	if (nexthdr != NEXTHDR_NONE && nexthdr != NEXTHDR_ESP)
 		temp |= MASK_PROTO;
 
 	if (info->modeflag)
@@ -124,7 +124,7 @@
 	}
 }
 
-static int
+static bool
 ipv6header_checkentry(const char *tablename,
 		      const void *ip,
 		      const struct xt_match *match,
@@ -136,12 +136,12 @@
 	/* invflags is 0 or 0xff in hard mode */
 	if ((!info->modeflag) && info->invflags != 0x00 &&
 	    info->invflags != 0xFF)
-		return 0;
+		return false;
 
-	return 1;
+	return true;
 }
 
-static struct xt_match ip6t_ipv6header_match = {
+static struct xt_match ip6t_ipv6header_match __read_mostly = {
 	.name		= "ipv6header",
 	.family		= AF_INET6,
 	.match		= &ipv6header_match,
diff --git a/net/ipv6/netfilter/ip6t_mh.c b/net/ipv6/netfilter/ip6t_mh.c
index c2a9098..0fa7140 100644
--- a/net/ipv6/netfilter/ip6t_mh.c
+++ b/net/ipv6/netfilter/ip6t_mh.c
@@ -31,16 +31,13 @@
 #endif
 
 /* Returns 1 if the type is matched by the range, 0 otherwise */
-static inline int
-type_match(u_int8_t min, u_int8_t max, u_int8_t type, int invert)
+static inline bool
+type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
 {
-	int ret;
-
-	ret = (type >= min && type <= max) ^ invert;
-	return ret;
+	return (type >= min && type <= max) ^ invert;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
 	 const struct net_device *in,
 	 const struct net_device *out,
@@ -48,29 +45,30 @@
 	 const void *matchinfo,
 	 int offset,
 	 unsigned int protoff,
-	 int *hotdrop)
+	 bool *hotdrop)
 {
-	struct ip6_mh _mh, *mh;
+	struct ip6_mh _mh;
+	const struct ip6_mh *mh;
 	const struct ip6t_mh *mhinfo = matchinfo;
 
 	/* Must not be a fragment. */
 	if (offset)
-		return 0;
+		return false;
 
 	mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh);
 	if (mh == NULL) {
 		/* We've been asked to examine this packet, and we
 		   can't.  Hence, no choice but to drop. */
 		duprintf("Dropping evil MH tinygram.\n");
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	if (mh->ip6mh_proto != IPPROTO_NONE) {
 		duprintf("Dropping invalid MH Payload Proto: %u\n",
 			 mh->ip6mh_proto);
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	return type_match(mhinfo->types[0], mhinfo->types[1], mh->ip6mh_type,
@@ -78,7 +76,7 @@
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 mh_checkentry(const char *tablename,
 	      const void *entry,
 	      const struct xt_match *match,
@@ -91,7 +89,7 @@
 	return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
 }
 
-static struct xt_match mh_match = {
+static struct xt_match mh_match __read_mostly = {
 	.name		= "mh",
 	.family		= AF_INET6,
 	.checkentry	= mh_checkentry,
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
index 43738bb..6036613 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -23,7 +23,7 @@
 MODULE_LICENSE("GPL");
 
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -31,29 +31,27 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct ip6t_owner_info *info = matchinfo;
 
 	if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
-		return 0;
+		return false;
 
-	if (info->match & IP6T_OWNER_UID) {
+	if (info->match & IP6T_OWNER_UID)
 		if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
 		    !!(info->invert & IP6T_OWNER_UID))
-			return 0;
-	}
+			return false;
 
-	if (info->match & IP6T_OWNER_GID) {
+	if (info->match & IP6T_OWNER_GID)
 		if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
 		    !!(info->invert & IP6T_OWNER_GID))
-			return 0;
-	}
+			return false;
 
-	return 1;
+	return true;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *ip,
 	   const struct xt_match *match,
@@ -65,12 +63,12 @@
 	if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
 		printk("ipt_owner: pid and sid matching "
 		       "not supported anymore\n");
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_match owner_match = {
+static struct xt_match owner_match __read_mostly = {
 	.name		= "owner",
 	.family		= AF_INET6,
 	.match		= match,
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index 81ab00d..357cea7 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -24,25 +24,19 @@
 MODULE_DESCRIPTION("IPv6 RT match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Returns 1 if the id is matched by the range, 0 otherwise */
-static inline int
-segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert)
+static inline bool
+segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
 {
-	int r = 0;
-	DEBUGP("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x",
-	       invert ? '!' : ' ', min, id, max);
+	bool r;
+	pr_debug("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x",
+		 invert ? '!' : ' ', min, id, max);
 	r = (id >= min && id <= max) ^ invert;
-	DEBUGP(" result %s\n", r ? "PASS" : "FAILED");
+	pr_debug(" result %s\n", r ? "PASS" : "FAILED");
 	return r;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -50,59 +44,61 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
-	struct ipv6_rt_hdr _route, *rh;
+	struct ipv6_rt_hdr _route;
+	const struct ipv6_rt_hdr *rh;
 	const struct ip6t_rt *rtinfo = matchinfo;
 	unsigned int temp;
 	unsigned int ptr;
 	unsigned int hdrlen = 0;
-	unsigned int ret = 0;
-	struct in6_addr *ap, _addr;
+	bool ret = false;
+	struct in6_addr _addr;
+	const struct in6_addr *ap;
 	int err;
 
 	err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
 	if (err < 0) {
 		if (err != -ENOENT)
-			*hotdrop = 1;
-		return 0;
+			*hotdrop = true;
+		return false;
 	}
 
 	rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
 	if (rh == NULL) {
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	hdrlen = ipv6_optlen(rh);
 	if (skb->len - ptr < hdrlen) {
 		/* Pcket smaller than its length field */
-		return 0;
+		return false;
 	}
 
-	DEBUGP("IPv6 RT LEN %u %u ", hdrlen, rh->hdrlen);
-	DEBUGP("TYPE %04X ", rh->type);
-	DEBUGP("SGS_LEFT %u %02X\n", rh->segments_left, rh->segments_left);
+	pr_debug("IPv6 RT LEN %u %u ", hdrlen, rh->hdrlen);
+	pr_debug("TYPE %04X ", rh->type);
+	pr_debug("SGS_LEFT %u %02X\n", rh->segments_left, rh->segments_left);
 
-	DEBUGP("IPv6 RT segsleft %02X ",
-	       (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
-			       rh->segments_left,
-			       !!(rtinfo->invflags & IP6T_RT_INV_SGS))));
-	DEBUGP("type %02X %02X %02X ",
-	       rtinfo->rt_type, rh->type,
-	       (!(rtinfo->flags & IP6T_RT_TYP) ||
-		((rtinfo->rt_type == rh->type) ^
-		 !!(rtinfo->invflags & IP6T_RT_INV_TYP))));
-	DEBUGP("len %02X %04X %02X ",
-	       rtinfo->hdrlen, hdrlen,
-	       (!(rtinfo->flags & IP6T_RT_LEN) ||
-		((rtinfo->hdrlen == hdrlen) ^
-		 !!(rtinfo->invflags & IP6T_RT_INV_LEN))));
-	DEBUGP("res %02X %02X %02X ",
-	       (rtinfo->flags & IP6T_RT_RES),
-	       ((struct rt0_hdr *)rh)->reserved,
-	       !((rtinfo->flags & IP6T_RT_RES) &&
-		 (((struct rt0_hdr *)rh)->reserved)));
+	pr_debug("IPv6 RT segsleft %02X ",
+		 segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
+				rh->segments_left,
+				!!(rtinfo->invflags & IP6T_RT_INV_SGS)));
+	pr_debug("type %02X %02X %02X ",
+		 rtinfo->rt_type, rh->type,
+		 (!(rtinfo->flags & IP6T_RT_TYP) ||
+		  ((rtinfo->rt_type == rh->type) ^
+		   !!(rtinfo->invflags & IP6T_RT_INV_TYP))));
+	pr_debug("len %02X %04X %02X ",
+		 rtinfo->hdrlen, hdrlen,
+		 !(rtinfo->flags & IP6T_RT_LEN) ||
+		  ((rtinfo->hdrlen == hdrlen) ^
+		   !!(rtinfo->invflags & IP6T_RT_INV_LEN)));
+	pr_debug("res %02X %02X %02X ",
+		 rtinfo->flags & IP6T_RT_RES,
+		 ((const struct rt0_hdr *)rh)->reserved,
+		 !((rtinfo->flags & IP6T_RT_RES) &&
+		   (((const struct rt0_hdr *)rh)->reserved)));
 
 	ret = (rh != NULL)
 	      &&
@@ -129,18 +125,18 @@
 		ret = (*rp == 0);
 	}
 
-	DEBUGP("#%d ", rtinfo->addrnr);
+	pr_debug("#%d ", rtinfo->addrnr);
 	if (!(rtinfo->flags & IP6T_RT_FST)) {
 		return ret;
 	} else if (rtinfo->flags & IP6T_RT_FST_NSTRICT) {
-		DEBUGP("Not strict ");
+		pr_debug("Not strict ");
 		if (rtinfo->addrnr > (unsigned int)((hdrlen - 8) / 16)) {
-			DEBUGP("There isn't enough space\n");
-			return 0;
+			pr_debug("There isn't enough space\n");
+			return false;
 		} else {
 			unsigned int i = 0;
 
-			DEBUGP("#%d ", rtinfo->addrnr);
+			pr_debug("#%d ", rtinfo->addrnr);
 			for (temp = 0;
 			     temp < (unsigned int)((hdrlen - 8) / 16);
 			     temp++) {
@@ -154,25 +150,25 @@
 				BUG_ON(ap == NULL);
 
 				if (ipv6_addr_equal(ap, &rtinfo->addrs[i])) {
-					DEBUGP("i=%d temp=%d;\n", i, temp);
+					pr_debug("i=%d temp=%d;\n", i, temp);
 					i++;
 				}
 				if (i == rtinfo->addrnr)
 					break;
 			}
-			DEBUGP("i=%d #%d\n", i, rtinfo->addrnr);
+			pr_debug("i=%d #%d\n", i, rtinfo->addrnr);
 			if (i == rtinfo->addrnr)
 				return ret;
 			else
-				return 0;
+				return false;
 		}
 	} else {
-		DEBUGP("Strict ");
+		pr_debug("Strict ");
 		if (rtinfo->addrnr > (unsigned int)((hdrlen - 8) / 16)) {
-			DEBUGP("There isn't enough space\n");
-			return 0;
+			pr_debug("There isn't enough space\n");
+			return false;
 		} else {
-			DEBUGP("#%d ", rtinfo->addrnr);
+			pr_debug("#%d ", rtinfo->addrnr);
 			for (temp = 0; temp < rtinfo->addrnr; temp++) {
 				ap = skb_header_pointer(skb,
 							ptr
@@ -185,20 +181,20 @@
 				if (!ipv6_addr_equal(ap, &rtinfo->addrs[temp]))
 					break;
 			}
-			DEBUGP("temp=%d #%d\n", temp, rtinfo->addrnr);
-			if ((temp == rtinfo->addrnr) &&
-			    (temp == (unsigned int)((hdrlen - 8) / 16)))
+			pr_debug("temp=%d #%d\n", temp, rtinfo->addrnr);
+			if (temp == rtinfo->addrnr &&
+			    temp == (unsigned int)((hdrlen - 8) / 16))
 				return ret;
 			else
-				return 0;
+				return false;
 		}
 	}
 
-	return 0;
+	return false;
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *entry,
 	   const struct xt_match *match,
@@ -208,21 +204,21 @@
 	const struct ip6t_rt *rtinfo = matchinfo;
 
 	if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
-		DEBUGP("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
-		return 0;
+		pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
+		return false;
 	}
 	if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) &&
 	    (!(rtinfo->flags & IP6T_RT_TYP) ||
 	     (rtinfo->rt_type != 0) ||
 	     (rtinfo->invflags & IP6T_RT_INV_TYP))) {
-		DEBUGP("`--rt-type 0' required before `--rt-0-*'");
-		return 0;
+		pr_debug("`--rt-type 0' required before `--rt-0-*'");
+		return false;
 	}
 
-	return 1;
+	return true;
 }
 
-static struct xt_match rt_match = {
+static struct xt_match rt_match __read_mostly = {
 	.name		= "rt",
 	.family		= AF_INET6,
 	.match		= match,
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index f2d2649..f0a9efa 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -21,12 +21,6 @@
 			    (1 << NF_IP6_LOCAL_OUT) | \
 			    (1 << NF_IP6_POST_ROUTING))
 
-#if 0
-#define DEBUGP(x, args...)	printk(KERN_DEBUG x, ## args)
-#else
-#define DEBUGP(x, args...)
-#endif
-
 static struct
 {
 	struct ip6t_replace repl;
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 0acda45..ec290e4 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -8,12 +8,6 @@
 
 #define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
 
-#if 0
-#define DEBUGP(x, args...)	printk(KERN_DEBUG x, ## args)
-#else
-#define DEBUGP(x, args...)
-#endif
-
 static struct
 {
 	struct ip6t_replace repl;
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 1b1797f..89e20ab 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -26,12 +26,6 @@
 #include <net/netfilter/nf_conntrack_l3proto.h>
 #include <net/netfilter/nf_conntrack_core.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
 			     struct nf_conntrack_tuple *tuple)
 {
@@ -136,7 +130,7 @@
 	 * except of IPv6 & ext headers. but it's tracked anyway. - YK
 	 */
 	if ((protoff < 0) || (protoff > (*pskb)->len)) {
-		DEBUGP("ip6_conntrack_core: can't find proto in pkt\n");
+		pr_debug("ip6_conntrack_core: can't find proto in pkt\n");
 		NF_CT_STAT_INC_ATOMIC(error);
 		NF_CT_STAT_INC_ATOMIC(invalid);
 		return -NF_ACCEPT;
@@ -147,11 +141,6 @@
 	return NF_ACCEPT;
 }
 
-static u_int32_t ipv6_get_features(const struct nf_conntrack_tuple *tuple)
-{
-	return NF_CT_F_BASIC;
-}
-
 static unsigned int ipv6_confirm(unsigned int hooknum,
 				 struct sk_buff **pskb,
 				 const struct net_device *in,
@@ -183,7 +172,7 @@
 	protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
 					 (*pskb)->len - extoff);
 	if (protoff > (*pskb)->len || pnum == NEXTHDR_FRAGMENT) {
-		DEBUGP("proto header not found\n");
+		pr_debug("proto header not found\n");
 		return NF_ACCEPT;
 	}
 
@@ -397,7 +386,6 @@
 	.ctl_table_path		= nf_net_netfilter_sysctl_path,
 	.ctl_table		= nf_ct_ipv6_sysctl_table,
 #endif
-	.get_features		= ipv6_get_features,
 	.me			= THIS_MODULE,
 };
 
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 8814b95..9defc7e 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -27,12 +27,6 @@
 
 static unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ;
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static int icmpv6_pkt_to_tuple(const struct sk_buff *skb,
 			       unsigned int dataoff,
 			       struct nf_conntrack_tuple *tuple)
@@ -125,8 +119,8 @@
 
 	if (type < 0 || type >= sizeof(valid_new) || !valid_new[type]) {
 		/* Can't create a new ICMPv6 `conn' with this. */
-		DEBUGP("icmpv6: can't create new conn with type %u\n",
-		       type + 128);
+		pr_debug("icmpv6: can't create new conn with type %u\n",
+			 type + 128);
 		NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
 		return 0;
 	}
@@ -152,14 +146,15 @@
 
 	hp = skb_header_pointer(skb, icmp6off, sizeof(_hdr), &_hdr);
 	if (hp == NULL) {
-		DEBUGP("icmpv6_error: Can't get ICMPv6 hdr.\n");
+		pr_debug("icmpv6_error: Can't get ICMPv6 hdr.\n");
 		return -NF_ACCEPT;
 	}
 
 	inip6off = icmp6off + sizeof(_hdr);
 	if (skb_copy_bits(skb, inip6off+offsetof(struct ipv6hdr, nexthdr),
 			  &inprotonum, sizeof(inprotonum)) != 0) {
-		DEBUGP("icmpv6_error: Can't get nexthdr in inner IPv6 header.\n");
+		pr_debug("icmpv6_error: Can't get nexthdr in inner IPv6 "
+			 "header.\n");
 		return -NF_ACCEPT;
 	}
 	inprotoff = nf_ct_ipv6_skip_exthdr(skb,
@@ -169,7 +164,8 @@
 						    - sizeof(struct ipv6hdr));
 
 	if ((inprotoff > skb->len) || (inprotonum == NEXTHDR_FRAGMENT)) {
-		DEBUGP("icmpv6_error: Can't get protocol header in ICMPv6 payload.\n");
+		pr_debug("icmpv6_error: Can't get protocol header in ICMPv6 "
+			 "payload.\n");
 		return -NF_ACCEPT;
 	}
 
@@ -179,7 +175,7 @@
 	/* Are they talking about one of our connections? */
 	if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum,
 			     &origtuple, &nf_conntrack_l3proto_ipv6, inproto)) {
-		DEBUGP("icmpv6_error: Can't get tuple\n");
+		pr_debug("icmpv6_error: Can't get tuple\n");
 		return -NF_ACCEPT;
 	}
 
@@ -187,15 +183,15 @@
 	   been preserved inside the ICMP. */
 	if (!nf_ct_invert_tuple(&intuple, &origtuple,
 				&nf_conntrack_l3proto_ipv6, inproto)) {
-		DEBUGP("icmpv6_error: Can't invert tuple\n");
+		pr_debug("icmpv6_error: Can't invert tuple\n");
 		return -NF_ACCEPT;
 	}
 
 	*ctinfo = IP_CT_RELATED;
 
-	h = nf_conntrack_find_get(&intuple, NULL);
+	h = nf_conntrack_find_get(&intuple);
 	if (!h) {
-		DEBUGP("icmpv6_error: no match\n");
+		pr_debug("icmpv6_error: no match\n");
 		return -NF_ACCEPT;
 	} else {
 		if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 347ab76..25442a8 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -44,12 +44,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 #define NF_CT_FRAG6_HIGH_THRESH 262144 /* == 256*1024 */
 #define NF_CT_FRAG6_LOW_THRESH 196608  /* == 192*1024 */
 #define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
@@ -343,7 +337,7 @@
 	struct nf_ct_frag6_queue *fq;
 
 	if ((fq = frag_alloc_queue()) == NULL) {
-		DEBUGP("Can't alloc new queue\n");
+		pr_debug("Can't alloc new queue\n");
 		goto oom;
 	}
 
@@ -393,7 +387,7 @@
 	int offset, end;
 
 	if (fq->last_in & COMPLETE) {
-		DEBUGP("Allready completed\n");
+		pr_debug("Allready completed\n");
 		goto err;
 	}
 
@@ -402,7 +396,7 @@
 			((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
 
 	if ((unsigned int)end > IPV6_MAXPLEN) {
-		DEBUGP("offset is too large.\n");
+		pr_debug("offset is too large.\n");
 		return -1;
 	}
 
@@ -420,7 +414,7 @@
 		 */
 		if (end < fq->len ||
 		    ((fq->last_in & LAST_IN) && end != fq->len)) {
-			DEBUGP("already received last fragment\n");
+			pr_debug("already received last fragment\n");
 			goto err;
 		}
 		fq->last_in |= LAST_IN;
@@ -433,13 +427,13 @@
 			/* RFC2460 says always send parameter problem in
 			 * this case. -DaveM
 			 */
-			DEBUGP("the end of this fragment is not rounded to 8 bytes.\n");
+			pr_debug("end of fragment not rounded to 8 bytes.\n");
 			return -1;
 		}
 		if (end > fq->len) {
 			/* Some bits beyond end -> corruption. */
 			if (fq->last_in & LAST_IN) {
-				DEBUGP("last packet already reached.\n");
+				pr_debug("last packet already reached.\n");
 				goto err;
 			}
 			fq->len = end;
@@ -451,11 +445,11 @@
 
 	/* Point into the IP datagram 'data' part. */
 	if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) {
-		DEBUGP("queue: message is too short.\n");
+		pr_debug("queue: message is too short.\n");
 		goto err;
 	}
 	if (pskb_trim_rcsum(skb, end - offset)) {
-		DEBUGP("Can't trim\n");
+		pr_debug("Can't trim\n");
 		goto err;
 	}
 
@@ -480,11 +474,11 @@
 		if (i > 0) {
 			offset += i;
 			if (end <= offset) {
-				DEBUGP("overlap\n");
+				pr_debug("overlap\n");
 				goto err;
 			}
 			if (!pskb_pull(skb, i)) {
-				DEBUGP("Can't pull\n");
+				pr_debug("Can't pull\n");
 				goto err;
 			}
 			if (skb->ip_summed != CHECKSUM_UNNECESSARY)
@@ -503,7 +497,7 @@
 			/* Eat head of the next overlapped fragment
 			 * and leave the loop. The next ones cannot overlap.
 			 */
-			DEBUGP("Eat head of the overlapped parts.: %d", i);
+			pr_debug("Eat head of the overlapped parts.: %d", i);
 			if (!pskb_pull(next, i))
 				goto err;
 
@@ -586,13 +580,13 @@
 		       sizeof(struct ipv6hdr) + fq->len -
 		       sizeof(struct frag_hdr));
 	if (payload_len > IPV6_MAXPLEN) {
-		DEBUGP("payload len is too large.\n");
+		pr_debug("payload len is too large.\n");
 		goto out_oversize;
 	}
 
 	/* Head of list must not be cloned. */
 	if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) {
-		DEBUGP("skb is cloned but can't expand head");
+		pr_debug("skb is cloned but can't expand head");
 		goto out_oom;
 	}
 
@@ -604,7 +598,7 @@
 		int i, plen = 0;
 
 		if ((clone = alloc_skb(0, GFP_ATOMIC)) == NULL) {
-			DEBUGP("Can't alloc skb\n");
+			pr_debug("Can't alloc skb\n");
 			goto out_oom;
 		}
 		clone->next = head->next;
@@ -719,11 +713,11 @@
 			return -1;
 		}
 		if (len < (int)sizeof(struct ipv6_opt_hdr)) {
-			DEBUGP("too short\n");
+			pr_debug("too short\n");
 			return -1;
 		}
 		if (nexthdr == NEXTHDR_NONE) {
-			DEBUGP("next header is none\n");
+			pr_debug("next header is none\n");
 			return -1;
 		}
 		if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
@@ -764,7 +758,7 @@
 
 	/* Jumbo payload inhibits frag. header */
 	if (ipv6_hdr(skb)->payload_len == 0) {
-		DEBUGP("payload len = 0\n");
+		pr_debug("payload len = 0\n");
 		return skb;
 	}
 
@@ -773,14 +767,14 @@
 
 	clone = skb_clone(skb, GFP_ATOMIC);
 	if (clone == NULL) {
-		DEBUGP("Can't clone skb\n");
+		pr_debug("Can't clone skb\n");
 		return skb;
 	}
 
 	NFCT_FRAG6_CB(clone)->orig = skb;
 
 	if (!pskb_may_pull(clone, fhoff + sizeof(*fhdr))) {
-		DEBUGP("message is too short.\n");
+		pr_debug("message is too short.\n");
 		goto ret_orig;
 	}
 
@@ -789,7 +783,7 @@
 	fhdr = (struct frag_hdr *)skb_transport_header(clone);
 
 	if (!(fhdr->frag_off & htons(0xFFF9))) {
-		DEBUGP("Invalid fragment offset\n");
+		pr_debug("Invalid fragment offset\n");
 		/* It is not a fragmented frame */
 		goto ret_orig;
 	}
@@ -799,7 +793,7 @@
 
 	fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr);
 	if (fq == NULL) {
-		DEBUGP("Can't find and can't create new queue\n");
+		pr_debug("Can't find and can't create new queue\n");
 		goto ret_orig;
 	}
 
@@ -807,7 +801,7 @@
 
 	if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) {
 		spin_unlock(&fq->lock);
-		DEBUGP("Can't insert skb to queue\n");
+		pr_debug("Can't insert skb to queue\n");
 		fq_put(fq, NULL);
 		goto ret_orig;
 	}
@@ -815,7 +809,7 @@
 	if (fq->last_in == (FIRST_IN|LAST_IN) && fq->meat == fq->len) {
 		ret_skb = nf_ct_frag6_reasm(fq, dev);
 		if (ret_skb == NULL)
-			DEBUGP("Can't reassemble fragmented packets\n");
+			pr_debug("Can't reassemble fragmented packets\n");
 	}
 	spin_unlock(&fq->lock);
 
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index a58459a..e27383d 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -49,7 +49,7 @@
 #include <net/udp.h>
 #include <net/inet_common.h>
 #include <net/tcp_states.h>
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 #include <net/mip6.h>
 #endif
 
@@ -137,6 +137,28 @@
 	return 0;
 }
 
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+static int (*mh_filter)(struct sock *sock, struct sk_buff *skb);
+
+int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
+					   struct sk_buff *skb))
+{
+	rcu_assign_pointer(mh_filter, filter);
+	return 0;
+}
+EXPORT_SYMBOL(rawv6_mh_filter_register);
+
+int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock,
+					     struct sk_buff *skb))
+{
+	rcu_assign_pointer(mh_filter, NULL);
+	synchronize_rcu();
+	return 0;
+}
+EXPORT_SYMBOL(rawv6_mh_filter_unregister);
+
+#endif
+
 /*
  *	demultiplex raw sockets.
  *	(should consider queueing the skb in the sock receive_queue
@@ -178,16 +200,22 @@
 		case IPPROTO_ICMPV6:
 			filtered = icmpv6_filter(sk, skb);
 			break;
-#ifdef CONFIG_IPV6_MIP6
+
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 		case IPPROTO_MH:
+		{
 			/* XXX: To validate MH only once for each packet,
 			 * this is placed here. It should be after checking
 			 * xfrm policy, however it doesn't. The checking xfrm
 			 * policy is placed in rawv6_rcv() because it is
 			 * required for each socket.
 			 */
-			filtered = mip6_mh_filter(sk, skb);
+			int (*filter)(struct sock *sock, struct sk_buff *skb);
+
+			filter = rcu_dereference(mh_filter);
+			filtered = filter ? filter(sk, skb) : 0;
 			break;
+		}
 #endif
 		default:
 			filtered = 0;
@@ -611,9 +639,7 @@
 	struct iovec *iov;
 	u8 __user *type = NULL;
 	u8 __user *code = NULL;
-#ifdef CONFIG_IPV6_MIP6
 	u8 len = 0;
-#endif
 	int probed = 0;
 	int i;
 
@@ -646,7 +672,6 @@
 				probed = 1;
 			}
 			break;
-#ifdef CONFIG_IPV6_MIP6
 		case IPPROTO_MH:
 			if (iov->iov_base && iov->iov_len < 1)
 				break;
@@ -660,7 +685,6 @@
 				len += iov->iov_len;
 
 			break;
-#endif
 		default:
 			probed = 1;
 			break;
@@ -1256,7 +1280,7 @@
 	return 0;
 }
 
-static struct seq_operations raw6_seq_ops = {
+static const struct seq_operations raw6_seq_ops = {
 	.start =	raw6_seq_start,
 	.next =		raw6_seq_next,
 	.stop =		raw6_seq_stop,
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 1efa95a..eb20bb6 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -532,7 +532,8 @@
 	 */
 	max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr);
 
-	if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
+	if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
+	    (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
 		struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
 		if (!new_skb) {
 			ip_rt_put(rt);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 193d9d6..d67fb1e 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -484,17 +484,6 @@
 
 	if (dst == NULL) {
 		opt = np->opt;
-		if (opt == NULL &&
-		    np->rxopt.bits.osrcrt == 2 &&
-		    treq->pktopts) {
-			struct sk_buff *pktopts = treq->pktopts;
-			struct inet6_skb_parm *rxopt = IP6CB(pktopts);
-			if (rxopt->srcrt)
-				opt = ipv6_invert_rthdr(sk,
-			  (struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
-						 rxopt->srcrt));
-		}
-
 		if (opt && opt->srcrt) {
 			struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
 			ipv6_addr_copy(&final, &fl.fl6_dst);
@@ -1391,15 +1380,6 @@
 	if (sk_acceptq_is_full(sk))
 		goto out_overflow;
 
-	if (np->rxopt.bits.osrcrt == 2 &&
-	    opt == NULL && treq->pktopts) {
-		struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
-		if (rxopt->srcrt)
-			opt = ipv6_invert_rthdr(sk,
-		   (struct ipv6_rt_hdr *)(skb_network_header(treq->pktopts) +
-					  rxopt->srcrt));
-	}
-
 	if (dst == NULL) {
 		struct in6_addr *final_p = NULL, final;
 		struct flowi fl;
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 1faa2ea..3ec0c47 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -18,7 +18,7 @@
 #include <net/ip.h>
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 #include <net/mip6.h>
 #endif
 
@@ -318,7 +318,7 @@
 			fl->proto = nexthdr;
 			return;
 
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 		case IPPROTO_MH:
 			if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
 				struct ip6_mh *mh;
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index baa461b..cdadb48 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -65,7 +65,7 @@
 		goto end;
 
 	/* Rule 2: select MIPv6 RO or inbound trigger */
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 	for (i = 0; i < n; i++) {
 		if (src[i] &&
 		    (src[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION ||
@@ -130,7 +130,7 @@
 		goto end;
 
 	/* Rule 2: select MIPv6 RO or inbound trigger */
-#ifdef CONFIG_IPV6_MIP6
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 	for (i = 0; i < n; i++) {
 		if (src[i] &&
 		    (src[i]->mode == XFRM_MODE_ROUTEOPTIMIZATION ||
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 5502cc94..6f87dd5 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -379,3 +379,4 @@
 module_init(xfrm6_tunnel_init);
 module_exit(xfrm6_tunnel_fini);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_IPV6);
diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c
index db32ac8..4226e71 100644
--- a/net/ipx/ipx_proc.c
+++ b/net/ipx/ipx_proc.c
@@ -286,21 +286,21 @@
 	return 0;
 }
 
-static struct seq_operations ipx_seq_interface_ops = {
+static const struct seq_operations ipx_seq_interface_ops = {
 	.start  = ipx_seq_interface_start,
 	.next   = ipx_seq_interface_next,
 	.stop   = ipx_seq_interface_stop,
 	.show   = ipx_seq_interface_show,
 };
 
-static struct seq_operations ipx_seq_route_ops = {
+static const struct seq_operations ipx_seq_route_ops = {
 	.start  = ipx_seq_route_start,
 	.next   = ipx_seq_route_next,
 	.stop   = ipx_seq_route_stop,
 	.show   = ipx_seq_route_show,
 };
 
-static struct seq_operations ipx_seq_socket_ops = {
+static const struct seq_operations ipx_seq_socket_ops = {
 	.start  = ipx_seq_socket_start,
 	.next   = ipx_seq_socket_next,
 	.stop   = ipx_seq_interface_stop,
diff --git a/net/irda/Makefile b/net/irda/Makefile
index d1366c2..187f6c5 100644
--- a/net/irda/Makefile
+++ b/net/irda/Makefile
@@ -10,6 +10,6 @@
 irda-y := iriap.o iriap_event.o irlmp.o irlmp_event.o irlmp_frame.o \
           irlap.o irlap_event.o irlap_frame.o timer.o qos.o irqueue.o \
           irttp.o irda_device.o irias_object.o wrapper.o af_irda.o \
-	  discovery.o parameters.o irmod.o
+	  discovery.o parameters.o irnetlink.o irmod.o
 irda-$(CONFIG_PROC_FS) += irproc.o
 irda-$(CONFIG_SYSCTL) += irsysctl.o
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
index f097341..af0cea7 100644
--- a/net/irda/discovery.c
+++ b/net/irda/discovery.c
@@ -395,7 +395,7 @@
 	return 0;
 }
 
-static struct seq_operations discovery_seq_ops = {
+static const struct seq_operations discovery_seq_ops = {
 	.start  = discovery_seq_start,
 	.next   = discovery_seq_next,
 	.stop   = discovery_seq_stop,
diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c
index 4749f8f..2d63fa8 100644
--- a/net/irda/ircomm/ircomm_core.c
+++ b/net/irda/ircomm/ircomm_core.c
@@ -562,7 +562,7 @@
 	return 0;
 }
 
-static struct seq_operations ircomm_seq_ops = {
+static const struct seq_operations ircomm_seq_ops = {
 	.start  = ircomm_seq_start,
 	.next   = ircomm_seq_next,
 	.stop   = ircomm_seq_stop,
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index 915d938..774eb70 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -1066,7 +1066,7 @@
 	return 0;
 }
 
-static struct seq_operations irias_seq_ops = {
+static const struct seq_operations irias_seq_ops = {
 	.start  = irias_seq_start,
 	.next   = irias_seq_next,
 	.stop   = irias_seq_stop,
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
index ed69773..f5778ef 100644
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -1217,7 +1217,7 @@
 	return 0;
 }
 
-static struct seq_operations irlan_seq_ops = {
+static const struct seq_operations irlan_seq_ops = {
 	.start = irlan_seq_start,
 	.next  = irlan_seq_next,
 	.stop  = irlan_seq_stop,
diff --git a/net/irda/irlap.c b/net/irda/irlap.c
index d93ebd1..2fc9f51 100644
--- a/net/irda/irlap.c
+++ b/net/irda/irlap.c
@@ -1210,7 +1210,7 @@
 	return 0;
 }
 
-static struct seq_operations irlap_seq_ops = {
+static const struct seq_operations irlap_seq_ops = {
 	.start  = irlap_seq_start,
 	.next   = irlap_seq_next,
 	.stop   = irlap_seq_stop,
diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
index 3013c49a..25a3444 100644
--- a/net/irda/irlap_frame.c
+++ b/net/irda/irlap_frame.c
@@ -101,6 +101,13 @@
 
 	irlap_insert_info(self, skb);
 
+	if (unlikely(self->mode & IRDA_MODE_MONITOR)) {
+		IRDA_DEBUG(3, "%s(): %s is in monitor mode\n", __FUNCTION__,
+			   self->netdev->name);
+		dev_kfree_skb(skb);
+		return;
+	}
+
 	dev_queue_xmit(skb);
 }
 
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
index 9df0461..24a5e3f 100644
--- a/net/irda/irlmp.c
+++ b/net/irda/irlmp.c
@@ -1994,7 +1994,7 @@
 	return 0;
 }
 
-static struct seq_operations irlmp_seq_ops = {
+static const struct seq_operations irlmp_seq_ops = {
 	.start  = irlmp_seq_start,
 	.next   = irlmp_seq_next,
 	.stop   = irlmp_seq_stop,
diff --git a/net/irda/irmod.c b/net/irda/irmod.c
index c7fad2c..1900937 100644
--- a/net/irda/irmod.c
+++ b/net/irda/irmod.c
@@ -88,16 +88,23 @@
  */
 static int __init irda_init(void)
 {
+	int ret = 0;
+
 	IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
 
 	/* Lower layer of the stack */
 	irlmp_init();
 	irlap_init();
 
+	/* Driver/dongle support */
+	irda_device_init();
+
 	/* Higher layers of the stack */
 	iriap_init();
 	irttp_init();
-	irsock_init();
+	ret = irsock_init();
+	if (ret < 0)
+		goto out_err_1;
 
 	/* Add IrDA packet type (Start receiving packets) */
 	dev_add_pack(&irda_packet_type);
@@ -107,13 +114,44 @@
 	irda_proc_register();
 #endif
 #ifdef CONFIG_SYSCTL
-	irda_sysctl_register();
+	ret = irda_sysctl_register();
+	if (ret < 0)
+		goto out_err_2;
 #endif
 
-	/* Driver/dongle support */
-	irda_device_init();
+	ret = irda_nl_register();
+	if (ret < 0)
+		goto out_err_3;
 
 	return 0;
+
+ out_err_3:
+#ifdef CONFIG_SYSCTL
+	irda_sysctl_unregister();
+#endif
+ out_err_2:
+#ifdef CONFIG_PROC_FS
+	irda_proc_unregister();
+#endif
+
+	/* Remove IrDA packet type (stop receiving packets) */
+	dev_remove_pack(&irda_packet_type);
+
+	/* Remove higher layers */
+	irsock_cleanup();
+ out_err_1:
+	irttp_cleanup();
+	iriap_cleanup();
+
+	/* Remove lower layers */
+	irda_device_cleanup();
+	irlap_cleanup(); /* Must be done before irlmp_cleanup()! DB */
+
+	/* Remove middle layer */
+	irlmp_cleanup();
+
+
+	return ret;
 }
 
 /*
@@ -125,6 +163,8 @@
 static void __exit irda_cleanup(void)
 {
 	/* Remove External APIs */
+	irda_nl_unregister();
+
 #ifdef CONFIG_SYSCTL
 	irda_sysctl_unregister();
 #endif
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c
new file mode 100644
index 0000000..db71658
--- /dev/null
+++ b/net/irda/irnetlink.c
@@ -0,0 +1,170 @@
+/*
+ * IrDA netlink layer, for stack configuration.
+ *
+ * Copyright (c) 2007 Samuel Ortiz <samuel@sortiz>
+ *
+ * Partly based on the 802.11 nelink implementation
+ * (see net/wireless/nl80211.c) which is:
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/socket.h>
+#include <linux/irda.h>
+#include <net/sock.h>
+#include <net/irda/irda.h>
+#include <net/irda/irlap.h>
+#include <net/genetlink.h>
+
+
+
+static struct genl_family irda_nl_family = {
+	.id = GENL_ID_GENERATE,
+	.name = IRDA_NL_NAME,
+	.hdrsize = 0,
+	.version = IRDA_NL_VERSION,
+	.maxattr = IRDA_NL_CMD_MAX,
+};
+
+static struct net_device * ifname_to_netdev(struct genl_info *info)
+{
+	char * ifname;
+
+	if (!info->attrs[IRDA_NL_ATTR_IFNAME])
+		return NULL;
+
+	ifname = nla_data(info->attrs[IRDA_NL_ATTR_IFNAME]);
+
+	IRDA_DEBUG(5, "%s(): Looking for %s\n", __FUNCTION__, ifname);
+
+	return dev_get_by_name(ifname);
+}
+
+static int irda_nl_set_mode(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net_device * dev;
+	struct irlap_cb * irlap;
+	u32 mode;
+
+	if (!info->attrs[IRDA_NL_ATTR_MODE])
+		return -EINVAL;
+
+	mode = nla_get_u32(info->attrs[IRDA_NL_ATTR_MODE]);
+
+	IRDA_DEBUG(5, "%s(): Switching to mode: %d\n", __FUNCTION__, mode);
+
+	dev = ifname_to_netdev(info);
+	if (!dev)
+		return -ENODEV;
+
+	irlap = (struct irlap_cb *)dev->atalk_ptr;
+	if (!irlap) {
+		dev_put(dev);
+		return -ENODEV;
+	}
+
+	irlap->mode = mode;
+
+	dev_put(dev);
+
+	return 0;
+}
+
+static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info)
+{
+	struct net_device * dev;
+	struct irlap_cb * irlap;
+	struct sk_buff *msg;
+	void *hdr;
+	int ret = -ENOBUFS;
+
+	dev = ifname_to_netdev(info);
+	if (!dev)
+		return -ENODEV;
+
+	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!msg) {
+		dev_put(dev);
+		return -ENOMEM;
+	}
+
+	irlap = (struct irlap_cb *)dev->atalk_ptr;
+	if (!irlap) {
+		ret = -ENODEV;
+		goto err_out;
+	}
+
+	hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
+			  &irda_nl_family, 0,  IRDA_NL_CMD_GET_MODE);
+	if (IS_ERR(hdr)) {
+		ret = PTR_ERR(hdr);
+		goto err_out;
+	}
+
+	if(nla_put_string(msg, IRDA_NL_ATTR_IFNAME,
+			  dev->name));
+		goto err_out;
+
+	if(nla_put_u32(msg, IRDA_NL_ATTR_MODE, irlap->mode))
+		goto err_out;
+
+	genlmsg_end(msg, hdr);
+
+	return genlmsg_unicast(msg, info->snd_pid);
+
+ err_out:
+	nlmsg_free(msg);
+	dev_put(dev);
+
+	return ret;
+}
+
+static struct nla_policy irda_nl_policy[IRDA_NL_ATTR_MAX + 1] = {
+	[IRDA_NL_ATTR_IFNAME] = { .type = NLA_NUL_STRING,
+				  .len = IFNAMSIZ-1 },
+	[IRDA_NL_ATTR_MODE] = { .type = NLA_U32 },
+};
+
+static struct genl_ops irda_nl_ops[] = {
+	{
+		.cmd = IRDA_NL_CMD_SET_MODE,
+		.doit = irda_nl_set_mode,
+		.policy = irda_nl_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = IRDA_NL_CMD_GET_MODE,
+		.doit = irda_nl_get_mode,
+		.policy = irda_nl_policy,
+		/* can be retrieved by unprivileged users */
+	},
+
+};
+
+int irda_nl_register(void)
+{
+	int err, i;
+
+	err = genl_register_family(&irda_nl_family);
+	if (err)
+		return err;
+
+	for (i = 0; i < ARRAY_SIZE(irda_nl_ops); i++) {
+		err = genl_register_ops(&irda_nl_family, &irda_nl_ops[i]);
+		if (err)
+			goto err_out;
+	}
+	return 0;
+ err_out:
+	genl_unregister_family(&irda_nl_family);
+	return err;
+}
+
+void irda_nl_unregister(void)
+{
+	genl_unregister_family(&irda_nl_family);
+}
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
index 7069e4a..7f50832a 100644
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -369,6 +369,20 @@
 /* Everything is happily mixed up. Waiting for next clean up - Jean II */
 
 /*
+ * Initialization, that has to be done on new tsap
+ * instance allocation and on duplication
+ */
+static void irttp_init_tsap(struct tsap_cb *tsap)
+{
+	spin_lock_init(&tsap->lock);
+	init_timer(&tsap->todo_timer);
+
+	skb_queue_head_init(&tsap->rx_queue);
+	skb_queue_head_init(&tsap->tx_queue);
+	skb_queue_head_init(&tsap->rx_fragments);
+}
+
+/*
  * Function irttp_open_tsap (stsap, notify)
  *
  *    Create TSAP connection endpoint,
@@ -395,10 +409,11 @@
 		IRDA_DEBUG(0, "%s(), unable to kmalloc!\n", __FUNCTION__);
 		return NULL;
 	}
-	spin_lock_init(&self->lock);
+
+	/* Initialize internal objects */
+	irttp_init_tsap(self);
 
 	/* Initialise todo timer */
-	init_timer(&self->todo_timer);
 	self->todo_timer.data     = (unsigned long) self;
 	self->todo_timer.function = &irttp_todo_expired;
 
@@ -418,9 +433,6 @@
 	self->magic = TTP_TSAP_MAGIC;
 	self->connected = FALSE;
 
-	skb_queue_head_init(&self->rx_queue);
-	skb_queue_head_init(&self->tx_queue);
-	skb_queue_head_init(&self->rx_fragments);
 	/*
 	 *  Create LSAP at IrLMP layer
 	 */
@@ -1455,12 +1467,9 @@
 
 	/* Not everything should be copied */
 	new->notify.instance = instance;
-	spin_lock_init(&new->lock);
-	init_timer(&new->todo_timer);
 
-	skb_queue_head_init(&new->rx_queue);
-	skb_queue_head_init(&new->tx_queue);
-	skb_queue_head_init(&new->rx_fragments);
+	/* Initialize internal objects */
+	irttp_init_tsap(new);
 
 	/* This is locked */
 	hashbin_insert(irttp->tsaps, (irda_queue_t *) new, (long) new, NULL);
@@ -1866,7 +1875,7 @@
 	return 0;
 }
 
-static struct seq_operations irttp_seq_ops = {
+static const struct seq_operations irttp_seq_ops = {
 	.start  = irttp_seq_start,
 	.next   = irttp_seq_next,
 	.stop   = irttp_seq_stop,
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c
index 3ab9d9f..49be6c9 100644
--- a/net/llc/llc_proc.c
+++ b/net/llc/llc_proc.c
@@ -184,14 +184,14 @@
 	return 0;
 }
 
-static struct seq_operations llc_seq_socket_ops = {
+static const struct seq_operations llc_seq_socket_ops = {
 	.start  = llc_seq_start,
 	.next   = llc_seq_next,
 	.stop   = llc_seq_stop,
 	.show   = llc_seq_socket_show,
 };
 
-static struct seq_operations llc_seq_core_ops = {
+static const struct seq_operations llc_seq_core_ops = {
 	.start  = llc_seq_start,
 	.next   = llc_seq_next,
 	.stop   = llc_seq_stop,
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index 352f03b..66e8a97 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -838,6 +838,29 @@
 }
 
 
+static int ieee80211_ioctl_giwrate(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_param *rate, char *extra)
+{
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+	struct sta_info *sta;
+	struct ieee80211_sub_if_data *sdata;
+
+	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	if (sdata->type == IEEE80211_IF_TYPE_STA)
+		sta = sta_info_get(local, sdata->u.sta.bssid);
+	else
+		return -EOPNOTSUPP;
+	if (!sta)
+		return -ENODEV;
+	if (sta->txrate < local->oper_hw_mode->num_rates)
+		rate->value = local->oper_hw_mode->rates[sta->txrate].rate * 100000;
+	else
+		rate->value = 0;
+	sta_info_put(sta);
+	return 0;
+}
+
 static int ieee80211_ioctl_siwrts(struct net_device *dev,
 				  struct iw_request_info *info,
 				  struct iw_param *rts, char *extra)
@@ -1779,7 +1802,7 @@
 	(iw_handler) NULL,				/* -- hole -- */
 	(iw_handler) NULL,				/* -- hole -- */
 	(iw_handler) NULL,				/* SIOCSIWRATE */
-	(iw_handler) NULL,				/* SIOCGIWRATE */
+	(iw_handler) ieee80211_ioctl_giwrate,		/* SIOCGIWRATE */
 	(iw_handler) ieee80211_ioctl_siwrts,		/* SIOCSIWRTS */
 	(iw_handler) ieee80211_ioctl_giwrts,		/* SIOCGIWRTS */
 	(iw_handler) ieee80211_ioctl_siwfrag,		/* SIOCSIWFRAG */
diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c
index 2048cfd..5ae7fc4 100644
--- a/net/mac80211/rc80211_simple.c
+++ b/net/mac80211/rc80211_simple.c
@@ -283,14 +283,16 @@
 	int i;
 	sta->txrate = 0;
 	mode = local->oper_hw_mode;
-	/* TODO: what is a good starting rate for STA? About middle? Maybe not
-	 * the lowest or the highest rate.. Could consider using RSSI from
-	 * previous packets? Need to have IEEE 802.1X auth succeed immediately
-	 * after assoc.. */
+	/* TODO: This routine should consider using RSSI from previous packets
+	 * as we need to have IEEE 802.1X auth succeed immediately after assoc..
+	 * Until that method is implemented, we will use the lowest supported rate
+	 * as a workaround, */
 	for (i = 0; i < mode->num_rates; i++) {
 		if ((sta->supp_rates & BIT(i)) &&
-		    (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED))
+		    (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) {
 			sta->txrate = i;
+			break;
+		}
 	}
 }
 
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index a567dae..df5e8da 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -343,6 +343,18 @@
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
+config NETFILTER_XT_TARGET_TRACE
+	tristate  '"TRACE" target support'
+	depends on NETFILTER_XTABLES
+	depends on IP_NF_RAW || IP6_NF_RAW
+	help
+	  The TRACE target allows you to mark packets so that the kernel
+	  will log every rule which match the packets as those traverse
+	  the tables, chains, rules.
+
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
 config NETFILTER_XT_TARGET_SECMARK
 	tristate '"SECMARK" target support'
 	depends on NETFILTER_XTABLES && NETWORK_SECMARK
@@ -635,6 +647,19 @@
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_MATCH_U32
+	tristate '"u32" match support'
+	depends on NETFILTER_XTABLES
+	---help---
+	  u32 allows you to extract quantities of up to 4 bytes from a packet,
+	  AND them with specified masks, shift them by specified amounts and
+	  test whether the results are in any of a set of specified ranges.
+	  The specification of what to extract is general enough to skip over
+	  headers with lengths stored in the packet, as in IP or TCP header
+	  lengths.
+
+	  Details and examples are in the kernel module source.
+
 config NETFILTER_XT_MATCH_HASHLIMIT
 	tristate '"hashlimit" match support'
 	depends on NETFILTER_XTABLES && (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index b2b5c75..58b4245 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -1,6 +1,6 @@
 netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o
 
-nf_conntrack-y	:= nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o
+nf_conntrack-y	:= nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o
 nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
 
 obj-$(CONFIG_NETFILTER) = netfilter.o
@@ -44,6 +44,7 @@
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
@@ -72,4 +73,5 @@
 obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index a84478e..381a77c 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -203,7 +203,9 @@
 		return 0;
 
 	/* Not exclusive use of packet?  Must copy. */
-	if (skb_shared(*pskb) || skb_cloned(*pskb))
+	if (skb_cloned(*pskb) && !skb_clone_writable(*pskb, writable_len))
+		goto copy_skb;
+	if (skb_shared(*pskb))
 		goto copy_skb;
 
 	return pskb_may_pull(*pskb, writable_len);
@@ -229,13 +231,13 @@
 {
 	__be32 diff[] = { ~from, to };
 	if (skb->ip_summed != CHECKSUM_PARTIAL) {
-		*sum = csum_fold(csum_partial((char *)diff, sizeof(diff),
+		*sum = csum_fold(csum_partial(diff, sizeof(diff),
 				~csum_unfold(*sum)));
 		if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
-			skb->csum = ~csum_partial((char *)diff, sizeof(diff),
+			skb->csum = ~csum_partial(diff, sizeof(diff),
 						~skb->csum);
 	} else if (pseudohdr)
-		*sum = ~csum_fold(csum_partial((char *)diff, sizeof(diff),
+		*sum = ~csum_fold(csum_partial(diff, sizeof(diff),
 				csum_unfold(*sum)));
 }
 EXPORT_SYMBOL(nf_proto_csum_replace4);
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index 0568f2e86..e42ab23 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -142,23 +142,22 @@
 		if (port == 0 || len > 5)
 			break;
 
-		exp = nf_conntrack_expect_alloc(ct);
+		exp = nf_ct_expect_alloc(ct);
 		if (exp == NULL) {
 			ret = NF_DROP;
 			goto out;
 		}
 		tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
-		nf_conntrack_expect_init(exp, family,
-					 &tuple->src.u3, &tuple->dst.u3,
-					 IPPROTO_TCP, NULL, &port);
+		nf_ct_expect_init(exp, family, &tuple->src.u3, &tuple->dst.u3,
+				  IPPROTO_TCP, NULL, &port);
 
 		nf_nat_amanda = rcu_dereference(nf_nat_amanda_hook);
 		if (nf_nat_amanda && ct->status & IPS_NAT_MASK)
 			ret = nf_nat_amanda(pskb, ctinfo, off - dataoff,
 					    len, exp);
-		else if (nf_conntrack_expect_related(exp) != 0)
+		else if (nf_ct_expect_related(exp) != 0)
 			ret = NF_DROP;
-		nf_conntrack_expect_put(exp);
+		nf_ct_expect_put(exp);
 	}
 
 out:
@@ -175,9 +174,6 @@
 		.tuple.src.l3num	= AF_INET,
 		.tuple.src.u.udp.port	= __constant_htons(10080),
 		.tuple.dst.protonum	= IPPROTO_UDP,
-		.mask.src.l3num		= 0xFFFF,
-		.mask.src.u.udp.port	= __constant_htons(0xFFFF),
-		.mask.dst.protonum	= 0xFF,
 	},
 	{
 		.name			= "amanda",
@@ -188,9 +184,6 @@
 		.tuple.src.l3num	= AF_INET6,
 		.tuple.src.u.udp.port	= __constant_htons(10080),
 		.tuple.dst.protonum	= IPPROTO_UDP,
-		.mask.src.l3num		= 0xFFFF,
-		.mask.src.u.udp.port	= __constant_htons(0xFFFF),
-		.mask.dst.protonum	= 0xFF,
 	},
 };
 
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 7a15e30..3d14110 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -36,15 +36,10 @@
 #include <net/netfilter/nf_conntrack_expect.h>
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_extend.h>
 
 #define NF_CONNTRACK_VERSION	"0.5.0"
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 DEFINE_RWLOCK(nf_conntrack_lock);
 EXPORT_SYMBOL_GPL(nf_conntrack_lock);
 
@@ -52,57 +47,27 @@
 atomic_t nf_conntrack_count = ATOMIC_INIT(0);
 EXPORT_SYMBOL_GPL(nf_conntrack_count);
 
-void (*nf_conntrack_destroyed)(struct nf_conn *conntrack);
-EXPORT_SYMBOL_GPL(nf_conntrack_destroyed);
-
 unsigned int nf_conntrack_htable_size __read_mostly;
 EXPORT_SYMBOL_GPL(nf_conntrack_htable_size);
 
 int nf_conntrack_max __read_mostly;
 EXPORT_SYMBOL_GPL(nf_conntrack_max);
 
-struct list_head *nf_conntrack_hash __read_mostly;
+struct hlist_head *nf_conntrack_hash __read_mostly;
 EXPORT_SYMBOL_GPL(nf_conntrack_hash);
 
 struct nf_conn nf_conntrack_untracked __read_mostly;
 EXPORT_SYMBOL_GPL(nf_conntrack_untracked);
 
 unsigned int nf_ct_log_invalid __read_mostly;
-LIST_HEAD(unconfirmed);
+HLIST_HEAD(unconfirmed);
 static int nf_conntrack_vmalloc __read_mostly;
-
+static struct kmem_cache *nf_conntrack_cachep __read_mostly;
 static unsigned int nf_conntrack_next_id;
 
 DEFINE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
 EXPORT_PER_CPU_SYMBOL(nf_conntrack_stat);
 
-/*
- * This scheme offers various size of "struct nf_conn" dependent on
- * features(helper, nat, ...)
- */
-
-#define NF_CT_FEATURES_NAMELEN	256
-static struct {
-	/* name of slab cache. printed in /proc/slabinfo */
-	char *name;
-
-	/* size of slab cache */
-	size_t size;
-
-	/* slab cache pointer */
-	struct kmem_cache *cachep;
-
-	/* allocated slab cache + modules which uses this slab cache */
-	int use;
-
-} nf_ct_cache[NF_CT_F_NUM];
-
-/* protect members of nf_ct_cache except of "use" */
-DEFINE_RWLOCK(nf_ct_cache_lock);
-
-/* This avoids calling kmem_cache_create() with same name simultaneously */
-static DEFINE_MUTEX(nf_ct_cache_mutex);
-
 static int nf_conntrack_hash_rnd_initted;
 static unsigned int nf_conntrack_hash_rnd;
 
@@ -125,122 +90,6 @@
 				nf_conntrack_hash_rnd);
 }
 
-int nf_conntrack_register_cache(u_int32_t features, const char *name,
-				size_t size)
-{
-	int ret = 0;
-	char *cache_name;
-	struct kmem_cache *cachep;
-
-	DEBUGP("nf_conntrack_register_cache: features=0x%x, name=%s, size=%d\n",
-	       features, name, size);
-
-	if (features < NF_CT_F_BASIC || features >= NF_CT_F_NUM) {
-		DEBUGP("nf_conntrack_register_cache: invalid features.: 0x%x\n",
-			features);
-		return -EINVAL;
-	}
-
-	mutex_lock(&nf_ct_cache_mutex);
-
-	write_lock_bh(&nf_ct_cache_lock);
-	/* e.g: multiple helpers are loaded */
-	if (nf_ct_cache[features].use > 0) {
-		DEBUGP("nf_conntrack_register_cache: already resisterd.\n");
-		if ((!strncmp(nf_ct_cache[features].name, name,
-			      NF_CT_FEATURES_NAMELEN))
-		    && nf_ct_cache[features].size == size) {
-			DEBUGP("nf_conntrack_register_cache: reusing.\n");
-			nf_ct_cache[features].use++;
-			ret = 0;
-		} else
-			ret = -EBUSY;
-
-		write_unlock_bh(&nf_ct_cache_lock);
-		mutex_unlock(&nf_ct_cache_mutex);
-		return ret;
-	}
-	write_unlock_bh(&nf_ct_cache_lock);
-
-	/*
-	 * The memory space for name of slab cache must be alive until
-	 * cache is destroyed.
-	 */
-	cache_name = kmalloc(sizeof(char)*NF_CT_FEATURES_NAMELEN, GFP_ATOMIC);
-	if (cache_name == NULL) {
-		DEBUGP("nf_conntrack_register_cache: can't alloc cache_name\n");
-		ret = -ENOMEM;
-		goto out_up_mutex;
-	}
-
-	if (strlcpy(cache_name, name, NF_CT_FEATURES_NAMELEN)
-						>= NF_CT_FEATURES_NAMELEN) {
-		printk("nf_conntrack_register_cache: name too long\n");
-		ret = -EINVAL;
-		goto out_free_name;
-	}
-
-	cachep = kmem_cache_create(cache_name, size, 0, 0,
-				   NULL, NULL);
-	if (!cachep) {
-		printk("nf_conntrack_register_cache: Can't create slab cache "
-		       "for the features = 0x%x\n", features);
-		ret = -ENOMEM;
-		goto out_free_name;
-	}
-
-	write_lock_bh(&nf_ct_cache_lock);
-	nf_ct_cache[features].use = 1;
-	nf_ct_cache[features].size = size;
-	nf_ct_cache[features].cachep = cachep;
-	nf_ct_cache[features].name = cache_name;
-	write_unlock_bh(&nf_ct_cache_lock);
-
-	goto out_up_mutex;
-
-out_free_name:
-	kfree(cache_name);
-out_up_mutex:
-	mutex_unlock(&nf_ct_cache_mutex);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(nf_conntrack_register_cache);
-
-/* FIXME: In the current, only nf_conntrack_cleanup() can call this function. */
-void nf_conntrack_unregister_cache(u_int32_t features)
-{
-	struct kmem_cache *cachep;
-	char *name;
-
-	/*
-	 * This assures that kmem_cache_create() isn't called before destroying
-	 * slab cache.
-	 */
-	DEBUGP("nf_conntrack_unregister_cache: 0x%04x\n", features);
-	mutex_lock(&nf_ct_cache_mutex);
-
-	write_lock_bh(&nf_ct_cache_lock);
-	if (--nf_ct_cache[features].use > 0) {
-		write_unlock_bh(&nf_ct_cache_lock);
-		mutex_unlock(&nf_ct_cache_mutex);
-		return;
-	}
-	cachep = nf_ct_cache[features].cachep;
-	name = nf_ct_cache[features].name;
-	nf_ct_cache[features].cachep = NULL;
-	nf_ct_cache[features].name = NULL;
-	nf_ct_cache[features].size = 0;
-	write_unlock_bh(&nf_ct_cache_lock);
-
-	synchronize_net();
-
-	kmem_cache_destroy(cachep);
-	kfree(name);
-
-	mutex_unlock(&nf_ct_cache_mutex);
-}
-EXPORT_SYMBOL_GPL(nf_conntrack_unregister_cache);
-
 int
 nf_ct_get_tuple(const struct sk_buff *skb,
 		unsigned int nhoff,
@@ -286,9 +135,9 @@
 static void
 clean_from_lists(struct nf_conn *ct)
 {
-	DEBUGP("clean_from_lists(%p)\n", ct);
-	list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
-	list_del(&ct->tuplehash[IP_CT_DIR_REPLY].list);
+	pr_debug("clean_from_lists(%p)\n", ct);
+	hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
+	hlist_del(&ct->tuplehash[IP_CT_DIR_REPLY].hnode);
 
 	/* Destroy all pending expectations */
 	nf_ct_remove_expectations(ct);
@@ -299,9 +148,8 @@
 {
 	struct nf_conn *ct = (struct nf_conn *)nfct;
 	struct nf_conntrack_l4proto *l4proto;
-	typeof(nf_conntrack_destroyed) destroyed;
 
-	DEBUGP("destroy_conntrack(%p)\n", ct);
+	pr_debug("destroy_conntrack(%p)\n", ct);
 	NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
 	NF_CT_ASSERT(!timer_pending(&ct->timeout));
 
@@ -317,9 +165,7 @@
 	if (l4proto && l4proto->destroy)
 		l4proto->destroy(ct);
 
-	destroyed = rcu_dereference(nf_conntrack_destroyed);
-	if (destroyed)
-		destroyed(ct);
+	nf_ct_ext_destroy(ct);
 
 	rcu_read_unlock();
 
@@ -332,8 +178,8 @@
 
 	/* We overload first tuple to link into unconfirmed list. */
 	if (!nf_ct_is_confirmed(ct)) {
-		BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list));
-		list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
+		BUG_ON(hlist_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode));
+		hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
 	}
 
 	NF_CT_STAT_INC(delete);
@@ -342,7 +188,7 @@
 	if (ct->master)
 		nf_ct_put(ct->master);
 
-	DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
+	pr_debug("destroy_conntrack: returning ct=%p to slab\n", ct);
 	nf_conntrack_free(ct);
 }
 
@@ -374,9 +220,10 @@
 		    const struct nf_conn *ignored_conntrack)
 {
 	struct nf_conntrack_tuple_hash *h;
+	struct hlist_node *n;
 	unsigned int hash = hash_conntrack(tuple);
 
-	list_for_each_entry(h, &nf_conntrack_hash[hash], list) {
+	hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) {
 		if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
 		    nf_ct_tuple_equal(tuple, &h->tuple)) {
 			NF_CT_STAT_INC(found);
@@ -391,13 +238,12 @@
 
 /* Find a connection corresponding to a tuple. */
 struct nf_conntrack_tuple_hash *
-nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
-		      const struct nf_conn *ignored_conntrack)
+nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple)
 {
 	struct nf_conntrack_tuple_hash *h;
 
 	read_lock_bh(&nf_conntrack_lock);
-	h = __nf_conntrack_find(tuple, ignored_conntrack);
+	h = __nf_conntrack_find(tuple, NULL);
 	if (h)
 		atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
 	read_unlock_bh(&nf_conntrack_lock);
@@ -411,10 +257,10 @@
 				       unsigned int repl_hash)
 {
 	ct->id = ++nf_conntrack_next_id;
-	list_add(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list,
-		 &nf_conntrack_hash[hash]);
-	list_add(&ct->tuplehash[IP_CT_DIR_REPLY].list,
-		 &nf_conntrack_hash[repl_hash]);
+	hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
+		       &nf_conntrack_hash[hash]);
+	hlist_add_head(&ct->tuplehash[IP_CT_DIR_REPLY].hnode,
+		       &nf_conntrack_hash[repl_hash]);
 }
 
 void nf_conntrack_hash_insert(struct nf_conn *ct)
@@ -438,6 +284,7 @@
 	struct nf_conntrack_tuple_hash *h;
 	struct nf_conn *ct;
 	struct nf_conn_help *help;
+	struct hlist_node *n;
 	enum ip_conntrack_info ctinfo;
 
 	ct = nf_ct_get(*pskb, &ctinfo);
@@ -460,24 +307,24 @@
 	/* No external references means noone else could have
 	   confirmed us. */
 	NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
-	DEBUGP("Confirming conntrack %p\n", ct);
+	pr_debug("Confirming conntrack %p\n", ct);
 
 	write_lock_bh(&nf_conntrack_lock);
 
 	/* See if there's one in the list already, including reverse:
 	   NAT could have grabbed it without realizing, since we're
 	   not in the hash.  If there is, we lost race. */
-	list_for_each_entry(h, &nf_conntrack_hash[hash], list)
+	hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode)
 		if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
 				      &h->tuple))
 			goto out;
-	list_for_each_entry(h, &nf_conntrack_hash[repl_hash], list)
+	hlist_for_each_entry(h, n, &nf_conntrack_hash[repl_hash], hnode)
 		if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
 				      &h->tuple))
 			goto out;
 
 	/* Remove from unconfirmed list */
-	list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
+	hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
 
 	__nf_conntrack_hash_insert(ct, hash, repl_hash);
 	/* Timer relative to confirmation time, not original
@@ -524,24 +371,33 @@
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
 
+#define NF_CT_EVICTION_RANGE	8
+
 /* There's a small race here where we may free a just-assured
    connection.  Too bad: we're in trouble anyway. */
-static int early_drop(struct list_head *chain)
+static int early_drop(unsigned int hash)
 {
-	/* Traverse backwards: gives us oldest, which is roughly LRU */
+	/* Use oldest entry, which is roughly LRU */
 	struct nf_conntrack_tuple_hash *h;
 	struct nf_conn *ct = NULL, *tmp;
+	struct hlist_node *n;
+	unsigned int i, cnt = 0;
 	int dropped = 0;
 
 	read_lock_bh(&nf_conntrack_lock);
-	list_for_each_entry_reverse(h, chain, list) {
-		tmp = nf_ct_tuplehash_to_ctrack(h);
-		if (!test_bit(IPS_ASSURED_BIT, &tmp->status)) {
-			ct = tmp;
-			atomic_inc(&ct->ct_general.use);
-			break;
+	for (i = 0; i < nf_conntrack_htable_size; i++) {
+		hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) {
+			tmp = nf_ct_tuplehash_to_ctrack(h);
+			if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
+				ct = tmp;
+			cnt++;
 		}
+		if (ct || cnt >= NF_CT_EVICTION_RANGE)
+			break;
+		hash = (hash + 1) % nf_conntrack_htable_size;
 	}
+	if (ct)
+		atomic_inc(&ct->ct_general.use);
 	read_unlock_bh(&nf_conntrack_lock);
 
 	if (!ct)
@@ -556,14 +412,10 @@
 	return dropped;
 }
 
-static struct nf_conn *
-__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
-		     const struct nf_conntrack_tuple *repl,
-		     const struct nf_conntrack_l3proto *l3proto,
-		     u_int32_t features)
+struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
+				   const struct nf_conntrack_tuple *repl)
 {
 	struct nf_conn *conntrack = NULL;
-	struct nf_conntrack_helper *helper;
 
 	if (unlikely(!nf_conntrack_hash_rnd_initted)) {
 		get_random_bytes(&nf_conntrack_hash_rnd, 4);
@@ -576,8 +428,7 @@
 	if (nf_conntrack_max
 	    && atomic_read(&nf_conntrack_count) > nf_conntrack_max) {
 		unsigned int hash = hash_conntrack(orig);
-		/* Try dropping from this hash chain. */
-		if (!early_drop(&nf_conntrack_hash[hash])) {
+		if (!early_drop(hash)) {
 			atomic_dec(&nf_conntrack_count);
 			if (net_ratelimit())
 				printk(KERN_WARNING
@@ -587,72 +438,28 @@
 		}
 	}
 
-	/*  find features needed by this conntrack. */
-	features |= l3proto->get_features(orig);
-
-	/* FIXME: protect helper list per RCU */
-	read_lock_bh(&nf_conntrack_lock);
-	helper = __nf_ct_helper_find(repl);
-	/* NAT might want to assign a helper later */
-	if (helper || features & NF_CT_F_NAT)
-		features |= NF_CT_F_HELP;
-	read_unlock_bh(&nf_conntrack_lock);
-
-	DEBUGP("nf_conntrack_alloc: features=0x%x\n", features);
-
-	read_lock_bh(&nf_ct_cache_lock);
-
-	if (unlikely(!nf_ct_cache[features].use)) {
-		DEBUGP("nf_conntrack_alloc: not supported features = 0x%x\n",
-			features);
-		goto out;
-	}
-
-	conntrack = kmem_cache_alloc(nf_ct_cache[features].cachep, GFP_ATOMIC);
+	conntrack = kmem_cache_zalloc(nf_conntrack_cachep, GFP_ATOMIC);
 	if (conntrack == NULL) {
-		DEBUGP("nf_conntrack_alloc: Can't alloc conntrack from cache\n");
-		goto out;
+		pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
+		atomic_dec(&nf_conntrack_count);
+		return ERR_PTR(-ENOMEM);
 	}
 
-	memset(conntrack, 0, nf_ct_cache[features].size);
-	conntrack->features = features;
 	atomic_set(&conntrack->ct_general.use, 1);
 	conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
 	conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
 	/* Don't set timer yet: wait for confirmation */
 	setup_timer(&conntrack->timeout, death_by_timeout,
 		    (unsigned long)conntrack);
-	read_unlock_bh(&nf_ct_cache_lock);
 
 	return conntrack;
-out:
-	read_unlock_bh(&nf_ct_cache_lock);
-	atomic_dec(&nf_conntrack_count);
-	return conntrack;
-}
-
-struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
-				   const struct nf_conntrack_tuple *repl)
-{
-	struct nf_conntrack_l3proto *l3proto;
-	struct nf_conn *ct;
-
-	rcu_read_lock();
-	l3proto = __nf_ct_l3proto_find(orig->src.l3num);
-	ct = __nf_conntrack_alloc(orig, repl, l3proto, 0);
-	rcu_read_unlock();
-
-	return ct;
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
 
 void nf_conntrack_free(struct nf_conn *conntrack)
 {
-	u_int32_t features = conntrack->features;
-	NF_CT_ASSERT(features >= NF_CT_F_BASIC && features < NF_CT_F_NUM);
-	DEBUGP("nf_conntrack_free: features = 0x%x, conntrack=%p\n", features,
-	       conntrack);
-	kmem_cache_free(nf_ct_cache[features].cachep, conntrack);
+	nf_ct_ext_free(conntrack);
+	kmem_cache_free(nf_conntrack_cachep, conntrack);
 	atomic_dec(&nf_conntrack_count);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_free);
@@ -670,43 +477,38 @@
 	struct nf_conn_help *help;
 	struct nf_conntrack_tuple repl_tuple;
 	struct nf_conntrack_expect *exp;
-	u_int32_t features = 0;
 
 	if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) {
-		DEBUGP("Can't invert tuple.\n");
+		pr_debug("Can't invert tuple.\n");
 		return NULL;
 	}
 
-	read_lock_bh(&nf_conntrack_lock);
-	exp = __nf_conntrack_expect_find(tuple);
-	if (exp && exp->helper)
-		features = NF_CT_F_HELP;
-	read_unlock_bh(&nf_conntrack_lock);
-
-	conntrack = __nf_conntrack_alloc(tuple, &repl_tuple, l3proto, features);
+	conntrack = nf_conntrack_alloc(tuple, &repl_tuple);
 	if (conntrack == NULL || IS_ERR(conntrack)) {
-		DEBUGP("Can't allocate conntrack.\n");
+		pr_debug("Can't allocate conntrack.\n");
 		return (struct nf_conntrack_tuple_hash *)conntrack;
 	}
 
 	if (!l4proto->new(conntrack, skb, dataoff)) {
 		nf_conntrack_free(conntrack);
-		DEBUGP("init conntrack: can't track with proto module\n");
+		pr_debug("init conntrack: can't track with proto module\n");
 		return NULL;
 	}
 
 	write_lock_bh(&nf_conntrack_lock);
-	exp = find_expectation(tuple);
-
-	help = nfct_help(conntrack);
+	exp = nf_ct_find_expectation(tuple);
 	if (exp) {
-		DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
-			conntrack, exp);
+		pr_debug("conntrack: expectation arrives ct=%p exp=%p\n",
+			 conntrack, exp);
 		/* Welcome, Mr. Bond.  We've been expecting you... */
 		__set_bit(IPS_EXPECTED_BIT, &conntrack->status);
 		conntrack->master = exp->master;
-		if (exp->helper)
-			rcu_assign_pointer(help->helper, exp->helper);
+		if (exp->helper) {
+			help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
+			if (help)
+				rcu_assign_pointer(help->helper, exp->helper);
+		}
+
 #ifdef CONFIG_NF_CONNTRACK_MARK
 		conntrack->mark = exp->master->mark;
 #endif
@@ -716,23 +518,27 @@
 		nf_conntrack_get(&conntrack->master->ct_general);
 		NF_CT_STAT_INC(expect_new);
 	} else {
-		if (help) {
-			/* not in hash table yet, so not strictly necessary */
-			rcu_assign_pointer(help->helper,
-					   __nf_ct_helper_find(&repl_tuple));
+		struct nf_conntrack_helper *helper;
+
+		helper = __nf_ct_helper_find(&repl_tuple);
+		if (helper) {
+			help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
+			if (help)
+				rcu_assign_pointer(help->helper, helper);
 		}
 		NF_CT_STAT_INC(new);
 	}
 
 	/* Overload tuple linked list to put us in unconfirmed list. */
-	list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);
+	hlist_add_head(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
+		       &unconfirmed);
 
 	write_unlock_bh(&nf_conntrack_lock);
 
 	if (exp) {
 		if (exp->expectfn)
 			exp->expectfn(conntrack, exp);
-		nf_conntrack_expect_put(exp);
+		nf_ct_expect_put(exp);
 	}
 
 	return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
@@ -756,12 +562,12 @@
 	if (!nf_ct_get_tuple(skb, skb_network_offset(skb),
 			     dataoff, l3num, protonum, &tuple, l3proto,
 			     l4proto)) {
-		DEBUGP("resolve_normal_ct: Can't get tuple\n");
+		pr_debug("resolve_normal_ct: Can't get tuple\n");
 		return NULL;
 	}
 
 	/* look for tuple match */
-	h = nf_conntrack_find_get(&tuple, NULL);
+	h = nf_conntrack_find_get(&tuple);
 	if (!h) {
 		h = init_conntrack(&tuple, l3proto, l4proto, skb, dataoff);
 		if (!h)
@@ -779,13 +585,14 @@
 	} else {
 		/* Once we've had two way comms, always ESTABLISHED. */
 		if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
-			DEBUGP("nf_conntrack_in: normal packet for %p\n", ct);
+			pr_debug("nf_conntrack_in: normal packet for %p\n", ct);
 			*ctinfo = IP_CT_ESTABLISHED;
 		} else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) {
-			DEBUGP("nf_conntrack_in: related packet for %p\n", ct);
+			pr_debug("nf_conntrack_in: related packet for %p\n",
+				 ct);
 			*ctinfo = IP_CT_RELATED;
 		} else {
-			DEBUGP("nf_conntrack_in: new packet for %p\n", ct);
+			pr_debug("nf_conntrack_in: new packet for %p\n", ct);
 			*ctinfo = IP_CT_NEW;
 		}
 		*set_reply = 0;
@@ -817,7 +624,7 @@
 	l3proto = __nf_ct_l3proto_find((u_int16_t)pf);
 
 	if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) {
-		DEBUGP("not prepared to track yet or error occured\n");
+		pr_debug("not prepared to track yet or error occured\n");
 		return -ret;
 	}
 
@@ -853,7 +660,7 @@
 	if (ret < 0) {
 		/* Invalid: inverse of the return code tells
 		 * the netfilter core what to do */
-		DEBUGP("nf_conntrack_in: Can't track with proto module\n");
+		pr_debug("nf_conntrack_in: Can't track with proto module\n");
 		nf_conntrack_put((*pskb)->nfct);
 		(*pskb)->nfct = NULL;
 		NF_CT_STAT_INC_ATOMIC(invalid);
@@ -888,23 +695,36 @@
 			      const struct nf_conntrack_tuple *newreply)
 {
 	struct nf_conn_help *help = nfct_help(ct);
+	struct nf_conntrack_helper *helper;
 
 	write_lock_bh(&nf_conntrack_lock);
 	/* Should be unconfirmed, so not in hash table yet */
 	NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
 
-	DEBUGP("Altering reply tuple of %p to ", ct);
+	pr_debug("Altering reply tuple of %p to ", ct);
 	NF_CT_DUMP_TUPLE(newreply);
 
 	ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
-	if (!ct->master && help && help->expecting == 0) {
-		struct nf_conntrack_helper *helper;
-		helper = __nf_ct_helper_find(newreply);
-		if (helper)
-			memset(&help->help, 0, sizeof(help->help));
-		/* not in hash table yet, so not strictly necessary */
-		rcu_assign_pointer(help->helper, helper);
+	if (ct->master || (help && help->expecting != 0))
+		goto out;
+
+	helper = __nf_ct_helper_find(newreply);
+	if (helper == NULL) {
+		if (help)
+			rcu_assign_pointer(help->helper, NULL);
+		goto out;
 	}
+
+	if (help == NULL) {
+		help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
+		if (help == NULL)
+			goto out;
+	} else {
+		memset(&help->help, 0, sizeof(help->help));
+	}
+
+	rcu_assign_pointer(help->helper, helper);
+out:
 	write_unlock_bh(&nf_conntrack_lock);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
@@ -1048,16 +868,17 @@
 {
 	struct nf_conntrack_tuple_hash *h;
 	struct nf_conn *ct;
+	struct hlist_node *n;
 
 	write_lock_bh(&nf_conntrack_lock);
 	for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
-		list_for_each_entry(h, &nf_conntrack_hash[*bucket], list) {
+		hlist_for_each_entry(h, n, &nf_conntrack_hash[*bucket], hnode) {
 			ct = nf_ct_tuplehash_to_ctrack(h);
 			if (iter(ct, data))
 				goto found;
 		}
 	}
-	list_for_each_entry(h, &unconfirmed, list) {
+	hlist_for_each_entry(h, n, &unconfirmed, hnode) {
 		ct = nf_ct_tuplehash_to_ctrack(h);
 		if (iter(ct, data))
 			set_bit(IPS_DYING_BIT, &ct->status);
@@ -1092,14 +913,15 @@
 	return 1;
 }
 
-static void free_conntrack_hash(struct list_head *hash, int vmalloced, int size)
+void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, int size)
 {
 	if (vmalloced)
 		vfree(hash);
 	else
 		free_pages((unsigned long)hash,
-			   get_order(sizeof(struct list_head) * size));
+			   get_order(sizeof(struct hlist_head) * size));
 }
+EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);
 
 void nf_conntrack_flush(void)
 {
@@ -1111,8 +933,6 @@
    supposed to kill the mall. */
 void nf_conntrack_cleanup(void)
 {
-	int i;
-
 	rcu_assign_pointer(ip_ct_attach, NULL);
 
 	/* This makes sure all current packets have passed through
@@ -1133,49 +953,46 @@
 
 	rcu_assign_pointer(nf_ct_destroy, NULL);
 
-	for (i = 0; i < NF_CT_F_NUM; i++) {
-		if (nf_ct_cache[i].use == 0)
-			continue;
-
-		NF_CT_ASSERT(nf_ct_cache[i].use == 1);
-		nf_ct_cache[i].use = 1;
-		nf_conntrack_unregister_cache(i);
-	}
-	kmem_cache_destroy(nf_conntrack_expect_cachep);
-	free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
-			    nf_conntrack_htable_size);
+	kmem_cache_destroy(nf_conntrack_cachep);
+	nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_vmalloc,
+			     nf_conntrack_htable_size);
 
 	nf_conntrack_proto_fini();
+	nf_conntrack_helper_fini();
+	nf_conntrack_expect_fini();
 }
 
-static struct list_head *alloc_hashtable(int size, int *vmalloced)
+struct hlist_head *nf_ct_alloc_hashtable(int *sizep, int *vmalloced)
 {
-	struct list_head *hash;
-	unsigned int i;
+	struct hlist_head *hash;
+	unsigned int size, i;
 
 	*vmalloced = 0;
+
+	size = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_head));
 	hash = (void*)__get_free_pages(GFP_KERNEL,
-				       get_order(sizeof(struct list_head)
+				       get_order(sizeof(struct hlist_head)
 						 * size));
 	if (!hash) {
 		*vmalloced = 1;
 		printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n");
-		hash = vmalloc(sizeof(struct list_head) * size);
+		hash = vmalloc(sizeof(struct hlist_head) * size);
 	}
 
 	if (hash)
 		for (i = 0; i < size; i++)
-			INIT_LIST_HEAD(&hash[i]);
+			INIT_HLIST_HEAD(&hash[i]);
 
 	return hash;
 }
+EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable);
 
 int set_hashsize(const char *val, struct kernel_param *kp)
 {
 	int i, bucket, hashsize, vmalloced;
 	int old_vmalloced, old_size;
 	int rnd;
-	struct list_head *hash, *old_hash;
+	struct hlist_head *hash, *old_hash;
 	struct nf_conntrack_tuple_hash *h;
 
 	/* On boot, we can set this without any fancy locking. */
@@ -1186,7 +1003,7 @@
 	if (!hashsize)
 		return -EINVAL;
 
-	hash = alloc_hashtable(hashsize, &vmalloced);
+	hash = nf_ct_alloc_hashtable(&hashsize, &vmalloced);
 	if (!hash)
 		return -ENOMEM;
 
@@ -1196,12 +1013,12 @@
 
 	write_lock_bh(&nf_conntrack_lock);
 	for (i = 0; i < nf_conntrack_htable_size; i++) {
-		while (!list_empty(&nf_conntrack_hash[i])) {
-			h = list_entry(nf_conntrack_hash[i].next,
-				       struct nf_conntrack_tuple_hash, list);
-			list_del(&h->list);
+		while (!hlist_empty(&nf_conntrack_hash[i])) {
+			h = hlist_entry(nf_conntrack_hash[i].first,
+					struct nf_conntrack_tuple_hash, hnode);
+			hlist_del(&h->hnode);
 			bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
-			list_add_tail(&h->list, &hash[bucket]);
+			hlist_add_head(&h->hnode, &hash[bucket]);
 		}
 	}
 	old_size = nf_conntrack_htable_size;
@@ -1214,7 +1031,7 @@
 	nf_conntrack_hash_rnd = rnd;
 	write_unlock_bh(&nf_conntrack_lock);
 
-	free_conntrack_hash(old_hash, old_vmalloced, old_size);
+	nf_ct_free_hashtable(old_hash, old_vmalloced, old_size);
 	return 0;
 }
 
@@ -1223,50 +1040,58 @@
 
 int __init nf_conntrack_init(void)
 {
+	int max_factor = 8;
 	int ret;
 
 	/* Idea from tcp.c: use 1/16384 of memory.  On i386: 32MB
-	 * machine has 256 buckets.  >= 1GB machines have 8192 buckets. */
+	 * machine has 512 buckets. >= 1GB machines have 16384 buckets. */
 	if (!nf_conntrack_htable_size) {
 		nf_conntrack_htable_size
 			= (((num_physpages << PAGE_SHIFT) / 16384)
-			   / sizeof(struct list_head));
+			   / sizeof(struct hlist_head));
 		if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
-			nf_conntrack_htable_size = 8192;
-		if (nf_conntrack_htable_size < 16)
-			nf_conntrack_htable_size = 16;
+			nf_conntrack_htable_size = 16384;
+		if (nf_conntrack_htable_size < 32)
+			nf_conntrack_htable_size = 32;
+
+		/* Use a max. factor of four by default to get the same max as
+		 * with the old struct list_heads. When a table size is given
+		 * we use the old value of 8 to avoid reducing the max.
+		 * entries. */
+		max_factor = 4;
 	}
-	nf_conntrack_max = 8 * nf_conntrack_htable_size;
-
-	printk("nf_conntrack version %s (%u buckets, %d max)\n",
-	       NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
-	       nf_conntrack_max);
-
-	nf_conntrack_hash = alloc_hashtable(nf_conntrack_htable_size,
-					    &nf_conntrack_vmalloc);
+	nf_conntrack_hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
+						  &nf_conntrack_vmalloc);
 	if (!nf_conntrack_hash) {
 		printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
 		goto err_out;
 	}
 
-	ret = nf_conntrack_register_cache(NF_CT_F_BASIC, "nf_conntrack:basic",
-					  sizeof(struct nf_conn));
-	if (ret < 0) {
+	nf_conntrack_max = max_factor * nf_conntrack_htable_size;
+
+	printk("nf_conntrack version %s (%u buckets, %d max)\n",
+	       NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
+	       nf_conntrack_max);
+
+	nf_conntrack_cachep = kmem_cache_create("nf_conntrack",
+						sizeof(struct nf_conn),
+						0, 0, NULL, NULL);
+	if (!nf_conntrack_cachep) {
 		printk(KERN_ERR "Unable to create nf_conn slab cache\n");
 		goto err_free_hash;
 	}
 
-	nf_conntrack_expect_cachep = kmem_cache_create("nf_conntrack_expect",
-					sizeof(struct nf_conntrack_expect),
-					0, 0, NULL, NULL);
-	if (!nf_conntrack_expect_cachep) {
-		printk(KERN_ERR "Unable to create nf_expect slab cache\n");
-		goto err_free_conntrack_slab;
-	}
-
 	ret = nf_conntrack_proto_init();
 	if (ret < 0)
-		goto out_free_expect_slab;
+		goto err_free_conntrack_slab;
+
+	ret = nf_conntrack_expect_init();
+	if (ret < 0)
+		goto out_fini_proto;
+
+	ret = nf_conntrack_helper_init();
+	if (ret < 0)
+		goto out_fini_expect;
 
 	/* For use by REJECT target */
 	rcu_assign_pointer(ip_ct_attach, __nf_conntrack_attach);
@@ -1280,13 +1105,15 @@
 
 	return ret;
 
-out_free_expect_slab:
-	kmem_cache_destroy(nf_conntrack_expect_cachep);
+out_fini_expect:
+	nf_conntrack_expect_fini();
+out_fini_proto:
+	nf_conntrack_proto_fini();
 err_free_conntrack_slab:
-	nf_conntrack_unregister_cache(NF_CT_F_BASIC);
+	kmem_cache_destroy(nf_conntrack_cachep);
 err_free_hash:
-	free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
-			    nf_conntrack_htable_size);
+	nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_vmalloc,
+			     nf_conntrack_htable_size);
 err_out:
 	return -ENOMEM;
 }
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index 6bd421d..83c41ac 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -26,8 +26,8 @@
 ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain);
 EXPORT_SYMBOL_GPL(nf_conntrack_chain);
 
-ATOMIC_NOTIFIER_HEAD(nf_conntrack_expect_chain);
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_chain);
+ATOMIC_NOTIFIER_HEAD(nf_ct_expect_chain);
+EXPORT_SYMBOL_GPL(nf_ct_expect_chain);
 
 DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
 EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
@@ -103,14 +103,14 @@
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
 
-int nf_conntrack_expect_register_notifier(struct notifier_block *nb)
+int nf_ct_expect_register_notifier(struct notifier_block *nb)
 {
-	return atomic_notifier_chain_register(&nf_conntrack_expect_chain, nb);
+	return atomic_notifier_chain_register(&nf_ct_expect_chain, nb);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_register_notifier);
+EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier);
 
-int nf_conntrack_expect_unregister_notifier(struct notifier_block *nb)
+int nf_ct_expect_unregister_notifier(struct notifier_block *nb)
 {
-	return atomic_notifier_chain_unregister(&nf_conntrack_expect_chain, nb);
+	return atomic_notifier_chain_unregister(&nf_ct_expect_chain, nb);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_unregister_notifier);
+EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 504fb6c..2191fe0 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -19,6 +19,7 @@
 #include <linux/err.h>
 #include <linux/percpu.h>
 #include <linux/kernel.h>
+#include <linux/jhash.h>
 
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_core.h>
@@ -26,11 +27,20 @@
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <net/netfilter/nf_conntrack_tuple.h>
 
-LIST_HEAD(nf_conntrack_expect_list);
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_list);
+struct hlist_head *nf_ct_expect_hash __read_mostly;
+EXPORT_SYMBOL_GPL(nf_ct_expect_hash);
 
-struct kmem_cache *nf_conntrack_expect_cachep __read_mostly;
-static unsigned int nf_conntrack_expect_next_id;
+unsigned int nf_ct_expect_hsize __read_mostly;
+EXPORT_SYMBOL_GPL(nf_ct_expect_hsize);
+
+static unsigned int nf_ct_expect_hash_rnd __read_mostly;
+static unsigned int nf_ct_expect_count;
+unsigned int nf_ct_expect_max __read_mostly;
+static int nf_ct_expect_hash_rnd_initted __read_mostly;
+static int nf_ct_expect_vmalloc;
+
+static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
+static unsigned int nf_ct_expect_next_id;
 
 /* nf_conntrack_expect helper functions */
 void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
@@ -40,60 +50,83 @@
 	NF_CT_ASSERT(master_help);
 	NF_CT_ASSERT(!timer_pending(&exp->timeout));
 
-	list_del(&exp->list);
-	NF_CT_STAT_INC(expect_delete);
+	hlist_del(&exp->hnode);
+	nf_ct_expect_count--;
+
+	hlist_del(&exp->lnode);
 	master_help->expecting--;
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
+
+	NF_CT_STAT_INC(expect_delete);
 }
 EXPORT_SYMBOL_GPL(nf_ct_unlink_expect);
 
-static void expectation_timed_out(unsigned long ul_expect)
+static void nf_ct_expectation_timed_out(unsigned long ul_expect)
 {
 	struct nf_conntrack_expect *exp = (void *)ul_expect;
 
 	write_lock_bh(&nf_conntrack_lock);
 	nf_ct_unlink_expect(exp);
 	write_unlock_bh(&nf_conntrack_lock);
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
+}
+
+static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple)
+{
+	if (unlikely(!nf_ct_expect_hash_rnd_initted)) {
+		get_random_bytes(&nf_ct_expect_hash_rnd, 4);
+		nf_ct_expect_hash_rnd_initted = 1;
+	}
+
+	return jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
+		      (((tuple->dst.protonum ^ tuple->src.l3num) << 16) |
+		       tuple->dst.u.all) ^ nf_ct_expect_hash_rnd) %
+	       nf_ct_expect_hsize;
 }
 
 struct nf_conntrack_expect *
-__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple)
+__nf_ct_expect_find(const struct nf_conntrack_tuple *tuple)
 {
 	struct nf_conntrack_expect *i;
+	struct hlist_node *n;
+	unsigned int h;
 
-	list_for_each_entry(i, &nf_conntrack_expect_list, list) {
+	if (!nf_ct_expect_count)
+		return NULL;
+
+	h = nf_ct_expect_dst_hash(tuple);
+	hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) {
 		if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask))
 			return i;
 	}
 	return NULL;
 }
-EXPORT_SYMBOL_GPL(__nf_conntrack_expect_find);
+EXPORT_SYMBOL_GPL(__nf_ct_expect_find);
 
 /* Just find a expectation corresponding to a tuple. */
 struct nf_conntrack_expect *
-nf_conntrack_expect_find_get(const struct nf_conntrack_tuple *tuple)
+nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple)
 {
 	struct nf_conntrack_expect *i;
 
 	read_lock_bh(&nf_conntrack_lock);
-	i = __nf_conntrack_expect_find(tuple);
+	i = __nf_ct_expect_find(tuple);
 	if (i)
 		atomic_inc(&i->use);
 	read_unlock_bh(&nf_conntrack_lock);
 
 	return i;
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_find_get);
+EXPORT_SYMBOL_GPL(nf_ct_expect_find_get);
 
 /* If an expectation for this connection is found, it gets delete from
  * global list then returned. */
 struct nf_conntrack_expect *
-find_expectation(const struct nf_conntrack_tuple *tuple)
+nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple)
 {
 	struct nf_conntrack_expect *exp;
 
-	exp = __nf_conntrack_expect_find(tuple);
+	exp = __nf_ct_expect_find(tuple);
 	if (!exp)
 		return NULL;
 
@@ -119,17 +152,18 @@
 /* delete all expectations for this conntrack */
 void nf_ct_remove_expectations(struct nf_conn *ct)
 {
-	struct nf_conntrack_expect *i, *tmp;
 	struct nf_conn_help *help = nfct_help(ct);
+	struct nf_conntrack_expect *exp;
+	struct hlist_node *n, *next;
 
 	/* Optimization: most connection never expect any others. */
 	if (!help || help->expecting == 0)
 		return;
 
-	list_for_each_entry_safe(i, tmp, &nf_conntrack_expect_list, list) {
-		if (i->master == ct && del_timer(&i->timeout)) {
-			nf_ct_unlink_expect(i);
-			nf_conntrack_expect_put(i);
+	hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) {
+		if (del_timer(&exp->timeout)) {
+			nf_ct_unlink_expect(exp);
+			nf_ct_expect_put(exp);
 		}
 	}
 }
@@ -141,25 +175,16 @@
 {
 	/* Part covered by intersection of masks must be unequal,
 	   otherwise they clash */
-	struct nf_conntrack_tuple intersect_mask;
+	struct nf_conntrack_tuple_mask intersect_mask;
 	int count;
 
-	intersect_mask.src.l3num = a->mask.src.l3num & b->mask.src.l3num;
 	intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all;
-	intersect_mask.dst.u.all = a->mask.dst.u.all & b->mask.dst.u.all;
-	intersect_mask.dst.protonum = a->mask.dst.protonum
-					& b->mask.dst.protonum;
 
 	for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
 		intersect_mask.src.u3.all[count] =
 			a->mask.src.u3.all[count] & b->mask.src.u3.all[count];
 	}
 
-	for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
-		intersect_mask.dst.u3.all[count] =
-			a->mask.dst.u3.all[count] & b->mask.dst.u3.all[count];
-	}
-
 	return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask);
 }
 
@@ -168,36 +193,29 @@
 {
 	return a->master == b->master
 		&& nf_ct_tuple_equal(&a->tuple, &b->tuple)
-		&& nf_ct_tuple_equal(&a->mask, &b->mask);
+		&& nf_ct_tuple_mask_equal(&a->mask, &b->mask);
 }
 
 /* Generally a bad idea to call this: could have matched already. */
-void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp)
+void nf_ct_unexpect_related(struct nf_conntrack_expect *exp)
 {
-	struct nf_conntrack_expect *i;
-
 	write_lock_bh(&nf_conntrack_lock);
-	/* choose the oldest expectation to evict */
-	list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
-		if (expect_matches(i, exp) && del_timer(&i->timeout)) {
-			nf_ct_unlink_expect(i);
-			write_unlock_bh(&nf_conntrack_lock);
-			nf_conntrack_expect_put(i);
-			return;
-		}
+	if (del_timer(&exp->timeout)) {
+		nf_ct_unlink_expect(exp);
+		nf_ct_expect_put(exp);
 	}
 	write_unlock_bh(&nf_conntrack_lock);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_unexpect_related);
+EXPORT_SYMBOL_GPL(nf_ct_unexpect_related);
 
 /* We don't increase the master conntrack refcount for non-fulfilled
  * conntracks. During the conntrack destruction, the expectations are
  * always killed before the conntrack itself */
-struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me)
+struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me)
 {
 	struct nf_conntrack_expect *new;
 
-	new = kmem_cache_alloc(nf_conntrack_expect_cachep, GFP_ATOMIC);
+	new = kmem_cache_alloc(nf_ct_expect_cachep, GFP_ATOMIC);
 	if (!new)
 		return NULL;
 
@@ -205,12 +223,12 @@
 	atomic_set(&new->use, 1);
 	return new;
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_alloc);
+EXPORT_SYMBOL_GPL(nf_ct_expect_alloc);
 
-void nf_conntrack_expect_init(struct nf_conntrack_expect *exp, int family,
-			      union nf_conntrack_address *saddr,
-			      union nf_conntrack_address *daddr,
-			      u_int8_t proto, __be16 *src, __be16 *dst)
+void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
+		       union nf_conntrack_address *saddr,
+		       union nf_conntrack_address *daddr,
+		       u_int8_t proto, __be16 *src, __be16 *dst)
 {
 	int len;
 
@@ -224,8 +242,6 @@
 	exp->helper = NULL;
 	exp->tuple.src.l3num = family;
 	exp->tuple.dst.protonum = proto;
-	exp->mask.src.l3num = 0xFFFF;
-	exp->mask.dst.protonum = 0xFF;
 
 	if (saddr) {
 		memcpy(&exp->tuple.src.u3, saddr, len);
@@ -242,21 +258,6 @@
 		memset(&exp->mask.src.u3, 0x00, sizeof(exp->mask.src.u3));
 	}
 
-	if (daddr) {
-		memcpy(&exp->tuple.dst.u3, daddr, len);
-		if (sizeof(exp->tuple.dst.u3) > len)
-			/* address needs to be cleared for nf_ct_tuple_equal */
-			memset((void *)&exp->tuple.dst.u3 + len, 0x00,
-			       sizeof(exp->tuple.dst.u3) - len);
-		memset(&exp->mask.dst.u3, 0xFF, len);
-		if (sizeof(exp->mask.dst.u3) > len)
-			memset((void *)&exp->mask.dst.u3 + len, 0x00,
-			       sizeof(exp->mask.dst.u3) - len);
-	} else {
-		memset(&exp->tuple.dst.u3, 0x00, sizeof(exp->tuple.dst.u3));
-		memset(&exp->mask.dst.u3, 0x00, sizeof(exp->mask.dst.u3));
-	}
-
 	if (src) {
 		exp->tuple.src.u.all = (__force u16)*src;
 		exp->mask.src.u.all = 0xFFFF;
@@ -265,36 +266,42 @@
 		exp->mask.src.u.all = 0;
 	}
 
-	if (dst) {
-		exp->tuple.dst.u.all = (__force u16)*dst;
-		exp->mask.dst.u.all = 0xFFFF;
-	} else {
-		exp->tuple.dst.u.all = 0;
-		exp->mask.dst.u.all = 0;
-	}
-}
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_init);
+	memcpy(&exp->tuple.dst.u3, daddr, len);
+	if (sizeof(exp->tuple.dst.u3) > len)
+		/* address needs to be cleared for nf_ct_tuple_equal */
+		memset((void *)&exp->tuple.dst.u3 + len, 0x00,
+		       sizeof(exp->tuple.dst.u3) - len);
 
-void nf_conntrack_expect_put(struct nf_conntrack_expect *exp)
+	exp->tuple.dst.u.all = (__force u16)*dst;
+}
+EXPORT_SYMBOL_GPL(nf_ct_expect_init);
+
+void nf_ct_expect_put(struct nf_conntrack_expect *exp)
 {
 	if (atomic_dec_and_test(&exp->use))
-		kmem_cache_free(nf_conntrack_expect_cachep, exp);
+		kmem_cache_free(nf_ct_expect_cachep, exp);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_put);
+EXPORT_SYMBOL_GPL(nf_ct_expect_put);
 
-static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
+static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
 {
 	struct nf_conn_help *master_help = nfct_help(exp->master);
+	unsigned int h = nf_ct_expect_dst_hash(&exp->tuple);
 
 	atomic_inc(&exp->use);
-	master_help->expecting++;
-	list_add(&exp->list, &nf_conntrack_expect_list);
 
-	setup_timer(&exp->timeout, expectation_timed_out, (unsigned long)exp);
+	hlist_add_head(&exp->lnode, &master_help->expectations);
+	master_help->expecting++;
+
+	hlist_add_head(&exp->hnode, &nf_ct_expect_hash[h]);
+	nf_ct_expect_count++;
+
+	setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
+		    (unsigned long)exp);
 	exp->timeout.expires = jiffies + master_help->helper->timeout * HZ;
 	add_timer(&exp->timeout);
 
-	exp->id = ++nf_conntrack_expect_next_id;
+	exp->id = ++nf_ct_expect_next_id;
 	atomic_inc(&exp->use);
 	NF_CT_STAT_INC(expect_create);
 }
@@ -302,16 +309,16 @@
 /* Race with expectations being used means we could have none to find; OK. */
 static void evict_oldest_expect(struct nf_conn *master)
 {
-	struct nf_conntrack_expect *i;
+	struct nf_conn_help *master_help = nfct_help(master);
+	struct nf_conntrack_expect *exp = NULL;
+	struct hlist_node *n;
 
-	list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
-		if (i->master == master) {
-			if (del_timer(&i->timeout)) {
-				nf_ct_unlink_expect(i);
-				nf_conntrack_expect_put(i);
-			}
-			break;
-		}
+	hlist_for_each_entry(exp, n, &master_help->expectations, lnode)
+		; /* nothing */
+
+	if (exp && del_timer(&exp->timeout)) {
+		nf_ct_unlink_expect(exp);
+		nf_ct_expect_put(exp);
 	}
 }
 
@@ -327,11 +334,13 @@
 	return 1;
 }
 
-int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
+int nf_ct_expect_related(struct nf_conntrack_expect *expect)
 {
 	struct nf_conntrack_expect *i;
 	struct nf_conn *master = expect->master;
 	struct nf_conn_help *master_help = nfct_help(master);
+	struct hlist_node *n;
+	unsigned int h;
 	int ret;
 
 	NF_CT_ASSERT(master_help);
@@ -341,7 +350,8 @@
 		ret = -ESHUTDOWN;
 		goto out;
 	}
-	list_for_each_entry(i, &nf_conntrack_expect_list, list) {
+	h = nf_ct_expect_dst_hash(&expect->tuple);
+	hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) {
 		if (expect_matches(i, expect)) {
 			/* Refresh timer: if it's dying, ignore.. */
 			if (refresh_timer(i)) {
@@ -358,57 +368,86 @@
 	    master_help->expecting >= master_help->helper->max_expected)
 		evict_oldest_expect(master);
 
-	nf_conntrack_expect_insert(expect);
-	nf_conntrack_expect_event(IPEXP_NEW, expect);
+	if (nf_ct_expect_count >= nf_ct_expect_max) {
+		if (net_ratelimit())
+			printk(KERN_WARNING
+			       "nf_conntrack: expectation table full");
+		ret = -EMFILE;
+		goto out;
+	}
+
+	nf_ct_expect_insert(expect);
+	nf_ct_expect_event(IPEXP_NEW, expect);
 	ret = 0;
 out:
 	write_unlock_bh(&nf_conntrack_lock);
 	return ret;
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_expect_related);
+EXPORT_SYMBOL_GPL(nf_ct_expect_related);
 
 #ifdef CONFIG_PROC_FS
-static void *exp_seq_start(struct seq_file *s, loff_t *pos)
+struct ct_expect_iter_state {
+	unsigned int bucket;
+};
+
+static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
 {
-	struct list_head *e = &nf_conntrack_expect_list;
-	loff_t i;
+	struct ct_expect_iter_state *st = seq->private;
 
-	/* strange seq_file api calls stop even if we fail,
-	 * thus we need to grab lock since stop unlocks */
-	read_lock_bh(&nf_conntrack_lock);
-
-	if (list_empty(e))
-		return NULL;
-
-	for (i = 0; i <= *pos; i++) {
-		e = e->next;
-		if (e == &nf_conntrack_expect_list)
-			return NULL;
+	for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
+		if (!hlist_empty(&nf_ct_expect_hash[st->bucket]))
+			return nf_ct_expect_hash[st->bucket].first;
 	}
-	return e;
+	return NULL;
 }
 
-static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
+static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
+					     struct hlist_node *head)
 {
-	struct list_head *e = v;
+	struct ct_expect_iter_state *st = seq->private;
 
-	++*pos;
-	e = e->next;
-
-	if (e == &nf_conntrack_expect_list)
-		return NULL;
-
-	return e;
+	head = head->next;
+	while (head == NULL) {
+		if (++st->bucket >= nf_ct_expect_hsize)
+			return NULL;
+		head = nf_ct_expect_hash[st->bucket].first;
+	}
+	return head;
 }
 
-static void exp_seq_stop(struct seq_file *s, void *v)
+static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
+{
+	struct hlist_node *head = ct_expect_get_first(seq);
+
+	if (head)
+		while (pos && (head = ct_expect_get_next(seq, head)))
+			pos--;
+	return pos ? NULL : head;
+}
+
+static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	read_lock_bh(&nf_conntrack_lock);
+	return ct_expect_get_idx(seq, *pos);
+}
+
+static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	(*pos)++;
+	return ct_expect_get_next(seq, v);
+}
+
+static void exp_seq_stop(struct seq_file *seq, void *v)
 {
 	read_unlock_bh(&nf_conntrack_lock);
 }
 
 static int exp_seq_show(struct seq_file *s, void *v)
 {
-	struct nf_conntrack_expect *expect = v;
+	struct nf_conntrack_expect *expect;
+	struct hlist_node *n = v;
+
+	expect = hlist_entry(n, struct nf_conntrack_expect, hnode);
 
 	if (expect->timeout.function)
 		seq_printf(s, "%ld ", timer_pending(&expect->timeout)
@@ -425,7 +464,7 @@
 	return seq_putc(s, '\n');
 }
 
-static struct seq_operations exp_seq_ops = {
+static const struct seq_operations exp_seq_ops = {
 	.start = exp_seq_start,
 	.next = exp_seq_next,
 	.stop = exp_seq_stop,
@@ -434,14 +473,96 @@
 
 static int exp_open(struct inode *inode, struct file *file)
 {
-	return seq_open(file, &exp_seq_ops);
+	struct seq_file *seq;
+	struct ct_expect_iter_state *st;
+	int ret;
+
+	st = kmalloc(sizeof(struct ct_expect_iter_state), GFP_KERNEL);
+	if (st == NULL)
+		return -ENOMEM;
+	ret = seq_open(file, &exp_seq_ops);
+	if (ret)
+		goto out_free;
+	seq          = file->private_data;
+	seq->private = st;
+	memset(st, 0, sizeof(struct ct_expect_iter_state));
+	return ret;
+out_free:
+	kfree(st);
+	return ret;
 }
 
-const struct file_operations exp_file_ops = {
+static const struct file_operations exp_file_ops = {
 	.owner   = THIS_MODULE,
 	.open    = exp_open,
 	.read    = seq_read,
 	.llseek  = seq_lseek,
-	.release = seq_release
+	.release = seq_release_private,
 };
 #endif /* CONFIG_PROC_FS */
+
+static int __init exp_proc_init(void)
+{
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry *proc;
+
+	proc = proc_net_fops_create("nf_conntrack_expect", 0440, &exp_file_ops);
+	if (!proc)
+		return -ENOMEM;
+#endif /* CONFIG_PROC_FS */
+	return 0;
+}
+
+static void exp_proc_remove(void)
+{
+#ifdef CONFIG_PROC_FS
+	proc_net_remove("nf_conntrack_expect");
+#endif /* CONFIG_PROC_FS */
+}
+
+module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0600);
+
+int __init nf_conntrack_expect_init(void)
+{
+	int err = -ENOMEM;
+
+	if (!nf_ct_expect_hsize) {
+		nf_ct_expect_hsize = nf_conntrack_htable_size / 256;
+		if (!nf_ct_expect_hsize)
+			nf_ct_expect_hsize = 1;
+	}
+	nf_ct_expect_max = nf_ct_expect_hsize * 4;
+
+	nf_ct_expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize,
+						  &nf_ct_expect_vmalloc);
+	if (nf_ct_expect_hash == NULL)
+		goto err1;
+
+	nf_ct_expect_cachep = kmem_cache_create("nf_conntrack_expect",
+					sizeof(struct nf_conntrack_expect),
+					0, 0, NULL, NULL);
+	if (!nf_ct_expect_cachep)
+		goto err2;
+
+	err = exp_proc_init();
+	if (err < 0)
+		goto err3;
+
+	return 0;
+
+err3:
+	nf_ct_free_hashtable(nf_ct_expect_hash, nf_ct_expect_vmalloc,
+			     nf_ct_expect_hsize);
+err2:
+	kmem_cache_destroy(nf_ct_expect_cachep);
+err1:
+	return err;
+}
+
+void nf_conntrack_expect_fini(void)
+{
+	exp_proc_remove();
+	kmem_cache_destroy(nf_ct_expect_cachep);
+	nf_ct_free_hashtable(nf_ct_expect_hash, nf_ct_expect_vmalloc,
+			     nf_ct_expect_hsize);
+}
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
new file mode 100644
index 0000000..a1a65a1
--- /dev/null
+++ b/net/netfilter/nf_conntrack_extend.c
@@ -0,0 +1,195 @@
+/* Structure dynamic extension infrastructure
+ * Copyright (C) 2004 Rusty Russell IBM Corporation
+ * Copyright (C) 2007 Netfilter Core Team <coreteam@netfilter.org>
+ * Copyright (C) 2007 USAGI/WIDE Project <http://www.linux-ipv6.org>
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/rcupdate.h>
+#include <linux/slab.h>
+#include <linux/skbuff.h>
+#include <net/netfilter/nf_conntrack_extend.h>
+
+static struct nf_ct_ext_type *nf_ct_ext_types[NF_CT_EXT_NUM];
+static DEFINE_MUTEX(nf_ct_ext_type_mutex);
+
+/* Horrible trick to figure out smallest amount worth kmallocing. */
+#define CACHE(x) (x) + 0 *
+enum {
+	NF_CT_EXT_MIN_SIZE =
+#include <linux/kmalloc_sizes.h>
+	1 };
+#undef CACHE
+
+void __nf_ct_ext_destroy(struct nf_conn *ct)
+{
+	unsigned int i;
+	struct nf_ct_ext_type *t;
+
+	for (i = 0; i < NF_CT_EXT_NUM; i++) {
+		if (!nf_ct_ext_exist(ct, i))
+			continue;
+
+		rcu_read_lock();
+		t = rcu_dereference(nf_ct_ext_types[i]);
+
+		/* Here the nf_ct_ext_type might have been unregisterd.
+		 * I.e., it has responsible to cleanup private
+		 * area in all conntracks when it is unregisterd.
+		 */
+		if (t && t->destroy)
+			t->destroy(ct);
+		rcu_read_unlock();
+	}
+}
+EXPORT_SYMBOL(__nf_ct_ext_destroy);
+
+static void *
+nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp)
+{
+	unsigned int off, len, real_len;
+	struct nf_ct_ext_type *t;
+
+	rcu_read_lock();
+	t = rcu_dereference(nf_ct_ext_types[id]);
+	BUG_ON(t == NULL);
+	off = ALIGN(sizeof(struct nf_ct_ext), t->align);
+	len = off + t->len;
+	real_len = t->alloc_size;
+	rcu_read_unlock();
+
+	*ext = kzalloc(real_len, gfp);
+	if (!*ext)
+		return NULL;
+
+	(*ext)->offset[id] = off;
+	(*ext)->len = len;
+	(*ext)->real_len = real_len;
+
+	return (void *)(*ext) + off;
+}
+
+void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
+{
+	struct nf_ct_ext *new;
+	int i, newlen, newoff;
+	struct nf_ct_ext_type *t;
+
+	if (!ct->ext)
+		return nf_ct_ext_create(&ct->ext, id, gfp);
+
+	if (nf_ct_ext_exist(ct, id))
+		return NULL;
+
+	rcu_read_lock();
+	t = rcu_dereference(nf_ct_ext_types[id]);
+	BUG_ON(t == NULL);
+
+	newoff = ALIGN(ct->ext->len, t->align);
+	newlen = newoff + t->len;
+	rcu_read_unlock();
+
+	if (newlen >= ct->ext->real_len) {
+		new = kmalloc(newlen, gfp);
+		if (!new)
+			return NULL;
+
+		memcpy(new, ct->ext, ct->ext->len);
+
+		for (i = 0; i < NF_CT_EXT_NUM; i++) {
+			if (!nf_ct_ext_exist(ct, i))
+				continue;
+
+			rcu_read_lock();
+			t = rcu_dereference(nf_ct_ext_types[i]);
+			if (t && t->move)
+				t->move(ct, ct->ext + ct->ext->offset[id]);
+			rcu_read_unlock();
+		}
+		kfree(ct->ext);
+		new->real_len = newlen;
+		ct->ext = new;
+	}
+
+	ct->ext->offset[id] = newoff;
+	ct->ext->len = newlen;
+	memset((void *)ct->ext + newoff, 0, newlen - newoff);
+	return (void *)ct->ext + newoff;
+}
+EXPORT_SYMBOL(__nf_ct_ext_add);
+
+static void update_alloc_size(struct nf_ct_ext_type *type)
+{
+	int i, j;
+	struct nf_ct_ext_type *t1, *t2;
+	enum nf_ct_ext_id min = 0, max = NF_CT_EXT_NUM - 1;
+
+	/* unnecessary to update all types */
+	if ((type->flags & NF_CT_EXT_F_PREALLOC) == 0) {
+		min = type->id;
+		max = type->id;
+	}
+
+	/* This assumes that extended areas in conntrack for the types
+	   whose NF_CT_EXT_F_PREALLOC bit set are allocated in order */
+	for (i = min; i <= max; i++) {
+		t1 = nf_ct_ext_types[i];
+		if (!t1)
+			continue;
+
+		t1->alloc_size = sizeof(struct nf_ct_ext)
+				 + ALIGN(sizeof(struct nf_ct_ext), t1->align)
+				 + t1->len;
+		for (j = 0; j < NF_CT_EXT_NUM; j++) {
+			t2 = nf_ct_ext_types[j];
+			if (t2 == NULL || t2 == t1 ||
+			    (t2->flags & NF_CT_EXT_F_PREALLOC) == 0)
+				continue;
+
+			t1->alloc_size = ALIGN(t1->alloc_size, t2->align)
+					 + t2->len;
+		}
+		if (t1->alloc_size < NF_CT_EXT_MIN_SIZE)
+			t1->alloc_size = NF_CT_EXT_MIN_SIZE;
+	}
+}
+
+/* This MUST be called in process context. */
+int nf_ct_extend_register(struct nf_ct_ext_type *type)
+{
+	int ret = 0;
+
+	mutex_lock(&nf_ct_ext_type_mutex);
+	if (nf_ct_ext_types[type->id]) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	/* This ensures that nf_ct_ext_create() can allocate enough area
+	   before updating alloc_size */
+	type->alloc_size = ALIGN(sizeof(struct nf_ct_ext), type->align)
+			   + type->len;
+	rcu_assign_pointer(nf_ct_ext_types[type->id], type);
+	update_alloc_size(type);
+out:
+	mutex_unlock(&nf_ct_ext_type_mutex);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(nf_ct_extend_register);
+
+/* This MUST be called in process context. */
+void nf_ct_extend_unregister(struct nf_ct_ext_type *type)
+{
+	mutex_lock(&nf_ct_ext_type_mutex);
+	rcu_assign_pointer(nf_ct_ext_types[type->id], NULL);
+	update_alloc_size(type);
+	mutex_unlock(&nf_ct_ext_type_mutex);
+	synchronize_rcu();
+}
+EXPORT_SYMBOL_GPL(nf_ct_extend_unregister);
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 82db2aa..c763ee7 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -51,12 +51,6 @@
 				struct nf_conntrack_expect *exp);
 EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, char);
 static int try_eprt(const char *, size_t, struct nf_conntrack_man *, char);
 static int try_epsv_response(const char *, size_t, struct nf_conntrack_man *,
@@ -138,13 +132,13 @@
 			if (*data == term && i == array_size - 1)
 				return len;
 
-			DEBUGP("Char %u (got %u nums) `%u' unexpected\n",
-			       len, i, *data);
+			pr_debug("Char %u (got %u nums) `%u' unexpected\n",
+				 len, i, *data);
 			return 0;
 		}
 	}
-	DEBUGP("Failed to fill %u numbers separated by %c\n", array_size, sep);
-
+	pr_debug("Failed to fill %u numbers separated by %c\n",
+		 array_size, sep);
 	return 0;
 }
 
@@ -178,13 +172,13 @@
 			if (tmp_port == 0)
 				break;
 			*port = htons(tmp_port);
-			DEBUGP("get_port: return %d\n", tmp_port);
+			pr_debug("get_port: return %d\n", tmp_port);
 			return i + 1;
 		}
 		else if (data[i] >= '0' && data[i] <= '9')
 			tmp_port = tmp_port*10 + data[i] - '0';
 		else { /* Some other crap */
-			DEBUGP("get_port: invalid char.\n");
+			pr_debug("get_port: invalid char.\n");
 			break;
 		}
 	}
@@ -201,22 +195,22 @@
 	/* First character is delimiter, then "1" for IPv4 or "2" for IPv6,
 	   then delimiter again. */
 	if (dlen <= 3) {
-		DEBUGP("EPRT: too short\n");
+		pr_debug("EPRT: too short\n");
 		return 0;
 	}
 	delim = data[0];
 	if (isdigit(delim) || delim < 33 || delim > 126 || data[2] != delim) {
-		DEBUGP("try_eprt: invalid delimitter.\n");
+		pr_debug("try_eprt: invalid delimitter.\n");
 		return 0;
 	}
 
 	if ((cmd->l3num == PF_INET && data[1] != '1') ||
 	    (cmd->l3num == PF_INET6 && data[1] != '2')) {
-		DEBUGP("EPRT: invalid protocol number.\n");
+		pr_debug("EPRT: invalid protocol number.\n");
 		return 0;
 	}
 
-	DEBUGP("EPRT: Got %c%c%c\n", delim, data[1], delim);
+	pr_debug("EPRT: Got %c%c%c\n", delim, data[1], delim);
 
 	if (data[1] == '1') {
 		u_int32_t array[4];
@@ -234,7 +228,7 @@
 
 	if (length == 0)
 		return 0;
-	DEBUGP("EPRT: Got IP address!\n");
+	pr_debug("EPRT: Got IP address!\n");
 	/* Start offset includes initial "|1|", and trailing delimiter */
 	return get_port(data, 3 + length + 1, dlen, delim, &cmd->u.tcp.port);
 }
@@ -267,7 +261,7 @@
 {
 	size_t i;
 
-	DEBUGP("find_pattern `%s': dlen = %u\n", pattern, dlen);
+	pr_debug("find_pattern `%s': dlen = %Zu\n", pattern, dlen);
 	if (dlen == 0)
 		return 0;
 
@@ -282,17 +276,17 @@
 #if 0
 		size_t i;
 
-		DEBUGP("ftp: string mismatch\n");
+		pr_debug("ftp: string mismatch\n");
 		for (i = 0; i < plen; i++) {
-			DEBUGP("ftp:char %u `%c'(%u) vs `%c'(%u)\n",
-				i, data[i], data[i],
-				pattern[i], pattern[i]);
+			pr_debug("ftp:char %u `%c'(%u) vs `%c'(%u)\n",
+				 i, data[i], data[i],
+				 pattern[i], pattern[i]);
 		}
 #endif
 		return 0;
 	}
 
-	DEBUGP("Pattern matches!\n");
+	pr_debug("Pattern matches!\n");
 	/* Now we've found the constant string, try to skip
 	   to the 'skip' character */
 	for (i = plen; data[i] != skip; i++)
@@ -301,14 +295,14 @@
 	/* Skip over the last character */
 	i++;
 
-	DEBUGP("Skipped up to `%c'!\n", skip);
+	pr_debug("Skipped up to `%c'!\n", skip);
 
 	*numoff = i;
 	*numlen = getnum(data + i, dlen - i, cmd, term);
 	if (!*numlen)
 		return -1;
 
-	DEBUGP("Match succeeded!\n");
+	pr_debug("Match succeeded!\n");
 	return 1;
 }
 
@@ -364,6 +358,7 @@
 	unsigned int matchlen, matchoff;
 	struct nf_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info;
 	struct nf_conntrack_expect *exp;
+	union nf_conntrack_address *daddr;
 	struct nf_conntrack_man cmd = {};
 	unsigned int i;
 	int found = 0, ends_in_nl;
@@ -372,7 +367,7 @@
 	/* Until there's been traffic both ways, don't look in packets. */
 	if (ctinfo != IP_CT_ESTABLISHED
 	    && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {
-		DEBUGP("ftp: Conntrackinfo = %u\n", ctinfo);
+		pr_debug("ftp: Conntrackinfo = %u\n", ctinfo);
 		return NF_ACCEPT;
 	}
 
@@ -383,8 +378,8 @@
 	dataoff = protoff + th->doff * 4;
 	/* No data? */
 	if (dataoff >= (*pskb)->len) {
-		DEBUGP("ftp: dataoff(%u) >= skblen(%u)\n", dataoff,
-			(*pskb)->len);
+		pr_debug("ftp: dataoff(%u) >= skblen(%u)\n", dataoff,
+			 (*pskb)->len);
 		return NF_ACCEPT;
 	}
 	datalen = (*pskb)->len - dataoff;
@@ -399,11 +394,11 @@
 	/* Look up to see if we're just after a \n. */
 	if (!find_nl_seq(ntohl(th->seq), ct_ftp_info, dir)) {
 		/* Now if this ends in \n, update ftp info. */
-		DEBUGP("nf_conntrack_ftp_help: wrong seq pos %s(%u) or %s(%u)\n",
-		       ct_ftp_info->seq_aft_nl_num[dir] > 0 ? "" : "(UNSET)",
-		       ct_ftp_info->seq_aft_nl[dir][0],
-		       ct_ftp_info->seq_aft_nl_num[dir] > 1 ? "" : "(UNSET)",
-		       ct_ftp_info->seq_aft_nl[dir][1]);
+		pr_debug("nf_conntrack_ftp: wrong seq pos %s(%u) or %s(%u)\n",
+			 ct_ftp_info->seq_aft_nl_num[dir] > 0 ? "" : "(UNSET)",
+			 ct_ftp_info->seq_aft_nl[dir][0],
+			 ct_ftp_info->seq_aft_nl_num[dir] > 1 ? "" : "(UNSET)",
+			 ct_ftp_info->seq_aft_nl[dir][1]);
 		ret = NF_ACCEPT;
 		goto out_update_nl;
 	}
@@ -441,11 +436,11 @@
 		goto out_update_nl;
 	}
 
-	DEBUGP("conntrack_ftp: match `%.*s' (%u bytes at %u)\n",
-	       (int)matchlen, fb_ptr + matchoff,
-	       matchlen, ntohl(th->seq) + matchoff);
+	pr_debug("conntrack_ftp: match `%.*s' (%u bytes at %u)\n",
+		 matchlen, fb_ptr + matchoff,
+		 matchlen, ntohl(th->seq) + matchoff);
 
-	exp = nf_conntrack_expect_alloc(ct);
+	exp = nf_ct_expect_alloc(ct);
 	if (exp == NULL) {
 		ret = NF_DROP;
 		goto out;
@@ -454,7 +449,7 @@
 	/* We refer to the reverse direction ("!dir") tuples here,
 	 * because we're expecting something in the other direction.
 	 * Doesn't matter unless NAT is happening.  */
-	exp->tuple.dst.u3 = ct->tuplehash[!dir].tuple.dst.u3;
+	daddr = &ct->tuplehash[!dir].tuple.dst.u3;
 
 	/* Update the ftp info */
 	if ((cmd.l3num == ct->tuplehash[dir].tuple.src.l3num) &&
@@ -465,14 +460,16 @@
 		   different IP address.  Simply don't record it for
 		   NAT. */
 		if (cmd.l3num == PF_INET) {
-			DEBUGP("conntrack_ftp: NOT RECORDING: " NIPQUAD_FMT " != " NIPQUAD_FMT "\n",
-			       NIPQUAD(cmd.u3.ip),
-			       NIPQUAD(ct->tuplehash[dir].tuple.src.u3.ip));
+			pr_debug("conntrack_ftp: NOT RECORDING: " NIPQUAD_FMT
+				 " != " NIPQUAD_FMT "\n",
+				 NIPQUAD(cmd.u3.ip),
+				 NIPQUAD(ct->tuplehash[dir].tuple.src.u3.ip));
 		} else {
-			DEBUGP("conntrack_ftp: NOT RECORDING: " NIP6_FMT " != " NIP6_FMT "\n",
-			       NIP6(*((struct in6_addr *)cmd.u3.ip6)),
-			       NIP6(*((struct in6_addr *)ct->tuplehash[dir]
-							.tuple.src.u3.ip6)));
+			pr_debug("conntrack_ftp: NOT RECORDING: " NIP6_FMT
+				 " != " NIP6_FMT "\n",
+				 NIP6(*((struct in6_addr *)cmd.u3.ip6)),
+				 NIP6(*((struct in6_addr *)
+					ct->tuplehash[dir].tuple.src.u3.ip6)));
 		}
 
 		/* Thanks to Cristiano Lincoln Mattos
@@ -483,37 +480,12 @@
 			ret = NF_ACCEPT;
 			goto out_put_expect;
 		}
-		memcpy(&exp->tuple.dst.u3, &cmd.u3.all,
-		       sizeof(exp->tuple.dst.u3));
+		daddr = &cmd.u3;
 	}
 
-	exp->tuple.src.u3 = ct->tuplehash[!dir].tuple.src.u3;
-	exp->tuple.src.l3num = cmd.l3num;
-	exp->tuple.src.u.tcp.port = 0;
-	exp->tuple.dst.u.tcp.port = cmd.u.tcp.port;
-	exp->tuple.dst.protonum = IPPROTO_TCP;
-
-	exp->mask = (struct nf_conntrack_tuple)
-		    { .src = { .l3num = 0xFFFF,
-			       .u = { .tcp = { 0 }},
-			     },
-		      .dst = { .protonum = 0xFF,
-			       .u = { .tcp = { __constant_htons(0xFFFF) }},
-			     },
-		    };
-	if (cmd.l3num == PF_INET) {
-		exp->mask.src.u3.ip = htonl(0xFFFFFFFF);
-		exp->mask.dst.u3.ip = htonl(0xFFFFFFFF);
-	} else {
-		memset(exp->mask.src.u3.ip6, 0xFF,
-		       sizeof(exp->mask.src.u3.ip6));
-		memset(exp->mask.dst.u3.ip6, 0xFF,
-		       sizeof(exp->mask.src.u3.ip6));
-	}
-
-	exp->expectfn = NULL;
-	exp->helper = NULL;
-	exp->flags = 0;
+	nf_ct_expect_init(exp, cmd.l3num,
+			  &ct->tuplehash[!dir].tuple.src.u3, daddr,
+			  IPPROTO_TCP, NULL, &cmd.u.tcp.port);
 
 	/* Now, NAT might want to mangle the packet, and register the
 	 * (possibly changed) expectation itself. */
@@ -523,14 +495,14 @@
 				 matchoff, matchlen, exp);
 	else {
 		/* Can't expect this?  Best to drop packet now. */
-		if (nf_conntrack_expect_related(exp) != 0)
+		if (nf_ct_expect_related(exp) != 0)
 			ret = NF_DROP;
 		else
 			ret = NF_ACCEPT;
 	}
 
 out_put_expect:
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
 
 out_update_nl:
 	/* Now if this ends in \n, update ftp info.  Seq may have been
@@ -542,8 +514,8 @@
 	return ret;
 }
 
-static struct nf_conntrack_helper ftp[MAX_PORTS][2];
-static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")];
+static struct nf_conntrack_helper ftp[MAX_PORTS][2] __read_mostly;
+static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")] __read_mostly;
 
 /* don't make this __exit, since it's called from __init ! */
 static void nf_conntrack_ftp_fini(void)
@@ -554,9 +526,9 @@
 			if (ftp[i][j].me == NULL)
 				continue;
 
-			DEBUGP("nf_ct_ftp: unregistering helper for pf: %d "
-			       "port: %d\n",
-				ftp[i][j].tuple.src.l3num, ports[i]);
+			pr_debug("nf_ct_ftp: unregistering helper for pf: %d "
+				 "port: %d\n",
+				 ftp[i][j].tuple.src.l3num, ports[i]);
 			nf_conntrack_helper_unregister(&ftp[i][j]);
 		}
 	}
@@ -584,9 +556,6 @@
 		for (j = 0; j < 2; j++) {
 			ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]);
 			ftp[i][j].tuple.dst.protonum = IPPROTO_TCP;
-			ftp[i][j].mask.src.l3num = 0xFFFF;
-			ftp[i][j].mask.src.u.tcp.port = htons(0xFFFF);
-			ftp[i][j].mask.dst.protonum = 0xFF;
 			ftp[i][j].max_expected = 1;
 			ftp[i][j].timeout = 5 * 60;	/* 5 Minutes */
 			ftp[i][j].me = THIS_MODULE;
@@ -598,9 +567,9 @@
 				sprintf(tmpname, "ftp-%d", ports[i]);
 			ftp[i][j].name = tmpname;
 
-			DEBUGP("nf_ct_ftp: registering helper for pf: %d "
-			       "port: %d\n",
-				ftp[i][j].tuple.src.l3num, ports[i]);
+			pr_debug("nf_ct_ftp: registering helper for pf: %d "
+				 "port: %d\n",
+				 ftp[i][j].tuple.src.l3num, ports[i]);
 			ret = nf_conntrack_helper_register(&ftp[i][j]);
 			if (ret) {
 				printk("nf_ct_ftp: failed to register helper "
diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c
index 6b7eaa0..a869403 100644
--- a/net/netfilter/nf_conntrack_h323_asn1.c
+++ b/net/netfilter/nf_conntrack_h323_asn1.c
@@ -555,15 +555,6 @@
 
 	/* Decode the extension components */
 	for (opt = 0; opt < bmp2_len; opt++, i++, son++) {
-		if (i < f->ub && son->attr & STOP) {
-			PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
-			      son->name);
-			return H323_ERROR_STOP;
-		}
-
-		if (!((0x80000000 >> opt) & bmp2))	/* Not present */
-			continue;
-
 		/* Check Range */
 		if (i >= f->ub) {	/* Newer Version? */
 			CHECK_BOUND(bs, 2);
@@ -573,6 +564,15 @@
 			continue;
 		}
 
+		if (son->attr & STOP) {
+			PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
+			      son->name);
+			return H323_ERROR_STOP;
+		}
+
+		if (!((0x80000000 >> opt) & bmp2))	/* Not present */
+			continue;
+
 		CHECK_BOUND(bs, 2);
 		len = get_len(bs);
 		CHECK_BOUND(bs, len);
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index a1b95ac..a8a9dfb 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -31,12 +31,6 @@
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <linux/netfilter/nf_conntrack_h323.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Parameters */
 static unsigned int default_rrq_ttl __read_mostly = 300;
 module_param(default_rrq_ttl, uint, 0600);
@@ -150,9 +144,9 @@
 		if (tcpdatalen < 4 || tpkt[0] != 0x03 || tpkt[1] != 0) {
 			/* Netmeeting sends TPKT header and data separately */
 			if (info->tpkt_len[dir] > 0) {
-				DEBUGP("nf_ct_h323: previous packet "
-				       "indicated separate TPKT data of %hu "
-				       "bytes\n", info->tpkt_len[dir]);
+				pr_debug("nf_ct_h323: previous packet "
+					 "indicated separate TPKT data of %hu "
+					 "bytes\n", info->tpkt_len[dir]);
 				if (info->tpkt_len[dir] <= tcpdatalen) {
 					/* Yes, there was a TPKT header
 					 * received */
@@ -163,9 +157,7 @@
 				}
 
 				/* Fragmented TPKT */
-				if (net_ratelimit())
-					printk("nf_ct_h323: "
-					       "fragmented TPKT\n");
+				pr_debug("nf_ct_h323: fragmented TPKT\n");
 				goto clear_out;
 			}
 
@@ -192,9 +184,9 @@
 	if (tpktlen > tcpdatalen) {
 		if (tcpdatalen == 4) {	/* Separate TPKT header */
 			/* Netmeeting sends TPKT header and data separately */
-			DEBUGP("nf_ct_h323: separate TPKT header indicates "
-			       "there will be TPKT data of %hu bytes\n",
-			       tpktlen - 4);
+			pr_debug("nf_ct_h323: separate TPKT header indicates "
+				 "there will be TPKT data of %hu bytes\n",
+				 tpktlen - 4);
 			info->tpkt_len[dir] = tpktlen - 4;
 			return 0;
 		}
@@ -282,22 +274,22 @@
 	rtcp_port = htons(ntohs(port) + 1);
 
 	/* Create expect for RTP */
-	if ((rtp_exp = nf_conntrack_expect_alloc(ct)) == NULL)
+	if ((rtp_exp = nf_ct_expect_alloc(ct)) == NULL)
 		return -1;
-	nf_conntrack_expect_init(rtp_exp, ct->tuplehash[!dir].tuple.src.l3num,
-				 &ct->tuplehash[!dir].tuple.src.u3,
-				 &ct->tuplehash[!dir].tuple.dst.u3,
-				 IPPROTO_UDP, NULL, &rtp_port);
+	nf_ct_expect_init(rtp_exp, ct->tuplehash[!dir].tuple.src.l3num,
+			  &ct->tuplehash[!dir].tuple.src.u3,
+			  &ct->tuplehash[!dir].tuple.dst.u3,
+			  IPPROTO_UDP, NULL, &rtp_port);
 
 	/* Create expect for RTCP */
-	if ((rtcp_exp = nf_conntrack_expect_alloc(ct)) == NULL) {
-		nf_conntrack_expect_put(rtp_exp);
+	if ((rtcp_exp = nf_ct_expect_alloc(ct)) == NULL) {
+		nf_ct_expect_put(rtp_exp);
 		return -1;
 	}
-	nf_conntrack_expect_init(rtcp_exp, ct->tuplehash[!dir].tuple.src.l3num,
-				 &ct->tuplehash[!dir].tuple.src.u3,
-				 &ct->tuplehash[!dir].tuple.dst.u3,
-				 IPPROTO_UDP, NULL, &rtcp_port);
+	nf_ct_expect_init(rtcp_exp, ct->tuplehash[!dir].tuple.src.l3num,
+			  &ct->tuplehash[!dir].tuple.src.u3,
+			  &ct->tuplehash[!dir].tuple.dst.u3,
+			  IPPROTO_UDP, NULL, &rtcp_port);
 
 	if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
 		   &ct->tuplehash[!dir].tuple.dst.u3,
@@ -308,22 +300,22 @@
 		ret = nat_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
 				   taddr, port, rtp_port, rtp_exp, rtcp_exp);
 	} else {		/* Conntrack only */
-		if (nf_conntrack_expect_related(rtp_exp) == 0) {
-			if (nf_conntrack_expect_related(rtcp_exp) == 0) {
-				DEBUGP("nf_ct_h323: expect RTP ");
+		if (nf_ct_expect_related(rtp_exp) == 0) {
+			if (nf_ct_expect_related(rtcp_exp) == 0) {
+				pr_debug("nf_ct_h323: expect RTP ");
 				NF_CT_DUMP_TUPLE(&rtp_exp->tuple);
-				DEBUGP("nf_ct_h323: expect RTCP ");
+				pr_debug("nf_ct_h323: expect RTCP ");
 				NF_CT_DUMP_TUPLE(&rtcp_exp->tuple);
 			} else {
-				nf_conntrack_unexpect_related(rtp_exp);
+				nf_ct_unexpect_related(rtp_exp);
 				ret = -1;
 			}
 		} else
 			ret = -1;
 	}
 
-	nf_conntrack_expect_put(rtp_exp);
-	nf_conntrack_expect_put(rtcp_exp);
+	nf_ct_expect_put(rtp_exp);
+	nf_ct_expect_put(rtcp_exp);
 
 	return ret;
 }
@@ -349,12 +341,12 @@
 		return 0;
 
 	/* Create expect for T.120 connections */
-	if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+	if ((exp = nf_ct_expect_alloc(ct)) == NULL)
 		return -1;
-	nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-				 &ct->tuplehash[!dir].tuple.src.u3,
-				 &ct->tuplehash[!dir].tuple.dst.u3,
-				 IPPROTO_TCP, NULL, &port);
+	nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+			  &ct->tuplehash[!dir].tuple.src.u3,
+			  &ct->tuplehash[!dir].tuple.dst.u3,
+			  IPPROTO_TCP, NULL, &port);
 	exp->flags = NF_CT_EXPECT_PERMANENT;	/* Accept multiple channels */
 
 	if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
@@ -366,14 +358,14 @@
 		ret = nat_t120(pskb, ct, ctinfo, data, dataoff, taddr,
 			       port, exp);
 	} else {		/* Conntrack only */
-		if (nf_conntrack_expect_related(exp) == 0) {
-			DEBUGP("nf_ct_h323: expect T.120 ");
+		if (nf_ct_expect_related(exp) == 0) {
+			pr_debug("nf_ct_h323: expect T.120 ");
 			NF_CT_DUMP_TUPLE(&exp->tuple);
 		} else
 			ret = -1;
 	}
 
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
 
 	return ret;
 }
@@ -415,7 +407,7 @@
 {
 	int ret;
 
-	DEBUGP("nf_ct_h323: OpenLogicalChannel\n");
+	pr_debug("nf_ct_h323: OpenLogicalChannel\n");
 
 	if (olc->forwardLogicalChannelParameters.multiplexParameters.choice ==
 	    eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
@@ -475,7 +467,7 @@
 	H2250LogicalChannelAckParameters *ack;
 	int ret;
 
-	DEBUGP("nf_ct_h323: OpenLogicalChannelAck\n");
+	pr_debug("nf_ct_h323: OpenLogicalChannelAck\n");
 
 	if ((olca->options &
 	     eOpenLogicalChannelAck_reverseLogicalChannelParameters) &&
@@ -546,8 +538,8 @@
 			return process_olc(pskb, ct, ctinfo, data, dataoff,
 					   &mscm->request.openLogicalChannel);
 		}
-		DEBUGP("nf_ct_h323: H.245 Request %d\n",
-		       mscm->request.choice);
+		pr_debug("nf_ct_h323: H.245 Request %d\n",
+			 mscm->request.choice);
 		break;
 	case eMultimediaSystemControlMessage_response:
 		if (mscm->response.choice ==
@@ -556,11 +548,11 @@
 					    &mscm->response.
 					    openLogicalChannelAck);
 		}
-		DEBUGP("nf_ct_h323: H.245 Response %d\n",
-		       mscm->response.choice);
+		pr_debug("nf_ct_h323: H.245 Response %d\n",
+			 mscm->response.choice);
 		break;
 	default:
-		DEBUGP("nf_ct_h323: H.245 signal %d\n", mscm->choice);
+		pr_debug("nf_ct_h323: H.245 signal %d\n", mscm->choice);
 		break;
 	}
 
@@ -582,24 +574,23 @@
 	    ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
 		return NF_ACCEPT;
 	}
-	DEBUGP("nf_ct_h245: skblen = %u\n", (*pskb)->len);
+	pr_debug("nf_ct_h245: skblen = %u\n", (*pskb)->len);
 
 	spin_lock_bh(&nf_h323_lock);
 
 	/* Process each TPKT */
 	while (get_tpkt_data(pskb, protoff, ct, ctinfo,
 			     &data, &datalen, &dataoff)) {
-		DEBUGP("nf_ct_h245: TPKT len=%d ", datalen);
+		pr_debug("nf_ct_h245: TPKT len=%d ", datalen);
 		NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
 
 		/* Decode H.245 signal */
 		ret = DecodeMultimediaSystemControlMessage(data, datalen,
 							   &mscm);
 		if (ret < 0) {
-			if (net_ratelimit())
-				printk("nf_ct_h245: decoding error: %s\n",
-				       ret == H323_ERROR_BOUND ?
-				       "out of bound" : "out of range");
+			pr_debug("nf_ct_h245: decoding error: %s\n",
+				 ret == H323_ERROR_BOUND ?
+				 "out of bound" : "out of range");
 			/* We don't drop when decoding error */
 			break;
 		}
@@ -626,8 +617,6 @@
 	.max_expected		= H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */,
 	.timeout		= 240,
 	.tuple.dst.protonum	= IPPROTO_UDP,
-	.mask.src.u.udp.port	= __constant_htons(0xFFFF),
-	.mask.dst.protonum	= 0xFF,
 	.help			= h245_help
 };
 
@@ -684,12 +673,12 @@
 		return 0;
 
 	/* Create expect for h245 connection */
-	if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+	if ((exp = nf_ct_expect_alloc(ct)) == NULL)
 		return -1;
-	nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-				 &ct->tuplehash[!dir].tuple.src.u3,
-				 &ct->tuplehash[!dir].tuple.dst.u3,
-				 IPPROTO_TCP, NULL, &port);
+	nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+			  &ct->tuplehash[!dir].tuple.src.u3,
+			  &ct->tuplehash[!dir].tuple.dst.u3,
+			  IPPROTO_TCP, NULL, &port);
 	exp->helper = &nf_conntrack_helper_h245;
 
 	if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
@@ -701,14 +690,14 @@
 		ret = nat_h245(pskb, ct, ctinfo, data, dataoff, taddr,
 			       port, exp);
 	} else {		/* Conntrack only */
-		if (nf_conntrack_expect_related(exp) == 0) {
-			DEBUGP("nf_ct_q931: expect H.245 ");
+		if (nf_ct_expect_related(exp) == 0) {
+			pr_debug("nf_ct_q931: expect H.245 ");
 			NF_CT_DUMP_TUPLE(&exp->tuple);
 		} else
 			ret = -1;
 	}
 
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
 
 	return ret;
 }
@@ -791,16 +780,16 @@
 	if (callforward_filter &&
 	    callforward_do_filter(&addr, &ct->tuplehash[!dir].tuple.src.u3,
 				  ct->tuplehash[!dir].tuple.src.l3num)) {
-		DEBUGP("nf_ct_q931: Call Forwarding not tracked\n");
+		pr_debug("nf_ct_q931: Call Forwarding not tracked\n");
 		return 0;
 	}
 
 	/* Create expect for the second call leg */
-	if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+	if ((exp = nf_ct_expect_alloc(ct)) == NULL)
 		return -1;
-	nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-				 &ct->tuplehash[!dir].tuple.src.u3, &addr,
-				 IPPROTO_TCP, NULL, &port);
+	nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+			  &ct->tuplehash[!dir].tuple.src.u3, &addr,
+			  IPPROTO_TCP, NULL, &port);
 	exp->helper = nf_conntrack_helper_q931;
 
 	if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
@@ -812,14 +801,14 @@
 		ret = nat_callforwarding(pskb, ct, ctinfo, data, dataoff,
 					 taddr, port, exp);
 	} else {		/* Conntrack only */
-		if (nf_conntrack_expect_related(exp) == 0) {
-			DEBUGP("nf_ct_q931: expect Call Forwarding ");
+		if (nf_ct_expect_related(exp) == 0) {
+			pr_debug("nf_ct_q931: expect Call Forwarding ");
 			NF_CT_DUMP_TUPLE(&exp->tuple);
 		} else
 			ret = -1;
 	}
 
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
 
 	return ret;
 }
@@ -837,7 +826,7 @@
 	union nf_conntrack_address addr;
 	typeof(set_h225_addr_hook) set_h225_addr;
 
-	DEBUGP("nf_ct_q931: Setup\n");
+	pr_debug("nf_ct_q931: Setup\n");
 
 	if (setup->options & eSetup_UUIE_h245Address) {
 		ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -852,11 +841,11 @@
 	    get_h225_addr(ct, *data, &setup->destCallSignalAddress,
 			  &addr, &port) &&
 	    memcmp(&addr, &ct->tuplehash[!dir].tuple.src.u3, sizeof(addr))) {
-		DEBUGP("nf_ct_q931: set destCallSignalAddress "
-		       NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
-		       NIP6(*(struct in6_addr *)&addr), ntohs(port),
-		       NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.src.u3),
-		       ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port));
+		pr_debug("nf_ct_q931: set destCallSignalAddress "
+			 NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
+			 NIP6(*(struct in6_addr *)&addr), ntohs(port),
+			 NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.src.u3),
+			 ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port));
 		ret = set_h225_addr(pskb, data, dataoff,
 				    &setup->destCallSignalAddress,
 				    &ct->tuplehash[!dir].tuple.src.u3,
@@ -870,11 +859,11 @@
 	    get_h225_addr(ct, *data, &setup->sourceCallSignalAddress,
 			  &addr, &port) &&
 	    memcmp(&addr, &ct->tuplehash[!dir].tuple.dst.u3, sizeof(addr))) {
-		DEBUGP("nf_ct_q931: set sourceCallSignalAddress "
-		       NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
-		       NIP6(*(struct in6_addr *)&addr), ntohs(port),
-		       NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.dst.u3),
-		       ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port));
+		pr_debug("nf_ct_q931: set sourceCallSignalAddress "
+			 NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
+			 NIP6(*(struct in6_addr *)&addr), ntohs(port),
+			 NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.dst.u3),
+			 ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port));
 		ret = set_h225_addr(pskb, data, dataoff,
 				    &setup->sourceCallSignalAddress,
 				    &ct->tuplehash[!dir].tuple.dst.u3,
@@ -905,7 +894,7 @@
 	int ret;
 	int i;
 
-	DEBUGP("nf_ct_q931: CallProceeding\n");
+	pr_debug("nf_ct_q931: CallProceeding\n");
 
 	if (callproc->options & eCallProceeding_UUIE_h245Address) {
 		ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -935,7 +924,7 @@
 	int ret;
 	int i;
 
-	DEBUGP("nf_ct_q931: Connect\n");
+	pr_debug("nf_ct_q931: Connect\n");
 
 	if (connect->options & eConnect_UUIE_h245Address) {
 		ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -965,7 +954,7 @@
 	int ret;
 	int i;
 
-	DEBUGP("nf_ct_q931: Alerting\n");
+	pr_debug("nf_ct_q931: Alerting\n");
 
 	if (alert->options & eAlerting_UUIE_h245Address) {
 		ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -995,7 +984,7 @@
 	int ret;
 	int i;
 
-	DEBUGP("nf_ct_q931: Facility\n");
+	pr_debug("nf_ct_q931: Facility\n");
 
 	if (facility->reason.choice == eFacilityReason_callForwarded) {
 		if (facility->options & eFacility_UUIE_alternativeAddress)
@@ -1034,7 +1023,7 @@
 	int ret;
 	int i;
 
-	DEBUGP("nf_ct_q931: Progress\n");
+	pr_debug("nf_ct_q931: Progress\n");
 
 	if (progress->options & eProgress_UUIE_h245Address) {
 		ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -1091,8 +1080,8 @@
 				       &pdu->h323_message_body.progress);
 		break;
 	default:
-		DEBUGP("nf_ct_q931: Q.931 signal %d\n",
-		       pdu->h323_message_body.choice);
+		pr_debug("nf_ct_q931: Q.931 signal %d\n",
+			 pdu->h323_message_body.choice);
 		break;
 	}
 
@@ -1126,23 +1115,22 @@
 	    ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
 		return NF_ACCEPT;
 	}
-	DEBUGP("nf_ct_q931: skblen = %u\n", (*pskb)->len);
+	pr_debug("nf_ct_q931: skblen = %u\n", (*pskb)->len);
 
 	spin_lock_bh(&nf_h323_lock);
 
 	/* Process each TPKT */
 	while (get_tpkt_data(pskb, protoff, ct, ctinfo,
 			     &data, &datalen, &dataoff)) {
-		DEBUGP("nf_ct_q931: TPKT len=%d ", datalen);
+		pr_debug("nf_ct_q931: TPKT len=%d ", datalen);
 		NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
 
 		/* Decode Q.931 signal */
 		ret = DecodeQ931(data, datalen, &q931);
 		if (ret < 0) {
-			if (net_ratelimit())
-				printk("nf_ct_q931: decoding error: %s\n",
-				       ret == H323_ERROR_BOUND ?
-				       "out of bound" : "out of range");
+			pr_debug("nf_ct_q931: decoding error: %s\n",
+				 ret == H323_ERROR_BOUND ?
+				 "out of bound" : "out of range");
 			/* We don't drop when decoding error */
 			break;
 		}
@@ -1173,9 +1161,6 @@
 		.tuple.src.l3num	= AF_INET,
 		.tuple.src.u.tcp.port	= __constant_htons(Q931_PORT),
 		.tuple.dst.protonum	= IPPROTO_TCP,
-		.mask.src.l3num		= 0xFFFF,
-		.mask.src.u.tcp.port	= __constant_htons(0xFFFF),
-		.mask.dst.protonum	= 0xFF,
 		.help			= q931_help
 	},
 	{
@@ -1187,9 +1172,6 @@
 		.tuple.src.l3num	= AF_INET6,
 		.tuple.src.u.tcp.port	= __constant_htons(Q931_PORT),
 		.tuple.dst.protonum	= IPPROTO_TCP,
-		.mask.src.l3num		= 0xFFFF,
-		.mask.src.u.tcp.port	= __constant_htons(0xFFFF),
-		.mask.dst.protonum	= 0xFF,
 		.help			= q931_help
 	},
 };
@@ -1225,7 +1207,7 @@
 	tuple.dst.u.tcp.port = port;
 	tuple.dst.protonum = IPPROTO_TCP;
 
-	exp = __nf_conntrack_expect_find(&tuple);
+	exp = __nf_ct_expect_find(&tuple);
 	if (exp && exp->master == ct)
 		return exp;
 	return NULL;
@@ -1271,14 +1253,13 @@
 		return 0;
 
 	/* Create expect for Q.931 */
-	if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+	if ((exp = nf_ct_expect_alloc(ct)) == NULL)
 		return -1;
-	nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-				 gkrouted_only ? /* only accept calls from GK? */
-					&ct->tuplehash[!dir].tuple.src.u3 :
-					NULL,
-				 &ct->tuplehash[!dir].tuple.dst.u3,
-				 IPPROTO_TCP, NULL, &port);
+	nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+			  gkrouted_only ? /* only accept calls from GK? */
+				&ct->tuplehash[!dir].tuple.src.u3 : NULL,
+			  &ct->tuplehash[!dir].tuple.dst.u3,
+			  IPPROTO_TCP, NULL, &port);
 	exp->helper = nf_conntrack_helper_q931;
 	exp->flags = NF_CT_EXPECT_PERMANENT;	/* Accept multiple calls */
 
@@ -1286,8 +1267,8 @@
 	if (nat_q931 && ct->status & IPS_NAT_MASK) {	/* Need NAT */
 		ret = nat_q931(pskb, ct, ctinfo, data, taddr, i, port, exp);
 	} else {		/* Conntrack only */
-		if (nf_conntrack_expect_related(exp) == 0) {
-			DEBUGP("nf_ct_ras: expect Q.931 ");
+		if (nf_ct_expect_related(exp) == 0) {
+			pr_debug("nf_ct_ras: expect Q.931 ");
 			NF_CT_DUMP_TUPLE(&exp->tuple);
 
 			/* Save port for looking up expect in processing RCF */
@@ -1296,7 +1277,7 @@
 			ret = -1;
 	}
 
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
 
 	return ret;
 }
@@ -1308,7 +1289,7 @@
 {
 	typeof(set_ras_addr_hook) set_ras_addr;
 
-	DEBUGP("nf_ct_ras: GRQ\n");
+	pr_debug("nf_ct_ras: GRQ\n");
 
 	set_ras_addr = rcu_dereference(set_ras_addr_hook);
 	if (set_ras_addr && ct->status & IPS_NAT_MASK)	/* NATed */
@@ -1328,7 +1309,7 @@
 	union nf_conntrack_address addr;
 	struct nf_conntrack_expect *exp;
 
-	DEBUGP("nf_ct_ras: GCF\n");
+	pr_debug("nf_ct_ras: GCF\n");
 
 	if (!get_h225_addr(ct, *data, &gcf->rasAddress, &addr, &port))
 		return 0;
@@ -1343,20 +1324,20 @@
 		return 0;
 
 	/* Need new expect */
-	if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+	if ((exp = nf_ct_expect_alloc(ct)) == NULL)
 		return -1;
-	nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-				 &ct->tuplehash[!dir].tuple.src.u3, &addr,
-				 IPPROTO_UDP, NULL, &port);
+	nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+			  &ct->tuplehash[!dir].tuple.src.u3, &addr,
+			  IPPROTO_UDP, NULL, &port);
 	exp->helper = nf_conntrack_helper_ras;
 
-	if (nf_conntrack_expect_related(exp) == 0) {
-		DEBUGP("nf_ct_ras: expect RAS ");
+	if (nf_ct_expect_related(exp) == 0) {
+		pr_debug("nf_ct_ras: expect RAS ");
 		NF_CT_DUMP_TUPLE(&exp->tuple);
 	} else
 		ret = -1;
 
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
 
 	return ret;
 }
@@ -1370,7 +1351,7 @@
 	int ret;
 	typeof(set_ras_addr_hook) set_ras_addr;
 
-	DEBUGP("nf_ct_ras: RRQ\n");
+	pr_debug("nf_ct_ras: RRQ\n");
 
 	ret = expect_q931(pskb, ct, ctinfo, data,
 			  rrq->callSignalAddress.item,
@@ -1388,7 +1369,7 @@
 	}
 
 	if (rrq->options & eRegistrationRequest_timeToLive) {
-		DEBUGP("nf_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive);
+		pr_debug("nf_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive);
 		info->timeout = rrq->timeToLive;
 	} else
 		info->timeout = default_rrq_ttl;
@@ -1407,7 +1388,7 @@
 	struct nf_conntrack_expect *exp;
 	typeof(set_sig_addr_hook) set_sig_addr;
 
-	DEBUGP("nf_ct_ras: RCF\n");
+	pr_debug("nf_ct_ras: RCF\n");
 
 	set_sig_addr = rcu_dereference(set_sig_addr_hook);
 	if (set_sig_addr && ct->status & IPS_NAT_MASK) {
@@ -1419,14 +1400,13 @@
 	}
 
 	if (rcf->options & eRegistrationConfirm_timeToLive) {
-		DEBUGP("nf_ct_ras: RCF TTL = %u seconds\n", rcf->timeToLive);
+		pr_debug("nf_ct_ras: RCF TTL = %u seconds\n", rcf->timeToLive);
 		info->timeout = rcf->timeToLive;
 	}
 
 	if (info->timeout > 0) {
-		DEBUGP
-		    ("nf_ct_ras: set RAS connection timeout to %u seconds\n",
-		     info->timeout);
+		pr_debug("nf_ct_ras: set RAS connection timeout to "
+			 "%u seconds\n", info->timeout);
 		nf_ct_refresh(ct, *pskb, info->timeout * HZ);
 
 		/* Set expect timeout */
@@ -1434,9 +1414,9 @@
 		exp = find_expect(ct, &ct->tuplehash[dir].tuple.dst.u3,
 				  info->sig_port[!dir]);
 		if (exp) {
-			DEBUGP("nf_ct_ras: set Q.931 expect "
-			       "timeout to %u seconds for",
-			       info->timeout);
+			pr_debug("nf_ct_ras: set Q.931 expect "
+				 "timeout to %u seconds for",
+				 info->timeout);
 			NF_CT_DUMP_TUPLE(&exp->tuple);
 			set_expect_timeout(exp, info->timeout);
 		}
@@ -1456,7 +1436,7 @@
 	int ret;
 	typeof(set_sig_addr_hook) set_sig_addr;
 
-	DEBUGP("nf_ct_ras: URQ\n");
+	pr_debug("nf_ct_ras: URQ\n");
 
 	set_sig_addr = rcu_dereference(set_sig_addr_hook);
 	if (set_sig_addr && ct->status & IPS_NAT_MASK) {
@@ -1489,7 +1469,7 @@
 	union nf_conntrack_address addr;
 	typeof(set_h225_addr_hook) set_h225_addr;
 
-	DEBUGP("nf_ct_ras: ARQ\n");
+	pr_debug("nf_ct_ras: ARQ\n");
 
 	set_h225_addr = rcu_dereference(set_h225_addr_hook);
 	if ((arq->options & eAdmissionRequest_destCallSignalAddress) &&
@@ -1532,7 +1512,7 @@
 	struct nf_conntrack_expect *exp;
 	typeof(set_sig_addr_hook) set_sig_addr;
 
-	DEBUGP("nf_ct_ras: ACF\n");
+	pr_debug("nf_ct_ras: ACF\n");
 
 	if (!get_h225_addr(ct, *data, &acf->destCallSignalAddress,
 			   &addr, &port))
@@ -1548,21 +1528,21 @@
 	}
 
 	/* Need new expect */
-	if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+	if ((exp = nf_ct_expect_alloc(ct)) == NULL)
 		return -1;
-	nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-				 &ct->tuplehash[!dir].tuple.src.u3, &addr,
-				 IPPROTO_TCP, NULL, &port);
+	nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+			  &ct->tuplehash[!dir].tuple.src.u3, &addr,
+			  IPPROTO_TCP, NULL, &port);
 	exp->flags = NF_CT_EXPECT_PERMANENT;
 	exp->helper = nf_conntrack_helper_q931;
 
-	if (nf_conntrack_expect_related(exp) == 0) {
-		DEBUGP("nf_ct_ras: expect Q.931 ");
+	if (nf_ct_expect_related(exp) == 0) {
+		pr_debug("nf_ct_ras: expect Q.931 ");
 		NF_CT_DUMP_TUPLE(&exp->tuple);
 	} else
 		ret = -1;
 
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
 
 	return ret;
 }
@@ -1574,7 +1554,7 @@
 {
 	typeof(set_ras_addr_hook) set_ras_addr;
 
-	DEBUGP("nf_ct_ras: LRQ\n");
+	pr_debug("nf_ct_ras: LRQ\n");
 
 	set_ras_addr = rcu_dereference(set_ras_addr_hook);
 	if (set_ras_addr && ct->status & IPS_NAT_MASK)
@@ -1594,28 +1574,28 @@
 	union nf_conntrack_address addr;
 	struct nf_conntrack_expect *exp;
 
-	DEBUGP("nf_ct_ras: LCF\n");
+	pr_debug("nf_ct_ras: LCF\n");
 
 	if (!get_h225_addr(ct, *data, &lcf->callSignalAddress,
 			   &addr, &port))
 		return 0;
 
 	/* Need new expect for call signal */
-	if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
+	if ((exp = nf_ct_expect_alloc(ct)) == NULL)
 		return -1;
-	nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
-				 &ct->tuplehash[!dir].tuple.src.u3, &addr,
-				 IPPROTO_TCP, NULL, &port);
+	nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
+			  &ct->tuplehash[!dir].tuple.src.u3, &addr,
+			  IPPROTO_TCP, NULL, &port);
 	exp->flags = NF_CT_EXPECT_PERMANENT;
 	exp->helper = nf_conntrack_helper_q931;
 
-	if (nf_conntrack_expect_related(exp) == 0) {
-		DEBUGP("nf_ct_ras: expect Q.931 ");
+	if (nf_ct_expect_related(exp) == 0) {
+		pr_debug("nf_ct_ras: expect Q.931 ");
 		NF_CT_DUMP_TUPLE(&exp->tuple);
 	} else
 		ret = -1;
 
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
 
 	/* Ignore rasAddress */
 
@@ -1631,7 +1611,7 @@
 	typeof(set_ras_addr_hook) set_ras_addr;
 	typeof(set_sig_addr_hook) set_sig_addr;
 
-	DEBUGP("nf_ct_ras: IRR\n");
+	pr_debug("nf_ct_ras: IRR\n");
 
 	set_ras_addr = rcu_dereference(set_ras_addr_hook);
 	if (set_ras_addr && ct->status & IPS_NAT_MASK) {
@@ -1690,7 +1670,7 @@
 		return process_irr(pskb, ct, ctinfo, data,
 				   &ras->infoRequestResponse);
 	default:
-		DEBUGP("nf_ct_ras: RAS message %d\n", ras->choice);
+		pr_debug("nf_ct_ras: RAS message %d\n", ras->choice);
 		break;
 	}
 
@@ -1706,7 +1686,7 @@
 	int datalen = 0;
 	int ret;
 
-	DEBUGP("nf_ct_ras: skblen = %u\n", (*pskb)->len);
+	pr_debug("nf_ct_ras: skblen = %u\n", (*pskb)->len);
 
 	spin_lock_bh(&nf_h323_lock);
 
@@ -1714,16 +1694,15 @@
 	data = get_udp_data(pskb, protoff, &datalen);
 	if (data == NULL)
 		goto accept;
-	DEBUGP("nf_ct_ras: RAS message len=%d ", datalen);
+	pr_debug("nf_ct_ras: RAS message len=%d ", datalen);
 	NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
 
 	/* Decode RAS message */
 	ret = DecodeRasMessage(data, datalen, &ras);
 	if (ret < 0) {
-		if (net_ratelimit())
-			printk("nf_ct_ras: decoding error: %s\n",
-			       ret == H323_ERROR_BOUND ?
-			       "out of bound" : "out of range");
+		pr_debug("nf_ct_ras: decoding error: %s\n",
+			 ret == H323_ERROR_BOUND ?
+			 "out of bound" : "out of range");
 		goto accept;
 	}
 
@@ -1752,9 +1731,6 @@
 		.tuple.src.l3num	= AF_INET,
 		.tuple.src.u.udp.port	= __constant_htons(RAS_PORT),
 		.tuple.dst.protonum	= IPPROTO_UDP,
-		.mask.src.l3num		= 0xFFFF,
-		.mask.src.u.udp.port	= __constant_htons(0xFFFF),
-		.mask.dst.protonum	= 0xFF,
 		.help			= ras_help,
 	},
 	{
@@ -1765,9 +1741,6 @@
 		.tuple.src.l3num	= AF_INET6,
 		.tuple.src.u.udp.port	= __constant_htons(RAS_PORT),
 		.tuple.dst.protonum	= IPPROTO_UDP,
-		.mask.src.l3num		= 0xFFFF,
-		.mask.src.u.udp.port	= __constant_htons(0xFFFF),
-		.mask.dst.protonum	= 0xFF,
 		.help			= ras_help,
 	},
 };
@@ -1780,7 +1753,7 @@
 	nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]);
 	nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]);
 	kfree(h323_buffer);
-	DEBUGP("nf_ct_h323: fini\n");
+	pr_debug("nf_ct_h323: fini\n");
 }
 
 /****************************************************************************/
@@ -1803,7 +1776,7 @@
 	ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[1]);
 	if (ret < 0)
 		goto err4;
-	DEBUGP("nf_ct_h323: init success\n");
+	pr_debug("nf_ct_h323: init success\n");
 	return 0;
 
 err4:
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index f868b7f..b1179dd 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -26,23 +26,43 @@
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_extend.h>
 
-static __read_mostly LIST_HEAD(helpers);
+static struct hlist_head *nf_ct_helper_hash __read_mostly;
+static unsigned int nf_ct_helper_hsize __read_mostly;
+static unsigned int nf_ct_helper_count __read_mostly;
+static int nf_ct_helper_vmalloc;
+
+
+/* Stupid hash, but collision free for the default registrations of the
+ * helpers currently in the kernel. */
+static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple)
+{
+	return (((tuple->src.l3num << 8) | tuple->dst.protonum) ^
+		tuple->src.u.all) % nf_ct_helper_hsize;
+}
 
 struct nf_conntrack_helper *
 __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
 {
-	struct nf_conntrack_helper *h;
+	struct nf_conntrack_helper *helper;
+	struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };
+	struct hlist_node *n;
+	unsigned int h;
 
-	list_for_each_entry(h, &helpers, list) {
-		if (nf_ct_tuple_mask_cmp(tuple, &h->tuple, &h->mask))
-			return h;
+	if (!nf_ct_helper_count)
+		return NULL;
+
+	h = helper_hash(tuple);
+	hlist_for_each_entry(helper, n, &nf_ct_helper_hash[h], hnode) {
+		if (nf_ct_tuple_src_mask_cmp(tuple, &helper->tuple, &mask))
+			return helper;
 	}
 	return NULL;
 }
 
 struct nf_conntrack_helper *
-nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple)
+nf_ct_helper_find_get(const struct nf_conntrack_tuple *tuple)
 {
 	struct nf_conntrack_helper *helper;
 
@@ -75,16 +95,32 @@
 __nf_conntrack_helper_find_byname(const char *name)
 {
 	struct nf_conntrack_helper *h;
+	struct hlist_node *n;
+	unsigned int i;
 
-	list_for_each_entry(h, &helpers, list) {
-		if (!strcmp(h->name, name))
-			return h;
+	for (i = 0; i < nf_ct_helper_hsize; i++) {
+		hlist_for_each_entry(h, n, &nf_ct_helper_hash[i], hnode) {
+			if (!strcmp(h->name, name))
+				return h;
+		}
 	}
-
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(__nf_conntrack_helper_find_byname);
 
+struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp)
+{
+	struct nf_conn_help *help;
+
+	help = nf_ct_ext_add(ct, NF_CT_EXT_HELPER, gfp);
+	if (help)
+		INIT_HLIST_HEAD(&help->expectations);
+	else
+		pr_debug("failed to add helper extension area");
+	return help;
+}
+EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);
+
 static inline int unhelp(struct nf_conntrack_tuple_hash *i,
 			 const struct nf_conntrack_helper *me)
 {
@@ -100,20 +136,13 @@
 
 int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
 {
-	int size, ret;
+	unsigned int h = helper_hash(&me->tuple);
 
 	BUG_ON(me->timeout == 0);
 
-	size = ALIGN(sizeof(struct nf_conn), __alignof__(struct nf_conn_help)) +
-	       sizeof(struct nf_conn_help);
-	ret = nf_conntrack_register_cache(NF_CT_F_HELP, "nf_conntrack:help",
-					  size);
-	if (ret < 0) {
-		printk(KERN_ERR "nf_conntrack_helper_register: Unable to create slab cache for conntracks\n");
-		return ret;
-	}
 	write_lock_bh(&nf_conntrack_lock);
-	list_add(&me->list, &helpers);
+	hlist_add_head(&me->hnode, &nf_ct_helper_hash[h]);
+	nf_ct_helper_count++;
 	write_unlock_bh(&nf_conntrack_lock);
 
 	return 0;
@@ -122,29 +151,34 @@
 
 void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
 {
-	unsigned int i;
 	struct nf_conntrack_tuple_hash *h;
-	struct nf_conntrack_expect *exp, *tmp;
+	struct nf_conntrack_expect *exp;
+	struct hlist_node *n, *next;
+	unsigned int i;
 
 	/* Need write lock here, to delete helper. */
 	write_lock_bh(&nf_conntrack_lock);
-	list_del(&me->list);
+	hlist_del(&me->hnode);
+	nf_ct_helper_count--;
 
 	/* Get rid of expectations */
-	list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) {
-		struct nf_conn_help *help = nfct_help(exp->master);
-		if ((help->helper == me || exp->helper == me) &&
-		    del_timer(&exp->timeout)) {
-			nf_ct_unlink_expect(exp);
-			nf_conntrack_expect_put(exp);
+	for (i = 0; i < nf_ct_expect_hsize; i++) {
+		hlist_for_each_entry_safe(exp, n, next,
+					  &nf_ct_expect_hash[i], hnode) {
+			struct nf_conn_help *help = nfct_help(exp->master);
+			if ((help->helper == me || exp->helper == me) &&
+			    del_timer(&exp->timeout)) {
+				nf_ct_unlink_expect(exp);
+				nf_ct_expect_put(exp);
+			}
 		}
 	}
 
 	/* Get rid of expecteds, set helpers to NULL. */
-	list_for_each_entry(h, &unconfirmed, list)
+	hlist_for_each_entry(h, n, &unconfirmed, hnode)
 		unhelp(h, me);
 	for (i = 0; i < nf_conntrack_htable_size; i++) {
-		list_for_each_entry(h, &nf_conntrack_hash[i], list)
+		hlist_for_each_entry(h, n, &nf_conntrack_hash[i], hnode)
 			unhelp(h, me);
 	}
 	write_unlock_bh(&nf_conntrack_lock);
@@ -153,3 +187,38 @@
 	synchronize_net();
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
+
+static struct nf_ct_ext_type helper_extend __read_mostly = {
+	.len	= sizeof(struct nf_conn_help),
+	.align	= __alignof__(struct nf_conn_help),
+	.id	= NF_CT_EXT_HELPER,
+};
+
+int nf_conntrack_helper_init()
+{
+	int err;
+
+	nf_ct_helper_hsize = 1; /* gets rounded up to use one page */
+	nf_ct_helper_hash = nf_ct_alloc_hashtable(&nf_ct_helper_hsize,
+						  &nf_ct_helper_vmalloc);
+	if (!nf_ct_helper_hash)
+		return -ENOMEM;
+
+	err = nf_ct_extend_register(&helper_extend);
+	if (err < 0)
+		goto err1;
+
+	return 0;
+
+err1:
+	nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_vmalloc,
+			     nf_ct_helper_hsize);
+	return err;
+}
+
+void nf_conntrack_helper_fini()
+{
+	nf_ct_extend_unregister(&helper_extend);
+	nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_vmalloc,
+			     nf_ct_helper_hsize);
+}
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 43ccd0e..1562ca9 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -12,6 +12,7 @@
 #include <linux/moduleparam.h>
 #include <linux/skbuff.h>
 #include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/netfilter.h>
 
@@ -55,13 +56,6 @@
 
 #define MINMATCHLEN	5
 
-#if 0
-#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s:" format, \
-				       __FILE__, __FUNCTION__ , ## args)
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* tries to get the ip_addr and port out of a dcc command
  * return value: -1 on failure, 0 on success
  *	data		pointer to first byte of DCC command data
@@ -99,6 +93,7 @@
 		struct nf_conn *ct, enum ip_conntrack_info ctinfo)
 {
 	unsigned int dataoff;
+	struct iphdr *iph;
 	struct tcphdr _tcph, *th;
 	char *data, *data_limit, *ib_ptr;
 	int dir = CTINFO2DIR(ctinfo);
@@ -148,9 +143,10 @@
 		data += 5;
 		/* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
 
-		DEBUGP("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u...\n",
-			NIPQUAD(iph->saddr), ntohs(th->source),
-			NIPQUAD(iph->daddr), ntohs(th->dest));
+		iph = ip_hdr(*pskb);
+		pr_debug("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u\n",
+			 NIPQUAD(iph->saddr), ntohs(th->source),
+			 NIPQUAD(iph->daddr), ntohs(th->dest));
 
 		for (i = 0; i < ARRAY_SIZE(dccprotos); i++) {
 			if (memcmp(data, dccprotos[i], strlen(dccprotos[i]))) {
@@ -158,18 +154,18 @@
 				continue;
 			}
 			data += strlen(dccprotos[i]);
-			DEBUGP("DCC %s detected\n", dccprotos[i]);
+			pr_debug("DCC %s detected\n", dccprotos[i]);
 
 			/* we have at least
 			 * (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
 			 * data left (== 14/13 bytes) */
 			if (parse_dcc((char *)data, data_limit, &dcc_ip,
 				       &dcc_port, &addr_beg_p, &addr_end_p)) {
-				DEBUGP("unable to parse dcc command\n");
+				pr_debug("unable to parse dcc command\n");
 				continue;
 			}
-			DEBUGP("DCC bound ip/port: %u.%u.%u.%u:%u\n",
-				HIPQUAD(dcc_ip), dcc_port);
+			pr_debug("DCC bound ip/port: %u.%u.%u.%u:%u\n",
+				 HIPQUAD(dcc_ip), dcc_port);
 
 			/* dcc_ip can be the internal OR external (NAT'ed) IP */
 			tuple = &ct->tuplehash[dir].tuple;
@@ -184,16 +180,16 @@
 				continue;
 			}
 
-			exp = nf_conntrack_expect_alloc(ct);
+			exp = nf_ct_expect_alloc(ct);
 			if (exp == NULL) {
 				ret = NF_DROP;
 				goto out;
 			}
 			tuple = &ct->tuplehash[!dir].tuple;
 			port = htons(dcc_port);
-			nf_conntrack_expect_init(exp, tuple->src.l3num,
-						 NULL, &tuple->dst.u3,
-						 IPPROTO_TCP, NULL, &port);
+			nf_ct_expect_init(exp, tuple->src.l3num,
+					  NULL, &tuple->dst.u3,
+					  IPPROTO_TCP, NULL, &port);
 
 			nf_nat_irc = rcu_dereference(nf_nat_irc_hook);
 			if (nf_nat_irc && ct->status & IPS_NAT_MASK)
@@ -201,9 +197,9 @@
 						 addr_beg_p - ib_ptr,
 						 addr_end_p - addr_beg_p,
 						 exp);
-			else if (nf_conntrack_expect_related(exp) != 0)
+			else if (nf_ct_expect_related(exp) != 0)
 				ret = NF_DROP;
-			nf_conntrack_expect_put(exp);
+			nf_ct_expect_put(exp);
 			goto out;
 		}
 	}
@@ -239,9 +235,6 @@
 		irc[i].tuple.src.l3num = AF_INET;
 		irc[i].tuple.src.u.tcp.port = htons(ports[i]);
 		irc[i].tuple.dst.protonum = IPPROTO_TCP;
-		irc[i].mask.src.l3num = 0xFFFF;
-		irc[i].mask.src.u.tcp.port = htons(0xFFFF);
-		irc[i].mask.dst.protonum = 0xFF;
 		irc[i].max_expected = max_dcc_channels;
 		irc[i].timeout = dcc_timeout;
 		irc[i].me = THIS_MODULE;
diff --git a/net/netfilter/nf_conntrack_l3proto_generic.c b/net/netfilter/nf_conntrack_l3proto_generic.c
index cbd96f3..b1bfa20 100644
--- a/net/netfilter/nf_conntrack_l3proto_generic.c
+++ b/net/netfilter/nf_conntrack_l3proto_generic.c
@@ -31,12 +31,6 @@
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 static int generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
 				struct nf_conntrack_tuple *tuple)
 {
@@ -76,12 +70,6 @@
 }
 
 
-static u_int32_t generic_get_features(const struct nf_conntrack_tuple *tuple)
-
-{
-	return NF_CT_F_BASIC;
-}
-
 struct nf_conntrack_l3proto nf_conntrack_l3proto_generic = {
 	.l3proto	 = PF_UNSPEC,
 	.name		 = "unknown",
@@ -90,6 +78,5 @@
 	.print_tuple	 = generic_print_tuple,
 	.print_conntrack = generic_print_conntrack,
 	.prepare	 = generic_prepare,
-	.get_features	 = generic_get_features,
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_generic);
diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c
index 1093478..1d59fab 100644
--- a/net/netfilter/nf_conntrack_netbios_ns.c
+++ b/net/netfilter/nf_conntrack_netbios_ns.c
@@ -74,7 +74,7 @@
 	if (mask == 0)
 		goto out;
 
-	exp = nf_conntrack_expect_alloc(ct);
+	exp = nf_ct_expect_alloc(ct);
 	if (exp == NULL)
 		goto out;
 
@@ -83,16 +83,13 @@
 
 	exp->mask.src.u3.ip       = mask;
 	exp->mask.src.u.udp.port  = htons(0xFFFF);
-	exp->mask.dst.u3.ip       = htonl(0xFFFFFFFF);
-	exp->mask.dst.u.udp.port  = htons(0xFFFF);
-	exp->mask.dst.protonum    = 0xFF;
 
 	exp->expectfn             = NULL;
 	exp->flags                = NF_CT_EXPECT_PERMANENT;
 	exp->helper               = NULL;
 
-	nf_conntrack_expect_related(exp);
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_related(exp);
+	nf_ct_expect_put(exp);
 
 	nf_ct_refresh(ct, *pskb, timeout * HZ);
 out:
@@ -104,9 +101,6 @@
 	.tuple.src.l3num	= AF_INET,
 	.tuple.src.u.udp.port	= __constant_htons(NMBD_PORT),
 	.tuple.dst.protonum	= IPPROTO_UDP,
-	.mask.src.l3num		= 0xFFFF,
-	.mask.src.u.udp.port	= __constant_htons(0xFFFF),
-	.mask.dst.protonum	= 0xFF,
 	.max_expected		= 1,
 	.me			= THIS_MODULE,
 	.help			= help,
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index d0fe3d7..6f89b10 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -428,7 +428,7 @@
 {
 	struct nf_conn *ct, *last;
 	struct nf_conntrack_tuple_hash *h;
-	struct list_head *i;
+	struct hlist_node *n;
 	struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
 	u_int8_t l3proto = nfmsg->nfgen_family;
 
@@ -436,8 +436,8 @@
 	last = (struct nf_conn *)cb->args[1];
 	for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
 restart:
-		list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) {
-			h = (struct nf_conntrack_tuple_hash *) i;
+		hlist_for_each_entry(h, n, &nf_conntrack_hash[cb->args[0]],
+				     hnode) {
 			if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
 				continue;
 			ct = nf_ct_tuplehash_to_ctrack(h);
@@ -689,7 +689,7 @@
 	if (err < 0)
 		return err;
 
-	h = nf_conntrack_find_get(&tuple, NULL);
+	h = nf_conntrack_find_get(&tuple);
 	if (!h)
 		return -ENOENT;
 
@@ -744,7 +744,7 @@
 	if (err < 0)
 		return err;
 
-	h = nf_conntrack_find_get(&tuple, NULL);
+	h = nf_conntrack_find_get(&tuple);
 	if (!h)
 		return -ENOENT;
 
@@ -856,23 +856,23 @@
 		return 0;
 	}
 
-	if (!help) {
-		/* FIXME: we need to reallocate and rehash */
-		return -EBUSY;
-	}
-
 	helper = __nf_conntrack_helper_find_byname(helpname);
 	if (helper == NULL)
 		return -EINVAL;
 
-	if (help->helper == helper)
-		return 0;
+	if (help) {
+		if (help->helper == helper)
+			return 0;
+		if (help->helper)
+			return -EBUSY;
+		/* need to zero data of old helper */
+		memset(&help->help, 0, sizeof(help->help));
+	} else {
+		help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
+		if (help == NULL)
+			return -ENOMEM;
+	}
 
-	if (help->helper)
-		return -EBUSY;
-
-	/* need to zero data of old helper */
-	memset(&help->help, 0, sizeof(help->help));
 	rcu_assign_pointer(help->helper, helper);
 
 	return 0;
@@ -957,7 +957,7 @@
 	struct nf_conn *ct;
 	int err = -EINVAL;
 	struct nf_conn_help *help;
-	struct nf_conntrack_helper *helper = NULL;
+	struct nf_conntrack_helper *helper;
 
 	ct = nf_conntrack_alloc(otuple, rtuple);
 	if (ct == NULL || IS_ERR(ct))
@@ -987,9 +987,14 @@
 		ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
 #endif
 
-	help = nfct_help(ct);
-	if (help) {
-		helper = nf_ct_helper_find_get(rtuple);
+	helper = nf_ct_helper_find_get(rtuple);
+	if (helper) {
+		help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
+		if (help == NULL) {
+			nf_ct_helper_put(helper);
+			err = -ENOMEM;
+			goto err;
+		}
 		/* not in hash table yet so not strictly necessary */
 		rcu_assign_pointer(help->helper, helper);
 	}
@@ -1089,22 +1094,29 @@
 static inline int
 ctnetlink_exp_dump_mask(struct sk_buff *skb,
 			const struct nf_conntrack_tuple *tuple,
-			const struct nf_conntrack_tuple *mask)
+			const struct nf_conntrack_tuple_mask *mask)
 {
 	int ret;
 	struct nf_conntrack_l3proto *l3proto;
 	struct nf_conntrack_l4proto *l4proto;
-	struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
+	struct nf_conntrack_tuple m;
+	struct nfattr *nest_parms;
+
+	memset(&m, 0xFF, sizeof(m));
+	m.src.u.all = mask->src.u.all;
+	memcpy(&m.src.u3, &mask->src.u3, sizeof(m.src.u3));
+
+	nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
 
 	l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
-	ret = ctnetlink_dump_tuples_ip(skb, mask, l3proto);
+	ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto);
 	nf_ct_l3proto_put(l3proto);
 
 	if (unlikely(ret < 0))
 		goto nfattr_failure;
 
 	l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
-	ret = ctnetlink_dump_tuples_proto(skb, mask, l4proto);
+	ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto);
 	nf_ct_l4proto_put(l4proto);
 	if (unlikely(ret < 0))
 		goto nfattr_failure;
@@ -1223,32 +1235,52 @@
 	return NOTIFY_DONE;
 }
 #endif
+static int ctnetlink_exp_done(struct netlink_callback *cb)
+{
+	if (cb->args[1])
+		nf_ct_expect_put((struct nf_conntrack_expect *)cb->args[1]);
+	return 0;
+}
 
 static int
 ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
 {
-	struct nf_conntrack_expect *exp = NULL;
-	struct list_head *i;
-	u_int32_t *id = (u_int32_t *) &cb->args[0];
+	struct nf_conntrack_expect *exp, *last;
 	struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
+	struct hlist_node *n;
 	u_int8_t l3proto = nfmsg->nfgen_family;
 
 	read_lock_bh(&nf_conntrack_lock);
-	list_for_each_prev(i, &nf_conntrack_expect_list) {
-		exp = (struct nf_conntrack_expect *) i;
-		if (l3proto && exp->tuple.src.l3num != l3proto)
-			continue;
-		if (exp->id <= *id)
-			continue;
-		if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid,
-					    cb->nlh->nlmsg_seq,
-					    IPCTNL_MSG_EXP_NEW,
-					    1, exp) < 0)
-			goto out;
-		*id = exp->id;
+	last = (struct nf_conntrack_expect *)cb->args[1];
+	for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
+restart:
+		hlist_for_each_entry(exp, n, &nf_ct_expect_hash[cb->args[0]],
+				     hnode) {
+			if (l3proto && exp->tuple.src.l3num != l3proto)
+				continue;
+			if (cb->args[1]) {
+				if (exp != last)
+					continue;
+				cb->args[1] = 0;
+			}
+			if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid,
+						    cb->nlh->nlmsg_seq,
+						    IPCTNL_MSG_EXP_NEW,
+						    1, exp) < 0) {
+				atomic_inc(&exp->use);
+				cb->args[1] = (unsigned long)exp;
+				goto out;
+			}
+		}
+		if (cb->args[1]) {
+			cb->args[1] = 0;
+			goto restart;
+		}
 	}
 out:
 	read_unlock_bh(&nf_conntrack_lock);
+	if (last)
+		nf_ct_expect_put(last);
 
 	return skb->len;
 }
@@ -1275,7 +1307,7 @@
 	if (nlh->nlmsg_flags & NLM_F_DUMP) {
 		return netlink_dump_start(ctnl, skb, nlh,
 					  ctnetlink_exp_dump_table,
-					  ctnetlink_done);
+					  ctnetlink_exp_done);
 	}
 
 	if (cda[CTA_EXPECT_MASTER-1])
@@ -1286,14 +1318,14 @@
 	if (err < 0)
 		return err;
 
-	exp = nf_conntrack_expect_find_get(&tuple);
+	exp = nf_ct_expect_find_get(&tuple);
 	if (!exp)
 		return -ENOENT;
 
 	if (cda[CTA_EXPECT_ID-1]) {
 		__be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
 		if (exp->id != ntohl(id)) {
-			nf_conntrack_expect_put(exp);
+			nf_ct_expect_put(exp);
 			return -ENOENT;
 		}
 	}
@@ -1309,14 +1341,14 @@
 	if (err <= 0)
 		goto free;
 
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
 
 	return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
 
 free:
 	kfree_skb(skb2);
 out:
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
 	return err;
 }
 
@@ -1324,11 +1356,13 @@
 ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
 		     struct nlmsghdr *nlh, struct nfattr *cda[])
 {
-	struct nf_conntrack_expect *exp, *tmp;
+	struct nf_conntrack_expect *exp;
 	struct nf_conntrack_tuple tuple;
 	struct nf_conntrack_helper *h;
 	struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+	struct hlist_node *n, *next;
 	u_int8_t u3 = nfmsg->nfgen_family;
+	unsigned int i;
 	int err;
 
 	if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
@@ -1341,25 +1375,26 @@
 			return err;
 
 		/* bump usage count to 2 */
-		exp = nf_conntrack_expect_find_get(&tuple);
+		exp = nf_ct_expect_find_get(&tuple);
 		if (!exp)
 			return -ENOENT;
 
 		if (cda[CTA_EXPECT_ID-1]) {
 			__be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
 			if (exp->id != ntohl(id)) {
-				nf_conntrack_expect_put(exp);
+				nf_ct_expect_put(exp);
 				return -ENOENT;
 			}
 		}
 
 		/* after list removal, usage count == 1 */
-		nf_conntrack_unexpect_related(exp);
+		nf_ct_unexpect_related(exp);
 		/* have to put what we 'get' above.
 		 * after this line usage count == 0 */
-		nf_conntrack_expect_put(exp);
+		nf_ct_expect_put(exp);
 	} else if (cda[CTA_EXPECT_HELP_NAME-1]) {
 		char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]);
+		struct nf_conn_help *m_help;
 
 		/* delete all expectations for this helper */
 		write_lock_bh(&nf_conntrack_lock);
@@ -1368,24 +1403,30 @@
 			write_unlock_bh(&nf_conntrack_lock);
 			return -EINVAL;
 		}
-		list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
-					 list) {
-			struct nf_conn_help *m_help = nfct_help(exp->master);
-			if (m_help->helper == h
-			    && del_timer(&exp->timeout)) {
-				nf_ct_unlink_expect(exp);
-				nf_conntrack_expect_put(exp);
+		for (i = 0; i < nf_ct_expect_hsize; i++) {
+			hlist_for_each_entry_safe(exp, n, next,
+						  &nf_ct_expect_hash[i],
+						  hnode) {
+				m_help = nfct_help(exp->master);
+				if (m_help->helper == h
+				    && del_timer(&exp->timeout)) {
+					nf_ct_unlink_expect(exp);
+					nf_ct_expect_put(exp);
+				}
 			}
 		}
 		write_unlock_bh(&nf_conntrack_lock);
 	} else {
 		/* This basically means we have to flush everything*/
 		write_lock_bh(&nf_conntrack_lock);
-		list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
-					 list) {
-			if (del_timer(&exp->timeout)) {
-				nf_ct_unlink_expect(exp);
-				nf_conntrack_expect_put(exp);
+		for (i = 0; i < nf_ct_expect_hsize; i++) {
+			hlist_for_each_entry_safe(exp, n, next,
+						  &nf_ct_expect_hash[i],
+						  hnode) {
+				if (del_timer(&exp->timeout)) {
+					nf_ct_unlink_expect(exp);
+					nf_ct_expect_put(exp);
+				}
 			}
 		}
 		write_unlock_bh(&nf_conntrack_lock);
@@ -1421,7 +1462,7 @@
 		return err;
 
 	/* Look for master conntrack of this expectation */
-	h = nf_conntrack_find_get(&master_tuple, NULL);
+	h = nf_conntrack_find_get(&master_tuple);
 	if (!h)
 		return -ENOENT;
 	ct = nf_ct_tuplehash_to_ctrack(h);
@@ -1433,7 +1474,7 @@
 		goto out;
 	}
 
-	exp = nf_conntrack_expect_alloc(ct);
+	exp = nf_ct_expect_alloc(ct);
 	if (!exp) {
 		err = -ENOMEM;
 		goto out;
@@ -1444,10 +1485,11 @@
 	exp->master = ct;
 	exp->helper = NULL;
 	memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
-	memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple));
+	memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3));
+	exp->mask.src.u.all = mask.src.u.all;
 
-	err = nf_conntrack_expect_related(exp);
-	nf_conntrack_expect_put(exp);
+	err = nf_ct_expect_related(exp);
+	nf_ct_expect_put(exp);
 
 out:
 	nf_ct_put(nf_ct_tuplehash_to_ctrack(h));
@@ -1477,7 +1519,7 @@
 		return err;
 
 	write_lock_bh(&nf_conntrack_lock);
-	exp = __nf_conntrack_expect_find(&tuple);
+	exp = __nf_ct_expect_find(&tuple);
 
 	if (!exp) {
 		write_unlock_bh(&nf_conntrack_lock);
@@ -1567,7 +1609,7 @@
 		goto err_unreg_exp_subsys;
 	}
 
-	ret = nf_conntrack_expect_register_notifier(&ctnl_notifier_exp);
+	ret = nf_ct_expect_register_notifier(&ctnl_notifier_exp);
 	if (ret < 0) {
 		printk("ctnetlink_init: cannot expect register notifier.\n");
 		goto err_unreg_notifier;
@@ -1593,7 +1635,7 @@
 	printk("ctnetlink: unregistering from nfnetlink.\n");
 
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
-	nf_conntrack_expect_unregister_notifier(&ctnl_notifier_exp);
+	nf_ct_expect_unregister_notifier(&ctnl_notifier_exp);
 	nf_conntrack_unregister_notifier(&ctnl_notifier);
 #endif
 
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 115bcb5..b080419 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -65,7 +65,7 @@
 			     struct nf_conntrack_expect *exp) __read_mostly;
 EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
 
-#if 0
+#ifdef DEBUG
 /* PptpControlMessageType names */
 const char *pptp_msg_name[] = {
 	"UNKNOWN_MESSAGE",
@@ -86,9 +86,6 @@
 	"SET_LINK_INFO"
 };
 EXPORT_SYMBOL(pptp_msg_name);
-#define DEBUGP(format, args...)	printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
-#else
-#define DEBUGP(format, args...)
 #endif
 
 #define SECS *HZ
@@ -102,7 +99,7 @@
 			 struct nf_conntrack_expect *exp)
 {
 	typeof(nf_nat_pptp_hook_expectfn) nf_nat_pptp_expectfn;
-	DEBUGP("increasing timeouts\n");
+	pr_debug("increasing timeouts\n");
 
 	/* increase timeout of GRE data channel conntrack entry */
 	ct->proto.gre.timeout	     = PPTP_GRE_TIMEOUT;
@@ -121,17 +118,17 @@
 
 		/* obviously this tuple inversion only works until you do NAT */
 		nf_ct_invert_tuplepr(&inv_t, &exp->tuple);
-		DEBUGP("trying to unexpect other dir: ");
+		pr_debug("trying to unexpect other dir: ");
 		NF_CT_DUMP_TUPLE(&inv_t);
 
-		exp_other = nf_conntrack_expect_find_get(&inv_t);
+		exp_other = nf_ct_expect_find_get(&inv_t);
 		if (exp_other) {
 			/* delete other expectation.  */
-			DEBUGP("found\n");
-			nf_conntrack_unexpect_related(exp_other);
-			nf_conntrack_expect_put(exp_other);
+			pr_debug("found\n");
+			nf_ct_unexpect_related(exp_other);
+			nf_ct_expect_put(exp_other);
 		} else {
-			DEBUGP("not found\n");
+			pr_debug("not found\n");
 		}
 	}
 	rcu_read_unlock();
@@ -143,13 +140,13 @@
 	struct nf_conntrack_expect *exp;
 	struct nf_conn *sibling;
 
-	DEBUGP("trying to timeout ct or exp for tuple ");
+	pr_debug("trying to timeout ct or exp for tuple ");
 	NF_CT_DUMP_TUPLE(t);
 
-	h = nf_conntrack_find_get(t, NULL);
+	h = nf_conntrack_find_get(t);
 	if (h)  {
 		sibling = nf_ct_tuplehash_to_ctrack(h);
-		DEBUGP("setting timeout of conntrack %p to 0\n", sibling);
+		pr_debug("setting timeout of conntrack %p to 0\n", sibling);
 		sibling->proto.gre.timeout	  = 0;
 		sibling->proto.gre.stream_timeout = 0;
 		if (del_timer(&sibling->timeout))
@@ -157,11 +154,11 @@
 		nf_ct_put(sibling);
 		return 1;
 	} else {
-		exp = nf_conntrack_expect_find_get(t);
+		exp = nf_ct_expect_find_get(t);
 		if (exp) {
-			DEBUGP("unexpect_related of expect %p\n", exp);
-			nf_conntrack_unexpect_related(exp);
-			nf_conntrack_expect_put(exp);
+			pr_debug("unexpect_related of expect %p\n", exp);
+			nf_ct_unexpect_related(exp);
+			nf_ct_expect_put(exp);
 			return 1;
 		}
 	}
@@ -182,7 +179,7 @@
 	t.src.u.gre.key = help->help.ct_pptp_info.pns_call_id;
 	t.dst.u.gre.key = help->help.ct_pptp_info.pac_call_id;
 	if (!destroy_sibling_or_exp(&t))
-		DEBUGP("failed to timeout original pns->pac ct/exp\n");
+		pr_debug("failed to timeout original pns->pac ct/exp\n");
 
 	/* try reply (pac->pns) tuple */
 	memcpy(&t, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, sizeof(t));
@@ -190,7 +187,7 @@
 	t.src.u.gre.key = help->help.ct_pptp_info.pac_call_id;
 	t.dst.u.gre.key = help->help.ct_pptp_info.pns_call_id;
 	if (!destroy_sibling_or_exp(&t))
-		DEBUGP("failed to timeout reply pac->pns ct/exp\n");
+		pr_debug("failed to timeout reply pac->pns ct/exp\n");
 }
 
 /* expect GRE connections (PNS->PAC and PAC->PNS direction) */
@@ -201,36 +198,36 @@
 	int ret = 1;
 	typeof(nf_nat_pptp_hook_exp_gre) nf_nat_pptp_exp_gre;
 
-	exp_orig = nf_conntrack_expect_alloc(ct);
+	exp_orig = nf_ct_expect_alloc(ct);
 	if (exp_orig == NULL)
 		goto out;
 
-	exp_reply = nf_conntrack_expect_alloc(ct);
+	exp_reply = nf_ct_expect_alloc(ct);
 	if (exp_reply == NULL)
 		goto out_put_orig;
 
 	/* original direction, PNS->PAC */
 	dir = IP_CT_DIR_ORIGINAL;
-	nf_conntrack_expect_init(exp_orig, ct->tuplehash[dir].tuple.src.l3num,
-				 &ct->tuplehash[dir].tuple.src.u3,
-				 &ct->tuplehash[dir].tuple.dst.u3,
-				 IPPROTO_GRE, &peer_callid, &callid);
+	nf_ct_expect_init(exp_orig, ct->tuplehash[dir].tuple.src.l3num,
+			  &ct->tuplehash[dir].tuple.src.u3,
+			  &ct->tuplehash[dir].tuple.dst.u3,
+			  IPPROTO_GRE, &peer_callid, &callid);
 	exp_orig->expectfn = pptp_expectfn;
 
 	/* reply direction, PAC->PNS */
 	dir = IP_CT_DIR_REPLY;
-	nf_conntrack_expect_init(exp_reply, ct->tuplehash[dir].tuple.src.l3num,
-				 &ct->tuplehash[dir].tuple.src.u3,
-				 &ct->tuplehash[dir].tuple.dst.u3,
-				 IPPROTO_GRE, &callid, &peer_callid);
+	nf_ct_expect_init(exp_reply, ct->tuplehash[dir].tuple.src.l3num,
+			  &ct->tuplehash[dir].tuple.src.u3,
+			  &ct->tuplehash[dir].tuple.dst.u3,
+			  IPPROTO_GRE, &callid, &peer_callid);
 	exp_reply->expectfn = pptp_expectfn;
 
 	nf_nat_pptp_exp_gre = rcu_dereference(nf_nat_pptp_hook_exp_gre);
 	if (nf_nat_pptp_exp_gre && ct->status & IPS_NAT_MASK)
 		nf_nat_pptp_exp_gre(exp_orig, exp_reply);
-	if (nf_conntrack_expect_related(exp_orig) != 0)
+	if (nf_ct_expect_related(exp_orig) != 0)
 		goto out_put_both;
-	if (nf_conntrack_expect_related(exp_reply) != 0)
+	if (nf_ct_expect_related(exp_reply) != 0)
 		goto out_unexpect_orig;
 
 	/* Add GRE keymap entries */
@@ -243,16 +240,16 @@
 	ret = 0;
 
 out_put_both:
-	nf_conntrack_expect_put(exp_reply);
+	nf_ct_expect_put(exp_reply);
 out_put_orig:
-	nf_conntrack_expect_put(exp_orig);
+	nf_ct_expect_put(exp_orig);
 out:
 	return ret;
 
 out_unexpect_both:
-	nf_conntrack_unexpect_related(exp_reply);
+	nf_ct_unexpect_related(exp_reply);
 out_unexpect_orig:
-	nf_conntrack_unexpect_related(exp_orig);
+	nf_ct_unexpect_related(exp_orig);
 	goto out_put_both;
 }
 
@@ -270,7 +267,7 @@
 	typeof(nf_nat_pptp_hook_inbound) nf_nat_pptp_inbound;
 
 	msg = ntohs(ctlh->messageType);
-	DEBUGP("inbound control message %s\n", pptp_msg_name[msg]);
+	pr_debug("inbound control message %s\n", pptp_msg_name[msg]);
 
 	switch (msg) {
 	case PPTP_START_SESSION_REPLY:
@@ -305,8 +302,8 @@
 		pcid = pptpReq->ocack.peersCallID;
 		if (info->pns_call_id != pcid)
 			goto invalid;
-		DEBUGP("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg],
-			ntohs(cid), ntohs(pcid));
+		pr_debug("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg],
+			 ntohs(cid), ntohs(pcid));
 
 		if (pptpReq->ocack.resultCode == PPTP_OUTCALL_CONNECT) {
 			info->cstate = PPTP_CALL_OUT_CONF;
@@ -322,7 +319,7 @@
 			goto invalid;
 
 		cid = pptpReq->icreq.callID;
-		DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
+		pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
 		info->cstate = PPTP_CALL_IN_REQ;
 		info->pac_call_id = cid;
 		break;
@@ -341,7 +338,7 @@
 		if (info->pns_call_id != pcid)
 			goto invalid;
 
-		DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid));
+		pr_debug("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid));
 		info->cstate = PPTP_CALL_IN_CONF;
 
 		/* we expect a GRE connection from PAC to PNS */
@@ -351,7 +348,7 @@
 	case PPTP_CALL_DISCONNECT_NOTIFY:
 		/* server confirms disconnect */
 		cid = pptpReq->disc.callID;
-		DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
+		pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
 		info->cstate = PPTP_CALL_NONE;
 
 		/* untrack this call id, unexpect GRE packets */
@@ -374,11 +371,11 @@
 	return NF_ACCEPT;
 
 invalid:
-	DEBUGP("invalid %s: type=%d cid=%u pcid=%u "
-	       "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
-	       msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
-	       msg, ntohs(cid), ntohs(pcid),  info->cstate, info->sstate,
-	       ntohs(info->pns_call_id), ntohs(info->pac_call_id));
+	pr_debug("invalid %s: type=%d cid=%u pcid=%u "
+		 "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
+		 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
+		 msg, ntohs(cid), ntohs(pcid),  info->cstate, info->sstate,
+		 ntohs(info->pns_call_id), ntohs(info->pac_call_id));
 	return NF_ACCEPT;
 }
 
@@ -396,7 +393,7 @@
 	typeof(nf_nat_pptp_hook_outbound) nf_nat_pptp_outbound;
 
 	msg = ntohs(ctlh->messageType);
-	DEBUGP("outbound control message %s\n", pptp_msg_name[msg]);
+	pr_debug("outbound control message %s\n", pptp_msg_name[msg]);
 
 	switch (msg) {
 	case PPTP_START_SESSION_REQUEST:
@@ -418,7 +415,7 @@
 		info->cstate = PPTP_CALL_OUT_REQ;
 		/* track PNS call id */
 		cid = pptpReq->ocreq.callID;
-		DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
+		pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
 		info->pns_call_id = cid;
 		break;
 
@@ -432,8 +429,8 @@
 		pcid = pptpReq->icack.peersCallID;
 		if (info->pac_call_id != pcid)
 			goto invalid;
-		DEBUGP("%s, CID=%X PCID=%X\n", pptp_msg_name[msg],
-		       ntohs(cid), ntohs(pcid));
+		pr_debug("%s, CID=%X PCID=%X\n", pptp_msg_name[msg],
+			 ntohs(cid), ntohs(pcid));
 
 		if (pptpReq->icack.resultCode == PPTP_INCALL_ACCEPT) {
 			/* part two of the three-way handshake */
@@ -469,11 +466,11 @@
 	return NF_ACCEPT;
 
 invalid:
-	DEBUGP("invalid %s: type=%d cid=%u pcid=%u "
-	       "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
-	       msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
-	       msg, ntohs(cid), ntohs(pcid),  info->cstate, info->sstate,
-	       ntohs(info->pns_call_id), ntohs(info->pac_call_id));
+	pr_debug("invalid %s: type=%d cid=%u pcid=%u "
+		 "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
+		 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
+		 msg, ntohs(cid), ntohs(pcid),  info->cstate, info->sstate,
+		 ntohs(info->pns_call_id), ntohs(info->pac_call_id));
 	return NF_ACCEPT;
 }
 
@@ -524,7 +521,7 @@
 
 	pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph);
 	if (!pptph) {
-		DEBUGP("no full PPTP header, can't track\n");
+		pr_debug("no full PPTP header, can't track\n");
 		return NF_ACCEPT;
 	}
 	nexthdr_off += sizeof(_pptph);
@@ -533,7 +530,7 @@
 	/* if it's not a control message we can't do anything with it */
 	if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL ||
 	    ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) {
-		DEBUGP("not a control packet\n");
+		pr_debug("not a control packet\n");
 		return NF_ACCEPT;
 	}
 
@@ -569,8 +566,8 @@
 		/* server -> client (PAC -> PNS) */
 		ret = pptp_inbound_pkt(pskb, ctlh, pptpReq, reqlen, ct,
 				       ctinfo);
-	DEBUGP("sstate: %d->%d, cstate: %d->%d\n",
-		oldsstate, info->sstate, oldcstate, info->cstate);
+	pr_debug("sstate: %d->%d, cstate: %d->%d\n",
+		 oldsstate, info->sstate, oldcstate, info->cstate);
 	spin_unlock_bh(&nf_pptp_lock);
 
 	return ret;
@@ -585,9 +582,6 @@
 	.tuple.src.l3num	= AF_INET,
 	.tuple.src.u.tcp.port	= __constant_htons(PPTP_CONTROL_PORT),
 	.tuple.dst.protonum	= IPPROTO_TCP,
-	.mask.src.l3num		= 0xffff,
-	.mask.src.u.tcp.port	= __constant_htons(0xffff),
-	.mask.dst.protonum	= 0xff,
 	.help			= conntrack_pptp_help,
 	.destroy		= pptp_destroy_siblings,
 };
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 339c397..771c4c2 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -40,12 +40,6 @@
 #define GRE_TIMEOUT		(30 * HZ)
 #define GRE_STREAM_TIMEOUT	(180 * HZ)
 
-#if 0
-#define DEBUGP(format, args...)	printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
-#else
-#define DEBUGP(x, args...)
-#endif
-
 static DEFINE_RWLOCK(nf_ct_gre_lock);
 static LIST_HEAD(gre_keymap_list);
 
@@ -87,7 +81,7 @@
 	}
 	read_unlock_bh(&nf_ct_gre_lock);
 
-	DEBUGP("lookup src key 0x%x for ", key);
+	pr_debug("lookup src key 0x%x for ", key);
 	NF_CT_DUMP_TUPLE(t);
 
 	return key;
@@ -107,8 +101,8 @@
 			if (gre_key_cmpfn(km, t) && km == *kmp)
 				return 0;
 		}
-		DEBUGP("trying to override keymap_%s for ct %p\n",
-			dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct);
+		pr_debug("trying to override keymap_%s for ct %p\n",
+			 dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct);
 		return -EEXIST;
 	}
 
@@ -118,7 +112,7 @@
 	memcpy(&km->tuple, t, sizeof(*t));
 	*kmp = km;
 
-	DEBUGP("adding new entry %p: ", km);
+	pr_debug("adding new entry %p: ", km);
 	NF_CT_DUMP_TUPLE(&km->tuple);
 
 	write_lock_bh(&nf_ct_gre_lock);
@@ -135,13 +129,13 @@
 	struct nf_conn_help *help = nfct_help(ct);
 	enum ip_conntrack_dir dir;
 
-	DEBUGP("entering for ct %p\n", ct);
+	pr_debug("entering for ct %p\n", ct);
 
 	write_lock_bh(&nf_ct_gre_lock);
 	for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) {
 		if (help->help.ct_pptp_info.keymap[dir]) {
-			DEBUGP("removing %p from list\n",
-				help->help.ct_pptp_info.keymap[dir]);
+			pr_debug("removing %p from list\n",
+				 help->help.ct_pptp_info.keymap[dir]);
 			list_del(&help->help.ct_pptp_info.keymap[dir]->list);
 			kfree(help->help.ct_pptp_info.keymap[dir]);
 			help->help.ct_pptp_info.keymap[dir] = NULL;
@@ -186,7 +180,7 @@
 		return 1;
 
 	if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) {
-		DEBUGP("GRE_VERSION_PPTP but unknown proto\n");
+		pr_debug("GRE_VERSION_PPTP but unknown proto\n");
 		return 0;
 	}
 
@@ -242,7 +236,7 @@
 static int gre_new(struct nf_conn *ct, const struct sk_buff *skb,
 		   unsigned int dataoff)
 {
-	DEBUGP(": ");
+	pr_debug(": ");
 	NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
 
 	/* initialize to sane value.  Ideally a conntrack helper
@@ -258,10 +252,10 @@
 static void gre_destroy(struct nf_conn *ct)
 {
 	struct nf_conn *master = ct->master;
-	DEBUGP(" entering\n");
+	pr_debug(" entering\n");
 
 	if (!master)
-		DEBUGP("no master !?!\n");
+		pr_debug("no master !?!\n");
 	else
 		nf_ct_gre_keymap_destroy(master);
 }
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 0d3254b..debfe61 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -25,12 +25,6 @@
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
 
-#if 0
-#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Protects conntrack->proto.sctp */
 static DEFINE_RWLOCK(sctp_lock);
 
@@ -151,9 +145,6 @@
 {
 	sctp_sctphdr_t _hdr, *hp;
 
-	DEBUGP(__FUNCTION__);
-	DEBUGP("\n");
-
 	/* Actually only need first 8 bytes. */
 	hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
 	if (hp == NULL)
@@ -167,9 +158,6 @@
 static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
 			     const struct nf_conntrack_tuple *orig)
 {
-	DEBUGP(__FUNCTION__);
-	DEBUGP("\n");
-
 	tuple->src.u.sctp.port = orig->dst.u.sctp.port;
 	tuple->dst.u.sctp.port = orig->src.u.sctp.port;
 	return 1;
@@ -179,9 +167,6 @@
 static int sctp_print_tuple(struct seq_file *s,
 			    const struct nf_conntrack_tuple *tuple)
 {
-	DEBUGP(__FUNCTION__);
-	DEBUGP("\n");
-
 	return seq_printf(s, "sport=%hu dport=%hu ",
 			  ntohs(tuple->src.u.sctp.port),
 			  ntohs(tuple->dst.u.sctp.port));
@@ -193,9 +178,6 @@
 {
 	enum sctp_conntrack state;
 
-	DEBUGP(__FUNCTION__);
-	DEBUGP("\n");
-
 	read_lock_bh(&sctp_lock);
 	state = conntrack->proto.sctp.state;
 	read_unlock_bh(&sctp_lock);
@@ -219,13 +201,10 @@
 	sctp_chunkhdr_t _sch, *sch;
 	int flag;
 
-	DEBUGP(__FUNCTION__);
-	DEBUGP("\n");
-
 	flag = 0;
 
 	for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
-		DEBUGP("Chunk Num: %d  Type: %d\n", count, sch->type);
+		pr_debug("Chunk Num: %d  Type: %d\n", count, sch->type);
 
 		if (sch->type == SCTP_CID_INIT
 			|| sch->type == SCTP_CID_INIT_ACK
@@ -242,7 +221,7 @@
 			|| sch->type == SCTP_CID_COOKIE_ECHO
 			|| flag)
 		      && count !=0) || !sch->length) {
-			DEBUGP("Basic checks failed\n");
+			pr_debug("Basic checks failed\n");
 			return 1;
 		}
 
@@ -251,7 +230,7 @@
 		}
 	}
 
-	DEBUGP("Basic checks passed\n");
+	pr_debug("Basic checks passed\n");
 	return count == 0;
 }
 
@@ -261,50 +240,47 @@
 {
 	int i;
 
-	DEBUGP(__FUNCTION__);
-	DEBUGP("\n");
-
-	DEBUGP("Chunk type: %d\n", chunk_type);
+	pr_debug("Chunk type: %d\n", chunk_type);
 
 	switch (chunk_type) {
 		case SCTP_CID_INIT:
-			DEBUGP("SCTP_CID_INIT\n");
+			pr_debug("SCTP_CID_INIT\n");
 			i = 0; break;
 		case SCTP_CID_INIT_ACK:
-			DEBUGP("SCTP_CID_INIT_ACK\n");
+			pr_debug("SCTP_CID_INIT_ACK\n");
 			i = 1; break;
 		case SCTP_CID_ABORT:
-			DEBUGP("SCTP_CID_ABORT\n");
+			pr_debug("SCTP_CID_ABORT\n");
 			i = 2; break;
 		case SCTP_CID_SHUTDOWN:
-			DEBUGP("SCTP_CID_SHUTDOWN\n");
+			pr_debug("SCTP_CID_SHUTDOWN\n");
 			i = 3; break;
 		case SCTP_CID_SHUTDOWN_ACK:
-			DEBUGP("SCTP_CID_SHUTDOWN_ACK\n");
+			pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
 			i = 4; break;
 		case SCTP_CID_ERROR:
-			DEBUGP("SCTP_CID_ERROR\n");
+			pr_debug("SCTP_CID_ERROR\n");
 			i = 5; break;
 		case SCTP_CID_COOKIE_ECHO:
-			DEBUGP("SCTP_CID_COOKIE_ECHO\n");
+			pr_debug("SCTP_CID_COOKIE_ECHO\n");
 			i = 6; break;
 		case SCTP_CID_COOKIE_ACK:
-			DEBUGP("SCTP_CID_COOKIE_ACK\n");
+			pr_debug("SCTP_CID_COOKIE_ACK\n");
 			i = 7; break;
 		case SCTP_CID_SHUTDOWN_COMPLETE:
-			DEBUGP("SCTP_CID_SHUTDOWN_COMPLETE\n");
+			pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
 			i = 8; break;
 		default:
 			/* Other chunks like DATA, SACK, HEARTBEAT and
 			its ACK do not cause a change in state */
-			DEBUGP("Unknown chunk type, Will stay in %s\n",
-						sctp_conntrack_names[cur_state]);
+			pr_debug("Unknown chunk type, Will stay in %s\n",
+				 sctp_conntrack_names[cur_state]);
 			return cur_state;
 	}
 
-	DEBUGP("dir: %d   cur_state: %s  chunk_type: %d  new_state: %s\n",
-			dir, sctp_conntrack_names[cur_state], chunk_type,
-			sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
+	pr_debug("dir: %d   cur_state: %s  chunk_type: %d  new_state: %s\n",
+		 dir, sctp_conntrack_names[cur_state], chunk_type,
+		 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
 
 	return sctp_conntracks[dir][i][cur_state];
 }
@@ -323,9 +299,6 @@
 	u_int32_t offset, count;
 	char map[256 / sizeof (char)] = {0};
 
-	DEBUGP(__FUNCTION__);
-	DEBUGP("\n");
-
 	sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
 	if (sh == NULL)
 		return -1;
@@ -340,7 +313,7 @@
 		&& !test_bit(SCTP_CID_ABORT, (void *)map)
 		&& !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map)
 		&& (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
-		DEBUGP("Verification tag check failed\n");
+		pr_debug("Verification tag check failed\n");
 		return -1;
 	}
 
@@ -385,8 +358,9 @@
 
 		/* Invalid */
 		if (newconntrack == SCTP_CONNTRACK_MAX) {
-			DEBUGP("nf_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",
-			       CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
+			pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
+				 "conntrack=%u\n",
+				 CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
 			write_unlock_bh(&sctp_lock);
 			return -1;
 		}
@@ -402,8 +376,8 @@
 					write_unlock_bh(&sctp_lock);
 					return -1;
 			}
-			DEBUGP("Setting vtag %x for dir %d\n",
-					ih->init_tag, !CTINFO2DIR(ctinfo));
+			pr_debug("Setting vtag %x for dir %d\n",
+				 ih->init_tag, !CTINFO2DIR(ctinfo));
 			conntrack->proto.sctp.vtag[!CTINFO2DIR(ctinfo)] = ih->init_tag;
 		}
 
@@ -418,7 +392,7 @@
 	if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED
 		&& CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY
 		&& newconntrack == SCTP_CONNTRACK_ESTABLISHED) {
-		DEBUGP("Setting assured bit\n");
+		pr_debug("Setting assured bit\n");
 		set_bit(IPS_ASSURED_BIT, &conntrack->status);
 		nf_conntrack_event_cache(IPCT_STATUS, skb);
 	}
@@ -436,9 +410,6 @@
 	u_int32_t offset, count;
 	char map[256 / sizeof (char)] = {0};
 
-	DEBUGP(__FUNCTION__);
-	DEBUGP("\n");
-
 	sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
 	if (sh == NULL)
 		return 0;
@@ -460,8 +431,9 @@
 					 SCTP_CONNTRACK_NONE, sch->type);
 
 		/* Invalid: delete conntrack */
-		if (newconntrack == SCTP_CONNTRACK_MAX) {
-			DEBUGP("nf_conntrack_sctp: invalid new deleting.\n");
+		if (newconntrack == SCTP_CONNTRACK_NONE ||
+		    newconntrack == SCTP_CONNTRACK_MAX) {
+			pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
 			return 0;
 		}
 
@@ -475,8 +447,8 @@
 				if (ih == NULL)
 					return 0;
 
-				DEBUGP("Setting vtag %x for new conn\n",
-					ih->init_tag);
+				pr_debug("Setting vtag %x for new conn\n",
+					 ih->init_tag);
 
 				conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =
 								ih->init_tag;
@@ -488,8 +460,8 @@
 		/* If it is a shutdown ack OOTB packet, we expect a return
 		   shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
 		else {
-			DEBUGP("Setting vtag %x for new conn OOTB\n",
-				sh->vtag);
+			pr_debug("Setting vtag %x for new conn OOTB\n",
+				 sh->vtag);
 			conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
 		}
 
@@ -688,8 +660,6 @@
  cleanup_sctp4:
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
  out:
-	DEBUGP("SCTP conntrack module loading %s\n",
-					ret ? "failed": "succeeded");
 	return ret;
 }
 
@@ -697,7 +667,6 @@
 {
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
 	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
-	DEBUGP("SCTP conntrack module unloaded\n");
 }
 
 module_init(nf_conntrack_proto_sctp_init);
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index ccdd5d2..1c8206e 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -26,13 +26,6 @@
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
 
-#if 0
-#define DEBUGP printk
-#define DEBUGP_VARS
-#else
-#define DEBUGP(format, args...)
-#endif
-
 /* Protects conntrack->proto.tcp */
 static DEFINE_RWLOCK(tcp_lock);
 
@@ -496,7 +489,8 @@
 	}
 }
 
-static int tcp_in_window(struct ip_ct_tcp *state,
+static int tcp_in_window(struct nf_conn *ct,
+			 struct ip_ct_tcp *state,
 			 enum ip_conntrack_dir dir,
 			 unsigned int index,
 			 const struct sk_buff *skb,
@@ -506,6 +500,7 @@
 {
 	struct ip_ct_tcp_state *sender = &state->seen[dir];
 	struct ip_ct_tcp_state *receiver = &state->seen[!dir];
+	struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
 	__u32 seq, ack, sack, end, win, swin;
 	int res;
 
@@ -520,18 +515,17 @@
 	if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM)
 		tcp_sack(skb, dataoff, tcph, &sack);
 
-	DEBUGP("tcp_in_window: START\n");
-	DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
-	       "seq=%u ack=%u sack=%u win=%u end=%u\n",
-		NIPQUAD(iph->saddr), ntohs(tcph->source),
-		NIPQUAD(iph->daddr), ntohs(tcph->dest),
-		seq, ack, sack, win, end);
-	DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
-	       "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-		sender->td_end, sender->td_maxend, sender->td_maxwin,
-		sender->td_scale,
-		receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
-		receiver->td_scale);
+	pr_debug("tcp_in_window: START\n");
+	pr_debug("tcp_in_window: ");
+	NF_CT_DUMP_TUPLE(tuple);
+	pr_debug("seq=%u ack=%u sack=%u win=%u end=%u\n",
+		 seq, ack, sack, win, end);
+	pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
+		 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
+		 sender->td_end, sender->td_maxend, sender->td_maxwin,
+		 sender->td_scale,
+		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+		 receiver->td_scale);
 
 	if (sender->td_end == 0) {
 		/*
@@ -609,23 +603,22 @@
 		 */
 		seq = end = sender->td_end;
 
-	DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
-	       "seq=%u ack=%u sack =%u win=%u end=%u\n",
-		NIPQUAD(iph->saddr), ntohs(tcph->source),
-		NIPQUAD(iph->daddr), ntohs(tcph->dest),
-		seq, ack, sack, win, end);
-	DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
-	       "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-		sender->td_end, sender->td_maxend, sender->td_maxwin,
-		sender->td_scale,
-		receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
-		receiver->td_scale);
+	pr_debug("tcp_in_window: ");
+	NF_CT_DUMP_TUPLE(tuple);
+	pr_debug("seq=%u ack=%u sack =%u win=%u end=%u\n",
+		 seq, ack, sack, win, end);
+	pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
+		 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
+		 sender->td_end, sender->td_maxend, sender->td_maxwin,
+		 sender->td_scale,
+		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+		 receiver->td_scale);
 
-	DEBUGP("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
-		before(seq, sender->td_maxend + 1),
-		after(end, sender->td_end - receiver->td_maxwin - 1),
-		before(sack, receiver->td_end + 1),
-		after(ack, receiver->td_end - MAXACKWINDOW(sender)));
+	pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
+		 before(seq, sender->td_maxend + 1),
+		 after(end, sender->td_end - receiver->td_maxwin - 1),
+		 before(sack, receiver->td_end + 1),
+		 after(ack, receiver->td_end - MAXACKWINDOW(sender)));
 
 	if (before(seq, sender->td_maxend + 1) &&
 	    after(end, sender->td_end - receiver->td_maxwin - 1) &&
@@ -694,10 +687,10 @@
 			: "SEQ is over the upper bound (over the window of the receiver)");
 	}
 
-	DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
-	       "receiver end=%u maxend=%u maxwin=%u\n",
-		res, sender->td_end, sender->td_maxend, sender->td_maxwin,
-		receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
+	pr_debug("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
+		 "receiver end=%u maxend=%u maxwin=%u\n",
+		 res, sender->td_end, sender->td_maxend, sender->td_maxwin,
+		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
 
 	return res;
 }
@@ -711,11 +704,9 @@
 			     int dir)
 {
 	struct tcphdr *tcph = (void *)skb->data + dataoff;
-	__u32 end;
-#ifdef DEBUGP_VARS
 	struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[dir];
 	struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[!dir];
-#endif
+	__u32 end;
 
 	end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph);
 
@@ -727,12 +718,12 @@
 		conntrack->proto.tcp.seen[dir].td_end = end;
 	conntrack->proto.tcp.last_end = end;
 	write_unlock_bh(&tcp_lock);
-	DEBUGP("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
-	       "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-		sender->td_end, sender->td_maxend, sender->td_maxwin,
-		sender->td_scale,
-		receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
-		receiver->td_scale);
+	pr_debug("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
+		 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
+		 sender->td_end, sender->td_maxend, sender->td_maxwin,
+		 sender->td_scale,
+		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+		 receiver->td_scale);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update);
 #endif
@@ -823,6 +814,7 @@
 		      int pf,
 		      unsigned int hooknum)
 {
+	struct nf_conntrack_tuple *tuple;
 	enum tcp_conntrack new_state, old_state;
 	enum ip_conntrack_dir dir;
 	struct tcphdr *th, _tcph;
@@ -837,6 +829,7 @@
 	dir = CTINFO2DIR(ctinfo);
 	index = get_conntrack_index(th);
 	new_state = tcp_conntracks[dir][index][old_state];
+	tuple = &conntrack->tuplehash[dir].tuple;
 
 	switch (new_state) {
 	case TCP_CONNTRACK_IGNORE:
@@ -880,9 +873,8 @@
 		return NF_ACCEPT;
 	case TCP_CONNTRACK_MAX:
 		/* Invalid packet */
-		DEBUGP("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
-		       dir, get_conntrack_index(th),
-		       old_state);
+		pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
+			 dir, get_conntrack_index(th), old_state);
 		write_unlock_bh(&tcp_lock);
 		if (LOG_INVALID(IPPROTO_TCP))
 			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
@@ -933,7 +925,7 @@
 		break;
 	}
 
-	if (!tcp_in_window(&conntrack->proto.tcp, dir, index,
+	if (!tcp_in_window(conntrack, &conntrack->proto.tcp, dir, index,
 			   skb, dataoff, th, pf)) {
 		write_unlock_bh(&tcp_lock);
 		return -NF_ACCEPT;
@@ -942,13 +934,12 @@
 	/* From now on we have got in-window packets */
 	conntrack->proto.tcp.last_index = index;
 
-	DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
-	       "syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
-		NIPQUAD(iph->saddr), ntohs(th->source),
-		NIPQUAD(iph->daddr), ntohs(th->dest),
-		(th->syn ? 1 : 0), (th->ack ? 1 : 0),
-		(th->fin ? 1 : 0), (th->rst ? 1 : 0),
-		old_state, new_state);
+	pr_debug("tcp_conntracks: ");
+	NF_CT_DUMP_TUPLE(tuple);
+	pr_debug("syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
+		 (th->syn ? 1 : 0), (th->ack ? 1 : 0),
+		 (th->fin ? 1 : 0), (th->rst ? 1 : 0),
+		 old_state, new_state);
 
 	conntrack->proto.tcp.state = new_state;
 	if (old_state != new_state
@@ -997,10 +988,8 @@
 {
 	enum tcp_conntrack new_state;
 	struct tcphdr *th, _tcph;
-#ifdef DEBUGP_VARS
 	struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[0];
 	struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[1];
-#endif
 
 	th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
 	BUG_ON(th == NULL);
@@ -1012,7 +1001,7 @@
 
 	/* Invalid: delete conntrack */
 	if (new_state >= TCP_CONNTRACK_MAX) {
-		DEBUGP("nf_ct_tcp: invalid new deleting.\n");
+		pr_debug("nf_ct_tcp: invalid new deleting.\n");
 		return 0;
 	}
 
@@ -1065,12 +1054,12 @@
 	conntrack->proto.tcp.state = TCP_CONNTRACK_NONE;
 	conntrack->proto.tcp.last_index = TCP_NONE_SET;
 
-	DEBUGP("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
-	       "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
-		sender->td_end, sender->td_maxend, sender->td_maxwin,
-		sender->td_scale,
-		receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
-		receiver->td_scale);
+	pr_debug("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
+		 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
+		 sender->td_end, sender->td_maxend, sender->td_maxwin,
+		 sender->td_scale,
+		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+		 receiver->td_scale);
 	return 1;
 }
 
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index eb2d1dc..355d371 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -40,12 +40,6 @@
 static unsigned int ports_c;
 module_param_array(ports, ushort, &ports_c, 0400);
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 struct sane_request {
 	__be32 RPC_code;
 #define SANE_NET_START      7   /* RPC code */
@@ -125,15 +119,15 @@
 	ct_sane_info->state = SANE_STATE_NORMAL;
 
 	if (datalen < sizeof(struct sane_reply_net_start)) {
-		DEBUGP("nf_ct_sane: NET_START reply too short\n");
+		pr_debug("nf_ct_sane: NET_START reply too short\n");
 		goto out;
 	}
 
 	reply = (struct sane_reply_net_start *)sb_ptr;
 	if (reply->status != htonl(SANE_STATUS_SUCCESS)) {
 		/* saned refused the command */
-		DEBUGP("nf_ct_sane: unsuccessful SANE_STATUS = %u\n",
-			ntohl(reply->status));
+		pr_debug("nf_ct_sane: unsuccessful SANE_STATUS = %u\n",
+			 ntohl(reply->status));
 		goto out;
 	}
 
@@ -141,35 +135,32 @@
 	if (reply->zero != 0)
 		goto out;
 
-	exp = nf_conntrack_expect_alloc(ct);
+	exp = nf_ct_expect_alloc(ct);
 	if (exp == NULL) {
 		ret = NF_DROP;
 		goto out;
 	}
 
 	tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
-	nf_conntrack_expect_init(exp, family,
-				 &tuple->src.u3, &tuple->dst.u3,
-				 IPPROTO_TCP,
-				 NULL, &reply->port);
+	nf_ct_expect_init(exp, family, &tuple->src.u3, &tuple->dst.u3,
+			  IPPROTO_TCP, NULL, &reply->port);
 
-	DEBUGP("nf_ct_sane: expect: ");
+	pr_debug("nf_ct_sane: expect: ");
 	NF_CT_DUMP_TUPLE(&exp->tuple);
-	NF_CT_DUMP_TUPLE(&exp->mask);
 
 	/* Can't expect this?  Best to drop packet now. */
-	if (nf_conntrack_expect_related(exp) != 0)
+	if (nf_ct_expect_related(exp) != 0)
 		ret = NF_DROP;
 
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
 
 out:
 	spin_unlock_bh(&nf_sane_lock);
 	return ret;
 }
 
-static struct nf_conntrack_helper sane[MAX_PORTS][2];
-static char sane_names[MAX_PORTS][2][sizeof("sane-65535")];
+static struct nf_conntrack_helper sane[MAX_PORTS][2] __read_mostly;
+static char sane_names[MAX_PORTS][2][sizeof("sane-65535")] __read_mostly;
 
 /* don't make this __exit, since it's called from __init ! */
 static void nf_conntrack_sane_fini(void)
@@ -178,9 +169,9 @@
 
 	for (i = 0; i < ports_c; i++) {
 		for (j = 0; j < 2; j++) {
-			DEBUGP("nf_ct_sane: unregistering helper for pf: %d "
-			       "port: %d\n",
-				sane[i][j].tuple.src.l3num, ports[i]);
+			pr_debug("nf_ct_sane: unregistering helper for pf: %d "
+				 "port: %d\n",
+				 sane[i][j].tuple.src.l3num, ports[i]);
 			nf_conntrack_helper_unregister(&sane[i][j]);
 		}
 	}
@@ -208,8 +199,6 @@
 		for (j = 0; j < 2; j++) {
 			sane[i][j].tuple.src.u.tcp.port = htons(ports[i]);
 			sane[i][j].tuple.dst.protonum = IPPROTO_TCP;
-			sane[i][j].mask.src.u.tcp.port = 0xFFFF;
-			sane[i][j].mask.dst.protonum = 0xFF;
 			sane[i][j].max_expected = 1;
 			sane[i][j].timeout = 5 * 60;	/* 5 Minutes */
 			sane[i][j].me = THIS_MODULE;
@@ -221,9 +210,9 @@
 				sprintf(tmpname, "sane-%d", ports[i]);
 			sane[i][j].name = tmpname;
 
-			DEBUGP("nf_ct_sane: registering helper for pf: %d "
-			       "port: %d\n",
-				sane[i][j].tuple.src.l3num, ports[i]);
+			pr_debug("nf_ct_sane: registering helper for pf: %d "
+				 "port: %d\n",
+				 sane[i][j].tuple.src.l3num, ports[i]);
 			ret = nf_conntrack_helper_register(&sane[i][j]);
 			if (ret) {
 				printk(KERN_ERR "nf_ct_sane: failed to "
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 1b5c6c1..1276a44 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -21,12 +21,6 @@
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <linux/netfilter/nf_conntrack_sip.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
 MODULE_DESCRIPTION("SIP connection tracking helper");
@@ -285,7 +279,7 @@
 	const char *aux = dptr;
 
 	if (!parse_addr(ct, dptr, &dptr, &addr, limit)) {
-		DEBUGP("ip: %s parse failed.!\n", dptr);
+		pr_debug("ip: %s parse failed.!\n", dptr);
 		return 0;
 	}
 
@@ -344,8 +338,8 @@
 				    ct_sip_lnlen(dptr, limit),
 				    hnfo->case_sensitive);
 		if (!aux) {
-			DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str,
-			       hnfo->lname);
+			pr_debug("'%s' not found in '%s'.\n", hnfo->ln_str,
+				 hnfo->lname);
 			return -1;
 		}
 		aux += hnfo->ln_strlen;
@@ -356,11 +350,11 @@
 
 		*matchoff = (aux - k) + shift;
 
-		DEBUGP("%s match succeeded! - len: %u\n", hnfo->lname,
-		       *matchlen);
+		pr_debug("%s match succeeded! - len: %u\n", hnfo->lname,
+			 *matchlen);
 		return 1;
 	}
-	DEBUGP("%s header not found.\n", hnfo->lname);
+	pr_debug("%s header not found.\n", hnfo->lname);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(ct_sip_get_info);
@@ -378,23 +372,23 @@
 	int ret;
 	typeof(nf_nat_sdp_hook) nf_nat_sdp;
 
-	exp = nf_conntrack_expect_alloc(ct);
+	exp = nf_ct_expect_alloc(ct);
 	if (exp == NULL)
 		return NF_DROP;
-	nf_conntrack_expect_init(exp, family,
-				 &ct->tuplehash[!dir].tuple.src.u3, addr,
-				 IPPROTO_UDP, NULL, &port);
+	nf_ct_expect_init(exp, family,
+			  &ct->tuplehash[!dir].tuple.src.u3, addr,
+			  IPPROTO_UDP, NULL, &port);
 
 	nf_nat_sdp = rcu_dereference(nf_nat_sdp_hook);
 	if (nf_nat_sdp && ct->status & IPS_NAT_MASK)
 		ret = nf_nat_sdp(pskb, ctinfo, exp, dptr);
 	else {
-		if (nf_conntrack_expect_related(exp) != 0)
+		if (nf_ct_expect_related(exp) != 0)
 			ret = NF_DROP;
 		else
 			ret = NF_ACCEPT;
 	}
-	nf_conntrack_expect_put(exp);
+	nf_ct_expect_put(exp);
 
 	return ret;
 }
@@ -424,7 +418,7 @@
 	if (!skb_is_nonlinear(*pskb))
 		dptr = (*pskb)->data + dataoff;
 	else {
-		DEBUGP("Copy of skbuff not supported yet.\n");
+		pr_debug("Copy of skbuff not supported yet.\n");
 		goto out;
 	}
 
@@ -506,9 +500,6 @@
 		for (j = 0; j < 2; j++) {
 			sip[i][j].tuple.dst.protonum = IPPROTO_UDP;
 			sip[i][j].tuple.src.u.udp.port = htons(ports[i]);
-			sip[i][j].mask.src.l3num = 0xFFFF;
-			sip[i][j].mask.src.u.udp.port = htons(0xFFFF);
-			sip[i][j].mask.dst.protonum = 0xFF;
 			sip[i][j].max_expected = 2;
 			sip[i][j].timeout = 3 * 60; /* 3 minutes */
 			sip[i][j].me = THIS_MODULE;
@@ -521,7 +512,7 @@
 				sprintf(tmpname, "sip-%u", i);
 			sip[i][j].name = tmpname;
 
-			DEBUGP("port #%u: %u\n", i, ports[i]);
+			pr_debug("port #%u: %u\n", i, ports[i]);
 
 			ret = nf_conntrack_helper_register(&sip[i][j]);
 			if (ret) {
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 45baeb0..ffb6ff8 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -25,12 +25,6 @@
 #include <net/netfilter/nf_conntrack_expect.h>
 #include <net/netfilter/nf_conntrack_helper.h>
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 MODULE_LICENSE("GPL");
 
 #ifdef CONFIG_PROC_FS
@@ -60,35 +54,36 @@
 	unsigned int bucket;
 };
 
-static struct list_head *ct_get_first(struct seq_file *seq)
+static struct hlist_node *ct_get_first(struct seq_file *seq)
 {
 	struct ct_iter_state *st = seq->private;
 
 	for (st->bucket = 0;
 	     st->bucket < nf_conntrack_htable_size;
 	     st->bucket++) {
-		if (!list_empty(&nf_conntrack_hash[st->bucket]))
-			return nf_conntrack_hash[st->bucket].next;
+		if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
+			return nf_conntrack_hash[st->bucket].first;
 	}
 	return NULL;
 }
 
-static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head)
+static struct hlist_node *ct_get_next(struct seq_file *seq,
+				      struct hlist_node *head)
 {
 	struct ct_iter_state *st = seq->private;
 
 	head = head->next;
-	while (head == &nf_conntrack_hash[st->bucket]) {
+	while (head == NULL) {
 		if (++st->bucket >= nf_conntrack_htable_size)
 			return NULL;
-		head = nf_conntrack_hash[st->bucket].next;
+		head = nf_conntrack_hash[st->bucket].first;
 	}
 	return head;
 }
 
-static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos)
+static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
 {
-	struct list_head *head = ct_get_first(seq);
+	struct hlist_node *head = ct_get_first(seq);
 
 	if (head)
 		while (pos && (head = ct_get_next(seq, head)))
@@ -190,7 +185,7 @@
 	return 0;
 }
 
-static struct seq_operations ct_seq_ops = {
+static const struct seq_operations ct_seq_ops = {
 	.start = ct_seq_start,
 	.next  = ct_seq_next,
 	.stop  = ct_seq_stop,
@@ -294,7 +289,7 @@
 	return 0;
 }
 
-static struct seq_operations ct_cpu_seq_ops = {
+static const struct seq_operations ct_cpu_seq_ops = {
 	.start	= ct_cpu_seq_start,
 	.next	= ct_cpu_seq_next,
 	.stop	= ct_cpu_seq_stop,
@@ -371,7 +366,14 @@
 		.extra1		= &log_invalid_proto_min,
 		.extra2		= &log_invalid_proto_max,
 	},
-
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "nf_conntrack_expect_max",
+		.data		= &nf_ct_expect_max,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
 	{ .ctl_name = 0 }
 };
 
@@ -410,7 +412,7 @@
 static int __init nf_conntrack_standalone_init(void)
 {
 #ifdef CONFIG_PROC_FS
-	struct proc_dir_entry *proc, *proc_exp, *proc_stat;
+	struct proc_dir_entry *proc, *proc_stat;
 #endif
 	int ret = 0;
 
@@ -422,13 +424,9 @@
 	proc = proc_net_fops_create("nf_conntrack", 0440, &ct_file_ops);
 	if (!proc) goto cleanup_init;
 
-	proc_exp = proc_net_fops_create("nf_conntrack_expect", 0440,
-					&exp_file_ops);
-	if (!proc_exp) goto cleanup_proc;
-
 	proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, proc_net_stat);
 	if (!proc_stat)
-		goto cleanup_proc_exp;
+		goto cleanup_proc;
 
 	proc_stat->proc_fops = &ct_cpu_seq_fops;
 	proc_stat->owner = THIS_MODULE;
@@ -448,8 +446,6 @@
 #endif
 #ifdef CONFIG_PROC_FS
 	remove_proc_entry("nf_conntrack", proc_net_stat);
- cleanup_proc_exp:
-	proc_net_remove("nf_conntrack_expect");
  cleanup_proc:
 	proc_net_remove("nf_conntrack");
  cleanup_init:
@@ -465,7 +461,6 @@
 #endif
 #ifdef CONFIG_PROC_FS
 	remove_proc_entry("nf_conntrack", proc_net_stat);
-	proc_net_remove("nf_conntrack_expect");
 	proc_net_remove("nf_conntrack");
 #endif /* CNFIG_PROC_FS */
 	nf_conntrack_cleanup();
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index 37c4542..cc19506 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -29,13 +29,6 @@
 module_param_array(ports, ushort, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "Port numbers of TFTP servers");
 
-#if 0
-#define DEBUGP(format, args...) printk("%s:%s:" format, \
-				       __FILE__, __FUNCTION__ , ## args)
-#else
-#define DEBUGP(format, args...)
-#endif
-
 unsigned int (*nf_nat_tftp_hook)(struct sk_buff **pskb,
 				 enum ip_conntrack_info ctinfo,
 				 struct nf_conntrack_expect *exp) __read_mostly;
@@ -62,39 +55,35 @@
 	case TFTP_OPCODE_READ:
 	case TFTP_OPCODE_WRITE:
 		/* RRQ and WRQ works the same way */
-		DEBUGP("");
 		NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
 		NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
 
-		exp = nf_conntrack_expect_alloc(ct);
+		exp = nf_ct_expect_alloc(ct);
 		if (exp == NULL)
 			return NF_DROP;
 		tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
-		nf_conntrack_expect_init(exp, family,
-					 &tuple->src.u3, &tuple->dst.u3,
-					 IPPROTO_UDP,
-					 NULL, &tuple->dst.u.udp.port);
+		nf_ct_expect_init(exp, family, &tuple->src.u3, &tuple->dst.u3,
+				  IPPROTO_UDP, NULL, &tuple->dst.u.udp.port);
 
-		DEBUGP("expect: ");
+		pr_debug("expect: ");
 		NF_CT_DUMP_TUPLE(&exp->tuple);
-		NF_CT_DUMP_TUPLE(&exp->mask);
 
 		nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook);
 		if (nf_nat_tftp && ct->status & IPS_NAT_MASK)
 			ret = nf_nat_tftp(pskb, ctinfo, exp);
-		else if (nf_conntrack_expect_related(exp) != 0)
+		else if (nf_ct_expect_related(exp) != 0)
 			ret = NF_DROP;
-		nf_conntrack_expect_put(exp);
+		nf_ct_expect_put(exp);
 		break;
 	case TFTP_OPCODE_DATA:
 	case TFTP_OPCODE_ACK:
-		DEBUGP("Data/ACK opcode\n");
+		pr_debug("Data/ACK opcode\n");
 		break;
 	case TFTP_OPCODE_ERROR:
-		DEBUGP("Error opcode\n");
+		pr_debug("Error opcode\n");
 		break;
 	default:
-		DEBUGP("Unknown opcode\n");
+		pr_debug("Unknown opcode\n");
 	}
 	return ret;
 }
@@ -128,9 +117,6 @@
 		for (j = 0; j < 2; j++) {
 			tftp[i][j].tuple.dst.protonum = IPPROTO_UDP;
 			tftp[i][j].tuple.src.u.udp.port = htons(ports[i]);
-			tftp[i][j].mask.src.l3num = 0xFFFF;
-			tftp[i][j].mask.dst.protonum = 0xFF;
-			tftp[i][j].mask.src.u.udp.port = htons(0xFFFF);
 			tftp[i][j].max_expected = 1;
 			tftp[i][j].timeout = 5 * 60; /* 5 minutes */
 			tftp[i][j].me = THIS_MODULE;
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 91b220c..9498579 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -140,7 +140,7 @@
 	return seq_printf(s, "%2lld %s\n", *pos, logger->name);
 }
 
-static struct seq_operations nflog_seq_ops = {
+static const struct seq_operations nflog_seq_ops = {
 	.start	= seq_start,
 	.next	= seq_next,
 	.stop	= seq_stop,
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index b1f2ace..a481a34 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -17,7 +17,7 @@
  */
 static struct nf_queue_handler *queue_handler[NPROTO];
 
-static DEFINE_RWLOCK(queue_handler_lock);
+static DEFINE_MUTEX(queue_handler_mutex);
 
 /* return EBUSY when somebody else is registered, return EEXIST if the
  * same handler is registered, return 0 in case of success. */
@@ -28,30 +28,37 @@
 	if (pf >= NPROTO)
 		return -EINVAL;
 
-	write_lock_bh(&queue_handler_lock);
+	mutex_lock(&queue_handler_mutex);
 	if (queue_handler[pf] == qh)
 		ret = -EEXIST;
 	else if (queue_handler[pf])
 		ret = -EBUSY;
 	else {
-		queue_handler[pf] = qh;
+		rcu_assign_pointer(queue_handler[pf], qh);
 		ret = 0;
 	}
-	write_unlock_bh(&queue_handler_lock);
+	mutex_unlock(&queue_handler_mutex);
 
 	return ret;
 }
 EXPORT_SYMBOL(nf_register_queue_handler);
 
 /* The caller must flush their queue before this */
-int nf_unregister_queue_handler(int pf)
+int nf_unregister_queue_handler(int pf, struct nf_queue_handler *qh)
 {
 	if (pf >= NPROTO)
 		return -EINVAL;
 
-	write_lock_bh(&queue_handler_lock);
-	queue_handler[pf] = NULL;
-	write_unlock_bh(&queue_handler_lock);
+	mutex_lock(&queue_handler_mutex);
+	if (queue_handler[pf] != qh) {
+		mutex_unlock(&queue_handler_mutex);
+		return -EINVAL;
+	}
+
+	rcu_assign_pointer(queue_handler[pf], NULL);
+	mutex_unlock(&queue_handler_mutex);
+
+	synchronize_rcu();
 
 	return 0;
 }
@@ -61,12 +68,14 @@
 {
 	int pf;
 
-	write_lock_bh(&queue_handler_lock);
+	mutex_lock(&queue_handler_mutex);
 	for (pf = 0; pf < NPROTO; pf++)  {
 		if (queue_handler[pf] == qh)
-			queue_handler[pf] = NULL;
+			rcu_assign_pointer(queue_handler[pf], NULL);
 	}
-	write_unlock_bh(&queue_handler_lock);
+	mutex_unlock(&queue_handler_mutex);
+
+	synchronize_rcu();
 }
 EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
 
@@ -89,18 +98,21 @@
 	struct net_device *physoutdev = NULL;
 #endif
 	struct nf_afinfo *afinfo;
+	struct nf_queue_handler *qh;
 
 	/* QUEUE == DROP if noone is waiting, to be safe. */
-	read_lock(&queue_handler_lock);
-	if (!queue_handler[pf]) {
-		read_unlock(&queue_handler_lock);
+	rcu_read_lock();
+
+	qh = rcu_dereference(queue_handler[pf]);
+	if (!qh) {
+		rcu_read_unlock();
 		kfree_skb(skb);
 		return 1;
 	}
 
 	afinfo = nf_get_afinfo(pf);
 	if (!afinfo) {
-		read_unlock(&queue_handler_lock);
+		rcu_read_unlock();
 		kfree_skb(skb);
 		return 1;
 	}
@@ -110,7 +122,7 @@
 		if (net_ratelimit())
 			printk(KERN_ERR "OOM queueing packet %p\n",
 			       skb);
-		read_unlock(&queue_handler_lock);
+		rcu_read_unlock();
 		kfree_skb(skb);
 		return 1;
 	}
@@ -120,7 +132,7 @@
 
 	/* If it's going away, ignore hook. */
 	if (!try_module_get(info->elem->owner)) {
-		read_unlock(&queue_handler_lock);
+		rcu_read_unlock();
 		kfree(info);
 		return 0;
 	}
@@ -138,10 +150,9 @@
 	}
 #endif
 	afinfo->saveroute(skb, info);
-	status = queue_handler[pf]->outfn(skb, info, queuenum,
-					  queue_handler[pf]->data);
+	status = qh->outfn(skb, info, queuenum, qh->data);
 
-	read_unlock(&queue_handler_lock);
+	rcu_read_unlock();
 
 	if (status < 0) {
 		/* James M doesn't say fuck enough. */
@@ -308,18 +319,18 @@
 	loff_t *pos = v;
 	struct nf_queue_handler *qh;
 
-	read_lock_bh(&queue_handler_lock);
-	qh = queue_handler[*pos];
+	rcu_read_lock();
+	qh = rcu_dereference(queue_handler[*pos]);
 	if (!qh)
 		ret = seq_printf(s, "%2lld NONE\n", *pos);
 	else
 		ret = seq_printf(s, "%2lld %s\n", *pos, qh->name);
-	read_unlock_bh(&queue_handler_lock);
+	rcu_read_unlock();
 
 	return ret;
 }
 
-static struct seq_operations nfqueue_seq_ops = {
+static const struct seq_operations nfqueue_seq_ops = {
 	.start	= seq_start,
 	.next	= seq_next,
 	.stop	= seq_stop,
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index e32e30e..e185a5b 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -962,7 +962,7 @@
 			  inst->flushtimeout, atomic_read(&inst->use));
 }
 
-static struct seq_operations nful_seq_ops = {
+static const struct seq_operations nful_seq_ops = {
 	.start	= seq_start,
 	.next	= seq_next,
 	.stop	= seq_stop,
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 7a97bec..bb65a38 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -913,9 +913,7 @@
 		case NFQNL_CFG_CMD_PF_UNBIND:
 			QDEBUG("unregistering queue handler for pf=%u\n",
 				ntohs(cmd->pf));
-			/* This is a bug and a feature.  We can unregister
-			 * other handlers(!) */
-			ret = nf_unregister_queue_handler(ntohs(cmd->pf));
+			ret = nf_unregister_queue_handler(ntohs(cmd->pf), &nfqh);
 			break;
 		default:
 			ret = -EINVAL;
@@ -1050,7 +1048,7 @@
 			  atomic_read(&inst->use));
 }
 
-static struct seq_operations nfqnl_seq_ops = {
+static const struct seq_operations nfqnl_seq_ops = {
 	.start	= seq_start,
 	.next	= seq_next,
 	.stop	= seq_stop,
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 0eb2504..cc2baa6 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -320,8 +320,8 @@
 		return -EINVAL;
 	}
 	if (match->hooks && (hook_mask & ~match->hooks) != 0) {
-		printk("%s_tables: %s match: bad hook_mask %u\n",
-		       xt_prefix[family], match->name, hook_mask);
+		printk("%s_tables: %s match: bad hook_mask %u/%u\n",
+		       xt_prefix[family], match->name, hook_mask, match->hooks);
 		return -EINVAL;
 	}
 	if (match->proto && (match->proto != proto || inv_proto)) {
@@ -410,8 +410,9 @@
 		return -EINVAL;
 	}
 	if (target->hooks && (hook_mask & ~target->hooks) != 0) {
-		printk("%s_tables: %s target: bad hook_mask %u\n",
-		       xt_prefix[family], target->name, hook_mask);
+		printk("%s_tables: %s target: bad hook_mask %u/%u\n",
+		       xt_prefix[family], target->name, hook_mask,
+		       target->hooks);
 		return -EINVAL;
 	}
 	if (target->proto && (target->proto != proto || inv_proto)) {
@@ -744,7 +745,7 @@
 		return 0;
 }
 
-static struct seq_operations xt_tgt_seq_ops = {
+static const struct seq_operations xt_tgt_seq_ops = {
 	.start	= xt_tgt_seq_start,
 	.next	= xt_tgt_seq_next,
 	.stop	= xt_tgt_seq_stop,
diff --git a/net/netfilter/xt_CLASSIFY.c b/net/netfilter/xt_CLASSIFY.c
index 3088483..5194285 100644
--- a/net/netfilter/xt_CLASSIFY.c
+++ b/net/netfilter/xt_CLASSIFY.c
@@ -39,7 +39,7 @@
 	return XT_CONTINUE;
 }
 
-static struct xt_target xt_classify_target[] = {
+static struct xt_target xt_classify_target[] __read_mostly = {
 	{
 		.family		= AF_INET,
 		.name 		= "CLASSIFY",
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index b03ce00..5a00c54 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -76,33 +76,33 @@
 	return XT_CONTINUE;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *entry,
 	   const struct xt_target *target,
 	   void *targinfo,
 	   unsigned int hook_mask)
 {
-	struct xt_connmark_target_info *matchinfo = targinfo;
+	const struct xt_connmark_target_info *matchinfo = targinfo;
 
 	if (nf_ct_l3proto_try_module_get(target->family) < 0) {
 		printk(KERN_WARNING "can't load conntrack support for "
 				    "proto=%d\n", target->family);
-		return 0;
+		return false;
 	}
 	if (matchinfo->mode == XT_CONNMARK_RESTORE) {
 		if (strcmp(tablename, "mangle") != 0) {
 			printk(KERN_WARNING "CONNMARK: restore can only be "
 			       "called from \"mangle\" table, not \"%s\"\n",
 			       tablename);
-			return 0;
+			return false;
 		}
 	}
 	if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) {
 		printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n");
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
 static void
@@ -121,7 +121,7 @@
 
 static void compat_from_user(void *dst, void *src)
 {
-	struct compat_xt_connmark_target_info *cm = src;
+	const struct compat_xt_connmark_target_info *cm = src;
 	struct xt_connmark_target_info m = {
 		.mark	= cm->mark,
 		.mask	= cm->mask,
@@ -132,7 +132,7 @@
 
 static int compat_to_user(void __user *dst, void *src)
 {
-	struct xt_connmark_target_info *m = src;
+	const struct xt_connmark_target_info *m = src;
 	struct compat_xt_connmark_target_info cm = {
 		.mark	= m->mark,
 		.mask	= m->mask,
@@ -142,7 +142,7 @@
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_target xt_connmark_target[] = {
+static struct xt_target xt_connmark_target[] __read_mostly = {
 	{
 		.name		= "CONNMARK",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 81c0c58..63d7313 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -33,7 +33,7 @@
  * If the packet has a security mark and the connection does not, copy
  * the security mark from the packet to the connection.
  */
-static void secmark_save(struct sk_buff *skb)
+static void secmark_save(const struct sk_buff *skb)
 {
 	if (skb->secmark) {
 		struct nf_conn *ct;
@@ -85,16 +85,16 @@
 	return XT_CONTINUE;
 }
 
-static int checkentry(const char *tablename, const void *entry,
-		      const struct xt_target *target, void *targinfo,
-		      unsigned int hook_mask)
+static bool checkentry(const char *tablename, const void *entry,
+		       const struct xt_target *target, void *targinfo,
+		       unsigned int hook_mask)
 {
-	struct xt_connsecmark_target_info *info = targinfo;
+	const struct xt_connsecmark_target_info *info = targinfo;
 
 	if (nf_ct_l3proto_try_module_get(target->family) < 0) {
 		printk(KERN_WARNING "can't load conntrack support for "
 				    "proto=%d\n", target->family);
-		return 0;
+		return false;
 	}
 	switch (info->mode) {
 	case CONNSECMARK_SAVE:
@@ -103,10 +103,10 @@
 
 	default:
 		printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode);
-		return 0;
+		return false;
 	}
 
-	return 1;
+	return true;
 }
 
 static void
@@ -115,7 +115,7 @@
 	nf_ct_l3proto_module_put(target->family);
 }
 
-static struct xt_target xt_connsecmark_target[] = {
+static struct xt_target xt_connsecmark_target[] __read_mostly = {
 	{
 		.name		= "CONNSECMARK",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c
index 9f2f220..798ab73 100644
--- a/net/netfilter/xt_DSCP.c
+++ b/net/netfilter/xt_DSCP.c
@@ -66,22 +66,22 @@
 	return XT_CONTINUE;
 }
 
-static int checkentry(const char *tablename,
-		      const void *e_void,
-		      const struct xt_target *target,
-		      void *targinfo,
-		      unsigned int hook_mask)
+static bool checkentry(const char *tablename,
+		       const void *e_void,
+		       const struct xt_target *target,
+		       void *targinfo,
+		       unsigned int hook_mask)
 {
 	const u_int8_t dscp = ((struct xt_DSCP_info *)targinfo)->dscp;
 
-	if ((dscp > XT_DSCP_MAX)) {
+	if (dscp > XT_DSCP_MAX) {
 		printk(KERN_WARNING "DSCP: dscp %x out of range\n", dscp);
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_target xt_dscp_target[] = {
+static struct xt_target xt_dscp_target[] __read_mostly = {
 	{
 		.name		= "DSCP",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c
index 4381780..f30fe0b 100644
--- a/net/netfilter/xt_MARK.c
+++ b/net/netfilter/xt_MARK.c
@@ -65,43 +65,43 @@
 }
 
 
-static int
+static bool
 checkentry_v0(const char *tablename,
 	      const void *entry,
 	      const struct xt_target *target,
 	      void *targinfo,
 	      unsigned int hook_mask)
 {
-	struct xt_mark_target_info *markinfo = targinfo;
+	const struct xt_mark_target_info *markinfo = targinfo;
 
 	if (markinfo->mark > 0xffffffff) {
 		printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static int
+static bool
 checkentry_v1(const char *tablename,
 	      const void *entry,
 	      const struct xt_target *target,
 	      void *targinfo,
 	      unsigned int hook_mask)
 {
-	struct xt_mark_target_info_v1 *markinfo = targinfo;
+	const struct xt_mark_target_info_v1 *markinfo = targinfo;
 
 	if (markinfo->mode != XT_MARK_SET
 	    && markinfo->mode != XT_MARK_AND
 	    && markinfo->mode != XT_MARK_OR) {
 		printk(KERN_WARNING "MARK: unknown mode %u\n",
 		       markinfo->mode);
-		return 0;
+		return false;
 	}
 	if (markinfo->mark > 0xffffffff) {
 		printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
 #ifdef CONFIG_COMPAT
@@ -114,7 +114,7 @@
 
 static void compat_from_user_v1(void *dst, void *src)
 {
-	struct compat_xt_mark_target_info_v1 *cm = src;
+	const struct compat_xt_mark_target_info_v1 *cm = src;
 	struct xt_mark_target_info_v1 m = {
 		.mark	= cm->mark,
 		.mode	= cm->mode,
@@ -124,7 +124,7 @@
 
 static int compat_to_user_v1(void __user *dst, void *src)
 {
-	struct xt_mark_target_info_v1 *m = src;
+	const struct xt_mark_target_info_v1 *m = src;
 	struct compat_xt_mark_target_info_v1 cm = {
 		.mark	= m->mark,
 		.mode	= m->mode,
@@ -133,7 +133,7 @@
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_target xt_mark_target[] = {
+static struct xt_target xt_mark_target[] __read_mostly = {
 	{
 		.name		= "MARK",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c
index 901ed7a..d3594c7 100644
--- a/net/netfilter/xt_NFLOG.c
+++ b/net/netfilter/xt_NFLOG.c
@@ -38,21 +38,21 @@
 	return XT_CONTINUE;
 }
 
-static int
+static bool
 nflog_checkentry(const char *tablename, const void *entry,
 		 const struct xt_target *target, void *targetinfo,
 		 unsigned int hookmask)
 {
-	struct xt_nflog_info *info = targetinfo;
+	const struct xt_nflog_info *info = targetinfo;
 
 	if (info->flags & ~XT_NFLOG_MASK)
-		return 0;
+		return false;
 	if (info->prefix[sizeof(info->prefix) - 1] != '\0')
-		return 0;
-	return 1;
+		return false;
+	return true;
 }
 
-static struct xt_target xt_nflog_target[] = {
+static struct xt_target xt_nflog_target[] __read_mostly = {
 	{
 		.name		= "NFLOG",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c
index 201155b..13f59f3 100644
--- a/net/netfilter/xt_NFQUEUE.c
+++ b/net/netfilter/xt_NFQUEUE.c
@@ -36,7 +36,7 @@
 	return NF_QUEUE_NR(tinfo->queuenum);
 }
 
-static struct xt_target xt_nfqueue_target[] = {
+static struct xt_target xt_nfqueue_target[] __read_mostly = {
 	{
 		.name		= "NFQUEUE",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c
index 5085fb3..b7d6312 100644
--- a/net/netfilter/xt_NOTRACK.c
+++ b/net/netfilter/xt_NOTRACK.c
@@ -33,7 +33,7 @@
 	return XT_CONTINUE;
 }
 
-static struct xt_target xt_notrack_target[] = {
+static struct xt_target xt_notrack_target[] __read_mostly = {
 	{
 		.name		= "NOTRACK",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 705f0e8..c83779a 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -51,7 +51,7 @@
 	return XT_CONTINUE;
 }
 
-static int checkentry_selinux(struct xt_secmark_target_info *info)
+static bool checkentry_selinux(struct xt_secmark_target_info *info)
 {
 	int err;
 	struct xt_secmark_target_selinux_info *sel = &info->u.sel;
@@ -63,53 +63,53 @@
 		if (err == -EINVAL)
 			printk(KERN_INFO PFX "invalid SELinux context \'%s\'\n",
 			       sel->selctx);
-		return 0;
+		return false;
 	}
 
 	if (!sel->selsid) {
 		printk(KERN_INFO PFX "unable to map SELinux context \'%s\'\n",
 		       sel->selctx);
-		return 0;
+		return false;
 	}
 
 	err = selinux_relabel_packet_permission(sel->selsid);
 	if (err) {
 		printk(KERN_INFO PFX "unable to obtain relabeling permission\n");
-		return 0;
+		return false;
 	}
 
-	return 1;
+	return true;
 }
 
-static int checkentry(const char *tablename, const void *entry,
-		      const struct xt_target *target, void *targinfo,
-		      unsigned int hook_mask)
+static bool checkentry(const char *tablename, const void *entry,
+		       const struct xt_target *target, void *targinfo,
+		       unsigned int hook_mask)
 {
 	struct xt_secmark_target_info *info = targinfo;
 
 	if (mode && mode != info->mode) {
 		printk(KERN_INFO PFX "mode already set to %hu cannot mix with "
 		       "rules for mode %hu\n", mode, info->mode);
-		return 0;
+		return false;
 	}
 
 	switch (info->mode) {
 	case SECMARK_MODE_SEL:
 		if (!checkentry_selinux(info))
-			return 0;
+			return false;
 		break;
 
 	default:
 		printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode);
-		return 0;
+		return false;
 	}
 
 	if (!mode)
 		mode = info->mode;
-	return 1;
+	return true;
 }
 
-static struct xt_target xt_secmark_target[] = {
+static struct xt_target xt_secmark_target[] __read_mostly = {
 	{
 		.name		= "SECMARK",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index 15fe8f6..d40f7e4 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -93,7 +93,7 @@
 				return 0;
 
 			opt[i+2] = (newmss & 0xff00) >> 8;
-			opt[i+3] = (newmss & 0x00ff);
+			opt[i+3] = newmss & 0x00ff;
 
 			nf_proto_csum_replace2(&tcph->check, *pskb,
 					       htons(oldmss), htons(newmss), 0);
@@ -126,7 +126,7 @@
 	opt[0] = TCPOPT_MSS;
 	opt[1] = TCPOLEN_MSS;
 	opt[2] = (newmss & 0xff00) >> 8;
-	opt[3] = (newmss & 0x00ff);
+	opt[3] = newmss & 0x00ff;
 
 	nf_proto_csum_replace4(&tcph->check, *pskb, 0, *((__be32 *)opt), 0);
 
@@ -197,19 +197,19 @@
 #define TH_SYN 0x02
 
 /* Must specify -p tcp --syn */
-static inline int find_syn_match(const struct xt_entry_match *m)
+static inline bool find_syn_match(const struct xt_entry_match *m)
 {
 	const struct xt_tcp *tcpinfo = (const struct xt_tcp *)m->data;
 
 	if (strcmp(m->u.kernel.match->name, "tcp") == 0 &&
 	    tcpinfo->flg_cmp & TH_SYN &&
 	    !(tcpinfo->invflags & XT_TCP_INV_FLAGS))
-		return 1;
+		return true;
 
-	return 0;
+	return false;
 }
 
-static int
+static bool
 xt_tcpmss_checkentry4(const char *tablename,
 		      const void *entry,
 		      const struct xt_target *target,
@@ -225,16 +225,16 @@
 			   (1 << NF_IP_POST_ROUTING))) != 0) {
 		printk("xt_TCPMSS: path-MTU clamping only supported in "
 		       "FORWARD, OUTPUT and POSTROUTING hooks\n");
-		return 0;
+		return false;
 	}
 	if (IPT_MATCH_ITERATE(e, find_syn_match))
-		return 1;
+		return true;
 	printk("xt_TCPMSS: Only works on TCP SYN packets\n");
-	return 0;
+	return false;
 }
 
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
-static int
+static bool
 xt_tcpmss_checkentry6(const char *tablename,
 		      const void *entry,
 		      const struct xt_target *target,
@@ -250,16 +250,16 @@
 			   (1 << NF_IP6_POST_ROUTING))) != 0) {
 		printk("xt_TCPMSS: path-MTU clamping only supported in "
 		       "FORWARD, OUTPUT and POSTROUTING hooks\n");
-		return 0;
+		return false;
 	}
 	if (IP6T_MATCH_ITERATE(e, find_syn_match))
-		return 1;
+		return true;
 	printk("xt_TCPMSS: Only works on TCP SYN packets\n");
-	return 0;
+	return false;
 }
 #endif
 
-static struct xt_target xt_tcpmss_reg[] = {
+static struct xt_target xt_tcpmss_reg[] __read_mostly = {
 	{
 		.family		= AF_INET,
 		.name		= "TCPMSS",
diff --git a/net/netfilter/xt_TRACE.c b/net/netfilter/xt_TRACE.c
new file mode 100644
index 0000000..4df2ded
--- /dev/null
+++ b/net/netfilter/xt_TRACE.c
@@ -0,0 +1,53 @@
+/* This is a module which is used to mark packets for tracing.
+ */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+
+#include <linux/netfilter/x_tables.h>
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_TRACE");
+MODULE_ALIAS("ip6t_TRACE");
+
+static unsigned int
+target(struct sk_buff **pskb,
+       const struct net_device *in,
+       const struct net_device *out,
+       unsigned int hooknum,
+       const struct xt_target *target,
+       const void *targinfo)
+{
+	(*pskb)->nf_trace = 1;
+	return XT_CONTINUE;
+}
+
+static struct xt_target xt_trace_target[] __read_mostly = {
+	{
+		.name		= "TRACE",
+		.family		= AF_INET,
+		.target		= target,
+		.table		= "raw",
+		.me		= THIS_MODULE,
+	},
+	{
+		.name		= "TRACE",
+		.family		= AF_INET6,
+		.target		= target,
+		.table		= "raw",
+		.me		= THIS_MODULE,
+	},
+};
+
+static int __init xt_trace_init(void)
+{
+	return xt_register_targets(xt_trace_target,
+				   ARRAY_SIZE(xt_trace_target));
+}
+
+static void __exit xt_trace_fini(void)
+{
+	xt_unregister_targets(xt_trace_target, ARRAY_SIZE(xt_trace_target));
+}
+
+module_init(xt_trace_init);
+module_exit(xt_trace_fini);
diff --git a/net/netfilter/xt_comment.c b/net/netfilter/xt_comment.c
index 7db492d..64bcdb0 100644
--- a/net/netfilter/xt_comment.c
+++ b/net/netfilter/xt_comment.c
@@ -15,7 +15,7 @@
 MODULE_ALIAS("ipt_comment");
 MODULE_ALIAS("ip6t_comment");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -23,13 +23,13 @@
       const void *matchinfo,
       int offset,
       unsigned int protooff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	/* We always match */
-	return 1;
+	return true;
 }
 
-static struct xt_match xt_comment_match[] = {
+static struct xt_match xt_comment_match[] __read_mostly = {
 	{
 		.name		= "comment",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index 804afe5..dd4d79b 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -15,7 +15,7 @@
 MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection");
 MODULE_ALIAS("ipt_connbytes");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -23,10 +23,10 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct xt_connbytes_info *sinfo = matchinfo;
-	struct nf_conn *ct;
+	const struct nf_conn *ct;
 	enum ip_conntrack_info ctinfo;
 	u_int64_t what = 0;	/* initialize to make gcc happy */
 	u_int64_t bytes = 0;
@@ -35,7 +35,7 @@
 
 	ct = nf_ct_get(skb, &ctinfo);
 	if (!ct)
-		return 0;
+		return false;
 	counters = ct->counters;
 
 	switch (sinfo->what) {
@@ -90,36 +90,36 @@
 	}
 
 	if (sinfo->count.to)
-		return (what <= sinfo->count.to && what >= sinfo->count.from);
+		return what <= sinfo->count.to && what >= sinfo->count.from;
 	else
-		return (what >= sinfo->count.from);
+		return what >= sinfo->count.from;
 }
 
-static int check(const char *tablename,
-		 const void *ip,
-		 const struct xt_match *match,
-		 void *matchinfo,
-		 unsigned int hook_mask)
+static bool check(const char *tablename,
+		  const void *ip,
+		  const struct xt_match *match,
+		  void *matchinfo,
+		  unsigned int hook_mask)
 {
 	const struct xt_connbytes_info *sinfo = matchinfo;
 
 	if (sinfo->what != XT_CONNBYTES_PKTS &&
 	    sinfo->what != XT_CONNBYTES_BYTES &&
 	    sinfo->what != XT_CONNBYTES_AVGPKT)
-		return 0;
+		return false;
 
 	if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL &&
 	    sinfo->direction != XT_CONNBYTES_DIR_REPLY &&
 	    sinfo->direction != XT_CONNBYTES_DIR_BOTH)
-		return 0;
+		return false;
 
 	if (nf_ct_l3proto_try_module_get(match->family) < 0) {
 		printk(KERN_WARNING "can't load conntrack support for "
 				    "proto=%d\n", match->family);
-		return 0;
+		return false;
 	}
 
-	return 1;
+	return true;
 }
 
 static void
@@ -128,7 +128,7 @@
 	nf_ct_l3proto_module_put(match->family);
 }
 
-static struct xt_match xt_connbytes_match[] = {
+static struct xt_match xt_connbytes_match[] __read_mostly = {
 	{
 		.name		= "connbytes",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index e180325..e73fa9b 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -30,7 +30,7 @@
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_connmark");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -38,38 +38,38 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct xt_connmark_info *info = matchinfo;
-	struct nf_conn *ct;
+	const struct nf_conn *ct;
 	enum ip_conntrack_info ctinfo;
 
 	ct = nf_ct_get(skb, &ctinfo);
 	if (!ct)
-		return 0;
+		return false;
 
-	return (((ct->mark) & info->mask) == info->mark) ^ info->invert;
+	return ((ct->mark & info->mask) == info->mark) ^ info->invert;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *ip,
 	   const struct xt_match *match,
 	   void *matchinfo,
 	   unsigned int hook_mask)
 {
-	struct xt_connmark_info *cm = matchinfo;
+	const struct xt_connmark_info *cm = matchinfo;
 
 	if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) {
 		printk(KERN_WARNING "connmark: only support 32bit mark\n");
-		return 0;
+		return false;
 	}
 	if (nf_ct_l3proto_try_module_get(match->family) < 0) {
 		printk(KERN_WARNING "can't load conntrack support for "
 				    "proto=%d\n", match->family);
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
 static void
@@ -88,7 +88,7 @@
 
 static void compat_from_user(void *dst, void *src)
 {
-	struct compat_xt_connmark_info *cm = src;
+	const struct compat_xt_connmark_info *cm = src;
 	struct xt_connmark_info m = {
 		.mark	= cm->mark,
 		.mask	= cm->mask,
@@ -99,7 +99,7 @@
 
 static int compat_to_user(void __user *dst, void *src)
 {
-	struct xt_connmark_info *m = src;
+	const struct xt_connmark_info *m = src;
 	struct compat_xt_connmark_info cm = {
 		.mark	= m->mark,
 		.mask	= m->mask,
@@ -109,7 +109,7 @@
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_match xt_connmark_match[] = {
+static struct xt_match xt_connmark_match[] __read_mostly = {
 	{
 		.name		= "connmark",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 189ded5..ca4b69f 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -19,7 +19,7 @@
 MODULE_DESCRIPTION("iptables connection tracking match module");
 MODULE_ALIAS("ipt_conntrack");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -27,14 +27,14 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct xt_conntrack_info *sinfo = matchinfo;
-	struct nf_conn *ct;
+	const struct nf_conn *ct;
 	enum ip_conntrack_info ctinfo;
 	unsigned int statebit;
 
-	ct = nf_ct_get((struct sk_buff *)skb, &ctinfo);
+	ct = nf_ct_get(skb, &ctinfo);
 
 #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
 
@@ -54,53 +54,53 @@
 		}
 		if (FWINV((statebit & sinfo->statemask) == 0,
 			  XT_CONNTRACK_STATE))
-			return 0;
+			return false;
 	}
 
 	if (ct == NULL) {
 		if (sinfo->flags & ~XT_CONNTRACK_STATE)
-			return 0;
-		return 1;
+			return false;
+		return true;
 	}
 
 	if (sinfo->flags & XT_CONNTRACK_PROTO &&
 	    FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum !=
 		  sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum,
 		  XT_CONNTRACK_PROTO))
-		return 0;
+		return false;
 
 	if (sinfo->flags & XT_CONNTRACK_ORIGSRC &&
 	    FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip &
 		   sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
 		  sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip,
 		  XT_CONNTRACK_ORIGSRC))
-		return 0;
+		return false;
 
 	if (sinfo->flags & XT_CONNTRACK_ORIGDST &&
 	    FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip &
 		   sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
 		  sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip,
 		  XT_CONNTRACK_ORIGDST))
-		return 0;
+		return false;
 
 	if (sinfo->flags & XT_CONNTRACK_REPLSRC &&
 	    FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip &
 		   sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) !=
 		  sinfo->tuple[IP_CT_DIR_REPLY].src.ip,
 		  XT_CONNTRACK_REPLSRC))
-		return 0;
+		return false;
 
 	if (sinfo->flags & XT_CONNTRACK_REPLDST &&
 	    FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip &
 		   sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) !=
 		  sinfo->tuple[IP_CT_DIR_REPLY].dst.ip,
 		  XT_CONNTRACK_REPLDST))
-		return 0;
+		return false;
 
 	if (sinfo->flags & XT_CONNTRACK_STATUS &&
 	    FWINV((ct->status & sinfo->statusmask) == 0,
 		  XT_CONNTRACK_STATUS))
-		return 0;
+		return false;
 
 	if(sinfo->flags & XT_CONNTRACK_EXPIRES) {
 		unsigned long expires = timer_pending(&ct->timeout) ?
@@ -109,12 +109,12 @@
 		if (FWINV(!(expires >= sinfo->expires_min &&
 			    expires <= sinfo->expires_max),
 			  XT_CONNTRACK_EXPIRES))
-			return 0;
+			return false;
 	}
-	return 1;
+	return true;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *ip,
 	   const struct xt_match *match,
@@ -124,9 +124,9 @@
 	if (nf_ct_l3proto_try_module_get(match->family) < 0) {
 		printk(KERN_WARNING "can't load conntrack support for "
 				    "proto=%d\n", match->family);
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
 static void destroy(const struct xt_match *match, void *matchinfo)
@@ -150,7 +150,7 @@
 
 static void compat_from_user(void *dst, void *src)
 {
-	struct compat_xt_conntrack_info *cm = src;
+	const struct compat_xt_conntrack_info *cm = src;
 	struct xt_conntrack_info m = {
 		.statemask	= cm->statemask,
 		.statusmask	= cm->statusmask,
@@ -167,7 +167,7 @@
 
 static int compat_to_user(void __user *dst, void *src)
 {
-	struct xt_conntrack_info *m = src;
+	const struct xt_conntrack_info *m = src;
 	struct compat_xt_conntrack_info cm = {
 		.statemask	= m->statemask,
 		.statusmask	= m->statusmask,
@@ -183,7 +183,7 @@
 }
 #endif
 
-static struct xt_match conntrack_match = {
+static struct xt_match conntrack_match __read_mostly = {
 	.name		= "conntrack",
 	.match		= match,
 	.checkentry	= checkentry,
diff --git a/net/netfilter/xt_dccp.c b/net/netfilter/xt_dccp.c
index 2c9c0de..83224ec 100644
--- a/net/netfilter/xt_dccp.c
+++ b/net/netfilter/xt_dccp.c
@@ -31,40 +31,40 @@
 static unsigned char *dccp_optbuf;
 static DEFINE_SPINLOCK(dccp_buflock);
 
-static inline int
+static inline bool
 dccp_find_option(u_int8_t option,
 		 const struct sk_buff *skb,
 		 unsigned int protoff,
 		 const struct dccp_hdr *dh,
-		 int *hotdrop)
+		 bool *hotdrop)
 {
 	/* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
-	unsigned char *op;
+	const unsigned char *op;
 	unsigned int optoff = __dccp_hdr_len(dh);
 	unsigned int optlen = dh->dccph_doff*4 - __dccp_hdr_len(dh);
 	unsigned int i;
 
 	if (dh->dccph_doff * 4 < __dccp_hdr_len(dh)) {
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	if (!optlen)
-		return 0;
+		return false;
 
 	spin_lock_bh(&dccp_buflock);
 	op = skb_header_pointer(skb, protoff + optoff, optlen, dccp_optbuf);
 	if (op == NULL) {
 		/* If we don't have the whole header, drop packet. */
 		spin_unlock_bh(&dccp_buflock);
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	for (i = 0; i < optlen; ) {
 		if (op[i] == option) {
 			spin_unlock_bh(&dccp_buflock);
-			return 1;
+			return true;
 		}
 
 		if (op[i] < 2)
@@ -74,24 +74,24 @@
 	}
 
 	spin_unlock_bh(&dccp_buflock);
-	return 0;
+	return false;
 }
 
 
-static inline int
+static inline bool
 match_types(const struct dccp_hdr *dh, u_int16_t typemask)
 {
-	return (typemask & (1 << dh->dccph_type));
+	return typemask & (1 << dh->dccph_type);
 }
 
-static inline int
+static inline bool
 match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff,
-	     const struct dccp_hdr *dh, int *hotdrop)
+	     const struct dccp_hdr *dh, bool *hotdrop)
 {
 	return dccp_find_option(option, skb, protoff, dh, hotdrop);
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -99,25 +99,25 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct xt_dccp_info *info = matchinfo;
 	struct dccp_hdr _dh, *dh;
 
 	if (offset)
-		return 0;
+		return false;
 
 	dh = skb_header_pointer(skb, protoff, sizeof(_dh), &_dh);
 	if (dh == NULL) {
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
-	return  DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0])
-			&& (ntohs(dh->dccph_sport) <= info->spts[1])),
+	return  DCCHECK(ntohs(dh->dccph_sport) >= info->spts[0]
+			&& ntohs(dh->dccph_sport) <= info->spts[1],
 			XT_DCCP_SRC_PORTS, info->flags, info->invflags)
-		&& DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0])
-			&& (ntohs(dh->dccph_dport) <= info->dpts[1])),
+		&& DCCHECK(ntohs(dh->dccph_dport) >= info->dpts[0]
+			&& ntohs(dh->dccph_dport) <= info->dpts[1],
 			XT_DCCP_DEST_PORTS, info->flags, info->invflags)
 		&& DCCHECK(match_types(dh, info->typemask),
 			   XT_DCCP_TYPE, info->flags, info->invflags)
@@ -126,7 +126,7 @@
 			   XT_DCCP_OPTION, info->flags, info->invflags);
 }
 
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *inf,
 	   const struct xt_match *match,
@@ -140,7 +140,7 @@
 		&& !(info->invflags & ~info->flags);
 }
 
-static struct xt_match xt_dccp_match[] = {
+static struct xt_match xt_dccp_match[] __read_mostly = {
 	{
 		.name 		= "dccp",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c
index 56b247e..dde6d66 100644
--- a/net/netfilter/xt_dscp.c
+++ b/net/netfilter/xt_dscp.c
@@ -22,14 +22,14 @@
 MODULE_ALIAS("ipt_dscp");
 MODULE_ALIAS("ip6t_dscp");
 
-static int match(const struct sk_buff *skb,
-		 const struct net_device *in,
-		 const struct net_device *out,
-		 const struct xt_match *match,
-		 const void *matchinfo,
-		 int offset,
-		 unsigned int protoff,
-		 int *hotdrop)
+static bool match(const struct sk_buff *skb,
+		  const struct net_device *in,
+		  const struct net_device *out,
+		  const struct xt_match *match,
+		  const void *matchinfo,
+		  int offset,
+		  unsigned int protoff,
+		  bool *hotdrop)
 {
 	const struct xt_dscp_info *info = matchinfo;
 	u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT;
@@ -37,14 +37,14 @@
 	return (dscp == info->dscp) ^ !!info->invert;
 }
 
-static int match6(const struct sk_buff *skb,
-		  const struct net_device *in,
-		  const struct net_device *out,
-		  const struct xt_match *match,
-		  const void *matchinfo,
-		  int offset,
-		  unsigned int protoff,
-		  int *hotdrop)
+static bool match6(const struct sk_buff *skb,
+		   const struct net_device *in,
+		   const struct net_device *out,
+		   const struct xt_match *match,
+		   const void *matchinfo,
+		   int offset,
+		   unsigned int protoff,
+		   bool *hotdrop)
 {
 	const struct xt_dscp_info *info = matchinfo;
 	u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
@@ -52,23 +52,23 @@
 	return (dscp == info->dscp) ^ !!info->invert;
 }
 
-static int checkentry(const char *tablename,
-		      const void *info,
-		      const struct xt_match *match,
-		      void *matchinfo,
-		      unsigned int hook_mask)
+static bool checkentry(const char *tablename,
+		       const void *info,
+		       const struct xt_match *match,
+		       void *matchinfo,
+		       unsigned int hook_mask)
 {
 	const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp;
 
 	if (dscp > XT_DSCP_MAX) {
 		printk(KERN_ERR "xt_dscp: dscp %x out of range\n", dscp);
-		return 0;
+		return false;
 	}
 
-	return 1;
+	return true;
 }
 
-static struct xt_match xt_dscp_match[] = {
+static struct xt_match xt_dscp_match[] __read_mostly = {
 	{
 		.name		= "dscp",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_esp.c b/net/netfilter/xt_esp.c
index 7c95f14..b11378e 100644
--- a/net/netfilter/xt_esp.c
+++ b/net/netfilter/xt_esp.c
@@ -31,10 +31,10 @@
 #endif
 
 /* Returns 1 if the spi is matched by the range, 0 otherwise */
-static inline int
-spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
+static inline bool
+spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 {
-	int r = 0;
+	bool r;
 	duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
 		 min, spi, max);
 	r = (spi >= min && spi <= max) ^ invert;
@@ -42,7 +42,7 @@
 	return r;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -50,14 +50,14 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	struct ip_esp_hdr _esp, *eh;
 	const struct xt_esp *espinfo = matchinfo;
 
 	/* Must not be a fragment. */
 	if (offset)
-		return 0;
+		return false;
 
 	eh = skb_header_pointer(skb, protoff, sizeof(_esp), &_esp);
 	if (eh == NULL) {
@@ -65,8 +65,8 @@
 		 * can't.  Hence, no choice but to drop.
 		 */
 		duprintf("Dropping evil ESP tinygram.\n");
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	return spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi),
@@ -74,7 +74,7 @@
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *ip_void,
 	   const struct xt_match *match,
@@ -85,13 +85,13 @@
 
 	if (espinfo->invflags & ~XT_ESP_INV_MASK) {
 		duprintf("xt_esp: unknown flags %X\n", espinfo->invflags);
-		return 0;
+		return false;
 	}
 
-	return 1;
+	return true;
 }
 
-static struct xt_match xt_esp_match[] = {
+static struct xt_match xt_esp_match[] __read_mostly = {
 	{
 		.name		= "esp",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index d3043fa..d6b3d01 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -94,7 +94,8 @@
 static HLIST_HEAD(hashlimit_htables);
 static struct kmem_cache *hashlimit_cachep __read_mostly;
 
-static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
+static inline bool dst_cmp(const struct dsthash_ent *ent,
+			   const struct dsthash_dst *b)
 {
 	return !memcmp(&ent->dst, b, sizeof(ent->dst));
 }
@@ -106,7 +107,8 @@
 }
 
 static struct dsthash_ent *
-dsthash_find(const struct xt_hashlimit_htable *ht, struct dsthash_dst *dst)
+dsthash_find(const struct xt_hashlimit_htable *ht,
+	     const struct dsthash_dst *dst)
 {
 	struct dsthash_ent *ent;
 	struct hlist_node *pos;
@@ -122,7 +124,8 @@
 
 /* allocate dsthash_ent, initialize dst, put in htable and lock it */
 static struct dsthash_ent *
-dsthash_alloc_init(struct xt_hashlimit_htable *ht, struct dsthash_dst *dst)
+dsthash_alloc_init(struct xt_hashlimit_htable *ht,
+		   const struct dsthash_dst *dst)
 {
 	struct dsthash_ent *ent;
 
@@ -227,19 +230,21 @@
 	return 0;
 }
 
-static int select_all(struct xt_hashlimit_htable *ht, struct dsthash_ent *he)
+static bool select_all(const struct xt_hashlimit_htable *ht,
+		       const struct dsthash_ent *he)
 {
 	return 1;
 }
 
-static int select_gc(struct xt_hashlimit_htable *ht, struct dsthash_ent *he)
+static bool select_gc(const struct xt_hashlimit_htable *ht,
+		      const struct dsthash_ent *he)
 {
-	return (jiffies >= he->expires);
+	return jiffies >= he->expires;
 }
 
 static void htable_selective_cleanup(struct xt_hashlimit_htable *ht,
-				int (*select)(struct xt_hashlimit_htable *ht,
-					      struct dsthash_ent *he))
+			bool (*select)(const struct xt_hashlimit_htable *ht,
+				      const struct dsthash_ent *he))
 {
 	unsigned int i;
 
@@ -282,7 +287,8 @@
 	vfree(hinfo);
 }
 
-static struct xt_hashlimit_htable *htable_find_get(char *name, int family)
+static struct xt_hashlimit_htable *htable_find_get(const char *name,
+						   int family)
 {
 	struct xt_hashlimit_htable *hinfo;
 	struct hlist_node *pos;
@@ -367,7 +373,8 @@
 }
 
 static int
-hashlimit_init_dst(struct xt_hashlimit_htable *hinfo, struct dsthash_dst *dst,
+hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
+		   struct dsthash_dst *dst,
 		   const struct sk_buff *skb, unsigned int protoff)
 {
 	__be16 _ports[2], *ports;
@@ -432,7 +439,7 @@
 	return 0;
 }
 
-static int
+static bool
 hashlimit_match(const struct sk_buff *skb,
 		const struct net_device *in,
 		const struct net_device *out,
@@ -440,10 +447,10 @@
 		const void *matchinfo,
 		int offset,
 		unsigned int protoff,
-		int *hotdrop)
+		bool *hotdrop)
 {
-	struct xt_hashlimit_info *r =
-		((struct xt_hashlimit_info *)matchinfo)->u.master;
+	const struct xt_hashlimit_info *r =
+		((const struct xt_hashlimit_info *)matchinfo)->u.master;
 	struct xt_hashlimit_htable *hinfo = r->hinfo;
 	unsigned long now = jiffies;
 	struct dsthash_ent *dh;
@@ -478,20 +485,20 @@
 		/* We're underlimit. */
 		dh->rateinfo.credit -= dh->rateinfo.cost;
 		spin_unlock_bh(&hinfo->lock);
-		return 1;
+		return true;
 	}
 
 	spin_unlock_bh(&hinfo->lock);
 
 	/* default case: we're overlimit, thus don't match */
-	return 0;
+	return false;
 
 hotdrop:
-	*hotdrop = 1;
-	return 0;
+	*hotdrop = true;
+	return false;
 }
 
-static int
+static bool
 hashlimit_checkentry(const char *tablename,
 		     const void *inf,
 		     const struct xt_match *match,
@@ -505,20 +512,20 @@
 	    user2credits(r->cfg.avg * r->cfg.burst) < user2credits(r->cfg.avg)) {
 		printk(KERN_ERR "xt_hashlimit: overflow, try lower: %u/%u\n",
 		       r->cfg.avg, r->cfg.burst);
-		return 0;
+		return false;
 	}
 	if (r->cfg.mode == 0 ||
 	    r->cfg.mode > (XT_HASHLIMIT_HASH_DPT |
 			   XT_HASHLIMIT_HASH_DIP |
 			   XT_HASHLIMIT_HASH_SIP |
 			   XT_HASHLIMIT_HASH_SPT))
-		return 0;
+		return false;
 	if (!r->cfg.gc_interval)
-		return 0;
+		return false;
 	if (!r->cfg.expire)
-		return 0;
+		return false;
 	if (r->name[sizeof(r->name) - 1] != '\0')
-		return 0;
+		return false;
 
 	/* This is the best we've got: We cannot release and re-grab lock,
 	 * since checkentry() is called before x_tables.c grabs xt_mutex.
@@ -530,19 +537,19 @@
 	r->hinfo = htable_find_get(r->name, match->family);
 	if (!r->hinfo && htable_create(r, match->family) != 0) {
 		mutex_unlock(&hlimit_mutex);
-		return 0;
+		return false;
 	}
 	mutex_unlock(&hlimit_mutex);
 
 	/* Ugly hack: For SMP, we only want to use one set */
 	r->u.master = r;
-	return 1;
+	return true;
 }
 
 static void
 hashlimit_destroy(const struct xt_match *match, void *matchinfo)
 {
-	struct xt_hashlimit_info *r = matchinfo;
+	const struct xt_hashlimit_info *r = matchinfo;
 
 	htable_put(r->hinfo);
 }
@@ -571,7 +578,7 @@
 }
 #endif
 
-static struct xt_match xt_hashlimit[] = {
+static struct xt_match xt_hashlimit[] __read_mostly = {
 	{
 		.name		= "hashlimit",
 		.family		= AF_INET,
@@ -694,7 +701,7 @@
 	return 0;
 }
 
-static struct seq_operations dl_seq_ops = {
+static const struct seq_operations dl_seq_ops = {
 	.start = dl_seq_start,
 	.next  = dl_seq_next,
 	.stop  = dl_seq_stop,
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index c139b2f..0a1f4c6 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -22,13 +22,8 @@
 MODULE_ALIAS("ipt_helper");
 MODULE_ALIAS("ip6t_helper");
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -36,61 +31,51 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct xt_helper_info *info = matchinfo;
-	struct nf_conn *ct;
-	struct nf_conn_help *master_help;
+	const struct nf_conn *ct;
+	const struct nf_conn_help *master_help;
+	const struct nf_conntrack_helper *helper;
 	enum ip_conntrack_info ctinfo;
-	int ret = info->invert;
+	bool ret = info->invert;
 
-	ct = nf_ct_get((struct sk_buff *)skb, &ctinfo);
-	if (!ct) {
-		DEBUGP("xt_helper: Eek! invalid conntrack?\n");
+	ct = nf_ct_get(skb, &ctinfo);
+	if (!ct || !ct->master)
 		return ret;
-	}
 
-	if (!ct->master) {
-		DEBUGP("xt_helper: conntrack %p has no master\n", ct);
-		return ret;
-	}
-
-	read_lock_bh(&nf_conntrack_lock);
 	master_help = nfct_help(ct->master);
-	if (!master_help || !master_help->helper) {
-		DEBUGP("xt_helper: master ct %p has no helper\n",
-			exp->expectant);
-		goto out_unlock;
-	}
+	if (!master_help)
+		return ret;
 
-	DEBUGP("master's name = %s , info->name = %s\n",
-		ct->master->helper->name, info->name);
+	/* rcu_read_lock()ed by nf_hook_slow */
+	helper = rcu_dereference(master_help->helper);
+	if (!helper)
+		return ret;
 
 	if (info->name[0] == '\0')
-		ret ^= 1;
+		ret = !ret;
 	else
 		ret ^= !strncmp(master_help->helper->name, info->name,
 				strlen(master_help->helper->name));
-out_unlock:
-	read_unlock_bh(&nf_conntrack_lock);
 	return ret;
 }
 
-static int check(const char *tablename,
-		 const void *inf,
-		 const struct xt_match *match,
-		 void *matchinfo,
-		 unsigned int hook_mask)
+static bool check(const char *tablename,
+		  const void *inf,
+		  const struct xt_match *match,
+		  void *matchinfo,
+		  unsigned int hook_mask)
 {
 	struct xt_helper_info *info = matchinfo;
 
 	if (nf_ct_l3proto_try_module_get(match->family) < 0) {
 		printk(KERN_WARNING "can't load conntrack support for "
 				    "proto=%d\n", match->family);
-		return 0;
+		return false;
 	}
 	info->name[29] = '\0';
-	return 1;
+	return true;
 }
 
 static void
@@ -99,7 +84,7 @@
 	nf_ct_l3proto_module_put(match->family);
 }
 
-static struct xt_match xt_helper_match[] = {
+static struct xt_match xt_helper_match[] __read_mostly = {
 	{
 		.name		= "helper",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_length.c b/net/netfilter/xt_length.c
index 77288c5..3dad173 100644
--- a/net/netfilter/xt_length.c
+++ b/net/netfilter/xt_length.c
@@ -20,7 +20,7 @@
 MODULE_ALIAS("ipt_length");
 MODULE_ALIAS("ip6t_length");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -28,7 +28,7 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct xt_length_info *info = matchinfo;
 	u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len);
@@ -36,7 +36,7 @@
 	return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
 }
 
-static int
+static bool
 match6(const struct sk_buff *skb,
        const struct net_device *in,
        const struct net_device *out,
@@ -44,16 +44,16 @@
        const void *matchinfo,
        int offset,
        unsigned int protoff,
-       int *hotdrop)
+       bool *hotdrop)
 {
 	const struct xt_length_info *info = matchinfo;
-	const u_int16_t pktlen = (ntohs(ipv6_hdr(skb)->payload_len) +
-				  sizeof(struct ipv6hdr));
+	const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) +
+				 sizeof(struct ipv6hdr);
 
 	return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
 }
 
-static struct xt_match xt_length_match[] = {
+static struct xt_match xt_length_match[] __read_mostly = {
 	{
 		.name		= "length",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c
index 571a72a..4fcca79 100644
--- a/net/netfilter/xt_limit.c
+++ b/net/netfilter/xt_limit.c
@@ -57,7 +57,7 @@
 
 #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
 
-static int
+static bool
 ipt_limit_match(const struct sk_buff *skb,
 		const struct net_device *in,
 		const struct net_device *out,
@@ -65,9 +65,10 @@
 		const void *matchinfo,
 		int offset,
 		unsigned int protoff,
-		int *hotdrop)
+		bool *hotdrop)
 {
-	struct xt_rateinfo *r = ((struct xt_rateinfo *)matchinfo)->master;
+	struct xt_rateinfo *r =
+		((const struct xt_rateinfo *)matchinfo)->master;
 	unsigned long now = jiffies;
 
 	spin_lock_bh(&limit_lock);
@@ -79,11 +80,11 @@
 		/* We're not limited. */
 		r->credit -= r->cost;
 		spin_unlock_bh(&limit_lock);
-		return 1;
+		return true;
 	}
 
 	spin_unlock_bh(&limit_lock);
-	return 0;
+	return false;
 }
 
 /* Precision saver. */
@@ -98,7 +99,7 @@
 	return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE;
 }
 
-static int
+static bool
 ipt_limit_checkentry(const char *tablename,
 		     const void *inf,
 		     const struct xt_match *match,
@@ -112,7 +113,7 @@
 	    || user2credits(r->avg * r->burst) < user2credits(r->avg)) {
 		printk("Overflow in xt_limit, try lower: %u/%u\n",
 		       r->avg, r->burst);
-		return 0;
+		return false;
 	}
 
 	/* For SMP, we only want to use one set of counters. */
@@ -125,7 +126,7 @@
 		r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */
 		r->cost = user2credits(r->avg);
 	}
-	return 1;
+	return true;
 }
 
 #ifdef CONFIG_COMPAT
@@ -144,7 +145,7 @@
  * master pointer, which does not need to be preserved. */
 static void compat_from_user(void *dst, void *src)
 {
-	struct compat_xt_rateinfo *cm = src;
+	const struct compat_xt_rateinfo *cm = src;
 	struct xt_rateinfo m = {
 		.avg		= cm->avg,
 		.burst		= cm->burst,
@@ -158,7 +159,7 @@
 
 static int compat_to_user(void __user *dst, void *src)
 {
-	struct xt_rateinfo *m = src;
+	const struct xt_rateinfo *m = src;
 	struct compat_xt_rateinfo cm = {
 		.avg		= m->avg,
 		.burst		= m->burst,
@@ -172,7 +173,7 @@
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_match xt_limit_match[] = {
+static struct xt_match xt_limit_match[] __read_mostly = {
 	{
 		.name		= "limit",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
index 1d3a1d9..00490d7 100644
--- a/net/netfilter/xt_mac.c
+++ b/net/netfilter/xt_mac.c
@@ -24,7 +24,7 @@
 MODULE_ALIAS("ipt_mac");
 MODULE_ALIAS("ip6t_mac");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -32,19 +32,19 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
     const struct xt_mac_info *info = matchinfo;
 
     /* Is mac pointer valid? */
-    return (skb_mac_header(skb) >= skb->head &&
-	    (skb_mac_header(skb) + ETH_HLEN) <= skb->data
-	    /* If so, compare... */
-	    && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr))
-		^ info->invert));
+    return skb_mac_header(skb) >= skb->head &&
+	   skb_mac_header(skb) + ETH_HLEN <= skb->data
+	   /* If so, compare... */
+	   && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr))
+		^ info->invert);
 }
 
-static struct xt_match xt_mac_match[] = {
+static struct xt_match xt_mac_match[] __read_mostly = {
 	{
 		.name		= "mac",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c
index 39911dd..c02a7f8 100644
--- a/net/netfilter/xt_mark.c
+++ b/net/netfilter/xt_mark.c
@@ -19,7 +19,7 @@
 MODULE_ALIAS("ipt_mark");
 MODULE_ALIAS("ip6t_mark");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -27,14 +27,14 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct xt_mark_info *info = matchinfo;
 
 	return ((skb->mark & info->mask) == info->mark) ^ info->invert;
 }
 
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *entry,
 	   const struct xt_match *match,
@@ -45,9 +45,9 @@
 
 	if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) {
 		printk(KERN_WARNING "mark: only supports 32bit mark\n");
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
 #ifdef CONFIG_COMPAT
@@ -60,7 +60,7 @@
 
 static void compat_from_user(void *dst, void *src)
 {
-	struct compat_xt_mark_info *cm = src;
+	const struct compat_xt_mark_info *cm = src;
 	struct xt_mark_info m = {
 		.mark	= cm->mark,
 		.mask	= cm->mask,
@@ -71,7 +71,7 @@
 
 static int compat_to_user(void __user *dst, void *src)
 {
-	struct xt_mark_info *m = src;
+	const struct xt_mark_info *m = src;
 	struct compat_xt_mark_info cm = {
 		.mark	= m->mark,
 		.mask	= m->mask,
@@ -81,7 +81,7 @@
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_match xt_mark_match[] = {
+static struct xt_match xt_mark_match[] __read_mostly = {
 	{
 		.name		= "mark",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c
index 4dce2a8..e8ae102 100644
--- a/net/netfilter/xt_multiport.c
+++ b/net/netfilter/xt_multiport.c
@@ -33,24 +33,24 @@
 #endif
 
 /* Returns 1 if the port is matched by the test, 0 otherwise. */
-static inline int
+static inline bool
 ports_match(const u_int16_t *portlist, enum xt_multiport_flags flags,
 	    u_int8_t count, u_int16_t src, u_int16_t dst)
 {
 	unsigned int i;
 	for (i = 0; i < count; i++) {
 		if (flags != XT_MULTIPORT_DESTINATION && portlist[i] == src)
-			return 1;
+			return true;
 
 		if (flags != XT_MULTIPORT_SOURCE && portlist[i] == dst)
-			return 1;
+			return true;
 	}
 
-	return 0;
+	return false;
 }
 
 /* Returns 1 if the port is matched by the test, 0 otherwise. */
-static inline int
+static inline bool
 ports_match_v1(const struct xt_multiport_v1 *minfo,
 	       u_int16_t src, u_int16_t dst)
 {
@@ -67,34 +67,34 @@
 
 			if (minfo->flags == XT_MULTIPORT_SOURCE
 			    && src >= s && src <= e)
-				return 1 ^ minfo->invert;
+				return true ^ minfo->invert;
 			if (minfo->flags == XT_MULTIPORT_DESTINATION
 			    && dst >= s && dst <= e)
-				return 1 ^ minfo->invert;
+				return true ^ minfo->invert;
 			if (minfo->flags == XT_MULTIPORT_EITHER
 			    && ((dst >= s && dst <= e)
 				|| (src >= s && src <= e)))
-				return 1 ^ minfo->invert;
+				return true ^ minfo->invert;
 		} else {
 			/* exact port matching */
 			duprintf("src or dst matches with %d?\n", s);
 
 			if (minfo->flags == XT_MULTIPORT_SOURCE
 			    && src == s)
-				return 1 ^ minfo->invert;
+				return true ^ minfo->invert;
 			if (minfo->flags == XT_MULTIPORT_DESTINATION
 			    && dst == s)
-				return 1 ^ minfo->invert;
+				return true ^ minfo->invert;
 			if (minfo->flags == XT_MULTIPORT_EITHER
 			    && (src == s || dst == s))
-				return 1 ^ minfo->invert;
+				return true ^ minfo->invert;
 		}
 	}
 
 	return minfo->invert;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -102,13 +102,13 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	__be16 _ports[2], *pptr;
 	const struct xt_multiport *multiinfo = matchinfo;
 
 	if (offset)
-		return 0;
+		return false;
 
 	pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports);
 	if (pptr == NULL) {
@@ -116,8 +116,8 @@
 		 * can't.  Hence, no choice but to drop.
 		 */
 		duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	return ports_match(multiinfo->ports,
@@ -125,7 +125,7 @@
 			   ntohs(pptr[0]), ntohs(pptr[1]));
 }
 
-static int
+static bool
 match_v1(const struct sk_buff *skb,
 	 const struct net_device *in,
 	 const struct net_device *out,
@@ -133,13 +133,13 @@
 	 const void *matchinfo,
 	 int offset,
 	 unsigned int protoff,
-	 int *hotdrop)
+	 bool *hotdrop)
 {
 	__be16 _ports[2], *pptr;
 	const struct xt_multiport_v1 *multiinfo = matchinfo;
 
 	if (offset)
-		return 0;
+		return false;
 
 	pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports);
 	if (pptr == NULL) {
@@ -147,14 +147,14 @@
 		 * can't.  Hence, no choice but to drop.
 		 */
 		duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1]));
 }
 
-static inline int
+static inline bool
 check(u_int16_t proto,
       u_int8_t ip_invflags,
       u_int8_t match_flags,
@@ -172,7 +172,7 @@
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *info,
 	   const struct xt_match *match,
@@ -186,7 +186,7 @@
 		     multiinfo->count);
 }
 
-static int
+static bool
 checkentry_v1(const char *tablename,
 	      const void *info,
 	      const struct xt_match *match,
@@ -200,7 +200,7 @@
 		     multiinfo->count);
 }
 
-static int
+static bool
 checkentry6(const char *tablename,
 	    const void *info,
 	    const struct xt_match *match,
@@ -214,7 +214,7 @@
 		     multiinfo->count);
 }
 
-static int
+static bool
 checkentry6_v1(const char *tablename,
 	       const void *info,
 	       const struct xt_match *match,
@@ -228,7 +228,7 @@
 		     multiinfo->count);
 }
 
-static struct xt_match xt_multiport_match[] = {
+static struct xt_match xt_multiport_match[] __read_mostly = {
 	{
 		.name		= "multiport",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index 35a0fe2..f47cab7a6 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -14,8 +14,6 @@
 #include <linux/netfilter/xt_physdev.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_bridge.h>
-#define MATCH   1
-#define NOMATCH 0
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
@@ -23,7 +21,7 @@
 MODULE_ALIAS("ipt_physdev");
 MODULE_ALIAS("ip6t_physdev");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -31,14 +29,14 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	int i;
 	static const char nulldevname[IFNAMSIZ];
 	const struct xt_physdev_info *info = matchinfo;
-	unsigned int ret;
+	bool ret;
 	const char *indev, *outdev;
-	struct nf_bridge_info *nf_bridge;
+	const struct nf_bridge_info *nf_bridge;
 
 	/* Not a bridged IP packet or no info available yet:
 	 * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if
@@ -47,61 +45,61 @@
 		/* Return MATCH if the invert flags of the used options are on */
 		if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) &&
 		    !(info->invert & XT_PHYSDEV_OP_BRIDGED))
-			return NOMATCH;
+			return false;
 		if ((info->bitmask & XT_PHYSDEV_OP_ISIN) &&
 		    !(info->invert & XT_PHYSDEV_OP_ISIN))
-			return NOMATCH;
+			return false;
 		if ((info->bitmask & XT_PHYSDEV_OP_ISOUT) &&
 		    !(info->invert & XT_PHYSDEV_OP_ISOUT))
-			return NOMATCH;
+			return false;
 		if ((info->bitmask & XT_PHYSDEV_OP_IN) &&
 		    !(info->invert & XT_PHYSDEV_OP_IN))
-			return NOMATCH;
+			return false;
 		if ((info->bitmask & XT_PHYSDEV_OP_OUT) &&
 		    !(info->invert & XT_PHYSDEV_OP_OUT))
-			return NOMATCH;
-		return MATCH;
+			return false;
+		return true;
 	}
 
 	/* This only makes sense in the FORWARD and POSTROUTING chains */
 	if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) &&
 	    (!!(nf_bridge->mask & BRNF_BRIDGED) ^
 	    !(info->invert & XT_PHYSDEV_OP_BRIDGED)))
-		return NOMATCH;
+		return false;
 
 	if ((info->bitmask & XT_PHYSDEV_OP_ISIN &&
 	    (!nf_bridge->physindev ^ !!(info->invert & XT_PHYSDEV_OP_ISIN))) ||
 	    (info->bitmask & XT_PHYSDEV_OP_ISOUT &&
 	    (!nf_bridge->physoutdev ^ !!(info->invert & XT_PHYSDEV_OP_ISOUT))))
-		return NOMATCH;
+		return false;
 
 	if (!(info->bitmask & XT_PHYSDEV_OP_IN))
 		goto match_outdev;
 	indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
-	for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
+	for (i = 0, ret = false; i < IFNAMSIZ/sizeof(unsigned int); i++) {
 		ret |= (((const unsigned int *)indev)[i]
 			^ ((const unsigned int *)info->physindev)[i])
 			& ((const unsigned int *)info->in_mask)[i];
 	}
 
-	if ((ret == 0) ^ !(info->invert & XT_PHYSDEV_OP_IN))
-		return NOMATCH;
+	if (!ret ^ !(info->invert & XT_PHYSDEV_OP_IN))
+		return false;
 
 match_outdev:
 	if (!(info->bitmask & XT_PHYSDEV_OP_OUT))
-		return MATCH;
+		return true;
 	outdev = nf_bridge->physoutdev ?
 		 nf_bridge->physoutdev->name : nulldevname;
-	for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
+	for (i = 0, ret = false; i < IFNAMSIZ/sizeof(unsigned int); i++) {
 		ret |= (((const unsigned int *)outdev)[i]
 			^ ((const unsigned int *)info->physoutdev)[i])
 			& ((const unsigned int *)info->out_mask)[i];
 	}
 
-	return (ret != 0) ^ !(info->invert & XT_PHYSDEV_OP_OUT);
+	return ret ^ !(info->invert & XT_PHYSDEV_OP_OUT);
 }
 
-static int
+static bool
 checkentry(const char *tablename,
 		       const void *ip,
 		       const struct xt_match *match,
@@ -112,7 +110,7 @@
 
 	if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
 	    info->bitmask & ~XT_PHYSDEV_OP_MASK)
-		return 0;
+		return false;
 	if (info->bitmask & XT_PHYSDEV_OP_OUT &&
 	    (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
 	     info->invert & XT_PHYSDEV_OP_BRIDGED) &&
@@ -122,12 +120,12 @@
 		       "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
 		       "traffic is not supported anymore.\n");
 		if (hook_mask & (1 << NF_IP_LOCAL_OUT))
-			return 0;
+			return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_match xt_physdev_match[] = {
+static struct xt_match xt_physdev_match[] __read_mostly = {
 	{
 		.name		= "physdev",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_pkttype.c b/net/netfilter/xt_pkttype.c
index e1409fc..a52925f 100644
--- a/net/netfilter/xt_pkttype.c
+++ b/net/netfilter/xt_pkttype.c
@@ -21,29 +21,29 @@
 MODULE_ALIAS("ipt_pkttype");
 MODULE_ALIAS("ip6t_pkttype");
 
-static int match(const struct sk_buff *skb,
+static bool match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       const struct xt_match *match,
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	u_int8_t type;
 	const struct xt_pkttype_info *info = matchinfo;
 
 	if (skb->pkt_type == PACKET_LOOPBACK)
-		type = (MULTICAST(ip_hdr(skb)->daddr)
+		type = MULTICAST(ip_hdr(skb)->daddr)
 			? PACKET_MULTICAST
-			: PACKET_BROADCAST);
+			: PACKET_BROADCAST;
 	else
 		type = skb->pkt_type;
 
 	return (type == info->pkttype) ^ info->invert;
 }
 
-static struct xt_match xt_pkttype_match[] = {
+static struct xt_match xt_pkttype_match[] __read_mostly = {
 	{
 		.name		= "pkttype",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c
index 15b45a9..6d6d3b7 100644
--- a/net/netfilter/xt_policy.c
+++ b/net/netfilter/xt_policy.c
@@ -20,7 +20,7 @@
 MODULE_DESCRIPTION("Xtables IPsec policy matching module");
 MODULE_LICENSE("GPL");
 
-static inline int
+static inline bool
 xt_addr_cmp(const union xt_policy_addr *a1, const union xt_policy_addr *m,
 	    const union xt_policy_addr *a2, unsigned short family)
 {
@@ -30,11 +30,11 @@
 	case AF_INET6:
 		return !ipv6_masked_addr_cmp(&a1->a6, &m->a6, &a2->a6);
 	}
-	return 0;
+	return false;
 }
 
-static inline int
-match_xfrm_state(struct xfrm_state *x, const struct xt_policy_elem *e,
+static inline bool
+match_xfrm_state(const struct xfrm_state *x, const struct xt_policy_elem *e,
 		 unsigned short family)
 {
 #define MATCH_ADDR(x,y,z)	(!e->match.x ||			       \
@@ -55,7 +55,7 @@
 		unsigned short family)
 {
 	const struct xt_policy_elem *e;
-	struct sec_path *sp = skb->sp;
+	const struct sec_path *sp = skb->sp;
 	int strict = info->flags & XT_POLICY_MATCH_STRICT;
 	int i, pos;
 
@@ -85,7 +85,7 @@
 		 unsigned short family)
 {
 	const struct xt_policy_elem *e;
-	struct dst_entry *dst = skb->dst;
+	const struct dst_entry *dst = skb->dst;
 	int strict = info->flags & XT_POLICY_MATCH_STRICT;
 	int i, pos;
 
@@ -108,14 +108,14 @@
 	return strict ? i == info->len : 0;
 }
 
-static int match(const struct sk_buff *skb,
-		 const struct net_device *in,
-		 const struct net_device *out,
-		 const struct xt_match *match,
-		 const void *matchinfo,
-		 int offset,
-		 unsigned int protoff,
-		 int *hotdrop)
+static bool match(const struct sk_buff *skb,
+		  const struct net_device *in,
+		  const struct net_device *out,
+		  const struct xt_match *match,
+		  const void *matchinfo,
+		  int offset,
+		  unsigned int protoff,
+		  bool *hotdrop)
 {
 	const struct xt_policy_info *info = matchinfo;
 	int ret;
@@ -126,45 +126,45 @@
 		ret = match_policy_out(skb, info, match->family);
 
 	if (ret < 0)
-		ret = info->flags & XT_POLICY_MATCH_NONE ? 1 : 0;
+		ret = info->flags & XT_POLICY_MATCH_NONE ? true : false;
 	else if (info->flags & XT_POLICY_MATCH_NONE)
-		ret = 0;
+		ret = false;
 
 	return ret;
 }
 
-static int checkentry(const char *tablename, const void *ip_void,
-		      const struct xt_match *match,
-		      void *matchinfo, unsigned int hook_mask)
+static bool checkentry(const char *tablename, const void *ip_void,
+		       const struct xt_match *match,
+		       void *matchinfo, unsigned int hook_mask)
 {
 	struct xt_policy_info *info = matchinfo;
 
 	if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) {
 		printk(KERN_ERR "xt_policy: neither incoming nor "
 				"outgoing policy selected\n");
-		return 0;
+		return false;
 	}
 	/* hook values are equal for IPv4 and IPv6 */
 	if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
 	    && info->flags & XT_POLICY_MATCH_OUT) {
 		printk(KERN_ERR "xt_policy: output policy not valid in "
 				"PRE_ROUTING and INPUT\n");
-		return 0;
+		return false;
 	}
 	if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
 	    && info->flags & XT_POLICY_MATCH_IN) {
 		printk(KERN_ERR "xt_policy: input policy not valid in "
 				"POST_ROUTING and OUTPUT\n");
-		return 0;
+		return false;
 	}
 	if (info->len > XT_POLICY_MAX_ELEM) {
 		printk(KERN_ERR "xt_policy: too many policy elements\n");
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
-static struct xt_match xt_policy_match[] = {
+static struct xt_match xt_policy_match[] __read_mostly = {
 	{
 		.name		= "policy",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_quota.c b/net/netfilter/xt_quota.c
index bfdde06..dae9744 100644
--- a/net/netfilter/xt_quota.c
+++ b/net/netfilter/xt_quota.c
@@ -16,19 +16,20 @@
 
 static DEFINE_SPINLOCK(quota_lock);
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in, const struct net_device *out,
       const struct xt_match *match, const void *matchinfo,
-      int offset, unsigned int protoff, int *hotdrop)
+      int offset, unsigned int protoff, bool *hotdrop)
 {
-	struct xt_quota_info *q = ((struct xt_quota_info *)matchinfo)->master;
-	int ret = q->flags & XT_QUOTA_INVERT ? 1 : 0;
+	struct xt_quota_info *q =
+		((const struct xt_quota_info *)matchinfo)->master;
+	bool ret = q->flags & XT_QUOTA_INVERT;
 
 	spin_lock_bh(&quota_lock);
 	if (q->quota >= skb->len) {
 		q->quota -= skb->len;
-		ret ^= 1;
+		ret = !ret;
 	} else {
 		/* we do not allow even small packets from now on */
 		q->quota = 0;
@@ -38,21 +39,21 @@
 	return ret;
 }
 
-static int
+static bool
 checkentry(const char *tablename, const void *entry,
 	   const struct xt_match *match, void *matchinfo,
 	   unsigned int hook_mask)
 {
-	struct xt_quota_info *q = (struct xt_quota_info *)matchinfo;
+	struct xt_quota_info *q = matchinfo;
 
 	if (q->flags & ~XT_QUOTA_MASK)
-		return 0;
+		return false;
 	/* For SMP, we only want to use one set of counters. */
 	q->master = q;
-	return 1;
+	return true;
 }
 
-static struct xt_match xt_quota_match[] = {
+static struct xt_match xt_quota_match[] __read_mostly = {
 	{
 		.name		= "quota",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_realm.c b/net/netfilter/xt_realm.c
index c2017f8..cc3e76d 100644
--- a/net/netfilter/xt_realm.c
+++ b/net/netfilter/xt_realm.c
@@ -21,7 +21,7 @@
 MODULE_DESCRIPTION("X_tables realm match");
 MODULE_ALIAS("ipt_realm");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -29,15 +29,15 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct xt_realm_info *info = matchinfo;
-	struct dst_entry *dst = skb->dst;
+	const struct dst_entry *dst = skb->dst;
 
 	return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
 }
 
-static struct xt_match realm_match = {
+static struct xt_match realm_match __read_mostly = {
 	.name		= "realm",
 	.match		= match,
 	.matchsize	= sizeof(struct xt_realm_info),
diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c
index f86d8d7..c002153 100644
--- a/net/netfilter/xt_sctp.c
+++ b/net/netfilter/xt_sctp.c
@@ -23,7 +23,7 @@
 #define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
 					      || (!!((invflag) & (option)) ^ (cond)))
 
-static int
+static bool
 match_flags(const struct xt_sctp_flag_info *flag_info,
 	    const int flag_count,
 	    u_int8_t chunktype,
@@ -31,23 +31,21 @@
 {
 	int i;
 
-	for (i = 0; i < flag_count; i++) {
-		if (flag_info[i].chunktype == chunktype) {
+	for (i = 0; i < flag_count; i++)
+		if (flag_info[i].chunktype == chunktype)
 			return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag;
-		}
-	}
 
-	return 1;
+	return true;
 }
 
-static inline int
+static inline bool
 match_packet(const struct sk_buff *skb,
 	     unsigned int offset,
 	     const u_int32_t *chunkmap,
 	     int chunk_match_type,
 	     const struct xt_sctp_flag_info *flag_info,
 	     const int flag_count,
-	     int *hotdrop)
+	     bool *hotdrop)
 {
 	u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
 	sctp_chunkhdr_t _sch, *sch;
@@ -56,16 +54,15 @@
 	int i = 0;
 #endif
 
-	if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) {
+	if (chunk_match_type == SCTP_CHUNK_MATCH_ALL)
 		SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
-	}
 
 	do {
 		sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch);
 		if (sch == NULL || sch->length == 0) {
 			duprintf("Dropping invalid SCTP packet.\n");
-			*hotdrop = 1;
-			return 0;
+			*hotdrop = true;
+			return false;
 		}
 
 		duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
@@ -80,28 +77,26 @@
 			case SCTP_CHUNK_MATCH_ANY:
 				if (match_flags(flag_info, flag_count,
 					sch->type, sch->flags)) {
-					return 1;
+					return true;
 				}
 				break;
 
 			case SCTP_CHUNK_MATCH_ALL:
 				if (match_flags(flag_info, flag_count,
-					sch->type, sch->flags)) {
+				    sch->type, sch->flags))
 					SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch->type);
-				}
 				break;
 
 			case SCTP_CHUNK_MATCH_ONLY:
 				if (!match_flags(flag_info, flag_count,
-					sch->type, sch->flags)) {
-					return 0;
-				}
+				    sch->type, sch->flags))
+					return false;
 				break;
 			}
 		} else {
 			switch (chunk_match_type) {
 			case SCTP_CHUNK_MATCH_ONLY:
-				return 0;
+				return false;
 			}
 		}
 	} while (offset < skb->len);
@@ -110,16 +105,16 @@
 	case SCTP_CHUNK_MATCH_ALL:
 		return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
 	case SCTP_CHUNK_MATCH_ANY:
-		return 0;
+		return false;
 	case SCTP_CHUNK_MATCH_ONLY:
-		return 1;
+		return true;
 	}
 
 	/* This will never be reached, but required to stop compiler whine */
-	return 0;
+	return false;
 }
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -127,29 +122,29 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct xt_sctp_info *info = matchinfo;
 	sctp_sctphdr_t _sh, *sh;
 
 	if (offset) {
 		duprintf("Dropping non-first fragment.. FIXME\n");
-		return 0;
+		return false;
 	}
 
 	sh = skb_header_pointer(skb, protoff, sizeof(_sh), &_sh);
 	if (sh == NULL) {
 		duprintf("Dropping evil TCP offset=0 tinygram.\n");
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 	duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest));
 
-	return  SCCHECK(((ntohs(sh->source) >= info->spts[0])
-			&& (ntohs(sh->source) <= info->spts[1])),
+	return  SCCHECK(ntohs(sh->source) >= info->spts[0]
+			&& ntohs(sh->source) <= info->spts[1],
 			XT_SCTP_SRC_PORTS, info->flags, info->invflags)
-		&& SCCHECK(((ntohs(sh->dest) >= info->dpts[0])
-			&& (ntohs(sh->dest) <= info->dpts[1])),
+		&& SCCHECK(ntohs(sh->dest) >= info->dpts[0]
+			&& ntohs(sh->dest) <= info->dpts[1],
 			XT_SCTP_DEST_PORTS, info->flags, info->invflags)
 		&& SCCHECK(match_packet(skb, protoff + sizeof (sctp_sctphdr_t),
 					info->chunkmap, info->chunk_match_type,
@@ -158,7 +153,7 @@
 			   XT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
 }
 
-static int
+static bool
 checkentry(const char *tablename,
 	   const void *inf,
 	   const struct xt_match *match,
@@ -177,7 +172,7 @@
 				| SCTP_CHUNK_MATCH_ONLY)));
 }
 
-static struct xt_match xt_sctp_match[] = {
+static struct xt_match xt_sctp_match[] __read_mostly = {
 	{
 		.name		= "sctp",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c
index 149294f..e0a528d 100644
--- a/net/netfilter/xt_state.c
+++ b/net/netfilter/xt_state.c
@@ -20,7 +20,7 @@
 MODULE_ALIAS("ipt_state");
 MODULE_ALIAS("ip6t_state");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -28,7 +28,7 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct xt_state_info *sinfo = matchinfo;
 	enum ip_conntrack_info ctinfo;
@@ -44,18 +44,18 @@
 	return (sinfo->statemask & statebit);
 }
 
-static int check(const char *tablename,
-		 const void *inf,
-		 const struct xt_match *match,
-		 void *matchinfo,
-		 unsigned int hook_mask)
+static bool check(const char *tablename,
+		  const void *inf,
+		  const struct xt_match *match,
+		  void *matchinfo,
+		  unsigned int hook_mask)
 {
 	if (nf_ct_l3proto_try_module_get(match->family) < 0) {
 		printk(KERN_WARNING "can't load conntrack support for "
 				    "proto=%d\n", match->family);
-		return 0;
+		return false;
 	}
-	return 1;
+	return true;
 }
 
 static void
@@ -64,7 +64,7 @@
 	nf_ct_l3proto_module_put(match->family);
 }
 
-static struct xt_match xt_state_match[] = {
+static struct xt_match xt_state_match[] __read_mostly = {
 	{
 		.name		= "state",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c
index 091a9f8..4089dae 100644
--- a/net/netfilter/xt_statistic.c
+++ b/net/netfilter/xt_statistic.c
@@ -24,26 +24,26 @@
 
 static DEFINE_SPINLOCK(nth_lock);
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in, const struct net_device *out,
       const struct xt_match *match, const void *matchinfo,
-      int offset, unsigned int protoff, int *hotdrop)
+      int offset, unsigned int protoff, bool *hotdrop)
 {
 	struct xt_statistic_info *info = (struct xt_statistic_info *)matchinfo;
-	int ret = info->flags & XT_STATISTIC_INVERT ? 1 : 0;
+	bool ret = info->flags & XT_STATISTIC_INVERT;
 
 	switch (info->mode) {
 	case XT_STATISTIC_MODE_RANDOM:
 		if ((net_random() & 0x7FFFFFFF) < info->u.random.probability)
-			ret ^= 1;
+			ret = !ret;
 		break;
 	case XT_STATISTIC_MODE_NTH:
 		info = info->master;
 		spin_lock_bh(&nth_lock);
 		if (info->u.nth.count++ == info->u.nth.every) {
 			info->u.nth.count = 0;
-			ret ^= 1;
+			ret = !ret;
 		}
 		spin_unlock_bh(&nth_lock);
 		break;
@@ -52,21 +52,21 @@
 	return ret;
 }
 
-static int
+static bool
 checkentry(const char *tablename, const void *entry,
 	   const struct xt_match *match, void *matchinfo,
 	   unsigned int hook_mask)
 {
-	struct xt_statistic_info *info = (struct xt_statistic_info *)matchinfo;
+	struct xt_statistic_info *info = matchinfo;
 
 	if (info->mode > XT_STATISTIC_MODE_MAX ||
 	    info->flags & ~XT_STATISTIC_MASK)
-		return 0;
+		return false;
 	info->master = info;
-	return 1;
+	return true;
 }
 
-static struct xt_match xt_statistic_match[] = {
+static struct xt_match xt_statistic_match[] __read_mostly = {
 	{
 		.name		= "statistic",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c
index 999a005..8641334 100644
--- a/net/netfilter/xt_string.c
+++ b/net/netfilter/xt_string.c
@@ -21,14 +21,14 @@
 MODULE_ALIAS("ipt_string");
 MODULE_ALIAS("ip6t_string");
 
-static int match(const struct sk_buff *skb,
-		 const struct net_device *in,
-		 const struct net_device *out,
-		 const struct xt_match *match,
-		 const void *matchinfo,
-		 int offset,
-		 unsigned int protoff,
-		 int *hotdrop)
+static bool match(const struct sk_buff *skb,
+		  const struct net_device *in,
+		  const struct net_device *out,
+		  const struct xt_match *match,
+		  const void *matchinfo,
+		  int offset,
+		  unsigned int protoff,
+		  bool *hotdrop)
 {
 	const struct xt_string_info *conf = matchinfo;
 	struct ts_state state;
@@ -42,30 +42,30 @@
 
 #define STRING_TEXT_PRIV(m) ((struct xt_string_info *) m)
 
-static int checkentry(const char *tablename,
-		      const void *ip,
-		      const struct xt_match *match,
-		      void *matchinfo,
-		      unsigned int hook_mask)
+static bool checkentry(const char *tablename,
+		       const void *ip,
+		       const struct xt_match *match,
+		       void *matchinfo,
+		       unsigned int hook_mask)
 {
 	struct xt_string_info *conf = matchinfo;
 	struct ts_config *ts_conf;
 
 	/* Damn, can't handle this case properly with iptables... */
 	if (conf->from_offset > conf->to_offset)
-		return 0;
+		return false;
 	if (conf->algo[XT_STRING_MAX_ALGO_NAME_SIZE - 1] != '\0')
-		return 0;
+		return false;
 	if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE)
-		return 0;
+		return false;
 	ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen,
 				     GFP_KERNEL, TS_AUTOLOAD);
 	if (IS_ERR(ts_conf))
-		return 0;
+		return false;
 
 	conf->config = ts_conf;
 
-	return 1;
+	return true;
 }
 
 static void destroy(const struct xt_match *match, void *matchinfo)
@@ -73,7 +73,7 @@
 	textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config);
 }
 
-static struct xt_match xt_string_match[] = {
+static struct xt_match xt_string_match[] __read_mostly = {
 	{
 		.name 		= "string",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c
index 80571d0..cd5f6d7 100644
--- a/net/netfilter/xt_tcpmss.c
+++ b/net/netfilter/xt_tcpmss.c
@@ -23,7 +23,7 @@
 MODULE_DESCRIPTION("iptables TCP MSS match module");
 MODULE_ALIAS("ipt_tcpmss");
 
-static int
+static bool
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
@@ -31,7 +31,7 @@
       const void *matchinfo,
       int offset,
       unsigned int protoff,
-      int *hotdrop)
+      bool *hotdrop)
 {
 	const struct xt_tcpmss_match_info *info = matchinfo;
 	struct tcphdr _tcph, *th;
@@ -77,11 +77,11 @@
 	return info->invert;
 
 dropit:
-	*hotdrop = 1;
-	return 0;
+	*hotdrop = true;
+	return false;
 }
 
-static struct xt_match xt_tcpmss_match[] = {
+static struct xt_match xt_tcpmss_match[] __read_mostly = {
 	{
 		.name		= "tcpmss",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c
index 46414b5..ab7d845 100644
--- a/net/netfilter/xt_tcpudp.c
+++ b/net/netfilter/xt_tcpudp.c
@@ -27,22 +27,19 @@
 
 
 /* Returns 1 if the port is matched by the range, 0 otherwise */
-static inline int
-port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert)
+static inline bool
+port_match(u_int16_t min, u_int16_t max, u_int16_t port, bool invert)
 {
-	int ret;
-
-	ret = (port >= min && port <= max) ^ invert;
-	return ret;
+	return (port >= min && port <= max) ^ invert;
 }
 
-static int
+static bool
 tcp_find_option(u_int8_t option,
 		const struct sk_buff *skb,
 		unsigned int protoff,
 		unsigned int optlen,
-		int invert,
-		int *hotdrop)
+		bool invert,
+		bool *hotdrop)
 {
 	/* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
 	u_int8_t _opt[60 - sizeof(struct tcphdr)], *op;
@@ -57,8 +54,8 @@
 	op = skb_header_pointer(skb, protoff + sizeof(struct tcphdr),
 				optlen, _opt);
 	if (op == NULL) {
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	for (i = 0; i < optlen; ) {
@@ -70,7 +67,7 @@
 	return invert;
 }
 
-static int
+static bool
 tcp_match(const struct sk_buff *skb,
 	  const struct net_device *in,
 	  const struct net_device *out,
@@ -78,7 +75,7 @@
 	  const void *matchinfo,
 	  int offset,
 	  unsigned int protoff,
-	  int *hotdrop)
+	  bool *hotdrop)
 {
 	struct tcphdr _tcph, *th;
 	const struct xt_tcp *tcpinfo = matchinfo;
@@ -92,51 +89,51 @@
 		*/
 		if (offset == 1) {
 			duprintf("Dropping evil TCP offset=1 frag.\n");
-			*hotdrop = 1;
+			*hotdrop = true;
 		}
 		/* Must not be a fragment. */
-		return 0;
+		return false;
 	}
 
-#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
+#define FWINVTCP(bool, invflg) ((bool) ^ !!(tcpinfo->invflags & (invflg)))
 
 	th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
 	if (th == NULL) {
 		/* We've been asked to examine this packet, and we
 		   can't.  Hence, no choice but to drop. */
 		duprintf("Dropping evil TCP offset=0 tinygram.\n");
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1],
 			ntohs(th->source),
 			!!(tcpinfo->invflags & XT_TCP_INV_SRCPT)))
-		return 0;
+		return false;
 	if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1],
 			ntohs(th->dest),
 			!!(tcpinfo->invflags & XT_TCP_INV_DSTPT)))
-		return 0;
+		return false;
 	if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask)
 		      == tcpinfo->flg_cmp,
 		      XT_TCP_INV_FLAGS))
-		return 0;
+		return false;
 	if (tcpinfo->option) {
 		if (th->doff * 4 < sizeof(_tcph)) {
-			*hotdrop = 1;
-			return 0;
+			*hotdrop = true;
+			return false;
 		}
 		if (!tcp_find_option(tcpinfo->option, skb, protoff,
 				     th->doff*4 - sizeof(_tcph),
 				     tcpinfo->invflags & XT_TCP_INV_OPTION,
 				     hotdrop))
-			return 0;
+			return false;
 	}
-	return 1;
+	return true;
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 tcp_checkentry(const char *tablename,
 	       const void *info,
 	       const struct xt_match *match,
@@ -149,7 +146,7 @@
 	return !(tcpinfo->invflags & ~XT_TCP_INV_MASK);
 }
 
-static int
+static bool
 udp_match(const struct sk_buff *skb,
 	  const struct net_device *in,
 	  const struct net_device *out,
@@ -157,22 +154,22 @@
 	  const void *matchinfo,
 	  int offset,
 	  unsigned int protoff,
-	  int *hotdrop)
+	  bool *hotdrop)
 {
 	struct udphdr _udph, *uh;
 	const struct xt_udp *udpinfo = matchinfo;
 
 	/* Must not be a fragment. */
 	if (offset)
-		return 0;
+		return false;
 
 	uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph);
 	if (uh == NULL) {
 		/* We've been asked to examine this packet, and we
 		   can't.  Hence, no choice but to drop. */
 		duprintf("Dropping evil UDP tinygram.\n");
-		*hotdrop = 1;
-		return 0;
+		*hotdrop = true;
+		return false;
 	}
 
 	return port_match(udpinfo->spts[0], udpinfo->spts[1],
@@ -184,7 +181,7 @@
 }
 
 /* Called when user tries to insert an entry of this type. */
-static int
+static bool
 udp_checkentry(const char *tablename,
 	       const void *info,
 	       const struct xt_match *match,
@@ -197,7 +194,7 @@
 	return !(udpinfo->invflags & ~XT_UDP_INV_MASK);
 }
 
-static struct xt_match xt_tcpudp_match[] = {
+static struct xt_match xt_tcpudp_match[] __read_mostly = {
 	{
 		.name		= "tcp",
 		.family		= AF_INET,
diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c
new file mode 100644
index 0000000..04b677a
--- /dev/null
+++ b/net/netfilter/xt_u32.c
@@ -0,0 +1,135 @@
+/*
+ *	xt_u32 - kernel module to match u32 packet content
+ *
+ *	Original author: Don Cohen <don@isis.cs3-inc.com>
+ *	© Jan Engelhardt <jengelh@gmx.de>, 2007
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <linux/types.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_u32.h>
+
+static bool u32_match_it(const struct xt_u32 *data,
+			 const struct sk_buff *skb)
+{
+	const struct xt_u32_test *ct;
+	unsigned int testind;
+	unsigned int nnums;
+	unsigned int nvals;
+	unsigned int i;
+	u_int32_t pos;
+	u_int32_t val;
+	u_int32_t at;
+	int ret;
+
+	/*
+	 * Small example: "0 >> 28 == 4 && 8 & 0xFF0000 >> 16 = 6, 17"
+	 * (=IPv4 and (TCP or UDP)). Outer loop runs over the "&&" operands.
+	 */
+	for (testind = 0; testind < data->ntests; ++testind) {
+		ct  = &data->tests[testind];
+		at  = 0;
+		pos = ct->location[0].number;
+
+		if (skb->len < 4 || pos > skb->len - 4);
+			return false;
+
+		ret   = skb_copy_bits(skb, pos, &val, sizeof(val));
+		BUG_ON(ret < 0);
+		val   = ntohl(val);
+		nnums = ct->nnums;
+
+		/* Inner loop runs over "&", "<<", ">>" and "@" operands */
+		for (i = 1; i < nnums; ++i) {
+			u_int32_t number = ct->location[i].number;
+			switch (ct->location[i].nextop) {
+			case XT_U32_AND:
+				val &= number;
+				break;
+			case XT_U32_LEFTSH:
+				val <<= number;
+				break;
+			case XT_U32_RIGHTSH:
+				val >>= number;
+				break;
+			case XT_U32_AT:
+				if (at + val < at)
+					return false;
+				at += val;
+				pos = number;
+				if (at + 4 < at || skb->len < at + 4 ||
+				    pos > skb->len - at - 4)
+					return false;
+
+				ret = skb_copy_bits(skb, at + pos, &val,
+						    sizeof(val));
+				BUG_ON(ret < 0);
+				val = ntohl(val);
+				break;
+			}
+		}
+
+		/* Run over the "," and ":" operands */
+		nvals = ct->nvalues;
+		for (i = 0; i < nvals; ++i)
+			if (ct->value[i].min <= val && val <= ct->value[i].max)
+				break;
+
+		if (i >= ct->nvalues)
+			return false;
+	}
+
+	return true;
+}
+
+static bool u32_match(const struct sk_buff *skb,
+		      const struct net_device *in,
+		      const struct net_device *out,
+		      const struct xt_match *match, const void *matchinfo,
+		      int offset, unsigned int protoff, bool *hotdrop)
+{
+	const struct xt_u32 *data = matchinfo;
+	bool ret;
+
+	ret = u32_match_it(data, skb);
+	return ret ^ data->invert;
+}
+
+static struct xt_match u32_reg[] __read_mostly = {
+	{
+		.name       = "u32",
+		.family     = AF_INET,
+		.match      = u32_match,
+		.matchsize  = sizeof(struct xt_u32),
+		.me         = THIS_MODULE,
+	},
+	{
+		.name       = "u32",
+		.family     = AF_INET6,
+		.match      = u32_match,
+		.matchsize  = sizeof(struct xt_u32),
+		.me         = THIS_MODULE,
+	},
+};
+
+static int __init xt_u32_init(void)
+{
+	return xt_register_matches(u32_reg, ARRAY_SIZE(u32_reg));
+}
+
+static void __exit xt_u32_exit(void)
+{
+	xt_unregister_matches(u32_reg, ARRAY_SIZE(u32_reg));
+}
+
+module_init(xt_u32_init);
+module_exit(xt_u32_exit);
+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
+MODULE_DESCRIPTION("netfilter u32 match module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_u32");
+MODULE_ALIAS("ip6t_u32");
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 1f15821..a3c8e69 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1713,7 +1713,7 @@
 	return 0;
 }
 
-static struct seq_operations netlink_seq_ops = {
+static const struct seq_operations netlink_seq_ops = {
 	.start  = netlink_seq_start,
 	.next   = netlink_seq_next,
 	.stop   = netlink_seq_stop,
diff --git a/net/netlink/attr.c b/net/netlink/attr.c
index c591212..e4d7bed 100644
--- a/net/netlink/attr.c
+++ b/net/netlink/attr.c
@@ -72,6 +72,17 @@
 			return -ERANGE;
 		break;
 
+	case NLA_NESTED_COMPAT:
+		if (attrlen < pt->len)
+			return -ERANGE;
+		if (attrlen < NLA_ALIGN(pt->len))
+			break;
+		if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN)
+			return -ERANGE;
+		nla = nla_data(nla) + NLA_ALIGN(pt->len);
+		if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN + nla_len(nla))
+			return -ERANGE;
+		break;
 	default:
 		if (pt->len)
 			minlen = pt->len;
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 5d4a26c..5d66490 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1328,7 +1328,7 @@
 	return 0;
 }
 
-static struct seq_operations nr_info_seqops = {
+static const struct seq_operations nr_info_seqops = {
 	.start = nr_info_start,
 	.next = nr_info_next,
 	.stop = nr_info_stop,
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 2f76e062..24fe4a6 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -922,7 +922,7 @@
 	return 0;
 }
 
-static struct seq_operations nr_node_seqops = {
+static const struct seq_operations nr_node_seqops = {
 	.start = nr_node_start,
 	.next = nr_node_next,
 	.stop = nr_node_stop,
@@ -1006,7 +1006,7 @@
 	return 0;
 }
 
-static struct seq_operations nr_neigh_seqops = {
+static const struct seq_operations nr_neigh_seqops = {
 	.start = nr_neigh_start,
 	.next = nr_neigh_next,
 	.stop = nr_neigh_stop,
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index f8b8301..7c27bd3 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1928,7 +1928,7 @@
 	return 0;
 }
 
-static struct seq_operations packet_seq_ops = {
+static const struct seq_operations packet_seq_ops = {
 	.start	= packet_seq_start,
 	.next	= packet_seq_next,
 	.stop	= packet_seq_stop,
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index d476c43..f4d3aba 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1454,7 +1454,7 @@
 	return 0;
 }
 
-static struct seq_operations rose_info_seqops = {
+static const struct seq_operations rose_info_seqops = {
 	.start = rose_info_start,
 	.next = rose_info_next,
 	.stop = rose_info_stop,
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 929a784..bbcbad1 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -1118,7 +1118,7 @@
 	return 0;
 }
 
-static struct seq_operations rose_node_seqops = {
+static const struct seq_operations rose_node_seqops = {
 	.start = rose_node_start,
 	.next = rose_node_next,
 	.stop = rose_node_stop,
@@ -1200,7 +1200,7 @@
 }
 
 
-static struct seq_operations rose_neigh_seqops = {
+static const struct seq_operations rose_neigh_seqops = {
 	.start = rose_neigh_start,
 	.next = rose_neigh_next,
 	.stop = rose_neigh_stop,
@@ -1284,7 +1284,7 @@
 	return 0;
 }
 
-static struct seq_operations rose_route_seqops = {
+static const struct seq_operations rose_route_seqops = {
 	.start = rose_route_start,
 	.next = rose_route_next,
 	.stop = rose_route_stop,
diff --git a/net/rxrpc/ar-proc.c b/net/rxrpc/ar-proc.c
index 1c0be0e..2e83ce3 100644
--- a/net/rxrpc/ar-proc.c
+++ b/net/rxrpc/ar-proc.c
@@ -30,31 +30,13 @@
  */
 static void *rxrpc_call_seq_start(struct seq_file *seq, loff_t *_pos)
 {
-	struct list_head *_p;
-	loff_t pos = *_pos;
-
 	read_lock(&rxrpc_call_lock);
-	if (!pos)
-		return SEQ_START_TOKEN;
-	pos--;
-
-	list_for_each(_p, &rxrpc_calls)
-		if (!pos--)
-			break;
-
-	return _p != &rxrpc_calls ? _p : NULL;
+	return seq_list_start_head(&rxrpc_calls, *_pos);
 }
 
 static void *rxrpc_call_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	struct list_head *_p;
-
-	(*pos)++;
-
-	_p = v;
-	_p = (v == SEQ_START_TOKEN) ? rxrpc_calls.next : _p->next;
-
-	return _p != &rxrpc_calls ? _p : NULL;
+	return seq_list_next(v, &rxrpc_calls, pos);
 }
 
 static void rxrpc_call_seq_stop(struct seq_file *seq, void *v)
@@ -68,7 +50,7 @@
 	struct rxrpc_call *call;
 	char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1];
 
-	if (v == SEQ_START_TOKEN) {
+	if (v == &rxrpc_calls) {
 		seq_puts(seq,
 			 "Proto Local                  Remote                "
 			 " SvID ConnID   CallID   End Use State    Abort   "
@@ -104,7 +86,7 @@
 	return 0;
 }
 
-static struct seq_operations rxrpc_call_seq_ops = {
+static const struct seq_operations rxrpc_call_seq_ops = {
 	.start  = rxrpc_call_seq_start,
 	.next   = rxrpc_call_seq_next,
 	.stop   = rxrpc_call_seq_stop,
@@ -129,32 +111,14 @@
  */
 static void *rxrpc_connection_seq_start(struct seq_file *seq, loff_t *_pos)
 {
-	struct list_head *_p;
-	loff_t pos = *_pos;
-
 	read_lock(&rxrpc_connection_lock);
-	if (!pos)
-		return SEQ_START_TOKEN;
-	pos--;
-
-	list_for_each(_p, &rxrpc_connections)
-		if (!pos--)
-			break;
-
-	return _p != &rxrpc_connections ? _p : NULL;
+	return seq_list_start_head(&rxrpc_connections, *_pos);
 }
 
 static void *rxrpc_connection_seq_next(struct seq_file *seq, void *v,
 				       loff_t *pos)
 {
-	struct list_head *_p;
-
-	(*pos)++;
-
-	_p = v;
-	_p = (v == SEQ_START_TOKEN) ? rxrpc_connections.next : _p->next;
-
-	return _p != &rxrpc_connections ? _p : NULL;
+	return seq_list_next(v, &rxrpc_connections, pos);
 }
 
 static void rxrpc_connection_seq_stop(struct seq_file *seq, void *v)
@@ -168,7 +132,7 @@
 	struct rxrpc_transport *trans;
 	char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1];
 
-	if (v == SEQ_START_TOKEN) {
+	if (v == &rxrpc_connections) {
 		seq_puts(seq,
 			 "Proto Local                  Remote                "
 			 " SvID ConnID   Calls    End Use State    Key     "
@@ -206,7 +170,7 @@
 	return 0;
 }
 
-static struct seq_operations rxrpc_connection_seq_ops = {
+static const struct seq_operations rxrpc_connection_seq_ops = {
 	.start  = rxrpc_connection_seq_start,
 	.next   = rxrpc_connection_seq_next,
 	.stop   = rxrpc_connection_seq_stop,
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 475df84..b466288 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -111,6 +111,17 @@
 	  To compile this code as a module, choose M here: the
 	  module will be called sch_prio.
 
+config NET_SCH_RR
+	tristate "Multi Band Round Robin Queuing (RR)"
+	select NET_SCH_PRIO
+	---help---
+	  Say Y here if you want to use an n-band round robin packet
+	  scheduler.
+
+	  The module uses sch_prio for its framework and is aliased as
+	  sch_rr, so it will load sch_prio, although it is referred
+	  to using sch_rr.
+
 config NET_SCH_RED
 	tristate "Random Early Detection (RED)"
 	---help---
@@ -275,7 +286,6 @@
 config NET_CLS_RSVP
 	tristate "IPv4 Resource Reservation Protocol (RSVP)"
 	select NET_CLS
-	select NET_ESTIMATOR
 	---help---
 	  The Resource Reservation Protocol (RSVP) permits end systems to
 	  request a minimum and maximum data flow rate for a connection; this
@@ -290,7 +300,6 @@
 config NET_CLS_RSVP6
 	tristate "IPv6 Resource Reservation Protocol (RSVP6)"
 	select NET_CLS
-	select NET_ESTIMATOR
 	---help---
 	  The Resource Reservation Protocol (RSVP) permits end systems to
 	  request a minimum and maximum data flow rate for a connection; this
@@ -382,7 +391,6 @@
 
 config NET_CLS_ACT
 	bool "Actions"
-	select NET_ESTIMATOR
 	---help---
 	  Say Y here if you want to use traffic control actions. Actions
 	  get attached to classifiers and are invoked after a successful
@@ -465,7 +473,6 @@
 config NET_CLS_POLICE
 	bool "Traffic Policing (obsolete)"
 	depends on NET_CLS_ACT!=y
-	select NET_ESTIMATOR
 	---help---
 	  Say Y here if you want to do traffic policing, i.e. strict
 	  bandwidth limiting. This option is obsoleted by the traffic
@@ -480,14 +487,6 @@
 	  classification based on the incoming device. This option is
 	  likely to disappear in favour of the metadata ematch.
 
-config NET_ESTIMATOR
-	bool "Rate estimator"
-	---help---
-	  Say Y here to allow using rate estimators to estimate the current
-	  rate-of-flow for network devices, queues, etc. This module is
-	  automatically selected if needed but can be selected manually for
-	  statistical purposes.
-
 endif # NET_SCHED
 
 endmenu
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 711dd26..feef366 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -11,23 +11,13 @@
  *
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/kmod.h>
-#include <net/sock.h>
 #include <net/sch_generic.h>
 #include <net/act_api.h>
 #include <net/netlink.h>
@@ -42,10 +32,8 @@
 			write_lock_bh(hinfo->lock);
 			*p1p = p->tcfc_next;
 			write_unlock_bh(hinfo->lock);
-#ifdef CONFIG_NET_ESTIMATOR
 			gen_kill_estimator(&p->tcfc_bstats,
 					   &p->tcfc_rate_est);
-#endif
 			kfree(p);
 			return;
 		}
@@ -232,15 +220,12 @@
 		p->tcfc_bindcnt = 1;
 
 	spin_lock_init(&p->tcfc_lock);
-	p->tcfc_stats_lock = &p->tcfc_lock;
 	p->tcfc_index = index ? index : tcf_hash_new_index(idx_gen, hinfo);
 	p->tcfc_tm.install = jiffies;
 	p->tcfc_tm.lastuse = jiffies;
-#ifdef CONFIG_NET_ESTIMATOR
 	if (est)
 		gen_new_estimator(&p->tcfc_bstats, &p->tcfc_rate_est,
-				  p->tcfc_stats_lock, est);
-#endif
+				  &p->tcfc_lock, est);
 	a->priv = (void *) p;
 	return p;
 }
@@ -599,12 +584,12 @@
 	if (compat_mode) {
 		if (a->type == TCA_OLD_COMPAT)
 			err = gnet_stats_start_copy_compat(skb, 0,
-				TCA_STATS, TCA_XSTATS, h->tcf_stats_lock, &d);
+				TCA_STATS, TCA_XSTATS, &h->tcf_lock, &d);
 		else
 			return 0;
 	} else
 		err = gnet_stats_start_copy(skb, TCA_ACT_STATS,
-			h->tcf_stats_lock, &d);
+					    &h->tcf_lock, &d);
 
 	if (err < 0)
 		goto errout;
@@ -614,9 +599,7 @@
 			goto errout;
 
 	if (gnet_stats_copy_basic(&d, &h->tcf_bstats) < 0 ||
-#ifdef CONFIG_NET_ESTIMATOR
 	    gnet_stats_copy_rate_est(&d, &h->tcf_rate_est) < 0 ||
-#endif
 	    gnet_stats_copy_queue(&d, &h->tcf_qstats) < 0)
 		goto errout;
 
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index 7517f37..a9631e4 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -10,26 +10,15 @@
  *
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <linux/tc_act/tc_gact.h>
 #include <net/tc_act/tc_gact.h>
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 00b05f4..6b407ec 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -11,27 +11,15 @@
  * Copyright:	Jamal Hadi Salim (2002-4)
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/kmod.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <linux/tc_act/tc_ipt.h>
 #include <net/tc_act/tc_ipt.h>
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index de21c92..5795789 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -12,31 +12,19 @@
  *
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <linux/tc_act/tc_mirred.h>
 #include <net/tc_act/tc_mirred.h>
 
-#include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 
 #define MIRRED_TAB_MASK     7
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 6f8684b..b46fab5 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -9,26 +9,15 @@
  * Authors:	Jamal Hadi Salim (2002-4)
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <linux/tc_act/tc_pedit.h>
 #include <net/tc_act/tc_pedit.h>
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 616f465..d204038 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -10,25 +10,15 @@
  * 		J Hadi Salim (action changes)
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/module.h>
 #include <linux/rtnetlink.h>
 #include <linux/init.h>
-#include <net/sock.h>
 #include <net/act_api.h>
 #include <net/netlink.h>
 
@@ -118,10 +108,8 @@
 			write_lock_bh(&police_lock);
 			*p1p = p->tcf_next;
 			write_unlock_bh(&police_lock);
-#ifdef CONFIG_NET_ESTIMATOR
 			gen_kill_estimator(&p->tcf_bstats,
 					   &p->tcf_rate_est);
-#endif
 			if (p->tcfp_R_tab)
 				qdisc_put_rtab(p->tcfp_R_tab);
 			if (p->tcfp_P_tab)
@@ -185,7 +173,6 @@
 	ret = ACT_P_CREATED;
 	police->tcf_refcnt = 1;
 	spin_lock_init(&police->tcf_lock);
-	police->tcf_stats_lock = &police->tcf_lock;
 	if (bind)
 		police->tcf_bindcnt = 1;
 override:
@@ -227,15 +214,13 @@
 		police->tcfp_ptoks = L2T_P(police, police->tcfp_mtu);
 	police->tcf_action = parm->action;
 
-#ifdef CONFIG_NET_ESTIMATOR
 	if (tb[TCA_POLICE_AVRATE-1])
 		police->tcfp_ewma_rate =
 			*(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]);
 	if (est)
 		gen_replace_estimator(&police->tcf_bstats,
 				      &police->tcf_rate_est,
-				      police->tcf_stats_lock, est);
-#endif
+				      &police->tcf_lock, est);
 
 	spin_unlock_bh(&police->tcf_lock);
 	if (ret != ACT_P_CREATED)
@@ -281,14 +266,12 @@
 	police->tcf_bstats.bytes += skb->len;
 	police->tcf_bstats.packets++;
 
-#ifdef CONFIG_NET_ESTIMATOR
 	if (police->tcfp_ewma_rate &&
 	    police->tcf_rate_est.bps >= police->tcfp_ewma_rate) {
 		police->tcf_qstats.overlimits++;
 		spin_unlock(&police->tcf_lock);
 		return police->tcf_action;
 	}
-#endif
 
 	if (skb->len <= police->tcfp_mtu) {
 		if (police->tcfp_R_tab == NULL) {
@@ -348,10 +331,8 @@
 	if (police->tcfp_result)
 		RTA_PUT(skb, TCA_POLICE_RESULT, sizeof(int),
 			&police->tcfp_result);
-#ifdef CONFIG_NET_ESTIMATOR
 	if (police->tcfp_ewma_rate)
 		RTA_PUT(skb, TCA_POLICE_AVRATE, 4, &police->tcfp_ewma_rate);
-#endif
 	return skb->len;
 
 rtattr_failure:
@@ -458,7 +439,6 @@
 
 	police->tcf_refcnt = 1;
 	spin_lock_init(&police->tcf_lock);
-	police->tcf_stats_lock = &police->tcf_lock;
 	if (parm->rate.rate) {
 		police->tcfp_R_tab =
 			qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1]);
@@ -477,14 +457,12 @@
 			goto failure;
 		police->tcfp_result = *(u32*)RTA_DATA(tb[TCA_POLICE_RESULT-1]);
 	}
-#ifdef CONFIG_NET_ESTIMATOR
 	if (tb[TCA_POLICE_AVRATE-1]) {
 		if (RTA_PAYLOAD(tb[TCA_POLICE_AVRATE-1]) != sizeof(u32))
 			goto failure;
 		police->tcfp_ewma_rate =
 			*(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]);
 	}
-#endif
 	police->tcfp_toks = police->tcfp_burst = parm->burst;
 	police->tcfp_mtu = parm->mtu;
 	if (police->tcfp_mtu == 0) {
@@ -498,11 +476,9 @@
 	police->tcf_index = parm->index ? parm->index :
 		tcf_police_new_index();
 	police->tcf_action = parm->action;
-#ifdef CONFIG_NET_ESTIMATOR
 	if (est)
 		gen_new_estimator(&police->tcf_bstats, &police->tcf_rate_est,
-				  police->tcf_stats_lock, est);
-#endif
+				  &police->tcf_lock, est);
 	h = tcf_hash(police->tcf_index, POL_TAB_MASK);
 	write_lock_bh(&police_lock);
 	police->tcf_next = tcf_police_ht[h];
@@ -528,14 +504,12 @@
 	police->tcf_bstats.bytes += skb->len;
 	police->tcf_bstats.packets++;
 
-#ifdef CONFIG_NET_ESTIMATOR
 	if (police->tcfp_ewma_rate &&
 	    police->tcf_rate_est.bps >= police->tcfp_ewma_rate) {
 		police->tcf_qstats.overlimits++;
 		spin_unlock(&police->tcf_lock);
 		return police->tcf_action;
 	}
-#endif
 	if (skb->len <= police->tcfp_mtu) {
 		if (police->tcfp_R_tab == NULL) {
 			spin_unlock(&police->tcf_lock);
@@ -591,10 +565,8 @@
 	if (police->tcfp_result)
 		RTA_PUT(skb, TCA_POLICE_RESULT, sizeof(int),
 			&police->tcfp_result);
-#ifdef CONFIG_NET_ESTIMATOR
 	if (police->tcfp_ewma_rate)
 		RTA_PUT(skb, TCA_POLICE_AVRATE, 4, &police->tcfp_ewma_rate);
-#endif
 	return skb->len;
 
 rtattr_failure:
@@ -607,14 +579,12 @@
 	struct gnet_dump d;
 
 	if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
-					 TCA_XSTATS, police->tcf_stats_lock,
+					 TCA_XSTATS, &police->tcf_lock,
 					 &d) < 0)
 		goto errout;
 
 	if (gnet_stats_copy_basic(&d, &police->tcf_bstats) < 0 ||
-#ifdef CONFIG_NET_ESTIMATOR
 	    gnet_stats_copy_rate_est(&d, &police->tcf_rate_est) < 0 ||
-#endif
 	    gnet_stats_copy_queue(&d, &police->tcf_qstats) < 0)
 		goto errout;
 
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 36e1eda..fb84ef3 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -13,7 +13,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <net/netlink.h>
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index ebf94ed..36b72aa 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -14,26 +14,16 @@
  *
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/netlink.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <net/pkt_cls.h>
 
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index c885412..8dbcf27 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -13,7 +13,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index bbec4a0..8adbd6a 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -19,29 +19,12 @@
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <linux/netfilter.h>
-#include <net/ip.h>
-#include <net/netlink.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/netlink.h>
 #include <net/act_api.h>
 #include <net/pkt_cls.h>
 
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index cc941d0..0a8409c 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -10,28 +10,14 @@
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/netlink.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/dst.h>
+#include <net/route.h>
+#include <net/netlink.h>
 #include <net/act_api.h>
 #include <net/pkt_cls.h>
 
diff --git a/net/sched/cls_rsvp.c b/net/sched/cls_rsvp.c
index 0a683c0..cbb5e0d 100644
--- a/net/sched/cls_rsvp.c
+++ b/net/sched/cls_rsvp.c
@@ -10,27 +10,12 @@
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/ip.h>
 #include <net/netlink.h>
 #include <net/act_api.h>
 #include <net/pkt_cls.h>
diff --git a/net/sched/cls_rsvp6.c b/net/sched/cls_rsvp6.c
index 93b6abe..dd08aea 100644
--- a/net/sched/cls_rsvp6.c
+++ b/net/sched/cls_rsvp6.c
@@ -10,28 +10,12 @@
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
 #include <linux/ipv6.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
 #include <net/act_api.h>
 #include <net/pkt_cls.h>
 #include <net/netlink.h>
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 47ac0c5..2314820 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -9,12 +9,9 @@
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <net/ip.h>
 #include <net/act_api.h>
 #include <net/netlink.h>
 #include <net/pkt_cls.h>
-#include <net/route.h>
 
 
 /*
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index c7a347b..77961e2 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -30,30 +30,14 @@
  *	nfmark match added by Catalin(ux aka Dino) BOIE <catab at umbrella.ro>
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
 #include <linux/rtnetlink.h>
-#include <net/ip.h>
-#include <net/netlink.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/netlink.h>
 #include <net/act_api.h>
 #include <net/pkt_cls.h>
 
diff --git a/net/sched/em_cmp.c b/net/sched/em_cmp.c
index 8d6dacd..cc49c93 100644
--- a/net/sched/em_cmp.c
+++ b/net/sched/em_cmp.c
@@ -98,3 +98,4 @@
 module_init(init_em_cmp);
 module_exit(exit_em_cmp);
 
+MODULE_ALIAS_TCF_EMATCH(TCF_EM_CMP);
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 60acf8c..650f09c 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -848,3 +848,5 @@
 
 module_init(init_em_meta);
 module_exit(exit_em_meta);
+
+MODULE_ALIAS_TCF_EMATCH(TCF_EM_META);
diff --git a/net/sched/em_nbyte.c b/net/sched/em_nbyte.c
index b4b36ef..370a1b2 100644
--- a/net/sched/em_nbyte.c
+++ b/net/sched/em_nbyte.c
@@ -76,3 +76,5 @@
 
 module_init(init_em_nbyte);
 module_exit(exit_em_nbyte);
+
+MODULE_ALIAS_TCF_EMATCH(TCF_EM_NBYTE);
diff --git a/net/sched/em_text.c b/net/sched/em_text.c
index e8f4616..d5cd86e 100644
--- a/net/sched/em_text.c
+++ b/net/sched/em_text.c
@@ -150,3 +150,5 @@
 
 module_init(init_em_text);
 module_exit(exit_em_text);
+
+MODULE_ALIAS_TCF_EMATCH(TCF_EM_TEXT);
diff --git a/net/sched/em_u32.c b/net/sched/em_u32.c
index 0a2a7fe..112796e 100644
--- a/net/sched/em_u32.c
+++ b/net/sched/em_u32.c
@@ -60,3 +60,5 @@
 
 module_init(init_em_u32);
 module_exit(exit_em_u32);
+
+MODULE_ALIAS_TCF_EMATCH(TCF_EM_U32);
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index 63146d3..f3a104e 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -84,9 +84,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/mm.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
 #include <net/pkt_cls.h>
@@ -224,6 +222,19 @@
 
 		if (em->ops == NULL) {
 			err = -ENOENT;
+#ifdef CONFIG_KMOD
+			__rtnl_unlock();
+			request_module("ematch-kind-%u", em_hdr->kind);
+			rtnl_lock();
+			em->ops = tcf_em_lookup(em_hdr->kind);
+			if (em->ops) {
+				/* We dropped the RTNL mutex in order to
+				 * perform the module load. Tell the caller
+				 * to replay the request. */
+				module_put(em->ops->owner);
+				err = -EAGAIN;
+			}
+#endif
 			goto errout;
 		}
 
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index bec600a..d92ea26 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -19,30 +19,18 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/kmod.h>
 #include <linux/list.h>
-#include <linux/bitops.h>
 #include <linux/hrtimer.h>
 
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
 static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, u32 clid,
 			struct Qdisc *old, struct Qdisc *new);
 static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n,
@@ -515,7 +503,6 @@
 	sch->handle = handle;
 
 	if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
-#ifdef CONFIG_NET_ESTIMATOR
 		if (tca[TCA_RATE-1]) {
 			err = gen_new_estimator(&sch->bstats, &sch->rate_est,
 						sch->stats_lock,
@@ -531,7 +518,6 @@
 				goto err_out3;
 			}
 		}
-#endif
 		qdisc_lock_tree(dev);
 		list_add_tail(&sch->list, &dev->qdisc_list);
 		qdisc_unlock_tree(dev);
@@ -559,11 +545,9 @@
 		if (err)
 			return err;
 	}
-#ifdef CONFIG_NET_ESTIMATOR
 	if (tca[TCA_RATE-1])
 		gen_replace_estimator(&sch->bstats, &sch->rate_est,
 			sch->stats_lock, tca[TCA_RATE-1]);
-#endif
 	return 0;
 }
 
@@ -839,9 +823,7 @@
 		goto rtattr_failure;
 
 	if (gnet_stats_copy_basic(&d, &q->bstats) < 0 ||
-#ifdef CONFIG_NET_ESTIMATOR
 	    gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 ||
-#endif
 	    gnet_stats_copy_queue(&d, &q->qstats) < 0)
 		goto rtattr_failure;
 
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index d1c383f..54b92d2 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -8,15 +8,12 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/skbuff.h>
-#include <linux/interrupt.h>
 #include <linux/atmdev.h>
 #include <linux/atmclip.h>
-#include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/file.h> /* for fput */
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <net/sock.h>
 
 
 extern struct socket *sockfd_lookup(int fd, int *err); /* @@@ fix this */
@@ -71,7 +68,6 @@
 	int			ref;		/* reference count */
 	struct gnet_stats_basic	bstats;
 	struct gnet_stats_queue	qstats;
-	spinlock_t		*stats_lock;
 	struct atm_flow_data	*next;
 	struct atm_flow_data	*excess;	/* flow for excess traffic;
 						   NULL to set CLP instead */
diff --git a/net/sched/sch_blackhole.c b/net/sched/sch_blackhole.c
index cb0c456..f914fc4 100644
--- a/net/sched/sch_blackhole.c
+++ b/net/sched/sch_blackhole.c
@@ -14,7 +14,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/pkt_sched.h>
 
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index ee2d596..b184c35 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -11,28 +11,12 @@
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/netlink.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/netlink.h>
 #include <net/pkt_sched.h>
 
 
@@ -148,7 +132,6 @@
 	struct gnet_stats_basic bstats;
 	struct gnet_stats_queue qstats;
 	struct gnet_stats_rate_est rate_est;
-	spinlock_t		*stats_lock;
 	struct tc_cbq_xstats	xstats;
 
 	struct tcf_proto	*filter_list;
@@ -1442,7 +1425,6 @@
 	q->link.ewma_log = TC_CBQ_DEF_EWMA;
 	q->link.avpkt = q->link.allot/2;
 	q->link.minidle = -0x7FFFFFFF;
-	q->link.stats_lock = &sch->dev->queue_lock;
 
 	qdisc_watchdog_init(&q->watchdog, sch);
 	hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
@@ -1653,9 +1635,7 @@
 		cl->xstats.undertime = cl->undertime - q->now;
 
 	if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
-#ifdef CONFIG_NET_ESTIMATOR
 	    gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
-#endif
 	    gnet_stats_copy_queue(d, &cl->qstats) < 0)
 		return -1;
 
@@ -1726,9 +1706,7 @@
 	tcf_destroy_chain(cl->filter_list);
 	qdisc_destroy(cl->q);
 	qdisc_put_rtab(cl->R_tab);
-#ifdef CONFIG_NET_ESTIMATOR
 	gen_kill_estimator(&cl->bstats, &cl->rate_est);
-#endif
 	if (cl != &q->link)
 		kfree(cl);
 }
@@ -1873,11 +1851,10 @@
 
 		sch_tree_unlock(sch);
 
-#ifdef CONFIG_NET_ESTIMATOR
 		if (tca[TCA_RATE-1])
 			gen_replace_estimator(&cl->bstats, &cl->rate_est,
-				cl->stats_lock, tca[TCA_RATE-1]);
-#endif
+					      &sch->dev->queue_lock,
+					      tca[TCA_RATE-1]);
 		return 0;
 	}
 
@@ -1935,7 +1912,6 @@
 	cl->allot = parent->allot;
 	cl->quantum = cl->allot;
 	cl->weight = cl->R_tab->rate.rate;
-	cl->stats_lock = &sch->dev->queue_lock;
 
 	sch_tree_lock(sch);
 	cbq_link_class(cl);
@@ -1963,11 +1939,9 @@
 		cbq_set_fopt(cl, RTA_DATA(tb[TCA_CBQ_FOPT-1]));
 	sch_tree_unlock(sch);
 
-#ifdef CONFIG_NET_ESTIMATOR
 	if (tca[TCA_RATE-1])
 		gen_new_estimator(&cl->bstats, &cl->rate_est,
-			cl->stats_lock, tca[TCA_RATE-1]);
-#endif
+				  &sch->dev->queue_lock, tca[TCA_RATE-1]);
 
 	*arg = (unsigned long)cl;
 	return 0;
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 3c6fd18..4d2c233 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -9,7 +9,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/skbuff.h>
-#include <linux/netdevice.h> /* for pkt_sched */
 #include <linux/rtnetlink.h>
 #include <net/pkt_sched.h>
 #include <net/dsfield.h>
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index c2689f4..c264308 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -13,7 +13,6 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/pkt_sched.h>
 
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index f4d3448..c81649c 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -11,27 +11,19 @@
  *              - Ingress support
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
 #include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/init.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 
 /* Main transmission queue. */
@@ -59,122 +51,143 @@
 	spin_unlock_bh(&dev->queue_lock);
 }
 
+static inline int qdisc_qlen(struct Qdisc *q)
+{
+	return q->q.qlen;
+}
+
+static inline int dev_requeue_skb(struct sk_buff *skb, struct net_device *dev,
+				  struct Qdisc *q)
+{
+	if (unlikely(skb->next))
+		dev->gso_skb = skb;
+	else
+		q->ops->requeue(skb, q);
+
+	netif_schedule(dev);
+	return 0;
+}
+
+static inline struct sk_buff *dev_dequeue_skb(struct net_device *dev,
+					      struct Qdisc *q)
+{
+	struct sk_buff *skb;
+
+	if ((skb = dev->gso_skb))
+		dev->gso_skb = NULL;
+	else
+		skb = q->dequeue(q);
+
+	return skb;
+}
+
+static inline int handle_dev_cpu_collision(struct sk_buff *skb,
+					   struct net_device *dev,
+					   struct Qdisc *q)
+{
+	int ret;
+
+	if (unlikely(dev->xmit_lock_owner == smp_processor_id())) {
+		/*
+		 * Same CPU holding the lock. It may be a transient
+		 * configuration error, when hard_start_xmit() recurses. We
+		 * detect it by checking xmit owner and drop the packet when
+		 * deadloop is detected. Return OK to try the next skb.
+		 */
+		kfree_skb(skb);
+		if (net_ratelimit())
+			printk(KERN_WARNING "Dead loop on netdevice %s, "
+			       "fix it urgently!\n", dev->name);
+		ret = qdisc_qlen(q);
+	} else {
+		/*
+		 * Another cpu is holding lock, requeue & delay xmits for
+		 * some time.
+		 */
+		__get_cpu_var(netdev_rx_stat).cpu_collision++;
+		ret = dev_requeue_skb(skb, dev, q);
+	}
+
+	return ret;
+}
+
 /*
-   dev->queue_lock serializes queue accesses for this device
-   AND dev->qdisc pointer itself.
-
-   netif_tx_lock serializes accesses to device driver.
-
-   dev->queue_lock and netif_tx_lock are mutually exclusive,
-   if one is grabbed, another must be free.
+ * NOTE: Called under dev->queue_lock with locally disabled BH.
+ *
+ * __LINK_STATE_QDISC_RUNNING guarantees only one CPU can process this
+ * device at a time. dev->queue_lock serializes queue accesses for
+ * this device AND dev->qdisc pointer itself.
+ *
+ *  netif_tx_lock serializes accesses to device driver.
+ *
+ *  dev->queue_lock and netif_tx_lock are mutually exclusive,
+ *  if one is grabbed, another must be free.
+ *
+ * Note, that this procedure can be called by a watchdog timer
+ *
+ * Returns to the caller:
+ *				0  - queue is empty or throttled.
+ *				>0 - queue is not empty.
+ *
  */
-
-
-/* Kick device.
-
-   Returns:  0  - queue is empty or throttled.
-	    >0  - queue is not empty.
-
-   NOTE: Called under dev->queue_lock with locally disabled BH.
-*/
-
 static inline int qdisc_restart(struct net_device *dev)
 {
 	struct Qdisc *q = dev->qdisc;
 	struct sk_buff *skb;
+	unsigned lockless;
+	int ret;
 
 	/* Dequeue packet */
-	if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) {
-		unsigned nolock = (dev->features & NETIF_F_LLTX);
+	if (unlikely((skb = dev_dequeue_skb(dev, q)) == NULL))
+		return 0;
 
-		dev->gso_skb = NULL;
+	/*
+	 * When the driver has LLTX set, it does its own locking in
+	 * start_xmit. These checks are worth it because even uncongested
+	 * locks can be quite expensive. The driver can do a trylock, as
+	 * is being done here; in case of lock contention it should return
+	 * NETDEV_TX_LOCKED and the packet will be requeued.
+	 */
+	lockless = (dev->features & NETIF_F_LLTX);
 
-		/*
-		 * When the driver has LLTX set it does its own locking
-		 * in start_xmit. No need to add additional overhead by
-		 * locking again. These checks are worth it because
-		 * even uncongested locks can be quite expensive.
-		 * The driver can do trylock like here too, in case
-		 * of lock congestion it should return -1 and the packet
-		 * will be requeued.
-		 */
-		if (!nolock) {
-			if (!netif_tx_trylock(dev)) {
-			collision:
-				/* So, someone grabbed the driver. */
-
-				/* It may be transient configuration error,
-				   when hard_start_xmit() recurses. We detect
-				   it by checking xmit owner and drop the
-				   packet when deadloop is detected.
-				*/
-				if (dev->xmit_lock_owner == smp_processor_id()) {
-					kfree_skb(skb);
-					if (net_ratelimit())
-						printk(KERN_DEBUG "Dead loop on netdevice %s, fix it urgently!\n", dev->name);
-					goto out;
-				}
-				__get_cpu_var(netdev_rx_stat).cpu_collision++;
-				goto requeue;
-			}
-		}
-
-		{
-			/* And release queue */
-			spin_unlock(&dev->queue_lock);
-
-			if (!netif_queue_stopped(dev)) {
-				int ret;
-
-				ret = dev_hard_start_xmit(skb, dev);
-				if (ret == NETDEV_TX_OK) {
-					if (!nolock) {
-						netif_tx_unlock(dev);
-					}
-					spin_lock(&dev->queue_lock);
-					q = dev->qdisc;
-					goto out;
-				}
-				if (ret == NETDEV_TX_LOCKED && nolock) {
-					spin_lock(&dev->queue_lock);
-					q = dev->qdisc;
-					goto collision;
-				}
-			}
-
-			/* NETDEV_TX_BUSY - we need to requeue */
-			/* Release the driver */
-			if (!nolock) {
-				netif_tx_unlock(dev);
-			}
-			spin_lock(&dev->queue_lock);
-			q = dev->qdisc;
-		}
-
-		/* Device kicked us out :(
-		   This is possible in three cases:
-
-		   0. driver is locked
-		   1. fastroute is enabled
-		   2. device cannot determine busy state
-		      before start of transmission (f.e. dialout)
-		   3. device is buggy (ppp)
-		 */
-
-requeue:
-		if (unlikely(q == &noop_qdisc))
-			kfree_skb(skb);
-		else if (skb->next)
-			dev->gso_skb = skb;
-		else
-			q->ops->requeue(skb, q);
-		netif_schedule(dev);
+	if (!lockless && !netif_tx_trylock(dev)) {
+		/* Another CPU grabbed the driver tx lock */
+		return handle_dev_cpu_collision(skb, dev, q);
 	}
-	return 0;
 
-out:
-	BUG_ON((int) q->q.qlen < 0);
-	return q->q.qlen;
+	/* And release queue */
+	spin_unlock(&dev->queue_lock);
+
+	ret = dev_hard_start_xmit(skb, dev);
+
+	if (!lockless)
+		netif_tx_unlock(dev);
+
+	spin_lock(&dev->queue_lock);
+	q = dev->qdisc;
+
+	switch (ret) {
+	case NETDEV_TX_OK:
+		/* Driver sent out skb successfully */
+		ret = qdisc_qlen(q);
+		break;
+
+	case NETDEV_TX_LOCKED:
+		/* Driver try lock failed */
+		ret = handle_dev_cpu_collision(skb, dev, q);
+		break;
+
+	default:
+		/* Driver returned NETDEV_TX_BUSY - requeue skb */
+		if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit()))
+			printk(KERN_WARNING "BUG %s code %d qlen %d\n",
+			       dev->name, ret, q->q.qlen);
+
+		ret = dev_requeue_skb(skb, dev, q);
+		break;
+	}
+
+	return ret;
 }
 
 void __qdisc_run(struct net_device *dev)
@@ -493,9 +506,7 @@
 		return;
 
 	list_del(&qdisc->list);
-#ifdef CONFIG_NET_ESTIMATOR
 	gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
-#endif
 	if (ops->reset)
 		ops->reset(qdisc);
 	if (ops->destroy)
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index fa1b4fe..3cc6dda 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -21,7 +21,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/pkt_sched.h>
 #include <net/red.h>
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 9d124c4..874452c 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -53,7 +53,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/jiffies.h>
 #include <linux/compiler.h>
 #include <linux/spinlock.h>
 #include <linux/skbuff.h>
@@ -62,13 +61,11 @@
 #include <linux/list.h>
 #include <linux/rbtree.h>
 #include <linux/init.h>
-#include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/pkt_sched.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
 #include <net/pkt_cls.h>
-#include <asm/system.h>
 #include <asm/div64.h>
 
 /*
@@ -122,7 +119,6 @@
 	struct gnet_stats_basic bstats;
 	struct gnet_stats_queue qstats;
 	struct gnet_stats_rate_est rate_est;
-	spinlock_t	*stats_lock;
 	unsigned int	level;		/* class level in hierarchy */
 	struct tcf_proto *filter_list;	/* filter list */
 	unsigned int	filter_cnt;	/* filter count */
@@ -1054,11 +1050,10 @@
 		}
 		sch_tree_unlock(sch);
 
-#ifdef CONFIG_NET_ESTIMATOR
 		if (tca[TCA_RATE-1])
 			gen_replace_estimator(&cl->bstats, &cl->rate_est,
-				cl->stats_lock, tca[TCA_RATE-1]);
-#endif
+					      &sch->dev->queue_lock,
+					      tca[TCA_RATE-1]);
 		return 0;
 	}
 
@@ -1098,7 +1093,6 @@
 	cl->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid);
 	if (cl->qdisc == NULL)
 		cl->qdisc = &noop_qdisc;
-	cl->stats_lock = &sch->dev->queue_lock;
 	INIT_LIST_HEAD(&cl->children);
 	cl->vt_tree = RB_ROOT;
 	cl->cf_tree = RB_ROOT;
@@ -1112,11 +1106,9 @@
 	cl->cl_pcvtoff = parent->cl_cvtoff;
 	sch_tree_unlock(sch);
 
-#ifdef CONFIG_NET_ESTIMATOR
 	if (tca[TCA_RATE-1])
 		gen_new_estimator(&cl->bstats, &cl->rate_est,
-			cl->stats_lock, tca[TCA_RATE-1]);
-#endif
+				  &sch->dev->queue_lock, tca[TCA_RATE-1]);
 	*arg = (unsigned long)cl;
 	return 0;
 }
@@ -1128,9 +1120,7 @@
 
 	tcf_destroy_chain(cl->filter_list);
 	qdisc_destroy(cl->qdisc);
-#ifdef CONFIG_NET_ESTIMATOR
 	gen_kill_estimator(&cl->bstats, &cl->rate_est);
-#endif
 	if (cl != &q->root)
 		kfree(cl);
 }
@@ -1384,9 +1374,7 @@
 	xstats.rtwork  = cl->cl_cumul;
 
 	if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
-#ifdef CONFIG_NET_ESTIMATOR
 	    gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
-#endif
 	    gnet_stats_copy_queue(d, &cl->qstats) < 0)
 		return -1;
 
@@ -1448,8 +1436,6 @@
 		return -EINVAL;
 	qopt = RTA_DATA(opt);
 
-	sch->stats_lock = &sch->dev->queue_lock;
-
 	q->defcls = qopt->defcls;
 	for (i = 0; i < HFSC_HSIZE; i++)
 		INIT_LIST_HEAD(&q->clhash[i]);
@@ -1464,7 +1450,6 @@
 					  sch->handle);
 	if (q->root.qdisc == NULL)
 		q->root.qdisc = &noop_qdisc;
-	q->root.stats_lock = &sch->dev->queue_lock;
 	INIT_LIST_HEAD(&q->root.children);
 	q->root.vt_tree = RB_ROOT;
 	q->root.cf_tree = RB_ROOT;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 035788c..b417a95 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -28,32 +28,16 @@
  * $Id: sch_htb.c,v 1.25 2003/12/07 11:08:25 devik Exp devik $
  */
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
 #include <linux/list.h>
 #include <linux/compiler.h>
-#include <net/netlink.h>
-#include <net/sock.h>
-#include <net/pkt_sched.h>
 #include <linux/rbtree.h>
+#include <net/netlink.h>
+#include <net/pkt_sched.h>
 
 /* HTB algorithm.
     Author: devik@cdi.cz
@@ -69,8 +53,6 @@
 */
 
 #define HTB_HSIZE 16		/* classid hash size */
-#define HTB_EWMAC 2		/* rate average over HTB_EWMAC*HTB_HSIZE sec */
-#define HTB_RATECM 1		/* whether to use rate computer */
 #define HTB_HYSTERESIS 1	/* whether to use mode hysteresis for speedup */
 #define HTB_VER 0x30011		/* major must be matched with number suplied by TC as version */
 
@@ -95,12 +77,6 @@
 	struct tc_htb_xstats xstats;	/* our special stats */
 	int refcnt;		/* usage count of this class */
 
-#ifdef HTB_RATECM
-	/* rate measurement counters */
-	unsigned long rate_bytes, sum_bytes;
-	unsigned long rate_packets, sum_packets;
-#endif
-
 	/* topology */
 	int level;		/* our level (see above) */
 	struct htb_class *parent;	/* parent class */
@@ -153,15 +129,12 @@
 				/* of un.leaf originals should be done. */
 };
 
-/* TODO: maybe compute rate when size is too large .. or drop ? */
 static inline long L2T(struct htb_class *cl, struct qdisc_rate_table *rate,
 			   int size)
 {
 	int slot = size >> rate->rate.cell_log;
-	if (slot > 255) {
-		cl->xstats.giants++;
-		slot = 255;
-	}
+	if (slot > 255)
+		return (rate->data[255]*(slot >> 8) + rate->data[slot & 0xFF]);
 	return rate->data[slot];
 }
 
@@ -194,10 +167,6 @@
 	int rate2quantum;	/* quant = rate / rate2quantum */
 	psched_time_t now;	/* cached dequeue time */
 	struct qdisc_watchdog watchdog;
-#ifdef HTB_RATECM
-	struct timer_list rttim;	/* rate computer timer */
-	int recmp_bucket;	/* which hash bucket to recompute next */
-#endif
 
 	/* non shaped skbs; let them go directly thru */
 	struct sk_buff_head direct_queue;
@@ -634,13 +603,14 @@
 		cl->qstats.drops++;
 		return NET_XMIT_DROP;
 	} else {
-		cl->bstats.packets++;
+		cl->bstats.packets +=
+			skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
 		cl->bstats.bytes += skb->len;
 		htb_activate(q, cl);
 	}
 
 	sch->q.qlen++;
-	sch->bstats.packets++;
+	sch->bstats.packets += skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
 	sch->bstats.bytes += skb->len;
 	return NET_XMIT_SUCCESS;
 }
@@ -677,34 +647,6 @@
 	return NET_XMIT_SUCCESS;
 }
 
-#ifdef HTB_RATECM
-#define RT_GEN(D,R) R+=D-(R/HTB_EWMAC);D=0
-static void htb_rate_timer(unsigned long arg)
-{
-	struct Qdisc *sch = (struct Qdisc *)arg;
-	struct htb_sched *q = qdisc_priv(sch);
-	struct hlist_node *p;
-	struct htb_class *cl;
-
-
-	/* lock queue so that we can muck with it */
-	spin_lock_bh(&sch->dev->queue_lock);
-
-	q->rttim.expires = jiffies + HZ;
-	add_timer(&q->rttim);
-
-	/* scan and recompute one bucket at time */
-	if (++q->recmp_bucket >= HTB_HSIZE)
-		q->recmp_bucket = 0;
-
-	hlist_for_each_entry(cl,p, q->hash + q->recmp_bucket, hlist) {
-		RT_GEN(cl->sum_bytes, cl->rate_bytes);
-		RT_GEN(cl->sum_packets, cl->rate_packets);
-	}
-	spin_unlock_bh(&sch->dev->queue_lock);
-}
-#endif
-
 /**
  * htb_charge_class - charges amount "bytes" to leaf and ancestors
  *
@@ -717,8 +659,9 @@
  * In such case we remove class from event queue first.
  */
 static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
-			     int level, int bytes)
+			     int level, struct sk_buff *skb)
 {
+	int bytes = skb->len;
 	long toks, diff;
 	enum htb_cmode old_mode;
 
@@ -750,16 +693,12 @@
 			if (cl->cmode != HTB_CAN_SEND)
 				htb_add_to_wait_tree(q, cl, diff);
 		}
-#ifdef HTB_RATECM
-		/* update rate counters */
-		cl->sum_bytes += bytes;
-		cl->sum_packets++;
-#endif
 
 		/* update byte stats except for leaves which are already updated */
 		if (cl->level) {
 			cl->bstats.bytes += bytes;
-			cl->bstats.packets++;
+			cl->bstats.packets += skb_is_gso(skb)?
+					skb_shinfo(skb)->gso_segs:1;
 		}
 		cl = cl->parent;
 	}
@@ -943,7 +882,7 @@
 		   gives us slightly better performance */
 		if (!cl->un.leaf.q->q.qlen)
 			htb_deactivate(q, cl);
-		htb_charge_class(q, cl, level, skb->len);
+		htb_charge_class(q, cl, level, skb);
 	}
 	return skb;
 }
@@ -1095,13 +1034,6 @@
 	if (q->direct_qlen < 2)	/* some devices have zero tx_queue_len */
 		q->direct_qlen = 2;
 
-#ifdef HTB_RATECM
-	init_timer(&q->rttim);
-	q->rttim.function = htb_rate_timer;
-	q->rttim.data = (unsigned long)sch;
-	q->rttim.expires = jiffies + HZ;
-	add_timer(&q->rttim);
-#endif
 	if ((q->rate2quantum = gopt->rate2quantum) < 1)
 		q->rate2quantum = 1;
 	q->defcls = gopt->defcls;
@@ -1175,11 +1107,6 @@
 {
 	struct htb_class *cl = (struct htb_class *)arg;
 
-#ifdef HTB_RATECM
-	cl->rate_est.bps = cl->rate_bytes / (HTB_EWMAC * HTB_HSIZE);
-	cl->rate_est.pps = cl->rate_packets / (HTB_EWMAC * HTB_HSIZE);
-#endif
-
 	if (!cl->level && cl->un.leaf.q)
 		cl->qstats.qlen = cl->un.leaf.q->q.qlen;
 	cl->xstats.tokens = cl->tokens;
@@ -1277,6 +1204,7 @@
 		BUG_TRAP(cl->un.leaf.q);
 		qdisc_destroy(cl->un.leaf.q);
 	}
+	gen_kill_estimator(&cl->bstats, &cl->rate_est);
 	qdisc_put_rtab(cl->rate);
 	qdisc_put_rtab(cl->ceil);
 
@@ -1305,9 +1233,6 @@
 	struct htb_sched *q = qdisc_priv(sch);
 
 	qdisc_watchdog_cancel(&q->watchdog);
-#ifdef HTB_RATECM
-	del_timer_sync(&q->rttim);
-#endif
 	/* This line used to be after htb_destroy_class call below
 	   and surprisingly it worked in 2.4. But it must precede it
 	   because filter need its target class alive to be able to call
@@ -1403,6 +1328,20 @@
 	if (!cl) {		/* new class */
 		struct Qdisc *new_q;
 		int prio;
+		struct {
+			struct rtattr		rta;
+			struct gnet_estimator	opt;
+		} est = {
+			.rta = {
+				.rta_len	= RTA_LENGTH(sizeof(est.opt)),
+				.rta_type	= TCA_RATE,
+			},
+			.opt = {
+				/* 4s interval, 16s averaging constant */
+				.interval	= 2,
+				.ewma_log	= 2,
+			},
+		};
 
 		/* check for valid classid */
 		if (!classid || TC_H_MAJ(classid ^ sch->handle)
@@ -1418,6 +1357,9 @@
 		if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL)
 			goto failure;
 
+		gen_new_estimator(&cl->bstats, &cl->rate_est,
+				  &sch->dev->queue_lock,
+				  tca[TCA_RATE-1] ? : &est.rta);
 		cl->refcnt = 1;
 		INIT_LIST_HEAD(&cl->sibling);
 		INIT_HLIST_NODE(&cl->hlist);
@@ -1469,8 +1411,13 @@
 		hlist_add_head(&cl->hlist, q->hash + htb_hash(classid));
 		list_add_tail(&cl->sibling,
 			      parent ? &parent->children : &q->root);
-	} else
+	} else {
+		if (tca[TCA_RATE-1])
+			gen_replace_estimator(&cl->bstats, &cl->rate_est,
+					      &sch->dev->queue_lock,
+					      tca[TCA_RATE-1]);
 		sch_tree_lock(sch);
+	}
 
 	/* it used to be a nasty bug here, we have to check that node
 	   is really leaf before changing cl->un.leaf ! */
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index f8b9f1c..cd0aab6 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -9,21 +9,14 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/list.h>
 #include <linux/skbuff.h>
-#include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
 #include <linux/netfilter.h>
-#include <linux/smp.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <asm/byteorder.h>
-#include <asm/uaccess.h>
-#include <linux/kmod.h>
-#include <linux/stat.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
 
 
 #undef DEBUG_INGRESS
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 5d9d8bc..9e5e87e 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -14,11 +14,9 @@
  */
 
 #include <linux/module.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 6d7542c..2d8c084 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -12,37 +12,23 @@
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
 #include <net/netlink.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 
 
 struct prio_sched_data
 {
 	int bands;
+	int curband; /* for round-robin */
 	struct tcf_proto *filter_list;
 	u8  prio2band[TC_PRIO_MAX+1];
 	struct Qdisc *queues[TCQ_PRIO_BANDS];
+	int mq;
 };
 
 
@@ -70,14 +56,17 @@
 #endif
 			if (TC_H_MAJ(band))
 				band = 0;
-			return q->queues[q->prio2band[band&TC_PRIO_MAX]];
+			band = q->prio2band[band&TC_PRIO_MAX];
+			goto out;
 		}
 		band = res.classid;
 	}
 	band = TC_H_MIN(band) - 1;
 	if (band >= q->bands)
-		return q->queues[q->prio2band[0]];
-
+		band = q->prio2band[0];
+out:
+	if (q->mq)
+		skb_set_queue_mapping(skb, band);
 	return q->queues[band];
 }
 
@@ -144,17 +133,58 @@
 	struct Qdisc *qdisc;
 
 	for (prio = 0; prio < q->bands; prio++) {
-		qdisc = q->queues[prio];
-		skb = qdisc->dequeue(qdisc);
-		if (skb) {
-			sch->q.qlen--;
-			return skb;
+		/* Check if the target subqueue is available before
+		 * pulling an skb.  This way we avoid excessive requeues
+		 * for slower queues.
+		 */
+		if (!netif_subqueue_stopped(sch->dev, (q->mq ? prio : 0))) {
+			qdisc = q->queues[prio];
+			skb = qdisc->dequeue(qdisc);
+			if (skb) {
+				sch->q.qlen--;
+				return skb;
+			}
 		}
 	}
 	return NULL;
 
 }
 
+static struct sk_buff *rr_dequeue(struct Qdisc* sch)
+{
+	struct sk_buff *skb;
+	struct prio_sched_data *q = qdisc_priv(sch);
+	struct Qdisc *qdisc;
+	int bandcount;
+
+	/* Only take one pass through the queues.  If nothing is available,
+	 * return nothing.
+	 */
+	for (bandcount = 0; bandcount < q->bands; bandcount++) {
+		/* Check if the target subqueue is available before
+		 * pulling an skb.  This way we avoid excessive requeues
+		 * for slower queues.  If the queue is stopped, try the
+		 * next queue.
+		 */
+		if (!netif_subqueue_stopped(sch->dev,
+					    (q->mq ? q->curband : 0))) {
+			qdisc = q->queues[q->curband];
+			skb = qdisc->dequeue(qdisc);
+			if (skb) {
+				sch->q.qlen--;
+				q->curband++;
+				if (q->curband >= q->bands)
+					q->curband = 0;
+				return skb;
+			}
+		}
+		q->curband++;
+		if (q->curband >= q->bands)
+			q->curband = 0;
+	}
+	return NULL;
+}
+
 static unsigned int prio_drop(struct Qdisc* sch)
 {
 	struct prio_sched_data *q = qdisc_priv(sch);
@@ -198,21 +228,41 @@
 static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
 {
 	struct prio_sched_data *q = qdisc_priv(sch);
-	struct tc_prio_qopt *qopt = RTA_DATA(opt);
+	struct tc_prio_qopt *qopt;
+	struct rtattr *tb[TCA_PRIO_MAX];
 	int i;
 
-	if (opt->rta_len < RTA_LENGTH(sizeof(*qopt)))
+	if (rtattr_parse_nested_compat(tb, TCA_PRIO_MAX, opt, qopt,
+				       sizeof(*qopt)))
 		return -EINVAL;
-	if (qopt->bands > TCQ_PRIO_BANDS || qopt->bands < 2)
+	q->bands = qopt->bands;
+	/* If we're multiqueue, make sure the number of incoming bands
+	 * matches the number of queues on the device we're associating with.
+	 * If the number of bands requested is zero, then set q->bands to
+	 * dev->egress_subqueue_count.
+	 */
+	q->mq = RTA_GET_FLAG(tb[TCA_PRIO_MQ - 1]);
+	if (q->mq) {
+		if (sch->handle != TC_H_ROOT)
+			return -EINVAL;
+		if (netif_is_multiqueue(sch->dev)) {
+			if (q->bands == 0)
+				q->bands = sch->dev->egress_subqueue_count;
+			else if (q->bands != sch->dev->egress_subqueue_count)
+				return -EINVAL;
+		} else
+			return -EOPNOTSUPP;
+	}
+
+	if (q->bands > TCQ_PRIO_BANDS || q->bands < 2)
 		return -EINVAL;
 
 	for (i=0; i<=TC_PRIO_MAX; i++) {
-		if (qopt->priomap[i] >= qopt->bands)
+		if (qopt->priomap[i] >= q->bands)
 			return -EINVAL;
 	}
 
 	sch_tree_lock(sch);
-	q->bands = qopt->bands;
 	memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1);
 
 	for (i=q->bands; i<TCQ_PRIO_BANDS; i++) {
@@ -268,11 +318,17 @@
 {
 	struct prio_sched_data *q = qdisc_priv(sch);
 	unsigned char *b = skb_tail_pointer(skb);
+	struct rtattr *nest;
 	struct tc_prio_qopt opt;
 
 	opt.bands = q->bands;
 	memcpy(&opt.priomap, q->prio2band, TC_PRIO_MAX+1);
-	RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+
+	nest = RTA_NEST_COMPAT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+	if (q->mq)
+		RTA_PUT_FLAG(skb, TCA_PRIO_MQ);
+	RTA_NEST_COMPAT_END(skb, nest);
+
 	return skb->len;
 
 rtattr_failure:
@@ -443,17 +499,44 @@
 	.owner		=	THIS_MODULE,
 };
 
+static struct Qdisc_ops rr_qdisc_ops = {
+	.next		=	NULL,
+	.cl_ops		=	&prio_class_ops,
+	.id		=	"rr",
+	.priv_size	=	sizeof(struct prio_sched_data),
+	.enqueue	=	prio_enqueue,
+	.dequeue	=	rr_dequeue,
+	.requeue	=	prio_requeue,
+	.drop		=	prio_drop,
+	.init		=	prio_init,
+	.reset		=	prio_reset,
+	.destroy	=	prio_destroy,
+	.change		=	prio_tune,
+	.dump		=	prio_dump,
+	.owner		=	THIS_MODULE,
+};
+
 static int __init prio_module_init(void)
 {
-	return register_qdisc(&prio_qdisc_ops);
+	int err;
+
+	err = register_qdisc(&prio_qdisc_ops);
+	if (err < 0)
+		return err;
+	err = register_qdisc(&rr_qdisc_ops);
+	if (err < 0)
+		unregister_qdisc(&prio_qdisc_ops);
+	return err;
 }
 
 static void __exit prio_module_exit(void)
 {
 	unregister_qdisc(&prio_qdisc_ops);
+	unregister_qdisc(&rr_qdisc_ops);
 }
 
 module_init(prio_module_init)
 module_exit(prio_module_exit)
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("sch_rr");
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 00db53e..9b95fef 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -17,7 +17,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/pkt_sched.h>
 #include <net/inet_ecn.h>
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 96dfdf7..9579573 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -10,31 +10,17 @@
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/jiffies.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
 #include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
 #include <linux/init.h>
+#include <linux/ipv6.h>
+#include <linux/skbuff.h>
 #include <net/ip.h>
 #include <net/netlink.h>
-#include <linux/ipv6.h>
-#include <net/route.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 
 
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 5386295..22e431d 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -13,29 +13,12 @@
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/jiffies.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/netlink.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
+#include <net/netlink.h>
 #include <net/pkt_sched.h>
 
 
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index f05ad9a..0968184 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -9,30 +9,17 @@
  */
 
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
 #include <linux/if_arp.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
 #include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
 #include <linux/init.h>
-#include <net/ip.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
 #include <linux/moduleparam.h>
-#include <net/sock.h>
+#include <net/dst.h>
+#include <net/neighbour.h>
 #include <net/pkt_sched.h>
 
 /*
@@ -225,7 +212,6 @@
 	return 0;
 }
 
-/* "teql*" netdevice routines */
 
 static int
 __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev)
@@ -277,6 +263,7 @@
 	int busy;
 	int nores;
 	int len = skb->len;
+	int subq = skb->queue_mapping;
 	struct sk_buff *skb_res = NULL;
 
 	start = master->slaves;
@@ -293,7 +280,9 @@
 
 		if (slave->qdisc_sleeping != q)
 			continue;
-		if (netif_queue_stopped(slave) || ! netif_running(slave)) {
+		if (netif_queue_stopped(slave) ||
+		    netif_subqueue_stopped(slave, subq) ||
+		    !netif_running(slave)) {
 			busy = 1;
 			continue;
 		}
@@ -302,6 +291,7 @@
 		case 0:
 			if (netif_tx_trylock(slave)) {
 				if (!netif_queue_stopped(slave) &&
+				    !netif_subqueue_stopped(slave, subq) &&
 				    slave->hard_start_xmit(skb, slave) == 0) {
 					netif_tx_unlock(slave);
 					master->slaves = NEXT_SLAVE(q);
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index 2f12bf2..e4cd841 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -250,7 +250,7 @@
 	return 0;
 }
 
-static struct seq_operations sctp_eps_ops = {
+static const struct seq_operations sctp_eps_ops = {
 	.start = sctp_eps_seq_start,
 	.next  = sctp_eps_seq_next,
 	.stop  = sctp_eps_seq_stop,
@@ -361,7 +361,7 @@
 	return 0;
 }
 
-static struct seq_operations sctp_assoc_ops = {
+static const struct seq_operations sctp_assoc_ops = {
 	.start = sctp_assocs_seq_start,
 	.next  = sctp_assocs_seq_next,
 	.stop  = sctp_assocs_seq_stop,
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 543b085..01c3c41 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -1210,7 +1210,7 @@
 	return cd->cache_show(m, cd, cp);
 }
 
-static struct seq_operations cache_content_op = {
+static const struct seq_operations cache_content_op = {
 	.start	= c_start,
 	.next	= c_next,
 	.stop	= c_stop,
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 77d2d9c..711ca4b 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -1,8 +1,8 @@
 /*
  * net/tipc/eth_media.c: Ethernet bearer support for TIPC
  *
- * Copyright (c) 2001-2006, Ericsson AB
- * Copyright (c) 2005-2006, Wind River Systems
+ * Copyright (c) 2001-2007, Ericsson AB
+ * Copyright (c) 2005-2007, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -87,6 +87,9 @@
 /**
  * recv_msg - handle incoming TIPC message from an Ethernet interface
  *
+ * Accept only packets explicitly sent to this node, or broadcast packets;
+ * ignores packets sent using Ethernet multicast, and traffic sent to other
+ * nodes (which can happen if interface is running in promiscuous mode).
  * Routine truncates any Ethernet padding/CRC appended to the message,
  * and ensures message size matches actual length
  */
@@ -98,9 +101,7 @@
 	u32 size;
 
 	if (likely(eb_ptr->bearer)) {
-	       if (likely(!dev->promiscuity) ||
-		   !memcmp(skb_mac_header(buf), dev->dev_addr, ETH_ALEN) ||
-		   !memcmp(skb_mac_header(buf), dev->broadcast, ETH_ALEN)) {
+		if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
 			size = msg_size((struct tipc_msg *)buf->data);
 			skb_trim(buf, size);
 			if (likely(buf->len == size)) {
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 2124f32..5adfdfd 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1,8 +1,8 @@
 /*
  * net/tipc/link.c: TIPC link code
  *
- * Copyright (c) 1996-2006, Ericsson AB
- * Copyright (c) 2004-2006, Wind River Systems
+ * Copyright (c) 1996-2007, Ericsson AB
+ * Copyright (c) 2004-2007, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -1260,7 +1260,7 @@
 	 * (Must not hold any locks while building message.)
 	 */
 
-	res = msg_build(hdr, msg_sect, num_sect, sender->max_pkt,
+	res = msg_build(hdr, msg_sect, num_sect, sender->publ.max_pkt,
 			!sender->user_port, &buf);
 
 	read_lock_bh(&tipc_net_lock);
@@ -1271,7 +1271,7 @@
 		if (likely(l_ptr)) {
 			if (likely(buf)) {
 				res = link_send_buf_fast(l_ptr, buf,
-							 &sender->max_pkt);
+							 &sender->publ.max_pkt);
 				if (unlikely(res < 0))
 					buf_discard(buf);
 exit:
@@ -1299,12 +1299,12 @@
 			 * then re-try fast path or fragment the message
 			 */
 
-			sender->max_pkt = link_max_pkt(l_ptr);
+			sender->publ.max_pkt = link_max_pkt(l_ptr);
 			tipc_node_unlock(node);
 			read_unlock_bh(&tipc_net_lock);
 
 
-			if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
+			if ((msg_hdr_sz(hdr) + res) <= sender->publ.max_pkt)
 				goto again;
 
 			return link_send_sections_long(sender, msg_sect,
@@ -1357,7 +1357,7 @@
 
 again:
 	fragm_no = 1;
-	max_pkt = sender->max_pkt - INT_H_SIZE;
+	max_pkt = sender->publ.max_pkt - INT_H_SIZE;
 		/* leave room for tunnel header in case of link changeover */
 	fragm_sz = max_pkt - INT_H_SIZE;
 		/* leave room for fragmentation header in each fragment */
@@ -1463,7 +1463,7 @@
 			goto reject;
 		}
 		if (link_max_pkt(l_ptr) < max_pkt) {
-			sender->max_pkt = link_max_pkt(l_ptr);
+			sender->publ.max_pkt = link_max_pkt(l_ptr);
 			tipc_node_unlock(node);
 			for (; buf_chain; buf_chain = buf) {
 				buf = buf_chain->next;
diff --git a/net/tipc/port.c b/net/tipc/port.c
index bcd5da0..5d2b9ce 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -1,8 +1,8 @@
 /*
  * net/tipc/port.c: TIPC port code
  *
- * Copyright (c) 1992-2006, Ericsson AB
- * Copyright (c) 2004-2005, Wind River Systems
+ * Copyright (c) 1992-2007, Ericsson AB
+ * Copyright (c) 2004-2007, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -239,6 +239,8 @@
 	}
 
 	tipc_port_lock(ref);
+	p_ptr->publ.usr_handle = usr_handle;
+	p_ptr->publ.max_pkt = MAX_PKT_DEFAULT;
 	p_ptr->publ.ref = ref;
 	msg = &p_ptr->publ.phdr;
 	msg_init(msg, DATA_LOW, TIPC_NAMED_MSG, TIPC_OK, LONG_H_SIZE, 0);
@@ -248,11 +250,9 @@
 	msg_set_importance(msg,importance);
 	p_ptr->last_in_seqno = 41;
 	p_ptr->sent = 1;
-	p_ptr->publ.usr_handle = usr_handle;
 	INIT_LIST_HEAD(&p_ptr->wait_list);
 	INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
 	p_ptr->congested_link = NULL;
-	p_ptr->max_pkt = MAX_PKT_DEFAULT;
 	p_ptr->dispatcher = dispatcher;
 	p_ptr->wakeup = wakeup;
 	p_ptr->user_port = NULL;
@@ -1243,7 +1243,7 @@
 	res = TIPC_OK;
 exit:
 	tipc_port_unlock(p_ptr);
-	p_ptr->max_pkt = tipc_link_get_max_pkt(peer->node, ref);
+	p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref);
 	return res;
 }
 
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 7ef4d64..e5f8c16 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -1,8 +1,8 @@
 /*
  * net/tipc/port.h: Include file for TIPC port code
  *
- * Copyright (c) 1994-2006, Ericsson AB
- * Copyright (c) 2004-2005, Wind River Systems
+ * Copyright (c) 1994-2007, Ericsson AB
+ * Copyright (c) 2004-2007, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -81,7 +81,6 @@
  * @acked:
  * @publications: list of publications for port
  * @pub_count: total # of publications port has made during its lifetime
- * @max_pkt: maximum packet size "hint" used when building messages sent by port
  * @probing_state:
  * @probing_interval:
  * @last_in_seqno:
@@ -102,7 +101,6 @@
 	u32 acked;
 	struct list_head publications;
 	u32 pub_count;
-	u32 max_pkt;
 	u32 probing_state;
 	u32 probing_interval;
 	u32 last_in_seqno;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 45832fb..4a8f37f 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1,8 +1,8 @@
 /*
  * net/tipc/socket.c: TIPC socket API
  *
- * Copyright (c) 2001-2006, Ericsson AB
- * Copyright (c) 2004-2006, Wind River Systems
+ * Copyright (c) 2001-2007, Ericsson AB
+ * Copyright (c) 2004-2007, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -607,23 +607,24 @@
 static int send_stream(struct kiocb *iocb, struct socket *sock,
 		       struct msghdr *m, size_t total_len)
 {
+	struct tipc_port *tport;
 	struct msghdr my_msg;
 	struct iovec my_iov;
 	struct iovec *curr_iov;
 	int curr_iovlen;
 	char __user *curr_start;
+	u32 hdr_size;
 	int curr_left;
 	int bytes_to_send;
 	int bytes_sent;
 	int res;
 
-	if (likely(total_len <= TIPC_MAX_USER_MSG_SIZE))
-		return send_packet(iocb, sock, m, total_len);
-
-	/* Can only send large data streams if already connected */
+	/* Handle special cases where there is no connection */
 
 	if (unlikely(sock->state != SS_CONNECTED)) {
-		if (sock->state == SS_DISCONNECTING)
+		if (sock->state == SS_UNCONNECTED)
+			return send_packet(iocb, sock, m, total_len);
+		else if (sock->state == SS_DISCONNECTING)
 			return -EPIPE;
 		else
 			return -ENOTCONN;
@@ -648,17 +649,25 @@
 	my_msg.msg_name = NULL;
 	bytes_sent = 0;
 
+	tport = tipc_sk(sock->sk)->p;
+	hdr_size = msg_hdr_sz(&tport->phdr);
+
 	while (curr_iovlen--) {
 		curr_start = curr_iov->iov_base;
 		curr_left = curr_iov->iov_len;
 
 		while (curr_left) {
-			bytes_to_send = (curr_left < TIPC_MAX_USER_MSG_SIZE)
-				? curr_left : TIPC_MAX_USER_MSG_SIZE;
+			bytes_to_send = tport->max_pkt - hdr_size;
+			if (bytes_to_send > TIPC_MAX_USER_MSG_SIZE)
+				bytes_to_send = TIPC_MAX_USER_MSG_SIZE;
+			if (curr_left < bytes_to_send)
+				bytes_to_send = curr_left;
 			my_iov.iov_base = curr_start;
 			my_iov.iov_len = bytes_to_send;
 			if ((res = send_packet(iocb, sock, &my_msg, 0)) < 0) {
-				return bytes_sent ? bytes_sent : res;
+				if (bytes_sent != 0)
+					res = bytes_sent;
+				return res;
 			}
 			curr_left -= bytes_to_send;
 			curr_start += bytes_to_send;
@@ -1600,33 +1609,6 @@
 }
 
 /**
- * Placeholders for non-implemented functionality
- *
- * Returns error code (POSIX-compliant where defined)
- */
-
-static int ioctl(struct socket *s, u32 cmd, unsigned long arg)
-{
-	return -EINVAL;
-}
-
-static int no_mmap(struct file *file, struct socket *sock,
-		   struct vm_area_struct *vma)
-{
-	return -EINVAL;
-}
-static ssize_t no_sendpage(struct socket *sock, struct page *page,
-			   int offset, size_t size, int flags)
-{
-	return -EINVAL;
-}
-
-static int no_skpair(struct socket *s1, struct socket *s2)
-{
-	return -EOPNOTSUPP;
-}
-
-/**
  * Protocol switches for the various types of TIPC sockets
  */
 
@@ -1636,19 +1618,19 @@
 	.release	= release,
 	.bind		= bind,
 	.connect	= connect,
-	.socketpair	= no_skpair,
+	.socketpair	= sock_no_socketpair,
 	.accept		= accept,
 	.getname	= get_name,
 	.poll		= poll,
-	.ioctl		= ioctl,
+	.ioctl		= sock_no_ioctl,
 	.listen		= listen,
 	.shutdown	= shutdown,
 	.setsockopt	= setsockopt,
 	.getsockopt	= getsockopt,
 	.sendmsg	= send_msg,
 	.recvmsg	= recv_msg,
-	.mmap		= no_mmap,
-	.sendpage	= no_sendpage
+        .mmap		= sock_no_mmap,
+        .sendpage	= sock_no_sendpage
 };
 
 static struct proto_ops packet_ops = {
@@ -1657,19 +1639,19 @@
 	.release	= release,
 	.bind		= bind,
 	.connect	= connect,
-	.socketpair	= no_skpair,
+	.socketpair	= sock_no_socketpair,
 	.accept		= accept,
 	.getname	= get_name,
 	.poll		= poll,
-	.ioctl		= ioctl,
+	.ioctl		= sock_no_ioctl,
 	.listen		= listen,
 	.shutdown	= shutdown,
 	.setsockopt	= setsockopt,
 	.getsockopt	= getsockopt,
 	.sendmsg	= send_packet,
 	.recvmsg	= recv_msg,
-	.mmap		= no_mmap,
-	.sendpage	= no_sendpage
+        .mmap		= sock_no_mmap,
+        .sendpage	= sock_no_sendpage
 };
 
 static struct proto_ops stream_ops = {
@@ -1678,19 +1660,19 @@
 	.release	= release,
 	.bind		= bind,
 	.connect	= connect,
-	.socketpair	= no_skpair,
+	.socketpair	= sock_no_socketpair,
 	.accept		= accept,
 	.getname	= get_name,
 	.poll		= poll,
-	.ioctl		= ioctl,
+	.ioctl		= sock_no_ioctl,
 	.listen		= listen,
 	.shutdown	= shutdown,
 	.setsockopt	= setsockopt,
 	.getsockopt	= getsockopt,
 	.sendmsg	= send_stream,
 	.recvmsg	= recv_stream,
-	.mmap		= no_mmap,
-	.sendpage	= no_sendpage
+        .mmap		= sock_no_mmap,
+        .sendpage	= sock_no_sendpage
 };
 
 static struct net_proto_family tipc_family_ops = {
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index d70fa30..65ebccc 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -592,7 +592,8 @@
 	u->dentry = NULL;
 	u->mnt	  = NULL;
 	spin_lock_init(&u->lock);
-	atomic_set(&u->inflight, sock ? 0 : -1);
+	atomic_set(&u->inflight, 0);
+	INIT_LIST_HEAD(&u->link);
 	mutex_init(&u->readlock); /* single task reading lock */
 	init_waitqueue_head(&u->peer_wait);
 	unix_insert_socket(unix_sockets_unbound, sk);
@@ -1134,9 +1135,6 @@
 	/* take ten and and send info to listening sock */
 	spin_lock(&other->sk_receive_queue.lock);
 	__skb_queue_tail(&other->sk_receive_queue, skb);
-	/* Undo artificially decreased inflight after embrion
-	 * is installed to listening socket. */
-	atomic_inc(&newu->inflight);
 	spin_unlock(&other->sk_receive_queue.lock);
 	unix_state_unlock(other);
 	other->sk_data_ready(other, 0);
@@ -2048,7 +2046,7 @@
 	return 0;
 }
 
-static struct seq_operations unix_seq_ops = {
+static const struct seq_operations unix_seq_ops = {
 	.start  = unix_seq_start,
 	.next   = unix_seq_next,
 	.stop   = unix_seq_stop,
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index f20b7ea..406b643 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -62,6 +62,10 @@
  *	AV		1 Mar 1999
  *		Damn. Added missing check for ->dead in listen queues scanning.
  *
+ *	Miklos Szeredi 25 Jun 2007
+ *		Reimplement with a cycle collecting algorithm. This should
+ *		solve several problems with the previous code, like being racy
+ *		wrt receive and holding up unrelated socket operations.
  */
 
 #include <linux/kernel.h>
@@ -84,10 +88,9 @@
 
 /* Internal data structures and random procedures: */
 
-#define GC_HEAD		((struct sock *)(-1))
-#define GC_ORPHAN	((struct sock *)(-3))
-
-static struct sock *gc_current = GC_HEAD; /* stack of objects to mark */
+static LIST_HEAD(gc_inflight_list);
+static LIST_HEAD(gc_candidates);
+static DEFINE_SPINLOCK(unix_gc_lock);
 
 atomic_t unix_tot_inflight = ATOMIC_INIT(0);
 
@@ -122,8 +125,16 @@
 {
 	struct sock *s = unix_get_socket(fp);
 	if(s) {
-		atomic_inc(&unix_sk(s)->inflight);
+		struct unix_sock *u = unix_sk(s);
+		spin_lock(&unix_gc_lock);
+		if (atomic_inc_return(&u->inflight) == 1) {
+			BUG_ON(!list_empty(&u->link));
+			list_add_tail(&u->link, &gc_inflight_list);
+		} else {
+			BUG_ON(list_empty(&u->link));
+		}
 		atomic_inc(&unix_tot_inflight);
+		spin_unlock(&unix_gc_lock);
 	}
 }
 
@@ -131,182 +142,218 @@
 {
 	struct sock *s = unix_get_socket(fp);
 	if(s) {
-		atomic_dec(&unix_sk(s)->inflight);
+		struct unix_sock *u = unix_sk(s);
+		spin_lock(&unix_gc_lock);
+		BUG_ON(list_empty(&u->link));
+		if (atomic_dec_and_test(&u->inflight))
+			list_del_init(&u->link);
 		atomic_dec(&unix_tot_inflight);
+		spin_unlock(&unix_gc_lock);
 	}
 }
 
-
-/*
- *	Garbage Collector Support Functions
- */
-
-static inline struct sock *pop_stack(void)
+static inline struct sk_buff *sock_queue_head(struct sock *sk)
 {
-	struct sock *p = gc_current;
-	gc_current = unix_sk(p)->gc_tree;
-	return p;
+	return (struct sk_buff *) &sk->sk_receive_queue;
 }
 
-static inline int empty_stack(void)
+#define receive_queue_for_each_skb(sk, next, skb) \
+	for (skb = sock_queue_head(sk)->next, next = skb->next; \
+	     skb != sock_queue_head(sk); skb = next, next = skb->next)
+
+static void scan_inflight(struct sock *x, void (*func)(struct sock *),
+			  struct sk_buff_head *hitlist)
 {
-	return gc_current == GC_HEAD;
+	struct sk_buff *skb;
+	struct sk_buff *next;
+
+	spin_lock(&x->sk_receive_queue.lock);
+	receive_queue_for_each_skb(x, next, skb) {
+		/*
+		 *	Do we have file descriptors ?
+		 */
+		if (UNIXCB(skb).fp) {
+			bool hit = false;
+			/*
+			 *	Process the descriptors of this socket
+			 */
+			int nfd = UNIXCB(skb).fp->count;
+			struct file **fp = UNIXCB(skb).fp->fp;
+			while (nfd--) {
+				/*
+				 *	Get the socket the fd matches
+				 *	if it indeed does so
+				 */
+				struct sock *sk = unix_get_socket(*fp++);
+				if(sk) {
+					hit = true;
+					func(sk);
+				}
+			}
+			if (hit && hitlist != NULL) {
+				__skb_unlink(skb, &x->sk_receive_queue);
+				__skb_queue_tail(hitlist, skb);
+			}
+		}
+	}
+	spin_unlock(&x->sk_receive_queue.lock);
 }
 
-static void maybe_unmark_and_push(struct sock *x)
+static void scan_children(struct sock *x, void (*func)(struct sock *),
+			  struct sk_buff_head *hitlist)
 {
-	struct unix_sock *u = unix_sk(x);
+	if (x->sk_state != TCP_LISTEN)
+		scan_inflight(x, func, hitlist);
+	else {
+		struct sk_buff *skb;
+		struct sk_buff *next;
+		struct unix_sock *u;
+		LIST_HEAD(embryos);
 
-	if (u->gc_tree != GC_ORPHAN)
-		return;
-	sock_hold(x);
-	u->gc_tree = gc_current;
-	gc_current = x;
+		/*
+		 * For a listening socket collect the queued embryos
+		 * and perform a scan on them as well.
+		 */
+		spin_lock(&x->sk_receive_queue.lock);
+		receive_queue_for_each_skb(x, next, skb) {
+			u = unix_sk(skb->sk);
+
+			/*
+			 * An embryo cannot be in-flight, so it's safe
+			 * to use the list link.
+			 */
+			BUG_ON(!list_empty(&u->link));
+			list_add_tail(&u->link, &embryos);
+		}
+		spin_unlock(&x->sk_receive_queue.lock);
+
+		while (!list_empty(&embryos)) {
+			u = list_entry(embryos.next, struct unix_sock, link);
+			scan_inflight(&u->sk, func, hitlist);
+			list_del_init(&u->link);
+		}
+	}
 }
 
+static void dec_inflight(struct sock *sk)
+{
+	atomic_dec(&unix_sk(sk)->inflight);
+}
+
+static void inc_inflight(struct sock *sk)
+{
+	atomic_inc(&unix_sk(sk)->inflight);
+}
+
+static void inc_inflight_move_tail(struct sock *sk)
+{
+	struct unix_sock *u = unix_sk(sk);
+
+	atomic_inc(&u->inflight);
+	/*
+	 * If this is still a candidate, move it to the end of the
+	 * list, so that it's checked even if it was already passed
+	 * over
+	 */
+	if (u->gc_candidate)
+		list_move_tail(&u->link, &gc_candidates);
+}
 
 /* The external entry point: unix_gc() */
 
 void unix_gc(void)
 {
-	static DEFINE_MUTEX(unix_gc_sem);
-	int i;
-	struct sock *s;
+	static bool gc_in_progress = false;
+
+	struct unix_sock *u;
+	struct unix_sock *next;
 	struct sk_buff_head hitlist;
-	struct sk_buff *skb;
+	struct list_head cursor;
 
+	spin_lock(&unix_gc_lock);
+
+	/* Avoid a recursive GC. */
+	if (gc_in_progress)
+		goto out;
+
+	gc_in_progress = true;
 	/*
-	 *	Avoid a recursive GC.
+	 * First, select candidates for garbage collection.  Only
+	 * in-flight sockets are considered, and from those only ones
+	 * which don't have any external reference.
+	 *
+	 * Holding unix_gc_lock will protect these candidates from
+	 * being detached, and hence from gaining an external
+	 * reference.  This also means, that since there are no
+	 * possible receivers, the receive queues of these sockets are
+	 * static during the GC, even though the dequeue is done
+	 * before the detach without atomicity guarantees.
 	 */
+	list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
+		int total_refs;
+		int inflight_refs;
 
-	if (!mutex_trylock(&unix_gc_sem))
-		return;
+		total_refs = file_count(u->sk.sk_socket->file);
+		inflight_refs = atomic_read(&u->inflight);
 
-	spin_lock(&unix_table_lock);
-
-	forall_unix_sockets(i, s)
-	{
-		unix_sk(s)->gc_tree = GC_ORPHAN;
-	}
-	/*
-	 *	Everything is now marked
-	 */
-
-	/* Invariant to be maintained:
-		- everything unmarked is either:
-		-- (a) on the stack, or
-		-- (b) has all of its children unmarked
-		- everything on the stack is always unmarked
-		- nothing is ever pushed onto the stack twice, because:
-		-- nothing previously unmarked is ever pushed on the stack
-	 */
-
-	/*
-	 *	Push root set
-	 */
-
-	forall_unix_sockets(i, s)
-	{
-		int open_count = 0;
-
-		/*
-		 *	If all instances of the descriptor are not
-		 *	in flight we are in use.
-		 *
-		 *	Special case: when socket s is embrion, it may be
-		 *	hashed but still not in queue of listening socket.
-		 *	In this case (see unix_create1()) we set artificial
-		 *	negative inflight counter to close race window.
-		 *	It is trick of course and dirty one.
-		 */
-		if (s->sk_socket && s->sk_socket->file)
-			open_count = file_count(s->sk_socket->file);
-		if (open_count > atomic_read(&unix_sk(s)->inflight))
-			maybe_unmark_and_push(s);
-	}
-
-	/*
-	 *	Mark phase
-	 */
-
-	while (!empty_stack())
-	{
-		struct sock *x = pop_stack();
-		struct sock *sk;
-
-		spin_lock(&x->sk_receive_queue.lock);
-		skb = skb_peek(&x->sk_receive_queue);
-
-		/*
-		 *	Loop through all but first born
-		 */
-
-		while (skb && skb != (struct sk_buff *)&x->sk_receive_queue) {
-			/*
-			 *	Do we have file descriptors ?
-			 */
-			if(UNIXCB(skb).fp)
-			{
-				/*
-				 *	Process the descriptors of this socket
-				 */
-				int nfd=UNIXCB(skb).fp->count;
-				struct file **fp = UNIXCB(skb).fp->fp;
-				while(nfd--)
-				{
-					/*
-					 *	Get the socket the fd matches if
-					 *	it indeed does so
-					 */
-					if((sk=unix_get_socket(*fp++))!=NULL)
-					{
-						maybe_unmark_and_push(sk);
-					}
-				}
-			}
-			/* We have to scan not-yet-accepted ones too */
-			if (x->sk_state == TCP_LISTEN)
-				maybe_unmark_and_push(skb->sk);
-			skb=skb->next;
+		BUG_ON(inflight_refs < 1);
+		BUG_ON(total_refs < inflight_refs);
+		if (total_refs == inflight_refs) {
+			list_move_tail(&u->link, &gc_candidates);
+			u->gc_candidate = 1;
 		}
-		spin_unlock(&x->sk_receive_queue.lock);
-		sock_put(x);
 	}
 
+	/*
+	 * Now remove all internal in-flight reference to children of
+	 * the candidates.
+	 */
+	list_for_each_entry(u, &gc_candidates, link)
+		scan_children(&u->sk, dec_inflight, NULL);
+
+	/*
+	 * Restore the references for children of all candidates,
+	 * which have remaining references.  Do this recursively, so
+	 * only those remain, which form cyclic references.
+	 *
+	 * Use a "cursor" link, to make the list traversal safe, even
+	 * though elements might be moved about.
+	 */
+	list_add(&cursor, &gc_candidates);
+	while (cursor.next != &gc_candidates) {
+		u = list_entry(cursor.next, struct unix_sock, link);
+
+		/* Move cursor to after the current position. */
+		list_move(&cursor, &u->link);
+
+		if (atomic_read(&u->inflight) > 0) {
+			list_move_tail(&u->link, &gc_inflight_list);
+			u->gc_candidate = 0;
+			scan_children(&u->sk, inc_inflight_move_tail, NULL);
+		}
+	}
+	list_del(&cursor);
+
+	/*
+	 * Now gc_candidates contains only garbage.  Restore original
+	 * inflight counters for these as well, and remove the skbuffs
+	 * which are creating the cycle(s).
+	 */
 	skb_queue_head_init(&hitlist);
+	list_for_each_entry(u, &gc_candidates, link)
+		scan_children(&u->sk, inc_inflight, &hitlist);
 
-	forall_unix_sockets(i, s)
-	{
-		struct unix_sock *u = unix_sk(s);
+	spin_unlock(&unix_gc_lock);
 
-		if (u->gc_tree == GC_ORPHAN) {
-			struct sk_buff *nextsk;
-
-			spin_lock(&s->sk_receive_queue.lock);
-			skb = skb_peek(&s->sk_receive_queue);
-			while (skb &&
-			       skb != (struct sk_buff *)&s->sk_receive_queue) {
-				nextsk = skb->next;
-				/*
-				 *	Do we have file descriptors ?
-				 */
-				if (UNIXCB(skb).fp) {
-					__skb_unlink(skb,
-						     &s->sk_receive_queue);
-					__skb_queue_tail(&hitlist, skb);
-				}
-				skb = nextsk;
-			}
-			spin_unlock(&s->sk_receive_queue.lock);
-		}
-		u->gc_tree = GC_ORPHAN;
-	}
-	spin_unlock(&unix_table_lock);
-
-	/*
-	 *	Here we are. Hitlist is filled. Die.
-	 */
-
+	/* Here we are. Hitlist is filled. Die. */
 	__skb_queue_purge(&hitlist);
-	mutex_unlock(&unix_gc_sem);
+
+	spin_lock(&unix_gc_lock);
+
+	/* All candidates should have been detached by now. */
+	BUG_ON(!list_empty(&gc_candidates));
+	gc_in_progress = false;
+
+ out:
+	spin_unlock(&unix_gc_lock);
 }
diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c
index 2051065..236e7ea 100644
--- a/net/wanrouter/wanproc.c
+++ b/net/wanrouter/wanproc.c
@@ -164,14 +164,14 @@
 	return 0;
 }
 
-static struct seq_operations config_op = {
+static const struct seq_operations config_op = {
 	.start	= r_start,
 	.next	= r_next,
 	.stop	= r_stop,
 	.show	= config_show,
 };
 
-static struct seq_operations status_op = {
+static const struct seq_operations status_op = {
 	.start	= r_start,
 	.next	= r_next,
 	.stop	= r_stop,
diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c
index 96001f0..7405b9c 100644
--- a/net/x25/x25_proc.c
+++ b/net/x25/x25_proc.c
@@ -234,21 +234,21 @@
 	return 0;
 }
 
-static struct seq_operations x25_seq_route_ops = {
+static const struct seq_operations x25_seq_route_ops = {
 	.start  = x25_seq_route_start,
 	.next   = x25_seq_route_next,
 	.stop   = x25_seq_route_stop,
 	.show   = x25_seq_route_show,
 };
 
-static struct seq_operations x25_seq_socket_ops = {
+static const struct seq_operations x25_seq_socket_ops = {
 	.start  = x25_seq_socket_start,
 	.next   = x25_seq_socket_next,
 	.stop   = x25_seq_socket_stop,
 	.show   = x25_seq_socket_show,
 };
 
-static struct seq_operations x25_seq_forward_ops = {
+static const struct seq_operations x25_seq_forward_ops = {
 	.start  = x25_seq_forward_start,
 	.next   = x25_seq_forward_next,
 	.stop   = x25_seq_forward_stop,
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index dfacb9c..e070c3f 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -686,6 +686,37 @@
 	return x;
 }
 
+struct xfrm_state *
+xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
+		    unsigned short family, u8 mode, u8 proto, u32 reqid)
+{
+	unsigned int h = xfrm_dst_hash(daddr, saddr, reqid, family);
+	struct xfrm_state *rx = NULL, *x = NULL;
+	struct hlist_node *entry;
+
+	spin_lock(&xfrm_state_lock);
+	hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
+		if (x->props.family == family &&
+		    x->props.reqid == reqid &&
+		    !(x->props.flags & XFRM_STATE_WILDRECV) &&
+		    xfrm_state_addr_check(x, daddr, saddr, family) &&
+		    mode == x->props.mode &&
+		    proto == x->id.proto &&
+		    x->km.state == XFRM_STATE_VALID) {
+			rx = x;
+			break;
+		}
+	}
+
+	if (rx)
+		xfrm_state_hold(rx);
+	spin_unlock(&xfrm_state_lock);
+
+
+	return rx;
+}
+EXPORT_SYMBOL(xfrm_stateonly_find);
+
 static void __xfrm_state_insert(struct xfrm_state *x)
 {
 	unsigned int h;