Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (39 commits)
  [SCSI] qla2xxx: Update version number to 8.02.00-k5.
  [SCSI] qla2xxx: Correct display of ISP serial-number.
  [SCSI] qla2xxx: Correct residual-count handling discrepancies during UNDERRUN handling.
  [SCSI] qla2xxx: Make driver (mostly) legacy I/O port free.
  [SCSI] qla2xxx: Fix issue where final flash-segment updates were falling into the slow-path write handler.
  [SCSI] qla2xxx: Handle unaligned sector writes during NVRAM/VPD updates.
  [SCSI] qla2xxx: Defer explicit interrupt-polling processing to init-time scenarios.
  [SCSI] qla2xxx: Resync with latest HBA SSID specification -- 2.2u.
  [SCSI] sym53c8xx: Remove sym_xpt_async_sent_bdr
  [SCSI] sym53c8xx: Remove pci_dev pointer from sym_shcb
  [SCSI] sym53c8xx: Make interrupt handler capable of returning IRQ_NONE
  [SCSI] sym53c8xx: Get rid of IRQ_FMT and IRQ_PRM
  [SCSI] sym53c8xx: Use scmd_printk where appropriate
  [SCSI] sym53c8xx: Simplify DAC DMA handling
  [SCSI] sym53c8xx: Remove tag_ctrl module parameter
  [SCSI] sym53c8xx: Remove io_ws, mmio_ws and ram_ws elements
  [SCSI] sym53c8xx: Remove ->device_id
  [SCSI] sym53c8xx: Use pdev->revision
  [SCSI] sym53c8xx: PCI Error Recovery support
  [SCSI] sym53c8xx: Stop overriding scsi_done
  ...
diff --git a/.gitignore b/.gitignore
index 22fb8fa..8d14531 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@
 *.s
 *.ko
 *.so
+*.so.dbg
 *.mod.c
 *.i
 *.lst
diff --git a/CREDITS b/CREDITS
index 99566b1..ee909f2 100644
--- a/CREDITS
+++ b/CREDITS
@@ -959,7 +959,7 @@
 S: Boulder, Colorado 80302
 S: USA
 
-N: Heiko Eissfeldt
+N: Heiko Eißfeldt
 E: heiko@colossus.escape.de heiko@unifix.de
 D: verify_area stuff, generic SCSI fixes
 D: SCSI Programming HOWTO
@@ -1988,8 +1988,8 @@
 E: vl@kki.org
 D: Kernel smbfs (to mount WfW, NT and OS/2 network drives.)
 D: NCP filesystem support (to mount NetWare volumes)
-S: Von Ossietzky Str. 12
-S: 37085 Goettingen
+S: Von-Ossietzky-Str. 12
+S: 37085 Göttingen
 S: Germany
 
 N: Kevin Lentin
@@ -2431,11 +2431,11 @@
 S: Beaverton, Oregon 97005
 S: USA
 
-N: Eberhard Moenkeberg
+N: Eberhard Mönkeberg
 E: emoenke@gwdg.de
 D: CDROM driver "sbpcd" (Matsushita/Panasonic/Soundblaster)
-S: Ruhstrathoehe 2 b.
-S: D-37085 Goettingen
+S: Ruhstrathöhe 2 b.
+S: D-37085 Göttingen
 S: Germany
 
 N: Thomas Molina
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 1a7f530..054a7ec 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -165,7 +165,7 @@
 	@touch $@
 
 ###
-# Rules to generate postscripts and PNG imgages from .fig format files
+# Rules to generate postscripts and PNG images from .fig format files
 quiet_cmd_fig2eps = FIG2EPS $@
       cmd_fig2eps = fig2dev -Leps $< $@
 
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index d3290c4..aa38cc5 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -46,7 +46,7 @@
 
      <sect1><title>Atomic and pointer manipulation</title>
 !Iinclude/asm-x86/atomic_32.h
-!Iinclude/asm-x86/unaligned_32.h
+!Iinclude/asm-x86/unaligned.h
      </sect1>
 
      <sect1><title>Delaying, scheduling, and timer routines</title>
diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl
index 6fbc41d..957cf5c 100644
--- a/Documentation/DocBook/mtdnand.tmpl
+++ b/Documentation/DocBook/mtdnand.tmpl
@@ -282,7 +282,7 @@
 		goto out;
 	}
 
-	/* map physical adress */
+	/* map physical address */
 	baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024);
 	if(!baseaddr){
 		printk("Ioremap to access NAND chip failed\n");
@@ -306,7 +306,7 @@
 	this->dev_ready = board_dev_ready;
 	this->eccmode = NAND_ECC_SOFT;
 
-	/* Scan to find existance of the device */
+	/* Scan to find existence of the device */
 	if (nand_scan (board_mtd, 1)) {
 		err = -ENXIO;
 		goto out_ior;
@@ -340,7 +340,7 @@
 	/* Release resources, unregister device */
 	nand_release (board_mtd);
 
-	/* unmap physical adress */
+	/* unmap physical address */
 	iounmap((void *)baseaddr);
 	
 	/* Free the MTD device structure */
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt
index 24dc3fc..bc38283 100644
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -441,17 +441,20 @@
 0xca2.  If you want to turn this off, set the "trydefaults" option to
 false.
 
-If you have high-res timers compiled into the kernel, the driver will
-use them to provide much better performance.  Note that if you do not
-have high-res timers enabled in the kernel and you don't have
-interrupts enabled, the driver will run VERY slowly.  Don't blame me,
+If your IPMI interface does not support interrupts and is a KCS or
+SMIC interface, the IPMI driver will start a kernel thread for the
+interface to help speed things up.  This is a low-priority kernel
+thread that constantly polls the IPMI driver while an IPMI operation
+is in progress.  The force_kipmid module parameter will all the user to
+force this thread on or off.  If you force it off and don't have
+interrupts, the driver will run VERY slowly.  Don't blame me,
 these interfaces suck.
 
 The driver supports a hot add and remove of interfaces.  This way,
 interfaces can be added or removed after the kernel is up and running.
-This is done using /sys/modules/ipmi_si/hotmod, which is a write-only
-parameter.  You write a string to this interface.  The string has the
-format:
+This is done using /sys/modules/ipmi_si/parameters/hotmod, which is a
+write-only parameter.  You write a string to this interface.  The string
+has the format:
    <op1>[:op2[:op3...]]
 The "op"s are:
    add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]]
@@ -581,9 +584,11 @@
 gets a pre-action.  During a panic or a reboot, the watchdog will
 start a 120 timer if it is running to make sure the reboot occurs.
 
-Note that if you use the NMI preaction for the watchdog, you MUST
-NOT use nmi watchdog mode 1.  If you use the NMI watchdog, you
-must use mode 2.
+Note that if you use the NMI preaction for the watchdog, you MUST NOT
+use the nmi watchdog.  There is no reasonable way to tell if an NMI
+comes from the IPMI controller, so it must assume that if it gets an
+otherwise unhandled NMI, it must be from IPMI and it will panic
+immediately.
 
 Once you open the watchdog timer, you must write a 'V' character to the
 device to close it, or the timer will not stop.  This is a new semantic
diff --git a/Documentation/Intel-IOMMU.txt b/Documentation/Intel-IOMMU.txt
new file mode 100644
index 0000000..c232190
--- /dev/null
+++ b/Documentation/Intel-IOMMU.txt
@@ -0,0 +1,115 @@
+Linux IOMMU Support
+===================
+
+The architecture spec can be obtained from the below location.
+
+http://www.intel.com/technology/virtualization/
+
+This guide gives a quick cheat sheet for some basic understanding.
+
+Some Keywords
+
+DMAR - DMA remapping
+DRHD - DMA Engine Reporting Structure
+RMRR - Reserved memory Region Reporting Structure
+ZLR  - Zero length reads from PCI devices
+IOVA - IO Virtual address.
+
+Basic stuff
+-----------
+
+ACPI enumerates and lists the different DMA engines in the platform, and
+device scope relationships between PCI devices and which DMA engine  controls
+them.
+
+What is RMRR?
+-------------
+
+There are some devices the BIOS controls, for e.g USB devices to perform
+PS2 emulation. The regions of memory used for these devices are marked
+reserved in the e820 map. When we turn on DMA translation, DMA to those
+regions will fail. Hence BIOS uses RMRR to specify these regions along with
+devices that need to access these regions. OS is expected to setup
+unity mappings for these regions for these devices to access these regions.
+
+How is IOVA generated?
+---------------------
+
+Well behaved drivers call pci_map_*() calls before sending command to device
+that needs to perform DMA. Once DMA is completed and mapping is no longer
+required, device performs a pci_unmap_*() calls to unmap the region.
+
+The Intel IOMMU driver allocates a virtual address per domain. Each PCIE
+device has its own domain (hence protection). Devices under p2p bridges
+share the virtual address with all devices under the p2p bridge due to
+transaction id aliasing for p2p bridges.
+
+IOVA generation is pretty generic. We used the same technique as vmalloc()
+but these are not global address spaces, but separate for each domain.
+Different DMA engines may support different number of domains.
+
+We also allocate gaurd pages with each mapping, so we can attempt to catch
+any overflow that might happen.
+
+
+Graphics Problems?
+------------------
+If you encounter issues with graphics devices, you can try adding
+option intel_iommu=igfx_off to turn off the integrated graphics engine.
+
+If it happens to be a PCI device included in the INCLUDE_ALL Engine,
+then try enabling CONFIG_DMAR_GFX_WA to setup a 1-1 map. We hear
+graphics drivers may be in process of using DMA api's in the near
+future and at that time this option can be yanked out.
+
+Some exceptions to IOVA
+-----------------------
+Interrupt ranges are not address translated, (0xfee00000 - 0xfeefffff).
+The same is true for peer to peer transactions. Hence we reserve the
+address from PCI MMIO ranges so they are not allocated for IOVA addresses.
+
+
+Fault reporting
+---------------
+When errors are reported, the DMA engine signals via an interrupt. The fault
+reason and device that caused it with fault reason is printed on console.
+
+See below for sample.
+
+
+Boot Message Sample
+-------------------
+
+Something like this gets printed indicating presence of DMAR tables
+in ACPI.
+
+ACPI: DMAR (v001 A M I  OEMDMAR  0x00000001 MSFT 0x00000097) @ 0x000000007f5b5ef0
+
+When DMAR is being processed and initialized by ACPI, prints DMAR locations
+and any RMRR's processed.
+
+ACPI DMAR:Host address width 36
+ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed90000
+ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed91000
+ACPI DMAR:DRHD (flags: 0x00000001)base: 0x00000000fed93000
+ACPI DMAR:RMRR base: 0x00000000000ed000 end: 0x00000000000effff
+ACPI DMAR:RMRR base: 0x000000007f600000 end: 0x000000007fffffff
+
+When DMAR is enabled for use, you will notice..
+
+PCI-DMA: Using DMAR IOMMU
+
+Fault reporting
+---------------
+
+DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
+DMAR:[fault reason 05] PTE Write access is not set
+DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
+DMAR:[fault reason 05] PTE Write access is not set
+
+TBD
+----
+
+- For compatibility testing, could use unity map domain for all devices, just
+  provide a 1-1 for all useful memory under a single domain for all devices.
+- API for paravirt ops for abstracting functionlity for VMM folks.
diff --git a/Documentation/SubmitChecklist b/Documentation/SubmitChecklist
index 19e7f65..34e06d2 100644
--- a/Documentation/SubmitChecklist
+++ b/Documentation/SubmitChecklist
@@ -67,7 +67,7 @@
 20: Check that it all passes `make headers_check'.
 
 21: Has been checked with injection of at least slab and page-allocation
-    fauilures.  See Documentation/fault-injection/.
+    failures.  See Documentation/fault-injection/.
 
     If the new code is substantial, addition of subsystem-specific fault
     injection might be appropriate.
diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers
index d7e2642..24f2eb4 100644
--- a/Documentation/SubmittingDrivers
+++ b/Documentation/SubmittingDrivers
@@ -36,8 +36,7 @@
 	If the code area has a general maintainer then please submit it to
 	the maintainer listed in MAINTAINERS in the kernel file. If the
 	maintainer does not respond or you cannot find the appropriate
-	maintainer then please contact Marcelo Tosatti
-	<marcelo.tosatti@cyclades.com>.
+	maintainer then please contact Willy Tarreau <w@1wt.eu>.
 
 Linux 2.6:
 	The same rules apply as 2.4 except that you should follow linux-kernel
diff --git a/Documentation/accounting/cgroupstats.txt b/Documentation/accounting/cgroupstats.txt
new file mode 100644
index 0000000..eda40fd
--- /dev/null
+++ b/Documentation/accounting/cgroupstats.txt
@@ -0,0 +1,27 @@
+Control Groupstats is inspired by the discussion at
+http://lkml.org/lkml/2007/4/11/187 and implements per cgroup statistics as
+suggested by Andrew Morton in http://lkml.org/lkml/2007/4/11/263.
+
+Per cgroup statistics infrastructure re-uses code from the taskstats
+interface. A new set of cgroup operations are registered with commands
+and attributes specific to cgroups. It should be very easy to
+extend per cgroup statistics, by adding members to the cgroupstats
+structure.
+
+The current model for cgroupstats is a pull, a push model (to post
+statistics on interesting events), should be very easy to add. Currently
+user space requests for statistics by passing the cgroup path.
+Statistics about the state of all the tasks in the cgroup is returned to
+user space.
+
+NOTE: We currently rely on delay accounting for extracting information
+about tasks blocked on I/O. If CONFIG_TASK_DELAY_ACCT is disabled, this
+information will not be available.
+
+To extract cgroup statistics a utility very similar to getdelays.c
+has been developed, the sample output of the utility is shown below
+
+~/balbir/cgroupstats # ./getdelays  -C "/cgroup/a"
+sleeping 1, blocked 0, running 1, stopped 0, uninterruptible 0
+~/balbir/cgroupstats # ./getdelays  -C "/cgroup"
+sleeping 155, blocked 0, running 1, stopped 0, uninterruptible 2
diff --git a/Documentation/arm/Samsung-S3C24XX/DMA.txt b/Documentation/arm/Samsung-S3C24XX/DMA.txt
index 37f4edc..3ed8238 100644
--- a/Documentation/arm/Samsung-S3C24XX/DMA.txt
+++ b/Documentation/arm/Samsung-S3C24XX/DMA.txt
@@ -5,7 +5,7 @@
 ------------
 
    The kernel provides an interface to manage DMA transfers
-   using the DMA channels in the cpu, so that the central
+   using the DMA channels in the CPU, so that the central
    duty of managing channel mappings, and programming the
    channel generators is in one place.
 
@@ -17,24 +17,24 @@
    channels to all sources, which means that some devices
    have a restricted number of channels that can be used.
 
-   To allow flexibilty for each cpu type and board, the
-   dma code can be given an dma ordering structure which
+   To allow flexibility for each CPU type and board, the
+   DMA code can be given a DMA ordering structure which
    allows the order of channel search to be specified, as
    well as allowing the prohibition of certain claims.
 
    struct s3c24xx_dma_order has a list of channels, and
-   each channel within has a slot for a list of dma
-   channel numbers. The slots are searched in order, for
-   the presence of a dma channel number with DMA_CH_VALID
-   orred in.
+   each channel within has a slot for a list of DMA
+   channel numbers. The slots are searched in order for
+   the presence of a DMA channel number with DMA_CH_VALID
+   or-ed in.
 
    If the order has the flag DMA_CH_NEVER set, then after
    checking the channel list, the system will return no
    found channel, thus denying the request.
 
    A board support file can call s3c24xx_dma_order_set()
-   to register an complete ordering set. The routine will
-   copy the data, so the original can be discared with
+   to register a complete ordering set. The routine will
+   copy the data, so the original can be discarded with
    __initdata.
 
 
diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt
index d46306f..f20c10c 100644
--- a/Documentation/atomic_ops.txt
+++ b/Documentation/atomic_ops.txt
@@ -418,6 +418,20 @@
 	 */
 	 smp_mb__after_clear_bit();
 
+There are two special bitops with lock barrier semantics (acquire/release,
+same as spinlocks). These operate in the same way as their non-_lock/unlock
+postfixed variants, except that they are to provide acquire/release semantics,
+respectively. This means they can be used for bit_spin_trylock and
+bit_spin_unlock type operations without specifying any more barriers.
+
+	int test_and_set_bit_lock(unsigned long nr, unsigned long *addr);
+	void clear_bit_unlock(unsigned long nr, unsigned long *addr);
+	void __clear_bit_unlock(unsigned long nr, unsigned long *addr);
+
+The __clear_bit_unlock version is non-atomic, however it still implements
+unlock barrier semantics. This can be useful if the lock itself is protecting
+the other bits in the word.
+
 Finally, there are non-atomic versions of the bitmask operations
 provided.  They are used in contexts where some other higher-level SMP
 locking scheme is being used to protect the bitmask, and thus less
diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt
index 552caba..da42ab4 100644
--- a/Documentation/cachetlb.txt
+++ b/Documentation/cachetlb.txt
@@ -87,30 +87,7 @@
 
 	This is used primarily during fault processing.
 
-5) void flush_tlb_pgtables(struct mm_struct *mm,
-			   unsigned long start, unsigned long end)
-
-   The software page tables for address space 'mm' for virtual
-   addresses in the range 'start' to 'end-1' are being torn down.
-
-   Some platforms cache the lowest level of the software page tables
-   in a linear virtually mapped array, to make TLB miss processing
-   more efficient.  On such platforms, since the TLB is caching the
-   software page table structure, it needs to be flushed when parts
-   of the software page table tree are unlinked/freed.
-
-   Sparc64 is one example of a platform which does this.
-
-   Usually, when munmap()'ing an area of user virtual address
-   space, the kernel leaves the page table parts around and just
-   marks the individual pte's as invalid.  However, if very large
-   portions of the address space are unmapped, the kernel frees up
-   those portions of the software page tables to prevent potential
-   excessive kernel memory usage caused by erratic mmap/mmunmap
-   sequences.  It is at these times that flush_tlb_pgtables will
-   be invoked.
-
-6) void update_mmu_cache(struct vm_area_struct *vma,
+5) void update_mmu_cache(struct vm_area_struct *vma,
 			 unsigned long address, pte_t pte)
 
 	At the end of every page fault, this routine is invoked to
@@ -123,7 +100,7 @@
 	translations for software managed TLB configurations.
 	The sparc64 port currently does this.
 
-7) void tlb_migrate_finish(struct mm_struct *mm)
+6) void tlb_migrate_finish(struct mm_struct *mm)
 
 	This interface is called at the end of an explicit
 	process migration. This interface provides a hook
diff --git a/Documentation/cdrom/cdrom-standard.tex b/Documentation/cdrom/cdrom-standard.tex
index 92f94e5..c713aeb 100644
--- a/Documentation/cdrom/cdrom-standard.tex
+++ b/Documentation/cdrom/cdrom-standard.tex
@@ -1009,7 +1009,7 @@
 \cdrom-related code in the 2.1-kernel.  Thanks to Scott Snyder and
 Gerd Knorr, who were the first to implement this interface for SCSI
 and IDE-CD drivers and added many ideas for extension of the data
-structures relative to kernel~2.0.  Further thanks to Heiko Eissfeldt,
+structures relative to kernel~2.0.  Further thanks to Heiko Ei{\sz}feldt,
 Thomas Quinot, Jon Tombs, Ken Pizzini, Eberhard M\"onkeberg and Andrew
 Kroll, the \linux\ \cdrom\ device driver developers who were kind
 enough to give suggestions and criticisms during the writing. Finally
diff --git a/Documentation/cgroups.txt b/Documentation/cgroups.txt
new file mode 100644
index 0000000..98a26f8
--- /dev/null
+++ b/Documentation/cgroups.txt
@@ -0,0 +1,545 @@
+				CGROUPS
+				-------
+
+Written by Paul Menage <menage@google.com> based on Documentation/cpusets.txt
+
+Original copyright statements from cpusets.txt:
+Portions Copyright (C) 2004 BULL SA.
+Portions Copyright (c) 2004-2006 Silicon Graphics, Inc.
+Modified by Paul Jackson <pj@sgi.com>
+Modified by Christoph Lameter <clameter@sgi.com>
+
+CONTENTS:
+=========
+
+1. Control Groups
+  1.1 What are cgroups ?
+  1.2 Why are cgroups needed ?
+  1.3 How are cgroups implemented ?
+  1.4 What does notify_on_release do ?
+  1.5 How do I use cgroups ?
+2. Usage Examples and Syntax
+  2.1 Basic Usage
+  2.2 Attaching processes
+3. Kernel API
+  3.1 Overview
+  3.2 Synchronization
+  3.3 Subsystem API
+4. Questions
+
+1. Control Groups
+==========
+
+1.1 What are cgroups ?
+----------------------
+
+Control Groups provide a mechanism for aggregating/partitioning sets of
+tasks, and all their future children, into hierarchical groups with
+specialized behaviour.
+
+Definitions:
+
+A *cgroup* associates a set of tasks with a set of parameters for one
+or more subsystems.
+
+A *subsystem* is a module that makes use of the task grouping
+facilities provided by cgroups to treat groups of tasks in
+particular ways. A subsystem is typically a "resource controller" that
+schedules a resource or applies per-cgroup limits, but it may be
+anything that wants to act on a group of processes, e.g. a
+virtualization subsystem.
+
+A *hierarchy* is a set of cgroups arranged in a tree, such that
+every task in the system is in exactly one of the cgroups in the
+hierarchy, and a set of subsystems; each subsystem has system-specific
+state attached to each cgroup in the hierarchy.  Each hierarchy has
+an instance of the cgroup virtual filesystem associated with it.
+
+At any one time there may be multiple active hierachies of task
+cgroups. Each hierarchy is a partition of all tasks in the system.
+
+User level code may create and destroy cgroups by name in an
+instance of the cgroup virtual file system, specify and query to
+which cgroup a task is assigned, and list the task pids assigned to
+a cgroup. Those creations and assignments only affect the hierarchy
+associated with that instance of the cgroup file system.
+
+On their own, the only use for cgroups is for simple job
+tracking. The intention is that other subsystems hook into the generic
+cgroup support to provide new attributes for cgroups, such as
+accounting/limiting the resources which processes in a cgroup can
+access. For example, cpusets (see Documentation/cpusets.txt) allows
+you to associate a set of CPUs and a set of memory nodes with the
+tasks in each cgroup.
+
+1.2 Why are cgroups needed ?
+----------------------------
+
+There are multiple efforts to provide process aggregations in the
+Linux kernel, mainly for resource tracking purposes. Such efforts
+include cpusets, CKRM/ResGroups, UserBeanCounters, and virtual server
+namespaces. These all require the basic notion of a
+grouping/partitioning of processes, with newly forked processes ending
+in the same group (cgroup) as their parent process.
+
+The kernel cgroup patch provides the minimum essential kernel
+mechanisms required to efficiently implement such groups. It has
+minimal impact on the system fast paths, and provides hooks for
+specific subsystems such as cpusets to provide additional behaviour as
+desired.
+
+Multiple hierarchy support is provided to allow for situations where
+the division of tasks into cgroups is distinctly different for
+different subsystems - having parallel hierarchies allows each
+hierarchy to be a natural division of tasks, without having to handle
+complex combinations of tasks that would be present if several
+unrelated subsystems needed to be forced into the same tree of
+cgroups.
+
+At one extreme, each resource controller or subsystem could be in a
+separate hierarchy; at the other extreme, all subsystems
+would be attached to the same hierarchy.
+
+As an example of a scenario (originally proposed by vatsa@in.ibm.com)
+that can benefit from multiple hierarchies, consider a large
+university server with various users - students, professors, system
+tasks etc. The resource planning for this server could be along the
+following lines:
+
+       CPU :           Top cpuset
+                       /       \
+               CPUSet1         CPUSet2
+                  |              |
+               (Profs)         (Students)
+
+               In addition (system tasks) are attached to topcpuset (so
+               that they can run anywhere) with a limit of 20%
+
+       Memory : Professors (50%), students (30%), system (20%)
+
+       Disk : Prof (50%), students (30%), system (20%)
+
+       Network : WWW browsing (20%), Network File System (60%), others (20%)
+                               / \
+                       Prof (15%) students (5%)
+
+Browsers like firefox/lynx go into the WWW network class, while (k)nfsd go
+into NFS network class.
+
+At the same time firefox/lynx will share an appropriate CPU/Memory class
+depending on who launched it (prof/student).
+
+With the ability to classify tasks differently for different resources
+(by putting those resource subsystems in different hierarchies) then
+the admin can easily set up a script which receives exec notifications
+and depending on who is launching the browser he can
+
+       # echo browser_pid > /mnt/<restype>/<userclass>/tasks
+
+With only a single hierarchy, he now would potentially have to create
+a separate cgroup for every browser launched and associate it with
+approp network and other resource class.  This may lead to
+proliferation of such cgroups.
+
+Also lets say that the administrator would like to give enhanced network
+access temporarily to a student's browser (since it is night and the user
+wants to do online gaming :)  OR give one of the students simulation
+apps enhanced CPU power,
+
+With ability to write pids directly to resource classes, its just a
+matter of :
+
+       # echo pid > /mnt/network/<new_class>/tasks
+       (after some time)
+       # echo pid > /mnt/network/<orig_class>/tasks
+
+Without this ability, he would have to split the cgroup into
+multiple separate ones and then associate the new cgroups with the
+new resource classes.
+
+
+
+1.3 How are cgroups implemented ?
+---------------------------------
+
+Control Groups extends the kernel as follows:
+
+ - Each task in the system has a reference-counted pointer to a
+   css_set.
+
+ - A css_set contains a set of reference-counted pointers to
+   cgroup_subsys_state objects, one for each cgroup subsystem
+   registered in the system. There is no direct link from a task to
+   the cgroup of which it's a member in each hierarchy, but this
+   can be determined by following pointers through the
+   cgroup_subsys_state objects. This is because accessing the
+   subsystem state is something that's expected to happen frequently
+   and in performance-critical code, whereas operations that require a
+   task's actual cgroup assignments (in particular, moving between
+   cgroups) are less common. A linked list runs through the cg_list
+   field of each task_struct using the css_set, anchored at
+   css_set->tasks.
+
+ - A cgroup hierarchy filesystem can be mounted  for browsing and
+   manipulation from user space.
+
+ - You can list all the tasks (by pid) attached to any cgroup.
+
+The implementation of cgroups requires a few, simple hooks
+into the rest of the kernel, none in performance critical paths:
+
+ - in init/main.c, to initialize the root cgroups and initial
+   css_set at system boot.
+
+ - in fork and exit, to attach and detach a task from its css_set.
+
+In addition a new file system, of type "cgroup" may be mounted, to
+enable browsing and modifying the cgroups presently known to the
+kernel.  When mounting a cgroup hierarchy, you may specify a
+comma-separated list of subsystems to mount as the filesystem mount
+options.  By default, mounting the cgroup filesystem attempts to
+mount a hierarchy containing all registered subsystems.
+
+If an active hierarchy with exactly the same set of subsystems already
+exists, it will be reused for the new mount. If no existing hierarchy
+matches, and any of the requested subsystems are in use in an existing
+hierarchy, the mount will fail with -EBUSY. Otherwise, a new hierarchy
+is activated, associated with the requested subsystems.
+
+It's not currently possible to bind a new subsystem to an active
+cgroup hierarchy, or to unbind a subsystem from an active cgroup
+hierarchy. This may be possible in future, but is fraught with nasty
+error-recovery issues.
+
+When a cgroup filesystem is unmounted, if there are any
+child cgroups created below the top-level cgroup, that hierarchy
+will remain active even though unmounted; if there are no
+child cgroups then the hierarchy will be deactivated.
+
+No new system calls are added for cgroups - all support for
+querying and modifying cgroups is via this cgroup file system.
+
+Each task under /proc has an added file named 'cgroup' displaying,
+for each active hierarchy, the subsystem names and the cgroup name
+as the path relative to the root of the cgroup file system.
+
+Each cgroup is represented by a directory in the cgroup file system
+containing the following files describing that cgroup:
+
+ - tasks: list of tasks (by pid) attached to that cgroup
+ - notify_on_release flag: run /sbin/cgroup_release_agent on exit?
+
+Other subsystems such as cpusets may add additional files in each
+cgroup dir
+
+New cgroups are created using the mkdir system call or shell
+command.  The properties of a cgroup, such as its flags, are
+modified by writing to the appropriate file in that cgroups
+directory, as listed above.
+
+The named hierarchical structure of nested cgroups allows partitioning
+a large system into nested, dynamically changeable, "soft-partitions".
+
+The attachment of each task, automatically inherited at fork by any
+children of that task, to a cgroup allows organizing the work load
+on a system into related sets of tasks.  A task may be re-attached to
+any other cgroup, if allowed by the permissions on the necessary
+cgroup file system directories.
+
+When a task is moved from one cgroup to another, it gets a new
+css_set pointer - if there's an already existing css_set with the
+desired collection of cgroups then that group is reused, else a new
+css_set is allocated. Note that the current implementation uses a
+linear search to locate an appropriate existing css_set, so isn't
+very efficient. A future version will use a hash table for better
+performance.
+
+To allow access from a cgroup to the css_sets (and hence tasks)
+that comprise it, a set of cg_cgroup_link objects form a lattice;
+each cg_cgroup_link is linked into a list of cg_cgroup_links for
+a single cgroup on its cont_link_list field, and a list of
+cg_cgroup_links for a single css_set on its cg_link_list.
+
+Thus the set of tasks in a cgroup can be listed by iterating over
+each css_set that references the cgroup, and sub-iterating over
+each css_set's task set.
+
+The use of a Linux virtual file system (vfs) to represent the
+cgroup hierarchy provides for a familiar permission and name space
+for cgroups, with a minimum of additional kernel code.
+
+1.4 What does notify_on_release do ?
+------------------------------------
+
+*** notify_on_release is disabled in the current patch set. It will be
+*** reactivated in a future patch in a less-intrusive manner
+
+If the notify_on_release flag is enabled (1) in a cgroup, then
+whenever the last task in the cgroup leaves (exits or attaches to
+some other cgroup) and the last child cgroup of that cgroup
+is removed, then the kernel runs the command specified by the contents
+of the "release_agent" file in that hierarchy's root directory,
+supplying the pathname (relative to the mount point of the cgroup
+file system) of the abandoned cgroup.  This enables automatic
+removal of abandoned cgroups.  The default value of
+notify_on_release in the root cgroup at system boot is disabled
+(0).  The default value of other cgroups at creation is the current
+value of their parents notify_on_release setting. The default value of
+a cgroup hierarchy's release_agent path is empty.
+
+1.5 How do I use cgroups ?
+--------------------------
+
+To start a new job that is to be contained within a cgroup, using
+the "cpuset" cgroup subsystem, the steps are something like:
+
+ 1) mkdir /dev/cgroup
+ 2) mount -t cgroup -ocpuset cpuset /dev/cgroup
+ 3) Create the new cgroup by doing mkdir's and write's (or echo's) in
+    the /dev/cgroup virtual file system.
+ 4) Start a task that will be the "founding father" of the new job.
+ 5) Attach that task to the new cgroup by writing its pid to the
+    /dev/cgroup tasks file for that cgroup.
+ 6) fork, exec or clone the job tasks from this founding father task.
+
+For example, the following sequence of commands will setup a cgroup
+named "Charlie", containing just CPUs 2 and 3, and Memory Node 1,
+and then start a subshell 'sh' in that cgroup:
+
+  mount -t cgroup cpuset -ocpuset /dev/cgroup
+  cd /dev/cgroup
+  mkdir Charlie
+  cd Charlie
+  /bin/echo 2-3 > cpus
+  /bin/echo 1 > mems
+  /bin/echo $$ > tasks
+  sh
+  # The subshell 'sh' is now running in cgroup Charlie
+  # The next line should display '/Charlie'
+  cat /proc/self/cgroup
+
+2. Usage Examples and Syntax
+============================
+
+2.1 Basic Usage
+---------------
+
+Creating, modifying, using the cgroups can be done through the cgroup
+virtual filesystem.
+
+To mount a cgroup hierarchy will all available subsystems, type:
+# mount -t cgroup xxx /dev/cgroup
+
+The "xxx" is not interpreted by the cgroup code, but will appear in
+/proc/mounts so may be any useful identifying string that you like.
+
+To mount a cgroup hierarchy with just the cpuset and numtasks
+subsystems, type:
+# mount -t cgroup -o cpuset,numtasks hier1 /dev/cgroup
+
+To change the set of subsystems bound to a mounted hierarchy, just
+remount with different options:
+
+# mount -o remount,cpuset,ns  /dev/cgroup
+
+Note that changing the set of subsystems is currently only supported
+when the hierarchy consists of a single (root) cgroup. Supporting
+the ability to arbitrarily bind/unbind subsystems from an existing
+cgroup hierarchy is intended to be implemented in the future.
+
+Then under /dev/cgroup you can find a tree that corresponds to the
+tree of the cgroups in the system. For instance, /dev/cgroup
+is the cgroup that holds the whole system.
+
+If you want to create a new cgroup under /dev/cgroup:
+# cd /dev/cgroup
+# mkdir my_cgroup
+
+Now you want to do something with this cgroup.
+# cd my_cgroup
+
+In this directory you can find several files:
+# ls
+notify_on_release release_agent tasks
+(plus whatever files are added by the attached subsystems)
+
+Now attach your shell to this cgroup:
+# /bin/echo $$ > tasks
+
+You can also create cgroups inside your cgroup by using mkdir in this
+directory.
+# mkdir my_sub_cs
+
+To remove a cgroup, just use rmdir:
+# rmdir my_sub_cs
+
+This will fail if the cgroup is in use (has cgroups inside, or
+has processes attached, or is held alive by other subsystem-specific
+reference).
+
+2.2 Attaching processes
+-----------------------
+
+# /bin/echo PID > tasks
+
+Note that it is PID, not PIDs. You can only attach ONE task at a time.
+If you have several tasks to attach, you have to do it one after another:
+
+# /bin/echo PID1 > tasks
+# /bin/echo PID2 > tasks
+	...
+# /bin/echo PIDn > tasks
+
+3. Kernel API
+=============
+
+3.1 Overview
+------------
+
+Each kernel subsystem that wants to hook into the generic cgroup
+system needs to create a cgroup_subsys object. This contains
+various methods, which are callbacks from the cgroup system, along
+with a subsystem id which will be assigned by the cgroup system.
+
+Other fields in the cgroup_subsys object include:
+
+- subsys_id: a unique array index for the subsystem, indicating which
+  entry in cgroup->subsys[] this subsystem should be
+  managing. Initialized by cgroup_register_subsys(); prior to this
+  it should be initialized to -1
+
+- hierarchy: an index indicating which hierarchy, if any, this
+  subsystem is currently attached to. If this is -1, then the
+  subsystem is not attached to any hierarchy, and all tasks should be
+  considered to be members of the subsystem's top_cgroup. It should
+  be initialized to -1.
+
+- name: should be initialized to a unique subsystem name prior to
+  calling cgroup_register_subsystem. Should be no longer than
+  MAX_CGROUP_TYPE_NAMELEN
+
+Each cgroup object created by the system has an array of pointers,
+indexed by subsystem id; this pointer is entirely managed by the
+subsystem; the generic cgroup code will never touch this pointer.
+
+3.2 Synchronization
+-------------------
+
+There is a global mutex, cgroup_mutex, used by the cgroup
+system. This should be taken by anything that wants to modify a
+cgroup. It may also be taken to prevent cgroups from being
+modified, but more specific locks may be more appropriate in that
+situation.
+
+See kernel/cgroup.c for more details.
+
+Subsystems can take/release the cgroup_mutex via the functions
+cgroup_lock()/cgroup_unlock(), and can
+take/release the callback_mutex via the functions
+cgroup_lock()/cgroup_unlock().
+
+Accessing a task's cgroup pointer may be done in the following ways:
+- while holding cgroup_mutex
+- while holding the task's alloc_lock (via task_lock())
+- inside an rcu_read_lock() section via rcu_dereference()
+
+3.3 Subsystem API
+--------------------------
+
+Each subsystem should:
+
+- add an entry in linux/cgroup_subsys.h
+- define a cgroup_subsys object called <name>_subsys
+
+Each subsystem may export the following methods. The only mandatory
+methods are create/destroy. Any others that are null are presumed to
+be successful no-ops.
+
+struct cgroup_subsys_state *create(struct cgroup *cont)
+LL=cgroup_mutex
+
+Called to create a subsystem state object for a cgroup. The
+subsystem should allocate its subsystem state object for the passed
+cgroup, returning a pointer to the new object on success or a
+negative error code. On success, the subsystem pointer should point to
+a structure of type cgroup_subsys_state (typically embedded in a
+larger subsystem-specific object), which will be initialized by the
+cgroup system. Note that this will be called at initialization to
+create the root subsystem state for this subsystem; this case can be
+identified by the passed cgroup object having a NULL parent (since
+it's the root of the hierarchy) and may be an appropriate place for
+initialization code.
+
+void destroy(struct cgroup *cont)
+LL=cgroup_mutex
+
+The cgroup system is about to destroy the passed cgroup; the
+subsystem should do any necessary cleanup
+
+int can_attach(struct cgroup_subsys *ss, struct cgroup *cont,
+	       struct task_struct *task)
+LL=cgroup_mutex
+
+Called prior to moving a task into a cgroup; if the subsystem
+returns an error, this will abort the attach operation.  If a NULL
+task is passed, then a successful result indicates that *any*
+unspecified task can be moved into the cgroup. Note that this isn't
+called on a fork. If this method returns 0 (success) then this should
+remain valid while the caller holds cgroup_mutex.
+
+void attach(struct cgroup_subsys *ss, struct cgroup *cont,
+	    struct cgroup *old_cont, struct task_struct *task)
+LL=cgroup_mutex
+
+
+Called after the task has been attached to the cgroup, to allow any
+post-attachment activity that requires memory allocations or blocking.
+
+void fork(struct cgroup_subsy *ss, struct task_struct *task)
+LL=callback_mutex, maybe read_lock(tasklist_lock)
+
+Called when a task is forked into a cgroup. Also called during
+registration for all existing tasks.
+
+void exit(struct cgroup_subsys *ss, struct task_struct *task)
+LL=callback_mutex
+
+Called during task exit
+
+int populate(struct cgroup_subsys *ss, struct cgroup *cont)
+LL=none
+
+Called after creation of a cgroup to allow a subsystem to populate
+the cgroup directory with file entries.  The subsystem should make
+calls to cgroup_add_file() with objects of type cftype (see
+include/linux/cgroup.h for details).  Note that although this
+method can return an error code, the error code is currently not
+always handled well.
+
+void post_clone(struct cgroup_subsys *ss, struct cgroup *cont)
+
+Called at the end of cgroup_clone() to do any paramater
+initialization which might be required before a task could attach.  For
+example in cpusets, no task may attach before 'cpus' and 'mems' are set
+up.
+
+void bind(struct cgroup_subsys *ss, struct cgroup *root)
+LL=callback_mutex
+
+Called when a cgroup subsystem is rebound to a different hierarchy
+and root cgroup. Currently this will only involve movement between
+the default hierarchy (which never has sub-cgroups) and a hierarchy
+that is being created/destroyed (and hence has no sub-cgroups).
+
+4. Questions
+============
+
+Q: what's up with this '/bin/echo' ?
+A: bash's builtin 'echo' command does not check calls to write() against
+   errors. If you use it in the cgroup file system, you won't be
+   able to tell whether a command succeeded or failed.
+
+Q: When I attach processes, only the first of the line gets really attached !
+A: We can only return one error code per call to write(). So you should also
+   put only ONE pid.
+
diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt
index b6d24c2..a741f65 100644
--- a/Documentation/cpu-hotplug.txt
+++ b/Documentation/cpu-hotplug.txt
@@ -220,7 +220,9 @@
   CPU_DOWN_PREPARE or CPU_DOWN_PREPARE_FROZEN, depending on whether or not the
   CPU is being offlined while tasks are frozen due to a suspend operation in
   progress
-- All process is migrated away from this outgoing CPU to a new CPU
+- All processes are migrated away from this outgoing CPU to new CPUs.
+  The new CPU is chosen from each process' current cpuset, which may be
+  a subset of all online CPUs.
 - All interrupts targeted to this CPU is migrated to a new CPU
 - timers/bottom half/task lets are also migrated to a new CPU
 - Once all services are migrated, kernel calls an arch specific routine
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index ec9de69..141bef1 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -7,6 +7,7 @@
 Portions Copyright (c) 2004-2006 Silicon Graphics, Inc.
 Modified by Paul Jackson <pj@sgi.com>
 Modified by Christoph Lameter <clameter@sgi.com>
+Modified by Paul Menage <menage@google.com>
 
 CONTENTS:
 =========
@@ -16,9 +17,9 @@
   1.2 Why are cpusets needed ?
   1.3 How are cpusets implemented ?
   1.4 What are exclusive cpusets ?
-  1.5 What does notify_on_release do ?
-  1.6 What is memory_pressure ?
-  1.7 What is memory spread ?
+  1.5 What is memory_pressure ?
+  1.6 What is memory spread ?
+  1.7 What is sched_load_balance ?
   1.8 How do I use cpusets ?
 2. Usage Examples and Syntax
   2.1 Basic Usage
@@ -44,18 +45,19 @@
 hooks, beyond what is already present, required to manage dynamic
 job placement on large systems.
 
-Each task has a pointer to a cpuset.  Multiple tasks may reference
-the same cpuset.  Requests by a task, using the sched_setaffinity(2)
-system call to include CPUs in its CPU affinity mask, and using the
-mbind(2) and set_mempolicy(2) system calls to include Memory Nodes
-in its memory policy, are both filtered through that tasks cpuset,
-filtering out any CPUs or Memory Nodes not in that cpuset.  The
-scheduler will not schedule a task on a CPU that is not allowed in
-its cpus_allowed vector, and the kernel page allocator will not
-allocate a page on a node that is not allowed in the requesting tasks
-mems_allowed vector.
+Cpusets use the generic cgroup subsystem described in
+Documentation/cgroup.txt.
 
-User level code may create and destroy cpusets by name in the cpuset
+Requests by a task, using the sched_setaffinity(2) system call to
+include CPUs in its CPU affinity mask, and using the mbind(2) and
+set_mempolicy(2) system calls to include Memory Nodes in its memory
+policy, are both filtered through that tasks cpuset, filtering out any
+CPUs or Memory Nodes not in that cpuset.  The scheduler will not
+schedule a task on a CPU that is not allowed in its cpus_allowed
+vector, and the kernel page allocator will not allocate a page on a
+node that is not allowed in the requesting tasks mems_allowed vector.
+
+User level code may create and destroy cpusets by name in the cgroup
 virtual file system, manage the attributes and permissions of these
 cpusets and which CPUs and Memory Nodes are assigned to each cpuset,
 specify and query to which cpuset a task is assigned, and list the
@@ -115,7 +117,7 @@
  - Cpusets are sets of allowed CPUs and Memory Nodes, known to the
    kernel.
  - Each task in the system is attached to a cpuset, via a pointer
-   in the task structure to a reference counted cpuset structure.
+   in the task structure to a reference counted cgroup structure.
  - Calls to sched_setaffinity are filtered to just those CPUs
    allowed in that tasks cpuset.
  - Calls to mbind and set_mempolicy are filtered to just
@@ -145,15 +147,10 @@
  - in page_alloc.c, to restrict memory to allowed nodes.
  - in vmscan.c, to restrict page recovery to the current cpuset.
 
-In addition a new file system, of type "cpuset" may be mounted,
-typically at /dev/cpuset, to enable browsing and modifying the cpusets
-presently known to the kernel.  No new system calls are added for
-cpusets - all support for querying and modifying cpusets is via
-this cpuset file system.
-
-Each task under /proc has an added file named 'cpuset', displaying
-the cpuset name, as the path relative to the root of the cpuset file
-system.
+You should mount the "cgroup" filesystem type in order to enable
+browsing and modifying the cpusets presently known to the kernel.  No
+new system calls are added for cpusets - all support for querying and
+modifying cpusets is via this cpuset file system.
 
 The /proc/<pid>/status file for each task has two added lines,
 displaying the tasks cpus_allowed (on which CPUs it may be scheduled)
@@ -163,16 +160,15 @@
   Cpus_allowed:   ffffffff,ffffffff,ffffffff,ffffffff
   Mems_allowed:   ffffffff,ffffffff
 
-Each cpuset is represented by a directory in the cpuset file system
-containing the following files describing that cpuset:
+Each cpuset is represented by a directory in the cgroup file system
+containing (on top of the standard cgroup files) the following
+files describing that cpuset:
 
  - cpus: list of CPUs in that cpuset
  - mems: list of Memory Nodes in that cpuset
  - memory_migrate flag: if set, move pages to cpusets nodes
  - cpu_exclusive flag: is cpu placement exclusive?
  - mem_exclusive flag: is memory placement exclusive?
- - tasks: list of tasks (by pid) attached to that cpuset
- - notify_on_release flag: run /sbin/cpuset_release_agent on exit?
  - memory_pressure: measure of how much paging pressure in cpuset
 
 In addition, the root cpuset only has the following file:
@@ -237,21 +233,7 @@
 outside even a mem_exclusive cpuset.
 
 
-1.5 What does notify_on_release do ?
-------------------------------------
-
-If the notify_on_release flag is enabled (1) in a cpuset, then whenever
-the last task in the cpuset leaves (exits or attaches to some other
-cpuset) and the last child cpuset of that cpuset is removed, then
-the kernel runs the command /sbin/cpuset_release_agent, supplying the
-pathname (relative to the mount point of the cpuset file system) of the
-abandoned cpuset.  This enables automatic removal of abandoned cpusets.
-The default value of notify_on_release in the root cpuset at system
-boot is disabled (0).  The default value of other cpusets at creation
-is the current value of their parents notify_on_release setting.
-
-
-1.6 What is memory_pressure ?
+1.5 What is memory_pressure ?
 -----------------------------
 The memory_pressure of a cpuset provides a simple per-cpuset metric
 of the rate that the tasks in a cpuset are attempting to free up in
@@ -308,7 +290,7 @@
 times 1000.
 
 
-1.7 What is memory spread ?
+1.6 What is memory spread ?
 ---------------------------
 There are two boolean flag files per cpuset that control where the
 kernel allocates pages for the file system buffers and related in
@@ -378,6 +360,142 @@
 data set, the memory allocation across the nodes in the jobs cpuset
 can become very uneven.
 
+1.7 What is sched_load_balance ?
+--------------------------------
+
+The kernel scheduler (kernel/sched.c) automatically load balances
+tasks.  If one CPU is underutilized, kernel code running on that
+CPU will look for tasks on other more overloaded CPUs and move those
+tasks to itself, within the constraints of such placement mechanisms
+as cpusets and sched_setaffinity.
+
+The algorithmic cost of load balancing and its impact on key shared
+kernel data structures such as the task list increases more than
+linearly with the number of CPUs being balanced.  So the scheduler
+has support to  partition the systems CPUs into a number of sched
+domains such that it only load balances within each sched domain.
+Each sched domain covers some subset of the CPUs in the system;
+no two sched domains overlap; some CPUs might not be in any sched
+domain and hence won't be load balanced.
+
+Put simply, it costs less to balance between two smaller sched domains
+than one big one, but doing so means that overloads in one of the
+two domains won't be load balanced to the other one.
+
+By default, there is one sched domain covering all CPUs, except those
+marked isolated using the kernel boot time "isolcpus=" argument.
+
+This default load balancing across all CPUs is not well suited for
+the following two situations:
+ 1) On large systems, load balancing across many CPUs is expensive.
+    If the system is managed using cpusets to place independent jobs
+    on separate sets of CPUs, full load balancing is unnecessary.
+ 2) Systems supporting realtime on some CPUs need to minimize
+    system overhead on those CPUs, including avoiding task load
+    balancing if that is not needed.
+
+When the per-cpuset flag "sched_load_balance" is enabled (the default
+setting), it requests that all the CPUs in that cpusets allowed 'cpus'
+be contained in a single sched domain, ensuring that load balancing
+can move a task (not otherwised pinned, as by sched_setaffinity)
+from any CPU in that cpuset to any other.
+
+When the per-cpuset flag "sched_load_balance" is disabled, then the
+scheduler will avoid load balancing across the CPUs in that cpuset,
+--except-- in so far as is necessary because some overlapping cpuset
+has "sched_load_balance" enabled.
+
+So, for example, if the top cpuset has the flag "sched_load_balance"
+enabled, then the scheduler will have one sched domain covering all
+CPUs, and the setting of the "sched_load_balance" flag in any other
+cpusets won't matter, as we're already fully load balancing.
+
+Therefore in the above two situations, the top cpuset flag
+"sched_load_balance" should be disabled, and only some of the smaller,
+child cpusets have this flag enabled.
+
+When doing this, you don't usually want to leave any unpinned tasks in
+the top cpuset that might use non-trivial amounts of CPU, as such tasks
+may be artificially constrained to some subset of CPUs, depending on
+the particulars of this flag setting in descendent cpusets.  Even if
+such a task could use spare CPU cycles in some other CPUs, the kernel
+scheduler might not consider the possibility of load balancing that
+task to that underused CPU.
+
+Of course, tasks pinned to a particular CPU can be left in a cpuset
+that disables "sched_load_balance" as those tasks aren't going anywhere
+else anyway.
+
+There is an impedance mismatch here, between cpusets and sched domains.
+Cpusets are hierarchical and nest.  Sched domains are flat; they don't
+overlap and each CPU is in at most one sched domain.
+
+It is necessary for sched domains to be flat because load balancing
+across partially overlapping sets of CPUs would risk unstable dynamics
+that would be beyond our understanding.  So if each of two partially
+overlapping cpusets enables the flag 'sched_load_balance', then we
+form a single sched domain that is a superset of both.  We won't move
+a task to a CPU outside it cpuset, but the scheduler load balancing
+code might waste some compute cycles considering that possibility.
+
+This mismatch is why there is not a simple one-to-one relation
+between which cpusets have the flag "sched_load_balance" enabled,
+and the sched domain configuration.  If a cpuset enables the flag, it
+will get balancing across all its CPUs, but if it disables the flag,
+it will only be assured of no load balancing if no other overlapping
+cpuset enables the flag.
+
+If two cpusets have partially overlapping 'cpus' allowed, and only
+one of them has this flag enabled, then the other may find its
+tasks only partially load balanced, just on the overlapping CPUs.
+This is just the general case of the top_cpuset example given a few
+paragraphs above.  In the general case, as in the top cpuset case,
+don't leave tasks that might use non-trivial amounts of CPU in
+such partially load balanced cpusets, as they may be artificially
+constrained to some subset of the CPUs allowed to them, for lack of
+load balancing to the other CPUs.
+
+1.7.1 sched_load_balance implementation details.
+------------------------------------------------
+
+The per-cpuset flag 'sched_load_balance' defaults to enabled (contrary
+to most cpuset flags.)  When enabled for a cpuset, the kernel will
+ensure that it can load balance across all the CPUs in that cpuset
+(makes sure that all the CPUs in the cpus_allowed of that cpuset are
+in the same sched domain.)
+
+If two overlapping cpusets both have 'sched_load_balance' enabled,
+then they will be (must be) both in the same sched domain.
+
+If, as is the default, the top cpuset has 'sched_load_balance' enabled,
+then by the above that means there is a single sched domain covering
+the whole system, regardless of any other cpuset settings.
+
+The kernel commits to user space that it will avoid load balancing
+where it can.  It will pick as fine a granularity partition of sched
+domains as it can while still providing load balancing for any set
+of CPUs allowed to a cpuset having 'sched_load_balance' enabled.
+
+The internal kernel cpuset to scheduler interface passes from the
+cpuset code to the scheduler code a partition of the load balanced
+CPUs in the system. This partition is a set of subsets (represented
+as an array of cpumask_t) of CPUs, pairwise disjoint, that cover all
+the CPUs that must be load balanced.
+
+Whenever the 'sched_load_balance' flag changes, or CPUs come or go
+from a cpuset with this flag enabled, or a cpuset with this flag
+enabled is removed, the cpuset code builds a new such partition and
+passes it to the scheduler sched domain setup code, to have the sched
+domains rebuilt as necessary.
+
+This partition exactly defines what sched domains the scheduler should
+setup - one sched domain for each element (cpumask_t) in the partition.
+
+The scheduler remembers the currently active sched domain partitions.
+When the scheduler routine partition_sched_domains() is invoked from
+the cpuset code to update these sched domains, it compares the new
+partition requested with the current, and updates its sched domains,
+removing the old and adding the new, for each change.
 
 1.8 How do I use cpusets ?
 --------------------------
@@ -469,7 +587,7 @@
 To start a new job that is to be contained within a cpuset, the steps are:
 
  1) mkdir /dev/cpuset
- 2) mount -t cpuset none /dev/cpuset
+ 2) mount -t cgroup -ocpuset cpuset /dev/cpuset
  3) Create the new cpuset by doing mkdir's and write's (or echo's) in
     the /dev/cpuset virtual file system.
  4) Start a task that will be the "founding father" of the new job.
@@ -481,7 +599,7 @@
 named "Charlie", containing just CPUs 2 and 3, and Memory Node 1,
 and then start a subshell 'sh' in that cpuset:
 
-  mount -t cpuset none /dev/cpuset
+  mount -t cgroup -ocpuset cpuset /dev/cpuset
   cd /dev/cpuset
   mkdir Charlie
   cd Charlie
@@ -513,7 +631,7 @@
 virtual filesystem.
 
 To mount it, type:
-# mount -t cpuset none /dev/cpuset
+# mount -t cgroup -o cpuset cpuset /dev/cpuset
 
 Then under /dev/cpuset you can find a tree that corresponds to the
 tree of the cpusets in the system. For instance, /dev/cpuset
@@ -556,6 +674,18 @@
 This will fail if the cpuset is in use (has cpusets inside, or has
 processes attached).
 
+Note that for legacy reasons, the "cpuset" filesystem exists as a
+wrapper around the cgroup filesystem.
+
+The command
+
+mount -t cpuset X /dev/cpuset
+
+is equivalent to
+
+mount -t cgroup -ocpuset X /dev/cpuset
+echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent
+
 2.2 Adding/removing cpus
 ------------------------
 
diff --git a/Documentation/device-mapper/dm-uevent.txt b/Documentation/device-mapper/dm-uevent.txt
new file mode 100644
index 0000000..07edbd8
--- /dev/null
+++ b/Documentation/device-mapper/dm-uevent.txt
@@ -0,0 +1,97 @@
+The device-mapper uevent code adds the capability to device-mapper to create
+and send kobject uevents (uevents).  Previously device-mapper events were only
+available through the ioctl interface.  The advantage of the uevents interface
+is the event contains environment attributes providing increased context for
+the event avoiding the need to query the state of the device-mapper device after
+the event is received.
+
+There are two functions currently for device-mapper events.  The first function
+listed creates the event and the second function sends the event(s).
+
+void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
+                    const char *path, unsigned nr_valid_paths)
+
+void dm_send_uevents(struct list_head *events, struct kobject *kobj)
+
+
+The variables added to the uevent environment are:
+
+Variable Name: DM_TARGET
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description:
+Value: Name of device-mapper target that generated the event.
+
+Variable Name: DM_ACTION
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description:
+Value: Device-mapper specific action that caused the uevent action.
+	PATH_FAILED - A path has failed.
+	PATH_REINSTATED - A path has been reinstated.
+
+Variable Name: DM_SEQNUM
+Uevent Action(s): KOBJ_CHANGE
+Type: unsigned integer
+Description: A sequence number for this specific device-mapper device.
+Value: Valid unsigned integer range.
+
+Variable Name: DM_PATH
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description: Major and minor number of the path device pertaining to this
+event.
+Value: Path name in the form of "Major:Minor"
+
+Variable Name: DM_NR_VALID_PATHS
+Uevent Action(s): KOBJ_CHANGE
+Type: unsigned integer
+Description:
+Value: Valid unsigned integer range.
+
+Variable Name: DM_NAME
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description: Name of the device-mapper device.
+Value: Name
+
+Variable Name: DM_UUID
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description: UUID of the device-mapper device.
+Value: UUID. (Empty string if there isn't one.)
+
+An example of the uevents generated as captured by udevmonitor is shown
+below.
+
+1.) Path failure.
+UEVENT[1192521009.711215] change@/block/dm-3
+ACTION=change
+DEVPATH=/block/dm-3
+SUBSYSTEM=block
+DM_TARGET=multipath
+DM_ACTION=PATH_FAILED
+DM_SEQNUM=1
+DM_PATH=8:32
+DM_NR_VALID_PATHS=0
+DM_NAME=mpath2
+DM_UUID=mpath-35333333000002328
+MINOR=3
+MAJOR=253
+SEQNUM=1130
+
+2.) Path reinstate.
+UEVENT[1192521132.989927] change@/block/dm-3
+ACTION=change
+DEVPATH=/block/dm-3
+SUBSYSTEM=block
+DM_TARGET=multipath
+DM_ACTION=PATH_REINSTATED
+DM_SEQNUM=2
+DM_PATH=8:32
+DM_NR_VALID_PATHS=1
+DM_NAME=mpath2
+DM_UUID=mpath-35333333000002328
+MINOR=3
+MAJOR=253
+SEQNUM=1131
diff --git a/Documentation/devices.txt b/Documentation/devices.txt
index 6c46730..e6244cd 100644
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -2188,7 +2188,7 @@
 
 136-143 char	Unix98 PTY slaves
 		  0 = /dev/pts/0	First Unix98 pseudo-TTY
-		  1 = /dev/pts/1	Second Unix98 pesudo-TTY
+		  1 = /dev/pts/1	Second Unix98 pseudo-TTY
 		    ...
 
 		These device nodes are automatically generated with
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 8569072..387b8a7 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -32,7 +32,7 @@
 
 For one reason or another, low level drivers don't receive as much
 attention or testing as core code, and bugs on driver detach or
-initilaization failure doesn't happen often enough to be noticeable.
+initialization failure don't happen often enough to be noticeable.
 Init failure path is worse because it's much less travelled while
 needs to handle multiple entry points.
 
@@ -160,7 +160,7 @@
   devres_release_group(dev, NULL);
   return err_code;
 
-As resource acquision failure usually means probe failure, constructs
+As resource acquisition failure usually means probe failure, constructs
 like above are usually useful in midlayer driver (e.g. libata core
 layer) where interface function shouldn't have side effect on failure.
 For LLDs, just returning error code suffices in most cases.
diff --git a/Documentation/fb/deferred_io.txt b/Documentation/fb/deferred_io.txt
index 73cf9fb..63883a8 100644
--- a/Documentation/fb/deferred_io.txt
+++ b/Documentation/fb/deferred_io.txt
@@ -3,7 +3,7 @@
 
 Deferred IO is a way to delay and repurpose IO. It uses host memory as a
 buffer and the MMU pagefault as a pretrigger for when to perform the device
-IO. The following example may be a useful explaination of how one such setup
+IO. The following example may be a useful explanation of how one such setup
 works:
 
 - userspace app like Xfbdev mmaps framebuffer
@@ -28,7 +28,7 @@
 
 For some types of nonvolatile high latency displays, the desired image is
 the final image rather than the intermediate stages which is why it's okay
-to not update for each write that is occuring.
+to not update for each write that is occurring.
 
 It may be the case that this is useful in other scenarios as well. Paul Mundt
 has mentioned a case where it is beneficial to use the page count to decide
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 280ec06..6bb9be5 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -14,18 +14,6 @@
 
 ---------------------------
 
-What:	V4L2 VIDIOC_G_MPEGCOMP and VIDIOC_S_MPEGCOMP
-When:	October 2007
-Why:	Broken attempt to set MPEG compression parameters. These ioctls are
-	not able to implement the wide variety of parameters that can be set
-	by hardware MPEG encoders. A new MPEG control mechanism was created
-	in kernel 2.6.18 that replaces these ioctls. See the V4L2 specification
-	(section 1.9: Extended controls) for more information on this topic.
-Who:	Hans Verkuil <hverkuil@xs4all.nl> and
-	Mauro Carvalho Chehab <mchehab@infradead.org>
-
----------------------------
-
 What:	dev->power.power_state
 When:	July 2007
 Why:	Broken design for runtime control over driver power states, confusing
@@ -49,10 +37,10 @@
 ---------------------------
 
 What:	Video4Linux API 1 ioctls and video_decoder.h from Video devices.
-When:	December 2006
-Files:	include/linux/video_decoder.h
-Check:	include/linux/video_decoder.h
-Why:	V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
+When:	December 2008
+Files:	include/linux/video_decoder.h include/linux/videodev.h
+Check:	include/linux/video_decoder.h include/linux/videodev.h
+Why:	V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6
 	series. The old API have lots of drawbacks and don't provide enough
 	means to work with all video and audio standards. The newer API is
 	already available on the main drivers and should be used instead.
@@ -61,7 +49,9 @@
 	Decoder iocts are using internally to allow video drivers to
 	communicate with video decoders. This should also be improved to allow
 	V4L2 calls being translated into compatible internal ioctls.
-Who:	Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+	Compatibility ioctls will be provided, for a while, via 
+	v4l1-compat module. 
+Who:	Mauro Carvalho Chehab <mchehab@infradead.org>
 
 ---------------------------
 
@@ -82,6 +72,41 @@
 
 ---------------------------
 
+What:	sys_sysctl
+When:	September 2010
+Option: CONFIG_SYSCTL_SYSCALL
+Why:	The same information is available in a more convenient from
+	/proc/sys, and none of the sysctl variables appear to be
+	important performance wise.
+
+	Binary sysctls are a long standing source of subtle kernel
+	bugs and security issues.
+
+	When I looked several months ago all I could find after
+	searching several distributions were 5 user space programs and
+	glibc (which falls back to /proc/sys) using this syscall.
+
+	The man page for sysctl(2) documents it as unusable for user
+	space programs.
+
+	sysctl(2) is not generally ABI compatible to a 32bit user
+	space application on a 64bit and a 32bit kernel.
+
+	For the last several months the policy has been no new binary
+	sysctls and no one has put forward an argument to use them.
+
+	Binary sysctls issues seem to keep happening appearing so
+	properly deprecating them (with a warning to user space) and a
+	2 year grace warning period will mean eventually we can kill
+	them and end the pain.
+
+	In the mean time individual binary sysctls can be dealt with
+	in a piecewise fashion.
+
+Who:	Eric Biederman <ebiederm@xmission.com>
+
+---------------------------
+
 What:  a.out interpreter support for ELF executables
 When:  2.6.25
 Files: fs/binfmt_elf.c
@@ -184,13 +209,6 @@
 
 ---------------------------
 
-What:  drivers depending on OBSOLETE_OSS
-When:  options in 2.6.22, code in 2.6.24
-Why:   OSS drivers with ALSA replacements
-Who:   Adrian Bunk <bunk@stusta.de>
-
----------------------------
-
 What:	ACPI procfs interface
 When:	July 2008
 Why:	ACPI sysfs conversion should be finished by January 2008.
diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt
index d6fd6c6..bf80806 100644
--- a/Documentation/filesystems/9p.txt
+++ b/Documentation/filesystems/9p.txt
@@ -42,10 +42,12 @@
 
   trans=name	select an alternative transport.  Valid options are
   		currently:
- 			unix - specifying a named pipe mount point
- 			tcp  - specifying a normal TCP/IP connection
- 			fd   - used passed file descriptors for connection
+			unix 	- specifying a named pipe mount point
+			tcp	- specifying a normal TCP/IP connection
+			fd   	- used passed file descriptors for connection
                                 (see rfdno and wfdno)
+			virtio	- connect to the next virtio channel available
+				(from lguest or KVM with trans_virtio module)
 
   uname=name	user name to attempt mount as on the remote server.  The
   		server may override or ignore this value.  Certain user
@@ -54,7 +56,7 @@
   aname=name	aname specifies the file tree to access when the server is
   		offering several exported file systems.
 
-  cache=mode	specifies a cacheing policy.  By default, no caches are used.
+  cache=mode	specifies a caching policy.  By default, no caches are used.
 			loose = no attempts are made at consistency,
                                 intended for exclusive, read-only mounts
 
diff --git a/Documentation/filesystems/Exporting b/Documentation/filesystems/Exporting
index 31047e0..87019d2 100644
--- a/Documentation/filesystems/Exporting
+++ b/Documentation/filesystems/Exporting
@@ -2,9 +2,12 @@
 Making Filesystems Exportable
 =============================
 
-Most filesystem operations require a dentry (or two) as a starting
+Overview
+--------
+
+All filesystem operations require a dentry (or two) as a starting
 point.  Local applications have a reference-counted hold on suitable
-dentrys via open file descriptors or cwd/root.  However remote
+dentries via open file descriptors or cwd/root.  However remote
 applications that access a filesystem via a remote filesystem protocol
 such as NFS may not be able to hold such a reference, and so need a
 different way to refer to a particular dentry.  As the alternative
@@ -13,14 +16,14 @@
 problematic), there is no simple answer like 'filename'.
 
 The mechanism discussed here allows each filesystem implementation to
-specify how to generate an opaque (out side of the filesystem) byte
+specify how to generate an opaque (outside of the filesystem) byte
 string for any dentry, and how to find an appropriate dentry for any
 given opaque byte string.
 This byte string will be called a "filehandle fragment" as it
 corresponds to part of an NFS filehandle.
 
 A filesystem which supports the mapping between filehandle fragments
-and dentrys will be termed "exportable".
+and dentries will be termed "exportable".
 
 
 
@@ -89,11 +92,9 @@
    1/ provide the filehandle fragment routines described below.
    2/ make sure that d_splice_alias is used rather than d_add
       when ->lookup finds an inode for a given parent and name.
-      Typically the ->lookup routine will end:
-		if (inode)
-			return d_splice(inode, dentry);
-		d_add(dentry, inode);
-		return NULL;
+      Typically the ->lookup routine will end with a:
+
+		return d_splice_alias(inode, dentry);
 	}
 
 
@@ -101,67 +102,39 @@
   A file system implementation declares that instances of the filesystem
 are exportable by setting the s_export_op field in the struct
 super_block.  This field must point to a "struct export_operations"
-struct which could potentially be full of NULLs, though normally at
-least get_parent will be set.
+struct which has the following members:
 
- The primary operations are decode_fh and encode_fh.  
-decode_fh takes a filehandle fragment and tries to find or create a
-dentry for the object referred to by the filehandle.
-encode_fh takes a dentry and creates a filehandle fragment which can
-later be used to find/create a dentry for the same object.
+ encode_fh  (optional)
+    Takes a dentry and creates a filehandle fragment which can later be used
+    to find or create a dentry for the same object.  The default
+    implementation creates a filehandle fragment that encodes a 32bit inode
+    and generation number for the inode encoded, and if necessary the
+    same information for the parent.
 
-decode_fh will probably make use of "find_exported_dentry".
-This function lives in the "exportfs" module which a filesystem does
-not need unless it is being exported.  So rather that calling
-find_exported_dentry directly, each filesystem should call it through
-the find_exported_dentry pointer in it's export_operations table.
-This field is set correctly by the exporting agent (e.g. nfsd) when a
-filesystem is exported, and before any export operations are called.
+  fh_to_dentry (mandatory)
+    Given a filehandle fragment, this should find the implied object and
+    create a dentry for it (possibly with d_alloc_anon).
 
-find_exported_dentry needs three support functions from the
-filesystem:
-  get_name.  When given a parent dentry and a child dentry, this
-    should find a name in the directory identified by the parent
-    dentry, which leads to the object identified by the child dentry.
-    If no get_name function is supplied, a default implementation is
-    provided which uses vfs_readdir to find potential names, and
-    matches inode numbers to find the correct match.
+  fh_to_parent (optional but strongly recommended)
+    Given a filehandle fragment, this should find the parent of the
+    implied object and create a dentry for it (possibly with d_alloc_anon).
+    May fail if the filehandle fragment is too small.
 
-  get_parent.  When given a dentry for a directory, this should return 
-    a dentry for the parent.  Quite possibly the parent dentry will
-    have been allocated by d_alloc_anon.  
-    The default get_parent function just returns an error so any
-    filehandle lookup that requires finding a parent will fail.
-    ->lookup("..") is *not* used as a default as it can leave ".."
-    entries in the dcache which are too messy to work with.
+  get_parent (optional but strongly recommended)
+    When given a dentry for a directory, this should return  a dentry for
+    the parent.  Quite possibly the parent dentry will have been allocated
+    by d_alloc_anon.  The default get_parent function just returns an error
+    so any filehandle lookup that requires finding a parent will fail.
+    ->lookup("..") is *not* used as a default as it can leave ".." entries
+    in the dcache which are too messy to work with.
 
-  get_dentry.  When given an opaque datum, this should find the
-    implied object and create a dentry for it (possibly with
-    d_alloc_anon). 
-    The opaque datum is whatever is passed down by the decode_fh
-    function, and is often simply a fragment of the filehandle
-    fragment.
-    decode_fh passes two datums through find_exported_dentry.  One that 
-    should be used to identify the target object, and one that can be
-    used to identify the object's parent, should that be necessary.
-    The default get_dentry function assumes that the datum contains an
-    inode number and a generation number, and it attempts to get the
-    inode using "iget" and check it's validity by matching the
-    generation number.  A filesystem should only depend on the default
-    if iget can safely be used this way.
-
-If decode_fh and/or encode_fh are left as NULL, then default
-implementations are used.  These defaults are suitable for ext2 and 
-extremely similar filesystems (like ext3).
-
-The default encode_fh creates a filehandle fragment from the inode
-number and generation number of the target together with the inode
-number and generation number of the parent (if the parent is
-required).
-
-The default decode_fh extract the target and parent datums from the
-filehandle assuming the format used by the default encode_fh and
-passed them to find_exported_dentry.
+  get_name (optional)
+    When given a parent dentry and a child dentry, this should find a name
+    in the directory identified by the parent dentry, which leads to the
+    object identified by the child dentry.  If no get_name function is
+    supplied, a default implementation is provided which uses vfs_readdir
+    to find potential names, and matches inode numbers to find the correct
+    match.
 
 
 A filehandle fragment consists of an array of 1 or more 4byte words,
@@ -172,5 +145,3 @@
 nuls.  Rather, the encode_fh routine should choose a "type" which
 indicates the decode_fh how much of the filehandle is valid, and how
 it should be interpreted.
-
- 
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index fe26cc9..37c10cb 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -224,7 +224,7 @@
 redirty_page_for_writepage(), then unlock the page and return zero.
 This may also be done to avoid internal deadlocks, but rarely.
 
-If the filesytem is called for sync then it must wait on any
+If the filesystem is called for sync then it must wait on any
 in-progress I/O and then start new I/O.
 
 The filesystem should unlock the page synchronously, before returning to the
diff --git a/Documentation/filesystems/ext3.txt b/Documentation/filesystems/ext3.txt
index 4aecc9b..b45f3c1b 100644
--- a/Documentation/filesystems/ext3.txt
+++ b/Documentation/filesystems/ext3.txt
@@ -130,12 +130,12 @@
 
 Journaling Block Device layer
 -----------------------------
-The Journaling Block Device layer (JBD) isn't ext3 specific.  It was design to
-add journaling capabilities on a block device.  The ext3 filesystem code will
-inform the JBD of modifications it is performing (called a transaction).  The
-journal supports the transactions start and stop, and in case of crash, the
-journal can replayed the transactions to put the partition back in a
-consistent state fast.
+The Journaling Block Device layer (JBD) isn't ext3 specific.  It was designed
+to add journaling capabilities to a block device.  The ext3 filesystem code
+will inform the JBD of modifications it is performing (called a transaction).
+The journal supports the transactions start and stop, and in case of a crash,
+the journal can replay the transactions to quickly put the partition back into
+a consistent state.
 
 Handles represent a single atomic update to a filesystem.  JBD can handle an
 external journal on a block device.
@@ -164,7 +164,7 @@
 In the event of a crash, the journal can be replayed, bringing both data and
 metadata into a consistent state.  This mode is the slowest except when data
 needs to be read from and written to disk at the same time where it
-outperforms all others modes.
+outperforms all other modes.
 
 Compatibility
 -------------
diff --git a/Documentation/filesystems/files.txt b/Documentation/filesystems/files.txt
index 133e213..bb0142f 100644
--- a/Documentation/filesystems/files.txt
+++ b/Documentation/filesystems/files.txt
@@ -76,13 +76,13 @@
 5. Handling of the file structures is special. Since the look-up
    of the fd (fget()/fget_light()) are lock-free, it is possible
    that look-up may race with the last put() operation on the
-   file structure. This is avoided using the rcuref APIs
+   file structure. This is avoided using atomic_inc_not_zero()
    on ->f_count :
 
 	rcu_read_lock();
 	file = fcheck_files(files, fd);
 	if (file) {
-		if (rcuref_inc_lf(&file->f_count))
+		if (atomic_inc_not_zero(&file->f_count))
 			*fput_needed = 1;
 		else
 		/* Didn't get the reference, someone's freed */
@@ -92,7 +92,7 @@
 	....
 	return file;
 
-   rcuref_inc_lf() detects if refcounts is already zero or
+   atomic_inc_not_zero() detects if refcounts is already zero or
    goes to zero during increment. If it does, we fail
    fget()/fget_light().
 
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index e5c1df5..dec9945 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -813,9 +813,9 @@
 since the system first booted.  For a quick look, simply cat the file:
 
   > cat /proc/stat
-  cpu  2255 34 2290 22625563 6290 127 456
-  cpu0 1132 34 1441 11311718 3675 127 438
-  cpu1 1123 0 849 11313845 2614 0 18
+  cpu  2255 34 2290 22625563 6290 127 456 0
+  cpu0 1132 34 1441 11311718 3675 127 438 0
+  cpu1 1123 0 849 11313845 2614 0 18 0
   intr 114930548 113199788 3 0 5 263 0 4 [... lots more numbers ...]
   ctxt 1990473
   btime 1062191376
@@ -835,6 +835,7 @@
 - iowait: waiting for I/O to complete
 - irq: servicing interrupts
 - softirq: servicing softirqs
+- steal: involuntary wait
 
 The "intr" line gives counts of interrupts  serviced since boot time, for each
 of the  possible system interrupts.   The first  column  is the  total of  all
diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt
index 4b5ca26..4598ef7 100644
--- a/Documentation/filesystems/sysfs.txt
+++ b/Documentation/filesystems/sysfs.txt
@@ -51,7 +51,7 @@
 attributes.
 
 Attributes should be ASCII text files, preferably with only one value
-per file. It is noted that it may not be efficient to contain only
+per file. It is noted that it may not be efficient to contain only one
 value per file, so it is socially acceptable to express an array of
 values of the same type. 
 
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 6f8e16e..9d019d3 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -706,7 +706,7 @@
         wants to make it a free page.  If ->releasepage succeeds, the
         page will be removed from the address_space and become free.
 
-	The second case if when a request has been made to invalidate
+	The second case is when a request has been made to invalidate
         some or all pages in an address_space.  This can happen
         through the fadvice(POSIX_FADV_DONTNEED) system call or by the
         filesystem explicitly requesting it as nfs and 9fs do (when
diff --git a/Documentation/i2c/i2c-protocol b/Documentation/i2c/i2c-protocol
index 579b92d..10518dd 100644
--- a/Documentation/i2c/i2c-protocol
+++ b/Documentation/i2c/i2c-protocol
@@ -68,7 +68,7 @@
 
   Flags I2C_M_IGNORE_NAK
     Normally message is interrupted immediately if there is [NA] from the
-    client. Setting this flag treats any [NA] as [A], and all of
+    client. Setting this flag treats any [NA] as [A], and all of
     message is sent.
     These messages may still fail to SCL lo->hi timeout.
 
diff --git a/Documentation/i386/boot.txt b/Documentation/i386/boot.txt
index 35985b3..2f75e75 100644
--- a/Documentation/i386/boot.txt
+++ b/Documentation/i386/boot.txt
@@ -168,6 +168,8 @@
 0234/1	2.05+	relocatable_kernel Whether kernel is relocatable or not
 0235/3	N/A	pad2		Unused
 0238/4	2.06+	cmdline_size	Maximum size of the kernel command line
+023C/4	2.07+	hardware_subarch Hardware subarchitecture
+0240/8	2.07+	hardware_subarch_data Subarchitecture-specific data
 
 (1) For backwards compatibility, if the setup_sects field contains 0, the
     real value is 4.
@@ -204,7 +206,7 @@
 
 The byte order of all fields is littleendian (this is x86, after all.)
 
-Field name:	setup_secs
+Field name:	setup_sects
 Type:		read
 Offset/size:	0x1f1/1
 Protocol:	ALL
@@ -356,6 +358,13 @@
 	- If 0, the protected-mode code is loaded at 0x10000.
 	- If 1, the protected-mode code is loaded at 0x100000.
 
+  Bit 6 (write): KEEP_SEGMENTS
+	Protocol: 2.07+
+	- if 0, reload the segment registers in the 32bit entry point.
+	- if 1, do not reload the segment registers in the 32bit entry point.
+		Assume that %cs %ds %ss %es are all set to flat segments with
+		a base of 0 (or the equivalent for their environment).
+
   Bit 7 (write): CAN_USE_HEAP
 	Set this bit to 1 to indicate that the value entered in the
 	heap_end_ptr is valid.  If this field is clear, some setup code
@@ -480,6 +489,29 @@
   cmdline_size characters. With protocol version 2.05 and earlier, the
   maximum size was 255.
 
+Field name:	hardware_subarch
+Type:		write
+Offset/size:	0x23c/4
+Protocol:	2.07+
+
+  In a paravirtualized environment the hardware low level architectural
+  pieces such as interrupt handling, page table handling, and
+  accessing process control registers needs to be done differently.
+
+  This field allows the bootloader to inform the kernel we are in one
+  one of those environments.
+
+  0x00000000	The default x86/PC environment
+  0x00000001	lguest
+  0x00000002	Xen
+
+Field name:	hardware_subarch_data
+Type:		write
+Offset/size:	0x240/8
+Protocol:	2.07+
+
+  A pointer to data that is specific to hardware subarch
+
 
 **** THE KERNEL COMMAND LINE
 
diff --git a/Documentation/ia64/err_inject.txt b/Documentation/ia64/err_inject.txt
index 6449a70..223e4f0 100644
--- a/Documentation/ia64/err_inject.txt
+++ b/Documentation/ia64/err_inject.txt
@@ -21,10 +21,10 @@
 
 Below is a sample application as part of the whole tool. The sample
 can be used as a working test tool. Or it can be expanded to include
-more features. It also can be a integrated into a libary or other user
+more features. It also can be a integrated into a library or other user
 application to have more thorough test.
 
-The sample application takes err.conf as error configuation input. Gcc
+The sample application takes err.conf as error configuration input. GCC
 compiles the code. After you install err_inject driver, you can run
 this sample application to inject errors.
 
@@ -809,7 +809,7 @@
 	}
 
 	/* Create semaphore: If one_lock, one semaphore for all processors.
-	   Otherwise, one sempaphore for each processor. */
+	   Otherwise, one semaphore for each processor. */
 	if (one_lock) {
 		if (create_sem(0)) {
 			printf("Can not create semaphore...exit\n");
diff --git a/Documentation/input/atarikbd.txt b/Documentation/input/atarikbd.txt
index ab05062..f3a3ba8 100644
--- a/Documentation/input/atarikbd.txt
+++ b/Documentation/input/atarikbd.txt
@@ -170,7 +170,7 @@
 keys. Any keys down at power-up are presumed to be stuck, and their BREAK
 (sic) code is returned (which without the preceding MAKE code is a flag for a
 keyboard error). If the controller self-test completes without error, the code
-0xF0 is returned. (This code will be used to indicate the version/rlease of
+0xF0 is returned. (This code will be used to indicate the version/release of
 the ikbd controller. The first release of the ikbd is version 0xF0, should
 there be a second release it will be 0xF1, and so on.)
 The ikbd defaults to a mouse position reporting with threshold of 1 unit in
@@ -413,7 +413,7 @@
             %nnnnmmmm   ; where m is JOYSTICK1 state
                         ; and n is JOYSTICK0 state
 
-Sets the ikbd to do nothing but monitor the serial command lne, maintain the
+Sets the ikbd to do nothing but monitor the serial command line, maintain the
 time-of-day clock, and monitor the joystick. The rate sets the interval
 between joystick samples.
 N.B. The user should not set the rate higher than the serial communications
@@ -446,10 +446,10 @@
                         ; until vertical cursor key is generated before RY
                         ; has elapsed
     VX                  ; length (in tenths of seconds) of joystick closure
-                        ; until horizontal cursor keystokes are generated
+                        ; until horizontal cursor keystrokes are generated
                         ; after RX has elapsed
     VY                  ; length (in tenths of seconds) of joystick closure
-                        ; until vertical cursor keystokes are generated
+                        ; until vertical cursor keystrokes are generated
                         ; after RY has elapsed
 
 In this mode, joystick 0 is scanned in a way that simulates cursor keystrokes.
diff --git a/Documentation/input/ff.txt b/Documentation/input/ff.txt
index 085eb15..ded4d5f 100644
--- a/Documentation/input/ff.txt
+++ b/Documentation/input/ff.txt
@@ -1,5 +1,5 @@
 Force feedback for Linux.
-By Johann Deneux <deneux@ifrance.com> on 2001/04/22.
+By Johann Deneux <johann.deneux@gmail.com> on 2001/04/22.
 Updated by Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09.
 You may redistribute this file. Please remember to include shape.fig and
 interactive.fig as well.
diff --git a/Documentation/input/iforce-protocol.txt b/Documentation/input/iforce-protocol.txt
index 8777d2d..3ac9241 100644
--- a/Documentation/input/iforce-protocol.txt
+++ b/Documentation/input/iforce-protocol.txt
@@ -4,10 +4,10 @@
 from Immerse. That's why you should not trust what is written in this
 document. This document is intended to help understanding the protocol.
 This is not a reference. Comments and corrections are welcome.  To contact me,
-send an email to: deneux@ifrance.com
+send an email to: johann.deneux@gmail.com
 
 ** WARNING **
-I may not be held responsible for any dammage or harm caused if you try to
+I shall not be held responsible for any damage or harm caused if you try to
 send data to your I-Force device based on what you read in this document.
 
 ** Preliminary Notes:
@@ -151,13 +151,13 @@
 Query command. Length varies according to the query type.
 The general format of this packet is:
 ff 01 QUERY [INDEX] CHECKSUM
-reponses are of the same form:
+responses are of the same form:
 FF LEN QUERY VALUE_QUERIED CHECKSUM2
 where LEN = 1 + length(VALUE_QUERIED)
 
 **** Query ram size ****
 QUERY = 42 ('B'uffer size)
-The device should reply with the same packet plus two additionnal bytes
+The device should reply with the same packet plus two additional bytes
 containing the size of the memory:
 ff 03 42 03 e8 CS would mean that the device has 1000 bytes of ram available.
 
@@ -234,19 +234,23 @@
 
 ** Appendix: How to study the protocol ? **
 
-1. Generate effects using the force editor provided with the DirectX SDK, or use Immersion Studio (freely available at their web site in the developer section: www.immersion.com)
-2. Start a soft spying RS232 or USB (depending on where you connected your joystick/wheel). I used ComPortSpy from fCoder (alpha version!)
+1. Generate effects using the force editor provided with the DirectX SDK, or 
+use Immersion Studio (freely available at their web site in the developer section: 
+www.immersion.com)
+2. Start a soft spying RS232 or USB (depending on where you connected your 
+joystick/wheel). I used ComPortSpy from fCoder (alpha version!)
 3. Play the effect, and watch what happens on the spy screen.
 
 A few words about ComPortSpy:
-At first glance, this soft seems, hum, well... buggy. In fact, data appear with a few seconds latency. Personnaly, I restart it every time I play an effect.
+At first glance, this software seems, hum, well... buggy. In fact, data appear with a
+few seconds latency. Personally, I restart it every time I play an effect.
 Remember it's free (as in free beer) and alpha!
 
 ** URLS **
 Check www.immerse.com for Immersion Studio, and www.fcoder.com for ComPortSpy.
 
 ** Author of this document **
-Johann Deneux <deneux@ifrance.com>
+Johann Deneux <johann.deneux@gmail.com>
 Home page at http://www.esil.univ-mrs.fr/~jdeneux/projects/ff/
 
 Additions by Vojtech Pavlik.
diff --git a/Documentation/input/input-programming.txt b/Documentation/input/input-programming.txt
index d9d5230..47fc868 100644
--- a/Documentation/input/input-programming.txt
+++ b/Documentation/input/input-programming.txt
@@ -42,8 +42,8 @@
 		goto err_free_irq;
 	}
 
-	button_dev->evbit[0] = BIT(EV_KEY);
-	button_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+	button_dev->evbit[0] = BIT_MASK(EV_KEY);
+	button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
 
 	error = input_register_device(button_dev);
 	if (error) {
@@ -79,7 +79,7 @@
 booting the kernel, it grabs the required resources (it should also check
 for the presence of the device).
 
-Then it allocates a new input device structure with input_aloocate_device()
+Then it allocates a new input device structure with input_allocate_device()
 and sets up input bitfields. This way the device driver tells the other
 parts of the input systems what it is - what events can be generated or
 accepted by this input device. Our example device can only generate EV_KEY
@@ -217,14 +217,15 @@
 that the thing is precise and always returns to exactly the center position
 (if it has any).
 
-1.4 NBITS(), LONG(), BIT()
+1.4 BITS_TO_LONGS(), BIT_WORD(), BIT_MASK()
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-These three macros from input.h help some bitfield computations:
+These three macros from bitops.h help some bitfield computations:
 
-	NBITS(x) - returns the length of a bitfield array in longs for x bits
-	LONG(x)  - returns the index in the array in longs for bit x
-	BIT(x)   - returns the index in a long for bit x
+	BITS_TO_LONGS(x) - returns the length of a bitfield array in longs for
+			   x bits
+	BIT_WORD(x)	 - returns the index in the array in longs for bit x
+	BIT_MASK(x)	 - returns the index in a long for bit x
 
 1.5 The id* and name fields
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/Documentation/isdn/CREDITS b/Documentation/isdn/CREDITS
index 7c17c83..8cac6c2 100644
--- a/Documentation/isdn/CREDITS
+++ b/Documentation/isdn/CREDITS
@@ -40,7 +40,7 @@
 Pedro Roque Marques (roque@di.fc.ul.pt)
   For lot of new ideas and the pcbit driver.
 
-Eberhard Moenkeberg (emoenke@gwdg.de)
+Eberhard Mönkeberg (emoenke@gwdg.de)
   For testing and help to get into kernel.
 
 Thomas Neumann (tn@ruhr.de)
diff --git a/Documentation/isdn/README.concap b/Documentation/isdn/README.concap
index 2f114ba..a76d748 100644
--- a/Documentation/isdn/README.concap
+++ b/Documentation/isdn/README.concap
@@ -111,7 +111,7 @@
 	struct concap_proto *  (*proto_new) (void);
 
 	/* delete encapsulation protocol instance and free all its resources.
-	   cprot may no loger be referenced after calling this */
+	   cprot may no longer be referenced after calling this */
 	void (*proto_del)(struct concap_proto *cprot);
 
 	/* initialize the protocol's data. To be called at interface startup
diff --git a/Documentation/java.txt b/Documentation/java.txt
index 3cce3fb..e6a7232 100644
--- a/Documentation/java.txt
+++ b/Documentation/java.txt
@@ -37,7 +37,7 @@
    or the following, if you want to be more selective:
      ':Applet:M::<!--applet::/usr/bin/appletviewer:'
 
-   Of cause you have to fix the path names. Given path/file names in this
+   Of course you have to fix the path names. The path/file names given in this
    document match the Debian 2.1 system. (i.e. jdk installed in /usr,
    custom wrappers from this document in /usr/local)
 
diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt
index fe8b0c4..616043a 100644
--- a/Documentation/kbuild/kconfig-language.txt
+++ b/Documentation/kbuild/kconfig-language.txt
@@ -77,7 +77,12 @@
   Optionally, dependencies only for this default value can be added with
   "if".
 
-- dependencies: "depends on"/"requires" <expr>
+- type definition + default value:
+	"def_bool"/"def_tristate" <expr> ["if" <expr>]
+  This is a shorthand notation for a type definition plus a value.
+  Optionally dependencies for this default value can be added with "if".
+
+- dependencies: "depends on" <expr>
   This defines a dependency for this menu entry. If multiple
   dependencies are defined, they are connected with '&&'. Dependencies
   are applied to all other options within this menu entry (which also
@@ -289,3 +294,10 @@
 	"source" <prompt>
 
 This reads the specified configuration file. This file is always parsed.
+
+mainmenu:
+
+	"mainmenu" <prompt>
+
+This sets the config program's title bar if the config program chooses
+to use it.
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index f099b81..7a77533 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -518,6 +518,28 @@
 	In this example for a specific GCC version the build will error out explaining
 	to the user why it stops.
 
+    cc-cross-prefix
+	cc-cross-prefix is used to check if there exists a $(CC) in path with
+	one of the listed prefixes. The first prefix where there exist a
+	prefix$(CC) in the PATH is returned - and if no prefix$(CC) is found
+	then nothing is returned.
+	Additional prefixes are separated by a single space in the
+	call of cc-cross-prefix.
+	This functionality is useful for architecture Makefiles that try
+	to set CROSS_COMPILE to well-known values but may have several
+	values to select between.
+	It is recommended only to try to set CROSS_COMPILE if it is a cross
+	build (host arch is different from target arch). And if CROSS_COMPILE
+	is already set then leave it with the old value.
+
+	Example:
+		#arch/m68k/Makefile
+		ifneq ($(SUBARCH),$(ARCH))
+		        ifeq ($(CROSS_COMPILE),)
+		               CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu-)
+			endif
+		endif
+
 === 4 Host Program support
 
 Kbuild supports building executables on the host for use during the
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
index 1b37b28..d0ac72c 100644
--- a/Documentation/kdump/kdump.txt
+++ b/Documentation/kdump/kdump.txt
@@ -231,6 +231,32 @@
   any space below the alignment point will be wasted.
 
 
+Extended crashkernel syntax
+===========================
+
+While the "crashkernel=size[@offset]" syntax is sufficient for most
+configurations, sometimes it's handy to have the reserved memory dependent
+on the value of System RAM -- that's mostly for distributors that pre-setup
+the kernel command line to avoid a unbootable system after some memory has
+been removed from the machine.
+
+The syntax is:
+
+    crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset]
+    range=start-[end]
+
+For example:
+
+    crashkernel=512M-2G:64M,2G-:128M
+
+This would mean:
+
+    1) if the RAM is smaller than 512M, then don't reserve anything
+       (this is the "rescue" case)
+    2) if the RAM size is between 512M and 2G, then reserve 64M
+    3) if the RAM size is larger than 2G, then reserve 128M
+
+
 Boot into System Kernel
 =======================
 
diff --git a/Documentation/kernel-docs.txt b/Documentation/kernel-docs.txt
index d9e3b19..5a4ef48 100644
--- a/Documentation/kernel-docs.txt
+++ b/Documentation/kernel-docs.txt
@@ -76,9 +76,9 @@
      * Title: "Conceptual Architecture of the Linux Kernel"
        Author: Ivan T. Bowman.
        URL: http://plg.uwaterloo.ca/~itbowman/papers/CS746G-a1.html
-       Keywords: conceptual software arquitecture, extracted design,
+       Keywords: conceptual software architecture, extracted design,
        reverse engineering, system structure.
-       Description: Conceptual software arquitecture of the Linux kernel,
+       Description: Conceptual software architecture of the Linux kernel,
        automatically extracted from the source code. Very detailed. Good
        figures. Gives good overall kernel understanding.
 
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 98cf90f..b236166 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -222,9 +222,6 @@
 			Warning: Many of these options can produce a lot of
 			output and make your system unusable. Be very careful.
 
-
-	acpi_fake_ecdt	[HW,ACPI] Workaround failure due to BIOS lacking ECDT
-
 	acpi_pm_good	[X86-32,X86-64]
 			Override the pmtimer bug detection: force the kernel
 			to assume that this machine's pmtimer latches its value
@@ -297,9 +294,6 @@
 	apm=		[APM] Advanced Power Management
 			See header of arch/i386/kernel/apm.c.
 
-	applicom=	[HW]
-			Format: <mem>,<irq>
-
 	arcrimi=	[HW,NET] ARCnet - "RIM I" (entirely mem-mapped) cards
 			Format: <io>,<irq>,<nodeID>
 
@@ -345,12 +339,6 @@
 			Format: <io>,<irq>,<mode>
 			See header of drivers/net/hamradio/baycom_ser_hdx.c.
 
-	blkmtd_device=	[HW,MTD]
-	blkmtd_erasesz=
-	blkmtd_ro=
-	blkmtd_bs=
-	blkmtd_count=
-
 	boot_delay=	Milliseconds to delay each printk during boot.
 			Values larger than 10 seconds (10000) are changed to
 			no delay (0).
@@ -431,8 +419,10 @@
 			over the 8254 in addition to over the IO-APIC. The
 			kernel tries to set a sensible default.
 
-	hpet=		[X86-32,HPET] option to disable HPET and use PIT.
-			Format: disable
+	hpet=		[X86-32,HPET] option to control HPET usage
+			Format: { enable (default) | disable | force }
+			disable: disable HPET and use PIT instead
+			force: allow force enabled of undocumented chips (ICH4, VIA)
 
 	com20020=	[HW,NET] ARCnet - COM20020 chipset
 			Format:
@@ -479,6 +469,16 @@
 			UART at the specified I/O port or MMIO address.
 			The options are the same as for ttyS, above.
 
+	no_console_suspend
+			[HW] Never suspend the console
+			Disable suspending of consoles during suspend and
+			hibernate operations.  Once disabled, debugging
+			messages can reach various consoles while the rest
+			of the system is being put to sleep (ie, while
+			debugging driver suspend/resume hooks).  This may
+			not work reliably with all consoles, but is known
+			to work with serial and VGA consoles.
+
 	cpcihp_generic=	[HW,PCI] Generic port I/O CompactPCI driver
 			Format:
 			<first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
@@ -487,6 +487,13 @@
 			[KNL] Reserve a chunk of physical memory to
 			hold a kernel to switch to with kexec on panic.
 
+	crashkernel=range1:size1[,range2:size2,...][@offset]
+			[KNL] Same as above, but depends on the memory
+			in the running system. The syntax of range is
+			start-[end] where start and end are both
+			a memory unit (amount[KMG]). See also
+			Documentation/kdump/kdump.txt for a example.
+
 	cs4232=		[HW,OSS]
 			Format: <io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>
 
@@ -496,8 +503,6 @@
 	cs89x0_media=	[HW,NET]
 			Format: { rj45 | aui | bnc }
 
-	cyclades=	[HW,SERIAL] Cyclades multi-serial port adapter.
-
 	dasd=		[HW,NET]
 			See header of drivers/s390/block/dasd_devmap.c.
 
@@ -555,10 +560,6 @@
 			See drivers/char/README.epca and
 			Documentation/digiepca.txt.
 
-	dmascc=		[HW,AX25,SERIAL] AX.25 Z80SCC driver with DMA
-			support available.
-			Format: <io_dev0>[,<io_dev1>[,..<io_dev32>]]
-
 	dmasound=	[HW,OSS] Sound subsystem buffers
 
 	dscc4.setup=	[NET]
@@ -589,17 +590,10 @@
 			0: polling mode
 			non-0: interrupt mode (default)
 
-	eda=		[HW,PS2]
-
-	edb=		[HW,PS2]
-
 	edd=		[EDD]
 			Format: {"of[f]" | "sk[ipmbr]"}
 			See comment in arch/i386/boot/edd.S
 
-	eicon=		[HW,ISDN]
-			Format: <id>,<membase>,<irq>
-
 	eisa_irq_edge=	[PARISC,HW]
 			See header of drivers/parisc/eisa.c.
 
@@ -778,6 +772,23 @@
 
 	inttest=	[IA64]
 
+	intel_iommu=	[DMAR] Intel IOMMU driver (DMAR) option
+		off
+			Disable intel iommu driver.
+		igfx_off [Default Off]
+			By default, gfx is mapped as normal device. If a gfx
+			device has a dedicated DMAR unit, the DMAR unit is
+			bypassed by not enabling DMAR with this option. In
+			this case, gfx device will use physical address for
+			DMA.
+		forcedac [x86_64]
+			With this option iommu will not optimize to look
+			for io virtual address below 32 bit forcing dual
+			address cycle on pci bus for cards supporting greater
+			than 32 bit addressing. The default is to look
+			for translation below 32 bit and if not available
+			then look in the higher range.
+
 	io7=		[HW] IO7 for Marvel based alpha systems
 			See comment before marvel_specify_io7 in
 			arch/alpha/kernel/core_marvel.c.
@@ -875,9 +886,6 @@
 	lapic_timer_c2_ok	[X86-32,x86-64,APIC] trust the local apic timer in
 			C2 power state.
 
-	lasi=		[HW,SCSI] PARISC LASI driver for the 53c700 chip
-			Format: addr:<io>,irq:<irq>
-
 	libata.noacpi	[LIBATA] Disables use of ACPI in libata suspend/resume
 			when set.
 			Format: <int>
@@ -1125,9 +1133,6 @@
 	noapic		[SMP,APIC] Tells the kernel to not make use of any
 			IOAPICs that may be present in the system.
 
-	noasync		[HW,M68K] Disables async and sync negotiation for
-			all devices.
-
 	nobats		[PPC] Do not use BATs for mapping kernel lowmem
 			on "Classic" PPC cores.
 
@@ -1439,6 +1444,7 @@
 			Param: <number> - step/bucket size as a power of 2 for
 				statistical time based profiling.
 			Param: "sleep" - profile D-state sleeping (millisecs)
+			Param: "kvm" - profile VM exits.
 
 	processor.max_cstate=	[HW,ACPI]
 			Limit processor to maximum C-state
@@ -1565,9 +1571,6 @@
 	sa1100ir	[NET]
 			See drivers/net/irda/sa1100_ir.c.
 
-	sb=		[HW,OSS]
-			Format: <io>,<irq>,<dma>,<dma2>
-
 	sbni=		[NET] Granch SBNI12 leased line adapter
 
 	sc1200wdt=	[HW,WDT] SC1200 WDT (watchdog) driver
@@ -1611,8 +1614,6 @@
 
 	serialnumber	[BUGS=X86-32]
 
-	sg_def_reserved_size=	[SCSI]
-
 	shapers=	[NET]
 			Maximal number of shapers.
 
@@ -2003,10 +2004,6 @@
 	norandmaps	Don't use address space randomization
 			Equivalent to echo 0 > /proc/sys/kernel/randomize_va_space
 
- 	unwind_debug=N 	N > 0 will enable dwarf2 unwinder debugging
-			This is useful to get more information why
-			you got a "dwarf2 unwinder stuck"
-
 ______________________________________________________________________
 
 TODO:
diff --git a/Documentation/lguest/Makefile b/Documentation/lguest/Makefile
index c0b7a45..bac037e 100644
--- a/Documentation/lguest/Makefile
+++ b/Documentation/lguest/Makefile
@@ -1,28 +1,8 @@
 # This creates the demonstration utility "lguest" which runs a Linux guest.
-
-# For those people that have a separate object dir, look there for .config
-KBUILD_OUTPUT := ../..
-ifdef O
-  ifeq ("$(origin O)", "command line")
-    KBUILD_OUTPUT := $(O)
-  endif
-endif
-# We rely on CONFIG_PAGE_OFFSET to know where to put lguest binary.
-include $(KBUILD_OUTPUT)/.config
-LGUEST_GUEST_TOP := ($(CONFIG_PAGE_OFFSET) - 0x08000000)
-
-CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -Wl,-T,lguest.lds
+CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -I../../include
 LDLIBS:=-lz
-# Removing this works for some versions of ld.so (eg. Ubuntu Feisty) and
-# not others (eg. FC7).
-LDFLAGS+=-static
-all: lguest.lds lguest
 
-# The linker script on x86 is so complex the only way of creating one
-# which will link our binary in the right place is to mangle the
-# default one.
-lguest.lds:
-	$(LD) --verbose | awk '/^==========/ { PRINT=1; next; } /SIZEOF_HEADERS/ { gsub(/0x[0-9A-F]*/, "$(LGUEST_GUEST_TOP)") } { if (PRINT) print $$0; }' > $@
+all: lguest
 
 clean:
-	rm -f lguest.lds lguest
+	rm -f lguest
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 103e346..5bdc37f 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -1,10 +1,7 @@
 /*P:100 This is the Launcher code, a simple program which lays out the
  * "physical" memory for the new Guest by mapping the kernel image and the
  * virtual devices, then reads repeatedly from /dev/lguest to run the Guest.
- *
- * The only trick: the Makefile links it at a high address so it will be clear
- * of the guest memory region.  It means that each Guest cannot have more than
- * about 2.5G of memory on a normally configured Host. :*/
+:*/
 #define _LARGEFILE64_SOURCE
 #define _GNU_SOURCE
 #include <stdio.h>
@@ -15,6 +12,7 @@
 #include <stdlib.h>
 #include <elf.h>
 #include <sys/mman.h>
+#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
@@ -34,7 +32,9 @@
 #include <termios.h>
 #include <getopt.h>
 #include <zlib.h>
-/*L:110 We can ignore the 28 include files we need for this program, but I do
+#include <assert.h>
+#include <sched.h>
+/*L:110 We can ignore the 30 include files we need for this program, but I do
  * want to draw attention to the use of kernel-style types.
  *
  * As Linus said, "C is a Spartan language, and so should your naming be."  I
@@ -45,8 +45,14 @@
 typedef uint32_t u32;
 typedef uint16_t u16;
 typedef uint8_t u8;
-#include "../../include/linux/lguest_launcher.h"
-#include "../../include/asm-x86/e820_32.h"
+#include "linux/lguest_launcher.h"
+#include "linux/pci_ids.h"
+#include "linux/virtio_config.h"
+#include "linux/virtio_net.h"
+#include "linux/virtio_blk.h"
+#include "linux/virtio_console.h"
+#include "linux/virtio_ring.h"
+#include "asm-x86/bootparam.h"
 /*:*/
 
 #define PAGE_PRESENT 0x7 	/* Present, RW, Execute */
@@ -55,6 +61,10 @@
 #ifndef SIOCBRADDIF
 #define SIOCBRADDIF	0x89a2		/* add interface to bridge      */
 #endif
+/* We can have up to 256 pages for devices. */
+#define DEVICE_PAGES 256
+/* This fits nicely in a single 4096-byte page. */
+#define VIRTQUEUE_NUM 127
 
 /*L:120 verbose is both a global flag and a macro.  The C preprocessor allows
  * this, and although I wouldn't recommend it, it works quite nicely here. */
@@ -65,8 +75,10 @@
 
 /* The pipe to send commands to the waker process */
 static int waker_fd;
-/* The top of guest physical memory. */
-static u32 top;
+/* The pointer to the start of guest memory. */
+static void *guest_base;
+/* The maximum guest physical address allowed, and maximum possible. */
+static unsigned long guest_limit, guest_max;
 
 /* This is our list of devices. */
 struct device_list
@@ -76,8 +88,17 @@
 	fd_set infds;
 	int max_infd;
 
+	/* Counter to assign interrupt numbers. */
+	unsigned int next_irq;
+
+	/* Counter to print out convenient device numbers. */
+	unsigned int device_num;
+
 	/* The descriptor page for the devices. */
-	struct lguest_device_desc *descs;
+	u8 *descpage;
+
+	/* The tail of the last descriptor. */
+	unsigned int desc_used;
 
 	/* A single linked list of devices. */
 	struct device *dev;
@@ -85,31 +106,111 @@
 	struct device **lastdev;
 };
 
+/* The list of Guest devices, based on command line arguments. */
+static struct device_list devices;
+
 /* The device structure describes a single device. */
 struct device
 {
 	/* The linked-list pointer. */
 	struct device *next;
-	/* The descriptor for this device, as mapped into the Guest. */
+
+	/* The this device's descriptor, as mapped into the Guest. */
 	struct lguest_device_desc *desc;
-	/* The memory page(s) of this device, if any.  Also mapped in Guest. */
-	void *mem;
+
+	/* The name of this device, for --verbose. */
+	const char *name;
 
 	/* If handle_input is set, it wants to be called when this file
 	 * descriptor is ready. */
 	int fd;
 	bool (*handle_input)(int fd, struct device *me);
 
-	/* If handle_output is set, it wants to be called when the Guest sends
-	 * DMA to this key. */
-	unsigned long watch_key;
-	u32 (*handle_output)(int fd, const struct iovec *iov,
-			     unsigned int num, struct device *me);
+	/* Any queues attached to this device */
+	struct virtqueue *vq;
 
 	/* Device-specific data. */
 	void *priv;
 };
 
+/* The virtqueue structure describes a queue attached to a device. */
+struct virtqueue
+{
+	struct virtqueue *next;
+
+	/* Which device owns me. */
+	struct device *dev;
+
+	/* The configuration for this queue. */
+	struct lguest_vqconfig config;
+
+	/* The actual ring of buffers. */
+	struct vring vring;
+
+	/* Last available index we saw. */
+	u16 last_avail_idx;
+
+	/* The routine to call when the Guest pings us. */
+	void (*handle_output)(int fd, struct virtqueue *me);
+};
+
+/* Since guest is UP and we don't run at the same time, we don't need barriers.
+ * But I include them in the code in case others copy it. */
+#define wmb()
+
+/* Convert an iovec element to the given type.
+ *
+ * This is a fairly ugly trick: we need to know the size of the type and
+ * alignment requirement to check the pointer is kosher.  It's also nice to
+ * have the name of the type in case we report failure.
+ *
+ * Typing those three things all the time is cumbersome and error prone, so we
+ * have a macro which sets them all up and passes to the real function. */
+#define convert(iov, type) \
+	((type *)_convert((iov), sizeof(type), __alignof__(type), #type))
+
+static void *_convert(struct iovec *iov, size_t size, size_t align,
+		      const char *name)
+{
+	if (iov->iov_len != size)
+		errx(1, "Bad iovec size %zu for %s", iov->iov_len, name);
+	if ((unsigned long)iov->iov_base % align != 0)
+		errx(1, "Bad alignment %p for %s", iov->iov_base, name);
+	return iov->iov_base;
+}
+
+/* The virtio configuration space is defined to be little-endian.  x86 is
+ * little-endian too, but it's nice to be explicit so we have these helpers. */
+#define cpu_to_le16(v16) (v16)
+#define cpu_to_le32(v32) (v32)
+#define cpu_to_le64(v64) (v64)
+#define le16_to_cpu(v16) (v16)
+#define le32_to_cpu(v32) (v32)
+#define le64_to_cpu(v32) (v64)
+
+/*L:100 The Launcher code itself takes us out into userspace, that scary place
+ * where pointers run wild and free!  Unfortunately, like most userspace
+ * programs, it's quite boring (which is why everyone likes to hack on the
+ * kernel!).  Perhaps if you make up an Lguest Drinking Game at this point, it
+ * will get you through this section.  Or, maybe not.
+ *
+ * The Launcher sets up a big chunk of memory to be the Guest's "physical"
+ * memory and stores it in "guest_base".  In other words, Guest physical ==
+ * Launcher virtual with an offset.
+ *
+ * This can be tough to get your head around, but usually it just means that we
+ * use these trivial conversion functions when the Guest gives us it's
+ * "physical" addresses: */
+static void *from_guest_phys(unsigned long addr)
+{
+	return guest_base + addr;
+}
+
+static unsigned long to_guest_phys(const void *addr)
+{
+	return (addr - guest_base);
+}
+
 /*L:130
  * Loading the Kernel.
  *
@@ -123,43 +224,55 @@
 	return fd;
 }
 
-/* map_zeroed_pages() takes a (page-aligned) address and a number of pages. */
-static void *map_zeroed_pages(unsigned long addr, unsigned int num)
+/* map_zeroed_pages() takes a number of pages. */
+static void *map_zeroed_pages(unsigned int num)
 {
-	/* We cache the /dev/zero file-descriptor so we only open it once. */
-	static int fd = -1;
-
-	if (fd == -1)
-		fd = open_or_die("/dev/zero", O_RDONLY);
+	int fd = open_or_die("/dev/zero", O_RDONLY);
+	void *addr;
 
 	/* We use a private mapping (ie. if we write to the page, it will be
-	 * copied), and obviously we insist that it be mapped where we ask. */
-	if (mmap((void *)addr, getpagesize() * num,
-		 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, fd, 0)
-	    != (void *)addr)
-		err(1, "Mmaping %u pages of /dev/zero @%p", num, (void *)addr);
+	 * copied). */
+	addr = mmap(NULL, getpagesize() * num,
+		    PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0);
+	if (addr == MAP_FAILED)
+		err(1, "Mmaping %u pages of /dev/zero", num);
 
-	/* Returning the address is just a courtesy: can simplify callers. */
-	return (void *)addr;
+	return addr;
 }
 
-/* To find out where to start we look for the magic Guest string, which marks
- * the code we see in lguest_asm.S.  This is a hack which we are currently
- * plotting to replace with the normal Linux entry point. */
-static unsigned long entry_point(void *start, void *end,
-				 unsigned long page_offset)
+/* Get some more pages for a device. */
+static void *get_pages(unsigned int num)
 {
-	void *p;
+	void *addr = from_guest_phys(guest_limit);
 
-	/* The scan gives us the physical starting address.  We want the
-	 * virtual address in this case, and fortunately, we already figured
-	 * out the physical-virtual difference and passed it here in
-	 * "page_offset". */
-	for (p = start; p < end; p++)
-		if (memcmp(p, "GenuineLguest", strlen("GenuineLguest")) == 0)
-			return (long)p + strlen("GenuineLguest") + page_offset;
+	guest_limit += num * getpagesize();
+	if (guest_limit > guest_max)
+		errx(1, "Not enough memory for devices");
+	return addr;
+}
 
-	err(1, "Is this image a genuine lguest?");
+/* This routine is used to load the kernel or initrd.  It tries mmap, but if
+ * that fails (Plan 9's kernel file isn't nicely aligned on page boundaries),
+ * it falls back to reading the memory in. */
+static void map_at(int fd, void *addr, unsigned long offset, unsigned long len)
+{
+	ssize_t r;
+
+	/* We map writable even though for some segments are marked read-only.
+	 * The kernel really wants to be writable: it patches its own
+	 * instructions.
+	 *
+	 * MAP_PRIVATE means that the page won't be copied until a write is
+	 * done to it.  This allows us to share untouched memory between
+	 * Guests. */
+	if (mmap(addr, len, PROT_READ|PROT_WRITE|PROT_EXEC,
+		 MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED)
+		return;
+
+	/* pread does a seek and a read in one shot: saves a few lines. */
+	r = pread(fd, addr, len, offset);
+	if (r != len)
+		err(1, "Reading offset %lu len %lu gave %zi", offset, len, r);
 }
 
 /* This routine takes an open vmlinux image, which is in ELF, and maps it into
@@ -167,19 +280,14 @@
  * by all modern binaries on Linux including the kernel.
  *
  * The ELF headers give *two* addresses: a physical address, and a virtual
- * address.  The Guest kernel expects to be placed in memory at the physical
- * address, and the page tables set up so it will correspond to that virtual
- * address.  We return the difference between the virtual and physical
- * addresses in the "page_offset" pointer.
+ * address.  We use the physical address; the Guest will map itself to the
+ * virtual address.
  *
  * We return the starting address. */
-static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr,
-			     unsigned long *page_offset)
+static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr)
 {
-	void *addr;
 	Elf32_Phdr phdr[ehdr->e_phnum];
 	unsigned int i;
-	unsigned long start = -1UL, end = 0;
 
 	/* Sanity checks on the main ELF header: an x86 executable with a
 	 * reasonable number of correctly-sized program headers. */
@@ -199,9 +307,6 @@
 	if (read(elf_fd, phdr, sizeof(phdr)) != sizeof(phdr))
 		err(1, "Reading program headers");
 
-	/* We don't know page_offset yet. */
-	*page_offset = 0;
-
 	/* Try all the headers: there are usually only three.  A read-only one,
 	 * a read-write one, and a "note" section which isn't loadable. */
 	for (i = 0; i < ehdr->e_phnum; i++) {
@@ -212,158 +317,53 @@
 		verbose("Section %i: size %i addr %p\n",
 			i, phdr[i].p_memsz, (void *)phdr[i].p_paddr);
 
-		/* We expect a simple linear address space: every segment must
-		 * have the same difference between virtual (p_vaddr) and
-		 * physical (p_paddr) address. */
-		if (!*page_offset)
-			*page_offset = phdr[i].p_vaddr - phdr[i].p_paddr;
-		else if (*page_offset != phdr[i].p_vaddr - phdr[i].p_paddr)
-			errx(1, "Page offset of section %i different", i);
-
-		/* We track the first and last address we mapped, so we can
-		 * tell entry_point() where to scan. */
-		if (phdr[i].p_paddr < start)
-			start = phdr[i].p_paddr;
-		if (phdr[i].p_paddr + phdr[i].p_filesz > end)
-			end = phdr[i].p_paddr + phdr[i].p_filesz;
-
-		/* We map this section of the file at its physical address.  We
-		 * map it read & write even if the header says this segment is
-		 * read-only.  The kernel really wants to be writable: it
-		 * patches its own instructions which would normally be
-		 * read-only.
-		 *
-		 * MAP_PRIVATE means that the page won't be copied until a
-		 * write is done to it.  This allows us to share much of the
-		 * kernel memory between Guests. */
-		addr = mmap((void *)phdr[i].p_paddr,
-			    phdr[i].p_filesz,
-			    PROT_READ|PROT_WRITE|PROT_EXEC,
-			    MAP_FIXED|MAP_PRIVATE,
-			    elf_fd, phdr[i].p_offset);
-		if (addr != (void *)phdr[i].p_paddr)
-			err(1, "Mmaping vmlinux seg %i gave %p not %p",
-			    i, addr, (void *)phdr[i].p_paddr);
+		/* We map this section of the file at its physical address. */
+		map_at(elf_fd, from_guest_phys(phdr[i].p_paddr),
+		       phdr[i].p_offset, phdr[i].p_filesz);
 	}
 
-	return entry_point((void *)start, (void *)end, *page_offset);
-}
-
-/*L:170 Prepare to be SHOCKED and AMAZED.  And possibly a trifle nauseated.
- *
- * We know that CONFIG_PAGE_OFFSET sets what virtual address the kernel expects
- * to be.  We don't know what that option was, but we can figure it out
- * approximately by looking at the addresses in the code.  I chose the common
- * case of reading a memory location into the %eax register:
- *
- *  movl <some-address>, %eax
- *
- * This gets encoded as five bytes: "0xA1 <4-byte-address>".  For example,
- * "0xA1 0x18 0x60 0x47 0xC0" reads the address 0xC0476018 into %eax.
- *
- * In this example can guess that the kernel was compiled with
- * CONFIG_PAGE_OFFSET set to 0xC0000000 (it's always a round number).  If the
- * kernel were larger than 16MB, we might see 0xC1 addresses show up, but our
- * kernel isn't that bloated yet.
- *
- * Unfortunately, x86 has variable-length instructions, so finding this
- * particular instruction properly involves writing a disassembler.  Instead,
- * we rely on statistics.  We look for "0xA1" and tally the different bytes
- * which occur 4 bytes later (the "0xC0" in our example above).  When one of
- * those bytes appears three times, we can be reasonably confident that it
- * forms the start of CONFIG_PAGE_OFFSET.
- *
- * This is amazingly reliable. */
-static unsigned long intuit_page_offset(unsigned char *img, unsigned long len)
-{
-	unsigned int i, possibilities[256] = { 0 };
-
-	for (i = 0; i + 4 < len; i++) {
-		/* mov 0xXXXXXXXX,%eax */
-		if (img[i] == 0xA1 && ++possibilities[img[i+4]] > 3)
-			return (unsigned long)img[i+4] << 24;
-	}
-	errx(1, "could not determine page offset");
-}
-
-/*L:160 Unfortunately the entire ELF image isn't compressed: the segments
- * which need loading are extracted and compressed raw.  This denies us the
- * information we need to make a fully-general loader. */
-static unsigned long unpack_bzimage(int fd, unsigned long *page_offset)
-{
-	gzFile f;
-	int ret, len = 0;
-	/* A bzImage always gets loaded at physical address 1M.  This is
-	 * actually configurable as CONFIG_PHYSICAL_START, but as the comment
-	 * there says, "Don't change this unless you know what you are doing".
-	 * Indeed. */
-	void *img = (void *)0x100000;
-
-	/* gzdopen takes our file descriptor (carefully placed at the start of
-	 * the GZIP header we found) and returns a gzFile. */
-	f = gzdopen(fd, "rb");
-	/* We read it into memory in 64k chunks until we hit the end. */
-	while ((ret = gzread(f, img + len, 65536)) > 0)
-		len += ret;
-	if (ret < 0)
-		err(1, "reading image from bzImage");
-
-	verbose("Unpacked size %i addr %p\n", len, img);
-
-	/* Without the ELF header, we can't tell virtual-physical gap.  This is
-	 * CONFIG_PAGE_OFFSET, and people do actually change it.  Fortunately,
-	 * I have a clever way of figuring it out from the code itself.  */
-	*page_offset = intuit_page_offset(img, len);
-
-	return entry_point(img, img + len, *page_offset);
+	/* The entry point is given in the ELF header. */
+	return ehdr->e_entry;
 }
 
 /*L:150 A bzImage, unlike an ELF file, is not meant to be loaded.  You're
- * supposed to jump into it and it will unpack itself.  We can't do that
- * because the Guest can't run the unpacking code, and adding features to
- * lguest kills puppies, so we don't want to.
+ * supposed to jump into it and it will unpack itself.  We used to have to
+ * perform some hairy magic because the unpacking code scared me.
  *
- * The bzImage is formed by putting the decompressing code in front of the
- * compressed kernel code.  So we can simple scan through it looking for the
- * first "gzip" header, and start decompressing from there. */
-static unsigned long load_bzimage(int fd, unsigned long *page_offset)
+ * Fortunately, Jeremy Fitzhardinge convinced me it wasn't that hard and wrote
+ * a small patch to jump over the tricky bits in the Guest, so now we just read
+ * the funky header so we know where in the file to load, and away we go! */
+static unsigned long load_bzimage(int fd)
 {
-	unsigned char c;
-	int state = 0;
+	struct boot_params boot;
+	int r;
+	/* Modern bzImages get loaded at 1M. */
+	void *p = from_guest_phys(0x100000);
 
-	/* GZIP header is 0x1F 0x8B <method> <flags>... <compressed-by>. */
-	while (read(fd, &c, 1) == 1) {
-		switch (state) {
-		case 0:
-			if (c == 0x1F)
-				state++;
-			break;
-		case 1:
-			if (c == 0x8B)
-				state++;
-			else
-				state = 0;
-			break;
-		case 2 ... 8:
-			state++;
-			break;
-		case 9:
-			/* Seek back to the start of the gzip header. */
-			lseek(fd, -10, SEEK_CUR);
-			/* One final check: "compressed under UNIX". */
-			if (c != 0x03)
-				state = -1;
-			else
-				return unpack_bzimage(fd, page_offset);
-		}
-	}
-	errx(1, "Could not find kernel in bzImage");
+	/* Go back to the start of the file and read the header.  It should be
+	 * a Linux boot header (see Documentation/i386/boot.txt) */
+	lseek(fd, 0, SEEK_SET);
+	read(fd, &boot, sizeof(boot));
+
+	/* Inside the setup_hdr, we expect the magic "HdrS" */
+	if (memcmp(&boot.hdr.header, "HdrS", 4) != 0)
+		errx(1, "This doesn't look like a bzImage to me");
+
+	/* Skip over the extra sectors of the header. */
+	lseek(fd, (boot.hdr.setup_sects+1) * 512, SEEK_SET);
+
+	/* Now read everything into memory. in nice big chunks. */
+	while ((r = read(fd, p, 65536)) > 0)
+		p += r;
+
+	/* Finally, code32_start tells us where to enter the kernel. */
+	return boot.hdr.code32_start;
 }
 
 /*L:140 Loading the kernel is easy when it's a "vmlinux", but most kernels
  * come wrapped up in the self-decompressing "bzImage" format.  With some funky
  * coding, we can load those, too. */
-static unsigned long load_kernel(int fd, unsigned long *page_offset)
+static unsigned long load_kernel(int fd)
 {
 	Elf32_Ehdr hdr;
 
@@ -373,10 +373,10 @@
 
 	/* If it's an ELF file, it starts with "\177ELF" */
 	if (memcmp(hdr.e_ident, ELFMAG, SELFMAG) == 0)
-		return map_elf(fd, &hdr, page_offset);
+		return map_elf(fd, &hdr);
 
 	/* Otherwise we assume it's a bzImage, and try to unpack it */
-	return load_bzimage(fd, page_offset);
+	return load_bzimage(fd);
 }
 
 /* This is a trivial little helper to align pages.  Andi Kleen hated it because
@@ -402,59 +402,45 @@
 	int ifd;
 	struct stat st;
 	unsigned long len;
-	void *iaddr;
 
 	ifd = open_or_die(name, O_RDONLY);
 	/* fstat() is needed to get the file size. */
 	if (fstat(ifd, &st) < 0)
 		err(1, "fstat() on initrd '%s'", name);
 
-	/* The length needs to be rounded up to a page size: mmap needs the
-	 * address to be page aligned. */
+	/* We map the initrd at the top of memory, but mmap wants it to be
+	 * page-aligned, so we round the size up for that. */
 	len = page_align(st.st_size);
-	/* We map the initrd at the top of memory. */
-	iaddr = mmap((void *)mem - len, st.st_size,
-		     PROT_READ|PROT_EXEC|PROT_WRITE,
-		     MAP_FIXED|MAP_PRIVATE, ifd, 0);
-	if (iaddr != (void *)mem - len)
-		err(1, "Mmaping initrd '%s' returned %p not %p",
-		    name, iaddr, (void *)mem - len);
+	map_at(ifd, from_guest_phys(mem - len), 0, st.st_size);
 	/* Once a file is mapped, you can close the file descriptor.  It's a
 	 * little odd, but quite useful. */
 	close(ifd);
-	verbose("mapped initrd %s size=%lu @ %p\n", name, st.st_size, iaddr);
+	verbose("mapped initrd %s size=%lu @ %p\n", name, len, (void*)mem-len);
 
 	/* We return the initrd size. */
 	return len;
 }
 
-/* Once we know how much memory we have, and the address the Guest kernel
- * expects, we can construct simple linear page tables which will get the Guest
- * far enough into the boot to create its own.
+/* Once we know how much memory we have, we can construct simple linear page
+ * tables which set virtual == physical which will get the Guest far enough
+ * into the boot to create its own.
  *
  * We lay them out of the way, just below the initrd (which is why we need to
  * know its size). */
 static unsigned long setup_pagetables(unsigned long mem,
-				      unsigned long initrd_size,
-				      unsigned long page_offset)
+				      unsigned long initrd_size)
 {
-	u32 *pgdir, *linear;
+	unsigned long *pgdir, *linear;
 	unsigned int mapped_pages, i, linear_pages;
-	unsigned int ptes_per_page = getpagesize()/sizeof(u32);
+	unsigned int ptes_per_page = getpagesize()/sizeof(void *);
 
-	/* Ideally we map all physical memory starting at page_offset.
-	 * However, if page_offset is 0xC0000000 we can only map 1G of physical
-	 * (0xC0000000 + 1G overflows). */
-	if (mem <= -page_offset)
-		mapped_pages = mem/getpagesize();
-	else
-		mapped_pages = -page_offset/getpagesize();
+	mapped_pages = mem/getpagesize();
 
 	/* Each PTE page can map ptes_per_page pages: how many do we need? */
 	linear_pages = (mapped_pages + ptes_per_page-1)/ptes_per_page;
 
 	/* We put the toplevel page directory page at the top of memory. */
-	pgdir = (void *)mem - initrd_size - getpagesize();
+	pgdir = from_guest_phys(mem) - initrd_size - getpagesize();
 
 	/* Now we use the next linear_pages pages as pte pages */
 	linear = (void *)pgdir - linear_pages*getpagesize();
@@ -465,20 +451,19 @@
 	for (i = 0; i < mapped_pages; i++)
 		linear[i] = ((i * getpagesize()) | PAGE_PRESENT);
 
-	/* The top level points to the linear page table pages above.  The
-	 * entry representing page_offset points to the first one, and they
-	 * continue from there. */
+	/* The top level points to the linear page table pages above. */
 	for (i = 0; i < mapped_pages; i += ptes_per_page) {
-		pgdir[(i + page_offset/getpagesize())/ptes_per_page]
-			= (((u32)linear + i*sizeof(u32)) | PAGE_PRESENT);
+		pgdir[i/ptes_per_page]
+			= ((to_guest_phys(linear) + i*sizeof(void *))
+			   | PAGE_PRESENT);
 	}
 
-	verbose("Linear mapping of %u pages in %u pte pages at %p\n",
-		mapped_pages, linear_pages, linear);
+	verbose("Linear mapping of %u pages in %u pte pages at %#lx\n",
+		mapped_pages, linear_pages, to_guest_phys(linear));
 
 	/* We return the top level (guest-physical) address: the kernel needs
 	 * to know where it is. */
-	return (unsigned long)pgdir;
+	return to_guest_phys(pgdir);
 }
 
 /* Simple routine to roll all the commandline arguments together with spaces
@@ -498,14 +483,17 @@
 
 /* This is where we actually tell the kernel to initialize the Guest.  We saw
  * the arguments it expects when we looked at initialize() in lguest_user.c:
- * the top physical page to allow, the top level pagetable, the entry point and
- * the page_offset constant for the Guest. */
-static int tell_kernel(u32 pgdir, u32 start, u32 page_offset)
+ * the base of guest "physical" memory, the top physical page to allow, the
+ * top level pagetable and the entry point for the Guest. */
+static int tell_kernel(unsigned long pgdir, unsigned long start)
 {
-	u32 args[] = { LHREQ_INITIALIZE,
-		       top/getpagesize(), pgdir, start, page_offset };
+	unsigned long args[] = { LHREQ_INITIALIZE,
+				 (unsigned long)guest_base,
+				 guest_limit / getpagesize(), pgdir, start };
 	int fd;
 
+	verbose("Guest: %p - %p (%#lx)\n",
+		guest_base, guest_base + guest_limit, guest_limit);
 	fd = open_or_die("/dev/lguest", O_RDWR);
 	if (write(fd, args, sizeof(args)) < 0)
 		err(1, "Writing to /dev/lguest");
@@ -515,11 +503,11 @@
 }
 /*:*/
 
-static void set_fd(int fd, struct device_list *devices)
+static void add_device_fd(int fd)
 {
-	FD_SET(fd, &devices->infds);
-	if (fd > devices->max_infd)
-		devices->max_infd = fd;
+	FD_SET(fd, &devices.infds);
+	if (fd > devices.max_infd)
+		devices.max_infd = fd;
 }
 
 /*L:200
@@ -537,36 +525,38 @@
  *
  * This, of course, is merely a different *kind* of icky.
  */
-static void wake_parent(int pipefd, int lguest_fd, struct device_list *devices)
+static void wake_parent(int pipefd, int lguest_fd)
 {
 	/* Add the pipe from the Launcher to the fdset in the device_list, so
 	 * we watch it, too. */
-	set_fd(pipefd, devices);
+	add_device_fd(pipefd);
 
 	for (;;) {
-		fd_set rfds = devices->infds;
-		u32 args[] = { LHREQ_BREAK, 1 };
+		fd_set rfds = devices.infds;
+		unsigned long args[] = { LHREQ_BREAK, 1 };
 
 		/* Wait until input is ready from one of the devices. */
-		select(devices->max_infd+1, &rfds, NULL, NULL, NULL);
+		select(devices.max_infd+1, &rfds, NULL, NULL, NULL);
 		/* Is it a message from the Launcher? */
 		if (FD_ISSET(pipefd, &rfds)) {
-			int ignorefd;
+			int fd;
 			/* If read() returns 0, it means the Launcher has
 			 * exited.  We silently follow. */
-			if (read(pipefd, &ignorefd, sizeof(ignorefd)) == 0)
+			if (read(pipefd, &fd, sizeof(fd)) == 0)
 				exit(0);
-			/* Otherwise it's telling us there's a problem with one
-			 * of the devices, and we should ignore that file
-			 * descriptor from now on. */
-			FD_CLR(ignorefd, &devices->infds);
+			/* Otherwise it's telling us to change what file
+			 * descriptors we're to listen to. */
+			if (fd >= 0)
+				FD_SET(fd, &devices.infds);
+			else
+				FD_CLR(-fd - 1, &devices.infds);
 		} else /* Send LHREQ_BREAK command. */
 			write(lguest_fd, args, sizeof(args));
 	}
 }
 
 /* This routine just sets up a pipe to the Waker process. */
-static int setup_waker(int lguest_fd, struct device_list *device_list)
+static int setup_waker(int lguest_fd)
 {
 	int pipefd[2], child;
 
@@ -580,7 +570,7 @@
 	if (child == 0) {
 		/* Close the "writing" end of our copy of the pipe */
 		close(pipefd[1]);
-		wake_parent(pipefd[0], lguest_fd, device_list);
+		wake_parent(pipefd[0], lguest_fd);
 	}
 	/* Close the reading end of our copy of the pipe. */
 	close(pipefd[0]);
@@ -602,83 +592,128 @@
 {
 	/* We have to separately check addr and addr+size, because size could
 	 * be huge and addr + size might wrap around. */
-	if (addr >= top || addr + size >= top)
-		errx(1, "%s:%i: Invalid address %li", __FILE__, line, addr);
+	if (addr >= guest_limit || addr + size >= guest_limit)
+		errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr);
 	/* We return a pointer for the caller's convenience, now we know it's
 	 * safe to use. */
-	return (void *)addr;
+	return from_guest_phys(addr);
 }
 /* A macro which transparently hands the line number to the real function. */
 #define check_pointer(addr,size) _check_pointer(addr, size, __LINE__)
 
-/* The Guest has given us the address of a "struct lguest_dma".  We check it's
- * OK and convert it to an iovec (which is a simple array of ptr/size
- * pairs). */
-static u32 *dma2iov(unsigned long dma, struct iovec iov[], unsigned *num)
+/* This function returns the next descriptor in the chain, or vq->vring.num. */
+static unsigned next_desc(struct virtqueue *vq, unsigned int i)
 {
-	unsigned int i;
-	struct lguest_dma *udma;
+	unsigned int next;
 
-	/* First we make sure that the array memory itself is valid. */
-	udma = check_pointer(dma, sizeof(*udma));
-	/* Now we check each element */
-	for (i = 0; i < LGUEST_MAX_DMA_SECTIONS; i++) {
-		/* A zero length ends the array. */
-		if (!udma->len[i])
-			break;
+	/* If this descriptor says it doesn't chain, we're done. */
+	if (!(vq->vring.desc[i].flags & VRING_DESC_F_NEXT))
+		return vq->vring.num;
 
-		iov[i].iov_base = check_pointer(udma->addr[i], udma->len[i]);
-		iov[i].iov_len = udma->len[i];
-	}
-	*num = i;
+	/* Check they're not leading us off end of descriptors. */
+	next = vq->vring.desc[i].next;
+	/* Make sure compiler knows to grab that: we don't want it changing! */
+	wmb();
 
-	/* We return the pointer to where the caller should write the amount of
-	 * the buffer used. */
-	return &udma->used_len;
+	if (next >= vq->vring.num)
+		errx(1, "Desc next is %u", next);
+
+	return next;
 }
 
-/* This routine gets a DMA buffer from the Guest for a given key, and converts
- * it to an iovec array.  It returns the interrupt the Guest wants when we're
- * finished, and a pointer to the "used_len" field to fill in. */
-static u32 *get_dma_buffer(int fd, void *key,
-			   struct iovec iov[], unsigned int *num, u32 *irq)
+/* This looks in the virtqueue and for the first available buffer, and converts
+ * it to an iovec for convenient access.  Since descriptors consist of some
+ * number of output then some number of input descriptors, it's actually two
+ * iovecs, but we pack them into one and note how many of each there were.
+ *
+ * This function returns the descriptor number found, or vq->vring.num (which
+ * is never a valid descriptor number) if none was found. */
+static unsigned get_vq_desc(struct virtqueue *vq,
+			    struct iovec iov[],
+			    unsigned int *out_num, unsigned int *in_num)
 {
-	u32 buf[] = { LHREQ_GETDMA, (u32)key };
-	unsigned long udma;
-	u32 *res;
+	unsigned int i, head;
 
-	/* Ask the kernel for a DMA buffer corresponding to this key. */
-	udma = write(fd, buf, sizeof(buf));
-	/* They haven't registered any, or they're all used? */
-	if (udma == (unsigned long)-1)
-		return NULL;
+	/* Check it isn't doing very strange things with descriptor numbers. */
+	if ((u16)(vq->vring.avail->idx - vq->last_avail_idx) > vq->vring.num)
+		errx(1, "Guest moved used index from %u to %u",
+		     vq->last_avail_idx, vq->vring.avail->idx);
 
-	/* Convert it into our iovec array */
-	res = dma2iov(udma, iov, num);
-	/* The kernel stashes irq in ->used_len to get it out to us. */
-	*irq = *res;
-	/* Return a pointer to ((struct lguest_dma *)udma)->used_len. */
-	return res;
+	/* If there's nothing new since last we looked, return invalid. */
+	if (vq->vring.avail->idx == vq->last_avail_idx)
+		return vq->vring.num;
+
+	/* Grab the next descriptor number they're advertising, and increment
+	 * the index we've seen. */
+	head = vq->vring.avail->ring[vq->last_avail_idx++ % vq->vring.num];
+
+	/* If their number is silly, that's a fatal mistake. */
+	if (head >= vq->vring.num)
+		errx(1, "Guest says index %u is available", head);
+
+	/* When we start there are none of either input nor output. */
+	*out_num = *in_num = 0;
+
+	i = head;
+	do {
+		/* Grab the first descriptor, and check it's OK. */
+		iov[*out_num + *in_num].iov_len = vq->vring.desc[i].len;
+		iov[*out_num + *in_num].iov_base
+			= check_pointer(vq->vring.desc[i].addr,
+					vq->vring.desc[i].len);
+		/* If this is an input descriptor, increment that count. */
+		if (vq->vring.desc[i].flags & VRING_DESC_F_WRITE)
+			(*in_num)++;
+		else {
+			/* If it's an output descriptor, they're all supposed
+			 * to come before any input descriptors. */
+			if (*in_num)
+				errx(1, "Descriptor has out after in");
+			(*out_num)++;
+		}
+
+		/* If we've got too many, that implies a descriptor loop. */
+		if (*out_num + *in_num > vq->vring.num)
+			errx(1, "Looped descriptor");
+	} while ((i = next_desc(vq, i)) != vq->vring.num);
+
+	return head;
 }
 
-/* This is a convenient routine to send the Guest an interrupt. */
-static void trigger_irq(int fd, u32 irq)
+/* Once we've used one of their buffers, we tell them about it.  We'll then
+ * want to send them an interrupt, using trigger_irq(). */
+static void add_used(struct virtqueue *vq, unsigned int head, int len)
 {
-	u32 buf[] = { LHREQ_IRQ, irq };
+	struct vring_used_elem *used;
+
+	/* Get a pointer to the next entry in the used ring. */
+	used = &vq->vring.used->ring[vq->vring.used->idx % vq->vring.num];
+	used->id = head;
+	used->len = len;
+	/* Make sure buffer is written before we update index. */
+	wmb();
+	vq->vring.used->idx++;
+}
+
+/* This actually sends the interrupt for this virtqueue */
+static void trigger_irq(int fd, struct virtqueue *vq)
+{
+	unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
+
+	if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
+		return;
+
+	/* Send the Guest an interrupt tell them we used something up. */
 	if (write(fd, buf, sizeof(buf)) != 0)
-		err(1, "Triggering irq %i", irq);
+		err(1, "Triggering irq %i", vq->config.irq);
 }
 
-/* This simply sets up an iovec array where we can put data to be discarded.
- * This happens when the Guest doesn't want or can't handle the input: we have
- * to get rid of it somewhere, and if we bury it in the ceiling space it will
- * start to smell after a week. */
-static void discard_iovec(struct iovec *iov, unsigned int *num)
+/* And here's the combo meal deal.  Supersize me! */
+static void add_used_and_trigger(int fd, struct virtqueue *vq,
+				 unsigned int head, int len)
 {
-	static char discard_buf[1024];
-	*num = 1;
-	iov->iov_base = discard_buf;
-	iov->iov_len = sizeof(discard_buf);
+	add_used(vq, head, len);
+	trigger_irq(fd, vq);
 }
 
 /* Here is the input terminal setting we save, and the routine to restore them
@@ -701,38 +736,39 @@
 /* This is the routine which handles console input (ie. stdin). */
 static bool handle_console_input(int fd, struct device *dev)
 {
-	u32 irq = 0, *lenp;
 	int len;
-	unsigned int num;
-	struct iovec iov[LGUEST_MAX_DMA_SECTIONS];
+	unsigned int head, in_num, out_num;
+	struct iovec iov[dev->vq->vring.num];
 	struct console_abort *abort = dev->priv;
 
-	/* First we get the console buffer from the Guest.  The key is dev->mem
-	 * which was set to 0 in setup_console(). */
-	lenp = get_dma_buffer(fd, dev->mem, iov, &num, &irq);
-	if (!lenp) {
-		/* If it's not ready for input, warn and set up to discard. */
-		warn("console: no dma buffer!");
-		discard_iovec(iov, &num);
-	}
+	/* First we need a console buffer from the Guests's input virtqueue. */
+	head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
+
+	/* If they're not ready for input, stop listening to this file
+	 * descriptor.  We'll start again once they add an input buffer. */
+	if (head == dev->vq->vring.num)
+		return false;
+
+	if (out_num)
+		errx(1, "Output buffers in console in queue?");
 
 	/* This is why we convert to iovecs: the readv() call uses them, and so
 	 * it reads straight into the Guest's buffer. */
-	len = readv(dev->fd, iov, num);
+	len = readv(dev->fd, iov, in_num);
 	if (len <= 0) {
 		/* This implies that the console is closed, is /dev/null, or
-		 * something went terribly wrong.  We still go through the rest
-		 * of the logic, though, especially the exit handling below. */
+		 * something went terribly wrong. */
 		warnx("Failed to get console input, ignoring console.");
-		len = 0;
+		/* Put the input terminal back. */
+		restore_term();
+		/* Remove callback from input vq, so it doesn't restart us. */
+		dev->vq->handle_output = NULL;
+		/* Stop listening to this fd: don't call us again. */
+		return false;
 	}
 
-	/* If we read the data into the Guest, fill in the length and send the
-	 * interrupt. */
-	if (lenp) {
-		*lenp = len;
-		trigger_irq(fd, irq);
-	}
+	/* Tell the Guest about the new input. */
+	add_used_and_trigger(fd, dev->vq, head, len);
 
 	/* Three ^C within one second?  Exit.
 	 *
@@ -746,7 +782,7 @@
 			struct timeval now;
 			gettimeofday(&now, NULL);
 			if (now.tv_sec <= abort->start.tv_sec+1) {
-				u32 args[] = { LHREQ_BREAK, 0 };
+				unsigned long args[] = { LHREQ_BREAK, 0 };
 				/* Close the fd so Waker will know it has to
 				 * exit. */
 				close(waker_fd);
@@ -761,214 +797,163 @@
 		/* Any other key resets the abort counter. */
 		abort->count = 0;
 
-	/* Now, if we didn't read anything, put the input terminal back and
-	 * return failure (meaning, don't call us again). */
-	if (!len) {
-		restore_term();
-		return false;
-	}
 	/* Everything went OK! */
 	return true;
 }
 
-/* Handling console output is much simpler than input. */
-static u32 handle_console_output(int fd, const struct iovec *iov,
-				 unsigned num, struct device*dev)
+/* Handling output for console is simple: we just get all the output buffers
+ * and write them to stdout. */
+static void handle_console_output(int fd, struct virtqueue *vq)
 {
-	/* Whatever the Guest sends, write it to standard output.  Return the
-	 * number of bytes written. */
-	return writev(STDOUT_FILENO, iov, num);
+	unsigned int head, out, in;
+	int len;
+	struct iovec iov[vq->vring.num];
+
+	/* Keep getting output buffers from the Guest until we run out. */
+	while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) {
+		if (in)
+			errx(1, "Input buffers in output queue?");
+		len = writev(STDOUT_FILENO, iov, out);
+		add_used_and_trigger(fd, vq, head, len);
+	}
 }
 
-/* Guest->Host network output is also pretty easy. */
-static u32 handle_tun_output(int fd, const struct iovec *iov,
-			     unsigned num, struct device *dev)
+/* Handling output for network is also simple: we get all the output buffers
+ * and write them (ignoring the first element) to this device's file descriptor
+ * (stdout). */
+static void handle_net_output(int fd, struct virtqueue *vq)
 {
-	/* We put a flag in the "priv" pointer of the network device, and set
-	 * it as soon as we see output.  We'll see why in handle_tun_input() */
-	*(bool *)dev->priv = true;
-	/* Whatever packet the Guest sent us, write it out to the tun
-	 * device. */
-	return writev(dev->fd, iov, num);
+	unsigned int head, out, in;
+	int len;
+	struct iovec iov[vq->vring.num];
+
+	/* Keep getting output buffers from the Guest until we run out. */
+	while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) {
+		if (in)
+			errx(1, "Input buffers in output queue?");
+		/* Check header, but otherwise ignore it (we said we supported
+		 * no features). */
+		(void)convert(&iov[0], struct virtio_net_hdr);
+		len = writev(vq->dev->fd, iov+1, out-1);
+		add_used_and_trigger(fd, vq, head, len);
+	}
 }
 
-/* This matches the peer_key() in lguest_net.c.  The key for any given slot
- * is the address of the network device's page plus 4 * the slot number. */
-static unsigned long peer_offset(unsigned int peernum)
-{
-	return 4 * peernum;
-}
-
-/* This is where we handle a packet coming in from the tun device */
+/* This is where we handle a packet coming in from the tun device to our
+ * Guest. */
 static bool handle_tun_input(int fd, struct device *dev)
 {
-	u32 irq = 0, *lenp;
+	unsigned int head, in_num, out_num;
 	int len;
-	unsigned num;
-	struct iovec iov[LGUEST_MAX_DMA_SECTIONS];
+	struct iovec iov[dev->vq->vring.num];
+	struct virtio_net_hdr *hdr;
 
-	/* First we get a buffer the Guest has bound to its key. */
-	lenp = get_dma_buffer(fd, dev->mem+peer_offset(NET_PEERNUM), iov, &num,
-			      &irq);
-	if (!lenp) {
+	/* First we need a network buffer from the Guests's recv virtqueue. */
+	head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
+	if (head == dev->vq->vring.num) {
 		/* Now, it's expected that if we try to send a packet too
-		 * early, the Guest won't be ready yet.  This is why we set a
-		 * flag when the Guest sends its first packet.  If it's sent a
-		 * packet we assume it should be ready to receive them.
-		 *
-		 * Actually, this is what the status bits in the descriptor are
-		 * for: we should *use* them.  FIXME! */
-		if (*(bool *)dev->priv)
+		 * early, the Guest won't be ready yet.  Wait until the device
+		 * status says it's ready. */
+		/* FIXME: Actually want DRIVER_ACTIVE here. */
+		if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK)
 			warn("network: no dma buffer!");
-		discard_iovec(iov, &num);
-	}
+		/* We'll turn this back on if input buffers are registered. */
+		return false;
+	} else if (out_num)
+		errx(1, "Output buffers in network recv queue?");
+
+	/* First element is the header: we set it to 0 (no features). */
+	hdr = convert(&iov[0], struct virtio_net_hdr);
+	hdr->flags = 0;
+	hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
 
 	/* Read the packet from the device directly into the Guest's buffer. */
-	len = readv(dev->fd, iov, num);
+	len = readv(dev->fd, iov+1, in_num-1);
 	if (len <= 0)
 		err(1, "reading network");
 
-	/* Write the used_len, and trigger the interrupt for the Guest */
-	if (lenp) {
-		*lenp = len;
-		trigger_irq(fd, irq);
-	}
+	/* Tell the Guest about the new packet. */
+	add_used_and_trigger(fd, dev->vq, head, sizeof(*hdr) + len);
+
 	verbose("tun input packet len %i [%02x %02x] (%s)\n", len,
-		((u8 *)iov[0].iov_base)[0], ((u8 *)iov[0].iov_base)[1],
-		lenp ? "sent" : "discarded");
+		((u8 *)iov[1].iov_base)[0], ((u8 *)iov[1].iov_base)[1],
+		head != dev->vq->vring.num ? "sent" : "discarded");
+
 	/* All good. */
 	return true;
 }
 
-/* The last device handling routine is block output: the Guest has sent a DMA
- * to the block device.  It will have placed the command it wants in the
- * "struct lguest_block_page". */
-static u32 handle_block_output(int fd, const struct iovec *iov,
-			       unsigned num, struct device *dev)
+/* This callback ensures we try again, in case we stopped console or net
+ * delivery because Guest didn't have any buffers. */
+static void enable_fd(int fd, struct virtqueue *vq)
 {
-	struct lguest_block_page *p = dev->mem;
-	u32 irq, *lenp;
-	unsigned int len, reply_num;
-	struct iovec reply[LGUEST_MAX_DMA_SECTIONS];
-	off64_t device_len, off = (off64_t)p->sector * 512;
-
-	/* First we extract the device length from the dev->priv pointer. */
-	device_len = *(off64_t *)dev->priv;
-
-	/* We first check that the read or write is within the length of the
-	 * block file. */
-	if (off >= device_len)
-		err(1, "Bad offset %llu vs %llu", off, device_len);
-	/* Move to the right location in the block file.  This shouldn't fail,
-	 * but best to check. */
-	if (lseek64(dev->fd, off, SEEK_SET) != off)
-		err(1, "Bad seek to sector %i", p->sector);
-
-	verbose("Block: %s at offset %llu\n", p->type ? "WRITE" : "READ", off);
-
-	/* They were supposed to bind a reply buffer at key equal to the start
-	 * of the block device memory.  We need this to tell them when the
-	 * request is finished. */
-	lenp = get_dma_buffer(fd, dev->mem, reply, &reply_num, &irq);
-	if (!lenp)
-		err(1, "Block request didn't give us a dma buffer");
-
-	if (p->type) {
-		/* A write request.  The DMA they sent contained the data, so
-		 * write it out. */
-		len = writev(dev->fd, iov, num);
-		/* Grr... Now we know how long the "struct lguest_dma" they
-		 * sent was, we make sure they didn't try to write over the end
-		 * of the block file (possibly extending it). */
-		if (off + len > device_len) {
-			/* Trim it back to the correct length */
-			ftruncate64(dev->fd, device_len);
-			/* Die, bad Guest, die. */
-			errx(1, "Write past end %llu+%u", off, len);
-		}
-		/* The reply length is 0: we just send back an empty DMA to
-		 * interrupt them and tell them the write is finished. */
-		*lenp = 0;
-	} else {
-		/* A read request.  They sent an empty DMA to start the
-		 * request, and we put the read contents into the reply
-		 * buffer. */
-		len = readv(dev->fd, reply, reply_num);
-		*lenp = len;
-	}
-
-	/* The result is 1 (done), 2 if there was an error (short read or
-	 * write). */
-	p->result = 1 + (p->bytes != len);
-	/* Now tell them we've used their reply buffer. */
-	trigger_irq(fd, irq);
-
-	/* We're supposed to return the number of bytes of the output buffer we
-	 * used.  But the block device uses the "result" field instead, so we
-	 * don't bother. */
-	return 0;
+	add_device_fd(vq->dev->fd);
+	/* Tell waker to listen to it again */
+	write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd));
 }
 
-/* This is the generic routine we call when the Guest sends some DMA out. */
-static void handle_output(int fd, unsigned long dma, unsigned long key,
-			  struct device_list *devices)
+/* This is the generic routine we call when the Guest uses LHCALL_NOTIFY. */
+static void handle_output(int fd, unsigned long addr)
 {
 	struct device *i;
-	u32 *lenp;
-	struct iovec iov[LGUEST_MAX_DMA_SECTIONS];
-	unsigned num = 0;
+	struct virtqueue *vq;
 
-	/* Convert the "struct lguest_dma" they're sending to a "struct
-	 * iovec". */
-	lenp = dma2iov(dma, iov, &num);
-
-	/* Check each device: if they expect output to this key, tell them to
-	 * handle it. */
-	for (i = devices->dev; i; i = i->next) {
-		if (i->handle_output && key == i->watch_key) {
-			/* We write the result straight into the used_len field
-			 * for them. */
-			*lenp = i->handle_output(fd, iov, num, i);
-			return;
+	/* Check each virtqueue. */
+	for (i = devices.dev; i; i = i->next) {
+		for (vq = i->vq; vq; vq = vq->next) {
+			if (vq->config.pfn == addr/getpagesize()
+			    && vq->handle_output) {
+				verbose("Output to %s\n", vq->dev->name);
+				vq->handle_output(fd, vq);
+				return;
+			}
 		}
 	}
 
-	/* This can happen: the kernel sends any SEND_DMA which doesn't match
-	 * another Guest to us.  It could be that another Guest just left a
-	 * network, for example.  But it's unusual. */
-	warnx("Pending dma %p, key %p", (void *)dma, (void *)key);
+	/* Early console write is done using notify on a nul-terminated string
+	 * in Guest memory. */
+	if (addr >= guest_limit)
+		errx(1, "Bad NOTIFY %#lx", addr);
+
+	write(STDOUT_FILENO, from_guest_phys(addr),
+	      strnlen(from_guest_phys(addr), guest_limit - addr));
 }
 
 /* This is called when the waker wakes us up: check for incoming file
  * descriptors. */
-static void handle_input(int fd, struct device_list *devices)
+static void handle_input(int fd)
 {
 	/* select() wants a zeroed timeval to mean "don't wait". */
 	struct timeval poll = { .tv_sec = 0, .tv_usec = 0 };
 
 	for (;;) {
 		struct device *i;
-		fd_set fds = devices->infds;
+		fd_set fds = devices.infds;
 
 		/* If nothing is ready, we're done. */
-		if (select(devices->max_infd+1, &fds, NULL, NULL, &poll) == 0)
+		if (select(devices.max_infd+1, &fds, NULL, NULL, &poll) == 0)
 			break;
 
 		/* Otherwise, call the device(s) which have readable
 		 * file descriptors and a method of handling them.  */
-		for (i = devices->dev; i; i = i->next) {
+		for (i = devices.dev; i; i = i->next) {
 			if (i->handle_input && FD_ISSET(i->fd, &fds)) {
+				int dev_fd;
+				if (i->handle_input(fd, i))
+					continue;
+
 				/* If handle_input() returns false, it means we
-				 * should no longer service it.
-				 * handle_console_input() does this. */
-				if (!i->handle_input(fd, i)) {
-					/* Clear it from the set of input file
-					 * descriptors kept at the head of the
-					 * device list. */
-					FD_CLR(i->fd, &devices->infds);
-					/* Tell waker to ignore it too... */
-					write(waker_fd, &i->fd, sizeof(i->fd));
-				}
+				 * should no longer service it.  Networking and
+				 * console do this when there's no input
+				 * buffers to deliver into.  Console also uses
+				 * it when it discovers that stdin is
+				 * closed. */
+				FD_CLR(i->fd, &devices.infds);
+				/* Tell waker to ignore it too, by sending a
+				 * negative fd number (-1, since 0 is a valid
+				 * FD number). */
+				dev_fd = -i->fd - 1;
+				write(waker_fd, &dev_fd, sizeof(dev_fd));
 			}
 		}
 	}
@@ -982,43 +967,93 @@
  * routines to allocate them.
  *
  * This routine allocates a new "struct lguest_device_desc" from descriptor
- * table in the devices array just above the Guest's normal memory. */
-static struct lguest_device_desc *
-new_dev_desc(struct lguest_device_desc *descs,
-	     u16 type, u16 features, u16 num_pages)
+ * table just above the Guest's normal memory.  It returns a pointer to that
+ * descriptor. */
+static struct lguest_device_desc *new_dev_desc(u16 type)
 {
-	unsigned int i;
+	struct lguest_device_desc *d;
 
-	for (i = 0; i < LGUEST_MAX_DEVICES; i++) {
-		if (!descs[i].type) {
-			descs[i].type = type;
-			descs[i].features = features;
-			descs[i].num_pages = num_pages;
-			/* If they said the device needs memory, we allocate
-			 * that now, bumping up the top of Guest memory. */
-			if (num_pages) {
-				map_zeroed_pages(top, num_pages);
-				descs[i].pfn = top/getpagesize();
-				top += num_pages*getpagesize();
-			}
-			return &descs[i];
-		}
-	}
-	errx(1, "too many devices");
+	/* We only have one page for all the descriptors. */
+	if (devices.desc_used + sizeof(*d) > getpagesize())
+		errx(1, "Too many devices");
+
+	/* We don't need to set config_len or status: page is 0 already. */
+	d = (void *)devices.descpage + devices.desc_used;
+	d->type = type;
+	devices.desc_used += sizeof(*d);
+
+	return d;
 }
 
-/* This monster routine does all the creation and setup of a new device,
- * including caling new_dev_desc() to allocate the descriptor and device
- * memory. */
-static struct device *new_device(struct device_list *devices,
-				 u16 type, u16 num_pages, u16 features,
-				 int fd,
-				 bool (*handle_input)(int, struct device *),
-				 unsigned long watch_off,
-				 u32 (*handle_output)(int,
-						      const struct iovec *,
-						      unsigned,
-						      struct device *))
+/* Each device descriptor is followed by some configuration information.
+ * The first byte is a "status" byte for the Guest to report what's happening.
+ * After that are fields: u8 type, u8 len, [... len bytes...].
+ *
+ * This routine adds a new field to an existing device's descriptor.  It only
+ * works for the last device, but that's OK because that's how we use it. */
+static void add_desc_field(struct device *dev, u8 type, u8 len, const void *c)
+{
+	/* This is the last descriptor, right? */
+	assert(devices.descpage + devices.desc_used
+	       == (u8 *)(dev->desc + 1) + dev->desc->config_len);
+
+	/* We only have one page of device descriptions. */
+	if (devices.desc_used + 2 + len > getpagesize())
+		errx(1, "Too many devices");
+
+	/* Copy in the new config header: type then length. */
+	devices.descpage[devices.desc_used++] = type;
+	devices.descpage[devices.desc_used++] = len;
+	memcpy(devices.descpage + devices.desc_used, c, len);
+	devices.desc_used += len;
+
+	/* Update the device descriptor length: two byte head then data. */
+	dev->desc->config_len += 2 + len;
+}
+
+/* This routine adds a virtqueue to a device.  We specify how many descriptors
+ * the virtqueue is to have. */
+static void add_virtqueue(struct device *dev, unsigned int num_descs,
+			  void (*handle_output)(int fd, struct virtqueue *me))
+{
+	unsigned int pages;
+	struct virtqueue **i, *vq = malloc(sizeof(*vq));
+	void *p;
+
+	/* First we need some pages for this virtqueue. */
+	pages = (vring_size(num_descs) + getpagesize() - 1) / getpagesize();
+	p = get_pages(pages);
+
+	/* Initialize the configuration. */
+	vq->config.num = num_descs;
+	vq->config.irq = devices.next_irq++;
+	vq->config.pfn = to_guest_phys(p) / getpagesize();
+
+	/* Initialize the vring. */
+	vring_init(&vq->vring, num_descs, p);
+
+	/* Add the configuration information to this device's descriptor. */
+	add_desc_field(dev, VIRTIO_CONFIG_F_VIRTQUEUE,
+		       sizeof(vq->config), &vq->config);
+
+	/* Add to tail of list, so dev->vq is first vq, dev->vq->next is
+	 * second.  */
+	for (i = &dev->vq; *i; i = &(*i)->next);
+	*i = vq;
+
+	/* Link virtqueue back to device. */
+	vq->dev = dev;
+
+	/* Set up handler. */
+	vq->handle_output = handle_output;
+	if (!handle_output)
+		vq->vring.used->flags = VRING_USED_F_NO_NOTIFY;
+}
+
+/* This routine does all the creation and setup of a new device, including
+ * caling new_dev_desc() to allocate the descriptor and device memory. */
+static struct device *new_device(const char *name, u16 type, int fd,
+				 bool (*handle_input)(int, struct device *))
 {
 	struct device *dev = malloc(sizeof(*dev));
 
@@ -1026,27 +1061,25 @@
 	 * easier, but the user expects the devices to be arranged on the bus
 	 * in command-line order.  The first network device on the command line
 	 * is eth0, the first block device /dev/lgba, etc. */
-	*devices->lastdev = dev;
+	*devices.lastdev = dev;
 	dev->next = NULL;
-	devices->lastdev = &dev->next;
+	devices.lastdev = &dev->next;
 
 	/* Now we populate the fields one at a time. */
 	dev->fd = fd;
 	/* If we have an input handler for this file descriptor, then we add it
 	 * to the device_list's fdset and maxfd. */
 	if (handle_input)
-		set_fd(dev->fd, devices);
-	dev->desc = new_dev_desc(devices->descs, type, features, num_pages);
-	dev->mem = (void *)(dev->desc->pfn * getpagesize());
+		add_device_fd(dev->fd);
+	dev->desc = new_dev_desc(type);
 	dev->handle_input = handle_input;
-	dev->watch_key = (unsigned long)dev->mem + watch_off;
-	dev->handle_output = handle_output;
+	dev->name = name;
 	return dev;
 }
 
 /* Our first setup routine is the console.  It's a fairly simple device, but
  * UNIX tty handling makes it uglier than it could be. */
-static void setup_console(struct device_list *devices)
+static void setup_console(void)
 {
 	struct device *dev;
 
@@ -1062,128 +1095,39 @@
 		atexit(restore_term);
 	}
 
-	/* We don't currently require any memory for the console, so we ask for
-	 * 0 pages. */
-	dev = new_device(devices, LGUEST_DEVICE_T_CONSOLE, 0, 0,
-			 STDIN_FILENO, handle_console_input,
-			 LGUEST_CONSOLE_DMA_KEY, handle_console_output);
+	dev = new_device("console", VIRTIO_ID_CONSOLE,
+			 STDIN_FILENO, handle_console_input);
 	/* We store the console state in dev->priv, and initialize it. */
 	dev->priv = malloc(sizeof(struct console_abort));
 	((struct console_abort *)dev->priv)->count = 0;
-	verbose("device %p: console\n",
-		(void *)(dev->desc->pfn * getpagesize()));
-}
 
-/* Setting up a block file is also fairly straightforward. */
-static void setup_block_file(const char *filename, struct device_list *devices)
-{
-	int fd;
-	struct device *dev;
-	off64_t *device_len;
-	struct lguest_block_page *p;
+	/* The console needs two virtqueues: the input then the output.  When
+	 * they put something the input queue, we make sure we're listening to
+	 * stdin.  When they put something in the output queue, we write it to
+	 * stdout.  */
+	add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
+	add_virtqueue(dev, VIRTQUEUE_NUM, handle_console_output);
 
-	/* We open with O_LARGEFILE because otherwise we get stuck at 2G.  We
-	 * open with O_DIRECT because otherwise our benchmarks go much too
-	 * fast. */
-	fd = open_or_die(filename, O_RDWR|O_LARGEFILE|O_DIRECT);
-
-	/* We want one page, and have no input handler (the block file never
-	 * has anything interesting to say to us).  Our timing will be quite
-	 * random, so it should be a reasonable randomness source. */
-	dev = new_device(devices, LGUEST_DEVICE_T_BLOCK, 1,
-			 LGUEST_DEVICE_F_RANDOMNESS,
-			 fd, NULL, 0, handle_block_output);
-
-	/* We store the device size in the private area */
-	device_len = dev->priv = malloc(sizeof(*device_len));
-	/* This is the safe way of establishing the size of our device: it
-	 * might be a normal file or an actual block device like /dev/hdb. */
-	*device_len = lseek64(fd, 0, SEEK_END);
-
-	/* The device memory is a "struct lguest_block_page".  It's zeroed
-	 * already, we just need to put in the device size.  Block devices
-	 * think in sectors (ie. 512 byte chunks), so we translate here. */
-	p = dev->mem;
-	p->num_sectors = *device_len/512;
-	verbose("device %p: block %i sectors\n",
-		(void *)(dev->desc->pfn * getpagesize()), p->num_sectors);
-}
-
-/*
- * Network Devices.
- *
- * Setting up network devices is quite a pain, because we have three types.
- * First, we have the inter-Guest network.  This is a file which is mapped into
- * the address space of the Guests who are on the network.  Because it is a
- * shared mapping, the same page underlies all the devices, and they can send
- * DMA to each other.
- *
- * Remember from our network driver, the Guest is told what slot in the page it
- * is to use.  We use exclusive fnctl locks to reserve a slot.  If another
- * Guest is using a slot, the lock will fail and we try another.  Because fnctl
- * locks are cleaned up automatically when we die, this cleverly means that our
- * reservation on the slot will vanish if we crash. */
-static unsigned int find_slot(int netfd, const char *filename)
-{
-	struct flock fl;
-
-	fl.l_type = F_WRLCK;
-	fl.l_whence = SEEK_SET;
-	fl.l_len = 1;
-	/* Try a 1 byte lock in each possible position number */
-	for (fl.l_start = 0;
-	     fl.l_start < getpagesize()/sizeof(struct lguest_net);
-	     fl.l_start++) {
-		/* If we succeed, return the slot number. */
-		if (fcntl(netfd, F_SETLK, &fl) == 0)
-			return fl.l_start;
-	}
-	errx(1, "No free slots in network file %s", filename);
-}
-
-/* This function sets up the network file */
-static void setup_net_file(const char *filename,
-			   struct device_list *devices)
-{
-	int netfd;
-	struct device *dev;
-
-	/* We don't use open_or_die() here: for friendliness we create the file
-	 * if it doesn't already exist. */
-	netfd = open(filename, O_RDWR, 0);
-	if (netfd < 0) {
-		if (errno == ENOENT) {
-			netfd = open(filename, O_RDWR|O_CREAT, 0600);
-			if (netfd >= 0) {
-				/* If we succeeded, initialize the file with a
-				 * blank page. */
-				char page[getpagesize()];
-				memset(page, 0, sizeof(page));
-				write(netfd, page, sizeof(page));
-			}
-		}
-		if (netfd < 0)
-			err(1, "cannot open net file '%s'", filename);
-	}
-
-	/* We need 1 page, and the features indicate the slot to use and that
-	 * no checksum is needed.  We never touch this device again; it's
-	 * between the Guests on the network, so we don't register input or
-	 * output handlers. */
-	dev = new_device(devices, LGUEST_DEVICE_T_NET, 1,
-			 find_slot(netfd, filename)|LGUEST_NET_F_NOCSUM,
-			 -1, NULL, 0, NULL);
-
-	/* Map the shared file. */
-	if (mmap(dev->mem, getpagesize(), PROT_READ|PROT_WRITE,
-			 MAP_FIXED|MAP_SHARED, netfd, 0) != dev->mem)
-			err(1, "could not mmap '%s'", filename);
-	verbose("device %p: shared net %s, peer %i\n",
-		(void *)(dev->desc->pfn * getpagesize()), filename,
-		dev->desc->features & ~LGUEST_NET_F_NOCSUM);
+	verbose("device %u: console\n", devices.device_num++);
 }
 /*:*/
 
+/*M:010 Inter-guest networking is an interesting area.  Simplest is to have a
+ * --sharenet=<name> option which opens or creates a named pipe.  This can be
+ * used to send packets to another guest in a 1:1 manner.
+ *
+ * More sopisticated is to use one of the tools developed for project like UML
+ * to do networking.
+ *
+ * Faster is to do virtio bonding in kernel.  Doing this 1:1 would be
+ * completely generic ("here's my vring, attach to your vring") and would work
+ * for any traffic.  Of course, namespace and permissions issues need to be
+ * dealt with.  A more sophisticated "multi-channel" virtio_net.c could hide
+ * multiple inter-guest channels behind one interface, although it would
+ * require some manner of hotplugging new virtio channels.
+ *
+ * Finally, we could implement a virtio network switch in the kernel. :*/
+
 static u32 str2ip(const char *ipaddr)
 {
 	unsigned int byte[4];
@@ -1217,7 +1161,7 @@
 
 /* This sets up the Host end of the network device with an IP address, brings
  * it up so packets will flow, the copies the MAC address into the hwaddr
- * pointer (in practice, the Host's slot in the network device's memory). */
+ * pointer. */
 static void configure_device(int fd, const char *devname, u32 ipaddr,
 			     unsigned char hwaddr[6])
 {
@@ -1243,18 +1187,18 @@
 	memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6);
 }
 
-/*L:195 The other kind of network is a Host<->Guest network.  This can either
- * use briding or routing, but the principle is the same: it uses the "tun"
- * device to inject packets into the Host as if they came in from a normal
- * network card.  We just shunt packets between the Guest and the tun
- * device. */
-static void setup_tun_net(const char *arg, struct device_list *devices)
+/*L:195 Our network is a Host<->Guest network.  This can either use bridging or
+ * routing, but the principle is the same: it uses the "tun" device to inject
+ * packets into the Host as if they came in from a normal network card.  We
+ * just shunt packets between the Guest and the tun device. */
+static void setup_tun_net(const char *arg)
 {
 	struct device *dev;
 	struct ifreq ifr;
 	int netfd, ipfd;
 	u32 ip;
 	const char *br_name = NULL;
+	u8 hwaddr[6];
 
 	/* We open the /dev/net/tun device and tell it we want a tap device.  A
 	 * tap device is like a tun device, only somehow different.  To tell
@@ -1270,21 +1214,13 @@
 	 * device: trust us! */
 	ioctl(netfd, TUNSETNOCSUM, 1);
 
-	/* We create the net device with 1 page, using the features field of
-	 * the descriptor to tell the Guest it is in slot 1 (NET_PEERNUM), and
-	 * that the device has fairly random timing.  We do *not* specify
-	 * LGUEST_NET_F_NOCSUM: these packets can reach the real world.
-	 *
-	 * We will put our MAC address is slot 0 for the Guest to see, so
-	 * it will send packets to us using the key "peer_offset(0)": */
-	dev = new_device(devices, LGUEST_DEVICE_T_NET, 1,
-			 NET_PEERNUM|LGUEST_DEVICE_F_RANDOMNESS, netfd,
-			 handle_tun_input, peer_offset(0), handle_tun_output);
+	/* First we create a new network device. */
+	dev = new_device("net", VIRTIO_ID_NET, netfd, handle_tun_input);
 
-	/* We keep a flag which says whether we've seen packets come out from
-	 * this network device. */
-	dev->priv = malloc(sizeof(bool));
-	*(bool *)dev->priv = false;
+	/* Network devices need a receive and a send queue, just like
+	 * console. */
+	add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
+	add_virtqueue(dev, VIRTQUEUE_NUM, handle_net_output);
 
 	/* We need a socket to perform the magic network ioctls to bring up the
 	 * tap interface, connect to the bridge etc.  Any socket will do! */
@@ -1300,44 +1236,251 @@
 	} else /* It is an IP address to set up the device with */
 		ip = str2ip(arg);
 
-	/* We are peer 0, ie. first slot, so we hand dev->mem to this routine
-	 * to write the MAC address at the start of the device memory.  */
-	configure_device(ipfd, ifr.ifr_name, ip, dev->mem);
+	/* Set up the tun device, and get the mac address for the interface. */
+	configure_device(ipfd, ifr.ifr_name, ip, hwaddr);
 
-	/* Set "promisc" bit: we want every single packet if we're going to
-	 * bridge to other machines (and otherwise it doesn't matter). */
-	*((u8 *)dev->mem) |= 0x1;
+	/* Tell Guest what MAC address to use. */
+	add_desc_field(dev, VIRTIO_CONFIG_NET_MAC_F, sizeof(hwaddr), hwaddr);
 
+	/* We don't seed the socket any more; setup is done. */
 	close(ipfd);
 
-	verbose("device %p: tun net %u.%u.%u.%u\n",
-		(void *)(dev->desc->pfn * getpagesize()),
-		(u8)(ip>>24), (u8)(ip>>16), (u8)(ip>>8), (u8)ip);
+	verbose("device %u: tun net %u.%u.%u.%u\n",
+		devices.device_num++,
+		(u8)(ip>>24),(u8)(ip>>16),(u8)(ip>>8),(u8)ip);
 	if (br_name)
 		verbose("attached to bridge: %s\n", br_name);
 }
+
+
+/*
+ * Block device.
+ *
+ * Serving a block device is really easy: the Guest asks for a block number and
+ * we read or write that position in the file.
+ *
+ * Unfortunately, this is amazingly slow: the Guest waits until the read is
+ * finished before running anything else, even if it could be doing useful
+ * work.  We could use async I/O, except it's reputed to suck so hard that
+ * characters actually go missing from your code when you try to use it.
+ *
+ * So we farm the I/O out to thread, and communicate with it via a pipe. */
+
+/* This hangs off device->priv, with the data. */
+struct vblk_info
+{
+	/* The size of the file. */
+	off64_t len;
+
+	/* The file descriptor for the file. */
+	int fd;
+
+	/* IO thread listens on this file descriptor [0]. */
+	int workpipe[2];
+
+	/* IO thread writes to this file descriptor to mark it done, then
+	 * Launcher triggers interrupt to Guest. */
+	int done_fd;
+};
+
+/* This is the core of the I/O thread.  It returns true if it did something. */
+static bool service_io(struct device *dev)
+{
+	struct vblk_info *vblk = dev->priv;
+	unsigned int head, out_num, in_num, wlen;
+	int ret;
+	struct virtio_blk_inhdr *in;
+	struct virtio_blk_outhdr *out;
+	struct iovec iov[dev->vq->vring.num];
+	off64_t off;
+
+	head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
+	if (head == dev->vq->vring.num)
+		return false;
+
+	if (out_num == 0 || in_num == 0)
+		errx(1, "Bad virtblk cmd %u out=%u in=%u",
+		     head, out_num, in_num);
+
+	out = convert(&iov[0], struct virtio_blk_outhdr);
+	in = convert(&iov[out_num+in_num-1], struct virtio_blk_inhdr);
+	off = out->sector * 512;
+
+	/* This is how we implement barriers.  Pretty poor, no? */
+	if (out->type & VIRTIO_BLK_T_BARRIER)
+		fdatasync(vblk->fd);
+
+	if (out->type & VIRTIO_BLK_T_SCSI_CMD) {
+		fprintf(stderr, "Scsi commands unsupported\n");
+		in->status = VIRTIO_BLK_S_UNSUPP;
+		wlen = sizeof(in);
+	} else if (out->type & VIRTIO_BLK_T_OUT) {
+		/* Write */
+
+		/* Move to the right location in the block file.  This can fail
+		 * if they try to write past end. */
+		if (lseek64(vblk->fd, off, SEEK_SET) != off)
+			err(1, "Bad seek to sector %llu", out->sector);
+
+		ret = writev(vblk->fd, iov+1, out_num-1);
+		verbose("WRITE to sector %llu: %i\n", out->sector, ret);
+
+		/* Grr... Now we know how long the descriptor they sent was, we
+		 * make sure they didn't try to write over the end of the block
+		 * file (possibly extending it). */
+		if (ret > 0 && off + ret > vblk->len) {
+			/* Trim it back to the correct length */
+			ftruncate64(vblk->fd, vblk->len);
+			/* Die, bad Guest, die. */
+			errx(1, "Write past end %llu+%u", off, ret);
+		}
+		wlen = sizeof(in);
+		in->status = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR);
+	} else {
+		/* Read */
+
+		/* Move to the right location in the block file.  This can fail
+		 * if they try to read past end. */
+		if (lseek64(vblk->fd, off, SEEK_SET) != off)
+			err(1, "Bad seek to sector %llu", out->sector);
+
+		ret = readv(vblk->fd, iov+1, in_num-1);
+		verbose("READ from sector %llu: %i\n", out->sector, ret);
+		if (ret >= 0) {
+			wlen = sizeof(in) + ret;
+			in->status = VIRTIO_BLK_S_OK;
+		} else {
+			wlen = sizeof(in);
+			in->status = VIRTIO_BLK_S_IOERR;
+		}
+	}
+
+	/* We can't trigger an IRQ, because we're not the Launcher.  It does
+	 * that when we tell it we're done. */
+	add_used(dev->vq, head, wlen);
+	return true;
+}
+
+/* This is the thread which actually services the I/O. */
+static int io_thread(void *_dev)
+{
+	struct device *dev = _dev;
+	struct vblk_info *vblk = dev->priv;
+	char c;
+
+	/* Close other side of workpipe so we get 0 read when main dies. */
+	close(vblk->workpipe[1]);
+	/* Close the other side of the done_fd pipe. */
+	close(dev->fd);
+
+	/* When this read fails, it means Launcher died, so we follow. */
+	while (read(vblk->workpipe[0], &c, 1) == 1) {
+		/* We acknowledge each request immediately, to reduce latency,
+		 * rather than waiting until we've done them all.  I haven't
+		 * measured to see if it makes any difference. */
+		while (service_io(dev))
+			write(vblk->done_fd, &c, 1);
+	}
+	return 0;
+}
+
+/* When the thread says some I/O is done, we interrupt the Guest. */
+static bool handle_io_finish(int fd, struct device *dev)
+{
+	char c;
+
+	/* If child died, presumably it printed message. */
+	if (read(dev->fd, &c, 1) != 1)
+		exit(1);
+
+	/* It did some work, so trigger the irq. */
+	trigger_irq(fd, dev->vq);
+	return true;
+}
+
+/* When the Guest submits some I/O, we wake the I/O thread. */
+static void handle_virtblk_output(int fd, struct virtqueue *vq)
+{
+	struct vblk_info *vblk = vq->dev->priv;
+	char c = 0;
+
+	/* Wake up I/O thread and tell it to go to work! */
+	if (write(vblk->workpipe[1], &c, 1) != 1)
+		/* Presumably it indicated why it died. */
+		exit(1);
+}
+
+/* This creates a virtual block device. */
+static void setup_block_file(const char *filename)
+{
+	int p[2];
+	struct device *dev;
+	struct vblk_info *vblk;
+	void *stack;
+	u64 cap;
+	unsigned int val;
+
+	/* This is the pipe the I/O thread will use to tell us I/O is done. */
+	pipe(p);
+
+	/* The device responds to return from I/O thread. */
+	dev = new_device("block", VIRTIO_ID_BLOCK, p[0], handle_io_finish);
+
+	/* The device has a virtqueue. */
+	add_virtqueue(dev, VIRTQUEUE_NUM, handle_virtblk_output);
+
+	/* Allocate the room for our own bookkeeping */
+	vblk = dev->priv = malloc(sizeof(*vblk));
+
+	/* First we open the file and store the length. */
+	vblk->fd = open_or_die(filename, O_RDWR|O_LARGEFILE);
+	vblk->len = lseek64(vblk->fd, 0, SEEK_END);
+
+	/* Tell Guest how many sectors this device has. */
+	cap = cpu_to_le64(vblk->len / 512);
+	add_desc_field(dev, VIRTIO_CONFIG_BLK_F_CAPACITY, sizeof(cap), &cap);
+
+	/* Tell Guest not to put in too many descriptors at once: two are used
+	 * for the in and out elements. */
+	val = cpu_to_le32(VIRTQUEUE_NUM - 2);
+	add_desc_field(dev, VIRTIO_CONFIG_BLK_F_SEG_MAX, sizeof(val), &val);
+
+	/* The I/O thread writes to this end of the pipe when done. */
+	vblk->done_fd = p[1];
+
+	/* This is how we tell the I/O thread about more work. */
+	pipe(vblk->workpipe);
+
+	/* Create stack for thread and run it */
+	stack = malloc(32768);
+	if (clone(io_thread, stack + 32768, CLONE_VM, dev) == -1)
+		err(1, "Creating clone");
+
+	/* We don't need to keep the I/O thread's end of the pipes open. */
+	close(vblk->done_fd);
+	close(vblk->workpipe[0]);
+
+	verbose("device %u: virtblock %llu sectors\n",
+		devices.device_num, cap);
+}
 /* That's the end of device setup. */
 
 /*L:220 Finally we reach the core of the Launcher, which runs the Guest, serves
  * its input and output, and finally, lays it to rest. */
-static void __attribute__((noreturn))
-run_guest(int lguest_fd, struct device_list *device_list)
+static void __attribute__((noreturn)) run_guest(int lguest_fd)
 {
 	for (;;) {
-		u32 args[] = { LHREQ_BREAK, 0 };
-		unsigned long arr[2];
+		unsigned long args[] = { LHREQ_BREAK, 0 };
+		unsigned long notify_addr;
 		int readval;
 
 		/* We read from the /dev/lguest device to run the Guest. */
-		readval = read(lguest_fd, arr, sizeof(arr));
+		readval = read(lguest_fd, &notify_addr, sizeof(notify_addr));
 
-		/* The read can only really return sizeof(arr) (the Guest did a
-		 * SEND_DMA to us), or an error. */
-
-		/* For a successful read, arr[0] is the address of the "struct
-		 * lguest_dma", and arr[1] is the key the Guest sent to. */
-		if (readval == sizeof(arr)) {
-			handle_output(lguest_fd, arr[0], arr[1], device_list);
+		/* One unsigned long means the Guest did HCALL_NOTIFY */
+		if (readval == sizeof(notify_addr)) {
+			verbose("Notify on address %#lx\n", notify_addr);
+			handle_output(lguest_fd, notify_addr);
 			continue;
 		/* ENOENT means the Guest died.  Reading tells us why. */
 		} else if (errno == ENOENT) {
@@ -1351,7 +1494,7 @@
 
 		/* Service input, then unset the BREAK which releases
 		 * the Waker. */
-		handle_input(lguest_fd, device_list);
+		handle_input(lguest_fd);
 		if (write(lguest_fd, args, sizeof(args)) < 0)
 			err(1, "Resetting break");
 	}
@@ -1365,7 +1508,6 @@
 
 static struct option opts[] = {
 	{ "verbose", 0, NULL, 'v' },
-	{ "sharenet", 1, NULL, 's' },
 	{ "tunnet", 1, NULL, 't' },
 	{ "block", 1, NULL, 'b' },
 	{ "initrd", 1, NULL, 'i' },
@@ -1374,37 +1516,21 @@
 static void usage(void)
 {
 	errx(1, "Usage: lguest [--verbose] "
-	     "[--sharenet=<filename>|--tunnet=(<ipaddr>|bridge:<bridgename>)\n"
+	     "[--tunnet=(<ipaddr>|bridge:<bridgename>)\n"
 	     "|--block=<filename>|--initrd=<filename>]...\n"
 	     "<mem-in-mb> vmlinux [args...]");
 }
 
-/*L:100 The Launcher code itself takes us out into userspace, that scary place
- * where pointers run wild and free!  Unfortunately, like most userspace
- * programs, it's quite boring (which is why everyone like to hack on the
- * kernel!).  Perhaps if you make up an Lguest Drinking Game at this point, it
- * will get you through this section.  Or, maybe not.
- *
- * The Launcher binary sits up high, usually starting at address 0xB8000000.
- * Everything below this is the "physical" memory for the Guest.  For example,
- * if the Guest were to write a "1" at physical address 0, we would see a "1"
- * in the Launcher at "(int *)0".  Guest physical == Launcher virtual.
- *
- * This can be tough to get your head around, but usually it just means that we
- * don't need to do any conversion when the Guest gives us it's "physical"
- * addresses.
- */
+/*L:105 The main routine is where the real work begins: */
 int main(int argc, char *argv[])
 {
-	/* Memory, top-level pagetable, code startpoint, PAGE_OFFSET and size
-	 * of the (optional) initrd. */
-	unsigned long mem = 0, pgdir, start, page_offset, initrd_size = 0;
+	/* Memory, top-level pagetable, code startpoint and size of the
+	 * (optional) initrd. */
+	unsigned long mem = 0, pgdir, start, initrd_size = 0;
 	/* A temporary and the /dev/lguest file descriptor. */
 	int i, c, lguest_fd;
-	/* The list of Guest devices, based on command line arguments. */
-	struct device_list device_list;
-	/* The boot information for the Guest: at guest-physical address 0. */
-	void *boot = (void *)0;
+	/* The boot information for the Guest. */
+	struct boot_params *boot;
 	/* If they specify an initrd file to load. */
 	const char *initrd_name = NULL;
 
@@ -1412,11 +1538,12 @@
 	 * device receive input from a file descriptor, we keep an fdset
 	 * (infds) and the maximum fd number (max_infd) with the head of the
 	 * list.  We also keep a pointer to the last device, for easy appending
-	 * to the list. */
-	device_list.max_infd = -1;
-	device_list.dev = NULL;
-	device_list.lastdev = &device_list.dev;
-	FD_ZERO(&device_list.infds);
+	 * to the list.  Finally, we keep the next interrupt number to hand out
+	 * (1: remember that 0 is used by the timer). */
+	FD_ZERO(&devices.infds);
+	devices.max_infd = -1;
+	devices.lastdev = &devices.dev;
+	devices.next_irq = 1;
 
 	/* We need to know how much memory so we can set up the device
 	 * descriptor and memory pages for the devices as we parse the command
@@ -1424,9 +1551,16 @@
 	 * of memory now. */
 	for (i = 1; i < argc; i++) {
 		if (argv[i][0] != '-') {
-			mem = top = atoi(argv[i]) * 1024 * 1024;
-			device_list.descs = map_zeroed_pages(top, 1);
-			top += getpagesize();
+			mem = atoi(argv[i]) * 1024 * 1024;
+			/* We start by mapping anonymous pages over all of
+			 * guest-physical memory range.  This fills it with 0,
+			 * and ensures that the Guest won't be killed when it
+			 * tries to access it. */
+			guest_base = map_zeroed_pages(mem / getpagesize()
+						      + DEVICE_PAGES);
+			guest_limit = mem;
+			guest_max = mem + DEVICE_PAGES*getpagesize();
+			devices.descpage = get_pages(1);
 			break;
 		}
 	}
@@ -1437,14 +1571,11 @@
 		case 'v':
 			verbose = true;
 			break;
-		case 's':
-			setup_net_file(optarg, &device_list);
-			break;
 		case 't':
-			setup_tun_net(optarg, &device_list);
+			setup_tun_net(optarg);
 			break;
 		case 'b':
-			setup_block_file(optarg, &device_list);
+			setup_block_file(optarg);
 			break;
 		case 'i':
 			initrd_name = optarg;
@@ -1459,56 +1590,60 @@
 	if (optind + 2 > argc)
 		usage();
 
-	/* We always have a console device */
-	setup_console(&device_list);
+	verbose("Guest base is at %p\n", guest_base);
 
-	/* We start by mapping anonymous pages over all of guest-physical
-	 * memory range.  This fills it with 0, and ensures that the Guest
-	 * won't be killed when it tries to access it. */
-	map_zeroed_pages(0, mem / getpagesize());
+	/* We always have a console device */
+	setup_console();
 
 	/* Now we load the kernel */
-	start = load_kernel(open_or_die(argv[optind+1], O_RDONLY),
-			    &page_offset);
+	start = load_kernel(open_or_die(argv[optind+1], O_RDONLY));
+
+	/* Boot information is stashed at physical address 0 */
+	boot = from_guest_phys(0);
 
 	/* Map the initrd image if requested (at top of physical memory) */
 	if (initrd_name) {
 		initrd_size = load_initrd(initrd_name, mem);
 		/* These are the location in the Linux boot header where the
 		 * start and size of the initrd are expected to be found. */
-		*(unsigned long *)(boot+0x218) = mem - initrd_size;
-		*(unsigned long *)(boot+0x21c) = initrd_size;
+		boot->hdr.ramdisk_image = mem - initrd_size;
+		boot->hdr.ramdisk_size = initrd_size;
 		/* The bootloader type 0xFF means "unknown"; that's OK. */
-		*(unsigned char *)(boot+0x210) = 0xFF;
+		boot->hdr.type_of_loader = 0xFF;
 	}
 
 	/* Set up the initial linear pagetables, starting below the initrd. */
-	pgdir = setup_pagetables(mem, initrd_size, page_offset);
+	pgdir = setup_pagetables(mem, initrd_size);
 
 	/* The Linux boot header contains an "E820" memory map: ours is a
 	 * simple, single region. */
-	*(char*)(boot+E820NR) = 1;
-	*((struct e820entry *)(boot+E820MAP))
-		= ((struct e820entry) { 0, mem, E820_RAM });
+	boot->e820_entries = 1;
+	boot->e820_map[0] = ((struct e820entry) { 0, mem, E820_RAM });
 	/* The boot header contains a command line pointer: we put the command
-	 * line after the boot header (at address 4096) */
-	*(void **)(boot + 0x228) = boot + 4096;
-	concat(boot + 4096, argv+optind+2);
+	 * line after the boot header. */
+	boot->hdr.cmd_line_ptr = to_guest_phys(boot + 1);
+	concat((char *)(boot + 1), argv+optind+2);
 
-	/* The guest type value of "1" tells the Guest it's under lguest. */
-	*(int *)(boot + 0x23c) = 1;
+	/* Boot protocol version: 2.07 supports the fields for lguest. */
+	boot->hdr.version = 0x207;
+
+	/* The hardware_subarch value of "1" tells the Guest it's an lguest. */
+	boot->hdr.hardware_subarch = 1;
+
+	/* Tell the entry path not to try to reload segment registers. */
+	boot->hdr.loadflags |= KEEP_SEGMENTS;
 
 	/* We tell the kernel to initialize the Guest: this returns the open
 	 * /dev/lguest file descriptor. */
-	lguest_fd = tell_kernel(pgdir, start, page_offset);
+	lguest_fd = tell_kernel(pgdir, start);
 
 	/* We fork off a child process, which wakes the Launcher whenever one
 	 * of the input file descriptors needs attention.  Otherwise we would
 	 * run the Guest until it tries to output something. */
-	waker_fd = setup_waker(lguest_fd, &device_list);
+	waker_fd = setup_waker(lguest_fd);
 
 	/* Finally, run the Guest.  This doesn't return. */
-	run_guest(lguest_fd, &device_list);
+	run_guest(lguest_fd);
 }
 /*:*/
 
diff --git a/Documentation/lguest/lguest.txt b/Documentation/lguest/lguest.txt
index 821617b..7885ab2 100644
--- a/Documentation/lguest/lguest.txt
+++ b/Documentation/lguest/lguest.txt
@@ -6,7 +6,7 @@
 Linux developers and users to experiment with virtualization with the
 minimum of complexity.  Nonetheless, it should have sufficient
 features to make it useful for specific tasks, and, of course, you are
-encouraged to fork and enhance it.
+encouraged to fork and enhance it (see drivers/lguest/README).
 
 Features:
 
@@ -23,19 +23,30 @@
 
 Running Lguest:
 
-- Lguest runs the same kernel as guest and host.  You can configure
-  them differently, but usually it's easiest not to.
+- The easiest way to run lguest is to use same kernel as guest and host.
+  You can configure them differently, but usually it's easiest not to.
 
   You will need to configure your kernel with the following options:
 
-  CONFIG_HIGHMEM64G=n ("High Memory Support" "64GB")[1]
-  CONFIG_TUN=y/m ("Universal TUN/TAP device driver support")
-  CONFIG_EXPERIMENTAL=y ("Prompt for development and/or incomplete code/drivers")
-  CONFIG_PARAVIRT=y ("Paravirtualization support (EXPERIMENTAL)")
-  CONFIG_LGUEST=y/m ("Linux hypervisor example code")
+  "General setup":
+     "Prompt for development and/or incomplete code/drivers" = Y
+        (CONFIG_EXPERIMENTAL=y)
 
-  and I recommend:
-  CONFIG_HZ=100 ("Timer frequency")[2]
+  "Processor type and features":
+     "Paravirtualized guest support" = Y
+        "Lguest guest support" = Y
+     "High Memory Support" = off/4GB
+     "Alignment value to which kernel should be aligned" = 0x100000
+        (CONFIG_PARAVIRT=y, CONFIG_LGUEST_GUEST=y, CONFIG_HIGHMEM64G=n and
+         CONFIG_PHYSICAL_ALIGN=0x100000)
+
+  "Device Drivers":
+     "Network device support"
+        "Universal TUN/TAP device driver support" = M/Y
+           (CONFIG_TUN=m)
+     "Virtualization"
+        "Linux hypervisor example code" = M/Y
+           (CONFIG_LGUEST=m)
 
 - A tool called "lguest" is available in this directory: type "make"
   to build it.  If you didn't build your kernel in-tree, use "make
@@ -51,14 +62,17 @@
 	  dd if=/dev/zero of=rootfile bs=1M count=2048
 	  qemu -cdrom image.iso -hda rootfile -net user -net nic -boot d
 
+  Make sure that you install a getty on /dev/hvc0 if you want to log in on the
+  console!
+
 - "modprobe lg" if you built it as a module.
 
 - Run an lguest as root:
 
-      Documentation/lguest/lguest 64m vmlinux --tunnet=192.168.19.1 --block=rootfile root=/dev/lgba
+      Documentation/lguest/lguest 64 vmlinux --tunnet=192.168.19.1 --block=rootfile root=/dev/vda
 
    Explanation:
-    64m: the amount of memory to use.
+    64: the amount of memory to use, in MB.
 
     vmlinux: the kernel image found in the top of your build directory.  You
        can also use a standard bzImage.
@@ -66,10 +80,10 @@
     --tunnet=192.168.19.1: configures a "tap" device for networking with this
        IP address.
 
-    --block=rootfile: a file or block device which becomes /dev/lgba
+    --block=rootfile: a file or block device which becomes /dev/vda
        inside the guest.
 
-    root=/dev/lgba: this (and anything else on the command line) are
+    root=/dev/vda: this (and anything else on the command line) are
        kernel boot parameters.
 
 - Configuring networking.  I usually have the host masquerade, using
@@ -99,31 +113,7 @@
   "--sharenet=<filename>": any two guests using the same file are on
   the same network.  This file is created if it does not exist.
 
-Lguest I/O model:
+There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest
 
-Lguest uses a simplified DMA model plus shared memory for I/O.  Guests
-can communicate with each other if they share underlying memory
-(usually by the lguest program mmaping the same file), but they can
-use any non-shared memory to communicate with the lguest process.
-
-Guests can register DMA buffers at any key (must be a valid physical
-address) using the LHCALL_BIND_DMA(key, dmabufs, num<<8|irq)
-hypercall.  "dmabufs" is the physical address of an array of "num"
-"struct lguest_dma": each contains a used_len, and an array of
-physical addresses and lengths.  When a transfer occurs, the
-"used_len" field of one of the buffers which has used_len 0 will be
-set to the length transferred and the irq will fire.
-
-Using an irq value of 0 unbinds the dma buffers.
-
-To send DMA, the LHCALL_SEND_DMA(key, dma_physaddr) hypercall is used,
-and the bytes used is written to the used_len field.  This can be 0 if
-noone else has bound a DMA buffer to that key or some other error.
-DMA buffers bound by the same guest are ignored.
-
-Cheers!
+Good luck!
 Rusty Russell rusty@rustcorp.com.au.
-
-[1] These are on various places on the TODO list, waiting for you to
-    get annoyed enough at the limitation to fix it.
-[2] Lguest is not yet tickless when idle.  See [1].
diff --git a/Documentation/m68k/kernel-options.txt b/Documentation/m68k/kernel-options.txt
index 8a523f6..248589e 100644
--- a/Documentation/m68k/kernel-options.txt
+++ b/Documentation/m68k/kernel-options.txt
@@ -890,10 +890,7 @@
 5.5.2) noasync
 --------------
 
-Syntax: noasync:0
-
-  Disables async and sync negotiation for all devices.  Any value
-  after the colon is acceptable (and has the same effect).
+[OBSOLETE, REMOVED]
 
 5.5.3) nodisconnect
 -------------------
diff --git a/Documentation/markers.txt b/Documentation/markers.txt
new file mode 100644
index 0000000..295a71b
--- /dev/null
+++ b/Documentation/markers.txt
@@ -0,0 +1,81 @@
+ 	             Using the Linux Kernel Markers
+
+			    Mathieu Desnoyers
+
+
+This document introduces Linux Kernel Markers and their use. It provides
+examples of how to insert markers in the kernel and connect probe functions to
+them and provides some examples of probe functions.
+
+
+* Purpose of markers
+
+A marker placed in code provides a hook to call a function (probe) that you can
+provide at runtime. A marker can be "on" (a probe is connected to it) or "off"
+(no probe is attached). When a marker is "off" it has no effect, except for
+adding a tiny time penalty (checking a condition for a branch) and space
+penalty (adding a few bytes for the function call at the end of the
+instrumented function and adds a data structure in a separate section).  When a
+marker is "on", the function you provide is called each time the marker is
+executed, in the execution context of the caller. When the function provided
+ends its execution, it returns to the caller (continuing from the marker site).
+
+You can put markers at important locations in the code. Markers are
+lightweight hooks that can pass an arbitrary number of parameters,
+described in a printk-like format string, to the attached probe function.
+
+They can be used for tracing and performance accounting.
+
+
+* Usage
+
+In order to use the macro trace_mark, you should include linux/marker.h.
+
+#include <linux/marker.h>
+
+And,
+
+trace_mark(subsystem_event, "%d %s", someint, somestring);
+Where :
+- subsystem_event is an identifier unique to your event
+    - subsystem is the name of your subsystem.
+    - event is the name of the event to mark.
+- "%d %s" is the formatted string for the serializer.
+- someint is an integer.
+- somestring is a char pointer.
+
+Connecting a function (probe) to a marker is done by providing a probe (function
+to call) for the specific marker through marker_probe_register() and can be
+activated by calling marker_arm(). Marker deactivation can be done by calling
+marker_disarm() as many times as marker_arm() has been called. Removing a probe
+is done through marker_probe_unregister(); it will disarm the probe and make
+sure there is no caller left using the probe when it returns. Probe removal is
+preempt-safe because preemption is disabled around the probe call. See the
+"Probe example" section below for a sample probe module.
+
+The marker mechanism supports inserting multiple instances of the same marker.
+Markers can be put in inline functions, inlined static functions, and
+unrolled loops as well as regular functions.
+
+The naming scheme "subsystem_event" is suggested here as a convention intended
+to limit collisions. Marker names are global to the kernel: they are considered
+as being the same whether they are in the core kernel image or in modules.
+Conflicting format strings for markers with the same name will cause the markers
+to be detected to have a different format string not to be armed and will output
+a printk warning which identifies the inconsistency:
+
+"Format mismatch for probe probe_name (format), marker (format)"
+
+
+* Probe / marker example
+
+See the example provided in samples/markers/src
+
+Compile them with your kernel.
+
+Run, as root :
+modprobe marker-example (insmod order is not important)
+modprobe probe-example
+cat /proc/marker-example (returns an expected error)
+rmmod marker-example probe-example
+dmesg
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 650657c..4e17beb 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -1479,7 +1479,8 @@
 
 Any atomic operation that modifies some state in memory and returns information
 about the state (old or new) implies an SMP-conditional general memory barrier
-(smp_mb()) on each side of the actual operation.  These include:
+(smp_mb()) on each side of the actual operation (with the exception of
+explicit lock operations, described later).  These include:
 
 	xchg();
 	cmpxchg();
@@ -1536,10 +1537,19 @@
 do need memory barriers as a lock primitive generally has to do things in a
 specific order.
 
-
 Basically, each usage case has to be carefully considered as to whether memory
 barriers are needed or not.
 
+The following operations are special locking primitives:
+
+	test_and_set_bit_lock();
+	clear_bit_unlock();
+	__clear_bit_unlock();
+
+These implement LOCK-class and UNLOCK-class operations. These should be used in
+preference to other operations when implementing locking primitives, because
+their implementations can be optimised on many architectures.
+
 [!] Note that special memory barrier primitives are available for these
 situations because on some CPUs the atomic instructions used imply full memory
 barriers, and so barrier instructions are superfluous in conjunction with them,
diff --git a/Documentation/memory-hotplug.txt b/Documentation/memory-hotplug.txt
index 5fbcc22..168117b 100644
--- a/Documentation/memory-hotplug.txt
+++ b/Documentation/memory-hotplug.txt
@@ -2,7 +2,8 @@
 Memory Hotplug
 ==============
 
-Last Updated: Jul 28 2007
+Created:					Jul 28 2007
+Add description of notifier of memory hotplug	Oct 11 2007
 
 This document is about memory hotplug including how-to-use and current status.
 Because Memory Hotplug is still under development, contents of this text will
@@ -24,7 +25,8 @@
   6.1 Memory offline and ZONE_MOVABLE
   6.2. How to offline memory
 7. Physical memory remove
-8. Future Work List
+8. Memory hotplug event notifier
+9. Future Work List
 
 Note(1): x86_64's has special implementation for memory hotplug.
          This text does not describe it.
@@ -307,8 +309,58 @@
  - Notification completion of remove works by OS to firmware.
  - Guard from remove if not yet.
 
+--------------------------------
+8. Memory hotplug event notifier
+--------------------------------
+Memory hotplug has event notifer. There are 6 types of notification.
+
+MEMORY_GOING_ONLINE
+  Generated before new memory becomes available in order to be able to
+  prepare subsystems to handle memory. The page allocator is still unable
+  to allocate from the new memory.
+
+MEMORY_CANCEL_ONLINE
+  Generated if MEMORY_GOING_ONLINE fails.
+
+MEMORY_ONLINE
+  Generated when memory has succesfully brought online. The callback may
+  allocate pages from the new memory.
+
+MEMORY_GOING_OFFLINE
+  Generated to begin the process of offlining memory. Allocations are no
+  longer possible from the memory but some of the memory to be offlined
+  is still in use. The callback can be used to free memory known to a
+  subsystem from the indicated memory section.
+
+MEMORY_CANCEL_OFFLINE
+  Generated if MEMORY_GOING_OFFLINE fails. Memory is available again from
+  the section that we attempted to offline.
+
+MEMORY_OFFLINE
+  Generated after offlining memory is complete.
+
+A callback routine can be registered by
+  hotplug_memory_notifier(callback_func, priority)
+
+The second argument of callback function (action) is event types of above.
+The third argument is passed by pointer of struct memory_notify.
+
+struct memory_notify {
+       unsigned long start_pfn;
+       unsigned long nr_pages;
+       int status_cahnge_nid;
+}
+
+start_pfn is start_pfn of online/offline memory.
+nr_pages is # of pages of online/offline memory.
+status_change_nid is set node id when N_HIGH_MEMORY of nodemask is (will be)
+set/clear. It means a new(memoryless) node gets new memory by online and a
+node loses all memory. If this is -1, then nodemask status is not changed.
+If status_changed_nid >= 0, callback should create/discard structures for the
+node if necessary.
+
 --------------
-8. Future Work
+9. Future Work
 --------------
   - allowing memory hot-add to ZONE_MOVABLE. maybe we need some switch like
     sysctl or new control file.
diff --git a/Documentation/mips/00-INDEX b/Documentation/mips/00-INDEX
index 9df8a2e..3f13bf8 100644
--- a/Documentation/mips/00-INDEX
+++ b/Documentation/mips/00-INDEX
@@ -4,5 +4,3 @@
 	- README for MIPS AU1XXX IDE driver.
 GT64120.README
 	- README for dir with info on MIPS boards using GT-64120 or GT-64120A.
-time.README
-	- README for MIPS time services.
diff --git a/Documentation/mips/AU1xxx_IDE.README b/Documentation/mips/AU1xxx_IDE.README
index afb31c1..5c83341 100644
--- a/Documentation/mips/AU1xxx_IDE.README
+++ b/Documentation/mips/AU1xxx_IDE.README
@@ -59,7 +59,7 @@
   CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA    - enable the PIO+DBDMA mode
   CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA  - enable the MWDMA mode
   CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - set Burstable FIFO in DBDMA
-                                           controler
+                                           controller
   CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ - maximum transfer size
                                            per descriptor
 
diff --git a/Documentation/mips/time.README b/Documentation/mips/time.README
deleted file mode 100644
index a4ce603..0000000
--- a/Documentation/mips/time.README
+++ /dev/null
@@ -1,173 +0,0 @@
-README for MIPS time services
-
-Jun Sun
-jsun@mvista.com or jsun@junsun.net
-
-
-ABOUT
------
-This file describes the new arch/mips/kernel/time.c, related files and the 
-services they provide. 
-
-If you are short in patience and just want to know how to use time.c for a 
-new board or convert an existing board, go to the last section.
-
-
-FILES, COMPATABILITY AND CONFIGS
----------------------------------
-
-The old arch/mips/kernel/time.c is renamed to old-time.c.
-
-A new time.c is put there, together with include/asm-mips/time.h.
-
-Two configs variables are introduced, CONFIG_OLD_TIME_C and CONFIG_NEW_TIME_C.
-So we allow boards using 
-
-	1) old time.c (CONFIG_OLD_TIME_C)
-	2) new time.c (CONFIG_NEW_TIME_C)
-	3) neither (their own private time.c)
-
-However, it is expected every board will move to the new time.c in the near
-future.
-
-
-WHAT THE NEW CODE PROVIDES?
---------------------------- 
-
-The new time code provide the following services:
-
-  a) Implements functions required by Linux common code:
-	time_init
-
-  b) provides an abstraction of RTC and null RTC implementation as default.
-	extern unsigned long (*rtc_get_time)(void);
-	extern int (*rtc_set_time)(unsigned long);
-
-  c) high-level and low-level timer interrupt routines where the timer
-     interrupt source  may or may not be the CPU timer.  The high-level
-     routine is dispatched through do_IRQ() while the low-level is
-     dispatched in assemably code (usually int-handler.S)
-
-
-WHAT THE NEW CODE REQUIRES?
----------------------------
-
-For the new code to work properly, each board implementation needs to supply
-the following functions or values:
-
-  a) board_time_init - a function pointer.  Invoked at the beginnig of
-     time_init().  It is optional.
-	1. (optional) set up RTC routines
-	2. (optional) calibrate and set the mips_hpt_frequency
-
-  b) plat_timer_setup - a function pointer.  Invoked at the end of time_init()
-	1. (optional) over-ride any decisions made in time_init()
-	2. set up the irqaction for timer interrupt.
-	3. enable the timer interrupt
-
-  c) (optional) board-specific RTC routines.
-
-  d) (optional) mips_hpt_frequency - It must be definied if the board
-     is using CPU counter for timer interrupt.
-
-
-PORTING GUIDE
--------------
-
-Step 1: decide how you like to implement the time services.
-
-  a) does this board have a RTC?  If yes, implement the two RTC funcs.
-
-  b) does the CPU have counter/compare registers? 
-
-     If the answer is no, you need a timer to provide the timer interrupt
-     at 100 HZ speed.
-
-  c) The following sub steps assume your CPU has counter register.
-     Do you plan to use the CPU counter register as the timer interrupt
-     or use an exnternal timer?
-
-     In order to use CPU counter register as the timer interrupt source, you
-     must know the counter speed (mips_hpt_frequency).  It is usually the
-     same as the CPU speed or an integral divisor of it.
-
-  d) decide on whether you want to use high-level or low-level timer
-     interrupt routines.  The low-level one is presumably faster, but should
-     not make too mcuh difference.
-
-
-Step 2:  the machine setup() function
-
-  If you supply board_time_init(), set the function poointer.
-
-
-Step 3: implement rtc routines, board_time_init() and plat_timer_setup()
-  if needed.
-
-  board_time_init() -
-  	a) (optional) set up RTC routines,
-        b) (optional) calibrate and set the mips_hpt_frequency
- 	    (only needed if you intended to use cpu counter as timer interrupt
- 	     source)
-
-  plat_timer_setup() -
- 	a) (optional) over-write any choices made above by time_init().
- 	b) machine specific code should setup the timer irqaction.
- 	c) enable the timer interrupt
-
-
-  If the RTC chip is a common chip, I suggest the routines are put under
-  arch/mips/libs.  For example, for DS1386 chip, one would create
-  rtc-ds1386.c under arch/mips/lib directory.  Add the following line to
-  the arch/mips/lib/Makefile:
-
-	obj-$(CONFIG_DDB5476) += rtc-ds1386.o
-
-Step 4: if you are using low-level timer interrupt, change your interrupt
-  dispathcing code to check for timer interrupt and jump to 
-  ll_timer_interrupt() directly  if one is detected.
-
-Step 5: Modify arch/mips/config.in and add CONFIG_NEW_TIME_C to your machine.
-  Modify the appropriate defconfig if applicable.
-
-Final notes: 
-
-For some tricky cases, you may need to add your own wrapper functions 
-for some of the functions in time.c.  
-
-For example, you may define your own timer interrupt routine, which does
-some of its own processing and then calls timer_interrupt().
-
-You can also over-ride any of the built-in functions (RTC routines
-and/or timer interrupt routine).
-
-
-PORTING NOTES FOR SMP
-----------------------
-
-If you have a SMP box, things are slightly more complicated.
-
-The time service running every jiffy is logically divided into two parts:
-
-  1) the one for the whole system  (defined in timer_interrupt())
-  2) the one that should run for each CPU (defined in local_timer_interrupt())
-
-You need to decide on your timer interrupt sources.
-
-  case 1) - whole system has only one timer interrupt delivered to one CPU
-
-	In this case, you set up timer interrupt as in UP systems.  In addtion,
-	you need to set emulate_local_timer_interrupt to 1 so that other
-	CPUs get to call local_timer_interrupt().
-
-	THIS IS CURRENTLY NOT IMPLEMNETED.  However, it is rather easy to write
-	one should such a need arise.  You simply make a IPI call.
-
-  case 2) - each CPU has a separate timer interrupt
-
-	In this case, you need to set up IRQ such that each of them will
-	call local_timer_interrupt().  In addition, you need to arrange
-	one and only one of them to call timer_interrupt().
-
-	You can also do the low-level version of those interrupt routines,
-	following similar dispatching routes described above.
diff --git a/Documentation/mutex-design.txt b/Documentation/mutex-design.txt
index 51f9351..aa60d1f 100644
--- a/Documentation/mutex-design.txt
+++ b/Documentation/mutex-design.txt
@@ -133,4 +133,6 @@
  int  mutex_trylock(struct mutex *lock);
  void mutex_unlock(struct mutex *lock);
  int  mutex_is_locked(struct mutex *lock);
-
+ void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
+ int  mutex_lock_interruptible_nested(struct mutex *lock,
+                                      unsigned int subclass);
diff --git a/Documentation/networking/bcm43xx.txt b/Documentation/networking/bcm43xx.txt
index a136721..d602c8d 100644
--- a/Documentation/networking/bcm43xx.txt
+++ b/Documentation/networking/bcm43xx.txt
@@ -37,7 +37,7 @@
 required. The firmware used by the chip is the intellectual property
 of Broadcom and they have not given the bcm43xx team redistribution
 rights to this firmware.  Since we cannot legally redistribute
-the firwmare we cannot include it with the driver. Furthermore, it
+the firmware we cannot include it with the driver. Furthermore, it
 cannot be placed in the downloadable archives of any distributing
 organization; therefore, the user is responsible for obtaining the
 firmware and placing it in the appropriate location so that the driver
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 6ae2fef..747a5d1 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -293,7 +293,7 @@
 	when the connection closes, so that connections established in the
 	near future can use these to set initial conditions.  Usually, this
 	increases overall performance, but may sometimes cause performance
-	degredation.  If set, TCP will not cache metrics on closing
+	degradation.  If set, TCP will not cache metrics on closing
 	connections.
 
 tcp_orphan_retries - INTEGER
diff --git a/Documentation/networking/rxrpc.txt b/Documentation/networking/rxrpc.txt
index c36b64b0..c3669a3 100644
--- a/Documentation/networking/rxrpc.txt
+++ b/Documentation/networking/rxrpc.txt
@@ -689,7 +689,7 @@
      buffers manipulated directly.
 
 To use the RxRPC facility, a kernel utility must still open an AF_RXRPC socket,
-bind an addess as appropriate and listen if it's to be a server socket, but
+bind an address as appropriate and listen if it's to be a server socket, but
 then it passes this to the kernel interface functions.
 
 The kernel interface functions are as follows:
diff --git a/Documentation/networking/udplite.txt b/Documentation/networking/udplite.txt
index 6be09ba..b6409ca 100644
--- a/Documentation/networking/udplite.txt
+++ b/Documentation/networking/udplite.txt
@@ -12,7 +12,7 @@
   For in-depth information, you can consult:
 
    o The UDP-Lite Homepage: http://www.erg.abdn.ac.uk/users/gerrit/udp-lite/
-       Fom here you can also download some example application source code.
+       From here you can also download some example application source code.
 
    o The UDP-Lite HOWTO on
        http://www.erg.abdn.ac.uk/users/gerrit/udp-lite/files/UDP-Lite-HOWTO.txt
@@ -223,7 +223,7 @@
   While it is important that such cases are dealt with correctly, they
   are (annoyingly) rare: UDP-Lite is designed for optimising multimedia
   performance over wireless (or generally noisy) links and thus smaller
-  coverage lenghts are likely to be expected.
+  coverage lengths are likely to be expected.
 
 
   V) UDP-LITE RUNTIME STATISTICS AND THEIR MEANING
@@ -259,7 +259,7 @@
   VI) IPTABLES
 
   There is packet match support for UDP-Lite as well as support for the LOG target.
-  If you copy and paste the following line into /etc/protcols,
+  If you copy and paste the following line into /etc/protocols,
 
   udplite 136     UDP-Lite        # UDP-Lite [RFC 3828]
 
diff --git a/Documentation/parport-lowlevel.txt b/Documentation/parport-lowlevel.txt
index 8f23024..265fcdc 100644
--- a/Documentation/parport-lowlevel.txt
+++ b/Documentation/parport-lowlevel.txt
@@ -25,7 +25,6 @@
   parport_open
   parport_close
   parport_device_id
-  parport_device_num
   parport_device_coords
   parport_find_class
   parport_find_device
@@ -735,7 +734,7 @@
 
 SEE ALSO
 
-parport_register_device, parport_device_num
+parport_register_device
 
 parport_close - unregister device for particular device number
 -------------
@@ -787,29 +786,7 @@
 
 SEE ALSO
 
-parport_find_class, parport_find_device, parport_device_num
-
-parport_device_num - convert device coordinates to device number
-------------------
-
-SYNOPSIS
-
-#include <linux/parport.h>
-
-int parport_device_num (int parport, int mux, int daisy);
-
-DESCRIPTION
-
-Convert between device coordinates (port, multiplexor, daisy chain
-address) and device number (zero-based).
-
-RETURN VALUE
-
-Device number, or -1 if no device at given coordinates.
-
-SEE ALSO
-
-parport_device_coords, parport_open, parport_device_id
+parport_find_class, parport_find_device
 
 parport_device_coords - convert device number to device coordinates
 ------------------
@@ -833,7 +810,7 @@
 
 SEE ALSO
 
-parport_device_num, parport_open, parport_device_id
+parport_open, parport_device_id
 
 parport_find_class - find a device by its class
 ------------------
diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt
index 1a85e2b..57aef2f 100644
--- a/Documentation/power/basic-pm-debugging.txt
+++ b/Documentation/power/basic-pm-debugging.txt
@@ -78,8 +78,8 @@
 In case the STD does not work on your system even in the minimal configuration
 and compiling more drivers as modules is not practical or some modules cannot
 be unloaded, you can use one of the more advanced debugging techniques to find
-the problem.  First, if there is a serial port in your box, you can set the
-CONFIG_DISABLE_CONSOLE_SUSPEND kernel configuration option and try to log kernel
+the problem.  First, if there is a serial port in your box, you can boot the
+kernel with the 'no_console_suspend' parameter and try to log kernel
 messages using the serial console.  This may provide you with some information
 about the reasons of the suspend (resume) failure.  Alternatively, it may be
 possible to use a FireWire port for debugging with firescope
diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt
index 04dc1cf..38b5724 100644
--- a/Documentation/power/freezing-of-tasks.txt
+++ b/Documentation/power/freezing-of-tasks.txt
@@ -19,12 +19,13 @@
 Namely, as the first step of the hibernation procedure the function
 freeze_processes() (defined in kernel/power/process.c) is called.  It executes
 try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and
-sends a fake signal to each of them.  A task that receives such a signal and has
-TIF_FREEZE set, should react to it by calling the refrigerator() function
-(defined in kernel/power/process.c), which sets the task's PF_FROZEN flag,
-changes its state to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is
-cleared for it.  Then, we say that the task is 'frozen' and therefore the set of
-functions handling this mechanism is called 'the freezer' (these functions are
+either wakes them up, if they are kernel threads, or sends fake signals to them,
+if they are user space processes.  A task that has TIF_FREEZE set, should react
+to it by calling the function called refrigerator() (defined in
+kernel/power/process.c), which sets the task's PF_FROZEN flag, changes its state
+to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it.
+Then, we say that the task is 'frozen' and therefore the set of functions
+handling this mechanism is referred to as 'the freezer' (these functions are
 defined in kernel/power/process.c and include/linux/freezer.h).  User space
 processes are generally frozen before kernel threads.
 
@@ -35,21 +36,27 @@
 
 For user space processes try_to_freeze() is called automatically from the
 signal-handling code, but the freezable kernel threads need to call it
-explicitly in suitable places.  The code to do this may look like the following:
+explicitly in suitable places or use the wait_event_freezable() or
+wait_event_freezable_timeout() macros (defined in include/linux/freezer.h)
+that combine interruptible sleep with checking if TIF_FREEZE is set and calling
+try_to_freeze().  The main loop of a freezable kernel thread may look like the
+following one:
 
+	set_freezable();
 	do {
 		hub_events();
-		wait_event_interruptible(khubd_wait,
-					!list_empty(&hub_event_list));
-		try_to_freeze();
-	} while (!signal_pending(current));
+		wait_event_freezable(khubd_wait,
+				!list_empty(&hub_event_list) ||
+				kthread_should_stop());
+	} while (!kthread_should_stop() || !list_empty(&hub_event_list));
 
 (from drivers/usb/core/hub.c::hub_thread()).
 
 If a freezable kernel thread fails to call try_to_freeze() after the freezer has
 set TIF_FREEZE for it, the freezing of tasks will fail and the entire
 hibernation operation will be cancelled.  For this reason, freezable kernel
-threads must call try_to_freeze() somewhere.
+threads must call try_to_freeze() somewhere or use one of the
+wait_event_freezable() and wait_event_freezable_timeout() macros.
 
 After the system memory state has been restored from a hibernation image and
 devices have been reinitialized, the function thaw_processes() is called in
@@ -81,7 +88,16 @@
 The majority of these are user space processes, but if any of the kernel threads
 may cause something like this to happen, they have to be freezable.
 
-2. The second reason is to prevent user space processes and some kernel threads
+2. Next, to create the hibernation image we need to free a sufficient amount of
+memory (approximately 50% of available RAM) and we need to do that before
+devices are deactivated, because we generally need them for swapping out.  Then,
+after the memory for the image has been freed, we don't want tasks to allocate
+additional memory and we prevent them from doing that by freezing them earlier.
+[Of course, this also means that device drivers should not allocate substantial
+amounts of memory from their .suspend() callbacks before hibernation, but this
+is e separate issue.]
+
+3. The third reason is to prevent user space processes and some kernel threads
 from interfering with the suspending and resuming of devices.  A user space
 process running on a second CPU while we are suspending devices may, for
 example, be troublesome and without the freezing of tasks we would need some
@@ -111,7 +127,7 @@
 thawed after the driver's .resume() callback has run, so it won't be accessing
 the device while it's suspended.
 
-3. Another reason for freezing tasks is to prevent user space processes from
+4. Another reason for freezing tasks is to prevent user space processes from
 realizing that hibernation (or suspend) operation takes place.  Ideally, user
 space processes should not notice that such a system-wide operation has occurred
 and should continue running without any problems after the restore (or resume
diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt
index fd5192a..e67211f 100644
--- a/Documentation/power/interface.txt
+++ b/Documentation/power/interface.txt
@@ -20,7 +20,7 @@
 /sys/power/disk controls the operating mode of the suspend-to-disk
 mechanism. Suspend-to-disk can be handled in several ways. We have a
 few options for putting the system to sleep - using the platform driver
-(e.g. ACPI or other pm_ops), powering off the system or rebooting the
+(e.g. ACPI or other suspend_ops), powering off the system or rebooting the
 system (for testing).
 
 Additionally, /sys/power/disk can be used to turn on one of the two testing
diff --git a/Documentation/power/swsusp-and-swap-files.txt b/Documentation/power/swsusp-and-swap-files.txt
index 06f911a..f281886 100644
--- a/Documentation/power/swsusp-and-swap-files.txt
+++ b/Documentation/power/swsusp-and-swap-files.txt
@@ -39,7 +39,7 @@
 where <swap_file_partition> is the partition on which the swap file is located
 and <swap_file_offset> is the offset of the swap header determined by the
 application in 2) (of course, this step may be carried out automatically
-by the same application that determies the swap file's header offset using the
+by the same application that determines the swap file's header offset using the
 FIBMAP ioctl)
 
 OR
diff --git a/Documentation/powerpc/eeh-pci-error-recovery.txt b/Documentation/powerpc/eeh-pci-error-recovery.txt
index 4530d1b..df7afe4 100644
--- a/Documentation/powerpc/eeh-pci-error-recovery.txt
+++ b/Documentation/powerpc/eeh-pci-error-recovery.txt
@@ -36,8 +36,8 @@
 EEH was originally designed to guard against hardware failure, such
 as PCI cards dying from heat, humidity, dust, vibration and bad
 electrical connections. The vast majority of EEH errors seen in
-"real life" are due to eithr poorly seated PCI cards, or,
-unfortunately quite commonly, due device driver bugs, device firmware
+"real life" are due to either poorly seated PCI cards, or,
+unfortunately quite commonly, due to device driver bugs, device firmware
 bugs, and sometimes PCI card hardware bugs.
 
 The most common software bug, is one that causes the device to
diff --git a/Documentation/powerpc/mpc52xx-device-tree-bindings.txt b/Documentation/powerpc/mpc52xx-device-tree-bindings.txt
index e59fcbb..5e03610 100644
--- a/Documentation/powerpc/mpc52xx-device-tree-bindings.txt
+++ b/Documentation/powerpc/mpc52xx-device-tree-bindings.txt
@@ -17,12 +17,12 @@
 describes what devices are present on the board and how they are
 connected.  The device tree can either be passed as a binary blob (as
 described in Documentation/powerpc/booting-without-of.txt), or passed
-by Open Firmare (IEEE 1275) compatible firmware using an OF compatible
+by Open Firmware (IEEE 1275) compatible firmware using an OF compatible
 client interface API.
 
 This document specifies the requirements on the device-tree for mpc5200
 based boards.  These requirements are above and beyond the details
-specified in either the OpenFirmware spec or booting-without-of.txt
+specified in either the Open Firmware spec or booting-without-of.txt
 
 All new mpc5200-based boards are expected to match this document.  In
 cases where this document is not sufficient to support a new board port,
@@ -73,8 +73,8 @@
 selected.
 
 The split between the MPC5200 and the MPC5200B leaves a bit of a
-connundrum.  How should the compatible property be set up to provide
-maximum compatability information; but still acurately describe the
+conundrum.  How should the compatible property be set up to provide
+maximum compatibility information; but still accurately describe the
 chip?  For the MPC5200; the answer is easy.  Most of the SoC devices
 originally appeared on the MPC5200.  Since they didn't exist anywhere
 else; the 5200 compatible properties will contain only one item;
@@ -84,7 +84,7 @@
 silicon bugs and it adds a small number of enhancements.  Most of the
 devices either provide exactly the same interface as on the 5200.  A few
 devices have extra functions but still have a backwards compatible mode.
-To express this infomation as completely as possible, 5200B device trees
+To express this information as completely as possible, 5200B device trees
 should have two items in the compatible list;
 "mpc5200b-<device>\0mpc5200-<device>".  It is *strongly* recommended
 that 5200B device trees follow this convention (instead of only listing
@@ -185,7 +185,7 @@
 Recommended soc5200 child nodes; populate as needed for your board
 name		device_type	compatible	  Description
 ----		-----------	----------	  -----------
-gpt@<addr>	gpt		mpc5200-gpt	  General purpose timers
+gpt@<addr>	gpt		fsl,mpc5200-gpt	  General purpose timers
 rtc@<addr>	rtc		mpc5200-rtc	  Real time clock
 mscan@<addr>	mscan		mpc5200-mscan	  CAN bus controller
 pci@<addr>	pci		mpc5200-pci	  PCI bridge
@@ -199,7 +199,7 @@
 ata@<addr>	ata		mpc5200-ata	  IDE ATA interface
 i2c@<addr>	i2c		mpc5200-i2c	  I2C controller
 usb@<addr>	usb-ohci-be	mpc5200-ohci,ohci-be	USB controller
-xlb@<addr>	xlb		mpc5200-xlb	  XLB arbritrator
+xlb@<addr>	xlb		mpc5200-xlb	  XLB arbitrator
 
 Important child node properties
 name		type		description
@@ -213,7 +213,7 @@
 5) General Purpose Timer nodes (child of soc5200 node)
 On the mpc5200 and 5200b, GPT0 has a watchdog timer function.  If the board
 design supports the internal wdt, then the device node for GPT0 should
-include the empty property 'has-wdt'.
+include the empty property 'fsl,has-wdt'.
 
 6) PSC nodes (child of soc5200 node)
 PSC nodes can define the optional 'port-number' property to force assignment
diff --git a/Documentation/scsi/aic79xx.txt b/Documentation/scsi/aic79xx.txt
index 6aa9a89..683ccae 100644
--- a/Documentation/scsi/aic79xx.txt
+++ b/Documentation/scsi/aic79xx.txt
@@ -120,7 +120,7 @@
           list size to avoid SCSI malloc pool fragmentation.
         - Cleanup channel display in our /proc output.
         - Workaround duplicate device entries in the mid-layer
-          devlice list during add-single-device.
+          device list during add-single-device.
 
    1.3.6 (March 28th, 2003)
         - Correct a double free in the Domain Validation code.
diff --git a/Documentation/scsi/aic7xxx.txt b/Documentation/scsi/aic7xxx.txt
index 5f34d2b..b7e238c 100644
--- a/Documentation/scsi/aic7xxx.txt
+++ b/Documentation/scsi/aic7xxx.txt
@@ -159,7 +159,7 @@
         - Add support for 2.5.X's scsi_report_device_reset().
 
    6.2.34 (May 5th, 2003)
-        - Fix locking regression instroduced in 6.2.29 that
+        - Fix locking regression introduced in 6.2.29 that
           could cause a lock order reversal between the io_request_lock
           and our per-softc lock.  This was only possible on RH9,
           SuSE, and kernel.org 2.4.X kernels.
@@ -264,7 +264,7 @@
               Option: tag_info:{{value[,value...]}[,{value[,value...]}...]}
           Definition: Set the per-target tagged queue depth on a
                       per controller basis.  Both controllers and targets
-                      may be ommitted indicating that they should retain
+                      may be omitted indicating that they should retain
                       the default tag depth.
             Examples: tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32}
                         On Controller 0
@@ -290,7 +290,7 @@
    -----------------------------------------------------------------
               Option: dv: {value[,value...]} 
           Definition: Set Domain Validation Policy on a per-controller basis.
-                      Controllers may be ommitted indicating that
+                      Controllers may be omitted indicating that
                       they should retain the default read streaming setting.
              Example: dv:{-1,0,,1,1,0}
                         On Controller 0 leave DV at its default setting.
diff --git a/Documentation/scsi/arcmsr_spec.txt b/Documentation/scsi/arcmsr_spec.txt
index 5e00423..45d9482 100644
--- a/Documentation/scsi/arcmsr_spec.txt
+++ b/Documentation/scsi/arcmsr_spec.txt
@@ -3,7 +3,7 @@
 *******************************************************************************
 **	Usage of IOP331 adapter
 **	(All In/Out is in IOP331's view)
-**	1. Message 0 --> InitThread message and retrun code
+**	1. Message 0 --> InitThread message and return code
 **	2. Doorbell is used for RS-232 emulation
 **		inDoorBell :    bit0 -- data in ready
 **			(DRIVER DATA WRITE OK)
diff --git a/Documentation/scsi/ibmmca.txt b/Documentation/scsi/ibmmca.txt
index a08e225..a810421 100644
--- a/Documentation/scsi/ibmmca.txt
+++ b/Documentation/scsi/ibmmca.txt
@@ -21,7 +21,7 @@
    versions older than 4.0 do not work with kernels 2.4.0 or later! If you
    try to compile your kernel with the wrong driver source, the 
    compilation is aborted and you get a corresponding error message. This is
-   no bug in the driver. It prevents you from using the wrong sourcecode
+   no bug in the driver; it prevents you from using the wrong source code
    with the wrong kernel version.
 
    Authors of this Driver
@@ -58,7 +58,7 @@
    5 Users' Manual
      5.1 Commandline Parameters
      5.2 Troubleshooting
-     5.3 Bugreports
+     5.3 Bug reports
      5.4 Support WWW-page
    6 References
    7 Credits to
@@ -71,13 +71,13 @@
 
    1 Abstract
    ----------
-   This README-file describes the IBM SCSI-subsystem low level driver for 
-   Linux. The descriptions which were formerly kept in the source-code have 
-   been taken out to this file to easify the codes' readability. The driver 
+   This README-file describes the IBM SCSI-subsystem low level driver for
+   Linux. The descriptions which were formerly kept in the source code have
+   been taken out of this file to simplify the codes readability. The driver
    description has been updated, as most of the former description was already
-   quite outdated. The history of the driver development is also kept inside 
-   here. Multiple historical developments have been summarized to shorten the 
-   textsize a bit. At the end of this file you can find a small manual for 
+   quite outdated. The history of the driver development is also kept inside
+   here. Multiple historical developments have been summarized to shorten the
+   text size a bit. At the end of this file you can find a small manual for
    this driver and hints to get it running on your machine.
 
    2 Driver Description
@@ -186,7 +186,7 @@
    between 0 and 7). The IBM SCSI-2 F/W adapter offers this on up to two
    busses and provides support for 30 logical devices at the same time, where
    in wide-addressing mode you can have 16 puns with 32 luns on each device.
-   This section dexribes you the handling of devices on non-F/W adapters.
+   This section describes the handling of devices on non-F/W adapters.
    Just imagine, that you can have 16 * 32 = 512 devices on a F/W adapter
    which means a lot of possible devices for such a small machine.
 
@@ -209,10 +209,10 @@
    --------------------------------------------------------
    One consequence of information hiding is that the real (pun,lun)    
    numbers are also hidden. The two possibilities to get around this problem
-   is to offer fake pun/lun combinations to the operating system or to 
+   are to offer fake pun/lun combinations to the operating system or to 
    delete the whole mapping of the adapter and to reassign the ldns, using
    the immediate assign command of the SCSI-subsystem for probing through
-   all possible pun/lun combinations. a ldn is a "logical device number"
+   all possible pun/lun combinations.  An ldn is a "logical device number"
    which is used by IBM SCSI-subsystems to access some valid SCSI-device.
    At the beginning of the development of this driver, the following approach 
    was used:
@@ -251,9 +251,9 @@
    lun>0 or to non-existing devices, in order to satisfy the subsystem, if 
    there are less than 15 SCSI-devices connected. In the case of more than 15 
    devices, the dynamical mapping goes active. If the get_scsi[][] reports a 
-   device to be existant, but it has no ldn assigned, it gets a ldn out of 7 
-   to 14. The numbers are assigned in cyclic order. Therefore it takes 8 
-   dynamical reassignments on the SCSI-devices, until a certain device 
+   device to be existent, but it has no ldn assigned, it gets an ldn out of 7
+   to 14. The numbers are assigned in cyclic order, therefore it takes 8 
+   dynamical reassignments on the SCSI-devices until a certain device 
    loses its ldn again. This assures that dynamical remapping is avoided 
    during intense I/O between up to 15 SCSI-devices (means pun,lun 
    combinations). A further advantage of this method is that people who
@@ -551,7 +551,7 @@
       than devices are available, they are assigned to non existing pun,lun
       combinations to satisfy the adapter. With this, the dynamical mapping
       was possible to implement. (For further info see the text in the 
-      source-code and in the description below. Read the description
+      source code and in the description below. Read the description
       below BEFORE installing this driver on your system!)
    2) Changed the name IBMMCA_DRIVER_VERSION to IBMMCA_SCSI_DRIVER_VERSION.
    3) The LED-display shows on PS/2-95 no longer the ldn, but the SCSI-ID
@@ -762,9 +762,9 @@
    - Michael Lang
 
    Apr 23, 2000 (v3.2pre1)
-   1) During a very long time, I collected a huge amount of bugreports from
+   1) During a very long time, I collected a huge amount of bug reports from
       various people, trying really quite different things on their SCSI-
-      PS/2s. Today, all these bugreports are taken into account and should be
+      PS/2s. Today, all these bug reports are taken into account and should be
       mostly solved. The major topics were:
       - Driver crashes during boottime by no obvious reason.
       - Driver panics while the midlevel-SCSI-driver is trying to inquire
@@ -819,7 +819,7 @@
    - Michael Lang
    
    July 17, 2000 (v3.2pre8)
-   A long period of collecting bugreports from all corners of the world
+   A long period of collecting bug reports from all corners of the world
    now lead to the following corrections to the code:
    1) SCSI-2 F/W support crashed with a COMMAND ERROR. The reason for this 
       was that it is possible to disable Fast-SCSI for the external bus.
@@ -873,7 +873,7 @@
    July 26, 2000 (v3.2pre11)
    1) I passed a horrible weekend getting mad with NMIs on kernel 2.2.14 and
       a model 9595. Asking around in the community, nobody except of me has
-      seen such errors. Weired, but I am trying to recompile everything on
+      seen such errors. Weird, but I am trying to recompile everything on
       the model 9595. Maybe, as I use a specially modified gcc, that could
       cause problems. But, it was not the reason. The true background was,
       that the kernel was compiled for i386 and the 9595 has a 486DX-2. 
@@ -886,7 +886,7 @@
       alive rotator during boottime. This makes sense, when no monitor is 
       connected to the system. You can get rid of all display activity, if
       you do not use any parameter or just ibmmcascsi=activity, for the 
-      harddrive activity LED, existant on all PS/2, except models 8595-XXX.
+      harddrive activity LED, existent on all PS/2, except models 8595-XXX.
       If no monitor is available, please use ibmmcascsi=display, which works
       fine together with the linuxinfo utility for the LED-panel.
    - Michael Lang
@@ -1115,7 +1115,7 @@
         If this really happens, do also send e-mail to the maintainer, as
 	forced detection should be never necessary. Forced detection is in
 	principal some flaw of the driver adapter detection and goes into 
-	bugreports.
+	bug reports.
      Q: The driver screws up, if it starts to probe SCSI-devices, is there
         some way out of it?
      A: Yes, that was some recognition problem of the correct SCSI-adapter
@@ -1172,7 +1172,7 @@
 	recommended version is 3.2 or later. Here, the F/W support is in
 	a stable and reliable condition. Wide-addressing is in addition 
 	supported.
-     Q: I get a Ooops message and something like "killing interrupt".
+     Q: I get an Oops message and something like "killing interrupt".
      A: The reason for this is that the IBM SCSI-subsystem only sends a 
         termination status back, if some error appeared. In former releases
 	of the driver, it was not checked, if the termination status block
@@ -1213,21 +1213,21 @@
 	problem. Not yet tried, but guessing that it could work. To get this,
 	set unchecked_isa_dma argument of ibmmca.h from 0 to 1.
 
-   5.3 Bugreports
+   5.3 Bug reports
    --------------
-   If you really find bugs in the sourcecode or the driver will successfully
+   If you really find bugs in the source code or the driver will successfully
    refuse to work on your machine, you should send a bug report to me. The
    best for this is to follow the instructions on the WWW-page for this
    driver. Fill out the bug-report form, placed on the WWW-page and ship it,
    so the bugs can be taken into account with maximum efforts. But, please
    do not send bug reports about this driver to Linus Torvalds or Leonard
-   Zubkoff, as Linus is burried in E-Mail and Leonard is supervising all
+   Zubkoff, as Linus is buried in E-Mail and Leonard is supervising all
    SCSI-drivers and won't have the time left to look inside every single
    driver to fix a bug and especially DO NOT send modified code to Linus
    Torvalds or Alan J. Cox which has not been checked here!!! They are both
-   quite burried in E-mail (as me, sometimes, too) and one should first check
+   quite buried in E-mail (as me, sometimes, too) and one should first check
    for problems on my local teststand. Recently, I got a lot of 
-   bugreports for errors in the ibmmca.c code, which I could not imagine, but
+   bug reports for errors in the ibmmca.c code, which I could not imagine, but
    a look inside some Linux-distribution showed me quite often some modified
    code, which did no longer work on most other machines than the one of the
    modifier. Ok, so now that there is maintenance service available for this
@@ -1261,7 +1261,7 @@
    some e-mail directly, but at least with the same information as required by
    the formular.
    
-   If you have extensive bugreports, including Ooops messages and 
+   If you have extensive bug reports, including Oops messages and
    screen-shots, please feel free to send it directly to the address
    of the maintainer, too. The current address of the maintainer is:
    
@@ -1318,7 +1318,7 @@
 		detailed bug reports and ideas for this driver (and his 
 		patience ;-)).
    Alan J. Cox  
-                for his bugreports and his bold activities in cross-checking
+                for his bug reports and his bold activities in cross-checking
 		the driver-code with his teststand.
 		
    7.2 Sponsors & Supporters
diff --git a/Documentation/sharedsubtree.txt b/Documentation/sharedsubtree.txt
index ccf1ceb..7365400 100644
--- a/Documentation/sharedsubtree.txt
+++ b/Documentation/sharedsubtree.txt
@@ -153,6 +153,7 @@
 	#include <stdio.h>
 	#include <stdlib.h>
 	#include <unistd.h>
+	#include <string.h>
 	#include <sys/mount.h>
 	#include <sys/fsuid.h>
 
diff --git a/Documentation/sound/alsa/soc/DAI.txt b/Documentation/sound/alsa/soc/DAI.txt
index 58cbfd0..3feeb9e 100644
--- a/Documentation/sound/alsa/soc/DAI.txt
+++ b/Documentation/sound/alsa/soc/DAI.txt
@@ -20,12 +20,12 @@
 ===
 
  I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and
-Rx lines are used for audio transmision, whilst the bit clock (BCLK) and
+Rx lines are used for audio transmission, whilst the bit clock (BCLK) and
 left/right clock (LRC) synchronise the link. I2S is flexible in that either the
 controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock
 usually varies depending on the sample rate and the master system clock
 (SYSCLK). LRCLK is the same as the sample rate. A few devices support separate
-ADC and DAC LRCLK's, this allows for similtanious capture and playback at
+ADC and DAC LRCLK's, this allows for simultaneous capture and playback at
 different sample rates.
 
 I2S has several different operating modes:-
@@ -41,12 +41,12 @@
 PCM
 ===
 
-PCM is another 4 wire interface, very similar to I2S, that can support a more
+PCM is another 4 wire interface, very similar to I2S, which can support a more
 flexible protocol. It has bit clock (BCLK) and sync (SYNC) lines that are used
 to synchronise the link whilst the Tx and Rx lines are used to transmit and
 receive the audio data. Bit clock usually varies depending on sample rate
 whilst sync runs at the sample rate. PCM also supports Time Division
-Multiplexing (TDM) in that several devices can use the bus similtaniuosly (This
+Multiplexing (TDM) in that several devices can use the bus simultaneously (this
 is sometimes referred to as network mode).
 
 Common PCM operating modes:-
diff --git a/Documentation/sound/alsa/soc/clocking.txt b/Documentation/sound/alsa/soc/clocking.txt
index e93960d..1493088 100644
--- a/Documentation/sound/alsa/soc/clocking.txt
+++ b/Documentation/sound/alsa/soc/clocking.txt
@@ -2,20 +2,20 @@
 ==============
 
 This text describes the audio clocking terms in ASoC and digital audio in
-general. Note: Audio clocking can be complex !
+general. Note: Audio clocking can be complex!
 
 
 Master Clock
 ------------
 
-Every audio subsystem is driven by a master clock (sometimes refered to as MCLK
+Every audio subsystem is driven by a master clock (sometimes referred to as MCLK
 or SYSCLK). This audio master clock can be derived from a number of sources
 (e.g. crystal, PLL, CPU clock) and is responsible for producing the correct
 audio playback and capture sample rates.
 
-Some master clocks (e.g. PLL's and CPU based clocks) are configuarble in that
+Some master clocks (e.g. PLL's and CPU based clocks) are configurable in that
 their speed can be altered by software (depending on the system use and to save
-power). Other master clocks are fixed at at set frequency (i.e. crystals).
+power). Other master clocks are fixed at a set frequency (i.e. crystals).
 
 
 DAI Clocks
@@ -44,7 +44,7 @@
 it's best to configure BCLK to the lowest possible speed (depending on your
 rate, number of channels and wordsize) to save on power.
 
-It's also desireable to use the codec (if possible) to drive (or master) the
+It's also desirable to use the codec (if possible) to drive (or master) the
 audio clocks as it's usually gives more accurate sample rates than the CPU.
 
 
diff --git a/Documentation/sound/alsa/soc/codec.txt b/Documentation/sound/alsa/soc/codec.txt
index 48983c7..1e766ad 100644
--- a/Documentation/sound/alsa/soc/codec.txt
+++ b/Documentation/sound/alsa/soc/codec.txt
@@ -19,7 +19,7 @@
  6) DAPM event handler.
  7) DAC Digital mute control.
 
-It's probably best to use this guide in conjuction with the existing codec
+It's probably best to use this guide in conjunction with the existing codec
 driver code in sound/soc/codecs/
 
 ASoC Codec driver breakdown
@@ -28,7 +28,7 @@
 1 - Codec DAI and PCM configuration
 -----------------------------------
 Each codec driver must have a struct snd_soc_codec_dai to define it's DAI and
-PCM's capablities and operations. This struct is exported so that it can be
+PCM's capabilities and operations. This struct is exported so that it can be
 registered with the core by your machine driver.
 
 e.g.
@@ -67,7 +67,7 @@
 
 2 - Codec control IO
 --------------------
-The codec can ususally be controlled via an I2C or SPI style interface (AC97
+The codec can usually be controlled via an I2C or SPI style interface (AC97
 combines control with data in the DAI). The codec drivers will have to provide
 functions to read and write the codec registers along with supplying a register
 cache:-
diff --git a/Documentation/sound/alsa/soc/dapm.txt b/Documentation/sound/alsa/soc/dapm.txt
index c11877f..ab0766f 100644
--- a/Documentation/sound/alsa/soc/dapm.txt
+++ b/Documentation/sound/alsa/soc/dapm.txt
@@ -11,7 +11,7 @@
 
 DAPM is also completely transparent to all user space applications as all power
 switching is done within the ASoC core. No code changes or recompiling are
-required for user space applications. DAPM makes power switching descisions based
+required for user space applications. DAPM makes power switching decisions based
 upon any audio stream (capture/playback) activity and audio mixer settings
 within the device.
 
@@ -38,7 +38,7 @@
       Enabled and disabled when stream playback/capture is started and
       stopped respectively. e.g. aplay, arecord.
 
-All DAPM power switching descisons are made automatically by consulting an audio
+All DAPM power switching decisions are made automatically by consulting an audio
 routing map of the whole machine. This map is specific to each machine and
 consists of the interconnections between every audio component (including
 internal codec components). All audio components that effect power are called
diff --git a/Documentation/sound/alsa/soc/overview.txt b/Documentation/sound/alsa/soc/overview.txt
index 753c5cc..c47ce95 100644
--- a/Documentation/sound/alsa/soc/overview.txt
+++ b/Documentation/sound/alsa/soc/overview.txt
@@ -2,18 +2,19 @@
 ==============
 
 The overall project goal of the ALSA System on Chip (ASoC) layer is to provide
-better ALSA support for embedded system on chip procesors (e.g. pxa2xx, au1x00,
+better ALSA support for embedded system-on-chip processors (e.g. pxa2xx, au1x00,
 iMX, etc) and portable audio codecs. Currently there is some support in the
 kernel for SoC audio, however it has some limitations:-
 
   * Currently, codec drivers are often tightly coupled to the underlying SoC
-    cpu. This is not ideal and leads to code duplication i.e. Linux now has 4
+    CPU. This is not ideal and leads to code duplication i.e. Linux now has 4
     different wm8731 drivers for 4 different SoC platforms.
 
-  * There is no standard method to signal user initiated audio events.
-    e.g. Headphone/Mic insertion, Headphone/Mic detection after an insertion
-    event. These are quite common events on portable devices and ofter require
-    machine specific code to re route audio, enable amps etc after such an event.
+  * There is no standard method to signal user initiated audio events (e.g.
+    Headphone/Mic insertion, Headphone/Mic detection after an insertion
+    event). These are quite common events on portable devices and often require
+    machine specific code to re-route audio, enable amps, etc., after such an
+    event.
 
   * Current drivers tend to power up the entire codec when playing
     (or recording) audio. This is fine for a PC, but tends to waste a lot of
@@ -44,7 +45,7 @@
     signals the codec when to change power states.
 
   * Machine specific controls: Allow machines to add controls to the sound card
-    e.g. volume control for speaker amp.
+    (e.g. volume control for speaker amp).
 
 To achieve all this, ASoC basically splits an embedded audio system into 3
 components :-
@@ -57,7 +58,7 @@
     interface drivers (e.g. I2S, AC97, PCM) for that platform.
 
   * Machine driver: The machine driver handles any machine specific controls and
-    audio events. i.e. turing on an amp at start of playback.
+    audio events (e.g. turning on an amp at start of playback).
 
 
 Documentation
diff --git a/Documentation/sound/alsa/soc/platform.txt b/Documentation/sound/alsa/soc/platform.txt
index e95b16d..d4678b4 100644
--- a/Documentation/sound/alsa/soc/platform.txt
+++ b/Documentation/sound/alsa/soc/platform.txt
@@ -20,7 +20,7 @@
 	int (*trigger)(struct snd_pcm_substream *, int);
 };
 
-The platform driver exports it's DMA functionailty via struct snd_soc_platform:-
+The platform driver exports its DMA functionality via struct snd_soc_platform:-
 
 struct snd_soc_platform {
 	char *name;
diff --git a/Documentation/sound/alsa/soc/pops_clicks.txt b/Documentation/sound/alsa/soc/pops_clicks.txt
index 2cf7ee5..3371bd9 100644
--- a/Documentation/sound/alsa/soc/pops_clicks.txt
+++ b/Documentation/sound/alsa/soc/pops_clicks.txt
@@ -2,7 +2,7 @@
 =====================
 
 Pops and clicks are unwanted audio artifacts caused by the powering up and down
-of components within the audio subsystem. This is noticable on PC's when an
+of components within the audio subsystem. This is noticeable on PCs when an
 audio module is either loaded or unloaded (at module load time the sound card is
 powered up and causes a popping noise on the speakers).
 
@@ -16,7 +16,7 @@
 ===================================
 
 Playback pops in portable audio subsystems cannot be completely eliminated atm,
-however future audio codec hardware will have better pop and click supression.
+however future audio codec hardware will have better pop and click suppression.
 Pops can be reduced within playback by powering the audio components in a
 specific order. This order is different for startup and shutdown and follows
 some basic rules:-
@@ -33,7 +33,7 @@
 ==================================
 
 Capture artifacts are somewhat easier to get rid as we can delay activating the
-ADC until all the pops have occured. This follows similar power rules to
+ADC until all the pops have occurred. This follows similar power rules to
 playback in that components are powered in a sequence depending upon stream
 startup or shutdown.
 
diff --git a/Documentation/sound/oss/es1371 b/Documentation/sound/oss/es1371
deleted file mode 100644
index c315126..0000000
--- a/Documentation/sound/oss/es1371
+++ /dev/null
@@ -1,64 +0,0 @@
-/proc/sound, /dev/sndstat
--------------------------
-
-/proc/sound and /dev/sndstat is not supported by the
-driver. To find out whether the driver succeeded loading,
-check the kernel log (dmesg).
-
-
-ALaw/uLaw sample formats
-------------------------
-
-This driver does not support the ALaw/uLaw sample formats.
-ALaw is the default mode when opening a sound device
-using OSS/Free. The reason for the lack of support is
-that the hardware does not support these formats, and adding
-conversion routines to the kernel would lead to very ugly
-code in the presence of the mmap interface to the driver.
-And since xquake uses mmap, mmap is considered important :-)
-and no sane application uses ALaw/uLaw these days anyway.
-In short, playing a Sun .au file as follows:
-
-cat my_file.au > /dev/dsp
-
-does not work. Instead, you may use the play script from
-Chris Bagwell's sox-12.14 package (available from the URL
-below) to play many different audio file formats.
-The script automatically determines the audio format
-and does do audio conversions if necessary.
-http://home.sprynet.com/sprynet/cbagwell/projects.html
-
-
-Blocking vs. nonblocking IO
----------------------------
-
-Unlike OSS/Free this driver honours the O_NONBLOCK file flag
-not only during open, but also during read and write.
-This is an effort to make the sound driver interface more
-regular. Timidity has problems with this; a patch
-is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
-(Timidity patched will also run on OSS/Free).
-
-
-MIDI UART
----------
-
-The driver supports a simple MIDI UART interface, with
-no ioctl's supported.
-
-
-MIDI synthesizer
-----------------
-
-This soundcard does not have any hardware MIDI synthesizer;
-MIDI synthesis has to be done in software. To allow this
-the driver/soundcard supports two PCM (/dev/dsp) interfaces.
-
-There is a freely available software package that allows
-MIDI file playback on this soundcard called Timidity.
-See http://www.cgs.fi/~tt/timidity/.
-
-
-
-Thomas Sailer
-t.sailer@alumni.ethz.ch
diff --git a/Documentation/spi/pxa2xx b/Documentation/spi/pxa2xx
index 215e3b8..f3853cc 100644
--- a/Documentation/spi/pxa2xx
+++ b/Documentation/spi/pxa2xx
@@ -1,4 +1,4 @@
-PXA2xx SPI on SSP driver HOWTO
+PXA2xx SPI on SSP driver HOWTO
 ===================================================
 This a mini howto on the pxa2xx_spi driver.  The driver turns a PXA2xx
 synchronous serial port into a SPI master controller
diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index 60953d6..ec49926 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -105,10 +105,15 @@
 as a driver attribute (see below).
 
 Sysfs driver attributes are on the driver's sysfs attribute space,
-for 2.6.20 this is /sys/bus/platform/drivers/thinkpad_acpi/.
+for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and
+/sys/bus/platform/drivers/thinkpad_hwmon/
 
-Sysfs device attributes are on the driver's sysfs attribute space,
-for 2.6.20 this is /sys/devices/platform/thinkpad_acpi/.
+Sysfs device attributes are on the thinkpad_acpi device sysfs attribute
+space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/.
+
+Sysfs device attributes for the sensors and fan are on the
+thinkpad_hwmon device's sysfs attribute space, but you should locate it
+looking for a hwmon device with the name attribute of "thinkpad".
 
 Driver version
 --------------
@@ -766,7 +771,7 @@
 -------------------
 
 procfs: /proc/acpi/ibm/thermal
-sysfs device attributes: (hwmon) temp*_input
+sysfs device attributes: (hwmon "thinkpad") temp*_input
 
 Most ThinkPads include six or more separate temperature sensors but only
 expose the CPU temperature through the standard ACPI methods.  This
@@ -989,7 +994,9 @@
 ---------------------------------------------------------
 
 procfs: /proc/acpi/ibm/fan
-sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable
+sysfs device attributes: (hwmon "thinkpad") fan1_input, pwm1,
+			  pwm1_enable
+sysfs hwmon driver attributes: fan_watchdog
 
 NOTE NOTE NOTE: fan control operations are disabled by default for
 safety reasons.  To enable them, the module parameter "fan_control=1"
@@ -1028,7 +1035,7 @@
 
 An enabled fan in level "auto" may stop spinning if the EC decides the
 ThinkPad is cool enough and doesn't need the extra airflow.  This is
-normal, and the EC will spin the fan up if the varios thermal readings
+normal, and the EC will spin the fan up if the various thermal readings
 rise too much.
 
 On the X40, this seems to depend on the CPU and HDD temperatures.
@@ -1131,7 +1138,7 @@
 	which can take up to two minutes.  May return rubbish on older
 	ThinkPads.
 
-driver attribute fan_watchdog:
+hwmon driver attribute fan_watchdog:
 	Fan safety watchdog timer interval, in seconds.  Minimum is
 	1 second, maximum is 120 seconds.  0 disables the watchdog.
 
@@ -1196,7 +1203,7 @@
 Enabling debugging output
 -------------------------
 
-The module takes a debug paramater which can be used to selectively
+The module takes a debug parameter which can be used to selectively
 enable various classes of debugging output, for example:
 
 	 modprobe ibm_acpi debug=0xffff
@@ -1233,3 +1240,9 @@
 		layer, the radio switch generates input event EV_RADIO,
 		and the driver enables hot key handling by default in
 		the firmware.
+
+0x020000:	ABI fix: added a separate hwmon platform device and
+		driver, which must be located by name (thinkpad)
+		and the hwmon class for libsensors4 (lm-sensors 3)
+		compatibility.  Moved all hwmon attributes to this
+		new platform device.
diff --git a/Documentation/usb/usb-serial.txt b/Documentation/usb/usb-serial.txt
index 4e0b62b..8b077e4 100644
--- a/Documentation/usb/usb-serial.txt
+++ b/Documentation/usb/usb-serial.txt
@@ -338,7 +338,7 @@
   This driver is for the MCT USB-RS232 Converter (25 pin, Model No.
   U232-P25) from Magic Control Technology Corp. (there is also a 9 pin
   Model No. U232-P9). More information about this device can be found at
-  the manufacture's web-site: http://www.mct.com.tw.
+  the manufacturer's web-site: http://www.mct.com.tw.
 
   The driver is generally working, though it still needs some more testing.
   It is derived from the Belkin USB Serial Adapter F5U103 driver and its
diff --git a/Documentation/watchdog/src/watchdog-simple.c b/Documentation/watchdog/src/watchdog-simple.c
index 47801bc..4cf72f3 100644
--- a/Documentation/watchdog/src/watchdog-simple.c
+++ b/Documentation/watchdog/src/watchdog-simple.c
@@ -3,15 +3,25 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-int main(int argc, const char *argv[]) {
+int main(void)
+{
 	int fd = open("/dev/watchdog", O_WRONLY);
+	int ret = 0;
 	if (fd == -1) {
 		perror("watchdog");
-		exit(1);
+		exit(EXIT_FAILURE);
 	}
 	while (1) {
-		write(fd, "\0", 1);
-		fsync(fd);
+		ret = write(fd, "\0", 1);
+		if (ret != 1) {
+			ret = -1;
+			break;
+		}
+		ret = fsync(fd);
+		if (ret)
+			break;
 		sleep(10);
 	}
+	close(fd);
+	return ret;
 }
diff --git a/MAINTAINERS b/MAINTAINERS
index 75fd297..05504f2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1969,11 +1969,6 @@
 L:	linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
 S:	Maintained
 
-INTEL APIC/IOAPIC, LOWLEVEL X86 SMP SUPPORT
-P:	Ingo Molnar
-M:	mingo@redhat.com
-S:	Maintained
-
 INTEL I8XX RANDOM NUMBER GENERATOR SUPPORT
 P:	Jeff Garzik
 M:	jgarzik@pobox.com
@@ -2184,7 +2179,7 @@
 KCONFIG
 P:	Roman Zippel
 M:	zippel@linux-m68k.org
-L:	kbuild-devel@lists.sourceforge.net
+L:	linux-kbuild@vger.kernel.org
 S:	Maintained
 
 KDUMP
@@ -2213,6 +2208,7 @@
 P:	Sam Ravnborg
 M:	sam@ravnborg.org
 T:	git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
+L:	linux-kbuild@vger.kernel.org
 S:	Maintained
 
 KERNEL JANITORS
@@ -2240,7 +2236,7 @@
 KEXEC
 P:	Eric Biederman
 M:	ebiederm@xmission.com
-W:	http://www.xmission.com/~ebiederm/files/kexec/
+W:	http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/
 L:	linux-kernel@vger.kernel.org
 L:	kexec@lists.infradead.org
 S:	Maintained
@@ -2348,6 +2344,8 @@
 S:	Maintained
 
 LINUX FOR POWERPC EMBEDDED PPC8XX
+P:	Vitaly Bordug
+M:	vitb@kernel.crashing.org
 P:	Marcelo Tosatti
 M:	marcelo@kvack.org
 W:	http://www.penguinppc.org/
@@ -2946,13 +2944,6 @@
 L:	linux-pci@atrey.karlin.mff.cuni.cz
 S:	Supported
 
-PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)
-P:	Thomas Sailer
-M:	sailer@ife.ee.ethz.ch
-L:	linux-sound@vger.kernel.org
-W:	http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html
-S:	Maintained
-
 PCI SUBSYSTEM
 P:	Greg Kroah-Hartman
 M:	gregkh@suse.de
@@ -4281,9 +4272,15 @@
 L:	linux-serial@vger.kernel.org
 S:	Maintained
 
-X86 3-LEVEL PAGING (PAE) SUPPORT
+X86 ARCHITECTURE (32-BIT AND 64-BIT)
+P:	Thomas Gleixner
+M:	tglx@linutronix.de
 P:	Ingo Molnar
 M:	mingo@redhat.com
+P:	H. Peter Anvin
+M:	hpa@zytor.com
+L:	linux-kernel@vger.kernel.org
+T:	git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
 S:	Maintained
 
 YAM DRIVER FOR AX.25
diff --git a/Makefile b/Makefile
index 529b904..264f37b8 100644
--- a/Makefile
+++ b/Makefile
@@ -774,6 +774,9 @@
 ifdef CONFIG_HEADERS_CHECK
 	$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
 endif
+ifdef CONFIG_SAMPLES
+	$(Q)$(MAKE) $(build)=samples
+endif
 	$(call vmlinux-modpost)
 	$(call if_changed_rule,vmlinux__)
 	$(Q)rm -f .old_version
@@ -884,10 +887,7 @@
 
 prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \
                    include/asm include/config/auto.conf
-ifneq ($(KBUILD_MODULES),)
-	$(Q)mkdir -p $(MODVERDIR)
-	$(Q)rm -f $(MODVERDIR)/*
-endif
+	$(cmd_crmodverdir)
 
 archprepare: prepare1 scripts_basic
 
@@ -903,14 +903,24 @@
 
 export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
 
-# FIXME: The asm symlink changes when $(ARCH) changes. That's
-# hard to detect, but I suppose "make mrproper" is a good idea
-# before switching between archs anyway.
+# The asm symlink changes when $(ARCH) changes.
+# Detect this and ask user to run make mrproper
 
-include/asm:
-	@echo '  SYMLINK $@ -> include/asm-$(SRCARCH)'
-	$(Q)if [ ! -d include ]; then mkdir -p include; fi;
-	@ln -fsn asm-$(SRCARCH) $@
+include/asm: FORCE
+	$(Q)set -e; asmlink=`readlink include/asm | cut -d '-' -f 2`;   \
+	if [ -L include/asm ]; then                                     \
+		if [ "$$asmlink" != "$(SRCARCH)" ]; then                \
+			echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \
+			echo "       set ARCH or save .config and run 'make mrproper' to fix it";             \
+			exit 1;                                         \
+		fi;                                                     \
+	else                                                            \
+		echo '  SYMLINK $@ -> include/asm-$(SRCARCH)';          \
+		if [ ! -d include ]; then                               \
+			mkdir -p include;                               \
+		fi;                                                     \
+		ln -fsn asm-$(SRCARCH) $@;                              \
+	fi
 
 # Generate some files
 # ---------------------------------------------------------------------------
@@ -1020,19 +1030,12 @@
 	fi
 	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
 
-# If System.map exists, run depmod.  This deliberately does not have a
-# dependency on System.map since that would run the dependency tree on
-# vmlinux.  This depmod is only for convenience to give the initial
+# This depmod is only for convenience to give the initial
 # boot a modules.dep even before / is mounted read-write.  However the
 # boot script depmod is the master version.
-ifeq "$(strip $(INSTALL_MOD_PATH))" ""
-depmod_opts	:=
-else
-depmod_opts	:= -b $(INSTALL_MOD_PATH) -r
-endif
 PHONY += _modinst_post
 _modinst_post: _modinst_
-	if [ -r System.map -a -x $(DEPMOD) ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
+	$(call cmd,depmod)
 
 else # CONFIG_MODULES
 
@@ -1220,8 +1223,7 @@
 KBUILD_MODULES := 1
 PHONY += crmodverdir
 crmodverdir:
-	$(Q)mkdir -p $(MODVERDIR)
-	$(Q)rm -f $(MODVERDIR)/*
+	$(cmd_crmodverdir)
 
 PHONY += $(objtree)/Module.symvers
 $(objtree)/Module.symvers:
@@ -1249,15 +1251,6 @@
 	$(Q)mkdir -p $(MODLIB)/$(install-dir)
 	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
 
-# Run depmod only is we have System.map and depmod is executable
-quiet_cmd_depmod = DEPMOD  $(KERNELRELEASE)
-      cmd_depmod = if [ -r System.map -a -x $(DEPMOD) ]; then \
-                      $(DEPMOD) -ae -F System.map             \
-                      $(if $(strip $(INSTALL_MOD_PATH)),      \
-		      -b $(INSTALL_MOD_PATH) -r)              \
-		      $(KERNELRELEASE);                       \
-                   fi
-
 PHONY += _emodinst_post
 _emodinst_post: _emodinst_
 	$(call cmd,depmod)
@@ -1341,7 +1334,7 @@
 	  find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
 	       -name $1 -print; \
 	  find $(__srctree) $(RCS_FIND_IGNORE) \
-	       \( -name include -o -name arch \) -prune -o \
+	       \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \
 	       -name $1 -print; \
 	  )
 endef
@@ -1490,9 +1483,11 @@
 
 # Modules
 / %/: prepare scripts FORCE
+	$(cmd_crmodverdir)
 	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
 	$(build)=$(build-dir)
 %.ko: prepare scripts FORCE
+	$(cmd_crmodverdir)
 	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1)   \
 	$(build)=$(build-dir) $(@:.ko=.o)
 	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
@@ -1506,6 +1501,20 @@
 quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN   $(wildcard $(rm-files)))
       cmd_rmfiles = rm -f $(rm-files)
 
+# Run depmod only is we have System.map and depmod is executable
+# and we build for the host arch
+quiet_cmd_depmod = DEPMOD  $(KERNELRELEASE)
+      cmd_depmod = \
+	if [ -r System.map -a -x $(DEPMOD) ]; then                              \
+		$(DEPMOD) -ae -F System.map                                     \
+		$(if $(strip $(INSTALL_MOD_PATH)), -b $(INSTALL_MOD_PATH) -r)   \
+		$(KERNELRELEASE);                                               \
+	fi
+
+# Create temporary dir for module support files
+# clean it up only when building all modules
+cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \
+                  $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*)
 
 a_flags = -Wp,-MD,$(depfile) $(KBUILD_AFLAGS) $(AFLAGS_KERNEL) \
 	  $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 2a85dc3..4c002ba 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -654,7 +654,7 @@
 
 source "fs/Kconfig"
 
-source "arch/alpha/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/alpha/Kconfig.debug"
 
diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c
index f2956ac..497877b 100644
--- a/arch/alpha/kernel/err_marvel.c
+++ b/arch/alpha/kernel/err_marvel.c
@@ -1082,7 +1082,7 @@
 	}	
 
 	/*
-	 * A system event or error has occured, handle it here.
+	 * A system event or error has occurred, handle it here.
 	 *
 	 * Any errors in the logout frame have already been cleared by the
 	 * PALcode, so just parse it.
diff --git a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c
index 543d96d..6f38678 100644
--- a/arch/alpha/kernel/err_titan.c
+++ b/arch/alpha/kernel/err_titan.c
@@ -591,7 +591,7 @@
 		(struct el_PRIVATEER_envdata_mcheck *)
 		((unsigned long)mchk_header + mchk_header->sys_offset);
 
-	/* TODO - catagorize errors, for now, no error */
+	/* TODO - categorize errors, for now, no error */
 
 	if (!print)
 		return status;
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index ce85715..6413c5f 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -715,7 +715,7 @@
 		/* 
 		 * Alpha Architecture Handbook 4.7.7.3:
 		 * To be fully IEEE compiant, we must track the current IEEE
-		 * exception state in software, because spurrious bits can be
+		 * exception state in software, because spurious bits can be
 		 * set in the trap shadow of a software-complete insn.
 		 */
 
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index e1c4707..2d00a08 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -7,6 +7,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
+#include <linux/scatterlist.h>
 #include <linux/log2.h>
 
 #include <asm/io.h>
@@ -465,7 +466,7 @@
    Write dma_length of each leader with the combined lengths of
    the mergable followers.  */
 
-#define SG_ENT_VIRT_ADDRESS(SG) (page_address((SG)->page) + (SG)->offset)
+#define SG_ENT_VIRT_ADDRESS(SG) (sg_virt((SG)))
 #define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG))
 
 static void
diff --git a/arch/alpha/kernel/semaphore.c b/arch/alpha/kernel/semaphore.c
index 8c8aaa2..8d2982a 100644
--- a/arch/alpha/kernel/semaphore.c
+++ b/arch/alpha/kernel/semaphore.c
@@ -69,7 +69,7 @@
 
 #ifdef CONFIG_DEBUG_SEMAPHORE
 	printk("%s(%d): down failed(%p)\n",
-	       tsk->comm, tsk->pid, sem);
+	       tsk->comm, task_pid_nr(tsk), sem);
 #endif
 
 	tsk->state = TASK_UNINTERRUPTIBLE;
@@ -98,7 +98,7 @@
 
 #ifdef CONFIG_DEBUG_SEMAPHORE
 	printk("%s(%d): down acquired(%p)\n",
-	       tsk->comm, tsk->pid, sem);
+	       tsk->comm, task_pid_nr(tsk), sem);
 #endif
 }
 
@@ -111,7 +111,7 @@
 
 #ifdef CONFIG_DEBUG_SEMAPHORE
 	printk("%s(%d): down failed(%p)\n",
-	       tsk->comm, tsk->pid, sem);
+	       tsk->comm, task_pid_nr(tsk), sem);
 #endif
 
 	tsk->state = TASK_INTERRUPTIBLE;
@@ -139,7 +139,7 @@
 
 #ifdef CONFIG_DEBUG_SEMAPHORE
 	printk("%s(%d): down %s(%p)\n",
-	       current->comm, current->pid,
+	       current->comm, task_pid_nr(current),
 	       (ret < 0 ? "interrupted" : "acquired"), sem);
 #endif
 	return ret;
@@ -168,7 +168,7 @@
 #endif
 #ifdef CONFIG_DEBUG_SEMAPHORE
 	printk("%s(%d): down(%p) <count=%d> from %p\n",
-	       current->comm, current->pid, sem,
+	       current->comm, task_pid_nr(current), sem,
 	       atomic_read(&sem->count), __builtin_return_address(0));
 #endif
 	__down(sem);
@@ -182,7 +182,7 @@
 #endif
 #ifdef CONFIG_DEBUG_SEMAPHORE
 	printk("%s(%d): down(%p) <count=%d> from %p\n",
-	       current->comm, current->pid, sem,
+	       current->comm, task_pid_nr(current), sem,
 	       atomic_read(&sem->count), __builtin_return_address(0));
 #endif
 	return __down_interruptible(sem);
@@ -201,7 +201,7 @@
 
 #ifdef CONFIG_DEBUG_SEMAPHORE
 	printk("%s(%d): down_trylock %s from %p\n",
-	       current->comm, current->pid,
+	       current->comm, task_pid_nr(current),
 	       ret ? "failed" : "acquired",
 	       __builtin_return_address(0));
 #endif
@@ -217,7 +217,7 @@
 #endif
 #ifdef CONFIG_DEBUG_SEMAPHORE
 	printk("%s(%d): up(%p) <count=%d> from %p\n",
-	       current->comm, current->pid, sem,
+	       current->comm, task_pid_nr(current), sem,
 	       atomic_read(&sem->count), __builtin_return_address(0));
 #endif
 	__up(sem);
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index ad17644..f4ab233 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -439,7 +439,6 @@
 				((char *)cpubase + i*hwrpb->processor_size);
 			if ((cpu->flags & 0x1cc) == 0x1cc) {
 				smp_num_probed++;
-				/* Assume here that "whami" == index */
 				cpu_set(i, cpu_present_map);
 				cpu->pal_revision = boot_cpu_palrev;
 			}
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
index 49bedfb..d187d01 100644
--- a/arch/alpha/kernel/sys_alcor.c
+++ b/arch/alpha/kernel/sys_alcor.c
@@ -138,7 +138,7 @@
 
 	for (i = 16; i < 48; ++i) {
 		/* On Alcor, at least, lines 20..30 are not connected
-		   and can generate spurrious interrupts if we turn them
+		   and can generate spurious interrupts if we turn them
 		   on while IRQ probing.  */
 		if (i >= 16+20 && i <= 16+30)
 			continue;
diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c
index 14b5a75..ee7b900 100644
--- a/arch/alpha/kernel/sys_sio.c
+++ b/arch/alpha/kernel/sys_sio.c
@@ -78,7 +78,7 @@
  * example, sound boards seem to like using IRQ 9.
  *
  * This is NOT how we should do it. PIRQ0-X should have
- * their own IRQ's, the way intel uses the IO-APIC irq's.
+ * their own IRQs, the way intel uses the IO-APIC IRQs.
  */
 
 static void __init
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index ec0f05e..2dc7f9f 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -182,7 +182,7 @@
 #ifdef CONFIG_SMP
 	printk("CPU %d ", hard_smp_processor_id());
 #endif
-	printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
+	printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);
 	dik_show_regs(regs, r9_15);
 	add_taint(TAINT_DIE);
 	dik_show_trace((unsigned long *)(regs+1));
@@ -646,7 +646,7 @@
 	lock_kernel();
 
 	printk("%s(%d): unhandled unaligned exception\n",
-	       current->comm, current->pid);
+	       current->comm, task_pid_nr(current));
 
 	printk("pc = [<%016lx>]  ra = [<%016lx>]  ps = %04lx\n",
 	       pc, una_reg(26), regs->ps);
@@ -786,7 +786,7 @@
 		}
 		if (++cnt < 5) {
 			printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
-			       current->comm, current->pid,
+			       current->comm, task_pid_nr(current),
 			       regs->pc - 4, va, opcode, reg);
 		}
 		last_time = jiffies;
diff --git a/arch/alpha/lib/checksum.c b/arch/alpha/lib/checksum.c
index 8698e07..199f6ef 100644
--- a/arch/alpha/lib/checksum.c
+++ b/arch/alpha/lib/checksum.c
@@ -5,7 +5,7 @@
  * in an architecture-specific manner due to speed..
  * Comments in other versions indicate that the algorithms are from RFC1071
  *
- * accellerated versions (and 21264 assembly versions ) contributed by
+ * accelerated versions (and 21264 assembly versions ) contributed by
  *	Rick Gorton	<rick.gorton@alpha-processor.com>
  */
  
diff --git a/arch/alpha/lib/csum_partial_copy.c b/arch/alpha/lib/csum_partial_copy.c
index 4ca75c7..40736da 100644
--- a/arch/alpha/lib/csum_partial_copy.c
+++ b/arch/alpha/lib/csum_partial_copy.c
@@ -2,7 +2,7 @@
  * csum_partial_copy - do IP checksumming and copy
  *
  * (C) Copyright 1996 Linus Torvalds
- * accellerated versions (and 21264 assembly versions ) contributed by
+ * accelerated versions (and 21264 assembly versions ) contributed by
  *	Rick Gorton	<rick.gorton@alpha-processor.com>
  *
  * Don't look at this too closely - you'll go mad. The things
diff --git a/arch/alpha/lib/fls.c b/arch/alpha/lib/fls.c
index 7ad84ea..32afaa3 100644
--- a/arch/alpha/lib/fls.c
+++ b/arch/alpha/lib/fls.c
@@ -3,7 +3,7 @@
  */
 
 #include <linux/module.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 /* This is fls(x)-1, except zero is held to zero.  This allows most
    efficent input into extbl, plus it allows easy handling of fls(0)=0.  */
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index 25154df..4829f96 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -188,13 +188,13 @@
 	/* We ran out of memory, or some other thing happened to us that
 	   made us unable to handle the page fault gracefully.  */
  out_of_memory:
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
 	}
 	printk(KERN_ALERT "VM: killing process %s(%d)\n",
-	       current->comm, current->pid);
+	       current->comm, task_pid_nr(current));
 	if (!user_mode(regs))
 		goto no_context;
 	do_group_exit(SIGKILL);
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index 5e6da47..40c15e7 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -235,7 +235,7 @@
 			unsigned long pfn = crb->map[i].pa >> PAGE_SHIFT;
 			crb->map[i].va = vaddr;
 			for (j = 0; j < crb->map[i].count; ++j) {
-				/* Newer console's (especially on larger
+				/* Newer consoles (especially on larger
 				   systems) may require more pages of
 				   PTEs. Grab additional pages as needed. */
 				if (pmd != pmd_offset(pgd, vaddr)) {
diff --git a/arch/alpha/oprofile/Kconfig b/arch/alpha/oprofile/Kconfig
deleted file mode 100644
index 5ade198..0000000
--- a/arch/alpha/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-	  
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
-endmenu
-
diff --git a/arch/alpha/oprofile/op_impl.h b/arch/alpha/oprofile/op_impl.h
index 6b97893..b2b87ae 100644
--- a/arch/alpha/oprofile/op_impl.h
+++ b/arch/alpha/oprofile/op_impl.h
@@ -38,7 +38,7 @@
 	unsigned long need_reset;
 };
 
-/* Per-architecture configury and hooks.  */
+/* Per-architecture configuration and hooks.  */
 struct op_axp_model {
 	void (*reg_setup) (struct op_register_config *,
 			   struct op_counter_config *,
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0a0c88d..a0cdaaf 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -851,7 +851,7 @@
 	help
 	  kexec is a system call that implements the ability to shutdown your
 	  current kernel, and to start another kernel.  It is like a reboot
-	  but it is indepedent of the system firmware.   And like a reboot
+	  but it is independent of the system firmware.   And like a reboot
 	  you can start any kernel with it, not just Linux.
 
 	  It is an ongoing process to be certain the hardware in a machine
@@ -1068,7 +1068,7 @@
 
 source "fs/Kconfig"
 
-source "arch/arm/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/arm/Kconfig.debug"
 
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 44ab0da..52fc6a8 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -29,6 +29,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/dmapool.h>
 #include <linux/list.h>
+#include <linux/scatterlist.h>
 
 #include <asm/cacheflush.h>
 
@@ -442,7 +443,7 @@
 	BUG_ON(dir == DMA_NONE);
 
 	for (i = 0; i < nents; i++, sg++) {
-		struct page *page = sg->page;
+		struct page *page = sg_page(sg);
 		unsigned int offset = sg->offset;
 		unsigned int length = sg->length;
 		void *ptr = page_address(page) + offset;
diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c
index 111a7fa5..5bba525 100644
--- a/arch/arm/common/sharpsl_pm.c
+++ b/arch/arm/common/sharpsl_pm.c
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/apm-emulation.h>
+#include <linux/suspend.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -765,9 +766,9 @@
 	info->battery_life = sharpsl_pm.battstat.mainbat_percent;
 }
 
-static struct pm_ops sharpsl_pm_ops = {
+static struct platform_suspend_ops sharpsl_pm_ops = {
 	.enter		= corgi_pxa_pm_enter,
-	.valid		= pm_valid_only_mem,
+	.valid		= suspend_valid_only_mem,
 };
 
 static int __init sharpsl_pm_probe(struct platform_device *pdev)
@@ -799,7 +800,7 @@
 
 	apm_get_power_status = sharpsl_apm_get_power_status;
 
-	pm_set_ops(&sharpsl_pm_ops);
+	suspend_set_ops(&sharpsl_pm_ops);
 
 	mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
 
@@ -808,7 +809,7 @@
 
 static int sharpsl_pm_remove(struct platform_device *pdev)
 {
-	pm_set_ops(NULL);
+	suspend_set_ops(NULL);
 
 	device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
 	device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 93b7f8e..4f1a031 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -265,7 +265,7 @@
 void show_regs(struct pt_regs * regs)
 {
 	printk("\n");
-	printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
+	printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm);
 	__show_regs(regs);
 	__backtrace();
 }
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 5feee72..4b05dc5 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -382,16 +382,16 @@
 
 		if (ret != 2 || old_insn.thumb != BREAKINST_THUMB)
 			printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at "
-				"0x%08lx (0x%04x)\n", task->comm, task->pid,
-				addr, old_insn.thumb);
+				"0x%08lx (0x%04x)\n", task->comm,
+				task_pid_nr(task), addr, old_insn.thumb);
 	} else {
 		ret = swap_insn(task, addr & ~3, &old_insn.arm,
 				&bp->insn.arm, 4);
 
 		if (ret != 4 || old_insn.arm != BREAKINST_ARM)
 			printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at "
-				"0x%08lx (0x%08x)\n", task->comm, task->pid,
-				addr, old_insn.arm);
+				"0x%08lx (0x%08x)\n", task->comm,
+				task_pid_nr(task), addr, old_insn.arm);
 	}
 }
 
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 8ad4761..4764bd9 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -223,7 +223,7 @@
 	print_modules();
 	__show_regs(regs);
 	printk("Process %s (pid: %d, stack limit = 0x%p)\n",
-		tsk->comm, tsk->pid, thread + 1);
+		tsk->comm, task_pid_nr(tsk), thread + 1);
 
 	if (!user_mode(regs) || in_interrupt()) {
 		dump_mem("Stack: ", regs->ARM_sp,
@@ -337,7 +337,7 @@
 #ifdef CONFIG_DEBUG_USER
 	if (user_debug & UDBG_UNDEFINED) {
 		printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
-			current->comm, current->pid, pc);
+			current->comm, task_pid_nr(current), pc);
 		dump_instr(regs);
 	}
 #endif
@@ -388,7 +388,7 @@
 #ifdef CONFIG_DEBUG_USER
 	if (user_debug & UDBG_SYSCALL) {
 		printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
-			current->pid, current->comm, n);
+			task_pid_nr(current), current->comm, n);
 		dump_instr(regs);
 	}
 #endif
@@ -565,7 +565,7 @@
 	 */
 	if (user_debug & UDBG_SYSCALL) {
 		printk("[%d] %s: arm syscall %d\n",
-		       current->pid, current->comm, no);
+		       task_pid_nr(current), current->comm, no);
 		dump_instr(regs);
 		if (user_mode(regs)) {
 			__show_regs(regs);
@@ -642,7 +642,7 @@
 #ifdef CONFIG_DEBUG_USER
 	if (user_debug & UDBG_BADABORT) {
 		printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
-			current->pid, current->comm, code, instr);
+			task_pid_nr(current), current->comm, code, instr);
 		dump_instr(regs);
 		show_pte(current->mm, addr);
 	}
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index ba4a1bb..aa2d365 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -439,7 +439,7 @@
 		for (i = 0; i < 32; i++, pin++) {
 			/*
 			 * Can use the "simple" and not "edge" handler since it's
-			 * shorter, and the AIC handles interupts sanely.
+			 * shorter, and the AIC handles interrupts sanely.
 			 */
 			set_irq_chip(pin, &gpio_irqchip);
 			set_irq_handler(pin, handle_simple_irq);
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index ddf9184..98cb614 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -10,10 +10,9 @@
  * (at your option) any later version.
  */
 
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/pm.h>
 #include <linux/interrupt.h>
 #include <linux/sysfs.h>
 #include <linux/module.h>
@@ -199,7 +198,7 @@
 }
 
 
-static struct pm_ops at91_pm_ops ={
+static struct platform_suspend_ops at91_pm_ops ={
 	.valid		= at91_pm_valid_state,
 	.set_target	= at91_pm_set_target,
 	.enter		= at91_pm_enter,
@@ -220,7 +219,7 @@
 	/* Disable SDRAM low-power mode.  Cannot be used with self-refresh. */
 	at91_sys_write(AT91_SDRAMC_LPR, 0);
 
-	pm_set_ops(&at91_pm_ops);
+	suspend_set_ops(&at91_pm_ops);
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index 0733078..1da9d59 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 2004 Nokia Corporation
  * Written by Tony Lindgren <tony@atomide.com>
- * Major cleanups by Juha Yrjölä <juha.yrjola@nokia.com>
+ * Major cleanups by Juha Yrjölä <juha.yrjola@nokia.com>
  *
  * Completely re-written to support various OMAP chips with bank specific
  * interrupt handlers.
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index 089b820..3bf01e2 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -35,10 +35,9 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/pm.h>
 #include <linux/interrupt.h>
 #include <linux/sysfs.h>
 #include <linux/module.h>
@@ -600,27 +599,15 @@
 
 /*
  *	omap_pm_prepare - Do preliminary suspend work.
- *	@state:		suspend state we're entering.
  *
  */
-static int omap_pm_prepare(suspend_state_t state)
+static int omap_pm_prepare(void)
 {
-	int error = 0;
-
 	/* We cannot sleep in idle until we have resumed */
 	saved_idle = pm_idle;
 	pm_idle = NULL;
 
-	switch (state)
-	{
-	case PM_SUSPEND_STANDBY:
-	case PM_SUSPEND_MEM:
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return error;
+	return 0;
 }
 
 
@@ -648,16 +635,14 @@
 
 /**
  *	omap_pm_finish - Finish up suspend sequence.
- *	@state:		State we're coming out of.
  *
  *	This is called after we wake back up (or if entering the sleep state
  *	failed).
  */
 
-static int omap_pm_finish(suspend_state_t state)
+static void omap_pm_finish(void)
 {
 	pm_idle = saved_idle;
-	return 0;
 }
 
 
@@ -674,11 +659,11 @@
 
 
 
-static struct pm_ops omap_pm_ops ={
+static struct platform_suspend_ops omap_pm_ops ={
 	.prepare	= omap_pm_prepare,
 	.enter		= omap_pm_enter,
 	.finish		= omap_pm_finish,
-	.valid		= pm_valid_only_mem,
+	.valid		= suspend_valid_only_mem,
 };
 
 static int __init omap_pm_init(void)
@@ -735,7 +720,7 @@
 	else if (cpu_is_omap16xx())
 		omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
 
-	pm_set_ops(&omap_pm_ops);
+	suspend_set_ops(&omap_pm_ops);
 
 #if defined(DEBUG) && defined(CONFIG_PROC_FS)
 	omap_pm_init_proc();
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 6f4a543..baf7d82 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -16,10 +16,9 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/pm.h>
 #include <linux/interrupt.h>
 #include <linux/sysfs.h>
 #include <linux/module.h>
@@ -71,28 +70,12 @@
 	local_irq_enable();
 }
 
-static int omap2_pm_prepare(suspend_state_t state)
+static int omap2_pm_prepare(void)
 {
-	int error = 0;
-
 	/* We cannot sleep in idle until we have resumed */
 	saved_idle = pm_idle;
 	pm_idle = NULL;
-
-	switch (state)
-	{
-	case PM_SUSPEND_STANDBY:
-	case PM_SUSPEND_MEM:
-		break;
-
-	case PM_SUSPEND_DISK:
-		return -ENOTSUPP;
-
-	default:
-		return -EINVAL;
-	}
-
-	return error;
+	return 0;
 }
 
 #define INT0_WAKE_MASK	(OMAP_IRQ_BIT(INT_24XX_GPIO_BANK1) |	\
@@ -353,9 +336,6 @@
 	case PM_SUSPEND_MEM:
 		ret = omap2_pm_suspend();
 		break;
-	case PM_SUSPEND_DISK:
-		ret = -ENOTSUPP;
-		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -363,17 +343,16 @@
 	return ret;
 }
 
-static int omap2_pm_finish(suspend_state_t state)
+static void omap2_pm_finish(void)
 {
 	pm_idle = saved_idle;
-	return 0;
 }
 
-static struct pm_ops omap_pm_ops = {
+static struct platform_suspend_ops omap_pm_ops = {
 	.prepare	= omap2_pm_prepare,
 	.enter		= omap2_pm_enter,
 	.finish		= omap2_pm_finish,
-	.valid		= pm_valid_only_mem,
+	.valid		= suspend_valid_only_mem,
 };
 
 int __init omap2_pm_init(void)
@@ -397,7 +376,7 @@
 	omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
 					    omap24xx_cpu_suspend_sz);
 
-	pm_set_ops(&omap_pm_ops);
+	suspend_set_ops(&omap_pm_ops);
 	pm_idle = omap2_pm_idle;
 
 	pmdomain_init();
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 62e801e..8d322c2 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 2005 Nokia Corporation
  * Author: Paul Mundt <paul.mundt@nokia.com>
- *         Juha Yrjölä <juha.yrjola@nokia.com>
+ *         Juha Yrjölä <juha.yrjola@nokia.com>
  * OMAP Dual-mode timer framework support by Timo Teras
  *
  * Some parts based off of TI's 24xx code:
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c
index 2a137f3..40116d2 100644
--- a/arch/arm/mach-pnx4008/pm.c
+++ b/arch/arm/mach-pnx4008/pm.c
@@ -15,7 +15,7 @@
 #include <linux/rtc.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
 
@@ -117,7 +117,7 @@
 	       (state == PM_SUSPEND_MEM);
 }
 
-static struct pm_ops pnx4008_pm_ops = {
+static struct platform_suspend_ops pnx4008_pm_ops = {
 	.enter = pnx4008_pm_enter,
 	.valid = pnx4008_pm_valid,
 };
@@ -146,7 +146,7 @@
 		return -ENOMEM;
 	}
 
-	pm_set_ops(&pnx4008_pm_ops);
+	suspend_set_ops(&pnx4008_pm_ops);
 	return 0;
 }
 
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index b59a81a..a941c71 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -86,7 +86,7 @@
 	return -EINVAL;
 }
 
-static struct pm_ops pxa_pm_ops = {
+static struct platform_suspend_ops pxa_pm_ops = {
 	.valid		= pxa_pm_valid,
 	.enter		= pxa_pm_enter,
 };
@@ -104,7 +104,7 @@
 		return -ENOMEM;
 	}
 
-	pm_set_ops(&pxa_pm_ops);
+	suspend_set_ops(&pxa_pm_ops);
 	return 0;
 }
 
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 0d6a725..dcd81f8 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -20,7 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
 
 #include <asm/hardware.h>
 #include <asm/arch/irqs.h>
@@ -215,7 +215,7 @@
 
 static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
 	.save_size	= SLEEP_SAVE_SIZE,
-	.valid		= pm_valid_only_mem,
+	.valid		= suspend_valid_only_mem,
 	.save		= pxa25x_cpu_pm_save,
 	.restore	= pxa25x_cpu_pm_restore,
 	.enter		= pxa25x_cpu_pm_enter,
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 2d7fc39..d0f2b59 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -14,7 +14,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/platform_device.h>
 
 #include <asm/hardware.h>
diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c
index 5363b13..7a34231 100644
--- a/arch/arm/mach-pxa/pxa300.c
+++ b/arch/arm/mach-pxa/pxa300.c
@@ -23,8 +23,10 @@
 
 	MFP_ADDR_X(GPIO0,   GPIO2,   0x00b4),
 	MFP_ADDR_X(GPIO3,   GPIO26,  0x027c),
-	MFP_ADDR_X(GPIO27,  GPIO127, 0x0400),
-	MFP_ADDR_X(GPIO0_2, GPIO6_2, 0x02ec),
+	MFP_ADDR_X(GPIO27,  GPIO98,  0x0400),
+	MFP_ADDR_X(GPIO99,  GPIO127, 0x0600),
+	MFP_ADDR_X(GPIO0_2, GPIO1_2, 0x0674),
+	MFP_ADDR_X(GPIO2_2, GPIO6_2, 0x02dc),
 
 	MFP_ADDR(nBE0, 0x0204),
 	MFP_ADDR(nBE1, 0x0208),
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index cab9d62..2bfaa61 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -238,7 +238,7 @@
 	}
 
 	/* We must be careful disabling the clocks we are not intending to
-	 * be using at boot time, as subsytems such as the LCD which do
+	 * be using at boot time, as subsystems such as the LCD which do
 	 * their own DMA requests to the bus can cause the system to lockup
 	 * if they where in the middle of requesting bus access.
 	 *
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index 8543dd6..4589936 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -689,7 +689,7 @@
 	}
 
 	/* We must be careful disabling the clocks we are not intending to
-	 * be using at boot time, as subsytems such as the LCD which do
+	 * be using at boot time, as subsystems such as the LCD which do
 	 * their own DMA requests to the bus can cause the system to lockup
 	 * if they where in the middle of requesting bus access.
 	 *
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 5840294..b42f956 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -1005,7 +1005,7 @@
 	}
 
 	/* We must be careful disabling the clocks we are not intending to
-	 * be using at boot time, as subsytems such as the LCD which do
+	 * be using at boot time, as subsystems such as the LCD which do
 	 * their own DMA requests to the bus can cause the system to lockup
 	 * if they where in the middle of requesting bus access.
 	 *
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index 01a37d3..246c573 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -122,14 +122,14 @@
 	return virt_to_phys(sp);
 }
 
-static struct pm_ops sa11x0_pm_ops = {
+static struct platform_suspend_ops sa11x0_pm_ops = {
 	.enter		= sa11x0_pm_enter,
-	.valid		= pm_valid_only_mem,
+	.valid		= suspend_valid_only_mem,
 };
 
 static int __init sa11x0_pm_init(void)
 {
-	pm_set_ops(&sa11x0_pm_ops);
+	suspend_set_ops(&sa11x0_pm_ops);
 	return 0;
 }
 
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 074b7cb..e162cca 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -757,7 +757,7 @@
 	if (ai_usermode & 1)
 		printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx "
 		       "Address=0x%08lx FSR 0x%03x\n", current->comm,
-			current->pid, instrptr,
+			task_pid_nr(current), instrptr,
 		        thumb_mode(regs) ? 4 : 8,
 		        thumb_mode(regs) ? tinstr : instr,
 		        addr, fsr);
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 59ed1d0..a8a7dab 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -197,7 +197,7 @@
 	return fault;
 
 out_of_memory:
-	if (!is_init(tsk))
+	if (!is_global_init(tsk))
 		goto out;
 
 	/*
diff --git a/arch/arm/nwfpe/fpopcode.h b/arch/arm/nwfpe/fpopcode.h
index ec78e35..786e4c9 100644
--- a/arch/arm/nwfpe/fpopcode.h
+++ b/arch/arm/nwfpe/fpopcode.h
@@ -78,11 +78,11 @@
 +-------------------------+---+---+---------+---------+
 |  Precision              | u | v | FPSR.EP | length  |
 +-------------------------+---+---+---------+---------+
-| Single                  | 0 ü 0 |    x    | 1 words |
-| Double                  | 1 ü 1 |    x    | 2 words |
-| Extended                | 1 ü 1 |    x    | 3 words |
-| Packed decimal          | 1 ü 1 |    0    | 3 words |
-| Expanded packed decimal | 1 ü 1 |    1    | 4 words |
+| Single                  | 0 | 0 |    x    | 1 words |
+| Double                  | 1 | 1 |    x    | 2 words |
+| Extended                | 1 | 1 |    x    | 3 words |
+| Packed decimal          | 1 | 1 |    0    | 3 words |
+| Expanded packed decimal | 1 | 1 |    1    | 4 words |
 +-------------------------+---+---+---------+---------+
 Note: x = don't care
 */
@@ -92,10 +92,10 @@
 +---+---+---------------------------------+
 | w | x | Number of registers to transfer |
 +---+---+---------------------------------+
-| 0 ü 1 |  1                              |
-| 1 ü 0 |  2                              |
-| 1 ü 1 |  3                              |
-| 0 ü 0 |  4                              |
+| 0 | 1 |  1                              |
+| 1 | 0 |  2                              |
+| 1 | 1 |  3                              |
+| 0 | 0 |  4                              |
 +---+---+---------------------------------+
 */
 
@@ -156,10 +156,10 @@
 +-------------------------+---+---+
 |  Rounding Precision     | e | f |
 +-------------------------+---+---+
-| IEEE Single precision   | 0 ü 0 |
-| IEEE Double precision   | 0 ü 1 |
-| IEEE Extended precision | 1 ü 0 |
-| undefined (trap)        | 1 ü 1 |
+| IEEE Single precision   | 0 | 0 |
+| IEEE Double precision   | 0 | 1 |
+| IEEE Extended precision | 1 | 0 |
+| undefined (trap)        | 1 | 1 |
 +-------------------------+---+---+
 */
 
@@ -168,10 +168,10 @@
 +---------------------------------+---+---+
 |  Rounding Mode                  | g | h |
 +---------------------------------+---+---+
-| Round to nearest (default)      | 0 ü 0 |
-| Round toward plus infinity      | 0 ü 1 |
-| Round toward negative infinity  | 1 ü 0 |
-| Round toward zero               | 1 ü 1 |
+| Round to nearest (default)      | 0 | 0 |
+| Round toward plus infinity      | 0 | 1 |
+| Round toward negative infinity  | 1 | 0 |
+| Round toward zero               | 1 | 1 |
 +---------------------------------+---+---+
 */
 
@@ -369,20 +369,20 @@
 #define getRoundingMode(opcode)		((opcode & MASK_ROUNDING_MODE) >> 5)
 
 #ifdef CONFIG_FPE_NWFPE_XP
-static inline __attribute_pure__ floatx80 getExtendedConstant(const unsigned int nIndex)
+static inline floatx80 __pure getExtendedConstant(const unsigned int nIndex)
 {
 	extern const floatx80 floatx80Constant[];
 	return floatx80Constant[nIndex];
 }
 #endif
 
-static inline __attribute_pure__ float64 getDoubleConstant(const unsigned int nIndex)
+static inline float64 __pure getDoubleConstant(const unsigned int nIndex)
 {
 	extern const float64 float64Constant[];
 	return float64Constant[nIndex];
 }
 
-static inline __attribute_pure__ float32 getSingleConstant(const unsigned int nIndex)
+static inline float32 __pure getSingleConstant(const unsigned int nIndex)
 {
 	extern const float32 float32Constant[];
 	return float32Constant[nIndex];
diff --git a/arch/arm/oprofile/Kconfig b/arch/arm/oprofile/Kconfig
deleted file mode 100644
index afd93ad..0000000
--- a/arch/arm/oprofile/Kconfig
+++ /dev/null
@@ -1,42 +0,0 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
-if OPROFILE
-
-config OPROFILE_ARMV6
-	bool
-	depends on CPU_V6 && !SMP
-	default y
-	select OPROFILE_ARM11_CORE
-
-config OPROFILE_MPCORE
-	bool
-	depends on CPU_V6 && SMP
-	default y
-	select OPROFILE_ARM11_CORE
-
-config OPROFILE_ARM11_CORE
-	bool
-
-endif
-
-endmenu
-
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 05a3849..dcbba07 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -2,7 +2,7 @@
  * linux/arch/arm/plat-omap/dma.c
  *
  * Copyright (C) 2003 Nokia Corporation
- * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
  * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
  * Graphics DMA and LCD DMA graphics tranformations
  * by Imre Deak <imre.deak@nokia.com>
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 337455d..6097753 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -4,7 +4,7 @@
  * Support functions for OMAP GPIO
  *
  * Copyright (C) 2003-2005 Nokia Corporation
- * Written by Juha Yrjölä <juha.yrjola@nokia.com>
+ * Written by Juha Yrjölä <juha.yrjola@nokia.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
index eab1850..4fdb311 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -612,9 +612,9 @@
 	return 0;
 }
 
-static struct pm_ops s3c2410_pm_ops = {
+static struct platform_suspend_ops s3c2410_pm_ops = {
 	.enter		= s3c2410_pm_enter,
-	.valid		= pm_valid_only_mem,
+	.valid		= suspend_valid_only_mem,
 };
 
 /* s3c2410_pm_init
@@ -628,6 +628,6 @@
 {
 	printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n");
 
-	pm_set_ops(&s3c2410_pm_ops);
+	suspend_set_ops(&s3c2410_pm_ops);
 	return 0;
 }
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
index 74e89f8..190a09a 100644
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -1132,7 +1132,7 @@
 	unsigned int vecitr, veclen, vecstride;
 	struct op *fop;
 
-	vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2;
+	vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK));
 
 	fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)];
 
@@ -1184,10 +1184,10 @@
 		 * CHECK: It appears to be undefined whether we stop when
 		 * we encounter an exception.  We continue.
 		 */
-		dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 6);
-		dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6);
+		dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 3);
+		dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 3);
 		if (FREG_BANK(dm) != 0)
-			dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 6);
+			dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 3);
 	}
 	return exceptions;
 
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index eea3f50..b4e210d 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -229,7 +229,7 @@
 	/*
 	 * Enable access to the VFP so we can handle the bounce.
 	 */
-	fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_INV|FPEXC_UFC|FPEXC_IOC));
+	fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_FPV2|FPEXC_INV|FPEXC_UFC|FPEXC_OFC|FPEXC_IOC));
 
 	orig_fpscr = fpscr = fmrx(FPSCR);
 
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index d12346a..bbecbd8 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -189,7 +189,7 @@
 
 endmenu
 
-menu "Power managment options"
+menu "Power management options"
 
 menu "CPU Frequency scaling"
 
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index 6b9e466..5be0d13 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/at73c213.h>
 
 #include <video/atmel_lcdc.h>
 
@@ -49,7 +50,26 @@
 };
 
 #ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM
+#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
+static struct at73c213_board_info at73c213_data = {
+	.ssc_id		= 0,
+	.shortname	= "AVR32 STK1000 external DAC",
+};
+#endif
+#endif
+
+#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM
 static struct spi_board_info spi0_board_info[] __initdata = {
+#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
+	{
+		/* AT73C213 */
+		.modalias	= "at73c213",
+		.max_speed_hz	= 200000,
+		.chip_select	= 0,
+		.mode		= SPI_MODE_1,
+		.platform_data	= &at73c213_data,
+	},
+#endif
 	{
 		/* QVGA display */
 		.modalias	= "ltv350qv",
@@ -180,6 +200,38 @@
 }
 #endif
 
+#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM
+#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
+static void __init at73c213_set_clk(struct at73c213_board_info *info)
+{
+	struct clk *gclk;
+	struct clk *pll;
+
+	gclk = clk_get(NULL, "gclk0");
+	if (IS_ERR(gclk))
+		goto err_gclk;
+	pll = clk_get(NULL, "pll0");
+	if (IS_ERR(pll))
+		goto err_pll;
+
+	if (clk_set_parent(gclk, pll)) {
+		pr_debug("STK1000: failed to set pll0 as parent for DAC clock\n");
+		goto err_set_clk;
+	}
+
+	at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
+	info->dac_clk = gclk;
+
+err_set_clk:
+	clk_put(pll);
+err_pll:
+	clk_put(gclk);
+err_gclk:
+	return;
+}
+#endif
+#endif
+
 void __init setup_board(void)
 {
 #ifdef	CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
@@ -248,6 +300,12 @@
 
 	setup_j2_leds();
 
+#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
+#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM
+	at73c213_set_clk(&at73c213_data);
+#endif
+#endif
+
 	return 0;
 }
 postcore_initcall(atstk1002_init);
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c
index 9a73ce7..8a7caf8e 100644
--- a/arch/avr32/kernel/traps.c
+++ b/arch/avr32/kernel/traps.c
@@ -89,7 +89,7 @@
 	 * generate the same exception over and over again and we get
 	 * nowhere.  Better to kill it and let the kernel panic.
 	 */
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		__sighandler_t handler;
 
 		spin_lock_irq(&current->sighand->siglock);
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c
index f6d154c..a9d9ec0 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap7000.c
@@ -556,6 +556,17 @@
 	.users		= 1,
 };
 
+static struct resource dmaca0_resource[] = {
+	{
+		.start	= 0xff200000,
+		.end	= 0xff20ffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	IRQ(2),
+};
+DEFINE_DEV(dmaca, 0);
+DEV_CLK(hclk, dmaca0, hsb, 10);
+
 /* --------------------------------------------------------------------
  * HMATRIX
  * -------------------------------------------------------------------- */
@@ -655,6 +666,7 @@
 	platform_device_register(&at32_eic0_device);
 	platform_device_register(&smc0_device);
 	platform_device_register(&pdc_device);
+	platform_device_register(&dmaca0_device);
 
 	platform_device_register(&at32_systc0_device);
 
@@ -960,6 +972,96 @@
 }
 
 /* --------------------------------------------------------------------
+ *  TWI
+ * -------------------------------------------------------------------- */
+static struct resource atmel_twi0_resource[] __initdata = {
+	PBMEM(0xffe00800),
+	IRQ(5),
+};
+static struct clk atmel_twi0_pclk = {
+	.name		= "twi_pclk",
+	.parent		= &pba_clk,
+	.mode		= pba_clk_mode,
+	.get_rate	= pba_clk_get_rate,
+	.index		= 2,
+};
+
+struct platform_device *__init at32_add_device_twi(unsigned int id)
+{
+	struct platform_device *pdev;
+
+	if (id != 0)
+		return NULL;
+
+	pdev = platform_device_alloc("atmel_twi", id);
+	if (!pdev)
+		return NULL;
+
+	if (platform_device_add_resources(pdev, atmel_twi0_resource,
+				ARRAY_SIZE(atmel_twi0_resource)))
+		goto err_add_resources;
+
+	select_peripheral(PA(6),  PERIPH_A, 0);	/* SDA	*/
+	select_peripheral(PA(7),  PERIPH_A, 0);	/* SDL	*/
+
+	atmel_twi0_pclk.dev = &pdev->dev;
+
+	platform_device_add(pdev);
+	return pdev;
+
+err_add_resources:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* --------------------------------------------------------------------
+ * MMC
+ * -------------------------------------------------------------------- */
+static struct resource atmel_mci0_resource[] __initdata = {
+	PBMEM(0xfff02400),
+	IRQ(28),
+};
+static struct clk atmel_mci0_pclk = {
+	.name		= "mci_clk",
+	.parent		= &pbb_clk,
+	.mode		= pbb_clk_mode,
+	.get_rate	= pbb_clk_get_rate,
+	.index		= 9,
+};
+
+struct platform_device *__init at32_add_device_mci(unsigned int id)
+{
+	struct platform_device *pdev;
+
+	if (id != 0)
+		return NULL;
+
+	pdev = platform_device_alloc("atmel_mci", id);
+	if (!pdev)
+		return NULL;
+
+	if (platform_device_add_resources(pdev, atmel_mci0_resource,
+				ARRAY_SIZE(atmel_mci0_resource)))
+		goto err_add_resources;
+
+	select_peripheral(PA(10), PERIPH_A, 0);	/* CLK	 */
+	select_peripheral(PA(11), PERIPH_A, 0);	/* CMD	 */
+	select_peripheral(PA(12), PERIPH_A, 0);	/* DATA0 */
+	select_peripheral(PA(13), PERIPH_A, 0);	/* DATA1 */
+	select_peripheral(PA(14), PERIPH_A, 0);	/* DATA2 */
+	select_peripheral(PA(15), PERIPH_A, 0);	/* DATA3 */
+
+	atmel_mci0_pclk.dev = &pdev->dev;
+
+	platform_device_add(pdev);
+	return pdev;
+
+err_add_resources:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* --------------------------------------------------------------------
  *  LCDC
  * -------------------------------------------------------------------- */
 static struct atmel_lcdfb_info atmel_lcdfb0_data;
@@ -1228,6 +1330,241 @@
 }
 
 /* --------------------------------------------------------------------
+ * IDE / CompactFlash
+ * -------------------------------------------------------------------- */
+static struct resource at32_smc_cs4_resource[] __initdata = {
+	{
+		.start	= 0x04000000,
+		.end	= 0x07ffffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	IRQ(~0UL), /* Magic IRQ will be overridden */
+};
+static struct resource at32_smc_cs5_resource[] __initdata = {
+	{
+		.start	= 0x20000000,
+		.end	= 0x23ffffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	IRQ(~0UL), /* Magic IRQ will be overridden */
+};
+
+static int __init at32_init_ide_or_cf(struct platform_device *pdev,
+		unsigned int cs, unsigned int extint)
+{
+	static unsigned int extint_pin_map[4] __initdata = {
+		GPIO_PIN_PB(25),
+		GPIO_PIN_PB(26),
+		GPIO_PIN_PB(27),
+		GPIO_PIN_PB(28),
+	};
+	static bool common_pins_initialized __initdata = false;
+	unsigned int extint_pin;
+	int ret;
+
+	if (extint >= ARRAY_SIZE(extint_pin_map))
+		return -EINVAL;
+	extint_pin = extint_pin_map[extint];
+
+	switch (cs) {
+	case 4:
+		ret = platform_device_add_resources(pdev,
+				at32_smc_cs4_resource,
+				ARRAY_SIZE(at32_smc_cs4_resource));
+		if (ret)
+			return ret;
+
+		select_peripheral(PE(21), PERIPH_A, 0); /* NCS4   -> OE_N  */
+		set_ebi_sfr_bits(HMATRIX_BIT(CS4A));
+		break;
+	case 5:
+		ret = platform_device_add_resources(pdev,
+				at32_smc_cs5_resource,
+				ARRAY_SIZE(at32_smc_cs5_resource));
+		if (ret)
+			return ret;
+
+		select_peripheral(PE(22), PERIPH_A, 0); /* NCS5   -> OE_N  */
+		set_ebi_sfr_bits(HMATRIX_BIT(CS5A));
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (!common_pins_initialized) {
+		select_peripheral(PE(19), PERIPH_A, 0);	/* CFCE1  -> CS0_N */
+		select_peripheral(PE(20), PERIPH_A, 0);	/* CFCE2  -> CS1_N */
+		select_peripheral(PE(23), PERIPH_A, 0); /* CFRNW  -> DIR   */
+		select_peripheral(PE(24), PERIPH_A, 0); /* NWAIT  <- IORDY */
+		common_pins_initialized = true;
+	}
+
+	at32_select_periph(extint_pin, GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH);
+
+	pdev->resource[1].start = EIM_IRQ_BASE + extint;
+	pdev->resource[1].end = pdev->resource[1].start;
+
+	return 0;
+}
+
+struct platform_device *__init
+at32_add_device_ide(unsigned int id, unsigned int extint,
+		    struct ide_platform_data *data)
+{
+	struct platform_device *pdev;
+
+	pdev = platform_device_alloc("at32_ide", id);
+	if (!pdev)
+		goto fail;
+
+	if (platform_device_add_data(pdev, data,
+				sizeof(struct ide_platform_data)))
+		goto fail;
+
+	if (at32_init_ide_or_cf(pdev, data->cs, extint))
+		goto fail;
+
+	platform_device_add(pdev);
+	return pdev;
+
+fail:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+struct platform_device *__init
+at32_add_device_cf(unsigned int id, unsigned int extint,
+		    struct cf_platform_data *data)
+{
+	struct platform_device *pdev;
+
+	pdev = platform_device_alloc("at32_cf", id);
+	if (!pdev)
+		goto fail;
+
+	if (platform_device_add_data(pdev, data,
+				sizeof(struct cf_platform_data)))
+		goto fail;
+
+	if (at32_init_ide_or_cf(pdev, data->cs, extint))
+		goto fail;
+
+	if (data->detect_pin != GPIO_PIN_NONE)
+		at32_select_gpio(data->detect_pin, AT32_GPIOF_DEGLITCH);
+	if (data->reset_pin != GPIO_PIN_NONE)
+		at32_select_gpio(data->reset_pin, 0);
+	if (data->vcc_pin != GPIO_PIN_NONE)
+		at32_select_gpio(data->vcc_pin, 0);
+	/* READY is used as extint, so we can't select it as gpio */
+
+	platform_device_add(pdev);
+	return pdev;
+
+fail:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* --------------------------------------------------------------------
+ * AC97C
+ * -------------------------------------------------------------------- */
+static struct resource atmel_ac97c0_resource[] __initdata = {
+	PBMEM(0xfff02800),
+	IRQ(29),
+};
+static struct clk atmel_ac97c0_pclk = {
+	.name		= "pclk",
+	.parent		= &pbb_clk,
+	.mode		= pbb_clk_mode,
+	.get_rate	= pbb_clk_get_rate,
+	.index		= 10,
+};
+
+struct platform_device *__init at32_add_device_ac97c(unsigned int id)
+{
+	struct platform_device *pdev;
+
+	if (id != 0)
+		return NULL;
+
+	pdev = platform_device_alloc("atmel_ac97c", id);
+	if (!pdev)
+		return NULL;
+
+	if (platform_device_add_resources(pdev, atmel_ac97c0_resource,
+				ARRAY_SIZE(atmel_ac97c0_resource)))
+		goto err_add_resources;
+
+	select_peripheral(PB(20), PERIPH_B, 0);	/* SYNC	*/
+	select_peripheral(PB(21), PERIPH_B, 0);	/* SDO	*/
+	select_peripheral(PB(22), PERIPH_B, 0);	/* SDI	*/
+	select_peripheral(PB(23), PERIPH_B, 0);	/* SCLK	*/
+
+	atmel_ac97c0_pclk.dev = &pdev->dev;
+
+	platform_device_add(pdev);
+	return pdev;
+
+err_add_resources:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* --------------------------------------------------------------------
+ * ABDAC
+ * -------------------------------------------------------------------- */
+static struct resource abdac0_resource[] __initdata = {
+	PBMEM(0xfff02000),
+	IRQ(27),
+};
+static struct clk abdac0_pclk = {
+	.name		= "pclk",
+	.parent		= &pbb_clk,
+	.mode		= pbb_clk_mode,
+	.get_rate	= pbb_clk_get_rate,
+	.index		= 8,
+};
+static struct clk abdac0_sample_clk = {
+	.name		= "sample_clk",
+	.mode		= genclk_mode,
+	.get_rate	= genclk_get_rate,
+	.set_rate	= genclk_set_rate,
+	.set_parent	= genclk_set_parent,
+	.index		= 6,
+};
+
+struct platform_device *__init at32_add_device_abdac(unsigned int id)
+{
+	struct platform_device *pdev;
+
+	if (id != 0)
+		return NULL;
+
+	pdev = platform_device_alloc("abdac", id);
+	if (!pdev)
+		return NULL;
+
+	if (platform_device_add_resources(pdev, abdac0_resource,
+				ARRAY_SIZE(abdac0_resource)))
+		goto err_add_resources;
+
+	select_peripheral(PB(20), PERIPH_A, 0);	/* DATA1	*/
+	select_peripheral(PB(21), PERIPH_A, 0);	/* DATA0	*/
+	select_peripheral(PB(22), PERIPH_A, 0);	/* DATAN1	*/
+	select_peripheral(PB(23), PERIPH_A, 0);	/* DATAN0	*/
+
+	abdac0_pclk.dev = &pdev->dev;
+	abdac0_sample_clk.dev = &pdev->dev;
+
+	platform_device_add(pdev);
+	return pdev;
+
+err_add_resources:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* --------------------------------------------------------------------
  *  GCLK
  * -------------------------------------------------------------------- */
 static struct clk gclk0 = {
@@ -1290,6 +1627,7 @@
 	&smc0_mck,
 	&pdc_hclk,
 	&pdc_pclk,
+	&dmaca0_hclk,
 	&pico_clk,
 	&pio0_mck,
 	&pio1_mck,
@@ -1307,6 +1645,8 @@
 	&macb1_pclk,
 	&atmel_spi0_spi_clk,
 	&atmel_spi1_spi_clk,
+	&atmel_twi0_pclk,
+	&atmel_mci0_pclk,
 	&atmel_lcdfb0_hck1,
 	&atmel_lcdfb0_pixclk,
 	&ssc0_pclk,
@@ -1314,6 +1654,9 @@
 	&ssc2_pclk,
 	&usba0_hclk,
 	&usba0_pclk,
+	&atmel_ac97c0_pclk,
+	&abdac0_pclk,
+	&abdac0_sample_clk,
 	&gclk0,
 	&gclk1,
 	&gclk2,
@@ -1355,6 +1698,7 @@
 	genclk_init_parent(&gclk3);
 	genclk_init_parent(&gclk4);
 	genclk_init_parent(&atmel_lcdfb0_pixclk);
+	genclk_init_parent(&abdac0_sample_clk);
 
 	/*
 	 * Turn on all clocks that have at least one user already, and
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
index 8acd0109..f5bfd4c 100644
--- a/arch/avr32/mach-at32ap/extint.c
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -142,7 +142,7 @@
 	return ret;
 }
 
-struct irq_chip eic_chip = {
+static struct irq_chip eic_chip = {
 	.name		= "eic",
 	.ack		= eic_ack_irq,
 	.mask		= eic_mask_irq,
diff --git a/arch/avr32/mach-at32ap/pm.h b/arch/avr32/mach-at32ap/pm.h
index 47efd0d..694d521 100644
--- a/arch/avr32/mach-at32ap/pm.h
+++ b/arch/avr32/mach-at32ap/pm.h
@@ -113,8 +113,8 @@
 
 /* Register access macros */
 #define pm_readl(reg)							\
-	__raw_readl((void __iomem *)AT32_PM_BASE + PM_##reg)
+	__raw_readl((void __iomem __force *)AT32_PM_BASE + PM_##reg)
 #define pm_writel(reg,value)						\
-	__raw_writel((value), (void __iomem *)AT32_PM_BASE + PM_##reg)
+	__raw_writel((value), (void __iomem __force *)AT32_PM_BASE + PM_##reg)
 
 #endif /* __ARCH_AVR32_MACH_AT32AP_PM_H__ */
diff --git a/arch/avr32/mach-at32ap/time-tc.c b/arch/avr32/mach-at32ap/time-tc.c
index e3070bd..1026586 100644
--- a/arch/avr32/mach-at32ap/time-tc.c
+++ b/arch/avr32/mach-at32ap/time-tc.c
@@ -79,7 +79,7 @@
 {
 	unsigned int cycles_max = (clocksource_avr32.mask + 1) / 2;
 	unsigned int divs[] = { 4, 8, 16, 32 };
-	int divs_size = sizeof(divs) / sizeof(*divs);
+	int divs_size = ARRAY_SIZE(divs);
 	int i = 0;
 	unsigned long count_hz;
 	unsigned long shift;
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index 11472f8..6560cb1 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -160,7 +160,7 @@
 		if (exception_trace && printk_ratelimit())
 			printk("%s%s[%d]: segfault at %08lx pc %08lx "
 			       "sp %08lx ecr %lu\n",
-			       is_init(tsk) ? KERN_EMERG : KERN_INFO,
+			       is_global_init(tsk) ? KERN_EMERG : KERN_INFO,
 			       tsk->comm, tsk->pid, address, regs->pc,
 			       regs->sp, ecr);
 		_exception(SIGSEGV, regs, code, address);
@@ -209,7 +209,7 @@
 	 */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
@@ -231,7 +231,7 @@
 	if (exception_trace)
 		printk("%s%s[%d]: bus error at %08lx pc %08lx "
 		       "sp %08lx ecr %lu\n",
-		       is_init(tsk) ? KERN_EMERG : KERN_INFO,
+		       is_global_init(tsk) ? KERN_EMERG : KERN_INFO,
 		       tsk->comm, tsk->pid, address, regs->pc,
 		       regs->sp, ecr);
 
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index aa9db30..7888551 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -71,7 +71,7 @@
 
 config IRQCHIP_DEMUX_GPIO
 	bool
-	depends on (BF53x || BF561 || BF54x)
+	depends on (BF52x || BF53x || BF561 || BF54x)
 	default y
 
 source "init/Kconfig"
@@ -85,6 +85,21 @@
 	prompt "CPU"
 	default BF533
 
+config BF522
+	bool "BF522"
+	help
+	  BF522 Processor Support.
+
+config BF525
+	bool "BF525"
+	help
+	  BF525 Processor Support.
+
+config BF527
+	bool "BF527"
+	help
+	  BF527 Processor Support.
+
 config BF531
 	bool "BF531"
 	help
@@ -144,13 +159,18 @@
 
 choice
 	prompt "Silicon Rev"
+	default BF_REV_0_1 if BF527
 	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)
+	depends on (BF549 || BF527)
+
+config BF_REV_0_1
+	bool "0.2"
+	depends on (BF549 || BF527)
 
 config BF_REV_0_2
 	bool "0.2"
@@ -176,6 +196,11 @@
 
 endchoice
 
+config BF52x
+	bool
+	depends on (BF522 || BF525 || BF527)
+	default y
+
 config BF53x
 	bool
 	depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537)
@@ -204,6 +229,12 @@
 	  configuration to ensure that all the other settings are
 	  correct.
 
+config BFIN527_EZKIT
+	bool "BF527-EZKIT"
+	depends on (BF522 || BF525 || BF527)
+	help
+	  BF533-EZKIT-LITE board Support.
+
 config BFIN533_EZKIT
 	bool "BF533-EZKIT"
 	depends on (BF533 || BF532 || BF531)
@@ -299,11 +330,17 @@
 	depends on (BFIN561_BLUETECHNIX_CM)
 	default y
 
+config MEM_MT48LC32M16A2TG_75
+	bool
+	depends on (BFIN527_EZKIT)
+	default y
+
 config BFIN_SHARED_FLASH_ENET
 	bool
 	depends on (BFIN533_STAMP)
 	default y
 
+source "arch/blackfin/mach-bf527/Kconfig"
 source "arch/blackfin/mach-bf533/Kconfig"
 source "arch/blackfin/mach-bf561/Kconfig"
 source "arch/blackfin/mach-bf537/Kconfig"
@@ -329,7 +366,7 @@
 	int "Crystal Frequency in Hz"
 	default "11059200" if BFIN533_STAMP
 	default "27000000" if BFIN533_EZKIT
-	default "25000000" if BFIN537_STAMP
+	default "25000000" if (BFIN537_STAMP || BFIN527_EZKIT)
 	default "30000000" if BFIN561_EZKIT
 	default "24576000" if PNAV10
 	help
@@ -362,7 +399,7 @@
 	range 1 64
 	default "22" if BFIN533_EZKIT
 	default "45" if BFIN533_STAMP
-	default "20" if BFIN537_STAMP
+	default "20" if (BFIN537_STAMP || BFIN527_EZKIT)
 	default "22" if BFIN533_BLUETECHNIX_CM
 	default "20" if BFIN537_BLUETECHNIX_CM
 	default "20" if BFIN561_BLUETECHNIX_CM
@@ -398,7 +435,7 @@
 	range 1 15
 	default 5 if BFIN533_EZKIT
 	default 5 if BFIN533_STAMP
-	default 4 if BFIN537_STAMP
+	default 4 if (BFIN537_STAMP || BFIN527_EZKIT)
 	default 5 if BFIN533_BLUETECHNIX_CM
 	default 4 if BFIN537_BLUETECHNIX_CM
 	default 4 if BFIN561_BLUETECHNIX_CM
@@ -450,6 +487,7 @@
 config MEM_SIZE
 	int "SDRAM Memory Size in MBytes"
 	default  32 if BFIN533_EZKIT
+	default  64 if BFIN527_EZKIT
 	default  64 if BFIN537_STAMP
 	default  64 if BFIN561_EZKIT
 	default 128 if BFIN533_STAMP
@@ -459,6 +497,7 @@
 	int "SDRAM Memory Address Width"
 	default  9 if BFIN533_EZKIT
 	default  9 if BFIN561_EZKIT
+	default 10 if BFIN527_EZKIT
 	default 10 if BFIN537_STAMP
 	default 11 if BFIN533_STAMP
 	default 10 if PNAV10
@@ -613,85 +652,86 @@
 	bool "Locate interrupt entry code in L1 Memory"
 	default y
 	help
-	  If enabled interrupt entry code (STORE/RESTORE CONTEXT) is linked
-	  into L1 instruction memory.(less latency)
+	  If enabled, interrupt entry code (STORE/RESTORE CONTEXT) is linked
+	  into L1 instruction memory. (less latency)
 
 config EXCPT_IRQ_SYSC_L1
-	bool "Locate entire ASM lowlevel excepetion / interrupt - Syscall and CPLB handler code in L1 Memory"
+	bool "Locate entire ASM lowlevel exception / interrupt - Syscall and CPLB handler code in L1 Memory"
 	default y
 	help
-	  If enabled entire ASM lowlevel exception and interrupt entry code (STORE/RESTORE CONTEXT) is linked
-	  into L1 instruction memory.(less latency)
+	  If enabled, the entire ASM lowlevel exception and interrupt entry code
+	  (STORE/RESTORE CONTEXT) is linked into L1 instruction memory. 
+	  (less latency)
 
 config DO_IRQ_L1
 	bool "Locate frequently called do_irq dispatcher function in L1 Memory"
 	default y
 	help
-	  If enabled frequently called do_irq dispatcher function is linked
-	  into L1 instruction memory.(less latency)
+	  If enabled, the frequently called do_irq dispatcher function is linked
+	  into L1 instruction memory. (less latency)
 
 config CORE_TIMER_IRQ_L1
 	bool "Locate frequently called timer_interrupt() function in L1 Memory"
 	default y
 	help
-	  If enabled frequently called timer_interrupt() function is linked
-	  into L1 instruction memory.(less latency)
+	  If enabled, the frequently called timer_interrupt() function is linked
+	  into L1 instruction memory. (less latency)
 
 config IDLE_L1
 	bool "Locate frequently idle function in L1 Memory"
 	default y
 	help
-	  If enabled frequently called idle function is linked
-	  into L1 instruction memory.(less latency)
+	  If enabled, the frequently called idle function is linked
+	  into L1 instruction memory. (less latency)
 
 config SCHEDULE_L1
 	bool "Locate kernel schedule function in L1 Memory"
 	default y
 	help
-	  If enabled frequently called kernel schedule is linked
-	  into L1 instruction memory.(less latency)
+	  If enabled, the frequently called kernel schedule is linked
+	  into L1 instruction memory. (less latency)
 
 config ARITHMETIC_OPS_L1
 	bool "Locate kernel owned arithmetic functions in L1 Memory"
 	default y
 	help
-	  If enabled arithmetic functions are linked
-	  into L1 instruction memory.(less latency)
+	  If enabled, arithmetic functions are linked
+	  into L1 instruction memory. (less latency)
 
 config ACCESS_OK_L1
 	bool "Locate access_ok function in L1 Memory"
 	default y
 	help
-	  If enabled access_ok function is linked
-	  into L1 instruction memory.(less latency)
+	  If enabled, the access_ok function is linked
+	  into L1 instruction memory. (less latency)
 
 config MEMSET_L1
 	bool "Locate memset function in L1 Memory"
 	default y
 	help
-	  If enabled memset function is linked
-	  into L1 instruction memory.(less latency)
+	  If enabled, the memset function is linked
+	  into L1 instruction memory. (less latency)
 
 config MEMCPY_L1
 	bool "Locate memcpy function in L1 Memory"
 	default y
 	help
-	  If enabled memcpy function is linked
-	  into L1 instruction memory.(less latency)
+	  If enabled, the memcpy function is linked
+	  into L1 instruction memory. (less latency)
 
 config SYS_BFIN_SPINLOCK_L1
 	bool "Locate sys_bfin_spinlock function in L1 Memory"
 	default y
 	help
-	  If enabled sys_bfin_spinlock function is linked
-	  into L1 instruction memory.(less latency)
+	  If enabled, sys_bfin_spinlock function is linked
+	  into L1 instruction memory. (less latency)
 
 config IP_CHECKSUM_L1
 	bool "Locate IP Checksum function in L1 Memory"
 	default n
 	help
-	  If enabled IP Checksum function is linked
-	  into L1 instruction memory.(less latency)
+	  If enabled, the IP Checksum function is linked
+	  into L1 instruction memory. (less latency)
 
 config CACHELINE_ALIGNED_L1
 	bool "Locate cacheline_aligned data to L1 Data Memory"
@@ -699,24 +739,24 @@
 	default n if BF54x
 	depends on !BF531
 	help
-	  If enabled cacheline_anligned data is linked
-	  into L1 data memory.(less latency)
+	  If enabled, cacheline_anligned data is linked
+	  into L1 data memory. (less latency)
 
 config SYSCALL_TAB_L1
 	bool "Locate Syscall Table L1 Data Memory"
 	default n
 	depends on !BF531
 	help
-	  If enabled the Syscall LUT is linked
-	  into L1 data memory.(less latency)
+	  If enabled, the Syscall LUT is linked
+	  into L1 data memory. (less latency)
 
 config CPLB_SWITCH_TAB_L1
 	bool "Locate CPLB Switch Tables L1 Data Memory"
 	default n
 	depends on !BF531
 	help
-	  If enabled the CPLB Switch Tables are linked
-	  into L1 data memory.(less latency)
+	  If enabled, the CPLB Switch Tables are linked
+	  into L1 data memory. (less latency)
 
 endmenu
 
@@ -748,9 +788,19 @@
 	  a lot of RAM, and you need to able to allocate very large
 	  contiguous chunks. If unsure, say N.
 
+config BFIN_GPTIMERS
+	tristate "Enable Blackfin General Purpose Timers API"
+	default n
+	help
+	  Enable support for the General Purpose Timers API.  If you
+	  are unsure, say N.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called gptimers.ko.
+
 config BFIN_DMA_5XX
 	bool "Enable DMA Support"
-	depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561 || BF54x)
+	depends on (BF52x || BF53x || BF561 || BF54x)
 	default y
 	help
 	  DMA driver for BF5xx.
@@ -1012,7 +1062,7 @@
 
 source "fs/Kconfig"
 
-source "arch/blackfin/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 menu "Kernel hacking"
 
@@ -1029,13 +1079,13 @@
 	  from.
 
 config DEBUG_ICACHE_CHECK
-	bool "Check Instruction cache coherancy"
+	bool "Check Instruction cache coherency"
 	depends on DEBUG_KERNEL
 	depends on DEBUG_HWERR
 	help
-	  Say Y here if you are getting wierd unexplained errors. This will
-	  ensure that icache is what SDRAM says it should be, by doing a
-	  byte wise comparision between SDRAM and instruction cache. This
+	  Say Y here if you are getting weird unexplained errors. This will
+	  ensure that icache is what SDRAM says it should be by doing a
+	  byte wise comparison between SDRAM and instruction cache. This
 	  also relocates the irq_panic() function to L1 memory, (which is
 	  un-cached).
 
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
index 3689337..f7cac7c 100644
--- a/arch/blackfin/Makefile
+++ b/arch/blackfin/Makefile
@@ -12,12 +12,17 @@
 OBJCOPYFLAGS     := -O binary -R .note -R .comment -S
 GZFLAGS          := -9
 
+KBUILD_CFLAGS           += $(call cc-option,-mno-fdpic)
+KBUILD_AFLAGS           += $(call cc-option,-mno-fdpic)
 CFLAGS_MODULE    += -mlong-calls
 KALLSYMS         += --symbol-prefix=_
 
 KBUILD_DEFCONFIG := BF537-STAMP_defconfig
 
 # setup the machine name and the machine dependent settings
+machine-$(CONFIG_BF522) := bf527
+machine-$(CONFIG_BF525) := bf527
+machine-$(CONFIG_BF527) := bf527
 machine-$(CONFIG_BF531) := bf533
 machine-$(CONFIG_BF532) := bf533
 machine-$(CONFIG_BF533) := bf533
@@ -32,6 +37,9 @@
 MACHINE := $(machine-y)
 export MACHINE
 
+cpu-$(CONFIG_BF522) := bf522
+cpu-$(CONFIG_BF525) := bf525
+cpu-$(CONFIG_BF527) := bf527
 cpu-$(CONFIG_BF531) := bf531
 cpu-$(CONFIG_BF532) := bf532
 cpu-$(CONFIG_BF533) := bf533
@@ -97,12 +105,23 @@
 	$(Q)$(MAKE) $(clean)=$(boot)
 
 
-all: vmImage
 boot := arch/$(ARCH)/boot
 BOOT_TARGETS = vmImage
-.PHONY: $(BOOT_TARGETS)
+PHONY += $(BOOT_TARGETS) install
+KBUILD_IMAGE := $(boot)/vmImage
+
+all: vmImage
+
 $(BOOT_TARGETS): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+install:
+	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+
 define archhelp
   echo  '* vmImage         - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage)'
+  echo  '  install         - Install kernel using'
+  echo  '                     (your) ~/bin/$(CROSS_COMPILE)installkernel or'
+  echo  '                     (distribution) PATH: $(CROSS_COMPILE)installkernel or'
+  echo  '                     install to $$(INSTALL_PATH)'
 endef
diff --git a/arch/blackfin/boot/Makefile b/arch/blackfin/boot/Makefile
index 8cd3356..522f3c1 100644
--- a/arch/blackfin/boot/Makefile
+++ b/arch/blackfin/boot/Makefile
@@ -26,3 +26,6 @@
 $(obj)/vmImage: $(obj)/vmlinux.gz
 	$(call if_changed,uimage)
 	@echo 'Kernel: $@ is ready'
+
+install:
+	sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
diff --git a/arch/blackfin/boot/install.sh b/arch/blackfin/boot/install.sh
new file mode 100644
index 0000000..9560a6b
--- /dev/null
+++ b/arch/blackfin/boot/install.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# arch/blackfin/boot/install.sh
+#
+# 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) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Mike Frysinger
+#
+# "make install" script for Blackfin architecture
+#
+# Arguments:
+#   $1 - kernel version
+#   $2 - kernel image file
+#   $3 - kernel map file
+#   $4 - default install path (blank if root directory)
+#
+
+verify () {
+	if [ ! -f "$1" ]; then
+		echo ""                                                   1>&2
+		echo " *** Missing file: $1"                              1>&2
+		echo ' *** You need to run "make" before "make install".' 1>&2
+		echo ""                                                   1>&2
+		exit 1
+ 	fi
+}
+
+# Make sure the files actually exist
+verify "$2"
+verify "$3"
+
+# User may have a custom install script
+
+if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
+if which ${CROSS_COMPILE}installkernel >/dev/null 2>&1; then
+	exec ${CROSS_COMPILE}installkernel "$@"
+fi
+
+# Default install - same as make zlilo
+
+back_it_up() {
+	local file=$1
+	[ -f ${file} ] || return 0
+	local stamp=$(stat -c %Y ${file} 2>/dev/null)
+	mv ${file} ${file}.${stamp:-old}
+}
+
+back_it_up $4/uImage
+back_it_up $4/System.map
+
+cat $2 > $4/uImage
+cp $3 $4/System.map
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
new file mode 100644
index 0000000..df974e7
--- /dev/null
+++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -0,0 +1,1241 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.22.9
+#
+# 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_GPIO=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+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=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+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_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
+# CONFIG_NP2 is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
+
+#
+# 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_BF522 is not set
+# CONFIG_BF525 is not set
+CONFIG_BF527=y
+# 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 is not set
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_0_0=y
+# CONFIG_BF_REV_0_1 is not set
+# 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_BF52x=y
+CONFIG_BFIN_SINGLE_CORE=y
+CONFIG_BFIN527_EZKIT=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 is not set
+# 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_MEM_MT48LC32M16A2TG_75=y
+
+#
+# BF527 Specific Configuration
+#
+
+#
+# Alternative Multiplexing Scheme
+#
+# CONFIG_BF527_SPORT0_PORTF is not set
+CONFIG_BF527_SPORT0_PORTG=y
+CONFIG_BF527_SPORT0_TSCLK_PG10=y
+# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set
+# CONFIG_BF527_UART1_PORTF is not set
+CONFIG_BF527_UART1_PORTG=y
+# CONFIG_BF527_NAND_D_PORTF is not set
+CONFIG_BF527_NAND_D_PORTH=y
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_PLL_WAKEUP=7
+CONFIG_IRQ_DMA0_ERROR=7
+CONFIG_IRQ_DMAR0_BLK=7
+CONFIG_IRQ_DMAR1_BLK=7
+CONFIG_IRQ_DMAR0_OVR=7
+CONFIG_IRQ_DMAR1_OVR=7
+CONFIG_IRQ_PPI_ERROR=7
+CONFIG_IRQ_MAC_ERROR=7
+CONFIG_IRQ_SPORT0_ERROR=7
+CONFIG_IRQ_SPORT1_ERROR=7
+CONFIG_IRQ_UART0_ERROR=7
+CONFIG_IRQ_UART1_ERROR=7
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_PPI=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_TWI=10
+CONFIG_IRQ_SPI=10
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+CONFIG_IRQ_OPTSEC=11
+CONFIG_IRQ_CNT=11
+CONFIG_IRQ_MAC_RX=11
+CONFIG_IRQ_PORTH_INTA=11
+CONFIG_IRQ_MAC_TX=11
+CONFIG_IRQ_PORTH_INTB=11
+CONFIG_IRQ_TMR0=12
+CONFIG_IRQ_TMR1=12
+CONFIG_IRQ_TMR2=12
+CONFIG_IRQ_TMR3=12
+CONFIG_IRQ_TMR4=12
+CONFIG_IRQ_TMR5=12
+CONFIG_IRQ_TMR6=12
+CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_PORTG_INTA=12
+CONFIG_IRQ_PORTG_INTB=12
+CONFIG_IRQ_MEM_DMA0=13
+CONFIG_IRQ_MEM_DMA1=13
+CONFIG_IRQ_WATCH=13
+CONFIG_IRQ_PORTF_INTA=13
+CONFIG_IRQ_PORTF_INTB=13
+CONFIG_IRQ_SPI_ERROR=7
+CONFIG_IRQ_NFC_ERROR=7
+CONFIG_IRQ_HDMA_ERROR=7
+CONFIG_IRQ_HDMA=7
+CONFIG_IRQ_USB_EINT=10
+CONFIG_IRQ_USB_INT0=11
+CONFIG_IRQ_USB_INT1=11
+CONFIG_IRQ_USB_INT2=11
+CONFIG_IRQ_USB_DMA=11
+
+#
+# Board customizations
+#
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Clock/PLL Setup
+#
+CONFIG_CLKIN_HZ=25000000
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=600000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133000000
+CONFIG_MIN_SCLK_HZ=27000000
+
+#
+# Kernel Timer/Scheduler
+#
+# 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 Setup
+#
+CONFIG_MEM_SIZE=64
+CONFIG_MEM_ADD_WIDTH=10
+CONFIG_BOOT_LOAD=0x1000
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# 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 is not set
+CONFIG_ARITHMETIC_OPS_L1=y
+CONFIG_ACCESS_OK_L1=y
+# CONFIG_MEMSET_L1 is not set
+# CONFIG_MEMCPY_L1 is not set
+# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set
+# 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_BFIN_ICACHE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+# CONFIG_BFIN_ICACHE_LOCK is not set
+# CONFIG_BFIN_WB is not set
+CONFIG_BFIN_WT=y
+CONFIG_L1_MAX_PIECE=16
+
+#
+# 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=0x5554
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0xFFC0
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# 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
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+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
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# 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_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+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=m
+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=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_MW320D=m
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=m
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_BF5xx=m
+CONFIG_BFIN_FLASH_SIZE=0x400000
+CONFIG_EBIU_FLASH_BASE=0x20000000
+# CONFIG_MTD_UCLINUX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_BFIN=m
+CONFIG_BFIN_NAND_BASE=0x20212000
+CONFIG_BFIN_NAND_CLE=2
+CONFIG_BFIN_NAND_ALE=1
+CONFIG_BFIN_NAND_READY=3
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI 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
+#
+# 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
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# 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
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_SMC91X is not set
+CONFIG_BFIN_MAC=y
+CONFIG_BFIN_MAC_USE_L1=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+CONFIG_BFIN_MAC_RMII=y
+# CONFIG_SMSC911X is not set
+# CONFIG_DM9000 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# 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
+# CONFIG_INPUT_POLLDEV 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_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_BF53X_PFBUTTONS is not set
+# CONFIG_TWI_KEYPAD 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_TWI_LCD is not set
+# CONFIG_AD5304 is not set
+# CONFIG_BF5xx_TEA5764 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_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
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_BLACKFIN_GPIO is not set
+CONFIG_I2C_BLACKFIN_TWI=m
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_AD5252 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCF8575 is not set
+# CONFIG_SENSORS_PCA9543 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF 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
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE 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
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+# 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
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+
+#
+# Platform 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_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_BFIN=y
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# PBX support
+#
+# CONFIG_PBX is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# 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 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_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=m
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN 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=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 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=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_MMRS=y
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
+# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+CONFIG_EARLY_PRINTK=y
+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_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
index e80f3d5..d856988 100644
--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -809,7 +809,14 @@
 # IPMI
 #
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
 CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index 8aeb606..8a4cfb2 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -9,6 +9,7 @@
 	sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
 	fixed_code.o cplbinit.o cacheinit.o reboot.o bfin_gpio.o
 
+obj-$(CONFIG_BFIN_GPTIMERS)          += gptimers.o
 obj-$(CONFIG_MODULES)                += module.o
 obj-$(CONFIG_BFIN_DMA_5XX)           += bfin_dma_5xx.o
 obj-$(CONFIG_DUAL_CORE_TEST_MODULE)  += dualcore_test.o
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index e19164f..503eef4 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -420,6 +420,32 @@
 }
 EXPORT_SYMBOL(get_dma_curr_ycount);
 
+unsigned long get_dma_next_desc_ptr(unsigned int channel)
+{
+	BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+	      && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+	return dma_ch[channel].regs->next_desc_ptr;
+}
+EXPORT_SYMBOL(get_dma_next_desc_ptr);
+
+unsigned long get_dma_curr_desc_ptr(unsigned int channel)
+{
+	BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+	      && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+	return dma_ch[channel].regs->curr_desc_ptr;
+}
+
+unsigned long get_dma_curr_addr(unsigned int channel)
+{
+	BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+	      && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+	return dma_ch[channel].regs->curr_addr_ptr;
+}
+EXPORT_SYMBOL(get_dma_curr_addr);
+
 static void *__dma_memcpy(void *dest, const void *src, size_t size)
 {
 	int direction;	/* 1 - address decrease, 0 - address increase */
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index 3fe0cd4..ce85d4b 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -124,7 +124,7 @@
 };
 #endif
 
-#ifdef BF537_FAMILY
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
 static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
 	(struct gpio_port_t *) PORTFIO,
 	(struct gpio_port_t *) PORTGIO,
@@ -139,6 +139,21 @@
 
 #endif
 
+#ifdef BF527_FAMILY
+static unsigned short *port_mux[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+	(unsigned short *) PORTF_MUX,
+	(unsigned short *) PORTG_MUX,
+	(unsigned short *) PORTH_MUX,
+};
+
+static const
+u8 pmux_offset[][16] =
+	{{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */
+	 { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */
+	 { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */
+	};
+#endif
+
 #ifdef BF561_FAMILY
 static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
 	(struct gpio_port_t *) FIO0_FLAG_D,
@@ -186,6 +201,10 @@
 static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX};
 #endif
 
+#ifdef BF527_FAMILY
+static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB};
+#endif
+
 #ifdef BF561_FAMILY
 static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB};
 #endif
@@ -238,7 +257,7 @@
 		return -EINVAL;
 }
 
-#ifdef BF537_FAMILY
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
 static void port_setup(unsigned short gpio, unsigned short usage)
 {
 	if (!check_gpio(gpio)) {
@@ -354,6 +373,18 @@
 
 	return (pmux >> (2 * gpio_sub_n(portno)) & 0x3);
 }
+#elif defined(BF527_FAMILY)
+inline void portmux_setup(unsigned short portno, unsigned short function)
+{
+	u16 pmux, ident = P_IDENT(portno);
+	u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)];
+
+	pmux = *port_mux[gpio_bank(ident)];
+	pmux &= ~(3 << offset);
+	pmux |= (function & 3) << offset;
+	*port_mux[gpio_bank(ident)] = pmux;
+	SSYNC();
+}
 #else
 # define portmux_setup(...)  do { } while (0)
 #endif
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index 94d7b11..a16cb03 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -160,8 +160,7 @@
 	BUG_ON(direction == DMA_NONE);
 
 	for (i = 0; i < nents; i++, sg++) {
-		sg->dma_address = (dma_addr_t)(page_address(sg->page) +
-					sg->offset);
+		sg->dma_address = (dma_addr_t) sg_virt(sg);
 
 		invalidate_dcache_range(sg_dma_address(sg),
 					sg_dma_address(sg) +
diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c
new file mode 100644
index 0000000..cb7ba9b
--- /dev/null
+++ b/arch/blackfin/kernel/gptimers.c
@@ -0,0 +1,250 @@
+/*
+ * bfin_gptimers.c - derived from bf53x_timers.c
+ *  Driver for General Purpose Timer functions on the Blackfin processor
+ *
+ *  Copyright (C) 2005 John DeHority
+ *  Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
+ *
+ * Licensed under the GPLv2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/blackfin.h>
+#include <asm/gptimers.h>
+
+#ifdef DEBUG
+# define tassert(expr)
+#else
+# define tassert(expr) \
+	if (!(expr)) \
+		printk(KERN_DEBUG "%s:%s:%i: Assertion failed: " #expr "\n", \
+			__FILE__, __func__, __LINE__);
+#endif
+
+#define BFIN_TIMER_NUM_GROUP  (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1)
+
+typedef struct {
+	uint16_t config;
+	uint16_t __pad;
+	uint32_t counter;
+	uint32_t period;
+	uint32_t width;
+} GPTIMER_timer_regs;
+
+typedef struct {
+	uint16_t enable;
+	uint16_t __pad0;
+	uint16_t disable;
+	uint16_t __pad1;
+	uint32_t status;
+} GPTIMER_group_regs;
+
+static volatile GPTIMER_timer_regs *const timer_regs[MAX_BLACKFIN_GPTIMERS] =
+{
+	(GPTIMER_timer_regs *)TIMER0_CONFIG,
+	(GPTIMER_timer_regs *)TIMER1_CONFIG,
+	(GPTIMER_timer_regs *)TIMER2_CONFIG,
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+	(GPTIMER_timer_regs *)TIMER3_CONFIG,
+	(GPTIMER_timer_regs *)TIMER4_CONFIG,
+	(GPTIMER_timer_regs *)TIMER5_CONFIG,
+	(GPTIMER_timer_regs *)TIMER6_CONFIG,
+	(GPTIMER_timer_regs *)TIMER7_CONFIG,
+#endif
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+	(GPTIMER_timer_regs *)TIMER8_CONFIG,
+	(GPTIMER_timer_regs *)TIMER9_CONFIG,
+	(GPTIMER_timer_regs *)TIMER10_CONFIG,
+	(GPTIMER_timer_regs *)TIMER11_CONFIG,
+#endif
+};
+
+static volatile GPTIMER_group_regs *const group_regs[BFIN_TIMER_NUM_GROUP] =
+{
+	(GPTIMER_group_regs *)TIMER0_GROUP_REG,
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+	(GPTIMER_group_regs *)TIMER8_GROUP_REG,
+#endif
+};
+
+static uint32_t const dis_mask[MAX_BLACKFIN_GPTIMERS] =
+{
+	TIMER_STATUS_TRUN0,
+	TIMER_STATUS_TRUN1,
+	TIMER_STATUS_TRUN2,
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+	TIMER_STATUS_TRUN3,
+	TIMER_STATUS_TRUN4,
+	TIMER_STATUS_TRUN5,
+	TIMER_STATUS_TRUN6,
+	TIMER_STATUS_TRUN7,
+#endif
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+	TIMER_STATUS_TRUN8,
+	TIMER_STATUS_TRUN9,
+	TIMER_STATUS_TRUN10,
+	TIMER_STATUS_TRUN11,
+#endif
+};
+
+static uint32_t const irq_mask[MAX_BLACKFIN_GPTIMERS] =
+{
+	TIMER_STATUS_TIMIL0,
+	TIMER_STATUS_TIMIL1,
+	TIMER_STATUS_TIMIL2,
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+	TIMER_STATUS_TIMIL3,
+	TIMER_STATUS_TIMIL4,
+	TIMER_STATUS_TIMIL5,
+	TIMER_STATUS_TIMIL6,
+	TIMER_STATUS_TIMIL7,
+#endif
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+	TIMER_STATUS_TIMIL8,
+	TIMER_STATUS_TIMIL9,
+	TIMER_STATUS_TIMIL10,
+	TIMER_STATUS_TIMIL11,
+#endif
+};
+
+void set_gptimer_pwidth(int timer_id, uint32_t value)
+{
+	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+	timer_regs[timer_id]->width = value;
+	SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_pwidth);
+
+uint32_t get_gptimer_pwidth(int timer_id)
+{
+	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+	return timer_regs[timer_id]->width;
+}
+EXPORT_SYMBOL(get_gptimer_pwidth);
+
+void set_gptimer_period(int timer_id, uint32_t period)
+{
+	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+	timer_regs[timer_id]->period = period;
+	SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_period);
+
+uint32_t get_gptimer_period(int timer_id)
+{
+	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+	return timer_regs[timer_id]->period;
+}
+EXPORT_SYMBOL(get_gptimer_period);
+
+uint32_t get_gptimer_count(int timer_id)
+{
+	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+	return timer_regs[timer_id]->counter;
+}
+EXPORT_SYMBOL(get_gptimer_count);
+
+uint32_t get_gptimer_status(int group)
+{
+	tassert(group < BFIN_TIMER_NUM_GROUP);
+	return group_regs[group]->status;
+}
+EXPORT_SYMBOL(get_gptimer_status);
+
+void set_gptimer_status(int group, uint32_t value)
+{
+	tassert(group < BFIN_TIMER_NUM_GROUP);
+	group_regs[group]->status = value;
+	SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_status);
+
+uint16_t get_gptimer_intr(int timer_id)
+{
+	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+	return (group_regs[BFIN_TIMER_OCTET(timer_id)]->status & irq_mask[timer_id]) ? 1 : 0;
+}
+EXPORT_SYMBOL(get_gptimer_intr);
+
+void clear_gptimer_intr(int timer_id)
+{
+	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+	group_regs[BFIN_TIMER_OCTET(timer_id)]->status = irq_mask[timer_id];
+}
+EXPORT_SYMBOL(clear_gptimer_intr);
+
+void set_gptimer_config(int timer_id, uint16_t config)
+{
+	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+	timer_regs[timer_id]->config = config;
+	SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_config);
+
+uint16_t get_gptimer_config(int timer_id)
+{
+	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+	return timer_regs[timer_id]->config;
+}
+EXPORT_SYMBOL(get_gptimer_config);
+
+void enable_gptimers(uint16_t mask)
+{
+	int i;
+	tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0);
+	for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) {
+		group_regs[i]->enable = mask & 0xFF;
+		mask >>= 8;
+	}
+	SSYNC();
+}
+EXPORT_SYMBOL(enable_gptimers);
+
+void disable_gptimers(uint16_t mask)
+{
+	int i;
+	uint16_t m = mask;
+	tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0);
+	for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) {
+		group_regs[i]->disable = m & 0xFF;
+		m >>= 8;
+	}
+	for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i)
+		if (mask & (1 << i))
+			group_regs[BFIN_TIMER_OCTET(i)]->status |= dis_mask[i];
+	SSYNC();
+}
+EXPORT_SYMBOL(disable_gptimers);
+
+void set_gptimer_pulse_hi(int timer_id)
+{
+	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+	timer_regs[timer_id]->config |= TIMER_PULSE_HI;
+	SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_pulse_hi);
+
+void clear_gptimer_pulse_hi(int timer_id)
+{
+	tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+	timer_regs[timer_id]->config &= ~TIMER_PULSE_HI;
+	SSYNC();
+}
+EXPORT_SYMBOL(clear_gptimer_pulse_hi);
+
+uint16_t get_enabled_gptimers(void)
+{
+	int i;
+	uint16_t result = 0;
+	for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i)
+		result |= (group_regs[i]->enable << (i << 3));
+	return result;
+}
+EXPORT_SYMBOL(get_enabled_gptimers);
+
+MODULE_AUTHOR("Axel Weiss (awe@aglaia-gmbh.de)");
+MODULE_DESCRIPTION("Blackfin General Purpose Timers API");
+MODULE_LICENSE("GPL");
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c
index 356078e..ae28aac 100644
--- a/arch/blackfin/kernel/reboot.c
+++ b/arch/blackfin/kernel/reboot.c
@@ -11,7 +11,7 @@
 #include <asm/reboot.h>
 #include <asm/system.h>
 
-#if defined(BF537_FAMILY) || defined(BF533_FAMILY)
+#if defined(BF537_FAMILY) || defined(BF533_FAMILY) || defined(BF527_FAMILY)
 #define SYSCR_VAL 	0x0
 #elif defined(BF561_FAMILY)
 #define SYSCR_VAL 	0x20
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 8dcd76e..f1b059e 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -459,7 +459,7 @@
 	return vco;
 }
 
-/*Get the Core clock*/
+/* Get the Core clock */
 u_long get_cclk(void)
 {
 	u_long csel, ssel;
@@ -493,12 +493,24 @@
 }
 EXPORT_SYMBOL(get_sclk);
 
+unsigned long sclk_to_usecs(unsigned long sclk)
+{
+	return (USEC_PER_SEC * (u64)sclk) / get_sclk();
+}
+EXPORT_SYMBOL(sclk_to_usecs);
+
+unsigned long usecs_to_sclk(unsigned long usecs)
+{
+	return (get_sclk() * (u64)usecs) / USEC_PER_SEC;
+}
+EXPORT_SYMBOL(usecs_to_sclk);
+
 /*
  *	Get CPU information for use by the procfs.
  */
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
-	char *cpu, *mmu, *fpu, *name;
+	char *cpu, *mmu, *fpu, *vendor, *cache;
 	uint32_t revid;
 
 	u_long cclk = 0, sclk = 0;
@@ -508,70 +520,83 @@
 	mmu = "none";
 	fpu = "none";
 	revid = bfin_revid();
-	name = bfin_board_name;
 
 	cclk = get_cclk();
 	sclk = get_sclk();
 
-	seq_printf(m, "CPU:\t\tADSP-%s Rev. 0.%d\n"
-		   "MMU:\t\t%s\n"
-		   "FPU:\t\t%s\n"
-		   "Core Clock:\t%9lu Hz\n"
-		   "System Clock:\t%9lu Hz\n"
-		   "BogoMips:\t%lu.%02lu\n"
-		   "Calibration:\t%lu loops\n",
-		   cpu, revid, mmu, fpu,
-		   cclk,
-		   sclk,
-		   (loops_per_jiffy * HZ) / 500000,
-		   ((loops_per_jiffy * HZ) / 5000) % 100,
-		   (loops_per_jiffy * HZ));
-	seq_printf(m, "Board Name:\t%s\n", name);
-	seq_printf(m, "Board Memory:\t%ld MB\n", physical_mem_end >> 20);
-	seq_printf(m, "Kernel Memory:\t%ld MB\n", (unsigned long)_ramend >> 20);
-	if (bfin_read_IMEM_CONTROL() & (ENICPLB | IMC))
-		seq_printf(m, "I-CACHE:\tON\n");
-	else
-		seq_printf(m, "I-CACHE:\tOFF\n");
-	if ((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE))
-		seq_printf(m, "D-CACHE:\tON"
-#if defined CONFIG_BFIN_WB
-			   " (write-back)"
-#elif defined CONFIG_BFIN_WT
-			   " (write-through)"
-#endif
-			   "\n");
-	else
-		seq_printf(m, "D-CACHE:\tOFF\n");
+	switch (bfin_read_CHIPID() & CHIPID_MANUFACTURE) {
+	case 0xca:
+		vendor = "Analog Devices";
+		break;
+	default:
+		vendor = "unknown";
+		break;
+	}
 
+	seq_printf(m, "processor\t: %d\n"
+		"vendor_id\t: %s\n"
+		"cpu family\t: 0x%x\n"
+		"model name\t: ADSP-%s %lu(MHz CCLK) %lu(MHz SCLK)\n"
+		"stepping\t: %d\n",
+		0,
+		vendor,
+		(bfin_read_CHIPID() & CHIPID_FAMILY),
+		cpu, cclk/1000000, sclk/1000000,
+		revid);
 
+	seq_printf(m, "cpu MHz\t\t: %lu.%03lu/%lu.%03lu\n",
+		cclk/1000000, cclk%1000000,
+		sclk/1000000, sclk%1000000);
+	seq_printf(m, "bogomips\t: %lu.%02lu\n"
+		"Calibration\t: %lu loops\n",
+		(loops_per_jiffy * HZ) / 500000,
+		((loops_per_jiffy * HZ) / 5000) % 100,
+		(loops_per_jiffy * HZ));
+
+	/* Check Cache configutation */
 	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");
+		cache = "dbank-A/B\t: cache/sram";
 		dcache_size = 16;
 		dsup_banks = 1;
 		break;
 	case ACACHE_BCACHE:
-		seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
+		cache = "dbank-A/B\t: cache/cache";
 		dcache_size = 32;
 		dsup_banks = 2;
 		break;
 	case ASRAM_BSRAM:
-		seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
+		cache = "dbank-A/B\t: sram/sram";
 		dcache_size = 0;
 		dsup_banks = 0;
 		break;
 	default:
+		cache = "unknown";
+		dcache_size = 0;
+		dsup_banks = 0;
 		break;
 	}
 
+	/* Is it turned on? */
+	if (!((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE)))
+		dcache_size = 0;
 
-	seq_printf(m, "I-CACHE Size:\t%dKB\n", BFIN_ICACHESIZE / 1024);
-	seq_printf(m, "D-CACHE Size:\t%dKB\n", dcache_size);
-	seq_printf(m, "I-CACHE Setup:\t%d Sub-banks/%d Ways, %d Lines/Way\n",
+	seq_printf(m, "cache size\t: %d KB(L1 icache) "
+		"%d KB(L1 dcache-%s) %d KB(L2 cache)\n",
+		BFIN_ICACHESIZE / 1024, dcache_size,
+#if defined CONFIG_BFIN_WB
+		"wb"
+#elif defined CONFIG_BFIN_WT
+		"wt"
+#endif
+		"", 0);
+
+	seq_printf(m, "%s\n", cache);
+
+	seq_printf(m, "icache setup\t: %d Sub-banks/%d Ways, %d Lines/Way\n",
 		   BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES);
 	seq_printf(m,
-		   "D-CACHE Setup:\t%d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n",
+		   "dcache setup\t: %d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n",
 		   dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS,
 		   BFIN_DLINES);
 #ifdef CONFIG_BFIN_ICACHE_LOCK
@@ -625,6 +650,15 @@
 		seq_printf(m, "No Ways are locked\n");
 	}
 #endif
+
+	seq_printf(m, "board name\t: %s\n", bfin_board_name);
+	seq_printf(m, "board memory\t: %ld kB (0x%p -> 0x%p)\n",
+		 physical_mem_end >> 10, (void *)0, (void *)physical_mem_end);
+	seq_printf(m, "kernel memory\t: %d kB (0x%p -> 0x%p)\n",
+		((int)memory_end - (int)_stext) >> 10,
+		_stext,
+		(void *)memory_end);
+
 	return 0;
 }
 
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 8823e9a..afd044e 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -118,12 +118,14 @@
 					offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
 
 				write_unlock_irq(&tasklist_lock);
+				mmput(mm);
 				return printk("<0x%p> [ %s + 0x%lx ]",
 				              (void *)address, name, offset);
 			}
 
 			vml = vml->next;
 		}
+		mmput(mm);
 	}
 	write_unlock_irq(&tasklist_lock);
 
diff --git a/arch/blackfin/lib/Makefile b/arch/blackfin/lib/Makefile
index 635288f..bfdad52 100644
--- a/arch/blackfin/lib/Makefile
+++ b/arch/blackfin/lib/Makefile
@@ -4,7 +4,7 @@
 
 lib-y := \
 	ashldi3.o ashrdi3.o lshrdi3.o \
-	muldi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \
+	muldi3.o divsi3.o udivsi3.o udivdi3.o modsi3.o umodsi3.o \
 	checksum.o memcpy.o memset.o memcmp.o memchr.o memmove.o \
 	strcmp.o strcpy.o strncmp.o strncpy.o \
 	umulsi3_highpart.o smulsi3_highpart.o \
diff --git a/arch/blackfin/lib/udivdi3.S b/arch/blackfin/lib/udivdi3.S
new file mode 100644
index 0000000..ad1ebee
--- /dev/null
+++ b/arch/blackfin/lib/udivdi3.S
@@ -0,0 +1,375 @@
+/*
+ * udivdi3.S - unsigned long long division
+ *
+ * Copyright 2003-2007 Analog Devices Inc.
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPLv2 or later.
+ */
+
+#include <linux/linkage.h>
+
+#define CARRY AC0
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+
+ENTRY(___udivdi3)
+   R3 = [SP + 12];
+   [--SP] = (R7:4, P5:3);
+
+   /* Attempt to use divide primitive first; these will handle
+   **  most cases, and they're quick - avoids stalls incurred by
+   ** testing for identities.
+   */
+
+   R4 = R2 | R3;
+   CC = R4 == 0;
+   IF CC JUMP .LDIV_BY_ZERO;
+
+   R4.H = 0x8000;
+   R4 >>>= 16;                  // R4 now 0xFFFF8000
+   R5 = R0 | R2;                // If either dividend or
+   R4 = R5 & R4;                // divisor have bits in
+   CC = R4;                     // top half or low half's sign
+   IF CC JUMP .LIDENTS;          // bit, skip builtins.
+   R4 = R1 | R3;                // Also check top halves
+   CC = R4;
+   IF CC JUMP .LIDENTS;
+
+   /* Can use the builtins. */
+
+   AQ = CC;                     // Clear AQ (CC==0)
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   DIVQ(R0, R2);
+   R0 = R0.L (Z);
+   R1 = 0;
+   (R7:4, P5:3) = [SP++];
+   RTS;
+
+.LIDENTS:
+   /* Test for common identities. Value to be returned is
+   ** placed in R6,R7.
+   */
+                                // Check for 0/y, return 0
+   R4 = R0 | R1;
+   CC = R4 == 0;
+   IF CC JUMP .LRETURN_R0;
+
+                                // Check for x/x, return 1
+   R6 = R0 - R2;                // If x == y, then both R6 and R7 will be zero
+   R7 = R1 - R3;
+   R4 = R6 | R7;                // making R4 zero.
+   R6 += 1;                     // which would now make R6:R7==1.
+   CC = R4 == 0;
+   IF CC JUMP .LRETURN_IDENT;
+
+                                // Check for x/1, return x
+   R6 = R0;
+   R7 = R1;
+   CC = R3 == 0;
+   IF !CC JUMP .Lnexttest;
+   CC = R2 == 1;
+   IF CC JUMP .LRETURN_IDENT;
+
+.Lnexttest:
+   R4.L = ONES R2;              // check for div by power of two which
+   R5.L = ONES R3;              // can be done using a shift
+   R6 = PACK (R5.L, R4.L);
+   CC = R6 == 1;
+   IF CC JUMP .Lpower_of_two_upper_zero;
+   R6 = PACK (R4.L, R5.L);
+   CC = R6 == 1;
+   IF CC JUMP .Lpower_of_two_lower_zero;
+
+                                // Check for x < y, return 0
+   R6 = 0;
+   R7 = R6;
+   CC = R1 < R3 (IU);
+   IF CC JUMP .LRETURN_IDENT;
+   CC = R1 == R3;
+   IF !CC JUMP .Lno_idents;
+   CC = R0 < R2 (IU);
+   IF CC JUMP .LRETURN_IDENT;
+
+.Lno_idents:                    // Idents don't match. Go for the full operation
+
+
+   // If X, or X and Y have high bit set, it'll affect the
+   // results, so shift right one to stop this. Note: we've already
+   // checked that X >= Y, so Y's msb won't be set unless X's
+   // is.
+
+   R4 = 0;
+   CC = R1 < 0;
+   IF !CC JUMP .Lx_msb_clear;
+   CC = !CC;                   // 1 -> 0;
+   R1 = ROT R1 BY -1;          // Shift X >> 1
+   R0 = ROT R0 BY -1;          // lsb -> CC
+   BITSET(R4,31);              // to record only x msb was set
+   CC = R3 < 0;
+   IF !CC JUMP .Ly_msb_clear;
+   CC = !CC;
+   R3 = ROT R3 BY -1;          // Shift Y >> 1
+   R2 = ROT R2 BY -1;
+   BITCLR(R4,31);              // clear bit to record only x msb was set
+
+.Ly_msb_clear:
+.Lx_msb_clear:
+   // Bit 31 in R4 indicates X msb set, but Y msb wasn't, and no bits
+   // were lost, so we should shift result left by one.
+
+   [--SP] = R4;                // save for later
+
+   // In the loop that follows, each iteration we add
+   // either Y' or -Y' to the Remainder. We compute the
+   // negated Y', and store, for convenience. Y' goes
+   // into P0:P1, while -Y' goes into P2:P3.
+
+   P0 = R2;
+   P1 = R3;
+   R2 = -R2;
+   CC = CARRY;
+   CC = !CC;
+   R4 = CC;
+   R3 = -R3;
+   R3 = R3 - R4;
+
+   R6 = 0;                     // remainder = 0
+   R7 = R6;
+
+   [--SP] = R2; P2 = SP;
+   [--SP] = R3; P3 = SP;
+   [--SP] = R6; P5 = SP;       // AQ = 0
+   [--SP] = P1;
+
+   /* In the loop that follows, we use the following
+   ** register assignments:
+   ** R0,R1 X, workspace
+   ** R2,R3 Y, workspace
+   ** R4,R5 partial Div
+   ** R6,R7 partial remainder
+   ** P5 AQ
+   ** The remainder and div form a 128-bit number, with
+   ** the remainder in the high 64-bits.
+   */
+   R4 = R0;                    // Div = X'
+   R5 = R1;
+   R3 = 0;
+
+   P4 = 64;                    // Iterate once per bit
+   LSETUP(.LULST,.LULEND) LC0 = P4;
+.LULST:
+        /* Shift Div and remainder up by one. The bit shifted
+        ** out of the top of the quotient is shifted into the bottom
+        ** of the remainder.
+        */
+        CC = R3;
+        R4 = ROT R4 BY 1;
+        R5 = ROT R5 BY 1 ||        // low q to high q
+             R2 = [P5];            // load saved AQ
+        R6 = ROT R6 BY 1 ||        // high q to low r
+             R0 = [P2];            // load -Y'
+        R7 = ROT R7 BY 1 ||        // low r to high r
+             R1 = [P3];
+
+                                   // Assume add -Y'
+        CC = R2 < 0;               // But if AQ is set...
+        IF CC R0 = P0;             // then add Y' instead
+        IF CC R1 = P1;
+
+        R6 = R6 + R0;              // Rem += (Y' or -Y')
+        CC = CARRY;
+        R0 = CC;
+        R7 = R7 + R1;
+        R7 = R7 + R0 (NS) ||
+             R1 = [SP];
+                                   // Set the next AQ bit
+        R1 = R7 ^ R1;              // from Remainder and Y'
+        R1 = R1 >> 31 ||           // Negate AQ's value, and
+             [P5] = R1;            // save next AQ
+        BITTGL(R1, 0);             // add neg AQ  to the Div
+.LULEND: R4 = R4 + R1;
+
+   R6 = [SP + 16];
+
+   R0 = R4;
+   R1 = R5;
+   CC = BITTST(R6,30);         // Just set CC=0
+   R4 = ROT R0 BY 1;           // but if we had to shift X,
+   R5 = ROT R1 BY 1;           // and didn't shift any bits out,
+   CC = BITTST(R6,31);         // then the result will be half as
+   IF CC R0 = R4;              // much as required, so shift left
+   IF CC R1 = R5;              // one space.
+
+   SP += 20;
+   (R7:4, P5:3) = [SP++];
+   RTS;
+
+.Lpower_of_two:
+   /* Y has a single bit set, which means it's a power of two.
+   ** That means we can perform the division just by shifting
+   ** X to the right the appropriate number of bits
+   */
+
+   /* signbits returns the number of sign bits, minus one.
+   ** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need
+   ** to shift right n-signbits spaces. It also means 0x80000000
+   ** is a special case, because that *also* gives a signbits of 0
+   */
+.Lpower_of_two_lower_zero:
+   R7 = 0;
+   R6 = R1 >> 31;
+   CC = R3 < 0;
+   IF CC JUMP .LRETURN_IDENT;
+
+   R2.L = SIGNBITS R3;
+   R2 = R2.L (Z);
+   R2 += -62;
+   (R7:4, P5:3) = [SP++];
+   JUMP ___lshftli;
+
+.Lpower_of_two_upper_zero:
+   CC = R2 < 0;
+   IF CC JUMP .Lmaxint_shift;
+
+   R2.L = SIGNBITS R2;
+   R2 = R2.L (Z);
+   R2 += -30;
+   (R7:4, P5:3) = [SP++];
+   JUMP ___lshftli;
+
+.Lmaxint_shift:
+   R2 = -31;
+   (R7:4, P5:3) = [SP++];
+   JUMP ___lshftli;
+
+.LRETURN_IDENT:
+   R0 = R6;
+   R1 = R7;
+.LRETURN_R0:
+   (R7:4, P5:3) = [SP++];
+   RTS;
+.LDIV_BY_ZERO:
+   R0 = ~R2;
+   R1 = R0;
+   (R7:4, P5:3) = [SP++];
+   RTS;
+
+ENDPROC(___udivdi3)
+
+
+ENTRY(___lshftli)
+	CC = R2 == 0;
+	IF CC JUMP .Lfinished;	// nothing to do
+	CC = R2 < 0;
+	IF CC JUMP .Lrshift;
+	R3 = 64;
+	CC = R2 < R3;
+	IF !CC JUMP .Lretzero;
+
+	// We're shifting left, and it's less than 64 bits, so
+	// a valid result will be returned.
+
+	R3 >>= 1;	// R3 now 32
+	CC = R2 < R3;
+
+	IF !CC JUMP .Lzerohalf;
+
+	// We're shifting left, between 1 and 31 bits, which means
+	// some of the low half will be shifted into the high half.
+	// Work out how much.
+
+	R3 = R3 - R2;
+
+	// Save that much data from the bottom half.
+
+	P1 = R7;
+	R7 = R0;
+	R7 >>= R3;
+
+	// Adjust both parts of the parameter.
+
+	R0 <<= R2;
+	R1 <<= R2;
+
+	// And include the bits moved across.
+
+	R1 = R1 | R7;
+	R7 = P1;
+	RTS;
+
+.Lzerohalf:
+	// We're shifting left, between 32 and 63 bits, so the
+	// bottom half will become zero, and the top half will
+	// lose some bits. How many?
+
+	R2 = R2 - R3;	// N - 32
+	R1 = LSHIFT R0 BY R2.L;
+	R0 = R0 - R0;
+	RTS;
+
+.Lretzero:
+	R0 = R0 - R0;
+	R1 = R0;
+.Lfinished:
+	RTS;
+
+.Lrshift:
+	// We're shifting right, but by how much?
+	R2 = -R2;
+	R3 = 64;
+	CC = R2 < R3;
+	IF !CC JUMP .Lretzero;
+
+	// Shifting right less than 64 bits, so some result bits will
+	// be retained.
+
+	R3 >>= 1;	// R3 now 32
+	CC = R2 < R3;
+	IF !CC JUMP .Lsignhalf;
+
+	// Shifting right between 1 and 31 bits, so need to copy
+	// data across words.
+
+	P1 = R7;
+	R3 = R3 - R2;
+	R7 = R1;
+	R7 <<= R3;
+	R1 >>= R2;
+	R0 >>= R2;
+	R0 = R7 | R0;
+	R7 = P1;
+	RTS;
+
+.Lsignhalf:
+	// Shifting right between 32 and 63 bits, so the top half
+	// will become all zero-bits, and the bottom half is some
+	// of the top half. But how much?
+
+	R2 = R2 - R3;
+	R0 = R1;
+	R0 >>= R2;
+	R1 = 0;
+	RTS;
+
+ENDPROC(___lshftli)
diff --git a/arch/blackfin/mach-bf527/Kconfig b/arch/blackfin/mach-bf527/Kconfig
new file mode 100644
index 0000000..50321f7
--- /dev/null
+++ b/arch/blackfin/mach-bf527/Kconfig
@@ -0,0 +1,251 @@
+if (BF52x)
+
+menu "BF527 Specific Configuration"
+
+comment "Alternative Multiplexing Scheme"
+
+choice
+	prompt "SPORT0"
+	default BF527_SPORT0_PORTG
+	help
+	  Select PORT used for SPORT0. See Hardware Reference Manual
+
+config BF527_SPORT0_PORTF
+	bool "PORT F"
+	help
+	  PORT F
+
+config BF527_SPORT0_PORTG
+	bool "PORT G"
+	help
+	  PORT G
+endchoice
+
+choice
+	prompt "SPORT0 TSCLK Location"
+	depends on BF527_SPORT0_PORTG
+	default BF527_SPORT0_TSCLK_PG10
+	help
+	  Select PIN used for SPORT0_TSCLK. See Hardware Reference Manual
+
+config BF527_SPORT0_TSCLK_PG10
+	bool "PORT PG10"
+	help
+	  PORT PG10
+
+config BF527_SPORT0_TSCLK_PG14
+	bool "PORT PG14"
+	help
+	  PORT PG14
+endchoice
+
+choice
+	prompt "UART1"
+	default BF527_UART1_PORTG
+	help
+	  Select PORT used for UART1. See Hardware Reference Manual
+
+config BF527_UART1_PORTF
+	bool "PORT F"
+	help
+	  PORT F
+
+config BF527_UART1_PORTG
+	bool "PORT G"
+	help
+	  PORT G
+endchoice
+
+choice
+	prompt "NAND (NFC) Data"
+	default BF527_NAND_D_PORTH
+	help
+	  Select PORT used for NAND Data Bus. See Hardware Reference Manual
+
+config BF527_NAND_D_PORTF
+	bool "PORT F"
+	help
+	  PORT F
+
+config BF527_NAND_D_PORTH
+	bool "PORT H"
+	help
+	  PORT H
+endchoice
+
+comment "Interrupt Priority Assignment"
+menu "Priority"
+
+config IRQ_PLL_WAKEUP
+	int "IRQ_PLL_WAKEUP"
+	default 7
+config IRQ_DMA0_ERROR
+	int "IRQ_DMA0_ERROR"
+	default 7
+config IRQ_DMAR0_BLK
+	int "IRQ_DMAR0_BLK"
+	default 7
+config IRQ_DMAR1_BLK
+	int "IRQ_DMAR1_BLK"
+	default 7
+config IRQ_DMAR0_OVR
+	int "IRQ_DMAR0_OVR"
+	default 7
+config IRQ_DMAR1_OVR
+	int "IRQ_DMAR1_OVR"
+	default 7
+config IRQ_PPI_ERROR
+	int "IRQ_PPI_ERROR"
+	default 7
+config IRQ_MAC_ERROR
+	int "IRQ_MAC_ERROR"
+	default 7
+config IRQ_SPORT0_ERROR
+	int "IRQ_SPORT0_ERROR"
+	default 7
+config IRQ_SPORT1_ERROR
+	int "IRQ_SPORT1_ERROR"
+	default 7
+config IRQ_UART0_ERROR
+	int "IRQ_UART0_ERROR"
+	default 7
+config IRQ_UART1_ERROR
+	int "IRQ_UART1_ERROR"
+	default 7
+config IRQ_RTC
+	int "IRQ_RTC"
+	default 8
+config IRQ_PPI
+	int "IRQ_PPI"
+	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_TWI
+	int "IRQ_TWI"
+	default 10
+config IRQ_SPI
+	int "IRQ_SPI"
+	default 10
+config IRQ_UART0_RX
+	int "IRQ_UART0_RX"
+	default 10
+config IRQ_UART0_TX
+	int "IRQ_UART0_TX"
+	default 10
+config IRQ_UART1_RX
+	int "IRQ_UART1_RX"
+	default 10
+config IRQ_UART1_TX
+	int "IRQ_UART1_TX"
+	default 10
+config IRQ_OPTSEC
+	int "IRQ_OPTSEC"
+	default 11
+config IRQ_CNT
+	int "IRQ_CNT"
+	default 11
+config IRQ_MAC_RX
+	int "IRQ_MAC_RX"
+	default 11
+config IRQ_PORTH_INTA
+	int "IRQ_PORTH_INTA"
+	default 11
+config IRQ_MAC_TX
+	int "IRQ_MAC_TX/NFC"
+	default 11
+config IRQ_PORTH_INTB
+	int "IRQ_PORTH_INTB"
+	default 11
+config IRQ_TMR0
+	int "IRQ_TMR0"
+	default 12
+config IRQ_TMR1
+	int "IRQ_TMR1"
+	default 12
+config IRQ_TMR2
+	int "IRQ_TMR2"
+	default 12
+config IRQ_TMR3
+	int "IRQ_TMR3"
+	default 12
+config IRQ_TMR4
+	int "IRQ_TMR4"
+	default 12
+config IRQ_TMR5
+	int "IRQ_TMR5"
+	default 12
+config IRQ_TMR6
+	int "IRQ_TMR6"
+	default 12
+config IRQ_TMR7
+	int "IRQ_TMR7"
+	default 12
+config IRQ_PORTG_INTA
+	int "IRQ_PORTG_INTA"
+	default 12
+config IRQ_PORTG_INTB
+	int "IRQ_PORTG_INTB"
+	default 12
+config IRQ_MEM_DMA0
+	int "IRQ_MEM_DMA0"
+	default 13
+config IRQ_MEM_DMA1
+	int "IRQ_MEM_DMA1"
+	default 13
+config IRQ_WATCH
+	int "IRQ_WATCH"
+	default 13
+config IRQ_PORTF_INTA
+	int "IRQ_PORTF_INTA"
+	default 13
+config IRQ_PORTF_INTB
+	int "IRQ_PORTF_INTB"
+	default 13
+config IRQ_SPI_ERROR
+	int "IRQ_SPI_ERROR"
+	default 7
+config IRQ_NFC_ERROR
+	int "IRQ_NFC_ERROR"
+	default 7
+config IRQ_HDMA_ERROR
+	int "IRQ_HDMA_ERROR"
+	default 7
+config IRQ_HDMA
+	int "IRQ_HDMA"
+	default 7
+config IRQ_USB_EINT
+	int "IRQ_USB_EINT"
+	default 10
+config IRQ_USB_INT0
+	int "IRQ_USB_INT0"
+	default 10
+config IRQ_USB_INT1
+	int "IRQ_USB_INT1"
+	default 10
+config IRQ_USB_INT2
+	int "IRQ_USB_INT2"
+	default 10
+config IRQ_USB_DMA
+	int "IRQ_USB_DMA"
+	default 10
+
+	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
+
+endmenu
+
+endif
diff --git a/arch/blackfin/mach-bf527/Makefile b/arch/blackfin/mach-bf527/Makefile
new file mode 100644
index 0000000..9f99f5d
--- /dev/null
+++ b/arch/blackfin/mach-bf527/Makefile
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf527/Makefile
+#
+
+extra-y := head.o
+
+obj-y := ints-priority.o dma.o
+
+obj-$(CONFIG_CPU_FREQ)   += cpu.o
diff --git a/arch/blackfin/mach-bf527/boards/Makefile b/arch/blackfin/mach-bf527/boards/Makefile
new file mode 100644
index 0000000..912ac8e
--- /dev/null
+++ b/arch/blackfin/mach-bf527/boards/Makefile
@@ -0,0 +1,7 @@
+#
+# arch/blackfin/mach-bf532/boards/Makefile
+#
+
+obj-y					+= eth_mac.o
+obj-$(CONFIG_BFIN527_EZKIT)		+= ezkit.o
+
diff --git a/arch/blackfin/mach-bf527/boards/eth_mac.c b/arch/blackfin/mach-bf527/boards/eth_mac.c
new file mode 100644
index 0000000..a725cc8
--- /dev/null
+++ b/arch/blackfin/mach-bf527/boards/eth_mac.c
@@ -0,0 +1,50 @@
+/*
+ *  arch/blackfin/mach-bf537/board/eth_mac.c
+ *
+ *  Copyright (C) 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/module.h>
+#include <asm/blackfin.h>
+
+#if	defined(CONFIG_GENERIC_BOARD) || defined(CONFIG_BFIN537_STAMP)
+
+/*
+ * Currently the MAC address is saved in Flash by U-Boot
+ */
+#define FLASH_MAC	0x203f0000
+
+void get_bf537_ether_addr(char *addr)
+{
+	unsigned int flash_mac = (unsigned int) FLASH_MAC;
+	*(u32 *)(&(addr[0])) = bfin_read32(flash_mac);
+	flash_mac += 4;
+	*(u16 *)(&(addr[4])) = bfin_read16(flash_mac);
+}
+
+#else
+
+/*
+ * Provide MAC address function for other specific board setting
+ */
+void get_bf537_ether_addr(char *addr)
+{
+	printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n", __FILE__);
+}
+
+#endif
+
+EXPORT_SYMBOL(get_bf537_ether_addr);
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
new file mode 100644
index 0000000..3e884f3
--- /dev/null
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -0,0 +1,737 @@
+/*
+ * File:         arch/blackfin/mach-bf527/boards/ezkit.c
+ * Based on:     arch/blackfin/mach-bf537/boards/stamp.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>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb_isp1362.h>
+#endif
+#include <linux/pata_platform.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/usb_sl811.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/reboot.h>
+#include <linux/spi/ad7877.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "ADDS-BF527-EZKIT";
+
+/*
+ *  Driver needs to know address, irq and flag pin.
+ */
+
+#define ISP1761_BASE       0x203C0000
+#define ISP1761_IRQ        IRQ_PF7
+
+#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,
+	},
+};
+
+static struct platform_device bfin_isp1761_device = {
+	.name           = "isp1761",
+	.id             = 0,
+	.num_resources  = ARRAY_SIZE(bfin_isp1761_resources),
+	.resource       = bfin_isp1761_resources,
+};
+
+static struct platform_device *bfin_isp1761_devices[] = {
+	&bfin_isp1761_device,
+};
+
+int __init bfin_isp1761_init(void)
+{
+	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);
+
+	return platform_add_devices(bfin_isp1761_devices, num_devices);
+}
+
+void __exit bfin_isp1761_exit(void)
+{
+	platform_device_unregister(&bfin_isp1761_device);
+}
+
+arch_initcall(bfin_isp1761_init);
+#endif
+
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+static struct resource bfin_pcmcia_cf_resources[] = {
+	{
+		.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,
+	},
+};
+
+static struct platform_device bfin_pcmcia_cf_device = {
+	.name = "bfin_cf_pcmcia",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources),
+	.resource = bfin_pcmcia_cf_resources,
+};
+#endif
+
+#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_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+	{
+		.name = "smc91x-regs",
+		.start = 0x20300300,
+		.end = 0x20300300 + 16,
+		.flags = IORESOURCE_MEM,
+	}, {
+
+		.start = IRQ_PF7,
+		.end = IRQ_PF7,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+	},
+};
+static struct platform_device smc91x_device = {
+	.name = "smc91x",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(smc91x_resources),
+	.resource = smc91x_resources,
+};
+#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,
+	},
+};
+
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+void sl811_port_power(struct device *dev, int is_on)
+{
+	gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
+	gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS);
+
+	if (is_on)
+		gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
+	else
+		gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
+}
+#endif
+
+static struct sl811_platform_data sl811_priv = {
+	.potpg = 10,
+	.power = 250,       /* == 500mA */
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+	.port_power = &sl811_port_power,
+#endif
+};
+
+static struct platform_device sl811_hcd_device = {
+	.name = "sl811-hcd",
+	.id = 0,
+	.dev = {
+		.platform_data = &sl811_priv,
+	},
+	.num_resources = ARRAY_SIZE(sl811_hcd_resources),
+	.resource = sl811_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+	{
+		.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,
+	},
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+	.sel15Kres = 1,
+	.clknotstop = 0,
+	.oc_enable = 0,
+	.int_act_high = 0,
+	.int_edge_triggered = 0,
+	.remote_wakeup_connected = 0,
+	.no_power_switching = 1,
+	.power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+	.name = "isp1362-hcd",
+	.id = 0,
+	.dev = {
+		.platform_data = &isp1362_priv,
+	},
+	.num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+	.resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mac_device = {
+	.name = "bfin_mac",
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+	{
+		.start = 0x20300000,
+		.end = 0x20300000 + 0x100,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PF7,
+		.end = IRQ_PF7,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+	},
+};
+
+static struct platform_device net2272_bfin_device = {
+	.name = "net2272",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(net2272_bfin_resources),
+	.resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) \
+	|| defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+	{
+		.name = "bootloader",
+		.size = 0x00020000,
+		.offset = 0,
+		.mask_flags = MTD_CAP_ROM
+	}, {
+		.name = "kernel",
+		.size = 0xe0000,
+		.offset = 0x20000
+	}, {
+		.name = "file system",
+		.size = 0x700000,
+		.offset = 0x00100000,
+	}
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+	.name = "m25p80",
+	.parts = bfin_spi_flash_partitions,
+	.nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+	.type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+	.enable_dma = 0,         /* use dma transfer with this chip*/
+	.bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+	|| defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+	.enable_dma = 1,         /* use dma transfer with this chip*/
+	.bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+static struct bfin5xx_spi_chip spi_mmc_chip_info = {
+	.enable_dma = 1,
+	.bits_per_word = 8,
+};
+#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_AD5304) || defined(CONFIG_AD5304_MODULE)
+static struct bfin5xx_spi_chip ad5304_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 16,
+};
+
+static const struct ad7877_platform_data bfin_ad7877_ts_info = {
+	.model			= 7877,
+	.vref_delay_usecs	= 50,	/* internal, no capacitor */
+	.x_plate_ohms		= 419,
+	.y_plate_ohms		= 486,
+	.pressure_max		= 1000,
+	.pressure_min		= 0,
+	.stopacq_polarity 	= 1,
+	.first_conversion_delay = 3,
+	.acquisition_time 	= 1,
+	.averaging 		= 1,
+	.pen_down_acc_interval 	= 1,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+	|| defined(CONFIG_MTD_M25P80_MODULE)
+	{
+		/* the modalias must be the same as spi device driver name */
+		.modalias = "m25p80", /* Name of spi_driver for this device */
+		.max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0, /* Framework bus number */
+		.chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+		.platform_data = &bfin_spi_flash_data,
+		.controller_data = &spi_flash_chip_info,
+		.mode = SPI_MODE_3,
+	},
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+	|| defined(CONFIG_SPI_ADC_BF533_MODULE)
+	{
+		.modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+		.max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0, /* Framework bus number */
+		.chip_select = 1, /* Framework chip select. */
+		.platform_data = NULL, /* No spi_driver specific config */
+		.controller_data = &spi_adc_chip_info,
+	},
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+	{
+		.modalias = "ad1836-spi",
+		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+		.controller_data = &ad1836_spi_chip_info,
+	},
+#endif
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+	{
+		.modalias = "ad9960-spi",
+		.max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = 1,
+		.controller_data = &ad9960_spi_chip_info,
+	},
+#endif
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+	{
+		.modalias = "spi_mmc_dummy",
+		.max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = 0,
+		.platform_data = NULL,
+		.controller_data = &spi_mmc_chip_info,
+		.mode = SPI_MODE_3,
+	},
+	{
+		.modalias = "spi_mmc",
+		.max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = CONFIG_SPI_MMC_CS_CHAN,
+		.platform_data = NULL,
+		.controller_data = &spi_mmc_chip_info,
+		.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 = 0,
+		.chip_select = 8 - CONFIG_J11_JUMPER,
+		.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 = 0,
+		.chip_select = 8 - CONFIG_J19_JUMPER,
+		.controller_data = &spi_si3xxx_chip_info,
+		.mode = SPI_MODE_3,
+	},
+#endif
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+	{
+		.modalias = "ad5304_spi",
+		.max_speed_hz = 1250000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = 2,
+		.platform_data = NULL,
+		.controller_data = &ad5304_chip_info,
+		.mode = SPI_MODE_2,
+	},
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+	{
+		.modalias		= "ad7877",
+		.platform_data		= &bfin_ad7877_ts_info,
+		.irq			= IRQ_PF6,
+		.max_speed_hz	= 12500000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num	= 1,
+		.chip_select  = 1,
+		.controller_data = &spi_ad7877_chip_info,
+	},
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+	.num_chipselect = 8,
+	.enable_dma = 1,  /* master has the ability to do dma transfer */
+};
+
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+	[0] = {
+		.start = SPI0_REGBASE,
+		.end   = SPI0_REGBASE + 0xFF,
+		.flags = IORESOURCE_MEM,
+		},
+	[1] = {
+		.start = CH_SPI,
+		.end   = CH_SPI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device bfin_spi0_device = {
+	.name = "bfin-spi",
+	.id = 0, /* Bus number */
+	.num_resources = ARRAY_SIZE(bfin_spi0_resource),
+	.resource = bfin_spi0_resource,
+	.dev = {
+		.platform_data = &bfin_spi0_info, /* Passed to driver */
+	},
+};
+#endif  /* spi master and devices */
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+static struct platform_device bfin_fb_device = {
+	.name = "bf537-lq035",
+};
+#endif
+
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+static struct platform_device bfin_fb_adv7393_device = {
+	.name = "bfin-adv7393",
+};
+#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
+};
+
+static struct platform_device bfin_uart_device = {
+	.name = "bfin-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_uart_resources),
+	.resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+	[0] = {
+		.start = TWI0_REGBASE,
+		.end   = TWI0_REGBASE,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_TWI,
+		.end   = IRQ_TWI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+	.name = "i2c-bfin-twi",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_twi0_resource),
+	.resource = bfin_twi0_resource,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 1,
+};
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT	55
+
+static struct pata_platform_info bfin_pata_platform_data = {
+	.ioport_shift = 1,
+	.irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+	{
+		.start = 0x20314020,
+		.end = 0x2031403F,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = 0x2031401C,
+		.end = 0x2031401F,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = PATA_INT,
+		.end = PATA_INT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device bfin_pata_device = {
+	.name = "pata_platform",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(bfin_pata_resources),
+	.resource = bfin_pata_resources,
+	.dev = {
+		.platform_data = &bfin_pata_platform_data,
+	}
+};
+#endif
+
+static struct platform_device *stamp_devices[] __initdata = {
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+	&bfin_pcmcia_cf_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+	&rtc_device,
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+	&sl811_hcd_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+	&isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+	&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
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+	&net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+	&bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+	&bfin_fb_device,
+#endif
+
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+	&bfin_fb_adv7393_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+	&bfin_uart_device,
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+	&i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+	&bfin_sport0_uart_device,
+	&bfin_sport1_uart_device,
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+	&bfin_pata_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+	printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+	spi_register_board_info(bfin_spi_board_info,
+				ARRAY_SIZE(bfin_spi_board_info));
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+	irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
+	return 0;
+}
+
+arch_initcall(stamp_init);
+
+void native_machine_restart(char *cmd)
+{
+	/* workaround reboot hang when booting from SPI */
+	if ((bfin_read_SYSCR() & 0x7) == 0x3)
+		bfin_gpio_reset_spi0_ssel1();
+}
diff --git a/arch/blackfin/mach-bf527/cpu.c b/arch/blackfin/mach-bf527/cpu.c
new file mode 100644
index 0000000..1975402
--- /dev/null
+++ b/arch/blackfin/mach-bf527/cpu.c
@@ -0,0 +1,161 @@
+/*
+ * File:         arch/blackfin/mach-bf527/cpu.c
+ * Based on:	arch/blackfin/mach-bf537/cpu.c
+ * Author:       michael.kang@analog.com
+ *
+ * Created:
+ * Description:  clock scaling for the bf527
+ *
+ * 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=11059200 */
+#define VCO5 (CONFIG_CLKIN_HZ*45)	/*497664000 */
+#define VCO4 (CONFIG_CLKIN_HZ*36)	/*398131200 */
+#define VCO3 (CONFIG_CLKIN_HZ*27)	/*298598400 */
+#define VCO2 (CONFIG_CLKIN_HZ*18)	/*199065600 */
+#define VCO1 (CONFIG_CLKIN_HZ*9)	/*99532800 */
+#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 bf527_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 bf527_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 bf527_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, bf527_freq_table, target_freq, relation, &index))
+		return -EINVAL;
+
+	cclk_mhz = bf527_freq_table[index].frequency;
+	vco_mhz = bf527_freq_table[index].index;
+
+	dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz);
+	freqs.old = bf527_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 bf527_verify_speed(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, &bf527_freq_table);
+}
+
+static int __init __bf527_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 = bf527_getfreq(0);
+	cpufreq_frequency_table_get_attr(bf527_freq_table, policy->cpu);
+	return cpufreq_frequency_table_cpuinfo(policy, bf527_freq_table);
+}
+
+static struct freq_attr *bf527_freq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver bf527_driver = {
+	.verify = bf527_verify_speed,
+	.target = bf527_target,
+	.get = bf527_getfreq,
+	.init = __bf527_cpu_init,
+	.name = "bf527",
+	.owner = THIS_MODULE,
+	.attr = bf527_freq_attr,
+};
+
+static int __init bf527_cpu_init(void)
+{
+	return cpufreq_register_driver(&bf527_driver);
+}
+
+static void __exit bf527_cpu_exit(void)
+{
+	cpufreq_unregister_driver(&bf527_driver);
+}
+
+MODULE_AUTHOR("Mickael Kang");
+MODULE_DESCRIPTION("cpufreq driver for bf527 CPU");
+MODULE_LICENSE("GPL");
+
+module_init(bf527_cpu_init);
+module_exit(bf527_cpu_exit);
diff --git a/arch/blackfin/mach-bf527/dma.c b/arch/blackfin/mach-bf527/dma.c
new file mode 100644
index 0000000..522de24
--- /dev/null
+++ b/arch/blackfin/mach-bf527/dma.c
@@ -0,0 +1,115 @@
+/*
+ * File:         arch/blackfin/mach-bf527/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_UART0_RX:
+		ret_irq = IRQ_UART0_RX;
+		break;
+
+	case CH_UART0_TX:
+		ret_irq = IRQ_UART0_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-bf527/head.S b/arch/blackfin/mach-bf527/head.S
new file mode 100644
index 0000000..cdb00a0
--- /dev/null
+++ b/arch/blackfin/mach-bf527/head.S
@@ -0,0 +1,456 @@
+/*
+ * File:         arch/blackfin/mach-bf527/head.S
+ * Based on:     arch/blackfin/mach-bf533/head.S
+ * Author:       Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
+ *
+ * Created:      1998
+ * Description:  Startup code for Blackfin BF537
+ *
+ * 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 <linux/init.h>
+#include <asm/blackfin.h>
+#include <asm/trace.h>
+
+#if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach-common/clocks.h>
+#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
+
+__INIT
+
+ENTRY(__start)
+	/* R0: argument of command line string, passed from uboot, save it */
+	R7 = R0;
+	/* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+	R0 = SYSCFG_SNEN;
+#else
+	R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
+	SYSCFG = R0;
+	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_init(p0,r0);
+	P0 = R1;
+	R0 = R1;
+
+	/* Turn off the icache */
+	p0.l = LO(IMEM_CONTROL);
+	p0.h = HI(IMEM_CONTROL);
+	R1 = [p0];
+	R0 = ~ENICPLB;
+	R0 = R0 & R1;
+
+	/* Anomaly 05000125 */
+#if ANOMALY_05000125
+	CLI R2;
+	SSYNC;
+#endif
+	[p0] = R0;
+	SSYNC;
+#if ANOMALY_05000125
+	STI R2;
+#endif
+
+	/* Turn off the dcache */
+	p0.l = LO(DMEM_CONTROL);
+	p0.h = HI(DMEM_CONTROL);
+	R1 = [p0];
+	R0 = ~ENDCPLB;
+	R0 = R0 & R1;
+
+	/* Anomaly 05000125 */
+#if ANOMALY_05000125
+	CLI R2;
+	SSYNC;
+#endif
+	[p0] = R0;
+	SSYNC;
+#if ANOMALY_05000125
+	STI R2;
+#endif
+
+
+#if defined(CONFIG_BF527)
+	p0.h = hi(EMAC_SYSTAT);
+	p0.l = lo(EMAC_SYSTAT);
+	R0.h = 0xFFFF; /* Clear EMAC Interrupt Status bits */
+	R0.l = 0xFFFF;
+	[P0] = R0;
+	SSYNC;
+#endif
+
+	/* Initialise UART - when booting from u-boot, the UART is not disabled
+	 * so if we dont initalize here, our serial console gets hosed */
+	p0.h = hi(UART1_LCR);
+	p0.l = lo(UART1_LCR);
+	r0 = 0x0(Z);
+	w[p0] = r0.L;	/* To enable DLL writes */
+	ssync;
+
+	p0.h = hi(UART1_DLL);
+	p0.l = lo(UART1_DLL);
+	r0 = 0x0(Z);
+	w[p0] = r0.L;
+	ssync;
+
+	p0.h = hi(UART1_DLH);
+	p0.l = lo(UART1_DLH);
+	r0 = 0x00(Z);
+	w[p0] = r0.L;
+	ssync;
+
+	p0.h = hi(UART1_GCTL);
+	p0.l = lo(UART1_GCTL);
+	r0 = 0x0(Z);
+	w[p0] = r0.L;	/* To enable UART clock */
+	ssync;
+
+	/* Initialize stack pointer */
+	sp.l = lo(INITIAL_STACK);
+	sp.h = hi(INITIAL_STACK);
+	fp = sp;
+	usp = sp;
+
+#ifdef CONFIG_EARLY_PRINTK
+	SP += -12;
+	call _init_early_exception_vectors;
+	SP += 12;
+#endif
+
+	/* 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 ANOMALY_05000281
+	nop; nop; nop;
+#endif
+	rti;
+
+.LWAIT_HERE:
+	jump .LWAIT_HERE;
+ENDPROC(__start)
+
+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;
+	jump.l _start_kernel;
+ENDPROC(_real_start)
+
+__FINIT
+
+.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_IWR0);
+	p0.l = lo(SIC_IWR0);
+	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 = LO(EBIU_SDBCTL);
+	p0.h = HI(EBIU_SDBCTL);     /* 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_IWR0);
+	p0.l = lo(SIC_IWR0);
+	r0.l = lo(IWR_ENABLE_ALL);
+	r0.h = hi(IWR_ENABLE_ALL);
+	[p0] = r0;
+	SSYNC;
+
+	RTS;
+ENDPROC(_start_dma_code)
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+.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-bf527/ints-priority.c b/arch/blackfin/mach-bf527/ints-priority.c
new file mode 100644
index 0000000..1fa3897
--- /dev/null
+++ b/arch/blackfin/mach-bf527/ints-priority.c
@@ -0,0 +1,100 @@
+/*
+ * File:         arch/blackfin/mach-bf537/ints-priority.c
+ * Based on:     arch/blackfin/mach-bf533/ints-priority.c
+ * Author:       Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * Created:
+ * Description:  Set up the interrupt priorities
+ *
+ * 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/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_DMA0_ERROR - 7) << IRQ_DMA0_ERROR_POS) |
+			((CONFIG_IRQ_DMAR0_BLK - 7) << IRQ_DMAR0_BLK_POS) |
+			((CONFIG_IRQ_DMAR1_BLK - 7) << IRQ_DMAR1_BLK_POS) |
+			((CONFIG_IRQ_DMAR0_OVR - 7) << IRQ_DMAR0_OVR_POS) |
+			((CONFIG_IRQ_DMAR1_OVR - 7) << IRQ_DMAR1_OVR_POS) |
+			((CONFIG_IRQ_PPI_ERROR - 7) << IRQ_PPI_ERROR_POS) |
+			((CONFIG_IRQ_MAC_ERROR - 7) << IRQ_MAC_ERROR_POS));
+
+
+	bfin_write_SIC_IAR1(((CONFIG_IRQ_SPORT0_ERROR - 7) << IRQ_SPORT0_ERROR_POS) |
+			((CONFIG_IRQ_SPORT1_ERROR - 7) << IRQ_SPORT1_ERROR_POS) |
+			((CONFIG_IRQ_UART0_ERROR - 7) << IRQ_UART0_ERROR_POS) |
+			((CONFIG_IRQ_UART1_ERROR - 7) << IRQ_UART1_ERROR_POS) |
+			((CONFIG_IRQ_RTC - 7) << IRQ_RTC_POS) |
+			((CONFIG_IRQ_PPI - 7) << IRQ_PPI_POS));
+
+	bfin_write_SIC_IAR2(((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_TWI - 7) << IRQ_TWI_POS) |
+			((CONFIG_IRQ_SPI - 7) << IRQ_SPI_POS) |
+			((CONFIG_IRQ_UART0_RX - 7) << IRQ_UART0_RX_POS) |
+			((CONFIG_IRQ_UART0_TX - 7) << IRQ_UART0_TX_POS));
+
+	bfin_write_SIC_IAR3(((CONFIG_IRQ_UART1_RX - 7) << IRQ_UART1_RX_POS) |
+			((CONFIG_IRQ_UART1_TX - 7) << IRQ_UART1_TX_POS) |
+			((CONFIG_IRQ_OPTSEC - 7) << IRQ_OPTSEC_POS) |
+			((CONFIG_IRQ_CNT - 7) << IRQ_CNT_POS) |
+			((CONFIG_IRQ_MAC_RX - 7) << IRQ_MAC_RX_POS) |
+			((CONFIG_IRQ_PORTH_INTA - 7) << IRQ_PORTH_INTA_POS) |
+			((CONFIG_IRQ_MAC_TX - 7) << IRQ_MAC_TX_POS) |
+			((CONFIG_IRQ_PORTH_INTB - 7) << IRQ_PORTH_INTB_POS));
+
+	bfin_write_SIC_IAR4(((CONFIG_IRQ_TMR0 - 7) << IRQ_TMR0_POS) |
+			((CONFIG_IRQ_TMR1 - 7) << IRQ_TMR1_POS) |
+			((CONFIG_IRQ_TMR2 - 7) << IRQ_TMR2_POS) |
+			((CONFIG_IRQ_TMR3 - 7) << IRQ_TMR3_POS) |
+			((CONFIG_IRQ_TMR4 - 7) << IRQ_TMR4_POS) |
+			((CONFIG_IRQ_TMR5 - 7) << IRQ_TMR5_POS) |
+			((CONFIG_IRQ_TMR6 - 7) << IRQ_TMR6_POS) |
+			((CONFIG_IRQ_TMR7 - 7) << IRQ_TMR7_POS));
+
+	bfin_write_SIC_IAR5(((CONFIG_IRQ_PORTG_INTA - 7) << IRQ_PORTG_INTA_POS) |
+			((CONFIG_IRQ_PORTG_INTB - 7) << IRQ_PORTG_INTB_POS) |
+			((CONFIG_IRQ_MEM_DMA0 - 7) << IRQ_MEM_DMA0_POS) |
+			((CONFIG_IRQ_MEM_DMA1 - 7) << IRQ_MEM_DMA1_POS) |
+			((CONFIG_IRQ_WATCH - 7) << IRQ_WATCH_POS) |
+			((CONFIG_IRQ_PORTF_INTA - 7) << IRQ_PORTF_INTA_POS) |
+			((CONFIG_IRQ_PORTF_INTB - 7) << IRQ_PORTF_INTB_POS) |
+			((CONFIG_IRQ_SPI_ERROR - 7) << IRQ_SPI_ERROR_POS));
+
+	bfin_write_SIC_IAR6(((CONFIG_IRQ_NFC_ERROR - 7) << IRQ_NFC_ERROR_POS) |
+			((CONFIG_IRQ_HDMA_ERROR - 7) << IRQ_HDMA_ERROR_POS) |
+			((CONFIG_IRQ_HDMA - 7) << IRQ_HDMA_POS) |
+			((CONFIG_IRQ_USB_EINT - 7) << IRQ_USB_EINT_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));
+
+	SSYNC();
+}
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
index a57b52d..1c5a86a 100644
--- a/arch/blackfin/mach-bf533/boards/cm_bf533.c
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -42,7 +42,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "Bluetechnix CM BF533";
+const char bfin_board_name[] = "Bluetechnix CM BF533";
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
 /* all SPI peripherals info goes here */
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index 5c1e35d..34b6392 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -43,7 +43,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "ADDS-BF533-EZKIT";
+const char bfin_board_name[] = "ADDS-BF533-EZKIT";
 
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
 static struct platform_device rtc_device = {
diff --git a/arch/blackfin/mach-bf533/boards/generic_board.c b/arch/blackfin/mach-bf533/boards/generic_board.c
index 9bc1f0d..310b777 100644
--- a/arch/blackfin/mach-bf533/boards/generic_board.c
+++ b/arch/blackfin/mach-bf533/boards/generic_board.c
@@ -35,7 +35,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "UNKNOWN BOARD";
+const char bfin_board_name[] = "UNKNOWN BOARD";
 
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
 static struct platform_device rtc_device = {
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 8975e06..f84be4e 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -46,7 +46,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "ADDS-BF533-STAMP";
+const char bfin_board_name[] = "ADDS-BF533-STAMP";
 
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
 static struct platform_device rtc_device = {
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c
index 44dea05..52e2320 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c
@@ -43,7 +43,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "Bluetechnix CM BF537";
+const char bfin_board_name[] = "Bluetechnix CM BF537";
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
 /* all SPI peripherals info goes here */
diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c
index 6668c8e..255da7a 100644
--- a/arch/blackfin/mach-bf537/boards/generic_board.c
+++ b/arch/blackfin/mach-bf537/boards/generic_board.c
@@ -49,7 +49,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "GENERIC Board";
+const char bfin_board_name[] = "GENERIC Board";
 
 /*
  *  Driver needs to know address, irq and flag pin.
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index f83a254..87b8089 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -47,7 +47,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "PNAV-1.0";
+const char bfin_board_name[] = "PNAV-1.0";
 
 /*
  *  Driver needs to know address, irq and flag pin.
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index f42ba3a..cc41f6c 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -49,7 +49,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "ADDS-BF537-STAMP";
+const char bfin_board_name[] = "ADDS-BF537-STAMP";
 
 /*
  *  Driver needs to know address, irq and flag pin.
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index 046e6d8..6b6490e 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -49,7 +49,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "ADSP-BF548-EZKIT";
+const char bfin_board_name[] = "ADSP-BF548-EZKIT";
 
 /*
  *  Driver needs to know address, irq and flag pin.
@@ -560,7 +560,7 @@
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
 	&bf54x_spi_master0,
-/*	&bf54x_spi_master1,*/
+	&bf54x_spi_master1,
 #endif
 
 #if defined(CONFIG_KEYBOARD_BFIN) || defined(CONFIG_KEYBOARD_BFIN_MODULE)
diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c
index a818411..957bf13 100644
--- a/arch/blackfin/mach-bf548/dma.c
+++ b/arch/blackfin/mach-bf548/dma.c
@@ -64,6 +64,7 @@
 	(struct dma_register *) MDMA_D3_NEXT_DESC_PTR,
 	(struct dma_register *) MDMA_S3_NEXT_DESC_PTR,
 };
+EXPORT_SYMBOL(base_addr);
 
 int channel2irq(unsigned int channel)
 {
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
index cd827a1..97aeb43 100644
--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -42,7 +42,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "Bluetechnix CM BF561";
+const char bfin_board_name[] = "Bluetechnix CM BF561";
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
 /* all SPI peripherals info goes here */
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 57e14ed..059d516 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -39,7 +39,7 @@
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "ADDS-BF561-EZKIT";
+const char bfin_board_name[] = "ADDS-BF561-EZKIT";
 
 #define ISP1761_BASE       0x2C0F0000
 #define ISP1761_IRQ        IRQ_PF10
diff --git a/arch/blackfin/mach-bf561/boards/generic_board.c b/arch/blackfin/mach-bf561/boards/generic_board.c
index 4dfea5d..46816be 100644
--- a/arch/blackfin/mach-bf561/boards/generic_board.c
+++ b/arch/blackfin/mach-bf561/boards/generic_board.c
@@ -32,7 +32,7 @@
 #include <linux/platform_device.h>
 #include <linux/irq.h>
 
-char *bfin_board_name = "UNKNOWN BOARD";
+const char bfin_board_name[] = "UNKNOWN BOARD";
 
 /*
  *  Driver needs to know address, irq and flag pin.
diff --git a/arch/blackfin/mach-bf561/boards/tepla.c b/arch/blackfin/mach-bf561/boards/tepla.c
index c442eb2..4a17c6d 100644
--- a/arch/blackfin/mach-bf561/boards/tepla.c
+++ b/arch/blackfin/mach-bf561/boards/tepla.c
@@ -16,7 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/irq.h>
 
-char *bfin_board_name = "Tepla-BF561";
+const char bfin_board_name[] = "Tepla-BF561";
 
 /*
  *  Driver needs to know address, irq and flag pin.
diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c
index 2db3546..c2f05fa 100644
--- a/arch/blackfin/mach-common/ints-priority-dc.c
+++ b/arch/blackfin/mach-common/ints-priority-dc.c
@@ -52,7 +52,13 @@
  * -
  */
 
-unsigned long irq_flags = 0;
+/* Initialize this to an actual value to force it into the .data
+ * section so that we know it is properly initialized at entry into
+ * the kernel but before bss is initialized to zero (which is where
+ * it would live otherwise).  The 0x1f magic represents the IRQs we
+ * cannot actually mask out in hardware.
+ */
+unsigned long irq_flags = 0x1f;
 
 /* The number of spurious interrupts */
 atomic_t num_spurious;
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c
index d3b7672..2d2b635 100644
--- a/arch/blackfin/mach-common/ints-priority-sc.c
+++ b/arch/blackfin/mach-common/ints-priority-sc.c
@@ -58,7 +58,13 @@
  * -
  */
 
-unsigned long irq_flags = 0;
+/* Initialize this to an actual value to force it into the .data
+ * section so that we know it is properly initialized at entry into
+ * the kernel but before bss is initialized to zero (which is where
+ * it would live otherwise).  The 0x1f magic represents the IRQs we
+ * cannot actually mask out in hardware.
+ */
+unsigned long irq_flags = 0x1f;
 
 /* The number of spurious interrupts */
 atomic_t num_spurious;
@@ -92,10 +98,15 @@
 
 		for (irqn = 0; irqn < NR_PERI_INTS; irqn++) {
 			int iar_shift = (irqn & 7) * 4;
-			if (ivg ==
+				if (ivg ==
 			    (0xf &
+#ifndef CONFIG_BF52x
 			     bfin_read32((unsigned long *)SIC_IAR0 +
 					 (irqn >> 3)) >> iar_shift)) {
+#else
+			     bfin_read32((unsigned long *)SIC_IAR0 +
+					 ((irqn%32) >> 3) + ((irqn / 32) * 16)) >> iar_shift)) {
+#endif
 				ivg_table[irq_pos].irqno = IVG7 + irqn;
 				ivg_table[irq_pos].isrflag = 1 << (irqn % 32);
 				ivg7_13[ivg].istop++;
@@ -140,7 +151,7 @@
 
 static void bfin_internal_mask_irq(unsigned int irq)
 {
-#ifndef CONFIG_BF54x
+#ifdef CONFIG_BF53x
 	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
 			     ~(1 << (irq - (IRQ_CORETMR + 1))));
 #else
@@ -155,7 +166,7 @@
 
 static void bfin_internal_unmask_irq(unsigned int irq)
 {
-#ifndef CONFIG_BF54x
+#ifdef CONFIG_BF53x
 	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
 			     (1 << (irq - (IRQ_CORETMR + 1))));
 #else
@@ -750,13 +761,15 @@
 	int irq;
 	unsigned long ilat = 0;
 	/*  Disable all the peripheral intrs  - page 4-29 HW Ref manual */
-#ifdef CONFIG_BF54x
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
 	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);
+#ifdef CONFIG_BF54x
+	bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
 	bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
+#endif
 #else
 	bfin_write_SIC_IMASK(SIC_UNMASK_ALL);
 	bfin_write_SIC_IWR(IWR_ENABLE_ALL);
@@ -787,7 +800,7 @@
 
 			switch (irq) {
 #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
-#ifndef CONFIG_BF54x
+#if defined(CONFIG_BF53x)
 			case IRQ_PROG_INTA:
 				set_irq_chained_handler(irq,
 							bfin_demux_gpio_irq);
@@ -798,7 +811,7 @@
 							bfin_demux_gpio_irq);
 				break;
 #endif
-#else
+#elif defined(CONFIG_BF54x)
 			case IRQ_PINT0:
 				set_irq_chained_handler(irq,
 							bfin_demux_gpio_irq);
@@ -815,7 +828,20 @@
 				set_irq_chained_handler(irq,
 							bfin_demux_gpio_irq);
 				break;
-#endif				/*CONFIG_BF54x */
+#elif defined(CONFIG_BF52x)
+			case IRQ_PORTF_INTA:
+				set_irq_chained_handler(irq,
+							bfin_demux_gpio_irq);
+				break;
+			case IRQ_PORTG_INTA:
+				set_irq_chained_handler(irq,
+							bfin_demux_gpio_irq);
+				break;
+			case IRQ_PORTH_INTA:
+				set_irq_chained_handler(irq,
+							bfin_demux_gpio_irq);
+				break;
+#endif
 #endif
 			default:
 				set_irq_handler(irq, handle_simple_irq);
@@ -880,14 +906,15 @@
 	} else {
 		struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
 		struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
-#ifdef CONFIG_BF54x
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
 		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);
-
+		sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
+		sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1();
+#ifdef CONFIG_BF54x
+		sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2();
+#endif
 		for (;; ivg++) {
 			if (ivg >= ivg_stop) {
 				atomic_inc(&num_spurious);
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index b103027..dac51fb 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -32,7 +32,7 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
 #include <linux/io.h>
@@ -89,28 +89,15 @@
 #endif				/* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */
 }
 
-
 /*
- *	bfin_pm_prepare - Do preliminary suspend work.
- *	@state:		suspend state we're entering.
+ *	bfin_pm_valid - Tell the PM core that we only support the standby sleep
+ *			state
+ *	@state:		suspend state we're checking.
  *
  */
-static int bfin_pm_prepare(suspend_state_t state)
+static int bfin_pm_valid(suspend_state_t state)
 {
-	int error = 0;
-
-	switch (state) {
-	case PM_SUSPEND_STANDBY:
-		break;
-
-	case PM_SUSPEND_MEM:
-		return -ENOTSUPP;
-
-	default:
-		return -EINVAL;
-	}
-
-	return error;
+	return (state == PM_SUSPEND_STANDBY);
 }
 
 /*
@@ -135,44 +122,14 @@
 	return 0;
 }
 
-/*
- *	bfin_pm_finish - Finish up suspend sequence.
- *	@state:		State we're coming out of.
- *
- *	This is called after we wake back up (or if entering the sleep state
- *	failed).
- */
-static int bfin_pm_finish(suspend_state_t state)
-{
-	switch (state) {
-	case PM_SUSPEND_STANDBY:
-		break;
-
-	case PM_SUSPEND_MEM:
-		return -ENOTSUPP;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int bfin_pm_valid(suspend_state_t state)
-{
-	return (state == PM_SUSPEND_STANDBY);
-}
-
-struct pm_ops bfin_pm_ops = {
-	.prepare = bfin_pm_prepare,
+struct platform_suspend_ops bfin_pm_ops = {
 	.enter = bfin_pm_enter,
-	.finish = bfin_pm_finish,
 	.valid	= bfin_pm_valid,
 };
 
 static int __init bfin_pm_init(void)
 {
-	pm_set_ops(&bfin_pm_ops);
+	suspend_set_ops(&bfin_pm_ops);
 	return 0;
 }
 
diff --git a/arch/blackfin/oprofile/Kconfig b/arch/blackfin/oprofile/Kconfig
deleted file mode 100644
index 0a2fd99..0000000
--- a/arch/blackfin/oprofile/Kconfig
+++ /dev/null
@@ -1,29 +0,0 @@
-menu "Profiling support"
-depends on EXPERIMENTAL
-
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
-config HARDWARE_PM
-	tristate "Hardware Performance Monitor Profiling"
-	depends on PROFILING
-	help
-	  take use of hardware performance monitor to profiling the kernel
-	  and application.
-
-	  If unsure, say N.
-
-endmenu
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 6b4d026..21900a9 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -196,6 +196,8 @@
 
 source "drivers/usb/Kconfig"
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/cris/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/cris/arch-v10/Kconfig b/arch/cris/arch-v10/Kconfig
index c7ea9ef..f1ce6f6 100644
--- a/arch/cris/arch-v10/Kconfig
+++ b/arch/cris/arch-v10/Kconfig
@@ -182,7 +182,7 @@
 	  set this to same as CONFIG_ETRAX_LED1G (normally 2).
 
 config ETRAX_LED8Y
-	int "Eigth yellow LED bit"
+	int "Eighth yellow LED bit"
 	depends on ETRAX_CSP0_LEDS
 	default "2"
 	help
diff --git a/arch/cris/arch-v10/boot/compressed/misc.c b/arch/cris/arch-v10/boot/compressed/misc.c
index ffb8d21..e205d2e 100644
--- a/arch/cris/arch-v10/boot/compressed/misc.c
+++ b/arch/cris/arch-v10/boot/compressed/misc.c
@@ -8,7 +8,7 @@
  *
  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
  * puts by Nick Holloway 1993, better puts by Martin Mares 1995
- * adoptation for Linux/CRIS Axis Communications AB, 1999
+ * adaptation for Linux/CRIS Axis Communications AB, 1999
  * 
  */
 
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c
index 1de0026..c263b82 100644
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ b/arch/cris/arch-v10/drivers/pcf8563.c
@@ -4,7 +4,7 @@
  * From Phillips' datasheet:
  *
  * The PCF8563 is a CMOS real-time clock/calendar optimized for low power
- * consumption. A programmable clock output, interupt output and voltage
+ * consumption. A programmable clock output, interrupt output and voltage
  * low detector are also provided. All address and data are transferred
  * serially via two-line bidirectional I2C-bus. Maximum bus speed is
  * 400 kbits/s. The built-in word address register is incremented
diff --git a/arch/cris/arch-v10/kernel/debugport.c b/arch/cris/arch-v10/kernel/debugport.c
index 2b536ca..93679a4 100644
--- a/arch/cris/arch-v10/kernel/debugport.c
+++ b/arch/cris/arch-v10/kernel/debugport.c
@@ -83,7 +83,7 @@
  *
  * Revision 1.4  2002/11/19 14:35:24  starvik
  * Changes from linux 2.4
- * Changed struct initializer syntax to the currently prefered notation
+ * Changed struct initializer syntax to the currently preferred notation
  *
  * Revision 1.3  2002/11/06 09:47:03  starvik
  * Modified for new interrupt macros
diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S
index ae45d45..c5844cb 100644
--- a/arch/cris/arch-v10/kernel/entry.S
+++ b/arch/cris/arch-v10/kernel/entry.S
@@ -97,7 +97,7 @@
  *
  *  Revision 1.36  2001/11/22 13:36:36  bjornw
  *  * In ret_from_intr, check regs->dccr for usermode reentrance instead of
- *    DCCR explicitely (because the latter might not reflect current reality)
+ *    DCCR explicitly (because the latter might not reflect current reality)
  *  * In mmu_bus_fault, set $r9 _after_ calling the C-code instead of before
  *    since $r9 is call-clobbered and is potentially needed afterwards
  *
diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c
index 8cbdf59..d3ea052 100644
--- a/arch/cris/arch-v10/kernel/fasttimer.c
+++ b/arch/cris/arch-v10/kernel/fasttimer.c
@@ -84,7 +84,7 @@
  * with time based on jiffies and *R_TIMER0_DATA, uses a table
  * for fast conversion of timer value to microseconds.
  * (Much faster the standard do_gettimeofday() and we don't really
- * wan't to use the true time - we wan't the "uptime" so timers don't screw up
+ * want to use the true time - we want the "uptime" so timers don't screw up
  * when we change the time.
  * TODO: Add efficient support for continuous timers as well.
  *
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c
index 96094cb..845c95f 100644
--- a/arch/cris/arch-v10/kernel/irq.c
+++ b/arch/cris/arch-v10/kernel/irq.c
@@ -169,7 +169,7 @@
         for (i = 0; i < 256; i++)
                etrax_irv->v[i] = weird_irq;
 
-	/* Initialize IRQ handler descriptiors. */
+	/* Initialize IRQ handler descriptors. */
 	for(i = 2; i < NR_IRQS; i++) {
 		irq_desc[i].chip = &crisv10_irq_type;
 		set_int_vector(i, interrupt[i]);
diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c
index 07628a1..77f4b14 100644
--- a/arch/cris/arch-v10/kernel/kgdb.c
+++ b/arch/cris/arch-v10/kernel/kgdb.c
@@ -959,7 +959,7 @@
 
 	/* Send register contents. We probably only need to send the
 	 * PC, frame pointer and stack pointer here. Other registers will be
-	 * explicitely asked for. But for now, send all. 
+	 * explicitly asked for. But for now, send all.
 	 */
 	
 	for (regno = R0; regno <= USP; regno++) {
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c
index b6831ce..1a3760c 100644
--- a/arch/cris/arch-v10/kernel/process.c
+++ b/arch/cris/arch-v10/kernel/process.c
@@ -64,7 +64,7 @@
 #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
 	cause_of_death = 0xbedead;
 #else
-	/* Since we dont plan to keep on reseting the watchdog,
+	/* Since we dont plan to keep on resetting the watchdog,
 	   the key can be arbitrary hence three */
 	*R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, 3) |
 		IO_STATE(R_WATCHDOG, enable, start);
diff --git a/arch/cris/arch-v10/kernel/shadows.c b/arch/cris/arch-v10/kernel/shadows.c
index 38fd44d..326178a 100644
--- a/arch/cris/arch-v10/kernel/shadows.c
+++ b/arch/cris/arch-v10/kernel/shadows.c
@@ -20,7 +20,7 @@
  * These are only usable if there actually IS a latch connected
  * to the corresponding external chip-select pin.
  *
- * A common usage is that CSP0 controls LED's and CSP4 video chips.
+ * A common usage is that CSP0 controls LEDs and CSP4 video chips.
  */
 
 unsigned long port_cse1_shadow;
diff --git a/arch/cris/arch-v10/lib/dram_init.S b/arch/cris/arch-v10/lib/dram_init.S
index 9cf8393..6a6bdfd 100644
--- a/arch/cris/arch-v10/lib/dram_init.S
+++ b/arch/cris/arch-v10/lib/dram_init.S
@@ -40,7 +40,7 @@
  * Copy warning from head.S about r8 and r9
  *
  * Revision 1.7  2001/04/18 12:05:39  bjornw
- * Fixed comments, and explicitely include config.h to be sure its there
+ * Fixed comments, and explicitly include config.h to be sure its there
  *
  * Revision 1.6  2001/04/10 06:20:16  starvik
  * Delay should be 200us, not 200ns
@@ -66,7 +66,7 @@
  */
 
 /* Just to be certain the config file is included, we include it here
- * explicitely instead of depending on it being included in the file that
+ * explicitly instead of depending on it being included in the file that
  * uses this code.
  */
 
diff --git a/arch/cris/arch-v10/lib/string.c b/arch/cris/arch-v10/lib/string.c
index 8ffde49..15d6662 100644
--- a/arch/cris/arch-v10/lib/string.c
+++ b/arch/cris/arch-v10/lib/string.c
@@ -41,7 +41,7 @@
      Make sure the compiler is able to make something useful of this.
       As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on. */
 
   register void *return_dst __asm__ ("r10") = pdst;
diff --git a/arch/cris/arch-v10/lib/usercopy.c b/arch/cris/arch-v10/lib/usercopy.c
index 43778d5..a12c708 100644
--- a/arch/cris/arch-v10/lib/usercopy.c
+++ b/arch/cris/arch-v10/lib/usercopy.c
@@ -38,7 +38,7 @@
      As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
      FIXME: Comment for old gcc version.  Check.
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on. */
 
   register char *dst __asm__ ("r13") = pdst;
@@ -200,7 +200,7 @@
      As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
      FIXME: Comment for old gcc version.  Check.
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on.  */
 
   register char *dst __asm__ ("r13") = pdst;
@@ -380,7 +380,7 @@
       As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
      FIXME: Comment for old gcc version.  Check.
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on. */
 
   register char *dst __asm__ ("r13") = pto;
diff --git a/arch/cris/arch-v32/boot/compressed/misc.c b/arch/cris/arch-v32/boot/compressed/misc.c
index 1190269..0169ba1 100644
--- a/arch/cris/arch-v32/boot/compressed/misc.c
+++ b/arch/cris/arch-v32/boot/compressed/misc.c
@@ -8,7 +8,7 @@
  *
  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
  * puts by Nick Holloway 1993, better puts by Martin Mares 1995
- * adoptation for Linux/CRIS Axis Communications AB, 1999
+ * adaptation for Linux/CRIS Axis Communications AB, 1999
  *
  */
 
@@ -151,7 +151,7 @@
 	do {
 		rs = REG_RD(ser, regi_ser, rs_stat_din);
 	}
-	while (!rs.tr_rdy);/* Wait for tranceiver. */
+	while (!rs.tr_rdy);/* Wait for transceiver. */
 
 	REG_WR(ser, regi_ser, rw_dout, dout);
 }
@@ -264,7 +264,7 @@
 	tr_ctrl.stop_bits = 1;	/* 2 stop bits. */
 
 	/*
-	 * The baudrate setup is a bit fishy, but in the end the tranceiver is
+	 * The baudrate setup is a bit fishy, but in the end the transceiver is
 	 * set to 4800 and the receiver to 115200. The magic value is
 	 * 29.493 MHz.
 	 */
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c
index 5180d45..3ec12ea 100644
--- a/arch/cris/arch-v32/drivers/axisflashmap.c
+++ b/arch/cris/arch-v32/drivers/axisflashmap.c
@@ -205,7 +205,7 @@
 /*
  * Probe each chip select individually for flash chips. If there are chips on
  * both cse0 and cse1, the mtd_info structs will be concatenated to one struct
- * so that MTD partitions can cross chip boundries.
+ * so that MTD partitions can cross chip boundaries.
  *
  * The only known restriction to how you can mount your chips is that each
  * chip select must hold similar flash chips. But you need external hardware
diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c
index e12f6cc..f1edd2e 100644
--- a/arch/cris/arch-v32/drivers/i2c.c
+++ b/arch/cris/arch-v32/drivers/i2c.c
@@ -275,7 +275,7 @@
 		ack = 0;
 	i2c_delay(CLOCK_HIGH_TIME/2);
 	if(!ack){
-		if(!i2c_getbit()) /* receiver pulld SDA low */
+		if(!i2c_getbit()) /* receiver pulled SDA low */
 			ack = 1;
 		i2c_delay(CLOCK_HIGH_TIME/2);
 	}
diff --git a/arch/cris/arch-v32/drivers/nandflash.c b/arch/cris/arch-v32/drivers/nandflash.c
index 93ddea4d..5ce015c 100644
--- a/arch/cris/arch-v32/drivers/nandflash.c
+++ b/arch/cris/arch-v32/drivers/nandflash.c
@@ -138,7 +138,7 @@
 	/* Enable the following for a flash based bad block table */
 	this->options = NAND_USE_FLASH_BBT;
 
-	/* Scan to find existance of the device */
+	/* Scan to find existence of the device */
 	if (nand_scan (crisv32_mtd, 1)) {
 		err = -ENXIO;
 		goto out_ior;
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
index da479a1..6dbd700 100644
--- a/arch/cris/arch-v32/drivers/pcf8563.c
+++ b/arch/cris/arch-v32/drivers/pcf8563.c
@@ -4,7 +4,7 @@
  * From Phillips' datasheet:
  *
  * The PCF8563 is a CMOS real-time clock/calendar optimized for low power
- * consumption. A programmable clock output, interupt output and voltage
+ * consumption. A programmable clock output, interrupt output and voltage
  * low detector are also provided. All address and data are transferred
  * serially via two-line bidirectional I2C-bus. Maximum bus speed is
  * 400 kbits/s. The built-in word address register is incremented
diff --git a/arch/cris/arch-v32/kernel/fasttimer.c b/arch/cris/arch-v32/kernel/fasttimer.c
index 79e1e4c..b40551f 100644
--- a/arch/cris/arch-v32/kernel/fasttimer.c
+++ b/arch/cris/arch-v32/kernel/fasttimer.c
@@ -97,7 +97,7 @@
  * with time based on jiffies and *R_TIMER0_DATA, uses a table
  * for fast conversion of timer value to microseconds.
  * (Much faster the standard do_gettimeofday() and we don't really
- * wan't to use the true time - we wan't the "uptime" so timers don't screw up
+ * want to use the true time - we want the "uptime" so timers don't screw up
  * when we change the time.
  * TODO: Add efficient support for continuous timers as well.
  *
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c
index cc361bf..a9acaa27 100644
--- a/arch/cris/arch-v32/kernel/irq.c
+++ b/arch/cris/arch-v32/kernel/irq.c
@@ -140,7 +140,7 @@
         spin_lock_irqsave(&irq_lock, flags);
         intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
 
-	/* Remember; 1 let thru, 0 block. */
+	/* Remember; 1 let through, 0 block. */
 	intr_mask &= ~(1 << (irq - FIRST_IRQ));
 
 	REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, intr_mask);
@@ -156,7 +156,7 @@
         spin_lock_irqsave(&irq_lock, flags);
         intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
 
-	/* Remember; 1 let thru, 0 block. */
+	/* Remember; 1 let through, 0 block. */
 	intr_mask |= (1 << (irq - FIRST_IRQ));
 
 	REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, intr_mask);
@@ -308,7 +308,7 @@
 	 */
 	irq_enter();
 
-	/* Get which IRQs that happend. */
+	/* Get which IRQs that happened. */
 	masked = REG_RD_INT(intr_vect, irq_regs[cpu], r_masked_vect);
 
 	/* Calculate new IRQ mask with these IRQs disabled. */
@@ -366,7 +366,7 @@
 	for (i = 0; i < 256; i++)
 		etrax_irv->v[i] = weird_irq;
 
-	/* Point all IRQ's to bad handlers. */
+	/* Point all IRQs to bad handlers. */
 	for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) {
 		irq_desc[j].chip = &crisv32_irq_type;
 		set_exception_vector(i, interrupt[j]);
diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c
index 6326351..b72a155 100644
--- a/arch/cris/arch-v32/kernel/process.c
+++ b/arch/cris/arch-v32/kernel/process.c
@@ -162,7 +162,7 @@
 	/* Put the switch stack right below the pt_regs. */
 	swstack = ((struct switch_stack *) childregs) - 1;
 
-	/* Paramater to ret_from_sys_call. 0 is don't restart the syscall. */
+	/* Parameter to ret_from_sys_call. 0 is don't restart the syscall. */
 	swstack->r9 = 0;
 
 	/*
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index 7cd6ac8..024cc69 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -347,7 +347,7 @@
 /* Grab and setup a signal frame.
  *
  * Basically a lot of state-info is stacked, and arranged for the
- * user-mode program to return to the kernel using either a trampiline
+ * user-mode program to return to the kernel using either a trampoline
  * which performs the syscall sigreturn(), or a provided user-mode
  * trampoline.
   */
@@ -641,7 +641,7 @@
 		user_regs(ti)->spc = 0;
 	}
 	/* FIXME: Filter out false h/w breakpoint hits (i.e. EDA
-	   not withing any configured h/w breakpoint range). Synchronize with
+	   not within any configured h/w breakpoint range). Synchronize with
 	   what already exists for kernel debugging.  */
 	if (((user_regs(ti)->exs & 0xff00) >> 8) == BREAK_8_INTR_VECT) {
 		/* Break 8: subtract 2 from ERP unless in a delay slot. */
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 697494b..171c96e 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -142,7 +142,7 @@
 	return -1;
 }
 
-/* Secondary CPUs starts uing C here. Here we need to setup CPU
+/* Secondary CPUs starts using C here. Here we need to setup CPU
  * specific stuff such as the local timer and the MMU. */
 void __init smp_callin(void)
 {
diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c
index be0a016..2f7e8e2 100644
--- a/arch/cris/arch-v32/kernel/time.c
+++ b/arch/cris/arch-v32/kernel/time.c
@@ -99,7 +99,7 @@
 /* From timer MDS describing the hardware watchdog:
  * 4.3.1 Watchdog Operation
  * The watchdog timer is an 8-bit timer with a configurable start value.
- * Once started the whatchdog counts downwards with a frequency of 763 Hz
+ * Once started the watchdog counts downwards with a frequency of 763 Hz
  * (100/131072 MHz). When the watchdog counts down to 1, it generates an
  * NMI (Non Maskable Interrupt), and when it counts down to 0, it resets the
  * chip.
diff --git a/arch/cris/arch-v32/kernel/traps.c b/arch/cris/arch-v32/kernel/traps.c
index 2462b1e..17fd3db 100644
--- a/arch/cris/arch-v32/kernel/traps.c
+++ b/arch/cris/arch-v32/kernel/traps.c
@@ -105,7 +105,7 @@
 
 /*
  * This gets called from entry.S when the watchdog has bitten. Show something
- * similiar to an Oops dump, and if the kernel if configured to be a nice doggy;
+ * similar to an Oops dump, and if the kernel is configured to be a nice doggy;
  * halt instead of reboot.
  */
 void
diff --git a/arch/cris/arch-v32/lib/dram_init.S b/arch/cris/arch-v32/lib/dram_init.S
index 158b3db..218fbe2 100644
--- a/arch/cris/arch-v32/lib/dram_init.S
+++ b/arch/cris/arch-v32/lib/dram_init.S
@@ -12,7 +12,7 @@
  */
 
 /* Just to be certain the config file is included, we include it here
- * explicitely instead of depending on it being included in the file that
+ * explicitly instead of depending on it being included in the file that
  * uses this code.
  */
 
diff --git a/arch/cris/arch-v32/lib/string.c b/arch/cris/arch-v32/lib/string.c
index 98e282a..6740b2c 100644
--- a/arch/cris/arch-v32/lib/string.c
+++ b/arch/cris/arch-v32/lib/string.c
@@ -41,7 +41,7 @@
      Make sure the compiler is able to make something useful of this.
       As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on. */
 
   register void *return_dst __asm__ ("r10") = pdst;
diff --git a/arch/cris/arch-v32/lib/usercopy.c b/arch/cris/arch-v32/lib/usercopy.c
index f0b0846..04d0cf3 100644
--- a/arch/cris/arch-v32/lib/usercopy.c
+++ b/arch/cris/arch-v32/lib/usercopy.c
@@ -34,7 +34,7 @@
      As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
      FIXME: Comment for old gcc version.  Check.
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on. */
 
   register char *dst __asm__ ("r13") = pdst;
@@ -168,7 +168,7 @@
      As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
      FIXME: Comment for old gcc version.  Check.
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on.  */
 
   register char *dst __asm__ ("r13") = pdst;
@@ -332,7 +332,7 @@
       As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
 
      FIXME: Comment for old gcc version.  Check.
-     If gcc was allright, it really would need no temporaries, and no
+     If gcc was alright, it really would need no temporaries, and no
      stack space to save stuff on. */
 
   register char *dst __asm__ ("r13") = pto;
diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c
index c2d12e9..a076ef6 100644
--- a/arch/cris/arch-v32/mm/tlb.c
+++ b/arch/cris/arch-v32/mm/tlb.c
@@ -30,8 +30,8 @@
  * The TLB can host up to 256 different mm contexts at the same time. The running
  * context is found in the PID register. Each TLB entry contains a page_id that
  * has to match the PID register to give a hit. page_id_map keeps track of which
- * mm's is assigned to which page_id's, making sure it's known when to
- * invalidate TLB entries.
+ * mm is assigned to which page_id, making sure it's known when to invalidate TLB
+ * entries.
  *
  * The last page_id is never running, it is used as an invalid page_id so that
  * it's possible to make TLB entries that will nerver match.
@@ -188,7 +188,7 @@
 	spin_unlock(&mmu_context_lock);
 
 	/*
-	 * Remember the pgd for the fault handlers. Keep a seperate copy of it
+	 * Remember the pgd for the fault handlers. Keep a separate copy of it
 	 * because current and active_mm might be invalid at points where
 	 * there's still a need to derefer the pgd.
 	 */
diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
index 903ea62..5c27ff8 100644
--- a/arch/cris/kernel/irq.c
+++ b/arch/cris/kernel/irq.c
@@ -7,7 +7,7 @@
  *      Authors: Bjorn Wesen (bjornw@axis.com)
  *
  * This file contains the code used by various IRQ handling routines:
- * asking for different IRQ's should be done through these routines
+ * asking for different IRQs should be done through these routines
  * instead of just grabbing them. Thus setups with different IRQ numbers
  * shouldn't result in any weird surprises, and installing new handlers
  * should be easier.
@@ -15,7 +15,7 @@
  */
 
 /*
- * IRQ's are in fact implemented a bit like signal handlers for the kernel.
+ * IRQs are in fact implemented a bit like signal handlers for the kernel.
  * Naturally it's not a 1:1 relation, but there are similarities.
  */
 
@@ -83,9 +83,9 @@
 
 
 /* called by the assembler IRQ entry functions defined in irq.h
- * to dispatch the interrupts to registred handlers
+ * to dispatch the interrupts to registered handlers
  * interrupts are disabled upon entry - depending on if the
- * interrupt was registred with IRQF_DISABLED or not, interrupts
+ * interrupt was registered with IRQF_DISABLED or not, interrupts
  * are re-enabled or not.
  */
 
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index 8aab814..3034f3f 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -13,7 +13,7 @@
  *  Fixed warning.
  *
  *  Revision 1.18  2005/01/12 08:10:14  starvik
- *  Readded the change of frametype when handling kernel page fault fixup
+ *  Re-added the change of frametype when handling kernel page fault fixup
  *  for v10. This is necessary to avoid that the CPU remakes the faulting
  *  access.
  *
@@ -49,7 +49,7 @@
  *
  *  Revision 1.8  2003/07/04 13:02:48  tobiasa
  *  Moved code snippet from arch/cris/mm/fault.c that searches for fixup code
- *  to seperate function in arch-specific files.
+ *  to separate function in arch-specific files.
  *
  *  Revision 1.7  2003/01/22 06:48:38  starvik
  *  Fixed warnings issued by GCC 3.2.1
diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c
index b7842ff..0c833d1 100644
--- a/arch/cris/mm/init.c
+++ b/arch/cris/mm/init.c
@@ -8,7 +8,7 @@
  *
  *  $Log: init.c,v $
  *  Revision 1.11  2004/05/28 09:28:56  starvik
- *  Calculation of loops_per_usec moved because initalization order has changed
+ *  Calculation of loops_per_usec moved because initialization order has changed
  *  in Linux 2.6.
  *
  *  Revision 1.10  2004/05/14 07:58:05  starvik
diff --git a/arch/cris/mm/tlb.c b/arch/cris/mm/tlb.c
index c4a98e2..b7f8de5 100644
--- a/arch/cris/mm/tlb.c
+++ b/arch/cris/mm/tlb.c
@@ -16,7 +16,7 @@
 /* The TLB can host up to 64 different mm contexts at the same time.
  * The running context is R_MMU_CONTEXT, and each TLB entry contains a
  * page_id that has to match to give a hit. In page_id_map, we keep track
- * of which mm's we have assigned which page_id's, so that we know when
+ * of which mm we have assigned to which page_id, so that we know when
  * to invalidate TLB entries.
  *
  * The last page_id is never running - it is used as an invalid page_id
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 74eef71..43153e7 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -375,6 +375,8 @@
 
 source "fs/Kconfig"
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/frv/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c
index ad753c1..9e38f99 100644
--- a/arch/frv/kernel/irq-mb93091.c
+++ b/arch/frv/kernel/irq-mb93091.c
@@ -17,10 +17,10 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/delay.h>
 #include <asm/irq.h>
 #include <asm/irc-regs.h>
diff --git a/arch/frv/kernel/irq-mb93093.c b/arch/frv/kernel/irq-mb93093.c
index e0983f6..3c2752c 100644
--- a/arch/frv/kernel/irq-mb93093.c
+++ b/arch/frv/kernel/irq-mb93093.c
@@ -17,10 +17,10 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/delay.h>
 #include <asm/irq.h>
 #include <asm/irc-regs.h>
diff --git a/arch/frv/kernel/irq-mb93493.c b/arch/frv/kernel/irq-mb93493.c
index c157eef..7754c73 100644
--- a/arch/frv/kernel/irq-mb93493.c
+++ b/arch/frv/kernel/irq-mb93493.c
@@ -17,10 +17,10 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/delay.h>
 #include <asm/irq.h>
 #include <asm/irc-regs.h>
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index c7e59dc..73abae7 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -24,12 +24,12 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/module.h>
+#include <linux/bitops.h>
 
 #include <asm/atomic.h>
 #include <asm/io.h>
 #include <asm/smp.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 #include <asm/delay.h>
@@ -134,7 +134,7 @@
 };
 
 /*
- * handles all normal device IRQ's
+ * handles all normal device IRQs
  * - registers are referred to by the __frame variable (GR28)
  * - IRQ distribution is complicated in this arch because of the many PICs, the
  *   way they work and the way they cascade
diff --git a/arch/frv/kernel/semaphore.c b/arch/frv/kernel/semaphore.c
index 8e182ce..7ee3a14 100644
--- a/arch/frv/kernel/semaphore.c
+++ b/arch/frv/kernel/semaphore.c
@@ -139,7 +139,7 @@
 	waiter = list_entry(sem->wait_list.next, struct sem_waiter, list);
 
 	/* We must be careful not to touch 'waiter' after we set ->task = NULL.
-	 * It is an allocated on the waiter's stack and may become invalid at
+	 * It is allocated on the waiter's stack and may become invalid at
 	 * any time after that point (due to a wakeup from another source).
 	 */
 	list_del_init(&waiter->list);
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index e83e0bc..925fb01 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -66,7 +66,7 @@
 	/*
 	 * Here we are in the timer irq handler. We just have irqs locally
 	 * disabled but we don't know if the timer_bh is running on the other
-	 * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
+	 * CPU. We need to avoid to SMP race with it. NOTE: we don't need
 	 * the irq version of write_lock because as just said we have irq
 	 * locally disabled. -arca
 	 */
@@ -126,7 +126,7 @@
 
 	/* FIX by dqg : Set to zero for platforms that don't have tod */
 	/* without this time is undefined and can overflow time_t, causing  */
-	/* very stange errors */
+	/* very strange errors */
 	year = 1980;
 	mon = day = 1;
 	hour = min = sec = 0;
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index e35f74e..e2e9f57 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -223,6 +223,8 @@
 
 source "fs/Kconfig"
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/h8300/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/h8300/Kconfig.debug b/arch/h8300/Kconfig.debug
index 996d97e..ee671c3 100644
--- a/arch/h8300/Kconfig.debug
+++ b/arch/h8300/Kconfig.debug
@@ -42,16 +42,16 @@
 	  Require eCos/RedBoot
 
 config DEFAULT_CMDLINE
-	bool "Use buildin commandline"
+	bool "Use builtin commandline"
 	default n
 	help
-	  buildin kernel commandline enabled.
+	  builtin kernel commandline enabled.
 
 config KERNEL_COMMAND
 	string "Buildin commmand string"
 	depends on DEFAULT_CMDLINE
 	help
-	  buildin kernel commandline strings.
+	  builtin kernel commandline strings.
 
 config BLKDEV_RESERVE
 	bool "BLKDEV Reserved Memory"
diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c
index 43d21e9..8dec4dd 100644
--- a/arch/h8300/kernel/irq.c
+++ b/arch/h8300/kernel/irq.c
@@ -68,7 +68,7 @@
 }
 
 /*
- * h8300 interrupt controler implementation
+ * h8300 interrupt controller implementation
  */
 struct irq_chip h8300irq_chip = {
 	.name		= "H8300-INTC",
diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c
index 3306382..e37c835 100644
--- a/arch/h8300/kernel/time.c
+++ b/arch/h8300/kernel/time.c
@@ -53,7 +53,7 @@
 
 	/* FIX by dqg : Set to zero for platforms that don't have tod */
 	/* without this time is undefined and can overflow time_t, causing  */
-	/* very stange errors */
+	/* very strange errors */
 	year = 1980;
 	mon = day = 1;
 	hour = min = sec = 0;
diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c
index f971830..f8f7d7ea 100644
--- a/arch/h8300/kernel/traps.c
+++ b/arch/h8300/kernel/traps.c
@@ -5,7 +5,7 @@
  * Cloned from Linux/m68k.
  *
  * No original Copyright holder listed,
- * Probabily original (C) Roman Zippel (assigned DJD, 1999)
+ * Probable original (C) Roman Zippel (assigned DJD, 1999)
  *
  * Copyright 1999-2000 D. Jeff Dionne, <jeff@rt-control.com>
  *
diff --git a/arch/h8300/platform/h8s/ints.c b/arch/h8300/platform/h8s/ints.c
index a71d6e2..551fd5f 100644
--- a/arch/h8300/platform/h8s/ints.c
+++ b/arch/h8300/platform/h8s/ints.c
@@ -179,7 +179,7 @@
 	if (use_kmalloc)
 		irq_handle = kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
 	else {
-		/* use bootmem allocater */
+		/* use bootmem allocator */
 		irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
 		irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000);
 	}
diff --git a/arch/h8300/platform/h8s/ints_h8s.c b/arch/h8300/platform/h8s/ints_h8s.c
index 93395d2..faa8a45 100644
--- a/arch/h8300/platform/h8s/ints_h8s.c
+++ b/arch/h8300/platform/h8s/ints_h8s.c
@@ -63,7 +63,7 @@
 	{H8300_GPIO_P2,H8300_GPIO_B6},{H8300_GPIO_P2,H8300_GPIO_B7},
 };
 
-/* IRQ to GPIO pinno transrate */
+/* IRQ to GPIO pin translation */
 #define IRQ_GPIO_MAP(irqbit,irq,port,bit)			  \
 do {								  \
 	if (*(volatile unsigned short *)ITSR & irqbit) {	  \
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index b84d505..5bed8be 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -227,28 +227,40 @@
 	  If in doubt, say "Y".
 
 config PARAVIRT
-	bool "Paravirtualization support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
+	bool
 	depends on !(X86_VISWS || X86_VOYAGER)
 	help
-	  Paravirtualization is a way of running multiple instances of
-	  Linux on the same machine, under a hypervisor.  This option
-	  changes the kernel so it can modify itself when it is run
-	  under a hypervisor, improving performance significantly.
-	  However, when run without a hypervisor the kernel is
-	  theoretically slower.  If in doubt, say N.
+	  This changes the kernel so it can modify itself when it is run
+	  under a hypervisor, potentially improving performance significantly
+	  over full virtualization.  However, when run without a hypervisor
+	  the kernel is theoretically slower and slightly larger.
+
+menuconfig PARAVIRT_GUEST
+	bool "Paravirtualized guest support"
+	help
+	  Say Y here to get to see options related to running Linux under
+	  various hypervisors.  This option alone does not add any kernel code.
+
+	  If you say N, all options in this submenu will be skipped and disabled.
+
+if PARAVIRT_GUEST
 
 source "arch/x86/xen/Kconfig"
 
 config VMI
-	bool "VMI Paravirt-ops support"
-	depends on PARAVIRT
+	bool "VMI Guest support"
+	select PARAVIRT
+	depends on !(X86_VISWS || X86_VOYAGER)
 	help
 	  VMI provides a paravirtualized interface to the VMware ESX server
 	  (it could be used by other hypervisors in theory too, but is not
 	  at the moment), by linking the kernel to a GPL-ed ROM module
 	  provided by the hypervisor.
 
+source "arch/x86/lguest/Kconfig"
+
+endif
+
 config ACPI_SRAT
 	bool
 	default y
@@ -392,7 +404,7 @@
 	  will look at the machine check registers to see if anything happened.
 	  Non-fatal problems automatically get corrected (but still logged).
 	  Disable this if you don't want to see these messages.
-	  Seeing the messages this option prints out may be indicative of dying hardware,
+	  Seeing the messages this option prints out may be indicative of dying
 	  or out-of-spec (ie, overclocked) hardware.
 	  This option only does something on certain CPUs.
 	  (AMD Athlon/Duron and Intel Pentium 4)
@@ -631,7 +643,7 @@
 	default n if X86_PC
 	default y if (X86_NUMAQ || X86_SUMMIT)
 	help
-	  NUMA support for i386. This is currently high experimental
+	  NUMA support for i386. This is currently highly experimental
 	  and should be only used for kernel development. It might also
 	  cause boot failures.
 
@@ -1080,7 +1092,9 @@
 
 endif # APM
 
-source "arch/x86/kernel/cpu/cpufreq/Kconfig"
+source "arch/x86/kernel/cpu/cpufreq/Kconfig_32"
+
+source "drivers/cpuidle/Kconfig"
 
 endmenu
 
@@ -1256,31 +1270,6 @@
 
 source "fs/Kconfig"
 
-menuconfig INSTRUMENTATION
-	bool "Instrumentation Support"
-	default y
-	---help---
-	  Say Y here to get to see options related to performance measurement,
-	  debugging, and testing. This option alone does not add any kernel code.
-
-	  If you say N, all options in this submenu will be skipped and disabled.
-
-if INSTRUMENTATION
-
-source "arch/x86/oprofile/Kconfig"
-
-config KPROBES
-	bool "Kprobes"
-	depends on KALLSYMS && MODULES
-	help
-	  Kprobes allows you to trap at almost any kernel address and
-	  execute a callback function.  register_kprobe() establishes
-	  a probepoint and specifies the callback.  Kprobes is useful
-	  for kernel debugging, non-intrusive instrumentation and testing.
-	  If in doubt, say "N".
-
-endif # INSTRUMENTATION
-
 source "arch/i386/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index f036d2d..b81cb64 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -99,10 +99,13 @@
 # Xen paravirtualization support
 core-$(CONFIG_XEN)		+= arch/x86/xen/
 
+# lguest paravirtualization support
+core-$(CONFIG_LGUEST_GUEST)	+= arch/x86/lguest/
+
 # default subarch .h files
 mflags-y += -Iinclude/asm-x86/mach-default
 
-head-y := arch/x86/kernel/head_32.o arch/x86/kernel/init_task_32.o
+head-y := arch/x86/kernel/head_32.o arch/x86/kernel/init_task.o
 
 libs-y 					+= arch/x86/lib/
 core-y					+= arch/x86/kernel/ \
@@ -131,9 +134,9 @@
 zImage zlilo zdisk: KBUILD_IMAGE := arch/x86/boot/zImage
 
 zImage bzImage: vmlinux
-	$(Q)mkdir -p $(objtree)/arch/i386/boot
-	$(Q)ln -fsn $(objtree)/arch/x86/boot/bzImage $(objtree)/arch/i386/boot/bzImage
 	$(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
+	$(Q)mkdir -p $(objtree)/arch/i386/boot
+	$(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/i386/boot/bzImage
 
 compressed: zImage
 
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index c60532d..bef4772 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -452,9 +452,9 @@
 config IA64_MC_ERR_INJECT
 	tristate "MC error injection support"
 	help
-	  Selets whether support for MC error injection. By enabling the
-	  support, kernel provide sysfs interface for user application to
-	  call MC error injection PAL procedure to inject various errors.
+	  Adds support for MC error injection. If enabled, the kernel 
+	  will provide a sysfs interface for user applications to
+	  call MC error injection PAL procedures to inject various errors.
 	  This is a useful tool for MCA testing.
 
 	  If you're unsure, do not select this option.
@@ -491,7 +491,7 @@
 	  but it is independent of the system firmware.   And like a reboot
 	  you can start any kernel with it, not just Linux.
 
-	  The name comes from the similiarity to the exec system call.
+	  The name comes from the similarity to the exec system call.
 
 	  It is an ongoing process to be certain the hardware in a machine
 	  is properly shutdown, so do not be surprised if this code does not
@@ -592,20 +592,7 @@
 
 source "arch/ia64/hp/sim/Kconfig"
 
-menu "Instrumentation Support"
-
-source "arch/ia64/oprofile/Kconfig"
-
-config KPROBES
-	bool "Kprobes"
-	depends on KALLSYMS && MODULES
-	help
-	  Kprobes allows you to trap at almost any kernel address and
-	  execute a callback function.  register_kprobe() establishes
-	  a probepoint and specifies the callback.  Kprobes is useful
-	  for kernel debugging, non-intrusive instrumentation and testing.
-	  If in doubt, say "N".
-endmenu
+source "kernel/Kconfig.instrumentation"
 
 source "arch/ia64/Kconfig.debug"
 
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index 449d3e7..75fd90d 100644
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -26,6 +26,7 @@
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=20
+CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 3c95f41..bc859a3 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -246,7 +246,7 @@
 static SBA_INLINE void sba_mark_invalid(struct ioc *, dma_addr_t, size_t);
 static SBA_INLINE void sba_free_range(struct ioc *, dma_addr_t, size_t);
 
-#define sba_sg_address(sg)	(page_address((sg)->page) + (sg)->offset)
+#define sba_sg_address(sg)	sg_virt((sg))
 
 #ifdef FULL_VALID_PDIR
 static u64 prefetch_spill_page;
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index a3a558a..6ef9b52 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -131,7 +131,7 @@
 	stat.fd = desc[sc->device->id];
 
 	scsi_for_each_sg(sc, sl, scsi_sg_count(sc), i) {
-		req.addr = __pa(page_address(sl->page) + sl->offset);
+		req.addr = __pa(sg_virt(sl));
 		req.len  = sl->length;
 		if (DBG)
 			printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
@@ -212,7 +212,7 @@
 		if (!len)
 			break;
 		thislen = min(len, slp->length);
-		memcpy(page_address(slp->page) + slp->offset, buf, thislen);
+		memcpy(sg_virt(slp), buf, thislen);
 		len -= thislen;
 	}
 }
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index a3405b3..d025a22 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -773,7 +773,7 @@
 			if (flags & MAP_SHARED)
 				printk(KERN_INFO
 				       "%s(%d): emulate_mmap() can't share head (addr=0x%lx)\n",
-				       current->comm, current->pid, start);
+				       current->comm, task_pid_nr(current), start);
 			ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags,
 					   off);
 			if (IS_ERR((void *) ret))
@@ -786,7 +786,7 @@
 			if (flags & MAP_SHARED)
 				printk(KERN_INFO
 				       "%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n",
-				       current->comm, current->pid, end);
+				       current->comm, task_pid_nr(current), end);
 			ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags,
 					   (off + len) - offset_in_page(end));
 			if (IS_ERR((void *) ret))
@@ -816,7 +816,7 @@
 
 	if ((flags & MAP_SHARED) && !is_congruent)
 		printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap "
-		       "(addr=0x%lx,off=0x%llx)\n", current->comm, current->pid, start, off);
+		       "(addr=0x%lx,off=0x%llx)\n", current->comm, task_pid_nr(current), start, off);
 
 	DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llx\n", pstart, pend,
 	    is_congruent ? "congruent" : "not congruent", poff);
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 73ca86d..3f7ea13 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -967,7 +967,7 @@
  * to use.  We can allocate partial granules only if the unavailable
  * parts exist, and are WB.
  */
-void
+unsigned long
 efi_memmap_init(unsigned long *s, unsigned long *e)
 {
 	struct kern_memdesc *k, *prev = NULL;
@@ -1084,11 +1084,14 @@
 	/* reserve the memory we are using for kern_memmap */
 	*s = (u64)kern_memmap;
 	*e = (u64)++k;
+
+	return total_mem;
 }
 
 void
 efi_initialize_iomem_resources(struct resource *code_resource,
-			       struct resource *data_resource)
+			       struct resource *data_resource,
+			       struct resource *bss_resource)
 {
 	struct resource *res;
 	void *efi_map_start, *efi_map_end, *p;
@@ -1169,6 +1172,7 @@
 			 */
 			insert_resource(res, code_resource);
 			insert_resource(res, data_resource);
+			insert_resource(res, bss_resource);
 #ifdef CONFIG_KEXEC
                         insert_resource(res, &efi_memmap_res);
                         insert_resource(res, &boot_param_res);
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index f55fa078..59169bf7 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -158,14 +158,14 @@
  */
 #define PROTECT_CTX(c, f) \
 	do {  \
-		DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, current->pid)); \
+		DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, task_pid_nr(current))); \
 		spin_lock_irqsave(&(c)->ctx_lock, f); \
-		DPRINT(("spinlocked ctx %p  by [%d]\n", c, current->pid)); \
+		DPRINT(("spinlocked ctx %p  by [%d]\n", c, task_pid_nr(current))); \
 	} while(0)
 
 #define UNPROTECT_CTX(c, f) \
 	do { \
-		DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, current->pid)); \
+		DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, task_pid_nr(current))); \
 		spin_unlock_irqrestore(&(c)->ctx_lock, f); \
 	} while(0)
 
@@ -227,12 +227,12 @@
 #ifdef PFM_DEBUGGING
 #define DPRINT(a) \
 	do { \
-		if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \
+		if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
 	} while (0)
 
 #define DPRINT_ovfl(a) \
 	do { \
-		if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \
+		if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
 	} while (0)
 #endif
 
@@ -913,7 +913,7 @@
 	unsigned long mask, val, ovfl_mask;
 	int i;
 
-	DPRINT_ovfl(("masking monitoring for [%d]\n", task->pid));
+	DPRINT_ovfl(("masking monitoring for [%d]\n", task_pid_nr(task)));
 
 	ovfl_mask = pmu_conf->ovfl_val;
 	/*
@@ -992,12 +992,12 @@
 	ovfl_mask = pmu_conf->ovfl_val;
 
 	if (task != current) {
-		printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task->pid, current->pid);
+		printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task_pid_nr(task), task_pid_nr(current));
 		return;
 	}
 	if (ctx->ctx_state != PFM_CTX_MASKED) {
 		printk(KERN_ERR "perfmon.%d: task[%d] current[%d] invalid state=%d\n", __LINE__,
-			task->pid, current->pid, ctx->ctx_state);
+			task_pid_nr(task), task_pid_nr(current), ctx->ctx_state);
 		return;
 	}
 	psr = pfm_get_psr();
@@ -1051,7 +1051,8 @@
 		if ((mask & 0x1) == 0UL) continue;
 		ctx->th_pmcs[i] = ctx->ctx_pmcs[i];
 		ia64_set_pmc(i, ctx->th_pmcs[i]);
-		DPRINT(("[%d] pmc[%d]=0x%lx\n", task->pid, i, ctx->th_pmcs[i]));
+		DPRINT(("[%d] pmc[%d]=0x%lx\n",
+					task_pid_nr(task), i, ctx->th_pmcs[i]));
 	}
 	ia64_srlz_d();
 
@@ -1370,7 +1371,7 @@
 
 error_conflict:
 	DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
-  		pfm_sessions.pfs_sys_session[cpu]->pid,
+  		task_pid_nr(pfm_sessions.pfs_sys_session[cpu]),
 		cpu));
 abort:
 	UNLOCK_PFS(flags);
@@ -1442,7 +1443,7 @@
 
 	/* sanity checks */
 	if (task->mm == NULL || size == 0UL || vaddr == NULL) {
-		printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task->pid, task->mm);
+		printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task_pid_nr(task), task->mm);
 		return -EINVAL;
 	}
 
@@ -1459,7 +1460,7 @@
 
 	up_write(&task->mm->mmap_sem);
 	if (r !=0) {
-		printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task->pid, vaddr, size);
+		printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size);
 	}
 
 	DPRINT(("do_unmap(%p, %lu)=%d\n", vaddr, size, r));
@@ -1501,7 +1502,7 @@
 	return 0;
 
 invalid_free:
-	printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", current->pid);
+	printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", task_pid_nr(current));
 	return -EINVAL;
 }
 #endif
@@ -1547,13 +1548,13 @@
 	unsigned long flags;
   	DECLARE_WAITQUEUE(wait, current);
 	if (PFM_IS_FILE(filp) == 0) {
-		printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid);
+		printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current));
 		return -EINVAL;
 	}
 
 	ctx = (pfm_context_t *)filp->private_data;
 	if (ctx == NULL) {
-		printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", current->pid);
+		printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", task_pid_nr(current));
 		return -EINVAL;
 	}
 
@@ -1607,7 +1608,7 @@
 
 		PROTECT_CTX(ctx, flags);
 	}
-	DPRINT(("[%d] back to running ret=%ld\n", current->pid, ret));
+	DPRINT(("[%d] back to running ret=%ld\n", task_pid_nr(current), ret));
   	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&ctx->ctx_msgq_wait, &wait);
 
@@ -1616,7 +1617,7 @@
 	ret = -EINVAL;
 	msg = pfm_get_next_msg(ctx);
 	if (msg == NULL) {
-		printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, current->pid);
+		printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, task_pid_nr(current));
 		goto abort_locked;
 	}
 
@@ -1647,13 +1648,13 @@
 	unsigned int mask = 0;
 
 	if (PFM_IS_FILE(filp) == 0) {
-		printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid);
+		printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current));
 		return 0;
 	}
 
 	ctx = (pfm_context_t *)filp->private_data;
 	if (ctx == NULL) {
-		printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", current->pid);
+		printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", task_pid_nr(current));
 		return 0;
 	}
 
@@ -1692,7 +1693,7 @@
 	ret = fasync_helper (fd, filp, on, &ctx->ctx_async_queue);
 
 	DPRINT(("pfm_fasync called by [%d] on ctx_fd=%d on=%d async_queue=%p ret=%d\n",
-		current->pid,
+		task_pid_nr(current),
 		fd,
 		on,
 		ctx->ctx_async_queue, ret));
@@ -1707,13 +1708,13 @@
 	int ret;
 
 	if (PFM_IS_FILE(filp) == 0) {
-		printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", current->pid);
+		printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", task_pid_nr(current));
 		return -EBADF;
 	}
 
 	ctx = (pfm_context_t *)filp->private_data;
 	if (ctx == NULL) {
-		printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", current->pid);
+		printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", task_pid_nr(current));
 		return -EBADF;
 	}
 	/*
@@ -1759,7 +1760,7 @@
 	if (owner != ctx->ctx_task) {
 		printk(KERN_ERR "perfmon: pfm_syswide_force_stop CPU%d unexpected owner [%d] instead of [%d]\n",
 			smp_processor_id(),
-			owner->pid, ctx->ctx_task->pid);
+			task_pid_nr(owner), task_pid_nr(ctx->ctx_task));
 		return;
 	}
 	if (GET_PMU_CTX() != ctx) {
@@ -1769,7 +1770,7 @@
 		return;
 	}
 
-	DPRINT(("on CPU%d forcing system wide stop for [%d]\n", smp_processor_id(), ctx->ctx_task->pid));	
+	DPRINT(("on CPU%d forcing system wide stop for [%d]\n", smp_processor_id(), task_pid_nr(ctx->ctx_task)));
 	/*
 	 * the context is already protected in pfm_close(), we simply
 	 * need to mask interrupts to avoid a PMU interrupt race on
@@ -1821,7 +1822,7 @@
 
 	ctx = (pfm_context_t *)filp->private_data;
 	if (ctx == NULL) {
-		printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", current->pid);
+		printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", task_pid_nr(current));
 		return -EBADF;
 	}
 
@@ -1969,7 +1970,7 @@
 	
 	ctx = (pfm_context_t *)filp->private_data;
 	if (ctx == NULL) {
-		printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", current->pid);
+		printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", task_pid_nr(current));
 		return -EBADF;
 	}
 
@@ -2066,7 +2067,7 @@
 	 	 */
 		ctx->ctx_state = PFM_CTX_ZOMBIE;
 
-		DPRINT(("zombie ctx for [%d]\n", task->pid));
+		DPRINT(("zombie ctx for [%d]\n", task_pid_nr(task)));
 		/*
 		 * cannot free the context on the spot. deferred until
 		 * the task notices the ZOMBIE state
@@ -2472,7 +2473,7 @@
 	/* invoke and lock buffer format, if found */
 	fmt = pfm_find_buffer_fmt(arg->ctx_smpl_buf_id);
 	if (fmt == NULL) {
-		DPRINT(("[%d] cannot find buffer format\n", task->pid));
+		DPRINT(("[%d] cannot find buffer format\n", task_pid_nr(task)));
 		return -EINVAL;
 	}
 
@@ -2483,7 +2484,7 @@
 
 	ret = pfm_buf_fmt_validate(fmt, task, ctx_flags, cpu, fmt_arg);
 
-	DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task->pid, ctx_flags, cpu, fmt_arg, ret));
+	DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task_pid_nr(task), ctx_flags, cpu, fmt_arg, ret));
 
 	if (ret) goto error;
 
@@ -2605,23 +2606,23 @@
 	 * no kernel task or task not owner by caller
 	 */
 	if (task->mm == NULL) {
-		DPRINT(("task [%d] has not memory context (kernel thread)\n", task->pid));
+		DPRINT(("task [%d] has not memory context (kernel thread)\n", task_pid_nr(task)));
 		return -EPERM;
 	}
 	if (pfm_bad_permissions(task)) {
-		DPRINT(("no permission to attach to  [%d]\n", task->pid));
+		DPRINT(("no permission to attach to  [%d]\n", task_pid_nr(task)));
 		return -EPERM;
 	}
 	/*
 	 * cannot block in self-monitoring mode
 	 */
 	if (CTX_OVFL_NOBLOCK(ctx) == 0 && task == current) {
-		DPRINT(("cannot load a blocking context on self for [%d]\n", task->pid));
+		DPRINT(("cannot load a blocking context on self for [%d]\n", task_pid_nr(task)));
 		return -EINVAL;
 	}
 
 	if (task->exit_state == EXIT_ZOMBIE) {
-		DPRINT(("cannot attach to  zombie task [%d]\n", task->pid));
+		DPRINT(("cannot attach to  zombie task [%d]\n", task_pid_nr(task)));
 		return -EBUSY;
 	}
 
@@ -2631,7 +2632,7 @@
 	if (task == current) return 0;
 
 	if ((task->state != TASK_STOPPED) && (task->state != TASK_TRACED)) {
-		DPRINT(("cannot attach to non-stopped task [%d] state=%ld\n", task->pid, task->state));
+		DPRINT(("cannot attach to non-stopped task [%d] state=%ld\n", task_pid_nr(task), task->state));
 		return -EBUSY;
 	}
 	/*
@@ -3512,7 +3513,7 @@
 
 	if (pmu_conf->use_rr_dbregs == 0) return 0;
 
-	DPRINT(("called for [%d]\n", task->pid));
+	DPRINT(("called for [%d]\n", task_pid_nr(task)));
 
 	/*
 	 * do it only once
@@ -3543,7 +3544,7 @@
 	DPRINT(("ptrace_use_dbregs=%u  sys_use_dbregs=%u by [%d] ret = %d\n",
 		  pfm_sessions.pfs_ptrace_use_dbregs,
 		  pfm_sessions.pfs_sys_use_dbregs,
-		  task->pid, ret));
+		  task_pid_nr(task), ret));
 
 	UNLOCK_PFS(flags);
 
@@ -3568,7 +3569,7 @@
 
 	LOCK_PFS(flags);
 	if (pfm_sessions.pfs_ptrace_use_dbregs == 0) {
-		printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task->pid);
+		printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task_pid_nr(task));
 		ret = -1;
 	}  else {
 		pfm_sessions.pfs_ptrace_use_dbregs--;
@@ -3620,7 +3621,7 @@
 
 	/* sanity check */
 	if (unlikely(task == NULL)) {
-		printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", current->pid);
+		printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", task_pid_nr(current));
 		return -EINVAL;
 	}
 
@@ -3629,7 +3630,7 @@
 		fmt = ctx->ctx_buf_fmt;
 
 		DPRINT(("restarting self %d ovfl=0x%lx\n",
-			task->pid,
+			task_pid_nr(task),
 			ctx->ctx_ovfl_regs[0]));
 
 		if (CTX_HAS_SMPL(ctx)) {
@@ -3653,11 +3654,11 @@
 				pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET);
 
 			if (rst_ctrl.bits.mask_monitoring == 0) {
-				DPRINT(("resuming monitoring for [%d]\n", task->pid));
+				DPRINT(("resuming monitoring for [%d]\n", task_pid_nr(task)));
 
 				if (state == PFM_CTX_MASKED) pfm_restore_monitoring(task);
 			} else {
-				DPRINT(("keeping monitoring stopped for [%d]\n", task->pid));
+				DPRINT(("keeping monitoring stopped for [%d]\n", task_pid_nr(task)));
 
 				// cannot use pfm_stop_monitoring(task, regs);
 			}
@@ -3714,10 +3715,10 @@
 	 * "self-monitoring".
 	 */
 	if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) {
-		DPRINT(("unblocking [%d] \n", task->pid));
+		DPRINT(("unblocking [%d] \n", task_pid_nr(task)));
 		complete(&ctx->ctx_restart_done);
 	} else {
-		DPRINT(("[%d] armed exit trap\n", task->pid));
+		DPRINT(("[%d] armed exit trap\n", task_pid_nr(task)));
 
 		ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_RESET;
 
@@ -3805,7 +3806,7 @@
 	 * don't bother if we are loaded and task is being debugged
 	 */
 	if (is_loaded && (thread->flags & IA64_THREAD_DBG_VALID) != 0) {
-		DPRINT(("debug registers already in use for [%d]\n", task->pid));
+		DPRINT(("debug registers already in use for [%d]\n", task_pid_nr(task)));
 		return -EBUSY;
 	}
 
@@ -3846,7 +3847,7 @@
 	 * is shared by all processes running on it
  	 */
 	if (first_time && can_access_pmu) {
-		DPRINT(("[%d] clearing ibrs, dbrs\n", task->pid));
+		DPRINT(("[%d] clearing ibrs, dbrs\n", task_pid_nr(task)));
 		for (i=0; i < pmu_conf->num_ibrs; i++) {
 			ia64_set_ibr(i, 0UL);
 			ia64_dv_serialize_instruction();
@@ -4035,7 +4036,7 @@
 		return -EBUSY;
 	}
 	DPRINT(("task [%d] ctx_state=%d is_system=%d\n",
-		PFM_CTX_TASK(ctx)->pid,
+		task_pid_nr(PFM_CTX_TASK(ctx)),
 		state,
 		is_system));
 	/*
@@ -4093,7 +4094,7 @@
 		 * monitoring disabled in kernel at next reschedule
 		 */
 		ctx->ctx_saved_psr_up = 0;
-		DPRINT(("task=[%d]\n", task->pid));
+		DPRINT(("task=[%d]\n", task_pid_nr(task)));
 	}
 	return 0;
 }
@@ -4298,11 +4299,12 @@
 
 		if (is_system) {
 			if (pfm_sessions.pfs_ptrace_use_dbregs) {
-				DPRINT(("cannot load [%d] dbregs in use\n", task->pid));
+				DPRINT(("cannot load [%d] dbregs in use\n",
+							task_pid_nr(task)));
 				ret = -EBUSY;
 			} else {
 				pfm_sessions.pfs_sys_use_dbregs++;
-				DPRINT(("load [%d] increased sys_use_dbreg=%u\n", task->pid, pfm_sessions.pfs_sys_use_dbregs));
+				DPRINT(("load [%d] increased sys_use_dbreg=%u\n", task_pid_nr(task), pfm_sessions.pfs_sys_use_dbregs));
 				set_dbregs = 1;
 			}
 		}
@@ -4394,7 +4396,7 @@
 
 			/* allow user level control */
 			ia64_psr(regs)->sp = 0;
-			DPRINT(("clearing psr.sp for [%d]\n", task->pid));
+			DPRINT(("clearing psr.sp for [%d]\n", task_pid_nr(task)));
 
 			SET_LAST_CPU(ctx, smp_processor_id());
 			INC_ACTIVATION();
@@ -4429,7 +4431,7 @@
 		 */
 		SET_PMU_OWNER(task, ctx);
 
-		DPRINT(("context loaded on PMU for [%d]\n", task->pid));
+		DPRINT(("context loaded on PMU for [%d]\n", task_pid_nr(task)));
 	} else {
 		/*
 		 * when not current, task MUST be stopped, so this is safe
@@ -4493,7 +4495,7 @@
 	int prev_state, is_system;
 	int ret;
 
-	DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1));
+	DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task_pid_nr(task) : -1));
 
 	prev_state = ctx->ctx_state;
 	is_system  = ctx->ctx_fl_system;
@@ -4568,7 +4570,7 @@
 		 */
 		ia64_psr(regs)->sp = 1;
 
-		DPRINT(("setting psr.sp for [%d]\n", task->pid));
+		DPRINT(("setting psr.sp for [%d]\n", task_pid_nr(task)));
 	}
 	/*
 	 * save PMDs to context
@@ -4608,7 +4610,7 @@
 	ctx->ctx_fl_can_restart  = 0;
 	ctx->ctx_fl_going_zombie = 0;
 
-	DPRINT(("disconnected [%d] from context\n", task->pid));
+	DPRINT(("disconnected [%d] from context\n", task_pid_nr(task)));
 
 	return 0;
 }
@@ -4631,7 +4633,7 @@
 
 	PROTECT_CTX(ctx, flags);
 
-	DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task->pid));
+	DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task_pid_nr(task)));
 
 	state = ctx->ctx_state;
 	switch(state) {
@@ -4640,13 +4642,13 @@
 	 		 * only comes to this function if pfm_context is not NULL, i.e., cannot
 			 * be in unloaded state
 	 		 */
-			printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task->pid);
+			printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task_pid_nr(task));
 			break;
 		case PFM_CTX_LOADED:
 		case PFM_CTX_MASKED:
 			ret = pfm_context_unload(ctx, NULL, 0, regs);
 			if (ret) {
-				printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, state, ret);
+				printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret);
 			}
 			DPRINT(("ctx unloaded for current state was %d\n", state));
 
@@ -4655,12 +4657,12 @@
 		case PFM_CTX_ZOMBIE:
 			ret = pfm_context_unload(ctx, NULL, 0, regs);
 			if (ret) {
-				printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, state, ret);
+				printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret);
 			}
 			free_ok = 1;
 			break;
 		default:
-			printk(KERN_ERR "perfmon: pfm_exit_thread [%d] unexpected state=%d\n", task->pid, state);
+			printk(KERN_ERR "perfmon: pfm_exit_thread [%d] unexpected state=%d\n", task_pid_nr(task), state);
 			break;
 	}
 	UNPROTECT_CTX(ctx, flags);
@@ -4744,7 +4746,7 @@
 	DPRINT(("context %d state=%d [%d] task_state=%ld must_stop=%d\n",
 		ctx->ctx_fd,
 		state,
-		task->pid,
+		task_pid_nr(task),
 		task->state, PFM_CMD_STOPPED(cmd)));
 
 	/*
@@ -4791,7 +4793,7 @@
 	 */
 	if (PFM_CMD_STOPPED(cmd)) {
 		if ((task->state != TASK_STOPPED) && (task->state != TASK_TRACED)) {
-			DPRINT(("[%d] task not in stopped state\n", task->pid));
+			DPRINT(("[%d] task not in stopped state\n", task_pid_nr(task)));
 			return -EBUSY;
 		}
 		/*
@@ -4884,7 +4886,7 @@
 	 * limit abuse to min page size
 	 */
 	if (unlikely(sz > PFM_MAX_ARGSIZE)) {
-		printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", current->pid, sz);
+		printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", task_pid_nr(current), sz);
 		return -E2BIG;
 	}
 
@@ -5031,11 +5033,11 @@
 {
 	int ret;
 
-	DPRINT(("entering for [%d]\n", current->pid));
+	DPRINT(("entering for [%d]\n", task_pid_nr(current)));
 
 	ret = pfm_context_unload(ctx, NULL, 0, regs);
 	if (ret) {
-		printk(KERN_ERR "pfm_context_force_terminate: [%d] unloaded failed with %d\n", current->pid, ret);
+		printk(KERN_ERR "pfm_context_force_terminate: [%d] unloaded failed with %d\n", task_pid_nr(current), ret);
 	}
 
 	/*
@@ -5072,7 +5074,7 @@
 
 	ctx = PFM_GET_CTX(current);
 	if (ctx == NULL) {
-		printk(KERN_ERR "perfmon: [%d] has no PFM context\n", current->pid);
+		printk(KERN_ERR "perfmon: [%d] has no PFM context\n", task_pid_nr(current));
 		return;
 	}
 
@@ -5269,7 +5271,7 @@
 	DPRINT_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s "
 		     "used_pmds=0x%lx\n",
 			pmc0,
-			task ? task->pid: -1,
+			task ? task_pid_nr(task): -1,
 			(regs ? regs->cr_iip : 0),
 			CTX_OVFL_NOBLOCK(ctx) ? "nonblocking" : "blocking",
 			ctx->ctx_used_pmds[0]));
@@ -5458,7 +5460,7 @@
 	}
 
 	DPRINT_ovfl(("owner [%d] pending=%ld reason=%u ovfl_pmds=0x%lx ovfl_notify=0x%lx masked=%d\n",
-			GET_PMU_OWNER() ? GET_PMU_OWNER()->pid : -1,
+			GET_PMU_OWNER() ? task_pid_nr(GET_PMU_OWNER()) : -1,
 			PFM_GET_WORK_PENDING(task),
 			ctx->ctx_fl_trap_reason,
 			ovfl_pmds,
@@ -5483,7 +5485,7 @@
 sanity_check:
 	printk(KERN_ERR "perfmon: CPU%d overflow handler [%d] pmc0=0x%lx\n",
 			smp_processor_id(),
-			task ? task->pid : -1,
+			task ? task_pid_nr(task) : -1,
 			pmc0);
 	return;
 
@@ -5516,7 +5518,7 @@
 	 *
 	 * Overall pretty hairy stuff....
 	 */
-	DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task->pid: -1));
+	DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task_pid_nr(task): -1));
 	pfm_clear_psr_up();
 	ia64_psr(regs)->up = 0;
 	ia64_psr(regs)->sp = 1;
@@ -5577,13 +5579,13 @@
 
 report_spurious1:
 	printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d has no PFM context\n",
-		this_cpu, task->pid);
+		this_cpu, task_pid_nr(task));
 	pfm_unfreeze_pmu();
 	return -1;
 report_spurious2:
 	printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d, invalid flag\n", 
 		this_cpu, 
-		task->pid);
+		task_pid_nr(task));
 	pfm_unfreeze_pmu();
 	return -1;
 }
@@ -5870,7 +5872,8 @@
 	ia64_psr(regs)->sp = 1;
 
 	if (GET_PMU_OWNER() == task) {
-		DPRINT(("cleared ownership for [%d]\n", ctx->ctx_task->pid));
+		DPRINT(("cleared ownership for [%d]\n",
+					task_pid_nr(ctx->ctx_task)));
 		SET_PMU_OWNER(NULL, NULL);
 	}
 
@@ -5882,7 +5885,7 @@
 	task->thread.pfm_context  = NULL;
 	task->thread.flags       &= ~IA64_THREAD_PM_VALID;
 
-	DPRINT(("force cleanup for [%d]\n",  task->pid));
+	DPRINT(("force cleanup for [%d]\n",  task_pid_nr(task)));
 }
 
 
@@ -6426,7 +6429,7 @@
 
 		if (PMD_IS_COUNTING(i)) {
 			DPRINT(("[%d] pmd[%d] ctx_pmd=0x%lx hw_pmd=0x%lx\n",
-				task->pid,
+				task_pid_nr(task),
 				i,
 				ctx->ctx_pmds[i].val,
 				val & ovfl_val));
@@ -6448,11 +6451,11 @@
 			 */
 			if (pmc0 & (1UL << i)) {
 				val += 1 + ovfl_val;
-				DPRINT(("[%d] pmd[%d] overflowed\n", task->pid, i));
+				DPRINT(("[%d] pmd[%d] overflowed\n", task_pid_nr(task), i));
 			}
 		}
 
-		DPRINT(("[%d] ctx_pmd[%d]=0x%lx  pmd_val=0x%lx\n", task->pid, i, val, pmd_val));
+		DPRINT(("[%d] ctx_pmd[%d]=0x%lx  pmd_val=0x%lx\n", task_pid_nr(task), i, val, pmd_val));
 
 		if (is_self) ctx->th_pmds[i] = pmd_val;
 
@@ -6793,14 +6796,14 @@
 	printk("CPU%d from %s() current [%d] iip=0x%lx %s\n", 
 		this_cpu, 
 		from, 
-		current->pid, 
+		task_pid_nr(current),
 		regs->cr_iip,
 		current->comm);
 
 	task = GET_PMU_OWNER();
 	ctx  = GET_PMU_CTX();
 
-	printk("->CPU%d owner [%d] ctx=%p\n", this_cpu, task ? task->pid : -1, ctx);
+	printk("->CPU%d owner [%d] ctx=%p\n", this_cpu, task ? task_pid_nr(task) : -1, ctx);
 
 	psr = pfm_get_psr();
 
@@ -6848,7 +6851,7 @@
 {
 	struct thread_struct *thread;
 
-	DPRINT(("perfmon: pfm_inherit clearing state for [%d]\n", task->pid));
+	DPRINT(("perfmon: pfm_inherit clearing state for [%d]\n", task_pid_nr(task)));
 
 	thread = &task->thread;
 
diff --git a/arch/ia64/kernel/perfmon_default_smpl.c b/arch/ia64/kernel/perfmon_default_smpl.c
index ff80eab..a7af1cb 100644
--- a/arch/ia64/kernel/perfmon_default_smpl.c
+++ b/arch/ia64/kernel/perfmon_default_smpl.c
@@ -44,11 +44,11 @@
 	int ret = 0;
 
 	if (data == NULL) {
-		DPRINT(("[%d] no argument passed\n", task->pid));
+		DPRINT(("[%d] no argument passed\n", task_pid_nr(task)));
 		return -EINVAL;
 	}
 
-	DPRINT(("[%d] validate flags=0x%x CPU%d\n", task->pid, flags, cpu));
+	DPRINT(("[%d] validate flags=0x%x CPU%d\n", task_pid_nr(task), flags, cpu));
 
 	/*
 	 * must hold at least the buffer header + one minimally sized entry
@@ -88,7 +88,7 @@
 	hdr->hdr_count        = 0UL;
 
 	DPRINT(("[%d] buffer=%p buf_size=%lu hdr_size=%lu hdr_version=%u cur_offs=%lu\n",
-		task->pid,
+		task_pid_nr(task),
 		buf,
 		hdr->hdr_buf_size,
 		sizeof(*hdr),
@@ -245,7 +245,7 @@
 static int
 default_exit(struct task_struct *task, void *buf, struct pt_regs *regs)
 {
-	DPRINT(("[%d] exit(%p)\n", task->pid, buf));
+	DPRINT(("[%d] exit(%p)\n", task_pid_nr(task), buf));
 	return 0;
 }
 
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index c613fc0..2418289 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -105,7 +105,8 @@
 	unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
 
 	print_modules();
-	printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm);
+	printk("\nPid: %d, CPU %d, comm: %20s\n", task_pid_nr(current),
+			smp_processor_id(), current->comm);
 	printk("psr : %016lx ifs : %016lx ip  : [<%016lx>]    %s\n",
 	       regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
 	print_symbol("ip is at %s\n", ip);
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index c5cfcfa..ae6c3c0 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -90,7 +90,12 @@
 	.name	= "Kernel code",
 	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM
 };
-extern char _text[], _end[], _etext[];
+
+static struct resource bss_resource = {
+	.name	= "Kernel bss",
+	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM
+};
+extern char _text[], _end[], _etext[], _edata[], _bss[];
 
 unsigned long ia64_max_cacheline_size;
 
@@ -200,14 +205,59 @@
 	code_resource.start = ia64_tpa(_text);
 	code_resource.end   = ia64_tpa(_etext) - 1;
 	data_resource.start = ia64_tpa(_etext);
-	data_resource.end   = ia64_tpa(_end) - 1;
-	efi_initialize_iomem_resources(&code_resource, &data_resource);
+	data_resource.end   = ia64_tpa(_edata) - 1;
+	bss_resource.start  = ia64_tpa(_bss);
+	bss_resource.end    = ia64_tpa(_end) - 1;
+	efi_initialize_iomem_resources(&code_resource, &data_resource,
+			&bss_resource);
 
 	return 0;
 }
 
 __initcall(register_memory);
 
+
+#ifdef CONFIG_KEXEC
+static void __init setup_crashkernel(unsigned long total, int *n)
+{
+	unsigned long long base = 0, size = 0;
+	int ret;
+
+	ret = parse_crashkernel(boot_command_line, total,
+			&size, &base);
+	if (ret == 0 && size > 0) {
+		if (!base) {
+			sort_regions(rsvd_region, *n);
+			base = kdump_find_rsvd_region(size,
+					rsvd_region, *n);
+		}
+		if (base != ~0UL) {
+			printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+					"for crashkernel (System RAM: %ldMB)\n",
+					(unsigned long)(size >> 20),
+					(unsigned long)(base >> 20),
+					(unsigned long)(total >> 20));
+			rsvd_region[*n].start =
+				(unsigned long)__va(base);
+			rsvd_region[*n].end =
+				(unsigned long)__va(base + size);
+			(*n)++;
+			crashk_res.start = base;
+			crashk_res.end = base + size - 1;
+		}
+	}
+	efi_memmap_res.start = ia64_boot_param->efi_memmap;
+	efi_memmap_res.end = efi_memmap_res.start +
+		ia64_boot_param->efi_memmap_size;
+	boot_param_res.start = __pa(ia64_boot_param);
+	boot_param_res.end = boot_param_res.start +
+		sizeof(*ia64_boot_param);
+}
+#else
+static inline void __init setup_crashkernel(unsigned long total, int *n)
+{}
+#endif
+
 /**
  * reserve_memory - setup reserved memory areas
  *
@@ -219,6 +269,7 @@
 reserve_memory (void)
 {
 	int n = 0;
+	unsigned long total_memory;
 
 	/*
 	 * none of the entries in this table overlap
@@ -254,50 +305,11 @@
 		n++;
 #endif
 
-	efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
+	total_memory = efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
 	n++;
 
-#ifdef CONFIG_KEXEC
-	/* crashkernel=size@offset specifies the size to reserve for a crash
-	 * kernel. If offset is 0, then it is determined automatically.
-	 * By reserving this memory we guarantee that linux never set's it
-	 * up as a DMA target.Useful for holding code to do something
-	 * appropriate after a kernel panic.
-	 */
-	{
-		char *from = strstr(boot_command_line, "crashkernel=");
-		unsigned long base, size;
-		if (from) {
-			size = memparse(from + 12, &from);
-			if (*from == '@')
-				base = memparse(from+1, &from);
-			else
-				base = 0;
-			if (size) {
-				if (!base) {
-					sort_regions(rsvd_region, n);
-					base = kdump_find_rsvd_region(size,
-							      	rsvd_region, n);
-					}
-				if (base != ~0UL) {
-					rsvd_region[n].start =
-						(unsigned long)__va(base);
-					rsvd_region[n].end =
-						(unsigned long)__va(base + size);
-					n++;
-					crashk_res.start = base;
-					crashk_res.end = base + size - 1;
-				}
-			}
-		}
-		efi_memmap_res.start = ia64_boot_param->efi_memmap;
-                efi_memmap_res.end = efi_memmap_res.start +
-                        ia64_boot_param->efi_memmap_size;
-                boot_param_res.start = __pa(ia64_boot_param);
-                boot_param_res.end = boot_param_res.start +
-                        sizeof(*ia64_boot_param);
-	}
-#endif
+	setup_crashkernel(total_memory, &n);
+
 	/* end of memory marker */
 	rsvd_region[n].start = ~0UL;
 	rsvd_region[n].end   = ~0UL;
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index aeec818..cdb64cc 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -227,7 +227,7 @@
 	si.si_signo = SIGSEGV;
 	si.si_errno = 0;
 	si.si_code = SI_KERNEL;
-	si.si_pid = current->pid;
+	si.si_pid = task_pid_vnr(current);
 	si.si_uid = current->uid;
 	si.si_addr = sc;
 	force_sig_info(SIGSEGV, &si, current);
@@ -332,7 +332,7 @@
 	si.si_signo = SIGSEGV;
 	si.si_errno = 0;
 	si.si_code = SI_KERNEL;
-	si.si_pid = current->pid;
+	si.si_pid = task_pid_vnr(current);
 	si.si_uid = current->uid;
 	si.si_addr = addr;
 	force_sig_info(SIGSEGV, &si, current);
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 98cfc90..2bb8421 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -371,6 +371,11 @@
 		ia64_printk_clock = ia64_itc_printk_clock;
 }
 
+/* IA64 doesn't cache the timezone */
+void update_vsyscall_tz(void)
+{
+}
+
 void update_vsyscall(struct timespec *wall, struct clocksource *c)
 {
         unsigned long flags;
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index 3aeaf15..78d65cb 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -61,7 +61,7 @@
 
 	if (++die.lock_owner_depth < 3) {
 		printk("%s[%d]: %s %ld [%d]\n",
-			current->comm, current->pid, str, err, ++die_counter);
+		current->comm, task_pid_nr(current), str, err, ++die_counter);
 		(void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
 		show_regs(regs);
   	} else
@@ -315,7 +315,7 @@
 				last.time = current_jiffies + 5 * HZ;
 				printk(KERN_WARNING
 		       			"%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
-		       			current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
+		       			current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr);
 			}
 		}
 	}
@@ -453,7 +453,7 @@
 		if (code == 8) {
 # ifdef CONFIG_IA64_PRINT_HAZARDS
 			printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
-			       current->comm, current->pid,
+			       current->comm, task_pid_nr(current),
 			       regs.cr_iip + ia64_psr(&regs)->ri, regs.pr);
 # endif
 			return;
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index fe6aa5a..2173de9 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -1340,7 +1340,8 @@
 			size_t len;
 
 			len = sprintf(buf, "%s(%d): unaligned access to 0x%016lx, "
-				      "ip=0x%016lx\n\r", current->comm, current->pid,
+				      "ip=0x%016lx\n\r", current->comm,
+				      task_pid_nr(current),
 				      ifa, regs->cr_iip + ipsr->ri);
 			/*
 			 * Don't call tty_write_message() if we're in the kernel; we might
@@ -1363,7 +1364,7 @@
 				       "administrator\n"
 				       "echo 0 > /proc/sys/kernel/ignore-"
 				       "unaligned-usertrap to re-enable\n",
-				       current->comm, current->pid);
+				       current->comm, task_pid_nr(current));
 			}
 		}
 	} else {
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 32f2625..7571076 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -274,7 +274,7 @@
 
   out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 3e10152..c6c19bf 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -127,8 +127,8 @@
 		vma->vm_mm = current->mm;
 		vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
 		vma->vm_end = vma->vm_start + PAGE_SIZE;
-		vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
 		vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
+		vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
 		down_write(&current->mm->mmap_sem);
 		if (insert_vm_struct(current->mm, vma)) {
 			up_write(&current->mm->mmap_sem);
diff --git a/arch/ia64/oprofile/Kconfig b/arch/ia64/oprofile/Kconfig
deleted file mode 100644
index 97271ab..0000000
--- a/arch/ia64/oprofile/Kconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  Due to firmware bugs, you may need to use the "nohalt" boot
-	  option if you're using OProfile with the hardware performance
-	  counters.
-
-	  If unsure, say N.
-
diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c
index e58fcad..a5df672 100644
--- a/arch/ia64/sn/kernel/xpnet.c
+++ b/arch/ia64/sn/kernel/xpnet.c
@@ -269,8 +269,9 @@
 	skb->protocol = eth_type_trans(skb, xpnet_device);
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-	dev_dbg(xpnet, "passing skb to network layer; \n\tskb->head=0x%p "
-		"skb->data=0x%p skb->tail=0x%p skb->end=0x%p skb->len=%d\n",
+	dev_dbg(xpnet, "passing skb to network layer\n"
+		KERN_DEBUG "\tskb->head=0x%p skb->data=0x%p skb->tail=0x%p "
+		"skb->end=0x%p skb->len=%d\n",
 		(void *)skb->head, (void *)skb->data, skb_tail_pointer(skb),
 		skb_end_pointer(skb), skb->len);
 
@@ -576,10 +577,10 @@
 		msg->tailout_ignore = end_addr - (u64)skb_tail_pointer(skb);
 		msg->buf_pa = __pa(start_addr);
 
-		dev_dbg(xpnet, "sending XPC message to %d:%d\nmsg->buf_pa="
-			"0x%lx, msg->size=%u, msg->leadin_ignore=%u, "
-			"msg->tailout_ignore=%u\n", dest_partid,
-			XPC_NET_CHANNEL, msg->buf_pa, msg->size,
+		dev_dbg(xpnet, "sending XPC message to %d:%d\n"
+			KERN_DEBUG "msg->buf_pa=0x%lx, msg->size=%u, "
+			"msg->leadin_ignore=%u, msg->tailout_ignore=%u\n",
+			dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size,
 			msg->leadin_ignore, msg->tailout_ignore);
 
 
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index ecd8a52..511db2f 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -16,7 +16,7 @@
 #include <asm/sn/pcidev.h>
 #include <asm/sn/sn_sal.h>
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)	(sg_virt((sg)))
 #define SG_ENT_PHYS_ADDRESS(SG)	virt_to_phys(SG_ENT_VIRT_ADDRESS(SG))
 
 /**
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index bd5fe76..ab9a264 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -426,7 +426,7 @@
 
 source "fs/Kconfig"
 
-source "arch/m32r/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/m32r/Kconfig.debug"
 
diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c
index f8d8650..d0c5b0b 100644
--- a/arch/m32r/kernel/irq.c
+++ b/arch/m32r/kernel/irq.c
@@ -71,7 +71,7 @@
 }
 
 /*
- * do_IRQ handles all normal device IRQ's (the special
+ * do_IRQ handles all normal device IRQs (the special
  * SMP cross-CPU interrupts have their own specific
  * handlers).
  */
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index 916faf6..a753d79 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -358,7 +358,7 @@
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 	if (signr > 0) {
-		/* Reenable any watchpoints before delivering the
+		/* Re-enable any watchpoints before delivering the
 		 * signal to user space. The processor register will
 		 * have been cleared if the watchpoint triggered
 		 * inside the kernel.
diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c
index 3601291..c837bc13 100644
--- a/arch/m32r/kernel/smp.c
+++ b/arch/m32r/kernel/smp.c
@@ -202,7 +202,7 @@
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* TLB flush request Routins                                                 */
+/* TLB flush request Routines                                                */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
 /*==========================================================================*
@@ -378,7 +378,7 @@
  * Name:         flush_tlb_others
  *
  * Description:  This routine requests other CPU to execute flush TLB.
- *               1.Setup parmeters.
+ *               1.Setup parameters.
  *               2.Send 'INVALIDATE_TLB_IPI' to other CPU.
  *                 Request other CPU to execute 'smp_invalidate_interrupt()'.
  *               3.Wait for other CPUs operation finished.
@@ -502,7 +502,7 @@
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Stop CPU request Routins                                                 */
+/* Stop CPU request Routines                                                 */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
 /*==========================================================================*
@@ -566,7 +566,7 @@
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Call function Routins                                                     */
+/* Call function Routines                                                    */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
 /*==========================================================================*
@@ -690,7 +690,7 @@
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Timer Routins                                                             */
+/* Timer Routines                                                            */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
 /*==========================================================================*
@@ -802,7 +802,7 @@
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Send IPI Routins                                                          */
+/* Send IPI Routines                                                         */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
 /*==========================================================================*
@@ -814,7 +814,7 @@
  *
  * Arguments:    ipi_num - Number of IPI
  *               try -  0 : Send IPI certainly.
- *                     !0 : The following IPI is not sended when Target CPU
+ *                     !0 : The following IPI is not sent when Target CPU
  *                          has not received the before IPI.
  *
  * Returns:      void (cannot fail)
@@ -844,7 +844,7 @@
  * Arguments:    cpu_mask - Bitmap of target CPUs logical ID
  *               ipi_num - Number of IPI
  *               try -  0 : Send IPI certainly.
- *                     !0 : The following IPI is not sended when Target CPU
+ *                     !0 : The following IPI is not sent when Target CPU
  *                          has not received the before IPI.
  *
  * Returns:      void (cannot fail)
@@ -885,7 +885,7 @@
  * Arguments:    cpu_mask - Bitmap of target CPUs physical ID
  *               ipi_num - Number of IPI
  *               try -  0 : Send IPI certainly.
- *                     !0 : The following IPI is not sended when Target CPU
+ *                     !0 : The following IPI is not sent when Target CPU
  *                          has not received the before IPI.
  *
  * Returns:      IPICRi regster value.
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index 9dae410..0e383da 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -133,7 +133,7 @@
 static void unmap_cpu_to_physid(int, int);
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Boot up APs Routins : BSP                                                 */
+/* Boot up APs Routines : BSP                                                */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 void __devinit smp_prepare_boot_cpu(void)
 {
@@ -404,7 +404,7 @@
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Activate a secondary processor Routins                                    */
+/* Activate a secondary processor Routines                                   */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
 /*==========================================================================*
@@ -509,7 +509,7 @@
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Boot up CPUs common Routins                                               */
+/* Boot up CPUs common Routines                                              */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 static void __init show_mp_info(int nr_cpu)
 {
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
index 0fc2efe..6d7a80f 100644
--- a/arch/m32r/kernel/sys_m32r.c
+++ b/arch/m32r/kernel/sys_m32r.c
@@ -214,7 +214,7 @@
 
 asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
 {
-	/* This should flush more selectivly ...  */
+	/* This should flush more selectively ...  */
 	_flush_cache_all();
 	return 0;
 }
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c
index 97e0b1c..89ba4a0 100644
--- a/arch/m32r/kernel/traps.c
+++ b/arch/m32r/kernel/traps.c
@@ -196,7 +196,7 @@
 		printk("SPI: %08lx\n", sp);
 	}
 	printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
-		current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current);
+		current->comm, task_pid_nr(current), 0xffff & i, 4096+(unsigned long)current);
 
 	/*
 	 * When in-kernel, we also print out the stack and code at the
diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c
index 70a766a..4a71df4 100644
--- a/arch/m32r/mm/fault.c
+++ b/arch/m32r/mm/fault.c
@@ -271,7 +271,7 @@
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (is_init(tsk)) {
+	if (is_global_init(tsk)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
diff --git a/arch/m32r/oprofile/Kconfig b/arch/m32r/oprofile/Kconfig
deleted file mode 100644
index 19d3773..0000000
--- a/arch/m32r/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
-endmenu
-
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 20a9c08..01dee84 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -683,6 +683,8 @@
 
 source "fs/Kconfig"
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/m68k/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/m68k/amiga/pcmcia.c b/arch/m68k/amiga/pcmcia.c
index fc57c6e..186662c 100644
--- a/arch/m68k/amiga/pcmcia.c
+++ b/arch/m68k/amiga/pcmcia.c
@@ -33,7 +33,7 @@
 
 
 /* copy a tuple, including tuple header. return nb bytes copied */
-/* be carefull as this may trigger a GAYLE_IRQ_WR interrupt ! */
+/* be careful as this may trigger a GAYLE_IRQ_WR interrupt ! */
 
 int pcmcia_copy_tuple(unsigned char tuple_id, void *tuple, int max_len)
 {
diff --git a/arch/m68k/ifpsp060/CHANGES b/arch/m68k/ifpsp060/CHANGES
index c1e712d..ba96596 100644
--- a/arch/m68k/ifpsp060/CHANGES
+++ b/arch/m68k/ifpsp060/CHANGES
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/MISC b/arch/m68k/ifpsp060/MISC
index b7e644b..1a63913 100644
--- a/arch/m68k/ifpsp060/MISC
+++ b/arch/m68k/ifpsp060/MISC
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/README b/arch/m68k/ifpsp060/README
index e3bced4..f6f8f5c 100644
--- a/arch/m68k/ifpsp060/README
+++ b/arch/m68k/ifpsp060/README
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/TEST.DOC b/arch/m68k/ifpsp060/TEST.DOC
index 5e5900c..1ba3aef 100644
--- a/arch/m68k/ifpsp060/TEST.DOC
+++ b/arch/m68k/ifpsp060/TEST.DOC
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/fplsp.doc b/arch/m68k/ifpsp060/fplsp.doc
index fb637c4..89730a9 100644
--- a/arch/m68k/ifpsp060/fplsp.doc
+++ b/arch/m68k/ifpsp060/fplsp.doc
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/fpsp.doc b/arch/m68k/ifpsp060/fpsp.doc
index 4083152..23d513f 100644
--- a/arch/m68k/ifpsp060/fpsp.doc
+++ b/arch/m68k/ifpsp060/fpsp.doc
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/fskeleton.S b/arch/m68k/ifpsp060/fskeleton.S
index a45a4ff..0a1ae4f 100644
--- a/arch/m68k/ifpsp060/fskeleton.S
+++ b/arch/m68k/ifpsp060/fskeleton.S
@@ -4,7 +4,7 @@
 |M68060 Software Package
 |Production Release P1.00 -- October 10, 1994
 |
-|M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+|M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 |
 |THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 |To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/ilsp.doc b/arch/m68k/ifpsp060/ilsp.doc
index f6fae6d..4e6292f 100644
--- a/arch/m68k/ifpsp060/ilsp.doc
+++ b/arch/m68k/ifpsp060/ilsp.doc
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/iskeleton.S b/arch/m68k/ifpsp060/iskeleton.S
index b2dbdf5..91a9c65 100644
--- a/arch/m68k/ifpsp060/iskeleton.S
+++ b/arch/m68k/ifpsp060/iskeleton.S
@@ -4,7 +4,7 @@
 |M68060 Software Package
 |Production Release P1.00 -- October 10, 1994
 |
-|M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+|M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 |
 |THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 |To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/isp.doc b/arch/m68k/ifpsp060/isp.doc
index 5a90fde..9dadd72 100644
--- a/arch/m68k/ifpsp060/isp.doc
+++ b/arch/m68k/ifpsp060/isp.doc
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/os.S b/arch/m68k/ifpsp060/os.S
index aa4df87..7a0d6e4 100644
--- a/arch/m68k/ifpsp060/os.S
+++ b/arch/m68k/ifpsp060/os.S
@@ -4,7 +4,7 @@
 |M68060 Software Package
 |Production Release P1.00 -- October 10, 1994
 |
-|M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+|M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 |
 |THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 |To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/fplsp.S b/arch/m68k/ifpsp060/src/fplsp.S
index fdb79b9..3b7ea2d 100644
--- a/arch/m68k/ifpsp060/src/fplsp.S
+++ b/arch/m68k/ifpsp060/src/fplsp.S
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/fpsp.S b/arch/m68k/ifpsp060/src/fpsp.S
index 3b597a9..6c1a9a2 100644
--- a/arch/m68k/ifpsp060/src/fpsp.S
+++ b/arch/m68k/ifpsp060/src/fpsp.S
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/ftest.S b/arch/m68k/ifpsp060/src/ftest.S
index 2edcbae..1f94791 100644
--- a/arch/m68k/ifpsp060/src/ftest.S
+++ b/arch/m68k/ifpsp060/src/ftest.S
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/ilsp.S b/arch/m68k/ifpsp060/src/ilsp.S
index afa7422..970abaf 100644
--- a/arch/m68k/ifpsp060/src/ilsp.S
+++ b/arch/m68k/ifpsp060/src/ilsp.S
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/isp.S b/arch/m68k/ifpsp060/src/isp.S
index b269091..6dccda7 100644
--- a/arch/m68k/ifpsp060/src/isp.S
+++ b/arch/m68k/ifpsp060/src/isp.S
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/itest.S b/arch/m68k/ifpsp060/src/itest.S
index ba4a30c..beca47e 100644
--- a/arch/m68k/ifpsp060/src/itest.S
+++ b/arch/m68k/ifpsp060/src/itest.S
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/pfpsp.S b/arch/m68k/ifpsp060/src/pfpsp.S
index 0c997c4..51b9f7d 100644
--- a/arch/m68k/ifpsp060/src/pfpsp.S
+++ b/arch/m68k/ifpsp060/src/pfpsp.S
@@ -4,7 +4,7 @@
 M68060 Software Package
 Production Release P1.00 -- October 10, 1994
 
-M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
 
 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 9d4e4b5..ef490e1 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -121,7 +121,7 @@
 	int i;
 
 	for (i = 0; i < nents; sg++, i++) {
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_address = sg_phys(sg);
 		dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
 	}
 	return nents;
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index 4e2752a..97f556f 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -900,7 +900,7 @@
 	       regs->d4, regs->d5, regs->a0, regs->a1);
 
 	printk("Process %s (pid: %d, task=%p)\n",
-		current->comm, current->pid, current);
+		current->comm, task_pid_nr(current), current);
 	addr = (unsigned long)&fp->un;
 	printk("Frame format=%X ", regs->format);
 	switch (regs->format) {
@@ -1038,7 +1038,7 @@
 				fp->un.fmtb.daddr, space_names[ssw & DFC],
 				fp->ptregs.pc);
 	}
-	printk ("Current process id is %d\n", current->pid);
+	printk ("Current process id is %d\n", task_pid_nr(current));
 	die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
 }
 
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 8547dbc..01b468b 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -284,7 +284,7 @@
 	},
 
 	/*
-	 *	Weirdified MacII hardware - all subtley different. Gee thanks
+	 *	Weirdified MacII hardware - all subtly different. Gee thanks
 	 *	Apple. All these boxes seem to have VIA2 in a different place to
 	 *	the MacII (+1A000 rather than +4000)
 	 * CSA: see http://developer.apple.com/technotes/hw/hw_09.html
@@ -707,7 +707,7 @@
 	 * All of these probably have onboard SONIC in the Dock which
 	 * means we'll have to probe for it eventually.
 	 *
-	 * Are these reallly MAC_VIA_IIci? The developer notes for the
+	 * Are these really MAC_VIA_IIci? The developer notes for the
 	 * Duos show pretty much the same custom parts as in most of
 	 * the other PowerBooks which would imply MAC_VIA_QUADRA.
 	 */
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c
index 0cea21f..5b2799e 100644
--- a/arch/m68k/mac/iop.c
+++ b/arch/m68k/mac/iop.c
@@ -100,7 +100,7 @@
  * finished; this function moves the message state to MSG_COMPLETE and signals
  * the IOP. This two-step process is provided to allow the handler to defer
  * message processing to a bottom-half handler if the processing will take
- * a signifigant amount of time (handlers are called at interrupt time so they
+ * a significant amount of time (handlers are called at interrupt time so they
  * should execute quickly.)
  */
 
@@ -120,7 +120,7 @@
 
 /*#define DEBUG_IOP*/
 
-/* Set to nonezero if the IOPs are present. Set by iop_init() */
+/* Set to non-zero if the IOPs are present. Set by iop_init() */
 
 int iop_scc_present,iop_ism_present;
 
diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c
index d7be169..50603d3 100644
--- a/arch/m68k/mac/oss.c
+++ b/arch/m68k/mac/oss.c
@@ -8,7 +8,7 @@
  *
  * 990502 (jmt) - Major rewrite for new interrupt architecture as well as some
  *		  recent insights into OSS operational details.
- * 990610 (jmt) - Now taking fulll advantage of the OSS. Interrupts are mapped
+ * 990610 (jmt) - Now taking full advantage of the OSS. Interrupts are mapped
  *		  to mostly match the A/UX interrupt scheme supported on the
  *		  VIA side. Also added support for enabling the ISM irq again
  *		  since we now have a functional IOP manager.
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index d5cac72..8df270e 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -1,7 +1,7 @@
 /*
  *	6522 Versatile Interface Adapter (VIA)
  *
- *	There are two of these on the Mac II. Some IRQ's are vectored
+ *	There are two of these on the Mac II. Some IRQs are vectored
  *	via them as are assorted bits and bobs - eg RTC, ADB.
  *
  * CSA: Motorola seems to have removed documentation on the 6522 from
diff --git a/arch/m68k/math-emu/fp_log.c b/arch/m68k/math-emu/fp_log.c
index 87b4f01..b1033ae 100644
--- a/arch/m68k/math-emu/fp_log.c
+++ b/arch/m68k/math-emu/fp_log.c
@@ -65,7 +65,7 @@
 	fp_copy_ext(&src2, dest);
 
 	/*
-	 * The taylor row arround a for sqrt(x) is:
+	 * The taylor row around a for sqrt(x) is:
 	 *	sqrt(x) = sqrt(a) + 1/(2*sqrt(a))*(x-a) + R
 	 * With a=1 this gives:
 	 *	sqrt(x) = 1 + 1/2*(x-1)
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index eaa6186..f493f03 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -180,7 +180,7 @@
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
index ad3ed1f..46161ce 100644
--- a/arch/m68k/q40/q40ints.c
+++ b/arch/m68k/q40/q40ints.c
@@ -184,7 +184,7 @@
 };
 
 /* complain only this many times about spurious ints : */
-static int ccleirq=60;    /* ISA dev IRQ's*/
+static int ccleirq=60;    /* ISA dev IRQs*/
 /*static int cclirq=60;*/     /* internal */
 
 /* FIXME: add shared ints,mask,unmask,probing.... */
@@ -234,7 +234,7 @@
  * There is a little mess wrt which IRQ really caused this irq request. The
  * main problem is that IIRQ_REG and EIRQ_REG reflect the state when they
  * are read - which is long after the request came in. In theory IRQs should
- * not just go away but they occassionally do
+ * not just go away but they occasionally do
  */
 				if (irq > 4 && irq <= 15 && mext_disabled) {
 					/*aliased_irq++;*/
diff --git a/arch/m68k/sun3/mmu_emu.c b/arch/m68k/sun3/mmu_emu.c
index 7a0e3a2..fb0f6a2 100644
--- a/arch/m68k/sun3/mmu_emu.c
+++ b/arch/m68k/sun3/mmu_emu.c
@@ -239,7 +239,7 @@
 /* gets an empty context.  if full, kills the next context listed to
    die first */
 /* This context invalidation scheme is, well, totally arbitrary, I'm
-   sure it could be much more intellegent...  but it gets the job done
+   sure it could be much more intelligent...  but it gets the job done
    for now without much overhead in making it's decision. */
 /* todo: come up with optimized scheme for flushing contexts */
 unsigned long get_free_context(struct mm_struct *mm)
diff --git a/arch/m68k/tools/amiga/dmesg.c b/arch/m68k/tools/amiga/dmesg.c
index e892748..7340f5b 100644
--- a/arch/m68k/tools/amiga/dmesg.c
+++ b/arch/m68k/tools/amiga/dmesg.c
@@ -3,7 +3,7 @@
  *					   in Chip RAM with the kernel command
  *					   line option `debug=mem'.
  *
- *  © Copyright 1996 by Geert Uytterhoeven <geert@linux-m68k.org>
+ *  © Copyright 1996 by Geert Uytterhoeven <geert@linux-m68k.org>
  *
  *
  *  Usage:
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 185906b..f4b582c 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -451,6 +451,12 @@
 	help
 	  Support for the Netburner MOD-5272 board.
 
+config SAVANTrosie1
+	bool "Savant Rosie1 board support"
+	depends on M523x
+	help
+	  Support for the Savant Rosie1 board.
+
 config ROMFS_FROM_ROM
 	bool "ROMFS image not RAM resident"
 	depends on (NETtel || SNAPGEAR)
@@ -492,7 +498,12 @@
         bool
 	default y
 	depends on CPU16B
-	
+
+config SAVANT
+	bool
+	default y
+	depends on SAVANTrosie1
+
 config AVNET
 	bool
 	default y
@@ -696,6 +707,8 @@
 
 source "fs/Kconfig"
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/m68knommu/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index 92227aa..30aa255 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -48,6 +48,7 @@
 board-$(CONFIG_M5208EVB)	:= M5208EVB
 board-$(CONFIG_MOD5272)		:= MOD5272
 board-$(CONFIG_AVNET)           := AVNET
+board-$(CONFIG_SAVANT)		:= SAVANT
 BOARD := $(board-y)
 
 model-$(CONFIG_RAMKERNEL)	:= ram
@@ -117,4 +118,4 @@
 libs-y	+= arch/m68knommu/lib/
 
 archclean:
-	$(Q)$(MAKE) $(clean)=arch/m68knommu/boot
+
diff --git a/arch/m68knommu/defconfig b/arch/m68knommu/defconfig
index 3891de0..5a0ecaa 100644
--- a/arch/m68knommu/defconfig
+++ b/arch/m68knommu/defconfig
@@ -1,41 +1,48 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Tue Jun 27 12:57:06 2006
+# Linux kernel version: 2.6.23
+# Thu Oct 18 13:17:38 2007
 #
 CONFIG_M68K=y
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
+CONFIG_ZONE_DMA=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_LOW_RES=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_NO_IOPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # General setup
 #
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SYSFS_DEPRECATED is not set
 # CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
+# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
 # CONFIG_KALLSYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_PRINTK=y
@@ -44,20 +51,25 @@
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
 CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
 
 #
 # IO Schedulers
@@ -99,6 +111,7 @@
 #
 # Platform
 #
+# CONFIG_UC5272 is not set
 CONFIG_M5272C3=y
 # CONFIG_COBRA5272 is not set
 # CONFIG_CANCam is not set
@@ -107,7 +120,6 @@
 # CONFIG_CPU16B is not set
 # CONFIG_MOD5272 is not set
 CONFIG_FREESCALE=y
-# CONFIG_LARGE_ALLOCS is not set
 CONFIG_4KSTACKS=y
 
 #
@@ -121,6 +133,11 @@
 # CONFIG_RAM8BIT is not set
 # CONFIG_RAM16BIT is not set
 # CONFIG_RAM32BIT is not set
+
+#
+# ROM configuration
+#
+# CONFIG_ROM is not set
 CONFIG_RAMKERNEL=y
 # CONFIG_ROMKERNEL is not set
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -131,20 +148,19 @@
 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_VIRT_TO_BUS=y
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
 # CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
 
 #
 # Executable file formats
@@ -168,7 +184,6 @@
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -187,27 +202,21 @@
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -218,7 +227,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -234,7 +242,17 @@
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -245,16 +263,8 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
@@ -266,11 +276,13 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -290,7 +302,6 @@
 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
@@ -313,42 +324,25 @@
 # 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
+# UBI - Unsorted block images
 #
+# CONFIG_MTD_UBI is not set
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP 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_INITRD is not set
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_MISC_DEVICES is not set
 # CONFIG_IDE is not set
 
 #
@@ -356,67 +350,29 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
 # 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_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_FEC=y
 # CONFIG_FEC2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
 
 #
-# Ethernet (1000 Mbit)
+# Wireless LAN
 #
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 CONFIG_PPP=y
 # CONFIG_PPP_MULTILINK is not set
@@ -427,20 +383,14 @@
 # CONFIG_PPP_BSDCOMP is not set
 # CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=y
 # 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
 
 #
@@ -472,34 +422,13 @@
 # CONFIG_UNIX98_PTYS is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
 # CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
 
 #
@@ -507,101 +436,74 @@
 #
 # 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_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
+# Multifunction device drivers
 #
+# CONFIG_MFD_SM501 is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
 
 #
 # Graphics support
 #
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
 # CONFIG_FB is not set
 
 #
 # Sound
 #
 # CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI 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_USB_SUPPORT is not set
 # 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_CLASS is not set
 
 #
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # 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=y
@@ -629,6 +531,7 @@
 # Pseudo filesystems
 #
 CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
@@ -645,7 +548,6 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
@@ -664,7 +566,6 @@
 # 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
@@ -678,15 +579,21 @@
 # CONFIG_NLS is not set
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
 # CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
-# CONFIG_UNWIND_INFO is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FULLDEBUG is not set
 # CONFIG_HIGHPROFILE is not set
 # CONFIG_BOOTPARAM is not set
@@ -699,20 +606,16 @@
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
 # CONFIG_CRYPTO is not set
 
 #
-# Hardware crypto devices
-#
-
-#
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 # CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index 3f86ade..74bf949 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -151,27 +151,15 @@
 #ifdef CONFIG_ELITE
 	printk(KERN_INFO "Modified for M5206eLITE by Rob Scott, rscott@mtrob.fdns.net\n");
 #endif
-#ifdef CONFIG_TELOS
-	printk(KERN_INFO "Modified for Omnia ToolVox by James D. Schettine, james@telos-systems.com\n");
-#endif
 #endif
 	printk(KERN_INFO "Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
 
 #if defined( CONFIG_PILOT ) && defined( CONFIG_M68328 )
 	printk(KERN_INFO "TRG SuperPilot FLASH card support <info@trgnet.com>\n");
 #endif
-
 #if defined( CONFIG_PILOT ) && defined( CONFIG_M68EZ328 )
 	printk(KERN_INFO "PalmV support by Lineo Inc. <jeff@uclinux.com>\n");
 #endif
-
-#ifdef CONFIG_M68EZ328ADS
-	printk(KERN_INFO "M68EZ328ADS board support (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>\n");
-#endif
-
-#ifdef CONFIG_ALMA_ANS
-	printk(KERN_INFO "Alma Electronics board support (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>\n");
-#endif
 #if defined (CONFIG_M68360)
 	printk(KERN_INFO "QUICC port done by SED Systems <hamilton@sedsystems.ca>,\n");
 	printk(KERN_INFO "based on 2.0.38 port by Lineo Inc. <mleslie@lineo.com>.\n");
@@ -188,11 +176,9 @@
 		"BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
 		(int) &_sdata, (int) &_edata,
 		(int) &_sbss, (int) &_ebss);
-	printk(KERN_DEBUG "KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x "
-		"STACK=0x%06x-0x%06x\n",
+	printk(KERN_DEBUG "MEMORY -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x\n ",
 		(int) &_ebss, (int) memory_start,
-		(int) memory_start, (int) memory_end,
-		(int) memory_end, (int) _ramend);
+		(int) memory_start, (int) memory_end);
 #endif
 
 	/* Keep a copy of command line */
@@ -287,12 +273,3 @@
 	.show	= show_cpuinfo,
 };
 
-void arch_gettod(int *year, int *mon, int *day, int *hour,
-		 int *min, int *sec)
-{
-	if (mach_gettod)
-		mach_gettod(year, mon, day, hour, min, sec);
-	else
-		*year = *mon = *day = *hour = *min = *sec = 0;
-}
-
diff --git a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c
index 437f8c6..7037137 100644
--- a/arch/m68knommu/kernel/signal.c
+++ b/arch/m68knommu/kernel/signal.c
@@ -781,15 +781,7 @@
 	/* Did we come from a system call? */
 	if (regs->orig_d0 >= 0) {
 		/* Restart the system call - no handlers present */
-		if (regs->d0 == -ERESTARTNOHAND
-		    || regs->d0 == -ERESTARTSYS
-		    || regs->d0 == -ERESTARTNOINTR) {
-			regs->d0 = regs->orig_d0;
-			regs->pc -= 2;
-		} else if (regs->d0 == -ERESTART_RESTARTBLOCK) {
-			regs->d0 = __NR_restart_syscall;
-			regs->pc -= 2;
-		}
+		handle_restart(regs, NULL, 0);
 	}
 	return 0;
 }
diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c
index 467053d..77e5375 100644
--- a/arch/m68knommu/kernel/time.c
+++ b/arch/m68knommu/kernel/time.c
@@ -27,7 +27,6 @@
 
 #define	TICK_SIZE (tick_nsec / 1000)
 
-
 static inline int set_rtc_mmss(unsigned long nowtime)
 {
 	if (mach_set_clock_mmss)
@@ -39,15 +38,11 @@
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-static irqreturn_t timer_interrupt(int irq, void *dummy)
+irqreturn_t arch_timer_interrupt(int irq, void *dummy)
 {
 	/* last time the cmos clock got updated */
 	static long last_rtc_update=0;
 
-	/* may need to kick the hardware timer */
-	if (mach_tick)
-	  mach_tick();
-
 	write_seqlock(&xtime_lock);
 
 	do_timer(1);
@@ -103,10 +98,10 @@
 {
 	unsigned int year, mon, day, hour, min, sec;
 
-	extern void arch_gettod(int *year, int *mon, int *day, int *hour,
-				int *min, int *sec);
-
-	arch_gettod(&year, &mon, &day, &hour, &min, &sec);
+	if (mach_gettod)
+		mach_gettod(&year, &mon, &day, &hour, &min, &sec);
+	else
+		year = mon = day = hour = min = sec = 0;
 
 	if ((year += 1900) < 1970)
 		year += 100;
@@ -114,7 +109,7 @@
 	xtime.tv_nsec = 0;
 	wall_to_monotonic.tv_sec = -xtime.tv_sec;
 
-	mach_sched_init(timer_interrupt);
+	hw_timer_init();
 }
 
 /*
@@ -128,7 +123,7 @@
 
 	do {
 		seq = read_seqbegin_irqsave(&xtime_lock, flags);
-		usec = mach_gettimeoffset ? mach_gettimeoffset() : 0;
+		usec = hw_timer_offset();
 		sec = xtime.tv_sec;
 		usec += (xtime.tv_nsec / 1000);
 	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
@@ -160,8 +155,7 @@
 	 * Discover what correction gettimeofday
 	 * would have done, and then undo it!
 	 */
-	if (mach_gettimeoffset)
-		nsec -= (mach_gettimeoffset() * 1000);
+	nsec -= (hw_timer_offset() * 1000);
 
 	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
 	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
diff --git a/arch/m68knommu/platform/5206/config.c b/arch/m68knommu/platform/5206/config.c
index d0f2dc5..b3c4dd4 100644
--- a/arch/m68knommu/platform/5206/config.c
+++ b/arch/m68knommu/platform/5206/config.c
@@ -10,13 +10,10 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcftimer.h>
@@ -25,9 +22,6 @@
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -97,9 +91,6 @@
 void config_BSP(char *commandp, int size)
 {
 	mcf_setimr(MCFSIM_IMR_MASKALL);
-	mach_sched_init = coldfire_timer_init;
-	mach_tick = coldfire_tick;
-	mach_gettimeoffset = coldfire_timer_offset;
 	mach_reset = coldfire_reset;
 }
 
diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c
index 425703f..f84a4ae 100644
--- a/arch/m68knommu/platform/5206e/config.c
+++ b/arch/m68knommu/platform/5206e/config.c
@@ -9,23 +9,16 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfdma.h>
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -102,9 +95,6 @@
 	commandp[size-1] = 0;
 #endif /* CONFIG_NETtel */
 
-	mach_sched_init = coldfire_timer_init;
-	mach_tick = coldfire_tick;
-	mach_gettimeoffset = coldfire_timer_offset;
 	mach_reset = coldfire_reset;
 }
 
diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c
index a2c95be..6edbd41 100644
--- a/arch/m68knommu/platform/520x/config.c
+++ b/arch/m68knommu/platform/520x/config.c
@@ -27,9 +27,6 @@
 
 /***************************************************************************/
 
-void coldfire_pit_tick(void);
-void coldfire_pit_init(irq_handler_t handler);
-unsigned long coldfire_pit_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -47,10 +44,7 @@
 
 void config_BSP(char *commandp, int size)
 {
-    mach_sched_init = coldfire_pit_init;
-    mach_tick = coldfire_pit_tick;
-    mach_gettimeoffset = coldfire_pit_offset;
-    mach_reset = coldfire_reset;
+	mach_reset = coldfire_reset;
 }
 
 /***************************************************************************/
diff --git a/arch/m68knommu/platform/523x/config.c b/arch/m68knommu/platform/523x/config.c
index 0a3af05..e7f80c8 100644
--- a/arch/m68knommu/platform/523x/config.c
+++ b/arch/m68knommu/platform/523x/config.c
@@ -13,12 +13,10 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
@@ -26,9 +24,6 @@
 
 /***************************************************************************/
 
-void coldfire_pit_tick(void);
-void coldfire_pit_init(irq_handler_t handler);
-unsigned long coldfire_pit_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -62,9 +57,6 @@
 void config_BSP(char *commandp, int size)
 {
 	mcf_disableall();
-	mach_sched_init = coldfire_pit_init;
-	mach_tick = coldfire_pit_tick;
-	mach_gettimeoffset = coldfire_pit_offset;
 	mach_reset = coldfire_reset;
 }
 
diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c
index dc2c362..d4d3943 100644
--- a/arch/m68knommu/platform/5249/config.c
+++ b/arch/m68knommu/platform/5249/config.c
@@ -9,24 +9,17 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfdma.h>
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -95,9 +88,6 @@
 void config_BSP(char *commandp, int size)
 {
 	mcf_setimr(MCFSIM_IMR_MASKALL);
-	mach_sched_init = coldfire_timer_init;
-	mach_tick = coldfire_tick;
-	mach_gettimeoffset = coldfire_timer_offset;
 	mach_reset = coldfire_reset;
 }
 
diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c
index 1365a83..634a637 100644
--- a/arch/m68knommu/platform/5272/config.c
+++ b/arch/m68knommu/platform/5272/config.c
@@ -10,24 +10,17 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfdma.h>
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 extern unsigned int mcf_timervector;
@@ -128,9 +121,6 @@
 
 	mcf_timervector = 69;
 	mcf_profilevector = 70;
-	mach_sched_init = coldfire_timer_init;
-	mach_tick = coldfire_tick;
-	mach_gettimeoffset = coldfire_timer_offset;
 	mach_reset = coldfire_reset;
 }
 
diff --git a/arch/m68knommu/platform/527x/config.c b/arch/m68knommu/platform/527x/config.c
index 1b82044..9cbfbc6 100644
--- a/arch/m68knommu/platform/527x/config.c
+++ b/arch/m68knommu/platform/527x/config.c
@@ -13,12 +13,10 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
@@ -26,9 +24,6 @@
 
 /***************************************************************************/
 
-void coldfire_pit_tick(void);
-void coldfire_pit_init(irq_handler_t handler);
-unsigned long coldfire_pit_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -62,9 +57,6 @@
 void config_BSP(char *commandp, int size)
 {
 	mcf_disableall();
-	mach_sched_init = coldfire_pit_init;
-	mach_tick = coldfire_pit_tick;
-	mach_gettimeoffset = coldfire_pit_offset;
 	mach_reset = coldfire_reset;
 }
 
diff --git a/arch/m68knommu/platform/528x/config.c b/arch/m68knommu/platform/528x/config.c
index a089e95..acbd434 100644
--- a/arch/m68knommu/platform/528x/config.c
+++ b/arch/m68knommu/platform/528x/config.c
@@ -13,12 +13,10 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
@@ -26,9 +24,6 @@
 
 /***************************************************************************/
 
-void coldfire_pit_tick(void);
-void coldfire_pit_init(irq_handler_t handler);
-unsigned long coldfire_pit_offset(void);
 void coldfire_reset(void);
 
 /***************************************************************************/
@@ -62,9 +57,6 @@
 void config_BSP(char *commandp, int size)
 {
 	mcf_disableall();
-	mach_sched_init = coldfire_pit_init;
-	mach_tick = coldfire_pit_tick;
-	mach_gettimeoffset = coldfire_pit_offset;
 	mach_reset = coldfire_reset;
 }
 
diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c
index e346161..6040821 100644
--- a/arch/m68knommu/platform/5307/config.c
+++ b/arch/m68knommu/platform/5307/config.c
@@ -10,25 +10,18 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfdma.h>
 #include <asm/mcfwdebug.h>
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 extern unsigned int mcf_timervector;
@@ -122,9 +115,6 @@
 	mcf_timerlevel = 6;
 #endif
 
-	mach_sched_init = coldfire_timer_init;
-	mach_tick = coldfire_tick;
-	mach_gettimeoffset = coldfire_timer_offset;
 	mach_reset = coldfire_reset;
 
 #ifdef MCF_BDM_DISABLE
diff --git a/arch/m68knommu/platform/5307/entry.S b/arch/m68knommu/platform/5307/entry.S
index a8cd867..b333731 100644
--- a/arch/m68knommu/platform/5307/entry.S
+++ b/arch/m68knommu/platform/5307/entry.S
@@ -74,7 +74,8 @@
 	movel	%sp,%d2			/* get thread_info pointer */
 	andl	#-THREAD_SIZE,%d2	/* at start of kernel stack */
 	movel	%d2,%a0
-	movel	%sp,%a0@(THREAD_ESP0)	/* save top of frame */
+	movel	%a0@,%a1		/* save top of frame */
+	movel	%sp,%a1@(TASK_THREAD+THREAD_ESP0)
 	btst	#(TIF_SYSCALL_TRACE%8),%a0@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
 	bnes	1f
 
@@ -83,6 +84,8 @@
 	movel	%d0,%sp@(PT_D0)		/* save the return value */
 	jra	ret_from_exception
 1:
+	movel	#-ENOSYS,%d2		/* strace needs -ENOSYS in PT_D0 */
+	movel	%d2,PT_D0(%sp)		/* on syscall entry */
 	subql	#4,%sp
 	SAVE_SWITCH_STACK
 	jbsr	syscall_trace
diff --git a/arch/m68knommu/platform/5307/pit.c b/arch/m68knommu/platform/5307/pit.c
index e53c446..173b754 100644
--- a/arch/m68knommu/platform/5307/pit.c
+++ b/arch/m68knommu/platform/5307/pit.c
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <asm/machdep.h>
 #include <asm/io.h>
 #include <asm/coldfire.h>
 #include <asm/mcfpit.h>
@@ -31,28 +32,30 @@
 
 /***************************************************************************/
 
-void coldfire_pit_tick(void)
+static irqreturn_t hw_tick(int irq, void *dummy)
 {
 	unsigned short pcsr;
 
 	/* Reset the ColdFire timer */
 	pcsr = __raw_readw(TA(MCFPIT_PCSR));
 	__raw_writew(pcsr | MCFPIT_PCSR_PIF, TA(MCFPIT_PCSR));
+
+	return arch_timer_interrupt(irq, dummy);
 }
 
 /***************************************************************************/
 
 static struct irqaction coldfire_pit_irq = {
-	.name    = "timer",
-	.flags   = IRQF_DISABLED | IRQF_TIMER,
+	.name	 = "timer",
+	.flags	 = IRQF_DISABLED | IRQF_TIMER,
+	.handler = hw_tick,
 };
 
-void coldfire_pit_init(irq_handler_t handler)
+void hw_timer_init(void)
 {
 	volatile unsigned char *icrp;
 	volatile unsigned long *imrp;
 
-	coldfire_pit_irq.handler = handler;
 	setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &coldfire_pit_irq);
 
 	icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
@@ -71,7 +74,7 @@
 
 /***************************************************************************/
 
-unsigned long coldfire_pit_offset(void)
+unsigned long hw_timer_offset(void)
 {
 	volatile unsigned long *ipr;
 	unsigned long pmr, pcntr, offset;
@@ -83,7 +86,7 @@
 
 	/*
 	 * If we are still in the first half of the upcount and a
-	 * timer interupt is pending, then add on a ticks worth of time.
+	 * timer interrupt is pending, then add on a ticks worth of time.
 	 */
 	offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr;
 	if ((offset < (1000000 / HZ / 2)) && (*ipr & MCFPIT_IMR_IBIT))
diff --git a/arch/m68knommu/platform/5307/timers.c b/arch/m68knommu/platform/5307/timers.c
index 64bd0ff..489dec8 100644
--- a/arch/m68knommu/platform/5307/timers.c
+++ b/arch/m68knommu/platform/5307/timers.c
@@ -9,10 +9,9 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/param.h>
-#include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <asm/io.h>
 #include <asm/traps.h>
@@ -54,24 +53,28 @@
 
 /***************************************************************************/
 
-void coldfire_tick(void)
+static irqreturn_t hw_tick(int irq, void *dummy)
 {
 	/* Reset the ColdFire timer */
 	__raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER));
+
+	return arch_timer_interrupt(irq, dummy);
 }
 
 /***************************************************************************/
 
 static struct irqaction coldfire_timer_irq = {
-        .name    = "timer",
-        .flags   = IRQF_DISABLED | IRQF_TIMER,
+	.name	 = "timer",
+	.flags	 = IRQF_DISABLED | IRQF_TIMER,
+	.handler = hw_tick,
 };
 
+/***************************************************************************/
+
 static int ticks_per_intr;
 
-void coldfire_timer_init(irq_handler_t handler)
+void hw_timer_init(void)
 {
-	coldfire_timer_irq.handler = handler;
 	setup_irq(mcf_timervector, &coldfire_timer_irq);
 
 	__raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
@@ -89,7 +92,7 @@
 
 /***************************************************************************/
 
-unsigned long coldfire_timer_offset(void)
+unsigned long hw_timer_offset(void)
 {
 	unsigned long tcn, offset;
 
diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c
index b32c642..f77328b 100644
--- a/arch/m68knommu/platform/532x/config.c
+++ b/arch/m68knommu/platform/532x/config.c
@@ -18,25 +18,18 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfdma.h>
 #include <asm/mcfwdebug.h>
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 extern unsigned int mcf_timervector;
@@ -104,9 +97,6 @@
 
 	mcf_timervector = 64+32;
 	mcf_profilevector = 64+33;
-	mach_sched_init = coldfire_timer_init;
-	mach_tick = coldfire_tick;
-	mach_gettimeoffset = coldfire_timer_offset;
 	mach_reset = coldfire_reset;
 
 #ifdef MCF_BDM_DISABLE
diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c
index e692536..2d3b62e 100644
--- a/arch/m68knommu/platform/5407/config.c
+++ b/arch/m68knommu/platform/5407/config.c
@@ -10,24 +10,17 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
-#include <asm/traps.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
-#include <asm/mcftimer.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfdma.h>
 
 /***************************************************************************/
 
-void coldfire_tick(void);
-void coldfire_timer_init(irq_handler_t handler);
-unsigned long coldfire_timer_offset(void);
 void coldfire_reset(void);
 
 extern unsigned int mcf_timervector;
@@ -108,9 +101,6 @@
 	mcf_timerlevel = 6;
 #endif
 
-	mach_sched_init = coldfire_timer_init;
-	mach_tick = coldfire_tick;
-	mach_gettimeoffset = coldfire_timer_offset;
 	mach_reset = coldfire_reset;
 }
 
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 235d451..61262c5 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -21,6 +21,7 @@
 
 config BASLER_EXCITE
 	bool "Basler eXcite smart camera"
+	select CEVT_R4K
 	select DMA_COHERENT
 	select HW_HAS_PCI
 	select IRQ_CPU
@@ -47,6 +48,7 @@
 
 config BCM47XX
 	bool "BCM47XX based boards"
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
 	select IRQ_CPU
@@ -63,6 +65,8 @@
 
 config MIPS_COBALT
 	bool "Cobalt Server"
+	select CEVT_R4K
+	select CEVT_GT641XX
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
 	select I8253
@@ -80,6 +84,7 @@
 config MACH_DECSTATION
 	bool "DECstations"
 	select BOOT_ELF32
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select NO_IOPORT
 	select IRQ_CPU
@@ -111,6 +116,7 @@
 	select ARC
 	select ARC32
 	select ARCH_MAY_HAVE_PC_FDC
+	select CEVT_R4K
 	select GENERIC_ISA_DMA
 	select IRQ_CPU
 	select I8253
@@ -130,6 +136,7 @@
 
 config LASAT
 	bool "LASAT Networks platforms"
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select SYS_HAS_EARLY_PRINTK
 	select HW_HAS_PCI
@@ -146,6 +153,7 @@
 config LEMOTE_FULONG
 	bool "Lemote Fulong mini-PC"
 	select ARCH_SPARSEMEM_ENABLE
+	select CEVT_R4K
 	select SYS_HAS_CPU_LOONGSON2
 	select DMA_NONCOHERENT
 	select BOOT_ELF32
@@ -170,6 +178,7 @@
 config MIPS_ATLAS
 	bool "MIPS Atlas board"
 	select BOOT_ELF32
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select SYS_HAS_EARLY_PRINTK
 	select IRQ_CPU
@@ -200,6 +209,7 @@
 	bool "MIPS Malta board"
 	select ARCH_MAY_HAVE_PC_FDC
 	select BOOT_ELF32
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select GENERIC_ISA_DMA
 	select IRQ_CPU
@@ -230,6 +240,7 @@
 
 config MIPS_SEAD
 	bool "MIPS SEAD board"
+	select CEVT_R4K
 	select IRQ_CPU
 	select DMA_NONCOHERENT
 	select SYS_HAS_EARLY_PRINTK
@@ -248,6 +259,7 @@
 
 config MIPS_SIM
 	bool 'MIPS simulator (MIPSsim)'
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select SYS_HAS_EARLY_PRINTK
 	select IRQ_CPU
@@ -265,6 +277,7 @@
 
 config MARKEINS
 	bool "NEC EMMA2RH Mark-eins"
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
 	select IRQ_CPU
@@ -279,6 +292,7 @@
 
 config MACH_VR41XX
 	bool "NEC VR4100 series based machines"
+	select CEVT_R4K
 	select SYS_HAS_CPU_VR41XX
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 
@@ -315,6 +329,7 @@
 
 config PMC_YOSEMITE
 	bool "PMC-Sierra Yosemite eval board"
+	select CEVT_R4K
 	select DMA_COHERENT
 	select HW_HAS_PCI
 	select IRQ_CPU
@@ -335,6 +350,7 @@
 
 config QEMU
 	bool "Qemu"
+	select CEVT_R4K
 	select DMA_COHERENT
 	select GENERIC_ISA_DMA
 	select HAVE_STD_PC_SERIAL_PORT
@@ -365,6 +381,7 @@
 	select ARC
 	select ARC32
 	select BOOT_ELF32
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select HW_HAS_EISA
 	select I8253
@@ -409,6 +426,7 @@
 	select ARC
 	select ARC32
 	select BOOT_ELF32
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
 	select IRQ_CPU
@@ -536,6 +554,7 @@
 	select ARC32 if CPU_LITTLE_ENDIAN
 	select ARCH_MAY_HAVE_PC_FDC
 	select BOOT_ELF32
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select GENERIC_ISA_DMA
 	select HW_HAS_EISA
@@ -577,6 +596,7 @@
 
 config TOSHIBA_RBTX4927
 	bool "Toshiba RBTX49[23]7 board"
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select HAS_TXX9_SERIAL
 	select HW_HAS_PCI
@@ -597,6 +617,7 @@
 
 config TOSHIBA_RBTX4938
 	bool "Toshiba RBTX4938 board"
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select HAS_TXX9_SERIAL
 	select HW_HAS_PCI
@@ -616,6 +637,7 @@
 
 config WR_PPMC
 	bool "Wind River PPMC board"
+	select CEVT_R4K
 	select IRQ_CPU
 	select BOOT_ELF32
 	select DMA_NONCOHERENT
@@ -708,6 +730,12 @@
 config BOOT_RAW
 	bool
 
+config CEVT_GT641XX
+	bool
+
+config CEVT_R4K
+	bool
+
 config CFE
 	bool
 
@@ -1788,7 +1816,7 @@
 	  but it is independent of the system firmware.   And like a reboot
 	  you can start any kernel with it, not just Linux.
 
-	  The name comes from the similiarity to the exec system call.
+	  The name comes from the similarity to the exec system call.
 
 	  It is an ongoing process to be certain the hardware in a machine
 	  is properly shutdown, so do not be surprised if this code does not
@@ -1981,7 +2009,7 @@
 
 source "fs/Kconfig"
 
-source "arch/mips/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/mips/Kconfig.debug"
 
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug
index 3efe117..fd7124c 100644
--- a/arch/mips/Kconfig.debug
+++ b/arch/mips/Kconfig.debug
@@ -6,18 +6,6 @@
 
 source "lib/Kconfig.debug"
 
-config CROSSCOMPILE
-	bool "Are you using a crosscompiler"
-	help
-	  Say Y here if you are compiling the kernel on a different
-	  architecture than the one it is intended to run on.  This is just a
-	  convenience option which will select the appropriate value for
-	  the CROSS_COMPILE make variable which otherwise has to be passed on
-	  the command line from mips-linux-, mipsel-linux-, mips64-linux- and
-	  mips64el-linux- as appropriate for a particular kernel configuration.
-	  You will have to pass the value for CROSS_COMPILE manually if the
-	  name prefix for your tools is different.
-
 config CMDLINE
 	string "Default kernel command string"
 	default ""
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 14164c2..23c1775 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -18,15 +18,15 @@
 # Select the object file format to substitute into the linker script.
 #
 ifdef CONFIG_CPU_LITTLE_ENDIAN
-32bit-tool-prefix	= mipsel-linux-
-64bit-tool-prefix	= mips64el-linux-
+32bit-tool-archpref	= mipsel
+64bit-tool-archpref	= mips64el
 32bit-bfd		= elf32-tradlittlemips
 64bit-bfd		= elf64-tradlittlemips
 32bit-emul		= elf32ltsmip
 64bit-emul		= elf64ltsmip
 else
-32bit-tool-prefix	= mips-linux-
-64bit-tool-prefix	= mips64-linux-
+32bit-tool-archpref	= mips
+64bit-tool-archpref	= mips64
 32bit-bfd		= elf32-tradbigmips
 64bit-bfd		= elf64-tradbigmips
 32bit-emul		= elf32btsmip
@@ -34,16 +34,18 @@
 endif
 
 ifdef CONFIG_32BIT
-tool-prefix		= $(32bit-tool-prefix)
+tool-archpref		= $(32bit-tool-archpref)
 UTS_MACHINE		:= mips
 endif
 ifdef CONFIG_64BIT
-tool-prefix		= $(64bit-tool-prefix)
+tool-archpref		= $(64bit-tool-archpref)
 UTS_MACHINE		:= mips64
 endif
 
-ifdef CONFIG_CROSSCOMPILE
-CROSS_COMPILE		:= $(tool-prefix)
+ifneq ($(SUBARCH),$(ARCH))
+  ifeq ($(CROSS_COMPILE),)
+    CROSS_COMPILE := $(call cc-cross-prefix, $(tool-archpref)-linux-  $(tool-archpref)-gnu-linux-  $(tool-archpref)-unknown-gnu-linux-)
+  endif
 endif
 
 ifdef CONFIG_32BIT
diff --git a/arch/mips/au1000/Kconfig b/arch/mips/au1000/Kconfig
index a23d415..b36cec58 100644
--- a/arch/mips/au1000/Kconfig
+++ b/arch/mips/au1000/Kconfig
@@ -137,6 +137,7 @@
 config SOC_AU1X00
 	bool
 	select 64BIT_PHYS_ADDR
+	select CEVT_R4K
 	select IRQ_CPU
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_SUPPORTS_32BIT_KERNEL
diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c
index 5f48b06..bdf00e2 100644
--- a/arch/mips/au1000/pb1200/irqmap.c
+++ b/arch/mips/au1000/pb1200/irqmap.c
@@ -36,8 +36,8 @@
 #include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/delay.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/bootinfo.h>
 #include <asm/io.h>
 #include <asm/mipsregs.h>
diff --git a/arch/mips/basler/excite/excite_irq.c b/arch/mips/basler/excite/excite_irq.c
index 1ecab63..4903e06 100644
--- a/arch/mips/basler/excite/excite_irq.c
+++ b/arch/mips/basler/excite/excite_irq.c
@@ -29,7 +29,7 @@
 #include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/random.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/bootinfo.h>
 #include <asm/io.h>
 #include <asm/irq.h>
diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c
index 0ab4676..0c6f47b 100644
--- a/arch/mips/bcm47xx/time.c
+++ b/arch/mips/bcm47xx/time.c
@@ -46,10 +46,3 @@
 	/* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
 	mips_hpt_frequency = hz;
 }
-
-void __init
-plat_timer_setup(struct irqaction *irq)
-{
-	/* Enable the timer interrupt */
-	setup_irq(7, irq);
-}
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
index 6b83f4d..d73833b 100644
--- a/arch/mips/cobalt/Makefile
+++ b/arch/mips/cobalt/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the Cobalt micro systems family specific parts of the kernel
 #
 
-obj-y := buttons.o irq.o led.o reset.o rtc.o serial.o setup.o
+obj-y := buttons.o irq.o led.o reset.o rtc.o serial.o setup.o time.o
 
 obj-$(CONFIG_PCI)		+= pci.o
 obj-$(CONFIG_EARLY_PRINTK)	+= console.o
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index d11bb1b..dd23beb 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -9,19 +9,17 @@
  * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
  *
  */
-#include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/pm.h>
 
 #include <asm/bootinfo.h>
-#include <asm/time.h>
-#include <asm/i8253.h>
-#include <asm/io.h>
 #include <asm/reboot.h>
 #include <asm/gt64120.h>
 
 #include <cobalt.h>
-#include <irq.h>
 
 extern void cobalt_machine_restart(char *command);
 extern void cobalt_machine_halt(void);
@@ -41,17 +39,6 @@
 	return "MIPS Cobalt";
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	/* Load timer value for HZ (TCLK is 50MHz) */
-	GT_WRITE(GT_TC0_OFS, 50*1000*1000 / HZ);
-
-	/* Enable timer0 */
-	GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
-
-	setup_irq(GT641XX_TIMER0_IRQ, irq);
-}
-
 /*
  * Cobalt doesn't have PS/2 keyboard/mouse interfaces,
  * keyboard conntroller is never used.
@@ -84,11 +71,6 @@
 	},
 };
 
-void __init plat_time_init(void)
-{
-	setup_pit_timer();
-}
-
 void __init plat_mem_setup(void)
 {
 	int i;
diff --git a/arch/mips/cobalt/time.c b/arch/mips/cobalt/time.c
new file mode 100644
index 0000000..fa819fc
--- /dev/null
+++ b/arch/mips/cobalt/time.c
@@ -0,0 +1,35 @@
+/*
+ *  Cobalt time initialization.
+ *
+ *  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/init.h>
+
+#include <asm/gt64120.h>
+#include <asm/i8253.h>
+#include <asm/time.h>
+
+#define GT641XX_BASE_CLOCK	50000000	/* 50MHz */
+
+void __init plat_time_init(void)
+{
+	setup_pit_timer();
+
+	gt641xx_set_base_clock(GT641XX_BASE_CLOCK);
+
+	mips_timer_state = gt641xx_timer0_state;
+}
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 49bcc58..892d4c3 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -175,6 +175,7 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=15
+CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index 86dcb74..61b72f5 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -1,71 +1,68 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:35 2007
+# Linux kernel version: 2.6.23
+# Thu Oct 18 22:45:52 2007
 #
 CONFIG_MIPS=y
 
 #
 # Machine selection
 #
-CONFIG_ZONE_DMA=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MACH_ALCHEMY is not set
 # CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
-# CONFIG_WR_PPMC is not set
 CONFIG_MIPS_SIM=y
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_QEMU is not set
-# CONFIG_MARKEINS is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
 # CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
 # CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_BIGSUR is not set
 # CONFIG_SNI_RM is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_WR_PPMC is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 # CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_BOOT_RAW=y
+CONFIG_CEVT_R4K=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_HOTPLUG_CPU is not set
+# CONFIG_NO_IOPORT is not set
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
@@ -76,6 +73,11 @@
 #
 # CPU selection
 #
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_CPU_LOONGSON2 is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -115,8 +117,8 @@
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
+CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 # CONFIG_MIPS_VPE_LOADER is not set
-# CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -130,50 +132,52 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
 # CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
+CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
 # CONFIG_HZ_250 is not set
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
+# CONFIG_SWAP is not set
 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_USER_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
@@ -187,31 +191,29 @@
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 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=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 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
+# CONFIG_BLK_DEV_BSG is not set
 
 #
 # IO Schedulers
@@ -229,18 +231,11 @@
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 
 #
-# PCI Hotplug Support
-#
-
-#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
@@ -250,9 +245,8 @@
 #
 # Power management options
 #
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
 
 #
 # Networking
@@ -262,75 +256,50 @@
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
+# CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
 CONFIG_ASK_IP_FIB_HASH=y
 # CONFIG_IP_FIB_TRIE is not set
 CONFIG_IP_FIB_HASH=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
-CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
+# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
+# CONFIG_SYN_COOKIES is not set
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=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=y
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
+# 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=m
-# CONFIG_SCTP_DBG_MSG is not set
-# CONFIG_SCTP_DBG_OBJCNT is not set
-# CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
+# CONFIG_IP_SCTP is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -347,44 +316,7 @@
 #
 # QoS and/or fair queueing
 #
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_FIFO=y
-CONFIG_NET_SCH_CLK_JIFFIES=y
-# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
-# CONFIG_NET_SCH_CLK_CPU is not set
-
-#
-# Queueing/Scheduling
-#
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_INGRESS=m
-
-#
-# Classification
-#
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-# CONFIG_NET_CLS_FW is not set
-# CONFIG_NET_CLS_U32 is not set
-# CONFIG_NET_CLS_RSVP is not set
-# CONFIG_NET_CLS_RSVP6 is not set
-# CONFIG_NET_EMATCH is not set
-# CONFIG_NET_CLS_ACT is not set
-# CONFIG_NET_CLS_POLICE is not set
-CONFIG_NET_ESTIMATOR=y
+# CONFIG_NET_SCHED is not set
 
 #
 # Network testing
@@ -393,8 +325,17 @@
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
-CONFIG_FIB_RULES=y
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -403,52 +344,25 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # 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 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=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_MISC_DEVICES is not set
 # CONFIG_IDE is not set
 
 #
@@ -456,48 +370,29 @@
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA 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_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_VETH is not set
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_AX88796 is not set
 CONFIG_MIPS_SIM_NET=y
 # CONFIG_DM9000 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 
@@ -513,49 +408,18 @@
 # 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 is not set
+# CONFIG_INPUT is not set
 
 #
 # Hardware I/O ports
 #
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -581,31 +445,13 @@
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_RTC is not set
-# 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
 
 #
@@ -613,118 +459,60 @@
 #
 # CONFIG_SPI is not set
 # CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
 # CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
 
 #
-# Hardware Monitoring support
+# Sonics Silicon Backplane
 #
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
 # Sound
 #
 # CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
-# CONFIG_HID is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI 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_USB_SUPPORT is not set
 # 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 is not set
 
 #
-# DMA Engine support
+# Userspace I/O
 #
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
+# CONFIG_UIO is not set
 
 #
 # File systems
 #
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
@@ -732,6 +520,7 @@
 # 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=y
 # CONFIG_INOTIFY is not set
@@ -760,10 +549,11 @@
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
-# CONFIG_SYSFS is not set
-# CONFIG_TMPFS is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -781,10 +571,7 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -796,6 +583,7 @@
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -803,22 +591,14 @@
 # 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
@@ -833,20 +613,22 @@
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHED_DEBUG is not set
 # 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=y
+# CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -854,7 +636,9 @@
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -865,60 +649,20 @@
 # Security options
 #
 # CONFIG_KEYS is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-# CONFIG_CRYPTO_DES is not set
-CONFIG_CRYPTO_FCRYPT=m
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
 
 #
 # Library routines
 #
-CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=y
-CONFIG_CRC32=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index 3ed991a..49dfcef 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -196,6 +196,7 @@
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
diff --git a/arch/mips/emma2rh/markeins/setup.c b/arch/mips/emma2rh/markeins/setup.c
index 5e1da53..82f9e901 100644
--- a/arch/mips/emma2rh/markeins/setup.c
+++ b/arch/mips/emma2rh/markeins/setup.c
@@ -104,12 +104,6 @@
 	mips_hpt_frequency = (bus_frequency * (4 + reg)) / 4 / 2;
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	/* we are using the cpu counter for timer interrupts */
-	setup_irq(CPU_IRQ_BASE + 7, irq);
-}
-
 static void markeins_board_init(void);
 extern void markeins_irq_setup(void);
 
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index 835b056..ae25b48 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -4,7 +4,7 @@
  * for more details.
  *
  * Copyright (C) 1992 Linus Torvalds
- * Copyright (C) 1994 - 2001, 2003 Ralf Baechle
+ * Copyright (C) 1994 - 2001, 2003, 07 Ralf Baechle
  */
 #include <linux/clockchips.h>
 #include <linux/init.h>
@@ -13,6 +13,7 @@
 #include <linux/spinlock.h>
 
 #include <asm/irq_cpu.h>
+#include <asm/i8253.h>
 #include <asm/i8259.h>
 #include <asm/io.h>
 #include <asm/jazz.h>
@@ -136,7 +137,7 @@
 	.name		= "timer",
 };
 
-void __init plat_timer_setup(struct irqaction *ignored)
+void __init plat_time_init(void)
 {
 	struct irqaction *irq = &r4030_timer_irqaction;
 
@@ -152,4 +153,5 @@
 	setup_irq(JAZZ_TIMER_IRQ, irq);
 
 	clockevents_register_device(&r4030_clockevent);
+	setup_pit_timer();
 }
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
index cfc7dce..a785797 100644
--- a/arch/mips/jazz/setup.c
+++ b/arch/mips/jazz/setup.c
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 1998, 2001 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998, 2001, 07 by Ralf Baechle
  * Copyright (C) 2001 MIPS Technologies, Inc.
  * Copyright (C) 2007 by Thomas Bogendoerfer
  */
@@ -25,7 +25,6 @@
 #include <linux/serial_8250.h>
 
 #include <asm/bootinfo.h>
-#include <asm/i8253.h>
 #include <asm/irq.h>
 #include <asm/jazz.h>
 #include <asm/jazzdma.h>
@@ -64,11 +63,6 @@
 	}
 };
 
-void __init plat_time_init(void)
-{
-	setup_pit_timer();
-}
-
 void __init plat_mem_setup(void)
 {
 	int i;
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index 0c7aee1..edb9e59 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -1,15 +1,4 @@
-/***********************************************************************
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *              ahennessy@mvista.com
- *
- * Based on arch/mips/ddb5xxx/ddb5477/setup.c
- *
- *     Setup file for JMR3927.
- *
- * Copyright (C) 2000-2001 Toshiba 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
@@ -30,9 +19,15 @@
  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  *
- ***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *              ahennessy@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
  */
 
+#include <linux/clockchips.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kdev_t.h>
@@ -104,27 +99,60 @@
 	return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr;
 }
 
-static void jmr3927_timer_ack(void)
+static void jmr3927_set_mode(enum clock_event_mode mode,
+	struct clock_event_device *evt)
 {
-	jmr3927_tmrptr->tisr = 0;       /* ack interrupt */
+	/* Nothing to do here */
 }
 
+struct clock_event_device jmr3927_clock_event_device = {
+	.name		= "MIPS",
+	.features	= CLOCK_EVT_FEAT_PERIODIC,
+	.shift		= 32,
+	.rating		= 300,
+	.cpumask	= CPU_MASK_CPU0,
+	.irq		= JMR3927_IRQ_TICK,
+	.set_mode	= jmr3927_set_mode,
+};
+
+static irqreturn_t jmr3927_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *cd = &jmr3927_clock_event_device;
+
+	jmr3927_tmrptr->tisr = 0;       /* ack interrupt */
+
+	cd->event_handler(cd);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction jmr3927_timer_irqaction = {
+	.handler	= jmr3927_timer_interrupt,
+	.flags		= IRQF_DISABLED | IRQF_PERCPU,
+	.name		= "jmr3927-timer",
+};
+
 void __init plat_time_init(void)
 {
-	clocksource_mips.read = jmr3927_hpt_read;
-	mips_timer_ack = jmr3927_timer_ack;
-	mips_hpt_frequency = JMR3927_TIMER_CLK;
-}
+	struct clock_event_device *cd;
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
+	clocksource_mips.read = jmr3927_hpt_read;
+	mips_hpt_frequency = JMR3927_TIMER_CLK;
+
 	jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ;
 	jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE;
 	jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD;
 	jmr3927_tmrptr->tcr =
 		TXx927_TMTCR_TCE | TXx927_TMTCR_CCDE | TXx927_TMTCR_TMODE_ITVL;
 
-	setup_irq(JMR3927_IRQ_TICK, irq);
+	cd = &jmr3927_clock_event_device;
+	/* Calculate the min / max delta */
+	cd->mult = div_sc((unsigned long) JMR3927_IMCLK, NSEC_PER_SEC, 32);
+	cd->max_delta_ns	= clockevent_delta2ns(0x7fffffff, cd);
+	cd->min_delta_ns	= clockevent_delta2ns(0x300, cd);
+	clockevents_register_device(cd);
+
+	setup_irq(JMR3927_IRQ_TICK, &jmr3927_timer_irqaction);
 }
 
 #define DO_WRITE_THROUGH
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 95a356e..d7745c8 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -8,6 +8,9 @@
 		   ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \
 		   time.o topology.o traps.o unaligned.o
 
+obj-$(CONFIG_CEVT_R4K)		+= cevt-r4k.o
+obj-$(CONFIG_CEVT_GT641XX)	+= cevt-gt641xx.o
+
 binfmt_irix-objs	:= irixelf.o irixinv.o irixioctl.o irixsig.o	\
 			   irix5sys.o sysirix.o
 
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c
new file mode 100644
index 0000000..4c651b2
--- /dev/null
+++ b/arch/mips/kernel/cevt-gt641xx.c
@@ -0,0 +1,144 @@
+/*
+ *  GT641xx clockevent routines.
+ *
+ *  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/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+#include <asm/gt64120.h>
+#include <asm/time.h>
+
+#include <irq.h>
+
+static DEFINE_SPINLOCK(gt641xx_timer_lock);
+static unsigned int gt641xx_base_clock;
+
+void gt641xx_set_base_clock(unsigned int clock)
+{
+	gt641xx_base_clock = clock;
+}
+
+int gt641xx_timer0_state(void)
+{
+	if (GT_READ(GT_TC0_OFS))
+		return 0;
+
+	GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ);
+	GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK);
+
+	return 1;
+}
+
+static int gt641xx_timer0_set_next_event(unsigned long delta,
+					 struct clock_event_device *evt)
+{
+	unsigned long flags;
+	u32 ctrl;
+
+	spin_lock_irqsave(&gt641xx_timer_lock, flags);
+
+	ctrl = GT_READ(GT_TC_CONTROL_OFS);
+	ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
+	ctrl |= GT_TC_CONTROL_ENTC0_MSK;
+
+	GT_WRITE(GT_TC0_OFS, delta);
+	GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
+
+	spin_unlock_irqrestore(&gt641xx_timer_lock, flags);
+
+	return 0;
+}
+
+static void gt641xx_timer0_set_mode(enum clock_event_mode mode,
+				    struct clock_event_device *evt)
+{
+	unsigned long flags;
+	u32 ctrl;
+
+	spin_lock_irqsave(&gt641xx_timer_lock, flags);
+
+	ctrl = GT_READ(GT_TC_CONTROL_OFS);
+	ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		ctrl |= GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK;
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		ctrl |= GT_TC_CONTROL_ENTC0_MSK;
+		break;
+	default:
+		break;
+	}
+
+	GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
+
+	spin_unlock_irqrestore(&gt641xx_timer_lock, flags);
+}
+
+static void gt641xx_timer0_event_handler(struct clock_event_device *dev)
+{
+}
+
+static struct clock_event_device gt641xx_timer0_clockevent = {
+	.name		= "gt641xx-timer0",
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.cpumask	= CPU_MASK_CPU0,
+	.irq		= GT641XX_TIMER0_IRQ,
+	.set_next_event	= gt641xx_timer0_set_next_event,
+	.set_mode	= gt641xx_timer0_set_mode,
+	.event_handler	= gt641xx_timer0_event_handler,
+};
+
+static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *cd = &gt641xx_timer0_clockevent;
+
+	cd->event_handler(cd);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction gt641xx_timer0_irqaction = {
+	.handler	= gt641xx_timer0_interrupt,
+	.flags		= IRQF_DISABLED | IRQF_PERCPU,
+	.name		= "gt641xx_timer0",
+};
+
+static int __init gt641xx_timer0_clockevent_init(void)
+{
+	struct clock_event_device *cd;
+
+	if (!gt641xx_base_clock)
+		return 0;
+
+	GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ);
+
+	cd = &gt641xx_timer0_clockevent;
+	cd->rating = 200 + gt641xx_base_clock / 10000000;
+	cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
+	cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+	clockevent_set_clock(cd, gt641xx_base_clock);
+
+	clockevents_register_device(&gt641xx_timer0_clockevent);
+
+	return setup_irq(GT641XX_TIMER0_IRQ, &gt641xx_timer0_irqaction);
+}
+arch_initcall(gt641xx_timer0_clockevent_init);
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
new file mode 100644
index 0000000..ae2984f
--- /dev/null
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -0,0 +1,273 @@
+/*
+ * 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) 2007 MIPS Technologies, Inc.
+ * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+
+#include <asm/smtc_ipi.h>
+#include <asm/time.h>
+
+static int mips_next_event(unsigned long delta,
+                           struct clock_event_device *evt)
+{
+	unsigned int cnt;
+	int res;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+	{
+	unsigned long flags, vpflags;
+	local_irq_save(flags);
+	vpflags = dvpe();
+#endif
+	cnt = read_c0_count();
+	cnt += delta;
+	write_c0_compare(cnt);
+	res = ((long)(read_c0_count() - cnt ) > 0) ? -ETIME : 0;
+#ifdef CONFIG_MIPS_MT_SMTC
+	evpe(vpflags);
+	local_irq_restore(flags);
+	}
+#endif
+	return res;
+}
+
+static void mips_set_mode(enum clock_event_mode mode,
+                          struct clock_event_device *evt)
+{
+	/* Nothing to do ...  */
+}
+
+static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
+static int cp0_timer_irq_installed;
+
+/*
+ * Timer ack for an R4k-compatible timer of a known frequency.
+ */
+static void c0_timer_ack(void)
+{
+	write_c0_compare(read_c0_compare());
+}
+
+/*
+ * Possibly handle a performance counter interrupt.
+ * Return true if the timer interrupt should not be checked
+ */
+static inline int handle_perf_irq(int r2)
+{
+	/*
+	 * The performance counter overflow interrupt may be shared with the
+	 * timer interrupt (cp0_perfcount_irq < 0). If it is and a
+	 * performance counter has overflowed (perf_irq() == IRQ_HANDLED)
+	 * and we can't reliably determine if a counter interrupt has also
+	 * happened (!r2) then don't check for a timer interrupt.
+	 */
+	return (cp0_perfcount_irq < 0) &&
+		perf_irq() == IRQ_HANDLED &&
+		!r2;
+}
+
+static irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
+{
+	const int r2 = cpu_has_mips_r2;
+	struct clock_event_device *cd;
+	int cpu = smp_processor_id();
+
+	/*
+	 * Suckage alert:
+	 * Before R2 of the architecture there was no way to see if a
+	 * performance counter interrupt was pending, so we have to run
+	 * the performance counter interrupt handler anyway.
+	 */
+	if (handle_perf_irq(r2))
+		goto out;
+
+	/*
+	 * The same applies to performance counter interrupts.  But with the
+	 * above we now know that the reason we got here must be a timer
+	 * interrupt.  Being the paranoiacs we are we check anyway.
+	 */
+	if (!r2 || (read_c0_cause() & (1 << 30))) {
+		c0_timer_ack();
+#ifdef CONFIG_MIPS_MT_SMTC
+		if (cpu_data[cpu].vpe_id)
+			goto out;
+		cpu = 0;
+#endif
+		cd = &per_cpu(mips_clockevent_device, cpu);
+		cd->event_handler(cd);
+	}
+
+out:
+	return IRQ_HANDLED;
+}
+
+static struct irqaction c0_compare_irqaction = {
+	.handler = c0_compare_interrupt,
+#ifdef CONFIG_MIPS_MT_SMTC
+	.flags = IRQF_DISABLED,
+#else
+	.flags = IRQF_DISABLED | IRQF_PERCPU,
+#endif
+	.name = "timer",
+};
+
+#ifdef CONFIG_MIPS_MT_SMTC
+DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device);
+
+static void smtc_set_mode(enum clock_event_mode mode,
+                          struct clock_event_device *evt)
+{
+}
+
+static void mips_broadcast(cpumask_t mask)
+{
+	unsigned int cpu;
+
+	for_each_cpu_mask(cpu, mask)
+		smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0);
+}
+
+static void setup_smtc_dummy_clockevent_device(void)
+{
+	//uint64_t mips_freq = mips_hpt_^frequency;
+	unsigned int cpu = smp_processor_id();
+	struct clock_event_device *cd;
+
+	cd = &per_cpu(smtc_dummy_clockevent_device, cpu);
+
+	cd->name		= "SMTC";
+	cd->features		= CLOCK_EVT_FEAT_DUMMY;
+
+	/* Calculate the min / max delta */
+	cd->mult	= 0; //div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
+	cd->shift		= 0; //32;
+	cd->max_delta_ns	= 0; //clockevent_delta2ns(0x7fffffff, cd);
+	cd->min_delta_ns	= 0; //clockevent_delta2ns(0x30, cd);
+
+	cd->rating		= 200;
+	cd->irq			= 17; //-1;
+//	if (cpu)
+//		cd->cpumask	= CPU_MASK_ALL; // cpumask_of_cpu(cpu);
+//	else
+		cd->cpumask	= cpumask_of_cpu(cpu);
+
+	cd->set_mode		= smtc_set_mode;
+
+	cd->broadcast		= mips_broadcast;
+
+	clockevents_register_device(cd);
+}
+#endif
+
+static void mips_event_handler(struct clock_event_device *dev)
+{
+}
+
+/*
+ * FIXME: This doesn't hold for the relocated E9000 compare interrupt.
+ */
+static int c0_compare_int_pending(void)
+{
+	return (read_c0_cause() >> cp0_compare_irq) & 0x100;
+}
+
+static int c0_compare_int_usable(void)
+{
+	const unsigned int delta = 0x300000;
+	unsigned int cnt;
+
+	/*
+	 * IP7 already pending?  Try to clear it by acking the timer.
+	 */
+	if (c0_compare_int_pending()) {
+		write_c0_compare(read_c0_count());
+		irq_disable_hazard();
+		if (c0_compare_int_pending())
+			return 0;
+	}
+
+	cnt = read_c0_count();
+	cnt += delta;
+	write_c0_compare(cnt);
+
+	while ((long)(read_c0_count() - cnt) <= 0)
+		;	/* Wait for expiry  */
+
+	if (!c0_compare_int_pending())
+		return 0;
+
+	write_c0_compare(read_c0_count());
+	irq_disable_hazard();
+	if (c0_compare_int_pending())
+		return 0;
+
+	/*
+	 * Feels like a real count / compare timer.
+	 */
+	return 1;
+}
+
+void __cpuinit mips_clockevent_init(void)
+{
+	uint64_t mips_freq = mips_hpt_frequency;
+	unsigned int cpu = smp_processor_id();
+	struct clock_event_device *cd;
+	unsigned int irq = MIPS_CPU_IRQ_BASE + 7;
+
+	if (!cpu_has_counter)
+		return;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+	setup_smtc_dummy_clockevent_device();
+
+	/*
+	 * On SMTC we only register VPE0's compare interrupt as clockevent
+	 * device.
+	 */
+	if (cpu)
+		return;
+#endif
+
+	if (!c0_compare_int_usable())
+		return;
+
+	cd = &per_cpu(mips_clockevent_device, cpu);
+
+	cd->name		= "MIPS";
+	cd->features		= CLOCK_EVT_FEAT_ONESHOT;
+
+	/* Calculate the min / max delta */
+	cd->mult	= div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
+	cd->shift		= 32;
+	cd->max_delta_ns	= clockevent_delta2ns(0x7fffffff, cd);
+	cd->min_delta_ns	= clockevent_delta2ns(0x300, cd);
+
+	cd->rating		= 300;
+	cd->irq			= irq;
+#ifdef CONFIG_MIPS_MT_SMTC
+	cd->cpumask		= CPU_MASK_ALL;
+#else
+	cd->cpumask		= cpumask_of_cpu(cpu);
+#endif
+	cd->set_next_event	= mips_next_event;
+	cd->set_mode		= mips_set_mode;
+	cd->event_handler	= mips_event_handler;
+
+	clockevents_register_device(cd);
+
+	if (!cp0_timer_irq_installed) {
+#ifdef CONFIG_MIPS_MT_SMTC
+#define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq)
+		setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT);
+#else
+		setup_irq(irq, &c0_compare_irqaction);
+#endif /* CONFIG_MIPS_MT_SMTC */
+		cp0_timer_irq_installed = 1;
+	}
+}
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index bf164a5..2367687 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -27,16 +27,6 @@
 
 #include <kernel-entry-init.h>
 
-	.macro	ARC64_TWIDDLE_PC
-#if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL)
-	/* We get launched at a XKPHYS address but the kernel is linked to
-	   run at a KSEG0 address, so jump there.  */
-	PTR_LA	t0, \@f
-	jr	t0
-\@:
-#endif
-	.endm
-
 	/*
 	 * inputs are the text nasid in t1, data nasid in t2.
 	 */
@@ -157,7 +147,11 @@
 
 	setup_c0_status_pri
 
-	ARC64_TWIDDLE_PC
+	/* We might not get launched at the address the kernel is linked to,
+	   so we jump there.  */
+	PTR_LA	t0, 0f
+	jr	t0
+0:
 
 #ifdef CONFIG_MIPS_MT_SMTC
 	/*
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index b997af7..7852c7c 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -1172,8 +1172,8 @@
 	prstatus.pr_sighold = current->blocked.sig[0];
 	psinfo.pr_pid = prstatus.pr_pid = current->pid;
 	psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid;
-	psinfo.pr_pgrp = prstatus.pr_pgrp = process_group(current);
-	psinfo.pr_sid = prstatus.pr_sid = process_session(current);
+	psinfo.pr_pgrp = prstatus.pr_pgrp = task_pgrp_nr(current);
+	psinfo.pr_sid = prstatus.pr_sid = task_session_nr(current);
 	if (current->pid == current->tgid) {
 		/*
 		 * This is the record for the group leader.  Add in the
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 85c2e38..a0a9105 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -609,7 +609,7 @@
 		p = list_entry(_p, struct task_struct, sibling);
 		if ((type == IRIX_P_PID) && p->pid != pid)
 			continue;
-		if ((type == IRIX_P_PGID) && process_group(p) != pid)
+		if ((type == IRIX_P_PGID) && task_pgrp_nr(p) != pid)
 			continue;
 		if ((p->exit_signal != SIGCHLD))
 			continue;
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index cb08014..e7ed0ac 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -381,7 +381,7 @@
 	return e;
 }
 
-/* Put in dbe list if neccessary. */
+/* Put in dbe list if necessary. */
 int module_finalize(const Elf_Ehdr *hdr,
 		    const Elf_Shdr *sechdrs,
 		    struct module *me)
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index ee7790d..4c477c7 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -763,11 +763,11 @@
 	printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
 #endif
 	if(!flags)
-		error = process_group(current);
+		error = task_pgrp_nr(current);
 	else
 		error = sys_setsid();
 #ifdef DEBUG_PROCGRPS
-	printk("returning %d\n", process_group(current));
+	printk("returning %d\n", task_pgrp_nr(current));
 #endif
 
 	return error;
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index e4b5e64..6c6849a 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -40,17 +40,6 @@
 #include <irq.h>
 
 /*
- * The integer part of the number of usecs per jiffy is taken from tick,
- * but the fractional part is not recorded, so we calculate it using the
- * initial value of HZ.  This aids systems where tick isn't really an
- * integer (e.g. for HZ = 128).
- */
-#define USECS_PER_JIFFY		TICK_SIZE
-#define USECS_PER_JIFFY_FRAC	((unsigned long)(u32)((1000000ULL << 32) / HZ))
-
-#define TICK_SIZE	(tick_nsec / 1000)
-
-/*
  * forward reference
  */
 DEFINE_SPINLOCK(rtc_lock);
@@ -72,14 +61,6 @@
 	return rtc_mips_set_mmss(now.tv_sec);
 }
 
-/* how many counter cycles in a jiffy */
-static unsigned long cycles_per_jiffy __read_mostly;
-
-/*
- * Null timer ack for systems not needing one (e.g. i8254).
- */
-static void null_timer_ack(void) { /* nothing */ }
-
 /*
  * Null high precision timer functions for systems lacking one.
  */
@@ -89,14 +70,6 @@
 }
 
 /*
- * Timer ack for an R4k-compatible timer of a known frequency.
- */
-static void c0_timer_ack(void)
-{
-	write_c0_compare(read_c0_compare());
-}
-
-/*
  * High precision timer functions for a R4k-compatible timer.
  */
 static cycle_t c0_hpt_read(void)
@@ -105,7 +78,6 @@
 }
 
 int (*mips_timer_state)(void);
-void (*mips_timer_ack)(void);
 
 /*
  * local_timer_interrupt() does profiling and process accounting
@@ -135,35 +107,6 @@
 EXPORT_SYMBOL(perf_irq);
 
 /*
- * Timer interrupt
- */
-int cp0_compare_irq;
-
-/*
- * Performance counter IRQ or -1 if shared with timer
- */
-int cp0_perfcount_irq;
-EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
-
-/*
- * Possibly handle a performance counter interrupt.
- * Return true if the timer interrupt should not be checked
- */
-static inline int handle_perf_irq(int r2)
-{
-	/*
-	 * The performance counter overflow interrupt may be shared with the
-	 * timer interrupt (cp0_perfcount_irq < 0). If it is and a
-	 * performance counter has overflowed (perf_irq() == IRQ_HANDLED)
-	 * and we can't reliably determine if a counter interrupt has also
-	 * happened (!r2) then don't check for a timer interrupt.
-	 */
-	return (cp0_perfcount_irq < 0) &&
-		perf_irq() == IRQ_HANDLED &&
-		!r2;
-}
-
-/*
  * time_init() - it does the following things.
  *
  * 1) plat_time_init() -
@@ -228,103 +171,48 @@
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static int mips_next_event(unsigned long delta,
-                           struct clock_event_device *evt)
-{
-	unsigned int cnt;
-	int res;
-
-#ifdef CONFIG_MIPS_MT_SMTC
-	{
-	unsigned long flags, vpflags;
-	local_irq_save(flags);
-	vpflags = dvpe();
-#endif
-	cnt = read_c0_count();
-	cnt += delta;
-	write_c0_compare(cnt);
-	res = ((long)(read_c0_count() - cnt ) > 0) ? -ETIME : 0;
-#ifdef CONFIG_MIPS_MT_SMTC
-	evpe(vpflags);
-	local_irq_restore(flags);
-	}
-#endif
-	return res;
-}
-
-static void mips_set_mode(enum clock_event_mode mode,
-                          struct clock_event_device *evt)
-{
-	/* Nothing to do ...  */
-}
-
-static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
-static int cp0_timer_irq_installed;
-
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
-	const int r2 = cpu_has_mips_r2;
-	struct clock_event_device *cd;
-	int cpu = smp_processor_id();
-
-	/*
-	 * Suckage alert:
-	 * Before R2 of the architecture there was no way to see if a
-	 * performance counter interrupt was pending, so we have to run
-	 * the performance counter interrupt handler anyway.
-	 */
-	if (handle_perf_irq(r2))
-		goto out;
-
-	/*
-	 * The same applies to performance counter interrupts.  But with the
-	 * above we now know that the reason we got here must be a timer
-	 * interrupt.  Being the paranoiacs we are we check anyway.
-	 */
-	if (!r2 || (read_c0_cause() & (1 << 30))) {
-		c0_timer_ack();
-#ifdef CONFIG_MIPS_MT_SMTC
-		if (cpu_data[cpu].vpe_id)
-			goto out;
-		cpu = 0;
-#endif
-		cd = &per_cpu(mips_clockevent_device, cpu);
-		cd->event_handler(cd);
-	}
-
-out:
-	return IRQ_HANDLED;
-}
-
-static struct irqaction timer_irqaction = {
-	.handler = timer_interrupt,
-#ifdef CONFIG_MIPS_MT_SMTC
-	.flags = IRQF_DISABLED,
-#else
-	.flags = IRQF_DISABLED | IRQF_PERCPU,
-#endif
-	.name = "timer",
-};
-
-static void __init init_mips_clocksource(void)
+void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
 {
 	u64 temp;
 	u32 shift;
 
+	/* Find a shift value */
+	for (shift = 32; shift > 0; shift--) {
+		temp = (u64) NSEC_PER_SEC << shift;
+		do_div(temp, clock);
+		if ((temp >> 32) == 0)
+			break;
+	}
+	cs->shift = shift;
+	cs->mult = (u32) temp;
+}
+
+void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
+	unsigned int clock)
+{
+	u64 temp;
+	u32 shift;
+
+	/* Find a shift value */
+	for (shift = 32; shift > 0; shift--) {
+		temp = (u64) clock << shift;
+		do_div(temp, NSEC_PER_SEC);
+		if ((temp >> 32) == 0)
+			break;
+	}
+	cd->shift = shift;
+	cd->mult = (u32) temp;
+}
+
+static void __init init_mips_clocksource(void)
+{
 	if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read)
 		return;
 
 	/* Calclate a somewhat reasonable rating value */
 	clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
-	/* Find a shift value */
-	for (shift = 32; shift > 0; shift--) {
-		temp = (u64) NSEC_PER_SEC << shift;
-		do_div(temp, mips_hpt_frequency);
-		if ((temp >> 32) == 0)
-			break;
-	}
-	clocksource_mips.shift = shift;
-	clocksource_mips.mult = (u32)temp;
+
+	clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
 
 	clocksource_register(&clocksource_mips);
 }
@@ -337,163 +225,6 @@
 {
 }
 
-#ifdef CONFIG_MIPS_MT_SMTC
-DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device);
-
-static void smtc_set_mode(enum clock_event_mode mode,
-                          struct clock_event_device *evt)
-{
-}
-
-int dummycnt[NR_CPUS];
-
-static void mips_broadcast(cpumask_t mask)
-{
-	unsigned int cpu;
-
-	for_each_cpu_mask(cpu, mask)
-		smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0);
-}
-
-static void setup_smtc_dummy_clockevent_device(void)
-{
-	//uint64_t mips_freq = mips_hpt_^frequency;
-	unsigned int cpu = smp_processor_id();
-	struct clock_event_device *cd;
-
-	cd = &per_cpu(smtc_dummy_clockevent_device, cpu);
-
-	cd->name		= "SMTC";
-	cd->features		= CLOCK_EVT_FEAT_DUMMY;
-
-	/* Calculate the min / max delta */
-	cd->mult	= 0; //div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
-	cd->shift		= 0; //32;
-	cd->max_delta_ns	= 0; //clockevent_delta2ns(0x7fffffff, cd);
-	cd->min_delta_ns	= 0; //clockevent_delta2ns(0x30, cd);
-
-	cd->rating		= 200;
-	cd->irq			= 17; //-1;
-//	if (cpu)
-//		cd->cpumask	= CPU_MASK_ALL; // cpumask_of_cpu(cpu);
-//	else
-		cd->cpumask	= cpumask_of_cpu(cpu);
-
-	cd->set_mode		= smtc_set_mode;
-
-	cd->broadcast		= mips_broadcast;
-
-	clockevents_register_device(cd);
-}
-#endif
-
-static void mips_event_handler(struct clock_event_device *dev)
-{
-}
-
-/*
- * FIXME: This doesn't hold for the relocated E9000 compare interrupt.
- */
-static int c0_compare_int_pending(void)
-{
-	return (read_c0_cause() >> cp0_compare_irq) & 0x100;
-}
-
-static int c0_compare_int_usable(void)
-{
-	const unsigned int delta = 0x300000;
-	unsigned int cnt;
-
-	/*
-	 * IP7 already pending?  Try to clear it by acking the timer.
-	 */
-	if (c0_compare_int_pending()) {
-		write_c0_compare(read_c0_compare());
-		irq_disable_hazard();
-		if (c0_compare_int_pending())
-			return 0;
-	}
-
-	cnt = read_c0_count();
-	cnt += delta;
-	write_c0_compare(cnt);
-
-	while ((long)(read_c0_count() - cnt) <= 0)
-		;	/* Wait for expiry  */
-
-	if (!c0_compare_int_pending())
-		return 0;
-
-	write_c0_compare(read_c0_compare());
-	irq_disable_hazard();
-	if (c0_compare_int_pending())
-		return 0;
-
-	/*
-	 * Feels like a real count / compare timer.
-	 */
-	return 1;
-}
-
-void __cpuinit mips_clockevent_init(void)
-{
-	uint64_t mips_freq = mips_hpt_frequency;
-	unsigned int cpu = smp_processor_id();
-	struct clock_event_device *cd;
-	unsigned int irq = MIPS_CPU_IRQ_BASE + 7;
-
-	if (!cpu_has_counter)
-		return;
-
-#ifdef CONFIG_MIPS_MT_SMTC
-	setup_smtc_dummy_clockevent_device();
-
-	/*
-	 * On SMTC we only register VPE0's compare interrupt as clockevent
-	 * device.
-	 */
-	if (cpu)
-		return;
-#endif
-
-	if (!c0_compare_int_usable())
-		return;
-
-	cd = &per_cpu(mips_clockevent_device, cpu);
-
-	cd->name		= "MIPS";
-	cd->features		= CLOCK_EVT_FEAT_ONESHOT;
-
-	/* Calculate the min / max delta */
-	cd->mult	= div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
-	cd->shift		= 32;
-	cd->max_delta_ns	= clockevent_delta2ns(0x7fffffff, cd);
-	cd->min_delta_ns	= clockevent_delta2ns(0x300, cd);
-
-	cd->rating		= 300;
-	cd->irq			= irq;
-#ifdef CONFIG_MIPS_MT_SMTC
-	cd->cpumask		= CPU_MASK_ALL;
-#else
-	cd->cpumask		= cpumask_of_cpu(cpu);
-#endif
-	cd->set_next_event	= mips_next_event;
-	cd->set_mode		= mips_set_mode;
-	cd->event_handler	= mips_event_handler;
-
-	clockevents_register_device(cd);
-
-	if (!cp0_timer_irq_installed) {
-#ifdef CONFIG_MIPS_MT_SMTC
-#define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq)
-		setup_irq_smtc(irq, &timer_irqaction, CPUCTR_IMASKBIT);
-#else
-		setup_irq(irq, &timer_irqaction);
-#endif /* CONFIG_MIPS_MT_SMTC */
-		cp0_timer_irq_installed = 1;
-	}
-}
-
 void __init time_init(void)
 {
 	plat_time_init();
@@ -512,14 +243,6 @@
 		if (!clocksource_mips.read) {
 			/* No external high precision timer -- use R4k.  */
 			clocksource_mips.read = c0_hpt_read;
-
-			if (!mips_timer_state) {
-				/* No external timer interrupt -- use R4k.  */
-				mips_timer_ack = c0_timer_ack;
-				/* Calculate cache parameters.  */
-				cycles_per_jiffy =
-					(mips_hpt_frequency + HZ / 2) / HZ;
-			}
 		}
 		if (!mips_hpt_frequency)
 			mips_hpt_frequency = calibrate_hpt();
@@ -528,29 +251,8 @@
 		printk("Using %u.%03u MHz high precision timer.\n",
 		       ((mips_hpt_frequency + 500) / 1000) / 1000,
 		       ((mips_hpt_frequency + 500) / 1000) % 1000);
-
-#ifdef CONFIG_IRQ_CPU
-		setup_irq(MIPS_CPU_IRQ_BASE + 7, &timer_irqaction);
-#endif
 	}
 
-	if (!mips_timer_ack)
-		/* No timer interrupt ack (e.g. i8254).  */
-		mips_timer_ack = null_timer_ack;
-
-	/*
-	 * Call board specific timer interrupt setup.
-	 *
-	 * this pointer must be setup in machine setup routine.
-	 *
-	 * Even if a machine chooses to use a low-level timer interrupt,
-	 * it still needs to setup the timer_irqaction.
-	 * In that case, it might be better to set timer_irqaction.handler
-	 * to be NULL function so that we are sure the high-level code
-	 * is not invoked accidentally.
-	 */
-	plat_timer_setup(&timer_irqaction);
-
 	init_mips_clocksource();
 	mips_clockevent_init();
 }
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index bbf01b8..fa50078 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -314,7 +314,7 @@
 	__show_regs(regs);
 	print_modules();
 	printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
-	        current->comm, current->pid, current_thread_info(), current);
+	        current->comm, task_pid_nr(current), current_thread_info(), current);
 	show_stacktrace(current, regs);
 	show_code((unsigned int __user *) regs->cp0_epc);
 	printk("\n");
@@ -1336,6 +1336,17 @@
 extern void tlb_init(void);
 extern void flush_tlb_handlers(void);
 
+/*
+ * Timer interrupt
+ */
+int cp0_compare_irq;
+
+/*
+ * Performance counter IRQ or -1 if shared with timer
+ */
+int cp0_perfcount_irq;
+EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
+
 void __init per_cpu_trap_init(void)
 {
 	unsigned int cpu = smp_processor_id();
diff --git a/arch/mips/lemote/lm2e/setup.c b/arch/mips/lemote/lm2e/setup.c
index 09314a2..2cc6745 100644
--- a/arch/mips/lemote/lm2e/setup.c
+++ b/arch/mips/lemote/lm2e/setup.c
@@ -53,11 +53,6 @@
 unsigned int memsize;
 unsigned int highmemsize = 0;
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	setup_irq(MIPS_CPU_IRQ_BASE + 7, irq);
-}
-
 void __init plat_time_init(void)
 {
 	/* setup mips r4k timer */
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
index 1d00b77..9d6243a 100644
--- a/arch/mips/mips-boards/generic/time.c
+++ b/arch/mips/mips-boards/generic/time.c
@@ -147,21 +147,8 @@
 #endif
 }
 
-//static irqreturn_t mips_perf_interrupt(int irq, void *dev_id)
-//{
-//	return perf_irq();
-//}
-
-//static struct irqaction perf_irqaction = {
-//	.handler = mips_perf_interrupt,
-//	.flags = IRQF_DISABLED | IRQF_PERCPU,
-//	.name = "performance",
-//};
-
 void __init plat_perf_setup(void)
 {
-//	struct irqaction *irq = &perf_irqaction;
-
 	cp0_perfcount_irq = -1;
 
 #ifdef MSC01E_INT_BASE
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 98b5e5b..b1b4052 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -13,6 +13,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/string.h>
+#include <linux/scatterlist.h>
 
 #include <asm/cache.h>
 #include <asm/io.h>
@@ -165,12 +166,11 @@
 	for (i = 0; i < nents; i++, sg++) {
 		unsigned long addr;
 
-		addr = (unsigned long) page_address(sg->page);
+		addr = (unsigned long) sg_virt(sg);
 		if (!plat_device_is_coherent(dev) && addr)
-			__dma_sync(addr + sg->offset, sg->length, direction);
+			__dma_sync(addr, sg->length, direction);
 		sg->dma_address = plat_map_dma_mem(dev,
-				                   (void *)(addr + sg->offset),
-						   sg->length);
+				                   (void *)addr, sg->length);
 	}
 
 	return nents;
@@ -223,10 +223,9 @@
 	for (i = 0; i < nhwentries; i++, sg++) {
 		if (!plat_device_is_coherent(dev) &&
 		    direction != DMA_TO_DEVICE) {
-			addr = (unsigned long) page_address(sg->page);
+			addr = (unsigned long) sg_virt(sg);
 			if (addr)
-				__dma_sync(addr + sg->offset, sg->length,
-				           direction);
+				__dma_sync(addr, sg->length, direction);
 		}
 		plat_unmap_dma_mem(sg->dma_address);
 	}
@@ -304,7 +303,7 @@
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nelems; i++, sg++) {
 		if (cpu_is_noncoherent_r10000(dev))
-			__dma_sync((unsigned long)page_address(sg->page),
+			__dma_sync((unsigned long)page_address(sg_page(sg)),
 			           sg->length, direction);
 		plat_unmap_dma_mem(sg->dma_address);
 	}
@@ -322,7 +321,7 @@
 	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nelems; i++, sg++) {
 		if (!plat_device_is_coherent(dev))
-			__dma_sync((unsigned long)page_address(sg->page),
+			__dma_sync((unsigned long)page_address(sg_page(sg)),
 			           sg->length, direction);
 		plat_unmap_dma_mem(sg->dma_address);
 	}
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 5699c77..fa636fc 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -173,7 +173,7 @@
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (is_init(tsk)) {
+	if (is_global_init(tsk)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
diff --git a/arch/mips/oprofile/Kconfig b/arch/mips/oprofile/Kconfig
deleted file mode 100644
index fb6f235..0000000
--- a/arch/mips/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING && !MIPS_MT_SMTC && EXPERIMENTAL
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
-endmenu
-
diff --git a/arch/mips/pci/pci-excite.c b/arch/mips/pci/pci-excite.c
index 3c86c77..8a56876 100644
--- a/arch/mips/pci/pci-excite.c
+++ b/arch/mips/pci/pci-excite.c
@@ -131,7 +131,7 @@
 		ocd_writel(0x00000000, bar + 0x100);
 	}
 
-	/* Finally, enable the PCI interupt */
+	/* Finally, enable the PCI interrupt */
 #if USB_IRQ > 7
 	set_c0_intcontrol(1 << USB_IRQ);
 #else
diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig
index abbd0bb..6b293ce 100644
--- a/arch/mips/pmc-sierra/Kconfig
+++ b/arch/mips/pmc-sierra/Kconfig
@@ -4,11 +4,13 @@
 
 config PMC_MSP4200_EVAL
 	bool "PMC-Sierra MSP4200 Eval Board"
+	select CEVT_R4K
 	select IRQ_MSP_SLP
 	select HW_HAS_PCI
 
 config PMC_MSP4200_GW
 	bool "PMC-Sierra MSP4200 VoIP Gateway"
+	select CEVT_R4K
 	select IRQ_MSP_SLP
 	select HW_HAS_PCI
 
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_time.c b/arch/mips/pmc-sierra/msp71xx/msp_time.c
index f221d47..7cfeda5 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_time.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_time.c
@@ -86,8 +86,5 @@
 #ifdef CONFIG_IRQ_MSP_CIC
 	/* we are using the vpe0 counter for timer interrupts */
 	setup_irq(MSP_INT_VPE0_TIMER, irq);
-#else
-	/* we are using the mips counter for timer interrupts */
-	setup_irq(MSP_INT_TIMER, irq);
 #endif
 }
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
index 015fcc3..855977c 100644
--- a/arch/mips/pmc-sierra/yosemite/setup.c
+++ b/arch/mips/pmc-sierra/yosemite/setup.c
@@ -137,11 +137,6 @@
 	return 0;
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	setup_irq(7, irq);
-}
-
 void __init plat_time_init(void)
 {
 	mips_hpt_frequency = cpu_clock_freq / 2;
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
index 681b593..3305fa9 100644
--- a/arch/mips/sgi-ip27/ip27-init.c
+++ b/arch/mips/sgi-ip27/ip27-init.c
@@ -110,7 +110,7 @@
 	}
 }
 
-void __init per_cpu_init(void)
+void __cpuinit per_cpu_init(void)
 {
 	int cpu = smp_processor_id();
 	int slice = LOCAL_HUB_L(PI_CPU_NUM);
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 856649c..1bb692a 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -374,14 +374,13 @@
 	return irq;
 }
 
-extern void ip27_rt_timer_interrupt(void);
-
 asmlinkage void plat_irq_dispatch(void)
 {
 	unsigned long pending = read_c0_cause() & read_c0_status();
+	extern unsigned int rt_timer_irq;
 
 	if (pending & CAUSEF_IP4)
-		ip27_rt_timer_interrupt();
+		do_IRQ(rt_timer_irq);
 	else if (pending & CAUSEF_IP2)	/* PI_INT_PEND_0 or CC_PEND_{A|B} */
 		ip27_do_irq_mask0();
 	else if (pending & CAUSEF_IP3)	/* PI_INT_PEND_1 */
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index b7b3479..f5dccf0 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -3,6 +3,7 @@
  * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/bcd.h>
+#include <linux/clockchips.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -25,22 +26,8 @@
 #include <asm/sn/sn0/ip27.h>
 #include <asm/sn/sn0/hub.h>
 
-/*
- * This is a hack; we really need to figure these values out dynamically
- *
- * Since 800 ns works very well with various HUB frequencies, such as
- * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
- *
- * Ralf: which clock rate is used to feed the counter?
- */
-#define NSEC_PER_CYCLE		800
-#define CYCLES_PER_SEC		(NSEC_PER_SEC/NSEC_PER_CYCLE)
-#define CYCLES_PER_JIFFY	(CYCLES_PER_SEC/HZ)
-
 #define TICK_SIZE (tick_nsec / 1000)
 
-static unsigned long ct_cur[NR_CPUS];	/* What counter should be at next timer irq */
-
 #if 0
 static int set_rtc_mmss(unsigned long nowtime)
 {
@@ -86,36 +73,6 @@
 }
 #endif
 
-static unsigned int rt_timer_irq;
-
-void ip27_rt_timer_interrupt(void)
-{
-	int cpu = smp_processor_id();
-	int cpuA = cputoslice(cpu) == 0;
-	unsigned int irq = rt_timer_irq;
-
-	irq_enter();
-	write_seqlock(&xtime_lock);
-
-again:
-	LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0);	/* Ack  */
-	ct_cur[cpu] += CYCLES_PER_JIFFY;
-	LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]);
-
-	if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu])
-		goto again;
-
-	kstat_this_cpu.irqs[irq]++;		/* kstat only for bootcpu? */
-
-	if (cpu == 0)
-		do_timer(1);
-
-	update_process_times(user_mode(get_irq_regs()));
-
-	write_sequnlock(&xtime_lock);
-	irq_exit();
-}
-
 /* Includes for ioc3_init().  */
 #include <asm/sn/types.h>
 #include <asm/sn/sn0/addrs.h>
@@ -171,33 +128,109 @@
 	.eoi		= enable_rt_irq,
 };
 
-static struct irqaction rt_irqaction = {
-	.handler	= (irq_handler_t) ip27_rt_timer_interrupt,
-	.flags		= IRQF_DISABLED,
-	.mask		= CPU_MASK_NONE,
-	.name		= "timer"
+static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
+{
+	unsigned int cpu = smp_processor_id();
+	int slice = cputoslice(cpu) == 0;
+	unsigned long cnt;
+
+	cnt = LOCAL_HUB_L(PI_RT_COUNT);
+	cnt += delta;
+	LOCAL_HUB_S(slice ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, cnt);
+
+	return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0;
+}
+
+static void rt_set_mode(enum clock_event_mode mode,
+		struct clock_event_device *evt)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* The only mode supported */
+		break;
+
+	case CLOCK_EVT_MODE_PERIODIC:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_RESUME:
+		/* Nothing to do  */
+		break;
+	}
+}
+
+unsigned int rt_timer_irq;
+
+static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
+{
+	struct clock_event_device *cd = dev_id;
+	unsigned int cpu = smp_processor_id();
+	int slice = cputoslice(cpu) == 0;
+
+	LOCAL_HUB_S(slice ? PI_RT_PEND_A : PI_RT_PEND_B, 0);	/* Ack  */
+	cd->event_handler(cd);
+
+	return IRQ_HANDLED;
+}
+
+struct irqaction hub_rt_irqaction = {
+	.handler	= hub_rt_counter_handler,
+	.flags		= IRQF_DISABLED | IRQF_PERCPU,
+	.name		= "hub-rt",
 };
 
-void __init plat_timer_setup(struct irqaction *irq)
+/*
+ * This is a hack; we really need to figure these values out dynamically
+ *
+ * Since 800 ns works very well with various HUB frequencies, such as
+ * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
+ *
+ * Ralf: which clock rate is used to feed the counter?
+ */
+#define NSEC_PER_CYCLE		800
+#define CYCLES_PER_SEC		(NSEC_PER_SEC / NSEC_PER_CYCLE)
+
+static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent);
+static DEFINE_PER_CPU(char [11], hub_rt_name);
+
+static void __cpuinit hub_rt_clock_event_init(void)
 {
-	int irqno  = allocate_irqno();
+	unsigned int cpu = smp_processor_id();
+	struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu);
+	unsigned char *name = per_cpu(hub_rt_name, cpu);
+	int irq = rt_timer_irq;
 
-	if (irqno < 0)
-		panic("Can't allocate interrupt number for timer interrupt");
+	sprintf(name, "hub-rt %d", cpu);
+	cd->name		= "HUB-RT",
+	cd->features		= CLOCK_EVT_FEAT_ONESHOT,
+	clockevent_set_clock(cd, CYCLES_PER_SEC);
+	cd->max_delta_ns        = clockevent_delta2ns(0xfffffffffffff, cd);
+	cd->min_delta_ns        = clockevent_delta2ns(0x300, cd);
+	cd->rating		= 200,
+	cd->irq			= irq,
+	cd->cpumask		= cpumask_of_cpu(cpu),
+	cd->rating		= 300,
+	cd->set_next_event	= rt_next_event,
+	cd->set_mode		= rt_set_mode,
+	clockevents_register_device(cd);
+}
 
-	set_irq_chip_and_handler(irqno, &rt_irq_type, handle_percpu_irq);
+static void __init hub_rt_clock_event_global_init(void)
+{
+	unsigned int irq;
 
-	/* over-write the handler, we use our own way */
-	irq->handler = no_action;
+	do {
+		smp_wmb();
+		irq = rt_timer_irq;
+		if (irq)
+			break;
 
-	/* setup irqaction */
-	irq_desc[irqno].status |= IRQ_PER_CPU;
+		irq = allocate_irqno();
+		if (irq < 0)
+			panic("Allocation of irq number for timer failed");
+	} while (xchg(&rt_timer_irq, irq));
 
-	rt_timer_irq = irqno;
-	/*
-	 * Only needed to get /proc/interrupt to display timer irq stats
-	 */
-	setup_irq(irqno, &rt_irqaction);
+	set_irq_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq);
+	setup_irq(irq, &hub_rt_irqaction);
 }
 
 static cycle_t hub_rt_read(void)
@@ -205,21 +238,29 @@
 	return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT);
 }
 
-struct clocksource ht_rt_clocksource = {
-	.name	= "HUB",
+struct clocksource hub_rt_clocksource = {
+	.name	= "HUB-RT",
 	.rating	= 200,
 	.read	= hub_rt_read,
 	.mask	= CLOCKSOURCE_MASK(52),
-	.shift	= 32,
 	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-void __init plat_time_init(void)
+static void __init hub_rt_clocksource_init(void)
 {
-	clocksource_register(&ht_rt_clocksource);
+	struct clocksource *cs = &hub_rt_clocksource;
+
+	clocksource_set_clock(cs, CYCLES_PER_SEC);
+	clocksource_register(cs);
 }
 
-void __init cpu_time_init(void)
+void __init plat_time_init(void)
+{
+	hub_rt_clocksource_init();
+	hub_rt_clock_event_global_init();
+}
+
+void __cpuinit cpu_time_init(void)
 {
 	lboard_t *board;
 	klcpu_t *cpu;
@@ -237,6 +278,7 @@
 
 	printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
 
+	hub_rt_clock_event_init();
 	set_c0_status(SRB_TIMOCLK);
 }
 
@@ -248,17 +290,12 @@
 	 * node and timeouts will not happen there.
 	 */
 	if (get_compact_nodeid() == cnode) {
-		int cpu = smp_processor_id();
 		LOCAL_HUB_S(PI_RT_EN_A, 1);
 		LOCAL_HUB_S(PI_RT_EN_B, 1);
 		LOCAL_HUB_S(PI_PROF_EN_A, 0);
 		LOCAL_HUB_S(PI_PROF_EN_B, 0);
-		ct_cur[cpu] = CYCLES_PER_JIFFY;
-		LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]);
 		LOCAL_HUB_S(PI_RT_COUNT, 0);
 		LOCAL_HUB_S(PI_RT_PEND_A, 0);
-		LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]);
-		LOCAL_HUB_S(PI_RT_COUNT, 0);
 		LOCAL_HUB_S(PI_RT_PEND_B, 0);
 	}
 }
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c
index fc75bfc..1024bf4 100644
--- a/arch/mips/sgi-ip32/ip32-setup.c
+++ b/arch/mips/sgi-ip32/ip32-setup.c
@@ -80,12 +80,6 @@
 	printk("%d MHz CPU detected\n", mips_hpt_frequency * 2 / 1000000);
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	irq->handler = no_action;
-	setup_irq(MIPS_CPU_IRQ_BASE + 7, irq);
-}
-
 void __init plat_mem_setup(void)
 {
 	board_be_init = ip32_be_init;
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 7aa79bf..10299ba 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -452,6 +452,43 @@
 
 extern void bcm1480_mailbox_interrupt(void);
 
+static inline void dispatch_ip4(void)
+{
+	int cpu = smp_processor_id();
+	int irq = K_BCM1480_INT_TIMER_0 + cpu;
+
+	/* Reset the timer */
+	__raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
+	            IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+
+	do_IRQ(irq);
+}
+
+static inline void dispatch_ip2(void)
+{
+	unsigned long long mask_h, mask_l;
+	unsigned int cpu = smp_processor_id();
+	unsigned long base;
+
+	/*
+	 * Default...we've hit an IP[2] interrupt, which means we've got to
+	 * check the 1480 interrupt registers to figure out what to do.  Need
+	 * to detect which CPU we're on, now that smp_affinity is supported.
+	 */
+	base = A_BCM1480_IMR_MAPPER(cpu);
+	mask_h = __raw_readq(
+		IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
+	mask_l = __raw_readq(
+		IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
+
+	if (mask_h) {
+		if (mask_h ^ 1)
+			do_IRQ(fls64(mask_h) - 1);
+		else if (mask_l)
+			do_IRQ(63 + fls64(mask_l));
+	}
+}
+
 asmlinkage void plat_irq_dispatch(void)
 {
 	unsigned int pending;
@@ -469,17 +506,8 @@
 	else
 #endif
 
-	if (pending & CAUSEF_IP4) {
-		int cpu = smp_processor_id();
-		int irq = K_BCM1480_INT_TIMER_0 + cpu;
-
-		/* Reset the timer */
-		__raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
-		            IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
-
-		do_IRQ(irq);
-	}
-
+	if (pending & CAUSEF_IP4)
+		dispatch_ip4();
 #ifdef CONFIG_SMP
 	else if (pending & CAUSEF_IP3)
 		bcm1480_mailbox_interrupt();
@@ -490,27 +518,6 @@
 		bcm1480_kgdb_interrupt();		/* KGDB (uart 1) */
 #endif
 
-	else if (pending & CAUSEF_IP2) {
-		unsigned long long mask_h, mask_l;
-		unsigned long base;
-
-		/*
-		 * Default...we've hit an IP[2] interrupt, which means we've
-		 * got to check the 1480 interrupt registers to figure out what
-		 * to do.  Need to detect which CPU we're on, now that
-		 * smp_affinity is supported.
-		 */
-		base = A_BCM1480_IMR_MAPPER(smp_processor_id());
-		mask_h = __raw_readq(
-			IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
-		mask_l = __raw_readq(
-			IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
-
-		if (mask_h) {
-			if (mask_h ^ 1)
-				do_IRQ(fls64(mask_h) - 1);
-			else
-				do_IRQ(63 + fls64(mask_l));
-		}
-	}
+	else if (pending & CAUSEF_IP2)
+		dispatch_ip2();
 }
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
index 6eac36d..436ba78 100644
--- a/arch/mips/sibyte/bcm1480/smp.c
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -58,7 +58,7 @@
 /*
  * SMP init and finish on secondary CPUs
  */
-void bcm1480_smp_init(void)
+void __cpuinit bcm1480_smp_init(void)
 {
 	unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
 		STATUSF_IP1 | STATUSF_IP0;
@@ -67,10 +67,11 @@
 	change_c0_status(ST0_IM, imask);
 }
 
-void bcm1480_smp_finish(void)
+void __cpuinit bcm1480_smp_finish(void)
 {
-	extern void bcm1480_time_init(void);
-	bcm1480_time_init();
+	extern void sb1480_clockevent_init(void);
+
+	sb1480_clockevent_init();
 	local_irq_enable();
 }
 
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c
index 5b4bfbb..610f025 100644
--- a/arch/mips/sibyte/bcm1480/time.c
+++ b/arch/mips/sibyte/bcm1480/time.c
@@ -15,23 +15,12 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
-
-/*
- * These are routines to set up and handle interrupts from the
- * bcm1480 general purpose timer 0.  We're using the timer as a
- * system clock, so we set it up to run at 100 Hz.  On every
- * interrupt, we update our idea of what the time of day is,
- * then call do_timer() in the architecture-independent kernel
- * code to do general bookkeeping (e.g. update jiffies, run
- * bottom halves, etc.)
- */
 #include <linux/clockchips.h>
 #include <linux/interrupt.h>
-#include <linux/sched.h>
+#include <linux/irq.h>
+#include <linux/percpu.h>
 #include <linux/spinlock.h>
-#include <linux/kernel_stat.h>
 
-#include <asm/irq.h>
 #include <asm/addrspace.h>
 #include <asm/time.h>
 #include <asm/io.h>
@@ -48,33 +37,10 @@
 #define IMR_IP3_VAL	K_BCM1480_INT_MAP_I1
 #define IMR_IP4_VAL	K_BCM1480_INT_MAP_I2
 
-#ifdef CONFIG_SIMULATION
-#define BCM1480_HPT_VALUE	50000
-#else
-#define BCM1480_HPT_VALUE	1000000
-#endif
-
 extern int bcm1480_steal_irq(int irq);
 
-void __init plat_time_init(void)
-{
-	unsigned int cpu = smp_processor_id();
-	unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
-
-	BUG_ON(cpu > 3);	/* Only have 4 general purpose timers */
-
-	bcm1480_mask_irq(cpu, irq);
-
-	/* Map the timer interrupt to ip[4] of this cpu */
-	__raw_writeq(IMR_IP4_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H)
-	      + (irq<<3)));
-
-	bcm1480_unmask_irq(cpu, irq);
-	bcm1480_steal_irq(irq);
-}
-
 /*
- * The general purpose timer ticks at 1 Mhz independent if
+ * The general purpose timer ticks at 1MHz independent if
  * the rest of the system
  */
 static void sibyte_set_mode(enum clock_event_mode mode,
@@ -89,7 +55,7 @@
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 		__raw_writeq(0, timer_cfg);
-		__raw_writeq(BCM1480_HPT_VALUE / HZ - 1, timer_init);
+		__raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init);
 		__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
 			     timer_cfg);
 		break;
@@ -101,76 +67,117 @@
 		break;
 
 	case CLOCK_EVT_MODE_UNUSED:	/* shuddup gcc */
+	case CLOCK_EVT_MODE_RESUME:
 		;
 	}
 }
 
-struct clock_event_device sibyte_hpt_clockevent = {
-	.name		= "bcm1480-counter",
-	.features	= CLOCK_EVT_FEAT_PERIODIC,
-	.set_mode	= sibyte_set_mode,
-	.shift		= 32,
-	.irq		= 0,
-};
+static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
+{
+	unsigned int cpu = smp_processor_id();
+	void __iomem *timer_init;
+	unsigned int cnt;
+	int res;
+
+	timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
+	cnt = __raw_readq(timer_init);
+	cnt += delta;
+	__raw_writeq(cnt, timer_init);
+	res = ((long)(__raw_readq(timer_init) - cnt ) > 0) ? -ETIME : 0;
+
+	return res;
+}
 
 static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
 {
-	struct clock_event_device *cd = &sibyte_hpt_clockevent;
 	unsigned int cpu = smp_processor_id();
+	struct clock_event_device *cd = dev_id;
+	void __iomem *timer_cfg;
+
+	timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
 
 	/* Reset the timer */
-	__raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
-	             IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+	__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+	             timer_cfg);
 	cd->event_handler(cd);
 
 	return IRQ_HANDLED;
 }
 
-static struct irqaction sibyte_counter_irqaction = {
-	.handler	= sibyte_counter_handler,
-	.flags		= IRQF_DISABLED | IRQF_PERCPU,
-	.name		= "timer",
-};
+static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
+static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
+static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
 
-/*
- * This interrupt is "special" in that it doesn't use the request_irq
- * way to hook the irq line.  The timer interrupt is initialized early
- * enough to make this a major pain, and it's also firing enough to
- * warrant a bit of special case code.  bcm1480_timer_interrupt is
- * called directly from irq_handler.S when IP[4] is set during an
- * interrupt
- */
-static void __init sb1480_clockevent_init(void)
+void __cpuinit sb1480_clockevent_init(void)
 {
 	unsigned int cpu = smp_processor_id();
 	unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
+	struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
+	struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
+	unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
 
-	setup_irq(irq, &sibyte_counter_irqaction);
-}
+	BUG_ON(cpu > 3);	/* Only have 4 general purpose timers */
 
-void bcm1480_timer_interrupt(void)
-{
-	int cpu = smp_processor_id();
-	int irq = K_BCM1480_INT_TIMER_0 + cpu;
+	sprintf(name, "bcm1480-counter %d", cpu);
+	cd->name		= name;
+	cd->features		= CLOCK_EVT_FEAT_PERIODIC |
+				  CLOCK_EVT_MODE_ONESHOT;
+	clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
+	cd->max_delta_ns	= clockevent_delta2ns(0x7fffff, cd);
+	cd->min_delta_ns	= clockevent_delta2ns(1, cd);
+	cd->rating		= 200;
+	cd->irq			= irq;
+	cd->cpumask		= cpumask_of_cpu(cpu);
+	cd->set_next_event	= sibyte_next_event;
+	cd->set_mode		= sibyte_set_mode;
+	clockevents_register_device(cd);
 
-	/* Reset the timer */
-	__raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
-	      IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+	bcm1480_mask_irq(cpu, irq);
 
-	ll_timer_interrupt(irq);
+	/*
+	 * Map timer interrupt to IP[4] of this cpu
+	 */
+	__raw_writeq(IMR_IP4_VAL,
+		     IOADDR(A_BCM1480_IMR_REGISTER(cpu,
+			R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3)));
+
+	bcm1480_unmask_irq(cpu, irq);
+	bcm1480_steal_irq(irq);
+
+	action->handler	= sibyte_counter_handler;
+	action->flags	= IRQF_DISABLED | IRQF_PERCPU;
+	action->name	= name;
+	action->dev_id	= cd;
+	setup_irq(irq, action);
 }
 
 static cycle_t bcm1480_hpt_read(void)
 {
-	/* We assume this function is called xtime_lock held. */
-	unsigned long count =
-		__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
-	return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count;
+	return (cycle_t) __raw_readq(IOADDR(A_SCD_ZBBUS_CYCLE_COUNT));
 }
 
-void __init bcm1480_hpt_setup(void)
+struct clocksource bcm1480_clocksource = {
+	.name	= "zbbus-cycles",
+	.rating	= 200,
+	.read	= bcm1480_hpt_read,
+	.mask	= CLOCKSOURCE_MASK(64),
+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init sb1480_clocksource_init(void)
 {
-	clocksource_mips.read = bcm1480_hpt_read;
-	mips_hpt_frequency = BCM1480_HPT_VALUE;
+	struct clocksource *cs = &bcm1480_clocksource;
+	unsigned int plldiv;
+	unsigned long zbbus;
+
+	plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+	zbbus = ((plldiv >> 1) * 50000000) + ((plldiv & 1) * 25000000);
+	clocksource_set_clock(cs, zbbus);
+	clocksource_register(cs);
+}
+
+void __init plat_time_init(void)
+{
+	sb1480_clocksource_init();
 	sb1480_clockevent_init();
 }
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index 7659174..53780a1 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -400,43 +400,27 @@
 
 #endif 	/* CONFIG_KGDB */
 
-static inline void sb1250_timer_interrupt(void)
-{
-	int cpu = smp_processor_id();
-	int irq = K_INT_TIMER_0 + cpu;
-
-	irq_enter();
-	kstat_this_cpu.irqs[irq]++;
-
-	write_seqlock(&xtime_lock);
-
-	/* ACK interrupt */
-	____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
-		       IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
-
-	/*
-	 * call the generic timer interrupt handling
-	 */
-	do_timer(1);
-
-	write_sequnlock(&xtime_lock);
-
-	/*
-	 * In UP mode, we call local_timer_interrupt() to do profiling
-	 * and process accouting.
-	 *
-	 * In SMP mode, local_timer_interrupt() is invoked by appropriate
-	 * low-level local timer interrupt handler.
-	 */
-	local_timer_interrupt(irq);
-
-	irq_exit();
-}
-
 extern void sb1250_mailbox_interrupt(void);
 
+static inline void dispatch_ip2(void)
+{
+	unsigned int cpu = smp_processor_id();
+	unsigned long long mask;
+
+	/*
+	 * Default...we've hit an IP[2] interrupt, which means we've got to
+	 * check the 1250 interrupt registers to figure out what to do.  Need
+	 * to detect which CPU we're on, now that smp_affinity is supported.
+	 */
+	mask = __raw_readq(IOADDR(A_IMR_REGISTER(cpu,
+				  R_IMR_INTERRUPT_STATUS_BASE)));
+	if (mask)
+		do_IRQ(fls64(mask) - 1);
+}
+
 asmlinkage void plat_irq_dispatch(void)
 {
+	unsigned int cpu = smp_processor_id();
 	unsigned int pending;
 
 	/*
@@ -454,7 +438,7 @@
 	if (pending & CAUSEF_IP7) /* CPU performance counter interrupt */
 		do_IRQ(MIPS_CPU_IRQ_BASE + 7);
 	else if (pending & CAUSEF_IP4)
-		sb1250_timer_interrupt();
+		do_IRQ(K_INT_TIMER_0 + cpu); 	/* sb1250_timer_interrupt() */
 
 #ifdef CONFIG_SMP
 	else if (pending & CAUSEF_IP3)
@@ -466,21 +450,8 @@
 		sb1250_kgdb_interrupt();
 #endif
 
-	else if (pending & CAUSEF_IP2) {
-		unsigned long long mask;
-
-		/*
-		 * Default...we've hit an IP[2] interrupt, which means we've
-		 * got to check the 1250 interrupt registers to figure out what
-		 * to do.  Need to detect which CPU we're on, now that
-		 * smp_affinity is supported.
-		 */
-		mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(),
-		                              R_IMR_INTERRUPT_STATUS_BASE)));
-		if (mask)
-			do_IRQ(fls64(mask) - 1);
-		else
-			spurious_interrupt();
-	} else
+	else if (pending & CAUSEF_IP2)
+		dispatch_ip2();
+	else
 		spurious_interrupt();
 }
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
index c38e1f3..3f52c95 100644
--- a/arch/mips/sibyte/sb1250/smp.c
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -46,7 +46,7 @@
 /*
  * SMP init and finish on secondary CPUs
  */
-void sb1250_smp_init(void)
+void __cpuinit sb1250_smp_init(void)
 {
 	unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
 		STATUSF_IP1 | STATUSF_IP0;
@@ -55,10 +55,11 @@
 	change_c0_status(ST0_IM, imask);
 }
 
-void sb1250_smp_finish(void)
+void __cpuinit sb1250_smp_finish(void)
 {
-	extern void sb1250_time_init(void);
-	sb1250_time_init();
+	extern void sb1250_clockevent_init(void);
+
+	sb1250_clockevent_init();
 	local_irq_enable();
 }
 
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
index fe11fed..a41e908 100644
--- a/arch/mips/sibyte/sb1250/time.c
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -52,26 +52,6 @@
 
 extern int sb1250_steal_irq(int irq);
 
-static cycle_t sb1250_hpt_read(void);
-
-void __init sb1250_hpt_setup(void)
-{
-	int cpu = smp_processor_id();
-
-	if (!cpu) {
-		/* Setup hpt using timer #3 but do not enable irq for it */
-		__raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG)));
-		__raw_writeq(SB1250_HPT_VALUE,
-			     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_INIT)));
-		__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
-			     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG)));
-
-		mips_hpt_frequency = V_SCD_TIMER_FREQ;
-		clocksource_mips.read = sb1250_hpt_read;
-		clocksource_mips.mask = M_SCD_TIMER_INIT;
-	}
-}
-
 /*
  * The general purpose timer ticks at 1 Mhz independent if
  * the rest of the system
@@ -100,6 +80,7 @@
 		break;
 
 	case CLOCK_EVT_MODE_UNUSED:	/* shuddup gcc */
+	case CLOCK_EVT_MODE_RESUME:
 		;
 	}
 }
@@ -120,18 +101,14 @@
 	return 0;
 }
 
-struct clock_event_device sibyte_hpt_clockevent = {
-	.name		= "sb1250-counter",
-	.features	= CLOCK_EVT_FEAT_PERIODIC,
-	.set_mode	= sibyte_set_mode,
-	.set_next_event	= sibyte_next_event,
-	.shift		= 32,
-	.irq		= 0,
-};
-
 static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
 {
-	struct clock_event_device *cd = &sibyte_hpt_clockevent;
+	unsigned int cpu = smp_processor_id();
+	struct clock_event_device *cd = dev_id;
+
+	/* ACK interrupt */
+	____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+		       IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
 
 	cd->event_handler(cd);
 
@@ -144,87 +121,35 @@
 	.name		= "timer",
 };
 
-/*
- * The general purpose timer ticks at 1 Mhz independent if
- * the rest of the system
- */
-static void sibyte_set_mode(enum clock_event_mode mode,
-                           struct clock_event_device *evt)
+static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
+static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
+static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
+
+void __cpuinit sb1250_clockevent_init(void)
 {
 	unsigned int cpu = smp_processor_id();
-	void __iomem *timer_cfg, *timer_init;
-
-	timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
-	timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
-
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		__raw_writeq(0, timer_cfg);
-		__raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init);
-		__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
-			     timer_cfg);
-		break;
-
-	case CLOCK_EVT_MODE_ONESHOT:
-		/* Stop the timer until we actually program a shot */
-	case CLOCK_EVT_MODE_SHUTDOWN:
-		__raw_writeq(0, timer_cfg);
-		break;
-
-	case CLOCK_EVT_MODE_UNUSED:	/* shuddup gcc */
-		;
-	}
-}
-
-static int
-sibyte_next_event(unsigned long delta, struct clock_event_device *evt)
-{
-	unsigned int cpu = smp_processor_id();
-	void __iomem *timer_cfg, *timer_init;
-
-	timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
-	timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
-
-	__raw_writeq(0, timer_cfg);
-	__raw_writeq(delta, timer_init);
-	__raw_writeq(M_SCD_TIMER_ENABLE, timer_cfg);
-
-	return 0;
-}
-
-struct clock_event_device sibyte_hpt_clockevent = {
-	.name		= "sb1250-counter",
-	.features	= CLOCK_EVT_FEAT_PERIODIC,
-	.set_mode	= sibyte_set_mode,
-	.set_next_event	= sibyte_next_event,
-	.shift		= 32,
-	.irq		= 0,
-};
-
-static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
-{
-	struct clock_event_device *cd = &sibyte_hpt_clockevent;
-
-	cd->event_handler(cd);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction sibyte_irqaction = {
-	.handler	= sibyte_counter_handler,
-	.flags		= IRQF_DISABLED | IRQF_PERCPU,
-	.name		= "timer",
-};
-
-static void __init sb1250_clockevent_init(void)
-{
-	struct clock_event_device *cd = &sibyte_hpt_clockevent;
-	unsigned int cpu = smp_processor_id();
-	int irq = K_INT_TIMER_0 + cpu;
+	unsigned int irq = K_INT_TIMER_0 + cpu;
+	struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
+	struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
+	unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
 
 	/* Only have 4 general purpose timers, and we use last one as hpt */
 	BUG_ON(cpu > 2);
 
+	sprintf(name, "bcm1480-counter %d", cpu);
+	cd->name		= name;
+	cd->features		= CLOCK_EVT_FEAT_PERIODIC |
+				  CLOCK_EVT_MODE_ONESHOT;
+	clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
+	cd->max_delta_ns	= clockevent_delta2ns(0x7fffff, cd);
+	cd->min_delta_ns	= clockevent_delta2ns(1, cd);
+	cd->rating		= 200;
+	cd->irq			= irq;
+	cd->cpumask		= cpumask_of_cpu(cpu);
+	cd->set_next_event	= sibyte_next_event;
+	cd->set_mode		= sibyte_set_mode;
+	clockevents_register_device(cd);
+
 	sb1250_mask_irq(cpu, irq);
 
 	/* Map the timer interrupt to ip[4] of this cpu */
@@ -236,23 +161,11 @@
 	sb1250_unmask_irq(cpu, irq);
 	sb1250_steal_irq(irq);
 
-	/*
-	 * This interrupt is "special" in that it doesn't use the request_irq
-	 * way to hook the irq line.  The timer interrupt is initialized early
-	 * enough to make this a major pain, and it's also firing enough to
-	 * warrant a bit of special case code.  sb1250_timer_interrupt is
-	 * called directly from irq_handler.S when IP[4] is set during an
-	 * interrupt
-	 */
+	action->handler	= sibyte_counter_handler;
+	action->flags	= IRQF_DISABLED | IRQF_PERCPU;
+	action->name	= name;
+	action->dev_id	= cd;
 	setup_irq(irq, &sibyte_irqaction);
-
-	clockevents_register_device(cd);
-}
-
-void __init plat_time_init(void)
-{
-	sb1250_clocksource_init();
-	sb1250_clockevent_init();
 }
 
 /*
@@ -267,3 +180,36 @@
 
 	return SB1250_HPT_VALUE - count;
 }
+
+struct clocksource bcm1250_clocksource = {
+	.name	= "MIPS",
+	.rating	= 200,
+	.read	= sb1250_hpt_read,
+	.mask	= CLOCKSOURCE_MASK(23),
+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init sb1250_clocksource_init(void)
+{
+	struct clocksource *cs = &bcm1250_clocksource;
+
+	/* Setup hpt using timer #3 but do not enable irq for it */
+	__raw_writeq(0,
+		     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
+						 R_SCD_TIMER_CFG)));
+	__raw_writeq(SB1250_HPT_VALUE,
+		     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
+						 R_SCD_TIMER_INIT)));
+	__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+		     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
+						 R_SCD_TIMER_CFG)));
+
+	clocksource_set_clock(cs, V_SCD_TIMER_FREQ);
+	clocksource_register(cs);
+}
+
+void __init plat_time_init(void)
+{
+	sb1250_clocksource_init();
+	sb1250_clockevent_init();
+}
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index 8b3ef0e..080c966 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -69,31 +69,6 @@
 	return "SiByte " SIBYTE_BOARD_NAME;
 }
 
-void __init plat_time_init(void)
-{
-#if defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
-	/* Setup HPT */
-	sb1250_hpt_setup();
-#endif
-}
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
-        /*
-         * we don't set up irqaction, because we will deliver timer
-         * interrupts through low-level (direct) meachanism.
-         */
-
-        /* We only need to setup the generic timer */
-#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
-	bcm1480_time_init();
-#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
-	sb1250_time_init();
-#else
-#error invalid SiByte board configuration
-#endif
-}
-
 int swarm_be_handler(struct pt_regs *regs, int is_fixup)
 {
 	if (!is_fixup && (regs->cp0_cause & 4)) {
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c
index 39bb15f..4df070f 100644
--- a/arch/mips/sni/pcimt.c
+++ b/arch/mips/sni/pcimt.c
@@ -246,7 +246,7 @@
 		/*
 		 * Note: ASIC PCI's builtin interrupt achknowledge feature is
 		 * broken.  Using it may result in loss of some or all i8259
-		 * interupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
+		 * interrupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
 		 */
 		irq = i8259_irq();
 		if (unlikely(irq < 0))
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
index b808773..0910b35 100644
--- a/arch/mips/sni/time.c
+++ b/arch/mips/sni/time.c
@@ -121,15 +121,6 @@
 	setup_pit_timer();
 }
 
-/*
- * R4k counter based timer interrupt. Works on RM200-225 and possibly
- * others but not on RM400
- */
-static void __init sni_cpu_timer_setup(struct irqaction *irq)
-{
-        setup_irq(SNI_MIPS_IRQ_CPU_TIMER, irq);
-}
-
 void __init plat_timer_setup(struct irqaction *irq)
 {
 	switch (sni_brd_type) {
@@ -139,15 +130,6 @@
 	case SNI_BRD_MINITOWER:
 	        sni_a20r_timer_setup(irq);
 	        break;
-
-	case SNI_BRD_PCI_TOWER:
-	case SNI_BRD_RM200:
-	case SNI_BRD_PCI_MTOWER:
-	case SNI_BRD_PCI_DESKTOP:
-	case SNI_BRD_PCI_TOWER_CPLUS:
-	case SNI_BRD_PCI_MTOWER_CPLUS:
-	        sni_cpu_timer_setup(irq);
-	        break;
 	}
 }
 
diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c
index 8ce0989..36c5f20 100644
--- a/arch/mips/tx4927/common/tx4927_setup.c
+++ b/arch/mips/tx4927/common/tx4927_setup.c
@@ -72,22 +72,6 @@
 #endif
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	setup_irq(TX4927_IRQ_CPU_TIMER, irq);
-
-#ifdef CONFIG_TOSHIBA_RBTX4927
-	{
-		extern void toshiba_rbtx4927_timer_setup(struct irqaction
-							 *irq);
-		toshiba_rbtx4927_timer_setup(irq);
-	}
-#endif
-
-	return;
-}
-
-
 #ifdef DEBUG
 void print_cp0(char *key, int num, char *name, u32 val)
 {
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index b97102a..c7470fb 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -94,7 +94,6 @@
 #define TOSHIBA_RBTX4927_SETUP_EFWFU       ( 1 <<  3 )
 #define TOSHIBA_RBTX4927_SETUP_SETUP       ( 1 <<  4 )
 #define TOSHIBA_RBTX4927_SETUP_TIME_INIT   ( 1 <<  5 )
-#define TOSHIBA_RBTX4927_SETUP_TIMER_SETUP ( 1 <<  6 )
 #define TOSHIBA_RBTX4927_SETUP_PCIBIOS     ( 1 <<  7 )
 #define TOSHIBA_RBTX4927_SETUP_PCI1        ( 1 <<  8 )
 #define TOSHIBA_RBTX4927_SETUP_PCI2        ( 1 <<  9 )
@@ -108,7 +107,6 @@
     (TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO |
      TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR |
      TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP |
-     TOSHIBA_RBTX4927_SETUP_TIME_INIT | TOSHIBA_RBTX4927_SETUP_TIMER_SETUP
      | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 |
      TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66);
 #endif
@@ -947,14 +945,6 @@
 
 }
 
-void __init toshiba_rbtx4927_timer_setup(struct irqaction *irq)
-{
-	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP,
-				       "-\n");
-	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP,
-				       "+\n");
-}
-
 static int __init toshiba_rbtx4927_rtc_init(void)
 {
 	static struct resource __initdata res = {
diff --git a/arch/mips/tx4938/common/setup.c b/arch/mips/tx4938/common/setup.c
index ab40822..3ba4101 100644
--- a/arch/mips/tx4938/common/setup.c
+++ b/arch/mips/tx4938/common/setup.c
@@ -24,7 +24,7 @@
 #include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/irq.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/bootinfo.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -43,8 +43,3 @@
 {
 	toshiba_rbtx4938_setup();
 }
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	setup_irq(TX4938_IRQ_CPU_TIMER, irq);
-}
diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig
index 8f4d3e7..eeb089f 100644
--- a/arch/mips/vr41xx/Kconfig
+++ b/arch/mips/vr41xx/Kconfig
@@ -5,6 +5,7 @@
 
 config CASIO_E55
 	bool "CASIO CASSIOPEIA E-10/15/55/65"
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select IRQ_CPU
 	select ISA
@@ -13,6 +14,7 @@
 
 config IBM_WORKPAD
 	bool "IBM WorkPad z50"
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select IRQ_CPU
 	select ISA
@@ -21,6 +23,7 @@
 
 config NEC_CMBVR4133
 	bool "NEC CMB-VR4133"
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select IRQ_CPU
 	select HW_HAS_PCI
@@ -29,6 +32,7 @@
 
 config TANBAC_TB022X
 	bool "TANBAC VR4131 multichip module and TANBAC VR4131DIMM"
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select IRQ_CPU
 	select HW_HAS_PCI
@@ -43,6 +47,7 @@
 
 config VICTOR_MPC30X
 	bool "Victor MP-C303/304"
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select IRQ_CPU
 	select HW_HAS_PCI
@@ -52,6 +57,7 @@
 
 config ZAO_CAPCELLA
 	bool "ZAO Networks Capcella"
+	select CEVT_R4K
 	select DMA_NONCOHERENT
 	select IRQ_CPU
 	select HW_HAS_PCI
diff --git a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c
index 407cec2..8d760df 100644
--- a/arch/mips/vr41xx/common/init.c
+++ b/arch/mips/vr41xx/common/init.c
@@ -48,11 +48,6 @@
 		mips_hpt_frequency = tclock / 4;
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	setup_irq(TIMER_IRQ, irq);
-}
-
 void __init plat_mem_setup(void)
 {
 	vr41xx_calculate_clock_frequency();
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 3d73545..b8ef178 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -267,7 +267,7 @@
 
 source "fs/Kconfig"
 
-source "arch/parisc/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/parisc/Kconfig.debug"
 
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index f3d0d7c7..ae4a9b3 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -19,26 +19,27 @@
 NM		= sh $(srctree)/arch/parisc/nm
 CHECKFLAGS	+= -D__hppa__=1
 
+MACHINE		:= $(shell uname -m)
+ifeq ($(MACHINE),parisc*)
+NATIVE		:= 1
+endif
+
 ifdef CONFIG_64BIT
-CROSS_COMPILE	:= $(shell if [ -x /usr/bin/hppa64-linux-gnu-gcc ]; then \
-			echo hppa64-linux-gnu-; else echo hppa64-linux-; fi)
 UTS_MACHINE	:= parisc64
 CHECKFLAGS	+= -D__LP64__=1 -m64
-else
-MACHINE := $(subst 64,,$(shell uname -m))
-ifneq ($(MACHINE),parisc)
-CROSS_COMPILE	:= hppa-linux-
-endif
+WIDTH		:= 64
+CROSS_COMPILE	:= hppa64-linux-gnu-
+else # 32-bit
+WIDTH		:=
 endif
 
-FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align 
+# attempt to help out folks who are cross-compiling
+ifeq ($(NATIVE),1)
+CROSS_COMPILE	:= hppa$(WIDTH)-linux-
+endif
 
 OBJCOPY_FLAGS =-O binary -R .note -R .comment -S
 
-ifneq ($(call cc-ifversion, -lt, 0303, "bad"),)
-$(error Sorry, GCC v3.3 or above is required.)
-endif
-
 cflags-y	:= -pipe
 
 # These flags should be implied by an hppa-linux configuration, but they
@@ -69,7 +70,7 @@
 kernel-$(CONFIG_HPUX)		+= hpux/
 
 core-y	+= $(addprefix arch/parisc/, $(kernel-y))
-libs-y	+= arch/parisc/lib/ `$(CC) -print-libgcc-file-name`
+libs-y	+= arch/parisc/lib/
 
 drivers-$(CONFIG_OPROFILE)		+= arch/parisc/oprofile/
 
@@ -77,27 +78,27 @@
 	elif [ -x /sbin/palo ]; then echo /sbin/palo; \
 	fi)
 
+PALOCONF := $(shell if [ -f $(src)/palo.conf ]; then echo $(src)/palo.conf; \
+	else echo $(obj)/palo.conf; \
+	fi)
+
 palo: vmlinux
-	@if [ -x $PALO ]; then \
+	@if test ! -x "$(PALO)"; then \
 		echo 'ERROR: Please install palo first (apt-get install palo)';\
 		echo 'or build it from source and install it somewhere in your $$PATH';\
 		false; \
 	fi
-	@if [ ! -f ./palo.conf ]; then \
-		cp arch/parisc/defpalo.conf palo.conf; \
-		echo 'A generic palo config file (./palo.conf) has been created for you.'; \
+	@if test ! -f "$(PALOCONF)"; then \
+		cp $(src)/arch/parisc/defpalo.conf $(obj)/palo.conf; \
+		echo 'A generic palo config file ($(obj)/palo.conf) has been created for you.'; \
 		echo 'You should check it and re-run "make palo".'; \
 		echo 'WARNING: the "lifimage" file is now placed in this directory by default!'; \
 		false; \
 	fi
-	$(PALO) -f ./palo.conf
+	$(PALO) -f $(PALOCONF)
 
-oldpalo: vmlinux
-	export TOPDIR=`pwd`; \
-	unset STRIP LDFLAGS CPP CPPFLAGS AFLAGS CFLAGS CC LD; cd ../palo && make lifimage
-
-# Shorthands for known targets not supported by parisc, use palo as default
-Image zImage bzImage: palo
+# Shorthands for known targets not supported by parisc, use vmlinux as default
+Image zImage bzImage: vmlinux
 
 kernel_install: vmlinux
 	sh $(src)/arch/parisc/install.sh \
@@ -116,3 +117,12 @@
 	@echo  '		  (distribution) /sbin/installkernel or'
 	@echo  '		  copy to $$(INSTALL_PATH)'
 endef
+
+# we require gcc 3.3 or above to compile the kernel
+archprepare: checkbin
+checkbin:
+	@if test "$(call cc-version)" -lt "0303"; then \
+		echo -n "Sorry, GCC v3.3 or above is required to build " ; \
+		echo "the kernel." ; \
+		false ; \
+	fi
diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig
index 41fd069..9fc96e7 100644
--- a/arch/parisc/configs/712_defconfig
+++ b/arch/parisc/configs/712_defconfig
@@ -1,39 +1,51 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-pa6
-# Sun Mar 26 19:59:51 2006
+# Linux kernel version: 2.6.23
+# Fri Oct 12 21:00:07 2007
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
 CONFIG_STACK_GROWSUP=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_IRQ_PER_CPU=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # General setup
 #
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -43,31 +55,29 @@
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 # 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
+# CONFIG_BLK_DEV_BSG is not set
 
 #
 # IO Schedulers
@@ -91,6 +101,9 @@
 # CONFIG_PA7300LC is not set
 # CONFIG_PA8X00 is not set
 CONFIG_PA11=y
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
 # CONFIG_SMP is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 # CONFIG_PREEMPT_NONE is not set
@@ -98,6 +111,7 @@
 # CONFIG_PREEMPT is not set
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -108,6 +122,9 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
 # CONFIG_HPUX is not set
 
 #
@@ -120,6 +137,7 @@
 # CONFIG_GSC_WAX is not set
 # CONFIG_EISA is not set
 # CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -127,14 +145,11 @@
 # CONFIG_PCCARD is not set
 
 #
-# PCI Hotplug Support
-#
-
-#
 # PA-RISC specific drivers
 #
 CONFIG_CHASSIS_LCD_LED=y
 # CONFIG_PDC_CHASSIS is not set
+CONFIG_PDC_CHASSIS_WARN=y
 CONFIG_PDC_STABLE=y
 
 #
@@ -151,13 +166,15 @@
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -174,17 +191,23 @@
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_TCP_DIAG=m
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-
-#
-# IP: Virtual Server Configuration
-#
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 
@@ -192,37 +215,18 @@
 # Core Netfilter Configuration
 #
 # CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
 # CONFIG_NETFILTER_XTABLES is not set
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-# CONFIG_IP_NF_PPTP is not set
 CONFIG_IP_NF_QUEUE=m
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
 # 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
@@ -234,7 +238,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -250,7 +253,17 @@
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -259,39 +272,24 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 # CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
 CONFIG_PARPORT=y
 CONFIG_PARPORT_PC=m
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
-CONFIG_PARPORT_NOT_PC=y
 CONFIG_PARPORT_GSC=y
+# CONFIG_PARPORT_AX88796 is not set
 # CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_PARPORT_NOT_PC=y
+CONFIG_BLK_DEV=y
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
@@ -300,13 +298,11 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_IDE is not set
 
 #
@@ -314,6 +310,9 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -333,104 +332,61 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
 CONFIG_SCSI_ISCSI_ATTRS=m
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_PPA is not set
 # CONFIG_SCSI_IMM is not set
 CONFIG_SCSI_LASI700=y
 CONFIG_53C700_LE_ON_BE=y
 # CONFIG_SCSI_ZALON is not set
 CONFIG_SCSI_DEBUG=m
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM 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_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=m
-
-#
-# PHY device support
-#
+# CONFIG_VETH is not set
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
 CONFIG_LASI_82596=y
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
 # CONFIG_NET_POCKET is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
 
 #
-# Ethernet (1000 Mbit)
+# Wireless LAN
 #
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_ATMEL is not set
-# CONFIG_HOSTAP is not set
-
-#
-# Wan interfaces
-#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_PLIP is not set
 CONFIG_PPP=m
@@ -442,26 +398,22 @@
 CONFIG_PPP_BSDCOMP=m
 CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # 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
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -486,14 +438,22 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_KEYBOARD_HIL_OLD is not set
 CONFIG_KEYBOARD_HIL=y
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
 CONFIG_MOUSE_SERIAL=m
 # CONFIG_MOUSE_VSXXXAA is not set
 CONFIG_MOUSE_HIL=m
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -516,6 +476,7 @@
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -523,6 +484,7 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_GSC=y
 CONFIG_SERIAL_8250_NR_UARTS=17
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
@@ -545,36 +507,15 @@
 # CONFIG_LP_CONSOLE is not set
 CONFIG_PPDEV=m
 # CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
 CONFIG_GEN_RTC=y
 CONFIG_GEN_RTC_X=y
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
 
 #
@@ -582,46 +523,59 @@
 #
 # 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_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# Multimedia Capabilities Port drivers
+# 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
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
 CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
 CONFIG_FB_STI=y
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
@@ -633,6 +587,7 @@
 CONFIG_DUMMY_CONSOLE_COLUMNS=128
 CONFIG_DUMMY_CONSOLE_ROWS=48
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
 # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_STI_CONSOLE=y
 CONFIG_FONTS=y
@@ -646,16 +601,11 @@
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
 # CONFIG_FONT_10x18 is not set
-
-#
-# Logo configuration
-#
 CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_PARISC_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -673,9 +623,11 @@
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
@@ -685,8 +637,10 @@
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_VIRMIDI is not set
 # CONFIG_SND_MTPAV is not set
+# CONFIG_SND_MTS64 is not set
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
+# CONFIG_SND_PORTMAN2X4 is not set
 
 #
 # GSC devices
@@ -694,15 +648,25 @@
 CONFIG_SND_HARMONY=y
 
 #
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
+
+#
 # Open Sound System
 #
 # CONFIG_SOUND_PRIME is not set
-
-#
-# USB support
-#
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+CONFIG_USB_SUPPORT=y
 # CONFIG_USB_ARCH_HAS_HCD is not set
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -712,19 +676,28 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
 # CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_RTC_CLASS is not set
 
 #
-# InfiniBand support
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
 #
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# DMA Devices
 #
+# CONFIG_AUXDISPLAY is not set
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
 
 #
 # File systems
@@ -734,6 +707,7 @@
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
@@ -744,15 +718,16 @@
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
-CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -783,11 +758,12 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -795,6 +771,7 @@
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -806,6 +783,8 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
 
 #
 # Network File Systems
@@ -827,6 +806,7 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_RPCSEC_GSS_SPKM3=m
 CONFIG_SMB_FS=m
@@ -834,12 +814,13 @@
 CONFIG_SMB_NLS_REMOTE="cp437"
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
 # CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_CIFS_EXPERIMENTAL 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
@@ -892,6 +873,11 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 CONFIG_PROFILING=y
@@ -901,21 +887,32 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
+# 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_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=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=y
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 CONFIG_DEBUG_RODATA=y
 
 #
@@ -924,12 +921,13 @@
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
@@ -938,9 +936,18 @@
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -949,21 +956,28 @@
 CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_KHAZAD=m
 CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_SEED is not set
 CONFIG_CRYPTO_DEFLATE=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_TEST=m
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
index f3b812f..ea07121 100644
--- a/arch/parisc/configs/a500_defconfig
+++ b/arch/parisc/configs/a500_defconfig
@@ -1,73 +1,98 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc5-pa1
-# Fri Oct 21 23:04:54 2005
+# Linux kernel version: 2.6.23
+# Fri Oct 12 21:12:44 2007
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
 CONFIG_STACK_GROWSUP=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+CONFIG_TIME_LOW_RES=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ARCH_MAY_HAVE_PC_FDC=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_IRQ_PER_CPU=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # General setup
 #
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BLOCK_COMPAT=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
 
 #
 # Processor type and features
@@ -80,11 +105,23 @@
 CONFIG_PA20=y
 CONFIG_PREFETCH=y
 CONFIG_64BIT=y
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_NODES_SHIFT=3
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -95,7 +132,10 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=y
 # CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_PREEMPT is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
 CONFIG_COMPAT=y
 CONFIG_NR_CPUS=8
 
@@ -104,7 +144,7 @@
 #
 # CONFIG_GSC is not set
 CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_DEBUG is not set
 CONFIG_PCI_LBA=y
 CONFIG_IOSAPIC=y
@@ -124,13 +164,14 @@
 # PC-card bridges
 #
 CONFIG_YENTA=m
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
 CONFIG_PD6729=m
 CONFIG_I82092=m
 CONFIG_PCCARD_NONSTATIC=m
-
-#
-# PCI Hotplug Support
-#
 # CONFIG_HOTPLUG_PCI is not set
 
 #
@@ -139,6 +180,7 @@
 # CONFIG_SUPERIO is not set
 # CONFIG_CHASSIS_LCD_LED is not set
 CONFIG_PDC_CHASSIS=y
+CONFIG_PDC_CHASSIS_WARN=y
 CONFIG_PDC_STABLE=y
 
 #
@@ -160,7 +202,10 @@
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -177,97 +222,97 @@
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-
-#
-# IP: Virtual Server Configuration
-#
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IP_VS is not set
 CONFIG_IPV6=m
 # CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
 CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
 # CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-# CONFIG_IP_NF_PPTP is not set
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
+# CONFIG_IP_NF_MATCH_AH is not set
 CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
 CONFIG_IP_NF_MATCH_OWNER=m
 # CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_REALM is not set
-CONFIG_IP_NF_MATCH_SCTP=m
-# CONFIG_IP_NF_MATCH_DCCP is not set
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-# CONFIG_IP_NF_MATCH_STRING is not set
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_TARGET_NFQUEUE is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
 # CONFIG_IP_NF_TARGET_TTL is not set
-CONFIG_IP_NF_TARGET_CONNMARK=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
@@ -277,48 +322,38 @@
 #
 # CONFIG_IP6_NF_QUEUE is not set
 CONFIG_IP6_NF_IPTABLES=m
-# CONFIG_IP6_NF_MATCH_LIMIT is not set
-CONFIG_IP6_NF_MATCH_MAC=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_MATCH_OPTS=m
 CONFIG_IP6_NF_MATCH_FRAG=m
 CONFIG_IP6_NF_MATCH_HL=m
-# CONFIG_IP6_NF_MATCH_MULTIPORT is not set
 # CONFIG_IP6_NF_MATCH_OWNER is not set
-# CONFIG_IP6_NF_MATCH_MARK is not set
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-# CONFIG_IP6_NF_MATCH_AHESP is not set
-# CONFIG_IP6_NF_MATCH_LENGTH is not set
+# CONFIG_IP6_NF_MATCH_AH is not set
+# CONFIG_IP6_NF_MATCH_MH is not set
 # CONFIG_IP6_NF_MATCH_EUI64 is not set
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_TARGET_REJECT=m
-# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
 CONFIG_IP6_NF_MANGLE=m
-# CONFIG_IP6_NF_TARGET_MARK is not set
 # CONFIG_IP6_NF_TARGET_HL is not set
 CONFIG_IP6_NF_RAW=m
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 CONFIG_IP_DCCP=m
 CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
 
 #
 # DCCP CCIDs Configuration (EXPERIMENTAL)
 #
+CONFIG_IP_DCCP_CCID2=m
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
 # CONFIG_IP_DCCP_CCID3 is not set
 
 #
 # DCCP Kernel Hacking
 #
 # CONFIG_IP_DCCP_DEBUG is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -329,11 +364,13 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -342,7 +379,17 @@
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -351,34 +398,17 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 # CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -391,21 +421,14 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
 # CONFIG_IDE is not set
 
 #
@@ -413,6 +436,9 @@
 #
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -432,18 +458,18 @@
 CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=m
 CONFIG_SCSI_ISCSI_ATTRS=m
-CONFIG_SCSI_SAS_ATTRS=m
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -451,59 +477,40 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-CONFIG_SCSI_QLOGIC_FC=m
-# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
 CONFIG_SCSI_QLOGIC_1280=m
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-CONFIG_SCSI_QLA2300=m
-CONFIG_SCSI_QLA2322=m
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 CONFIG_SCSI_DEBUG=m
-
-#
-# PCMCIA SCSI adapter support
-#
-CONFIG_PCMCIA_FDOMAIN=m
-CONFIG_PCMCIA_QLOGIC=m
-CONFIG_PCMCIA_SYM53C500=m
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 # CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
@@ -517,39 +524,25 @@
 # CONFIG_FUSION_SAS is not set
 CONFIG_FUSION_MAX_SGE=128
 CONFIG_FUSION_CTL=m
+# CONFIG_FUSION_LOGGING is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
+# CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
 # CONFIG_I2O is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=m
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
 # CONFIG_HAPPYMEAL is not set
@@ -558,10 +551,6 @@
 CONFIG_NET_VENDOR_3COM=y
 CONFIG_VORTEX=m
 CONFIG_TYPHOON=m
-
-#
-# Tulip family network device support
-#
 CONFIG_NET_TULIP=y
 CONFIG_DE2104X=m
 CONFIG_TULIP=y
@@ -573,15 +562,18 @@
 # CONFIG_DM9102 is not set
 # CONFIG_ULI526X is not set
 CONFIG_PCMCIA_XIRCOM=m
-# CONFIG_PCMCIA_XIRTULIP is not set
 CONFIG_HP100=m
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
+# CONFIG_PCNET32_NAPI is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=m
 # CONFIG_FEALNX is not set
@@ -593,84 +585,46 @@
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+# CONFIG_SC92031 is not set
+CONFIG_NETDEV_1000=y
 CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
 CONFIG_E1000_NAPI=y
 # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
 # CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
 # CONFIG_TR is not set
 
 #
-# Wireless LAN (non-hamradio)
+# Wireless LAN
 #
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_PCMCIA_WAVELAN is not set
-CONFIG_PCMCIA_NETWAVE=m
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-CONFIG_PCMCIA_RAYCS=m
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=m
-CONFIG_PLX_HERMES=m
-CONFIG_TMD_HERMES=m
-# CONFIG_NORTEL_HERMES is not set
-CONFIG_PCI_HERMES=m
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-# CONFIG_PCMCIA_SPECTRUM is not set
-CONFIG_AIRO_CS=m
-CONFIG_PCMCIA_WL3501=m
-
-#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-# CONFIG_PRISM54 is not set
-# CONFIG_HOSTAP is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
-#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 CONFIG_NET_PCMCIA=y
 CONFIG_PCMCIA_3C589=m
 CONFIG_PCMCIA_3C574=m
@@ -680,10 +634,6 @@
 CONFIG_PCMCIA_SMC91C92=m
 CONFIG_PCMCIA_XIRC2PS=m
 # CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -694,28 +644,25 @@
 CONFIG_PPP_SYNC_TTY=m
 CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# 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
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -732,6 +679,7 @@
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -747,6 +695,7 @@
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -754,8 +703,10 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_CS=m
 CONFIG_SERIAL_8250_NR_UARTS=17
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -765,83 +716,73 @@
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_MUX is not set
 CONFIG_PDC_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM 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
-
-#
-# Ftape, the floppy tape device driver
-#
+CONFIG_AGP=y
+CONFIG_AGP_PARISC=y
 # CONFIG_DRM is not set
 
 #
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 
 #
-# Dallas's 1-wire bus
+# SPI support
 #
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# Multimedia Capabilities Port drivers
+# 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
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
 
 #
@@ -856,32 +797,45 @@
 # Sound
 #
 # CONFIG_SOUND is not set
-
-#
-# USB support
-#
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB 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
-
-#
-# InfiniBand support
-#
+# CONFIG_NEW_LEDS is not set
 # CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
 
 #
-# SN Devices
+# DMA Engine support
 #
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
 
 #
 # File systems
@@ -891,6 +845,7 @@
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
@@ -901,14 +856,16 @@
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
-CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -939,18 +896,20 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-# CONFIG_HUGETLBFS is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -963,6 +922,7 @@
 # CONFIG_SYSV_FS is not set
 CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
 
 #
 # Network File Systems
@@ -983,6 +943,7 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
+# CONFIG_SUNRPC_BIND34 is not set
 CONFIG_RPCSEC_GSS_KRB5=m
 CONFIG_RPCSEC_GSS_SPKM3=m
 CONFIG_SMB_FS=m
@@ -990,12 +951,13 @@
 CONFIG_SMB_NLS_REMOTE="cp437"
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
 # CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_CIFS_EXPERIMENTAL 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
@@ -1048,6 +1010,11 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 CONFIG_PROFILING=y
@@ -1057,19 +1024,34 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_IOREMAP is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=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 is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_RWLOCK is not set
+# CONFIG_DEBUG_RODATA is not set
 
 #
 # Security options
@@ -1077,12 +1059,13 @@
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
 CONFIG_CRYPTO_NULL=m
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
@@ -1091,32 +1074,47 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
 CONFIG_CRYPTO_BLOWFISH=m
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
 # CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_CAST5 is not set
+CONFIG_CRYPTO_CAST5=m
 # CONFIG_CRYPTO_CAST6 is not set
 # CONFIG_CRYPTO_TEA is not set
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 CONFIG_CRYPTO_DEFLATE=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_TEST=m
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig
index 3509361..1bf22c9 100644
--- a/arch/parisc/configs/b180_defconfig
+++ b/arch/parisc/configs/b180_defconfig
@@ -1,38 +1,47 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc1-pa0
-# Tue Jan 17 08:21:01 2006
+# Linux kernel version: 2.6.23
+# Fri Oct 12 21:16:46 2007
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
 CONFIG_STACK_GROWSUP=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
-
-#
-# Code maturity level options
-#
-# CONFIG_EXPERIMENTAL is not set
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_IRQ_PER_CPU=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # General setup
 #
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -42,30 +51,27 @@
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
-
-#
-# Block layer
-#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
 
 #
 # IO Schedulers
@@ -89,16 +95,26 @@
 # CONFIG_PA7300LC is not set
 # CONFIG_PA8X00 is not set
 CONFIG_PA11=y
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
 # CONFIG_SMP is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_PREEMPT is not set
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
 # CONFIG_HPUX is not set
 
 #
@@ -113,7 +129,7 @@
 CONFIG_EISA_NAMES=y
 CONFIG_ISA=y
 CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_DEBUG is not set
 CONFIG_GSC_DINO=y
 # CONFIG_PCI_LBA is not set
@@ -124,14 +140,11 @@
 # CONFIG_PCCARD is not set
 
 #
-# PCI Hotplug Support
-#
-
-#
 # PA-RISC specific drivers
 #
 CONFIG_CHASSIS_LCD_LED=y
 # CONFIG_PDC_CHASSIS is not set
+CONFIG_PDC_CHASSIS_WARN=y
 CONFIG_PDC_STABLE=y
 
 #
@@ -151,6 +164,8 @@
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -167,18 +182,32 @@
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_IPV6=y
 # CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 # CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+CONFIG_IPV6_SIT=y
 # CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -199,7 +228,14 @@
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
 
 #
 # Device Drivers
@@ -208,39 +244,24 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 # CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
 CONFIG_PARPORT=y
 CONFIG_PARPORT_PC=y
 # CONFIG_PARPORT_SERIAL is not set
-CONFIG_PARPORT_NOT_PC=y
 CONFIG_PARPORT_GSC=y
+# CONFIG_PARPORT_AX88796 is not set
 # CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
+CONFIG_PARPORT_NOT_PC=y
 # CONFIG_PNP is not set
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
@@ -251,15 +272,13 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
 # CONFIG_IDE is not set
 
 #
@@ -267,6 +286,8 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -286,18 +307,17 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
@@ -308,12 +328,14 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -327,23 +349,22 @@
 # CONFIG_SCSI_NCR53C406A is not set
 CONFIG_SCSI_LASI700=y
 CONFIG_53C700_LE_ON_BE=y
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 CONFIG_SCSI_SYM53C8XX_MMIO=y
-# CONFIG_SCSI_IPR is not set
 CONFIG_SCSI_ZALON=y
 CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
 CONFIG_SCSI_NCR53C8XX_SYNC=40
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_SIM710 is not set
 # CONFIG_SCSI_SYM53C416 is not set
@@ -351,22 +372,14 @@
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
-CONFIG_MD_RAID5=y
-CONFIG_MD_RAID6=y
+# CONFIG_MD_RAID456 is not set
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
@@ -382,35 +395,21 @@
 #
 # IEEE 1394 (FireWire) support
 #
+
+#
+# An alternative FireWire stack is available with EXPERIMENTAL=y
+#
 # CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
 # CONFIG_I2O is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 CONFIG_LASI_82596=y
@@ -420,10 +419,6 @@
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
-
-#
-# Tulip family network device support
-#
 CONFIG_NET_TULIP=y
 CONFIG_TULIP=y
 # CONFIG_TULIP_MMIO is not set
@@ -435,62 +430,47 @@
 # CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
 # CONFIG_NET_ISA is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 # CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
 # CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_R8169 is not set
 # CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_QLA3XXX is not set
+CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
 # CONFIG_TR is not set
 
 #
-# Wireless LAN (non-hamradio)
+# Wireless LAN
 #
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_ARLAN is not set
-# CONFIG_WAVELAN is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-# CONFIG_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-# CONFIG_HOSTAP is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Wan interfaces
-#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_PLIP is not set
@@ -501,24 +481,19 @@
 # CONFIG_PPP_DEFLATE is not set
 # CONFIG_PPP_BSDCOMP is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=y
 # CONFIG_NET_FC 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
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -543,19 +518,31 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_KEYBOARD_HIL_OLD is not set
 CONFIG_KEYBOARD_HIL=y
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
 # CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
 # CONFIG_MOUSE_INPORT is not set
 # CONFIG_MOUSE_LOGIBM is not set
 # CONFIG_MOUSE_PC110PAD is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 CONFIG_MOUSE_HIL=y
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_POWERMATE is not set
 # CONFIG_INPUT_UINPUT is not set
 # CONFIG_HP_SDC_RTC is not set
 
@@ -579,6 +566,7 @@
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -586,17 +574,20 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_GSC=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_NR_UARTS=13
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
 # CONFIG_SERIAL_8250_FOURPORT is not set
 # CONFIG_SERIAL_8250_ACCENT is not set
 # CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
 # CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
 
 #
 # Non-8250 serial port support
@@ -605,6 +596,7 @@
 CONFIG_SERIAL_MUX_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -612,35 +604,18 @@
 # CONFIG_LP_CONSOLE is not set
 # CONFIG_PPDEV is not set
 # CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 
 #
@@ -648,46 +623,59 @@
 #
 # 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_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# Multimedia Capabilities Port drivers
+# 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
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
 CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -698,16 +686,18 @@
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -717,21 +707,17 @@
 CONFIG_DUMMY_CONSOLE_COLUMNS=160
 CONFIG_DUMMY_CONSOLE_ROWS=64
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
 # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_STI_CONSOLE=y
 # CONFIG_FONTS is not set
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
 CONFIG_LOGO=y
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_LOGO_PARISC_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -749,8 +735,11 @@
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
@@ -760,13 +749,16 @@
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_VIRMIDI is not set
 # CONFIG_SND_MTPAV is not set
+# CONFIG_SND_MTS64 is not set
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
+# CONFIG_SND_PORTMAN2X4 is not set
 
 #
 # PCI devices
 #
 # CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
 # CONFIG_SND_ATIIXP_MODEM is not set
@@ -778,6 +770,18 @@
 # CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
 # CONFIG_SND_EMU10K1 is not set
 # CONFIG_SND_EMU10K1X is not set
 # CONFIG_SND_ENS1370 is not set
@@ -791,11 +795,13 @@
 # CONFIG_SND_ICE1712 is not set
 # CONFIG_SND_ICE1724 is not set
 # CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
 # CONFIG_SND_KORG1212 is not set
 # CONFIG_SND_MAESTRO3 is not set
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
 # CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
 # CONFIG_SND_RME32 is not set
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
@@ -812,15 +818,25 @@
 CONFIG_SND_HARMONY=y
 
 #
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
+
+#
 # Open Sound System
 #
 # CONFIG_SOUND_PRIME is not set
-
-#
-# USB support
-#
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB is not set
 
 #
@@ -831,20 +847,29 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
 # CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
+# CONFIG_NEW_LEDS is not set
 # CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
 
 #
-# SN Devices
+# DMA Engine support
 #
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+# CONFIG_AUXDISPLAY is not set
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
 
 #
 # File systems
@@ -860,9 +885,11 @@
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_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
@@ -889,11 +916,12 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -912,6 +940,7 @@
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
@@ -982,22 +1011,32 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_IOREMAP is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=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=y
+# CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_RODATA is not set
 
 #
@@ -1007,13 +1046,10 @@
 CONFIG_SECURITY=y
 # CONFIG_SECURITY_NETWORK is not set
 CONFIG_SECURITY_CAPABILITIES=y
-# CONFIG_SECURITY_SECLVL is not set
-# CONFIG_SECURITY_SELINUX is not set
-
-#
-# Cryptographic options
-#
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -1023,7 +1059,12 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1034,19 +1075,26 @@
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
index eb2f9a3..c6def3c 100644
--- a/arch/parisc/configs/c3000_defconfig
+++ b/arch/parisc/configs/c3000_defconfig
@@ -1,39 +1,50 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-pa6
-# Sun Mar 26 20:03:29 2006
+# Linux kernel version: 2.6.23
+# Fri Oct 12 21:24:00 2007
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
 CONFIG_STACK_GROWSUP=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_IRQ_PER_CPU=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # General setup
 #
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -43,31 +54,29 @@
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 # 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
+# CONFIG_BLK_DEV_BSG is not set
 
 #
 # IO Schedulers
@@ -93,6 +102,9 @@
 CONFIG_PA20=y
 CONFIG_PREFETCH=y
 # CONFIG_64BIT is not set
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
 # CONFIG_SMP is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 # CONFIG_PREEMPT_NONE is not set
@@ -100,6 +112,7 @@
 # CONFIG_PREEMPT is not set
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -110,6 +123,9 @@
 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=0
+CONFIG_VIRT_TO_BUS=y
 # CONFIG_HPUX is not set
 
 #
@@ -117,7 +133,7 @@
 #
 # CONFIG_GSC is not set
 CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_DEBUG is not set
 CONFIG_PCI_LBA=y
 CONFIG_IOSAPIC=y
@@ -127,10 +143,6 @@
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
 # CONFIG_HOTPLUG_PCI is not set
 
 #
@@ -139,6 +151,7 @@
 CONFIG_SUPERIO=y
 CONFIG_CHASSIS_LCD_LED=y
 # CONFIG_PDC_CHASSIS is not set
+CONFIG_PDC_CHASSIS_WARN=y
 CONFIG_PDC_STABLE=y
 
 #
@@ -155,13 +168,15 @@
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -178,22 +193,36 @@
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-
-#
-# IP: Virtual Server Configuration
-#
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IP_VS is not set
 CONFIG_IPV6=m
 # CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
 CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 CONFIG_NETFILTER_DEBUG=y
 
@@ -201,42 +230,24 @@
 # Core Netfilter Configuration
 #
 # CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
 # CONFIG_NETFILTER_XTABLES is not set
 
 #
 # IP: Netfilter Configuration
 #
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
-# CONFIG_IP_NF_CT_PROTO_SCTP is not set
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-# CONFIG_IP_NF_PPTP is not set
 CONFIG_IP_NF_QUEUE=m
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
 
 #
 # IPv6: Netfilter Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP6_NF_QUEUE is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_IP6_NF_IPTABLES is not set
 # 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
@@ -247,7 +258,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -263,7 +273,17 @@
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -272,33 +292,17 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 # CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -310,14 +314,15 @@
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -331,19 +336,26 @@
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 CONFIG_BLK_DEV_IDESCSI=y
 # CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
 # CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
+CONFIG_IDEDMA_ONLYDISK=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
@@ -354,8 +366,10 @@
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
 # CONFIG_BLK_DEV_IT821X is not set
 CONFIG_BLK_DEV_NS87415=y
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -365,10 +379,10 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
 # CONFIG_BLK_DEV_HD is not set
 
 #
@@ -376,6 +390,9 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -395,18 +412,17 @@
 CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
 CONFIG_SCSI_ISCSI_ATTRS=m
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
@@ -415,66 +431,53 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
-CONFIG_SCSI_ATA_PIIX=m
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
-# CONFIG_SCSI_PDC_ADMA is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-CONFIG_SCSI_SATA_PROMISE=m
-# CONFIG_SCSI_SATA_SX4 is not set
-CONFIG_SCSI_SATA_SIL=m
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-CONFIG_SCSI_SATA_VIA=m
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 CONFIG_SCSI_SYM53C8XX_MMIO=y
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 CONFIG_SCSI_DEBUG=m
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 # CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_MULTIPATH_EMC is not set
+# CONFIG_DM_MULTIPATH_RDAC is not set
+# CONFIG_DM_DELAY is not set
 
 #
 # Fusion MPT device support
@@ -485,49 +488,31 @@
 # CONFIG_FUSION_SAS is not set
 CONFIG_FUSION_MAX_SGE=128
 CONFIG_FUSION_CTL=m
+# CONFIG_FUSION_LOGGING is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
+# CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
 # CONFIG_I2O is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=m
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
 CONFIG_NET_TULIP=y
 CONFIG_DE2104X=m
 CONFIG_TULIP=y
@@ -539,13 +524,16 @@
 # CONFIG_DM9102 is not set
 # CONFIG_ULI526X is not set
 # CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=m
 # CONFIG_FEALNX is not set
@@ -558,16 +546,15 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+# CONFIG_SC92031 is not set
+CONFIG_NETDEV_1000=y
 CONFIG_ACENIC=m
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
 # CONFIG_DL2K is not set
 CONFIG_E1000=m
 # CONFIG_E1000_NAPI is not set
 # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -579,27 +566,36 @@
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
 # CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
 # CONFIG_TR is not set
 
 #
-# Wireless LAN (non-hamradio)
+# Wireless LAN
 #
-# CONFIG_NET_RADIO is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 
 #
-# Wan interfaces
+# USB Network Adapters
 #
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -612,27 +608,23 @@
 CONFIG_PPP_BSDCOMP=m
 # CONFIG_PPP_MPPE is not set
 CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# 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
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -655,11 +647,14 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -679,6 +674,7 @@
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -686,6 +682,7 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_NR_UARTS=13
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
@@ -704,38 +701,19 @@
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM 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
-
-#
-# Ftape, the floppy tape device driver
-#
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 
 #
@@ -743,46 +721,59 @@
 #
 # 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_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# Multimedia Capabilities Port drivers
+# 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
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
 CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -793,17 +784,20 @@
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -813,21 +807,17 @@
 CONFIG_DUMMY_CONSOLE_COLUMNS=160
 CONFIG_DUMMY_CONSOLE_ROWS=64
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
 # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_STI_CONSOLE=y
 # CONFIG_FONTS is not set
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
 CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_PARISC_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -845,9 +835,11 @@
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
@@ -855,7 +847,6 @@
 # Generic devices
 #
 CONFIG_SND_AC97_CODEC=y
-CONFIG_SND_AC97_BUS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_VIRMIDI is not set
 # CONFIG_SND_MTPAV is not set
@@ -866,7 +857,7 @@
 # PCI devices
 #
 CONFIG_SND_AD1889=y
-# CONFIG_SND_AD1889_OPL3 is not set
+# CONFIG_SND_ALS300 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
 # CONFIG_SND_ATIIXP_MODEM is not set
@@ -879,6 +870,18 @@
 # CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
 # CONFIG_SND_EMU10K1 is not set
 # CONFIG_SND_EMU10K1X is not set
 # CONFIG_SND_ENS1370 is not set
@@ -898,6 +901,7 @@
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
 # CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
 # CONFIG_SND_RME32 is not set
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
@@ -907,22 +911,43 @@
 # CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
 # CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
 
 #
 # USB devices
 #
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
 
 #
 # Open Sound System
 #
 # CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
 
 #
-# USB support
+# USB Input Devices
 #
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 CONFIG_USB_DEBUG=y
 
@@ -930,7 +955,7 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
+CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
 
@@ -940,15 +965,16 @@
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
 
 #
 # USB Device Class drivers
 #
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=m
 
@@ -970,54 +996,14 @@
 CONFIG_USB_STORAGE_SDDR55=y
 CONFIG_USB_STORAGE_JUMPSHOT=y
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-CONFIG_USB_HIDDEV=y
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-
-#
 # USB Imaging devices
 #
 CONFIG_USB_MDC800=m
 CONFIG_USB_MICROTEK=m
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
 # CONFIG_USB_MON is not set
 
 #
@@ -1034,16 +1020,22 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 CONFIG_USB_LEGOTOWER=m
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1054,20 +1046,28 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
 # CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
+# CONFIG_NEW_LEDS is not set
 # CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# DMA Engine support
 #
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
 
 #
 # File systems
@@ -1077,21 +1077,23 @@
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 CONFIG_XFS_FS=m
-CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -1121,11 +1123,12 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1164,6 +1167,7 @@
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1171,7 +1175,6 @@
 # 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
@@ -1224,6 +1227,11 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 CONFIG_PROFILING=y
@@ -1233,21 +1241,32 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=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=y
+# 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 is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 CONFIG_DEBUG_RODATA=y
 
 #
@@ -1255,12 +1274,12 @@
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
 # CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
 CONFIG_CRYPTO_NULL=m
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=m
@@ -1269,7 +1288,15 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
 CONFIG_CRYPTO_BLOWFISH=m
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1280,21 +1307,28 @@
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 CONFIG_CRYPTO_DEFLATE=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_TEST=m
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig
index b38b58e..448a757 100644
--- a/arch/parisc/defconfig
+++ b/arch/parisc/defconfig
@@ -1,39 +1,51 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-pa10
-# Sun Apr  2 15:26:38 2006
+# Linux kernel version: 2.6.23
+# Fri Oct 12 20:54:57 2007
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
 CONFIG_STACK_GROWSUP=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_IRQ_PER_CPU=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # General setup
 #
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -43,31 +55,29 @@
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 # 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
+# CONFIG_BLK_DEV_BSG is not set
 
 #
 # IO Schedulers
@@ -101,6 +111,7 @@
 # CONFIG_PREEMPT is not set
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -111,6 +122,9 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
 # CONFIG_HPUX is not set
 
 #
@@ -125,7 +139,7 @@
 CONFIG_EISA_NAMES=y
 # CONFIG_ISA is not set
 CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_DEBUG is not set
 CONFIG_GSC_DINO=y
 CONFIG_PCI_LBA=y
@@ -154,10 +168,6 @@
 CONFIG_PD6729=y
 CONFIG_I82092=y
 CONFIG_PCCARD_NONSTATIC=y
-
-#
-# PCI Hotplug Support
-#
 # CONFIG_HOTPLUG_PCI is not set
 
 #
@@ -166,6 +176,7 @@
 CONFIG_SUPERIO=y
 CONFIG_CHASSIS_LCD_LED=y
 CONFIG_PDC_CHASSIS=y
+CONFIG_PDC_CHASSIS_WARN=y
 CONFIG_PDC_STABLE=y
 
 #
@@ -182,13 +193,15 @@
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -205,33 +218,39 @@
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=m
 CONFIG_INET_TCP_DIAG=m
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 CONFIG_IPV6=y
 # CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
 CONFIG_INET6_AH=y
 CONFIG_INET6_ESP=y
 CONFIG_INET6_IPCOMP=y
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=y
 CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
 # CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES 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
@@ -243,7 +262,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -259,7 +277,17 @@
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -268,41 +296,26 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 # CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
 CONFIG_PARPORT=y
 CONFIG_PARPORT_PC=m
 # CONFIG_PARPORT_SERIAL is not set
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
 CONFIG_PARPORT_PC_PCMCIA=m
-CONFIG_PARPORT_NOT_PC=y
 CONFIG_PARPORT_GSC=y
+# CONFIG_PARPORT_AX88796 is not set
 CONFIG_PARPORT_1284=y
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_PARPORT_NOT_PC=y
+CONFIG_BLK_DEV=y
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
@@ -317,13 +330,14 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDE=y
 
@@ -334,24 +348,32 @@
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
 CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_DELKIN is not set
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 CONFIG_BLK_DEV_IDESCSI=y
 # CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
 
 #
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
 CONFIG_BLK_DEV_GENERIC=y
 # CONFIG_BLK_DEV_OPTI621 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
+CONFIG_IDEDMA_ONLYDISK=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
@@ -362,8 +384,10 @@
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
 # CONFIG_BLK_DEV_IT821X is not set
 CONFIG_BLK_DEV_NS87415=y
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -373,10 +397,10 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
 # CONFIG_BLK_DEV_HD is not set
 
 #
@@ -384,6 +408,9 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -403,18 +430,17 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
@@ -424,11 +450,13 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
@@ -438,55 +466,45 @@
 # CONFIG_SCSI_IMM is not set
 CONFIG_SCSI_LASI700=y
 CONFIG_53C700_LE_ON_BE=y
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 CONFIG_SCSI_SYM53C8XX_MMIO=y
-# CONFIG_SCSI_IPR is not set
 CONFIG_SCSI_ZALON=y
 CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
 CONFIG_SCSI_NCR53C8XX_SYNC=20
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_SIM710 is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 CONFIG_MD_RAID10=y
-CONFIG_MD_RAID5=y
-CONFIG_MD_RAID6=y
+# CONFIG_MD_RAID456 is not set
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
 # CONFIG_DM_CRYPT is not set
 # CONFIG_DM_SNAPSHOT is not set
 # CONFIG_DM_MIRROR is not set
 # CONFIG_DM_ZERO is not set
 # CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
 
 #
 # Fusion MPT device support
@@ -499,35 +517,20 @@
 #
 # IEEE 1394 (FireWire) support
 #
+# CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
 # CONFIG_I2O is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=m
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
 CONFIG_LASI_82596=y
@@ -536,10 +539,6 @@
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_SMC is not set
-
-#
-# Tulip family network device support
-#
 CONFIG_NET_TULIP=y
 # CONFIG_DE2104X is not set
 CONFIG_TULIP=y
@@ -554,6 +553,10 @@
 # CONFIG_PCMCIA_XIRTULIP is not set
 # CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
@@ -561,7 +564,6 @@
 # CONFIG_AC3200 is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
 # CONFIG_LNE390 is not set
@@ -577,15 +579,14 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
 # CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+CONFIG_NETDEV_1000=y
 CONFIG_ACENIC=y
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -597,64 +598,36 @@
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
 # CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
 # CONFIG_TR is not set
 
 #
-# Wireless LAN (non-hamradio)
+# Wireless LAN
 #
-CONFIG_NET_RADIO=y
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 
 #
-# Obsolete Wireless cards support (pre-802.11)
+# USB Network Adapters
 #
-# CONFIG_STRIP is not set
-# CONFIG_PCMCIA_WAVELAN is not set
-# CONFIG_PCMCIA_NETWAVE is not set
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-# CONFIG_PCMCIA_RAYCS is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=y
-# CONFIG_PLX_HERMES is not set
-# CONFIG_TMD_HERMES is not set
-# CONFIG_NORTEL_HERMES is not set
-# CONFIG_PCI_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=y
-CONFIG_PCMCIA_SPECTRUM=y
-# CONFIG_AIRO_CS is not set
-# CONFIG_PCMCIA_WL3501 is not set
-
-#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-# CONFIG_PRISM54 is not set
-# CONFIG_HOSTAP is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
-#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
 CONFIG_NET_PCMCIA=y
 # CONFIG_PCMCIA_3C589 is not set
 # CONFIG_PCMCIA_3C574 is not set
@@ -664,10 +637,6 @@
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
 # CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -681,27 +650,23 @@
 CONFIG_PPP_BSDCOMP=m
 # CONFIG_PPP_MPPE is not set
 CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# 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
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -726,14 +691,23 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 # CONFIG_KEYBOARD_HIL_OLD is not set
 CONFIG_KEYBOARD_HIL=y
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
 CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_APPLETOUCH is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 CONFIG_MOUSE_HIL=y
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -757,6 +731,7 @@
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -764,6 +739,8 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_GSC=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_CS=y
 CONFIG_SERIAL_8250_NR_UARTS=17
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
@@ -788,25 +765,14 @@
 # CONFIG_LP_CONSOLE is not set
 CONFIG_PPDEV=m
 # CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM 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
-
-#
-# Ftape, the floppy tape device driver
-#
+# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 
 #
@@ -816,16 +782,8 @@
 # CONFIG_CARDMAN_4000 is not set
 # CONFIG_CARDMAN_4040 is not set
 # CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 
 #
@@ -833,46 +791,59 @@
 #
 # 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_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
+# Sonics Silicon Backplane
 #
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
-# Multimedia Capabilities Port drivers
+# 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
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
 
 #
 # Graphics support
 #
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
 CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -883,17 +854,20 @@
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -903,6 +877,7 @@
 CONFIG_DUMMY_CONSOLE_COLUMNS=128
 CONFIG_DUMMY_CONSOLE_ROWS=48
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
 # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_STI_CONSOLE=y
 CONFIG_FONTS=y
@@ -916,16 +891,11 @@
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
 # CONFIG_FONT_10x18 is not set
-
-#
-# Logo configuration
-#
 CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_PARISC_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -938,35 +908,36 @@
 CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
-CONFIG_SND_HWDEP=y
 CONFIG_SND_SEQUENCER=y
 # CONFIG_SND_SEQ_DUMMY is not set
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
 CONFIG_SND_DYNAMIC_MINORS=y
 CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
 #
 # Generic devices
 #
-CONFIG_SND_OPL3_LIB=y
 CONFIG_SND_AC97_CODEC=y
-CONFIG_SND_AC97_BUS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_VIRMIDI is not set
 # CONFIG_SND_MTPAV is not set
+# CONFIG_SND_MTS64 is not set
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
+# CONFIG_SND_PORTMAN2X4 is not set
 
 #
 # PCI devices
 #
 CONFIG_SND_AD1889=y
-CONFIG_SND_AD1889_OPL3=y
+# CONFIG_SND_ALS300 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
 # CONFIG_SND_ATIIXP_MODEM is not set
@@ -979,6 +950,18 @@
 # CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
 # CONFIG_SND_EMU10K1 is not set
 # CONFIG_SND_EMU10K1X is not set
 # CONFIG_SND_ENS1370 is not set
@@ -998,6 +981,7 @@
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
 # CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
 # CONFIG_SND_RME32 is not set
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
@@ -1007,15 +991,19 @@
 # CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
 # CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
 
 #
 # USB devices
 #
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
 
 #
 # PCMCIA devices
 #
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
 
 #
 # GSC devices
@@ -1023,15 +1011,34 @@
 CONFIG_SND_HARMONY=y
 
 #
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
+
+#
 # Open Sound System
 #
 # CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
 
 #
-# USB support
+# USB Input Devices
 #
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -1039,7 +1046,7 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
+CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
 
@@ -1049,15 +1056,16 @@
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
 
 #
 # USB Device Class drivers
 #
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 
@@ -1072,52 +1080,10 @@
 # CONFIG_USB_LIBUSUAL is not set
 
 #
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-
-#
 # USB Imaging devices
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_ZD1201 is not set
 CONFIG_USB_MON=y
 
 #
@@ -1135,16 +1101,22 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1155,20 +1127,29 @@
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
 # CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
+# CONFIG_NEW_LEDS is not set
 # CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
 
 #
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# DMA Engine support
 #
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+# CONFIG_AUXDISPLAY is not set
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
 
 #
 # File systems
@@ -1178,16 +1159,19 @@
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
@@ -1217,11 +1201,12 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1229,6 +1214,7 @@
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -1261,6 +1247,7 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_RPCSEC_GSS_SPKM3=m
 CONFIG_SMB_FS=m
@@ -1268,12 +1255,13 @@
 CONFIG_SMB_NLS_REMOTE="cp437"
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
 # CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_CIFS_EXPERIMENTAL 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
@@ -1326,6 +1314,11 @@
 CONFIG_NLS_UTF8=y
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Profiling support
 #
 CONFIG_PROFILING=y
@@ -1335,21 +1328,32 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=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=y
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_RODATA is not set
 
 #
@@ -1358,12 +1362,13 @@
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
@@ -1372,9 +1377,18 @@
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
@@ -1383,21 +1397,28 @@
 CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_KHAZAD=m
 CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_SEED is not set
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
 CONFIG_CRYPTO_TEST=m
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
 #
+CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/parisc/hpux/gate.S b/arch/parisc/hpux/gate.S
index 0b9d5b1..38a1c1b 100644
--- a/arch/parisc/hpux/gate.S
+++ b/arch/parisc/hpux/gate.S
@@ -20,7 +20,7 @@
 	.import hpux_call_table
 	.import hpux_syscall_exit,code
 
-	.align 4096
+	.align	PAGE_SIZE
 ENTRY(hpux_gateway_page)
 	nop
 #ifdef CONFIG_64BIT
@@ -103,5 +103,5 @@
 	ldo	-ENOSYS(%r0),%r28
 ENDPROC(hpux_gateway_page)
 
-	.align 4096
+	.align	PAGE_SIZE
 ENTRY(end_hpux_gateway_page)
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
index d3b7917..eaa79bc 100644
--- a/arch/parisc/kernel/asm-offsets.c
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -290,9 +290,6 @@
 	DEFINE(ASM_PTE_ENTRY_SIZE, PTE_ENTRY_SIZE);
 	DEFINE(ASM_PFN_PTE_SHIFT, PFN_PTE_SHIFT);
 	DEFINE(ASM_PT_INITIAL, PT_INITIAL);
-	DEFINE(ASM_PAGE_SIZE, PAGE_SIZE);
-	DEFINE(ASM_PAGE_SIZE_DIV64, PAGE_SIZE/64);
-	DEFINE(ASM_PAGE_SIZE_DIV128, PAGE_SIZE/128);
 	BLANK();
 	DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
 	DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 42598ab..111d472 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -98,7 +98,6 @@
 	 * The "get_stack" macros are responsible for determining the
 	 * kernel stack value.
 	 *
-	 * For Faults:
 	 *      If sr7 == 0
 	 *          Already using a kernel stack, so call the
 	 *          get_stack_use_r30 macro to push a pt_regs structure
@@ -110,26 +109,6 @@
 	 *          task pointer pointed to by cr30. Set the stack
 	 *          pointer to point to the end of the task structure.
 	 *
-	 * For Interrupts:
-	 *      If sr7 == 0
-	 *          Already using a kernel stack, check to see if r30
-	 *          is already pointing to the per processor interrupt
-	 *          stack. If it is, call the get_stack_use_r30 macro
-	 *          to push a pt_regs structure on the stack, and store
-	 *          registers there. Otherwise, call get_stack_use_cr31
-	 *          to get a pointer to the base of the interrupt stack
-	 *          and push a pt_regs structure on that stack.
-	 *      else
-	 *          Need to set up a kernel stack, so call the
-	 *          get_stack_use_cr30 macro to set up a pointer
-	 *          to the pt_regs structure contained within the
-	 *          task pointer pointed to by cr30. Set the stack
-	 *          pointer to point to the end of the task structure.
-	 *          N.B: We don't use the interrupt stack for the
-	 *          first interrupt from userland, because signals/
-	 *          resched's are processed when returning to userland,
-	 *          and we can sleep in those cases.
-	 *
 	 * Note that we use shadowed registers for temps until
 	 * we can save %r26 and %r29. %r26 is used to preserve
 	 * %r8 (a shadowed register) which temporarily contained
@@ -652,7 +631,7 @@
 
 	.text
 
-	.align 4096
+	.align	PAGE_SIZE
 
 ENTRY(fault_vector_20)
 	/* First vector is invalid (0) */
@@ -904,7 +883,7 @@
 	 *
 	 */
 
-	.align 4096
+	.align	PAGE_SIZE
 
 ENTRY(syscall_exit_rfi)
 	mfctl   %cr30,%r16
@@ -1086,23 +1065,13 @@
 
 intr_extint:
 	CMPIB=,n 0,%r16,1f
+
 	get_stack_use_cr30
-	b,n 3f
+	b,n 2f
 
 1:
-#if 0  /* Interrupt Stack support not working yet! */
-	mfctl	%cr31,%r1
-	copy	%r30,%r17
-	/* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
-	DEPI	0,31,15,%r17
-	CMPB=,n	%r1,%r17,2f
-	get_stack_use_cr31
-	b,n 3f
-#endif
-2:
 	get_stack_use_r30
-
-3:
+2:
 	save_specials	%r29
 	virt_map
 	save_general	%r29
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
index 9676c48..a7b8859 100644
--- a/arch/parisc/kernel/head.S
+++ b/arch/parisc/kernel/head.S
@@ -95,7 +95,7 @@
 
 1:
 	stw		%r3,0(%r4)
-	ldo		(ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
+	ldo		(PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
 	addib,>		-1,%r1,1b
 #if PT_NLEVELS == 3
 	ldo             ASM_PMD_ENTRY_SIZE(%r4),%r4
@@ -128,10 +128,6 @@
 	/* And the stack pointer too */
 	ldo             THREAD_SZ_ALGN(%r6),%sp
 
-	/* And the interrupt stack */
-	load32		interrupt_stack,%r6
-	mtctl           %r6,%cr31
-
 #ifdef CONFIG_SMP
 	/* Set the smp rendevous address into page zero.
 	** It would be safer to do this in init_smp_config() but
diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S
index 43b41df..2cbf13b 100644
--- a/arch/parisc/kernel/hpmc.S
+++ b/arch/parisc/kernel/hpmc.S
@@ -55,13 +55,13 @@
 	 * IODC requires 7K byte stack.  That leaves 1K byte for os_hpmc.
 	 */
 
-	.align 4096
+	.align	PAGE_SIZE
 hpmc_stack:
 	.block 16384
 
 #define HPMC_IODC_BUF_SIZE 0x8000
 
-	.align 4096
+	.align	PAGE_SIZE
 hpmc_iodc_buf:
 	.block HPMC_IODC_BUF_SIZE
 
diff --git a/arch/parisc/kernel/init_task.c b/arch/parisc/kernel/init_task.c
index 446f98d..26198a0 100644
--- a/arch/parisc/kernel/init_task.c
+++ b/arch/parisc/kernel/init_task.c
@@ -49,7 +49,6 @@
  * way process stacks are handled. This is done by having a special
  * "init_task" linker map entry..
  */
-unsigned char interrupt_stack[ISTACK_SIZE] __attribute__ ((section("init_istack"), aligned(4096)));
 union thread_union init_thread_union
 	__attribute__((aligned(128))) __attribute__((__section__(".data.init_task"))) =
 		{ INIT_THREAD_INFO(init_task) };
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 90b2408..5901092 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -289,7 +289,7 @@
 	 */
 
 	ldd		0(%r25), %r19
-	ldi		ASM_PAGE_SIZE_DIV128, %r1
+	ldi		(PAGE_SIZE / 128), %r1
 
 	ldw		64(%r25), %r0		/* prefetch 1 cacheline ahead */
 	ldw		128(%r25), %r0		/* prefetch 2 */
@@ -355,7 +355,7 @@
 	 * use ldd/std on a 32 bit kernel.
 	 */
 	ldw		0(%r25), %r19
-	ldi		ASM_PAGE_SIZE_DIV64, %r1
+	ldi		(PAGE_SIZE / 64), %r1
 
 1:
 	ldw		4(%r25), %r20
@@ -553,7 +553,7 @@
 	pdtlb		0(%r28)
 
 #ifdef CONFIG_64BIT
-	ldi		ASM_PAGE_SIZE_DIV128, %r1
+	ldi		(PAGE_SIZE / 128), %r1
 
 	/* PREFETCH (Write) has not (yet) been proven to help here */
 	/* #define	PREFETCHW_OP	ldd		256(%0), %r0 */
@@ -578,7 +578,7 @@
 	ldo		128(%r28), %r28
 
 #else	/* ! CONFIG_64BIT */
-	ldi		ASM_PAGE_SIZE_DIV64, %r1
+	ldi		(PAGE_SIZE / 64), %r1
 
 1:
 	stw		%r0, 0(%r28)
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
index 7aca704..671ee5b 100644
--- a/arch/parisc/kernel/parisc_ksyms.c
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -122,31 +122,9 @@
 EXPORT_SYMBOL($$divI_14);
 EXPORT_SYMBOL($$divI_15);
 
-extern void __ashrdi3(void);
-extern void __ashldi3(void);
-extern void __lshrdi3(void);
-extern void __muldi3(void);
-
-EXPORT_SYMBOL(__ashrdi3);
-EXPORT_SYMBOL(__ashldi3);
-EXPORT_SYMBOL(__lshrdi3);
-EXPORT_SYMBOL(__muldi3);
-
 asmlinkage void * __canonicalize_funcptr_for_compare(void *);
 EXPORT_SYMBOL(__canonicalize_funcptr_for_compare);
 
-#ifdef CONFIG_64BIT
-extern void __divdi3(void);
-extern void __udivdi3(void);
-extern void __umoddi3(void);
-extern void __moddi3(void);
-
-EXPORT_SYMBOL(__divdi3);
-EXPORT_SYMBOL(__udivdi3);
-EXPORT_SYMBOL(__umoddi3);
-EXPORT_SYMBOL(__moddi3);
-#endif
-
 #ifndef CONFIG_64BIT
 extern void $$dyncall(void);
 EXPORT_SYMBOL($$dyncall);
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index 23c1388..9448d4e 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/types.h>
+#include <linux/scatterlist.h>
 
 #include <asm/cacheflush.h>
 #include <asm/dma.h>    /* for DMA_CHUNK_SIZE */
@@ -569,11 +570,10 @@
 static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
 					  dma_addr_t *dma_handle, gfp_t flag)
 {
-	void *addr = NULL;
+	void *addr;
 
-	/* rely on kmalloc to be cacheline aligned */
-	addr = kmalloc(size, flag);
-	if(addr)
+	addr = (void *)__get_free_pages(flag, get_order(size));
+	if (addr)
 		*dma_handle = (dma_addr_t)virt_to_phys(addr);
 
 	return addr;
@@ -582,7 +582,7 @@
 static void pa11_dma_free_noncoherent(struct device *dev, size_t size,
 					void *vaddr, dma_addr_t iova)
 {
-	kfree(vaddr);
+	free_pages((unsigned long)vaddr, get_order(size));
 	return;
 }
 
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index 563df00..507d0ac 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -194,37 +194,13 @@
 	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl);
 }
 
-
-/* KLUGE: Link the child and parent resources - generic PCI didn't */
-static void
-pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
-{
-	if (!r->parent) {
-		printk(KERN_EMERG "PCI: resource not parented! [%p-%p]\n",
-				(void*) r->start, (void*) r->end);
-		r->parent = hba_res;
-
-		/* reverse link is harder *sigh*  */
-		if (r->parent->child) {
-			if (r->parent->sibling) {
-				struct resource *next = r->parent->sibling;
-				while (next->sibling)
-					 next = next->sibling;
-				next->sibling = r;
-			} else {
-				r->parent->sibling = r;
-			}
-		} else
-			r->parent->child = r;
-	}
-}
-
 /* called by drivers/pci/setup-bus.c:pci_setup_bridge().  */
 void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
 		struct pci_bus_region *region, struct resource *res)
 {
-	struct pci_bus *bus = dev->bus;
-	struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data);
+#ifdef CONFIG_64BIT
+	struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data);
+#endif
 
 	if (res->flags & IORESOURCE_IO) {
 		/*
@@ -243,23 +219,15 @@
 	}
 
 	DBG_RES("pcibios_resource_to_bus(%02x %s [%lx,%lx])\n",
-		bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM",
+		dev->bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM",
 		region->start, region->end);
-
-	/* KLUGE ALERT
-	** if this resource isn't linked to a "parent", then it seems
-	** to be a child of the HBA - lets link it in.
-	*/
-	pcibios_link_hba_resources(&hba->io_space, bus->resource[0]);
-	pcibios_link_hba_resources(&hba->lmmio_space, bus->resource[1]);
 }
 
 void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
 			      struct pci_bus_region *region)
 {
 #ifdef CONFIG_64BIT
-	struct pci_bus *bus = dev->bus;
-	struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data);
+	struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data);
 #endif
 
 	if (res->flags & IORESOURCE_MEM) {
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 549f548..370086f 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -82,7 +82,12 @@
 	unsigned long cpuid;
 	struct cpuinfo_parisc *p;
 
-#ifndef CONFIG_SMP
+#ifdef CONFIG_SMP
+	if (num_online_cpus() >= NR_CPUS) {
+		printk(KERN_INFO "num_online_cpus() >= NR_CPUS\n");
+		return 1;
+	}
+#else
 	if (boot_cpu_data.cpu_count > 0) {
 		printk(KERN_INFO "CONFIG_SMP=n  ignoring additional CPUs\n");
 		return 1;
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index fb35ebc..2ce3806 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -181,7 +181,7 @@
 	si.si_signo = SIGSEGV;
 	si.si_errno = 0;
 	si.si_code = SI_KERNEL;
-	si.si_pid = current->pid;
+	si.si_pid = task_pid_vnr(current);
 	si.si_uid = current->uid;
 	si.si_addr = &frame->uc;
 	force_sig_info(SIGSEGV, &si, current);
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index d7bc7bb..85fc775 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -432,22 +432,10 @@
 void __init smp_callin(void)
 {
 	int slave_id = cpu_now_booting;
-#if 0
-	void *istack;
-#endif
 
 	smp_cpu_init(slave_id);
 	preempt_disable();
 
-#if 0	/* NOT WORKING YET - see entry.S */
-	istack = (void *)__get_free_pages(GFP_KERNEL,ISTACK_ORDER);
-	if (istack == NULL) {
-	    printk(KERN_CRIT "Failed to allocate interrupt stack for cpu %d\n",slave_id);
-	    BUG();
-	}
-	mtctl(istack,31);
-#endif
-
 	flush_cache_all_local(); /* start with known state */
 	flush_tlb_all_local(NULL);
 
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index 2989c66..50bbf33 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -473,3 +473,10 @@
 	return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
 				  buf, len);
 }
+
+asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo,
+				u32 lenhi, u32 lenlo)
+{
+        return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo,
+                             ((loff_t)lenhi << 32) | lenlo);
+}
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 56f6231..69b6eeb 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -10,6 +10,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/unistd.h>
 #include <asm/errno.h>
+#include <asm/page.h>
 #include <asm/psw.h>
 #include <asm/thread_info.h>
 #include <asm/assembly.h>
@@ -38,7 +39,7 @@
 	 * pointers.
 	 */
 
-	.align ASM_PAGE_SIZE
+	.align PAGE_SIZE
 ENTRY(linux_gateway_page)
 
         /* ADDRESS 0x00 to 0xb0 = 176 bytes / 4 bytes per insn = 44 insns */
@@ -597,7 +598,7 @@
 
 
 	/* Make sure nothing else is placed on this page */
-	.align ASM_PAGE_SIZE
+	.align PAGE_SIZE
 END(linux_gateway_page)
 ENTRY(end_linux_gateway_page)
 
@@ -608,7 +609,7 @@
 
 	.section .rodata,"a"
 
-	.align ASM_PAGE_SIZE
+	.align PAGE_SIZE
 	/* Light-weight-syscall table */
 	/* Start of lws table. */
 ENTRY(lws_table)
@@ -617,13 +618,13 @@
 END(lws_table)
 	/* End of lws table */
 
-	.align ASM_PAGE_SIZE
+	.align PAGE_SIZE
 ENTRY(sys_call_table)
 #include "syscall_table.S"
 END(sys_call_table)
 
 #ifdef CONFIG_64BIT
-	.align ASM_PAGE_SIZE
+	.align PAGE_SIZE
 ENTRY(sys_call_table64)
 #define SYSCALL_TABLE_64BIT
 #include "syscall_table.S"
@@ -636,7 +637,7 @@
 		will use this set of locks 
 	*/
 	.section .data
-	.align 4096
+	.align	PAGE_SIZE
 ENTRY(lws_lock_start)
 	/* lws locks */
 	.align 16
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 2540786..117438e 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -403,6 +403,7 @@
 	ENTRY_COMP(signalfd)
 	ENTRY_COMP(timerfd)
 	ENTRY_SAME(eventfd)
+	ENTRY_COMP(fallocate)		/* 305 */
 
 	/* Nothing yet */
 
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 8b3062a..24be86b 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -189,16 +189,14 @@
 #ifdef CONFIG_SMP
 int update_cr16_clocksource(void)
 {
-	int change = 0;
-
 	/* since the cr16 cycle counters are not synchronized across CPUs,
 	   we'll check if we should switch to a safe clocksource: */
 	if (clocksource_cr16.rating != 0 && num_online_cpus() > 1) {
 		clocksource_change_rating(&clocksource_cr16, 0);
-		change = 1;
+		return 1;
 	}
 
-	return change;
+	return 0;
 }
 #else
 int update_cr16_clocksource(void)
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index bbf029a..99fd569 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -219,7 +219,7 @@
 			return; /* STFU */
 
 		printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
-			current->comm, current->pid, str, err, regs->iaoq[0]);
+			current->comm, task_pid_nr(current), str, err, regs->iaoq[0]);
 #ifdef PRINT_USER_FAULTS
 		/* XXX for debugging only */
 		show_regs(regs);
@@ -252,7 +252,7 @@
 	
 	if (err)
 		printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
-			current->comm, current->pid, str, err);
+			current->comm, task_pid_nr(current), str, err);
 
 	/* Wot's wrong wif bein' racy? */
 	if (current->thread.flags & PARISC_KERNEL_DEATH) {
@@ -317,7 +317,7 @@
 	if (unlikely(iir != GDB_BREAK_INSN)) {
 		printk(KERN_DEBUG "break %d,%d: pid=%d command='%s'\n",
 			iir & 31, (iir>>13) & ((1<<13)-1),
-			current->pid, current->comm);
+			task_pid_nr(current), current->comm);
 		show_regs(regs);
 	}
 #endif
@@ -747,7 +747,7 @@
 		if (user_mode(regs)) {
 #ifdef PRINT_USER_FAULTS
 			printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n",
-			    current->pid, current->comm);
+			    task_pid_nr(current), current->comm);
 			show_regs(regs);
 #endif
 			/* SIGBUS, for lack of a better one. */
@@ -772,7 +772,7 @@
 		else
 			printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ",
 			       code);
-		printk("pid=%d command='%s'\n", current->pid, current->comm);
+		printk("pid=%d command='%s'\n", task_pid_nr(current), current->comm);
 		show_regs(regs);
 #endif
 		si.si_signo = SIGSEGV;
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index 347bb92..aebf3c1 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -469,7 +469,7 @@
 		    && ++unaligned_count < 5) {
 			char buf[256];
 			sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
-				current->comm, current->pid, regs->ior, regs->iaoq[0]);
+				current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]);
 			printk(KERN_WARNING "%s", buf);
 #ifdef DEBUG_UNALIGNED
 			show_regs(regs);
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index cf780cb..701b2d2 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -209,8 +209,8 @@
 
 static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int frame_size)
 {
-	void handle_interruption(int, struct pt_regs *);
-	static unsigned long *hi = (unsigned long)&handle_interruption;
+	extern void handle_interruption(int, struct pt_regs *);
+	static unsigned long *hi = (unsigned long *)&handle_interruption;
 
 	if (pc == get_func_addr(hi)) {
 		struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN);
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index ee7a16e..40d0ff9 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -46,168 +46,211 @@
 #endif
 SECTIONS
 {
+	. = KERNEL_BINARY_TEXT_START;
 
-  . = KERNEL_BINARY_TEXT_START;
-
-  _text = .;			/* Text and read-only data */
-  .text ALIGN(16) : {
-	TEXT_TEXT
-	SCHED_TEXT
-	LOCK_TEXT
-	*(.text.do_softirq)
-	*(.text.sys_exit)
-	*(.text.do_sigaltstack)
-	*(.text.do_fork)
-	*(.text.*)
-	*(.fixup)
-	*(.lock.text)		/* out-of-line lock text */
-	*(.gnu.warning)
+	_text = .;		/* Text and read-only data */
+	.text ALIGN(16) : {
+		TEXT_TEXT
+		SCHED_TEXT
+		LOCK_TEXT
+		*(.text.do_softirq)
+		*(.text.sys_exit)
+		*(.text.do_sigaltstack)
+		*(.text.do_fork)
+		*(.text.*)
+		*(.fixup)
+		*(.lock.text)		/* out-of-line lock text */
+		*(.gnu.warning)
 	} = 0
+	/* End of text section */
+	_etext = .;
 
-  _etext = .;			/* End of text section */
+	RODATA
+	BUG_TABLE
 
-  RODATA
-
-  BUG_TABLE
-
-  /* writeable */
-  . = ALIGN(ASM_PAGE_SIZE);	/* Make sure this is page aligned so
-  				   that we can properly leave these
-				   as writable */
-  data_start = .;
-
-  . = ALIGN(16);		/* Exception table */
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
-  __stop___ex_table = .;
-
-  NOTES
-
-  __start___unwind = .;         /* unwind info */
-  .PARISC.unwind : { *(.PARISC.unwind) }
-  __stop___unwind = .;
-
-  /* rarely changed data like cpu maps */
-  . = ALIGN(16);
-  .data.read_mostly : { *(.data.read_mostly) }
-
-  . = ALIGN(L1_CACHE_BYTES);
-  .data : {			/* Data */
-	DATA_DATA
-	CONSTRUCTORS
+	/* writeable */
+	/* Make sure this is page aligned so
+	 * that we can properly leave these
+	 * as writable
+	 */
+	. = ALIGN(PAGE_SIZE);
+	data_start = .;
+	. = ALIGN(16);
+	/* Exception table */
+	__ex_table : {
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
 	}
 
-  . = ALIGN(L1_CACHE_BYTES);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+	NOTES
 
-  /* PA-RISC locks requires 16-byte alignment */
-  . = ALIGN(16);
-  .data.lock_aligned : { *(.data.lock_aligned) }
-
-  . = ALIGN(ASM_PAGE_SIZE);
-  /* nosave data is really only used for software suspend...it's here
-   * just in case we ever implement it */
-  __nosave_begin = .;
-  .data_nosave : { *(.data.nosave) }
-  . = ALIGN(ASM_PAGE_SIZE);
-  __nosave_end = .;
-
-  _edata = .;			/* End of data section */
-
-  __bss_start = .;		/* BSS */
-  /* page table entries need to be PAGE_SIZE aligned */
-  . = ALIGN(ASM_PAGE_SIZE);
-  .data.vmpages : {
-	*(.data.vm0.pmd)
-	*(.data.vm0.pgd)
-	*(.data.vm0.pte)
+	/* unwind info */
+	.PARISC.unwind : {
+		__start___unwind = .;
+		*(.PARISC.unwind)
+		__stop___unwind = .;
 	}
-  .bss : { *(.bss) *(COMMON) }
-  __bss_stop = .;
+
+	/* rarely changed data like cpu maps */
+	. = ALIGN(16);
+	.data.read_mostly : {
+		*(.data.read_mostly)
+	}
+
+	. = ALIGN(L1_CACHE_BYTES);
+	/* Data */
+	.data : {
+		DATA_DATA
+		CONSTRUCTORS
+	}
+
+	. = ALIGN(L1_CACHE_BYTES);
+	.data.cacheline_aligned : {
+		*(.data.cacheline_aligned)
+	}
+
+	/* PA-RISC locks requires 16-byte alignment */
+	. = ALIGN(16);
+	.data.lock_aligned : {
+		*(.data.lock_aligned)
+	}
+
+	/* nosave data is really only used for software suspend...it's here
+	 * just in case we ever implement it
+	 */
+	. = ALIGN(PAGE_SIZE);
+	__nosave_begin = .;
+	.data_nosave : {
+		*(.data.nosave)
+	}
+	. = ALIGN(PAGE_SIZE);
+	__nosave_end = .;
+
+	/* End of data section */
+	_edata = .;
+
+	/* BSS */
+	__bss_start = .;
+	/* page table entries need to be PAGE_SIZE aligned */
+	. = ALIGN(PAGE_SIZE);
+	.data.vmpages : {
+		*(.data.vm0.pmd)
+		*(.data.vm0.pgd)
+		*(.data.vm0.pte)
+	}
+	.bss : {
+		*(.bss)
+		*(COMMON)
+	}
+	__bss_stop = .;
 
 
-  /* assembler code expects init_task to be 16k aligned */
-  . = ALIGN(16384); 		/* init_task */
-  .data.init_task : { *(.data.init_task) }
-
-  /* The interrupt stack is currently partially coded, but not yet
-   * implemented */
-  . = ALIGN(16384);	
-  init_istack : { *(init_istack) }
+	/* assembler code expects init_task to be 16k aligned */
+	. = ALIGN(16384);
+	/* init_task */
+	.data.init_task : {
+		*(.data.init_task)
+	}
 
 #ifdef CONFIG_64BIT
-  . = ALIGN(16);               /* Linkage tables */
-  .opd : { *(.opd) } PROVIDE (__gp = .); 
-  .plt : { *(.plt) } 
-  .dlt : { *(.dlt) }
+	. = ALIGN(16);
+	/* Linkage tables */
+	.opd : {
+		*(.opd)
+	} PROVIDE (__gp = .); 
+	.plt : {
+		*(.plt)
+	} 
+	.dlt : {
+		*(.dlt)
+	}
 #endif
 
-  /* reserve space for interrupt stack by aligning __init* to 16k */
-  . = ALIGN(16384);
-  __init_begin = .;
-  .init.text : { 
-	_sinittext = .;
-	*(.init.text)
-	_einittext = .;
-  }
-  .init.data : { *(.init.data) }
-  . = ALIGN(16);
-  __setup_start = .;
-  .init.setup : { *(.init.setup) }
-  __setup_end = .;
-  __initcall_start = .;
-  .initcall.init : {
-	INITCALLS
-  }
-  __initcall_end = .;
-  __con_initcall_start = .;
-  .con_initcall.init : { *(.con_initcall.init) }
-  __con_initcall_end = .;
-  SECURITY_INIT
-  /* alternate instruction replacement.  This is a mechanism x86 uses
-   * to detect the CPU type and replace generic instruction sequences
-   * with CPU specific ones.  We don't currently do this in PA, but
-   * it seems like a good idea... */
-  . = ALIGN(4);
-  __alt_instructions = .;
-  .altinstructions : { *(.altinstructions) } 
-  __alt_instructions_end = .; 
- .altinstr_replacement : { *(.altinstr_replacement) } 
-  /* .exit.text is discard at runtime, not link time, to deal with references
-     from .altinstructions and .eh_frame */
-  .exit.text : { *(.exit.text) }
-  .exit.data : { *(.exit.data) }
+	/* reserve space for interrupt stack by aligning __init* to 16k */
+	. = ALIGN(16384);
+	__init_begin = .;
+	.init.text : { 
+		_sinittext = .;
+		*(.init.text)
+		_einittext = .;
+	}
+	.init.data : {
+		*(.init.data)
+	}
+	. = ALIGN(16);
+	.init.setup : {
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+	}
+	.initcall.init : {
+		__initcall_start = .;
+		INITCALLS
+		__initcall_end = .;
+	}
+	.con_initcall.init : {
+		__con_initcall_start = .;
+		*(.con_initcall.init)
+		__con_initcall_end = .;
+	}
+	SECURITY_INIT
+
+	/* alternate instruction replacement.  This is a mechanism x86 uses
+	 * to detect the CPU type and replace generic instruction sequences
+	 * with CPU specific ones.  We don't currently do this in PA, but
+	 * it seems like a good idea...
+	 */
+	. = ALIGN(4);
+	.altinstructions : {
+		__alt_instructions = .;
+		*(.altinstructions)
+		__alt_instructions_end = .; 
+	} 
+	.altinstr_replacement : {
+		*(.altinstr_replacement)
+	} 
+
+	/* .exit.text is discard at runtime, not link time, to deal with references
+	 *  from .altinstructions and .eh_frame
+	 */
+	.exit.text : {
+		*(.exit.text)
+	}
+	.exit.data : {
+		*(.exit.data)
+	}
 #ifdef CONFIG_BLK_DEV_INITRD
-  . = ALIGN(ASM_PAGE_SIZE);
-  __initramfs_start = .;
-  .init.ramfs : { *(.init.ramfs) }
-  __initramfs_end = .;
+	. = ALIGN(PAGE_SIZE);
+	.init.ramfs : {
+		__initramfs_start = .;
+		*(.init.ramfs)
+		__initramfs_end = .;
+	}
 #endif
 
-  PERCPU(ASM_PAGE_SIZE)
+	PERCPU(PAGE_SIZE)
+	. = ALIGN(PAGE_SIZE);
+	__init_end = .;
+	/* freed after init ends here */
+	_end = . ;
 
-  . = ALIGN(ASM_PAGE_SIZE);
-  __init_end = .;
-  /* freed after init ends here */
-	
-  _end = . ;
-
-  /* Sections to be discarded */
-  /DISCARD/ : {
-	*(.exitcall.exit)
+	/* Sections to be discarded */
+	/DISCARD/ : {
+		*(.exitcall.exit)
 #ifdef CONFIG_64BIT
-	/* temporary hack until binutils is fixed to not emit these
-	 for static binaries */
-	*(.interp)
-	*(.dynsym)
-	*(.dynstr)
-	*(.dynamic)
-	*(.hash)
-	*(.gnu.hash)
+		/* temporary hack until binutils is fixed to not emit these
+	 	 * for static binaries
+		 */
+		*(.interp)
+		*(.dynsym)
+		*(.dynstr)
+		*(.dynamic)
+		*(.hash)
+		*(.gnu.hash)
 #endif
 	}
 
-  STABS_DEBUG
-  .note 0 : { *(.note) }	
-
+	STABS_DEBUG
+	.note 0 : { *(.note) }	
 }
diff --git a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile
index 5f2e690..7ce406c 100644
--- a/arch/parisc/lib/Makefile
+++ b/arch/parisc/lib/Makefile
@@ -4,4 +4,4 @@
 
 lib-y	:= lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o
 
-obj-y	:= iomap.o
+obj-y	:= libgcc/ milli/ iomap.o
diff --git a/arch/parisc/lib/libgcc/Makefile b/arch/parisc/lib/libgcc/Makefile
new file mode 100644
index 0000000..b67a85a
--- /dev/null
+++ b/arch/parisc/lib/libgcc/Makefile
@@ -0,0 +1,4 @@
+obj-y	:= __ashldi3.o __ashrdi3.o __clzsi2.o __divdi3.o __divsi3.o	\
+		__lshrdi3.o __moddi3.o __modsi3.o __udivdi3.o		\
+		__udivmoddi4.o __udivmodsi4.o __udivsi3.o 		\
+		__umoddi3.o __umodsi3.o __muldi3.o __umulsidi3.o
diff --git a/arch/parisc/lib/libgcc/__ashldi3.c b/arch/parisc/lib/libgcc/__ashldi3.c
new file mode 100644
index 0000000..a14a257
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__ashldi3.c
@@ -0,0 +1,19 @@
+#include "libgcc.h"
+
+u64 __ashldi3(u64 v, int cnt)
+{
+	int c = cnt & 31;
+	u32 vl = (u32) v;
+	u32 vh = (u32) (v >> 32);
+
+	if (cnt & 32) {
+		vh = (vl << c);
+		vl = 0;
+	} else {
+		vh = (vh << c) + (vl >> (32 - c));
+		vl = (vl << c);
+	}
+
+	return ((u64) vh << 32) + vl;
+}
+EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/parisc/lib/libgcc/__ashrdi3.c b/arch/parisc/lib/libgcc/__ashrdi3.c
new file mode 100644
index 0000000..8636a5a
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__ashrdi3.c
@@ -0,0 +1,19 @@
+#include "libgcc.h"
+
+u64 __ashrdi3(u64 v, int cnt)
+{
+	int c = cnt & 31;
+	u32 vl = (u32) v;
+	u32 vh = (u32) (v >> 32);
+
+	if (cnt & 32) {
+		vl = ((s32) vh >> c);
+		vh = (s32) vh >> 31;
+	} else {
+		vl = (vl >> c) + (vh << (32 - c));
+		vh = ((s32) vh >> c);
+	}
+
+	return ((u64) vh << 32) + vl;
+}
+EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/parisc/lib/libgcc/__clzsi2.c b/arch/parisc/lib/libgcc/__clzsi2.c
new file mode 100644
index 0000000..a7aa2f5
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__clzsi2.c
@@ -0,0 +1,30 @@
+#include "libgcc.h"
+
+u32 __clzsi2(u32 v)
+{
+	int p = 31;
+
+	if (v & 0xffff0000) {
+		p -= 16;
+		v >>= 16;
+	}
+	if (v & 0xff00) {
+		p -= 8;
+		v >>= 8;
+	}
+	if (v & 0xf0) {
+		p -= 4;
+		v >>= 4;
+	}
+	if (v & 0xc) {
+		p -= 2;
+		v >>= 2;
+	}
+	if (v & 0x2) {
+		p -= 1;
+		v >>= 1;
+	}
+
+	return p;
+}
+EXPORT_SYMBOL(__clzsi2);
diff --git a/arch/parisc/lib/libgcc/__divdi3.c b/arch/parisc/lib/libgcc/__divdi3.c
new file mode 100644
index 0000000..f23c6fe
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__divdi3.c
@@ -0,0 +1,23 @@
+#include "libgcc.h"
+
+s64 __divdi3(s64 num, s64 den)
+{
+	int minus = 0;
+	s64 v;
+
+	if (num < 0) {
+		num = -num;
+		minus = 1;
+	}
+	if (den < 0) {
+		den = -den;
+		minus ^= 1;
+	}
+
+	v = __udivmoddi4(num, den, NULL);
+	if (minus)
+		v = -v;
+
+	return v;
+}
+EXPORT_SYMBOL(__divdi3);
diff --git a/arch/parisc/lib/libgcc/__divsi3.c b/arch/parisc/lib/libgcc/__divsi3.c
new file mode 100644
index 0000000..730fb53
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__divsi3.c
@@ -0,0 +1,23 @@
+#include "libgcc.h"
+
+s32 __divsi3(s32 num, s32 den)
+{
+	int minus = 0;
+	s32 v;
+
+	if (num < 0) {
+		num = -num;
+		minus = 1;
+	}
+	if (den < 0) {
+		den = -den;
+		minus ^= 1;
+	}
+
+	v = __udivmodsi4(num, den, NULL);
+	if (minus)
+		v = -v;
+
+	return v;
+}
+EXPORT_SYMBOL(__divsi3);
diff --git a/arch/parisc/lib/libgcc/__lshrdi3.c b/arch/parisc/lib/libgcc/__lshrdi3.c
new file mode 100644
index 0000000..4a82070
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__lshrdi3.c
@@ -0,0 +1,19 @@
+#include "libgcc.h"
+
+u64 __lshrdi3(u64 v, int cnt)
+{
+	int c = cnt & 31;
+	u32 vl = (u32) v;
+	u32 vh = (u32) (v >> 32);
+
+	if (cnt & 32) {
+		vl = (vh >> c);
+		vh = 0;
+	} else {
+		vl = (vl >> c) + (vh << (32 - c));
+		vh = (vh >> c);
+	}
+
+	return ((u64) vh << 32) + vl;
+}
+EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/parisc/lib/libgcc/__moddi3.c b/arch/parisc/lib/libgcc/__moddi3.c
new file mode 100644
index 0000000..ed64bba
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__moddi3.c
@@ -0,0 +1,23 @@
+#include "libgcc.h"
+
+s64 __moddi3(s64 num, s64 den)
+{
+	int minus = 0;
+	s64 v;
+
+	if (num < 0) {
+		num = -num;
+		minus = 1;
+	}
+	if (den < 0) {
+		den = -den;
+		minus ^= 1;
+	}
+
+	(void)__udivmoddi4(num, den, (u64 *) & v);
+	if (minus)
+		v = -v;
+
+	return v;
+}
+EXPORT_SYMBOL(__moddi3);
diff --git a/arch/parisc/lib/libgcc/__modsi3.c b/arch/parisc/lib/libgcc/__modsi3.c
new file mode 100644
index 0000000..62f773e
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__modsi3.c
@@ -0,0 +1,23 @@
+#include "libgcc.h"
+
+s32 __modsi3(s32 num, s32 den)
+{
+	int minus = 0;
+	s32 v;
+
+	if (num < 0) {
+		num = -num;
+		minus = 1;
+	}
+	if (den < 0) {
+		den = -den;
+		minus ^= 1;
+	}
+
+	(void)__udivmodsi4(num, den, (u32 *) & v);
+	if (minus)
+		v = -v;
+
+	return v;
+}
+EXPORT_SYMBOL(__modsi3);
diff --git a/arch/parisc/lib/libgcc/__muldi3.c b/arch/parisc/lib/libgcc/__muldi3.c
new file mode 100644
index 0000000..3308abd
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__muldi3.c
@@ -0,0 +1,22 @@
+#include "libgcc.h"
+
+union DWunion {
+	struct {
+		s32 high;
+		s32 low;
+	} s;
+	s64 ll;
+};
+
+s64 __muldi3(s64 u, s64 v)
+{
+	const union DWunion uu = { .ll = u };
+	const union DWunion vv = { .ll = v };
+	union DWunion w = { .ll = __umulsidi3(uu.s.low, vv.s.low) };
+
+	w.s.high += ((u32)uu.s.low * (u32)vv.s.high
+		+ (u32)uu.s.high * (u32)vv.s.low);
+
+	return w.ll;
+}
+EXPORT_SYMBOL(__muldi3);
diff --git a/arch/parisc/lib/libgcc/__udivdi3.c b/arch/parisc/lib/libgcc/__udivdi3.c
new file mode 100644
index 0000000..740023d
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__udivdi3.c
@@ -0,0 +1,7 @@
+#include "libgcc.h"
+
+u64 __udivdi3(u64 num, u64 den)
+{
+	return __udivmoddi4(num, den, NULL);
+}
+EXPORT_SYMBOL(__udivdi3);
diff --git a/arch/parisc/lib/libgcc/__udivmoddi4.c b/arch/parisc/lib/libgcc/__udivmoddi4.c
new file mode 100644
index 0000000..2df0caa
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__udivmoddi4.c
@@ -0,0 +1,31 @@
+#include "libgcc.h"
+
+u64 __udivmoddi4(u64 num, u64 den, u64 * rem_p)
+{
+	u64 quot = 0, qbit = 1;
+
+	if (den == 0) {
+		BUG();
+	}
+
+	/* Left-justify denominator and count shift */
+	while ((s64) den >= 0) {
+		den <<= 1;
+		qbit <<= 1;
+	}
+
+	while (qbit) {
+		if (den <= num) {
+			num -= den;
+			quot += qbit;
+		}
+		den >>= 1;
+		qbit >>= 1;
+	}
+
+	if (rem_p)
+		*rem_p = num;
+
+	return quot;
+}
+EXPORT_SYMBOL(__udivmoddi4);
diff --git a/arch/parisc/lib/libgcc/__udivmodsi4.c b/arch/parisc/lib/libgcc/__udivmodsi4.c
new file mode 100644
index 0000000..2a2fc28
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__udivmodsi4.c
@@ -0,0 +1,31 @@
+#include "libgcc.h"
+
+u32 __udivmodsi4(u32 num, u32 den, u32 * rem_p)
+{
+	u32 quot = 0, qbit = 1;
+
+	if (den == 0) {
+		BUG();
+	}
+
+	/* Left-justify denominator and count shift */
+	while ((s32) den >= 0) {
+		den <<= 1;
+		qbit <<= 1;
+	}
+
+	while (qbit) {
+		if (den <= num) {
+			num -= den;
+			quot += qbit;
+		}
+		den >>= 1;
+		qbit >>= 1;
+	}
+
+	if (rem_p)
+		*rem_p = num;
+
+	return quot;
+}
+EXPORT_SYMBOL(__udivmodsi4);
diff --git a/arch/parisc/lib/libgcc/__udivsi3.c b/arch/parisc/lib/libgcc/__udivsi3.c
new file mode 100644
index 0000000..756a441
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__udivsi3.c
@@ -0,0 +1,7 @@
+#include "libgcc.h"
+
+u32 __udivsi3(u32 num, u32 den)
+{
+	return __udivmodsi4(num, den, NULL);
+}
+EXPORT_SYMBOL(__udivsi3);
diff --git a/arch/parisc/lib/libgcc/__umoddi3.c b/arch/parisc/lib/libgcc/__umoddi3.c
new file mode 100644
index 0000000..ac744e9
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__umoddi3.c
@@ -0,0 +1,10 @@
+#include "libgcc.h"
+
+u64 __umoddi3(u64 num, u64 den)
+{
+	u64 v;
+
+	(void)__udivmoddi4(num, den, &v);
+	return v;
+}
+EXPORT_SYMBOL(__umoddi3);
diff --git a/arch/parisc/lib/libgcc/__umodsi3.c b/arch/parisc/lib/libgcc/__umodsi3.c
new file mode 100644
index 0000000..51f55aa
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__umodsi3.c
@@ -0,0 +1,10 @@
+#include "libgcc.h"
+
+u32 __umodsi3(u32 num, u32 den)
+{
+	u32 v;
+
+	(void)__udivmodsi4(num, den, &v);
+	return v;
+}
+EXPORT_SYMBOL(__umodsi3);
diff --git a/arch/parisc/lib/libgcc/__umulsidi3.c b/arch/parisc/lib/libgcc/__umulsidi3.c
new file mode 100644
index 0000000..396f669
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__umulsidi3.c
@@ -0,0 +1,46 @@
+#include "libgcc.h"
+
+#define __ll_B ((u32) 1 << (32 / 2))
+#define __ll_lowpart(t) ((u32) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((u32) (t) >> 16)
+
+#define umul_ppmm(w1, w0, u, v)						\
+  do {									\
+    u32 __x0, __x1, __x2, __x3;						\
+    u16 __ul, __vl, __uh, __vh;						\
+									\
+    __ul = __ll_lowpart (u);						\
+    __uh = __ll_highpart (u);						\
+    __vl = __ll_lowpart (v);						\
+    __vh = __ll_highpart (v);						\
+									\
+    __x0 = (u32) __ul * __vl;						\
+    __x1 = (u32) __ul * __vh;						\
+    __x2 = (u32) __uh * __vl;						\
+    __x3 = (u32) __uh * __vh;						\
+									\
+    __x1 += __ll_highpart (__x0);/* this can't give carry */		\
+    __x1 += __x2;		 /* but this indeed can */		\
+    if (__x1 < __x2)		 /* did we get it? */			\
+      __x3 += __ll_B;		 /* yes, add it in the proper pos.  */	\
+									\
+    (w1) = __x3 + __ll_highpart (__x1);					\
+    (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);		\
+  } while (0)
+
+union DWunion {
+	struct {
+		s32 high;
+		s32 low;
+	} s;
+	s64 ll;
+};
+
+u64 __umulsidi3(u32 u, u32 v)
+{
+	union DWunion __w;
+
+	umul_ppmm(__w.s.high, __w.s.low, u, v);
+
+	return __w.ll;
+}
diff --git a/arch/parisc/lib/libgcc/libgcc.h b/arch/parisc/lib/libgcc/libgcc.h
new file mode 100644
index 0000000..5a6f7a5
--- /dev/null
+++ b/arch/parisc/lib/libgcc/libgcc.h
@@ -0,0 +1,32 @@
+#ifndef _PA_LIBGCC_H_
+#define _PA_LIBGCC_H_
+
+#include <linux/types.h>
+#include <linux/module.h>
+
+/* Cribbed from klibc/libgcc/ */
+u64 __ashldi3(u64 v, int cnt);
+u64 __ashrdi3(u64 v, int cnt);
+
+u32 __clzsi2(u32 v);
+
+s64 __divdi3(s64 num, s64 den);
+s32 __divsi3(s32 num, s32 den);
+
+u64 __lshrdi3(u64 v, int cnt);
+
+s64 __moddi3(s64 num, s64 den);
+s32 __modsi3(s32 num, s32 den);
+
+u64 __udivdi3(u64 num, u64 den);
+u32 __udivsi3(u32 num, u32 den);
+
+u64 __udivmoddi4(u64 num, u64 den, u64 * rem_p);
+u32 __udivmodsi4(u32 num, u32 den, u32 * rem_p);
+
+u64 __umulsidi3(u32 u, u32 v);
+
+u64 __umoddi3(u64 num, u64 den);
+u32 __umodsi3(u32 num, u32 den);
+
+#endif /*_PA_LIBGCC_H_*/
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
index 2c43ebe..d22042d 100644
--- a/arch/parisc/lib/memcpy.c
+++ b/arch/parisc/lib/memcpy.c
@@ -139,12 +139,12 @@
 #define stw(_s,_t,_o,_a,_e) 	def_store_insn(stw,"r",_s,_t,_o,_a,_e)
 
 #ifdef  CONFIG_PREFETCH
-extern inline void prefetch_src(const void *addr)
+static inline void prefetch_src(const void *addr)
 {
 	__asm__("ldw 0(" s_space ",%0), %%r0" : : "r" (addr));
 }
 
-extern inline void prefetch_dst(const void *addr)
+static inline void prefetch_dst(const void *addr)
 {
 	__asm__("ldd 0(" d_space ",%0), %%r0" : : "r" (addr));
 }
diff --git a/arch/parisc/lib/milli/Makefile b/arch/parisc/lib/milli/Makefile
new file mode 100644
index 0000000..9b24e9b
--- /dev/null
+++ b/arch/parisc/lib/milli/Makefile
@@ -0,0 +1 @@
+obj-y	:= dyncall.o divI.o divU.o remI.o remU.o div_const.o mulI.o
diff --git a/arch/parisc/lib/milli/divI.S b/arch/parisc/lib/milli/divI.S
new file mode 100644
index 0000000..ac106b7
--- /dev/null
+++ b/arch/parisc/lib/milli/divI.S
@@ -0,0 +1,254 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_divI
+/* ROUTINES:	$$divI, $$divoI
+
+   Single precision divide for signed binary integers.
+
+   The quotient is truncated towards zero.
+   The sign of the quotient is the XOR of the signs of the dividend and
+   divisor.
+   Divide by zero is trapped.
+   Divide of -2**31 by -1 is trapped for $$divoI but not for $$divI.
+
+   INPUT REGISTERS:
+   .	arg0 ==	dividend
+   .	arg1 ==	divisor
+   .	mrp  == return pc
+   .	sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .	arg0 =	undefined
+   .	arg1 =	undefined
+   .	ret1 =	quotient
+
+   OTHER REGISTERS AFFECTED:
+   .	r1   =	undefined
+
+   SIDE EFFECTS:
+   .	Causes a trap under the following conditions:
+   .		divisor is zero  (traps with ADDIT,=  0,25,0)
+   .		dividend==-2**31  and divisor==-1 and routine is $$divoI
+   .				 (traps with ADDO  26,25,0)
+   .	Changes memory at the following places:
+   .		NONE
+
+   PERMISSIBLE CONTEXT:
+   .	Unwindable.
+   .	Suitable for internal or external millicode.
+   .	Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .	Branchs to other millicode routines using BE
+   .		$$div_# for # being 2,3,4,5,6,7,8,9,10,12,14,15
+   .
+   .	For selected divisors, calls a divide by constant routine written by
+   .	Karl Pettis.  Eligible divisors are 1..15 excluding 11 and 13.
+   .
+   .	The only overflow case is -2**31 divided by -1.
+   .	Both routines return -2**31 but only $$divoI traps.  */
+
+RDEFINE(temp,r1)
+RDEFINE(retreg,ret1)	/*  r29 */
+RDEFINE(temp1,arg0)
+	SUBSPA_MILLI_DIV
+	ATTR_MILLI
+	.import $$divI_2,millicode
+	.import $$divI_3,millicode
+	.import $$divI_4,millicode
+	.import $$divI_5,millicode
+	.import $$divI_6,millicode
+	.import $$divI_7,millicode
+	.import $$divI_8,millicode
+	.import $$divI_9,millicode
+	.import $$divI_10,millicode
+	.import $$divI_12,millicode
+	.import $$divI_14,millicode
+	.import $$divI_15,millicode
+	.export $$divI,millicode
+	.export	$$divoI,millicode
+	.proc
+	.callinfo	millicode
+	.entry
+GSYM($$divoI)
+	comib,=,n  -1,arg1,LREF(negative1)	/*  when divisor == -1 */
+GSYM($$divI)
+	ldo	-1(arg1),temp		/*  is there at most one bit set ? */
+	and,<>	arg1,temp,r0		/*  if not, don't use power of 2 divide */
+	addi,>	0,arg1,r0		/*  if divisor > 0, use power of 2 divide */
+	b,n	LREF(neg_denom)
+LSYM(pow2)
+	addi,>=	0,arg0,retreg		/*  if numerator is negative, add the */
+	add	arg0,temp,retreg	/*  (denominaotr -1) to correct for shifts */
+	extru,=	arg1,15,16,temp		/*  test denominator with 0xffff0000 */
+	extrs	retreg,15,16,retreg	/*  retreg = retreg >> 16 */
+	or	arg1,temp,arg1		/*  arg1 = arg1 | (arg1 >> 16) */
+	ldi	0xcc,temp1		/*  setup 0xcc in temp1 */
+	extru,= arg1,23,8,temp		/*  test denominator with 0xff00 */
+	extrs	retreg,23,24,retreg	/*  retreg = retreg >> 8 */
+	or	arg1,temp,arg1		/*  arg1 = arg1 | (arg1 >> 8) */
+	ldi	0xaa,temp		/*  setup 0xaa in temp */
+	extru,= arg1,27,4,r0		/*  test denominator with 0xf0 */
+	extrs	retreg,27,28,retreg	/*  retreg = retreg >> 4 */
+	and,=	arg1,temp1,r0		/*  test denominator with 0xcc */
+	extrs	retreg,29,30,retreg	/*  retreg = retreg >> 2 */
+	and,=	arg1,temp,r0		/*  test denominator with 0xaa */
+	extrs	retreg,30,31,retreg	/*  retreg = retreg >> 1 */
+	MILLIRETN
+LSYM(neg_denom)
+	addi,<	0,arg1,r0		/*  if arg1 >= 0, it's not power of 2 */
+	b,n	LREF(regular_seq)
+	sub	r0,arg1,temp		/*  make denominator positive */
+	comb,=,n  arg1,temp,LREF(regular_seq)	/*  test against 0x80000000 and 0 */
+	ldo	-1(temp),retreg		/*  is there at most one bit set ? */
+	and,=	temp,retreg,r0		/*  if so, the denominator is power of 2 */
+	b,n	LREF(regular_seq)
+	sub	r0,arg0,retreg		/*  negate numerator */
+	comb,=,n arg0,retreg,LREF(regular_seq) /*  test against 0x80000000 */
+	copy	retreg,arg0		/*  set up arg0, arg1 and temp	*/
+	copy	temp,arg1		/*  before branching to pow2 */
+	b	LREF(pow2)
+	ldo	-1(arg1),temp
+LSYM(regular_seq)
+	comib,>>=,n 15,arg1,LREF(small_divisor)
+	add,>=	0,arg0,retreg		/*  move dividend, if retreg < 0, */
+LSYM(normal)
+	subi	0,retreg,retreg		/*    make it positive */
+	sub	0,arg1,temp		/*  clear carry,  */
+					/*    negate the divisor */
+	ds	0,temp,0		/*  set V-bit to the comple- */
+					/*    ment of the divisor sign */
+	add	retreg,retreg,retreg	/*  shift msb bit into carry */
+	ds	r0,arg1,temp		/*  1st divide step, if no carry */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  2nd divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  3rd divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  4th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  5th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  6th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  7th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  8th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  9th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  10th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  11th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  12th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  13th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  14th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  15th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  16th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  17th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  18th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  19th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  20th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  21st divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  22nd divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  23rd divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  24th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  25th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  26th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  27th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  28th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  29th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  30th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  31st divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  32nd divide step, */
+	addc	retreg,retreg,retreg	/*  shift last retreg bit into retreg */
+	xor,>=	arg0,arg1,0		/*  get correct sign of quotient */
+	  sub	0,retreg,retreg		/*    based on operand signs */
+	MILLIRETN
+	nop
+
+LSYM(small_divisor)
+
+#if defined(CONFIG_64BIT)
+/*  Clear the upper 32 bits of the arg1 register.  We are working with	*/
+/*  small divisors (and 32-bit integers)   We must not be mislead  */
+/*  by "1" bits left in the upper 32 bits.  */
+	depd %r0,31,32,%r25
+#endif
+	blr,n	arg1,r0
+	nop
+/*  table for divisor == 0,1, ... ,15 */
+	addit,=	0,arg1,r0	/*  trap if divisor == 0 */
+	nop
+	MILLIRET		/*  divisor == 1 */
+	copy	arg0,retreg
+	MILLI_BEN($$divI_2)	/*  divisor == 2 */
+	nop
+	MILLI_BEN($$divI_3)	/*  divisor == 3 */
+	nop
+	MILLI_BEN($$divI_4)	/*  divisor == 4 */
+	nop
+	MILLI_BEN($$divI_5)	/*  divisor == 5 */
+	nop
+	MILLI_BEN($$divI_6)	/*  divisor == 6 */
+	nop
+	MILLI_BEN($$divI_7)	/*  divisor == 7 */
+	nop
+	MILLI_BEN($$divI_8)	/*  divisor == 8 */
+	nop
+	MILLI_BEN($$divI_9)	/*  divisor == 9 */
+	nop
+	MILLI_BEN($$divI_10)	/*  divisor == 10 */
+	nop
+	b	LREF(normal)		/*  divisor == 11 */
+	add,>=	0,arg0,retreg
+	MILLI_BEN($$divI_12)	/*  divisor == 12 */
+	nop
+	b	LREF(normal)		/*  divisor == 13 */
+	add,>=	0,arg0,retreg
+	MILLI_BEN($$divI_14)	/*  divisor == 14 */
+	nop
+	MILLI_BEN($$divI_15)	/*  divisor == 15 */
+	nop
+
+LSYM(negative1)
+	sub	0,arg0,retreg	/*  result is negation of dividend */
+	MILLIRET
+	addo	arg0,arg1,r0	/*  trap iff dividend==0x80000000 && divisor==-1 */
+	.exit
+	.procend
+	.end
+#endif
diff --git a/arch/parisc/lib/milli/divU.S b/arch/parisc/lib/milli/divU.S
new file mode 100644
index 0000000..9287fe2
--- /dev/null
+++ b/arch/parisc/lib/milli/divU.S
@@ -0,0 +1,235 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_divU
+/* ROUTINE:	$$divU
+   .
+   .	Single precision divide for unsigned integers.
+   .
+   .	Quotient is truncated towards zero.
+   .	Traps on divide by zero.
+
+   INPUT REGISTERS:
+   .	arg0 ==	dividend
+   .	arg1 ==	divisor
+   .	mrp  == return pc
+   .	sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .	arg0 =	undefined
+   .	arg1 =	undefined
+   .	ret1 =	quotient
+
+   OTHER REGISTERS AFFECTED:
+   .	r1   =	undefined
+
+   SIDE EFFECTS:
+   .	Causes a trap under the following conditions:
+   .		divisor is zero
+   .	Changes memory at the following places:
+   .		NONE
+
+   PERMISSIBLE CONTEXT:
+   .	Unwindable.
+   .	Does not create a stack frame.
+   .	Suitable for internal or external millicode.
+   .	Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .	Branchs to other millicode routines using BE:
+   .		$$divU_# for 3,5,6,7,9,10,12,14,15
+   .
+   .	For selected small divisors calls the special divide by constant
+   .	routines written by Karl Pettis.  These are: 3,5,6,7,9,10,12,14,15.  */
+
+RDEFINE(temp,r1)
+RDEFINE(retreg,ret1)	/* r29 */
+RDEFINE(temp1,arg0)
+	SUBSPA_MILLI_DIV
+	ATTR_MILLI
+	.export $$divU,millicode
+	.import $$divU_3,millicode
+	.import $$divU_5,millicode
+	.import $$divU_6,millicode
+	.import $$divU_7,millicode
+	.import $$divU_9,millicode
+	.import $$divU_10,millicode
+	.import $$divU_12,millicode
+	.import $$divU_14,millicode
+	.import $$divU_15,millicode
+	.proc
+	.callinfo	millicode
+	.entry
+GSYM($$divU)
+/* The subtract is not nullified since it does no harm and can be used
+   by the two cases that branch back to "normal".  */
+	ldo	-1(arg1),temp		/* is there at most one bit set ? */
+	and,=	arg1,temp,r0		/* if so, denominator is power of 2 */
+	b	LREF(regular_seq)
+	addit,=	0,arg1,0		/* trap for zero dvr */
+	copy	arg0,retreg
+	extru,= arg1,15,16,temp		/* test denominator with 0xffff0000 */
+	extru	retreg,15,16,retreg	/* retreg = retreg >> 16 */
+	or	arg1,temp,arg1		/* arg1 = arg1 | (arg1 >> 16) */
+	ldi	0xcc,temp1		/* setup 0xcc in temp1 */
+	extru,= arg1,23,8,temp		/* test denominator with 0xff00 */
+	extru	retreg,23,24,retreg	/* retreg = retreg >> 8 */
+	or	arg1,temp,arg1		/* arg1 = arg1 | (arg1 >> 8) */
+	ldi	0xaa,temp		/* setup 0xaa in temp */
+	extru,= arg1,27,4,r0		/* test denominator with 0xf0 */
+	extru	retreg,27,28,retreg	/* retreg = retreg >> 4 */
+	and,=	arg1,temp1,r0		/* test denominator with 0xcc */
+	extru	retreg,29,30,retreg	/* retreg = retreg >> 2 */
+	and,=	arg1,temp,r0		/* test denominator with 0xaa */
+	extru	retreg,30,31,retreg	/* retreg = retreg >> 1 */
+	MILLIRETN
+	nop	
+LSYM(regular_seq)
+	comib,>=  15,arg1,LREF(special_divisor)
+	subi	0,arg1,temp		/* clear carry, negate the divisor */
+	ds	r0,temp,r0		/* set V-bit to 1 */
+LSYM(normal)
+	add	arg0,arg0,retreg	/* shift msb bit into carry */
+	ds	r0,arg1,temp		/* 1st divide step, if no carry */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 2nd divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 3rd divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 4th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 5th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 6th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 7th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 8th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 9th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 10th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 11th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 12th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 13th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 14th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 15th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 16th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 17th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 18th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 19th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 20th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 21st divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 22nd divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 23rd divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 24th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 25th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 26th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 27th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 28th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 29th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 30th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 31st divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 32nd divide step, */
+	MILLIRET
+	addc	retreg,retreg,retreg	/* shift last retreg bit into retreg */
+
+/* Handle the cases where divisor is a small constant or has high bit on.  */
+LSYM(special_divisor)
+/*	blr	arg1,r0 */
+/*	comib,>,n  0,arg1,LREF(big_divisor) ; nullify previous instruction */
+
+/* Pratap 8/13/90. The 815 Stirling chip set has a bug that prevents us from
+   generating such a blr, comib sequence. A problem in nullification. So I
+   rewrote this code.  */
+
+#if defined(CONFIG_64BIT)
+/* Clear the upper 32 bits of the arg1 register.  We are working with
+   small divisors (and 32-bit unsigned integers)   We must not be mislead
+   by "1" bits left in the upper 32 bits.  */
+	depd %r0,31,32,%r25
+#endif
+	comib,>	0,arg1,LREF(big_divisor)
+	nop
+	blr	arg1,r0
+	nop
+
+LSYM(zero_divisor)	/* this label is here to provide external visibility */
+	addit,=	0,arg1,0		/* trap for zero dvr */
+	nop
+	MILLIRET			/* divisor == 1 */
+	copy	arg0,retreg
+	MILLIRET			/* divisor == 2 */
+	extru	arg0,30,31,retreg
+	MILLI_BEN($$divU_3)		/* divisor == 3 */
+	nop
+	MILLIRET			/* divisor == 4 */
+	extru	arg0,29,30,retreg
+	MILLI_BEN($$divU_5)		/* divisor == 5 */
+	nop
+	MILLI_BEN($$divU_6)		/* divisor == 6 */
+	nop
+	MILLI_BEN($$divU_7)		/* divisor == 7 */
+	nop
+	MILLIRET			/* divisor == 8 */
+	extru	arg0,28,29,retreg
+	MILLI_BEN($$divU_9)		/* divisor == 9 */
+	nop
+	MILLI_BEN($$divU_10)		/* divisor == 10 */
+	nop
+	b	LREF(normal)		/* divisor == 11 */
+	ds	r0,temp,r0		/* set V-bit to 1 */
+	MILLI_BEN($$divU_12)		/* divisor == 12 */
+	nop
+	b	LREF(normal)		/* divisor == 13 */
+	ds	r0,temp,r0		/* set V-bit to 1 */
+	MILLI_BEN($$divU_14)		/* divisor == 14 */
+	nop
+	MILLI_BEN($$divU_15)		/* divisor == 15 */
+	nop
+
+/* Handle the case where the high bit is on in the divisor.
+   Compute:	if( dividend>=divisor) quotient=1; else quotient=0;
+   Note:	dividend>==divisor iff dividend-divisor does not borrow
+   and		not borrow iff carry.  */
+LSYM(big_divisor)
+	sub	arg0,arg1,r0
+	MILLIRET
+	addc	r0,r0,retreg
+	.exit
+	.procend
+	.end
+#endif
diff --git a/arch/parisc/lib/milli/div_const.S b/arch/parisc/lib/milli/div_const.S
new file mode 100644
index 0000000..dd66007
--- /dev/null
+++ b/arch/parisc/lib/milli/div_const.S
@@ -0,0 +1,682 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_div_const
+/* ROUTINE:	$$divI_2
+   .		$$divI_3	$$divU_3
+   .		$$divI_4
+   .		$$divI_5	$$divU_5
+   .		$$divI_6	$$divU_6
+   .		$$divI_7	$$divU_7
+   .		$$divI_8
+   .		$$divI_9	$$divU_9
+   .		$$divI_10	$$divU_10
+   .
+   .		$$divI_12	$$divU_12
+   .
+   .		$$divI_14	$$divU_14
+   .		$$divI_15	$$divU_15
+   .		$$divI_16
+   .		$$divI_17	$$divU_17
+   .
+   .	Divide by selected constants for single precision binary integers.
+
+   INPUT REGISTERS:
+   .	arg0 ==	dividend
+   .	mrp  == return pc
+   .	sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .	arg0 =	undefined
+   .	arg1 =	undefined
+   .	ret1 =	quotient
+
+   OTHER REGISTERS AFFECTED:
+   .	r1   =	undefined
+
+   SIDE EFFECTS:
+   .	Causes a trap under the following conditions: NONE
+   .	Changes memory at the following places:  NONE
+
+   PERMISSIBLE CONTEXT:
+   .	Unwindable.
+   .	Does not create a stack frame.
+   .	Suitable for internal or external millicode.
+   .	Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .	Calls other millicode routines using mrp:  NONE
+   .	Calls other millicode routines:  NONE  */
+
+
+/* TRUNCATED DIVISION BY SMALL INTEGERS
+
+   We are interested in q(x) = floor(x/y), where x >= 0 and y > 0
+   (with y fixed).
+
+   Let a = floor(z/y), for some choice of z.  Note that z will be
+   chosen so that division by z is cheap.
+
+   Let r be the remainder(z/y).  In other words, r = z - ay.
+
+   Now, our method is to choose a value for b such that
+
+   q'(x) = floor((ax+b)/z)
+
+   is equal to q(x) over as large a range of x as possible.  If the
+   two are equal over a sufficiently large range, and if it is easy to
+   form the product (ax), and it is easy to divide by z, then we can
+   perform the division much faster than the general division algorithm.
+
+   So, we want the following to be true:
+
+   .	For x in the following range:
+   .
+   .	    ky <= x < (k+1)y
+   .
+   .	implies that
+   .
+   .	    k <= (ax+b)/z < (k+1)
+
+   We want to determine b such that this is true for all k in the
+   range {0..K} for some maximum K.
+
+   Since (ax+b) is an increasing function of x, we can take each
+   bound separately to determine the "best" value for b.
+
+   (ax+b)/z < (k+1)	       implies
+
+   (a((k+1)y-1)+b < (k+1)z     implies
+
+   b < a + (k+1)(z-ay)	       implies
+
+   b < a + (k+1)r
+
+   This needs to be true for all k in the range {0..K}.  In
+   particular, it is true for k = 0 and this leads to a maximum
+   acceptable value for b.
+
+   b < a+r   or   b <= a+r-1
+
+   Taking the other bound, we have
+
+   k <= (ax+b)/z	       implies
+
+   k <= (aky+b)/z	       implies
+
+   k(z-ay) <= b		       implies
+
+   kr <= b
+
+   Clearly, the largest range for k will be achieved by maximizing b,
+   when r is not zero.	When r is zero, then the simplest choice for b
+   is 0.  When r is not 0, set
+
+   .	b = a+r-1
+
+   Now, by construction, q'(x) = floor((ax+b)/z) = q(x) = floor(x/y)
+   for all x in the range:
+
+   .	0 <= x < (K+1)y
+
+   We need to determine what K is.  Of our two bounds,
+
+   .	b < a+(k+1)r	is satisfied for all k >= 0, by construction.
+
+   The other bound is
+
+   .	kr <= b
+
+   This is always true if r = 0.  If r is not 0 (the usual case), then
+   K = floor((a+r-1)/r), is the maximum value for k.
+
+   Therefore, the formula q'(x) = floor((ax+b)/z) yields the correct
+   answer for q(x) = floor(x/y) when x is in the range
+
+   (0,(K+1)y-1)	       K = floor((a+r-1)/r)
+
+   To be most useful, we want (K+1)y-1 = (max x) >= 2**32-1 so that
+   the formula for q'(x) yields the correct value of q(x) for all x
+   representable by a single word in HPPA.
+
+   We are also constrained in that computing the product (ax), adding
+   b, and dividing by z must all be done quickly, otherwise we will be
+   better off going through the general algorithm using the DS
+   instruction, which uses approximately 70 cycles.
+
+   For each y, there is a choice of z which satisfies the constraints
+   for (K+1)y >= 2**32.  We may not, however, be able to satisfy the
+   timing constraints for arbitrary y.	It seems that z being equal to
+   a power of 2 or a power of 2 minus 1 is as good as we can do, since
+   it minimizes the time to do division by z.  We want the choice of z
+   to also result in a value for (a) that minimizes the computation of
+   the product (ax).  This is best achieved if (a) has a regular bit
+   pattern (so the multiplication can be done with shifts and adds).
+   The value of (a) also needs to be less than 2**32 so the product is
+   always guaranteed to fit in 2 words.
+
+   In actual practice, the following should be done:
+
+   1) For negative x, you should take the absolute value and remember
+   .  the fact so that the result can be negated.  This obviously does
+   .  not apply in the unsigned case.
+   2) For even y, you should factor out the power of 2 that divides y
+   .  and divide x by it.  You can then proceed by dividing by the
+   .  odd factor of y.
+
+   Here is a table of some odd values of y, and corresponding choices
+   for z which are "good".
+
+    y	  z	  r	 a (hex)     max x (hex)
+
+    3	2**32	  1	55555555      100000001
+    5	2**32	  1	33333333      100000003
+    7  2**24-1	  0	  249249     (infinite)
+    9  2**24-1	  0	  1c71c7     (infinite)
+   11  2**20-1	  0	   1745d     (infinite)
+   13  2**24-1	  0	  13b13b     (infinite)
+   15	2**32	  1	11111111      10000000d
+   17	2**32	  1	 f0f0f0f      10000000f
+
+   If r is 1, then b = a+r-1 = a.  This simplifies the computation
+   of (ax+b), since you can compute (x+1)(a) instead.  If r is 0,
+   then b = 0 is ok to use which simplifies (ax+b).
+
+   The bit patterns for 55555555, 33333333, and 11111111 are obviously
+   very regular.  The bit patterns for the other values of a above are:
+
+    y	   (hex)	  (binary)
+
+    7	  249249  001001001001001001001001  << regular >>
+    9	  1c71c7  000111000111000111000111  << regular >>
+   11	   1745d  000000010111010001011101  << irregular >>
+   13	  13b13b  000100111011000100111011  << irregular >>
+
+   The bit patterns for (a) corresponding to (y) of 11 and 13 may be
+   too irregular to warrant using this method.
+
+   When z is a power of 2 minus 1, then the division by z is slightly
+   more complicated, involving an iterative solution.
+
+   The code presented here solves division by 1 through 17, except for
+   11 and 13. There are algorithms for both signed and unsigned
+   quantities given.
+
+   TIMINGS (cycles)
+
+   divisor  positive  negative	unsigned
+
+   .   1	2	   2	     2
+   .   2	4	   4	     2
+   .   3       19	  21	    19
+   .   4	4	   4	     2
+   .   5       18	  22	    19
+   .   6       19	  22	    19
+   .   8	4	   4	     2
+   .  10       18	  19	    17
+   .  12       18	  20	    18
+   .  15       16	  18	    16
+   .  16	4	   4	     2
+   .  17       16	  18	    16
+
+   Now, the algorithm for 7, 9, and 14 is an iterative one.  That is,
+   a loop body is executed until the tentative quotient is 0.  The
+   number of times the loop body is executed varies depending on the
+   dividend, but is never more than two times.	If the dividend is
+   less than the divisor, then the loop body is not executed at all.
+   Each iteration adds 4 cycles to the timings.
+
+   divisor  positive  negative	unsigned
+
+   .   7       19+4n	 20+4n	   20+4n    n = number of iterations
+   .   9       21+4n	 22+4n	   21+4n
+   .  14       21+4n	 22+4n	   20+4n
+
+   To give an idea of how the number of iterations varies, here is a
+   table of dividend versus number of iterations when dividing by 7.
+
+   smallest	 largest       required
+   dividend	dividend      iterations
+
+   .	0	     6		    0
+   .	7	 0x6ffffff	    1
+   0x1000006	0xffffffff	    2
+
+   There is some overlap in the range of numbers requiring 1 and 2
+   iterations.	*/
+
+RDEFINE(t2,r1)
+RDEFINE(x2,arg0)	/*  r26 */
+RDEFINE(t1,arg1)	/*  r25 */
+RDEFINE(x1,ret1)	/*  r29 */
+
+	SUBSPA_MILLI_DIV
+	ATTR_MILLI
+
+	.proc
+	.callinfo	millicode
+	.entry
+/* NONE of these routines require a stack frame
+   ALL of these routines are unwindable from millicode	*/
+
+GSYM($$divide_by_constant)
+	.export $$divide_by_constant,millicode
+/*  Provides a "nice" label for the code covered by the unwind descriptor
+    for things like gprof.  */
+
+/* DIVISION BY 2 (shift by 1) */
+GSYM($$divI_2)
+	.export		$$divI_2,millicode
+	comclr,>=	arg0,0,0
+	addi		1,arg0,arg0
+	MILLIRET
+	extrs		arg0,30,31,ret1
+
+
+/* DIVISION BY 4 (shift by 2) */
+GSYM($$divI_4)
+	.export		$$divI_4,millicode
+	comclr,>=	arg0,0,0
+	addi		3,arg0,arg0
+	MILLIRET
+	extrs		arg0,29,30,ret1
+
+
+/* DIVISION BY 8 (shift by 3) */
+GSYM($$divI_8)
+	.export		$$divI_8,millicode
+	comclr,>=	arg0,0,0
+	addi		7,arg0,arg0
+	MILLIRET
+	extrs		arg0,28,29,ret1
+
+/* DIVISION BY 16 (shift by 4) */
+GSYM($$divI_16)
+	.export		$$divI_16,millicode
+	comclr,>=	arg0,0,0
+	addi		15,arg0,arg0
+	MILLIRET
+	extrs		arg0,27,28,ret1
+
+/****************************************************************************
+*
+*	DIVISION BY DIVISORS OF FFFFFFFF, and powers of 2 times these
+*
+*	includes 3,5,15,17 and also 6,10,12
+*
+****************************************************************************/
+
+/* DIVISION BY 3 (use z = 2**32; a = 55555555) */
+
+GSYM($$divI_3)
+	.export		$$divI_3,millicode
+	comb,<,N	x2,0,LREF(neg3)
+
+	addi		1,x2,x2		/* this cannot overflow	*/
+	extru		x2,1,2,x1	/* multiply by 5 to get started */
+	sh2add		x2,x2,x2
+	b		LREF(pos)
+	addc		x1,0,x1
+
+LSYM(neg3)
+	subi		1,x2,x2		/* this cannot overflow	*/
+	extru		x2,1,2,x1	/* multiply by 5 to get started */
+	sh2add		x2,x2,x2
+	b		LREF(neg)
+	addc		x1,0,x1
+
+GSYM($$divU_3)
+	.export		$$divU_3,millicode
+	addi		1,x2,x2		/* this CAN overflow */
+	addc		0,0,x1
+	shd		x1,x2,30,t1	/* multiply by 5 to get started */
+	sh2add		x2,x2,x2
+	b		LREF(pos)
+	addc		x1,t1,x1
+
+/* DIVISION BY 5 (use z = 2**32; a = 33333333) */
+
+GSYM($$divI_5)
+	.export		$$divI_5,millicode
+	comb,<,N	x2,0,LREF(neg5)
+
+	addi		3,x2,t1		/* this cannot overflow	*/
+	sh1add		x2,t1,x2	/* multiply by 3 to get started */
+	b		LREF(pos)
+	addc		0,0,x1
+
+LSYM(neg5)
+	sub		0,x2,x2		/* negate x2			*/
+	addi		1,x2,x2		/* this cannot overflow	*/
+	shd		0,x2,31,x1	/* get top bit (can be 1)	*/
+	sh1add		x2,x2,x2	/* multiply by 3 to get started */
+	b		LREF(neg)
+	addc		x1,0,x1
+
+GSYM($$divU_5)
+	.export		$$divU_5,millicode
+	addi		1,x2,x2		/* this CAN overflow */
+	addc		0,0,x1
+	shd		x1,x2,31,t1	/* multiply by 3 to get started */
+	sh1add		x2,x2,x2
+	b		LREF(pos)
+	addc		t1,x1,x1
+
+/* DIVISION BY	6 (shift to divide by 2 then divide by 3) */
+GSYM($$divI_6)
+	.export		$$divI_6,millicode
+	comb,<,N	x2,0,LREF(neg6)
+	extru		x2,30,31,x2	/* divide by 2			*/
+	addi		5,x2,t1		/* compute 5*(x2+1) = 5*x2+5	*/
+	sh2add		x2,t1,x2	/* multiply by 5 to get started */
+	b		LREF(pos)
+	addc		0,0,x1
+
+LSYM(neg6)
+	subi		2,x2,x2		/* negate, divide by 2, and add 1 */
+					/* negation and adding 1 are done */
+					/* at the same time by the SUBI   */
+	extru		x2,30,31,x2
+	shd		0,x2,30,x1
+	sh2add		x2,x2,x2	/* multiply by 5 to get started */
+	b		LREF(neg)
+	addc		x1,0,x1
+
+GSYM($$divU_6)
+	.export		$$divU_6,millicode
+	extru		x2,30,31,x2	/* divide by 2 */
+	addi		1,x2,x2		/* cannot carry */
+	shd		0,x2,30,x1	/* multiply by 5 to get started */
+	sh2add		x2,x2,x2
+	b		LREF(pos)
+	addc		x1,0,x1
+
+/* DIVISION BY 10 (shift to divide by 2 then divide by 5) */
+GSYM($$divU_10)
+	.export		$$divU_10,millicode
+	extru		x2,30,31,x2	/* divide by 2 */
+	addi		3,x2,t1		/* compute 3*(x2+1) = (3*x2)+3	*/
+	sh1add		x2,t1,x2	/* multiply by 3 to get started */
+	addc		0,0,x1
+LSYM(pos)
+	shd		x1,x2,28,t1	/* multiply by 0x11 */
+	shd		x2,0,28,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+LSYM(pos_for_17)
+	shd		x1,x2,24,t1	/* multiply by 0x101 */
+	shd		x2,0,24,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+
+	shd		x1,x2,16,t1	/* multiply by 0x10001 */
+	shd		x2,0,16,t2
+	add		x2,t2,x2
+	MILLIRET
+	addc		x1,t1,x1
+
+GSYM($$divI_10)
+	.export		$$divI_10,millicode
+	comb,<		x2,0,LREF(neg10)
+	copy		0,x1
+	extru		x2,30,31,x2	/* divide by 2 */
+	addib,TR	1,x2,LREF(pos)	/* add 1 (cannot overflow)     */
+	sh1add		x2,x2,x2	/* multiply by 3 to get started */
+
+LSYM(neg10)
+	subi		2,x2,x2		/* negate, divide by 2, and add 1 */
+					/* negation and adding 1 are done */
+					/* at the same time by the SUBI   */
+	extru		x2,30,31,x2
+	sh1add		x2,x2,x2	/* multiply by 3 to get started */
+LSYM(neg)
+	shd		x1,x2,28,t1	/* multiply by 0x11 */
+	shd		x2,0,28,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+LSYM(neg_for_17)
+	shd		x1,x2,24,t1	/* multiply by 0x101 */
+	shd		x2,0,24,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+
+	shd		x1,x2,16,t1	/* multiply by 0x10001 */
+	shd		x2,0,16,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+	MILLIRET
+	sub		0,x1,x1
+
+/* DIVISION BY 12 (shift to divide by 4 then divide by 3) */
+GSYM($$divI_12)
+	.export		$$divI_12,millicode
+	comb,<		x2,0,LREF(neg12)
+	copy		0,x1
+	extru		x2,29,30,x2	/* divide by 4			*/
+	addib,tr	1,x2,LREF(pos)	/* compute 5*(x2+1) = 5*x2+5    */
+	sh2add		x2,x2,x2	/* multiply by 5 to get started */
+
+LSYM(neg12)
+	subi		4,x2,x2		/* negate, divide by 4, and add 1 */
+					/* negation and adding 1 are done */
+					/* at the same time by the SUBI   */
+	extru		x2,29,30,x2
+	b		LREF(neg)
+	sh2add		x2,x2,x2	/* multiply by 5 to get started */
+
+GSYM($$divU_12)
+	.export		$$divU_12,millicode
+	extru		x2,29,30,x2	/* divide by 4   */
+	addi		5,x2,t1		/* cannot carry */
+	sh2add		x2,t1,x2	/* multiply by 5 to get started */
+	b		LREF(pos)
+	addc		0,0,x1
+
+/* DIVISION BY 15 (use z = 2**32; a = 11111111) */
+GSYM($$divI_15)
+	.export		$$divI_15,millicode
+	comb,<		x2,0,LREF(neg15)
+	copy		0,x1
+	addib,tr	1,x2,LREF(pos)+4
+	shd		x1,x2,28,t1
+
+LSYM(neg15)
+	b		LREF(neg)
+	subi		1,x2,x2
+
+GSYM($$divU_15)
+	.export		$$divU_15,millicode
+	addi		1,x2,x2		/* this CAN overflow */
+	b		LREF(pos)
+	addc		0,0,x1
+
+/* DIVISION BY 17 (use z = 2**32; a =  f0f0f0f) */
+GSYM($$divI_17)
+	.export		$$divI_17,millicode
+	comb,<,n	x2,0,LREF(neg17)
+	addi		1,x2,x2		/* this cannot overflow */
+	shd		0,x2,28,t1	/* multiply by 0xf to get started */
+	shd		x2,0,28,t2
+	sub		t2,x2,x2
+	b		LREF(pos_for_17)
+	subb		t1,0,x1
+
+LSYM(neg17)
+	subi		1,x2,x2		/* this cannot overflow */
+	shd		0,x2,28,t1	/* multiply by 0xf to get started */
+	shd		x2,0,28,t2
+	sub		t2,x2,x2
+	b		LREF(neg_for_17)
+	subb		t1,0,x1
+
+GSYM($$divU_17)
+	.export		$$divU_17,millicode
+	addi		1,x2,x2		/* this CAN overflow */
+	addc		0,0,x1
+	shd		x1,x2,28,t1	/* multiply by 0xf to get started */
+LSYM(u17)
+	shd		x2,0,28,t2
+	sub		t2,x2,x2
+	b		LREF(pos_for_17)
+	subb		t1,x1,x1
+
+
+/* DIVISION BY DIVISORS OF FFFFFF, and powers of 2 times these
+   includes 7,9 and also 14
+
+
+   z = 2**24-1
+   r = z mod x = 0
+
+   so choose b = 0
+
+   Also, in order to divide by z = 2**24-1, we approximate by dividing
+   by (z+1) = 2**24 (which is easy), and then correcting.
+
+   (ax) = (z+1)q' + r
+   .	= zq' + (q'+r)
+
+   So to compute (ax)/z, compute q' = (ax)/(z+1) and r = (ax) mod (z+1)
+   Then the true remainder of (ax)/z is (q'+r).  Repeat the process
+   with this new remainder, adding the tentative quotients together,
+   until a tentative quotient is 0 (and then we are done).  There is
+   one last correction to be done.  It is possible that (q'+r) = z.
+   If so, then (q'+r)/(z+1) = 0 and it looks like we are done.	But,
+   in fact, we need to add 1 more to the quotient.  Now, it turns
+   out that this happens if and only if the original value x is
+   an exact multiple of y.  So, to avoid a three instruction test at
+   the end, instead use 1 instruction to add 1 to x at the beginning.  */
+
+/* DIVISION BY 7 (use z = 2**24-1; a = 249249) */
+GSYM($$divI_7)
+	.export		$$divI_7,millicode
+	comb,<,n	x2,0,LREF(neg7)
+LSYM(7)
+	addi		1,x2,x2		/* cannot overflow */
+	shd		0,x2,29,x1
+	sh3add		x2,x2,x2
+	addc		x1,0,x1
+LSYM(pos7)
+	shd		x1,x2,26,t1
+	shd		x2,0,26,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+
+	shd		x1,x2,20,t1
+	shd		x2,0,20,t2
+	add		x2,t2,x2
+	addc		x1,t1,t1
+
+	/* computed <t1,x2>.  Now divide it by (2**24 - 1)	*/
+
+	copy		0,x1
+	shd,=		t1,x2,24,t1	/* tentative quotient  */
+LSYM(1)
+	addb,tr		t1,x1,LREF(2)	/* add to previous quotient   */
+	extru		x2,31,24,x2	/* new remainder (unadjusted) */
+
+	MILLIRETN
+
+LSYM(2)
+	addb,tr		t1,x2,LREF(1)	/* adjust remainder */
+	extru,=		x2,7,8,t1	/* new quotient     */
+
+LSYM(neg7)
+	subi		1,x2,x2		/* negate x2 and add 1 */
+LSYM(8)
+	shd		0,x2,29,x1
+	sh3add		x2,x2,x2
+	addc		x1,0,x1
+
+LSYM(neg7_shift)
+	shd		x1,x2,26,t1
+	shd		x2,0,26,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+
+	shd		x1,x2,20,t1
+	shd		x2,0,20,t2
+	add		x2,t2,x2
+	addc		x1,t1,t1
+
+	/* computed <t1,x2>.  Now divide it by (2**24 - 1)	*/
+
+	copy		0,x1
+	shd,=		t1,x2,24,t1	/* tentative quotient  */
+LSYM(3)
+	addb,tr		t1,x1,LREF(4)	/* add to previous quotient   */
+	extru		x2,31,24,x2	/* new remainder (unadjusted) */
+
+	MILLIRET
+	sub		0,x1,x1		/* negate result    */
+
+LSYM(4)
+	addb,tr		t1,x2,LREF(3)	/* adjust remainder */
+	extru,=		x2,7,8,t1	/* new quotient     */
+
+GSYM($$divU_7)
+	.export		$$divU_7,millicode
+	addi		1,x2,x2		/* can carry */
+	addc		0,0,x1
+	shd		x1,x2,29,t1
+	sh3add		x2,x2,x2
+	b		LREF(pos7)
+	addc		t1,x1,x1
+
+/* DIVISION BY 9 (use z = 2**24-1; a = 1c71c7) */
+GSYM($$divI_9)
+	.export		$$divI_9,millicode
+	comb,<,n	x2,0,LREF(neg9)
+	addi		1,x2,x2		/* cannot overflow */
+	shd		0,x2,29,t1
+	shd		x2,0,29,t2
+	sub		t2,x2,x2
+	b		LREF(pos7)
+	subb		t1,0,x1
+
+LSYM(neg9)
+	subi		1,x2,x2		/* negate and add 1 */
+	shd		0,x2,29,t1
+	shd		x2,0,29,t2
+	sub		t2,x2,x2
+	b		LREF(neg7_shift)
+	subb		t1,0,x1
+
+GSYM($$divU_9)
+	.export		$$divU_9,millicode
+	addi		1,x2,x2		/* can carry */
+	addc		0,0,x1
+	shd		x1,x2,29,t1
+	shd		x2,0,29,t2
+	sub		t2,x2,x2
+	b		LREF(pos7)
+	subb		t1,x1,x1
+
+/* DIVISION BY 14 (shift to divide by 2 then divide by 7) */
+GSYM($$divI_14)
+	.export		$$divI_14,millicode
+	comb,<,n	x2,0,LREF(neg14)
+GSYM($$divU_14)
+	.export		$$divU_14,millicode
+	b		LREF(7)		/* go to 7 case */
+	extru		x2,30,31,x2	/* divide by 2  */
+
+LSYM(neg14)
+	subi		2,x2,x2		/* negate (and add 2) */
+	b		LREF(8)
+	extru		x2,30,31,x2	/* divide by 2	      */
+	.exit
+	.procend
+	.end
+#endif
diff --git a/arch/parisc/lib/milli/dyncall.S b/arch/parisc/lib/milli/dyncall.S
new file mode 100644
index 0000000..27f9ca5
--- /dev/null
+++ b/arch/parisc/lib/milli/dyncall.S
@@ -0,0 +1,32 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_dyncall
+	SUBSPA_MILLI
+	ATTR_DATA
+GSYM($$dyncall)
+	.export $$dyncall,millicode
+	.proc
+	.callinfo	millicode
+	.entry
+	bb,>=,n %r22,30,LREF(1)		; branch if not plabel address
+	depi	0,31,2,%r22		; clear the two least significant bits
+	ldw	4(%r22),%r19		; load new LTP value
+	ldw	0(%r22),%r22		; load address of target
+LSYM(1)
+	bv	%r0(%r22)		; branch to the real target
+	stw	%r2,-24(%r30)		; save return address into frame marker
+	.exit
+	.procend
+#endif
diff --git a/arch/parisc/lib/milli/milli.S b/arch/parisc/lib/milli/milli.S
new file mode 100644
index 0000000..47c6cde
--- /dev/null
+++ b/arch/parisc/lib/milli/milli.S
@@ -0,0 +1,2071 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#ifdef CONFIG_64BIT
+        .level  2.0w
+#endif
+
+/* Hardware General Registers.  */
+r0:	.reg	%r0
+r1:	.reg	%r1
+r2:	.reg	%r2
+r3:	.reg	%r3
+r4:	.reg	%r4
+r5:	.reg	%r5
+r6:	.reg	%r6
+r7:	.reg	%r7
+r8:	.reg	%r8
+r9:	.reg	%r9
+r10:	.reg	%r10
+r11:	.reg	%r11
+r12:	.reg	%r12
+r13:	.reg	%r13
+r14:	.reg	%r14
+r15:	.reg	%r15
+r16:	.reg	%r16
+r17:	.reg	%r17
+r18:	.reg	%r18
+r19:	.reg	%r19
+r20:	.reg	%r20
+r21:	.reg	%r21
+r22:	.reg	%r22
+r23:	.reg	%r23
+r24:	.reg	%r24
+r25:	.reg	%r25
+r26:	.reg	%r26
+r27:	.reg	%r27
+r28:	.reg	%r28
+r29:	.reg	%r29
+r30:	.reg	%r30
+r31:	.reg	%r31
+
+/* Hardware Space Registers.  */
+sr0:	.reg	%sr0
+sr1:	.reg	%sr1
+sr2:	.reg	%sr2
+sr3:	.reg	%sr3
+sr4:	.reg	%sr4
+sr5:	.reg	%sr5
+sr6:	.reg	%sr6
+sr7:	.reg	%sr7
+
+/* Hardware Floating Point Registers.  */
+fr0:	.reg	%fr0
+fr1:	.reg	%fr1
+fr2:	.reg	%fr2
+fr3:	.reg	%fr3
+fr4:	.reg	%fr4
+fr5:	.reg	%fr5
+fr6:	.reg	%fr6
+fr7:	.reg	%fr7
+fr8:	.reg	%fr8
+fr9:	.reg	%fr9
+fr10:	.reg	%fr10
+fr11:	.reg	%fr11
+fr12:	.reg	%fr12
+fr13:	.reg	%fr13
+fr14:	.reg	%fr14
+fr15:	.reg	%fr15
+
+/* Hardware Control Registers.  */
+cr11:	.reg	%cr11
+sar:	.reg	%cr11	/* Shift Amount Register */
+
+/* Software Architecture General Registers.  */
+rp:	.reg    r2	/* return pointer */
+#ifdef CONFIG_64BIT
+mrp:	.reg	r2 	/* millicode return pointer */
+#else
+mrp:	.reg	r31	/* millicode return pointer */
+#endif
+ret0:	.reg    r28	/* return value */
+ret1:	.reg    r29	/* return value (high part of double) */
+sp:	.reg 	r30	/* stack pointer */
+dp:	.reg	r27	/* data pointer */
+arg0:	.reg	r26	/* argument */
+arg1:	.reg	r25	/* argument or high part of double argument */
+arg2:	.reg	r24	/* argument */
+arg3:	.reg	r23	/* argument or high part of double argument */
+
+/* Software Architecture Space Registers.  */
+/* 		sr0	; return link from BLE */
+sret:	.reg	sr1	/* return value */
+sarg:	.reg	sr1	/* argument */
+/* 		sr4	; PC SPACE tracker */
+/* 		sr5	; process private data */
+
+/* Frame Offsets (millicode convention!)  Used when calling other
+   millicode routines.  Stack unwinding is dependent upon these
+   definitions.  */
+r31_slot:	.equ	-20	/* "current RP" slot */
+sr0_slot:	.equ	-16     /* "static link" slot */
+#if defined(CONFIG_64BIT)
+mrp_slot:       .equ    -16	/* "current RP" slot */
+psp_slot:       .equ    -8	/* "previous SP" slot */
+#else
+mrp_slot:	.equ	-20     /* "current RP" slot (replacing "r31_slot") */
+#endif
+
+
+#define DEFINE(name,value)name:	.EQU	value
+#define RDEFINE(name,value)name:	.REG	value
+#ifdef milliext
+#define MILLI_BE(lbl)   BE    lbl(sr7,r0)
+#define MILLI_BEN(lbl)  BE,n  lbl(sr7,r0)
+#define MILLI_BLE(lbl)	BLE   lbl(sr7,r0)
+#define MILLI_BLEN(lbl)	BLE,n lbl(sr7,r0)
+#define MILLIRETN	BE,n  0(sr0,mrp)
+#define MILLIRET	BE    0(sr0,mrp)
+#define MILLI_RETN	BE,n  0(sr0,mrp)
+#define MILLI_RET	BE    0(sr0,mrp)
+#else
+#define MILLI_BE(lbl)	B     lbl
+#define MILLI_BEN(lbl)  B,n   lbl
+#define MILLI_BLE(lbl)	BL    lbl,mrp
+#define MILLI_BLEN(lbl)	BL,n  lbl,mrp
+#define MILLIRETN	BV,n  0(mrp)
+#define MILLIRET	BV    0(mrp)
+#define MILLI_RETN	BV,n  0(mrp)
+#define MILLI_RET	BV    0(mrp)
+#endif
+
+#define CAT(a,b)	a##b
+
+#define SUBSPA_MILLI	 .section .text
+#define SUBSPA_MILLI_DIV .section .text.div,"ax",@progbits! .align 16
+#define SUBSPA_MILLI_MUL .section .text.mul,"ax",@progbits! .align 16
+#define ATTR_MILLI
+#define SUBSPA_DATA	 .section .data
+#define ATTR_DATA
+#define GLOBAL		 $global$
+#define GSYM(sym) 	 !sym:
+#define LSYM(sym)	 !CAT(.L,sym:)
+#define LREF(sym)	 CAT(.L,sym)
+
+#ifdef L_dyncall
+	SUBSPA_MILLI
+	ATTR_DATA
+GSYM($$dyncall)
+	.export $$dyncall,millicode
+	.proc
+	.callinfo	millicode
+	.entry
+	bb,>=,n %r22,30,LREF(1)		; branch if not plabel address
+	depi	0,31,2,%r22		; clear the two least significant bits
+	ldw	4(%r22),%r19		; load new LTP value
+	ldw	0(%r22),%r22		; load address of target
+LSYM(1)
+	bv	%r0(%r22)		; branch to the real target
+	stw	%r2,-24(%r30)		; save return address into frame marker
+	.exit
+	.procend
+#endif
+
+#ifdef L_divI
+/* ROUTINES:	$$divI, $$divoI
+
+   Single precision divide for signed binary integers.
+
+   The quotient is truncated towards zero.
+   The sign of the quotient is the XOR of the signs of the dividend and
+   divisor.
+   Divide by zero is trapped.
+   Divide of -2**31 by -1 is trapped for $$divoI but not for $$divI.
+
+   INPUT REGISTERS:
+   .	arg0 ==	dividend
+   .	arg1 ==	divisor
+   .	mrp  == return pc
+   .	sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .	arg0 =	undefined
+   .	arg1 =	undefined
+   .	ret1 =	quotient
+
+   OTHER REGISTERS AFFECTED:
+   .	r1   =	undefined
+
+   SIDE EFFECTS:
+   .	Causes a trap under the following conditions:
+   .		divisor is zero  (traps with ADDIT,=  0,25,0)
+   .		dividend==-2**31  and divisor==-1 and routine is $$divoI
+   .				 (traps with ADDO  26,25,0)
+   .	Changes memory at the following places:
+   .		NONE
+
+   PERMISSIBLE CONTEXT:
+   .	Unwindable.
+   .	Suitable for internal or external millicode.
+   .	Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .	Branchs to other millicode routines using BE
+   .		$$div_# for # being 2,3,4,5,6,7,8,9,10,12,14,15
+   .
+   .	For selected divisors, calls a divide by constant routine written by
+   .	Karl Pettis.  Eligible divisors are 1..15 excluding 11 and 13.
+   .
+   .	The only overflow case is -2**31 divided by -1.
+   .	Both routines return -2**31 but only $$divoI traps.  */
+
+RDEFINE(temp,r1)
+RDEFINE(retreg,ret1)	/*  r29 */
+RDEFINE(temp1,arg0)
+	SUBSPA_MILLI_DIV
+	ATTR_MILLI
+	.import $$divI_2,millicode
+	.import $$divI_3,millicode
+	.import $$divI_4,millicode
+	.import $$divI_5,millicode
+	.import $$divI_6,millicode
+	.import $$divI_7,millicode
+	.import $$divI_8,millicode
+	.import $$divI_9,millicode
+	.import $$divI_10,millicode
+	.import $$divI_12,millicode
+	.import $$divI_14,millicode
+	.import $$divI_15,millicode
+	.export $$divI,millicode
+	.export	$$divoI,millicode
+	.proc
+	.callinfo	millicode
+	.entry
+GSYM($$divoI)
+	comib,=,n  -1,arg1,LREF(negative1)	/*  when divisor == -1 */
+GSYM($$divI)
+	ldo	-1(arg1),temp		/*  is there at most one bit set ? */
+	and,<>	arg1,temp,r0		/*  if not, don't use power of 2 divide */
+	addi,>	0,arg1,r0		/*  if divisor > 0, use power of 2 divide */
+	b,n	LREF(neg_denom)
+LSYM(pow2)
+	addi,>=	0,arg0,retreg		/*  if numerator is negative, add the */
+	add	arg0,temp,retreg	/*  (denominaotr -1) to correct for shifts */
+	extru,=	arg1,15,16,temp		/*  test denominator with 0xffff0000 */
+	extrs	retreg,15,16,retreg	/*  retreg = retreg >> 16 */
+	or	arg1,temp,arg1		/*  arg1 = arg1 | (arg1 >> 16) */
+	ldi	0xcc,temp1		/*  setup 0xcc in temp1 */
+	extru,= arg1,23,8,temp		/*  test denominator with 0xff00 */
+	extrs	retreg,23,24,retreg	/*  retreg = retreg >> 8 */
+	or	arg1,temp,arg1		/*  arg1 = arg1 | (arg1 >> 8) */
+	ldi	0xaa,temp		/*  setup 0xaa in temp */
+	extru,= arg1,27,4,r0		/*  test denominator with 0xf0 */
+	extrs	retreg,27,28,retreg	/*  retreg = retreg >> 4 */
+	and,=	arg1,temp1,r0		/*  test denominator with 0xcc */
+	extrs	retreg,29,30,retreg	/*  retreg = retreg >> 2 */
+	and,=	arg1,temp,r0		/*  test denominator with 0xaa */
+	extrs	retreg,30,31,retreg	/*  retreg = retreg >> 1 */
+	MILLIRETN
+LSYM(neg_denom)
+	addi,<	0,arg1,r0		/*  if arg1 >= 0, it's not power of 2 */
+	b,n	LREF(regular_seq)
+	sub	r0,arg1,temp		/*  make denominator positive */
+	comb,=,n  arg1,temp,LREF(regular_seq)	/*  test against 0x80000000 and 0 */
+	ldo	-1(temp),retreg		/*  is there at most one bit set ? */
+	and,=	temp,retreg,r0		/*  if so, the denominator is power of 2 */
+	b,n	LREF(regular_seq)
+	sub	r0,arg0,retreg		/*  negate numerator */
+	comb,=,n arg0,retreg,LREF(regular_seq) /*  test against 0x80000000 */
+	copy	retreg,arg0		/*  set up arg0, arg1 and temp	*/
+	copy	temp,arg1		/*  before branching to pow2 */
+	b	LREF(pow2)
+	ldo	-1(arg1),temp
+LSYM(regular_seq)
+	comib,>>=,n 15,arg1,LREF(small_divisor)
+	add,>=	0,arg0,retreg		/*  move dividend, if retreg < 0, */
+LSYM(normal)
+	subi	0,retreg,retreg		/*    make it positive */
+	sub	0,arg1,temp		/*  clear carry,  */
+					/*    negate the divisor */
+	ds	0,temp,0		/*  set V-bit to the comple- */
+					/*    ment of the divisor sign */
+	add	retreg,retreg,retreg	/*  shift msb bit into carry */
+	ds	r0,arg1,temp		/*  1st divide step, if no carry */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  2nd divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  3rd divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  4th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  5th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  6th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  7th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  8th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  9th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  10th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  11th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  12th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  13th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  14th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  15th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  16th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  17th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  18th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  19th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  20th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  21st divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  22nd divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  23rd divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  24th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  25th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  26th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  27th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  28th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  29th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  30th divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  31st divide step */
+	addc	retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds	temp,arg1,temp		/*  32nd divide step, */
+	addc	retreg,retreg,retreg	/*  shift last retreg bit into retreg */
+	xor,>=	arg0,arg1,0		/*  get correct sign of quotient */
+	  sub	0,retreg,retreg		/*    based on operand signs */
+	MILLIRETN
+	nop
+
+LSYM(small_divisor)
+
+#if defined(CONFIG_64BIT)
+/*  Clear the upper 32 bits of the arg1 register.  We are working with	*/
+/*  small divisors (and 32-bit integers)   We must not be mislead  */
+/*  by "1" bits left in the upper 32 bits.  */
+	depd %r0,31,32,%r25
+#endif
+	blr,n	arg1,r0
+	nop
+/*  table for divisor == 0,1, ... ,15 */
+	addit,=	0,arg1,r0	/*  trap if divisor == 0 */
+	nop
+	MILLIRET		/*  divisor == 1 */
+	copy	arg0,retreg
+	MILLI_BEN($$divI_2)	/*  divisor == 2 */
+	nop
+	MILLI_BEN($$divI_3)	/*  divisor == 3 */
+	nop
+	MILLI_BEN($$divI_4)	/*  divisor == 4 */
+	nop
+	MILLI_BEN($$divI_5)	/*  divisor == 5 */
+	nop
+	MILLI_BEN($$divI_6)	/*  divisor == 6 */
+	nop
+	MILLI_BEN($$divI_7)	/*  divisor == 7 */
+	nop
+	MILLI_BEN($$divI_8)	/*  divisor == 8 */
+	nop
+	MILLI_BEN($$divI_9)	/*  divisor == 9 */
+	nop
+	MILLI_BEN($$divI_10)	/*  divisor == 10 */
+	nop
+	b	LREF(normal)		/*  divisor == 11 */
+	add,>=	0,arg0,retreg
+	MILLI_BEN($$divI_12)	/*  divisor == 12 */
+	nop
+	b	LREF(normal)		/*  divisor == 13 */
+	add,>=	0,arg0,retreg
+	MILLI_BEN($$divI_14)	/*  divisor == 14 */
+	nop
+	MILLI_BEN($$divI_15)	/*  divisor == 15 */
+	nop
+
+LSYM(negative1)
+	sub	0,arg0,retreg	/*  result is negation of dividend */
+	MILLIRET
+	addo	arg0,arg1,r0	/*  trap iff dividend==0x80000000 && divisor==-1 */
+	.exit
+	.procend
+	.end
+#endif
+
+#ifdef L_divU
+/* ROUTINE:	$$divU
+   .
+   .	Single precision divide for unsigned integers.
+   .
+   .	Quotient is truncated towards zero.
+   .	Traps on divide by zero.
+
+   INPUT REGISTERS:
+   .	arg0 ==	dividend
+   .	arg1 ==	divisor
+   .	mrp  == return pc
+   .	sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .	arg0 =	undefined
+   .	arg1 =	undefined
+   .	ret1 =	quotient
+
+   OTHER REGISTERS AFFECTED:
+   .	r1   =	undefined
+
+   SIDE EFFECTS:
+   .	Causes a trap under the following conditions:
+   .		divisor is zero
+   .	Changes memory at the following places:
+   .		NONE
+
+   PERMISSIBLE CONTEXT:
+   .	Unwindable.
+   .	Does not create a stack frame.
+   .	Suitable for internal or external millicode.
+   .	Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .	Branchs to other millicode routines using BE:
+   .		$$divU_# for 3,5,6,7,9,10,12,14,15
+   .
+   .	For selected small divisors calls the special divide by constant
+   .	routines written by Karl Pettis.  These are: 3,5,6,7,9,10,12,14,15.  */
+
+RDEFINE(temp,r1)
+RDEFINE(retreg,ret1)	/* r29 */
+RDEFINE(temp1,arg0)
+	SUBSPA_MILLI_DIV
+	ATTR_MILLI
+	.export $$divU,millicode
+	.import $$divU_3,millicode
+	.import $$divU_5,millicode
+	.import $$divU_6,millicode
+	.import $$divU_7,millicode
+	.import $$divU_9,millicode
+	.import $$divU_10,millicode
+	.import $$divU_12,millicode
+	.import $$divU_14,millicode
+	.import $$divU_15,millicode
+	.proc
+	.callinfo	millicode
+	.entry
+GSYM($$divU)
+/* The subtract is not nullified since it does no harm and can be used
+   by the two cases that branch back to "normal".  */
+	ldo	-1(arg1),temp		/* is there at most one bit set ? */
+	and,=	arg1,temp,r0		/* if so, denominator is power of 2 */
+	b	LREF(regular_seq)
+	addit,=	0,arg1,0		/* trap for zero dvr */
+	copy	arg0,retreg
+	extru,= arg1,15,16,temp		/* test denominator with 0xffff0000 */
+	extru	retreg,15,16,retreg	/* retreg = retreg >> 16 */
+	or	arg1,temp,arg1		/* arg1 = arg1 | (arg1 >> 16) */
+	ldi	0xcc,temp1		/* setup 0xcc in temp1 */
+	extru,= arg1,23,8,temp		/* test denominator with 0xff00 */
+	extru	retreg,23,24,retreg	/* retreg = retreg >> 8 */
+	or	arg1,temp,arg1		/* arg1 = arg1 | (arg1 >> 8) */
+	ldi	0xaa,temp		/* setup 0xaa in temp */
+	extru,= arg1,27,4,r0		/* test denominator with 0xf0 */
+	extru	retreg,27,28,retreg	/* retreg = retreg >> 4 */
+	and,=	arg1,temp1,r0		/* test denominator with 0xcc */
+	extru	retreg,29,30,retreg	/* retreg = retreg >> 2 */
+	and,=	arg1,temp,r0		/* test denominator with 0xaa */
+	extru	retreg,30,31,retreg	/* retreg = retreg >> 1 */
+	MILLIRETN
+	nop	
+LSYM(regular_seq)
+	comib,>=  15,arg1,LREF(special_divisor)
+	subi	0,arg1,temp		/* clear carry, negate the divisor */
+	ds	r0,temp,r0		/* set V-bit to 1 */
+LSYM(normal)
+	add	arg0,arg0,retreg	/* shift msb bit into carry */
+	ds	r0,arg1,temp		/* 1st divide step, if no carry */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 2nd divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 3rd divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 4th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 5th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 6th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 7th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 8th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 9th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 10th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 11th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 12th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 13th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 14th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 15th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 16th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 17th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 18th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 19th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 20th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 21st divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 22nd divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 23rd divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 24th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 25th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 26th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 27th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 28th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 29th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 30th divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 31st divide step */
+	addc	retreg,retreg,retreg	/* shift retreg with/into carry */
+	ds	temp,arg1,temp		/* 32nd divide step, */
+	MILLIRET
+	addc	retreg,retreg,retreg	/* shift last retreg bit into retreg */
+
+/* Handle the cases where divisor is a small constant or has high bit on.  */
+LSYM(special_divisor)
+/*	blr	arg1,r0 */
+/*	comib,>,n  0,arg1,LREF(big_divisor) ; nullify previous instruction */
+
+/* Pratap 8/13/90. The 815 Stirling chip set has a bug that prevents us from
+   generating such a blr, comib sequence. A problem in nullification. So I
+   rewrote this code.  */
+
+#if defined(CONFIG_64BIT)
+/* Clear the upper 32 bits of the arg1 register.  We are working with
+   small divisors (and 32-bit unsigned integers)   We must not be mislead
+   by "1" bits left in the upper 32 bits.  */
+	depd %r0,31,32,%r25
+#endif
+	comib,>	0,arg1,LREF(big_divisor)
+	nop
+	blr	arg1,r0
+	nop
+
+LSYM(zero_divisor)	/* this label is here to provide external visibility */
+	addit,=	0,arg1,0		/* trap for zero dvr */
+	nop
+	MILLIRET			/* divisor == 1 */
+	copy	arg0,retreg
+	MILLIRET			/* divisor == 2 */
+	extru	arg0,30,31,retreg
+	MILLI_BEN($$divU_3)		/* divisor == 3 */
+	nop
+	MILLIRET			/* divisor == 4 */
+	extru	arg0,29,30,retreg
+	MILLI_BEN($$divU_5)		/* divisor == 5 */
+	nop
+	MILLI_BEN($$divU_6)		/* divisor == 6 */
+	nop
+	MILLI_BEN($$divU_7)		/* divisor == 7 */
+	nop
+	MILLIRET			/* divisor == 8 */
+	extru	arg0,28,29,retreg
+	MILLI_BEN($$divU_9)		/* divisor == 9 */
+	nop
+	MILLI_BEN($$divU_10)		/* divisor == 10 */
+	nop
+	b	LREF(normal)		/* divisor == 11 */
+	ds	r0,temp,r0		/* set V-bit to 1 */
+	MILLI_BEN($$divU_12)		/* divisor == 12 */
+	nop
+	b	LREF(normal)		/* divisor == 13 */
+	ds	r0,temp,r0		/* set V-bit to 1 */
+	MILLI_BEN($$divU_14)		/* divisor == 14 */
+	nop
+	MILLI_BEN($$divU_15)		/* divisor == 15 */
+	nop
+
+/* Handle the case where the high bit is on in the divisor.
+   Compute:	if( dividend>=divisor) quotient=1; else quotient=0;
+   Note:	dividend>==divisor iff dividend-divisor does not borrow
+   and		not borrow iff carry.  */
+LSYM(big_divisor)
+	sub	arg0,arg1,r0
+	MILLIRET
+	addc	r0,r0,retreg
+	.exit
+	.procend
+	.end
+#endif
+
+#ifdef L_remI
+/* ROUTINE:	$$remI
+
+   DESCRIPTION:
+   .	$$remI returns the remainder of the division of two signed 32-bit
+   .	integers.  The sign of the remainder is the same as the sign of
+   .	the dividend.
+
+
+   INPUT REGISTERS:
+   .	arg0 == dividend
+   .	arg1 == divisor
+   .	mrp  == return pc
+   .	sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .	arg0 = destroyed
+   .	arg1 = destroyed
+   .	ret1 = remainder
+
+   OTHER REGISTERS AFFECTED:
+   .	r1   = undefined
+
+   SIDE EFFECTS:
+   .	Causes a trap under the following conditions:  DIVIDE BY ZERO
+   .	Changes memory at the following places:  NONE
+
+   PERMISSIBLE CONTEXT:
+   .	Unwindable
+   .	Does not create a stack frame
+   .	Is usable for internal or external microcode
+
+   DISCUSSION:
+   .	Calls other millicode routines via mrp:  NONE
+   .	Calls other millicode routines:  NONE  */
+
+RDEFINE(tmp,r1)
+RDEFINE(retreg,ret1)
+
+	SUBSPA_MILLI
+	ATTR_MILLI
+	.proc
+	.callinfo millicode
+	.entry
+GSYM($$remI)
+GSYM($$remoI)
+	.export $$remI,MILLICODE
+	.export $$remoI,MILLICODE
+	ldo		-1(arg1),tmp		/*  is there at most one bit set ? */
+	and,<>		arg1,tmp,r0		/*  if not, don't use power of 2 */
+	addi,>		0,arg1,r0		/*  if denominator > 0, use power */
+						/*  of 2 */
+	b,n		LREF(neg_denom)
+LSYM(pow2)
+	comb,>,n	0,arg0,LREF(neg_num)	/*  is numerator < 0 ? */
+	and		arg0,tmp,retreg		/*  get the result */
+	MILLIRETN
+LSYM(neg_num)
+	subi		0,arg0,arg0		/*  negate numerator */
+	and		arg0,tmp,retreg		/*  get the result */
+	subi		0,retreg,retreg		/*  negate result */
+	MILLIRETN
+LSYM(neg_denom)
+	addi,<		0,arg1,r0		/*  if arg1 >= 0, it's not power */
+						/*  of 2 */
+	b,n		LREF(regular_seq)
+	sub		r0,arg1,tmp		/*  make denominator positive */
+	comb,=,n	arg1,tmp,LREF(regular_seq) /*  test against 0x80000000 and 0 */
+	ldo		-1(tmp),retreg		/*  is there at most one bit set ? */
+	and,=		tmp,retreg,r0		/*  if not, go to regular_seq */
+	b,n		LREF(regular_seq)
+	comb,>,n	0,arg0,LREF(neg_num_2)	/*  if arg0 < 0, negate it  */
+	and		arg0,retreg,retreg
+	MILLIRETN
+LSYM(neg_num_2)
+	subi		0,arg0,tmp		/*  test against 0x80000000 */
+	and		tmp,retreg,retreg
+	subi		0,retreg,retreg
+	MILLIRETN
+LSYM(regular_seq)
+	addit,=		0,arg1,0		/*  trap if div by zero */
+	add,>=		0,arg0,retreg		/*  move dividend, if retreg < 0, */
+	sub		0,retreg,retreg		/*    make it positive */
+	sub		0,arg1, tmp		/*  clear carry,  */
+						/*    negate the divisor */
+	ds		0, tmp,0		/*  set V-bit to the comple- */
+						/*    ment of the divisor sign */
+	or		0,0, tmp		/*  clear  tmp */
+	add		retreg,retreg,retreg	/*  shift msb bit into carry */
+	ds		 tmp,arg1, tmp		/*  1st divide step, if no carry */
+						/*    out, msb of quotient = 0 */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+LSYM(t1)
+	ds		 tmp,arg1, tmp		/*  2nd divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  3rd divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  4th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  5th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  6th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  7th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  8th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  9th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  10th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  11th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  12th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  13th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  14th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  15th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  16th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  17th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  18th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  19th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  20th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  21st divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  22nd divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  23rd divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  24th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  25th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  26th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  27th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  28th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  29th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  30th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  31st divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  32nd divide step, */
+	addc		retreg,retreg,retreg	/*  shift last bit into retreg */
+	movb,>=,n	 tmp,retreg,LREF(finish) /*  branch if pos.  tmp */
+	add,<		arg1,0,0		/*  if arg1 > 0, add arg1 */
+	add,tr		 tmp,arg1,retreg	/*    for correcting remainder tmp */
+	sub		 tmp,arg1,retreg	/*  else add absolute value arg1 */
+LSYM(finish)
+	add,>=		arg0,0,0		/*  set sign of remainder */
+	sub		0,retreg,retreg		/*    to sign of dividend */
+	MILLIRET
+	nop
+	.exit
+	.procend
+#ifdef milliext
+	.origin 0x00000200
+#endif
+	.end
+#endif
+
+#ifdef L_remU
+/* ROUTINE:	$$remU
+   .	Single precision divide for remainder with unsigned binary integers.
+   .
+   .	The remainder must be dividend-(dividend/divisor)*divisor.
+   .	Divide by zero is trapped.
+
+   INPUT REGISTERS:
+   .	arg0 ==	dividend
+   .	arg1 == divisor
+   .	mrp  == return pc
+   .	sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .	arg0 =	undefined
+   .	arg1 =	undefined
+   .	ret1 =	remainder
+
+   OTHER REGISTERS AFFECTED:
+   .	r1   =	undefined
+
+   SIDE EFFECTS:
+   .	Causes a trap under the following conditions:  DIVIDE BY ZERO
+   .	Changes memory at the following places:  NONE
+
+   PERMISSIBLE CONTEXT:
+   .	Unwindable.
+   .	Does not create a stack frame.
+   .	Suitable for internal or external millicode.
+   .	Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .	Calls other millicode routines using mrp: NONE
+   .	Calls other millicode routines: NONE  */
+
+
+RDEFINE(temp,r1)
+RDEFINE(rmndr,ret1)	/*  r29 */
+	SUBSPA_MILLI
+	ATTR_MILLI
+	.export $$remU,millicode
+	.proc
+	.callinfo	millicode
+	.entry
+GSYM($$remU)
+	ldo	-1(arg1),temp		/*  is there at most one bit set ? */
+	and,=	arg1,temp,r0		/*  if not, don't use power of 2 */
+	b	LREF(regular_seq)
+	addit,=	0,arg1,r0		/*  trap on div by zero */
+	and	arg0,temp,rmndr		/*  get the result for power of 2 */
+	MILLIRETN
+LSYM(regular_seq)
+	comib,>=,n  0,arg1,LREF(special_case)
+	subi	0,arg1,rmndr		/*  clear carry, negate the divisor */
+	ds	r0,rmndr,r0		/*  set V-bit to 1 */
+	add	arg0,arg0,temp		/*  shift msb bit into carry */
+	ds	r0,arg1,rmndr		/*  1st divide step, if no carry */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  2nd divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  3rd divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  4th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  5th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  6th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  7th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  8th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  9th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  10th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  11th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  12th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  13th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  14th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  15th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  16th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  17th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  18th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  19th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  20th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  21st divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  22nd divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  23rd divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  24th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  25th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  26th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  27th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  28th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  29th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  30th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  31st divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  32nd divide step, */
+	comiclr,<= 0,rmndr,r0
+	  add	rmndr,arg1,rmndr	/*  correction */
+	MILLIRETN
+	nop
+
+/* Putting >= on the last DS and deleting COMICLR does not work!  */
+LSYM(special_case)
+	sub,>>=	arg0,arg1,rmndr
+	  copy	arg0,rmndr
+	MILLIRETN
+	nop
+	.exit
+	.procend
+	.end
+#endif
+
+#ifdef L_div_const
+/* ROUTINE:	$$divI_2
+   .		$$divI_3	$$divU_3
+   .		$$divI_4
+   .		$$divI_5	$$divU_5
+   .		$$divI_6	$$divU_6
+   .		$$divI_7	$$divU_7
+   .		$$divI_8
+   .		$$divI_9	$$divU_9
+   .		$$divI_10	$$divU_10
+   .
+   .		$$divI_12	$$divU_12
+   .
+   .		$$divI_14	$$divU_14
+   .		$$divI_15	$$divU_15
+   .		$$divI_16
+   .		$$divI_17	$$divU_17
+   .
+   .	Divide by selected constants for single precision binary integers.
+
+   INPUT REGISTERS:
+   .	arg0 ==	dividend
+   .	mrp  == return pc
+   .	sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .	arg0 =	undefined
+   .	arg1 =	undefined
+   .	ret1 =	quotient
+
+   OTHER REGISTERS AFFECTED:
+   .	r1   =	undefined
+
+   SIDE EFFECTS:
+   .	Causes a trap under the following conditions: NONE
+   .	Changes memory at the following places:  NONE
+
+   PERMISSIBLE CONTEXT:
+   .	Unwindable.
+   .	Does not create a stack frame.
+   .	Suitable for internal or external millicode.
+   .	Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .	Calls other millicode routines using mrp:  NONE
+   .	Calls other millicode routines:  NONE  */
+
+
+/* TRUNCATED DIVISION BY SMALL INTEGERS
+
+   We are interested in q(x) = floor(x/y), where x >= 0 and y > 0
+   (with y fixed).
+
+   Let a = floor(z/y), for some choice of z.  Note that z will be
+   chosen so that division by z is cheap.
+
+   Let r be the remainder(z/y).  In other words, r = z - ay.
+
+   Now, our method is to choose a value for b such that
+
+   q'(x) = floor((ax+b)/z)
+
+   is equal to q(x) over as large a range of x as possible.  If the
+   two are equal over a sufficiently large range, and if it is easy to
+   form the product (ax), and it is easy to divide by z, then we can
+   perform the division much faster than the general division algorithm.
+
+   So, we want the following to be true:
+
+   .	For x in the following range:
+   .
+   .	    ky <= x < (k+1)y
+   .
+   .	implies that
+   .
+   .	    k <= (ax+b)/z < (k+1)
+
+   We want to determine b such that this is true for all k in the
+   range {0..K} for some maximum K.
+
+   Since (ax+b) is an increasing function of x, we can take each
+   bound separately to determine the "best" value for b.
+
+   (ax+b)/z < (k+1)	       implies
+
+   (a((k+1)y-1)+b < (k+1)z     implies
+
+   b < a + (k+1)(z-ay)	       implies
+
+   b < a + (k+1)r
+
+   This needs to be true for all k in the range {0..K}.  In
+   particular, it is true for k = 0 and this leads to a maximum
+   acceptable value for b.
+
+   b < a+r   or   b <= a+r-1
+
+   Taking the other bound, we have
+
+   k <= (ax+b)/z	       implies
+
+   k <= (aky+b)/z	       implies
+
+   k(z-ay) <= b		       implies
+
+   kr <= b
+
+   Clearly, the largest range for k will be achieved by maximizing b,
+   when r is not zero.	When r is zero, then the simplest choice for b
+   is 0.  When r is not 0, set
+
+   .	b = a+r-1
+
+   Now, by construction, q'(x) = floor((ax+b)/z) = q(x) = floor(x/y)
+   for all x in the range:
+
+   .	0 <= x < (K+1)y
+
+   We need to determine what K is.  Of our two bounds,
+
+   .	b < a+(k+1)r	is satisfied for all k >= 0, by construction.
+
+   The other bound is
+
+   .	kr <= b
+
+   This is always true if r = 0.  If r is not 0 (the usual case), then
+   K = floor((a+r-1)/r), is the maximum value for k.
+
+   Therefore, the formula q'(x) = floor((ax+b)/z) yields the correct
+   answer for q(x) = floor(x/y) when x is in the range
+
+   (0,(K+1)y-1)	       K = floor((a+r-1)/r)
+
+   To be most useful, we want (K+1)y-1 = (max x) >= 2**32-1 so that
+   the formula for q'(x) yields the correct value of q(x) for all x
+   representable by a single word in HPPA.
+
+   We are also constrained in that computing the product (ax), adding
+   b, and dividing by z must all be done quickly, otherwise we will be
+   better off going through the general algorithm using the DS
+   instruction, which uses approximately 70 cycles.
+
+   For each y, there is a choice of z which satisfies the constraints
+   for (K+1)y >= 2**32.  We may not, however, be able to satisfy the
+   timing constraints for arbitrary y.	It seems that z being equal to
+   a power of 2 or a power of 2 minus 1 is as good as we can do, since
+   it minimizes the time to do division by z.  We want the choice of z
+   to also result in a value for (a) that minimizes the computation of
+   the product (ax).  This is best achieved if (a) has a regular bit
+   pattern (so the multiplication can be done with shifts and adds).
+   The value of (a) also needs to be less than 2**32 so the product is
+   always guaranteed to fit in 2 words.
+
+   In actual practice, the following should be done:
+
+   1) For negative x, you should take the absolute value and remember
+   .  the fact so that the result can be negated.  This obviously does
+   .  not apply in the unsigned case.
+   2) For even y, you should factor out the power of 2 that divides y
+   .  and divide x by it.  You can then proceed by dividing by the
+   .  odd factor of y.
+
+   Here is a table of some odd values of y, and corresponding choices
+   for z which are "good".
+
+    y	  z	  r	 a (hex)     max x (hex)
+
+    3	2**32	  1	55555555      100000001
+    5	2**32	  1	33333333      100000003
+    7  2**24-1	  0	  249249     (infinite)
+    9  2**24-1	  0	  1c71c7     (infinite)
+   11  2**20-1	  0	   1745d     (infinite)
+   13  2**24-1	  0	  13b13b     (infinite)
+   15	2**32	  1	11111111      10000000d
+   17	2**32	  1	 f0f0f0f      10000000f
+
+   If r is 1, then b = a+r-1 = a.  This simplifies the computation
+   of (ax+b), since you can compute (x+1)(a) instead.  If r is 0,
+   then b = 0 is ok to use which simplifies (ax+b).
+
+   The bit patterns for 55555555, 33333333, and 11111111 are obviously
+   very regular.  The bit patterns for the other values of a above are:
+
+    y	   (hex)	  (binary)
+
+    7	  249249  001001001001001001001001  << regular >>
+    9	  1c71c7  000111000111000111000111  << regular >>
+   11	   1745d  000000010111010001011101  << irregular >>
+   13	  13b13b  000100111011000100111011  << irregular >>
+
+   The bit patterns for (a) corresponding to (y) of 11 and 13 may be
+   too irregular to warrant using this method.
+
+   When z is a power of 2 minus 1, then the division by z is slightly
+   more complicated, involving an iterative solution.
+
+   The code presented here solves division by 1 through 17, except for
+   11 and 13. There are algorithms for both signed and unsigned
+   quantities given.
+
+   TIMINGS (cycles)
+
+   divisor  positive  negative	unsigned
+
+   .   1	2	   2	     2
+   .   2	4	   4	     2
+   .   3       19	  21	    19
+   .   4	4	   4	     2
+   .   5       18	  22	    19
+   .   6       19	  22	    19
+   .   8	4	   4	     2
+   .  10       18	  19	    17
+   .  12       18	  20	    18
+   .  15       16	  18	    16
+   .  16	4	   4	     2
+   .  17       16	  18	    16
+
+   Now, the algorithm for 7, 9, and 14 is an iterative one.  That is,
+   a loop body is executed until the tentative quotient is 0.  The
+   number of times the loop body is executed varies depending on the
+   dividend, but is never more than two times.	If the dividend is
+   less than the divisor, then the loop body is not executed at all.
+   Each iteration adds 4 cycles to the timings.
+
+   divisor  positive  negative	unsigned
+
+   .   7       19+4n	 20+4n	   20+4n    n = number of iterations
+   .   9       21+4n	 22+4n	   21+4n
+   .  14       21+4n	 22+4n	   20+4n
+
+   To give an idea of how the number of iterations varies, here is a
+   table of dividend versus number of iterations when dividing by 7.
+
+   smallest	 largest       required
+   dividend	dividend      iterations
+
+   .	0	     6		    0
+   .	7	 0x6ffffff	    1
+   0x1000006	0xffffffff	    2
+
+   There is some overlap in the range of numbers requiring 1 and 2
+   iterations.	*/
+
+RDEFINE(t2,r1)
+RDEFINE(x2,arg0)	/*  r26 */
+RDEFINE(t1,arg1)	/*  r25 */
+RDEFINE(x1,ret1)	/*  r29 */
+
+	SUBSPA_MILLI_DIV
+	ATTR_MILLI
+
+	.proc
+	.callinfo	millicode
+	.entry
+/* NONE of these routines require a stack frame
+   ALL of these routines are unwindable from millicode	*/
+
+GSYM($$divide_by_constant)
+	.export $$divide_by_constant,millicode
+/*  Provides a "nice" label for the code covered by the unwind descriptor
+    for things like gprof.  */
+
+/* DIVISION BY 2 (shift by 1) */
+GSYM($$divI_2)
+	.export		$$divI_2,millicode
+	comclr,>=	arg0,0,0
+	addi		1,arg0,arg0
+	MILLIRET
+	extrs		arg0,30,31,ret1
+
+
+/* DIVISION BY 4 (shift by 2) */
+GSYM($$divI_4)
+	.export		$$divI_4,millicode
+	comclr,>=	arg0,0,0
+	addi		3,arg0,arg0
+	MILLIRET
+	extrs		arg0,29,30,ret1
+
+
+/* DIVISION BY 8 (shift by 3) */
+GSYM($$divI_8)
+	.export		$$divI_8,millicode
+	comclr,>=	arg0,0,0
+	addi		7,arg0,arg0
+	MILLIRET
+	extrs		arg0,28,29,ret1
+
+/* DIVISION BY 16 (shift by 4) */
+GSYM($$divI_16)
+	.export		$$divI_16,millicode
+	comclr,>=	arg0,0,0
+	addi		15,arg0,arg0
+	MILLIRET
+	extrs		arg0,27,28,ret1
+
+/****************************************************************************
+*
+*	DIVISION BY DIVISORS OF FFFFFFFF, and powers of 2 times these
+*
+*	includes 3,5,15,17 and also 6,10,12
+*
+****************************************************************************/
+
+/* DIVISION BY 3 (use z = 2**32; a = 55555555) */
+
+GSYM($$divI_3)
+	.export		$$divI_3,millicode
+	comb,<,N	x2,0,LREF(neg3)
+
+	addi		1,x2,x2		/* this cannot overflow	*/
+	extru		x2,1,2,x1	/* multiply by 5 to get started */
+	sh2add		x2,x2,x2
+	b		LREF(pos)
+	addc		x1,0,x1
+
+LSYM(neg3)
+	subi		1,x2,x2		/* this cannot overflow	*/
+	extru		x2,1,2,x1	/* multiply by 5 to get started */
+	sh2add		x2,x2,x2
+	b		LREF(neg)
+	addc		x1,0,x1
+
+GSYM($$divU_3)
+	.export		$$divU_3,millicode
+	addi		1,x2,x2		/* this CAN overflow */
+	addc		0,0,x1
+	shd		x1,x2,30,t1	/* multiply by 5 to get started */
+	sh2add		x2,x2,x2
+	b		LREF(pos)
+	addc		x1,t1,x1
+
+/* DIVISION BY 5 (use z = 2**32; a = 33333333) */
+
+GSYM($$divI_5)
+	.export		$$divI_5,millicode
+	comb,<,N	x2,0,LREF(neg5)
+
+	addi		3,x2,t1		/* this cannot overflow	*/
+	sh1add		x2,t1,x2	/* multiply by 3 to get started */
+	b		LREF(pos)
+	addc		0,0,x1
+
+LSYM(neg5)
+	sub		0,x2,x2		/* negate x2			*/
+	addi		1,x2,x2		/* this cannot overflow	*/
+	shd		0,x2,31,x1	/* get top bit (can be 1)	*/
+	sh1add		x2,x2,x2	/* multiply by 3 to get started */
+	b		LREF(neg)
+	addc		x1,0,x1
+
+GSYM($$divU_5)
+	.export		$$divU_5,millicode
+	addi		1,x2,x2		/* this CAN overflow */
+	addc		0,0,x1
+	shd		x1,x2,31,t1	/* multiply by 3 to get started */
+	sh1add		x2,x2,x2
+	b		LREF(pos)
+	addc		t1,x1,x1
+
+/* DIVISION BY	6 (shift to divide by 2 then divide by 3) */
+GSYM($$divI_6)
+	.export		$$divI_6,millicode
+	comb,<,N	x2,0,LREF(neg6)
+	extru		x2,30,31,x2	/* divide by 2			*/
+	addi		5,x2,t1		/* compute 5*(x2+1) = 5*x2+5	*/
+	sh2add		x2,t1,x2	/* multiply by 5 to get started */
+	b		LREF(pos)
+	addc		0,0,x1
+
+LSYM(neg6)
+	subi		2,x2,x2		/* negate, divide by 2, and add 1 */
+					/* negation and adding 1 are done */
+					/* at the same time by the SUBI   */
+	extru		x2,30,31,x2
+	shd		0,x2,30,x1
+	sh2add		x2,x2,x2	/* multiply by 5 to get started */
+	b		LREF(neg)
+	addc		x1,0,x1
+
+GSYM($$divU_6)
+	.export		$$divU_6,millicode
+	extru		x2,30,31,x2	/* divide by 2 */
+	addi		1,x2,x2		/* cannot carry */
+	shd		0,x2,30,x1	/* multiply by 5 to get started */
+	sh2add		x2,x2,x2
+	b		LREF(pos)
+	addc		x1,0,x1
+
+/* DIVISION BY 10 (shift to divide by 2 then divide by 5) */
+GSYM($$divU_10)
+	.export		$$divU_10,millicode
+	extru		x2,30,31,x2	/* divide by 2 */
+	addi		3,x2,t1		/* compute 3*(x2+1) = (3*x2)+3	*/
+	sh1add		x2,t1,x2	/* multiply by 3 to get started */
+	addc		0,0,x1
+LSYM(pos)
+	shd		x1,x2,28,t1	/* multiply by 0x11 */
+	shd		x2,0,28,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+LSYM(pos_for_17)
+	shd		x1,x2,24,t1	/* multiply by 0x101 */
+	shd		x2,0,24,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+
+	shd		x1,x2,16,t1	/* multiply by 0x10001 */
+	shd		x2,0,16,t2
+	add		x2,t2,x2
+	MILLIRET
+	addc		x1,t1,x1
+
+GSYM($$divI_10)
+	.export		$$divI_10,millicode
+	comb,<		x2,0,LREF(neg10)
+	copy		0,x1
+	extru		x2,30,31,x2	/* divide by 2 */
+	addib,TR	1,x2,LREF(pos)	/* add 1 (cannot overflow)     */
+	sh1add		x2,x2,x2	/* multiply by 3 to get started */
+
+LSYM(neg10)
+	subi		2,x2,x2		/* negate, divide by 2, and add 1 */
+					/* negation and adding 1 are done */
+					/* at the same time by the SUBI   */
+	extru		x2,30,31,x2
+	sh1add		x2,x2,x2	/* multiply by 3 to get started */
+LSYM(neg)
+	shd		x1,x2,28,t1	/* multiply by 0x11 */
+	shd		x2,0,28,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+LSYM(neg_for_17)
+	shd		x1,x2,24,t1	/* multiply by 0x101 */
+	shd		x2,0,24,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+
+	shd		x1,x2,16,t1	/* multiply by 0x10001 */
+	shd		x2,0,16,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+	MILLIRET
+	sub		0,x1,x1
+
+/* DIVISION BY 12 (shift to divide by 4 then divide by 3) */
+GSYM($$divI_12)
+	.export		$$divI_12,millicode
+	comb,<		x2,0,LREF(neg12)
+	copy		0,x1
+	extru		x2,29,30,x2	/* divide by 4			*/
+	addib,tr	1,x2,LREF(pos)	/* compute 5*(x2+1) = 5*x2+5    */
+	sh2add		x2,x2,x2	/* multiply by 5 to get started */
+
+LSYM(neg12)
+	subi		4,x2,x2		/* negate, divide by 4, and add 1 */
+					/* negation and adding 1 are done */
+					/* at the same time by the SUBI   */
+	extru		x2,29,30,x2
+	b		LREF(neg)
+	sh2add		x2,x2,x2	/* multiply by 5 to get started */
+
+GSYM($$divU_12)
+	.export		$$divU_12,millicode
+	extru		x2,29,30,x2	/* divide by 4   */
+	addi		5,x2,t1		/* cannot carry */
+	sh2add		x2,t1,x2	/* multiply by 5 to get started */
+	b		LREF(pos)
+	addc		0,0,x1
+
+/* DIVISION BY 15 (use z = 2**32; a = 11111111) */
+GSYM($$divI_15)
+	.export		$$divI_15,millicode
+	comb,<		x2,0,LREF(neg15)
+	copy		0,x1
+	addib,tr	1,x2,LREF(pos)+4
+	shd		x1,x2,28,t1
+
+LSYM(neg15)
+	b		LREF(neg)
+	subi		1,x2,x2
+
+GSYM($$divU_15)
+	.export		$$divU_15,millicode
+	addi		1,x2,x2		/* this CAN overflow */
+	b		LREF(pos)
+	addc		0,0,x1
+
+/* DIVISION BY 17 (use z = 2**32; a =  f0f0f0f) */
+GSYM($$divI_17)
+	.export		$$divI_17,millicode
+	comb,<,n	x2,0,LREF(neg17)
+	addi		1,x2,x2		/* this cannot overflow */
+	shd		0,x2,28,t1	/* multiply by 0xf to get started */
+	shd		x2,0,28,t2
+	sub		t2,x2,x2
+	b		LREF(pos_for_17)
+	subb		t1,0,x1
+
+LSYM(neg17)
+	subi		1,x2,x2		/* this cannot overflow */
+	shd		0,x2,28,t1	/* multiply by 0xf to get started */
+	shd		x2,0,28,t2
+	sub		t2,x2,x2
+	b		LREF(neg_for_17)
+	subb		t1,0,x1
+
+GSYM($$divU_17)
+	.export		$$divU_17,millicode
+	addi		1,x2,x2		/* this CAN overflow */
+	addc		0,0,x1
+	shd		x1,x2,28,t1	/* multiply by 0xf to get started */
+LSYM(u17)
+	shd		x2,0,28,t2
+	sub		t2,x2,x2
+	b		LREF(pos_for_17)
+	subb		t1,x1,x1
+
+
+/* DIVISION BY DIVISORS OF FFFFFF, and powers of 2 times these
+   includes 7,9 and also 14
+
+
+   z = 2**24-1
+   r = z mod x = 0
+
+   so choose b = 0
+
+   Also, in order to divide by z = 2**24-1, we approximate by dividing
+   by (z+1) = 2**24 (which is easy), and then correcting.
+
+   (ax) = (z+1)q' + r
+   .	= zq' + (q'+r)
+
+   So to compute (ax)/z, compute q' = (ax)/(z+1) and r = (ax) mod (z+1)
+   Then the true remainder of (ax)/z is (q'+r).  Repeat the process
+   with this new remainder, adding the tentative quotients together,
+   until a tentative quotient is 0 (and then we are done).  There is
+   one last correction to be done.  It is possible that (q'+r) = z.
+   If so, then (q'+r)/(z+1) = 0 and it looks like we are done.	But,
+   in fact, we need to add 1 more to the quotient.  Now, it turns
+   out that this happens if and only if the original value x is
+   an exact multiple of y.  So, to avoid a three instruction test at
+   the end, instead use 1 instruction to add 1 to x at the beginning.  */
+
+/* DIVISION BY 7 (use z = 2**24-1; a = 249249) */
+GSYM($$divI_7)
+	.export		$$divI_7,millicode
+	comb,<,n	x2,0,LREF(neg7)
+LSYM(7)
+	addi		1,x2,x2		/* cannot overflow */
+	shd		0,x2,29,x1
+	sh3add		x2,x2,x2
+	addc		x1,0,x1
+LSYM(pos7)
+	shd		x1,x2,26,t1
+	shd		x2,0,26,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+
+	shd		x1,x2,20,t1
+	shd		x2,0,20,t2
+	add		x2,t2,x2
+	addc		x1,t1,t1
+
+	/* computed <t1,x2>.  Now divide it by (2**24 - 1)	*/
+
+	copy		0,x1
+	shd,=		t1,x2,24,t1	/* tentative quotient  */
+LSYM(1)
+	addb,tr		t1,x1,LREF(2)	/* add to previous quotient   */
+	extru		x2,31,24,x2	/* new remainder (unadjusted) */
+
+	MILLIRETN
+
+LSYM(2)
+	addb,tr		t1,x2,LREF(1)	/* adjust remainder */
+	extru,=		x2,7,8,t1	/* new quotient     */
+
+LSYM(neg7)
+	subi		1,x2,x2		/* negate x2 and add 1 */
+LSYM(8)
+	shd		0,x2,29,x1
+	sh3add		x2,x2,x2
+	addc		x1,0,x1
+
+LSYM(neg7_shift)
+	shd		x1,x2,26,t1
+	shd		x2,0,26,t2
+	add		x2,t2,x2
+	addc		x1,t1,x1
+
+	shd		x1,x2,20,t1
+	shd		x2,0,20,t2
+	add		x2,t2,x2
+	addc		x1,t1,t1
+
+	/* computed <t1,x2>.  Now divide it by (2**24 - 1)	*/
+
+	copy		0,x1
+	shd,=		t1,x2,24,t1	/* tentative quotient  */
+LSYM(3)
+	addb,tr		t1,x1,LREF(4)	/* add to previous quotient   */
+	extru		x2,31,24,x2	/* new remainder (unadjusted) */
+
+	MILLIRET
+	sub		0,x1,x1		/* negate result    */
+
+LSYM(4)
+	addb,tr		t1,x2,LREF(3)	/* adjust remainder */
+	extru,=		x2,7,8,t1	/* new quotient     */
+
+GSYM($$divU_7)
+	.export		$$divU_7,millicode
+	addi		1,x2,x2		/* can carry */
+	addc		0,0,x1
+	shd		x1,x2,29,t1
+	sh3add		x2,x2,x2
+	b		LREF(pos7)
+	addc		t1,x1,x1
+
+/* DIVISION BY 9 (use z = 2**24-1; a = 1c71c7) */
+GSYM($$divI_9)
+	.export		$$divI_9,millicode
+	comb,<,n	x2,0,LREF(neg9)
+	addi		1,x2,x2		/* cannot overflow */
+	shd		0,x2,29,t1
+	shd		x2,0,29,t2
+	sub		t2,x2,x2
+	b		LREF(pos7)
+	subb		t1,0,x1
+
+LSYM(neg9)
+	subi		1,x2,x2		/* negate and add 1 */
+	shd		0,x2,29,t1
+	shd		x2,0,29,t2
+	sub		t2,x2,x2
+	b		LREF(neg7_shift)
+	subb		t1,0,x1
+
+GSYM($$divU_9)
+	.export		$$divU_9,millicode
+	addi		1,x2,x2		/* can carry */
+	addc		0,0,x1
+	shd		x1,x2,29,t1
+	shd		x2,0,29,t2
+	sub		t2,x2,x2
+	b		LREF(pos7)
+	subb		t1,x1,x1
+
+/* DIVISION BY 14 (shift to divide by 2 then divide by 7) */
+GSYM($$divI_14)
+	.export		$$divI_14,millicode
+	comb,<,n	x2,0,LREF(neg14)
+GSYM($$divU_14)
+	.export		$$divU_14,millicode
+	b		LREF(7)		/* go to 7 case */
+	extru		x2,30,31,x2	/* divide by 2  */
+
+LSYM(neg14)
+	subi		2,x2,x2		/* negate (and add 2) */
+	b		LREF(8)
+	extru		x2,30,31,x2	/* divide by 2	      */
+	.exit
+	.procend
+	.end
+#endif
+
+#ifdef L_mulI
+/* VERSION "@(#)$$mulI $ Revision: 12.4 $ $ Date: 94/03/17 17:18:51 $" */
+/******************************************************************************
+This routine is used on PA2.0 processors when gcc -mno-fpregs is used
+
+ROUTINE:	$$mulI
+
+
+DESCRIPTION:	
+
+	$$mulI multiplies two single word integers, giving a single 
+	word result.  
+
+
+INPUT REGISTERS:
+
+	arg0 = Operand 1
+	arg1 = Operand 2
+	r31  == return pc
+	sr0  == return space when called externally 
+
+
+OUTPUT REGISTERS:
+
+	arg0 = undefined
+	arg1 = undefined
+	ret1 = result 
+
+OTHER REGISTERS AFFECTED:
+
+	r1   = undefined
+
+SIDE EFFECTS:
+
+	Causes a trap under the following conditions:  NONE
+	Changes memory at the following places:  NONE
+
+PERMISSIBLE CONTEXT:
+
+	Unwindable
+	Does not create a stack frame
+	Is usable for internal or external microcode
+
+DISCUSSION:
+
+	Calls other millicode routines via mrp:  NONE
+	Calls other millicode routines:  NONE
+
+***************************************************************************/
+
+
+#define	a0	%arg0
+#define	a1	%arg1
+#define	t0	%r1
+#define	r	%ret1
+
+#define	a0__128a0	zdep	a0,24,25,a0
+#define	a0__256a0	zdep	a0,23,24,a0
+#define	a1_ne_0_b_l0	comb,<>	a1,0,LREF(l0)
+#define	a1_ne_0_b_l1	comb,<>	a1,0,LREF(l1)
+#define	a1_ne_0_b_l2	comb,<>	a1,0,LREF(l2)
+#define	b_n_ret_t0	b,n	LREF(ret_t0)
+#define	b_e_shift	b	LREF(e_shift)
+#define	b_e_t0ma0	b	LREF(e_t0ma0)
+#define	b_e_t0		b	LREF(e_t0)
+#define	b_e_t0a0	b	LREF(e_t0a0)
+#define	b_e_t02a0	b	LREF(e_t02a0)
+#define	b_e_t04a0	b	LREF(e_t04a0)
+#define	b_e_2t0		b	LREF(e_2t0)
+#define	b_e_2t0a0	b	LREF(e_2t0a0)
+#define	b_e_2t04a0	b	LREF(e2t04a0)
+#define	b_e_3t0		b	LREF(e_3t0)
+#define	b_e_4t0		b	LREF(e_4t0)
+#define	b_e_4t0a0	b	LREF(e_4t0a0)
+#define	b_e_4t08a0	b	LREF(e4t08a0)
+#define	b_e_5t0		b	LREF(e_5t0)
+#define	b_e_8t0		b	LREF(e_8t0)
+#define	b_e_8t0a0	b	LREF(e_8t0a0)
+#define	r__r_a0		add	r,a0,r
+#define	r__r_2a0	sh1add	a0,r,r
+#define	r__r_4a0	sh2add	a0,r,r
+#define	r__r_8a0	sh3add	a0,r,r
+#define	r__r_t0		add	r,t0,r
+#define	r__r_2t0	sh1add	t0,r,r
+#define	r__r_4t0	sh2add	t0,r,r
+#define	r__r_8t0	sh3add	t0,r,r
+#define	t0__3a0		sh1add	a0,a0,t0
+#define	t0__4a0		sh2add	a0,0,t0
+#define	t0__5a0		sh2add	a0,a0,t0
+#define	t0__8a0		sh3add	a0,0,t0
+#define	t0__9a0		sh3add	a0,a0,t0
+#define	t0__16a0	zdep	a0,27,28,t0
+#define	t0__32a0	zdep	a0,26,27,t0
+#define	t0__64a0	zdep	a0,25,26,t0
+#define	t0__128a0	zdep	a0,24,25,t0
+#define	t0__t0ma0	sub	t0,a0,t0
+#define	t0__t0_a0	add	t0,a0,t0
+#define	t0__t0_2a0	sh1add	a0,t0,t0
+#define	t0__t0_4a0	sh2add	a0,t0,t0
+#define	t0__t0_8a0	sh3add	a0,t0,t0
+#define	t0__2t0_a0	sh1add	t0,a0,t0
+#define	t0__3t0		sh1add	t0,t0,t0
+#define	t0__4t0		sh2add	t0,0,t0
+#define	t0__4t0_a0	sh2add	t0,a0,t0
+#define	t0__5t0		sh2add	t0,t0,t0
+#define	t0__8t0		sh3add	t0,0,t0
+#define	t0__8t0_a0	sh3add	t0,a0,t0
+#define	t0__9t0		sh3add	t0,t0,t0
+#define	t0__16t0	zdep	t0,27,28,t0
+#define	t0__32t0	zdep	t0,26,27,t0
+#define	t0__256a0	zdep	a0,23,24,t0
+
+
+	SUBSPA_MILLI
+	ATTR_MILLI
+	.align 16
+	.proc
+	.callinfo millicode
+	.export $$mulI,millicode
+GSYM($$mulI)	
+	combt,<<=	a1,a0,LREF(l4)	/* swap args if unsigned a1>a0 */
+	copy		0,r		/* zero out the result */
+	xor		a0,a1,a0	/* swap a0 & a1 using the */
+	xor		a0,a1,a1	/*  old xor trick */
+	xor		a0,a1,a0
+LSYM(l4)
+	combt,<=	0,a0,LREF(l3)		/* if a0>=0 then proceed like unsigned */
+	zdep		a1,30,8,t0	/* t0 = (a1&0xff)<<1 ********* */
+	sub,>		0,a1,t0		/* otherwise negate both and */
+	combt,<=,n	a0,t0,LREF(l2)	/*  swap back if |a0|<|a1| */
+	sub		0,a0,a1
+	movb,tr,n	t0,a0,LREF(l2)	/* 10th inst.  */
+
+LSYM(l0)	r__r_t0				/* add in this partial product */
+LSYM(l1)	a0__256a0			/* a0 <<= 8 ****************** */
+LSYM(l2)	zdep		a1,30,8,t0	/* t0 = (a1&0xff)<<1 ********* */
+LSYM(l3)	blr		t0,0		/* case on these 8 bits ****** */
+		extru		a1,23,24,a1	/* a1 >>= 8 ****************** */
+
+/*16 insts before this.  */
+/*			  a0 <<= 8 ************************** */
+LSYM(x0)	a1_ne_0_b_l2	! a0__256a0	! MILLIRETN	! nop
+LSYM(x1)	a1_ne_0_b_l1	! r__r_a0	! MILLIRETN	! nop
+LSYM(x2)	a1_ne_0_b_l1	! r__r_2a0	! MILLIRETN	! nop
+LSYM(x3)	a1_ne_0_b_l0	! t0__3a0	! MILLIRET	! r__r_t0
+LSYM(x4)	a1_ne_0_b_l1	! r__r_4a0	! MILLIRETN	! nop
+LSYM(x5)	a1_ne_0_b_l0	! t0__5a0	! MILLIRET	! r__r_t0
+LSYM(x6)	t0__3a0		! a1_ne_0_b_l1	! r__r_2t0	! MILLIRETN
+LSYM(x7)	t0__3a0		! a1_ne_0_b_l0	! r__r_4a0	! b_n_ret_t0
+LSYM(x8)	a1_ne_0_b_l1	! r__r_8a0	! MILLIRETN	! nop
+LSYM(x9)	a1_ne_0_b_l0	! t0__9a0	! MILLIRET	! r__r_t0
+LSYM(x10)	t0__5a0		! a1_ne_0_b_l1	! r__r_2t0	! MILLIRETN
+LSYM(x11)	t0__3a0		! a1_ne_0_b_l0	! r__r_8a0	! b_n_ret_t0
+LSYM(x12)	t0__3a0		! a1_ne_0_b_l1	! r__r_4t0	! MILLIRETN
+LSYM(x13)	t0__5a0		! a1_ne_0_b_l0	! r__r_8a0	! b_n_ret_t0
+LSYM(x14)	t0__3a0		! t0__2t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x15)	t0__5a0		! a1_ne_0_b_l0	! t0__3t0	! b_n_ret_t0
+LSYM(x16)	t0__16a0	! a1_ne_0_b_l1	! r__r_t0	! MILLIRETN
+LSYM(x17)	t0__9a0		! a1_ne_0_b_l0	! t0__t0_8a0	! b_n_ret_t0
+LSYM(x18)	t0__9a0		! a1_ne_0_b_l1	! r__r_2t0	! MILLIRETN
+LSYM(x19)	t0__9a0		! a1_ne_0_b_l0	! t0__2t0_a0	! b_n_ret_t0
+LSYM(x20)	t0__5a0		! a1_ne_0_b_l1	! r__r_4t0	! MILLIRETN
+LSYM(x21)	t0__5a0		! a1_ne_0_b_l0	! t0__4t0_a0	! b_n_ret_t0
+LSYM(x22)	t0__5a0		! t0__2t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x23)	t0__5a0		! t0__2t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x24)	t0__3a0		! a1_ne_0_b_l1	! r__r_8t0	! MILLIRETN
+LSYM(x25)	t0__5a0		! a1_ne_0_b_l0	! t0__5t0	! b_n_ret_t0
+LSYM(x26)	t0__3a0		! t0__4t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x27)	t0__3a0		! a1_ne_0_b_l0	! t0__9t0	! b_n_ret_t0
+LSYM(x28)	t0__3a0		! t0__2t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x29)	t0__3a0		! t0__2t0_a0	! b_e_t0	! t0__4t0_a0
+LSYM(x30)	t0__5a0		! t0__3t0	! b_e_shift	! r__r_2t0
+LSYM(x31)	t0__32a0	! a1_ne_0_b_l0	! t0__t0ma0	! b_n_ret_t0
+LSYM(x32)	t0__32a0	! a1_ne_0_b_l1	! r__r_t0	! MILLIRETN
+LSYM(x33)	t0__8a0		! a1_ne_0_b_l0	! t0__4t0_a0	! b_n_ret_t0
+LSYM(x34)	t0__16a0	! t0__t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x35)	t0__9a0		! t0__3t0	! b_e_t0	! t0__t0_8a0
+LSYM(x36)	t0__9a0		! a1_ne_0_b_l1	! r__r_4t0	! MILLIRETN
+LSYM(x37)	t0__9a0		! a1_ne_0_b_l0	! t0__4t0_a0	! b_n_ret_t0
+LSYM(x38)	t0__9a0		! t0__2t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x39)	t0__9a0		! t0__2t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x40)	t0__5a0		! a1_ne_0_b_l1	! r__r_8t0	! MILLIRETN
+LSYM(x41)	t0__5a0		! a1_ne_0_b_l0	! t0__8t0_a0	! b_n_ret_t0
+LSYM(x42)	t0__5a0		! t0__4t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x43)	t0__5a0		! t0__4t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x44)	t0__5a0		! t0__2t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x45)	t0__9a0		! a1_ne_0_b_l0	! t0__5t0	! b_n_ret_t0
+LSYM(x46)	t0__9a0		! t0__5t0	! b_e_t0	! t0__t0_a0
+LSYM(x47)	t0__9a0		! t0__5t0	! b_e_t0	! t0__t0_2a0
+LSYM(x48)	t0__3a0		! a1_ne_0_b_l0	! t0__16t0	! b_n_ret_t0
+LSYM(x49)	t0__9a0		! t0__5t0	! b_e_t0	! t0__t0_4a0
+LSYM(x50)	t0__5a0		! t0__5t0	! b_e_shift	! r__r_2t0
+LSYM(x51)	t0__9a0		! t0__t0_8a0	! b_e_t0	! t0__3t0
+LSYM(x52)	t0__3a0		! t0__4t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x53)	t0__3a0		! t0__4t0_a0	! b_e_t0	! t0__4t0_a0
+LSYM(x54)	t0__9a0		! t0__3t0	! b_e_shift	! r__r_2t0
+LSYM(x55)	t0__9a0		! t0__3t0	! b_e_t0	! t0__2t0_a0
+LSYM(x56)	t0__3a0		! t0__2t0_a0	! b_e_shift	! r__r_8t0
+LSYM(x57)	t0__9a0		! t0__2t0_a0	! b_e_t0	! t0__3t0
+LSYM(x58)	t0__3a0		! t0__2t0_a0	! b_e_2t0	! t0__4t0_a0
+LSYM(x59)	t0__9a0		! t0__2t0_a0	! b_e_t02a0	! t0__3t0
+LSYM(x60)	t0__5a0		! t0__3t0	! b_e_shift	! r__r_4t0
+LSYM(x61)	t0__5a0		! t0__3t0	! b_e_t0	! t0__4t0_a0
+LSYM(x62)	t0__32a0	! t0__t0ma0	! b_e_shift	! r__r_2t0
+LSYM(x63)	t0__64a0	! a1_ne_0_b_l0	! t0__t0ma0	! b_n_ret_t0
+LSYM(x64)	t0__64a0	! a1_ne_0_b_l1	! r__r_t0	! MILLIRETN
+LSYM(x65)	t0__8a0		! a1_ne_0_b_l0	! t0__8t0_a0	! b_n_ret_t0
+LSYM(x66)	t0__32a0	! t0__t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x67)	t0__8a0		! t0__4t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x68)	t0__8a0		! t0__2t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x69)	t0__8a0		! t0__2t0_a0	! b_e_t0	! t0__4t0_a0
+LSYM(x70)	t0__64a0	! t0__t0_4a0	! b_e_t0	! t0__t0_2a0
+LSYM(x71)	t0__9a0		! t0__8t0	! b_e_t0	! t0__t0ma0
+LSYM(x72)	t0__9a0		! a1_ne_0_b_l1	! r__r_8t0	! MILLIRETN
+LSYM(x73)	t0__9a0		! t0__8t0_a0	! b_e_shift	! r__r_t0
+LSYM(x74)	t0__9a0		! t0__4t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x75)	t0__9a0		! t0__4t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x76)	t0__9a0		! t0__2t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x77)	t0__9a0		! t0__2t0_a0	! b_e_t0	! t0__4t0_a0
+LSYM(x78)	t0__9a0		! t0__2t0_a0	! b_e_2t0	! t0__2t0_a0
+LSYM(x79)	t0__16a0	! t0__5t0	! b_e_t0	! t0__t0ma0
+LSYM(x80)	t0__16a0	! t0__5t0	! b_e_shift	! r__r_t0
+LSYM(x81)	t0__9a0		! t0__9t0	! b_e_shift	! r__r_t0
+LSYM(x82)	t0__5a0		! t0__8t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x83)	t0__5a0		! t0__8t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x84)	t0__5a0		! t0__4t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x85)	t0__8a0		! t0__2t0_a0	! b_e_t0	! t0__5t0
+LSYM(x86)	t0__5a0		! t0__4t0_a0	! b_e_2t0	! t0__2t0_a0
+LSYM(x87)	t0__9a0		! t0__9t0	! b_e_t02a0	! t0__t0_4a0
+LSYM(x88)	t0__5a0		! t0__2t0_a0	! b_e_shift	! r__r_8t0
+LSYM(x89)	t0__5a0		! t0__2t0_a0	! b_e_t0	! t0__8t0_a0
+LSYM(x90)	t0__9a0		! t0__5t0	! b_e_shift	! r__r_2t0
+LSYM(x91)	t0__9a0		! t0__5t0	! b_e_t0	! t0__2t0_a0
+LSYM(x92)	t0__5a0		! t0__2t0_a0	! b_e_4t0	! t0__2t0_a0
+LSYM(x93)	t0__32a0	! t0__t0ma0	! b_e_t0	! t0__3t0
+LSYM(x94)	t0__9a0		! t0__5t0	! b_e_2t0	! t0__t0_2a0
+LSYM(x95)	t0__9a0		! t0__2t0_a0	! b_e_t0	! t0__5t0
+LSYM(x96)	t0__8a0		! t0__3t0	! b_e_shift	! r__r_4t0
+LSYM(x97)	t0__8a0		! t0__3t0	! b_e_t0	! t0__4t0_a0
+LSYM(x98)	t0__32a0	! t0__3t0	! b_e_t0	! t0__t0_2a0
+LSYM(x99)	t0__8a0		! t0__4t0_a0	! b_e_t0	! t0__3t0
+LSYM(x100)	t0__5a0		! t0__5t0	! b_e_shift	! r__r_4t0
+LSYM(x101)	t0__5a0		! t0__5t0	! b_e_t0	! t0__4t0_a0
+LSYM(x102)	t0__32a0	! t0__t0_2a0	! b_e_t0	! t0__3t0
+LSYM(x103)	t0__5a0		! t0__5t0	! b_e_t02a0	! t0__4t0_a0
+LSYM(x104)	t0__3a0		! t0__4t0_a0	! b_e_shift	! r__r_8t0
+LSYM(x105)	t0__5a0		! t0__4t0_a0	! b_e_t0	! t0__5t0
+LSYM(x106)	t0__3a0		! t0__4t0_a0	! b_e_2t0	! t0__4t0_a0
+LSYM(x107)	t0__9a0		! t0__t0_4a0	! b_e_t02a0	! t0__8t0_a0
+LSYM(x108)	t0__9a0		! t0__3t0	! b_e_shift	! r__r_4t0
+LSYM(x109)	t0__9a0		! t0__3t0	! b_e_t0	! t0__4t0_a0
+LSYM(x110)	t0__9a0		! t0__3t0	! b_e_2t0	! t0__2t0_a0
+LSYM(x111)	t0__9a0		! t0__4t0_a0	! b_e_t0	! t0__3t0
+LSYM(x112)	t0__3a0		! t0__2t0_a0	! b_e_t0	! t0__16t0
+LSYM(x113)	t0__9a0		! t0__4t0_a0	! b_e_t02a0	! t0__3t0
+LSYM(x114)	t0__9a0		! t0__2t0_a0	! b_e_2t0	! t0__3t0
+LSYM(x115)	t0__9a0		! t0__2t0_a0	! b_e_2t0a0	! t0__3t0
+LSYM(x116)	t0__3a0		! t0__2t0_a0	! b_e_4t0	! t0__4t0_a0
+LSYM(x117)	t0__3a0		! t0__4t0_a0	! b_e_t0	! t0__9t0
+LSYM(x118)	t0__3a0		! t0__4t0_a0	! b_e_t0a0	! t0__9t0
+LSYM(x119)	t0__3a0		! t0__4t0_a0	! b_e_t02a0	! t0__9t0
+LSYM(x120)	t0__5a0		! t0__3t0	! b_e_shift	! r__r_8t0
+LSYM(x121)	t0__5a0		! t0__3t0	! b_e_t0	! t0__8t0_a0
+LSYM(x122)	t0__5a0		! t0__3t0	! b_e_2t0	! t0__4t0_a0
+LSYM(x123)	t0__5a0		! t0__8t0_a0	! b_e_t0	! t0__3t0
+LSYM(x124)	t0__32a0	! t0__t0ma0	! b_e_shift	! r__r_4t0
+LSYM(x125)	t0__5a0		! t0__5t0	! b_e_t0	! t0__5t0
+LSYM(x126)	t0__64a0	! t0__t0ma0	! b_e_shift	! r__r_2t0
+LSYM(x127)	t0__128a0	! a1_ne_0_b_l0	! t0__t0ma0	! b_n_ret_t0
+LSYM(x128)	t0__128a0	! a1_ne_0_b_l1	! r__r_t0	! MILLIRETN
+LSYM(x129)	t0__128a0	! a1_ne_0_b_l0	! t0__t0_a0	! b_n_ret_t0
+LSYM(x130)	t0__64a0	! t0__t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x131)	t0__8a0		! t0__8t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x132)	t0__8a0		! t0__4t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x133)	t0__8a0		! t0__4t0_a0	! b_e_t0	! t0__4t0_a0
+LSYM(x134)	t0__8a0		! t0__4t0_a0	! b_e_2t0	! t0__2t0_a0
+LSYM(x135)	t0__9a0		! t0__5t0	! b_e_t0	! t0__3t0
+LSYM(x136)	t0__8a0		! t0__2t0_a0	! b_e_shift	! r__r_8t0
+LSYM(x137)	t0__8a0		! t0__2t0_a0	! b_e_t0	! t0__8t0_a0
+LSYM(x138)	t0__8a0		! t0__2t0_a0	! b_e_2t0	! t0__4t0_a0
+LSYM(x139)	t0__8a0		! t0__2t0_a0	! b_e_2t0a0	! t0__4t0_a0
+LSYM(x140)	t0__3a0		! t0__2t0_a0	! b_e_4t0	! t0__5t0
+LSYM(x141)	t0__8a0		! t0__2t0_a0	! b_e_4t0a0	! t0__2t0_a0
+LSYM(x142)	t0__9a0		! t0__8t0	! b_e_2t0	! t0__t0ma0
+LSYM(x143)	t0__16a0	! t0__9t0	! b_e_t0	! t0__t0ma0
+LSYM(x144)	t0__9a0		! t0__8t0	! b_e_shift	! r__r_2t0
+LSYM(x145)	t0__9a0		! t0__8t0	! b_e_t0	! t0__2t0_a0
+LSYM(x146)	t0__9a0		! t0__8t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x147)	t0__9a0		! t0__8t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x148)	t0__9a0		! t0__4t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x149)	t0__9a0		! t0__4t0_a0	! b_e_t0	! t0__4t0_a0
+LSYM(x150)	t0__9a0		! t0__4t0_a0	! b_e_2t0	! t0__2t0_a0
+LSYM(x151)	t0__9a0		! t0__4t0_a0	! b_e_2t0a0	! t0__2t0_a0
+LSYM(x152)	t0__9a0		! t0__2t0_a0	! b_e_shift	! r__r_8t0
+LSYM(x153)	t0__9a0		! t0__2t0_a0	! b_e_t0	! t0__8t0_a0
+LSYM(x154)	t0__9a0		! t0__2t0_a0	! b_e_2t0	! t0__4t0_a0
+LSYM(x155)	t0__32a0	! t0__t0ma0	! b_e_t0	! t0__5t0
+LSYM(x156)	t0__9a0		! t0__2t0_a0	! b_e_4t0	! t0__2t0_a0
+LSYM(x157)	t0__32a0	! t0__t0ma0	! b_e_t02a0	! t0__5t0
+LSYM(x158)	t0__16a0	! t0__5t0	! b_e_2t0	! t0__t0ma0
+LSYM(x159)	t0__32a0	! t0__5t0	! b_e_t0	! t0__t0ma0
+LSYM(x160)	t0__5a0		! t0__4t0	! b_e_shift	! r__r_8t0
+LSYM(x161)	t0__8a0		! t0__5t0	! b_e_t0	! t0__4t0_a0
+LSYM(x162)	t0__9a0		! t0__9t0	! b_e_shift	! r__r_2t0
+LSYM(x163)	t0__9a0		! t0__9t0	! b_e_t0	! t0__2t0_a0
+LSYM(x164)	t0__5a0		! t0__8t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x165)	t0__8a0		! t0__4t0_a0	! b_e_t0	! t0__5t0
+LSYM(x166)	t0__5a0		! t0__8t0_a0	! b_e_2t0	! t0__2t0_a0
+LSYM(x167)	t0__5a0		! t0__8t0_a0	! b_e_2t0a0	! t0__2t0_a0
+LSYM(x168)	t0__5a0		! t0__4t0_a0	! b_e_shift	! r__r_8t0
+LSYM(x169)	t0__5a0		! t0__4t0_a0	! b_e_t0	! t0__8t0_a0
+LSYM(x170)	t0__32a0	! t0__t0_2a0	! b_e_t0	! t0__5t0
+LSYM(x171)	t0__9a0		! t0__2t0_a0	! b_e_t0	! t0__9t0
+LSYM(x172)	t0__5a0		! t0__4t0_a0	! b_e_4t0	! t0__2t0_a0
+LSYM(x173)	t0__9a0		! t0__2t0_a0	! b_e_t02a0	! t0__9t0
+LSYM(x174)	t0__32a0	! t0__t0_2a0	! b_e_t04a0	! t0__5t0
+LSYM(x175)	t0__8a0		! t0__2t0_a0	! b_e_5t0	! t0__2t0_a0
+LSYM(x176)	t0__5a0		! t0__4t0_a0	! b_e_8t0	! t0__t0_a0
+LSYM(x177)	t0__5a0		! t0__4t0_a0	! b_e_8t0a0	! t0__t0_a0
+LSYM(x178)	t0__5a0		! t0__2t0_a0	! b_e_2t0	! t0__8t0_a0
+LSYM(x179)	t0__5a0		! t0__2t0_a0	! b_e_2t0a0	! t0__8t0_a0
+LSYM(x180)	t0__9a0		! t0__5t0	! b_e_shift	! r__r_4t0
+LSYM(x181)	t0__9a0		! t0__5t0	! b_e_t0	! t0__4t0_a0
+LSYM(x182)	t0__9a0		! t0__5t0	! b_e_2t0	! t0__2t0_a0
+LSYM(x183)	t0__9a0		! t0__5t0	! b_e_2t0a0	! t0__2t0_a0
+LSYM(x184)	t0__5a0		! t0__9t0	! b_e_4t0	! t0__t0_a0
+LSYM(x185)	t0__9a0		! t0__4t0_a0	! b_e_t0	! t0__5t0
+LSYM(x186)	t0__32a0	! t0__t0ma0	! b_e_2t0	! t0__3t0
+LSYM(x187)	t0__9a0		! t0__4t0_a0	! b_e_t02a0	! t0__5t0
+LSYM(x188)	t0__9a0		! t0__5t0	! b_e_4t0	! t0__t0_2a0
+LSYM(x189)	t0__5a0		! t0__4t0_a0	! b_e_t0	! t0__9t0
+LSYM(x190)	t0__9a0		! t0__2t0_a0	! b_e_2t0	! t0__5t0
+LSYM(x191)	t0__64a0	! t0__3t0	! b_e_t0	! t0__t0ma0
+LSYM(x192)	t0__8a0		! t0__3t0	! b_e_shift	! r__r_8t0
+LSYM(x193)	t0__8a0		! t0__3t0	! b_e_t0	! t0__8t0_a0
+LSYM(x194)	t0__8a0		! t0__3t0	! b_e_2t0	! t0__4t0_a0
+LSYM(x195)	t0__8a0		! t0__8t0_a0	! b_e_t0	! t0__3t0
+LSYM(x196)	t0__8a0		! t0__3t0	! b_e_4t0	! t0__2t0_a0
+LSYM(x197)	t0__8a0		! t0__3t0	! b_e_4t0a0	! t0__2t0_a0
+LSYM(x198)	t0__64a0	! t0__t0_2a0	! b_e_t0	! t0__3t0
+LSYM(x199)	t0__8a0		! t0__4t0_a0	! b_e_2t0a0	! t0__3t0
+LSYM(x200)	t0__5a0		! t0__5t0	! b_e_shift	! r__r_8t0
+LSYM(x201)	t0__5a0		! t0__5t0	! b_e_t0	! t0__8t0_a0
+LSYM(x202)	t0__5a0		! t0__5t0	! b_e_2t0	! t0__4t0_a0
+LSYM(x203)	t0__5a0		! t0__5t0	! b_e_2t0a0	! t0__4t0_a0
+LSYM(x204)	t0__8a0		! t0__2t0_a0	! b_e_4t0	! t0__3t0
+LSYM(x205)	t0__5a0		! t0__8t0_a0	! b_e_t0	! t0__5t0
+LSYM(x206)	t0__64a0	! t0__t0_4a0	! b_e_t02a0	! t0__3t0
+LSYM(x207)	t0__8a0		! t0__2t0_a0	! b_e_3t0	! t0__4t0_a0
+LSYM(x208)	t0__5a0		! t0__5t0	! b_e_8t0	! t0__t0_a0
+LSYM(x209)	t0__5a0		! t0__5t0	! b_e_8t0a0	! t0__t0_a0
+LSYM(x210)	t0__5a0		! t0__4t0_a0	! b_e_2t0	! t0__5t0
+LSYM(x211)	t0__5a0		! t0__4t0_a0	! b_e_2t0a0	! t0__5t0
+LSYM(x212)	t0__3a0		! t0__4t0_a0	! b_e_4t0	! t0__4t0_a0
+LSYM(x213)	t0__3a0		! t0__4t0_a0	! b_e_4t0a0	! t0__4t0_a0
+LSYM(x214)	t0__9a0		! t0__t0_4a0	! b_e_2t04a0	! t0__8t0_a0
+LSYM(x215)	t0__5a0		! t0__4t0_a0	! b_e_5t0	! t0__2t0_a0
+LSYM(x216)	t0__9a0		! t0__3t0	! b_e_shift	! r__r_8t0
+LSYM(x217)	t0__9a0		! t0__3t0	! b_e_t0	! t0__8t0_a0
+LSYM(x218)	t0__9a0		! t0__3t0	! b_e_2t0	! t0__4t0_a0
+LSYM(x219)	t0__9a0		! t0__8t0_a0	! b_e_t0	! t0__3t0
+LSYM(x220)	t0__3a0		! t0__9t0	! b_e_4t0	! t0__2t0_a0
+LSYM(x221)	t0__3a0		! t0__9t0	! b_e_4t0a0	! t0__2t0_a0
+LSYM(x222)	t0__9a0		! t0__4t0_a0	! b_e_2t0	! t0__3t0
+LSYM(x223)	t0__9a0		! t0__4t0_a0	! b_e_2t0a0	! t0__3t0
+LSYM(x224)	t0__9a0		! t0__3t0	! b_e_8t0	! t0__t0_a0
+LSYM(x225)	t0__9a0		! t0__5t0	! b_e_t0	! t0__5t0
+LSYM(x226)	t0__3a0		! t0__2t0_a0	! b_e_t02a0	! t0__32t0
+LSYM(x227)	t0__9a0		! t0__5t0	! b_e_t02a0	! t0__5t0
+LSYM(x228)	t0__9a0		! t0__2t0_a0	! b_e_4t0	! t0__3t0
+LSYM(x229)	t0__9a0		! t0__2t0_a0	! b_e_4t0a0	! t0__3t0
+LSYM(x230)	t0__9a0		! t0__5t0	! b_e_5t0	! t0__t0_a0
+LSYM(x231)	t0__9a0		! t0__2t0_a0	! b_e_3t0	! t0__4t0_a0
+LSYM(x232)	t0__3a0		! t0__2t0_a0	! b_e_8t0	! t0__4t0_a0
+LSYM(x233)	t0__3a0		! t0__2t0_a0	! b_e_8t0a0	! t0__4t0_a0
+LSYM(x234)	t0__3a0		! t0__4t0_a0	! b_e_2t0	! t0__9t0
+LSYM(x235)	t0__3a0		! t0__4t0_a0	! b_e_2t0a0	! t0__9t0
+LSYM(x236)	t0__9a0		! t0__2t0_a0	! b_e_4t08a0	! t0__3t0
+LSYM(x237)	t0__16a0	! t0__5t0	! b_e_3t0	! t0__t0ma0
+LSYM(x238)	t0__3a0		! t0__4t0_a0	! b_e_2t04a0	! t0__9t0
+LSYM(x239)	t0__16a0	! t0__5t0	! b_e_t0ma0	! t0__3t0
+LSYM(x240)	t0__9a0		! t0__t0_a0	! b_e_8t0	! t0__3t0
+LSYM(x241)	t0__9a0		! t0__t0_a0	! b_e_8t0a0	! t0__3t0
+LSYM(x242)	t0__5a0		! t0__3t0	! b_e_2t0	! t0__8t0_a0
+LSYM(x243)	t0__9a0		! t0__9t0	! b_e_t0	! t0__3t0
+LSYM(x244)	t0__5a0		! t0__3t0	! b_e_4t0	! t0__4t0_a0
+LSYM(x245)	t0__8a0		! t0__3t0	! b_e_5t0	! t0__2t0_a0
+LSYM(x246)	t0__5a0		! t0__8t0_a0	! b_e_2t0	! t0__3t0
+LSYM(x247)	t0__5a0		! t0__8t0_a0	! b_e_2t0a0	! t0__3t0
+LSYM(x248)	t0__32a0	! t0__t0ma0	! b_e_shift	! r__r_8t0
+LSYM(x249)	t0__32a0	! t0__t0ma0	! b_e_t0	! t0__8t0_a0
+LSYM(x250)	t0__5a0		! t0__5t0	! b_e_2t0	! t0__5t0
+LSYM(x251)	t0__5a0		! t0__5t0	! b_e_2t0a0	! t0__5t0
+LSYM(x252)	t0__64a0	! t0__t0ma0	! b_e_shift	! r__r_4t0
+LSYM(x253)	t0__64a0	! t0__t0ma0	! b_e_t0	! t0__4t0_a0
+LSYM(x254)	t0__128a0	! t0__t0ma0	! b_e_shift	! r__r_2t0
+LSYM(x255)	t0__256a0	! a1_ne_0_b_l0	! t0__t0ma0	! b_n_ret_t0
+/*1040 insts before this.  */
+LSYM(ret_t0)	MILLIRET
+LSYM(e_t0)	r__r_t0
+LSYM(e_shift)	a1_ne_0_b_l2
+	a0__256a0	/* a0 <<= 8 *********** */
+	MILLIRETN
+LSYM(e_t0ma0)	a1_ne_0_b_l0
+	t0__t0ma0
+	MILLIRET
+	r__r_t0
+LSYM(e_t0a0)	a1_ne_0_b_l0
+	t0__t0_a0
+	MILLIRET
+	r__r_t0
+LSYM(e_t02a0)	a1_ne_0_b_l0
+	t0__t0_2a0
+	MILLIRET
+	r__r_t0
+LSYM(e_t04a0)	a1_ne_0_b_l0
+	t0__t0_4a0
+	MILLIRET
+	r__r_t0
+LSYM(e_2t0)	a1_ne_0_b_l1
+	r__r_2t0
+	MILLIRETN
+LSYM(e_2t0a0)	a1_ne_0_b_l0
+	t0__2t0_a0
+	MILLIRET
+	r__r_t0
+LSYM(e2t04a0)	t0__t0_2a0
+	a1_ne_0_b_l1
+	r__r_2t0
+	MILLIRETN
+LSYM(e_3t0)	a1_ne_0_b_l0
+	t0__3t0
+	MILLIRET
+	r__r_t0
+LSYM(e_4t0)	a1_ne_0_b_l1
+	r__r_4t0
+	MILLIRETN
+LSYM(e_4t0a0)	a1_ne_0_b_l0
+	t0__4t0_a0
+	MILLIRET
+	r__r_t0
+LSYM(e4t08a0)	t0__t0_2a0
+	a1_ne_0_b_l1
+	r__r_4t0
+	MILLIRETN
+LSYM(e_5t0)	a1_ne_0_b_l0
+	t0__5t0
+	MILLIRET
+	r__r_t0
+LSYM(e_8t0)	a1_ne_0_b_l1
+	r__r_8t0
+	MILLIRETN
+LSYM(e_8t0a0)	a1_ne_0_b_l0
+	t0__8t0_a0
+	MILLIRET
+	r__r_t0
+
+	.procend
+	.end
+#endif
diff --git a/arch/parisc/lib/milli/milli.h b/arch/parisc/lib/milli/milli.h
new file mode 100644
index 0000000..19ac79f
--- /dev/null
+++ b/arch/parisc/lib/milli/milli.h
@@ -0,0 +1,165 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#ifndef _PA_MILLI_H_
+#define _PA_MILLI_H_
+
+#define L_dyncall
+#define L_divI
+#define L_divU
+#define L_remI
+#define L_remU
+#define L_div_const
+#define L_mulI
+
+#ifdef CONFIG_64BIT
+        .level  2.0w
+#endif
+
+/* Hardware General Registers.  */
+r0:	.reg	%r0
+r1:	.reg	%r1
+r2:	.reg	%r2
+r3:	.reg	%r3
+r4:	.reg	%r4
+r5:	.reg	%r5
+r6:	.reg	%r6
+r7:	.reg	%r7
+r8:	.reg	%r8
+r9:	.reg	%r9
+r10:	.reg	%r10
+r11:	.reg	%r11
+r12:	.reg	%r12
+r13:	.reg	%r13
+r14:	.reg	%r14
+r15:	.reg	%r15
+r16:	.reg	%r16
+r17:	.reg	%r17
+r18:	.reg	%r18
+r19:	.reg	%r19
+r20:	.reg	%r20
+r21:	.reg	%r21
+r22:	.reg	%r22
+r23:	.reg	%r23
+r24:	.reg	%r24
+r25:	.reg	%r25
+r26:	.reg	%r26
+r27:	.reg	%r27
+r28:	.reg	%r28
+r29:	.reg	%r29
+r30:	.reg	%r30
+r31:	.reg	%r31
+
+/* Hardware Space Registers.  */
+sr0:	.reg	%sr0
+sr1:	.reg	%sr1
+sr2:	.reg	%sr2
+sr3:	.reg	%sr3
+sr4:	.reg	%sr4
+sr5:	.reg	%sr5
+sr6:	.reg	%sr6
+sr7:	.reg	%sr7
+
+/* Hardware Floating Point Registers.  */
+fr0:	.reg	%fr0
+fr1:	.reg	%fr1
+fr2:	.reg	%fr2
+fr3:	.reg	%fr3
+fr4:	.reg	%fr4
+fr5:	.reg	%fr5
+fr6:	.reg	%fr6
+fr7:	.reg	%fr7
+fr8:	.reg	%fr8
+fr9:	.reg	%fr9
+fr10:	.reg	%fr10
+fr11:	.reg	%fr11
+fr12:	.reg	%fr12
+fr13:	.reg	%fr13
+fr14:	.reg	%fr14
+fr15:	.reg	%fr15
+
+/* Hardware Control Registers.  */
+cr11:	.reg	%cr11
+sar:	.reg	%cr11	/* Shift Amount Register */
+
+/* Software Architecture General Registers.  */
+rp:	.reg    r2	/* return pointer */
+#ifdef CONFIG_64BIT
+mrp:	.reg	r2 	/* millicode return pointer */
+#else
+mrp:	.reg	r31	/* millicode return pointer */
+#endif
+ret0:	.reg    r28	/* return value */
+ret1:	.reg    r29	/* return value (high part of double) */
+sp:	.reg 	r30	/* stack pointer */
+dp:	.reg	r27	/* data pointer */
+arg0:	.reg	r26	/* argument */
+arg1:	.reg	r25	/* argument or high part of double argument */
+arg2:	.reg	r24	/* argument */
+arg3:	.reg	r23	/* argument or high part of double argument */
+
+/* Software Architecture Space Registers.  */
+/* 		sr0	; return link from BLE */
+sret:	.reg	sr1	/* return value */
+sarg:	.reg	sr1	/* argument */
+/* 		sr4	; PC SPACE tracker */
+/* 		sr5	; process private data */
+
+/* Frame Offsets (millicode convention!)  Used when calling other
+   millicode routines.  Stack unwinding is dependent upon these
+   definitions.  */
+r31_slot:	.equ	-20	/* "current RP" slot */
+sr0_slot:	.equ	-16     /* "static link" slot */
+#if defined(CONFIG_64BIT)
+mrp_slot:       .equ    -16	/* "current RP" slot */
+psp_slot:       .equ    -8	/* "previous SP" slot */
+#else
+mrp_slot:	.equ	-20     /* "current RP" slot (replacing "r31_slot") */
+#endif
+
+
+#define DEFINE(name,value)name:	.EQU	value
+#define RDEFINE(name,value)name:	.REG	value
+#ifdef milliext
+#define MILLI_BE(lbl)   BE    lbl(sr7,r0)
+#define MILLI_BEN(lbl)  BE,n  lbl(sr7,r0)
+#define MILLI_BLE(lbl)	BLE   lbl(sr7,r0)
+#define MILLI_BLEN(lbl)	BLE,n lbl(sr7,r0)
+#define MILLIRETN	BE,n  0(sr0,mrp)
+#define MILLIRET	BE    0(sr0,mrp)
+#define MILLI_RETN	BE,n  0(sr0,mrp)
+#define MILLI_RET	BE    0(sr0,mrp)
+#else
+#define MILLI_BE(lbl)	B     lbl
+#define MILLI_BEN(lbl)  B,n   lbl
+#define MILLI_BLE(lbl)	BL    lbl,mrp
+#define MILLI_BLEN(lbl)	BL,n  lbl,mrp
+#define MILLIRETN	BV,n  0(mrp)
+#define MILLIRET	BV    0(mrp)
+#define MILLI_RETN	BV,n  0(mrp)
+#define MILLI_RET	BV    0(mrp)
+#endif
+
+#define CAT(a,b)	a##b
+
+#define SUBSPA_MILLI	 .section .text
+#define SUBSPA_MILLI_DIV .section .text.div,"ax",@progbits! .align 16
+#define SUBSPA_MILLI_MUL .section .text.mul,"ax",@progbits! .align 16
+#define ATTR_MILLI
+#define SUBSPA_DATA	 .section .data
+#define ATTR_DATA
+#define GLOBAL		 $global$
+#define GSYM(sym) 	 !sym:
+#define LSYM(sym)	 !CAT(.L,sym:)
+#define LREF(sym)	 CAT(.L,sym)
+
+#endif /*_PA_MILLI_H_*/
diff --git a/arch/parisc/lib/milli/mulI.S b/arch/parisc/lib/milli/mulI.S
new file mode 100644
index 0000000..4c7e0c3
--- /dev/null
+++ b/arch/parisc/lib/milli/mulI.S
@@ -0,0 +1,474 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_mulI
+/* VERSION "@(#)$$mulI $ Revision: 12.4 $ $ Date: 94/03/17 17:18:51 $" */
+/******************************************************************************
+This routine is used on PA2.0 processors when gcc -mno-fpregs is used
+
+ROUTINE:	$$mulI
+
+
+DESCRIPTION:	
+
+	$$mulI multiplies two single word integers, giving a single 
+	word result.  
+
+
+INPUT REGISTERS:
+
+	arg0 = Operand 1
+	arg1 = Operand 2
+	r31  == return pc
+	sr0  == return space when called externally 
+
+
+OUTPUT REGISTERS:
+
+	arg0 = undefined
+	arg1 = undefined
+	ret1 = result 
+
+OTHER REGISTERS AFFECTED:
+
+	r1   = undefined
+
+SIDE EFFECTS:
+
+	Causes a trap under the following conditions:  NONE
+	Changes memory at the following places:  NONE
+
+PERMISSIBLE CONTEXT:
+
+	Unwindable
+	Does not create a stack frame
+	Is usable for internal or external microcode
+
+DISCUSSION:
+
+	Calls other millicode routines via mrp:  NONE
+	Calls other millicode routines:  NONE
+
+***************************************************************************/
+
+
+#define	a0	%arg0
+#define	a1	%arg1
+#define	t0	%r1
+#define	r	%ret1
+
+#define	a0__128a0	zdep	a0,24,25,a0
+#define	a0__256a0	zdep	a0,23,24,a0
+#define	a1_ne_0_b_l0	comb,<>	a1,0,LREF(l0)
+#define	a1_ne_0_b_l1	comb,<>	a1,0,LREF(l1)
+#define	a1_ne_0_b_l2	comb,<>	a1,0,LREF(l2)
+#define	b_n_ret_t0	b,n	LREF(ret_t0)
+#define	b_e_shift	b	LREF(e_shift)
+#define	b_e_t0ma0	b	LREF(e_t0ma0)
+#define	b_e_t0		b	LREF(e_t0)
+#define	b_e_t0a0	b	LREF(e_t0a0)
+#define	b_e_t02a0	b	LREF(e_t02a0)
+#define	b_e_t04a0	b	LREF(e_t04a0)
+#define	b_e_2t0		b	LREF(e_2t0)
+#define	b_e_2t0a0	b	LREF(e_2t0a0)
+#define	b_e_2t04a0	b	LREF(e2t04a0)
+#define	b_e_3t0		b	LREF(e_3t0)
+#define	b_e_4t0		b	LREF(e_4t0)
+#define	b_e_4t0a0	b	LREF(e_4t0a0)
+#define	b_e_4t08a0	b	LREF(e4t08a0)
+#define	b_e_5t0		b	LREF(e_5t0)
+#define	b_e_8t0		b	LREF(e_8t0)
+#define	b_e_8t0a0	b	LREF(e_8t0a0)
+#define	r__r_a0		add	r,a0,r
+#define	r__r_2a0	sh1add	a0,r,r
+#define	r__r_4a0	sh2add	a0,r,r
+#define	r__r_8a0	sh3add	a0,r,r
+#define	r__r_t0		add	r,t0,r
+#define	r__r_2t0	sh1add	t0,r,r
+#define	r__r_4t0	sh2add	t0,r,r
+#define	r__r_8t0	sh3add	t0,r,r
+#define	t0__3a0		sh1add	a0,a0,t0
+#define	t0__4a0		sh2add	a0,0,t0
+#define	t0__5a0		sh2add	a0,a0,t0
+#define	t0__8a0		sh3add	a0,0,t0
+#define	t0__9a0		sh3add	a0,a0,t0
+#define	t0__16a0	zdep	a0,27,28,t0
+#define	t0__32a0	zdep	a0,26,27,t0
+#define	t0__64a0	zdep	a0,25,26,t0
+#define	t0__128a0	zdep	a0,24,25,t0
+#define	t0__t0ma0	sub	t0,a0,t0
+#define	t0__t0_a0	add	t0,a0,t0
+#define	t0__t0_2a0	sh1add	a0,t0,t0
+#define	t0__t0_4a0	sh2add	a0,t0,t0
+#define	t0__t0_8a0	sh3add	a0,t0,t0
+#define	t0__2t0_a0	sh1add	t0,a0,t0
+#define	t0__3t0		sh1add	t0,t0,t0
+#define	t0__4t0		sh2add	t0,0,t0
+#define	t0__4t0_a0	sh2add	t0,a0,t0
+#define	t0__5t0		sh2add	t0,t0,t0
+#define	t0__8t0		sh3add	t0,0,t0
+#define	t0__8t0_a0	sh3add	t0,a0,t0
+#define	t0__9t0		sh3add	t0,t0,t0
+#define	t0__16t0	zdep	t0,27,28,t0
+#define	t0__32t0	zdep	t0,26,27,t0
+#define	t0__256a0	zdep	a0,23,24,t0
+
+
+	SUBSPA_MILLI
+	ATTR_MILLI
+	.align 16
+	.proc
+	.callinfo millicode
+	.export $$mulI,millicode
+GSYM($$mulI)	
+	combt,<<=	a1,a0,LREF(l4)	/* swap args if unsigned a1>a0 */
+	copy		0,r		/* zero out the result */
+	xor		a0,a1,a0	/* swap a0 & a1 using the */
+	xor		a0,a1,a1	/*  old xor trick */
+	xor		a0,a1,a0
+LSYM(l4)
+	combt,<=	0,a0,LREF(l3)		/* if a0>=0 then proceed like unsigned */
+	zdep		a1,30,8,t0	/* t0 = (a1&0xff)<<1 ********* */
+	sub,>		0,a1,t0		/* otherwise negate both and */
+	combt,<=,n	a0,t0,LREF(l2)	/*  swap back if |a0|<|a1| */
+	sub		0,a0,a1
+	movb,tr,n	t0,a0,LREF(l2)	/* 10th inst.  */
+
+LSYM(l0)	r__r_t0				/* add in this partial product */
+LSYM(l1)	a0__256a0			/* a0 <<= 8 ****************** */
+LSYM(l2)	zdep		a1,30,8,t0	/* t0 = (a1&0xff)<<1 ********* */
+LSYM(l3)	blr		t0,0		/* case on these 8 bits ****** */
+		extru		a1,23,24,a1	/* a1 >>= 8 ****************** */
+
+/*16 insts before this.  */
+/*			  a0 <<= 8 ************************** */
+LSYM(x0)	a1_ne_0_b_l2	! a0__256a0	! MILLIRETN	! nop
+LSYM(x1)	a1_ne_0_b_l1	! r__r_a0	! MILLIRETN	! nop
+LSYM(x2)	a1_ne_0_b_l1	! r__r_2a0	! MILLIRETN	! nop
+LSYM(x3)	a1_ne_0_b_l0	! t0__3a0	! MILLIRET	! r__r_t0
+LSYM(x4)	a1_ne_0_b_l1	! r__r_4a0	! MILLIRETN	! nop
+LSYM(x5)	a1_ne_0_b_l0	! t0__5a0	! MILLIRET	! r__r_t0
+LSYM(x6)	t0__3a0		! a1_ne_0_b_l1	! r__r_2t0	! MILLIRETN
+LSYM(x7)	t0__3a0		! a1_ne_0_b_l0	! r__r_4a0	! b_n_ret_t0
+LSYM(x8)	a1_ne_0_b_l1	! r__r_8a0	! MILLIRETN	! nop
+LSYM(x9)	a1_ne_0_b_l0	! t0__9a0	! MILLIRET	! r__r_t0
+LSYM(x10)	t0__5a0		! a1_ne_0_b_l1	! r__r_2t0	! MILLIRETN
+LSYM(x11)	t0__3a0		! a1_ne_0_b_l0	! r__r_8a0	! b_n_ret_t0
+LSYM(x12)	t0__3a0		! a1_ne_0_b_l1	! r__r_4t0	! MILLIRETN
+LSYM(x13)	t0__5a0		! a1_ne_0_b_l0	! r__r_8a0	! b_n_ret_t0
+LSYM(x14)	t0__3a0		! t0__2t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x15)	t0__5a0		! a1_ne_0_b_l0	! t0__3t0	! b_n_ret_t0
+LSYM(x16)	t0__16a0	! a1_ne_0_b_l1	! r__r_t0	! MILLIRETN
+LSYM(x17)	t0__9a0		! a1_ne_0_b_l0	! t0__t0_8a0	! b_n_ret_t0
+LSYM(x18)	t0__9a0		! a1_ne_0_b_l1	! r__r_2t0	! MILLIRETN
+LSYM(x19)	t0__9a0		! a1_ne_0_b_l0	! t0__2t0_a0	! b_n_ret_t0
+LSYM(x20)	t0__5a0		! a1_ne_0_b_l1	! r__r_4t0	! MILLIRETN
+LSYM(x21)	t0__5a0		! a1_ne_0_b_l0	! t0__4t0_a0	! b_n_ret_t0
+LSYM(x22)	t0__5a0		! t0__2t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x23)	t0__5a0		! t0__2t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x24)	t0__3a0		! a1_ne_0_b_l1	! r__r_8t0	! MILLIRETN
+LSYM(x25)	t0__5a0		! a1_ne_0_b_l0	! t0__5t0	! b_n_ret_t0
+LSYM(x26)	t0__3a0		! t0__4t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x27)	t0__3a0		! a1_ne_0_b_l0	! t0__9t0	! b_n_ret_t0
+LSYM(x28)	t0__3a0		! t0__2t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x29)	t0__3a0		! t0__2t0_a0	! b_e_t0	! t0__4t0_a0
+LSYM(x30)	t0__5a0		! t0__3t0	! b_e_shift	! r__r_2t0
+LSYM(x31)	t0__32a0	! a1_ne_0_b_l0	! t0__t0ma0	! b_n_ret_t0
+LSYM(x32)	t0__32a0	! a1_ne_0_b_l1	! r__r_t0	! MILLIRETN
+LSYM(x33)	t0__8a0		! a1_ne_0_b_l0	! t0__4t0_a0	! b_n_ret_t0
+LSYM(x34)	t0__16a0	! t0__t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x35)	t0__9a0		! t0__3t0	! b_e_t0	! t0__t0_8a0
+LSYM(x36)	t0__9a0		! a1_ne_0_b_l1	! r__r_4t0	! MILLIRETN
+LSYM(x37)	t0__9a0		! a1_ne_0_b_l0	! t0__4t0_a0	! b_n_ret_t0
+LSYM(x38)	t0__9a0		! t0__2t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x39)	t0__9a0		! t0__2t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x40)	t0__5a0		! a1_ne_0_b_l1	! r__r_8t0	! MILLIRETN
+LSYM(x41)	t0__5a0		! a1_ne_0_b_l0	! t0__8t0_a0	! b_n_ret_t0
+LSYM(x42)	t0__5a0		! t0__4t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x43)	t0__5a0		! t0__4t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x44)	t0__5a0		! t0__2t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x45)	t0__9a0		! a1_ne_0_b_l0	! t0__5t0	! b_n_ret_t0
+LSYM(x46)	t0__9a0		! t0__5t0	! b_e_t0	! t0__t0_a0
+LSYM(x47)	t0__9a0		! t0__5t0	! b_e_t0	! t0__t0_2a0
+LSYM(x48)	t0__3a0		! a1_ne_0_b_l0	! t0__16t0	! b_n_ret_t0
+LSYM(x49)	t0__9a0		! t0__5t0	! b_e_t0	! t0__t0_4a0
+LSYM(x50)	t0__5a0		! t0__5t0	! b_e_shift	! r__r_2t0
+LSYM(x51)	t0__9a0		! t0__t0_8a0	! b_e_t0	! t0__3t0
+LSYM(x52)	t0__3a0		! t0__4t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x53)	t0__3a0		! t0__4t0_a0	! b_e_t0	! t0__4t0_a0
+LSYM(x54)	t0__9a0		! t0__3t0	! b_e_shift	! r__r_2t0
+LSYM(x55)	t0__9a0		! t0__3t0	! b_e_t0	! t0__2t0_a0
+LSYM(x56)	t0__3a0		! t0__2t0_a0	! b_e_shift	! r__r_8t0
+LSYM(x57)	t0__9a0		! t0__2t0_a0	! b_e_t0	! t0__3t0
+LSYM(x58)	t0__3a0		! t0__2t0_a0	! b_e_2t0	! t0__4t0_a0
+LSYM(x59)	t0__9a0		! t0__2t0_a0	! b_e_t02a0	! t0__3t0
+LSYM(x60)	t0__5a0		! t0__3t0	! b_e_shift	! r__r_4t0
+LSYM(x61)	t0__5a0		! t0__3t0	! b_e_t0	! t0__4t0_a0
+LSYM(x62)	t0__32a0	! t0__t0ma0	! b_e_shift	! r__r_2t0
+LSYM(x63)	t0__64a0	! a1_ne_0_b_l0	! t0__t0ma0	! b_n_ret_t0
+LSYM(x64)	t0__64a0	! a1_ne_0_b_l1	! r__r_t0	! MILLIRETN
+LSYM(x65)	t0__8a0		! a1_ne_0_b_l0	! t0__8t0_a0	! b_n_ret_t0
+LSYM(x66)	t0__32a0	! t0__t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x67)	t0__8a0		! t0__4t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x68)	t0__8a0		! t0__2t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x69)	t0__8a0		! t0__2t0_a0	! b_e_t0	! t0__4t0_a0
+LSYM(x70)	t0__64a0	! t0__t0_4a0	! b_e_t0	! t0__t0_2a0
+LSYM(x71)	t0__9a0		! t0__8t0	! b_e_t0	! t0__t0ma0
+LSYM(x72)	t0__9a0		! a1_ne_0_b_l1	! r__r_8t0	! MILLIRETN
+LSYM(x73)	t0__9a0		! t0__8t0_a0	! b_e_shift	! r__r_t0
+LSYM(x74)	t0__9a0		! t0__4t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x75)	t0__9a0		! t0__4t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x76)	t0__9a0		! t0__2t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x77)	t0__9a0		! t0__2t0_a0	! b_e_t0	! t0__4t0_a0
+LSYM(x78)	t0__9a0		! t0__2t0_a0	! b_e_2t0	! t0__2t0_a0
+LSYM(x79)	t0__16a0	! t0__5t0	! b_e_t0	! t0__t0ma0
+LSYM(x80)	t0__16a0	! t0__5t0	! b_e_shift	! r__r_t0
+LSYM(x81)	t0__9a0		! t0__9t0	! b_e_shift	! r__r_t0
+LSYM(x82)	t0__5a0		! t0__8t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x83)	t0__5a0		! t0__8t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x84)	t0__5a0		! t0__4t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x85)	t0__8a0		! t0__2t0_a0	! b_e_t0	! t0__5t0
+LSYM(x86)	t0__5a0		! t0__4t0_a0	! b_e_2t0	! t0__2t0_a0
+LSYM(x87)	t0__9a0		! t0__9t0	! b_e_t02a0	! t0__t0_4a0
+LSYM(x88)	t0__5a0		! t0__2t0_a0	! b_e_shift	! r__r_8t0
+LSYM(x89)	t0__5a0		! t0__2t0_a0	! b_e_t0	! t0__8t0_a0
+LSYM(x90)	t0__9a0		! t0__5t0	! b_e_shift	! r__r_2t0
+LSYM(x91)	t0__9a0		! t0__5t0	! b_e_t0	! t0__2t0_a0
+LSYM(x92)	t0__5a0		! t0__2t0_a0	! b_e_4t0	! t0__2t0_a0
+LSYM(x93)	t0__32a0	! t0__t0ma0	! b_e_t0	! t0__3t0
+LSYM(x94)	t0__9a0		! t0__5t0	! b_e_2t0	! t0__t0_2a0
+LSYM(x95)	t0__9a0		! t0__2t0_a0	! b_e_t0	! t0__5t0
+LSYM(x96)	t0__8a0		! t0__3t0	! b_e_shift	! r__r_4t0
+LSYM(x97)	t0__8a0		! t0__3t0	! b_e_t0	! t0__4t0_a0
+LSYM(x98)	t0__32a0	! t0__3t0	! b_e_t0	! t0__t0_2a0
+LSYM(x99)	t0__8a0		! t0__4t0_a0	! b_e_t0	! t0__3t0
+LSYM(x100)	t0__5a0		! t0__5t0	! b_e_shift	! r__r_4t0
+LSYM(x101)	t0__5a0		! t0__5t0	! b_e_t0	! t0__4t0_a0
+LSYM(x102)	t0__32a0	! t0__t0_2a0	! b_e_t0	! t0__3t0
+LSYM(x103)	t0__5a0		! t0__5t0	! b_e_t02a0	! t0__4t0_a0
+LSYM(x104)	t0__3a0		! t0__4t0_a0	! b_e_shift	! r__r_8t0
+LSYM(x105)	t0__5a0		! t0__4t0_a0	! b_e_t0	! t0__5t0
+LSYM(x106)	t0__3a0		! t0__4t0_a0	! b_e_2t0	! t0__4t0_a0
+LSYM(x107)	t0__9a0		! t0__t0_4a0	! b_e_t02a0	! t0__8t0_a0
+LSYM(x108)	t0__9a0		! t0__3t0	! b_e_shift	! r__r_4t0
+LSYM(x109)	t0__9a0		! t0__3t0	! b_e_t0	! t0__4t0_a0
+LSYM(x110)	t0__9a0		! t0__3t0	! b_e_2t0	! t0__2t0_a0
+LSYM(x111)	t0__9a0		! t0__4t0_a0	! b_e_t0	! t0__3t0
+LSYM(x112)	t0__3a0		! t0__2t0_a0	! b_e_t0	! t0__16t0
+LSYM(x113)	t0__9a0		! t0__4t0_a0	! b_e_t02a0	! t0__3t0
+LSYM(x114)	t0__9a0		! t0__2t0_a0	! b_e_2t0	! t0__3t0
+LSYM(x115)	t0__9a0		! t0__2t0_a0	! b_e_2t0a0	! t0__3t0
+LSYM(x116)	t0__3a0		! t0__2t0_a0	! b_e_4t0	! t0__4t0_a0
+LSYM(x117)	t0__3a0		! t0__4t0_a0	! b_e_t0	! t0__9t0
+LSYM(x118)	t0__3a0		! t0__4t0_a0	! b_e_t0a0	! t0__9t0
+LSYM(x119)	t0__3a0		! t0__4t0_a0	! b_e_t02a0	! t0__9t0
+LSYM(x120)	t0__5a0		! t0__3t0	! b_e_shift	! r__r_8t0
+LSYM(x121)	t0__5a0		! t0__3t0	! b_e_t0	! t0__8t0_a0
+LSYM(x122)	t0__5a0		! t0__3t0	! b_e_2t0	! t0__4t0_a0
+LSYM(x123)	t0__5a0		! t0__8t0_a0	! b_e_t0	! t0__3t0
+LSYM(x124)	t0__32a0	! t0__t0ma0	! b_e_shift	! r__r_4t0
+LSYM(x125)	t0__5a0		! t0__5t0	! b_e_t0	! t0__5t0
+LSYM(x126)	t0__64a0	! t0__t0ma0	! b_e_shift	! r__r_2t0
+LSYM(x127)	t0__128a0	! a1_ne_0_b_l0	! t0__t0ma0	! b_n_ret_t0
+LSYM(x128)	t0__128a0	! a1_ne_0_b_l1	! r__r_t0	! MILLIRETN
+LSYM(x129)	t0__128a0	! a1_ne_0_b_l0	! t0__t0_a0	! b_n_ret_t0
+LSYM(x130)	t0__64a0	! t0__t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x131)	t0__8a0		! t0__8t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x132)	t0__8a0		! t0__4t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x133)	t0__8a0		! t0__4t0_a0	! b_e_t0	! t0__4t0_a0
+LSYM(x134)	t0__8a0		! t0__4t0_a0	! b_e_2t0	! t0__2t0_a0
+LSYM(x135)	t0__9a0		! t0__5t0	! b_e_t0	! t0__3t0
+LSYM(x136)	t0__8a0		! t0__2t0_a0	! b_e_shift	! r__r_8t0
+LSYM(x137)	t0__8a0		! t0__2t0_a0	! b_e_t0	! t0__8t0_a0
+LSYM(x138)	t0__8a0		! t0__2t0_a0	! b_e_2t0	! t0__4t0_a0
+LSYM(x139)	t0__8a0		! t0__2t0_a0	! b_e_2t0a0	! t0__4t0_a0
+LSYM(x140)	t0__3a0		! t0__2t0_a0	! b_e_4t0	! t0__5t0
+LSYM(x141)	t0__8a0		! t0__2t0_a0	! b_e_4t0a0	! t0__2t0_a0
+LSYM(x142)	t0__9a0		! t0__8t0	! b_e_2t0	! t0__t0ma0
+LSYM(x143)	t0__16a0	! t0__9t0	! b_e_t0	! t0__t0ma0
+LSYM(x144)	t0__9a0		! t0__8t0	! b_e_shift	! r__r_2t0
+LSYM(x145)	t0__9a0		! t0__8t0	! b_e_t0	! t0__2t0_a0
+LSYM(x146)	t0__9a0		! t0__8t0_a0	! b_e_shift	! r__r_2t0
+LSYM(x147)	t0__9a0		! t0__8t0_a0	! b_e_t0	! t0__2t0_a0
+LSYM(x148)	t0__9a0		! t0__4t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x149)	t0__9a0		! t0__4t0_a0	! b_e_t0	! t0__4t0_a0
+LSYM(x150)	t0__9a0		! t0__4t0_a0	! b_e_2t0	! t0__2t0_a0
+LSYM(x151)	t0__9a0		! t0__4t0_a0	! b_e_2t0a0	! t0__2t0_a0
+LSYM(x152)	t0__9a0		! t0__2t0_a0	! b_e_shift	! r__r_8t0
+LSYM(x153)	t0__9a0		! t0__2t0_a0	! b_e_t0	! t0__8t0_a0
+LSYM(x154)	t0__9a0		! t0__2t0_a0	! b_e_2t0	! t0__4t0_a0
+LSYM(x155)	t0__32a0	! t0__t0ma0	! b_e_t0	! t0__5t0
+LSYM(x156)	t0__9a0		! t0__2t0_a0	! b_e_4t0	! t0__2t0_a0
+LSYM(x157)	t0__32a0	! t0__t0ma0	! b_e_t02a0	! t0__5t0
+LSYM(x158)	t0__16a0	! t0__5t0	! b_e_2t0	! t0__t0ma0
+LSYM(x159)	t0__32a0	! t0__5t0	! b_e_t0	! t0__t0ma0
+LSYM(x160)	t0__5a0		! t0__4t0	! b_e_shift	! r__r_8t0
+LSYM(x161)	t0__8a0		! t0__5t0	! b_e_t0	! t0__4t0_a0
+LSYM(x162)	t0__9a0		! t0__9t0	! b_e_shift	! r__r_2t0
+LSYM(x163)	t0__9a0		! t0__9t0	! b_e_t0	! t0__2t0_a0
+LSYM(x164)	t0__5a0		! t0__8t0_a0	! b_e_shift	! r__r_4t0
+LSYM(x165)	t0__8a0		! t0__4t0_a0	! b_e_t0	! t0__5t0
+LSYM(x166)	t0__5a0		! t0__8t0_a0	! b_e_2t0	! t0__2t0_a0
+LSYM(x167)	t0__5a0		! t0__8t0_a0	! b_e_2t0a0	! t0__2t0_a0
+LSYM(x168)	t0__5a0		! t0__4t0_a0	! b_e_shift	! r__r_8t0
+LSYM(x169)	t0__5a0		! t0__4t0_a0	! b_e_t0	! t0__8t0_a0
+LSYM(x170)	t0__32a0	! t0__t0_2a0	! b_e_t0	! t0__5t0
+LSYM(x171)	t0__9a0		! t0__2t0_a0	! b_e_t0	! t0__9t0
+LSYM(x172)	t0__5a0		! t0__4t0_a0	! b_e_4t0	! t0__2t0_a0
+LSYM(x173)	t0__9a0		! t0__2t0_a0	! b_e_t02a0	! t0__9t0
+LSYM(x174)	t0__32a0	! t0__t0_2a0	! b_e_t04a0	! t0__5t0
+LSYM(x175)	t0__8a0		! t0__2t0_a0	! b_e_5t0	! t0__2t0_a0
+LSYM(x176)	t0__5a0		! t0__4t0_a0	! b_e_8t0	! t0__t0_a0
+LSYM(x177)	t0__5a0		! t0__4t0_a0	! b_e_8t0a0	! t0__t0_a0
+LSYM(x178)	t0__5a0		! t0__2t0_a0	! b_e_2t0	! t0__8t0_a0
+LSYM(x179)	t0__5a0		! t0__2t0_a0	! b_e_2t0a0	! t0__8t0_a0
+LSYM(x180)	t0__9a0		! t0__5t0	! b_e_shift	! r__r_4t0
+LSYM(x181)	t0__9a0		! t0__5t0	! b_e_t0	! t0__4t0_a0
+LSYM(x182)	t0__9a0		! t0__5t0	! b_e_2t0	! t0__2t0_a0
+LSYM(x183)	t0__9a0		! t0__5t0	! b_e_2t0a0	! t0__2t0_a0
+LSYM(x184)	t0__5a0		! t0__9t0	! b_e_4t0	! t0__t0_a0
+LSYM(x185)	t0__9a0		! t0__4t0_a0	! b_e_t0	! t0__5t0
+LSYM(x186)	t0__32a0	! t0__t0ma0	! b_e_2t0	! t0__3t0
+LSYM(x187)	t0__9a0		! t0__4t0_a0	! b_e_t02a0	! t0__5t0
+LSYM(x188)	t0__9a0		! t0__5t0	! b_e_4t0	! t0__t0_2a0
+LSYM(x189)	t0__5a0		! t0__4t0_a0	! b_e_t0	! t0__9t0
+LSYM(x190)	t0__9a0		! t0__2t0_a0	! b_e_2t0	! t0__5t0
+LSYM(x191)	t0__64a0	! t0__3t0	! b_e_t0	! t0__t0ma0
+LSYM(x192)	t0__8a0		! t0__3t0	! b_e_shift	! r__r_8t0
+LSYM(x193)	t0__8a0		! t0__3t0	! b_e_t0	! t0__8t0_a0
+LSYM(x194)	t0__8a0		! t0__3t0	! b_e_2t0	! t0__4t0_a0
+LSYM(x195)	t0__8a0		! t0__8t0_a0	! b_e_t0	! t0__3t0
+LSYM(x196)	t0__8a0		! t0__3t0	! b_e_4t0	! t0__2t0_a0
+LSYM(x197)	t0__8a0		! t0__3t0	! b_e_4t0a0	! t0__2t0_a0
+LSYM(x198)	t0__64a0	! t0__t0_2a0	! b_e_t0	! t0__3t0
+LSYM(x199)	t0__8a0		! t0__4t0_a0	! b_e_2t0a0	! t0__3t0
+LSYM(x200)	t0__5a0		! t0__5t0	! b_e_shift	! r__r_8t0
+LSYM(x201)	t0__5a0		! t0__5t0	! b_e_t0	! t0__8t0_a0
+LSYM(x202)	t0__5a0		! t0__5t0	! b_e_2t0	! t0__4t0_a0
+LSYM(x203)	t0__5a0		! t0__5t0	! b_e_2t0a0	! t0__4t0_a0
+LSYM(x204)	t0__8a0		! t0__2t0_a0	! b_e_4t0	! t0__3t0
+LSYM(x205)	t0__5a0		! t0__8t0_a0	! b_e_t0	! t0__5t0
+LSYM(x206)	t0__64a0	! t0__t0_4a0	! b_e_t02a0	! t0__3t0
+LSYM(x207)	t0__8a0		! t0__2t0_a0	! b_e_3t0	! t0__4t0_a0
+LSYM(x208)	t0__5a0		! t0__5t0	! b_e_8t0	! t0__t0_a0
+LSYM(x209)	t0__5a0		! t0__5t0	! b_e_8t0a0	! t0__t0_a0
+LSYM(x210)	t0__5a0		! t0__4t0_a0	! b_e_2t0	! t0__5t0
+LSYM(x211)	t0__5a0		! t0__4t0_a0	! b_e_2t0a0	! t0__5t0
+LSYM(x212)	t0__3a0		! t0__4t0_a0	! b_e_4t0	! t0__4t0_a0
+LSYM(x213)	t0__3a0		! t0__4t0_a0	! b_e_4t0a0	! t0__4t0_a0
+LSYM(x214)	t0__9a0		! t0__t0_4a0	! b_e_2t04a0	! t0__8t0_a0
+LSYM(x215)	t0__5a0		! t0__4t0_a0	! b_e_5t0	! t0__2t0_a0
+LSYM(x216)	t0__9a0		! t0__3t0	! b_e_shift	! r__r_8t0
+LSYM(x217)	t0__9a0		! t0__3t0	! b_e_t0	! t0__8t0_a0
+LSYM(x218)	t0__9a0		! t0__3t0	! b_e_2t0	! t0__4t0_a0
+LSYM(x219)	t0__9a0		! t0__8t0_a0	! b_e_t0	! t0__3t0
+LSYM(x220)	t0__3a0		! t0__9t0	! b_e_4t0	! t0__2t0_a0
+LSYM(x221)	t0__3a0		! t0__9t0	! b_e_4t0a0	! t0__2t0_a0
+LSYM(x222)	t0__9a0		! t0__4t0_a0	! b_e_2t0	! t0__3t0
+LSYM(x223)	t0__9a0		! t0__4t0_a0	! b_e_2t0a0	! t0__3t0
+LSYM(x224)	t0__9a0		! t0__3t0	! b_e_8t0	! t0__t0_a0
+LSYM(x225)	t0__9a0		! t0__5t0	! b_e_t0	! t0__5t0
+LSYM(x226)	t0__3a0		! t0__2t0_a0	! b_e_t02a0	! t0__32t0
+LSYM(x227)	t0__9a0		! t0__5t0	! b_e_t02a0	! t0__5t0
+LSYM(x228)	t0__9a0		! t0__2t0_a0	! b_e_4t0	! t0__3t0
+LSYM(x229)	t0__9a0		! t0__2t0_a0	! b_e_4t0a0	! t0__3t0
+LSYM(x230)	t0__9a0		! t0__5t0	! b_e_5t0	! t0__t0_a0
+LSYM(x231)	t0__9a0		! t0__2t0_a0	! b_e_3t0	! t0__4t0_a0
+LSYM(x232)	t0__3a0		! t0__2t0_a0	! b_e_8t0	! t0__4t0_a0
+LSYM(x233)	t0__3a0		! t0__2t0_a0	! b_e_8t0a0	! t0__4t0_a0
+LSYM(x234)	t0__3a0		! t0__4t0_a0	! b_e_2t0	! t0__9t0
+LSYM(x235)	t0__3a0		! t0__4t0_a0	! b_e_2t0a0	! t0__9t0
+LSYM(x236)	t0__9a0		! t0__2t0_a0	! b_e_4t08a0	! t0__3t0
+LSYM(x237)	t0__16a0	! t0__5t0	! b_e_3t0	! t0__t0ma0
+LSYM(x238)	t0__3a0		! t0__4t0_a0	! b_e_2t04a0	! t0__9t0
+LSYM(x239)	t0__16a0	! t0__5t0	! b_e_t0ma0	! t0__3t0
+LSYM(x240)	t0__9a0		! t0__t0_a0	! b_e_8t0	! t0__3t0
+LSYM(x241)	t0__9a0		! t0__t0_a0	! b_e_8t0a0	! t0__3t0
+LSYM(x242)	t0__5a0		! t0__3t0	! b_e_2t0	! t0__8t0_a0
+LSYM(x243)	t0__9a0		! t0__9t0	! b_e_t0	! t0__3t0
+LSYM(x244)	t0__5a0		! t0__3t0	! b_e_4t0	! t0__4t0_a0
+LSYM(x245)	t0__8a0		! t0__3t0	! b_e_5t0	! t0__2t0_a0
+LSYM(x246)	t0__5a0		! t0__8t0_a0	! b_e_2t0	! t0__3t0
+LSYM(x247)	t0__5a0		! t0__8t0_a0	! b_e_2t0a0	! t0__3t0
+LSYM(x248)	t0__32a0	! t0__t0ma0	! b_e_shift	! r__r_8t0
+LSYM(x249)	t0__32a0	! t0__t0ma0	! b_e_t0	! t0__8t0_a0
+LSYM(x250)	t0__5a0		! t0__5t0	! b_e_2t0	! t0__5t0
+LSYM(x251)	t0__5a0		! t0__5t0	! b_e_2t0a0	! t0__5t0
+LSYM(x252)	t0__64a0	! t0__t0ma0	! b_e_shift	! r__r_4t0
+LSYM(x253)	t0__64a0	! t0__t0ma0	! b_e_t0	! t0__4t0_a0
+LSYM(x254)	t0__128a0	! t0__t0ma0	! b_e_shift	! r__r_2t0
+LSYM(x255)	t0__256a0	! a1_ne_0_b_l0	! t0__t0ma0	! b_n_ret_t0
+/*1040 insts before this.  */
+LSYM(ret_t0)	MILLIRET
+LSYM(e_t0)	r__r_t0
+LSYM(e_shift)	a1_ne_0_b_l2
+	a0__256a0	/* a0 <<= 8 *********** */
+	MILLIRETN
+LSYM(e_t0ma0)	a1_ne_0_b_l0
+	t0__t0ma0
+	MILLIRET
+	r__r_t0
+LSYM(e_t0a0)	a1_ne_0_b_l0
+	t0__t0_a0
+	MILLIRET
+	r__r_t0
+LSYM(e_t02a0)	a1_ne_0_b_l0
+	t0__t0_2a0
+	MILLIRET
+	r__r_t0
+LSYM(e_t04a0)	a1_ne_0_b_l0
+	t0__t0_4a0
+	MILLIRET
+	r__r_t0
+LSYM(e_2t0)	a1_ne_0_b_l1
+	r__r_2t0
+	MILLIRETN
+LSYM(e_2t0a0)	a1_ne_0_b_l0
+	t0__2t0_a0
+	MILLIRET
+	r__r_t0
+LSYM(e2t04a0)	t0__t0_2a0
+	a1_ne_0_b_l1
+	r__r_2t0
+	MILLIRETN
+LSYM(e_3t0)	a1_ne_0_b_l0
+	t0__3t0
+	MILLIRET
+	r__r_t0
+LSYM(e_4t0)	a1_ne_0_b_l1
+	r__r_4t0
+	MILLIRETN
+LSYM(e_4t0a0)	a1_ne_0_b_l0
+	t0__4t0_a0
+	MILLIRET
+	r__r_t0
+LSYM(e4t08a0)	t0__t0_2a0
+	a1_ne_0_b_l1
+	r__r_4t0
+	MILLIRETN
+LSYM(e_5t0)	a1_ne_0_b_l0
+	t0__5t0
+	MILLIRET
+	r__r_t0
+LSYM(e_8t0)	a1_ne_0_b_l1
+	r__r_8t0
+	MILLIRETN
+LSYM(e_8t0a0)	a1_ne_0_b_l0
+	t0__8t0_a0
+	MILLIRET
+	r__r_t0
+
+	.procend
+	.end
+#endif
diff --git a/arch/parisc/lib/milli/remI.S b/arch/parisc/lib/milli/remI.S
new file mode 100644
index 0000000..63bc094
--- /dev/null
+++ b/arch/parisc/lib/milli/remI.S
@@ -0,0 +1,185 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_remI
+/* ROUTINE:	$$remI
+
+   DESCRIPTION:
+   .	$$remI returns the remainder of the division of two signed 32-bit
+   .	integers.  The sign of the remainder is the same as the sign of
+   .	the dividend.
+
+
+   INPUT REGISTERS:
+   .	arg0 == dividend
+   .	arg1 == divisor
+   .	mrp  == return pc
+   .	sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .	arg0 = destroyed
+   .	arg1 = destroyed
+   .	ret1 = remainder
+
+   OTHER REGISTERS AFFECTED:
+   .	r1   = undefined
+
+   SIDE EFFECTS:
+   .	Causes a trap under the following conditions:  DIVIDE BY ZERO
+   .	Changes memory at the following places:  NONE
+
+   PERMISSIBLE CONTEXT:
+   .	Unwindable
+   .	Does not create a stack frame
+   .	Is usable for internal or external microcode
+
+   DISCUSSION:
+   .	Calls other millicode routines via mrp:  NONE
+   .	Calls other millicode routines:  NONE  */
+
+RDEFINE(tmp,r1)
+RDEFINE(retreg,ret1)
+
+	SUBSPA_MILLI
+	ATTR_MILLI
+	.proc
+	.callinfo millicode
+	.entry
+GSYM($$remI)
+GSYM($$remoI)
+	.export $$remI,MILLICODE
+	.export $$remoI,MILLICODE
+	ldo		-1(arg1),tmp		/*  is there at most one bit set ? */
+	and,<>		arg1,tmp,r0		/*  if not, don't use power of 2 */
+	addi,>		0,arg1,r0		/*  if denominator > 0, use power */
+						/*  of 2 */
+	b,n		LREF(neg_denom)
+LSYM(pow2)
+	comb,>,n	0,arg0,LREF(neg_num)	/*  is numerator < 0 ? */
+	and		arg0,tmp,retreg		/*  get the result */
+	MILLIRETN
+LSYM(neg_num)
+	subi		0,arg0,arg0		/*  negate numerator */
+	and		arg0,tmp,retreg		/*  get the result */
+	subi		0,retreg,retreg		/*  negate result */
+	MILLIRETN
+LSYM(neg_denom)
+	addi,<		0,arg1,r0		/*  if arg1 >= 0, it's not power */
+						/*  of 2 */
+	b,n		LREF(regular_seq)
+	sub		r0,arg1,tmp		/*  make denominator positive */
+	comb,=,n	arg1,tmp,LREF(regular_seq) /*  test against 0x80000000 and 0 */
+	ldo		-1(tmp),retreg		/*  is there at most one bit set ? */
+	and,=		tmp,retreg,r0		/*  if not, go to regular_seq */
+	b,n		LREF(regular_seq)
+	comb,>,n	0,arg0,LREF(neg_num_2)	/*  if arg0 < 0, negate it  */
+	and		arg0,retreg,retreg
+	MILLIRETN
+LSYM(neg_num_2)
+	subi		0,arg0,tmp		/*  test against 0x80000000 */
+	and		tmp,retreg,retreg
+	subi		0,retreg,retreg
+	MILLIRETN
+LSYM(regular_seq)
+	addit,=		0,arg1,0		/*  trap if div by zero */
+	add,>=		0,arg0,retreg		/*  move dividend, if retreg < 0, */
+	sub		0,retreg,retreg		/*    make it positive */
+	sub		0,arg1, tmp		/*  clear carry,  */
+						/*    negate the divisor */
+	ds		0, tmp,0		/*  set V-bit to the comple- */
+						/*    ment of the divisor sign */
+	or		0,0, tmp		/*  clear  tmp */
+	add		retreg,retreg,retreg	/*  shift msb bit into carry */
+	ds		 tmp,arg1, tmp		/*  1st divide step, if no carry */
+						/*    out, msb of quotient = 0 */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+LSYM(t1)
+	ds		 tmp,arg1, tmp		/*  2nd divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  3rd divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  4th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  5th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  6th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  7th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  8th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  9th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  10th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  11th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  12th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  13th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  14th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  15th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  16th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  17th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  18th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  19th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  20th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  21st divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  22nd divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  23rd divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  24th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  25th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  26th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  27th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  28th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  29th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  30th divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  31st divide step */
+	addc		retreg,retreg,retreg	/*  shift retreg with/into carry */
+	ds		 tmp,arg1, tmp		/*  32nd divide step, */
+	addc		retreg,retreg,retreg	/*  shift last bit into retreg */
+	movb,>=,n	 tmp,retreg,LREF(finish) /*  branch if pos.  tmp */
+	add,<		arg1,0,0		/*  if arg1 > 0, add arg1 */
+	add,tr		 tmp,arg1,retreg	/*    for correcting remainder tmp */
+	sub		 tmp,arg1,retreg	/*  else add absolute value arg1 */
+LSYM(finish)
+	add,>=		arg0,0,0		/*  set sign of remainder */
+	sub		0,retreg,retreg		/*    to sign of dividend */
+	MILLIRET
+	nop
+	.exit
+	.procend
+#ifdef milliext
+	.origin 0x00000200
+#endif
+	.end
+#endif
diff --git a/arch/parisc/lib/milli/remU.S b/arch/parisc/lib/milli/remU.S
new file mode 100644
index 0000000..c0a2d6e
--- /dev/null
+++ b/arch/parisc/lib/milli/remU.S
@@ -0,0 +1,148 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+   adapted for gcc by Paul Bame <bame@debian.org>
+   and Alan Modra <alan@linuxcare.com.au>.
+
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   This file is part of GCC and is released under the terms of
+   of the GNU General Public License as published by the Free Software
+   Foundation; either version 2, or (at your option) any later version.
+   See the file COPYING in the top-level GCC source directory for a copy
+   of the license.  */
+
+#include "milli.h"
+
+#ifdef L_remU
+/* ROUTINE:	$$remU
+   .	Single precision divide for remainder with unsigned binary integers.
+   .
+   .	The remainder must be dividend-(dividend/divisor)*divisor.
+   .	Divide by zero is trapped.
+
+   INPUT REGISTERS:
+   .	arg0 ==	dividend
+   .	arg1 == divisor
+   .	mrp  == return pc
+   .	sr0  == return space when called externally
+
+   OUTPUT REGISTERS:
+   .	arg0 =	undefined
+   .	arg1 =	undefined
+   .	ret1 =	remainder
+
+   OTHER REGISTERS AFFECTED:
+   .	r1   =	undefined
+
+   SIDE EFFECTS:
+   .	Causes a trap under the following conditions:  DIVIDE BY ZERO
+   .	Changes memory at the following places:  NONE
+
+   PERMISSIBLE CONTEXT:
+   .	Unwindable.
+   .	Does not create a stack frame.
+   .	Suitable for internal or external millicode.
+   .	Assumes the special millicode register conventions.
+
+   DISCUSSION:
+   .	Calls other millicode routines using mrp: NONE
+   .	Calls other millicode routines: NONE  */
+
+
+RDEFINE(temp,r1)
+RDEFINE(rmndr,ret1)	/*  r29 */
+	SUBSPA_MILLI
+	ATTR_MILLI
+	.export $$remU,millicode
+	.proc
+	.callinfo	millicode
+	.entry
+GSYM($$remU)
+	ldo	-1(arg1),temp		/*  is there at most one bit set ? */
+	and,=	arg1,temp,r0		/*  if not, don't use power of 2 */
+	b	LREF(regular_seq)
+	addit,=	0,arg1,r0		/*  trap on div by zero */
+	and	arg0,temp,rmndr		/*  get the result for power of 2 */
+	MILLIRETN
+LSYM(regular_seq)
+	comib,>=,n  0,arg1,LREF(special_case)
+	subi	0,arg1,rmndr		/*  clear carry, negate the divisor */
+	ds	r0,rmndr,r0		/*  set V-bit to 1 */
+	add	arg0,arg0,temp		/*  shift msb bit into carry */
+	ds	r0,arg1,rmndr		/*  1st divide step, if no carry */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  2nd divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  3rd divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  4th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  5th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  6th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  7th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  8th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  9th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  10th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  11th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  12th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  13th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  14th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  15th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  16th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  17th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  18th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  19th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  20th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  21st divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  22nd divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  23rd divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  24th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  25th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  26th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  27th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  28th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  29th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  30th divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  31st divide step */
+	addc	temp,temp,temp		/*  shift temp with/into carry */
+	ds	rmndr,arg1,rmndr		/*  32nd divide step, */
+	comiclr,<= 0,rmndr,r0
+	  add	rmndr,arg1,rmndr	/*  correction */
+	MILLIRETN
+	nop
+
+/* Putting >= on the last DS and deleting COMICLR does not work!  */
+LSYM(special_case)
+	sub,>>=	arg0,arg1,rmndr
+	  copy	arg0,rmndr
+	MILLIRETN
+	nop
+	.exit
+	.procend
+	.end
+#endif
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 1c091b4..b2e3e9a 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -211,7 +211,7 @@
 #ifdef PRINT_USER_FAULTS
 		printk(KERN_DEBUG "\n");
 		printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n",
-		    tsk->pid, tsk->comm, code, address);
+		    task_pid_nr(tsk), tsk->comm, code, address);
 		if (vma) {
 			printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n",
 					vma->vm_start, vma->vm_end);
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index e724b36..aa875fa 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -607,7 +607,7 @@
 
 				printk("Zone list for zone %d on node %d: ", j, i);
 				for (k = 0; zl->zones[k] != NULL; k++) 
-					printk("[%ld/%s] ", zone_to_nid(zl->zones[k]), zl->zones[k]->name);
+					printk("[%d/%s] ", zone_to_nid(zl->zones[k]), zl->zones[k]->name);
 				printk("\n");
 			}
 		}
diff --git a/arch/parisc/oprofile/Kconfig b/arch/parisc/oprofile/Kconfig
deleted file mode 100644
index 5ade198..0000000
--- a/arch/parisc/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-	  
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
-endmenu
-
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 3763f68..18f397ca 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -669,20 +669,7 @@
 
 source "lib/Kconfig"
 
-menu "Instrumentation Support"
-
-source "arch/powerpc/oprofile/Kconfig"
-
-config KPROBES
-	bool "Kprobes"
-	depends on !BOOKE && !4xx && KALLSYMS && MODULES
-	help
-	  Kprobes allows you to trap at almost any kernel address and
-	  execute a callback function.  register_kprobe() establishes
-	  a probepoint and specifies the callback.  Kprobes is useful
-	  for kernel debugging, non-intrusive instrumentation and testing.
-	  If in doubt, say "N".
-endmenu
+source "kernel/Kconfig.instrumentation"
 
 source "arch/powerpc/Kconfig.debug"
 
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index c939fe8..6a79fe4 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -216,7 +216,6 @@
 config PPC_EARLY_DEBUG_44x
 	bool "Early serial debugging for IBM/AMCC 44x CPUs"
 	depends on 44x
-	select PPC_UDBG_16550
 	help
 	  Select this to enable early debugging for IBM 44x chips via the
 	  inbuilt serial port.
diff --git a/arch/powerpc/boot/dts/bamboo.dts b/arch/powerpc/boot/dts/bamboo.dts
index a88ae3d..cb2fb50 100644
--- a/arch/powerpc/boot/dts/bamboo.dts
+++ b/arch/powerpc/boot/dts/bamboo.dts
@@ -98,11 +98,13 @@
 			interrupt-parent = <&MAL0>;
 			interrupts = <0 1 2 3 4>;
 			#interrupt-cells = <1>;
+			#address-cells = <0>;
+			#size-cells = <0>;
 			interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
 					/*RXEOB*/ 1 &UIC0 b 4
 					/*SERR*/  2 &UIC1 0 4
 					/*TXDE*/  3 &UIC1 1 4
-					/*RXDE*/  4 &UIC1 3 4>;
+					/*RXDE*/  4 &UIC1 2 4>;
 		};
 
 		POB0: opb {
@@ -196,6 +198,7 @@
 			};
 
 			EMAC0: ethernet@ef600e00 {
+				linux,network-index = <0>;
 				device_type = "network";
 				compatible = "ibm,emac-440ep", "ibm,emac-440gp", "ibm,emac";
 				interrupt-parent = <&UIC1>;
@@ -210,12 +213,13 @@
 				rx-fifo-size = <1000>;
 				tx-fifo-size = <800>;
 				phy-mode = "rmii";
-				phy-map = <00000001>;
+				phy-map = <00000000>;
 				zmii-device = <&ZMII0>;
 				zmii-channel = <0>;
 			};
 
 			EMAC1: ethernet@ef600f00 {
+				linux,network-index = <1>;
 				device_type = "network";
 				compatible = "ibm,emac-440ep", "ibm,emac-440gp", "ibm,emac";
 				interrupt-parent = <&UIC1>;
@@ -230,7 +234,7 @@
 				rx-fifo-size = <1000>;
 				tx-fifo-size = <800>;
 				phy-mode = "rmii";
-				phy-map = <00000001>;
+				phy-map = <00000000>;
 				zmii-device = <&ZMII0>;
 				zmii-channel = <1>;
 			};
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts
index bc45f5f..6731763 100644
--- a/arch/powerpc/boot/dts/lite5200.dts
+++ b/arch/powerpc/boot/dts/lite5200.dts
@@ -70,18 +70,16 @@
 		};
 
 		gpt@600 {	// General Purpose Timer
-			compatible = "mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200-gpt";
 			cell-index = <0>;
 			reg = <600 10>;
 			interrupts = <1 9 0>;
 			interrupt-parent = <&mpc5200_pic>;
-			has-wdt;
+			fsl,has-wdt;
 		};
 
 		gpt@610 {	// General Purpose Timer
-			compatible = "mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200-gpt";
 			cell-index = <1>;
 			reg = <610 10>;
 			interrupts = <1 a 0>;
@@ -89,8 +87,7 @@
 		};
 
 		gpt@620 {	// General Purpose Timer
-			compatible = "mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200-gpt";
 			cell-index = <2>;
 			reg = <620 10>;
 			interrupts = <1 b 0>;
@@ -98,8 +95,7 @@
 		};
 
 		gpt@630 {	// General Purpose Timer
-			compatible = "mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200-gpt";
 			cell-index = <3>;
 			reg = <630 10>;
 			interrupts = <1 c 0>;
@@ -107,8 +103,7 @@
 		};
 
 		gpt@640 {	// General Purpose Timer
-			compatible = "mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200-gpt";
 			cell-index = <4>;
 			reg = <640 10>;
 			interrupts = <1 d 0>;
@@ -116,8 +111,7 @@
 		};
 
 		gpt@650 {	// General Purpose Timer
-			compatible = "mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200-gpt";
 			cell-index = <5>;
 			reg = <650 10>;
 			interrupts = <1 e 0>;
@@ -125,8 +119,7 @@
 		};
 
 		gpt@660 {	// General Purpose Timer
-			compatible = "mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200-gpt";
 			cell-index = <6>;
 			reg = <660 10>;
 			interrupts = <1 f 0>;
@@ -134,8 +127,7 @@
 		};
 
 		gpt@670 {	// General Purpose Timer
-			compatible = "mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200-gpt";
 			cell-index = <7>;
 			reg = <670 10>;
 			interrupts = <1 10 0>;
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts
index 6582c9a..b540388 100644
--- a/arch/powerpc/boot/dts/lite5200b.dts
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -70,18 +70,16 @@
 		};
 
 		gpt@600 {	// General Purpose Timer
-			compatible = "mpc5200b-gpt","mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			cell-index = <0>;
 			reg = <600 10>;
 			interrupts = <1 9 0>;
 			interrupt-parent = <&mpc5200_pic>;
-			has-wdt;
+			fsl,has-wdt;
 		};
 
 		gpt@610 {	// General Purpose Timer
-			compatible = "mpc5200b-gpt","mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			cell-index = <1>;
 			reg = <610 10>;
 			interrupts = <1 a 0>;
@@ -89,8 +87,7 @@
 		};
 
 		gpt@620 {	// General Purpose Timer
-			compatible = "mpc5200b-gpt","mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			cell-index = <2>;
 			reg = <620 10>;
 			interrupts = <1 b 0>;
@@ -98,8 +95,7 @@
 		};
 
 		gpt@630 {	// General Purpose Timer
-			compatible = "mpc5200b-gpt","mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			cell-index = <3>;
 			reg = <630 10>;
 			interrupts = <1 c 0>;
@@ -107,8 +103,7 @@
 		};
 
 		gpt@640 {	// General Purpose Timer
-			compatible = "mpc5200b-gpt","mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			cell-index = <4>;
 			reg = <640 10>;
 			interrupts = <1 d 0>;
@@ -116,8 +111,7 @@
 		};
 
 		gpt@650 {	// General Purpose Timer
-			compatible = "mpc5200b-gpt","mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			cell-index = <5>;
 			reg = <650 10>;
 			interrupts = <1 e 0>;
@@ -125,8 +119,7 @@
 		};
 
 		gpt@660 {	// General Purpose Timer
-			compatible = "mpc5200b-gpt","mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			cell-index = <6>;
 			reg = <660 10>;
 			interrupts = <1 f 0>;
@@ -134,8 +127,7 @@
 		};
 
 		gpt@670 {	// General Purpose Timer
-			compatible = "mpc5200b-gpt","mpc5200-gpt";
-			device_type = "gpt";
+			compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
 			cell-index = <7>;
 			reg = <670 10>;
 			interrupts = <1 10 0>;
diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts
index 36be75b..8833dfe 100644
--- a/arch/powerpc/boot/dts/sequoia.dts
+++ b/arch/powerpc/boot/dts/sequoia.dts
@@ -241,6 +241,12 @@
 				reg = <ef600d00 c>;
 			};
 
+			RGMII0: emac-rgmii@ef601000 {
+				device_type = "rgmii-interface";
+				compatible = "ibm,rgmii-440epx", "ibm,rgmii";
+				reg = <ef601000 8>;
+			};
+
 			EMAC0: ethernet@ef600e00 {
 				linux,network-index = <0>;
 				device_type = "network";
@@ -261,10 +267,12 @@
 				max-frame-size = <5dc>;
 				rx-fifo-size = <1000>;
 				tx-fifo-size = <800>;
-				phy-mode = "rmii";
+				phy-mode = "rgmii";
 				phy-map = <00000000>;
 				zmii-device = <&ZMII0>;
 				zmii-channel = <0>;
+				rgmii-device = <&RGMII0>;
+				rgmii-channel = <0>;
 			};
 
 			EMAC1: ethernet@ef600f00 {
@@ -287,10 +295,12 @@
 				max-frame-size = <5dc>;
 				rx-fifo-size = <1000>;
 				tx-fifo-size = <800>;
-				phy-mode = "rmii";
+				phy-mode = "rgmii";
 				phy-map = <00000000>;
 				zmii-device = <&ZMII0>;
 				zmii-channel = <1>;
+				rgmii-device = <&RGMII0>;
+				rgmii-channel = <1>;
 			};
 		};
 	};
diff --git a/arch/powerpc/boot/dts/walnut.dts b/arch/powerpc/boot/dts/walnut.dts
index ec54f4e..fa681f5 100644
--- a/arch/powerpc/boot/dts/walnut.dts
+++ b/arch/powerpc/boot/dts/walnut.dts
@@ -64,10 +64,15 @@
 		MAL: mcmal {
 			compatible = "ibm,mcmal-405gp", "ibm,mcmal";
 			dcr-reg = <180 62>;
-			num-tx-chans = <2>;
+			num-tx-chans = <1>;
 			num-rx-chans = <1>;
 			interrupt-parent = <&UIC0>;
-			interrupts = <a 4 b 4 c 4 d 4 e 4>;
+			interrupts = <
+				b 4 /* TXEOB */
+				c 4 /* RXEOB */
+				a 4 /* SERR */
+				d 4 /* TXDE */
+				e 4 /* RXDE */>;
 		};
 
 		POB0: opb {
@@ -118,9 +123,10 @@
 				compatible = "ibm,emac-405gp", "ibm,emac";
 				interrupt-parent = <&UIC0>;
 				interrupts = <9 4 f 4>;
+				local-mac-address = [000000000000]; /* Filled in by zImage */
 				reg = <ef600800 70>;
 				mal-device = <&MAL>;
-				mal-tx-channel = <0 1>;
+				mal-tx-channel = <0>;
 				mal-rx-channel = <0>;
 				cell-index = <0>;
 				max-frame-size = <5dc>;
diff --git a/arch/powerpc/boot/treeboot-walnut.c b/arch/powerpc/boot/treeboot-walnut.c
index 3adf2d0..bb2c309 100644
--- a/arch/powerpc/boot/treeboot-walnut.c
+++ b/arch/powerpc/boot/treeboot-walnut.c
@@ -57,8 +57,8 @@
 	}
 
 	/* setup the timebase clock to tick at the cpu frequency */
-	cpc0_cr1 = cpc0_cr1 & ~ 0x00800000;
-	mtdcr(DCRN_CPC0_CR1, cpc0_cr1);
+	cpc0_cr1 = cpc0_cr1 & ~0x00800000;
+	mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1);
 	tb = cpu;
 
 	dt_fixup_cpu_clocks(cpu, tb, 0);
@@ -109,6 +109,7 @@
 	setprop(sram, "reg", reg_sram, sizeof(reg_sram));
 }
 
+#define WALNUT_OPENBIOS_MAC_OFF 0xfffffe0b
 static void walnut_fixups(void)
 {
 	ibm4xx_fixup_memsize();
@@ -116,6 +117,7 @@
 	ibm4xx_quiesce_eth((u32 *)0xef600800, NULL);
 	ibm4xx_fixup_ebc_ranges("/plb/ebc");
 	walnut_flashsel_fixup();
+	dt_fixup_mac_addresses((u8 *) WALNUT_OPENBIOS_MAC_OFF);
 }
 
 void platform_init(void)
diff --git a/arch/powerpc/configs/bamboo_defconfig b/arch/powerpc/configs/bamboo_defconfig
index d22fed6..844808e 100644
--- a/arch/powerpc/configs/bamboo_defconfig
+++ b/arch/powerpc/configs/bamboo_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc1
-# Fri Aug  3 10:46:53 2007
+# Linux kernel version: 2.6.23
+# Fri Oct 19 09:01:11 2007
 #
 # CONFIG_PPC64 is not set
 
@@ -22,8 +22,13 @@
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -67,6 +72,8 @@
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -87,7 +94,6 @@
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
@@ -133,6 +139,7 @@
 # CONFIG_PQ2ADS is not set
 CONFIG_BAMBOO=y
 # CONFIG_EBONY is not set
+# CONFIG_SEQUOIA is not set
 CONFIG_440EP=y
 CONFIG_IBM440EP_ERR42=y
 # CONFIG_MPIC is not set
@@ -146,11 +153,16 @@
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
 # CONFIG_CPM2 is not set
+# CONFIG_FSL_ULI1575 is not set
 
 #
 # Kernel options
 #
 # CONFIG_HIGHMEM is not set
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
@@ -172,6 +184,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
@@ -197,10 +210,6 @@
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
 # CONFIG_PCI_DEBUG is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -215,7 +224,7 @@
 CONFIG_HIGHMEM_START=0xfe000000
 CONFIG_LOWMEM_SIZE=0x30000000
 CONFIG_KERNEL_START=0xc0000000
-CONFIG_TASK_SIZE=0x80000000
+CONFIG_TASK_SIZE=0xc0000000
 CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_BOOT_LOAD=0x01000000
@@ -252,6 +261,7 @@
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -309,6 +319,7 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -353,10 +364,6 @@
 # CONFIG_SCSI_NETLINK is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
 # CONFIG_FUSION is not set
 
 #
@@ -375,12 +382,36 @@
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
-# CONFIG_NET_ETHERNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=128
+CONFIG_IBM_NEW_EMAC_TXB=64
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -388,6 +419,7 @@
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -396,11 +428,14 @@
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
 # CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
 # CONFIG_TR is not set
 
 #
@@ -463,14 +498,11 @@
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_NVRAM is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
@@ -484,6 +516,13 @@
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -500,16 +539,17 @@
 #
 # Graphics support
 #
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-# CONFIG_FB is not set
-# CONFIG_FB_IBM_GXT4500 is not set
 
 #
 # Sound
@@ -536,19 +576,6 @@
 # CONFIG_RTC_CLASS is not set
 
 #
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
 # Userspace I/O
 #
 # CONFIG_UIO is not set
@@ -600,7 +627,6 @@
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -619,10 +645,7 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -648,15 +671,7 @@
 #
 # 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
 # CONFIG_UCC_SLOW is not set
 
@@ -709,6 +724,7 @@
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
@@ -728,6 +744,7 @@
 # CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
 # CONFIG_PPC_EARLY_DEBUG_BEAT is not set
 CONFIG_PPC_EARLY_DEBUG_44x=y
+# CONFIG_PPC_EARLY_DEBUG_CPM is not set
 CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300
 CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x0
 
@@ -736,6 +753,7 @@
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=y
@@ -755,6 +773,7 @@
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_PCBC=y
 # CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
@@ -768,9 +787,12 @@
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index 8b47c84..dcd7c02 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -68,6 +68,7 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=15
+CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
diff --git a/arch/powerpc/configs/ebony_defconfig b/arch/powerpc/configs/ebony_defconfig
index 35a95dd..d3ef642 100644
--- a/arch/powerpc/configs/ebony_defconfig
+++ b/arch/powerpc/configs/ebony_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc4
-# Thu Aug 30 16:34:11 2007
+# Linux kernel version: 2.6.23
+# Thu Oct 18 08:01:57 2007
 #
 # CONFIG_PPC64 is not set
 
@@ -21,8 +21,13 @@
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -66,6 +71,8 @@
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -86,7 +93,6 @@
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
@@ -130,7 +136,9 @@
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+# CONFIG_BAMBOO is not set
 CONFIG_EBONY=y
+# CONFIG_SEQUOIA is not set
 CONFIG_440GP=y
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
@@ -149,6 +157,10 @@
 # Kernel options
 #
 # CONFIG_HIGHMEM is not set
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
@@ -170,6 +182,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
@@ -194,10 +207,6 @@
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
 # CONFIG_PCI_DEBUG is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -212,7 +221,7 @@
 CONFIG_HIGHMEM_START=0xfe000000
 CONFIG_LOWMEM_SIZE=0x30000000
 CONFIG_KERNEL_START=0xc0000000
-CONFIG_TASK_SIZE=0x80000000
+CONFIG_TASK_SIZE=0xc0000000
 CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_BOOT_LOAD=0x01000000
@@ -249,6 +258,7 @@
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -306,6 +316,7 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -332,6 +343,7 @@
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -364,6 +376,7 @@
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -423,10 +436,6 @@
 # CONFIG_SCSI_NETLINK is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
 # CONFIG_FUSION is not set
 
 #
@@ -443,12 +452,36 @@
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
-# CONFIG_NET_ETHERNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=128
+CONFIG_IBM_NEW_EMAC_TXB=64
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -456,6 +489,7 @@
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
@@ -464,11 +498,14 @@
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
 # CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
 # CONFIG_TR is not set
 
 #
@@ -537,8 +574,6 @@
 # CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
@@ -554,6 +589,12 @@
 # CONFIG_HWMON is not set
 
 #
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
 # Multifunction device drivers
 #
 # CONFIG_MFD_SM501 is not set
@@ -568,16 +609,17 @@
 #
 # Graphics support
 #
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_FB_IBM_GXT4500 is not set
 
 #
 # Sound
@@ -604,19 +646,6 @@
 # CONFIG_RTC_CLASS is not set
 
 #
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
 # Userspace I/O
 #
 # CONFIG_UIO is not set
@@ -668,7 +697,6 @@
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -684,10 +712,12 @@
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
 # CONFIG_JFFS2_SUMMARY is not set
 # CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
@@ -696,10 +726,7 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -725,15 +752,7 @@
 #
 # 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
 # CONFIG_UCC_SLOW is not set
 
@@ -787,6 +806,7 @@
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
@@ -801,6 +821,7 @@
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=y
@@ -820,6 +841,7 @@
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_PCBC=y
 # CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
@@ -833,9 +855,12 @@
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig
index 95b823b..8e5988c 100644
--- a/arch/powerpc/configs/pmac32_defconfig
+++ b/arch/powerpc/configs/pmac32_defconfig
@@ -209,7 +209,6 @@
 # CONFIG_PM_LEGACY is not set
 CONFIG_PM_DEBUG=y
 # CONFIG_PM_VERBOSE is not set
-# CONFIG_DISABLE_CONSOLE_SUSPEND is not set
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_HIBERNATION=y
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index bb8d4e4..05582af 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -71,6 +71,7 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index c09eb8c..62a3840 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -71,6 +71,7 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
diff --git a/arch/powerpc/configs/walnut_defconfig b/arch/powerpc/configs/walnut_defconfig
index 7724292..02896ec 100644
--- a/arch/powerpc/configs/walnut_defconfig
+++ b/arch/powerpc/configs/walnut_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc4
-# Wed Sep  5 12:06:37 2007
+# Linux kernel version: 2.6.23
+# Thu Oct 18 12:54:18 2007
 #
 # CONFIG_PPC64 is not set
 
@@ -18,8 +18,13 @@
 # CONFIG_PPC_MM_SLICES is not set
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
 CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -63,6 +68,8 @@
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -83,7 +90,6 @@
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
@@ -127,7 +133,9 @@
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PQ2ADS is not set
+# CONFIG_KILAUEA is not set
 CONFIG_WALNUT=y
+# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
 CONFIG_405GP=y
 CONFIG_IBM405_ERR77=y
 CONFIG_IBM405_ERR51=y
@@ -148,6 +156,10 @@
 # Kernel options
 #
 # CONFIG_HIGHMEM is not set
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
@@ -169,6 +181,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
@@ -177,6 +190,8 @@
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_HIBERNATION_UP_POSSIBLE=y
 CONFIG_SECCOMP=y
 CONFIG_WANT_DEVICE_TREE=y
 CONFIG_DEVICE_TREE="walnut.dts"
@@ -190,10 +205,6 @@
 # CONFIG_PCI_DOMAINS is not set
 # CONFIG_PCI_SYSCALL is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
 # CONFIG_PCCARD is not set
 
 #
@@ -207,7 +218,7 @@
 CONFIG_HIGHMEM_START=0xfe000000
 CONFIG_LOWMEM_SIZE=0x30000000
 CONFIG_KERNEL_START=0xc0000000
-CONFIG_TASK_SIZE=0x80000000
+CONFIG_TASK_SIZE=0xc0000000
 CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_BOOT_LOAD=0x00400000
@@ -244,6 +255,7 @@
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -301,6 +313,7 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -328,6 +341,7 @@
 # CONFIG_INFTL is not set
 # CONFIG_RFD_FTL is not set
 # CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -360,7 +374,6 @@
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_PHYSMAP_OF=y
-# CONFIG_MTD_WALNUT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -419,7 +432,22 @@
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_NET_ETHERNET is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=128
+CONFIG_IBM_NEW_EMAC_TXB=64
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 
@@ -498,6 +526,12 @@
 # CONFIG_HWMON is not set
 
 #
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
 # Multifunction device drivers
 #
 # CONFIG_MFD_SM501 is not set
@@ -512,16 +546,15 @@
 #
 # Graphics support
 #
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-# CONFIG_FB is not set
-# CONFIG_FB_IBM_GXT4500 is not set
 
 #
 # Sound
@@ -546,19 +579,6 @@
 # CONFIG_RTC_CLASS is not set
 
 #
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
 # Userspace I/O
 #
 # CONFIG_UIO is not set
@@ -610,7 +630,6 @@
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -630,10 +649,7 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -659,15 +675,7 @@
 #
 # 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
 # CONFIG_UCC_SLOW is not set
 
@@ -720,6 +728,7 @@
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
@@ -734,6 +743,7 @@
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=y
@@ -753,6 +763,7 @@
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_PCBC=y
 # CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
@@ -766,9 +777,12 @@
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_AUTHENC is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 0ae5d57..2c8e756 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -141,6 +141,7 @@
 	DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr));
 	DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
 	DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
+	DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
 	DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
 	DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
 	DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr));
diff --git a/arch/powerpc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S
index 8b4a4ee..f1ee0b3 100644
--- a/arch/powerpc/kernel/cpu_setup_6xx.S
+++ b/arch/powerpc/kernel/cpu_setup_6xx.S
@@ -113,7 +113,7 @@
  * around #3 and with the same fix we use. We may want to
  * check if the CPU is using 60x bus mode in which case
  * the workaround for errata #4 is useless. Also, we may
- * want to explicitely clear HID0_NOPDST as this is not
+ * want to explicitly clear HID0_NOPDST as this is not
  * needed once we have applied workaround #5 (though it's
  * not set by Apple's firmware at least).
  */
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 9001104..14206e3 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -161,8 +161,7 @@
 	int i;
 
 	for_each_sg(sgl, sg, nents, i) {
-		sg->dma_address = (page_to_phys(sg->page) + sg->offset) |
-			dma_direct_offset;
+		sg->dma_address = sg_phys(sg) | dma_direct_offset;
 		sg->dma_length = sg->length;
 	}
 
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 289d7e9..72fd871 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -102,8 +102,7 @@
 	int i;
 
 	for_each_sg(sgl, sg, nents, i) {
-		sg->dma_address = (dma_addr_t)page_address(sg->page)
-			+ sg->offset;
+		sg->dma_address = (dma_addr_t) sg_virt(sg);
 		sg->dma_length = sg->length;
 	}
 
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 306a6f7..2d0c9ef 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -307,7 +307,7 @@
 			continue;
 		}
 		/* Allocate iommu entries for that segment */
-		vaddr = (unsigned long)page_address(s->page) + s->offset;
+		vaddr = (unsigned long) sg_virt(s);
 		npages = iommu_num_pages(vaddr, slen);
 		entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0);
 
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 2250f9e..b0e5deb 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -491,7 +491,7 @@
 
 			/* Legacy flags are left to default at this point,
 			 * one can then use irq_create_mapping() to
-			 * explicitely change them
+			 * explicitly change them
 			 */
 			ops->map(host, i, i);
 		}
diff --git a/arch/powerpc/kernel/l2cr_6xx.S b/arch/powerpc/kernel/l2cr_6xx.S
index 858f28a..2a2f3c3 100644
--- a/arch/powerpc/kernel/l2cr_6xx.S
+++ b/arch/powerpc/kernel/l2cr_6xx.S
@@ -1,6 +1,6 @@
 /*
 	L2CR functions
-	Copyright © 1997-1998 by PowerLogix R & D, Inc.
+	Copyright © 1997-1998 by PowerLogix R & D, 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
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c
index e60a0c5..c0c8e8c 100644
--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -61,45 +61,39 @@
 	for(;;);
 }
 
-static int __init early_parse_crashk(char *p)
-{
-	unsigned long size;
-
-	if (!p)
-		return 1;
-
-	size = memparse(p, &p);
-
-	if (*p == '@')
-		crashk_res.start = memparse(p + 1, &p);
-	else
-		crashk_res.start = KDUMP_KERNELBASE;
-
-	crashk_res.end = crashk_res.start + size - 1;
-
-	return 0;
-}
-early_param("crashkernel", early_parse_crashk);
-
 void __init reserve_crashkernel(void)
 {
-	unsigned long size;
+	unsigned long long crash_size, crash_base;
+	int ret;
 
-	if (crashk_res.start == 0)
+	/* this is necessary because of lmb_phys_mem_size() */
+	lmb_analyze();
+
+	/* use common parsing */
+	ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(),
+			&crash_size, &crash_base);
+	if (ret == 0 && crash_size > 0) {
+		if (crash_base == 0)
+			crash_base = KDUMP_KERNELBASE;
+		crashk_res.start = crash_base;
+	} else {
+		/* handle the device tree */
+		crash_size = crashk_res.end - crashk_res.start + 1;
+	}
+
+	if (crash_size == 0)
 		return;
 
 	/* We might have got these values via the command line or the
 	 * device tree, either way sanitise them now. */
 
-	size = crashk_res.end - crashk_res.start + 1;
-
 	if (crashk_res.start != KDUMP_KERNELBASE)
 		printk("Crash kernel location must be 0x%x\n",
 				KDUMP_KERNELBASE);
 
 	crashk_res.start = KDUMP_KERNELBASE;
-	size = PAGE_ALIGN(size);
-	crashk_res.end = crashk_res.start + size - 1;
+	crash_size = PAGE_ALIGN(crash_size);
+	crashk_res.end = crashk_res.start + crash_size - 1;
 
 	/* Crash kernel trumps memory limit */
 	if (memory_limit && memory_limit <= crashk_res.end) {
@@ -108,7 +102,13 @@
 				memory_limit);
 	}
 
-	lmb_reserve(crashk_res.start, size);
+	printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+			"for crashkernel (System RAM: %ldMB)\n",
+			(unsigned long)(crash_size >> 20),
+			(unsigned long)(crashk_res.start >> 20),
+			(unsigned long)(lmb_phys_mem_size() >> 20));
+
+	lmb_reserve(crashk_res.start, crash_size);
 }
 
 int overlaps_crashkernel(unsigned long start, unsigned long size)
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index ea6ad7a..b9d8837 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -459,7 +459,7 @@
 		printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
 #endif
 	printk("TASK = %p[%d] '%s' THREAD: %p",
-	       current, current->pid, current->comm, task_thread_info(current));
+	       current, task_pid_nr(current), current->comm, task_thread_info(current));
 
 #ifdef CONFIG_SMP
 	printk(" CPU: %d", smp_processor_id());
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 863a5d6..9eb3284 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -212,23 +212,44 @@
 }
 
 /*
+ * Read the SPURR on systems that have it, otherwise the purr
+ */
+static u64 read_spurr(u64 purr)
+{
+	if (cpu_has_feature(CPU_FTR_SPURR))
+		return mfspr(SPRN_SPURR);
+	return purr;
+}
+
+/*
  * Account time for a transition between system, hard irq
  * or soft irq state.
  */
 void account_system_vtime(struct task_struct *tsk)
 {
-	u64 now, delta;
+	u64 now, nowscaled, delta, deltascaled;
 	unsigned long flags;
 
 	local_irq_save(flags);
 	now = read_purr();
 	delta = now - get_paca()->startpurr;
 	get_paca()->startpurr = now;
+	nowscaled = read_spurr(now);
+	deltascaled = nowscaled - get_paca()->startspurr;
+	get_paca()->startspurr = nowscaled;
 	if (!in_interrupt()) {
+		/* deltascaled includes both user and system time.
+		 * Hence scale it based on the purr ratio to estimate
+		 * the system time */
+		deltascaled = deltascaled * get_paca()->system_time /
+			(get_paca()->system_time + get_paca()->user_time);
 		delta += get_paca()->system_time;
 		get_paca()->system_time = 0;
 	}
 	account_system_time(tsk, 0, delta);
+	get_paca()->purrdelta = delta;
+	account_system_time_scaled(tsk, deltascaled);
+	get_paca()->spurrdelta = deltascaled;
 	local_irq_restore(flags);
 }
 
@@ -240,11 +261,17 @@
  */
 void account_process_vtime(struct task_struct *tsk)
 {
-	cputime_t utime;
+	cputime_t utime, utimescaled;
 
 	utime = get_paca()->user_time;
 	get_paca()->user_time = 0;
 	account_user_time(tsk, utime);
+
+	/* Estimate the scaled utime by scaling the real utime based
+	 * on the last spurr to purr ratio */
+	utimescaled = utime * get_paca()->spurrdelta / get_paca()->purrdelta;
+	get_paca()->spurrdelta = get_paca()->purrdelta = 0;
+	account_user_time_scaled(tsk, utimescaled);
 }
 
 static void account_process_time(struct pt_regs *regs)
@@ -266,6 +293,7 @@
 	int	initialized;			/* thread is running */
 	u64	tb;			/* last TB value read */
 	u64	purr;			/* last PURR value read */
+	u64	spurr;			/* last SPURR value read */
 };
 
 /*
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index bf9e39c..59c464e 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -201,7 +201,7 @@
 	 * generate the same exception over and over again and we get
 	 * nowhere.  Better to kill it and let the kernel panic.
 	 */
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		__sighandler_t handler;
 
 		spin_lock_irq(&current->sighand->siglock);
@@ -881,7 +881,7 @@
 void trace_syscall(struct pt_regs *regs)
 {
 	printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
-	       current, current->pid, regs->nip, regs->link, regs->gpr[0],
+	       current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0],
 	       regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
 }
 
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index ab3546c..a18fda3 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -375,7 +375,7 @@
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
diff --git a/arch/powerpc/oprofile/Kconfig b/arch/powerpc/oprofile/Kconfig
deleted file mode 100644
index 7089e79..0000000
--- a/arch/powerpc/oprofile/Kconfig
+++ /dev/null
@@ -1,24 +0,0 @@
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
-config OPROFILE_CELL
-	bool "OProfile for Cell Broadband Engine"
-	depends on (SPU_FS = y && OPROFILE = m) || (SPU_FS = y && OPROFILE = y) || (SPU_FS = m && OPROFILE = m)
-	default y
-	help
-	  Profiling of Cell BE SPUs requires special support enabled
-	  by this option.
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
index 47b3b0a..8f6699f 100644
--- a/arch/powerpc/platforms/40x/Kconfig
+++ b/arch/powerpc/platforms/40x/Kconfig
@@ -100,6 +100,7 @@
 	bool
 	select IBM405_ERR77
 	select IBM405_ERR51
+	select IBM_NEW_EMAC_ZMII
 
 config 405EP
 	bool
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 51f3ea4..8390cc1 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -43,14 +43,14 @@
 	bool
 	select PPC_FPU
 	select IBM440EP_ERR42
-#	select IBM_NEW_EMAC_ZMII
+	select IBM_NEW_EMAC_ZMII
 
 config 440EPX
 	bool
 	select PPC_FPU
-# Disabled until the new EMAC Driver is merged.
-#	select IBM_NEW_EMAC_EMAC4
-#	select IBM_NEW_EMAC_ZMII
+	select IBM_NEW_EMAC_EMAC4
+	select IBM_NEW_EMAC_RGMII
+	select IBM_NEW_EMAC_ZMII
 
 config 440GP
 	bool
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index 65b7ae4..25d2bfa 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -145,6 +145,9 @@
 	/* Some mpc5200 & mpc5200b related configuration */
 	mpc5200_setup_xlb_arbiter();
 
+	/* Map wdt for mpc52xx_restart() */
+	mpc52xx_map_wdt();
+
 #ifdef CONFIG_PM
 	mpc52xx_suspend.board_suspend_prepare = lite5200_suspend_prepare;
 	mpc52xx_suspend.board_resume_finish = lite5200_resume_finish;
@@ -183,5 +186,6 @@
 	.init		= mpc52xx_declare_of_platform_devices,
 	.init_IRQ 	= mpc52xx_init_irq,
 	.get_irq 	= mpc52xx_get_irq,
+	.restart	= mpc52xx_restart,
 	.calibrate_decr	= generic_calibrate_decr,
 };
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c
index f26afcd..ffa14af 100644
--- a/arch/powerpc/platforms/52xx/lite5200_pm.c
+++ b/arch/powerpc/platforms/52xx/lite5200_pm.c
@@ -1,5 +1,5 @@
 #include <linux/init.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <asm/io.h>
 #include <asm/time.h>
 #include <asm/mpc52xx.h>
@@ -18,6 +18,8 @@
 static const int sram_size = 0x4000;	/* 16 kBytes */
 static void __iomem *mbar;
 
+static suspend_state_t lite5200_pm_target_state;
+
 static int lite5200_pm_valid(suspend_state_t state)
 {
 	switch (state) {
@@ -29,13 +31,22 @@
 	}
 }
 
-static int lite5200_pm_prepare(suspend_state_t state)
+static int lite5200_pm_set_target(suspend_state_t state)
+{
+	if (lite5200_pm_valid(state)) {
+		lite5200_pm_target_state = state;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static int lite5200_pm_prepare(void)
 {
 	/* deep sleep? let mpc52xx code handle that */
-	if (state == PM_SUSPEND_STANDBY)
-		return mpc52xx_pm_prepare(state);
+	if (lite5200_pm_target_state == PM_SUSPEND_STANDBY)
+		return mpc52xx_pm_prepare();
 
-	if (state != PM_SUSPEND_MEM)
+	if (lite5200_pm_target_state != PM_SUSPEND_MEM)
 		return -EINVAL;
 
 	/* map registers */
@@ -190,17 +201,16 @@
 	return 0;
 }
 
-static int lite5200_pm_finish(suspend_state_t state)
+static void lite5200_pm_finish(void)
 {
 	/* deep sleep? let mpc52xx code handle that */
-	if (state == PM_SUSPEND_STANDBY) {
-		return mpc52xx_pm_finish(state);
-	}
-	return 0;
+	if (lite5200_pm_target_state == PM_SUSPEND_STANDBY)
+		mpc52xx_pm_finish();
 }
 
-static struct pm_ops lite5200_pm_ops = {
+static struct platform_suspend_ops lite5200_pm_ops = {
 	.valid		= lite5200_pm_valid,
+	.set_target	= lite5200_pm_set_target,
 	.prepare	= lite5200_pm_prepare,
 	.enter		= lite5200_pm_enter,
 	.finish		= lite5200_pm_finish,
@@ -208,6 +218,6 @@
 
 int __init lite5200_pm_init(void)
 {
-	pm_set_ops(&lite5200_pm_ops);
+	suspend_set_ops(&lite5200_pm_ops);
 	return 0;
 }
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 3bc201e..9850685 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -18,15 +18,20 @@
 #include <asm/prom.h>
 #include <asm/mpc52xx.h>
 
+/*
+ * This variable is mapped in mpc52xx_map_wdt() and used in mpc52xx_restart().
+ * Permanent mapping is required because mpc52xx_restart() can be called
+ * from interrupt context while node mapping (which calls ioremap())
+ * cannot be used at such point.
+ */
+static volatile struct mpc52xx_gpt *mpc52xx_wdt = NULL;
 
-void __iomem *
-mpc52xx_find_and_map(const char *compatible)
+static void __iomem *
+mpc52xx_map_node(struct device_node *ofn)
 {
-	struct device_node *ofn;
 	const u32 *regaddr_p;
 	u64 regaddr64, size64;
 
-	ofn = of_find_compatible_node(NULL, NULL, compatible);
 	if (!ofn)
 		return NULL;
 
@@ -42,8 +47,23 @@
 
 	return ioremap((u32)regaddr64, (u32)size64);
 }
+
+void __iomem *
+mpc52xx_find_and_map(const char *compatible)
+{
+	return mpc52xx_map_node(
+		of_find_compatible_node(NULL, NULL, compatible));
+}
+
 EXPORT_SYMBOL(mpc52xx_find_and_map);
 
+void __iomem *
+mpc52xx_find_and_map_path(const char *path)
+{
+	return mpc52xx_map_node(of_find_node_by_path(path));
+}
+
+EXPORT_SYMBOL(mpc52xx_find_and_map_path);
 
 /**
  * 	mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device
@@ -113,3 +133,46 @@
 			"Error while probing of_platform bus\n");
 }
 
+void __init
+mpc52xx_map_wdt(void)
+{
+	const void *has_wdt;
+	struct device_node *np;
+
+	/* mpc52xx_wdt is mapped here and used in mpc52xx_restart,
+	 * possibly from a interrupt context. wdt is only implement
+	 * on a gpt0, so check has-wdt property before mapping.
+	 */
+	for_each_compatible_node(np, NULL, "fsl,mpc5200-gpt") {
+		has_wdt = of_get_property(np, "fsl,has-wdt", NULL);
+		if (has_wdt) {
+			mpc52xx_wdt = mpc52xx_map_node(np);
+			return;
+		}
+	}
+	for_each_compatible_node(np, NULL, "mpc5200-gpt") {
+		has_wdt = of_get_property(np, "has-wdt", NULL);
+		if (has_wdt) {
+			mpc52xx_wdt = mpc52xx_map_node(np);
+			return;
+		}
+	}
+}
+
+void
+mpc52xx_restart(char *cmd)
+{
+	local_irq_disable();
+
+	/* Turn on the watchdog and wait for it to expire.
+	 * It effectively does a reset. */
+	if (mpc52xx_wdt) {
+		out_be32(&mpc52xx_wdt->mode, 0x00000000);
+		out_be32(&mpc52xx_wdt->count, 0x000000ff);
+		out_be32(&mpc52xx_wdt->mode, 0x00009004);
+	} else
+		printk("mpc52xx_restart: Can't access wdt. "
+			"Restart impossible, system halted.\n");
+
+	while (1);
+}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
index ee2e763..7ffa7ba 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
@@ -1,5 +1,5 @@
 #include <linux/init.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/io.h>
 #include <asm/time.h>
 #include <asm/cacheflush.h>
@@ -57,11 +57,8 @@
 	return 0;
 }
 
-int mpc52xx_pm_prepare(suspend_state_t state)
+int mpc52xx_pm_prepare(void)
 {
-	if (state != PM_SUSPEND_STANDBY)
-		return -EINVAL;
-
 	/* map the whole register space */
 	mbar = mpc52xx_find_and_map("mpc5200");
 	if (!mbar) {
@@ -166,18 +163,16 @@
 	return 0;
 }
 
-int mpc52xx_pm_finish(suspend_state_t state)
+void mpc52xx_pm_finish(void)
 {
 	/* call board resume code */
 	if (mpc52xx_suspend.board_resume_finish)
 		mpc52xx_suspend.board_resume_finish(mbar);
 
 	iounmap(mbar);
-
-	return 0;
 }
 
-static struct pm_ops mpc52xx_pm_ops = {
+static struct platform_suspend_ops mpc52xx_pm_ops = {
 	.valid		= mpc52xx_pm_valid,
 	.prepare	= mpc52xx_pm_prepare,
 	.enter		= mpc52xx_pm_enter,
@@ -186,6 +181,6 @@
 
 int __init mpc52xx_pm_init(void)
 {
-	pm_set_ops(&mpc52xx_pm_ops);
+	suspend_set_ops(&mpc52xx_pm_ops);
 	return 0;
 }
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 229d355..ea22cad 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -120,7 +120,7 @@
 	depends on PPC_IBM_CELL_BLADE
 	help
 	  PMI (Platform Management Interrupt) is a way to
-	  communicate with the BMC (Baseboard Mangement Controller).
+	  communicate with the BMC (Baseboard Management Controller).
 	  It is used in some IBM Cell blades.
 	default m
 
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 3c7325e..99684ea 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -48,6 +48,7 @@
 	bool "AMCC 44x"
 	select PPC_DCR_NATIVE
 	select WANT_DEVICE_TREE
+	select PPC_UDBG_16550
 
 config E200
 	bool "Freescale e200"
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index d72b16d..d9e56a5 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -748,7 +748,7 @@
 	if (count)
 		goto out;
 
-	/* write aѕ much as possible */
+	/* write as much as possible */
 	for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) {
 		int ret;
 		ret = __get_user(wbox_data, udata);
diff --git a/arch/powerpc/platforms/celleb/scc_uhc.c b/arch/powerpc/platforms/celleb/scc_uhc.c
index a7c548b..b59c38a 100644
--- a/arch/powerpc/platforms/celleb/scc_uhc.c
+++ b/arch/powerpc/platforms/celleb/scc_uhc.c
@@ -36,7 +36,7 @@
 }
 
 /*
- * UHC(usb host controler) enable function.
+ * UHC(usb host controller) enable function.
  * affect to both of OHCI and EHCI core module.
  */
 static void enable_scc_uhc(struct pci_dev *dev)
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index 354c058..144177d 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -41,13 +41,13 @@
 #include <linux/root_dev.h>
 #include <linux/serial.h>
 #include <linux/smp.h>
+#include <linux/bitops.h>
 
 #include <asm/processor.h>
 #include <asm/sections.h>
 #include <asm/prom.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/kexec.h>
 #include <asm/pci-bridge.h>
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 07e64b4..6405f4a 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -628,9 +628,8 @@
 	int i;
 
 	for_each_sg(sgl, sg, nents, i) {
-		int result = ps3_dma_map(dev->d_region,
-			page_to_phys(sg->page) + sg->offset, sg->length,
-					 &sg->dma_address, 0);
+		int result = ps3_dma_map(dev->d_region, sg_phys(sg),
+					sg->length, &sg->dma_address, 0);
 
 		if (result) {
 			pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 3a393c7..a1ab25c 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -332,7 +332,7 @@
 		   err->disposition == RTAS_DISP_NOT_RECOVERED &&
 		   err->target == RTAS_TARGET_MEMORY &&
 		   err->type == RTAS_TYPE_ECC_UNCORR &&
-		   !(current->pid == 0 || is_init(current))) {
+		   !(current->pid == 0 || is_global_init(current))) {
 		/* Kill off a user process with an ECC error */
 		printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n",
 		       current->pid);
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c
index 48492a8..740ad73 100644
--- a/arch/powerpc/sysdev/bestcomm/bestcomm.c
+++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c
@@ -269,6 +269,7 @@
 	int task;
 	phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa;
 	unsigned int tdt_size, ctx_size, var_size, fdt_size;
+	u16 regval;
 
 	/* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */
 	tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt);
@@ -319,9 +320,11 @@
 	/* Init 'always' initiator */
 	out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
 
-	/* Disable COMM Bus Prefetch, apparently it's not reliable yet */
-	/* FIXME: This should be done on 5200 and not 5200B ... */
-	out_be16(&bcom_eng->regs->PtdCntrl, in_be16(&bcom_eng->regs->PtdCntrl) | 1);
+	/* Disable COMM Bus Prefetch on the original 5200; it's broken */
+	if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) {
+		regval = in_be16(&bcom_eng->regs->PtdCntrl);
+		out_be16(&bcom_eng->regs->PtdCntrl,  regval | 1);
+	}
 
 	/* Init lock */
 	spin_lock_init(&bcom_eng->lock);
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 607925c..6473fa7 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -1317,7 +1317,7 @@
 
 source "lib/Kconfig"
 
-source "arch/powerpc/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/ppc/Kconfig.debug"
 
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
index 487dc66..500497e 100644
--- a/arch/ppc/boot/Makefile
+++ b/arch/ppc/boot/Makefile
@@ -13,6 +13,8 @@
 # modified by Cort (cort@cs.nmt.edu)
 #
 
+# KBUILD_CFLAGS used when building rest of boot (takes effect recursively)
+KBUILD_CFLAGS 	+= -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include
 HOSTCFLAGS	+= -Iarch/$(ARCH)/boot/include
 
 BOOT_TARGETS	= zImage zImage.initrd znetboot znetboot.initrd
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 3f3b292..c785689 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -121,7 +121,7 @@
 	 * generate the same exception over and over again and we get
 	 * nowhere.  Better to kill it and let the kernel panic.
 	 */
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		__sighandler_t handler;
 
 		spin_lock_irq(&current->sighand->siglock);
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 94913dd..254c23b 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -290,7 +290,7 @@
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
diff --git a/arch/ppc/platforms/chestnut.c b/arch/ppc/platforms/chestnut.c
index 248684f..dcd6070 100644
--- a/arch/ppc/platforms/chestnut.c
+++ b/arch/ppc/platforms/chestnut.c
@@ -49,7 +49,6 @@
 extern void gen550_init(int, struct uart_port *);
 extern void mv64360_pcibios_fixup(mv64x60_handle_t *bh);
 
-#define BIT(x) (1<<x)
 #define CHESTNUT_PRESERVE_MASK (BIT(MV64x60_CPU2DEV_0_WIN) | \
 				BIT(MV64x60_CPU2DEV_1_WIN) | \
 				BIT(MV64x60_CPU2DEV_2_WIN) | \
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index b711321..4ec716d 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -529,21 +529,7 @@
 
 source "fs/Kconfig"
 
-menu "Instrumentation Support"
-
-source "arch/s390/oprofile/Kconfig"
-
-config KPROBES
-	bool "Kprobes (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && MODULES
-	help
-	  Kprobes allows you to trap at almost any kernel address and
-	  execute a callback function.	register_kprobe() establishes
-	  a probepoint and specifies the callback.  Kprobes is useful
-	  for kernel debugging, non-intrusive instrumentation and testing.
-	  If in doubt, say "N".
-
-endmenu
+source "kernel/Kconfig.instrumentation"
 
 source "arch/s390/Kconfig.debug"
 
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 2aae23d..ece7b99 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22
-# Tue Jul 17 12:50:23 2007
+# Linux kernel version: 2.6.23
+# Mon Oct 22 12:10:44 2007
 #
 CONFIG_MMU=y
 CONFIG_ZONE_DMA=y
@@ -19,15 +19,11 @@
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
-# Code maturity level options
+# General setup
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
@@ -42,7 +38,14 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_NS=y
+CONFIG_CGROUP_CPUACCT=y
 # CONFIG_CPUSETS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -63,7 +66,6 @@
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
@@ -83,6 +85,7 @@
 CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 CONFIG_BLK_DEV_BSG=y
+CONFIG_BLOCK_COMPAT=y
 
 #
 # IO Schedulers
@@ -108,7 +111,6 @@
 CONFIG_SMP=y
 CONFIG_NR_CPUS=32
 CONFIG_HOTPLUG_CPU=y
-CONFIG_DEFAULT_MIGRATION_COST=1000000
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
 CONFIG_AUDIT_ARCH=y
@@ -143,9 +145,11 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_HOLES_IN_ZONE=y
 
@@ -219,12 +223,14 @@
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=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_IP_VS is not set
 CONFIG_IPV6=y
 # CONFIG_IPV6_PRIVACY is not set
 # CONFIG_IPV6_ROUTER_PREF is not set
@@ -243,7 +249,48 @@
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETFILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK=m
+# CONFIG_NF_CT_ACCT is not set
+# CONFIG_NF_CONNTRACK_MARK is not set
+# CONFIG_NF_CONNTRACK_EVENTS is not set
+# CONFIG_NF_CT_PROTO_SCTP is not set
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
+# CONFIG_NF_CONNTRACK_AMANDA is not set
+# CONFIG_NF_CONNTRACK_FTP is not set
+# CONFIG_NF_CONNTRACK_H323 is not set
+# CONFIG_NF_CONNTRACK_IRC is not set
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+# CONFIG_NF_CONNTRACK_PPTP is not set
+# CONFIG_NF_CONNTRACK_SANE is not set
+# CONFIG_NF_CONNTRACK_SIP is not set
+# CONFIG_NF_CONNTRACK_TFTP is not set
+# CONFIG_NF_CT_NETLINK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_CONNTRACK_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_NF_CONNTRACK_IPV6 is not set
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
 # CONFIG_IP_DCCP is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
@@ -263,12 +310,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
 CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_FIFO=y
 
 #
 # Queueing/Scheduling
@@ -306,10 +348,12 @@
 CONFIG_NET_ACT_POLICE=y
 # CONFIG_NET_ACT_GACT is not set
 # CONFIG_NET_ACT_MIRRED is not set
+CONFIG_NET_ACT_NAT=m
 # CONFIG_NET_ACT_PEDIT is not set
 # CONFIG_NET_ACT_SIMP is not set
 CONFIG_NET_CLS_POLICE=y
 # CONFIG_NET_CLS_IND is not set
+CONFIG_NET_SCH_FIFO=y
 
 #
 # Network testing
@@ -329,6 +373,7 @@
 #
 # Generic Driver Options
 #
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
@@ -400,17 +445,11 @@
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_ZFCP=y
-
-#
-# Multi-device support (RAID and LVM)
-#
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_LINEAR=m
@@ -429,7 +468,9 @@
 CONFIG_DM_MULTIPATH=y
 # CONFIG_DM_MULTIPATH_EMC is not set
 # CONFIG_DM_MULTIPATH_RDAC is not set
+# CONFIG_DM_MULTIPATH_HP is not set
 # CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_IFB is not set
@@ -438,8 +479,13 @@
 # CONFIG_MACVLAN is not set
 CONFIG_EQUALIZER=m
 CONFIG_TUN=m
+CONFIG_VETH=m
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 # CONFIG_TR is not set
@@ -473,7 +519,6 @@
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=m
 # CONFIG_R3964 is not set
 CONFIG_RAW_DRIVER=m
@@ -490,7 +535,6 @@
 CONFIG_TN3215=y
 CONFIG_TN3215_CONSOLE=y
 CONFIG_CCW_CONSOLE=y
-CONFIG_SCLP=y
 CONFIG_SCLP_TTY=y
 CONFIG_SCLP_CONSOLE=y
 CONFIG_SCLP_VT220_TTY=y
@@ -514,6 +558,11 @@
 CONFIG_MONWRITER=m
 CONFIG_S390_VMUR=m
 # CONFIG_POWER_SUPPLY is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
 
 #
 # File systems
@@ -569,7 +618,6 @@
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
 CONFIG_CONFIGFS_FS=m
 
 #
@@ -588,10 +636,7 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
@@ -638,27 +683,13 @@
 # CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 # CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
 # CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
 CONFIG_DLM=m
 # CONFIG_DLM_DEBUG is not set
-
-#
-# Instrumentation Support
-#
-
-#
-# Profiling support
-#
+CONFIG_INSTRUMENTATION=y
 # CONFIG_PROFILING is not set
 CONFIG_KPROBES=y
+# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
@@ -682,6 +713,7 @@
 CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -694,14 +726,17 @@
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+CONFIG_SAMPLES=y
 
 #
 # Security options
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=m
 CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=m
 CONFIG_CRYPTO_MANAGER=y
@@ -720,6 +755,7 @@
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_DES is not set
 CONFIG_CRYPTO_FCRYPT=m
@@ -733,11 +769,13 @@
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_SEED=m
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
 CONFIG_CRYPTO_CAMELLIA=m
 # CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_AUTHENC=m
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_SHA1_S390 is not set
 # CONFIG_CRYPTO_SHA256_S390 is not set
@@ -755,5 +793,6 @@
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=m
+CONFIG_CRC7=m
 # CONFIG_LIBCRC32C is not set
 CONFIG_PLIST=y
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 66b5190..ce0856d 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -648,6 +648,8 @@
 	case DUMP_TYPE_CCW:
 		if (MACHINE_IS_VM)
 			dump_method = DUMP_METHOD_CCW_VM;
+		else if (diag308_set_works)
+			dump_method = DUMP_METHOD_CCW_DIAG;
 		else
 			dump_method = DUMP_METHOD_CCW_CIO;
 		break;
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index abb447a..96492cf 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -44,6 +44,7 @@
 #include <asm/processor.h>
 #include <asm/irq.h>
 #include <asm/timer.h>
+#include <asm/cpu.h>
 
 asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
 
@@ -91,6 +92,14 @@
 
 void do_monitor_call(struct pt_regs *regs, long interruption_code)
 {
+	struct s390_idle_data *idle;
+
+	idle = &__get_cpu_var(s390_idle);
+	spin_lock(&idle->lock);
+	idle->idle_time += get_clock() - idle->idle_enter;
+	idle->in_idle = 0;
+	spin_unlock(&idle->lock);
+
 	/* disable monitor call class 0 */
 	__ctl_clear_bit(8, 15);
 
@@ -105,6 +114,7 @@
 static void default_idle(void)
 {
 	int cpu, rc;
+	struct s390_idle_data *idle;
 
 	/* CPU is going idle. */
 	cpu = smp_processor_id();
@@ -142,6 +152,12 @@
 		return;
 	}
 
+	idle = &__get_cpu_var(s390_idle);
+	spin_lock(&idle->lock);
+	idle->idle_count++;
+	idle->in_idle = 1;
+	idle->idle_enter = get_clock();
+	spin_unlock(&idle->lock);
 	trace_hardirqs_on();
 	/* Wait for external, I/O or machine check interrupt. */
 	__load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
@@ -166,7 +182,7 @@
 
         printk("CPU:    %d    %s\n", task_thread_info(tsk)->cpu, print_tainted());
         printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
-	       current->comm, current->pid, (void *) tsk,
+	       current->comm, task_pid_nr(current), (void *) tsk,
 	       (void *) tsk->thread.ksp);
 
 	show_registers(regs);
@@ -254,14 +270,12 @@
 	save_fp_regs(&current->thread.fp_regs);
 	memcpy(&p->thread.fp_regs, &current->thread.fp_regs,
 	       sizeof(s390_fp_regs));
-        p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _SEGMENT_TABLE;
 	/* Set a new TLS ?  */
 	if (clone_flags & CLONE_SETTLS)
 		p->thread.acrs[0] = regs->gprs[6];
 #else /* CONFIG_64BIT */
 	/* Save the fpu registers to new thread structure. */
 	save_fp_regs(&p->thread.fp_regs);
-        p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _REGION_TABLE;
 	/* Set a new TLS ?  */
 	if (clone_flags & CLONE_SETTLS) {
 		if (test_thread_flag(TIF_31BIT)) {
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 35edbef..1d97fe1 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -42,6 +42,7 @@
 #include <asm/tlbflush.h>
 #include <asm/timer.h>
 #include <asm/lowcore.h>
+#include <asm/cpu.h>
 
 /*
  * An array with a pointer the lowcore of every CPU.
@@ -325,7 +326,7 @@
  */
 void smp_ptlb_callback(void *info)
 {
-	local_flush_tlb();
+	__tlb_flush_local();
 }
 
 void smp_ptlb_all(void)
@@ -494,6 +495,8 @@
 	return 0;
 }
 
+DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
+
 static void __init smp_create_idle(unsigned int cpu)
 {
 	struct task_struct *p;
@@ -506,6 +509,7 @@
 	if (IS_ERR(p))
 		panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
 	current_set[cpu] = p;
+	spin_lock_init(&(&per_cpu(s390_idle, cpu))->lock);
 }
 
 static int cpu_stopped(int cpu)
@@ -724,6 +728,7 @@
 	cpu_set(0, cpu_online_map);
 	S390_lowcore.percpu_offset = __per_cpu_offset[0];
 	current_set[0] = current;
+	spin_lock_init(&(&__get_cpu_var(s390_idle))->lock);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
@@ -756,22 +761,71 @@
 }
 static SYSDEV_ATTR(capability, 0444, show_capability, NULL);
 
+static ssize_t show_idle_count(struct sys_device *dev, char *buf)
+{
+	struct s390_idle_data *idle;
+	unsigned long long idle_count;
+
+	idle = &per_cpu(s390_idle, dev->id);
+	spin_lock_irq(&idle->lock);
+	idle_count = idle->idle_count;
+	spin_unlock_irq(&idle->lock);
+	return sprintf(buf, "%llu\n", idle_count);
+}
+static SYSDEV_ATTR(idle_count, 0444, show_idle_count, NULL);
+
+static ssize_t show_idle_time(struct sys_device *dev, char *buf)
+{
+	struct s390_idle_data *idle;
+	unsigned long long new_time;
+
+	idle = &per_cpu(s390_idle, dev->id);
+	spin_lock_irq(&idle->lock);
+	if (idle->in_idle) {
+		new_time = get_clock();
+		idle->idle_time += new_time - idle->idle_enter;
+		idle->idle_enter = new_time;
+	}
+	new_time = idle->idle_time;
+	spin_unlock_irq(&idle->lock);
+	return sprintf(buf, "%llu us\n", new_time >> 12);
+}
+static SYSDEV_ATTR(idle_time, 0444, show_idle_time, NULL);
+
+static struct attribute *cpu_attrs[] = {
+	&attr_capability.attr,
+	&attr_idle_count.attr,
+	&attr_idle_time.attr,
+	NULL,
+};
+
+static struct attribute_group cpu_attr_group = {
+	.attrs = cpu_attrs,
+};
+
 static int __cpuinit smp_cpu_notify(struct notifier_block *self,
 				    unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned int)(long)hcpu;
 	struct cpu *c = &per_cpu(cpu_devices, cpu);
 	struct sys_device *s = &c->sysdev;
+	struct s390_idle_data *idle;
 
 	switch (action) {
 	case CPU_ONLINE:
 	case CPU_ONLINE_FROZEN:
-		if (sysdev_create_file(s, &attr_capability))
+		idle = &per_cpu(s390_idle, cpu);
+		spin_lock_irq(&idle->lock);
+		idle->idle_enter = 0;
+		idle->idle_time = 0;
+		idle->idle_count = 0;
+		spin_unlock_irq(&idle->lock);
+		if (sysfs_create_group(&s->kobj, &cpu_attr_group))
 			return NOTIFY_BAD;
 		break;
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
-		sysdev_remove_file(s, &attr_capability);
+		sysfs_remove_group(&s->kobj, &cpu_attr_group);
 		break;
 	}
 	return NOTIFY_OK;
@@ -784,6 +838,7 @@
 static int __init topology_init(void)
 {
 	int cpu;
+	int rc;
 
 	register_cpu_notifier(&smp_cpu_nb);
 
@@ -796,7 +851,9 @@
 		if (!cpu_online(cpu))
 			continue;
 		s = &c->sysdev;
-		sysdev_create_file(s, &attr_capability);
+		rc = sysfs_create_group(&s->kobj, &cpu_attr_group);
+		if (rc)
+			return rc;
 	}
 	return 0;
 }
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c
index 60604b2..7e8efaa 100644
--- a/arch/s390/lib/uaccess_pt.c
+++ b/arch/s390/lib/uaccess_pt.c
@@ -15,6 +15,27 @@
 #include <asm/futex.h>
 #include "uaccess.h"
 
+static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+
+	pgd = pgd_offset(mm, addr);
+	if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
+		return NULL;
+
+	pud = pud_offset(pgd, addr);
+	if (pud_none(*pud) || unlikely(pud_bad(*pud)))
+		return NULL;
+
+	pmd = pmd_offset(pud, addr);
+	if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
+		return NULL;
+
+	return pte_offset_map(pmd, addr);
+}
+
 static int __handle_fault(struct mm_struct *mm, unsigned long address,
 			  int write_access)
 {
@@ -64,7 +85,7 @@
 
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
@@ -85,8 +106,6 @@
 {
 	struct mm_struct *mm = current->mm;
 	unsigned long offset, pfn, done, size;
-	pgd_t *pgd;
-	pmd_t *pmd;
 	pte_t *pte;
 	void *from, *to;
 
@@ -94,15 +113,7 @@
 retry:
 	spin_lock(&mm->page_table_lock);
 	do {
-		pgd = pgd_offset(mm, uaddr);
-		if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
-			goto fault;
-
-		pmd = pmd_offset(pgd, uaddr);
-		if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
-			goto fault;
-
-		pte = pte_offset_map(pmd, uaddr);
+		pte = follow_table(mm, uaddr);
 		if (!pte || !pte_present(*pte) ||
 		    (write_user && !pte_write(*pte)))
 			goto fault;
@@ -142,22 +153,12 @@
 {
 	struct mm_struct *mm = current->mm;
 	unsigned long pfn, ret;
-	pgd_t *pgd;
-	pmd_t *pmd;
 	pte_t *pte;
 	int rc;
 
 	ret = 0;
 retry:
-	pgd = pgd_offset(mm, uaddr);
-	if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
-		goto fault;
-
-	pmd = pmd_offset(pgd, uaddr);
-	if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
-		goto fault;
-
-	pte = pte_offset_map(pmd, uaddr);
+	pte = follow_table(mm, uaddr);
 	if (!pte || !pte_present(*pte))
 		goto fault;
 
@@ -229,8 +230,6 @@
 	unsigned long uaddr = (unsigned long) src;
 	struct mm_struct *mm = current->mm;
 	unsigned long offset, pfn, done, len;
-	pgd_t *pgd;
-	pmd_t *pmd;
 	pte_t *pte;
 	size_t len_str;
 
@@ -240,15 +239,7 @@
 retry:
 	spin_lock(&mm->page_table_lock);
 	do {
-		pgd = pgd_offset(mm, uaddr);
-		if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
-			goto fault;
-
-		pmd = pmd_offset(pgd, uaddr);
-		if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
-			goto fault;
-
-		pte = pte_offset_map(pmd, uaddr);
+		pte = follow_table(mm, uaddr);
 		if (!pte || !pte_present(*pte))
 			goto fault;
 
@@ -308,8 +299,6 @@
 		      uaddr, done, size;
 	unsigned long uaddr_from = (unsigned long) from;
 	unsigned long uaddr_to = (unsigned long) to;
-	pgd_t *pgd_from, *pgd_to;
-	pmd_t *pmd_from, *pmd_to;
 	pte_t *pte_from, *pte_to;
 	int write_user;
 
@@ -317,39 +306,14 @@
 retry:
 	spin_lock(&mm->page_table_lock);
 	do {
-		pgd_from = pgd_offset(mm, uaddr_from);
-		if (pgd_none(*pgd_from) || unlikely(pgd_bad(*pgd_from))) {
-			uaddr = uaddr_from;
-			write_user = 0;
-			goto fault;
-		}
-		pgd_to = pgd_offset(mm, uaddr_to);
-		if (pgd_none(*pgd_to) || unlikely(pgd_bad(*pgd_to))) {
-			uaddr = uaddr_to;
-			write_user = 1;
-			goto fault;
-		}
-
-		pmd_from = pmd_offset(pgd_from, uaddr_from);
-		if (pmd_none(*pmd_from) || unlikely(pmd_bad(*pmd_from))) {
-			uaddr = uaddr_from;
-			write_user = 0;
-			goto fault;
-		}
-		pmd_to = pmd_offset(pgd_to, uaddr_to);
-		if (pmd_none(*pmd_to) || unlikely(pmd_bad(*pmd_to))) {
-			uaddr = uaddr_to;
-			write_user = 1;
-			goto fault;
-		}
-
-		pte_from = pte_offset_map(pmd_from, uaddr_from);
+		pte_from = follow_table(mm, uaddr_from);
 		if (!pte_from || !pte_present(*pte_from)) {
 			uaddr = uaddr_from;
 			write_user = 0;
 			goto fault;
 		}
-		pte_to = pte_offset_map(pmd_to, uaddr_to);
+
+		pte_to = follow_table(mm, uaddr_to);
 		if (!pte_to || !pte_present(*pte_to) || !pte_write(*pte_to)) {
 			uaddr = uaddr_to;
 			write_user = 1;
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index f95449b..6640193 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -2,6 +2,6 @@
 # Makefile for the linux s390-specific parts of the memory manager.
 #
 
-obj-y	 := init.o fault.o extmem.o mmap.o vmem.o
+obj-y	 := init.o fault.o extmem.o mmap.o vmem.o pgtable.o
 obj-$(CONFIG_CMM) += cmm.o
 
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 14c241c..2456b52 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -211,7 +211,7 @@
 	struct mm_struct *mm = tsk->mm;
 
 	up_read(&mm->mmap_sem);
-	if (is_init(tsk)) {
+	if (is_global_init(tsk)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		return 1;
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 3a25bbf..b234bb4 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -81,6 +81,7 @@
 static void __init setup_ro_region(void)
 {
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	pte_t new_pte;
@@ -91,7 +92,8 @@
 
 	for (; address < end; address += PAGE_SIZE) {
 		pgd = pgd_offset_k(address);
-		pmd = pmd_offset(pgd, address);
+		pud = pud_offset(pgd, address);
+		pmd = pmd_offset(pud, address);
 		pte = pte_offset_kernel(pmd, address);
 		new_pte = mk_pte_phys(address, __pgprot(_PAGE_RO));
 		*pte = new_pte;
@@ -103,32 +105,28 @@
  */
 void __init paging_init(void)
 {
-	pgd_t *pg_dir;
-	int i;
-	unsigned long pgdir_k;
 	static const int ssm_mask = 0x04000000L;
 	unsigned long max_zone_pfns[MAX_NR_ZONES];
+	unsigned long pgd_type;
 
-	pg_dir = swapper_pg_dir;
-	
+	init_mm.pgd = swapper_pg_dir;
+	S390_lowcore.kernel_asce = __pa(init_mm.pgd) & PAGE_MASK;
 #ifdef CONFIG_64BIT
-	pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERN_REGION_TABLE;
-	for (i = 0; i < PTRS_PER_PGD; i++)
-		pgd_clear_kernel(pg_dir + i);
+	S390_lowcore.kernel_asce |= _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH;
+	pgd_type = _REGION3_ENTRY_EMPTY;
 #else
-	pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE;
-	for (i = 0; i < PTRS_PER_PGD; i++)
-		pmd_clear_kernel((pmd_t *)(pg_dir + i));
+	S390_lowcore.kernel_asce |= _ASCE_TABLE_LENGTH;
+	pgd_type = _SEGMENT_ENTRY_EMPTY;
 #endif
+	clear_table((unsigned long *) init_mm.pgd, pgd_type,
+		    sizeof(unsigned long)*2048);
 	vmem_map_init();
 	setup_ro_region();
 
-	S390_lowcore.kernel_asce = pgdir_k;
-
         /* enable virtual mapping in kernel mode */
-	__ctl_load(pgdir_k, 1, 1);
-	__ctl_load(pgdir_k, 7, 7);
-	__ctl_load(pgdir_k, 13, 13);
+	__ctl_load(S390_lowcore.kernel_asce, 1, 1);
+	__ctl_load(S390_lowcore.kernel_asce, 7, 7);
+	__ctl_load(S390_lowcore.kernel_asce, 13, 13);
 	__raw_local_irq_ssm(ssm_mask);
 
 	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
new file mode 100644
index 0000000..e60e0ae
--- /dev/null
+++ b/arch/s390/mm/pgtable.c
@@ -0,0 +1,94 @@
+/*
+ *  arch/s390/mm/pgtable.c
+ *
+ *    Copyright IBM Corp. 2007
+ *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/smp.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/quicklist.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+
+#ifndef CONFIG_64BIT
+#define ALLOC_ORDER	1
+#else
+#define ALLOC_ORDER	2
+#endif
+
+unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec)
+{
+	struct page *page = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
+
+	if (!page)
+		return NULL;
+	page->index = 0;
+	if (noexec) {
+		struct page *shadow = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
+		if (!shadow) {
+			__free_pages(page, ALLOC_ORDER);
+			return NULL;
+		}
+		page->index = page_to_phys(shadow);
+	}
+	return (unsigned long *) page_to_phys(page);
+}
+
+void crst_table_free(unsigned long *table)
+{
+	unsigned long *shadow = get_shadow_table(table);
+
+	if (shadow)
+		free_pages((unsigned long) shadow, ALLOC_ORDER);
+	free_pages((unsigned long) table, ALLOC_ORDER);
+}
+
+/*
+ * page table entry allocation/free routines.
+ */
+unsigned long *page_table_alloc(int noexec)
+{
+	struct page *page = alloc_page(GFP_KERNEL);
+	unsigned long *table;
+
+	if (!page)
+		return NULL;
+	page->index = 0;
+	if (noexec) {
+		struct page *shadow = alloc_page(GFP_KERNEL);
+		if (!shadow) {
+			__free_page(page);
+			return NULL;
+		}
+		table = (unsigned long *) page_to_phys(shadow);
+		clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
+		page->index = (addr_t) table;
+	}
+	table = (unsigned long *) page_to_phys(page);
+	clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
+	return table;
+}
+
+void page_table_free(unsigned long *table)
+{
+	unsigned long *shadow = get_shadow_pte(table);
+
+	if (shadow)
+		free_page((unsigned long) shadow);
+	free_page((unsigned long) table);
+
+}
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index fd594d5..fb9c5a8 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -73,31 +73,28 @@
 	return alloc_bootmem_pages((1 << order) * PAGE_SIZE);
 }
 
+#define vmem_pud_alloc()	({ BUG(); ((pud_t *) NULL); })
+
 static inline pmd_t *vmem_pmd_alloc(void)
 {
-	pmd_t *pmd;
-	int i;
+	pmd_t *pmd = NULL;
 
-	pmd = vmem_alloc_pages(PMD_ALLOC_ORDER);
+#ifdef CONFIG_64BIT
+	pmd = vmem_alloc_pages(2);
 	if (!pmd)
 		return NULL;
-	for (i = 0; i < PTRS_PER_PMD; i++)
-		pmd_clear_kernel(pmd + i);
+	clear_table((unsigned long *) pmd, _SEGMENT_ENTRY_EMPTY, PAGE_SIZE*4);
+#endif
 	return pmd;
 }
 
 static inline pte_t *vmem_pte_alloc(void)
 {
-	pte_t *pte;
-	pte_t empty_pte;
-	int i;
+	pte_t *pte = vmem_alloc_pages(0);
 
-	pte = vmem_alloc_pages(PTE_ALLOC_ORDER);
 	if (!pte)
 		return NULL;
-	pte_val(empty_pte) = _PAGE_TYPE_EMPTY;
-	for (i = 0; i < PTRS_PER_PTE; i++)
-		pte[i] = empty_pte;
+	clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY, PAGE_SIZE);
 	return pte;
 }
 
@@ -108,6 +105,7 @@
 {
 	unsigned long address;
 	pgd_t *pg_dir;
+	pud_t *pu_dir;
 	pmd_t *pm_dir;
 	pte_t *pt_dir;
 	pte_t  pte;
@@ -116,13 +114,21 @@
 	for (address = start; address < start + size; address += PAGE_SIZE) {
 		pg_dir = pgd_offset_k(address);
 		if (pgd_none(*pg_dir)) {
+			pu_dir = vmem_pud_alloc();
+			if (!pu_dir)
+				goto out;
+			pgd_populate_kernel(&init_mm, pg_dir, pu_dir);
+		}
+
+		pu_dir = pud_offset(pg_dir, address);
+		if (pud_none(*pu_dir)) {
 			pm_dir = vmem_pmd_alloc();
 			if (!pm_dir)
 				goto out;
-			pgd_populate_kernel(&init_mm, pg_dir, pm_dir);
+			pud_populate_kernel(&init_mm, pu_dir, pm_dir);
 		}
 
-		pm_dir = pmd_offset(pg_dir, address);
+		pm_dir = pmd_offset(pu_dir, address);
 		if (pmd_none(*pm_dir)) {
 			pt_dir = vmem_pte_alloc();
 			if (!pt_dir)
@@ -148,6 +154,7 @@
 {
 	unsigned long address;
 	pgd_t *pg_dir;
+	pud_t *pu_dir;
 	pmd_t *pm_dir;
 	pte_t *pt_dir;
 	pte_t  pte;
@@ -155,9 +162,10 @@
 	pte_val(pte) = _PAGE_TYPE_EMPTY;
 	for (address = start; address < start + size; address += PAGE_SIZE) {
 		pg_dir = pgd_offset_k(address);
-		if (pgd_none(*pg_dir))
+		pu_dir = pud_offset(pg_dir, address);
+		if (pud_none(*pu_dir))
 			continue;
-		pm_dir = pmd_offset(pg_dir, address);
+		pm_dir = pmd_offset(pu_dir, address);
 		if (pmd_none(*pm_dir))
 			continue;
 		pt_dir = pte_offset_kernel(pm_dir, address);
@@ -174,6 +182,7 @@
 	unsigned long address, start_addr, end_addr;
 	struct page *map_start, *map_end;
 	pgd_t *pg_dir;
+	pud_t *pu_dir;
 	pmd_t *pm_dir;
 	pte_t *pt_dir;
 	pte_t  pte;
@@ -188,13 +197,21 @@
 	for (address = start_addr; address < end_addr; address += PAGE_SIZE) {
 		pg_dir = pgd_offset_k(address);
 		if (pgd_none(*pg_dir)) {
+			pu_dir = vmem_pud_alloc();
+			if (!pu_dir)
+				goto out;
+			pgd_populate_kernel(&init_mm, pg_dir, pu_dir);
+		}
+
+		pu_dir = pud_offset(pg_dir, address);
+		if (pud_none(*pu_dir)) {
 			pm_dir = vmem_pmd_alloc();
 			if (!pm_dir)
 				goto out;
-			pgd_populate_kernel(&init_mm, pg_dir, pm_dir);
+			pud_populate_kernel(&init_mm, pu_dir, pm_dir);
 		}
 
-		pm_dir = pmd_offset(pg_dir, address);
+		pm_dir = pmd_offset(pu_dir, address);
 		if (pmd_none(*pm_dir)) {
 			pt_dir = vmem_pte_alloc();
 			if (!pt_dir)
diff --git a/arch/s390/oprofile/Kconfig b/arch/s390/oprofile/Kconfig
deleted file mode 100644
index 208220a..0000000
--- a/arch/s390/oprofile/Kconfig
+++ /dev/null
@@ -1,22 +0,0 @@
-
-menu "Profiling support"
-
-config PROFILING
-	bool "Profiling support"
-	help
-	  Say Y here to enable profiling support mechanisms used by
-	  profilers such as readprofile or OProfile.
-
-
-config OPROFILE
-	tristate "OProfile system profiling"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
-endmenu
-
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 44982c1..247f8a6 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -758,7 +758,7 @@
 
 source "fs/Kconfig"
 
-source "arch/sh/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/sh/Kconfig.debug"
 
diff --git a/arch/sh/boards/hp6xx/pm.c b/arch/sh/boards/hp6xx/pm.c
index 8143d1b..d22f6ea 100644
--- a/arch/sh/boards/hp6xx/pm.c
+++ b/arch/sh/boards/hp6xx/pm.c
@@ -67,14 +67,14 @@
 	return 0;
 }
 
-static struct pm_ops hp6x0_pm_ops = {
+static struct platform_suspend_ops hp6x0_pm_ops = {
 	.enter		= hp6x0_pm_enter,
-	.valid		= pm_valid_only_mem,
+	.valid		= suspend_valid_only_mem,
 };
 
 static int __init hp6x0_pm_init(void)
 {
-	pm_set_ops(&hp6x0_pm_ops);
+	suspend_set_ops(&hp6x0_pm_ops);
 	return 0;
 }
 
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 790ed69..5c17de5 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -104,24 +104,3 @@
 	(*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
 }
 
-/* crashkernel=size@addr specifies the location to reserve for
- * a crash kernel.  By reserving this memory we guarantee
- * that linux never sets it up as a DMA target.
- * Useful for holding code to do something appropriate
- * after a kernel panic.
- */
-static int __init parse_crashkernel(char *arg)
-{
-	unsigned long size, base;
-	size = memparse(arg, &arg);
-	if (*arg == '@') {
-		base = memparse(arg+1, &arg);
-		/* FIXME: Do I want a sanity check
-		 * to validate the memory range?
-		 */
-		crashk_res.start = base;
-		crashk_res.end   = base + size - 1;
-	}
-	return 0;
-}
-early_param("crashkernel", parse_crashkernel);
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index b446999..6d7f2b0 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -121,7 +121,7 @@
 void show_regs(struct pt_regs * regs)
 {
 	printk("\n");
-	printk("Pid : %d, Comm: %20s\n", current->pid, current->comm);
+	printk("Pid : %d, Comm: %20s\n", task_pid_nr(current), current->comm);
 	print_symbol("PC is at %s\n", instruction_pointer(regs));
 	printk("PC  : %08lx SP  : %08lx SR  : %08lx ",
 	       regs->pc, regs->regs[15], regs->sr);
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index b3027a6..b749403 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -128,6 +128,37 @@
 	free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
 }
 
+#ifdef CONFIG_KEXEC
+static void __init reserve_crashkernel(void)
+{
+	unsigned long long free_mem;
+	unsigned long long crash_size, crash_base;
+	int ret;
+
+	free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
+
+	ret = parse_crashkernel(boot_command_line, free_mem,
+			&crash_size, &crash_base);
+	if (ret == 0 && crash_size) {
+		if (crash_base > 0) {
+			printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+					"for crashkernel (System RAM: %ldMB)\n",
+					(unsigned long)(crash_size >> 20),
+					(unsigned long)(crash_base >> 20),
+					(unsigned long)(free_mem >> 20));
+			crashk_res.start = crash_base;
+			crashk_res.end   = crash_base + crash_size - 1;
+			reserve_bootmem(crash_base, crash_size);
+		} else
+			printk(KERN_INFO "crashkernel reservation failed - "
+					"you have to specify a base address\n");
+	}
+}
+#else
+static inline void __init reserve_crashkernel(void)
+{}
+#endif
+
 void __init setup_bootmem_allocator(unsigned long free_pfn)
 {
 	unsigned long bootmap_size;
@@ -189,11 +220,8 @@
 		}
 	}
 #endif
-#ifdef CONFIG_KEXEC
-	if (crashk_res.start != crashk_res.end)
-		reserve_bootmem(crashk_res.start,
-			crashk_res.end - crashk_res.start + 1);
-#endif
+
+	reserve_crashkernel();
 }
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 2f42442..ca754fd 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -382,7 +382,7 @@
 	set_fs(USER_DS);
 
 	pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
-		 current->comm, current->pid, frame, regs->pc, regs->pr);
+		 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
 
 	flush_cache_sigtramp(regs->pr);
 
@@ -462,7 +462,7 @@
 	set_fs(USER_DS);
 
 	pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
-		 current->comm, current->pid, frame, regs->pc, regs->pr);
+		 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
 
 	flush_cache_sigtramp(regs->pr);
 
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index dcb46e7..cf99111c 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -95,8 +95,8 @@
 	print_modules();
 	show_regs(regs);
 
-	printk("Process: %s (pid: %d, stack limit = %p)\n",
-	       current->comm, current->pid, task_stack_page(current) + 1);
+	printk("Process: %s (pid: %d, stack limit = %p)\n", current->comm,
+			task_pid_nr(current), task_stack_page(current) + 1);
 
 	if (!user_mode(regs) || in_interrupt())
 		dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
@@ -386,7 +386,8 @@
 
 		printk(KERN_NOTICE "Fixing up unaligned userspace access "
 		       "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
-		       current->comm,current->pid,(u16*)regs->pc,instruction);
+		       current->comm, task_pid_nr(current),
+		       (u16 *)regs->pc, instruction);
 	}
 
 	ret = -EFAULT;
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 4729668..f33cedb 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -207,7 +207,7 @@
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
diff --git a/arch/sh/oprofile/Kconfig b/arch/sh/oprofile/Kconfig
deleted file mode 100644
index 5ade198..0000000
--- a/arch/sh/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-	  
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
-endmenu
-
diff --git a/arch/sh64/Kconfig b/arch/sh64/Kconfig
index b3327ce..ba204ba 100644
--- a/arch/sh64/Kconfig
+++ b/arch/sh64/Kconfig
@@ -284,7 +284,7 @@
 
 source "fs/Kconfig"
 
-source "arch/sh64/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
 
 source "arch/sh64/Kconfig.debug"
 
diff --git a/arch/sh64/kernel/pci_sh5.c b/arch/sh64/kernel/pci_sh5.c
index 388bb71..b4d9534 100644
--- a/arch/sh64/kernel/pci_sh5.c
+++ b/arch/sh64/kernel/pci_sh5.c
@@ -480,7 +480,7 @@
                 return -EINVAL;
         }
 
-	/* The pci subsytem needs to know where memory is and how much
+	/* The pci subsystem needs to know where memory is and how much
 	 * of it there is. I've simply made these globals. A better mechanism
 	 * is probably needed.
 	 */
diff --git a/arch/sh64/kernel/traps.c b/arch/sh64/kernel/traps.c
index 9d0d58f..c03101f 100644
--- a/arch/sh64/kernel/traps.c
+++ b/arch/sh64/kernel/traps.c
@@ -764,7 +764,7 @@
 		--user_mode_unaligned_fixup_count;
 		/* Only do 'count' worth of these reports, to remove a potential DoS against syslog */
 		printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n",
-		       current->comm, current->pid, (__u32)regs->pc, opcode);
+		       current->comm, task_pid_nr(current), (__u32)regs->pc, opcode);
 	} else
 #endif
 	if (!user_mode(regs) && (kernel_mode_unaligned_fixup_count > 0)) {
@@ -774,7 +774,7 @@
 			       (__u32)regs->pc, opcode);
 		} else {
 			printk("Fixing up unaligned kernelspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n",
-			       current->comm, current->pid, (__u32)regs->pc, opcode);
+			       current->comm, task_pid_nr(current), (__u32)regs->pc, opcode);
 		}
 	}
 
diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c
index dd81c66..7c79a1b 100644
--- a/arch/sh64/mm/fault.c
+++ b/arch/sh64/mm/fault.c
@@ -81,7 +81,7 @@
 
 static inline void print_task(struct task_struct *tsk)
 {
-	printk("Task pid %d\n", tsk->pid);
+	printk("Task pid %d\n", task_pid_nr(tsk));
 }
 
 static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address)
@@ -272,13 +272,13 @@
 			 * usermode, so only need a few */
 			count++;
 			printk("user mode bad_area address=%08lx pid=%d (%s) pc=%08lx\n",
-				address, current->pid, current->comm,
+				address, task_pid_nr(current), current->comm,
 				(unsigned long) regs->pc);
 #if 0
 			show_regs(regs);
 #endif
 		}
-		if (is_init(tsk)) {
+		if (is_global_init(tsk)) {
 			panic("INIT had user mode bad_area\n");
 		}
 		tsk->thread.address = address;
@@ -320,14 +320,14 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		panic("INIT out of memory\n");
 		yield();
 		goto survive;
 	}
 	printk("fault:Out of memory\n");
 	up_read(&mm->mmap_sem);
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
diff --git a/arch/sh64/oprofile/Kconfig b/arch/sh64/oprofile/Kconfig
deleted file mode 100644
index 19d3773..0000000
--- a/arch/sh64/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
-	depends on EXPERIMENTAL
-
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
-endmenu
-
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index c0f4ba1..527adc8 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -320,11 +320,7 @@
 
 source "fs/Kconfig"
 
-menu "Instrumentation Support"
-
-source "arch/sparc/oprofile/Kconfig"
-
-endmenu
+source "kernel/Kconfig.instrumentation"
 
 source "arch/sparc/Kconfig.debug"
 
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 9c3ed88..97aa50d 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -727,9 +727,8 @@
 	BUG_ON(direction == PCI_DMA_NONE);
 	/* IIep is write-through, not flushing. */
 	for_each_sg(sgl, sg, nents, n) {
-		BUG_ON(page_address(sg->page) == NULL);
-		sg->dvma_address =
-			virt_to_phys(page_address(sg->page)) + sg->offset;
+		BUG_ON(page_address(sg_page(sg)) == NULL);
+		sg->dvma_address = virt_to_phys(sg_virt(sg));
 		sg->dvma_length = sg->length;
 	}
 	return nents;
@@ -748,9 +747,9 @@
 	BUG_ON(direction == PCI_DMA_NONE);
 	if (direction != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg->page) == NULL);
+			BUG_ON(page_address(sg_page(sg)) == NULL);
 			mmu_inval_dma_area(
-			    (unsigned long) page_address(sg->page),
+			    (unsigned long) page_address(sg_page(sg)),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 		}
 	}
@@ -798,9 +797,9 @@
 	BUG_ON(direction == PCI_DMA_NONE);
 	if (direction != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg->page) == NULL);
+			BUG_ON(page_address(sg_page(sg)) == NULL);
 			mmu_inval_dma_area(
-			    (unsigned long) page_address(sg->page),
+			    (unsigned long) page_address(sg_page(sg)),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 		}
 	}
@@ -814,9 +813,9 @@
 	BUG_ON(direction == PCI_DMA_NONE);
 	if (direction != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg->page) == NULL);
+			BUG_ON(page_address(sg_page(sg)) == NULL);
 			mmu_inval_dma_area(
-			    (unsigned long) page_address(sg->page),
+			    (unsigned long) page_address(sg_page(sg)),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 		}
 	}
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
index fb2caef..3ea000d 100644
--- a/arch/sparc/kernel/of_device.c
+++ b/arch/sparc/kernel/of_device.c
@@ -585,24 +585,6 @@
 
 __setup("of_debug=", of_debug);
 
-int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
-{
-	/* initialize common driver fields */
-	if (!drv->driver.name)
-		drv->driver.name = drv->name;
-	if (!drv->driver.owner)
-		drv->driver.owner = drv->owner;
-	drv->driver.bus = bus;
-
-	/* register with core */
-	return driver_register(&drv->driver);
-}
-
-void of_unregister_driver(struct of_platform_driver *drv)
-{
-	driver_unregister(&drv->driver);
-}
-
 struct of_device* of_platform_device_create(struct device_node *np,
 					    const char *bus_id,
 					    struct device *parent,
@@ -628,6 +610,4 @@
 	return dev;
 }
 
-EXPORT_SYMBOL(of_register_driver);
-EXPORT_SYMBOL(of_unregister_driver);
 EXPORT_SYMBOL(of_platform_device_create);
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index 003f8ee..fe562db 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -155,7 +155,7 @@
 		/* Rest of them are completely unsupported. */
 	default:
 		printk("%s [%d]: Wants to read user offset %ld\n",
-		       current->comm, current->pid, offset);
+		       current->comm, task_pid_nr(current), offset);
 		pt_error_return(regs, EIO);
 		return;
 	}
@@ -222,7 +222,7 @@
 		/* Rest of them are completely unsupported or "no-touch". */
 	default:
 		printk("%s [%d]: Wants to write user offset %ld\n",
-		       current->comm, current->pid, offset);
+		       current->comm, task_pid_nr(current), offset);
 		goto failure;
 	}
 success:
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index 6c0221e..42bf09d 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -357,7 +357,7 @@
 	if (count++ > 5)
 		return -ENOSYS;
 	printk ("%s[%d]: Unimplemented SPARC system call %d\n",
-		current->comm, current->pid, (int)regs->u_regs[1]);
+		current->comm, task_pid_nr(current), (int)regs->u_regs[1]);
 #ifdef DEBUG_UNIMP_SYSCALL	
 	show_regs (regs);
 #endif
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index f807172..28c187c 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -866,7 +866,7 @@
 	rcu_read_lock();
 	ret = -EINVAL;
 	if (pgrp > 0)
-		ret = kill_pgrp(find_pid(pgrp), sig, 0);
+		ret = kill_pgrp(find_vpid(pgrp), sig, 0);
 	rcu_read_unlock();
 
 	return ret;
diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
index 3bc3bff..d404e79 100644
--- a/arch/sparc/kernel/traps.c
+++ b/arch/sparc/kernel/traps.c
@@ -38,7 +38,7 @@
 
 void syscall_trace_entry(struct pt_regs *regs)
 {
-	printk("%s[%d]: ", current->comm, current->pid);
+	printk("%s[%d]: ", current->comm, task_pid_nr(current));
 	printk("scall<%d> (could be %d)\n", (int) regs->u_regs[UREG_G1],
 	       (int) regs->u_regs[UREG_I0]);
 }
@@ -99,7 +99,7 @@
 "              /_| \\__/ |_\\\n"
 "                 \\__U_/\n");
 
-	printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
+	printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter);
 	show_regs(regs);
 	add_taint(TAINT_DIE);
 
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index 375b4db..1666087 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -144,7 +144,7 @@
 	spin_lock_irqsave(&iounit->lock, flags);
 	while (sz != 0) {
 		--sz;
-		sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg->page) + sg->offset, sg->length);
+		sg->dvma_address = iounit_get_area(iounit, sg_virt(sg), sg->length);
 		sg->dvma_length = sg->length;
 		sg = sg_next(sg);
 	}
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 283656d..4b93427 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -238,7 +238,7 @@
 	while (sz != 0) {
 		--sz;
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
-		sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
 		sg->dvma_length = (__u32) sg->length;
 		sg = sg_next(sg);
 	}
@@ -252,7 +252,7 @@
 	while (sz != 0) {
 		--sz;
 		n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
-		sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
 		sg->dvma_length = (__u32) sg->length;
 		sg = sg_next(sg);
 	}
@@ -273,7 +273,7 @@
 		 * XXX Is this a good assumption?
 		 * XXX What if someone else unmaps it here and races us?
 		 */
-		if ((page = (unsigned long) page_address(sg->page)) != 0) {
+		if ((page = (unsigned long) page_address(sg_page(sg))) != 0) {
 			for (i = 0; i < n; i++) {
 				if (page != oldpage) {	/* Already flushed? */
 					flush_page_for_dma(page);
@@ -283,7 +283,7 @@
 			}
 		}
 
-		sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+		sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
 		sg->dvma_length = (__u32) sg->length;
 		sg = sg_next(sg);
 	}
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index ee6708f..a2cc141 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1228,7 +1228,7 @@
 {
 	while (sz != 0) {
 		--sz;
-		sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg->page) + sg->offset, sg->length);
+		sg->dvma_address = (__u32)sun4c_lockarea(sg_virt(sg), sg->length);
 		sg->dvma_length = sg->length;
 		sg = sg_next(sg);
 	}
diff --git a/arch/sparc/oprofile/Kconfig b/arch/sparc/oprofile/Kconfig
deleted file mode 100644
index d8a8408..0000000
--- a/arch/sparc/oprofile/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-	  
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 5cc8847..bd59ab0 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -72,6 +72,10 @@
 config OF
 	def_bool y
 
+config GENERIC_HARDIRQS_NO__DO_IRQ
+	bool
+	def_bool y
+
 choice
 	prompt "Kernel page size"
 	default SPARC64_PAGE_SIZE_8KB
@@ -458,20 +462,7 @@
 
 source "fs/Kconfig"
 
-menu "Instrumentation Support"
-
-source "arch/sparc64/oprofile/Kconfig"
-
-config KPROBES
-	bool "Kprobes (EXPERIMENTAL)"
-	depends on KALLSYMS && EXPERIMENTAL && MODULES
-	help
-	  Kprobes allows you to trap at almost any kernel address and
-	  execute a callback function.  register_kprobe() establishes
-	  a probepoint and specifies the callback.  Kprobes is useful
-	  for kernel debugging, non-intrusive instrumentation and testing.
-	  If in doubt, say "N".
-endmenu
+source "kernel/Kconfig.instrumentation"
 
 source "arch/sparc64/Kconfig.debug"
 
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
index 6c92a42..01159cb 100644
--- a/arch/sparc64/Makefile
+++ b/arch/sparc64/Makefile
@@ -18,8 +18,6 @@
 NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
 UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; )
 
-export NEW_GCC
-
 ifneq ($(NEW_GAS),y)
 AS		= sparc64-linux-as
 LD		= sparc64-linux-ld
@@ -58,8 +56,6 @@
 core-$(CONFIG_SOLARIS_EMUL)	+= arch/sparc64/solaris/
 core-y				+= arch/sparc64/math-emu/
 libs-y				+= arch/sparc64/prom/ arch/sparc64/lib/
-
-# FIXME: is drivers- right?
 drivers-$(CONFIG_OPROFILE)	+= arch/sparc64/oprofile/
 
 boot := arch/sparc64/boot
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 1aa2c40..e023d4b 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.23
-# Sat Oct 13 21:53:54 2007
+# Sun Oct 21 19:57:44 2007
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -49,6 +49,10 @@
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=18
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
 # CONFIG_BLK_DEV_INITRD is not set
@@ -145,7 +149,10 @@
 CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
-CONFIG_SPARSEMEM_STATIC=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSEMEM_VMEMMAP=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=0
@@ -275,10 +282,6 @@
 # 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
 
 #
@@ -372,8 +375,6 @@
 # CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_ONLYDISK=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_WDC_ALI15X3 is not set
@@ -401,6 +402,7 @@
 # CONFIG_BLK_DEV_TC86C001 is not set
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDE_ARCH_OBSOLETE_INIT=y
 # CONFIG_BLK_DEV_HD is not set
 
 #
@@ -441,6 +443,7 @@
 CONFIG_SCSI_ISCSI_ATTRS=m
 # CONFIG_SCSI_SAS_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 CONFIG_ISCSI_TCP=m
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
@@ -492,14 +495,8 @@
 CONFIG_DM_ZERO=m
 # CONFIG_DM_MULTIPATH is not set
 # CONFIG_DM_DELAY is not set
-
-#
-# Fusion MPT device support
-#
+# CONFIG_DM_UEVENT is not set
 # CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -638,7 +635,6 @@
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
@@ -714,11 +710,9 @@
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
@@ -786,8 +780,6 @@
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_ABITUGURU3 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
@@ -795,12 +787,12 @@
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
@@ -836,6 +828,7 @@
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_WATCHDOG is not set
 
 #
 # Sonics Silicon Backplane
@@ -858,12 +851,7 @@
 #
 # Graphics support
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
 CONFIG_FB=y
@@ -872,6 +860,7 @@
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
 # CONFIG_FB_SYS_FILLRECT is not set
 # CONFIG_FB_SYS_COPYAREA is not set
 # CONFIG_FB_SYS_IMAGEBLIT is not set
@@ -890,6 +879,7 @@
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
+# CONFIG_FB_UVESA is not set
 # CONFIG_FB_SBUS is not set
 # CONFIG_FB_XVR500 is not set
 # CONFIG_FB_XVR2500 is not set
@@ -915,6 +905,12 @@
 # CONFIG_FB_ARK is not set
 # CONFIG_FB_PM3 is not set
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
 
 #
 # Console display driver support
@@ -1066,6 +1062,7 @@
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
 
 #
 # USB Input Devices
@@ -1187,19 +1184,6 @@
 # CONFIG_RTC_CLASS is not set
 
 #
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
 # Userspace I/O
 #
 # CONFIG_UIO is not set
@@ -1275,7 +1259,6 @@
 # CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1295,10 +1278,7 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
@@ -1313,10 +1293,6 @@
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
 CONFIG_SUN_PARTITION=y
-
-#
-# Native Language Support
-#
 CONFIG_NLS=m
 CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_CODEPAGE_437 is not set
@@ -1357,18 +1333,12 @@
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
 # CONFIG_DLM is not set
-
-#
-# Instrumentation Support
-#
+CONFIG_INSTRUMENTATION=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=m
 CONFIG_KPROBES=y
+# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
@@ -1402,9 +1372,11 @@
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_DCFLUSH is not set
 # CONFIG_STACK_DEBUG is not set
@@ -1417,6 +1389,7 @@
 CONFIG_KEYS=y
 # CONFIG_KEYS_DEBUG_PROC_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_XOR_BLOCKS=m
 CONFIG_ASYNC_CORE=m
 CONFIG_ASYNC_MEMCPY=m
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 112c46e..ef50d21 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -39,12 +39,3 @@
     obj-y += sys_sunos32.o sunos_ioctl32.o
   endif
 endif
-
-ifneq ($(NEW_GCC),y)
-  CMODEL_CFLAG := -mmedlow
-else
-  CMODEL_CFLAG := -m64 -mcmodel=medlow
-endif
-
-head.o: head.S ttable.S itlb_miss.S dtlb_miss.S ktlb.S tsb.S \
-	etrap.S rtrap.S winfixup.S entry.S
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 29af777..070a484 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -472,8 +472,7 @@
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
-#define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+#define SG_ENT_PHYS_ADDRESS(SG)	(__pa(sg_virt((SG))))
 
 static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
 		    int nused, int nelems,
@@ -565,9 +564,7 @@
 	/* Fast path single entry scatterlists. */
 	if (nelems == 1) {
 		sglist->dma_address =
-			dma_4u_map_single(dev,
-					  (page_address(sglist->page) +
-					   sglist->offset),
+			dma_4u_map_single(dev, sg_virt(sglist),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
 			return 0;
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index d7ca900..b70324e 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -73,7 +73,7 @@
 
 	daddr = dma_sg->dma_address;
 	sglen = sg->length;
-	sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+	sgaddr = (unsigned long) sg_virt(sg);
 	while (dlen > 0) {
 		unsigned long paddr;
 
@@ -123,7 +123,7 @@
 		sg = sg_next(sg);
 		if (--nents <= 0)
 			break;
-		sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+		sgaddr = (unsigned long) sg_virt(sg);
 		sglen = sg->length;
 	}
 	if (dlen < 0) {
@@ -191,7 +191,7 @@
 			printk("sg(%d): page_addr(%p) off(%x) length(%x) "
 			       "dma_address[%016x] dma_length[%016x]\n",
 			       i,
-			       page_address(sg->page), sg->offset,
+			       page_address(sg_page(sg)), sg->offset,
 			       sg->length,
 			       sg->dma_address, sg->dma_length);
 		}
@@ -207,15 +207,14 @@
 	unsigned long prev;
 	u32 dent_addr, dent_len;
 
-	prev  = (unsigned long) (page_address(sg->page) + sg->offset);
+	prev  = (unsigned long) sg_virt(sg);
 	prev += (unsigned long) (dent_len = sg->length);
-	dent_addr = (u32) ((unsigned long)(page_address(sg->page) + sg->offset)
-			   & (IO_PAGE_SIZE - 1UL));
+	dent_addr = (u32) ((unsigned long)(sg_virt(sg)) & (IO_PAGE_SIZE - 1UL));
 	while (--nents) {
 		unsigned long addr;
 
 		sg = sg_next(sg);
-		addr = (unsigned long) (page_address(sg->page) + sg->offset);
+		addr = (unsigned long) sg_virt(sg);
 		if (! VCONTIG(prev, addr)) {
 			dma_sg->dma_address = dent_addr;
 			dma_sg->dma_length = dent_len;
@@ -234,6 +233,11 @@
 	dma_sg->dma_address = dent_addr;
 	dma_sg->dma_length = dent_len;
 
+	if (dma_sg != sg) {
+		dma_sg = next_sg(dma_sg);
+		dma_sg->dma_length = 0;
+	}
+
 	return ((unsigned long) dent_addr +
 		(unsigned long) dent_len +
 		(IO_PAGE_SIZE - 1UL)) >> IO_PAGE_SHIFT;
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index f3922e5..30431bd 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -257,8 +257,8 @@
 	unsigned long	imap;
 
 	void		(*pre_handler)(unsigned int, void *, void *);
-	void		*pre_handler_arg1;
-	void		*pre_handler_arg2;
+	void		*arg1;
+	void		*arg2;
 };
 
 #ifdef CONFIG_SMP
@@ -346,7 +346,7 @@
 	}
 }
 
-static void sun4u_irq_end(unsigned int virt_irq)
+static void sun4u_irq_eoi(unsigned int virt_irq)
 {
 	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
 	struct irq_desc *desc = irq_desc + virt_irq;
@@ -401,7 +401,7 @@
 		       "err(%d)\n", ino, err);
 }
 
-static void sun4v_irq_end(unsigned int virt_irq)
+static void sun4v_irq_eoi(unsigned int virt_irq)
 {
 	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
 	struct irq_desc *desc = irq_desc + virt_irq;
@@ -478,7 +478,7 @@
 		       dev_handle, dev_ino, err);
 }
 
-static void sun4v_virq_end(unsigned int virt_irq)
+static void sun4v_virq_eoi(unsigned int virt_irq)
 {
 	struct irq_desc *desc = irq_desc + virt_irq;
 	unsigned long dev_handle, dev_ino;
@@ -498,33 +498,11 @@
 		       dev_handle, dev_ino, err);
 }
 
-static void run_pre_handler(unsigned int virt_irq)
-{
-	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
-	unsigned int ino;
-
-	ino = virt_irq_table[virt_irq].dev_ino;
-	if (likely(data->pre_handler)) {
-		data->pre_handler(ino,
-				  data->pre_handler_arg1,
-				  data->pre_handler_arg2);
-	}
-}
-
 static struct irq_chip sun4u_irq = {
 	.typename	= "sun4u",
 	.enable		= sun4u_irq_enable,
 	.disable	= sun4u_irq_disable,
-	.end		= sun4u_irq_end,
-	.set_affinity	= sun4u_set_affinity,
-};
-
-static struct irq_chip sun4u_irq_ack = {
-	.typename	= "sun4u+ack",
-	.enable		= sun4u_irq_enable,
-	.disable	= sun4u_irq_disable,
-	.ack		= run_pre_handler,
-	.end		= sun4u_irq_end,
+	.eoi		= sun4u_irq_eoi,
 	.set_affinity	= sun4u_set_affinity,
 };
 
@@ -532,7 +510,7 @@
 	.typename	= "sun4v",
 	.enable		= sun4v_irq_enable,
 	.disable	= sun4v_irq_disable,
-	.end		= sun4v_irq_end,
+	.eoi		= sun4v_irq_eoi,
 	.set_affinity	= sun4v_set_affinity,
 };
 
@@ -540,31 +518,33 @@
 	.typename	= "vsun4v",
 	.enable		= sun4v_virq_enable,
 	.disable	= sun4v_virq_disable,
-	.end		= sun4v_virq_end,
+	.eoi		= sun4v_virq_eoi,
 	.set_affinity	= sun4v_virt_set_affinity,
 };
 
+static void fastcall pre_flow_handler(unsigned int virt_irq,
+				      struct irq_desc *desc)
+{
+	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
+	unsigned int ino = virt_irq_table[virt_irq].dev_ino;
+
+	data->pre_handler(ino, data->arg1, data->arg2);
+
+	handle_fasteoi_irq(virt_irq, desc);
+}
+
 void irq_install_pre_handler(int virt_irq,
 			     void (*func)(unsigned int, void *, void *),
 			     void *arg1, void *arg2)
 {
 	struct irq_handler_data *data = get_irq_chip_data(virt_irq);
-	struct irq_chip *chip = get_irq_chip(virt_irq);
-
-	if (WARN_ON(chip == &sun4v_irq || chip == &sun4v_virq)) {
-		printk(KERN_ERR "IRQ: Trying to install pre-handler on "
-		       "sun4v irq %u\n", virt_irq);
-		return;
-	}
+	struct irq_desc *desc = irq_desc + virt_irq;
 
 	data->pre_handler = func;
-	data->pre_handler_arg1 = arg1;
-	data->pre_handler_arg2 = arg2;
+	data->arg1 = arg1;
+	data->arg2 = arg2;
 
-	if (chip == &sun4u_irq_ack)
-		return;
-
-	set_irq_chip(virt_irq, &sun4u_irq_ack);
+	desc->handle_irq = pre_flow_handler;
 }
 
 unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
@@ -582,7 +562,10 @@
 	if (!virt_irq) {
 		virt_irq = virt_irq_alloc(0, ino);
 		bucket_set_virt_irq(__pa(bucket), virt_irq);
-		set_irq_chip(virt_irq, &sun4u_irq);
+		set_irq_chip_and_handler_name(virt_irq,
+					      &sun4u_irq,
+					      handle_fasteoi_irq,
+					      "IVEC");
 	}
 
 	data = get_irq_chip_data(virt_irq);
@@ -617,7 +600,9 @@
 	if (!virt_irq) {
 		virt_irq = virt_irq_alloc(0, sysino);
 		bucket_set_virt_irq(__pa(bucket), virt_irq);
-		set_irq_chip(virt_irq, chip);
+		set_irq_chip_and_handler_name(virt_irq, chip,
+					      handle_fasteoi_irq,
+					      "IVEC");
 	}
 
 	data = get_irq_chip_data(virt_irq);
@@ -665,7 +650,10 @@
 
 	virt_irq = virt_irq_alloc(devhandle, devino);
 	bucket_set_virt_irq(__pa(bucket), virt_irq);
-	set_irq_chip(virt_irq, &sun4v_virq);
+
+	set_irq_chip_and_handler_name(virt_irq, &sun4v_virq,
+				      handle_fasteoi_irq,
+				      "IVEC");
 
 	data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC);
 	if (unlikely(!data))
@@ -724,6 +712,7 @@
 			     : "memory");
 
 	while (bucket_pa) {
+		struct irq_desc *desc;
 		unsigned long next_pa;
 		unsigned int virt_irq;
 
@@ -731,7 +720,9 @@
 		virt_irq = bucket_get_virt_irq(bucket_pa);
 		bucket_clear_chain_pa(bucket_pa);
 
-		__do_IRQ(virt_irq);
+		desc = irq_desc + virt_irq;
+
+		desc->handle_irq(virt_irq, desc);
 
 		bucket_pa = next_pa;
 	}
@@ -877,7 +868,7 @@
 static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask)
 {
 	unsigned long size = PAGE_ALIGN(qmask + 1);
-	void *p = __alloc_bootmem_low(size, size, 0);
+	void *p = __alloc_bootmem(size, size, 0);
 	if (!p) {
 		prom_printf("SUN4V: Error, cannot allocate mondo queue.\n");
 		prom_halt();
@@ -889,7 +880,7 @@
 static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask)
 {
 	unsigned long size = PAGE_ALIGN(qmask + 1);
-	void *p = __alloc_bootmem_low(size, size, 0);
+	void *p = __alloc_bootmem(size, size, 0);
 
 	if (!p) {
 		prom_printf("SUN4V: Error, cannot allocate kbuf page.\n");
@@ -906,7 +897,7 @@
 
 	BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64));
 
-	page = alloc_bootmem_low_pages(PAGE_SIZE);
+	page = alloc_bootmem_pages(PAGE_SIZE);
 	if (!page) {
 		prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n");
 		prom_halt();
@@ -953,7 +944,7 @@
 	kill_prom_timer();
 
 	size = sizeof(struct ino_bucket) * NUM_IVECS;
-	ivector_table = alloc_bootmem_low(size);
+	ivector_table = alloc_bootmem(size);
 	if (!ivector_table) {
 		prom_printf("Fatal error, cannot allocate ivector_table\n");
 		prom_halt();
diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c
index 85a2be0..c8313cb 100644
--- a/arch/sparc64/kernel/ldc.c
+++ b/arch/sparc64/kernel/ldc.c
@@ -2057,7 +2057,7 @@
 
 static int sg_count_one(struct scatterlist *sg)
 {
-	unsigned long base = page_to_pfn(sg->page) << PAGE_SHIFT;
+	unsigned long base = page_to_pfn(sg_page(sg)) << PAGE_SHIFT;
 	long len = sg->length;
 
 	if ((sg->offset | len) & (8UL - 1))
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index 42d7798..fc5c0cc 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -869,26 +869,6 @@
 
 __setup("of_debug=", of_debug);
 
-int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
-{
-	/* initialize common driver fields */
-	if (!drv->driver.name)
-		drv->driver.name = drv->name;
-	if (!drv->driver.owner)
-		drv->driver.owner = drv->owner;
-	drv->driver.bus = bus;
-
-	/* register with core */
-	return driver_register(&drv->driver);
-}
-EXPORT_SYMBOL(of_register_driver);
-
-void of_unregister_driver(struct of_platform_driver *drv)
-{
-	driver_unregister(&drv->driver);
-}
-EXPORT_SYMBOL(of_unregister_driver);
-
 struct of_device* of_platform_device_create(struct device_node *np,
 					    const char *bus_id,
 					    struct device *parent,
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 9b80864..63b3ebc 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -207,8 +207,7 @@
 	{ "SUNW,sun4v-pci", sun4v_pci_init },
 	{ "pciex108e,80f0", fire_pci_init },
 };
-#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \
-				  sizeof(pci_controller_table[0]))
+#define PCI_NUM_CONTROLLER_TYPES	ARRAY_SIZE(pci_controller_table)
 
 static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp)
 {
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c
index c76bfbb..923e0bc 100644
--- a/arch/sparc64/kernel/pci_common.c
+++ b/arch/sparc64/kernel/pci_common.c
@@ -396,6 +396,13 @@
 
 	saw_mem = saw_io = 0;
 	pbm_ranges = of_get_property(pbm->prom_node, "ranges", &i);
+	if (!pbm_ranges) {
+		prom_printf("PCI: Fatal error, missing PBM ranges property "
+			    " for %s\n",
+			    pbm->name);
+		prom_halt();
+	}
+
 	num_pbm_ranges = i / sizeof(*pbm_ranges);
 
 	for (i = 0; i < num_pbm_ranges; i++) {
diff --git a/arch/sparc64/kernel/pci_msi.c b/arch/sparc64/kernel/pci_msi.c
index 31a165f..d6d64b4 100644
--- a/arch/sparc64/kernel/pci_msi.c
+++ b/arch/sparc64/kernel/pci_msi.c
@@ -28,8 +28,15 @@
 		unsigned long msi;
 
 		err = ops->dequeue_msi(pbm, msiqid, &head, &msi);
-		if (likely(err > 0))
-			__do_IRQ(pbm->msi_irq_table[msi - pbm->msi_first]);
+		if (likely(err > 0)) {
+			struct irq_desc *desc;
+			unsigned int virt_irq;
+
+			virt_irq = pbm->msi_irq_table[msi - pbm->msi_first];
+			desc = irq_desc + virt_irq;
+
+			desc->handle_irq(virt_irq, desc);
+		}
 
 		if (unlikely(err < 0))
 			goto err_dequeue;
@@ -128,7 +135,8 @@
 	if (!*virt_irq_p)
 		goto out_err;
 
-	set_irq_chip(*virt_irq_p, &msi_irq);
+	set_irq_chip_and_handler_name(*virt_irq_p, &msi_irq,
+				      handle_simple_irq, "MSI");
 
 	err = alloc_msi(pbm);
 	if (unlikely(err < 0))
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index fe46ace..8c4875b 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -365,8 +365,7 @@
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
-#define SG_ENT_PHYS_ADDRESS(SG)	\
-	(__pa(page_address((SG)->page)) + (SG)->offset)
+#define SG_ENT_PHYS_ADDRESS(SG)	(__pa(sg_virt((SG))))
 
 static long fill_sg(long entry, struct device *dev,
 		    struct scatterlist *sg,
@@ -477,9 +476,7 @@
 	/* Fast path single entry scatterlists. */
 	if (nelems == 1) {
 		sglist->dma_address =
-			dma_4v_map_single(dev,
-					  (page_address(sglist->page) +
-					   sglist->offset),
+			dma_4v_map_single(dev, sg_virt(sglist),
 					  sglist->length, direction);
 		if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
 			return 0;
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 8f7a06e..170d6ca 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -831,7 +831,7 @@
 	rcu_read_lock();
 	ret = -EINVAL;
 	if (pgrp > 0)
-		ret = kill_pgrp(find_pid(pgrp), sig, 0);
+		ret = kill_pgrp(find_vpid(pgrp), sig, 0);
 	rcu_read_unlock();
 
 	return ret;
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 34573a5..e9c7e4f 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -2225,7 +2225,7 @@
 "              /_| \\__/ |_\\\n"
 "                 \\__U_/\n");
 
-	printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
+	printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter);
 	notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);
 	__asm__ __volatile__("flushw");
 	__show_regs(regs);
diff --git a/arch/sparc64/lib/atomic.S b/arch/sparc64/lib/atomic.S
index 9633750..70ac418 100644
--- a/arch/sparc64/lib/atomic.S
+++ b/arch/sparc64/lib/atomic.S
@@ -1,10 +1,10 @@
-/* $Id: atomic.S,v 1.4 2001/11/18 00:12:56 davem Exp $
- * atomic.S: These things are too big to do inline.
+/* atomic.S: These things are too big to do inline.
  *
- * Copyright (C) 1999 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #include <asm/asi.h>
+#include <asm/backoff.h>
 
 	.text
 
@@ -16,27 +16,31 @@
 	.globl	atomic_add
 	.type	atomic_add,#function
 atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
+	BACKOFF_SETUP(%o2)
 1:	lduw	[%o1], %g1
 	add	%g1, %o0, %g7
 	cas	[%o1], %g1, %g7
 	cmp	%g1, %g7
-	bne,pn	%icc, 1b
+	bne,pn	%icc, 2f
 	 nop
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o2, %o3, 1b)
 	.size	atomic_add, .-atomic_add
 
 	.globl	atomic_sub
 	.type	atomic_sub,#function
 atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
+	BACKOFF_SETUP(%o2)
 1:	lduw	[%o1], %g1
 	sub	%g1, %o0, %g7
 	cas	[%o1], %g1, %g7
 	cmp	%g1, %g7
-	bne,pn	%icc, 1b
+	bne,pn	%icc, 2f
 	 nop
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o2, %o3, 1b)
 	.size	atomic_sub, .-atomic_sub
 
 	/* On SMP we need to use memory barriers to ensure
@@ -60,89 +64,101 @@
 	.globl	atomic_add_ret
 	.type	atomic_add_ret,#function
 atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
+	BACKOFF_SETUP(%o2)
 	ATOMIC_PRE_BARRIER
 1:	lduw	[%o1], %g1
 	add	%g1, %o0, %g7
 	cas	[%o1], %g1, %g7
 	cmp	%g1, %g7
-	bne,pn	%icc, 1b
+	bne,pn	%icc, 2f
 	 add	%g7, %o0, %g7
 	sra	%g7, 0, %o0
 	ATOMIC_POST_BARRIER
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o2, %o3, 1b)
 	.size	atomic_add_ret, .-atomic_add_ret
 
 	.globl	atomic_sub_ret
 	.type	atomic_sub_ret,#function
 atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
+	BACKOFF_SETUP(%o2)
 	ATOMIC_PRE_BARRIER
 1:	lduw	[%o1], %g1
 	sub	%g1, %o0, %g7
 	cas	[%o1], %g1, %g7
 	cmp	%g1, %g7
-	bne,pn	%icc, 1b
+	bne,pn	%icc, 2f
 	 sub	%g7, %o0, %g7
 	sra	%g7, 0, %o0
 	ATOMIC_POST_BARRIER
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o2, %o3, 1b)
 	.size	atomic_sub_ret, .-atomic_sub_ret
 
 	.globl	atomic64_add
 	.type	atomic64_add,#function
 atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
+	BACKOFF_SETUP(%o2)
 1:	ldx	[%o1], %g1
 	add	%g1, %o0, %g7
 	casx	[%o1], %g1, %g7
 	cmp	%g1, %g7
-	bne,pn	%xcc, 1b
+	bne,pn	%xcc, 2f
 	 nop
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o2, %o3, 1b)
 	.size	atomic64_add, .-atomic64_add
 
 	.globl	atomic64_sub
 	.type	atomic64_sub,#function
 atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
+	BACKOFF_SETUP(%o2)
 1:	ldx	[%o1], %g1
 	sub	%g1, %o0, %g7
 	casx	[%o1], %g1, %g7
 	cmp	%g1, %g7
-	bne,pn	%xcc, 1b
+	bne,pn	%xcc, 2f
 	 nop
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o2, %o3, 1b)
 	.size	atomic64_sub, .-atomic64_sub
 
 	.globl	atomic64_add_ret
 	.type	atomic64_add_ret,#function
 atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
+	BACKOFF_SETUP(%o2)
 	ATOMIC_PRE_BARRIER
 1:	ldx	[%o1], %g1
 	add	%g1, %o0, %g7
 	casx	[%o1], %g1, %g7
 	cmp	%g1, %g7
-	bne,pn	%xcc, 1b
+	bne,pn	%xcc, 2f
 	 add	%g7, %o0, %g7
 	mov	%g7, %o0
 	ATOMIC_POST_BARRIER
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o2, %o3, 1b)
 	.size	atomic64_add_ret, .-atomic64_add_ret
 
 	.globl	atomic64_sub_ret
 	.type	atomic64_sub_ret,#function
 atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
+	BACKOFF_SETUP(%o2)
 	ATOMIC_PRE_BARRIER
 1:	ldx	[%o1], %g1
 	sub	%g1, %o0, %g7
 	casx	[%o1], %g1, %g7
 	cmp	%g1, %g7
-	bne,pn	%xcc, 1b
+	bne,pn	%xcc, 2f
 	 sub	%g7, %o0, %g7
 	mov	%g7, %o0
 	ATOMIC_POST_BARRIER
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o2, %o3, 1b)
 	.size	atomic64_sub_ret, .-atomic64_sub_ret
diff --git a/arch/sparc64/lib/bitops.S b/arch/sparc64/lib/bitops.S
index 892431a..6b015a6 100644
--- a/arch/sparc64/lib/bitops.S
+++ b/arch/sparc64/lib/bitops.S
@@ -1,10 +1,10 @@
-/* $Id: bitops.S,v 1.3 2001/11/18 00:12:56 davem Exp $
- * bitops.S: Sparc64 atomic bit operations.
+/* bitops.S: Sparc64 atomic bit operations.
  *
- * Copyright (C) 2000 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #include <asm/asi.h>
+#include <asm/backoff.h>
 
 	.text
 
@@ -29,6 +29,7 @@
 	.globl	test_and_set_bit
 	.type	test_and_set_bit,#function
 test_and_set_bit:	/* %o0=nr, %o1=addr */
+	BACKOFF_SETUP(%o3)
 	BITOP_PRE_BARRIER
 	srlx	%o0, 6, %g1
 	mov	1, %o2
@@ -40,18 +41,20 @@
 	or	%g7, %o2, %g1
 	casx	[%o1], %g7, %g1
 	cmp	%g7, %g1
-	bne,pn	%xcc, 1b
+	bne,pn	%xcc, 2f
 	 and	%g7, %o2, %g2
 	clr	%o0
 	movrne	%g2, 1, %o0
 	BITOP_POST_BARRIER
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o3, %o4, 1b)
 	.size	test_and_set_bit, .-test_and_set_bit
 
 	.globl	test_and_clear_bit
 	.type	test_and_clear_bit,#function
 test_and_clear_bit:	/* %o0=nr, %o1=addr */
+	BACKOFF_SETUP(%o3)
 	BITOP_PRE_BARRIER
 	srlx	%o0, 6, %g1
 	mov	1, %o2
@@ -63,18 +66,20 @@
 	andn	%g7, %o2, %g1
 	casx	[%o1], %g7, %g1
 	cmp	%g7, %g1
-	bne,pn	%xcc, 1b
+	bne,pn	%xcc, 2f
 	 and	%g7, %o2, %g2
 	clr	%o0
 	movrne	%g2, 1, %o0
 	BITOP_POST_BARRIER
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o3, %o4, 1b)
 	.size	test_and_clear_bit, .-test_and_clear_bit
 
 	.globl	test_and_change_bit
 	.type	test_and_change_bit,#function
 test_and_change_bit:	/* %o0=nr, %o1=addr */
+	BACKOFF_SETUP(%o3)
 	BITOP_PRE_BARRIER
 	srlx	%o0, 6, %g1
 	mov	1, %o2
@@ -86,18 +91,20 @@
 	xor	%g7, %o2, %g1
 	casx	[%o1], %g7, %g1
 	cmp	%g7, %g1
-	bne,pn	%xcc, 1b
+	bne,pn	%xcc, 2f
 	 and	%g7, %o2, %g2
 	clr	%o0
 	movrne	%g2, 1, %o0
 	BITOP_POST_BARRIER
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o3, %o4, 1b)
 	.size	test_and_change_bit, .-test_and_change_bit
 
 	.globl	set_bit
 	.type	set_bit,#function
 set_bit:		/* %o0=nr, %o1=addr */
+	BACKOFF_SETUP(%o3)
 	srlx	%o0, 6, %g1
 	mov	1, %o2
 	sllx	%g1, 3, %g3
@@ -108,15 +115,17 @@
 	or	%g7, %o2, %g1
 	casx	[%o1], %g7, %g1
 	cmp	%g7, %g1
-	bne,pn	%xcc, 1b
+	bne,pn	%xcc, 2f
 	 nop
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o3, %o4, 1b)
 	.size	set_bit, .-set_bit
 
 	.globl	clear_bit
 	.type	clear_bit,#function
 clear_bit:		/* %o0=nr, %o1=addr */
+	BACKOFF_SETUP(%o3)
 	srlx	%o0, 6, %g1
 	mov	1, %o2
 	sllx	%g1, 3, %g3
@@ -127,15 +136,17 @@
 	andn	%g7, %o2, %g1
 	casx	[%o1], %g7, %g1
 	cmp	%g7, %g1
-	bne,pn	%xcc, 1b
+	bne,pn	%xcc, 2f
 	 nop
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o3, %o4, 1b)
 	.size	clear_bit, .-clear_bit
 
 	.globl	change_bit
 	.type	change_bit,#function
 change_bit:		/* %o0=nr, %o1=addr */
+	BACKOFF_SETUP(%o3)
 	srlx	%o0, 6, %g1
 	mov	1, %o2
 	sllx	%g1, 3, %g3
@@ -146,8 +157,9 @@
 	xor	%g7, %o2, %g1
 	casx	[%o1], %g7, %g1
 	cmp	%g7, %g1
-	bne,pn	%xcc, 1b
+	bne,pn	%xcc, 2f
 	 nop
 	retl
 	 nop
+2:	BACKOFF_SPIN(%o3, %o4, 1b)
 	.size	change_bit, .-change_bit
diff --git a/arch/sparc64/math-emu/Makefile b/arch/sparc64/math-emu/Makefile
index a0b06fd..cc5cb9b 100644
--- a/arch/sparc64/math-emu/Makefile
+++ b/arch/sparc64/math-emu/Makefile
@@ -4,4 +4,4 @@
 
 obj-y    := math.o
 
-EXTRA_CFLAGS = -I. -Iinclude/math-emu -w
+EXTRA_CFLAGS = -Iinclude/math-emu -w
diff --git a/arch/sparc64/oprofile/Kconfig b/arch/sparc64/oprofile/Kconfig
deleted file mode 100644
index d8a8408..0000000
--- a/arch/sparc64/oprofile/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-config PROFILING
-	bool "Profiling support (EXPERIMENTAL)"
-	help
-	  Say Y here to enable the extended profiling support mechanisms used
-	  by profilers such as OProfile.
-	  
-
-config OPROFILE
-	tristate "OProfile system profiling (EXPERIMENTAL)"
-	depends on PROFILING
-	help
-	  OProfile is a profiling system capable of profiling the
-	  whole system, include the kernel, kernel modules, libraries,
-	  and applications.
-
-	  If unsure, say N.
-
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index 3b67de7..c86cb30 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -415,7 +415,7 @@
 	
 	switch (cmd) {
 	case 0: /* getpgrp */
-		return process_group(current);
+		return task_pgrp_nr(current);
 	case 1: /* setpgrp */
 		{
 			int (*sys_setpgid)(pid_t,pid_t) =
@@ -426,7 +426,7 @@
 			ret = sys_setpgid(0, 0);
 			if (ret) return ret;
 			proc_clear_tty(current);
-			return process_group(current);
+			return task_pgrp_nr(current);
 		}
 	case 2: /* getsid */
 		{
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 740d8a9..dd1689b 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -3,7 +3,7 @@
 	option defconfig_list
 	default "arch/$ARCH/defconfig"
 
-# UML uses the generic IRQ sugsystem
+# UML uses the generic IRQ subsystem
 config GENERIC_HARDIRQS
 	bool
 	default y
@@ -289,4 +289,6 @@
 	bool
 	default n
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/um/Kconfig.debug"
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 76fe0b0..83bf15a 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -35,7 +35,7 @@
 /*
  * Returns the free space inside the ring buffer of this line.
  *
- * Should be called while holding line->lock (this does not modify datas).
+ * Should be called while holding line->lock (this does not modify data).
  */
 static int write_room(struct line *line)
 {
diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c
index 21ad3d7..2b45a14 100644
--- a/arch/um/drivers/null.c
+++ b/arch/um/drivers/null.c
@@ -9,7 +9,7 @@
 #include "chan_user.h"
 #include "os.h"
 
-/* This address is used only as a unique identifer */
+/* This address is used only as a unique identifier */
 static int null_chan;
 
 static void *null_init(char *str, int device, const struct chan_opts *opts)
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index ae67e71..6b4a0f9 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -31,10 +31,8 @@
 	slip_proto_init(&spri->slip);
 
 	dev->init = NULL;
-	dev->header_cache_update = NULL;
-	dev->hard_header_cache = NULL;
-	dev->hard_header = NULL;
 	dev->hard_header_len = 0;
+	dev->header_ops = NULL;
 	dev->addr_len = 0;
 	dev->type = ARPHRD_SLIP;
 	dev->tx_queue_len = 256;
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index 240ee65..d987af2 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -34,9 +34,7 @@
 
 	dev->init = NULL;
 	dev->hard_header_len = 0;
-	dev->header_cache_update = NULL;
-	dev->hard_header_cache = NULL;
-	dev->hard_header = NULL;
+	dev->header_ops = NULL;
 	dev->addr_len = 0;
 	dev->type = ARPHRD_SLIP;
 	dev->tx_queue_len = 256;
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c
index 4739dd5..d07a97f 100644
--- a/arch/um/drivers/stderr_console.c
+++ b/arch/um/drivers/stderr_console.c
@@ -8,7 +8,7 @@
 /* trivial console driver -- simply dump everything to stderr                    */
 
 /*
- * Don't register by default -- as this registeres very early in the
+ * Don't register by default -- as this registers very early in the
  * boot process it becomes the default console.
  *
  * Initialized at init time.
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 25b248a..3a8cd3d 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1115,7 +1115,7 @@
 			}
 			prepare_request(req, io_req,
 					(unsigned long long) req->sector << 9,
-					sg->offset, sg->length, sg->page);
+					sg->offset, sg->length, sg_page(sg));
 
 			last_sectors = sg->length >> 9;
 			n = os_write_file(thread_fd, &io_req,
diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c
index 13aa115..734f873 100644
--- a/arch/um/kernel/gmon_syms.c
+++ b/arch/um/kernel/gmon_syms.c
@@ -12,8 +12,8 @@
  * versions in libgcov.
  *
  * Since SuSE backported the fix, we cannot handle it depending on GCC version.
- * So, unconditinally export it. But also give it a weak declaration, which will
- * be overriden by any other one.
+ * So, unconditionally export it. But also give it a weak declaration, which will
+ * be overridden by any other one.
  */
 
 extern void __gcov_init(void *) __attribute__((weak));
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 277fce1..70c2d62 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -326,7 +326,7 @@
 }
 
 /*
- * do_IRQ handles all normal device IRQ's (the special
+ * do_IRQ handles all normal device IRQs (the special
  * SMP cross-CPU interrupts have their own specific
  * handlers).
  */
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index a0eba08..47b57b4 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -237,7 +237,7 @@
 	/* User-mode eip? */
 	info.si_addr = UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL;
 
-	/* Send us the fakey SIGTRAP */
+	/* Send us the fake SIGTRAP */
 	force_sig_info(SIGTRAP, &info, tsk);
 }
 
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index bd06055..cb3321f 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -108,7 +108,7 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		up_read(&mm->mmap_sem);
 		yield();
 		down_read(&mm->mmap_sem);
diff --git a/arch/um/sys-i386/bug.c b/arch/um/sys-i386/bug.c
index 200c8ba..a4360b5 100644
--- a/arch/um/sys-i386/bug.c
+++ b/arch/um/sys-i386/bug.c
@@ -6,7 +6,7 @@
 #include <linux/uaccess.h>
 
 /* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because
- * that's not relevent in skas mode.
+ * that's not relevant in skas mode.
  */
 
 int is_valid_bugaddr(unsigned long eip)
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c
index b02266a..fcaff86 100644
--- a/arch/um/sys-i386/tls.c
+++ b/arch/um/sys-i386/tls.c
@@ -45,7 +45,7 @@
  * XXX: Consider leaving one free slot for glibc usage at first place. This must
  * be done here (and by changing GDT_ENTRY_TLS_* macros) and nowhere else.
  *
- * Also, this must be tested when compiling in SKAS mode with dinamic linking
+ * Also, this must be tested when compiling in SKAS mode with dynamic linking
  * and running against NPTL.
  */
 static int get_free_idx(struct task_struct* task)
diff --git a/arch/um/sys-x86_64/bug.c b/arch/um/sys-x86_64/bug.c
index 200c8ba..a4360b5 100644
--- a/arch/um/sys-x86_64/bug.c
+++ b/arch/um/sys-x86_64/bug.c
@@ -6,7 +6,7 @@
 #include <linux/uaccess.h>
 
 /* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because
- * that's not relevent in skas mode.
+ * that's not relevant in skas mode.
  */
 
 int is_valid_bugaddr(unsigned long eip)
diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c
index ce3e07f..7654440 100644
--- a/arch/um/sys-x86_64/sysrq.c
+++ b/arch/um/sys-x86_64/sysrq.c
@@ -15,8 +15,8 @@
 {
 	printk("\n");
 	print_modules();
-	printk("Pid: %d, comm: %.20s %s %s\n",
-	       current->pid, current->comm, print_tainted(), init_utsname()->release);
+	printk("Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current),
+		current->comm, print_tainted(), init_utsname()->release);
 	printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff,
 	       PT_REGS_RIP(regs));
 	printk("\nRSP: %016lx  EFLAGS: %08lx\n", PT_REGS_RSP(regs),
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index ace479a..b6a50b8 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -331,6 +331,8 @@
 
 source "drivers/usb/Kconfig"
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/v850/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/v850/kernel/me2.c b/arch/v850/kernel/me2.c
index 38be5c1..007115d 100644
--- a/arch/v850/kernel/me2.c
+++ b/arch/v850/kernel/me2.c
@@ -58,13 +58,13 @@
 void me2_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
 {
 	if (chan == 0) {
-		/* Specify that the relevent pins on the chip should do
+		/* Specify that the relevant pins on the chip should do
 		   serial I/O, not direct I/O.  */
 		ME2_PORT1_PMC |= 0xC;
 		/* Specify that we're using the UART, not the CSI device. */
 		ME2_PORT1_PFC |= 0xC;
 	} else if (chan == 1) {
-		/* Specify that the relevent pins on the chip should do
+		/* Specify that the relevant pins on the chip should do
 		   serial I/O, not direct I/O.  */
 		ME2_PORT2_PMC |= 0x6;
 		/* Specify that we're using the UART, not the CSI device. */
diff --git a/arch/v850/kernel/rte_mb_a_pci.c b/arch/v850/kernel/rte_mb_a_pci.c
index 35a4bd5..7165478 100644
--- a/arch/v850/kernel/rte_mb_a_pci.c
+++ b/arch/v850/kernel/rte_mb_a_pci.c
@@ -179,7 +179,7 @@
 		   default uses.  */
 
 		/* Significant address bits used for decoding PCI GCS5 space
-		   accessess.  */
+		   accesses.  */
 		MB_A_PCI_DMRR = ~(MB_A_PCI_MEM_SIZE - 1);
 
 		/* I don't understand this, but the SolutionGear example code
@@ -775,7 +775,7 @@
 /* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
    be values that were returned from pci_alloc_consistent.  SIZE must be
    the same as what as passed into pci_alloc_consistent.  References to
-   the memory and mappings assosciated with CPU_ADDR or DMA_ADDR past
+   the memory and mappings associated with CPU_ADDR or DMA_ADDR past
    this call are illegal.  */
 void
 pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr,
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index f35ea22..a0ae2e7 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -27,13 +27,22 @@
 #include <asm/segment.h>
 #include <asm/page.h>
 #include <asm/boot.h>
+#include <asm/asm-offsets.h>
 
 .section ".text.head","ax",@progbits
 	.globl startup_32
 
 startup_32:
-	cld
-	cli
+	/* check to see if KEEP_SEGMENTS flag is meaningful */
+	cmpw $0x207, BP_version(%esi)
+	jb 1f
+
+	/* test KEEP_SEGMENTS flag to see if the bootloader is asking
+	 * us to not reload segments */
+	testb $(1<<6), BP_loadflags(%esi)
+	jnz 2f
+
+1:	cli
 	movl $(__BOOT_DS),%eax
 	movl %eax,%ds
 	movl %eax,%es
@@ -41,6 +50,8 @@
 	movl %eax,%gs
 	movl %eax,%ss
 
+2:	cld
+
 /* Calculate the delta between where we were compiled to run
  * 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
diff --git a/arch/x86/boot/compressed/misc_32.c b/arch/x86/boot/compressed/misc_32.c
index b28505c..b74d60d 100644
--- a/arch/x86/boot/compressed/misc_32.c
+++ b/arch/x86/boot/compressed/misc_32.c
@@ -25,7 +25,7 @@
 
 /*
  * Getting to provable safe in place decompression is hard.
- * Worst case behaviours need to be analized.
+ * Worst case behaviours need to be analyzed.
  * Background information:
  *
  * The file layout is:
@@ -94,7 +94,7 @@
  * Adding 32768 instead of 32767 just makes for round numbers.
  * Adding the decompressor_size is necessary as it musht live after all
  * of the data as well.  Last I measured the decompressor is about 14K.
- * 10K of actuall data and 4K of bss.
+ * 10K of actual data and 4K of bss.
  *
  */
 
@@ -247,6 +247,9 @@
 	int x,y,pos;
 	char c;
 
+	if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0)
+		return;
+
 	x = RM_SCREEN_INFO.orig_x;
 	y = RM_SCREEN_INFO.orig_y;
 
diff --git a/arch/x86/boot/compressed/misc_64.c b/arch/x86/boot/compressed/misc_64.c
index f932b0e..6ea015a 100644
--- a/arch/x86/boot/compressed/misc_64.c
+++ b/arch/x86/boot/compressed/misc_64.c
@@ -25,7 +25,7 @@
 
 /*
  * Getting to provable safe in place decompression is hard.
- * Worst case behaviours need to be analized.
+ * Worst case behaviours need to be analyzed.
  * Background information:
  *
  * The file layout is:
@@ -94,7 +94,7 @@
  * Adding 32768 instead of 32767 just makes for round numbers.
  * Adding the decompressor_size is necessary as it musht live after all
  * of the data as well.  Last I measured the decompressor is about 14K.
- * 10K of actuall data and 4K of bss.
+ * 10K of actual data and 4K of bss.
  *
  */
 
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index f3140e5..8353c81 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -119,7 +119,7 @@
 	# Part 2 of the header, from the old setup.S
 
 		.ascii	"HdrS"		# header signature
-		.word	0x0206		# header version number (>= 0x0105)
+		.word	0x0207		# header version number (>= 0x0105)
 					# or else old loadlin-1.5 will fail)
 		.globl realmode_swtch
 realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
@@ -214,6 +214,11 @@
                                                 #added with boot protocol
                                                 #version 2.06
 
+hardware_subarch:	.long 0			# subarchitecture, added with 2.07
+						# default to 0 for normal x86 PC
+
+hardware_subarch_data:	.quad 0
+
 # End of setup header #####################################################
 
 	.section ".inittext", "ax"
diff --git a/arch/x86/ia32/ia32_binfmt.c b/arch/x86/ia32/ia32_binfmt.c
index 118b9f9..55822d2 100644
--- a/arch/x86/ia32/ia32_binfmt.c
+++ b/arch/x86/ia32/ia32_binfmt.c
@@ -5,10 +5,6 @@
  * This tricks binfmt_elf.c into loading 32bit binaries using lots 
  * of ugly preprocessor tricks. Talk about very very poor man's inheritance.
  */ 
-#define __ASM_X86_64_ELF_H 1
-
-#undef ELF_CLASS
-#define ELF_CLASS ELFCLASS32
 
 #include <linux/types.h>
 #include <linux/stddef.h>
@@ -19,6 +15,7 @@
 #include <linux/binfmts.h>
 #include <linux/mm.h>
 #include <linux/security.h>
+#include <linux/elfcore-compat.h>
 
 #include <asm/segment.h> 
 #include <asm/ptrace.h>
@@ -31,6 +28,20 @@
 #include <asm/ia32.h>
 #include <asm/vsyscall32.h>
 
+#undef	ELF_ARCH
+#undef	ELF_CLASS
+#define ELF_CLASS	ELFCLASS32
+#define ELF_ARCH	EM_386
+
+#undef	elfhdr
+#undef	elf_phdr
+#undef	elf_note
+#undef	elf_addr_t
+#define elfhdr		elf32_hdr
+#define elf_phdr	elf32_phdr
+#define elf_note	elf32_note
+#define elf_addr_t	Elf32_Off
+
 #define ELF_NAME "elf/i386"
 
 #define AT_SYSINFO 32
@@ -48,74 +59,20 @@
 } while(0)
 
 struct file;
-struct elf_phdr; 
 
 #define IA32_EMULATOR 1
 
+#undef ELF_ET_DYN_BASE
+
 #define ELF_ET_DYN_BASE		(TASK_UNMAPPED_BASE + 0x1000000)
 
-#undef ELF_ARCH
-#define ELF_ARCH EM_386
-
-#define ELF_DATA	ELFDATA2LSB
-
-#define USE_ELF_CORE_DUMP 1
-
-/* Override elfcore.h */ 
-#define _LINUX_ELFCORE_H 1
-typedef unsigned int elf_greg_t;
-
-#define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-struct elf_siginfo
-{
-	int	si_signo;			/* signal number */
-	int	si_code;			/* extra code */
-	int	si_errno;			/* errno */
-};
-
 #define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
 
-struct elf_prstatus
-{
-	struct elf_siginfo pr_info;	/* Info associated with signal */
-	short	pr_cursig;		/* Current signal */
-	unsigned int pr_sigpend;	/* Set of pending signals */
-	unsigned int pr_sighold;	/* Set of held signals */
-	pid_t	pr_pid;
-	pid_t	pr_ppid;
-	pid_t	pr_pgrp;
-	pid_t	pr_sid;
-	struct compat_timeval pr_utime;	/* User time */
-	struct compat_timeval pr_stime;	/* System time */
-	struct compat_timeval pr_cutime;	/* Cumulative user time */
-	struct compat_timeval pr_cstime;	/* Cumulative system time */
-	elf_gregset_t pr_reg;	/* GP registers */
-	int pr_fpvalid;		/* True if math co-processor being used.  */
-};
-
-#define ELF_PRARGSZ	(80)	/* Number of chars for args */
-
-struct elf_prpsinfo
-{
-	char	pr_state;	/* numeric process state */
-	char	pr_sname;	/* char for pr_state */
-	char	pr_zomb;	/* zombie */
-	char	pr_nice;	/* nice val */
-	unsigned int pr_flag;	/* flags */
-	__u16	pr_uid;
-	__u16	pr_gid;
-	pid_t	pr_pid, pr_ppid, pr_pgrp, pr_sid;
-	/* Lots missing */
-	char	pr_fname[16];	/* filename of executable */
-	char	pr_psargs[ELF_PRARGSZ];	/* initial part of arg list */
-};
-
 #define _GET_SEG(x) \
 	({ __u32 seg; asm("movl %%" __stringify(x) ",%0" : "=r"(seg)); seg; })
 
 /* Assumes current==process to be dumped */
+#undef	ELF_CORE_COPY_REGS
 #define ELF_CORE_COPY_REGS(pr_reg, regs)       		\
 	pr_reg[0] = regs->rbx;				\
 	pr_reg[1] = regs->rcx;				\
@@ -135,36 +92,41 @@
 	pr_reg[15] = regs->rsp;				\
 	pr_reg[16] = regs->ss;
 
-#define user user32
+
+#define elf_prstatus	compat_elf_prstatus
+#define elf_prpsinfo	compat_elf_prpsinfo
+#define elf_fpregset_t	struct user_i387_ia32_struct
+#define	elf_fpxregset_t	struct user32_fxsr_struct
+#define user		user32
 
 #undef elf_read_implies_exec
 #define elf_read_implies_exec(ex, executable_stack)     (executable_stack != EXSTACK_DISABLE_X)
-//#include <asm/ia32.h>
-#include <linux/elf.h>
 
-typedef struct user_i387_ia32_struct elf_fpregset_t;
-typedef struct user32_fxsr_struct elf_fpxregset_t;
-
-
-static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *regs)
+#define elf_core_copy_regs		elf32_core_copy_regs
+static inline void elf32_core_copy_regs(compat_elf_gregset_t *elfregs,
+					struct pt_regs *regs)
 {
-	ELF_CORE_COPY_REGS((*elfregs), regs)
+	ELF_CORE_COPY_REGS((&elfregs->ebx), regs)
 }
 
-static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
+#define elf_core_copy_task_regs		elf32_core_copy_task_regs
+static inline int elf32_core_copy_task_regs(struct task_struct *t,
+					    compat_elf_gregset_t* elfregs)
 {	
 	struct pt_regs *pp = task_pt_regs(t);
-	ELF_CORE_COPY_REGS((*elfregs), pp);
+	ELF_CORE_COPY_REGS((&elfregs->ebx), pp);
 	/* fix wrong segments */ 
-	(*elfregs)[7] = t->thread.ds; 
-	(*elfregs)[9] = t->thread.fsindex; 
-	(*elfregs)[10] = t->thread.gsindex; 
-	(*elfregs)[8] = t->thread.es; 	
+	elfregs->ds = t->thread.ds;
+	elfregs->fs = t->thread.fsindex;
+	elfregs->gs = t->thread.gsindex;
+	elfregs->es = t->thread.es;
 	return 1; 
 }
 
+#define elf_core_copy_task_fpregs	elf32_core_copy_task_fpregs
 static inline int 
-elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu)
+elf32_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs,
+			    elf_fpregset_t *fpu)
 {
 	struct _fpstate_ia32 *fpstate = (void*)fpu; 
 	mm_segment_t oldfs = get_fs();
@@ -186,8 +148,9 @@
 
 #define ELF_CORE_COPY_XFPREGS 1
 #define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
+#define elf_core_copy_task_xfpregs	elf32_core_copy_task_xfpregs
 static inline int 
-elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
+elf32_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
 {
 	struct pt_regs *regs = task_pt_regs(t);
 	if (!tsk_used_math(t))
@@ -206,6 +169,10 @@
 
 extern int force_personality32;
 
+#undef	ELF_EXEC_PAGESIZE
+#undef	ELF_HWCAP
+#undef	ELF_PLATFORM
+#undef	SET_PERSONALITY
 #define ELF_EXEC_PAGESIZE PAGE_SIZE
 #define ELF_HWCAP (boot_cpu_data.x86_capability[0])
 #define ELF_PLATFORM  ("i686")
@@ -231,6 +198,7 @@
 
 #define load_elf_binary load_elf32_binary
 
+#undef	ELF_PLAT_INIT
 #define ELF_PLAT_INIT(r, load_addr)	elf32_init(r)
 
 #undef start_thread
@@ -289,7 +257,6 @@
 
 static ctl_table abi_table2[] = {
 	{
-		.ctl_name	= 99,
 		.procname	= "vsyscall32",
 		.data		= &sysctl_vsyscall32,
 		.maxlen		= sizeof(int),
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
index a3fa11f..ccea590 100644
--- a/arch/x86/kernel/Makefile_32
+++ b/arch/x86/kernel/Makefile_32
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-extra-y := head_32.o init_task_32.o vmlinux.lds
+extra-y := head_32.o init_task.o vmlinux.lds
 
 obj-y	:= process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
 		ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
@@ -17,6 +17,7 @@
 obj-$(CONFIG_X86_MSR)		+= msr.o
 obj-$(CONFIG_X86_CPUID)		+= cpuid.o
 obj-$(CONFIG_MICROCODE)		+= microcode.o
+obj-$(CONFIG_PCI)		+= early-quirks.o
 obj-$(CONFIG_APM)		+= apm_32.o
 obj-$(CONFIG_X86_SMP)		+= smp_32.o smpboot_32.o tsc_sync.o
 obj-$(CONFIG_SMP)		+= smpcommon_32.o
diff --git a/arch/x86/kernel/Makefile_64 b/arch/x86/kernel/Makefile_64
index 43da662..dec06e7 100644
--- a/arch/x86/kernel/Makefile_64
+++ b/arch/x86/kernel/Makefile_64
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-extra-y 	:= head_64.o head64.o init_task_64.o vmlinux.lds
+extra-y 	:= head_64.o head64.o init_task.o vmlinux.lds
 EXTRA_AFLAGS	:= -traditional
 obj-y	:= process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \
 		ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \
@@ -39,7 +39,7 @@
 obj-$(CONFIG_AUDIT)		+= audit_64.o
 
 obj-$(CONFIG_MODULES)		+= module_64.o
-obj-$(CONFIG_PCI)		+= early-quirks_64.o
+obj-$(CONFIG_PCI)		+= early-quirks.o
 
 obj-y				+= topology.o
 obj-y				+= intel_cacheinfo.o
diff --git a/arch/x86/kernel/acpi/Makefile_32 b/arch/x86/kernel/acpi/Makefile_32
index a4852a2..045dd54 100644
--- a/arch/x86/kernel/acpi/Makefile_32
+++ b/arch/x86/kernel/acpi/Makefile_32
@@ -1,7 +1,4 @@
 obj-$(CONFIG_ACPI)		+= boot.o
-ifneq ($(CONFIG_PCI),)
-obj-$(CONFIG_X86_IO_APIC)	+= earlyquirk_32.o
-endif
 obj-$(CONFIG_ACPI_SLEEP)	+= sleep_32.o wakeup_32.o
 
 ifneq ($(CONFIG_ACPI_PROCESSOR),)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index afd2afe..289247d 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -99,7 +99,7 @@
 
 /*
  * The default interrupt routing model is PIC (8259).  This gets
- * overriden if IOAPICs are enumerated (below).
+ * overridden if IOAPICs are enumerated (below).
  */
 enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
 
@@ -414,8 +414,8 @@
  *
  * Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers
  * for the 8259 PIC.  bit[n] = 1 means irq[n] is Level, otherwise Edge.
- * ECLR1 is IRQ's 0-7 (IRQ 0, 1, 2 must be 0)
- * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0)
+ * ECLR1 is IRQs 0-7 (IRQ 0, 1, 2 must be 0)
+ * ECLR2 is IRQs 8-15 (IRQ 8, 13 must be 0)
  */
 
 void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
@@ -427,7 +427,7 @@
 	old = inb(0x4d0) | (inb(0x4d1) << 8);
 
 	/*
-	 * If we use ACPI to set PCI irq's, then we should clear ELCR
+	 * If we use ACPI to set PCI IRQs, then we should clear ELCR
 	 * since we will set it correctly as we enable the PCI irq
 	 * routing.
 	 */
@@ -555,7 +555,7 @@
 
 int acpi_unmap_lsapic(int cpu)
 {
-	x86_cpu_to_apicid[cpu] = -1;
+	per_cpu(x86_cpu_to_apicid, cpu) = -1;
 	cpu_clear(cpu, cpu_present_map);
 	num_processors--;
 
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
index 2d39f55..10b6717 100644
--- a/arch/x86/kernel/acpi/cstate.c
+++ b/arch/x86/kernel/acpi/cstate.c
@@ -29,7 +29,7 @@
 void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
 					unsigned int cpu)
 {
-	struct cpuinfo_x86 *c = cpu_data + cpu;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
 	flags->bm_check = 0;
 	if (num_online_cpus() == 1)
@@ -72,7 +72,7 @@
 		struct acpi_processor_cx *cx, struct acpi_power_register *reg)
 {
 	struct cstate_entry *percpu_entry;
-	struct cpuinfo_x86 *c = cpu_data + cpu;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
 	cpumask_t saved_mask;
 	int retval;
diff --git a/arch/x86/kernel/acpi/earlyquirk_32.c b/arch/x86/kernel/acpi/earlyquirk_32.c
deleted file mode 100644
index 23f78ef..0000000
--- a/arch/x86/kernel/acpi/earlyquirk_32.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* 
- * Do early PCI probing for bug detection when the main PCI subsystem is 
- * not up yet.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/acpi.h>
-
-#include <asm/pci-direct.h>
-#include <asm/acpi.h>
-#include <asm/apic.h>
-
-#ifdef CONFIG_ACPI
-
-static int __init nvidia_hpet_check(struct acpi_table_header *header)
-{
-	return 0;
-}
-#endif
-
-static int __init check_bridge(int vendor, int device)
-{
-#ifdef CONFIG_ACPI
-	static int warned;
-	/* According to Nvidia all timer overrides are bogus unless HPET
-	   is enabled. */
-	if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) {
-		if (!warned && acpi_table_parse(ACPI_SIG_HPET,
-						nvidia_hpet_check)) {
-			warned = 1;
-			acpi_skip_timer_override = 1;
-			  printk(KERN_INFO "Nvidia board "
-                       "detected. Ignoring ACPI "
-                       "timer override.\n");
-                printk(KERN_INFO "If you got timer trouble "
-			 	 "try acpi_use_timer_override\n");
-
-		}
-	}
-#endif
-	if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) {
-		timer_over_8254 = 0;
-		printk(KERN_INFO "ATI board detected. Disabling timer routing "
-				"over 8254.\n");
-	}
-	return 0;
-}
-
-void __init check_acpi_pci(void)
-{
-	int num, slot, func;
-
-	/* Assume the machine supports type 1. If not it will 
-	   always read ffffffff and should not have any side effect.
-	   Actually a few buggy systems can machine check. Allow the user
-	   to disable it by command line option at least -AK */
-	if (!early_pci_allowed())
-		return;
-
-	/* Poor man's PCI discovery */
-	for (num = 0; num < 32; num++) {
-		for (slot = 0; slot < 32; slot++) {
-			for (func = 0; func < 8; func++) {
-				u32 class;
-				u32 vendor;
-				class = read_pci_config(num, slot, func,
-							PCI_CLASS_REVISION);
-				if (class == 0xffffffff)
-					break;
-
-				if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
-					continue;
-
-				vendor = read_pci_config(num, slot, func,
-							 PCI_VENDOR_ID);
-
-				if (check_bridge(vendor & 0xffff, vendor >> 16))
-					return;
-			}
-
-		}
-	}
-}
diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c
index b54fded..2ed0a4c 100644
--- a/arch/x86/kernel/acpi/processor.c
+++ b/arch/x86/kernel/acpi/processor.c
@@ -63,7 +63,7 @@
 void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
 {
 	unsigned int cpu = pr->id;
-	struct cpuinfo_x86 *c = cpu_data + cpu;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
 	pr->pdc = NULL;
 	if (c->x86_vendor == X86_VENDOR_INTEL)
diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S
index f22ba85..a97313b 100644
--- a/arch/x86/kernel/acpi/wakeup_32.S
+++ b/arch/x86/kernel/acpi/wakeup_32.S
@@ -11,7 +11,7 @@
 #
 # If physical address of wakeup_code is 0x12345, BIOS should call us with
 # cs = 0x1234, eip = 0x05
-# 
+#
 
 #define BEEP \
 	inb	$97, %al; 	\
@@ -52,7 +52,6 @@
 	BEEP
 1:
 	mov	$(wakeup_stack - wakeup_code), %sp		# Private stack is needed for ASUS board
-	movw	$0x0e00 + 'S', %fs:(0x12)
 
 	pushl	$0						# Kill any dangerous flags
 	popfl
@@ -90,9 +89,6 @@
 	# make sure %cr4 is set correctly (features, etc)
 	movl	real_save_cr4 - wakeup_code, %eax
 	movl	%eax, %cr4
-	movw	$0xb800, %ax
-	movw	%ax,%fs
-	movw	$0x0e00 + 'i', %fs:(0x12)
 	
 	# need a gdt -- use lgdtl to force 32-bit operands, in case
 	# the GDT is located past 16 megabytes.
@@ -102,8 +98,6 @@
 	movl	%eax, %cr0
 	jmp 1f
 1:
-	movw	$0x0e00 + 'n', %fs:(0x14)
-
 	movl	real_magic - wakeup_code, %eax
 	cmpl	$0x12345678, %eax
 	jne	bogus_real_magic
@@ -122,13 +116,11 @@
 real_magic:	.long 0
 video_mode:	.long 0
 realmode_flags:	.long 0
-beep_flags:	.long 0
 real_efer_save_restore:	.long 0
 real_save_efer_edx: 	.long 0
 real_save_efer_eax: 	.long 0
 
 bogus_real_magic:
-	movw	$0x0e00 + 'B', %fs:(0x12)
 	jmp bogus_real_magic
 
 /* This code uses an extended set of video mode numbers. These include:
@@ -194,7 +186,6 @@
 	movw	%ax, %es
 	movw	%ax, %fs
 	movw	%ax, %gs
-	movw	$0x0e00 + 'u', 0xb8016
 
 	# reload the gdt, as we need the full 32 bit address
 	lgdt	saved_gdt
@@ -218,7 +209,6 @@
 	jmp	*%eax
 
 bogus_magic:
-	movw	$0x0e00 + 'B', 0xb8018
 	jmp	bogus_magic
 
 
diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S
index 8b4357e..55608ec 100644
--- a/arch/x86/kernel/acpi/wakeup_64.S
+++ b/arch/x86/kernel/acpi/wakeup_64.S
@@ -41,7 +41,6 @@
 
 # Running in *copy* of this code, somewhere in low 1MB.
 
-	movb	$0xa1, %al	;  outb %al, $0x80
 	cli
 	cld
 	# setup data segment
@@ -65,11 +64,6 @@
 	cmpl	$0x12345678, %eax
 	jne	bogus_real_magic
 
-  	call	verify_cpu			# Verify the cpu supports long
-						# mode
-	testl	%eax, %eax
-	jnz	no_longmode
-
 	testl	$1, realmode_flags - wakeup_code
 	jz	1f
 	lcall   $0xc000,$3
@@ -84,12 +78,6 @@
 	call	mode_set
 1:
 
- 	movw	$0xb800, %ax
-	movw	%ax,%fs
-	movw	$0x0e00 + 'L', %fs:(0x10)
-
-	movb	$0xa2, %al	;  outb %al, $0x80
-	
 	mov	%ds, %ax			# Find 32bit wakeup_code addr
 	movzx   %ax, %esi			# (Convert %ds:gdt to a liner ptr)
 	shll    $4, %esi
@@ -117,14 +105,10 @@
 	.code32
 wakeup_32:
 # Running in this code, but at low address; paging is not yet turned on.
-	movb	$0xa5, %al	;  outb %al, $0x80
 
 	movl	$__KERNEL_DS, %eax
 	movl	%eax, %ds
 
-	movw	$0x0e00 + 'i', %ds:(0xb8012)
-	movb	$0xa8, %al	;  outb %al, $0x80;
-
 	/*
 	 * Prepare for entering 64bits mode
 	 */
@@ -200,16 +184,11 @@
 	 */
 	lgdt	cpu_gdt_descr
 
-	movw	$0x0e00 + 'n', %ds:(0xb8014)
-	movb	$0xa9, %al	;  outb %al, $0x80
-
 	movq    saved_magic, %rax
 	movq    $0x123456789abcdef0, %rdx
 	cmpq    %rdx, %rax
 	jne     bogus_64_magic
 
-	movw	$0x0e00 + 'u', %ds:(0xb8016)
-	
 	nop
 	nop
 	movw	$__KERNEL_DS, %ax
@@ -220,13 +199,11 @@
 	movw	%ax, %gs
 	movq	saved_rsp, %rsp
 
-	movw	$0x0e00 + 'x', %ds:(0xb8018)
 	movq	saved_rbx, %rbx
 	movq	saved_rdi, %rdi
 	movq	saved_rsi, %rsi
 	movq	saved_rbp, %rbp
 
-	movw	$0x0e00 + '!', %ds:(0xb801a)
 	movq	saved_rip, %rax
 	jmp	*%rax
 
@@ -256,21 +233,12 @@
 
 .code16
 bogus_real_magic:
-	movb	$0xba,%al	;  outb %al,$0x80
 	jmp bogus_real_magic
 
 .code64
 bogus_64_magic:
-	movb	$0xb3,%al	;  outb %al,$0x80
 	jmp bogus_64_magic
 
-.code16
-no_longmode:
-	movb    $0xbc,%al       ;  outb %al,$0x80
-	jmp no_longmode
-
-#include "../verify_cpu_64.S"
-	
 /* This code uses an extended set of video mode numbers. These include:
  * Aliases for standard modes
  *	NORMAL_VGA (-1)
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 3bd2688..d6405e0 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -357,14 +357,14 @@
 	if (smp) {
 		printk(KERN_INFO "SMP alternatives: switching to SMP code\n");
 		clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
-		clear_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
+		clear_bit(X86_FEATURE_UP, cpu_data(0).x86_capability);
 		list_for_each_entry(mod, &smp_alt_modules, next)
 			alternatives_smp_lock(mod->locks, mod->locks_end,
 					      mod->text, mod->text_end);
 	} else {
 		printk(KERN_INFO "SMP alternatives: switching to UP code\n");
 		set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
-		set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
+		set_bit(X86_FEATURE_UP, cpu_data(0).x86_capability);
 		list_for_each_entry(mod, &smp_alt_modules, next)
 			alternatives_smp_unlock(mod->locks, mod->locks_end,
 						mod->text, mod->text_end);
@@ -432,7 +432,7 @@
 		if (1 == num_possible_cpus()) {
 			printk(KERN_INFO "SMP alternatives: switching to UP code\n");
 			set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
-			set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
+			set_bit(X86_FEATURE_UP, cpu_data(0).x86_capability);
 			alternatives_smp_unlock(__smp_locks, __smp_locks_end,
 						_text, _etext);
 		}
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index 793341f..08b07c1 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -947,7 +947,7 @@
 	 * Set up LVT0, LVT1:
 	 *
 	 * set up through-local-APIC on the BP's LINT0. This is not
-	 * strictly necessery in pure symmetric-IO mode, but sometimes
+	 * strictly necessary in pure symmetric-IO mode, but sometimes
 	 * we delegate interrupts to the 8259A.
 	 */
 	/*
@@ -998,7 +998,7 @@
 	} else {
 		if (esr_disable)
 			/*
-			 * Something untraceble is creating bad interrupts on
+			 * Something untraceable is creating bad interrupts on
 			 * secondary quads ... for the moment, just leave the
 			 * ESR disabled - we can't do anything useful with the
 			 * errors anyway - mbligh
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 32f2365..17089a0 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -57,7 +57,7 @@
  *         screen-blanking and gpm (Stephen Rothwell); Linux 1.99.4
  *    1.2a:Simple change to stop mysterious bug reports with SMP also added
  *	   levels to the printk calls. APM is not defined for SMP machines.
- *         The new replacment for it is, but Linux doesn't yet support this.
+ *         The new replacement for it is, but Linux doesn't yet support this.
  *         Alan Cox Linux 2.1.55
  *    1.3: Set up a valid data descriptor 0x40 for buggy BIOS's
  *    1.4: Upgraded to support APM 1.2. Integrated ThinkPad suspend patch by
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index f1b7cdd..0e45981 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -15,6 +15,7 @@
 #include <asm/fixmap.h>
 #include <asm/processor.h>
 #include <asm/thread_info.h>
+#include <asm/bootparam.h>
 #include <asm/elf.h>
 
 #include <xen/interface/xen.h>
@@ -135,6 +136,7 @@
 #ifdef CONFIG_LGUEST_GUEST
 	BLANK();
 	OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled);
+	OFFSET(LGUEST_DATA_pgdir, lguest_data, pgdir);
 	OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc);
 	OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc);
 	OFFSET(LGUEST_PAGES_host_cr3, lguest_pages, state.host_cr3);
@@ -146,4 +148,10 @@
 	OFFSET(LGUEST_PAGES_regs_errcode, lguest_pages, regs.errcode);
 	OFFSET(LGUEST_PAGES_regs, lguest_pages, regs);
 #endif
+
+	BLANK();
+	OFFSET(BP_scratch, boot_params, scratch);
+	OFFSET(BP_loadflags, boot_params, hdr.loadflags);
+	OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch);
+	OFFSET(BP_version, boot_params, hdr.version);
 }
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 5f8af87..1ff88c7 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -266,7 +266,7 @@
 #ifdef CONFIG_X86_HT
 	/*
 	 * On a AMD multi core setup the lower bits of the APIC id
-	 * distingush the cores.
+	 * distinguish the cores.
 	 */
 	if (c->x86_max_cores > 1) {
 		int cpu = smp_processor_id();
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c
index 473eac8..9681fa1 100644
--- a/arch/x86/kernel/cpu/centaur.c
+++ b/arch/x86/kernel/cpu/centaur.c
@@ -53,7 +53,7 @@
 			continue;
 		/*
 		 *	Don't MCR over reserved space. Ignore the ISA hole
-		 *	we frob around that catastrophy already
+		 *	we frob around that catastrophe already
 		 */
 		 			
 		if (e820.map[i].type == E820_RESERVED)
@@ -287,7 +287,7 @@
 		c->x86_capability[5] = cpuid_edx(0xC0000001);
 	}
 
-	/* Cyrix III family needs CX8 & PGE explicity enabled. */
+	/* Cyrix III family needs CX8 & PGE explicitly enabled. */
 	if (c->x86_model >=6 && c->x86_model <= 9) {
 		rdmsr (MSR_VIA_FCR, lo, hi);
 		lo |= (1<<1 | 1<<7);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index d506201..e2fcf20 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -207,7 +207,7 @@
 
 static int __init x86_fxsr_setup(char * s)
 {
-	/* Tell all the other CPU's to not use it... */
+	/* Tell all the other CPUs to not use it... */
 	disable_x86_fxsr = 1;
 
 	/*
diff --git a/arch/x86/kernel/cpu/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig_32
similarity index 100%
rename from arch/x86/kernel/cpu/cpufreq/Kconfig
rename to arch/x86/kernel/cpu/cpufreq/Kconfig_32
diff --git a/arch/x86/kernel/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig_64
similarity index 97%
rename from arch/x86/kernel/cpufreq/Kconfig
rename to arch/x86/kernel/cpu/cpufreq/Kconfig_64
index a3fd519..9c9699f 100644
--- a/arch/x86/kernel/cpufreq/Kconfig
+++ b/arch/x86/kernel/cpu/cpufreq/Kconfig_64
@@ -19,7 +19,7 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called powernow-k8.
 
-	  For details, take a look at <file:Documentation/cpu-freq/>. 
+	  For details, take a look at <file:Documentation/cpu-freq/>.
 
 	  If in doubt, say N.
 
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 2ca43ba..fea0af0 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -77,7 +77,7 @@
 
 static int check_est_cpu(unsigned int cpuid)
 {
-	struct cpuinfo_x86 *cpu = &cpu_data[cpuid];
+	struct cpuinfo_x86 *cpu = &cpu_data(cpuid);
 
 	if (cpu->x86_vendor != X86_VENDOR_INTEL ||
 	    !cpu_has(cpu, X86_FEATURE_EST))
@@ -560,7 +560,7 @@
 	unsigned int cpu = policy->cpu;
 	struct acpi_cpufreq_data *data;
 	unsigned int result = 0;
-	struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
+	struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
 	struct acpi_processor_performance *perf;
 
 	dprintk("acpi_cpufreq_cpu_init\n");
diff --git a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
index 32f0bda..f03e9153 100644
--- a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
+++ b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
@@ -260,7 +260,7 @@
 
 	freqs.old = nforce2_get(policy->cpu);
 	freqs.new = target_fsb * fid * 100;
-	freqs.cpu = 0;		/* Only one CPU on nForce2 plattforms */
+	freqs.cpu = 0;		/* Only one CPU on nForce2 platforms */
 
 	if (freqs.old == freqs.new)
 		return 0;
diff --git a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
index c11baaf..326a4c8 100644
--- a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
+++ b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
@@ -305,7 +305,7 @@
 
 static int __init eps_init(void)
 {
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 
 	/* This driver will work only on Centaur C7 processors with
 	 * Enhanced SpeedStep/PowerSaver registers */
diff --git a/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
index 1e7ae7d..94619c2 100644
--- a/arch/x86/kernel/cpu/cpufreq/elanfreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
@@ -199,7 +199,7 @@
 
 static int elanfreq_cpu_init(struct cpufreq_policy *policy)
 {
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 	unsigned int i;
 	int result;
 
@@ -280,7 +280,7 @@
 
 static int __init elanfreq_init(void)
 {
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 
 	/* Test if we have the right hardware */
 	if ((c->x86_vendor != X86_VENDOR_AMD) ||
diff --git a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
index ed2bda1..2ed7db2 100644
--- a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
@@ -12,12 +12,12 @@
  *      of any nature resulting due to the use of this software. This
  *      software is provided AS-IS with no warranties.
  *
- * Theoritical note:
+ * Theoretical note:
  *
  *	(see Geode(tm) CS5530 manual (rev.4.1) page.56)
  *
  *	CPU frequency control on NatSemi Geode GX1/GXLV processor and CS55x0
- *	are based on Suspend Moduration.
+ *	are based on Suspend Modulation.
  *
  *	Suspend Modulation works by asserting and de-asserting the SUSP# pin
  *	to CPU(GX1/GXLV) for configurable durations. When asserting SUSP#
@@ -101,11 +101,11 @@
 
 /* SUSCFG bits */
 #define SUSMOD		(1<<0)	/* enable/disable suspend modulation */
-/* the belows support only with cs5530 (after rev.1.2)/cs5530A */
+/* the below is supported only with cs5530 (after rev.1.2)/cs5530A */
 #define SMISPDUP	(1<<1)	/* select how SMI re-enable suspend modulation: */
 				/* IRQTC timer or read SMI speedup disable reg.(F1BAR[08-09h]) */
 #define SUSCFG		(1<<2)	/* enable powering down a GXLV processor. "Special 3Volt Suspend" mode */
-/* the belows support only with cs5530A */
+/* the below is supported only with cs5530A */
 #define PWRSVE_ISA	(1<<3)	/* stop ISA clock  */
 #define PWRSVE		(1<<4)	/* active idle */
 
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
index 5045f5d..749d00c 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -780,7 +780,7 @@
 
 static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
 {
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 	char *cpuname=NULL;
 	int ret;
 	u32 lo, hi;
@@ -959,7 +959,7 @@
 
 static int __init longhaul_init(void)
 {
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 
 	if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
 		return -ENODEV;
diff --git a/arch/x86/kernel/cpu/cpufreq/longrun.c b/arch/x86/kernel/cpu/cpufreq/longrun.c
index b268951..af4a867 100644
--- a/arch/x86/kernel/cpu/cpufreq/longrun.c
+++ b/arch/x86/kernel/cpu/cpufreq/longrun.c
@@ -172,7 +172,7 @@
 	u32 save_lo, save_hi;
 	u32 eax, ebx, ecx, edx;
 	u32 try_hi;
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 
 	if (!low_freq || !high_freq)
 		return -EINVAL;
@@ -298,7 +298,7 @@
  */
 static int __init longrun_init(void)
 {
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 
 	if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
 	    !cpu_has(c, X86_FEATURE_LONGRUN))
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
index 793eae8..14791ec 100644
--- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
@@ -195,7 +195,7 @@
 
 static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
 {
-	struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
+	struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
 	int cpuid = 0;
 	unsigned int i;
 
@@ -279,7 +279,7 @@
 
 static int __init cpufreq_p4_init(void)
 {
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 	int ret;
 
 	/*
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
index 6d02853..eb9b62b 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
@@ -1,6 +1,6 @@
 /*
  *  This file was based upon code in Powertweak Linux (http://powertweak.sf.net)
- *  (C) 2000-2003  Dave Jones, Arjan van de Ven, Janne Pänkälä, Dominik Brodowski.
+ *  (C) 2000-2003  Dave Jones, Arjan van de Ven, Janne Pänkälä, Dominik Brodowski.
  *
  *  Licensed under the terms of the GNU GPL License version 2.
  *
@@ -215,7 +215,7 @@
  */
 static int __init powernow_k6_init(void)
 {
-	struct cpuinfo_x86      *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 
 	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
 		((c->x86_model != 12) && (c->x86_model != 13)))
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
index f3686a5..b5a9863 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
@@ -114,7 +114,7 @@
 
 static int check_powernow(void)
 {
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 	unsigned int maxei, eax, ebx, ecx, edx;
 
 	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 !=6)) {
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index c06ac68..9c36a53 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -168,7 +168,7 @@
 	return;
 }
 
-/* the voltage stabalization time */
+/* the voltage stabilization time */
 static void count_off_vst(struct powernow_k8_data *data)
 {
 	udelay(data->vstable * VST_UNITS_20US);
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
index b06c812..7c4f6e0 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
@@ -148,10 +148,10 @@
 #define PLL_LOCK_CONVERSION (1000/5) /* ms to ns, then divide by clock period */
 
 #define MAXIMUM_VID_STEPS 1  /* Current cpus only allow a single step of 25mV */
-#define VST_UNITS_20US 20   /* Voltage Stabalization Time is in units of 20us */
+#define VST_UNITS_20US 20   /* Voltage Stabilization Time is in units of 20us */
 
 /*
- * Most values of interest are enocoded in a single field of the _PSS
+ * Most values of interest are encoded in a single field of the _PSS
  * entries: the "control" value.
  */
 
diff --git a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
index d9f3e90..42da9bd 100644
--- a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
+++ b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
@@ -102,7 +102,7 @@
 
 static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
 {
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 	int result;
 
 	/* capability check */
@@ -151,7 +151,7 @@
 
 static int __init sc520_freq_init(void)
 {
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 	int err;
 
 	/* Test if we have the right hardware */
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
index 811d474..3031f11 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -230,7 +230,7 @@
 
 static int centrino_cpu_init_table(struct cpufreq_policy *policy)
 {
-	struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
+	struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
 	struct cpu_model *model;
 
 	for(model = models; model->cpu_id != NULL; model++)
@@ -340,7 +340,7 @@
 
 static int centrino_cpu_init(struct cpufreq_policy *policy)
 {
-	struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
+	struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
 	unsigned freq;
 	unsigned l, h;
 	int ret;
@@ -612,7 +612,7 @@
  */
 static int __init centrino_init(void)
 {
-	struct cpuinfo_x86 *cpu = cpu_data;
+	struct cpuinfo_x86 *cpu = &cpu_data(0);
 
 	if (!cpu_has(cpu, X86_FEATURE_EST))
 		return -ENODEV;
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
index b1acc8c..76c3ab0 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
@@ -228,7 +228,7 @@
 
 unsigned int speedstep_detect_processor (void)
 {
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 	u32 ebx, msr_lo, msr_hi;
 
 	dprintk("x86: %x, model: %x\n", c->x86, c->x86_model);
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c
index 122d2d7..88d66fb 100644
--- a/arch/x86/kernel/cpu/cyrix.c
+++ b/arch/x86/kernel/cpu/cyrix.c
@@ -93,7 +93,7 @@
 
 		local_irq_save(flags);
 		ccr3 = getCx86(CX86_CCR3);
-		setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN  */
+		setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
 		ccr5 = getCx86(CX86_CCR5);
 		if (ccr5 & 2)
 			setCx86(CX86_CCR5, ccr5 & 0xfd);  /* reset SLOP */
@@ -115,9 +115,9 @@
 
 	printk(KERN_INFO "Enable Memory access reorder on Cyrix/NSC processor.\n");
 	ccr3 = getCx86(CX86_CCR3);
-	setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN  */
+	setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
 
-	/* Load/Store Serialize to mem access disable (=reorder it)  */
+	/* Load/Store Serialize to mem access disable (=reorder it) */
 	setCx86(CX86_PCR0, getCx86(CX86_PCR0) & ~0x80);
 	/* set load/store serialize from 1GB to 4GB */
 	ccr3 |= 0xe0;
@@ -146,7 +146,7 @@
 	printk(KERN_INFO "Enable Incrementor on Cyrix/NSC processor.\n");
 
 	ccr3 = getCx86(CX86_CCR3);
-	setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN  */
+	setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
 	/* PCR1 -- Performance Control */
 	/* Incrementor on, whatever that is */
 	setCx86(CX86_PCR1, getCx86(CX86_PCR1) | 0x02);
@@ -256,7 +256,7 @@
 		u32 vendor, device;
 		/* It isn't really a PCI quirk directly, but the cure is the
 		   same. The MediaGX has deep magic SMM stuff that handles the
-		   SB emulation. It thows away the fifo on disable_dma() which
+		   SB emulation. It throws away the fifo on disable_dma() which
 		   is wrong and ruins the audio. 
 
 		   Bug2: VSA1 has a wrap bug so that using maximum sized DMA 
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 1826395..9921b01 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -295,7 +295,7 @@
 	unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
 	unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
 #ifdef CONFIG_X86_HT
-	unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data);
+	unsigned int cpu = c->cpu_index;
 #endif
 
 	if (c->cpuid_level > 3) {
@@ -417,14 +417,14 @@
 	if (new_l2) {
 		l2 = new_l2;
 #ifdef CONFIG_X86_HT
-		cpu_llc_id[cpu] = l2_id;
+		per_cpu(cpu_llc_id, cpu) = l2_id;
 #endif
 	}
 
 	if (new_l3) {
 		l3 = new_l3;
 #ifdef CONFIG_X86_HT
-		cpu_llc_id[cpu] = l3_id;
+		per_cpu(cpu_llc_id, cpu) = l3_id;
 #endif
 	}
 
@@ -459,7 +459,7 @@
 	struct _cpuid4_info	*this_leaf, *sibling_leaf;
 	unsigned long num_threads_sharing;
 	int index_msb, i;
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
 	this_leaf = CPUID4_INFO_IDX(cpu, index);
 	num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
@@ -470,8 +470,8 @@
 		index_msb = get_count_order(num_threads_sharing);
 
 		for_each_online_cpu(i) {
-			if (c[i].apicid >> index_msb ==
-			    c[cpu].apicid >> index_msb) {
+			if (cpu_data(i).apicid >> index_msb ==
+			    c->apicid >> index_msb) {
 				cpu_set(i, this_leaf->shared_cpu_map);
 				if (i != cpu && cpuid4_info[i])  {
 					sibling_leaf = CPUID4_INFO_IDX(i, index);
@@ -499,6 +499,11 @@
 
 static void free_cache_attributes(unsigned int cpu)
 {
+	int i;
+
+	for (i = 0; i < num_cache_leaves; i++)
+		cache_remove_shared_cpu_map(cpu, i);
+
 	kfree(cpuid4_info[cpu]);
 	cpuid4_info[cpu] = NULL;
 }
@@ -506,8 +511,8 @@
 static int __cpuinit detect_cache_attributes(unsigned int cpu)
 {
 	struct _cpuid4_info	*this_leaf;
-	unsigned long 		j;
-	int 			retval;
+	unsigned long		j;
+	int			retval;
 	cpumask_t		oldmask;
 
 	if (num_cache_leaves == 0)
@@ -524,19 +529,26 @@
 		goto out;
 
 	/* Do cpuid and store the results */
-	retval = 0;
 	for (j = 0; j < num_cache_leaves; j++) {
 		this_leaf = CPUID4_INFO_IDX(cpu, j);
 		retval = cpuid4_cache_lookup(j, this_leaf);
-		if (unlikely(retval < 0))
+		if (unlikely(retval < 0)) {
+			int i;
+
+			for (i = 0; i < j; i++)
+				cache_remove_shared_cpu_map(cpu, i);
 			break;
+		}
 		cache_shared_cpu_map_setup(cpu, j);
 	}
 	set_cpus_allowed(current, oldmask);
 
 out:
-	if (retval)
-		free_cache_attributes(cpu);
+	if (retval) {
+		kfree(cpuid4_info[cpu]);
+		cpuid4_info[cpu] = NULL;
+	}
+
 	return retval;
 }
 
@@ -669,7 +681,7 @@
 	.sysfs_ops	= &sysfs_ops,
 };
 
-static void cpuid4_cache_sysfs_exit(unsigned int cpu)
+static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
 {
 	kfree(cache_kobject[cpu]);
 	kfree(index_kobject[cpu]);
@@ -680,13 +692,14 @@
 
 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
 {
+	int err;
 
 	if (num_cache_leaves == 0)
 		return -ENOENT;
 
-	detect_cache_attributes(cpu);
-	if (cpuid4_info[cpu] == NULL)
-		return -ENOENT;
+	err = detect_cache_attributes(cpu);
+	if (err)
+		return err;
 
 	/* Allocate all required memory */
 	cache_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL);
@@ -705,13 +718,15 @@
 	return -ENOMEM;
 }
 
+static cpumask_t cache_dev_map = CPU_MASK_NONE;
+
 /* Add/Remove cache interface for CPU device */
 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
 {
 	unsigned int cpu = sys_dev->id;
 	unsigned long i, j;
 	struct _index_kobject *this_object;
-	int retval = 0;
+	int retval;
 
 	retval = cpuid4_cache_sysfs_init(cpu);
 	if (unlikely(retval < 0))
@@ -721,6 +736,10 @@
 	kobject_set_name(cache_kobject[cpu], "%s", "cache");
 	cache_kobject[cpu]->ktype = &ktype_percpu_entry;
 	retval = kobject_register(cache_kobject[cpu]);
+	if (retval < 0) {
+		cpuid4_cache_sysfs_exit(cpu);
+		return retval;
+	}
 
 	for (i = 0; i < num_cache_leaves; i++) {
 		this_object = INDEX_KOBJECT_PTR(cpu,i);
@@ -740,6 +759,9 @@
 			break;
 		}
 	}
+	if (!retval)
+		cpu_set(cpu, cache_dev_map);
+
 	return retval;
 }
 
@@ -750,13 +772,14 @@
 
 	if (cpuid4_info[cpu] == NULL)
 		return;
-	for (i = 0; i < num_cache_leaves; i++) {
-		cache_remove_shared_cpu_map(cpu, i);
+	if (!cpu_isset(cpu, cache_dev_map))
+		return;
+	cpu_clear(cpu, cache_dev_map);
+
+	for (i = 0; i < num_cache_leaves; i++)
 		kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
-	}
 	kobject_unregister(cache_kobject[cpu]);
 	cpuid4_cache_sysfs_exit(cpu);
-	return;
 }
 
 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
@@ -781,7 +804,7 @@
 
 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
 {
-    .notifier_call = cacheinfo_cpu_callback,
+	.notifier_call = cacheinfo_cpu_callback,
 };
 
 static int __cpuinit cache_sysfs_init(void)
@@ -791,14 +814,15 @@
 	if (num_cache_leaves == 0)
 		return 0;
 
-	register_hotcpu_notifier(&cacheinfo_cpu_notifier);
-
 	for_each_online_cpu(i) {
-		struct sys_device *sys_dev = get_cpu_sysdev((unsigned int)i);
+		int err;
+		struct sys_device *sys_dev = get_cpu_sysdev(i);
 
-		cache_add_dev(sys_dev);
+		err = cache_add_dev(sys_dev);
+		if (err)
+			return err;
 	}
-
+	register_hotcpu_notifier(&cacheinfo_cpu_notifier);
 	return 0;
 }
 
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
index 494d320..24885be 100644
--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
+++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
@@ -131,17 +131,19 @@
 {
 	unsigned int cpu = (unsigned long)hcpu;
 	struct sys_device *sys_dev;
-	int err;
+	int err = 0;
 
 	sys_dev = get_cpu_sysdev(cpu);
 	switch (action) {
-	case CPU_ONLINE:
-	case CPU_ONLINE_FROZEN:
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
 		mutex_lock(&therm_cpu_lock);
 		err = thermal_throttle_add_dev(sys_dev);
 		mutex_unlock(&therm_cpu_lock);
 		WARN_ON(err);
 		break;
+	case CPU_UP_CANCELED:
+	case CPU_UP_CANCELED_FROZEN:
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
 		mutex_lock(&therm_cpu_lock);
@@ -149,7 +151,7 @@
 		mutex_unlock(&therm_cpu_lock);
 		break;
 	}
-	return NOTIFY_OK;
+	return err ? NOTIFY_BAD : NOTIFY_OK;
 }
 
 static struct notifier_block thermal_throttle_cpu_notifier __cpuinitdata =
diff --git a/arch/x86/kernel/cpu/mtrr/cyrix.c b/arch/x86/kernel/cpu/mtrr/cyrix.c
index 2287d48..9964be3 100644
--- a/arch/x86/kernel/cpu/mtrr/cyrix.c
+++ b/arch/x86/kernel/cpu/mtrr/cyrix.c
@@ -147,10 +147,10 @@
 	write_cr0(cr0);
 	wbinvd();
 
-	/* Cyrix ARRs - everything else were excluded at the top */
+	/* Cyrix ARRs - everything else was excluded at the top */
 	ccr3 = getCx86(CX86_CCR3);
 
-	/* Cyrix ARRs - everything else were excluded at the top */
+	/* Cyrix ARRs - everything else was excluded at the top */
 	setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);
 
 }
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 56f64e3..992f08d 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -182,7 +182,7 @@
 
 /**
  * Checks and updates an fixed-range MTRR if it differs from the value it
- * should have. If K8 extenstions are wanted, update the K8 SYSCFG MSR also.
+ * should have. If K8 extentions are wanted, update the K8 SYSCFG MSR also.
  * see AMD publication no. 24593, chapter 7.8.1, page 233 for more information
  * \param msr MSR address of the MTTR which should be checked and updated
  * \param changed pointer which indicates whether the MTRR needed to be changed
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 5e4be30..9abbdf7 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -748,7 +748,7 @@
 	if (use_intel())
 		mtrr_state_warn();
 	else {
-		/* The CPUs haven't MTRR and seemes not support SMP. They have
+		/* The CPUs haven't MTRR and seem to not support SMP. They have
 		 * specific drivers, we use a tricky method to support
 		 * suspend/resume for them.
 		 * TBD: is there any system with such CPU which supports
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index 54cdbf1..c02541e 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -120,7 +120,9 @@
 	unsigned int counter;
 
 	counter = nmi_perfctr_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+	/* register not managed by the allocator? */
+	if (counter > NMI_MAX_COUNTER_BITS)
+		return 1;
 
 	if (!test_and_set_bit(counter, perfctr_nmi_owner))
 		return 1;
@@ -132,7 +134,9 @@
 	unsigned int counter;
 
 	counter = nmi_perfctr_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+	/* register not managed by the allocator? */
+	if (counter > NMI_MAX_COUNTER_BITS)
+		return;
 
 	clear_bit(counter, perfctr_nmi_owner);
 }
@@ -142,7 +146,9 @@
 	unsigned int counter;
 
 	counter = nmi_evntsel_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+	/* register not managed by the allocator? */
+	if (counter > NMI_MAX_COUNTER_BITS)
+		return 1;
 
 	if (!test_and_set_bit(counter, evntsel_nmi_owner))
 		return 1;
@@ -154,7 +160,9 @@
 	unsigned int counter;
 
 	counter = nmi_evntsel_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+	/* register not managed by the allocator? */
+	if (counter > NMI_MAX_COUNTER_BITS)
+		return;
 
 	clear_bit(counter, evntsel_nmi_owner);
 }
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 879a0f7..2d42b41 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -85,12 +85,13 @@
 		/* nothing */
 	};
 	struct cpuinfo_x86 *c = v;
-	int i, n = c - cpu_data;
+	int i, n = 0;
 	int fpu_exception;
 
 #ifdef CONFIG_SMP
 	if (!cpu_online(n))
 		return 0;
+	n = c->cpu_index;
 #endif
 	seq_printf(m, "processor\t: %d\n"
 		"vendor_id\t: %s\n"
@@ -175,11 +176,15 @@
 
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
-	return *pos < NR_CPUS ? cpu_data + *pos : NULL;
+	if (*pos == 0)	/* just in case, cpu 0 is not the first */
+		*pos = first_cpu(cpu_possible_map);
+	if ((*pos) < NR_CPUS && cpu_possible(*pos))
+		return &cpu_data(*pos);
+	return NULL;
 }
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
-	++*pos;
+	*pos = next_cpu(*pos, cpu_possible_map);
 	return c_start(m, pos);
 }
 static void c_stop(struct seq_file *m, void *v)
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index 70dcf91..05c9936 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -114,7 +114,7 @@
 static int cpuid_open(struct inode *inode, struct file *file)
 {
 	unsigned int cpu = iminor(file->f_path.dentry->d_inode);
-	struct cpuinfo_x86 *c = &(cpu_data)[cpu];
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
 	if (cpu >= NR_CPUS || !cpu_online(cpu))
 		return -ENXIO;	/* No such CPU */
@@ -134,15 +134,18 @@
 	.open = cpuid_open,
 };
 
-static int __cpuinit cpuid_device_create(int i)
+static __cpuinit int cpuid_device_create(int cpu)
 {
-	int err = 0;
 	struct device *dev;
 
-	dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), "cpu%d",i);
-	if (IS_ERR(dev))
-		err = PTR_ERR(dev);
-	return err;
+	dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu),
+			    "cpu%d", cpu);
+	return IS_ERR(dev) ? PTR_ERR(dev) : 0;
+}
+
+static void cpuid_device_destroy(int cpu)
+{
+	device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
 }
 
 static int __cpuinit cpuid_class_cpu_callback(struct notifier_block *nfb,
@@ -150,18 +153,21 @@
 					      void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
+	int err = 0;
 
 	switch (action) {
-	case CPU_ONLINE:
-	case CPU_ONLINE_FROZEN:
-		cpuid_device_create(cpu);
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
+		err = cpuid_device_create(cpu);
 		break;
+	case CPU_UP_CANCELED:
+	case CPU_UP_CANCELED_FROZEN:
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
-		device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
+		cpuid_device_destroy(cpu);
 		break;
 	}
-	return NOTIFY_OK;
+	return err ? NOTIFY_BAD : NOTIFY_OK;
 }
 
 static struct notifier_block __cpuinitdata cpuid_class_cpu_notifier =
@@ -198,7 +204,7 @@
 out_class:
 	i = 0;
 	for_each_online_cpu(i) {
-		device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i));
+		cpuid_device_destroy(i);
 	}
 	class_destroy(cpuid_class);
 out_chrdev:
@@ -212,7 +218,7 @@
 	int cpu = 0;
 
 	for_each_online_cpu(cpu)
-		device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
+		cpuid_device_destroy(cpu);
 	class_destroy(cpuid_class);
 	unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
 	unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c
index 32e75d0..72d0c56 100644
--- a/arch/x86/kernel/crash_dump_32.c
+++ b/arch/x86/kernel/crash_dump_32.c
@@ -47,6 +47,7 @@
 		if (!kdump_buf_page) {
 			printk(KERN_WARNING "Kdump: Kdump buffer page not"
 				" allocated\n");
+			kunmap_atomic(vaddr, KM_PTE0);
 			return -EFAULT;
 		}
 		copy_page(kdump_buf_page, vaddr);
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c
index 3c86b97..18f500d 100644
--- a/arch/x86/kernel/e820_32.c
+++ b/arch/x86/kernel/e820_32.c
@@ -51,6 +51,13 @@
 	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM
 };
 
+struct resource bss_resource = {
+	.name	= "Kernel bss",
+	.start	= 0,
+	.end	= 0,
+	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
 static struct resource system_rom_resource = {
 	.name	= "System ROM",
 	.start	= 0xf0000,
@@ -254,7 +261,9 @@
  * and also for regions reported as reserved by the e820.
  */
 static void __init
-legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
+legacy_init_iomem_resources(struct resource *code_resource,
+			    struct resource *data_resource,
+			    struct resource *bss_resource)
 {
 	int i;
 
@@ -287,8 +296,10 @@
 			 */
 			request_resource(res, code_resource);
 			request_resource(res, data_resource);
+			request_resource(res, bss_resource);
 #ifdef CONFIG_KEXEC
-			request_resource(res, &crashk_res);
+			if (crashk_res.start != crashk_res.end)
+				request_resource(res, &crashk_res);
 #endif
 		}
 	}
@@ -306,9 +317,11 @@
 
 	printk("Setting up standard PCI resources\n");
 	if (efi_enabled)
-		efi_initialize_iomem_resources(&code_resource, &data_resource);
+		efi_initialize_iomem_resources(&code_resource,
+				&data_resource, &bss_resource);
 	else
-		legacy_init_iomem_resources(&code_resource, &data_resource);
+		legacy_init_iomem_resources(&code_resource,
+				&data_resource, &bss_resource);
 
 	/* EFI systems may still have VGA */
 	request_resource(&iomem_resource, &video_ram_resource);
@@ -705,7 +718,7 @@
 	int i;
 
 	/*
-	 * Search for the bigest gap in the low 32 bits of the e820
+	 * Search for the biggest gap in the low 32 bits of the e820
 	 * memory space.
 	 */
 	last = 0x100000000ull;
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c
index e422b81..04698e0 100644
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -47,7 +47,7 @@
  */
 static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT;
 
-extern struct resource code_resource, data_resource;
+extern struct resource code_resource, data_resource, bss_resource;
 
 /* Check for some hardcoded bad areas that early boot is not allowed to touch */ 
 static inline int bad_addr(unsigned long *addrp, unsigned long size)
@@ -225,8 +225,10 @@
 			 */
 			request_resource(res, &code_resource);
 			request_resource(res, &data_resource);
+			request_resource(res, &bss_resource);
 #ifdef CONFIG_KEXEC
-			request_resource(res, &crashk_res);
+			if (crashk_res.start != crashk_res.end)
+				request_resource(res, &crashk_res);
 #endif
 		}
 	}
@@ -728,3 +730,22 @@
 	printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
 		pci_mem_start, gapstart, gapsize);
 }
+
+int __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
+{
+	int i;
+
+	if (slot < 0 || slot >= e820.nr_map)
+		return -1;
+	for (i = slot; i < e820.nr_map; i++) {
+		if (e820.map[i].type != E820_RAM)
+			continue;
+		break;
+	}
+	if (i == e820.nr_map || e820.map[i].addr > (max_pfn << PAGE_SHIFT))
+		return -1;
+	*addr = e820.map[i].addr;
+	*size = min_t(u64, e820.map[i].size + e820.map[i].addr,
+		max_pfn << PAGE_SHIFT) - *addr;
+	return i + 1;
+}
diff --git a/arch/x86/kernel/early-quirks_64.c b/arch/x86/kernel/early-quirks.c
similarity index 88%
rename from arch/x86/kernel/early-quirks_64.c
rename to arch/x86/kernel/early-quirks.c
index 13aa4fd..dc34acb 100644
--- a/arch/x86/kernel/early-quirks_64.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -13,9 +13,13 @@
 #include <linux/acpi.h>
 #include <linux/pci_ids.h>
 #include <asm/pci-direct.h>
-#include <asm/proto.h>
-#include <asm/iommu.h>
 #include <asm/dma.h>
+#include <asm/io_apic.h>
+#include <asm/apic.h>
+
+#ifdef CONFIG_IOMMU
+#include <asm/iommu.h>
+#endif
 
 static void __init via_bugs(void)
 {
@@ -23,7 +27,8 @@
 	if ((end_pfn > MAX_DMA32_PFN ||  force_iommu) &&
 	    !iommu_aperture_allowed) {
 		printk(KERN_INFO
-  "Looks like a VIA chipset. Disabling IOMMU. Override with iommu=allowed\n");
+		       "Looks like a VIA chipset. Disabling IOMMU."
+		       " Override with iommu=allowed\n");
 		iommu_aperture_disabled = 1;
 	}
 #endif
@@ -40,6 +45,7 @@
 static void __init nvidia_bugs(void)
 {
 #ifdef CONFIG_ACPI
+#ifdef CONFIG_X86_IO_APIC
 	/*
 	 * All timer overrides on Nvidia are
 	 * wrong unless HPET is enabled.
@@ -59,17 +65,20 @@
 			"try acpi_use_timer_override\n");
 	}
 #endif
+#endif
 	/* RED-PEN skip them on mptables too? */
 
 }
 
 static void __init ati_bugs(void)
 {
+#ifdef CONFIG_X86_IO_APIC
 	if (timer_over_8254 == 1) {
 		timer_over_8254 = 0;
 		printk(KERN_INFO
-	 	"ATI board detected. Disabling timer routing over 8254.\n");
+		"ATI board detected. Disabling timer routing over 8254.\n");
 	}
+#endif
 }
 
 struct chipset {
@@ -104,7 +113,7 @@
 				if (class == 0xffffffff)
 					break;
 
-		       		if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
+				if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
 					continue;
 
 				vendor = read_pci_config(num, slot, func,
diff --git a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c
index b42558c..e2be78f 100644
--- a/arch/x86/kernel/efi_32.c
+++ b/arch/x86/kernel/efi_32.c
@@ -603,7 +603,8 @@
 
 void __init
 efi_initialize_iomem_resources(struct resource *code_resource,
-			       struct resource *data_resource)
+			       struct resource *data_resource,
+			       struct resource *bss_resource)
 {
 	struct resource *res;
 	efi_memory_desc_t *md;
@@ -675,6 +676,7 @@
 		if (md->type == EFI_CONVENTIONAL_MEMORY) {
 			request_resource(res, code_resource);
 			request_resource(res, data_resource);
+			request_resource(res, bss_resource);
 #ifdef CONFIG_KEXEC
 			request_resource(res, &crashk_res);
 #endif
diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c
index 4ae03e3..ce703e2 100644
--- a/arch/x86/kernel/genapic_64.c
+++ b/arch/x86/kernel/genapic_64.c
@@ -24,10 +24,19 @@
 #include <acpi/acpi_bus.h>
 #endif
 
-/* which logical CPU number maps to which CPU (physical APIC ID) */
-u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly
+/*
+ * which logical CPU number maps to which CPU (physical APIC ID)
+ *
+ * The following static array is used during kernel startup
+ * and the x86_cpu_to_apicid_ptr contains the address of the
+ * array during this time.  Is it zeroed when the per_cpu
+ * data area is removed.
+ */
+u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata
 					= { [0 ... NR_CPUS-1] = BAD_APICID };
-EXPORT_SYMBOL(x86_cpu_to_apicid);
+void *x86_cpu_to_apicid_ptr;
+DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
+EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
 
 struct genapic __read_mostly *genapic = &apic_flat;
 
diff --git a/arch/x86/kernel/genapic_flat_64.c b/arch/x86/kernel/genapic_flat_64.c
index 91c75267..07352b7 100644
--- a/arch/x86/kernel/genapic_flat_64.c
+++ b/arch/x86/kernel/genapic_flat_64.c
@@ -172,7 +172,7 @@
 	 */
 	cpu = first_cpu(cpumask);
 	if ((unsigned)cpu < NR_CPUS)
-		return x86_cpu_to_apicid[cpu];
+		return per_cpu(x86_cpu_to_apicid, cpu);
 	else
 		return BAD_APICID;
 }
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index a7eee0a..6b34693 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -58,7 +58,7 @@
 
 	for (i = 0; i < IDT_ENTRIES; i++)
 		set_intr_gate(i, early_idt_handler);
-	asm volatile("lidt %0" :: "m" (idt_descr));
+	load_idt((const struct desc_ptr *)&idt_descr);
 
 	early_printk("Kernel alive\n");
 
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 3967796..00b1c2c 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -79,22 +79,30 @@
  */
 .section .text.head,"ax",@progbits
 ENTRY(startup_32)
+	/* check to see if KEEP_SEGMENTS flag is meaningful */
+	cmpw $0x207, BP_version(%esi)
+	jb 1f
+
+	/* test KEEP_SEGMENTS flag to see if the bootloader is asking
+		us to not reload segments */
+	testb $(1<<6), BP_loadflags(%esi)
+	jnz 2f
 
 /*
  * Set segments to known values.
  */
-	cld
-	lgdt boot_gdt_descr - __PAGE_OFFSET
+1:	lgdt boot_gdt_descr - __PAGE_OFFSET
 	movl $(__BOOT_DS),%eax
 	movl %eax,%ds
 	movl %eax,%es
 	movl %eax,%fs
 	movl %eax,%gs
+2:
 
 /*
  * Clear BSS first so that there are no surprises...
- * No need to cld as DF is already clear from cld above...
  */
+	cld
 	xorl %eax,%eax
 	movl $__bss_start - __PAGE_OFFSET,%edi
 	movl $__bss_stop - __PAGE_OFFSET,%ecx
@@ -128,6 +136,35 @@
 	movsl
 1:
 
+#ifdef CONFIG_PARAVIRT
+	cmpw $0x207, (boot_params + BP_version - __PAGE_OFFSET)
+	jb default_entry
+
+	/* Paravirt-compatible boot parameters.  Look to see what architecture
+		we're booting under. */
+	movl (boot_params + BP_hardware_subarch - __PAGE_OFFSET), %eax
+	cmpl $num_subarch_entries, %eax
+	jae bad_subarch
+
+	movl subarch_entries - __PAGE_OFFSET(,%eax,4), %eax
+	subl $__PAGE_OFFSET, %eax
+	jmp *%eax
+
+bad_subarch:
+WEAK(lguest_entry)
+WEAK(xen_entry)
+	/* Unknown implementation; there's really
+	   nothing we can do at this point. */
+	ud2a
+.data
+subarch_entries:
+	.long default_entry		/* normal x86/PC */
+	.long lguest_entry		/* lguest hypervisor */
+	.long xen_entry			/* Xen hypervisor */
+num_subarch_entries = (. - subarch_entries) / 4
+.previous
+#endif /* CONFIG_PARAVIRT */
+
 /*
  * Initialize page tables.  This creates a PDE and a set of page
  * tables, which are located immediately beyond _end.  The variable
@@ -140,6 +177,7 @@
  */
 page_pde_offset = (__PAGE_OFFSET >> 20);
 
+default_entry:
 	movl $(pg0 - __PAGE_OFFSET), %edi
 	movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
 	movl $0x007, %eax			/* 0x007 = PRESENT+RW+USER */
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index f836707..53303f2 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -69,12 +69,15 @@
  * HPET command line enable / disable
  */
 static int boot_hpet_disable;
+int hpet_force_user;
 
 static int __init hpet_setup(char* str)
 {
 	if (str) {
 		if (!strncmp("disable", str, 7))
 			boot_hpet_disable = 1;
+		if (!strncmp("force", str, 5))
+			hpet_force_user = 1;
 	}
 	return 1;
 }
@@ -350,7 +353,7 @@
 	 *
 	 * hpet period is in femto seconds per cycle
 	 * so we need to convert this to ns/cyc units
-	 * aproximated by mult/2^shift
+	 * approximated by mult/2^shift
 	 *
 	 *  fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift
 	 *  fsec/cyc * 1ns/1000000fsec * 2^shift = mult
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c
index 5cc8841..a42c807 100644
--- a/arch/x86/kernel/i8253.c
+++ b/arch/x86/kernel/i8253.c
@@ -86,7 +86,7 @@
  * On UP the PIT can serve all of the possible timer functions. On SMP systems
  * it can be solely used for the global tick.
  *
- * The profiling and update capabilites are switched off once the local apic is
+ * The profiling and update capabilities are switched off once the local apic is
  * registered. This mechanism replaces the previous #ifdef LOCAL_APIC -
  * !using_apic_timer decisions in do_timer_interrupt_hook()
  */
diff --git a/arch/x86/kernel/i8259_32.c b/arch/x86/kernel/i8259_32.c
index d34a10c..f634fc7 100644
--- a/arch/x86/kernel/i8259_32.c
+++ b/arch/x86/kernel/i8259_32.c
@@ -403,7 +403,8 @@
 		int vector = FIRST_EXTERNAL_VECTOR + i;
 		if (i >= NR_IRQS)
 			break;
-		if (vector != SYSCALL_VECTOR) 
+		/* SYSCALL_VECTOR was reserved in trap_init. */
+		if (!test_bit(vector, used_vectors))
 			set_intr_gate(vector, interrupt[i]);
 	}
 
diff --git a/arch/x86/kernel/init_task_32.c b/arch/x86/kernel/init_task.c
similarity index 79%
rename from arch/x86/kernel/init_task_32.c
rename to arch/x86/kernel/init_task.c
index d26fc06..468c9c4 100644
--- a/arch/x86/kernel/init_task_32.c
+++ b/arch/x86/kernel/init_task.c
@@ -15,7 +15,6 @@
 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
 static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
 struct mm_struct init_mm = INIT_MM(init_mm);
-
 EXPORT_SYMBOL(init_mm);
 
 /*
@@ -25,7 +24,7 @@
  * way process stacks are handled. This is done by having a special
  * "init_task" linker map entry..
  */
-union thread_union init_thread_union 
+union thread_union init_thread_union
 	__attribute__((__section__(".data.init_task"))) =
 		{ INIT_THREAD_INFO(init_task) };
 
@@ -35,12 +34,14 @@
  * All other task structs will be allocated on slabs in fork.c
  */
 struct task_struct init_task = INIT_TASK(init_task);
-
 EXPORT_SYMBOL(init_task);
 
 /*
  * per-CPU TSS segments. Threads are completely 'soft' on Linux,
- * no more per-task TSS's.
- */ 
+ * no more per-task TSS's. The TSS size is kept cacheline-aligned
+ * so they are allowed to end up in the .data.cacheline_aligned
+ * section. Since TSS's are completely CPU-local, we want them
+ * on exact cacheline boundaries, to eliminate cacheline ping-pong.
+ */
 DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
 
diff --git a/arch/x86/kernel/init_task_64.c b/arch/x86/kernel/init_task_64.c
deleted file mode 100644
index 4ff33d4..0000000
--- a/arch/x86/kernel/init_task_64.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/init_task.h>
-#include <linux/fs.h>
-#include <linux/mqueue.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/desc.h>
-
-static struct fs_struct init_fs = INIT_FS;
-static struct files_struct init_files = INIT_FILES;
-static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
-static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
-struct mm_struct init_mm = INIT_MM(init_mm);
-
-EXPORT_SYMBOL(init_mm);
-
-/*
- * Initial task structure.
- *
- * We need to make sure that this is 8192-byte aligned due to the
- * way process stacks are handled. This is done by having a special
- * "init_task" linker map entry..
- */
-union thread_union init_thread_union 
-	__attribute__((__section__(".data.init_task"))) =
-		{ INIT_THREAD_INFO(init_task) };
-
-/*
- * Initial task structure.
- *
- * All other task structs will be allocated on slabs in fork.c
- */
-struct task_struct init_task = INIT_TASK(init_task);
-
-EXPORT_SYMBOL(init_task);
-/*
- * per-CPU TSS segments. Threads are completely 'soft' on Linux,
- * no more per-task TSS's. The TSS size is kept cacheline-aligned
- * so they are allowed to end up in the .data.cacheline_aligned
- * section. Since TSS's are completely CPU-local, we want them
- * on exact cacheline boundaries, to eliminate cacheline ping-pong.
- */ 
-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
-
-/* Copies of the original ist values from the tss are only accessed during
- * debugging, no special alignment required.
- */
-DEFINE_PER_CPU(struct orig_ist, orig_ist);
-
-#define ALIGN_TO_4K __attribute__((section(".data.init_task")))
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index 5f10c71..f35c6eb 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -584,7 +584,7 @@
 
 	imbalance = move_this_load;
 	
-	/* For physical_balance case, we accumlated both load
+	/* For physical_balance case, we accumulated both load
 	 * values in the one of the siblings cpu_irq[],
 	 * to use the same code for physical and logical processors
 	 * as much as possible. 
@@ -1198,7 +1198,7 @@
 static int __assign_irq_vector(int irq)
 {
 	static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
-	int vector, offset, i;
+	int vector, offset;
 
 	BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
 
@@ -1215,11 +1215,8 @@
 	}
 	if (vector == current_vector)
 		return -ENOSPC;
-	if (vector == SYSCALL_VECTOR)
+	if (test_and_set_bit(vector, used_vectors))
 		goto next;
-	for (i = 0; i < NR_IRQ_VECTORS; i++)
-		if (irq_vector[i] == vector)
-			goto next;
 
 	current_vector = vector;
 	current_offset = offset;
@@ -2295,6 +2292,12 @@
 
 void __init setup_IO_APIC(void)
 {
+	int i;
+
+	/* Reserve all the system vectors. */
+	for (i = FIRST_SYSTEM_VECTOR; i < NR_VECTORS; i++)
+		set_bit(i, used_vectors);
+
 	enable_IO_APIC();
 
 	if (acpi_ioapic)
@@ -2472,7 +2475,7 @@
 }
 
 /*
- * MSI mesage composition
+ * MSI message composition
  */
 #ifdef CONFIG_PCI_MSI
 static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 1c2c7bf..953328b 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -31,6 +31,7 @@
 #include <linux/sysdev.h>
 #include <linux/msi.h>
 #include <linux/htirq.h>
+#include <linux/dmar.h>
 #ifdef CONFIG_ACPI
 #include <acpi/acpi_bus.h>
 #endif
@@ -1770,7 +1771,7 @@
 
 /*
  *
- * IRQ's that are handled by the PIC in the MPS IOAPIC case.
+ * IRQs that are handled by the PIC in the MPS IOAPIC case.
  * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
  *   Linux doesn't really care, as it's not actually used
  *   for any interrupt handling anyway.
@@ -1921,7 +1922,7 @@
 }
 
 /*
- * MSI mesage composition
+ * MSI message composition
  */
 #ifdef CONFIG_PCI_MSI
 static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
@@ -2031,8 +2032,64 @@
 	destroy_irq(irq);
 }
 
-#endif /* CONFIG_PCI_MSI */
+#ifdef CONFIG_DMAR
+#ifdef CONFIG_SMP
+static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
+{
+	struct irq_cfg *cfg = irq_cfg + irq;
+	struct msi_msg msg;
+	unsigned int dest;
+	cpumask_t tmp;
 
+	cpus_and(tmp, mask, cpu_online_map);
+	if (cpus_empty(tmp))
+		return;
+
+	if (assign_irq_vector(irq, mask))
+		return;
+
+	cpus_and(tmp, cfg->domain, mask);
+	dest = cpu_mask_to_apicid(tmp);
+
+	dmar_msi_read(irq, &msg);
+
+	msg.data &= ~MSI_DATA_VECTOR_MASK;
+	msg.data |= MSI_DATA_VECTOR(cfg->vector);
+	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+
+	dmar_msi_write(irq, &msg);
+	irq_desc[irq].affinity = mask;
+}
+#endif /* CONFIG_SMP */
+
+struct irq_chip dmar_msi_type = {
+	.name = "DMAR_MSI",
+	.unmask = dmar_msi_unmask,
+	.mask = dmar_msi_mask,
+	.ack = ack_apic_edge,
+#ifdef CONFIG_SMP
+	.set_affinity = dmar_msi_set_affinity,
+#endif
+	.retrigger = ioapic_retrigger_irq,
+};
+
+int arch_setup_dmar_msi(unsigned int irq)
+{
+	int ret;
+	struct msi_msg msg;
+
+	ret = msi_compose_msg(NULL, irq, &msg);
+	if (ret < 0)
+		return ret;
+	dmar_msi_write(irq, &msg);
+	set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq,
+		"edge");
+	return 0;
+}
+#endif
+
+#endif /* CONFIG_PCI_MSI */
 /*
  * Hypertransport interrupt support
  */
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index 8459ca6..11b935f 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -149,28 +149,6 @@
 			image->start, cpu_has_pae);
 }
 
-/* crashkernel=size@addr specifies the location to reserve for
- * a crash kernel.  By reserving this memory we guarantee
- * that linux never sets it up as a DMA target.
- * Useful for holding code to do something appropriate
- * after a kernel panic.
- */
-static int __init parse_crashkernel(char *arg)
-{
-	unsigned long size, base;
-	size = memparse(arg, &arg);
-	if (*arg == '@') {
-		base = memparse(arg+1, &arg);
-		/* FIXME: Do I want a sanity check
-		 * to validate the memory range?
-		 */
-		crashk_res.start = base;
-		crashk_res.end   = base + size - 1;
-	}
-	return 0;
-}
-early_param("crashkernel", parse_crashkernel);
-
 void arch_crash_save_vmcoreinfo(void)
 {
 #ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index 7450b69..0d8577f 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -231,33 +231,6 @@
 			image->start);
 }
 
-/* crashkernel=size@addr specifies the location to reserve for
- * a crash kernel.  By reserving this memory we guarantee
- * that linux never set's it up as a DMA target.
- * Useful for holding code to do something appropriate
- * after a kernel panic.
- */
-static int __init setup_crashkernel(char *arg)
-{
-	unsigned long size, base;
-	char *p;
-	if (!arg)
-		return -EINVAL;
-	size = memparse(arg, &p);
-	if (arg == p)
-		return -EINVAL;
-	if (*p == '@') {
-		base = memparse(p+1, &p);
-		/* FIXME: Do I want a sanity check to validate the
-		 * memory range?  Yes you do, but it's too early for
-		 * e820 -AK */
-		crashk_res.start = base;
-		crashk_res.end   = base + size - 1;
-	}
-	return 0;
-}
-early_param("crashkernel", setup_crashkernel);
-
 void arch_crash_save_vmcoreinfo(void)
 {
 #ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
diff --git a/arch/x86/kernel/mce_64.c b/arch/x86/kernel/mce_64.c
index 8ca8f86..07bbfe7 100644
--- a/arch/x86/kernel/mce_64.c
+++ b/arch/x86/kernel/mce_64.c
@@ -320,7 +320,7 @@
 #ifdef CONFIG_X86_MCE_INTEL
 /***
  * mce_log_therm_throt_event - Logs the thermal throttling event to mcelog
- * @cpu: The CPU on which the event occured.
+ * @cpu: The CPU on which the event occurred.
  * @status: Event status information
  *
  * This function should be called by the thermal interrupt after the
@@ -688,7 +688,7 @@
 	return 1;
 }
 
-/* mce=off disables machine check. Note you can reenable it later
+/* mce=off disables machine check. Note you can re-enable it later
    using sysfs.
    mce=TOLERANCELEVEL (number, see above)
    mce=bootlog Log MCEs from before booting. Disabled by default on AMD.
@@ -799,19 +799,33 @@
 {
 	int err;
 	int i;
-	if (!mce_available(&cpu_data[cpu]))
+
+	if (!mce_available(&cpu_data(cpu)))
 		return -EIO;
 
+	memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
 	per_cpu(device_mce,cpu).id = cpu;
 	per_cpu(device_mce,cpu).cls = &mce_sysclass;
 
 	err = sysdev_register(&per_cpu(device_mce,cpu));
+	if (err)
+		return err;
 
-	if (!err) {
-		for (i = 0; mce_attributes[i]; i++)
-			sysdev_create_file(&per_cpu(device_mce,cpu),
-				mce_attributes[i]);
+	for (i = 0; mce_attributes[i]; i++) {
+		err = sysdev_create_file(&per_cpu(device_mce,cpu),
+					 mce_attributes[i]);
+		if (err)
+			goto error;
 	}
+
+	return 0;
+error:
+	while (i--) {
+		sysdev_remove_file(&per_cpu(device_mce,cpu),
+				   mce_attributes[i]);
+	}
+	sysdev_unregister(&per_cpu(device_mce,cpu));
+
 	return err;
 }
 
@@ -823,7 +837,6 @@
 		sysdev_remove_file(&per_cpu(device_mce,cpu),
 			mce_attributes[i]);
 	sysdev_unregister(&per_cpu(device_mce,cpu));
-	memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
 }
 
 /* Get notified when a cpu comes on/off. Be hotplug friendly. */
@@ -831,18 +844,21 @@
 mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
+	int err = 0;
 
 	switch (action) {
-	case CPU_ONLINE:
-	case CPU_ONLINE_FROZEN:
-		mce_create_device(cpu);
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
+		err = mce_create_device(cpu);
 		break;
+	case CPU_UP_CANCELED:
+	case CPU_UP_CANCELED_FROZEN:
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
 		mce_remove_device(cpu);
 		break;
 	}
-	return NOTIFY_OK;
+	return err ? NOTIFY_BAD : NOTIFY_OK;
 }
 
 static struct notifier_block mce_cpu_notifier = {
@@ -857,9 +873,13 @@
 	if (!mce_available(&boot_cpu_data))
 		return -EIO;
 	err = sysdev_class_register(&mce_sysclass);
+	if (err)
+		return err;
 
 	for_each_online_cpu(i) {
-		mce_create_device(i);
+		err = mce_create_device(i);
+		if (err)
+			return err;
 	}
 
 	register_hotcpu_notifier(&mce_cpu_notifier);
diff --git a/arch/x86/kernel/mce_amd_64.c b/arch/x86/kernel/mce_amd_64.c
index 0d2afd9..752fb16 100644
--- a/arch/x86/kernel/mce_amd_64.c
+++ b/arch/x86/kernel/mce_amd_64.c
@@ -472,11 +472,11 @@
 	sprintf(name, "threshold_bank%i", bank);
 
 #ifdef CONFIG_SMP
-	if (cpu_data[cpu].cpu_core_id && shared_bank[bank]) {	/* symlink */
+	if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) {	/* symlink */
 		i = first_cpu(per_cpu(cpu_core_map, cpu));
 
 		/* first core not up yet */
-		if (cpu_data[i].cpu_core_id)
+		if (cpu_data(i).cpu_core_id)
 			goto out;
 
 		/* already linked */
diff --git a/arch/x86/kernel/microcode.c b/arch/x86/kernel/microcode.c
index 09cf781..09c3152 100644
--- a/arch/x86/kernel/microcode.c
+++ b/arch/x86/kernel/microcode.c
@@ -132,7 +132,7 @@
 
 static void collect_cpu_info(int cpu_num)
 {
-	struct cpuinfo_x86 *c = cpu_data + cpu_num;
+	struct cpuinfo_x86 *c = &cpu_data(cpu_num);
 	struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
 	unsigned int val[2];
 
@@ -522,7 +522,7 @@
 static int cpu_request_microcode(int cpu)
 {
 	char name[30];
-	struct cpuinfo_x86 *c = cpu_data + cpu;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	const struct firmware *firmware;
 	void *buf;
 	unsigned long size;
@@ -570,7 +570,7 @@
 
 static int apply_microcode_check_cpu(int cpu)
 {
-	struct cpuinfo_x86 *c = cpu_data + cpu;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
 	cpumask_t old;
 	unsigned int val[2];
diff --git a/arch/x86/kernel/mpparse_32.c b/arch/x86/kernel/mpparse_32.c
index 13abb4e..7a05a7f 100644
--- a/arch/x86/kernel/mpparse_32.c
+++ b/arch/x86/kernel/mpparse_32.c
@@ -1001,7 +1001,7 @@
 
 	/* 
 	 * Use the default configuration for the IRQs 0-15.  Unless
-	 * overriden by (MADT) interrupt source override entries.
+	 * overridden by (MADT) interrupt source override entries.
 	 */
 	for (i = 0; i < 16; i++) {
 		int idx;
diff --git a/arch/x86/kernel/mpparse_64.c b/arch/x86/kernel/mpparse_64.c
index 8bf0ca0..ef4aab1 100644
--- a/arch/x86/kernel/mpparse_64.c
+++ b/arch/x86/kernel/mpparse_64.c
@@ -57,6 +57,8 @@
 
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_id = -1U;
+EXPORT_SYMBOL(boot_cpu_id);
+
 /* Internal processor count */
 unsigned int num_processors __cpuinitdata = 0;
 
@@ -86,7 +88,7 @@
 	return sum & 0xFF;
 }
 
-static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
+static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
 {
 	int cpu;
 	cpumask_t tmp_map;
@@ -123,7 +125,18 @@
 		cpu = 0;
  	}
 	bios_cpu_apicid[cpu] = m->mpc_apicid;
-	x86_cpu_to_apicid[cpu] = m->mpc_apicid;
+	/*
+	 * We get called early in the the start_kernel initialization
+	 * process when the per_cpu data area is not yet setup, so we
+	 * use a static array that is removed after the per_cpu data
+	 * area is created.
+	 */
+	if (x86_cpu_to_apicid_ptr) {
+		u8 *x86_cpu_to_apicid = (u8 *)x86_cpu_to_apicid_ptr;
+		x86_cpu_to_apicid[cpu] = m->mpc_apicid;
+	} else {
+		per_cpu(x86_cpu_to_apicid, cpu) = m->mpc_apicid;
+	}
 
 	cpu_set(cpu, cpu_possible_map);
 	cpu_set(cpu, cpu_present_map);
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index df85c9c..ee6eba4 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -112,7 +112,7 @@
 static int msr_open(struct inode *inode, struct file *file)
 {
 	unsigned int cpu = iminor(file->f_path.dentry->d_inode);
-	struct cpuinfo_x86 *c = &(cpu_data)[cpu];
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
 	if (cpu >= NR_CPUS || !cpu_online(cpu))
 		return -ENXIO;	/* No such CPU */
@@ -133,37 +133,42 @@
 	.open = msr_open,
 };
 
-static int __cpuinit msr_device_create(int i)
+static int __cpuinit msr_device_create(int cpu)
 {
-	int err = 0;
 	struct device *dev;
 
-	dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), "msr%d",i);
-	if (IS_ERR(dev))
-		err = PTR_ERR(dev);
-	return err;
+	dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu),
+			    "msr%d", cpu);
+	return IS_ERR(dev) ? PTR_ERR(dev) : 0;
+}
+
+static void msr_device_destroy(int cpu)
+{
+	device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
 }
 
 static int __cpuinit msr_class_cpu_callback(struct notifier_block *nfb,
 				unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
+	int err = 0;
 
 	switch (action) {
-	case CPU_ONLINE:
-	case CPU_ONLINE_FROZEN:
-		msr_device_create(cpu);
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
+		err = msr_device_create(cpu);
 		break;
+	case CPU_UP_CANCELED:
+	case CPU_UP_CANCELED_FROZEN:
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
-		device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
+		msr_device_destroy(cpu);
 		break;
 	}
-	return NOTIFY_OK;
+	return err ? NOTIFY_BAD : NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata msr_class_cpu_notifier =
-{
+static struct notifier_block __cpuinitdata msr_class_cpu_notifier = {
 	.notifier_call = msr_class_cpu_callback,
 };
 
@@ -196,7 +201,7 @@
 out_class:
 	i = 0;
 	for_each_online_cpu(i)
-		device_destroy(msr_class, MKDEV(MSR_MAJOR, i));
+		msr_device_destroy(i);
 	class_destroy(msr_class);
 out_chrdev:
 	unregister_chrdev(MSR_MAJOR, "cpu/msr");
@@ -208,7 +213,7 @@
 {
 	int cpu = 0;
 	for_each_online_cpu(cpu)
-		device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
+		msr_device_destroy(cpu);
 	class_destroy(msr_class);
 	unregister_chrdev(MSR_MAJOR, "cpu/msr");
 	unregister_hotcpu_notifier(&msr_class_cpu_notifier);
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 5098f58..1a20fe31 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -411,8 +411,10 @@
 	int i;
 
 	for_each_sg(sg, s, nelems, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		struct page *p = sg_page(s);
+
+		BUG_ON(!p);
+		s->dma_address = virt_to_bus(sg_virt(s));
 		s->dma_length = s->length;
 	}
 	return nelems;
@@ -432,9 +434,9 @@
 		return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
 
 	for_each_sg(sg, s, nelems, i) {
-		BUG_ON(!s->page);
+		BUG_ON(!sg_page(s));
 
-		vaddr = (unsigned long)page_address(s->page) + s->offset;
+		vaddr = (unsigned long) sg_virt(s);
 		npages = num_dma_pages(vaddr, s->length);
 
 		entry = iommu_range_alloc(tbl, npages);
diff --git a/arch/x86/kernel/pci-dma_64.c b/arch/x86/kernel/pci-dma_64.c
index b2b42bd..393e272 100644
--- a/arch/x86/kernel/pci-dma_64.c
+++ b/arch/x86/kernel/pci-dma_64.c
@@ -7,11 +7,12 @@
 #include <linux/string.h>
 #include <linux/pci.h>
 #include <linux/module.h>
+#include <linux/dmar.h>
 #include <asm/io.h>
 #include <asm/iommu.h>
 #include <asm/calgary.h>
 
-int iommu_merge __read_mostly = 0;
+int iommu_merge __read_mostly = 1;
 EXPORT_SYMBOL(iommu_merge);
 
 dma_addr_t bad_dma_address __read_mostly;
@@ -305,6 +306,8 @@
 	detect_calgary();
 #endif
 
+	detect_intel_iommu();
+
 #ifdef CONFIG_SWIOTLB
 	pci_swiotlb_init();
 #endif
@@ -316,6 +319,8 @@
 	calgary_iommu_init();
 #endif
 
+	intel_iommu_init();
+
 #ifdef CONFIG_IOMMU
 	gart_iommu_init();
 #endif
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 5cdfab6..c56e9ee 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -302,7 +302,7 @@
 #endif
 
 	for_each_sg(sg, s, nents, i) {
-		unsigned long addr = page_to_phys(s->page) + s->offset; 
+		unsigned long addr = sg_phys(s);
 		if (nonforced_iommu(dev, addr, s->length)) { 
 			addr = dma_map_area(dev, addr, s->length, dir);
 			if (addr == bad_dma_address) { 
@@ -397,7 +397,7 @@
 	start_sg = sgmap = sg;
 	ps = NULL; /* shut up gcc */
 	for_each_sg(sg, s, nents, i) {
-		dma_addr_t addr = page_to_phys(s->page) + s->offset;
+		dma_addr_t addr = sg_phys(s);
 		s->dma_address = addr;
 		BUG_ON(s->length == 0); 
 
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c
index e85d436..faf70bd 100644
--- a/arch/x86/kernel/pci-nommu_64.c
+++ b/arch/x86/kernel/pci-nommu_64.c
@@ -62,8 +62,8 @@
 	int i;
 
 	for_each_sg(sg, s, nents, i) {
-		BUG_ON(!s->page);
-		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+		BUG_ON(!sg_page(s));
+		s->dma_address = virt_to_bus(sg_virt(s));
 		if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
 			return 0;
 		s->dma_length = s->length;
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 097aeaf..7b89958 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -295,34 +295,52 @@
 }
 early_param("idle", idle_setup);
 
-void show_regs(struct pt_regs * regs)
+void __show_registers(struct pt_regs *regs, int all)
 {
 	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
 	unsigned long d0, d1, d2, d3, d6, d7;
+	unsigned long esp;
+	unsigned short ss, gs;
+
+	if (user_mode_vm(regs)) {
+		esp = regs->esp;
+		ss = regs->xss & 0xffff;
+		savesegment(gs, gs);
+	} else {
+		esp = (unsigned long) (&regs->esp);
+		savesegment(ss, ss);
+		savesegment(gs, gs);
+	}
 
 	printk("\n");
-	printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
-	printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
+	printk("Pid: %d, comm: %s %s (%s %.*s)\n",
+			task_pid_nr(current), current->comm,
+			print_tainted(), init_utsname()->release,
+			(int)strcspn(init_utsname()->version, " "),
+			init_utsname()->version);
+
+	printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
+			0xffff & regs->xcs, regs->eip, regs->eflags,
+			smp_processor_id());
 	print_symbol("EIP is at %s\n", regs->eip);
 
-	if (user_mode_vm(regs))
-		printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
-	printk(" EFLAGS: %08lx    %s  (%s %.*s)\n",
-	       regs->eflags, print_tainted(), init_utsname()->release,
-	       (int)strcspn(init_utsname()->version, " "),
-	       init_utsname()->version);
 	printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
-		regs->eax,regs->ebx,regs->ecx,regs->edx);
-	printk("ESI: %08lx EDI: %08lx EBP: %08lx",
-		regs->esi, regs->edi, regs->ebp);
-	printk(" DS: %04x ES: %04x FS: %04x\n",
-	       0xffff & regs->xds,0xffff & regs->xes, 0xffff & regs->xfs);
+		regs->eax, regs->ebx, regs->ecx, regs->edx);
+	printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
+		regs->esi, regs->edi, regs->ebp, esp);
+	printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
+	       regs->xds & 0xffff, regs->xes & 0xffff,
+	       regs->xfs & 0xffff, gs, ss);
+
+	if (!all)
+		return;
 
 	cr0 = read_cr0();
 	cr2 = read_cr2();
 	cr3 = read_cr3();
 	cr4 = read_cr4_safe();
-	printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
+	printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
+			cr0, cr2, cr3, cr4);
 
 	get_debugreg(d0, 0);
 	get_debugreg(d1, 1);
@@ -330,10 +348,16 @@
 	get_debugreg(d3, 3);
 	printk("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
 			d0, d1, d2, d3);
+
 	get_debugreg(d6, 6);
 	get_debugreg(d7, 7);
-	printk("DR6: %08lx DR7: %08lx\n", d6, d7);
+	printk("DR6: %08lx DR7: %08lx\n",
+			d6, d7);
+}
 
+void show_regs(struct pt_regs *regs)
+{
+	__show_registers(regs, 1);
 	show_trace(NULL, regs, &regs->esp);
 }
 
diff --git a/arch/x86/kernel/ptrace_32.c b/arch/x86/kernel/ptrace_32.c
index 99102ec..ff5431c 100644
--- a/arch/x86/kernel/ptrace_32.c
+++ b/arch/x86/kernel/ptrace_32.c
@@ -632,7 +632,7 @@
 	/* User-mode eip? */
 	info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
 
-	/* Send us the fakey SIGTRAP */
+	/* Send us the fake SIGTRAP */
 	force_sig_info(SIGTRAP, &info, tsk);
 }
 
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index d769e20..a4ce191 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -45,9 +45,12 @@
 	if (!(config & 0x2))
 		pci_write_config_byte(dev, 0xf4, config);
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7320_MCH,	quirk_intel_irqbalance);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7525_MCH,	quirk_intel_irqbalance);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7520_MCH,	quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH,
+			quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH,
+			quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH,
+			quirk_intel_irqbalance);
 #endif
 
 #if defined(CONFIG_HPET_TIMER)
@@ -56,7 +59,8 @@
 static enum {
 	NONE_FORCE_HPET_RESUME,
 	OLD_ICH_FORCE_HPET_RESUME,
-	ICH_FORCE_HPET_RESUME
+	ICH_FORCE_HPET_RESUME,
+	VT8237_FORCE_HPET_RESUME
 } force_hpet_resume_type;
 
 static void __iomem *rcba_base;
@@ -146,17 +150,17 @@
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0,
-                         ich_force_enable_hpet);
+			 ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,
-                         ich_force_enable_hpet);
+			 ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,
-                         ich_force_enable_hpet);
+			 ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,
-                         ich_force_enable_hpet);
+			 ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,
-                         ich_force_enable_hpet);
+			 ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1,
-                         ich_force_enable_hpet);
+			 ich_force_enable_hpet);
 
 
 static struct pci_dev *cached_dev;
@@ -232,10 +236,91 @@
 	printk(KERN_DEBUG "Failed to force enable HPET\n");
 }
 
+/*
+ * Undocumented chipset features. Make sure that the user enforced
+ * this.
+ */
+static void old_ich_force_enable_hpet_user(struct pci_dev *dev)
+{
+	if (hpet_force_user)
+		old_ich_force_enable_hpet(dev);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
+			 old_ich_force_enable_hpet_user);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,
+			 old_ich_force_enable_hpet_user);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
+			 old_ich_force_enable_hpet_user);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,
+			 old_ich_force_enable_hpet_user);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
-                         old_ich_force_enable_hpet);
+			 old_ich_force_enable_hpet);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12,
-                         old_ich_force_enable_hpet);
+			 old_ich_force_enable_hpet);
+
+
+static void vt8237_force_hpet_resume(void)
+{
+	u32 val;
+
+	if (!force_hpet_address || !cached_dev)
+		return;
+
+	val = 0xfed00000 | 0x80;
+	pci_write_config_dword(cached_dev, 0x68, val);
+
+	pci_read_config_dword(cached_dev, 0x68, &val);
+	if (val & 0x80)
+		printk(KERN_DEBUG "Force enabled HPET at resume\n");
+	else
+		BUG();
+}
+
+static void vt8237_force_enable_hpet(struct pci_dev *dev)
+{
+	u32 uninitialized_var(val);
+
+	if (!hpet_force_user || hpet_address || force_hpet_address)
+		return;
+
+	pci_read_config_dword(dev, 0x68, &val);
+	/*
+	 * Bit 7 is HPET enable bit.
+	 * Bit 31:10 is HPET base address (contrary to what datasheet claims)
+	 */
+	if (val & 0x80) {
+		force_hpet_address = (val & ~0x3ff);
+		printk(KERN_DEBUG "HPET at base address 0x%lx\n",
+			       force_hpet_address);
+		return;
+	}
+
+	/*
+	 * HPET is disabled. Trying enabling at FED00000 and check
+	 * whether it sticks
+	 */
+	val = 0xfed00000 | 0x80;
+	pci_write_config_dword(dev, 0x68, val);
+
+	pci_read_config_dword(dev, 0x68, &val);
+	if (val & 0x80) {
+		force_hpet_address = (val & ~0x3ff);
+		printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+			       force_hpet_address);
+		cached_dev = dev;
+		force_hpet_resume_type = VT8237_FORCE_HPET_RESUME;
+		return;
+	}
+
+	printk(KERN_DEBUG "Failed to force enable HPET\n");
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
+			 vt8237_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
+			 vt8237_force_enable_hpet);
+
 
 void force_hpet_resume(void)
 {
@@ -246,6 +331,9 @@
 	    case OLD_ICH_FORCE_HPET_RESUME:
 		return old_ich_force_hpet_resume();
 
+	    case VT8237_FORCE_HPET_RESUME:
+		return vt8237_force_hpet_resume();
+
 	    default:
 		break;
 	}
diff --git a/arch/x86/kernel/reboot_64.c b/arch/x86/kernel/reboot_64.c
index 368db2b..776eb06 100644
--- a/arch/x86/kernel/reboot_64.c
+++ b/arch/x86/kernel/reboot_64.c
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <asm/io.h>
 #include <asm/delay.h>
+#include <asm/desc.h>
 #include <asm/hw_irq.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -136,7 +137,7 @@
 		}
 
 		case BOOT_TRIPLE: 
-			__asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
+			load_idt((const struct desc_ptr *)&no_idt);
 			__asm__ __volatile__("int3");
 
 			reboot_type = BOOT_KBD;
diff --git a/arch/x86/kernel/reboot_fixups_32.c b/arch/x86/kernel/reboot_fixups_32.c
index 8b30b26..1a07bbe 100644
--- a/arch/x86/kernel/reboot_fixups_32.c
+++ b/arch/x86/kernel/reboot_fixups_32.c
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <asm/reboot_fixups.h>
 #include <asm/msr.h>
+#include <asm/geode.h>
 
 static void cs5530a_warm_reset(struct pci_dev *dev)
 {
@@ -24,11 +25,8 @@
 
 static void cs5536_warm_reset(struct pci_dev *dev)
 {
-	/*
-	 * 6.6.2.12 Soft Reset (DIVIL_SOFT_RESET)
-	 * writing 1 to the LSB of this MSR causes a hard reset.
-	 */
-	wrmsrl(0x51400017, 1ULL);
+	/* writing 1 to the LSB of this MSR causes a hard reset */
+	wrmsrl(MSR_DIVIL_SOFT_RESET, 1ULL);
 	udelay(50); /* shouldn't get here but be safe and spin a while */
 }
 
diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c
index ba91882..3558ac7 100644
--- a/arch/x86/kernel/setup64.c
+++ b/arch/x86/kernel/setup64.c
@@ -185,6 +185,12 @@
 unsigned long kernel_eflags;
 
 /*
+ * Copies of the original ist values from the tss are only accessed during
+ * debugging, no special alignment required.
+ */
+DEFINE_PER_CPU(struct orig_ist, orig_ist);
+
+/*
  * cpu_init() initializes state that is per-CPU. Some data is already
  * initialized (naturally) in the bootstrap process, such as the GDT
  * and IDT. We reload them nevertheless, this function acts as a
@@ -224,8 +230,8 @@
  		memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
 
 	cpu_gdt_descr[cpu].size = GDT_SIZE;
-	asm volatile("lgdt %0" :: "m" (cpu_gdt_descr[cpu]));
-	asm volatile("lidt %0" :: "m" (idt_descr));
+	load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
+	load_idt((const struct desc_ptr *)&idt_descr);
 
 	memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
 	syscall_init();
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index b87a6fd..cc0e914 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -60,6 +60,7 @@
 #include <asm/vmi.h>
 #include <setup_arch.h>
 #include <bios_ebda.h>
+#include <asm/cacheflush.h>
 
 /* This value is set up by the early boot code to point to the value
    immediately after the boot time page tables.  It contains a *physical*
@@ -73,6 +74,7 @@
  */
 extern struct resource code_resource;
 extern struct resource data_resource;
+extern struct resource bss_resource;
 
 /* cpu data as detected by the assembly code in head.S */
 struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
@@ -378,6 +380,49 @@
 extern void zone_sizes_init(void);
 #endif /* !CONFIG_NEED_MULTIPLE_NODES */
 
+static inline unsigned long long get_total_mem(void)
+{
+	unsigned long long total;
+
+	total = max_low_pfn - min_low_pfn;
+#ifdef CONFIG_HIGHMEM
+	total += highend_pfn - highstart_pfn;
+#endif
+
+	return total << PAGE_SHIFT;
+}
+
+#ifdef CONFIG_KEXEC
+static void __init reserve_crashkernel(void)
+{
+	unsigned long long total_mem;
+	unsigned long long crash_size, crash_base;
+	int ret;
+
+	total_mem = get_total_mem();
+
+	ret = parse_crashkernel(boot_command_line, total_mem,
+			&crash_size, &crash_base);
+	if (ret == 0 && crash_size > 0) {
+		if (crash_base > 0) {
+			printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+					"for crashkernel (System RAM: %ldMB)\n",
+					(unsigned long)(crash_size >> 20),
+					(unsigned long)(crash_base >> 20),
+					(unsigned long)(total_mem >> 20));
+			crashk_res.start = crash_base;
+			crashk_res.end   = crash_base + crash_size - 1;
+			reserve_bootmem(crash_base, crash_size);
+		} else
+			printk(KERN_INFO "crashkernel reservation failed - "
+					"you have to specify a base address\n");
+	}
+}
+#else
+static inline void __init reserve_crashkernel(void)
+{}
+#endif
+
 void __init setup_bootmem_allocator(void)
 {
 	unsigned long bootmap_size;
@@ -453,11 +498,7 @@
 		}
 	}
 #endif
-#ifdef CONFIG_KEXEC
-	if (crashk_res.start != crashk_res.end)
-		reserve_bootmem(crashk_res.start,
-			crashk_res.end - crashk_res.start + 1);
-#endif
+	reserve_crashkernel();
 }
 
 /*
@@ -561,6 +602,8 @@
 	code_resource.end = virt_to_phys(_etext)-1;
 	data_resource.start = virt_to_phys(_etext);
 	data_resource.end = virt_to_phys(_edata)-1;
+	bss_resource.start = virt_to_phys(&__bss_start);
+	bss_resource.end = virt_to_phys(&__bss_stop)-1;
 
 	parse_early_param();
 
@@ -585,7 +628,7 @@
 	/*
 	 * NOTE: before this point _nobody_ is allowed to allocate
 	 * any memory using the bootmem allocator.  Although the
-	 * alloctor is now initialised only the first 8Mb of the kernel
+	 * allocator is now initialised only the first 8Mb of the kernel
 	 * virtual address space has been mapped.  All allocations before
 	 * paging_init() has completed must use the alloc_bootmem_low_pages()
 	 * variant (which allocates DMA'able memory) and care must be taken
@@ -622,9 +665,7 @@
 #endif
 
 #ifdef CONFIG_PCI
-#ifdef CONFIG_X86_IO_APIC
-	check_acpi_pci();	/* Checks more than just ACPI actually */
-#endif
+	early_quirks();
 #endif
 
 #ifdef CONFIG_ACPI
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index 5a19f0c..e7a9e36 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -58,6 +58,7 @@
 #include <asm/numa.h>
 #include <asm/sections.h>
 #include <asm/dmi.h>
+#include <asm/cacheflush.h>
 
 /*
  * Machine setup..
@@ -133,6 +134,12 @@
 	.end = 0,
 	.flags = IORESOURCE_RAM,
 };
+struct resource bss_resource = {
+	.name = "Kernel bss",
+	.start = 0,
+	.end = 0,
+	.flags = IORESOURCE_RAM,
+};
 
 #ifdef CONFIG_PROC_VMCORE
 /* elfcorehdr= specifies the location of elf core header
@@ -191,6 +198,37 @@
 }
 #endif
 
+#ifdef CONFIG_KEXEC
+static void __init reserve_crashkernel(void)
+{
+	unsigned long long free_mem;
+	unsigned long long crash_size, crash_base;
+	int ret;
+
+	free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
+
+	ret = parse_crashkernel(boot_command_line, free_mem,
+			&crash_size, &crash_base);
+	if (ret == 0 && crash_size) {
+		if (crash_base > 0) {
+			printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+					"for crashkernel (System RAM: %ldMB)\n",
+					(unsigned long)(crash_size >> 20),
+					(unsigned long)(crash_base >> 20),
+					(unsigned long)(free_mem >> 20));
+			crashk_res.start = crash_base;
+			crashk_res.end   = crash_base + crash_size - 1;
+			reserve_bootmem(crash_base, crash_size);
+		} else
+			printk(KERN_INFO "crashkernel reservation failed - "
+					"you have to specify a base address\n");
+	}
+}
+#else
+static inline void __init reserve_crashkernel(void)
+{}
+#endif
+
 #define EBDA_ADDR_POINTER 0x40E
 
 unsigned __initdata ebda_addr;
@@ -245,6 +283,8 @@
 	code_resource.end = virt_to_phys(&_etext)-1;
 	data_resource.start = virt_to_phys(&_etext);
 	data_resource.end = virt_to_phys(&_edata)-1;
+	bss_resource.start = virt_to_phys(&__bss_start);
+	bss_resource.end = virt_to_phys(&__bss_stop)-1;
 
 	early_identify_cpu(&boot_cpu_data);
 
@@ -271,6 +311,11 @@
 
 	dmi_scan_machine();
 
+#ifdef CONFIG_SMP
+	/* setup to use the static apicid table during kernel startup */
+	x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init;
+#endif
+
 #ifdef CONFIG_ACPI
 	/*
 	 * Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
@@ -357,13 +402,7 @@
 		}
 	}
 #endif
-#ifdef CONFIG_KEXEC
-	if (crashk_res.start != crashk_res.end) {
-		reserve_bootmem_generic(crashk_res.start,
-			crashk_res.end - crashk_res.start + 1);
-	}
-#endif
-
+	reserve_crashkernel();
 	paging_init();
 
 #ifdef CONFIG_PCI
@@ -529,7 +568,7 @@
  		   but in the same order as the HT nodeids.
  		   If that doesn't result in a usable node fall back to the
  		   path for the previous case.  */
- 		int ht_nodeid = apicid - (cpu_data[0].phys_proc_id << bits);
+		int ht_nodeid = apicid - (cpu_data(0).phys_proc_id << bits);
  		if (ht_nodeid >= 0 &&
  		    apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
  			node = apicid_to_node[ht_nodeid];
@@ -853,6 +892,7 @@
 
 #ifdef CONFIG_SMP
 	c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
+	c->cpu_index = 0;
 #endif
 }
 
@@ -959,6 +999,7 @@
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
 	struct cpuinfo_x86 *c = v;
+	int cpu = 0;
 
 	/* 
 	 * These flag bits must match the definitions in <asm/cpufeature.h>.
@@ -1037,8 +1078,9 @@
 
 
 #ifdef CONFIG_SMP
-	if (!cpu_online(c-cpu_data))
+	if (!cpu_online(c->cpu_index))
 		return 0;
+	cpu = c->cpu_index;
 #endif
 
 	seq_printf(m,"processor\t: %u\n"
@@ -1046,7 +1088,7 @@
 		     "cpu family\t: %d\n"
 		     "model\t\t: %d\n"
 		     "model name\t: %s\n",
-		     (unsigned)(c-cpu_data),
+		     (unsigned)cpu,
 		     c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
 		     c->x86,
 		     (int)c->x86_model,
@@ -1058,7 +1100,7 @@
 		seq_printf(m, "stepping\t: unknown\n");
 	
 	if (cpu_has(c,X86_FEATURE_TSC)) {
-		unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data));
+		unsigned int freq = cpufreq_quick_get((unsigned)cpu);
 		if (!freq)
 			freq = cpu_khz;
 		seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
@@ -1071,7 +1113,6 @@
 	
 #ifdef CONFIG_SMP
 	if (smp_num_siblings * c->x86_max_cores > 1) {
-		int cpu = c - cpu_data;
 		seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
 		seq_printf(m, "siblings\t: %d\n",
 			       cpus_weight(per_cpu(cpu_core_map, cpu)));
@@ -1129,12 +1170,16 @@
 
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
-	return *pos < NR_CPUS ? cpu_data + *pos : NULL;
+	if (*pos == 0)	/* just in case, cpu 0 is not the first */
+		*pos = first_cpu(cpu_possible_map);
+	if ((*pos) < NR_CPUS && cpu_possible(*pos))
+		return &cpu_data(*pos);
+	return NULL;
 }
 
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
-	++*pos;
+	*pos = next_cpu(*pos, cpu_possible_map);
 	return c_start(m, pos);
 }
 
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index 0d79df3..9bdd830 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -200,8 +200,8 @@
 	if (show_unhandled_signals && printk_ratelimit())
 		printk("%s%s[%d] bad frame in sigreturn frame:%p eip:%lx"
 		       " esp:%lx oeax:%lx\n",
-		    current->pid > 1 ? KERN_INFO : KERN_EMERG,
-		    current->comm, current->pid, frame, regs->eip,
+		    task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
+		    current->comm, task_pid_nr(current), frame, regs->eip,
 		    regs->esp, regs->orig_eax);
 
 	force_sig(SIGSEGV, current);
@@ -594,7 +594,7 @@
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 	if (signr > 0) {
-		/* Reenable any watchpoints before delivering the
+		/* Re-enable any watchpoints before delivering the
 		 * signal to user space. The processor register will
 		 * have been cleared if the watchpoint triggered
 		 * inside the kernel.
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 683802b..ab086b0 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -410,7 +410,7 @@
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 	if (signr > 0) {
-		/* Reenable any watchpoints before delivering the
+		/* Re-enable any watchpoints before delivering the
 		 * signal to user space. The processor register will
 		 * have been cleared if the watchpoint triggered
 		 * inside the kernel.
diff --git a/arch/x86/kernel/smp_32.c b/arch/x86/kernel/smp_32.c
index 791d9f8..f321153 100644
--- a/arch/x86/kernel/smp_32.c
+++ b/arch/x86/kernel/smp_32.c
@@ -69,7 +69,7 @@
  *
  *		B stepping CPUs may hang. There are hardware work arounds
  *	for this. We warn about it in case your board doesn't have the work
- *	arounds. Basically thats so I can tell anyone with a B stepping
+ *	arounds. Basically that's so I can tell anyone with a B stepping
  *	CPU and SMP problems "tough".
  *
  *	Specific items [From Pentium Processor Specification Update]
@@ -273,7 +273,7 @@
  * 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask);
  * 	Stop ipi delivery for the old mm. This is not synchronized with
  * 	the other cpus, but smp_invalidate_interrupt ignore flush ipis
- * 	for the wrong mm, and in the worst case we perform a superflous
+ * 	for the wrong mm, and in the worst case we perform a superfluous
  * 	tlb flush.
  * 1a2) set cpu_tlbstate to TLBSTATE_OK
  * 	Now the smp_invalidate_interrupt won't call leave_mm if cpu0
@@ -610,7 +610,7 @@
 	 */
 	cpu_clear(smp_processor_id(), cpu_online_map);
 	disable_local_APIC();
-	if (cpu_data[smp_processor_id()].hlt_works_ok)
+	if (cpu_data(smp_processor_id()).hlt_works_ok)
 		for(;;) halt();
 	for (;;);
 }
@@ -676,7 +676,7 @@
 	int i;
 
 	for (i = 0; i < NR_CPUS; i++) {
-		if (x86_cpu_to_apicid[i] == apic_id)
+		if (per_cpu(x86_cpu_to_apicid, i) == apic_id)
 			return i;
 	}
 	return -1;
diff --git a/arch/x86/kernel/smp_64.c b/arch/x86/kernel/smp_64.c
index 5c29647..03fa6ed 100644
--- a/arch/x86/kernel/smp_64.c
+++ b/arch/x86/kernel/smp_64.c
@@ -322,17 +322,27 @@
 }
 
 /*
- * this function sends a 'generic call function' IPI to one other CPU
- * in the system.
- *
- * cpu is a standard Linux logical CPU number.
+ * this function sends a 'generic call function' IPI to all other CPU
+ * of the system defined in the mask.
  */
-static void
-__smp_call_function_single(int cpu, void (*func) (void *info), void *info,
-				int nonatomic, int wait)
+
+static int
+__smp_call_function_mask(cpumask_t mask,
+			 void (*func)(void *), void *info,
+			 int wait)
 {
 	struct call_data_struct data;
-	int cpus = 1;
+	cpumask_t allbutself;
+	int cpus;
+
+	allbutself = cpu_online_map;
+	cpu_clear(smp_processor_id(), allbutself);
+
+	cpus_and(mask, mask, allbutself);
+	cpus = cpus_weight(mask);
+
+	if (!cpus)
+		return 0;
 
 	data.func = func;
 	data.info = info;
@@ -343,19 +353,55 @@
 
 	call_data = &data;
 	wmb();
-	/* Send a message to all other CPUs and wait for them to respond */
-	send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR);
+
+	/* Send a message to other CPUs */
+	if (cpus_equal(mask, allbutself))
+		send_IPI_allbutself(CALL_FUNCTION_VECTOR);
+	else
+		send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
 
 	/* Wait for response */
 	while (atomic_read(&data.started) != cpus)
 		cpu_relax();
 
 	if (!wait)
-		return;
+		return 0;
 
 	while (atomic_read(&data.finished) != cpus)
 		cpu_relax();
+
+	return 0;
 }
+/**
+ * smp_call_function_mask(): Run a function on a set of other CPUs.
+ * @mask: The set of cpus to run on.  Must not include the current cpu.
+ * @func: The function to run. This must be fast and non-blocking.
+ * @info: An arbitrary pointer to pass to the function.
+ * @wait: If true, wait (atomically) until function has completed on other CPUs.
+ *
+ * Returns 0 on success, else a negative status code.
+ *
+ * If @wait is true, then returns once @func has returned; otherwise
+ * it returns just before the target cpu calls @func.
+ *
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler or from a bottom half handler.
+ */
+int smp_call_function_mask(cpumask_t mask,
+			   void (*func)(void *), void *info,
+			   int wait)
+{
+	int ret;
+
+	/* Can deadlock when called with interrupts disabled */
+	WARN_ON(irqs_disabled());
+
+	spin_lock(&call_lock);
+	ret = __smp_call_function_mask(mask, func, info, wait);
+	spin_unlock(&call_lock);
+	return ret;
+}
+EXPORT_SYMBOL(smp_call_function_mask);
 
 /*
  * smp_call_function_single - Run a function on a specific CPU
@@ -374,6 +420,7 @@
 	int nonatomic, int wait)
 {
 	/* prevent preemption and reschedule on another processor */
+	int ret;
 	int me = get_cpu();
 
 	/* Can deadlock when called with interrupts disabled */
@@ -387,51 +434,14 @@
 		return 0;
 	}
 
-	spin_lock(&call_lock);
-	__smp_call_function_single(cpu, func, info, nonatomic, wait);
-	spin_unlock(&call_lock);
+	ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, wait);
+
 	put_cpu();
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL(smp_call_function_single);
 
 /*
- * this function sends a 'generic call function' IPI to all other CPUs
- * in the system.
- */
-static void __smp_call_function (void (*func) (void *info), void *info,
-				int nonatomic, int wait)
-{
-	struct call_data_struct data;
-	int cpus = num_online_cpus()-1;
-
-	if (!cpus)
-		return;
-
-	data.func = func;
-	data.info = info;
-	atomic_set(&data.started, 0);
-	data.wait = wait;
-	if (wait)
-		atomic_set(&data.finished, 0);
-
-	call_data = &data;
-	wmb();
-	/* Send a message to all other CPUs and wait for them to respond */
-	send_IPI_allbutself(CALL_FUNCTION_VECTOR);
-
-	/* Wait for response */
-	while (atomic_read(&data.started) != cpus)
-		cpu_relax();
-
-	if (!wait)
-		return;
-
-	while (atomic_read(&data.finished) != cpus)
-		cpu_relax();
-}
-
-/*
  * smp_call_function - run a function on all other CPUs.
  * @func: The function to run. This must be fast and non-blocking.
  * @info: An arbitrary pointer to pass to the function.
@@ -449,10 +459,7 @@
 int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
 			int wait)
 {
-	spin_lock(&call_lock);
-	__smp_call_function(func,info,nonatomic,wait);
-	spin_unlock(&call_lock);
-	return 0;
+	return smp_call_function_mask(cpu_online_map, func, info, wait);
 }
 EXPORT_SYMBOL(smp_call_function);
 
@@ -479,7 +486,7 @@
 	/* Don't deadlock on the call lock in panic */
 	nolock = !spin_trylock(&call_lock);
 	local_irq_save(flags);
-	__smp_call_function(stop_this_cpu, NULL, 0, 0);
+	__smp_call_function_mask(cpu_online_map, stop_this_cpu, NULL, 0);
 	if (!nolock)
 		spin_unlock(&call_lock);
 	disable_local_APIC();
diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c
index be3faac..ef0f34e 100644
--- a/arch/x86/kernel/smpboot_32.c
+++ b/arch/x86/kernel/smpboot_32.c
@@ -67,7 +67,7 @@
 EXPORT_SYMBOL(smp_num_siblings);
 
 /* Last level cache ID of each logical CPU */
-int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
+DEFINE_PER_CPU(u8, cpu_llc_id) = BAD_APICID;
 
 /* representing HT siblings of each logical CPU */
 DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
@@ -89,12 +89,20 @@
 static cpumask_t smp_commenced_mask;
 
 /* Per CPU bogomips and other parameters */
-struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_data);
+DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
+EXPORT_PER_CPU_SYMBOL(cpu_info);
 
-u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
-			{ [0 ... NR_CPUS-1] = 0xff };
-EXPORT_SYMBOL(x86_cpu_to_apicid);
+/*
+ * The following static array is used during kernel startup
+ * and the x86_cpu_to_apicid_ptr contains the address of the
+ * array during this time.  Is it zeroed when the per_cpu
+ * data area is removed.
+ */
+u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata =
+			{ [0 ... NR_CPUS-1] = BAD_APICID };
+void *x86_cpu_to_apicid_ptr;
+DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
+EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
 
 u8 apicid_2_node[MAX_APICID];
 
@@ -150,9 +158,10 @@
 
 void __cpuinit smp_store_cpu_info(int id)
 {
-	struct cpuinfo_x86 *c = cpu_data + id;
+	struct cpuinfo_x86 *c = &cpu_data(id);
 
 	*c = boot_cpu_data;
+	c->cpu_index = id;
 	if (id!=0)
 		identify_secondary_cpu(c);
 	/*
@@ -294,7 +303,7 @@
 /* maps the cpu to the sched domain representing multi-core */
 cpumask_t cpu_coregroup_map(int cpu)
 {
-	struct cpuinfo_x86 *c = cpu_data + cpu;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	/*
 	 * For perf, we return last level cache shared map.
 	 * And for power savings, we return cpu_core_map
@@ -311,41 +320,41 @@
 void __cpuinit set_cpu_sibling_map(int cpu)
 {
 	int i;
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
 	cpu_set(cpu, cpu_sibling_setup_map);
 
 	if (smp_num_siblings > 1) {
 		for_each_cpu_mask(i, cpu_sibling_setup_map) {
-			if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
-			    c[cpu].cpu_core_id == c[i].cpu_core_id) {
+			if (c->phys_proc_id == cpu_data(i).phys_proc_id &&
+			    c->cpu_core_id == cpu_data(i).cpu_core_id) {
 				cpu_set(i, per_cpu(cpu_sibling_map, cpu));
 				cpu_set(cpu, per_cpu(cpu_sibling_map, i));
 				cpu_set(i, per_cpu(cpu_core_map, cpu));
 				cpu_set(cpu, per_cpu(cpu_core_map, i));
-				cpu_set(i, c[cpu].llc_shared_map);
-				cpu_set(cpu, c[i].llc_shared_map);
+				cpu_set(i, c->llc_shared_map);
+				cpu_set(cpu, cpu_data(i).llc_shared_map);
 			}
 		}
 	} else {
 		cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
 	}
 
-	cpu_set(cpu, c[cpu].llc_shared_map);
+	cpu_set(cpu, c->llc_shared_map);
 
 	if (current_cpu_data.x86_max_cores == 1) {
 		per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
-		c[cpu].booted_cores = 1;
+		c->booted_cores = 1;
 		return;
 	}
 
 	for_each_cpu_mask(i, cpu_sibling_setup_map) {
-		if (cpu_llc_id[cpu] != BAD_APICID &&
-		    cpu_llc_id[cpu] == cpu_llc_id[i]) {
-			cpu_set(i, c[cpu].llc_shared_map);
-			cpu_set(cpu, c[i].llc_shared_map);
+		if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
+		    per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
+			cpu_set(i, c->llc_shared_map);
+			cpu_set(cpu, cpu_data(i).llc_shared_map);
 		}
-		if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
+		if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
 			cpu_set(i, per_cpu(cpu_core_map, cpu));
 			cpu_set(cpu, per_cpu(cpu_core_map, i));
 			/*
@@ -357,15 +366,15 @@
 				 * the booted_cores for this new cpu
 				 */
 				if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
-					c[cpu].booted_cores++;
+					c->booted_cores++;
 				/*
 				 * increment the core count for all
 				 * the other cpus in this package
 				 */
 				if (i != cpu)
-					c[i].booted_cores++;
-			} else if (i != cpu && !c[cpu].booted_cores)
-				c[cpu].booted_cores = c[i].booted_cores;
+					cpu_data(i).booted_cores++;
+			} else if (i != cpu && !c->booted_cores)
+				c->booted_cores = cpu_data(i).booted_cores;
 		}
 	}
 }
@@ -412,7 +421,7 @@
 	/*
 	 * We need to hold call_lock, so there is no inconsistency
 	 * between the time smp_call_function() determines number of
-	 * IPI receipients, and the time when the determination is made
+	 * IPI recipients, and the time when the determination is made
 	 * for which cpus receive the IPI. Holding this
 	 * lock helps us to not include this cpu in a currently in progress
 	 * smp_call_function().
@@ -804,7 +813,7 @@
 
 	irq_ctx_init(cpu);
 
-	x86_cpu_to_apicid[cpu] = apicid;
+	per_cpu(x86_cpu_to_apicid, cpu) = apicid;
 	/*
 	 * This grunge runs the startup process for
 	 * the targeted processor.
@@ -844,7 +853,7 @@
 			/* number CPUs logically, starting from 1 (BSP is 0) */
 			Dprintk("OK.\n");
 			printk("CPU%d: ", cpu);
-			print_cpu_info(&cpu_data[cpu]);
+			print_cpu_info(&cpu_data(cpu));
 			Dprintk("CPU has booted.\n");
 		} else {
 			boot_error= 1;
@@ -866,7 +875,7 @@
 		cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
 		cpucount--;
 	} else {
-		x86_cpu_to_apicid[cpu] = apicid;
+		per_cpu(x86_cpu_to_apicid, cpu) = apicid;
 		cpu_set(cpu, cpu_present_map);
 	}
 
@@ -915,7 +924,7 @@
 	struct warm_boot_cpu_info info;
 	int	apicid, ret;
 
-	apicid = x86_cpu_to_apicid[cpu];
+	apicid = per_cpu(x86_cpu_to_apicid, cpu);
 	if (apicid == BAD_APICID) {
 		ret = -ENODEV;
 		goto exit;
@@ -961,11 +970,11 @@
 	 */
 	smp_store_cpu_info(0); /* Final full version of the data */
 	printk("CPU%d: ", 0);
-	print_cpu_info(&cpu_data[0]);
+	print_cpu_info(&cpu_data(0));
 
 	boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
 	boot_cpu_logical_apicid = logical_smp_processor_id();
-	x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
+	per_cpu(x86_cpu_to_apicid, 0) = boot_cpu_physical_apicid;
 
 	current_thread_info()->cpu = 0;
 
@@ -1008,6 +1017,7 @@
 		printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
 		smpboot_clear_io_apic_irqs();
 		phys_cpu_present_map = physid_mask_of_physid(0);
+		map_cpu_to_logical_apicid();
 		cpu_set(0, per_cpu(cpu_sibling_map, 0));
 		cpu_set(0, per_cpu(cpu_core_map, 0));
 		return;
@@ -1029,6 +1039,7 @@
 		}
 		smpboot_clear_io_apic_irqs();
 		phys_cpu_present_map = physid_mask_of_physid(0);
+		map_cpu_to_logical_apicid();
 		cpu_set(0, per_cpu(cpu_sibling_map, 0));
 		cpu_set(0, per_cpu(cpu_core_map, 0));
 		return;
@@ -1082,7 +1093,7 @@
 	Dprintk("Before bogomips.\n");
 	for (cpu = 0; cpu < NR_CPUS; cpu++)
 		if (cpu_isset(cpu, cpu_callout_map))
-			bogosum += cpu_data[cpu].loops_per_jiffy;
+			bogosum += cpu_data(cpu).loops_per_jiffy;
 	printk(KERN_INFO
 		"Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
 		cpucount+1,
@@ -1152,7 +1163,7 @@
 void remove_siblinginfo(int cpu)
 {
 	int sibling;
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
 	for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
 		cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
@@ -1160,15 +1171,15 @@
 		 * last thread sibling in this cpu core going down
 		 */
 		if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
-			c[sibling].booted_cores--;
+			cpu_data(sibling).booted_cores--;
 	}
 			
 	for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
 		cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
 	cpus_clear(per_cpu(cpu_sibling_map, cpu));
 	cpus_clear(per_cpu(cpu_core_map, cpu));
-	c[cpu].phys_proc_id = 0;
-	c[cpu].cpu_core_id = 0;
+	c->phys_proc_id = 0;
+	c->cpu_core_id = 0;
 	cpu_clear(cpu, cpu_sibling_setup_map);
 }
 
diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c
index e351ac4..b7e768d 100644
--- a/arch/x86/kernel/smpboot_64.c
+++ b/arch/x86/kernel/smpboot_64.c
@@ -65,7 +65,7 @@
 EXPORT_SYMBOL(smp_num_siblings);
 
 /* Last level cache ID of each logical CPU */
-u8 cpu_llc_id[NR_CPUS] __cpuinitdata  = {[0 ... NR_CPUS-1] = BAD_APICID};
+DEFINE_PER_CPU(u8, cpu_llc_id) = BAD_APICID;
 
 /* Bitmask of currently online CPUs */
 cpumask_t cpu_online_map __read_mostly;
@@ -84,8 +84,8 @@
 EXPORT_SYMBOL(cpu_possible_map);
 
 /* Per CPU bogomips and other parameters */
-struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_data);
+DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
+EXPORT_PER_CPU_SYMBOL(cpu_info);
 
 /* Set when the idlers are all forked */
 int smp_threads_ready;
@@ -138,9 +138,10 @@
 
 static void __cpuinit smp_store_cpu_info(int id)
 {
-	struct cpuinfo_x86 *c = cpu_data + id;
+	struct cpuinfo_x86 *c = &cpu_data(id);
 
 	*c = boot_cpu_data;
+	c->cpu_index = id;
 	identify_cpu(c);
 	print_cpu_info(c);
 }
@@ -237,7 +238,7 @@
 /* maps the cpu to the sched domain representing multi-core */
 cpumask_t cpu_coregroup_map(int cpu)
 {
-	struct cpuinfo_x86 *c = cpu_data + cpu;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	/*
 	 * For perf, we return last level cache shared map.
 	 * And for power savings, we return cpu_core_map
@@ -254,41 +255,41 @@
 static inline void set_cpu_sibling_map(int cpu)
 {
 	int i;
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
 	cpu_set(cpu, cpu_sibling_setup_map);
 
 	if (smp_num_siblings > 1) {
 		for_each_cpu_mask(i, cpu_sibling_setup_map) {
-			if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
-			    c[cpu].cpu_core_id == c[i].cpu_core_id) {
+			if (c->phys_proc_id == cpu_data(i).phys_proc_id &&
+			    c->cpu_core_id == cpu_data(i).cpu_core_id) {
 				cpu_set(i, per_cpu(cpu_sibling_map, cpu));
 				cpu_set(cpu, per_cpu(cpu_sibling_map, i));
 				cpu_set(i, per_cpu(cpu_core_map, cpu));
 				cpu_set(cpu, per_cpu(cpu_core_map, i));
-				cpu_set(i, c[cpu].llc_shared_map);
-				cpu_set(cpu, c[i].llc_shared_map);
+				cpu_set(i, c->llc_shared_map);
+				cpu_set(cpu, cpu_data(i).llc_shared_map);
 			}
 		}
 	} else {
 		cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
 	}
 
-	cpu_set(cpu, c[cpu].llc_shared_map);
+	cpu_set(cpu, c->llc_shared_map);
 
 	if (current_cpu_data.x86_max_cores == 1) {
 		per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
-		c[cpu].booted_cores = 1;
+		c->booted_cores = 1;
 		return;
 	}
 
 	for_each_cpu_mask(i, cpu_sibling_setup_map) {
-		if (cpu_llc_id[cpu] != BAD_APICID &&
-		    cpu_llc_id[cpu] == cpu_llc_id[i]) {
-			cpu_set(i, c[cpu].llc_shared_map);
-			cpu_set(cpu, c[i].llc_shared_map);
+		if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
+		    per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
+			cpu_set(i, c->llc_shared_map);
+			cpu_set(cpu, cpu_data(i).llc_shared_map);
 		}
-		if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
+		if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
 			cpu_set(i, per_cpu(cpu_core_map, cpu));
 			cpu_set(cpu, per_cpu(cpu_core_map, i));
 			/*
@@ -300,15 +301,15 @@
 				 * the booted_cores for this new cpu
 				 */
 				if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
-					c[cpu].booted_cores++;
+					c->booted_cores++;
 				/*
 				 * increment the core count for all
 				 * the other cpus in this package
 				 */
 				if (i != cpu)
-					c[i].booted_cores++;
-			} else if (i != cpu && !c[cpu].booted_cores)
-				c[cpu].booted_cores = c[i].booted_cores;
+					cpu_data(i).booted_cores++;
+			} else if (i != cpu && !c->booted_cores)
+				c->booted_cores = cpu_data(i).booted_cores;
 		}
 	}
 }
@@ -350,7 +351,7 @@
 	/*
 	 * We need to hold call_lock, so there is no inconsistency
 	 * between the time smp_call_function() determines number of
-	 * IPI receipients, and the time when the determination is made
+	 * IPI recipients, and the time when the determination is made
 	 * for which cpus receive the IPI in genapic_flat.c. Holding this
 	 * lock helps us to not include this cpu in a currently in progress
 	 * smp_call_function().
@@ -694,7 +695,7 @@
 		clear_node_cpumask(cpu); /* was set by numa_add_cpu */
 		cpu_clear(cpu, cpu_present_map);
 		cpu_clear(cpu, cpu_possible_map);
-		x86_cpu_to_apicid[cpu] = BAD_APICID;
+		per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
 		return -EIO;
 	}
 
@@ -841,6 +842,26 @@
 }
 
 /*
+ * Copy apicid's found by MP_processor_info from initial array to the per cpu
+ * data area.  The x86_cpu_to_apicid_init array is then expendable and the
+ * x86_cpu_to_apicid_ptr is zeroed indicating that the static array is no
+ * longer available.
+ */
+void __init smp_set_apicids(void)
+{
+	int cpu;
+
+	for_each_cpu_mask(cpu, cpu_possible_map) {
+		if (per_cpu_offset(cpu))
+			per_cpu(x86_cpu_to_apicid, cpu) =
+						x86_cpu_to_apicid_init[cpu];
+	}
+
+	/* indicate the static array will be going away soon */
+	x86_cpu_to_apicid_ptr = NULL;
+}
+
+/*
  * Prepare for SMP bootup.  The MP table or ACPI has been read
  * earlier.  Just do some sanity checking here and enable APIC mode.
  */
@@ -849,6 +870,7 @@
 	nmi_watchdog_default();
 	current_cpu_data = boot_cpu_data;
 	current_thread_info()->cpu = 0;  /* needed? */
+	smp_set_apicids();
 	set_cpu_sibling_map(0);
 
 	if (smp_sanity_check(max_cpus) < 0) {
@@ -968,7 +990,7 @@
 static void remove_siblinginfo(int cpu)
 {
 	int sibling;
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
 	for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
 		cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
@@ -976,15 +998,15 @@
 		 * last thread sibling in this cpu core going down
 		 */
 		if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
-			c[sibling].booted_cores--;
+			cpu_data(sibling).booted_cores--;
 	}
 			
 	for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
 		cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
 	cpus_clear(per_cpu(cpu_sibling_map, cpu));
 	cpus_clear(per_cpu(cpu_core_map, cpu));
-	c[cpu].phys_proc_id = 0;
-	c[cpu].cpu_core_id = 0;
+	c->phys_proc_id = 0;
+	c->cpu_core_id = 0;
 	cpu_clear(cpu, cpu_sibling_setup_map);
 }
 
diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c
index 91c7acc..72f4634 100644
--- a/arch/x86/kernel/summit_32.c
+++ b/arch/x86/kernel/summit_32.c
@@ -64,7 +64,7 @@
 
 	switch (rio_devs[wpeg_num]->type){
 	case CompatWPEG:
-		/* The Compatability Winnipeg controls the 2 legacy buses,
+		/* The Compatibility Winnipeg controls the 2 legacy buses,
 		 * the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case
 		 * a PCI-PCI bridge card is used in either slot: total 5 buses.
 		 */
diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c
index 573c0a6..bc9f59c 100644
--- a/arch/x86/kernel/suspend_64.c
+++ b/arch/x86/kernel/suspend_64.c
@@ -32,9 +32,9 @@
 	/*
 	 * descriptor tables
 	 */
-	asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
-	asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
-	asm volatile ("str %0"  : "=m" (ctxt->tr));
+	store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
+	store_idt((struct desc_ptr *)&ctxt->idt_limit);
+	store_tr(ctxt->tr);
 
 	/* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
 	/*
@@ -91,8 +91,9 @@
 	 * now restore the descriptor tables to their proper values
 	 * ltr is done i fix_processor_context().
 	 */
-	asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
-	asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
+	load_gdt((const struct desc_ptr *)&ctxt->gdt_limit);
+	load_idt((const struct desc_ptr *)&ctxt->idt_limit);
+
 
 	/*
 	 * segment registers
@@ -123,7 +124,7 @@
 	int cpu = smp_processor_id();
 	struct tss_struct *t = &per_cpu(init_tss, cpu);
 
-	set_tss_desc(cpu,t);	/* This just modifies memory; should not be neccessary. But... This is neccessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
+	set_tss_desc(cpu,t);	/* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
 
 	cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9;
 
@@ -150,8 +151,22 @@
 /* Defined in arch/x86_64/kernel/suspend_asm.S */
 extern int restore_image(void);
 
+/*
+ * Address to jump to in the last phase of restore in order to get to the image
+ * kernel's text (this value is passed in the image header).
+ */
+unsigned long restore_jump_address;
+
+/*
+ * Value of the cr3 register from before the hibernation (this value is passed
+ * in the image header).
+ */
+unsigned long restore_cr3;
+
 pgd_t *temp_level4_pgt;
 
+void *relocated_restore_code;
+
 static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
 {
 	long i, j;
@@ -175,7 +190,7 @@
 
 			if (paddr >= end)
 				break;
-			pe = _PAGE_NX | _PAGE_PSE | _KERNPG_TABLE | paddr;
+			pe = __PAGE_KERNEL_LARGE_EXEC | paddr;
 			pe &= __supported_pte_mask;
 			set_pmd(pmd, __pmd(pe));
 		}
@@ -183,25 +198,42 @@
 	return 0;
 }
 
+static int res_kernel_text_pud_init(pud_t *pud, unsigned long start)
+{
+	pmd_t *pmd;
+	unsigned long paddr;
+
+	pmd = (pmd_t *)get_safe_page(GFP_ATOMIC);
+	if (!pmd)
+		return -ENOMEM;
+	set_pud(pud + pud_index(start), __pud(__pa(pmd) | _KERNPG_TABLE));
+	for (paddr = 0; paddr < KERNEL_TEXT_SIZE; pmd++, paddr += PMD_SIZE) {
+		unsigned long pe;
+
+		pe = __PAGE_KERNEL_LARGE_EXEC | _PAGE_GLOBAL | paddr;
+		pe &= __supported_pte_mask;
+		set_pmd(pmd, __pmd(pe));
+	}
+
+	return 0;
+}
+
 static int set_up_temporary_mappings(void)
 {
 	unsigned long start, end, next;
+	pud_t *pud;
 	int error;
 
 	temp_level4_pgt = (pgd_t *)get_safe_page(GFP_ATOMIC);
 	if (!temp_level4_pgt)
 		return -ENOMEM;
 
-	/* It is safe to reuse the original kernel mapping */
-	set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
-		init_level4_pgt[pgd_index(__START_KERNEL_map)]);
-
 	/* Set up the direct mapping from scratch */
 	start = (unsigned long)pfn_to_kaddr(0);
 	end = (unsigned long)pfn_to_kaddr(end_pfn);
 
 	for (; start < end; start = next) {
-		pud_t *pud = (pud_t *)get_safe_page(GFP_ATOMIC);
+		pud = (pud_t *)get_safe_page(GFP_ATOMIC);
 		if (!pud)
 			return -ENOMEM;
 		next = start + PGDIR_SIZE;
@@ -212,7 +244,17 @@
 		set_pgd(temp_level4_pgt + pgd_index(start),
 			mk_kernel_pgd(__pa(pud)));
 	}
-	return 0;
+
+	/* Set up the kernel text mapping from scratch */
+	pud = (pud_t *)get_safe_page(GFP_ATOMIC);
+	if (!pud)
+		return -ENOMEM;
+	error = res_kernel_text_pud_init(pud, __START_KERNEL_map);
+	if (!error)
+		set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
+			__pgd(__pa(pud) | _PAGE_TABLE));
+
+	return error;
 }
 
 int swsusp_arch_resume(void)
@@ -222,6 +264,13 @@
 	/* We have got enough memory and from now on we cannot recover */
 	if ((error = set_up_temporary_mappings()))
 		return error;
+
+	relocated_restore_code = (void *)get_safe_page(GFP_ATOMIC);
+	if (!relocated_restore_code)
+		return -ENOMEM;
+	memcpy(relocated_restore_code, &core_restore_code,
+	       &restore_registers - &core_restore_code);
+
 	restore_image();
 	return 0;
 }
@@ -236,4 +285,43 @@
 	unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT;
 	return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
 }
+
+struct restore_data_record {
+	unsigned long jump_address;
+	unsigned long cr3;
+	unsigned long magic;
+};
+
+#define RESTORE_MAGIC	0x0123456789ABCDEFUL
+
+/**
+ *	arch_hibernation_header_save - populate the architecture specific part
+ *		of a hibernation image header
+ *	@addr: address to save the data at
+ */
+int arch_hibernation_header_save(void *addr, unsigned int max_size)
+{
+	struct restore_data_record *rdr = addr;
+
+	if (max_size < sizeof(struct restore_data_record))
+		return -EOVERFLOW;
+	rdr->jump_address = restore_jump_address;
+	rdr->cr3 = restore_cr3;
+	rdr->magic = RESTORE_MAGIC;
+	return 0;
+}
+
+/**
+ *	arch_hibernation_header_restore - read the architecture specific data
+ *		from the hibernation image header
+ *	@addr: address to read the data from
+ */
+int arch_hibernation_header_restore(void *addr)
+{
+	struct restore_data_record *rdr = addr;
+
+	restore_jump_address = rdr->jump_address;
+	restore_cr3 = rdr->cr3;
+	return (rdr->magic == RESTORE_MAGIC) ? 0 : -EINVAL;
+}
 #endif /* CONFIG_HIBERNATION */
diff --git a/arch/x86/kernel/suspend_asm_64.S b/arch/x86/kernel/suspend_asm_64.S
index 16d183f..48344b6 100644
--- a/arch/x86/kernel/suspend_asm_64.S
+++ b/arch/x86/kernel/suspend_asm_64.S
@@ -2,8 +2,8 @@
  *
  * Distribute under GPLv2.
  *
- * swsusp_arch_resume may not use any stack, nor any variable that is
- * not "NoSave" during copying pages:
+ * swsusp_arch_resume must not use any stack or any nonlocal variables while
+ * copying pages:
  *
  * Its rewriting one kernel image with another. What is stack in "old"
  * image could very well be data page in "new" image, and overwriting
@@ -36,6 +36,13 @@
 	movq %r15, saved_context_r15(%rip)
 	pushfq ; popq saved_context_eflags(%rip)
 
+	/* save the address of restore_registers */
+	movq	$restore_registers, %rax
+	movq	%rax, restore_jump_address(%rip)
+	/* save cr3 */
+	movq	%cr3, %rax
+	movq	%rax, restore_cr3(%rip)
+
 	call swsusp_save
 	ret
 
@@ -54,7 +61,17 @@
 	movq	%rcx, %cr3;
 	movq	%rax, %cr4;  # turn PGE back on
 
+	/* prepare to jump to the image kernel */
+	movq	restore_jump_address(%rip), %rax
+	movq	restore_cr3(%rip), %rbx
+
+	/* prepare to copy image data to their original locations */
 	movq	restore_pblist(%rip), %rdx
+	movq	relocated_restore_code(%rip), %rcx
+	jmpq	*%rcx
+
+	/* code below has been relocated to a safe page */
+ENTRY(core_restore_code)
 loop:
 	testq	%rdx, %rdx
 	jz	done
@@ -62,7 +79,7 @@
 	/* get addresses from the pbe and copy the page */
 	movq	pbe_address(%rdx), %rsi
 	movq	pbe_orig_address(%rdx), %rdi
-	movq	$512, %rcx
+	movq	$(PAGE_SIZE >> 3), %rcx
 	rep
 	movsq
 
@@ -70,10 +87,22 @@
 	movq	pbe_next(%rdx), %rdx
 	jmp	loop
 done:
+	/* jump to the restore_registers address from the image header */
+	jmpq	*%rax
+	/*
+	 * NOTE: This assumes that the boot kernel's text mapping covers the
+	 * image kernel's page containing restore_registers and the address of
+	 * this page is the same as in the image kernel's text mapping (it
+	 * should always be true, because the text mapping is linear, starting
+	 * from 0, and is supposed to cover the entire kernel text for every
+	 * kernel).
+	 *
+	 * code below belongs to the image kernel
+	 */
+
+ENTRY(restore_registers)
 	/* go back to the original page tables */
-	movq    $(init_level4_pgt - __START_KERNEL_map), %rax
-	addq    phys_base(%rip), %rax
-	movq    %rax, %cr3
+	movq    %rbx, %cr3
 
 	/* Flush TLB, including "global" things (vmalloc) */
 	movq	mmu_cr4_features(%rip), %rax
@@ -84,12 +113,9 @@
 	movq	%rcx, %cr3
 	movq	%rax, %cr4;  # turn PGE back on
 
-	movl	$24, %eax
-	movl	%eax, %ds
-
 	movq saved_context_esp(%rip), %rsp
 	movq saved_context_ebp(%rip), %rbp
-	/* Don't restore %rax, it must be 0 anyway */
+	/* restore GPRs (we don't restore %rax, it must be 0 anyway) */
 	movq saved_context_ebx(%rip), %rbx
 	movq saved_context_ecx(%rip), %rcx
 	movq saved_context_edx(%rip), %rdx
@@ -107,4 +133,7 @@
 
 	xorq	%rax, %rax
 
+	/* tell the hibernation core that we've just restored the memory */
+	movq	%rax, in_suspend(%rip)
+
 	ret
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index b132d39..cc9acac 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -63,6 +63,9 @@
 
 int panic_on_unrecovered_nmi;
 
+DECLARE_BITMAP(used_vectors, NR_VECTORS);
+EXPORT_SYMBOL_GPL(used_vectors);
+
 asmlinkage int system_call(void);
 
 /* Do we ignore FPU interrupts ? */
@@ -288,48 +291,24 @@
 void show_registers(struct pt_regs *regs)
 {
 	int i;
-	int in_kernel = 1;
-	unsigned long esp;
-	unsigned short ss, gs;
 
-	esp = (unsigned long) (&regs->esp);
-	savesegment(ss, ss);
-	savesegment(gs, gs);
-	if (user_mode_vm(regs)) {
-		in_kernel = 0;
-		esp = regs->esp;
-		ss = regs->xss & 0xffff;
-	}
 	print_modules();
-	printk(KERN_EMERG "CPU:    %d\n"
-		KERN_EMERG "EIP:    %04x:[<%08lx>]    %s VLI\n"
-		KERN_EMERG "EFLAGS: %08lx   (%s %.*s)\n",
-		smp_processor_id(), 0xffff & regs->xcs, regs->eip,
-		print_tainted(), regs->eflags, init_utsname()->release,
-		(int)strcspn(init_utsname()->version, " "),
-		init_utsname()->version);
-	print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip);
-	printk(KERN_EMERG "eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
-		regs->eax, regs->ebx, regs->ecx, regs->edx);
-	printk(KERN_EMERG "esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
-		regs->esi, regs->edi, regs->ebp, esp);
-	printk(KERN_EMERG "ds: %04x   es: %04x   fs: %04x  gs: %04x  ss: %04x\n",
-	       regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ss);
+	__show_registers(regs, 0);
 	printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)",
-		TASK_COMM_LEN, current->comm, current->pid,
+		TASK_COMM_LEN, current->comm, task_pid_nr(current),
 		current_thread_info(), current, task_thread_info(current));
 	/*
 	 * When in-kernel, we also print out the stack and code at the
 	 * time of the fault..
 	 */
-	if (in_kernel) {
+	if (!user_mode_vm(regs)) {
 		u8 *eip;
 		unsigned int code_prologue = code_bytes * 43 / 64;
 		unsigned int code_len = code_bytes;
 		unsigned char c;
 
 		printk("\n" KERN_EMERG "Stack: ");
-		show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
+		show_stack_log_lvl(NULL, regs, &regs->esp, KERN_EMERG);
 
 		printk(KERN_EMERG "Code: ");
 
@@ -374,11 +353,11 @@
 void die(const char * str, struct pt_regs * regs, long err)
 {
 	static struct {
-		spinlock_t lock;
+		raw_spinlock_t lock;
 		u32 lock_owner;
 		int lock_owner_depth;
 	} die = {
-		.lock =			__SPIN_LOCK_UNLOCKED(die.lock),
+		.lock =			__RAW_SPIN_LOCK_UNLOCKED,
 		.lock_owner =		-1,
 		.lock_owner_depth =	0
 	};
@@ -389,13 +368,14 @@
 
 	if (die.lock_owner != raw_smp_processor_id()) {
 		console_verbose();
-		spin_lock_irqsave(&die.lock, flags);
+		__raw_spin_lock(&die.lock);
+		raw_local_save_flags(flags);
 		die.lock_owner = smp_processor_id();
 		die.lock_owner_depth = 0;
 		bust_spinlocks(1);
 	}
 	else
-		local_save_flags(flags);
+		raw_local_save_flags(flags);
 
 	if (++die.lock_owner_depth < 3) {
 		unsigned long esp;
@@ -439,7 +419,8 @@
 	bust_spinlocks(0);
 	die.lock_owner = -1;
 	add_taint(TAINT_DIE);
-	spin_unlock_irqrestore(&die.lock, flags);
+	__raw_spin_unlock(&die.lock);
+	raw_local_irq_restore(flags);
 
 	if (!regs)
 		return;
@@ -622,7 +603,7 @@
 	    printk_ratelimit())
 		printk(KERN_INFO
 		    "%s[%d] general protection eip:%lx esp:%lx error:%lx\n",
-		    current->comm, current->pid,
+		    current->comm, task_pid_nr(current),
 		    regs->eip, regs->esp, error_code);
 
 	force_sig(SIGSEGV, current);
@@ -1142,6 +1123,8 @@
 
 void __init trap_init(void)
 {
+	int i;
+
 #ifdef CONFIG_EISA
 	void __iomem *p = ioremap(0x0FFFD9, 4);
 	if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
@@ -1201,6 +1184,11 @@
 
 	set_system_gate(SYSCALL_VECTOR,&system_call);
 
+	/* Reserve all the builtin and the syscall vector. */
+	for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
+		set_bit(i, used_vectors);
+	set_bit(SYSCALL_VECTOR, used_vectors);
+
 	/*
 	 * Should be a barrier for any external CPU state.
 	 */
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index b4a9b3d..d0c2bc7 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -201,7 +201,7 @@
 #define MSG(txt) ops->warning(data, txt)
 
 /*
- * x86-64 can have upto three kernel stacks: 
+ * x86-64 can have up to three kernel stacks: 
  * process stack
  * interrupt stack
  * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
@@ -462,7 +462,7 @@
 EXPORT_SYMBOL(out_of_line_bug);
 #endif
 
-static DEFINE_SPINLOCK(die_lock);
+static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
 static int die_owner = -1;
 static unsigned int die_nest_count;
 
@@ -474,13 +474,13 @@
 	oops_enter();
 
 	/* racy, but better than risking deadlock. */
-	local_irq_save(flags);
+	raw_local_irq_save(flags);
 	cpu = smp_processor_id();
-	if (!spin_trylock(&die_lock)) { 
+	if (!__raw_spin_trylock(&die_lock)) {
 		if (cpu == die_owner) 
 			/* nested oops. should stop eventually */;
 		else
-			spin_lock(&die_lock);
+			__raw_spin_lock(&die_lock);
 	}
 	die_nest_count++;
 	die_owner = cpu;
@@ -494,12 +494,10 @@
 	die_owner = -1;
 	bust_spinlocks(0);
 	die_nest_count--;
-	if (die_nest_count)
-		/* We still own the lock */
-		local_irq_restore(flags);
-	else
+	if (!die_nest_count)
 		/* Nest count reaches zero, release the lock. */
-		spin_unlock_irqrestore(&die_lock, flags);
+		__raw_spin_unlock(&die_lock);
+	raw_local_irq_restore(flags);
 	if (panic_on_oops)
 		panic("Fatal exception");
 	oops_exit();
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c
index e87a393..d78444c 100644
--- a/arch/x86/kernel/tsc_32.c
+++ b/arch/x86/kernel/tsc_32.c
@@ -59,7 +59,7 @@
 }
 EXPORT_SYMBOL_GPL(check_tsc_unstable);
 
-/* Accellerators for sched_clock()
+/* Accelerators for sched_clock()
  * convert from cycles(64bits) => nanoseconds (64bits)
  *  basic equation:
  *		ns = cycles / (freq / ns_per_sec)
@@ -74,7 +74,7 @@
  *	And since SC is a constant power of two, we can convert the div
  *  into a shift.
  *
- *  We can use khz divisor instead of mhz to keep a better percision, since
+ *  We can use khz divisor instead of mhz to keep a better precision, since
  *  cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
  *  (mathieu.desnoyers@polymtl.ca)
  *
@@ -181,8 +181,8 @@
 	if (cpu_has_tsc) {
 		cpu_khz = calculate_cpu_khz();
 		tsc_khz = cpu_khz;
-		cpu_data[0].loops_per_jiffy =
-			cpufreq_scale(cpu_data[0].loops_per_jiffy,
+		cpu_data(0).loops_per_jiffy =
+			cpufreq_scale(cpu_data(0).loops_per_jiffy,
 					cpu_khz_old, cpu_khz);
 		return 0;
 	} else
@@ -215,7 +215,7 @@
 			return 0;
 		}
 		ref_freq = freq->old;
-		loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy;
+		loops_per_jiffy_ref = cpu_data(freq->cpu).loops_per_jiffy;
 		cpu_khz_ref = cpu_khz;
 	}
 
@@ -223,7 +223,7 @@
 	    (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
 	    (val == CPUFREQ_RESUMECHANGE)) {
 		if (!(freq->flags & CPUFREQ_CONST_LOOPS))
-			cpu_data[freq->cpu].loops_per_jiffy =
+			cpu_data(freq->cpu).loops_per_jiffy =
 				cpufreq_scale(loops_per_jiffy_ref,
 						ref_freq, freq->new);
 
diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c
index 9f22e54..9c70af4 100644
--- a/arch/x86/kernel/tsc_64.c
+++ b/arch/x86/kernel/tsc_64.c
@@ -73,13 +73,13 @@
 	struct cpufreq_freqs *freq = data;
 	unsigned long *lpj, dummy;
 
-	if (cpu_has(&cpu_data[freq->cpu], X86_FEATURE_CONSTANT_TSC))
+	if (cpu_has(&cpu_data(freq->cpu), X86_FEATURE_CONSTANT_TSC))
 		return 0;
 
 	lpj = &dummy;
 	if (!(freq->flags & CPUFREQ_CONST_LOOPS))
 #ifdef CONFIG_SMP
-		lpj = &cpu_data[freq->cpu].loops_per_jiffy;
+		lpj = &cpu_data(freq->cpu).loops_per_jiffy;
 #else
 		lpj = &boot_cpu_data.loops_per_jiffy;
 #endif
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 8a67e282..ad4005c 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -48,12 +48,12 @@
 	({unsigned long v;  		\
 	extern char __vsyscall_0; 	\
 	  asm("" : "=r" (v) : "0" (x)); \
-	  ((v - VSYSCALL_FIRST_PAGE) + __pa_symbol(&__vsyscall_0)); })
+	  ((v - VSYSCALL_START) + __pa_symbol(&__vsyscall_0)); })
 
 /*
  * vsyscall_gtod_data contains data that is :
  * - readonly from vsyscalls
- * - writen by timer interrupt or systcl (/proc/sys/kernel/vsyscall64)
+ * - written by timer interrupt or systcl (/proc/sys/kernel/vsyscall64)
  * Try to keep this structure as small as possible to avoid cache line ping pongs
  */
 int __vgetcpu_mode __section_vgetcpu_mode;
@@ -64,6 +64,16 @@
 	.sysctl_enabled = 1,
 };
 
+void update_vsyscall_tz(void)
+{
+	unsigned long flags;
+
+	write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags);
+	/* sys_tz has changed */
+	vsyscall_gtod_data.sys_tz = sys_tz;
+	write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
+}
+
 void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
 {
 	unsigned long flags;
@@ -77,7 +87,6 @@
 	vsyscall_gtod_data.clock.shift = clock->shift;
 	vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
 	vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
-	vsyscall_gtod_data.sys_tz = sys_tz;
 	vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic;
 	write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 }
@@ -163,7 +172,7 @@
 	if (unlikely(!__vsyscall_gtod_data.sysctl_enabled))
 		return time_syscall(t);
 
-	vgettimeofday(&tv, 0);
+	vgettimeofday(&tv, NULL);
 	result = tv.tv_sec;
 	if (t)
 		*t = result;
@@ -257,18 +266,10 @@
 	return ret;
 }
 
-static int vsyscall_sysctl_nostrat(ctl_table *t, int __user *name, int nlen,
-				void __user *oldval, size_t __user *oldlenp,
-				void __user *newval, size_t newlen)
-{
-	return -ENOSYS;
-}
-
 static ctl_table kernel_table2[] = {
-	{ .ctl_name = 99, .procname = "vsyscall64",
+	{ .procname = "vsyscall64",
 	  .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
 	  .mode = 0644,
-	  .strategy = vsyscall_sysctl_nostrat,
 	  .proc_handler = vsyscall_sysctl_change },
 	{}
 };
@@ -290,7 +291,7 @@
 #ifdef CONFIG_NUMA
 	node = cpu_to_node(cpu);
 #endif
-	if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP))
+	if (cpu_has(&cpu_data(cpu), X86_FEATURE_RDTSCP))
 		write_rdtscp_aux((node << 12) | cpu);
 
 	/* Store cpu number in limit so that it can be loaded quickly
diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig
new file mode 100644
index 0000000..c4dffbe
--- /dev/null
+++ b/arch/x86/lguest/Kconfig
@@ -0,0 +1,14 @@
+config LGUEST_GUEST
+	bool "Lguest guest support"
+	select PARAVIRT
+	depends on !X86_PAE
+	select VIRTIO
+	select VIRTIO_RING
+	select VIRTIO_CONSOLE
+	help
+	  Lguest is a tiny in-kernel hypervisor.  Selecting this will
+	  allow your kernel to boot under lguest.  This option will increase
+	  your kernel size by about 6k.  If in doubt, say N.
+
+	  If you say Y here, make sure you say Y (or M) to the virtio block
+	  and net drivers which lguest needs.
diff --git a/arch/x86/lguest/Makefile b/arch/x86/lguest/Makefile
new file mode 100644
index 0000000..27f0c9e
--- /dev/null
+++ b/arch/x86/lguest/Makefile
@@ -0,0 +1 @@
+obj-y		:= i386_head.o boot.o
diff --git a/drivers/lguest/lguest.c b/arch/x86/lguest/boot.c
similarity index 93%
rename from drivers/lguest/lguest.c
rename to arch/x86/lguest/boot.c
index 3ba337d..d2235db 100644
--- a/drivers/lguest/lguest.c
+++ b/arch/x86/lguest/boot.c
@@ -55,7 +55,7 @@
 #include <linux/clockchips.h>
 #include <linux/lguest.h>
 #include <linux/lguest_launcher.h>
-#include <linux/lguest_bus.h>
+#include <linux/virtio_console.h>
 #include <asm/paravirt.h>
 #include <asm/param.h>
 #include <asm/page.h>
@@ -65,6 +65,7 @@
 #include <asm/e820.h>
 #include <asm/mce.h>
 #include <asm/io.h>
+#include <asm/i387.h>
 
 /*G:010 Welcome to the Guest!
  *
@@ -85,9 +86,10 @@
 	.hcall_status = { [0 ... LHCALL_RING_SIZE-1] = 0xFF },
 	.noirq_start = (u32)lguest_noirq_start,
 	.noirq_end = (u32)lguest_noirq_end,
+	.kernel_address = PAGE_OFFSET,
 	.blocked_interrupts = { 1 }, /* Block timer interrupts */
+	.syscall_vec = SYSCALL_VECTOR,
 };
-struct lguest_device_desc *lguest_devices;
 static cycle_t clock_base;
 
 /*G:035 Notice the lazy_hcall() above, rather than hcall().  This is our first
@@ -146,10 +148,10 @@
 		/* Table full, so do normal hcall which will flush table. */
 		hcall(call, arg1, arg2, arg3);
 	} else {
-		lguest_data.hcalls[next_call].eax = call;
-		lguest_data.hcalls[next_call].edx = arg1;
-		lguest_data.hcalls[next_call].ebx = arg2;
-		lguest_data.hcalls[next_call].ecx = arg3;
+		lguest_data.hcalls[next_call].arg0 = call;
+		lguest_data.hcalls[next_call].arg1 = arg1;
+		lguest_data.hcalls[next_call].arg2 = arg2;
+		lguest_data.hcalls[next_call].arg3 = arg3;
 		/* Arguments must all be written before we mark it to go */
 		wmb();
 		lguest_data.hcall_status[next_call] = 0;
@@ -160,46 +162,6 @@
 }
 /*:*/
 
-/* Wrappers for the SEND_DMA and BIND_DMA hypercalls.  This is mainly because
- * Jeff Garzik complained that __pa() should never appear in drivers, and this
- * helps remove most of them.   But also, it wraps some ugliness. */
-void lguest_send_dma(unsigned long key, struct lguest_dma *dma)
-{
-	/* The hcall might not write this if something goes wrong */
-	dma->used_len = 0;
-	hcall(LHCALL_SEND_DMA, key, __pa(dma), 0);
-}
-
-int lguest_bind_dma(unsigned long key, struct lguest_dma *dmas,
-		    unsigned int num, u8 irq)
-{
-	/* This is the only hypercall which actually wants 5 arguments, and we
-	 * only support 4.  Fortunately the interrupt number is always less
-	 * than 256, so we can pack it with the number of dmas in the final
-	 * argument.  */
-	if (!hcall(LHCALL_BIND_DMA, key, __pa(dmas), (num << 8) | irq))
-		return -ENOMEM;
-	return 0;
-}
-
-/* Unbinding is the same hypercall as binding, but with 0 num & irq. */
-void lguest_unbind_dma(unsigned long key, struct lguest_dma *dmas)
-{
-	hcall(LHCALL_BIND_DMA, key, __pa(dmas), 0);
-}
-
-/* For guests, device memory can be used as normal memory, so we cast away the
- * __iomem to quieten sparse. */
-void *lguest_map(unsigned long phys_addr, unsigned long pages)
-{
-	return (__force void *)ioremap(phys_addr, PAGE_SIZE*pages);
-}
-
-void lguest_unmap(void *addr)
-{
-	iounmap((__force void __iomem *)addr);
-}
-
 /*G:033
  * Here are our first native-instruction replacements: four functions for
  * interrupt control.
@@ -680,6 +642,7 @@
 	.mask		= CLOCKSOURCE_MASK(64),
 	.mult		= 1 << 22,
 	.shift		= 22,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
 /* The "scheduler clock" is just our real clock, adjusted to start at zero */
@@ -761,11 +724,9 @@
 	 * the TSC, otherwise it's a dumb nanosecond-resolution clock.  Either
 	 * way, the "rating" is initialized so high that it's always chosen
 	 * over any other clocksource. */
-	if (lguest_data.tsc_khz) {
+	if (lguest_data.tsc_khz)
 		lguest_clock.mult = clocksource_khz2mult(lguest_data.tsc_khz,
 							 lguest_clock.shift);
-		lguest_clock.flags = CLOCK_SOURCE_IS_CONTINUOUS;
-	}
 	clock_base = lguest_clock_read();
 	clocksource_register(&lguest_clock);
 
@@ -889,6 +850,23 @@
 	return "LGUEST";
 }
 
+/* Before virtqueues are set up, we use LHCALL_NOTIFY on normal memory to
+ * produce console output. */
+static __init int early_put_chars(u32 vtermno, const char *buf, int count)
+{
+	char scratch[17];
+	unsigned int len = count;
+
+	if (len > sizeof(scratch) - 1)
+		len = sizeof(scratch) - 1;
+	scratch[len] = '\0';
+	memcpy(scratch, buf, len);
+	hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0);
+
+	/* This routine returns the number of bytes actually written. */
+	return len;
+}
+
 /*G:050
  * Patching (Powerfully Placating Performance Pedants)
  *
@@ -950,18 +928,8 @@
 /*G:030 Once we get to lguest_init(), we know we're a Guest.  The pv_ops
  * structures in the kernel provide points for (almost) every routine we have
  * to override to avoid privileged instructions. */
-__init void lguest_init(void *boot)
+__init void lguest_init(void)
 {
-	/* Copy boot parameters first: the Launcher put the physical location
-	 * in %esi, and head.S converted that to a virtual address and handed
-	 * it to us.  We use "__memcpy" because "memcpy" sometimes tries to do
-	 * tricky things to go faster, and we're not ready for that. */
-	__memcpy(&boot_params, boot, PARAM_SIZE);
-	/* The boot parameters also tell us where the command-line is: save
-	 * that, too. */
-	__memcpy(boot_command_line, __va(boot_params.hdr.cmd_line_ptr),
-	       COMMAND_LINE_SIZE);
-
 	/* We're under lguest, paravirt is enabled, and we're running at
 	 * privilege level 1, not 0 as normal. */
 	pv_info.name = "lguest";
@@ -1033,11 +1001,7 @@
 
 	/*G:070 Now we've seen all the paravirt_ops, we return to
 	 * lguest_init() where the rest of the fairly chaotic boot setup
-	 * occurs.
-	 *
-	 * The Host expects our first hypercall to tell it where our "struct
-	 * lguest_data" is, so we do that first. */
-	hcall(LHCALL_LGUEST_INIT, __pa(&lguest_data), 0, 0);
+	 * occurs. */
 
 	/* The native boot code sets up initial page tables immediately after
 	 * the kernel itself, and sets init_pg_tables_end so they're not
@@ -1050,11 +1014,6 @@
 	 * the normal data segment to get through booting. */
 	asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory");
 
-	/* Clear the part of the kernel data which is expected to be zero.
-	 * Normally it will be anyway, but if we're loading from a bzImage with
-	 * CONFIG_RELOCATALE=y, the relocations will be sitting here. */
-	memset(__bss_start, 0, __bss_stop - __bss_start);
-
 	/* The Host uses the top of the Guest's virtual address space for the
 	 * Host<->Guest Switcher, and it tells us how much it needs in
 	 * lguest_data.reserve_mem, set up on the LGUEST_INIT hypercall. */
@@ -1092,6 +1051,9 @@
 	 * adapted for lguest's use. */
 	add_preferred_console("hvc", 0, NULL);
 
+	/* Register our very early console. */
+	virtio_cons_early_init(early_put_chars);
+
 	/* Last of all, we set the power management poweroff hook to point to
 	 * the Guest routine to power off. */
 	pm_power_off = lguest_power_off;
diff --git a/drivers/lguest/lguest_asm.S b/arch/x86/lguest/i386_head.S
similarity index 72%
rename from drivers/lguest/lguest_asm.S
rename to arch/x86/lguest/i386_head.S
index 1ddcd5c..ebc6ac7 100644
--- a/drivers/lguest/lguest_asm.S
+++ b/arch/x86/lguest/i386_head.S
@@ -1,25 +1,47 @@
 #include <linux/linkage.h>
 #include <linux/lguest.h>
+#include <asm/lguest_hcall.h>
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
 #include <asm/processor-flags.h>
 
-/*G:020 This is where we begin: we have a magic signature which the launcher
- * looks for.  The plan is that the Linux boot protocol will be extended with a
- * "platform type" field which will guide us here from the normal entry point,
- * but for the moment this suffices.  The normal boot code uses %esi for the
- * boot header, so we do too.  We convert it to a virtual address by adding
- * PAGE_OFFSET, and hand it to lguest_init() as its argument (ie. %eax).
+/*G:020 This is where we begin: head.S notes that the boot header's platform
+ * type field is "1" (lguest), so calls us here.  The boot header is in %esi.
+ *
+ * WARNING: be very careful here!  We're running at addresses equal to physical
+ * addesses (around 0), not above PAGE_OFFSET as most code expectes
+ * (eg. 0xC0000000).  Jumps are relative, so they're OK, but we can't touch any
+ * data.
  *
  * The .section line puts this code in .init.text so it will be discarded after
  * boot. */
 .section .init.text, "ax", @progbits
-.ascii "GenuineLguest"
-	/* Set up initial stack. */
- 	movl $(init_thread_union+THREAD_SIZE),%esp
-	movl %esi, %eax
-	addl $__PAGE_OFFSET, %eax
-	jmp lguest_init
+ENTRY(lguest_entry)
+	/* Make initial hypercall now, so we can set up the pagetables. */
+	movl $LHCALL_LGUEST_INIT, %eax
+	movl $lguest_data - __PAGE_OFFSET, %edx
+	int $LGUEST_TRAP_ENTRY
+
+	/* The Host put the toplevel pagetable in lguest_data.pgdir.  The movsl
+	 * instruction uses %esi implicitly. */
+	movl lguest_data - __PAGE_OFFSET + LGUEST_DATA_pgdir, %esi
+
+	/* Copy first 32 entries of page directory to __PAGE_OFFSET entries.
+	 * This means the first 128M of kernel memory will be mapped at
+	 * PAGE_OFFSET where the kernel expects to run.  This will get it far
+	 * enough through boot to switch to its own pagetables. */
+	movl $32, %ecx
+	movl %esi, %edi
+	addl $((__PAGE_OFFSET >> 22) * 4), %edi
+	rep
+	movsl
+
+	/* Set up the initial stack so we can run C code. */
+	movl $(init_thread_union+THREAD_SIZE),%esp
+
+	/* Jumps are relative, and we're running __PAGE_OFFSET too low at the
+	 * moment. */
+	jmp lguest_init+__PAGE_OFFSET
 
 /*G:055 We create a macro which puts the assembler code between lgstart_ and
  * lgend_ markers.  These templates are put in the .text section: they can't be
diff --git a/arch/x86/lib/delay_32.c b/arch/x86/lib/delay_32.c
index f6edb11..952e7a8 100644
--- a/arch/x86/lib/delay_32.c
+++ b/arch/x86/lib/delay_32.c
@@ -82,7 +82,7 @@
 	__asm__("mull %0"
 		:"=d" (xloops), "=&a" (d0)
 		:"1" (xloops), "0"
-		(cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4)));
+		(cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4)));
 
 	__delay(++xloops);
 }
diff --git a/arch/x86/lib/delay_64.c b/arch/x86/lib/delay_64.c
index 2dbebd3..0ebbfb9 100644
--- a/arch/x86/lib/delay_64.c
+++ b/arch/x86/lib/delay_64.c
@@ -40,7 +40,8 @@
 
 inline void __const_udelay(unsigned long xloops)
 {
-	__delay(((xloops * HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32) + 1);
+	__delay(((xloops * HZ *
+		cpu_data(raw_smp_processor_id()).loops_per_jiffy) >> 32) + 1);
 }
 EXPORT_SYMBOL(__const_udelay);
 
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
index 9f38b12..8bab2b2 100644
--- a/arch/x86/lib/usercopy_32.c
+++ b/arch/x86/lib/usercopy_32.c
@@ -748,7 +748,7 @@
 			retval = get_user_pages(current, current->mm,
 					(unsigned long )to, 1, 1, 0, &pg, NULL);
 
-			if (retval == -ENOMEM && is_init(current)) {
+			if (retval == -ENOMEM && is_global_init(current)) {
 				up_read(&current->mm->mmap_sem);
 				congestion_wait(WRITE, HZ/50);
 				goto survive;
diff --git a/arch/x86/mach-default/setup.c b/arch/x86/mach-default/setup.c
index 3f08010..0c28a07 100644
--- a/arch/x86/mach-default/setup.c
+++ b/arch/x86/mach-default/setup.c
@@ -108,7 +108,7 @@
  * mca_nmi_hook - hook into MCA specific NMI chain
  *
  * Description:
- *	The MCA (Microchannel Arcitecture) has an NMI chain for NMI sources
+ *	The MCA (Microchannel Architecture) has an NMI chain for NMI sources
  *	along the MCA bus.  Use this to hook into that chain if you will need
  *	it.
  **/
@@ -131,7 +131,7 @@
 	return 1;
 }
 
-__setup("no_ipi_broadcast", no_ipi_broadcast);
+__setup("no_ipi_broadcast=", no_ipi_broadcast);
 
 static int __init print_ipi_mode(void)
 {
diff --git a/arch/x86/mach-generic/default.c b/arch/x86/mach-generic/default.c
index 8685208..1af0cc7 100644
--- a/arch/x86/mach-generic/default.c
+++ b/arch/x86/mach-generic/default.c
@@ -1,5 +1,5 @@
 /* 
- * Default generic APIC driver. This handles upto 8 CPUs.
+ * Default generic APIC driver. This handles up to 8 CPUs.
  */
 #define APIC_DEFINITION 1
 #include <linux/threads.h>
diff --git a/arch/x86/mach-generic/probe.c b/arch/x86/mach-generic/probe.c
index 4121d15..f410d3c 100644
--- a/arch/x86/mach-generic/probe.c
+++ b/arch/x86/mach-generic/probe.c
@@ -56,7 +56,7 @@
 	/*
 	 * This routine is used to switch to bigsmp mode when
 	 * - There is no apic= option specified by the user
-	 * - generic_apic_probe() has choosen apic_default as the sub_arch
+	 * - generic_apic_probe() has chosen apic_default as the sub_arch
 	 * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
 	 */
 
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c
index e4928aa..361ac51 100644
--- a/arch/x86/mach-voyager/voyager_smp.c
+++ b/arch/x86/mach-voyager/voyager_smp.c
@@ -36,8 +36,8 @@
 
 /* per CPU data structure (for /proc/cpuinfo et al), visible externally
  * indexed physically */
-struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_data);
+DEFINE_PER_CPU(cpuinfo_x86, cpu_info) __cacheline_aligned;
+EXPORT_PER_CPU_SYMBOL(cpu_info);
 
 /* physical ID of the CPU used to boot the system */
 unsigned char boot_cpu_id;
@@ -389,7 +389,7 @@
 
 	/* The boot CPU must be extended */
 	voyager_extended_vic_processors = 1<<boot_cpu_id;
-	/* initially, all of the first 8 cpu's can boot */
+	/* initially, all of the first 8 CPUs can boot */
 	voyager_allowed_boot_processors = 0xff;
 	/* set up everything for just this CPU, we can alter
 	 * this as we start the other CPUs later */
@@ -430,7 +430,7 @@
 void __init
 smp_store_cpu_info(int id)
 {
-	struct cpuinfo_x86 *c=&cpu_data[id];
+	struct cpuinfo_x86 *c = &cpu_data(id);
 
 	*c = boot_cpu_data;
 
@@ -634,7 +634,7 @@
 			cpu, smp_processor_id()));
 	
 		printk("CPU%d: ", cpu);
-		print_cpu_info(&cpu_data[cpu]);
+		print_cpu_info(&cpu_data(cpu));
 		wmb();
 		cpu_set(cpu, cpu_callout_map);
 		cpu_set(cpu, cpu_present_map);
@@ -683,7 +683,7 @@
 	 */
 	smp_store_cpu_info(boot_cpu_id);
 	printk("CPU%d: ", boot_cpu_id);
-	print_cpu_info(&cpu_data[boot_cpu_id]);
+	print_cpu_info(&cpu_data(boot_cpu_id));
 
 	if(is_cpu_quad()) {
 		/* booting on a Quad CPU */
@@ -714,7 +714,7 @@
 		unsigned long bogosum = 0;
 		for (i = 0; i < NR_CPUS; i++)
 			if (cpu_isset(i, cpu_online_map))
-				bogosum += cpu_data[i].loops_per_jiffy;
+				bogosum += cpu_data(i).loops_per_jiffy;
 		printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
 			cpucount+1,
 			bogosum/(500000/HZ),
@@ -1010,7 +1010,7 @@
 
 /* execute a thread on a new CPU.  The function to be called must be
  * previously set up.  This is used to schedule a function for
- * execution on all CPU's - set up the function then broadcast a
+ * execution on all CPUs - set up the function then broadcast a
  * function_interrupt CPI to come here on each CPU */
 static void
 smp_call_function_interrupt(void)
@@ -1095,7 +1095,7 @@
  * CPI here.  We don't use this actually for counting so losing
  * ticks doesn't matter 
  *
- * FIXME: For those CPU's which actually have a local APIC, we could
+ * FIXME: For those CPUs which actually have a local APIC, we could
  * try to use it to trigger this interrupt instead of having to
  * broadcast the timer tick.  Unfortunately, all my pentium DYADs have
  * no local APIC, so I can't do this
@@ -1287,7 +1287,7 @@
 
 	/*
 	 * We take the 'long' return path, and there every subsystem
-	 * grabs the apropriate locks (kernel lock/ irq lock).
+	 * grabs the appropriate locks (kernel lock/ irq lock).
 	 *
 	 * we might want to decouple profiling from the 'long path',
 	 * and do the profiling totally in assembly.
@@ -1759,7 +1759,7 @@
 	real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors;
 	
 	if(cpus_addr(mask)[0] == 0)
-		/* can't have no cpu's to accept the interrupt -- extremely
+		/* can't have no CPUs to accept the interrupt -- extremely
 		 * bad things will happen */
 		return;
 
@@ -1791,7 +1791,7 @@
 	}
 	/* this is magic, we now have the correct affinity maps, so
 	 * enable the interrupt.  This will send an enable CPI to
-	 * those cpu's who need to enable it in their local masks,
+	 * those CPUs who need to enable it in their local masks,
 	 * causing them to correct for the new affinity . If the
 	 * interrupt is currently globally disabled, it will simply be
 	 * disabled again as it comes in (voyager lazy disable).  If
diff --git a/arch/x86/mach-voyager/voyager_thread.c b/arch/x86/mach-voyager/voyager_thread.c
index f9d5953..50f9366 100644
--- a/arch/x86/mach-voyager/voyager_thread.c
+++ b/arch/x86/mach-voyager/voyager_thread.c
@@ -64,7 +64,7 @@
 {
 	if(voyager_status.switch_off) {
 		
-		/* FIXME: This should be configureable via proc */
+		/* FIXME: This should be configurable via proc */
 		execute("umask 600; echo 0 > /etc/initrunlvl; kill -HUP 1");
 	} else if(voyager_status.power_fail) {
 		VDEBUG(("Voyager daemon detected AC power failure\n"));
diff --git a/arch/x86/mm/boot_ioremap_32.c b/arch/x86/mm/boot_ioremap_32.c
index 4de95a1..f14da2a 100644
--- a/arch/x86/mm/boot_ioremap_32.c
+++ b/arch/x86/mm/boot_ioremap_32.c
@@ -10,7 +10,7 @@
 
 /*
  * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
- * keeps that from happenning.  If anyone has a better way, I'm listening.
+ * keeps that from happening.  If anyone has a better way, I'm listening.
  *
  * boot_pte_t is defined only if this all works correctly
  */
diff --git a/arch/x86/mm/discontig_32.c b/arch/x86/mm/discontig_32.c
index 1389377..fe608a4 100644
--- a/arch/x86/mm/discontig_32.c
+++ b/arch/x86/mm/discontig_32.c
@@ -273,7 +273,7 @@
 	 * When mapping a NUMA machine we allocate the node_mem_map arrays
 	 * from node local memory.  They are then mapped directly into KVA
 	 * between zone normal and vmalloc space.  Calculate the size of
-	 * this space and use it to adjust the boundry between ZONE_NORMAL
+	 * this space and use it to adjust the boundary between ZONE_NORMAL
 	 * and ZONE_HIGHMEM.
 	 */
 	find_max_pfn();
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c
index 6555c3d..503dfc0 100644
--- a/arch/x86/mm/fault_32.c
+++ b/arch/x86/mm/fault_32.c
@@ -354,7 +354,7 @@
 
 	/* When running in the kernel we expect faults to occur only to
 	 * addresses in user space.  All other faults represent errors in the
-	 * kernel and should generate an OOPS.  Unfortunatly, in the case of an
+	 * kernel and should generate an OOPS.  Unfortunately, in the case of an
 	 * erroneous fault occurring in a code path which already holds mmap_sem
 	 * we will deadlock attempting to validate the fault against the
 	 * address space.  Luckily the kernel only validly references user
@@ -362,7 +362,7 @@
 	 * exceptions table.
 	 *
 	 * As the vast majority of faults will be valid we will only perform
-	 * the source reference check when there is a possibilty of a deadlock.
+	 * the source reference check when there is a possibility of a deadlock.
 	 * Attempt to lock the address space, if we cannot we then validate the
 	 * source.  If this is invalid we can skip the address space check,
 	 * thus avoiding the deadlock.
@@ -471,8 +471,8 @@
 		    printk_ratelimit()) {
 			printk("%s%s[%d]: segfault at %08lx eip %08lx "
 			    "esp %08lx error %lx\n",
-			    tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
-			    tsk->comm, tsk->pid, address, regs->eip,
+			    task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
+			    tsk->comm, task_pid_nr(tsk), address, regs->eip,
 			    regs->esp, error_code);
 		}
 		tsk->thread.cr2 = address;
@@ -564,7 +564,8 @@
 		 * it's allocated already.
 		 */
 		if ((page >> PAGE_SHIFT) < max_low_pfn
-		    && (page & _PAGE_PRESENT)) {
+		    && (page & _PAGE_PRESENT)
+		    && !(page & _PAGE_PSE)) {
 			page &= PAGE_MASK;
 			page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
 			                                         & (PTRS_PER_PTE - 1)];
@@ -587,7 +588,7 @@
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (is_init(tsk)) {
+	if (is_global_init(tsk)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c
index 5e0e549..644b4f7 100644
--- a/arch/x86/mm/fault_64.c
+++ b/arch/x86/mm/fault_64.c
@@ -169,7 +169,7 @@
 	pmd = pmd_offset(pud, address);
 	if (bad_address(pmd)) goto bad;
 	printk("PMD %lx ", pmd_val(*pmd));
-	if (!pmd_present(*pmd))	goto ret;	 
+	if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret;
 
 	pte = pte_offset_kernel(pmd, address);
 	if (bad_address(pte)) goto bad;
@@ -285,7 +285,6 @@
 	return 0;
 }
 
-static int page_fault_trace;
 int show_unhandled_signals = 1;
 
 /*
@@ -354,10 +353,6 @@
 	if (likely(regs->eflags & X86_EFLAGS_IF))
 		local_irq_enable();
 
-	if (unlikely(page_fault_trace))
-		printk("pagefault rip:%lx rsp:%lx cs:%lu ss:%lu address %lx error %lx\n",
-		       regs->rip,regs->rsp,regs->cs,regs->ss,address,error_code); 
-
 	if (unlikely(error_code & PF_RSVD))
 		pgtable_bad(address, regs, error_code);
 
@@ -378,7 +373,7 @@
  again:
 	/* When running in the kernel we expect faults to occur only to
 	 * addresses in user space.  All other faults represent errors in the
-	 * kernel and should generate an OOPS.  Unfortunatly, in the case of an
+	 * kernel and should generate an OOPS.  Unfortunately, in the case of an
 	 * erroneous fault occurring in a code path which already holds mmap_sem
 	 * we will deadlock attempting to validate the fault against the
 	 * address space.  Luckily the kernel only validly references user
@@ -386,7 +381,7 @@
 	 * exceptions table.
 	 *
 	 * As the vast majority of faults will be valid we will only perform
-	 * the source reference check when there is a possibilty of a deadlock.
+	 * the source reference check when there is a possibility of a deadlock.
 	 * Attempt to lock the address space, if we cannot we then validate the
 	 * source.  If this is invalid we can skip the address space check,
 	 * thus avoiding the deadlock.
@@ -488,7 +483,7 @@
 		if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
 		    printk_ratelimit()) {
 			printk(
-		       "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
+		       "%s%s[%d]: segfault at %lx rip %lx rsp %lx error %lx\n",
 					tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
 					tsk->comm, tsk->pid, address, regs->rip,
 					regs->rsp, error_code);
@@ -554,7 +549,7 @@
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		yield();
 		goto again;
 	}
@@ -621,10 +616,3 @@
 	BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) == 
 				(__START_KERNEL & PGDIR_MASK)));
 }
-
-static int __init enable_pagefaulttrace(char *str)
-{
-	page_fault_trace = 1;
-	return 1;
-}
-__setup("pagefaulttrace", enable_pagefaulttrace);
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 5eec5e5..3d6926b 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -612,7 +612,7 @@
 {
 	int i;
  	for (i = 0; i < NR_CPUS; i++) {
-		u8 apicid = x86_cpu_to_apicid[i];
+		u8 apicid = x86_cpu_to_apicid_init[i];
 		if (apicid == BAD_APICID)
 			continue;
 		if (apicid_to_node[apicid] == NUMA_NO_NODE)
diff --git a/arch/x86/mm/pageattr_64.c b/arch/x86/mm/pageattr_64.c
index 8a4f65b..c40afba 100644
--- a/arch/x86/mm/pageattr_64.c
+++ b/arch/x86/mm/pageattr_64.c
@@ -61,10 +61,10 @@
 	return base;
 } 
 
-static void cache_flush_page(void *adr)
+void clflush_cache_range(void *adr, int size)
 {
 	int i;
-	for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
+	for (i = 0; i < size; i += boot_cpu_data.x86_clflush_size)
 		clflush(adr+i);
 }
 
@@ -80,7 +80,7 @@
 		asm volatile("wbinvd" ::: "memory");
 	else list_for_each_entry(pg, l, lru) {
 		void *adr = page_address(pg);
-		cache_flush_page(adr);
+		clflush_cache_range(adr, PAGE_SIZE);
 	}
 	__flush_tlb_all();
 }
@@ -230,9 +230,14 @@
 	struct page *pg, *next;
 	struct list_head l;
 
-	down_read(&init_mm.mmap_sem);
+	/*
+	 * Write-protect the semaphore, to exclude two contexts
+	 * doing a list_replace_init() call in parallel and to
+	 * exclude new additions to the deferred_pages list:
+	 */
+	down_write(&init_mm.mmap_sem);
 	list_replace_init(&deferred_pages, &l);
-	up_read(&init_mm.mmap_sem);
+	up_write(&init_mm.mmap_sem);
 
 	flush_map(&l);
 
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index 56089cc..ea85172 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -218,7 +218,7 @@
 /*
  * Update nodes_add and decide if to include add are in the zone.
  * Both SPARSE and RESERVE need nodes_add infomation.
- * This code supports one contigious hot add area per node.
+ * This code supports one contiguous hot add area per node.
  */
 static int reserve_hotadd(int node, unsigned long start, unsigned long end)
 {
diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c
index c049ce4..0ed046a 100644
--- a/arch/x86/oprofile/backtrace.c
+++ b/arch/x86/oprofile/backtrace.c
@@ -13,26 +13,46 @@
 #include <linux/mm.h>
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
+#include <asm/stacktrace.h>
+
+static void backtrace_warning_symbol(void *data, char *msg,
+				     unsigned long symbol)
+{
+	/* Ignore warnings */
+}
+
+static void backtrace_warning(void *data, char *msg)
+{
+	/* Ignore warnings */
+}
+
+static int backtrace_stack(void *data, char *name)
+{
+	/* Yes, we want all stacks */
+	return 0;
+}
+
+static void backtrace_address(void *data, unsigned long addr)
+{
+	unsigned int *depth = data;
+
+	if ((*depth)--)
+		oprofile_add_trace(addr);
+}
+
+static struct stacktrace_ops backtrace_ops = {
+	.warning = backtrace_warning,
+	.warning_symbol = backtrace_warning_symbol,
+	.stack = backtrace_stack,
+	.address = backtrace_address,
+};
 
 struct frame_head {
-	struct frame_head * ebp;
+	struct frame_head *ebp;
 	unsigned long ret;
 } __attribute__((packed));
 
 static struct frame_head *
-dump_kernel_backtrace(struct frame_head * head)
-{
-	oprofile_add_trace(head->ret);
-
-	/* frame pointers should strictly progress back up the stack
-	 * (towards higher addresses) */
-	if (head >= head->ebp)
-		return NULL;
-
-	return head->ebp;
-}
-
-static struct frame_head *
 dump_user_backtrace(struct frame_head * head)
 {
 	struct frame_head bufhead[2];
@@ -53,72 +73,16 @@
 	return bufhead[0].ebp;
 }
 
-/*
- * |             | /\ Higher addresses
- * |             |
- * --------------- stack base (address of current_thread_info)
- * | thread info |
- * .             .
- * |    stack    |
- * --------------- saved regs->ebp value if valid (frame_head address)
- * .             .
- * --------------- saved regs->rsp value if x86_64
- * |             |
- * --------------- struct pt_regs * stored on stack if 32-bit
- * |             |
- * .             .
- * |             |
- * --------------- %esp
- * |             |
- * |             | \/ Lower addresses
- *
- * Thus, regs (or regs->rsp for x86_64) <-> stack base restricts the
- * valid(ish) ebp values. Note: (1) for x86_64, NMI and several other
- * exceptions use special stacks, maintained by the interrupt stack table
- * (IST). These stacks are set up in trap_init() in
- * arch/x86_64/kernel/traps.c. Thus, for x86_64, regs now does not point
- * to the kernel stack; instead, it points to some location on the NMI
- * stack. On the other hand, regs->rsp is the stack pointer saved when the
- * NMI occurred. (2) For 32-bit, regs->esp is not valid because the
- * processor does not save %esp on the kernel stack when interrupts occur
- * in the kernel mode.
- */
-#ifdef CONFIG_FRAME_POINTER
-static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs)
-{
-	unsigned long headaddr = (unsigned long)head;
-#ifdef CONFIG_X86_64
-	unsigned long stack = (unsigned long)regs->rsp;
-#else
-	unsigned long stack = (unsigned long)regs;
-#endif
-	unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
-
-	return headaddr > stack && headaddr < stack_base;
-}
-#else
-/* without fp, it's just junk */
-static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs)
-{
-	return 0;
-}
-#endif
-
-
 void
 x86_backtrace(struct pt_regs * const regs, unsigned int depth)
 {
-	struct frame_head *head;
-
-#ifdef CONFIG_X86_64
-	head = (struct frame_head *)regs->rbp;
-#else
-	head = (struct frame_head *)regs->ebp;
-#endif
+	struct frame_head *head = (struct frame_head *)frame_pointer(regs);
+	unsigned long stack = stack_pointer(regs);
 
 	if (!user_mode_vm(regs)) {
-		while (depth-- && valid_kernel_stack(head, regs))
-			head = dump_kernel_backtrace(head);
+		if (depth)
+			dump_trace(NULL, regs, (unsigned long *)stack,
+				   &backtrace_ops, &depth);
 		return;
 	}
 
diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h
index abb1aa9..45b605f 100644
--- a/arch/x86/oprofile/op_x86_model.h
+++ b/arch/x86/oprofile/op_x86_model.h
@@ -29,7 +29,7 @@
 struct pt_regs;
 
 /* The model vtable abstracts the differences between
- * various x86 CPU model's perfctr support.
+ * various x86 CPU models' perfctr support.
  */
 struct op_x86_model_spec {
 	unsigned int const num_counters;
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index c52150f..88d8f5c 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -169,7 +169,7 @@
 }
 
 /*
- * Common IRQ routing practice: nybbles in config space,
+ * Common IRQ routing practice: nibbles in config space,
  * offset by some magic constant.
  */
 static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr)
@@ -585,7 +585,7 @@
 	/* FIXME: We should move some of the quirk fixup stuff here */
 
 	/*
-	 * work arounds for some buggy BIOSes
+	 * workarounds for some buggy BIOSes
 	 */
 	if (device == PCI_DEVICE_ID_VIA_82C586_0) {
 		switch(router->device) {
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index 9df99e1..fbfa55c 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -3,8 +3,9 @@
 #
 
 config XEN
-	bool "Enable support for Xen hypervisor"
-	depends on PARAVIRT && X86_CMPXCHG && X86_TSC && !NEED_MULTIPLE_NODES
+	bool "Xen guest support"
+	select PARAVIRT
+	depends on X86_CMPXCHG && X86_TSC && !NEED_MULTIPLE_NODES && !(X86_VISWS || X86_VOYAGER)
 	help
 	  This is the Linux Xen port.  Enabling this will allow the
 	  kernel to boot in a paravirtualized environment under the
diff --git a/arch/x86_64/.gitignore b/arch/x86_64/.gitignore
new file mode 100644
index 0000000..36ef4c3
--- /dev/null
+++ b/arch/x86_64/.gitignore
@@ -0,0 +1 @@
+boot
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 43fafe9..c2d2499 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -716,9 +716,16 @@
 
 source kernel/power/Kconfig
 
+config ARCH_HIBERNATION_HEADER
+	bool
+	depends on HIBERNATION
+	default y
+
 source "drivers/acpi/Kconfig"
 
-source "arch/x86/kernel/cpufreq/Kconfig"
+source "arch/x86/kernel/cpu/cpufreq/Kconfig_64"
+
+source "drivers/cpuidle/Kconfig"
 
 endmenu
 
@@ -743,6 +750,38 @@
 	depends on PCI
 	default y
 
+config DMAR
+	bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
+	depends on PCI_MSI && ACPI && EXPERIMENTAL
+	default y
+	help
+	  DMA remapping (DMAR) devices support enables independent address
+	  translations for Direct Memory Access (DMA) from devices.
+	  These DMA remapping devices are reported via ACPI tables
+	  and include PCI device scope covered by these DMA
+	  remapping devices.
+
+config DMAR_GFX_WA
+	bool "Support for Graphics workaround"
+	depends on DMAR
+	default y
+	help
+	 Current Graphics drivers tend to use physical address
+	 for DMA and avoid using DMA APIs. Setting this config
+	 option permits the IOMMU driver to set a unity map for
+	 all the OS-visible memory. Hence the driver can continue
+	 to use physical addresses for DMA.
+
+config DMAR_FLOPPY_WA
+	bool
+	depends on DMAR
+	default y
+	help
+	 Floppy disk drivers are know to bypass DMA API calls
+	 thereby failing to work when IOMMU is enabled. This
+	 workaround will setup a 1:1 mapping for the first
+	 16M to make floppy (an ISA device) work.
+
 source "drivers/pci/pcie/Kconfig"
 
 source "drivers/pci/Kconfig"
@@ -761,9 +800,9 @@
 config IA32_EMULATION
 	bool "IA32 Emulation"
 	help
-	  Include code to run 32-bit programs under a 64-bit kernel. You should likely
-	  turn this on, unless you're 100% sure that you don't have any 32-bit programs
-	  left.
+	  Include code to run 32-bit programs under a 64-bit kernel. You should
+	  likely turn this on, unless you're 100% sure that you don't have any
+	  32-bit programs left.
 
 config IA32_AOUT
        tristate "IA32 a.out support"
@@ -794,21 +833,6 @@
 
 source fs/Kconfig
 
-menu "Instrumentation Support"
-
-source "arch/x86/oprofile/Kconfig"
-
-config KPROBES
-	bool "Kprobes"
-	depends on KALLSYMS && MODULES
-	help
-	  Kprobes allows you to trap at almost any kernel address and
-	  execute a callback function.  register_kprobe() establishes
-	  a probepoint and specifies the callback.  Kprobes is useful
-	  for kernel debugging, non-intrusive instrumentation and testing.
-	  If in doubt, say "N".
-endmenu
-
 source "arch/x86_64/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 03e1ede..6d89ab7 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -74,7 +74,7 @@
 CFLAGS_KERNEL += $(cflags-kernel-y)
 KBUILD_AFLAGS += -m64
 
-head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task_64.o
+head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task.o
 
 libs-y 					+= arch/x86/lib/
 core-y					+= arch/x86/kernel/ \
@@ -97,9 +97,9 @@
 KBUILD_IMAGE                  := $(BOOTIMAGE)
 
 bzImage: vmlinux
-	$(Q)mkdir -p $(objtree)/arch/x86_64/boot
-	$(Q)ln -fsn $(objtree)/arch/x86/boot/bzImage $(objtree)/arch/x86_64/boot/bzImage
 	$(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE)
+	$(Q)mkdir -p $(objtree)/arch/x86_64/boot
+	$(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/x86_64/boot/bzImage
 
 bzlilo: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zlilo
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 7fbb44b..85ffbb4 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -251,6 +251,8 @@
 	  provide one yourself.
 endmenu
 
+source "kernel/Kconfig.instrumentation"
+
 source "arch/xtensa/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile
index 9c5185f..40aa55b 100644
--- a/arch/xtensa/boot/Makefile
+++ b/arch/xtensa/boot/Makefile
@@ -8,7 +8,8 @@
 #
 
 
-EXTRA_CFLAGS	+= -fno-builtin -Iarch/$(ARCH)/boot/include
+# KBUILD_CFLAGS used when building rest of boot (takes effect recursively)
+KBUILD_CFLAGS	+= -fno-builtin -Iarch/$(ARCH)/boot/include
 HOSTFLAGS	+= -Iarch/$(ARCH)/boot/include
 
 BIG_ENDIAN	:= $(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#")
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 8be99c7..397bcd6 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -176,7 +176,7 @@
 	printk("Caught unhandled exception in '%s' "
 	       "(pid = %d, pc = %#010lx) - should not happen\n"
 	       "\tEXCCAUSE is %ld\n",
-	       current->comm, current->pid, regs->pc, exccause);
+	       current->comm, task_pid_nr(current), regs->pc, exccause);
 	force_sig(SIGILL, current);
 }
 
@@ -228,7 +228,7 @@
 	/* If in user mode, send SIGILL signal to current process. */
 
 	printk("Illegal Instruction in '%s' (pid = %d, pc = %#010lx)\n",
-	    current->comm, current->pid, regs->pc);
+	    current->comm, task_pid_nr(current), regs->pc);
 	force_sig(SIGILL, current);
 }
 
@@ -254,7 +254,7 @@
 	current->thread.error_code = -3;
 	printk("Unaligned memory access to %08lx in '%s' "
 	       "(pid = %d, pc = %#010lx)\n",
-	       regs->excvaddr, current->comm, current->pid, regs->pc);
+	       regs->excvaddr, current->comm, task_pid_nr(current), regs->pc);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRALN;
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index 2f84285..33f366b 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -145,7 +145,7 @@
 	 */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (is_init(current)) {
+	if (is_global_init(current)) {
 		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
index f09962f..b61fb36 100644
--- a/arch/xtensa/platform-iss/network.c
+++ b/arch/xtensa/platform-iss/network.c
@@ -798,7 +798,7 @@
 
 #undef ERR
 
-__setup("eth", iss_net_setup);
+__setup("eth=", iss_net_setup);
 
 /*
  * Initialize all ISS Ethernet devices previously registered in iss_net_setup.
diff --git a/block/elevator.c b/block/elevator.c
index 952aee0..446aea2 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -390,7 +390,7 @@
 
 /*
  * Insert rq into dispatch queue of q.  Queue lock must be held on
- * entry.  rq is sort insted into the dispatch queue. To be used by
+ * entry.  rq is sort instead into the dispatch queue. To be used by
  * specific elevators.
  */
 void elv_dispatch_sort(struct request_queue *q, struct request *rq)
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 3935469..de5ba47 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1351,11 +1351,22 @@
 new_segment:
 			if (!sg)
 				sg = sglist;
-			else
+			else {
+				/*
+				 * If the driver previously mapped a shorter
+				 * list, we could see a termination bit
+				 * prematurely unless it fully inits the sg
+				 * table on each mapping. We KNOW that there
+				 * must be more entries here or the driver
+				 * would be buggy, so force clear the
+				 * termination bit to avoid doing a full
+				 * sg_init_table() in drivers for each command.
+				 */
+				sg->page_link &= ~0x02;
 				sg = sg_next(sg);
+			}
 
-			memset(sg, 0, sizeof(*sg));
-			sg->page = bvec->bv_page;
+			sg_set_page(sg, bvec->bv_page);
 			sg->length = nbytes;
 			sg->offset = bvec->bv_offset;
 			nsegs++;
@@ -1363,6 +1374,9 @@
 		bvprv = bvec;
 	} /* segments in rq */
 
+	if (sg)
+		__sg_mark_end(sg);
+
 	return nsegs;
 }
 
@@ -3367,7 +3381,7 @@
 		if (unlikely(block_dump)) {
 			char b[BDEVNAME_SIZE];
 			printk(KERN_DEBUG "%s(%d): %s block %Lu on %s\n",
-				current->comm, current->pid,
+			current->comm, task_pid_nr(current),
 				(rw & WRITE) ? "WRITE" : "READ",
 				(unsigned long long)bio->bi_sector,
 				bdevname(bio->bi_bdev,b));
@@ -3739,7 +3753,7 @@
 
 /**
  * end_request - end I/O on the current segment of the request
- * @rq:		the request being processed
+ * @req:	the request being processed
  * @uptodate:	error value or 0/1 uptodate flag
  *
  * Description:
diff --git a/crypto/api.c b/crypto/api.c
index 4ccc5af..1f5c724 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -6,7 +6,7 @@
  * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
- * and Nettle, by Niels Möller.
+ * and Nettle, by Niels Möller.
  *
  * 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
diff --git a/crypto/digest.c b/crypto/digest.c
index e56de67..8871dec 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -41,7 +41,7 @@
 		return 0;
 
 	for (;;) {
-		struct page *pg = sg->page;
+		struct page *pg = sg_page(sg);
 		unsigned int offset = sg->offset;
 		unsigned int l = sg->length;
 
diff --git a/crypto/fcrypt.c b/crypto/fcrypt.c
index 9c2bb53..d161949 100644
--- a/crypto/fcrypt.c
+++ b/crypto/fcrypt.c
@@ -10,7 +10,7 @@
  *
  * Based on code:
  *
- * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 8802fb6..e4eb6ac 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -159,7 +159,8 @@
 	desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
 
 	sg_set_buf(sg1, ipad, bs);
-	sg1[1].page = (void *)sg;
+
+	sg_set_page(&sg[1], (void *) sg);
 	sg1[1].length = 0;
 	sg_set_buf(sg2, opad, bs + ds);
 
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index d6852c3..b9bbda0 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -54,7 +54,7 @@
 	if (out) {
 		struct page *page;
 
-		page = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT);
+		page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
 		flush_dcache_page(page);
 	}
 
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
index 9c73e37..87ed681 100644
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -22,13 +22,13 @@
 
 static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
 {
-	return (++sg)->length ? sg : (void *)sg->page;
+	return (++sg)->length ? sg : (void *) sg_page(sg);
 }
 
 static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
 						struct scatter_walk *walk_out)
 {
-	return !(((walk_in->sg->page - walk_out->sg->page) << PAGE_SHIFT) +
+	return !(((sg_page(walk_in->sg) - sg_page(walk_out->sg)) << PAGE_SHIFT) +
 		 (int)(walk_in->offset - walk_out->offset));
 }
 
@@ -60,7 +60,7 @@
 
 static inline struct page *scatterwalk_page(struct scatter_walk *walk)
 {
-	return walk->sg->page + (walk->offset >> PAGE_SHIFT);
+	return sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
 }
 
 static inline void scatterwalk_unmap(void *vaddr, int out)
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 18d489c..d741c63 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -317,7 +317,7 @@
 				goto out;
 			}
 
-			q = kmap(sg[0].page) + sg[0].offset;
+			q = kmap(sg_page(&sg[0])) + sg[0].offset;
 			hexdump(q, cipher_tv[i].rlen);
 
 			printk("%s\n",
@@ -390,7 +390,7 @@
 			temp = 0;
 			for (k = 0; k < cipher_tv[i].np; k++) {
 				printk("page %u\n", k);
-				q = kmap(sg[k].page) + sg[k].offset;
+				q = kmap(sg_page(&sg[k])) + sg[k].offset;
 				hexdump(q, cipher_tv[i].tap[k]);
 				printk("%s\n",
 					memcmp(q, cipher_tv[i].result + temp,
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 9f502b8..ac68f3b 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -120,7 +120,7 @@
 
 	do {
 
-		struct page *pg = sg[i].page;
+		struct page *pg = sg_page(&sg[i]);
 		unsigned int offset = sg[i].offset;
 		unsigned int slen = sg[i].length;
 
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 4fb134d..f4076d9 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -58,6 +58,8 @@
 
 source "drivers/hwmon/Kconfig"
 
+source "drivers/watchdog/Kconfig"
+
 source "drivers/ssb/Kconfig"
 
 source "drivers/mfd/Kconfig"
@@ -92,5 +94,5 @@
 
 source "drivers/uio/Kconfig"
 
-source "drivers/lguest/Kconfig"
+source "drivers/virtio/Kconfig"
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 8c645bc..8cb37e3 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -65,7 +65,7 @@
 obj-$(CONFIG_W1)		+= w1/
 obj-$(CONFIG_POWER_SUPPLY)	+= power/
 obj-$(CONFIG_HWMON)		+= hwmon/
-obj-$(CONFIG_WATCHDOG)		+= char/watchdog/
+obj-$(CONFIG_WATCHDOG)		+= watchdog/
 obj-$(CONFIG_PHONE)		+= telephony/
 obj-$(CONFIG_MD)		+= md/
 obj-$(CONFIG_BT)		+= bluetooth/
@@ -75,6 +75,7 @@
 obj-$(CONFIG_EISA)		+= eisa/
 obj-$(CONFIG_LGUEST_GUEST)	+= lguest/
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
+obj-$(CONFIG_CPU_IDLE)		+= cpuidle/
 obj-$(CONFIG_MMC)		+= mmc/
 obj-$(CONFIG_NEW_LEDS)		+= leds/
 obj-$(CONFIG_INFINIBAND)	+= infiniband/
@@ -89,3 +90,4 @@
 obj-$(CONFIG_PPC_PS3)		+= ps3/
 obj-$(CONFIG_OF)		+= of/
 obj-$(CONFIG_SSB)		+= ssb/
+obj-$(CONFIG_VIRTIO)		+= virtio/
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 4875f01..5d0e26a 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -52,7 +52,7 @@
 	depends on PROC_FS
 	---help---
 	  For backwards compatibility, this option allows
-	  depricated /proc/acpi/ files to exist, even when
+	  deprecated /proc/acpi/ files to exist, even when
 	  they have been replaced by functions in /sys.
 	  The deprecated files (and their replacements) include:
 
@@ -88,7 +88,7 @@
 
 config ACPI_AC
 	tristate "AC Adapter"
-	depends on X86
+	depends on X86 && POWER_SUPPLY
 	default y
 	help
 	  This driver adds support for the AC Adapter object, which indicates
@@ -97,7 +97,7 @@
 
 config ACPI_BATTERY
 	tristate "Battery"
-	depends on X86
+	depends on X86 && POWER_SUPPLY
 	default y
 	help
 	  This driver adds support for battery information through
@@ -117,6 +117,7 @@
 config ACPI_VIDEO
 	tristate "Video"
 	depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL
+	depends on INPUT
 	help
 	  This driver implement the ACPI Extensions For Display Adapters
 	  for integrated graphics devices on motherboard, as specified in
@@ -349,12 +350,11 @@
 		$>modprobe acpi_memhotplug 
 
 config ACPI_SBS
-	tristate "Smart Battery System (EXPERIMENTAL)"
+	tristate "Smart Battery System"
 	depends on X86
-	depends on EXPERIMENTAL
+	depends on POWER_SUPPLY
 	help
-	  This driver adds support for the Smart Battery System.
-	  A "Smart Battery" is quite old and quite rare compared
-	  to today's ACPI "Control Method" battery.
+	  This driver adds support for the Smart Battery System, another
+	  type of access to battery information, found on some laptops.
 
 endif	# ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index d4336f1..54e3ab0 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -60,3 +60,4 @@
 obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o
 obj-y				+= cm_sbs.o
 obj-$(CONFIG_ACPI_SBS)		+= sbs.o
+obj-$(CONFIG_ACPI_SBS)		+= sbshc.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 26d7070..e03de37 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -29,6 +29,7 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/power_supply.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -72,16 +73,37 @@
 };
 
 struct acpi_ac {
+	struct power_supply charger;
 	struct acpi_device * device;
 	unsigned long state;
 };
 
+#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger);
+
 static const struct file_operations acpi_ac_fops = {
 	.open = acpi_ac_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
+static int get_ac_property(struct power_supply *psy,
+			   enum power_supply_property psp,
+			   union power_supply_propval *val)
+{
+	struct acpi_ac *ac = to_acpi_ac(psy);
+	switch (psp) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = ac->state;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static enum power_supply_property ac_props[] = {
+	POWER_SUPPLY_PROP_ONLINE,
+};
 
 /* --------------------------------------------------------------------------
                                AC Adapter Management
@@ -208,6 +230,7 @@
 		acpi_bus_generate_netlink_event(device->pnp.device_class,
 						  device->dev.bus_id, event,
 						  (u32) ac->state);
+		kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
 		break;
 	default:
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -244,7 +267,12 @@
 	result = acpi_ac_add_fs(device);
 	if (result)
 		goto end;
-
+	ac->charger.name = acpi_device_bid(device);
+	ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
+	ac->charger.properties = ac_props;
+	ac->charger.num_properties = ARRAY_SIZE(ac_props);
+	ac->charger.get_property = get_ac_property;
+	power_supply_register(&ac->device->dev, &ac->charger);
 	status = acpi_install_notify_handler(device->handle,
 					     ACPI_ALL_NOTIFY, acpi_ac_notify,
 					     ac);
@@ -279,7 +307,8 @@
 
 	status = acpi_remove_notify_handler(device->handle,
 					    ACPI_ALL_NOTIFY, acpi_ac_notify);
-
+	if (ac->charger.dev)
+		power_supply_unregister(&ac->charger);
 	acpi_ac_remove_fs(device);
 
 	kfree(ac);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 9b2c0f7..681e26b 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -1,6 +1,8 @@
 /*
- *  acpi_battery.c - ACPI Battery Driver ($Revision: 37 $)
+ *  battery.c - ACPI Battery Driver (Revision: 2.0)
  *
+ *  Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
+ *  Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  *
@@ -27,244 +29,288 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
+#include <linux/jiffies.h>
+
+#ifdef CONFIG_ACPI_PROCFS
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
+#endif
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
-#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
+#include <linux/power_supply.h>
 
-#define ACPI_BATTERY_FORMAT_BIF	"NNNNNNNNNSSSS"
-#define ACPI_BATTERY_FORMAT_BST	"NNNN"
+#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
 
 #define ACPI_BATTERY_COMPONENT		0x00040000
 #define ACPI_BATTERY_CLASS		"battery"
 #define ACPI_BATTERY_DEVICE_NAME	"Battery"
 #define ACPI_BATTERY_NOTIFY_STATUS	0x80
 #define ACPI_BATTERY_NOTIFY_INFO	0x81
-#define ACPI_BATTERY_UNITS_WATTS	"mW"
-#define ACPI_BATTERY_UNITS_AMPS		"mA"
 
 #define _COMPONENT		ACPI_BATTERY_COMPONENT
 
-#define ACPI_BATTERY_UPDATE_TIME	0
-
-#define ACPI_BATTERY_NONE_UPDATE	0
-#define ACPI_BATTERY_EASY_UPDATE	1
-#define ACPI_BATTERY_INIT_UPDATE	2
-
 ACPI_MODULE_NAME("battery");
 
 MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
 MODULE_DESCRIPTION("ACPI Battery Driver");
 MODULE_LICENSE("GPL");
 
-static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME;
+static unsigned int cache_time = 1000;
+module_param(cache_time, uint, 0644);
+MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
 
-/* 0 - every time, > 0 - by update_time */
-module_param(update_time, uint, 0644);
-
+#ifdef CONFIG_ACPI_PROCFS
 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 
-static int acpi_battery_add(struct acpi_device *device);
-static int acpi_battery_remove(struct acpi_device *device, int type);
-static int acpi_battery_resume(struct acpi_device *device);
+enum acpi_battery_files {
+	info_tag = 0,
+	state_tag,
+	alarm_tag,
+	ACPI_BATTERY_NUMFILES,
+};
+
+#endif
 
 static const struct acpi_device_id battery_device_ids[] = {
 	{"PNP0C0A", 0},
 	{"", 0},
 };
+
 MODULE_DEVICE_TABLE(acpi, battery_device_ids);
 
-static struct acpi_driver acpi_battery_driver = {
-	.name = "battery",
-	.class = ACPI_BATTERY_CLASS,
-	.ids = battery_device_ids,
-	.ops = {
-		.add = acpi_battery_add,
-		.resume = acpi_battery_resume,
-		.remove = acpi_battery_remove,
-		},
-};
-
-struct acpi_battery_state {
-	acpi_integer state;
-	acpi_integer present_rate;
-	acpi_integer remaining_capacity;
-	acpi_integer present_voltage;
-};
-
-struct acpi_battery_info {
-	acpi_integer power_unit;
-	acpi_integer design_capacity;
-	acpi_integer last_full_capacity;
-	acpi_integer battery_technology;
-	acpi_integer design_voltage;
-	acpi_integer design_capacity_warning;
-	acpi_integer design_capacity_low;
-	acpi_integer battery_capacity_granularity_1;
-	acpi_integer battery_capacity_granularity_2;
-	acpi_string model_number;
-	acpi_string serial_number;
-	acpi_string battery_type;
-	acpi_string oem_info;
-};
-
-enum acpi_battery_files{
-	ACPI_BATTERY_INFO = 0,
-	ACPI_BATTERY_STATE,
-	ACPI_BATTERY_ALARM,
-	ACPI_BATTERY_NUMFILES,
-};
-
-struct acpi_battery_flags {
-	u8 battery_present_prev;
-	u8 alarm_present;
-	u8 init_update;
-	u8 update[ACPI_BATTERY_NUMFILES];
-	u8 power_unit;
-};
 
 struct acpi_battery {
-	struct mutex mutex;
+	struct mutex lock;
+	struct power_supply bat;
 	struct acpi_device *device;
-	struct acpi_battery_flags flags;
-	struct acpi_buffer bif_data;
-	struct acpi_buffer bst_data;
-	unsigned long alarm;
-	unsigned long update_time[ACPI_BATTERY_NUMFILES];
+	unsigned long update_time;
+	int current_now;
+	int capacity_now;
+	int voltage_now;
+	int design_capacity;
+	int full_charge_capacity;
+	int technology;
+	int design_voltage;
+	int design_capacity_warning;
+	int design_capacity_low;
+	int capacity_granularity_1;
+	int capacity_granularity_2;
+	int alarm;
+	char model_number[32];
+	char serial_number[32];
+	char type[32];
+	char oem_info[32];
+	int state;
+	int power_unit;
+	u8 alarm_present;
 };
 
+#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
+
 inline int acpi_battery_present(struct acpi_battery *battery)
 {
 	return battery->device->status.battery_present;
 }
-inline char *acpi_battery_power_units(struct acpi_battery *battery)
+
+static int acpi_battery_technology(struct acpi_battery *battery)
 {
-	if (battery->flags.power_unit)
-		return ACPI_BATTERY_UNITS_AMPS;
-	else
-		return ACPI_BATTERY_UNITS_WATTS;
+	if (!strcasecmp("NiCd", battery->type))
+		return POWER_SUPPLY_TECHNOLOGY_NiCd;
+	if (!strcasecmp("NiMH", battery->type))
+		return POWER_SUPPLY_TECHNOLOGY_NiMH;
+	if (!strcasecmp("LION", battery->type))
+		return POWER_SUPPLY_TECHNOLOGY_LION;
+	if (!strcasecmp("LiP", battery->type))
+		return POWER_SUPPLY_TECHNOLOGY_LIPO;
+	return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
 }
 
-inline acpi_handle acpi_battery_handle(struct acpi_battery *battery)
+static int acpi_battery_get_property(struct power_supply *psy,
+				     enum power_supply_property psp,
+				     union power_supply_propval *val)
 {
-	return battery->device->handle;
+	struct acpi_battery *battery = to_acpi_battery(psy);
+
+	if ((!acpi_battery_present(battery)) &&
+	     psp != POWER_SUPPLY_PROP_PRESENT)
+		return -ENODEV;
+	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		if (battery->state & 0x01)
+			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		else if (battery->state & 0x02)
+			val->intval = POWER_SUPPLY_STATUS_CHARGING;
+		else if (battery->state == 0)
+			val->intval = POWER_SUPPLY_STATUS_FULL;
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = acpi_battery_present(battery);
+		break;
+	case POWER_SUPPLY_PROP_TECHNOLOGY:
+		val->intval = acpi_battery_technology(battery);
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+		val->intval = battery->design_voltage * 1000;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		val->intval = battery->voltage_now * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+		val->intval = battery->current_now * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+		val->intval = battery->design_capacity * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_FULL:
+	case POWER_SUPPLY_PROP_ENERGY_FULL:
+		val->intval = battery->full_charge_capacity * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_NOW:
+	case POWER_SUPPLY_PROP_ENERGY_NOW:
+		val->intval = battery->capacity_now * 1000;
+		break;
+	case POWER_SUPPLY_PROP_MODEL_NAME:
+		val->strval = battery->model_number;
+		break;
+	case POWER_SUPPLY_PROP_MANUFACTURER:
+		val->strval = battery->oem_info;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
 }
 
+static enum power_supply_property charge_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+	POWER_SUPPLY_PROP_CHARGE_FULL,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static enum power_supply_property energy_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+	POWER_SUPPLY_PROP_ENERGY_FULL,
+	POWER_SUPPLY_PROP_ENERGY_NOW,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+#ifdef CONFIG_ACPI_PROCFS
+inline char *acpi_battery_units(struct acpi_battery *battery)
+{
+	return (battery->power_unit)?"mA":"mW";
+}
+#endif
+
 /* --------------------------------------------------------------------------
                                Battery Management
    -------------------------------------------------------------------------- */
+struct acpi_offsets {
+	size_t offset;		/* offset inside struct acpi_sbs_battery */
+	u8 mode;		/* int or string? */
+};
 
-static void acpi_battery_check_result(struct acpi_battery *battery, int result)
+static struct acpi_offsets state_offsets[] = {
+	{offsetof(struct acpi_battery, state), 0},
+	{offsetof(struct acpi_battery, current_now), 0},
+	{offsetof(struct acpi_battery, capacity_now), 0},
+	{offsetof(struct acpi_battery, voltage_now), 0},
+};
+
+static struct acpi_offsets info_offsets[] = {
+	{offsetof(struct acpi_battery, power_unit), 0},
+	{offsetof(struct acpi_battery, design_capacity), 0},
+	{offsetof(struct acpi_battery, full_charge_capacity), 0},
+	{offsetof(struct acpi_battery, technology), 0},
+	{offsetof(struct acpi_battery, design_voltage), 0},
+	{offsetof(struct acpi_battery, design_capacity_warning), 0},
+	{offsetof(struct acpi_battery, design_capacity_low), 0},
+	{offsetof(struct acpi_battery, capacity_granularity_1), 0},
+	{offsetof(struct acpi_battery, capacity_granularity_2), 0},
+	{offsetof(struct acpi_battery, model_number), 1},
+	{offsetof(struct acpi_battery, serial_number), 1},
+	{offsetof(struct acpi_battery, type), 1},
+	{offsetof(struct acpi_battery, oem_info), 1},
+};
+
+static int extract_package(struct acpi_battery *battery,
+			   union acpi_object *package,
+			   struct acpi_offsets *offsets, int num)
 {
-	if (!battery)
-		return;
-
-	if (result) {
-		battery->flags.init_update = 1;
-	}
-}
-
-static int acpi_battery_extract_package(struct acpi_battery *battery,
-					union acpi_object *package,
-					struct acpi_buffer *format,
-					struct acpi_buffer *data,
-					char *package_name)
-{
-	acpi_status status = AE_OK;
-	struct acpi_buffer data_null = { 0, NULL };
-
-	status = acpi_extract_package(package, format, &data_null);
-	if (status != AE_BUFFER_OVERFLOW) {
-		ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s",
-				package_name));
-		return -ENODEV;
-	}
-
-	if (data_null.length != data->length) {
-		kfree(data->pointer);
-		data->pointer = kzalloc(data_null.length, GFP_KERNEL);
-		if (!data->pointer) {
-			ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()"));
-			return -ENOMEM;
+	int i, *x;
+	union acpi_object *element;
+	if (package->type != ACPI_TYPE_PACKAGE)
+		return -EFAULT;
+	for (i = 0; i < num; ++i) {
+		if (package->package.count <= i)
+			return -EFAULT;
+		element = &package->package.elements[i];
+		if (offsets[i].mode) {
+			if (element->type != ACPI_TYPE_STRING &&
+			    element->type != ACPI_TYPE_BUFFER)
+				return -EFAULT;
+			strncpy((u8 *)battery + offsets[i].offset,
+				element->string.pointer, 32);
+		} else {
+			if (element->type != ACPI_TYPE_INTEGER)
+				return -EFAULT;
+			x = (int *)((u8 *)battery + offsets[i].offset);
+			*x = element->integer.value;
 		}
-		data->length = data_null.length;
 	}
-
-	status = acpi_extract_package(package, format, data);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Extracting %s",
-				package_name));
-		return -ENODEV;
-	}
-
 	return 0;
 }
 
 static int acpi_battery_get_status(struct acpi_battery *battery)
 {
-	int result = 0;
-
-	result = acpi_bus_get_status(battery->device);
-	if (result) {
+	if (acpi_bus_get_status(battery->device)) {
 		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
 		return -ENODEV;
 	}
-	return result;
+	return 0;
 }
 
 static int acpi_battery_get_info(struct acpi_battery *battery)
 {
-	int result = 0;
+	int result = -EFAULT;
 	acpi_status status = 0;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF),
-		ACPI_BATTERY_FORMAT_BIF
-	};
-	union acpi_object *package = NULL;
-	struct acpi_buffer *data = NULL;
-	struct acpi_battery_info *bif = NULL;
-
-	battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
 
 	if (!acpi_battery_present(battery))
 		return 0;
+	mutex_lock(&battery->lock);
+	status = acpi_evaluate_object(battery->device->handle, "_BIF",
+				      NULL, &buffer);
+	mutex_unlock(&battery->lock);
 
-	/* Evaluate _BIF */
-
-	status =
-	    acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
-				 &buffer);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
 		return -ENODEV;
 	}
 
-	package = buffer.pointer;
-
-	data = &battery->bif_data;
-
-	/* Extract Package Data */
-
-	result =
-	    acpi_battery_extract_package(battery, package, &format, data,
-					 "_BIF");
-	if (result)
-		goto end;
-
-      end:
-
+	result = extract_package(battery, buffer.pointer,
+				 info_offsets, ARRAY_SIZE(info_offsets));
 	kfree(buffer.pointer);
-
-	if (!result) {
-		bif = data->pointer;
-		battery->flags.power_unit = bif->power_unit;
-	}
-
 	return result;
 }
 
@@ -273,342 +319,203 @@
 	int result = 0;
 	acpi_status status = 0;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST),
-		ACPI_BATTERY_FORMAT_BST
-	};
-	union acpi_object *package = NULL;
-	struct acpi_buffer *data = NULL;
-
-	battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
 
 	if (!acpi_battery_present(battery))
 		return 0;
 
-	/* Evaluate _BST */
+	if (battery->update_time &&
+	    time_before(jiffies, battery->update_time +
+			msecs_to_jiffies(cache_time)))
+		return 0;
 
-	status =
-	    acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
-				 &buffer);
+	mutex_lock(&battery->lock);
+	status = acpi_evaluate_object(battery->device->handle, "_BST",
+				      NULL, &buffer);
+	mutex_unlock(&battery->lock);
+
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
 		return -ENODEV;
 	}
 
-	package = buffer.pointer;
-
-	data = &battery->bst_data;
-
-	/* Extract Package Data */
-
-	result =
-	    acpi_battery_extract_package(battery, package, &format, data,
-					 "_BST");
-	if (result)
-		goto end;
-
-      end:
+	result = extract_package(battery, buffer.pointer,
+				 state_offsets, ARRAY_SIZE(state_offsets));
+	battery->update_time = jiffies;
 	kfree(buffer.pointer);
-
 	return result;
 }
 
-static int acpi_battery_get_alarm(struct acpi_battery *battery)
-{
-	battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
-
-	return 0;
-}
-
-static int acpi_battery_set_alarm(struct acpi_battery *battery,
-				  unsigned long alarm)
+static int acpi_battery_set_alarm(struct acpi_battery *battery)
 {
 	acpi_status status = 0;
-	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+	union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
 	struct acpi_object_list arg_list = { 1, &arg0 };
 
-	battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
-
-	if (!acpi_battery_present(battery))
+	if (!acpi_battery_present(battery)|| !battery->alarm_present)
 		return -ENODEV;
 
-	if (!battery->flags.alarm_present)
-		return -ENODEV;
+	arg0.integer.value = battery->alarm;
 
-	arg0.integer.value = alarm;
-
-	status =
-	    acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
+	mutex_lock(&battery->lock);
+	status = acpi_evaluate_object(battery->device->handle, "_BTP",
 				 &arg_list, NULL);
+	mutex_unlock(&battery->lock);
+
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm));
-
-	battery->alarm = alarm;
-
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
 	return 0;
 }
 
 static int acpi_battery_init_alarm(struct acpi_battery *battery)
 {
-	int result = 0;
 	acpi_status status = AE_OK;
 	acpi_handle handle = NULL;
-	struct acpi_battery_info *bif = battery->bif_data.pointer;
-	unsigned long alarm = battery->alarm;
 
 	/* See if alarms are supported, and if so, set default */
-
-	status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
-	if (ACPI_SUCCESS(status)) {
-		battery->flags.alarm_present = 1;
-		if (!alarm && bif) {
-			alarm = bif->design_capacity_warning;
-		}
-		result = acpi_battery_set_alarm(battery, alarm);
-		if (result)
-			goto end;
-	} else {
-		battery->flags.alarm_present = 0;
+	status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
+	if (ACPI_FAILURE(status)) {
+		battery->alarm_present = 0;
+		return 0;
 	}
-
-      end:
-
-	return result;
+	battery->alarm_present = 1;
+	if (!battery->alarm)
+		battery->alarm = battery->design_capacity_warning;
+	return acpi_battery_set_alarm(battery);
 }
 
-static int acpi_battery_init_update(struct acpi_battery *battery)
+static int acpi_battery_update(struct acpi_battery *battery)
 {
-	int result = 0;
-
-	result = acpi_battery_get_status(battery);
-	if (result)
+	int saved_present = acpi_battery_present(battery);
+	int result = acpi_battery_get_status(battery);
+	if (result || !acpi_battery_present(battery))
 		return result;
-
-	battery->flags.battery_present_prev = acpi_battery_present(battery);
-
-	if (acpi_battery_present(battery)) {
+	if (saved_present != acpi_battery_present(battery) ||
+	    !battery->update_time) {
+		battery->update_time = 0;
 		result = acpi_battery_get_info(battery);
 		if (result)
 			return result;
-		result = acpi_battery_get_state(battery);
-		if (result)
-			return result;
-
+		if (battery->power_unit) {
+			battery->bat.properties = charge_battery_props;
+			battery->bat.num_properties =
+				ARRAY_SIZE(charge_battery_props);
+		} else {
+			battery->bat.properties = energy_battery_props;
+			battery->bat.num_properties =
+				ARRAY_SIZE(energy_battery_props);
+		}
 		acpi_battery_init_alarm(battery);
 	}
-
-	return result;
-}
-
-static int acpi_battery_update(struct acpi_battery *battery,
-			       int update, int *update_result_ptr)
-{
-	int result = 0;
-	int update_result = ACPI_BATTERY_NONE_UPDATE;
-
-	if (!acpi_battery_present(battery)) {
-		update = 1;
-	}
-
-	if (battery->flags.init_update) {
-		result = acpi_battery_init_update(battery);
-		if (result)
-			goto end;
-		update_result = ACPI_BATTERY_INIT_UPDATE;
-	} else if (update) {
-		result = acpi_battery_get_status(battery);
-		if (result)
-			goto end;
-		if ((!battery->flags.battery_present_prev & acpi_battery_present(battery))
-		    || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) {
-			result = acpi_battery_init_update(battery);
-			if (result)
-				goto end;
-			update_result = ACPI_BATTERY_INIT_UPDATE;
-		} else {
-			update_result = ACPI_BATTERY_EASY_UPDATE;
-		}
-	}
-
-      end:
-
-	battery->flags.init_update = (result != 0);
-
-	*update_result_ptr = update_result;
-
-	return result;
-}
-
-static void acpi_battery_notify_update(struct acpi_battery *battery)
-{
-	acpi_battery_get_status(battery);
-
-	if (battery->flags.init_update) {
-		return;
-	}
-
-	if ((!battery->flags.battery_present_prev &
-	     acpi_battery_present(battery)) ||
-	    (battery->flags.battery_present_prev &
-	     !acpi_battery_present(battery))) {
-		battery->flags.init_update = 1;
-	} else {
-		battery->flags.update[ACPI_BATTERY_INFO] = 1;
-		battery->flags.update[ACPI_BATTERY_STATE] = 1;
-		battery->flags.update[ACPI_BATTERY_ALARM] = 1;
-	}
+	return acpi_battery_get_state(battery);
 }
 
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
+#ifdef CONFIG_ACPI_PROCFS
 static struct proc_dir_entry *acpi_battery_dir;
 
 static int acpi_battery_print_info(struct seq_file *seq, int result)
 {
 	struct acpi_battery *battery = seq->private;
-	struct acpi_battery_info *bif = NULL;
-	char *units = "?";
 
 	if (result)
 		goto end;
 
-	if (acpi_battery_present(battery))
-		seq_printf(seq, "present:                 yes\n");
-	else {
-		seq_printf(seq, "present:                 no\n");
+	seq_printf(seq, "present:                 %s\n",
+		   acpi_battery_present(battery)?"yes":"no");
+	if (!acpi_battery_present(battery))
 		goto end;
-	}
-
-	bif = battery->bif_data.pointer;
-	if (!bif) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL"));
-		result = -ENODEV;
-		goto end;
-	}
-
-	/* Battery Units */
-
-	units = acpi_battery_power_units(battery);
-
-	if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "design capacity:         unknown\n");
 	else
 		seq_printf(seq, "design capacity:         %d %sh\n",
-			   (u32) bif->design_capacity, units);
+			   battery->design_capacity,
+			   acpi_battery_units(battery));
 
-	if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "last full capacity:      unknown\n");
 	else
 		seq_printf(seq, "last full capacity:      %d %sh\n",
-			   (u32) bif->last_full_capacity, units);
+			   battery->full_charge_capacity,
+			   acpi_battery_units(battery));
 
-	switch ((u32) bif->battery_technology) {
-	case 0:
-		seq_printf(seq, "battery technology:      non-rechargeable\n");
-		break;
-	case 1:
-		seq_printf(seq, "battery technology:      rechargeable\n");
-		break;
-	default:
-		seq_printf(seq, "battery technology:      unknown\n");
-		break;
-	}
+	seq_printf(seq, "battery technology:      %srechargeable\n",
+		   (!battery->technology)?"non-":"");
 
-	if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "design voltage:          unknown\n");
 	else
 		seq_printf(seq, "design voltage:          %d mV\n",
-			   (u32) bif->design_voltage);
+			   battery->design_voltage);
 	seq_printf(seq, "design capacity warning: %d %sh\n",
-		   (u32) bif->design_capacity_warning, units);
+		   battery->design_capacity_warning,
+		   acpi_battery_units(battery));
 	seq_printf(seq, "design capacity low:     %d %sh\n",
-		   (u32) bif->design_capacity_low, units);
+		   battery->design_capacity_low,
+		   acpi_battery_units(battery));
 	seq_printf(seq, "capacity granularity 1:  %d %sh\n",
-		   (u32) bif->battery_capacity_granularity_1, units);
+		   battery->capacity_granularity_1,
+		   acpi_battery_units(battery));
 	seq_printf(seq, "capacity granularity 2:  %d %sh\n",
-		   (u32) bif->battery_capacity_granularity_2, units);
-	seq_printf(seq, "model number:            %s\n", bif->model_number);
-	seq_printf(seq, "serial number:           %s\n", bif->serial_number);
-	seq_printf(seq, "battery type:            %s\n", bif->battery_type);
-	seq_printf(seq, "OEM info:                %s\n", bif->oem_info);
-
+		   battery->capacity_granularity_2,
+		   acpi_battery_units(battery));
+	seq_printf(seq, "model number:            %s\n", battery->model_number);
+	seq_printf(seq, "serial number:           %s\n", battery->serial_number);
+	seq_printf(seq, "battery type:            %s\n", battery->type);
+	seq_printf(seq, "OEM info:                %s\n", battery->oem_info);
       end:
-
 	if (result)
 		seq_printf(seq, "ERROR: Unable to read battery info\n");
-
 	return result;
 }
 
 static int acpi_battery_print_state(struct seq_file *seq, int result)
 {
 	struct acpi_battery *battery = seq->private;
-	struct acpi_battery_state *bst = NULL;
-	char *units = "?";
 
 	if (result)
 		goto end;
 
-	if (acpi_battery_present(battery))
-		seq_printf(seq, "present:                 yes\n");
-	else {
-		seq_printf(seq, "present:                 no\n");
+	seq_printf(seq, "present:                 %s\n",
+		   acpi_battery_present(battery)?"yes":"no");
+	if (!acpi_battery_present(battery))
 		goto end;
-	}
 
-	bst = battery->bst_data.pointer;
-	if (!bst) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL"));
-		result = -ENODEV;
-		goto end;
-	}
-
-	/* Battery Units */
-
-	units = acpi_battery_power_units(battery);
-
-	if (!(bst->state & 0x04))
-		seq_printf(seq, "capacity state:          ok\n");
-	else
-		seq_printf(seq, "capacity state:          critical\n");
-
-	if ((bst->state & 0x01) && (bst->state & 0x02)) {
+	seq_printf(seq, "capacity state:          %s\n",
+			(battery->state & 0x04)?"critical":"ok");
+	if ((battery->state & 0x01) && (battery->state & 0x02))
 		seq_printf(seq,
 			   "charging state:          charging/discharging\n");
-	} else if (bst->state & 0x01)
+	else if (battery->state & 0x01)
 		seq_printf(seq, "charging state:          discharging\n");
-	else if (bst->state & 0x02)
+	else if (battery->state & 0x02)
 		seq_printf(seq, "charging state:          charging\n");
-	else {
+	else
 		seq_printf(seq, "charging state:          charged\n");
-	}
 
-	if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "present rate:            unknown\n");
 	else
 		seq_printf(seq, "present rate:            %d %s\n",
-			   (u32) bst->present_rate, units);
+			   battery->current_now, acpi_battery_units(battery));
 
-	if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "remaining capacity:      unknown\n");
 	else
 		seq_printf(seq, "remaining capacity:      %d %sh\n",
-			   (u32) bst->remaining_capacity, units);
-
-	if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
+			   battery->capacity_now, acpi_battery_units(battery));
+	if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "present voltage:         unknown\n");
 	else
 		seq_printf(seq, "present voltage:         %d mV\n",
-			   (u32) bst->present_voltage);
-
+			   battery->voltage_now);
       end:
-
-	if (result) {
+	if (result)
 		seq_printf(seq, "ERROR: Unable to read battery state\n");
-	}
 
 	return result;
 }
@@ -616,7 +523,6 @@
 static int acpi_battery_print_alarm(struct seq_file *seq, int result)
 {
 	struct acpi_battery *battery = seq->private;
-	char *units = "?";
 
 	if (result)
 		goto end;
@@ -625,189 +531,121 @@
 		seq_printf(seq, "present:                 no\n");
 		goto end;
 	}
-
-	/* Battery Units */
-
-	units = acpi_battery_power_units(battery);
-
 	seq_printf(seq, "alarm:                   ");
 	if (!battery->alarm)
 		seq_printf(seq, "unsupported\n");
 	else
-		seq_printf(seq, "%lu %sh\n", battery->alarm, units);
-
+		seq_printf(seq, "%u %sh\n", battery->alarm,
+				acpi_battery_units(battery));
       end:
-
 	if (result)
 		seq_printf(seq, "ERROR: Unable to read battery alarm\n");
-
 	return result;
 }
 
-static ssize_t
-acpi_battery_write_alarm(struct file *file,
-			 const char __user * buffer,
-			 size_t count, loff_t * ppos)
+static ssize_t acpi_battery_write_alarm(struct file *file,
+					const char __user * buffer,
+					size_t count, loff_t * ppos)
 {
 	int result = 0;
 	char alarm_string[12] = { '\0' };
 	struct seq_file *m = file->private_data;
 	struct acpi_battery *battery = m->private;
-	int update_result = ACPI_BATTERY_NONE_UPDATE;
 
 	if (!battery || (count > sizeof(alarm_string) - 1))
 		return -EINVAL;
-
-	mutex_lock(&battery->mutex);
-
-	result = acpi_battery_update(battery, 1, &update_result);
 	if (result) {
 		result = -ENODEV;
 		goto end;
 	}
-
 	if (!acpi_battery_present(battery)) {
 		result = -ENODEV;
 		goto end;
 	}
-
 	if (copy_from_user(alarm_string, buffer, count)) {
 		result = -EFAULT;
 		goto end;
 	}
-
 	alarm_string[count] = '\0';
-
-	result = acpi_battery_set_alarm(battery,
-					simple_strtoul(alarm_string, NULL, 0));
-	if (result)
-		goto end;
-
+	battery->alarm = simple_strtol(alarm_string, NULL, 0);
+	result = acpi_battery_set_alarm(battery);
       end:
-
-	acpi_battery_check_result(battery, result);
-
 	if (!result)
-		result = count;
-
-	mutex_unlock(&battery->mutex);
-
+		return count;
 	return result;
 }
 
 typedef int(*print_func)(struct seq_file *seq, int result);
-typedef int(*get_func)(struct acpi_battery *battery);
 
-static struct acpi_read_mux {
-	print_func print;
-	get_func get;
-} acpi_read_funcs[ACPI_BATTERY_NUMFILES] = {
-	{.get = acpi_battery_get_info, .print = acpi_battery_print_info},
-	{.get = acpi_battery_get_state, .print = acpi_battery_print_state},
-	{.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm},
+static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
+	acpi_battery_print_info,
+	acpi_battery_print_state,
+	acpi_battery_print_alarm,
 };
 
 static int acpi_battery_read(int fid, struct seq_file *seq)
 {
 	struct acpi_battery *battery = seq->private;
-	int result = 0;
-	int update_result = ACPI_BATTERY_NONE_UPDATE;
-	int update = 0;
+	int result = acpi_battery_update(battery);
+	return acpi_print_funcs[fid](seq, result);
+}
 
-	mutex_lock(&battery->mutex);
+#define DECLARE_FILE_FUNCTIONS(_name) \
+static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
+{ \
+	return acpi_battery_read(_name##_tag, seq); \
+} \
+static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
+{ \
+	return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \
+}
 
-	update = (get_seconds() - battery->update_time[fid] >= update_time);
-	update = (update | battery->flags.update[fid]);
+DECLARE_FILE_FUNCTIONS(info);
+DECLARE_FILE_FUNCTIONS(state);
+DECLARE_FILE_FUNCTIONS(alarm);
 
-	result = acpi_battery_update(battery, update, &update_result);
-	if (result)
-		goto end;
+#undef DECLARE_FILE_FUNCTIONS
 
-	if (update_result == ACPI_BATTERY_EASY_UPDATE) {
-		result = acpi_read_funcs[fid].get(battery);
-		if (result)
-			goto end;
+#define FILE_DESCRIPTION_RO(_name) \
+	{ \
+	.name = __stringify(_name), \
+	.mode = S_IRUGO, \
+	.ops = { \
+		.open = acpi_battery_##_name##_open_fs, \
+		.read = seq_read, \
+		.llseek = seq_lseek, \
+		.release = single_release, \
+		.owner = THIS_MODULE, \
+		}, \
 	}
 
-      end:
-	result = acpi_read_funcs[fid].print(seq, result);
-	acpi_battery_check_result(battery, result);
-	battery->flags.update[fid] = result;
-	mutex_unlock(&battery->mutex);
-	return result;
-}
-
-static int acpi_battery_read_info(struct seq_file *seq, void *offset)
-{
-	return acpi_battery_read(ACPI_BATTERY_INFO, seq);
-}
-
-static int acpi_battery_read_state(struct seq_file *seq, void *offset)
-{
-	return acpi_battery_read(ACPI_BATTERY_STATE, seq);
-}
-
-static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
-{
-	return acpi_battery_read(ACPI_BATTERY_ALARM, seq);
-}
-
-static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_battery_read_info, PDE(inode)->data);
-}
-
-static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_battery_read_state, PDE(inode)->data);
-}
-
-static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
-}
+#define FILE_DESCRIPTION_RW(_name) \
+	{ \
+	.name = __stringify(_name), \
+	.mode = S_IFREG | S_IRUGO | S_IWUSR, \
+	.ops = { \
+		.open = acpi_battery_##_name##_open_fs, \
+		.read = seq_read, \
+		.llseek = seq_lseek, \
+		.write = acpi_battery_write_##_name, \
+		.release = single_release, \
+		.owner = THIS_MODULE, \
+		}, \
+	}
 
 static struct battery_file {
 	struct file_operations ops;
 	mode_t mode;
 	char *name;
 } acpi_battery_file[] = {
-	{
-	.name = "info",
-	.mode = S_IRUGO,
-	.ops = {
-	.open = acpi_battery_info_open_fs,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-	.owner = THIS_MODULE,
-	},
-	},
-	{
-	.name = "state",
-	.mode = S_IRUGO,
-	.ops = {
-	.open = acpi_battery_state_open_fs,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-	.owner = THIS_MODULE,
-	},
-	},
-	{
-	.name = "alarm",
-	.mode = S_IFREG | S_IRUGO | S_IWUSR,
-	.ops = {
-	.open = acpi_battery_alarm_open_fs,
-	.read = seq_read,
-	.write = acpi_battery_write_alarm,
-	.llseek = seq_lseek,
-	.release = single_release,
-	.owner = THIS_MODULE,
-	},
-	},
+	FILE_DESCRIPTION_RO(info),
+	FILE_DESCRIPTION_RO(state),
+	FILE_DESCRIPTION_RW(alarm),
 };
 
+#undef FILE_DESCRIPTION_RO
+#undef FILE_DESCRIPTION_RW
+
 static int acpi_battery_add_fs(struct acpi_device *device)
 {
 	struct proc_dir_entry *entry = NULL;
@@ -832,25 +670,51 @@
 			entry->owner = THIS_MODULE;
 		}
 	}
-
 	return 0;
 }
 
-static int acpi_battery_remove_fs(struct acpi_device *device)
+static void acpi_battery_remove_fs(struct acpi_device *device)
 {
 	int i;
-	if (acpi_device_dir(device)) {
-		for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
-			remove_proc_entry(acpi_battery_file[i].name,
+	if (!acpi_device_dir(device))
+		return;
+	for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)
+		remove_proc_entry(acpi_battery_file[i].name,
 				  acpi_device_dir(device));
-		}
-		remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
-		acpi_device_dir(device) = NULL;
-	}
 
-	return 0;
+	remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
+	acpi_device_dir(device) = NULL;
 }
 
+#endif
+
+static ssize_t acpi_battery_alarm_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+	return sprintf(buf, "%d\n", battery->alarm * 1000);
+}
+
+static ssize_t acpi_battery_alarm_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	unsigned long x;
+	struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+	if (sscanf(buf, "%ld\n", &x) == 1)
+		battery->alarm = x/1000;
+	if (acpi_battery_present(battery))
+		acpi_battery_set_alarm(battery);
+	return count;
+}
+
+static struct device_attribute alarm_attr = {
+	.attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
+	.show = acpi_battery_alarm_show,
+	.store = acpi_battery_alarm_store,
+};
+
 /* --------------------------------------------------------------------------
                                  Driver Interface
    -------------------------------------------------------------------------- */
@@ -858,33 +722,17 @@
 static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
 {
 	struct acpi_battery *battery = data;
-	struct acpi_device *device = NULL;
-
+	struct acpi_device *device;
 	if (!battery)
 		return;
-
 	device = battery->device;
-
-	switch (event) {
-	case ACPI_BATTERY_NOTIFY_STATUS:
-	case ACPI_BATTERY_NOTIFY_INFO:
-	case ACPI_NOTIFY_BUS_CHECK:
-	case ACPI_NOTIFY_DEVICE_CHECK:
-		device = battery->device;
-		acpi_battery_notify_update(battery);
-		acpi_bus_generate_proc_event(device, event,
+	acpi_battery_update(battery);
+	acpi_bus_generate_proc_event(device, event,
+				     acpi_battery_present(battery));
+	acpi_bus_generate_netlink_event(device->pnp.device_class,
+					device->dev.bus_id, event,
 					acpi_battery_present(battery));
-		acpi_bus_generate_netlink_event(device->pnp.device_class,
-						  device->dev.bus_id, event,
-						  acpi_battery_present(battery));
-		break;
-	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Unsupported event [0x%x]\n", event));
-		break;
-	}
-
-	return;
+	kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
 }
 
 static int acpi_battery_add(struct acpi_device *device)
@@ -892,33 +740,27 @@
 	int result = 0;
 	acpi_status status = 0;
 	struct acpi_battery *battery = NULL;
-
 	if (!device)
 		return -EINVAL;
-
 	battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
 	if (!battery)
 		return -ENOMEM;
-
-	mutex_init(&battery->mutex);
-
-	mutex_lock(&battery->mutex);
-
 	battery->device = device;
 	strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
 	acpi_driver_data(device) = battery;
-
-	result = acpi_battery_get_status(battery);
-	if (result)
-		goto end;
-
-	battery->flags.init_update = 1;
-
+	mutex_init(&battery->lock);
+	acpi_battery_update(battery);
+#ifdef CONFIG_ACPI_PROCFS
 	result = acpi_battery_add_fs(device);
 	if (result)
 		goto end;
-
+#endif
+	battery->bat.name = acpi_device_bid(device);
+	battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+	battery->bat.get_property = acpi_battery_get_property;
+	result = power_supply_register(&battery->device->dev, &battery->bat);
+	result = device_create_file(battery->bat.dev, &alarm_attr);
 	status = acpi_install_notify_handler(device->handle,
 					     ACPI_ALL_NOTIFY,
 					     acpi_battery_notify, battery);
@@ -927,20 +769,16 @@
 		result = -ENODEV;
 		goto end;
 	}
-
 	printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
 	       ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
 	       device->status.battery_present ? "present" : "absent");
-
       end:
-
 	if (result) {
+#ifdef CONFIG_ACPI_PROCFS
 		acpi_battery_remove_fs(device);
+#endif
 		kfree(battery);
 	}
-
-	mutex_unlock(&battery->mutex);
-
 	return result;
 }
 
@@ -951,27 +789,19 @@
 
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
-
 	battery = acpi_driver_data(device);
-
-	mutex_lock(&battery->mutex);
-
 	status = acpi_remove_notify_handler(device->handle,
 					    ACPI_ALL_NOTIFY,
 					    acpi_battery_notify);
-
+#ifdef CONFIG_ACPI_PROCFS
 	acpi_battery_remove_fs(device);
-
-	kfree(battery->bif_data.pointer);
-
-	kfree(battery->bst_data.pointer);
-
-	mutex_unlock(&battery->mutex);
-
-	mutex_destroy(&battery->mutex);
-
+#endif
+	if (battery->bat.dev) {
+		device_remove_file(battery->bat.dev, &alarm_attr);
+		power_supply_unregister(&battery->bat);
+	}
+	mutex_destroy(&battery->lock);
 	kfree(battery);
-
 	return 0;
 }
 
@@ -979,44 +809,48 @@
 static int acpi_battery_resume(struct acpi_device *device)
 {
 	struct acpi_battery *battery;
-
 	if (!device)
 		return -EINVAL;
-
-	battery = device->driver_data;
-
-	battery->flags.init_update = 1;
-
+	battery = acpi_driver_data(device);
+	battery->update_time = 0;
 	return 0;
 }
 
+static struct acpi_driver acpi_battery_driver = {
+	.name = "battery",
+	.class = ACPI_BATTERY_CLASS,
+	.ids = battery_device_ids,
+	.ops = {
+		.add = acpi_battery_add,
+		.resume = acpi_battery_resume,
+		.remove = acpi_battery_remove,
+		},
+};
+
 static int __init acpi_battery_init(void)
 {
-	int result;
-
 	if (acpi_disabled)
 		return -ENODEV;
-
+#ifdef CONFIG_ACPI_PROCFS
 	acpi_battery_dir = acpi_lock_battery_dir();
 	if (!acpi_battery_dir)
 		return -ENODEV;
-
-	result = acpi_bus_register_driver(&acpi_battery_driver);
-	if (result < 0) {
+#endif
+	if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
+#ifdef CONFIG_ACPI_PROCFS
 		acpi_unlock_battery_dir(acpi_battery_dir);
+#endif
 		return -ENODEV;
 	}
-
 	return 0;
 }
 
 static void __exit acpi_battery_exit(void)
 {
 	acpi_bus_unregister_driver(&acpi_battery_driver);
-
+#ifdef CONFIG_ACPI_PROCFS
 	acpi_unlock_battery_dir(acpi_battery_dir);
-
-	return;
+#endif
 }
 
 module_init(acpi_battery_init);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index cbfc815..fb2cff9 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -286,15 +286,11 @@
 
 extern int event_is_open;
 
-int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
+int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
 {
-	struct acpi_bus_event *event = NULL;
+	struct acpi_bus_event *event;
 	unsigned long flags = 0;
 
-
-	if (!device)
-		return -EINVAL;
-
 	/* drop event on the floor if no one's listening */
 	if (!event_is_open)
 		return 0;
@@ -303,8 +299,8 @@
 	if (!event)
 		return -ENOMEM;
 
-	strcpy(event->device_class, device->pnp.device_class);
-	strcpy(event->bus_id, device->pnp.bus_id);
+	strcpy(event->device_class, device_class);
+	strcpy(event->bus_id, bus_id);
 	event->type = type;
 	event->data = data;
 
@@ -315,6 +311,17 @@
 	wake_up_interruptible(&acpi_bus_event_queue);
 
 	return 0;
+
+}
+
+EXPORT_SYMBOL_GPL(acpi_bus_generate_proc_event4);
+
+int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
+{
+	if (!device)
+		return -EINVAL;
+	return acpi_bus_generate_proc_event4(device->pnp.device_class,
+					     device->pnp.bus_id, type, data);
 }
 
 EXPORT_SYMBOL(acpi_bus_generate_proc_event);
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 2e79a33..301e832 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -434,18 +434,18 @@
 	switch (button->type) {
 	case ACPI_BUTTON_TYPE_POWER:
 	case ACPI_BUTTON_TYPE_POWERF:
-		input->evbit[0] = BIT(EV_KEY);
+		input->evbit[0] = BIT_MASK(EV_KEY);
 		set_bit(KEY_POWER, input->keybit);
 		break;
 
 	case ACPI_BUTTON_TYPE_SLEEP:
 	case ACPI_BUTTON_TYPE_SLEEPF:
-		input->evbit[0] = BIT(EV_KEY);
+		input->evbit[0] = BIT_MASK(EV_KEY);
 		set_bit(KEY_SLEEP, input->keybit);
 		break;
 
 	case ACPI_BUTTON_TYPE_LID:
-		input->evbit[0] = BIT(EV_SW);
+		input->evbit[0] = BIT_MASK(EV_SW);
 		set_bit(SW_LID, input->swbit);
 		break;
 	}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 3f7935a..7b41783 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -121,6 +121,7 @@
 	atomic_t event_count;
 	wait_queue_head_t wait;
 	struct list_head list;
+	u8 handlers_installed;
 } *boot_ec, *first_ec;
 
 /* --------------------------------------------------------------------------
@@ -425,7 +426,7 @@
 	handler->func = func;
 	handler->data = data;
 	mutex_lock(&ec->lock);
-	list_add_tail(&handler->node, &ec->list);
+	list_add(&handler->node, &ec->list);
 	mutex_unlock(&ec->lock);
 	return 0;
 }
@@ -440,7 +441,6 @@
 		if (query_bit == handler->query_bit) {
 			list_del(&handler->node);
 			kfree(handler);
-			break;
 		}
 	}
 	mutex_unlock(&ec->lock);
@@ -680,32 +680,50 @@
 	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
 	if (ACPI_FAILURE(status))
 		return status;
-
 	/* Find and register all query methods */
 	acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
 			    acpi_ec_register_query_methods, ec, NULL);
-
 	/* Use the global lock for all EC transactions? */
 	acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
-
 	ec->handle = handle;
-
-	printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
-			  ec->gpe, ec->command_addr, ec->data_addr);
-
 	return AE_CTRL_TERMINATE;
 }
 
+static void ec_remove_handlers(struct acpi_ec *ec)
+{
+	if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
+				ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
+		printk(KERN_ERR PREFIX "failed to remove space handler\n");
+	if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
+				&acpi_ec_gpe_handler)))
+		printk(KERN_ERR PREFIX "failed to remove gpe handler\n");
+	ec->handlers_installed = 0;
+}
+
 static int acpi_ec_add(struct acpi_device *device)
 {
 	struct acpi_ec *ec = NULL;
 
 	if (!device)
 		return -EINVAL;
-
 	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 
+	/* Check for boot EC */
+	if (boot_ec) {
+		if (boot_ec->handle == device->handle) {
+			/* Pre-loaded EC from DSDT, just move pointer */
+			ec = boot_ec;
+			boot_ec = NULL;
+			goto end;
+		} else if (boot_ec->handle == ACPI_ROOT_OBJECT) {
+			/* ECDT-based EC, time to shut it down */
+			ec_remove_handlers(boot_ec);
+			kfree(boot_ec);
+			first_ec = boot_ec = NULL;
+		}
+	}
+
 	ec = make_acpi_ec();
 	if (!ec)
 		return -ENOMEM;
@@ -715,25 +733,14 @@
 		kfree(ec);
 		return -EINVAL;
 	}
-
-	/* Check if we found the boot EC */
-	if (boot_ec) {
-		if (boot_ec->gpe == ec->gpe) {
-			/* We might have incorrect info for GL at boot time */
-			mutex_lock(&boot_ec->lock);
-			boot_ec->global_lock = ec->global_lock;
-			/* Copy handlers from new ec into boot ec */
-			list_splice(&ec->list, &boot_ec->list);
-			mutex_unlock(&boot_ec->lock);
-			kfree(ec);
-			ec = boot_ec;
-		}
-	} else
-		first_ec = ec;
 	ec->handle = device->handle;
+      end:
+	if (!first_ec)
+		first_ec = ec;
 	acpi_driver_data(device) = ec;
-
 	acpi_ec_add_fs(device);
+	printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
+			  ec->gpe, ec->command_addr, ec->data_addr);
 	return 0;
 }
 
@@ -756,10 +763,7 @@
 	acpi_driver_data(device) = NULL;
 	if (ec == first_ec)
 		first_ec = NULL;
-
-	/* Don't touch boot EC */
-	if (boot_ec != ec)
-		kfree(ec);
+	kfree(ec);
 	return 0;
 }
 
@@ -789,6 +793,8 @@
 static int ec_install_handlers(struct acpi_ec *ec)
 {
 	acpi_status status;
+	if (ec->handlers_installed)
+		return 0;
 	status = acpi_install_gpe_handler(NULL, ec->gpe,
 					  ACPI_GPE_EDGE_TRIGGERED,
 					  &acpi_ec_gpe_handler, ec);
@@ -807,6 +813,7 @@
 		return -ENODEV;
 	}
 
+	ec->handlers_installed = 1;
 	return 0;
 }
 
@@ -823,41 +830,22 @@
 	if (!ec)
 		return -EINVAL;
 
-	/* Boot EC is already working */
-	if (ec != boot_ec)
-		ret = ec_install_handlers(ec);
+	ret = ec_install_handlers(ec);
 
 	/* EC is fully operational, allow queries */
 	atomic_set(&ec->query_pending, 0);
-
 	return ret;
 }
 
 static int acpi_ec_stop(struct acpi_device *device, int type)
 {
-	acpi_status status;
 	struct acpi_ec *ec;
-
 	if (!device)
 		return -EINVAL;
-
 	ec = acpi_driver_data(device);
 	if (!ec)
 		return -EINVAL;
-
-	/* Don't touch boot EC */
-	if (ec == boot_ec)
-		return 0;
-
-	status = acpi_remove_address_space_handler(ec->handle,
-						   ACPI_ADR_SPACE_EC,
-						   &acpi_ec_space_handler);
-	if (ACPI_FAILURE(status))
-		return -ENODEV;
-
-	status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
-	if (ACPI_FAILURE(status))
-		return -ENODEV;
+	ec_remove_handlers(ec);
 
 	return 0;
 }
@@ -877,7 +865,7 @@
 	status = acpi_get_table(ACPI_SIG_ECDT, 1,
 				(struct acpi_table_header **)&ecdt_ptr);
 	if (ACPI_SUCCESS(status)) {
-		printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n");
+		printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
 		boot_ec->command_addr = ecdt_ptr->control.address;
 		boot_ec->data_addr = ecdt_ptr->data.address;
 		boot_ec->gpe = ecdt_ptr->gpe;
@@ -899,7 +887,6 @@
       error:
 	kfree(boot_ec);
 	boot_ec = NULL;
-
 	return -ENODEV;
 }
 
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index a1f87b5..e412878 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -239,10 +239,8 @@
 	 * Read the fixed feature status and enable registers, as all the cases
 	 * depend on their values.  Ignore errors here.
 	 */
-	(void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-				    ACPI_REGISTER_PM1_STATUS, &fixed_status);
-	(void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-				    ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
+	(void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
+	(void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
 			  "Fixed Event Block: Enable %08X Status %08X\n",
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index 1d371fa..73f9c5f 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -75,8 +75,7 @@
 
 	lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
 
-	status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-					ACPI_REGISTER_PM1_STATUS,
+	status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
 					ACPI_BITMASK_ALL_FIXED_STATUS);
 	if (ACPI_FAILURE(status)) {
 		goto unlock_and_exit;
@@ -259,7 +258,7 @@
  *
  ******************************************************************************/
 
-acpi_status acpi_get_register(u32 register_id, u32 * return_value)
+acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value)
 {
 	u32 register_value = 0;
 	struct acpi_bit_register_info *bit_reg_info;
@@ -276,8 +275,7 @@
 
 	/* Read from the register */
 
-	status = acpi_hw_register_read(ACPI_MTX_LOCK,
-				       bit_reg_info->parent_register,
+	status = acpi_hw_register_read(bit_reg_info->parent_register,
 				       &register_value);
 
 	if (ACPI_SUCCESS(status)) {
@@ -298,6 +296,16 @@
 	return_ACPI_STATUS(status);
 }
 
+acpi_status acpi_get_register(u32 register_id, u32 * return_value)
+{
+	acpi_status status;
+	acpi_cpu_flags flags;
+	flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
+	status = acpi_get_register_unlocked(register_id, return_value);
+	acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
+	return status;
+}
+
 ACPI_EXPORT_SYMBOL(acpi_get_register)
 
 /*******************************************************************************
@@ -335,8 +343,7 @@
 
 	/* Always do a register read first so we can insert the new bits  */
 
-	status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-				       bit_reg_info->parent_register,
+	status = acpi_hw_register_read(bit_reg_info->parent_register,
 				       &register_value);
 	if (ACPI_FAILURE(status)) {
 		goto unlock_and_exit;
@@ -363,8 +370,7 @@
 						   bit_reg_info->
 						   access_bit_mask);
 		if (value) {
-			status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-							ACPI_REGISTER_PM1_STATUS,
+			status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
 							(u16) value);
 			register_value = 0;
 		}
@@ -377,8 +383,7 @@
 					   bit_reg_info->access_bit_mask,
 					   value);
 
-		status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-						ACPI_REGISTER_PM1_ENABLE,
+		status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
 						(u16) register_value);
 		break;
 
@@ -397,15 +402,13 @@
 					   bit_reg_info->access_bit_mask,
 					   value);
 
-		status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-						ACPI_REGISTER_PM1_CONTROL,
+		status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
 						(u16) register_value);
 		break;
 
 	case ACPI_REGISTER_PM2_CONTROL:
 
-		status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-					       ACPI_REGISTER_PM2_CONTROL,
+		status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
 					       &register_value);
 		if (ACPI_FAILURE(status)) {
 			goto unlock_and_exit;
@@ -430,8 +433,7 @@
 						     xpm2_control_block.
 						     address)));
 
-		status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-						ACPI_REGISTER_PM2_CONTROL,
+		status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
 						(u8) (register_value));
 		break;
 
@@ -461,8 +463,7 @@
  *
  * FUNCTION:    acpi_hw_register_read
  *
- * PARAMETERS:  use_lock            - Lock hardware? True/False
- *              register_id         - ACPI Register ID
+ * PARAMETERS:  register_id         - ACPI Register ID
  *              return_value        - Where the register value is returned
  *
  * RETURN:      Status and the value read.
@@ -471,19 +472,14 @@
  *
  ******************************************************************************/
 acpi_status
-acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
+acpi_hw_register_read(u32 register_id, u32 * return_value)
 {
 	u32 value1 = 0;
 	u32 value2 = 0;
 	acpi_status status;
-	acpi_cpu_flags lock_flags = 0;
 
 	ACPI_FUNCTION_TRACE(hw_register_read);
 
-	if (ACPI_MTX_LOCK == use_lock) {
-		lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
-	}
-
 	switch (register_id) {
 	case ACPI_REGISTER_PM1_STATUS:	/* 16-bit access */
 
@@ -491,7 +487,7 @@
 		    acpi_hw_low_level_read(16, &value1,
 					   &acpi_gbl_FADT.xpm1a_event_block);
 		if (ACPI_FAILURE(status)) {
-			goto unlock_and_exit;
+			goto exit;
 		}
 
 		/* PM1B is optional */
@@ -507,7 +503,7 @@
 		status =
 		    acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable);
 		if (ACPI_FAILURE(status)) {
-			goto unlock_and_exit;
+			goto exit;
 		}
 
 		/* PM1B is optional */
@@ -523,7 +519,7 @@
 		    acpi_hw_low_level_read(16, &value1,
 					   &acpi_gbl_FADT.xpm1a_control_block);
 		if (ACPI_FAILURE(status)) {
-			goto unlock_and_exit;
+			goto exit;
 		}
 
 		status =
@@ -558,10 +554,7 @@
 		break;
 	}
 
-      unlock_and_exit:
-	if (ACPI_MTX_LOCK == use_lock) {
-		acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
-	}
+      exit:
 
 	if (ACPI_SUCCESS(status)) {
 		*return_value = value1;
@@ -574,8 +567,7 @@
  *
  * FUNCTION:    acpi_hw_register_write
  *
- * PARAMETERS:  use_lock            - Lock hardware? True/False
- *              register_id         - ACPI Register ID
+ * PARAMETERS:  register_id         - ACPI Register ID
  *              Value               - The value to write
  *
  * RETURN:      Status
@@ -597,28 +589,22 @@
  *
  ******************************************************************************/
 
-acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
+acpi_status acpi_hw_register_write(u32 register_id, u32 value)
 {
 	acpi_status status;
-	acpi_cpu_flags lock_flags = 0;
 	u32 read_value;
 
 	ACPI_FUNCTION_TRACE(hw_register_write);
 
-	if (ACPI_MTX_LOCK == use_lock) {
-		lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
-	}
-
 	switch (register_id) {
 	case ACPI_REGISTER_PM1_STATUS:	/* 16-bit access */
 
 		/* Perform a read first to preserve certain bits (per ACPI spec) */
 
-		status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-					       ACPI_REGISTER_PM1_STATUS,
+		status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
 					       &read_value);
 		if (ACPI_FAILURE(status)) {
-			goto unlock_and_exit;
+			goto exit;
 		}
 
 		/* Insert the bits to be preserved */
@@ -632,7 +618,7 @@
 		    acpi_hw_low_level_write(16, value,
 					    &acpi_gbl_FADT.xpm1a_event_block);
 		if (ACPI_FAILURE(status)) {
-			goto unlock_and_exit;
+			goto exit;
 		}
 
 		/* PM1B is optional */
@@ -647,7 +633,7 @@
 		status =
 		    acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable);
 		if (ACPI_FAILURE(status)) {
-			goto unlock_and_exit;
+			goto exit;
 		}
 
 		/* PM1B is optional */
@@ -661,11 +647,10 @@
 		/*
 		 * Perform a read first to preserve certain bits (per ACPI spec)
 		 */
-		status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-					       ACPI_REGISTER_PM1_CONTROL,
+		status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
 					       &read_value);
 		if (ACPI_FAILURE(status)) {
-			goto unlock_and_exit;
+			goto exit;
 		}
 
 		/* Insert the bits to be preserved */
@@ -679,7 +664,7 @@
 		    acpi_hw_low_level_write(16, value,
 					    &acpi_gbl_FADT.xpm1a_control_block);
 		if (ACPI_FAILURE(status)) {
-			goto unlock_and_exit;
+			goto exit;
 		}
 
 		status =
@@ -728,11 +713,7 @@
 		break;
 	}
 
-      unlock_and_exit:
-	if (ACPI_MTX_LOCK == use_lock) {
-		acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
-	}
-
+      exit:
 	return_ACPI_STATUS(status);
 }
 
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index cf69c00..81b2484 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -234,15 +234,11 @@
 				"While executing method _SST"));
 	}
 
-	/*
-	 * 1) Disable/Clear all GPEs
-	 */
-	status = acpi_hw_disable_all_gpes();
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
+	/* Disable/Clear all GPEs */
 
-	return_ACPI_STATUS(AE_OK);
+	status = acpi_hw_disable_all_gpes();
+
+	return_ACPI_STATUS(status);
 }
 
 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
@@ -313,8 +309,7 @@
 
 	/* Get current value of PM1A control */
 
-	status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-				       ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+	status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -341,15 +336,13 @@
 
 	/* Write #1: fill in SLP_TYP data */
 
-	status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-					ACPI_REGISTER_PM1A_CONTROL,
+	status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
 					PM1Acontrol);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
-	status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-					ACPI_REGISTER_PM1B_CONTROL,
+	status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
 					PM1Bcontrol);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
@@ -364,15 +357,13 @@
 
 	ACPI_FLUSH_CPU_CACHE();
 
-	status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-					ACPI_REGISTER_PM1A_CONTROL,
+	status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
 					PM1Acontrol);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
-	status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-					ACPI_REGISTER_PM1B_CONTROL,
+	status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
 					PM1Bcontrol);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
@@ -392,8 +383,7 @@
 		 */
 		acpi_os_stall(10000000);
 
-		status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-						ACPI_REGISTER_PM1_CONTROL,
+		status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
 						sleep_enable_reg_info->
 						access_bit_mask);
 		if (ACPI_FAILURE(status)) {
@@ -404,7 +394,8 @@
 	/* Wait until we enter sleep state */
 
 	do {
-		status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
+		status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
+						    &in_value);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
@@ -520,8 +511,7 @@
 
 		/* Get current value of PM1A control */
 
-		status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
-					       ACPI_REGISTER_PM1_CONTROL,
+		status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
 					       &PM1Acontrol);
 		if (ACPI_SUCCESS(status)) {
 
@@ -543,11 +533,9 @@
 
 			/* Just ignore any errors */
 
-			(void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-						     ACPI_REGISTER_PM1A_CONTROL,
+			(void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
 						     PM1Acontrol);
-			(void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-						     ACPI_REGISTER_PM1B_CONTROL,
+			(void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
 						     PM1Bcontrol);
 		}
 	}
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 352cf81..aabc6ca 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1043,14 +1043,6 @@
 __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
 
 /*
- * max_cstate is defined in the base kernel so modules can
- * change it w/o depending on the state of the processor module.
- */
-unsigned int max_cstate = ACPI_PROCESSOR_MAX_POWER;
-
-EXPORT_SYMBOL(max_cstate);
-
-/*
  * Acquire a spinlock.
  *
  * handle is a pointer to the spinlock_t.
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 9f11dc2..235a51e 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -44,6 +44,7 @@
 #include <linux/seq_file.h>
 #include <linux/dmi.h>
 #include <linux/moduleparam.h>
+#include <linux/cpuidle.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -421,12 +422,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_IA64
-#define arch_cpu_to_apicid 	ia64_cpu_to_sapicid
-#else
-#define arch_cpu_to_apicid 	x86_cpu_to_apicid
-#endif
-
 static int map_madt_entry(u32 acpi_id)
 {
 	unsigned long madt_end, entry;
@@ -500,7 +495,7 @@
 		return apic_id;
 
 	for (i = 0; i < NR_CPUS; ++i) {
-		if (arch_cpu_to_apicid[i] == apic_id)
+		if (cpu_physical_id(i) == apic_id)
 			return i;
 	}
 	return -1;
@@ -1049,11 +1044,13 @@
 		return -ENOMEM;
 	acpi_processor_dir->owner = THIS_MODULE;
 
+	result = cpuidle_register_driver(&acpi_idle_driver);
+	if (result < 0)
+		goto out_proc;
+
 	result = acpi_bus_register_driver(&acpi_processor_driver);
-	if (result < 0) {
-		remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
-		return result;
-	}
+	if (result < 0)
+		goto out_cpuidle;
 
 	acpi_processor_install_hotplug_notify();
 
@@ -1062,11 +1059,18 @@
 	acpi_processor_ppc_init();
 
 	return 0;
+
+out_cpuidle:
+	cpuidle_unregister_driver(&acpi_idle_driver);
+
+out_proc:
+	remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+
+	return result;
 }
 
 static void __exit acpi_processor_exit(void)
 {
-
 	acpi_processor_ppc_exit();
 
 	acpi_thermal_cpufreq_exit();
@@ -1075,6 +1079,8 @@
 
 	acpi_bus_unregister_driver(&acpi_processor_driver);
 
+	cpuidle_unregister_driver(&acpi_idle_driver);
+
 	remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
 
 	return;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 1f6fb38..f996d0e 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -40,6 +40,7 @@
 #include <linux/sched.h>	/* need_resched() */
 #include <linux/latency.h>
 #include <linux/clockchips.h>
+#include <linux/cpuidle.h>
 
 /*
  * Include the apic definitions for x86 to have the APIC timer related defines
@@ -64,14 +65,22 @@
 #define ACPI_PROCESSOR_FILE_POWER	"power"
 #define US_TO_PM_TIMER_TICKS(t)		((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
 #define PM_TIMER_TICK_NS		(1000000000ULL/PM_TIMER_FREQUENCY)
+#ifndef CONFIG_CPU_IDLE
 #define C2_OVERHEAD			4	/* 1us (3.579 ticks per us) */
 #define C3_OVERHEAD			4	/* 1us (3.579 ticks per us) */
 static void (*pm_idle_save) (void) __read_mostly;
-module_param(max_cstate, uint, 0644);
+#else
+#define C2_OVERHEAD			1	/* 1us */
+#define C3_OVERHEAD			1	/* 1us */
+#endif
+#define PM_TIMER_TICKS_TO_US(p)		(((p) * 1000)/(PM_TIMER_FREQUENCY/1000))
 
+static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
+module_param(max_cstate, uint, 0000);
 static unsigned int nocst __read_mostly;
 module_param(nocst, uint, 0000);
 
+#ifndef CONFIG_CPU_IDLE
 /*
  * bm_history -- bit-mask with a bit per jiffy of bus-master activity
  * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms
@@ -82,9 +91,10 @@
 static unsigned int bm_history __read_mostly =
     (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
 module_param(bm_history, uint, 0644);
-/* --------------------------------------------------------------------------
-                                Power Management
-   -------------------------------------------------------------------------- */
+
+static int acpi_processor_set_power_policy(struct acpi_processor *pr);
+
+#endif
 
 /*
  * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
@@ -177,6 +187,18 @@
 		return ((0xFFFFFFFF - t1) + t2);
 }
 
+static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
+{
+	if (t2 >= t1)
+		return PM_TIMER_TICKS_TO_US(t2 - t1);
+	else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
+		return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
+	else
+		return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
+}
+
+#ifndef CONFIG_CPU_IDLE
+
 static void
 acpi_processor_power_activate(struct acpi_processor *pr,
 			      struct acpi_processor_cx *new)
@@ -248,6 +270,7 @@
 		unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
 	}
 }
+#endif /* !CONFIG_CPU_IDLE */
 
 #ifdef ARCH_APICTIMER_STOPS_ON_C3
 
@@ -330,6 +353,7 @@
 	return 0;
 }
 
+#ifndef CONFIG_CPU_IDLE
 static void acpi_processor_idle(void)
 {
 	struct acpi_processor *pr = NULL;
@@ -427,7 +451,7 @@
 	 * an SMP system. We do it here instead of doing it at _CST/P_LVL
 	 * detection phase, to work cleanly with logical CPU hotplug.
 	 */
-	if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && 
+	if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
 	    !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
 		cx = &pr->power.states[ACPI_STATE_C1];
 #endif
@@ -727,6 +751,7 @@
 
 	return 0;
 }
+#endif /* !CONFIG_CPU_IDLE */
 
 static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
 {
@@ -744,7 +769,7 @@
 #ifndef CONFIG_HOTPLUG_CPU
 	/*
 	 * Check for P_LVL2_UP flag before entering C2 and above on
-	 * an SMP system. 
+	 * an SMP system.
 	 */
 	if ((num_online_cpus() > 1) &&
 	    !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
@@ -945,7 +970,12 @@
 	 * Normalize the C2 latency to expidite policy
 	 */
 	cx->valid = 1;
+
+#ifndef CONFIG_CPU_IDLE
 	cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
+#else
+	cx->latency_ticks = cx->latency;
+#endif
 
 	return;
 }
@@ -1025,7 +1055,12 @@
 	 * use this in our C3 policy
 	 */
 	cx->valid = 1;
+
+#ifndef CONFIG_CPU_IDLE
 	cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
+#else
+	cx->latency_ticks = cx->latency;
+#endif
 
 	return;
 }
@@ -1090,6 +1125,7 @@
 
 	pr->power.count = acpi_processor_power_verify(pr);
 
+#ifndef CONFIG_CPU_IDLE
 	/*
 	 * Set Default Policy
 	 * ------------------
@@ -1101,6 +1137,7 @@
 	result = acpi_processor_set_power_policy(pr);
 	if (result)
 		return result;
+#endif
 
 	/*
 	 * if one state of type C2 or C3 is available, mark this
@@ -1117,35 +1154,6 @@
 	return 0;
 }
 
-int acpi_processor_cst_has_changed(struct acpi_processor *pr)
-{
-	int result = 0;
-
-
-	if (!pr)
-		return -EINVAL;
-
-	if (nocst) {
-		return -ENODEV;
-	}
-
-	if (!pr->flags.power_setup_done)
-		return -ENODEV;
-
-	/* Fall back to the default idle loop */
-	pm_idle = pm_idle_save;
-	synchronize_sched();	/* Relies on interrupts forcing exit from idle. */
-
-	pr->flags.power = 0;
-	result = acpi_processor_get_power_info(pr);
-	if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
-		pm_idle = acpi_processor_idle;
-
-	return result;
-}
-
-/* proc interface */
-
 static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
 {
 	struct acpi_processor *pr = seq->private;
@@ -1227,6 +1235,35 @@
 	.release = single_release,
 };
 
+#ifndef CONFIG_CPU_IDLE
+
+int acpi_processor_cst_has_changed(struct acpi_processor *pr)
+{
+	int result = 0;
+
+
+	if (!pr)
+		return -EINVAL;
+
+	if (nocst) {
+		return -ENODEV;
+	}
+
+	if (!pr->flags.power_setup_done)
+		return -ENODEV;
+
+	/* Fall back to the default idle loop */
+	pm_idle = pm_idle_save;
+	synchronize_sched();	/* Relies on interrupts forcing exit from idle. */
+
+	pr->flags.power = 0;
+	result = acpi_processor_get_power_info(pr);
+	if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
+		pm_idle = acpi_processor_idle;
+
+	return result;
+}
+
 #ifdef CONFIG_SMP
 static void smp_callback(void *v)
 {
@@ -1249,8 +1286,367 @@
 static struct notifier_block acpi_processor_latency_notifier = {
 	.notifier_call = acpi_processor_latency_notify,
 };
+
 #endif
 
+#else /* CONFIG_CPU_IDLE */
+
+/**
+ * acpi_idle_bm_check - checks if bus master activity was detected
+ */
+static int acpi_idle_bm_check(void)
+{
+	u32 bm_status = 0;
+
+	acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+	if (bm_status)
+		acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
+	/*
+	 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
+	 * the true state of bus mastering activity; forcing us to
+	 * manually check the BMIDEA bit of each IDE channel.
+	 */
+	else if (errata.piix4.bmisx) {
+		if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
+		    || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
+			bm_status = 1;
+	}
+	return bm_status;
+}
+
+/**
+ * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state
+ * @pr: the processor
+ * @target: the new target state
+ */
+static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr,
+					   struct acpi_processor_cx *target)
+{
+	if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) {
+		acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
+		pr->flags.bm_rld_set = 0;
+	}
+
+	if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) {
+		acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
+		pr->flags.bm_rld_set = 1;
+	}
+}
+
+/**
+ * acpi_idle_do_entry - a helper function that does C2 and C3 type entry
+ * @cx: cstate data
+ */
+static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
+{
+	if (cx->space_id == ACPI_CSTATE_FFH) {
+		/* Call into architectural FFH based C-state */
+		acpi_processor_ffh_cstate_enter(cx);
+	} else {
+		int unused;
+		/* IO port based C-state */
+		inb(cx->address);
+		/* Dummy wait op - must do something useless after P_LVL2 read
+		   because chipsets cannot guarantee that STPCLK# signal
+		   gets asserted in time to freeze execution properly. */
+		unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	}
+}
+
+/**
+ * acpi_idle_enter_c1 - enters an ACPI C1 state-type
+ * @dev: the target CPU
+ * @state: the state data
+ *
+ * This is equivalent to the HALT instruction.
+ */
+static int acpi_idle_enter_c1(struct cpuidle_device *dev,
+			      struct cpuidle_state *state)
+{
+	struct acpi_processor *pr;
+	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
+	pr = processors[smp_processor_id()];
+
+	if (unlikely(!pr))
+		return 0;
+
+	if (pr->flags.bm_check)
+		acpi_idle_update_bm_rld(pr, cx);
+
+	current_thread_info()->status &= ~TS_POLLING;
+	/*
+	 * TS_POLLING-cleared state must be visible before we test
+	 * NEED_RESCHED:
+	 */
+	smp_mb();
+	if (!need_resched())
+		safe_halt();
+	current_thread_info()->status |= TS_POLLING;
+
+	cx->usage++;
+
+	return 0;
+}
+
+/**
+ * acpi_idle_enter_simple - enters an ACPI state without BM handling
+ * @dev: the target CPU
+ * @state: the state data
+ */
+static int acpi_idle_enter_simple(struct cpuidle_device *dev,
+				  struct cpuidle_state *state)
+{
+	struct acpi_processor *pr;
+	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
+	u32 t1, t2;
+	pr = processors[smp_processor_id()];
+
+	if (unlikely(!pr))
+		return 0;
+
+	if (acpi_idle_suspend)
+		return(acpi_idle_enter_c1(dev, state));
+
+	if (pr->flags.bm_check)
+		acpi_idle_update_bm_rld(pr, cx);
+
+	local_irq_disable();
+	current_thread_info()->status &= ~TS_POLLING;
+	/*
+	 * TS_POLLING-cleared state must be visible before we test
+	 * NEED_RESCHED:
+	 */
+	smp_mb();
+
+	if (unlikely(need_resched())) {
+		current_thread_info()->status |= TS_POLLING;
+		local_irq_enable();
+		return 0;
+	}
+
+	if (cx->type == ACPI_STATE_C3)
+		ACPI_FLUSH_CPU_CACHE();
+
+	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	acpi_state_timer_broadcast(pr, cx, 1);
+	acpi_idle_do_entry(cx);
+	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+
+#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
+	/* TSC could halt in idle, so notify users */
+	mark_tsc_unstable("TSC halts in idle");;
+#endif
+
+	local_irq_enable();
+	current_thread_info()->status |= TS_POLLING;
+
+	cx->usage++;
+
+	acpi_state_timer_broadcast(pr, cx, 0);
+	cx->time += ticks_elapsed(t1, t2);
+	return ticks_elapsed_in_us(t1, t2);
+}
+
+static int c3_cpu_count;
+static DEFINE_SPINLOCK(c3_lock);
+
+/**
+ * acpi_idle_enter_bm - enters C3 with proper BM handling
+ * @dev: the target CPU
+ * @state: the state data
+ *
+ * If BM is detected, the deepest non-C3 idle state is entered instead.
+ */
+static int acpi_idle_enter_bm(struct cpuidle_device *dev,
+			      struct cpuidle_state *state)
+{
+	struct acpi_processor *pr;
+	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
+	u32 t1, t2;
+	pr = processors[smp_processor_id()];
+
+	if (unlikely(!pr))
+		return 0;
+
+	if (acpi_idle_suspend)
+		return(acpi_idle_enter_c1(dev, state));
+
+	local_irq_disable();
+	current_thread_info()->status &= ~TS_POLLING;
+	/*
+	 * TS_POLLING-cleared state must be visible before we test
+	 * NEED_RESCHED:
+	 */
+	smp_mb();
+
+	if (unlikely(need_resched())) {
+		current_thread_info()->status |= TS_POLLING;
+		local_irq_enable();
+		return 0;
+	}
+
+	/*
+	 * Must be done before busmaster disable as we might need to
+	 * access HPET !
+	 */
+	acpi_state_timer_broadcast(pr, cx, 1);
+
+	if (acpi_idle_bm_check()) {
+		cx = pr->power.bm_state;
+
+		acpi_idle_update_bm_rld(pr, cx);
+
+		t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+		acpi_idle_do_entry(cx);
+		t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	} else {
+		acpi_idle_update_bm_rld(pr, cx);
+
+		spin_lock(&c3_lock);
+		c3_cpu_count++;
+		/* Disable bus master arbitration when all CPUs are in C3 */
+		if (c3_cpu_count == num_online_cpus())
+			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+		spin_unlock(&c3_lock);
+
+		t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+		acpi_idle_do_entry(cx);
+		t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+
+		spin_lock(&c3_lock);
+		/* Re-enable bus master arbitration */
+		if (c3_cpu_count == num_online_cpus())
+			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+		c3_cpu_count--;
+		spin_unlock(&c3_lock);
+	}
+
+#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
+	/* TSC could halt in idle, so notify users */
+	mark_tsc_unstable("TSC halts in idle");
+#endif
+
+	local_irq_enable();
+	current_thread_info()->status |= TS_POLLING;
+
+	cx->usage++;
+
+	acpi_state_timer_broadcast(pr, cx, 0);
+	cx->time += ticks_elapsed(t1, t2);
+	return ticks_elapsed_in_us(t1, t2);
+}
+
+struct cpuidle_driver acpi_idle_driver = {
+	.name =		"acpi_idle",
+	.owner =	THIS_MODULE,
+};
+
+/**
+ * acpi_processor_setup_cpuidle - prepares and configures CPUIDLE
+ * @pr: the ACPI processor
+ */
+static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
+{
+	int i, count = 0;
+	struct acpi_processor_cx *cx;
+	struct cpuidle_state *state;
+	struct cpuidle_device *dev = &pr->power.dev;
+
+	if (!pr->flags.power_setup_done)
+		return -EINVAL;
+
+	if (pr->flags.power == 0) {
+		return -EINVAL;
+	}
+
+	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
+		cx = &pr->power.states[i];
+		state = &dev->states[count];
+
+		if (!cx->valid)
+			continue;
+
+#ifdef CONFIG_HOTPLUG_CPU
+		if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
+		    !pr->flags.has_cst &&
+		    !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
+			continue;
+#endif
+		cpuidle_set_statedata(state, cx);
+
+		snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
+		state->exit_latency = cx->latency;
+		state->target_residency = cx->latency * 6;
+		state->power_usage = cx->power;
+
+		state->flags = 0;
+		switch (cx->type) {
+			case ACPI_STATE_C1:
+			state->flags |= CPUIDLE_FLAG_SHALLOW;
+			state->enter = acpi_idle_enter_c1;
+			break;
+
+			case ACPI_STATE_C2:
+			state->flags |= CPUIDLE_FLAG_BALANCED;
+			state->flags |= CPUIDLE_FLAG_TIME_VALID;
+			state->enter = acpi_idle_enter_simple;
+			break;
+
+			case ACPI_STATE_C3:
+			state->flags |= CPUIDLE_FLAG_DEEP;
+			state->flags |= CPUIDLE_FLAG_TIME_VALID;
+			state->flags |= CPUIDLE_FLAG_CHECK_BM;
+			state->enter = pr->flags.bm_check ?
+					acpi_idle_enter_bm :
+					acpi_idle_enter_simple;
+			break;
+		}
+
+		count++;
+	}
+
+	dev->state_count = count;
+
+	if (!count)
+		return -EINVAL;
+
+	/* find the deepest state that can handle active BM */
+	if (pr->flags.bm_check) {
+		for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++)
+			if (pr->power.states[i].type == ACPI_STATE_C3)
+				break;
+		pr->power.bm_state = &pr->power.states[i-1];
+	}
+
+	return 0;
+}
+
+int acpi_processor_cst_has_changed(struct acpi_processor *pr)
+{
+	int ret;
+
+	if (!pr)
+		return -EINVAL;
+
+	if (nocst) {
+		return -ENODEV;
+	}
+
+	if (!pr->flags.power_setup_done)
+		return -ENODEV;
+
+	cpuidle_pause_and_lock();
+	cpuidle_disable_device(&pr->power.dev);
+	acpi_processor_get_power_info(pr);
+	acpi_processor_setup_cpuidle(pr);
+	ret = cpuidle_enable_device(&pr->power.dev);
+	cpuidle_resume_and_unlock();
+
+	return ret;
+}
+
+#endif /* CONFIG_CPU_IDLE */
+
 int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
 			      struct acpi_device *device)
 {
@@ -1267,7 +1663,7 @@
 			       "ACPI: processor limited to max C-state %d\n",
 			       max_cstate);
 		first_run++;
-#ifdef CONFIG_SMP
+#if !defined (CONFIG_CPU_IDLE) && defined (CONFIG_SMP)
 		register_latency_notifier(&acpi_processor_latency_notifier);
 #endif
 	}
@@ -1285,6 +1681,7 @@
 	}
 
 	acpi_processor_get_power_info(pr);
+	pr->flags.power_setup_done = 1;
 
 	/*
 	 * Install the idle handler if processor power management is supported.
@@ -1292,6 +1689,13 @@
 	 * platforms that only support C1.
 	 */
 	if ((pr->flags.power) && (!boot_option_idle_override)) {
+#ifdef CONFIG_CPU_IDLE
+		acpi_processor_setup_cpuidle(pr);
+		pr->power.dev.cpu = pr->id;
+		if (cpuidle_register_device(&pr->power.dev))
+			return -EIO;
+#endif
+
 		printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
 		for (i = 1; i <= pr->power.count; i++)
 			if (pr->power.states[i].valid)
@@ -1299,10 +1703,12 @@
 				       pr->power.states[i].type);
 		printk(")\n");
 
+#ifndef CONFIG_CPU_IDLE
 		if (pr->id == 0) {
 			pm_idle_save = pm_idle;
 			pm_idle = acpi_processor_idle;
 		}
+#endif
 	}
 
 	/* 'power' [R] */
@@ -1316,21 +1722,24 @@
 		entry->owner = THIS_MODULE;
 	}
 
-	pr->flags.power_setup_done = 1;
-
 	return 0;
 }
 
 int acpi_processor_power_exit(struct acpi_processor *pr,
 			      struct acpi_device *device)
 {
-
+#ifdef CONFIG_CPU_IDLE
+	if ((pr->flags.power) && (!boot_option_idle_override))
+		cpuidle_unregister_device(&pr->power.dev);
+#endif
 	pr->flags.power_setup_done = 0;
 
 	if (acpi_device_dir(device))
 		remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,
 				  acpi_device_dir(device));
 
+#ifndef CONFIG_CPU_IDLE
+
 	/* Unregister the idle handler when processor #0 is removed. */
 	if (pr->id == 0) {
 		pm_idle = pm_idle_save;
@@ -1345,6 +1754,7 @@
 		unregister_latency_notifier(&acpi_processor_latency_notifier);
 #endif
 	}
+#endif
 
 	return 0;
 }
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index a578986..90fd09c 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -1,6 +1,8 @@
 /*
- *  acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $)
+ *  sbs.c - ACPI Smart Battery System Driver ($Revision: 2.0 $)
  *
+ *  Copyright (c) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
+ *  Copyright (c) 2005-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
  *  Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -26,15 +28,22 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
+
+#ifdef CONFIG_ACPI_PROCFS
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <asm/uaccess.h>
+#endif
+
 #include <linux/acpi.h>
 #include <linux/timer.h>
 #include <linux/jiffies.h>
 #include <linux/delay.h>
 
-#define ACPI_SBS_COMPONENT		0x00080000
+#include <linux/power_supply.h>
+
+#include "sbshc.h"
+
 #define ACPI_SBS_CLASS			"sbs"
 #define ACPI_AC_CLASS			"ac_adapter"
 #define ACPI_BATTERY_CLASS		"battery"
@@ -44,836 +53,436 @@
 #define ACPI_SBS_FILE_ALARM		"alarm"
 #define ACPI_BATTERY_DIR_NAME		"BAT%i"
 #define ACPI_AC_DIR_NAME		"AC0"
-#define ACPI_SBC_SMBUS_ADDR		0x9
-#define ACPI_SBSM_SMBUS_ADDR		0xa
-#define ACPI_SB_SMBUS_ADDR		0xb
-#define ACPI_SBS_AC_NOTIFY_STATUS	0x80
-#define ACPI_SBS_BATTERY_NOTIFY_STATUS	0x80
-#define ACPI_SBS_BATTERY_NOTIFY_INFO	0x81
 
-#define _COMPONENT			ACPI_SBS_COMPONENT
+enum acpi_sbs_device_addr {
+	ACPI_SBS_CHARGER = 0x9,
+	ACPI_SBS_MANAGER = 0xa,
+	ACPI_SBS_BATTERY = 0xb,
+};
 
-ACPI_MODULE_NAME("sbs");
+#define ACPI_SBS_NOTIFY_STATUS		0x80
+#define ACPI_SBS_NOTIFY_INFO		0x81
 
-MODULE_AUTHOR("Rich Townsend");
+MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
 MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
 MODULE_LICENSE("GPL");
 
-#define	xmsleep(t)	msleep(t)
-
-#define ACPI_EC_SMB_PRTCL	0x00	/* protocol, PEC */
-
-#define ACPI_EC_SMB_STS		0x01	/* status */
-#define ACPI_EC_SMB_ADDR	0x02	/* address */
-#define ACPI_EC_SMB_CMD		0x03	/* command */
-#define ACPI_EC_SMB_DATA	0x04	/* 32 data registers */
-#define ACPI_EC_SMB_BCNT	0x24	/* number of data bytes */
-
-#define ACPI_EC_SMB_STS_DONE	0x80
-#define ACPI_EC_SMB_STS_STATUS	0x1f
-
-#define ACPI_EC_SMB_PRTCL_WRITE		0x00
-#define ACPI_EC_SMB_PRTCL_READ		0x01
-#define ACPI_EC_SMB_PRTCL_WORD_DATA	0x08
-#define ACPI_EC_SMB_PRTCL_BLOCK_DATA	0x0a
-
-#define ACPI_EC_SMB_TRANSACTION_SLEEP	1
-#define ACPI_EC_SMB_ACCESS_SLEEP1	1
-#define ACPI_EC_SMB_ACCESS_SLEEP2	10
-
-#define	DEF_CAPACITY_UNIT	3
-#define	MAH_CAPACITY_UNIT	1
-#define	MWH_CAPACITY_UNIT	2
-#define	CAPACITY_UNIT		DEF_CAPACITY_UNIT
-
-#define	REQUEST_UPDATE_MODE	1
-#define	QUEUE_UPDATE_MODE	2
-
-#define	DATA_TYPE_COMMON	0
-#define	DATA_TYPE_INFO		1
-#define	DATA_TYPE_STATE		2
-#define	DATA_TYPE_ALARM		3
-#define	DATA_TYPE_AC_STATE	4
+static unsigned int cache_time = 1000;
+module_param(cache_time, uint, 0644);
+MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
 
 extern struct proc_dir_entry *acpi_lock_ac_dir(void);
 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
 extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
 extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 
-#define	MAX_SBS_BAT			4
+#define MAX_SBS_BAT			4
 #define ACPI_SBS_BLOCK_MAX		32
 
-#define ACPI_SBS_SMBUS_READ		1
-#define ACPI_SBS_SMBUS_WRITE		2
-
-#define ACPI_SBS_WORD_DATA		1
-#define ACPI_SBS_BLOCK_DATA		2
-
-#define	UPDATE_DELAY	10
-
-/* 0 - every time, > 0 - by update_time */
-static unsigned int update_time = 120;
-
-static unsigned int capacity_mode = CAPACITY_UNIT;
-
-module_param(update_time, uint, 0644);
-module_param(capacity_mode, uint, 0444);
-
-static int acpi_sbs_add(struct acpi_device *device);
-static int acpi_sbs_remove(struct acpi_device *device, int type);
-static int acpi_sbs_resume(struct acpi_device *device);
-
 static const struct acpi_device_id sbs_device_ids[] = {
-	{"ACPI0001", 0},
-	{"ACPI0005", 0},
+	{"ACPI0002", 0},
 	{"", 0},
 };
 MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
 
-static struct acpi_driver acpi_sbs_driver = {
-	.name = "sbs",
-	.class = ACPI_SBS_CLASS,
-	.ids = sbs_device_ids,
-	.ops = {
-		.add = acpi_sbs_add,
-		.remove = acpi_sbs_remove,
-		.resume = acpi_sbs_resume,
-		},
-};
-
-struct acpi_ac {
-	int ac_present;
-};
-
-struct acpi_battery_info {
-	int capacity_mode;
-	s16 full_charge_capacity;
-	s16 design_capacity;
-	s16 design_voltage;
-	int vscale;
-	int ipscale;
-	s16 serial_number;
-	char manufacturer_name[ACPI_SBS_BLOCK_MAX + 3];
-	char device_name[ACPI_SBS_BLOCK_MAX + 3];
-	char device_chemistry[ACPI_SBS_BLOCK_MAX + 3];
-};
-
-struct acpi_battery_state {
-	s16 voltage;
-	s16 amperage;
-	s16 remaining_capacity;
-	s16 battery_state;
-};
-
-struct acpi_battery_alarm {
-	s16 remaining_capacity;
-};
-
 struct acpi_battery {
-	int alive;
-	int id;
-	int init_state;
-	int battery_present;
+	struct power_supply bat;
 	struct acpi_sbs *sbs;
-	struct acpi_battery_info info;
-	struct acpi_battery_state state;
-	struct acpi_battery_alarm alarm;
-	struct proc_dir_entry *battery_entry;
+#ifdef CONFIG_ACPI_PROCFS
+	struct proc_dir_entry *proc_entry;
+#endif
+	unsigned long update_time;
+	char name[8];
+	char manufacturer_name[ACPI_SBS_BLOCK_MAX];
+	char device_name[ACPI_SBS_BLOCK_MAX];
+	char device_chemistry[ACPI_SBS_BLOCK_MAX];
+	u16 alarm_capacity;
+	u16 full_charge_capacity;
+	u16 design_capacity;
+	u16 design_voltage;
+	u16 serial_number;
+	u16 cycle_count;
+	u16 temp_now;
+	u16 voltage_now;
+	s16 current_now;
+	s16 current_avg;
+	u16 capacity_now;
+	u16 state_of_charge;
+	u16 state;
+	u16 mode;
+	u16 spec;
+	u8 id;
+	u8 present:1;
 };
 
+#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
+
 struct acpi_sbs {
-	int base;
+	struct power_supply charger;
 	struct acpi_device *device;
-	struct mutex mutex;
-	int sbsm_present;
-	int sbsm_batteries_supported;
-	struct proc_dir_entry *ac_entry;
-	struct acpi_ac ac;
+	struct acpi_smb_hc *hc;
+	struct mutex lock;
+#ifdef CONFIG_ACPI_PROCFS
+	struct proc_dir_entry *charger_entry;
+#endif
 	struct acpi_battery battery[MAX_SBS_BAT];
-	int zombie;
-	struct timer_list update_timer;
-	int run_cnt;
-	int update_proc_flg;
+	u8 batteries_supported:4;
+	u8 manager_present:1;
+	u8 charger_present:1;
 };
 
-static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type);
-static void acpi_sbs_update_time(void *data);
+#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger)
 
-union sbs_rw_data {
-	u16 word;
-	u8 block[ACPI_SBS_BLOCK_MAX + 2];
-};
-
-static int acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
-			      char read_write, u8 command, int size,
-			      union sbs_rw_data *data);
-
-/* --------------------------------------------------------------------------
-                               SMBus Communication
-   -------------------------------------------------------------------------- */
-
-static int acpi_ec_sbs_read(struct acpi_sbs *sbs, u8 address, u8 * data)
+static inline int battery_scale(int log)
 {
-	u8 val;
-	int err;
-
-	err = ec_read(sbs->base + address, &val);
-	if (!err) {
-		*data = val;
-	}
-	xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP);
-	return (err);
+	int scale = 1;
+	while (log--)
+		scale *= 10;
+	return scale;
 }
 
-static int acpi_ec_sbs_write(struct acpi_sbs *sbs, u8 address, u8 data)
+static inline int acpi_battery_vscale(struct acpi_battery *battery)
 {
-	int err;
-
-	err = ec_write(sbs->base + address, data);
-	return (err);
+	return battery_scale((battery->spec & 0x0f00) >> 8);
 }
 
-static int
-acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
-		   char read_write, u8 command, int size,
-		   union sbs_rw_data *data)
+static inline int acpi_battery_ipscale(struct acpi_battery *battery)
 {
-	unsigned char protocol, len = 0, temp[2] = { 0, 0 };
-	int i;
+	return battery_scale((battery->spec & 0xf000) >> 12);
+}
 
-	if (read_write == ACPI_SBS_SMBUS_READ) {
-		protocol = ACPI_EC_SMB_PRTCL_READ;
-	} else {
-		protocol = ACPI_EC_SMB_PRTCL_WRITE;
-	}
+static inline int acpi_battery_mode(struct acpi_battery *battery)
+{
+	return (battery->mode & 0x8000);
+}
 
-	switch (size) {
+static inline int acpi_battery_scale(struct acpi_battery *battery)
+{
+	return (acpi_battery_mode(battery) ? 10 : 1) *
+	    acpi_battery_ipscale(battery);
+}
 
-	case ACPI_SBS_WORD_DATA:
-		acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command);
-		if (read_write == ACPI_SBS_SMBUS_WRITE) {
-			acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA, data->word);
-			acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + 1,
-					  data->word >> 8);
-		}
-		protocol |= ACPI_EC_SMB_PRTCL_WORD_DATA;
-		break;
-	case ACPI_SBS_BLOCK_DATA:
-		acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command);
-		if (read_write == ACPI_SBS_SMBUS_WRITE) {
-			len = min_t(u8, data->block[0], 32);
-			acpi_ec_sbs_write(sbs, ACPI_EC_SMB_BCNT, len);
-			for (i = 0; i < len; i++)
-				acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + i,
-						  data->block[i + 1]);
-		}
-		protocol |= ACPI_EC_SMB_PRTCL_BLOCK_DATA;
+static int sbs_get_ac_property(struct power_supply *psy,
+			       enum power_supply_property psp,
+			       union power_supply_propval *val)
+{
+	struct acpi_sbs *sbs = to_acpi_sbs(psy);
+	switch (psp) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = sbs->charger_present;
 		break;
 	default:
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"unsupported transaction %d", size));
-		return (-1);
+		return -EINVAL;
 	}
-
-	acpi_ec_sbs_write(sbs, ACPI_EC_SMB_ADDR, addr << 1);
-	acpi_ec_sbs_write(sbs, ACPI_EC_SMB_PRTCL, protocol);
-
-	acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
-
-	if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
-		xmsleep(ACPI_EC_SMB_ACCESS_SLEEP1);
-		acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
-	}
-	if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
-		xmsleep(ACPI_EC_SMB_ACCESS_SLEEP2);
-		acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
-	}
-	if ((~temp[0] & ACPI_EC_SMB_STS_DONE)
-	    || (temp[0] & ACPI_EC_SMB_STS_STATUS)) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"transaction %d error", size));
-		return (-1);
-	}
-
-	if (read_write == ACPI_SBS_SMBUS_WRITE) {
-		return (0);
-	}
-
-	switch (size) {
-
-	case ACPI_SBS_WORD_DATA:
-		acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA, temp);
-		acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + 1, temp + 1);
-		data->word = (temp[1] << 8) | temp[0];
-		break;
-
-	case ACPI_SBS_BLOCK_DATA:
-		len = 0;
-		acpi_ec_sbs_read(sbs, ACPI_EC_SMB_BCNT, &len);
-		len = min_t(u8, len, 32);
-		for (i = 0; i < len; i++)
-			acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + i,
-					 data->block + i + 1);
-		data->block[0] = len;
-		break;
-	default:
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"unsupported transaction %d", size));
-		return (-1);
-	}
-
-	return (0);
-}
-
-static int
-acpi_sbs_read_word(struct acpi_sbs *sbs, int addr, int func, u16 * word)
-{
-	union sbs_rw_data data;
-	int result = 0;
-
-	result = acpi_ec_sbs_access(sbs, addr,
-				    ACPI_SBS_SMBUS_READ, func,
-				    ACPI_SBS_WORD_DATA, &data);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_ec_sbs_access() failed"));
-	} else {
-		*word = data.word;
-	}
-
-	return result;
-}
-
-static int
-acpi_sbs_read_str(struct acpi_sbs *sbs, int addr, int func, char *str)
-{
-	union sbs_rw_data data;
-	int result = 0;
-
-	result = acpi_ec_sbs_access(sbs, addr,
-				    ACPI_SBS_SMBUS_READ, func,
-				    ACPI_SBS_BLOCK_DATA, &data);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_ec_sbs_access() failed"));
-	} else {
-		strncpy(str, (const char *)data.block + 1, data.block[0]);
-		str[data.block[0]] = 0;
-	}
-
-	return result;
-}
-
-static int
-acpi_sbs_write_word(struct acpi_sbs *sbs, int addr, int func, int word)
-{
-	union sbs_rw_data data;
-	int result = 0;
-
-	data.word = word;
-
-	result = acpi_ec_sbs_access(sbs, addr,
-				    ACPI_SBS_SMBUS_WRITE, func,
-				    ACPI_SBS_WORD_DATA, &data);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_ec_sbs_access() failed"));
-	}
-
-	return result;
-}
-
-static int sbs_zombie(struct acpi_sbs *sbs)
-{
-	return (sbs->zombie);
-}
-
-static int sbs_mutex_lock(struct acpi_sbs *sbs)
-{
-	if (sbs_zombie(sbs)) {
-		return -ENODEV;
-	}
-	mutex_lock(&sbs->mutex);
 	return 0;
 }
 
-static void sbs_mutex_unlock(struct acpi_sbs *sbs)
+static int acpi_battery_technology(struct acpi_battery *battery)
 {
-	mutex_unlock(&sbs->mutex);
+	if (!strcasecmp("NiCd", battery->device_chemistry))
+		return POWER_SUPPLY_TECHNOLOGY_NiCd;
+	if (!strcasecmp("NiMH", battery->device_chemistry))
+		return POWER_SUPPLY_TECHNOLOGY_NiMH;
+	if (!strcasecmp("LION", battery->device_chemistry))
+		return POWER_SUPPLY_TECHNOLOGY_LION;
+	if (!strcasecmp("LiP", battery->device_chemistry))
+		return POWER_SUPPLY_TECHNOLOGY_LIPO;
+	return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
 }
 
+static int acpi_sbs_battery_get_property(struct power_supply *psy,
+					 enum power_supply_property psp,
+					 union power_supply_propval *val)
+{
+	struct acpi_battery *battery = to_acpi_battery(psy);
+
+	if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT)
+		return -ENODEV;
+	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		if (battery->current_now < 0)
+			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		else if (battery->current_now > 0)
+			val->intval = POWER_SUPPLY_STATUS_CHARGING;
+		else
+			val->intval = POWER_SUPPLY_STATUS_FULL;
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = battery->present;
+		break;
+	case POWER_SUPPLY_PROP_TECHNOLOGY:
+		val->intval = acpi_battery_technology(battery);
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+		val->intval = battery->design_voltage *
+			acpi_battery_vscale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		val->intval = battery->voltage_now *
+				acpi_battery_vscale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+		val->intval = abs(battery->current_now) *
+				acpi_battery_ipscale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_AVG:
+		val->intval = abs(battery->current_avg) *
+				acpi_battery_ipscale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CAPACITY:
+		val->intval = battery->state_of_charge;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+		val->intval = battery->design_capacity *
+			acpi_battery_scale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_FULL:
+	case POWER_SUPPLY_PROP_ENERGY_FULL:
+		val->intval = battery->full_charge_capacity *
+			acpi_battery_scale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_NOW:
+	case POWER_SUPPLY_PROP_ENERGY_NOW:
+		val->intval = battery->capacity_now *
+				acpi_battery_scale(battery) * 1000;
+		break;
+	case POWER_SUPPLY_PROP_TEMP:
+		val->intval = battery->temp_now - 2730;	// dK -> dC
+		break;
+	case POWER_SUPPLY_PROP_MODEL_NAME:
+		val->strval = battery->device_name;
+		break;
+	case POWER_SUPPLY_PROP_MANUFACTURER:
+		val->strval = battery->manufacturer_name;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static enum power_supply_property sbs_ac_props[] = {
+	POWER_SUPPLY_PROP_ONLINE,
+};
+
+static enum power_supply_property sbs_charge_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+	POWER_SUPPLY_PROP_CHARGE_FULL,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static enum power_supply_property sbs_energy_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+	POWER_SUPPLY_PROP_ENERGY_FULL,
+	POWER_SUPPLY_PROP_ENERGY_NOW,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
 /* --------------------------------------------------------------------------
                             Smart Battery System Management
    -------------------------------------------------------------------------- */
 
-static int acpi_check_update_proc(struct acpi_sbs *sbs)
-{
-	acpi_status status = AE_OK;
+struct acpi_battery_reader {
+	u8 command;		/* command for battery */
+	u8 mode;		/* word or block? */
+	size_t offset;		/* offset inside struct acpi_sbs_battery */
+};
 
-	if (update_time == 0) {
-		sbs->update_proc_flg = 0;
-		return 0;
-	}
-	if (sbs->update_proc_flg == 0) {
-		status = acpi_os_execute(OSL_GPE_HANDLER,
-					 acpi_sbs_update_time, sbs);
-		if (status != AE_OK) {
-			ACPI_EXCEPTION((AE_INFO, status,
-					"acpi_os_execute() failed"));
-			return 1;
-		}
-		sbs->update_proc_flg = 1;
-	}
-	return 0;
-}
+static struct acpi_battery_reader info_readers[] = {
+	{0x01, SMBUS_READ_WORD, offsetof(struct acpi_battery, alarm_capacity)},
+	{0x03, SMBUS_READ_WORD, offsetof(struct acpi_battery, mode)},
+	{0x10, SMBUS_READ_WORD, offsetof(struct acpi_battery, full_charge_capacity)},
+	{0x17, SMBUS_READ_WORD, offsetof(struct acpi_battery, cycle_count)},
+	{0x18, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_capacity)},
+	{0x19, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_voltage)},
+	{0x1a, SMBUS_READ_WORD, offsetof(struct acpi_battery, spec)},
+	{0x1c, SMBUS_READ_WORD, offsetof(struct acpi_battery, serial_number)},
+	{0x20, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, manufacturer_name)},
+	{0x21, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_name)},
+	{0x22, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_chemistry)},
+};
 
-static int acpi_sbs_generate_event(struct acpi_device *device,
-				   int event, int state, char *bid, char *class)
-{
-	char bid_saved[5];
-	char class_saved[20];
-	int result = 0;
+static struct acpi_battery_reader state_readers[] = {
+	{0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
+	{0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
+	{0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
+	{0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
+	{0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
+	{0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
+	{0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
+};
 
-	strcpy(bid_saved, acpi_device_bid(device));
-	strcpy(class_saved, acpi_device_class(device));
-
-	strcpy(acpi_device_bid(device), bid);
-	strcpy(acpi_device_class(device), class);
-
-	result = acpi_bus_generate_proc_event(device, event, state);
-
-	strcpy(acpi_device_bid(device), bid_saved);
-	strcpy(acpi_device_class(device), class_saved);
-
-	acpi_bus_generate_netlink_event(class, bid, event, state);
-	return result;
-}
-
-static int acpi_battery_get_present(struct acpi_battery *battery)
-{
-	s16 state;
-	int result = 0;
-	int is_present = 0;
-
-	result = acpi_sbs_read_word(battery->sbs,
-				    ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-	}
-	if (!result) {
-		is_present = (state & 0x000f) & (1 << battery->id);
-	}
-	battery->battery_present = is_present;
-
-	return result;
-}
-
-static int acpi_battery_select(struct acpi_battery *battery)
-{
-	struct acpi_sbs *sbs = battery->sbs;
-	int result = 0;
-	s16 state;
-	int foo;
-
-	if (sbs->sbsm_present) {
-
-		/* Take special care not to knobble other nibbles of
-		 * state (aka selector_state), since
-		 * it causes charging to halt on SBSELs */
-
-		result =
-		    acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_read_word() failed"));
-			goto end;
-		}
-
-		foo = (state & 0x0fff) | (1 << (battery->id + 12));
-		result =
-		    acpi_sbs_write_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, foo);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_write_word() failed"));
-			goto end;
-		}
-	}
-
-      end:
-	return result;
-}
-
-static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
+static int acpi_manager_get_info(struct acpi_sbs *sbs)
 {
 	int result = 0;
-	s16 battery_system_info;
+	u16 battery_system_info;
 
-	result = acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x04,
-				    &battery_system_info);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-	sbs->sbsm_present = 1;
-	sbs->sbsm_batteries_supported = battery_system_info & 0x000f;
-
-      end:
-
+	result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
+				 0x04, (u8 *)&battery_system_info);
+	if (!result)
+		sbs->batteries_supported = battery_system_info & 0x000f;
 	return result;
 }
 
 static int acpi_battery_get_info(struct acpi_battery *battery)
 {
-	struct acpi_sbs *sbs = battery->sbs;
-	int result = 0;
-	s16 battery_mode;
-	s16 specification_info;
+	int i, result = 0;
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
-				    &battery_mode);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
+	for (i = 0; i < ARRAY_SIZE(info_readers); ++i) {
+		result = acpi_smbus_read(battery->sbs->hc,
+					 info_readers[i].mode,
+					 ACPI_SBS_BATTERY,
+					 info_readers[i].command,
+					 (u8 *) battery +
+						info_readers[i].offset);
+		if (result)
+			break;
 	}
-	battery->info.capacity_mode = (battery_mode & 0x8000) >> 15;
-
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x10,
-				    &battery->info.full_charge_capacity);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x18,
-				    &battery->info.design_capacity);
-
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x19,
-				    &battery->info.design_voltage);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1a,
-				    &specification_info);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-	switch ((specification_info & 0x0f00) >> 8) {
-	case 1:
-		battery->info.vscale = 10;
-		break;
-	case 2:
-		battery->info.vscale = 100;
-		break;
-	case 3:
-		battery->info.vscale = 1000;
-		break;
-	default:
-		battery->info.vscale = 1;
-	}
-
-	switch ((specification_info & 0xf000) >> 12) {
-	case 1:
-		battery->info.ipscale = 10;
-		break;
-	case 2:
-		battery->info.ipscale = 100;
-		break;
-	case 3:
-		battery->info.ipscale = 1000;
-		break;
-	default:
-		battery->info.ipscale = 1;
-	}
-
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c,
-				    &battery->info.serial_number);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-	result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x20,
-				   battery->info.manufacturer_name);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_str() failed"));
-		goto end;
-	}
-
-	result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x21,
-				   battery->info.device_name);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_str() failed"));
-		goto end;
-	}
-
-	result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x22,
-				   battery->info.device_chemistry);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_str() failed"));
-		goto end;
-	}
-
-      end:
 	return result;
 }
 
 static int acpi_battery_get_state(struct acpi_battery *battery)
 {
-	struct acpi_sbs *sbs = battery->sbs;
-	int result = 0;
+	int i, result = 0;
 
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09,
-				    &battery->state.voltage);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
+	if (battery->update_time &&
+	    time_before(jiffies, battery->update_time +
+				msecs_to_jiffies(cache_time)))
+		return 0;
+	for (i = 0; i < ARRAY_SIZE(state_readers); ++i) {
+		result = acpi_smbus_read(battery->sbs->hc,
+					 state_readers[i].mode,
+					 ACPI_SBS_BATTERY,
+					 state_readers[i].command,
+				         (u8 *)battery +
+						state_readers[i].offset);
+		if (result)
+			goto end;
 	}
-
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a,
-				    &battery->state.amperage);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f,
-				    &battery->state.remaining_capacity);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16,
-				    &battery->state.battery_state);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
       end:
+	battery->update_time = jiffies;
 	return result;
 }
 
 static int acpi_battery_get_alarm(struct acpi_battery *battery)
 {
-	struct acpi_sbs *sbs = battery->sbs;
-	int result = 0;
-
-	result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
-				    &battery->alarm.remaining_capacity);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-      end:
-
-	return result;
+	return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
+				 ACPI_SBS_BATTERY, 0x01,
+				 (u8 *)&battery->alarm_capacity);
 }
 
-static int acpi_battery_set_alarm(struct acpi_battery *battery,
-				  unsigned long alarm)
+static int acpi_battery_set_alarm(struct acpi_battery *battery)
 {
 	struct acpi_sbs *sbs = battery->sbs;
-	int result = 0;
-	s16 battery_mode;
-	int foo;
+	u16 value, sel = 1 << (battery->id + 12);
 
-	result = acpi_battery_select(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_select() failed"));
-		goto end;
-	}
+	int ret;
 
-	/* If necessary, enable the alarm */
 
-	if (alarm > 0) {
-		result =
-		    acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
-				       &battery_mode);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_read_word() failed"));
+	if (sbs->manager_present) {
+		ret = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
+				0x01, (u8 *)&value);
+		if (ret)
 			goto end;
-		}
-
-		result =
-		    acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
-					battery_mode & 0xbfff);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_write_word() failed"));
+		if ((value & 0xf000) != sel) {
+			value &= 0x0fff;
+			value |= sel;
+		ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD,
+					 ACPI_SBS_MANAGER,
+					 0x01, (u8 *)&value, 2);
+		if (ret)
 			goto end;
 		}
 	}
-
-	foo = alarm / (battery->info.capacity_mode ? 10 : 1);
-	result = acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, foo);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_write_word() failed"));
-		goto end;
-	}
-
+	ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_BATTERY,
+				0x01, (u8 *)&battery->alarm_capacity, 2);
       end:
-
-	return result;
-}
-
-static int acpi_battery_set_mode(struct acpi_battery *battery)
-{
-	struct acpi_sbs *sbs = battery->sbs;
-	int result = 0;
-	s16 battery_mode;
-
-	if (capacity_mode == DEF_CAPACITY_UNIT) {
-		goto end;
-	}
-
-	result = acpi_sbs_read_word(sbs,
-				    ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-	if (capacity_mode == MAH_CAPACITY_UNIT) {
-		battery_mode &= 0x7fff;
-	} else {
-		battery_mode |= 0x8000;
-	}
-	result = acpi_sbs_write_word(sbs,
-				     ACPI_SB_SMBUS_ADDR, 0x03, battery_mode);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_write_word() failed"));
-		goto end;
-	}
-
-	result = acpi_sbs_read_word(sbs,
-				    ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-      end:
-	return result;
-}
-
-static int acpi_battery_init(struct acpi_battery *battery)
-{
-	int result = 0;
-
-	result = acpi_battery_select(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_select() failed"));
-		goto end;
-	}
-
-	result = acpi_battery_set_mode(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_set_mode() failed"));
-		goto end;
-	}
-
-	result = acpi_battery_get_info(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_get_info() failed"));
-		goto end;
-	}
-
-	result = acpi_battery_get_state(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_get_state() failed"));
-		goto end;
-	}
-
-	result = acpi_battery_get_alarm(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_get_alarm() failed"));
-		goto end;
-	}
-
-      end:
-	return result;
+	return ret;
 }
 
 static int acpi_ac_get_present(struct acpi_sbs *sbs)
 {
-	int result = 0;
-	s16 charger_status;
+	int result;
+	u16 status;
 
-	result = acpi_sbs_read_word(sbs, ACPI_SBC_SMBUS_ADDR, 0x13,
-				    &charger_status);
-
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_read_word() failed"));
-		goto end;
-	}
-
-	sbs->ac.ac_present = (charger_status & 0x8000) >> 15;
-
-      end:
-
+	result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER,
+				 0x13, (u8 *) & status);
+	if (!result)
+		sbs->charger_present = (status >> 15) & 0x1;
 	return result;
 }
 
+static ssize_t acpi_battery_alarm_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+	acpi_battery_get_alarm(battery);
+	return sprintf(buf, "%d\n", battery->alarm_capacity *
+				acpi_battery_scale(battery) * 1000);
+}
+
+static ssize_t acpi_battery_alarm_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	unsigned long x;
+	struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+	if (sscanf(buf, "%ld\n", &x) == 1)
+		battery->alarm_capacity = x /
+			(1000 * acpi_battery_scale(battery));
+	if (battery->present)
+		acpi_battery_set_alarm(battery);
+	return count;
+}
+
+static struct device_attribute alarm_attr = {
+	.attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
+	.show = acpi_battery_alarm_show,
+	.store = acpi_battery_alarm_store,
+};
+
 /* --------------------------------------------------------------------------
                               FS Interface (/proc/acpi)
    -------------------------------------------------------------------------- */
 
+#ifdef CONFIG_ACPI_PROCFS
 /* Generic Routines */
-
 static int
-acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
-			struct proc_dir_entry *parent_dir,
-			char *dir_name,
-			struct file_operations *info_fops,
-			struct file_operations *state_fops,
-			struct file_operations *alarm_fops, void *data)
+acpi_sbs_add_fs(struct proc_dir_entry **dir,
+		struct proc_dir_entry *parent_dir,
+		char *dir_name,
+		struct file_operations *info_fops,
+		struct file_operations *state_fops,
+		struct file_operations *alarm_fops, void *data)
 {
 	struct proc_dir_entry *entry = NULL;
 
 	if (!*dir) {
 		*dir = proc_mkdir(dir_name, parent_dir);
 		if (!*dir) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"proc_mkdir() failed"));
 			return -ENODEV;
 		}
 		(*dir)->owner = THIS_MODULE;
@@ -882,10 +491,7 @@
 	/* 'info' [R] */
 	if (info_fops) {
 		entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
-		if (!entry) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"create_proc_entry() failed"));
-		} else {
+		if (entry) {
 			entry->proc_fops = info_fops;
 			entry->data = data;
 			entry->owner = THIS_MODULE;
@@ -895,10 +501,7 @@
 	/* 'state' [R] */
 	if (state_fops) {
 		entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
-		if (!entry) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"create_proc_entry() failed"));
-		} else {
+		if (entry) {
 			entry->proc_fops = state_fops;
 			entry->data = data;
 			entry->owner = THIS_MODULE;
@@ -908,24 +511,19 @@
 	/* 'alarm' [R/W] */
 	if (alarm_fops) {
 		entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
-		if (!entry) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"create_proc_entry() failed"));
-		} else {
+		if (entry) {
 			entry->proc_fops = alarm_fops;
 			entry->data = data;
 			entry->owner = THIS_MODULE;
 		}
 	}
-
 	return 0;
 }
 
 static void
-acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
+acpi_sbs_remove_fs(struct proc_dir_entry **dir,
 			   struct proc_dir_entry *parent_dir)
 {
-
 	if (*dir) {
 		remove_proc_entry(ACPI_SBS_FILE_INFO, *dir);
 		remove_proc_entry(ACPI_SBS_FILE_STATE, *dir);
@@ -933,82 +531,52 @@
 		remove_proc_entry((*dir)->name, parent_dir);
 		*dir = NULL;
 	}
-
 }
 
 /* Smart Battery Interface */
-
 static struct proc_dir_entry *acpi_battery_dir = NULL;
 
+static inline char *acpi_battery_units(struct acpi_battery *battery)
+{
+	return acpi_battery_mode(battery) ? " mWh" : " mAh";
+}
+
+
 static int acpi_battery_read_info(struct seq_file *seq, void *offset)
 {
 	struct acpi_battery *battery = seq->private;
 	struct acpi_sbs *sbs = battery->sbs;
-	int cscale;
 	int result = 0;
 
-	if (sbs_mutex_lock(sbs)) {
-		return -ENODEV;
-	}
+	mutex_lock(&sbs->lock);
 
-	result = acpi_check_update_proc(sbs);
-	if (result)
+	seq_printf(seq, "present:                 %s\n",
+		   (battery->present) ? "yes" : "no");
+	if (!battery->present)
 		goto end;
 
-	if (update_time == 0) {
-		result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_INFO);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_update_run() failed"));
-		}
-	}
-
-	if (battery->battery_present) {
-		seq_printf(seq, "present:                 yes\n");
-	} else {
-		seq_printf(seq, "present:                 no\n");
-		goto end;
-	}
-
-	if (battery->info.capacity_mode) {
-		cscale = battery->info.vscale * battery->info.ipscale;
-	} else {
-		cscale = battery->info.ipscale;
-	}
 	seq_printf(seq, "design capacity:         %i%s\n",
-		   battery->info.design_capacity * cscale,
-		   battery->info.capacity_mode ? "0 mWh" : " mAh");
-
+		   battery->design_capacity * acpi_battery_scale(battery),
+		   acpi_battery_units(battery));
 	seq_printf(seq, "last full capacity:      %i%s\n",
-		   battery->info.full_charge_capacity * cscale,
-		   battery->info.capacity_mode ? "0 mWh" : " mAh");
-
+		   battery->full_charge_capacity * acpi_battery_scale(battery),
+		   acpi_battery_units(battery));
 	seq_printf(seq, "battery technology:      rechargeable\n");
-
 	seq_printf(seq, "design voltage:          %i mV\n",
-		   battery->info.design_voltage * battery->info.vscale);
-
+		   battery->design_voltage * acpi_battery_vscale(battery));
 	seq_printf(seq, "design capacity warning: unknown\n");
 	seq_printf(seq, "design capacity low:     unknown\n");
 	seq_printf(seq, "capacity granularity 1:  unknown\n");
 	seq_printf(seq, "capacity granularity 2:  unknown\n");
-
-	seq_printf(seq, "model number:            %s\n",
-		   battery->info.device_name);
-
+	seq_printf(seq, "model number:            %s\n", battery->device_name);
 	seq_printf(seq, "serial number:           %i\n",
-		   battery->info.serial_number);
-
+		   battery->serial_number);
 	seq_printf(seq, "battery type:            %s\n",
-		   battery->info.device_chemistry);
-
+		   battery->device_chemistry);
 	seq_printf(seq, "OEM info:                %s\n",
-		   battery->info.manufacturer_name);
-
+		   battery->manufacturer_name);
       end:
-
-	sbs_mutex_unlock(sbs);
-
+	mutex_unlock(&sbs->lock);
 	return result;
 }
 
@@ -1022,73 +590,29 @@
 	struct acpi_battery *battery = seq->private;
 	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
-	int cscale;
-	int foo;
 
-	if (sbs_mutex_lock(sbs)) {
-		return -ENODEV;
-	}
-
-	result = acpi_check_update_proc(sbs);
-	if (result)
+	mutex_lock(&sbs->lock);
+	seq_printf(seq, "present:                 %s\n",
+		   (battery->present) ? "yes" : "no");
+	if (!battery->present)
 		goto end;
 
-	if (update_time == 0) {
-		result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_STATE);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_update_run() failed"));
-		}
-	}
-
-	if (battery->battery_present) {
-		seq_printf(seq, "present:                 yes\n");
-	} else {
-		seq_printf(seq, "present:                 no\n");
-		goto end;
-	}
-
-	if (battery->info.capacity_mode) {
-		cscale = battery->info.vscale * battery->info.ipscale;
-	} else {
-		cscale = battery->info.ipscale;
-	}
-
-	if (battery->state.battery_state & 0x0010) {
-		seq_printf(seq, "capacity state:          critical\n");
-	} else {
-		seq_printf(seq, "capacity state:          ok\n");
-	}
-
-	foo = (s16) battery->state.amperage * battery->info.ipscale;
-	if (battery->info.capacity_mode) {
-		foo = foo * battery->info.design_voltage / 1000;
-	}
-	if (battery->state.amperage < 0) {
-		seq_printf(seq, "charging state:          discharging\n");
-		seq_printf(seq, "present rate:            %d %s\n",
-			   -foo, battery->info.capacity_mode ? "mW" : "mA");
-	} else if (battery->state.amperage > 0) {
-		seq_printf(seq, "charging state:          charging\n");
-		seq_printf(seq, "present rate:            %d %s\n",
-			   foo, battery->info.capacity_mode ? "mW" : "mA");
-	} else {
-		seq_printf(seq, "charging state:          charged\n");
-		seq_printf(seq, "present rate:            0 %s\n",
-			   battery->info.capacity_mode ? "mW" : "mA");
-	}
-
+	acpi_battery_get_state(battery);
+	seq_printf(seq, "capacity state:          %s\n",
+		   (battery->state & 0x0010) ? "critical" : "ok");
+	seq_printf(seq, "charging state:          %s\n",
+		   (battery->current_now < 0) ? "discharging" :
+		   ((battery->current_now > 0) ? "charging" : "charged"));
+	seq_printf(seq, "present rate:            %d mA\n",
+		   abs(battery->current_now) * acpi_battery_ipscale(battery));
 	seq_printf(seq, "remaining capacity:      %i%s\n",
-		   battery->state.remaining_capacity * cscale,
-		   battery->info.capacity_mode ? "0 mWh" : " mAh");
-
+		   battery->capacity_now * acpi_battery_scale(battery),
+		   acpi_battery_units(battery));
 	seq_printf(seq, "present voltage:         %i mV\n",
-		   battery->state.voltage * battery->info.vscale);
+		   battery->voltage_now * acpi_battery_vscale(battery));
 
       end:
-
-	sbs_mutex_unlock(sbs);
-
+	mutex_unlock(&sbs->lock);
 	return result;
 }
 
@@ -1102,48 +626,25 @@
 	struct acpi_battery *battery = seq->private;
 	struct acpi_sbs *sbs = battery->sbs;
 	int result = 0;
-	int cscale;
 
-	if (sbs_mutex_lock(sbs)) {
-		return -ENODEV;
-	}
+	mutex_lock(&sbs->lock);
 
-	result = acpi_check_update_proc(sbs);
-	if (result)
-		goto end;
-
-	if (update_time == 0) {
-		result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_ALARM);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_update_run() failed"));
-		}
-	}
-
-	if (!battery->battery_present) {
+	if (!battery->present) {
 		seq_printf(seq, "present:                 no\n");
 		goto end;
 	}
 
-	if (battery->info.capacity_mode) {
-		cscale = battery->info.vscale * battery->info.ipscale;
-	} else {
-		cscale = battery->info.ipscale;
-	}
-
+	acpi_battery_get_alarm(battery);
 	seq_printf(seq, "alarm:                   ");
-	if (battery->alarm.remaining_capacity) {
+	if (battery->alarm_capacity)
 		seq_printf(seq, "%i%s\n",
-			   battery->alarm.remaining_capacity * cscale,
-			   battery->info.capacity_mode ? "0 mWh" : " mAh");
-	} else {
+			   battery->alarm_capacity *
+			   acpi_battery_scale(battery),
+			   acpi_battery_units(battery));
+	else
 		seq_printf(seq, "disabled\n");
-	}
-
       end:
-
-	sbs_mutex_unlock(sbs);
-
+	mutex_unlock(&sbs->lock);
 	return result;
 }
 
@@ -1155,59 +656,29 @@
 	struct acpi_battery *battery = seq->private;
 	struct acpi_sbs *sbs = battery->sbs;
 	char alarm_string[12] = { '\0' };
-	int result, old_alarm, new_alarm;
-
-	if (sbs_mutex_lock(sbs)) {
-		return -ENODEV;
-	}
-
-	result = acpi_check_update_proc(sbs);
-	if (result)
-		goto end;
-
-	if (!battery->battery_present) {
+	int result = 0;
+	mutex_lock(&sbs->lock);
+	if (!battery->present) {
 		result = -ENODEV;
 		goto end;
 	}
-
 	if (count > sizeof(alarm_string) - 1) {
 		result = -EINVAL;
 		goto end;
 	}
-
 	if (copy_from_user(alarm_string, buffer, count)) {
 		result = -EFAULT;
 		goto end;
 	}
-
 	alarm_string[count] = 0;
-
-	old_alarm = battery->alarm.remaining_capacity;
-	new_alarm = simple_strtoul(alarm_string, NULL, 0);
-
-	result = acpi_battery_set_alarm(battery, new_alarm);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_set_alarm() failed"));
-		acpi_battery_set_alarm(battery, old_alarm);
-		goto end;
-	}
-	result = acpi_battery_get_alarm(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_get_alarm() failed"));
-		acpi_battery_set_alarm(battery, old_alarm);
-		goto end;
-	}
-
+	battery->alarm_capacity = simple_strtoul(alarm_string, NULL, 0) /
+					acpi_battery_scale(battery);
+	acpi_battery_set_alarm(battery);
       end:
-	sbs_mutex_unlock(sbs);
-
-	if (result) {
+	mutex_unlock(&sbs->lock);
+	if (result)
 		return result;
-	} else {
-		return count;
-	}
+	return count;
 }
 
 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
@@ -1246,26 +717,15 @@
 
 static int acpi_ac_read_state(struct seq_file *seq, void *offset)
 {
+
 	struct acpi_sbs *sbs = seq->private;
-	int result;
 
-	if (sbs_mutex_lock(sbs)) {
-		return -ENODEV;
-	}
-
-	if (update_time == 0) {
-		result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_AC_STATE);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_update_run() failed"));
-		}
-	}
+	mutex_lock(&sbs->lock);
 
 	seq_printf(seq, "state:                   %s\n",
-		   sbs->ac.ac_present ? "on-line" : "off-line");
+		   sbs->charger_present ? "on-line" : "off-line");
 
-	sbs_mutex_unlock(sbs);
-
+	mutex_unlock(&sbs->lock);
 	return 0;
 }
 
@@ -1282,429 +742,203 @@
 	.owner = THIS_MODULE,
 };
 
+#endif
+
 /* --------------------------------------------------------------------------
                                  Driver Interface
    -------------------------------------------------------------------------- */
+static int acpi_battery_read(struct acpi_battery *battery)
+{
+	int result = 0, saved_present = battery->present;
+	u16 state;
+
+	if (battery->sbs->manager_present) {
+		result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
+				ACPI_SBS_MANAGER, 0x01, (u8 *)&state);
+		if (!result)
+			battery->present = state & (1 << battery->id);
+		state &= 0x0fff;
+		state |= 1 << (battery->id + 12);
+		acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD,
+				  ACPI_SBS_MANAGER, 0x01, (u8 *)&state, 2);
+	} else if (battery->id == 0)
+		battery->present = 1;
+	if (result || !battery->present)
+		return result;
+
+	if (saved_present != battery->present) {
+		battery->update_time = 0;
+		result = acpi_battery_get_info(battery);
+		if (result)
+			return result;
+	}
+	result = acpi_battery_get_state(battery);
+	return result;
+}
 
 /* Smart Battery */
-
 static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 {
-	int is_present;
+	struct acpi_battery *battery = &sbs->battery[id];
 	int result;
-	char dir_name[32];
-	struct acpi_battery *battery;
 
-	battery = &sbs->battery[id];
-
-	battery->alive = 0;
-
-	battery->init_state = 0;
 	battery->id = id;
 	battery->sbs = sbs;
+	result = acpi_battery_read(battery);
+	if (result)
+		return result;
 
-	result = acpi_battery_select(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_select() failed"));
-		goto end;
+	sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
+#ifdef CONFIG_ACPI_PROCFS
+	acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir,
+			battery->name, &acpi_battery_info_fops,
+			&acpi_battery_state_fops, &acpi_battery_alarm_fops,
+			battery);
+#endif
+	battery->bat.name = battery->name;
+	battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+	if (!acpi_battery_mode(battery)) {
+		battery->bat.properties = sbs_charge_battery_props;
+		battery->bat.num_properties =
+		    ARRAY_SIZE(sbs_charge_battery_props);
+	} else {
+		battery->bat.properties = sbs_energy_battery_props;
+		battery->bat.num_properties =
+		    ARRAY_SIZE(sbs_energy_battery_props);
 	}
-
-	result = acpi_battery_get_present(battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_battery_get_present() failed"));
-		goto end;
-	}
-
-	is_present = battery->battery_present;
-
-	if (is_present) {
-		result = acpi_battery_init(battery);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_battery_init() failed"));
-			goto end;
-		}
-		battery->init_state = 1;
-	}
-
-	sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
-
-	result = acpi_sbs_generic_add_fs(&battery->battery_entry,
-					 acpi_battery_dir,
-					 dir_name,
-					 &acpi_battery_info_fops,
-					 &acpi_battery_state_fops,
-					 &acpi_battery_alarm_fops, battery);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_generic_add_fs() failed"));
-		goto end;
-	}
-	battery->alive = 1;
-
+	battery->bat.get_property = acpi_sbs_battery_get_property;
+	result = power_supply_register(&sbs->device->dev, &battery->bat);
+	device_create_file(battery->bat.dev, &alarm_attr);
 	printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
-	       ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), dir_name,
-	       sbs->battery->battery_present ? "present" : "absent");
-
-      end:
+	       ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
+	       battery->name, sbs->battery->present ? "present" : "absent");
 	return result;
 }
 
 static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 {
-
-	if (sbs->battery[id].battery_entry) {
-		acpi_sbs_generic_remove_fs(&(sbs->battery[id].battery_entry),
-					   acpi_battery_dir);
+	if (sbs->battery[id].bat.dev)
+		device_remove_file(sbs->battery[id].bat.dev, &alarm_attr);
+		power_supply_unregister(&sbs->battery[id].bat);
+#ifdef CONFIG_ACPI_PROCFS
+	if (sbs->battery[id].proc_entry) {
+		acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry),
+				   acpi_battery_dir);
 	}
+#endif
 }
 
-static int acpi_ac_add(struct acpi_sbs *sbs)
+static int acpi_charger_add(struct acpi_sbs *sbs)
 {
 	int result;
 
 	result = acpi_ac_get_present(sbs);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_ac_get_present() failed"));
+	if (result)
 		goto end;
-	}
-
-	result = acpi_sbs_generic_add_fs(&sbs->ac_entry,
-					 acpi_ac_dir,
-					 ACPI_AC_DIR_NAME,
-					 NULL, &acpi_ac_state_fops, NULL, sbs);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_generic_add_fs() failed"));
+#ifdef CONFIG_ACPI_PROCFS
+	result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir,
+				 ACPI_AC_DIR_NAME, NULL,
+				 &acpi_ac_state_fops, NULL, sbs);
+	if (result)
 		goto end;
-	}
-
+#endif
+	sbs->charger.name = "sbs-charger";
+	sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
+	sbs->charger.properties = sbs_ac_props;
+	sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props);
+	sbs->charger.get_property = sbs_get_ac_property;
+	power_supply_register(&sbs->device->dev, &sbs->charger);
 	printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
 	       ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
-	       ACPI_AC_DIR_NAME, sbs->ac.ac_present ? "on-line" : "off-line");
-
+	       ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
       end:
-
 	return result;
 }
 
-static void acpi_ac_remove(struct acpi_sbs *sbs)
+static void acpi_charger_remove(struct acpi_sbs *sbs)
 {
+	if (sbs->charger.dev)
+		power_supply_unregister(&sbs->charger);
+#ifdef CONFIG_ACPI_PROCFS
+	if (sbs->charger_entry)
+		acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
+#endif
+}
 
-	if (sbs->ac_entry) {
-		acpi_sbs_generic_remove_fs(&sbs->ac_entry, acpi_ac_dir);
+void acpi_sbs_callback(void *context)
+{
+	int id;
+	struct acpi_sbs *sbs = context;
+	struct acpi_battery *bat;
+	u8 saved_charger_state = sbs->charger_present;
+	u8 saved_battery_state;
+	acpi_ac_get_present(sbs);
+	if (sbs->charger_present != saved_charger_state) {
+#ifdef CONFIG_ACPI_PROC_EVENT
+		acpi_bus_generate_proc_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME,
+					      ACPI_SBS_NOTIFY_STATUS,
+					      sbs->charger_present);
+#endif
+		kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
+	}
+	if (sbs->manager_present) {
+		for (id = 0; id < MAX_SBS_BAT; ++id) {
+			if (!(sbs->batteries_supported & (1 << id)))
+				continue;
+			bat = &sbs->battery[id];
+			saved_battery_state = bat->present;
+			acpi_battery_read(bat);
+			if (saved_battery_state == bat->present)
+				continue;
+#ifdef CONFIG_ACPI_PROC_EVENT
+			acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS,
+						      bat->name,
+						      ACPI_SBS_NOTIFY_STATUS,
+						      bat->present);
+#endif
+			kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE);
+		}
 	}
 }
 
-static void acpi_sbs_update_time_run(unsigned long data)
-{
-	acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_time, (void *)data);
-}
-
-static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
-{
-	struct acpi_battery *battery;
-	int result = 0, cnt;
-	int old_ac_present = -1;
-	int old_battery_present = -1;
-	int new_ac_present = -1;
-	int new_battery_present = -1;
-	int id_min = 0, id_max = MAX_SBS_BAT - 1;
-	char dir_name[32];
-	int do_battery_init = 0, do_ac_init = 0;
-	int old_remaining_capacity = 0;
-	int update_battery = 1;
-	int up_tm = update_time;
-
-	if (sbs_zombie(sbs)) {
-		goto end;
-	}
-
-	if (id >= 0) {
-		id_min = id_max = id;
-	}
-
-	if (data_type == DATA_TYPE_COMMON && up_tm > 0) {
-		cnt = up_tm / (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
-		if (sbs->run_cnt % cnt != 0) {
-			update_battery = 0;
-		}
-	}
-
-	sbs->run_cnt++;
-
-	old_ac_present = sbs->ac.ac_present;
-
-	result = acpi_ac_get_present(sbs);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_ac_get_present() failed"));
-	}
-
-	new_ac_present = sbs->ac.ac_present;
-
-	do_ac_init = (old_ac_present != new_ac_present);
-	if (sbs->run_cnt == 1 && data_type == DATA_TYPE_COMMON) {
-		do_ac_init = 1;
-	}
-
-	if (do_ac_init) {
-		result = acpi_sbs_generate_event(sbs->device,
-						 ACPI_SBS_AC_NOTIFY_STATUS,
-						 new_ac_present,
-						 ACPI_AC_DIR_NAME,
-						 ACPI_AC_CLASS);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_generate_event() failed"));
-		}
-	}
-
-	if (data_type == DATA_TYPE_COMMON) {
-		if (!do_ac_init && !update_battery) {
-			goto end;
-		}
-	}
-
-	if (data_type == DATA_TYPE_AC_STATE && !do_ac_init) {
-		goto end;
-	}
-
-	for (id = id_min; id <= id_max; id++) {
-		battery = &sbs->battery[id];
-		if (battery->alive == 0) {
-			continue;
-		}
-
-		old_remaining_capacity = battery->state.remaining_capacity;
-
-		old_battery_present = battery->battery_present;
-
-		result = acpi_battery_select(battery);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_battery_select() failed"));
-		}
-
-		result = acpi_battery_get_present(battery);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_battery_get_present() failed"));
-		}
-
-		new_battery_present = battery->battery_present;
-
-		do_battery_init = ((old_battery_present != new_battery_present)
-				   && new_battery_present);
-		if (!new_battery_present)
-			goto event;
-		if (do_ac_init || do_battery_init) {
-			result = acpi_battery_init(battery);
-			if (result) {
-				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_battery_init() "
-						"failed"));
-			}
-		}
-		if (sbs_zombie(sbs)) {
-			goto end;
-		}
-
-		if ((data_type == DATA_TYPE_COMMON
-		     || data_type == DATA_TYPE_INFO)
-		    && new_battery_present) {
-			result = acpi_battery_get_info(battery);
-			if (result) {
-				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_battery_get_info() failed"));
-			}
-		}
-		if (data_type == DATA_TYPE_INFO) {
-			continue;
-		}
-		if (sbs_zombie(sbs)) {
-			goto end;
-		}
-
-		if ((data_type == DATA_TYPE_COMMON
-		     || data_type == DATA_TYPE_STATE)
-		    && new_battery_present) {
-			result = acpi_battery_get_state(battery);
-			if (result) {
-				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_battery_get_state() failed"));
-			}
-		}
-		if (data_type == DATA_TYPE_STATE) {
-			goto event;
-		}
-		if (sbs_zombie(sbs)) {
-			goto end;
-		}
-
-		if ((data_type == DATA_TYPE_COMMON
-		     || data_type == DATA_TYPE_ALARM)
-		    && new_battery_present) {
-			result = acpi_battery_get_alarm(battery);
-			if (result) {
-				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_battery_get_alarm() "
-						"failed"));
-			}
-		}
-		if (data_type == DATA_TYPE_ALARM) {
-			continue;
-		}
-		if (sbs_zombie(sbs)) {
-			goto end;
-		}
-
-	      event:
-
-		if (old_battery_present != new_battery_present || do_ac_init ||
-		    old_remaining_capacity !=
-		    battery->state.remaining_capacity) {
-			sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
-			result = acpi_sbs_generate_event(sbs->device,
-							 ACPI_SBS_BATTERY_NOTIFY_STATUS,
-							 new_battery_present,
-							 dir_name,
-							 ACPI_BATTERY_CLASS);
-			if (result) {
-				ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-						"acpi_sbs_generate_event() "
-						"failed"));
-			}
-		}
-	}
-
-      end:
-
-	return result;
-}
-
-static void acpi_sbs_update_time(void *data)
-{
-	struct acpi_sbs *sbs = data;
-	unsigned long delay = -1;
-	int result;
-	unsigned int up_tm = update_time;
-
-	if (sbs_mutex_lock(sbs))
-		return;
-
-	result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_COMMON);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_sbs_update_run() failed"));
-	}
-
-	if (sbs_zombie(sbs)) {
-		goto end;
-	}
-
-	if (!up_tm) {
-		if (timer_pending(&sbs->update_timer))
-			del_timer(&sbs->update_timer);
-	} else {
-		delay = (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
-		delay = jiffies + HZ * delay;
-		if (timer_pending(&sbs->update_timer)) {
-			mod_timer(&sbs->update_timer, delay);
-		} else {
-			sbs->update_timer.data = (unsigned long)data;
-			sbs->update_timer.function = acpi_sbs_update_time_run;
-			sbs->update_timer.expires = delay;
-			add_timer(&sbs->update_timer);
-		}
-	}
-
-      end:
-
-	sbs_mutex_unlock(sbs);
-}
+static int acpi_sbs_remove(struct acpi_device *device, int type);
 
 static int acpi_sbs_add(struct acpi_device *device)
 {
-	struct acpi_sbs *sbs = NULL;
-	int result = 0, remove_result = 0;
+	struct acpi_sbs *sbs;
+	int result = 0;
 	int id;
-	acpi_status status = AE_OK;
-	unsigned long val;
-
-	status =
-	    acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC"));
-		return -EIO;
-	}
 
 	sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
 	if (!sbs) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kzalloc() failed"));
 		result = -ENOMEM;
 		goto end;
 	}
 
-	mutex_init(&sbs->mutex);
+	mutex_init(&sbs->lock);
 
-	sbs_mutex_lock(sbs);
-
-	sbs->base = 0xff & (val >> 8);
+	sbs->hc = acpi_driver_data(device->parent);
 	sbs->device = device;
-
 	strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
 	acpi_driver_data(device) = sbs;
 
-	result = acpi_ac_add(sbs);
-	if (result) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
-		goto end;
-	}
-
-	acpi_sbsm_get_info(sbs);
-
-	if (!sbs->sbsm_present) {
-		result = acpi_battery_add(sbs, 0);
-		if (result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_battery_add() failed"));
-			goto end;
-		}
-	} else {
-		for (id = 0; id < MAX_SBS_BAT; id++) {
-			if ((sbs->sbsm_batteries_supported & (1 << id))) {
-				result = acpi_battery_add(sbs, id);
-				if (result) {
-					ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-							"acpi_battery_add() failed"));
-					goto end;
-				}
-			}
-		}
-	}
-
-	init_timer(&sbs->update_timer);
-	result = acpi_check_update_proc(sbs);
+	result = acpi_charger_add(sbs);
 	if (result)
 		goto end;
 
+	result = acpi_manager_get_info(sbs);
+	if (!result) {
+		sbs->manager_present = 1;
+		for (id = 0; id < MAX_SBS_BAT; ++id)
+			if ((sbs->batteries_supported & (1 << id)))
+				acpi_battery_add(sbs, id);
+	} else
+		acpi_battery_add(sbs, 0);
+	acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs);
       end:
-
-	sbs_mutex_unlock(sbs);
-
-	if (result) {
-		remove_result = acpi_sbs_remove(device, 0);
-		if (remove_result) {
-			ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-					"acpi_sbs_remove() failed"));
-		}
-	}
-
+	if (result)
+		acpi_sbs_remove(device, 0);
 	return result;
 }
 
@@ -1713,39 +947,25 @@
 	struct acpi_sbs *sbs;
 	int id;
 
-	if (!device) {
+	if (!device)
 		return -EINVAL;
-	}
-
 	sbs = acpi_driver_data(device);
-	if (!sbs) {
+	if (!sbs)
 		return -EINVAL;
-	}
-
-	sbs_mutex_lock(sbs);
-
-	sbs->zombie = 1;
-	del_timer_sync(&sbs->update_timer);
-	acpi_os_wait_events_complete(NULL);
-	del_timer_sync(&sbs->update_timer);
-
-	for (id = 0; id < MAX_SBS_BAT; id++) {
+	mutex_lock(&sbs->lock);
+	acpi_smbus_unregister_callback(sbs->hc);
+	for (id = 0; id < MAX_SBS_BAT; ++id)
 		acpi_battery_remove(sbs, id);
-	}
-
-	acpi_ac_remove(sbs);
-
-	sbs_mutex_unlock(sbs);
-
-	mutex_destroy(&sbs->mutex);
-
+	acpi_charger_remove(sbs);
+	mutex_unlock(&sbs->lock);
+	mutex_destroy(&sbs->lock);
 	kfree(sbs);
-
 	return 0;
 }
 
 static void acpi_sbs_rmdirs(void)
 {
+#ifdef CONFIG_ACPI_PROCFS
 	if (acpi_ac_dir) {
 		acpi_unlock_ac_dir(acpi_ac_dir);
 		acpi_ac_dir = NULL;
@@ -1754,69 +974,58 @@
 		acpi_unlock_battery_dir(acpi_battery_dir);
 		acpi_battery_dir = NULL;
 	}
+#endif
 }
 
 static int acpi_sbs_resume(struct acpi_device *device)
 {
 	struct acpi_sbs *sbs;
-
 	if (!device)
 		return -EINVAL;
-
 	sbs = device->driver_data;
-
-	sbs->run_cnt = 0;
-
+	acpi_sbs_callback(sbs);
 	return 0;
 }
 
+static struct acpi_driver acpi_sbs_driver = {
+	.name = "sbs",
+	.class = ACPI_SBS_CLASS,
+	.ids = sbs_device_ids,
+	.ops = {
+		.add = acpi_sbs_add,
+		.remove = acpi_sbs_remove,
+		.resume = acpi_sbs_resume,
+		},
+};
+
 static int __init acpi_sbs_init(void)
 {
 	int result = 0;
 
 	if (acpi_disabled)
 		return -ENODEV;
-
-	if (capacity_mode != DEF_CAPACITY_UNIT
-	    && capacity_mode != MAH_CAPACITY_UNIT
-	    && capacity_mode != MWH_CAPACITY_UNIT) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"invalid capacity_mode = %d", capacity_mode));
-		return -EINVAL;
-	}
-
+#ifdef CONFIG_ACPI_PROCFS
 	acpi_ac_dir = acpi_lock_ac_dir();
-	if (!acpi_ac_dir) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_lock_ac_dir() failed"));
+	if (!acpi_ac_dir)
 		return -ENODEV;
-	}
-
 	acpi_battery_dir = acpi_lock_battery_dir();
 	if (!acpi_battery_dir) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_lock_battery_dir() failed"));
 		acpi_sbs_rmdirs();
 		return -ENODEV;
 	}
-
+#endif
 	result = acpi_bus_register_driver(&acpi_sbs_driver);
 	if (result < 0) {
-		ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-				"acpi_bus_register_driver() failed"));
 		acpi_sbs_rmdirs();
 		return -ENODEV;
 	}
-
 	return 0;
 }
 
 static void __exit acpi_sbs_exit(void)
 {
 	acpi_bus_unregister_driver(&acpi_sbs_driver);
-
 	acpi_sbs_rmdirs();
-
 	return;
 }
 
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
new file mode 100644
index 0000000..046d7c3
--- /dev/null
+++ b/drivers/acpi/sbshc.c
@@ -0,0 +1,309 @@
+/*
+ * SMBus driver for ACPI Embedded Controller (v0.1)
+ *
+ * Copyright (c) 2007 Alexey Starikovskiy
+ *
+ * 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.
+ */
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/actypes.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include "sbshc.h"
+
+#define ACPI_SMB_HC_CLASS	"smbus_host_controller"
+#define ACPI_SMB_HC_DEVICE_NAME	"ACPI SMBus HC"
+
+struct acpi_smb_hc {
+	struct acpi_ec *ec;
+	struct mutex lock;
+	wait_queue_head_t wait;
+	u8 offset;
+	u8 query_bit;
+	smbus_alarm_callback callback;
+	void *context;
+};
+
+static int acpi_smbus_hc_add(struct acpi_device *device);
+static int acpi_smbus_hc_remove(struct acpi_device *device, int type);
+
+static const struct acpi_device_id sbs_device_ids[] = {
+	{"ACPI0001", 0},
+	{"ACPI0005", 0},
+	{"", 0},
+};
+
+MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
+
+static struct acpi_driver acpi_smb_hc_driver = {
+	.name = "smbus_hc",
+	.class = ACPI_SMB_HC_CLASS,
+	.ids = sbs_device_ids,
+	.ops = {
+		.add = acpi_smbus_hc_add,
+		.remove = acpi_smbus_hc_remove,
+		},
+};
+
+union acpi_smb_status {
+	u8 raw;
+	struct {
+		u8 status:5;
+		u8 reserved:1;
+		u8 alarm:1;
+		u8 done:1;
+	} fields;
+};
+
+enum acpi_smb_status_codes {
+	SMBUS_OK = 0,
+	SMBUS_UNKNOWN_FAILURE = 0x07,
+	SMBUS_DEVICE_ADDRESS_NACK = 0x10,
+	SMBUS_DEVICE_ERROR = 0x11,
+	SMBUS_DEVICE_COMMAND_ACCESS_DENIED = 0x12,
+	SMBUS_UNKNOWN_ERROR = 0x13,
+	SMBUS_DEVICE_ACCESS_DENIED = 0x17,
+	SMBUS_TIMEOUT = 0x18,
+	SMBUS_HOST_UNSUPPORTED_PROTOCOL = 0x19,
+	SMBUS_BUSY = 0x1a,
+	SMBUS_PEC_ERROR = 0x1f,
+};
+
+enum acpi_smb_offset {
+	ACPI_SMB_PROTOCOL = 0,	/* protocol, PEC */
+	ACPI_SMB_STATUS = 1,	/* status */
+	ACPI_SMB_ADDRESS = 2,	/* address */
+	ACPI_SMB_COMMAND = 3,	/* command */
+	ACPI_SMB_DATA = 4,	/* 32 data registers */
+	ACPI_SMB_BLOCK_COUNT = 0x24,	/* number of data bytes */
+	ACPI_SMB_ALARM_ADDRESS = 0x25,	/* alarm address */
+	ACPI_SMB_ALARM_DATA = 0x26,	/* 2 bytes alarm data */
+};
+
+static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data)
+{
+	return ec_read(hc->offset + address, data);
+}
+
+static inline int smb_hc_write(struct acpi_smb_hc *hc, u8 address, u8 data)
+{
+	return ec_write(hc->offset + address, data);
+}
+
+static inline int smb_check_done(struct acpi_smb_hc *hc)
+{
+	union acpi_smb_status status = {.raw = 0};
+	smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw);
+	return status.fields.done && (status.fields.status == SMBUS_OK);
+}
+
+static int wait_transaction_complete(struct acpi_smb_hc *hc, int timeout)
+{
+	if (wait_event_timeout(hc->wait, smb_check_done(hc),
+			       msecs_to_jiffies(timeout)))
+		return 0;
+	else
+		return -ETIME;
+}
+
+int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+		    u8 command, u8 *data, u8 length)
+{
+	int ret = -EFAULT, i;
+	u8 temp, sz = 0;
+
+	mutex_lock(&hc->lock);
+	if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp))
+		goto end;
+	if (temp) {
+		ret = -EBUSY;
+		goto end;
+	}
+	smb_hc_write(hc, ACPI_SMB_COMMAND, command);
+	smb_hc_write(hc, ACPI_SMB_COMMAND, command);
+	if (!(protocol & 0x01)) {
+		smb_hc_write(hc, ACPI_SMB_BLOCK_COUNT, length);
+		for (i = 0; i < length; ++i)
+			smb_hc_write(hc, ACPI_SMB_DATA + i, data[i]);
+	}
+	smb_hc_write(hc, ACPI_SMB_ADDRESS, address << 1);
+	smb_hc_write(hc, ACPI_SMB_PROTOCOL, protocol);
+	/*
+	 * Wait for completion. Save the status code, data size,
+	 * and data into the return package (if required by the protocol).
+	 */
+	ret = wait_transaction_complete(hc, 1000);
+	if (ret || !(protocol & 0x01))
+		goto end;
+	switch (protocol) {
+	case SMBUS_RECEIVE_BYTE:
+	case SMBUS_READ_BYTE:
+		sz = 1;
+		break;
+	case SMBUS_READ_WORD:
+		sz = 2;
+		break;
+	case SMBUS_READ_BLOCK:
+		if (smb_hc_read(hc, ACPI_SMB_BLOCK_COUNT, &sz)) {
+			ret = -EFAULT;
+			goto end;
+		}
+		sz &= 0x1f;
+		break;
+	}
+	for (i = 0; i < sz; ++i)
+		smb_hc_read(hc, ACPI_SMB_DATA + i, &data[i]);
+      end:
+	mutex_unlock(&hc->lock);
+	return ret;
+}
+
+int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+		    u8 command, u8 *data)
+{
+	return acpi_smbus_transaction(hc, protocol, address, command, data, 0);
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_read);
+
+int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+		     u8 command, u8 *data, u8 length)
+{
+	return acpi_smbus_transaction(hc, protocol, address, command, data, length);
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_write);
+
+int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
+			         smbus_alarm_callback callback, void *context)
+{
+	mutex_lock(&hc->lock);
+	hc->callback = callback;
+	hc->context = context;
+	mutex_unlock(&hc->lock);
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_register_callback);
+
+int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc)
+{
+	mutex_lock(&hc->lock);
+	hc->callback = NULL;
+	hc->context = NULL;
+	mutex_unlock(&hc->lock);
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_unregister_callback);
+
+static void acpi_smbus_callback(void *context)
+{
+	struct acpi_smb_hc *hc = context;
+
+	if (hc->callback)
+		hc->callback(hc->context);
+}
+
+static int smbus_alarm(void *context)
+{
+	struct acpi_smb_hc *hc = context;
+	union acpi_smb_status status;
+	if (smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw))
+		return 0;
+	/* Check if it is only a completion notify */
+	if (status.fields.done)
+		wake_up(&hc->wait);
+	if (!status.fields.alarm)
+		return 0;
+	mutex_lock(&hc->lock);
+	smb_hc_write(hc, ACPI_SMB_STATUS, status.raw);
+	if (hc->callback)
+		acpi_os_execute(OSL_GPE_HANDLER, acpi_smbus_callback, hc);
+	mutex_unlock(&hc->lock);
+	return 0;
+}
+
+typedef int (*acpi_ec_query_func) (void *data);
+
+extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
+			      acpi_handle handle, acpi_ec_query_func func,
+			      void *data);
+
+static int acpi_smbus_hc_add(struct acpi_device *device)
+{
+	int status;
+	unsigned long val;
+	struct acpi_smb_hc *hc;
+
+	if (!device)
+		return -EINVAL;
+
+	status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "error obtaining _EC.\n");
+		return -EIO;
+	}
+
+	strcpy(acpi_device_name(device), ACPI_SMB_HC_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_SMB_HC_CLASS);
+
+	hc = kzalloc(sizeof(struct acpi_smb_hc), GFP_KERNEL);
+	if (!hc)
+		return -ENOMEM;
+	mutex_init(&hc->lock);
+	init_waitqueue_head(&hc->wait);
+
+	hc->ec = acpi_driver_data(device->parent);
+	hc->offset = (val >> 8) & 0xff;
+	hc->query_bit = val & 0xff;
+	acpi_driver_data(device) = hc;
+
+	acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
+	printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
+		hc->ec, hc->offset, hc->query_bit);
+
+	return 0;
+}
+
+extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
+
+static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
+{
+	struct acpi_smb_hc *hc;
+
+	if (!device)
+		return -EINVAL;
+
+	hc = acpi_driver_data(device);
+	acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
+	kfree(hc);
+	return 0;
+}
+
+static int __init acpi_smb_hc_init(void)
+{
+	int result;
+
+	result = acpi_bus_register_driver(&acpi_smb_hc_driver);
+	if (result < 0)
+		return -ENODEV;
+	return 0;
+}
+
+static void __exit acpi_smb_hc_exit(void)
+{
+	acpi_bus_unregister_driver(&acpi_smb_hc_driver);
+}
+
+module_init(acpi_smb_hc_init);
+module_exit(acpi_smb_hc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexey Starikovskiy");
+MODULE_DESCRIPTION("ACPI SMBus HC driver");
diff --git a/drivers/acpi/sbshc.h b/drivers/acpi/sbshc.h
new file mode 100644
index 0000000..3bda349
--- /dev/null
+++ b/drivers/acpi/sbshc.h
@@ -0,0 +1,27 @@
+struct acpi_smb_hc;
+enum acpi_smb_protocol {
+	SMBUS_WRITE_QUICK = 2,
+	SMBUS_READ_QUICK = 3,
+	SMBUS_SEND_BYTE = 4,
+	SMBUS_RECEIVE_BYTE = 5,
+	SMBUS_WRITE_BYTE = 6,
+	SMBUS_READ_BYTE = 7,
+	SMBUS_WRITE_WORD  = 8,
+	SMBUS_READ_WORD  = 9,
+	SMBUS_WRITE_BLOCK = 0xa,
+	SMBUS_READ_BLOCK = 0xb,
+	SMBUS_PROCESS_CALL = 0xc,
+	SMBUS_BLOCK_PROCESS_CALL = 0xd,
+};
+
+static const u8 SMBUS_PEC = 0x80;
+
+typedef void (*smbus_alarm_callback)(void *context);
+
+extern int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+	       u8 command, u8 * data);
+extern int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 slave_address,
+		u8 command, u8 * data, u8 length);
+extern int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
+			         smbus_alarm_callback callback, void *context);
+extern int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc);
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 5055acf..f3d3867 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -44,13 +44,12 @@
 	ACPI_FLUSH_CPU_CACHE();
 	acpi_enable_wakeup_device_prep(acpi_state);
 #endif
-	acpi_gpe_sleep_prepare(acpi_state);
 	acpi_enter_sleep_state_prep(acpi_state);
 	return 0;
 }
 
 #ifdef CONFIG_SUSPEND
-static struct pm_ops acpi_pm_ops;
+static struct platform_suspend_ops acpi_pm_ops;
 
 extern void do_suspend_lowlevel(void);
 
@@ -85,13 +84,12 @@
 
 /**
  *	acpi_pm_prepare - Do preliminary suspend work.
- *	@pm_state: ignored
  *
  *	If necessary, set the firmware waking vector and do arch-specific
  *	nastiness to get the wakeup code to the waking vector.
  */
 
-static int acpi_pm_prepare(suspend_state_t pm_state)
+static int acpi_pm_prepare(void)
 {
 	int error = acpi_sleep_prepare(acpi_target_sleep_state);
 
@@ -160,13 +158,12 @@
 
 /**
  *	acpi_pm_finish - Finish up suspend sequence.
- *	@pm_state: ignored
  *
  *	This is called after we wake back up (or if entering the sleep state
  *	failed). 
  */
 
-static int acpi_pm_finish(suspend_state_t pm_state)
+static void acpi_pm_finish(void)
 {
 	u32 acpi_state = acpi_target_sleep_state;
 
@@ -184,7 +181,6 @@
 		init_8259A(0);
 	}
 #endif
-	return 0;
 }
 
 static int acpi_pm_state_valid(suspend_state_t pm_state)
@@ -203,7 +199,7 @@
 	}
 }
 
-static struct pm_ops acpi_pm_ops = {
+static struct platform_suspend_ops acpi_pm_ops = {
 	.valid = acpi_pm_state_valid,
 	.set_target = acpi_pm_set_target,
 	.prepare = acpi_pm_prepare,
@@ -233,6 +229,12 @@
 #endif /* CONFIG_SUSPEND */
 
 #ifdef CONFIG_HIBERNATION
+static int acpi_hibernation_start(void)
+{
+	acpi_target_sleep_state = ACPI_STATE_S4;
+	return 0;
+}
+
 static int acpi_hibernation_prepare(void)
 {
 	return acpi_sleep_prepare(ACPI_STATE_S4);
@@ -254,13 +256,29 @@
 	return ACPI_SUCCESS(status) ? 0 : -EFAULT;
 }
 
+static void acpi_hibernation_leave(void)
+{
+	/*
+	 * If ACPI is not enabled by the BIOS and the boot kernel, we need to
+	 * enable it here.
+	 */
+	acpi_enable();
+}
+
 static void acpi_hibernation_finish(void)
 {
+	/*
+	 * If ACPI is not enabled by the BIOS and the boot kernel, we need to
+	 * enable it here.
+	 */
+	acpi_enable();
 	acpi_leave_sleep_state(ACPI_STATE_S4);
 	acpi_disable_wakeup_device(ACPI_STATE_S4);
 
 	/* reset firmware waking vector */
 	acpi_set_firmware_waking_vector((acpi_physical_address) 0);
+
+	acpi_target_sleep_state = ACPI_STATE_S0;
 }
 
 static int acpi_hibernation_pre_restore(void)
@@ -277,10 +295,13 @@
 	acpi_hw_enable_all_runtime_gpes();
 }
 
-static struct hibernation_ops acpi_hibernation_ops = {
+static struct platform_hibernation_ops acpi_hibernation_ops = {
+	.start = acpi_hibernation_start,
+	.pre_snapshot = acpi_hibernation_prepare,
+	.finish = acpi_hibernation_finish,
 	.prepare = acpi_hibernation_prepare,
 	.enter = acpi_hibernation_enter,
-	.finish = acpi_hibernation_finish,
+	.leave = acpi_hibernation_leave,
 	.pre_restore = acpi_hibernation_pre_restore,
 	.restore_cleanup = acpi_hibernation_restore_cleanup,
 };
@@ -417,7 +438,7 @@
 		}
 	}
 
-	pm_set_ops(&acpi_pm_ops);
+	suspend_set_ops(&acpi_pm_ops);
 #endif
 
 #ifdef CONFIG_HIBERNATION
diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h
index ff1f850..a2ea125 100644
--- a/drivers/acpi/sleep/sleep.h
+++ b/drivers/acpi/sleep/sleep.h
@@ -5,6 +5,5 @@
 extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
 extern void acpi_enable_wakeup_device(u8 sleep_state);
 extern void acpi_disable_wakeup_device(u8 sleep_state);
-extern void acpi_gpe_sleep_prepare(u32 sleep_state);
 
 extern int acpi_sleep_prepare(u32 acpi_state);
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
index 97c27dd..ed8e41b 100644
--- a/drivers/acpi/sleep/wakeup.c
+++ b/drivers/acpi/sleep/wakeup.c
@@ -64,36 +64,29 @@
 	ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device");
 	spin_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
-		struct acpi_device *dev = container_of(node,
-						       struct acpi_device,
-						       wakeup_list);
-
+		struct acpi_device *dev =
+			container_of(node, struct acpi_device, wakeup_list);
+		if (!dev->wakeup.flags.valid)
+			continue;
 		/* If users want to disable run-wake GPE,
 		 * we only disable it for wake and leave it for runtime
 		 */
-		if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
-			spin_unlock(&acpi_device_lock);
-			acpi_set_gpe_type(dev->wakeup.gpe_device,
-					  dev->wakeup.gpe_number,
-					  ACPI_GPE_TYPE_RUNTIME);
-			/* Re-enable it, since set_gpe_type will disable it */
-			acpi_enable_gpe(dev->wakeup.gpe_device,
-					dev->wakeup.gpe_number, ACPI_ISR);
-			spin_lock(&acpi_device_lock);
+		if (!dev->wakeup.state.enabled ||
+		    sleep_state > (u32) dev->wakeup.sleep_state) {
+			if (dev->wakeup.flags.run_wake) {
+				spin_unlock(&acpi_device_lock);
+				/* set_gpe_type will disable GPE, leave it like that */
+				acpi_set_gpe_type(dev->wakeup.gpe_device,
+						  dev->wakeup.gpe_number,
+						  ACPI_GPE_TYPE_RUNTIME);
+				spin_lock(&acpi_device_lock);
+			}
 			continue;
 		}
-
-		if (!dev->wakeup.flags.valid ||
-		    !dev->wakeup.state.enabled ||
-		    (sleep_state > (u32) dev->wakeup.sleep_state))
-			continue;
-
 		spin_unlock(&acpi_device_lock);
-		/* run-wake GPE has been enabled */
 		if (!dev->wakeup.flags.run_wake)
 			acpi_enable_gpe(dev->wakeup.gpe_device,
 					dev->wakeup.gpe_number, ACPI_ISR);
-		dev->wakeup.state.active = 1;
 		spin_lock(&acpi_device_lock);
 	}
 	spin_unlock(&acpi_device_lock);
@@ -112,27 +105,26 @@
 
 	spin_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
-		struct acpi_device *dev = container_of(node,
-						       struct acpi_device,
-						       wakeup_list);
+		struct acpi_device *dev =
+			container_of(node, struct acpi_device, wakeup_list);
 
-		if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
-			spin_unlock(&acpi_device_lock);
-			acpi_set_gpe_type(dev->wakeup.gpe_device,
-					  dev->wakeup.gpe_number,
-					  ACPI_GPE_TYPE_WAKE_RUN);
-			/* Re-enable it, since set_gpe_type will disable it */
-			acpi_enable_gpe(dev->wakeup.gpe_device,
-					dev->wakeup.gpe_number, ACPI_NOT_ISR);
-			spin_lock(&acpi_device_lock);
+		if (!dev->wakeup.flags.valid)
+			continue;
+		if (!dev->wakeup.state.enabled ||
+		    sleep_state > (u32) dev->wakeup.sleep_state) {
+			if (dev->wakeup.flags.run_wake) {
+				spin_unlock(&acpi_device_lock);
+				acpi_set_gpe_type(dev->wakeup.gpe_device,
+						  dev->wakeup.gpe_number,
+						  ACPI_GPE_TYPE_WAKE_RUN);
+				/* Re-enable it, since set_gpe_type will disable it */
+				acpi_enable_gpe(dev->wakeup.gpe_device,
+						dev->wakeup.gpe_number, ACPI_NOT_ISR);
+				spin_lock(&acpi_device_lock);
+			}
 			continue;
 		}
 
-		if (!dev->wakeup.flags.valid ||
-		    !dev->wakeup.state.active ||
-		    (sleep_state > (u32) dev->wakeup.sleep_state))
-			continue;
-
 		spin_unlock(&acpi_device_lock);
 		acpi_disable_wakeup_device_power(dev);
 		/* Never disable run-wake GPE */
@@ -142,7 +134,6 @@
 			acpi_clear_gpe(dev->wakeup.gpe_device,
 				       dev->wakeup.gpe_number, ACPI_NOT_ISR);
 		}
-		dev->wakeup.state.active = 0;
 		spin_lock(&acpi_device_lock);
 	}
 	spin_unlock(&acpi_device_lock);
@@ -160,48 +151,20 @@
 		struct acpi_device *dev = container_of(node,
 						       struct acpi_device,
 						       wakeup_list);
-
 		/* In case user doesn't load button driver */
-		if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
-			spin_unlock(&acpi_device_lock);
-			acpi_set_gpe_type(dev->wakeup.gpe_device,
-					  dev->wakeup.gpe_number,
-					  ACPI_GPE_TYPE_WAKE_RUN);
-			acpi_enable_gpe(dev->wakeup.gpe_device,
-					dev->wakeup.gpe_number, ACPI_NOT_ISR);
-			dev->wakeup.state.enabled = 1;
-			spin_lock(&acpi_device_lock);
-		}
+		if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
+			continue;
+		spin_unlock(&acpi_device_lock);
+		acpi_set_gpe_type(dev->wakeup.gpe_device,
+				  dev->wakeup.gpe_number,
+				  ACPI_GPE_TYPE_WAKE_RUN);
+		acpi_enable_gpe(dev->wakeup.gpe_device,
+				dev->wakeup.gpe_number, ACPI_NOT_ISR);
+		dev->wakeup.state.enabled = 1;
+		spin_lock(&acpi_device_lock);
 	}
 	spin_unlock(&acpi_device_lock);
-
 	return 0;
 }
 
 late_initcall(acpi_wakeup_device_init);
-
-/*
- * Disable all wakeup GPEs before entering requested sleep state.
- *	@sleep_state:	ACPI state
- * Since acpi_enter_sleep_state() will disable all
- * RUNTIME GPEs, we simply mark all GPES that
- * are not enabled for wakeup from requested state as RUNTIME.
- */
-void acpi_gpe_sleep_prepare(u32 sleep_state)
-{
-	struct list_head *node, *next;
-
-	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
-		struct acpi_device *dev = container_of(node,
-						       struct acpi_device,
-						       wakeup_list);
-
-		/* The GPE can wakeup system from this state, don't touch it */
-		if ((u32) dev->wakeup.sleep_state >= sleep_state)
-			continue;
-		/* acpi_set_gpe_type will automatically disable GPE */
-		acpi_set_gpe_type(dev->wakeup.gpe_device,
-				  dev->wakeup.gpe_number,
-				  ACPI_GPE_TYPE_RUNTIME);
-	}
-}
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 8cc9492..5f1d85f 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -400,7 +400,7 @@
 	u32 table_count;
 	struct acpi_table_header *table;
 	acpi_physical_address address;
-	acpi_physical_address rsdt_address;
+	acpi_physical_address uninitialized_var(rsdt_address);
 	u32 length;
 	u8 *table_entry;
 	acpi_status status;
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index ad898e1..5f79b44 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -195,6 +195,7 @@
 	struct acpi_thermal_trips trips;
 	struct acpi_handle_list devices;
 	struct timer_list timer;
+	struct mutex lock;
 };
 
 static const struct file_operations acpi_thermal_state_fops = {
@@ -711,6 +712,7 @@
 	int result = 0;
 	struct acpi_thermal *tz = data;
 	unsigned long sleep_time = 0;
+	unsigned long timeout_jiffies = 0;
 	int i = 0;
 	struct acpi_thermal_state state;
 
@@ -720,11 +722,15 @@
 		return;
 	}
 
+	/* Check if someone else is already running */
+	if (!mutex_trylock(&tz->lock))
+		return;
+
 	state = tz->state;
 
 	result = acpi_thermal_get_temperature(tz);
 	if (result)
-		return;
+		goto unlock;
 
 	memset(&tz->state, 0, sizeof(tz->state));
 
@@ -787,10 +793,13 @@
 	 * a thermal event occurs).  Note that _TSP and _TZD values are
 	 * given in 1/10th seconds (we must covert to milliseconds).
 	 */
-	if (tz->state.passive)
+	if (tz->state.passive) {
 		sleep_time = tz->trips.passive.tsp * 100;
-	else if (tz->polling_frequency > 0)
+		timeout_jiffies =  jiffies + (HZ * sleep_time) / 1000;
+	} else if (tz->polling_frequency > 0) {
 		sleep_time = tz->polling_frequency * 100;
+		timeout_jiffies =  round_jiffies(jiffies + (HZ * sleep_time) / 1000);
+	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
 			  tz->name, tz->temperature, sleep_time));
@@ -804,17 +813,16 @@
 			del_timer(&(tz->timer));
 	} else {
 		if (timer_pending(&(tz->timer)))
-			mod_timer(&(tz->timer),
-					jiffies + (HZ * sleep_time) / 1000);
+			mod_timer(&(tz->timer), timeout_jiffies);
 		else {
 			tz->timer.data = (unsigned long)tz;
 			tz->timer.function = acpi_thermal_run;
-			tz->timer.expires = jiffies + (HZ * sleep_time) / 1000;
+			tz->timer.expires = timeout_jiffies;
 			add_timer(&(tz->timer));
 		}
 	}
-
-	return;
+      unlock:
+	mutex_unlock(&tz->lock);
 }
 
 /* --------------------------------------------------------------------------
@@ -1251,7 +1259,7 @@
 	strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
 	acpi_driver_data(device) = tz;
-
+	mutex_init(&tz->lock);
 	result = acpi_thermal_get_info(tz);
 	if (result)
 		goto end;
@@ -1321,7 +1329,7 @@
 	}
 
 	acpi_thermal_remove_fs(device);
-
+	mutex_destroy(&tz->lock);
 	kfree(tz);
 	return 0;
 }
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index b8a2095..bac956b 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -409,14 +409,17 @@
 static int
 acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
 {
-	int status;
+	int status = AE_OK;
 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list args = { 1, &arg0 };
 
 
 	arg0.integer.value = level;
-	status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL);
 
+	if (device->cap._BCM)
+		status = acpi_evaluate_object(device->dev->handle, "_BCM",
+					      &args, NULL);
+	device->brightness->curr = level;
 	return status;
 }
 
@@ -424,11 +427,11 @@
 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
 					unsigned long *level)
 {
-	int status;
-
-	status = acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, level);
-
-	return status;
+	if (device->cap._BQC)
+		return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
+					     level);
+	*level = device->brightness->curr;
+	return AE_OK;
 }
 
 static int
@@ -1633,9 +1636,20 @@
 acpi_video_get_next_level(struct acpi_video_device *device,
 			  u32 level_current, u32 event)
 {
-	int min, max, min_above, max_below, i, l;
+	int min, max, min_above, max_below, i, l, delta = 255;
 	max = max_below = 0;
 	min = min_above = 255;
+	/* Find closest level to level_current */
+	for (i = 0; i < device->brightness->count; i++) {
+		l = device->brightness->levels[i];
+		if (abs(l - level_current) < abs(delta)) {
+			delta = l - level_current;
+			if (!delta)
+				break;
+		}
+	}
+	/* Ajust level_current to closest available level */
+	level_current += delta;
 	for (i = 0; i < device->brightness->count; i++) {
 		l = device->brightness->levels[i];
 		if (l < min)
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 33f5eb0..ba63619 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -182,6 +182,15 @@
 	  firmware in the BIOS. This driver can sometimes handle
 	  otherwise unsupported hardware.
 
+config SATA_FSL
+	tristate "Freescale 3.0Gbps SATA support"
+	depends on PPC_MPC837x
+	help
+	  This option enables support for Freescale 3.0Gbps SATA controller.
+	  It can be found on MPC837x and MPC8315.
+
+	  If unsure, say N.
+
 config PATA_ALI
 	tristate "ALi PATA support (Experimental)"
 	depends on PCI && EXPERIMENTAL
@@ -641,11 +650,4 @@
 
 	  If unsure, say N.
 
-config PATA_BF54X_DMA
-	bool "DMA mode"
-	depends on PATA_BF54X
-	default y
-	help
-	  Enable DMA mode for Blackfin ATAPI controller.
-
 endif # ATA
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 6bdc307..b13feb2 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -17,6 +17,7 @@
 obj-$(CONFIG_SATA_MV)		+= sata_mv.o
 obj-$(CONFIG_SATA_INIC162X)	+= sata_inic162x.o
 obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
+obj-$(CONFIG_SATA_FSL)		+= sata_fsl.o
 
 obj-$(CONFIG_PATA_ALI)		+= pata_ali.o
 obj-$(CONFIG_PATA_AMD)		+= pata_amd.o
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 10bc3f6..47c8060 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1479,7 +1479,7 @@
 		return;
 	}
 
-	/* hmmm... a spurious interupt */
+	/* hmmm... a spurious interrupt */
 
 	/* if !NCQ, ignore.  No modern ATA device has broken HSM
 	 * implementation for non-NCQ commands.
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bbaa545..69092bc 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1392,7 +1392,7 @@
  *	@tf: Taskfile registers for the command and the result
  *	@cdb: CDB for packet command
  *	@dma_dir: Data tranfer direction of the command
- *	@sg: sg list for the data buffer of the command
+ *	@sgl: sg list for the data buffer of the command
  *	@n_elem: Number of sg entries
  *	@timeout: Timeout in msecs (0 for default)
  *
@@ -4296,7 +4296,7 @@
 		sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
 		if (pad_buf) {
 			struct scatterlist *psg = &qc->pad_sgent;
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(addr + psg->offset, pad_buf, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4686,11 +4686,11 @@
 		 * data in this function or read data in ata_sg_clean.
 		 */
 		offset = lsg->offset + lsg->length - qc->pad_len;
-		psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT);
+		sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT));
 		psg->offset = offset_in_page(offset);
 
 		if (qc->tf.flags & ATA_TFLAG_WRITE) {
-			void *addr = kmap_atomic(psg->page, KM_IRQ0);
+			void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
 			memcpy(pad_buf, addr + psg->offset, qc->pad_len);
 			kunmap_atomic(addr, KM_IRQ0);
 		}
@@ -4836,7 +4836,7 @@
 	if (qc->curbytes == qc->nbytes - qc->sect_size)
 		ap->hsm_task_state = HSM_ST_LAST;
 
-	page = qc->cursg->page;
+	page = sg_page(qc->cursg);
 	offset = qc->cursg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
@@ -4988,7 +4988,7 @@
 
 	sg = qc->cursg;
 
-	page = sg->page;
+	page = sg_page(sg);
 	offset = sg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9fbb39c..5b758b9 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1544,7 +1544,7 @@
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	if (sg) {
-		buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 		buflen = sg->length;
 	} else {
 		buf = NULL;
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 026439e..8227c45 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -156,7 +156,7 @@
 {
 	struct ata_ioports *ioaddr = &ap->ioaddr;
 
-	tf->command = ata_check_status(ap);
+	tf->command = ata_chk_status(ap);
 	tf->feature = ioread8(ioaddr->error_addr);
 	tf->nsect = ioread8(ioaddr->nsect_addr);
 	tf->lbal = ioread8(ioaddr->lbal_addr);
@@ -856,7 +856,7 @@
  *	@pdev: PCI device
  *
  *	Some PCI ATA devices report simplex mode but in fact can be told to
- *	enter non simplex mode. This implements the neccessary logic to
+ *	enter non simplex mode. This implements the necessary logic to
  *	perform the task on such devices. Calling it on other devices will
  *	have -undefined- behaviour.
  */
@@ -882,7 +882,7 @@
 	/* Filter out DMA modes if the device has been configured by
 	   the BIOS as PIO only */
 
-	if (adev->link->ap->ioaddr.bmdma_addr == 0)
+	if (adev->link->ap->ioaddr.bmdma_addr == NULL)
 		xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
 	return xfer_mask;
 }
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index 5d3920f..0f6f7bc 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -370,8 +370,10 @@
 	.id_table		= pacpi_pci_tbl,
 	.probe			= pacpi_init_one,
 	.remove			= ata_pci_remove_one,
+#ifdef CONFIG_PM
 	.suspend		= ata_pci_device_suspend,
 	.resume			= ata_pci_device_resume,
+#endif
 };
 
 static int __init pacpi_init(void)
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c
index 747549e..b5e3842 100644
--- a/drivers/ata/pata_bf54x.c
+++ b/drivers/ata/pata_bf54x.c
@@ -1092,14 +1092,15 @@
  *	Note: Original code is ata_std_softreset().
  */
 
-static int bfin_std_softreset(struct ata_port *ap, unsigned int *classes,
+static int bfin_std_softreset(struct ata_link *link, unsigned int *classes,
 		unsigned long deadline)
 {
+	struct ata_port *ap = link->ap;
 	unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
 	unsigned int devmask = 0, err_mask;
 	u8 err;
 
-	if (ata_port_offline(ap)) {
+	if (ata_link_offline(link)) {
 		classes[0] = ATA_DEV_NONE;
 		goto out;
 	}
@@ -1122,9 +1123,11 @@
 	}
 
 	/* determine by signature whether we have ATA or ATAPI devices */
-	classes[0] = ata_dev_try_classify(ap, 0, &err);
+	classes[0] = ata_dev_try_classify(&ap->link.device[0],
+				devmask & (1 << 0), &err);
 	if (slave_possible && err != 0x81)
-		classes[1] = ata_dev_try_classify(ap, 1, &err);
+		classes[1] = ata_dev_try_classify(&ap->link.device[1],
+					devmask & (1 << 1), &err);
 
  out:
 	return 0;
@@ -1167,7 +1170,7 @@
 static void bfin_data_xfer(struct ata_device *adev, unsigned char *buf,
 			   unsigned int buflen, int write_data)
 {
-	struct ata_port *ap = adev->ap;
+	struct ata_port *ap = adev->link->ap;
 	unsigned int words = buflen >> 1;
 	unsigned short *buf16 = (u16 *) buf;
 	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
@@ -1206,7 +1209,10 @@
 	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
 
 	pr_debug("in atapi irq clear\n");
-	ATAPI_SET_INT_STATUS(base, 0x1FF);
+
+	ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT
+		| MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT
+		| MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT);
 }
 
 /**
@@ -1234,33 +1240,6 @@
 }
 
 /**
- *	bfin_irq_ack - Acknowledge a device interrupt.
- *	@ap: Port on which interrupts are enabled.
- *
- *	Note: Original code is ata_irq_ack().
- */
-
-static unsigned char bfin_irq_ack(struct ata_port *ap, unsigned int chk_drq)
-{
-	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
-	unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
-	unsigned char status;
-
-	pr_debug("in atapi irq ack\n");
-	status = ata_busy_wait(ap, bits, 1000);
-	if (status & bits)
-		if (ata_msg_err(ap))
-			dev_err(ap->dev, "abnormal status 0x%X\n", status);
-
-	/* get controller status; clear intr, err bits */
-	ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT
-		| MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT
-		| MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT);
-
-	return bfin_bmdma_status(ap);
-}
-
-/**
  *	bfin_bmdma_freeze - Freeze DMA controller port
  *	@ap: port to freeze
  *
@@ -1308,8 +1287,9 @@
  *	Note: Original code is ata_std_postreset().
  */
 
-static void bfin_std_postreset(struct ata_port *ap, unsigned int *classes)
+static void bfin_std_postreset(struct ata_link *link, unsigned int *classes)
 {
+	struct ata_port *ap = link->ap;
 	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
 
 	/* re-enable interrupts */
@@ -1395,7 +1375,6 @@
 };
 
 static const struct ata_port_operations bfin_pata_ops = {
-	.port_disable		= ata_port_disable,
 	.set_piomode		= bfin_set_piomode,
 	.set_dmamode		= bfin_set_dmamode,
 
@@ -1423,7 +1402,6 @@
 	.irq_handler		= ata_interrupt,
 	.irq_clear		= bfin_irq_clear,
 	.irq_on			= bfin_irq_on,
-	.irq_ack		= bfin_irq_ack,
 
 	.port_start		= bfin_port_start,
 	.port_stop		= bfin_port_stop,
@@ -1437,11 +1415,7 @@
 				| ATA_FLAG_NO_LEGACY,
 		.pio_mask	= 0x1f,	/* pio0-4 */
 		.mwdma_mask	= 0,
-#ifdef CONFIG_PATA_BF54X_DMA
-		.udma_mask	= ATA_UDMA5,
-#else
 		.udma_mask	= 0,
-#endif
 		.port_ops	= &bfin_pata_ops,
 	},
 };
@@ -1607,9 +1581,25 @@
 	},
 };
 
+#define ATAPI_MODE_SIZE		10
+static char bfin_atapi_mode[ATAPI_MODE_SIZE];
+
 static int __init bfin_atapi_init(void)
 {
 	pr_info("register bfin atapi driver\n");
+
+	switch(bfin_atapi_mode[0]) {
+	case 'p':
+	case 'P':
+		break;
+	case 'm':
+	case 'M':
+		bfin_port_info[0].mwdma_mask = ATA_MWDMA2;
+		break;
+	default:
+		bfin_port_info[0].udma_mask = ATA_UDMA5;
+	};
+
 	return platform_driver_register(&bfin_atapi_driver);
 }
 
@@ -1620,6 +1610,13 @@
 
 module_init(bfin_atapi_init);
 module_exit(bfin_atapi_exit);
+/*
+ * ATAPI mode:
+ * pio/PIO
+ * udma/UDMA (default)
+ * mwdma/MWDMA
+ */
+module_param_string(bfin_atapi_mode, bfin_atapi_mode, ATAPI_MODE_SIZE, 0);
 
 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
 MODULE_DESCRIPTION("PATA driver for blackfin 54x ATAPI controller");
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 9e412c2..7acbbd9 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -215,7 +215,7 @@
 	regU &= ~(0x05 << adev->devno);
 
 	if (adev->dma_mode >= XFER_UDMA_0) {
-		/* Merge thge timing value */
+		/* Merge the timing value */
 		regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;
 		/* Merge the control bits */
 		regU |= 1 << adev->devno; /* UDMA on */
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 57e827e..e1818fd 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -138,7 +138,7 @@
  *
  *	Called when the libata layer is about to issue a command. We wrap
  *	this interface so that we can load the correct ATA timings if
- *	neccessary.  Specifically we have a problem that there is only
+ *	necessary.  Specifically we have a problem that there is only
  *	one MWDMA/UDMA bit.
  */
 
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index 3578593..0132453 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -25,7 +25,7 @@
  * Documentation:
  *	Available from AMD web site.
  * TODO
- *	Review errata to see if serializing is neccessary
+ *	Review errata to see if serializing is necessary
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c
index 53070f6..d753e56 100644
--- a/drivers/ata/pata_cs5536.c
+++ b/drivers/ata/pata_cs5536.c
@@ -40,7 +40,7 @@
 #include <asm/msr.h>
 
 #define DRV_NAME	"pata_cs5536"
-#define DRV_VERSION	"0.0.5"
+#define DRV_VERSION	"0.0.6"
 
 enum {
 	CFG			= 0,
@@ -214,7 +214,7 @@
 		cs5536_read(pdev, DTC, &dtc);
 
 		dtc &= ~(IDE_DRV_MASK << dshift);
-		dtc |= mwdma_timings[mode] << dshift;
+		dtc |= mwdma_timings[mode - XFER_MW_DMA_0] << dshift;
 
 		cs5536_write(pdev, DTC, dtc);
 	}
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 988ef73..ca9aae0 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -105,7 +105,7 @@
 
 /*
  *	We allow users to force the card into non raid mode without
- *	flashing the alternative BIOS. This is also neccessary right now
+ *	flashing the alternative BIOS. This is also necessary right now
  *	for embedded platforms that cannot run a PC BIOS but are using this
  *	device.
  */
@@ -383,7 +383,7 @@
  *	@ap: ATA port
  *	@device: Device number (not pointer)
  *
- *	Device selection hook. If neccessary perform clock switching
+ *	Device selection hook. If necessary perform clock switching
  */
 
 static void it821x_passthru_dev_select(struct ata_port *ap,
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index d548308..c0d9e0c 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -129,7 +129,7 @@
  *
  *	Called when the libata layer is about to issue a command. We wrap
  *	this interface so that we can load the correct ATA timings if
- *	neccessary. Our logic also clears TIME0/TIME1 for the other device so
+ *	necessary. Our logic also clears TIME0/TIME1 for the other device so
  *	that, even if we get this wrong, cycles to the other device will
  *	be made PIO0.
  */
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index 6e8e557..9fe66fd 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -124,7 +124,7 @@
  *
  *	Called when the libata layer is about to issue a command. We wrap
  *	this interface so that we can load the correct ATA timings if
- *	neccessary.
+ *	necessary.
  */
 
 static unsigned int ns87410_qc_issue_prot(struct ata_queued_cmd *qc)
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 3cd5eb2..44da09a 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -200,7 +200,7 @@
  *
  *	Called when the libata layer is about to issue a command. We wrap
  *	this interface so that we can load the correct ATA timings if
- *	neccessary. Our logic also clears TIME0/TIME1 for the other device so
+ *	necessary. Our logic also clears TIME0/TIME1 for the other device so
  *	that, even if we get this wrong, cycles to the other device will
  *	be made PIO0.
  */
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index d5b7649..8109b08 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -161,7 +161,7 @@
  *
  *	Called when the libata layer is about to issue a command. We wrap
  *	this interface so that we can load the correct ATA timings if
- *	neccessary. Our logic also clears TIME0/TIME1 for the other device so
+ *	necessary. Our logic also clears TIME0/TIME1 for the other device so
  *	that, even if we get this wrong, cycles to the other device will
  *	be made PIO0.
  */
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 21ebc48..725a858 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -156,7 +156,7 @@
  *
  *	Called when the libata layer is about to issue a command. We wrap
  *	this interface so that we can load the correct ATA timings if
- *	neccessary.  Specifically we have a problem that there is only
+ *	necessary.  Specifically we have a problem that there is only
  *	one MWDMA/UDMA bit.
  */
 
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 4dc2e73..5c1e9cb 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -16,7 +16,7 @@
  *
  *	If you have strange problems with nVidia chipset systems please
  *	see the SI support documentation and update your system BIOS
- *	if neccessary
+ *	if necessary
  *
  * TODO
  *	If we know all our devices are LBA28 (or LBA28 sized)  we could use
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 5d41b66..ea7a9a6 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -420,7 +420,7 @@
  *	@pdev: PCI device
  *	@flags: configuration flags
  *
- *	Set the FIFO properties for this device if neccessary. Used both on
+ *	Set the FIFO properties for this device if necessary. Used both on
  *	set up and on and the resume path
  */
 
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 8d1b03d..199f7e1 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -318,7 +318,7 @@
 	struct scatterlist *sg;
 	struct ata_port *ap = qc->ap;
 	struct adma_port_priv *pp = ap->private_data;
-	u8  *buf = pp->pkt;
+	u8  *buf = pp->pkt, *last_buf = NULL;
 	int i = (2 + buf[3]) * 8;
 	u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0);
 
@@ -334,8 +334,7 @@
 		*(__le32 *)(buf + i) = cpu_to_le32(len);
 		i += 4;
 
-		if (ata_sg_is_last(sg, qc))
-			pFLAGS |= pEND;
+		last_buf = &buf[i];
 		buf[i++] = pFLAGS;
 		buf[i++] = qc->dev->dma_mode & 0xf;
 		buf[i++] = 0;	/* pPKLW */
@@ -348,6 +347,10 @@
 		VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", i/4,
 					(unsigned long)addr, len);
 	}
+
+	if (likely(last_buf))
+		*last_buf |= pEND;
+
 	return i;
 }
 
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
new file mode 100644
index 0000000..b4c37b9
--- /dev/null
+++ b/drivers/ata/sata_fsl.c
@@ -0,0 +1,1490 @@
+/*
+ * drivers/ata/sata_fsl.c
+ *
+ * Freescale 3.0Gbps SATA device driver
+ *
+ * Author: Ashish Kalra <ashish.kalra@freescale.com>
+ * Li Yang <leoli@freescale.com>
+ *
+ * Copyright (c) 2006-2007 Freescale Semiconductor, 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
+#include <linux/libata.h>
+#include <asm/io.h>
+#include <linux/of_platform.h>
+
+/* Controller information */
+enum {
+	SATA_FSL_QUEUE_DEPTH	= 16,
+	SATA_FSL_MAX_PRD	= 63,
+	SATA_FSL_MAX_PRD_USABLE	= SATA_FSL_MAX_PRD - 1,
+	SATA_FSL_MAX_PRD_DIRECT	= 16,	/* Direct PRDT entries */
+
+	SATA_FSL_HOST_FLAGS	= (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+				ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+				ATA_FLAG_NCQ  | ATA_FLAG_SKIP_D2H_BSY),
+
+	SATA_FSL_MAX_CMDS	= SATA_FSL_QUEUE_DEPTH,
+	SATA_FSL_CMD_HDR_SIZE	= 16,	/* 4 DWORDS */
+	SATA_FSL_CMD_SLOT_SIZE  = (SATA_FSL_MAX_CMDS * SATA_FSL_CMD_HDR_SIZE),
+
+	/*
+	 * SATA-FSL host controller supports a max. of (15+1) direct PRDEs, and
+	 * chained indirect PRDEs upto a max count of 63.
+	 * We are allocating an array of 63 PRDEs contigiously, but PRDE#15 will
+	 * be setup as an indirect descriptor, pointing to it's next
+	 * (contigious) PRDE. Though chained indirect PRDE arrays are
+	 * supported,it will be more efficient to use a direct PRDT and
+	 * a single chain/link to indirect PRDE array/PRDT.
+	 */
+
+	SATA_FSL_CMD_DESC_CFIS_SZ	= 32,
+	SATA_FSL_CMD_DESC_SFIS_SZ	= 32,
+	SATA_FSL_CMD_DESC_ACMD_SZ	= 16,
+	SATA_FSL_CMD_DESC_RSRVD		= 16,
+
+	SATA_FSL_CMD_DESC_SIZE	= (SATA_FSL_CMD_DESC_CFIS_SZ +
+				 SATA_FSL_CMD_DESC_SFIS_SZ +
+				 SATA_FSL_CMD_DESC_ACMD_SZ +
+				 SATA_FSL_CMD_DESC_RSRVD +
+				 SATA_FSL_MAX_PRD * 16),
+
+	SATA_FSL_CMD_DESC_OFFSET_TO_PRDT	=
+				(SATA_FSL_CMD_DESC_CFIS_SZ +
+				 SATA_FSL_CMD_DESC_SFIS_SZ +
+				 SATA_FSL_CMD_DESC_ACMD_SZ +
+				 SATA_FSL_CMD_DESC_RSRVD),
+
+	SATA_FSL_CMD_DESC_AR_SZ	= (SATA_FSL_CMD_DESC_SIZE * SATA_FSL_MAX_CMDS),
+	SATA_FSL_PORT_PRIV_DMA_SZ = (SATA_FSL_CMD_SLOT_SIZE +
+					SATA_FSL_CMD_DESC_AR_SZ),
+
+	/*
+	 * MPC8315 has two SATA controllers, SATA1 & SATA2
+	 * (one port per controller)
+	 * MPC837x has 2/4 controllers, one port per controller
+	 */
+
+	SATA_FSL_MAX_PORTS	= 1,
+
+	SATA_FSL_IRQ_FLAG	= IRQF_SHARED,
+};
+
+/*
+* Host Controller command register set - per port
+*/
+enum {
+	CQ = 0,
+	CA = 8,
+	CC = 0x10,
+	CE = 0x18,
+	DE = 0x20,
+	CHBA = 0x24,
+	HSTATUS = 0x28,
+	HCONTROL = 0x2C,
+	CQPMP = 0x30,
+	SIGNATURE = 0x34,
+	ICC = 0x38,
+
+	/*
+	 * Host Status Register (HStatus) bitdefs
+	 */
+	ONLINE = (1 << 31),
+	GOING_OFFLINE = (1 << 30),
+	BIST_ERR = (1 << 29),
+
+	FATAL_ERR_HC_MASTER_ERR = (1 << 18),
+	FATAL_ERR_PARITY_ERR_TX = (1 << 17),
+	FATAL_ERR_PARITY_ERR_RX = (1 << 16),
+	FATAL_ERR_DATA_UNDERRUN = (1 << 13),
+	FATAL_ERR_DATA_OVERRUN = (1 << 12),
+	FATAL_ERR_CRC_ERR_TX = (1 << 11),
+	FATAL_ERR_CRC_ERR_RX = (1 << 10),
+	FATAL_ERR_FIFO_OVRFL_TX = (1 << 9),
+	FATAL_ERR_FIFO_OVRFL_RX = (1 << 8),
+
+	FATAL_ERROR_DECODE = FATAL_ERR_HC_MASTER_ERR |
+	    FATAL_ERR_PARITY_ERR_TX |
+	    FATAL_ERR_PARITY_ERR_RX |
+	    FATAL_ERR_DATA_UNDERRUN |
+	    FATAL_ERR_DATA_OVERRUN |
+	    FATAL_ERR_CRC_ERR_TX |
+	    FATAL_ERR_CRC_ERR_RX |
+	    FATAL_ERR_FIFO_OVRFL_TX | FATAL_ERR_FIFO_OVRFL_RX,
+
+	INT_ON_FATAL_ERR = (1 << 5),
+	INT_ON_PHYRDY_CHG = (1 << 4),
+
+	INT_ON_SIGNATURE_UPDATE = (1 << 3),
+	INT_ON_SNOTIFY_UPDATE = (1 << 2),
+	INT_ON_SINGL_DEVICE_ERR = (1 << 1),
+	INT_ON_CMD_COMPLETE = 1,
+
+	INT_ON_ERROR = INT_ON_FATAL_ERR |
+	    INT_ON_PHYRDY_CHG | INT_ON_SINGL_DEVICE_ERR,
+
+	/*
+	 * Host Control Register (HControl) bitdefs
+	 */
+	HCONTROL_ONLINE_PHY_RST = (1 << 31),
+	HCONTROL_FORCE_OFFLINE = (1 << 30),
+	HCONTROL_PARITY_PROT_MOD = (1 << 14),
+	HCONTROL_DPATH_PARITY = (1 << 12),
+	HCONTROL_SNOOP_ENABLE = (1 << 10),
+	HCONTROL_PMP_ATTACHED = (1 << 9),
+	HCONTROL_COPYOUT_STATFIS = (1 << 8),
+	IE_ON_FATAL_ERR = (1 << 5),
+	IE_ON_PHYRDY_CHG = (1 << 4),
+	IE_ON_SIGNATURE_UPDATE = (1 << 3),
+	IE_ON_SNOTIFY_UPDATE = (1 << 2),
+	IE_ON_SINGL_DEVICE_ERR = (1 << 1),
+	IE_ON_CMD_COMPLETE = 1,
+
+	DEFAULT_PORT_IRQ_ENABLE_MASK = IE_ON_FATAL_ERR | IE_ON_PHYRDY_CHG |
+	    IE_ON_SIGNATURE_UPDATE |
+	    IE_ON_SINGL_DEVICE_ERR | IE_ON_CMD_COMPLETE,
+
+	EXT_INDIRECT_SEG_PRD_FLAG = (1 << 31),
+	DATA_SNOOP_ENABLE = (1 << 22),
+};
+
+/*
+ * SATA Superset Registers
+ */
+enum {
+	SSTATUS = 0,
+	SERROR = 4,
+	SCONTROL = 8,
+	SNOTIFY = 0xC,
+};
+
+/*
+ * Control Status Register Set
+ */
+enum {
+	TRANSCFG = 0,
+	TRANSSTATUS = 4,
+	LINKCFG = 8,
+	LINKCFG1 = 0xC,
+	LINKCFG2 = 0x10,
+	LINKSTATUS = 0x14,
+	LINKSTATUS1 = 0x18,
+	PHYCTRLCFG = 0x1C,
+	COMMANDSTAT = 0x20,
+};
+
+/* PHY (link-layer) configuration control */
+enum {
+	PHY_BIST_ENABLE = 0x01,
+};
+
+/*
+ * Command Header Table entry, i.e, command slot
+ * 4 Dwords per command slot, command header size ==  64 Dwords.
+ */
+struct cmdhdr_tbl_entry {
+	u32 cda;
+	u32 prde_fis_len;
+	u32 ttl;
+	u32 desc_info;
+};
+
+/*
+ * Description information bitdefs
+ */
+enum {
+	VENDOR_SPECIFIC_BIST = (1 << 10),
+	CMD_DESC_SNOOP_ENABLE = (1 << 9),
+	FPDMA_QUEUED_CMD = (1 << 8),
+	SRST_CMD = (1 << 7),
+	BIST = (1 << 6),
+	ATAPI_CMD = (1 << 5),
+};
+
+/*
+ * Command Descriptor
+ */
+struct command_desc {
+	u8 cfis[8 * 4];
+	u8 sfis[8 * 4];
+	u8 acmd[4 * 4];
+	u8 fill[4 * 4];
+	u32 prdt[SATA_FSL_MAX_PRD_DIRECT * 4];
+	u32 prdt_indirect[(SATA_FSL_MAX_PRD - SATA_FSL_MAX_PRD_DIRECT) * 4];
+};
+
+/*
+ * Physical region table descriptor(PRD)
+ */
+
+struct prde {
+	u32 dba;
+	u8 fill[2 * 4];
+	u32 ddc_and_ext;
+};
+
+/*
+ * ata_port private data
+ * This is our per-port instance data.
+ */
+struct sata_fsl_port_priv {
+	struct cmdhdr_tbl_entry *cmdslot;
+	dma_addr_t cmdslot_paddr;
+	struct command_desc *cmdentry;
+	dma_addr_t cmdentry_paddr;
+
+	/*
+	 * SATA FSL controller has a Status FIS which should contain the
+	 * received D2H FIS & taskfile registers. This SFIS is present in
+	 * the command descriptor, and to have a ready reference to it,
+	 * we are caching it here, quite similar to what is done in H/W on
+	 * AHCI compliant devices by copying taskfile fields to a 32-bit
+	 * register.
+	 */
+
+	struct ata_taskfile tf;
+};
+
+/*
+ * ata_port->host_set private data
+ */
+struct sata_fsl_host_priv {
+	void __iomem *hcr_base;
+	void __iomem *ssr_base;
+	void __iomem *csr_base;
+};
+
+static inline unsigned int sata_fsl_tag(unsigned int tag,
+					void __iomem * hcr_base)
+{
+	/* We let libATA core do actual (queue) tag allocation */
+
+	/* all non NCQ/queued commands should have tag#0 */
+	if (ata_tag_internal(tag)) {
+		DPRINTK("mapping internal cmds to tag#0\n");
+		return 0;
+	}
+
+	if (unlikely(tag >= SATA_FSL_QUEUE_DEPTH)) {
+		DPRINTK("tag %d invalid : out of range\n", tag);
+		return 0;
+	}
+
+	if (unlikely((ioread32(hcr_base + CQ)) & (1 << tag))) {
+		DPRINTK("tag %d invalid : in use!!\n", tag);
+		return 0;
+	}
+
+	return tag;
+}
+
+static void sata_fsl_setup_cmd_hdr_entry(struct sata_fsl_port_priv *pp,
+					 unsigned int tag, u32 desc_info,
+					 u32 data_xfer_len, u8 num_prde,
+					 u8 fis_len)
+{
+	dma_addr_t cmd_descriptor_address;
+
+	cmd_descriptor_address = pp->cmdentry_paddr +
+	    tag * SATA_FSL_CMD_DESC_SIZE;
+
+	/* NOTE: both data_xfer_len & fis_len are Dword counts */
+
+	pp->cmdslot[tag].cda = cpu_to_le32(cmd_descriptor_address);
+	pp->cmdslot[tag].prde_fis_len =
+	    cpu_to_le32((num_prde << 16) | (fis_len << 2));
+	pp->cmdslot[tag].ttl = cpu_to_le32(data_xfer_len & ~0x03);
+	pp->cmdslot[tag].desc_info = cpu_to_le32((desc_info | (tag & 0x1F)));
+
+	VPRINTK("cda=0x%x, prde_fis_len=0x%x, ttl=0x%x, di=0x%x\n",
+		pp->cmdslot[tag].cda,
+		pp->cmdslot[tag].prde_fis_len,
+		pp->cmdslot[tag].ttl, pp->cmdslot[tag].desc_info);
+
+}
+
+static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc,
+				     u32 * ttl, dma_addr_t cmd_desc_paddr)
+{
+	struct scatterlist *sg;
+	unsigned int num_prde = 0;
+	u32 ttl_dwords = 0;
+
+	/*
+	 * NOTE : direct & indirect prdt's are contigiously allocated
+	 */
+	struct prde *prd = (struct prde *)&((struct command_desc *)
+					    cmd_desc)->prdt;
+
+	struct prde *prd_ptr_to_indirect_ext = NULL;
+	unsigned indirect_ext_segment_sz = 0;
+	dma_addr_t indirect_ext_segment_paddr;
+
+	VPRINTK("SATA FSL : cd = 0x%x, prd = 0x%x\n", cmd_desc, prd);
+
+	indirect_ext_segment_paddr = cmd_desc_paddr +
+	    SATA_FSL_CMD_DESC_OFFSET_TO_PRDT + SATA_FSL_MAX_PRD_DIRECT * 16;
+
+	ata_for_each_sg(sg, qc) {
+		dma_addr_t sg_addr = sg_dma_address(sg);
+		u32 sg_len = sg_dma_len(sg);
+
+		VPRINTK("SATA FSL : fill_sg, sg_addr = 0x%x, sg_len = %d\n",
+			sg_addr, sg_len);
+
+		/* warn if each s/g element is not dword aligned */
+		if (sg_addr & 0x03)
+			ata_port_printk(qc->ap, KERN_ERR,
+					"s/g addr unaligned : 0x%x\n", sg_addr);
+		if (sg_len & 0x03)
+			ata_port_printk(qc->ap, KERN_ERR,
+					"s/g len unaligned : 0x%x\n", sg_len);
+
+		if ((num_prde == (SATA_FSL_MAX_PRD_DIRECT - 1)) &&
+		    !ata_sg_is_last(sg, qc)) {
+			VPRINTK("setting indirect prde\n");
+			prd_ptr_to_indirect_ext = prd;
+			prd->dba = cpu_to_le32(indirect_ext_segment_paddr);
+			indirect_ext_segment_sz = 0;
+			++prd;
+			++num_prde;
+		}
+
+		ttl_dwords += sg_len;
+		prd->dba = cpu_to_le32(sg_addr);
+		prd->ddc_and_ext =
+		    cpu_to_le32(DATA_SNOOP_ENABLE | (sg_len & ~0x03));
+
+		VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n",
+			ttl_dwords, prd->dba, prd->ddc_and_ext);
+
+		++num_prde;
+		++prd;
+		if (prd_ptr_to_indirect_ext)
+			indirect_ext_segment_sz += sg_len;
+	}
+
+	if (prd_ptr_to_indirect_ext) {
+		/* set indirect extension flag along with indirect ext. size */
+		prd_ptr_to_indirect_ext->ddc_and_ext =
+		    cpu_to_le32((EXT_INDIRECT_SEG_PRD_FLAG |
+				 DATA_SNOOP_ENABLE |
+				 (indirect_ext_segment_sz & ~0x03)));
+	}
+
+	*ttl = ttl_dwords;
+	return num_prde;
+}
+
+static void sata_fsl_qc_prep(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct sata_fsl_port_priv *pp = ap->private_data;
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
+	struct command_desc *cd;
+	u32 desc_info = CMD_DESC_SNOOP_ENABLE;
+	u32 num_prde = 0;
+	u32 ttl_dwords = 0;
+	dma_addr_t cd_paddr;
+
+	cd = (struct command_desc *)pp->cmdentry + tag;
+	cd_paddr = pp->cmdentry_paddr + tag * SATA_FSL_CMD_DESC_SIZE;
+
+	ata_tf_to_fis(&qc->tf, 0, 1, (u8 *) & cd->cfis);
+
+	VPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x\n",
+		cd->cfis[0], cd->cfis[1], cd->cfis[2]);
+
+	if (qc->tf.protocol == ATA_PROT_NCQ) {
+		VPRINTK("FPDMA xfer,Sctor cnt[0:7],[8:15] = %d,%d\n",
+			cd->cfis[3], cd->cfis[11]);
+	}
+
+	/* setup "ACMD - atapi command" in cmd. desc. if this is ATAPI cmd */
+	if (is_atapi_taskfile(&qc->tf)) {
+		desc_info |= ATAPI_CMD;
+		memset((void *)&cd->acmd, 0, 32);
+		memcpy((void *)&cd->acmd, qc->cdb, qc->dev->cdb_len);
+	}
+
+	if (qc->flags & ATA_QCFLAG_DMAMAP)
+		num_prde = sata_fsl_fill_sg(qc, (void *)cd,
+					    &ttl_dwords, cd_paddr);
+
+	if (qc->tf.protocol == ATA_PROT_NCQ)
+		desc_info |= FPDMA_QUEUED_CMD;
+
+	sata_fsl_setup_cmd_hdr_entry(pp, tag, desc_info, ttl_dwords,
+				     num_prde, 5);
+
+	VPRINTK("SATA FSL : xx_qc_prep, di = 0x%x, ttl = %d, num_prde = %d\n",
+		desc_info, ttl_dwords, num_prde);
+}
+
+static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
+
+	VPRINTK("xx_qc_issue called,CQ=0x%x,CA=0x%x,CE=0x%x,CC=0x%x\n",
+		ioread32(CQ + hcr_base),
+		ioread32(CA + hcr_base),
+		ioread32(CE + hcr_base), ioread32(CC + hcr_base));
+
+	/* Simply queue command to the controller/device */
+	iowrite32(1 << tag, CQ + hcr_base);
+
+	VPRINTK("xx_qc_issue called, tag=%d, CQ=0x%x, CA=0x%x\n",
+		tag, ioread32(CQ + hcr_base), ioread32(CA + hcr_base));
+
+	VPRINTK("CE=0x%x, DE=0x%x, CC=0x%x, CmdStat = 0x%x\n",
+		ioread32(CE + hcr_base),
+		ioread32(DE + hcr_base),
+		ioread32(CC + hcr_base), ioread32(COMMANDSTAT + csr_base));
+
+	return 0;
+}
+
+static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
+			       u32 val)
+{
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *ssr_base = host_priv->ssr_base;
+	unsigned int sc_reg;
+
+	switch (sc_reg_in) {
+	case SCR_STATUS:
+		sc_reg = 0;
+		break;
+	case SCR_ERROR:
+		sc_reg = 1;
+		break;
+	case SCR_CONTROL:
+		sc_reg = 2;
+		break;
+	case SCR_ACTIVE:
+		sc_reg = 3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	VPRINTK("xx_scr_write, reg_in = %d\n", sc_reg);
+
+	iowrite32(val, (void __iomem *)ssr_base + (sc_reg * 4));
+	return 0;
+}
+
+static int sata_fsl_scr_read(struct ata_port *ap, unsigned int sc_reg_in,
+			u32 *val)
+{
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *ssr_base = host_priv->ssr_base;
+	unsigned int sc_reg;
+
+	switch (sc_reg_in) {
+	case SCR_STATUS:
+		sc_reg = 0;
+		break;
+	case SCR_ERROR:
+		sc_reg = 1;
+		break;
+	case SCR_CONTROL:
+		sc_reg = 2;
+		break;
+	case SCR_ACTIVE:
+		sc_reg = 3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	VPRINTK("xx_scr_read, reg_in = %d\n", sc_reg);
+
+	*val = ioread32((void __iomem *)ssr_base + (sc_reg * 4));
+	return 0;
+}
+
+static void sata_fsl_freeze(struct ata_port *ap)
+{
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	u32 temp;
+
+	VPRINTK("xx_freeze, CQ=0x%x, CA=0x%x, CE=0x%x, DE=0x%x\n",
+		ioread32(CQ + hcr_base),
+		ioread32(CA + hcr_base),
+		ioread32(CE + hcr_base), ioread32(DE + hcr_base));
+	VPRINTK("CmdStat = 0x%x\n", ioread32(csr_base + COMMANDSTAT));
+
+	/* disable interrupts on the controller/port */
+	temp = ioread32(hcr_base + HCONTROL);
+	iowrite32((temp & ~0x3F), hcr_base + HCONTROL);
+
+	VPRINTK("in xx_freeze : HControl = 0x%x, HStatus = 0x%x\n",
+		ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS));
+}
+
+static void sata_fsl_thaw(struct ata_port *ap)
+{
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	u32 temp;
+
+	/* ack. any pending IRQs for this controller/port */
+	temp = ioread32(hcr_base + HSTATUS);
+
+	VPRINTK("xx_thaw, pending IRQs = 0x%x\n", (temp & 0x3F));
+
+	if (temp & 0x3F)
+		iowrite32((temp & 0x3F), hcr_base + HSTATUS);
+
+	/* enable interrupts on the controller/port */
+	temp = ioread32(hcr_base + HCONTROL);
+	iowrite32((temp | DEFAULT_PORT_IRQ_ENABLE_MASK), hcr_base + HCONTROL);
+
+	VPRINTK("xx_thaw : HControl = 0x%x, HStatus = 0x%x\n",
+		ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS));
+}
+
+/*
+ * NOTE : 1st D2H FIS from device does not update sfis in command descriptor.
+ */
+static inline void sata_fsl_cache_taskfile_from_d2h_fis(struct ata_queued_cmd
+							*qc,
+							struct ata_port *ap)
+{
+	struct sata_fsl_port_priv *pp = ap->private_data;
+	u8 fis[6 * 4];
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
+	struct command_desc *cd;
+
+	cd = pp->cmdentry + tag;
+
+	memcpy(fis, &cd->sfis, 6 * 4);	/* should we use memcpy_from_io() */
+	ata_tf_from_fis(fis, &pp->tf);
+}
+
+static u8 sata_fsl_check_status(struct ata_port *ap)
+{
+	struct sata_fsl_port_priv *pp = ap->private_data;
+
+	return pp->tf.command;
+}
+
+static void sata_fsl_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+	struct sata_fsl_port_priv *pp = ap->private_data;
+
+	*tf = pp->tf;
+}
+
+static int sata_fsl_port_start(struct ata_port *ap)
+{
+	struct device *dev = ap->host->dev;
+	struct sata_fsl_port_priv *pp;
+	int retval;
+	void *mem;
+	dma_addr_t mem_dma;
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	u32 temp;
+
+	pp = kzalloc(sizeof(*pp), GFP_KERNEL);
+	if (!pp)
+		return -ENOMEM;
+
+	/*
+	 * allocate per command dma alignment pad buffer, which is used
+	 * internally by libATA to ensure that all transfers ending on
+	 * unaligned boundaries are padded, to align on Dword boundaries
+	 */
+	retval = ata_pad_alloc(ap, dev);
+	if (retval) {
+		kfree(pp);
+		return retval;
+	}
+
+	mem = dma_alloc_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, &mem_dma,
+				 GFP_KERNEL);
+	if (!mem) {
+		ata_pad_free(ap, dev);
+		kfree(pp);
+		return -ENOMEM;
+	}
+	memset(mem, 0, SATA_FSL_PORT_PRIV_DMA_SZ);
+
+	pp->cmdslot = mem;
+	pp->cmdslot_paddr = mem_dma;
+
+	mem += SATA_FSL_CMD_SLOT_SIZE;
+	mem_dma += SATA_FSL_CMD_SLOT_SIZE;
+
+	pp->cmdentry = mem;
+	pp->cmdentry_paddr = mem_dma;
+
+	ap->private_data = pp;
+
+	VPRINTK("CHBA = 0x%x, cmdentry_phys = 0x%x\n",
+		pp->cmdslot_paddr, pp->cmdentry_paddr);
+
+	/* Now, update the CHBA register in host controller cmd register set */
+	iowrite32(pp->cmdslot_paddr & 0xffffffff, hcr_base + CHBA);
+
+	/*
+	 * Now, we can bring the controller on-line & also initiate
+	 * the COMINIT sequence, we simply return here and the boot-probing
+	 * & device discovery process is re-initiated by libATA using a
+	 * Softreset EH (dummy) session. Hence, boot probing and device
+	 * discovey will be part of sata_fsl_softreset() callback.
+	 */
+
+	temp = ioread32(hcr_base + HCONTROL);
+	iowrite32((temp | HCONTROL_ONLINE_PHY_RST), hcr_base + HCONTROL);
+
+	VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+	VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+	VPRINTK("CHBA  = 0x%x\n", ioread32(hcr_base + CHBA));
+
+	/*
+	 * Workaround for 8315DS board 3gbps link-up issue,
+	 * currently limit SATA port to GEN1 speed
+	 */
+	sata_fsl_scr_read(ap, SCR_CONTROL, &temp);
+	temp &= ~(0xF << 4);
+	temp |= (0x1 << 4);
+	sata_fsl_scr_write(ap, SCR_CONTROL, temp);
+
+	sata_fsl_scr_read(ap, SCR_CONTROL, &temp);
+	dev_printk(KERN_WARNING, dev, "scr_control, speed limited to %x\n",
+			temp);
+
+	return 0;
+}
+
+static void sata_fsl_port_stop(struct ata_port *ap)
+{
+	struct device *dev = ap->host->dev;
+	struct sata_fsl_port_priv *pp = ap->private_data;
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	u32 temp;
+
+	/*
+	 * Force host controller to go off-line, aborting current operations
+	 */
+	temp = ioread32(hcr_base + HCONTROL);
+	temp &= ~HCONTROL_ONLINE_PHY_RST;
+	temp |= HCONTROL_FORCE_OFFLINE;
+	iowrite32(temp, hcr_base + HCONTROL);
+
+	/* Poll for controller to go offline - should happen immediately */
+	ata_wait_register(hcr_base + HSTATUS, ONLINE, ONLINE, 1, 1);
+
+	ap->private_data = NULL;
+	dma_free_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ,
+			  pp->cmdslot, pp->cmdslot_paddr);
+
+	ata_pad_free(ap, dev);
+	kfree(pp);
+}
+
+static unsigned int sata_fsl_dev_classify(struct ata_port *ap)
+{
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	struct ata_taskfile tf;
+	u32 temp;
+
+	temp = ioread32(hcr_base + SIGNATURE);
+
+	VPRINTK("raw sig = 0x%x\n", temp);
+	VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+	VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+
+	tf.lbah = (temp >> 24) & 0xff;
+	tf.lbam = (temp >> 16) & 0xff;
+	tf.lbal = (temp >> 8) & 0xff;
+	tf.nsect = temp & 0xff;
+
+	return ata_dev_classify(&tf);
+}
+
+static int sata_fsl_softreset(struct ata_port *ap, unsigned int *class,
+			      unsigned long deadline)
+{
+	struct sata_fsl_port_priv *pp = ap->private_data;
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	u32 temp;
+	struct ata_taskfile tf;
+	u8 *cfis;
+	u32 Serror;
+	int i = 0;
+	struct ata_queued_cmd qc;
+	u8 *buf;
+	dma_addr_t dma_address;
+	struct scatterlist *sg;
+	unsigned long start_jiffies;
+
+	DPRINTK("in xx_softreset\n");
+
+try_offline_again:
+	/*
+	 * Force host controller to go off-line, aborting current operations
+	 */
+	temp = ioread32(hcr_base + HCONTROL);
+	temp &= ~HCONTROL_ONLINE_PHY_RST;
+	iowrite32(temp, hcr_base + HCONTROL);
+
+	/* Poll for controller to go offline */
+	temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, ONLINE, 1, 500);
+
+	if (temp & ONLINE) {
+		ata_port_printk(ap, KERN_ERR,
+				"Softreset failed, not off-lined %d\n", i);
+
+		/*
+		 * Try to offline controller atleast twice
+		 */
+		i++;
+		if (i == 2)
+			goto err;
+		else
+			goto try_offline_again;
+	}
+
+	DPRINTK("softreset, controller off-lined\n");
+	VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+	VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+
+	/*
+	 * PHY reset should remain asserted for atleast 1ms
+	 */
+	msleep(1);
+
+	/*
+	 * Now, bring the host controller online again, this can take time
+	 * as PHY reset and communication establishment, 1st D2H FIS and
+	 * device signature update is done, on safe side assume 500ms
+	 * NOTE : Host online status may be indicated immediately!!
+	 */
+
+	temp = ioread32(hcr_base + HCONTROL);
+	temp |= (HCONTROL_ONLINE_PHY_RST | HCONTROL_SNOOP_ENABLE);
+	iowrite32(temp, hcr_base + HCONTROL);
+
+	temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, 0, 1, 500);
+
+	if (!(temp & ONLINE)) {
+		ata_port_printk(ap, KERN_ERR,
+				"Softreset failed, not on-lined\n");
+		goto err;
+	}
+
+	DPRINTK("softreset, controller off-lined & on-lined\n");
+	VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+	VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+
+	/*
+	 * First, wait for the PHYRDY change to occur before waiting for
+	 * the signature, and also verify if SStatus indicates device
+	 * presence
+	 */
+
+	temp = ata_wait_register(hcr_base + HSTATUS, 0xFF, 0, 1, 500);
+	if ((!(temp & 0x10)) || ata_port_offline(ap)) {
+		ata_port_printk(ap, KERN_WARNING,
+				"No Device OR PHYRDY change,Hstatus = 0x%x\n",
+				ioread32(hcr_base + HSTATUS));
+		goto err;
+	}
+
+	/*
+	 * Wait for the first D2H from device,i.e,signature update notification
+	 */
+	start_jiffies = jiffies;
+	temp = ata_wait_register(hcr_base + HSTATUS, 0xFF, 0x10,
+			500, jiffies_to_msecs(deadline - start_jiffies));
+
+	if ((temp & 0xFF) != 0x18) {
+		ata_port_printk(ap, KERN_WARNING, "No Signature Update\n");
+		goto err;
+	} else {
+		ata_port_printk(ap, KERN_INFO,
+				"Signature Update detected @ %d msecs\n",
+				jiffies_to_msecs(jiffies - start_jiffies));
+	}
+
+	/*
+	 * Send a device reset (SRST) explicitly on command slot #0
+	 * Check : will the command queue (reg) be cleared during offlining ??
+	 * Also we will be online only if Phy commn. has been established
+	 * and device presence has been detected, therefore if we have
+	 * reached here, we can send a command to the target device
+	 */
+
+	if (ap->sactive)
+		goto skip_srst_do_ncq_error_handling;
+
+	DPRINTK("Sending SRST/device reset\n");
+
+	ata_tf_init(ap->device, &tf);
+	cfis = (u8 *) & pp->cmdentry->cfis;
+
+	/* device reset/SRST is a control register update FIS, uses tag0 */
+	sata_fsl_setup_cmd_hdr_entry(pp, 0,
+				     SRST_CMD | CMD_DESC_SNOOP_ENABLE, 0, 0, 5);
+
+	tf.ctl |= ATA_SRST;	/* setup SRST bit in taskfile control reg */
+	ata_tf_to_fis(&tf, 0, 0, cfis);
+
+	DPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x, 0x%x\n",
+		cfis[0], cfis[1], cfis[2], cfis[3]);
+
+	/*
+	 * Queue SRST command to the controller/device, ensure that no
+	 * other commands are active on the controller/device
+	 */
+
+	DPRINTK("@Softreset, CQ = 0x%x, CA = 0x%x, CC = 0x%x\n",
+		ioread32(CQ + hcr_base),
+		ioread32(CA + hcr_base), ioread32(CC + hcr_base));
+
+	iowrite32(0xFFFF, CC + hcr_base);
+	iowrite32(1, CQ + hcr_base);
+
+	temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000);
+	if (temp & 0x1) {
+		ata_port_printk(ap, KERN_WARNING, "ATA_SRST issue failed\n");
+
+		DPRINTK("Softreset@5000,CQ=0x%x,CA=0x%x,CC=0x%x\n",
+			ioread32(CQ + hcr_base),
+			ioread32(CA + hcr_base), ioread32(CC + hcr_base));
+
+		sata_fsl_scr_read(ap, SCR_ERROR, &Serror);
+
+		DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+		DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+		DPRINTK("Serror = 0x%x\n", Serror);
+		goto err;
+	}
+
+	msleep(1);
+
+	/*
+	 * SATA device enters reset state after receving a Control register
+	 * FIS with SRST bit asserted and it awaits another H2D Control reg.
+	 * FIS with SRST bit cleared, then the device does internal diags &
+	 * initialization, followed by indicating it's initialization status
+	 * using ATA signature D2H register FIS to the host controller.
+	 */
+
+	sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_SNOOP_ENABLE, 0, 0, 5);
+
+	tf.ctl &= ~ATA_SRST;	/* 2nd H2D Ctl. register FIS */
+	ata_tf_to_fis(&tf, 0, 0, cfis);
+
+	iowrite32(1, CQ + hcr_base);
+	msleep(150);		/* ?? */
+
+	/*
+	 * The above command would have signalled an interrupt on command
+	 * complete, which needs special handling, by clearing the Nth
+	 * command bit of the CCreg
+	 */
+	iowrite32(0x01, CC + hcr_base);	/* We know it will be cmd#0 always */
+	goto check_device_signature;
+
+skip_srst_do_ncq_error_handling:
+
+	VPRINTK("Sending read log ext(10h) command\n");
+
+	memset(&qc, 0, sizeof(struct ata_queued_cmd));
+	ata_tf_init(ap->device, &tf);
+
+	tf.command = ATA_CMD_READ_LOG_EXT;
+	tf.lbal = ATA_LOG_SATA_NCQ;
+	tf.nsect = 1;
+	tf.hob_nsect = 0;
+	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE;
+	tf.protocol = ATA_PROT_PIO;
+
+	qc.tag = ATA_TAG_INTERNAL;
+	qc.scsicmd = NULL;
+	qc.ap = ap;
+	qc.dev = ap->device;
+
+	qc.tf = tf;
+	qc.flags |= ATA_QCFLAG_RESULT_TF;
+	qc.dma_dir = DMA_FROM_DEVICE;
+
+	buf = ap->sector_buf;
+	ata_sg_init_one(&qc, buf, 1 * ATA_SECT_SIZE);
+
+	/*
+	 * Need to DMA-map the memory buffer associated with the command
+	 */
+
+	sg = qc.__sg;
+	dma_address = dma_map_single(ap->dev, qc.buf_virt,
+				     sg->length, DMA_FROM_DEVICE);
+
+	sg_dma_address(sg) = dma_address;
+	sg_dma_len(sg) = sg->length;
+
+	VPRINTK("EH, addr = 0x%x, len = 0x%x\n", dma_address, sg->length);
+
+	sata_fsl_qc_prep(&qc);
+	sata_fsl_qc_issue(&qc);
+
+	temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000);
+	if (temp & 0x1) {
+		VPRINTK("READ_LOG_EXT_10H issue failed\n");
+
+		VPRINTK("READ_LOG@5000,CQ=0x%x,CA=0x%x,CC=0x%x\n",
+			ioread32(CQ + hcr_base),
+			ioread32(CA + hcr_base), ioread32(CC + hcr_base));
+
+		sata_fsl_scr_read(ap, SCR_ERROR, &Serror);
+
+		VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+		VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+		VPRINTK("Serror = 0x%x\n", Serror);
+		goto err;
+	}
+
+	iowrite32(0x01, CC + hcr_base);	/* We know it will be cmd#0 always */
+
+      check_device_signature:
+
+	DPRINTK("SATA FSL : Now checking device signature\n");
+
+	*class = ATA_DEV_NONE;
+
+	/* Verify if SStatus indicates device presence */
+	if (ata_port_online(ap)) {
+		/*
+		 * if we are here, device presence has been detected,
+		 * 1st D2H FIS would have been received, but sfis in
+		 * command desc. is not updated, but signature register
+		 * would have been updated
+		 */
+
+		*class = sata_fsl_dev_classify(ap);
+
+		DPRINTK("class = %d\n", *class);
+		VPRINTK("ccreg = 0x%x\n", ioread32(hcr_base + CC));
+		VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE));
+	}
+
+	return 0;
+
+err:
+	return -EIO;
+}
+
+static int sata_fsl_hardreset(struct ata_port *ap, unsigned int *class,
+			      unsigned long deadline)
+{
+	int retval;
+
+	retval = sata_std_hardreset(ap, class, deadline);
+
+	DPRINTK("SATA FSL : in xx_hardreset, retval = 0x%d\n", retval);
+
+	return retval;
+}
+
+static void sata_fsl_error_handler(struct ata_port *ap)
+{
+
+	DPRINTK("in xx_error_handler\n");
+
+	/* perform recovery */
+	ata_do_eh(ap, ata_std_prereset, sata_fsl_softreset, sata_fsl_hardreset,
+		  ata_std_postreset);
+}
+
+static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc)
+{
+	if (qc->flags & ATA_QCFLAG_FAILED)
+		qc->err_mask |= AC_ERR_OTHER;
+
+	if (qc->err_mask) {
+		/* make DMA engine forget about the failed command */
+
+	}
+}
+
+static void sata_fsl_irq_clear(struct ata_port *ap)
+{
+	/* unused */
+}
+
+static void sata_fsl_error_intr(struct ata_port *ap)
+{
+	struct ata_eh_info *ehi = &ap->eh_info;
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	u32 hstatus, dereg, cereg = 0, SError = 0;
+	unsigned int err_mask = 0, action = 0;
+	struct ata_queued_cmd *qc;
+	int freeze = 0;
+
+	hstatus = ioread32(hcr_base + HSTATUS);
+	cereg = ioread32(hcr_base + CE);
+
+	ata_ehi_clear_desc(ehi);
+
+	/*
+	 * Handle & Clear SError
+	 */
+
+	sata_fsl_scr_read(ap, SCR_ERROR, &SError);
+	if (unlikely(SError & 0xFFFF0000)) {
+		sata_fsl_scr_write(ap, SCR_ERROR, SError);
+		err_mask |= AC_ERR_ATA_BUS;
+	}
+
+	DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n",
+		hstatus, cereg, ioread32(hcr_base + DE), SError);
+
+	/* handle single device errors */
+	if (cereg) {
+		/*
+		 * clear the command error, also clears queue to the device
+		 * in error, and we can (re)issue commands to this device.
+		 * When a device is in error all commands queued into the
+		 * host controller and at the device are considered aborted
+		 * and the queue for that device is stopped. Now, after
+		 * clearing the device error, we can issue commands to the
+		 * device to interrogate it to find the source of the error.
+		 */
+		dereg = ioread32(hcr_base + DE);
+		iowrite32(dereg, hcr_base + DE);
+		iowrite32(cereg, hcr_base + CE);
+
+		DPRINTK("single device error, CE=0x%x, DE=0x%x\n",
+			ioread32(hcr_base + CE), ioread32(hcr_base + DE));
+		/*
+		 * We should consider this as non fatal error, and TF must
+		 * be updated as done below.
+		 */
+
+		err_mask |= AC_ERR_DEV;
+	}
+
+	/* handle fatal errors */
+	if (hstatus & FATAL_ERROR_DECODE) {
+		err_mask |= AC_ERR_ATA_BUS;
+		action |= ATA_EH_SOFTRESET;
+		/* how will fatal error interrupts be completed ?? */
+		freeze = 1;
+	}
+
+	/* Handle PHYRDY change notification */
+	if (hstatus & INT_ON_PHYRDY_CHG) {
+		DPRINTK("SATA FSL: PHYRDY change indication\n");
+
+		/* Setup a soft-reset EH action */
+		ata_ehi_hotplugged(ehi);
+		freeze = 1;
+	}
+
+	/* record error info */
+	qc = ata_qc_from_tag(ap, ap->active_tag);
+
+	if (qc) {
+		sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap);
+		qc->err_mask |= err_mask;
+	} else
+		ehi->err_mask |= err_mask;
+
+	ehi->action |= action;
+	ehi->serror |= SError;
+
+	/* freeze or abort */
+	if (freeze)
+		ata_port_freeze(ap);
+	else
+		ata_port_abort(ap);
+}
+
+static void sata_fsl_qc_complete(struct ata_queued_cmd *qc)
+{
+	if (qc->flags & ATA_QCFLAG_RESULT_TF) {
+		DPRINTK("xx_qc_complete called\n");
+		sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap);
+	}
+}
+
+static void sata_fsl_host_intr(struct ata_port *ap)
+{
+	struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	u32 hstatus, qc_active = 0;
+	struct ata_queued_cmd *qc;
+	u32 SError;
+
+	hstatus = ioread32(hcr_base + HSTATUS);
+
+	sata_fsl_scr_read(ap, SCR_ERROR, &SError);
+
+	if (unlikely(SError & 0xFFFF0000)) {
+		DPRINTK("serror @host_intr : 0x%x\n", SError);
+		sata_fsl_error_intr(ap);
+
+	}
+
+	if (unlikely(hstatus & INT_ON_ERROR)) {
+		DPRINTK("error interrupt!!\n");
+		sata_fsl_error_intr(ap);
+		return;
+	}
+
+	if (ap->sactive) {	/* only true for NCQ commands */
+		int i;
+		/* Read command completed register */
+		qc_active = ioread32(hcr_base + CC);
+		/* clear CC bit, this will also complete the interrupt */
+		iowrite32(qc_active, hcr_base + CC);
+
+		DPRINTK("Status of all queues :\n");
+		DPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x\n",
+			qc_active, ioread32(hcr_base + CA),
+			ioread32(hcr_base + CE));
+
+		for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) {
+			if (qc_active & (1 << i)) {
+				qc = ata_qc_from_tag(ap, i);
+				if (qc) {
+					sata_fsl_qc_complete(qc);
+					ata_qc_complete(qc);
+				}
+				DPRINTK
+				    ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n",
+				     i, ioread32(hcr_base + CC),
+				     ioread32(hcr_base + CA));
+			}
+		}
+		return;
+
+	} else if (ap->qc_active) {
+		iowrite32(1, hcr_base + CC);
+		qc = ata_qc_from_tag(ap, ap->active_tag);
+
+		DPRINTK("completing non-ncq cmd, tag=%d,CC=0x%x\n",
+			ap->active_tag, ioread32(hcr_base + CC));
+
+		if (qc) {
+			sata_fsl_qc_complete(qc);
+			ata_qc_complete(qc);
+		}
+	} else {
+		/* Spurious Interrupt!! */
+		DPRINTK("spurious interrupt!!, CC = 0x%x\n",
+			ioread32(hcr_base + CC));
+		return;
+	}
+}
+
+static irqreturn_t sata_fsl_interrupt(int irq, void *dev_instance)
+{
+	struct ata_host *host = dev_instance;
+	struct sata_fsl_host_priv *host_priv = host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	u32 interrupt_enables;
+	unsigned handled = 0;
+	struct ata_port *ap;
+
+	/* ack. any pending IRQs for this controller/port */
+	interrupt_enables = ioread32(hcr_base + HSTATUS);
+	interrupt_enables &= 0x3F;
+
+	DPRINTK("interrupt status 0x%x\n", interrupt_enables);
+
+	if (!interrupt_enables)
+		return IRQ_NONE;
+
+	spin_lock(&host->lock);
+
+	/* Assuming one port per host controller */
+
+	ap = host->ports[0];
+	if (ap) {
+		sata_fsl_host_intr(ap);
+	} else {
+		dev_printk(KERN_WARNING, host->dev,
+			   "interrupt on disabled port 0\n");
+	}
+
+	iowrite32(interrupt_enables, hcr_base + HSTATUS);
+	handled = 1;
+
+	spin_unlock(&host->lock);
+
+	return IRQ_RETVAL(handled);
+}
+
+/*
+ * Multiple ports are represented by multiple SATA controllers with
+ * one port per controller
+ */
+static int sata_fsl_init_controller(struct ata_host *host)
+{
+	struct sata_fsl_host_priv *host_priv = host->private_data;
+	void __iomem *hcr_base = host_priv->hcr_base;
+	u32 temp;
+
+	/*
+	 * NOTE : We cannot bring the controller online before setting
+	 * the CHBA, hence main controller initialization is done as
+	 * part of the port_start() callback
+	 */
+
+	/* ack. any pending IRQs for this controller/port */
+	temp = ioread32(hcr_base + HSTATUS);
+	if (temp & 0x3F)
+		iowrite32((temp & 0x3F), hcr_base + HSTATUS);
+
+	/* Keep interrupts disabled on the controller */
+	temp = ioread32(hcr_base + HCONTROL);
+	iowrite32((temp & ~0x3F), hcr_base + HCONTROL);
+
+	/* Disable interrupt coalescing control(icc), for the moment */
+	DPRINTK("icc = 0x%x\n", ioread32(hcr_base + ICC));
+	iowrite32(0x01000000, hcr_base + ICC);
+
+	/* clear error registers, SError is cleared by libATA  */
+	iowrite32(0x00000FFFF, hcr_base + CE);
+	iowrite32(0x00000FFFF, hcr_base + DE);
+
+	/* initially assuming no Port multiplier, set CQPMP to 0 */
+	iowrite32(0x0, hcr_base + CQPMP);
+
+	/*
+	 * host controller will be brought on-line, during xx_port_start()
+	 * callback, that should also initiate the OOB, COMINIT sequence
+	 */
+
+	DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+	DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+
+	return 0;
+}
+
+/*
+ * scsi mid-layer and libata interface structures
+ */
+static struct scsi_host_template sata_fsl_sht = {
+	.module = THIS_MODULE,
+	.name = "sata_fsl",
+	.ioctl = ata_scsi_ioctl,
+	.queuecommand = ata_scsi_queuecmd,
+	.change_queue_depth = ata_scsi_change_queue_depth,
+	.can_queue = SATA_FSL_QUEUE_DEPTH,
+	.this_id = ATA_SHT_THIS_ID,
+	.sg_tablesize = SATA_FSL_MAX_PRD_USABLE,
+	.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+	.emulated = ATA_SHT_EMULATED,
+	.use_clustering = ATA_SHT_USE_CLUSTERING,
+	.proc_name = "sata_fsl",
+	.dma_boundary = ATA_DMA_BOUNDARY,
+	.slave_configure = ata_scsi_slave_config,
+	.slave_destroy = ata_scsi_slave_destroy,
+	.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
+	.suspend = ata_scsi_device_suspend,
+	.resume = ata_scsi_device_resume,
+#endif
+};
+
+static const struct ata_port_operations sata_fsl_ops = {
+	.port_disable = ata_port_disable,
+
+	.check_status = sata_fsl_check_status,
+	.check_altstatus = sata_fsl_check_status,
+	.dev_select = ata_noop_dev_select,
+
+	.tf_read = sata_fsl_tf_read,
+
+	.qc_prep = sata_fsl_qc_prep,
+	.qc_issue = sata_fsl_qc_issue,
+	.irq_clear = sata_fsl_irq_clear,
+	.irq_on = ata_dummy_irq_on,
+	.irq_ack = ata_dummy_irq_ack,
+
+	.scr_read = sata_fsl_scr_read,
+	.scr_write = sata_fsl_scr_write,
+
+	.freeze = sata_fsl_freeze,
+	.thaw = sata_fsl_thaw,
+	.error_handler = sata_fsl_error_handler,
+	.post_internal_cmd = sata_fsl_post_internal_cmd,
+
+	.port_start = sata_fsl_port_start,
+	.port_stop = sata_fsl_port_stop,
+};
+
+static const struct ata_port_info sata_fsl_port_info[] = {
+	{
+	 .flags = SATA_FSL_HOST_FLAGS,
+	 .pio_mask = 0x1f,	/* pio 0-4 */
+	 .udma_mask = 0x7f,	/* udma 0-6 */
+	 .port_ops = &sata_fsl_ops,
+	 },
+};
+
+static int sata_fsl_probe(struct of_device *ofdev,
+			const struct of_device_id *match)
+{
+	int retval = 0;
+	void __iomem *hcr_base = NULL;
+	void __iomem *ssr_base = NULL;
+	void __iomem *csr_base = NULL;
+	struct sata_fsl_host_priv *host_priv = NULL;
+	struct resource *r;
+	int irq;
+	struct ata_host *host;
+
+	struct ata_port_info pi = sata_fsl_port_info[0];
+	const struct ata_port_info *ppi[] = { &pi, NULL };
+
+	dev_printk(KERN_INFO, &ofdev->dev,
+		   "Sata FSL Platform/CSB Driver init\n");
+
+	r = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+	hcr_base = of_iomap(ofdev->node, 0);
+	if (!hcr_base)
+		goto error_exit_with_cleanup;
+
+	ssr_base = hcr_base + 0x100;
+	csr_base = hcr_base + 0x140;
+
+	DPRINTK("@reset i/o = 0x%x\n", ioread32(csr_base + TRANSCFG));
+	DPRINTK("sizeof(cmd_desc) = %d\n", sizeof(struct command_desc));
+	DPRINTK("sizeof(#define cmd_desc) = %d\n", SATA_FSL_CMD_DESC_SIZE);
+
+	host_priv = kzalloc(sizeof(struct sata_fsl_host_priv), GFP_KERNEL);
+	if (!host_priv)
+		goto error_exit_with_cleanup;
+
+	host_priv->hcr_base = hcr_base;
+	host_priv->ssr_base = ssr_base;
+	host_priv->csr_base = csr_base;
+
+	irq = irq_of_parse_and_map(ofdev->node, 0);
+	if (irq < 0) {
+		dev_printk(KERN_ERR, &ofdev->dev, "invalid irq from platform\n");
+		goto error_exit_with_cleanup;
+	}
+
+	/* allocate host structure */
+	host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS);
+
+	/* host->iomap is not used currently */
+	host->private_data = host_priv;
+
+	/* setup port(s) */
+
+	host->ports[0]->ioaddr.cmd_addr = host_priv->hcr_base;
+	host->ports[0]->ioaddr.scr_addr = host_priv->ssr_base;
+
+	/* initialize host controller */
+	sata_fsl_init_controller(host);
+
+	/*
+	 * Now, register with libATA core, this will also initiate the
+	 * device discovery process, invoking our port_start() handler &
+	 * error_handler() to execute a dummy Softreset EH session
+	 */
+	ata_host_activate(host, irq, sata_fsl_interrupt, SATA_FSL_IRQ_FLAG,
+			  &sata_fsl_sht);
+
+	dev_set_drvdata(&ofdev->dev, host);
+
+	return 0;
+
+error_exit_with_cleanup:
+
+	if (hcr_base)
+		iounmap(hcr_base);
+	if (host_priv)
+		kfree(host_priv);
+
+	return retval;
+}
+
+static int sata_fsl_remove(struct of_device *ofdev)
+{
+	struct ata_host *host = dev_get_drvdata(&ofdev->dev);
+	struct sata_fsl_host_priv *host_priv = host->private_data;
+
+	ata_host_detach(host);
+
+	dev_set_drvdata(&ofdev->dev, NULL);
+
+	irq_dispose_mapping(host->irq);
+	iounmap(host_priv->hcr_base);
+	kfree(host_priv);
+
+	return 0;
+}
+
+static struct of_device_id fsl_sata_match[] = {
+	{
+		.compatible = "fsl,mpc8315-sata",
+	},
+	{
+		.compatible = "fsl,mpc8379-sata",
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, fsl_sata_match);
+
+static struct of_platform_driver fsl_sata_driver = {
+	.name		= "fsl-sata",
+	.match_table	= fsl_sata_match,
+	.probe		= sata_fsl_probe,
+	.remove		= sata_fsl_remove,
+};
+
+static int __init sata_fsl_init(void)
+{
+	of_register_platform_driver(&fsl_sata_driver);
+	return 0;
+}
+
+static void __exit sata_fsl_exit(void)
+{
+	of_unregister_platform_driver(&fsl_sata_driver);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ashish Kalra, Freescale Semiconductor");
+MODULE_DESCRIPTION("Freescale 3.0Gbps SATA controller low level driver");
+MODULE_VERSION("1.10");
+
+module_init(sata_fsl_init);
+module_exit(sata_fsl_exit);
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 4df8311..7f1b13e 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -421,7 +421,6 @@
 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_slave_config(struct scsi_device *sdev);
 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,
@@ -459,7 +458,7 @@
 	.use_clustering		= 1,
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= MV_DMA_BOUNDARY,
-	.slave_configure	= mv_slave_config,
+	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
 };
@@ -477,7 +476,7 @@
 	.use_clustering		= 1,
 	.proc_name		= DRV_NAME,
 	.dma_boundary		= MV_DMA_BOUNDARY,
-	.slave_configure	= mv_slave_config,
+	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
 };
@@ -756,17 +755,6 @@
 {
 }
 
-static int mv_slave_config(struct scsi_device *sdev)
-{
-	int rc = ata_scsi_slave_config(sdev);
-	if (rc)
-		return rc;
-
-	blk_queue_max_phys_segments(sdev->request_queue, MV_MAX_SG_CT / 2);
-
-	return 0;	/* scsi layer doesn't check return value, sigh */
-}
-
 static void mv_set_edma_ptrs(void __iomem *port_mmio,
 			     struct mv_host_priv *hpriv,
 			     struct mv_port_priv *pp)
@@ -1138,7 +1126,7 @@
 {
 	struct mv_port_priv *pp = qc->ap->private_data;
 	struct scatterlist *sg;
-	struct mv_sg *mv_sg;
+	struct mv_sg *mv_sg, *last_sg = NULL;
 
 	mv_sg = pp->sg_tbl;
 	ata_for_each_sg(sg, qc) {
@@ -1159,13 +1147,13 @@
 			sg_len -= len;
 			addr += len;
 
-			if (!sg_len && ata_sg_is_last(sg, qc))
-				mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
-
+			last_sg = mv_sg;
 			mv_sg++;
 		}
-
 	}
+
+	if (likely(last_sg))
+		last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
 }
 
 static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index b061927..26ebffc 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -796,16 +796,19 @@
 				 struct sil24_sge *sge)
 {
 	struct scatterlist *sg;
+	struct sil24_sge *last_sge = NULL;
 
 	ata_for_each_sg(sg, qc) {
 		sge->addr = cpu_to_le64(sg_dma_address(sg));
 		sge->cnt = cpu_to_le32(sg_dma_len(sg));
-		if (ata_sg_is_last(sg, qc))
-			sge->flags = cpu_to_le32(SGE_TRM);
-		else
-			sge->flags = 0;
+		sge->flags = 0;
+
+		last_sge = sge;
 		sge++;
 	}
+
+	if (likely(last_sge))
+		last_sge->flags = cpu_to_le32(SGE_TRM);
 }
 
 static int sil24_qc_defer(struct ata_queued_cmd *qc)
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 8d98a9f..f147dc7 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -92,7 +92,7 @@
 	.queuecommand		= ata_scsi_queuecmd,
 	.can_queue		= ATA_DEF_QUEUE,
 	.this_id		= ATA_SHT_THIS_ID,
-	.sg_tablesize		= ATA_MAX_PRD,
+	.sg_tablesize		= LIBATA_MAX_PRD,
 	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
 	.emulated		= ATA_SHT_EMULATED,
 	.use_clustering		= ATA_SHT_USE_CLUSTERING,
@@ -166,11 +166,11 @@
 	return addr;
 }
 
-static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
+static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg, u32 *val)
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
-	u32 val, val2 = 0;
+	u32 val2 = 0;
 	u8 pmr;
 
 	if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
@@ -178,13 +178,16 @@
 
 	pci_read_config_byte(pdev, SIS_PMR, &pmr);
 
-	pci_read_config_dword(pdev, cfg_addr, &val);
+	pci_read_config_dword(pdev, cfg_addr, val);
 
 	if ((pdev->device == 0x0182) || (pdev->device == 0x0183) ||
 	    (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED))
 		pci_read_config_dword(pdev, cfg_addr+0x10, &val2);
 
-	return (val|val2) &  0xfffffffb; /* avoid problems with powerdowned ports */
+	*val |= val2;
+	*val &= 0xfffffffb;	/* avoid problems with powerdowned ports */
+
+	return 0;
 }
 
 static void sis_scr_cfg_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
@@ -214,7 +217,7 @@
 		return -EINVAL;
 
 	if (ap->flags & SIS_FLAG_CFGSCR)
-		return sis_scr_cfg_read(ap, sc_reg);
+		return sis_scr_cfg_read(ap, sc_reg, val);
 
 	pci_read_config_byte(pdev, SIS_PMR, &pmr);
 
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 94ebc9d..f8f7139 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1596,7 +1596,7 @@
 
 	/* print the bits in the ISR register. */
 	if (fs_debug & FS_DEBUG_IRQ) {
-		/* The FS_DEBUG things are unneccesary here. But this way it is
+		/* The FS_DEBUG things are unnecessary here. But this way it is
 		   clear for grep that these are debug prints. */
 		fs_dprintk (FS_DEBUG_IRQ,  "IRQ status:");
 		for (i=0;i<27;i++) 
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c
index fbae867..5beddc3 100644
--- a/drivers/base/dmapool.c
+++ b/drivers/base/dmapool.c
@@ -366,7 +366,7 @@
 	unsigned long		flags;
 	int			map, block;
 
-	if ((page = pool_find_page (pool, dma)) == 0) {
+	if ((page = pool_find_page(pool, dma)) == NULL) {
 		if (pool->dev)
 			dev_err(pool->dev, "dma_pool_free %s, %p/%lx (bad dma)\n",
 				pool->name, vaddr, (unsigned long) dma);
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index c41d072..7868707 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -137,7 +137,7 @@
 	return len;
 }
 
-static inline int memory_notify(unsigned long val, void *v)
+int memory_notify(unsigned long val, void *v)
 {
 	return blocking_notifier_call_chain(&memory_chain, val, v);
 }
@@ -183,7 +183,6 @@
 			break;
 		case MEM_OFFLINE:
 			mem->state = MEM_GOING_OFFLINE;
-			memory_notify(MEM_GOING_OFFLINE, NULL);
 			start_paddr = page_to_pfn(first_page) << PAGE_SHIFT;
 			ret = remove_memory(start_paddr,
 					    PAGES_PER_SECTION << PAGE_SHIFT);
@@ -191,7 +190,6 @@
 				mem->state = old_state;
 				break;
 			}
-			memory_notify(MEM_MAPPING_INVALID, NULL);
 			break;
 		default:
 			printk(KERN_WARNING "%s(%p, %ld) unknown action: %ld\n",
@@ -199,11 +197,6 @@
 			WARN_ON(1);
 			ret = -EINVAL;
 	}
-	/*
-	 * For now, only notify on successful memory operations
-	 */
-	if (!ret)
-		memory_notify(action, NULL);
 
 	return ret;
 }
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c
index 2b0c601..2b4b392 100644
--- a/drivers/base/power/trace.c
+++ b/drivers/base/power/trace.c
@@ -114,7 +114,7 @@
 	get_rtc_time(&time);
 	printk("Time: %2d:%02d:%02d  Date: %02d/%02d/%02d\n",
 		time.tm_hour, time.tm_min, time.tm_sec,
-		time.tm_mon, time.tm_mday, time.tm_year);
+		time.tm_mon + 1, time.tm_mday, time.tm_year % 100);
 	val = time.tm_year;				/* 100 years */
 	if (val > 100)
 		val -= 100;
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index 8d8cdfe..e1d3ad4d 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -94,27 +94,18 @@
 	.name = "topology"
 };
 
-static cpumask_t topology_dev_map = CPU_MASK_NONE;
-
 /* Add/Remove cpu_topology interface for CPU device */
 static int __cpuinit topology_add_dev(unsigned int cpu)
 {
-	int rc;
 	struct sys_device *sys_dev = get_cpu_sysdev(cpu);
 
-	rc = sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
-	if (!rc)
-		cpu_set(cpu, topology_dev_map);
-	return rc;
+	return sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
 }
 
 static void __cpuinit topology_remove_dev(unsigned int cpu)
 {
 	struct sys_device *sys_dev = get_cpu_sysdev(cpu);
 
-	if (!cpu_isset(cpu, topology_dev_map))
-		return;
-	cpu_clear(cpu, topology_dev_map);
 	sysfs_remove_group(&sys_dev->kobj, &topology_attr_group);
 }
 
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 84d6aa5..9030c37 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -44,6 +44,7 @@
 #include <linux/init.h>
 #include <linux/jiffies.h>
 #include <linux/random.h>
+#include <linux/scatterlist.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include "DAC960.h"
@@ -345,6 +346,7 @@
 	Command->V1.ScatterGatherList =
 		(DAC960_V1_ScatterGatherSegment_T *)ScatterGatherCPU;
 	Command->V1.ScatterGatherListDMA = ScatterGatherDMA;
+	sg_init_table(Command->cmd_sglist, DAC960_V1_ScatterGatherLimit);
       } else {
         Command->cmd_sglist = Command->V2.ScatterList;
 	Command->V2.ScatterGatherList =
@@ -353,6 +355,7 @@
 	Command->V2.RequestSense =
 				(DAC960_SCSI_RequestSense_T *)RequestSenseCPU;
 	Command->V2.RequestSenseDMA = RequestSenseDMA;
+	sg_init_table(Command->cmd_sglist, DAC960_V2_ScatterGatherLimit);
       }
     }
   return true;
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index ca4d7f0..4d0119e 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -204,23 +204,6 @@
 	bool
 	default BLK_DEV_UBD
 
-config MMAPPER
-	tristate "Example IO memory driver (BROKEN)"
-	depends on UML && BROKEN
-	---help---
-          The User-Mode Linux port can provide support for IO Memory
-          emulation with this option.  This allows a host file to be
-          specified as an I/O region on the kernel command line. That file
-          will be mapped into UML's kernel address space where a driver can
-          locate it and do whatever it wants with the memory, including
-          providing an interface to it for UML processes to use.
-
-          For more information, see
-          <http://user-mode-linux.sourceforge.net/iomem.html>.
-
-          If you'd like to be able to provide a simulated IO port space for
-          User-Mode Linux processes, say Y.  If unsure, say N.
-
 config BLK_DEV_LOOP
 	tristate "Loopback device support"
 	---help---
@@ -351,7 +334,7 @@
 	default "16"
 	depends on BLK_DEV_RAM
 	help
-	  The default value is 16 RAM disks. Change this if you know what
+	  The default value is 16 RAM disks. Change this if you know what you
 	  are doing. If you boot from a filesystem that needs to be extracted
 	  in memory, you will need at least one RAM disk (e.g. root on cramfs).
 
@@ -361,7 +344,7 @@
 	default "4096"
 	help
 	  The default value is 4096 kilobytes. Only change this if you know
-	  what are you doing.
+	  what you are doing.
 
 config BLK_DEV_RAM_BLOCKSIZE
 	int "Default RAM disk block size (bytes)"
@@ -442,4 +425,10 @@
 	  block device driver.  It communicates with a back-end driver
 	  in another domain which drives the actual block device.
 
+config VIRTIO_BLK
+	tristate "Virtio block driver (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && VIRTIO
+	---help---
+	  This is the virtual block driver for lguest.  Say Y or M.
+
 endif # BLK_DEV
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 014e721..7691505 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -25,10 +25,10 @@
 obj-$(CONFIG_BLK_DEV_UMEM)	+= umem.o
 obj-$(CONFIG_BLK_DEV_NBD)	+= nbd.o
 obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o
+obj-$(CONFIG_VIRTIO_BLK)	+= virtio_blk.o
 
 obj-$(CONFIG_VIODASD)		+= viodasd.o
 obj-$(CONFIG_BLK_DEV_SX8)	+= sx8.o
 obj-$(CONFIG_BLK_DEV_UB)	+= ub.o
 
 obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= xen-blkfront.o
-obj-$(CONFIG_LGUEST_BLOCK)	+= lguest_blk.o
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 7c2cfde..5a6fe17 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2610,7 +2610,7 @@
 	       (int)creq->nr_sectors);
 #endif				/* CCISS_DEBUG */
 
-	memset(tmp_sg, 0, sizeof(tmp_sg));
+	sg_init_table(tmp_sg, MAXSGENTRIES);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* get the DMA records for the setup */
@@ -2621,7 +2621,7 @@
 
 	for (i = 0; i < seg; i++) {
 		c->SG[i].Len = tmp_sg[i].length;
-		temp64.val = (__u64) pci_map_page(h->pdev, tmp_sg[i].page,
+		temp64.val = (__u64) pci_map_page(h->pdev, sg_page(&tmp_sg[i]),
 						  tmp_sg[i].offset,
 						  tmp_sg[i].length, dir);
 		c->SG[i].Addr.lower = temp64.val32.lower;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 568603d..c8132d9 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -37,6 +37,7 @@
 #include <linux/spinlock.h>
 #include <linux/blkdev.h>
 #include <linux/genhd.h>
+#include <linux/scatterlist.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -918,6 +919,7 @@
 DBGPX(
 	printk("sector=%d, nr_sectors=%d\n", creq->sector, creq->nr_sectors);
 );
+	sg_init_table(tmp_sg, SG_MAX);
 	seg = blk_rq_map_sg(q, creq, tmp_sg);
 
 	/* Now do all the DMA Mappings */
@@ -929,7 +931,7 @@
 	{
 		c->req.sg[i].size = tmp_sg[i].length;
 		c->req.sg[i].addr = (__u32) pci_map_page(h->pci_dev,
-						 tmp_sg[i].page,
+						 sg_page(&tmp_sg[i]),
 						 tmp_sg[i].offset,
 						 tmp_sg[i].length, dir);
 	}
diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c
index 4053503..1b58b01 100644
--- a/drivers/block/cryptoloop.c
+++ b/drivers/block/cryptoloop.c
@@ -26,6 +26,7 @@
 #include <linux/crypto.h>
 #include <linux/blkdev.h>
 #include <linux/loop.h>
+#include <linux/scatterlist.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
 
@@ -119,14 +120,17 @@
 		.tfm = tfm,
 		.flags = CRYPTO_TFM_REQ_MAY_SLEEP,
 	};
-	struct scatterlist sg_out = { NULL, };
-	struct scatterlist sg_in = { NULL, };
+	struct scatterlist sg_out;
+	struct scatterlist sg_in;
 
 	encdec_cbc_t encdecfunc;
 	struct page *in_page, *out_page;
 	unsigned in_offs, out_offs;
 	int err;
 
+	sg_init_table(&sg_out, 1);
+	sg_init_table(&sg_in, 1);
+
 	if (cmd == READ) {
 		in_page = raw_page;
 		in_offs = raw_off;
@@ -146,11 +150,11 @@
 		u32 iv[4] = { 0, };
 		iv[0] = cpu_to_le32(IV & 0xffffffff);
 
-		sg_in.page = in_page;
+		sg_set_page(&sg_in, in_page);
 		sg_in.offset = in_offs;
 		sg_in.length = sz;
 
-		sg_out.page = out_page;
+		sg_set_page(&sg_out, out_page);
 		sg_out.offset = out_offs;
 		sg_out.length = sz;
 
diff --git a/drivers/block/lguest_blk.c b/drivers/block/lguest_blk.c
deleted file mode 100644
index fa8e423..0000000
--- a/drivers/block/lguest_blk.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*D:400
- * The Guest block driver
- *
- * This is a simple block driver, which appears as /dev/lgba, lgbb, lgbc etc.
- * The mechanism is simple: we place the information about the request in the
- * device page, then use SEND_DMA (containing the data for a write, or an empty
- * "ping" DMA for a read).
- :*/
-/* Copyright 2006 Rusty Russell <rusty@rustcorp.com.au> IBM 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
- */
-//#define DEBUG
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/blkdev.h>
-#include <linux/interrupt.h>
-#include <linux/lguest_bus.h>
-
-static char next_block_index = 'a';
-
-/*D:420 Here is the structure which holds all the information we need about
- * each Guest block device.
- *
- * I'm sure at this stage, you're wondering "hey, where was the adventure I was
- * promised?" and thinking "Rusty sucks, I shall say nasty things about him on
- * my blog".  I think Real adventures have boring bits, too, and you're in the
- * middle of one.  But it gets better.  Just not quite yet. */
-struct blockdev
-{
-	/* The block queue infrastructure wants a spinlock: it is held while it
-	 * calls our block request function.  We grab it in our interrupt
-	 * handler so the responses don't mess with new requests. */
-	spinlock_t lock;
-
-	/* The disk structure registered with kernel. */
-	struct gendisk *disk;
-
-	/* The major device number for this disk, and the interrupt.  We only
-	 * really keep them here for completeness; we'd need them if we
-	 * supported device unplugging. */
-	int major;
-	int irq;
-
-	/* The physical address of this device's memory page */
-	unsigned long phys_addr;
-	/* The mapped memory page for convenient acces. */
-	struct lguest_block_page *lb_page;
-
-	/* We only have a single request outstanding at a time: this is it. */
-	struct lguest_dma dma;
-	struct request *req;
-};
-
-/*D:495 We originally used end_request() throughout the driver, but it turns
- * out that end_request() is deprecated, and doesn't actually end the request
- * (which seems like a good reason to deprecate it!).  It simply ends the first
- * bio.  So if we had 3 bios in a "struct request" we would do all 3,
- * end_request(), do 2, end_request(), do 1 and end_request(): twice as much
- * work as we needed to do.
- *
- * This reinforced to me that I do not understand the block layer.
- *
- * Nonetheless, Jens Axboe gave me this nice helper to end all chunks of a
- * request.  This improved disk speed by 130%. */
-static void end_entire_request(struct request *req, int uptodate)
-{
-	if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
-		BUG();
-	add_disk_randomness(req->rq_disk);
-	blkdev_dequeue_request(req);
-	end_that_request_last(req, uptodate);
-}
-
-/* I'm told there are only two stories in the world worth telling: love and
- * hate.  So there used to be a love scene here like this:
- *
- *  Launcher:	We could make beautiful I/O together, you and I.
- *  Guest:	My, that's a big disk!
- *
- * Unfortunately, it was just too raunchy for our otherwise-gentle tale. */
-
-/*D:490 This is the interrupt handler, called when a block read or write has
- * been completed for us. */
-static irqreturn_t lgb_irq(int irq, void *_bd)
-{
-	/* We handed our "struct blockdev" as the argument to request_irq(), so
-	 * it is passed through to us here.  This tells us which device we're
-	 * dealing with in case we have more than one. */
-	struct blockdev *bd = _bd;
-	unsigned long flags;
-
-	/* We weren't doing anything?  Strange, but could happen if we shared
-	 * interrupts (we don't!). */
-	if (!bd->req) {
-		pr_debug("No work!\n");
-		return IRQ_NONE;
-	}
-
-	/* Not done yet?  That's equally strange. */
-	if (!bd->lb_page->result) {
-		pr_debug("No result!\n");
-		return IRQ_NONE;
-	}
-
-	/* We have to grab the lock before ending the request. */
-	spin_lock_irqsave(&bd->lock, flags);
-	/* "result" is 1 for success, 2 for failure: end_entire_request() wants
-	 * to know whether this succeeded or not. */
-	end_entire_request(bd->req, bd->lb_page->result == 1);
-	/* Clear out request, it's done. */
-	bd->req = NULL;
-	/* Reset incoming DMA for next time. */
-	bd->dma.used_len = 0;
-	/* Ready for more reads or writes */
-	blk_start_queue(bd->disk->queue);
-	spin_unlock_irqrestore(&bd->lock, flags);
-
-	/* The interrupt was for us, we dealt with it. */
-	return IRQ_HANDLED;
-}
-
-/*D:480 The block layer's "struct request" contains a number of "struct bio"s,
- * each of which contains "struct bio_vec"s, each of which contains a page, an
- * offset and a length.
- *
- * Fortunately there are iterators to help us walk through the "struct
- * request".  Even more fortunately, there were plenty of places to steal the
- * code from.  We pack the "struct request" into our "struct lguest_dma" and
- * return the total length. */
-static unsigned int req_to_dma(struct request *req, struct lguest_dma *dma)
-{
-	unsigned int i = 0, len = 0;
-	struct req_iterator iter;
-	struct bio_vec *bvec;
-
-	rq_for_each_segment(bvec, req, iter) {
-		/* We told the block layer not to give us too many. */
-		BUG_ON(i == LGUEST_MAX_DMA_SECTIONS);
-		/* If we had a zero-length segment, it would look like
-		 * the end of the data referred to by the "struct
-		 * lguest_dma", so make sure that doesn't happen. */
-		BUG_ON(!bvec->bv_len);
-		/* Convert page & offset to a physical address */
-		dma->addr[i] = page_to_phys(bvec->bv_page)
-			+ bvec->bv_offset;
-		dma->len[i] = bvec->bv_len;
-		len += bvec->bv_len;
-		i++;
-	}
-	/* If the array isn't full, we mark the end with a 0 length */
-	if (i < LGUEST_MAX_DMA_SECTIONS)
-		dma->len[i] = 0;
-	return len;
-}
-
-/* This creates an empty DMA, useful for prodding the Host without sending data
- * (ie. when we want to do a read) */
-static void empty_dma(struct lguest_dma *dma)
-{
-	dma->len[0] = 0;
-}
-
-/*D:470 Setting up a request is fairly easy: */
-static void setup_req(struct blockdev *bd,
-		      int type, struct request *req, struct lguest_dma *dma)
-{
-	/* The type is 1 (write) or 0 (read). */
-	bd->lb_page->type = type;
-	/* The sector on disk where the read or write starts. */
-	bd->lb_page->sector = req->sector;
-	/* The result is initialized to 0 (unfinished). */
-	bd->lb_page->result = 0;
-	/* The current request (so we can end it in the interrupt handler). */
-	bd->req = req;
-	/* The number of bytes: returned as a side-effect of req_to_dma(),
-	 * which packs the block layer's "struct request" into our "struct
-	 * lguest_dma" */
-	bd->lb_page->bytes = req_to_dma(req, dma);
-}
-
-/*D:450 Write is pretty straightforward: we pack the request into a "struct
- * lguest_dma", then use SEND_DMA to send the request. */
-static void do_write(struct blockdev *bd, struct request *req)
-{
-	struct lguest_dma send;
-
-	pr_debug("lgb: WRITE sector %li\n", (long)req->sector);
-	setup_req(bd, 1, req, &send);
-
-	lguest_send_dma(bd->phys_addr, &send);
-}
-
-/* Read is similar to write, except we pack the request into our receive
- * "struct lguest_dma" and send through an empty DMA just to tell the Host that
- * there's a request pending. */
-static void do_read(struct blockdev *bd, struct request *req)
-{
-	struct lguest_dma ping;
-
-	pr_debug("lgb: READ sector %li\n", (long)req->sector);
-	setup_req(bd, 0, req, &bd->dma);
-
-	empty_dma(&ping);
-	lguest_send_dma(bd->phys_addr, &ping);
-}
-
-/*D:440 This where requests come in: we get handed the request queue and are
- * expected to pull a "struct request" off it until we've finished them or
- * we're waiting for a reply: */
-static void do_lgb_request(struct request_queue *q)
-{
-	struct blockdev *bd;
-	struct request *req;
-
-again:
-	/* This sometimes returns NULL even on the very first time around.  I
-	 * wonder if it's something to do with letting elves handle the request
-	 * queue... */
-	req = elv_next_request(q);
-	if (!req)
-		return;
-
-	/* We attached the struct blockdev to the disk: get it back */
-	bd = req->rq_disk->private_data;
-	/* Sometimes we get repeated requests after blk_stop_queue(), but we
-	 * can only handle one at a time. */
-	if (bd->req)
-		return;
-
-	/* We only do reads and writes: no tricky business! */
-	if (!blk_fs_request(req)) {
-		pr_debug("Got non-command 0x%08x\n", req->cmd_type);
-		req->errors++;
-		end_entire_request(req, 0);
-		goto again;
-	}
-
-	if (rq_data_dir(req) == WRITE)
-		do_write(bd, req);
-	else
-		do_read(bd, req);
-
-	/* We've put out the request, so stop any more coming in until we get
-	 * an interrupt, which takes us to lgb_irq() to re-enable the queue. */
-	blk_stop_queue(q);
-}
-
-/*D:430 This is the "struct block_device_operations" we attach to the disk at
- * the end of lguestblk_probe().  It doesn't seem to want much. */
-static struct block_device_operations lguestblk_fops = {
-	.owner = THIS_MODULE,
-};
-
-/*D:425 Setting up a disk device seems to involve a lot of code.  I'm not sure
- * quite why.  I do know that the IDE code sent two or three of the maintainers
- * insane, perhaps this is the fringe of the same disease?
- *
- * As in the console code, the probe function gets handed the generic
- * lguest_device from lguest_bus.c: */
-static int lguestblk_probe(struct lguest_device *lgdev)
-{
-	struct blockdev *bd;
-	int err;
-	int irqflags = IRQF_SHARED;
-
-	/* First we allocate our own "struct blockdev" and initialize the easy
-	 * fields. */
-	bd = kmalloc(sizeof(*bd), GFP_KERNEL);
-	if (!bd)
-		return -ENOMEM;
-
-	spin_lock_init(&bd->lock);
-	bd->irq = lgdev_irq(lgdev);
-	bd->req = NULL;
-	bd->dma.used_len = 0;
-	bd->dma.len[0] = 0;
-	/* The descriptor in the lguest_devices array provided by the Host
-	 * gives the Guest the physical page number of the device's page. */
-	bd->phys_addr = (lguest_devices[lgdev->index].pfn << PAGE_SHIFT);
-
-	/* We use lguest_map() to get a pointer to the device page */
-	bd->lb_page = lguest_map(bd->phys_addr, 1);
-	if (!bd->lb_page) {
-		err = -ENOMEM;
-		goto out_free_bd;
-	}
-
-	/* We need a major device number: 0 means "assign one dynamically". */
-	bd->major = register_blkdev(0, "lguestblk");
-	if (bd->major < 0) {
-		err = bd->major;
-		goto out_unmap;
-	}
-
-	/* This allocates a "struct gendisk" where we pack all the information
-	 * about the disk which the rest of Linux sees.  The argument is the
-	 * number of minor devices desired: we need one minor for the main
-	 * disk, and one for each partition.  Of course, we can't possibly know
-	 * how many partitions are on the disk (add_disk does that).
-	 */
-	bd->disk = alloc_disk(16);
-	if (!bd->disk) {
-		err = -ENOMEM;
-		goto out_unregister_blkdev;
-	}
-
-	/* Every disk needs a queue for requests to come in: we set up the
-	 * queue with a callback function (the core of our driver) and the lock
-	 * to use. */
-	bd->disk->queue = blk_init_queue(do_lgb_request, &bd->lock);
-	if (!bd->disk->queue) {
-		err = -ENOMEM;
-		goto out_put_disk;
-	}
-
-	/* We can only handle a certain number of pointers in our SEND_DMA
-	 * call, so we set that with blk_queue_max_hw_segments().  This is not
-	 * to be confused with blk_queue_max_phys_segments() of course!  I
-	 * know, who could possibly confuse the two?
-	 *
-	 * Well, it's simple to tell them apart: this one seems to work and the
-	 * other one didn't. */
-	blk_queue_max_hw_segments(bd->disk->queue, LGUEST_MAX_DMA_SECTIONS);
-
-	/* Due to technical limitations of our Host (and simple coding) we
-	 * can't have a single buffer which crosses a page boundary.  Tell it
-	 * here.  This means that our maximum request size is 16
-	 * (LGUEST_MAX_DMA_SECTIONS) pages. */
-	blk_queue_segment_boundary(bd->disk->queue, PAGE_SIZE-1);
-
-	/* We name our disk: this becomes the device name when udev does its
-	 * magic thing and creates the device node, such as /dev/lgba.
-	 * next_block_index is a global which starts at 'a'.  Unfortunately
-	 * this simple increment logic means that the 27th disk will be called
-	 * "/dev/lgb{".  In that case, I recommend having at least 29 disks, so
-	 * your /dev directory will be balanced. */
-	sprintf(bd->disk->disk_name, "lgb%c", next_block_index++);
-
-	/* We look to the device descriptor again to see if this device's
-	 * interrupts are expected to be random.  If they are, we tell the irq
-	 * subsystem.  At the moment this bit is always set. */
-	if (lguest_devices[lgdev->index].features & LGUEST_DEVICE_F_RANDOMNESS)
-		irqflags |= IRQF_SAMPLE_RANDOM;
-
-	/* Now we have the name and irqflags, we can request the interrupt; we
-	 * give it the "struct blockdev" we have set up to pass to lgb_irq()
-	 * when there is an interrupt. */
-	err = request_irq(bd->irq, lgb_irq, irqflags, bd->disk->disk_name, bd);
-	if (err)
-		goto out_cleanup_queue;
-
-	/* We bind our one-entry DMA pool to the key for this block device so
-	 * the Host can reply to our requests.  The key is equal to the
-	 * physical address of the device's page, which is conveniently
-	 * unique. */
-	err = lguest_bind_dma(bd->phys_addr, &bd->dma, 1, bd->irq);
-	if (err)
-		goto out_free_irq;
-
-	/* We finish our disk initialization and add the disk to the system. */
-	bd->disk->major = bd->major;
-	bd->disk->first_minor = 0;
-	bd->disk->private_data = bd;
-	bd->disk->fops = &lguestblk_fops;
-	/* This is initialized to the disk size by the Launcher. */
-	set_capacity(bd->disk, bd->lb_page->num_sectors);
-	add_disk(bd->disk);
-
-	printk(KERN_INFO "%s: device %i at major %d\n",
-	       bd->disk->disk_name, lgdev->index, bd->major);
-
-	/* We don't need to keep the "struct blockdev" around, but if we ever
-	 * implemented device removal, we'd need this. */
-	lgdev->private = bd;
-	return 0;
-
-out_free_irq:
-	free_irq(bd->irq, bd);
-out_cleanup_queue:
-	blk_cleanup_queue(bd->disk->queue);
-out_put_disk:
-	put_disk(bd->disk);
-out_unregister_blkdev:
-	unregister_blkdev(bd->major, "lguestblk");
-out_unmap:
-	lguest_unmap(bd->lb_page);
-out_free_bd:
-	kfree(bd);
-	return err;
-}
-
-/*D:410 The boilerplate code for registering the lguest block driver is just
- * like the console: */
-static struct lguest_driver lguestblk_drv = {
-	.name = "lguestblk",
-	.owner = THIS_MODULE,
-	.device_type = LGUEST_DEVICE_T_BLOCK,
-	.probe = lguestblk_probe,
-};
-
-static __init int lguestblk_init(void)
-{
-	return register_lguest_driver(&lguestblk_drv);
-}
-module_init(lguestblk_init);
-
-MODULE_DESCRIPTION("Lguest block driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 589cbbd..56e23042 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -29,7 +29,7 @@
  *
  * Maximum number of loop devices when compiled-in now selectable by passing
  * max_loop=<1-255> to the kernel on boot.
- * Erik I. Bolsø, <eriki@himolde.no>, Oct 31, 1999
+ * Erik I. Bolsø, <eriki@himolde.no>, Oct 31, 1999
  *
  * Completely rewrite request handling to be make_request_fn style and
  * non blocking, pushing work to a helper thread. Lots of fixes from
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index cb136a9..6332aca 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -188,7 +188,7 @@
 		if (signal_pending(current)) {
 			siginfo_t info;
 			printk(KERN_WARNING "nbd (pid %d: %s) got signal %d\n",
-				current->pid, current->comm,
+				task_pid_nr(current), current->comm,
 				dequeue_signal_lock(current, &current->blocked, &info));
 			result = -EINTR;
 			sock_shutdown(lo, !send);
@@ -508,7 +508,6 @@
 		nbd_end_request(req);
 		spin_lock(q->queue_lock);
 	}
-	return;
 }
 
 static int nbd_ioctl(struct inode *inode, struct file *file,
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 08176d2..47f8ac6 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -365,7 +365,7 @@
 		/*
 		 * Deep badness.  rd_blkdev_pagecache_IO() needs to allocate
 		 * pagecache pages within a request_fn.  We cannot recur back
-		 * into the filesytem which is mounted atop the ramdisk, because
+		 * into the filesystem which is mounted atop the ramdisk, because
 		 * that would deadlock on fs locks.  And we really don't want
 		 * to reenter rd_blkdev_pagecache_IO when we're already within
 		 * that function.
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 317a790..7276f7d 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -388,6 +388,7 @@
 		op = VD_OP_BWRITE;
 	}
 
+	sg_init_table(sg, port->ring_cookies);
 	nsg = blk_rq_map_sg(req->q, req, sg);
 
 	len = 0;
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index 402209f..52dc5e1 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -27,6 +27,7 @@
 #include <linux/hdreg.h>
 #include <linux/dma-mapping.h>
 #include <linux/completion.h>
+#include <linux/scatterlist.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
@@ -522,6 +523,7 @@
 			host->n_msgs++;
 
 			assert(host->n_msgs <= CARM_MAX_REQ);
+			sg_init_table(crq->sg, CARM_MAX_REQ_SG);
 			return crq;
 		}
 
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index c57dd2b..14143f2 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -25,6 +25,7 @@
 #include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/timer.h>
+#include <linux/scatterlist.h>
 #include <scsi/scsi.h>
 
 #define DRV_NAME "ub"
@@ -656,6 +657,7 @@
 	if ((cmd = ub_get_cmd(lun)) == NULL)
 		return -1;
 	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
+	sg_init_table(cmd->sgv, UB_MAX_REQ_SG);
 
 	blkdev_dequeue_request(rq);
 
@@ -1309,9 +1311,8 @@
 	else
 		pipe = sc->send_bulk_pipe;
 	sc->last_pipe = pipe;
-	usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
-	    page_address(sg->page) + sg->offset, sg->length,
-	    ub_urb_complete, sc);
+	usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, sg_virt(sg),
+	    sg->length, ub_urb_complete, sc);
 	sc->work_urb.actual_length = 0;
 	sc->work_urb.error_count = 0;
 	sc->work_urb.status = 0;
@@ -1427,7 +1428,7 @@
 	scmd->state = UB_CMDST_INIT;
 	scmd->nsg = 1;
 	sg = &scmd->sgv[0];
-	sg->page = virt_to_page(sc->top_sense);
+	sg_set_page(sg, virt_to_page(sc->top_sense));
 	sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1);
 	sg->length = UB_SENSE_SIZE;
 	scmd->len = UB_SENSE_SIZE;
@@ -1863,7 +1864,7 @@
 	cmd->state = UB_CMDST_INIT;
 	cmd->nsg = 1;
 	sg = &cmd->sgv[0];
-	sg->page = virt_to_page(p);
+	sg_set_page(sg, virt_to_page(p));
 	sg->offset = (unsigned long)p & (PAGE_SIZE-1);
 	sg->length = 8;
 	cmd->len = 8;
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index e824b67..ab5d404 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -41,6 +41,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/completion.h>
 #include <linux/device.h>
+#include <linux/scatterlist.h>
 
 #include <asm/uaccess.h>
 #include <asm/vio.h>
@@ -270,6 +271,7 @@
         d = req->rq_disk->private_data;
 
 	/* Now build the scatter-gather list */
+	sg_init_table(sg, VIOMAXBLOCKDMA);
 	nsg = blk_rq_map_sg(req->q, req, sg);
 	nsg = dma_map_sg(d->dev, sg, nsg, direction);
 
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
new file mode 100644
index 0000000..a901eee
--- /dev/null
+++ b/drivers/block/virtio_blk.c
@@ -0,0 +1,308 @@
+//#define DEBUG
+#include <linux/spinlock.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/virtio.h>
+#include <linux/virtio_blk.h>
+#include <linux/virtio_blk.h>
+
+static unsigned char virtblk_index = 'a';
+struct virtio_blk
+{
+	spinlock_t lock;
+
+	struct virtio_device *vdev;
+	struct virtqueue *vq;
+
+	/* The disk structure for the kernel. */
+	struct gendisk *disk;
+
+	/* Request tracking. */
+	struct list_head reqs;
+
+	mempool_t *pool;
+
+	/* Scatterlist: can be too big for stack. */
+	struct scatterlist sg[3+MAX_PHYS_SEGMENTS];
+};
+
+struct virtblk_req
+{
+	struct list_head list;
+	struct request *req;
+	struct virtio_blk_outhdr out_hdr;
+	struct virtio_blk_inhdr in_hdr;
+};
+
+static bool blk_done(struct virtqueue *vq)
+{
+	struct virtio_blk *vblk = vq->vdev->priv;
+	struct virtblk_req *vbr;
+	unsigned int len;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vblk->lock, flags);
+	while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) {
+		int uptodate;
+		switch (vbr->in_hdr.status) {
+		case VIRTIO_BLK_S_OK:
+			uptodate = 1;
+			break;
+		case VIRTIO_BLK_S_UNSUPP:
+			uptodate = -ENOTTY;
+			break;
+		default:
+			uptodate = 0;
+			break;
+		}
+
+		end_dequeued_request(vbr->req, uptodate);
+		list_del(&vbr->list);
+		mempool_free(vbr, vblk->pool);
+	}
+	/* In case queue is stopped waiting for more buffers. */
+	blk_start_queue(vblk->disk->queue);
+	spin_unlock_irqrestore(&vblk->lock, flags);
+	return true;
+}
+
+static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
+		   struct request *req)
+{
+	unsigned long num, out, in;
+	struct virtblk_req *vbr;
+
+	vbr = mempool_alloc(vblk->pool, GFP_ATOMIC);
+	if (!vbr)
+		/* When another request finishes we'll try again. */
+		return false;
+
+	vbr->req = req;
+	if (blk_fs_request(vbr->req)) {
+		vbr->out_hdr.type = 0;
+		vbr->out_hdr.sector = vbr->req->sector;
+		vbr->out_hdr.ioprio = vbr->req->ioprio;
+	} else if (blk_pc_request(vbr->req)) {
+		vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD;
+		vbr->out_hdr.sector = 0;
+		vbr->out_hdr.ioprio = vbr->req->ioprio;
+	} else {
+		/* We don't put anything else in the queue. */
+		BUG();
+	}
+
+	if (blk_barrier_rq(vbr->req))
+		vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER;
+
+	/* We have to zero this, otherwise blk_rq_map_sg gets upset. */
+	memset(vblk->sg, 0, sizeof(vblk->sg));
+	sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr));
+	num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);
+	sg_set_buf(&vblk->sg[num+1], &vbr->in_hdr, sizeof(vbr->in_hdr));
+
+	if (rq_data_dir(vbr->req) == WRITE) {
+		vbr->out_hdr.type |= VIRTIO_BLK_T_OUT;
+		out = 1 + num;
+		in = 1;
+	} else {
+		vbr->out_hdr.type |= VIRTIO_BLK_T_IN;
+		out = 1;
+		in = 1 + num;
+	}
+
+	if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr)) {
+		mempool_free(vbr, vblk->pool);
+		return false;
+	}
+
+	list_add_tail(&vbr->list, &vblk->reqs);
+	return true;
+}
+
+static void do_virtblk_request(struct request_queue *q)
+{
+	struct virtio_blk *vblk = NULL;
+	struct request *req;
+	unsigned int issued = 0;
+
+	while ((req = elv_next_request(q)) != NULL) {
+		vblk = req->rq_disk->private_data;
+		BUG_ON(req->nr_phys_segments > ARRAY_SIZE(vblk->sg));
+
+		/* If this request fails, stop queue and wait for something to
+		   finish to restart it. */
+		if (!do_req(q, vblk, req)) {
+			blk_stop_queue(q);
+			break;
+		}
+		blkdev_dequeue_request(req);
+		issued++;
+	}
+
+	if (issued)
+		vblk->vq->vq_ops->kick(vblk->vq);
+}
+
+static int virtblk_ioctl(struct inode *inode, struct file *filp,
+			 unsigned cmd, unsigned long data)
+{
+	return scsi_cmd_ioctl(filp, inode->i_bdev->bd_disk->queue,
+			      inode->i_bdev->bd_disk, cmd,
+			      (void __user *)data);
+}
+
+static struct block_device_operations virtblk_fops = {
+	.ioctl = virtblk_ioctl,
+	.owner = THIS_MODULE,
+};
+
+static int virtblk_probe(struct virtio_device *vdev)
+{
+	struct virtio_blk *vblk;
+	int err, major;
+	void *token;
+	unsigned int len;
+	u64 cap;
+	u32 v;
+
+	vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL);
+	if (!vblk) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	INIT_LIST_HEAD(&vblk->reqs);
+	spin_lock_init(&vblk->lock);
+	vblk->vdev = vdev;
+
+	/* We expect one virtqueue, for output. */
+	vblk->vq = vdev->config->find_vq(vdev, blk_done);
+	if (IS_ERR(vblk->vq)) {
+		err = PTR_ERR(vblk->vq);
+		goto out_free_vblk;
+	}
+
+	vblk->pool = mempool_create_kmalloc_pool(1,sizeof(struct virtblk_req));
+	if (!vblk->pool) {
+		err = -ENOMEM;
+		goto out_free_vq;
+	}
+
+	major = register_blkdev(0, "virtblk");
+	if (major < 0) {
+		err = major;
+		goto out_mempool;
+	}
+
+	/* FIXME: How many partitions?  How long is a piece of string? */
+	vblk->disk = alloc_disk(1 << 4);
+	if (!vblk->disk) {
+		err = -ENOMEM;
+		goto out_unregister_blkdev;
+	}
+
+	vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock);
+	if (!vblk->disk->queue) {
+		err = -ENOMEM;
+		goto out_put_disk;
+	}
+
+	sprintf(vblk->disk->disk_name, "vd%c", virtblk_index++);
+	vblk->disk->major = major;
+	vblk->disk->first_minor = 0;
+	vblk->disk->private_data = vblk;
+	vblk->disk->fops = &virtblk_fops;
+
+	/* If barriers are supported, tell block layer that queue is ordered */
+	token = vdev->config->find(vdev, VIRTIO_CONFIG_BLK_F, &len);
+	if (virtio_use_bit(vdev, token, len, VIRTIO_BLK_F_BARRIER))
+		blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL);
+
+	err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap);
+	if (err) {
+		dev_err(&vdev->dev, "Bad/missing capacity in config\n");
+		goto out_put_disk;
+	}
+
+	/* If capacity is too big, truncate with warning. */
+	if ((sector_t)cap != cap) {
+		dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n",
+			 (unsigned long long)cap);
+		cap = (sector_t)-1;
+	}
+	set_capacity(vblk->disk, cap);
+
+	err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SIZE_MAX, &v);
+	if (!err)
+		blk_queue_max_segment_size(vblk->disk->queue, v);
+	else if (err != -ENOENT) {
+		dev_err(&vdev->dev, "Bad SIZE_MAX in config\n");
+		goto out_put_disk;
+	}
+
+	err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v);
+	if (!err)
+		blk_queue_max_hw_segments(vblk->disk->queue, v);
+	else if (err != -ENOENT) {
+		dev_err(&vdev->dev, "Bad SEG_MAX in config\n");
+		goto out_put_disk;
+	}
+
+	add_disk(vblk->disk);
+	return 0;
+
+out_put_disk:
+	put_disk(vblk->disk);
+out_unregister_blkdev:
+	unregister_blkdev(major, "virtblk");
+out_mempool:
+	mempool_destroy(vblk->pool);
+out_free_vq:
+	vdev->config->del_vq(vblk->vq);
+out_free_vblk:
+	kfree(vblk);
+out:
+	return err;
+}
+
+static void virtblk_remove(struct virtio_device *vdev)
+{
+	struct virtio_blk *vblk = vdev->priv;
+	int major = vblk->disk->major;
+
+	BUG_ON(!list_empty(&vblk->reqs));
+	blk_cleanup_queue(vblk->disk->queue);
+	put_disk(vblk->disk);
+	unregister_blkdev(major, "virtblk");
+	mempool_destroy(vblk->pool);
+	kfree(vblk);
+}
+
+static struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_BLOCK, VIRTIO_DEV_ANY_ID },
+	{ 0 },
+};
+
+static struct virtio_driver virtio_blk = {
+	.driver.name =	KBUILD_MODNAME,
+	.driver.owner =	THIS_MODULE,
+	.id_table =	id_table,
+	.probe =	virtblk_probe,
+	.remove =	__devexit_p(virtblk_remove),
+};
+
+static int __init init(void)
+{
+	return register_virtio_driver(&virtio_blk);
+}
+
+static void __exit fini(void)
+{
+	unregister_virtio_driver(&virtio_blk);
+}
+module_init(init);
+module_exit(fini);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_DESCRIPTION("Virtio block driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 9e7652d..82effce 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -390,8 +390,8 @@
 static void ace_dump_regs(struct ace_device *ace)
 {
 	dev_info(ace->dev, "    ctrl:  %.8x  seccnt/cmd: %.4x      ver:%.4x\n"
-		 "    status:%.8x  mpu_lba:%.8x  busmode:%4x\n"
-		 "    error: %.8x  cfg_lba:%.8x  fatstat:%.4x\n",
+		 KERN_INFO "    status:%.8x  mpu_lba:%.8x  busmode:%4x\n"
+		 KERN_INFO "    error: %.8x  cfg_lba:%.8x  fatstat:%.4x\n",
 		 ace_in32(ace, ACE_CTRL),
 		 ace_in(ace, ACE_SECCNTCMD),
 		 ace_in(ace, ACE_VERSION),
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index b9fbe6e..075598e 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -22,6 +22,30 @@
 
 	  Say Y here to compile support for SCO over HCI USB.
 
+config BT_HCIBTUSB
+	tristate "HCI USB driver (alternate version)"
+	depends on USB && EXPERIMENTAL && BT_HCIUSB=n
+	help
+	  Bluetooth HCI USB driver.
+	  This driver is required if you want to use Bluetooth devices with
+	  USB interface.
+
+          This driver is still experimental and has no SCO support.
+
+	  Say Y here to compile support for Bluetooth USB devices into the
+	  kernel or say M to compile it as module (btusb).
+
+config BT_HCIBTSDIO
+	tristate "HCI SDIO driver"
+	depends on MMC
+	help
+	  Bluetooth HCI SDIO driver.
+	  This driver is required if you want to use Bluetooth device with
+	  SDIO interface.
+
+	  Say Y here to compile support for Bluetooth SDIO devices into the
+	  kernel or say M to compile it as module (btsdio).
+
 config BT_HCIUART
 	tristate "HCI UART driver"
 	help
@@ -55,6 +79,17 @@
 
 	  Say Y here to compile support for HCI BCSP protocol.
 
+config BT_HCIUART_LL
+	bool "HCILL protocol support"
+	depends on BT_HCIUART
+	help
+	  HCILL (HCI Low Level) is a serial protocol for communication
+	  between Bluetooth device and host. This protocol is required for
+	  serial Bluetooth devices that are based on Texas Instruments'
+	  BRF chips.
+
+	  Say Y here to compile support for HCILL protocol.
+
 config BT_HCIBCM203X
 	tristate "HCI BCM203x USB driver"
 	depends on USB
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 08c10e1..77444af 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -13,7 +13,11 @@
 obj-$(CONFIG_BT_HCIBLUECARD)	+= bluecard_cs.o
 obj-$(CONFIG_BT_HCIBTUART)	+= btuart_cs.o
 
+obj-$(CONFIG_BT_HCIBTUSB)	+= btusb.o
+obj-$(CONFIG_BT_HCIBTSDIO)	+= btsdio.o
+
 hci_uart-y				:= hci_ldisc.o
 hci_uart-$(CONFIG_BT_HCIUART_H4)	+= hci_h4.o
 hci_uart-$(CONFIG_BT_HCIUART_BCSP)	+= hci_bcsp.o
+hci_uart-$(CONFIG_BT_HCIUART_LL)	+= hci_ll.o
 hci_uart-objs				:= $(hci_uart-y)
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 851de4d..bcf5792 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -503,10 +503,7 @@
 	unsigned int iobase;
 	unsigned char reg;
 
-	if (!info || !info->hdev) {
-		BT_ERR("Call of irq %d for unknown device", irq);
-		return IRQ_NONE;
-	}
+	BUG_ON(!info->hdev);
 
 	if (!test_bit(CARD_READY, &(info->hw_state)))
 		return IRQ_HANDLED;
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index e8ebd5d..1375b53 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -2,7 +2,7 @@
  *
  *  Digianswer Bluetooth USB driver
  *
- *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -21,13 +21,14 @@
  *
  */
 
-#include <linux/module.h>
-
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/sched.h>
 #include <linux/errno.h>
+#include <linux/skbuff.h>
 
 #include <linux/usb.h>
 
@@ -39,7 +40,7 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "0.8"
+#define VERSION "0.9"
 
 static int ignore = 0;
 
@@ -52,393 +53,285 @@
 
 MODULE_DEVICE_TABLE(usb, bpa10x_table);
 
-#define BPA10X_CMD_EP		0x00
-#define BPA10X_EVT_EP		0x81
-#define BPA10X_TX_EP		0x02
-#define BPA10X_RX_EP		0x82
-
-#define BPA10X_CMD_BUF_SIZE	252
-#define BPA10X_EVT_BUF_SIZE	16
-#define BPA10X_TX_BUF_SIZE	384
-#define BPA10X_RX_BUF_SIZE	384
-
 struct bpa10x_data {
-	struct hci_dev		*hdev;
-	struct usb_device	*udev;
+	struct hci_dev    *hdev;
+	struct usb_device *udev;
 
-	rwlock_t		lock;
+	struct usb_anchor tx_anchor;
+	struct usb_anchor rx_anchor;
 
-	struct sk_buff_head	cmd_queue;
-	struct urb		*cmd_urb;
-	struct urb		*evt_urb;
-	struct sk_buff		*evt_skb;
-	unsigned int		evt_len;
-
-	struct sk_buff_head	tx_queue;
-	struct urb		*tx_urb;
-	struct urb		*rx_urb;
+	struct sk_buff *rx_skb[2];
 };
 
-#define HCI_VENDOR_HDR_SIZE	5
+#define HCI_VENDOR_HDR_SIZE 5
 
 struct hci_vendor_hdr {
-	__u8	type;
-	__le16	snum;
-	__le16	dlen;
+	__u8    type;
+	__le16  snum;
+	__le16  dlen;
 } __attribute__ ((packed));
 
-static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count)
+static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
 {
-	struct hci_acl_hdr *ah;
-	struct hci_sco_hdr *sh;
-	struct hci_vendor_hdr *vh;
-	struct sk_buff *skb;
-	int len;
+	struct bpa10x_data *data = hdev->driver_data;
+
+	BT_DBG("%s queue %d buffer %p count %d", hdev->name,
+							queue, buf, count);
+
+	if (queue < 0 || queue > 1)
+		return -EILSEQ;
+
+	hdev->stat.byte_rx += count;
 
 	while (count) {
-		switch (*buf++) {
-		case HCI_ACLDATA_PKT:
-			ah = (struct hci_acl_hdr *) buf;
-			len = HCI_ACL_HDR_SIZE + __le16_to_cpu(ah->dlen);
-			skb = bt_skb_alloc(len, GFP_ATOMIC);
-			if (skb) {
-				memcpy(skb_put(skb, len), buf, len);
-				skb->dev = (void *) data->hdev;
-				bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
-				hci_recv_frame(skb);
-			}
-			break;
+		struct sk_buff *skb = data->rx_skb[queue];
+		struct { __u8 type; int expect; } *scb;
+		int type, len = 0;
 
-		case HCI_SCODATA_PKT:
-			sh = (struct hci_sco_hdr *) buf;
-			len = HCI_SCO_HDR_SIZE + sh->dlen;
-			skb = bt_skb_alloc(len, GFP_ATOMIC);
-			if (skb) {
-				memcpy(skb_put(skb, len), buf, len);
-				skb->dev = (void *) data->hdev;
-				bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
-				hci_recv_frame(skb);
-			}
-			break;
-
-		case HCI_VENDOR_PKT:
-			vh = (struct hci_vendor_hdr *) buf;
-			len = HCI_VENDOR_HDR_SIZE + __le16_to_cpu(vh->dlen);
-			skb = bt_skb_alloc(len, GFP_ATOMIC);
-			if (skb) {
-				memcpy(skb_put(skb, len), buf, len);
-				skb->dev = (void *) data->hdev;
-				bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
-				hci_recv_frame(skb);
-			}
-			break;
-
-		default:
-			len = count - 1;
-			break;
-		}
-
-		buf   += len;
-		count -= (len + 1);
-	}
-}
-
-static int bpa10x_recv_event(struct bpa10x_data *data, unsigned char *buf, int size)
-{
-	BT_DBG("data %p buf %p size %d", data, buf, size);
-
-	if (data->evt_skb) {
-		struct sk_buff *skb = data->evt_skb;
-
-		memcpy(skb_put(skb, size), buf, size);
-
-		if (skb->len == data->evt_len) {
-			data->evt_skb = NULL;
-			data->evt_len = 0;
-			hci_recv_frame(skb);
-		}
-	} else {
-		struct sk_buff *skb;
-		struct hci_event_hdr *hdr;
-		unsigned char pkt_type;
-		int pkt_len = 0;
-
-		if (size < HCI_EVENT_HDR_SIZE + 1) {
-			BT_ERR("%s event packet block with size %d is too short",
-							data->hdev->name, size);
-			return -EILSEQ;
-		}
-
-		pkt_type = *buf++;
-		size--;
-
-		if (pkt_type != HCI_EVENT_PKT) {
-			BT_ERR("%s unexpected event packet start byte 0x%02x",
-							data->hdev->name, pkt_type);
-			return -EPROTO;
-		}
-
-		hdr = (struct hci_event_hdr *) buf;
-		pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
-
-		skb = bt_skb_alloc(pkt_len, GFP_ATOMIC);
 		if (!skb) {
-			BT_ERR("%s no memory for new event packet",
-							data->hdev->name);
-			return -ENOMEM;
-		}
+			/* Start of the frame */
 
-		skb->dev = (void *) data->hdev;
-		bt_cb(skb)->pkt_type = pkt_type;
+			type = *((__u8 *) buf);
+			count--; buf++;
 
-		memcpy(skb_put(skb, size), buf, size);
+			switch (type) {
+			case HCI_EVENT_PKT:
+				if (count >= HCI_EVENT_HDR_SIZE) {
+					struct hci_event_hdr *h = buf;
+					len = HCI_EVENT_HDR_SIZE + h->plen;
+				} else
+					return -EILSEQ;
+				break;
 
-		if (pkt_len == size) {
-			hci_recv_frame(skb);
+			case HCI_ACLDATA_PKT:
+				if (count >= HCI_ACL_HDR_SIZE) {
+					struct hci_acl_hdr *h = buf;
+					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 = buf;
+					len = HCI_SCO_HDR_SIZE + h->dlen;
+				} else
+					return -EILSEQ;
+				break;
+
+			case HCI_VENDOR_PKT:
+				if (count >= HCI_VENDOR_HDR_SIZE) {
+					struct hci_vendor_hdr *h = buf;
+					len = HCI_VENDOR_HDR_SIZE +
+							__le16_to_cpu(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;
+
+			data->rx_skb[queue] = skb;
+
+			scb = (void *) skb->cb;
+			scb->type = type;
+			scb->expect = len;
 		} else {
-			data->evt_skb = skb;
-			data->evt_len = pkt_len;
+			/* Continuation */
+
+			scb = (void *) skb->cb;
+			len = scb->expect;
 		}
+
+		len = min(len, count);
+
+		memcpy(skb_put(skb, len), buf, len);
+
+		scb->expect -= len;
+
+		if (scb->expect == 0) {
+			/* Complete frame */
+
+			data->rx_skb[queue] = NULL;
+
+			bt_cb(skb)->pkt_type = scb->type;
+			hci_recv_frame(skb);
+		}
+
+		count -= len; buf += len;
 	}
 
 	return 0;
 }
 
-static void bpa10x_wakeup(struct bpa10x_data *data)
+static void bpa10x_tx_complete(struct urb *urb)
 {
-	struct urb *urb;
-	struct sk_buff *skb;
+	struct sk_buff *skb = urb->context;
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+
+	BT_DBG("%s urb %p status %d count %d", hdev->name,
+					urb, urb->status, urb->actual_length);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		goto done;
+
+	if (!urb->status)
+		hdev->stat.byte_tx += urb->transfer_buffer_length;
+	else
+		hdev->stat.err_tx++;
+
+done:
+	kfree(urb->setup_packet);
+
+	kfree_skb(skb);
+}
+
+static void bpa10x_rx_complete(struct urb *urb)
+{
+	struct hci_dev *hdev = urb->context;
+	struct bpa10x_data *data = hdev->driver_data;
 	int err;
 
-	BT_DBG("data %p", data);
+	BT_DBG("%s urb %p status %d count %d", hdev->name,
+					urb, urb->status, urb->actual_length);
 
-	urb = data->cmd_urb;
-	if (urb->status == -EINPROGRESS)
-		skb = NULL;
-	else
-		skb = skb_dequeue(&data->cmd_queue);
-
-	if (skb) {
-		struct usb_ctrlrequest *cr;
-
-		if (skb->len > BPA10X_CMD_BUF_SIZE) {
-			BT_ERR("%s command packet with size %d is too big",
-							data->hdev->name, skb->len);
-			kfree_skb(skb);
-			return;
-		}
-
-		cr = (struct usb_ctrlrequest *) urb->setup_packet;
-		cr->wLength = __cpu_to_le16(skb->len);
-
-		skb_copy_from_linear_data(skb, urb->transfer_buffer, skb->len);
-		urb->transfer_buffer_length = skb->len;
-
-		err = usb_submit_urb(urb, GFP_ATOMIC);
-		if (err < 0 && err != -ENODEV) {
-			BT_ERR("%s submit failed for command urb %p with error %d",
-							data->hdev->name, urb, err);
-			skb_queue_head(&data->cmd_queue, skb);
-		} else
-			kfree_skb(skb);
-	}
-
-	urb = data->tx_urb;
-	if (urb->status == -EINPROGRESS)
-		skb = NULL;
-	else
-		skb = skb_dequeue(&data->tx_queue);
-
-	if (skb) {
-		skb_copy_from_linear_data(skb, urb->transfer_buffer, skb->len);
-		urb->transfer_buffer_length = skb->len;
-
-		err = usb_submit_urb(urb, GFP_ATOMIC);
-		if (err < 0 && err != -ENODEV) {
-			BT_ERR("%s submit failed for command urb %p with error %d",
-							data->hdev->name, urb, err);
-			skb_queue_head(&data->tx_queue, skb);
-		} else
-			kfree_skb(skb);
-	}
-}
-
-static void bpa10x_complete(struct urb *urb)
-{
-	struct bpa10x_data *data = urb->context;
-	unsigned char *buf = urb->transfer_buffer;
-	int err, count = urb->actual_length;
-
-	BT_DBG("data %p urb %p buf %p count %d", data, urb, buf, count);
-
-	read_lock(&data->lock);
-
-	if (!test_bit(HCI_RUNNING, &data->hdev->flags))
-		goto unlock;
-
-	if (urb->status < 0 || !count)
-		goto resubmit;
-
-	if (usb_pipein(urb->pipe)) {
-		data->hdev->stat.byte_rx += count;
-
-		if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)
-			bpa10x_recv_event(data, buf, count);
-
-		if (usb_pipetype(urb->pipe) == PIPE_BULK)
-			bpa10x_recv_bulk(data, buf, count);
-	} else {
-		data->hdev->stat.byte_tx += count;
-
-		bpa10x_wakeup(data);
-	}
-
-resubmit:
-	if (usb_pipein(urb->pipe)) {
-		err = usb_submit_urb(urb, GFP_ATOMIC);
-		if (err < 0 && err != -ENODEV) {
-			BT_ERR("%s urb %p type %d resubmit status %d",
-				data->hdev->name, urb, usb_pipetype(urb->pipe), err);
-		}
-	}
-
-unlock:
-	read_unlock(&data->lock);
-}
-
-static inline struct urb *bpa10x_alloc_urb(struct usb_device *udev, unsigned int pipe,
-					size_t size, gfp_t flags, void *data)
-{
-	struct urb *urb;
-	struct usb_ctrlrequest *cr;
-	unsigned char *buf;
-
-	BT_DBG("udev %p data %p", udev, data);
-
-	urb = usb_alloc_urb(0, flags);
-	if (!urb)
-		return NULL;
-
-	buf = kmalloc(size, flags);
-	if (!buf) {
-		usb_free_urb(urb);
-		return NULL;
-	}
-
-	switch (usb_pipetype(pipe)) {
-	case PIPE_CONTROL:
-		cr = kmalloc(sizeof(*cr), flags);
-		if (!cr) {
-			kfree(buf);
-			usb_free_urb(urb);
-			return NULL;
-		}
-
-		cr->bRequestType = USB_TYPE_VENDOR;
-		cr->bRequest     = 0;
-		cr->wIndex       = 0;
-		cr->wValue       = 0;
-		cr->wLength      = __cpu_to_le16(0);
-
-		usb_fill_control_urb(urb, udev, pipe, (void *) cr, buf, 0, bpa10x_complete, data);
-		break;
-
-	case PIPE_INTERRUPT:
-		usb_fill_int_urb(urb, udev, pipe, buf, size, bpa10x_complete, data, 1);
-		break;
-
-	case PIPE_BULK:
-		usb_fill_bulk_urb(urb, udev, pipe, buf, size, bpa10x_complete, data);
-		break;
-
-	default:
-		kfree(buf);
-		usb_free_urb(urb);
-		return NULL;
-	}
-
-	return urb;
-}
-
-static inline void bpa10x_free_urb(struct urb *urb)
-{
-	BT_DBG("urb %p", urb);
-
-	if (!urb)
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return;
 
-	kfree(urb->setup_packet);
-	kfree(urb->transfer_buffer);
+	if (urb->status == 0) {
+		if (bpa10x_recv(hdev, usb_pipebulk(urb->pipe),
+						urb->transfer_buffer,
+						urb->actual_length) < 0) {
+			BT_ERR("%s corrupted event packet", hdev->name);
+			hdev->stat.err_rx++;
+		}
+	}
+
+	usb_anchor_urb(urb, &data->rx_anchor);
+
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err < 0) {
+		BT_ERR("%s urb %p failed to resubmit (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+	}
+}
+
+static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev)
+{
+	struct bpa10x_data *data = hdev->driver_data;
+	struct urb *urb;
+	unsigned char *buf;
+	unsigned int pipe;
+	int err, size = 16;
+
+	BT_DBG("%s", hdev->name);
+
+	urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!urb)
+		return -ENOMEM;
+
+	buf = kmalloc(size, GFP_KERNEL);
+	if (!buf) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	pipe = usb_rcvintpipe(data->udev, 0x81);
+
+	usb_fill_int_urb(urb, data->udev, pipe, buf, size,
+						bpa10x_rx_complete, hdev, 1);
+
+	urb->transfer_flags |= URB_FREE_BUFFER;
+
+	usb_anchor_urb(urb, &data->rx_anchor);
+
+	err = usb_submit_urb(urb, GFP_KERNEL);
+	if (err < 0) {
+		BT_ERR("%s urb %p submission failed (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+		kfree(buf);
+	}
 
 	usb_free_urb(urb);
+
+	return err;
+}
+
+static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev)
+{
+	struct bpa10x_data *data = hdev->driver_data;
+	struct urb *urb;
+	unsigned char *buf;
+	unsigned int pipe;
+	int err, size = 64;
+
+	BT_DBG("%s", hdev->name);
+
+	urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!urb)
+		return -ENOMEM;
+
+	buf = kmalloc(size, GFP_KERNEL);
+	if (!buf) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	pipe = usb_rcvbulkpipe(data->udev, 0x82);
+
+	usb_fill_bulk_urb(urb, data->udev, pipe,
+					buf, size, bpa10x_rx_complete, hdev);
+
+	urb->transfer_flags |= URB_FREE_BUFFER;
+
+	usb_anchor_urb(urb, &data->rx_anchor);
+
+	err = usb_submit_urb(urb, GFP_KERNEL);
+	if (err < 0) {
+		BT_ERR("%s urb %p submission failed (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+		kfree(buf);
+	}
+
+	usb_free_urb(urb);
+
+	return err;
 }
 
 static int bpa10x_open(struct hci_dev *hdev)
 {
 	struct bpa10x_data *data = hdev->driver_data;
-	struct usb_device *udev = data->udev;
-	unsigned long flags;
 	int err;
 
-	BT_DBG("hdev %p data %p", hdev, data);
+	BT_DBG("%s", hdev->name);
 
 	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
 		return 0;
 
-	data->cmd_urb = bpa10x_alloc_urb(udev, usb_sndctrlpipe(udev, BPA10X_CMD_EP),
-					BPA10X_CMD_BUF_SIZE, GFP_KERNEL, data);
-	if (!data->cmd_urb) {
-		err = -ENOMEM;
-		goto done;
-	}
-
-	data->evt_urb = bpa10x_alloc_urb(udev, usb_rcvintpipe(udev, BPA10X_EVT_EP),
-					BPA10X_EVT_BUF_SIZE, GFP_KERNEL, data);
-	if (!data->evt_urb) {
-		bpa10x_free_urb(data->cmd_urb);
-		err = -ENOMEM;
-		goto done;
-	}
-
-	data->rx_urb = bpa10x_alloc_urb(udev, usb_rcvbulkpipe(udev, BPA10X_RX_EP),
-					BPA10X_RX_BUF_SIZE, GFP_KERNEL, data);
-	if (!data->rx_urb) {
-		bpa10x_free_urb(data->evt_urb);
-		bpa10x_free_urb(data->cmd_urb);
-		err = -ENOMEM;
-		goto done;
-	}
-
-	data->tx_urb = bpa10x_alloc_urb(udev, usb_sndbulkpipe(udev, BPA10X_TX_EP),
-					BPA10X_TX_BUF_SIZE, GFP_KERNEL, data);
-	if (!data->rx_urb) {
-		bpa10x_free_urb(data->rx_urb);
-		bpa10x_free_urb(data->evt_urb);
-		bpa10x_free_urb(data->cmd_urb);
-		err = -ENOMEM;
-		goto done;
-	}
-
-	write_lock_irqsave(&data->lock, flags);
-
-	err = usb_submit_urb(data->evt_urb, GFP_ATOMIC);
-	if (err < 0) {
-		BT_ERR("%s submit failed for event urb %p with error %d",
-					data->hdev->name, data->evt_urb, err);
-	} else {
-		err = usb_submit_urb(data->rx_urb, GFP_ATOMIC);
-		if (err < 0) {
-			BT_ERR("%s submit failed for rx urb %p with error %d",
-					data->hdev->name, data->evt_urb, err);
-			usb_kill_urb(data->evt_urb);
-		}
-	}
-
-	write_unlock_irqrestore(&data->lock, flags);
-
-done:
+	err = bpa10x_submit_intr_urb(hdev);
 	if (err < 0)
-		clear_bit(HCI_RUNNING, &hdev->flags);
+		goto error;
+
+	err = bpa10x_submit_bulk_urb(hdev);
+	if (err < 0)
+		goto error;
+
+	return 0;
+
+error:
+	usb_kill_anchored_urbs(&data->rx_anchor);
+
+	clear_bit(HCI_RUNNING, &hdev->flags);
 
 	return err;
 }
@@ -446,27 +339,13 @@
 static int bpa10x_close(struct hci_dev *hdev)
 {
 	struct bpa10x_data *data = hdev->driver_data;
-	unsigned long flags;
 
-	BT_DBG("hdev %p data %p", hdev, data);
+	BT_DBG("%s", hdev->name);
 
 	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
 		return 0;
 
-	write_lock_irqsave(&data->lock, flags);
-
-	skb_queue_purge(&data->cmd_queue);
-	usb_kill_urb(data->cmd_urb);
-	usb_kill_urb(data->evt_urb);
-	usb_kill_urb(data->rx_urb);
-	usb_kill_urb(data->tx_urb);
-
-	write_unlock_irqrestore(&data->lock, flags);
-
-	bpa10x_free_urb(data->cmd_urb);
-	bpa10x_free_urb(data->evt_urb);
-	bpa10x_free_urb(data->rx_urb);
-	bpa10x_free_urb(data->tx_urb);
+	usb_kill_anchored_urbs(&data->rx_anchor);
 
 	return 0;
 }
@@ -475,9 +354,9 @@
 {
 	struct bpa10x_data *data = hdev->driver_data;
 
-	BT_DBG("hdev %p data %p", hdev, data);
+	BT_DBG("%s", hdev->name);
 
-	skb_queue_purge(&data->cmd_queue);
+	usb_kill_anchored_urbs(&data->tx_anchor);
 
 	return 0;
 }
@@ -485,45 +364,78 @@
 static int bpa10x_send_frame(struct sk_buff *skb)
 {
 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-	struct bpa10x_data *data;
+	struct bpa10x_data *data = hdev->driver_data;
+	struct usb_ctrlrequest *dr;
+	struct urb *urb;
+	unsigned int pipe;
+	int err;
 
-	BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
-
-	if (!hdev) {
-		BT_ERR("Frame for unknown HCI device");
-		return -ENODEV;
-	}
+	BT_DBG("%s", hdev->name);
 
 	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return -EBUSY;
 
-	data = hdev->driver_data;
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!urb)
+		return -ENOMEM;
 
 	/* Prepend skb with frame type */
-	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
+	*skb_push(skb, 1) = bt_cb(skb)->pkt_type;
 
 	switch (bt_cb(skb)->pkt_type) {
 	case HCI_COMMAND_PKT:
+		dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
+		if (!dr) {
+			usb_free_urb(urb);
+			return -ENOMEM;
+		}
+
+		dr->bRequestType = USB_TYPE_VENDOR;
+		dr->bRequest     = 0;
+		dr->wIndex       = 0;
+		dr->wValue       = 0;
+		dr->wLength      = __cpu_to_le16(skb->len);
+
+		pipe = usb_sndctrlpipe(data->udev, 0x00);
+
+		usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
+				skb->data, skb->len, bpa10x_tx_complete, skb);
+
 		hdev->stat.cmd_tx++;
-		skb_queue_tail(&data->cmd_queue, skb);
 		break;
 
 	case HCI_ACLDATA_PKT:
+		pipe = usb_sndbulkpipe(data->udev, 0x02);
+
+		usb_fill_bulk_urb(urb, data->udev, pipe,
+				skb->data, skb->len, bpa10x_tx_complete, skb);
+
 		hdev->stat.acl_tx++;
-		skb_queue_tail(&data->tx_queue, skb);
 		break;
 
 	case HCI_SCODATA_PKT:
+		pipe = usb_sndbulkpipe(data->udev, 0x02);
+
+		usb_fill_bulk_urb(urb, data->udev, pipe,
+				skb->data, skb->len, bpa10x_tx_complete, skb);
+
 		hdev->stat.sco_tx++;
-		skb_queue_tail(&data->tx_queue, skb);
 		break;
-	};
 
-	read_lock(&data->lock);
+	default:
+		return -EILSEQ;
+	}
 
-	bpa10x_wakeup(data);
+	usb_anchor_urb(urb, &data->tx_anchor);
 
-	read_unlock(&data->lock);
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err < 0) {
+		BT_ERR("%s urb %p submission failed", hdev->name, urb);
+		kfree(urb->setup_packet);
+		usb_unanchor_urb(urb);
+	}
+
+	usb_free_urb(urb);
 
 	return 0;
 }
@@ -532,16 +444,17 @@
 {
 	struct bpa10x_data *data = hdev->driver_data;
 
-	BT_DBG("hdev %p data %p", hdev, data);
+	BT_DBG("%s", hdev->name);
 
+	kfree(data->rx_skb[0]);
+	kfree(data->rx_skb[1]);
 	kfree(data);
 }
 
 static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
-	struct usb_device *udev = interface_to_usbdev(intf);
-	struct hci_dev *hdev;
 	struct bpa10x_data *data;
+	struct hci_dev *hdev;
 	int err;
 
 	BT_DBG("intf %p id %p", intf, id);
@@ -549,48 +462,43 @@
 	if (ignore)
 		return -ENODEV;
 
-	if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
+	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
 		return -ENODEV;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data) {
-		BT_ERR("Can't allocate data structure");
+	if (!data)
 		return -ENOMEM;
-	}
 
-	data->udev = udev;
+	data->udev = interface_to_usbdev(intf);
 
-	rwlock_init(&data->lock);
-
-	skb_queue_head_init(&data->cmd_queue);
-	skb_queue_head_init(&data->tx_queue);
+	init_usb_anchor(&data->tx_anchor);
+	init_usb_anchor(&data->rx_anchor);
 
 	hdev = hci_alloc_dev();
 	if (!hdev) {
-		BT_ERR("Can't allocate HCI device");
 		kfree(data);
 		return -ENOMEM;
 	}
 
-	data->hdev = hdev;
-
 	hdev->type = HCI_USB;
 	hdev->driver_data = data;
+
+	data->hdev = hdev;
+
 	SET_HCIDEV_DEV(hdev, &intf->dev);
 
-	hdev->open	= bpa10x_open;
-	hdev->close	= bpa10x_close;
-	hdev->flush	= bpa10x_flush;
-	hdev->send	= bpa10x_send_frame;
-	hdev->destruct	= bpa10x_destruct;
+	hdev->open     = bpa10x_open;
+	hdev->close    = bpa10x_close;
+	hdev->flush    = bpa10x_flush;
+	hdev->send     = bpa10x_send_frame;
+	hdev->destruct = bpa10x_destruct;
 
 	hdev->owner = THIS_MODULE;
 
 	err = hci_register_dev(hdev);
 	if (err < 0) {
-		BT_ERR("Can't register HCI device");
-		kfree(data);
 		hci_free_dev(hdev);
+		kfree(data);
 		return err;
 	}
 
@@ -602,19 +510,17 @@
 static void bpa10x_disconnect(struct usb_interface *intf)
 {
 	struct bpa10x_data *data = usb_get_intfdata(intf);
-	struct hci_dev *hdev = data->hdev;
 
 	BT_DBG("intf %p", intf);
 
-	if (!hdev)
+	if (!data)
 		return;
 
 	usb_set_intfdata(intf, NULL);
 
-	if (hci_unregister_dev(hdev) < 0)
-		BT_ERR("Can't unregister HCI device %s", hdev->name);
+	hci_unregister_dev(data->hdev);
 
-	hci_free_dev(hdev);
+	hci_free_dev(data->hdev);
 }
 
 static struct usb_driver bpa10x_driver = {
@@ -626,15 +532,9 @@
 
 static int __init bpa10x_init(void)
 {
-	int err;
-
 	BT_INFO("Digianswer Bluetooth USB driver ver %s", VERSION);
 
-	err = usb_register(&bpa10x_driver);
-	if (err < 0)
-		BT_ERR("Failed to register USB driver");
-
-	return err;
+	return usb_register(&bpa10x_driver);
 }
 
 static void __exit bpa10x_exit(void)
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 3951607..a18f9b8 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -344,10 +344,7 @@
 	unsigned int iobase;
 	int iir;
 
-	if (!info || !info->hdev) {
-		BT_ERR("Call of irq %d for unknown device", irq);
-		return IRQ_NONE;
-	}
+	BUG_ON(!info->hdev);
 
 	iobase = info->p_dev->io.BasePort1;
 
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
new file mode 100644
index 0000000..b786f61
--- /dev/null
+++ b/drivers/bluetooth/btsdio.c
@@ -0,0 +1,406 @@
+/*
+ *
+ *  Generic Bluetooth SDIO driver
+ *
+ *  Copyright (C) 2007  Cambridge Silicon Radio Ltd.
+ *  Copyright (C) 2007  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio_func.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#ifndef CONFIG_BT_HCIBTSDIO_DEBUG
+#undef  BT_DBG
+#define BT_DBG(D...)
+#endif
+
+#define VERSION "0.1"
+
+static const struct sdio_device_id btsdio_table[] = {
+	/* Generic Bluetooth Type-A SDIO device */
+	{ SDIO_DEVICE_CLASS(SDIO_CLASS_BT_A) },
+
+	/* Generic Bluetooth Type-B SDIO device */
+	{ SDIO_DEVICE_CLASS(SDIO_CLASS_BT_B) },
+
+	{ }	/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(sdio, btsdio_table);
+
+struct btsdio_data {
+	struct hci_dev   *hdev;
+	struct sdio_func *func;
+
+	struct work_struct work;
+
+	struct sk_buff_head txq;
+};
+
+#define REG_RDAT     0x00	/* Receiver Data */
+#define REG_TDAT     0x00	/* Transmitter Data */
+#define REG_PC_RRT   0x10	/* Read Packet Control */
+#define REG_PC_WRT   0x11	/* Write Packet Control */
+#define REG_RTC_STAT 0x12	/* Retry Control Status */
+#define REG_RTC_SET  0x12	/* Retry Control Set */
+#define REG_INTRD    0x13	/* Interrupt Indication */
+#define REG_CL_INTRD 0x13	/* Interrupt Clear */
+#define REG_EN_INTRD 0x14	/* Interrupt Enable */
+#define REG_MD_STAT  0x20	/* Bluetooth Mode Status */
+
+static int btsdio_tx_packet(struct btsdio_data *data, struct sk_buff *skb)
+{
+	int err;
+
+	BT_DBG("%s", data->hdev->name);
+
+	/* Prepend Type-A header */
+	skb_push(skb, 4);
+	skb->data[0] = (skb->len & 0x0000ff);
+	skb->data[1] = (skb->len & 0x00ff00) >> 8;
+	skb->data[2] = (skb->len & 0xff0000) >> 16;
+	skb->data[3] = bt_cb(skb)->pkt_type;
+
+	err = sdio_writesb(data->func, REG_TDAT, skb->data, skb->len);
+	if (err < 0) {
+		sdio_writeb(data->func, 0x01, REG_PC_WRT, NULL);
+		return err;
+	}
+
+	data->hdev->stat.byte_tx += skb->len;
+
+	kfree_skb(skb);
+
+	return 0;
+}
+
+static void btsdio_work(struct work_struct *work)
+{
+	struct btsdio_data *data = container_of(work, struct btsdio_data, work);
+	struct sk_buff *skb;
+	int err;
+
+	BT_DBG("%s", data->hdev->name);
+
+	sdio_claim_host(data->func);
+
+	while ((skb = skb_dequeue(&data->txq))) {
+		err = btsdio_tx_packet(data, skb);
+		if (err < 0) {
+			data->hdev->stat.err_tx++;
+			skb_queue_head(&data->txq, skb);
+			break;
+		}
+	}
+
+	sdio_release_host(data->func);
+}
+
+static int btsdio_rx_packet(struct btsdio_data *data)
+{
+	u8 hdr[4] __attribute__ ((aligned(4)));
+	struct sk_buff *skb;
+	int err, len;
+
+	BT_DBG("%s", data->hdev->name);
+
+	err = sdio_readsb(data->func, hdr, REG_RDAT, 4);
+	if (err < 0)
+		return err;
+
+	len = hdr[0] | (hdr[1] << 8) | (hdr[2] << 16);
+	if (len < 4 || len > 65543)
+		return -EILSEQ;
+
+	skb = bt_skb_alloc(len - 4, GFP_KERNEL);
+	if (!skb) {
+		/* Out of memory. Prepare a read retry and just
+		 * return with the expectation that the next time
+		 * we're called we'll have more memory. */
+		return -ENOMEM;
+	}
+
+	skb_put(skb, len - 4);
+
+	err = sdio_readsb(data->func, skb->data, REG_RDAT, len - 4);
+	if (err < 0) {
+		kfree(skb);
+		return err;
+	}
+
+	data->hdev->stat.byte_rx += len;
+
+	skb->dev = (void *) data->hdev;
+	bt_cb(skb)->pkt_type = hdr[3];
+
+	err = hci_recv_frame(skb);
+	if (err < 0) {
+		kfree(skb);
+		return err;
+	}
+
+	sdio_writeb(data->func, 0x00, REG_PC_RRT, NULL);
+
+	return 0;
+}
+
+static void btsdio_interrupt(struct sdio_func *func)
+{
+	struct btsdio_data *data = sdio_get_drvdata(func);
+	int intrd;
+
+	BT_DBG("%s", data->hdev->name);
+
+	intrd = sdio_readb(func, REG_INTRD, NULL);
+	if (intrd & 0x01) {
+		sdio_writeb(func, 0x01, REG_CL_INTRD, NULL);
+
+		if (btsdio_rx_packet(data) < 0) {
+			data->hdev->stat.err_rx++;
+			sdio_writeb(data->func, 0x01, REG_PC_RRT, NULL);
+		}
+	}
+}
+
+static int btsdio_open(struct hci_dev *hdev)
+{
+	struct btsdio_data *data = hdev->driver_data;
+	int err;
+
+	BT_DBG("%s", hdev->name);
+
+	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
+
+	sdio_claim_host(data->func);
+
+	err = sdio_enable_func(data->func);
+	if (err < 0) {
+		clear_bit(HCI_RUNNING, &hdev->flags);
+		goto release;
+	}
+
+	err = sdio_claim_irq(data->func, btsdio_interrupt);
+	if (err < 0) {
+		sdio_disable_func(data->func);
+		clear_bit(HCI_RUNNING, &hdev->flags);
+		goto release;
+	}
+
+	if (data->func->class == SDIO_CLASS_BT_B)
+		sdio_writeb(data->func, 0x00, REG_MD_STAT, NULL);
+
+	sdio_writeb(data->func, 0x01, REG_EN_INTRD, NULL);
+
+release:
+	sdio_release_host(data->func);
+
+	return err;
+}
+
+static int btsdio_close(struct hci_dev *hdev)
+{
+	struct btsdio_data *data = hdev->driver_data;
+
+	BT_DBG("%s", hdev->name);
+
+	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
+
+	sdio_claim_host(data->func);
+
+	sdio_writeb(data->func, 0x00, REG_EN_INTRD, NULL);
+
+	sdio_release_irq(data->func);
+	sdio_disable_func(data->func);
+
+	sdio_release_host(data->func);
+
+	return 0;
+}
+
+static int btsdio_flush(struct hci_dev *hdev)
+{
+	struct btsdio_data *data = hdev->driver_data;
+
+	BT_DBG("%s", hdev->name);
+
+	skb_queue_purge(&data->txq);
+
+	return 0;
+}
+
+static int btsdio_send_frame(struct sk_buff *skb)
+{
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+	struct btsdio_data *data = hdev->driver_data;
+
+	BT_DBG("%s", hdev->name);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return -EBUSY;
+
+	switch (bt_cb(skb)->pkt_type) {
+	case HCI_COMMAND_PKT:
+		hdev->stat.cmd_tx++;
+		break;
+
+	case HCI_ACLDATA_PKT:
+		hdev->stat.acl_tx++;
+		break;
+
+	case HCI_SCODATA_PKT:
+		hdev->stat.sco_tx++;
+		break;
+
+	default:
+		return -EILSEQ;
+	}
+
+	skb_queue_tail(&data->txq, skb);
+
+	schedule_work(&data->work);
+
+	return 0;
+}
+
+static void btsdio_destruct(struct hci_dev *hdev)
+{
+	struct btsdio_data *data = hdev->driver_data;
+
+	BT_DBG("%s", hdev->name);
+
+	kfree(data);
+}
+
+static int btsdio_probe(struct sdio_func *func,
+				const struct sdio_device_id *id)
+{
+	struct btsdio_data *data;
+	struct hci_dev *hdev;
+	struct sdio_func_tuple *tuple = func->tuples;
+	int err;
+
+	BT_DBG("func %p id %p class 0x%04x", func, id, func->class);
+
+	while (tuple) {
+		BT_DBG("code 0x%x size %d", tuple->code, tuple->size);
+		tuple = tuple->next;
+	}
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->func = func;
+
+	INIT_WORK(&data->work, btsdio_work);
+
+	skb_queue_head_init(&data->txq);
+
+	hdev = hci_alloc_dev();
+	if (!hdev) {
+		kfree(data);
+		return -ENOMEM;
+	}
+
+	hdev->type = HCI_SDIO;
+	hdev->driver_data = data;
+
+	data->hdev = hdev;
+
+	SET_HCIDEV_DEV(hdev, &func->dev);
+
+	hdev->open     = btsdio_open;
+	hdev->close    = btsdio_close;
+	hdev->flush    = btsdio_flush;
+	hdev->send     = btsdio_send_frame;
+	hdev->destruct = btsdio_destruct;
+
+	hdev->owner = THIS_MODULE;
+
+	err = hci_register_dev(hdev);
+	if (err < 0) {
+		hci_free_dev(hdev);
+		kfree(data);
+		return err;
+	}
+
+	sdio_set_drvdata(func, data);
+
+	return 0;
+}
+
+static void btsdio_remove(struct sdio_func *func)
+{
+	struct btsdio_data *data = sdio_get_drvdata(func);
+	struct hci_dev *hdev;
+
+	BT_DBG("func %p", func);
+
+	if (!data)
+		return;
+
+	hdev = data->hdev;
+
+	sdio_set_drvdata(func, NULL);
+
+	hci_unregister_dev(hdev);
+
+	hci_free_dev(hdev);
+}
+
+static struct sdio_driver btsdio_driver = {
+	.name		= "btsdio",
+	.probe		= btsdio_probe,
+	.remove		= btsdio_remove,
+	.id_table	= btsdio_table,
+};
+
+static int __init btsdio_init(void)
+{
+	BT_INFO("Generic Bluetooth SDIO driver ver %s", VERSION);
+
+	return sdio_register_driver(&btsdio_driver);
+}
+
+static void __exit btsdio_exit(void)
+{
+	sdio_unregister_driver(&btsdio_driver);
+}
+
+module_init(btsdio_init);
+module_exit(btsdio_exit);
+
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
+MODULE_DESCRIPTION("Generic Bluetooth SDIO driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index d7d2ea0..08f48d5 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -294,10 +294,7 @@
 	int boguscount = 0;
 	int iir, lsr;
 
-	if (!info || !info->hdev) {
-		BT_ERR("Call of irq %d for unknown device", irq);
-		return IRQ_NONE;
-	}
+	BUG_ON(!info->hdev);
 
 	iobase = info->p_dev->io.BasePort1;
 
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
new file mode 100644
index 0000000..12e1089
--- /dev/null
+++ b/drivers/bluetooth/btusb.c
@@ -0,0 +1,564 @@
+/*
+ *
+ *  Generic Bluetooth USB driver
+ *
+ *  Copyright (C) 2005-2007  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+
+#include <linux/usb.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+//#define CONFIG_BT_HCIBTUSB_DEBUG
+#ifndef CONFIG_BT_HCIBTUSB_DEBUG
+#undef  BT_DBG
+#define BT_DBG(D...)
+#endif
+
+#define VERSION "0.1"
+
+static struct usb_device_id btusb_table[] = {
+	/* Generic Bluetooth USB device */
+	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
+
+	{ }	/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, btusb_table);
+
+static struct usb_device_id blacklist_table[] = {
+	{ }	/* Terminating entry */
+};
+
+#define BTUSB_INTR_RUNNING	0
+#define BTUSB_BULK_RUNNING	1
+
+struct btusb_data {
+	struct hci_dev       *hdev;
+	struct usb_device    *udev;
+
+	spinlock_t lock;
+
+	unsigned long flags;
+
+	struct work_struct work;
+
+	struct usb_anchor tx_anchor;
+	struct usb_anchor intr_anchor;
+	struct usb_anchor bulk_anchor;
+
+	struct usb_endpoint_descriptor *intr_ep;
+	struct usb_endpoint_descriptor *bulk_tx_ep;
+	struct usb_endpoint_descriptor *bulk_rx_ep;
+};
+
+static void btusb_intr_complete(struct urb *urb)
+{
+	struct hci_dev *hdev = urb->context;
+	struct btusb_data *data = hdev->driver_data;
+	int err;
+
+	BT_DBG("%s urb %p status %d count %d", hdev->name,
+					urb, urb->status, urb->actual_length);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return;
+
+	if (urb->status == 0) {
+		if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
+						urb->transfer_buffer,
+						urb->actual_length) < 0) {
+			BT_ERR("%s corrupted event packet", hdev->name);
+			hdev->stat.err_rx++;
+		}
+	}
+
+	if (!test_bit(BTUSB_INTR_RUNNING, &data->flags))
+		return;
+
+	usb_anchor_urb(urb, &data->intr_anchor);
+
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err < 0) {
+		BT_ERR("%s urb %p failed to resubmit (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+	}
+}
+
+static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
+{
+	struct btusb_data *data = hdev->driver_data;
+	struct urb *urb;
+	unsigned char *buf;
+	unsigned int pipe;
+	int err, size;
+
+	BT_DBG("%s", hdev->name);
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!urb)
+		return -ENOMEM;
+
+	size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
+
+	buf = kmalloc(size, GFP_ATOMIC);
+	if (!buf) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress);
+
+	usb_fill_int_urb(urb, data->udev, pipe, buf, size,
+						btusb_intr_complete, hdev,
+						data->intr_ep->bInterval);
+
+	urb->transfer_flags |= URB_FREE_BUFFER;
+
+	usb_anchor_urb(urb, &data->intr_anchor);
+
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err < 0) {
+		BT_ERR("%s urb %p submission failed (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+		kfree(buf);
+	}
+
+	usb_free_urb(urb);
+
+	return err;
+}
+
+static void btusb_bulk_complete(struct urb *urb)
+{
+	struct hci_dev *hdev = urb->context;
+	struct btusb_data *data = hdev->driver_data;
+	int err;
+
+	BT_DBG("%s urb %p status %d count %d", hdev->name,
+					urb, urb->status, urb->actual_length);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return;
+
+	if (urb->status == 0) {
+		if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
+						urb->transfer_buffer,
+						urb->actual_length) < 0) {
+			BT_ERR("%s corrupted ACL packet", hdev->name);
+			hdev->stat.err_rx++;
+		}
+	}
+
+	if (!test_bit(BTUSB_BULK_RUNNING, &data->flags))
+		return;
+
+	usb_anchor_urb(urb, &data->bulk_anchor);
+
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err < 0) {
+		BT_ERR("%s urb %p failed to resubmit (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+	}
+}
+
+static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
+{
+	struct btusb_data *data = hdev->driver_data;
+	struct urb *urb;
+	unsigned char *buf;
+	unsigned int pipe;
+	int err, size;
+
+	BT_DBG("%s", hdev->name);
+
+	urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!urb)
+		return -ENOMEM;
+
+	size = le16_to_cpu(data->bulk_rx_ep->wMaxPacketSize);
+
+	buf = kmalloc(size, GFP_KERNEL);
+	if (!buf) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress);
+
+	usb_fill_bulk_urb(urb, data->udev, pipe,
+					buf, size, btusb_bulk_complete, hdev);
+
+	urb->transfer_flags |= URB_FREE_BUFFER;
+
+	usb_anchor_urb(urb, &data->bulk_anchor);
+
+	err = usb_submit_urb(urb, GFP_KERNEL);
+	if (err < 0) {
+		BT_ERR("%s urb %p submission failed (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+		kfree(buf);
+	}
+
+	usb_free_urb(urb);
+
+	return err;
+}
+
+static void btusb_tx_complete(struct urb *urb)
+{
+	struct sk_buff *skb = urb->context;
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+
+	BT_DBG("%s urb %p status %d count %d", hdev->name,
+					urb, urb->status, urb->actual_length);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		goto done;
+
+	if (!urb->status)
+		hdev->stat.byte_tx += urb->transfer_buffer_length;
+	else
+		hdev->stat.err_tx++;
+
+done:
+	kfree(urb->setup_packet);
+
+	kfree_skb(skb);
+}
+
+static int btusb_open(struct hci_dev *hdev)
+{
+	struct btusb_data *data = hdev->driver_data;
+	int err;
+
+	BT_DBG("%s", hdev->name);
+
+	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
+
+	if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
+		return 0;
+
+	err = btusb_submit_intr_urb(hdev);
+	if (err < 0) {
+		clear_bit(BTUSB_INTR_RUNNING, &hdev->flags);
+		clear_bit(HCI_RUNNING, &hdev->flags);
+	}
+
+	return err;
+}
+
+static int btusb_close(struct hci_dev *hdev)
+{
+	struct btusb_data *data = hdev->driver_data;
+
+	BT_DBG("%s", hdev->name);
+
+	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
+
+	clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+	usb_kill_anchored_urbs(&data->bulk_anchor);
+
+	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
+	usb_kill_anchored_urbs(&data->intr_anchor);
+
+	return 0;
+}
+
+static int btusb_flush(struct hci_dev *hdev)
+{
+	struct btusb_data *data = hdev->driver_data;
+
+	BT_DBG("%s", hdev->name);
+
+	usb_kill_anchored_urbs(&data->tx_anchor);
+
+	return 0;
+}
+
+static int btusb_send_frame(struct sk_buff *skb)
+{
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+	struct btusb_data *data = hdev->driver_data;
+	struct usb_ctrlrequest *dr;
+	struct urb *urb;
+	unsigned int pipe;
+	int err;
+
+	BT_DBG("%s", hdev->name);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return -EBUSY;
+
+	switch (bt_cb(skb)->pkt_type) {
+	case HCI_COMMAND_PKT:
+		urb = usb_alloc_urb(0, GFP_ATOMIC);
+		if (!urb)
+			return -ENOMEM;
+
+		dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
+		if (!dr) {
+			usb_free_urb(urb);
+			return -ENOMEM;
+		}
+
+		dr->bRequestType = USB_TYPE_CLASS;
+		dr->bRequest     = 0;
+		dr->wIndex       = 0;
+		dr->wValue       = 0;
+		dr->wLength      = __cpu_to_le16(skb->len);
+
+		pipe = usb_sndctrlpipe(data->udev, 0x00);
+
+		usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
+				skb->data, skb->len, btusb_tx_complete, skb);
+
+		hdev->stat.cmd_tx++;
+		break;
+
+	case HCI_ACLDATA_PKT:
+		urb = usb_alloc_urb(0, GFP_ATOMIC);
+		if (!urb)
+			return -ENOMEM;
+
+		pipe = usb_sndbulkpipe(data->udev,
+					data->bulk_tx_ep->bEndpointAddress);
+
+		usb_fill_bulk_urb(urb, data->udev, pipe,
+				skb->data, skb->len, btusb_tx_complete, skb);
+
+		hdev->stat.acl_tx++;
+		break;
+
+	case HCI_SCODATA_PKT:
+		hdev->stat.sco_tx++;
+		kfree_skb(skb);
+		return 0;
+
+	default:
+		return -EILSEQ;
+	}
+
+	usb_anchor_urb(urb, &data->tx_anchor);
+
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err < 0) {
+		BT_ERR("%s urb %p submission failed", hdev->name, urb);
+		kfree(urb->setup_packet);
+		usb_unanchor_urb(urb);
+	}
+
+	usb_free_urb(urb);
+
+	return err;
+}
+
+static void btusb_destruct(struct hci_dev *hdev)
+{
+	struct btusb_data *data = hdev->driver_data;
+
+	BT_DBG("%s", hdev->name);
+
+	kfree(data);
+}
+
+static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
+{
+	struct btusb_data *data = hdev->driver_data;
+
+	BT_DBG("%s evt %d", hdev->name, evt);
+
+	if (evt == HCI_NOTIFY_CONN_ADD || evt == HCI_NOTIFY_CONN_DEL)
+		schedule_work(&data->work);
+}
+
+static void btusb_work(struct work_struct *work)
+{
+	struct btusb_data *data = container_of(work, struct btusb_data, work);
+	struct hci_dev *hdev = data->hdev;
+
+	if (hdev->conn_hash.acl_num == 0) {
+		clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+		usb_kill_anchored_urbs(&data->bulk_anchor);
+		return;
+	}
+
+	if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
+		if (btusb_submit_bulk_urb(hdev) < 0)
+			clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+		else
+			btusb_submit_bulk_urb(hdev);
+	}
+}
+
+static int btusb_probe(struct usb_interface *intf,
+				const struct usb_device_id *id)
+{
+	struct usb_endpoint_descriptor *ep_desc;
+	struct btusb_data *data;
+	struct hci_dev *hdev;
+	int i, err;
+
+	BT_DBG("intf %p id %p", intf, id);
+
+	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
+		return -ENODEV;
+
+	if (!id->driver_info) {
+		const struct usb_device_id *match;
+		match = usb_match_id(intf, blacklist_table);
+		if (match)
+			id = match;
+	}
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
+		ep_desc = &intf->cur_altsetting->endpoint[i].desc;
+
+		if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
+			data->intr_ep = ep_desc;
+			continue;
+		}
+
+		if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
+			data->bulk_tx_ep = ep_desc;
+			continue;
+		}
+
+		if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
+			data->bulk_rx_ep = ep_desc;
+			continue;
+		}
+	}
+
+	if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
+		kfree(data);
+		return -ENODEV;
+	}
+
+	data->udev = interface_to_usbdev(intf);
+
+	spin_lock_init(&data->lock);
+
+	INIT_WORK(&data->work, btusb_work);
+
+	init_usb_anchor(&data->tx_anchor);
+	init_usb_anchor(&data->intr_anchor);
+	init_usb_anchor(&data->bulk_anchor);
+
+	hdev = hci_alloc_dev();
+	if (!hdev) {
+		kfree(data);
+		return -ENOMEM;
+	}
+
+	hdev->type = HCI_USB;
+	hdev->driver_data = data;
+
+	data->hdev = hdev;
+
+	SET_HCIDEV_DEV(hdev, &intf->dev);
+
+	hdev->open     = btusb_open;
+	hdev->close    = btusb_close;
+	hdev->flush    = btusb_flush;
+	hdev->send     = btusb_send_frame;
+	hdev->destruct = btusb_destruct;
+	hdev->notify   = btusb_notify;
+
+	hdev->owner = THIS_MODULE;
+
+	set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
+
+	err = hci_register_dev(hdev);
+	if (err < 0) {
+		hci_free_dev(hdev);
+		kfree(data);
+		return err;
+	}
+
+	usb_set_intfdata(intf, data);
+
+	return 0;
+}
+
+static void btusb_disconnect(struct usb_interface *intf)
+{
+	struct btusb_data *data = usb_get_intfdata(intf);
+	struct hci_dev *hdev;
+
+	BT_DBG("intf %p", intf);
+
+	if (!data)
+		return;
+
+	hdev = data->hdev;
+
+	usb_set_intfdata(intf, NULL);
+
+	hci_unregister_dev(hdev);
+
+	hci_free_dev(hdev);
+}
+
+static struct usb_driver btusb_driver = {
+	.name		= "btusb",
+	.probe		= btusb_probe,
+	.disconnect	= btusb_disconnect,
+	.id_table	= btusb_table,
+};
+
+static int __init btusb_init(void)
+{
+	BT_INFO("Generic Bluetooth USB driver ver %s", VERSION);
+
+	return usb_register(&btusb_driver);
+}
+
+static void __exit btusb_exit(void)
+{
+	usb_deregister(&btusb_driver);
+}
+
+module_init(btusb_init);
+module_exit(btusb_exit);
+
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
+MODULE_DESCRIPTION("Generic Bluetooth USB driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 7f9c54b..dae45cd 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -298,10 +298,7 @@
 	int boguscount = 0;
 	int iir, lsr;
 
-	if (!info || !info->hdev) {
-		BT_ERR("Call of irq %d for unknown device", irq);
-		return IRQ_NONE;
-	}
+	BUG_ON(!info->hdev);
 
 	iobase = info->p_dev->io.BasePort1;
 
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index d66064c..696f752 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -237,7 +237,8 @@
 	if (hciextn && chan == 5) {
 		struct hci_command_hdr *hdr = (struct hci_command_hdr *) data;
 
-		if (hci_opcode_ogf(__le16_to_cpu(hdr->opcode)) == OGF_VENDOR_CMD) {
+		/* Vendor specific commands */
+		if (hci_opcode_ogf(__le16_to_cpu(hdr->opcode)) == 0x3f) {
 			u8 desc = *(data + HCI_COMMAND_HDR_SIZE);
 			if ((desc & 0xf0) == 0xc0) {
 				data += HCI_COMMAND_HDR_SIZE + 1;
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 6055b9c..e68821d 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -549,7 +549,10 @@
 #ifdef CONFIG_BT_HCIUART_BCSP
 	bcsp_init();
 #endif
-	
+#ifdef CONFIG_BT_HCIUART_LL
+	ll_init();
+#endif
+
 	return 0;
 }
 
@@ -563,6 +566,9 @@
 #ifdef CONFIG_BT_HCIUART_BCSP
 	bcsp_deinit();
 #endif
+#ifdef CONFIG_BT_HCIUART_LL
+	ll_deinit();
+#endif
 
 	/* Release tty registration of line discipline */
 	if ((err = tty_unregister_ldisc(N_HCI)))
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
new file mode 100644
index 0000000..8c3e62a
--- /dev/null
+++ b/drivers/bluetooth/hci_ll.c
@@ -0,0 +1,531 @@
+/*
+ *  Texas Instruments' Bluetooth HCILL UART protocol
+ *
+ *  HCILL (HCI Low Level) is a Texas Instruments' power management
+ *  protocol extension to H4.
+ *
+ *  Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ *  Written by Ohad Ben-Cohen <ohad@bencohen.org>
+ *
+ *  Acknowledgements:
+ *  This file is based on hci_h4.c, which was written
+ *  by Maxim Krasnyansky and Marcel Holtmann.
+ *
+ *  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
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/poll.h>
+
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/signal.h>
+#include <linux/ioctl.h>
+#include <linux/skbuff.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "hci_uart.h"
+
+/* HCILL commands */
+#define HCILL_GO_TO_SLEEP_IND	0x30
+#define HCILL_GO_TO_SLEEP_ACK	0x31
+#define HCILL_WAKE_UP_IND	0x32
+#define HCILL_WAKE_UP_ACK	0x33
+
+/* HCILL receiver States */
+#define HCILL_W4_PACKET_TYPE	0
+#define HCILL_W4_EVENT_HDR	1
+#define HCILL_W4_ACL_HDR	2
+#define HCILL_W4_SCO_HDR	3
+#define HCILL_W4_DATA		4
+
+/* HCILL states */
+enum hcill_states_e {
+	HCILL_ASLEEP,
+	HCILL_ASLEEP_TO_AWAKE,
+	HCILL_AWAKE,
+	HCILL_AWAKE_TO_ASLEEP
+};
+
+struct hcill_cmd {
+	u8 cmd;
+} __attribute__((packed));
+
+struct ll_struct {
+	unsigned long rx_state;
+	unsigned long rx_count;
+	struct sk_buff *rx_skb;
+	struct sk_buff_head txq;
+	spinlock_t hcill_lock;		/* HCILL state lock	*/
+	unsigned long hcill_state;	/* HCILL power state	*/
+	struct sk_buff_head tx_wait_q;	/* HCILL wait queue	*/
+};
+
+/*
+ * Builds and sends an HCILL command packet.
+ * These are very simple packets with only 1 cmd byte
+ */
+static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
+{
+	int err = 0;
+	struct sk_buff *skb = NULL;
+	struct ll_struct *ll = hu->priv;
+	struct hcill_cmd *hcill_packet;
+
+	BT_DBG("hu %p cmd 0x%x", hu, cmd);
+
+	/* allocate packet */
+	skb = bt_skb_alloc(1, GFP_ATOMIC);
+	if (!skb) {
+		BT_ERR("cannot allocate memory for HCILL packet");
+		err = -ENOMEM;
+		goto out;
+	}
+
+	/* prepare packet */
+	hcill_packet = (struct hcill_cmd *) skb_put(skb, 1);
+	hcill_packet->cmd = cmd;
+	skb->dev = (void *) hu->hdev;
+
+	/* send packet */
+	skb_queue_tail(&ll->txq, skb);
+out:
+	return err;
+}
+
+/* Initialize protocol */
+static int ll_open(struct hci_uart *hu)
+{
+	struct ll_struct *ll;
+
+	BT_DBG("hu %p", hu);
+
+	ll = kzalloc(sizeof(*ll), GFP_ATOMIC);
+	if (!ll)
+		return -ENOMEM;
+
+	skb_queue_head_init(&ll->txq);
+	skb_queue_head_init(&ll->tx_wait_q);
+	spin_lock_init(&ll->hcill_lock);
+
+	ll->hcill_state = HCILL_AWAKE;
+
+	hu->priv = ll;
+
+	return 0;
+}
+
+/* Flush protocol data */
+static int ll_flush(struct hci_uart *hu)
+{
+	struct ll_struct *ll = hu->priv;
+
+	BT_DBG("hu %p", hu);
+
+	skb_queue_purge(&ll->tx_wait_q);
+	skb_queue_purge(&ll->txq);
+
+	return 0;
+}
+
+/* Close protocol */
+static int ll_close(struct hci_uart *hu)
+{
+	struct ll_struct *ll = hu->priv;
+
+	BT_DBG("hu %p", hu);
+
+	skb_queue_purge(&ll->tx_wait_q);
+	skb_queue_purge(&ll->txq);
+
+	if (ll->rx_skb)
+		kfree_skb(ll->rx_skb);
+
+	hu->priv = NULL;
+
+	kfree(ll);
+
+	return 0;
+}
+
+/*
+ * internal function, which does common work of the device wake up process:
+ * 1. places all pending packets (waiting in tx_wait_q list) in txq list.
+ * 2. changes internal state to HCILL_AWAKE.
+ * Note: assumes that hcill_lock spinlock is taken,
+ * shouldn't be called otherwise!
+ */
+static void __ll_do_awake(struct ll_struct *ll)
+{
+	struct sk_buff *skb = NULL;
+
+	while ((skb = skb_dequeue(&ll->tx_wait_q)))
+		skb_queue_tail(&ll->txq, skb);
+
+	ll->hcill_state = HCILL_AWAKE;
+}
+
+/*
+ * Called upon a wake-up-indication from the device
+ */
+static void ll_device_want_to_wakeup(struct hci_uart *hu)
+{
+	unsigned long flags;
+	struct ll_struct *ll = hu->priv;
+
+	BT_DBG("hu %p", hu);
+
+	/* lock hcill state */
+	spin_lock_irqsave(&ll->hcill_lock, flags);
+
+	switch (ll->hcill_state) {
+	case HCILL_ASLEEP:
+		/* acknowledge device wake up */
+		if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) {
+			BT_ERR("cannot acknowledge device wake up");
+			goto out;
+		}
+		break;
+	case HCILL_ASLEEP_TO_AWAKE:
+		/*
+		 * this state means that a wake-up-indication
+		 * is already on its way to the device,
+		 * and will serve as the required wake-up-ack
+		 */
+		BT_DBG("dual wake-up-indication");
+		break;
+	default:
+		/* any other state are illegal */
+		BT_ERR("received HCILL_WAKE_UP_IND in state %ld", ll->hcill_state);
+		break;
+	}
+
+	/* send pending packets and change state to HCILL_AWAKE */
+	__ll_do_awake(ll);
+
+out:
+	spin_unlock_irqrestore(&ll->hcill_lock, flags);
+
+	/* actually send the packets */
+	hci_uart_tx_wakeup(hu);
+}
+
+/*
+ * Called upon a sleep-indication from the device
+ */
+static void ll_device_want_to_sleep(struct hci_uart *hu)
+{
+	unsigned long flags;
+	struct ll_struct *ll = hu->priv;
+
+	BT_DBG("hu %p", hu);
+
+	/* lock hcill state */
+	spin_lock_irqsave(&ll->hcill_lock, flags);
+
+	/* sanity check */
+	if (ll->hcill_state != HCILL_AWAKE)
+		BT_ERR("ERR: HCILL_GO_TO_SLEEP_IND in state %ld", ll->hcill_state);
+
+	/* acknowledge device sleep */
+	if (send_hcill_cmd(HCILL_GO_TO_SLEEP_ACK, hu) < 0) {
+		BT_ERR("cannot acknowledge device sleep");
+		goto out;
+	}
+
+	/* update state */
+	ll->hcill_state = HCILL_ASLEEP;
+
+out:
+	spin_unlock_irqrestore(&ll->hcill_lock, flags);
+
+	/* actually send the sleep ack packet */
+	hci_uart_tx_wakeup(hu);
+}
+
+/*
+ * Called upon wake-up-acknowledgement from the device
+ */
+static void ll_device_woke_up(struct hci_uart *hu)
+{
+	unsigned long flags;
+	struct ll_struct *ll = hu->priv;
+
+	BT_DBG("hu %p", hu);
+
+	/* lock hcill state */
+	spin_lock_irqsave(&ll->hcill_lock, flags);
+
+	/* sanity check */
+	if (ll->hcill_state != HCILL_ASLEEP_TO_AWAKE)
+		BT_ERR("received HCILL_WAKE_UP_ACK in state %ld", ll->hcill_state);
+
+	/* send pending packets and change state to HCILL_AWAKE */
+	__ll_do_awake(ll);
+
+	spin_unlock_irqrestore(&ll->hcill_lock, flags);
+
+	/* actually send the packets */
+	hci_uart_tx_wakeup(hu);
+}
+
+/* Enqueue frame for transmittion (padding, crc, etc) */
+/* may be called from two simultaneous tasklets */
+static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
+{
+	unsigned long flags = 0;
+	struct ll_struct *ll = hu->priv;
+
+	BT_DBG("hu %p skb %p", hu, skb);
+
+	/* Prepend skb with frame type */
+	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
+
+	/* lock hcill state */
+	spin_lock_irqsave(&ll->hcill_lock, flags);
+
+	/* act according to current state */
+	switch (ll->hcill_state) {
+	case HCILL_AWAKE:
+		BT_DBG("device awake, sending normally");
+		skb_queue_tail(&ll->txq, skb);
+		break;
+	case HCILL_ASLEEP:
+		BT_DBG("device asleep, waking up and queueing packet");
+		/* save packet for later */
+		skb_queue_tail(&ll->tx_wait_q, skb);
+		/* awake device */
+		if (send_hcill_cmd(HCILL_WAKE_UP_IND, hu) < 0) {
+			BT_ERR("cannot wake up device");
+			break;
+		}
+		ll->hcill_state = HCILL_ASLEEP_TO_AWAKE;
+		break;
+	case HCILL_ASLEEP_TO_AWAKE:
+		BT_DBG("device waking up, queueing packet");
+		/* transient state; just keep packet for later */
+		skb_queue_tail(&ll->tx_wait_q, skb);
+		break;
+	default:
+		BT_ERR("illegal hcill state: %ld (losing packet)", ll->hcill_state);
+		kfree_skb(skb);
+		break;
+	}
+
+	spin_unlock_irqrestore(&ll->hcill_lock, flags);
+
+	return 0;
+}
+
+static inline int ll_check_data_len(struct ll_struct *ll, int len)
+{
+	register int room = skb_tailroom(ll->rx_skb);
+
+	BT_DBG("len %d room %d", len, room);
+
+	if (!len) {
+		hci_recv_frame(ll->rx_skb);
+	} else if (len > room) {
+		BT_ERR("Data length is too large");
+		kfree_skb(ll->rx_skb);
+	} else {
+		ll->rx_state = HCILL_W4_DATA;
+		ll->rx_count = len;
+		return len;
+	}
+
+	ll->rx_state = HCILL_W4_PACKET_TYPE;
+	ll->rx_skb   = NULL;
+	ll->rx_count = 0;
+
+	return 0;
+}
+
+/* Recv data */
+static int ll_recv(struct hci_uart *hu, void *data, int count)
+{
+	struct ll_struct *ll = hu->priv;
+	register char *ptr;
+	struct hci_event_hdr *eh;
+	struct hci_acl_hdr   *ah;
+	struct hci_sco_hdr   *sh;
+	register int len, type, dlen;
+
+	BT_DBG("hu %p count %d rx_state %ld rx_count %ld", hu, count, ll->rx_state, ll->rx_count);
+
+	ptr = data;
+	while (count) {
+		if (ll->rx_count) {
+			len = min_t(unsigned int, ll->rx_count, count);
+			memcpy(skb_put(ll->rx_skb, len), ptr, len);
+			ll->rx_count -= len; count -= len; ptr += len;
+
+			if (ll->rx_count)
+				continue;
+
+			switch (ll->rx_state) {
+			case HCILL_W4_DATA:
+				BT_DBG("Complete data");
+				hci_recv_frame(ll->rx_skb);
+
+				ll->rx_state = HCILL_W4_PACKET_TYPE;
+				ll->rx_skb = NULL;
+				continue;
+
+			case HCILL_W4_EVENT_HDR:
+				eh = (struct hci_event_hdr *) ll->rx_skb->data;
+
+				BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
+
+				ll_check_data_len(ll, eh->plen);
+				continue;
+
+			case HCILL_W4_ACL_HDR:
+				ah = (struct hci_acl_hdr *) ll->rx_skb->data;
+				dlen = __le16_to_cpu(ah->dlen);
+
+				BT_DBG("ACL header: dlen %d", dlen);
+
+				ll_check_data_len(ll, dlen);
+				continue;
+
+			case HCILL_W4_SCO_HDR:
+				sh = (struct hci_sco_hdr *) ll->rx_skb->data;
+
+				BT_DBG("SCO header: dlen %d", sh->dlen);
+
+				ll_check_data_len(ll, sh->dlen);
+				continue;
+			}
+		}
+
+		/* HCILL_W4_PACKET_TYPE */
+		switch (*ptr) {
+		case HCI_EVENT_PKT:
+			BT_DBG("Event packet");
+			ll->rx_state = HCILL_W4_EVENT_HDR;
+			ll->rx_count = HCI_EVENT_HDR_SIZE;
+			type = HCI_EVENT_PKT;
+			break;
+
+		case HCI_ACLDATA_PKT:
+			BT_DBG("ACL packet");
+			ll->rx_state = HCILL_W4_ACL_HDR;
+			ll->rx_count = HCI_ACL_HDR_SIZE;
+			type = HCI_ACLDATA_PKT;
+			break;
+
+		case HCI_SCODATA_PKT:
+			BT_DBG("SCO packet");
+			ll->rx_state = HCILL_W4_SCO_HDR;
+			ll->rx_count = HCI_SCO_HDR_SIZE;
+			type = HCI_SCODATA_PKT;
+			break;
+
+		/* HCILL signals */
+		case HCILL_GO_TO_SLEEP_IND:
+			BT_DBG("HCILL_GO_TO_SLEEP_IND packet");
+			ll_device_want_to_sleep(hu);
+			ptr++; count--;
+			continue;
+
+		case HCILL_GO_TO_SLEEP_ACK:
+			/* shouldn't happen */
+			BT_ERR("received HCILL_GO_TO_SLEEP_ACK (in state %ld)", ll->hcill_state);
+			ptr++; count--;
+			continue;
+
+		case HCILL_WAKE_UP_IND:
+			BT_DBG("HCILL_WAKE_UP_IND packet");
+			ll_device_want_to_wakeup(hu);
+			ptr++; count--;
+			continue;
+
+		case HCILL_WAKE_UP_ACK:
+			BT_DBG("HCILL_WAKE_UP_ACK packet");
+			ll_device_woke_up(hu);
+			ptr++; count--;
+			continue;
+
+		default:
+			BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
+			hu->hdev->stat.err_rx++;
+			ptr++; count--;
+			continue;
+		};
+
+		ptr++; count--;
+
+		/* Allocate packet */
+		ll->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
+		if (!ll->rx_skb) {
+			BT_ERR("Can't allocate mem for new packet");
+			ll->rx_state = HCILL_W4_PACKET_TYPE;
+			ll->rx_count = 0;
+			return 0;
+		}
+
+		ll->rx_skb->dev = (void *) hu->hdev;
+		bt_cb(ll->rx_skb)->pkt_type = type;
+	}
+
+	return count;
+}
+
+static struct sk_buff *ll_dequeue(struct hci_uart *hu)
+{
+	struct ll_struct *ll = hu->priv;
+	return skb_dequeue(&ll->txq);
+}
+
+static struct hci_uart_proto llp = {
+	.id		= HCI_UART_LL,
+	.open		= ll_open,
+	.close		= ll_close,
+	.recv		= ll_recv,
+	.enqueue	= ll_enqueue,
+	.dequeue	= ll_dequeue,
+	.flush		= ll_flush,
+};
+
+int ll_init(void)
+{
+	int err = hci_uart_register_proto(&llp);
+
+	if (!err)
+		BT_INFO("HCILL protocol initialized");
+	else
+		BT_ERR("HCILL protocol registration failed");
+
+	return err;
+}
+
+int ll_deinit(void)
+{
+	return hci_uart_unregister_proto(&llp);
+}
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index 1097ce7..50113db 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -33,12 +33,13 @@
 #define HCIUARTGETDEVICE	_IOR('U', 202, int)
 
 /* UART protocols */
-#define HCI_UART_MAX_PROTO	4
+#define HCI_UART_MAX_PROTO	5
 
 #define HCI_UART_H4	0
 #define HCI_UART_BCSP	1
 #define HCI_UART_3WIRE	2
 #define HCI_UART_H4DS	3
+#define HCI_UART_LL	4
 
 struct hci_uart;
 
@@ -85,3 +86,8 @@
 int bcsp_init(void);
 int bcsp_deinit(void);
 #endif
+
+#ifdef CONFIG_BT_HCIUART_LL
+int ll_init(void);
+int ll_deinit(void);
+#endif
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 79245714..af05610 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -1107,7 +1107,7 @@
 		       is the default case! */
 		    cdinfo(CD_OPEN, "bummer. wrong media type.\n"); 
 		    cdinfo(CD_WARNING, "pid %d must open device O_NONBLOCK!\n",
-					(unsigned int)current->pid); 
+					(unsigned int)task_pid_nr(current));
 		    ret=-EMEDIUMTYPE;
 		    goto clean_up_and_return;
 		}
@@ -3458,47 +3458,19 @@
 static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp,
 				void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-	int *valp = ctl->data;
-	int val = *valp;
 	int ret;
 	
 	ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
 
-	if (write && *valp != val) {
+	if (write) {
 	
 		/* we only care for 1 or 0. */
-		if (*valp)
-			*valp = 1;
-		else
-			*valp = 0;
+		autoclose        = !!cdrom_sysctl_settings.autoclose;
+		autoeject        = !!cdrom_sysctl_settings.autoeject;
+		debug	         = !!cdrom_sysctl_settings.debug;
+		lockdoor         = !!cdrom_sysctl_settings.lock;
+		check_media_type = !!cdrom_sysctl_settings.check;
 
-		switch (ctl->ctl_name) {
-		case DEV_CDROM_AUTOCLOSE: {
-			if (valp == &cdrom_sysctl_settings.autoclose)
-				autoclose = cdrom_sysctl_settings.autoclose;
-			break;
-			}
-		case DEV_CDROM_AUTOEJECT: {
-			if (valp == &cdrom_sysctl_settings.autoeject)
-				autoeject = cdrom_sysctl_settings.autoeject;
-			break;
-			}
-		case DEV_CDROM_DEBUG: {
-			if (valp == &cdrom_sysctl_settings.debug)
-				debug = cdrom_sysctl_settings.debug;
-			break;
-			}
-		case DEV_CDROM_LOCK: {
-			if (valp == &cdrom_sysctl_settings.lock)
-				lockdoor = cdrom_sysctl_settings.lock;
-			break;
-			}
-		case DEV_CDROM_CHECK_MEDIA: {
-			if (valp == &cdrom_sysctl_settings.check)
-				check_media_type = cdrom_sysctl_settings.check;
-			break;
-			}
-		}
 		/* update the option flags according to the changes. we
 		   don't have per device options through sysctl yet,
 		   but we will have and then this will disappear. */
@@ -3511,7 +3483,6 @@
 /* Place files in /proc/sys/dev/cdrom */
 static ctl_table cdrom_table[] = {
 	{
-		.ctl_name	= DEV_CDROM_INFO,
 		.procname	= "info",
 		.data		= &cdrom_sysctl_settings.info, 
 		.maxlen		= CDROM_STR_SIZE,
@@ -3519,7 +3490,6 @@
 		.proc_handler	= &cdrom_sysctl_info,
 	},
 	{
-		.ctl_name	= DEV_CDROM_AUTOCLOSE,
 		.procname	= "autoclose",
 		.data		= &cdrom_sysctl_settings.autoclose,
 		.maxlen		= sizeof(int),
@@ -3527,7 +3497,6 @@
 		.proc_handler	= &cdrom_sysctl_handler,
 	},
 	{
-		.ctl_name	= DEV_CDROM_AUTOEJECT,
 		.procname	= "autoeject",
 		.data		= &cdrom_sysctl_settings.autoeject,
 		.maxlen		= sizeof(int),
@@ -3535,7 +3504,6 @@
 		.proc_handler	= &cdrom_sysctl_handler,
 	},
 	{
-		.ctl_name	= DEV_CDROM_DEBUG,
 		.procname	= "debug",
 		.data		= &cdrom_sysctl_settings.debug,
 		.maxlen		= sizeof(int),
@@ -3543,7 +3511,6 @@
 		.proc_handler	= &cdrom_sysctl_handler,
 	},
 	{
-		.ctl_name	= DEV_CDROM_LOCK,
 		.procname	= "lock",
 		.data		= &cdrom_sysctl_settings.lock,
 		.maxlen		= sizeof(int),
@@ -3551,7 +3518,6 @@
 		.proc_handler	= &cdrom_sysctl_handler,
 	},
 	{
-		.ctl_name	= DEV_CDROM_CHECK_MEDIA,
 		.procname	= "check_media",
 		.data		= &cdrom_sysctl_settings.check,
 		.maxlen		= sizeof(int),
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 204d53e..bf18d75 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -36,23 +36,6 @@
 	  If unsure, say Y, or else you won't be able to do much with your new
 	  shiny Linux system :-)
 
-config VT_UNICODE
-	bool "Virtual console is Unicode by default"
-	depends on VT
-	default n
-	---help---
-	  If you say Y here, the virtual terminal will be in UTF-8 by default,
-	  and the keyboard will run in unicode mode.
-
-	  If you say N here, the virtual terminal will not be in UTF-8 by
-	  default, and the keyboard will run in XLATE mode.
-
-	  This can also be changed by passing 'default_utf8=<0|1>' on the
-	  kernel command line.
-
-	  Historically, the kernel has defaulted to non-UTF8 and XLATE mode.
-	  If unsure, say N here.
-
 config VT_CONSOLE
 	bool "Support for console on virtual terminal" if EMBEDDED
 	depends on VT
@@ -630,6 +613,10 @@
 	help
 	  Xen virtual console device driver
 
+config VIRTIO_CONSOLE
+	bool
+	select HVC_DRIVER
+
 config HVCS
 	tristate "IBM Hypervisor Virtual Console Server support"
 	depends on PPC_PSERIES
@@ -649,8 +636,6 @@
 
 source "drivers/char/ipmi/Kconfig"
 
-source "drivers/char/watchdog/Kconfig"
-
 config DS1620
 	tristate "NetWinder thermometer support"
 	depends on ARCH_NETWINDER
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index c78ff26..07304d5 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -42,7 +42,6 @@
 obj-$(CONFIG_N_HDLC)		+= n_hdlc.o
 obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
 obj-$(CONFIG_SX)		+= sx.o generic_serial.o
-obj-$(CONFIG_LGUEST_GUEST)	+= hvc_lguest.o
 obj-$(CONFIG_RIO)		+= rio/ generic_serial.o
 obj-$(CONFIG_HVC_CONSOLE)	+= hvc_vio.o hvsi.o
 obj-$(CONFIG_HVC_ISERIES)	+= hvc_iseries.o
@@ -50,6 +49,7 @@
 obj-$(CONFIG_HVC_BEAT)		+= hvc_beat.o
 obj-$(CONFIG_HVC_DRIVER)	+= hvc_console.o
 obj-$(CONFIG_HVC_XEN)		+= hvc_xen.o
+obj-$(CONFIG_VIRTIO_CONSOLE)	+= virtio_console.o
 obj-$(CONFIG_RAW_DRIVER)	+= raw.o
 obj-$(CONFIG_SGI_SNSC)		+= snsc.o snsc_event.o
 obj-$(CONFIG_MSPEC)		+= mspec.o
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c
index ec116df..c99e43b 100644
--- a/drivers/char/apm-emulation.c
+++ b/drivers/char/apm-emulation.c
@@ -18,7 +18,7 @@
 #include <linux/apm_bios.h>
 #include <linux/capability.h>
 #include <linux/sched.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
 #include <linux/apm-emulation.h>
 #include <linux/freezer.h>
 #include <linux/device.h>
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 9e0adfe..e4f579c 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -359,7 +359,7 @@
  *
  * Revision 1.36.3.8  1996/06/07 16:29:00  bentson
  * starting minor number at zero; added missing verify_area
- * as noted by Heiko Eissfeldt <heiko@colossus.escape.de>
+ * as noted by Heiko Eißfeldt <heiko@colossus.escape.de>
  *
  * Revision 1.36.3.7  1996/04/19 21:06:18  bentson
  * remove unneeded boot message & fix CLOCAL hardware flow
@@ -662,7 +662,7 @@
 static void cy_throttle(struct tty_struct *tty);
 static void cy_send_xchar(struct tty_struct *tty, char ch);
 
-#define IS_CYC_Z(card) ((card).num_chips == -1)
+#define IS_CYC_Z(card) ((card).num_chips == (unsigned int)-1)
 
 #define Z_FPGA_CHECK(card) \
 	((readl(&((struct RUNTIME_9060 __iomem *) \
@@ -727,8 +727,6 @@
    driver to probe addresses at a different address, add it to
    this table.  If the driver is probing some other board and
    causing problems, remove the offending address from this table.
-   The cy_setup function extracts additional addresses from the
-   boot options line.  The form is "cyclades=address,address..."
 */
 
 static unsigned int cy_isa_addresses[] = {
@@ -897,71 +895,6 @@
 	return 0;
 }				/* serial_paranoia_check */
 
-/*
- * This routine is used by the interrupt handler to schedule
- * processing in the software interrupt portion of the driver
- * (also known as the "bottom half").  This can be called any
- * number of times for any channel without harm.
- */
-static inline void cy_sched_event(struct cyclades_port *info, int event)
-{
-	info->event |= 1 << event; /* remember what kind of event and who */
-	schedule_work(&info->tqueue);
-}				/* cy_sched_event */
-
-/*
- * This routine is used to handle the "bottom half" processing for the
- * serial driver, known also the "software interrupt" processing.
- * This processing is done at the kernel interrupt level, after the
- * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
- * is where time-consuming activities which can not be done in the
- * interrupt driver proper are done; the interrupt driver schedules
- * them using cy_sched_event(), and they get done here.
- *
- * This is done through one level of indirection--the task queue.
- * When a hardware interrupt service routine wants service by the
- * driver's bottom half, it enqueues the appropriate tq_struct (one
- * per port) to the keventd work queue and sets a request flag
- * that the work queue be processed.
- *
- * Although this may seem unwieldy, it gives the system a way to
- * pass an argument (in this case the pointer to the cyclades_port
- * structure) to the bottom half of the driver.  Previous kernels
- * had to poll every port to see if that port needed servicing.
- */
-static void
-do_softint(struct work_struct *work)
-{
-	struct cyclades_port *info =
-		container_of(work, struct cyclades_port, tqueue);
-	struct tty_struct    *tty;
-
-	tty = info->tty;
-	if (!tty)
-		return;
-
-	if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
-		tty_hangup(info->tty);
-		wake_up_interruptible(&info->open_wait);
-		        info->flags &= ~ASYNC_NORMAL_ACTIVE;
-	}
-	if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event))
-		wake_up_interruptible(&info->open_wait);
-#ifdef CONFIG_CYZ_INTR
-	if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) &&
-			!timer_pending(&cyz_rx_full_timer[info->line]))
-		mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1);
-#endif
-	if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event))
-		wake_up_interruptible(&info->delta_msr_wait);
-	tty_wakeup(tty);
-#ifdef Z_WAKE
-	if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event))
-		complete(&info->shutdown_wait);
-#endif
-} /* do_softint */
-
-
 /***********************************************************/
 /********* Start of block of Cyclom-Y specific code ********/
 
@@ -1045,382 +978,332 @@
 }
 #endif				/* CONFIG_ISA */
 
-static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
-			void __iomem * base_addr, int status, int index)
+static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
+		void __iomem *base_addr)
 {
 	struct cyclades_port *info;
 	struct tty_struct *tty;
-	int char_count;
-	int j, len, mdm_change, mdm_status, outch;
-	int save_xir, channel, save_car;
-	char data;
+	int len, index = cinfo->bus_index;
+	u8 save_xir, channel, save_car, data, char_count;
 
-	if (status & CySRReceive) {	/* reception interrupt */
 #ifdef CY_DEBUG_INTERRUPTS
-		printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
+	printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
 #endif
-		/* determine the channel & change to that context */
-		spin_lock(&cinfo->card_lock);
-		save_xir = (u_char) readb(base_addr + (CyRIR << index));
-		channel = (u_short) (save_xir & CyIRChannel);
-		info = &cinfo->ports[channel + chip * 4];
-		save_car = readb(base_addr + (CyCAR << index));
-		cy_writeb(base_addr + (CyCAR << index), save_xir);
+	/* determine the channel & change to that context */
+	save_xir = readb(base_addr + (CyRIR << index));
+	channel = save_xir & CyIRChannel;
+	info = &cinfo->ports[channel + chip * 4];
+	save_car = readb(base_addr + (CyCAR << index));
+	cy_writeb(base_addr + (CyCAR << index), save_xir);
 
-		/* if there is nowhere to put the data, discard it */
-		if (info->tty == NULL) {
-			j = (readb(base_addr + (CyRIVR << index)) &
-				CyIVRMask);
-			if (j == CyIVRRxEx) {	/* exception */
+	/* if there is nowhere to put the data, discard it */
+	if (info->tty == NULL) {
+		if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
+				CyIVRRxEx) {	/* exception */
+			data = readb(base_addr + (CyRDSR << index));
+		} else {	/* normal character reception */
+			char_count = readb(base_addr + (CyRDCR << index));
+			while (char_count--)
 				data = readb(base_addr + (CyRDSR << index));
-			} else {	/* normal character reception */
-				char_count = readb(base_addr +
-						(CyRDCR << index));
-				while (char_count--) {
-					data = readb(base_addr +
-						(CyRDSR << index));
-				}
-			}
-		} else {	/* there is an open port for this data */
-			tty = info->tty;
-			j = (readb(base_addr + (CyRIVR << index)) &
-					CyIVRMask);
-			if (j == CyIVRRxEx) {	/* exception */
-				data = readb(base_addr + (CyRDSR << index));
+		}
+		goto end;
+	}
+	/* there is an open port for this data */
+	tty = info->tty;
+	if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
+			CyIVRRxEx) {	/* exception */
+		data = readb(base_addr + (CyRDSR << index));
 
-				/* For statistics only */
-				if (data & CyBREAK)
-					info->icount.brk++;
-				else if (data & CyFRAME)
-					info->icount.frame++;
-				else if (data & CyPARITY)
-					info->icount.parity++;
-				else if (data & CyOVERRUN)
-					info->icount.overrun++;
+		/* For statistics only */
+		if (data & CyBREAK)
+			info->icount.brk++;
+		else if (data & CyFRAME)
+			info->icount.frame++;
+		else if (data & CyPARITY)
+			info->icount.parity++;
+		else if (data & CyOVERRUN)
+			info->icount.overrun++;
 
-				if (data & info->ignore_status_mask) {
+		if (data & info->ignore_status_mask) {
+			info->icount.rx++;
+			return;
+		}
+		if (tty_buffer_request_room(tty, 1)) {
+			if (data & info->read_status_mask) {
+				if (data & CyBREAK) {
+					tty_insert_flip_char(tty,
+						readb(base_addr + (CyRDSR <<
+							index)), TTY_BREAK);
 					info->icount.rx++;
-					spin_unlock(&cinfo->card_lock);
-					return;
-				}
-				if (tty_buffer_request_room(tty, 1)) {
-					if (data & info->read_status_mask) {
-						if (data & CyBREAK) {
-							tty_insert_flip_char(
-								tty,
-								readb(
-								base_addr +
-								(CyRDSR <<
-									index)),
-								TTY_BREAK);
-							info->icount.rx++;
-							if (info->flags &
-							    ASYNC_SAK) {
-								do_SAK(tty);
-							}
-						} else if (data & CyFRAME) {
-							tty_insert_flip_char(
-								tty,
-								readb(
-								base_addr +
-								(CyRDSR <<
-									index)),
-								TTY_FRAME);
-							info->icount.rx++;
-							info->idle_stats.
-								frame_errs++;
-						} else if (data & CyPARITY) {
-							/* Pieces of seven... */
-							tty_insert_flip_char(
-								tty,
-								readb(
-								base_addr +
-								(CyRDSR <<
-									index)),
-								TTY_PARITY);
-							info->icount.rx++;
-							info->idle_stats.
-								parity_errs++;
-						} else if (data & CyOVERRUN) {
-							tty_insert_flip_char(
-								tty, 0,
-								TTY_OVERRUN);
-							info->icount.rx++;
-						/* If the flip buffer itself is
-						   overflowing, we still lose
-						   the next incoming character.
-						 */
-							tty_insert_flip_char(
-								tty,
-								readb(
-								base_addr +
-								(CyRDSR <<
-									index)),
-								TTY_FRAME);
-							info->icount.rx++;
-							info->idle_stats.
-								overruns++;
-					/* These two conditions may imply */
-					/* a normal read should be done. */
-					/* }else if(data & CyTIMEOUT){ */
-					/* }else if(data & CySPECHAR){ */
-						} else {
-							tty_insert_flip_char(
-								tty, 0,
-								TTY_NORMAL);
-							info->icount.rx++;
-						}
-					} else {
-						tty_insert_flip_char(tty, 0,
-								TTY_NORMAL);
-						info->icount.rx++;
-					}
-				} else {
-					/* there was a software buffer
-					   overrun and nothing could be
-					   done about it!!! */
-					info->icount.buf_overrun++;
+					if (info->flags & ASYNC_SAK)
+						do_SAK(tty);
+				} else if (data & CyFRAME) {
+					tty_insert_flip_char( tty,
+						readb(base_addr + (CyRDSR <<
+							index)), TTY_FRAME);
+					info->icount.rx++;
+					info->idle_stats.frame_errs++;
+				} else if (data & CyPARITY) {
+					/* Pieces of seven... */
+					tty_insert_flip_char(tty,
+						readb(base_addr + (CyRDSR <<
+							index)), TTY_PARITY);
+					info->icount.rx++;
+					info->idle_stats.parity_errs++;
+				} else if (data & CyOVERRUN) {
+					tty_insert_flip_char(tty, 0,
+							TTY_OVERRUN);
+					info->icount.rx++;
+					/* If the flip buffer itself is
+					   overflowing, we still lose
+					   the next incoming character.
+					 */
+					tty_insert_flip_char(tty,
+						readb(base_addr + (CyRDSR <<
+							index)), TTY_FRAME);
+					info->icount.rx++;
 					info->idle_stats.overruns++;
+				/* These two conditions may imply */
+				/* a normal read should be done. */
+				/* } else if(data & CyTIMEOUT) { */
+				/* } else if(data & CySPECHAR) { */
+				} else {
+					tty_insert_flip_char(tty, 0,
+							TTY_NORMAL);
+					info->icount.rx++;
 				}
-			} else {	/* normal character reception */
-				/* load # chars available from the chip */
-				char_count = readb(base_addr +
-						(CyRDCR << index));
+			} else {
+				tty_insert_flip_char(tty, 0, TTY_NORMAL);
+				info->icount.rx++;
+			}
+		} else {
+			/* there was a software buffer overrun and nothing
+			 * could be done about it!!! */
+			info->icount.buf_overrun++;
+			info->idle_stats.overruns++;
+		}
+	} else {	/* normal character reception */
+		/* load # chars available from the chip */
+		char_count = readb(base_addr + (CyRDCR << index));
 
 #ifdef CY_ENABLE_MONITORING
-				++info->mon.int_count;
-				info->mon.char_count += char_count;
-				if (char_count > info->mon.char_max)
-					info->mon.char_max = char_count;
-				info->mon.char_last = char_count;
+		++info->mon.int_count;
+		info->mon.char_count += char_count;
+		if (char_count > info->mon.char_max)
+			info->mon.char_max = char_count;
+		info->mon.char_last = char_count;
 #endif
-				len = tty_buffer_request_room(tty, char_count);
-				while (len--) {
-					data = readb(base_addr +
-							(CyRDSR << index));
-					tty_insert_flip_char(tty, data,
-							TTY_NORMAL);
-					info->idle_stats.recv_bytes++;
-					info->icount.rx++;
+		len = tty_buffer_request_room(tty, char_count);
+		while (len--) {
+			data = readb(base_addr + (CyRDSR << index));
+			tty_insert_flip_char(tty, data, TTY_NORMAL);
+			info->idle_stats.recv_bytes++;
+			info->icount.rx++;
 #ifdef CY_16Y_HACK
-					udelay(10L);
+			udelay(10L);
 #endif
-				}
-				info->idle_stats.recv_idle = jiffies;
-			}
-			tty_schedule_flip(tty);
 		}
-		/* end of service */
-		cy_writeb(base_addr + (CyRIR << index), (save_xir & 0x3f));
-		cy_writeb(base_addr + (CyCAR << index), (save_car));
-		spin_unlock(&cinfo->card_lock);
+		info->idle_stats.recv_idle = jiffies;
+	}
+	tty_schedule_flip(tty);
+end:
+	/* end of service */
+	cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f);
+	cy_writeb(base_addr + (CyCAR << index), save_car);
+}
+
+static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
+		void __iomem *base_addr)
+{
+	struct cyclades_port *info;
+	int char_count, index = cinfo->bus_index;
+	u8 save_xir, channel, save_car, outch;
+
+	/* Since we only get here when the transmit buffer
+	   is empty, we know we can always stuff a dozen
+	   characters. */
+#ifdef CY_DEBUG_INTERRUPTS
+	printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip);
+#endif
+
+	/* determine the channel & change to that context */
+	save_xir = readb(base_addr + (CyTIR << index));
+	channel = save_xir & CyIRChannel;
+	save_car = readb(base_addr + (CyCAR << index));
+	cy_writeb(base_addr + (CyCAR << index), save_xir);
+
+	/* validate the port# (as configured and open) */
+	if (channel + chip * 4 >= cinfo->nports) {
+		cy_writeb(base_addr + (CySRER << index),
+			  readb(base_addr + (CySRER << index)) & ~CyTxRdy);
+		goto end;
+	}
+	info = &cinfo->ports[channel + chip * 4];
+	if (info->tty == NULL) {
+		cy_writeb(base_addr + (CySRER << index),
+			  readb(base_addr + (CySRER << index)) & ~CyTxRdy);
+		goto end;
 	}
 
-	if (status & CySRTransmit) {	/* transmission interrupt */
-		/* Since we only get here when the transmit buffer
-		   is empty, we know we can always stuff a dozen
-		   characters. */
-#ifdef CY_DEBUG_INTERRUPTS
-		printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip);
-#endif
+	/* load the on-chip space for outbound data */
+	char_count = info->xmit_fifo_size;
 
-		/* determine the channel & change to that context */
-		spin_lock(&cinfo->card_lock);
-		save_xir = (u_char) readb(base_addr + (CyTIR << index));
-		channel = (u_short) (save_xir & CyIRChannel);
-		save_car = readb(base_addr + (CyCAR << index));
-		cy_writeb(base_addr + (CyCAR << index), save_xir);
+	if (info->x_char) {	/* send special char */
+		outch = info->x_char;
+		cy_writeb(base_addr + (CyTDR << index), outch);
+		char_count--;
+		info->icount.tx++;
+		info->x_char = 0;
+	}
 
-		/* validate the port# (as configured and open) */
-		if (channel + chip * 4 >= cinfo->nports) {
-			cy_writeb(base_addr + (CySRER << index),
-				  readb(base_addr + (CySRER << index)) &
-				  ~CyTxRdy);
-			goto txend;
+	if (info->breakon || info->breakoff) {
+		if (info->breakon) {
+			cy_writeb(base_addr + (CyTDR << index), 0);
+			cy_writeb(base_addr + (CyTDR << index), 0x81);
+			info->breakon = 0;
+			char_count -= 2;
 		}
-		info = &cinfo->ports[channel + chip * 4];
-		if (info->tty == NULL) {
-			cy_writeb(base_addr + (CySRER << index),
-				  readb(base_addr + (CySRER << index)) &
-				  ~CyTxRdy);
-			goto txdone;
+		if (info->breakoff) {
+			cy_writeb(base_addr + (CyTDR << index), 0);
+			cy_writeb(base_addr + (CyTDR << index), 0x83);
+			info->breakoff = 0;
+			char_count -= 2;
 		}
+	}
 
-		/* load the on-chip space for outbound data */
-		char_count = info->xmit_fifo_size;
-
-		if (info->x_char) {	/* send special char */
-			outch = info->x_char;
-			cy_writeb(base_addr + (CyTDR << index), outch);
-			char_count--;
-			info->icount.tx++;
-			info->x_char = 0;
-		}
-
-		if (info->breakon || info->breakoff) {
-			if (info->breakon) {
-				cy_writeb(base_addr + (CyTDR << index), 0);
-				cy_writeb(base_addr + (CyTDR << index), 0x81);
-				info->breakon = 0;
-				char_count -= 2;
-			}
-			if (info->breakoff) {
-				cy_writeb(base_addr + (CyTDR << index), 0);
-				cy_writeb(base_addr + (CyTDR << index), 0x83);
-				info->breakoff = 0;
-				char_count -= 2;
-			}
-		}
-
-		while (char_count-- > 0) {
-			if (!info->xmit_cnt) {
-				if (readb(base_addr + (CySRER << index)) &
-						CyTxMpty) {
-					cy_writeb(base_addr + (CySRER << index),
-						readb(base_addr +
-							(CySRER << index)) &
+	while (char_count-- > 0) {
+		if (!info->xmit_cnt) {
+			if (readb(base_addr + (CySRER << index)) & CyTxMpty) {
+				cy_writeb(base_addr + (CySRER << index),
+					readb(base_addr + (CySRER << index)) &
 						~CyTxMpty);
-				} else {
-					cy_writeb(base_addr + (CySRER << index),
-						(readb(base_addr +
-						  	(CySRER << index)) &
+			} else {
+				cy_writeb(base_addr + (CySRER << index),
+					(readb(base_addr + (CySRER << index)) &
 						~CyTxRdy) | CyTxMpty);
-				}
-				goto txdone;
 			}
-			if (info->xmit_buf == NULL) {
-				cy_writeb(base_addr + (CySRER << index),
-					readb(base_addr + (CySRER << index)) &
+			goto done;
+		}
+		if (info->xmit_buf == NULL) {
+			cy_writeb(base_addr + (CySRER << index),
+				readb(base_addr + (CySRER << index)) &
 					~CyTxRdy);
-				goto txdone;
-			}
-			if (info->tty->stopped || info->tty->hw_stopped) {
-				cy_writeb(base_addr + (CySRER << index),
-					readb(base_addr + (CySRER << index)) &
+			goto done;
+		}
+		if (info->tty->stopped || info->tty->hw_stopped) {
+			cy_writeb(base_addr + (CySRER << index),
+				readb(base_addr + (CySRER << index)) &
 					~CyTxRdy);
-				goto txdone;
-			}
-			/* Because the Embedded Transmit Commands have
-			   been enabled, we must check to see if the
-			   escape character, NULL, is being sent.  If it
-			   is, we must ensure that there is room for it
-			   to be doubled in the output stream.  Therefore
-			   we no longer advance the pointer when the
-			   character is fetched, but rather wait until
-			   after the check for a NULL output character.
-			   This is necessary because there may not be
-			   room for the two chars needed to send a NULL.)
-			 */
-			outch = info->xmit_buf[info->xmit_tail];
-			if (outch) {
+			goto done;
+		}
+		/* Because the Embedded Transmit Commands have been enabled,
+		 * we must check to see if the escape character, NULL, is being
+		 * sent. If it is, we must ensure that there is room for it to
+		 * be doubled in the output stream.  Therefore we no longer
+		 * advance the pointer when the character is fetched, but
+		 * rather wait until after the check for a NULL output
+		 * character. This is necessary because there may not be room
+		 * for the two chars needed to send a NULL.)
+		 */
+		outch = info->xmit_buf[info->xmit_tail];
+		if (outch) {
+			info->xmit_cnt--;
+			info->xmit_tail = (info->xmit_tail + 1) &
+					(SERIAL_XMIT_SIZE - 1);
+			cy_writeb(base_addr + (CyTDR << index), outch);
+			info->icount.tx++;
+		} else {
+			if (char_count > 1) {
 				info->xmit_cnt--;
 				info->xmit_tail = (info->xmit_tail + 1) &
-						(SERIAL_XMIT_SIZE - 1);
+					(SERIAL_XMIT_SIZE - 1);
 				cy_writeb(base_addr + (CyTDR << index), outch);
+				cy_writeb(base_addr + (CyTDR << index), 0);
 				info->icount.tx++;
-			} else {
-				if (char_count > 1) {
-					info->xmit_cnt--;
-					info->xmit_tail = (info->xmit_tail + 1)&
-						(SERIAL_XMIT_SIZE - 1);
-					cy_writeb(base_addr + (CyTDR << index),
-						outch);
-					cy_writeb(base_addr + (CyTDR << index),
-						0);
-					info->icount.tx++;
-					char_count--;
-				}
+				char_count--;
 			}
 		}
-
-txdone:
-		if (info->xmit_cnt < WAKEUP_CHARS) {
-			cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
-		}
-txend:
-		/* end of service */
-		cy_writeb(base_addr + (CyTIR << index), (save_xir & 0x3f));
-		cy_writeb(base_addr + (CyCAR << index), (save_car));
-		spin_unlock(&cinfo->card_lock);
 	}
 
-	if (status & CySRModem) {	/* modem interrupt */
+done:
+	tty_wakeup(info->tty);
+end:
+	/* end of service */
+	cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f);
+	cy_writeb(base_addr + (CyCAR << index), save_car);
+}
 
-		/* determine the channel & change to that context */
-		spin_lock(&cinfo->card_lock);
-		save_xir = (u_char) readb(base_addr + (CyMIR << index));
-		channel = (u_short) (save_xir & CyIRChannel);
-		info = &cinfo->ports[channel + chip * 4];
-		save_car = readb(base_addr + (CyCAR << index));
-		cy_writeb(base_addr + (CyCAR << index), save_xir);
+static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
+		void __iomem *base_addr)
+{
+	struct cyclades_port *info;
+	int index = cinfo->bus_index;
+	u8 save_xir, channel, save_car, mdm_change, mdm_status;
 
-		mdm_change = readb(base_addr + (CyMISR << index));
-		mdm_status = readb(base_addr + (CyMSVR1 << index));
+	/* determine the channel & change to that context */
+	save_xir = readb(base_addr + (CyMIR << index));
+	channel = save_xir & CyIRChannel;
+	info = &cinfo->ports[channel + chip * 4];
+	save_car = readb(base_addr + (CyCAR << index));
+	cy_writeb(base_addr + (CyCAR << index), save_xir);
 
-		if (info->tty) {
-			if (mdm_change & CyANY_DELTA) {
-				/* For statistics only */
-				if (mdm_change & CyDCD)
-					info->icount.dcd++;
-				if (mdm_change & CyCTS)
-					info->icount.cts++;
-				if (mdm_change & CyDSR)
-					info->icount.dsr++;
-				if (mdm_change & CyRI)
-					info->icount.rng++;
+	mdm_change = readb(base_addr + (CyMISR << index));
+	mdm_status = readb(base_addr + (CyMSVR1 << index));
 
-				cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
-			}
+	if (!info->tty)
+		goto end;
 
-			if ((mdm_change & CyDCD) &&
-					(info->flags & ASYNC_CHECK_CD)) {
-				if (mdm_status & CyDCD) {
-					cy_sched_event(info,
-							Cy_EVENT_OPEN_WAKEUP);
-				} else {
-					cy_sched_event(info, Cy_EVENT_HANGUP);
-				}
-			}
-			if ((mdm_change & CyCTS) &&
-					(info->flags & ASYNC_CTS_FLOW)) {
-				if (info->tty->hw_stopped) {
-					if (mdm_status & CyCTS) {
-						/* cy_start isn't used
-						   because... !!! */
-						info->tty->hw_stopped = 0;
-						cy_writeb(base_addr +
-							(CySRER << index),
-							readb(base_addr +
-								(CySRER <<
-									index))|
-							CyTxRdy);
-						cy_sched_event(info,
-							Cy_EVENT_WRITE_WAKEUP);
-					}
-				} else {
-					if (!(mdm_status & CyCTS)) {
-						/* cy_stop isn't used
-						   because ... !!! */
-						info->tty->hw_stopped = 1;
-						cy_writeb(base_addr +
-							(CySRER << index),
-							readb(base_addr +
-								(CySRER <<
-								index)) &
-							~CyTxRdy);
-					}
-				}
-			}
-/*			if (mdm_change & CyDSR) {
-			}
-			if (mdm_change & CyRI) {
-			}*/
-		}
-		/* end of service */
-		cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f));
-		cy_writeb(base_addr + (CyCAR << index), save_car);
-		spin_unlock(&cinfo->card_lock);
+	if (mdm_change & CyANY_DELTA) {
+		/* For statistics only */
+		if (mdm_change & CyDCD)
+			info->icount.dcd++;
+		if (mdm_change & CyCTS)
+			info->icount.cts++;
+		if (mdm_change & CyDSR)
+			info->icount.dsr++;
+		if (mdm_change & CyRI)
+			info->icount.rng++;
+
+		wake_up_interruptible(&info->delta_msr_wait);
 	}
+
+	if ((mdm_change & CyDCD) && (info->flags & ASYNC_CHECK_CD)) {
+		if (!(mdm_status & CyDCD)) {
+			tty_hangup(info->tty);
+			info->flags &= ~ASYNC_NORMAL_ACTIVE;
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	if ((mdm_change & CyCTS) && (info->flags & ASYNC_CTS_FLOW)) {
+		if (info->tty->hw_stopped) {
+			if (mdm_status & CyCTS) {
+				/* cy_start isn't used
+				   because... !!! */
+				info->tty->hw_stopped = 0;
+				cy_writeb(base_addr + (CySRER << index),
+					readb(base_addr + (CySRER << index)) |
+						CyTxRdy);
+				tty_wakeup(info->tty);
+			}
+		} else {
+			if (!(mdm_status & CyCTS)) {
+				/* cy_stop isn't used
+				   because ... !!! */
+				info->tty->hw_stopped = 1;
+				cy_writeb(base_addr + (CySRER << index),
+					readb(base_addr + (CySRER << index)) &
+						~CyTxRdy);
+			}
+		}
+	}
+/*	if (mdm_change & CyDSR) {
+	}
+	if (mdm_change & CyRI) {
+	}*/
+end:
+	/* end of service */
+	cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f);
+	cy_writeb(base_addr + (CyCAR << index), save_car);
 }
 
 /* The real interrupt service routine is called
@@ -1432,10 +1315,8 @@
 	int status;
 	struct cyclades_card *cinfo = dev_id;
 	void __iomem *base_addr, *card_base_addr;
-	int chip;
+	unsigned int chip, too_many, had_work;
 	int index;
-	int too_many;
-	int had_work;
 
 	if (unlikely(cinfo == NULL)) {
 #ifdef CY_DEBUG_INTERRUPTS
@@ -1470,11 +1351,16 @@
 			   chips to be checked in a round-robin fashion (after
 			   draining each of a bunch (1000) of characters).
 			 */
-				if (1000 < too_many++) {
+				if (1000 < too_many++)
 					break;
-				}
-				cyy_intr_chip(cinfo, chip, base_addr, status,
-						index);
+				spin_lock(&cinfo->card_lock);
+				if (status & CySRReceive) /* rx intr */
+					cyy_chip_rx(cinfo, chip, base_addr);
+				if (status & CySRTransmit) /* tx intr */
+					cyy_chip_tx(cinfo, chip, base_addr);
+				if (status & CySRModem) /* modem intr */
+					cyy_chip_modem(cinfo, chip, base_addr);
+				spin_unlock(&cinfo->card_lock);
 			}
 		}
 	} while (had_work);
@@ -1529,7 +1415,7 @@
 	struct ZFW_CTRL __iomem *zfw_ctrl;
 	struct BOARD_CTRL __iomem *board_ctrl;
 	__u32 __iomem *pci_doorbell;
-	int index;
+	unsigned int index;
 
 	firm_id = cinfo->base_addr + ID_ADDRESS;
 	if (!ISZLOADED(*cinfo)) {
@@ -1554,13 +1440,12 @@
 	return 0;
 }				/* cyz_issue_cmd */
 
-static void
-cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
+static void cyz_handle_rx(struct cyclades_port *info,
 		struct BUF_CTRL __iomem *buf_ctrl)
 {
 	struct cyclades_card *cinfo = info->card;
 	struct tty_struct *tty = info->tty;
-	int char_count;
+	unsigned int char_count;
 	int len;
 #ifdef BLOCKMOVE
 	unsigned char *buf;
@@ -1633,9 +1518,11 @@
 				char_count = rx_put - rx_get;
 			else
 				char_count = rx_put - rx_get + rx_bufsize;
-			if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) {
-				cy_sched_event(info, Cy_EVENT_Z_RX_FULL);
-			}
+			if (char_count >= readl(&buf_ctrl->rx_threshold) &&
+					!timer_pending(&cyz_rx_full_timer[
+							info->line]))
+				mod_timer(&cyz_rx_full_timer[info->line],
+						jiffies + 1);
 #endif
 			info->idle_stats.recv_idle = jiffies;
 			tty_schedule_flip(tty);
@@ -1645,14 +1532,13 @@
 	}
 }
 
-static void
-cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
+static void cyz_handle_tx(struct cyclades_port *info,
 		struct BUF_CTRL __iomem *buf_ctrl)
 {
 	struct cyclades_card *cinfo = info->card;
 	struct tty_struct *tty = info->tty;
-	char data;
-	int char_count;
+	u8 data;
+	unsigned int char_count;
 #ifdef BLOCKMOVE
 	int small_count;
 #endif
@@ -1716,10 +1602,8 @@
 			info->icount.tx++;
 		}
 #endif
+		tty_wakeup(tty);
 ztxdone:
-		if (info->xmit_cnt < WAKEUP_CHARS) {
-			cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
-		}
 		/* Update tx_put */
 		cy_writel(&buf_ctrl->tx_put, tx_put);
 	}
@@ -1781,10 +1665,11 @@
 				if ((fw_ver > 241 ? ((u_long) param) :
 						readl(&ch_ctrl->rs_status)) &
 						C_RS_DCD) {
-					cy_sched_event(info,
-						 	Cy_EVENT_OPEN_WAKEUP);
+					wake_up_interruptible(&info->open_wait);
 				} else {
-					cy_sched_event(info, Cy_EVENT_HANGUP);
+					tty_hangup(info->tty);
+					wake_up_interruptible(&info->open_wait);
+					info->flags &= ~ASYNC_NORMAL_ACTIVE;
 				}
 			}
 			break;
@@ -1802,7 +1687,7 @@
 			break;
 #ifdef Z_WAKE
 		case C_CM_IOCTLW:
-			cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
+			complete(&info->shutdown_wait);
 			break;
 #endif
 #ifdef CONFIG_CYZ_INTR
@@ -1814,7 +1699,7 @@
 			printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
 					"port %ld\n", info->card, channel);
 #endif
-			cyz_handle_rx(info, ch_ctrl, buf_ctrl);
+			cyz_handle_rx(info, buf_ctrl);
 			break;
 		case C_CM_TXBEMPTY:
 		case C_CM_TXLOWWM:
@@ -1824,7 +1709,7 @@
 			printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
 					"port %ld\n", info->card, channel);
 #endif
-			cyz_handle_tx(info, ch_ctrl, buf_ctrl);
+			cyz_handle_tx(info, buf_ctrl);
 			break;
 #endif				/* CONFIG_CYZ_INTR */
 		case C_CM_FATAL:
@@ -1834,7 +1719,7 @@
 			break;
 		}
 		if (delta_count)
-			cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
+			wake_up_interruptible(&info->delta_msr_wait);
 		if (special_count)
 			tty_schedule_flip(tty);
 	}
@@ -1893,10 +1778,9 @@
 	struct FIRM_ID __iomem *firm_id;
 	struct ZFW_CTRL __iomem *zfw_ctrl;
 	struct BOARD_CTRL __iomem *board_ctrl;
-	struct CH_CTRL __iomem *ch_ctrl;
 	struct BUF_CTRL __iomem *buf_ctrl;
 	unsigned long expires = jiffies + HZ;
-	int card, port;
+	unsigned int port, card;
 
 	for (card = 0; card < NR_CARDS; card++) {
 		cinfo = &cy_card[card];
@@ -1923,12 +1807,11 @@
 		for (port = 0; port < cinfo->nports; port++) {
 			info = &cinfo->ports[port];
 			tty = info->tty;
-			ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
 			buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
 
 			if (!info->throttle)
-				cyz_handle_rx(info, ch_ctrl, buf_ctrl);
-			cyz_handle_tx(info, ch_ctrl, buf_ctrl);
+				cyz_handle_rx(info, buf_ctrl);
+			cyz_handle_tx(info, buf_ctrl);
 		}
 		/* poll every 'cyz_polling_cycle' period */
 		expires = jiffies + cyz_polling_cycle;
@@ -2491,11 +2374,11 @@
 static int cy_open(struct tty_struct *tty, struct file *filp)
 {
 	struct cyclades_port *info;
-	unsigned int i;
-	int retval, line;
+	unsigned int i, line;
+	int retval;
 
 	line = tty->index;
-	if ((line < 0) || (NR_PORTS <= line)) {
+	if ((tty->index < 0) || (NR_PORTS <= line)) {
 		return -ENODEV;
 	}
 	for (i = 0; i < NR_CARDS; i++)
@@ -2812,7 +2695,6 @@
 	spin_lock_irqsave(&card->card_lock, flags);
 
 	tty->closing = 0;
-	info->event = 0;
 	info->tty = NULL;
 	if (info->blocked_open) {
 		spin_unlock_irqrestore(&card->card_lock, flags);
@@ -4444,7 +4326,6 @@
 
 	cy_flush_buffer(tty);
 	shutdown(info);
-	info->event = 0;
 	info->count = 0;
 #ifdef CY_DEBUG_COUNT
 	printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n",
@@ -4467,9 +4348,9 @@
 {
 	struct cyclades_port *info;
 	u32 uninitialized_var(mailbox);
-	unsigned int nports;
+	unsigned int nports, port;
 	unsigned short chip_number;
-	int uninitialized_var(index), port;
+	int uninitialized_var(index);
 
 	spin_lock_init(&cinfo->card_lock);
 
@@ -4502,7 +4383,6 @@
 		info->closing_wait = CLOSING_WAIT_DELAY;
 		info->close_delay = 5 * HZ / 10;
 
-		INIT_WORK(&info->tqueue, do_softint);
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
 		init_completion(&info->shutdown_wait);
@@ -5236,7 +5116,7 @@
 			}
 		}
 #endif				/* CONFIG_CYZ_INTR */
-		cy_card[card_no].num_chips = -1;
+		cy_card[card_no].num_chips = (unsigned int)-1;
 	}
 
 	/* set cy_card */
@@ -5480,13 +5360,13 @@
 #ifdef CONFIG_PCI
 	/* look for pci boards */
 	retval = pci_register_driver(&cy_pci_driver);
-	if (retval && !nboards)
-		goto err_unr;
+	if (retval && !nboards) {
+		tty_unregister_driver(cy_serial_driver);
+		goto err_frtty;
+	}
 #endif
 
 	return 0;
-err_unr:
-	tty_unregister_driver(cy_serial_driver);
 err_frtty:
 	put_tty_driver(cy_serial_driver);
 err:
@@ -5496,7 +5376,7 @@
 static void __exit cy_cleanup_module(void)
 {
 	struct cyclades_card *card;
-	int i, e1;
+	unsigned int i, e1;
 
 #ifndef CONFIG_CYZ_INTR
 	del_timer_sync(&cyz_timerlist);
@@ -5524,8 +5404,7 @@
 #endif /* CONFIG_CYZ_INTR */
 				)
 				free_irq(card->irq, card);
-			for (e1 = card->first_line;
-					e1 < card->first_line +
+			for (e1 = card->first_line; e1 < card->first_line +
 					card->nports; e1++)
 				tty_unregister_device(cy_serial_driver, e1);
 			kfree(card->ports);
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 856774f..d24a6c2 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -1456,7 +1456,7 @@
 		buf = dma->buflist[idx];
 		if (buf->file_priv != file_priv) {
 			DRM_ERROR("Process %d freeing buffer not owned\n",
-				  current->pid);
+				  task_pid_nr(current));
 			return -EINVAL;
 		}
 		drm_free_buffer(dev, buf);
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 72668b1..44a4626 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -463,7 +463,7 @@
 	++file_priv->ioctl_count;
 
 	DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
-		  current->pid, cmd, nr,
+		  task_pid_nr(current), cmd, nr,
 		  (long)old_encode_dev(file_priv->head->device),
 		  file_priv->authenticated);
 
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index f383fc3..3992f73 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -234,7 +234,7 @@
 	if (!drm_cpu_valid())
 		return -EINVAL;
 
-	DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
+	DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor);
 
 	priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
 	if (!priv)
@@ -244,7 +244,7 @@
 	filp->private_data = priv;
 	priv->filp = filp;
 	priv->uid = current->euid;
-	priv->pid = current->pid;
+	priv->pid = task_pid_nr(current);
 	priv->minor = minor;
 	priv->head = drm_heads[minor];
 	priv->ioctl_count = 0;
@@ -339,7 +339,8 @@
 	 */
 
 	DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
-		  current->pid, (long)old_encode_dev(file_priv->head->device),
+		  task_pid_nr(current),
+		  (long)old_encode_dev(file_priv->head->device),
 		  dev->open_count);
 
 	if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) {
diff --git a/drivers/char/drm/drm_hashtab.c b/drivers/char/drm/drm_hashtab.c
index 3ad3190..4b8e7db 100644
--- a/drivers/char/drm/drm_hashtab.c
+++ b/drivers/char/drm/drm_hashtab.c
@@ -29,7 +29,7 @@
  * Simple open hash tab implementation.
  *
  * Authors:
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #include "drmP.h"
diff --git a/drivers/char/drm/drm_hashtab.h b/drivers/char/drm/drm_hashtab.h
index 0f13767..573e333 100644
--- a/drivers/char/drm/drm_hashtab.h
+++ b/drivers/char/drm/drm_hashtab.h
@@ -29,7 +29,7 @@
  * Simple open hash tab implementation.
  *
  * Authors:
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #ifndef DRM_HASHTAB_H
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
index c6b73e7..bea2a7d 100644
--- a/drivers/char/drm/drm_lock.c
+++ b/drivers/char/drm/drm_lock.c
@@ -58,12 +58,12 @@
 
 	if (lock->context == DRM_KERNEL_CONTEXT) {
 		DRM_ERROR("Process %d using kernel context %d\n",
-			  current->pid, lock->context);
+			  task_pid_nr(current), lock->context);
 		return -EINVAL;
 	}
 
 	DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
-		  lock->context, current->pid,
+		  lock->context, task_pid_nr(current),
 		  dev->lock.hw_lock->lock, lock->flags);
 
 	if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
@@ -153,7 +153,7 @@
 
 	if (lock->context == DRM_KERNEL_CONTEXT) {
 		DRM_ERROR("Process %d using kernel context %d\n",
-			  current->pid, lock->context);
+			  task_pid_nr(current), lock->context);
 		return -EINVAL;
 	}
 
diff --git a/drivers/char/drm/drm_mm.c b/drivers/char/drm/drm_mm.c
index 3e6bc14..86f4eb6 100644
--- a/drivers/char/drm/drm_mm.c
+++ b/drivers/char/drm/drm_mm.c
@@ -38,7 +38,7 @@
  * Aligned allocations can also see improvement.
  *
  * Authors:
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #include "drmP.h"
diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
index 114e54e..76e44ac 100644
--- a/drivers/char/drm/drm_os_linux.h
+++ b/drivers/char/drm/drm_os_linux.h
@@ -7,7 +7,7 @@
 #include <linux/delay.h>
 
 /** Current process ID */
-#define DRM_CURRENTPID			current->pid
+#define DRM_CURRENTPID			task_pid_nr(current)
 #define DRM_SUSER(p)			capable(CAP_SYS_ADMIN)
 #define DRM_UDELAY(d)			udelay(d)
 /** Read a byte from a MMIO region */
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c
index e292bb0..b55d5bc 100644
--- a/drivers/char/drm/drm_pci.c
+++ b/drivers/char/drm/drm_pci.c
@@ -8,12 +8,12 @@
  * \todo Implement the remaining ioctl's for the PCI pools.
  * \todo The wrappers here are so thin that they would be better off inlined..
  *
- * \author Jose Fonseca <jrfonseca@tungstengraphics.com>
+ * \author José Fonseca <jrfonseca@tungstengraphics.com>
  * \author Leif Delgass <ldelgass@retinalburn.net>
  */
 
 /*
- * Copyright 2003 Jos�Fonseca.
+ * Copyright 2003 José Fonseca.
  * Copyright 2003 Leif Delgass.
  * All Rights Reserved.
  *
diff --git a/drivers/char/drm/drm_sarea.h b/drivers/char/drm/drm_sarea.h
index f546696..e040f47 100644
--- a/drivers/char/drm/drm_sarea.h
+++ b/drivers/char/drm/drm_sarea.h
@@ -2,7 +2,7 @@
  * \file drm_sarea.h
  * \brief SAREA definitions
  *
- * \author Michel Dänzer <michel@daenzer.net>
+ * \author Michel Dänzer <michel@daenzer.net>
  */
 
 /*
diff --git a/drivers/char/drm/drm_sman.c b/drivers/char/drm/drm_sman.c
index 8421a93..926f146 100644
--- a/drivers/char/drm/drm_sman.c
+++ b/drivers/char/drm/drm_sman.c
@@ -33,7 +33,7 @@
  * struct or a context identifier.
  *
  * Authors:
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #include "drm_sman.h"
diff --git a/drivers/char/drm/drm_sman.h b/drivers/char/drm/drm_sman.h
index 39a39fe..08ecf83 100644
--- a/drivers/char/drm/drm_sman.h
+++ b/drivers/char/drm/drm_sman.h
@@ -33,7 +33,7 @@
  * struct or a context identifier.
  *
  * Authors:
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #ifndef DRM_SMAN_H
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index 8e841bd..eb381a7 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -1024,7 +1024,7 @@
 	retcode = i810_dma_get_buffer(dev, d, file_priv);
 
 	DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
-		  current->pid, retcode, d->granted);
+		  task_pid_nr(current), retcode, d->granted);
 
 	sarea_priv->last_dispatch = (int)hw_status[5];
 
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index 43a1f78..69a363e 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -1409,7 +1409,7 @@
 	retcode = i830_dma_get_buffer(dev, d, file_priv);
 
 	DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n",
-		  current->pid, retcode, d->granted);
+		  task_pid_nr(current), retcode, d->granted);
 
 	sarea_priv->last_dispatch = (int)hw_status[5];
 
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
index 250d2aa..5041bd8 100644
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -29,7 +29,7 @@
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Kevin E. Martin <martin@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *    Michel D�zer <daenzerm@student.ethz.ch>
+ *    Michel Dänzer <daenzerm@student.ethz.ch>
  */
 
 #ifndef __R128_DRV_H__
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index 2b2407e..84f5bc3 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -27,7 +27,7 @@
  *
  * Authors:
  *    Keith Whitwell <keith@tungstengraphics.com>
- *    Michel D�zer <michel@daenzer.net>
+ *    Michel Dänzer <michel@daenzer.net>
  */
 
 #include "drmP.h"
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 69c9f2fe..f824f2f5 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -3005,7 +3005,7 @@
 		/*
 		 * This ioctl() doesn't work on 64-bit platforms because hw_lock is a
 		 * pointer which can't fit into an int-sized variable.  According to
-		 * Michel Dänzer, the ioctl() is only used on embedded platforms, so
+		 * Michel Dänzer, the ioctl() is only used on embedded platforms, so
 		 * not supporting it shouldn't be a problem.  If the same functionality
 		 * is needed on 64-bit platforms, a new ioctl() would have to be added,
 		 * so backwards-compatibility for the embedded platforms can be
diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
index 8c66838..6be1c57 100644
--- a/drivers/char/drm/sis_mm.c
+++ b/drivers/char/drm/sis_mm.c
@@ -28,7 +28,7 @@
 
 /*
  * Authors:
- *    Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ *    Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #include "drmP.h"
diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c
index 9afc168..3ffbf86 100644
--- a/drivers/char/drm/via_mm.c
+++ b/drivers/char/drm/via_mm.c
@@ -22,7 +22,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 /*
- * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #include "drmP.h"
diff --git a/drivers/char/drm/via_verifier.h b/drivers/char/drm/via_verifier.h
index 28b5029..d6f8214 100644
--- a/drivers/char/drm/via_verifier.h
+++ b/drivers/char/drm/via_verifier.h
@@ -20,7 +20,7 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  *
- * Author: Thomas Hellström 2004.
+ * Author: Thomas Hellström 2004.
  */
 
 #ifndef _VIA_VERIFIER_H_
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index 2e7ae42..2860776 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -19,7 +19,7 @@
  *
  *  rs_set_termios fixed to look also for changes of the input
  *      flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK.
- *                                            Bernd Anh�pl 05/17/96.
+ *                                            Bernd Anhäupl 05/17/96.
  *
  * --- End of notices from serial.c ---
  *
@@ -58,10 +58,10 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/bitops.h>
 
 #include <asm/dma.h>
 #include <linux/slab.h>
diff --git a/drivers/char/hvc_lguest.c b/drivers/char/hvc_lguest.c
deleted file mode 100644
index efccb21..0000000
--- a/drivers/char/hvc_lguest.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*D:300
- * The Guest console driver
- *
- * This is a trivial console driver: we use lguest's DMA mechanism to send
- * bytes out, and register a DMA buffer to receive bytes in.  It is assumed to
- * be present and available from the very beginning of boot.
- *
- * Writing console drivers is one of the few remaining Dark Arts in Linux.
- * Fortunately for us, the path of virtual consoles has been well-trodden by
- * the PowerPC folks, who wrote "hvc_console.c" to generically support any
- * virtual console.  We use that infrastructure which only requires us to write
- * the basic put_chars and get_chars functions and call the right register
- * functions.
- :*/
-
-/*M:002 The console can be flooded: while the Guest is processing input the
- * Host can send more.  Buffering in the Host could alleviate this, but it is a
- * difficult problem in general. :*/
-/* Copyright (C) 2006 Rusty Russell, IBM 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
- */
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/lguest_bus.h>
-#include <asm/paravirt.h>
-#include "hvc_console.h"
-
-/*D:340 This is our single console input buffer, with associated "struct
- * lguest_dma" referring to it.  Note the 0-terminated length array, and the
- * use of physical address for the buffer itself. */
-static char inbuf[256];
-static struct lguest_dma cons_input = { .used_len = 0,
-					.addr[0] = __pa(inbuf),
-					.len[0] = sizeof(inbuf),
-					.len[1] = 0 };
-
-/*D:310 The put_chars() callback is pretty straightforward.
- *
- * First we put the pointer and length in a "struct lguest_dma": we only have
- * one pointer, so we set the second length to 0.  Then we use SEND_DMA to send
- * the data to (Host) buffers attached to the console key.  Usually a device's
- * key is a physical address within the device's memory, but because the
- * console device doesn't have any associated physical memory, we use the
- * LGUEST_CONSOLE_DMA_KEY constant (aka 0). */
-static int put_chars(u32 vtermno, const char *buf, int count)
-{
-	struct lguest_dma dma;
-
-	/* FIXME: DMA buffers in a "struct lguest_dma" are not allowed
-	 * to go over page boundaries.  This never seems to happen,
-	 * but if it did we'd need to fix this code. */
-	dma.len[0] = count;
-	dma.len[1] = 0;
-	dma.addr[0] = __pa(buf);
-
-	lguest_send_dma(LGUEST_CONSOLE_DMA_KEY, &dma);
-	/* We're expected to return the amount of data we wrote: all of it. */
-	return count;
-}
-
-/*D:350 get_chars() is the callback from the hvc_console infrastructure when
- * an interrupt is received.
- *
- * Firstly we see if our buffer has been filled: if not, we return.  The rest
- * of the code deals with the fact that the hvc_console() infrastructure only
- * asks us for 16 bytes at a time.  We keep a "cons_offset" variable for
- * partially-read buffers. */
-static int get_chars(u32 vtermno, char *buf, int count)
-{
-	static int cons_offset;
-
-	/* Nothing left to see here... */
-	if (!cons_input.used_len)
-		return 0;
-
-	/* You want more than we have to give?  Well, try wanting less! */
-	if (cons_input.used_len - cons_offset < count)
-		count = cons_input.used_len - cons_offset;
-
-	/* Copy across to their buffer and increment offset. */
-	memcpy(buf, inbuf + cons_offset, count);
-	cons_offset += count;
-
-	/* Finished?  Zero offset, and reset cons_input so Host will use it
-	 * again. */
-	if (cons_offset == cons_input.used_len) {
-		cons_offset = 0;
-		cons_input.used_len = 0;
-	}
-	return count;
-}
-/*:*/
-
-static struct hv_ops lguest_cons = {
-	.get_chars = get_chars,
-	.put_chars = put_chars,
-};
-
-/*D:320 Console drivers are initialized very early so boot messages can go
- * out.  At this stage, the console is output-only.  Our driver checks we're a
- * Guest, and if so hands hvc_instantiate() the console number (0), priority
- * (0), and the struct hv_ops containing the put_chars() function. */
-static int __init cons_init(void)
-{
-	if (strcmp(pv_info.name, "lguest") != 0)
-		return 0;
-
-	return hvc_instantiate(0, 0, &lguest_cons);
-}
-console_initcall(cons_init);
-
-/*D:370 To set up and manage our virtual console, we call hvc_alloc() and
- * stash the result in the private pointer of the "struct lguest_device".
- * Since we never remove the console device we never need this pointer again,
- * but using ->private is considered good form, and you never know who's going
- * to copy your driver.
- *
- * Once the console is set up, we bind our input buffer ready for input. */
-static int lguestcons_probe(struct lguest_device *lgdev)
-{
-	int err;
-
-	/* The first argument of hvc_alloc() is the virtual console number, so
-	 * we use zero.  The second argument is the interrupt number.
-	 *
-	 * The third argument is a "struct hv_ops" containing the put_chars()
-	 * and get_chars() pointers.  The final argument is the output buffer
-	 * size: we use 256 and expect the Host to have room for us to send
-	 * that much. */
-	lgdev->private = hvc_alloc(0, lgdev_irq(lgdev), &lguest_cons, 256);
-	if (IS_ERR(lgdev->private))
-		return PTR_ERR(lgdev->private);
-
-	/* We bind a single DMA buffer at key LGUEST_CONSOLE_DMA_KEY.
-	 * "cons_input" is that statically-initialized global DMA buffer we saw
-	 * above, and we also give the interrupt we want. */
-	err = lguest_bind_dma(LGUEST_CONSOLE_DMA_KEY, &cons_input, 1,
-			      lgdev_irq(lgdev));
-	if (err)
-		printk("lguest console: failed to bind buffer.\n");
-	return err;
-}
-/* Note the use of lgdev_irq() for the interrupt number.  We tell hvc_alloc()
- * to expect input when this interrupt is triggered, and then tell
- * lguest_bind_dma() that is the interrupt to send us when input comes in. */
-
-/*D:360 From now on the console driver follows standard Guest driver form:
- * register_lguest_driver() registers the device type and probe function, and
- * the probe function sets up the device.
- *
- * The standard "struct lguest_driver": */
-static struct lguest_driver lguestcons_drv = {
-	.name = "lguestcons",
-	.owner = THIS_MODULE,
-	.device_type = LGUEST_DEVICE_T_CONSOLE,
-	.probe = lguestcons_probe,
-};
-
-/* The standard init function */
-static int __init hvc_lguest_init(void)
-{
-	return register_lguest_driver(&lguestcons_drv);
-}
-module_init(hvc_lguest_init);
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index e13dd18..3f35a1c 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -10,7 +10,7 @@
  * Mostly based on original driver:
  *
  * Copyright (C) 2005 Nokia Corporation
- * Author: Juha Yrj��<juha.yrjola@nokia.com>
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
  *
  * This file is licensed under  the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index cd40641..30e5645 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -371,14 +371,14 @@
 	int fn_key, cpu_temp, ac_power;
 	int left_fan, right_fan, left_speed, right_speed;
 
-	cpu_temp	= i8k_get_temp(0);			/* 11100 µs */
-	left_fan	= i8k_get_fan_status(I8K_FAN_LEFT);	/*   580 µs */
-	right_fan	= i8k_get_fan_status(I8K_FAN_RIGHT);	/*   580 µs */
-	left_speed	= i8k_get_fan_speed(I8K_FAN_LEFT);	/*   580 µs */
-	right_speed	= i8k_get_fan_speed(I8K_FAN_RIGHT);	/*   580 µs */
-	fn_key		= i8k_get_fn_status();			/*   750 µs */
+	cpu_temp	= i8k_get_temp(0);			/* 11100 µs */
+	left_fan	= i8k_get_fan_status(I8K_FAN_LEFT);	/*   580 µs */
+	right_fan	= i8k_get_fan_status(I8K_FAN_RIGHT);	/*   580 µs */
+	left_speed	= i8k_get_fan_speed(I8K_FAN_LEFT);	/*   580 µs */
+	right_speed	= i8k_get_fan_speed(I8K_FAN_RIGHT);	/*   580 µs */
+	fn_key		= i8k_get_fn_status();			/*   750 µs */
 	if (power_status)
-		ac_power = i8k_get_power_status();		/* 14700 µs */
+		ac_power = i8k_get_power_status();		/* 14700 µs */
 	else
 		ac_power = -1;
 
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 8435fba..5dc1265 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -221,10 +221,8 @@
 	void                     *send_info;
 
 #ifdef CONFIG_PROC_FS
-	/* A list of proc entries for this interface.  This does not
-	   need a lock, only one thread creates it and only one thread
-	   destroys it. */
-	spinlock_t             proc_entry_lock;
+	/* A list of proc entries for this interface. */
+	struct mutex           proc_entry_lock;
 	struct ipmi_proc_entry *proc_entries;
 #endif
 
@@ -1891,11 +1889,11 @@
 		file->write_proc = write_proc;
 		file->owner = owner;
 
-		spin_lock(&smi->proc_entry_lock);
+		mutex_lock(&smi->proc_entry_lock);
 		/* Stick it on the list. */
 		entry->next = smi->proc_entries;
 		smi->proc_entries = entry;
-		spin_unlock(&smi->proc_entry_lock);
+		mutex_unlock(&smi->proc_entry_lock);
 	}
 #endif /* CONFIG_PROC_FS */
 
@@ -1939,7 +1937,7 @@
 #ifdef CONFIG_PROC_FS
 	struct ipmi_proc_entry *entry;
 
-	spin_lock(&smi->proc_entry_lock);
+	mutex_lock(&smi->proc_entry_lock);
 	while (smi->proc_entries) {
 		entry = smi->proc_entries;
 		smi->proc_entries = entry->next;
@@ -1948,7 +1946,7 @@
 		kfree(entry->name);
 		kfree(entry);
 	}
-	spin_unlock(&smi->proc_entry_lock);
+	mutex_unlock(&smi->proc_entry_lock);
 	remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);
 #endif /* CONFIG_PROC_FS */
 }
@@ -2614,6 +2612,14 @@
 	return;
 }
 
+void ipmi_poll_interface(ipmi_user_t user)
+{
+	ipmi_smi_t intf = user->intf;
+
+	if (intf->handlers->poll)
+		intf->handlers->poll(intf->send_info);
+}
+
 int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
 		      void		       *send_info,
 		      struct ipmi_device_id    *device_id,
@@ -2671,7 +2677,7 @@
 	}
 	intf->curr_seq = 0;
 #ifdef CONFIG_PROC_FS
-	spin_lock_init(&intf->proc_entry_lock);
+	mutex_init(&intf->proc_entry_lock);
 #endif
 	spin_lock_init(&intf->waiting_msgs_lock);
 	INIT_LIST_HEAD(&intf->waiting_msgs);
@@ -4166,6 +4172,7 @@
 EXPORT_SYMBOL(ipmi_get_version);
 EXPORT_SYMBOL(ipmi_request_settime);
 EXPORT_SYMBOL(ipmi_request_supply_msgs);
+EXPORT_SYMBOL(ipmi_poll_interface);
 EXPORT_SYMBOL(ipmi_register_smi);
 EXPORT_SYMBOL(ipmi_unregister_smi);
 EXPORT_SYMBOL(ipmi_register_for_cmd);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index c1222e9..4f560d0 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -675,7 +675,8 @@
 }
 
 /* Called on timeouts and events.  Timeouts should pass the elapsed
-   time, interrupts should pass in zero. */
+   time, interrupts should pass in zero.  Must be called with
+   si_lock held and interrupts disabled. */
 static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
 					   int time)
 {
@@ -892,13 +893,16 @@
 static void poll(void *send_info)
 {
 	struct smi_info *smi_info = send_info;
+	unsigned long flags;
 
 	/*
 	 * Make sure there is some delay in the poll loop so we can
 	 * drive time forward and timeout things.
 	 */
 	udelay(10);
+	spin_lock_irqsave(&smi_info->si_lock, flags);
 	smi_event_handler(smi_info, 10);
+	spin_unlock_irqrestore(&smi_info->si_lock, flags);
 }
 
 static void request_events(void *send_info)
@@ -1006,6 +1010,10 @@
 
 	new_smi->intf = intf;
 
+	/* Try to claim any interrupts. */
+	if (new_smi->irq_setup)
+		new_smi->irq_setup(new_smi);
+
 	/* Set up the timer that drives the interface. */
 	setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
 	new_smi->last_timeout_jiffies = jiffies;
@@ -2372,20 +2380,9 @@
 	/* Otherwise, we got some data. */
 	resp_len = smi_info->handlers->get_result(smi_info->si_sm,
 						  resp, IPMI_MAX_MSG_LENGTH);
-	if (resp_len < 14) {
-		/* That's odd, it should be longer. */
-		rv = -EINVAL;
-		goto out;
-	}
 
-	if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0)) {
-		/* That's odd, it shouldn't be able to fail. */
-		rv = -EINVAL;
-		goto out;
-	}
-
-	/* Record info from the get device id, in case we need it. */
-	ipmi_demangle_device_id(resp+3, resp_len-3, &smi_info->device_id);
+	/* Check and record info from the get device id, in case we need it. */
+	rv = ipmi_demangle_device_id(resp, resp_len, &smi_info->device_id);
 
  out:
 	kfree(resp);
@@ -2765,10 +2762,6 @@
 	setup_oem_data_handler(new_smi);
 	setup_xaction_handlers(new_smi);
 
-	/* Try to claim any interrupts. */
-	if (new_smi->irq_setup)
-		new_smi->irq_setup(new_smi);
-
 	INIT_LIST_HEAD(&(new_smi->xmit_msgs));
 	INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs));
 	new_smi->curr_msg = NULL;
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 41f78e2..e686fc9 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -50,10 +50,19 @@
 #include <linux/poll.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
+#include <linux/delay.h>
 #include <asm/atomic.h>
 
-#ifdef CONFIG_X86_LOCAL_APIC
-#include <asm/apic.h>
+#ifdef CONFIG_X86
+/* This is ugly, but I've determined that x86 is the only architecture
+   that can reasonably support the IPMI NMI watchdog timeout at this
+   time.  If another architecture adds this capability somehow, it
+   will have to be a somewhat different mechanism and I have no idea
+   how it will work.  So in the unlikely event that another
+   architecture supports this, we can figure out a good generic
+   mechanism for it at that time. */
+#include <asm/kdebug.h>
+#define HAVE_DIE_NMI
 #endif
 
 #define	PFX "IPMI Watchdog: "
@@ -166,8 +175,6 @@
 
 static int ifnum_to_use = -1;
 
-static DECLARE_RWSEM(register_sem);
-
 /* Parameters to ipmi_set_timeout */
 #define IPMI_SET_TIMEOUT_NO_HB			0
 #define IPMI_SET_TIMEOUT_HB_IF_NECESSARY	1
@@ -193,11 +200,9 @@
 	if (endp == val)
 		return -EINVAL;
 
-	down_read(&register_sem);
 	*((int *)kp->arg) = l;
 	if (watchdog_user)
 		rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
-	up_read(&register_sem);
 
 	return rv;
 }
@@ -226,17 +231,15 @@
 
 	s = strstrip(valcp);
 
-	down_read(&register_sem);
 	rv = fn(s, NULL);
 	if (rv)
-		goto out_unlock;
+		goto out;
 
 	check_parms();
 	if (watchdog_user)
 		rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
 
- out_unlock:
-	up_read(&register_sem);
+ out:
 	return rv;
 }
 
@@ -319,9 +322,12 @@
 /* If a pretimeout occurs, this is used to allow only one panic to happen. */
 static atomic_t preop_panic_excl = ATOMIC_INIT(-1);
 
-static int ipmi_heartbeat(void);
-static void panic_halt_ipmi_heartbeat(void);
+#ifdef HAVE_DIE_NMI
+static int testing_nmi;
+static int nmi_handler_registered;
+#endif
 
+static int ipmi_heartbeat(void);
 
 /* We use a mutex to make sure that only one thing can send a set
    timeout at one time, because we only have one copy of the data.
@@ -360,6 +366,9 @@
 	int                               hbnow = 0;
 
 
+	/* These can be cleared as we are setting the timeout. */
+	pretimeout_since_last_heartbeat = 0;
+
 	data[0] = 0;
 	WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS);
 
@@ -434,31 +443,75 @@
 
 	wait_for_completion(&set_timeout_wait);
 
+	mutex_unlock(&set_timeout_lock);
+
 	if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB)
 	    || ((send_heartbeat_now)
 		&& (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY)))
-	{
 		rv = ipmi_heartbeat();
-	}
-	mutex_unlock(&set_timeout_lock);
 
 out:
 	return rv;
 }
 
-static void dummy_smi_free(struct ipmi_smi_msg *msg)
+static atomic_t panic_done_count = ATOMIC_INIT(0);
+
+static void panic_smi_free(struct ipmi_smi_msg *msg)
 {
+	atomic_dec(&panic_done_count);
 }
-static void dummy_recv_free(struct ipmi_recv_msg *msg)
+static void panic_recv_free(struct ipmi_recv_msg *msg)
 {
+	atomic_dec(&panic_done_count);
 }
+
+static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg =
+{
+	.done = panic_smi_free
+};
+static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg =
+{
+	.done = panic_recv_free
+};
+
+static void panic_halt_ipmi_heartbeat(void)
+{
+	struct kernel_ipmi_msg             msg;
+	struct ipmi_system_interface_addr addr;
+	int rv;
+
+	/* Don't reset the timer if we have the timer turned off, that
+           re-enables the watchdog. */
+	if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
+		return;
+
+	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+	addr.channel = IPMI_BMC_CHANNEL;
+	addr.lun = 0;
+
+	msg.netfn = 0x06;
+	msg.cmd = IPMI_WDOG_RESET_TIMER;
+	msg.data = NULL;
+	msg.data_len = 0;
+	rv = ipmi_request_supply_msgs(watchdog_user,
+				      (struct ipmi_addr *) &addr,
+				      0,
+				      &msg,
+				      NULL,
+				      &panic_halt_heartbeat_smi_msg,
+				      &panic_halt_heartbeat_recv_msg,
+				      1);
+	if (!rv)
+		atomic_add(2, &panic_done_count);
+}
+
 static struct ipmi_smi_msg panic_halt_smi_msg =
 {
-	.done = dummy_smi_free
+	.done = panic_smi_free
 };
 static struct ipmi_recv_msg panic_halt_recv_msg =
 {
-	.done = dummy_recv_free
+	.done = panic_recv_free
 };
 
 /* Special call, doesn't claim any locks.  This is only to be called
@@ -470,13 +523,21 @@
 	int send_heartbeat_now;
 	int rv;
 
+	/* Wait for the messages to be free. */
+	while (atomic_read(&panic_done_count) != 0)
+		ipmi_poll_interface(watchdog_user);
 	rv = i_ipmi_set_timeout(&panic_halt_smi_msg,
 				&panic_halt_recv_msg,
 				&send_heartbeat_now);
 	if (!rv) {
+		atomic_add(2, &panic_done_count);
 		if (send_heartbeat_now)
 			panic_halt_ipmi_heartbeat();
-	}
+	} else
+		printk(KERN_WARNING PFX
+		       "Unable to extend the watchdog timeout.");
+	while (atomic_read(&panic_done_count) != 0)
+		ipmi_poll_interface(watchdog_user);
 }
 
 /* We use a semaphore to make sure that only one thing can send a
@@ -505,24 +566,14 @@
 	.done = heartbeat_free_recv
 };
  
-static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg =
-{
-	.done = dummy_smi_free
-};
-static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg =
-{
-	.done = dummy_recv_free
-};
- 
 static int ipmi_heartbeat(void)
 {
 	struct kernel_ipmi_msg            msg;
 	int                               rv;
 	struct ipmi_system_interface_addr addr;
 
-	if (ipmi_ignore_heartbeat) {
+	if (ipmi_ignore_heartbeat)
 		return 0;
-	}
 
 	if (ipmi_start_timer_on_heartbeat) {
 		ipmi_start_timer_on_heartbeat = 0;
@@ -533,7 +584,6 @@
 		   We don't want to set the action, though, we want to
 		   leave that alone (thus it can't be combined with the
 		   above operation. */
-		pretimeout_since_last_heartbeat = 0;
 		return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
 	}
 
@@ -586,35 +636,6 @@
 	return rv;
 }
 
-static void panic_halt_ipmi_heartbeat(void)
-{
-	struct kernel_ipmi_msg             msg;
-	struct ipmi_system_interface_addr addr;
-
-
-	/* Don't reset the timer if we have the timer turned off, that
-           re-enables the watchdog. */
-	if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
-		return;
-
-	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
-	addr.channel = IPMI_BMC_CHANNEL;
-	addr.lun = 0;
-
-	msg.netfn = 0x06;
-	msg.cmd = IPMI_WDOG_RESET_TIMER;
-	msg.data = NULL;
-	msg.data_len = 0;
-	ipmi_request_supply_msgs(watchdog_user,
-				 (struct ipmi_addr *) &addr,
-				 0,
-				 &msg,
-				 NULL,
-				 &panic_halt_heartbeat_smi_msg,
-				 &panic_halt_heartbeat_recv_msg,
-				 1);
-}
-
 static struct watchdog_info ident =
 {
 	.options	= 0,	/* WDIOF_SETTIMEOUT, */
@@ -895,7 +916,6 @@
 {
 	int rv = -EBUSY;
 
-	down_write(&register_sem);
 	if (watchdog_user)
 		goto out;
 
@@ -921,15 +941,56 @@
 		printk(KERN_CRIT PFX "Unable to register misc device\n");
 	}
 
- out:
-	up_write(&register_sem);
+#ifdef HAVE_DIE_NMI
+	if (nmi_handler_registered) {
+		int old_pretimeout = pretimeout;
+		int old_timeout = timeout;
+		int old_preop_val = preop_val;
 
+		/* Set the pretimeout to go off in a second and give
+		   ourselves plenty of time to stop the timer. */
+		ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
+		preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */
+		pretimeout = 99;
+		timeout = 100;
+
+		testing_nmi = 1;
+
+		rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
+		if (rv) {
+			printk(KERN_WARNING PFX "Error starting timer to"
+			       " test NMI: 0x%x.  The NMI pretimeout will"
+			       " likely not work\n", rv);
+			rv = 0;
+			goto out_restore;
+		}
+
+		msleep(1500);
+
+		if (testing_nmi != 2) {
+			printk(KERN_WARNING PFX "IPMI NMI didn't seem to"
+			       " occur.  The NMI pretimeout will"
+			       " likely not work\n");
+		}
+	out_restore:
+		testing_nmi = 0;
+		preop_val = old_preop_val;
+		pretimeout = old_pretimeout;
+		timeout = old_timeout;
+	}
+#endif
+
+ out:
 	if ((start_now) && (rv == 0)) {
 		/* Run from startup, so start the timer now. */
 		start_now = 0; /* Disable this function after first startup. */
 		ipmi_watchdog_state = action_val;
 		ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
 		printk(KERN_INFO PFX "Starting now!\n");
+	} else {
+		/* Stop the timer now. */
+		ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
+		ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
 	}
 }
 
@@ -937,8 +998,6 @@
 {
 	int rv;
 
-	down_write(&register_sem);
-
 	if (!watchdog_user)
 		goto out;
 
@@ -963,20 +1022,44 @@
 	watchdog_user = NULL;
 
  out:
-	up_write(&register_sem);
+	return;
 }
 
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI
 static int
-ipmi_nmi(void *dev_id, int cpu, int handled)
+ipmi_nmi(struct notifier_block *self, unsigned long val, void *data)
 {
+	struct die_args *args = data;
+
+	if (val != DIE_NMI)
+		return NOTIFY_OK;
+
+	/* Hack, if it's a memory or I/O error, ignore it. */
+	if (args->err & 0xc0)
+		return NOTIFY_OK;
+
+	/*
+	 * If we get here, it's an NMI that's not a memory or I/O
+	 * error.  We can't truly tell if it's from IPMI or not
+	 * without sending a message, and sending a message is almost
+	 * impossible because of locking.
+	 */
+
+	if (testing_nmi) {
+		testing_nmi = 2;
+		return NOTIFY_STOP;
+	}
+
         /* If we are not expecting a timeout, ignore it. */
 	if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
-		return NOTIFY_DONE;
+		return NOTIFY_OK;
+
+	if (preaction_val != WDOG_PRETIMEOUT_NMI)
+		return NOTIFY_OK;
 
 	/* If no one else handled the NMI, we assume it was the IPMI
            watchdog. */
-	if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) {
+	if (preop_val == WDOG_PREOP_PANIC) {
 		/* On some machines, the heartbeat will give
 		   an error and not work unless we re-enable
 		   the timer.   So do so. */
@@ -985,18 +1068,12 @@
 			panic(PFX "pre-timeout");
 	}
 
-	return NOTIFY_DONE;
+	return NOTIFY_STOP;
 }
 
-static struct nmi_handler ipmi_nmi_handler =
-{
-	.link     = LIST_HEAD_INIT(ipmi_nmi_handler.link),
-	.dev_name = "ipmi_watchdog",
-	.dev_id   = NULL,
-	.handler  = ipmi_nmi,
-	.priority = 0, /* Call us last. */
+static struct notifier_block ipmi_nmi_handler = {
+	.notifier_call = ipmi_nmi
 };
-int nmi_handler_registered;
 #endif
 
 static int wdog_reboot_handler(struct notifier_block *this,
@@ -1009,7 +1086,7 @@
 		/* Make sure we only do this once. */
 		reboot_event_handled = 1;
 
-		if (code == SYS_DOWN || code == SYS_HALT) {
+		if (code == SYS_POWER_OFF || code == SYS_HALT) {
 			/* Disable the WDT if we are shutting down. */
 			ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
 			panic_halt_ipmi_set_timeout();
@@ -1113,7 +1190,7 @@
 		preaction_val = WDOG_PRETIMEOUT_NONE;
 	else if (strcmp(inval, "pre_smi") == 0)
 		preaction_val = WDOG_PRETIMEOUT_SMI;
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI
 	else if (strcmp(inval, "pre_nmi") == 0)
 		preaction_val = WDOG_PRETIMEOUT_NMI;
 #endif
@@ -1147,7 +1224,7 @@
 
 static void check_parms(void)
 {
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI
 	int do_nmi = 0;
 	int rv;
 
@@ -1160,20 +1237,9 @@
 			preop_op("preop_none", NULL);
 			do_nmi = 0;
 		}
-#ifdef CONFIG_X86_LOCAL_APIC
-		if (nmi_watchdog == NMI_IO_APIC) {
-			printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC"
-			       " mode (value is %d), that is incompatible"
-			       " with using NMI in the IPMI watchdog."
-			       " Disabling IPMI nmi pretimeout.\n",
-			       nmi_watchdog);
-			preaction_val = WDOG_PRETIMEOUT_NONE;
-			do_nmi = 0;
-		}
-#endif
 	}
 	if (do_nmi && !nmi_handler_registered) {
-		rv = request_nmi(&ipmi_nmi_handler);
+		rv = register_die_notifier(&ipmi_nmi_handler);
 		if (rv) {
 			printk(KERN_WARNING PFX
 			       "Can't register nmi handler\n");
@@ -1181,7 +1247,7 @@
 		} else
 			nmi_handler_registered = 1;
 	} else if (!do_nmi && nmi_handler_registered) {
-		release_nmi(&ipmi_nmi_handler);
+		unregister_die_notifier(&ipmi_nmi_handler);
 		nmi_handler_registered = 0;
 	}
 #endif
@@ -1217,9 +1283,9 @@
 
 	rv = ipmi_smi_watcher_register(&smi_watcher);
 	if (rv) {
-#ifdef HAVE_NMI_HANDLER
-		if (preaction_val == WDOG_PRETIMEOUT_NMI)
-			release_nmi(&ipmi_nmi_handler);
+#ifdef HAVE_DIE_NMI
+		if (nmi_handler_registered)
+			unregister_die_notifier(&ipmi_nmi_handler);
 #endif
 		atomic_notifier_chain_unregister(&panic_notifier_list,
 						 &wdog_panic_notifier);
@@ -1238,9 +1304,9 @@
 	ipmi_smi_watcher_unregister(&smi_watcher);
 	ipmi_unregister_watchdog(watchdog_ifnum);
 
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI
 	if (nmi_handler_registered)
-		release_nmi(&ipmi_nmi_handler);
+		unregister_die_notifier(&ipmi_nmi_handler);
 #endif
 
 	atomic_notifier_chain_unregister(&panic_notifier_list,
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 77a7a4a..85d596a 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1529,7 +1529,7 @@
 	portcount = inw(base + 0x2);
 	if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 &&
 				portcount != 8 && portcount != 16)) {
-		dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.",
+		dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
 			card + 1);
 		retval = -EIO;
 		goto end;
@@ -1622,7 +1622,9 @@
 
 		if ((status = inw(base + 0x4)) != 0) {
 			dev_warn(&pdev->dev, "Card%d rejected load header:\n"
-				"Address:0x%x\nCount:0x%x\nStatus:0x%x\n",
+				KERN_WARNING "Address:0x%x\n"
+				KERN_WARNING "Count:0x%x\n"
+				KERN_WARNING "Status:0x%x\n",
 				index + 1, frame->addr, frame->count, status);
 			goto errrelfw;
 		}
@@ -1666,7 +1668,9 @@
 
 		if ((status = inw(base + 0x4)) != 0) {
 			dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
-				"Address:0x%x\nCount:0x%x\nStatus: 0x%x\n",
+				KERN_WARNING "Address:0x%x\n"
+				KERN_WARNING "Count:0x%x\n"
+				KERN_WARNING "Status: 0x%x\n",
 				index + 1, frame->addr, frame->count, status);
 			goto errrelfw;
 		}
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 212276a..fc54d23 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -42,6 +42,7 @@
 #include <linux/sysrq.h>
 #include <linux/input.h>
 #include <linux/reboot.h>
+#include <linux/notifier.h>
 
 extern void ctrl_alt_del(void);
 
@@ -81,7 +82,8 @@
 typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
 			    char up_flag);
 static k_handler_fn K_HANDLERS;
-static k_handler_fn *k_handler[16] = { K_HANDLERS };
+k_handler_fn *k_handler[16] = { K_HANDLERS };
+EXPORT_SYMBOL_GPL(k_handler);
 
 #define FN_HANDLERS\
 	fn_null,	fn_enter,	fn_show_ptregs,	fn_show_mem,\
@@ -127,7 +129,7 @@
  */
 
 static struct input_handler kbd_handler;
-static unsigned long key_down[NBITS(KEY_MAX)];		/* keyboard key bitmap */
+static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)];	/* keyboard key bitmap */
 static unsigned char shift_down[NR_SHIFT];		/* shift state counters.. */
 static int dead_key_next;
 static int npadch = -1;					/* -1 or number assembled on pad */
@@ -160,6 +162,23 @@
 static int sysrq_alt;
 
 /*
+ * Notifier list for console keyboard events
+ */
+static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list);
+
+int register_keyboard_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_register(&keyboard_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_keyboard_notifier);
+
+int unregister_keyboard_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
+
+/*
  * Translation of scancodes to keycodes. We set them on only the first
  * keyboard in the list that accepts the scancode and keycode.
  * Explanation for not choosing the first attached keyboard anymore:
@@ -1130,6 +1149,7 @@
 	unsigned char type, raw_mode;
 	struct tty_struct *tty;
 	int shift_final;
+	struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
 
 	tty = vc->vc_tty;
 
@@ -1217,10 +1237,11 @@
 		return;
 	}
 
-	shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
+	param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
 	key_map = key_maps[shift_final];
 
-	if (!key_map) {
+	if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYCODE, &param) == NOTIFY_STOP || !key_map) {
+		atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNBOUND_KEYCODE, &param);
 		compute_shiftstate();
 		kbd->slockstate = 0;
 		return;
@@ -1237,6 +1258,9 @@
 	type = KTYP(keysym);
 
 	if (type < 0xf0) {
+		param.value = keysym;
+		if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNICODE, &param) == NOTIFY_STOP)
+			return;
 		if (down && !raw_mode)
 			to_utf8(vc, keysym);
 		return;
@@ -1244,9 +1268,6 @@
 
 	type -= 0xf0;
 
-	if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
-		return;
-
 	if (type == KT_LETTER) {
 		type = KT_LATIN;
 		if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
@@ -1255,9 +1276,18 @@
 				keysym = key_map[keycode];
 		}
 	}
+	param.value = keysym;
+
+	if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYSYM, &param) == NOTIFY_STOP)
+		return;
+
+	if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
+		return;
 
 	(*k_handler[type])(vc, keysym & 0xff, !down);
 
+	atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, &param);
+
 	if (type != KT_SLOCK)
 		kbd->slockstate = 0;
 }
@@ -1347,12 +1377,12 @@
 static const struct input_device_id kbd_ids[] = {
 	{
                 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
-                .evbit = { BIT(EV_KEY) },
+                .evbit = { BIT_MASK(EV_KEY) },
         },
 
 	{
                 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
-                .evbit = { BIT(EV_SND) },
+                .evbit = { BIT_MASK(EV_SND) },
         },
 
 	{ },    /* Terminating entry */
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index ed76f0a..2fc255a 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -41,6 +41,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/completion.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -142,7 +143,7 @@
 	struct tty_struct *tty;
 	int cflag;
 	wait_queue_head_t open_wait;
-	wait_queue_head_t close_wait;
+	struct completion close_wait;
 
 	struct timer_list emptyTimer;
 
@@ -166,7 +167,6 @@
 
 #define WAKEUP_CHARS		256
 
-static int verbose = 0;
 static int ttymajor = MOXAMAJOR;
 /* Variables for insmod */
 #ifdef MODULE
@@ -184,7 +184,6 @@
 module_param_array(numports, int, NULL, 0);
 #endif
 module_param(ttymajor, int, 0);
-module_param(verbose, bool, 0644);
 
 /*
  * static functions:
@@ -208,13 +207,13 @@
 static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
 			 unsigned int set, unsigned int clear);
 static void moxa_poll(unsigned long);
-static void set_tty_param(struct tty_struct *);
-static int block_till_ready(struct tty_struct *, struct file *,
+static void moxa_set_tty_param(struct tty_struct *);
+static int moxa_block_till_ready(struct tty_struct *, struct file *,
 			    struct moxa_port *);
-static void setup_empty_event(struct tty_struct *);
-static void check_xmit_empty(unsigned long);
-static void shut_down(struct moxa_port *);
-static void receive_data(struct moxa_port *);
+static void moxa_setup_empty_event(struct tty_struct *);
+static void moxa_check_xmit_empty(unsigned long);
+static void moxa_shut_down(struct moxa_port *);
+static void moxa_receive_data(struct moxa_port *);
 /*
  * moxa board interface functions:
  */
@@ -283,8 +282,10 @@
 	int retval;
 
 	retval = pci_enable_device(pdev);
-	if (retval)
+	if (retval) {
+		dev_err(&pdev->dev, "can't enable pci device\n");
 		goto err;
+	}
 
 	for (i = 0; i < MAX_BOARDS; i++)
 		if (moxa_boards[i].basemem == NULL)
@@ -292,16 +293,17 @@
 
 	retval = -ENODEV;
 	if (i >= MAX_BOARDS) {
-		if (verbose)
-			printk("More than %d MOXA Intellio family boards "
+		dev_warn(&pdev->dev, "more than %u MOXA Intellio family boards "
 				"found. Board is ignored.\n", MAX_BOARDS);
 		goto err;
 	}
 
 	board = &moxa_boards[i];
 	board->basemem = pci_iomap(pdev, 2, 0x4000);
-	if (board->basemem == NULL)
+	if (board->basemem == NULL) {
+		dev_err(&pdev->dev, "can't remap io space 2\n");
 		goto err;
+	}
 
 	board->boardType = board_type;
 	switch (board_type) {
@@ -347,7 +349,8 @@
 	int i, numBoards, retval = 0;
 	struct moxa_port *ch;
 
-	printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION);
+	printk(KERN_INFO "MOXA Intellio family driver version %s\n",
+			MOXA_VERSION);
 	moxaDriver = alloc_tty_driver(MAX_PORTS + 1);
 	if (!moxaDriver)
 		return -ENOMEM;
@@ -372,13 +375,13 @@
 		ch->closing_wait = 30 * HZ;
 		ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
 		init_waitqueue_head(&ch->open_wait);
-		init_waitqueue_head(&ch->close_wait);
+		init_completion(&ch->close_wait);
 
-		setup_timer(&ch->emptyTimer, check_xmit_empty,
+		setup_timer(&ch->emptyTimer, moxa_check_xmit_empty,
 				(unsigned long)ch);
 	}
 
-	printk("Tty devices major number = %d\n", ttymajor);
+	pr_debug("Moxa tty devices major number = %d\n", ttymajor);
 
 	if (tty_register_driver(moxaDriver)) {
 		printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n");
@@ -400,11 +403,10 @@
 				moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts;
 			moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;
 			moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr;
-			if (verbose)
-				printk("Board %2d: %s board(baseAddr=%lx)\n",
-				       numBoards + 1,
-				       moxa_brdname[moxa_boards[numBoards].boardType - 1],
-				       moxa_boards[numBoards].baseAddr);
+			pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",
+			       numBoards + 1,
+			       moxa_brdname[moxa_boards[numBoards].boardType-1],
+			       moxa_boards[numBoards].baseAddr);
 			numBoards++;
 		}
 	}
@@ -413,14 +415,13 @@
 	for (i = 0; i < MAX_BOARDS; i++) {
 		if ((type[i] == MOXA_BOARD_C218_ISA) ||
 		    (type[i] == MOXA_BOARD_C320_ISA)) {
-			if (verbose)
-				printk("Board %2d: %s board(baseAddr=%lx)\n",
-				       numBoards + 1,
-				       moxa_brdname[type[i] - 1],
-				       (unsigned long) baseaddr[i]);
+			pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",
+			       numBoards + 1, moxa_brdname[type[i] - 1],
+			       (unsigned long)baseaddr[i]);
 			if (numBoards >= MAX_BOARDS) {
-				if (verbose)
-					printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS);
+				printk(KERN_WARNING "More than %d MOXA "
+					"Intellio family boards found. Board "
+					"is ignored.\n", MAX_BOARDS);
 				continue;
 			}
 			moxa_boards[numBoards].boardType = type[i];
@@ -456,16 +457,14 @@
 {
 	int i;
 
-	if (verbose)
-		printk("Unloading module moxa ...\n");
-
 	del_timer_sync(&moxaTimer);
 
 	for (i = 0; i < MAX_PORTS; i++)
 		del_timer_sync(&moxa_ports[i].emptyTimer);
 
 	if (tty_unregister_driver(moxaDriver))
-		printk("Couldn't unregister MOXA Intellio family serial driver\n");
+		printk(KERN_ERR "Couldn't unregister MOXA Intellio family "
+				"serial driver\n");
 	put_tty_driver(moxaDriver);
 
 #ifdef CONFIG_PCI
@@ -475,9 +474,6 @@
 	for (i = 0; i < MAX_BOARDS; i++)
 		if (moxa_boards[i].basemem)
 			iounmap(moxa_boards[i].basemem);
-
-	if (verbose)
-		printk("Done\n");
 }
 
 module_init(moxa_init);
@@ -504,12 +500,12 @@
 	ch->tty = tty;
 	if (!(ch->asyncflags & ASYNC_INITIALIZED)) {
 		ch->statusflags = 0;
-		set_tty_param(tty);
+		moxa_set_tty_param(tty);
 		MoxaPortLineCtrl(ch->port, 1, 1);
 		MoxaPortEnable(ch->port);
 		ch->asyncflags |= ASYNC_INITIALIZED;
 	}
-	retval = block_till_ready(tty, filp, ch);
+	retval = moxa_block_till_ready(tty, filp, ch);
 
 	moxa_unthrottle(tty);
 
@@ -532,9 +528,7 @@
 		return;
 	}
 	if (!MoxaPortIsValid(port)) {
-#ifdef SERIAL_DEBUG_CLOSE
-		printk("Invalid portno in moxa_close\n");
-#endif
+		pr_debug("Invalid portno in moxa_close\n");
 		tty->driver_data = NULL;
 		return;
 	}
@@ -547,13 +541,13 @@
 	ch = (struct moxa_port *) tty->driver_data;
 
 	if ((tty->count == 1) && (ch->count != 1)) {
-		printk("moxa_close: bad serial port count; tty->count is 1, "
-		       "ch->count is %d\n", ch->count);
+		printk(KERN_WARNING "moxa_close: bad serial port count; "
+			"tty->count is 1, ch->count is %d\n", ch->count);
 		ch->count = 1;
 	}
 	if (--ch->count < 0) {
-		printk("moxa_close: bad serial port count, device=%s\n",
-		       tty->name);
+		printk(KERN_WARNING "moxa_close: bad serial port count, "
+			"device=%s\n", tty->name);
 		ch->count = 0;
 	}
 	if (ch->count) {
@@ -563,11 +557,11 @@
 
 	ch->cflag = tty->termios->c_cflag;
 	if (ch->asyncflags & ASYNC_INITIALIZED) {
-		setup_empty_event(tty);
+		moxa_setup_empty_event(tty);
 		tty_wait_until_sent(tty, 30 * HZ);	/* 30 seconds timeout */
 		del_timer_sync(&moxa_ports[ch->port].emptyTimer);
 	}
-	shut_down(ch);
+	moxa_shut_down(ch);
 	MoxaPortFlushData(port, 2);
 
 	if (tty->driver->flush_buffer)
@@ -584,7 +578,7 @@
 		wake_up_interruptible(&ch->open_wait);
 	}
 	ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
-	wake_up_interruptible(&ch->close_wait);
+	complete_all(&ch->close_wait);
 }
 
 static int moxa_write(struct tty_struct *tty,
@@ -653,7 +647,7 @@
 		 * in tty_ioctl.c, etc.
 		 */
 		if (!(ch->statusflags & EMPTYWAIT))
-			setup_empty_event(tty);
+			moxa_setup_empty_event(tty);
 	}
 	return (chars);
 }
@@ -751,7 +745,7 @@
 		retval = tty_check_change(tty);
 		if (retval)
 			return (retval);
-		setup_empty_event(tty);
+		moxa_setup_empty_event(tty);
 		tty_wait_until_sent(tty, 0);
 		if (!arg)
 			MoxaPortSendBreak(ch->port, 0);
@@ -760,7 +754,7 @@
 		retval = tty_check_change(tty);
 		if (retval)
 			return (retval);
-		setup_empty_event(tty);
+		moxa_setup_empty_event(tty);
 		tty_wait_until_sent(tty, 0);
 		MoxaPortSendBreak(ch->port, arg);
 		return (0);
@@ -809,7 +803,7 @@
 
 	if (ch == NULL)
 		return;
-	set_tty_param(tty);
+	moxa_set_tty_param(tty);
 	if (!(old_termios->c_cflag & CLOCAL) &&
 	    (tty->termios->c_cflag & CLOCAL))
 		wake_up_interruptible(&ch->open_wait);
@@ -845,7 +839,7 @@
 	struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
 
 	moxa_flush_buffer(tty);
-	shut_down(ch);
+	moxa_shut_down(ch);
 	ch->event = 0;
 	ch->count = 0;
 	ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
@@ -875,7 +869,7 @@
 				continue;
 			if (!(ch->statusflags & THROTTLE) &&
 			    (MoxaPortRxQueue(ch->port) > 0))
-				receive_data(ch);
+				moxa_receive_data(ch);
 			if ((tp = ch->tty) == 0)
 				continue;
 			if (ch->statusflags & LOWWAIT) {
@@ -909,7 +903,7 @@
 
 /******************************************************************************/
 
-static void set_tty_param(struct tty_struct *tty)
+static void moxa_set_tty_param(struct tty_struct *tty)
 {
 	register struct ktermios *ts;
 	struct moxa_port *ch;
@@ -934,7 +928,7 @@
 	MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty));
 }
 
-static int block_till_ready(struct tty_struct *tty, struct file *filp,
+static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
 			    struct moxa_port *ch)
 {
 	DECLARE_WAITQUEUE(wait,current);
@@ -948,7 +942,7 @@
 	 */
 	if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) {
 		if (ch->asyncflags & ASYNC_CLOSING)
-			interruptible_sleep_on(&ch->close_wait);
+			wait_for_completion_interruptible(&ch->close_wait);
 #ifdef SERIAL_DO_RESTART
 		if (ch->asyncflags & ASYNC_HUP_NOTIFY)
 			return (-EAGAIN);
@@ -971,10 +965,8 @@
 	 */
 	retval = 0;
 	add_wait_queue(&ch->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready before block: ttys%d, count = %d\n",
-	       ch->line, ch->count);
-#endif
+	pr_debug("block_til_ready before block: ttys%d, count = %d\n",
+		ch->port, ch->count);
 	spin_lock_irqsave(&moxa_lock, flags);
 	if (!tty_hung_up_p(filp))
 		ch->count--;
@@ -1013,10 +1005,8 @@
 		ch->count++;
 	ch->blocked_open--;
 	spin_unlock_irqrestore(&moxa_lock, flags);
-#ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready after blocking: ttys%d, count = %d\n",
-	       ch->line, ch->count);
-#endif
+	pr_debug("block_til_ready after blocking: ttys%d, count = %d\n",
+		ch->port, ch->count);
 	if (retval)
 		return (retval);
 	/* FIXME: review to see if we need to use set_bit on these */
@@ -1024,7 +1014,7 @@
 	return 0;
 }
 
-static void setup_empty_event(struct tty_struct *tty)
+static void moxa_setup_empty_event(struct tty_struct *tty)
 {
 	struct moxa_port *ch = tty->driver_data;
 	unsigned long flags;
@@ -1035,24 +1025,24 @@
 	spin_unlock_irqrestore(&moxa_lock, flags);
 }
 
-static void check_xmit_empty(unsigned long data)
+static void moxa_check_xmit_empty(unsigned long data)
 {
 	struct moxa_port *ch;
 
 	ch = (struct moxa_port *) data;
-	del_timer_sync(&moxa_ports[ch->port].emptyTimer);
 	if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
 		if (MoxaPortTxQueue(ch->port) == 0) {
 			ch->statusflags &= ~EMPTYWAIT;
 			tty_wakeup(ch->tty);
 			return;
 		}
-		mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ);
+		mod_timer(&moxa_ports[ch->port].emptyTimer,
+				round_jiffies(jiffies + HZ));
 	} else
 		ch->statusflags &= ~EMPTYWAIT;
 }
 
-static void shut_down(struct moxa_port *ch)
+static void moxa_shut_down(struct moxa_port *ch)
 {
 	struct tty_struct *tp;
 
@@ -1072,7 +1062,7 @@
 	ch->asyncflags &= ~ASYNC_INITIALIZED;
 }
 
-static void receive_data(struct moxa_port *ch)
+static void moxa_receive_data(struct moxa_port *ch)
 {
 	struct tty_struct *tp;
 	struct ktermios *ts;
@@ -1406,8 +1396,8 @@
 static int moxaFuncTout = HZ / 2;
 
 static void moxafunc(void __iomem *, int, ushort);
-static void wait_finish(void __iomem *);
-static void low_water_check(void __iomem *);
+static void moxa_wait_finish(void __iomem *);
+static void moxa_low_water_check(void __iomem *);
 static int moxaloadbios(int, unsigned char __user *, int);
 static int moxafindcard(int);
 static int moxaload320b(int, unsigned char __user *, int);
@@ -1473,7 +1463,7 @@
 	moxafunc(ofsAddr, FC_FlushQueue, mode);
 	if (mode != 1) {
 		moxa_ports[port].lowChkFlag = 0;
-		low_water_check(ofsAddr);
+		moxa_low_water_check(ofsAddr);
 	}
 }
 
@@ -1654,7 +1644,7 @@
 				if (moxa_ports[p].lowChkFlag) {
 					moxa_ports[p].lowChkFlag = 0;
 					ofsAddr = moxa_ports[p].tableAddr;
-					low_water_check(ofsAddr);
+					moxa_low_water_check(ofsAddr);
 				}
 			}
 		}
@@ -2081,7 +2071,7 @@
 		writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);
 		writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
 		writeb(FC_SetXonXoff, ofsAddr + FuncCode);
-		wait_finish(ofsAddr);
+		moxa_wait_finish(ofsAddr);
 
 	}
 	return (0);
@@ -2480,10 +2470,10 @@
 
 	writew(arg, ofsAddr + FuncArg);
 	writew(cmd, ofsAddr + FuncCode);
-	wait_finish(ofsAddr);
+	moxa_wait_finish(ofsAddr);
 }
 
-static void wait_finish(void __iomem *ofsAddr)
+static void moxa_wait_finish(void __iomem *ofsAddr)
 {
 	unsigned long i, j;
 
@@ -2496,7 +2486,7 @@
 	}
 }
 
-static void low_water_check(void __iomem *ofsAddr)
+static void moxa_low_water_check(void __iomem *ofsAddr)
 {
 	int len;
 	ushort rptr, wptr, mask;
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 2aee3fe..fd0abef 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -56,11 +56,11 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 
 #include "mxser.h"
@@ -383,7 +383,6 @@
 
 /* static void   mxser_poll(unsigned long); */
 static int mxser_get_ISA_conf(int, struct mxser_hwconf *);
-static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *);
 static void mxser_do_softint(struct work_struct *);
 static int mxser_open(struct tty_struct *, struct file *);
 static void mxser_close(struct tty_struct *, struct file *);
@@ -422,7 +421,7 @@
 static void mxser_startrx(struct tty_struct *tty);
 static void mxser_stoprx(struct tty_struct *tty);
 
-
+#ifdef CONFIG_PCI
 static int CheckIsMoxaMust(int io)
 {
 	u8 oldmcr, hwid;
@@ -445,6 +444,7 @@
 	}
 	return MOXA_OTHER_UART;
 }
+#endif
 
 /* above is modified by Victor Yu. 08-15-2002 */
 
@@ -1938,14 +1938,6 @@
 				inb(info->base + UART_MSR);
 				continue;
 			}
-			/* above add by Victor Yu. 09-13-2002 */
-			/*
-			   if (info->tty->flip.count < TTY_FLIPBUF_SIZE / 4) {
-			   info->IER |= MOXA_MUST_RECV_ISR;
-			   outb(info->IER, info->base + UART_IER);
-			   }
-			 */
-
 
 			/* mask by Victor Yu. 09-13-2002
 			   if ( !info->tty ||
@@ -2599,19 +2591,8 @@
 		info->IER |= UART_IER_MSI;
 		if ((info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) {
 			info->MCR |= UART_MCR_AFE;
-			/* status = mxser_get_msr(info->base, 0, info->port); */
-/*
-	save_flags(flags);
-	cli();
-	status = inb(baseaddr + UART_MSR);
-	restore_flags(flags);
-*/
-			/* mxser_check_modem_status(info, status); */
 		} else {
-			/* status = mxser_get_msr(info->base, 0, info->port); */
-			/* MX_LOCK(&info->slock); */
 			status = inb(info->base + UART_MSR);
-			/* MX_UNLOCK(&info->slock); */
 			if (info->tty->hw_stopped) {
 				if (status & UART_MSR_CTS) {
 					info->tty->hw_stopped = 0;
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
index 6a56393..081c84c 100644
--- a/drivers/char/mxser_new.c
+++ b/drivers/char/mxser_new.c
@@ -2,7 +2,7 @@
  *          mxser.c  -- MOXA Smartio/Industio family multiport serial driver.
  *
  *      Copyright (C) 1999-2006  Moxa Technologies (support@moxa.com.tw).
- *	Copyright (C) 2006       Jiri Slaby <jirislaby@gmail.com>
+ *	Copyright (C) 2006-2007  Jiri Slaby <jirislaby@gmail.com>
  *
  *      This code is loosely based on the 1.8 moxa driver which is based on
  *	Linux serial driver, written by Linus Torvalds, Theodore T'so and
@@ -39,16 +39,16 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 
 #include "mxser_new.h"
 
-#define	MXSER_VERSION	"2.0.1"		/* 1.9.15 */
+#define	MXSER_VERSION	"2.0.2"		/* 1.10 */
 #define	MXSERMAJOR	 174
 #define	MXSERCUMAJOR	 175
 
@@ -72,6 +72,12 @@
 #define UART_MCR_AFE		0x20
 #define UART_LSR_SPECIAL	0x1E
 
+#define PCI_DEVICE_ID_CB108	0x1080
+#define PCI_DEVICE_ID_CB114	0x1142
+#define PCI_DEVICE_ID_CB134I	0x1341
+#define PCI_DEVICE_ID_CP138U	0x1380
+#define PCI_DEVICE_ID_POS104UL	0x1044
+
 
 #define C168_ASIC_ID    1
 #define C104_ASIC_ID    2
@@ -107,71 +113,63 @@
 };
 
 static const struct mxser_cardinfo mxser_cards[] = {
-	{ 8, "C168 series", },			/* C168-ISA */
-	{ 4, "C104 series", },			/* C104-ISA */
-	{ 4, "CI-104J series", },		/* CI104J */
-	{ 8, "C168H/PCI series", },		/* C168-PCI */
-	{ 4, "C104H/PCI series", },		/* C104-PCI */
-	{ 4, "C102 series", MXSER_HAS2 },	/* C102-ISA */
-	{ 4, "CI-132 series", MXSER_HAS2 },	/* CI132 */
-	{ 4, "CI-134 series", },		/* CI134 */
-	{ 2, "CP-132 series", },		/* CP132 */
-	{ 4, "CP-114 series", },		/* CP114 */
-	{ 4, "CT-114 series", },		/* CT114 */
-	{ 2, "CP-102 series", MXSER_HIGHBAUD },	/* CP102 */
-	{ 4, "CP-104U series", },		/* CP104U */
-	{ 8, "CP-168U series", },		/* CP168U */
-	{ 2, "CP-132U series", },		/* CP132U */
-	{ 4, "CP-134U series", },		/* CP134U */
-	{ 4, "CP-104JU series", },		/* CP104JU */
+/* 0*/	{ 8, "C168 series", },
+	{ 4, "C104 series", },
+	{ 4, "CI-104J series", },
+	{ 8, "C168H/PCI series", },
+	{ 4, "C104H/PCI series", },
+/* 5*/	{ 4, "C102 series", MXSER_HAS2 },	/* C102-ISA */
+	{ 4, "CI-132 series", MXSER_HAS2 },
+	{ 4, "CI-134 series", },
+	{ 2, "CP-132 series", },
+	{ 4, "CP-114 series", },
+/*10*/	{ 4, "CT-114 series", },
+	{ 2, "CP-102 series", MXSER_HIGHBAUD },
+	{ 4, "CP-104U series", },
+	{ 8, "CP-168U series", },
+	{ 2, "CP-132U series", },
+/*15*/	{ 4, "CP-134U series", },
+	{ 4, "CP-104JU series", },
 	{ 8, "Moxa UC7000 Serial", },		/* RC7000 */
-	{ 8, "CP-118U series", },		/* CP118U */
-	{ 2, "CP-102UL series", },		/* CP102UL */
-	{ 2, "CP-102U series", },		/* CP102U */
-	{ 8, "CP-118EL series", },		/* CP118EL */
-	{ 8, "CP-168EL series", },		/* CP168EL */
-	{ 4, "CP-104EL series", }		/* CP104EL */
+	{ 8, "CP-118U series", },
+	{ 2, "CP-102UL series", },
+/*20*/	{ 2, "CP-102U series", },
+	{ 8, "CP-118EL series", },
+	{ 8, "CP-168EL series", },
+	{ 4, "CP-104EL series", },
+	{ 8, "CB-108 series", },
+/*25*/	{ 4, "CB-114 series", },
+	{ 4, "CB-134I series", },
+	{ 8, "CP-138U series", },
+	{ 4, "POS-104UL series", }
 };
 
 /* driver_data correspond to the lines in the structure above
    see also ISA probe function before you change something */
 static struct pci_device_id mxser_pcibrds[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168),
-		.driver_data = 3 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104),
-		.driver_data = 4 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132),
-		.driver_data = 8 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114),
-		.driver_data = 9 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114),
-		.driver_data = 10 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102),
-		.driver_data = 11 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U),
-		.driver_data = 12 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U),
-		.driver_data = 13 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U),
-		.driver_data = 14 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U),
-		.driver_data = 15 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU),
-		.driver_data = 16 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000),
-		.driver_data = 17 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U),
-		.driver_data = 18 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL),
-		.driver_data = 19 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U),
-		.driver_data = 20 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL),
-		.driver_data = 21 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL),
-		.driver_data = 22 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL),
-		.driver_data = 23 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168),	.driver_data = 3 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104),	.driver_data = 4 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132),	.driver_data = 8 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114),	.driver_data = 9 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CT114),	.driver_data = 10 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102),	.driver_data = 11 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U),	.driver_data = 12 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U),	.driver_data = 13 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U),	.driver_data = 14 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U),	.driver_data = 15 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 16 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000),	.driver_data = 17 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U),	.driver_data = 18 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 19 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U),	.driver_data = 20 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 21 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 22 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 23 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108),	.driver_data = 24 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114),	.driver_data = 25 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I),	.driver_data = 26 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U),	.driver_data = 27 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL),	.driver_data = 28 },
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 0380569..596c717 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -437,7 +437,7 @@
  *	@c: character input
  *	@tty: terminal device
  *
- *	Perform erase and neccessary output when an erase character is
+ *	Perform erase and necessary output when an erase character is
  *	present in the stream from the driver layer. Handles the complexities
  *	of UTF-8 multibyte symbols.
  */
@@ -657,7 +657,7 @@
  *	@c: character
  *
  *	Process a parity error and queue the right data to indicate
- *	the error case if neccessary. Locking as per n_tty_receive_buf.
+ *	the error case if necessary. Locking as per n_tty_receive_buf.
  */
 static inline void n_tty_receive_parity_error(struct tty_struct *tty,
 					      unsigned char c)
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 73de771..706ff347 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -318,7 +318,7 @@
 static int pty_limit_min = 0;
 static int pty_limit_max = NR_UNIX98_PTY_MAX;
 
-ctl_table pty_table[] = {
+static struct ctl_table pty_table[] = {
 	{
 		.ctl_name	= PTY_MAX,
 		.procname	= "max",
@@ -340,6 +340,27 @@
 	}
 };
 
+static struct ctl_table pty_kern_table[] = {
+	{
+		.ctl_name	= KERN_PTY,
+		.procname	= "pty",
+		.mode		= 0555,
+		.child		= pty_table,
+	},
+	{}
+};
+
+static struct ctl_table pty_root_table[] = {
+	{
+		.ctl_name	= CTL_KERN,
+		.procname	= "kernel",
+		.mode		= 0555,
+		.child		= pty_kern_table,
+	},
+	{}
+};
+
+
 static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file,
 			    unsigned int cmd, unsigned long arg)
 {
@@ -404,6 +425,7 @@
 		panic("Couldn't register Unix98 pts driver");
 
 	pty_table[1].data = &ptm_driver->refcount;
+	register_sysctl_table(pty_root_table);
 }
 #else
 static inline void unix98_pty_init(void) { }
diff --git a/drivers/char/random.c b/drivers/char/random.c
index af274e5..1756b1f 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -649,7 +649,7 @@
 
 void add_interrupt_randomness(int irq)
 {
-	if (irq >= NR_IRQS || irq_timer_state[irq] == 0)
+	if (irq >= NR_IRQS || irq_timer_state[irq] == NULL)
 		return;
 
 	DEBUG_ENT("irq event %d\n", irq);
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 56cbba7..d83419c 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -84,6 +84,7 @@
 #include <linux/mutex.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
+#include <linux/completion.h>
 #include <linux/wait.h>
 #include <linux/pci.h>
 #include <asm/uaccess.h>
@@ -548,8 +549,8 @@
 static void rp_do_poll(unsigned long dummy)
 {
 	CONTROLLER_t *ctlp;
-	int ctrl, aiop, ch, line, i;
-	unsigned int xmitmask;
+	int ctrl, aiop, ch, line;
+	unsigned int xmitmask, i;
 	unsigned int CtlMask;
 	unsigned char AiopMask;
 	Word_t bit;
@@ -562,7 +563,7 @@
 		/*  Get a ptr to the board's control struct */
 		ctlp = sCtlNumToCtlPtr(ctrl);
 
-		/*  Get the interupt status from the board */
+		/*  Get the interrupt status from the board */
 #ifdef CONFIG_PCI
 		if (ctlp->BusType == isPCI)
 			CtlMask = sPCIGetControllerIntStatus(ctlp);
@@ -650,7 +651,7 @@
 	info->closing_wait = 3000;
 	info->close_delay = 50;
 	init_waitqueue_head(&info->open_wait);
-	init_waitqueue_head(&info->close_wait);
+	init_completion(&info->close_wait);
 	info->flags &= ~ROCKET_MODE_MASK;
 	switch (pc104[board][line]) {
 	case 422:
@@ -699,8 +700,8 @@
 	spin_lock_init(&info->slock);
 	mutex_init(&info->write_mtx);
 	rp_table[line] = info;
-	if (pci_dev)
-		tty_register_device(rocket_driver, line, &pci_dev->dev);
+	tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev :
+			NULL);
 }
 
 /*
@@ -878,7 +879,8 @@
 	if (tty_hung_up_p(filp))
 		return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
 	if (info->flags & ROCKET_CLOSING) {
-		interruptible_sleep_on(&info->close_wait);
+		if (wait_for_completion_interruptible(&info->close_wait))
+			return -ERESTARTSYS;
 		return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
 	}
 
@@ -983,8 +985,10 @@
 		return -ENOMEM;
 
 	if (info->flags & ROCKET_CLOSING) {
-		interruptible_sleep_on(&info->close_wait);
+		retval = wait_for_completion_interruptible(&info->close_wait);
 		free_page(page);
+		if (retval)
+			return retval;
 		return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
 	}
 
@@ -1176,7 +1180,7 @@
 	}
 	info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE);
 	tty->closing = 0;
-	wake_up_interruptible(&info->close_wait);
+	complete_all(&info->close_wait);
 	atomic_dec(&rp_num_ports_open);
 
 #ifdef ROCKET_DEBUG_OPEN
@@ -1869,8 +1873,6 @@
 	int fast_clock = 0;
 	int altChanRingIndicator = 0;
 	int ports_per_aiop = 8;
-	int ret;
-	unsigned int class_rev;
 	WordIO_t ConfigIO = 0;
 	ByteIO_t UPCIRingInd = 0;
 
@@ -1878,12 +1880,6 @@
 		return 0;
 
 	rcktpt_io_addr[i] = pci_resource_start(dev, 0);
-	ret = pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-
-	if (ret) {
-		printk(KERN_INFO "  Error during register_PCI(), unable to read config dword \n");
-		return 0;
-	}
 
 	rcktpt_type[i] = ROCKET_TYPE_NORMAL;
 	rocketModel[i].loadrm2 = 0;
@@ -2037,8 +2033,9 @@
 		ports_per_aiop = 6;
 		str = "6-port";
 
-		/*  If class_rev is 1, the rocketmodem flash must be loaded.  If it is 2 it is a "socketed" version. */
-		if ((class_rev & 0xFF) == 1) {
+		/*  If revision is 1, the rocketmodem flash must be loaded.
+		 *  If it is 2 it is a "socketed" version. */
+		if (dev->revision == 1) {
 			rcktpt_type[i] = ROCKET_TYPE_MODEMII;
 			rocketModel[i].loadrm2 = 1;
 		} else {
@@ -2053,7 +2050,7 @@
 		max_num_aiops = 1;
 		ports_per_aiop = 4;
 		str = "4-port";
-		if ((class_rev & 0xFF) == 1) {
+		if (dev->revision == 1) {
 			rcktpt_type[i] = ROCKET_TYPE_MODEMII;
 			rocketModel[i].loadrm2 = 1;
 		} else {
@@ -2362,26 +2359,14 @@
  */
 static int __init rp_init(void)
 {
-	int retval, pci_boards_found, isa_boards_found, i;
+	int ret = -ENOMEM, pci_boards_found, isa_boards_found, i;
 
 	printk(KERN_INFO "RocketPort device driver module, version %s, %s\n",
 	       ROCKET_VERSION, ROCKET_DATE);
 
 	rocket_driver = alloc_tty_driver(MAX_RP_PORTS);
 	if (!rocket_driver)
-		return -ENOMEM;
-
-	/*
-	 * Initialize the array of pointers to our own internal state
-	 * structures.
-	 */
-	memset(rp_table, 0, sizeof (rp_table));
-	memset(xmit_flags, 0, sizeof (xmit_flags));
-
-	for (i = 0; i < MAX_RP_PORTS; i++)
-		lineNumbers[i] = 0;
-	nextLineNumber = 0;
-	memset(rocketModel, 0, sizeof (rocketModel));
+		goto err;
 
 	/*
 	 *  If board 1 is non-zero, there is at least one ISA configured.  If controller is 
@@ -2396,8 +2381,11 @@
 
 	/*  If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */
 	if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) {
-		printk(KERN_INFO "Unable to reserve IO region for first configured ISA RocketPort controller 0x%lx.  Driver exiting \n", controller);
-		return -EBUSY;
+		printk(KERN_ERR "Unable to reserve IO region for first "
+			"configured ISA RocketPort controller 0x%lx.  "
+			"Driver exiting\n", controller);
+		ret = -EBUSY;
+		goto err_tty;
 	}
 
 	/*  Store ISA variable retrieved from command line or .conf file. */
@@ -2434,15 +2422,14 @@
 	rocket_driver->init_termios.c_ispeed = 9600;
 	rocket_driver->init_termios.c_ospeed = 9600;
 #ifdef ROCKET_SOFT_FLOW
-	rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+	rocket_driver->flags |= TTY_DRIVER_REAL_RAW;
 #endif
 	tty_set_operations(rocket_driver, &rocket_ops);
 
-	retval = tty_register_driver(rocket_driver);
-	if (retval < 0) {
-		printk(KERN_INFO "Couldn't install tty RocketPort driver (error %d)\n", -retval);
-		put_tty_driver(rocket_driver);
-		return -1;
+	ret = tty_register_driver(rocket_driver);
+	if (ret < 0) {
+		printk(KERN_ERR "Couldn't install tty RocketPort driver\n");
+		goto err_tty;
 	}
 
 #ifdef ROCKET_DEBUG_OPEN
@@ -2469,14 +2456,18 @@
 	max_board = pci_boards_found + isa_boards_found;
 
 	if (max_board == 0) {
-		printk(KERN_INFO "No rocketport ports found; unloading driver.\n");
-		del_timer_sync(&rocket_timer);
-		tty_unregister_driver(rocket_driver);
-		put_tty_driver(rocket_driver);
-		return -ENXIO;
+		printk(KERN_ERR "No rocketport ports found; unloading driver\n");
+		ret = -ENXIO;
+		goto err_ttyu;
 	}
 
 	return 0;
+err_ttyu:
+	tty_unregister_driver(rocket_driver);
+err_tty:
+	put_tty_driver(rocket_driver);
+err:
+	return ret;
 }
 
 
@@ -2491,10 +2482,14 @@
 	if (retval)
 		printk(KERN_INFO "Error %d while trying to unregister "
 		       "rocketport driver\n", -retval);
-	put_tty_driver(rocket_driver);
 
 	for (i = 0; i < MAX_RP_PORTS; i++)
-		kfree(rp_table[i]);
+		if (rp_table[i]) {
+			tty_unregister_device(rocket_driver, i);
+			kfree(rp_table[i]);
+		}
+
+	put_tty_driver(rocket_driver);
 
 	for (i = 0; i < NUM_BOARDS; i++) {
 		if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index b4c53df..55b8f2d 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -1163,13 +1163,8 @@
 	int read_status_mask;
 	int cps;
 
-#ifdef DECLARE_WAITQUEUE
 	wait_queue_head_t open_wait;
-	wait_queue_head_t close_wait;
-#else
-	struct wait_queue *open_wait;
-	struct wait_queue *close_wait;
-#endif
+	struct completion close_wait;
 	spinlock_t slock;
 	struct mutex write_mtx;
 };
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 8598585..877e53d 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -7,7 +7,7 @@
  *
  * Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
  *
- * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
  *
  * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
  *
@@ -1178,9 +1178,9 @@
 	jog_dev->id.bustype = BUS_ISA;
 	jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
 
-	jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE);
-	jog_dev->relbit[0] = BIT(REL_WHEEL);
+	jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE);
+	jog_dev->relbit[0] = BIT_MASK(REL_WHEEL);
 
 	sonypi_device.input_key_dev = key_dev = input_allocate_device();
 	if (!key_dev) {
@@ -1193,7 +1193,7 @@
 	key_dev->id.vendor = PCI_VENDOR_ID_SONY;
 
 	/* Initialize the Input Drivers: special keys */
-	key_dev->evbit[0] = BIT(EV_KEY);
+	key_dev->evbit[0] = BIT_MASK(EV_KEY);
 	for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
 		if (sonypi_inputkeys[i].inputev)
 			set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 85a2328..a6e1c9b 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -1467,7 +1467,7 @@
 
 	line = tty->index;
 	sx_dprintk(SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, "
-			"np=%d)\n", current->pid, line, tty,
+			"np=%d)\n", task_pid_nr(current), line, tty,
 			current->signal->tty, sx_nports);
 
 	if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports))
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 78d1493..de60e1e 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -251,7 +251,7 @@
 	struct task_struct *p;
 
 	for_each_process(p) {
-		if (p->mm && !is_init(p))
+		if (p->mm && !is_global_init(p))
 			/* Not swapper, init nor kernel thread */
 			force_sig(sig, p);
 	}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 9c867cf..f36fecd 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -103,6 +103,7 @@
 #include <linux/selection.h>
 
 #include <linux/kmod.h>
+#include <linux/nsproxy.h>
 
 #undef TTY_DEBUG_HANGUP
 
@@ -942,7 +943,7 @@
  *	@tty: terminal to activate ldisc on
  *
  *	Set the TTY_LDISC flag when the line discipline can be called
- *	again. Do neccessary wakeups for existing sleepers.
+ *	again. Do necessary wakeups for existing sleepers.
  *
  *	Note: nobody should set this bit except via this function. Clearing
  *	directly is allowed.
@@ -1503,7 +1504,7 @@
  *
  *	The user has asked via system call for the terminal to be hung up.
  *	We do this synchronously so that when the syscall returns the process
- *	is complete. That guarantee is neccessary for security reasons.
+ *	is complete. That guarantee is necessary for security reasons.
  */
 
 void tty_vhangup(struct tty_struct * tty)
@@ -1690,7 +1691,7 @@
  *	@tty: tty to start
  *
  *	Start a tty that has been stopped if at all possible. Perform
- *	any neccessary wakeups and propagate the TIOCPKT status. If this
+ *	any necessary wakeups and propagate the TIOCPKT status. If this
  *	is the tty was previous stopped and is being started then the
  *	driver start method is invoked and the line discipline woken.
  *
@@ -2876,7 +2877,7 @@
  *	@tty: tty to fake input into
  *	@p: pointer to character
  *
- *	Fake input to a tty device. Does the neccessary locking and
+ *	Fake input to a tty device. Does the necessary locking and
  *	input management.
  *
  *	FIXME: does not honour flow control ??
@@ -3107,7 +3108,7 @@
 	 */
 	if (tty == real_tty && current->signal->tty != real_tty)
 		return -ENOTTY;
-	return put_user(pid_nr(real_tty->pgrp), p);
+	return put_user(pid_vnr(real_tty->pgrp), p);
 }
 
 /**
@@ -3141,7 +3142,7 @@
 	if (pgrp_nr < 0)
 		return -EINVAL;
 	rcu_read_lock();
-	pgrp = find_pid(pgrp_nr);
+	pgrp = find_vpid(pgrp_nr);
 	retval = -ESRCH;
 	if (!pgrp)
 		goto out_unlock;
@@ -3178,7 +3179,7 @@
 		return -ENOTTY;
 	if (!real_tty->session)
 		return -ENOTTY;
-	return put_user(pid_nr(real_tty->session), p);
+	return put_user(pid_vnr(real_tty->session), p);
 }
 
 /**
@@ -3528,8 +3529,8 @@
 	/* Kill the entire session */
 	do_each_pid_task(session, PIDTYPE_SID, p) {
 		printk(KERN_NOTICE "SAK: killed process %d"
-			" (%s): process_session(p)==tty->session\n",
-			p->pid, p->comm);
+			" (%s): task_session_nr(p)==tty->session\n",
+			task_pid_nr(p), p->comm);
 		send_sig(SIGKILL, p, 1);
 	} while_each_pid_task(session, PIDTYPE_SID, p);
 	/* Now kill any processes that happen to have the
@@ -3538,8 +3539,8 @@
 	do_each_thread(g, p) {
 		if (p->signal->tty == tty) {
 			printk(KERN_NOTICE "SAK: killed process %d"
-			    " (%s): process_session(p)==tty->session\n",
-			    p->pid, p->comm);
+			    " (%s): task_session_nr(p)==tty->session\n",
+			    task_pid_nr(p), p->comm);
 			send_sig(SIGKILL, p, 1);
 			continue;
 		}
@@ -3559,7 +3560,7 @@
 				    filp->private_data == tty) {
 					printk(KERN_NOTICE "SAK: killed process %d"
 					    " (%s): fd#%d opened to the tty\n",
-					    p->pid, p->comm, i);
+					    task_pid_nr(p), p->comm, i);
 					force_sig(SIGKILL, p);
 					break;
 				}
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 745d552..7a00350 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -228,7 +228,8 @@
  *	and will all go away once this is done.
  */
 
-void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud)
+void tty_termios_encode_baud_rate(struct ktermios *termios,
+				  speed_t ibaud, speed_t obaud)
 {
 	int i = 0;
 	int ifound = -1, ofound = -1;
@@ -263,11 +264,15 @@
 	 */
 
 	do {
-		if (obaud - oclose >= baud_table[i] && obaud + oclose <= baud_table[i]) {
+		if (obaud - oclose <= baud_table[i] &&
+		    obaud + oclose >= baud_table[i]) {
 			termios->c_cflag |= baud_bits[i];
 			ofound = i;
 		}
-		if (ibaud - iclose >= baud_table[i] && ibaud + iclose <= baud_table[i]) {
+		if (ibaud - iclose <= baud_table[i] &&
+		    ibaud + iclose >= baud_table[i]) {
+			/* For the case input == output don't set IBAUD bits
+			   if the user didn't do so */
 			if (ofound == i && !ibinput)
 				ifound  = i;
 #ifdef IBSHIFT
@@ -439,7 +444,7 @@
  *	@arg: user data
  *	@opt: option information
  *
- *	Helper function to prepare termios data and run neccessary other
+ *	Helper function to prepare termios data and run necessary other
  *	functions before using change_termios to do the actual changes.
  *
  *	Locking:
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
new file mode 100644
index 0000000..100e8a2
--- /dev/null
+++ b/drivers/char/virtio_console.c
@@ -0,0 +1,225 @@
+/*D:300
+ * The Guest console driver
+ *
+ * Writing console drivers is one of the few remaining Dark Arts in Linux.
+ * Fortunately for us, the path of virtual consoles has been well-trodden by
+ * the PowerPC folks, who wrote "hvc_console.c" to generically support any
+ * virtual console.  We use that infrastructure which only requires us to write
+ * the basic put_chars and get_chars functions and call the right register
+ * functions.
+ :*/
+
+/*M:002 The console can be flooded: while the Guest is processing input the
+ * Host can send more.  Buffering in the Host could alleviate this, but it is a
+ * difficult problem in general. :*/
+/* Copyright (C) 2006, 2007 Rusty Russell, IBM 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
+ */
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/virtio.h>
+#include <linux/virtio_console.h>
+#include "hvc_console.h"
+
+/*D:340 These represent our input and output console queues, and the virtio
+ * operations for them. */
+static struct virtqueue *in_vq, *out_vq;
+static struct virtio_device *vdev;
+
+/* This is our input buffer, and how much data is left in it. */
+static unsigned int in_len;
+static char *in, *inbuf;
+
+/* The operations for our console. */
+static struct hv_ops virtio_cons;
+
+/*D:310 The put_chars() callback is pretty straightforward.
+ *
+ * We turn the characters into a scatter-gather list, add it to the output
+ * queue and then kick the Host.  Then we sit here waiting for it to finish:
+ * inefficient in theory, but in practice implementations will do it
+ * immediately (lguest's Launcher does). */
+static int put_chars(u32 vtermno, const char *buf, int count)
+{
+	struct scatterlist sg[1];
+	unsigned int len;
+
+	/* This is a convenient routine to initialize a single-elem sg list */
+	sg_init_one(sg, buf, count);
+
+	/* add_buf wants a token to identify this buffer: we hand it any
+	 * non-NULL pointer, since there's only ever one buffer. */
+	if (out_vq->vq_ops->add_buf(out_vq, sg, 1, 0, (void *)1) == 0) {
+		/* Tell Host to go! */
+		out_vq->vq_ops->kick(out_vq);
+		/* Chill out until it's done with the buffer. */
+		while (!out_vq->vq_ops->get_buf(out_vq, &len))
+			cpu_relax();
+	}
+
+	/* We're expected to return the amount of data we wrote: all of it. */
+	return count;
+}
+
+/* Create a scatter-gather list representing our input buffer and put it in the
+ * queue. */
+static void add_inbuf(void)
+{
+	struct scatterlist sg[1];
+	sg_init_one(sg, inbuf, PAGE_SIZE);
+
+	/* We should always be able to add one buffer to an empty queue. */
+	if (in_vq->vq_ops->add_buf(in_vq, sg, 0, 1, inbuf) != 0)
+		BUG();
+	in_vq->vq_ops->kick(in_vq);
+}
+
+/*D:350 get_chars() is the callback from the hvc_console infrastructure when
+ * an interrupt is received.
+ *
+ * Most of the code deals with the fact that the hvc_console() infrastructure
+ * only asks us for 16 bytes at a time.  We keep in_offset and in_used fields
+ * for partially-filled buffers. */
+static int get_chars(u32 vtermno, char *buf, int count)
+{
+	/* If we don't have an input queue yet, we can't get input. */
+	BUG_ON(!in_vq);
+
+	/* No buffer?  Try to get one. */
+	if (!in_len) {
+		in = in_vq->vq_ops->get_buf(in_vq, &in_len);
+		if (!in)
+			return 0;
+	}
+
+	/* You want more than we have to give?  Well, try wanting less! */
+	if (in_len < count)
+		count = in_len;
+
+	/* Copy across to their buffer and increment offset. */
+	memcpy(buf, in, count);
+	in += count;
+	in_len -= count;
+
+	/* Finished?  Re-register buffer so Host will use it again. */
+	if (in_len == 0)
+		add_inbuf();
+
+	return count;
+}
+/*:*/
+
+/*D:320 Console drivers are initialized very early so boot messages can go out,
+ * so we do things slightly differently from the generic virtio initialization
+ * of the net and block drivers.
+ *
+ * At this stage, the console is output-only.  It's too early to set up a
+ * virtqueue, so we let the drivers do some boutique early-output thing. */
+int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int))
+{
+	virtio_cons.put_chars = put_chars;
+	return hvc_instantiate(0, 0, &virtio_cons);
+}
+
+/*D:370 Once we're further in boot, we get probed like any other virtio device.
+ * At this stage we set up the output virtqueue.
+ *
+ * To set up and manage our virtual console, we call hvc_alloc().  Since we
+ * never remove the console device we never need this pointer again.
+ *
+ * Finally we put our input buffer in the input queue, ready to receive. */
+static int virtcons_probe(struct virtio_device *dev)
+{
+	int err;
+	struct hvc_struct *hvc;
+
+	vdev = dev;
+
+	/* This is the scratch page we use to receive console input */
+	inbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!inbuf) {
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	/* Find the input queue. */
+	/* FIXME: This is why we want to wean off hvc: we do nothing
+	 * when input comes in. */
+	in_vq = vdev->config->find_vq(vdev, NULL);
+	if (IS_ERR(in_vq)) {
+		err = PTR_ERR(in_vq);
+		goto free;
+	}
+
+	out_vq = vdev->config->find_vq(vdev, NULL);
+	if (IS_ERR(out_vq)) {
+		err = PTR_ERR(out_vq);
+		goto free_in_vq;
+	}
+
+	/* Start using the new console output. */
+	virtio_cons.get_chars = get_chars;
+	virtio_cons.put_chars = put_chars;
+
+	/* The first argument of hvc_alloc() is the virtual console number, so
+	 * we use zero.  The second argument is the interrupt number; we
+	 * currently leave this as zero: it would be better not to use the
+	 * hvc mechanism and fix this (FIXME!).
+	 *
+	 * The third argument is a "struct hv_ops" containing the put_chars()
+	 * and get_chars() pointers.  The final argument is the output buffer
+	 * size: we can do any size, so we put PAGE_SIZE here. */
+	hvc = hvc_alloc(0, 0, &virtio_cons, PAGE_SIZE);
+	if (IS_ERR(hvc)) {
+		err = PTR_ERR(hvc);
+		goto free_out_vq;
+	}
+
+	/* Register the input buffer the first time. */
+	add_inbuf();
+	return 0;
+
+free_out_vq:
+	vdev->config->del_vq(out_vq);
+free_in_vq:
+	vdev->config->del_vq(in_vq);
+free:
+	kfree(inbuf);
+fail:
+	return err;
+}
+
+static struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_CONSOLE, VIRTIO_DEV_ANY_ID },
+	{ 0 },
+};
+
+static struct virtio_driver virtio_console = {
+	.driver.name =	KBUILD_MODNAME,
+	.driver.owner =	THIS_MODULE,
+	.id_table =	id_table,
+	.probe =	virtcons_probe,
+};
+
+static int __init init(void)
+{
+	return register_virtio_driver(&virtio_console);
+}
+module_init(init);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_DESCRIPTION("Virtio console driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 645ad98..7a5badf 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -99,6 +99,7 @@
 #include <linux/pm.h>
 #include <linux/font.h>
 #include <linux/bitops.h>
+#include <linux/notifier.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -158,11 +159,7 @@
 static void set_palette(struct vc_data *vc);
 
 static int printable;		/* Is console ready for printing? */
-#ifdef CONFIG_VT_UNICODE
-int default_utf8 = 1;
-#else
-int default_utf8;
-#endif
+int default_utf8 = true;
 module_param(default_utf8, int, S_IRUGO | S_IWUSR);
 
 /*
@@ -227,6 +224,35 @@
 };
 
 /*
+ * Notifier list for console events.
+ */
+static ATOMIC_NOTIFIER_HEAD(vt_notifier_list);
+
+int register_vt_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_register(&vt_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_vt_notifier);
+
+int unregister_vt_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_unregister(&vt_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_vt_notifier);
+
+static void notify_write(struct vc_data *vc, unsigned int unicode)
+{
+	struct vt_notifier_param param = { .vc = vc, unicode = unicode };
+	atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, &param);
+}
+
+static void notify_update(struct vc_data *vc)
+{
+	struct vt_notifier_param param = { .vc = vc };
+	atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param);
+}
+
+/*
  *	Low-Level Functions
  */
 
@@ -722,6 +748,7 @@
 		return -ENXIO;
 	if (!vc_cons[currcons].d) {
 	    struct vc_data *vc;
+	    struct vt_notifier_param param;
 
 	    /* prevent users from taking too much memory */
 	    if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE))
@@ -733,7 +760,7 @@
 	    /* although the numbers above are not valid since long ago, the
 	       point is still up-to-date and the comment still has its value
 	       even if only as a historical artifact.  --mj, July 1998 */
-	    vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
+	    param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
 	    if (!vc)
 		return -ENOMEM;
 	    vc_cons[currcons].d = vc;
@@ -750,6 +777,7 @@
 	    }
 	    vc->vc_kmalloced = 1;
 	    vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
+	    atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
 	}
 	return 0;
 }
@@ -911,6 +939,8 @@
 
 	if (vc_cons_allocated(currcons)) {
 		struct vc_data *vc = vc_cons[currcons].d;
+		struct vt_notifier_param param = { .vc = vc };
+		atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
 		vc->vc_sw->con_deinit(vc);
 		put_pid(vc->vt_pid);
 		module_put(vc->vc_sw->owner);
@@ -1023,6 +1053,7 @@
 		vc->vc_pos += vc->vc_size_row;
 	}
 	vc->vc_need_wrap = 0;
+	notify_write(vc, '\n');
 }
 
 static void ri(struct vc_data *vc)
@@ -1043,6 +1074,7 @@
 {
 	vc->vc_pos -= vc->vc_x << 1;
 	vc->vc_need_wrap = vc->vc_x = 0;
+	notify_write(vc, '\r');
 }
 
 static inline void bs(struct vc_data *vc)
@@ -1051,6 +1083,7 @@
 		vc->vc_pos -= 2;
 		vc->vc_x--;
 		vc->vc_need_wrap = 0;
+		notify_write(vc, '\b');
 	}
 }
 
@@ -1597,6 +1630,7 @@
 				break;
 		}
 		vc->vc_pos += (vc->vc_x << 1);
+		notify_write(vc, '\t');
 		return;
 	case 10: case 11: case 12:
 		lf(vc);
@@ -2256,6 +2290,7 @@
 				tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
 				if (tc < 0) tc = ' ';
 			}
+			notify_write(vc, c);
 
 			if (inverse) {
 				FLUSH
@@ -2278,6 +2313,7 @@
 	release_console_sem();
 
 out:
+	notify_update(vc);
 	return n;
 #undef FLUSH
 }
@@ -2321,6 +2357,7 @@
 		do_blank_screen(0);
 		blank_timer_expired = 0;
 	}
+	notify_update(vc_cons[fg_console].d);
 
 	release_console_sem();
 }
@@ -2422,6 +2459,7 @@
 				continue;
 		}
 		scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
+		notify_write(vc, c);
 		cnt++;
 		if (myx == vc->vc_cols - 1) {
 			vc->vc_need_wrap = 1;
@@ -2440,6 +2478,7 @@
 		}
 	}
 	set_cursor(vc);
+	notify_update(vc);
 
 quit:
 	clear_bit(0, &printing);
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
new file mode 100644
index 0000000..3bed412
--- /dev/null
+++ b/drivers/cpuidle/Kconfig
@@ -0,0 +1,20 @@
+
+config CPU_IDLE
+	bool "CPU idle PM support"
+	help
+	  CPU idle is a generic framework for supporting software-controlled
+	  idle processor power management.  It includes modular cross-platform
+	  governors that can be swapped during runtime.
+
+	  If you're using a mobile platform that supports CPU idle PM (e.g.
+	  an ACPI-capable notebook), you should say Y here.
+
+config CPU_IDLE_GOV_LADDER
+	bool
+	depends on CPU_IDLE
+	default y
+
+config CPU_IDLE_GOV_MENU
+	bool
+	depends on CPU_IDLE && NO_HZ
+	default y
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
new file mode 100644
index 0000000..5634f88
--- /dev/null
+++ b/drivers/cpuidle/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for cpuidle.
+#
+
+obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
new file mode 100644
index 0000000..fdf4106
--- /dev/null
+++ b/drivers/cpuidle/cpuidle.c
@@ -0,0 +1,295 @@
+/*
+ * cpuidle.c - core cpuidle infrastructure
+ *
+ * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *               Shaohua Li <shaohua.li@intel.com>
+ *               Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/latency.h>
+#include <linux/cpu.h>
+#include <linux/cpuidle.h>
+
+#include "cpuidle.h"
+
+DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
+EXPORT_PER_CPU_SYMBOL_GPL(cpuidle_devices);
+
+DEFINE_MUTEX(cpuidle_lock);
+LIST_HEAD(cpuidle_detected_devices);
+static void (*pm_idle_old)(void);
+
+static int enabled_devices;
+
+/**
+ * cpuidle_idle_call - the main idle loop
+ *
+ * NOTE: no locks or semaphores should be used here
+ */
+static void cpuidle_idle_call(void)
+{
+	struct cpuidle_device *dev = __get_cpu_var(cpuidle_devices);
+	struct cpuidle_state *target_state;
+	int next_state;
+
+	/* check if the device is ready */
+	if (!dev || !dev->enabled) {
+		if (pm_idle_old)
+			pm_idle_old();
+		else
+			local_irq_enable();
+		return;
+	}
+
+	/* ask the governor for the next state */
+	next_state = cpuidle_curr_governor->select(dev);
+	if (need_resched())
+		return;
+	target_state = &dev->states[next_state];
+
+	/* enter the state and update stats */
+	dev->last_residency = target_state->enter(dev, target_state);
+	dev->last_state = target_state;
+	target_state->time += dev->last_residency;
+	target_state->usage++;
+
+	/* give the governor an opportunity to reflect on the outcome */
+	if (cpuidle_curr_governor->reflect)
+		cpuidle_curr_governor->reflect(dev);
+}
+
+/**
+ * cpuidle_install_idle_handler - installs the cpuidle idle loop handler
+ */
+void cpuidle_install_idle_handler(void)
+{
+	if (enabled_devices && (pm_idle != cpuidle_idle_call)) {
+		/* Make sure all changes finished before we switch to new idle */
+		smp_wmb();
+		pm_idle = cpuidle_idle_call;
+	}
+}
+
+/**
+ * cpuidle_uninstall_idle_handler - uninstalls the cpuidle idle loop handler
+ */
+void cpuidle_uninstall_idle_handler(void)
+{
+	if (enabled_devices && (pm_idle != pm_idle_old)) {
+		pm_idle = pm_idle_old;
+		cpu_idle_wait();
+	}
+}
+
+/**
+ * cpuidle_pause_and_lock - temporarily disables CPUIDLE
+ */
+void cpuidle_pause_and_lock(void)
+{
+	mutex_lock(&cpuidle_lock);
+	cpuidle_uninstall_idle_handler();
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_pause_and_lock);
+
+/**
+ * cpuidle_resume_and_unlock - resumes CPUIDLE operation
+ */
+void cpuidle_resume_and_unlock(void)
+{
+	cpuidle_install_idle_handler();
+	mutex_unlock(&cpuidle_lock);
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
+
+/**
+ * cpuidle_enable_device - enables idle PM for a CPU
+ * @dev: the CPU
+ *
+ * This function must be called between cpuidle_pause_and_lock and
+ * cpuidle_resume_and_unlock when used externally.
+ */
+int cpuidle_enable_device(struct cpuidle_device *dev)
+{
+	int ret, i;
+
+	if (dev->enabled)
+		return 0;
+	if (!cpuidle_curr_driver || !cpuidle_curr_governor)
+		return -EIO;
+	if (!dev->state_count)
+		return -EINVAL;
+
+	if ((ret = cpuidle_add_state_sysfs(dev)))
+		return ret;
+
+	if (cpuidle_curr_governor->enable &&
+	    (ret = cpuidle_curr_governor->enable(dev)))
+		goto fail_sysfs;
+
+	for (i = 0; i < dev->state_count; i++) {
+		dev->states[i].usage = 0;
+		dev->states[i].time = 0;
+	}
+	dev->last_residency = 0;
+	dev->last_state = NULL;
+
+	smp_wmb();
+
+	dev->enabled = 1;
+
+	enabled_devices++;
+	return 0;
+
+fail_sysfs:
+	cpuidle_remove_state_sysfs(dev);
+
+	return ret;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_enable_device);
+
+/**
+ * cpuidle_disable_device - disables idle PM for a CPU
+ * @dev: the CPU
+ *
+ * This function must be called between cpuidle_pause_and_lock and
+ * cpuidle_resume_and_unlock when used externally.
+ */
+void cpuidle_disable_device(struct cpuidle_device *dev)
+{
+	if (!dev->enabled)
+		return;
+	if (!cpuidle_curr_driver || !cpuidle_curr_governor)
+		return;
+
+	dev->enabled = 0;
+
+	if (cpuidle_curr_governor->disable)
+		cpuidle_curr_governor->disable(dev);
+
+	cpuidle_remove_state_sysfs(dev);
+	enabled_devices--;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_disable_device);
+
+/**
+ * cpuidle_register_device - registers a CPU's idle PM feature
+ * @dev: the cpu
+ */
+int cpuidle_register_device(struct cpuidle_device *dev)
+{
+	int ret;
+	struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu);
+
+	if (!sys_dev)
+		return -EINVAL;
+	if (!try_module_get(cpuidle_curr_driver->owner))
+		return -EINVAL;
+
+	init_completion(&dev->kobj_unregister);
+
+	mutex_lock(&cpuidle_lock);
+
+	per_cpu(cpuidle_devices, dev->cpu) = dev;
+	list_add(&dev->device_list, &cpuidle_detected_devices);
+	if ((ret = cpuidle_add_sysfs(sys_dev))) {
+		mutex_unlock(&cpuidle_lock);
+		module_put(cpuidle_curr_driver->owner);
+		return ret;
+	}
+
+	cpuidle_enable_device(dev);
+	cpuidle_install_idle_handler();
+
+	mutex_unlock(&cpuidle_lock);
+
+	return 0;
+
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_register_device);
+
+/**
+ * cpuidle_unregister_device - unregisters a CPU's idle PM feature
+ * @dev: the cpu
+ */
+void cpuidle_unregister_device(struct cpuidle_device *dev)
+{
+	struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu);
+
+	cpuidle_pause_and_lock();
+
+	cpuidle_disable_device(dev);
+
+	cpuidle_remove_sysfs(sys_dev);
+	list_del(&dev->device_list);
+	wait_for_completion(&dev->kobj_unregister);
+	per_cpu(cpuidle_devices, dev->cpu) = NULL;
+
+	cpuidle_resume_and_unlock();
+
+	module_put(cpuidle_curr_driver->owner);
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_unregister_device);
+
+#ifdef CONFIG_SMP
+
+static void smp_callback(void *v)
+{
+	/* we already woke the CPU up, nothing more to do */
+}
+
+/*
+ * This function gets called when a part of the kernel has a new latency
+ * requirement.  This means we need to get all processors out of their C-state,
+ * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that
+ * wakes them all right up.
+ */
+static int cpuidle_latency_notify(struct notifier_block *b,
+		unsigned long l, void *v)
+{
+	smp_call_function(smp_callback, NULL, 0, 1);
+	return NOTIFY_OK;
+}
+
+static struct notifier_block cpuidle_latency_notifier = {
+	.notifier_call = cpuidle_latency_notify,
+};
+
+#define latency_notifier_init(x) do { register_latency_notifier(x); } while (0)
+
+#else /* CONFIG_SMP */
+
+#define latency_notifier_init(x) do { } while (0)
+
+#endif /* CONFIG_SMP */
+
+/**
+ * cpuidle_init - core initializer
+ */
+static int __init cpuidle_init(void)
+{
+	int ret;
+
+	pm_idle_old = pm_idle;
+
+	ret = cpuidle_add_class_sysfs(&cpu_sysdev_class);
+	if (ret)
+		return ret;
+
+	latency_notifier_init(&cpuidle_latency_notifier);
+
+	return 0;
+}
+
+core_initcall(cpuidle_init);
diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h
new file mode 100644
index 0000000..9476ba3
--- /dev/null
+++ b/drivers/cpuidle/cpuidle.h
@@ -0,0 +1,33 @@
+/*
+ * cpuidle.h - The internal header file
+ */
+
+#ifndef __DRIVER_CPUIDLE_H
+#define __DRIVER_CPUIDLE_H
+
+#include <linux/sysdev.h>
+
+/* For internal use only */
+extern struct cpuidle_governor *cpuidle_curr_governor;
+extern struct cpuidle_driver *cpuidle_curr_driver;
+extern struct list_head cpuidle_governors;
+extern struct list_head cpuidle_detected_devices;
+extern struct mutex cpuidle_lock;
+extern spinlock_t cpuidle_driver_lock;
+
+/* idle loop */
+extern void cpuidle_install_idle_handler(void);
+extern void cpuidle_uninstall_idle_handler(void);
+
+/* governors */
+extern int cpuidle_switch_governor(struct cpuidle_governor *gov);
+
+/* sysfs */
+extern int cpuidle_add_class_sysfs(struct sysdev_class *cls);
+extern void cpuidle_remove_class_sysfs(struct sysdev_class *cls);
+extern int cpuidle_add_state_sysfs(struct cpuidle_device *device);
+extern void cpuidle_remove_state_sysfs(struct cpuidle_device *device);
+extern int cpuidle_add_sysfs(struct sys_device *sysdev);
+extern void cpuidle_remove_sysfs(struct sys_device *sysdev);
+
+#endif /* __DRIVER_CPUIDLE_H */
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
new file mode 100644
index 0000000..2257004
--- /dev/null
+++ b/drivers/cpuidle/driver.c
@@ -0,0 +1,56 @@
+/*
+ * driver.c - driver support
+ *
+ * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *               Shaohua Li <shaohua.li@intel.com>
+ *               Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/mutex.h>
+#include <linux/module.h>
+#include <linux/cpuidle.h>
+
+#include "cpuidle.h"
+
+struct cpuidle_driver *cpuidle_curr_driver;
+DEFINE_SPINLOCK(cpuidle_driver_lock);
+
+/**
+ * cpuidle_register_driver - registers a driver
+ * @drv: the driver
+ */
+int cpuidle_register_driver(struct cpuidle_driver *drv)
+{
+	if (!drv)
+		return -EINVAL;
+
+	spin_lock(&cpuidle_driver_lock);
+	if (cpuidle_curr_driver) {
+		spin_unlock(&cpuidle_driver_lock);
+		return -EBUSY;
+	}
+	cpuidle_curr_driver = drv;
+	spin_unlock(&cpuidle_driver_lock);
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_register_driver);
+
+/**
+ * cpuidle_unregister_driver - unregisters a driver
+ * @drv: the driver
+ */
+void cpuidle_unregister_driver(struct cpuidle_driver *drv)
+{
+	if (!drv)
+		return;
+
+	spin_lock(&cpuidle_driver_lock);
+	cpuidle_curr_driver = NULL;
+	spin_unlock(&cpuidle_driver_lock);
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
new file mode 100644
index 0000000..bb699cb2
--- /dev/null
+++ b/drivers/cpuidle/governor.c
@@ -0,0 +1,141 @@
+/*
+ * governor.c - governor support
+ *
+ * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *               Shaohua Li <shaohua.li@intel.com>
+ *               Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/mutex.h>
+#include <linux/module.h>
+#include <linux/cpuidle.h>
+
+#include "cpuidle.h"
+
+LIST_HEAD(cpuidle_governors);
+struct cpuidle_governor *cpuidle_curr_governor;
+
+/**
+ * __cpuidle_find_governor - finds a governor of the specified name
+ * @str: the name
+ *
+ * Must be called with cpuidle_lock aquired.
+ */
+static struct cpuidle_governor * __cpuidle_find_governor(const char *str)
+{
+	struct cpuidle_governor *gov;
+
+	list_for_each_entry(gov, &cpuidle_governors, governor_list)
+		if (!strnicmp(str, gov->name, CPUIDLE_NAME_LEN))
+			return gov;
+
+	return NULL;
+}
+
+/**
+ * cpuidle_switch_governor - changes the governor
+ * @gov: the new target governor
+ *
+ * NOTE: "gov" can be NULL to specify disabled
+ * Must be called with cpuidle_lock aquired.
+ */
+int cpuidle_switch_governor(struct cpuidle_governor *gov)
+{
+	struct cpuidle_device *dev;
+
+	if (gov == cpuidle_curr_governor)
+		return 0;
+
+	cpuidle_uninstall_idle_handler();
+
+	if (cpuidle_curr_governor) {
+		list_for_each_entry(dev, &cpuidle_detected_devices, device_list)
+			cpuidle_disable_device(dev);
+		module_put(cpuidle_curr_governor->owner);
+	}
+
+	cpuidle_curr_governor = gov;
+
+	if (gov) {
+		if (!try_module_get(cpuidle_curr_governor->owner))
+			return -EINVAL;
+		list_for_each_entry(dev, &cpuidle_detected_devices, device_list)
+			cpuidle_enable_device(dev);
+		cpuidle_install_idle_handler();
+		printk(KERN_INFO "cpuidle: using governor %s\n", gov->name);
+	}
+
+	return 0;
+}
+
+/**
+ * cpuidle_register_governor - registers a governor
+ * @gov: the governor
+ */
+int cpuidle_register_governor(struct cpuidle_governor *gov)
+{
+	int ret = -EEXIST;
+
+	if (!gov || !gov->select)
+		return -EINVAL;
+
+	mutex_lock(&cpuidle_lock);
+	if (__cpuidle_find_governor(gov->name) == NULL) {
+		ret = 0;
+		list_add_tail(&gov->governor_list, &cpuidle_governors);
+		if (!cpuidle_curr_governor ||
+		    cpuidle_curr_governor->rating < gov->rating)
+			cpuidle_switch_governor(gov);
+	}
+	mutex_unlock(&cpuidle_lock);
+
+	return ret;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_register_governor);
+
+/**
+ * cpuidle_replace_governor - find a replacement governor
+ * @exclude_rating: the rating that will be skipped while looking for
+ * new governor.
+ */
+static struct cpuidle_governor *cpuidle_replace_governor(int exclude_rating)
+{
+	struct cpuidle_governor *gov;
+	struct cpuidle_governor *ret_gov = NULL;
+	unsigned int max_rating = 0;
+
+	list_for_each_entry(gov, &cpuidle_governors, governor_list) {
+		if (gov->rating == exclude_rating)
+			continue;
+		if (gov->rating > max_rating) {
+			max_rating = gov->rating;
+			ret_gov = gov;
+		}
+	}
+
+	return ret_gov;
+}
+
+/**
+ * cpuidle_unregister_governor - unregisters a governor
+ * @gov: the governor
+ */
+void cpuidle_unregister_governor(struct cpuidle_governor *gov)
+{
+	if (!gov)
+		return;
+
+	mutex_lock(&cpuidle_lock);
+	if (gov == cpuidle_curr_governor) {
+		struct cpuidle_governor *new_gov;
+		new_gov = cpuidle_replace_governor(gov->rating);
+		cpuidle_switch_governor(new_gov);
+	}
+	list_del(&gov->governor_list);
+	mutex_unlock(&cpuidle_lock);
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_unregister_governor);
diff --git a/drivers/cpuidle/governors/Makefile b/drivers/cpuidle/governors/Makefile
new file mode 100644
index 0000000..1b51272
--- /dev/null
+++ b/drivers/cpuidle/governors/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for cpuidle governors.
+#
+
+obj-$(CONFIG_CPU_IDLE_GOV_LADDER) += ladder.o
+obj-$(CONFIG_CPU_IDLE_GOV_MENU) += menu.o
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
new file mode 100644
index 0000000..eb666ec
--- /dev/null
+++ b/drivers/cpuidle/governors/ladder.c
@@ -0,0 +1,166 @@
+/*
+ * ladder.c - the residency ladder algorithm
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2004, 2005 Dominik Brodowski <linux@brodo.de>
+ *
+ * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *               Shaohua Li <shaohua.li@intel.com>
+ *               Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpuidle.h>
+#include <linux/latency.h>
+#include <linux/moduleparam.h>
+#include <linux/jiffies.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#define PROMOTION_COUNT 4
+#define DEMOTION_COUNT 1
+
+struct ladder_device_state {
+	struct {
+		u32 promotion_count;
+		u32 demotion_count;
+		u32 promotion_time;
+		u32 demotion_time;
+	} threshold;
+	struct {
+		int promotion_count;
+		int demotion_count;
+	} stats;
+};
+
+struct ladder_device {
+	struct ladder_device_state states[CPUIDLE_STATE_MAX];
+	int last_state_idx;
+};
+
+static DEFINE_PER_CPU(struct ladder_device, ladder_devices);
+
+/**
+ * ladder_do_selection - prepares private data for a state change
+ * @ldev: the ladder device
+ * @old_idx: the current state index
+ * @new_idx: the new target state index
+ */
+static inline void ladder_do_selection(struct ladder_device *ldev,
+				       int old_idx, int new_idx)
+{
+	ldev->states[old_idx].stats.promotion_count = 0;
+	ldev->states[old_idx].stats.demotion_count = 0;
+	ldev->last_state_idx = new_idx;
+}
+
+/**
+ * ladder_select_state - selects the next state to enter
+ * @dev: the CPU
+ */
+static int ladder_select_state(struct cpuidle_device *dev)
+{
+	struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
+	struct ladder_device_state *last_state;
+	int last_residency, last_idx = ldev->last_state_idx;
+
+	if (unlikely(!ldev))
+		return 0;
+
+	last_state = &ldev->states[last_idx];
+
+	if (dev->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID)
+		last_residency = cpuidle_get_last_residency(dev) - dev->states[last_idx].exit_latency;
+	else
+		last_residency = last_state->threshold.promotion_time + 1;
+
+	/* consider promotion */
+	if (last_idx < dev->state_count - 1 &&
+	    last_residency > last_state->threshold.promotion_time &&
+	    dev->states[last_idx + 1].exit_latency <= system_latency_constraint()) {
+		last_state->stats.promotion_count++;
+		last_state->stats.demotion_count = 0;
+		if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) {
+			ladder_do_selection(ldev, last_idx, last_idx + 1);
+			return last_idx + 1;
+		}
+	}
+
+	/* consider demotion */
+	if (last_idx > 0 &&
+	    last_residency < last_state->threshold.demotion_time) {
+		last_state->stats.demotion_count++;
+		last_state->stats.promotion_count = 0;
+		if (last_state->stats.demotion_count >= last_state->threshold.demotion_count) {
+			ladder_do_selection(ldev, last_idx, last_idx - 1);
+			return last_idx - 1;
+		}
+	}
+
+	/* otherwise remain at the current state */
+	return last_idx;
+}
+
+/**
+ * ladder_enable_device - setup for the governor
+ * @dev: the CPU
+ */
+static int ladder_enable_device(struct cpuidle_device *dev)
+{
+	int i;
+	struct ladder_device *ldev = &per_cpu(ladder_devices, dev->cpu);
+	struct ladder_device_state *lstate;
+	struct cpuidle_state *state;
+
+	ldev->last_state_idx = 0;
+
+	for (i = 0; i < dev->state_count; i++) {
+		state = &dev->states[i];
+		lstate = &ldev->states[i];
+
+		lstate->stats.promotion_count = 0;
+		lstate->stats.demotion_count = 0;
+
+		lstate->threshold.promotion_count = PROMOTION_COUNT;
+		lstate->threshold.demotion_count = DEMOTION_COUNT;
+
+		if (i < dev->state_count - 1)
+			lstate->threshold.promotion_time = state->exit_latency;
+		if (i > 0)
+			lstate->threshold.demotion_time = state->exit_latency;
+	}
+
+	return 0;
+}
+
+static struct cpuidle_governor ladder_governor = {
+	.name =		"ladder",
+	.rating =	10,
+	.enable =	ladder_enable_device,
+	.select =	ladder_select_state,
+	.owner =	THIS_MODULE,
+};
+
+/**
+ * init_ladder - initializes the governor
+ */
+static int __init init_ladder(void)
+{
+	return cpuidle_register_governor(&ladder_governor);
+}
+
+/**
+ * exit_ladder - exits the governor
+ */
+static void __exit exit_ladder(void)
+{
+	cpuidle_unregister_governor(&ladder_governor);
+}
+
+MODULE_LICENSE("GPL");
+module_init(init_ladder);
+module_exit(exit_ladder);
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
new file mode 100644
index 0000000..299d45c
--- /dev/null
+++ b/drivers/cpuidle/governors/menu.c
@@ -0,0 +1,137 @@
+/*
+ * menu.c - the menu idle governor
+ *
+ * Copyright (C) 2006-2007 Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpuidle.h>
+#include <linux/latency.h>
+#include <linux/time.h>
+#include <linux/ktime.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+
+#define BREAK_FUZZ	4	/* 4 us */
+
+struct menu_device {
+	int		last_state_idx;
+
+	unsigned int	expected_us;
+	unsigned int	predicted_us;
+	unsigned int	last_measured_us;
+	unsigned int	elapsed_us;
+};
+
+static DEFINE_PER_CPU(struct menu_device, menu_devices);
+
+/**
+ * menu_select - selects the next idle state to enter
+ * @dev: the CPU
+ */
+static int menu_select(struct cpuidle_device *dev)
+{
+	struct menu_device *data = &__get_cpu_var(menu_devices);
+	int i;
+
+	/* determine the expected residency time */
+	data->expected_us =
+		(u32) ktime_to_ns(tick_nohz_get_sleep_length()) / 1000;
+
+	/* find the deepest idle state that satisfies our constraints */
+	for (i = 1; i < dev->state_count; i++) {
+		struct cpuidle_state *s = &dev->states[i];
+
+		if (s->target_residency > data->expected_us)
+			break;
+		if (s->target_residency > data->predicted_us)
+			break;
+		if (s->exit_latency > system_latency_constraint())
+			break;
+	}
+
+	data->last_state_idx = i - 1;
+	return i - 1;
+}
+
+/**
+ * menu_reflect - attempts to guess what happened after entry
+ * @dev: the CPU
+ *
+ * NOTE: it's important to be fast here because this operation will add to
+ *       the overall exit latency.
+ */
+static void menu_reflect(struct cpuidle_device *dev)
+{
+	struct menu_device *data = &__get_cpu_var(menu_devices);
+	int last_idx = data->last_state_idx;
+	unsigned int measured_us =
+		cpuidle_get_last_residency(dev) + data->elapsed_us;
+	struct cpuidle_state *target = &dev->states[last_idx];
+
+	/*
+	 * Ugh, this idle state doesn't support residency measurements, so we
+	 * are basically lost in the dark.  As a compromise, assume we slept
+	 * for one full standard timer tick.  However, be aware that this
+	 * could potentially result in a suboptimal state transition.
+	 */
+	if (!(target->flags & CPUIDLE_FLAG_TIME_VALID))
+		measured_us = USEC_PER_SEC / HZ;
+
+	/* Predict time remaining until next break event */
+	if (measured_us + BREAK_FUZZ < data->expected_us - target->exit_latency) {
+		data->predicted_us = max(measured_us, data->last_measured_us);
+		data->last_measured_us = measured_us;
+		data->elapsed_us = 0;
+	} else {
+		if (data->elapsed_us < data->elapsed_us + measured_us)
+			data->elapsed_us = measured_us;
+		else
+			data->elapsed_us = -1;
+		data->predicted_us = max(measured_us, data->last_measured_us);
+	}
+}
+
+/**
+ * menu_enable_device - scans a CPU's states and does setup
+ * @dev: the CPU
+ */
+static int menu_enable_device(struct cpuidle_device *dev)
+{
+	struct menu_device *data = &per_cpu(menu_devices, dev->cpu);
+
+	memset(data, 0, sizeof(struct menu_device));
+
+	return 0;
+}
+
+static struct cpuidle_governor menu_governor = {
+	.name =		"menu",
+	.rating =	20,
+	.enable =	menu_enable_device,
+	.select =	menu_select,
+	.reflect =	menu_reflect,
+	.owner =	THIS_MODULE,
+};
+
+/**
+ * init_menu - initializes the governor
+ */
+static int __init init_menu(void)
+{
+	return cpuidle_register_governor(&menu_governor);
+}
+
+/**
+ * exit_menu - exits the governor
+ */
+static void __exit exit_menu(void)
+{
+	cpuidle_unregister_governor(&menu_governor);
+}
+
+MODULE_LICENSE("GPL");
+module_init(init_menu);
+module_exit(exit_menu);
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
new file mode 100644
index 0000000..0f3515e
--- /dev/null
+++ b/drivers/cpuidle/sysfs.c
@@ -0,0 +1,361 @@
+/*
+ * sysfs.c - sysfs support
+ *
+ * (C) 2006-2007 Shaohua Li <shaohua.li@intel.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpuidle.h>
+#include <linux/sysfs.h>
+#include <linux/cpu.h>
+
+#include "cpuidle.h"
+
+static unsigned int sysfs_switch;
+static int __init cpuidle_sysfs_setup(char *unused)
+{
+	sysfs_switch = 1;
+	return 1;
+}
+__setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup);
+
+static ssize_t show_available_governors(struct sys_device *dev, char *buf)
+{
+	ssize_t i = 0;
+	struct cpuidle_governor *tmp;
+
+	mutex_lock(&cpuidle_lock);
+	list_for_each_entry(tmp, &cpuidle_governors, governor_list) {
+		if (i >= (ssize_t) ((PAGE_SIZE/sizeof(char)) - CPUIDLE_NAME_LEN - 2))
+			goto out;
+		i += scnprintf(&buf[i], CPUIDLE_NAME_LEN, "%s ", tmp->name);
+	}
+
+out:
+	i+= sprintf(&buf[i], "\n");
+	mutex_unlock(&cpuidle_lock);
+	return i;
+}
+
+static ssize_t show_current_driver(struct sys_device *dev, char *buf)
+{
+	ssize_t ret;
+
+	spin_lock(&cpuidle_driver_lock);
+	if (cpuidle_curr_driver)
+		ret = sprintf(buf, "%s\n", cpuidle_curr_driver->name);
+	else
+		ret = sprintf(buf, "none\n");
+	spin_unlock(&cpuidle_driver_lock);
+
+	return ret;
+}
+
+static ssize_t show_current_governor(struct sys_device *dev, char *buf)
+{
+	ssize_t ret;
+
+	mutex_lock(&cpuidle_lock);
+	if (cpuidle_curr_governor)
+		ret = sprintf(buf, "%s\n", cpuidle_curr_governor->name);
+	else
+		ret = sprintf(buf, "none\n");
+	mutex_unlock(&cpuidle_lock);
+
+	return ret;
+}
+
+static ssize_t store_current_governor(struct sys_device *dev,
+	const char *buf, size_t count)
+{
+	char gov_name[CPUIDLE_NAME_LEN];
+	int ret = -EINVAL;
+	size_t len = count;
+	struct cpuidle_governor *gov;
+
+	if (!len || len >= sizeof(gov_name))
+		return -EINVAL;
+
+	memcpy(gov_name, buf, len);
+	gov_name[len] = '\0';
+	if (gov_name[len - 1] == '\n')
+		gov_name[--len] = '\0';
+
+	mutex_lock(&cpuidle_lock);
+
+	list_for_each_entry(gov, &cpuidle_governors, governor_list) {
+		if (strlen(gov->name) == len && !strcmp(gov->name, gov_name)) {
+			ret = cpuidle_switch_governor(gov);
+			break;
+		}
+	}
+
+	mutex_unlock(&cpuidle_lock);
+
+	if (ret)
+		return ret;
+	else
+		return count;
+}
+
+static SYSDEV_ATTR(current_driver, 0444, show_current_driver, NULL);
+static SYSDEV_ATTR(current_governor_ro, 0444, show_current_governor, NULL);
+
+static struct attribute *cpuclass_default_attrs[] = {
+	&attr_current_driver.attr,
+	&attr_current_governor_ro.attr,
+	NULL
+};
+
+static SYSDEV_ATTR(available_governors, 0444, show_available_governors, NULL);
+static SYSDEV_ATTR(current_governor, 0644, show_current_governor,
+	store_current_governor);
+
+static struct attribute *cpuclass_switch_attrs[] = {
+	&attr_available_governors.attr,
+	&attr_current_driver.attr,
+	&attr_current_governor.attr,
+	NULL
+};
+
+static struct attribute_group cpuclass_attr_group = {
+	.attrs = cpuclass_default_attrs,
+	.name = "cpuidle",
+};
+
+/**
+ * cpuidle_add_class_sysfs - add CPU global sysfs attributes
+ */
+int cpuidle_add_class_sysfs(struct sysdev_class *cls)
+{
+	if (sysfs_switch)
+		cpuclass_attr_group.attrs = cpuclass_switch_attrs;
+
+	return sysfs_create_group(&cls->kset.kobj, &cpuclass_attr_group);
+}
+
+/**
+ * cpuidle_remove_class_sysfs - remove CPU global sysfs attributes
+ */
+void cpuidle_remove_class_sysfs(struct sysdev_class *cls)
+{
+	sysfs_remove_group(&cls->kset.kobj, &cpuclass_attr_group);
+}
+
+struct cpuidle_attr {
+	struct attribute attr;
+	ssize_t (*show)(struct cpuidle_device *, char *);
+	ssize_t (*store)(struct cpuidle_device *, const char *, size_t count);
+};
+
+#define define_one_ro(_name, show) \
+	static struct cpuidle_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
+#define define_one_rw(_name, show, store) \
+	static struct cpuidle_attr attr_##_name = __ATTR(_name, 0644, show, store)
+
+#define kobj_to_cpuidledev(k) container_of(k, struct cpuidle_device, kobj)
+#define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr)
+static ssize_t cpuidle_show(struct kobject * kobj, struct attribute * attr ,char * buf)
+{
+	int ret = -EIO;
+	struct cpuidle_device *dev = kobj_to_cpuidledev(kobj);
+	struct cpuidle_attr * cattr = attr_to_cpuidleattr(attr);
+
+	if (cattr->show) {
+		mutex_lock(&cpuidle_lock);
+		ret = cattr->show(dev, buf);
+		mutex_unlock(&cpuidle_lock);
+	}
+	return ret;
+}
+
+static ssize_t cpuidle_store(struct kobject * kobj, struct attribute * attr,
+		     const char * buf, size_t count)
+{
+	int ret = -EIO;
+	struct cpuidle_device *dev = kobj_to_cpuidledev(kobj);
+	struct cpuidle_attr * cattr = attr_to_cpuidleattr(attr);
+
+	if (cattr->store) {
+		mutex_lock(&cpuidle_lock);
+		ret = cattr->store(dev, buf, count);
+		mutex_unlock(&cpuidle_lock);
+	}
+	return ret;
+}
+
+static struct sysfs_ops cpuidle_sysfs_ops = {
+	.show = cpuidle_show,
+	.store = cpuidle_store,
+};
+
+static void cpuidle_sysfs_release(struct kobject *kobj)
+{
+	struct cpuidle_device *dev = kobj_to_cpuidledev(kobj);
+
+	complete(&dev->kobj_unregister);
+}
+
+static struct kobj_type ktype_cpuidle = {
+	.sysfs_ops = &cpuidle_sysfs_ops,
+	.release = cpuidle_sysfs_release,
+};
+
+struct cpuidle_state_attr {
+	struct attribute attr;
+	ssize_t (*show)(struct cpuidle_state *, char *);
+	ssize_t (*store)(struct cpuidle_state *, const char *, size_t);
+};
+
+#define define_one_state_ro(_name, show) \
+static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
+
+#define define_show_state_function(_name) \
+static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
+{ \
+	return sprintf(buf, "%u\n", state->_name);\
+}
+
+static ssize_t show_state_name(struct cpuidle_state *state, char *buf)
+{
+	return sprintf(buf, "%s\n", state->name);
+}
+
+define_show_state_function(exit_latency)
+define_show_state_function(power_usage)
+define_show_state_function(usage)
+define_show_state_function(time)
+define_one_state_ro(name, show_state_name);
+define_one_state_ro(latency, show_state_exit_latency);
+define_one_state_ro(power, show_state_power_usage);
+define_one_state_ro(usage, show_state_usage);
+define_one_state_ro(time, show_state_time);
+
+static struct attribute *cpuidle_state_default_attrs[] = {
+	&attr_name.attr,
+	&attr_latency.attr,
+	&attr_power.attr,
+	&attr_usage.attr,
+	&attr_time.attr,
+	NULL
+};
+
+#define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj)
+#define kobj_to_state(k) (kobj_to_state_obj(k)->state)
+#define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr)
+static ssize_t cpuidle_state_show(struct kobject * kobj,
+	struct attribute * attr ,char * buf)
+{
+	int ret = -EIO;
+	struct cpuidle_state *state = kobj_to_state(kobj);
+	struct cpuidle_state_attr * cattr = attr_to_stateattr(attr);
+
+	if (cattr->show)
+		ret = cattr->show(state, buf);
+
+	return ret;
+}
+
+static struct sysfs_ops cpuidle_state_sysfs_ops = {
+	.show = cpuidle_state_show,
+};
+
+static void cpuidle_state_sysfs_release(struct kobject *kobj)
+{
+	struct cpuidle_state_kobj *state_obj = kobj_to_state_obj(kobj);
+
+	complete(&state_obj->kobj_unregister);
+}
+
+static struct kobj_type ktype_state_cpuidle = {
+	.sysfs_ops = &cpuidle_state_sysfs_ops,
+	.default_attrs = cpuidle_state_default_attrs,
+	.release = cpuidle_state_sysfs_release,
+};
+
+static void inline cpuidle_free_state_kobj(struct cpuidle_device *device, int i)
+{
+	kobject_unregister(&device->kobjs[i]->kobj);
+	wait_for_completion(&device->kobjs[i]->kobj_unregister);
+	kfree(device->kobjs[i]);
+	device->kobjs[i] = NULL;
+}
+
+/**
+ * cpuidle_add_driver_sysfs - adds driver-specific sysfs attributes
+ * @device: the target device
+ */
+int cpuidle_add_state_sysfs(struct cpuidle_device *device)
+{
+	int i, ret = -ENOMEM;
+	struct cpuidle_state_kobj *kobj;
+
+	/* state statistics */
+	for (i = 0; i < device->state_count; i++) {
+		kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL);
+		if (!kobj)
+			goto error_state;
+		kobj->state = &device->states[i];
+		init_completion(&kobj->kobj_unregister);
+
+		kobj->kobj.parent = &device->kobj;
+		kobj->kobj.ktype = &ktype_state_cpuidle;
+		kobject_set_name(&kobj->kobj, "state%d", i);
+		ret = kobject_register(&kobj->kobj);
+		if (ret) {
+			kfree(kobj);
+			goto error_state;
+		}
+		device->kobjs[i] = kobj;
+	}
+
+	return 0;
+
+error_state:
+	for (i = i - 1; i >= 0; i--)
+		cpuidle_free_state_kobj(device, i);
+	return ret;
+}
+
+/**
+ * cpuidle_remove_driver_sysfs - removes driver-specific sysfs attributes
+ * @device: the target device
+ */
+void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
+{
+	int i;
+
+	for (i = 0; i < device->state_count; i++)
+		cpuidle_free_state_kobj(device, i);
+}
+
+/**
+ * cpuidle_add_sysfs - creates a sysfs instance for the target device
+ * @sysdev: the target device
+ */
+int cpuidle_add_sysfs(struct sys_device *sysdev)
+{
+	int cpu = sysdev->id;
+	struct cpuidle_device *dev;
+
+	dev = per_cpu(cpuidle_devices, cpu);
+	dev->kobj.parent = &sysdev->kobj;
+	dev->kobj.ktype = &ktype_cpuidle;
+	kobject_set_name(&dev->kobj, "%s", "cpuidle");
+	return kobject_register(&dev->kobj);
+}
+
+/**
+ * cpuidle_remove_sysfs - deletes a sysfs instance on the target device
+ * @sysdev: the target device
+ */
+void cpuidle_remove_sysfs(struct sys_device *sysdev)
+{
+	int cpu = sysdev->id;
+	struct cpuidle_device *dev;
+
+	dev = per_cpu(cpuidle_devices, cpu);
+	kobject_unregister(&dev->kobj);
+}
diff --git a/drivers/dma/ioat.c b/drivers/dma/ioat.c
index f7276bf..f204c39 100644
--- a/drivers/dma/ioat.c
+++ b/drivers/dma/ioat.c
@@ -34,7 +34,7 @@
 #include "ioatdma_registers.h"
 #include "ioatdma_hw.h"
 
-MODULE_VERSION("1.24");
+MODULE_VERSION(IOAT_DMA_VERSION);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Intel Corporation");
 
@@ -55,9 +55,7 @@
 
 static int __devinit ioat_probe(struct pci_dev *pdev,
 				const struct pci_device_id *id);
-#ifdef IOAT_DMA_REMOVE
 static void __devexit ioat_remove(struct pci_dev *pdev);
-#endif
 
 static int ioat_dca_enabled = 1;
 module_param(ioat_dca_enabled, int, 0644);
@@ -73,7 +71,7 @@
 	switch (version) {
 	case IOAT_VER_1_2:
 		device->dma = ioat_dma_probe(pdev, iobase);
-		if (ioat_dca_enabled)
+		if (device->dma && ioat_dca_enabled)
 			device->dca = ioat_dca_init(pdev, iobase);
 		break;
 	default:
@@ -87,27 +85,25 @@
 {
 	struct ioat_device *device = pci_get_drvdata(pdev);
 
-	if (device->dma) {
-		ioat_dma_remove(device->dma);
-		device->dma = NULL;
-	}
-
+	dev_err(&pdev->dev, "Removing dma and dca services\n");
 	if (device->dca) {
 		unregister_dca_provider(device->dca);
 		free_dca_provider(device->dca);
 		device->dca = NULL;
 	}
 
+	if (device->dma) {
+		ioat_dma_remove(device->dma);
+		device->dma = NULL;
+	}
 }
 
-static struct pci_driver ioat_pci_drv = {
+static struct pci_driver ioat_pci_driver = {
 	.name		= "ioatdma",
 	.id_table	= ioat_pci_tbl,
 	.probe		= ioat_probe,
 	.shutdown	= ioat_shutdown_functionality,
-#ifdef IOAT_DMA_REMOVE
 	.remove		= __devexit_p(ioat_remove),
-#endif
 };
 
 static int __devinit ioat_probe(struct pci_dev *pdev,
@@ -122,7 +118,7 @@
 	if (err)
 		goto err_enable_device;
 
-	err = pci_request_regions(pdev, ioat_pci_drv.name);
+	err = pci_request_regions(pdev, ioat_pci_driver.name);
 	if (err)
 		goto err_request_regions;
 
@@ -176,13 +172,11 @@
 	return err;
 }
 
-#ifdef IOAT_DMA_REMOVE
 /*
  * It is unsafe to remove this module: if removed while a requested
  * dma is outstanding, esp. from tcp, it is possible to hang while
- * waiting for something that will never finish, thus hanging at
- * least one cpu.  However, if you're feeling lucky and need to do
- * some testing, this usually works just fine.
+ * waiting for something that will never finish.  However, if you're
+ * feeling lucky, this usually works just fine.
  */
 static void __devexit ioat_remove(struct pci_dev *pdev)
 {
@@ -191,21 +185,16 @@
 	ioat_shutdown_functionality(pdev);
 
 	kfree(device);
-
-	iounmap(device->iobase);
-	pci_release_regions(pdev);
-	pci_disable_device(pdev);
 }
-#endif
 
 static int __init ioat_init_module(void)
 {
-	return pci_register_driver(&ioat_pci_drv);
+	return pci_register_driver(&ioat_pci_driver);
 }
 module_init(ioat_init_module);
 
 static void __exit ioat_exit_module(void)
 {
-	pci_unregister_driver(&ioat_pci_drv);
+	pci_unregister_driver(&ioat_pci_driver);
 }
 module_exit(ioat_exit_module);
diff --git a/drivers/dma/ioat_dca.c b/drivers/dma/ioat_dca.c
index 2ae04c3..ba98571 100644
--- a/drivers/dma/ioat_dca.c
+++ b/drivers/dma/ioat_dca.c
@@ -65,7 +65,7 @@
 	return (pci->bus->number << 8) | pci->devfn;
 }
 
-static int dca_enabled_in_bios(void)
+static int dca_enabled_in_bios(struct pci_dev *pdev)
 {
 	/* CPUID level 9 returns DCA configuration */
 	/* Bit 0 indicates DCA enabled by the BIOS */
@@ -75,17 +75,17 @@
 	cpuid_level_9 = cpuid_eax(9);
 	res = test_bit(0, &cpuid_level_9);
 	if (!res)
-		printk(KERN_ERR "ioat dma: DCA is disabled in BIOS\n");
+		dev_err(&pdev->dev, "DCA is disabled in BIOS\n");
 
 	return res;
 }
 
-static int system_has_dca_enabled(void)
+static int system_has_dca_enabled(struct pci_dev *pdev)
 {
 	if (boot_cpu_has(X86_FEATURE_DCA))
-		return dca_enabled_in_bios();
+		return dca_enabled_in_bios(pdev);
 
-	printk(KERN_ERR "ioat dma: boot cpu doesn't have X86_FEATURE_DCA\n");
+	dev_err(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n");
 	return 0;
 }
 
@@ -208,7 +208,7 @@
 	int i;
 	int err;
 
-	if (!system_has_dca_enabled())
+	if (!system_has_dca_enabled(pdev))
 		return NULL;
 
 	/* I/OAT v1 systems must have a known tag_map to support DCA */
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index 66c5bb5..7e4a785 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -46,9 +46,12 @@
 /* internal functions */
 static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan);
 static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan);
+static struct ioat_desc_sw *
+ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan);
 
-static struct ioat_dma_chan *ioat_lookup_chan_by_index(struct ioatdma_device *device,
-						       int index)
+static inline struct ioat_dma_chan *ioat_lookup_chan_by_index(
+						struct ioatdma_device *device,
+						int index)
 {
 	return device->idx[index];
 }
@@ -148,57 +151,102 @@
 			 struct dma_async_tx_descriptor *tx,
 			 int index)
 {
-	struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx);
-	struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
-
-	pci_unmap_addr_set(desc, src, addr);
-
-	list_for_each_entry(iter, &desc->async_tx.tx_list, node) {
-		iter->hw->src_addr = addr;
-		addr += ioat_chan->xfercap;
-	}
-
+	tx_to_ioat_desc(tx)->src = addr;
 }
 
 static void ioat_set_dest(dma_addr_t addr,
 			  struct dma_async_tx_descriptor *tx,
 			  int index)
 {
-	struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx);
-	struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
-
-	pci_unmap_addr_set(desc, dst, addr);
-
-	list_for_each_entry(iter, &desc->async_tx.tx_list, node) {
-		iter->hw->dst_addr = addr;
-		addr += ioat_chan->xfercap;
-	}
+	tx_to_ioat_desc(tx)->dst = addr;
 }
 
 static dma_cookie_t ioat_tx_submit(struct dma_async_tx_descriptor *tx)
 {
 	struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
-	struct ioat_desc_sw *desc = tx_to_ioat_desc(tx);
+	struct ioat_desc_sw *first = tx_to_ioat_desc(tx);
+	struct ioat_desc_sw *prev, *new;
+	struct ioat_dma_descriptor *hw;
 	int append = 0;
 	dma_cookie_t cookie;
-	struct ioat_desc_sw *group_start;
+	LIST_HEAD(new_chain);
+	u32 copy;
+	size_t len;
+	dma_addr_t src, dst;
+	int orig_ack;
+	unsigned int desc_count = 0;
 
-	group_start = list_entry(desc->async_tx.tx_list.next,
-				 struct ioat_desc_sw, node);
+	/* src and dest and len are stored in the initial descriptor */
+	len = first->len;
+	src = first->src;
+	dst = first->dst;
+	orig_ack = first->async_tx.ack;
+	new = first;
+
 	spin_lock_bh(&ioat_chan->desc_lock);
+	prev = to_ioat_desc(ioat_chan->used_desc.prev);
+	prefetch(prev->hw);
+	do {
+		copy = min((u32) len, ioat_chan->xfercap);
+
+		new->async_tx.ack = 1;
+
+		hw = new->hw;
+		hw->size = copy;
+		hw->ctl = 0;
+		hw->src_addr = src;
+		hw->dst_addr = dst;
+		hw->next = 0;
+
+		/* chain together the physical address list for the HW */
+		wmb();
+		prev->hw->next = (u64) new->async_tx.phys;
+
+		len -= copy;
+		dst += copy;
+		src += copy;
+
+		list_add_tail(&new->node, &new_chain);
+		desc_count++;
+		prev = new;
+	} while (len && (new = ioat_dma_get_next_descriptor(ioat_chan)));
+
+	hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
+	if (new->async_tx.callback) {
+		hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
+		if (first != new) {
+			/* move callback into to last desc */
+			new->async_tx.callback = first->async_tx.callback;
+			new->async_tx.callback_param
+					= first->async_tx.callback_param;
+			first->async_tx.callback = NULL;
+			first->async_tx.callback_param = NULL;
+		}
+	}
+
+	new->tx_cnt = desc_count;
+	new->async_tx.ack = orig_ack; /* client is in control of this ack */
+
+	/* store the original values for use in later cleanup */
+	if (new != first) {
+		new->src = first->src;
+		new->dst = first->dst;
+		new->len = first->len;
+	}
+
 	/* cookie incr and addition to used_list must be atomic */
 	cookie = ioat_chan->common.cookie;
 	cookie++;
 	if (cookie < 0)
 		cookie = 1;
-	ioat_chan->common.cookie = desc->async_tx.cookie = cookie;
+	ioat_chan->common.cookie = new->async_tx.cookie = cookie;
 
 	/* write address into NextDescriptor field of last desc in chain */
 	to_ioat_desc(ioat_chan->used_desc.prev)->hw->next =
-						group_start->async_tx.phys;
-	list_splice_init(&desc->async_tx.tx_list, ioat_chan->used_desc.prev);
+							first->async_tx.phys;
+	__list_splice(&new_chain, ioat_chan->used_desc.prev);
 
-	ioat_chan->pending += desc->tx_cnt;
+	ioat_chan->pending += desc_count;
 	if (ioat_chan->pending >= 4) {
 		append = 1;
 		ioat_chan->pending = 0;
@@ -267,7 +315,7 @@
 	chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
 	if (chanerr) {
 		dev_err(&ioat_chan->device->pdev->dev,
-			"ioatdma: CHANERR = %x, clearing\n", chanerr);
+			"CHANERR = %x, clearing\n", chanerr);
 		writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
 	}
 
@@ -276,7 +324,7 @@
 		desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL);
 		if (!desc) {
 			dev_err(&ioat_chan->device->pdev->dev,
-				"ioatdma: Only %d initial descriptors\n", i);
+				"Only %d initial descriptors\n", i);
 			break;
 		}
 		list_add_tail(&desc->node, &tmp_list);
@@ -342,12 +390,13 @@
 	/* one is ok since we left it on there on purpose */
 	if (in_use_descs > 1)
 		dev_err(&ioat_chan->device->pdev->dev,
-			"ioatdma: Freeing %d in use descriptors!\n",
+			"Freeing %d in use descriptors!\n",
 			in_use_descs - 1);
 
 	ioat_chan->last_completion = ioat_chan->completion_addr = 0;
 	ioat_chan->pending = 0;
 }
+
 /**
  * ioat_dma_get_next_descriptor - return the next available descriptor
  * @ioat_chan: IOAT DMA channel handle
@@ -356,8 +405,8 @@
  * channel's desc_lock held.  Allocates more descriptors if the channel
  * has run out.
  */
-static struct ioat_desc_sw *ioat_dma_get_next_descriptor(
-						struct ioat_dma_chan *ioat_chan)
+static struct ioat_desc_sw *
+ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
 {
 	struct ioat_desc_sw *new = NULL;
 
@@ -382,51 +431,11 @@
 						int int_en)
 {
 	struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
-	struct ioat_desc_sw *first, *prev, *new;
-	LIST_HEAD(new_chain);
-	u32 copy;
-	size_t orig_len;
-	int desc_count = 0;
-
-	if (!len)
-		return NULL;
-
-	orig_len = len;
-
-	first = NULL;
-	prev = NULL;
+	struct ioat_desc_sw *new;
 
 	spin_lock_bh(&ioat_chan->desc_lock);
-	while (len) {
-		new = ioat_dma_get_next_descriptor(ioat_chan);
-		copy = min((u32) len, ioat_chan->xfercap);
-
-		new->hw->size = copy;
-		new->hw->ctl = 0;
-		new->async_tx.cookie = 0;
-		new->async_tx.ack = 1;
-
-		/* chain together the physical address list for the HW */
-		if (!first)
-			first = new;
-		else
-			prev->hw->next = (u64) new->async_tx.phys;
-
-		prev = new;
-		len  -= copy;
-		list_add_tail(&new->node, &new_chain);
-		desc_count++;
-	}
-
-	list_splice(&new_chain, &new->async_tx.tx_list);
-
-	new->hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
-	new->hw->next = 0;
-	new->tx_cnt = desc_count;
-	new->async_tx.ack = 0; /* client is in control of this ack */
-	new->async_tx.cookie = -EBUSY;
-
-	pci_unmap_len_set(new, len, orig_len);
+	new = ioat_dma_get_next_descriptor(ioat_chan);
+	new->len = len;
 	spin_unlock_bh(&ioat_chan->desc_lock);
 
 	return new ? &new->async_tx : NULL;
@@ -464,7 +473,7 @@
 
 	prefetch(ioat_chan->completion_virt);
 
-	if (!spin_trylock(&ioat_chan->cleanup_lock))
+	if (!spin_trylock_bh(&ioat_chan->cleanup_lock))
 		return;
 
 	/* The completion writeback can happen at any time,
@@ -474,22 +483,25 @@
 
 #if (BITS_PER_LONG == 64)
 	phys_complete =
-	ioat_chan->completion_virt->full & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR;
+		ioat_chan->completion_virt->full
+		& IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR;
 #else
-	phys_complete = ioat_chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK;
+	phys_complete =
+		ioat_chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK;
 #endif
 
-	if ((ioat_chan->completion_virt->full & IOAT_CHANSTS_DMA_TRANSFER_STATUS) ==
+	if ((ioat_chan->completion_virt->full
+		& IOAT_CHANSTS_DMA_TRANSFER_STATUS) ==
 				IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) {
 		dev_err(&ioat_chan->device->pdev->dev,
-			"ioatdma: Channel halted, chanerr = %x\n",
+			"Channel halted, chanerr = %x\n",
 			readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET));
 
 		/* TODO do something to salvage the situation */
 	}
 
 	if (phys_complete == ioat_chan->last_completion) {
-		spin_unlock(&ioat_chan->cleanup_lock);
+		spin_unlock_bh(&ioat_chan->cleanup_lock);
 		return;
 	}
 
@@ -517,6 +529,11 @@
 					pci_unmap_addr(desc, src),
 					pci_unmap_len(desc, len),
 					PCI_DMA_TODEVICE);
+			if (desc->async_tx.callback) {
+				desc->async_tx.callback(
+						desc->async_tx.callback_param);
+				desc->async_tx.callback = NULL;
+			}
 		}
 
 		if (desc->async_tx.phys != phys_complete) {
@@ -548,7 +565,7 @@
 	if (cookie != 0)
 		ioat_chan->completed_cookie = cookie;
 
-	spin_unlock(&ioat_chan->cleanup_lock);
+	spin_unlock_bh(&ioat_chan->cleanup_lock);
 }
 
 static void ioat_dma_dependency_added(struct dma_chan *chan)
@@ -613,8 +630,13 @@
 	spin_lock_bh(&ioat_chan->desc_lock);
 
 	desc = ioat_dma_get_next_descriptor(ioat_chan);
-	desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL;
+	desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL
+				| IOAT_DMA_DESCRIPTOR_CTL_INT_GN
+				| IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
 	desc->hw->next = 0;
+	desc->hw->size = 0;
+	desc->hw->src_addr = 0;
+	desc->hw->dst_addr = 0;
 	desc->async_tx.ack = 1;
 
 	list_add_tail(&desc->node, &ioat_chan->used_desc);
@@ -633,6 +655,12 @@
  */
 #define IOAT_TEST_SIZE 2000
 
+static void ioat_dma_test_callback(void *dma_async_param)
+{
+	printk(KERN_ERR "ioatdma: ioat_dma_test_callback(%p)\n",
+			dma_async_param);
+}
+
 /**
  * ioat_dma_self_test - Perform a IOAT transaction to verify the HW works.
  * @device: device to be tested
@@ -643,7 +671,7 @@
 	u8 *src;
 	u8 *dest;
 	struct dma_chan *dma_chan;
-	struct dma_async_tx_descriptor *tx;
+	struct dma_async_tx_descriptor *tx = NULL;
 	dma_addr_t addr;
 	dma_cookie_t cookie;
 	int err = 0;
@@ -673,6 +701,13 @@
 	}
 
 	tx = ioat_dma_prep_memcpy(dma_chan, IOAT_TEST_SIZE, 0);
+	if (!tx) {
+		dev_err(&device->pdev->dev,
+			"Self-test prep failed, disabling\n");
+		err = -ENODEV;
+		goto free_resources;
+	}
+
 	async_tx_ack(tx);
 	addr = dma_map_single(dma_chan->device->dev, src, IOAT_TEST_SIZE,
 			DMA_TO_DEVICE);
@@ -680,19 +715,27 @@
 	addr = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE,
 			DMA_FROM_DEVICE);
 	ioat_set_dest(addr, tx, 0);
+	tx->callback = ioat_dma_test_callback;
+	tx->callback_param = (void *)0x8086;
 	cookie = ioat_tx_submit(tx);
+	if (cookie < 0) {
+		dev_err(&device->pdev->dev,
+			"Self-test setup failed, disabling\n");
+		err = -ENODEV;
+		goto free_resources;
+	}
 	ioat_dma_memcpy_issue_pending(dma_chan);
 	msleep(1);
 
 	if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) {
 		dev_err(&device->pdev->dev,
-			"ioatdma: Self-test copy timed out, disabling\n");
+			"Self-test copy timed out, disabling\n");
 		err = -ENODEV;
 		goto free_resources;
 	}
 	if (memcmp(src, dest, IOAT_TEST_SIZE)) {
 		dev_err(&device->pdev->dev,
-			"ioatdma: Self-test copy failed compare, disabling\n");
+			"Self-test copy failed compare, disabling\n");
 		err = -ENODEV;
 		goto free_resources;
 	}
@@ -730,6 +773,9 @@
 		goto msi;
 	if (!strcmp(ioat_interrupt_style, "intx"))
 		goto intx;
+	dev_err(&device->pdev->dev, "invalid ioat_interrupt_style %s\n",
+		ioat_interrupt_style);
+	goto err_no_irq;
 
 msix:
 	/* The number of MSI-X vectors should equal the number of channels */
@@ -906,9 +952,9 @@
 	device->common.device_dependency_added = ioat_dma_dependency_added;
 	device->common.dev = &pdev->dev;
 	dev_err(&device->pdev->dev,
-		"ioatdma: Intel(R) I/OAT DMA Engine found,"
-		" %d channels, device version 0x%02x\n",
-		device->common.chancnt, device->version);
+		"Intel(R) I/OAT DMA Engine found,"
+		" %d channels, device version 0x%02x, driver version %s\n",
+		device->common.chancnt, device->version, IOAT_DMA_VERSION);
 
 	err = ioat_dma_setup_interrupts(device);
 	if (err)
@@ -931,9 +977,8 @@
 err_dma_pool:
 	kfree(device);
 err_kzalloc:
-	iounmap(iobase);
 	dev_err(&device->pdev->dev,
-		"ioatdma: Intel(R) I/OAT DMA Engine initialization failed\n");
+		"Intel(R) I/OAT DMA Engine initialization failed\n");
 	return NULL;
 }
 
@@ -942,13 +987,17 @@
 	struct dma_chan *chan, *_chan;
 	struct ioat_dma_chan *ioat_chan;
 
-	dma_async_device_unregister(&device->common);
-
 	ioat_dma_remove_interrupts(device);
 
+	dma_async_device_unregister(&device->common);
+
 	pci_pool_destroy(device->dma_pool);
 	pci_pool_destroy(device->completion_pool);
 
+	iounmap(device->reg_base);
+	pci_release_regions(device->pdev);
+	pci_disable_device(device->pdev);
+
 	list_for_each_entry_safe(chan, _chan,
 				 &device->common.channels, device_node) {
 		ioat_chan = to_ioat_chan(chan);
diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h
index 2a319e1..5f9881e7 100644
--- a/drivers/dma/ioatdma.h
+++ b/drivers/dma/ioatdma.h
@@ -28,6 +28,8 @@
 #include <linux/cache.h>
 #include <linux/pci_ids.h>
 
+#define IOAT_DMA_VERSION "1.26"
+
 enum ioat_interrupt {
 	none = 0,
 	msix_multi_vector = 1,
@@ -122,9 +124,9 @@
 	struct ioat_dma_descriptor *hw;
 	struct list_head node;
 	int tx_cnt;
-	DECLARE_PCI_UNMAP_LEN(len)
-	DECLARE_PCI_UNMAP_ADDR(src)
-	DECLARE_PCI_UNMAP_ADDR(dst)
+	size_t len;
+	dma_addr_t src;
+	dma_addr_t dst;
 	struct dma_async_tx_descriptor async_tx;
 };
 
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index e80af67..2d23e30 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -94,8 +94,6 @@
 
 #endif				/* !CONFIG_EDAC_DEBUG */
 
-#define BIT(x) (1 << (x))
-
 #define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \
 	PCI_DEVICE_ID_ ## vend ## _ ## dev
 
diff --git a/drivers/edac/pasemi_edac.c b/drivers/edac/pasemi_edac.c
index e66cdd4..9007d06 100644
--- a/drivers/edac/pasemi_edac.c
+++ b/drivers/edac/pasemi_edac.c
@@ -270,6 +270,7 @@
 
 static const struct pci_device_id pasemi_edac_pci_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa00a) },
+	{ }
 };
 
 MODULE_DEVICE_TABLE(pci, pasemi_edac_pci_tbl);
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 2f307c4..6758832 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -606,7 +606,7 @@
 at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
 {
 	struct fw_ohci *ohci = ctx->ohci;
-	dma_addr_t d_bus, payload_bus;
+	dma_addr_t d_bus, uninitialized_var(payload_bus);
 	struct driver_data *driver_data;
 	struct descriptor *d, *last;
 	__le32 *header;
@@ -1459,7 +1459,7 @@
 	/* FIXME: We need a fallback for pre 1.1 OHCI. */
 	if (callback == handle_ir_dualbuffer_packet &&
 	    ohci->version < OHCI_VERSION_1_1)
-		return ERR_PTR(-EINVAL);
+		return ERR_PTR(-ENOSYS);
 
 	spin_lock_irqsave(&ohci->lock, flags);
 	index = ffs(*mask) - 1;
@@ -1778,7 +1778,7 @@
 							 buffer, payload);
 	else
 		/* FIXME: Implement fallback for OHCI 1.0 controllers. */
-		return -EINVAL;
+		return -ENOSYS;
 }
 
 static const struct fw_card_driver ohci_driver = {
@@ -1898,7 +1898,12 @@
 	ohci->version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
 	fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n",
 		  dev->dev.bus_id, ohci->version >> 16, ohci->version & 0xff);
-
+	if (ohci->version < OHCI_VERSION_1_1) {
+		fw_notify("    Isochronous I/O is not yet implemented for "
+			  "OHCI 1.0 chips.\n");
+		fw_notify("    Cameras, audio devices etc. won't work on "
+			  "this controller with this driver version.\n");
+	}
 	return 0;
 
  fail_self_id:
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index 9959b79..c00d4a9 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -228,7 +228,7 @@
  *
  * @param card the card from which to send the request
  * @param tcode the tcode for this transaction.  Do not use
- *   TCODE_LOCK_REQUEST directly, insted use TCODE_LOCK_MASK_SWAP
+ *   TCODE_LOCK_REQUEST directly, instead use TCODE_LOCK_MASK_SWAP
  *   etc. to specify tcode and ext_tcode.
  * @param node_id the destination node ID (bus ID and PHY ID concatenated)
  * @param generation the generation for which node_id is valid
diff --git a/drivers/firmware/dcdbas.h b/drivers/firmware/dcdbas.h
index dcdba0f..87bc341 100644
--- a/drivers/firmware/dcdbas.h
+++ b/drivers/firmware/dcdbas.h
@@ -17,7 +17,6 @@
 #define _DCDBAS_H_
 
 #include <linux/device.h>
-#include <linux/input.h>
 #include <linux/sysfs.h>
 #include <linux/types.h>
 
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index a702e2f..1ca6f46 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -113,13 +113,13 @@
 
 	if (count > HID_MIN_BUFFER_SIZE) {
 		printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
-				current->pid);
+				task_pid_nr(current));
 		return -EINVAL;
 	}
 
 	if (count < 2) {
 		printk(KERN_WARNING "hidraw: pid %d passed too short report\n",
-				current->pid);
+				task_pid_nr(current));
 		return -EINVAL;
 	}
 
diff --git a/drivers/hid/usbhid/hid-ff.c b/drivers/hid/usbhid/hid-ff.c
index 22329fe..4c210e1 100644
--- a/drivers/hid/usbhid/hid-ff.c
+++ b/drivers/hid/usbhid/hid-ff.c
@@ -1,6 +1,4 @@
 /*
- * $Id: hid-ff.c,v 1.2 2002/04/18 22:02:47 jdeneux Exp $
- *
  *  Force feedback support for hid devices.
  *  Not all hid devices use the same protocol. For example, some use PID,
  *  other use their own proprietary procotol.
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
index b76b02f..775a1ef 100644
--- a/drivers/hid/usbhid/usbkbd.c
+++ b/drivers/hid/usbhid/usbkbd.c
@@ -274,8 +274,11 @@
 
 	input_set_drvdata(input_dev, kbd);
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
-	input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
+		BIT_MASK(EV_REP);
+	input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
+		BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_COMPOSE) |
+		BIT_MASK(LED_KANA);
 
 	for (i = 0; i < 255; i++)
 		set_bit(usb_kbd_keycode[i], input_dev->keybit);
diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c
index 5345c73..f8ad691 100644
--- a/drivers/hid/usbhid/usbmouse.c
+++ b/drivers/hid/usbhid/usbmouse.c
@@ -173,11 +173,13 @@
 	usb_to_input_id(dev, &input_dev->id);
 	input_dev->dev.parent = &intf->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-	input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-	input_dev->relbit[0] |= BIT(REL_WHEEL);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+	input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+	input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |
+		BIT_MASK(BTN_EXTRA);
+	input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
 
 	input_set_drvdata(input_dev, mouse);
 
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index aa875ca..3e63c14 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -1651,7 +1651,7 @@
 		break;
 	default :
 		dev_err(&adapter->dev, ": Internal error, invalid "
-			"kind (%d)!", kind);
+			"kind (%d)!\n", kind);
 		err = -EFAULT;
 		goto exitfree;
 	}
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 4879125..1001d2e 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -1099,7 +1099,7 @@
 	idev->name = "applesmc";
 	idev->id.bustype = BUS_HOST;
 	idev->dev.parent = &pdev->dev;
-	idev->evbit[0] = BIT(EV_ABS);
+	idev->evbit[0] = BIT_MASK(EV_ABS);
 	input_set_abs_params(idev, ABS_X,
 			-256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
 	input_set_abs_params(idev, ABS_Y,
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 6f66551..5c82ec7 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -150,7 +150,7 @@
 static int __devinit coretemp_probe(struct platform_device *pdev)
 {
 	struct coretemp_data *data;
-	struct cpuinfo_x86 *c = &(cpu_data)[pdev->id];
+	struct cpuinfo_x86 *c = &cpu_data(pdev->id);
 	int err;
 	u32 eax, edx;
 
@@ -359,7 +359,7 @@
 	struct pdev_entry *p, *n;
 
 	/* quick check if we run Intel */
-	if (cpu_data[0].x86_vendor != X86_VENDOR_INTEL)
+	if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
 		goto exit;
 
 	err = platform_driver_register(&coretemp_driver);
@@ -367,7 +367,7 @@
 		goto exit;
 
 	for_each_online_cpu(i) {
-		struct cpuinfo_x86 *c = &(cpu_data)[i];
+		struct cpuinfo_x86 *c = &cpu_data(i);
 
 		/* check if family 6, models e, f, 16 */
 		if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index a3b56c8..2d39d8f 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -2,7 +2,7 @@
     gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware
                 monitoring
     Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>,
-                              Kyösti Mälkki <kmalkki@cc.hut.fi>
+                              Kyösti Mälkki <kmalkki@cc.hut.fi>
     Copyright (c) 2005        Maarten Deprez <maartendeprez@users.sourceforge.net>
 
     This program is free software; you can redistribute it and/or modify
@@ -805,7 +805,7 @@
 
 
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
-	"Kyösti Mälkki <kmalkki@cc.hut.fi>, "
+	"Kyösti Mälkki <kmalkki@cc.hut.fi>, "
 	"Maarten Deprez <maartendeprez@users.sourceforge.net>");
 MODULE_DESCRIPTION("GL520SM driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 8a7ae03..bab5fd2 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -574,7 +574,7 @@
 	idev = hdaps_idev->input;
 	idev->name = "hdaps";
 	idev->dev.parent = &pdev->dev;
-	idev->evbit[0] = BIT(EV_ABS);
+	idev->evbit[0] = BIT_MASK(EV_ABS);
 	input_set_abs_params(idev, ABS_X,
 			-256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
 	input_set_abs_params(idev, ABS_Y,
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index f17e771..3330667 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -200,7 +200,7 @@
 
 u8 vid_which_vrm(void)
 {
-	struct cpuinfo_x86 *c = cpu_data;
+	struct cpuinfo_x86 *c = &cpu_data(0);
 	u32 eax;
 	u8 eff_family, eff_model, eff_stepping, vrm_ret;
 
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index f207434..650b07d 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -533,7 +533,7 @@
 
 	/* Start converting if needed */
 	if (data->config & 0x40) { /* standby */
-		dev_dbg(&client->dev, "Switching to operational mode");
+		dev_dbg(&client->dev, "Switching to operational mode\n");
 		data->config &= 0xA7;
 		i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1,
 					  data->config);
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index 860b71c..7e2d978 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -3,7 +3,7 @@
 		for hardware monitoring
 
     Copyright (C) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>,
-			Kyösti Mälkki <kmalkki@cc.hut.fi>, and
+			Kyösti Mälkki <kmalkki@cc.hut.fi>, and
 			Mark D. Studebaker <mdsxyz123@yahoo.com>
     Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
     the help of Jean Delvare <khali@linux-fr.org>
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index 8f63dad..2635bba 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -3,7 +3,7 @@
 		for hardware monitoring
 
     Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
-			Kyösti Mälkki <kmalkki@cc.hut.fi>,
+			Kyösti Mälkki <kmalkki@cc.hut.fi>,
 			Mark Studebaker <mdsxyz123@yahoo.com>,
 			and Bob Dougherty <bobd@stanford.edu>
     (Some conversion-factor data were contributed by Jonathan Teh Soon Yew
@@ -866,7 +866,7 @@
 	}
 }
 
-MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>, "
+MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>, "
 	      "Mark Studebaker <mdsxyz123@yahoo.com> "
 	      "and Bob Dougherty <bobd@stanford.edu>");
 MODULE_DESCRIPTION("VIA 686A Sensor device");
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index e694164..7dfcc8d 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -795,7 +795,7 @@
 
 	if ((val < 0) || (val > 255)) {
 		dev_err(dev, "pwm value %ld is out of range. "
-			"Choose a value between 0 and 255." , val);
+			"Choose a value between 0 and 255.\n" , val);
 		return -EINVAL;
 	}
 
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index b6f2ebf..a9c01a6 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -1096,7 +1096,7 @@
 	if (kind == w83791d) {
 		client_name = "w83791d";
 	} else {
-		dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?",
+		dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?\n",
 			kind);
 		goto error1;
 	}
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index f836198..007449d 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -1385,8 +1385,8 @@
 	if (kind == w83792d) {
 		client_name = "w83792d";
 	} else {
-		dev_err(dev, "w83792d: Internal error: unknown"
-					  " kind (%d)?!?", kind);
+		dev_err(dev, "w83792d: Internal error: unknown kind (%d)?!?\n",
+			kind);
 		goto ERROR1;
 	}
 
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index 7f0a0a6..a37cb6b 100644
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -18,7 +18,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
 /* ------------------------------------------------------------------------- */
 
-/* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki
+/* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki
    <kmalkki@cc.hut.fi> and Jean Delvare <khali@linux-fr.org> */
 
 #include <linux/kernel.h>
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
index 36fdf97..2a16211 100644
--- a/drivers/i2c/algos/i2c-algo-pca.c
+++ b/drivers/i2c/algos/i2c-algo-pca.c
@@ -350,7 +350,7 @@
 	pca_outw(adap, I2C_PCA_ADR, own << 1);
 
 	pca_set_con(adap, I2C_PCA_CON_ENSIO | clock);
-	udelay(500); /* 500 µs for oscilator to stabilise */
+	udelay(500); /* 500 µs for oscilator to stabilise */
 
 	return 0;
 }
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c
index ecb2c2d..ab2e6f3 100644
--- a/drivers/i2c/algos/i2c-algo-pcf.c
+++ b/drivers/i2c/algos/i2c-algo-pcf.c
@@ -19,7 +19,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
 /* ------------------------------------------------------------------------- */
 
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and 
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
    Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
    <mbailey@littlefeet-inc.com> */
 
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index de95c75..c466c6c 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -278,7 +278,7 @@
 	depends on ARCH_IXP2000
 	select I2C_ALGOBIT
 	help
-	  Say Y here if you have an Intel IXP2000(2400, 2800, 2850) based 
+	  Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based 
 	  system and are using GPIO lines for an I2C bus.
 
 	  This support is also available as a module. If so, the module
@@ -293,8 +293,8 @@
 	default y
 	help
 	  This exposes the various PowerMac i2c interfaces to the linux i2c
-	  layer and to userland. It is used by various drivers on the powemac
-	  platform, thus should generally be enabled.
+	  layer and to userland. It is used by various drivers on the PowerMac
+	  platform, and should generally be enabled.
 
 	  This support is also available as a module.  If so, the module
 	  will be called i2c-powermac.
@@ -438,12 +438,12 @@
 	tristate "Simtec Generic I2C interface"
 	select I2C_ALGOBIT
 	help
-	  If you say yes to this option, support will be inclyded for
+	  If you say yes to this option, support will be included for
 	  the Simtec Generic I2C interface. This driver is for the
 	  simple I2C bus used on newer Simtec products for general
 	  I2C, such as DDC on the Simtec BBD2016A.
 
-	  This driver can also be build as a module. If so, the module
+	  This driver can also be built as a module. If so, the module
 	  will be called i2c-simtec.
 
 config SCx200_I2C
diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
index 804f0a5..b7a9977 100644
--- a/drivers/i2c/busses/i2c-elektor.c
+++ b/drivers/i2c/busses/i2c-elektor.c
@@ -19,7 +19,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
 /* ------------------------------------------------------------------------- */
 
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
 /* Partialy rewriten by Oleg I. Vdovikin for mmapped support of
diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c
index 9832f77..f9972f9 100644
--- a/drivers/i2c/busses/i2c-hydra.c
+++ b/drivers/i2c/busses/i2c-hydra.c
@@ -7,7 +7,7 @@
     Copyright (c) 1999-2004 Geert Uytterhoeven <geert@linux-m68k.org>
 
     Based on i2c Support for Via Technologies 82C586B South Bridge
-    Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
+    Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
 
     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
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index e08baca..9b43ff72 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -18,7 +18,7 @@
  *   	Copyright 1995-97 Simon G. Vogl
  *                1998-99 Hans Berglund
  *
- *   	With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> 
+ *   	With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>
  *	and even Frodo Looijaard <frodol@dds.nl>
  *
  * This program is free software; you can redistribute  it and/or modify it
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index e471e3b..89a3002 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -8,7 +8,7 @@
  * Tony Lindgren <tony@atomide.com> and Imre Deak <imre.deak@nokia.com>
  * Copyright (C) 2005 Nokia Corporation
  *
- * Cleaned up by Juha Yrjölä <juha.yrjola@nokia.com>
+ * Cleaned up by Juha Yrjölä <juha.yrjola@nokia.com>
  *
  * 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
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c
index 49a95e2..c6faf9b 100644
--- a/drivers/i2c/busses/i2c-parport-light.c
+++ b/drivers/i2c/busses/i2c-parport-light.c
@@ -7,7 +7,7 @@
    Copyright (C) 1995-2000 Simon G. Vogl
    With some changes from:
    Frodo Looijaard <frodol@dds.nl>
-   Kyösti Mälkki <kmalkki@cc.hut.fi>
+   Kyösti Mälkki <kmalkki@cc.hut.fi>
    
    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
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index 039a07f..59ba208 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -7,7 +7,7 @@
    Copyright (C) 1995-2000 Simon G. Vogl
    With some changes from:
    Frodo Looijaard <frodol@dds.nl>
-   Kyösti Mälkki <kmalkki@cc.hut.fi>
+   Kyösti Mälkki <kmalkki@cc.hut.fi>
    
    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
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c
index 17cecf1..be99c02 100644
--- a/drivers/i2c/busses/i2c-pmcmsp.c
+++ b/drivers/i2c/busses/i2c-pmcmsp.c
@@ -591,18 +591,18 @@
 	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);
+	dev_dbg(&adap->dev, "I2C %s of %d bytes %s\n",
+		(msg->flags & I2C_M_RD) ? "read" : "write", msg->len,
+		(ret == MSP_TWI_XFER_OK) ? "succeeded" : "failed");
+
 	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;
 }
 
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index 17376fe..f8d0dff 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -575,7 +575,7 @@
 	else {
 		freq_mhz = PNX_DEFAULT_FREQ;
 		dev_info(&pdev->dev, "Setting bus frequency to default value: "
-		       "%d MHz", freq_mhz);
+		       "%d MHz\n", freq_mhz);
 	}
 
 	i2c_pnx->adapter->algo = &pnx_algorithm;
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 00fad11..6426a61 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -85,7 +85,7 @@
 	const char *set;
 	const char *unset;
 };
-#define BIT(m, s, u)	{ .mask = m, .set = s, .unset = u }
+#define PXA_BIT(m, s, u)	{ .mask = m, .set = s, .unset = u }
 
 static inline void
 decode_bits(const char *prefix, const struct bits *bits, int num, u32 val)
@@ -100,17 +100,17 @@
 }
 
 static const struct bits isr_bits[] = {
-	BIT(ISR_RWM,	"RX",		"TX"),
-	BIT(ISR_ACKNAK,	"NAK",		"ACK"),
-	BIT(ISR_UB,	"Bsy",		"Rdy"),
-	BIT(ISR_IBB,	"BusBsy",	"BusRdy"),
-	BIT(ISR_SSD,	"SlaveStop",	NULL),
-	BIT(ISR_ALD,	"ALD",		NULL),
-	BIT(ISR_ITE,	"TxEmpty",	NULL),
-	BIT(ISR_IRF,	"RxFull",	NULL),
-	BIT(ISR_GCAD,	"GenCall",	NULL),
-	BIT(ISR_SAD,	"SlaveAddr",	NULL),
-	BIT(ISR_BED,	"BusErr",	NULL),
+	PXA_BIT(ISR_RWM,	"RX",		"TX"),
+	PXA_BIT(ISR_ACKNAK,	"NAK",		"ACK"),
+	PXA_BIT(ISR_UB,		"Bsy",		"Rdy"),
+	PXA_BIT(ISR_IBB,	"BusBsy",	"BusRdy"),
+	PXA_BIT(ISR_SSD,	"SlaveStop",	NULL),
+	PXA_BIT(ISR_ALD,	"ALD",		NULL),
+	PXA_BIT(ISR_ITE,	"TxEmpty",	NULL),
+	PXA_BIT(ISR_IRF,	"RxFull",	NULL),
+	PXA_BIT(ISR_GCAD,	"GenCall",	NULL),
+	PXA_BIT(ISR_SAD,	"SlaveAddr",	NULL),
+	PXA_BIT(ISR_BED,	"BusErr",	NULL),
 };
 
 static void decode_ISR(unsigned int val)
@@ -120,21 +120,21 @@
 }
 
 static const struct bits icr_bits[] = {
-	BIT(ICR_START,  "START",	NULL),
-	BIT(ICR_STOP,   "STOP",		NULL),
-	BIT(ICR_ACKNAK, "ACKNAK",	NULL),
-	BIT(ICR_TB,     "TB",		NULL),
-	BIT(ICR_MA,     "MA",		NULL),
-	BIT(ICR_SCLE,   "SCLE",		"scle"),
-	BIT(ICR_IUE,    "IUE",		"iue"),
-	BIT(ICR_GCD,    "GCD",		NULL),
-	BIT(ICR_ITEIE,  "ITEIE",	NULL),
-	BIT(ICR_IRFIE,  "IRFIE",	NULL),
-	BIT(ICR_BEIE,   "BEIE",		NULL),
-	BIT(ICR_SSDIE,  "SSDIE",	NULL),
-	BIT(ICR_ALDIE,  "ALDIE",	NULL),
-	BIT(ICR_SADIE,  "SADIE",	NULL),
-	BIT(ICR_UR,     "UR",		"ur"),
+	PXA_BIT(ICR_START,  "START",	NULL),
+	PXA_BIT(ICR_STOP,   "STOP",	NULL),
+	PXA_BIT(ICR_ACKNAK, "ACKNAK",	NULL),
+	PXA_BIT(ICR_TB,     "TB",	NULL),
+	PXA_BIT(ICR_MA,     "MA",	NULL),
+	PXA_BIT(ICR_SCLE,   "SCLE",	"scle"),
+	PXA_BIT(ICR_IUE,    "IUE",	"iue"),
+	PXA_BIT(ICR_GCD,    "GCD",	NULL),
+	PXA_BIT(ICR_ITEIE,  "ITEIE",	NULL),
+	PXA_BIT(ICR_IRFIE,  "IRFIE",	NULL),
+	PXA_BIT(ICR_BEIE,   "BEIE",	NULL),
+	PXA_BIT(ICR_SSDIE,  "SSDIE",	NULL),
+	PXA_BIT(ICR_ALDIE,  "ALDIE",	NULL),
+	PXA_BIT(ICR_SADIE,  "SADIE",	NULL),
+	PXA_BIT(ICR_UR,     "UR",		"ur"),
 };
 
 static void decode_ICR(unsigned int val)
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
index 8152086..61716f6 100644
--- a/drivers/i2c/busses/i2c-via.c
+++ b/drivers/i2c/busses/i2c-via.c
@@ -4,7 +4,7 @@
 
     i2c Support for Via Technologies 82C586B South Bridge
 
-    Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
+    Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
 
     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
@@ -176,7 +176,7 @@
 }
 
 
-MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>");
+MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>");
 MODULE_DESCRIPTION("i2c for Via vt82c586b southbridge");
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index edc2750..c9ce77f 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -2,7 +2,7 @@
     i2c-viapro.c - Part of lm_sensors, Linux kernel modules for hardware
               monitoring
     Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
-    Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
+    Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
     Mark D. Studebaker <mdsxyz123@yahoo.com>
     Copyright (C) 2005 - 2007  Jean Delvare <khali@linux-fr.org>
 
diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c
index 66436ba..2dea012 100644
--- a/drivers/i2c/chips/menelaus.c
+++ b/drivers/i2c/chips/menelaus.c
@@ -1195,7 +1195,7 @@
 		err = request_irq(client->irq, menelaus_irq, IRQF_DISABLED,
 				  DRIVER_NAME, menelaus);
 		if (err) {
-			dev_dbg(&client->dev,  "can't get IRQ %d, err %d",
+			dev_dbg(&client->dev,  "can't get IRQ %d, err %d\n",
 					client->irq, err);
 			goto fail1;
 		}
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index e73d58c..1a4e8dc 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -17,7 +17,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
 /* ------------------------------------------------------------------------- */
 
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
    All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
    SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
    Jean Delvare <khali@linux-fr.org> */
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 6d9fd92..6eaece9 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -1056,6 +1056,9 @@
 config BLK_DEV_IDEDMA
 	def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
 
+config IDE_ARCH_OBSOLETE_INIT
+	def_bool ALPHA || (ARM && !ARCH_L7200) || BLACKFIN || X86 || IA64 || M32R || MIPS || PARISC || PPC || (SUPERH64 && BLK_DEV_IDEPCI) || SPARC
+
 endif
 
 config BLK_DEV_HD_ONLY
diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c
index f7449d0..48db616 100644
--- a/drivers/ide/arm/bast-ide.c
+++ b/drivers/ide/arm/bast-ide.c
@@ -45,7 +45,7 @@
 	hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20);
 	hw.irq = irq;
 
-	ide_register_hw(&hw, 0, hwif);
+	ide_register_hw(&hw, NULL, 0, hwif);
 
 	return 0;
 }
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index e4875ce..410a0d1 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -316,27 +316,29 @@
 
 	drive->waiting_for_dma = 0;
 
-	disable_dma(hwif->hw.dma);
+	disable_dma(state->dev->dma);
 
 	/* Teardown mappings after DMA has completed. */
 	dma_unmap_sg(state->dev, hwif->sg_table, hwif->sg_nents,
 		     hwif->sg_dma_direction);
 
-	return get_dma_residue(hwif->hw.dma) != 0;
+	return get_dma_residue(state->dev->dma) != 0;
 }
 
 static void icside_dma_start(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
+	struct icside_state *state = hwif->hwif_data;
 
 	/* We can not enable DMA on both channels simultaneously. */
-	BUG_ON(dma_channel_active(hwif->hw.dma));
-	enable_dma(hwif->hw.dma);
+	BUG_ON(dma_channel_active(state->dev->dma));
+	enable_dma(state->dev->dma);
 }
 
 static int icside_dma_setup(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
+	struct icside_state *state = hwif->hwif_data;
 	struct request *rq = hwif->hwgroup->rq;
 	unsigned int dma_mode;
 
@@ -348,7 +350,7 @@
 	/*
 	 * We can not enable DMA on both channels.
 	 */
-	BUG_ON(dma_channel_active(hwif->hw.dma));
+	BUG_ON(dma_channel_active(state->dev->dma));
 
 	icside_build_sglist(drive, rq);
 
@@ -365,14 +367,14 @@
 	/*
 	 * Select the correct timing for this drive.
 	 */
-	set_dma_speed(hwif->hw.dma, drive->drive_data);
+	set_dma_speed(state->dev->dma, drive->drive_data);
 
 	/*
 	 * Tell the DMA engine about the SG table and
 	 * data direction.
 	 */
-	set_dma_sg(hwif->hw.dma, hwif->sg_table, hwif->sg_nents);
-	set_dma_mode(hwif->hw.dma, dma_mode);
+	set_dma_sg(state->dev->dma, hwif->sg_table, hwif->sg_nents);
+	set_dma_mode(state->dev->dma, dma_mode);
 
 	drive->waiting_for_dma = 1;
 
@@ -415,7 +417,6 @@
 
 static void icside_dma_init(ide_hwif_t *hwif)
 {
-	hwif->atapi_dma		= 1;
 	hwif->mwdma_mask	= 7; /* MW0..2 */
 	hwif->swdma_mask	= 7; /* SW0..2 */
 
@@ -439,40 +440,16 @@
 #define icside_dma_init(hwif)	(0)
 #endif
 
-static ide_hwif_t *icside_find_hwif(unsigned long dataport)
-{
-	ide_hwif_t *hwif;
-	int index;
-
-	for (index = 0; index < MAX_HWIFS; ++index) {
-		hwif = &ide_hwifs[index];
-		if (hwif->io_ports[IDE_DATA_OFFSET] == dataport)
-			goto found;
-	}
-
-	for (index = 0; index < MAX_HWIFS; ++index) {
-		hwif = &ide_hwifs[index];
-		if (!hwif->io_ports[IDE_DATA_OFFSET])
-			goto found;
-	}
-
-	hwif = NULL;
-found:
-	return hwif;
-}
-
 static ide_hwif_t *
 icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *ec)
 {
 	unsigned long port = (unsigned long)base + info->dataoffset;
 	ide_hwif_t *hwif;
 
-	hwif = icside_find_hwif(port);
+	hwif = ide_find_port(port);
 	if (hwif) {
 		int i;
 
-		memset(&hwif->hw, 0, sizeof(hw_regs_t));
-
 		/*
 		 * Ensure we're using MMIO
 		 */
@@ -480,13 +457,10 @@
 		hwif->mmio = 1;
 
 		for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-			hwif->hw.io_ports[i] = port;
 			hwif->io_ports[i] = port;
 			port += 1 << info->stepping;
 		}
-		hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset;
 		hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset;
-		hwif->hw.irq  = ec->irq;
 		hwif->irq     = ec->irq;
 		hwif->noprobe = 0;
 		hwif->chipset = ide_acorn;
@@ -501,6 +475,7 @@
 {
 	ide_hwif_t *hwif;
 	void __iomem *base;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 	base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
 	if (!base)
@@ -524,9 +499,9 @@
 
 	state->hwif[0] = hwif;
 
-	probe_hwif_init(hwif);
+	idx[0] = hwif->index;
 
-	ide_proc_register_port(hwif);
+	ide_device_add(idx);
 
 	return 0;
 }
@@ -538,6 +513,7 @@
 	void __iomem *ioc_base, *easi_base;
 	unsigned int sel = 0;
 	int ret;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 	ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
 	if (!ioc_base) {
@@ -593,7 +569,6 @@
 	hwif->serialized  = 1;
 	hwif->config_data = (unsigned long)ioc_base;
 	hwif->select_data = sel;
-	hwif->hw.dma      = ec->dma;
 
 	mate->maskproc    = icside_maskproc;
 	mate->channel     = 1;
@@ -602,18 +577,16 @@
 	mate->serialized  = 1;
 	mate->config_data = (unsigned long)ioc_base;
 	mate->select_data = sel | 1;
-	mate->hw.dma      = ec->dma;
 
 	if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) {
 		icside_dma_init(hwif);
 		icside_dma_init(mate);
 	}
 
-	probe_hwif_init(hwif);
-	probe_hwif_init(mate);
+	idx[0] = hwif->index;
+	idx[1] = mate->index;
 
-	ide_proc_register_port(hwif);
-	ide_proc_register_port(mate);
+	ide_device_add(idx);
 
 	return 0;
 
diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c
index bce2bec..8957cba 100644
--- a/drivers/ide/arm/ide_arm.c
+++ b/drivers/ide/arm/ide_arm.c
@@ -31,5 +31,5 @@
 	memset(&hw, 0, sizeof(hw));
 	ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206);
 	hw.irq = IDE_ARM_IRQ;
-	ide_register_hw(&hw, 1, NULL);
+	ide_register_hw(&hw, NULL, 1, NULL);
 }
diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c
index 83811af..0775a3a 100644
--- a/drivers/ide/arm/rapide.c
+++ b/drivers/ide/arm/rapide.c
@@ -13,42 +13,25 @@
 
 #include <asm/ecard.h>
 
-/*
- * Something like this really should be in generic code, but isn't.
- */
 static ide_hwif_t *
 rapide_locate_hwif(void __iomem *base, void __iomem *ctrl, unsigned int sz, int irq)
 {
 	unsigned long port = (unsigned long)base;
-	ide_hwif_t *hwif;
-	int index, i;
+	ide_hwif_t *hwif = ide_find_port(port);
+	int i;
 
-	for (index = 0; index < MAX_HWIFS; ++index) {
-		hwif = ide_hwifs + index;
-		if (hwif->io_ports[IDE_DATA_OFFSET] == port)
-			goto found;
-	}
+	if (hwif == NULL)
+		goto out;
 
-	for (index = 0; index < MAX_HWIFS; ++index) {
-		hwif = ide_hwifs + index;
-		if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
-			goto found;
-	}
-
-	return NULL;
-
- found:
 	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		hwif->hw.io_ports[i] = port;
 		hwif->io_ports[i] = port;
 		port += sz;
 	}
-	hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
 	hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
-	hwif->hw.irq = hwif->irq = irq;
+	hwif->irq = irq;
 	hwif->mmio = 1;
 	default_hwif_mmiops(hwif);
-
+out:
 	return hwif;
 }
 
@@ -58,6 +41,7 @@
 	ide_hwif_t *hwif;
 	void __iomem *base;
 	int ret;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 	ret = ecard_request_resources(ec);
 	if (ret)
@@ -74,8 +58,11 @@
 		hwif->hwif_data = base;
 		hwif->gendev.parent = &ec->dev;
 		hwif->noprobe = 0;
-		probe_hwif_init(hwif);
-		ide_proc_register_port(hwif);
+
+		idx[0] = hwif->index;
+
+		ide_device_add(idx);
+
 		ecard_set_drvdata(ec, hwif);
 		goto out;
 	}
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index 06c75f1..e196aef 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -782,7 +782,7 @@
 		                ide_offsets,
 		                0, 0, cris_ide_ack_intr,
 		                ide_default_irq(0));
-		ide_register_hw(&hw, 1, &hwif);
+		ide_register_hw(&hw, NULL, 1, &hwif);
 		hwif->mmio = 1;
 		hwif->chipset = ide_etrax100;
 		hwif->set_pio_mode = &cris_set_pio_mode;
@@ -805,6 +805,7 @@
 		hwif->dma_host_on = &cris_dma_on;
 		hwif->dma_off_quietly = &cris_dma_off;
 		hwif->cbl = ATA_CBL_PATA40;
+		hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
 		hwif->pio_mask = ATA_PIO4,
 		hwif->drives[0].autotune = 1;
 		hwif->drives[1].autotune = 1;
@@ -934,11 +935,11 @@
 		 * than two possibly non-adjacent physical 4kB pages.
 		 */
 		/* group sequential buffers into one large buffer */
-		addr = page_to_phys(sg->page) + sg->offset;
+		addr = sg_phys(sg);
 		size = sg_dma_len(sg);
 		while (--i) {
 			sg = sg_next(sg);
-			if ((addr + size) != page_to_phys(sg->page) + sg->offset)
+			if ((addr + size) != sg_phys(sg))
 				break;
 			size += sg_dma_len(sg);
 		}
diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c
index 6d26ad7..4a49b5c 100644
--- a/drivers/ide/h8300/ide-h8300.c
+++ b/drivers/ide/h8300/ide-h8300.c
@@ -68,7 +68,6 @@
 		hw->io_ports[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i;
 	hw->io_ports[IDE_CONTROL_OFFSET] = CONFIG_H8300_IDE_ALT;
 	hw->irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ;
-	hw->dma = NO_DMA;
 	hw->chipset = ide_generic;
 }
 
@@ -101,7 +100,7 @@
 	hw_setup(&hw);
 
 	/* register if */
-	idx = ide_register_hw(&hw, 1, &hwif);
+	idx = ide_register_hw(&hw, NULL, 1, &hwif);
 	if (idx == -1) {
 		printk(KERN_ERR "ide-h8300: IDE I/F register failed\n");
 		return;
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index 1d5f682..89df48f 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -350,7 +350,7 @@
 
 	memset(&args, 0, sizeof(ide_task_t));
 	args.command_type = IDE_DRIVE_TASK_NO_DATA;
-	args.data_phase   = TASKFILE_IN;
+	args.data_phase   = TASKFILE_NO_DATA;
 	args.handler      = &task_no_data_intr;
 
 	/* convert gtf to IDE Taskfile */
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index ca84352..57a5f63 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -120,7 +120,7 @@
  *                       Reformat to match kernel tabbing style.
  *                       Add CDROM_GET_UPC ioctl.
  * 3.10  Apr 10, 1996 -- Fix compilation error with STANDARD_ATAPI.
- * 3.11  Apr 29, 1996 -- Patch from Heiko Eissfeldt <heiko@colossus.escape.de>
+ * 3.11  Apr 29, 1996 -- Patch from Heiko Eißfeldt <heiko@colossus.escape.de>
  *                       to remove redundant verify_area calls.
  * 3.12  May  7, 1996 -- Rudimentary changer support.  Based on patches
  *                        from Gerhard Zuber <zuber@berlin.snafu.de>.
@@ -256,7 +256,7 @@
  *			- Minimize the TOC reading - only do it when we
  *			  know a media change has occurred.
  *			- Moved all the CDROMREADx ioctls to the Uniform layer.
- *			- Heiko Eissfeldt <heiko@colossus.escape.de> supplied
+ *			- Heiko Eißfeldt <heiko@colossus.escape.de> supplied
  *			  some fixes for CDI.
  *			- CD-ROM leaving door locked fix from Andries
  *			  Brouwer <Andries.Brouwer@cwi.nl>
@@ -2341,7 +2341,7 @@
 		   If we get an error for the regular case, we assume
 		   a CDI without additional audio tracks. In this case
 		   the readable TOC is empty (CDI tracks are not included)
-		   and only holds the Leadout entry. Heiko Eißfeldt */
+		   and only holds the Leadout entry. Heiko Eißfeldt */
 		ntracks = 0;
 		stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
 					   (char *)&toc->hdr,
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 92177ca..00123d99 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -169,7 +169,7 @@
 
 	nsectors.all		= (u16) rq->nr_sectors;
 
-	if (hwif->no_lba48_dma && lba48 && dma) {
+	if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) {
 		if (block + rq->nr_sectors > 1ULL << 28)
 			dma = 0;
 		else
@@ -593,28 +593,12 @@
 	return ide_raw_taskfile(drive, &args, NULL);
 }
 
-static int get_smart_values(ide_drive_t *drive, u8 *buf)
+static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
 {
 	ide_task_t args;
 
 	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_FEATURE_OFFSET]	= SMART_READ_VALUES;
-	args.tfRegister[IDE_NSECTOR_OFFSET]	= 0x01;
-	args.tfRegister[IDE_LCYL_OFFSET]	= SMART_LCYL_PASS;
-	args.tfRegister[IDE_HCYL_OFFSET]	= SMART_HCYL_PASS;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SMART;
-	args.command_type			= IDE_DRIVE_TASK_IN;
-	args.data_phase				= TASKFILE_IN;
-	args.handler				= &task_in_intr;
-	(void) smart_enable(drive);
-	return ide_raw_taskfile(drive, &args, buf);
-}
-
-static int get_smart_thresholds(ide_drive_t *drive, u8 *buf)
-{
-	ide_task_t args;
-	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_FEATURE_OFFSET]	= SMART_READ_THRESHOLDS;
+	args.tfRegister[IDE_FEATURE_OFFSET]	= sub_cmd;
 	args.tfRegister[IDE_NSECTOR_OFFSET]	= 0x01;
 	args.tfRegister[IDE_LCYL_OFFSET]	= SMART_LCYL_PASS;
 	args.tfRegister[IDE_HCYL_OFFSET]	= SMART_HCYL_PASS;
@@ -656,7 +640,7 @@
 	ide_drive_t	*drive = (ide_drive_t *)data;
 	int		len = 0, i = 0;
 
-	if (!get_smart_thresholds(drive, page)) {
+	if (get_smart_data(drive, page, SMART_READ_THRESHOLDS) == 0) {
 		unsigned short *val = (unsigned short *) page;
 		char *out = ((char *)val) + (SECTOR_WORDS * 4);
 		page = out;
@@ -675,7 +659,7 @@
 	ide_drive_t	*drive = (ide_drive_t *)data;
 	int		len = 0, i = 0;
 
-	if (!get_smart_values(drive, page)) {
+	if (get_smart_data(drive, page, SMART_READ_VALUES) == 0) {
 		unsigned short *val = (unsigned short *) page;
 		char *out = ((char *)val) + (SECTOR_WORDS * 4);
 		page = out;
@@ -856,7 +840,7 @@
 
 	drive->addressing =  0;
 
-	if (HWIF(drive)->no_lba48)
+	if (drive->hwif->host_flags & IDE_HFLAG_NO_LBA48)
 		return 0;
 
 	if (!idedisk_supports_lba48(drive->id))
@@ -889,6 +873,7 @@
 
 static void idedisk_setup (ide_drive_t *drive)
 {
+	ide_hwif_t *hwif = drive->hwif;
 	struct hd_driveid *id = drive->id;
 	unsigned long long capacity;
 
@@ -909,7 +894,6 @@
 	(void)set_lba_addressing(drive, 1);
 
 	if (drive->addressing == 1) {
-		ide_hwif_t *hwif = HWIF(drive);
 		int max_s = 2048;
 
 		if (max_s > hwif->rqsize)
@@ -932,7 +916,7 @@
 		drive->capacity64 = 1ULL << 28;
 	}
 
-	if (drive->hwif->no_lba48_dma && drive->addressing) {
+	if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && drive->addressing) {
 		if (drive->capacity64 > 1ULL << 28) {
 			printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode will"
 					 " be used for accessing sectors > %u\n",
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index bc57ce6..428f7a8 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -338,8 +338,10 @@
 	ide_hwif_t *hwif = drive->hwif;
 	struct hd_driveid *id = drive->id;
 
-	if (drive->media != ide_disk && hwif->atapi_dma == 0)
-		return 0;
+	if (drive->media != ide_disk) {
+		if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
+			return -1;
+	}
 
 	/*
 	 * Enable DMA on any drive that has
@@ -726,8 +728,10 @@
 	int x, i;
 	u8 mode = 0;
 
-	if (drive->media != ide_disk && hwif->atapi_dma == 0)
-		return 0;
+	if (drive->media != ide_disk) {
+		if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
+			return 0;
+	}
 
 	for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) {
 		if (req_mode < xfer_mode_bases[i])
@@ -897,10 +901,7 @@
 
 EXPORT_SYMBOL(ide_dma_timeout);
 
-/*
- * Needed for allowing full modular support of ide-driver
- */
-static int ide_release_dma_engine(ide_hwif_t *hwif)
+static void ide_release_dma_engine(ide_hwif_t *hwif)
 {
 	if (hwif->dmatable_cpu) {
 		pci_free_consistent(hwif->pci_dev,
@@ -909,7 +910,6 @@
 				    hwif->dmatable_dma);
 		hwif->dmatable_cpu = NULL;
 	}
-	return 1;
 }
 
 static int ide_release_iomio_dma(ide_hwif_t *hwif)
@@ -952,12 +952,6 @@
 {
 	printk(KERN_INFO "    %s: MMIO-DMA ", hwif->name);
 
- 	hwif->dma_base = base;
-
-	if(hwif->mate)
-		hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
-	else
-		hwif->dma_master = base;
 	return 0;
 }
 
@@ -971,8 +965,6 @@
 		return 1;
 	}
 
-	hwif->dma_base = base;
-
 	if (hwif->cds->extra) {
 		hwif->extra_base = base + (hwif->channel ? 8 : 16);
 
@@ -987,10 +979,6 @@
 		}
 	}
 
-	if(hwif->mate)
-		hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base:base;
-	else
-		hwif->dma_master = base;
 	return 0;
 }
 
@@ -1002,12 +990,9 @@
 	return ide_iomio_dma(hwif, base, ports);
 }
 
-/*
- * This can be called for a dynamically installed interface. Don't __init it
- */
-void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports)
+void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports)
 {
-	if (ide_dma_iobase(hwif, dma_base, num_ports))
+	if (ide_dma_iobase(hwif, base, num_ports))
 		return;
 
 	if (ide_allocate_dma_engine(hwif)) {
@@ -1015,6 +1000,13 @@
 		return;
 	}
 
+	hwif->dma_base = base;
+
+	if (hwif->mate)
+		hwif->dma_master = hwif->channel ? hwif->mate->dma_base : base;
+	else
+		hwif->dma_master = base;
+
 	if (!(hwif->dma_command))
 		hwif->dma_command	= hwif->dma_base;
 	if (!(hwif->dma_vendor1))
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index ec835e3..c89f0d3 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -47,15 +47,15 @@
 #include <linux/device.h>
 #include <linux/kmod.h>
 #include <linux/scatterlist.h>
+#include <linux/bitops.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
-#include <asm/bitops.h>
 
 static int __ide_end_request(ide_drive_t *drive, struct request *rq,
-			     int uptodate, unsigned int nr_bytes)
+			     int uptodate, unsigned int nr_bytes, int dequeue)
 {
 	int ret = 1;
 
@@ -80,9 +80,11 @@
 
 	if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
 		add_disk_randomness(rq->rq_disk);
-		if (!list_empty(&rq->queuelist))
-			blkdev_dequeue_request(rq);
-		HWGROUP(drive)->rq = NULL;
+		if (dequeue) {
+			if (!list_empty(&rq->queuelist))
+				blkdev_dequeue_request(rq);
+			HWGROUP(drive)->rq = NULL;
+		}
 		end_that_request_last(rq, uptodate);
 		ret = 0;
 	}
@@ -122,7 +124,7 @@
 			nr_bytes = rq->hard_cur_sectors << 9;
 	}
 
-	ret = __ide_end_request(drive, rq, uptodate, nr_bytes);
+	ret = __ide_end_request(drive, rq, uptodate, nr_bytes, 1);
 
 	spin_unlock_irqrestore(&ide_lock, flags);
 	return ret;
@@ -255,39 +257,13 @@
 			     int uptodate, int nr_sectors)
 {
 	unsigned long flags;
-	int ret = 1;
+	int ret;
 
 	spin_lock_irqsave(&ide_lock, flags);
-
 	BUG_ON(!blk_rq_started(rq));
-
-	/*
-	 * if failfast is set on a request, override number of sectors and
-	 * complete the whole request right now
-	 */
-	if (blk_noretry_request(rq) && end_io_error(uptodate))
-		nr_sectors = rq->hard_nr_sectors;
-
-	if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors)
-		rq->errors = -EIO;
-
-	/*
-	 * decide whether to reenable DMA -- 3 is a random magic for now,
-	 * if we DMA timeout more than 3 times, just stay in PIO
-	 */
-	if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
-		drive->state = 0;
-		HWGROUP(drive)->hwif->ide_dma_on(drive);
-	}
-
-	if (!end_that_request_first(rq, uptodate, nr_sectors)) {
-		add_disk_randomness(rq->rq_disk);
-		if (blk_rq_tagged(rq))
-			blk_queue_end_tag(drive->queue, rq);
-		end_that_request_last(rq, uptodate);
-		ret = 0;
-	}
+	ret = __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0);
 	spin_unlock_irqrestore(&ide_lock, flags);
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(ide_end_dequeued_request);
@@ -484,7 +460,8 @@
 		}
 	}
 
-	if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0)
+	if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ &&
+	    (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0)
 		try_to_flush_leftover_data(drive);
 
 	if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
@@ -799,7 +776,20 @@
 		s->b.set_tune = 0;
 
 		if (set_pio_mode_abuse(drive->hwif, req_pio)) {
-			if (hwif->set_pio_mode)
+
+			if (hwif->set_pio_mode == NULL)
+				return ide_stopped;
+
+			/*
+			 * take ide_lock for drive->[no_]unmask/[no_]io_32bit
+			 */
+			if (req_pio == 8 || req_pio == 9) {
+				unsigned long flags;
+
+				spin_lock_irqsave(&ide_lock, flags);
+				hwif->set_pio_mode(drive, req_pio);
+				spin_unlock_irqrestore(&ide_lock, flags);
+			} else
 				hwif->set_pio_mode(drive, req_pio);
 		} else {
 			int keep_dma = drive->using_dma;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index d4d790f..9516883 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -693,35 +693,16 @@
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
-/*
- * Update the 
- */
-int ide_driveid_update (ide_drive_t *drive)
+int ide_driveid_update(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
+	ide_hwif_t *hwif = drive->hwif;
 	struct hd_driveid *id;
-#if 0
-	id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
-	if (!id)
-		return 0;
+	unsigned long timeout, flags;
 
-	taskfile_lib_get_identify(drive, (char *)&id);
-
-	ide_fix_driveid(id);
-	if (id) {
-		drive->id->dma_ultra = id->dma_ultra;
-		drive->id->dma_mword = id->dma_mword;
-		drive->id->dma_1word = id->dma_1word;
-		/* anything more ? */
-		kfree(id);
-	}
-	return 1;
-#else
 	/*
 	 * Re-read drive->id for possible DMA mode
 	 * change (copied from ide-probe.c)
 	 */
-	unsigned long timeout, flags;
 
 	SELECT_MASK(drive, 1);
 	if (IDE_CONTROL_REG)
@@ -763,7 +744,6 @@
 	}
 
 	return 1;
-#endif
 }
 
 int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
index 2b8009c..e245521 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -40,9 +40,8 @@
 	ide_std_init_ports(&hw, pnp_port_start(dev, 0),
 				pnp_port_start(dev, 1));
 	hw.irq = pnp_irq(dev, 0);
-	hw.dma = NO_DMA;
 
-	index = ide_register_hw(&hw, 1, &hwif);
+	index = ide_register_hw(&hw, NULL, 1, &hwif);
 
 	if (index != -1) {
 	    	printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 3c945d6..6a6f2e0 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -47,6 +47,7 @@
 #include <linux/spinlock.h>
 #include <linux/kmod.h>
 #include <linux/pci.h>
+#include <linux/scatterlist.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -717,7 +718,7 @@
  * This routine only knows how to look for drive units 0 and 1
  * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
  */
-static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
+static void probe_hwif(ide_hwif_t *hwif)
 {
 	unsigned long flags;
 	unsigned int irqd;
@@ -819,8 +820,8 @@
 		return;
 	}
 
-	if (fixup)
-		fixup(hwif);
+	if (hwif->fixup)
+		hwif->fixup(hwif);
 
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		ide_drive_t *drive = &hwif->drives[unit];
@@ -859,10 +860,11 @@
 }
 
 static int hwif_init(ide_hwif_t *hwif);
+static void hwif_register_devices(ide_hwif_t *hwif);
 
-int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
+static int probe_hwif_init(ide_hwif_t *hwif)
 {
-	probe_hwif(hwif, fixup);
+	probe_hwif(hwif);
 
 	if (!hwif_init(hwif)) {
 		printk(KERN_INFO "%s: failed to initialize IDE interface\n",
@@ -870,34 +872,12 @@
 		return -1;
 	}
 
-	if (hwif->present) {
-		u16 unit = 0;
-		int ret;
+	if (hwif->present)
+		hwif_register_devices(hwif);
 
-		for (unit = 0; unit < MAX_DRIVES; ++unit) {
-			ide_drive_t *drive = &hwif->drives[unit];
-			/* For now don't attach absent drives, we may
-			   want them on default or a new "empty" class
-			   for hotplug reprobing ? */
-			if (drive->present) {
-				ret = device_register(&drive->gendev);
-				if (ret < 0)
-					printk(KERN_WARNING "IDE: %s: "
-						"device_register error: %d\n",
-						__FUNCTION__, ret);
-			}
-		}
-	}
 	return 0;
 }
 
-int probe_hwif_init(ide_hwif_t *hwif)
-{
-	return probe_hwif_init_with_fixup(hwif, NULL);
-}
-
-EXPORT_SYMBOL(probe_hwif_init);
-
 #if MAX_HWIFS > 1
 /*
  * save_match() is used to simplify logic in init_irq() below.
@@ -951,7 +931,8 @@
 	blk_queue_segment_boundary(q, 0xffff);
 
 	if (!hwif->rqsize) {
-		if (hwif->no_lba48 || hwif->no_lba48_dma)
+		if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
+		    (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
 			hwif->rqsize = 256;
 		else
 			hwif->rqsize = 65536;
@@ -1337,12 +1318,14 @@
 	if (!hwif->sg_max_nents)
 		hwif->sg_max_nents = PRD_ENTRIES;
 
-	hwif->sg_table = kzalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+	hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
 				 GFP_KERNEL);
 	if (!hwif->sg_table) {
 		printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
 		goto out;
 	}
+
+	sg_init_table(hwif->sg_table, hwif->sg_max_nents);
 	
 	if (init_irq(hwif) == 0)
 		goto done;
@@ -1378,6 +1361,24 @@
 	return 0;
 }
 
+static void hwif_register_devices(ide_hwif_t *hwif)
+{
+	unsigned int i;
+
+	for (i = 0; i < MAX_DRIVES; i++) {
+		ide_drive_t *drive = &hwif->drives[i];
+
+		if (drive->present) {
+			int ret = device_register(&drive->gendev);
+
+			if (ret < 0)
+				printk(KERN_WARNING "IDE: %s: "
+					"device_register error: %d\n",
+					__FUNCTION__, ret);
+		}
+	}
+}
+
 int ideprobe_init (void)
 {
 	unsigned int index;
@@ -1389,27 +1390,18 @@
 
 	for (index = 0; index < MAX_HWIFS; ++index)
 		if (probe[index])
-			probe_hwif(&ide_hwifs[index], NULL);
+			probe_hwif(&ide_hwifs[index]);
 	for (index = 0; index < MAX_HWIFS; ++index)
 		if (probe[index])
 			hwif_init(&ide_hwifs[index]);
 	for (index = 0; index < MAX_HWIFS; ++index) {
 		if (probe[index]) {
 			ide_hwif_t *hwif = &ide_hwifs[index];
-			int unit;
 			if (!hwif->present)
 				continue;
 			if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced)
 				hwif->chipset = ide_generic;
-			for (unit = 0; unit < MAX_DRIVES; ++unit)
-				if (hwif->drives[unit].present) {
-					int ret = device_register(
-						&hwif->drives[unit].gendev);
-					if (ret < 0)
-						printk(KERN_WARNING "IDE: %s: "
-							"device_register error: %d\n",
-							__FUNCTION__, ret);
-				}
+			hwif_register_devices(hwif);
 		}
 	}
 	for (index = 0; index < MAX_HWIFS; ++index)
@@ -1419,3 +1411,22 @@
 }
 
 EXPORT_SYMBOL_GPL(ideprobe_init);
+
+int ide_device_add(u8 idx[4])
+{
+	int i, rc = 0;
+
+	for (i = 0; i < 4; i++) {
+		if (idx[i] != 0xff)
+			rc |= probe_hwif_init(&ide_hwifs[idx[i]]);
+	}
+
+	for (i = 0; i < 4; i++) {
+		if (idx[i] != 0xff)
+			ide_proc_register_port(&ide_hwifs[idx[i]]);
+	}
+
+	return rc;
+}
+
+EXPORT_SYMBOL_GPL(ide_device_add);
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index fc1d8ae..a4007d3 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -804,8 +804,6 @@
 	create_proc_ide_drives(hwif);
 }
 
-EXPORT_SYMBOL_GPL(ide_proc_register_port);
-
 #ifdef CONFIG_BLK_DEV_IDEPCI
 void ide_pci_create_host_proc(const char *name, get_info_t *get_info)
 {
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 1fa5794..7b9181b 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -565,7 +565,7 @@
  *	The following parameter is used to select the point in the internal
  *	tape fifo in which we will start to refill the buffer. Decreasing
  *	the following parameter will improve the system's latency and
- *	interactive response, while using a high value might improve sytem
+ *	interactive response, while using a high value might improve system
  *	throughput.
  */
 #define IDETAPE_FIFO_THRESHOLD 		2
@@ -621,7 +621,6 @@
  */
 #define USE_IOTRACE	0
 #if USE_IOTRACE
-#include <linux/io_trace.h>
 #define IO_IDETAPE_FIFO	500
 #endif
 
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 2a3c8d4..d066546 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -8,23 +8,6 @@
  *  Copyright (C) 2003-2004	Bartlomiej Zolnierkiewicz
  *
  *  The big the bad and the ugly.
- *
- *  Problems to be fixed because of BH interface or the lack therefore.
- *
- *  Fill me in stupid !!!
- *
- *  HOST:
- *	General refers to the Controller and Driver "pair".
- *  DATA HANDLER:
- *	Under the context of Linux it generally refers to an interrupt handler.
- *	However, it correctly describes the 'HOST'
- *  DATA BLOCK:
- *	The amount of data needed to be transfered as predefined in the
- *	setup of the device.
- *  STORAGE ATOMIC:
- *	The 'DATA BLOCK' associated to the 'DATA HANDLER', and can be as
- *	small as a single sector or as large as the entire command block
- *	request.
  */
 
 #include <linux/module.h>
@@ -278,7 +261,7 @@
 		hwif->cursg = sg;
 	}
 
-	page = cursg->page;
+	page = sg_page(cursg);
 	offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
 
 	/* get the current page and offset */
@@ -695,9 +678,6 @@
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
 
-/*
- * FIXME : this needs to map into at taskfile. <andre@linux-ide.org>
- */
 int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 {
 	int err = 0;
@@ -761,9 +741,6 @@
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
 
-/*
- * FIXME : this needs to map into at taskfile. <andre@linux-ide.org>
- */
 int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 {
 	void __user *p = (void __user *)arg;
@@ -860,9 +837,14 @@
 		case TASKFILE_OUT_DMA:
 		case TASKFILE_IN_DMAQ:
 		case TASKFILE_IN_DMA:
-			hwif->dma_setup(drive);
-			hwif->dma_exec_cmd(drive, taskfile->command);
-			hwif->dma_start(drive);
+			if (!drive->using_dma)
+				break;
+
+			if (!hwif->dma_setup(drive)) {
+				hwif->dma_exec_cmd(drive, taskfile->command);
+				hwif->dma_start(drive);
+				return ide_started;
+			}
 			break;
 
 	        default:
@@ -876,7 +858,8 @@
 				return task->prehandler(drive, task->rq);
 			}
 			ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL);
+			return ide_started;
 	}
 
-	return ide_started;
+	return ide_stopped;
 }
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 5b09066..674a65c 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -134,8 +134,6 @@
 
 	hwif->bus_state	= BUSSTATE_ON;
 
-	hwif->atapi_dma = 0;		/* disable all atapi dma */ 
-
 	init_completion(&hwif->gendev_rel_comp);
 
 	default_hwif_iops(hwif);
@@ -170,7 +168,6 @@
 
 	ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq);
 
-	memcpy(&hwif->hw, &hw, sizeof(hw));
 	memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));
 
 	hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
@@ -216,7 +213,7 @@
 		init_hwif_data(hwif, index);
 		init_hwif_default(hwif, index);
 #if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI)
-		hwif->irq = hwif->hw.irq =
+		hwif->irq =
 			ide_init_default_irq(hwif->io_ports[IDE_DATA_OFFSET]);
 #endif
 	}
@@ -267,6 +264,30 @@
 	return system_bus_speed;
 }
 
+ide_hwif_t * ide_find_port(unsigned long base)
+{
+	ide_hwif_t *hwif;
+	int i;
+
+	for (i = 0; i < MAX_HWIFS; i++) {
+		hwif = &ide_hwifs[i];
+		if (hwif->io_ports[IDE_DATA_OFFSET] == base)
+			goto found;
+	}
+
+	for (i = 0; i < MAX_HWIFS; i++) {
+		hwif = &ide_hwifs[i];
+		if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
+			goto found;
+	}
+
+	hwif = NULL;
+found:
+	return hwif;
+}
+
+EXPORT_SYMBOL_GPL(ide_find_port);
+
 static struct resource* hwif_request_region(ide_hwif_t *hwif,
 					    unsigned long addr, int num)
 {
@@ -379,7 +400,6 @@
 
 	hwif->pio_mask			= tmp_hwif->pio_mask;
 
-	hwif->atapi_dma			= tmp_hwif->atapi_dma;
 	hwif->ultra_mask		= tmp_hwif->ultra_mask;
 	hwif->mwdma_mask		= tmp_hwif->mwdma_mask;
 	hwif->swdma_mask		= tmp_hwif->swdma_mask;
@@ -394,6 +414,8 @@
 	hwif->cds			= tmp_hwif->cds;
 #endif
 
+	hwif->fixup			= tmp_hwif->fixup;
+
 	hwif->set_pio_mode		= tmp_hwif->set_pio_mode;
 	hwif->set_dma_mode		= tmp_hwif->set_dma_mode;
 	hwif->mdma_filter		= tmp_hwif->mdma_filter;
@@ -440,7 +462,6 @@
 
 	hwif->mmio			= tmp_hwif->mmio;
 	hwif->rqsize			= tmp_hwif->rqsize;
-	hwif->no_lba48			= tmp_hwif->no_lba48;
 
 #ifndef CONFIG_BLK_DEV_IDECS
 	hwif->irq			= tmp_hwif->irq;
@@ -656,7 +677,6 @@
 		}
 	}
 	hw->irq = irq;
-	hw->dma = NO_DMA;
 	hw->ack_intr = ack_intr;
 /*
  *	hw->iops = iops;
@@ -664,11 +684,11 @@
 }
 
 /**
- *	ide_register_hw_with_fixup	-	register IDE interface
+ *	ide_register_hw		-	register IDE interface
  *	@hw: hardware registers
+ *	@fixup: fixup function
  *	@initializing: set while initializing built-in drivers
  *	@hwifp: pointer to returned hwif
- *	@fixup: fixup function
  *
  *	Register an IDE interface, specifying exactly the registers etc.
  *	Set init=1 iff calling before probes have taken place.
@@ -676,9 +696,8 @@
  *	Returns -1 on error.
  */
 
-int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing,
-			       ide_hwif_t **hwifp,
-			       void(*fixup)(ide_hwif_t *hwif))
+int ide_register_hw(hw_regs_t *hw, void (*fixup)(ide_hwif_t *),
+		    int initializing, ide_hwif_t **hwifp)
 {
 	int index, retry = 1;
 	ide_hwif_t *hwif;
@@ -686,7 +705,7 @@
 	do {
 		for (index = 0; index < MAX_HWIFS; ++index) {
 			hwif = &ide_hwifs[index];
-			if (hwif->hw.io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET])
+			if (hwif->io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET])
 				goto found;
 		}
 		for (index = 0; index < MAX_HWIFS; ++index) {
@@ -694,7 +713,7 @@
 			if (hwif->hold)
 				continue;
 			if ((!hwif->present && !hwif->mate && !initializing) ||
-			    (!hwif->hw.io_ports[IDE_DATA_OFFSET] && initializing))
+			    (!hwif->io_ports[IDE_DATA_OFFSET] && initializing))
 				goto found;
 		}
 		for (index = 0; index < MAX_HWIFS; index++)
@@ -710,16 +729,18 @@
 	}
 	if (hwif->present)
 		return -1;
-	memcpy(&hwif->hw, hw, sizeof(*hw));
-	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
+	memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
 	hwif->irq = hw->irq;
 	hwif->noprobe = 0;
+	hwif->fixup = fixup;
 	hwif->chipset = hw->chipset;
 	hwif->gendev.parent = hw->dev;
+	hwif->ack_intr = hw->ack_intr;
 
-	if (!initializing) {
-		probe_hwif_init_with_fixup(hwif, fixup);
-		ide_proc_register_port(hwif);
+	if (initializing == 0) {
+		u8 idx[4] = { index, 0xff, 0xff, 0xff };
+
+		ide_device_add(idx);
 	}
 
 	if (hwifp)
@@ -728,13 +749,6 @@
 	return (initializing || hwif->present) ? index : -1;
 }
 
-EXPORT_SYMBOL(ide_register_hw_with_fixup);
-
-int ide_register_hw(hw_regs_t *hw, int initializing, ide_hwif_t **hwifp)
-{
-	return ide_register_hw_with_fixup(hw, initializing, hwifp, NULL);
-}
-
 EXPORT_SYMBOL(ide_register_hw);
 
 /*
@@ -1050,7 +1064,7 @@
 			ide_init_hwif_ports(&hw, (unsigned long) args[0],
 					    (unsigned long) args[1], NULL);
 			hw.irq = args[2];
-			if (ide_register_hw(&hw, 0, NULL) == -1)
+			if (ide_register_hw(&hw, NULL, 0, NULL) == -1)
 				return -EIO;
 			return 0;
 		}
@@ -1401,6 +1415,9 @@
 			"reset", "minus6", "ata66", "minus8", "minus9",
 			"minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb",
 			"dtc2278", "umc8672", "ali14xx", NULL };
+
+		hw_regs_t hwregs;
+
 		hw = s[3] - '0';
 		hwif = &ide_hwifs[hw];
 		i = match_parm(&s[4], ide_words, vals, 3);
@@ -1510,9 +1527,9 @@
 			case 2: /* base,ctl */
 				vals[2] = 0;	/* default irq = probe for it */
 			case 3: /* base,ctl,irq */
-				hwif->hw.irq = vals[2];
-				ide_init_hwif_ports(&hwif->hw, (unsigned long) vals[0], (unsigned long) vals[1], &hwif->irq);
-				memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+				memset(&hwregs, 0, sizeof(hwregs));
+				ide_init_hwif_ports(&hwregs, vals[0], vals[1], &hwif->irq);
+				memcpy(hwif->io_ports, hwregs.io_ports, sizeof(hwif->io_ports));
 				hwif->irq      = vals[2];
 				hwif->noprobe  = 0;
 				hwif->chipset  = ide_forced;
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c
index 2f0ef9b..10311ec 100644
--- a/drivers/ide/legacy/ali14xx.c
+++ b/drivers/ide/legacy/ali14xx.c
@@ -102,6 +102,8 @@
 	outb_p(data, dataPort);
 }
 
+static DEFINE_SPINLOCK(ali14xx_lock);
+
 /*
  * Set PIO mode for the specified drive.
  * This function computes timing parameters
@@ -129,14 +131,14 @@
 
 	/* stuff timing parameters into controller registers */
 	driveNum = (HWIF(drive)->index << 1) + drive->select.b.unit;
-	spin_lock_irqsave(&ide_lock, flags);
+	spin_lock_irqsave(&ali14xx_lock, flags);
 	outb_p(regOn, basePort);
 	outReg(param1, regTab[driveNum].reg1);
 	outReg(param2, regTab[driveNum].reg2);
 	outReg(param3, regTab[driveNum].reg3);
 	outReg(param4, regTab[driveNum].reg4);
 	outb_p(regOff, basePort);
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irqrestore(&ali14xx_lock, flags);
 }
 
 /*
@@ -193,6 +195,7 @@
 static int __init ali14xx_probe(void)
 {
 	ide_hwif_t *hwif, *mate;
+	static u8 idx[4] = { 0, 1, 0xff, 0xff };
 
 	printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n",
 			  basePort, regOn);
@@ -217,11 +220,7 @@
 	mate->mate = hwif;
 	mate->channel = 1;
 
-	probe_hwif_init(hwif);
-	probe_hwif_init(mate);
-
-	ide_proc_register_port(hwif);
-	ide_proc_register_port(mate);
+	ide_device_add(idx);
 
 	return 0;
 }
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c
index 101aee1..4a0be25 100644
--- a/drivers/ide/legacy/buddha.c
+++ b/drivers/ide/legacy/buddha.c
@@ -212,8 +212,8 @@
 //						xsurf_iops,
 						IRQ_AMIGA_PORTS);
 			}	
-			
-			index = ide_register_hw(&hw, 1, &hwif);
+
+			index = ide_register_hw(&hw, NULL, 1, &hwif);
 			if (index != -1) {
 				hwif->mmio = 1;
 				printk("ide%d: ", index);
diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c
index f165212..24a845d 100644
--- a/drivers/ide/legacy/dtc2278.c
+++ b/drivers/ide/legacy/dtc2278.c
@@ -67,20 +67,24 @@
 	}
 }
 
+static DEFINE_SPINLOCK(dtc2278_lock);
+
 static void dtc2278_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
 	unsigned long flags;
 
 	if (pio >= 3) {
-		spin_lock_irqsave(&ide_lock, flags);
+		spin_lock_irqsave(&dtc2278_lock, flags);
 		/*
 		 * This enables PIO mode4 (3?) on the first interface
 		 */
 		sub22(1,0xc3);
 		sub22(0,0xa0);
-		spin_unlock_irqrestore(&ide_lock, flags);
+		spin_unlock_irqrestore(&dtc2278_lock, flags);
 	} else {
 		/* we don't know how to set it back again.. */
+		/* Actually we do - there is a data sheet available for the
+		   Winbond but does anyone actually care */
 	}
 
 	/*
@@ -94,6 +98,7 @@
 {
 	unsigned long flags;
 	ide_hwif_t *hwif, *mate;
+	static u8 idx[4] = { 0, 1, 0xff, 0xff };
 
 	hwif = &ide_hwifs[0];
 	mate = &ide_hwifs[1];
@@ -129,16 +134,13 @@
 
 	mate->serialized = 1;
 	mate->chipset = ide_dtc2278;
+	mate->pio_mask = ATA_PIO4;
 	mate->drives[0].no_unmask = 1;
 	mate->drives[1].no_unmask = 1;
 	mate->mate = hwif;
 	mate->channel = 1;
 
-	probe_hwif_init(hwif);
-	probe_hwif_init(mate);
-
-	ide_proc_register_port(hwif);
-	ide_proc_register_port(mate);
+	ide_device_add(idx);
 
 	return 0;
 }
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c
index f0829b8..7d7936f 100644
--- a/drivers/ide/legacy/falconide.c
+++ b/drivers/ide/legacy/falconide.c
@@ -72,7 +72,7 @@
 			0, 0, NULL,
 //			falconide_iops,
 			IRQ_MFP_IDE);
-	index = ide_register_hw(&hw, 1, NULL);
+	index = ide_register_hw(&hw, NULL, 1, NULL);
 
 	if (index != -1)
 	    printk("ide%d: Falcon IDE interface\n", index);
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
index 0830a02..53331ee 100644
--- a/drivers/ide/legacy/gayle.c
+++ b/drivers/ide/legacy/gayle.c
@@ -165,7 +165,7 @@
 //			&gayle_iops,
 			IRQ_AMIGA_PORTS);
 
-	index = ide_register_hw(&hw, 1, &hwif);
+	index = ide_register_hw(&hw, NULL, 1, &hwif);
 	if (index != -1) {
 	    hwif->mmio = 1;
 	    switch (i) {
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
index 2e5a9cc..a4245d1 100644
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -247,6 +247,8 @@
 	}
 }
 
+static DEFINE_SPINLOCK(ht6560b_lock);
+
 /*
  *  Enable/Disable so called prefetch mode
  */
@@ -254,9 +256,9 @@
 {
 	unsigned long flags;
 	int t = HT_PREFETCH_MODE << 8;
-	
-	spin_lock_irqsave(&ide_lock, flags);
-	
+
+	spin_lock_irqsave(&ht6560b_lock, flags);
+
 	/*
 	 *  Prefetch mode and unmask irq seems to conflict
 	 */
@@ -268,9 +270,9 @@
 		drive->drive_data &= ~t;  /* disable prefetch mode */
 		drive->no_unmask = 0;
 	}
-	
-	spin_unlock_irqrestore(&ide_lock, flags);
-	
+
+	spin_unlock_irqrestore(&ht6560b_lock, flags);
+
 #ifdef DEBUG
 	printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis"));
 #endif
@@ -287,16 +289,14 @@
 		ht_set_prefetch(drive, pio & 1);
 		return;
 	}
-	
+
 	timing = ht_pio2timings(drive, pio);
-	
-	spin_lock_irqsave(&ide_lock, flags);
-	
+
+	spin_lock_irqsave(&ht6560b_lock, flags);
 	drive->drive_data &= 0xff00;
 	drive->drive_data |= timing;
-	
-	spin_unlock_irqrestore(&ide_lock, flags);
-	
+	spin_unlock_irqrestore(&ht6560b_lock, flags);
+
 #ifdef DEBUG
 	printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing);
 #endif
@@ -311,6 +311,7 @@
 int __init ht6560b_init(void)
 {
 	ide_hwif_t *hwif, *mate;
+	static u8 idx[4] = { 0, 1, 0xff, 0xff };
 	int t;
 
 	if (probe_ht6560b == 0)
@@ -359,11 +360,7 @@
 	mate->drives[0].drive_data = t;
 	mate->drives[1].drive_data = t;
 
-	probe_hwif_init(hwif);
-	probe_hwif_init(mate);
-
-	ide_proc_register_port(hwif);
-	ide_proc_register_port(mate);
+	ide_device_add(idx);
 
 	return 0;
 
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index e8e360c..03715c0 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -153,7 +153,7 @@
     hw.irq = irq;
     hw.chipset = ide_pci;
     hw.dev = &handle->dev;
-    return ide_register_hw_with_fixup(&hw, 0, NULL, ide_undecoded_slave);
+    return ide_register_hw(&hw, &ide_undecoded_slave, 0, NULL);
 }
 
 /*======================================================================
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c
index b992b2b..7bb79f5 100644
--- a/drivers/ide/legacy/ide_platform.c
+++ b/drivers/ide/legacy/ide_platform.c
@@ -33,39 +33,24 @@
 	    int mmio)
 {
 	unsigned long port = (unsigned long)base;
-	ide_hwif_t *hwif;
-	int index, i;
+	ide_hwif_t *hwif = ide_find_port(port);
+	int i;
 
-	for (index = 0; index < MAX_HWIFS; ++index) {
-		hwif = ide_hwifs + index;
-		if (hwif->io_ports[IDE_DATA_OFFSET] == port)
-			goto found;
-	}
+	if (hwif == NULL)
+		goto out;
 
-	for (index = 0; index < MAX_HWIFS; ++index) {
-		hwif = ide_hwifs + index;
-		if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
-			goto found;
-	}
-
-	return NULL;
-
-found:
-
-	hwif->hw.io_ports[IDE_DATA_OFFSET] = port;
+	hwif->io_ports[IDE_DATA_OFFSET] = port;
 
 	port += (1 << pdata->ioport_shift);
 	for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET;
 	     i++, port += (1 << pdata->ioport_shift))
-		hwif->hw.io_ports[i] = port;
+		hwif->io_ports[i] = port;
 
-	hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
+	hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
 
-	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
-	hwif->hw.irq = hwif->irq = irq;
+	hwif->irq = irq;
 
-	hwif->hw.dma = NO_DMA;
-	hwif->chipset = hwif->hw.chipset = ide_generic;
+	hwif->chipset = ide_generic;
 
 	if (mmio) {
 		hwif->mmio = 1;
@@ -73,8 +58,8 @@
 	}
 
 	hwif_prop.hwif = hwif;
-	hwif_prop.index = index;
-
+	hwif_prop.index = hwif->index;
+out:
 	return hwif;
 }
 
@@ -83,6 +68,7 @@
 	struct resource *res_base, *res_alt, *res_irq;
 	ide_hwif_t *hwif;
 	struct pata_platform_info *pdata;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	int ret = 0;
 	int mmio = 0;
 
@@ -130,10 +116,11 @@
 	hwif->gendev.parent = &pdev->dev;
 	hwif->noprobe = 0;
 
-	probe_hwif_init(hwif);
+	idx[0] = hwif->index;
+
+	ide_device_add(idx);
 
 	platform_set_drvdata(pdev, hwif);
-	ide_proc_register_port(hwif);
 
 	return 0;
 
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index b557c45..e87cd2f 100644
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -93,21 +93,21 @@
 				0, 0, macide_ack_intr,
 //				quadra_ide_iops,
 				IRQ_NUBUS_F);
-		index = ide_register_hw(&hw, 1, &hwif);
+		index = ide_register_hw(&hw, NULL, 1, &hwif);
 		break;
 	case MAC_IDE_PB:
 		ide_setup_ports(&hw, IDE_BASE, macide_offsets,
 				0, 0, macide_ack_intr,
 //				macide_pb_iops,
 				IRQ_NUBUS_C);
-		index = ide_register_hw(&hw, 1, &hwif);
+		index = ide_register_hw(&hw, NULL, 1, &hwif);
 		break;
 	case MAC_IDE_BABOON:
 		ide_setup_ports(&hw, BABOON_BASE, macide_offsets,
 				0, 0, NULL,
 //				macide_baboon_iops,
 				IRQ_BABOON_1);
-		index = ide_register_hw(&hw, 1, &hwif);
+		index = ide_register_hw(&hw, NULL, 1, &hwif);
 		if (index == -1) break;
 		if (macintosh_config->ident == MAC_MODEL_PB190) {
 
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
index e628a98..a73db1b 100644
--- a/drivers/ide/legacy/q40ide.c
+++ b/drivers/ide/legacy/q40ide.c
@@ -89,9 +89,8 @@
 		else
 			hw->io_ports[i] = Q40_ISA_IO_B(base + offsets[i]);
 	}
-	
+
 	hw->irq = irq;
-	hw->dma = NO_DMA;
 	hw->ack_intr = ack_intr;
 /*
  *	hw->iops = iops;
@@ -102,7 +101,7 @@
 
 /* 
  * the static array is needed to have the name reported in /proc/ioports,
- * hwif->name unfortunately isn´t available yet
+ * hwif->name unfortunately isn't available yet
  */
 static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={
 	"ide0", "ide1"
@@ -142,7 +141,7 @@
 			0, NULL,
 //			m68kide_iops,
 			q40ide_default_irq(pcide_bases[i]));
-	index = ide_register_hw(&hw, 1, &hwif);
+	index = ide_register_hw(&hw, NULL, 1, &hwif);
 	// **FIXME**
 	if (index != -1)
 		hwif->mmio = 1;
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c
index 0c81d2d..912e738 100644
--- a/drivers/ide/legacy/qd65xx.c
+++ b/drivers/ide/legacy/qd65xx.c
@@ -89,26 +89,6 @@
 
 static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
 
-static void qd_write_reg (u8 content, unsigned long reg)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&ide_lock, flags);
-	outb(content,reg);
-	spin_unlock_irqrestore(&ide_lock, flags);
-}
-
-static u8 __init qd_read_reg (unsigned long reg)
-{
-	unsigned long flags;
-	u8 read;
-
-	spin_lock_irqsave(&ide_lock, flags);
-	read = inb(reg);
-	spin_unlock_irqrestore(&ide_lock, flags);
-	return read;
-}
-
 /*
  * qd_select:
  *
@@ -121,7 +101,7 @@
 			(QD_TIMREG(drive) & 0x02);
 
 	if (timings[index] != QD_TIMING(drive))
-		qd_write_reg(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
+		outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
 }
 
 /*
@@ -284,7 +264,7 @@
 	}
 
 	if (!HWIF(drive)->channel && drive->media != ide_disk) {
-		qd_write_reg(0x5f, QD_CONTROL_PORT);
+		outb(0x5f, QD_CONTROL_PORT);
 		printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO "
 			"and post-write buffer on %s.\n",
 			drive->name, HWIF(drive)->name);
@@ -301,16 +281,15 @@
 
 static int __init qd_testreg(int port)
 {
-	u8 savereg;
-	u8 readreg;
 	unsigned long flags;
+	u8 savereg, readreg;
 
-	spin_lock_irqsave(&ide_lock, flags);
+	local_irq_save(flags);
 	savereg = inb_p(port);
 	outb_p(QD_TESTVAL, port);	/* safe value */
 	readreg = inb_p(port);
 	outb(savereg, port);
-	spin_unlock_irqrestore(&ide_lock, flags);
+	local_irq_restore(flags);
 
 	if (savereg == QD_TESTVAL) {
 		printk(KERN_ERR "Outch ! the probe for qd65xx isn't reliable !\n");
@@ -364,13 +343,13 @@
 
 	if (set_pio_mode == (void *)qd6500_set_pio_mode) {
 		// will do it for both
-		qd_write_reg(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+		outb(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
 	} else if (set_pio_mode == (void *)qd6580_set_pio_mode) {
 		if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) {
-			qd_write_reg(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
-			qd_write_reg(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
+			outb(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+			outb(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
 		} else {
-			qd_write_reg(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+			outb(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
 		}
 	} else {
 		printk(KERN_WARNING "Unknown qd65xx tuning fonction !\n");
@@ -389,10 +368,11 @@
 static int __init qd_probe(int base)
 {
 	ide_hwif_t *hwif;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	u8 config;
 	u8 unit;
 
-	config = qd_read_reg(QD_CONFIG_PORT);
+	config = inb(QD_CONFIG_PORT);
 
 	if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) )
 		return 1;
@@ -419,9 +399,9 @@
 
 		hwif->set_pio_mode = &qd6500_set_pio_mode;
 
-		probe_hwif_init(hwif);
+		idx[0] = unit;
 
-		ide_proc_register_port(hwif);
+		ide_device_add(idx);
 
 		return 1;
 	}
@@ -436,7 +416,7 @@
 
 		/* qd6580 found */
 
-		control = qd_read_reg(QD_CONTROL_PORT);
+		control = inb(QD_CONTROL_PORT);
 
 		printk(KERN_NOTICE "qd6580 at %#x\n", base);
 		printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n",
@@ -453,11 +433,11 @@
 
 			hwif->set_pio_mode = &qd6580_set_pio_mode;
 
-			probe_hwif_init(hwif);
+			idx[0] = unit;
 
-			qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+			ide_device_add(idx);
 
-			ide_proc_register_port(hwif);
+			outb(QD_DEF_CONTR, QD_CONTROL_PORT);
 
 			return 1;
 		} else {
@@ -474,19 +454,17 @@
 
 			hwif->set_pio_mode = &qd6580_set_pio_mode;
 
-			probe_hwif_init(hwif);
-
 			qd_setup(mate, base, config | (control << 8),
 				 QD6580_DEF_DATA2, QD6580_DEF_DATA2);
 
 			mate->set_pio_mode = &qd6580_set_pio_mode;
 
-			probe_hwif_init(mate);
+			idx[0] = 0;
+			idx[1] = 1;
 
-			qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+			ide_device_add(idx);
 
-			ide_proc_register_port(hwif);
-			ide_proc_register_port(mate);
+			outb(QD_DEF_CONTR, QD_CONTROL_PORT);
 
 			return 0; /* no other qd65xx possible */
 		}
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c
index 1151c92..79577b9 100644
--- a/drivers/ide/legacy/umc8672.c
+++ b/drivers/ide/legacy/umc8672.c
@@ -124,8 +124,9 @@
 
 static int __init umc8672_probe(void)
 {
-	unsigned long flags;
 	ide_hwif_t *hwif, *mate;
+	unsigned long flags;
+	static u8 idx[4] = { 0, 1, 0xff, 0xff };
 
 	if (!request_region(0x108, 2, "umc8672")) {
 		printk(KERN_ERR "umc8672: ports 0x108-0x109 already in use.\n");
@@ -158,11 +159,7 @@
 	mate->mate = hwif;
 	mate->channel = 1;
 
-	probe_hwif_init(hwif);
-	probe_hwif_init(mate);
-
-	ide_proc_register_port(hwif);
-	ide_proc_register_port(mate);
+	ide_device_add(idx);
 
 	return 0;
 }
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 47c035a..a4ce3ba 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -276,8 +276,7 @@
 
 			if (iswrite) {
 				if(!put_source_flags(ahwif->tx_chan, 
-						     (void*)(page_address(sg->page) 
-							     + sg->offset), 
+						     (void*) sg_virt(sg),
 						     tc, flags)) { 
 					printk(KERN_ERR "%s failed %d\n", 
 					       __FUNCTION__, __LINE__);
@@ -285,8 +284,7 @@
 			} else 
 			{
 				if(!put_dest_flags(ahwif->rx_chan, 
-						   (void*)(page_address(sg->page) 
-							   + sg->offset), 
+						   (void*) sg_virt(sg),
 						   tc, flags)) { 
 					printk(KERN_ERR "%s failed %d\n", 
 					       __FUNCTION__, __LINE__);
@@ -601,8 +599,9 @@
 	_auide_hwif *ahwif = &auide_hwif;
 	ide_hwif_t *hwif;
 	struct resource *res;
-	hw_regs_t *hw;
 	int ret = 0;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+	hw_regs_t hw;
 
 #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
 	char *mode = "MWDMA2";
@@ -644,12 +643,12 @@
 	/* FIXME:  This might possibly break PCMCIA IDE devices */
 
 	hwif                            = &ide_hwifs[pdev->id];
-	hw 				= &hwif->hw;
-	hwif->irq = hw->irq             = ahwif->irq;
+	hwif->irq			= ahwif->irq;
 	hwif->chipset                   = ide_au1xxx;
 
-	auide_setup_ports(hw, ahwif);
-	memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
+	memset(&hw, 0, sizeof(hw));
+	auide_setup_ports(&hw, ahwif);
+	memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
 
 	hwif->ultra_mask                = 0x0;  /* Disable Ultra DMA */
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
@@ -699,9 +698,6 @@
 	hwif->dma_host_on		= &auide_dma_host_on;
 	hwif->dma_lost_irq		= &auide_dma_lost_irq;
 	hwif->ide_dma_on                = &auide_dma_on;
-
-	hwif->atapi_dma                 = 1;
-
 #else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
 	hwif->channel                   = 0;
 	hwif->hold                      = 1;
@@ -709,8 +705,10 @@
 	hwif->config_data               = 0;    /* no chipset-specific code */
 
 	hwif->drives[0].autotune        = 1;    /* 1=autotune, 2=noautotune, 0=default */
+	hwif->drives[1].autotune	= 1;
 #endif
-	hwif->drives[0].no_io_32bit     = 1;   
+	hwif->drives[0].no_io_32bit	= 1;
+	hwif->drives[1].no_io_32bit	= 1;
 
 	auide_hwif.hwif                 = hwif;
 	hwif->hwif_data                 = &auide_hwif;
@@ -720,9 +718,9 @@
 	dbdma_init_done = 1;
 #endif
 
-	probe_hwif_init(hwif);
+	idx[0] = hwif->index;
 
-	ide_proc_register_port(hwif);
+	ide_device_add(idx);
 
 	dev_set_drvdata(dev, hwif);
 
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
index c2e2957..521edd4 100644
--- a/drivers/ide/mips/swarm.c
+++ b/drivers/ide/mips/swarm.c
@@ -71,6 +71,7 @@
 	u8 __iomem *base;
 	phys_t offset, size;
 	int i;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 	if (!SIBYTE_HAVE_IDE)
 		return -ENODEV;
@@ -119,18 +120,15 @@
 	hwif->noprobe = 0;
 
 	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-		hwif->hw.io_ports[i] =
+		hwif->io_ports[i] =
 				(unsigned long)(base + ((0x1f0 + i) << 5));
-	hwif->hw.io_ports[IDE_CONTROL_OFFSET] =
+	hwif->io_ports[IDE_CONTROL_OFFSET] =
 				(unsigned long)(base + (0x3f6 << 5));
-	hwif->hw.irq = K_INT_GB_IDE;
+	hwif->irq = K_INT_GB_IDE;
 
-	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
-	hwif->irq = hwif->hw.irq;
+	idx[0] = hwif->index;
 
-	probe_hwif_init(hwif);
-
-	ide_proc_register_port(hwif);
+	ide_device_add(idx);
 
 	dev_set_drvdata(dev, hwif);
 
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index 3a4c2c2..19ec421 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/aec62xx.c		Version 0.25	Aug 1, 2007
+ * linux/drivers/ide/pci/aec62xx.c		Version 0.27	Sep 16, 2007
  *
  * Copyright (C) 1999-2002	Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 2007		MontaVista Software, Inc. <source@mvista.com>
@@ -141,19 +141,6 @@
 	drive->hwif->set_dma_mode(drive, pio + XFER_PIO_0);
 }
 
-static void aec62xx_dma_lost_irq (ide_drive_t *drive)
-{
-	switch (HWIF(drive)->pci_dev->device) {
-		case PCI_DEVICE_ID_ARTOP_ATP860:
-		case PCI_DEVICE_ID_ARTOP_ATP860R:
-		case PCI_DEVICE_ID_ARTOP_ATP865:
-		case PCI_DEVICE_ID_ARTOP_ATP865R:
-			printk(" AEC62XX time out ");
-		default:
-			break;
-	}
-}
-
 static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name)
 {
 	int bus_speed = system_bus_clock();
@@ -184,34 +171,21 @@
 static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
 {
 	struct pci_dev *dev	= hwif->pci_dev;
-	u8 reg54 = 0,  mask	= hwif->channel ? 0xf0 : 0x0f;
-	unsigned long flags;
 
 	hwif->set_pio_mode = &aec_set_pio_mode;
 
-	if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
-		if(hwif->mate)
-			hwif->mate->serialized = hwif->serialized = 1;
+	if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
 		hwif->set_dma_mode = &aec6210_set_mode;
-	} else
+	else
 		hwif->set_dma_mode = &aec6260_set_mode;
 
-	hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->ultra_mask = hwif->cds->udma_mask;
-	hwif->mwdma_mask = 0x07;
+	if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
+		return;
 
-	hwif->dma_lost_irq	= &aec62xx_dma_lost_irq;
-
-	if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
-		spin_lock_irqsave(&ide_lock, flags);
-		pci_read_config_byte (dev, 0x54, &reg54);
-		pci_write_config_byte(dev, 0x54, (reg54 & ~mask));
-		spin_unlock_irqrestore(&ide_lock, flags);
-	} else if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
+	if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
 		u8 ata66 = 0, mask = hwif->channel ? 0x02 : 0x01;
 
 		pci_read_config_byte(hwif->pci_dev, 0x49, &ata66);
@@ -220,73 +194,53 @@
 	}
 }
 
-static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d)
-{
-	return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d)
-{
-	unsigned long dma_base = pci_resource_start(dev, 4);
-
-	if (inb(dma_base + 2) & 0x10) {
-		d->name = (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) ?
-			  "AEC6880R" : "AEC6880";
-		d->udma_mask = 0x7f; /* udma0-6 */
-	}
-
-	return ide_setup_pci_device(dev, d);
-}
-
-static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
+static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
 	{	/* 0 */
 		.name		= "AEC6210",
-		.init_setup	= init_setup_aec62xx,
 		.init_chipset	= init_chipset_aec62xx,
 		.init_hwif	= init_hwif_aec62xx,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
-		.bootable	= OFF_BOARD,
+		.host_flags	= IDE_HFLAG_SERIALIZE |
+				  IDE_HFLAG_NO_ATAPI_DMA |
+				  IDE_HFLAG_OFF_BOARD,
 		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x07, /* udma0-2 */
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA2,
 	},{	/* 1 */
 		.name		= "AEC6260",
-		.init_setup	= init_setup_aec62xx,
 		.init_chipset	= init_chipset_aec62xx,
 		.init_hwif	= init_hwif_aec62xx,
-		.autodma	= NOAUTODMA,
-		.bootable	= OFF_BOARD,
+		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA |
+				  IDE_HFLAG_OFF_BOARD,
 		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x1f, /* udma0-4 */
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA4,
 	},{	/* 2 */
 		.name		= "AEC6260R",
-		.init_setup	= init_setup_aec62xx,
 		.init_chipset	= init_chipset_aec62xx,
 		.init_hwif	= init_hwif_aec62xx,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
-		.bootable	= NEVER_BOARD,
+		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA,
 		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x1f, /* udma0-4 */
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA4,
 	},{	/* 3 */
 		.name		= "AEC6280",
-		.init_setup	= init_setup_aec6x80,
 		.init_chipset	= init_chipset_aec62xx,
 		.init_hwif	= init_hwif_aec62xx,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
+		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
 		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x3f, /* udma0-5 */
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
 	},{	/* 4 */
 		.name		= "AEC6280R",
-		.init_setup	= init_setup_aec6x80,
 		.init_chipset	= init_chipset_aec62xx,
 		.init_hwif	= init_hwif_aec62xx,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
-		.bootable	= OFF_BOARD,
+		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
 		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x3f, /* udma0-5 */
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
 	}
 };
 
@@ -299,14 +253,26 @@
  *	finds a device matching our IDE device tables.
  *
  *	NOTE: since we're going to modify the 'name' field for AEC-6[26]80[R]
- *	chips, pass a local copy of 'struct pci_device_id' down the call chain.
+ *	chips, pass a local copy of 'struct ide_port_info' down the call chain.
  */
- 
+
 static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_pci_device_t d = aec62xx_chipsets[id->driver_data];
+	struct ide_port_info d;
+	u8 idx = id->driver_data;
 
-	return d.init_setup(dev, &d);
+	d = aec62xx_chipsets[idx];
+
+	if (idx == 3 || idx == 4) {
+		unsigned long dma_base = pci_resource_start(dev, 4);
+
+		if (inb(dma_base + 2) & 0x10) {
+			d.name = (idx == 4) ? "AEC6880R" : "AEC6880";
+			d.udma_mask = ATA_UDMA6;
+		}
+	}
+
+	return ide_setup_pci_device(dev, &d);
 }
 
 static const struct pci_device_id aec62xx_pci_tbl[] = {
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 31d4e50..a607dd3 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/alim15x3.c		Version 0.26	Jul 14 2007
+ * linux/drivers/ide/pci/alim15x3.c		Version 0.29	Sep 16 2007
  *
  *  Copyright (C) 1998-2000 Michel Aubry, Maintainer
  *  Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
@@ -492,6 +492,13 @@
 		 * clear bit 7
 		 */
 		pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F);
+		/*
+		 * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
+		 */
+		if (m5229_revision >= 0x20 && isa_dev) {
+			pci_read_config_byte(isa_dev, 0x5e, &tmpbyte);
+			chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0;
+		}
 		goto out;
 	}
 
@@ -537,7 +544,30 @@
 			pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02);
 		}
 	}
+
 out:
+	/*
+	 * CD_ROM DMA on (m5229, 0x53, bit0)
+	 *      Enable this bit even if we want to use PIO.
+	 * PIO FIFO off (m5229, 0x53, bit1)
+	 *      The hardware will use 0x54h and 0x55h to control PIO FIFO.
+	 *	(Not on later devices it seems)
+	 *
+	 *	0x53 changes meaning on later revs - we must no touch
+	 *	bit 1 on them.  Need to check if 0x20 is the right break.
+	 */
+	if (m5229_revision >= 0x20) {
+		pci_read_config_byte(dev, 0x53, &tmpbyte);
+
+		if (m5229_revision <= 0x20)
+			tmpbyte = (tmpbyte & (~0x02)) | 0x01;
+		else if (m5229_revision == 0xc7 || m5229_revision == 0xc8)
+			tmpbyte |= 0x03;
+		else
+			tmpbyte |= 0x01;
+
+		pci_write_config_byte(dev, 0x53, tmpbyte);
+	}
 	pci_dev_put(north);
 	pci_dev_put(isa_dev);
 	local_irq_restore(flags);
@@ -616,36 +646,8 @@
 			if ((tmpbyte & (1 << hwif->channel)) == 0)
 				cbl = ATA_CBL_PATA80;
 		}
-	} else {
-		/*
-		 * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
-		 */
-		pci_read_config_byte(isa_dev, 0x5e, &tmpbyte);
-		chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0;
 	}
 
-	/*
-	 * CD_ROM DMA on (m5229, 0x53, bit0)
-	 *      Enable this bit even if we want to use PIO
-	 * PIO FIFO off (m5229, 0x53, bit1)
-	 *      The hardware will use 0x54h and 0x55h to control PIO FIFO
-	 *	(Not on later devices it seems)
-	 *
-	 *	0x53 changes meaning on later revs - we must no touch
-	 *	bit 1 on them. Need to check if 0x20 is the right break
-	 */
-	 
-	pci_read_config_byte(dev, 0x53, &tmpbyte);
-	
-	if(m5229_revision <= 0x20)
-		tmpbyte = (tmpbyte & (~0x02)) | 0x01;
-	else if (m5229_revision == 0xc7 || m5229_revision == 0xc8)
-		tmpbyte |= 0x03;
-	else
-		tmpbyte |= 0x01;
-
-	pci_write_config_byte(dev, 0x53, tmpbyte);
-
 	local_irq_restore(flags);
 
 	return cbl;
@@ -664,35 +666,8 @@
 	hwif->set_dma_mode = &ali_set_dma_mode;
 	hwif->udma_filter = &ali_udma_filter;
 
-	/* don't use LBA48 DMA on ALi devices before rev 0xC5 */
-	hwif->no_lba48_dma = (m5229_revision <= 0xC4) ? 1 : 0;
-
-	if (!hwif->dma_base) {
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
+	if (hwif->dma_base == 0)
 		return;
-	}
-
-	/*
-	 * check in ->init_dma guarantees m5229_revision >= 0x20 here
-	 */
-
-	if (m5229_revision > 0x20)
-		hwif->atapi_dma = 1;
-
-	if (m5229_revision <= 0x20)
-		hwif->ultra_mask = 0x00; /* no udma */
-	else if (m5229_revision < 0xC2)
-		hwif->ultra_mask = 0x07; /* udma0-2 */
-	else if (m5229_revision == 0xC2 || m5229_revision == 0xC3)
-		hwif->ultra_mask = 0x1f; /* udma0-4 */
-	else if (m5229_revision == 0xC4)
-		hwif->ultra_mask = 0x3f; /* udma0-5 */
-	else
-		hwif->ultra_mask = 0x7f; /* udma0-6 */
-
-	hwif->mwdma_mask = 0x07;
-	hwif->swdma_mask = 0x07;
 
 	hwif->dma_setup = &ali15x3_dma_setup;
 
@@ -771,14 +746,15 @@
 	ide_setup_dma(hwif, dmabase, 8);
 }
 
-static ide_pci_device_t ali15x3_chipset __devinitdata = {
+static const struct ide_port_info ali15x3_chipset __devinitdata = {
 	.name		= "ALI15X3",
 	.init_chipset	= init_chipset_ali15x3,
 	.init_hwif	= init_hwif_ali15x3,
 	.init_dma	= init_dma_ali15x3,
-	.autodma	= AUTODMA,
-	.bootable	= ON_BOARD,
+	.host_flags	= IDE_HFLAG_BOOTABLE,
 	.pio_mask	= ATA_PIO5,
+	.swdma_mask	= ATA_SWDMA2,
+	.mwdma_mask	= ATA_MWDMA2,
 };
 
 /**
@@ -796,15 +772,34 @@
 		{ },
 	};
 
-	ide_pci_device_t *d = &ali15x3_chipset;
+	struct ide_port_info d = ali15x3_chipset;
+	u8 rev = dev->revision;
 
 	if (pci_dev_present(ati_rs100))
 		printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
 
+	/* don't use LBA48 DMA on ALi devices before rev 0xC5 */
+	if (rev <= 0xC4)
+		d.host_flags |= IDE_HFLAG_NO_LBA48_DMA;
+
+	if (rev >= 0x20) {
+		if (rev == 0x20)
+			d.host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
+
+		if (rev < 0xC2)
+			d.udma_mask = ATA_UDMA2;
+		else if (rev == 0xC2 || rev == 0xC3)
+			d.udma_mask = ATA_UDMA4;
+		else if (rev == 0xC4)
+			d.udma_mask = ATA_UDMA5;
+		else
+			d.udma_mask = ATA_UDMA6;
+	}
+
 #if defined(CONFIG_SPARC64)
-	d->init_hwif = init_hwif_common_ali15x3;
+	d.init_hwif = init_hwif_common_ali15x3;
 #endif /* CONFIG_SPARC64 */
-	return ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, &d);
 }
 
 
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 3bf3d93..8d4125e 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -77,7 +77,7 @@
 };
 
 static struct amd_ide_chip *amd_config;
-static ide_pci_device_t *amd_chipset;
+static const struct ide_port_info *amd_chipset;
 static unsigned int amd_80w;
 static unsigned int amd_clock;
 
@@ -233,7 +233,6 @@
  * Print the boot message.
  */
 
-	pci_read_config_byte(dev, PCI_REVISION_ID, &t);
 	printk(KERN_INFO "%s: %s (rev %02x) UDMA%s controller\n",
 		amd_chipset->name, pci_name(dev), dev->revision,
 		amd_dma[fls(amd_config->udma_mask) - 1]);
@@ -243,29 +242,18 @@
 
 static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
 {
-	int i;
-
 	if (hwif->irq == 0) /* 0 is bogus but will do for now */
 		hwif->irq = pci_get_legacy_ide_irq(hwif->pci_dev, hwif->channel);
 
 	hwif->set_pio_mode = &amd_set_pio_mode;
 	hwif->set_dma_mode = &amd_set_drive;
 
-	for (i = 0; i < 2; i++) {
-		hwif->drives[i].io_32bit = 1;
-		hwif->drives[i].unmask = 1;
-		hwif->drives[i].autotune = 1;
-	}
-
 	if (!hwif->dma_base)
 		return;
 
-        hwif->atapi_dma = 1;
-
 	hwif->ultra_mask = amd_config->udma_mask;
-	hwif->mwdma_mask = 0x07;
-	if ((amd_config->flags & AMD_BAD_SWDMA) == 0)
-		hwif->swdma_mask = 0x07;
+	if (amd_config->flags & AMD_BAD_SWDMA)
+		hwif->swdma_mask = 0x00;
 
 	if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
 		if ((amd_80w >> hwif->channel) & 1)
@@ -275,18 +263,24 @@
 	}
 }
 
+#define IDE_HFLAGS_AMD \
+	(IDE_HFLAG_PIO_NO_BLACKLIST | \
+	 IDE_HFLAG_PIO_NO_DOWNGRADE | \
+	 IDE_HFLAG_POST_SET_MODE | \
+	 IDE_HFLAG_IO_32BIT | \
+	 IDE_HFLAG_UNMASK_IRQS | \
+	 IDE_HFLAG_BOOTABLE)
+
 #define DECLARE_AMD_DEV(name_str)					\
 	{								\
 		.name		= name_str,				\
 		.init_chipset	= init_chipset_amd74xx,			\
 		.init_hwif	= init_hwif_amd74xx,			\
-		.autodma	= AUTODMA,				\
 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},	\
-		.bootable	= ON_BOARD,				\
-		.host_flags	= IDE_HFLAG_PIO_NO_BLACKLIST		\
-				| IDE_HFLAG_PIO_NO_DOWNGRADE		\
-				| IDE_HFLAG_POST_SET_MODE,		\
+		.host_flags	= IDE_HFLAGS_AMD,			\
 		.pio_mask	= ATA_PIO5,				\
+		.swdma_mask	= ATA_SWDMA2,				\
+		.mwdma_mask	= ATA_MWDMA2,				\
 	}
 
 #define DECLARE_NV_DEV(name_str)					\
@@ -294,16 +288,14 @@
 		.name		= name_str,				\
 		.init_chipset	= init_chipset_amd74xx,			\
 		.init_hwif	= init_hwif_amd74xx,			\
-		.autodma	= AUTODMA,				\
 		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},	\
-		.bootable	= ON_BOARD,				\
-		.host_flags	= IDE_HFLAG_PIO_NO_BLACKLIST		\
-				| IDE_HFLAG_PIO_NO_DOWNGRADE		\
-				| IDE_HFLAG_POST_SET_MODE,		\
+		.host_flags	= IDE_HFLAGS_AMD,			\
 		.pio_mask	= ATA_PIO5,				\
+		.swdma_mask	= ATA_SWDMA2,				\
+		.mwdma_mask	= ATA_MWDMA2,				\
 	}
 
-static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
+static const struct ide_port_info amd74xx_chipsets[] __devinitdata = {
 	/*  0 */ DECLARE_AMD_DEV("AMD7401"),
 	/*  1 */ DECLARE_AMD_DEV("AMD7409"),
 	/*  2 */ DECLARE_AMD_DEV("AMD7411"),
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 446900d..ef8e016 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -172,21 +172,12 @@
 	u8 ch = hwif->channel;
 	struct pci_dev *pdev = hwif->pci_dev;
 
-	if (!hwif->irq)
-		hwif->irq = ch ? 15 : 14;
-
 	hwif->set_pio_mode = &atiixp_set_pio_mode;
 	hwif->set_dma_mode = &atiixp_set_dma_mode;
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
 
 	if (!hwif->dma_base)
 		return;
 
-	hwif->atapi_dma = 1;
-	hwif->ultra_mask = 0x3f;
-	hwif->mwdma_mask = 0x07;
-
 	pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode);
 
 	if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40)
@@ -198,23 +189,24 @@
 	hwif->dma_host_off = &atiixp_dma_host_off;
 }
 
-
-static ide_pci_device_t atiixp_pci_info[] __devinitdata = {
+static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
 	{	/* 0 */
 		.name		= "ATIIXP",
 		.init_hwif	= init_hwif_atiixp,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
-		.bootable	= ON_BOARD,
+		.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
 	},{	/* 1 */
 		.name		= "SB600_PATA",
 		.init_hwif	= init_hwif_atiixp,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x48,0x01,0x00}, {0x00,0x00,0x00}},
- 		.bootable	= ON_BOARD,
- 		.host_flags	= IDE_HFLAG_SINGLE,
+ 		.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS |
+				  IDE_HFLAG_BOOTABLE,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
  	},
 };
 
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
index f369645..4aa4810 100644
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -185,6 +185,8 @@
 
 #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
 
+static DEFINE_SPINLOCK(cmd640_lock);
+
 /*
  * These are initialized to point at the devices we control
  */
@@ -258,12 +260,12 @@
 
 static u8 get_cmd640_reg(u16 reg)
 {
-	u8 b;
 	unsigned long flags;
+	u8 b;
 
-	spin_lock_irqsave(&ide_lock, flags);
+	spin_lock_irqsave(&cmd640_lock, flags);
 	b = __get_cmd640_reg(reg);
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irqrestore(&cmd640_lock, flags);
 	return b;
 }
 
@@ -271,9 +273,9 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&ide_lock, flags);
+	spin_lock_irqsave(&cmd640_lock, flags);
 	__put_cmd640_reg(reg,val);
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irqrestore(&cmd640_lock, flags);
 }
 
 static int __init match_pci_cmd640_device (void)
@@ -351,7 +353,7 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&ide_lock, flags);
+	spin_lock_irqsave(&cmd640_lock, flags);
 
 	outb_p(0x0a, 0x170 + IDE_SELECT_OFFSET);	/* select drive0 */
 	udelay(100);
@@ -359,11 +361,11 @@
 		outb_p(0x1a, 0x170 + IDE_SELECT_OFFSET); /* select drive1 */
 		udelay(100);
 		if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x1a) {
-			spin_unlock_irqrestore(&ide_lock, flags);
+			spin_unlock_irqrestore(&cmd640_lock, flags);
 			return 0; /* nothing responded */
 		}
 	}
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irqrestore(&cmd640_lock, flags);
 	return 1; /* success */
 }
 
@@ -440,11 +442,11 @@
 static void set_prefetch_mode (unsigned int index, int mode)
 {
 	ide_drive_t *drive = cmd_drives[index];
+	unsigned long flags;
 	int reg = prefetch_regs[index];
 	u8 b;
-	unsigned long flags;
 
-	spin_lock_irqsave(&ide_lock, flags);
+	spin_lock_irqsave(&cmd640_lock, flags);
 	b = __get_cmd640_reg(reg);
 	if (mode) {	/* want prefetch on? */
 #if CMD640_PREFETCH_MASKS
@@ -460,7 +462,7 @@
 		b |= prefetch_masks[index];	/* disable prefetch */
 	}
 	__put_cmd640_reg(reg, b);
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irqrestore(&cmd640_lock, flags);
 }
 
 /*
@@ -561,7 +563,7 @@
 	/*
 	 * Now that everything is ready, program the new timings
 	 */
-	spin_lock_irqsave(&ide_lock, flags);
+	spin_lock_irqsave(&cmd640_lock, flags);
 	/*
 	 * Program the address_setup clocks into ARTTIM reg,
 	 * and then the active/recovery counts into the DRWTIM reg
@@ -570,7 +572,7 @@
 	setup_count |= __get_cmd640_reg(arttim_regs[index]) & 0x3f;
 	__put_cmd640_reg(arttim_regs[index], setup_count);
 	__put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count));
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irqrestore(&cmd640_lock, flags);
 }
 
 /*
@@ -670,20 +672,20 @@
 
 static int pci_conf1(void)
 {
-	u32 tmp;
 	unsigned long flags;
+	u32 tmp;
 
-	spin_lock_irqsave(&ide_lock, flags);
+	spin_lock_irqsave(&cmd640_lock, flags);
 	outb(0x01, 0xCFB);
 	tmp = inl(0xCF8);
 	outl(0x80000000, 0xCF8);
 	if (inl(0xCF8) == 0x80000000) {
 		outl(tmp, 0xCF8);
-		spin_unlock_irqrestore(&ide_lock, flags);
+		spin_unlock_irqrestore(&cmd640_lock, flags);
 		return 1;
 	}
 	outl(tmp, 0xCF8);
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irqrestore(&cmd640_lock, flags);
 	return 0;
 }
 
@@ -691,15 +693,15 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&ide_lock, flags);
+	spin_lock_irqsave(&cmd640_lock, flags);
 	outb(0x00, 0xCFB);
 	outb(0x00, 0xCF8);
 	outb(0x00, 0xCFA);
 	if (inb(0xCF8) == 0x00 && inb(0xCF8) == 0x00) {
-		spin_unlock_irqrestore(&ide_lock, flags);
+		spin_unlock_irqrestore(&cmd640_lock, flags);
 		return 1;
 	}
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irqrestore(&cmd640_lock, flags);
 	return 0;
 }
 
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index f3d3bde..ea0143e 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -439,11 +439,8 @@
 	u8 mrdmode = 0;
 
 	if (dev->device == PCI_DEVICE_ID_CMD_646) {
-		u8 rev = 0;
 
-		pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
-
-		switch (rev) {
+		switch (dev->revision) {
 		case 0x07:
 		case 0x05:
 			printk("%s: UltraDMA capable\n", name);
@@ -505,22 +502,13 @@
 static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
 {
 	struct pci_dev *dev	= hwif->pci_dev;
-	u8 rev			= 0;
-
-	pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
 
 	hwif->set_pio_mode = &cmd64x_set_pio_mode;
 	hwif->set_dma_mode = &cmd64x_set_dma_mode;
 
-	hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
 	if (!hwif->dma_base)
 		return;
 
-	hwif->atapi_dma  = 1;
-	hwif->mwdma_mask = 0x07;
-	hwif->ultra_mask = hwif->cds->udma_mask;
-
 	/*
 	 * UltraDMA only supported on PCI646U and PCI646U2, which
 	 * correspond to revisions 0x03, 0x05 and 0x07 respectively.
@@ -533,7 +521,7 @@
 	 *
 	 * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
 	 */
-	if (dev->device == PCI_DEVICE_ID_CMD_646 && rev < 5)
+	if (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 5)
 		hwif->ultra_mask = 0x00;
 
 	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
@@ -547,11 +535,10 @@
 		hwif->ide_dma_test_irq	= &cmd648_ide_dma_test_irq;
 		break;
 	case PCI_DEVICE_ID_CMD_646:
-		hwif->chipset = ide_cmd646;
-		if (rev == 0x01) {
+		if (dev->revision == 0x01) {
 			hwif->ide_dma_end = &cmd646_1_ide_dma_end;
 			break;
-		} else if (rev >= 0x03)
+		} else if (dev->revision >= 0x03)
 			goto alt_irq_bits;
 		/* fall thru */
 	default:
@@ -561,80 +548,62 @@
 	}
 }
 
-static int __devinit init_setup_cmd64x(struct pci_dev *dev, ide_pci_device_t *d)
-{
-	return ide_setup_pci_device(dev, d);
-}
+static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "CMD643",
+		.init_chipset	= init_chipset_cmd64x,
+		.init_hwif	= init_hwif_cmd64x,
+		.enablebits	= {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
+		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
+		.pio_mask	= ATA_PIO5,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= 0x00, /* no udma */
+	},{	/* 1 */
+		.name		= "CMD646",
+		.init_chipset	= init_chipset_cmd64x,
+		.init_hwif	= init_hwif_cmd64x,
+		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
+		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
+		.pio_mask	= ATA_PIO5,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA2,
+	},{	/* 2 */
+		.name		= "CMD648",
+		.init_chipset	= init_chipset_cmd64x,
+		.init_hwif	= init_hwif_cmd64x,
+		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
+		.chipset	= ide_cmd646,
+		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
+		.pio_mask	= ATA_PIO5,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA4,
+	},{	/* 3 */
+		.name		= "CMD649",
+		.init_chipset	= init_chipset_cmd64x,
+		.init_hwif	= init_hwif_cmd64x,
+		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
+		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
+		.pio_mask	= ATA_PIO5,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
+	}
+};
 
-static int __devinit init_setup_cmd646(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
+	struct ide_port_info d;
+	u8 idx = id->driver_data;
+
+	d = cmd64x_chipsets[idx];
+
 	/*
 	 * The original PCI0646 didn't have the primary channel enable bit,
 	 * it appeared starting with PCI0646U (i.e. revision ID 3).
 	 */
-	if (dev->revision < 3)
-		d->enablebits[0].reg = 0;
+	if (idx == 1 && dev->revision < 3)
+		d.enablebits[0].reg = 0;
 
-	return ide_setup_pci_device(dev, d);
-}
-
-static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "CMD643",
-		.init_setup	= init_setup_cmd64x,
-		.init_chipset	= init_chipset_cmd64x,
-		.init_hwif	= init_hwif_cmd64x,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH,
-		.pio_mask	= ATA_PIO5,
-		.udma_mask	= 0x00, /* no udma */
-	},{	/* 1 */
-		.name		= "CMD646",
-		.init_setup	= init_setup_cmd646,
-		.init_chipset	= init_chipset_cmd64x,
-		.init_hwif	= init_hwif_cmd64x,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH,
-		.pio_mask	= ATA_PIO5,
-		.udma_mask	= 0x07, /* udma0-2 */
-	},{	/* 2 */
-		.name		= "CMD648",
-		.init_setup	= init_setup_cmd64x,
-		.init_chipset	= init_chipset_cmd64x,
-		.init_hwif	= init_hwif_cmd64x,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH,
-		.pio_mask	= ATA_PIO5,
-		.udma_mask	= 0x1f, /* udma0-4 */
-	},{	/* 3 */
-		.name		= "CMD649",
-		.init_setup	= init_setup_cmd64x,
-		.init_chipset	= init_chipset_cmd64x,
-		.init_hwif	= init_hwif_cmd64x,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_ABUSE_PREFETCH,
-		.pio_mask	= ATA_PIO5,
-		.udma_mask	= 0x3f, /* udma0-5 */
-	}
-};
-
-/*
- * We may have to modify enablebits for PCI0646, so we'd better pass
- * a local copy of the ide_pci_device_t structure down the call chain...
- */
-static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
-{
-	ide_pci_device_t d = cmd64x_chipsets[id->driver_data];
-
-	return d.init_setup(dev, &d);
+	return ide_setup_pci_device(dev, &d);
 }
 
 static const struct pci_device_id cmd64x_pci_tbl[] = {
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index a8bf494..0466462 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -106,18 +106,6 @@
 }
 
 /*
- *	We provide a callback for our nonstandard DMA location
- */
-
-static void __devinit cs5520_init_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
-{
-	unsigned long bmide = pci_resource_start(dev, 2);	/* Not the usual 4 */
-	if(hwif->mate && hwif->mate->dma_base)	/* Second channel at primary + 8 */
-		bmide += 8;
-	ide_setup_dma(hwif, bmide, 8);
-}
-
-/*
  *	We wrap the DMA activate to set the vdma flag. This is needed
  *	so that the IDE DMA layer issues PIO not DMA commands over the
  *	DMA channel
@@ -125,6 +113,7 @@
  
 static int cs5520_dma_on(ide_drive_t *drive)
 {
+	/* ATAPI is harder so leave it for now */
 	drive->vdma = 1;
 	return 0;
 }
@@ -134,33 +123,25 @@
 	hwif->set_pio_mode = &cs5520_set_pio_mode;
 	hwif->set_dma_mode = &cs5520_set_dma_mode;
 
-	if (hwif->dma_base == 0) {
-		hwif->drives[1].autotune = hwif->drives[0].autotune = 1;
+	if (hwif->dma_base == 0)
 		return;
-	}
 
 	hwif->ide_dma_on = &cs5520_dma_on;
-
-	/* ATAPI is harder so leave it for now */
-	hwif->atapi_dma = 0;
-	hwif->ultra_mask = 0;
-	hwif->swdma_mask = 0;
-	hwif->mwdma_mask = 0;
 }
 
 #define DECLARE_CS_DEV(name_str)				\
 	{							\
 		.name		= name_str,			\
-		.init_setup_dma = cs5520_init_setup_dma,	\
 		.init_hwif	= init_hwif_cs5520,		\
-		.autodma	= AUTODMA,			\
-		.bootable	= ON_BOARD,			\
 		.host_flags	= IDE_HFLAG_ISA_PORTS |		\
-				  IDE_HFLAG_VDMA,		\
+				  IDE_HFLAG_CS5520 |		\
+				  IDE_HFLAG_VDMA |		\
+				  IDE_HFLAG_NO_ATAPI_DMA |	\
+				  IDE_HFLAG_BOOTABLE,		\
 		.pio_mask	= ATA_PIO4,			\
 	}
 
-static ide_pci_device_t cyrix_chipsets[] __devinitdata = {
+static const struct ide_port_info cyrix_chipsets[] __devinitdata = {
 	/* 0 */ DECLARE_CS_DEV("Cyrix 5510"),
 	/* 1 */ DECLARE_CS_DEV("Cyrix 5520")
 };
@@ -173,9 +154,8 @@
  
 static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_hwif_t *hwif = NULL, *mate = NULL;
-	ata_index_t index;
-	ide_pci_device_t *d = &cyrix_chipsets[id->driver_data];
+	const struct ide_port_info *d = &cyrix_chipsets[id->driver_data];
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 	ide_setup_pci_noise(dev, d);
 
@@ -191,29 +171,14 @@
 		return -ENODEV;
 	}
 
-	index.all = 0xf0f0;
-
 	/*
 	 *	Now the chipset is configured we can let the core
 	 *	do all the device setup for us
 	 */
 
-	ide_pci_setup_ports(dev, d, 14, &index);
+	ide_pci_setup_ports(dev, d, 14, &idx[0]);
 
-	if ((index.b.low & 0xf0) != 0xf0)
-		hwif = &ide_hwifs[index.b.low];
-	if ((index.b.high & 0xf0) != 0xf0)
-		mate = &ide_hwifs[index.b.high];
-
-	if (hwif)
-		probe_hwif_init(hwif);
-	if (mate)
-		probe_hwif_init(mate);
-
-	if (hwif)
-		ide_proc_register_port(hwif);
-	if (mate)
-		ide_proc_register_port(mate);
+	ide_device_add(idx);
 
 	return 0;
 }
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index 0d23b8a..5994089 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/cs5530.c		Version 0.76	Aug 3 2007
+ * linux/drivers/ide/pci/cs5530.c		Version 0.77	Sep 24 2007
  *
  * Copyright (C) 2000			Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 2000			Mark Lord <mlord@pobox.com>
@@ -146,7 +146,6 @@
 static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const char *name)
 {
 	struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
-	unsigned long flags;
 
 	if (pci_resource_start(dev, 4) == 0)
 		return -EFAULT;
@@ -171,9 +170,6 @@
 		goto out;
 	}
 
-	spin_lock_irqsave(&ide_lock, flags);
-		/* all CPUs (there should only be one CPU with this chipset) */
-
 	/*
 	 * Enable BusMaster and MemoryWriteAndInvalidate for the cs5530:
 	 * -->  OR 0x14 into 16-bit PCI COMMAND reg of function 0 of the cs5530
@@ -224,8 +220,6 @@
 	pci_write_config_byte(master_0, 0x42, 0x00);
 	pci_write_config_byte(master_0, 0x43, 0xc1);
 
-	spin_unlock_irqrestore(&ide_lock, flags);
-
 out:
 	pci_dev_put(master_0);
 	pci_dev_put(cs5530_0);
@@ -245,9 +239,6 @@
 	unsigned long basereg;
 	u32 d0_timings;
 
-	if (hwif->mate)
-		hwif->serialized = hwif->mate->serialized = 1;
-
 	hwif->set_pio_mode = &cs5530_set_pio_mode;
 	hwif->set_dma_mode = &cs5530_set_dma_mode;
 
@@ -258,27 +249,22 @@
 	if (CS5530_BAD_PIO(inl(basereg + 8)))
 		outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 8);
 
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->atapi_dma = 1;
-	hwif->ultra_mask = 0x07;
-	hwif->mwdma_mask = 0x07;
-
 	hwif->udma_filter = cs5530_udma_filter;
 }
 
-static ide_pci_device_t cs5530_chipset __devinitdata = {
+static const struct ide_port_info cs5530_chipset __devinitdata = {
 	.name		= "CS5530",
 	.init_chipset	= init_chipset_cs5530,
 	.init_hwif	= init_hwif_cs5530,
-	.autodma	= AUTODMA,
-	.bootable	= ON_BOARD,
+	.host_flags	= IDE_HFLAG_SERIALIZE |
+			  IDE_HFLAG_POST_SET_MODE |
+			  IDE_HFLAG_BOOTABLE,
 	.pio_mask	= ATA_PIO4,
-	.host_flags	= IDE_HFLAG_POST_SET_MODE,
+	.mwdma_mask	= ATA_MWDMA2,
+	.udma_mask	= ATA_UDMA2,
 };
 
 static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index e4891a1..9094916 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -84,7 +84,7 @@
 
 	/* Set the PIO timings */
 	if ((speed & XFER_MODE) == XFER_PIO) {
-		ide_drive_t *pair = &drive->hwif->drives[drive->dn ^ 1];
+		ide_drive_t *pair = ide_get_paired_drive(drive);
 		u8 cmd, pioa;
 
 		cmd = pioa = speed - XFER_PIO_0;
@@ -180,25 +180,20 @@
 	hwif->set_pio_mode = &cs5535_set_pio_mode;
 	hwif->set_dma_mode = &cs5535_set_dma_mode;
 
-	hwif->drives[1].autotune = hwif->drives[0].autotune = 1;
-
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->atapi_dma = 1;
-	hwif->ultra_mask = 0x1F;
-	hwif->mwdma_mask = 0x07;
-
 	hwif->cbl = cs5535_cable_detect(hwif->pci_dev);
 }
 
-static ide_pci_device_t cs5535_chipset __devinitdata = {
+static const struct ide_port_info cs5535_chipset __devinitdata = {
 	.name		= "CS5535",
 	.init_hwif	= init_hwif_cs5535,
-	.autodma	= AUTODMA,
-	.bootable	= ON_BOARD,
-	.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE,
+	.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE |
+			  IDE_HFLAG_BOOTABLE,
 	.pio_mask	= ATA_PIO4,
+	.mwdma_mask	= ATA_MWDMA2,
+	.udma_mask	= ATA_UDMA4,
 };
 
 static int __devinit cs5535_init_one(struct pci_dev *dev,
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index c498ecf..3ef4fc1 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/cy82c693.c		Version 0.40	Sep. 10, 2002
+ * linux/drivers/ide/pci/cy82c693.c		Version 0.41	Aug 27, 2007
  *
  *  Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
  *  Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
@@ -428,18 +428,10 @@
  */
 static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
 {
-	hwif->chipset = ide_cy82c693;
 	hwif->set_pio_mode = &cy82c693_set_pio_mode;
 
-	if (!hwif->dma_base) {
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
+	if (hwif->dma_base == 0)
 		return;
-	}
-
-	hwif->atapi_dma = 1;
-	hwif->mwdma_mask = 0x04;
-	hwif->swdma_mask = 0x04;
 
 	hwif->ide_dma_on = &cy82c693_ide_dma_on;
 }
@@ -456,15 +448,17 @@
 	}
 }
 
-static ide_pci_device_t cy82c693_chipset __devinitdata = {
+static const struct ide_port_info cy82c693_chipset __devinitdata = {
 	.name		= "CY82C693",
 	.init_chipset	= init_chipset_cy82c693,
 	.init_iops	= init_iops_cy82c693,
 	.init_hwif	= init_hwif_cy82c693,
-	.autodma	= AUTODMA,
-	.bootable	= ON_BOARD,
-	.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_TRUST_BIOS_FOR_DMA,
+	.chipset	= ide_cy82c693,
+	.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+			  IDE_HFLAG_BOOTABLE,
 	.pio_mask	= ATA_PIO4,
+	.swdma_mask	= ATA_SWDMA2_ONLY,
+	.mwdma_mask	= ATA_MWDMA2_ONLY,
 };
 
 static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
index 46f4a88..8382908 100644
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -80,7 +80,7 @@
 	hw.irq = dev->irq;
 	hw.chipset = ide_pci;		/* this enables IRQ sharing */
 
-	rc = ide_register_hw_with_fixup(&hw, 0, &hwif, ide_undecoded_slave);
+	rc = ide_register_hw(&hw, &ide_undecoded_slave, 0, &hwif);
 	if (rc < 0) {
 		printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc);
 		pci_disable_device(dev);
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index cce6311..f44d708 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -54,130 +54,61 @@
 module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
 MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
 
-static void __devinit init_hwif_generic (ide_hwif_t *hwif)
-{
-	switch(hwif->pci_dev->device) {
-		case PCI_DEVICE_ID_UMC_UM8673F:
-		case PCI_DEVICE_ID_UMC_UM8886A:
-		case PCI_DEVICE_ID_UMC_UM8886BF:
-			hwif->irq = hwif->channel ? 15 : 14;
-			break;
-		default:
-			break;
+#define IDE_HFLAGS_UMC (IDE_HFLAG_NO_DMA | IDE_HFLAG_FORCE_LEGACY_IRQS)
+
+#define DECLARE_GENERIC_PCI_DEV(name_str, extra_flags) \
+	{ \
+		.name		= name_str, \
+		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA | \
+				  extra_flags | \
+				  IDE_HFLAG_BOOTABLE, \
+		.swdma_mask	= ATA_SWDMA2, \
+		.mwdma_mask	= ATA_MWDMA2, \
+		.udma_mask	= ATA_UDMA6, \
 	}
 
-	if (!(hwif->dma_base))
-		return;
+static const struct ide_port_info generic_chipsets[] __devinitdata = {
+	/*  0 */ DECLARE_GENERIC_PCI_DEV("Unknown",	0),
 
-	hwif->atapi_dma = 1;
-	hwif->ultra_mask = 0x7f;
-	hwif->mwdma_mask = 0x07;
-	hwif->swdma_mask = 0x07;
-}
-
-#if 0
-	/* Logic to add back later on */
-
-	if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
-		ide_pci_device_t *unknown = unknown_chipset;
-		init_setup_unknown(dev, unknown);
-		return 1;
-	}
-	return 0;
-#endif	
-
-static ide_pci_device_t generic_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "Unknown",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 1 */
+	{	/* 1 */
 		.name		= "NS87410",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-        },{	/* 2 */
-		.name		= "SAMURAI",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 3 */
-		.name		= "HT6565",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 4 */
-		.name		= "UM8673F",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= NODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 5 */
-		.name		= "UM8886A",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= NODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 6 */
-		.name		= "UM8886BF",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= NODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 7 */
-		.name		= "HINT_IDE",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 8 */
-		.name		= "VIA_IDE",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= NOAUTODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 9 */
-		.name		= "OPTI621V",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= NOAUTODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 10 */
+		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+				  IDE_HFLAG_BOOTABLE,
+		.swdma_mask	= ATA_SWDMA2,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA6,
+	},
+
+	/*  2 */ DECLARE_GENERIC_PCI_DEV("SAMURAI",	0),
+	/*  3 */ DECLARE_GENERIC_PCI_DEV("HT6565",	0),
+	/*  4 */ DECLARE_GENERIC_PCI_DEV("UM8673F",	IDE_HFLAGS_UMC),
+	/*  5 */ DECLARE_GENERIC_PCI_DEV("UM8886A",	IDE_HFLAGS_UMC),
+	/*  6 */ DECLARE_GENERIC_PCI_DEV("UM8886BF",	IDE_HFLAGS_UMC),
+	/*  7 */ DECLARE_GENERIC_PCI_DEV("HINT_IDE",	0),
+	/*  8 */ DECLARE_GENERIC_PCI_DEV("VIA_IDE",	IDE_HFLAG_NO_AUTODMA),
+	/*  9 */ DECLARE_GENERIC_PCI_DEV("OPTI621V",	IDE_HFLAG_NO_AUTODMA),
+
+	{	/* 10 */
 		.name		= "VIA8237SATA",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 11 */
-		.name 		= "Piccolo0102",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= NOAUTODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 12 */
-		.name 		= "Piccolo0103",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= NOAUTODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 13 */
-		.name 		= "Piccolo0105",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= NOAUTODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
-	},{	/* 14 */
+		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+				  IDE_HFLAG_OFF_BOARD,
+		.swdma_mask	= ATA_SWDMA2,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA6,
+	},
+
+	/* 11 */ DECLARE_GENERIC_PCI_DEV("Piccolo0102",	IDE_HFLAG_NO_AUTODMA),
+	/* 12 */ DECLARE_GENERIC_PCI_DEV("Piccolo0103",	IDE_HFLAG_NO_AUTODMA),
+	/* 13 */ DECLARE_GENERIC_PCI_DEV("Piccolo0105",	IDE_HFLAG_NO_AUTODMA),
+
+	{	/* 14 */
 		.name		= "Revolution",
-		.init_hwif	= init_hwif_generic,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
+		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+				  IDE_HFLAG_OFF_BOARD,
+		.swdma_mask	= ATA_SWDMA2,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA6,
 	}
 };
 
@@ -192,7 +123,7 @@
  
 static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_pci_device_t *d = &generic_chipsets[id->driver_data];
+	const struct ide_port_info *d = &generic_chipsets[id->driver_data];
 	int ret = -ENODEV;
 
 	/* Don't use the generic entry unless instructed to do so */
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index 44ac0e2..ae6307f 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -125,49 +125,45 @@
 
 static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
 {
-	u16 pcicmd = 0;
-
 	hwif->set_pio_mode = &hpt34x_set_pio_mode;
 	hwif->set_dma_mode = &hpt34x_set_mode;
-
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-
-	pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd);
-
-	if (!hwif->dma_base)
-		return;
-
-#ifdef CONFIG_HPT34X_AUTODMA
-	if ((pcicmd & PCI_COMMAND_MEMORY) == 0)
-		return;
-
-	hwif->ultra_mask = 0x07;
-	hwif->mwdma_mask = 0x07;
-	hwif->swdma_mask = 0x07;
-#endif
 }
 
-static ide_pci_device_t hpt34x_chipset __devinitdata = {
-	.name		= "HPT34X",
-	.init_chipset	= init_chipset_hpt34x,
-	.init_hwif	= init_hwif_hpt34x,
-	.autodma	= NOAUTODMA,
-	.bootable	= NEVER_BOARD,
-	.extra		= 16,
-	.pio_mask	= ATA_PIO5,
+static const struct ide_port_info hpt34x_chipsets[] __devinitdata = {
+	{ /* 0 */
+		.name		= "HPT343",
+		.init_chipset	= init_chipset_hpt34x,
+		.init_hwif	= init_hwif_hpt34x,
+		.extra		= 16,
+		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA |
+				  IDE_HFLAG_NO_AUTODMA,
+		.pio_mask	= ATA_PIO5,
+	},
+	{ /* 1 */
+		.name		= "HPT345",
+		.init_chipset	= init_chipset_hpt34x,
+		.init_hwif	= init_hwif_hpt34x,
+		.extra		= 16,
+		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA |
+				  IDE_HFLAG_NO_AUTODMA |
+				  IDE_HFLAG_OFF_BOARD,
+		.pio_mask	= ATA_PIO5,
+#ifdef CONFIG_HPT34X_AUTODMA
+		.swdma_mask	= ATA_SWDMA2,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA2,
+#endif
+	}
 };
 
 static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_pci_device_t *d = &hpt34x_chipset;
-	static char *chipset_names[] = {"HPT343", "HPT345"};
+	const struct ide_port_info *d;
 	u16 pcicmd = 0;
 
 	pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
 
-	d->name = chipset_names[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0];
-	d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD;
+	d = &hpt34x_chipsets[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0];
 
 	return ide_setup_pci_device(dev, d);
 }
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index fcb21dd..612b795 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1,9 +1,10 @@
 /*
- * linux/drivers/ide/pci/hpt366.c		Version 1.14	Oct 1, 2007
+ * linux/drivers/ide/pci/hpt366.c		Version 1.20	Oct 1, 2007
  *
  * Copyright (C) 1999-2003		Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001	        Sun Microsystems, Inc.
  * Portions Copyright (C) 2003		Red Hat Inc
+ * Portions Copyright (C) 2007		Bartlomiej Zolnierkiewicz
  * Portions Copyright (C) 2005-2007	MontaVista Software, Inc.
  *
  * Thanks to HighPoint Technologies for their assistance, and hardware.
@@ -393,8 +394,9 @@
  */
 
 struct hpt_info {
+	char *chip_name;	/* Chip name */
 	u8 chip_type;		/* Chip type */
-	u8 max_ultra;		/* Max. UltraDMA mode allowed */
+	u8 udma_mask;		/* Allowed UltraDMA modes mask. */
 	u8 dpll_clk;		/* DPLL clock in MHz */
 	u8 pci_clk;		/* PCI  clock in MHz */
 	u32 **settings; 	/* Chipset settings table */
@@ -432,78 +434,89 @@
 };
 
 static struct hpt_info hpt36x __devinitdata = {
+	.chip_name	= "HPT36x",
 	.chip_type	= HPT36x,
-	.max_ultra	= HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? 4 : 3) : 2,
+	.udma_mask	= HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2,
 	.dpll_clk	= 0,	/* no DPLL */
 	.settings	= hpt36x_settings
 };
 
 static struct hpt_info hpt370 __devinitdata = {
+	.chip_name	= "HPT370",
 	.chip_type	= HPT370,
-	.max_ultra	= HPT370_ALLOW_ATA100_5 ? 5 : 4,
+	.udma_mask	= HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
 	.dpll_clk	= 48,
 	.settings	= hpt37x_settings
 };
 
 static struct hpt_info hpt370a __devinitdata = {
+	.chip_name	= "HPT370A",
 	.chip_type	= HPT370A,
-	.max_ultra	= HPT370_ALLOW_ATA100_5 ? 5 : 4,
+	.udma_mask	= HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
 	.dpll_clk	= 48,
 	.settings	= hpt37x_settings
 };
 
 static struct hpt_info hpt374 __devinitdata = {
+	.chip_name	= "HPT374",
 	.chip_type	= HPT374,
-	.max_ultra	= 5,
+	.udma_mask	= ATA_UDMA5,
 	.dpll_clk	= 48,
 	.settings	= hpt37x_settings
 };
 
 static struct hpt_info hpt372 __devinitdata = {
+	.chip_name	= "HPT372",
 	.chip_type	= HPT372,
-	.max_ultra	= HPT372_ALLOW_ATA133_6 ? 6 : 5,
+	.udma_mask	= HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
 	.dpll_clk	= 55,
 	.settings	= hpt37x_settings
 };
 
 static struct hpt_info hpt372a __devinitdata = {
+	.chip_name	= "HPT372A",
 	.chip_type	= HPT372A,
-	.max_ultra	= HPT372_ALLOW_ATA133_6 ? 6 : 5,
+	.udma_mask	= HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
 	.dpll_clk	= 66,
 	.settings	= hpt37x_settings
 };
 
 static struct hpt_info hpt302 __devinitdata = {
+	.chip_name	= "HPT302",
 	.chip_type	= HPT302,
-	.max_ultra	= HPT372_ALLOW_ATA133_6 ? 6 : 5,
+	.udma_mask	= HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
 	.dpll_clk	= 66,
 	.settings	= hpt37x_settings
 };
 
 static struct hpt_info hpt371 __devinitdata = {
+	.chip_name	= "HPT371",
 	.chip_type	= HPT371,
-	.max_ultra	= HPT371_ALLOW_ATA133_6 ? 6 : 5,
+	.udma_mask	= HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
 	.dpll_clk	= 66,
 	.settings	= hpt37x_settings
 };
 
 static struct hpt_info hpt372n __devinitdata = {
+	.chip_name	= "HPT372N",
 	.chip_type	= HPT372N,
-	.max_ultra	= HPT372_ALLOW_ATA133_6 ? 6 : 5,
+	.udma_mask	= HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
 	.dpll_clk	= 77,
 	.settings	= hpt37x_settings
 };
 
 static struct hpt_info hpt302n __devinitdata = {
+	.chip_name	= "HPT302N",
 	.chip_type	= HPT302N,
-	.max_ultra	= HPT302_ALLOW_ATA133_6 ? 6 : 5,
+	.udma_mask	= HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
 	.dpll_clk	= 77,
 	.settings	= hpt37x_settings
 };
 
 static struct hpt_info hpt371n __devinitdata = {
+	.chip_name	= "HPT371N",
 	.chip_type	= HPT371N,
-	.max_ultra	= HPT371_ALLOW_ATA133_6 ? 6 : 5,
+	.udma_mask	= HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
 	.dpll_clk	= 77,
 	.settings	= hpt37x_settings
 };
@@ -676,12 +689,11 @@
 
 static void hpt3xx_intrproc(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = HWIF(drive);
-
 	if (drive->quirk_list)
 		return;
+
 	/* drives in the quirk_list may not like intr setups/cleanups */
-	hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG);
+	outb(drive->ctl | 2, IDE_CONTROL_REG);
 }
 
 static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
@@ -709,8 +721,8 @@
 				enable_irq (hwif->irq);
 		}
 	} else
-		hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
-			   IDE_CONTROL_REG);
+		outb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
+		     IDE_CONTROL_REG);
 }
 
 /*
@@ -750,9 +762,9 @@
 	printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo & 0x1ff);
 
 	/* get DMA command mode */
-	dma_cmd = hwif->INB(hwif->dma_command);
+	dma_cmd = inb(hwif->dma_command);
 	/* stop DMA */
-	hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command);
+	outb(dma_cmd & ~0x1, hwif->dma_command);
 	hpt370_clear_engine(drive);
 }
 
@@ -767,12 +779,12 @@
 static int hpt370_ide_dma_end(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
-	u8  dma_stat		= hwif->INB(hwif->dma_status);
+	u8  dma_stat		= inb(hwif->dma_status);
 
 	if (dma_stat & 0x01) {
 		/* wait a little */
 		udelay(20);
-		dma_stat = hwif->INB(hwif->dma_status);
+		dma_stat = inb(hwif->dma_status);
 		if (dma_stat & 0x01)
 			hpt370_irq_timeout(drive);
 	}
@@ -833,34 +845,32 @@
 
 static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode)
 {
-	u8 scr2 = hwif->INB(hwif->dma_master + 0x7b);
+	u8 scr2 = inb(hwif->dma_master + 0x7b);
 
 	if ((scr2 & 0x7f) == mode)
 		return;
 
 	/* Tristate the bus */
-	hwif->OUTB(0x80, hwif->dma_master + 0x73);
-	hwif->OUTB(0x80, hwif->dma_master + 0x77);
+	outb(0x80, hwif->dma_master + 0x73);
+	outb(0x80, hwif->dma_master + 0x77);
 
 	/* Switch clock and reset channels */
-	hwif->OUTB(mode, hwif->dma_master + 0x7b);
-	hwif->OUTB(0xc0, hwif->dma_master + 0x79);
+	outb(mode, hwif->dma_master + 0x7b);
+	outb(0xc0, hwif->dma_master + 0x79);
 
 	/*
 	 * Reset the state machines.
 	 * NOTE: avoid accidentally enabling the disabled channels.
 	 */
-	hwif->OUTB(hwif->INB(hwif->dma_master + 0x70) | 0x32,
-		   hwif->dma_master + 0x70);
-	hwif->OUTB(hwif->INB(hwif->dma_master + 0x74) | 0x32,
-		   hwif->dma_master + 0x74);
+	outb(inb(hwif->dma_master + 0x70) | 0x32, hwif->dma_master + 0x70);
+	outb(inb(hwif->dma_master + 0x74) | 0x32, hwif->dma_master + 0x74);
 
 	/* Complete reset */
-	hwif->OUTB(0x00, hwif->dma_master + 0x79);
+	outb(0x00, hwif->dma_master + 0x79);
 
 	/* Reconnect channels to bus */
-	hwif->OUTB(0x00, hwif->dma_master + 0x73);
-	hwif->OUTB(0x00, hwif->dma_master + 0x77);
+	outb(0x00, hwif->dma_master + 0x73);
+	outb(0x00, hwif->dma_master + 0x77);
 }
 
 /**
@@ -1139,7 +1149,7 @@
 		  * Select 66 MHz DPLL clock only if UltraATA/133 mode is
 		  * supported/enabled, use 50 MHz DPLL clock otherwise...
 		  */
-		if (info->max_ultra == 6) {
+		if (info->udma_mask == ATA_UDMA6) {
 			dpll_clk = 66;
 			clock = ATA_CLOCK_66MHZ;
 		} else if (dpll_clk) {	/* HPT36x chips don't have DPLL */
@@ -1291,14 +1301,9 @@
 	if (new_mcr != old_mcr)
 		pci_write_config_byte(dev, hwif->select_data + 1, new_mcr);
 
-	hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->ultra_mask = hwif->cds->udma_mask;
-	hwif->mwdma_mask = 0x07;
-
 	/*
 	 * The HPT37x uses the CBLID pins as outputs for MA15/MA16
 	 * address lines to access an external EEPROM.  To read valid
@@ -1354,7 +1359,7 @@
 	u8 dma_new	= 0, dma_old	= 0;
 	unsigned long flags;
 
-	dma_old = hwif->INB(dmabase + 2);
+	dma_old = inb(dmabase + 2);
 
 	local_irq_save(flags);
 
@@ -1365,60 +1370,26 @@
 	if (masterdma & 0x30)	dma_new |= 0x20;
 	if ( slavedma & 0x30)	dma_new |= 0x40;
 	if (dma_new != dma_old)
-		hwif->OUTB(dma_new, dmabase + 2);
+		outb(dma_new, dmabase + 2);
 
 	local_irq_restore(flags);
 
 	ide_setup_dma(hwif, dmabase, 8);
 }
 
-static int __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2)
 {
-	struct pci_dev *dev2;
-
-	if (PCI_FUNC(dev->devfn) & 1)
-		return -ENODEV;
-
-	pci_set_drvdata(dev, &hpt374);
-
-	if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) {
-		int ret;
-
-		pci_set_drvdata(dev2, &hpt374);
-
-		if (dev2->irq != dev->irq) {
-			/* FIXME: we need a core pci_set_interrupt() */
-			dev2->irq = dev->irq;
-			printk(KERN_WARNING "%s: PCI config space interrupt "
-			       "fixed.\n", d->name);
-		}
-		ret = ide_setup_pci_devices(dev, dev2, d);
-		if (ret < 0)
-			pci_dev_put(dev2);
-		return ret;
+	if (dev2->irq != dev->irq) {
+		/* FIXME: we need a core pci_set_interrupt() */
+		dev2->irq = dev->irq;
+		printk(KERN_INFO "HPT374: PCI config space interrupt fixed\n");
 	}
-	return ide_setup_pci_device(dev, d);
 }
 
-static int __devinit init_setup_hpt372n(struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit hpt371_init(struct pci_dev *dev)
 {
-	pci_set_drvdata(dev, &hpt372n);
-
-	return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d)
-{
-	struct hpt_info *info;
 	u8 mcr1 = 0;
 
-	if (dev->revision > 1) {
-		d->name = "HPT371N";
-
-		info = &hpt371n;
-	} else
-		info = &hpt371;
-
 	/*
 	 * HPT371 chips physically have only one channel, the secondary one,
 	 * but the primary channel registers do exist!  Go figure...
@@ -1428,194 +1399,102 @@
 	pci_read_config_byte(dev, 0x50, &mcr1);
 	if (mcr1 & 0x04)
 		pci_write_config_byte(dev, 0x50, mcr1 & ~0x04);
-
-	pci_set_drvdata(dev, info);
-
-	return ide_setup_pci_device(dev, d);
 }
 
-static int __devinit init_setup_hpt372a(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
 {
-	struct hpt_info *info;
+	u8 mcr1 = 0, pin1 = 0, pin2 = 0;
 
-	if (dev->revision > 1) {
-		d->name = "HPT372N";
+	/*
+	 * Now we'll have to force both channels enabled if
+	 * at least one of them has been enabled by BIOS...
+	 */
+	pci_read_config_byte(dev, 0x50, &mcr1);
+	if (mcr1 & 0x30)
+		pci_write_config_byte(dev, 0x50, mcr1 | 0x30);
 
-		info = &hpt372n;
-	} else
-		info = &hpt372a;
-	pci_set_drvdata(dev, info);
+	pci_read_config_byte(dev,  PCI_INTERRUPT_PIN, &pin1);
+	pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);
 
-	return ide_setup_pci_device(dev, d);
+	if (pin1 != pin2 && dev->irq == dev2->irq) {
+		printk(KERN_INFO "HPT36x: onboard version of chipset, "
+				 "pin1=%d pin2=%d\n", pin1, pin2);
+		return 1;
+	}
+
+	return 0;
 }
 
-static int __devinit init_setup_hpt302(struct pci_dev *dev, ide_pci_device_t *d)
-{
-	struct hpt_info *info;
-
-	if (dev->revision > 1) {
-		d->name = "HPT302N";
-
-		info = &hpt302n;
-	} else
-		info = &hpt302;
-	pci_set_drvdata(dev, info);
-
-	return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
-{
-	struct pci_dev *dev2;
-	u8 rev = dev->revision;
-	static char   *chipset_names[] = { "HPT366", "HPT366",  "HPT368",
-					   "HPT370", "HPT370A", "HPT372",
-					   "HPT372N" };
-	static struct hpt_info *info[] = { &hpt36x,  &hpt36x,  &hpt36x,
-					   &hpt370,  &hpt370a, &hpt372,
-					   &hpt372n  };
-
-	if (PCI_FUNC(dev->devfn) & 1)
-		return -ENODEV;
-
-	switch (rev) {
-	case 0:
-	case 1:
-	case 2:
+static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
+	{	/* 0 */
+		.name		= "HPT36x",
+		.init_chipset	= init_chipset_hpt366,
+		.init_hwif	= init_hwif_hpt366,
+		.init_dma	= init_dma_hpt366,
 		/*
 		 * HPT36x chips have one channel per function and have
 		 * both channel enable bits located differently and visible
 		 * to both functions -- really stupid design decision... :-(
 		 * Bit 4 is for the primary channel, bit 5 for the secondary.
 		 */
-		d->host_flags |= IDE_HFLAG_SINGLE;
-		d->enablebits[0].mask = d->enablebits[0].val = 0x10;
-
-		d->udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ?
-			       ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2;
-		break;
-	case 3:
-	case 4:
-		d->udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4;
-		break;
-	default:
-		rev = 6;
-		/* fall thru */
-	case 5:
-	case 6:
-		d->udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5;
-		break;
-	}
-
-	d->name = chipset_names[rev];
-
-	pci_set_drvdata(dev, info[rev]);
-
-	if (rev > 2)
-		goto init_single;
-
-	if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) {
-		u8  mcr1 = 0, pin1 = 0, pin2 = 0;
-		int ret;
-
-		pci_set_drvdata(dev2, info[rev]);
-
-		/*
-		 * Now we'll have to force both channels enabled if
-		 * at least one of them has been enabled by BIOS...
-		 */
-		pci_read_config_byte(dev, 0x50, &mcr1);
-		if (mcr1 & 0x30)
-			pci_write_config_byte(dev, 0x50, mcr1 | 0x30);
-
-		pci_read_config_byte(dev,  PCI_INTERRUPT_PIN, &pin1);
-		pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);
-		if (pin1 != pin2 && dev->irq == dev2->irq) {
-			d->bootable = ON_BOARD;
-			printk("%s: onboard version of chipset, pin1=%d pin2=%d\n",
-			       d->name, pin1, pin2);
-		}
-		ret = ide_setup_pci_devices(dev, dev2, d);
-		if (ret < 0)
-			pci_dev_put(dev2);
-		return ret;
-	}
-init_single:
-	return ide_setup_pci_device(dev, d);
-}
-
-static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "HPT366",
-		.init_setup	= init_setup_hpt366,
-		.init_chipset	= init_chipset_hpt366,
-		.init_hwif	= init_hwif_hpt366,
-		.init_dma	= init_dma_hpt366,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
-		.bootable	= OFF_BOARD,
+		.enablebits	= {{0x50,0x10,0x10}, {0x54,0x04,0x04}},
 		.extra		= 240,
+		.host_flags	= IDE_HFLAG_SINGLE |
+				  IDE_HFLAG_NO_ATAPI_DMA |
+				  IDE_HFLAG_OFF_BOARD,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 	},{	/* 1 */
 		.name		= "HPT372A",
-		.init_setup	= init_setup_hpt372a,
 		.init_chipset	= init_chipset_hpt366,
 		.init_hwif	= init_hwif_hpt366,
 		.init_dma	= init_dma_hpt366,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
-		.udma_mask	= HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
-		.bootable	= OFF_BOARD,
 		.extra		= 240,
+		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 	},{	/* 2 */
 		.name		= "HPT302",
-		.init_setup	= init_setup_hpt302,
 		.init_chipset	= init_chipset_hpt366,
 		.init_hwif	= init_hwif_hpt366,
 		.init_dma	= init_dma_hpt366,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
-		.udma_mask	= HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
-		.bootable	= OFF_BOARD,
 		.extra		= 240,
+		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 	},{	/* 3 */
 		.name		= "HPT371",
-		.init_setup	= init_setup_hpt371,
 		.init_chipset	= init_chipset_hpt366,
 		.init_hwif	= init_hwif_hpt366,
 		.init_dma	= init_dma_hpt366,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
-		.udma_mask	= HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
-		.bootable	= OFF_BOARD,
 		.extra		= 240,
+		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 	},{	/* 4 */
 		.name		= "HPT374",
-		.init_setup	= init_setup_hpt374,
 		.init_chipset	= init_chipset_hpt366,
 		.init_hwif	= init_hwif_hpt366,
 		.init_dma	= init_dma_hpt366,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
 		.udma_mask	= ATA_UDMA5,
-		.bootable	= OFF_BOARD,
 		.extra		= 240,
+		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 	},{	/* 5 */
 		.name		= "HPT372N",
-		.init_setup	= init_setup_hpt372n,
 		.init_chipset	= init_chipset_hpt366,
 		.init_hwif	= init_hwif_hpt366,
 		.init_dma	= init_dma_hpt366,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
-		.udma_mask	= HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
-		.bootable	= OFF_BOARD,
 		.extra		= 240,
+		.host_flags	= IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
 	}
 };
 
@@ -1626,16 +1505,77 @@
  *
  *	Called when the PCI registration layer (or the IDE initialization)
  *	finds a device matching our IDE device tables.
- *
- *	NOTE: since we'll have to modify some fields of the ide_pci_device_t
- *	structure depending on the chip's revision, we'd better pass a local
- *	copy down the call chain...
  */
 static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_pci_device_t d = hpt366_chipsets[id->driver_data];
+	struct hpt_info *info = NULL;
+	struct pci_dev *dev2 = NULL;
+	struct ide_port_info d;
+	u8 idx = id->driver_data;
+	u8 rev = dev->revision;
 
-	return d.init_setup(dev, &d);
+	if ((idx == 0 || idx == 4) && (PCI_FUNC(dev->devfn) & 1))
+		return -ENODEV;
+
+	switch (idx) {
+	case 0:
+		if (rev < 3)
+			info = &hpt36x;
+		else {
+			static struct hpt_info *hpt37x_info[] =
+				{ &hpt370, &hpt370a, &hpt372, &hpt372n };
+
+			info = hpt37x_info[min_t(u8, rev, 6) - 3];
+			idx++;
+		}
+		break;
+	case 1:
+		info = (rev > 1) ? &hpt372n : &hpt372a;
+		break;
+	case 2:
+		info = (rev > 1) ? &hpt302n : &hpt302;
+		break;
+	case 3:
+		hpt371_init(dev);
+		info = (rev > 1) ? &hpt371n : &hpt371;
+		break;
+	case 4:
+		info = &hpt374;
+		break;
+	case 5:
+		info = &hpt372n;
+		break;
+	}
+
+	d = hpt366_chipsets[idx];
+
+	d.name = info->chip_name;
+	d.udma_mask = info->udma_mask;
+
+	pci_set_drvdata(dev, info);
+
+	if (info == &hpt36x || info == &hpt374)
+		dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
+
+	if (dev2) {
+		int ret;
+
+		pci_set_drvdata(dev2, info);
+
+		if (info == &hpt374)
+			hpt374_init(dev, dev2);
+		else {
+			if (hpt36x_init(dev, dev2))
+				d.host_flags |= IDE_HFLAG_BOOTABLE;
+		}
+
+		ret = ide_setup_pci_devices(dev, dev2, &d);
+		if (ret < 0)
+			pci_dev_put(dev2);
+		return ret;
+	}
+
+	return ide_setup_pci_device(dev, &d);
 }
 
 static const struct pci_device_id hpt366_pci_tbl[] = {
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index 24a71d0..90b52ed 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -170,17 +170,9 @@
 	hwif->set_dma_mode = &it8213_set_dma_mode;
 	hwif->set_pio_mode = &it8213_set_pio_mode;
 
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-
 	if (!hwif->dma_base)
 		return;
 
-	hwif->atapi_dma = 1;
-	hwif->ultra_mask = 0x7f;
-	hwif->mwdma_mask = 0x06;
-	hwif->swdma_mask = 0x04;
-
 	pci_read_config_byte(hwif->pci_dev, 0x42, &reg42h);
 
 	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
@@ -192,14 +184,16 @@
 	{						\
 		.name		= name_str,		\
 		.init_hwif	= init_hwif_it8213,	\
-		.autodma	= AUTODMA,		\
 		.enablebits	= {{0x41,0x80,0x80}}, \
-		.bootable	= ON_BOARD,		\
-		.host_flags	= IDE_HFLAG_SINGLE,	\
+		.host_flags	= IDE_HFLAG_SINGLE |	\
+				  IDE_HFLAG_BOOTABLE,	\
 		.pio_mask	= ATA_PIO4,		\
+		.swdma_mask	= ATA_SWDMA2_ONLY,	\
+		.mwdma_mask	= ATA_MWDMA12_ONLY,	\
+		.udma_mask	= ATA_UDMA6,		\
 	}
 
-static ide_pci_device_t it8213_chipsets[] __devinitdata = {
+static const struct ide_port_info it8213_chipsets[] __devinitdata = {
 	/* 0 */ DECLARE_ITE_DEV("IT8213"),
 };
 
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index f3391a8..5c99754 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -95,7 +95,7 @@
 
 /*
  *	We allow users to force the card into non raid mode without
- *	flashing the alternative BIOS. This is also neccessary right now
+ *	flashing the alternative BIOS. This is also necessary right now
  *	for embedded platforms that cannot run a PC BIOS but are using this
  *	device.
  */
@@ -544,12 +544,10 @@
 
 	ide_set_hwifdata(hwif, idev);
 
-	hwif->atapi_dma = 1;
-
 	pci_read_config_byte(hwif->pci_dev, 0x50, &conf);
-	if(conf & 1) {
+	if (conf & 1) {
 		idev->smart = 1;
-		hwif->atapi_dma = 0;
+		hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
 		/* Long I/O's although allowed in LBA48 space cause the
 		   onboard firmware to enter the twighlight zone */
 		hwif->rqsize = 256;
@@ -566,14 +564,14 @@
 
 	/*
 	 *	Not in the docs but according to the reference driver
-	 *	this is neccessary.
+	 *	this is necessary.
 	 */
 
 	pci_read_config_byte(hwif->pci_dev, 0x08, &conf);
-	if(conf == 0x10) {
+	if (conf == 0x10) {
 		idev->timing10 = 1;
-		hwif->atapi_dma = 0;
-		if(!idev->smart)
+		hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
+		if (idev->smart == 0)
 			printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n");
 	}
 
@@ -587,14 +585,11 @@
 	} else
 		hwif->host_flags |= IDE_HFLAG_NO_SET_MODE;
 
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->ultra_mask = 0x7f;
-	hwif->mwdma_mask = 0x07;
+	hwif->ultra_mask = ATA_UDMA6;
+	hwif->mwdma_mask = ATA_MWDMA2;
 
 	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
 		hwif->cbl = ata66_it821x(hwif);
@@ -638,13 +633,12 @@
 		.name		= name_str,		\
 		.init_chipset	= init_chipset_it821x,	\
 		.init_hwif	= init_hwif_it821x,	\
-		.autodma	= AUTODMA,		\
-		.bootable	= ON_BOARD,		\
 		.fixup	 	= it821x_fixups,	\
+		.host_flags	= IDE_HFLAG_BOOTABLE,	\
 		.pio_mask	= ATA_PIO4,		\
 	}
 
-static ide_pci_device_t it821x_chipsets[] __devinitdata = {
+static const struct ide_port_info it821x_chipsets[] __devinitdata = {
 	/* 0 */ DECLARE_ITE_DEV("IT8212"),
 };
 
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
index bb893ff..bdf64d9 100644
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -111,27 +111,21 @@
 	hwif->set_pio_mode = &jmicron_set_pio_mode;
 	hwif->set_dma_mode = &jmicron_set_dma_mode;
 
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->atapi_dma = 1;
-	hwif->ultra_mask = 0x7f;
-	hwif->mwdma_mask = 0x07;
-
 	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
 		hwif->cbl = ata66_jmicron(hwif);
 }
 
-static ide_pci_device_t jmicron_chipset __devinitdata = {
+static const struct ide_port_info jmicron_chipset __devinitdata = {
 	.name		= "JMB",
 	.init_hwif	= init_hwif_jmicron,
-	.autodma	= AUTODMA,
-	.bootable	= ON_BOARD,
+	.host_flags	= IDE_HFLAG_BOOTABLE,
 	.enablebits	= { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } },
 	.pio_mask	= ATA_PIO5,
+	.mwdma_mask	= ATA_MWDMA2,
+	.udma_mask	= ATA_UDMA6,
 };
 
 /**
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index a8cd50a..d4df464 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -260,15 +260,15 @@
 	hwif->ide_dma_end = &ns87415_ide_dma_end;
 }
 
-static ide_pci_device_t ns87415_chipset __devinitdata = {
+static const struct ide_port_info ns87415_chipset __devinitdata = {
 	.name		= "NS87415",
 #ifdef CONFIG_SUPERIO
 	.init_iops	= init_iops_ns87415,
 #endif
 	.init_hwif	= init_hwif_ns87415,
-	.autodma	= AUTODMA,
-	.bootable	= ON_BOARD,
-	.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
+	.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+			  IDE_HFLAG_NO_ATAPI_DMA |
+			  IDE_HFLAG_BOOTABLE,
 };
 
 static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index 250662e..8953d9c 100644
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pci/opti621.c		Version 0.7	Sept 10, 2002
+ *  linux/drivers/ide/pci/opti621.c		Version 0.9	Sep 24, 2007
  *
  *  Copyright (C) 1996-1998  Linus Torvalds & authors (see below)
  */
@@ -57,9 +57,6 @@
  * There is a 25/33MHz switch in configuration
  * register, but driver is written for use at any frequency which get
  * (use idebus=xx to select PCI bus speed).
- * Use hda=autotune and hdb=autotune for automatical tune of the PIO modes.
- * If you get strange results, do not use this and set PIO manually
- * by hdparm.
  *
  * Version 0.1, Nov 8, 1996
  * by Jaromir Koutek, for 2.1.8. 
@@ -136,6 +133,8 @@
 #define PIO_NOT_EXIST 254
 #define PIO_DONT_KNOW 255
 
+static DEFINE_SPINLOCK(opti621_lock);
+
 /* there are stored pio numbers from other calls of opti621_set_pio_mode */
 static void compute_pios(ide_drive_t *drive, const u8 pio)
 /* Store values into drive->drive_data
@@ -281,7 +280,7 @@
 		second.recovery_time, drdy);
 #endif
 
-	spin_lock_irqsave(&ide_lock, flags);
+	spin_lock_irqsave(&opti621_lock, flags);
 
      	reg_base = hwif->io_ports[IDE_DATA_OFFSET];
 
@@ -320,7 +319,7 @@
 	/*  and read prefetch for both drives */
 	write_reg(misc, MISC_REG);
 
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irqrestore(&opti621_lock, flags);
 }
 
 /*
@@ -332,32 +331,27 @@
 	hwif->drives[1].drive_data = PIO_DONT_KNOW;
 
 	hwif->set_pio_mode = &opti621_set_pio_mode;
-
-	if (!(hwif->dma_base))
-		return;
-
-	hwif->atapi_dma = 1;
-	hwif->mwdma_mask = 0x07;
-	hwif->swdma_mask = 0x07;
 }
 
-static ide_pci_device_t opti621_chipsets[] __devinitdata = {
+static const struct ide_port_info opti621_chipsets[] __devinitdata = {
 	{	/* 0 */
 		.name		= "OPTI621",
 		.init_hwif	= init_hwif_opti621,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
-		.bootable	= ON_BOARD,
+		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+				  IDE_HFLAG_BOOTABLE,
 		.pio_mask	= ATA_PIO3,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
+		.swdma_mask	= ATA_SWDMA2,
+		.mwdma_mask	= ATA_MWDMA2,
 	},{	/* 1 */
 		.name		= "OPTI621X",
 		.init_hwif	= init_hwif_opti621,
-		.autodma	= AUTODMA,
 		.enablebits	= {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
-		.bootable	= ON_BOARD,
+		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+				  IDE_HFLAG_BOOTABLE,
 		.pio_mask	= ATA_PIO3,
-		.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
+		.swdma_mask	= ATA_SWDMA2,
+		.mwdma_mask	= ATA_MWDMA2,
 	}
 };
 
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 8704b6f..4234efe 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -332,16 +332,12 @@
 static void __devinit apple_kiwi_init(struct pci_dev *pdev)
 {
 	struct device_node *np = pci_device_to_OF_node(pdev);
-	unsigned int class_rev = 0;
 	u8 conf;
 
 	if (np == NULL || !of_device_is_compatible(np, "kiwi-root"))
 		return;
 
-	pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
-	class_rev &= 0xff;
-
-	if (class_rev >= 0x03) {
+	if (pdev->revision >= 0x03) {
 		/* Setup chip magic config stuff (from darwin) */
 		pci_read_config_byte (pdev, 0x40, &conf);
 		pci_write_config_byte(pdev, 0x40, (conf | 0x01));
@@ -475,150 +471,56 @@
 	hwif->quirkproc = &pdcnew_quirkproc;
 	hwif->resetproc = &pdcnew_reset;
 
-	hwif->err_stops_fifo = 1;
-
-	hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->atapi_dma  = 1;
-
-	hwif->ultra_mask = hwif->cds->udma_mask;
-	hwif->mwdma_mask = 0x07;
-
 	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
 		hwif->cbl = pdcnew_cable_detect(hwif);
 }
 
-static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
+static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
 {
-	return ide_setup_pci_device(dev, d);
-}
+	struct pci_dev *dev2;
 
-static int __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d)
-{
-	struct pci_dev *bridge = dev->bus->self;
+	dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 2,
+						PCI_FUNC(dev->devfn)));
+	if (dev2 &&
+	    dev2->vendor == dev->vendor &&
+	    dev2->device == dev->device) {
 
-	if (bridge != NULL &&
-	    bridge->vendor == PCI_VENDOR_ID_DEC &&
-	    bridge->device == PCI_DEVICE_ID_DEC_21150) {
-		struct pci_dev *dev2;
-
-		if (PCI_SLOT(dev->devfn) & 2)
-			return -ENODEV;
-
-		dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 2,
-							PCI_FUNC(dev->devfn)));
-		if (dev2 != NULL &&
-		    dev2->vendor == dev->vendor &&
-		    dev2->device == dev->device) {
-			int ret;
-
-			if (dev2->irq != dev->irq) {
-				dev2->irq = dev->irq;
-
-				printk(KERN_WARNING "%s: PCI config space "
-				       "interrupt fixed.\n", d->name);
-			}
-
-			ret = ide_setup_pci_devices(dev, dev2, d);
-			if (ret < 0)
-				pci_dev_put(dev2);
-			return ret;
+		if (dev2->irq != dev->irq) {
+			dev2->irq = dev->irq;
+			printk(KERN_INFO "PDC20270: PCI config space "
+					 "interrupt fixed\n");
 		}
+
+		return dev2;
 	}
-	return ide_setup_pci_device(dev, d);
+
+	return NULL;
 }
 
-static int __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d)
-{
-	struct pci_dev *bridge = dev->bus->self;
-
-	if (bridge != NULL &&
-	    bridge->vendor == PCI_VENDOR_ID_INTEL &&
-	   (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
-	    bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
-
-		printk(KERN_INFO "%s: attached to I2O RAID controller, "
-				 "skipping.\n", d->name);
-		return -ENODEV;
+#define DECLARE_PDCNEW_DEV(name_str, udma) \
+	{ \
+		.name		= name_str, \
+		.init_chipset	= init_chipset_pdcnew, \
+		.init_hwif	= init_hwif_pdc202new, \
+		.host_flags	= IDE_HFLAG_POST_SET_MODE | \
+				  IDE_HFLAG_ERROR_STOPS_FIFO | \
+				  IDE_HFLAG_OFF_BOARD, \
+		.pio_mask	= ATA_PIO4, \
+		.mwdma_mask	= ATA_MWDMA2, \
+		.udma_mask	= udma, \
 	}
-	return ide_setup_pci_device(dev, d);
-}
 
-static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "PDC20268",
-		.init_setup	= init_setup_pdcnew,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x3f, /* udma0-5 */
-		.host_flags	= IDE_HFLAG_POST_SET_MODE,
-	},{	/* 1 */
-		.name		= "PDC20269",
-		.init_setup	= init_setup_pdcnew,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x7f, /* udma0-6*/
-		.host_flags	= IDE_HFLAG_POST_SET_MODE,
-	},{	/* 2 */
-		.name		= "PDC20270",
-		.init_setup	= init_setup_pdc20270,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x3f, /* udma0-5 */
-		.host_flags	= IDE_HFLAG_POST_SET_MODE,
-	},{	/* 3 */
-		.name		= "PDC20271",
-		.init_setup	= init_setup_pdcnew,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x7f, /* udma0-6*/
-		.host_flags	= IDE_HFLAG_POST_SET_MODE,
-	},{	/* 4 */
-		.name		= "PDC20275",
-		.init_setup	= init_setup_pdcnew,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x7f, /* udma0-6*/
-		.host_flags	= IDE_HFLAG_POST_SET_MODE,
-	},{	/* 5 */
-		.name		= "PDC20276",
-		.init_setup	= init_setup_pdc20276,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x7f, /* udma0-6*/
-		.host_flags	= IDE_HFLAG_POST_SET_MODE,
-	},{	/* 6 */
-		.name		= "PDC20277",
-		.init_setup	= init_setup_pdcnew,
-		.init_chipset	= init_chipset_pdcnew,
-		.init_hwif	= init_hwif_pdc202new,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x7f, /* udma0-6*/
-		.host_flags	= IDE_HFLAG_POST_SET_MODE,
-	}
+static const struct ide_port_info pdcnew_chipsets[] __devinitdata = {
+	/* 0 */ DECLARE_PDCNEW_DEV("PDC20268", ATA_UDMA5),
+	/* 1 */ DECLARE_PDCNEW_DEV("PDC20269", ATA_UDMA6),
+	/* 2 */ DECLARE_PDCNEW_DEV("PDC20270", ATA_UDMA5),
+	/* 3 */ DECLARE_PDCNEW_DEV("PDC20271", ATA_UDMA6),
+	/* 4 */ DECLARE_PDCNEW_DEV("PDC20275", ATA_UDMA6),
+	/* 5 */ DECLARE_PDCNEW_DEV("PDC20276", ATA_UDMA6),
+	/* 6 */ DECLARE_PDCNEW_DEV("PDC20277", ATA_UDMA6),
 };
 
 /**
@@ -632,9 +534,40 @@
  
 static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_pci_device_t *d = &pdcnew_chipsets[id->driver_data];
+	const struct ide_port_info *d;
+	struct pci_dev *bridge = dev->bus->self;
+	u8 idx = id->driver_data;
 
-	return d->init_setup(dev, d);
+	d = &pdcnew_chipsets[idx];
+
+	if (idx == 2 && bridge &&
+	    bridge->vendor == PCI_VENDOR_ID_DEC &&
+	    bridge->device == PCI_DEVICE_ID_DEC_21150) {
+		struct pci_dev *dev2;
+
+		if (PCI_SLOT(dev->devfn) & 2)
+			return -ENODEV;
+
+		dev2 = pdc20270_get_dev2(dev);
+
+		if (dev2) {
+			int ret = ide_setup_pci_devices(dev, dev2, d);
+			if (ret < 0)
+				pci_dev_put(dev2);
+			return ret;
+		}
+	}
+
+	if (idx == 5 && bridge &&
+	    bridge->vendor == PCI_VENDOR_ID_INTEL &&
+	    (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
+	     bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
+		printk(KERN_INFO "PDC20276: attached to I2O RAID controller, "
+				 "skipping\n");
+		return -ENODEV;
+	}
+
+	return ide_setup_pci_device(dev, d);
 }
 
 static const struct pci_device_id pdc202new_pci_tbl[] = {
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index e1d2337..e09742e 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pci/pdc202xx_old.c	Version 0.51	Jul 27, 2007
+ *  linux/drivers/ide/pci/pdc202xx_old.c	Version 0.52	Aug 27, 2007
  *
  *  Copyright (C) 1998-2002		Andre Hedrick <andre@linux-ide.org>
  *  Copyright (C) 2006-2007		MontaVista Software, Inc.
@@ -97,9 +97,6 @@
 		case XFER_MW_DMA_2:	TB = 0x60; TC = 0x03; break;
 		case XFER_MW_DMA_1:	TB = 0x60; TC = 0x04; break;
 		case XFER_MW_DMA_0:	TB = 0xE0; TC = 0x0F; break;
-		case XFER_SW_DMA_2:	TB = 0x60; TC = 0x05; break;
-		case XFER_SW_DMA_1:	TB = 0x80; TC = 0x06; break;
-		case XFER_SW_DMA_0:	TB = 0xC0; TC = 0x0B; break;
 		case XFER_PIO_4:	TA = 0x01; TB = 0x04; break;
 		case XFER_PIO_3:	TA = 0x02; TB = 0x06; break;
 		case XFER_PIO_2:	TA = 0x03; TB = 0x08; break;
@@ -305,13 +302,6 @@
 
 static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
 {
-	struct pci_dev *dev = hwif->pci_dev;
-
-	/* PDC20265 has problems with large LBA48 requests */
-	if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) ||
-	    (dev->device == PCI_DEVICE_ID_PROMISE_20265))
-		hwif->rqsize = 256;
-
 	hwif->set_pio_mode = &pdc202xx_set_pio_mode;
 	hwif->set_dma_mode = &pdc202xx_set_mode;
 
@@ -320,18 +310,9 @@
 	if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246)
 		hwif->resetproc = &pdc202xx_reset;
 
-	hwif->err_stops_fifo = 1;
-
-	hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->ultra_mask = hwif->cds->udma_mask;
-	hwif->mwdma_mask = 0x07;
-	hwif->swdma_mask = 0x07;
-	hwif->atapi_dma = 1;
-
 	hwif->dma_lost_irq = &pdc202xx_dma_lost_irq;
 	hwif->dma_timeout = &pdc202xx_dma_timeout;
 
@@ -377,8 +358,8 @@
 	ide_setup_dma(hwif, dmabase, 8);
 }
 
-static int __devinit init_setup_pdc202ata4(struct pci_dev *dev,
-					   ide_pci_device_t *d)
+static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
+					   const char *name)
 {
 	if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {
 		u8 irq = 0, irq2 = 0;
@@ -388,90 +369,45 @@
 		if (irq != irq2) {
 			pci_write_config_byte(dev,
 				(PCI_INTERRUPT_LINE)|0x80, irq);     /* 0xbc */
-			printk(KERN_INFO "%s: pci-config space interrupt "
-				"mirror fixed.\n", d->name);
+			printk(KERN_INFO "%s: PCI config space interrupt "
+					 "mirror fixed\n", name);
 		}
 	}
-	return ide_setup_pci_device(dev, d);
 }
 
-static int __devinit init_setup_pdc20265(struct pci_dev *dev,
-					 ide_pci_device_t *d)
-{
-	if ((dev->bus->self) &&
-	    (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) &&
-	    ((dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) ||
-	     (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) {
-		printk(KERN_INFO "ide: Skipping Promise PDC20265 "
-			"attached to I2O RAID controller.\n");
-		return -ENODEV;
+#define DECLARE_PDC2026X_DEV(name_str, udma, extra_flags) \
+	{ \
+		.name		= name_str, \
+		.init_chipset	= init_chipset_pdc202xx, \
+		.init_hwif	= init_hwif_pdc202xx, \
+		.init_dma	= init_dma_pdc202xx, \
+		.extra		= 48, \
+		.host_flags	= IDE_HFLAG_ERROR_STOPS_FIFO | \
+				  extra_flags | \
+				  IDE_HFLAG_OFF_BOARD, \
+		.pio_mask	= ATA_PIO4, \
+		.mwdma_mask	= ATA_MWDMA2, \
+		.udma_mask	= udma, \
 	}
-	return ide_setup_pci_device(dev, d);
-}
 
-static int __devinit init_setup_pdc202xx(struct pci_dev *dev,
-					 ide_pci_device_t *d)
-{
-	return ide_setup_pci_device(dev, d);
-}
-
-static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
+static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = {
 	{	/* 0 */
 		.name		= "PDC20246",
-		.init_setup	= init_setup_pdc202ata4,
 		.init_chipset	= init_chipset_pdc202xx,
 		.init_hwif	= init_hwif_pdc202xx,
 		.init_dma	= init_dma_pdc202xx,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
 		.extra		= 16,
+		.host_flags	= IDE_HFLAG_ERROR_STOPS_FIFO |
+				  IDE_HFLAG_OFF_BOARD,
 		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x07, /* udma0-2 */
-	},{	/* 1 */
-		.name		= "PDC20262",
-		.init_setup	= init_setup_pdc202ata4,
-		.init_chipset	= init_chipset_pdc202xx,
-		.init_hwif	= init_hwif_pdc202xx,
-		.init_dma	= init_dma_pdc202xx,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.extra		= 48,
-		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x1f, /* udma0-4 */
-	},{	/* 2 */
-		.name		= "PDC20263",
-		.init_setup	= init_setup_pdc202ata4,
-		.init_chipset	= init_chipset_pdc202xx,
-		.init_hwif	= init_hwif_pdc202xx,
-		.init_dma	= init_dma_pdc202xx,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.extra		= 48,
-		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x1f, /* udma0-4 */
-	},{	/* 3 */
-		.name		= "PDC20265",
-		.init_setup	= init_setup_pdc20265,
-		.init_chipset	= init_chipset_pdc202xx,
-		.init_hwif	= init_hwif_pdc202xx,
-		.init_dma	= init_dma_pdc202xx,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.extra		= 48,
-		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x3f, /* udma0-5 */
-	},{	/* 4 */
-		.name		= "PDC20267",
-		.init_setup	= init_setup_pdc202xx,
-		.init_chipset	= init_chipset_pdc202xx,
-		.init_hwif	= init_hwif_pdc202xx,
-		.init_dma	= init_dma_pdc202xx,
-		.autodma	= AUTODMA,
-		.bootable	= OFF_BOARD,
-		.extra		= 48,
-		.pio_mask	= ATA_PIO4,
-		.udma_mask	= 0x3f, /* udma0-5 */
-	}
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA2,
+	},
+
+	/* 1 */ DECLARE_PDC2026X_DEV("PDC20262", ATA_UDMA4, 0),
+	/* 2 */ DECLARE_PDC2026X_DEV("PDC20263", ATA_UDMA4, 0),
+	/* 3 */ DECLARE_PDC2026X_DEV("PDC20265", ATA_UDMA5, IDE_HFLAG_RQSIZE_256),
+	/* 4 */ DECLARE_PDC2026X_DEV("PDC20267", ATA_UDMA5, IDE_HFLAG_RQSIZE_256),
 };
 
 /**
@@ -485,9 +421,28 @@
  
 static int __devinit pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_pci_device_t *d = &pdc202xx_chipsets[id->driver_data];
+	const struct ide_port_info *d;
+	u8 idx = id->driver_data;
 
-	return d->init_setup(dev, d);
+	d = &pdc202xx_chipsets[idx];
+
+	if (idx < 3)
+		pdc202ata4_fixup_irq(dev, d->name);
+
+	if (idx == 3) {
+		struct pci_dev *bridge = dev->bus->self;
+
+		if (bridge &&
+		    bridge->vendor == PCI_VENDOR_ID_INTEL &&
+		    (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
+		     bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
+			printk(KERN_INFO "ide: Skipping Promise PDC20265 "
+				"attached to I2O RAID controller\n");
+			return -ENODEV;
+		}
+	}
+
+	return ide_setup_pci_device(dev, d);
 }
 
 static const struct pci_device_id pdc202xx_pci_tbl[] = {
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index a8dd0c0..9329d4a 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pci/piix.c	Version 0.53	Aug 9, 2007
+ *  linux/drivers/ide/pci/piix.c	Version 0.54	Sep 5, 2007
  *
  *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
  *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
@@ -254,53 +254,20 @@
 }
 
 /**
- *	piix_is_ichx	-	check if ICHx
- *	@dev: PCI device to check
- *
- *	returns 1 if ICHx, 0 otherwise.
- */
-static int piix_is_ichx(struct pci_dev *dev)
-{
-        switch (dev->device) {
-		case PCI_DEVICE_ID_INTEL_82801EB_1:
-		case PCI_DEVICE_ID_INTEL_82801AA_1:
-		case PCI_DEVICE_ID_INTEL_82801AB_1:
-		case PCI_DEVICE_ID_INTEL_82801BA_8:
-		case PCI_DEVICE_ID_INTEL_82801BA_9:
-		case PCI_DEVICE_ID_INTEL_82801CA_10:
-		case PCI_DEVICE_ID_INTEL_82801CA_11:
-		case PCI_DEVICE_ID_INTEL_82801DB_1:
-		case PCI_DEVICE_ID_INTEL_82801DB_10:
-		case PCI_DEVICE_ID_INTEL_82801DB_11:
-		case PCI_DEVICE_ID_INTEL_82801EB_11:
-		case PCI_DEVICE_ID_INTEL_82801E_11:
-		case PCI_DEVICE_ID_INTEL_ESB_2:
-		case PCI_DEVICE_ID_INTEL_ICH6_19:
-		case PCI_DEVICE_ID_INTEL_ICH7_21:
-		case PCI_DEVICE_ID_INTEL_ESB2_18:
-		case PCI_DEVICE_ID_INTEL_ICH8_6:
-			return 1;
-	}
-
-	return 0;
-}
-
-/**
- *	init_chipset_piix	-	set up the PIIX chipset
+ *	init_chipset_ich	-	set up the ICH chipset
  *	@dev: PCI device to set up
  *	@name: Name of the device
  *
- *	Initialize the PCI device as required. For the PIIX this turns
- *	out to be nice and simple
+ *	Initialize the PCI device as required.  For the ICH this turns
+ *	out to be nice and simple.
  */
 
-static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_ich(struct pci_dev *dev, const char *name)
 {
-	if (piix_is_ichx(dev)) {
-		unsigned int extra = 0;
-		pci_read_config_dword(dev, 0x54, &extra);
-		pci_write_config_dword(dev, 0x54, extra|0x400);
-	}
+	u32 extra = 0;
+
+	pci_read_config_dword(dev, 0x54, &extra);
+	pci_write_config_dword(dev, 0x54, extra | 0x400);
 
 	return 0;
 }
@@ -318,9 +285,9 @@
 	u8 dma_stat;
 
 	/* clear the INTR & ERROR bits */
-	dma_stat = hwif->INB(hwif->dma_status);
+	dma_stat = inb(hwif->dma_status);
 	/* Should we force the bit as well ? */
-	hwif->OUTB(dma_stat, hwif->dma_status);
+	outb(dma_stat, hwif->dma_status);
 }
 
 struct ich_laptop {
@@ -374,35 +341,12 @@
 
 static void __devinit init_hwif_piix(ide_hwif_t *hwif)
 {
-#ifndef CONFIG_IA64
-	if (!hwif->irq)
-		hwif->irq = hwif->channel ? 15 : 14;
-#endif /* CONFIG_IA64 */
-
-	if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_82371MX) {
-		/* This is a painful system best to let it self tune for now */
-		return;
-	}
-
 	hwif->set_pio_mode = &piix_set_pio_mode;
 	hwif->set_dma_mode = &piix_set_dma_mode;
 
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-
 	if (!hwif->dma_base)
 		return;
 
-	/* ICHx need to clear the bmdma status for all interrupts */
-	if (piix_is_ichx(hwif->pci_dev))
-		hwif->ide_dma_clear_irq = &piix_dma_clear_irq;
-
-	hwif->atapi_dma = 1;
-
-	hwif->ultra_mask = hwif->cds->udma_mask;
-	hwif->mwdma_mask = 0x06;
-	hwif->swdma_mask = 0x04;
-
 	if (hwif->ultra_mask & 0x78) {
 		if (hwif->cbl != ATA_CBL_PATA40_SHORT)
 			hwif->cbl = piix_cable_detect(hwif);
@@ -412,21 +356,49 @@
 		hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0;
 }
 
+static void __devinit init_hwif_ich(ide_hwif_t *hwif)
+{
+	init_hwif_piix(hwif);
+
+	/* ICHx need to clear the BMDMA status for all interrupts */
+	if (hwif->dma_base)
+		hwif->ide_dma_clear_irq = &piix_dma_clear_irq;
+}
+
+#ifndef CONFIG_IA64
+ #define IDE_HFLAGS_PIIX (IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE)
+#else
+ #define IDE_HFLAGS_PIIX IDE_HFLAG_BOOTABLE
+#endif
+
 #define DECLARE_PIIX_DEV(name_str, udma) \
 	{						\
 		.name		= name_str,		\
-		.init_chipset	= init_chipset_piix,	\
 		.init_hwif	= init_hwif_piix,	\
-		.autodma	= AUTODMA,		\
 		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
-		.bootable	= ON_BOARD,		\
+		.host_flags	= IDE_HFLAGS_PIIX,	\
 		.pio_mask	= ATA_PIO4,		\
+		.swdma_mask	= ATA_SWDMA2_ONLY,	\
+		.mwdma_mask	= ATA_MWDMA12_ONLY,	\
 		.udma_mask	= udma,			\
 	}
 
-static ide_pci_device_t piix_pci_info[] __devinitdata = {
-	/*  0 */ DECLARE_PIIX_DEV("PIIXa", 0x00),	/* no udma */
-	/*  1 */ DECLARE_PIIX_DEV("PIIXb", 0x00),	/* no udma */
+#define DECLARE_ICH_DEV(name_str, udma) \
+	{ \
+		.name		= name_str, \
+		.init_chipset	= init_chipset_ich, \
+		.init_hwif	= init_hwif_ich, \
+		.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
+		.host_flags	= IDE_HFLAGS_PIIX, \
+		.pio_mask	= ATA_PIO4, \
+		.swdma_mask	= ATA_SWDMA2_ONLY, \
+		.mwdma_mask	= ATA_MWDMA12_ONLY, \
+		.udma_mask	= udma, \
+	}
+
+static const struct ide_port_info piix_pci_info[] __devinitdata = {
+	/*  0 */ DECLARE_PIIX_DEV("PIIXa",	0x00),	/* no udma */
+	/*  1 */ DECLARE_PIIX_DEV("PIIXb",	0x00),	/* no udma */
 
 	/*  2 */
 	{	/*
@@ -435,36 +407,35 @@
 		 * of the bit 14 of the IDETIM register at offset 0x6c
 		 */
 		.name		= "MPIIX",
-		.init_hwif	= init_hwif_piix,
-		.autodma	= NODMA,
 		.enablebits	= {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}},
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_ISA_PORTS,
+		.host_flags	= IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA |
+				  IDE_HFLAGS_PIIX,
 		.pio_mask	= ATA_PIO4,
+		/* This is a painful system best to let it self tune for now */
 	},
 
-	/*  3 */ DECLARE_PIIX_DEV("PIIX3", 0x00),	/* no udma */
-	/*  4 */ DECLARE_PIIX_DEV("PIIX4", 0x07),	/* udma0-2 */
-	/*  5 */ DECLARE_PIIX_DEV("ICH0",  0x07),	/* udma0-2 */
-	/*  6 */ DECLARE_PIIX_DEV("PIIX4", 0x07),	/* udma0-2 */
-	/*  7 */ DECLARE_PIIX_DEV("ICH",   0x1f),	/* udma0-4 */
-	/*  8 */ DECLARE_PIIX_DEV("PIIX4", 0x1f),	/* udma0-4 */
-	/*  9 */ DECLARE_PIIX_DEV("PIIX4", 0x07),	/* udma0-2 */
-	/* 10 */ DECLARE_PIIX_DEV("ICH2",  0x3f),	/* udma0-5 */
-	/* 11 */ DECLARE_PIIX_DEV("ICH2M", 0x3f),	/* udma0-5 */
-	/* 12 */ DECLARE_PIIX_DEV("ICH3M", 0x3f),	/* udma0-5 */
-	/* 13 */ DECLARE_PIIX_DEV("ICH3",  0x3f),	/* udma0-5 */
-	/* 14 */ DECLARE_PIIX_DEV("ICH4",  0x3f),	/* udma0-5 */
-	/* 15 */ DECLARE_PIIX_DEV("ICH5",  0x3f),	/* udma0-5 */
-	/* 16 */ DECLARE_PIIX_DEV("C-ICH", 0x3f),	/* udma0-5 */
-	/* 17 */ DECLARE_PIIX_DEV("ICH4",  0x3f),	/* udma0-5 */
-	/* 18 */ DECLARE_PIIX_DEV("ICH5-SATA", 0x3f),	/* udma0-5 */
-	/* 19 */ DECLARE_PIIX_DEV("ICH5",  0x3f),	/* udma0-5 */
-	/* 20 */ DECLARE_PIIX_DEV("ICH6",  0x3f),	/* udma0-5 */
-	/* 21 */ DECLARE_PIIX_DEV("ICH7",  0x3f),	/* udma0-5 */
-	/* 22 */ DECLARE_PIIX_DEV("ICH4",  0x3f),	/* udma0-5 */
-	/* 23 */ DECLARE_PIIX_DEV("ESB2",  0x3f),	/* udma0-5 */
-	/* 24 */ DECLARE_PIIX_DEV("ICH8M", 0x3f),	/* udma0-5 */
+	/*  3 */ DECLARE_PIIX_DEV("PIIX3",	0x00),	/* no udma */
+	/*  4 */ DECLARE_PIIX_DEV("PIIX4",	ATA_UDMA2),
+	/*  5 */ DECLARE_ICH_DEV("ICH0",	ATA_UDMA2),
+	/*  6 */ DECLARE_PIIX_DEV("PIIX4",	ATA_UDMA2),
+	/*  7 */ DECLARE_ICH_DEV("ICH",		ATA_UDMA4),
+	/*  8 */ DECLARE_PIIX_DEV("PIIX4",	ATA_UDMA4),
+	/*  9 */ DECLARE_PIIX_DEV("PIIX4",	ATA_UDMA2),
+	/* 10 */ DECLARE_ICH_DEV("ICH2",	ATA_UDMA5),
+	/* 11 */ DECLARE_ICH_DEV("ICH2M",	ATA_UDMA5),
+	/* 12 */ DECLARE_ICH_DEV("ICH3M",	ATA_UDMA5),
+	/* 13 */ DECLARE_ICH_DEV("ICH3",	ATA_UDMA5),
+	/* 14 */ DECLARE_ICH_DEV("ICH4",	ATA_UDMA5),
+	/* 15 */ DECLARE_ICH_DEV("ICH5",	ATA_UDMA5),
+	/* 16 */ DECLARE_ICH_DEV("C-ICH",	ATA_UDMA5),
+	/* 17 */ DECLARE_ICH_DEV("ICH4",	ATA_UDMA5),
+	/* 18 */ DECLARE_ICH_DEV("ICH5-SATA",	ATA_UDMA5),
+	/* 19 */ DECLARE_ICH_DEV("ICH5",	ATA_UDMA5),
+	/* 20 */ DECLARE_ICH_DEV("ICH6",	ATA_UDMA5),
+	/* 21 */ DECLARE_ICH_DEV("ICH7",	ATA_UDMA5),
+	/* 22 */ DECLARE_ICH_DEV("ICH4",	ATA_UDMA5),
+	/* 23 */ DECLARE_ICH_DEV("ESB2",	ATA_UDMA5),
+	/* 24 */ DECLARE_ICH_DEV("ICH8M",	ATA_UDMA5),
 };
 
 /**
@@ -478,9 +449,7 @@
  
 static int __devinit piix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_pci_device_t *d = &piix_pci_info[id->driver_data];
-
-	return ide_setup_pci_device(dev, d);
+	return ide_setup_pci_device(dev, &piix_pci_info[id->driver_data]);
 }
 
 /**
diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c
index 3f506e8..6b10ae2 100644
--- a/drivers/ide/pci/rz1000.c
+++ b/drivers/ide/pci/rz1000.c
@@ -35,13 +35,13 @@
 	u16 reg;
 	struct pci_dev *dev = hwif->pci_dev;
 
-	hwif->chipset = ide_rz1000;
 	if (!pci_read_config_word (dev, 0x40, &reg) &&
 	    !pci_write_config_word(dev, 0x40, reg & 0xdfff)) {
 		printk(KERN_INFO "%s: disabled chipset read-ahead "
 			"(buggy RZ1000/RZ1001)\n", hwif->name);
 	} else {
-		hwif->serialized = 1;
+		if (hwif->mate)
+			hwif->mate->serialized = hwif->serialized = 1;
 		hwif->drives[0].no_unmask = 1;
 		hwif->drives[1].no_unmask = 1;
 		printk(KERN_INFO "%s: serialized, disabled unmasking "
@@ -49,11 +49,11 @@
 	}
 }
 
-static ide_pci_device_t rz1000_chipset __devinitdata = {
+static const struct ide_port_info rz1000_chipset __devinitdata = {
 	.name		= "RZ100x",
 	.init_hwif	= init_hwif_rz1000,
-	.autodma	= NODMA,
-	.bootable	= ON_BOARD,
+	.chipset	= ide_rz1000,
+	.host_flags	= IDE_HFLAG_NO_DMA | IDE_HFLAG_BOOTABLE,
 };
 
 static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index 54c5c98..d2c8b55 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -362,33 +362,26 @@
  */
 static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
 {
-	if (hwif->mate)
-		hwif->serialized = hwif->mate->serialized = 1;
-
 	hwif->set_pio_mode = &sc1200_set_pio_mode;
 	hwif->set_dma_mode = &sc1200_set_dma_mode;
 
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-
 	if (hwif->dma_base == 0)
 		return;
 
 	hwif->udma_filter = sc1200_udma_filter;
 	hwif->ide_dma_end   = &sc1200_ide_dma_end;
-
-        hwif->atapi_dma = 1;
-        hwif->ultra_mask = 0x07;
-        hwif->mwdma_mask = 0x07;
 }
 
-static ide_pci_device_t sc1200_chipset __devinitdata = {
+static const struct ide_port_info sc1200_chipset __devinitdata = {
 	.name		= "SC1200",
 	.init_hwif	= init_hwif_sc1200,
-	.autodma	= AUTODMA,
-	.bootable	= ON_BOARD,
-	.host_flags	= IDE_HFLAG_ABUSE_DMA_MODES | IDE_HFLAG_POST_SET_MODE,
+	.host_flags	= IDE_HFLAG_SERIALIZE |
+			  IDE_HFLAG_POST_SET_MODE |
+			  IDE_HFLAG_ABUSE_DMA_MODES |
+			  IDE_HFLAG_BOOTABLE,
 	.pio_mask	= ATA_PIO4,
+	.mwdma_mask	= ATA_MWDMA2,
+	.udma_mask	= ATA_UDMA2,
 };
 
 static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index bd4c1d3..ebb7132 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -472,7 +472,7 @@
 	if ((drive->media != ide_disk) && (mask & 0xE0)) {
 		printk(KERN_INFO "%s: limit %s to UDMA4\n",
 		       SCC_PATA_NAME, drive->name);
-		mask = 0x1F;
+		mask = ATA_UDMA4;
 	}
 
 	return mask;
@@ -538,12 +538,13 @@
 /**
  *	init_setup_scc	-	set up an SCC PATA Controller
  *	@dev: PCI device
- *	@d: IDE PCI device
+ *	@d: IDE port info
  *
  *	Perform the initial set up for this device.
  */
 
-static int __devinit init_setup_scc(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_scc(struct pci_dev *dev,
+				    const struct ide_port_info *d)
 {
 	unsigned long ctl_base;
 	unsigned long dma_base;
@@ -683,17 +684,10 @@
 	hwif->ide_dma_test_irq = scc_dma_test_irq;
 	hwif->udma_filter = scc_udma_filter;
 
-	hwif->drives[0].autotune = IDE_TUNE_AUTO;
-	hwif->drives[1].autotune = IDE_TUNE_AUTO;
-
-	if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) {
-		hwif->ultra_mask = 0x7f; /* 133MHz */
-	} else {
-		hwif->ultra_mask = 0x3f; /* 100MHz */
-	}
-	hwif->mwdma_mask = 0x00;
-	hwif->swdma_mask = 0x00;
-	hwif->atapi_dma = 1;
+	if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN)
+		hwif->ultra_mask = ATA_UDMA6; /* 133MHz */
+	else
+		hwif->ultra_mask = ATA_UDMA5; /* 100MHz */
 
 	/* we support 80c cable only. */
 	hwif->cbl = ATA_CBL_PATA80;
@@ -702,16 +696,14 @@
 #define DECLARE_SCC_DEV(name_str)			\
   {							\
       .name		= name_str,			\
-      .init_setup	= init_setup_scc,		\
       .init_iops	= init_iops_scc,		\
       .init_hwif	= init_hwif_scc,		\
-      .autodma	= AUTODMA,				\
-      .bootable	= ON_BOARD,				\
-      .host_flags	= IDE_HFLAG_SINGLE,		\
+      .host_flags	= IDE_HFLAG_SINGLE |		\
+			  IDE_HFLAG_BOOTABLE,		\
       .pio_mask		= ATA_PIO4,			\
   }
 
-static ide_pci_device_t scc_chipsets[] __devinitdata = {
+static const struct ide_port_info scc_chipsets[] __devinitdata = {
 	/* 0 */ DECLARE_SCC_DEV("sccIDE"),
 };
 
@@ -726,8 +718,7 @@
 
 static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_pci_device_t *d = &scc_chipsets[id->driver_data];
-	return d->init_setup(dev, d);
+	return init_setup_scc(dev, &scc_chipsets[id->driver_data]);
 }
 
 /**
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index d3ffc52..a728031 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -158,13 +158,6 @@
 
 	u8 ultra_enable	 = 0, ultra_timing = 0, dma_timing = 0;
 
-	/* If we are about to put a disk into UDMA mode we screwed up.
-	   Our code assumes we never _ever_ do this on an OSB4 */
-	   
-	if(dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4 &&
-		drive->media == ide_disk && speed >= XFER_UDMA_0)
-			BUG();
-
 	pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing);
 	pci_read_config_byte(dev, 0x54, &ultra_enable);
 
@@ -360,23 +353,10 @@
 
 static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
 {
-	if (!hwif->irq)
-		hwif->irq = hwif->channel ? 15 : 14;
-
 	hwif->set_pio_mode = &svwks_set_pio_mode;
 	hwif->set_dma_mode = &svwks_set_dma_mode;
 	hwif->udma_filter = &svwks_udma_filter;
 
-	hwif->atapi_dma = 1;
-
-	if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE)
-		hwif->ultra_mask = 0x3f;
-
-	hwif->mwdma_mask = 0x07;
-
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-
 	if (!hwif->dma_base)
 		return;
 
@@ -386,72 +366,49 @@
 	}
 }
 
-static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d)
-{
-	return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d)
-{
-	if (!(PCI_FUNC(dev->devfn) & 1)) {
-		d->bootable = NEVER_BOARD;
-		if (dev->resource[0].start == 0x01f1)
-			d->bootable = ON_BOARD;
-	}
-
-	if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE ||
-	    dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) &&
-	    (!(PCI_FUNC(dev->devfn) & 1)))
-		d->host_flags |= IDE_HFLAG_SINGLE;
-	else
-		d->host_flags &= ~IDE_HFLAG_SINGLE;
-
-	return ide_setup_pci_device(dev, d);
-}
-
-static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
+static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
 	{	/* 0 */
 		.name		= "SvrWks OSB4",
-		.init_setup	= init_setup_svwks,
 		.init_chipset	= init_chipset_svwks,
 		.init_hwif	= init_hwif_svwks,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
+		.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= 0x00, /* UDMA is problematic on OSB4 */
 	},{	/* 1 */
 		.name		= "SvrWks CSB5",
-		.init_setup	= init_setup_svwks,
 		.init_chipset	= init_chipset_svwks,
 		.init_hwif	= init_hwif_svwks,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
+		.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
 	},{	/* 2 */
 		.name		= "SvrWks CSB6",
-		.init_setup	= init_setup_csb6,
 		.init_chipset	= init_chipset_svwks,
 		.init_hwif	= init_hwif_svwks,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
+		.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
 	},{	/* 3 */
 		.name		= "SvrWks CSB6",
-		.init_setup	= init_setup_csb6,
 		.init_chipset	= init_chipset_svwks,
 		.init_hwif	= init_hwif_svwks,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_SINGLE,
+		.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_SINGLE |
+				  IDE_HFLAG_BOOTABLE,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
 	},{	/* 4 */
 		.name		= "SvrWks HT1000",
-		.init_setup	= init_setup_svwks,
 		.init_chipset	= init_chipset_svwks,
 		.init_hwif	= init_hwif_svwks,
-		.autodma	= AUTODMA,
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_SINGLE,
+		.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_SINGLE |
+				  IDE_HFLAG_BOOTABLE,
 		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask	= ATA_UDMA5,
 	}
 };
 
@@ -466,9 +423,21 @@
  
 static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_pci_device_t *d = &serverworks_chipsets[id->driver_data];
+	struct ide_port_info d;
+	u8 idx = id->driver_data;
 
-	return d->init_setup(dev, d);
+	d = serverworks_chipsets[idx];
+
+	if (idx == 2 || idx == 3) {
+		if ((PCI_FUNC(dev->devfn) & 1) == 0) {
+			if (pci_resource_start(dev, 0) != 0x01f1)
+				d.host_flags &= ~IDE_HFLAG_BOOTABLE;
+			d.host_flags |= IDE_HFLAG_SINGLE;
+		} else
+			d.host_flags &= ~IDE_HFLAG_SINGLE;
+	}
+
+	return ide_setup_pci_device(dev, &d);
 }
 
 static const struct pci_device_id svwks_pci_tbl[] = {
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 9a9474f..de820aa 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -592,8 +592,7 @@
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->atapi_dma = 1;
-	hwif->mwdma_mask = 0x04;
+	hwif->mwdma_mask = ATA_MWDMA2_ONLY;
 
 	hwif->dma_setup = &sgiioc4_ide_dma_setup;
 	hwif->dma_start = &sgiioc4_ide_dma_start;
@@ -615,6 +614,7 @@
 	void __iomem *virt_base;
 	ide_hwif_t *hwif;
 	int h;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 	/*
 	 * Find an empty HWIF; if none available, return -ENOMEM.
@@ -655,10 +655,12 @@
 	}
 
 	if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) {
+		hw_regs_t hw;
+
 		/* Initialize the IO registers */
-		sgiioc4_init_hwif_ports(&hwif->hw, cmd_base, ctl, irqport);
-		memcpy(hwif->io_ports, hwif->hw.io_ports,
-		       sizeof (hwif->io_ports));
+		memset(&hw, 0, sizeof(hw));
+		sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
+		memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
 		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
 	}
 
@@ -680,11 +682,10 @@
 
 	ide_init_sgiioc4(hwif);
 
-	if (probe_hwif_init(hwif))
-		return -EIO;
+	idx[0] = hwif->index;
 
-	/* Create /proc/ide entries */
-	ide_proc_register_port(hwif);
+	if (ide_device_add(idx))
+		return -EIO;
 
 	return 0;
 }
@@ -692,14 +693,12 @@
 static unsigned int __devinit
 pci_init_sgiioc4(struct pci_dev *dev)
 {
-	unsigned int class_rev;
 	int ret;
 
-	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-	class_rev &= 0xff;
 	printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n",
-			 DRV_NAME, pci_name(dev), class_rev);
-	if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) {
+			 DRV_NAME, pci_name(dev), dev->revision);
+
+	if (dev->revision < IOC4_SUPPORTED_FIRMWARE_REV) {
 		printk(KERN_ERR "Skipping %s IDE controller in slot %s: "
 				"firmware is obsolete - please upgrade to "
 				"revision46 or higher\n",
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 85d0afd..6d99441 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/siimage.c		Version 1.16	Jul 13 2007
+ * linux/drivers/ide/pci/siimage.c		Version 1.18	Oct 18 2007
  *
  * Copyright (C) 2001-2002	Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 2003		Red Hat <alan@redhat.com>
@@ -26,7 +26,7 @@
  *
  *	If you have strange problems with nVidia chipset systems please
  *	see the SI support documentation and update your system BIOS
- *	if neccessary
+ *	if necessary
  *
  *  The Dell DRAC4 has some interesting features including effectively hot
  *  unplugging/replugging the virtual CD interface when the DRAC is reset.
@@ -57,8 +57,8 @@
  
 static int pdev_is_sata(struct pci_dev *pdev)
 {
-	switch(pdev->device)
-	{
+#ifdef CONFIG_BLK_DEV_IDE_SATA
+	switch(pdev->device) {
 		case PCI_DEVICE_ID_SII_3112:
 		case PCI_DEVICE_ID_SII_1210SA:
 			return 1;
@@ -66,9 +66,10 @@
 			return 0;
 	}
 	BUG();
+#endif
 	return 0;
 }
- 
+
 /**
  *	is_sata			-	check if hwif is SATA
  *	@hwif:	interface to check
@@ -136,7 +137,7 @@
  *	SI3112 SATA controller life is a bit simpler.
  */
 
-static u8 sil_udma_filter(ide_drive_t *drive)
+static u8 sil_pata_udma_filter(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	unsigned long base = (unsigned long) hwif->hwif_data;
@@ -147,23 +148,23 @@
 	else
 		pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
 
-	if (is_sata(hwif)) {
-		mask = strstr(drive->id->model, "Maxtor") ? 0x3f : 0x7f;
-		goto out;
-	}
-
 	if ((scsc & 0x30) == 0x10)	/* 133 */
-		mask = 0x7f;
+		mask = ATA_UDMA6;
 	else if ((scsc & 0x30) == 0x20)	/* 2xPCI */
-		mask = 0x7f;
+		mask = ATA_UDMA6;
 	else if ((scsc & 0x30) == 0x00)	/* 100 */
-		mask = 0x3f;
+		mask = ATA_UDMA5;
 	else 	/* Disabled ? */
 		BUG();
-out:
+
 	return mask;
 }
 
+static u8 sil_sata_udma_filter(ide_drive_t *drive)
+{
+	return strstr(drive->id->model, "Maxtor") ? ATA_UDMA5 : ATA_UDMA6;
+}
+
 /**
  *	sil_set_pio_mode	-	set host controller for PIO mode
  *	@drive: drive
@@ -180,7 +181,7 @@
 	const u16 data_speed[]	= { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
 
 	ide_hwif_t *hwif	= HWIF(drive);
-	ide_drive_t *pair	= &hwif->drives[drive->dn ^ 1];
+	ide_drive_t *pair	= ide_get_paired_drive(drive);
 	u32 speedt		= 0;
 	u16 speedp		= 0;
 	unsigned long addr	= siimage_seldev(drive, 0x04);
@@ -340,10 +341,11 @@
 static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
-	unsigned long base	= (unsigned long)hwif->hwif_data;
 	unsigned long addr	= siimage_selreg(hwif, 0x1);
 
 	if (SATA_ERROR_REG) {
+		unsigned long base = (unsigned long)hwif->hwif_data;
+
 		u32 ext_stat = readl((void __iomem *)(base + 0x10));
 		u8 watchdog = 0;
 		if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
@@ -376,7 +378,7 @@
 }
 
 /**
- *	siimage_busproc		-	bus isolation ioctl
+ *	sil_sata_busproc	-	bus isolation IOCTL
  *	@drive: drive to isolate/restore
  *	@state: bus state to set
  *
@@ -384,8 +386,8 @@
  *	SATA controller the work required is quite limited, we 
  *	just have to clean up the statistics
  */
- 
-static int siimage_busproc (ide_drive_t * drive, int state)
+
+static int sil_sata_busproc(ide_drive_t * drive, int state)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u32 stat_config		= 0;
@@ -417,14 +419,14 @@
 }
 
 /**
- *	siimage_reset_poll	-	wait for sata reset
+ *	sil_sata_reset_poll	-	wait for SATA reset
  *	@drive: drive we are resetting
  *
  *	Poll the SATA phy and see whether it has come back from the dead
  *	yet.
  */
- 
-static int siimage_reset_poll (ide_drive_t *drive)
+
+static int sil_sata_reset_poll(ide_drive_t *drive)
 {
 	if (SATA_STATUS_REG) {
 		ide_hwif_t *hwif	= HWIF(drive);
@@ -436,27 +438,22 @@
 			HWGROUP(drive)->polling = 0;
 			return ide_started;
 		}
-		return 0;
-	} else {
-		return 0;
 	}
+
+	return 0;
 }
 
 /**
- *	siimage_pre_reset	-	reset hook
+ *	sil_sata_pre_reset	-	reset hook
  *	@drive: IDE device being reset
  *
  *	For the SATA devices we need to handle recalibration/geometry
  *	differently
  */
- 
-static void siimage_pre_reset (ide_drive_t *drive)
-{
-	if (drive->media != ide_disk)
-		return;
 
-	if (is_sata(HWIF(drive)))
-	{
+static void sil_sata_pre_reset(ide_drive_t *drive)
+{
+	if (drive->media == ide_disk) {
 		drive->special.b.set_geometry = 0;
 		drive->special.b.recalibrate = 0;
 	}
@@ -502,7 +499,6 @@
 			drive->failures++;
 		}
 	}
-
 }
 
 /**
@@ -640,13 +636,9 @@
 
 static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const char *name)
 {
-	u32 class_rev	= 0;
-	u8 tmpbyte	= 0;
-	u8 BA5_EN	= 0;
+	u8 rev = dev->revision, tmpbyte = 0, BA5_EN = 0;
 
-        pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-        class_rev &= 0xff;
-	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255);	
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, rev ? 1 : 255);
 
 	pci_read_config_byte(dev, 0x8A, &BA5_EN);
 	if ((BA5_EN & 0x01) || (pci_resource_start(dev, 5))) {
@@ -762,16 +754,11 @@
 		hwif->sata_misc[SATA_IEN_OFFSET]	= base + 0x148;
 	}
 
-	hw.irq				= hwif->pci_dev->irq;
+	memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
 
-	memcpy(&hwif->hw, &hw, sizeof(hw));
-	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
+	hwif->irq = dev->irq;
 
-	hwif->irq			= hw.irq;
-
-       	base = (unsigned long) addr;
-
-	hwif->dma_base			= base + (ch ? 0x08 : 0x00);
+	hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00);
 
 	hwif->mmio = 1;
 }
@@ -825,19 +812,14 @@
 
 static void __devinit init_iops_siimage(ide_hwif_t *hwif)
 {
-	struct pci_dev *dev	= hwif->pci_dev;
-	u32 class_rev		= 0;
-
-	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-	class_rev &= 0xff;
-	
 	hwif->hwif_data = NULL;
 
 	/* Pessimal until we finish probing */
 	hwif->rqsize = 15;
 
-	if (pci_get_drvdata(dev) == NULL)
+	if (pci_get_drvdata(hwif->pci_dev) == NULL)
 		return;
+
 	init_mmio_iops_siimage(hwif);
 }
 
@@ -873,34 +855,32 @@
 
 static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
 {
+	u8 sata = is_sata(hwif);
+
 	hwif->resetproc = &siimage_reset;
 	hwif->set_pio_mode = &sil_set_pio_mode;
 	hwif->set_dma_mode = &sil_set_dma_mode;
-	hwif->reset_poll = &siimage_reset_poll;
-	hwif->pre_reset = &siimage_pre_reset;
-	hwif->udma_filter = &sil_udma_filter;
 
-	if(is_sata(hwif)) {
+	if (sata) {
 		static int first = 1;
 
-		hwif->busproc   = &siimage_busproc;
+		hwif->busproc = &sil_sata_busproc;
+		hwif->reset_poll = &sil_sata_reset_poll;
+		hwif->pre_reset = &sil_sata_pre_reset;
+		hwif->udma_filter = &sil_sata_udma_filter;
 
 		if (first) {
 			printk(KERN_INFO "siimage: For full SATA support you should use the libata sata_sil module.\n");
 			first = 0;
 		}
-	}
-
-	hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+	} else
+		hwif->udma_filter = &sil_pata_udma_filter;
 
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->ultra_mask = 0x7f;
-	hwif->mwdma_mask = 0x07;
-
-	if (!is_sata(hwif))
-		hwif->atapi_dma = 1;
+	if (sata)
+		hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
 
 	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
 		hwif->cbl = ata66_siimage(hwif);
@@ -919,12 +899,13 @@
 		.init_iops	= init_iops_siimage,	\
 		.init_hwif	= init_hwif_siimage,	\
 		.fixup		= siimage_fixup,	\
-		.autodma	= AUTODMA,		\
-		.bootable	= ON_BOARD,		\
+		.host_flags	= IDE_HFLAG_BOOTABLE,	\
 		.pio_mask	= ATA_PIO4,		\
+		.mwdma_mask	= ATA_MWDMA2,		\
+		.udma_mask	= ATA_UDMA6,		\
 	}
 
-static ide_pci_device_t siimage_chipsets[] __devinitdata = {
+static const struct ide_port_info siimage_chipsets[] __devinitdata = {
 	/* 0 */ DECLARE_SII_DEV("SiI680"),
 	/* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA"),
 	/* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA")
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 5a54e2e..6b7bb53 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -264,7 +264,7 @@
 	if (mode >= XFER_MW_DMA_0) {
 		t1 &= ~0x04;	/* disable UDMA */
 		idx = mode - XFER_MW_DMA_0 + 5;
-	}
+	} else
 		idx = mode - XFER_PIO_0;
 	t1 |= ini_time_value[clk][idx] << 12;
 	t1 |= act_time_value[clk][idx] << 16;
@@ -564,38 +564,30 @@
 {
 	u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f };
 
-	if (!hwif->irq)
-		hwif->irq = hwif->channel ? 15 : 14;
-
 	hwif->set_pio_mode = &sis_set_pio_mode;
 	hwif->set_dma_mode = &sis_set_dma_mode;
 
 	if (chipset_family >= ATA_133)
 		hwif->udma_filter = sis5513_ata133_udma_filter;
 
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->atapi_dma = 1;
-
 	hwif->ultra_mask = udma_rates[chipset_family];
-	hwif->mwdma_mask = 0x07;
 
 	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
 		hwif->cbl = ata66_sis5513(hwif);
 }
 
-static ide_pci_device_t sis5513_chipset __devinitdata = {
+static const struct ide_port_info sis5513_chipset __devinitdata = {
 	.name		= "SIS5513",
 	.init_chipset	= init_chipset_sis5513,
 	.init_hwif	= init_hwif_sis5513,
-	.autodma	= NOAUTODMA,
 	.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
-	.bootable	= ON_BOARD,
+	.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA |
+			  IDE_HFLAG_BOOTABLE,
 	.pio_mask	= ATA_PIO4,
+	.mwdma_mask	= ATA_MWDMA2,
 };
 
 static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 771efb8..147d783 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -361,19 +361,6 @@
 	hwif->selectproc	= &sl82c105_selectproc;
 	hwif->resetproc 	= &sl82c105_resetproc;
 
-	/*
-	 * We support 32-bit I/O on this interface, and
-	 * it doesn't have problems with interrupts.
-	 */
-	hwif->drives[0].io_32bit = hwif->drives[1].io_32bit = 1;
-	hwif->drives[0].unmask   = hwif->drives[1].unmask   = 1;
-
-	/*
-	 * We always autotune PIO,  this is done before DMA is checked,
-	 * so there's no risk of accidentally disabling DMA
-	 */
-	hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
 	if (!hwif->dma_base)
 		return;
 
@@ -388,8 +375,7 @@
 		return;
 	}
 
-	hwif->atapi_dma  = 1;
-	hwif->mwdma_mask = 0x07;
+	hwif->mwdma_mask = ATA_MWDMA2;
 
 	hwif->ide_dma_on		= &sl82c105_ide_dma_on;
 	hwif->dma_off_quietly		= &sl82c105_dma_off_quietly;
@@ -401,13 +387,15 @@
 		hwif->serialized = hwif->mate->serialized = 1;
 }
 
-static ide_pci_device_t sl82c105_chipset __devinitdata = {
+static const struct ide_port_info sl82c105_chipset __devinitdata = {
 	.name		= "W82C105",
 	.init_chipset	= init_chipset_sl82c105,
 	.init_hwif	= init_hwif_sl82c105,
-	.autodma	= NOAUTODMA,
 	.enablebits	= {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
-	.bootable	= ON_BOARD,
+	.host_flags	= IDE_HFLAG_IO_32BIT |
+			  IDE_HFLAG_UNMASK_IRQS |
+			  IDE_HFLAG_NO_AUTODMA |
+			  IDE_HFLAG_BOOTABLE,
 	.pio_mask	= ATA_PIO5,
 };
 
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index fa8df6d..eb4445b 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/ide/pci/slc90e66.c	Version 0.18	Aug 9, 2007
+ *  linux/drivers/ide/pci/slc90e66.c	Version 0.19	Sep 24, 2007
  *
  *  Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
  *  Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com>
@@ -21,6 +21,8 @@
 
 #include <asm/io.h>
 
+static DEFINE_SPINLOCK(slc90e66_lock);
+
 static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
@@ -40,7 +42,7 @@
 					{ 2, 1 },
 					{ 2, 3 }, };
 
-	spin_lock_irqsave(&ide_lock, flags);
+	spin_lock_irqsave(&slc90e66_lock, flags);
 	pci_read_config_word(dev, master_port, &master_data);
 
 	if (pio > 1)
@@ -71,7 +73,7 @@
 	pci_write_config_word(dev, master_port, master_data);
 	if (is_slave)
 		pci_write_config_byte(dev, slave_port, slave_data);
-	spin_unlock_irqrestore(&ide_lock, flags);
+	spin_unlock_irqrestore(&slc90e66_lock, flags);
 }
 
 static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
@@ -133,37 +135,28 @@
 	u8 reg47 = 0;
 	u8 mask = hwif->channel ? 0x01 : 0x02;  /* bit0:Primary */
 
-	if (!hwif->irq)
-		hwif->irq = hwif->channel ? 15 : 14;
-
 	hwif->set_pio_mode = &slc90e66_set_pio_mode;
 	hwif->set_dma_mode = &slc90e66_set_dma_mode;
 
 	pci_read_config_byte(hwif->pci_dev, 0x47, &reg47);
 
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-
 	if (hwif->dma_base == 0)
 		return;
 
-	hwif->atapi_dma = 1;
-	hwif->ultra_mask = 0x1f;
-	hwif->mwdma_mask = 0x06;
-	hwif->swdma_mask = 0x04;
-
 	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
 		/* bit[0(1)]: 0:80, 1:40 */
 		hwif->cbl = (reg47 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
 }
 
-static ide_pci_device_t slc90e66_chipset __devinitdata = {
+static const struct ide_port_info slc90e66_chipset __devinitdata = {
 	.name		= "SLC90E66",
 	.init_hwif	= init_hwif_slc90e66,
-	.autodma	= AUTODMA,
 	.enablebits	= {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
-	.bootable	= ON_BOARD,
+	.host_flags	= IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
 	.pio_mask	= ATA_PIO4,
+	.swdma_mask	= ATA_SWDMA2_ONLY,
+	.mwdma_mask	= ATA_MWDMA12_ONLY,
+	.udma_mask	= ATA_UDMA4,
 };
 
 static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index de62db5..a66ebd1 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -1,5 +1,5 @@
 /*
- * drivers/ide/pci/tc86c001.c	Version 1.00	Dec 12, 2006
+ * drivers/ide/pci/tc86c001.c	Version 1.01	Sep 5, 2007
  *
  * Copyright (C) 2002 Toshiba Corporation
  * Copyright (C) 2005-2006 MontaVista Software, Inc. <source@mvista.com>
@@ -17,7 +17,7 @@
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	unsigned long scr_port	= hwif->config_data + (drive->dn ? 0x02 : 0x00);
-	u16 mode, scr		= hwif->INW(scr_port);
+	u16 mode, scr		= inw(scr_port);
 
 	switch (speed) {
 		case XFER_UDMA_4:	mode = 0x00c0; break;
@@ -65,7 +65,7 @@
 	ide_hwif_t *hwif	= HWIF(drive);
 	ide_expiry_t *expiry	= ide_get_hwifdata(hwif);
 	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
-	u8 dma_stat		= hwif->INB(hwif->dma_status);
+	u8 dma_stat		= inb(hwif->dma_status);
 
 	/* Restore a higher level driver's expiry handler first. */
 	hwgroup->expiry	= expiry;
@@ -73,7 +73,7 @@
 	if ((dma_stat & 5) == 1) {	/* DMA active and no interrupt */
 		unsigned long sc_base	= hwif->config_data;
 		unsigned long twcr_port	= sc_base + (drive->dn ? 0x06 : 0x04);
-		u8 dma_cmd		= hwif->INB(hwif->dma_command);
+		u8 dma_cmd		= inb(hwif->dma_command);
 
 		printk(KERN_WARNING "%s: DMA interrupt possibly stuck, "
 		       "attempting recovery...\n", drive->name);
@@ -135,7 +135,7 @@
 	u16 scr1;
 
 	/* System Control 1 Register bit 11 (ATA Hard Reset) read */
-	scr1 = hwif->INW(sc_base + 0x00);
+	scr1 = inw(sc_base + 0x00);
 
 	switch (state) {
 		case BUSSTATE_ON:
@@ -165,7 +165,7 @@
 static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
 {
 	unsigned long sc_base	= pci_resource_start(hwif->pci_dev, 5);
-	u16 scr1		= hwif->INW(sc_base + 0x00);;
+	u16 scr1		= inw(sc_base + 0x00);
 
 	/* System Control 1 Register bit 15 (Soft Reset) set */
 	outw(scr1 |  0x8000, sc_base + 0x00);
@@ -184,8 +184,6 @@
 
 	hwif->busproc	= &tc86c001_busproc;
 
-	hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
 	if (!hwif->dma_base)
 		return;
 
@@ -198,10 +196,6 @@
 	/* Sector Count Register limit */
 	hwif->rqsize	 = 0xffff;
 
-	hwif->atapi_dma  = 1;
-	hwif->ultra_mask = 0x1f;
-	hwif->mwdma_mask = 0x07;
-
 	hwif->dma_start 	= &tc86c001_dma_start;
 
 	if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
@@ -209,7 +203,7 @@
 		 * System Control  1 Register bit 13 (PDIAGN):
 		 * 0=80-pin cable, 1=40-pin cable
 		 */
-		scr1 = hwif->INW(sc_base + 0x00);
+		scr1 = inw(sc_base + 0x00);
 		hwif->cbl = (scr1 & 0x2000) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
 	}
 }
@@ -224,14 +218,14 @@
 	return err;
 }
 
-static ide_pci_device_t tc86c001_chipset __devinitdata = {
+static const struct ide_port_info tc86c001_chipset __devinitdata = {
 	.name		= "TC86C001",
 	.init_chipset	= init_chipset_tc86c001,
 	.init_hwif	= init_hwif_tc86c001,
-	.autodma	= AUTODMA,
-	.bootable	= OFF_BOARD,
-	.host_flags	= IDE_HFLAG_SINGLE,
+	.host_flags	= IDE_HFLAG_SINGLE | IDE_HFLAG_OFF_BOARD,
 	.pio_mask	= ATA_PIO4,
+	.mwdma_mask	= ATA_MWDMA2,
+	.udma_mask	= ATA_UDMA4,
 };
 
 static int __devinit tc86c001_init_one(struct pci_dev *dev,
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index 4075c90..a227c41 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -100,22 +100,16 @@
 {
 	hwif->set_pio_mode = &triflex_set_pio_mode;
 	hwif->set_dma_mode = &triflex_set_mode;
-
-	if (hwif->dma_base == 0)
-		return;
-
-	hwif->atapi_dma  = 1;
-	hwif->mwdma_mask = 0x07;
-	hwif->swdma_mask = 0x07;
 }
 
-static ide_pci_device_t triflex_device __devinitdata = {
+static const struct ide_port_info triflex_device __devinitdata = {
 	.name		= "TRIFLEX",
 	.init_hwif	= init_hwif_triflex,
-	.autodma	= AUTODMA,
 	.enablebits	= {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
-	.bootable	= ON_BOARD,
+	.host_flags	= IDE_HFLAG_BOOTABLE,
 	.pio_mask	= ATA_PIO4,
+	.swdma_mask	= ATA_SWDMA2,
+	.mwdma_mask	= ATA_MWDMA2,
 };
 
 static int __devinit triflex_init_one(struct pci_dev *dev, 
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
index e3d943a..5011ba2 100644
--- a/drivers/ide/pci/trm290.c
+++ b/drivers/ide/pci/trm290.c
@@ -250,8 +250,6 @@
 	u8 reg = 0;
 	struct pci_dev *dev = hwif->pci_dev;
 
-	hwif->no_lba48 = 1;
-	hwif->chipset = ide_trm290;
 	cfgbase = pci_resource_start(dev, 4);
 	if ((dev->class & 5) && cfgbase) {
 		hwif->config_data = cfgbase;
@@ -321,14 +319,17 @@
 #endif
 }
 
-static ide_pci_device_t trm290_chipset __devinitdata = {
+static const struct ide_port_info trm290_chipset __devinitdata = {
 	.name		= "TRM290",
 	.init_hwif	= init_hwif_trm290,
-	.autodma	= NOAUTODMA,
-	.bootable	= ON_BOARD,
+	.chipset	= ide_trm290,
+	.host_flags	= IDE_HFLAG_NO_ATAPI_DMA |
 #if 0 /* play it safe for now */
-	.host_flags	= IDE_HFLAG_TRUST_BIOS_FOR_DMA,
+			  IDE_HFLAG_TRUST_BIOS_FOR_DMA |
 #endif
+			  IDE_HFLAG_NO_AUTODMA |
+			  IDE_HFLAG_BOOTABLE |
+			  IDE_HFLAG_NO_LBA48,
 };
 
 static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index b25fb65..a0d3c16 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -1,6 +1,6 @@
 /*
  *
- * Version 3.49
+ * Version 3.50
  *
  * VIA IDE driver for Linux. Supported southbridges:
  *
@@ -422,67 +422,40 @@
 
 static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 {
-	struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
-	int i;
-
 	hwif->set_pio_mode = &via_set_pio_mode;
 	hwif->set_dma_mode = &via_set_drive;
 
-#ifdef CONFIG_PPC_CHRP
-	if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
-		hwif->irq = hwif->channel ? 15 : 14;
-	}
-#endif
-
-	for (i = 0; i < 2; i++) {
-		hwif->drives[i].io_32bit = 1;
-		hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
-		hwif->drives[i].autotune = 1;
-	}
-
 	if (!hwif->dma_base)
 		return;
 
-	hwif->atapi_dma = 1;
-
-	hwif->ultra_mask = vdev->via_config->udma_mask;
-	hwif->mwdma_mask = 0x07;
-	hwif->swdma_mask = 0x07;
-
 	if (hwif->cbl != ATA_CBL_PATA40_SHORT)
 		hwif->cbl = via82cxxx_cable_detect(hwif);
 }
 
-static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
-	{	/* 0 */
-		.name		= "VP_IDE",
-		.init_chipset	= init_chipset_via82cxxx,
-		.init_hwif	= init_hwif_via82cxxx,
-		.autodma	= NOAUTODMA,
-		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_PIO_NO_BLACKLIST
-				| IDE_HFLAG_PIO_NO_DOWNGRADE
-				| IDE_HFLAG_POST_SET_MODE,
-		.pio_mask	= ATA_PIO5,
-	},{	/* 1 */
-		.name		= "VP_IDE",
-		.init_chipset	= init_chipset_via82cxxx,
-		.init_hwif	= init_hwif_via82cxxx,
-		.autodma	= AUTODMA,
-		.enablebits	= {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
-		.bootable	= ON_BOARD,
-		.host_flags	= IDE_HFLAG_PIO_NO_BLACKLIST
-				| IDE_HFLAG_PIO_NO_DOWNGRADE
-				| IDE_HFLAG_POST_SET_MODE,
-		.pio_mask	= ATA_PIO5,
-	}
+static const struct ide_port_info via82cxxx_chipset __devinitdata = {
+	.name		= "VP_IDE",
+	.init_chipset	= init_chipset_via82cxxx,
+	.init_hwif	= init_hwif_via82cxxx,
+	.enablebits	= { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
+	.host_flags	= IDE_HFLAG_PIO_NO_BLACKLIST |
+			  IDE_HFLAG_PIO_NO_DOWNGRADE |
+			  IDE_HFLAG_POST_SET_MODE |
+			  IDE_HFLAG_IO_32BIT |
+			  IDE_HFLAG_BOOTABLE,
+	.pio_mask	= ATA_PIO5,
+	.swdma_mask	= ATA_SWDMA2,
+	.mwdma_mask	= ATA_MWDMA2,
 };
 
 static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	struct pci_dev *isa = NULL;
 	struct via_isa_bridge *via_config;
+	u8 idx = id->driver_data;
+	struct ide_port_info d;
+
+	d = via82cxxx_chipset;
+
 	/*
 	 * Find the ISA bridge and check we know what it is.
 	 */
@@ -492,7 +465,23 @@
 		printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
 		return -ENODEV;
 	}
-	return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
+
+	if (idx == 0)
+		d.host_flags |= IDE_HFLAG_NO_AUTODMA;
+	else
+		d.enablebits[1].reg = d.enablebits[0].reg = 0;
+
+	if ((via_config->flags & VIA_NO_UNMASK) == 0)
+		d.host_flags |= IDE_HFLAG_UNMASK_IRQS;
+
+#ifdef CONFIG_PPC_CHRP
+	if (machine_is(chrp) && _chrp_type == _CHRP_Pegasos)
+		d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS;
+#endif
+
+	d.udma_mask = via_config->udma_mask;
+
+	return ide_setup_pci_device(dev, &d);
 }
 
 static const struct pci_device_id via_pci_tbl[] = {
diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c
index df2e920..5f0da35 100644
--- a/drivers/ide/ppc/mpc8xx.c
+++ b/drivers/ide/ppc/mpc8xx.c
@@ -316,8 +316,8 @@
 
 	ide_hwifs[data_port].pio_mask = ATA_PIO4;
 	ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode;
+	ide_hwifs[data_port].ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
 
-	hw->ack_intr = (ide_ack_intr_t *) ide_interrupt_ack;
 	/* Enable Harddisk Interrupt,
 	 * and make it edge sensitive
 	 */
@@ -402,8 +402,8 @@
 
 	ide_hwifs[data_port].pio_mask = ATA_PIO4;
 	ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode;
+	ide_hwifs[data_port].ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
 
-	hw->ack_intr = (ide_ack_intr_t *) ide_interrupt_ack;
 	/* Enable Harddisk Interrupt,
 	 * and make it edge sensitive
 	 */
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 1d25a34..816b531 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1039,6 +1039,8 @@
 {
 	struct device_node *np = pmif->node;
 	const int *bidp;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+	hw_regs_t hw;
 
 	pmif->cable_80 = 0;
 	pmif->broken_dma = pmif->broken_dma_warn = 0;
@@ -1124,8 +1126,9 @@
 	/* Tell common code _not_ to mess with resources */
 	hwif->mmio = 1;
 	hwif->hwif_data = pmif;
-	pmac_ide_init_hwif_ports(&hwif->hw, pmif->regbase, 0, &hwif->irq);
-	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+	memset(&hw, 0, sizeof(hw));
+	pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, &hwif->irq);
+	memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
 	hwif->chipset = ide_pmac;
 	hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay;
 	hwif->hold = pmif->mediabay;
@@ -1163,10 +1166,9 @@
 		pmac_ide_setup_dma(pmif, hwif);
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 
-	/* We probe the hwif now */
-	probe_hwif_init(hwif);
+	idx[0] = hwif->index;
 
-	ide_proc_register_port(hwif);
+	ide_device_add(idx);
 
 	return 0;
 }
@@ -1780,7 +1782,6 @@
 	hwif->dma_timeout = &ide_dma_timeout;
 	hwif->dma_lost_irq = &pmac_ide_dma_lost_irq;
 
-	hwif->atapi_dma = 1;
 	switch(pmif->kind) {
 		case controller_sh_ata6:
 			hwif->ultra_mask = pmif->cable_80 ? 0x7f : 0x07;
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 3d101f7..02d14bf 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -147,14 +147,15 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
  *	ide_get_or_set_dma_base		-	setup BMIBA
- *	@hwif: Interface
+ *	@d: IDE port info
+ *	@hwif: IDE interface
  *
  *	Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space.
  *	Where a device has a partner that is already in DMA mode we check
  *	and enforce IDE simplex rules.
  */
 
-static unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif)
+static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_hwif_t *hwif)
 {
 	unsigned long	dma_base = 0;
 	struct pci_dev	*dev = hwif->pci_dev;
@@ -165,14 +166,15 @@
 	if (hwif->mate && hwif->mate->dma_base) {
 		dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
 	} else {
-		dma_base = pci_resource_start(dev, 4);
-		if (!dma_base) {
-			printk(KERN_ERR "%s: dma_base is invalid\n",
-					hwif->cds->name);
-		}
+		u8 baridx = (d->host_flags & IDE_HFLAG_CS5520) ? 2 : 4;
+
+		dma_base = pci_resource_start(dev, baridx);
+
+		if (dma_base == 0)
+			printk(KERN_ERR "%s: DMA base is invalid\n", d->name);
 	}
 
-	if (dma_base) {
+	if ((d->host_flags & IDE_HFLAG_CS5520) == 0 && dma_base) {
 		u8 simplex_stat = 0;
 		dma_base += hwif->channel ? 8 : 0;
 
@@ -183,13 +185,13 @@
 			case PCI_DEVICE_ID_CMD_643:
 			case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
 			case PCI_DEVICE_ID_REVOLUTION:
-				simplex_stat = hwif->INB(dma_base + 2);
-				hwif->OUTB((simplex_stat&0x60),(dma_base + 2));
-				simplex_stat = hwif->INB(dma_base + 2);
+				simplex_stat = inb(dma_base + 2);
+				outb(simplex_stat & 0x60, dma_base + 2);
+				simplex_stat = inb(dma_base + 2);
 				if (simplex_stat & 0x80) {
 					printk(KERN_INFO "%s: simplex device: "
-						"DMA forced\n",
-						hwif->cds->name);
+							 "DMA forced\n",
+							 d->name);
 				}
 				break;
 			default:
@@ -212,8 +214,8 @@
  */
 					if (hwif->mate && hwif->mate->dma_base) {
 						printk(KERN_INFO "%s: simplex device: "
-							"DMA disabled\n",
-							hwif->cds->name);
+								 "DMA disabled\n",
+								 d->name);
 						dma_base = 0;
 					}
 				}
@@ -223,10 +225,11 @@
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
-void ide_setup_pci_noise (struct pci_dev *dev, ide_pci_device_t *d)
+void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d)
 {
-	printk(KERN_INFO "%s: IDE controller at PCI slot %s\n",
-			 d->name, pci_name(dev));
+	printk(KERN_INFO "%s: IDE controller (0x%04x:0x%04x rev 0x%02x) at "
+			 " PCI slot %s\n", d->name, dev->vendor, dev->device,
+			 dev->revision, pci_name(dev));
 }
 
 EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
@@ -235,15 +238,15 @@
 /**
  *	ide_pci_enable	-	do PCI enables
  *	@dev: PCI device
- *	@d: IDE pci device data
+ *	@d: IDE port info
  *
  *	Enable the IDE PCI device. We attempt to enable the device in full
  *	but if that fails then we only need BAR4 so we will enable that.
  *	
  *	Returns zero on success or an error code
  */
- 
-static int ide_pci_enable(struct pci_dev *dev, ide_pci_device_t *d)
+
+static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
 {
 	int ret;
 
@@ -258,9 +261,9 @@
 	}
 
 	/*
-	 * assume all devices can do 32-bit dma for now. we can add a
-	 * dma mask field to the ide_pci_device_t if we need it (or let
-	 * lower level driver set the dma mask)
+	 * assume all devices can do 32-bit DMA for now, we can add
+	 * a DMA mask field to the struct ide_port_info if we need it
+	 * (or let lower level driver set the DMA mask)
 	 */
 	ret = pci_set_dma_mask(dev, DMA_32BIT_MASK);
 	if (ret < 0) {
@@ -282,13 +285,13 @@
 /**
  *	ide_pci_configure	-	configure an unconfigured device
  *	@dev: PCI device
- *	@d: IDE pci device data
+ *	@d: IDE port info
  *
  *	Enable and configure the PCI device we have been passed.
  *	Returns zero on success or an error code.
  */
- 
-static int ide_pci_configure(struct pci_dev *dev, ide_pci_device_t *d)
+
+static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d)
 {
 	u16 pcicmd = 0;
 	/*
@@ -316,15 +319,15 @@
 
 /**
  *	ide_pci_check_iomem	-	check a register is I/O
- *	@dev: pci device
- *	@d: ide_pci_device
- *	@bar: bar number
+ *	@dev: PCI device
+ *	@d: IDE port info
+ *	@bar: BAR number
  *
  *	Checks if a BAR is configured and points to MMIO space. If so
  *	print an error and return an error code. Otherwise return 0
  */
- 
-static int ide_pci_check_iomem(struct pci_dev *dev, ide_pci_device_t *d, int bar)
+
+static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d, int bar)
 {
 	ulong flags = pci_resource_flags(dev, bar);
 	
@@ -346,7 +349,7 @@
 /**
  *	ide_hwif_configure	-	configure an IDE interface
  *	@dev: PCI device holding interface
- *	@d: IDE pci data
+ *	@d: IDE port info
  *	@mate: Paired interface if any
  *
  *	Perform the initial set up for the hardware interface structure. This
@@ -355,11 +358,12 @@
  *
  *	Returns the new hardware interface structure, or NULL on a failure
  */
- 
-static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *mate, int port, int irq)
+
+static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *mate, int port, int irq)
 {
 	unsigned long ctl = 0, base = 0;
 	ide_hwif_t *hwif;
+	u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0;
 
 	if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) {
 		/*  Possibly we should fail if these checks report true */
@@ -380,23 +384,24 @@
 		ctl = port ? 0x374 : 0x3f4;
 		base = port ? 0x170 : 0x1f0;
 	}
-	if ((hwif = ide_match_hwif(base, d->bootable, d->name)) == NULL)
+	if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL)
 		return NULL;	/* no room in ide_hwifs[] */
 	if (hwif->io_ports[IDE_DATA_OFFSET] != base ||
 	    hwif->io_ports[IDE_CONTROL_OFFSET] != (ctl | 2)) {
-		memset(&hwif->hw, 0, sizeof(hwif->hw));
-#ifndef IDE_ARCH_OBSOLETE_INIT
-		ide_std_init_ports(&hwif->hw, base, (ctl | 2));
-		hwif->hw.io_ports[IDE_IRQ_OFFSET] = 0;
+		hw_regs_t hw;
+
+		memset(&hw, 0, sizeof(hw));
+#ifndef CONFIG_IDE_ARCH_OBSOLETE_INIT
+		ide_std_init_ports(&hw, base, ctl | 2);
 #else
-		ide_init_hwif_ports(&hwif->hw, base, (ctl | 2), NULL);
+		ide_init_hwif_ports(&hw, base, ctl | 2, NULL);
 #endif
-		memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+		memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
 		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
 	}
-	hwif->chipset = ide_pci;
+	hwif->chipset = d->chipset ? d->chipset : ide_pci;
 	hwif->pci_dev = dev;
-	hwif->cds = (struct ide_pci_device_s *) d;
+	hwif->cds = d;
 	hwif->channel = port;
 
 	if (!hwif->irq)
@@ -411,28 +416,25 @@
 /**
  *	ide_hwif_setup_dma	-	configure DMA interface
  *	@dev: PCI device
- *	@d: IDE pci data
- *	@hwif: Hardware interface we are configuring
+ *	@d: IDE port info
+ *	@hwif: IDE interface
  *
  *	Set up the DMA base for the interface. Enable the master bits as
  *	necessary and attempt to bring the device DMA into a ready to use
  *	state
  */
- 
-#ifndef CONFIG_BLK_DEV_IDEDMA_PCI
-static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
+
+static void ide_hwif_setup_dma(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *hwif)
 {
-}
-#else
-static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
-{
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 	u16 pcicmd;
+
 	pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
 
-	if ((d->autodma == AUTODMA) ||
+	if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 ||
 	    ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
 	     (dev->class & 0x80))) {
-		unsigned long dma_base = ide_get_or_set_dma_base(hwif);
+		unsigned long dma_base = ide_get_or_set_dma_base(d, hwif);
 		if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) {
 			/*
  			 * Set up BM-DMA capability
@@ -456,13 +458,13 @@
 				"(BIOS)\n", hwif->name, d->name);
 		}
 	}
-}
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI*/
+}
 
 /**
  *	ide_setup_pci_controller	-	set up IDE PCI
  *	@dev: PCI device
- *	@d: IDE PCI data
+ *	@d: IDE port info
  *	@noisy: verbose flag
  *	@config: returned as 1 if we configured the hardware
  *
@@ -470,11 +472,10 @@
  *	up the PCI side of the device, checks that the device is enabled
  *	and enables it if need be
  */
- 
-static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, int noisy, int *config)
+
+static int ide_setup_pci_controller(struct pci_dev *dev, const struct ide_port_info *d, int noisy, int *config)
 {
 	int ret;
-	u32 class_rev;
 	u16 pcicmd;
 
 	if (noisy)
@@ -497,10 +498,6 @@
 		printk(KERN_INFO "%s: device enabled (Linux)\n", d->name);
 	}
 
-	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-	class_rev &= 0xff;
-	if (noisy)
-		printk(KERN_INFO "%s: chipset revision %d\n", d->name, class_rev);
 out:
 	return ret;
 }
@@ -508,9 +505,9 @@
 /**
  *	ide_pci_setup_ports	-	configure ports/devices on PCI IDE
  *	@dev: PCI device
- *	@d: IDE pci device info
+ *	@d: IDE port info
  *	@pciirq: IRQ line
- *	@index: ata index to update
+ *	@idx: ATA index table to update
  *
  *	Scan the interfaces attached to this device and do any
  *	necessary per port setup. Attach the devices and ask the
@@ -520,26 +517,25 @@
  *	but is also used directly as a helper function by some controllers
  *	where the chipset setup is not the default PCI IDE one.
  */
- 
-void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, ata_index_t *index)
+
+void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int pciirq, u8 *idx)
 {
 	int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;
-	int at_least_one_hwif_enabled = 0;
 	ide_hwif_t *hwif, *mate = NULL;
 	u8 tmp;
 
-	index->all = 0xf0f0;
-
 	/*
 	 * Set up the IDE ports
 	 */
-	 
+
 	for (port = 0; port < channels; ++port) {
-		ide_pci_enablebit_t *e = &(d->enablebits[port]);
-	
+		const ide_pci_enablebit_t *e = &(d->enablebits[port]);
+
 		if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
-		    (tmp & e->mask) != e->val))
+		    (tmp & e->mask) != e->val)) {
+			printk(KERN_INFO "%s: IDE port disabled\n", d->name);
 			continue;	/* port not enabled */
+		}
 
 		if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)
 			continue;
@@ -547,27 +543,49 @@
 		/* setup proper ancestral information */
 		hwif->gendev.parent = &dev->dev;
 
-		if (hwif->channel) {
-			index->b.high = hwif->index;
-		} else {
-			index->b.low = hwif->index;
-		}
+		*(idx + port) = hwif->index;
 
 		
 		if (d->init_iops)
 			d->init_iops(hwif);
 
-		if (d->autodma == NODMA)
-			goto bypass_legacy_dma;
-
-		if(d->init_setup_dma)
-			d->init_setup_dma(dev, d, hwif);
-		else
+		if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0)
 			ide_hwif_setup_dma(dev, d, hwif);
-bypass_legacy_dma:
+
+		if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
+		    (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
+			hwif->irq = port ? 15 : 14;
+
+		hwif->fixup = d->fixup;
+
 		hwif->host_flags = d->host_flags;
 		hwif->pio_mask = d->pio_mask;
 
+		if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate)
+			hwif->mate->serialized = hwif->serialized = 1;
+
+		if (d->host_flags & IDE_HFLAG_IO_32BIT) {
+			hwif->drives[0].io_32bit = 1;
+			hwif->drives[1].io_32bit = 1;
+		}
+
+		if (d->host_flags & IDE_HFLAG_UNMASK_IRQS) {
+			hwif->drives[0].unmask = 1;
+			hwif->drives[1].unmask = 1;
+		}
+
+		if (hwif->dma_base) {
+			hwif->swdma_mask = d->swdma_mask;
+			hwif->mwdma_mask = d->mwdma_mask;
+			hwif->ultra_mask = d->udma_mask;
+		}
+
+		hwif->drives[0].autotune = 1;
+		hwif->drives[1].autotune = 1;
+
+		if (d->host_flags & IDE_HFLAG_RQSIZE_256)
+			hwif->rqsize = 256;
+
 		if (d->init_hwif)
 			/* Call chipset-specific routine
 			 * for each enabled hwif
@@ -575,10 +593,7 @@
 			d->init_hwif(hwif);
 
 		mate = hwif;
-		at_least_one_hwif_enabled = 1;
 	}
-	if (!at_least_one_hwif_enabled)
-		printk(KERN_INFO "%s: neither IDE port enabled (BIOS)\n", d->name);
 }
 
 EXPORT_SYMBOL_GPL(ide_pci_setup_ports);
@@ -590,13 +605,13 @@
  *
  * One thing that is not standardized is the location of the
  * primary/secondary interface "enable/disable" bits.  For chipsets that
- * we "know" about, this information is in the ide_pci_device_t struct;
+ * we "know" about, this information is in the struct ide_port_info;
  * for all other chipsets, we just assume both interfaces are enabled.
  */
-static int do_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d,
-				   ata_index_t *index, u8 noisy)
+static int do_ide_setup_pci_device(struct pci_dev *dev,
+				   const struct ide_port_info *d,
+				   u8 *idx, u8 noisy)
 {
-	static ata_index_t ata_index = { .b = { .low = 0xff, .high = 0xff } };
 	int tried_config = 0;
 	int pciirq, ret;
 
@@ -646,51 +661,35 @@
 
 	/* FIXME: silent failure can happen */
 
-	*index = ata_index;
-	ide_pci_setup_ports(dev, d, pciirq, index);
+	ide_pci_setup_ports(dev, d, pciirq, idx);
 out:
 	return ret;
 }
 
-int ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d)
+int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d)
 {
-	ide_hwif_t *hwif = NULL, *mate = NULL;
-	ata_index_t index_list;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 	int ret;
 
-	ret = do_ide_setup_pci_device(dev, d, &index_list, 1);
-	if (ret < 0)
-		goto out;
+	ret = do_ide_setup_pci_device(dev, d, &idx[0], 1);
 
-	if ((index_list.b.low & 0xf0) != 0xf0)
-		hwif = &ide_hwifs[index_list.b.low];
-	if ((index_list.b.high & 0xf0) != 0xf0)
-		mate = &ide_hwifs[index_list.b.high];
+	if (ret >= 0)
+		ide_device_add(idx);
 
-	if (hwif)
-		probe_hwif_init_with_fixup(hwif, d->fixup);
-	if (mate)
-		probe_hwif_init_with_fixup(mate, d->fixup);
-
-	if (hwif)
-		ide_proc_register_port(hwif);
-	if (mate)
-		ide_proc_register_port(mate);
-out:
 	return ret;
 }
 
 EXPORT_SYMBOL_GPL(ide_setup_pci_device);
 
 int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
-			  ide_pci_device_t *d)
+			  const struct ide_port_info *d)
 {
 	struct pci_dev *pdev[] = { dev1, dev2 };
-	ata_index_t index_list[2];
 	int ret, i;
+	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
 	for (i = 0; i < 2; i++) {
-		ret = do_ide_setup_pci_device(pdev[i], d, index_list + i, !i);
+		ret = do_ide_setup_pci_device(pdev[i], d, &idx[i*2], !i);
 		/*
 		 * FIXME: Mom, mom, they stole me the helper function to undo
 		 * do_ide_setup_pci_device() on the first device!
@@ -699,25 +698,7 @@
 			goto out;
 	}
 
-	for (i = 0; i < 2; i++) {
-		u8 idx[2] = { index_list[i].b.low, index_list[i].b.high };
-		int j;
-
-		for (j = 0; j < 2; j++) {
-			if ((idx[j] & 0xf0) != 0xf0)
-				probe_hwif_init(ide_hwifs + idx[j]);
-		}
-	}
-
-	for (i = 0; i < 2; i++) {
-		u8 idx[2] = { index_list[i].b.low, index_list[i].b.high };
-		int j;
-
-		for (j = 0; j < 2; j++) {
-			if ((idx[j] & 0xf0) != 0xf0)
-				ide_proc_register_port(ide_hwifs + idx[j]);
-		}
-	}
+	ide_device_add(idx);
 out:
 	return ret;
 }
@@ -742,9 +723,6 @@
  *	hands the controllers off to the core PCI code to do the rest of
  *	the work.
  *
- *	The driver_data of the driver table must point to an ide_pci_device_t
- *	describing the interface.
- *
  *	Returns are the same as for pci_register_driver
  */
 
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 45d6055..3051e31 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -12,7 +12,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 #include "dma.h"
 
@@ -111,7 +111,7 @@
 		unsigned long va =
 		    (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
 
-		dma->sglist[i].page = vmalloc_to_page((void *)va);
+		sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va));
 		dma->sglist[i].length = PAGE_SIZE;
 	}
 
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 1b353b9..d5dfe11 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -1466,7 +1466,7 @@
 		cmd->dma_size = sgpnt[0].length;
 		cmd->dma_type = CMD_DMA_PAGE;
 		cmd->cmd_dma = dma_map_page(hi->host->device.parent,
-					    sgpnt[0].page, sgpnt[0].offset,
+					    sg_page(&sgpnt[0]), sgpnt[0].offset,
 					    cmd->dma_size, cmd->dma_dir);
 
 		orb->data_descriptor_lo = cmd->cmd_dma;
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 93644f8..0751697 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -114,13 +114,16 @@
 
 	struct rdma_bind_list	*bind_list;
 	struct hlist_node	node;
-	struct list_head	list;
-	struct list_head	listen_list;
+	struct list_head	list; /* listen_any_list or cma_device.list */
+	struct list_head	listen_list; /* per device listens */
 	struct cma_device	*cma_dev;
 	struct list_head	mc_list;
 
+	int			internal_id;
 	enum cma_state		state;
 	spinlock_t		lock;
+	struct mutex		qp_mutex;
+
 	struct completion	comp;
 	atomic_t		refcount;
 	wait_queue_head_t	wait_remove;
@@ -389,6 +392,7 @@
 	id_priv->id.event_handler = event_handler;
 	id_priv->id.ps = ps;
 	spin_lock_init(&id_priv->lock);
+	mutex_init(&id_priv->qp_mutex);
 	init_completion(&id_priv->comp);
 	atomic_set(&id_priv->refcount, 1);
 	init_waitqueue_head(&id_priv->wait_remove);
@@ -474,61 +478,86 @@
 
 void rdma_destroy_qp(struct rdma_cm_id *id)
 {
-	ib_destroy_qp(id->qp);
+	struct rdma_id_private *id_priv;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	mutex_lock(&id_priv->qp_mutex);
+	ib_destroy_qp(id_priv->id.qp);
+	id_priv->id.qp = NULL;
+	mutex_unlock(&id_priv->qp_mutex);
 }
 EXPORT_SYMBOL(rdma_destroy_qp);
 
-static int cma_modify_qp_rtr(struct rdma_cm_id *id)
+static int cma_modify_qp_rtr(struct rdma_id_private *id_priv)
 {
 	struct ib_qp_attr qp_attr;
 	int qp_attr_mask, ret;
 
-	if (!id->qp)
-		return 0;
+	mutex_lock(&id_priv->qp_mutex);
+	if (!id_priv->id.qp) {
+		ret = 0;
+		goto out;
+	}
 
 	/* Need to update QP attributes from default values. */
 	qp_attr.qp_state = IB_QPS_INIT;
-	ret = rdma_init_qp_attr(id, &qp_attr, &qp_attr_mask);
+	ret = rdma_init_qp_attr(&id_priv->id, &qp_attr, &qp_attr_mask);
 	if (ret)
-		return ret;
+		goto out;
 
-	ret = ib_modify_qp(id->qp, &qp_attr, qp_attr_mask);
+	ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask);
 	if (ret)
-		return ret;
+		goto out;
 
 	qp_attr.qp_state = IB_QPS_RTR;
-	ret = rdma_init_qp_attr(id, &qp_attr, &qp_attr_mask);
+	ret = rdma_init_qp_attr(&id_priv->id, &qp_attr, &qp_attr_mask);
 	if (ret)
-		return ret;
+		goto out;
 
-	return ib_modify_qp(id->qp, &qp_attr, qp_attr_mask);
+	ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask);
+out:
+	mutex_unlock(&id_priv->qp_mutex);
+	return ret;
 }
 
-static int cma_modify_qp_rts(struct rdma_cm_id *id)
+static int cma_modify_qp_rts(struct rdma_id_private *id_priv)
 {
 	struct ib_qp_attr qp_attr;
 	int qp_attr_mask, ret;
 
-	if (!id->qp)
-		return 0;
+	mutex_lock(&id_priv->qp_mutex);
+	if (!id_priv->id.qp) {
+		ret = 0;
+		goto out;
+	}
 
 	qp_attr.qp_state = IB_QPS_RTS;
-	ret = rdma_init_qp_attr(id, &qp_attr, &qp_attr_mask);
+	ret = rdma_init_qp_attr(&id_priv->id, &qp_attr, &qp_attr_mask);
 	if (ret)
-		return ret;
+		goto out;
 
-	return ib_modify_qp(id->qp, &qp_attr, qp_attr_mask);
+	ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask);
+out:
+	mutex_unlock(&id_priv->qp_mutex);
+	return ret;
 }
 
-static int cma_modify_qp_err(struct rdma_cm_id *id)
+static int cma_modify_qp_err(struct rdma_id_private *id_priv)
 {
 	struct ib_qp_attr qp_attr;
+	int ret;
 
-	if (!id->qp)
-		return 0;
+	mutex_lock(&id_priv->qp_mutex);
+	if (!id_priv->id.qp) {
+		ret = 0;
+		goto out;
+	}
 
 	qp_attr.qp_state = IB_QPS_ERR;
-	return ib_modify_qp(id->qp, &qp_attr, IB_QP_STATE);
+	ret = ib_modify_qp(id_priv->id.qp, &qp_attr, IB_QP_STATE);
+out:
+	mutex_unlock(&id_priv->qp_mutex);
+	return ret;
 }
 
 static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv,
@@ -717,50 +746,27 @@
 	}
 }
 
-static inline int cma_internal_listen(struct rdma_id_private *id_priv)
-{
-	return (id_priv->state == CMA_LISTEN) && id_priv->cma_dev &&
-	       cma_any_addr(&id_priv->id.route.addr.src_addr);
-}
-
-static void cma_destroy_listen(struct rdma_id_private *id_priv)
-{
-	cma_exch(id_priv, CMA_DESTROYING);
-
-	if (id_priv->cma_dev) {
-		switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
-		case RDMA_TRANSPORT_IB:
-			if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib))
-				ib_destroy_cm_id(id_priv->cm_id.ib);
-			break;
-		case RDMA_TRANSPORT_IWARP:
-			if (id_priv->cm_id.iw && !IS_ERR(id_priv->cm_id.iw))
-				iw_destroy_cm_id(id_priv->cm_id.iw);
-			break;
-		default:
-			break;
-		}
-		cma_detach_from_dev(id_priv);
-	}
-	list_del(&id_priv->listen_list);
-
-	cma_deref_id(id_priv);
-	wait_for_completion(&id_priv->comp);
-
-	kfree(id_priv);
-}
-
 static void cma_cancel_listens(struct rdma_id_private *id_priv)
 {
 	struct rdma_id_private *dev_id_priv;
 
+	/*
+	 * Remove from listen_any_list to prevent added devices from spawning
+	 * additional listen requests.
+	 */
 	mutex_lock(&lock);
 	list_del(&id_priv->list);
 
 	while (!list_empty(&id_priv->listen_list)) {
 		dev_id_priv = list_entry(id_priv->listen_list.next,
 					 struct rdma_id_private, listen_list);
-		cma_destroy_listen(dev_id_priv);
+		/* sync with device removal to avoid duplicate destruction */
+		list_del_init(&dev_id_priv->list);
+		list_del(&dev_id_priv->listen_list);
+		mutex_unlock(&lock);
+
+		rdma_destroy_id(&dev_id_priv->id);
+		mutex_lock(&lock);
 	}
 	mutex_unlock(&lock);
 }
@@ -848,6 +854,9 @@
 	cma_deref_id(id_priv);
 	wait_for_completion(&id_priv->comp);
 
+	if (id_priv->internal_id)
+		cma_deref_id(id_priv->id.context);
+
 	kfree(id_priv->id.route.path_rec);
 	kfree(id_priv);
 }
@@ -857,11 +866,11 @@
 {
 	int ret;
 
-	ret = cma_modify_qp_rtr(&id_priv->id);
+	ret = cma_modify_qp_rtr(id_priv);
 	if (ret)
 		goto reject;
 
-	ret = cma_modify_qp_rts(&id_priv->id);
+	ret = cma_modify_qp_rts(id_priv);
 	if (ret)
 		goto reject;
 
@@ -871,7 +880,7 @@
 
 	return 0;
 reject:
-	cma_modify_qp_err(&id_priv->id);
+	cma_modify_qp_err(id_priv);
 	ib_send_cm_rej(id_priv->cm_id.ib, IB_CM_REJ_CONSUMER_DEFINED,
 		       NULL, 0, NULL, 0);
 	return ret;
@@ -947,7 +956,7 @@
 		/* ignore event */
 		goto out;
 	case IB_CM_REJ_RECEIVED:
-		cma_modify_qp_err(&id_priv->id);
+		cma_modify_qp_err(id_priv);
 		event.status = ib_event->param.rej_rcvd.reason;
 		event.event = RDMA_CM_EVENT_REJECTED;
 		event.param.conn.private_data = ib_event->private_data;
@@ -1404,14 +1413,13 @@
 
 	cma_attach_to_dev(dev_id_priv, cma_dev);
 	list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list);
+	atomic_inc(&id_priv->refcount);
+	dev_id_priv->internal_id = 1;
 
 	ret = rdma_listen(id, id_priv->backlog);
 	if (ret)
-		goto err;
-
-	return;
-err:
-	cma_destroy_listen(dev_id_priv);
+		printk(KERN_WARNING "RDMA CMA: cma_listen_on_dev, error %d, "
+		       "listening on device %s", ret, cma_dev->device->name);
 }
 
 static void cma_listen_on_all(struct rdma_id_private *id_priv)
@@ -2264,7 +2272,7 @@
 	sin = (struct sockaddr_in*) &id_priv->id.route.addr.dst_addr;
 	cm_id->remote_addr = *sin;
 
-	ret = cma_modify_qp_rtr(&id_priv->id);
+	ret = cma_modify_qp_rtr(id_priv);
 	if (ret)
 		goto out;
 
@@ -2331,7 +2339,7 @@
 	int qp_attr_mask, ret;
 
 	if (id_priv->id.qp) {
-		ret = cma_modify_qp_rtr(&id_priv->id);
+		ret = cma_modify_qp_rtr(id_priv);
 		if (ret)
 			goto out;
 
@@ -2370,7 +2378,7 @@
 	struct iw_cm_conn_param iw_param;
 	int ret;
 
-	ret = cma_modify_qp_rtr(&id_priv->id);
+	ret = cma_modify_qp_rtr(id_priv);
 	if (ret)
 		return ret;
 
@@ -2442,7 +2450,7 @@
 
 	return 0;
 reject:
-	cma_modify_qp_err(id);
+	cma_modify_qp_err(id_priv);
 	rdma_reject(id, NULL, 0);
 	return ret;
 }
@@ -2512,7 +2520,7 @@
 
 	switch (rdma_node_get_transport(id->device->node_type)) {
 	case RDMA_TRANSPORT_IB:
-		ret = cma_modify_qp_err(id);
+		ret = cma_modify_qp_err(id_priv);
 		if (ret)
 			goto out;
 		/* Initiate or respond to a disconnect. */
@@ -2543,9 +2551,11 @@
 	    cma_disable_remove(id_priv, CMA_ADDR_RESOLVED))
 		return 0;
 
+	mutex_lock(&id_priv->qp_mutex);
 	if (!status && id_priv->id.qp)
 		status = ib_attach_mcast(id_priv->id.qp, &multicast->rec.mgid,
 					 multicast->rec.mlid);
+	mutex_unlock(&id_priv->qp_mutex);
 
 	memset(&event, 0, sizeof event);
 	event.status = status;
@@ -2757,16 +2767,12 @@
 		id_priv = list_entry(cma_dev->id_list.next,
 				     struct rdma_id_private, list);
 
-		if (cma_internal_listen(id_priv)) {
-			cma_destroy_listen(id_priv);
-			continue;
-		}
-
+		list_del(&id_priv->listen_list);
 		list_del_init(&id_priv->list);
 		atomic_inc(&id_priv->refcount);
 		mutex_unlock(&lock);
 
-		ret = cma_remove_id_dev(id_priv);
+		ret = id_priv->internal_id ? 1 : cma_remove_id_dev(id_priv);
 		cma_deref_id(id_priv);
 		if (ret)
 			rdma_destroy_id(&id_priv->id);
@@ -2797,11 +2803,12 @@
 
 static int cma_init(void)
 {
-	int ret, low, high;
+	int ret, low, high, remaining;
 
 	get_random_bytes(&next_port, sizeof next_port);
 	inet_get_local_port_range(&low, &high);
-	next_port = ((unsigned int) next_port % (high - low)) + low;
+	remaining = (high - low) + 1;
+	next_port = ((unsigned int) next_port % remaining) + low;
 
 	cma_wq = create_singlethread_workqueue("rdma_cm");
 	if (!cma_wq)
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 2f54e29..14159ff 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -55,9 +55,11 @@
 		ib_dma_unmap_sg(dev, chunk->page_list,
 				chunk->nents, DMA_BIDIRECTIONAL);
 		for (i = 0; i < chunk->nents; ++i) {
+			struct page *page = sg_page(&chunk->page_list[i]);
+
 			if (umem->writable && dirty)
-				set_page_dirty_lock(chunk->page_list[i].page);
-			put_page(chunk->page_list[i].page);
+				set_page_dirty_lock(page);
+			put_page(page);
 		}
 
 		kfree(chunk);
@@ -164,11 +166,12 @@
 			}
 
 			chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
+			sg_init_table(chunk->page_list, chunk->nents);
 			for (i = 0; i < chunk->nents; ++i) {
 				if (vma_list &&
 				    !is_vm_hugetlb_page(vma_list[i + off]))
 					umem->hugetlb = 0;
-				chunk->page_list[i].page   = page_list[i + off];
+				sg_set_page(&chunk->page_list[i], page_list[i + off]);
 				chunk->page_list[i].offset = 0;
 				chunk->page_list[i].length = PAGE_SIZE;
 			}
@@ -179,7 +182,7 @@
 						    DMA_BIDIRECTIONAL);
 			if (chunk->nmap <= 0) {
 				for (i = 0; i < chunk->nents; ++i)
-					put_page(chunk->page_list[i].page);
+					put_page(sg_page(&chunk->page_list[i]));
 				kfree(chunk);
 
 				ret = -ENOMEM;
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 01d7008..495c803 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -147,8 +147,12 @@
 
 	spin_lock(&ib_uverbs_idr_lock);
 	uobj = idr_find(idr, id);
-	if (uobj)
-		kref_get(&uobj->ref);
+	if (uobj) {
+		if (uobj->context == context)
+			kref_get(&uobj->ref);
+		else
+			uobj = NULL;
+	}
 	spin_unlock(&ib_uverbs_idr_lock);
 
 	return uobj;
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 3f2d68c..2d660ae 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -323,7 +323,6 @@
 extern int ehca_port_act_time;
 extern int ehca_use_hp_mr;
 extern int ehca_scaling_code;
-extern int ehca_mr_largepage;
 
 struct ipzu_queue_resp {
 	u32 qe_size;      /* queue entry size */
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index 4aa3ffa..15806d1 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -77,6 +77,7 @@
 	}
 
 	memset(props, 0, sizeof(struct ib_device_attr));
+	props->page_size_cap   = shca->hca_cap_mr_pgsize;
 	props->fw_ver          = rblock->hw_ver;
 	props->max_mr_size     = rblock->max_mr_size;
 	props->vendor_id       = rblock->vendor_id >> 8;
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index a3409fd..c6cd38c 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -65,7 +65,7 @@
 int ehca_poll_all_eqs  = 1;
 int ehca_static_rate   = -1;
 int ehca_scaling_code  = 0;
-int ehca_mr_largepage  = 0;
+int ehca_mr_largepage  = 1;
 
 module_param_named(open_aqp1,     ehca_open_aqp1,     int, S_IRUGO);
 module_param_named(debug_level,   ehca_debug_level,   int, S_IRUGO);
@@ -260,13 +260,20 @@
 	{ HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" },
 };
 
-int ehca_sense_attributes(struct ehca_shca *shca)
+static int ehca_sense_attributes(struct ehca_shca *shca)
 {
 	int i, ret = 0;
 	u64 h_ret;
 	struct hipz_query_hca *rblock;
 	struct hipz_query_port *port;
 
+	static const u32 pgsize_map[] = {
+		HCA_CAP_MR_PGSIZE_4K,  0x1000,
+		HCA_CAP_MR_PGSIZE_64K, 0x10000,
+		HCA_CAP_MR_PGSIZE_1M,  0x100000,
+		HCA_CAP_MR_PGSIZE_16M, 0x1000000,
+	};
+
 	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
 	if (!rblock) {
 		ehca_gen_err("Cannot allocate rblock memory.");
@@ -329,8 +336,15 @@
 		if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
 			ehca_gen_dbg("   %s", hca_cap_descr[i].descr);
 
-	shca->hca_cap_mr_pgsize = rblock->memory_page_size_supported;
+	/* translate supported MR page sizes; always support 4K */
+	shca->hca_cap_mr_pgsize = EHCA_PAGESIZE;
+	if (ehca_mr_largepage) { /* support extra sizes only if enabled */
+		for (i = 0; i < ARRAY_SIZE(pgsize_map); i += 2)
+			if (rblock->memory_page_size_supported & pgsize_map[i])
+				shca->hca_cap_mr_pgsize |= pgsize_map[i + 1];
+	}
 
+	/* query max MTU from first port -- it's the same for all ports */
 	port = (struct hipz_query_port *)rblock;
 	h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
 	if (h_ret != H_SUCCESS) {
@@ -579,12 +593,12 @@
 									   \
 	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);			   \
 	if (!rblock) {						           \
-		dev_err(dev, "Can't allocate rblock memory.");		   \
+		dev_err(dev, "Can't allocate rblock memory.\n");           \
 		return 0;						   \
 	}								   \
 									   \
 	if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \
-		dev_err(dev, "Can't query device properties");	   	   \
+		dev_err(dev, "Can't query device properties\n");           \
 		ehca_free_fw_ctrlblock(rblock);			   	   \
 		return 0;					   	   \
 	}								   \
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index da88738..e239bbf 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -72,24 +72,14 @@
 
 static u32 ehca_encode_hwpage_size(u32 pgsize)
 {
-	u32 idx = 0;
-	pgsize >>= 12;
-	/*
-	 * map mr page size into hw code:
-	 * 0, 1, 2, 3 for 4K, 64K, 1M, 64M
-	 */
-	while (!(pgsize & 1)) {
-		idx++;
-		pgsize >>= 4;
-	}
-	return idx;
+	int log = ilog2(pgsize);
+	WARN_ON(log < 12 || log > 24 || log & 3);
+	return (log - 12) / 4;
 }
 
 static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca)
 {
-	if (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)
-		return EHCA_MR_PGSIZE16M;
-	return EHCA_MR_PGSIZE4K;
+	return 1UL << ilog2(shca->hca_cap_mr_pgsize);
 }
 
 static struct ehca_mr *ehca_mr_new(void)
@@ -259,7 +249,7 @@
 		pginfo.u.phy.num_phys_buf = num_phys_buf;
 		pginfo.u.phy.phys_buf_array = phys_buf_array;
 		pginfo.next_hwpage =
-			((u64)iova_start & ~(hw_pgsize - 1)) / hw_pgsize;
+			((u64)iova_start & ~PAGE_MASK) / hw_pgsize;
 
 		ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags,
 				  e_pd, &pginfo, &e_mr->ib.ib_mr.lkey,
@@ -296,7 +286,7 @@
 		container_of(pd->device, struct ehca_shca, ib_device);
 	struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
 	struct ehca_mr_pginfo pginfo;
-	int ret;
+	int ret, page_shift;
 	u32 num_kpages;
 	u32 num_hwpages;
 	u64 hwpage_size;
@@ -351,19 +341,20 @@
 	/* determine number of MR pages */
 	num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE);
 	/* select proper hw_pgsize */
-	if (ehca_mr_largepage &&
-	    (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)) {
-		int page_shift = PAGE_SHIFT;
-		if (e_mr->umem->hugetlb) {
-			/* determine page_shift, clamp between 4K and 16M */
-			page_shift = (fls64(length - 1) + 3) & ~3;
-			page_shift = min(max(page_shift, EHCA_MR_PGSHIFT4K),
-					 EHCA_MR_PGSHIFT16M);
-		}
-		hwpage_size = 1UL << page_shift;
-	} else
-		hwpage_size = EHCA_MR_PGSIZE4K; /* ehca1 only supports 4k */
-	ehca_dbg(pd->device, "hwpage_size=%lx", hwpage_size);
+	page_shift = PAGE_SHIFT;
+	if (e_mr->umem->hugetlb) {
+		/* determine page_shift, clamp between 4K and 16M */
+		page_shift = (fls64(length - 1) + 3) & ~3;
+		page_shift = min(max(page_shift, EHCA_MR_PGSHIFT4K),
+				 EHCA_MR_PGSHIFT16M);
+	}
+	hwpage_size = 1UL << page_shift;
+
+	/* now that we have the desired page size, shift until it's
+	 * supported, too. 4K is always supported, so this terminates.
+	 */
+	while (!(hwpage_size & shca->hca_cap_mr_pgsize))
+		hwpage_size >>= 4;
 
 reg_user_mr_fallback:
 	num_hwpages = NUM_CHUNKS((virt % hwpage_size) + length, hwpage_size);
@@ -547,7 +538,7 @@
 		pginfo.u.phy.num_phys_buf = num_phys_buf;
 		pginfo.u.phy.phys_buf_array = phys_buf_array;
 		pginfo.next_hwpage =
-			((u64)iova_start & ~(hw_pgsize - 1)) / hw_pgsize;
+			((u64)iova_start & ~PAGE_MASK) / hw_pgsize;
 	}
 	if (mr_rereg_mask & IB_MR_REREG_ACCESS)
 		new_acl = mr_access_flags;
@@ -809,8 +800,9 @@
 		ib_fmr = ERR_PTR(-EINVAL);
 		goto alloc_fmr_exit0;
 	}
-	hw_pgsize = ehca_get_max_hwpage_size(shca);
-	if ((1 << fmr_attr->page_shift) != hw_pgsize) {
+
+	hw_pgsize = 1 << fmr_attr->page_shift;
+	if (!(hw_pgsize & shca->hca_cap_mr_pgsize)) {
 		ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x",
 			 fmr_attr->page_shift);
 		ib_fmr = ERR_PTR(-EINVAL);
@@ -826,6 +818,7 @@
 
 	/* register MR on HCA */
 	memset(&pginfo, 0, sizeof(pginfo));
+	pginfo.hwpage_size = hw_pgsize;
 	/*
 	 * pginfo.num_hwpages==0, ie register_rpages() will not be called
 	 * but deferred to map_phys_fmr()
@@ -1776,7 +1769,7 @@
 	list_for_each_entry_continue(
 		chunk, (&(pginfo->u.usr.region->chunk_list)), list) {
 		for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) {
-			pgaddr = page_to_pfn(chunk->page_list[i].page)
+			pgaddr = page_to_pfn(sg_page(&chunk->page_list[i]))
 				<< PAGE_SHIFT ;
 			*kpage = phys_to_abs(pgaddr +
 					     (pginfo->next_hwpage *
@@ -1832,7 +1825,7 @@
 {
 	int t;
 	for (t = start_idx; t <= end_idx; t++) {
-		u64 pgaddr = page_to_pfn(page_list[t].page) << PAGE_SHIFT;
+		u64 pgaddr = page_to_pfn(sg_page(&page_list[t])) << PAGE_SHIFT;
 		ehca_gen_dbg("chunk_page=%lx value=%016lx", pgaddr,
 			     *(u64 *)abs_to_virt(phys_to_abs(pgaddr)));
 		if (pgaddr - PAGE_SIZE != *prev_pgaddr) {
@@ -1867,7 +1860,7 @@
 		chunk, (&(pginfo->u.usr.region->chunk_list)), list) {
 		for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) {
 			if (nr_kpages == kpages_per_hwpage) {
-				pgaddr = ( page_to_pfn(chunk->page_list[i].page)
+				pgaddr = ( page_to_pfn(sg_page(&chunk->page_list[i]))
 					   << PAGE_SHIFT );
 				*kpage = phys_to_abs(pgaddr);
 				if ( !(*kpage) ) {
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index e2bd62b..de18264 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -451,7 +451,6 @@
 		has_srq = 1;
 		parms.ext_type = EQPT_SRQBASE;
 		parms.srq_qpn = my_srq->real_qp_num;
-		parms.srq_token = my_srq->token;
 	}
 
 	if (is_llqp && has_srq) {
@@ -583,6 +582,9 @@
 		goto create_qp_exit1;
 	}
 
+	if (has_srq)
+		parms.srq_token = my_qp->token;
+
 	parms.servicetype = ibqptype2servicetype(qp_type);
 	if (parms.servicetype < 0) {
 		ret = -EINVAL;
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index 22709a4..e90a0ea 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -108,7 +108,7 @@
 	BUG_ON(!valid_dma_direction(direction));
 
 	for_each_sg(sgl, sg, nents, i) {
-		addr = (u64) page_address(sg->page);
+		addr = (u64) page_address(sg_page(sg));
 		/* TODO: handle highmem pages */
 		if (!addr) {
 			ret = 0;
@@ -127,7 +127,7 @@
 
 static u64 ipath_sg_dma_address(struct ib_device *dev, struct scatterlist *sg)
 {
-	u64 addr = (u64) page_address(sg->page);
+	u64 addr = (u64) page_address(sg_page(sg));
 
 	if (addr)
 		addr += sg->offset;
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c
index e442470..db4ba92 100644
--- a/drivers/infiniband/hw/ipath/ipath_mr.c
+++ b/drivers/infiniband/hw/ipath/ipath_mr.c
@@ -225,7 +225,7 @@
 		for (i = 0; i < chunk->nents; i++) {
 			void *vaddr;
 
-			vaddr = page_address(chunk->page_list[i].page);
+			vaddr = page_address(sg_page(&chunk->page_list[i]));
 			if (!vaddr) {
 				ret = ERR_PTR(-EINVAL);
 				goto bail;
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 31a480e..6b33224 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -63,6 +63,10 @@
 	u8			header_buf[MLX4_IB_UD_HEADER_SIZE];
 };
 
+enum {
+	MLX4_IB_MIN_SQ_STRIDE = 6
+};
+
 static const __be32 mlx4_ib_opcode[] = {
 	[IB_WR_SEND]			= __constant_cpu_to_be32(MLX4_OPCODE_SEND),
 	[IB_WR_SEND_WITH_IMM]		= __constant_cpu_to_be32(MLX4_OPCODE_SEND_IMM),
@@ -285,9 +289,17 @@
 	return 0;
 }
 
-static int set_user_sq_size(struct mlx4_ib_qp *qp,
+static int set_user_sq_size(struct mlx4_ib_dev *dev,
+			    struct mlx4_ib_qp *qp,
 			    struct mlx4_ib_create_qp *ucmd)
 {
+	/* Sanity check SQ size before proceeding */
+	if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes	 ||
+	    ucmd->log_sq_stride >
+		ilog2(roundup_pow_of_two(dev->dev->caps.max_sq_desc_sz)) ||
+	    ucmd->log_sq_stride < MLX4_IB_MIN_SQ_STRIDE)
+		return -EINVAL;
+
 	qp->sq.wqe_cnt   = 1 << ucmd->log_sq_bb_count;
 	qp->sq.wqe_shift = ucmd->log_sq_stride;
 
@@ -330,7 +342,7 @@
 
 		qp->sq_no_prefetch = ucmd.sq_no_prefetch;
 
-		err = set_user_sq_size(qp, &ucmd);
+		err = set_user_sq_size(dev, qp, &ucmd);
 		if (err)
 			goto err;
 
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index be6e1e0..6bd9f13 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -204,16 +204,11 @@
 static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq,
 				     int incr)
 {
-	__be32 doorbell[2];
-
 	if (mthca_is_memfree(dev)) {
 		*cq->set_ci_db = cpu_to_be32(cq->cons_index);
 		wmb();
 	} else {
-		doorbell[0] = cpu_to_be32(MTHCA_TAVOR_CQ_DB_INC_CI | cq->cqn);
-		doorbell[1] = cpu_to_be32(incr - 1);
-
-		mthca_write64(doorbell,
+		mthca_write64(MTHCA_TAVOR_CQ_DB_INC_CI | cq->cqn, incr - 1,
 			      dev->kar + MTHCA_CQ_DOORBELL,
 			      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 		/*
@@ -731,17 +726,12 @@
 
 int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags)
 {
-	__be32 doorbell[2];
+	u32 dbhi = ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
+		    MTHCA_TAVOR_CQ_DB_REQ_NOT_SOL :
+		    MTHCA_TAVOR_CQ_DB_REQ_NOT) |
+		to_mcq(cq)->cqn;
 
-	doorbell[0] = cpu_to_be32(((flags & IB_CQ_SOLICITED_MASK) ==
-				   IB_CQ_SOLICITED ?
-				   MTHCA_TAVOR_CQ_DB_REQ_NOT_SOL :
-				   MTHCA_TAVOR_CQ_DB_REQ_NOT)      |
-				  to_mcq(cq)->cqn);
-	doorbell[1] = (__force __be32) 0xffffffff;
-
-	mthca_write64(doorbell,
-		      to_mdev(cq->device)->kar + MTHCA_CQ_DOORBELL,
+	mthca_write64(dbhi, 0xffffffff, to_mdev(cq->device)->kar + MTHCA_CQ_DOORBELL,
 		      MTHCA_GET_DOORBELL_LOCK(&to_mdev(cq->device)->doorbell_lock));
 
 	return 0;
@@ -750,19 +740,16 @@
 int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
 {
 	struct mthca_cq *cq = to_mcq(ibcq);
-	__be32 doorbell[2];
-	u32 sn;
-	__be32 ci;
+	__be32 db_rec[2];
+	u32 dbhi;
+	u32 sn = cq->arm_sn & 3;
 
-	sn = cq->arm_sn & 3;
-	ci = cpu_to_be32(cq->cons_index);
+	db_rec[0] = cpu_to_be32(cq->cons_index);
+	db_rec[1] = cpu_to_be32((cq->cqn << 8) | (2 << 5) | (sn << 3) |
+				((flags & IB_CQ_SOLICITED_MASK) ==
+				 IB_CQ_SOLICITED ? 1 : 2));
 
-	doorbell[0] = ci;
-	doorbell[1] = cpu_to_be32((cq->cqn << 8) | (2 << 5) | (sn << 3) |
-				  ((flags & IB_CQ_SOLICITED_MASK) ==
-				   IB_CQ_SOLICITED ? 1 : 2));
-
-	mthca_write_db_rec(doorbell, cq->arm_db);
+	mthca_write_db_rec(db_rec, cq->arm_db);
 
 	/*
 	 * Make sure that the doorbell record in host memory is
@@ -770,14 +757,12 @@
 	 */
 	wmb();
 
-	doorbell[0] = cpu_to_be32((sn << 28)                       |
-				  ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
-				   MTHCA_ARBEL_CQ_DB_REQ_NOT_SOL :
-				   MTHCA_ARBEL_CQ_DB_REQ_NOT)      |
-				  cq->cqn);
-	doorbell[1] = ci;
+	dbhi = (sn << 28) |
+		((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
+		 MTHCA_ARBEL_CQ_DB_REQ_NOT_SOL :
+		 MTHCA_ARBEL_CQ_DB_REQ_NOT) | cq->cqn;
 
-	mthca_write64(doorbell,
+	mthca_write64(dbhi, cq->cons_index,
 		      to_mdev(ibcq->device)->kar + MTHCA_CQ_DOORBELL,
 		      MTHCA_GET_DOORBELL_LOCK(&to_mdev(ibcq->device)->doorbell_lock));
 
diff --git a/drivers/infiniband/hw/mthca/mthca_doorbell.h b/drivers/infiniband/hw/mthca/mthca_doorbell.h
index dd9a44d..b374dc3 100644
--- a/drivers/infiniband/hw/mthca/mthca_doorbell.h
+++ b/drivers/infiniband/hw/mthca/mthca_doorbell.h
@@ -58,10 +58,10 @@
 	__raw_writeq((__force u64) val, dest);
 }
 
-static inline void mthca_write64(__be32 val[2], void __iomem *dest,
+static inline void mthca_write64(u32 hi, u32 lo, void __iomem *dest,
 				 spinlock_t *doorbell_lock)
 {
-	__raw_writeq(*(u64 *) val, dest);
+	__raw_writeq((__force u64) cpu_to_be64((u64) hi << 32 | lo), dest);
 }
 
 static inline void mthca_write_db_rec(__be32 val[2], __be32 *db)
@@ -87,14 +87,17 @@
 	__raw_writel(((__force u32 *) &val)[1], dest + 4);
 }
 
-static inline void mthca_write64(__be32 val[2], void __iomem *dest,
+static inline void mthca_write64(u32 hi, u32 lo, void __iomem *dest,
 				 spinlock_t *doorbell_lock)
 {
 	unsigned long flags;
 
+	hi = (__force u32) cpu_to_be32(hi);
+	lo = (__force u32) cpu_to_be32(lo);
+
 	spin_lock_irqsave(doorbell_lock, flags);
-	__raw_writel((__force u32) val[0], dest);
-	__raw_writel((__force u32) val[1], dest + 4);
+	__raw_writel(hi, dest);
+	__raw_writel(lo, dest + 4);
 	spin_unlock_irqrestore(doorbell_lock, flags);
 }
 
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index 8592b26..b29de51 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -173,11 +173,6 @@
 
 static inline void tavor_set_eq_ci(struct mthca_dev *dev, struct mthca_eq *eq, u32 ci)
 {
-	__be32 doorbell[2];
-
-	doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_SET_CI | eq->eqn);
-	doorbell[1] = cpu_to_be32(ci & (eq->nent - 1));
-
 	/*
 	 * This barrier makes sure that all updates to ownership bits
 	 * done by set_eqe_hw() hit memory before the consumer index
@@ -187,7 +182,7 @@
 	 * having set_eqe_hw() overwrite the owner field.
 	 */
 	wmb();
-	mthca_write64(doorbell,
+	mthca_write64(MTHCA_EQ_DB_SET_CI | eq->eqn, ci & (eq->nent - 1),
 		      dev->kar + MTHCA_EQ_DOORBELL,
 		      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 }
@@ -212,12 +207,7 @@
 
 static inline void tavor_eq_req_not(struct mthca_dev *dev, int eqn)
 {
-	__be32 doorbell[2];
-
-	doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_REQ_NOT | eqn);
-	doorbell[1] = 0;
-
-	mthca_write64(doorbell,
+	mthca_write64(MTHCA_EQ_DB_REQ_NOT | eqn, 0,
 		      dev->kar + MTHCA_EQ_DOORBELL,
 		      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 }
@@ -230,12 +220,7 @@
 static inline void disarm_cq(struct mthca_dev *dev, int eqn, int cqn)
 {
 	if (!mthca_is_memfree(dev)) {
-		__be32 doorbell[2];
-
-		doorbell[0] = cpu_to_be32(MTHCA_EQ_DB_DISARM_CQ | eqn);
-		doorbell[1] = cpu_to_be32(cqn);
-
-		mthca_write64(doorbell,
+		mthca_write64(MTHCA_EQ_DB_DISARM_CQ | eqn, cqn,
 			      dev->kar + MTHCA_EQ_DOORBELL,
 			      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 	}
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index e61f3e6..007b381 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -71,7 +71,7 @@
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(chunk->mem[i].page,
+		__free_pages(sg_page(&chunk->mem[i]),
 			     get_order(chunk->mem[i].length));
 }
 
@@ -81,7 +81,7 @@
 
 	for (i = 0; i < chunk->npages; ++i) {
 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-				  lowmem_page_address(chunk->mem[i].page),
+				  lowmem_page_address(sg_page(&chunk->mem[i])),
 				  sg_dma_address(&chunk->mem[i]));
 	}
 }
@@ -107,10 +107,13 @@
 
 static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-	mem->page = alloc_pages(gfp_mask, order);
-	if (!mem->page)
+	struct page *page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
 		return -ENOMEM;
 
+	sg_set_page(mem, page);
 	mem->length = PAGE_SIZE << order;
 	mem->offset = 0;
 	return 0;
@@ -157,6 +160,7 @@
 			if (!chunk)
 				goto fail;
 
+			sg_init_table(chunk->mem, MTHCA_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
 			list_add_tail(&chunk->list, &icm->chunk_list);
@@ -304,7 +308,7 @@
 			 * so if we found the page, dma_handle has already
 			 * been assigned to. */
 			if (chunk->mem[i].length > offset) {
-				page = chunk->mem[i].page;
+				page = sg_page(&chunk->mem[i]);
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
@@ -445,6 +449,7 @@
 int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
 		      struct mthca_user_db_table *db_tab, int index, u64 uaddr)
 {
+	struct page *pages[1];
 	int ret = 0;
 	u8 status;
 	int i;
@@ -472,16 +477,17 @@
 	}
 
 	ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
-			     &db_tab->page[i].mem.page, NULL);
+			     pages, NULL);
 	if (ret < 0)
 		goto out;
 
+	sg_set_page(&db_tab->page[i].mem, pages[0]);
 	db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE;
 	db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
 
 	ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
 	if (ret < 0) {
-		put_page(db_tab->page[i].mem.page);
+		put_page(pages[0]);
 		goto out;
 	}
 
@@ -491,7 +497,7 @@
 		ret = -EINVAL;
 	if (ret) {
 		pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-		put_page(db_tab->page[i].mem.page);
+		put_page(sg_page(&db_tab->page[i].mem));
 		goto out;
 	}
 
@@ -557,7 +563,7 @@
 		if (db_tab->page[i].uvirt) {
 			mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
 			pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
-			put_page(db_tab->page[i].mem.page);
+			put_page(sg_page(&db_tab->page[i].mem));
 		}
 	}
 
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index df01b20..0e5461c 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1799,15 +1799,11 @@
 
 out:
 	if (likely(nreq)) {
-		__be32 doorbell[2];
-
-		doorbell[0] = cpu_to_be32(((qp->sq.next_ind << qp->sq.wqe_shift) +
-					   qp->send_wqe_offset) | f0 | op0);
-		doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);
-
 		wmb();
 
-		mthca_write64(doorbell,
+		mthca_write64(((qp->sq.next_ind << qp->sq.wqe_shift) +
+			       qp->send_wqe_offset) | f0 | op0,
+			      (qp->qpn << 8) | size0,
 			      dev->kar + MTHCA_SEND_DOORBELL,
 			      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 		/*
@@ -1829,7 +1825,6 @@
 {
 	struct mthca_dev *dev = to_mdev(ibqp->device);
 	struct mthca_qp *qp = to_mqp(ibqp);
-	__be32 doorbell[2];
 	unsigned long flags;
 	int err = 0;
 	int nreq;
@@ -1907,13 +1902,10 @@
 		if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
 			nreq = 0;
 
-			doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
-			doorbell[1] = cpu_to_be32(qp->qpn << 8);
-
 			wmb();
 
-			mthca_write64(doorbell,
-				      dev->kar + MTHCA_RECEIVE_DOORBELL,
+			mthca_write64((qp->rq.next_ind << qp->rq.wqe_shift) | size0,
+				      qp->qpn << 8, dev->kar + MTHCA_RECEIVE_DOORBELL,
 				      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 
 			qp->rq.next_ind = ind;
@@ -1923,13 +1915,10 @@
 
 out:
 	if (likely(nreq)) {
-		doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
-		doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq);
-
 		wmb();
 
-		mthca_write64(doorbell,
-			      dev->kar + MTHCA_RECEIVE_DOORBELL,
+		mthca_write64((qp->rq.next_ind << qp->rq.wqe_shift) | size0,
+			      qp->qpn << 8 | nreq, dev->kar + MTHCA_RECEIVE_DOORBELL,
 			      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 	}
 
@@ -1951,7 +1940,7 @@
 {
 	struct mthca_dev *dev = to_mdev(ibqp->device);
 	struct mthca_qp *qp = to_mqp(ibqp);
-	__be32 doorbell[2];
+	u32 dbhi;
 	void *wqe;
 	void *prev_wqe;
 	unsigned long flags;
@@ -1981,10 +1970,8 @@
 		if (unlikely(nreq == MTHCA_ARBEL_MAX_WQES_PER_SEND_DB)) {
 			nreq = 0;
 
-			doorbell[0] = cpu_to_be32((MTHCA_ARBEL_MAX_WQES_PER_SEND_DB << 24) |
-						  ((qp->sq.head & 0xffff) << 8) |
-						  f0 | op0);
-			doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);
+			dbhi = (MTHCA_ARBEL_MAX_WQES_PER_SEND_DB << 24) |
+				((qp->sq.head & 0xffff) << 8) | f0 | op0;
 
 			qp->sq.head += MTHCA_ARBEL_MAX_WQES_PER_SEND_DB;
 
@@ -2000,7 +1987,8 @@
 			 * write MMIO send doorbell.
 			 */
 			wmb();
-			mthca_write64(doorbell,
+
+			mthca_write64(dbhi, (qp->qpn << 8) | size0,
 				      dev->kar + MTHCA_SEND_DOORBELL,
 				      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 		}
@@ -2154,10 +2142,7 @@
 
 out:
 	if (likely(nreq)) {
-		doorbell[0] = cpu_to_be32((nreq << 24)                  |
-					  ((qp->sq.head & 0xffff) << 8) |
-					  f0 | op0);
-		doorbell[1] = cpu_to_be32((qp->qpn << 8) | size0);
+		dbhi = (nreq << 24) | ((qp->sq.head & 0xffff) << 8) | f0 | op0;
 
 		qp->sq.head += nreq;
 
@@ -2173,8 +2158,8 @@
 		 * write MMIO send doorbell.
 		 */
 		wmb();
-		mthca_write64(doorbell,
-			      dev->kar + MTHCA_SEND_DOORBELL,
+
+		mthca_write64(dbhi, (qp->qpn << 8) | size0, dev->kar + MTHCA_SEND_DOORBELL,
 			      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 	}
 
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 3f58c11..553d681 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -491,7 +491,6 @@
 {
 	struct mthca_dev *dev = to_mdev(ibsrq->device);
 	struct mthca_srq *srq = to_msrq(ibsrq);
-	__be32 doorbell[2];
 	unsigned long flags;
 	int err = 0;
 	int first_ind;
@@ -563,16 +562,13 @@
 		if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
 			nreq = 0;
 
-			doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
-			doorbell[1] = cpu_to_be32(srq->srqn << 8);
-
 			/*
 			 * Make sure that descriptors are written
 			 * before doorbell is rung.
 			 */
 			wmb();
 
-			mthca_write64(doorbell,
+			mthca_write64(first_ind << srq->wqe_shift, srq->srqn << 8,
 				      dev->kar + MTHCA_RECEIVE_DOORBELL,
 				      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 
@@ -581,16 +577,13 @@
 	}
 
 	if (likely(nreq)) {
-		doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
-		doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq);
-
 		/*
 		 * Make sure that descriptors are written before
 		 * doorbell is rung.
 		 */
 		wmb();
 
-		mthca_write64(doorbell,
+		mthca_write64(first_ind << srq->wqe_shift, (srq->srqn << 8) | nreq,
 			      dev->kar + MTHCA_RECEIVE_DOORBELL,
 			      MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
 	}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 1b3327a..eb7edab 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -84,9 +84,8 @@
 	IPOIB_MCAST_RUN 	  = 6,
 	IPOIB_STOP_REAPER         = 7,
 	IPOIB_MCAST_STARTED       = 8,
-	IPOIB_FLAG_NETIF_STOPPED  = 9,
-	IPOIB_FLAG_ADMIN_CM 	  = 10,
-	IPOIB_FLAG_UMCAST	  = 11,
+	IPOIB_FLAG_ADMIN_CM 	  = 9,
+	IPOIB_FLAG_UMCAST	  = 10,
 
 	IPOIB_MAX_BACKOFF_SECONDS = 16,
 
@@ -98,9 +97,9 @@
 
 #define	IPOIB_OP_RECV   (1ul << 31)
 #ifdef CONFIG_INFINIBAND_IPOIB_CM
-#define	IPOIB_CM_OP_SRQ (1ul << 30)
+#define	IPOIB_OP_CM     (1ul << 30)
 #else
-#define	IPOIB_CM_OP_SRQ (0)
+#define	IPOIB_OP_CM     (0)
 #endif
 
 /* structs */
@@ -197,7 +196,6 @@
 
 struct ipoib_cm_tx {
 	struct ib_cm_id     *id;
-	struct ib_cq        *cq;
 	struct ib_qp        *qp;
 	struct list_head     list;
 	struct net_device   *dev;
@@ -294,6 +292,7 @@
 	unsigned             tx_tail;
 	struct ib_sge        tx_sge;
 	struct ib_send_wr    tx_wr;
+	unsigned             tx_outstanding;
 
 	struct ib_wc ibwc[IPOIB_NUM_WC];
 
@@ -504,6 +503,7 @@
 void ipoib_cm_skb_too_long(struct net_device* dev, struct sk_buff *skb,
 			   unsigned int mtu);
 void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc);
+void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc);
 #else
 
 struct ipoib_cm_tx;
@@ -592,6 +592,9 @@
 {
 }
 
+static inline void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
+{
+}
 #endif
 
 #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 0a0dcb8..8761077 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -87,7 +87,7 @@
 	struct ib_recv_wr *bad_wr;
 	int i, ret;
 
-	priv->cm.rx_wr.wr_id = id | IPOIB_CM_OP_SRQ;
+	priv->cm.rx_wr.wr_id = id | IPOIB_OP_CM | IPOIB_OP_RECV;
 
 	for (i = 0; i < IPOIB_CM_RX_SG; ++i)
 		priv->cm.rx_sge[i].addr = priv->cm.srq_ring[id].mapping[i];
@@ -401,7 +401,7 @@
 void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
-	unsigned int wr_id = wc->wr_id & ~IPOIB_CM_OP_SRQ;
+	unsigned int wr_id = wc->wr_id & ~(IPOIB_OP_CM | IPOIB_OP_RECV);
 	struct sk_buff *skb, *newskb;
 	struct ipoib_cm_rx *p;
 	unsigned long flags;
@@ -412,7 +412,7 @@
 		       wr_id, wc->status);
 
 	if (unlikely(wr_id >= ipoib_recvq_size)) {
-		if (wr_id == (IPOIB_CM_RX_DRAIN_WRID & ~IPOIB_CM_OP_SRQ)) {
+		if (wr_id == (IPOIB_CM_RX_DRAIN_WRID & ~(IPOIB_OP_CM | IPOIB_OP_RECV))) {
 			spin_lock_irqsave(&priv->lock, flags);
 			list_splice_init(&priv->cm.rx_drain_list, &priv->cm.rx_reap_list);
 			ipoib_cm_start_rx_drain(priv);
@@ -434,7 +434,7 @@
 		goto repost;
 	}
 
-	if (!likely(wr_id & IPOIB_CM_RX_UPDATE_MASK)) {
+	if (unlikely(!(wr_id & IPOIB_CM_RX_UPDATE_MASK))) {
 		p = wc->qp->qp_context;
 		if (p && time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_UPDATE_TIME)) {
 			spin_lock_irqsave(&priv->lock, flags);
@@ -498,7 +498,7 @@
 	priv->tx_sge.addr             = addr;
 	priv->tx_sge.length           = len;
 
-	priv->tx_wr.wr_id 	      = wr_id;
+	priv->tx_wr.wr_id 	      = wr_id | IPOIB_OP_CM;
 
 	return ib_post_send(tx->qp, &priv->tx_wr, &bad_wr);
 }
@@ -549,20 +549,19 @@
 		dev->trans_start = jiffies;
 		++tx->tx_head;
 
-		if (tx->tx_head - tx->tx_tail == ipoib_sendq_size) {
+		if (++priv->tx_outstanding == ipoib_sendq_size) {
 			ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n",
 				  tx->qp->qp_num);
 			netif_stop_queue(dev);
-			set_bit(IPOIB_FLAG_NETIF_STOPPED, &tx->flags);
 		}
 	}
 }
 
-static void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ipoib_cm_tx *tx,
-				  struct ib_wc *wc)
+void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
-	unsigned int wr_id = wc->wr_id;
+	struct ipoib_cm_tx *tx = wc->qp->qp_context;
+	unsigned int wr_id = wc->wr_id & ~IPOIB_OP_CM;
 	struct ipoib_tx_buf *tx_req;
 	unsigned long flags;
 
@@ -587,11 +586,10 @@
 
 	spin_lock_irqsave(&priv->tx_lock, flags);
 	++tx->tx_tail;
-	if (unlikely(test_bit(IPOIB_FLAG_NETIF_STOPPED, &tx->flags)) &&
-	    tx->tx_head - tx->tx_tail <= ipoib_sendq_size >> 1) {
-		clear_bit(IPOIB_FLAG_NETIF_STOPPED, &tx->flags);
+	if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) &&
+	    netif_queue_stopped(dev) &&
+	    test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
 		netif_wake_queue(dev);
-	}
 
 	if (wc->status != IB_WC_SUCCESS &&
 	    wc->status != IB_WC_WR_FLUSH_ERR) {
@@ -614,11 +612,6 @@
 			tx->neigh = NULL;
 		}
 
-		/* queue would be re-started anyway when TX is destroyed,
-		 * but it makes sense to do it ASAP here. */
-		if (test_and_clear_bit(IPOIB_FLAG_NETIF_STOPPED, &tx->flags))
-			netif_wake_queue(dev);
-
 		if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) {
 			list_move(&tx->list, &priv->cm.reap_list);
 			queue_work(ipoib_workqueue, &priv->cm.reap_task);
@@ -632,19 +625,6 @@
 	spin_unlock_irqrestore(&priv->tx_lock, flags);
 }
 
-static void ipoib_cm_tx_completion(struct ib_cq *cq, void *tx_ptr)
-{
-	struct ipoib_cm_tx *tx = tx_ptr;
-	int n, i;
-
-	ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
-	do {
-		n = ib_poll_cq(cq, IPOIB_NUM_WC, tx->ibwc);
-		for (i = 0; i < n; ++i)
-			ipoib_cm_handle_tx_wc(tx->dev, tx, tx->ibwc + i);
-	} while (n == IPOIB_NUM_WC);
-}
-
 int ipoib_cm_dev_open(struct net_device *dev)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -807,17 +787,18 @@
 	return 0;
 }
 
-static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ib_cq *cq)
+static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_cm_tx *tx)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ib_qp_init_attr attr = {
-		.send_cq		= cq,
+		.send_cq		= priv->cq,
 		.recv_cq		= priv->cq,
 		.srq			= priv->cm.srq,
 		.cap.max_send_wr	= ipoib_sendq_size,
 		.cap.max_send_sge	= 1,
 		.sq_sig_type		= IB_SIGNAL_ALL_WR,
 		.qp_type		= IB_QPT_RC,
+		.qp_context		= tx
         };
 
 	return ib_create_qp(priv->pd, &attr);
@@ -899,21 +880,7 @@
 		goto err_tx;
 	}
 
-	p->cq = ib_create_cq(priv->ca, ipoib_cm_tx_completion, NULL, p,
-			     ipoib_sendq_size + 1, 0);
-	if (IS_ERR(p->cq)) {
-		ret = PTR_ERR(p->cq);
-		ipoib_warn(priv, "failed to allocate tx cq: %d\n", ret);
-		goto err_cq;
-	}
-
-	ret = ib_req_notify_cq(p->cq, IB_CQ_NEXT_COMP);
-	if (ret) {
-		ipoib_warn(priv, "failed to request completion notification: %d\n", ret);
-		goto err_req_notify;
-	}
-
-	p->qp = ipoib_cm_create_tx_qp(p->dev, p->cq);
+	p->qp = ipoib_cm_create_tx_qp(p->dev, p);
 	if (IS_ERR(p->qp)) {
 		ret = PTR_ERR(p->qp);
 		ipoib_warn(priv, "failed to allocate tx qp: %d\n", ret);
@@ -950,12 +917,8 @@
 err_id:
 	p->id = NULL;
 	ib_destroy_qp(p->qp);
-err_req_notify:
 err_qp:
 	p->qp = NULL;
-	ib_destroy_cq(p->cq);
-err_cq:
-	p->cq = NULL;
 err_tx:
 	return ret;
 }
@@ -964,6 +927,8 @@
 {
 	struct ipoib_dev_priv *priv = netdev_priv(p->dev);
 	struct ipoib_tx_buf *tx_req;
+	unsigned long flags;
+	unsigned long begin;
 
 	ipoib_dbg(priv, "Destroy active connection 0x%x head 0x%x tail 0x%x\n",
 		  p->qp ? p->qp->qp_num : 0, p->tx_head, p->tx_tail);
@@ -971,27 +936,40 @@
 	if (p->id)
 		ib_destroy_cm_id(p->id);
 
+	if (p->tx_ring) {
+		/* Wait for all sends to complete */
+		begin = jiffies;
+		while ((int) p->tx_tail - (int) p->tx_head < 0) {
+			if (time_after(jiffies, begin + 5 * HZ)) {
+				ipoib_warn(priv, "timing out; %d sends not completed\n",
+					   p->tx_head - p->tx_tail);
+				goto timeout;
+			}
+
+			msleep(1);
+		}
+	}
+
+timeout:
+
+	while ((int) p->tx_tail - (int) p->tx_head < 0) {
+		tx_req = &p->tx_ring[p->tx_tail & (ipoib_sendq_size - 1)];
+		ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len,
+				    DMA_TO_DEVICE);
+		dev_kfree_skb_any(tx_req->skb);
+		++p->tx_tail;
+		spin_lock_irqsave(&priv->tx_lock, flags);
+		if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) &&
+		    netif_queue_stopped(p->dev) &&
+		    test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
+			netif_wake_queue(p->dev);
+		spin_unlock_irqrestore(&priv->tx_lock, flags);
+	}
+
 	if (p->qp)
 		ib_destroy_qp(p->qp);
 
-	if (p->cq)
-		ib_destroy_cq(p->cq);
-
-	if (test_bit(IPOIB_FLAG_NETIF_STOPPED, &p->flags))
-		netif_wake_queue(p->dev);
-
-	if (p->tx_ring) {
-		while ((int) p->tx_tail - (int) p->tx_head < 0) {
-			tx_req = &p->tx_ring[p->tx_tail & (ipoib_sendq_size - 1)];
-			ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len,
-					 DMA_TO_DEVICE);
-			dev_kfree_skb_any(tx_req->skb);
-			++p->tx_tail;
-		}
-
-		kfree(p->tx_ring);
-	}
-
+	kfree(p->tx_ring);
 	kfree(p);
 }
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 1a77e79..5063dd5 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -267,11 +267,10 @@
 
 	spin_lock_irqsave(&priv->tx_lock, flags);
 	++priv->tx_tail;
-	if (unlikely(test_bit(IPOIB_FLAG_NETIF_STOPPED, &priv->flags)) &&
-	    priv->tx_head - priv->tx_tail <= ipoib_sendq_size >> 1) {
-		clear_bit(IPOIB_FLAG_NETIF_STOPPED, &priv->flags);
+	if (unlikely(--priv->tx_outstanding == ipoib_sendq_size >> 1) &&
+	    netif_queue_stopped(dev) &&
+	    test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
 		netif_wake_queue(dev);
-	}
 	spin_unlock_irqrestore(&priv->tx_lock, flags);
 
 	if (wc->status != IB_WC_SUCCESS &&
@@ -301,14 +300,18 @@
 		for (i = 0; i < n; i++) {
 			struct ib_wc *wc = priv->ibwc + i;
 
-			if (wc->wr_id & IPOIB_CM_OP_SRQ) {
+			if (wc->wr_id & IPOIB_OP_RECV) {
 				++done;
-				ipoib_cm_handle_rx_wc(dev, wc);
-			} else if (wc->wr_id & IPOIB_OP_RECV) {
-				++done;
-				ipoib_ib_handle_rx_wc(dev, wc);
-			} else
-				ipoib_ib_handle_tx_wc(dev, wc);
+				if (wc->wr_id & IPOIB_OP_CM)
+					ipoib_cm_handle_rx_wc(dev, wc);
+				else
+					ipoib_ib_handle_rx_wc(dev, wc);
+			} else {
+				if (wc->wr_id & IPOIB_OP_CM)
+					ipoib_cm_handle_tx_wc(dev, wc);
+				else
+					ipoib_ib_handle_tx_wc(dev, wc);
+			}
 		}
 
 		if (n != t)
@@ -401,10 +404,9 @@
 		address->last_send = priv->tx_head;
 		++priv->tx_head;
 
-		if (priv->tx_head - priv->tx_tail == ipoib_sendq_size) {
+		if (++priv->tx_outstanding == ipoib_sendq_size) {
 			ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");
 			netif_stop_queue(dev);
-			set_bit(IPOIB_FLAG_NETIF_STOPPED, &priv->flags);
 		}
 	}
 }
@@ -436,7 +438,8 @@
 	__ipoib_reap_ah(dev);
 
 	if (!test_bit(IPOIB_STOP_REAPER, &priv->flags))
-		queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ);
+		queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task,
+				   round_jiffies_relative(HZ));
 }
 
 int ipoib_ib_dev_open(struct net_device *dev)
@@ -472,7 +475,8 @@
 	}
 
 	clear_bit(IPOIB_STOP_REAPER, &priv->flags);
-	queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, HZ);
+	queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task,
+			   round_jiffies_relative(HZ));
 
 	set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
 
@@ -561,12 +565,17 @@
 			if (priv->ibwc[i].status == IB_WC_SUCCESS)
 				priv->ibwc[i].status = IB_WC_WR_FLUSH_ERR;
 
-			if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
-				ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
-			else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
-				ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
-			else
-				ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
+			if (priv->ibwc[i].wr_id & IPOIB_OP_RECV) {
+				if (priv->ibwc[i].wr_id & IPOIB_OP_CM)
+					ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
+				else
+					ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
+			} else {
+				if (priv->ibwc[i].wr_id & IPOIB_OP_CM)
+					ipoib_cm_handle_tx_wc(dev, priv->ibwc + i);
+				else
+					ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
+			}
 		}
 	} while (n == IPOIB_NUM_WC);
 }
@@ -612,6 +621,7 @@
 						    DMA_TO_DEVICE);
 				dev_kfree_skb_any(tx_req->skb);
 				++priv->tx_tail;
+				--priv->tx_outstanding;
 			}
 
 			for (i = 0; i < ipoib_recvq_size; ++i) {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 362610d..a03a65e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -148,8 +148,6 @@
 
 	netif_stop_queue(dev);
 
-	clear_bit(IPOIB_FLAG_NETIF_STOPPED, &priv->flags);
-
 	/*
 	 * Now flush workqueue to make sure a scheduled task doesn't
 	 * bring our internal state back up.
@@ -902,7 +900,7 @@
 		goto out_rx_ring_cleanup;
 	}
 
-	/* priv->tx_head & tx_tail are already 0 */
+	/* priv->tx_head, tx_tail & tx_outstanding are already 0 */
 
 	if (ipoib_ib_dev_init(dev, ca, port))
 		goto out_tx_ring_cleanup;
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index f3529b6..d687980 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -131,7 +131,7 @@
 
 		p = mem;
 		for_each_sg(sgl, sg, data->size, i) {
-			from = kmap_atomic(sg->page, KM_USER0);
+			from = kmap_atomic(sg_page(sg), KM_USER0);
 			memcpy(p,
 			       from + sg->offset,
 			       sg->length);
@@ -191,7 +191,7 @@
 
 		p = mem;
 		for_each_sg(sgl, sg, sg_size, i) {
-			to = kmap_atomic(sg->page, KM_SOFTIRQ0);
+			to = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
 			memcpy(to + sg->offset,
 			       p,
 			       sg->length);
@@ -300,7 +300,7 @@
 	for_each_sg(sgl, sg, data->dma_nents, i) {
 		/* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX "
 		   "offset: %ld sz: %ld\n", i,
-		   (unsigned long)page_to_phys(sg->page),
+		   (unsigned long)sg_phys(sg),
 		   (unsigned long)sg->offset,
 		   (unsigned long)sg->length); */
 		end_addr = ib_sg_dma_address(ibdev, sg) +
@@ -336,7 +336,7 @@
 		iser_err("sg[%d] dma_addr:0x%lX page:0x%p "
 			 "off:0x%x sz:0x%x dma_len:0x%x\n",
 			 i, (unsigned long)ib_sg_dma_address(ibdev, sg),
-			 sg->page, sg->offset,
+			 sg_page(sg), sg->offset,
 			 sg->length, ib_sg_dma_len(ibdev, sg));
 }
 
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 1d62c8b..e5b4e9b 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -495,7 +495,7 @@
 #ifdef CONFIG_COMPAT
 
 #define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)
-#define NBITS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1)
+#define BITS_TO_LONGS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1)
 
 #ifdef __BIG_ENDIAN
 static int bits_to_user(unsigned long *bits, unsigned int maxbit,
@@ -504,7 +504,7 @@
 	int len, i;
 
 	if (compat) {
-		len = NBITS_COMPAT(maxbit) * sizeof(compat_long_t);
+		len = BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t);
 		if (len > maxlen)
 			len = maxlen;
 
@@ -515,7 +515,7 @@
 					 sizeof(compat_long_t)))
 				return -EFAULT;
 	} else {
-		len = NBITS(maxbit) * sizeof(long);
+		len = BITS_TO_LONGS(maxbit) * sizeof(long);
 		if (len > maxlen)
 			len = maxlen;
 
@@ -530,8 +530,8 @@
 			unsigned int maxlen, void __user *p, int compat)
 {
 	int len = compat ?
-			NBITS_COMPAT(maxbit) * sizeof(compat_long_t) :
-			NBITS(maxbit) * sizeof(long);
+			BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t) :
+			BITS_TO_LONGS(maxbit) * sizeof(long);
 
 	if (len > maxlen)
 		len = maxlen;
@@ -545,7 +545,7 @@
 static int bits_to_user(unsigned long *bits, unsigned int maxbit,
 			unsigned int maxlen, void __user *p, int compat)
 {
-	int len = NBITS(maxbit) * sizeof(long);
+	int len = BITS_TO_LONGS(maxbit) * sizeof(long);
 
 	if (len > maxlen)
 		len = maxlen;
diff --git a/drivers/input/fixp-arith.h b/drivers/input/fixp-arith.h
index ed3d2da..3089d73 100644
--- a/drivers/input/fixp-arith.h
+++ b/drivers/input/fixp-arith.h
@@ -24,7 +24,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <deneux@ifrance.com>
+ * e-mail - mail your message to <johann.deneux@gmail.com>
  */
 
 #include <linux/types.h>
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 20896d5..bfc6061 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -136,7 +136,8 @@
 	}
 
 	gameport_close(gameport);
-	return (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx);
+	return (cpu_data(raw_smp_processor_id()).loops_per_jiffy *
+		(unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx);
 
 #else
 
@@ -448,9 +449,8 @@
 	set_freezable();
 	do {
 		gameport_handle_event();
-		wait_event_interruptible(gameport_wait,
+		wait_event_freezable(gameport_wait,
 			kthread_should_stop() || !list_empty(&gameport_event_list));
-		try_to_freeze();
 	} while (!kthread_should_stop());
 
 	printk(KERN_DEBUG "gameport: kgameportd exiting\n");
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 2f2b020..307c7b5 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -584,10 +584,10 @@
 
 
 #define MATCH_BIT(bit, max) \
-		for (i = 0; i < NBITS(max); i++) \
+		for (i = 0; i < BITS_TO_LONGS(max); i++) \
 			if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \
 				break; \
-		if (i != NBITS(max)) \
+		if (i != BITS_TO_LONGS(max)) \
 			continue;
 
 static const struct input_device_id *input_match_device(const struct input_device_id *id,
@@ -698,7 +698,7 @@
 {
 	int i;
 
-	for (i = NBITS(max) - 1; i > 0; i--)
+	for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)
 		if (bitmap[i])
 			break;
 
@@ -892,7 +892,7 @@
 
 	len += snprintf(buf, max(size, 0), "%c", name);
 	for (i = min_bit; i < max_bit; i++)
-		if (bm[LONG(i)] & BIT(i))
+		if (bm[BIT_WORD(i)] & BIT_MASK(i))
 			len += snprintf(buf + len, max(size - len, 0), "%X,", i);
 	return len;
 }
@@ -991,7 +991,7 @@
 	int i;
 	int len = 0;
 
-	for (i = NBITS(max) - 1; i > 0; i--)
+	for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)
 		if (bitmap[i])
 			break;
 
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 2b201f9..22b2789 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -844,8 +844,8 @@
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 				INPUT_DEVICE_ID_MATCH_KEYBIT,
-		.evbit = { BIT(EV_KEY) },
-		.keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
+		.evbit = { BIT_MASK(EV_KEY) },
+		.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
 	},	/* Avoid itouchpads, touchscreens and tablets */
 	{ }	/* Terminating entry */
 };
@@ -854,20 +854,20 @@
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 				INPUT_DEVICE_ID_MATCH_ABSBIT,
-		.evbit = { BIT(EV_ABS) },
-		.absbit = { BIT(ABS_X) },
+		.evbit = { BIT_MASK(EV_ABS) },
+		.absbit = { BIT_MASK(ABS_X) },
 	},
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 				INPUT_DEVICE_ID_MATCH_ABSBIT,
-		.evbit = { BIT(EV_ABS) },
-		.absbit = { BIT(ABS_WHEEL) },
+		.evbit = { BIT_MASK(EV_ABS) },
+		.absbit = { BIT_MASK(ABS_WHEEL) },
 	},
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 				INPUT_DEVICE_ID_MATCH_ABSBIT,
-		.evbit = { BIT(EV_ABS) },
-		.absbit = { BIT(ABS_THROTTLE) },
+		.evbit = { BIT_MASK(EV_ABS) },
+		.absbit = { BIT_MASK(ABS_THROTTLE) },
 	},
 	{ }	/* Terminating entry */
 };
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
index ff701ab..52ba16f 100644
--- a/drivers/input/joystick/a3d.c
+++ b/drivers/input/joystick/a3d.c
@@ -326,14 +326,19 @@
 
 		a3d->length = 33;
 
-		input_dev->evbit[0] |= BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
-		input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y);
-		input_dev->absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_RUDDER)
-					| BIT(ABS_HAT0X) | BIT(ABS_HAT0Y) | BIT(ABS_HAT1X) | BIT(ABS_HAT1Y);
-		input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE)
-							| BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-		input_dev->keybit[LONG(BTN_JOYSTICK)] |= BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP)
-							| BIT(BTN_PINKIE);
+		input_dev->evbit[0] |= BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY) |
+			BIT_MASK(EV_REL);
+		input_dev->relbit[0] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+		input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+			BIT_MASK(ABS_THROTTLE) | BIT_MASK(ABS_RUDDER) |
+			BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
+			BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y);
+		input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_RIGHT) |
+			BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) |
+			BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
+		input_dev->keybit[BIT_WORD(BTN_JOYSTICK)] |=
+			BIT_MASK(BTN_TRIGGER) | BIT_MASK(BTN_THUMB) |
+			BIT_MASK(BTN_TOP) | BIT_MASK(BTN_PINKIE);
 
 		a3d_read(a3d, data);
 
@@ -348,9 +353,10 @@
 	} else {
 		a3d->length = 29;
 
-		input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_REL);
-		input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y);
-		input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE);
+		input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+		input_dev->relbit[0] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+		input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_RIGHT) |
+			BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE);
 
 		a3d_read(a3d, data);
 
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
index 28140c4..d1ca8a1 100644
--- a/drivers/input/joystick/adi.c
+++ b/drivers/input/joystick/adi.c
@@ -431,7 +431,7 @@
 	input_dev->open = adi_open;
 	input_dev->close = adi_close;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 	for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++)
 		set_bit(adi->abs[i], input_dev->absbit);
diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
index b0f5541..5cf9f36 100644
--- a/drivers/input/joystick/amijoy.c
+++ b/drivers/input/joystick/amijoy.c
@@ -137,9 +137,10 @@
 		amijoy_dev[i]->open = amijoy_open;
 		amijoy_dev[i]->close = amijoy_close;
 
-		amijoy_dev[i]->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-		amijoy_dev[i]->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-		amijoy_dev[i]->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+		amijoy_dev[i]->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+		amijoy_dev[i]->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
+		amijoy_dev[i]->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+			BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
 		for (j = 0; j < 2; j++) {
 			amijoy_dev[i]->absmin[ABS_X + j] = -1;
 			amijoy_dev[i]->absmax[ABS_X + j] = 1;
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index bdd157c..1573988 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -456,7 +456,7 @@
 	input_dev->open = analog_open;
 	input_dev->close = analog_close;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 	for (i = j = 0; i < 4; i++)
 		if (analog->mask & (1 << i)) {
diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c
index d3352a8..55646a6 100644
--- a/drivers/input/joystick/cobra.c
+++ b/drivers/input/joystick/cobra.c
@@ -218,7 +218,7 @@
 		input_dev->open = cobra_open;
 		input_dev->close = cobra_close;
 
-		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 		input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
 		input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
 		for (j = 0; cobra_btn[j]; j++)
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
index b069ee1..a6ca9d5 100644
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -4,7 +4,7 @@
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:
- *	Andree Borrmann		Mats Sjövall
+ *	Andree Borrmann		Mats Sjövall
  */
 
 /*
@@ -631,7 +631,7 @@
 		input_dev->open = db9_open;
 		input_dev->close = db9_close;
 
-		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 		for (j = 0; j < db9_mode->n_buttons; j++)
 			set_bit(db9_mode->buttons[j], input_dev->keybit);
 		for (j = 0; j < db9_mode->n_axis; j++) {
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index 1a452e0..df2a9d0 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -653,12 +653,12 @@
 	input_dev->close = gc_close;
 
 	if (pad_type != GC_SNESMOUSE) {
-		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 		for (i = 0; i < 2; i++)
 			input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0);
 	} else
-		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
 
 	gc->pads[0] |= gc_status_bit[idx];
 	gc->pads[pad_type] |= gc_status_bit[idx];
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
index d514aeb..1f6302c 100644
--- a/drivers/input/joystick/gf2k.c
+++ b/drivers/input/joystick/gf2k.c
@@ -315,7 +315,7 @@
 	input_dev->open = gf2k_open;
 	input_dev->close = gf2k_close;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 	for (i = 0; i < gf2k_axes[gf2k->id]; i++)
 		set_bit(gf2k_abs[i], input_dev->absbit);
diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
index 73eb5ab..fd3853a 100644
--- a/drivers/input/joystick/grip.c
+++ b/drivers/input/joystick/grip.c
@@ -370,7 +370,7 @@
 		input_dev->open = grip_open;
 		input_dev->close = grip_close;
 
-		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 		for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
 
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
index 4ed3a3e..c57e21d 100644
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -606,7 +606,7 @@
 	input_dev->open = grip_open;
 	input_dev->close = grip_close;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 	for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++)
 		input_set_abs_params(input_dev, t, -1, 1, 0, 0);
diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c
index d4e8073..aa6bfb3 100644
--- a/drivers/input/joystick/guillemot.c
+++ b/drivers/input/joystick/guillemot.c
@@ -238,7 +238,7 @@
 	input_dev->open = guillemot_open;
 	input_dev->close = guillemot_close;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 	for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++)
 		input_set_abs_params(input_dev, t, 0, 255, 0, 0);
diff --git a/drivers/input/joystick/iforce/Makefile b/drivers/input/joystick/iforce/Makefile
index 17ae42b..74daff4 100644
--- a/drivers/input/joystick/iforce/Makefile
+++ b/drivers/input/joystick/iforce/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for the I-Force driver
 #
-# By Johann Deneux <deneux@ifrance.com>
+# By Johann Deneux <johann.deneux@gmail.com>
 #
 
 # Goal definition
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index 682244b..6f826b3 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -389,7 +389,8 @@
  * Set input device bitfields and ranges.
  */
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF_STATUS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
+		BIT_MASK(EV_FF_STATUS);
 
 	for (i = 0; iforce->type->btn[i] >= 0; i++)
 		set_bit(iforce->type->btn[i], input_dev->keybit);
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index 40a853a..a964a7c 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -62,13 +62,13 @@
 #define FF_CORE_IS_PLAYED	3	/* Effect is currently being played */
 #define FF_CORE_SHOULD_PLAY	4	/* User wants the effect to be played */
 #define FF_CORE_UPDATE		5	/* Effect is being updated */
-#define FF_MODCORE_MAX		5
+#define FF_MODCORE_CNT		6
 
 struct iforce_core_effect {
 	/* Information about where modifiers are stored in the device's memory */
 	struct resource mod1_chunk;
 	struct resource mod2_chunk;
-	unsigned long flags[NBITS(FF_MODCORE_MAX)];
+	unsigned long flags[BITS_TO_LONGS(FF_MODCORE_CNT)];
 };
 
 #define FF_CMD_EFFECT		0x010e
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c
index 1aec1e9..bc8ea95 100644
--- a/drivers/input/joystick/interact.c
+++ b/drivers/input/joystick/interact.c
@@ -269,7 +269,7 @@
 	input_dev->open = interact_open;
 	input_dev->close = interact_close;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 	for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) {
 		set_bit(t, input_dev->absbit);
diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
index b35604e..54e6769 100644
--- a/drivers/input/joystick/magellan.c
+++ b/drivers/input/joystick/magellan.c
@@ -170,7 +170,7 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 	for (i = 0; i < 9; i++)
 		set_bit(magellan_buttons[i], input_dev->keybit);
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
index 2adf73f..7b4865f 100644
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -758,7 +758,7 @@
 		input_dev->open = sw_open;
 		input_dev->close = sw_close;
 
-		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 		for (j = 0; (bits = sw_bit[sw->type][j]); j++) {
 			code = sw_abs[sw->type][j];
diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
index abb7c4c..d4087fd 100644
--- a/drivers/input/joystick/spaceball.c
+++ b/drivers/input/joystick/spaceball.c
@@ -228,18 +228,23 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 	switch (id) {
 		case SPACEBALL_4000FLX:
 		case SPACEBALL_4000FLX_L:
-			input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_9);
-			input_dev->keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
+			input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_9);
+			input_dev->keybit[BIT_WORD(BTN_A)] |= BIT_MASK(BTN_A) |
+				BIT_MASK(BTN_B) | BIT_MASK(BTN_C) |
+				BIT_MASK(BTN_MODE);
 		default:
-			input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
-				| BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8);
+			input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_2) |
+				BIT_MASK(BTN_3) | BIT_MASK(BTN_4) |
+				BIT_MASK(BTN_5) | BIT_MASK(BTN_6) |
+				BIT_MASK(BTN_7) | BIT_MASK(BTN_8);
 		case SPACEBALL_3003C:
-			input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
+			input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_1) |
+				BIT_MASK(BTN_8);
 	}
 
 	for (i = 0; i < 3; i++) {
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
index c4937f1..f7ce400 100644
--- a/drivers/input/joystick/spaceorb.c
+++ b/drivers/input/joystick/spaceorb.c
@@ -185,7 +185,7 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 	for (i = 0; i < 6; i++)
 		set_bit(spaceorb_buttons[i], input_dev->keybit);
diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
index 8581ee9..baa10b2 100644
--- a/drivers/input/joystick/stinger.c
+++ b/drivers/input/joystick/stinger.c
@@ -156,10 +156,11 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) |
-					 BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) |
-					 BIT(BTN_START) | BIT(BTN_SELECT);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_A)] = BIT_MASK(BTN_A) | BIT_MASK(BTN_B) |
+		BIT_MASK(BTN_C) | BIT_MASK(BTN_X) | BIT_MASK(BTN_Y) |
+		BIT_MASK(BTN_Z) | BIT_MASK(BTN_TL) | BIT_MASK(BTN_TR) |
+		BIT_MASK(BTN_START) | BIT_MASK(BTN_SELECT);
 	input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 4);
 	input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 4);
 
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
index 3b36ee0..0feeb8a 100644
--- a/drivers/input/joystick/tmdc.c
+++ b/drivers/input/joystick/tmdc.c
@@ -333,7 +333,7 @@
 	input_dev->open = tmdc_open;
 	input_dev->close = tmdc_close;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 	for (i = 0; i < port->absc && i < TMDC_ABS; i++)
 		if (port->abs[i] >= 0)
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
index 8381c6f..bbebd4e 100644
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -229,7 +229,7 @@
 		input_dev->open = tgfx_open;
 		input_dev->close = tgfx_close;
 
-		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 		input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
 		input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
 
diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
index c91504e..1085c84 100644
--- a/drivers/input/joystick/twidjoy.c
+++ b/drivers/input/joystick/twidjoy.c
@@ -207,7 +207,7 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 	input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4);
 	input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4);
 
diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
index 4e85f72..e928b6e 100644
--- a/drivers/input/joystick/warrior.c
+++ b/drivers/input/joystick/warrior.c
@@ -162,9 +162,11 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
-	input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
-	input_dev->relbit[0] = BIT(REL_DIAL);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) |
+		BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TRIGGER)] = BIT_MASK(BTN_TRIGGER) |
+		BIT_MASK(BTN_THUMB) | BIT_MASK(BTN_TOP) | BIT_MASK(BTN_TOP2);
+	input_dev->relbit[0] = BIT_MASK(REL_DIAL);
 	input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 8);
 	input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8);
 	input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0);
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 623629a..6dd3758 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -658,7 +658,7 @@
 	input_dev->open = xpad_open;
 	input_dev->close = xpad_close;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 	/* set up buttons */
 	for (i = 0; xpad_btn[i] >= 0; i++)
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c
index 63d6ead..72abc19 100644
--- a/drivers/input/keyboard/aaed2000_kbd.c
+++ b/drivers/input/keyboard/aaed2000_kbd.c
@@ -125,7 +125,7 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &pdev->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 	input_dev->keycode = aaedkbd->keycode;
 	input_dev->keycodesize = sizeof(unsigned char);
 	input_dev->keycodemax = ARRAY_SIZE(aaedkbd_keycode);
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index c67e84e..81bf756 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -209,7 +209,7 @@
 	amikbd_dev->id.product = 0x0001;
 	amikbd_dev->id.version = 0x0100;
 
-	amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	amikbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 
 	for (i = 0; i < 0x78; i++)
 		set_bit(i, amikbd_dev->keybit);
diff --git a/drivers/input/keyboard/atakbd.c b/drivers/input/keyboard/atakbd.c
index a180015..4e92100 100644
--- a/drivers/input/keyboard/atakbd.c
+++ b/drivers/input/keyboard/atakbd.c
@@ -237,7 +237,7 @@
 	atakbd_dev->id.product = 0x0001;
 	atakbd_dev->id.version = 0x0100;
 
-	atakbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	atakbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 	atakbd_dev->keycode = atakbd_keycode;
 	atakbd_dev->keycodesize = sizeof(unsigned char);
 	atakbd_dev->keycodemax = ARRAY_SIZE(atakbd_keycode);
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 41fc3d0..b39c5b3 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -900,27 +900,32 @@
 
 	input_set_drvdata(input_dev, atkbd);
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
+		BIT_MASK(EV_MSC);
 
 	if (atkbd->write) {
-		input_dev->evbit[0] |= BIT(EV_LED);
-		input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+		input_dev->evbit[0] |= BIT_MASK(EV_LED);
+		input_dev->ledbit[0] = BIT_MASK(LED_NUML) |
+			BIT_MASK(LED_CAPSL) | BIT_MASK(LED_SCROLLL);
 	}
 
 	if (atkbd->extra)
-		input_dev->ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
-					BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
+		input_dev->ledbit[0] |= BIT_MASK(LED_COMPOSE) |
+			BIT_MASK(LED_SUSPEND) | BIT_MASK(LED_SLEEP) |
+			BIT_MASK(LED_MUTE) | BIT_MASK(LED_MISC);
 
 	if (!atkbd->softrepeat) {
 		input_dev->rep[REP_DELAY] = 250;
 		input_dev->rep[REP_PERIOD] = 33;
 	}
 
-	input_dev->mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
+	input_dev->mscbit[0] = atkbd->softraw ? BIT_MASK(MSC_SCAN) :
+		BIT_MASK(MSC_RAW) | BIT_MASK(MSC_SCAN);
 
 	if (atkbd->scroll) {
-		input_dev->evbit[0] |= BIT(EV_REL);
-		input_dev->relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
+		input_dev->evbit[0] |= BIT_MASK(EV_REL);
+		input_dev->relbit[0] = BIT_MASK(REL_WHEEL) |
+			BIT_MASK(REL_HWHEEL);
 		set_bit(BTN_MIDDLE, input_dev->keybit);
 	}
 
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index a67b29b..e5f4da9 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -256,7 +256,6 @@
 		printk(KERN_ERR DRV_NAME
 			": unable to claim irq %d; error %d\n",
 			bf54x_kpad->irq, error);
-		error = -EBUSY;
 		goto out2;
 	}
 
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index 6578bff..790fed3 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -325,7 +325,8 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &pdev->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
+		BIT_MASK(EV_PWR) | BIT_MASK(EV_SW);
 	input_dev->keycode = corgikbd->keycode;
 	input_dev->keycodesize = sizeof(unsigned char);
 	input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode);
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index e2a3293..3eddf52 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -62,7 +62,7 @@
 
 	platform_set_drvdata(pdev, input);
 
-	input->evbit[0] = BIT(EV_KEY);
+	input->evbit[0] = BIT_MASK(EV_KEY);
 
 	input->name = pdev->name;
 	input->phys = "gpio-keys/input0";
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c
index cdd254f..adbf29f 100644
--- a/drivers/input/keyboard/hil_kbd.c
+++ b/drivers/input/keyboard/hil_kbd.c
@@ -323,8 +323,9 @@
 		goto bail2;
 	}
 
-	kbd->dev->evbit[0]	= BIT(EV_KEY) | BIT(EV_REP);
-	kbd->dev->ledbit[0]	= BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+	kbd->dev->evbit[0]	= BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+	kbd->dev->ledbit[0]	= BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
+		BIT_MASK(LED_SCROLLL);
 	kbd->dev->keycodemax	= HIL_KEYCODES_SET1_TBLSIZE;
 	kbd->dev->keycodesize	= sizeof(hil_kbd_set1[0]);
 	kbd->dev->keycode	= hil_kbd_set1;
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index 499b697..50d80ec 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -266,8 +266,9 @@
 		if (hphilkeyb_keycode[i] != KEY_RESERVED)
 			set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
 
-	hil_dev.dev->evbit[0]	= BIT(EV_KEY) | BIT(EV_REP);
-	hil_dev.dev->ledbit[0]	= BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+	hil_dev.dev->evbit[0]	= BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+	hil_dev.dev->ledbit[0]	= BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
+		BIT_MASK(LED_SCROLLL);
 	hil_dev.dev->keycodemax	= HIL_KEYCODES_SET1_TBLSIZE;
 	hil_dev.dev->keycodesize= sizeof(hphilkeyb_keycode[0]);
 	hil_dev.dev->keycode	= hphilkeyb_keycode;
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index 7a41b27..5a0ca18 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -233,7 +233,7 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &dev->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 	input_dev->keycode = locomokbd->keycode;
 	input_dev->keycodesize = sizeof(unsigned char);
 	input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode);
diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
index b97a41e..48d1cab 100644
--- a/drivers/input/keyboard/newtonkbd.c
+++ b/drivers/input/keyboard/newtonkbd.c
@@ -106,7 +106,7 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 	input_dev->keycode = nkbd->keycode;
 	input_dev->keycodesize = sizeof(unsigned char);
 	input_dev->keycodemax = ARRAY_SIZE(nkbd_keycode);
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 76f1969..babc913 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -4,7 +4,7 @@
  * OMAP Keypad Driver
  *
  * Copyright (C) 2003 Nokia Corporation
- * Written by Timo Teräs <ext-timo.teras@nokia.com>
+ * Written by Timo Teräs <ext-timo.teras@nokia.com>
  *
  * Added support for H2 & H3 Keypad
  * Copyright (C) 2004 Texas Instruments
@@ -481,6 +481,6 @@
 module_init(omap_kp_init);
 module_exit(omap_kp_exit);
 
-MODULE_AUTHOR("Timo Teräs");
+MODULE_AUTHOR("Timo Teräs");
 MODULE_DESCRIPTION("OMAP Keypad Driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/pxa27x_keyboard.c b/drivers/input/keyboard/pxa27x_keyboard.c
index b7061aa..bdd64ee 100644
--- a/drivers/input/keyboard/pxa27x_keyboard.c
+++ b/drivers/input/keyboard/pxa27x_keyboard.c
@@ -183,8 +183,9 @@
 	input_dev->close = pxakbd_close;
 	input_dev->dev.parent = &pdev->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
-	input_dev->relbit[LONG(REL_WHEEL)] = BIT(REL_WHEEL);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
+		BIT_MASK(EV_REL);
+	input_dev->relbit[BIT_WORD(REL_WHEEL)] = BIT_MASK(REL_WHEEL);
 	for (row = 0; row < pdata->nr_rows; row++) {
 		for (col = 0; col < pdata->nr_cols; col++) {
 			int code = pdata->keycodes[row][col];
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index 41b8038..410d78a 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -381,7 +381,8 @@
 	input_dev->id.product = 0x0001;
 	input_dev->id.version = 0x0100;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
+		BIT_MASK(EV_PWR) | BIT_MASK(EV_SW);
 	input_dev->keycode = spitzkbd->keycode;
 	input_dev->keycodesize = sizeof(unsigned char);
 	input_dev->keycodemax = ARRAY_SIZE(spitzkbd_keycode);
diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c
index b44b068..7437219 100644
--- a/drivers/input/keyboard/stowaway.c
+++ b/drivers/input/keyboard/stowaway.c
@@ -110,7 +110,7 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 	input_dev->keycode = skbd->keycode;
 	input_dev->keycodesize = sizeof(unsigned char);
 	input_dev->keycodemax = ARRAY_SIZE(skbd_keycode);
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index 1d4e396..be0f5d1 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -277,9 +277,11 @@
 
 	input_dev->event = sunkbd_event;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
-	input_dev->ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
-	input_dev->sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
+		BIT_MASK(EV_SND) | BIT_MASK(EV_REP);
+	input_dev->ledbit[0] = BIT_MASK(LED_CAPSL) | BIT_MASK(LED_COMPOSE) |
+		BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_NUML);
+	input_dev->sndbit[0] = BIT_MASK(SND_CLICK) | BIT_MASK(SND_BELL);
 
 	input_dev->keycode = sunkbd->keycode;
 	input_dev->keycodesize = sizeof(unsigned char);
diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
index f3a56eb..152a2c0 100644
--- a/drivers/input/keyboard/xtkbd.c
+++ b/drivers/input/keyboard/xtkbd.c
@@ -110,7 +110,7 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 	input_dev->keycode = xtkbd->keycode;
 	input_dev->keycodesize = sizeof(unsigned char);
 	input_dev->keycodemax = ARRAY_SIZE(xtkbd_keycode);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 7acc635..8f5c7b9 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -70,9 +70,9 @@
 	select LEDS_CLASS
 	select CHECK_SIGNATURE
 	help
-	  Say Y here for support of Winstron laptop button interface, used on
+	  Say Y here for support of Wistron laptop button interfaces, used on
 	  laptops of various brands, including Acer and Fujitsu-Siemens. If
-	  available, mail and wifi leds will be controlable via /sys/class/leds.
+	  available, mail and wifi LEDs will be controllable via /sys/class/leds.
 
 	  To compile this driver as a module, choose M here: the module will
 	  be called wistron_btns.
diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c
index 471aab2..3a79374 100644
--- a/drivers/input/misc/ati_remote.c
+++ b/drivers/input/misc/ati_remote.c
@@ -662,10 +662,10 @@
 	struct input_dev *idev = ati_remote->idev;
 	int i;
 
-	idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	idev->keybit[LONG(BTN_MOUSE)] = ( BIT(BTN_LEFT) | BIT(BTN_RIGHT) |
-					  BIT(BTN_SIDE) | BIT(BTN_EXTRA) );
-	idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
+	idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 	for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++)
 		if (ati_remote_tbl[i].type == EV_KEY)
 			set_bit(ati_remote_tbl[i].code, idev->keybit);
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index 1031543..f2709b8 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -346,9 +346,10 @@
 	ar2->idev = idev;
 	input_set_drvdata(idev, ar2);
 
-	idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
-	idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
-	idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL);
+	idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_RIGHT);
+	idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 	for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
 		set_bit(ati_remote2_key_table[i].key_code, idev->keybit);
 
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c
index e43e92f..4e3ad65 100644
--- a/drivers/input/misc/atlas_btns.c
+++ b/drivers/input/misc/atlas_btns.c
@@ -81,7 +81,7 @@
 	input_dev->name = "Atlas ACPI button driver";
 	input_dev->phys = "ASIM0000/atlas/input0";
 	input_dev->id.bustype = BUS_HOST;
-	input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY);
+	input_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY);
 
 	set_bit(KEY_F1, input_dev->keybit);
 	set_bit(KEY_F2, input_dev->keybit);
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c
index 064b079..1aef97e 100644
--- a/drivers/input/misc/cobalt_btns.c
+++ b/drivers/input/misc/cobalt_btns.c
@@ -104,7 +104,7 @@
 	input->id.bustype = BUS_HOST;
 	input->cdev.dev = &pdev->dev;
 
-	input->evbit[0] = BIT(EV_KEY);
+	input->evbit[0] = BIT_MASK(EV_KEY);
 	for (i = 0; i < ARRAY_SIZE(buttons_map); i++) {
 		set_bit(buttons_map[i].keycode, input->keybit);
 		buttons_map[i].count = 0;
diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c
index e759944..d2ade74 100644
--- a/drivers/input/misc/ixp4xx-beeper.c
+++ b/drivers/input/misc/ixp4xx-beeper.c
@@ -109,8 +109,8 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &dev->dev;
 
-	input_dev->evbit[0] = BIT(EV_SND);
-	input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+	input_dev->evbit[0] = BIT_MASK(EV_SND);
+	input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
 	input_dev->event = ixp4xx_spkr_event;
 
 	err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt,
diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c
index 1bffc9f..fd74347 100644
--- a/drivers/input/misc/keyspan_remote.c
+++ b/drivers/input/misc/keyspan_remote.c
@@ -497,7 +497,7 @@
 	usb_to_input_id(udev, &input_dev->id);
 	input_dev->dev.parent = &interface->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY);		/* We will only report KEY events. */
+	input_dev->evbit[0] = BIT_MASK(EV_KEY);		/* We will only report KEY events. */
 	for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++)
 		if (keyspan_key_table[i] != KEY_RESERVED)
 			set_bit(keyspan_key_table[i], input_dev->keybit);
diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c
index e9f26e7..0c64d9b 100644
--- a/drivers/input/misc/m68kspkr.c
+++ b/drivers/input/misc/m68kspkr.c
@@ -65,8 +65,8 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &dev->dev;
 
-	input_dev->evbit[0] = BIT(EV_SND);
-	input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+	input_dev->evbit[0] = BIT_MASK(EV_SND);
+	input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
 	input_dev->event = m68kspkr_event;
 
 	err = input_register_device(input_dev);
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index c19f77f..4941a9e 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -86,8 +86,8 @@
 	pcspkr_dev->id.version = 0x0100;
 	pcspkr_dev->dev.parent = &dev->dev;
 
-	pcspkr_dev->evbit[0] = BIT(EV_SND);
-	pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+	pcspkr_dev->evbit[0] = BIT_MASK(EV_SND);
+	pcspkr_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
 	pcspkr_dev->event = pcspkr_event;
 
 	err = input_register_device(pcspkr_dev);
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c
index 448a470..7a7b8c7 100644
--- a/drivers/input/misc/powermate.c
+++ b/drivers/input/misc/powermate.c
@@ -363,10 +363,11 @@
 
 	input_dev->event = powermate_input_event;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
-	input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
-	input_dev->relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
-	input_dev->mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) |
+		BIT_MASK(EV_MSC);
+	input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
+	input_dev->relbit[BIT_WORD(REL_DIAL)] = BIT_MASK(REL_DIAL);
+	input_dev->mscbit[BIT_WORD(MSC_PULSELED)] = BIT_MASK(MSC_PULSELED);
 
 	/* get a handle to the interrupt data pipe */
 	pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index e36ec1d..a3637d8 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -115,8 +115,8 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = dev;
 
-	input_dev->evbit[0] = BIT(EV_SND);
-	input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+	input_dev->evbit[0] = BIT_MASK(EV_SND);
+	input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
 
 	input_dev->event = state->event;
 
diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c
index ab15880..46279ef 100644
--- a/drivers/input/misc/yealink.c
+++ b/drivers/input/misc/yealink.c
@@ -945,7 +945,7 @@
 	/* input_dev->event = input_ev;	TODO */
 
 	/* register available key events */
-	input_dev->evbit[0] = BIT(EV_KEY);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY);
 	for (i = 0; i < 256; i++) {
 		int k = map_p1k_to_key(i);
 		if (k >= 0) {
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 64d70a9..2b5ed11 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -455,24 +455,25 @@
 	if (alps_hw_init(psmouse, &version))
 		goto init_fail;
 
-	dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
-	dev1->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
-	dev1->keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
-	dev1->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
+	dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);
+	dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER);
+	dev1->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
 
-	dev1->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
+	dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
 	input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
 	input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
 	input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
 
 	if (priv->i->flags & ALPS_WHEEL) {
-		dev1->evbit[LONG(EV_REL)] |= BIT(EV_REL);
-		dev1->relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
+		dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL);
+		dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL);
 	}
 
 	if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
-		dev1->keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
-		dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
+		dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD);
+		dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK);
 	}
 
 	snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
@@ -483,9 +484,10 @@
 	dev2->id.product = PSMOUSE_ALPS;
 	dev2->id.version = 0x0000;
 
-	dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
-	dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	dev2->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+	dev2->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
 
 	if (input_register_device(priv->dev2))
 		goto init_fail;
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
index 239a0e1..a185ac7 100644
--- a/drivers/input/mouse/amimouse.c
+++ b/drivers/input/mouse/amimouse.c
@@ -111,9 +111,10 @@
 	amimouse_dev->id.product = 0x0002;
 	amimouse_dev->id.version = 0x0100;
 
-	amimouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	amimouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-	amimouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	amimouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	amimouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+	amimouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
 	amimouse_dev->open = amimouse_open;
 	amimouse_dev->close = amimouse_close;
 
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 0117817..f132702 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -504,25 +504,22 @@
 		memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
 	}
 
-	/* Geyser 3 will continue to send packets continually after
+	input_report_key(dev->input, BTN_LEFT, key);
+	input_sync(dev->input);
+
+	/* Many Geysers will continue to send packets continually after
 	   the first touch unless reinitialised. Do so if it's been
 	   idle for a while in order to avoid waking the kernel up
 	   several hundred times a second */
 
-	if (atp_is_geyser_3(dev)) {
-		if (!x && !y && !key) {
-			dev->idlecount++;
-			if (dev->idlecount == 10) {
-				dev->valid = 0;
-				schedule_work(&dev->work);
-			}
+	if (!x && !y && !key) {
+		dev->idlecount++;
+		if (dev->idlecount == 10) {
+			dev->valid = 0;
+			schedule_work(&dev->work);
 		}
-		else
-			dev->idlecount = 0;
-	}
-
-	input_report_key(dev->input, BTN_LEFT, key);
-	input_sync(dev->input);
+	} else
+		dev->idlecount = 0;
 
 exit:
 	retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
diff --git a/drivers/input/mouse/atarimouse.c b/drivers/input/mouse/atarimouse.c
index c8c7244..98a3561 100644
--- a/drivers/input/mouse/atarimouse.c
+++ b/drivers/input/mouse/atarimouse.c
@@ -137,9 +137,10 @@
 	atamouse_dev->id.product = 0x0002;
 	atamouse_dev->id.version = 0x0100;
 
-	atamouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	atamouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-	atamouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	atamouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	atamouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+	atamouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
 	atamouse_dev->open = atamouse_open;
 	atamouse_dev->close = atamouse_close;
 
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c
index 449bf4d..27f88fb 100644
--- a/drivers/input/mouse/hil_ptr.c
+++ b/drivers/input/mouse/hil_ptr.c
@@ -298,12 +298,12 @@
 	idd = ptr->idd + 1;
 	txt = "unknown";
 	if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
-		ptr->dev->evbit[0] = BIT(EV_REL);
+		ptr->dev->evbit[0] = BIT_MASK(EV_REL);
 		txt = "relative";
 	}
 
 	if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) {
-		ptr->dev->evbit[0] = BIT(EV_ABS);
+		ptr->dev->evbit[0] = BIT_MASK(EV_ABS);
 		txt = "absolute";
 	}
 	if (!ptr->dev->evbit[0])
@@ -311,7 +311,7 @@
 
 	ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
 	if (ptr->nbtn)
-		ptr->dev->evbit[0] |= BIT(EV_KEY);
+		ptr->dev->evbit[0] |= BIT_MASK(EV_KEY);
 
 	naxsets = HIL_IDD_NUM_AXSETS(*idd);
 	ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
index 79b624f..655a392 100644
--- a/drivers/input/mouse/inport.c
+++ b/drivers/input/mouse/inport.c
@@ -163,9 +163,10 @@
 	inport_dev->id.product = 0x0001;
 	inport_dev->id.version = 0x0100;
 
-	inport_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	inport_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-	inport_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	inport_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	inport_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+	inport_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
 	inport_dev->open  = inport_open;
 	inport_dev->close = inport_close;
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index d7de4c5..9ec57d8 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -270,9 +270,10 @@
 	dev2->id.version = 0x0000;
 	dev2->dev.parent = &psmouse->ps2dev.serio->dev;
 
-	dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	dev2->relbit[LONG(REL_X)] = BIT(REL_X) | BIT(REL_Y);
-	dev2->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+	dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+	dev2->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_RIGHT);
 
 	error = input_register_device(priv->dev2);
 	if (error)
@@ -295,9 +296,9 @@
 	if (lifebook_absolute_mode(psmouse))
 		return -1;
 
-	dev1->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
+	dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
 	dev1->relbit[0] = 0;
-	dev1->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 	input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0);
 	input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0);
 
diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c
index 26c3b2e..b23a4f3 100644
--- a/drivers/input/mouse/logibm.c
+++ b/drivers/input/mouse/logibm.c
@@ -156,9 +156,10 @@
 	logibm_dev->id.product = 0x0001;
 	logibm_dev->id.version = 0x0100;
 
-	logibm_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	logibm_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-	logibm_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	logibm_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	logibm_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+	logibm_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
 	logibm_dev->open  = logibm_open;
 	logibm_dev->close = logibm_close;
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c
index 05d992e..8991ab0 100644
--- a/drivers/input/mouse/pc110pad.c
+++ b/drivers/input/mouse/pc110pad.c
@@ -144,9 +144,9 @@
 	pc110pad_dev->id.product = 0x0001;
 	pc110pad_dev->id.version = 0x0100;
 
-	pc110pad_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	pc110pad_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-	pc110pad_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	pc110pad_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	pc110pad_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
+	pc110pad_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
 	pc110pad_dev->absmax[ABS_X] = 0x1ff;
 	pc110pad_dev->absmax[ABS_Y] = 0x0ff;
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 0735257..21a9c0b 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -906,7 +906,7 @@
 
 /*
  * psmouse_deactivate() puts the mouse into poll mode so that we don't get motion
- * reports from it unless we explicitely request it.
+ * reports from it unless we explicitly request it.
  */
 
 static void psmouse_deactivate(struct psmouse *psmouse)
@@ -1115,9 +1115,10 @@
 
 	input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+	input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
 	psmouse->set_rate = psmouse_set_rate;
 	psmouse->set_resolution = psmouse_set_resolution;
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c
index 355efd0..18a4863 100644
--- a/drivers/input/mouse/rpcmouse.c
+++ b/drivers/input/mouse/rpcmouse.c
@@ -78,9 +78,10 @@
 	rpcmouse_dev->id.product = 0x0001;
 	rpcmouse_dev->id.version = 0x0100;
 
-	rpcmouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	rpcmouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-	rpcmouse_dev->relbit[0]	= BIT(REL_X) | BIT(REL_Y);
+	rpcmouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	rpcmouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+	rpcmouse_dev->relbit[0]	= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
 	rpcmouse_lastx = (short) iomd_readl(IOMD_MOUSEX);
 	rpcmouse_lasty = (short) iomd_readl(IOMD_MOUSEY);
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
index 77b8ee2..ed917bf 100644
--- a/drivers/input/mouse/sermouse.c
+++ b/drivers/input/mouse/sermouse.c
@@ -268,9 +268,10 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
-	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_RIGHT);
+	input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
 	if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit);
 	if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit);
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c
index 7b977fd..3fadb2a 100644
--- a/drivers/input/mouse/touchkit_ps2.c
+++ b/drivers/input/mouse/touchkit_ps2.c
@@ -85,7 +85,7 @@
 		return -ENODEV;
 
 	if (set_properties) {
-		dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+		dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 		set_bit(BTN_TOUCH, dev->keybit);
 		input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0);
 		input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0);
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
index 4a32157..404eedd 100644
--- a/drivers/input/mouse/vsxxxaa.c
+++ b/drivers/input/mouse/vsxxxaa.c
@@ -330,7 +330,7 @@
 
 	/*
 	 * Check for Power-On-Reset packets. These are sent out
-	 * after plugging the mouse in, or when explicitely
+	 * after plugging the mouse in, or when explicitly
 	 * requested by sending 'T'.
 	 *
 	 * [0]:	1	0	1	0	R3	R2	R1	R0
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 79146d6..78c3ea7 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -998,34 +998,36 @@
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 				INPUT_DEVICE_ID_MATCH_KEYBIT |
 				INPUT_DEVICE_ID_MATCH_RELBIT,
-		.evbit = { BIT(EV_KEY) | BIT(EV_REL) },
-		.keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) },
-		.relbit = { BIT(REL_X) | BIT(REL_Y) },
+		.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
+		.keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
+		.relbit = { BIT_MASK(REL_X) | BIT_MASK(REL_Y) },
 	},	/* A mouse like device, at least one button,
 		   two relative axes */
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 				INPUT_DEVICE_ID_MATCH_RELBIT,
-		.evbit = { BIT(EV_KEY) | BIT(EV_REL) },
-		.relbit = { BIT(REL_WHEEL) },
+		.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
+		.relbit = { BIT_MASK(REL_WHEEL) },
 	},	/* A separate scrollwheel */
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 				INPUT_DEVICE_ID_MATCH_KEYBIT |
 				INPUT_DEVICE_ID_MATCH_ABSBIT,
-		.evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
-		.keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
-		.absbit = { BIT(ABS_X) | BIT(ABS_Y) },
+		.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
+		.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
+		.absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
 	},	/* A tablet like device, at least touch detection,
 		   two absolute axes */
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 				INPUT_DEVICE_ID_MATCH_KEYBIT |
 				INPUT_DEVICE_ID_MATCH_ABSBIT,
-		.evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
-		.keybit = { [LONG(BTN_TOOL_FINGER)] = BIT(BTN_TOOL_FINGER) },
-		.absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) |
-				BIT(ABS_TOOL_WIDTH) },
+		.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
+		.keybit = { [BIT_WORD(BTN_TOOL_FINGER)] =
+				BIT_MASK(BTN_TOOL_FINGER) },
+		.absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+				BIT_MASK(ABS_PRESSURE) |
+				BIT_MASK(ABS_TOOL_WIDTH) },
 	},	/* A touchpad */
 
 	{ },	/* Terminating entry */
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 11dafc0..1a0cea3 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -20,6 +20,7 @@
 #include <linux/err.h>
 #include <linux/rcupdate.h>
 #include <linux/platform_device.h>
+#include <linux/i8042.h>
 
 #include <asm/io.h>
 
@@ -208,7 +209,7 @@
 	return 0;
 }
 
-static int i8042_command(unsigned char *param, int command)
+int i8042_command(unsigned char *param, int command)
 {
 	unsigned long flags;
 	int retval;
@@ -219,6 +220,7 @@
 
 	return retval;
 }
+EXPORT_SYMBOL(i8042_command);
 
 /*
  * i8042_kbd_write() sends a byte out through the keyboard interface.
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index b3eb7a7..dd22d91 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -61,28 +61,6 @@
 #define I8042_CTR_XLATE		0x40
 
 /*
- * Commands.
- */
-
-#define I8042_CMD_CTL_RCTR	0x0120
-#define I8042_CMD_CTL_WCTR	0x1060
-#define I8042_CMD_CTL_TEST	0x01aa
-
-#define I8042_CMD_KBD_DISABLE	0x00ad
-#define I8042_CMD_KBD_ENABLE	0x00ae
-#define I8042_CMD_KBD_TEST	0x01ab
-#define I8042_CMD_KBD_LOOP	0x11d2
-
-#define I8042_CMD_AUX_DISABLE	0x00a7
-#define I8042_CMD_AUX_ENABLE	0x00a8
-#define I8042_CMD_AUX_TEST	0x01a9
-#define I8042_CMD_AUX_SEND	0x10d4
-#define I8042_CMD_AUX_LOOP	0x11d3
-
-#define I8042_CMD_MUX_PFX	0x0090
-#define I8042_CMD_MUX_SEND	0x1090
-
-/*
  * Return codes.
  */
 
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index b3bc15a..7f52938 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -387,9 +387,8 @@
 	set_freezable();
 	do {
 		serio_handle_event();
-		wait_event_interruptible(serio_wait,
+		wait_event_freezable(serio_wait,
 			kthread_should_stop() || !list_empty(&serio_event_list));
-		try_to_freeze();
 	} while (!kthread_should_stop());
 
 	printk(KERN_DEBUG "serio: kseriod exiting\n");
diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c
index dd231045..b973d0e 100644
--- a/drivers/input/tablet/acecad.c
+++ b/drivers/input/tablet/acecad.c
@@ -192,10 +192,14 @@
 	input_dev->open = usb_acecad_open;
 	input_dev->close = usb_acecad_close;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
-	input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-	input_dev->keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+		BIT_MASK(ABS_PRESSURE);
+	input_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+	input_dev->keybit[BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_TOOL_PEN) |
+		BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS) |
+		BIT_MASK(BTN_STYLUS2);
 
 	switch (id->driver_info) {
 		case 0:
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
index b2ca10f2f..d2c6da2 100644
--- a/drivers/input/tablet/gtco.c
+++ b/drivers/input/tablet/gtco.c
@@ -573,10 +573,12 @@
 	struct gtco *device = input_get_drvdata(inputdev);
 
 	/* Which events */
-	inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
+	inputdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
+		BIT_MASK(EV_MSC);
 
 	/* Misc event menu block */
-	inputdev->mscbit[0] = BIT(MSC_SCAN)|BIT(MSC_SERIAL)|BIT(MSC_RAW) ;
+	inputdev->mscbit[0] = BIT_MASK(MSC_SCAN) | BIT_MASK(MSC_SERIAL) |
+		BIT_MASK(MSC_RAW);
 
 	/* Absolute values based on HID report info */
 	input_set_abs_params(inputdev, ABS_X, device->min_X, device->max_X,
diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c
index 91e6d00..1182fc1 100644
--- a/drivers/input/tablet/kbtab.c
+++ b/drivers/input/tablet/kbtab.c
@@ -153,10 +153,13 @@
 	input_dev->open = kbtab_open;
 	input_dev->close = kbtab_close;
 
-	input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
-	input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
-	input_dev->mscbit[0] |= BIT(MSC_SERIAL);
+	input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
+		BIT_MASK(EV_MSC);
+	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
+		BIT_MASK(BTN_TOUCH);
+	input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
 	input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
 	input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0);
 	input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 064e123..d64b1ea1 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -140,48 +140,58 @@
 
 void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-	input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_1) | BIT(BTN_5);
+	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_1) |
+		BIT_MASK(BTN_5);
 	input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
 }
 
 void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-	input_dev->evbit[0] |= BIT(EV_MSC);
-	input_dev->mscbit[0] |= BIT(MSC_SERIAL);
-	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
-	input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_4);
+	input_dev->evbit[0] |= BIT_MASK(EV_MSC);
+	input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
+	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER);
+	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) |
+		BIT_MASK(BTN_4);
 }
 
 void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-	input_dev->evbit[0] |= BIT(EV_REL);
-	input_dev->relbit[0] |= BIT(REL_WHEEL);
-	input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
+	input_dev->evbit[0] |= BIT_MASK(EV_REL);
+	input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
+	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+		BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2);
 	input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
 }
 
 void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
-	input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3);
+	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER);
+	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) |
+		BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3);
 	input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
 }
 
 void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-	input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
+	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_4) |
+		BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7);
 	input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
 }
 
 void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-	input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
-	input_dev->mscbit[0] |= BIT(MSC_SERIAL);
-	input_dev->relbit[0] |= BIT(REL_WHEEL);
-	input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE)	| BIT(BTN_TOOL_BRUSH)
-		| BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
+	input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL);
+	input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
+	input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
+	input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) |
+		BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
+	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+		BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) |
+		BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) |
+		BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2);
 	input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
 	input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
 	input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
@@ -192,12 +202,13 @@
 
 void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
+	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2) |
+		BIT_MASK(BTN_TOOL_RUBBER);
 }
 
 void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER);
+	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER);
 }
 
 static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -243,12 +254,13 @@
 	input_dev->open = wacom_open;
 	input_dev->close = wacom_close;
 
-	input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
-	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
+	input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
+		BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS);
 	input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0);
 	input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0);
 	input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0);
-	input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC);
+	input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
 
 	wacom_init_input_dev(input_dev, wacom_wac);
 
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index e3e0baa..fa8442b 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -202,6 +202,7 @@
 	  - DMC TSC-10/25
 	  - IRTOUCHSYSTEMS/UNITOP
 	  - IdealTEK URTC1000
+	  - GoTop Super_Q2/GogoPen/PenPower tablets
 
 	  Have a look at <http://linux.chapter7.ch/touchkit/> for
 	  a usage description and the required user-space stuff.
@@ -259,4 +260,9 @@
 	bool "GeneralTouch Touchscreen device support" if EMBEDDED
 	depends on TOUCHSCREEN_USB_COMPOSITE
 
+config TOUCHSCREEN_USB_GOTOP
+	default y
+	bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED
+	depends on TOUCHSCREEN_USB_COMPOSITE
+
 endif
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 51ae4fb..f59aecf 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -917,8 +917,8 @@
 	input_dev->phys = ts->phys;
 	input_dev->dev.parent = &spi->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 	input_set_abs_params(input_dev, ABS_X,
 			pdata->x_min ? : 0,
 			pdata->x_max ? : MAX_12BIT,
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index e6a31d1..b1b2e07 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -302,8 +302,8 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &pdev->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 	input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
 	input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
 	input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
index 557d781..d20689c 100644
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -320,8 +320,8 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
 	serio_set_drvdata(serio, elo);
 	err = serio_open(serio, drv);
diff --git a/drivers/input/touchscreen/fujitsu_ts.c b/drivers/input/touchscreen/fujitsu_ts.c
index daf7a4a..80b2180 100644
--- a/drivers/input/touchscreen/fujitsu_ts.c
+++ b/drivers/input/touchscreen/fujitsu_ts.c
@@ -122,8 +122,8 @@
 	input_dev->id.vendor = SERIO_FUJITSU;
 	input_dev->id.product = 0;
 	input_dev->id.version = 0x0100;
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
 	input_set_abs_params(input_dev, ABS_X, 0, 4096, 0, 0);
 	input_set_abs_params(input_dev, ABS_Y, 0, 4096, 0, 0);
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
index 39d6026..a48a158 100644
--- a/drivers/input/touchscreen/gunze.c
+++ b/drivers/input/touchscreen/gunze.c
@@ -137,8 +137,8 @@
 	input_dev->id.product = 0x0051;
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 	input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0);
 	input_set_abs_params(input_dev, ABS_Y, 24, 1000, 0, 0);
 
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
index 09ed780..2ae6c60 100644
--- a/drivers/input/touchscreen/h3600_ts_input.c
+++ b/drivers/input/touchscreen/h3600_ts_input.c
@@ -373,8 +373,9 @@
 
 	input_dev->event = h3600ts_event;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
-	input_dev->ledbit[0] = BIT(LED_SLEEP);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
+		BIT_MASK(EV_LED) | BIT_MASK(EV_PWR);
+	input_dev->ledbit[0] = BIT_MASK(LED_SLEEP);
 	input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0);
 	input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0);
 
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c
index 1a15475..c38d4e0 100644
--- a/drivers/input/touchscreen/hp680_ts_input.c
+++ b/drivers/input/touchscreen/hp680_ts_input.c
@@ -81,8 +81,8 @@
 	if (!hp680_ts_dev)
 		return -ENOMEM;
 
-	hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
-	hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	hp680_ts_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
+	hp680_ts_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
 	input_set_abs_params(hp680_ts_dev, ABS_X,
 		HP680_TS_ABS_X_MIN, HP680_TS_ABS_X_MAX, 0, 0);
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c
index 44140fe..80a6588 100644
--- a/drivers/input/touchscreen/mk712.c
+++ b/drivers/input/touchscreen/mk712.c
@@ -186,8 +186,8 @@
 	mk712_dev->open    = mk712_open;
 	mk712_dev->close   = mk712_close;
 
-	mk712_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	mk712_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	mk712_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	mk712_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 	input_set_abs_params(mk712_dev, ABS_X, 0, 0xfff, 88, 0);
 	input_set_abs_params(mk712_dev, ABS_Y, 0, 0xfff, 88, 0);
 
diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c
index 4ec3b1f..9077228 100644
--- a/drivers/input/touchscreen/mtouch.c
+++ b/drivers/input/touchscreen/mtouch.c
@@ -151,8 +151,8 @@
 	input_dev->id.product = 0;
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 	input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0);
 	input_set_abs_params(mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0);
 
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index f2c0d3c..c7f9ceb 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -113,8 +113,8 @@
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
 
-        input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-        input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+        input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+        input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
         input_set_abs_params(pm->dev, ABS_X, 0, 0x3ff, 0, 0);
         input_set_abs_params(pm->dev, ABS_Y, 0, 0x3ff, 0, 0);
 
diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c
index 3def7bb..3a5c142 100644
--- a/drivers/input/touchscreen/touchright.c
+++ b/drivers/input/touchscreen/touchright.c
@@ -125,8 +125,8 @@
 	input_dev->id.product = 0;
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 	input_set_abs_params(tr->dev, ABS_X, TR_MIN_XC, TR_MAX_XC, 0, 0);
 	input_set_abs_params(tr->dev, ABS_Y, TR_MIN_YC, TR_MAX_YC, 0, 0);
 
diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c
index ac4bdcf..763a656 100644
--- a/drivers/input/touchscreen/touchwin.c
+++ b/drivers/input/touchscreen/touchwin.c
@@ -132,8 +132,8 @@
 	input_dev->id.product = 0;
 	input_dev->id.version = 0x0100;
 	input_dev->dev.parent = &serio->dev;
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 	input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0);
 	input_set_abs_params(tw->dev, ABS_Y, TW_MIN_YC, TW_MAX_YC, 0, 0);
 
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 86aed64..7549939 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -333,10 +333,9 @@
 			timeout = msecs_to_jiffies(10);
 		}
 
-		wait_event_interruptible_timeout(ucb->ts_wait,
+		wait_event_freezable_timeout(ucb->ts_wait,
 			ucb->irq_pending || ucb->ts_restart || kthread_should_stop(),
 			timeout);
-		try_to_freeze();
 	}
 
 	/* Send the "pen off" if we are stopping with the pen still active */
@@ -518,7 +517,7 @@
 	idev->id.product	= id;
 	idev->open		= ucb1400_ts_open;
 	idev->close		= ucb1400_ts_close;
-	idev->evbit[0]		= BIT(EV_ABS);
+	idev->evbit[0]		= BIT_MASK(EV_ABS);
 
 	ucb1400_adc_enable(ucb);
 	x_res = ucb1400_ts_read_xres(ucb);
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 9fb3d5c..19055e7 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -11,8 +11,9 @@
  *  - DMC TSC-10/25
  *  - IRTOUCHSYSTEMS/UNITOP
  *  - IdealTEK URTC1000
+ *  - GoTop Super_Q2/GogoPen/PenPower tablets
  *
- * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch>
+ * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>
  * Copyright (C) by Todd E. Johnson (mtouchusb.c)
  *
  * This program is free software; you can redistribute it and/or
@@ -115,6 +116,7 @@
 	DEVTYPE_IRTOUCH,
 	DEVTYPE_IDEALTEK,
 	DEVTYPE_GENERAL_TOUCH,
+	DEVTYPE_GOTOP,
 };
 
 static struct usb_device_id usbtouch_devices[] = {
@@ -168,6 +170,12 @@
 	{USB_DEVICE(0x0dfc, 0x0001), .driver_info = DEVTYPE_GENERAL_TOUCH},
 #endif
 
+#ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
+	{USB_DEVICE(0x08f2, 0x007f), .driver_info = DEVTYPE_GOTOP},
+	{USB_DEVICE(0x08f2, 0x00ce), .driver_info = DEVTYPE_GOTOP},
+	{USB_DEVICE(0x08f2, 0x00f4), .driver_info = DEVTYPE_GOTOP},
+#endif
+
 	{}
 };
 
@@ -501,6 +509,20 @@
 #endif
 
 /*****************************************************************************
+ * GoTop Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
+static int gotop_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+	dev->x = ((pkt[1] & 0x38) << 4) | pkt[2];
+	dev->y = ((pkt[1] & 0x07) << 7) | pkt[3];
+	dev->touch = pkt[0] & 0x01;
+	return 1;
+}
+#endif
+
+
+/*****************************************************************************
  * the different device descriptors
  */
 static struct usbtouch_device_info usbtouch_dev_info[] = {
@@ -623,9 +645,19 @@
 		.max_yc		= 0x0500,
 		.rept_size	= 7,
 		.read_data	= general_touch_read_data,
-	}
+	},
 #endif
 
+#ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
+	[DEVTYPE_GOTOP] = {
+		.min_xc		= 0x0,
+		.max_xc		= 0x03ff,
+		.min_yc		= 0x0,
+		.max_yc		= 0x03ff,
+		.rept_size	= 4,
+		.read_data	= gotop_read_data,
+	},
+#endif
 };
 
 
@@ -868,8 +900,8 @@
 	input_dev->open = usbtouch_open;
 	input_dev->close = usbtouch_close;
 
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 	input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);
 	input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);
 	if (type->max_press)
diff --git a/drivers/isdn/act2000/act2000_isa.c b/drivers/isdn/act2000/act2000_isa.c
index 09ea50d..819ea85 100644
--- a/drivers/isdn/act2000/act2000_isa.c
+++ b/drivers/isdn/act2000/act2000_isa.c
@@ -126,7 +126,7 @@
 
 /*
  * Install interrupt handler, enable irq on card.
- * If irq is -1, choose next free irq, else irq is given explicitely.
+ * If irq is -1, choose next free irq, else irq is given explicitly.
  */
 int
 act2000_isa_config_irq(act2000_card * card, short irq)
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index 6df336b..acd4171 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -534,7 +534,8 @@
 			n = RBUFSIZE - tail;
 		if (!n) {
 			dev_err(inbuf->cs->dev,
-				"buffer overflow (%u bytes lost)", bytesleft);
+				"buffer overflow (%u bytes lost)\n",
+				bytesleft);
 			break;
 		}
 		if (n > bytesleft)
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c
index 7a69a18..4484a64 100644
--- a/drivers/isdn/hardware/avm/b1.c
+++ b/drivers/isdn/hardware/avm/b1.c
@@ -321,12 +321,15 @@
 	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
 	avmcard *card = cinfo->card;
 	unsigned int port = card->port;
+	unsigned long flags;
 
 	b1_reset(port);
 	b1_reset(port);
 
 	memset(cinfo->version, 0, sizeof(cinfo->version));
+	spin_lock_irqsave(&card->lock, flags);
 	capilib_release(&cinfo->ncci_head);
+	spin_unlock_irqrestore(&card->lock, flags);
 	capi_ctr_reseted(ctrl);
 }
 
@@ -361,9 +364,8 @@
 	unsigned int port = card->port;
 	unsigned long flags;
 
-	capilib_release_appl(&cinfo->ncci_head, appl);
-
 	spin_lock_irqsave(&card->lock, flags);
+	capilib_release_appl(&cinfo->ncci_head, appl);
 	b1_put_byte(port, SEND_RELEASE);
 	b1_put_word(port, appl);
 	spin_unlock_irqrestore(&card->lock, flags);
@@ -380,27 +382,27 @@
 	u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
 	u16 dlen, retval;
 
+	spin_lock_irqsave(&card->lock, flags);
 	if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
 		retval = capilib_data_b3_req(&cinfo->ncci_head,
 					     CAPIMSG_APPID(skb->data),
 					     CAPIMSG_NCCI(skb->data),
 					     CAPIMSG_MSGID(skb->data));
-		if (retval != CAPI_NOERROR) 
+		if (retval != CAPI_NOERROR) {
+			spin_unlock_irqrestore(&card->lock, flags);
 			return retval;
+		}
 
 		dlen = CAPIMSG_DATALEN(skb->data);
 
-	 	spin_lock_irqsave(&card->lock, flags);
 		b1_put_byte(port, SEND_DATA_B3_REQ);
 		b1_put_slice(port, skb->data, len);
 		b1_put_slice(port, skb->data + len, dlen);
-		spin_unlock_irqrestore(&card->lock, flags);
 	} else {
-	 	spin_lock_irqsave(&card->lock, flags);
 		b1_put_byte(port, SEND_MESSAGE);
 		b1_put_slice(port, skb->data, len);
-		spin_unlock_irqrestore(&card->lock, flags);
 	}
+	spin_unlock_irqrestore(&card->lock, flags);
 
 	dev_kfree_skb_any(skb);
 	return CAPI_NOERROR;
@@ -534,17 +536,17 @@
 
 		ApplId = (unsigned) b1_get_word(card->port);
 		MsgLen = b1_get_slice(card->port, card->msgbuf);
-		spin_unlock_irqrestore(&card->lock, flags);
 		if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
 			printk(KERN_ERR "%s: incoming packet dropped\n",
 					card->name);
+			spin_unlock_irqrestore(&card->lock, flags);
 		} else {
 			memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
 			if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
 				capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
 						     CAPIMSG_NCCI(skb->data),
 						     CAPIMSG_MSGID(skb->data));
-
+			spin_unlock_irqrestore(&card->lock, flags);
 			capi_ctr_handle_message(ctrl, ApplId, skb);
 		}
 		break;
@@ -554,21 +556,17 @@
 		ApplId = b1_get_word(card->port);
 		NCCI = b1_get_word(card->port);
 		WindowSize = b1_get_word(card->port);
-		spin_unlock_irqrestore(&card->lock, flags);
-
 		capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
-
+		spin_unlock_irqrestore(&card->lock, flags);
 		break;
 
 	case RECEIVE_FREE_NCCI:
 
 		ApplId = b1_get_word(card->port);
 		NCCI = b1_get_word(card->port);
-		spin_unlock_irqrestore(&card->lock, flags);
-
 		if (NCCI != 0xffffffff)
 			capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
-	       
+		spin_unlock_irqrestore(&card->lock, flags);
 		break;
 
 	case RECEIVE_START:
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c
index 428872b..669f6f6 100644
--- a/drivers/isdn/hardware/avm/b1dma.c
+++ b/drivers/isdn/hardware/avm/b1dma.c
@@ -486,11 +486,13 @@
 					card->name);
 		} else {
 			memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
-			if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
+			if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) {
+				spin_lock(&card->lock);
 				capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
-						     CAPIMSG_NCCI(skb->data),
-						     CAPIMSG_MSGID(skb->data));
-
+					CAPIMSG_NCCI(skb->data),
+					CAPIMSG_MSGID(skb->data));
+				spin_unlock(&card->lock);
+			}
 			capi_ctr_handle_message(ctrl, ApplId, skb);
 		}
 		break;
@@ -500,9 +502,9 @@
 		ApplId = _get_word(&p);
 		NCCI = _get_word(&p);
 		WindowSize = _get_word(&p);
-
+		spin_lock(&card->lock);
 		capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
-
+		spin_unlock(&card->lock);
 		break;
 
 	case RECEIVE_FREE_NCCI:
@@ -510,9 +512,11 @@
 		ApplId = _get_word(&p);
 		NCCI = _get_word(&p);
 
-		if (NCCI != 0xffffffff)
+		if (NCCI != 0xffffffff) {
+			spin_lock(&card->lock);
 			capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
-
+			spin_unlock(&card->lock);
+		}
 		break;
 
 	case RECEIVE_START:
@@ -751,10 +755,10 @@
 
 	spin_lock_irqsave(&card->lock, flags);
  	b1dma_reset(card);
-	spin_unlock_irqrestore(&card->lock, flags);
 
 	memset(cinfo->version, 0, sizeof(cinfo->version));
 	capilib_release(&cinfo->ncci_head);
+	spin_unlock_irqrestore(&card->lock, flags);
 	capi_ctr_reseted(ctrl);
 }
 
@@ -803,8 +807,11 @@
 	avmcard *card = cinfo->card;
 	struct sk_buff *skb;
 	void *p;
+	unsigned long flags;
 
+	spin_lock_irqsave(&card->lock, flags);
 	capilib_release_appl(&cinfo->ncci_head, appl);
+	spin_unlock_irqrestore(&card->lock, flags);
 
 	skb = alloc_skb(7, GFP_ATOMIC);
 	if (!skb) {
@@ -832,10 +839,13 @@
 	u16 retval = CAPI_NOERROR;
 
  	if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
+		unsigned long flags;
+		spin_lock_irqsave(&card->lock, flags);
 		retval = capilib_data_b3_req(&cinfo->ncci_head,
 					     CAPIMSG_APPID(skb->data),
 					     CAPIMSG_NCCI(skb->data),
 					     CAPIMSG_MSGID(skb->data));
+		spin_unlock_irqrestore(&card->lock, flags);
 	}
 	if (retval == CAPI_NOERROR) 
 		b1dma_queue_tx(card, skb);
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index d58f927..4bbbbe6 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -678,7 +678,9 @@
                 for (i=0; i < card->nr_controllers; i++) {
 			avmctrl_info *cinfo = &card->ctrlinfo[i];
 			memset(cinfo->version, 0, sizeof(cinfo->version));
+			spin_lock_irqsave(&card->lock, flags);
 			capilib_release(&cinfo->ncci_head);
+			spin_unlock_irqrestore(&card->lock, flags);
 			capi_ctr_reseted(&cinfo->capi_ctrl);
 		}
 		card->nlogcontr = 0;
@@ -727,6 +729,7 @@
 {
 	struct sk_buff *skb;
 	void *p;
+	unsigned long flags;
 
 	skb = alloc_skb(15, GFP_ATOMIC);
 	if (!skb) {
@@ -744,12 +747,15 @@
 	skb_put(skb, (u8 *)p - (u8 *)skb->data);
 
 	skb_queue_tail(&card->dma->send_queue, skb);
+	spin_lock_irqsave(&card->lock, flags);
 	c4_dispatch_tx(card);
+	spin_unlock_irqrestore(&card->lock, flags);
 }
 
 static int queue_sendconfigword(avmcard *card, u32 val)
 {
 	struct sk_buff *skb;
+	unsigned long flags;
 	void *p;
 
 	skb = alloc_skb(3+4, GFP_ATOMIC);
@@ -766,7 +772,9 @@
 	skb_put(skb, (u8 *)p - (u8 *)skb->data);
 
 	skb_queue_tail(&card->dma->send_queue, skb);
+	spin_lock_irqsave(&card->lock, flags);
 	c4_dispatch_tx(card);
+	spin_unlock_irqrestore(&card->lock, flags);
 	return 0;
 }
 
@@ -986,7 +994,9 @@
 	struct sk_buff *skb;
 	void *p;
 
+	spin_lock_irqsave(&card->lock, flags);
 	capilib_release_appl(&cinfo->ncci_head, appl);
+	spin_unlock_irqrestore(&card->lock, flags);
 
 	if (ctrl->cnr == card->cardnr) {
 		skb = alloc_skb(7, GFP_ATOMIC);
@@ -1019,7 +1029,8 @@
 	u16 retval = CAPI_NOERROR;
 	unsigned long flags;
 
- 	if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
+	spin_lock_irqsave(&card->lock, flags);
+	if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
 		retval = capilib_data_b3_req(&cinfo->ncci_head,
 					     CAPIMSG_APPID(skb->data),
 					     CAPIMSG_NCCI(skb->data),
@@ -1027,10 +1038,9 @@
 	}
 	if (retval == CAPI_NOERROR) {
 		skb_queue_tail(&card->dma->send_queue, skb);
-		spin_lock_irqsave(&card->lock, flags);
 		c4_dispatch_tx(card);
-		spin_unlock_irqrestore(&card->lock, flags);
 	}
+	spin_unlock_irqrestore(&card->lock, flags);
 	return retval;
 }
 
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c
index c925020..6130724 100644
--- a/drivers/isdn/hardware/avm/t1isa.c
+++ b/drivers/isdn/hardware/avm/t1isa.c
@@ -180,8 +180,8 @@
 
 			ApplId = (unsigned) b1_get_word(card->port);
 			MsgLen = t1_get_slice(card->port, card->msgbuf);
-			spin_unlock_irqrestore(&card->lock, flags);
 			if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
+				spin_unlock_irqrestore(&card->lock, flags);
 				printk(KERN_ERR "%s: incoming packet dropped\n",
 						card->name);
 			} else {
@@ -190,7 +190,7 @@
 					capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
 							     CAPIMSG_NCCI(skb->data),
 							     CAPIMSG_MSGID(skb->data));
-
+				spin_unlock_irqrestore(&card->lock, flags);
 				capi_ctr_handle_message(ctrl, ApplId, skb);
 			}
 			break;
@@ -200,21 +200,17 @@
 			ApplId = b1_get_word(card->port);
 			NCCI = b1_get_word(card->port);
 			WindowSize = b1_get_word(card->port);
-			spin_unlock_irqrestore(&card->lock, flags);
-
 			capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
-
+			spin_unlock_irqrestore(&card->lock, flags);
 			break;
 
 		case RECEIVE_FREE_NCCI:
 
 			ApplId = b1_get_word(card->port);
 			NCCI = b1_get_word(card->port);
-			spin_unlock_irqrestore(&card->lock, flags);
-
 			if (NCCI != 0xffffffff)
 				capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
-
+			spin_unlock_irqrestore(&card->lock, flags);
 			break;
 
 		case RECEIVE_START:
@@ -333,13 +329,16 @@
 	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
 	avmcard *card = cinfo->card;
 	unsigned int port = card->port;
+	unsigned long flags;
 
 	t1_disable_irq(port);
 	b1_reset(port);
 	b1_reset(port);
 
 	memset(cinfo->version, 0, sizeof(cinfo->version));
+	spin_lock_irqsave(&card->lock, flags);
 	capilib_release(&cinfo->ncci_head);
+	spin_unlock_irqrestore(&card->lock, flags);
 	capi_ctr_reseted(ctrl);
 }
 
@@ -466,29 +465,26 @@
 	u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
 	u16 dlen, retval;
 
+	spin_lock_irqsave(&card->lock, flags);
 	if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
 		retval = capilib_data_b3_req(&cinfo->ncci_head,
 					     CAPIMSG_APPID(skb->data),
 					     CAPIMSG_NCCI(skb->data),
 					     CAPIMSG_MSGID(skb->data));
-		if (retval != CAPI_NOERROR) 
+		if (retval != CAPI_NOERROR) {
+			spin_unlock_irqrestore(&card->lock, flags);
 			return retval;
-
+		}
 		dlen = CAPIMSG_DATALEN(skb->data);
 
-		spin_lock_irqsave(&card->lock, flags);
 		b1_put_byte(port, SEND_DATA_B3_REQ);
 		t1_put_slice(port, skb->data, len);
 		t1_put_slice(port, skb->data + len, dlen);
-		spin_unlock_irqrestore(&card->lock, flags);
 	} else {
-
-		spin_lock_irqsave(&card->lock, flags);
 		b1_put_byte(port, SEND_MESSAGE);
 		t1_put_slice(port, skb->data, len);
-		spin_unlock_irqrestore(&card->lock, flags);
 	}
-
+	spin_unlock_irqrestore(&card->lock, flags);
 	dev_kfree_skb_any(skb);
 	return CAPI_NOERROR;
 }
diff --git a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c
index 82edc1c..4d425c6 100644
--- a/drivers/isdn/hardware/eicon/capifunc.c
+++ b/drivers/isdn/hardware/eicon/capifunc.c
@@ -321,7 +321,7 @@
 				  DBG_BLK((((char *)(long)GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
 				  	((dlength - i) < 256) ? (dlength - i) : 256))
 				  if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
-					  break; /* not more if not explicitely requested */
+					  break; /* not more if not explicitly requested */
 				}
 			}
 			break;
@@ -965,7 +965,7 @@
 					((GET_WORD(&msg->info.data_b3_req.Data_Length) - j) <
 					  256) ? (GET_WORD(&msg->info.data_b3_req.Data_Length) - j) : 256))
 				if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
-					break;	/* not more if not explicitely requested */
+					break;	/* not more if not explicitly requested */
 			}
 		}
 #endif
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index 3b19cae..c0d7036 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -767,7 +767,7 @@
                 /* read */
                 if (*ptr++ >= 0x100) {
 			if (cmd < 8)
-                                /* setzt Register zurück */
+                                /* reset register */
                                 rByteAMD(cs, cmd);
 			else {
 				wByteAMD(cs, 0x00, cmd);
diff --git a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c
index b73027f..39f421e 100644
--- a/drivers/isdn/hisax/enternow_pci.c
+++ b/drivers/isdn/hisax/enternow_pci.c
@@ -75,16 +75,16 @@
 static const char *enternow_pci_rev = "$Revision: 1.1.4.5 $";
 
 
-/* für PowerISDN PCI */
+/* for PowerISDN PCI */
 #define TJ_AMD_IRQ                                              0x20
 #define TJ_LED1                                                 0x40
 #define TJ_LED2                                                 0x80
 
 
-/* Das Fenster zum AMD...
- * Ab Adresse hw.njet.base + TJ_AMD_PORT werden vom AMD jeweils 8 Bit in
- * den TigerJet i/o-Raum gemappt
- * -> 0x01 des AMD bei hw.njet.base + 0C4 */
+/* The window to [the] AMD [chip]...
+ * From address hw.njet.base + TJ_AMD_PORT onwards, the AMD
+ * maps [consecutive/multiple] 8 bits into the TigerJet I/O space
+ * -> 0x01 of the AMD at hw.njet.base + 0C4 */
 #define TJ_AMD_PORT                                             0xC0
 
 
@@ -96,11 +96,11 @@
 static unsigned char
 ReadByteAmd7930(struct IsdnCardState *cs, unsigned char offset)
 {
-	/* direktes Register */
+	/* direct register */
 	if(offset < 8)
 		return (inb(cs->hw.njet.isac + 4*offset));
 
-	/* indirektes Register */
+	/* indirect register */
 	else {
 		outb(offset, cs->hw.njet.isac + 4*AMD_CR);
 		return(inb(cs->hw.njet.isac + 4*AMD_DR));
@@ -111,11 +111,11 @@
 static void
 WriteByteAmd7930(struct IsdnCardState *cs, unsigned char offset, unsigned char value)
 {
-	/* direktes Register */
+	/* direct register */
 	if(offset < 8)
 		outb(value, cs->hw.njet.isac + 4*offset);
 
-	/* indirektes Register */
+	/* indirect register */
 	else {
 		outb(offset, cs->hw.njet.isac + 4*AMD_CR);
 		outb(value, cs->hw.njet.isac + 4*AMD_DR);
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 077080a..fba8b62 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1,6 +1,6 @@
 /* $Id: hfc_pci.c,v 1.48.2.4 2004/02/11 13:21:33 keil Exp $
  *
- * low level driver for CCD´s hfc-pci based cards
+ * low level driver for CCD's hfc-pci based cards
  *
  * Author       Werner Cornelius
  *              based on existing driver for CCD hfc ISA cards
diff --git a/drivers/isdn/hisax/isdnhdlc.c b/drivers/isdn/hisax/isdnhdlc.c
index 268dced..c69a77a 100644
--- a/drivers/isdn/hisax/isdnhdlc.c
+++ b/drivers/isdn/hisax/isdnhdlc.c
@@ -1,7 +1,7 @@
 /*
  * isdnhdlc.c  --  General purpose ISDN HDLC decoder.
  *
- *Copyright (C) 2002	Wolfgang Mües      <wolfgang@iksw-muees.de>
+ *Copyright (C) 2002	Wolfgang Mües      <wolfgang@iksw-muees.de>
  *		2001 	Frode Isaksen      <fisaksen@bewan.com>
  *              2001 	Kai Germaschewski  <kai.germaschewski@gmx.de>
  *
@@ -27,7 +27,7 @@
 
 /*-------------------------------------------------------------------*/
 
-MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
+MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
 	      "Frode Isaksen <fisaksen@bewan.com>, "
 	      "Kai Germaschewski <kai.germaschewski@gmx.de>");
 MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
diff --git a/drivers/isdn/hisax/isdnhdlc.h b/drivers/isdn/hisax/isdnhdlc.h
index 45167d2..cf0a95a 100644
--- a/drivers/isdn/hisax/isdnhdlc.h
+++ b/drivers/isdn/hisax/isdnhdlc.h
@@ -5,7 +5,7 @@
  * Neccessary because some ISDN devices don't have HDLC
  * controllers. Also included: a bit reversal table.
  *
- *Copyright (C) 2002    Wolfgang Mües      <wolfgang@iksw-muees.de>
+ *Copyright (C) 2002    Wolfgang Mües      <wolfgang@iksw-muees.de>
  *		2001 	Frode Isaksen      <fisaksen@bewan.com>
  *              2001 	Kai Germaschewski  <kai.germaschewski@gmx.de>
  *
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c
index 43d61d1..70840a7 100644
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -304,7 +304,7 @@
 	cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR,  0x00);
 	/* Setup host access to hdlc controller */
 	jade_write_indirect(cs, jade_HDLCCNTRACCESS, (jadeINDIRECT_HAH1|jadeINDIRECT_HAH2));
-	/* Unmask HDLC int (don´t forget DSP int later on)*/
+	/* Unmask HDLC int (don't forget DSP int later on)*/
 	cs->BC_Write_Reg(cs, -1,jade_INT, (jadeINT_HDLC1|jadeINT_HDLC2));
 
 	/* once again TRANSPARENT */	
diff --git a/drivers/isdn/pcbit/capi.c b/drivers/isdn/pcbit/capi.c
index 7b55e15..ac5a91c 100644
--- a/drivers/isdn/pcbit/capi.c
+++ b/drivers/isdn/pcbit/capi.c
@@ -15,9 +15,9 @@
 
 /*
  *        Documentation:
- *        - "Common ISDN API - Perfil Português - Versão 2.1",
+ *        - "Common ISDN API - Perfil Português - Versão 2.1",
  *           Telecom Portugal, Fev 1992.
- *        - "Common ISDN API - Especificação de protocolos para 
+ *        - "Common ISDN API - Especificação de protocolos para
  *           acesso aos canais B", Inesc, Jan 1994.
  */
 
diff --git a/drivers/isdn/sc/debug.h b/drivers/isdn/sc/debug.h
deleted file mode 100644
index e9db96e..0000000
--- a/drivers/isdn/sc/debug.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* $Id: debug.h,v 1.2.8.1 2001/09/23 22:24:59 kai Exp $
- *
- * Copyright (C) 1996  SpellCaster Telecommunications Inc.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * For more information, please contact gpl-info@spellcast.com or write:
- *
- *     SpellCaster Telecommunications Inc.
- *     5621 Finch Avenue East, Unit #3
- *     Scarborough, Ontario  Canada
- *     M1B 2T9
- *     +1 (416) 297-8565
- *     +1 (416) 297-6433 Facsimile
- */
-
-#define REQUEST_IRQ(a,b,c,d,e) request_irq(a,b,c,d,e)
-#define FREE_IRQ(a,b) free_irq(a,b)
diff --git a/drivers/isdn/sc/includes.h b/drivers/isdn/sc/includes.h
index 5286e0c..4766e5b 100644
--- a/drivers/isdn/sc/includes.h
+++ b/drivers/isdn/sc/includes.h
@@ -14,4 +14,3 @@
 #include <linux/timer.h>
 #include <linux/wait.h>
 #include <linux/isdnif.h>
-#include "debug.h"
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 0bf7634..d09c854 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -404,7 +404,7 @@
 		/*
 		 * Release the IRQ
 		 */
-		FREE_IRQ(sc_adapter[i]->interrupt, NULL);
+		free_irq(sc_adapter[i]->interrupt, NULL);
 
 		/*
 		 * Reset for a clean start
diff --git a/drivers/kvm/Kconfig b/drivers/kvm/Kconfig
index 8749fa4..6569206 100644
--- a/drivers/kvm/Kconfig
+++ b/drivers/kvm/Kconfig
@@ -47,4 +47,8 @@
 	  Provides support for KVM on AMD processors equipped with the AMD-V
 	  (SVM) extensions.
 
+# OK, it's a little counter-intuitive to do this, but it puts it neatly under
+# the virtualization menu.
+source drivers/lguest/Kconfig
+
 endif # VIRTUALIZATION
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index af2d288..07ae280 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -198,21 +198,15 @@
 
 static void ack_flush(void *_completed)
 {
-	atomic_t *completed = _completed;
-
-	atomic_inc(completed);
 }
 
 void kvm_flush_remote_tlbs(struct kvm *kvm)
 {
-	int i, cpu, needed;
+	int i, cpu;
 	cpumask_t cpus;
 	struct kvm_vcpu *vcpu;
-	atomic_t completed;
 
-	atomic_set(&completed, 0);
 	cpus_clear(cpus);
-	needed = 0;
 	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
 		vcpu = kvm->vcpus[i];
 		if (!vcpu)
@@ -221,23 +215,9 @@
 			continue;
 		cpu = vcpu->cpu;
 		if (cpu != -1 && cpu != raw_smp_processor_id())
-			if (!cpu_isset(cpu, cpus)) {
-				cpu_set(cpu, cpus);
-				++needed;
-			}
+			cpu_set(cpu, cpus);
 	}
-
-	/*
-	 * We really want smp_call_function_mask() here.  But that's not
-	 * available, so ipi all cpus in parallel and wait for them
-	 * to complete.
-	 */
-	for (cpu = first_cpu(cpus); cpu != NR_CPUS; cpu = next_cpu(cpu, cpus))
-		smp_call_function_single(cpu, ack_flush, &completed, 1, 0);
-	while (atomic_read(&completed) != needed) {
-		cpu_relax();
-		barrier();
-	}
+	smp_call_function_mask(cpus, ack_flush, NULL, 1);
 }
 
 int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
@@ -2054,12 +2034,21 @@
 
 	kvm_x86_ops->run(vcpu, kvm_run);
 
-	kvm_guest_exit();
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 
 	++vcpu->stat.exits;
 
+	/*
+	 * We must have an instruction between local_irq_enable() and
+	 * kvm_guest_exit(), so the timer interrupt isn't delayed by
+	 * the interrupt shadow.  The stat.exits increment will do nicely.
+	 * But we need to prevent reordering, hence this barrier():
+	 */
+	barrier();
+
+	kvm_guest_exit();
+
 	preempt_enable();
 
 	/*
diff --git a/drivers/kvm/lapic.c b/drivers/kvm/lapic.c
index a190587..238fcad 100644
--- a/drivers/kvm/lapic.c
+++ b/drivers/kvm/lapic.c
@@ -494,12 +494,19 @@
 
 static u32 apic_get_tmcct(struct kvm_lapic *apic)
 {
-	u32 counter_passed;
-	ktime_t passed, now = apic->timer.dev.base->get_time();
-	u32 tmcct = apic_get_reg(apic, APIC_TMICT);
+	u64 counter_passed;
+	ktime_t passed, now;
+	u32 tmcct;
 
 	ASSERT(apic != NULL);
 
+	now = apic->timer.dev.base->get_time();
+	tmcct = apic_get_reg(apic, APIC_TMICT);
+
+	/* if initial count is 0, current count should also be 0 */
+	if (tmcct == 0)
+		return 0;
+
 	if (unlikely(ktime_to_ns(now) <=
 		ktime_to_ns(apic->timer.last_update))) {
 		/* Wrap around */
@@ -514,15 +521,24 @@
 
 	counter_passed = div64_64(ktime_to_ns(passed),
 				  (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
-	tmcct -= counter_passed;
 
-	if (tmcct <= 0) {
-		if (unlikely(!apic_lvtt_period(apic)))
+	if (counter_passed > tmcct) {
+		if (unlikely(!apic_lvtt_period(apic))) {
+			/* one-shot timers stick at 0 until reset */
 			tmcct = 0;
-		else
-			do {
-				tmcct += apic_get_reg(apic, APIC_TMICT);
-			} while (tmcct <= 0);
+		} else {
+			/*
+			 * periodic timers reset to APIC_TMICT when they
+			 * hit 0. The while loop simulates this happening N
+			 * times. (counter_passed %= tmcct) would also work,
+			 * but might be slower or not work on 32-bit??
+			 */
+			while (counter_passed > tmcct)
+				counter_passed -= tmcct;
+			tmcct -= counter_passed;
+		}
+	} else {
+		tmcct -= counter_passed;
 	}
 
 	return tmcct;
@@ -853,7 +869,7 @@
 		apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
 		apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
 	}
-	apic->timer.divide_count = 0;
+	update_divide_count(apic);
 	atomic_set(&apic->timer.pending, 0);
 	if (vcpu->vcpu_id == 0)
 		vcpu->apic_base |= MSR_IA32_APICBASE_BSP;
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index 6d84d30..feb5ac9 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -1049,6 +1049,7 @@
 	destroy_kvm_mmu(vcpu);
 	return init_kvm_mmu(vcpu);
 }
+EXPORT_SYMBOL_GPL(kvm_mmu_reset_context);
 
 int kvm_mmu_load(struct kvm_vcpu *vcpu)
 {
@@ -1088,7 +1089,7 @@
 			mmu_page_remove_parent_pte(child, spte);
 		}
 	}
-	*spte = 0;
+	set_shadow_pte(spte, 0);
 	kvm_flush_remote_tlbs(vcpu->kvm);
 }
 
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 4f115a8..bb56ae3 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -523,6 +523,8 @@
 
 static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
 {
+	if (vcpu->rmode.active)
+		rflags |= IOPL_MASK | X86_EFLAGS_VM;
 	vmcs_writel(GUEST_RFLAGS, rflags);
 }
 
@@ -1128,6 +1130,7 @@
 	fix_rmode_seg(VCPU_SREG_GS, &vcpu->rmode.gs);
 	fix_rmode_seg(VCPU_SREG_FS, &vcpu->rmode.fs);
 
+	kvm_mmu_reset_context(vcpu);
 	init_rmode_tss(vcpu->kvm);
 }
 
@@ -1760,10 +1763,8 @@
 		set_bit(irq / BITS_PER_LONG, &vcpu->irq_summary);
 	}
 
-	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) { /* nmi */
-		asm ("int $2");
-		return 1;
-	}
+	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */
+		return 1;  /* already handled by vmx_vcpu_run() */
 
 	if (is_no_device(intr_info)) {
 		vmx_fpu_activate(vcpu);
@@ -2196,6 +2197,7 @@
 static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	u32 intr_info;
 
 	/*
 	 * Loading guest fpu may have cleared host cr0.ts
@@ -2322,6 +2324,12 @@
 
 	asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
 	vmx->launched = 1;
+
+	intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+
+	/* We need to handle NMIs before interrupts are enabled */
+	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */
+		asm("int $2");
 }
 
 static void vmx_inject_page_fault(struct kvm_vcpu *vcpu,
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 9737c3b..a6ace30 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -212,7 +212,8 @@
 	0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
 	    DstReg | SrcMem16 | ModRM | Mov,
 	/* 0xC0 - 0xCF */
-	0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM,
+	0, 0, 0, 0, 0, 0, 0, 0,
 	/* 0xD0 - 0xDF */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	/* 0xE0 - 0xEF */
@@ -596,11 +597,10 @@
 		case 0xf0:	/* LOCK */
 			lock_prefix = 1;
 			break;
+		case 0xf2:	/* REPNE/REPNZ */
 		case 0xf3:	/* REP/REPE/REPZ */
 			rep_prefix = 1;
 			break;
-		case 0xf2:	/* REPNE/REPNZ */
-			break;
 		default:
 			goto done_prefixes;
 		}
@@ -825,6 +825,14 @@
 		if (twobyte && b == 0x01 && modrm_reg == 7)
 			break;
 	      srcmem_common:
+		/*
+		 * For instructions with a ModR/M byte, switch to register
+		 * access if Mod = 3.
+		 */
+		if ((d & ModRM) && modrm_mod == 3) {
+			src.type = OP_REG;
+			break;
+		}
 		src.type = OP_MEM;
 		src.ptr = (unsigned long *)cr2;
 		src.val = 0;
@@ -893,6 +901,14 @@
 		dst.ptr = (unsigned long *)cr2;
 		dst.bytes = (d & ByteOp) ? 1 : op_bytes;
 		dst.val = 0;
+		/*
+		 * For instructions with a ModR/M byte, switch to register
+		 * access if Mod = 3.
+		 */
+		if ((d & ModRM) && modrm_mod == 3) {
+			dst.type = OP_REG;
+			break;
+		}
 		if (d & BitOp) {
 			unsigned long mask = ~(dst.bytes * 8 - 1);
 
@@ -1083,31 +1099,6 @@
 	case 0xd2 ... 0xd3:	/* Grp2 */
 		src.val = _regs[VCPU_REGS_RCX];
 		goto grp2;
-	case 0xe8: /* call (near) */ {
-		long int rel;
-		switch (op_bytes) {
-		case 2:
-			rel = insn_fetch(s16, 2, _eip);
-			break;
-		case 4:
-			rel = insn_fetch(s32, 4, _eip);
-			break;
-		case 8:
-			rel = insn_fetch(s64, 8, _eip);
-			break;
-		default:
-			DPRINTF("Call: Invalid op_bytes\n");
-			goto cannot_emulate;
-		}
-		src.val = (unsigned long) _eip;
-		JMP_REL(rel);
-		goto push;
-	}
-	case 0xe9: /* jmp rel */
-	case 0xeb: /* jmp rel short */
-		JMP_REL(src.val);
-		no_wb = 1; /* Disable writeback. */
-		break;
 	case 0xf6 ... 0xf7:	/* Grp3 */
 		switch (modrm_reg) {
 		case 0 ... 1:	/* test */
@@ -1350,6 +1341,32 @@
 	case 0xae ... 0xaf:	/* scas */
 		DPRINTF("Urk! I don't handle SCAS.\n");
 		goto cannot_emulate;
+	case 0xe8: /* call (near) */ {
+		long int rel;
+		switch (op_bytes) {
+		case 2:
+			rel = insn_fetch(s16, 2, _eip);
+			break;
+		case 4:
+			rel = insn_fetch(s32, 4, _eip);
+			break;
+		case 8:
+			rel = insn_fetch(s64, 8, _eip);
+			break;
+		default:
+			DPRINTF("Call: Invalid op_bytes\n");
+			goto cannot_emulate;
+		}
+		src.val = (unsigned long) _eip;
+		JMP_REL(rel);
+		goto push;
+	}
+	case 0xe9: /* jmp rel */
+	case 0xeb: /* jmp rel short */
+		JMP_REL(src.val);
+		no_wb = 1; /* Disable writeback. */
+		break;
+
 
 	}
 	goto writeback;
@@ -1501,6 +1518,10 @@
 		dst.bytes = op_bytes;
 		dst.val = (d & ByteOp) ? (s8) src.val : (s16) src.val;
 		break;
+	case 0xc3:		/* movnti */
+		dst.bytes = op_bytes;
+		dst.val = (op_bytes == 4) ? (u32) src.val : (u64) src.val;
+		break;
 	}
 	goto writeback;
 
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c
index 5091443..0fd6407 100644
--- a/drivers/leds/leds-s3c24xx.c
+++ b/drivers/leds/leds-s3c24xx.c
@@ -43,7 +43,7 @@
 	struct s3c24xx_gpio_led *led = to_gpio(led_cdev);
 	struct s3c24xx_led_platdata *pd = led->pdata;
 
-	/* there will be a sort delay between setting the output and
+	/* there will be a short delay between setting the output and
 	 * going from output to input when using tristate. */
 
 	s3c2410_gpio_setpin(pd->gpio, (value ? 1 : 0) ^
diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig
index 41e2250..7eb9ecf 100644
--- a/drivers/lguest/Kconfig
+++ b/drivers/lguest/Kconfig
@@ -1,7 +1,6 @@
 config LGUEST
 	tristate "Linux hypervisor example code"
-	depends on X86 && PARAVIRT && EXPERIMENTAL && !X86_PAE && FUTEX
-	select LGUEST_GUEST
+	depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX && !(X86_VISWS || X86_VOYAGER)
 	select HVC_DRIVER
 	---help---
 	  This is a very simple module which allows you to run
@@ -18,13 +17,3 @@
 	  The guest needs code built-in, even if the host has lguest
 	  support as a module.  The drivers are tiny, so we build them
 	  in too.
-
-config LGUEST_NET
-	tristate
-	default y
-	depends on LGUEST_GUEST && NET
-
-config LGUEST_BLOCK
-	tristate
-	default y
-	depends on LGUEST_GUEST && BLOCK
diff --git a/drivers/lguest/Makefile b/drivers/lguest/Makefile
index e504747..5e8272d 100644
--- a/drivers/lguest/Makefile
+++ b/drivers/lguest/Makefile
@@ -1,10 +1,12 @@
-# Guest requires the paravirt_ops replacement and the bus driver.
-obj-$(CONFIG_LGUEST_GUEST) += lguest.o lguest_asm.o lguest_bus.o
+# Guest requires the device configuration and probing code.
+obj-$(CONFIG_LGUEST_GUEST) += lguest_device.o
 
 # Host requires the other files, which can be a module.
 obj-$(CONFIG_LGUEST)	+= lg.o
-lg-y := core.o hypercalls.o page_tables.o interrupts_and_traps.o \
-	segments.o io.o lguest_user.o switcher.o
+lg-y = core.o hypercalls.o page_tables.o interrupts_and_traps.o \
+	segments.o lguest_user.o
+
+lg-$(CONFIG_X86_32) += x86/switcher_32.o x86/core.o
 
 Preparation Preparation!: PREFIX=P
 Guest: PREFIX=G
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index a0788c1..35d19ae 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -11,58 +11,20 @@
 #include <linux/vmalloc.h>
 #include <linux/cpu.h>
 #include <linux/freezer.h>
+#include <linux/highmem.h>
 #include <asm/paravirt.h>
-#include <asm/desc.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/poll.h>
-#include <asm/highmem.h>
 #include <asm/asm-offsets.h>
-#include <asm/i387.h>
 #include "lg.h"
 
-/* Found in switcher.S */
-extern char start_switcher_text[], end_switcher_text[], switch_to_guest[];
-extern unsigned long default_idt_entries[];
-
-/* Every guest maps the core switcher code. */
-#define SHARED_SWITCHER_PAGES \
-	DIV_ROUND_UP(end_switcher_text - start_switcher_text, PAGE_SIZE)
-/* Pages for switcher itself, then two pages per cpu */
-#define TOTAL_SWITCHER_PAGES (SHARED_SWITCHER_PAGES + 2 * NR_CPUS)
-
-/* We map at -4M for ease of mapping into the guest (one PTE page). */
-#define SWITCHER_ADDR 0xFFC00000
 
 static struct vm_struct *switcher_vma;
 static struct page **switcher_page;
 
-static int cpu_had_pge;
-static struct {
-	unsigned long offset;
-	unsigned short segment;
-} lguest_entry;
-
 /* This One Big lock protects all inter-guest data structures. */
 DEFINE_MUTEX(lguest_lock);
-static DEFINE_PER_CPU(struct lguest *, last_guest);
-
-/* FIXME: Make dynamic. */
-#define MAX_LGUEST_GUESTS 16
-struct lguest lguests[MAX_LGUEST_GUESTS];
-
-/* Offset from where switcher.S was compiled to where we've copied it */
-static unsigned long switcher_offset(void)
-{
-	return SWITCHER_ADDR - (unsigned long)start_switcher_text;
-}
-
-/* This cpu's struct lguest_pages. */
-static struct lguest_pages *lguest_pages(unsigned int cpu)
-{
-	return &(((struct lguest_pages *)
-		  (SWITCHER_ADDR + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]);
-}
 
 /*H:010 We need to set up the Switcher at a high virtual address.  Remember the
  * Switcher is a few hundred bytes of assembler code which actually changes the
@@ -73,9 +35,7 @@
  * Host since it will be running as the switchover occurs.
  *
  * Trying to map memory at a particular address is an unusual thing to do, so
- * it's not a simple one-liner.  We also set up the per-cpu parts of the
- * Switcher here.
- */
+ * it's not a simple one-liner. */
 static __init int map_switcher(void)
 {
 	int i, err;
@@ -132,90 +92,11 @@
 		goto free_vma;
 	}
 
-	/* Now the switcher is mapped at the right address, we can't fail!
-	 * Copy in the compiled-in Switcher code (from switcher.S). */
+	/* Now the Switcher is mapped at the right address, we can't fail!
+	 * Copy in the compiled-in Switcher code (from <arch>_switcher.S). */
 	memcpy(switcher_vma->addr, start_switcher_text,
 	       end_switcher_text - start_switcher_text);
 
-	/* Most of the switcher.S doesn't care that it's been moved; on Intel,
-	 * jumps are relative, and it doesn't access any references to external
-	 * code or data.
-	 *
-	 * The only exception is the interrupt handlers in switcher.S: their
-	 * addresses are placed in a table (default_idt_entries), so we need to
-	 * update the table with the new addresses.  switcher_offset() is a
-	 * convenience function which returns the distance between the builtin
-	 * switcher code and the high-mapped copy we just made. */
-	for (i = 0; i < IDT_ENTRIES; i++)
-		default_idt_entries[i] += switcher_offset();
-
-	/*
-	 * Set up the Switcher's per-cpu areas.
-	 *
-	 * Each CPU gets two pages of its own within the high-mapped region
-	 * (aka. "struct lguest_pages").  Much of this can be initialized now,
-	 * but some depends on what Guest we are running (which is set up in
-	 * copy_in_guest_info()).
-	 */
-	for_each_possible_cpu(i) {
-		/* lguest_pages() returns this CPU's two pages. */
-		struct lguest_pages *pages = lguest_pages(i);
-		/* This is a convenience pointer to make the code fit one
-		 * statement to a line. */
-		struct lguest_ro_state *state = &pages->state;
-
-		/* The Global Descriptor Table: the Host has a different one
-		 * for each CPU.  We keep a descriptor for the GDT which says
-		 * where it is and how big it is (the size is actually the last
-		 * byte, not the size, hence the "-1"). */
-		state->host_gdt_desc.size = GDT_SIZE-1;
-		state->host_gdt_desc.address = (long)get_cpu_gdt_table(i);
-
-		/* All CPUs on the Host use the same Interrupt Descriptor
-		 * Table, so we just use store_idt(), which gets this CPU's IDT
-		 * descriptor. */
-		store_idt(&state->host_idt_desc);
-
-		/* The descriptors for the Guest's GDT and IDT can be filled
-		 * out now, too.  We copy the GDT & IDT into ->guest_gdt and
-		 * ->guest_idt before actually running the Guest. */
-		state->guest_idt_desc.size = sizeof(state->guest_idt)-1;
-		state->guest_idt_desc.address = (long)&state->guest_idt;
-		state->guest_gdt_desc.size = sizeof(state->guest_gdt)-1;
-		state->guest_gdt_desc.address = (long)&state->guest_gdt;
-
-		/* We know where we want the stack to be when the Guest enters
-		 * the switcher: in pages->regs.  The stack grows upwards, so
-		 * we start it at the end of that structure. */
-		state->guest_tss.esp0 = (long)(&pages->regs + 1);
-		/* And this is the GDT entry to use for the stack: we keep a
-		 * couple of special LGUEST entries. */
-		state->guest_tss.ss0 = LGUEST_DS;
-
-		/* x86 can have a finegrained bitmap which indicates what I/O
-		 * ports the process can use.  We set it to the end of our
-		 * structure, meaning "none". */
-		state->guest_tss.io_bitmap_base = sizeof(state->guest_tss);
-
-		/* Some GDT entries are the same across all Guests, so we can
-		 * set them up now. */
-		setup_default_gdt_entries(state);
-		/* Most IDT entries are the same for all Guests, too.*/
-		setup_default_idt_entries(state, default_idt_entries);
-
-		/* The Host needs to be able to use the LGUEST segments on this
-		 * CPU, too, so put them in the Host GDT. */
-		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
-		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
-	}
-
-	/* In the Switcher, we want the %cs segment register to use the
-	 * LGUEST_CS GDT entry: we've put that in the Host and Guest GDTs, so
-	 * it will be undisturbed when we switch.  To change %cs and jump we
-	 * need this structure to feed to Intel's "lcall" instruction. */
-	lguest_entry.offset = (long)switch_to_guest + switcher_offset();
-	lguest_entry.segment = LGUEST_CS;
-
 	printk(KERN_INFO "lguest: mapped switcher at %p\n",
 	       switcher_vma->addr);
 	/* And we succeeded... */
@@ -247,86 +128,12 @@
 		__free_pages(switcher_page[i], 0);
 }
 
-/*H:130 Our Guest is usually so well behaved; it never tries to do things it
- * isn't allowed to.  Unfortunately, Linux's paravirtual infrastructure isn't
- * quite complete, because it doesn't contain replacements for the Intel I/O
- * instructions.  As a result, the Guest sometimes fumbles across one during
- * the boot process as it probes for various things which are usually attached
- * to a PC.
- *
- * When the Guest uses one of these instructions, we get trap #13 (General
- * Protection Fault) and come here.  We see if it's one of those troublesome
- * instructions and skip over it.  We return true if we did. */
-static int emulate_insn(struct lguest *lg)
-{
-	u8 insn;
-	unsigned int insnlen = 0, in = 0, shift = 0;
-	/* The eip contains the *virtual* address of the Guest's instruction:
-	 * guest_pa just subtracts the Guest's page_offset. */
-	unsigned long physaddr = guest_pa(lg, lg->regs->eip);
-
-	/* The guest_pa() function only works for Guest kernel addresses, but
-	 * that's all we're trying to do anyway. */
-	if (lg->regs->eip < lg->page_offset)
-		return 0;
-
-	/* Decoding x86 instructions is icky. */
-	lgread(lg, &insn, physaddr, 1);
-
-	/* 0x66 is an "operand prefix".  It means it's using the upper 16 bits
-	   of the eax register. */
-	if (insn == 0x66) {
-		shift = 16;
-		/* The instruction is 1 byte so far, read the next byte. */
-		insnlen = 1;
-		lgread(lg, &insn, physaddr + insnlen, 1);
-	}
-
-	/* We can ignore the lower bit for the moment and decode the 4 opcodes
-	 * we need to emulate. */
-	switch (insn & 0xFE) {
-	case 0xE4: /* in     <next byte>,%al */
-		insnlen += 2;
-		in = 1;
-		break;
-	case 0xEC: /* in     (%dx),%al */
-		insnlen += 1;
-		in = 1;
-		break;
-	case 0xE6: /* out    %al,<next byte> */
-		insnlen += 2;
-		break;
-	case 0xEE: /* out    %al,(%dx) */
-		insnlen += 1;
-		break;
-	default:
-		/* OK, we don't know what this is, can't emulate. */
-		return 0;
-	}
-
-	/* If it was an "IN" instruction, they expect the result to be read
-	 * into %eax, so we change %eax.  We always return all-ones, which
-	 * traditionally means "there's nothing there". */
-	if (in) {
-		/* Lower bit tells is whether it's a 16 or 32 bit access */
-		if (insn & 0x1)
-			lg->regs->eax = 0xFFFFFFFF;
-		else
-			lg->regs->eax |= (0xFFFF << shift);
-	}
-	/* Finally, we've "done" the instruction, so move past it. */
-	lg->regs->eip += insnlen;
-	/* Success! */
-	return 1;
-}
-/*:*/
-
 /*L:305
  * Dealing With Guest Memory.
  *
  * When the Guest gives us (what it thinks is) a physical address, we can use
- * the normal copy_from_user() & copy_to_user() on that address: remember,
- * Guest physical == Launcher virtual.
+ * the normal copy_from_user() & copy_to_user() on the corresponding place in
+ * the memory region allocated by the Launcher.
  *
  * But we can't trust the Guest: it might be trying to access the Launcher
  * code.  We have to check that the range is below the pfn_limit the Launcher
@@ -338,148 +145,27 @@
 	return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr);
 }
 
-/* This is a convenient routine to get a 32-bit value from the Guest (a very
- * common operation).  Here we can see how useful the kill_lguest() routine we
- * met in the Launcher can be: we return a random value (0) instead of needing
- * to return an error. */
-u32 lgread_u32(struct lguest *lg, unsigned long addr)
-{
-	u32 val = 0;
-
-	/* Don't let them access lguest binary. */
-	if (!lguest_address_ok(lg, addr, sizeof(val))
-	    || get_user(val, (u32 __user *)addr) != 0)
-		kill_guest(lg, "bad read address %#lx", addr);
-	return val;
-}
-
-/* Same thing for writing a value. */
-void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val)
-{
-	if (!lguest_address_ok(lg, addr, sizeof(val))
-	    || put_user(val, (u32 __user *)addr) != 0)
-		kill_guest(lg, "bad write address %#lx", addr);
-}
-
-/* This routine is more generic, and copies a range of Guest bytes into a
- * buffer.  If the copy_from_user() fails, we fill the buffer with zeroes, so
- * the caller doesn't end up using uninitialized kernel memory. */
-void lgread(struct lguest *lg, void *b, unsigned long addr, unsigned bytes)
+/* This routine copies memory from the Guest.  Here we can see how useful the
+ * kill_lguest() routine we met in the Launcher can be: we return a random
+ * value (all zeroes) instead of needing to return an error. */
+void __lgread(struct lguest *lg, void *b, unsigned long addr, unsigned bytes)
 {
 	if (!lguest_address_ok(lg, addr, bytes)
-	    || copy_from_user(b, (void __user *)addr, bytes) != 0) {
+	    || copy_from_user(b, lg->mem_base + addr, bytes) != 0) {
 		/* copy_from_user should do this, but as we rely on it... */
 		memset(b, 0, bytes);
 		kill_guest(lg, "bad read address %#lx len %u", addr, bytes);
 	}
 }
 
-/* Similarly, our generic routine to copy into a range of Guest bytes. */
-void lgwrite(struct lguest *lg, unsigned long addr, const void *b,
-	     unsigned bytes)
+/* This is the write (copy into guest) version. */
+void __lgwrite(struct lguest *lg, unsigned long addr, const void *b,
+	       unsigned bytes)
 {
 	if (!lguest_address_ok(lg, addr, bytes)
-	    || copy_to_user((void __user *)addr, b, bytes) != 0)
+	    || copy_to_user(lg->mem_base + addr, b, bytes) != 0)
 		kill_guest(lg, "bad write address %#lx len %u", addr, bytes);
 }
-/* (end of memory access helper routines) :*/
-
-static void set_ts(void)
-{
-	u32 cr0;
-
-	cr0 = read_cr0();
-	if (!(cr0 & 8))
-		write_cr0(cr0|8);
-}
-
-/*S:010
- * We are getting close to the Switcher.
- *
- * Remember that each CPU has two pages which are visible to the Guest when it
- * runs on that CPU.  This has to contain the state for that Guest: we copy the
- * state in just before we run the Guest.
- *
- * Each Guest has "changed" flags which indicate what has changed in the Guest
- * since it last ran.  We saw this set in interrupts_and_traps.c and
- * segments.c.
- */
-static void copy_in_guest_info(struct lguest *lg, struct lguest_pages *pages)
-{
-	/* Copying all this data can be quite expensive.  We usually run the
-	 * same Guest we ran last time (and that Guest hasn't run anywhere else
-	 * meanwhile).  If that's not the case, we pretend everything in the
-	 * Guest has changed. */
-	if (__get_cpu_var(last_guest) != lg || lg->last_pages != pages) {
-		__get_cpu_var(last_guest) = lg;
-		lg->last_pages = pages;
-		lg->changed = CHANGED_ALL;
-	}
-
-	/* These copies are pretty cheap, so we do them unconditionally: */
-	/* Save the current Host top-level page directory. */
-	pages->state.host_cr3 = __pa(current->mm->pgd);
-	/* Set up the Guest's page tables to see this CPU's pages (and no
-	 * other CPU's pages). */
-	map_switcher_in_guest(lg, pages);
-	/* Set up the two "TSS" members which tell the CPU what stack to use
-	 * for traps which do directly into the Guest (ie. traps at privilege
-	 * level 1). */
-	pages->state.guest_tss.esp1 = lg->esp1;
-	pages->state.guest_tss.ss1 = lg->ss1;
-
-	/* Copy direct-to-Guest trap entries. */
-	if (lg->changed & CHANGED_IDT)
-		copy_traps(lg, pages->state.guest_idt, default_idt_entries);
-
-	/* Copy all GDT entries which the Guest can change. */
-	if (lg->changed & CHANGED_GDT)
-		copy_gdt(lg, pages->state.guest_gdt);
-	/* If only the TLS entries have changed, copy them. */
-	else if (lg->changed & CHANGED_GDT_TLS)
-		copy_gdt_tls(lg, pages->state.guest_gdt);
-
-	/* Mark the Guest as unchanged for next time. */
-	lg->changed = 0;
-}
-
-/* Finally: the code to actually call into the Switcher to run the Guest. */
-static void run_guest_once(struct lguest *lg, struct lguest_pages *pages)
-{
-	/* This is a dummy value we need for GCC's sake. */
-	unsigned int clobber;
-
-	/* Copy the guest-specific information into this CPU's "struct
-	 * lguest_pages". */
-	copy_in_guest_info(lg, pages);
-
-	/* Set the trap number to 256 (impossible value).  If we fault while
-	 * switching to the Guest (bad segment registers or bug), this will
-	 * cause us to abort the Guest. */
-	lg->regs->trapnum = 256;
-
-	/* Now: we push the "eflags" register on the stack, then do an "lcall".
-	 * This is how we change from using the kernel code segment to using
-	 * the dedicated lguest code segment, as well as jumping into the
-	 * Switcher.
-	 *
-	 * The lcall also pushes the old code segment (KERNEL_CS) onto the
-	 * stack, then the address of this call.  This stack layout happens to
-	 * exactly match the stack of an interrupt... */
-	asm volatile("pushf; lcall *lguest_entry"
-		     /* This is how we tell GCC that %eax ("a") and %ebx ("b")
-		      * are changed by this routine.  The "=" means output. */
-		     : "=a"(clobber), "=b"(clobber)
-		     /* %eax contains the pages pointer.  ("0" refers to the
-		      * 0-th argument above, ie "a").  %ebx contains the
-		      * physical address of the Guest's top-level page
-		      * directory. */
-		     : "0"(pages), "1"(__pa(lg->pgdirs[lg->pgdidx].pgdir))
-		     /* We tell gcc that all these registers could change,
-		      * which means we don't have to save and restore them in
-		      * the Switcher. */
-		     : "memory", "%edx", "%ecx", "%edi", "%esi");
-}
 /*:*/
 
 /*H:030 Let's jump straight to the the main loop which runs the Guest.
@@ -489,22 +175,16 @@
 {
 	/* We stop running once the Guest is dead. */
 	while (!lg->dead) {
-		/* We need to initialize this, otherwise gcc complains.  It's
-		 * not (yet) clever enough to see that it's initialized when we
-		 * need it. */
-		unsigned int cr2 = 0; /* Damn gcc */
+		/* First we run any hypercalls the Guest wants done. */
+		if (lg->hcall)
+			do_hypercalls(lg);
 
-		/* First we run any hypercalls the Guest wants done: either in
-		 * the hypercall ring in "struct lguest_data", or directly by
-		 * using int 31 (LGUEST_TRAP_ENTRY). */
-		do_hypercalls(lg);
-		/* It's possible the Guest did a SEND_DMA hypercall to the
+		/* It's possible the Guest did a NOTIFY hypercall to the
 		 * Launcher, in which case we return from the read() now. */
-		if (lg->dma_is_pending) {
-			if (put_user(lg->pending_dma, user) ||
-			    put_user(lg->pending_key, user+1))
+		if (lg->pending_notify) {
+			if (put_user(lg->pending_notify, user))
 				return -EFAULT;
-			return sizeof(unsigned long)*2;
+			return sizeof(lg->pending_notify);
 		}
 
 		/* Check for signals */
@@ -542,144 +222,20 @@
 		 * the "Do Not Disturb" sign: */
 		local_irq_disable();
 
-		/* Remember the awfully-named TS bit?  If the Guest has asked
-		 * to set it we set it now, so we can trap and pass that trap
-		 * to the Guest if it uses the FPU. */
-		if (lg->ts)
-			set_ts();
-
-		/* SYSENTER is an optimized way of doing system calls.  We
-		 * can't allow it because it always jumps to privilege level 0.
-		 * A normal Guest won't try it because we don't advertise it in
-		 * CPUID, but a malicious Guest (or malicious Guest userspace
-		 * program) could, so we tell the CPU to disable it before
-		 * running the Guest. */
-		if (boot_cpu_has(X86_FEATURE_SEP))
-			wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);
-
-		/* Now we actually run the Guest.  It will pop back out when
-		 * something interesting happens, and we can examine its
-		 * registers to see what it was doing. */
-		run_guest_once(lg, lguest_pages(raw_smp_processor_id()));
-
-		/* The "regs" pointer contains two extra entries which are not
-		 * really registers: a trap number which says what interrupt or
-		 * trap made the switcher code come back, and an error code
-		 * which some traps set.  */
-
-		/* If the Guest page faulted, then the cr2 register will tell
-		 * us the bad virtual address.  We have to grab this now,
-		 * because once we re-enable interrupts an interrupt could
-		 * fault and thus overwrite cr2, or we could even move off to a
-		 * different CPU. */
-		if (lg->regs->trapnum == 14)
-			cr2 = read_cr2();
-		/* Similarly, if we took a trap because the Guest used the FPU,
-		 * we have to restore the FPU it expects to see. */
-		else if (lg->regs->trapnum == 7)
-			math_state_restore();
-
-		/* Restore SYSENTER if it's supposed to be on. */
-		if (boot_cpu_has(X86_FEATURE_SEP))
-			wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
+		/* Actually run the Guest until something happens. */
+		lguest_arch_run_guest(lg);
 
 		/* Now we're ready to be interrupted or moved to other CPUs */
 		local_irq_enable();
 
-		/* OK, so what happened? */
-		switch (lg->regs->trapnum) {
-		case 13: /* We've intercepted a GPF. */
-			/* Check if this was one of those annoying IN or OUT
-			 * instructions which we need to emulate.  If so, we
-			 * just go back into the Guest after we've done it. */
-			if (lg->regs->errcode == 0) {
-				if (emulate_insn(lg))
-					continue;
-			}
-			break;
-		case 14: /* We've intercepted a page fault. */
-			/* The Guest accessed a virtual address that wasn't
-			 * mapped.  This happens a lot: we don't actually set
-			 * up most of the page tables for the Guest at all when
-			 * we start: as it runs it asks for more and more, and
-			 * we set them up as required. In this case, we don't
-			 * even tell the Guest that the fault happened.
-			 *
-			 * The errcode tells whether this was a read or a
-			 * write, and whether kernel or userspace code. */
-			if (demand_page(lg, cr2, lg->regs->errcode))
-				continue;
-
-			/* OK, it's really not there (or not OK): the Guest
-			 * needs to know.  We write out the cr2 value so it
-			 * knows where the fault occurred.
-			 *
-			 * Note that if the Guest were really messed up, this
-			 * could happen before it's done the INITIALIZE
-			 * hypercall, so lg->lguest_data will be NULL, so
-			 * &lg->lguest_data->cr2 will be address 8.  Writing
-			 * into that address won't hurt the Host at all,
-			 * though. */
-			if (put_user(cr2, &lg->lguest_data->cr2))
-				kill_guest(lg, "Writing cr2");
-			break;
-		case 7: /* We've intercepted a Device Not Available fault. */
-			/* If the Guest doesn't want to know, we already
-			 * restored the Floating Point Unit, so we just
-			 * continue without telling it. */
-			if (!lg->ts)
-				continue;
-			break;
-		case 32 ... 255:
-			/* These values mean a real interrupt occurred, in
-			 * which case the Host handler has already been run.
-			 * We just do a friendly check if another process
-			 * should now be run, then fall through to loop
-			 * around: */
-			cond_resched();
-		case LGUEST_TRAP_ENTRY: /* Handled at top of loop */
-			continue;
-		}
-
-		/* If we get here, it's a trap the Guest wants to know
-		 * about. */
-		if (deliver_trap(lg, lg->regs->trapnum))
-			continue;
-
-		/* If the Guest doesn't have a handler (either it hasn't
-		 * registered any yet, or it's one of the faults we don't let
-		 * it handle), it dies with a cryptic error message. */
-		kill_guest(lg, "unhandled trap %li at %#lx (%#lx)",
-			   lg->regs->trapnum, lg->regs->eip,
-			   lg->regs->trapnum == 14 ? cr2 : lg->regs->errcode);
+		/* Now we deal with whatever happened to the Guest. */
+		lguest_arch_handle_trap(lg);
 	}
+
 	/* The Guest is dead => "No such file or directory" */
 	return -ENOENT;
 }
 
-/* Now we can look at each of the routines this calls, in increasing order of
- * complexity: do_hypercalls(), emulate_insn(), maybe_do_interrupt(),
- * deliver_trap() and demand_page().  After all those, we'll be ready to
- * examine the Switcher, and our philosophical understanding of the Host/Guest
- * duality will be complete. :*/
-
-int find_free_guest(void)
-{
-	unsigned int i;
-	for (i = 0; i < MAX_LGUEST_GUESTS; i++)
-		if (!lguests[i].tsk)
-			return i;
-	return -1;
-}
-
-static void adjust_pge(void *on)
-{
-	if (on)
-		write_cr4(read_cr4() | X86_CR4_PGE);
-	else
-		write_cr4(read_cr4() & ~X86_CR4_PGE);
-}
-
 /*H:000
  * Welcome to the Host!
  *
@@ -701,72 +257,50 @@
 	/* First we put the Switcher up in very high virtual memory. */
 	err = map_switcher();
 	if (err)
-		return err;
+		goto out;
 
 	/* Now we set up the pagetable implementation for the Guests. */
 	err = init_pagetables(switcher_page, SHARED_SWITCHER_PAGES);
-	if (err) {
-		unmap_switcher();
-		return err;
-	}
+	if (err)
+		goto unmap;
 
-	/* The I/O subsystem needs some things initialized. */
-	lguest_io_init();
+	/* We might need to reserve an interrupt vector. */
+	err = init_interrupts();
+	if (err)
+		goto free_pgtables;
 
 	/* /dev/lguest needs to be registered. */
 	err = lguest_device_init();
-	if (err) {
-		free_pagetables();
-		unmap_switcher();
-		return err;
-	}
+	if (err)
+		goto free_interrupts;
 
-	/* Finally, we need to turn off "Page Global Enable".  PGE is an
-	 * optimization where page table entries are specially marked to show
-	 * they never change.  The Host kernel marks all the kernel pages this
-	 * way because it's always present, even when userspace is running.
-	 *
-	 * Lguest breaks this: unbeknownst to the rest of the Host kernel, we
-	 * switch to the Guest kernel.  If you don't disable this on all CPUs,
-	 * you'll get really weird bugs that you'll chase for two days.
-	 *
-	 * I used to turn PGE off every time we switched to the Guest and back
-	 * on when we return, but that slowed the Switcher down noticibly. */
-
-	/* We don't need the complexity of CPUs coming and going while we're
-	 * doing this. */
-	lock_cpu_hotplug();
-	if (cpu_has_pge) { /* We have a broader idea of "global". */
-		/* Remember that this was originally set (for cleanup). */
-		cpu_had_pge = 1;
-		/* adjust_pge is a helper function which sets or unsets the PGE
-		 * bit on its CPU, depending on the argument (0 == unset). */
-		on_each_cpu(adjust_pge, (void *)0, 0, 1);
-		/* Turn off the feature in the global feature set. */
-		clear_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
-	}
-	unlock_cpu_hotplug();
+	/* Finally we do some architecture-specific setup. */
+	lguest_arch_host_init();
 
 	/* All good! */
 	return 0;
+
+free_interrupts:
+	free_interrupts();
+free_pgtables:
+	free_pagetables();
+unmap:
+	unmap_switcher();
+out:
+	return err;
 }
 
 /* Cleaning up is just the same code, backwards.  With a little French. */
 static void __exit fini(void)
 {
 	lguest_device_remove();
+	free_interrupts();
 	free_pagetables();
 	unmap_switcher();
 
-	/* If we had PGE before we started, turn it back on now. */
-	lock_cpu_hotplug();
-	if (cpu_had_pge) {
-		set_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
-		/* adjust_pge's argument "1" means set PGE. */
-		on_each_cpu(adjust_pge, (void *)1, 0, 1);
-	}
-	unlock_cpu_hotplug();
+	lguest_arch_host_fini();
 }
+/*:*/
 
 /* The Host side of lguest can be a module.  This is a nice way for people to
  * play with it.  */
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
index db6caac..9d5184c 100644
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -25,17 +25,13 @@
 #include <linux/mm.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <irq_vectors.h>
 #include "lg.h"
 
-/*H:120 This is the core hypercall routine: where the Guest gets what it
- * wants.  Or gets killed.  Or, in the case of LHCALL_CRASH, both.
- *
- * Remember from the Guest: %eax == which call to make, and the arguments are
- * packed into %edx, %ebx and %ecx if needed. */
-static void do_hcall(struct lguest *lg, struct lguest_regs *regs)
+/*H:120 This is the core hypercall routine: where the Guest gets what it wants.
+ * Or gets killed.  Or, in the case of LHCALL_CRASH, both. */
+static void do_hcall(struct lguest *lg, struct hcall_args *args)
 {
-	switch (regs->eax) {
+	switch (args->arg0) {
 	case LHCALL_FLUSH_ASYNC:
 		/* This call does nothing, except by breaking out of the Guest
 		 * it makes us process all the asynchronous hypercalls. */
@@ -51,7 +47,7 @@
 		char msg[128];
 		/* If the lgread fails, it will call kill_guest() itself; the
 		 * kill_guest() with the message will be ignored. */
-		lgread(lg, msg, regs->edx, sizeof(msg));
+		__lgread(lg, msg, args->arg1, sizeof(msg));
 		msg[sizeof(msg)-1] = '\0';
 		kill_guest(lg, "CRASH: %s", msg);
 		break;
@@ -59,67 +55,49 @@
 	case LHCALL_FLUSH_TLB:
 		/* FLUSH_TLB comes in two flavors, depending on the
 		 * argument: */
-		if (regs->edx)
+		if (args->arg1)
 			guest_pagetable_clear_all(lg);
 		else
 			guest_pagetable_flush_user(lg);
 		break;
-	case LHCALL_BIND_DMA:
-		/* BIND_DMA really wants four arguments, but it's the only call
-		 * which does.  So the Guest packs the number of buffers and
-		 * the interrupt number into the final argument, and we decode
-		 * it here.  This can legitimately fail, since we currently
-		 * place a limit on the number of DMA pools a Guest can have.
-		 * So we return true or false from this call. */
-		regs->eax = bind_dma(lg, regs->edx, regs->ebx,
-				     regs->ecx >> 8, regs->ecx & 0xFF);
-		break;
 
 	/* All these calls simply pass the arguments through to the right
 	 * routines. */
-	case LHCALL_SEND_DMA:
-		send_dma(lg, regs->edx, regs->ebx);
-		break;
-	case LHCALL_LOAD_GDT:
-		load_guest_gdt(lg, regs->edx, regs->ebx);
-		break;
-	case LHCALL_LOAD_IDT_ENTRY:
-		load_guest_idt_entry(lg, regs->edx, regs->ebx, regs->ecx);
-		break;
 	case LHCALL_NEW_PGTABLE:
-		guest_new_pagetable(lg, regs->edx);
+		guest_new_pagetable(lg, args->arg1);
 		break;
 	case LHCALL_SET_STACK:
-		guest_set_stack(lg, regs->edx, regs->ebx, regs->ecx);
+		guest_set_stack(lg, args->arg1, args->arg2, args->arg3);
 		break;
 	case LHCALL_SET_PTE:
-		guest_set_pte(lg, regs->edx, regs->ebx, mkgpte(regs->ecx));
+		guest_set_pte(lg, args->arg1, args->arg2, __pte(args->arg3));
 		break;
 	case LHCALL_SET_PMD:
-		guest_set_pmd(lg, regs->edx, regs->ebx);
-		break;
-	case LHCALL_LOAD_TLS:
-		guest_load_tls(lg, regs->edx);
+		guest_set_pmd(lg, args->arg1, args->arg2);
 		break;
 	case LHCALL_SET_CLOCKEVENT:
-		guest_set_clockevent(lg, regs->edx);
+		guest_set_clockevent(lg, args->arg1);
 		break;
-
 	case LHCALL_TS:
 		/* This sets the TS flag, as we saw used in run_guest(). */
-		lg->ts = regs->edx;
+		lg->ts = args->arg1;
 		break;
 	case LHCALL_HALT:
 		/* Similarly, this sets the halted flag for run_guest(). */
 		lg->halted = 1;
 		break;
+	case LHCALL_NOTIFY:
+		lg->pending_notify = args->arg1;
+		break;
 	default:
-		kill_guest(lg, "Bad hypercall %li\n", regs->eax);
+		if (lguest_arch_do_hcall(lg, args))
+			kill_guest(lg, "Bad hypercall %li\n", args->arg0);
 	}
 }
+/*:*/
 
-/* Asynchronous hypercalls are easy: we just look in the array in the Guest's
- * "struct lguest_data" and see if there are any new ones marked "ready".
+/*H:124 Asynchronous hypercalls are easy: we just look in the array in the
+ * Guest's "struct lguest_data" to see if any new ones are marked "ready".
  *
  * We are careful to do these in order: obviously we respect the order the
  * Guest put them in the ring, but we also promise the Guest that they will
@@ -134,10 +112,9 @@
 	if (copy_from_user(&st, &lg->lguest_data->hcall_status, sizeof(st)))
 		return;
 
-
 	/* We process "struct lguest_data"s hcalls[] ring once. */
 	for (i = 0; i < ARRAY_SIZE(st); i++) {
-		struct lguest_regs regs;
+		struct hcall_args args;
 		/* We remember where we were up to from last time.  This makes
 		 * sure that the hypercalls are done in the order the Guest
 		 * places them in the ring. */
@@ -152,18 +129,16 @@
 		if (++lg->next_hcall == LHCALL_RING_SIZE)
 			lg->next_hcall = 0;
 
-		/* We copy the hypercall arguments into a fake register
-		 * structure.  This makes life simple for do_hcall(). */
-		if (get_user(regs.eax, &lg->lguest_data->hcalls[n].eax)
-		    || get_user(regs.edx, &lg->lguest_data->hcalls[n].edx)
-		    || get_user(regs.ecx, &lg->lguest_data->hcalls[n].ecx)
-		    || get_user(regs.ebx, &lg->lguest_data->hcalls[n].ebx)) {
+		/* Copy the hypercall arguments into a local copy of
+		 * the hcall_args struct. */
+		if (copy_from_user(&args, &lg->lguest_data->hcalls[n],
+				   sizeof(struct hcall_args))) {
 			kill_guest(lg, "Fetching async hypercalls");
 			break;
 		}
 
 		/* Do the hypercall, same as a normal one. */
-		do_hcall(lg, &regs);
+		do_hcall(lg, &args);
 
 		/* Mark the hypercall done. */
 		if (put_user(0xFF, &lg->lguest_data->hcall_status[n])) {
@@ -171,9 +146,9 @@
 			break;
 		}
 
- 		/* Stop doing hypercalls if we've just done a DMA to the
-		 * Launcher: it needs to service this first. */
-		if (lg->dma_is_pending)
+		/* Stop doing hypercalls if they want to notify the Launcher:
+		 * it needs to service this first. */
+		if (lg->pending_notify)
 			break;
 	}
 }
@@ -182,76 +157,35 @@
  * Guest makes a hypercall, we end up here to set things up: */
 static void initialize(struct lguest *lg)
 {
-	u32 tsc_speed;
 
 	/* You can't do anything until you're initialized.  The Guest knows the
 	 * rules, so we're unforgiving here. */
-	if (lg->regs->eax != LHCALL_LGUEST_INIT) {
-		kill_guest(lg, "hypercall %li before LGUEST_INIT",
-			   lg->regs->eax);
+	if (lg->hcall->arg0 != LHCALL_LGUEST_INIT) {
+		kill_guest(lg, "hypercall %li before INIT", lg->hcall->arg0);
 		return;
 	}
 
-	/* We insist that the Time Stamp Counter exist and doesn't change with
-	 * cpu frequency.  Some devious chip manufacturers decided that TSC
-	 * changes could be handled in software.  I decided that time going
-	 * backwards might be good for benchmarks, but it's bad for users.
-	 *
-	 * We also insist that the TSC be stable: the kernel detects unreliable
-	 * TSCs for its own purposes, and we use that here. */
-	if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && !check_tsc_unstable())
-		tsc_speed = tsc_khz;
-	else
-		tsc_speed = 0;
-
-	/* The pointer to the Guest's "struct lguest_data" is the only
-	 * argument. */
-	lg->lguest_data = (struct lguest_data __user *)lg->regs->edx;
-	/* If we check the address they gave is OK now, we can simply
-	 * copy_to_user/from_user from now on rather than using lgread/lgwrite.
-	 * I put this in to show that I'm not immune to writing stupid
-	 * optimizations. */
-	if (!lguest_address_ok(lg, lg->regs->edx, sizeof(*lg->lguest_data))) {
+	if (lguest_arch_init_hypercalls(lg))
 		kill_guest(lg, "bad guest page %p", lg->lguest_data);
-		return;
-	}
+
 	/* The Guest tells us where we're not to deliver interrupts by putting
 	 * the range of addresses into "struct lguest_data". */
 	if (get_user(lg->noirq_start, &lg->lguest_data->noirq_start)
-	    || get_user(lg->noirq_end, &lg->lguest_data->noirq_end)
-	    /* We tell the Guest that it can't use the top 4MB of virtual
-	     * addresses used by the Switcher. */
-	    || put_user(4U*1024*1024, &lg->lguest_data->reserve_mem)
-	    || put_user(tsc_speed, &lg->lguest_data->tsc_khz)
-	    /* We also give the Guest a unique id, as used in lguest_net.c. */
-	    || put_user(lg->guestid, &lg->lguest_data->guestid))
+	    || get_user(lg->noirq_end, &lg->lguest_data->noirq_end))
 		kill_guest(lg, "bad guest page %p", lg->lguest_data);
 
 	/* We write the current time into the Guest's data page once now. */
 	write_timestamp(lg);
 
+	/* page_tables.c will also do some setup. */
+	page_table_guest_data_init(lg);
+
 	/* This is the one case where the above accesses might have been the
 	 * first write to a Guest page.  This may have caused a copy-on-write
 	 * fault, but the Guest might be referring to the old (read-only)
 	 * page. */
 	guest_pagetable_clear_all(lg);
 }
-/* Now we've examined the hypercall code; our Guest can make requests.  There
- * is one other way we can do things for the Guest, as we see in
- * emulate_insn(). */
-
-/*H:110 Tricky point: we mark the hypercall as "done" once we've done it.
- * Normally we don't need to do this: the Guest will run again and update the
- * trap number before we come back around the run_guest() loop to
- * do_hypercalls().
- *
- * However, if we are signalled or the Guest sends DMA to the Launcher, that
- * loop will exit without running the Guest.  When it comes back it would try
- * to re-run the hypercall. */
-static void clear_hcall(struct lguest *lg)
-{
-	lg->regs->trapnum = 255;
-}
 
 /*H:100
  * Hypercalls
@@ -261,16 +195,12 @@
  */
 void do_hypercalls(struct lguest *lg)
 {
-	/* Not initialized yet? */
+	/* Not initialized yet?  This hypercall must do it. */
 	if (unlikely(!lg->lguest_data)) {
-		/* Did the Guest make a hypercall?  We might have come back for
-		 * some other reason (an interrupt, a different trap). */
-		if (lg->regs->trapnum == LGUEST_TRAP_ENTRY) {
-			/* Set up the "struct lguest_data" */
-			initialize(lg);
-			/* The hypercall is done. */
-			clear_hcall(lg);
-		}
+		/* Set up the "struct lguest_data" */
+		initialize(lg);
+		/* Hcall is done. */
+		lg->hcall = NULL;
 		return;
 	}
 
@@ -280,12 +210,21 @@
 	do_async_hcalls(lg);
 
 	/* If we stopped reading the hypercall ring because the Guest did a
-	 * SEND_DMA to the Launcher, we want to return now.  Otherwise if the
-	 * Guest asked us to do a hypercall, we do it. */
-	if (!lg->dma_is_pending && lg->regs->trapnum == LGUEST_TRAP_ENTRY) {
-		do_hcall(lg, lg->regs);
-		/* The hypercall is done. */
-		clear_hcall(lg);
+	 * NOTIFY to the Launcher, we want to return now.  Otherwise we do
+	 * the hypercall. */
+	if (!lg->pending_notify) {
+		do_hcall(lg, lg->hcall);
+		/* Tricky point: we reset the hcall pointer to mark the
+		 * hypercall as "done".  We use the hcall pointer rather than
+		 * the trap number to indicate a hypercall is pending.
+		 * Normally it doesn't matter: the Guest will run again and
+		 * update the trap number before we come back here.
+		 *
+		 * However, if we are signalled or the Guest sends DMA to the
+		 * Launcher, the run_guest() loop will exit without running the
+		 * Guest.  When it comes back it would try to re-run the
+		 * hypercall. */
+		lg->hcall = NULL;
 	}
 }
 
@@ -295,6 +234,6 @@
 {
 	struct timespec now;
 	ktime_get_real_ts(&now);
-	if (put_user(now, &lg->lguest_data->time))
+	if (copy_to_user(&lg->lguest_data->time, &now, sizeof(struct timespec)))
 		kill_guest(lg, "Writing timestamp");
 }
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index 3973123..8296698 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -12,8 +12,14 @@
  * them first, so we also have a way of "reflecting" them into the Guest as if
  * they had been delivered to it directly. :*/
 #include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
 #include "lg.h"
 
+/* Allow Guests to use a non-128 (ie. non-Linux) syscall trap. */
+static unsigned int syscall_vector = SYSCALL_VECTOR;
+module_param(syscall_vector, uint, 0444);
+
 /* The address of the interrupt handler is split into two bits: */
 static unsigned long idt_address(u32 lo, u32 hi)
 {
@@ -39,7 +45,7 @@
 {
 	/* Stack grows upwards: move stack then write value. */
 	*gstack -= 4;
-	lgwrite_u32(lg, *gstack, val);
+	lgwrite(lg, *gstack, u32, val);
 }
 
 /*H:210 The set_guest_interrupt() routine actually delivers the interrupt or
@@ -56,8 +62,9 @@
  * it). */
 static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err)
 {
-	unsigned long gstack;
+	unsigned long gstack, origstack;
 	u32 eflags, ss, irq_enable;
+	unsigned long virtstack;
 
 	/* There are two cases for interrupts: one where the Guest is already
 	 * in the kernel, and a more complex one where the Guest is in
@@ -65,8 +72,10 @@
 	if ((lg->regs->ss&0x3) != GUEST_PL) {
 		/* The Guest told us their kernel stack with the SET_STACK
 		 * hypercall: both the virtual address and the segment */
-		gstack = guest_pa(lg, lg->esp1);
+		virtstack = lg->esp1;
 		ss = lg->ss1;
+
+		origstack = gstack = guest_pa(lg, virtstack);
 		/* We push the old stack segment and pointer onto the new
 		 * stack: when the Guest does an "iret" back from the interrupt
 		 * handler the CPU will notice they're dropping privilege
@@ -75,8 +84,10 @@
 		push_guest_stack(lg, &gstack, lg->regs->esp);
 	} else {
 		/* We're staying on the same Guest (kernel) stack. */
-		gstack = guest_pa(lg, lg->regs->esp);
+		virtstack = lg->regs->esp;
 		ss = lg->regs->ss;
+
+		origstack = gstack = guest_pa(lg, virtstack);
 	}
 
 	/* Remember that we never let the Guest actually disable interrupts, so
@@ -102,7 +113,7 @@
 	/* Now we've pushed all the old state, we change the stack, the code
 	 * segment and the address to execute. */
 	lg->regs->ss = ss;
-	lg->regs->esp = gstack + lg->page_offset;
+	lg->regs->esp = virtstack + (gstack - origstack);
 	lg->regs->cs = (__KERNEL_CS|GUEST_PL);
 	lg->regs->eip = idt_address(lo, hi);
 
@@ -165,7 +176,7 @@
 	/* Look at the IDT entry the Guest gave us for this interrupt.  The
 	 * first 32 (FIRST_EXTERNAL_VECTOR) entries are for traps, so we skip
 	 * over them. */
-	idt = &lg->idt[FIRST_EXTERNAL_VECTOR+irq];
+	idt = &lg->arch.idt[FIRST_EXTERNAL_VECTOR+irq];
 	/* If they don't have a handler (yet?), we just ignore it */
 	if (idt_present(idt->a, idt->b)) {
 		/* OK, mark it no longer pending and deliver it. */
@@ -183,6 +194,47 @@
 	 * timer interrupt. */
 	write_timestamp(lg);
 }
+/*:*/
+
+/* Linux uses trap 128 for system calls.  Plan9 uses 64, and Ron Minnich sent
+ * me a patch, so we support that too.  It'd be a big step for lguest if half
+ * the Plan 9 user base were to start using it.
+ *
+ * Actually now I think of it, it's possible that Ron *is* half the Plan 9
+ * userbase.  Oh well. */
+static bool could_be_syscall(unsigned int num)
+{
+	/* Normal Linux SYSCALL_VECTOR or reserved vector? */
+	return num == SYSCALL_VECTOR || num == syscall_vector;
+}
+
+/* The syscall vector it wants must be unused by Host. */
+bool check_syscall_vector(struct lguest *lg)
+{
+	u32 vector;
+
+	if (get_user(vector, &lg->lguest_data->syscall_vec))
+		return false;
+
+	return could_be_syscall(vector);
+}
+
+int init_interrupts(void)
+{
+	/* If they want some strange system call vector, reserve it now */
+	if (syscall_vector != SYSCALL_VECTOR
+	    && test_and_set_bit(syscall_vector, used_vectors)) {
+		printk("lg: couldn't reserve syscall %u\n", syscall_vector);
+		return -EBUSY;
+	}
+	return 0;
+}
+
+void free_interrupts(void)
+{
+	if (syscall_vector != SYSCALL_VECTOR)
+		clear_bit(syscall_vector, used_vectors);
+}
 
 /*H:220 Now we've got the routines to deliver interrupts, delivering traps
  * like page fault is easy.  The only trick is that Intel decided that some
@@ -197,14 +249,14 @@
 {
 	/* Trap numbers are always 8 bit, but we set an impossible trap number
 	 * for traps inside the Switcher, so check that here. */
-	if (num >= ARRAY_SIZE(lg->idt))
+	if (num >= ARRAY_SIZE(lg->arch.idt))
 		return 0;
 
 	/* Early on the Guest hasn't set the IDT entries (or maybe it put a
 	 * bogus one in): if we fail here, the Guest will be killed. */
-	if (!idt_present(lg->idt[num].a, lg->idt[num].b))
+	if (!idt_present(lg->arch.idt[num].a, lg->arch.idt[num].b))
 		return 0;
-	set_guest_interrupt(lg, lg->idt[num].a, lg->idt[num].b, has_err(num));
+	set_guest_interrupt(lg, lg->arch.idt[num].a, lg->arch.idt[num].b, has_err(num));
 	return 1;
 }
 
@@ -218,28 +270,20 @@
  * system calls down from 1750ns to 270ns.  Plus, if lguest didn't do it, all
  * the other hypervisors would tease it.
  *
- * This routine determines if a trap can be delivered directly. */
-static int direct_trap(const struct lguest *lg,
-		       const struct desc_struct *trap,
-		       unsigned int num)
+ * This routine indicates if a particular trap number could be delivered
+ * directly. */
+static int direct_trap(unsigned int num)
 {
 	/* Hardware interrupts don't go to the Guest at all (except system
 	 * call). */
-	if (num >= FIRST_EXTERNAL_VECTOR && num != SYSCALL_VECTOR)
+	if (num >= FIRST_EXTERNAL_VECTOR && !could_be_syscall(num))
 		return 0;
 
 	/* The Host needs to see page faults (for shadow paging and to save the
 	 * fault address), general protection faults (in/out emulation) and
 	 * device not available (TS handling), and of course, the hypercall
 	 * trap. */
-	if (num == 14 || num == 13 || num == 7 || num == LGUEST_TRAP_ENTRY)
-		return 0;
-
-	/* Only trap gates (type 15) can go direct to the Guest.  Interrupt
-	 * gates (type 14) disable interrupts as they are entered, which we
-	 * never let the Guest do.  Not present entries (type 0x0) also can't
-	 * go direct, of course 8) */
-	return idt_type(trap->a, trap->b) == 0xF;
+	return num != 14 && num != 13 && num != 7 && num != LGUEST_TRAP_ENTRY;
 }
 /*:*/
 
@@ -348,15 +392,11 @@
 	 * to copy this again. */
 	lg->changed |= CHANGED_IDT;
 
-	/* The IDT which we keep in "struct lguest" only contains 32 entries
-	 * for the traps and LGUEST_IRQS (32) entries for interrupts.  We
-	 * ignore attempts to set handlers for higher interrupt numbers, except
-	 * for the system call "interrupt" at 128: we have a special IDT entry
-	 * for that. */
-	if (num < ARRAY_SIZE(lg->idt))
-		set_trap(lg, &lg->idt[num], num, lo, hi);
-	else if (num == SYSCALL_VECTOR)
-		set_trap(lg, &lg->syscall_idt, num, lo, hi);
+	/* Check that the Guest doesn't try to step outside the bounds. */
+	if (num >= ARRAY_SIZE(lg->arch.idt))
+		kill_guest(lg, "Setting idt entry %u", num);
+	else
+		set_trap(lg, &lg->arch.idt[num], num, lo, hi);
 }
 
 /* The default entry for each interrupt points into the Switcher routines which
@@ -399,20 +439,21 @@
 
 	/* We can simply copy the direct traps, otherwise we use the default
 	 * ones in the Switcher: they will return to the Host. */
-	for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) {
-		if (direct_trap(lg, &lg->idt[i], i))
-			idt[i] = lg->idt[i];
+	for (i = 0; i < ARRAY_SIZE(lg->arch.idt); i++) {
+		/* If no Guest can ever override this trap, leave it alone. */
+		if (!direct_trap(i))
+			continue;
+
+		/* Only trap gates (type 15) can go direct to the Guest.
+		 * Interrupt gates (type 14) disable interrupts as they are
+		 * entered, which we never let the Guest do.  Not present
+		 * entries (type 0x0) also can't go direct, of course. */
+		if (idt_type(lg->arch.idt[i].a, lg->arch.idt[i].b) == 0xF)
+			idt[i] = lg->arch.idt[i];
 		else
+			/* Reset it to the default. */
 			default_idt_entry(&idt[i], i, def[i]);
 	}
-
-	/* Don't forget the system call trap!  The IDT entries for other
-	 * interupts never change, so no need to copy them. */
-	i = SYSCALL_VECTOR;
-	if (direct_trap(lg, &lg->syscall_idt, i))
-		idt[i] = lg->syscall_idt;
-	else
-		default_idt_entry(&idt[i], i, def[i]);
 }
 
 void guest_set_clockevent(struct lguest *lg, unsigned long delta)
diff --git a/drivers/lguest/io.c b/drivers/lguest/io.c
deleted file mode 100644
index ea68613..0000000
--- a/drivers/lguest/io.c
+++ /dev/null
@@ -1,626 +0,0 @@
-/*P:300 The I/O mechanism in lguest is simple yet flexible, allowing the Guest
- * to talk to the Launcher or directly to another Guest.  It uses familiar
- * concepts of DMA and interrupts, plus some neat code stolen from
- * futexes... :*/
-
-/* Copyright (C) 2006 Rusty Russell IBM 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-#include <linux/types.h>
-#include <linux/futex.h>
-#include <linux/jhash.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/uaccess.h>
-#include "lg.h"
-
-/*L:300
- * I/O
- *
- * Getting data in and out of the Guest is quite an art.  There are numerous
- * ways to do it, and they all suck differently.  We try to keep things fairly
- * close to "real" hardware so our Guest's drivers don't look like an alien
- * visitation in the middle of the Linux code, and yet make sure that Guests
- * can talk directly to other Guests, not just the Launcher.
- *
- * To do this, the Guest gives us a key when it binds or sends DMA buffers.
- * The key corresponds to a "physical" address inside the Guest (ie. a virtual
- * address inside the Launcher process).  We don't, however, use this key
- * directly.
- *
- * We want Guests which share memory to be able to DMA to each other: two
- * Launchers can mmap memory the same file, then the Guests can communicate.
- * Fortunately, the futex code provides us with a way to get a "union
- * futex_key" corresponding to the memory lying at a virtual address: if the
- * two processes share memory, the "union futex_key" for that memory will match
- * even if the memory is mapped at different addresses in each.  So we always
- * convert the keys to "union futex_key"s to compare them.
- *
- * Before we dive into this though, we need to look at another set of helper
- * routines used throughout the Host kernel code to access Guest memory.
- :*/
-static struct list_head dma_hash[61];
-
-/* An unfortunate side effect of the Linux double-linked list implementation is
- * that there's no good way to statically initialize an array of linked
- * lists. */
-void lguest_io_init(void)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(dma_hash); i++)
-		INIT_LIST_HEAD(&dma_hash[i]);
-}
-
-/* FIXME: allow multi-page lengths. */
-static int check_dma_list(struct lguest *lg, const struct lguest_dma *dma)
-{
-	unsigned int i;
-
-	for (i = 0; i < LGUEST_MAX_DMA_SECTIONS; i++) {
-		if (!dma->len[i])
-			return 1;
-		if (!lguest_address_ok(lg, dma->addr[i], dma->len[i]))
-			goto kill;
-		if (dma->len[i] > PAGE_SIZE)
-			goto kill;
-		/* We could do over a page, but is it worth it? */
-		if ((dma->addr[i] % PAGE_SIZE) + dma->len[i] > PAGE_SIZE)
-			goto kill;
-	}
-	return 1;
-
-kill:
-	kill_guest(lg, "bad DMA entry: %u@%#lx", dma->len[i], dma->addr[i]);
-	return 0;
-}
-
-/*L:330 This is our hash function, using the wonderful Jenkins hash.
- *
- * The futex key is a union with three parts: an unsigned long word, a pointer,
- * and an int "offset".  We could use jhash_2words() which takes three u32s.
- * (Ok, the hash functions are great: the naming sucks though).
- *
- * It's nice to be portable to 64-bit platforms, so we use the more generic
- * jhash2(), which takes an array of u32, the number of u32s, and an initial
- * u32 to roll in.  This is uglier, but breaks down to almost the same code on
- * 32-bit platforms like this one.
- *
- * We want a position in the array, so we modulo ARRAY_SIZE(dma_hash) (ie. 61).
- */
-static unsigned int hash(const union futex_key *key)
-{
-	return jhash2((u32*)&key->both.word,
-		      (sizeof(key->both.word)+sizeof(key->both.ptr))/4,
-		      key->both.offset)
-		% ARRAY_SIZE(dma_hash);
-}
-
-/* This is a convenience routine to compare two keys.  It's a much bemoaned C
- * weakness that it doesn't allow '==' on structures or unions, so we have to
- * open-code it like this. */
-static inline int key_eq(const union futex_key *a, const union futex_key *b)
-{
-	return (a->both.word == b->both.word
-		&& a->both.ptr == b->both.ptr
-		&& a->both.offset == b->both.offset);
-}
-
-/*L:360 OK, when we need to actually free up a Guest's DMA array we do several
- * things, so we have a convenient function to do it.
- *
- * The caller must hold a read lock on dmainfo owner's current->mm->mmap_sem
- * for the drop_futex_key_refs(). */
-static void unlink_dma(struct lguest_dma_info *dmainfo)
-{
-	/* You locked this too, right? */
-	BUG_ON(!mutex_is_locked(&lguest_lock));
-	/* This is how we know that the entry is free. */
-	dmainfo->interrupt = 0;
-	/* Remove it from the hash table. */
-	list_del(&dmainfo->list);
-	/* Drop the references we were holding (to the inode or mm). */
-	drop_futex_key_refs(&dmainfo->key);
-}
-
-/*L:350 This is the routine which we call when the Guest asks to unregister a
- * DMA array attached to a given key.  Returns true if the array was found. */
-static int unbind_dma(struct lguest *lg,
-		      const union futex_key *key,
-		      unsigned long dmas)
-{
-	int i, ret = 0;
-
-	/* We don't bother with the hash table, just look through all this
-	 * Guest's DMA arrays. */
-	for (i = 0; i < LGUEST_MAX_DMA; i++) {
-		/* In theory it could have more than one array on the same key,
-		 * or one array on multiple keys, so we check both */
-		if (key_eq(key, &lg->dma[i].key) && dmas == lg->dma[i].dmas) {
-			unlink_dma(&lg->dma[i]);
-			ret = 1;
-			break;
-		}
-	}
-	return ret;
-}
-
-/*L:340 BIND_DMA: this is the hypercall which sets up an array of "struct
- * lguest_dma" for receiving I/O.
- *
- * The Guest wants to bind an array of "struct lguest_dma"s to a particular key
- * to receive input.  This only happens when the Guest is setting up a new
- * device, so it doesn't have to be very fast.
- *
- * It returns 1 on a successful registration (it can fail if we hit the limit
- * of registrations for this Guest).
- */
-int bind_dma(struct lguest *lg,
-	     unsigned long ukey, unsigned long dmas, u16 numdmas, u8 interrupt)
-{
-	unsigned int i;
-	int ret = 0;
-	union futex_key key;
-	/* Futex code needs the mmap_sem. */
-	struct rw_semaphore *fshared = &current->mm->mmap_sem;
-
-	/* Invalid interrupt?  (We could kill the guest here). */
-	if (interrupt >= LGUEST_IRQS)
-		return 0;
-
-	/* We need to grab the Big Lguest Lock, because other Guests may be
-	 * trying to look through this Guest's DMAs to send something while
-	 * we're doing this. */
-	mutex_lock(&lguest_lock);
-	down_read(fshared);
-	if (get_futex_key((u32 __user *)ukey, fshared, &key) != 0) {
-		kill_guest(lg, "bad dma key %#lx", ukey);
-		goto unlock;
-	}
-
-	/* We want to keep this key valid once we drop mmap_sem, so we have to
-	 * hold a reference. */
-	get_futex_key_refs(&key);
-
-	/* If the Guest specified an interrupt of 0, that means they want to
-	 * unregister this array of "struct lguest_dma"s. */
-	if (interrupt == 0)
-		ret = unbind_dma(lg, &key, dmas);
-	else {
-		/* Look through this Guest's dma array for an unused entry. */
-		for (i = 0; i < LGUEST_MAX_DMA; i++) {
-			/* If the interrupt is non-zero, the entry is already
-			 * used. */
-			if (lg->dma[i].interrupt)
-				continue;
-
-			/* OK, a free one!  Fill on our details. */
-			lg->dma[i].dmas = dmas;
-			lg->dma[i].num_dmas = numdmas;
-			lg->dma[i].next_dma = 0;
-			lg->dma[i].key = key;
-			lg->dma[i].guestid = lg->guestid;
-			lg->dma[i].interrupt = interrupt;
-
-			/* Now we add it to the hash table: the position
-			 * depends on the futex key that we got. */
-			list_add(&lg->dma[i].list, &dma_hash[hash(&key)]);
-			/* Success! */
-			ret = 1;
-			goto unlock;
-		}
-	}
-	/* If we didn't find a slot to put the key in, drop the reference
-	 * again. */
-	drop_futex_key_refs(&key);
-unlock:
-	/* Unlock and out. */
- 	up_read(fshared);
-	mutex_unlock(&lguest_lock);
-	return ret;
-}
-
-/*L:385 Note that our routines to access a different Guest's memory are called
- * lgread_other() and lgwrite_other(): these names emphasize that they are only
- * used when the Guest is *not* the current Guest.
- *
- * The interface for copying from another process's memory is called
- * access_process_vm(), with a final argument of 0 for a read, and 1 for a
- * write.
- *
- * We need lgread_other() to read the destination Guest's "struct lguest_dma"
- * array. */
-static int lgread_other(struct lguest *lg,
-			void *buf, u32 addr, unsigned bytes)
-{
-	if (!lguest_address_ok(lg, addr, bytes)
-	    || access_process_vm(lg->tsk, addr, buf, bytes, 0) != bytes) {
-		memset(buf, 0, bytes);
-		kill_guest(lg, "bad address in registered DMA struct");
-		return 0;
-	}
-	return 1;
-}
-
-/* "lgwrite()" to another Guest: used to update the destination "used_len" once
- * we've transferred data into the buffer. */
-static int lgwrite_other(struct lguest *lg, u32 addr,
-			 const void *buf, unsigned bytes)
-{
-	if (!lguest_address_ok(lg, addr, bytes)
-	    || (access_process_vm(lg->tsk, addr, (void *)buf, bytes, 1)
-		!= bytes)) {
-		kill_guest(lg, "bad address writing to registered DMA");
-		return 0;
-	}
-	return 1;
-}
-
-/*L:400 This is the generic engine which copies from a source "struct
- * lguest_dma" from this Guest into another Guest's "struct lguest_dma".  The
- * destination Guest's pages have already been mapped, as contained in the
- * pages array.
- *
- * If you're wondering if there's a nice "copy from one process to another"
- * routine, so was I.  But Linux isn't really set up to copy between two
- * unrelated processes, so we have to write it ourselves.
- */
-static u32 copy_data(struct lguest *srclg,
-		     const struct lguest_dma *src,
-		     const struct lguest_dma *dst,
-		     struct page *pages[])
-{
-	unsigned int totlen, si, di, srcoff, dstoff;
-	void *maddr = NULL;
-
-	/* We return the total length transferred. */
-	totlen = 0;
-
-	/* We keep indexes into the source and destination "struct lguest_dma",
-	 * and an offset within each region. */
-	si = di = 0;
-	srcoff = dstoff = 0;
-
-	/* We loop until the source or destination is exhausted. */
-	while (si < LGUEST_MAX_DMA_SECTIONS && src->len[si]
-	       && di < LGUEST_MAX_DMA_SECTIONS && dst->len[di]) {
-		/* We can only transfer the rest of the src buffer, or as much
-		 * as will fit into the destination buffer. */
-		u32 len = min(src->len[si] - srcoff, dst->len[di] - dstoff);
-
-		/* For systems using "highmem" we need to use kmap() to access
-		 * the page we want.  We often use the same page over and over,
-		 * so rather than kmap() it on every loop, we set the maddr
-		 * pointer to NULL when we need to move to the next
-		 * destination page. */
-		if (!maddr)
-			maddr = kmap(pages[di]);
-
-		/* Copy directly from (this Guest's) source address to the
-		 * destination Guest's kmap()ed buffer.  Note that maddr points
-		 * to the start of the page: we need to add the offset of the
-		 * destination address and offset within the buffer. */
-
-		/* FIXME: This is not completely portable.  I looked at
-		 * copy_to_user_page(), and some arch's seem to need special
-		 * flushes.  x86 is fine. */
-		if (copy_from_user(maddr + (dst->addr[di] + dstoff)%PAGE_SIZE,
-				   (void __user *)src->addr[si], len) != 0) {
-			/* If a copy failed, it's the source's fault. */
-			kill_guest(srclg, "bad address in sending DMA");
-			totlen = 0;
-			break;
-		}
-
-		/* Increment the total and src & dst offsets */
-		totlen += len;
-		srcoff += len;
-		dstoff += len;
-
-		/* Presumably we reached the end of the src or dest buffers: */
-		if (srcoff == src->len[si]) {
-			/* Move to the next buffer at offset 0 */
-			si++;
-			srcoff = 0;
-		}
-		if (dstoff == dst->len[di]) {
-			/* We need to unmap that destination page and reset
-			 * maddr ready for the next one. */
-			kunmap(pages[di]);
-			maddr = NULL;
-			di++;
-			dstoff = 0;
-		}
-	}
-
-	/* If we still had a page mapped at the end, unmap now. */
-	if (maddr)
-		kunmap(pages[di]);
-
-	return totlen;
-}
-
-/*L:390 This is how we transfer a "struct lguest_dma" from the source Guest
- * (the current Guest which called SEND_DMA) to another Guest. */
-static u32 do_dma(struct lguest *srclg, const struct lguest_dma *src,
-		  struct lguest *dstlg, const struct lguest_dma *dst)
-{
-	int i;
-	u32 ret;
-	struct page *pages[LGUEST_MAX_DMA_SECTIONS];
-
-	/* We check that both source and destination "struct lguest_dma"s are
-	 * within the bounds of the source and destination Guests */
-	if (!check_dma_list(dstlg, dst) || !check_dma_list(srclg, src))
-		return 0;
-
-	/* We need to map the pages which correspond to each parts of
-	 * destination buffer. */
-	for (i = 0; i < LGUEST_MAX_DMA_SECTIONS; i++) {
-		if (dst->len[i] == 0)
-			break;
-		/* get_user_pages() is a complicated function, especially since
-		 * we only want a single page.  But it works, and returns the
-		 * number of pages.  Note that we're holding the destination's
-		 * mmap_sem, as get_user_pages() requires. */
-		if (get_user_pages(dstlg->tsk, dstlg->mm,
-				   dst->addr[i], 1, 1, 1, pages+i, NULL)
-		    != 1) {
-			/* This means the destination gave us a bogus buffer */
-			kill_guest(dstlg, "Error mapping DMA pages");
-			ret = 0;
-			goto drop_pages;
-		}
-	}
-
-	/* Now copy the data until we run out of src or dst. */
-	ret = copy_data(srclg, src, dst, pages);
-
-drop_pages:
-	while (--i >= 0)
-		put_page(pages[i]);
-	return ret;
-}
-
-/*L:380 Transferring data from one Guest to another is not as simple as I'd
- * like.  We've found the "struct lguest_dma_info" bound to the same address as
- * the send, we need to copy into it.
- *
- * This function returns true if the destination array was empty. */
-static int dma_transfer(struct lguest *srclg,
-			unsigned long udma,
-			struct lguest_dma_info *dst)
-{
-	struct lguest_dma dst_dma, src_dma;
-	struct lguest *dstlg;
-	u32 i, dma = 0;
-
-	/* From the "struct lguest_dma_info" we found in the hash, grab the
-	 * Guest. */
-	dstlg = &lguests[dst->guestid];
-	/* Read in the source "struct lguest_dma" handed to SEND_DMA. */
-	lgread(srclg, &src_dma, udma, sizeof(src_dma));
-
-	/* We need the destination's mmap_sem, and we already hold the source's
-	 * mmap_sem for the futex key lookup.  Normally this would suggest that
-	 * we could deadlock if the destination Guest was trying to send to
-	 * this source Guest at the same time, which is another reason that all
-	 * I/O is done under the big lguest_lock. */
-	down_read(&dstlg->mm->mmap_sem);
-
-	/* Look through the destination DMA array for an available buffer. */
-	for (i = 0; i < dst->num_dmas; i++) {
-		/* We keep a "next_dma" pointer which often helps us avoid
-		 * looking at lots of previously-filled entries. */
-		dma = (dst->next_dma + i) % dst->num_dmas;
-		if (!lgread_other(dstlg, &dst_dma,
-				  dst->dmas + dma * sizeof(struct lguest_dma),
-				  sizeof(dst_dma))) {
-			goto fail;
-		}
-		if (!dst_dma.used_len)
-			break;
-	}
-
-	/* If we found a buffer, we do the actual data copy. */
-	if (i != dst->num_dmas) {
-		unsigned long used_lenp;
-		unsigned int ret;
-
-		ret = do_dma(srclg, &src_dma, dstlg, &dst_dma);
-		/* Put used length in the source "struct lguest_dma"'s used_len
-		 * field.  It's a little tricky to figure out where that is,
-		 * though. */
-		lgwrite_u32(srclg,
-			    udma+offsetof(struct lguest_dma, used_len), ret);
-		/* Tranferring 0 bytes is OK if the source buffer was empty. */
-		if (ret == 0 && src_dma.len[0] != 0)
-			goto fail;
-
-		/* The destination Guest might be running on a different CPU:
-		 * we have to make sure that it will see the "used_len" field
-		 * change to non-zero *after* it sees the data we copied into
-		 * the buffer.  Hence a write memory barrier. */
-		wmb();
-		/* Figuring out where the destination's used_len field for this
-		 * "struct lguest_dma" in the array is also a little ugly. */
-		used_lenp = dst->dmas
-			+ dma * sizeof(struct lguest_dma)
-			+ offsetof(struct lguest_dma, used_len);
-		lgwrite_other(dstlg, used_lenp, &ret, sizeof(ret));
-		/* Move the cursor for next time. */
-		dst->next_dma++;
-	}
- 	up_read(&dstlg->mm->mmap_sem);
-
-	/* We trigger the destination interrupt, even if the destination was
-	 * empty and we didn't transfer anything: this gives them a chance to
-	 * wake up and refill. */
-	set_bit(dst->interrupt, dstlg->irqs_pending);
-	/* Wake up the destination process. */
-	wake_up_process(dstlg->tsk);
-	/* If we passed the last "struct lguest_dma", the receive had no
-	 * buffers left. */
-	return i == dst->num_dmas;
-
-fail:
-	up_read(&dstlg->mm->mmap_sem);
-	return 0;
-}
-
-/*L:370 This is the counter-side to the BIND_DMA hypercall; the SEND_DMA
- * hypercall.  We find out who's listening, and send to them. */
-void send_dma(struct lguest *lg, unsigned long ukey, unsigned long udma)
-{
-	union futex_key key;
-	int empty = 0;
-	struct rw_semaphore *fshared = &current->mm->mmap_sem;
-
-again:
-	mutex_lock(&lguest_lock);
-	down_read(fshared);
-	/* Get the futex key for the key the Guest gave us */
-	if (get_futex_key((u32 __user *)ukey, fshared, &key) != 0) {
-		kill_guest(lg, "bad sending DMA key");
-		goto unlock;
-	}
-	/* Since the key must be a multiple of 4, the futex key uses the lower
-	 * bit of the "offset" field (which would always be 0) to indicate a
-	 * mapping which is shared with other processes (ie. Guests). */
-	if (key.shared.offset & 1) {
-		struct lguest_dma_info *i;
-		/* Look through the hash for other Guests. */
-		list_for_each_entry(i, &dma_hash[hash(&key)], list) {
-			/* Don't send to ourselves. */
-			if (i->guestid == lg->guestid)
-				continue;
-			if (!key_eq(&key, &i->key))
-				continue;
-
-			/* If dma_transfer() tells us the destination has no
-			 * available buffers, we increment "empty". */
-			empty += dma_transfer(lg, udma, i);
-			break;
-		}
-		/* If the destination is empty, we release our locks and
-		 * give the destination Guest a brief chance to restock. */
-		if (empty == 1) {
-			/* Give any recipients one chance to restock. */
-			up_read(&current->mm->mmap_sem);
-			mutex_unlock(&lguest_lock);
-			/* Next time, we won't try again. */
-			empty++;
-			goto again;
-		}
-	} else {
-		/* Private mapping: Guest is sending to its Launcher.  We set
-		 * the "dma_is_pending" flag so that the main loop will exit
-		 * and the Launcher's read() from /dev/lguest will return. */
-		lg->dma_is_pending = 1;
-		lg->pending_dma = udma;
-		lg->pending_key = ukey;
-	}
-unlock:
-	up_read(fshared);
-	mutex_unlock(&lguest_lock);
-}
-/*:*/
-
-void release_all_dma(struct lguest *lg)
-{
-	unsigned int i;
-
-	BUG_ON(!mutex_is_locked(&lguest_lock));
-
-	down_read(&lg->mm->mmap_sem);
-	for (i = 0; i < LGUEST_MAX_DMA; i++) {
-		if (lg->dma[i].interrupt)
-			unlink_dma(&lg->dma[i]);
-	}
-	up_read(&lg->mm->mmap_sem);
-}
-
-/*M:007 We only return a single DMA buffer to the Launcher, but it would be
- * more efficient to return a pointer to the entire array of DMA buffers, which
- * it can cache and choose one whenever it wants.
- *
- * Currently the Launcher uses a write to /dev/lguest, and the return value is
- * the address of the DMA structure with the interrupt number placed in
- * dma->used_len.  If we wanted to return the entire array, we need to return
- * the address, array size and interrupt number: this seems to require an
- * ioctl(). :*/
-
-/*L:320 This routine looks for a DMA buffer registered by the Guest on the
- * given key (using the BIND_DMA hypercall). */
-unsigned long get_dma_buffer(struct lguest *lg,
-			     unsigned long ukey, unsigned long *interrupt)
-{
-	unsigned long ret = 0;
-	union futex_key key;
-	struct lguest_dma_info *i;
-	struct rw_semaphore *fshared = &current->mm->mmap_sem;
-
-	/* Take the Big Lguest Lock to stop other Guests sending this Guest DMA
-	 * at the same time. */
-	mutex_lock(&lguest_lock);
-	/* To match between Guests sharing the same underlying memory we steal
-	 * code from the futex infrastructure.  This requires that we hold the
-	 * "mmap_sem" for our process (the Launcher), and pass it to the futex
-	 * code. */
-	down_read(fshared);
-
-	/* This can fail if it's not a valid address, or if the address is not
-	 * divisible by 4 (the futex code needs that, we don't really). */
-	if (get_futex_key((u32 __user *)ukey, fshared, &key) != 0) {
-		kill_guest(lg, "bad registered DMA buffer");
-		goto unlock;
-	}
-	/* Search the hash table for matching entries (the Launcher can only
-	 * send to its own Guest for the moment, so the entry must be for this
-	 * Guest) */
-	list_for_each_entry(i, &dma_hash[hash(&key)], list) {
-		if (key_eq(&key, &i->key) && i->guestid == lg->guestid) {
-			unsigned int j;
-			/* Look through the registered DMA array for an
-			 * available buffer. */
-			for (j = 0; j < i->num_dmas; j++) {
-				struct lguest_dma dma;
-
-				ret = i->dmas + j * sizeof(struct lguest_dma);
-				lgread(lg, &dma, ret, sizeof(dma));
-				if (dma.used_len == 0)
-					break;
-			}
-			/* Store the interrupt the Guest wants when the buffer
-			 * is used. */
-			*interrupt = i->interrupt;
-			break;
-		}
-	}
-unlock:
-	up_read(fshared);
-	mutex_unlock(&lguest_lock);
-	return ret;
-}
-/*:*/
-
-/*L:410 This really has completed the Launcher.  Not only have we now finished
- * the longest chapter in our journey, but this also means we are over halfway
- * through!
- *
- * Enough prevaricating around the bush: it is time for us to dive into the
- * core of the Host, in "make Host".
- */
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index 64f0abe..d9144be 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -1,119 +1,25 @@
 #ifndef _LGUEST_H
 #define _LGUEST_H
 
-#include <asm/desc.h>
-
-#define GDT_ENTRY_LGUEST_CS	10
-#define GDT_ENTRY_LGUEST_DS	11
-#define LGUEST_CS		(GDT_ENTRY_LGUEST_CS * 8)
-#define LGUEST_DS		(GDT_ENTRY_LGUEST_DS * 8)
-
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/stringify.h>
-#include <linux/binfmts.h>
-#include <linux/futex.h>
 #include <linux/lguest.h>
 #include <linux/lguest_launcher.h>
 #include <linux/wait.h>
 #include <linux/err.h>
 #include <asm/semaphore.h>
-#include "irq_vectors.h"
 
-#define GUEST_PL 1
-
-struct lguest_regs
-{
-	/* Manually saved part. */
-	unsigned long ebx, ecx, edx;
-	unsigned long esi, edi, ebp;
-	unsigned long gs;
-	unsigned long eax;
-	unsigned long fs, ds, es;
-	unsigned long trapnum, errcode;
-	/* Trap pushed part */
-	unsigned long eip;
-	unsigned long cs;
-	unsigned long eflags;
-	unsigned long esp;
-	unsigned long ss;
-};
+#include <asm/lguest.h>
 
 void free_pagetables(void);
 int init_pagetables(struct page **switcher_page, unsigned int pages);
 
-/* Full 4G segment descriptors, suitable for CS and DS. */
-#define FULL_EXEC_SEGMENT ((struct desc_struct){0x0000ffff, 0x00cf9b00})
-#define FULL_SEGMENT ((struct desc_struct){0x0000ffff, 0x00cf9300})
-
-struct lguest_dma_info
-{
-	struct list_head list;
-	union futex_key key;
-	unsigned long dmas;
-	u16 next_dma;
-	u16 num_dmas;
-	u16 guestid;
-	u8 interrupt; 	/* 0 when not registered */
-};
-
-/*H:310 The page-table code owes a great debt of gratitude to Andi Kleen.  He
- * reviewed the original code which used "u32" for all page table entries, and
- * insisted that it would be far clearer with explicit typing.  I thought it
- * was overkill, but he was right: it is much clearer than it was before.
- *
- * We have separate types for the Guest's ptes & pgds and the shadow ptes &
- * pgds.  There's already a Linux type for these (pte_t and pgd_t) but they
- * change depending on kernel config options (PAE). */
-
-/* Each entry is identical: lower 12 bits of flags and upper 20 bits for the
- * "page frame number" (0 == first physical page, etc).  They are different
- * types so the compiler will warn us if we mix them improperly. */
-typedef union {
-	struct { unsigned flags:12, pfn:20; };
-	struct { unsigned long val; } raw;
-} spgd_t;
-typedef union {
-	struct { unsigned flags:12, pfn:20; };
-	struct { unsigned long val; } raw;
-} spte_t;
-typedef union {
-	struct { unsigned flags:12, pfn:20; };
-	struct { unsigned long val; } raw;
-} gpgd_t;
-typedef union {
-	struct { unsigned flags:12, pfn:20; };
-	struct { unsigned long val; } raw;
-} gpte_t;
-
-/* We have two convenient macros to convert a "raw" value as handed to us by
- * the Guest into the correct Guest PGD or PTE type. */
-#define mkgpte(_val) ((gpte_t){.raw.val = _val})
-#define mkgpgd(_val) ((gpgd_t){.raw.val = _val})
-/*:*/
-
 struct pgdir
 {
-	unsigned long cr3;
-	spgd_t *pgdir;
-};
-
-/* This is a guest-specific page (mapped ro) into the guest. */
-struct lguest_ro_state
-{
-	/* Host information we need to restore when we switch back. */
-	u32 host_cr3;
-	struct Xgt_desc_struct host_idt_desc;
-	struct Xgt_desc_struct host_gdt_desc;
-	u32 host_sp;
-
-	/* Fields which are used when guest is running. */
-	struct Xgt_desc_struct guest_idt_desc;
-	struct Xgt_desc_struct guest_gdt_desc;
-	struct i386_hw_tss guest_tss;
-	struct desc_struct guest_idt[IDT_ENTRIES];
-	struct desc_struct guest_gdt[GDT_ENTRIES];
+	unsigned long gpgdir;
+	pgd_t *pgdir;
 };
 
 /* We have two pages shared with guests, per cpu.  */
@@ -141,9 +47,11 @@
 	struct lguest_data __user *lguest_data;
 	struct task_struct *tsk;
 	struct mm_struct *mm; 	/* == tsk->mm, but that becomes NULL on exit */
-	u16 guestid;
 	u32 pfn_limit;
-	u32 page_offset;
+	/* This provides the offset to the base of guest-physical
+	 * memory in the Launcher. */
+	void __user *mem_base;
+	unsigned long kernel_address;
 	u32 cr2;
 	int halted;
 	int ts;
@@ -151,6 +59,9 @@
 	u32 esp1;
 	u8 ss1;
 
+	/* If a hypercall was asked for, this points to the arguments. */
+	struct hcall_args *hcall;
+
 	/* Do we need to stop what we're doing and return to userspace? */
 	int break_out;
 	wait_queue_head_t break_wq;
@@ -167,24 +78,15 @@
 	struct task_struct *wake;
 
 	unsigned long noirq_start, noirq_end;
-	int dma_is_pending;
-	unsigned long pending_dma; /* struct lguest_dma */
-	unsigned long pending_key; /* address they're sending to */
+	unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */
 
 	unsigned int stack_pages;
 	u32 tsc_khz;
 
-	struct lguest_dma_info dma[LGUEST_MAX_DMA];
-
 	/* Dead? */
 	const char *dead;
 
-	/* The GDT entries copied into lguest_ro_state when running. */
-	struct desc_struct gdt[GDT_ENTRIES];
-
-	/* The IDT entries: some copied into lguest_ro_state when running. */
-	struct desc_struct idt[FIRST_EXTERNAL_VECTOR+LGUEST_IRQS];
-	struct desc_struct syscall_idt;
+	struct lguest_arch arch;
 
 	/* Virtual clock device */
 	struct hrtimer hrt;
@@ -193,19 +95,38 @@
 	DECLARE_BITMAP(irqs_pending, LGUEST_IRQS);
 };
 
-extern struct lguest lguests[];
 extern struct mutex lguest_lock;
 
 /* core.c: */
-u32 lgread_u32(struct lguest *lg, unsigned long addr);
-void lgwrite_u32(struct lguest *lg, unsigned long addr, u32 val);
-void lgread(struct lguest *lg, void *buf, unsigned long addr, unsigned len);
-void lgwrite(struct lguest *lg, unsigned long, const void *buf, unsigned len);
-int find_free_guest(void);
 int lguest_address_ok(const struct lguest *lg,
 		      unsigned long addr, unsigned long len);
+void __lgread(struct lguest *, void *, unsigned long, unsigned);
+void __lgwrite(struct lguest *, unsigned long, const void *, unsigned);
+
+/*L:306 Using memory-copy operations like that is usually inconvient, so we
+ * have the following helper macros which read and write a specific type (often
+ * an unsigned long).
+ *
+ * This reads into a variable of the given type then returns that. */
+#define lgread(lg, addr, type)						\
+	({ type _v; __lgread((lg), &_v, (addr), sizeof(_v)); _v; })
+
+/* This checks that the variable is of the given type, then writes it out. */
+#define lgwrite(lg, addr, type, val)				\
+	do {							\
+		typecheck(type, val);				\
+		__lgwrite((lg), (addr), &(val), sizeof(val));	\
+	} while(0)
+/* (end of memory access helper routines) :*/
+
 int run_guest(struct lguest *lg, unsigned long __user *user);
 
+/* Helper macros to obtain the first 12 or the last 20 bits, this is only the
+ * first step in the migration to the kernel types.  pte_pfn is already defined
+ * in the kernel. */
+#define pgd_flags(x)	(pgd_val(x) & ~PAGE_MASK)
+#define pte_flags(x)	(pte_val(x) & ~PAGE_MASK)
+#define pgd_pfn(x)	(pgd_val(x) >> PAGE_SHIFT)
 
 /* interrupts_and_traps.c: */
 void maybe_do_interrupt(struct lguest *lg);
@@ -219,6 +140,9 @@
 		const unsigned long *def);
 void guest_set_clockevent(struct lguest *lg, unsigned long delta);
 void init_clockdev(struct lguest *lg);
+bool check_syscall_vector(struct lguest *lg);
+int init_interrupts(void);
+void free_interrupts(void);
 
 /* segments.c: */
 void setup_default_gdt_entries(struct lguest_ro_state *state);
@@ -232,28 +156,33 @@
 int init_guest_pagetable(struct lguest *lg, unsigned long pgtable);
 void free_guest_pagetable(struct lguest *lg);
 void guest_new_pagetable(struct lguest *lg, unsigned long pgtable);
-void guest_set_pmd(struct lguest *lg, unsigned long cr3, u32 i);
+void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 i);
 void guest_pagetable_clear_all(struct lguest *lg);
 void guest_pagetable_flush_user(struct lguest *lg);
-void guest_set_pte(struct lguest *lg, unsigned long cr3,
-		   unsigned long vaddr, gpte_t val);
+void guest_set_pte(struct lguest *lg, unsigned long gpgdir,
+		   unsigned long vaddr, pte_t val);
 void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages);
 int demand_page(struct lguest *info, unsigned long cr2, int errcode);
 void pin_page(struct lguest *lg, unsigned long vaddr);
+unsigned long guest_pa(struct lguest *lg, unsigned long vaddr);
+void page_table_guest_data_init(struct lguest *lg);
+
+/* <arch>/core.c: */
+void lguest_arch_host_init(void);
+void lguest_arch_host_fini(void);
+void lguest_arch_run_guest(struct lguest *lg);
+void lguest_arch_handle_trap(struct lguest *lg);
+int lguest_arch_init_hypercalls(struct lguest *lg);
+int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args);
+void lguest_arch_setup_regs(struct lguest *lg, unsigned long start);
+
+/* <arch>/switcher.S: */
+extern char start_switcher_text[], end_switcher_text[], switch_to_guest[];
 
 /* lguest_user.c: */
 int lguest_device_init(void);
 void lguest_device_remove(void);
 
-/* io.c: */
-void lguest_io_init(void);
-int bind_dma(struct lguest *lg,
-	     unsigned long key, unsigned long udma, u16 numdmas, u8 interrupt);
-void send_dma(struct lguest *info, unsigned long key, unsigned long udma);
-void release_all_dma(struct lguest *lg);
-unsigned long get_dma_buffer(struct lguest *lg, unsigned long key,
-			     unsigned long *interrupt);
-
 /* hypercalls.c: */
 void do_hypercalls(struct lguest *lg);
 void write_timestamp(struct lguest *lg);
@@ -292,9 +221,5 @@
 } while(0)
 /* (End of aside) :*/
 
-static inline unsigned long guest_pa(struct lguest *lg, unsigned long vaddr)
-{
-	return vaddr - lg->page_offset;
-}
 #endif	/* __ASSEMBLY__ */
 #endif	/* _LGUEST_H */
diff --git a/drivers/lguest/lguest_bus.c b/drivers/lguest/lguest_bus.c
deleted file mode 100644
index 57329788..0000000
--- a/drivers/lguest/lguest_bus.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*P:050 Lguest guests use a very simple bus for devices.  It's a simple array
- * of device descriptors contained just above the top of normal memory.  The
- * lguest bus is 80% tedious boilerplate code. :*/
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/lguest_bus.h>
-#include <asm/io.h>
-#include <asm/paravirt.h>
-
-static ssize_t type_show(struct device *_dev,
-                         struct device_attribute *attr, char *buf)
-{
-	struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
-	return sprintf(buf, "%hu", lguest_devices[dev->index].type);
-}
-static ssize_t features_show(struct device *_dev,
-                             struct device_attribute *attr, char *buf)
-{
-	struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
-	return sprintf(buf, "%hx", lguest_devices[dev->index].features);
-}
-static ssize_t pfn_show(struct device *_dev,
-			 struct device_attribute *attr, char *buf)
-{
-	struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
-	return sprintf(buf, "%u", lguest_devices[dev->index].pfn);
-}
-static ssize_t status_show(struct device *_dev,
-                           struct device_attribute *attr, char *buf)
-{
-	struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
-	return sprintf(buf, "%hx", lguest_devices[dev->index].status);
-}
-static ssize_t status_store(struct device *_dev, struct device_attribute *attr,
-                            const char *buf, size_t count)
-{
-	struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
-	if (sscanf(buf, "%hi", &lguest_devices[dev->index].status) != 1)
-		return -EINVAL;
-	return count;
-}
-static struct device_attribute lguest_dev_attrs[] = {
-	__ATTR_RO(type),
-	__ATTR_RO(features),
-	__ATTR_RO(pfn),
-	__ATTR(status, 0644, status_show, status_store),
-	__ATTR_NULL
-};
-
-/*D:130 The generic bus infrastructure requires a function which says whether a
- * device matches a driver.  For us, it is simple: "struct lguest_driver"
- * contains a "device_type" field which indicates what type of device it can
- * handle, so we just cast the args and compare: */
-static int lguest_dev_match(struct device *_dev, struct device_driver *_drv)
-{
-	struct lguest_device *dev = container_of(_dev,struct lguest_device,dev);
-	struct lguest_driver *drv = container_of(_drv,struct lguest_driver,drv);
-
-	return (drv->device_type == lguest_devices[dev->index].type);
-}
-/*:*/
-
-struct lguest_bus {
-	struct bus_type bus;
-	struct device dev;
-};
-
-static struct lguest_bus lguest_bus = {
-	.bus = {
-		.name  = "lguest",
-		.match = lguest_dev_match,
-		.dev_attrs = lguest_dev_attrs,
-	},
-	.dev = {
-		.parent = NULL,
-		.bus_id = "lguest",
-	}
-};
-
-/*D:140 This is the callback which occurs once the bus infrastructure matches
- * up a device and driver, ie. in response to add_lguest_device() calling
- * device_register(), or register_lguest_driver() calling driver_register().
- *
- * At the moment it's always the latter: the devices are added first, since
- * scan_devices() is called from a "core_initcall", and the drivers themselves
- * called later as a normal "initcall".  But it would work the other way too.
- *
- * So now we have the happy couple, we add the status bit to indicate that we
- * found a driver.  If the driver truly loves the device, it will return
- * happiness from its probe function (ok, perhaps this wasn't my greatest
- * analogy), and we set the final "driver ok" bit so the Host sees it's all
- * green. */
-static int lguest_dev_probe(struct device *_dev)
-{
-	int ret;
-	struct lguest_device*dev = container_of(_dev,struct lguest_device,dev);
-	struct lguest_driver*drv = container_of(dev->dev.driver,
-						struct lguest_driver, drv);
-
-	lguest_devices[dev->index].status |= LGUEST_DEVICE_S_DRIVER;
-	ret = drv->probe(dev);
-	if (ret == 0)
-		lguest_devices[dev->index].status |= LGUEST_DEVICE_S_DRIVER_OK;
-	return ret;
-}
-
-/* The last part of the bus infrastructure is the function lguest drivers use
- * to register themselves.  Firstly, we do nothing if there's no lguest bus
- * (ie. this is not a Guest), otherwise we fill in the embedded generic "struct
- * driver" fields and call the generic driver_register(). */
-int register_lguest_driver(struct lguest_driver *drv)
-{
-	if (!lguest_devices)
-		return 0;
-
-	drv->drv.bus = &lguest_bus.bus;
-	drv->drv.name = drv->name;
-	drv->drv.owner = drv->owner;
-	drv->drv.probe = lguest_dev_probe;
-
-	return driver_register(&drv->drv);
-}
-
-/* At the moment we build all the drivers into the kernel because they're so
- * simple: 8144 bytes for all three of them as I type this.  And as the console
- * really needs to be built in, it's actually only 3527 bytes for the network
- * and block drivers.
- *
- * If they get complex it will make sense for them to be modularized, so we
- * need to explicitly export the symbol.
- *
- * I don't think non-GPL modules make sense, so it's a GPL-only export.
- */
-EXPORT_SYMBOL_GPL(register_lguest_driver);
-
-/*D:120 This is the core of the lguest bus: actually adding a new device.
- * It's a separate function because it's neater that way, and because an
- * earlier version of the code supported hotplug and unplug.  They were removed
- * early on because they were never used.
- *
- * As Andrew Tridgell says, "Untested code is buggy code".
- *
- * It's worth reading this carefully: we start with an index into the array of
- * "struct lguest_device_desc"s indicating the device which is new: */
-static void add_lguest_device(unsigned int index)
-{
-	struct lguest_device *new;
-
-	/* Each "struct lguest_device_desc" has a "status" field, which the
-	 * Guest updates as the device is probed.  In the worst case, the Host
-	 * can look at these bits to tell what part of device setup failed,
-	 * even if the console isn't available. */
-	lguest_devices[index].status |= LGUEST_DEVICE_S_ACKNOWLEDGE;
-	new = kmalloc(sizeof(struct lguest_device), GFP_KERNEL);
-	if (!new) {
-		printk(KERN_EMERG "Cannot allocate lguest device %u\n", index);
-		lguest_devices[index].status |= LGUEST_DEVICE_S_FAILED;
-		return;
-	}
-
-	/* The "struct lguest_device" setup is pretty straight-forward example
-	 * code. */
-	new->index = index;
-	new->private = NULL;
-	memset(&new->dev, 0, sizeof(new->dev));
-	new->dev.parent = &lguest_bus.dev;
-	new->dev.bus = &lguest_bus.bus;
-	sprintf(new->dev.bus_id, "%u", index);
-
-	/* device_register() causes the bus infrastructure to look for a
-	 * matching driver. */
-	if (device_register(&new->dev) != 0) {
-		printk(KERN_EMERG "Cannot register lguest device %u\n", index);
-		lguest_devices[index].status |= LGUEST_DEVICE_S_FAILED;
-		kfree(new);
-	}
-}
-
-/*D:110 scan_devices() simply iterates through the device array.  The type 0
- * is reserved to mean "no device", and anything else means we have found a
- * device: add it. */
-static void scan_devices(void)
-{
-	unsigned int i;
-
-	for (i = 0; i < LGUEST_MAX_DEVICES; i++)
-		if (lguest_devices[i].type)
-			add_lguest_device(i);
-}
-
-/*D:100 Fairly early in boot, lguest_bus_init() is called to set up the lguest
- * bus.  We check that we are a Guest by checking paravirt_ops.name: there are
- * other ways of checking, but this seems most obvious to me.
- *
- * So we can access the array of "struct lguest_device_desc"s easily, we map
- * that memory and store the pointer in the global "lguest_devices".  Then we
- * register the bus with the core.  Doing two registrations seems clunky to me,
- * but it seems to be the correct sysfs incantation.
- *
- * Finally we call scan_devices() which adds all the devices found in the
- * "struct lguest_device_desc" array. */
-static int __init lguest_bus_init(void)
-{
-	if (strcmp(pv_info.name, "lguest") != 0)
-		return 0;
-
-	/* Devices are in a single page above top of "normal" mem */
-	lguest_devices = lguest_map(max_pfn<<PAGE_SHIFT, 1);
-
-	if (bus_register(&lguest_bus.bus) != 0
-	    || device_register(&lguest_bus.dev) != 0)
-		panic("lguest bus registration failed");
-
-	scan_devices();
-	return 0;
-}
-/* Do this after core stuff, before devices. */
-postcore_initcall(lguest_bus_init);
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
new file mode 100644
index 0000000..71c6483
--- /dev/null
+++ b/drivers/lguest/lguest_device.c
@@ -0,0 +1,373 @@
+/*P:050 Lguest guests use a very simple method to describe devices.  It's a
+ * series of device descriptors contained just above the top of normal
+ * memory.
+ *
+ * We use the standard "virtio" device infrastructure, which provides us with a
+ * console, a network and a block driver.  Each one expects some configuration
+ * information and a "virtqueue" mechanism to send and receive data. :*/
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/lguest_launcher.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/interrupt.h>
+#include <linux/virtio_ring.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include <asm/paravirt.h>
+#include <asm/lguest_hcall.h>
+
+/* The pointer to our (page) of device descriptions. */
+static void *lguest_devices;
+
+/* Unique numbering for lguest devices. */
+static unsigned int dev_index;
+
+/* For Guests, device memory can be used as normal memory, so we cast away the
+ * __iomem to quieten sparse. */
+static inline void *lguest_map(unsigned long phys_addr, unsigned long pages)
+{
+	return (__force void *)ioremap(phys_addr, PAGE_SIZE*pages);
+}
+
+static inline void lguest_unmap(void *addr)
+{
+	iounmap((__force void __iomem *)addr);
+}
+
+/*D:100 Each lguest device is just a virtio device plus a pointer to its entry
+ * in the lguest_devices page. */
+struct lguest_device {
+	struct virtio_device vdev;
+
+	/* The entry in the lguest_devices page for this device. */
+	struct lguest_device_desc *desc;
+};
+
+/* Since the virtio infrastructure hands us a pointer to the virtio_device all
+ * the time, it helps to have a curt macro to get a pointer to the struct
+ * lguest_device it's enclosed in.  */
+#define to_lgdev(vdev) container_of(vdev, struct lguest_device, vdev)
+
+/*D:130
+ * Device configurations
+ *
+ * The configuration information for a device consists of a series of fields.
+ * The device will look for these fields during setup.
+ *
+ * For us these fields come immediately after that device's descriptor in the
+ * lguest_devices page.
+ *
+ * Each field starts with a "type" byte, a "length" byte, then that number of
+ * bytes of configuration information.  The device descriptor tells us the
+ * total configuration length so we know when we've reached the last field. */
+
+/* type + length bytes */
+#define FHDR_LEN 2
+
+/* This finds the first field of a given type for a device's configuration. */
+static void *lg_find(struct virtio_device *vdev, u8 type, unsigned int *len)
+{
+	struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
+	int i;
+
+	for (i = 0; i < desc->config_len; i += FHDR_LEN + desc->config[i+1]) {
+		if (desc->config[i] == type) {
+			/* Mark it used, so Host can know we looked at it, and
+			 * also so we won't find the same one twice. */
+			desc->config[i] |= 0x80;
+			/* Remember, the second byte is the length. */
+			*len = desc->config[i+1];
+			/* We return a pointer to the field header. */
+			return desc->config + i;
+		}
+	}
+
+	/* Not found: return NULL for failure. */
+	return NULL;
+}
+
+/* Once they've found a field, getting a copy of it is easy. */
+static void lg_get(struct virtio_device *vdev, void *token,
+		   void *buf, unsigned len)
+{
+	/* Check they didn't ask for more than the length of the field! */
+	BUG_ON(len > ((u8 *)token)[1]);
+	memcpy(buf, token + FHDR_LEN, len);
+}
+
+/* Setting the contents is also trivial. */
+static void lg_set(struct virtio_device *vdev, void *token,
+		   const void *buf, unsigned len)
+{
+	BUG_ON(len > ((u8 *)token)[1]);
+	memcpy(token + FHDR_LEN, buf, len);
+}
+
+/* The operations to get and set the status word just access the status field
+ * of the device descriptor. */
+static u8 lg_get_status(struct virtio_device *vdev)
+{
+	return to_lgdev(vdev)->desc->status;
+}
+
+static void lg_set_status(struct virtio_device *vdev, u8 status)
+{
+	to_lgdev(vdev)->desc->status = status;
+}
+
+/*
+ * Virtqueues
+ *
+ * The other piece of infrastructure virtio needs is a "virtqueue": a way of
+ * the Guest device registering buffers for the other side to read from or
+ * write into (ie. send and receive buffers).  Each device can have multiple
+ * virtqueues: for example the console has one queue for sending and one for
+ * receiving.
+ *
+ * Fortunately for us, a very fast shared-memory-plus-descriptors virtqueue
+ * already exists in virtio_ring.c.  We just need to connect it up.
+ *
+ * We start with the information we need to keep about each virtqueue.
+ */
+
+/*D:140 This is the information we remember about each virtqueue. */
+struct lguest_vq_info
+{
+	/* A copy of the information contained in the device config. */
+	struct lguest_vqconfig config;
+
+	/* The address where we mapped the virtio ring, so we can unmap it. */
+	void *pages;
+};
+
+/* When the virtio_ring code wants to prod the Host, it calls us here and we
+ * make a hypercall.  We hand the page number of the virtqueue so the Host
+ * knows which virtqueue we're talking about. */
+static void lg_notify(struct virtqueue *vq)
+{
+	/* We store our virtqueue information in the "priv" pointer of the
+	 * virtqueue structure. */
+	struct lguest_vq_info *lvq = vq->priv;
+
+	hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0);
+}
+
+/* This routine finds the first virtqueue described in the configuration of
+ * this device and sets it up.
+ *
+ * This is kind of an ugly duckling.  It'd be nicer to have a standard
+ * representation of a virtqueue in the configuration space, but it seems that
+ * everyone wants to do it differently.  The KVM guys want the Guest to
+ * allocate its own pages and tell the Host where they are, but for lguest it's
+ * simpler for the Host to simply tell us where the pages are.
+ *
+ * So we provide devices with a "find virtqueue and set it up" function. */
+static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
+				    bool (*callback)(struct virtqueue *vq))
+{
+	struct lguest_vq_info *lvq;
+	struct virtqueue *vq;
+	unsigned int len;
+	void *token;
+	int err;
+
+	/* Look for a field of the correct type to mark a virtqueue.  Note that
+	 * if this succeeds, then the type will be changed so it won't be found
+	 * again, and future lg_find_vq() calls will find the next
+	 * virtqueue (if any). */
+	token = vdev->config->find(vdev, VIRTIO_CONFIG_F_VIRTQUEUE, &len);
+	if (!token)
+		return ERR_PTR(-ENOENT);
+
+	lvq = kmalloc(sizeof(*lvq), GFP_KERNEL);
+	if (!lvq)
+		return ERR_PTR(-ENOMEM);
+
+	/* Note: we could use a configuration space inside here, just like we
+	 * do for the device.  This would allow expansion in future, because
+	 * our configuration system is designed to be expansible.  But this is
+	 * way easier. */
+	if (len != sizeof(lvq->config)) {
+		dev_err(&vdev->dev, "Unexpected virtio config len %u\n", len);
+		err = -EIO;
+		goto free_lvq;
+	}
+	/* Make a copy of the "struct lguest_vqconfig" field.  We need a copy
+	 * because the config space might not be aligned correctly. */
+	vdev->config->get(vdev, token, &lvq->config, sizeof(lvq->config));
+
+	/* Figure out how many pages the ring will take, and map that memory */
+	lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT,
+				DIV_ROUND_UP(vring_size(lvq->config.num),
+					     PAGE_SIZE));
+	if (!lvq->pages) {
+		err = -ENOMEM;
+		goto free_lvq;
+	}
+
+	/* OK, tell virtio_ring.c to set up a virtqueue now we know its size
+	 * and we've got a pointer to its pages. */
+	vq = vring_new_virtqueue(lvq->config.num, vdev, lvq->pages,
+				 lg_notify, callback);
+	if (!vq) {
+		err = -ENOMEM;
+		goto unmap;
+	}
+
+	/* Tell the interrupt for this virtqueue to go to the virtio_ring
+	 * interrupt handler. */
+	/* FIXME: We used to have a flag for the Host to tell us we could use
+	 * the interrupt as a source of randomness: it'd be nice to have that
+	 * back.. */
+	err = request_irq(lvq->config.irq, vring_interrupt, IRQF_SHARED,
+			  vdev->dev.bus_id, vq);
+	if (err)
+		goto destroy_vring;
+
+	/* Last of all we hook up our 'struct lguest_vq_info" to the
+	 * virtqueue's priv pointer. */
+	vq->priv = lvq;
+	return vq;
+
+destroy_vring:
+	vring_del_virtqueue(vq);
+unmap:
+	lguest_unmap(lvq->pages);
+free_lvq:
+	kfree(lvq);
+	return ERR_PTR(err);
+}
+/*:*/
+
+/* Cleaning up a virtqueue is easy */
+static void lg_del_vq(struct virtqueue *vq)
+{
+	struct lguest_vq_info *lvq = vq->priv;
+
+	/* Tell virtio_ring.c to free the virtqueue. */
+	vring_del_virtqueue(vq);
+	/* Unmap the pages containing the ring. */
+	lguest_unmap(lvq->pages);
+	/* Free our own queue information. */
+	kfree(lvq);
+}
+
+/* The ops structure which hooks everything together. */
+static struct virtio_config_ops lguest_config_ops = {
+	.find = lg_find,
+	.get = lg_get,
+	.set = lg_set,
+	.get_status = lg_get_status,
+	.set_status = lg_set_status,
+	.find_vq = lg_find_vq,
+	.del_vq = lg_del_vq,
+};
+
+/* The root device for the lguest virtio devices.  This makes them appear as
+ * /sys/devices/lguest/0,1,2 not /sys/devices/0,1,2. */
+static struct device lguest_root = {
+	.parent = NULL,
+	.bus_id = "lguest",
+};
+
+/*D:120 This is the core of the lguest bus: actually adding a new device.
+ * It's a separate function because it's neater that way, and because an
+ * earlier version of the code supported hotplug and unplug.  They were removed
+ * early on because they were never used.
+ *
+ * As Andrew Tridgell says, "Untested code is buggy code".
+ *
+ * It's worth reading this carefully: we start with a pointer to the new device
+ * descriptor in the "lguest_devices" page. */
+static void add_lguest_device(struct lguest_device_desc *d)
+{
+	struct lguest_device *ldev;
+
+	ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
+	if (!ldev) {
+		printk(KERN_EMERG "Cannot allocate lguest dev %u\n",
+		       dev_index++);
+		return;
+	}
+
+	/* This devices' parent is the lguest/ dir. */
+	ldev->vdev.dev.parent = &lguest_root;
+	/* We have a unique device index thanks to the dev_index counter. */
+	ldev->vdev.index = dev_index++;
+	/* The device type comes straight from the descriptor.  There's also a
+	 * device vendor field in the virtio_device struct, which we leave as
+	 * 0. */
+	ldev->vdev.id.device = d->type;
+	/* We have a simple set of routines for querying the device's
+	 * configuration information and setting its status. */
+	ldev->vdev.config = &lguest_config_ops;
+	/* And we remember the device's descriptor for lguest_config_ops. */
+	ldev->desc = d;
+
+	/* register_virtio_device() sets up the generic fields for the struct
+	 * virtio_device and calls device_register().  This makes the bus
+	 * infrastructure look for a matching driver. */
+	if (register_virtio_device(&ldev->vdev) != 0) {
+		printk(KERN_ERR "Failed to register lguest device %u\n",
+		       ldev->vdev.index);
+		kfree(ldev);
+	}
+}
+
+/*D:110 scan_devices() simply iterates through the device page.  The type 0 is
+ * reserved to mean "end of devices". */
+static void scan_devices(void)
+{
+	unsigned int i;
+	struct lguest_device_desc *d;
+
+	/* We start at the page beginning, and skip over each entry. */
+	for (i = 0; i < PAGE_SIZE; i += sizeof(*d) + d->config_len) {
+		d = lguest_devices + i;
+
+		/* Once we hit a zero, stop. */
+		if (d->type == 0)
+			break;
+
+		add_lguest_device(d);
+	}
+}
+
+/*D:105 Fairly early in boot, lguest_devices_init() is called to set up the
+ * lguest device infrastructure.  We check that we are a Guest by checking
+ * pv_info.name: there are other ways of checking, but this seems most
+ * obvious to me.
+ *
+ * So we can access the "struct lguest_device_desc"s easily, we map that memory
+ * and store the pointer in the global "lguest_devices".  Then we register a
+ * root device from which all our devices will hang (this seems to be the
+ * correct sysfs incantation).
+ *
+ * Finally we call scan_devices() which adds all the devices found in the
+ * lguest_devices page. */
+static int __init lguest_devices_init(void)
+{
+	if (strcmp(pv_info.name, "lguest") != 0)
+		return 0;
+
+	if (device_register(&lguest_root) != 0)
+		panic("Could not register lguest root");
+
+	/* Devices are in a single page above top of "normal" mem */
+	lguest_devices = lguest_map(max_pfn<<PAGE_SHIFT, 1);
+
+	scan_devices();
+	return 0;
+}
+/* We do this after core stuff, but before the drivers. */
+postcore_initcall(lguest_devices_init);
+
+/*D:150 At this point in the journey we used to now wade through the lguest
+ * devices themselves: net, block and console.  Since they're all now virtio
+ * devices rather than lguest-specific, I've decided to ignore them.  Mostly,
+ * they're kind of boring.  But this does mean you'll never experience the
+ * thrill of reading the forbidden love scene buried deep in the block driver.
+ *
+ * "make Launcher" beckons, where we answer questions like "Where do Guests
+ * come from?", and "What do you do when someone asks for optimization?". */
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 80d1b58..ee405b38 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -1,73 +1,17 @@
 /*P:200 This contains all the /dev/lguest code, whereby the userspace launcher
  * controls and communicates with the Guest.  For example, the first write will
- * tell us the memory size, pagetable, entry point and kernel address offset.
- * A read will run the Guest until a signal is pending (-EINTR), or the Guest
- * does a DMA out to the Launcher.  Writes are also used to get a DMA buffer
- * registered by the Guest and to send the Guest an interrupt. :*/
+ * tell us the Guest's memory layout, pagetable, entry point and kernel address
+ * offset.  A read will run the Guest until something happens, such as a signal
+ * or the Guest doing a NOTIFY out to the Launcher. :*/
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
 #include <linux/fs.h>
 #include "lg.h"
 
-/*L:030 setup_regs() doesn't really belong in this file, but it gives us an
- * early glimpse deeper into the Host so it's worth having here.
- *
- * Most of the Guest's registers are left alone: we used get_zeroed_page() to
- * allocate the structure, so they will be 0. */
-static void setup_regs(struct lguest_regs *regs, unsigned long start)
-{
-	/* There are four "segment" registers which the Guest needs to boot:
-	 * The "code segment" register (cs) refers to the kernel code segment
-	 * __KERNEL_CS, and the "data", "extra" and "stack" segment registers
-	 * refer to the kernel data segment __KERNEL_DS.
-	 *
-	 * The privilege level is packed into the lower bits.  The Guest runs
-	 * at privilege level 1 (GUEST_PL).*/
-	regs->ds = regs->es = regs->ss = __KERNEL_DS|GUEST_PL;
-	regs->cs = __KERNEL_CS|GUEST_PL;
-
-	/* The "eflags" register contains miscellaneous flags.  Bit 1 (0x002)
-	 * is supposed to always be "1".  Bit 9 (0x200) controls whether
-	 * interrupts are enabled.  We always leave interrupts enabled while
-	 * running the Guest. */
-	regs->eflags = 0x202;
-
-	/* The "Extended Instruction Pointer" register says where the Guest is
-	 * running. */
-	regs->eip = start;
-
-	/* %esi points to our boot information, at physical address 0, so don't
-	 * touch it. */
-}
-
-/*L:310 To send DMA into the Guest, the Launcher needs to be able to ask for a
- * DMA buffer.  This is done by writing LHREQ_GETDMA and the key to
- * /dev/lguest. */
-static long user_get_dma(struct lguest *lg, const u32 __user *input)
-{
-	unsigned long key, udma, irq;
-
-	/* Fetch the key they wrote to us. */
-	if (get_user(key, input) != 0)
-		return -EFAULT;
-	/* Look for a free Guest DMA buffer bound to that key. */
-	udma = get_dma_buffer(lg, key, &irq);
-	if (!udma)
-		return -ENOENT;
-
-	/* We need to tell the Launcher what interrupt the Guest expects after
-	 * the buffer is filled.  We stash it in udma->used_len. */
-	lgwrite_u32(lg, udma + offsetof(struct lguest_dma, used_len), irq);
-
-	/* The (guest-physical) address of the DMA buffer is returned from
-	 * the write(). */
-	return udma;
-}
-
 /*L:315 To force the Guest to stop running and return to the Launcher, the
  * Waker sets writes LHREQ_BREAK and the value "1" to /dev/lguest.  The
  * Launcher then writes LHREQ_BREAK and "0" to release the Waker. */
-static int break_guest_out(struct lguest *lg, const u32 __user *input)
+static int break_guest_out(struct lguest *lg, const unsigned long __user *input)
 {
 	unsigned long on;
 
@@ -90,9 +34,9 @@
 
 /*L:050 Sending an interrupt is done by writing LHREQ_IRQ and an interrupt
  * number to /dev/lguest. */
-static int user_send_irq(struct lguest *lg, const u32 __user *input)
+static int user_send_irq(struct lguest *lg, const unsigned long __user *input)
 {
-	u32 irq;
+	unsigned long irq;
 
 	if (get_user(irq, input) != 0)
 		return -EFAULT;
@@ -133,17 +77,19 @@
 		return len;
 	}
 
-	/* If we returned from read() last time because the Guest sent DMA,
+	/* If we returned from read() last time because the Guest notified,
 	 * clear the flag. */
-	if (lg->dma_is_pending)
-		lg->dma_is_pending = 0;
+	if (lg->pending_notify)
+		lg->pending_notify = 0;
 
 	/* Run the Guest until something interesting happens. */
 	return run_guest(lg, (unsigned long __user *)user);
 }
 
-/*L:020 The initialization write supplies 4 32-bit values (in addition to the
- * 32-bit LHREQ_INITIALIZE value).  These are:
+/*L:020 The initialization write supplies 4 pointer sized (32 or 64 bit)
+ * values (in addition to the LHREQ_INITIALIZE value).  These are:
+ *
+ * base: The start of the Guest-physical memory inside the Launcher memory.
  *
  * pfnlimit: The highest (Guest-physical) page number the Guest should be
  * allowed to access.  The Launcher has to live in Guest memory, so it sets
@@ -153,23 +99,17 @@
  * pagetables (which are set up by the Launcher).
  *
  * start: The first instruction to execute ("eip" in x86-speak).
- *
- * page_offset: The PAGE_OFFSET constant in the Guest kernel.  We should
- * probably wean the code off this, but it's a very useful constant!  Any
- * address above this is within the Guest kernel, and any kernel address can
- * quickly converted from physical to virtual by adding PAGE_OFFSET.  It's
- * 0xC0000000 (3G) by default, but it's configurable at kernel build time.
  */
-static int initialize(struct file *file, const u32 __user *input)
+static int initialize(struct file *file, const unsigned long __user *input)
 {
 	/* "struct lguest" contains everything we (the Host) know about a
 	 * Guest. */
 	struct lguest *lg;
-	int err, i;
-	u32 args[4];
+	int err;
+	unsigned long args[4];
 
-	/* We grab the Big Lguest lock, which protects the global array
-	 * "lguests" and multiple simultaneous initializations. */
+	/* We grab the Big Lguest lock, which protects against multiple
+	 * simultaneous initializations. */
 	mutex_lock(&lguest_lock);
 	/* You can't initialize twice!  Close the device and start again... */
 	if (file->private_data) {
@@ -182,20 +122,15 @@
 		goto unlock;
 	}
 
-	/* Find an unused guest. */
-	i = find_free_guest();
-	if (i < 0) {
-		err = -ENOSPC;
+	lg = kzalloc(sizeof(*lg), GFP_KERNEL);
+	if (!lg) {
+		err = -ENOMEM;
 		goto unlock;
 	}
-	/* OK, we have an index into the "lguest" array: "lg" is a convenient
-	 * pointer. */
-	lg = &lguests[i];
 
 	/* Populate the easy fields of our "struct lguest" */
-	lg->guestid = i;
-	lg->pfn_limit = args[0];
-	lg->page_offset = args[3];
+	lg->mem_base = (void __user *)(long)args[0];
+	lg->pfn_limit = args[1];
 
 	/* We need a complete page for the Guest registers: they are accessible
 	 * to the Guest and we can only grant it access to whole pages. */
@@ -210,17 +145,13 @@
 	/* Initialize the Guest's shadow page tables, using the toplevel
 	 * address the Launcher gave us.  This allocates memory, so can
 	 * fail. */
-	err = init_guest_pagetable(lg, args[1]);
+	err = init_guest_pagetable(lg, args[2]);
 	if (err)
 		goto free_regs;
 
 	/* Now we initialize the Guest's registers, handing it the start
 	 * address. */
-	setup_regs(lg->regs, args[2]);
-
-	/* There are a couple of GDT entries the Guest expects when first
-	 * booting. */
-	setup_guest_gdt(lg);
+	lguest_arch_setup_regs(lg, args[3]);
 
 	/* The timer for lguest's clock needs initialization. */
 	init_clockdev(lg);
@@ -260,18 +191,19 @@
 /*L:010 The first operation the Launcher does must be a write.  All writes
  * start with a 32 bit number: for the first write this must be
  * LHREQ_INITIALIZE to set up the Guest.  After that the Launcher can use
- * writes of other values to get DMA buffers and send interrupts. */
-static ssize_t write(struct file *file, const char __user *input,
+ * writes of other values to send interrupts. */
+static ssize_t write(struct file *file, const char __user *in,
 		     size_t size, loff_t *off)
 {
 	/* Once the guest is initialized, we hold the "struct lguest" in the
 	 * file private data. */
 	struct lguest *lg = file->private_data;
-	u32 req;
+	const unsigned long __user *input = (const unsigned long __user *)in;
+	unsigned long req;
 
 	if (get_user(req, input) != 0)
 		return -EFAULT;
-	input += sizeof(req);
+	input++;
 
 	/* If you haven't initialized, you must do that first. */
 	if (req != LHREQ_INITIALIZE && !lg)
@@ -287,13 +219,11 @@
 
 	switch (req) {
 	case LHREQ_INITIALIZE:
-		return initialize(file, (const u32 __user *)input);
-	case LHREQ_GETDMA:
-		return user_get_dma(lg, (const u32 __user *)input);
+		return initialize(file, input);
 	case LHREQ_IRQ:
-		return user_send_irq(lg, (const u32 __user *)input);
+		return user_send_irq(lg, input);
 	case LHREQ_BREAK:
-		return break_guest_out(lg, (const u32 __user *)input);
+		return break_guest_out(lg, input);
 	default:
 		return -EINVAL;
 	}
@@ -319,8 +249,6 @@
 	mutex_lock(&lguest_lock);
 	/* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */
 	hrtimer_cancel(&lg->hrt);
-	/* Free any DMA buffers the Guest had bound. */
-	release_all_dma(lg);
 	/* Free up the shadow page tables for the Guest. */
 	free_guest_pagetable(lg);
 	/* Now all the memory cleanups are done, it's safe to release the
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index b7a924a..2a45f06 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -13,6 +13,7 @@
 #include <linux/random.h>
 #include <linux/percpu.h>
 #include <asm/tlbflush.h>
+#include <asm/uaccess.h>
 #include "lg.h"
 
 /*M:008 We hold reference to pages, which prevents them from being swapped.
@@ -44,44 +45,32 @@
  *  (vii) Setting up the page tables initially.
  :*/
 
-/* Pages a 4k long, and each page table entry is 4 bytes long, giving us 1024
- * (or 2^10) entries per page. */
-#define PTES_PER_PAGE_SHIFT 10
-#define PTES_PER_PAGE (1 << PTES_PER_PAGE_SHIFT)
 
 /* 1024 entries in a page table page maps 1024 pages: 4MB.  The Switcher is
  * conveniently placed at the top 4MB, so it uses a separate, complete PTE
  * page.  */
-#define SWITCHER_PGD_INDEX (PTES_PER_PAGE - 1)
+#define SWITCHER_PGD_INDEX (PTRS_PER_PGD - 1)
 
 /* We actually need a separate PTE page for each CPU.  Remember that after the
  * Switcher code itself comes two pages for each CPU, and we don't want this
  * CPU's guest to see the pages of any other CPU. */
-static DEFINE_PER_CPU(spte_t *, switcher_pte_pages);
+static DEFINE_PER_CPU(pte_t *, switcher_pte_pages);
 #define switcher_pte_page(cpu) per_cpu(switcher_pte_pages, cpu)
 
 /*H:320 With our shadow and Guest types established, we need to deal with
  * them: the page table code is curly enough to need helper functions to keep
  * it clear and clean.
  *
- * The first helper takes a virtual address, and says which entry in the top
- * level page table deals with that address.  Since each top level entry deals
- * with 4M, this effectively divides by 4M. */
-static unsigned vaddr_to_pgd_index(unsigned long vaddr)
-{
-	return vaddr >> (PAGE_SHIFT + PTES_PER_PAGE_SHIFT);
-}
-
-/* There are two functions which return pointers to the shadow (aka "real")
+ * There are two functions which return pointers to the shadow (aka "real")
  * page tables.
  *
  * spgd_addr() takes the virtual address and returns a pointer to the top-level
  * page directory entry for that address.  Since we keep track of several page
  * tables, the "i" argument tells us which one we're interested in (it's
  * usually the current one). */
-static spgd_t *spgd_addr(struct lguest *lg, u32 i, unsigned long vaddr)
+static pgd_t *spgd_addr(struct lguest *lg, u32 i, unsigned long vaddr)
 {
-	unsigned int index = vaddr_to_pgd_index(vaddr);
+	unsigned int index = pgd_index(vaddr);
 
 	/* We kill any Guest trying to touch the Switcher addresses. */
 	if (index >= SWITCHER_PGD_INDEX) {
@@ -95,28 +84,28 @@
 /* This routine then takes the PGD entry given above, which contains the
  * address of the PTE page.  It then returns a pointer to the PTE entry for the
  * given address. */
-static spte_t *spte_addr(struct lguest *lg, spgd_t spgd, unsigned long vaddr)
+static pte_t *spte_addr(struct lguest *lg, pgd_t spgd, unsigned long vaddr)
 {
-	spte_t *page = __va(spgd.pfn << PAGE_SHIFT);
+	pte_t *page = __va(pgd_pfn(spgd) << PAGE_SHIFT);
 	/* You should never call this if the PGD entry wasn't valid */
-	BUG_ON(!(spgd.flags & _PAGE_PRESENT));
-	return &page[(vaddr >> PAGE_SHIFT) % PTES_PER_PAGE];
+	BUG_ON(!(pgd_flags(spgd) & _PAGE_PRESENT));
+	return &page[(vaddr >> PAGE_SHIFT) % PTRS_PER_PTE];
 }
 
 /* These two functions just like the above two, except they access the Guest
  * page tables.  Hence they return a Guest address. */
 static unsigned long gpgd_addr(struct lguest *lg, unsigned long vaddr)
 {
-	unsigned int index = vaddr >> (PAGE_SHIFT + PTES_PER_PAGE_SHIFT);
-	return lg->pgdirs[lg->pgdidx].cr3 + index * sizeof(gpgd_t);
+	unsigned int index = vaddr >> (PGDIR_SHIFT);
+	return lg->pgdirs[lg->pgdidx].gpgdir + index * sizeof(pgd_t);
 }
 
 static unsigned long gpte_addr(struct lguest *lg,
-			       gpgd_t gpgd, unsigned long vaddr)
+			       pgd_t gpgd, unsigned long vaddr)
 {
-	unsigned long gpage = gpgd.pfn << PAGE_SHIFT;
-	BUG_ON(!(gpgd.flags & _PAGE_PRESENT));
-	return gpage + ((vaddr>>PAGE_SHIFT) % PTES_PER_PAGE) * sizeof(gpte_t);
+	unsigned long gpage = pgd_pfn(gpgd) << PAGE_SHIFT;
+	BUG_ON(!(pgd_flags(gpgd) & _PAGE_PRESENT));
+	return gpage + ((vaddr>>PAGE_SHIFT) % PTRS_PER_PTE) * sizeof(pte_t);
 }
 
 /*H:350 This routine takes a page number given by the Guest and converts it to
@@ -149,53 +138,55 @@
  * entry can be a little tricky.  The flags are (almost) the same, but the
  * Guest PTE contains a virtual page number: the CPU needs the real page
  * number. */
-static spte_t gpte_to_spte(struct lguest *lg, gpte_t gpte, int write)
+static pte_t gpte_to_spte(struct lguest *lg, pte_t gpte, int write)
 {
-	spte_t spte;
-	unsigned long pfn;
+	unsigned long pfn, base, flags;
 
 	/* The Guest sets the global flag, because it thinks that it is using
 	 * PGE.  We only told it to use PGE so it would tell us whether it was
 	 * flushing a kernel mapping or a userspace mapping.  We don't actually
 	 * use the global bit, so throw it away. */
-	spte.flags = (gpte.flags & ~_PAGE_GLOBAL);
+	flags = (pte_flags(gpte) & ~_PAGE_GLOBAL);
+
+	/* The Guest's pages are offset inside the Launcher. */
+	base = (unsigned long)lg->mem_base / PAGE_SIZE;
 
 	/* We need a temporary "unsigned long" variable to hold the answer from
 	 * get_pfn(), because it returns 0xFFFFFFFF on failure, which wouldn't
 	 * fit in spte.pfn.  get_pfn() finds the real physical number of the
 	 * page, given the virtual number. */
-	pfn = get_pfn(gpte.pfn, write);
+	pfn = get_pfn(base + pte_pfn(gpte), write);
 	if (pfn == -1UL) {
-		kill_guest(lg, "failed to get page %u", gpte.pfn);
+		kill_guest(lg, "failed to get page %lu", pte_pfn(gpte));
 		/* When we destroy the Guest, we'll go through the shadow page
 		 * tables and release_pte() them.  Make sure we don't think
 		 * this one is valid! */
-		spte.flags = 0;
+		flags = 0;
 	}
-	/* Now we assign the page number, and our shadow PTE is complete. */
-	spte.pfn = pfn;
-	return spte;
+	/* Now we assemble our shadow PTE from the page number and flags. */
+	return pfn_pte(pfn, __pgprot(flags));
 }
 
 /*H:460 And to complete the chain, release_pte() looks like this: */
-static void release_pte(spte_t pte)
+static void release_pte(pte_t pte)
 {
 	/* Remember that get_user_pages() took a reference to the page, in
 	 * get_pfn()?  We have to put it back now. */
-	if (pte.flags & _PAGE_PRESENT)
-		put_page(pfn_to_page(pte.pfn));
+	if (pte_flags(pte) & _PAGE_PRESENT)
+		put_page(pfn_to_page(pte_pfn(pte)));
 }
 /*:*/
 
-static void check_gpte(struct lguest *lg, gpte_t gpte)
+static void check_gpte(struct lguest *lg, pte_t gpte)
 {
-	if ((gpte.flags & (_PAGE_PWT|_PAGE_PSE)) || gpte.pfn >= lg->pfn_limit)
+	if ((pte_flags(gpte) & (_PAGE_PWT|_PAGE_PSE))
+	    || pte_pfn(gpte) >= lg->pfn_limit)
 		kill_guest(lg, "bad page table entry");
 }
 
-static void check_gpgd(struct lguest *lg, gpgd_t gpgd)
+static void check_gpgd(struct lguest *lg, pgd_t gpgd)
 {
-	if ((gpgd.flags & ~_PAGE_TABLE) || gpgd.pfn >= lg->pfn_limit)
+	if ((pgd_flags(gpgd) & ~_PAGE_TABLE) || pgd_pfn(gpgd) >= lg->pfn_limit)
 		kill_guest(lg, "bad page directory entry");
 }
 
@@ -211,21 +202,21 @@
  * true. */
 int demand_page(struct lguest *lg, unsigned long vaddr, int errcode)
 {
-	gpgd_t gpgd;
-	spgd_t *spgd;
+	pgd_t gpgd;
+	pgd_t *spgd;
 	unsigned long gpte_ptr;
-	gpte_t gpte;
-	spte_t *spte;
+	pte_t gpte;
+	pte_t *spte;
 
 	/* First step: get the top-level Guest page table entry. */
-	gpgd = mkgpgd(lgread_u32(lg, gpgd_addr(lg, vaddr)));
+	gpgd = lgread(lg, gpgd_addr(lg, vaddr), pgd_t);
 	/* Toplevel not present?  We can't map it in. */
-	if (!(gpgd.flags & _PAGE_PRESENT))
+	if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
 		return 0;
 
 	/* Now look at the matching shadow entry. */
 	spgd = spgd_addr(lg, lg->pgdidx, vaddr);
-	if (!(spgd->flags & _PAGE_PRESENT)) {
+	if (!(pgd_flags(*spgd) & _PAGE_PRESENT)) {
 		/* No shadow entry: allocate a new shadow PTE page. */
 		unsigned long ptepage = get_zeroed_page(GFP_KERNEL);
 		/* This is not really the Guest's fault, but killing it is
@@ -238,34 +229,35 @@
 		check_gpgd(lg, gpgd);
 		/* And we copy the flags to the shadow PGD entry.  The page
 		 * number in the shadow PGD is the page we just allocated. */
-		spgd->raw.val = (__pa(ptepage) | gpgd.flags);
+		*spgd = __pgd(__pa(ptepage) | pgd_flags(gpgd));
 	}
 
 	/* OK, now we look at the lower level in the Guest page table: keep its
 	 * address, because we might update it later. */
 	gpte_ptr = gpte_addr(lg, gpgd, vaddr);
-	gpte = mkgpte(lgread_u32(lg, gpte_ptr));
+	gpte = lgread(lg, gpte_ptr, pte_t);
 
 	/* If this page isn't in the Guest page tables, we can't page it in. */
-	if (!(gpte.flags & _PAGE_PRESENT))
+	if (!(pte_flags(gpte) & _PAGE_PRESENT))
 		return 0;
 
 	/* Check they're not trying to write to a page the Guest wants
 	 * read-only (bit 2 of errcode == write). */
-	if ((errcode & 2) && !(gpte.flags & _PAGE_RW))
+	if ((errcode & 2) && !(pte_flags(gpte) & _PAGE_RW))
 		return 0;
 
 	/* User access to a kernel page? (bit 3 == user access) */
-	if ((errcode & 4) && !(gpte.flags & _PAGE_USER))
+	if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER))
 		return 0;
 
 	/* Check that the Guest PTE flags are OK, and the page number is below
 	 * the pfn_limit (ie. not mapping the Launcher binary). */
 	check_gpte(lg, gpte);
 	/* Add the _PAGE_ACCESSED and (for a write) _PAGE_DIRTY flag */
-	gpte.flags |= _PAGE_ACCESSED;
+	gpte = pte_mkyoung(gpte);
+
 	if (errcode & 2)
-		gpte.flags |= _PAGE_DIRTY;
+		gpte = pte_mkdirty(gpte);
 
 	/* Get the pointer to the shadow PTE entry we're going to set. */
 	spte = spte_addr(lg, *spgd, vaddr);
@@ -275,21 +267,18 @@
 
 	/* If this is a write, we insist that the Guest page is writable (the
 	 * final arg to gpte_to_spte()). */
-	if (gpte.flags & _PAGE_DIRTY)
+	if (pte_dirty(gpte))
 		*spte = gpte_to_spte(lg, gpte, 1);
-	else {
+	else
 		/* If this is a read, don't set the "writable" bit in the page
 		 * table entry, even if the Guest says it's writable.  That way
 		 * we come back here when a write does actually ocur, so we can
 		 * update the Guest's _PAGE_DIRTY flag. */
-		gpte_t ro_gpte = gpte;
-		ro_gpte.flags &= ~_PAGE_RW;
-		*spte = gpte_to_spte(lg, ro_gpte, 0);
-	}
+		*spte = gpte_to_spte(lg, pte_wrprotect(gpte), 0);
 
 	/* Finally, we write the Guest PTE entry back: we've set the
 	 * _PAGE_ACCESSED and maybe the _PAGE_DIRTY flags. */
-	lgwrite_u32(lg, gpte_ptr, gpte.raw.val);
+	lgwrite(lg, gpte_ptr, pte_t, gpte);
 
 	/* We succeeded in mapping the page! */
 	return 1;
@@ -305,17 +294,18 @@
  * mapped by the shadow page tables, and is it writable? */
 static int page_writable(struct lguest *lg, unsigned long vaddr)
 {
-	spgd_t *spgd;
+	pgd_t *spgd;
 	unsigned long flags;
 
 	/* Look at the top level entry: is it present? */
 	spgd = spgd_addr(lg, lg->pgdidx, vaddr);
-	if (!(spgd->flags & _PAGE_PRESENT))
+	if (!(pgd_flags(*spgd) & _PAGE_PRESENT))
 		return 0;
 
 	/* Check the flags on the pte entry itself: it must be present and
 	 * writable. */
-	flags = spte_addr(lg, *spgd, vaddr)->flags;
+	flags = pte_flags(*(spte_addr(lg, *spgd, vaddr)));
+
 	return (flags & (_PAGE_PRESENT|_PAGE_RW)) == (_PAGE_PRESENT|_PAGE_RW);
 }
 
@@ -329,22 +319,22 @@
 }
 
 /*H:450 If we chase down the release_pgd() code, it looks like this: */
-static void release_pgd(struct lguest *lg, spgd_t *spgd)
+static void release_pgd(struct lguest *lg, pgd_t *spgd)
 {
 	/* If the entry's not present, there's nothing to release. */
-	if (spgd->flags & _PAGE_PRESENT) {
+	if (pgd_flags(*spgd) & _PAGE_PRESENT) {
 		unsigned int i;
 		/* Converting the pfn to find the actual PTE page is easy: turn
 		 * the page number into a physical address, then convert to a
 		 * virtual address (easy for kernel pages like this one). */
-		spte_t *ptepage = __va(spgd->pfn << PAGE_SHIFT);
+		pte_t *ptepage = __va(pgd_pfn(*spgd) << PAGE_SHIFT);
 		/* For each entry in the page, we might need to release it. */
-		for (i = 0; i < PTES_PER_PAGE; i++)
+		for (i = 0; i < PTRS_PER_PTE; i++)
 			release_pte(ptepage[i]);
 		/* Now we can free the page of PTEs */
 		free_page((long)ptepage);
 		/* And zero out the PGD entry we we never release it twice. */
-		spgd->raw.val = 0;
+		*spgd = __pgd(0);
 	}
 }
 
@@ -356,7 +346,7 @@
 {
 	unsigned int i;
 	/* Release every pgd entry up to the kernel's address. */
-	for (i = 0; i < vaddr_to_pgd_index(lg->page_offset); i++)
+	for (i = 0; i < pgd_index(lg->kernel_address); i++)
 		release_pgd(lg, lg->pgdirs[idx].pgdir + i);
 }
 
@@ -369,6 +359,25 @@
 }
 /*:*/
 
+/* We walk down the guest page tables to get a guest-physical address */
+unsigned long guest_pa(struct lguest *lg, unsigned long vaddr)
+{
+	pgd_t gpgd;
+	pte_t gpte;
+
+	/* First step: get the top-level Guest page table entry. */
+	gpgd = lgread(lg, gpgd_addr(lg, vaddr), pgd_t);
+	/* Toplevel not present?  We can't map it in. */
+	if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
+		kill_guest(lg, "Bad address %#lx", vaddr);
+
+	gpte = lgread(lg, gpte_addr(lg, gpgd, vaddr), pte_t);
+	if (!(pte_flags(gpte) & _PAGE_PRESENT))
+		kill_guest(lg, "Bad address %#lx", vaddr);
+
+	return pte_pfn(gpte) * PAGE_SIZE | (vaddr & ~PAGE_MASK);
+}
+
 /* We keep several page tables.  This is a simple routine to find the page
  * table (if any) corresponding to this top-level address the Guest has given
  * us. */
@@ -376,7 +385,7 @@
 {
 	unsigned int i;
 	for (i = 0; i < ARRAY_SIZE(lg->pgdirs); i++)
-		if (lg->pgdirs[i].cr3 == pgtable)
+		if (lg->pgdirs[i].gpgdir == pgtable)
 			break;
 	return i;
 }
@@ -385,7 +394,7 @@
  * allocate a new one (and so the kernel parts are not there), we set
  * blank_pgdir. */
 static unsigned int new_pgdir(struct lguest *lg,
-			      unsigned long cr3,
+			      unsigned long gpgdir,
 			      int *blank_pgdir)
 {
 	unsigned int next;
@@ -395,7 +404,7 @@
 	next = random32() % ARRAY_SIZE(lg->pgdirs);
 	/* If it's never been allocated at all before, try now. */
 	if (!lg->pgdirs[next].pgdir) {
-		lg->pgdirs[next].pgdir = (spgd_t *)get_zeroed_page(GFP_KERNEL);
+		lg->pgdirs[next].pgdir = (pgd_t *)get_zeroed_page(GFP_KERNEL);
 		/* If the allocation fails, just keep using the one we have */
 		if (!lg->pgdirs[next].pgdir)
 			next = lg->pgdidx;
@@ -405,7 +414,7 @@
 			*blank_pgdir = 1;
 	}
 	/* Record which Guest toplevel this shadows. */
-	lg->pgdirs[next].cr3 = cr3;
+	lg->pgdirs[next].gpgdir = gpgdir;
 	/* Release all the non-kernel mappings. */
 	flush_user_mappings(lg, next);
 
@@ -472,26 +481,27 @@
  * they set _PAGE_DIRTY then we can put a writable PTE entry in immediately.
  */
 static void do_set_pte(struct lguest *lg, int idx,
-		       unsigned long vaddr, gpte_t gpte)
+		       unsigned long vaddr, pte_t gpte)
 {
 	/* Look up the matching shadow page directot entry. */
-	spgd_t *spgd = spgd_addr(lg, idx, vaddr);
+	pgd_t *spgd = spgd_addr(lg, idx, vaddr);
 
 	/* If the top level isn't present, there's no entry to update. */
-	if (spgd->flags & _PAGE_PRESENT) {
+	if (pgd_flags(*spgd) & _PAGE_PRESENT) {
 		/* Otherwise, we start by releasing the existing entry. */
-		spte_t *spte = spte_addr(lg, *spgd, vaddr);
+		pte_t *spte = spte_addr(lg, *spgd, vaddr);
 		release_pte(*spte);
 
 		/* If they're setting this entry as dirty or accessed, we might
 		 * as well put that entry they've given us in now.  This shaves
 		 * 10% off a copy-on-write micro-benchmark. */
-		if (gpte.flags & (_PAGE_DIRTY | _PAGE_ACCESSED)) {
+		if (pte_flags(gpte) & (_PAGE_DIRTY | _PAGE_ACCESSED)) {
 			check_gpte(lg, gpte);
-			*spte = gpte_to_spte(lg, gpte, gpte.flags&_PAGE_DIRTY);
+			*spte = gpte_to_spte(lg, gpte,
+					     pte_flags(gpte) & _PAGE_DIRTY);
 		} else
 			/* Otherwise we can demand_page() it in later. */
-			spte->raw.val = 0;
+			*spte = __pte(0);
 	}
 }
 
@@ -506,18 +516,18 @@
  * The benefit is that when we have to track a new page table, we can copy keep
  * all the kernel mappings.  This speeds up context switch immensely. */
 void guest_set_pte(struct lguest *lg,
-		   unsigned long cr3, unsigned long vaddr, gpte_t gpte)
+		   unsigned long gpgdir, unsigned long vaddr, pte_t gpte)
 {
 	/* Kernel mappings must be changed on all top levels.  Slow, but
 	 * doesn't happen often. */
-	if (vaddr >= lg->page_offset) {
+	if (vaddr >= lg->kernel_address) {
 		unsigned int i;
 		for (i = 0; i < ARRAY_SIZE(lg->pgdirs); i++)
 			if (lg->pgdirs[i].pgdir)
 				do_set_pte(lg, i, vaddr, gpte);
 	} else {
 		/* Is this page table one we have a shadow for? */
-		int pgdir = find_pgdir(lg, cr3);
+		int pgdir = find_pgdir(lg, gpgdir);
 		if (pgdir != ARRAY_SIZE(lg->pgdirs))
 			/* If so, do the update. */
 			do_set_pte(lg, pgdir, vaddr, gpte);
@@ -538,7 +548,7 @@
  *
  * So with that in mind here's our code to to update a (top-level) PGD entry:
  */
-void guest_set_pmd(struct lguest *lg, unsigned long cr3, u32 idx)
+void guest_set_pmd(struct lguest *lg, unsigned long gpgdir, u32 idx)
 {
 	int pgdir;
 
@@ -548,7 +558,7 @@
 		return;
 
 	/* If they're talking about a page table we have a shadow for... */
-	pgdir = find_pgdir(lg, cr3);
+	pgdir = find_pgdir(lg, gpgdir);
 	if (pgdir < ARRAY_SIZE(lg->pgdirs))
 		/* ... throw it away. */
 		release_pgd(lg, lg->pgdirs[pgdir].pgdir + idx);
@@ -560,21 +570,34 @@
  * its first page table is.  We set some things up here: */
 int init_guest_pagetable(struct lguest *lg, unsigned long pgtable)
 {
-	/* In flush_user_mappings() we loop from 0 to
-	 * "vaddr_to_pgd_index(lg->page_offset)".  This assumes it won't hit
-	 * the Switcher mappings, so check that now. */
-	if (vaddr_to_pgd_index(lg->page_offset) >= SWITCHER_PGD_INDEX)
-		return -EINVAL;
 	/* We start on the first shadow page table, and give it a blank PGD
 	 * page. */
 	lg->pgdidx = 0;
-	lg->pgdirs[lg->pgdidx].cr3 = pgtable;
-	lg->pgdirs[lg->pgdidx].pgdir = (spgd_t*)get_zeroed_page(GFP_KERNEL);
+	lg->pgdirs[lg->pgdidx].gpgdir = pgtable;
+	lg->pgdirs[lg->pgdidx].pgdir = (pgd_t*)get_zeroed_page(GFP_KERNEL);
 	if (!lg->pgdirs[lg->pgdidx].pgdir)
 		return -ENOMEM;
 	return 0;
 }
 
+/* When the Guest calls LHCALL_LGUEST_INIT we do more setup. */
+void page_table_guest_data_init(struct lguest *lg)
+{
+	/* We get the kernel address: above this is all kernel memory. */
+	if (get_user(lg->kernel_address, &lg->lguest_data->kernel_address)
+	    /* We tell the Guest that it can't use the top 4MB of virtual
+	     * addresses used by the Switcher. */
+	    || put_user(4U*1024*1024, &lg->lguest_data->reserve_mem)
+	    || put_user(lg->pgdirs[lg->pgdidx].gpgdir,&lg->lguest_data->pgdir))
+		kill_guest(lg, "bad guest page %p", lg->lguest_data);
+
+	/* In flush_user_mappings() we loop from 0 to
+	 * "pgd_index(lg->kernel_address)".  This assumes it won't hit the
+	 * Switcher mappings, so check that now. */
+	if (pgd_index(lg->kernel_address) >= SWITCHER_PGD_INDEX)
+		kill_guest(lg, "bad kernel address %#lx", lg->kernel_address);
+}
+
 /* When a Guest dies, our cleanup is fairly simple. */
 void free_guest_pagetable(struct lguest *lg)
 {
@@ -594,14 +617,14 @@
  * for each CPU already set up, we just need to hook them in. */
 void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages)
 {
-	spte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages);
-	spgd_t switcher_pgd;
-	spte_t regs_pte;
+	pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages);
+	pgd_t switcher_pgd;
+	pte_t regs_pte;
 
 	/* Make the last PGD entry for this Guest point to the Switcher's PTE
 	 * page for this CPU (with appropriate flags). */
-	switcher_pgd.pfn = __pa(switcher_pte_page) >> PAGE_SHIFT;
-	switcher_pgd.flags = _PAGE_KERNEL;
+	switcher_pgd = __pgd(__pa(switcher_pte_page) | _PAGE_KERNEL);
+
 	lg->pgdirs[lg->pgdidx].pgdir[SWITCHER_PGD_INDEX] = switcher_pgd;
 
 	/* We also change the Switcher PTE page.  When we're running the Guest,
@@ -611,10 +634,8 @@
 	 * CPU's "struct lguest_pages": if we make sure the Guest's register
 	 * page is already mapped there, we don't have to copy them out
 	 * again. */
-	regs_pte.pfn = __pa(lg->regs_page) >> PAGE_SHIFT;
-	regs_pte.flags = _PAGE_KERNEL;
-	switcher_pte_page[(unsigned long)pages/PAGE_SIZE%PTES_PER_PAGE]
-		= regs_pte;
+	regs_pte = pfn_pte (__pa(lg->regs_page) >> PAGE_SHIFT, __pgprot(_PAGE_KERNEL));
+	switcher_pte_page[(unsigned long)pages/PAGE_SIZE%PTRS_PER_PTE] = regs_pte;
 }
 /*:*/
 
@@ -635,24 +656,25 @@
 					      unsigned int pages)
 {
 	unsigned int i;
-	spte_t *pte = switcher_pte_page(cpu);
+	pte_t *pte = switcher_pte_page(cpu);
 
 	/* The first entries are easy: they map the Switcher code. */
 	for (i = 0; i < pages; i++) {
-		pte[i].pfn = page_to_pfn(switcher_page[i]);
-		pte[i].flags = _PAGE_PRESENT|_PAGE_ACCESSED;
+		pte[i] = mk_pte(switcher_page[i],
+				__pgprot(_PAGE_PRESENT|_PAGE_ACCESSED));
 	}
 
 	/* The only other thing we map is this CPU's pair of pages. */
 	i = pages + cpu*2;
 
 	/* First page (Guest registers) is writable from the Guest */
-	pte[i].pfn = page_to_pfn(switcher_page[i]);
-	pte[i].flags = _PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_RW;
+	pte[i] = pfn_pte(page_to_pfn(switcher_page[i]),
+			 __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_RW));
+
 	/* The second page contains the "struct lguest_ro_state", and is
 	 * read-only. */
-	pte[i+1].pfn = page_to_pfn(switcher_page[i+1]);
-	pte[i+1].flags = _PAGE_PRESENT|_PAGE_ACCESSED;
+	pte[i+1] = pfn_pte(page_to_pfn(switcher_page[i+1]),
+			   __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED));
 }
 
 /*H:510 At boot or module load time, init_pagetables() allocates and populates
@@ -662,7 +684,7 @@
 	unsigned int i;
 
 	for_each_possible_cpu(i) {
-		switcher_pte_page(i) = (spte_t *)get_zeroed_page(GFP_KERNEL);
+		switcher_pte_page(i) = (pte_t *)get_zeroed_page(GFP_KERNEL);
 		if (!switcher_pte_page(i)) {
 			free_switcher_pte_pages();
 			return -ENOMEM;
diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c
index 9b81119..c2434ec 100644
--- a/drivers/lguest/segments.c
+++ b/drivers/lguest/segments.c
@@ -73,14 +73,14 @@
 		/* Segment descriptors contain a privilege level: the Guest is
 		 * sometimes careless and leaves this as 0, even though it's
 		 * running at privilege level 1.  If so, we fix it here. */
-		if ((lg->gdt[i].b & 0x00006000) == 0)
-			lg->gdt[i].b |= (GUEST_PL << 13);
+		if ((lg->arch.gdt[i].b & 0x00006000) == 0)
+			lg->arch.gdt[i].b |= (GUEST_PL << 13);
 
 		/* Each descriptor has an "accessed" bit.  If we don't set it
 		 * now, the CPU will try to set it when the Guest first loads
 		 * that entry into a segment register.  But the GDT isn't
 		 * writable by the Guest, so bad things can happen. */
-		lg->gdt[i].b |= 0x00000100;
+		lg->arch.gdt[i].b |= 0x00000100;
 	}
 }
 
@@ -106,12 +106,12 @@
 void setup_guest_gdt(struct lguest *lg)
 {
 	/* Start with full 0-4G segments... */
-	lg->gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT;
-	lg->gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT;
+	lg->arch.gdt[GDT_ENTRY_KERNEL_CS] = FULL_EXEC_SEGMENT;
+	lg->arch.gdt[GDT_ENTRY_KERNEL_DS] = FULL_SEGMENT;
 	/* ...except the Guest is allowed to use them, so set the privilege
 	 * level appropriately in the flags. */
-	lg->gdt[GDT_ENTRY_KERNEL_CS].b |= (GUEST_PL << 13);
-	lg->gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13);
+	lg->arch.gdt[GDT_ENTRY_KERNEL_CS].b |= (GUEST_PL << 13);
+	lg->arch.gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13);
 }
 
 /* Like the IDT, we never simply use the GDT the Guest gives us.  We set up the
@@ -126,7 +126,7 @@
 	unsigned int i;
 
 	for (i = GDT_ENTRY_TLS_MIN; i <= GDT_ENTRY_TLS_MAX; i++)
-		gdt[i] = lg->gdt[i];
+		gdt[i] = lg->arch.gdt[i];
 }
 
 /* This is the full version */
@@ -138,7 +138,7 @@
 	 * replaced.  See ignored_gdt() above. */
 	for (i = 0; i < GDT_ENTRIES; i++)
 		if (!ignored_gdt(i))
-			gdt[i] = lg->gdt[i];
+			gdt[i] = lg->arch.gdt[i];
 }
 
 /* This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT). */
@@ -146,12 +146,12 @@
 {
 	/* We assume the Guest has the same number of GDT entries as the
 	 * Host, otherwise we'd have to dynamically allocate the Guest GDT. */
-	if (num > ARRAY_SIZE(lg->gdt))
+	if (num > ARRAY_SIZE(lg->arch.gdt))
 		kill_guest(lg, "too many gdt entries %i", num);
 
 	/* We read the whole thing in, then fix it up. */
-	lgread(lg, lg->gdt, table, num * sizeof(lg->gdt[0]));
-	fixup_gdt_table(lg, 0, ARRAY_SIZE(lg->gdt));
+	__lgread(lg, lg->arch.gdt, table, num * sizeof(lg->arch.gdt[0]));
+	fixup_gdt_table(lg, 0, ARRAY_SIZE(lg->arch.gdt));
 	/* Mark that the GDT changed so the core knows it has to copy it again,
 	 * even if the Guest is run on the same CPU. */
 	lg->changed |= CHANGED_GDT;
@@ -159,9 +159,9 @@
 
 void guest_load_tls(struct lguest *lg, unsigned long gtls)
 {
-	struct desc_struct *tls = &lg->gdt[GDT_ENTRY_TLS_MIN];
+	struct desc_struct *tls = &lg->arch.gdt[GDT_ENTRY_TLS_MIN];
 
-	lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES);
+	__lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES);
 	fixup_gdt_table(lg, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1);
 	lg->changed |= CHANGED_GDT_TLS;
 }
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
new file mode 100644
index 0000000..9eed12d
--- /dev/null
+++ b/drivers/lguest/x86/core.c
@@ -0,0 +1,577 @@
+/*
+ * Copyright (C) 2006, Rusty Russell <rusty@rustcorp.com.au> IBM Corporation.
+ * Copyright (C) 2007, Jes Sorensen <jes@sgi.com> SGI.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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/kernel.h>
+#include <linux/start_kernel.h>
+#include <linux/string.h>
+#include <linux/console.h>
+#include <linux/screen_info.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/cpu.h>
+#include <linux/lguest.h>
+#include <linux/lguest_launcher.h>
+#include <asm/paravirt.h>
+#include <asm/param.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/desc.h>
+#include <asm/setup.h>
+#include <asm/lguest.h>
+#include <asm/uaccess.h>
+#include <asm/i387.h>
+#include "../lg.h"
+
+static int cpu_had_pge;
+
+static struct {
+	unsigned long offset;
+	unsigned short segment;
+} lguest_entry;
+
+/* Offset from where switcher.S was compiled to where we've copied it */
+static unsigned long switcher_offset(void)
+{
+	return SWITCHER_ADDR - (unsigned long)start_switcher_text;
+}
+
+/* This cpu's struct lguest_pages. */
+static struct lguest_pages *lguest_pages(unsigned int cpu)
+{
+	return &(((struct lguest_pages *)
+		  (SWITCHER_ADDR + SHARED_SWITCHER_PAGES*PAGE_SIZE))[cpu]);
+}
+
+static DEFINE_PER_CPU(struct lguest *, last_guest);
+
+/*S:010
+ * We are getting close to the Switcher.
+ *
+ * Remember that each CPU has two pages which are visible to the Guest when it
+ * runs on that CPU.  This has to contain the state for that Guest: we copy the
+ * state in just before we run the Guest.
+ *
+ * Each Guest has "changed" flags which indicate what has changed in the Guest
+ * since it last ran.  We saw this set in interrupts_and_traps.c and
+ * segments.c.
+ */
+static void copy_in_guest_info(struct lguest *lg, struct lguest_pages *pages)
+{
+	/* Copying all this data can be quite expensive.  We usually run the
+	 * same Guest we ran last time (and that Guest hasn't run anywhere else
+	 * meanwhile).  If that's not the case, we pretend everything in the
+	 * Guest has changed. */
+	if (__get_cpu_var(last_guest) != lg || lg->last_pages != pages) {
+		__get_cpu_var(last_guest) = lg;
+		lg->last_pages = pages;
+		lg->changed = CHANGED_ALL;
+	}
+
+	/* These copies are pretty cheap, so we do them unconditionally: */
+	/* Save the current Host top-level page directory. */
+	pages->state.host_cr3 = __pa(current->mm->pgd);
+	/* Set up the Guest's page tables to see this CPU's pages (and no
+	 * other CPU's pages). */
+	map_switcher_in_guest(lg, pages);
+	/* Set up the two "TSS" members which tell the CPU what stack to use
+	 * for traps which do directly into the Guest (ie. traps at privilege
+	 * level 1). */
+	pages->state.guest_tss.esp1 = lg->esp1;
+	pages->state.guest_tss.ss1 = lg->ss1;
+
+	/* Copy direct-to-Guest trap entries. */
+	if (lg->changed & CHANGED_IDT)
+		copy_traps(lg, pages->state.guest_idt, default_idt_entries);
+
+	/* Copy all GDT entries which the Guest can change. */
+	if (lg->changed & CHANGED_GDT)
+		copy_gdt(lg, pages->state.guest_gdt);
+	/* If only the TLS entries have changed, copy them. */
+	else if (lg->changed & CHANGED_GDT_TLS)
+		copy_gdt_tls(lg, pages->state.guest_gdt);
+
+	/* Mark the Guest as unchanged for next time. */
+	lg->changed = 0;
+}
+
+/* Finally: the code to actually call into the Switcher to run the Guest. */
+static void run_guest_once(struct lguest *lg, struct lguest_pages *pages)
+{
+	/* This is a dummy value we need for GCC's sake. */
+	unsigned int clobber;
+
+	/* Copy the guest-specific information into this CPU's "struct
+	 * lguest_pages". */
+	copy_in_guest_info(lg, pages);
+
+	/* Set the trap number to 256 (impossible value).  If we fault while
+	 * switching to the Guest (bad segment registers or bug), this will
+	 * cause us to abort the Guest. */
+	lg->regs->trapnum = 256;
+
+	/* Now: we push the "eflags" register on the stack, then do an "lcall".
+	 * This is how we change from using the kernel code segment to using
+	 * the dedicated lguest code segment, as well as jumping into the
+	 * Switcher.
+	 *
+	 * The lcall also pushes the old code segment (KERNEL_CS) onto the
+	 * stack, then the address of this call.  This stack layout happens to
+	 * exactly match the stack of an interrupt... */
+	asm volatile("pushf; lcall *lguest_entry"
+		     /* This is how we tell GCC that %eax ("a") and %ebx ("b")
+		      * are changed by this routine.  The "=" means output. */
+		     : "=a"(clobber), "=b"(clobber)
+		     /* %eax contains the pages pointer.  ("0" refers to the
+		      * 0-th argument above, ie "a").  %ebx contains the
+		      * physical address of the Guest's top-level page
+		      * directory. */
+		     : "0"(pages), "1"(__pa(lg->pgdirs[lg->pgdidx].pgdir))
+		     /* We tell gcc that all these registers could change,
+		      * which means we don't have to save and restore them in
+		      * the Switcher. */
+		     : "memory", "%edx", "%ecx", "%edi", "%esi");
+}
+/*:*/
+
+/*H:040 This is the i386-specific code to setup and run the Guest.  Interrupts
+ * are disabled: we own the CPU. */
+void lguest_arch_run_guest(struct lguest *lg)
+{
+	/* Remember the awfully-named TS bit?  If the Guest has asked
+	 * to set it we set it now, so we can trap and pass that trap
+	 * to the Guest if it uses the FPU. */
+	if (lg->ts)
+		lguest_set_ts();
+
+	/* SYSENTER is an optimized way of doing system calls.  We
+	 * can't allow it because it always jumps to privilege level 0.
+	 * A normal Guest won't try it because we don't advertise it in
+	 * CPUID, but a malicious Guest (or malicious Guest userspace
+	 * program) could, so we tell the CPU to disable it before
+	 * running the Guest. */
+	if (boot_cpu_has(X86_FEATURE_SEP))
+		wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);
+
+	/* Now we actually run the Guest.  It will pop back out when
+	 * something interesting happens, and we can examine its
+	 * registers to see what it was doing. */
+	run_guest_once(lg, lguest_pages(raw_smp_processor_id()));
+
+	/* The "regs" pointer contains two extra entries which are not
+	 * really registers: a trap number which says what interrupt or
+	 * trap made the switcher code come back, and an error code
+	 * which some traps set.  */
+
+	/* If the Guest page faulted, then the cr2 register will tell
+	 * us the bad virtual address.  We have to grab this now,
+	 * because once we re-enable interrupts an interrupt could
+	 * fault and thus overwrite cr2, or we could even move off to a
+	 * different CPU. */
+	if (lg->regs->trapnum == 14)
+		lg->arch.last_pagefault = read_cr2();
+	/* Similarly, if we took a trap because the Guest used the FPU,
+	 * we have to restore the FPU it expects to see. */
+	else if (lg->regs->trapnum == 7)
+		math_state_restore();
+
+	/* Restore SYSENTER if it's supposed to be on. */
+	if (boot_cpu_has(X86_FEATURE_SEP))
+		wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
+}
+
+/*H:130 Our Guest is usually so well behaved; it never tries to do things it
+ * isn't allowed to.  Unfortunately, Linux's paravirtual infrastructure isn't
+ * quite complete, because it doesn't contain replacements for the Intel I/O
+ * instructions.  As a result, the Guest sometimes fumbles across one during
+ * the boot process as it probes for various things which are usually attached
+ * to a PC.
+ *
+ * When the Guest uses one of these instructions, we get trap #13 (General
+ * Protection Fault) and come here.  We see if it's one of those troublesome
+ * instructions and skip over it.  We return true if we did. */
+static int emulate_insn(struct lguest *lg)
+{
+	u8 insn;
+	unsigned int insnlen = 0, in = 0, shift = 0;
+	/* The eip contains the *virtual* address of the Guest's instruction:
+	 * guest_pa just subtracts the Guest's page_offset. */
+	unsigned long physaddr = guest_pa(lg, lg->regs->eip);
+
+	/* This must be the Guest kernel trying to do something, not userspace!
+	 * The bottom two bits of the CS segment register are the privilege
+	 * level. */
+	if ((lg->regs->cs & 3) != GUEST_PL)
+		return 0;
+
+	/* Decoding x86 instructions is icky. */
+	insn = lgread(lg, physaddr, u8);
+
+	/* 0x66 is an "operand prefix".  It means it's using the upper 16 bits
+	   of the eax register. */
+	if (insn == 0x66) {
+		shift = 16;
+		/* The instruction is 1 byte so far, read the next byte. */
+		insnlen = 1;
+		insn = lgread(lg, physaddr + insnlen, u8);
+	}
+
+	/* We can ignore the lower bit for the moment and decode the 4 opcodes
+	 * we need to emulate. */
+	switch (insn & 0xFE) {
+	case 0xE4: /* in     <next byte>,%al */
+		insnlen += 2;
+		in = 1;
+		break;
+	case 0xEC: /* in     (%dx),%al */
+		insnlen += 1;
+		in = 1;
+		break;
+	case 0xE6: /* out    %al,<next byte> */
+		insnlen += 2;
+		break;
+	case 0xEE: /* out    %al,(%dx) */
+		insnlen += 1;
+		break;
+	default:
+		/* OK, we don't know what this is, can't emulate. */
+		return 0;
+	}
+
+	/* If it was an "IN" instruction, they expect the result to be read
+	 * into %eax, so we change %eax.  We always return all-ones, which
+	 * traditionally means "there's nothing there". */
+	if (in) {
+		/* Lower bit tells is whether it's a 16 or 32 bit access */
+		if (insn & 0x1)
+			lg->regs->eax = 0xFFFFFFFF;
+		else
+			lg->regs->eax |= (0xFFFF << shift);
+	}
+	/* Finally, we've "done" the instruction, so move past it. */
+	lg->regs->eip += insnlen;
+	/* Success! */
+	return 1;
+}
+
+/*H:050 Once we've re-enabled interrupts, we look at why the Guest exited. */
+void lguest_arch_handle_trap(struct lguest *lg)
+{
+	switch (lg->regs->trapnum) {
+	case 13: /* We've intercepted a GPF. */
+		 /* Check if this was one of those annoying IN or OUT
+		  * instructions which we need to emulate.  If so, we
+		  * just go back into the Guest after we've done it. */
+		if (lg->regs->errcode == 0) {
+			if (emulate_insn(lg))
+				return;
+		}
+		break;
+	case 14: /* We've intercepted a page fault. */
+		 /* The Guest accessed a virtual address that wasn't
+		  * mapped.  This happens a lot: we don't actually set
+		  * up most of the page tables for the Guest at all when
+		  * we start: as it runs it asks for more and more, and
+		  * we set them up as required. In this case, we don't
+		  * even tell the Guest that the fault happened.
+		  *
+		  * The errcode tells whether this was a read or a
+		  * write, and whether kernel or userspace code. */
+		if (demand_page(lg, lg->arch.last_pagefault, lg->regs->errcode))
+			return;
+
+		 /* OK, it's really not there (or not OK): the Guest
+		  * needs to know.  We write out the cr2 value so it
+		  * knows where the fault occurred.
+		  *
+		  * Note that if the Guest were really messed up, this
+		  * could happen before it's done the INITIALIZE
+		  * hypercall, so lg->lguest_data will be NULL */
+		if (lg->lguest_data &&
+		    put_user(lg->arch.last_pagefault, &lg->lguest_data->cr2))
+			kill_guest(lg, "Writing cr2");
+		break;
+	case 7: /* We've intercepted a Device Not Available fault. */
+		/* If the Guest doesn't want to know, we already
+		 * restored the Floating Point Unit, so we just
+		 * continue without telling it. */
+		if (!lg->ts)
+			return;
+		break;
+	case 32 ... 255:
+		/* These values mean a real interrupt occurred, in which case
+		 * the Host handler has already been run.  We just do a
+		 * friendly check if another process should now be run, then
+		 * return to run the Guest again */
+		cond_resched();
+		return;
+	case LGUEST_TRAP_ENTRY:
+		/* Our 'struct hcall_args' maps directly over our regs: we set
+		 * up the pointer now to indicate a hypercall is pending. */
+		lg->hcall = (struct hcall_args *)lg->regs;
+		return;
+	}
+
+	/* We didn't handle the trap, so it needs to go to the Guest. */
+	if (!deliver_trap(lg, lg->regs->trapnum))
+		/* If the Guest doesn't have a handler (either it hasn't
+		 * registered any yet, or it's one of the faults we don't let
+		 * it handle), it dies with a cryptic error message. */
+		kill_guest(lg, "unhandled trap %li at %#lx (%#lx)",
+			   lg->regs->trapnum, lg->regs->eip,
+			   lg->regs->trapnum == 14 ? lg->arch.last_pagefault
+			   : lg->regs->errcode);
+}
+
+/* Now we can look at each of the routines this calls, in increasing order of
+ * complexity: do_hypercalls(), emulate_insn(), maybe_do_interrupt(),
+ * deliver_trap() and demand_page().  After all those, we'll be ready to
+ * examine the Switcher, and our philosophical understanding of the Host/Guest
+ * duality will be complete. :*/
+static void adjust_pge(void *on)
+{
+	if (on)
+		write_cr4(read_cr4() | X86_CR4_PGE);
+	else
+		write_cr4(read_cr4() & ~X86_CR4_PGE);
+}
+
+/*H:020 Now the Switcher is mapped and every thing else is ready, we need to do
+ * some more i386-specific initialization. */
+void __init lguest_arch_host_init(void)
+{
+	int i;
+
+	/* Most of the i386/switcher.S doesn't care that it's been moved; on
+	 * Intel, jumps are relative, and it doesn't access any references to
+	 * external code or data.
+	 *
+	 * The only exception is the interrupt handlers in switcher.S: their
+	 * addresses are placed in a table (default_idt_entries), so we need to
+	 * update the table with the new addresses.  switcher_offset() is a
+	 * convenience function which returns the distance between the builtin
+	 * switcher code and the high-mapped copy we just made. */
+	for (i = 0; i < IDT_ENTRIES; i++)
+		default_idt_entries[i] += switcher_offset();
+
+	/*
+	 * Set up the Switcher's per-cpu areas.
+	 *
+	 * Each CPU gets two pages of its own within the high-mapped region
+	 * (aka. "struct lguest_pages").  Much of this can be initialized now,
+	 * but some depends on what Guest we are running (which is set up in
+	 * copy_in_guest_info()).
+	 */
+	for_each_possible_cpu(i) {
+		/* lguest_pages() returns this CPU's two pages. */
+		struct lguest_pages *pages = lguest_pages(i);
+		/* This is a convenience pointer to make the code fit one
+		 * statement to a line. */
+		struct lguest_ro_state *state = &pages->state;
+
+		/* The Global Descriptor Table: the Host has a different one
+		 * for each CPU.  We keep a descriptor for the GDT which says
+		 * where it is and how big it is (the size is actually the last
+		 * byte, not the size, hence the "-1"). */
+		state->host_gdt_desc.size = GDT_SIZE-1;
+		state->host_gdt_desc.address = (long)get_cpu_gdt_table(i);
+
+		/* All CPUs on the Host use the same Interrupt Descriptor
+		 * Table, so we just use store_idt(), which gets this CPU's IDT
+		 * descriptor. */
+		store_idt(&state->host_idt_desc);
+
+		/* The descriptors for the Guest's GDT and IDT can be filled
+		 * out now, too.  We copy the GDT & IDT into ->guest_gdt and
+		 * ->guest_idt before actually running the Guest. */
+		state->guest_idt_desc.size = sizeof(state->guest_idt)-1;
+		state->guest_idt_desc.address = (long)&state->guest_idt;
+		state->guest_gdt_desc.size = sizeof(state->guest_gdt)-1;
+		state->guest_gdt_desc.address = (long)&state->guest_gdt;
+
+		/* We know where we want the stack to be when the Guest enters
+		 * the switcher: in pages->regs.  The stack grows upwards, so
+		 * we start it at the end of that structure. */
+		state->guest_tss.esp0 = (long)(&pages->regs + 1);
+		/* And this is the GDT entry to use for the stack: we keep a
+		 * couple of special LGUEST entries. */
+		state->guest_tss.ss0 = LGUEST_DS;
+
+		/* x86 can have a finegrained bitmap which indicates what I/O
+		 * ports the process can use.  We set it to the end of our
+		 * structure, meaning "none". */
+		state->guest_tss.io_bitmap_base = sizeof(state->guest_tss);
+
+		/* Some GDT entries are the same across all Guests, so we can
+		 * set them up now. */
+		setup_default_gdt_entries(state);
+		/* Most IDT entries are the same for all Guests, too.*/
+		setup_default_idt_entries(state, default_idt_entries);
+
+		/* The Host needs to be able to use the LGUEST segments on this
+		 * CPU, too, so put them in the Host GDT. */
+		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
+		get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
+	}
+
+	/* In the Switcher, we want the %cs segment register to use the
+	 * LGUEST_CS GDT entry: we've put that in the Host and Guest GDTs, so
+	 * it will be undisturbed when we switch.  To change %cs and jump we
+	 * need this structure to feed to Intel's "lcall" instruction. */
+	lguest_entry.offset = (long)switch_to_guest + switcher_offset();
+	lguest_entry.segment = LGUEST_CS;
+
+	/* Finally, we need to turn off "Page Global Enable".  PGE is an
+	 * optimization where page table entries are specially marked to show
+	 * they never change.  The Host kernel marks all the kernel pages this
+	 * way because it's always present, even when userspace is running.
+	 *
+	 * Lguest breaks this: unbeknownst to the rest of the Host kernel, we
+	 * switch to the Guest kernel.  If you don't disable this on all CPUs,
+	 * you'll get really weird bugs that you'll chase for two days.
+	 *
+	 * I used to turn PGE off every time we switched to the Guest and back
+	 * on when we return, but that slowed the Switcher down noticibly. */
+
+	/* We don't need the complexity of CPUs coming and going while we're
+	 * doing this. */
+	lock_cpu_hotplug();
+	if (cpu_has_pge) { /* We have a broader idea of "global". */
+		/* Remember that this was originally set (for cleanup). */
+		cpu_had_pge = 1;
+		/* adjust_pge is a helper function which sets or unsets the PGE
+		 * bit on its CPU, depending on the argument (0 == unset). */
+		on_each_cpu(adjust_pge, (void *)0, 0, 1);
+		/* Turn off the feature in the global feature set. */
+		clear_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
+	}
+	unlock_cpu_hotplug();
+};
+/*:*/
+
+void __exit lguest_arch_host_fini(void)
+{
+	/* If we had PGE before we started, turn it back on now. */
+	lock_cpu_hotplug();
+	if (cpu_had_pge) {
+		set_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
+		/* adjust_pge's argument "1" means set PGE. */
+		on_each_cpu(adjust_pge, (void *)1, 0, 1);
+	}
+	unlock_cpu_hotplug();
+}
+
+
+/*H:122 The i386-specific hypercalls simply farm out to the right functions. */
+int lguest_arch_do_hcall(struct lguest *lg, struct hcall_args *args)
+{
+	switch (args->arg0) {
+	case LHCALL_LOAD_GDT:
+		load_guest_gdt(lg, args->arg1, args->arg2);
+		break;
+	case LHCALL_LOAD_IDT_ENTRY:
+		load_guest_idt_entry(lg, args->arg1, args->arg2, args->arg3);
+		break;
+	case LHCALL_LOAD_TLS:
+		guest_load_tls(lg, args->arg1);
+		break;
+	default:
+		/* Bad Guest.  Bad! */
+		return -EIO;
+	}
+	return 0;
+}
+
+/*H:126 i386-specific hypercall initialization: */
+int lguest_arch_init_hypercalls(struct lguest *lg)
+{
+	u32 tsc_speed;
+
+	/* The pointer to the Guest's "struct lguest_data" is the only
+	 * argument.  We check that address now. */
+	if (!lguest_address_ok(lg, lg->hcall->arg1, sizeof(*lg->lguest_data)))
+		return -EFAULT;
+
+	/* Having checked it, we simply set lg->lguest_data to point straight
+	 * into the Launcher's memory at the right place and then use
+	 * copy_to_user/from_user from now on, instead of lgread/write.  I put
+	 * this in to show that I'm not immune to writing stupid
+	 * optimizations. */
+	lg->lguest_data = lg->mem_base + lg->hcall->arg1;
+
+	/* We insist that the Time Stamp Counter exist and doesn't change with
+	 * cpu frequency.  Some devious chip manufacturers decided that TSC
+	 * changes could be handled in software.  I decided that time going
+	 * backwards might be good for benchmarks, but it's bad for users.
+	 *
+	 * We also insist that the TSC be stable: the kernel detects unreliable
+	 * TSCs for its own purposes, and we use that here. */
+	if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && !check_tsc_unstable())
+		tsc_speed = tsc_khz;
+	else
+		tsc_speed = 0;
+	if (put_user(tsc_speed, &lg->lguest_data->tsc_khz))
+		return -EFAULT;
+
+	/* The interrupt code might not like the system call vector. */
+	if (!check_syscall_vector(lg))
+		kill_guest(lg, "bad syscall vector");
+
+	return 0;
+}
+/* Now we've examined the hypercall code; our Guest can make requests.  There
+ * is one other way we can do things for the Guest, as we see in
+ * emulate_insn(). :*/
+
+/*L:030 lguest_arch_setup_regs()
+ *
+ * Most of the Guest's registers are left alone: we used get_zeroed_page() to
+ * allocate the structure, so they will be 0. */
+void lguest_arch_setup_regs(struct lguest *lg, unsigned long start)
+{
+	struct lguest_regs *regs = lg->regs;
+
+	/* There are four "segment" registers which the Guest needs to boot:
+	 * The "code segment" register (cs) refers to the kernel code segment
+	 * __KERNEL_CS, and the "data", "extra" and "stack" segment registers
+	 * refer to the kernel data segment __KERNEL_DS.
+	 *
+	 * The privilege level is packed into the lower bits.  The Guest runs
+	 * at privilege level 1 (GUEST_PL).*/
+	regs->ds = regs->es = regs->ss = __KERNEL_DS|GUEST_PL;
+	regs->cs = __KERNEL_CS|GUEST_PL;
+
+	/* The "eflags" register contains miscellaneous flags.  Bit 1 (0x002)
+	 * is supposed to always be "1".  Bit 9 (0x200) controls whether
+	 * interrupts are enabled.  We always leave interrupts enabled while
+	 * running the Guest. */
+	regs->eflags = 0x202;
+
+	/* The "Extended Instruction Pointer" register says where the Guest is
+	 * running. */
+	regs->eip = start;
+
+	/* %esi points to our boot information, at physical address 0, so don't
+	 * touch it. */
+	/* There are a couple of GDT entries the Guest expects when first
+	 * booting. */
+
+	setup_guest_gdt(lg);
+}
diff --git a/drivers/lguest/switcher.S b/drivers/lguest/x86/switcher_32.S
similarity index 98%
rename from drivers/lguest/switcher.S
rename to drivers/lguest/x86/switcher_32.S
index 7c9c230..1010b90 100644
--- a/drivers/lguest/switcher.S
+++ b/drivers/lguest/x86/switcher_32.S
@@ -48,7 +48,8 @@
 #include <linux/linkage.h>
 #include <asm/asm-offsets.h>
 #include <asm/page.h>
-#include "lg.h"
+#include <asm/segment.h>
+#include <asm/lguest.h>
 
 // We mark the start of the code to copy
 // It's placed in .text tho it's never run here
@@ -132,6 +133,7 @@
 	// The Guest's register page has been mapped
 	// Writable onto our %esp (stack) --
 	// We can simply pop off all Guest regs.
+	popl	%eax
 	popl	%ebx
 	popl	%ecx
 	popl	%edx
@@ -139,7 +141,6 @@
 	popl	%edi
 	popl	%ebp
 	popl	%gs
-	popl	%eax
 	popl	%fs
 	popl	%ds
 	popl	%es
@@ -167,7 +168,6 @@
 	pushl	%es;							\
 	pushl	%ds;							\
 	pushl	%fs;							\
-	pushl	%eax;							\
 	pushl	%gs;							\
 	pushl	%ebp;							\
 	pushl	%edi;							\
@@ -175,6 +175,7 @@
 	pushl	%edx;							\
 	pushl	%ecx;							\
 	pushl	%ebx;							\
+	pushl	%eax;							\
 	/* Our stack and our code are using segments			\
 	 * Set in the TSS and IDT					\
 	 * Yet if we were to touch data we'd use			\
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index 2766e4f..883da72 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -791,8 +791,10 @@
 			if (hid->keycode[i])
 				set_bit(hid->keycode[i], input_dev->keybit);
 
-		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
-		input_dev->ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML);
+		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
+			BIT_MASK(EV_REP);
+		input_dev->ledbit[0] = BIT_MASK(LED_SCROLLL) |
+			BIT_MASK(LED_CAPSL) | BIT_MASK(LED_NUML);
 		input_dev->event = adbhid_kbd_event;
 		input_dev->keycodemax = KEY_FN;
 		input_dev->keycodesize = sizeof(hid->keycode[0]);
@@ -801,16 +803,18 @@
 	case ADB_MOUSE:
 		sprintf(hid->name, "ADB mouse");
 
-		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-		input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-		input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+		input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+			BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+		input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 		break;
 
 	case ADB_MISC:
 		switch (original_handler_id) {
 		case 0x02: /* Adjustable keyboard button device */
 			sprintf(hid->name, "ADB adjustable keyboard buttons");
-			input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+			input_dev->evbit[0] = BIT_MASK(EV_KEY) |
+				BIT_MASK(EV_REP);
 			set_bit(KEY_SOUND, input_dev->keybit);
 			set_bit(KEY_MUTE, input_dev->keybit);
 			set_bit(KEY_VOLUMEUP, input_dev->keybit);
@@ -818,7 +822,8 @@
 			break;
 		case 0x1f: /* Powerbook button device */
 			sprintf(hid->name, "ADB Powerbook buttons");
-			input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+			input_dev->evbit[0] = BIT_MASK(EV_KEY) |
+				BIT_MASK(EV_REP);
 			set_bit(KEY_MUTE, input_dev->keybit);
 			set_bit(KEY_VOLUMEUP, input_dev->keybit);
 			set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index 33dee3a..8930230 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -117,9 +117,10 @@
 	emumousebtn->id.product = 0x0001;
 	emumousebtn->id.version = 0x0100;
 
-	emumousebtn->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	emumousebtn->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-	emumousebtn->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	emumousebtn->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	emumousebtn->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+	emumousebtn->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 
 	ret = input_register_device(emumousebtn);
 	if (ret)
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index c803d2b..48d647a 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -563,7 +563,7 @@
 				ide_init_hwif_ports(&hw, (unsigned long) bay->cd_base, (unsigned long) 0, NULL);
 				hw.irq = bay->cd_irq;
 				hw.chipset = ide_pmac;
-				bay->cd_index = ide_register_hw(&hw, 0, NULL);
+				bay->cd_index = ide_register_hw(&hw, NULL, 0, NULL);
 				pmu_resume();
 			}
 			if (bay->cd_index == -1) {
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index f7c509b..dc741d3 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -1521,7 +1521,7 @@
 			req = current_req;
 			/* 
 			 * For PMU sleep and freq change requests, we lock the
-			 * PMU until it's explicitely unlocked. This avoids any
+			 * PMU until it's explicitly unlocked. This avoids any
 			 * spurrious event polling getting in
 			 */
 			current_req = req->next;
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 34a8c60..9b6fbf0 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -267,6 +267,12 @@
 	---help---
 	  Multipath support for LSI/Engenio RDAC.
 
+config DM_MULTIPATH_HP
+        tristate "HP MSA multipath support (EXPERIMENTAL)"
+        depends on DM_MULTIPATH && BLK_DEV_DM && EXPERIMENTAL
+        ---help---
+          Multipath support for HP MSA (Active/Passive) series hardware.
+
 config DM_DELAY
 	tristate "I/O delaying target (EXPERIMENTAL)"
 	depends on BLK_DEV_DM && EXPERIMENTAL
@@ -276,4 +282,10 @@
 
 	If unsure, say N.
 
+config DM_UEVENT
+	bool "DM uevents (EXPERIMENTAL)"
+	depends on BLK_DEV_DM && EXPERIMENTAL
+	---help---
+	Generate udev events for DM events.
+
 endif # MD
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index c49366c..d9aa7ed 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -8,6 +8,7 @@
 dm-snapshot-objs := dm-snap.o dm-exception-store.o
 dm-mirror-objs	:= dm-log.o dm-raid1.o
 dm-rdac-objs	:= dm-mpath-rdac.o
+dm-hp-sw-objs	:= dm-mpath-hp-sw.o
 md-mod-objs     := md.o bitmap.o
 raid456-objs	:= raid5.o raid6algos.o raid6recov.o raid6tables.o \
 		   raid6int1.o raid6int2.o raid6int4.o \
@@ -35,6 +36,7 @@
 obj-$(CONFIG_DM_DELAY)		+= dm-delay.o
 obj-$(CONFIG_DM_MULTIPATH)	+= dm-multipath.o dm-round-robin.o
 obj-$(CONFIG_DM_MULTIPATH_EMC)	+= dm-emc.o
+obj-$(CONFIG_DM_MULTIPATH_HP)	+= dm-hp-sw.o
 obj-$(CONFIG_DM_MULTIPATH_RDAC)	+= dm-rdac.o
 obj-$(CONFIG_DM_SNAPSHOT)	+= dm-snapshot.o
 obj-$(CONFIG_DM_MIRROR)		+= dm-mirror.o
@@ -48,6 +50,10 @@
 altivec_flags := -maltivec -mabi=altivec
 endif
 
+ifeq ($(CONFIG_DM_UEVENT),y)
+dm-mod-objs			+= dm-uevent.o
+endif
+
 targets += raid6int1.c
 $(obj)/raid6int1.c:   UNROLL := 1
 $(obj)/raid6int1.c:   $(src)/raid6int.uc $(src)/unroll.pl FORCE
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 927cb34..7c426d0 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -274,7 +274,7 @@
 			if (bitmap->offset < 0) {
 				/* DATA  BITMAP METADATA  */
 				if (bitmap->offset
-				    + page->index * (PAGE_SIZE/512)
+				    + (long)(page->index * (PAGE_SIZE/512))
 				    + size/512 > 0)
 					/* bitmap runs in to metadata */
 					return -EINVAL;
diff --git a/drivers/md/dm-bio-list.h b/drivers/md/dm-bio-list.h
index 3f7b827..d4509be 100644
--- a/drivers/md/dm-bio-list.h
+++ b/drivers/md/dm-bio-list.h
@@ -21,11 +21,6 @@
 	return bl->head == NULL;
 }
 
-#define BIO_LIST_INIT { .head = NULL, .tail = NULL }
-
-#define BIO_LIST(bl) \
-	struct bio_list bl = BIO_LIST_INIT
-
 static inline void bio_list_init(struct bio_list *bl)
 {
 	bl->head = bl->tail = NULL;
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 64fee90..ac54f69 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -36,7 +36,6 @@
 	struct work_struct work;
 	atomic_t pending;
 	int error;
-	int post_process;
 };
 
 /*
@@ -57,7 +56,7 @@
 
 struct crypt_iv_operations {
 	int (*ctr)(struct crypt_config *cc, struct dm_target *ti,
-	           const char *opts);
+		   const char *opts);
 	void (*dtr)(struct crypt_config *cc);
 	const char *(*status)(struct crypt_config *cc);
 	int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector);
@@ -80,6 +79,8 @@
 	mempool_t *page_pool;
 	struct bio_set *bs;
 
+	struct workqueue_struct *io_queue;
+	struct workqueue_struct *crypt_queue;
 	/*
 	 * crypto related data
 	 */
@@ -112,7 +113,7 @@
  * Different IV generation algorithms:
  *
  * plain: the initial vector is the 32-bit little-endian version of the sector
- *        number, padded with zeros if neccessary.
+ *        number, padded with zeros if necessary.
  *
  * essiv: "encrypted sector|salt initial vector", the sector number is
  *        encrypted with the bulk cipher using a salt as key. The salt
@@ -137,7 +138,7 @@
 }
 
 static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
-	                      const char *opts)
+			      const char *opts)
 {
 	struct crypto_cipher *essiv_tfm;
 	struct crypto_hash *hash_tfm;
@@ -175,6 +176,7 @@
 
 	if (err) {
 		ti->error = "Error calculating hash in ESSIV";
+		kfree(salt);
 		return err;
 	}
 
@@ -188,7 +190,7 @@
 	if (crypto_cipher_blocksize(essiv_tfm) !=
 	    crypto_blkcipher_ivsize(cc->tfm)) {
 		ti->error = "Block size of ESSIV cipher does "
-			        "not match IV size of block cipher";
+			    "not match IV size of block cipher";
 		crypto_free_cipher(essiv_tfm);
 		kfree(salt);
 		return -EINVAL;
@@ -319,10 +321,10 @@
 	return r;
 }
 
-static void
-crypt_convert_init(struct crypt_config *cc, struct convert_context *ctx,
-                   struct bio *bio_out, struct bio *bio_in,
-                   sector_t sector, int write)
+static void crypt_convert_init(struct crypt_config *cc,
+			       struct convert_context *ctx,
+			       struct bio *bio_out, struct bio *bio_in,
+			       sector_t sector, int write)
 {
 	ctx->bio_in = bio_in;
 	ctx->bio_out = bio_out;
@@ -338,7 +340,7 @@
  * Encrypt / decrypt data from one bio to another one (can be the same one)
  */
 static int crypt_convert(struct crypt_config *cc,
-                         struct convert_context *ctx)
+			 struct convert_context *ctx)
 {
 	int r = 0;
 
@@ -346,16 +348,17 @@
 	      ctx->idx_out < ctx->bio_out->bi_vcnt) {
 		struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
 		struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
-		struct scatterlist sg_in = {
-			.page = bv_in->bv_page,
-			.offset = bv_in->bv_offset + ctx->offset_in,
-			.length = 1 << SECTOR_SHIFT
-		};
-		struct scatterlist sg_out = {
-			.page = bv_out->bv_page,
-			.offset = bv_out->bv_offset + ctx->offset_out,
-			.length = 1 << SECTOR_SHIFT
-		};
+		struct scatterlist sg_in, sg_out;
+
+		sg_init_table(&sg_in, 1);
+		sg_set_page(&sg_in, bv_in->bv_page);
+		sg_in.offset = bv_in->bv_offset + ctx->offset_in;
+		sg_in.length = 1 << SECTOR_SHIFT;
+
+		sg_init_table(&sg_out, 1);
+		sg_set_page(&sg_out, bv_out->bv_page);
+		sg_out.offset = bv_out->bv_offset + ctx->offset_out;
+		sg_out.length = 1 << SECTOR_SHIFT;
 
 		ctx->offset_in += sg_in.length;
 		if (ctx->offset_in >= bv_in->bv_len) {
@@ -370,7 +373,7 @@
 		}
 
 		r = crypt_convert_scatterlist(cc, &sg_out, &sg_in, sg_in.length,
-		                              ctx->write, ctx->sector);
+					      ctx->write, ctx->sector);
 		if (r < 0)
 			break;
 
@@ -380,13 +383,13 @@
 	return r;
 }
 
- static void dm_crypt_bio_destructor(struct bio *bio)
- {
+static void dm_crypt_bio_destructor(struct bio *bio)
+{
 	struct dm_crypt_io *io = bio->bi_private;
 	struct crypt_config *cc = io->target->private;
 
 	bio_free(bio, cc->bs);
- }
+}
 
 /*
  * Generate a new unfragmented bio with the given size
@@ -458,7 +461,7 @@
  * One of the bios was finished. Check for completion of
  * the whole request and correctly clean up the buffer.
  */
-static void dec_pending(struct dm_crypt_io *io, int error)
+static void crypt_dec_pending(struct dm_crypt_io *io, int error)
 {
 	struct crypt_config *cc = (struct crypt_config *) io->target->private;
 
@@ -474,18 +477,36 @@
 }
 
 /*
- * kcryptd:
+ * kcryptd/kcryptd_io:
  *
  * Needed because it would be very unwise to do decryption in an
  * interrupt context.
+ *
+ * kcryptd performs the actual encryption or decryption.
+ *
+ * kcryptd_io performs the IO submission.
+ *
+ * They must be separated as otherwise the final stages could be
+ * starved by new requests which can block in the first stages due
+ * to memory allocation.
  */
-static struct workqueue_struct *_kcryptd_workqueue;
 static void kcryptd_do_work(struct work_struct *work);
+static void kcryptd_do_crypt(struct work_struct *work);
 
 static void kcryptd_queue_io(struct dm_crypt_io *io)
 {
+	struct crypt_config *cc = io->target->private;
+
 	INIT_WORK(&io->work, kcryptd_do_work);
-	queue_work(_kcryptd_workqueue, &io->work);
+	queue_work(cc->io_queue, &io->work);
+}
+
+static void kcryptd_queue_crypt(struct dm_crypt_io *io)
+{
+	struct crypt_config *cc = io->target->private;
+
+	INIT_WORK(&io->work, kcryptd_do_crypt);
+	queue_work(cc->crypt_queue, &io->work);
 }
 
 static void crypt_endio(struct bio *clone, int error)
@@ -508,13 +529,12 @@
 	}
 
 	bio_put(clone);
-	io->post_process = 1;
-	kcryptd_queue_io(io);
+	kcryptd_queue_crypt(io);
 	return;
 
 out:
 	bio_put(clone);
-	dec_pending(io, error);
+	crypt_dec_pending(io, error);
 }
 
 static void clone_init(struct dm_crypt_io *io, struct bio *clone)
@@ -544,7 +564,7 @@
 	 */
 	clone = bio_alloc_bioset(GFP_NOIO, bio_segments(base_bio), cc->bs);
 	if (unlikely(!clone)) {
-		dec_pending(io, -ENOMEM);
+		crypt_dec_pending(io, -ENOMEM);
 		return;
 	}
 
@@ -579,7 +599,7 @@
 	while (remaining) {
 		clone = crypt_alloc_buffer(io, remaining);
 		if (unlikely(!clone)) {
-			dec_pending(io, -ENOMEM);
+			crypt_dec_pending(io, -ENOMEM);
 			return;
 		}
 
@@ -589,7 +609,7 @@
 		if (unlikely(crypt_convert(cc, &ctx) < 0)) {
 			crypt_free_buffer_pages(cc, clone);
 			bio_put(clone);
-			dec_pending(io, -EIO);
+			crypt_dec_pending(io, -EIO);
 			return;
 		}
 
@@ -624,17 +644,23 @@
 	crypt_convert_init(cc, &ctx, io->base_bio, io->base_bio,
 			   io->base_bio->bi_sector - io->target->begin, 0);
 
-	dec_pending(io, crypt_convert(cc, &ctx));
+	crypt_dec_pending(io, crypt_convert(cc, &ctx));
 }
 
 static void kcryptd_do_work(struct work_struct *work)
 {
 	struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work);
 
-	if (io->post_process)
-		process_read_endio(io);
-	else if (bio_data_dir(io->base_bio) == READ)
+	if (bio_data_dir(io->base_bio) == READ)
 		process_read(io);
+}
+
+static void kcryptd_do_crypt(struct work_struct *work)
+{
+	struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work);
+
+	if (bio_data_dir(io->base_bio) == READ)
+		process_read_endio(io);
 	else
 		process_write(io);
 }
@@ -690,7 +716,7 @@
 	cc->key_size = key_size; /* initial settings */
 
 	if ((!key_size && strcmp(key, "-")) ||
-	    (key_size && crypt_decode_key(cc->key, key, key_size) < 0))
+	   (key_size && crypt_decode_key(cc->key, key, key_size) < 0))
 		return -EINVAL;
 
 	set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
@@ -746,7 +772,7 @@
 
  	if (crypt_set_key(cc, argv[1])) {
 		ti->error = "Error decoding key";
-		goto bad1;
+		goto bad_cipher;
 	}
 
 	/* Compatiblity mode for old dm-crypt cipher strings */
@@ -757,19 +783,19 @@
 
 	if (strcmp(chainmode, "ecb") && !ivmode) {
 		ti->error = "This chaining mode requires an IV mechanism";
-		goto bad1;
+		goto bad_cipher;
 	}
 
-	if (snprintf(cc->cipher, CRYPTO_MAX_ALG_NAME, "%s(%s)", chainmode, 
-		     cipher) >= CRYPTO_MAX_ALG_NAME) {
+	if (snprintf(cc->cipher, CRYPTO_MAX_ALG_NAME, "%s(%s)",
+		     chainmode, cipher) >= CRYPTO_MAX_ALG_NAME) {
 		ti->error = "Chain mode + cipher name is too long";
-		goto bad1;
+		goto bad_cipher;
 	}
 
 	tfm = crypto_alloc_blkcipher(cc->cipher, 0, CRYPTO_ALG_ASYNC);
 	if (IS_ERR(tfm)) {
 		ti->error = "Error allocating crypto tfm";
-		goto bad1;
+		goto bad_cipher;
 	}
 
 	strcpy(cc->cipher, cipher);
@@ -793,18 +819,18 @@
 		cc->iv_gen_ops = &crypt_iv_null_ops;
 	else {
 		ti->error = "Invalid IV mode";
-		goto bad2;
+		goto bad_ivmode;
 	}
 
 	if (cc->iv_gen_ops && cc->iv_gen_ops->ctr &&
 	    cc->iv_gen_ops->ctr(cc, ti, ivopts) < 0)
-		goto bad2;
+		goto bad_ivmode;
 
 	cc->iv_size = crypto_blkcipher_ivsize(tfm);
 	if (cc->iv_size)
 		/* at least a 64 bit sector number should fit in our buffer */
 		cc->iv_size = max(cc->iv_size,
-		                  (unsigned int)(sizeof(u64) / sizeof(u8)));
+				  (unsigned int)(sizeof(u64) / sizeof(u8)));
 	else {
 		if (cc->iv_gen_ops) {
 			DMWARN("Selected cipher does not support IVs");
@@ -817,13 +843,13 @@
 	cc->io_pool = mempool_create_slab_pool(MIN_IOS, _crypt_io_pool);
 	if (!cc->io_pool) {
 		ti->error = "Cannot allocate crypt io mempool";
-		goto bad3;
+		goto bad_slab_pool;
 	}
 
 	cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0);
 	if (!cc->page_pool) {
 		ti->error = "Cannot allocate page mempool";
-		goto bad4;
+		goto bad_page_pool;
 	}
 
 	cc->bs = bioset_create(MIN_IOS, MIN_IOS);
@@ -834,25 +860,25 @@
 
 	if (crypto_blkcipher_setkey(tfm, cc->key, key_size) < 0) {
 		ti->error = "Error setting key";
-		goto bad5;
+		goto bad_device;
 	}
 
 	if (sscanf(argv[2], "%llu", &tmpll) != 1) {
 		ti->error = "Invalid iv_offset sector";
-		goto bad5;
+		goto bad_device;
 	}
 	cc->iv_offset = tmpll;
 
 	if (sscanf(argv[4], "%llu", &tmpll) != 1) {
 		ti->error = "Invalid device sector";
-		goto bad5;
+		goto bad_device;
 	}
 	cc->start = tmpll;
 
 	if (dm_get_device(ti, argv[3], cc->start, ti->len,
-	                  dm_table_get_mode(ti->table), &cc->dev)) {
+			  dm_table_get_mode(ti->table), &cc->dev)) {
 		ti->error = "Device lookup failed";
-		goto bad5;
+		goto bad_device;
 	}
 
 	if (ivmode && cc->iv_gen_ops) {
@@ -861,27 +887,45 @@
 		cc->iv_mode = kmalloc(strlen(ivmode) + 1, GFP_KERNEL);
 		if (!cc->iv_mode) {
 			ti->error = "Error kmallocing iv_mode string";
-			goto bad5;
+			goto bad_ivmode_string;
 		}
 		strcpy(cc->iv_mode, ivmode);
 	} else
 		cc->iv_mode = NULL;
 
+	cc->io_queue = create_singlethread_workqueue("kcryptd_io");
+	if (!cc->io_queue) {
+		ti->error = "Couldn't create kcryptd io queue";
+		goto bad_io_queue;
+	}
+
+	cc->crypt_queue = create_singlethread_workqueue("kcryptd");
+	if (!cc->crypt_queue) {
+		ti->error = "Couldn't create kcryptd queue";
+		goto bad_crypt_queue;
+	}
+
 	ti->private = cc;
 	return 0;
 
-bad5:
+bad_crypt_queue:
+	destroy_workqueue(cc->io_queue);
+bad_io_queue:
+	kfree(cc->iv_mode);
+bad_ivmode_string:
+	dm_put_device(ti, cc->dev);
+bad_device:
 	bioset_free(cc->bs);
 bad_bs:
 	mempool_destroy(cc->page_pool);
-bad4:
+bad_page_pool:
 	mempool_destroy(cc->io_pool);
-bad3:
+bad_slab_pool:
 	if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
 		cc->iv_gen_ops->dtr(cc);
-bad2:
+bad_ivmode:
 	crypto_free_blkcipher(tfm);
-bad1:
+bad_cipher:
 	/* Must zero key material before freeing */
 	memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
 	kfree(cc);
@@ -892,7 +936,8 @@
 {
 	struct crypt_config *cc = (struct crypt_config *) ti->private;
 
-	flush_workqueue(_kcryptd_workqueue);
+	destroy_workqueue(cc->io_queue);
+	destroy_workqueue(cc->crypt_queue);
 
 	bioset_free(cc->bs);
 	mempool_destroy(cc->page_pool);
@@ -918,9 +963,13 @@
 	io = mempool_alloc(cc->io_pool, GFP_NOIO);
 	io->target = ti;
 	io->base_bio = bio;
-	io->error = io->post_process = 0;
+	io->error = 0;
 	atomic_set(&io->pending, 0);
-	kcryptd_queue_io(io);
+
+	if (bio_data_dir(io->base_bio) == READ)
+		kcryptd_queue_io(io);
+	else
+		kcryptd_queue_crypt(io);
 
 	return DM_MAPIO_SUBMITTED;
 }
@@ -1037,25 +1086,12 @@
 	if (!_crypt_io_pool)
 		return -ENOMEM;
 
-	_kcryptd_workqueue = create_workqueue("kcryptd");
-	if (!_kcryptd_workqueue) {
-		r = -ENOMEM;
-		DMERR("couldn't create kcryptd");
-		goto bad1;
-	}
-
 	r = dm_register_target(&crypt_target);
 	if (r < 0) {
 		DMERR("register failed %d", r);
-		goto bad2;
+		kmem_cache_destroy(_crypt_io_pool);
 	}
 
-	return 0;
-
-bad2:
-	destroy_workqueue(_kcryptd_workqueue);
-bad1:
-	kmem_cache_destroy(_crypt_io_pool);
 	return r;
 }
 
@@ -1066,7 +1102,6 @@
 	if (r < 0)
 		DMERR("unregister failed %d", r);
 
-	destroy_workqueue(_kcryptd_workqueue);
 	kmem_cache_destroy(_crypt_io_pool);
 }
 
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c
index 6928c13..bdd37f8 100644
--- a/drivers/md/dm-delay.c
+++ b/drivers/md/dm-delay.c
@@ -83,7 +83,7 @@
 	struct dm_delay_info *delayed, *next;
 	unsigned long next_expires = 0;
 	int start_timer = 0;
-	BIO_LIST(flush_bios);
+	struct bio_list flush_bios = { };
 
 	mutex_lock(&delayed_bios_lock);
 	list_for_each_entry_safe(delayed, next, &dc->delayed_bios, list) {
@@ -163,34 +163,32 @@
 		goto bad;
 	}
 
-	if (argc == 3) {
-		dc->dev_write = NULL;
+	dc->dev_write = NULL;
+	if (argc == 3)
 		goto out;
-	}
 
 	if (sscanf(argv[4], "%llu", &tmpll) != 1) {
 		ti->error = "Invalid write device sector";
-		goto bad;
+		goto bad_dev_read;
 	}
 	dc->start_write = tmpll;
 
 	if (sscanf(argv[5], "%u", &dc->write_delay) != 1) {
 		ti->error = "Invalid write delay";
-		goto bad;
+		goto bad_dev_read;
 	}
 
 	if (dm_get_device(ti, argv[3], dc->start_write, ti->len,
 			  dm_table_get_mode(ti->table), &dc->dev_write)) {
 		ti->error = "Write device lookup failed";
-		dm_put_device(ti, dc->dev_read);
-		goto bad;
+		goto bad_dev_read;
 	}
 
 out:
 	dc->delayed_pool = mempool_create_slab_pool(128, delayed_cache);
 	if (!dc->delayed_pool) {
 		DMERR("Couldn't create delayed bio pool.");
-		goto bad;
+		goto bad_dev_write;
 	}
 
 	setup_timer(&dc->delay_timer, handle_delayed_timer, (unsigned long)dc);
@@ -203,6 +201,11 @@
 	ti->private = dc;
 	return 0;
 
+bad_dev_write:
+	if (dc->dev_write)
+		dm_put_device(ti, dc->dev_write);
+bad_dev_read:
+	dm_put_device(ti, dc->dev_read);
 bad:
 	kfree(dc);
 	return -EINVAL;
@@ -305,7 +308,7 @@
 		       (unsigned long long) dc->start_read,
 		       dc->read_delay);
 		if (dc->dev_write)
-			DMEMIT("%s %llu %u", dc->dev_write->name,
+			DMEMIT(" %s %llu %u", dc->dev_write->name,
 			       (unsigned long long) dc->start_write,
 			       dc->write_delay);
 		break;
diff --git a/drivers/md/dm-emc.c b/drivers/md/dm-emc.c
index 3425172..6b91b9a 100644
--- a/drivers/md/dm-emc.c
+++ b/drivers/md/dm-emc.c
@@ -81,7 +81,7 @@
 	}
 
 	if (bio_add_page(bio, page, data_size, 0) != data_size) {
-		DMERR("get_failover_bio: alloc_page() failed.");
+		DMERR("get_failover_bio: bio_add_page() failed.");
 		__free_page(page);
 		bio_put(bio);
 		return NULL;
@@ -211,12 +211,10 @@
 
 static struct emc_handler *alloc_emc_handler(void)
 {
-	struct emc_handler *h = kmalloc(sizeof(*h), GFP_KERNEL);
+	struct emc_handler *h = kzalloc(sizeof(*h), GFP_KERNEL);
 
-	if (h) {
-		memset(h, 0, sizeof(*h));
+	if (h)
 		spin_lock_init(&h->lock);
-	}
 
 	return h;
 }
diff --git a/drivers/md/dm-hw-handler.c b/drivers/md/dm-hw-handler.c
index baafaab..2ee84d8 100644
--- a/drivers/md/dm-hw-handler.c
+++ b/drivers/md/dm-hw-handler.c
@@ -91,12 +91,10 @@
 
 static struct hwh_internal *_alloc_hw_handler(struct hw_handler_type *hwht)
 {
-	struct hwh_internal *hwhi = kmalloc(sizeof(*hwhi), GFP_KERNEL);
+	struct hwh_internal *hwhi = kzalloc(sizeof(*hwhi), GFP_KERNEL);
 
-	if (hwhi) {
-		memset(hwhi, 0, sizeof(*hwhi));
+	if (hwhi)
 		hwhi->hwht = *hwht;
-	}
 
 	return hwhi;
 }
diff --git a/drivers/md/dm-hw-handler.h b/drivers/md/dm-hw-handler.h
index e0832e6..46809dc 100644
--- a/drivers/md/dm-hw-handler.h
+++ b/drivers/md/dm-hw-handler.h
@@ -58,5 +58,6 @@
 #define MP_FAIL_PATH 1
 #define MP_BYPASS_PG 2
 #define MP_ERROR_IO  4	/* Don't retry this I/O */
+#define MP_RETRY 8
 
 #endif
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index b441d82..138200b 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -700,7 +700,7 @@
 	int r;
 	char *new_name = (char *) param + param->data_start;
 
-	if (new_name < (char *) (param + 1) ||
+	if (new_name < (char *) param->data ||
 	    invalid_str(new_name, (void *) param + param_size)) {
 		DMWARN("Invalid new logical volume name supplied.");
 		return -EINVAL;
@@ -726,7 +726,7 @@
 	if (!md)
 		return -ENXIO;
 
-	if (geostr < (char *) (param + 1) ||
+	if (geostr < (char *) param->data ||
 	    invalid_str(geostr, (void *) param + param_size)) {
 		DMWARN("Invalid geometry supplied.");
 		goto out;
@@ -1233,7 +1233,7 @@
 	if (r)
 		goto out;
 
-	if (tmsg < (struct dm_target_msg *) (param + 1) ||
+	if (tmsg < (struct dm_target_msg *) param->data ||
 	    invalid_str(tmsg->message, (void *) param + param_size)) {
 		DMWARN("Invalid target message parameters.");
 		r = -EINVAL;
@@ -1358,7 +1358,7 @@
 	if (tmp.data_size < sizeof(tmp))
 		return -EINVAL;
 
-	dmi = (struct dm_ioctl *) vmalloc(tmp.data_size);
+	dmi = vmalloc(tmp.data_size);
 	if (!dmi)
 		return -ENOMEM;
 
@@ -1515,3 +1515,35 @@
 
 	dm_hash_exit();
 }
+
+/**
+ * dm_copy_name_and_uuid - Copy mapped device name & uuid into supplied buffers
+ * @md: Pointer to mapped_device
+ * @name: Buffer (size DM_NAME_LEN) for name
+ * @uuid: Buffer (size DM_UUID_LEN) for uuid or empty string if uuid not defined
+ */
+int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid)
+{
+	int r = 0;
+	struct hash_cell *hc;
+
+	if (!md)
+		return -ENXIO;
+
+	dm_get(md);
+	down_read(&_hash_lock);
+	hc = dm_get_mdptr(md);
+	if (!hc || hc->md != md) {
+		r = -ENXIO;
+		goto out;
+	}
+
+	strcpy(name, hc->name);
+	strcpy(uuid, hc->uuid ? : "");
+
+out:
+	up_read(&_hash_lock);
+	dm_put(md);
+
+	return r;
+}
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index a66428d..072ee43 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -696,7 +696,7 @@
 	.module = THIS_MODULE,
 	.ctr = disk_ctr,
 	.dtr = disk_dtr,
-	.suspend = disk_flush,
+	.postsuspend = disk_flush,
 	.resume = disk_resume,
 	.get_region_size = core_get_region_size,
 	.is_clean = core_is_clean,
diff --git a/drivers/md/dm-log.h b/drivers/md/dm-log.h
index 86a301c..3fae87e 100644
--- a/drivers/md/dm-log.h
+++ b/drivers/md/dm-log.h
@@ -32,7 +32,8 @@
 	 * There are times when we don't want the log to touch
 	 * the disk.
 	 */
-	int (*suspend)(struct dirty_log *log);
+	int (*presuspend)(struct dirty_log *log);
+	int (*postsuspend)(struct dirty_log *log);
 	int (*resume)(struct dirty_log *log);
 
 	/*
diff --git a/drivers/md/dm-mpath-hp-sw.c b/drivers/md/dm-mpath-hp-sw.c
new file mode 100644
index 0000000..204bf42
--- /dev/null
+++ b/drivers/md/dm-mpath-hp-sw.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2005 Mike Christie, All rights reserved.
+ * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
+ * Authors: Mike Christie
+ *          Dave Wysochanski
+ *
+ * This file is released under the GPL.
+ *
+ * This module implements the specific path activation code for
+ * HP StorageWorks and FSC FibreCat Asymmetric (Active/Passive)
+ * storage arrays.
+ * These storage arrays have controller-based failover, not
+ * LUN-based failover.  However, LUN-based failover is the design
+ * of dm-multipath. Thus, this module is written for LUN-based failover.
+ */
+#include <linux/blkdev.h>
+#include <linux/list.h>
+#include <linux/types.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
+
+#include "dm.h"
+#include "dm-hw-handler.h"
+
+#define DM_MSG_PREFIX "multipath hp-sw"
+#define DM_HP_HWH_NAME "hp-sw"
+#define DM_HP_HWH_VER "1.0.0"
+
+struct hp_sw_context {
+	unsigned char sense[SCSI_SENSE_BUFFERSIZE];
+};
+
+/*
+ * hp_sw_error_is_retryable - Is an HP-specific check condition retryable?
+ * @req: path activation request
+ *
+ * Examine error codes of request and determine whether the error is retryable.
+ * Some error codes are already retried by scsi-ml (see
+ * scsi_decide_disposition), but some HP specific codes are not.
+ * The intent of this routine is to supply the logic for the HP specific
+ * check conditions.
+ *
+ * Returns:
+ *  1 - command completed with retryable error
+ *  0 - command completed with non-retryable error
+ *
+ * Possible optimizations
+ * 1. More hardware-specific error codes
+ */
+static int hp_sw_error_is_retryable(struct request *req)
+{
+	/*
+	 * NOT_READY is known to be retryable
+	 * For now we just dump out the sense data and call it retryable
+	 */
+	if (status_byte(req->errors) == CHECK_CONDITION)
+		__scsi_print_sense(DM_HP_HWH_NAME, req->sense, req->sense_len);
+
+	/*
+	 * At this point we don't have complete information about all the error
+	 * codes from this hardware, so we are just conservative and retry
+	 * when in doubt.
+	 */
+	return 1;
+}
+
+/*
+ * hp_sw_end_io - Completion handler for HP path activation.
+ * @req: path activation request
+ * @error: scsi-ml error
+ *
+ *  Check sense data, free request structure, and notify dm that
+ *  pg initialization has completed.
+ *
+ * Context: scsi-ml softirq
+ *
+ */
+static void hp_sw_end_io(struct request *req, int error)
+{
+	struct dm_path *path = req->end_io_data;
+	unsigned err_flags = 0;
+
+	if (!error) {
+		DMDEBUG("%s path activation command - success",
+			path->dev->name);
+		goto out;
+	}
+
+	if (hp_sw_error_is_retryable(req)) {
+		DMDEBUG("%s path activation command - retry",
+			path->dev->name);
+		err_flags = MP_RETRY;
+		goto out;
+	}
+
+	DMWARN("%s path activation fail - error=0x%x",
+	       path->dev->name, error);
+	err_flags = MP_FAIL_PATH;
+
+out:
+	req->end_io_data = NULL;
+	__blk_put_request(req->q, req);
+	dm_pg_init_complete(path, err_flags);
+}
+
+/*
+ * hp_sw_get_request - Allocate an HP specific path activation request
+ * @path: path on which request will be sent (needed for request queue)
+ *
+ * The START command is used for path activation request.
+ * These arrays are controller-based failover, not LUN based.
+ * One START command issued to a single path will fail over all
+ * LUNs for the same controller.
+ *
+ * Possible optimizations
+ * 1. Make timeout configurable
+ * 2. Preallocate request
+ */
+static struct request *hp_sw_get_request(struct dm_path *path)
+{
+	struct request *req;
+	struct block_device *bdev = path->dev->bdev;
+	struct request_queue *q = bdev_get_queue(bdev);
+	struct hp_sw_context *h = path->hwhcontext;
+
+	req = blk_get_request(q, WRITE, GFP_NOIO);
+	if (!req)
+		goto out;
+
+	req->timeout = 60 * HZ;
+
+	req->errors = 0;
+	req->cmd_type = REQ_TYPE_BLOCK_PC;
+	req->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE;
+	req->end_io_data = path;
+	req->sense = h->sense;
+	memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
+
+	memset(&req->cmd, 0, BLK_MAX_CDB);
+	req->cmd[0] = START_STOP;
+	req->cmd[4] = 1;
+	req->cmd_len = COMMAND_SIZE(req->cmd[0]);
+
+out:
+	return req;
+}
+
+/*
+ * hp_sw_pg_init - HP path activation implementation.
+ * @hwh: hardware handler specific data
+ * @bypassed: unused; is the path group bypassed? (see dm-mpath.c)
+ * @path: path to send initialization command
+ *
+ * Send an HP-specific path activation command on 'path'.
+ * Do not try to optimize in any way, just send the activation command.
+ * More than one path activation command may be sent to the same controller.
+ * This seems to work fine for basic failover support.
+ *
+ * Possible optimizations
+ * 1. Detect an in-progress activation request and avoid submitting another one
+ * 2. Model the controller and only send a single activation request at a time
+ * 3. Determine the state of a path before sending an activation request
+ *
+ * Context: kmpathd (see process_queued_ios() in dm-mpath.c)
+ */
+static void hp_sw_pg_init(struct hw_handler *hwh, unsigned bypassed,
+			  struct dm_path *path)
+{
+	struct request *req;
+	struct hp_sw_context *h;
+
+	path->hwhcontext = hwh->context;
+	h = hwh->context;
+
+	req = hp_sw_get_request(path);
+	if (!req) {
+		DMERR("%s path activation command - allocation fail",
+		      path->dev->name);
+		goto retry;
+	}
+
+	DMDEBUG("%s path activation command - sent", path->dev->name);
+
+	blk_execute_rq_nowait(req->q, NULL, req, 1, hp_sw_end_io);
+	return;
+
+retry:
+	dm_pg_init_complete(path, MP_RETRY);
+}
+
+static int hp_sw_create(struct hw_handler *hwh, unsigned argc, char **argv)
+{
+	struct hp_sw_context *h;
+
+	h = kmalloc(sizeof(*h), GFP_KERNEL);
+	if (!h)
+		return -ENOMEM;
+
+	hwh->context = h;
+
+	return 0;
+}
+
+static void hp_sw_destroy(struct hw_handler *hwh)
+{
+	struct hp_sw_context *h = hwh->context;
+
+	kfree(h);
+}
+
+static struct hw_handler_type hp_sw_hwh = {
+	.name = DM_HP_HWH_NAME,
+	.module = THIS_MODULE,
+	.create = hp_sw_create,
+	.destroy = hp_sw_destroy,
+	.pg_init = hp_sw_pg_init,
+};
+
+static int __init hp_sw_init(void)
+{
+	int r;
+
+	r = dm_register_hw_handler(&hp_sw_hwh);
+	if (r < 0)
+		DMERR("register failed %d", r);
+	else
+		DMINFO("version " DM_HP_HWH_VER " loaded");
+
+	return r;
+}
+
+static void __exit hp_sw_exit(void)
+{
+	int r;
+
+	r = dm_unregister_hw_handler(&hp_sw_hwh);
+	if (r < 0)
+		DMERR("unregister failed %d", r);
+}
+
+module_init(hp_sw_init);
+module_exit(hp_sw_exit);
+
+MODULE_DESCRIPTION("DM Multipath HP StorageWorks / FSC FibreCat (A/P) support");
+MODULE_AUTHOR("Mike Christie, Dave Wysochanski <dm-devel@redhat.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DM_HP_HWH_VER);
diff --git a/drivers/md/dm-mpath-rdac.c b/drivers/md/dm-mpath-rdac.c
index 16b1613..e04eb5c 100644
--- a/drivers/md/dm-mpath-rdac.c
+++ b/drivers/md/dm-mpath-rdac.c
@@ -664,20 +664,21 @@
 
 static int __init rdac_init(void)
 {
-	int r = dm_register_hw_handler(&rdac_handler);
-
-	if (r < 0) {
-		DMERR("%s: register failed %d", RDAC_DM_HWH_NAME, r);
-		return r;
-	}
+	int r;
 
 	rdac_wkqd = create_singlethread_workqueue("rdac_wkqd");
 	if (!rdac_wkqd) {
 		DMERR("Failed to create workqueue rdac_wkqd.");
-		dm_unregister_hw_handler(&rdac_handler);
 		return -ENOMEM;
 	}
 
+	r = dm_register_hw_handler(&rdac_handler);
+	if (r < 0) {
+		DMERR("%s: register failed %d", RDAC_DM_HWH_NAME, r);
+		destroy_workqueue(rdac_wkqd);
+		return r;
+	}
+
 	DMINFO("%s: version %s loaded", RDAC_DM_HWH_NAME, RDAC_DM_HWH_VER);
 	return 0;
 }
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 31056ab..24b2b1e 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -10,6 +10,7 @@
 #include "dm-hw-handler.h"
 #include "dm-bio-list.h"
 #include "dm-bio-record.h"
+#include "dm-uevent.h"
 
 #include <linux/ctype.h>
 #include <linux/init.h>
@@ -75,6 +76,8 @@
 	unsigned queue_io;		/* Must we queue all I/O? */
 	unsigned queue_if_no_path;	/* Queue I/O if last path fails? */
 	unsigned saved_queue_if_no_path;/* Saved state during suspension */
+	unsigned pg_init_retries;	/* Number of times to retry pg_init */
+	unsigned pg_init_count;		/* Number of times pg_init called */
 
 	struct work_struct process_queued_ios;
 	struct bio_list queued_ios;
@@ -225,6 +228,8 @@
 		m->pg_init_required = 0;
 		m->queue_io = 0;
 	}
+
+	m->pg_init_count = 0;
 }
 
 static int __choose_path_in_pg(struct multipath *m, struct priority_group *pg)
@@ -424,6 +429,7 @@
 		must_queue = 0;
 
 	if (m->pg_init_required && !m->pg_init_in_progress) {
+		m->pg_init_count++;
 		m->pg_init_required = 0;
 		m->pg_init_in_progress = 1;
 		init_required = 1;
@@ -689,9 +695,11 @@
 	int r;
 	unsigned argc;
 	struct dm_target *ti = m->ti;
+	const char *param_name;
 
 	static struct param _params[] = {
-		{0, 1, "invalid number of feature args"},
+		{0, 3, "invalid number of feature args"},
+		{1, 50, "pg_init_retries must be between 1 and 50"},
 	};
 
 	r = read_param(_params, shift(as), &argc, &ti->error);
@@ -701,12 +709,28 @@
 	if (!argc)
 		return 0;
 
-	if (!strnicmp(shift(as), MESG_STR("queue_if_no_path")))
-		return queue_if_no_path(m, 1, 0);
-	else {
+	do {
+		param_name = shift(as);
+		argc--;
+
+		if (!strnicmp(param_name, MESG_STR("queue_if_no_path"))) {
+			r = queue_if_no_path(m, 1, 0);
+			continue;
+		}
+
+		if (!strnicmp(param_name, MESG_STR("pg_init_retries")) &&
+		    (argc >= 1)) {
+			r = read_param(_params + 1, shift(as),
+				       &m->pg_init_retries, &ti->error);
+			argc--;
+			continue;
+		}
+
 		ti->error = "Unrecognised multipath feature request";
-		return -EINVAL;
-	}
+		r = -EINVAL;
+	} while (argc && !r);
+
+	return r;
 }
 
 static int multipath_ctr(struct dm_target *ti, unsigned int argc,
@@ -834,6 +858,9 @@
 	if (pgpath == m->current_pgpath)
 		m->current_pgpath = NULL;
 
+	dm_path_uevent(DM_UEVENT_PATH_FAILED, m->ti,
+		      pgpath->path.dev->name, m->nr_valid_paths);
+
 	queue_work(kmultipathd, &m->trigger_event);
 
 out:
@@ -873,6 +900,9 @@
 	if (!m->nr_valid_paths++ && m->queue_size)
 		queue_work(kmultipathd, &m->process_queued_ios);
 
+	dm_path_uevent(DM_UEVENT_PATH_REINSTATED, m->ti,
+		      pgpath->path.dev->name, m->nr_valid_paths);
+
 	queue_work(kmultipathd, &m->trigger_event);
 
 out:
@@ -976,6 +1006,26 @@
 }
 
 /*
+ * Should we retry pg_init immediately?
+ */
+static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath)
+{
+	unsigned long flags;
+	int limit_reached = 0;
+
+	spin_lock_irqsave(&m->lock, flags);
+
+	if (m->pg_init_count <= m->pg_init_retries)
+		m->pg_init_required = 1;
+	else
+		limit_reached = 1;
+
+	spin_unlock_irqrestore(&m->lock, flags);
+
+	return limit_reached;
+}
+
+/*
  * pg_init must call this when it has completed its initialisation
  */
 void dm_pg_init_complete(struct dm_path *path, unsigned err_flags)
@@ -985,8 +1035,14 @@
 	struct multipath *m = pg->m;
 	unsigned long flags;
 
-	/* We insist on failing the path if the PG is already bypassed. */
-	if (err_flags && pg->bypassed)
+	/*
+	 * If requested, retry pg_init until maximum number of retries exceeded.
+	 * If retry not requested and PG already bypassed, always fail the path.
+	 */
+	if (err_flags & MP_RETRY) {
+		if (pg_init_limit_reached(m, pgpath))
+			err_flags |= MP_FAIL_PATH;
+	} else if (err_flags && pg->bypassed)
 		err_flags |= MP_FAIL_PATH;
 
 	if (err_flags & MP_FAIL_PATH)
@@ -996,7 +1052,7 @@
 		bypass_pg(m, pg, 1);
 
 	spin_lock_irqsave(&m->lock, flags);
-	if (err_flags) {
+	if (err_flags & ~MP_RETRY) {
 		m->current_pgpath = NULL;
 		m->current_pg = NULL;
 	} else if (!m->pg_init_required)
@@ -1148,11 +1204,15 @@
 
 	/* Features */
 	if (type == STATUSTYPE_INFO)
-		DMEMIT("1 %u ", m->queue_size);
-	else if (m->queue_if_no_path)
-		DMEMIT("1 queue_if_no_path ");
-	else
-		DMEMIT("0 ");
+		DMEMIT("2 %u %u ", m->queue_size, m->pg_init_count);
+	else {
+		DMEMIT("%u ", m->queue_if_no_path +
+			      (m->pg_init_retries > 0) * 2);
+		if (m->queue_if_no_path)
+			DMEMIT("queue_if_no_path ");
+		if (m->pg_init_retries)
+			DMEMIT("pg_init_retries %u ", m->pg_init_retries);
+	}
 
 	if (hwh->type && hwh->type->status)
 		sz += hwh->type->status(hwh, type, result + sz, maxlen - sz);
diff --git a/drivers/md/dm-path-selector.c b/drivers/md/dm-path-selector.c
index f10a0c8..ca1bb63 100644
--- a/drivers/md/dm-path-selector.c
+++ b/drivers/md/dm-path-selector.c
@@ -94,12 +94,10 @@
 
 static struct ps_internal *_alloc_path_selector(struct path_selector_type *pst)
 {
-	struct ps_internal *psi = kmalloc(sizeof(*psi), GFP_KERNEL);
+	struct ps_internal *psi = kzalloc(sizeof(*psi), GFP_KERNEL);
 
-	if (psi) {
-		memset(psi, 0, sizeof(*psi));
+	if (psi)
 		psi->pst = *pst;
-	}
 
 	return psi;
 }
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index d09ff15..31123d4a 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -19,6 +19,7 @@
 #include <linux/time.h>
 #include <linux/vmalloc.h>
 #include <linux/workqueue.h>
+#include <linux/log2.h>
 
 #define DM_MSG_PREFIX "raid1"
 #define DM_IO_PAGES 64
@@ -113,6 +114,7 @@
  * Mirror set structures.
  *---------------------------------------------------------------*/
 struct mirror {
+	struct mirror_set *ms;
 	atomic_t error_count;
 	struct dm_dev *dev;
 	sector_t offset;
@@ -974,6 +976,7 @@
 
 	if (rh_init(&ms->rh, ms, dl, region_size, ms->nr_regions)) {
 		ti->error = "Error creating dirty region hash";
+		dm_io_client_destroy(ms->io_client);
 		kfree(ms);
 		return NULL;
 	}
@@ -994,7 +997,7 @@
 
 static inline int _check_region_size(struct dm_target *ti, uint32_t size)
 {
-	return !(size % (PAGE_SIZE >> 9) || (size & (size - 1)) ||
+	return !(size % (PAGE_SIZE >> 9) || !is_power_of_2(size) ||
 		 size > ti->len);
 }
 
@@ -1015,6 +1018,7 @@
 		return -ENXIO;
 	}
 
+	ms->mirror[mirror].ms = ms;
 	ms->mirror[mirror].offset = offset;
 
 	return 0;
@@ -1163,16 +1167,14 @@
 	ms->kmirrord_wq = create_singlethread_workqueue("kmirrord");
 	if (!ms->kmirrord_wq) {
 		DMERR("couldn't start kmirrord");
-		free_context(ms, ti, m);
-		return -ENOMEM;
+		r = -ENOMEM;
+		goto err_free_context;
 	}
 	INIT_WORK(&ms->kmirrord_work, do_mirror);
 
 	r = parse_features(ms, argc, argv, &args_used);
-	if (r) {
-		free_context(ms, ti, ms->nr_mirrors);
-		return r;
-	}
+	if (r)
+		goto err_destroy_wq;
 
 	argv += args_used;
 	argc -= args_used;
@@ -1188,19 +1190,22 @@
 
 	if (argc) {
 		ti->error = "Too many mirror arguments";
-		free_context(ms, ti, ms->nr_mirrors);
-		return -EINVAL;
+		r = -EINVAL;
+		goto err_destroy_wq;
 	}
 
 	r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client);
-	if (r) {
-		destroy_workqueue(ms->kmirrord_wq);
-		free_context(ms, ti, ms->nr_mirrors);
-		return r;
-	}
+	if (r)
+		goto err_destroy_wq;
 
 	wake(ms);
 	return 0;
+
+err_destroy_wq:
+	destroy_workqueue(ms->kmirrord_wq);
+err_free_context:
+	free_context(ms, ti, ms->nr_mirrors);
+	return r;
 }
 
 static void mirror_dtr(struct dm_target *ti)
@@ -1302,7 +1307,7 @@
 	wait_event(_kmirrord_recovery_stopped,
 		   !atomic_read(&ms->rh.recovery_in_flight));
 
-	if (log->type->suspend && log->type->suspend(log))
+	if (log->type->postsuspend && log->type->postsuspend(log))
 		/* FIXME: need better error handling */
 		DMWARN("log suspend failed");
 }
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 98a633f..cee16fa 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/log2.h>
 
 #include "dm-snap.h"
 #include "dm-bio-list.h"
@@ -415,7 +416,7 @@
 	chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
 
 	/* Check chunk_size is a power of 2 */
-	if (chunk_size & (chunk_size - 1)) {
+	if (!is_power_of_2(chunk_size)) {
 		*error = "Chunk size is not a power of 2";
 		return -EINVAL;
 	}
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 51f5e07..969944a 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -11,6 +11,7 @@
 #include <linux/blkdev.h>
 #include <linux/bio.h>
 #include <linux/slab.h>
+#include <linux/log2.h>
 
 #define DM_MSG_PREFIX "striped"
 
@@ -99,7 +100,7 @@
 	/*
 	 * chunk_size is a power of two
 	 */
-	if (!chunk_size || (chunk_size & (chunk_size - 1)) ||
+	if (!is_power_of_2(chunk_size) ||
 	    (chunk_size < (PAGE_SIZE >> SECTOR_SHIFT))) {
 		ti->error = "Invalid chunk size";
 		return -EINVAL;
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index fbe477b..8939e61 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -213,12 +213,11 @@
 int dm_table_create(struct dm_table **result, int mode,
 		    unsigned num_targets, struct mapped_device *md)
 {
-	struct dm_table *t = kmalloc(sizeof(*t), GFP_KERNEL);
+	struct dm_table *t = kzalloc(sizeof(*t), GFP_KERNEL);
 
 	if (!t)
 		return -ENOMEM;
 
-	memset(t, 0, sizeof(*t));
 	INIT_LIST_HEAD(&t->devices);
 	atomic_set(&t->holders, 1);
 
diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c
index 477a041..835cf95 100644
--- a/drivers/md/dm-target.c
+++ b/drivers/md/dm-target.c
@@ -88,12 +88,10 @@
 
 static struct tt_internal *alloc_target(struct target_type *t)
 {
-	struct tt_internal *ti = kmalloc(sizeof(*ti), GFP_KERNEL);
+	struct tt_internal *ti = kzalloc(sizeof(*ti), GFP_KERNEL);
 
-	if (ti) {
-		memset(ti, 0, sizeof(*ti));
+	if (ti)
 		ti->tt = *t;
-	}
 
 	return ti;
 }
diff --git a/drivers/md/dm-uevent.c b/drivers/md/dm-uevent.c
new file mode 100644
index 0000000..50377e5
--- /dev/null
+++ b/drivers/md/dm-uevent.c
@@ -0,0 +1,222 @@
+/*
+ * Device Mapper Uevent Support (dm-uevent)
+ *
+ * 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.
+ *
+ * Copyright IBM Corporation, 2007
+ * 	Author: Mike Anderson <andmike@linux.vnet.ibm.com>
+ */
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/kobject.h>
+#include <linux/dm-ioctl.h>
+
+#include "dm.h"
+#include "dm-uevent.h"
+
+#define DM_MSG_PREFIX "uevent"
+
+static const struct {
+	enum dm_uevent_type type;
+	enum kobject_action action;
+	char *name;
+} _dm_uevent_type_names[] = {
+	{DM_UEVENT_PATH_FAILED, KOBJ_CHANGE, "PATH_FAILED"},
+	{DM_UEVENT_PATH_REINSTATED, KOBJ_CHANGE, "PATH_REINSTATED"},
+};
+
+static struct kmem_cache *_dm_event_cache;
+
+struct dm_uevent {
+	struct mapped_device *md;
+	enum kobject_action action;
+	struct kobj_uevent_env ku_env;
+	struct list_head elist;
+	char name[DM_NAME_LEN];
+	char uuid[DM_UUID_LEN];
+};
+
+static void dm_uevent_free(struct dm_uevent *event)
+{
+	kmem_cache_free(_dm_event_cache, event);
+}
+
+static struct dm_uevent *dm_uevent_alloc(struct mapped_device *md)
+{
+	struct dm_uevent *event;
+
+	event = kmem_cache_zalloc(_dm_event_cache, GFP_ATOMIC);
+	if (!event)
+		return NULL;
+
+	INIT_LIST_HEAD(&event->elist);
+	event->md = md;
+
+	return event;
+}
+
+static struct dm_uevent *dm_build_path_uevent(struct mapped_device *md,
+					      struct dm_target *ti,
+					      enum kobject_action action,
+					      const char *dm_action,
+					      const char *path,
+					      unsigned nr_valid_paths)
+{
+	struct dm_uevent *event;
+
+	event = dm_uevent_alloc(md);
+	if (!event) {
+		DMERR("%s: dm_uevent_alloc() failed", __FUNCTION__);
+		goto err_nomem;
+	}
+
+	event->action = action;
+
+	if (add_uevent_var(&event->ku_env, "DM_TARGET=%s", ti->type->name)) {
+		DMERR("%s: add_uevent_var() for DM_TARGET failed",
+		      __FUNCTION__);
+		goto err_add;
+	}
+
+	if (add_uevent_var(&event->ku_env, "DM_ACTION=%s", dm_action)) {
+		DMERR("%s: add_uevent_var() for DM_ACTION failed",
+		      __FUNCTION__);
+		goto err_add;
+	}
+
+	if (add_uevent_var(&event->ku_env, "DM_SEQNUM=%u",
+			   dm_next_uevent_seq(md))) {
+		DMERR("%s: add_uevent_var() for DM_SEQNUM failed",
+		      __FUNCTION__);
+		goto err_add;
+	}
+
+	if (add_uevent_var(&event->ku_env, "DM_PATH=%s", path)) {
+		DMERR("%s: add_uevent_var() for DM_PATH failed", __FUNCTION__);
+		goto err_add;
+	}
+
+	if (add_uevent_var(&event->ku_env, "DM_NR_VALID_PATHS=%d",
+			   nr_valid_paths)) {
+		DMERR("%s: add_uevent_var() for DM_NR_VALID_PATHS failed",
+		      __FUNCTION__);
+		goto err_add;
+	}
+
+	return event;
+
+err_add:
+	dm_uevent_free(event);
+err_nomem:
+	return ERR_PTR(-ENOMEM);
+}
+
+/**
+ * dm_send_uevents - send uevents for given list
+ *
+ * @events:	list of events to send
+ * @kobj:	kobject generating event
+ *
+ */
+void dm_send_uevents(struct list_head *events, struct kobject *kobj)
+{
+	int r;
+	struct dm_uevent *event, *next;
+
+	list_for_each_entry_safe(event, next, events, elist) {
+		list_del_init(&event->elist);
+
+		/*
+		 * Need to call dm_copy_name_and_uuid from here for now.
+		 * Context of previous var adds and locking used for
+		 * hash_cell not compatable.
+		 */
+		if (dm_copy_name_and_uuid(event->md, event->name,
+					  event->uuid)) {
+			DMERR("%s: dm_copy_name_and_uuid() failed",
+			      __FUNCTION__);
+			goto uevent_free;
+		}
+
+		if (add_uevent_var(&event->ku_env, "DM_NAME=%s", event->name)) {
+			DMERR("%s: add_uevent_var() for DM_NAME failed",
+			      __FUNCTION__);
+			goto uevent_free;
+		}
+
+		if (add_uevent_var(&event->ku_env, "DM_UUID=%s", event->uuid)) {
+			DMERR("%s: add_uevent_var() for DM_UUID failed",
+			      __FUNCTION__);
+			goto uevent_free;
+		}
+
+		r = kobject_uevent_env(kobj, event->action, event->ku_env.envp);
+		if (r)
+			DMERR("%s: kobject_uevent_env failed", __FUNCTION__);
+uevent_free:
+		dm_uevent_free(event);
+	}
+}
+EXPORT_SYMBOL_GPL(dm_send_uevents);
+
+/**
+ * dm_path_uevent - called to create a new path event and queue it
+ *
+ * @event_type:	path event type enum
+ * @ti:			pointer to a dm_target
+ * @path:		string containing pathname
+ * @nr_valid_paths:	number of valid paths remaining
+ *
+ */
+void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
+		   const char *path, unsigned nr_valid_paths)
+{
+	struct mapped_device *md = dm_table_get_md(ti->table);
+	struct dm_uevent *event;
+
+	if (event_type >= ARRAY_SIZE(_dm_uevent_type_names)) {
+		DMERR("%s: Invalid event_type %d", __FUNCTION__, event_type);
+		goto out;
+	}
+
+	event = dm_build_path_uevent(md, ti,
+				     _dm_uevent_type_names[event_type].action,
+				     _dm_uevent_type_names[event_type].name,
+				     path, nr_valid_paths);
+	if (IS_ERR(event))
+		goto out;
+
+	dm_uevent_add(md, &event->elist);
+
+out:
+	dm_put(md);
+}
+EXPORT_SYMBOL_GPL(dm_path_uevent);
+
+int dm_uevent_init(void)
+{
+	_dm_event_cache = KMEM_CACHE(dm_uevent, 0);
+	if (!_dm_event_cache)
+		return -ENOMEM;
+
+	DMINFO("version 1.0.3");
+
+	return 0;
+}
+
+void dm_uevent_exit(void)
+{
+	kmem_cache_destroy(_dm_event_cache);
+}
diff --git a/drivers/md/dm-uevent.h b/drivers/md/dm-uevent.h
new file mode 100644
index 0000000..2eccc8b
--- /dev/null
+++ b/drivers/md/dm-uevent.h
@@ -0,0 +1,59 @@
+/*
+ * Device Mapper Uevent Support
+ *
+ * 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.
+ *
+ * Copyright IBM Corporation, 2007
+ * 	Author: Mike Anderson <andmike@linux.vnet.ibm.com>
+ */
+#ifndef DM_UEVENT_H
+#define DM_UEVENT_H
+
+enum dm_uevent_type {
+	DM_UEVENT_PATH_FAILED,
+	DM_UEVENT_PATH_REINSTATED,
+};
+
+#ifdef CONFIG_DM_UEVENT
+
+extern int dm_uevent_init(void);
+extern void dm_uevent_exit(void);
+extern void dm_send_uevents(struct list_head *events, struct kobject *kobj);
+extern void dm_path_uevent(enum dm_uevent_type event_type,
+			   struct dm_target *ti, const char *path,
+			   unsigned nr_valid_paths);
+
+#else
+
+static inline int dm_uevent_init(void)
+{
+	return 0;
+}
+static inline void dm_uevent_exit(void)
+{
+}
+static inline void dm_send_uevents(struct list_head *events,
+				   struct kobject *kobj)
+{
+}
+static inline void dm_path_uevent(enum dm_uevent_type event_type,
+				  struct dm_target *ti, const char *path,
+				  unsigned nr_valid_paths)
+{
+}
+
+#endif	/* CONFIG_DM_UEVENT */
+
+#endif	/* DM_UEVENT_H */
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index d837d37..07cbbb8 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -7,6 +7,7 @@
 
 #include "dm.h"
 #include "dm-bio-list.h"
+#include "dm-uevent.h"
 
 #include <linux/init.h>
 #include <linux/module.h>
@@ -112,6 +113,9 @@
 	 */
 	atomic_t event_nr;
 	wait_queue_head_t eventq;
+	atomic_t uevent_seq;
+	struct list_head uevent_list;
+	spinlock_t uevent_lock; /* Protect access to uevent_list */
 
 	/*
 	 * freeze/thaw support require holding onto a super block
@@ -143,11 +147,19 @@
 		return -ENOMEM;
 	}
 
+	r = dm_uevent_init();
+	if (r) {
+		kmem_cache_destroy(_tio_cache);
+		kmem_cache_destroy(_io_cache);
+		return r;
+	}
+
 	_major = major;
 	r = register_blkdev(_major, _name);
 	if (r < 0) {
 		kmem_cache_destroy(_tio_cache);
 		kmem_cache_destroy(_io_cache);
+		dm_uevent_exit();
 		return r;
 	}
 
@@ -162,6 +174,7 @@
 	kmem_cache_destroy(_tio_cache);
 	kmem_cache_destroy(_io_cache);
 	unregister_blkdev(_major, _name);
+	dm_uevent_exit();
 
 	_major = 0;
 
@@ -751,15 +764,13 @@
 /*
  * Split the bio into several clones.
  */
-static void __split_bio(struct mapped_device *md, struct bio *bio)
+static int __split_bio(struct mapped_device *md, struct bio *bio)
 {
 	struct clone_info ci;
 
 	ci.map = dm_get_table(md);
-	if (!ci.map) {
-		bio_io_error(bio);
-		return;
-	}
+	if (unlikely(!ci.map))
+		return -EIO;
 
 	ci.md = md;
 	ci.bio = bio;
@@ -779,6 +790,8 @@
 	/* drop the extra reference count */
 	dec_pending(ci.io, 0);
 	dm_table_put(ci.map);
+
+	return 0;
 }
 /*-----------------------------------------------------------------
  * CRUD END
@@ -790,7 +803,7 @@
  */
 static int dm_request(struct request_queue *q, struct bio *bio)
 {
-	int r;
+	int r = -EIO;
 	int rw = bio_data_dir(bio);
 	struct mapped_device *md = q->queuedata;
 
@@ -815,18 +828,11 @@
 	while (test_bit(DMF_BLOCK_IO, &md->flags)) {
 		up_read(&md->io_lock);
 
-		if (bio_rw(bio) == READA) {
-			bio_io_error(bio);
-			return 0;
-		}
+		if (bio_rw(bio) != READA)
+			r = queue_io(md, bio);
 
-		r = queue_io(md, bio);
-		if (r < 0) {
-			bio_io_error(bio);
-			return 0;
-
-		} else if (r == 0)
-			return 0;	/* deferred successfully */
+		if (r <= 0)
+			goto out_req;
 
 		/*
 		 * We're in a while loop, because someone could suspend
@@ -835,8 +841,13 @@
 		down_read(&md->io_lock);
 	}
 
-	__split_bio(md, bio);
+	r = __split_bio(md, bio);
 	up_read(&md->io_lock);
+
+out_req:
+	if (r < 0)
+		bio_io_error(bio);
+
 	return 0;
 }
 
@@ -977,6 +988,9 @@
 	atomic_set(&md->holders, 1);
 	atomic_set(&md->open_count, 0);
 	atomic_set(&md->event_nr, 0);
+	atomic_set(&md->uevent_seq, 0);
+	INIT_LIST_HEAD(&md->uevent_list);
+	spin_lock_init(&md->uevent_lock);
 
 	md->queue = blk_alloc_queue(GFP_KERNEL);
 	if (!md->queue)
@@ -1044,12 +1058,14 @@
 	return NULL;
 }
 
+static void unlock_fs(struct mapped_device *md);
+
 static void free_dev(struct mapped_device *md)
 {
 	int minor = md->disk->first_minor;
 
 	if (md->suspended_bdev) {
-		thaw_bdev(md->suspended_bdev, NULL);
+		unlock_fs(md);
 		bdput(md->suspended_bdev);
 	}
 	mempool_destroy(md->tio_pool);
@@ -1073,8 +1089,16 @@
  */
 static void event_callback(void *context)
 {
+	unsigned long flags;
+	LIST_HEAD(uevents);
 	struct mapped_device *md = (struct mapped_device *) context;
 
+	spin_lock_irqsave(&md->uevent_lock, flags);
+	list_splice_init(&md->uevent_list, &uevents);
+	spin_unlock_irqrestore(&md->uevent_lock, flags);
+
+	dm_send_uevents(&uevents, &md->disk->kobj);
+
 	atomic_inc(&md->event_nr);
 	wake_up(&md->eventq);
 }
@@ -1233,7 +1257,8 @@
 	while (c) {
 		n = c->bi_next;
 		c->bi_next = NULL;
-		__split_bio(md, c);
+		if (__split_bio(md, c))
+			bio_io_error(c);
 		c = n;
 	}
 }
@@ -1491,6 +1516,11 @@
 /*-----------------------------------------------------------------
  * Event notification.
  *---------------------------------------------------------------*/
+uint32_t dm_next_uevent_seq(struct mapped_device *md)
+{
+	return atomic_add_return(1, &md->uevent_seq);
+}
+
 uint32_t dm_get_event_nr(struct mapped_device *md)
 {
 	return atomic_read(&md->event_nr);
@@ -1502,6 +1532,15 @@
 			(event_nr != atomic_read(&md->event_nr)));
 }
 
+void dm_uevent_add(struct mapped_device *md, struct list_head *elist)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&md->uevent_lock, flags);
+	list_add(elist, &md->uevent_list);
+	spin_unlock_irqrestore(&md->uevent_lock, flags);
+}
+
 /*
  * The gendisk is only valid as long as you have a reference
  * count on 'md'.
diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c
index 7e05237..f3831f3 100644
--- a/drivers/md/kcopyd.c
+++ b/drivers/md/kcopyd.c
@@ -198,7 +198,7 @@
 	 * These fields are only used if the job has been split
 	 * into more manageable parts.
 	 */
-	struct semaphore lock;
+	struct mutex lock;
 	atomic_t sub_jobs;
 	sector_t progress;
 };
@@ -456,7 +456,7 @@
 	sector_t count = 0;
 	struct kcopyd_job *job = (struct kcopyd_job *) context;
 
-	down(&job->lock);
+	mutex_lock(&job->lock);
 
 	/* update the error */
 	if (read_err)
@@ -480,7 +480,7 @@
 			job->progress += count;
 		}
 	}
-	up(&job->lock);
+	mutex_unlock(&job->lock);
 
 	if (count) {
 		int i;
@@ -562,7 +562,7 @@
 		dispatch_job(job);
 
 	else {
-		init_MUTEX(&job->lock);
+		mutex_init(&job->lock);
 		job->progress = 0;
 		split_job(job);
 	}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c059ae6..808cd95 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4717,7 +4717,7 @@
 
 void md_unregister_thread(mdk_thread_t *thread)
 {
-	dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
+	dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
 
 	kthread_stop(thread->tsk);
 	kfree(thread);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 16775a0..85478d6 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -9,7 +9,7 @@
  *
  * Better read-balancing code written by Mika Kuoppala <miku@iki.fi>, 2000
  *
- * Fixes to reconstruction by Jakob Østergaard" <jakob@ostenfeld.dk>
+ * Fixes to reconstruction by Jakob Østergaard" <jakob@ostenfeld.dk>
  * Various fixes by Neil Brown <neilb@cse.unsw.edu.au>
  *
  * Changes by Peter T. Breuer <ptb@it.uc3m.es> 31/1/2003 to support
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 8ee181a..80a67d7 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -376,7 +376,12 @@
 		ack++;
 
 	sh->ops.count -= ack;
-	BUG_ON(sh->ops.count < 0);
+	if (unlikely(sh->ops.count < 0)) {
+		printk(KERN_ERR "pending: %#lx ops.pending: %#lx ops.ack: %#lx "
+			"ops.complete: %#lx\n", pending, sh->ops.pending,
+			sh->ops.ack, sh->ops.complete);
+		BUG();
+	}
 
 	return pending;
 }
@@ -550,8 +555,7 @@
 			}
 		}
 	}
-	clear_bit(STRIPE_OP_BIOFILL, &sh->ops.ack);
-	clear_bit(STRIPE_OP_BIOFILL, &sh->ops.pending);
+	set_bit(STRIPE_OP_BIOFILL, &sh->ops.complete);
 
 	return_io(return_bi);
 
@@ -2893,6 +2897,13 @@
 	s.expanded = test_bit(STRIPE_EXPAND_READY, &sh->state);
 	/* Now to look around and see what can be done */
 
+	/* clean-up completed biofill operations */
+	if (test_bit(STRIPE_OP_BIOFILL, &sh->ops.complete)) {
+		clear_bit(STRIPE_OP_BIOFILL, &sh->ops.pending);
+		clear_bit(STRIPE_OP_BIOFILL, &sh->ops.ack);
+		clear_bit(STRIPE_OP_BIOFILL, &sh->ops.complete);
+	}
+
 	rcu_read_lock();
 	for (i=disks; i--; ) {
 		mdk_rdev_t *rdev;
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index aefcf28..185e8a8 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -1074,41 +1074,41 @@
 /* Mike Baikov <mike@baikov.com> */
 IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE] = {
 
-	[ 0x21 ] = KEY_POWER,
-	[ 0x69 ] = KEY_TV,
-	[ 0x33 ] = KEY_0,
-	[ 0x51 ] = KEY_1,
-	[ 0x31 ] = KEY_2,
-	[ 0x71 ] = KEY_3,
-	[ 0x3b ] = KEY_4,
-	[ 0x58 ] = KEY_5,
-	[ 0x41 ] = KEY_6,
-	[ 0x48 ] = KEY_7,
-	[ 0x30 ] = KEY_8,
-	[ 0x53 ] = KEY_9,
-	[ 0x73 ] = KEY_AGAIN, /* LOOP */
-	[ 0x0a ] = KEY_AUDIO,
-	[ 0x61 ] = KEY_PRINT, /* PREVIEW */
-	[ 0x7a ] = KEY_VIDEO,
-	[ 0x20 ] = KEY_CHANNELUP,
-	[ 0x40 ] = KEY_CHANNELDOWN,
-	[ 0x18 ] = KEY_VOLUMEDOWN,
-	[ 0x50 ] = KEY_VOLUMEUP,
-	[ 0x10 ] = KEY_MUTE,
-	[ 0x4a ] = KEY_SEARCH,
-	[ 0x7b ] = KEY_SHUFFLE, /* SNAPSHOT */
-	[ 0x22 ] = KEY_RECORD,
-	[ 0x62 ] = KEY_STOP,
-	[ 0x78 ] = KEY_PLAY,
-	[ 0x39 ] = KEY_REWIND,
-	[ 0x59 ] = KEY_PAUSE,
-	[ 0x19 ] = KEY_FORWARD,
-	[ 0x09 ] = KEY_ZOOM,
+	[ 0x11 ] = KEY_POWER,
+	[ 0x35 ] = KEY_TV,
+	[ 0x1b ] = KEY_0,
+	[ 0x29 ] = KEY_1,
+	[ 0x19 ] = KEY_2,
+	[ 0x39 ] = KEY_3,
+	[ 0x1f ] = KEY_4,
+	[ 0x2c ] = KEY_5,
+	[ 0x21 ] = KEY_6,
+	[ 0x24 ] = KEY_7,
+	[ 0x18 ] = KEY_8,
+	[ 0x2b ] = KEY_9,
+	[ 0x3b ] = KEY_AGAIN, /* LOOP */
+	[ 0x06 ] = KEY_AUDIO,
+	[ 0x31 ] = KEY_PRINT, /* PREVIEW */
+	[ 0x3e ] = KEY_VIDEO,
+	[ 0x10 ] = KEY_CHANNELUP,
+	[ 0x20 ] = KEY_CHANNELDOWN,
+	[ 0x0c ] = KEY_VOLUMEDOWN,
+	[ 0x28 ] = KEY_VOLUMEUP,
+	[ 0x08 ] = KEY_MUTE,
+	[ 0x26 ] = KEY_SEARCH, /*SCAN*/
+	[ 0x3f ] = KEY_SHUFFLE, /* SNAPSHOT */
+	[ 0x12 ] = KEY_RECORD,
+	[ 0x32 ] = KEY_STOP,
+	[ 0x3c ] = KEY_PLAY,
+	[ 0x1d ] = KEY_REWIND,
+	[ 0x2d ] = KEY_PAUSE,
+	[ 0x0d ] = KEY_FORWARD,
+	[ 0x05 ] = KEY_ZOOM,  /*FULL*/
 
-	[ 0x52 ] = KEY_F21, /* LIVE TIMESHIFT */
-	[ 0x1a ] = KEY_F22, /* MIN TIMESHIFT */
-	[ 0x3a ] = KEY_F23, /* TIMESHIFT */
-	[ 0x70 ] = KEY_F24, /* NORMAL TIMESHIFT */
+	[ 0x2a ] = KEY_F21, /* LIVE TIMESHIFT */
+	[ 0x0e ] = KEY_F22, /* MIN TIMESHIFT */
+	[ 0x1e ] = KEY_F23, /* TIMESHIFT */
+	[ 0x38 ] = KEY_F24, /* NORMAL TIMESHIFT */
 };
 
 EXPORT_SYMBOL_GPL(ir_codes_gotview7135);
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 365a221..2b1f8b4 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -112,12 +112,13 @@
 	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sglist[i].page   = pg;
+		sg_set_page(&sglist[i], pg);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c
index d290572..9c90539 100644
--- a/drivers/media/common/saa7146_hlp.c
+++ b/drivers/media/common/saa7146_hlp.c
@@ -312,7 +312,7 @@
 		return -EINVAL;
 	}
 
-	/* bubble sort the first ´count´ items of the array ´values´ */
+	/* bubble sort the first @count items of the array @values */
 	for( top = *count; top > 0; top--) {
 		for( low = 0, high = 1; high < top; low++, high++) {
 			if( values[low] > values[high] ) {
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index eca602d..85e36a1d 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -280,7 +280,7 @@
 		if (!(astat = (stat & mask)))
 			return IRQ_NONE;	/* this interrupt is not for me */
 /*		dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */
-		btwrite(astat, BT878_AINT_STAT);	/* try to clear interupt condition */
+		btwrite(astat, BT878_AINT_STAT);	/* try to clear interrupt condition */
 
 
 		if (astat & (BT878_ASCERR | BT878_AOCERR)) {
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 5a12b56..db08b0a 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -1,5 +1,5 @@
 /*
- * TerraTec Cinergy T²/qanu USB2 DVB-T adapter.
+ * TerraTec Cinergy T²/qanu USB2 DVB-T adapter.
  *
  * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
  *		    Holger Waechtler <holger@qanu.de>
@@ -345,7 +345,9 @@
 	struct dvb_demux *demux = dvbdmxfeed->demux;
 	struct cinergyt2 *cinergyt2 = demux->priv;
 
-	if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
+	if (cinergyt2->disconnect_pending)
+		return -EAGAIN;
+	if (mutex_lock_interruptible(&cinergyt2->sem))
 		return -ERESTARTSYS;
 
 	if (cinergyt2->streaming == 0)
@@ -361,7 +363,9 @@
 	struct dvb_demux *demux = dvbdmxfeed->demux;
 	struct cinergyt2 *cinergyt2 = demux->priv;
 
-	if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
+	if (cinergyt2->disconnect_pending)
+		return -EAGAIN;
+	if (mutex_lock_interruptible(&cinergyt2->sem))
 		return -ERESTARTSYS;
 
 	if (--cinergyt2->streaming == 0)
@@ -481,12 +485,16 @@
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct cinergyt2 *cinergyt2 = dvbdev->priv;
-	int err = -ERESTARTSYS;
+	int err = -EAGAIN;
 
-	if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem))
+	if (cinergyt2->disconnect_pending)
+		goto out;
+	err = mutex_lock_interruptible(&cinergyt2->wq_sem);
+	if (err)
 		goto out;
 
-	if (mutex_lock_interruptible(&cinergyt2->sem))
+	err = mutex_lock_interruptible(&cinergyt2->sem);
+	if (err)
 		goto out_unlock1;
 
 	if ((err = dvb_generic_open(inode, file)))
@@ -550,7 +558,9 @@
 	struct cinergyt2 *cinergyt2 = dvbdev->priv;
 	unsigned int mask = 0;
 
-	if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
+	if (cinergyt2->disconnect_pending)
+		return -EAGAIN;
+	if (mutex_lock_interruptible(&cinergyt2->sem))
 		return -ERESTARTSYS;
 
 	poll_wait(file, &cinergyt2->poll_wq, wait);
@@ -625,7 +635,9 @@
 		if (copy_from_user(&p, (void  __user*) arg, sizeof(p)))
 			return -EFAULT;
 
-		if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
+		if (cinergyt2->disconnect_pending)
+			return -EAGAIN;
+		if (mutex_lock_interruptible(&cinergyt2->sem))
 			return -ERESTARTSYS;
 
 		param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
@@ -820,7 +832,7 @@
 
 	input_dev->name = DRIVER_NAME " remote control";
 	input_dev->phys = cinergyt2->phys;
-	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 	for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3)
 		set_bit(rc_keys[i + 2], input_dev->keybit);
 	input_dev->keycodesize = 0;
@@ -996,7 +1008,9 @@
 {
 	struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
 
-	if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem))
+	if (cinergyt2->disconnect_pending)
+		return -EAGAIN;
+	if (mutex_lock_interruptible(&cinergyt2->wq_sem))
 		return -ERESTARTSYS;
 
 	cinergyt2_suspend_rc(cinergyt2);
@@ -1017,16 +1031,18 @@
 {
 	struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
 	struct dvbt_set_parameters_msg *param = &cinergyt2->param;
-	int err = -ERESTARTSYS;
+	int err = -EAGAIN;
 
-	if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem))
+	if (cinergyt2->disconnect_pending)
+		goto out;
+	err = mutex_lock_interruptible(&cinergyt2->wq_sem);
+	if (err)
 		goto out;
 
-	if (mutex_lock_interruptible(&cinergyt2->sem))
+	err = mutex_lock_interruptible(&cinergyt2->sem);
+	if (err)
 		goto out_unlock1;
 
-	err = 0;
-
 	if (!cinergyt2->sleeping) {
 		cinergyt2_sleep(cinergyt2, 0);
 		cinergyt2_command(cinergyt2, (char *) param, sizeof(*param), NULL, 0);
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 084a508..89437fd 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -972,7 +972,7 @@
 	/* main loop */
 	while (!kthread_should_stop()) {
 		/* sleep for a bit */
-		while (!ca->wakeup) {
+		if (!ca->wakeup) {
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(ca->delay);
 			if (kthread_should_stop())
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index b203640..445f026 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -527,7 +527,8 @@
 		up(&fepriv->sem);	    /* is locked when we enter the thread... */
 restart:
 		timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
-			dvb_frontend_should_wakeup(fe) || kthread_should_stop(),
+			dvb_frontend_should_wakeup(fe) || kthread_should_stop()
+				|| freezing(current),
 			fepriv->delay);
 
 		if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index e8c4a86..58452b5 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -828,7 +828,7 @@
 #define DIB0700_DEFAULT_DEVICE_PROPERTIES \
 	.caps              = DVB_USB_IS_AN_I2C_ADAPTER, \
 	.usb_ctrl          = DEVICE_SPECIFIC, \
-	.firmware          = "dvb-usb-dib0700-03-pre1.fw", \
+	.firmware          = "dvb-usb-dib0700-1.10.fw", \
 	.download_firmware = dib0700_download_firmware, \
 	.no_reconnect      = 1, \
 	.size_of_priv      = sizeof(struct dib0700_state), \
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index 7b9f35b..c0c2c22 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -106,7 +106,7 @@
 	if (!input_dev)
 		return -ENOMEM;
 
-	input_dev->evbit[0] = BIT(EV_KEY);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY);
 	input_dev->name = "IR-receiver inside an USB DVB receiver";
 	input_dev->phys = d->rc_phys;
 	usb_to_input_id(d->udev, &input_dev->id);
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index 5d19c40..a283e1d 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -27,7 +27,7 @@
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/kernel.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 #include "av7110.h"
 #include "av7110_hw.h"
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 288e79f..7902ae1 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -128,7 +128,7 @@
 	struct dvb_frontend* fe;
 };
 
-/* ugly workaround ... don't know why it's neccessary to read */
+/* ugly workaround ... don't know why it's necessary to read */
 /* all result codes. */
 
 #define DEBUG 0
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 5e691fd..1ec981d 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1198,7 +1198,7 @@
 
 	input_dev->name = "ttusb_dec remote control";
 	input_dev->phys = dec->rc_phys;
-	input_dev->evbit[0] = BIT(EV_KEY);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY);
 	input_dev->keycodesize = sizeof(u16);
 	input_dev->keycodemax = 0x1a;
 	input_dev->keycode = rc_keys;
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
index c7c9d1d..3ae56fe 100644
--- a/drivers/media/radio/miropcm20-radio.c
+++ b/drivers/media/radio/miropcm20-radio.c
@@ -229,7 +229,6 @@
 	.owner		= THIS_MODULE,
 	.name		= "Miro PCM 20 radio",
 	.type		= VID_TYPE_TUNER,
-	.hardware	= VID_HARDWARE_RTRACK,
 	.fops           = &pcm20_fops,
 	.priv		= &pcm20_unit
 };
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 0c963db..5e4b9dd 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -554,7 +554,6 @@
 	.owner			= THIS_MODULE,
 	.name			= "GemTek Radio card",
 	.type			= VID_TYPE_TUNER,
-	.hardware		= VID_HARDWARE_GEMTEK,
 	.fops			= &gemtek_fops,
 	.vidioc_querycap	= vidioc_querycap,
 	.vidioc_g_tuner		= vidioc_g_tuner,
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 19e9929..c94a4d0 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -755,7 +755,6 @@
 	.owner		= THIS_MODULE,
 	.name		= "Colour AR VGA",
 	.type		= VID_TYPE_CAPTURE,
-	.hardware	= VID_HARDWARE_ARV,
 	.fops		= &ar_fops,
 	.release	= ar_release,
 	.minor		= -1,
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index dd6a7d6..3abd9fa 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -1259,7 +1259,7 @@
 		.has_radio	= 1,
 	},
 	[BTTV_BOARD_LIFETEC_9415] = {
-		/* Tim Röstermundt <rosterm@uni-muenster.de>
+		/* Tim Röstermundt <rosterm@uni-muenster.de>
 		in de.comp.os.unix.linux.hardware:
 			options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
 			gpiomux =0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
@@ -2824,7 +2824,7 @@
 	},
 		/* ---- card 0x8b ---------------------------------- */
 	[BTTV_BOARD_PV_M4900] = {
-		/* Sérgio Fortier <sergiofortier@yahoo.com.br> */
+		/* Sérgio Fortier <sergiofortier@yahoo.com.br> */
 		.name           = "Prolink PixelView PlayTV MPEG2 PV-M4900",
 		.video_inputs   = 3,
 		.audio_inputs   = 1,
@@ -4709,18 +4709,18 @@
  *
  * The board hardwire Y0 (xpoint) to MUX1 and MUXOUT to Yin.
  * GPIO pins are wired as:
- *  GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroler)
- *  GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroler)
- *  GPIO[7]   - DATA (xpoint)    - P1[7] (microcontroler)
- *  GPIO[8]   -                  - P3[5] (microcontroler)
- *  GPIO[9]   - RESET (xpoint)   - P3[6] (microcontroler)
- *  GPIO[10]  - STROBE (xpoint)  - P3[7] (microcontroler)
- *  GPINTR    -                  - P3[4] (microcontroler)
+ *  GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroller)
+ *  GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroller)
+ *  GPIO[7]   - DATA (xpoint)    - P1[7] (microcontroller)
+ *  GPIO[8]   -                  - P3[5] (microcontroller)
+ *  GPIO[9]   - RESET (xpoint)   - P3[6] (microcontroller)
+ *  GPIO[10]  - STROBE (xpoint)  - P3[7] (microcontroller)
+ *  GPINTR    -                  - P3[4] (microcontroller)
  *
- * The microcontroler is a 80C32 like. It should be possible to change xpoint
- * configuration either directly (as we are doing) or using the microcontroler
+ * The microcontroller is a 80C32 like. It should be possible to change xpoint
+ * configuration either directly (as we are doing) or using the microcontroller
  * which is also wired to I2C interface. I have no further info on the
- * microcontroler features, one would need to disassembly the firmware.
+ * microcontroller features, one would need to disassembly the firmware.
  * note: the vendor refused to give any information on this product, all
  *       that stuff was found using a multimeter! :)
  */
@@ -4788,7 +4788,7 @@
  * The analog switch is controlled by the "master", but the detection order
  * of the four BT878A chips is in an order which I just don't understand.
  * The "master" is actually the second controller to be detected.  The
- * logic on the board uses logical numbers for the 4 controlers, but
+ * logic on the board uses logical numbers for the 4 controllers, but
  * those numbers are different from the detection sequence.  When working
  * with the analog switch, we need to "map" from the detection sequence
  * over to the board's logical controller number.  This mapping sequence
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 7a332b3..9feeb63 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -3877,7 +3877,6 @@
 	.name     = "UNSET",
 	.type     = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
 		    VID_TYPE_CLIPPING|VID_TYPE_SCALES,
-	.hardware = VID_HARDWARE_BT848,
 	.fops     = &bttv_fops,
 	.minor    = -1,
 };
@@ -3886,7 +3885,6 @@
 {
 	.name     = "bt848/878 vbi",
 	.type     = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
-	.hardware = VID_HARDWARE_BT848,
 	.fops     = &bttv_fops,
 	.minor    = -1,
 };
@@ -4034,7 +4032,6 @@
 {
 	.name     = "bt848/878 radio",
 	.type     = VID_TYPE_TUNER,
-	.hardware = VID_HARDWARE_BT848,
 	.fops     = &radio_fops,
 	.minor    = -1,
 };
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index 7f7e3d3..5842352 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -899,7 +899,6 @@
 	.owner		= THIS_MODULE,
 	.name		= "Connectix Quickcam",
 	.type		= VID_TYPE_CAPTURE,
-	.hardware	= VID_HARDWARE_QCAM_BW,
 	.fops           = &qcam_fops,
 };
 
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index f76c6a6..cf1546b 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -699,7 +699,6 @@
 	.owner		= THIS_MODULE,
 	.name		= "Colour QuickCam",
 	.type		= VID_TYPE_CAPTURE,
-	.hardware	= VID_HARDWARE_QCAM_C,
 	.fops           = &qcam_fops,
 };
 
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index a1d02e5..7c630f5 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -65,10 +65,6 @@
 
 #define ABOUT "V4L-Driver for Vision CPiA based cameras"
 
-#ifndef VID_HARDWARE_CPIA
-#define VID_HARDWARE_CPIA 24    /* FIXME -> from linux/videodev.h */
-#endif
-
 #define CPIA_MODULE_CPIA			(0<<5)
 #define CPIA_MODULE_SYSTEM			(1<<5)
 #define CPIA_MODULE_VP_CTRL			(5<<5)
@@ -3804,7 +3800,6 @@
 	.owner		= THIS_MODULE,
 	.name		= "CPiA Camera",
 	.type		= VID_TYPE_CAPTURE,
-	.hardware	= VID_HARDWARE_CPIA,
 	.fops           = &cpia_fops,
 };
 
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index e3aaba1..e378abe 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -86,10 +86,6 @@
 
 #define ABOUT "V4L-Driver for Vision CPiA2 based cameras"
 
-#ifndef VID_HARDWARE_CPIA2
-#error "VID_HARDWARE_CPIA2 should have been defined in linux/videodev.h"
-#endif
-
 struct control_menu_info {
 	int value;
 	char name[32];
@@ -1942,7 +1938,6 @@
 	.type=		VID_TYPE_CAPTURE,
 	.type2 = 	V4L2_CAP_VIDEO_CAPTURE |
 			V4L2_CAP_STREAMING,
-	.hardware=	VID_HARDWARE_CPIA2,
 	.minor=		-1,
 	.fops=		&fops_template,
 	.release=	video_device_release,
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index af16505..3cdd136 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -793,7 +793,7 @@
 		       dev->pci->subsystem_device);
 
 		cx23885_devcount--;
-		goto fail_free;
+		return -ENODEV;
 	}
 
 	/* PCIe stuff */
@@ -835,10 +835,6 @@
 	}
 
 	return 0;
-
-fail_free:
-	kfree(dev);
-	return -ENODEV;
 }
 
 void cx23885_dev_unregister(struct cx23885_dev *dev)
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 141dadf..40ffd7a 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -39,6 +39,7 @@
 #include <sound/pcm_params.h>
 #include <sound/control.h>
 #include <sound/initval.h>
+#include <sound/tlv.h>
 
 #include "cx88.h"
 #include "cx88-reg.h"
@@ -82,6 +83,7 @@
 
 
 
+
 /****************************************************************************
 			Module global static vars
  ****************************************************************************/
@@ -545,8 +547,8 @@
 /****************************************************************************
 				CONTROL INTERFACE
  ****************************************************************************/
-static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol,
-					struct snd_ctl_elem_info *info)
+static int snd_cx88_volume_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *info)
 {
 	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	info->count = 2;
@@ -556,9 +558,8 @@
 	return 0;
 }
 
-/* OK - TODO: test it */
-static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol,
-				       struct snd_ctl_elem_value *value)
+static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *value)
 {
 	snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
 	struct cx88_core *core=chip->core;
@@ -573,8 +574,8 @@
 }
 
 /* OK - TODO: test it */
-static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol,
-				       struct snd_ctl_elem_value *value)
+static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *value)
 {
 	snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
 	struct cx88_core *core=chip->core;
@@ -605,14 +606,67 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new snd_cx88_capture_volume = {
+static const DECLARE_TLV_DB_SCALE(snd_cx88_db_scale, -6300, 100, 0);
+
+static struct snd_kcontrol_new snd_cx88_volume = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "Capture Volume",
-	.info = snd_cx88_capture_volume_info,
-	.get = snd_cx88_capture_volume_get,
-	.put = snd_cx88_capture_volume_put,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+		  SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+	.name = "Playback Volume",
+	.info = snd_cx88_volume_info,
+	.get = snd_cx88_volume_get,
+	.put = snd_cx88_volume_put,
+	.tlv.p = snd_cx88_db_scale,
 };
 
+static int snd_cx88_switch_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *value)
+{
+	snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
+	struct cx88_core *core = chip->core;
+	u32 bit = kcontrol->private_value;
+
+	value->value.integer.value[0] = !(cx_read(AUD_VOL_CTL) & bit);
+	return 0;
+}
+
+static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *value)
+{
+	snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
+	struct cx88_core *core = chip->core;
+	u32 bit = kcontrol->private_value;
+	int ret = 0;
+	u32 vol;
+
+	spin_lock_irq(&chip->reg_lock);
+	vol = cx_read(AUD_VOL_CTL);
+	if (value->value.integer.value[0] != !(vol & bit)) {
+		vol ^= bit;
+		cx_write(AUD_VOL_CTL, vol);
+		ret = 1;
+	}
+	spin_unlock_irq(&chip->reg_lock);
+	return ret;
+}
+
+static struct snd_kcontrol_new snd_cx88_dac_switch = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Playback Switch",
+	.info = snd_ctl_boolean_mono_info,
+	.get = snd_cx88_switch_get,
+	.put = snd_cx88_switch_put,
+	.private_value = (1<<8),
+};
+
+static struct snd_kcontrol_new snd_cx88_source_switch = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Capture Switch",
+	.info = snd_ctl_boolean_mono_info,
+	.get = snd_cx88_switch_get,
+	.put = snd_cx88_switch_put,
+	.private_value = (1<<6),
+};
 
 /****************************************************************************
 			Basic Flow for Sound Devices
@@ -762,7 +816,13 @@
 	if (err < 0)
 		goto error;
 
-	err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_capture_volume, chip));
+	err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_volume, chip));
+	if (err < 0)
+		goto error;
+	err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_dac_switch, chip));
+	if (err < 0)
+		goto error;
+	err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_source_switch, chip));
 	if (err < 0)
 		goto error;
 
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 6d6f504..f33f0b4 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -527,44 +527,6 @@
 	cx2341x_update(dev, blackbird_mbox_func, NULL, &dev->params);
 }
 
-static struct v4l2_mpeg_compression default_mpeg_params = {
-	.st_type          = V4L2_MPEG_PS_2,
-	.st_bitrate       = {
-		.mode     = V4L2_BITRATE_CBR,
-		.min      = 0,
-		.target   = 0,
-		.max      = 0
-	},
-	.ts_pid_pmt       = 16,
-	.ts_pid_audio     = 260,
-	.ts_pid_video     = 256,
-	.ts_pid_pcr       = 259,
-	.ps_size          = 0,
-	.au_type          = V4L2_MPEG_AU_2_II,
-	.au_bitrate       = {
-		.mode     = V4L2_BITRATE_CBR,
-		.min      = 224,
-		.target   = 224,
-		.max      = 224
-	},
-	.au_sample_rate    = 48000,
-	.au_pesid          = 0,
-	.vi_type           = V4L2_MPEG_VI_2,
-	.vi_aspect_ratio   = V4L2_MPEG_ASPECT_4_3,
-	.vi_bitrate        = {
-		.mode      = V4L2_BITRATE_CBR,
-		.min       = 4000,
-		.target    = 4500,
-		.max       = 6000
-	},
-	.vi_frame_rate     = 25,
-	.vi_frames_per_gop = 12,
-	.vi_bframes_count  = 2,
-	.vi_pesid          = 0,
-	.closed_gops       = 1,
-	.pulldown          = 0
-};
-
 static int blackbird_initialize_codec(struct cx8802_dev *dev)
 {
 	struct cx88_core *core = dev->core;
@@ -852,23 +814,6 @@
 	return videobuf_streamoff(&fh->mpegq);
 }
 
-static int vidioc_g_mpegcomp (struct file *file, void *fh,
-			      struct v4l2_mpeg_compression *f)
-{
-	printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. "
-				"Replace with VIDIOC_G_EXT_CTRLS!");
-	memcpy(f,&default_mpeg_params,sizeof(*f));
-	return 0;
-}
-
-static int vidioc_s_mpegcomp (struct file *file, void *fh,
-			      struct v4l2_mpeg_compression *f)
-{
-	printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. "
-				"Replace with VIDIOC_S_EXT_CTRLS!");
-	return 0;
-}
-
 static int vidioc_g_ext_ctrls (struct file *file, void *priv,
 			       struct v4l2_ext_controls *f)
 {
@@ -1216,8 +1161,6 @@
 	.vidioc_dqbuf         = vidioc_dqbuf,
 	.vidioc_streamon      = vidioc_streamon,
 	.vidioc_streamoff     = vidioc_streamoff,
-	.vidioc_g_mpegcomp    = vidioc_g_mpegcomp,
-	.vidioc_s_mpegcomp    = vidioc_s_mpegcomp,
 	.vidioc_g_ext_ctrls   = vidioc_g_ext_ctrls,
 	.vidioc_s_ext_ctrls   = vidioc_s_ext_ctrls,
 	.vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index d16e5c6..fce19ca 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -475,8 +475,9 @@
 		break;
 	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
 #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
+		/* MT352 is on a secondary I2C bus made from some GPIO lines */
 		dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
-			&((struct vp3054_i2c_state *)dev->card_priv)->adap);
+					       &dev->vp3054->adap);
 		if (dev->dvb.frontend != NULL) {
 			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
 				   &dev->core->i2c_adap, DVB_PLL_FMD1216ME);
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index a652f29..448c673 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -79,7 +79,8 @@
 {
 	struct cx88_core *core = dev->core;
 
-	dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field);
+	dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n",
+		buf->vb.width, buf->vb.height, buf->vb.field);
 
 	/* setup fifo + format */
 	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -177,7 +178,6 @@
 				struct cx88_dmaqueue *q)
 {
 	struct cx88_buffer *buf;
-	struct list_head *item;
 
 	dprintk( 1, "cx8802_restart_queue\n" );
 	if (list_empty(&q->active))
@@ -223,10 +223,8 @@
 	dprintk(2,"restart_queue [%p/%d]: restart dma\n",
 		buf, buf->vb.i);
 	cx8802_start_dma(dev, q, buf);
-	list_for_each(item,&q->active) {
-		buf = list_entry(item, struct cx88_buffer, vb.queue);
+	list_for_each_entry(buf, &q->active, vb.queue)
 		buf->count = q->count++;
-	}
 	mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
 	return 0;
 }
@@ -572,42 +570,29 @@
 	return 0;
 }
 
+#if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \
+    defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE)
 struct cx8802_dev * cx8802_get_device(struct inode *inode)
 {
 	int minor = iminor(inode);
-	struct cx8802_dev *h = NULL;
-	struct list_head *list;
+	struct cx8802_dev *dev;
 
-	list_for_each(list,&cx8802_devlist) {
-		h = list_entry(list, struct cx8802_dev, devlist);
-		if (h->mpeg_dev && h->mpeg_dev->minor == minor)
-			return h;
-	}
+	list_for_each_entry(dev, &cx8802_devlist, devlist)
+		if (dev->mpeg_dev && dev->mpeg_dev->minor == minor)
+			return dev;
 
 	return NULL;
 }
+EXPORT_SYMBOL(cx8802_get_device);
+#endif
 
 struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype)
 {
-	struct cx8802_dev *h = NULL;
-	struct cx8802_driver *d = NULL;
-	struct list_head *list;
-	struct list_head *list2;
+	struct cx8802_driver *d;
 
-	list_for_each(list,&cx8802_devlist) {
-		h = list_entry(list, struct cx8802_dev, devlist);
-		if (h != dev)
-			continue;
-
-		list_for_each(list2, &h->drvlist.devlist) {
-			d = list_entry(list2, struct cx8802_driver, devlist);
-
-			/* only unregister the correct driver type */
-			if (d->type_id == btype) {
-				return d;
-			}
-		}
-	}
+	list_for_each_entry(d, &dev->drvlist, drvlist)
+		if (d->type_id == btype)
+			return d;
 
 	return NULL;
 }
@@ -671,10 +656,9 @@
 
 int cx8802_register_driver(struct cx8802_driver *drv)
 {
-	struct cx8802_dev *h;
+	struct cx8802_dev *dev;
 	struct cx8802_driver *driver;
-	struct list_head *list;
-	int err = 0, i = 0;
+	int err, i = 0;
 
 	printk(KERN_INFO
 	       "cx88/2: registering cx8802 driver, type: %s access: %s\n",
@@ -686,14 +670,12 @@
 		return err;
 	}
 
-	list_for_each(list,&cx8802_devlist) {
-		h = list_entry(list, struct cx8802_dev, devlist);
-
+	list_for_each_entry(dev, &cx8802_devlist, devlist) {
 		printk(KERN_INFO
 		       "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
-		       h->core->name, h->pci->subsystem_vendor,
-		       h->pci->subsystem_device, h->core->board.name,
-		       h->core->boardnr);
+		       dev->core->name, dev->pci->subsystem_vendor,
+		       dev->pci->subsystem_device, dev->core->board.name,
+		       dev->core->boardnr);
 
 		/* Bring up a new struct for each driver instance */
 		driver = kzalloc(sizeof(*drv),GFP_KERNEL);
@@ -701,7 +683,7 @@
 			return -ENOMEM;
 
 		/* Snapshot of the driver registration data */
-		drv->core = h->core;
+		drv->core = dev->core;
 		drv->suspend = cx8802_suspend_common;
 		drv->resume = cx8802_resume_common;
 		drv->request_acquire = cx8802_request_acquire;
@@ -712,49 +694,38 @@
 		if (err == 0) {
 			i++;
 			mutex_lock(&drv->core->lock);
-			list_add_tail(&driver->devlist,&h->drvlist.devlist);
+			list_add_tail(&driver->drvlist, &dev->drvlist);
 			mutex_unlock(&drv->core->lock);
 		} else {
 			printk(KERN_ERR
 			       "%s/2: cx8802 probe failed, err = %d\n",
-			       h->core->name, err);
+			       dev->core->name, err);
 		}
 
 	}
-	if (i == 0)
-		err = -ENODEV;
-	else
-		err = 0;
 
-	return err;
+	return i ? 0 : -ENODEV;
 }
 
 int cx8802_unregister_driver(struct cx8802_driver *drv)
 {
-	struct cx8802_dev *h;
-	struct cx8802_driver *d;
-	struct list_head *list;
-	struct list_head *list2, *q;
-	int err = 0, i = 0;
+	struct cx8802_dev *dev;
+	struct cx8802_driver *d, *dtmp;
+	int err = 0;
 
 	printk(KERN_INFO
 	       "cx88/2: unregistering cx8802 driver, type: %s access: %s\n",
 	       drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
 	       drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
 
-	list_for_each(list,&cx8802_devlist) {
-		i++;
-		h = list_entry(list, struct cx8802_dev, devlist);
-
+	list_for_each_entry(dev, &cx8802_devlist, devlist) {
 		printk(KERN_INFO
 		       "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
-		       h->core->name, h->pci->subsystem_vendor,
-		       h->pci->subsystem_device, h->core->board.name,
-		       h->core->boardnr);
+		       dev->core->name, dev->pci->subsystem_vendor,
+		       dev->pci->subsystem_device, dev->core->board.name,
+		       dev->core->boardnr);
 
-		list_for_each_safe(list2, q, &h->drvlist.devlist) {
-			d = list_entry(list2, struct cx8802_driver, devlist);
-
+		list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) {
 			/* only unregister the correct driver type */
 			if (d->type_id != drv->type_id)
 				continue;
@@ -762,12 +733,12 @@
 			err = d->remove(d);
 			if (err == 0) {
 				mutex_lock(&drv->core->lock);
-				list_del(list2);
+				list_del(&d->drvlist);
 				mutex_unlock(&drv->core->lock);
+				kfree(d);
 			} else
 				printk(KERN_ERR "%s/2: cx8802 driver remove "
-				       "failed (%d)\n", h->core->name, err);
-
+				       "failed (%d)\n", dev->core->name, err);
 		}
 
 	}
@@ -805,7 +776,7 @@
 	if (err != 0)
 		goto fail_free;
 
-	INIT_LIST_HEAD(&dev->drvlist.devlist);
+	INIT_LIST_HEAD(&dev->drvlist);
 	list_add_tail(&dev->devlist,&cx8802_devlist);
 
 	/* Maintain a reference so cx88-video can query the 8802 device. */
@@ -825,23 +796,30 @@
 static void __devexit cx8802_remove(struct pci_dev *pci_dev)
 {
 	struct cx8802_dev *dev;
-	struct cx8802_driver *h;
-	struct list_head *list;
 
 	dev = pci_get_drvdata(pci_dev);
 
 	dprintk( 1, "%s\n", __FUNCTION__);
 
-	list_for_each(list,&dev->drvlist.devlist) {
-		h = list_entry(list, struct cx8802_driver, devlist);
-		dprintk( 1, " ->driver\n");
-		if (h->remove == NULL) {
-			printk(KERN_ERR "%s .. skipping driver, no probe function\n", __FUNCTION__);
-			continue;
+	if (!list_empty(&dev->drvlist)) {
+		struct cx8802_driver *drv, *tmp;
+		int err;
+
+		printk(KERN_WARNING "%s/2: Trying to remove cx8802 driver "
+		       "while cx8802 sub-drivers still loaded?!\n",
+		       dev->core->name);
+
+		list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) {
+			err = drv->remove(drv);
+			if (err == 0) {
+				mutex_lock(&drv->core->lock);
+				list_del(&drv->drvlist);
+				mutex_unlock(&drv->core->lock);
+			} else
+				printk(KERN_ERR "%s/2: cx8802 driver remove "
+				       "failed (%d)\n", dev->core->name, err);
+			kfree(drv);
 		}
-		printk(KERN_INFO "%s .. Removing driver type %d\n", __FUNCTION__, h->type_id);
-		cx8802_unregister_driver(h);
-		list_del(&dev->drvlist.devlist);
 	}
 
 	/* Destroy any 8802 reference. */
@@ -901,7 +879,6 @@
 
 EXPORT_SYMBOL(cx8802_register_driver);
 EXPORT_SYMBOL(cx8802_unregister_driver);
-EXPORT_SYMBOL(cx8802_get_device);
 EXPORT_SYMBOL(cx8802_get_driver);
 /* ----------------------------------------------------------- */
 /*
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 231ae6c..5ee05f8 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1675,7 +1675,6 @@
 {
 	.name                 = "cx8800-radio",
 	.type                 = VID_TYPE_TUNER,
-	.hardware             = 0,
 	.fops                 = &radio_fops,
 	.minor                = -1,
 	.vidioc_querycap      = radio_querycap,
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c
index 77c3788..6ce5af4 100644
--- a/drivers/media/video/cx88/cx88-vp3054-i2c.c
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c
@@ -41,7 +41,7 @@
 {
 	struct cx8802_dev *dev = data;
 	struct cx88_core *core = dev->core;
-	struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
+	struct vp3054_i2c_state *vp3054_i2c = dev->vp3054;
 
 	if (state) {
 		vp3054_i2c->state |=  0x0001;	/* SCL high */
@@ -58,7 +58,7 @@
 {
 	struct cx8802_dev *dev = data;
 	struct cx88_core *core = dev->core;
-	struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
+	struct vp3054_i2c_state *vp3054_i2c = dev->vp3054;
 
 	if (state) {
 		vp3054_i2c->state |=  0x0002;	/* SDA high */
@@ -113,10 +113,10 @@
 	if (core->boardnr != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
 		return 0;
 
-	dev->card_priv = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL);
-	if (dev->card_priv == NULL)
+	vp3054_i2c = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL);
+	if (vp3054_i2c == NULL)
 		return -ENOMEM;
-	vp3054_i2c = dev->card_priv;
+	dev->vp3054 = vp3054_i2c;
 
 	memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template,
 	       sizeof(vp3054_i2c->algo));
@@ -139,8 +139,8 @@
 	if (0 != rc) {
 		printk("%s: vp3054_i2c register FAILED\n", core->name);
 
-		kfree(dev->card_priv);
-		dev->card_priv = NULL;
+		kfree(dev->vp3054);
+		dev->vp3054 = NULL;
 	}
 
 	return rc;
@@ -148,7 +148,7 @@
 
 void vp3054_i2c_remove(struct cx8802_dev *dev)
 {
-	struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
+	struct vp3054_i2c_state *vp3054_i2c = dev->vp3054;
 
 	if (vp3054_i2c == NULL ||
 	    dev->core->boardnr != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 42e0a9b..eb296bd 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -412,7 +412,9 @@
 
 struct cx8802_driver {
 	struct cx88_core *core;
-	struct list_head devlist;
+
+	/* List of drivers attached to device */
+	struct list_head drvlist;
 
 	/* Type of driver and access required */
 	enum cx88_board_type type_id;
@@ -453,27 +455,33 @@
 
 	/* for blackbird only */
 	struct list_head           devlist;
+#if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \
+    defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE)
 	struct video_device        *mpeg_dev;
 	u32                        mailbox;
 	int                        width;
 	int                        height;
 
+	/* mpeg params */
+	struct cx2341x_mpeg_params params;
+#endif
+
 #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
 	/* for dvb only */
 	struct videobuf_dvb        dvb;
+#endif
 
-	void			   *card_priv;
+#if defined(CONFIG_VIDEO_CX88_VP3054) || \
+    defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
+	/* For VP3045 secondary I2C bus support */
+	struct vp3054_i2c_state	   *vp3054;
 #endif
 	/* for switching modulation types */
 	unsigned char              ts_gen_cntrl;
 
-	/* mpeg params */
-	struct cx2341x_mpeg_params params;
-
 	/* List of attached drivers */
-	struct cx8802_driver       drvlist;
-	struct work_struct request_module_wk;
-
+	struct list_head	   drvlist;
+	struct work_struct	   request_module_wk;
 };
 
 /* ----------------------------------------------------------- */
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index d3282ec..d56484f 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -648,7 +648,7 @@
  */
 int em28xx_init_isoc(struct em28xx *dev)
 {
-	/* change interface to 3 which allowes the biggest packet sizes */
+	/* change interface to 3 which allows the biggest packet sizes */
 	int i, errCode;
 	const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
 
@@ -673,6 +673,7 @@
 					("unable to allocate %i bytes for transfer buffer %i\n",
 					 sb_size, i);
 			em28xx_uninit_isoc(dev);
+			usb_free_urb(urb);
 			return -ENOMEM;
 		}
 		memset(dev->transfer_buffer[i], 0, sb_size);
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index b8d5327..a4c2a90 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -907,7 +907,7 @@
 
 	/* stop io in case it is already in progress */
 	if (dev->stream == STREAM_ON) {
-		em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
+		em28xx_videodbg("VIDIOC_SET_FMT: interrupting stream\n");
 		if ((ret = em28xx_stream_interrupt(dev)))
 			return ret;
 	}
@@ -1617,7 +1617,6 @@
 
 	/* Fills VBI device info */
 	dev->vbi_dev->type = VFL_TYPE_VBI;
-	dev->vbi_dev->hardware = 0;
 	dev->vbi_dev->fops = &em28xx_v4l_fops;
 	dev->vbi_dev->minor = -1;
 	dev->vbi_dev->dev = &dev->udev->dev;
@@ -1629,7 +1628,6 @@
 	dev->vdev->type = VID_TYPE_CAPTURE;
 	if (dev->has_tuner)
 		dev->vdev->type |= VID_TYPE_TUNER;
-	dev->vdev->hardware = 0;
 	dev->vdev->fops = &em28xx_v4l_fops;
 	dev->vdev->minor = -1;
 	dev->vdev->dev = &dev->udev->dev;
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index d5fef4c0..d19d73b 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -2585,7 +2585,6 @@
 	strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera");
 	cam->v4ldev->owner = THIS_MODULE;
 	cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
-	cam->v4ldev->hardware = 0;
 	cam->v4ldev->fops = &et61x251_fops;
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index d98dd0d..29779d8 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -528,6 +528,7 @@
 		break;
 	case I2C_HW_B_CX2388x:
 		probe = probe_cx88;
+		break;
 	case I2C_HW_B_CX23885:
 		probe = probe_cx23885;
 		break;
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index fd7a932..6d2dd87 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -1003,8 +1003,6 @@
 
 	IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
 
-	mutex_lock(&itv->serialize_lock);
-
 	/* PCI Device Setup */
 	if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) {
 		if (retval == -EIO)
@@ -1064,7 +1062,7 @@
 	IVTV_DEBUG_INFO("activating i2c...\n");
 	if (init_ivtv_i2c(itv)) {
 		IVTV_ERR("Could not initialize i2c\n");
-		goto free_irq;
+		goto free_io;
 	}
 
 	IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active);
@@ -1176,7 +1174,11 @@
 		IVTV_ERR("Failed to register irq %d\n", retval);
 		goto free_streams;
 	}
-	mutex_unlock(&itv->serialize_lock);
+	retval = ivtv_streams_register(itv);
+	if (retval) {
+		IVTV_ERR("Error %d registering devices\n", retval);
+		goto free_irq;
+	}
 	IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name);
 	return 0;
 
@@ -1195,7 +1197,6 @@
 		release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
       free_workqueue:
 	destroy_workqueue(itv->irq_work_queues);
-	mutex_unlock(&itv->serialize_lock);
       err:
 	if (retval == 0)
 		retval = -ENODEV;
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 3bda1df..49ce14d 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -51,6 +51,7 @@
 #include <linux/unistd.h>
 #include <linux/byteorder/swab.h>
 #include <linux/pagemap.h>
+#include <linux/scatterlist.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index da50fa4..a200a8a 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -822,6 +822,11 @@
 			crystal_freq.flags = 0;
 			ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
 		}
+		if (atomic_read(&itv->capturing) > 0) {
+			/* Undo video mute */
+			ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
+				itv->params.video_mute | (itv->params.video_mute_yuv << 8));
+		}
 		/* Done! Unmute and continue. */
 		ivtv_unmute(itv);
 		ivtv_release_stream(s);
@@ -892,6 +897,7 @@
 			if (atomic_read(&itv->capturing) > 0) {
 				/* switching to radio while capture is
 				   in progress is not polite */
+				ivtv_release_stream(s);
 				kfree(item);
 				return -EBUSY;
 			}
@@ -947,7 +953,7 @@
 	if (itv == NULL) {
 		/* Couldn't find a device registered
 		   on that minor, shouldn't happen! */
-		IVTV_WARN("No ivtv device found on minor %d\n", minor);
+		printk(KERN_WARNING "No ivtv device found on minor %d\n", minor);
 		return -ENXIO;
 	}
 
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 206eee7..fd6826f 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -555,6 +555,7 @@
 
 	/* set window size */
 	if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		struct cx2341x_mpeg_params *p = &itv->params;
 		int w = fmt->fmt.pix.width;
 		int h = fmt->fmt.pix.height;
 
@@ -566,17 +567,19 @@
 		fmt->fmt.pix.width = w;
 		fmt->fmt.pix.height = h;
 
-		if (!set_fmt || (itv->params.width == w && itv->params.height == h))
+		if (!set_fmt || (p->width == w && p->height == h))
 			return 0;
 		if (atomic_read(&itv->capturing) > 0)
 			return -EBUSY;
 
-		itv->params.width = w;
-		itv->params.height = h;
+		p->width = w;
+		p->height = h;
 		if (w != 720 || h != (itv->is_50hz ? 576 : 480))
-			itv->params.video_temporal_filter = 0;
+			p->video_temporal_filter = 0;
 		else
-			itv->params.video_temporal_filter = 8;
+			p->video_temporal_filter = 8;
+		if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
+			fmt->fmt.pix.width /= 2;
 		itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
 		return ivtv_get_fmt(itv, streamtype, fmt);
 	}
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index fd13598..aa03e61 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -166,10 +166,9 @@
 	ivtv_queue_init(&s->q_io);
 }
 
-static int ivtv_reg_dev(struct ivtv *itv, int type)
+static int ivtv_prep_dev(struct ivtv *itv, int type)
 {
 	struct ivtv_stream *s = &itv->streams[type];
-	int vfl_type = ivtv_stream_info[type].vfl_type;
 	int minor_offset = ivtv_stream_info[type].minor_offset;
 	int minor;
 
@@ -187,15 +186,12 @@
 	if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
 		return 0;
 
-	if (minor_offset >= 0)
-		/* card number + user defined offset + device offset */
-		minor = itv->num + ivtv_first_minor + minor_offset;
-	else
-		minor = -1;
+	/* card number + user defined offset + device offset */
+	minor = itv->num + ivtv_first_minor + minor_offset;
 
 	/* User explicitly selected 0 buffers for these streams, so don't
 	   create them. */
-	if (minor >= 0 && ivtv_stream_info[type].dma != PCI_DMA_NONE &&
+	if (ivtv_stream_info[type].dma != PCI_DMA_NONE &&
 	    itv->options.kilobytes[type] == 0) {
 		IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name);
 		return 0;
@@ -223,21 +219,53 @@
 	s->v4l2dev->fops = ivtv_stream_info[type].fops;
 	s->v4l2dev->release = video_device_release;
 
-	if (minor >= 0) {
-		/* Register device. First try the desired minor, then any free one. */
-		if (video_register_device(s->v4l2dev, vfl_type, minor) &&
-		    video_register_device(s->v4l2dev, vfl_type, -1)) {
-			IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n",
-					s->name, minor);
-			video_device_release(s->v4l2dev);
-			s->v4l2dev = NULL;
-			return -ENOMEM;
-		}
+	return 0;
+}
+
+/* Initialize v4l2 variables and prepare v4l2 devices */
+int ivtv_streams_setup(struct ivtv *itv)
+{
+	int type;
+
+	/* Setup V4L2 Devices */
+	for (type = 0; type < IVTV_MAX_STREAMS; type++) {
+		/* Prepare device */
+		if (ivtv_prep_dev(itv, type))
+			break;
+
+		if (itv->streams[type].v4l2dev == NULL)
+			continue;
+
+		/* Allocate Stream */
+		if (ivtv_stream_alloc(&itv->streams[type]))
+			break;
 	}
-	else {
-		/* Don't register a 'hidden' stream (OSD) */
-		IVTV_INFO("Created framebuffer stream for %s\n", s->name);
+	if (type == IVTV_MAX_STREAMS)
 		return 0;
+
+	/* One or more streams could not be initialized. Clean 'em all up. */
+	ivtv_streams_cleanup(itv);
+	return -ENOMEM;
+}
+
+static int ivtv_reg_dev(struct ivtv *itv, int type)
+{
+	struct ivtv_stream *s = &itv->streams[type];
+	int vfl_type = ivtv_stream_info[type].vfl_type;
+	int minor;
+
+	if (s->v4l2dev == NULL)
+		return 0;
+
+	minor = s->v4l2dev->minor;
+	/* Register device. First try the desired minor, then any free one. */
+	if (video_register_device(s->v4l2dev, vfl_type, minor) &&
+			video_register_device(s->v4l2dev, vfl_type, -1)) {
+		IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n",
+				s->name, minor);
+		video_device_release(s->v4l2dev);
+		s->v4l2dev = NULL;
+		return -ENOMEM;
 	}
 
 	switch (vfl_type) {
@@ -262,27 +290,18 @@
 	return 0;
 }
 
-/* Initialize v4l2 variables and register v4l2 devices */
-int ivtv_streams_setup(struct ivtv *itv)
+/* Register v4l2 devices */
+int ivtv_streams_register(struct ivtv *itv)
 {
 	int type;
+	int err = 0;
 
-	/* Setup V4L2 Devices */
-	for (type = 0; type < IVTV_MAX_STREAMS; type++) {
-		/* Register Device */
-		if (ivtv_reg_dev(itv, type))
-			break;
+	/* Register V4L2 devices */
+	for (type = 0; type < IVTV_MAX_STREAMS; type++)
+		err |= ivtv_reg_dev(itv, type);
 
-		if (itv->streams[type].v4l2dev == NULL)
-			continue;
-
-		/* Allocate Stream */
-		if (ivtv_stream_alloc(&itv->streams[type]))
-			break;
-	}
-	if (type == IVTV_MAX_STREAMS) {
+	if (err == 0)
 		return 0;
-	}
 
 	/* One or more streams could not be initialized. Clean 'em all up. */
 	ivtv_streams_cleanup(itv);
@@ -303,11 +322,8 @@
 			continue;
 
 		ivtv_stream_free(&itv->streams[type]);
-		/* Free Device */
-		if (vdev->minor == -1) /* 'Hidden' never registered stream (OSD) */
-			video_device_release(vdev);
-		else    /* All others, just unregister. */
-			video_unregister_device(vdev);
+		/* Unregister device */
+		video_unregister_device(vdev);
 	}
 }
 
@@ -425,6 +441,7 @@
 {
 	u32 data[CX2341X_MBOX_MAX_DATA];
 	struct ivtv *itv = s->itv;
+	struct cx2341x_mpeg_params *p = &itv->params;
 	int captype = 0, subtype = 0;
 	int enable_passthrough = 0;
 
@@ -445,7 +462,7 @@
 		}
 		itv->mpg_data_received = itv->vbi_data_inserted = 0;
 		itv->dualwatch_jiffies = jiffies;
-		itv->dualwatch_stereo_mode = itv->params.audio_properties & 0x0300;
+		itv->dualwatch_stereo_mode = p->audio_properties & 0x0300;
 		itv->search_pack_header = 0;
 		break;
 
@@ -477,9 +494,6 @@
 	s->subtype = subtype;
 	s->buffers_stolen = 0;
 
-	/* mute/unmute video */
-	ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? 1 : 0);
-
 	/* Clear Streamoff flags in case left from last capture */
 	clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
 
@@ -536,7 +550,12 @@
 				itv->pgm_info_offset, itv->pgm_info_num);
 
 		/* Setup API for Stream */
-		cx2341x_update(itv, ivtv_api_func, NULL, &itv->params);
+		cx2341x_update(itv, ivtv_api_func, NULL, p);
+
+		/* mute if capturing radio */
+		if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
+			ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
+				1 | (p->video_mute_yuv << 8));
 	}
 
 	/* Vsync Setup */
@@ -585,6 +604,7 @@
 {
 	u32 data[CX2341X_MBOX_MAX_DATA];
 	struct ivtv *itv = s->itv;
+	struct cx2341x_mpeg_params *p = &itv->params;
 	int datatype;
 
 	if (s->v4l2dev == NULL)
@@ -623,7 +643,7 @@
 		break;
 	}
 	if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
-			itv->params.width, itv->params.height, itv->params.audio_properties)) {
+			p->width, p->height, p->audio_properties)) {
 		IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
 	}
 	return 0;
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h
index 8f5f5b1..3d76a41 100644
--- a/drivers/media/video/ivtv/ivtv-streams.h
+++ b/drivers/media/video/ivtv/ivtv-streams.h
@@ -22,6 +22,7 @@
 #define IVTV_STREAMS_H
 
 int ivtv_streams_setup(struct ivtv *itv);
+int ivtv_streams_register(struct ivtv *itv);
 void ivtv_streams_cleanup(struct ivtv *itv);
 
 /* Capture related */
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index c4626d1..912b424 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -63,10 +63,10 @@
 			memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
 			kunmap_atomic(src, KM_BOUNCE_READ);
 			local_irq_restore(flags);
-			dma->SGlist[map_offset].page = dma->bouncemap[map_offset];
+			sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset]);
 		}
 		else {
-			dma->SGlist[map_offset].page = dma->map[map_offset];
+			sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset]);
 		}
 		offset = 0;
 		map_offset++;
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index e2288f2..9091c48 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -710,7 +710,7 @@
 
 	/* If there's nothing to safe to display, we may as well stop now */
 	if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) {
-		return 0;
+		return IVTV_YUV_UPDATE_INVALID;
 	}
 
 	/* Ensure video remains inside OSD area */
@@ -791,7 +791,7 @@
 
 	/* Check again. If there's nothing to safe to display, stop now */
 	if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) {
-		return 0;
+		return IVTV_YUV_UPDATE_INVALID;
 	}
 
 	/* Both x offset & width are linked, so they have to be done together */
@@ -840,110 +840,118 @@
 	if (!(yuv_update = ivtv_yuv_window_setup (itv, &window)))
 		return;
 
-	/* Update horizontal settings */
-	if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL)
-		ivtv_yuv_handle_horizontal(itv, &window);
+	if (yuv_update & IVTV_YUV_UPDATE_INVALID) {
+		write_reg(0x01008080, 0x2898);
+	} else if (yuv_update) {
+		write_reg(0x00108080, 0x2898);
 
-	if (yuv_update & IVTV_YUV_UPDATE_VERTICAL)
-		ivtv_yuv_handle_vertical(itv, &window);
+		if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL)
+			ivtv_yuv_handle_horizontal(itv, &window);
+
+		if (yuv_update & IVTV_YUV_UPDATE_VERTICAL)
+			ivtv_yuv_handle_vertical(itv, &window);
+	}
 
 	memcpy(&itv->yuv_info.old_frame_info, &window, sizeof (itv->yuv_info.old_frame_info));
 }
 
 static void ivtv_yuv_init (struct ivtv *itv)
 {
+	struct yuv_playback_info *yi = &itv->yuv_info;
+
 	IVTV_DEBUG_YUV("ivtv_yuv_init\n");
 
 	/* Take a snapshot of the current register settings */
-	itv->yuv_info.reg_2834 = read_reg(0x02834);
-	itv->yuv_info.reg_2838 = read_reg(0x02838);
-	itv->yuv_info.reg_283c = read_reg(0x0283c);
-	itv->yuv_info.reg_2840 = read_reg(0x02840);
-	itv->yuv_info.reg_2844 = read_reg(0x02844);
-	itv->yuv_info.reg_2848 = read_reg(0x02848);
-	itv->yuv_info.reg_2854 = read_reg(0x02854);
-	itv->yuv_info.reg_285c = read_reg(0x0285c);
-	itv->yuv_info.reg_2864 = read_reg(0x02864);
-	itv->yuv_info.reg_2870 = read_reg(0x02870);
-	itv->yuv_info.reg_2874 = read_reg(0x02874);
-	itv->yuv_info.reg_2898 = read_reg(0x02898);
-	itv->yuv_info.reg_2890 = read_reg(0x02890);
+	yi->reg_2834 = read_reg(0x02834);
+	yi->reg_2838 = read_reg(0x02838);
+	yi->reg_283c = read_reg(0x0283c);
+	yi->reg_2840 = read_reg(0x02840);
+	yi->reg_2844 = read_reg(0x02844);
+	yi->reg_2848 = read_reg(0x02848);
+	yi->reg_2854 = read_reg(0x02854);
+	yi->reg_285c = read_reg(0x0285c);
+	yi->reg_2864 = read_reg(0x02864);
+	yi->reg_2870 = read_reg(0x02870);
+	yi->reg_2874 = read_reg(0x02874);
+	yi->reg_2898 = read_reg(0x02898);
+	yi->reg_2890 = read_reg(0x02890);
 
-	itv->yuv_info.reg_289c = read_reg(0x0289c);
-	itv->yuv_info.reg_2918 = read_reg(0x02918);
-	itv->yuv_info.reg_291c = read_reg(0x0291c);
-	itv->yuv_info.reg_2920 = read_reg(0x02920);
-	itv->yuv_info.reg_2924 = read_reg(0x02924);
-	itv->yuv_info.reg_2928 = read_reg(0x02928);
-	itv->yuv_info.reg_292c = read_reg(0x0292c);
-	itv->yuv_info.reg_2930 = read_reg(0x02930);
-	itv->yuv_info.reg_2934 = read_reg(0x02934);
-	itv->yuv_info.reg_2938 = read_reg(0x02938);
-	itv->yuv_info.reg_293c = read_reg(0x0293c);
-	itv->yuv_info.reg_2940 = read_reg(0x02940);
-	itv->yuv_info.reg_2944 = read_reg(0x02944);
-	itv->yuv_info.reg_2948 = read_reg(0x02948);
-	itv->yuv_info.reg_294c = read_reg(0x0294c);
-	itv->yuv_info.reg_2950 = read_reg(0x02950);
-	itv->yuv_info.reg_2954 = read_reg(0x02954);
-	itv->yuv_info.reg_2958 = read_reg(0x02958);
-	itv->yuv_info.reg_295c = read_reg(0x0295c);
-	itv->yuv_info.reg_2960 = read_reg(0x02960);
-	itv->yuv_info.reg_2964 = read_reg(0x02964);
-	itv->yuv_info.reg_2968 = read_reg(0x02968);
-	itv->yuv_info.reg_296c = read_reg(0x0296c);
-	itv->yuv_info.reg_2970 = read_reg(0x02970);
+	yi->reg_289c = read_reg(0x0289c);
+	yi->reg_2918 = read_reg(0x02918);
+	yi->reg_291c = read_reg(0x0291c);
+	yi->reg_2920 = read_reg(0x02920);
+	yi->reg_2924 = read_reg(0x02924);
+	yi->reg_2928 = read_reg(0x02928);
+	yi->reg_292c = read_reg(0x0292c);
+	yi->reg_2930 = read_reg(0x02930);
+	yi->reg_2934 = read_reg(0x02934);
+	yi->reg_2938 = read_reg(0x02938);
+	yi->reg_293c = read_reg(0x0293c);
+	yi->reg_2940 = read_reg(0x02940);
+	yi->reg_2944 = read_reg(0x02944);
+	yi->reg_2948 = read_reg(0x02948);
+	yi->reg_294c = read_reg(0x0294c);
+	yi->reg_2950 = read_reg(0x02950);
+	yi->reg_2954 = read_reg(0x02954);
+	yi->reg_2958 = read_reg(0x02958);
+	yi->reg_295c = read_reg(0x0295c);
+	yi->reg_2960 = read_reg(0x02960);
+	yi->reg_2964 = read_reg(0x02964);
+	yi->reg_2968 = read_reg(0x02968);
+	yi->reg_296c = read_reg(0x0296c);
+	yi->reg_2970 = read_reg(0x02970);
 
-	itv->yuv_info.v_filter_1 = -1;
-	itv->yuv_info.v_filter_2 = -1;
-	itv->yuv_info.h_filter = -1;
+	yi->v_filter_1 = -1;
+	yi->v_filter_2 = -1;
+	yi->h_filter = -1;
 
 	/* Set some valid size info */
-	itv->yuv_info.osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
-	itv->yuv_info.osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
+	yi->osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
+	yi->osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
 
 	/* Bit 2 of reg 2878 indicates current decoder output format
 	   0 : NTSC    1 : PAL */
 	if (read_reg(0x2878) & 4)
-		itv->yuv_info.decode_height = 576;
+		yi->decode_height = 576;
 	else
-		itv->yuv_info.decode_height = 480;
+		yi->decode_height = 480;
 
-	/* If no visible size set, assume full size */
-	if (!itv->yuv_info.osd_vis_w)
-		itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset;
-
-	if (!itv->yuv_info.osd_vis_h) {
-		itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
+	if (!itv->osd_info) {
+		yi->osd_vis_w = 720 - yi->osd_x_offset;
+		yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
 	} else {
-		/* If output video standard has changed, requested height may
-		not be legal */
-		if (itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset > itv->yuv_info.decode_height) {
-			IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
-					itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset,
-					itv->yuv_info.decode_height);
-			itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
+		/* If no visible size set, assume full size */
+		if (!yi->osd_vis_w)
+			yi->osd_vis_w = 720 - yi->osd_x_offset;
+
+		if (!yi->osd_vis_h)
+			yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
+		else {
+			/* If output video standard has changed, requested height may
+			not be legal */
+			if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) {
+				IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
+						yi->osd_vis_h + yi->osd_y_offset,
+						yi->decode_height);
+				yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
+			}
 		}
 	}
 
 	/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
-	itv->yuv_info.blanking_ptr = kzalloc(720*16,GFP_KERNEL);
-	if (itv->yuv_info.blanking_ptr) {
-		itv->yuv_info.blanking_dmaptr = pci_map_single(itv->dev, itv->yuv_info.blanking_ptr, 720*16, PCI_DMA_TODEVICE);
-	}
+	yi->blanking_ptr = kzalloc(720*16, GFP_KERNEL);
+	if (yi->blanking_ptr)
+		yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
 	else {
-		itv->yuv_info.blanking_dmaptr = 0;
-		IVTV_DEBUG_WARN ("Failed to allocate yuv blanking buffer\n");
+		yi->blanking_dmaptr = 0;
+		IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
 	}
 
-	IVTV_DEBUG_WARN("Enable video output\n");
-	write_reg_sync(0x00108080, 0x2898);
-
 	/* Enable YUV decoder output */
 	write_reg_sync(0x01, IVTV_REG_VDM);
 
 	set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
-	atomic_set(&itv->yuv_info.next_dma_frame,0);
+	atomic_set(&yi->next_dma_frame, 0);
 }
 
 int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
diff --git a/drivers/media/video/ivtv/ivtv-yuv.h b/drivers/media/video/ivtv/ivtv-yuv.h
index f7215ee..3b966f0 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.h
+++ b/drivers/media/video/ivtv/ivtv-yuv.h
@@ -34,6 +34,7 @@
 
 #define IVTV_YUV_UPDATE_HORIZONTAL  0x01
 #define IVTV_YUV_UPDATE_VERTICAL    0x02
+#define IVTV_YUV_UPDATE_INVALID     0x04
 
 extern const u32 yuv_offset[4];
 
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 9684048..52ffd15 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -55,7 +55,6 @@
 static int ivtvfb_card_id = -1;
 static int ivtvfb_debug = 0;
 static int osd_laced;
-static int osd_compat;
 static int osd_depth;
 static int osd_upper;
 static int osd_left;
@@ -65,7 +64,6 @@
 module_param(ivtvfb_card_id, int, 0444);
 module_param_named(debug,ivtvfb_debug, int, 0644);
 module_param(osd_laced, bool, 0444);
-module_param(osd_compat, bool, 0444);
 module_param(osd_depth, int, 0444);
 module_param(osd_upper, int, 0444);
 module_param(osd_left, int, 0444);
@@ -80,12 +78,6 @@
 		 "Debug level (bitmask). Default: errors only\n"
 		 "\t\t\t(debug = 3 gives full debugging)");
 
-MODULE_PARM_DESC(osd_compat,
-		 "Compatibility mode - Display size is locked (use for old X drivers)\n"
-		 "\t\t\t0=off\n"
-		 "\t\t\t1=on\n"
-		 "\t\t\tdefault off");
-
 /* Why upper, left, xres, yres, depth, laced ? To match terminology used
    by fbset.
    Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
@@ -166,9 +158,6 @@
 	unsigned long fb_end_aligned_physaddr;
 #endif
 
-	/* Current osd mode */
-	int osd_mode;
-
 	/* Store the buffer offset */
 	int set_osd_coords_x;
 	int set_osd_coords_y;
@@ -470,13 +459,11 @@
 			IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
 	}
 
-	/* Change osd mode if needed.
-	   Although rare, things can go wrong. The extra mode
-	   change seems to help... */
-	if (osd_mode != -1 && osd_mode != oi->osd_mode) {
+	/* Set video mode. Although rare, the display can become scrambled even
+	   if we don't change mode. Always 'bounce' to osd_mode via mode 0 */
+	if (osd_mode != -1) {
 		ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
 		ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
-		oi->osd_mode = osd_mode;
 	}
 
 	oi->bits_per_pixel = var->bits_per_pixel;
@@ -579,14 +566,6 @@
 		osd_height_limit = 480;
 	}
 
-	/* Check the bits per pixel */
-	if (osd_compat) {
-		if (var->bits_per_pixel != 32) {
-			IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
-			return -EINVAL;
-		}
-	}
-
 	if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
 		var->transp.offset = 24;
 		var->transp.length = 8;
@@ -638,32 +617,20 @@
 	}
 
 	/* Check the resolution */
-	if (osd_compat) {
-		if (var->xres != oi->ivtvfb_defined.xres ||
-		    var->yres != oi->ivtvfb_defined.yres ||
-		    var->xres_virtual != oi->ivtvfb_defined.xres_virtual ||
-		    var->yres_virtual != oi->ivtvfb_defined.yres_virtual) {
-			IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d (virtual %dx%d)\n",
-				var->xres, var->yres, var->xres_virtual, var->yres_virtual);
-			return -EINVAL;
-		}
+	if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
+		IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
+				var->xres, var->yres);
+		return -EINVAL;
 	}
-	else {
-		if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
-			IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
-					var->xres, var->yres);
-			return -EINVAL;
-		}
 
-		/* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
-		if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
-		    var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
-		    var->xres_virtual < var->xres ||
-		    var->yres_virtual < var->yres) {
-			IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
-				var->xres_virtual, var->yres_virtual);
-			return -EINVAL;
-		}
+	/* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
+	if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
+	    var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
+	    var->xres_virtual < var->xres ||
+	    var->yres_virtual < var->yres) {
+		IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
+			var->xres_virtual, var->yres_virtual);
+		return -EINVAL;
 	}
 
 	/* Some extra checks if in 8 bit mode */
@@ -877,17 +844,15 @@
 
 	/* Color mode */
 
-	if (osd_compat) osd_depth = 32;
-	if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) osd_depth = 8;
+	if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
+		osd_depth = 8;
 	oi->bits_per_pixel = osd_depth;
 	oi->bytes_per_pixel = oi->bits_per_pixel / 8;
 
-	/* Invalidate current osd mode to force a mode switch later */
-	oi->osd_mode = -1;
-
 	/* Horizontal size & position */
 
-	if (osd_xres > 720) osd_xres = 720;
+	if (osd_xres > 720)
+		osd_xres = 720;
 
 	/* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
 	if (osd_depth == 8)
@@ -895,10 +860,7 @@
 	else if (osd_depth == 16)
 		osd_xres &= ~1;
 
-	if (osd_xres)
-		start_window.width = osd_xres;
-	else
-		start_window.width = osd_compat ? 720: 640;
+	start_window.width = osd_xres ? osd_xres : 640;
 
 	/* Check horizontal start (osd_left). */
 	if (osd_left && osd_left + start_window.width > 721) {
@@ -921,10 +883,7 @@
 	if (osd_yres > max_height)
 		osd_yres = max_height;
 
-	if (osd_yres)
-		start_window.height = osd_yres;
-	else
-		start_window.height = osd_compat ? max_height : (itv->is_50hz ? 480 : 400);
+	start_window.height = osd_yres ? osd_yres : itv->is_50hz ? 480 : 400;
 
 	/* Check vertical start (osd_upper). */
 	if (osd_upper + start_window.height > max_height + 1) {
@@ -1127,10 +1086,6 @@
 	/* Enable the osd */
 	ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
 
-	/* Note if we're running in compatibility mode */
-	if (osd_compat)
-		IVTVFB_INFO("Running in compatibility mode. Display resize & mode change disabled\n");
-
 	/* Allocate DMA */
 	ivtv_udma_alloc(itv);
 	return 0;
@@ -1177,9 +1132,12 @@
 	for (i = 0; i < ivtv_cards_active; i++) {
 		itv = ivtv_cards[i];
 		if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) {
+			if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
+				IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", i);
+				return;
+			}
 			IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i);
 			ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info);
-			unregister_framebuffer(&itv->osd_info->ivtvfb_info);
 			ivtvfb_release_buffers(itv);
 			itv->osd_video_pbase = 0;
 		}
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 7533fc2..c311632 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
  *
- * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
  *
  * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
  *
@@ -1762,7 +1762,6 @@
 	.owner		= THIS_MODULE,
 	.name		= "meye",
 	.type		= VID_TYPE_CAPTURE,
-	.hardware	= VID_HARDWARE_MEYE,
 	.fops		= &meye_fops,
 	.release	= video_device_release,
 	.minor		= -1,
diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h
index 323d007..d535748 100644
--- a/drivers/media/video/meye.h
+++ b/drivers/media/video/meye.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
  *
- * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
  *
  * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
  *
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index b8d4ac0..d55d580 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -4668,7 +4668,6 @@
 	.owner =	THIS_MODULE,
 	.name =		"OV511 USB Camera",
 	.type =		VID_TYPE_CAPTURE,
-	.hardware =	VID_HARDWARE_OV511,
 	.fops =		&ov511_fops,
 	.release =	video_device_release,
 	.minor =	-1,
diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c
index 0ef73d9..ce4b2f9 100644
--- a/drivers/media/video/planb.c
+++ b/drivers/media/video/planb.c
@@ -2013,7 +2013,6 @@
 	.owner		= THIS_MODULE,
 	.name		= PLANB_DEVICE_NAME,
 	.type		= VID_TYPE_OVERLAY,
-	.hardware	= VID_HARDWARE_PLANB,
 	.open		= planb_open,
 	.close		= planb_close,
 	.read		= planb_read,
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index b5a67f0..6820c2a 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -895,7 +895,6 @@
 	.owner		= THIS_MODULE,
 	.name		= "Mediavision PMS",
 	.type		= VID_TYPE_CAPTURE,
-	.hardware	= VID_HARDWARE_PMS,
 	.fops           = &pms_fops,
 };
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 20b6144..205087a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -209,6 +209,11 @@
 
 	LOCK_TAKE(hdw->ctl_lock); do {
 
+		if (!hdw->flag_encoder_ok) {
+			ret = -EIO;
+			break;
+		}
+
 		retry_flag = 0;
 		try_count++;
 		ret = 0;
@@ -273,6 +278,7 @@
 			ret = -EBUSY;
 		}
 		if (ret) {
+			hdw->flag_encoder_ok = 0;
 			pvr2_trace(
 				PVR2_TRACE_ERROR_LEGS,
 				"Giving up on command."
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 985d9ae..f873994 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -225,11 +225,12 @@
 	unsigned int cmd_debug_write_len;  //
 	unsigned int cmd_debug_read_len;   //
 
-	int flag_ok;            // device in known good state
-	int flag_disconnected;  // flag_ok == 0 due to disconnect
-	int flag_init_ok;       // true if structure is fully initialized
-	int flag_streaming_enabled; // true if streaming should be on
-	int fw1_state;          // current situation with fw1
+	int flag_ok;            /* device in known good state */
+	int flag_disconnected;  /* flag_ok == 0 due to disconnect */
+	int flag_init_ok;       /* true if structure is fully initialized */
+	int flag_streaming_enabled; /* true if streaming should be on */
+	int fw1_state;          /* current situation with fw1 */
+	int flag_encoder_ok;    /* True if encoder is healthy */
 
 	int flag_decoder_is_tuned;
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 27b12b4..402c5948 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1248,6 +1248,8 @@
 	   time we configure the encoder, then we'll fully configure it. */
 	hdw->enc_cur_valid = 0;
 
+	hdw->flag_encoder_ok = 0;
+
 	/* First prepare firmware loading */
 	ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
 	ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
@@ -1346,6 +1348,7 @@
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 			   "firmware2 upload post-proc failure");
 	} else {
+		hdw->flag_encoder_ok = !0;
 		hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE);
 	}
 	return ret;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 4563b3d..7a596ea 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -1121,15 +1121,12 @@
 };
 
 
-#define VID_HARDWARE_PVRUSB2    38  /* FIXME : need a good value */
-
 static struct video_device vdev_template = {
 	.owner      = THIS_MODULE,
 	.type       = VID_TYPE_CAPTURE | VID_TYPE_TUNER,
 	.type2      = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE
 		       | V4L2_CAP_TUNER | V4L2_CAP_AUDIO
 		       | V4L2_CAP_READWRITE),
-	.hardware   = VID_HARDWARE_PVRUSB2,
 	.fops       = &vdev_fops,
 };
 
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 950da25..7300ace 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -166,7 +166,6 @@
 	.owner =	THIS_MODULE,
 	.name =		"Philips Webcam",	/* Filled in later */
 	.type =		VID_TYPE_CAPTURE,
-	.hardware =	VID_HARDWARE_PWC,
 	.release =	video_device_release,
 	.fops =         &pwc_fops,
 	.minor =        -1,
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index e20aa36..ad02329 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -196,10 +196,10 @@
 	return i2c_sendbuf(t, buf[0], ct-1, buf+1);
 }
 
-/* Get count number of bytes from I²C-device at address adr, store them in buf.
+/* Get count number of bytes from I²C-device at address adr, store them in buf.
  * Start & stop handshaking is done by this routine, ack will be sent after the
  * last byte to inhibit further sending of data. If uaccess is 'true', data is
- * written to user-space with put_user. Returns -1 if I²C-device didn't send
+ * written to user-space with put_user. Returns -1 if I²C-device didn't send
  * acknowledge, 0 otherwise
  */
 static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf)
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index 17f1e2e..94bb59a 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -291,10 +291,10 @@
 	return i2c_sendbuf(t, buf[0], ct-1, buf+1);
 }
 
-/* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop
+/* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop
  * handshaking is done by this routine, ack will be sent after the last byte to inhibit further
  * sending of data. If uaccess is 'true', data is written to user-space with put_user.
- * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise
+ * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise
  */
 
 static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 57f1f5d..002e70a 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -71,7 +71,6 @@
 
 struct saa6752hs_state {
 	struct i2c_client             client;
-	struct v4l2_mpeg_compression  old_params;
 	struct saa6752hs_mpeg_params  params;
 	enum saa6752hs_videoformat    video_format;
 	v4l2_std_id                   standard;
@@ -161,35 +160,6 @@
 	.au_l2_bitrate   = V4L2_MPEG_AUDIO_L2_BITRATE_256K,
 };
 
-static struct v4l2_mpeg_compression old_param_defaults =
-{
-	.st_type         = V4L2_MPEG_TS_2,
-	.st_bitrate      = {
-		.mode    = V4L2_BITRATE_CBR,
-		.target  = 7000,
-	},
-
-	.ts_pid_pmt      = 16,
-	.ts_pid_video    = 260,
-	.ts_pid_audio    = 256,
-	.ts_pid_pcr      = 259,
-
-	.vi_type         = V4L2_MPEG_VI_2,
-	.vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
-	.vi_bitrate      = {
-		.mode    = V4L2_BITRATE_VBR,
-		.target  = 4000,
-		.max     = 6000,
-	},
-
-	.au_type         = V4L2_MPEG_AU_2_II,
-	.au_bitrate      = {
-		.mode    = V4L2_BITRATE_CBR,
-		.target  = 256,
-	},
-
-};
-
 /* ---------------------------------------------------------------------- */
 
 static int saa6752hs_chip_command(struct i2c_client* client,
@@ -362,74 +332,6 @@
 }
 
 
-static void saa6752hs_old_set_params(struct i2c_client* client,
-				 struct v4l2_mpeg_compression* params)
-{
-	struct saa6752hs_state *h = i2c_get_clientdata(client);
-
-	/* check PIDs */
-	if (params->ts_pid_pmt <= MPEG_PID_MAX) {
-		h->old_params.ts_pid_pmt = params->ts_pid_pmt;
-		h->params.ts_pid_pmt = params->ts_pid_pmt;
-	}
-	if (params->ts_pid_pcr <= MPEG_PID_MAX) {
-		h->old_params.ts_pid_pcr = params->ts_pid_pcr;
-		h->params.ts_pid_pcr = params->ts_pid_pcr;
-	}
-	if (params->ts_pid_video <= MPEG_PID_MAX) {
-		h->old_params.ts_pid_video = params->ts_pid_video;
-		h->params.ts_pid_video = params->ts_pid_video;
-	}
-	if (params->ts_pid_audio <= MPEG_PID_MAX) {
-		h->old_params.ts_pid_audio = params->ts_pid_audio;
-		h->params.ts_pid_audio = params->ts_pid_audio;
-	}
-
-	/* check bitrate parameters */
-	if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) ||
-	    (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) {
-		h->old_params.vi_bitrate.mode = params->vi_bitrate.mode;
-		h->params.vi_bitrate_mode = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ?
-		       V4L2_MPEG_VIDEO_BITRATE_MODE_VBR : V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
-	}
-	if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
-		h->old_params.st_bitrate.target = params->st_bitrate.target;
-	if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
-		h->old_params.vi_bitrate.target = params->vi_bitrate.target;
-	if (params->vi_bitrate.mode == V4L2_BITRATE_VBR)
-		h->old_params.vi_bitrate.max = params->vi_bitrate.max;
-	if (params->au_bitrate.mode != V4L2_BITRATE_NONE)
-		h->old_params.au_bitrate.target = params->au_bitrate.target;
-
-	/* aspect ratio */
-	if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 ||
-	    params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) {
-		h->old_params.vi_aspect_ratio = params->vi_aspect_ratio;
-		if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3)
-			h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3;
-		else
-			h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_16x9;
-	}
-
-	/* range checks */
-	if (h->old_params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX)
-		h->old_params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX;
-	if (h->old_params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX)
-		h->old_params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX;
-	if (h->old_params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX)
-		h->old_params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX;
-	h->params.vi_bitrate = params->vi_bitrate.target;
-	h->params.vi_bitrate_peak = params->vi_bitrate.max;
-	if (h->old_params.au_bitrate.target <= 256) {
-		h->old_params.au_bitrate.target = 256;
-		h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
-	}
-	else {
-		h->old_params.au_bitrate.target = 384;
-		h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
-	}
-}
-
 static int handle_ctrl(struct saa6752hs_mpeg_params *params,
 		struct v4l2_ext_control *ctrl, unsigned int cmd)
 {
@@ -697,7 +599,6 @@
 		return -ENOMEM;
 	h->client = client_template;
 	h->params = param_defaults;
-	h->old_params = old_param_defaults;
 	h->client.adapter = adap;
 	h->client.addr = addr;
 
@@ -734,23 +635,11 @@
 {
 	struct saa6752hs_state *h = i2c_get_clientdata(client);
 	struct v4l2_ext_controls *ctrls = arg;
-	struct v4l2_mpeg_compression *old_params = arg;
 	struct saa6752hs_mpeg_params params;
 	int err = 0;
 	int i;
 
 	switch (cmd) {
-	case VIDIOC_S_MPEGCOMP:
-		if (NULL == old_params) {
-			/* apply settings and start encoder */
-			saa6752hs_init(client);
-			break;
-		}
-		saa6752hs_old_set_params(client, old_params);
-		/* fall through */
-	case VIDIOC_G_MPEGCOMP:
-		*old_params = h->old_params;
-		break;
 	case VIDIOC_S_EXT_CTRLS:
 		if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
 			return -EINVAL;
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 1a4a244..a499eea 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -429,7 +429,7 @@
 
 	assert_spin_locked(&dev->slock);
 
-	if (dev->inresume)
+	if (dev->insuspend)
 		return 0;
 
 	/* video capture -- dma 0 + video task A */
@@ -563,6 +563,9 @@
 	unsigned long report,status;
 	int loop, handled = 0;
 
+	if (dev->insuspend)
+		goto out;
+
 	for (loop = 0; loop < 10; loop++) {
 		report = saa_readl(SAA7134_IRQ_REPORT);
 		status = saa_readl(SAA7134_IRQ_STATUS);
@@ -1163,6 +1166,7 @@
 	kfree(dev);
 }
 
+#ifdef CONFIG_PM
 static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
 {
 
@@ -1176,6 +1180,19 @@
 	saa_writel(SAA7134_IRQ2, 0);
 	saa_writel(SAA7134_MAIN_CTRL, 0);
 
+	synchronize_irq(pci_dev->irq);
+	dev->insuspend = 1;
+
+	/* Disable timeout timers - if we have active buffers, we will
+	   fill them on resume*/
+
+	del_timer(&dev->video_q.timeout);
+	del_timer(&dev->vbi_q.timeout);
+	del_timer(&dev->ts_q.timeout);
+
+	if (dev->remote)
+		saa7134_ir_stop(dev);
+
 	pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
 	pci_save_state(pci_dev);
 
@@ -1194,24 +1211,27 @@
 	/* Do things that are done in saa7134_initdev ,
 		except of initializing memory structures.*/
 
-	dev->inresume = 1;
 	saa7134_board_init1(dev);
 
+	/* saa7134_hwinit1 */
 	if (saa7134_boards[dev->board].video_out)
 		saa7134_videoport_init(dev);
-
 	if (card_has_mpeg(dev))
 		saa7134_ts_init_hw(dev);
-
+	if (dev->remote)
+		saa7134_ir_start(dev, dev->remote);
 	saa7134_hw_enable1(dev);
-	saa7134_set_decoder(dev);
-	saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
-	saa7134_board_init2(dev);
-	saa7134_hw_enable2(dev);
 
+
+	saa7134_board_init2(dev);
+
+	/*saa7134_hwinit2*/
+	saa7134_set_tvnorm_hw(dev);
 	saa7134_tvaudio_setmute(dev);
 	saa7134_tvaudio_setvolume(dev, dev->ctl_volume);
+	saa7134_tvaudio_do_scan(dev);
 	saa7134_enable_i2s(dev);
+	saa7134_hw_enable2(dev);
 
 	/*resume unfinished buffer(s)*/
 	spin_lock_irqsave(&dev->slock, flags);
@@ -1219,13 +1239,19 @@
 	saa7134_buffer_requeue(dev, &dev->vbi_q);
 	saa7134_buffer_requeue(dev, &dev->ts_q);
 
+	/* FIXME: Disable DMA audio sound - temporary till proper support
+		  is implemented*/
+
+	dev->dmasound.dma_running = 0;
+
 	/* start DMA now*/
-	dev->inresume = 0;
+	dev->insuspend = 0;
 	saa7134_set_dmabits(dev);
 	spin_unlock_irqrestore(&dev->slock, flags);
 
 	return 0;
 }
+#endif
 
 /* ----------------------------------------------------------- */
 
@@ -1262,8 +1288,10 @@
 	.id_table = saa7134_pci_tbl,
 	.probe    = saa7134_initdev,
 	.remove   = __devexit_p(saa7134_finidev),
+#ifdef CONFIG_PM
 	.suspend  = saa7134_suspend,
 	.resume   = saa7134_resume
+#endif
 };
 
 static int saa7134_init(void)
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 34ca874d..75d0c5b 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -284,17 +284,6 @@
 	case VIDIOC_S_CTRL:
 		return saa7134_common_ioctl(dev, cmd, arg);
 
-	case VIDIOC_S_MPEGCOMP:
-		printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. "
-				    "Replace with VIDIOC_S_EXT_CTRLS!");
-		saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg);
-		ts_init_encoder(dev);
-		return 0;
-	case VIDIOC_G_MPEGCOMP:
-		printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. "
-				    "Replace with VIDIOC_G_EXT_CTRLS!");
-		saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg);
-		return 0;
 	case VIDIOC_S_EXT_CTRLS:
 		/* count == 0 is abused in saa6752hs.c, so that special
 		   case is handled here explicitly. */
@@ -342,7 +331,6 @@
 	.name          = "saa7134-empress",
 	.type          = 0 /* FIXME */,
 	.type2         = 0 /* FIXME */,
-	.hardware      = 0,
 	.fops          = &ts_fops,
 	.minor	       = -1,
 };
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 80d2644..3abaa1b 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -44,6 +44,14 @@
 static int ir_rc5_key_timeout = 115;
 module_param(ir_rc5_key_timeout, int, 0644);
 
+static int repeat_delay = 500;
+module_param(repeat_delay, int, 0644);
+MODULE_PARM_DESC(repeat_delay, "delay before key repeat started");
+static int repeat_period = 33;
+module_param(repeat_period, int, 0644);
+MODULE_PARM_DESC(repeat_period, "repeat period between"
+    "keypresses when key is down");
+
 #define dprintk(fmt, arg...)	if (ir_debug) \
 	printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
 #define i2cdprintk(fmt, arg...)    if (ir_debug) \
@@ -59,6 +67,13 @@
 	struct card_ir *ir = dev->remote;
 	u32 gpio, data;
 
+	/* here comes the additional handshake steps for some cards */
+	switch (dev->board) {
+	case SAA7134_BOARD_GOTVIEW_7135:
+		saa_setb(SAA7134_GPIO_GPSTATUS1, 0x80);
+		saa_clearb(SAA7134_GPIO_GPSTATUS1, 0x80);
+		break;
+	}
 	/* rising SAA7134_GPIO_GPRESCAN reads the status */
 	saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
 	saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
@@ -159,7 +174,7 @@
 	mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
 }
 
-static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
+void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
 {
 	if (ir->polling) {
 		setup_timer(&ir->timer, saa7134_input_timer,
@@ -182,7 +197,7 @@
 	}
 }
 
-static void saa7134_ir_stop(struct saa7134_dev *dev)
+void saa7134_ir_stop(struct saa7134_dev *dev)
 {
 	if (dev->remote->polling)
 		del_timer_sync(&dev->remote->timer);
@@ -285,10 +300,10 @@
 		break;
 	case SAA7134_BOARD_GOTVIEW_7135:
 		ir_codes     = ir_codes_gotview7135;
-		mask_keycode = 0x0003EC;
-		mask_keyup   = 0x008000;
+		mask_keycode = 0x0003CC;
 		mask_keydown = 0x000010;
-		polling	     = 50; // ms
+		polling	     = 5; /* ms */
+		saa_setb(SAA7134_GPIO_GPMODE1, 0x80);
 		break;
 	case SAA7134_BOARD_VIDEOMATE_TV_PVR:
 	case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
@@ -386,6 +401,10 @@
 	if (err)
 		goto err_out_stop;
 
+	/* the remote isn't as bouncy as a keyboard */
+	ir->dev->rep[REP_DELAY] = repeat_delay;
+	ir->dev->rep[REP_PERIOD] = repeat_period;
+
 	return 0;
 
  err_out_stop:
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index 1b9e39a..f8e304c 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -27,6 +27,7 @@
 #include <linux/kthread.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/freezer.h>
 #include <asm/div64.h>
 
 #include "saa7134-reg.h"
@@ -231,7 +232,7 @@
 	}
 
 	if (dev->hw_mute  == mute &&
-		dev->hw_input == in && !dev->inresume) {
+		dev->hw_input == in && !dev->insuspend) {
 		dprintk("mute/input: nothing to do [mute=%d,input=%s]\n",
 			mute,in->name);
 		return;
@@ -502,13 +503,17 @@
 	unsigned int i, audio, nscan;
 	int max1,max2,carrier,rx,mode,lastmode,default_carrier;
 
-	allow_signal(SIGTERM);
+
+	set_freezable();
+
 	for (;;) {
 		tvaudio_sleep(dev,-1);
-		if (kthread_should_stop() || signal_pending(current))
+		if (kthread_should_stop())
 			goto done;
 
 	restart:
+		try_to_freeze();
+
 		dev->thread.scan1 = dev->thread.scan2;
 		dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
 		dev->tvaudio  = NULL;
@@ -612,9 +617,12 @@
 
 		lastmode = 42;
 		for (;;) {
+
+			try_to_freeze();
+
 			if (tvaudio_sleep(dev,5000))
 				goto restart;
-			if (kthread_should_stop() || signal_pending(current))
+			if (kthread_should_stop())
 				break;
 			if (UNSET == dev->thread.mode) {
 				rx = tvaudio_getstereo(dev,&tvaudio[i]);
@@ -630,6 +638,7 @@
 	}
 
  done:
+	dev->thread.stopped = 1;
 	return 0;
 }
 
@@ -777,7 +786,8 @@
 	struct saa7134_dev *dev = data;
 	u32 value, norms, clock;
 
-	allow_signal(SIGTERM);
+
+	set_freezable();
 
 	clock = saa7134_boards[dev->board].audio_clock;
 	if (UNSET != audio_clock_override)
@@ -790,10 +800,13 @@
 
 	for (;;) {
 		tvaudio_sleep(dev,-1);
-		if (kthread_should_stop() || signal_pending(current))
+		if (kthread_should_stop())
 			goto done;
 
 	restart:
+
+		try_to_freeze();
+
 		dev->thread.scan1 = dev->thread.scan2;
 		dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
 
@@ -870,6 +883,7 @@
 	}
 
  done:
+	dev->thread.stopped = 1;
 	return 0;
 }
 
@@ -997,7 +1011,7 @@
 int saa7134_tvaudio_fini(struct saa7134_dev *dev)
 {
 	/* shutdown tvaudio thread */
-	if (dev->thread.thread)
+	if (dev->thread.thread && !dev->thread.stopped)
 		kthread_stop(dev->thread.thread);
 
 	saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */
@@ -1013,7 +1027,9 @@
 	} else if (dev->thread.thread) {
 		dev->thread.mode = UNSET;
 		dev->thread.scan2++;
-		wake_up_process(dev->thread.thread);
+
+		if (!dev->insuspend && !dev->thread.stopped)
+			wake_up_process(dev->thread.thread);
 	} else {
 		dev->automute = 0;
 		saa7134_tvaudio_setmute(dev);
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 471b927..3b9ffb4 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -560,15 +560,8 @@
 
 	dev->crop_current = dev->crop_defrect;
 
-	saa7134_set_decoder(dev);
+	saa7134_set_tvnorm_hw(dev);
 
-	if (card_in(dev, dev->ctl_input).tv) {
-		if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
-				&& ((card(dev).tuner_config == 1)
-				||  (card(dev).tuner_config == 2)))
-			saa7134_set_gpio(dev, 22, 5);
-		saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &norm->id);
-	}
 }
 
 static void video_mux(struct saa7134_dev *dev, int input)
@@ -579,7 +572,8 @@
 	saa7134_tvaudio_setinput(dev, &card_in(dev, input));
 }
 
-void saa7134_set_decoder(struct saa7134_dev *dev)
+
+static void saa7134_set_decoder(struct saa7134_dev *dev)
 {
 	int luma_control, sync_control, mux;
 
@@ -630,6 +624,19 @@
 	saa_writeb(SAA7134_RAW_DATA_OFFSET,       0x80);
 }
 
+void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)
+{
+	saa7134_set_decoder(dev);
+
+	if (card_in(dev, dev->ctl_input).tv) {
+		if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
+				&& ((card(dev).tuner_config == 1)
+				||  (card(dev).tuner_config == 2)))
+			saa7134_set_gpio(dev, 22, 5);
+		saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+	}
+}
+
 static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
 {
 	static const struct {
@@ -2352,7 +2359,6 @@
 	.name          = "saa7134-video",
 	.type          = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
 			 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
-	.hardware      = 0,
 	.fops          = &video_fops,
 	.minor         = -1,
 };
@@ -2361,7 +2367,6 @@
 {
 	.name          = "saa7134-vbi",
 	.type          = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
-	.hardware      = 0,
 	.fops          = &video_fops,
 	.minor         = -1,
 };
@@ -2370,7 +2375,6 @@
 {
 	.name          = "saa7134-radio",
 	.type          = VID_TYPE_TUNER,
-	.hardware      = 0,
 	.fops          = &radio_fops,
 	.minor         = -1,
 };
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 28ec680..66a390c 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -333,6 +333,7 @@
 	unsigned int               scan1;
 	unsigned int               scan2;
 	unsigned int               mode;
+	unsigned int		   stopped;
 };
 
 /* buffer for one video/vbi/ts frame */
@@ -524,7 +525,7 @@
 	unsigned int               hw_mute;
 	int                        last_carrier;
 	int                        nosignal;
-	unsigned int               inresume;
+	unsigned int               insuspend;
 
 	/* SAA7134_MPEG_* */
 	struct saa7134_ts          ts;
@@ -632,7 +633,7 @@
 
 void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm);
 int saa7134_videoport_init(struct saa7134_dev *dev);
-void saa7134_set_decoder(struct saa7134_dev *dev);
+void saa7134_set_tvnorm_hw(struct saa7134_dev *dev);
 
 int saa7134_common_ioctl(struct saa7134_dev *dev,
 			 unsigned int cmd, void *arg);
@@ -706,6 +707,8 @@
 void saa7134_input_fini(struct saa7134_dev *dev);
 void saa7134_input_irq(struct saa7134_dev *dev);
 void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
+void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir);
+void saa7134_ir_stop(struct saa7134_dev *dev);
 
 
 /*
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index 93fb04e..d5d7d6c 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -1231,7 +1231,6 @@
 	.owner =	THIS_MODULE,
 	.name =         "se401 USB camera",
 	.type =         VID_TYPE_CAPTURE,
-	.hardware =     VID_HARDWARE_SE401,
 	.fops =         &se401_fops,
 };
 
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 6991e06..5118479 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -3319,7 +3319,6 @@
 	strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
 	cam->v4ldev->owner = THIS_MODULE;
 	cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
-	cam->v4ldev->hardware = 0;
 	cam->v4ldev->fops = &sn9c102_fops;
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
index eb22046..3fb85af 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -1917,7 +1917,6 @@
 static struct video_device saa_template = {
 	.name = "SAA7146A",
 	.type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,
-	.hardware = VID_HARDWARE_SAA7146,
 	.fops = &saa_fops,
 	.minor = -1,
 };
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index 9e009a7..afc32aa 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -1398,7 +1398,6 @@
 	.owner =	THIS_MODULE,
 	.name =		"STV0680 USB camera",
 	.type =		VID_TYPE_CAPTURE,
-	.hardware =	VID_HARDWARE_SE401,
 	.fops =         &stv680_fops,
 	.release =	video_device_release,
 	.minor = 	-1,
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 9484308..6a77760 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -113,7 +113,7 @@
 static int fe_has_signal(struct tuner *t)
 {
 	struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
-	u16 strength;
+	u16 strength = 0;
 
 	if (fe_tuner_ops->get_rf_strength)
 		fe_tuner_ops->get_rf_strength(&t->fe, &strength);
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
index 491505d..3e93f80 100644
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -238,8 +238,8 @@
 	usb_to_input_id(dev, &input_dev->id);
 	input_dev->dev.parent = &dev->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY);
-	input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY);
+	input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
 
 	input_dev->private = cam;
 
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
index dd1a6d6..d847273 100644
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -102,8 +102,8 @@
 	usb_to_input_id(dev, &input_dev->id);
 	input_dev->dev.parent = &dev->dev;
 
-	input_dev->evbit[0] = BIT(EV_KEY);
-	input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+	input_dev->evbit[0] = BIT_MASK(EV_KEY);
+	input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
 
 	input_dev->private = cam;
 
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index 37ce36b..fb434b5 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -952,7 +952,6 @@
 static const struct video_device usbvideo_template = {
 	.owner =      THIS_MODULE,
 	.type =       VID_TYPE_CAPTURE,
-	.hardware =   VID_HARDWARE_CPIA,
 	.fops =       &usbvideo_fops,
 };
 
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index ff55512..da1ba02 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -955,7 +955,7 @@
 		request[7] = realShutter >> 8;
 	}
 
-	// Per John Markus Bjørndalen, byte at index 8 causes problems if it isn't 0
+	// Per John Markus Bjørndalen, byte at index 8 causes problems if it isn't 0
 	request[8] = 0;
 	// bytes 9-15 do not seem to affect exposure or image quality
 
@@ -1074,7 +1074,6 @@
 	.owner 		= THIS_MODULE,
 	.name 		= "ViCam-based USB Camera",
 	.type 		= VID_TYPE_CAPTURE,
-	.hardware 	= VID_HARDWARE_VICAM,
 	.fops 		= &vicam_fops,
 	.minor 		= -1,
 };
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index e2f3c01..36e689f 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -1400,7 +1400,6 @@
 static struct video_device usbvision_video_template = {
 	.owner             = THIS_MODULE,
 	.type		= VID_TYPE_TUNER | VID_TYPE_CAPTURE,
-	.hardware	= VID_HARDWARE_USBVISION,
 	.fops		= &usbvision_fops,
 	.name           = "usbvision-video",
 	.release	= video_device_release,
@@ -1455,7 +1454,6 @@
 {
 	.owner             = THIS_MODULE,
 	.type		= VID_TYPE_TUNER,
-	.hardware	= VID_HARDWARE_USBVISION,
 	.fops		= &usbvision_radio_fops,
 	.name           = "usbvision-radio",
 	.release	= video_device_release,
@@ -1492,7 +1490,6 @@
 {
 	.owner             = THIS_MODULE,
 	.type		= VID_TYPE_TUNER,
-	.hardware	= VID_HARDWARE_USBVISION,
 	.fops		= &usbvision_vbi_fops,
 	.release	= video_device_release,
 	.name           = "usbvision-vbi",
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 9eac65f..dcf22a3 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -144,7 +144,7 @@
 	[VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
 };
 
-static unsigned int __attribute_pure__
+static unsigned int __pure
 palette_to_pixelformat(unsigned int palette)
 {
 	if (palette < ARRAY_SIZE(palette2pixelformat))
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index c3440b2..1141b4b 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -37,7 +37,7 @@
  * Video4linux 1/2 integration by Justin Schoeman
  * <justin@suntiger.ee.up.ac.za>
  * 2.4 PROCFS support ported from 2.4 kernels by
- *  Iñaki García Etxebarria <garetxe@euskalnet.net>
+ *  Iñaki García Etxebarria <garetxe@euskalnet.net>
  * Makefile fix by "W. Michael Petullo" <mike@flyn.org>
  * 2.4 devfs support ported from 2.4 kernels by
  *  Dan Merillat <dan@merillat.org>
@@ -317,8 +317,6 @@
 	[_IOC_NR(VIDIOC_ENUM_FMT)]         = "VIDIOC_ENUM_FMT",
 	[_IOC_NR(VIDIOC_G_FMT)]            = "VIDIOC_G_FMT",
 	[_IOC_NR(VIDIOC_S_FMT)]            = "VIDIOC_S_FMT",
-	[_IOC_NR(VIDIOC_G_MPEGCOMP)]       = "VIDIOC_G_MPEGCOMP",
-	[_IOC_NR(VIDIOC_S_MPEGCOMP)]       = "VIDIOC_S_MPEGCOMP",
 	[_IOC_NR(VIDIOC_REQBUFS)]          = "VIDIOC_REQBUFS",
 	[_IOC_NR(VIDIOC_QUERYBUF)]         = "VIDIOC_QUERYBUF",
 	[_IOC_NR(VIDIOC_G_FBUF)]           = "VIDIOC_G_FBUF",
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 5599a36..89a44f1 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -967,6 +967,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(videobuf_cgmbuf);
 #endif
 
 /* --------------------------------------------------------------------- */
@@ -985,7 +986,6 @@
 EXPORT_SYMBOL_GPL(videobuf_querybuf);
 EXPORT_SYMBOL_GPL(videobuf_qbuf);
 EXPORT_SYMBOL_GPL(videobuf_dqbuf);
-EXPORT_SYMBOL_GPL(videobuf_cgmbuf);
 EXPORT_SYMBOL_GPL(videobuf_streamon);
 EXPORT_SYMBOL_GPL(videobuf_streamoff);
 
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 3eb6123..9ab94a7 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
+#include <linux/scatterlist.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
@@ -60,12 +61,13 @@
 	sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
 		pg = vmalloc_to_page(virt);
 		if (NULL == pg)
 			goto err;
 		BUG_ON(PageHighMem(pg));
-		sglist[i].page   = pg;
+		sg_set_page(&sglist[i], pg);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
@@ -86,13 +88,14 @@
 	sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL);
 	if (NULL == sglist)
 		return NULL;
+	sg_init_table(sglist, nr_pages);
 
 	if (NULL == pages[0])
 		goto nopage;
 	if (PageHighMem(pages[0]))
 		/* DMA to highmem pages might not work */
 		goto highmem;
-	sglist[0].page   = pages[0];
+	sg_set_page(&sglist[0], pages[0]);
 	sglist[0].offset = offset;
 	sglist[0].length = PAGE_SIZE - offset;
 	for (i = 1; i < nr_pages; i++) {
@@ -100,7 +103,7 @@
 			goto nopage;
 		if (PageHighMem(pages[i]))
 			goto highmem;
-		sglist[i].page   = pages[i];
+		sg_set_page(&sglist[i], pages[i]);
 		sglist[i].length = PAGE_SIZE;
 	}
 	return sglist;
diff --git a/drivers/media/video/videocodec.c b/drivers/media/video/videocodec.c
index f2bbd7a..87951ec 100644
--- a/drivers/media/video/videocodec.c
+++ b/drivers/media/video/videocodec.c
@@ -86,8 +86,8 @@
 	}
 
 	dprintk(2,
-		"videocodec_attach: '%s', type: %x, flags %lx, magic %lx\n",
-		master->name, master->type, master->flags, master->magic);
+		"videocodec_attach: '%s', flags %lx, magic %lx\n",
+		master->name, master->flags, master->magic);
 
 	if (!h) {
 		dprintk(1,
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 8d8e517..9611c39 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -1313,48 +1313,6 @@
 		ret=vfd->vidioc_cropcap(file, fh, p);
 		break;
 	}
-	case VIDIOC_G_MPEGCOMP:
-	{
-		struct v4l2_mpeg_compression *p=arg;
-
-		/*FIXME: Several fields not shown */
-		if (!vfd->vidioc_g_mpegcomp)
-			break;
-		ret=vfd->vidioc_g_mpegcomp(file, fh, p);
-		if (!ret)
-			dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
-					" ts_pid_video=%d, ts_pid_pcr=%d, "
-					"ps_size=%d, au_sample_rate=%d, "
-					"au_pesid=%c, vi_frame_rate=%d, "
-					"vi_frames_per_gop=%d, "
-					"vi_bframes_count=%d, vi_pesid=%c\n",
-					p->ts_pid_pmt,p->ts_pid_audio,
-					p->ts_pid_video,p->ts_pid_pcr,
-					p->ps_size, p->au_sample_rate,
-					p->au_pesid, p->vi_frame_rate,
-					p->vi_frames_per_gop,
-					p->vi_bframes_count, p->vi_pesid);
-		break;
-	}
-	case VIDIOC_S_MPEGCOMP:
-	{
-		struct v4l2_mpeg_compression *p=arg;
-		/*FIXME: Several fields not shown */
-		if (!vfd->vidioc_s_mpegcomp)
-			break;
-		dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
-				"ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
-				"au_sample_rate=%d, au_pesid=%c, "
-				"vi_frame_rate=%d, vi_frames_per_gop=%d, "
-				"vi_bframes_count=%d, vi_pesid=%c\n",
-				p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
-				p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
-				p->au_pesid, p->vi_frame_rate,
-				p->vi_frames_per_gop, p->vi_bframes_count,
-				p->vi_pesid);
-		ret=vfd->vidioc_s_mpegcomp(file, fh, p);
-		break;
-	}
 	case VIDIOC_G_JPEGCOMP:
 	{
 		struct v4l2_jpegcompression *p=arg;
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index b532aa2..ee73dc7 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -1119,7 +1119,6 @@
 static struct video_device vivi = {
 	.name		= "vivi",
 	.type		= VID_TYPE_CAPTURE,
-	.hardware	= 0,
 	.fops           = &vivi_fops,
 	.minor		= -1,
 //	.release	= video_device_release,
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 4736640..08aaae0 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -196,7 +196,6 @@
 	.owner		= THIS_MODULE,
 	.name           = W9966_DRIVERNAME,
 	.type           = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
-	.hardware       = VID_HARDWARE_W9966,
 	.fops           = &w9966_fops,
 };
 
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 9e7f3e6..2ae1430 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -3549,7 +3549,6 @@
 	strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
 	cam->v4ldev->owner = THIS_MODULE;
 	cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
-	cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
 	cam->v4ldev->fops = &w9968cf_fops;
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index 08a93c3..2c5665c 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -1985,7 +1985,6 @@
 	strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera");
 	cam->v4ldev->owner = THIS_MODULE;
 	cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
-	cam->v4ldev->hardware = 0;
 	cam->v4ldev->fops = &zc0301_fops;
 	cam->v4ldev->minor = video_nr[dev_nr];
 	cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
index 48da36a..6e0ac4c 100644
--- a/drivers/media/video/zoran_card.c
+++ b/drivers/media/video/zoran_card.c
@@ -1235,8 +1235,14 @@
 		return m;
 	}
 
-	m->magic = 0L; /* magic not used */
-	m->type = VID_HARDWARE_ZR36067;
+	/* magic and type are unused for master struct. Makes sense only at
+	   codec structs.
+	   In the past, .type were initialized to the old V4L1 .hardware
+	   value, as VID_HARDWARE_ZR36067
+	 */
+	m->magic = 0L;
+	m->type = 0;
+
 	m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
 	strncpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
 	m->data = zr;
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 1c14fa2..dd3d7d2 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -60,7 +60,6 @@
 
 #include <linux/spinlock.h>
 #define     MAP_NR(x)       virt_to_page(x)
-#define     ZORAN_HARDWARE  VID_HARDWARE_ZR36067
 #define     ZORAN_VID_TYPE  ( \
 				VID_TYPE_CAPTURE | \
 				VID_TYPE_OVERLAY | \
@@ -1285,7 +1284,7 @@
 	}
 
 	dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
-		ZR_DEVNAME(zr), current->comm, current->pid, zr->user);
+		ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
 
 	/* now, create the open()-specific file_ops struct */
 	fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
@@ -1358,7 +1357,7 @@
 	struct zoran *zr = fh->zr;
 
 	dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
-		ZR_DEVNAME(zr), current->comm, current->pid, zr->user);
+		ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
 
 	/* kernel locks (fs/device.c), so don't do that ourselves
 	 * (prevents deadlocks) */
@@ -4659,7 +4658,6 @@
 #ifdef CONFIG_VIDEO_V4L2
 	.type2 = ZORAN_V4L2_VID_FLAGS,
 #endif
-	.hardware = ZORAN_HARDWARE,
 	.fops = &zoran_fops,
 	.release = &zoran_vdev_release,
 	.minor = -1
diff --git a/drivers/message/i2o/README b/drivers/message/i2o/README
index a81f851..911fc30 100644
--- a/drivers/message/i2o/README
+++ b/drivers/message/i2o/README
@@ -30,13 +30,13 @@
 	Bug fixes
 	Core code extensions
 
-Auvo Häkkinen, University of Helsinki Finland
+Auvo Häkkinen, University of Helsinki Finland
 	LAN OSM code
 	/Proc interface to LAN class
 	Bug fixes
 	Core code extensions
 
-Taneli Vähäkangas, University of Helsinki Finland
+Taneli Vähäkangas, University of Helsinki Finland
 	Fixes to i2o_config
 
 CREDITS
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index ce8f1a3..6cbcc21 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -15,8 +15,8 @@
  *
  *	Fixes/additions:
  *		Philipp Rumpf
- *		Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
- *		Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
+ *		Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
+ *		Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
  *		Deepak Saxena <deepak@plexity.net>
  *		Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
  *		Alan Cox <alan@redhat.com>:
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 84e046e..c0fb77d 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -10,12 +10,12 @@
  *		Added basic ioctl() support
  *	Deepak Saxena (06/07/1999):
  *		Added software download ioctl (still testing)
- *	Auvo Häkkinen (09/10/1999):
+ *	Auvo Häkkinen (09/10/1999):
  *		Changes to i2o_cfg_reply(), ioctl_parms()
  *		Added ioct_validate()
- *	Taneli Vähäkangas (09/30/1999):
+ *	Taneli Vähäkangas (09/30/1999):
  *		Fixed ioctl_swdl()
- *	Taneli Vähäkangas (10/04/1999):
+ *	Taneli Vähäkangas (10/04/1999):
  *		Changed ioctl_swdl(), implemented ioctl_swul() and ioctl_swdel()
  *	Deepak Saxena (11/18/1999):
  *		Added event managmenet support
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
index 06892ac..6fdd072 100644
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/message/i2o/i2o_proc.c
@@ -19,8 +19,8 @@
  *
  *
  *	Fixes/additions:
- *		Juha Sievänen (Juha.Sievanen@cs.Helsinki.FI),
- *		Auvo Häkkinen (Auvo.Hakkinen@cs.Helsinki.FI)
+ *		Juha Sievänen (Juha.Sievanen@cs.Helsinki.FI),
+ *		Auvo Häkkinen (Auvo.Hakkinen@cs.Helsinki.FI)
  *		University of Helsinki, Department of Computer Science
  *			LAN entries
  *		Markus Lidel <Markus.Lidel@shadowconnect.com>
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index a1ec16a..7814a06 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -15,8 +15,8 @@
  *
  *	Fixes/additions:
  *		Philipp Rumpf
- *		Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
- *		Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
+ *		Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
+ *		Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
  *		Deepak Saxena <deepak@plexity.net>
  *		Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
  *		Alan Cox <alan@redhat.com>:
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
index 3661e6e..685a895 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -15,8 +15,8 @@
  *
  *	Fixes/additions:
  *		Philipp Rumpf
- *		Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
- *		Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
+ *		Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
+ *		Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
  *		Deepak Saxena <deepak@plexity.net>
  *		Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
  *		Alan Cox <alan@redhat.com>:
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index a20a51e..2571619 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -10,8 +10,8 @@
 	 ---help---
 	  This is the core driver for the Silicon Motion SM501 multimedia
 	  companion chip. This device is a multifunction device which may
-	  provide numerous interfaces including USB host controller USB gadget,
-	  Asyncronous Serial ports, Audio functions and a dual display video
+	  provide numerous interfaces including USB host controller, USB gadget,
+	  asynchronous serial ports, audio functions, and a dual display video
 	  interface. The device may be connected by PCI or local bus with
 	  varying functions enabled.
 
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 346c44e..b5e67c0 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -111,6 +111,21 @@
 
 	  If you have an ACPI-compatible ASUS laptop, say Y or M here.
 
+config FUJITSU_LAPTOP
+        tristate "Fujitsu Laptop Extras"
+        depends on X86
+        depends on ACPI
+        depends on BACKLIGHT_CLASS_DEVICE
+        ---help---
+	  This is a driver for laptops built by Fujitsu:
+
+	    * P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks
+	    * Possibly other Fujitsu laptop models
+
+	  It adds support for LCD brightness control.
+
+	  If you have a Fujitsu laptop, say Y or M here.
+
 config MSI_LAPTOP
         tristate "MSI Laptop Extras"
         depends on X86
@@ -134,6 +149,7 @@
 	tristate "Sony Laptop Extras"
 	depends on X86 && ACPI
 	select BACKLIGHT_CLASS_DEVICE
+	depends on INPUT
 	  ---help---
 	  This mini-driver drives the SNC and SPIC devices present in the ACPI
 	  BIOS of the Sony Vaio laptops.
@@ -156,6 +172,7 @@
 	select BACKLIGHT_CLASS_DEVICE
 	select HWMON
 	select NVRAM
+	depends on INPUT
 	---help---
 	  This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
 	  support for Fn-Fx key combinations, Bluetooth control, video
@@ -163,7 +180,7 @@
 	  For more information about this driver see 
 	  <file:Documentation/thinkpad-acpi.txt> and <http://ibm-acpi.sf.net/> .
 
-	  This driver was formely known as ibm-acpi.
+	  This driver was formerly known as ibm-acpi.
 
 	  If you have an IBM or Lenovo ThinkPad laptop, say Y or M here.
 
@@ -197,7 +214,7 @@
 	default y
 	---help---
 	  Allows the thinkpad_acpi driver to handle removable bays.  It will
-	  eletrically disable the device in the bay, and also generate
+	  electrically disable the device in the bay, and also generate
 	  notifications when the bay lever is ejected or inserted.
 
 	  If you are not sure, say Y here.
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a24c614..87f2685 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -15,4 +15,5 @@
 obj-$(CONFIG_SGI_IOC4)		+= ioc4.o
 obj-$(CONFIG_SONY_LAPTOP)	+= sony-laptop.o
 obj-$(CONFIG_THINKPAD_ACPI)	+= thinkpad_acpi.o
+obj-$(CONFIG_FUJITSU_LAPTOP)	+= fujitsu-laptop.o
 obj-$(CONFIG_EEPROM_93CX6)	+= eeprom_93cx6.o
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c
new file mode 100644
index 0000000..d366a6cc
--- /dev/null
+++ b/drivers/misc/fujitsu-laptop.c
@@ -0,0 +1,358 @@
+/*-*-linux-c-*-*/
+
+/*
+  Copyright (C) 2007 Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
+  Based on earlier work:
+    Copyright (C) 2003 Shane Spencer <shane@bogomip.com>
+    Adrian Yee <brewt-fujitsu@brewt.org>
+
+  Templated from msi-laptop.c which is copyright by its respective authors.
+
+  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.
+ */
+
+/*
+ * fujitsu-laptop.c - Fujitsu laptop support, providing access to additional
+ * features made available on a range of Fujitsu laptops including the
+ * P2xxx/P5xxx/S6xxx/S7xxx series.
+ *
+ * This driver exports a few files in /sys/devices/platform/fujitsu-laptop/;
+ * others may be added at a later date.
+ *
+ *   lcd_level - Screen brightness: contains a single integer in the
+ *   range 0..7. (rw)
+ *
+ * In addition to these platform device attributes the driver
+ * registers itself in the Linux backlight control subsystem and is
+ * available to userspace under /sys/class/backlight/fujitsu-laptop/.
+ *
+ * This driver has been tested on a Fujitsu Lifebook S7020.  It should
+ * work on most P-series and S-series Lifebooks, but YMMV.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <linux/autoconf.h>
+
+#define FUJITSU_DRIVER_VERSION "0.3"
+
+#define FUJITSU_LCD_N_LEVELS 8
+
+#define ACPI_FUJITSU_CLASS              "fujitsu"
+#define ACPI_FUJITSU_HID                "FUJ02B1"
+#define ACPI_FUJITSU_DRIVER_NAME        "Fujitsu laptop FUJ02B1 ACPI extras driver"
+#define ACPI_FUJITSU_DEVICE_NAME        "Fujitsu FUJ02B1"
+
+struct fujitsu_t {
+	acpi_handle acpi_handle;
+	struct backlight_device *bl_device;
+	struct platform_device *pf_device;
+
+	unsigned long fuj02b1_state;
+	unsigned int brightness_changed;
+	unsigned int brightness_level;
+};
+
+static struct fujitsu_t *fujitsu;
+
+/* Hardware access */
+
+static int set_lcd_level(int level)
+{
+	acpi_status status = AE_OK;
+	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+	struct acpi_object_list arg_list = { 1, &arg0 };
+	acpi_handle handle = NULL;
+
+	if (level < 0 || level >= FUJITSU_LCD_N_LEVELS)
+		return -EINVAL;
+
+	if (!fujitsu)
+		return -EINVAL;
+
+	status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SBLL not present\n"));
+		return -ENODEV;
+	}
+
+	arg0.integer.value = level;
+
+	status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	return 0;
+}
+
+static int get_lcd_level(void)
+{
+	unsigned long state = 0;
+	acpi_status status = AE_OK;
+
+	// Get the Brightness
+	status =
+	    acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state);
+	if (status < 0)
+		return status;
+
+	fujitsu->fuj02b1_state = state;
+	fujitsu->brightness_level = state & 0x0fffffff;
+
+	if (state & 0x80000000)
+		fujitsu->brightness_changed = 1;
+	else
+		fujitsu->brightness_changed = 0;
+
+	if (status < 0)
+		return status;
+
+	return fujitsu->brightness_level;
+}
+
+/* Backlight device stuff */
+
+static int bl_get_brightness(struct backlight_device *b)
+{
+	return get_lcd_level();
+}
+
+static int bl_update_status(struct backlight_device *b)
+{
+	return set_lcd_level(b->props.brightness);
+}
+
+static struct backlight_ops fujitsubl_ops = {
+	.get_brightness = bl_get_brightness,
+	.update_status = bl_update_status,
+};
+
+/* Platform device */
+
+static ssize_t show_lcd_level(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+
+	int ret;
+
+	ret = get_lcd_level();
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%i\n", ret);
+}
+
+static ssize_t store_lcd_level(struct device *dev,
+			       struct device_attribute *attr, const char *buf,
+			       size_t count)
+{
+
+	int level, ret;
+
+	if (sscanf(buf, "%i", &level) != 1
+	    || (level < 0 || level >= FUJITSU_LCD_N_LEVELS))
+		return -EINVAL;
+
+	ret = set_lcd_level(level);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
+
+static struct attribute *fujitsupf_attributes[] = {
+	&dev_attr_lcd_level.attr,
+	NULL
+};
+
+static struct attribute_group fujitsupf_attribute_group = {
+	.attrs = fujitsupf_attributes
+};
+
+static struct platform_driver fujitsupf_driver = {
+	.driver = {
+		   .name = "fujitsu-laptop",
+		   .owner = THIS_MODULE,
+		   }
+};
+
+/* ACPI device */
+
+int acpi_fujitsu_add(struct acpi_device *device)
+{
+	int result = 0;
+	int state = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_fujitsu_add");
+
+	if (!device)
+		return -EINVAL;
+
+	fujitsu->acpi_handle = device->handle;
+	sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME);
+	sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
+	acpi_driver_data(device) = fujitsu;
+
+	result = acpi_bus_get_power(fujitsu->acpi_handle, &state);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Error reading power state\n"));
+		goto end;
+	}
+
+	printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
+	       acpi_device_name(device), acpi_device_bid(device),
+	       !device->power.state ? "on" : "off");
+
+      end:
+
+	return result;
+}
+
+int acpi_fujitsu_remove(struct acpi_device *device, int type)
+{
+	ACPI_FUNCTION_TRACE("acpi_fujitsu_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return -EINVAL;
+	fujitsu->acpi_handle = 0;
+
+	return 0;
+}
+
+static const struct acpi_device_id fujitsu_device_ids[] = {
+	{ACPI_FUJITSU_HID, 0},
+	{"", 0},
+};
+
+static struct acpi_driver acpi_fujitsu_driver = {
+	.name = ACPI_FUJITSU_DRIVER_NAME,
+	.class = ACPI_FUJITSU_CLASS,
+	.ids = fujitsu_device_ids,
+	.ops = {
+		.add = acpi_fujitsu_add,
+		.remove = acpi_fujitsu_remove,
+		},
+};
+
+/* Initialization */
+
+static int __init fujitsu_init(void)
+{
+	int ret, result;
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	fujitsu = kmalloc(sizeof(struct fujitsu_t), GFP_KERNEL);
+	if (!fujitsu)
+		return -ENOMEM;
+	memset(fujitsu, 0, sizeof(struct fujitsu_t));
+
+	result = acpi_bus_register_driver(&acpi_fujitsu_driver);
+	if (result < 0) {
+		ret = -ENODEV;
+		goto fail_acpi;
+	}
+
+	/* Register backlight stuff */
+
+	fujitsu->bl_device =
+	    backlight_device_register("fujitsu-laptop", NULL, NULL,
+				      &fujitsubl_ops);
+	if (IS_ERR(fujitsu->bl_device))
+		return PTR_ERR(fujitsu->bl_device);
+
+	fujitsu->bl_device->props.max_brightness = FUJITSU_LCD_N_LEVELS - 1;
+	ret = platform_driver_register(&fujitsupf_driver);
+	if (ret)
+		goto fail_backlight;
+
+	/* Register platform stuff */
+
+	fujitsu->pf_device = platform_device_alloc("fujitsu-laptop", -1);
+	if (!fujitsu->pf_device) {
+		ret = -ENOMEM;
+		goto fail_platform_driver;
+	}
+
+	ret = platform_device_add(fujitsu->pf_device);
+	if (ret)
+		goto fail_platform_device1;
+
+	ret =
+	    sysfs_create_group(&fujitsu->pf_device->dev.kobj,
+			       &fujitsupf_attribute_group);
+	if (ret)
+		goto fail_platform_device2;
+
+	printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION
+	       " successfully loaded.\n");
+
+	return 0;
+
+      fail_platform_device2:
+
+	platform_device_del(fujitsu->pf_device);
+
+      fail_platform_device1:
+
+	platform_device_put(fujitsu->pf_device);
+
+      fail_platform_driver:
+
+	platform_driver_unregister(&fujitsupf_driver);
+
+      fail_backlight:
+
+	backlight_device_unregister(fujitsu->bl_device);
+
+      fail_acpi:
+
+	kfree(fujitsu);
+
+	return ret;
+}
+
+static void __exit fujitsu_cleanup(void)
+{
+	sysfs_remove_group(&fujitsu->pf_device->dev.kobj,
+			   &fujitsupf_attribute_group);
+	platform_device_unregister(fujitsu->pf_device);
+	platform_driver_unregister(&fujitsupf_driver);
+	backlight_device_unregister(fujitsu->bl_device);
+
+	acpi_bus_unregister_driver(&acpi_fujitsu_driver);
+
+	kfree(fujitsu);
+
+	printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n");
+}
+
+module_init(fujitsu_init);
+module_exit(fujitsu_cleanup);
+
+MODULE_AUTHOR("Jonathan Woithe");
+MODULE_DESCRIPTION("Fujitsu laptop extras support");
+MODULE_VERSION(FUJITSU_DRIVER_VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/ibmasm/remote.c b/drivers/misc/ibmasm/remote.c
index 0550ce0..477bb43 100644
--- a/drivers/misc/ibmasm/remote.c
+++ b/drivers/misc/ibmasm/remote.c
@@ -17,7 +17,7 @@
  *
  * Copyright (C) IBM Corporation, 2004
  *
- * Authors: Max Asböck <amax@us.ibm.com>
+ * Authors: Max Asböck <amax@us.ibm.com>
  *          Vernon Mauery <vernux@us.ibm.com>
  *
  */
@@ -226,9 +226,9 @@
 	mouse_dev->id.product = pdev->device;
 	mouse_dev->id.version = 1;
 	mouse_dev->dev.parent = sp->dev;
-	mouse_dev->evbit[0]  = BIT(EV_KEY) | BIT(EV_ABS);
-	mouse_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) |
-		BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+	mouse_dev->evbit[0]  = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	mouse_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
 	set_bit(BTN_TOUCH, mouse_dev->keybit);
 	mouse_dev->name = "ibmasm RSA I remote mouse";
 	input_set_abs_params(mouse_dev, ABS_X, 0, MOUSE_X_MAX, 0, 0);
@@ -239,7 +239,7 @@
 	keybd_dev->id.product = pdev->device;
 	keybd_dev->id.version = 2;
 	keybd_dev->dev.parent = sp->dev;
-	keybd_dev->evbit[0]  = BIT(EV_KEY);
+	keybd_dev->evbit[0]  = BIT_MASK(EV_KEY);
 	keybd_dev->name = "ibmasm RSA I remote keyboard";
 
 	for (i = 0; i < XLATE_SIZE; i++) {
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index 5108b7c..cd221fd 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -9,6 +9,7 @@
  *  You need an userspace library to cooperate with this driver. It (and other
  *  info) may be obtained here:
  *  http://www.fi.muni.cz/~xslaby/phantom.html
+ *  or alternatively, you might use OpenHaptics provided by Sensable.
  */
 
 #include <linux/kernel.h>
@@ -24,13 +25,14 @@
 #include <asm/atomic.h>
 #include <asm/io.h>
 
-#define PHANTOM_VERSION		"n0.9.5"
+#define PHANTOM_VERSION		"n0.9.7"
 
 #define PHANTOM_MAX_MINORS	8
 
 #define PHN_IRQCTL		0x4c    /* irq control in caddr space */
 
 #define PHB_RUNNING		1
+#define PHB_NOT_OH		2
 
 static struct class *phantom_class;
 static int phantom_major;
@@ -47,7 +49,11 @@
 	struct cdev cdev;
 
 	struct mutex open_lock;
-	spinlock_t ioctl_lock;
+	spinlock_t regs_lock;
+
+	/* used in NOT_OH mode */
+	struct phm_regs oregs;
+	u32 ctl_reg;
 };
 
 static unsigned char phantom_devices[PHANTOM_MAX_MINORS];
@@ -82,6 +88,7 @@
 	struct phm_regs rs;
 	struct phm_reg r;
 	void __user *argp = (void __user *)arg;
+	unsigned long flags;
 	unsigned int i;
 
 	if (_IOC_TYPE(cmd) != PH_IOC_MAGIC ||
@@ -96,32 +103,45 @@
 		if (r.reg > 7)
 			return -EINVAL;
 
-		spin_lock(&dev->ioctl_lock);
+		spin_lock_irqsave(&dev->regs_lock, flags);
 		if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
 				phantom_status(dev, dev->status | PHB_RUNNING)){
-			spin_unlock(&dev->ioctl_lock);
+			spin_unlock_irqrestore(&dev->regs_lock, flags);
 			return -ENODEV;
 		}
 
 		pr_debug("phantom: writing %x to %u\n", r.value, r.reg);
+
+		/* preserve amp bit (don't allow to change it when in NOT_OH) */
+		if (r.reg == PHN_CONTROL && (dev->status & PHB_NOT_OH)) {
+			r.value &= ~PHN_CTL_AMP;
+			r.value |= dev->ctl_reg & PHN_CTL_AMP;
+			dev->ctl_reg = r.value;
+		}
+
 		iowrite32(r.value, dev->iaddr + r.reg);
 		ioread32(dev->iaddr); /* PCI posting */
 
 		if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
 			phantom_status(dev, dev->status & ~PHB_RUNNING);
-		spin_unlock(&dev->ioctl_lock);
+		spin_unlock_irqrestore(&dev->regs_lock, flags);
 		break;
 	case PHN_SET_REGS:
 		if (copy_from_user(&rs, argp, sizeof(rs)))
 			return -EFAULT;
 
 		pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
-		spin_lock(&dev->ioctl_lock);
-		for (i = 0; i < min(rs.count, 8U); i++)
-			if ((1 << i) & rs.mask)
-				iowrite32(rs.values[i], dev->oaddr + i);
-		ioread32(dev->iaddr); /* PCI posting */
-		spin_unlock(&dev->ioctl_lock);
+		spin_lock_irqsave(&dev->regs_lock, flags);
+		if (dev->status & PHB_NOT_OH)
+			memcpy(&dev->oregs, &rs, sizeof(rs));
+		else {
+			u32 m = min(rs.count, 8U);
+			for (i = 0; i < m; i++)
+				if (rs.mask & BIT(i))
+					iowrite32(rs.values[i], dev->oaddr + i);
+			ioread32(dev->iaddr); /* PCI posting */
+		}
+		spin_unlock_irqrestore(&dev->regs_lock, flags);
 		break;
 	case PHN_GET_REG:
 		if (copy_from_user(&r, argp, sizeof(r)))
@@ -135,20 +155,35 @@
 		if (copy_to_user(argp, &r, sizeof(r)))
 			return -EFAULT;
 		break;
-	case PHN_GET_REGS:
+	case PHN_GET_REGS: {
+		u32 m;
+
 		if (copy_from_user(&rs, argp, sizeof(rs)))
 			return -EFAULT;
 
+		m = min(rs.count, 8U);
+
 		pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
-		spin_lock(&dev->ioctl_lock);
-		for (i = 0; i < min(rs.count, 8U); i++)
-			if ((1 << i) & rs.mask)
+		spin_lock_irqsave(&dev->regs_lock, flags);
+		for (i = 0; i < m; i++)
+			if (rs.mask & BIT(i))
 				rs.values[i] = ioread32(dev->iaddr + i);
-		spin_unlock(&dev->ioctl_lock);
+		spin_unlock_irqrestore(&dev->regs_lock, flags);
 
 		if (copy_to_user(argp, &rs, sizeof(rs)))
 			return -EFAULT;
 		break;
+	} case PHN_NOT_OH:
+		spin_lock_irqsave(&dev->regs_lock, flags);
+		if (dev->status & PHB_RUNNING) {
+			printk(KERN_ERR "phantom: you need to set NOT_OH "
+					"before you start the device!\n");
+			spin_unlock_irqrestore(&dev->regs_lock, flags);
+			return -EINVAL;
+		}
+		dev->status |= PHB_NOT_OH;
+		spin_unlock_irqrestore(&dev->regs_lock, flags);
+		break;
 	default:
 		return -ENOTTY;
 	}
@@ -171,8 +206,11 @@
 		return -EINVAL;
 	}
 
+	WARN_ON(dev->status & PHB_NOT_OH);
+
 	file->private_data = dev;
 
+	atomic_set(&dev->counter, 0);
 	dev->opened++;
 	mutex_unlock(&dev->open_lock);
 
@@ -187,6 +225,7 @@
 
 	dev->opened = 0;
 	phantom_status(dev, dev->status & ~PHB_RUNNING);
+	dev->status &= ~PHB_NOT_OH;
 
 	mutex_unlock(&dev->open_lock);
 
@@ -220,12 +259,32 @@
 static irqreturn_t phantom_isr(int irq, void *data)
 {
 	struct phantom_device *dev = data;
+	unsigned int i;
+	u32 ctl;
 
-	if (!(ioread32(dev->iaddr + PHN_CONTROL) & PHN_CTL_IRQ))
+	spin_lock(&dev->regs_lock);
+	ctl = ioread32(dev->iaddr + PHN_CONTROL);
+	if (!(ctl & PHN_CTL_IRQ)) {
+		spin_unlock(&dev->regs_lock);
 		return IRQ_NONE;
+	}
 
 	iowrite32(0, dev->iaddr);
 	iowrite32(0xc0, dev->iaddr);
+
+	if (dev->status & PHB_NOT_OH) {
+		struct phm_regs *r = &dev->oregs;
+		u32 m = min(r->count, 8U);
+
+		for (i = 0; i < m; i++)
+			if (r->mask & BIT(i))
+				iowrite32(r->values[i], dev->oaddr + i);
+
+		dev->ctl_reg ^= PHN_CTL_AMP;
+		iowrite32(dev->ctl_reg, dev->iaddr + PHN_CONTROL);
+	}
+	spin_unlock(&dev->regs_lock);
+
 	ioread32(dev->iaddr); /* PCI posting */
 
 	atomic_inc(&dev->counter);
@@ -297,7 +356,7 @@
 	}
 
 	mutex_init(&pht->open_lock);
-	spin_lock_init(&pht->ioctl_lock);
+	spin_lock_init(&pht->regs_lock);
 	init_waitqueue_head(&pht->wait);
 	cdev_init(&pht->cdev, &phantom_file_ops);
 	pht->cdev.owner = THIS_MODULE;
@@ -378,6 +437,8 @@
 	iowrite32(0, dev->caddr + PHN_IRQCTL);
 	ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
 
+	synchronize_irq(pdev->irq);
+
 	return 0;
 }
 
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index e73a71f0..bb13858 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -14,7 +14,7 @@
  *
  * Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
  *
- * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
  *
  * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
  *
@@ -277,7 +277,7 @@
 static DECLARE_WORK(sony_laptop_release_key_work,
 		do_sony_laptop_release_key);
 
-/* forward event to the input subsytem */
+/* forward event to the input subsystem */
 static void sony_laptop_report_input_event(u8 event)
 {
 	struct input_dev *jog_dev = sony_laptop_input.jog_dev;
@@ -411,9 +411,9 @@
 	jog_dev->id.bustype = BUS_ISA;
 	jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
 
-	jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE);
-	jog_dev->relbit[0] = BIT(REL_WHEEL);
+	jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+	jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE);
+	jog_dev->relbit[0] = BIT_MASK(REL_WHEEL);
 
 	error = input_register_device(jog_dev);
 	if (error)
@@ -1173,7 +1173,8 @@
 #define SONYPI_TYPE3_OFFSET	0x12
 
 struct sony_pic_ioport {
-	struct acpi_resource_io	io;
+	struct acpi_resource_io	io1;
+	struct acpi_resource_io	io2;
 	struct list_head	list;
 };
 
@@ -1443,11 +1444,11 @@
 {
 	u8 v1, v2;
 
-	wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2,
+	wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
 			ITERATIONS_LONG);
-	outb(dev, spic_dev.cur_ioport->io.minimum + 4);
-	v1 = inb_p(spic_dev.cur_ioport->io.minimum + 4);
-	v2 = inb_p(spic_dev.cur_ioport->io.minimum);
+	outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
+	v1 = inb_p(spic_dev.cur_ioport->io1.minimum + 4);
+	v2 = inb_p(spic_dev.cur_ioport->io1.minimum);
 	dprintk("sony_pic_call1: 0x%.4x\n", (v2 << 8) | v1);
 	return v2;
 }
@@ -1456,13 +1457,13 @@
 {
 	u8 v1;
 
-	wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2,
+	wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
 			ITERATIONS_LONG);
-	outb(dev, spic_dev.cur_ioport->io.minimum + 4);
-	wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2,
+	outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
+	wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
 			ITERATIONS_LONG);
-	outb(fn, spic_dev.cur_ioport->io.minimum);
-	v1 = inb_p(spic_dev.cur_ioport->io.minimum);
+	outb(fn, spic_dev.cur_ioport->io1.minimum);
+	v1 = inb_p(spic_dev.cur_ioport->io1.minimum);
 	dprintk("sony_pic_call2: 0x%.4x\n", v1);
 	return v1;
 }
@@ -1471,13 +1472,13 @@
 {
 	u8 v1;
 
-	wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG);
-	outb(dev, spic_dev.cur_ioport->io.minimum + 4);
-	wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG);
-	outb(fn, spic_dev.cur_ioport->io.minimum);
-	wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG);
-	outb(v, spic_dev.cur_ioport->io.minimum);
-	v1 = inb_p(spic_dev.cur_ioport->io.minimum);
+	wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
+	outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
+	wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
+	outb(fn, spic_dev.cur_ioport->io1.minimum);
+	wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
+	outb(v, spic_dev.cur_ioport->io1.minimum);
+	v1 = inb_p(spic_dev.cur_ioport->io1.minimum);
 	dprintk("sony_pic_call3: 0x%.4x\n", v1);
 	return v1;
 }
@@ -2074,7 +2075,18 @@
 
 	switch (resource->type) {
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
+		{
+			/* start IO enumeration */
+			struct sony_pic_ioport *ioport = kzalloc(sizeof(*ioport), GFP_KERNEL);
+			if (!ioport)
+				return AE_ERROR;
+
+			list_add(&ioport->list, &dev->ioports);
+			return AE_OK;
+		}
+
 	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
+		/* end IO enumeration */
 		return AE_OK;
 
 	case ACPI_RESOURCE_TYPE_IRQ:
@@ -2101,7 +2113,7 @@
 				if (!interrupt)
 					return AE_ERROR;
 
-				list_add_tail(&interrupt->list, &dev->interrupts);
+				list_add(&interrupt->list, &dev->interrupts);
 				interrupt->irq.triggering = p->triggering;
 				interrupt->irq.polarity = p->polarity;
 				interrupt->irq.sharable = p->sharable;
@@ -2113,18 +2125,27 @@
 	case ACPI_RESOURCE_TYPE_IO:
 		{
 			struct acpi_resource_io *io = &resource->data.io;
-			struct sony_pic_ioport *ioport = NULL;
+			struct sony_pic_ioport *ioport =
+				list_first_entry(&dev->ioports, struct sony_pic_ioport, list);
 			if (!io) {
 				dprintk("Blank IO resource\n");
 				return AE_OK;
 			}
 
-			ioport = kzalloc(sizeof(*ioport), GFP_KERNEL);
-			if (!ioport)
+			if (!ioport->io1.minimum) {
+				memcpy(&ioport->io1, io, sizeof(*io));
+				dprintk("IO1 at 0x%.4x (0x%.2x)\n", ioport->io1.minimum,
+						ioport->io1.address_length);
+			}
+			else if (!ioport->io2.minimum) {
+				memcpy(&ioport->io2, io, sizeof(*io));
+				dprintk("IO2 at 0x%.4x (0x%.2x)\n", ioport->io2.minimum,
+						ioport->io2.address_length);
+			}
+			else {
+				printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n");
 				return AE_ERROR;
-
-			list_add_tail(&ioport->list, &dev->ioports);
-			memcpy(&ioport->io, io, sizeof(*io));
+			}
 			return AE_OK;
 		}
 	default:
@@ -2199,10 +2220,22 @@
 {
 	acpi_status status;
 	int result = 0;
+	/* Type 1 resource layout is:
+	 *    IO
+	 *    IO
+	 *    IRQNoFlags
+	 *    End
+	 *
+	 * Type 2 and 3 resource layout is:
+	 *    IO
+	 *    IRQNoFlags
+	 *    End
+	 */
 	struct {
-		struct acpi_resource io_res;
-		struct acpi_resource irq_res;
-		struct acpi_resource end;
+		struct acpi_resource res1;
+		struct acpi_resource res2;
+		struct acpi_resource res3;
+		struct acpi_resource res4;
 	} *resource;
 	struct acpi_buffer buffer = { 0, NULL };
 
@@ -2217,21 +2250,49 @@
 	buffer.length = sizeof(*resource) + 1;
 	buffer.pointer = resource;
 
-	/* setup io resource */
-	resource->io_res.type = ACPI_RESOURCE_TYPE_IO;
-	resource->io_res.length = sizeof(struct acpi_resource);
-	memcpy(&resource->io_res.data.io, &ioport->io,
-			sizeof(struct acpi_resource_io));
+	/* setup Type 1 resources */
+	if (spic_dev.model == SONYPI_DEVICE_TYPE1) {
 
-	/* setup irq resource */
-	resource->irq_res.type = ACPI_RESOURCE_TYPE_IRQ;
-	resource->irq_res.length = sizeof(struct acpi_resource);
-	memcpy(&resource->irq_res.data.irq, &irq->irq,
-			sizeof(struct acpi_resource_irq));
-	/* we requested a shared irq */
-	resource->irq_res.data.irq.sharable = ACPI_SHARED;
+		/* setup io resources */
+		resource->res1.type = ACPI_RESOURCE_TYPE_IO;
+		resource->res1.length = sizeof(struct acpi_resource);
+		memcpy(&resource->res1.data.io, &ioport->io1,
+				sizeof(struct acpi_resource_io));
 
-	resource->end.type = ACPI_RESOURCE_TYPE_END_TAG;
+		resource->res2.type = ACPI_RESOURCE_TYPE_IO;
+		resource->res2.length = sizeof(struct acpi_resource);
+		memcpy(&resource->res2.data.io, &ioport->io2,
+				sizeof(struct acpi_resource_io));
+
+		/* setup irq resource */
+		resource->res3.type = ACPI_RESOURCE_TYPE_IRQ;
+		resource->res3.length = sizeof(struct acpi_resource);
+		memcpy(&resource->res3.data.irq, &irq->irq,
+				sizeof(struct acpi_resource_irq));
+		/* we requested a shared irq */
+		resource->res3.data.irq.sharable = ACPI_SHARED;
+
+		resource->res4.type = ACPI_RESOURCE_TYPE_END_TAG;
+
+	}
+	/* setup Type 2/3 resources */
+	else {
+		/* setup io resource */
+		resource->res1.type = ACPI_RESOURCE_TYPE_IO;
+		resource->res1.length = sizeof(struct acpi_resource);
+		memcpy(&resource->res1.data.io, &ioport->io1,
+				sizeof(struct acpi_resource_io));
+
+		/* setup irq resource */
+		resource->res2.type = ACPI_RESOURCE_TYPE_IRQ;
+		resource->res2.length = sizeof(struct acpi_resource);
+		memcpy(&resource->res2.data.irq, &irq->irq,
+				sizeof(struct acpi_resource_irq));
+		/* we requested a shared irq */
+		resource->res2.data.irq.sharable = ACPI_SHARED;
+
+		resource->res3.type = ACPI_RESOURCE_TYPE_END_TAG;
+	}
 
 	/* Attempt to set the resource */
 	dprintk("Evaluating _SRS\n");
@@ -2239,7 +2300,7 @@
 
 	/* check for total failure */
 	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR DRV_PFX "Error evaluating _SRS");
+		printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n");
 		result = -ENODEV;
 		goto end;
 	}
@@ -2268,11 +2329,14 @@
 
 	struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id;
 
-	ev = inb_p(dev->cur_ioport->io.minimum);
-	data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset);
+	ev = inb_p(dev->cur_ioport->io1.minimum);
+	if (dev->cur_ioport->io2.minimum)
+		data_mask = inb_p(dev->cur_ioport->io2.minimum);
+	else
+		data_mask = inb_p(dev->cur_ioport->io1.minimum + dev->evport_offset);
 
 	dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
-			ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset);
+			ev, data_mask, dev->cur_ioport->io1.minimum, dev->evport_offset);
 
 	if (ev == 0x00 || ev == 0xff)
 		return IRQ_HANDLED;
@@ -2323,8 +2387,11 @@
 	}
 
 	free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev);
-	release_region(spic_dev.cur_ioport->io.minimum,
-			spic_dev.cur_ioport->io.address_length);
+	release_region(spic_dev.cur_ioport->io1.minimum,
+			spic_dev.cur_ioport->io1.address_length);
+	if (spic_dev.cur_ioport->io2.minimum)
+		release_region(spic_dev.cur_ioport->io2.minimum,
+				spic_dev.cur_ioport->io2.address_length);
 
 	sonypi_compat_exit();
 
@@ -2397,14 +2464,36 @@
 		goto err_remove_input;
 
 	/* request io port */
-	list_for_each_entry(io, &spic_dev.ioports, list) {
-		if (request_region(io->io.minimum, io->io.address_length,
+	list_for_each_entry_reverse(io, &spic_dev.ioports, list) {
+		if (request_region(io->io1.minimum, io->io1.address_length,
 					"Sony Programable I/O Device")) {
-			dprintk("I/O port: 0x%.4x (0x%.4x) + 0x%.2x\n",
-					io->io.minimum, io->io.maximum,
-					io->io.address_length);
-			spic_dev.cur_ioport = io;
-			break;
+			dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n",
+					io->io1.minimum, io->io1.maximum,
+					io->io1.address_length);
+			/* Type 1 have 2 ioports */
+			if (io->io2.minimum) {
+				if (request_region(io->io2.minimum,
+						io->io2.address_length,
+						"Sony Programable I/O Device")) {
+					dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n",
+							io->io2.minimum, io->io2.maximum,
+							io->io2.address_length);
+					spic_dev.cur_ioport = io;
+					break;
+				}
+				else {
+					dprintk("Unable to get I/O port2: "
+							"0x%.4x (0x%.4x) + 0x%.2x\n",
+							io->io2.minimum, io->io2.maximum,
+							io->io2.address_length);
+					release_region(io->io1.minimum,
+							io->io1.address_length);
+				}
+			}
+			else {
+				spic_dev.cur_ioport = io;
+				break;
+			}
 		}
 	}
 	if (!spic_dev.cur_ioport) {
@@ -2414,7 +2503,7 @@
 	}
 
 	/* request IRQ */
-	list_for_each_entry(irq, &spic_dev.interrupts, list) {
+	list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) {
 		if (!request_irq(irq->irq.interrupts[0], sony_pic_irq,
 					IRQF_SHARED, "sony-laptop", &spic_dev)) {
 			dprintk("IRQ: %d - triggering: %d - "
@@ -2462,8 +2551,11 @@
 	free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev);
 
 err_release_region:
-	release_region(spic_dev.cur_ioport->io.minimum,
-			spic_dev.cur_ioport->io.address_length);
+	release_region(spic_dev.cur_ioport->io1.minimum,
+			spic_dev.cur_ioport->io1.address_length);
+	if (spic_dev.cur_ioport->io2.minimum)
+		release_region(spic_dev.cur_ioport->io2.minimum,
+				spic_dev.cur_ioport->io2.address_length);
 
 err_remove_compat:
 	sonypi_compat_exit();
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 81e068f..e953276 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -22,7 +22,7 @@
  */
 
 #define IBM_VERSION "0.16"
-#define TPACPI_SYSFS_VERSION 0x010000
+#define TPACPI_SYSFS_VERSION 0x020000
 
 /*
  *  Changelog:
@@ -117,6 +117,12 @@
 
 #define __unused __attribute__ ((unused))
 
+static enum {
+	TPACPI_LIFE_INIT = 0,
+	TPACPI_LIFE_RUNNING,
+	TPACPI_LIFE_EXITING,
+} tpacpi_lifecycle;
+
 /****************************************************************************
  ****************************************************************************
  *
@@ -342,6 +348,9 @@
 {
 	struct ibm_struct *ibm = data;
 
+	if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
+		return;
+
 	if (!ibm || !ibm->acpi || !ibm->acpi->notify)
 		return;
 
@@ -517,8 +526,10 @@
  ****************************************************************************/
 
 static struct platform_device *tpacpi_pdev;
+static struct platform_device *tpacpi_sensors_pdev;
 static struct device *tpacpi_hwmon;
 static struct input_dev *tpacpi_inputdev;
+static struct mutex tpacpi_inputdev_send_mutex;
 
 
 static int tpacpi_resume_handler(struct platform_device *pdev)
@@ -543,6 +554,12 @@
 	.resume = tpacpi_resume_handler,
 };
 
+static struct platform_driver tpacpi_hwmon_pdriver = {
+	.driver = {
+		.name = IBM_HWMON_DRVR_NAME,
+		.owner = THIS_MODULE,
+	},
+};
 
 /*************************************************************************
  * thinkpad-acpi driver attributes
@@ -692,6 +709,8 @@
 {
 	char *endp;
 
+	while (*buf && isspace(*buf))
+		buf++;
 	*value = simple_strtoul(buf, &endp, 0);
 	while (*endp && isspace(*endp))
 		endp++;
@@ -989,6 +1008,7 @@
 
 	int res, i;
 	int status;
+	int hkeyv;
 
 	vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
 
@@ -1014,18 +1034,35 @@
 			return res;
 
 		/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
-		   A30, R30, R31, T20-22, X20-21, X22-24 */
-		tp_features.hotkey_mask =
-			acpi_evalf(hkey_handle, NULL, "DHKN", "qv");
+		   A30, R30, R31, T20-22, X20-21, X22-24.  Detected by checking
+		   for HKEY interface version 0x100 */
+		if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
+			if ((hkeyv >> 8) != 1) {
+				printk(IBM_ERR "unknown version of the "
+				       "HKEY interface: 0x%x\n", hkeyv);
+				printk(IBM_ERR "please report this to %s\n",
+				       IBM_MAIL);
+			} else {
+				/*
+				 * MHKV 0x100 in A31, R40, R40e,
+				 * T4x, X31, and later
+				 * */
+				tp_features.hotkey_mask = 1;
+			}
+		}
 
 		vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
 			str_supported(tp_features.hotkey_mask));
 
 		if (tp_features.hotkey_mask) {
-			/* MHKA available in A31, R40, R40e, T4x, X31, and later */
 			if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
-					"MHKA", "qd"))
+					"MHKA", "qd")) {
+				printk(IBM_ERR
+				       "missing MHKA handler, "
+				       "please report this to %s\n",
+				       IBM_MAIL);
 				hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */
+			}
 		}
 
 		res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask);
@@ -1131,6 +1168,8 @@
 				  unsigned int keycode)
 {
 	if (keycode != KEY_RESERVED) {
+		mutex_lock(&tpacpi_inputdev_send_mutex);
+
 		input_report_key(tpacpi_inputdev, keycode, 1);
 		if (keycode == KEY_UNKNOWN)
 			input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
@@ -1142,6 +1181,8 @@
 			input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
 				    scancode);
 		input_sync(tpacpi_inputdev);
+
+		mutex_unlock(&tpacpi_inputdev_send_mutex);
 	}
 }
 
@@ -1149,18 +1190,47 @@
 {
 	int wlsw;
 
-	if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw))
+	mutex_lock(&tpacpi_inputdev_send_mutex);
+
+	if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) {
 		input_report_switch(tpacpi_inputdev,
 				    SW_RADIO, !!wlsw);
+		input_sync(tpacpi_inputdev);
+	}
+
+	mutex_unlock(&tpacpi_inputdev_send_mutex);
 }
 
 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
 {
 	u32 hkey;
 	unsigned int keycode, scancode;
-	int send_acpi_ev = 0;
+	int send_acpi_ev;
+	int ignore_acpi_ev;
 
-	if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
+	if (event != 0x80) {
+		printk(IBM_ERR "unknown HKEY notification event %d\n", event);
+		/* forward it to userspace, maybe it knows how to handle it */
+		acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+						ibm->acpi->device->dev.bus_id,
+						event, 0);
+		return;
+	}
+
+	while (1) {
+		if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
+			printk(IBM_ERR "failed to retrieve HKEY event\n");
+			return;
+		}
+
+		if (hkey == 0) {
+			/* queue empty */
+			return;
+		}
+
+		send_acpi_ev = 0;
+		ignore_acpi_ev = 0;
+
 		switch (hkey >> 12) {
 		case 1:
 			/* 0x1000-0x1FFF: key presses */
@@ -1182,9 +1252,11 @@
 			 * eat up known LID events */
 			if (hkey != 0x5001 && hkey != 0x5002) {
 				printk(IBM_ERR
-					"unknown LID-related hotkey event: 0x%04x\n",
-					hkey);
+				       "unknown LID-related HKEY event: 0x%04x\n",
+				       hkey);
 				send_acpi_ev = 1;
+			} else {
+				ignore_acpi_ev = 1;
 			}
 			break;
 		case 7:
@@ -1202,21 +1274,18 @@
 			printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey);
 			send_acpi_ev = 1;
 		}
-	} else {
-		printk(IBM_ERR "unknown hotkey notification event %d\n", event);
-		hkey = 0;
-		send_acpi_ev = 1;
-	}
 
-	/* Legacy events */
-	if (send_acpi_ev || hotkey_report_mode < 2)
-		acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
+		/* Legacy events */
+		if (!ignore_acpi_ev && (send_acpi_ev || hotkey_report_mode < 2)) {
+			acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
+		}
 
-	/* netlink events */
-	if (send_acpi_ev) {
-		acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
-						ibm->acpi->device->dev.bus_id,
-						event, hkey);
+		/* netlink events */
+		if (!ignore_acpi_ev && send_acpi_ev) {
+			acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+							ibm->acpi->device->dev.bus_id,
+							event, hkey);
+		}
 	}
 }
 
@@ -2812,7 +2881,7 @@
 
 	switch(thermal_read_mode) {
 	case TPACPI_THERMAL_TPEC_16:
-		res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+		res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
 				&thermal_temp_input16_group);
 		if (res)
 			return res;
@@ -2820,7 +2889,7 @@
 	case TPACPI_THERMAL_TPEC_8:
 	case TPACPI_THERMAL_ACPI_TMP07:
 	case TPACPI_THERMAL_ACPI_UPDT:
-		res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+		res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
 				&thermal_temp_input8_group);
 		if (res)
 			return res;
@@ -2837,13 +2906,13 @@
 {
 	switch(thermal_read_mode) {
 	case TPACPI_THERMAL_TPEC_16:
-		sysfs_remove_group(&tpacpi_pdev->dev.kobj,
+		sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
 				   &thermal_temp_input16_group);
 		break;
 	case TPACPI_THERMAL_TPEC_8:
 	case TPACPI_THERMAL_ACPI_TMP07:
 	case TPACPI_THERMAL_ACPI_UPDT:
-		sysfs_remove_group(&tpacpi_pdev->dev.kobj,
+		sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
 				   &thermal_temp_input16_group);
 		break;
 	case TPACPI_THERMAL_NONE:
@@ -3626,7 +3695,7 @@
 	__ATTR(fan1_input, S_IRUGO,
 		fan_fan1_input_show, NULL);
 
-/* sysfs fan fan_watchdog (driver) ------------------------------------- */
+/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */
 static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
 				     char *buf)
 {
@@ -3768,10 +3837,10 @@
 
 	if (fan_status_access_mode != TPACPI_FAN_NONE ||
 	    fan_control_access_mode != TPACPI_FAN_WR_NONE) {
-		rc = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+		rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
 					 &fan_attr_group);
 		if (!(rc < 0))
-			rc = driver_create_file(&tpacpi_pdriver.driver,
+			rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
 					&driver_attr_fan_watchdog);
 		if (rc < 0)
 			return rc;
@@ -3854,8 +3923,8 @@
 	vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n");
 
 	/* FIXME: can we really do this unconditionally? */
-	sysfs_remove_group(&tpacpi_pdev->dev.kobj, &fan_attr_group);
-	driver_remove_file(&tpacpi_pdriver.driver, &driver_attr_fan_watchdog);
+	sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group);
+	driver_remove_file(&tpacpi_hwmon_pdriver.driver, &driver_attr_fan_watchdog);
 
 	cancel_delayed_work(&fan_watchdog_task);
 	flush_scheduled_work();
@@ -3888,6 +3957,9 @@
 {
 	int rc;
 
+	if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
+		return;
+
 	printk(IBM_NOTICE "fan watchdog: enabling fan\n");
 	rc = fan_set_enable();
 	if (rc < 0) {
@@ -3908,7 +3980,8 @@
 	if (fan_watchdog_active)
 		cancel_delayed_work(&fan_watchdog_task);
 
-	if (fan_watchdog_maxinterval > 0) {
+	if (fan_watchdog_maxinterval > 0 &&
+	    tpacpi_lifecycle != TPACPI_LIFE_EXITING) {
 		fan_watchdog_active = 1;
 		if (!schedule_delayed_work(&fan_watchdog_task,
 				msecs_to_jiffies(fan_watchdog_maxinterval
@@ -4302,6 +4375,19 @@
  ****************************************************************************
  ****************************************************************************/
 
+/* sysfs name ---------------------------------------------------------- */
+static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", IBM_NAME);
+}
+
+static struct device_attribute dev_attr_thinkpad_acpi_pdev_name =
+	__ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL);
+
+/* --------------------------------------------------------------------- */
+
 /* /proc support */
 static struct proc_dir_entry *proc_dir;
 
@@ -4674,6 +4760,8 @@
 {
 	int ret, i;
 
+	tpacpi_lifecycle = TPACPI_LIFE_INIT;
+
 	/* Parameter checking */
 	if (hotkey_report_mode > 2)
 		return -EINVAL;
@@ -4702,19 +4790,31 @@
 
 	ret = platform_driver_register(&tpacpi_pdriver);
 	if (ret) {
-		printk(IBM_ERR "unable to register platform driver\n");
+		printk(IBM_ERR "unable to register main platform driver\n");
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
 	tp_features.platform_drv_registered = 1;
 
+	ret = platform_driver_register(&tpacpi_hwmon_pdriver);
+	if (ret) {
+		printk(IBM_ERR "unable to register hwmon platform driver\n");
+		thinkpad_acpi_module_exit();
+		return ret;
+	}
+	tp_features.sensors_pdrv_registered = 1;
+
 	ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
+	if (!ret) {
+		tp_features.platform_drv_attrs_registered = 1;
+		ret = tpacpi_create_driver_attributes(&tpacpi_hwmon_pdriver.driver);
+	}
 	if (ret) {
 		printk(IBM_ERR "unable to create sysfs driver attributes\n");
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
-	tp_features.platform_drv_attrs_registered = 1;
+	tp_features.sensors_pdrv_attrs_registered = 1;
 
 
 	/* Device initialization */
@@ -4727,7 +4827,26 @@
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
-	tpacpi_hwmon = hwmon_device_register(&tpacpi_pdev->dev);
+	tpacpi_sensors_pdev = platform_device_register_simple(
+							IBM_HWMON_DRVR_NAME,
+							-1, NULL, 0);
+	if (IS_ERR(tpacpi_sensors_pdev)) {
+		ret = PTR_ERR(tpacpi_sensors_pdev);
+		tpacpi_sensors_pdev = NULL;
+		printk(IBM_ERR "unable to register hwmon platform device\n");
+		thinkpad_acpi_module_exit();
+		return ret;
+	}
+	ret = device_create_file(&tpacpi_sensors_pdev->dev,
+				 &dev_attr_thinkpad_acpi_pdev_name);
+	if (ret) {
+		printk(IBM_ERR
+			"unable to create sysfs hwmon device attributes\n");
+		thinkpad_acpi_module_exit();
+		return ret;
+	}
+	tp_features.sensors_pdev_attrs_registered = 1;
+	tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev);
 	if (IS_ERR(tpacpi_hwmon)) {
 		ret = PTR_ERR(tpacpi_hwmon);
 		tpacpi_hwmon = NULL;
@@ -4735,6 +4854,7 @@
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
+	mutex_init(&tpacpi_inputdev_send_mutex);
 	tpacpi_inputdev = input_allocate_device();
 	if (!tpacpi_inputdev) {
 		printk(IBM_ERR "unable to allocate input device\n");
@@ -4769,6 +4889,7 @@
 		tp_features.input_device_registered = 1;
 	}
 
+	tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
 	return 0;
 }
 
@@ -4776,6 +4897,8 @@
 {
 	struct ibm_struct *ibm, *itmp;
 
+	tpacpi_lifecycle = TPACPI_LIFE_EXITING;
+
 	list_for_each_entry_safe_reverse(ibm, itmp,
 					 &tpacpi_all_drivers,
 					 all_drivers) {
@@ -4794,12 +4917,22 @@
 	if (tpacpi_hwmon)
 		hwmon_device_unregister(tpacpi_hwmon);
 
+	if (tp_features.sensors_pdev_attrs_registered)
+		device_remove_file(&tpacpi_sensors_pdev->dev,
+				   &dev_attr_thinkpad_acpi_pdev_name);
+	if (tpacpi_sensors_pdev)
+		platform_device_unregister(tpacpi_sensors_pdev);
 	if (tpacpi_pdev)
 		platform_device_unregister(tpacpi_pdev);
 
+	if (tp_features.sensors_pdrv_attrs_registered)
+		tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver);
 	if (tp_features.platform_drv_attrs_registered)
 		tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
 
+	if (tp_features.sensors_pdrv_registered)
+		platform_driver_unregister(&tpacpi_hwmon_pdriver);
+
 	if (tp_features.platform_drv_registered)
 		platform_driver_unregister(&tpacpi_pdriver);
 
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index acd5835..3abcc81 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -58,13 +58,14 @@
 
 #define IBM_NAME "thinkpad"
 #define IBM_DESC "ThinkPad ACPI Extras"
-#define IBM_FILE "thinkpad_acpi"
+#define IBM_FILE IBM_NAME "_acpi"
 #define IBM_URL "http://ibm-acpi.sf.net/"
 #define IBM_MAIL "ibm-acpi-devel@lists.sourceforge.net"
 
 #define IBM_PROC_DIR "ibm"
 #define IBM_ACPI_EVENT_PREFIX "ibm"
 #define IBM_DRVR_NAME IBM_FILE
+#define IBM_HWMON_DRVR_NAME IBM_NAME "_hwmon"
 
 #define IBM_LOG IBM_FILE ": "
 #define IBM_ERR	   KERN_ERR    IBM_LOG
@@ -171,6 +172,7 @@
 
 /* Device model */
 static struct platform_device *tpacpi_pdev;
+static struct platform_device *tpacpi_sensors_pdev;
 static struct device *tpacpi_hwmon;
 static struct platform_driver tpacpi_pdriver;
 static struct input_dev *tpacpi_inputdev;
@@ -233,22 +235,25 @@
 
 static struct {
 #ifdef CONFIG_THINKPAD_ACPI_BAY
-	u16 bay_status:1;
-	u16 bay_eject:1;
-	u16 bay_status2:1;
-	u16 bay_eject2:1;
+	u32 bay_status:1;
+	u32 bay_eject:1;
+	u32 bay_status2:1;
+	u32 bay_eject2:1;
 #endif
-	u16 bluetooth:1;
-	u16 hotkey:1;
-	u16 hotkey_mask:1;
-	u16 hotkey_wlsw:1;
-	u16 light:1;
-	u16 light_status:1;
-	u16 wan:1;
-	u16 fan_ctrl_status_undef:1;
-	u16 input_device_registered:1;
-	u16 platform_drv_registered:1;
-	u16 platform_drv_attrs_registered:1;
+	u32 bluetooth:1;
+	u32 hotkey:1;
+	u32 hotkey_mask:1;
+	u32 hotkey_wlsw:1;
+	u32 light:1;
+	u32 light_status:1;
+	u32 wan:1;
+	u32 fan_ctrl_status_undef:1;
+	u32 input_device_registered:1;
+	u32 platform_drv_registered:1;
+	u32 platform_drv_attrs_registered:1;
+	u32 sensors_pdrv_registered:1;
+	u32 sensors_pdrv_attrs_registered:1;
+	u32 sensors_pdev_attrs_registered:1;
 } tp_features;
 
 struct thinkpad_id_data {
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index a5d0354..9203a0b 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -13,6 +13,7 @@
 #include <linux/blkdev.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
+#include <linux/scatterlist.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -153,19 +154,21 @@
 			blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
 			blk_queue_max_segment_size(mq->queue, bouncesz);
 
-			mq->sg = kzalloc(sizeof(struct scatterlist),
+			mq->sg = kmalloc(sizeof(struct scatterlist),
 				GFP_KERNEL);
 			if (!mq->sg) {
 				ret = -ENOMEM;
 				goto cleanup_queue;
 			}
+			sg_init_table(mq->sg, 1);
 
-			mq->bounce_sg = kzalloc(sizeof(struct scatterlist) *
+			mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
 				bouncesz / 512, GFP_KERNEL);
 			if (!mq->bounce_sg) {
 				ret = -ENOMEM;
 				goto cleanup_queue;
 			}
+			sg_init_table(mq->bounce_sg, bouncesz / 512);
 		}
 	}
 #endif
@@ -302,12 +305,12 @@
 		BUG_ON(dst_len == 0);
 
 		if (dst_size == 0) {
-			dst_buf = page_address(dst->page) + dst->offset;
+			dst_buf = sg_virt(dst);
 			dst_size = dst->length;
 		}
 
 		if (src_size == 0) {
-			src_buf = page_address(src->page) + src->offset;
+			src_buf = sg_virt(dst);
 			src_size = src->length;
 		}
 
@@ -353,9 +356,7 @@
 		return 1;
 	}
 
-	mq->sg[0].page = virt_to_page(mq->bounce_buf);
-	mq->sg[0].offset = offset_in_page(mq->bounce_buf);
-	mq->sg[0].length = 0;
+	sg_init_one(mq->sg, mq->bounce_buf, 0);
 
 	while (sg_len) {
 		mq->sg[0].length += mq->bounce_sg[sg_len - 1].length;
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 7a452c2..b1edcef 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -149,7 +149,7 @@
 
 		sg = &data->sg[i];
 
-		sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+		sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
 		amount = min(size, sg->length);
 		size -= amount;
 
@@ -226,7 +226,7 @@
 		sg = &data->sg[host->transfer_index++];
 		pr_debug("sg = %p\n", sg);
 
-		sg->dma_address = dma_map_page(NULL, sg->page, sg->offset, sg->length, DMA_FROM_DEVICE);
+		sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE);
 
 		pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
 
@@ -283,7 +283,7 @@
 			int index;
 
 			/* Swap the contents of the buffer */
-			buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+			buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
 			pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
 
 			for (index = 0; index < (sg->length / 4); index++)
@@ -292,7 +292,7 @@
 			kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
 		}
 
-		flush_dcache_page(sg->page);
+		flush_dcache_page(sg_page(sg));
 	}
 
 	/* Is there another transfer to trigger? */
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index 92c4d0d..bcbb6d2 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -340,7 +340,7 @@
 
 	/* This is the pointer to the data buffer */
 	sg = &data->sg[host->pio.index];
-	sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+	sg_ptr = sg_virt(sg) + host->pio.offset;
 
 	/* This is the space left inside the buffer */
 	sg_len = data->sg[host->pio.index].length - host->pio.offset;
@@ -400,7 +400,7 @@
 
 	if (host->pio.index < host->dma.len) {
 		sg = &data->sg[host->pio.index];
-		sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+		sg_ptr = sg_virt(sg) + host->pio.offset;
 
 		/* This is the space left inside the buffer */
 		sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;
@@ -613,14 +613,11 @@
 
     			if (host->flags & HOST_F_XMIT){
       				ret = au1xxx_dbdma_put_source_flags(channel,
-					(void *) (page_address(sg->page) +
-						  sg->offset),
-					len, flags);
+					(void *) sg_virt(sg), len, flags);
 			}
     			else {
       				ret = au1xxx_dbdma_put_dest_flags(channel,
-					(void *) (page_address(sg->page) +
-						  sg->offset),
+					(void *) sg_virt(sg),
 					len, flags);
 			}
 
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index 6ebc41e..fc72e1f 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -262,7 +262,7 @@
 		}
 
 		/* Convert back to virtual address */
-		host->data_ptr = (u16*)(page_address(data->sg->page) + data->sg->offset);
+		host->data_ptr = (u16*)sg_virt(sg);
 		host->data_cnt = 0;
 
 		clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 7ae18ea..12c2d80 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -813,7 +813,7 @@
 					&& dir == DMA_FROM_DEVICE)
 				dir = DMA_BIDIRECTIONAL;
 
-			dma_addr = dma_map_page(dma_dev, sg->page, 0,
+			dma_addr = dma_map_page(dma_dev, sg_page(sg), 0,
 						PAGE_SIZE, dir);
 			if (direction == DMA_TO_DEVICE)
 				t->tx_dma = dma_addr + sg->offset;
@@ -822,7 +822,7 @@
 		}
 
 		/* allow pio too; we don't allow highmem */
-		kmap_addr = kmap(sg->page);
+		kmap_addr = kmap(sg_page(sg));
 		if (direction == DMA_TO_DEVICE)
 			t->tx_buf = kmap_addr + sg->offset;
 		else
@@ -855,8 +855,8 @@
 
 		/* discard mappings */
 		if (direction == DMA_FROM_DEVICE)
-			flush_kernel_dcache_page(sg->page);
-		kunmap(sg->page);
+			flush_kernel_dcache_page(sg_page(sg));
+		kunmap(sg_page(sg));
 		if (dma_dev)
 			dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
 
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 000e6a9..0f39c49 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -169,7 +169,7 @@
 	struct scatterlist *sg = host->sg_ptr;
 
 	local_irq_save(*flags);
-	return kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+	return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
 }
 
 static inline void mmci_kunmap_atomic(struct mmci_host *host, void *buffer, unsigned long *flags)
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 60a67df..971e18b 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -24,10 +24,10 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/clk.h>
+#include <linux/scatterlist.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/scatterlist.h>
 #include <asm/mach-types.h>
 
 #include <asm/arch/board.h>
@@ -383,7 +383,7 @@
 
 	sg = host->data->sg + host->sg_idx;
 	host->buffer_bytes_left = sg->length;
-	host->buffer = page_address(sg->page) + sg->offset;
+	host->buffer = sg_virt(sg);
 	if (host->buffer_bytes_left > host->total_bytes_left)
 		host->buffer_bytes_left = host->total_bytes_left;
 }
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index b397121..d7c5b94 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -13,6 +13,7 @@
 #include <linux/highmem.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
 
 #include <linux/mmc/host.h>
 
@@ -231,7 +232,7 @@
 
 static inline char* sdhci_sg_to_buffer(struct sdhci_host* host)
 {
-	return page_address(host->cur_sg->page) + host->cur_sg->offset;
+	return sg_virt(host->cur_sg);
 }
 
 static inline int sdhci_next_sg(struct sdhci_host* host)
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 9b90479..c11a3d2 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -192,7 +192,7 @@
 		}
 		off = sg[host->sg_pos].offset + host->block_pos;
 
-		pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+		pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
 		p_off = offset_in_page(off);
 		p_cnt = PAGE_SIZE - p_off;
 		p_cnt = min(p_cnt, cnt);
@@ -241,18 +241,18 @@
 		}
 		off = sg[host->sg_pos].offset + host->block_pos;
 
-		pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+		pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
 		p_off = offset_in_page(off);
 		p_cnt = PAGE_SIZE - p_off;
 		p_cnt = min(p_cnt, cnt);
 		p_cnt = min(p_cnt, t_size);
 
 		if (r_data->flags & MMC_DATA_WRITE)
-			tifm_sd_copy_page(host->bounce_buf.page,
+			tifm_sd_copy_page(sg_page(&host->bounce_buf),
 					  r_data->blksz - t_size,
 					  pg, p_off, p_cnt);
 		else if (r_data->flags & MMC_DATA_READ)
-			tifm_sd_copy_page(pg, p_off, host->bounce_buf.page,
+			tifm_sd_copy_page(pg, p_off, sg_page(&host->bounce_buf),
 					  r_data->blksz - t_size, p_cnt);
 
 		t_size -= p_cnt;
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 80db11c..fa4c8c5 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -269,7 +269,7 @@
 
 static inline char *wbsd_sg_to_buffer(struct wbsd_host *host)
 {
-	return page_address(host->cur_sg->page) + host->cur_sg->offset;
+	return sg_virt(host->cur_sg);
 }
 
 static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
@@ -283,7 +283,7 @@
 	len = data->sg_len;
 
 	for (i = 0; i < len; i++) {
-		sgbuf = page_address(sg[i].page) + sg[i].offset;
+		sgbuf = sg_virt(&sg[i]);
 		memcpy(dmabuf, sgbuf, sg[i].length);
 		dmabuf += sg[i].length;
 	}
@@ -300,7 +300,7 @@
 	len = data->sg_len;
 
 	for (i = 0; i < len; i++) {
-		sgbuf = page_address(sg[i].page) + sg[i].offset;
+		sgbuf = sg_virt(&sg[i]);
 		memcpy(sgbuf, dmabuf, sg[i].length);
 		dmabuf += sg[i].length;
 	}
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 3aa3dca..a9eb1c5 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -85,6 +85,7 @@
 static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
 			size_t len);
 
+static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
 static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr);
 #include "fwh_lock.h"
@@ -641,73 +642,13 @@
 /*
  *  *********** CHIP ACCESS FUNCTIONS ***********
  */
-
-static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
+static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	struct cfi_private *cfi = map->fldrv_priv;
 	map_word status, status_OK = CMD(0x80), status_PWS = CMD(0x01);
-	unsigned long timeo;
 	struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
-
- resettime:
-	timeo = jiffies + HZ;
- retry:
-	if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) {
-		/*
-		 * OK. We have possibility for contension on the write/erase
-		 * operations which are global to the real chip and not per
-		 * partition.  So let's fight it over in the partition which
-		 * currently has authority on the operation.
-		 *
-		 * The rules are as follows:
-		 *
-		 * - any write operation must own shared->writing.
-		 *
-		 * - any erase operation must own _both_ shared->writing and
-		 *   shared->erasing.
-		 *
-		 * - contension arbitration is handled in the owner's context.
-		 *
-		 * The 'shared' struct can be read and/or written only when
-		 * its lock is taken.
-		 */
-		struct flchip_shared *shared = chip->priv;
-		struct flchip *contender;
-		spin_lock(&shared->lock);
-		contender = shared->writing;
-		if (contender && contender != chip) {
-			/*
-			 * The engine to perform desired operation on this
-			 * partition is already in use by someone else.
-			 * Let's fight over it in the context of the chip
-			 * currently using it.  If it is possible to suspend,
-			 * that other partition will do just that, otherwise
-			 * it'll happily send us to sleep.  In any case, when
-			 * get_chip returns success we're clear to go ahead.
-			 */
-			int ret = spin_trylock(contender->mutex);
-			spin_unlock(&shared->lock);
-			if (!ret)
-				goto retry;
-			spin_unlock(chip->mutex);
-			ret = get_chip(map, contender, contender->start, mode);
-			spin_lock(chip->mutex);
-			if (ret) {
-				spin_unlock(contender->mutex);
-				return ret;
-			}
-			timeo = jiffies + HZ;
-			spin_lock(&shared->lock);
-			spin_unlock(contender->mutex);
-		}
-
-		/* We now own it */
-		shared->writing = chip;
-		if (mode == FL_ERASING)
-			shared->erasing = chip;
-		spin_unlock(&shared->lock);
-	}
+	unsigned long timeo = jiffies + HZ;
 
 	switch (chip->state) {
 
@@ -722,16 +663,11 @@
 			if (chip->priv && map_word_andequal(map, status, status_PWS, status_PWS))
 				break;
 
-			if (time_after(jiffies, timeo)) {
-				printk(KERN_ERR "%s: Waiting for chip to be ready timed out. Status %lx\n",
-				       map->name, status.x[0]);
-				return -EIO;
-			}
 			spin_unlock(chip->mutex);
 			cfi_udelay(1);
 			spin_lock(chip->mutex);
 			/* Someone else might have been playing with it. */
-			goto retry;
+			return -EAGAIN;
 		}
 
 	case FL_READY:
@@ -809,10 +745,82 @@
 		schedule();
 		remove_wait_queue(&chip->wq, &wait);
 		spin_lock(chip->mutex);
-		goto resettime;
+		return -EAGAIN;
 	}
 }
 
+static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
+{
+	int ret;
+
+ retry:
+	if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING
+			   || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) {
+		/*
+		 * OK. We have possibility for contention on the write/erase
+		 * operations which are global to the real chip and not per
+		 * partition.  So let's fight it over in the partition which
+		 * currently has authority on the operation.
+		 *
+		 * The rules are as follows:
+		 *
+		 * - any write operation must own shared->writing.
+		 *
+		 * - any erase operation must own _both_ shared->writing and
+		 *   shared->erasing.
+		 *
+		 * - contention arbitration is handled in the owner's context.
+		 *
+		 * The 'shared' struct can be read and/or written only when
+		 * its lock is taken.
+		 */
+		struct flchip_shared *shared = chip->priv;
+		struct flchip *contender;
+		spin_lock(&shared->lock);
+		contender = shared->writing;
+		if (contender && contender != chip) {
+			/*
+			 * The engine to perform desired operation on this
+			 * partition is already in use by someone else.
+			 * Let's fight over it in the context of the chip
+			 * currently using it.  If it is possible to suspend,
+			 * that other partition will do just that, otherwise
+			 * it'll happily send us to sleep.  In any case, when
+			 * get_chip returns success we're clear to go ahead.
+			 */
+			ret = spin_trylock(contender->mutex);
+			spin_unlock(&shared->lock);
+			if (!ret)
+				goto retry;
+			spin_unlock(chip->mutex);
+			ret = chip_ready(map, contender, contender->start, mode);
+			spin_lock(chip->mutex);
+
+			if (ret == -EAGAIN) {
+				spin_unlock(contender->mutex);
+				goto retry;
+			}
+			if (ret) {
+				spin_unlock(contender->mutex);
+				return ret;
+			}
+			spin_lock(&shared->lock);
+			spin_unlock(contender->mutex);
+		}
+
+		/* We now own it */
+		shared->writing = chip;
+		if (mode == FL_ERASING)
+			shared->erasing = chip;
+		spin_unlock(&shared->lock);
+	}
+	ret = chip_ready(map, chip, adr, mode);
+	if (ret == -EAGAIN)
+		goto retry;
+
+	return ret;
+}
+
 static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 2a2a125..a592fc0 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -54,7 +54,7 @@
 	help
 	  This is the total width of the data bus of the flash devices
 	  in octets. For example, if you have a data bus width of 32
-	  bits, you would set the bus width octect value to 4. This is
+	  bits, you would set the bus width octet value to 4. This is
 	  used internally by the CFI drivers.
 	  Ignore this option if you use run-time physmap configuration
 	  (i.e., run-time calling physmap_configure()).
@@ -73,12 +73,12 @@
 	depends on PMC_MSP && MTD_CFI
 	select MTD_PARTITIONS
 	help
-	  This provides a 'mapping' driver which support the way
-          in which user-programmable flash chips are connected on the
-          PMC-Sierra MSP eval/demo boards
+	  This provides a 'mapping' driver which supports the way
+	  in which user-programmable flash chips are connected on the
+	  PMC-Sierra MSP eval/demo boards.
 
 choice
-	prompt "Maximum mappable memory avialable for flash IO"
+	prompt "Maximum mappable memory available for flash IO"
 	depends on MTD_PMC_MSP_EVM
 	default MSP_FLASH_MAP_LIMIT_32M
 
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 8f9c3ba..246d451 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -300,7 +300,7 @@
 	  via platform_data.
 
 config MTD_ALAUDA
-	tristate "MTD driver for Olympus MAUSB-10 and Fijufilm DPC-R1"
+	tristate "MTD driver for Olympus MAUSB-10 and Fujifilm DPC-R1"
 	depends on MTD_NAND && USB
 	help
 	  These two (and possibly other) Alauda-based cardreaders for
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index ab9f5c5..0e72153 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -220,7 +220,7 @@
 		}
 	}
 	/* If the parity is wrong, no rescue possible */
-	return parity ? -1 : nerr;
+	return parity ? -EBADMSG : nerr;
 }
 
 static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
@@ -1034,7 +1034,7 @@
 		WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
 	else
 		WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
-	if (no_ecc_failures && (ret == -1)) {
+	if (no_ecc_failures && (ret == -EBADMSG)) {
 		printk(KERN_ERR "suppressing ECC failure\n");
 		ret = 0;
 	}
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index b4e0e77..e29c1da 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -789,7 +789,7 @@
 		int stat;
 
 		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
-		if (stat == -1)
+		if (stat < 0)
 			mtd->ecc_stats.failed++;
 		else
 			mtd->ecc_stats.corrected += stat;
@@ -833,7 +833,7 @@
 		int stat;
 
 		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
-		if (stat == -1)
+		if (stat < 0)
 			mtd->ecc_stats.failed++;
 		else
 			mtd->ecc_stats.corrected += stat;
@@ -874,7 +874,7 @@
 		chip->read_buf(mtd, oob, eccbytes);
 		stat = chip->ecc.correct(mtd, p, oob, NULL);
 
-		if (stat == -1)
+		if (stat < 0)
 			mtd->ecc_stats.failed++;
 		else
 			mtd->ecc_stats.corrected += stat;
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index fde593e..9003a135 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -189,7 +189,7 @@
 	if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1)
 		return 1;
 
-	return -1;
+	return -EBADMSG;
 }
 EXPORT_SYMBOL(nand_correct_data);
 
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index a757480..10490b4 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -511,7 +511,7 @@
 	}
 
 	if (ns->options & OPT_SMALLPAGE) {
-		if (ns->geom.totsz < (64 << 20)) {
+		if (ns->geom.totsz < (32 << 20)) {
 			ns->geom.pgaddrbytes  = 3;
 			ns->geom.secaddrbytes = 2;
 		} else {
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index b79a9cf..66f76e9 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -488,12 +488,24 @@
 	readsb(this->IO_ADDR_R, buf, len);
 }
 
+static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+	readsl(info->regs + S3C2440_NFDATA, buf, len / 4);
+}
+
 static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
 {
 	struct nand_chip *this = mtd->priv;
 	writesb(this->IO_ADDR_W, buf, len);
 }
 
+static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+	writesl(info->regs + S3C2440_NFDATA, buf, len / 4);
+}
+
 /* device management functions */
 
 static int s3c2410_nand_remove(struct platform_device *pdev)
@@ -604,6 +616,8 @@
 		info->sel_bit	= S3C2440_NFCONT_nFCE;
 		chip->cmd_ctrl  = s3c2440_nand_hwcontrol;
 		chip->dev_ready = s3c2440_nand_devready;
+		chip->read_buf  = s3c2440_nand_read_buf;
+		chip->write_buf	= s3c2440_nand_write_buf;
 		break;
 
 	case TYPE_S3C2412:
@@ -696,7 +710,7 @@
 
 	info->clk = clk_get(&pdev->dev, "nand");
 	if (IS_ERR(info->clk)) {
-		dev_err(&pdev->dev, "failed to get clock");
+		dev_err(&pdev->dev, "failed to get clock\n");
 		err = -ENOENT;
 		goto exit_error;
 	}
diff --git a/drivers/mtd/onenand/onenand_sim.c b/drivers/mtd/onenand/onenand_sim.c
index 0d89ad5..d64200b 100644
--- a/drivers/mtd/onenand/onenand_sim.c
+++ b/drivers/mtd/onenand/onenand_sim.c
@@ -88,11 +88,11 @@
 
 /**
  * onenand_lock_handle - Handle Lock scheme
- * @param this		OneNAND device structure
- * @param cmd		The command to be sent
+ * @this:		OneNAND device structure
+ * @cmd:		The command to be sent
  *
  * Send lock command to OneNAND device.
- * The lock scheme is depends on chip type.
+ * The lock scheme depends on chip type.
  */
 static void onenand_lock_handle(struct onenand_chip *this, int cmd)
 {
@@ -131,8 +131,8 @@
 
 /**
  * onenand_bootram_handle - Handle BootRAM area
- * @param this		OneNAND device structure
- * @param cmd		The command to be sent
+ * @this:		OneNAND device structure
+ * @cmd:		The command to be sent
  *
  * Emulate BootRAM area. It is possible to do basic operation using BootRAM.
  */
@@ -153,10 +153,10 @@
 
 /**
  * onenand_update_interrupt - Set interrupt register
- * @param this         OneNAND device structure
- * @param cmd          The command to be sent
+ * @this:         OneNAND device structure
+ * @cmd:          The command to be sent
  *
- * Update interrupt register. The status is depends on command.
+ * Update interrupt register. The status depends on command.
  */
 static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
 {
@@ -189,11 +189,12 @@
 }
 
 /**
- * onenand_check_overwrite - Check over-write if happend
- * @param dest		The destination pointer
- * @param src		The source pointer
- * @param count		The length to be check
- * @return		0 on same, otherwise 1
+ * onenand_check_overwrite - Check if over-write happened
+ * @dest:		The destination pointer
+ * @src:		The source pointer
+ * @count:		The length to be check
+ *
+ * Returns:		0 on same, otherwise 1
  *
  * Compare the source with destination
  */
@@ -213,10 +214,10 @@
 
 /**
  * onenand_data_handle - Handle OneNAND Core and DataRAM
- * @param this		OneNAND device structure
- * @param cmd		The command to be sent
- * @param dataram	Which dataram used
- * @param offset	The offset to OneNAND Core
+ * @this:		OneNAND device structure
+ * @cmd:		The command to be sent
+ * @dataram:		Which dataram used
+ * @offset:		The offset to OneNAND Core
  *
  * Copy data from OneNAND Core to DataRAM (read)
  * Copy data from DataRAM to OneNAND Core (write)
@@ -295,8 +296,8 @@
 
 /**
  * onenand_command_handle - Handle command
- * @param this		OneNAND device structure
- * @param cmd		The command to be sent
+ * @this:		OneNAND device structure
+ * @cmd:		The command to be sent
  *
  * Emulate OneNAND command.
  */
@@ -350,8 +351,8 @@
 
 /**
  * onenand_writew - [OneNAND Interface] Emulate write operation
- * @param value		value to write
- * @param addr		address to write
+ * @value:		value to write
+ * @addr:		address to write
  *
  * Write OneNAND register with value
  */
@@ -373,7 +374,7 @@
 
 /**
  * flash_init - Initialize OneNAND simulator
- * @param flash		OneNAND simulaotr data strucutres
+ * @flash:		OneNAND simulator data strucutres
  *
  * Initialize OneNAND simulator.
  */
@@ -416,7 +417,7 @@
 
 /**
  * flash_exit - Clean up OneNAND simulator
- * @param flash		OneNAND simulaotr data strucutres
+ * @flash:		OneNAND simulator data structures
  *
  * Clean up OneNAND simulator.
  */
@@ -424,7 +425,6 @@
 {
 	vfree(ONENAND_CORE(flash));
 	kfree(flash->base);
-	kfree(flash);
 }
 
 static int __init onenand_sim_init(void)
@@ -449,7 +449,7 @@
 	info->onenand.write_word = onenand_writew;
 
 	if (flash_init(&info->flash)) {
-		printk(KERN_ERR "Unable to allocat flash.\n");
+		printk(KERN_ERR "Unable to allocate flash.\n");
 		kfree(ffchars);
 		kfree(info);
 		return -ENOMEM;
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index a4f1bf3..6330c8c 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1309,7 +1309,7 @@
 	struct ubi_device *ubi = u;
 
 	ubi_msg("background thread \"%s\" started, PID %d",
-		ubi->bgt_name, current->pid);
+		ubi->bgt_name, task_pid_nr(current));
 
 	set_freezable();
 	for (;;) {
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 862f472..6f8e7d4 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1491,7 +1491,7 @@
 	struct vortex_private *vp = netdev_priv(dev);
 	void __iomem *ioaddr = vp->ioaddr;
 	unsigned int config;
-	int i, mii_reg1, mii_reg5, err;
+	int i, mii_reg1, mii_reg5, err = 0;
 
 	if (VORTEX_PCI(vp)) {
 		pci_set_power_state(VORTEX_PCI(vp), PCI_D0);	/* Go active */
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 973b684..eef6fec 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -73,7 +73,7 @@
 
 		Jean-Jacques Michel - bug fix
 
-		Tobias Ringström - Rx interrupt status checking suggestion
+		Tobias Ringström - Rx interrupt status checking suggestion
 
 		Andrew Morton - Clear blocked signals, avoid
 		buffer overrun setting current->comm.
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 83d52c8..2538816 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -855,7 +855,7 @@
 	depends on BFIN_MAC && BF537
 	default y
 	help
-	  To get maximum network performace, you should use L1 memory as rx/tx buffers.
+	  To get maximum network performance, you should use L1 memory as rx/tx buffers.
 	  Say N here if you want to reserve L1 memory for other uses.
 
 config BFIN_TX_DESC_NUM
@@ -1293,9 +1293,6 @@
 	  deployed on potentially unfriendly networks (e.g. in a firewall),
 	  then say Y here.
 
-	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-	  information.
-
 	  If in doubt, say N.
 
 config AMD8111_ETH
@@ -1313,7 +1310,7 @@
 	  will be called amd8111e.
 
 config AMD8111E_NAPI
-	bool "Enable NAPI support"
+	bool "Use RX polling (NAPI)"
 	depends on AMD8111_ETH
 	help
 	  NAPI is a new driver API designed to reduce CPU and interrupt load
@@ -1324,9 +1321,6 @@
 	  deployed on potentially unfriendly networks (e.g. in a firewall),
 	  then say Y here.
 
-	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-	  information.
-
 	  If in doubt, say N.
 
 config ADAPTEC_STARFIRE
@@ -1355,9 +1349,6 @@
 	  deployed on potentially unfriendly networks (e.g. in a firewall),
 	  then say Y here.
 
-	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-	  information.
-
 	  If in doubt, say N.
 
 config AC3200
@@ -1431,7 +1422,7 @@
 	  called forcedeth.
 
 config FORCEDETH_NAPI
-	bool "Use Rx and Tx Polling (NAPI) (EXPERIMENTAL)"
+	bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
 	depends on FORCEDETH && EXPERIMENTAL
 	help
 	  NAPI is a new driver API designed to reduce CPU and interrupt load
@@ -1442,9 +1433,6 @@
 	  deployed on potentially unfriendly networks (e.g. in a firewall),
 	  then say Y here.
 
-	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-	  information.
-
 	  If in doubt, say N.
 
 config CS89x0
@@ -1756,9 +1744,6 @@
 	  deployed on potentially unfriendly networks (e.g. in a firewall),
 	  then say Y here.
 
-	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-	  information.
-
 config LAN_SAA9730
 	bool "Philips SAA9730 Ethernet support"
 	depends on NET_PCI && PCI && MIPS_ATLAS
@@ -2003,9 +1988,6 @@
 	  deployed on potentially unfriendly networks (e.g. in a firewall),
 	  then say Y here.
 
-	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-	  information.
-
 	  If in doubt, say N.
 
 config E1000_DISABLE_PACKET_SPLIT
@@ -2099,7 +2081,7 @@
 	  will be called r8169.  This is recommended.
 
 config R8169_NAPI
-	bool "Use Rx and Tx Polling (NAPI) (EXPERIMENTAL)"
+	bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
 	depends on R8169 && EXPERIMENTAL
 	help
 	  NAPI is a new driver API designed to reduce CPU and interrupt load
@@ -2110,9 +2092,6 @@
 	  deployed on potentially unfriendly networks (e.g. in a firewall),
 	  then say Y here.
 
-	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-	  information.
-
 	  If in doubt, say N.
 
 config R8169_VLAN
@@ -2364,7 +2343,7 @@
 	  and MPC86xx family of chips, and the FEC on the 8540.
 
 config GFAR_NAPI
-	bool "NAPI Support"
+	bool "Use Rx Polling (NAPI)"
 	depends on GIANFAR
 
 config UCC_GETH
@@ -2376,7 +2355,7 @@
 	  which is available on some Freescale SOCs.
 
 config UGETH_NAPI
-	bool "NAPI Support"
+	bool "Use Rx Polling (NAPI)"
 	depends on UCC_GETH
 
 config UGETH_MAGIC_PACKET
@@ -2494,7 +2473,7 @@
 
 config EHEA
 	tristate "eHEA Ethernet support"
-	depends on IBMEBUS
+	depends on IBMEBUS && INET
 	select INET_LRO
 	---help---
 	  This driver supports the IBM pSeries eHEA ethernet adapter.
@@ -2559,9 +2538,6 @@
 	  deployed on potentially unfriendly networks (e.g. in a firewall),
 	  then say Y here.
 
-	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-	  information.
-
 	  If in doubt, say N.
 
 config S2IO
@@ -2584,14 +2560,11 @@
 	  deployed on potentially unfriendly networks (e.g. in a firewall),
 	  then say Y here.
 
-	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-	  information.
-
 	  If in doubt, say N.
 
 config MYRI10GE
 	tristate "Myricom Myri-10G Ethernet support"
-	depends on PCI
+	depends on PCI && INET
 	select FW_LOADER
 	select CRC32
 	select INET_LRO
@@ -3127,4 +3100,10 @@
 config NET_POLL_CONTROLLER
 	def_bool NETPOLL
 
+config VIRTIO_NET
+	tristate "Virtio network driver (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && VIRTIO
+	---help---
+	  This is the virtual network driver for lguest.  Say Y or M.
+
 endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 22f78cb..5932620 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -183,7 +183,6 @@
 obj-$(CONFIG_HPLANCE) += hplance.o 7990.o
 obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o
 obj-$(CONFIG_EQUALIZER) += eql.o
-obj-$(CONFIG_LGUEST_NET) += lguest_net.o
 obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
 obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
 obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
@@ -243,3 +242,4 @@
 
 obj-$(CONFIG_NETXEN_NIC) += netxen/
 obj-$(CONFIG_NIU) += niu.o
+obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 1cc74ec..eebf5bb 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -1111,7 +1111,7 @@
 
 	return new_stats;
 }
-/* This function recalculate the interupt coalescing  mode on every interrupt
+/* This function recalculate the interrupt coalescing  mode on every interrupt
 according to the datarate and the packet rate.
 */
 static int amd8111e_calc_coalesce(struct net_device *dev)
diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c
index 3fa3bcc..10f3a19 100644
--- a/drivers/net/ariadne.c
+++ b/drivers/net/ariadne.c
@@ -1,7 +1,7 @@
 /*
  *  Amiga Linux/m68k Ariadne Ethernet Driver
  *
- *  © Copyright 1995-2003 by Geert Uytterhoeven (geert@linux-m68k.org)
+ *  © Copyright 1995-2003 by Geert Uytterhoeven (geert@linux-m68k.org)
  *			     Peter De Schrijver (p2@mind.be)
  *
  *  ---------------------------------------------------------------------------
diff --git a/drivers/net/ariadne.h b/drivers/net/ariadne.h
index f7913d5..bb613f2 100644
--- a/drivers/net/ariadne.h
+++ b/drivers/net/ariadne.h
@@ -1,7 +1,7 @@
 /*
  *  Amiga Linux/m68k Ariadne Ethernet Driver
  *
- *  © Copyright 1995 by Geert Uytterhoeven (geert@linux-m68k.org)
+ *  © Copyright 1995 by Geert Uytterhoeven (geert@linux-m68k.org)
  *			Peter De Schrijver
  *		       (Peter.DeSchrijver@linux.cc.kuleuven.ac.be)
  *
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 185f98e..504b7ce 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -542,7 +542,7 @@
 static int num_ifs;
 
 /*
- * Setup the base address and interupt of the Au1xxx ethernet macs
+ * Setup the base address and interrupt of the Au1xxx ethernet macs
  * based on cpu type and whether the interface is enabled in sys_pinfunc
  * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
  */
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index 9fe0517..7495a9e 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -900,7 +900,7 @@
 
 		ax->map2 = ioremap(res->start, size);
 		if (ax->map2 == NULL) {
-			dev_err(&pdev->dev, "cannot map reset register");
+			dev_err(&pdev->dev, "cannot map reset register\n");
 			ret = -ENXIO;
 			goto exit_mem2;
 		}
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 78ed633..da767d3 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -26,7 +26,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/dma-mapping.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <linux/delay.h>
@@ -56,8 +56,8 @@
 
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.6.7"
-#define DRV_MODULE_RELDATE	"October 10, 2007"
+#define DRV_MODULE_VERSION	"1.6.8"
+#define DRV_MODULE_RELDATE	"October 17, 2007"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -3079,14 +3079,18 @@
 			autoneg = bp->autoneg;
 			advertising = bp->advertising;
 
-			bp->autoneg = AUTONEG_SPEED;
-			bp->advertising = ADVERTISED_10baseT_Half |
-				ADVERTISED_10baseT_Full |
-				ADVERTISED_100baseT_Half |
-				ADVERTISED_100baseT_Full |
-				ADVERTISED_Autoneg;
+			if (bp->phy_port == PORT_TP) {
+				bp->autoneg = AUTONEG_SPEED;
+				bp->advertising = ADVERTISED_10baseT_Half |
+					ADVERTISED_10baseT_Full |
+					ADVERTISED_100baseT_Half |
+					ADVERTISED_100baseT_Full |
+					ADVERTISED_Autoneg;
+			}
 
-			bnx2_setup_copper_phy(bp);
+			spin_lock_bh(&bp->phy_lock);
+			bnx2_setup_phy(bp, bp->phy_port);
+			spin_unlock_bh(&bp->phy_lock);
 
 			bp->autoneg = autoneg;
 			bp->advertising = advertising;
@@ -3097,10 +3101,16 @@
 
 			/* Enable port mode. */
 			val &= ~BNX2_EMAC_MODE_PORT;
-			val |= BNX2_EMAC_MODE_PORT_MII |
-			       BNX2_EMAC_MODE_MPKT_RCVD |
+			val |= BNX2_EMAC_MODE_MPKT_RCVD |
 			       BNX2_EMAC_MODE_ACPI_RCVD |
 			       BNX2_EMAC_MODE_MPKT;
+			if (bp->phy_port == PORT_TP)
+				val |= BNX2_EMAC_MODE_PORT_MII;
+			else {
+				val |= BNX2_EMAC_MODE_PORT_GMII;
+				if (bp->line_speed == SPEED_2500)
+					val |= BNX2_EMAC_MODE_25G_MODE;
+			}
 
 			REG_WR(bp, BNX2_EMAC_MODE, val);
 
@@ -6428,7 +6438,7 @@
 	/* enable device (incl. PCI PM wakeup), and bus-mastering */
 	rc = pci_enable_device(pdev);
 	if (rc) {
-		dev_err(&pdev->dev, "Cannot enable PCI device, aborting.");
+		dev_err(&pdev->dev, "Cannot enable PCI device, aborting.\n");
 		goto err_out;
 	}
 
diff --git a/drivers/net/bnx2_fw2.h b/drivers/net/bnx2_fw2.h
index 5bd52be..4b129b7 100644
--- a/drivers/net/bnx2_fw2.h
+++ b/drivers/net/bnx2_fw2.h
@@ -15,3248 +15,3270 @@
  */
 
 static u8 bnx2_COM_b09FwText[] = {
-/*	0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
-								    0xdc, 0x5b,
-	0x6d, 0x70, 0x5c, 0xd5, 0x79, 0x7e, 0xef, 0xd9, 0xbb, 0xf2, 0x5a, 0x92,
-	0xe5, 0x6b, 0x79, 0x23, 0x16, 0x4b, 0xc0, 0xae, 0x75, 0x6d, 0x69, 0xb0,
-	0x43, 0x16, 0xa1, 0x80, 0x9a, 0xd9, 0xc0, 0xb2, 0x2b, 0x33, 0x9e, 0x0c,
-	0x69, 0x64, 0x50, 0x80, 0xb6, 0x4c, 0x46, 0xec, 0x1a, 0x9a, 0x4e, 0x87,
-	0xd6, 0xa6, 0x6e, 0x9b, 0xc9, 0x34, 0x78, 0x47, 0x1f, 0x8d, 0xa7, 0x15,
-	0xba, 0x06, 0x1b, 0xd9, 0xd3, 0xd0, 0xa0, 0x6a, 0x71, 0xf1, 0x8f, 0x8d,
-	0xaf, 0xf9, 0x48, 0xaa, 0x4c, 0x4d, 0xa5, 0x18, 0x48, 0x69, 0xa7, 0x4d,
-	0xfb, 0xa3, 0x9e, 0xa1, 0x5f, 0x84, 0x32, 0xfd, 0xc1, 0x74, 0xda, 0x4e,
-	0x3a, 0x24, 0x53, 0x08, 0x84, 0xed, 0xf3, 0x9c, 0x7b, 0xee, 0xea, 0x6a,
-	0x25, 0x7f, 0xf1, 0x91, 0x1f, 0xd5, 0xcc, 0xfa, 0xde, 0xf3, 0xfd, 0x9e,
-	0xf7, 0xbc, 0xef, 0xf3, 0x7e, 0xdc, 0xe3, 0x4f, 0x8a, 0xb4, 0x8a, 0xf9,
-	0xdb, 0x80, 0x5f, 0xfa, 0xc1, 0xdf, 0x2c, 0x5f, 0x37, 0x78, 0xdd, 0x0d,
-	0x78, 0xbd, 0x41, 0xc5, 0xec, 0x18, 0xeb, 0xf9, 0x4f, 0x12, 0xbf, 0x01,
-	0xf3, 0xbe, 0xd6, 0x9f, 0x83, 0xdf, 0x9b, 0x68, 0x1c, 0xfb, 0x0f, 0x11,
-	0xeb, 0x3c, 0x7d, 0xa2, 0x7f, 0xf5, 0xfa, 0x85, 0xdb, 0x15, 0x69, 0xb9,
-	0x40, 0x7b, 0x2c, 0x58, 0x52, 0xd3, 0xcc, 0x9f, 0x24, 0x54, 0x6e, 0xec,
-	0xe1, 0x82, 0x2b, 0x89, 0x58, 0x6e, 0xf7, 0xc1, 0xb2, 0x2b, 0x92, 0xaf,
-	0xed, 0x48, 0x17, 0xe5, 0x67, 0xf5, 0x4a, 0xd2, 0x16, 0xd6, 0x5f, 0x95,
-	0x7b, 0xef, 0xc9, 0x17, 0x6e, 0xca, 0xfc, 0x68, 0x2e, 0x26, 0x09, 0x27,
-	0xf7, 0xbc, 0x38, 0xdb, 0x25, 0xd1, 0x83, 0x31, 0x4f, 0xf4, 0xe5, 0x2d,
-	0xe9, 0x08, 0xe7, 0x7a, 0xb3, 0xfe, 0x42, 0x9f, 0x54, 0xb6, 0xe4, 0x12,
-	0xa2, 0x72, 0xdb, 0x5e, 0x2d, 0xc4, 0x9c, 0xb1, 0x58, 0xce, 0x91, 0x45,
-	0x5f, 0x46, 0xee, 0x9f, 0x96, 0x44, 0x22, 0xf7, 0xe5, 0xc4, 0xba, 0x6d,
-	0x92, 0xb0, 0x73, 0x4b, 0x0f, 0xff, 0xbe, 0x7b, 0xb0, 0xae, 0x5c, 0xb7,
-	0x7f, 0x5e, 0xda, 0x87, 0x4e, 0x0c, 0xa2, 0xbd, 0x96, 0xe9, 0x17, 0xb9,
-	0x49, 0x94, 0x5b, 0x69, 0x8f, 0xb9, 0x09, 0x29, 0xf8, 0xae, 0x14, 0x7d,
-	0x91, 0xbf, 0xac, 0x59, 0x72, 0xc2, 0xed, 0x92, 0xf9, 0x9d, 0xef, 0xd5,
-	0xf3, 0xa0, 0xe5, 0xfb, 0xee, 0xd2, 0xc3, 0x93, 0x2e, 0xe9, 0x3d, 0x90,
-	0x08, 0xe8, 0xdd, 0xbb, 0xae, 0xec, 0xda, 0x32, 0x5e, 0x63, 0xdd, 0xa8,
-	0x62, 0x5d, 0x3c, 0x97, 0x68, 0x3d, 0xe1, 0xb6, 0x9b, 0xba, 0x57, 0x6f,
-	0x29, 0x60, 0xbe, 0x89, 0x1a, 0xfb, 0xe6, 0xaf, 0x2f, 0xbb, 0x49, 0x53,
-	0xbf, 0x70, 0x63, 0xc1, 0x4d, 0xa1, 0xbe, 0xc7, 0xb4, 0x8d, 0x3d, 0x58,
-	0x76, 0x5d, 0xd3, 0xf6, 0x76, 0xac, 0xe0, 0xf6, 0x9b, 0xfa, 0xf7, 0x6e,
-	0x2e, 0xbb, 0x3b, 0x4d, 0x7d, 0x0f, 0xe6, 0xca, 0x9a, 0xfa, 0x85, 0x7b,
-	0xca, 0xee, 0xa0, 0xa9, 0xdf, 0x7d, 0x73, 0xc1, 0x1d, 0x32, 0xf5, 0x89,
-	0xa1, 0xb2, 0x9b, 0x43, 0xfd, 0x97, 0x13, 0x6a, 0x9b, 0x23, 0x53, 0xb5,
-	0x34, 0x7e, 0x79, 0xb4, 0x0d, 0xa3, 0x6e, 0x37, 0x7e, 0xb7, 0xe3, 0xf7,
-	0xc8, 0x46, 0xe9, 0x18, 0xc1, 0xf3, 0xbf, 0xba, 0x03, 0xde, 0x81, 0x47,
-	0x5e, 0x42, 0x5e, 0x8f, 0xa5, 0xe4, 0x85, 0xbe, 0xd7, 0xc1, 0x43, 0x47,
-	0x4e, 0xfb, 0x62, 0x8d, 0xf4, 0xa5, 0xc0, 0xbb, 0xa4, 0x3c, 0xe3, 0xb7,
-	0x49, 0xec, 0xb1, 0x18, 0x78, 0xf3, 0xcb, 0x52, 0x4a, 0x26, 0x64, 0xd3,
-	0xac, 0x25, 0x5b, 0x07, 0x12, 0x92, 0x77, 0xb8, 0x36, 0x4e, 0x7b, 0x26,
-	0x29, 0xb1, 0xd9, 0xfc, 0x66, 0x25, 0xdb, 0x9c, 0xa2, 0x54, 0xc0, 0xbb,
-	0x57, 0x29, 0x97, 0x68, 0x4b, 0x4b, 0x71, 0xfa, 0x5a, 0x19, 0x73, 0x48,
-	0xd7, 0x1f, 0x5c, 0x15, 0xac, 0x95, 0xb0, 0x0a, 0xc7, 0x46, 0x65, 0xca,
-	0x6b, 0xb7, 0x8a, 0xc7, 0x6e, 0x96, 0x42, 0x56, 0x92, 0x18, 0x97, 0x2a,
-	0xa1, 0xa5, 0x5a, 0x1b, 0x95, 0x49, 0x4f, 0xac, 0x82, 0x47, 0x7e, 0x76,
-	0xa1, 0xbd, 0x43, 0xf7, 0x45, 0x5d, 0x4f, 0x4c, 0xcf, 0x9d, 0x40, 0xbd,
-	0x83, 0xfa, 0x4e, 0x6b, 0x58, 0xcf, 0xa1, 0xeb, 0xd3, 0x13, 0xd2, 0x2e,
-	0x4f, 0xd5, 0x92, 0xa6, 0x6f, 0xbd, 0x5e, 0xc8, 0x3a, 0xe8, 0x37, 0x2a,
-	0x13, 0x5e, 0x52, 0xc6, 0xf0, 0x1c, 0xf7, 0xb8, 0x7e, 0x0a, 0x32, 0x75,
-	0xdd, 0xc1, 0xd2, 0x51, 0x3d, 0x5f, 0x3a, 0x96, 0xe3, 0x7c, 0x3d, 0xe8,
-	0xf7, 0x12, 0xe8, 0xb2, 0xc4, 0xd6, 0x67, 0x99, 0x97, 0xd2, 0xb4, 0x05,
-	0x79, 0xc3, 0x53, 0xf3, 0x75, 0x18, 0xf4, 0xdb, 0xe2, 0x0e, 0x58, 0x52,
-	0xc6, 0x59, 0x55, 0x1c, 0x94, 0x6b, 0x0b, 0xaa, 0xe0, 0xad, 0x93, 0xa2,
-	0x9d, 0x96, 0xd8, 0x0c, 0x65, 0x69, 0x4c, 0x26, 0x30, 0x46, 0xb9, 0xec,
-	0xf3, 0x0e, 0xf6, 0x3d, 0xa6, 0xcf, 0xa1, 0x25, 0x57, 0x51, 0x45, 0xbf,
-	0x4b, 0xd4, 0xec, 0xbd, 0xf2, 0xd2, 0xb4, 0x38, 0x38, 0xc7, 0x7a, 0xc1,
-	0x9d, 0x54, 0x85, 0xa7, 0x6d, 0x89, 0xcf, 0x58, 0x32, 0xe9, 0x66, 0xa0,
-	0x01, 0x87, 0xd4, 0x2e, 0x7f, 0x01, 0xfd, 0x38, 0x0e, 0xfd, 0x6a, 0x0a,
-	0x7c, 0xe5, 0xfb, 0x0e, 0x47, 0x69, 0x79, 0x66, 0x1f, 0x9c, 0x01, 0xf6,
-	0xf1, 0x8c, 0x87, 0x33, 0xd1, 0x67, 0x94, 0xc6, 0x19, 0x89, 0x35, 0xdc,
-	0x07, 0x99, 0x3a, 0x6a, 0x4b, 0x29, 0x8b, 0x7d, 0xa1, 0x77, 0x29, 0xbb,
-	0x4c, 0xd7, 0xc4, 0x74, 0x33, 0x5d, 0x1c, 0x47, 0xba, 0x02, 0x9a, 0xc6,
-	0x8f, 0x92, 0xbe, 0x65, 0x7a, 0xa6, 0xa6, 0x43, 0x1a, 0xb9, 0x1e, 0x69,
-	0x0b, 0xe9, 0xe2, 0x38, 0xd2, 0xb5, 0x99, 0x67, 0xcd, 0x3f, 0x6b, 0x18,
-	0x74, 0x4c, 0x78, 0x36, 0xce, 0xa8, 0x5d, 0x4a, 0x4e, 0xc5, 0x9a, 0x18,
-	0xda, 0x91, 0x82, 0x36, 0x5b, 0xe3, 0x43, 0xa4, 0xd9, 0xc5, 0x39, 0xb6,
-	0xe8, 0xf3, 0x56, 0xb9, 0x49, 0xf2, 0x0e, 0xfd, 0xb9, 0x3e, 0xde, 0x6b,
-	0x8e, 0x4c, 0xea, 0xf9, 0x48, 0xd3, 0x47, 0x31, 0x0f, 0x69, 0x7d, 0x05,
-	0xb2, 0x3a, 0x08, 0x19, 0xcd, 0xca, 0x5f, 0xf8, 0x3b, 0xe5, 0xcf, 0xfc,
-	0x7e, 0xf9, 0x0e, 0xf4, 0xf6, 0xdb, 0x7e, 0x5a, 0x9e, 0xf7, 0x7b, 0xe4,
-	0x39, 0x3f, 0x25, 0xcf, 0x6a, 0xf9, 0x1d, 0x16, 0xe9, 0xa0, 0x4c, 0xa7,
-	0xa5, 0x13, 0xfa, 0xb3, 0x09, 0xba, 0xf9, 0x38, 0xf8, 0x77, 0xb4, 0x4f,
-	0xf2, 0x9b, 0x73, 0x92, 0xb8, 0x1a, 0xbf, 0x2b, 0xf0, 0xeb, 0xca, 0xd9,
-	0x5a, 0x56, 0xec, 0x1c, 0x79, 0x68, 0x4b, 0x51, 0xef, 0xd9, 0x96, 0x09,
-	0xff, 0x91, 0xab, 0x03, 0xd9, 0x15, 0x19, 0x01, 0x8f, 0xd5, 0xc0, 0x4f,
-	0xea, 0x79, 0x07, 0xfb, 0x18, 0xd8, 0xa1, 0x79, 0xaf, 0x06, 0x28, 0xb3,
-	0x69, 0xc8, 0xbd, 0x6d, 0x15, 0xbd, 0x93, 0xc0, 0x8d, 0x36, 0xab, 0x70,
-	0xa4, 0x22, 0xe5, 0x23, 0x75, 0x29, 0x67, 0xe3, 0xf2, 0x90, 0x53, 0x97,
-	0xe1, 0x6c, 0x8b, 0xec, 0x77, 0xc0, 0xfb, 0x9d, 0xbf, 0x6d, 0x85, 0x98,
-	0xfd, 0xb8, 0xff, 0x3b, 0x78, 0x67, 0x9d, 0xc8, 0x51, 0xfd, 0x1e, 0xd4,
-	0x57, 0xfc, 0xb8, 0xe4, 0x93, 0x95, 0x94, 0x2d, 0x5b, 0x54, 0xb0, 0xee,
-	0x78, 0xd8, 0x06, 0x7e, 0x2c, 0x01, 0x27, 0x33, 0x5a, 0x5f, 0x4a, 0xd3,
-	0xeb, 0xdf, 0xce, 0xeb, 0x6a, 0xf4, 0x77, 0x06, 0xe5, 0xac, 0xe6, 0x67,
-	0x7a, 0xcc, 0xca, 0x25, 0x65, 0x6b, 0x8d, 0xe5, 0x21, 0xeb, 0x4e, 0x9f,
-	0xf2, 0x8c, 0x77, 0x9f, 0x74, 0x5e, 0x89, 0x7e, 0x36, 0x9e, 0x79, 0x43,
-	0x6f, 0x94, 0x46, 0xce, 0x43, 0x1a, 0xf9, 0xfc, 0x66, 0x84, 0xc6, 0x27,
-	0x1b, 0xef, 0x47, 0x23, 0xef, 0x15, 0xff, 0x8f, 0x5a, 0x03, 0xda, 0x86,
-	0xe4, 0x8d, 0x99, 0xaf, 0x98, 0x75, 0xf0, 0x7e, 0x8a, 0xf3, 0x7f, 0xab,
-	0x1e, 0xc8, 0x4b, 0xe5, 0x22, 0xeb, 0x2c, 0x44, 0xd6, 0xf9, 0x6e, 0x64,
-	0x9d, 0xef, 0x46, 0xd6, 0xa9, 0x80, 0xa7, 0xb2, 0x51, 0x41, 0x86, 0x4b,
-	0x34, 0x63, 0x72, 0x08, 0x73, 0xbe, 0x2e, 0xb1, 0x1c, 0xf5, 0x3c, 0xc4,
-	0x9b, 0x73, 0xe8, 0x9f, 0x93, 0xb3, 0x33, 0x15, 0x29, 0x1d, 0x89, 0xcb,
-	0x1d, 0xba, 0xdf, 0x26, 0x43, 0x5f, 0xb4, 0x2d, 0x21, 0x7b, 0x92, 0x7c,
-	0x0f, 0xdb, 0x6c, 0xf0, 0x99, 0xe5, 0x6f, 0x5d, 0x19, 0x94, 0xf9, 0xbe,
-	0x60, 0xf6, 0x32, 0x1a, 0x8c, 0x3b, 0xf5, 0xa6, 0xc6, 0xc3, 0x45, 0x9f,
-	0xb8, 0x25, 0xd9, 0x98, 0x2b, 0xfb, 0x86, 0xb3, 0x5d, 0x32, 0xe1, 0x58,
-	0xd9, 0xf1, 0xfe, 0x75, 0xd4, 0x8b, 0xbc, 0x72, 0xdb, 0x80, 0x0d, 0x92,
-	0x56, 0xc4, 0x7c, 0xbd, 0x2f, 0x4b, 0x05, 0xf4, 0x3b, 0x2c, 0x8f, 0x28,
-	0xb7, 0xb3, 0xa9, 0x9e, 0xba, 0x1d, 0xc3, 0x3b, 0x65, 0x78, 0x97, 0x39,
-	0x63, 0x1b, 0x65, 0xe2, 0xf0, 0x35, 0xa6, 0x1c, 0xb6, 0x6f, 0xb6, 0x57,
-	0x96, 0xcf, 0x76, 0xaf, 0x2c, 0x87, 0x38, 0x11, 0xc5, 0x70, 0xee, 0x15,
-	0xf8, 0xe4, 0x52, 0xee, 0xe2, 0xa0, 0x35, 0x0b, 0x9d, 0x5b, 0x67, 0x68,
-	0xb8, 0xc2, 0xd0, 0x00, 0x5a, 0xfb, 0x20, 0x59, 0x5a, 0x97, 0xb4, 0x68,
-	0x35, 0x95, 0xc9, 0xfb, 0xf0, 0x7d, 0x83, 0x6e, 0x0f, 0x74, 0x2e, 0x7c,
-	0x86, 0xf8, 0xfe, 0x66, 0xc4, 0x5e, 0xf4, 0x40, 0x67, 0x93, 0xe0, 0x55,
-	0x88, 0xf5, 0xc4, 0xe0, 0x14, 0xec, 0x03, 0x64, 0x55, 0x63, 0x7b, 0x3b,
-	0xf0, 0xd0, 0x36, 0xd8, 0x9c, 0x30, 0xd8, 0xdc, 0x0e, 0x5c, 0x66, 0xd9,
-	0x31, 0xe5, 0xa4, 0x29, 0xa7, 0x50, 0x86, 0x1d, 0x9f, 0x25, 0x2e, 0x5f,
-	0x77, 0x70, 0xef, 0x51, 0x8d, 0xf7, 0xb4, 0x15, 0x40, 0x61, 0xe2, 0x35,
-	0x71, 0xbb, 0x47, 0xe6, 0x6b, 0x58, 0xaf, 0x81, 0x8d, 0xdc, 0x7b, 0x94,
-	0x1e, 0xd2, 0xb2, 0x5e, 0x14, 0x6c, 0x57, 0x3e, 0x49, 0x7a, 0x1f, 0xc4,
-	0xde, 0x89, 0x3f, 0xa4, 0xfb, 0x2a, 0xd0, 0xca, 0x7d, 0xfc, 0x3c, 0x69,
-	0xe5, 0x7a, 0xcd, 0xf4, 0x7e, 0x58, 0x1c, 0x24, 0xed, 0x27, 0xb1, 0xe7,
-	0x3c, 0x30, 0x4f, 0xac, 0xd1, 0xbe, 0x51, 0xec, 0x79, 0x04, 0x78, 0x78,
-	0x3b, 0xf0, 0x70, 0x37, 0xf0, 0x70, 0x18, 0x78, 0x98, 0x03, 0x16, 0x0e,
-	0x01, 0x0b, 0x07, 0x81, 0x85, 0x59, 0xf0, 0x26, 0x29, 0x73, 0xc0, 0xc6,
-	0x39, 0x60, 0xe4, 0x1c, 0xe6, 0x18, 0x9f, 0x15, 0xeb, 0x4b, 0xd8, 0xc3,
-	0x63, 0x33, 0x99, 0x93, 0x90, 0xa5, 0x54, 0x45, 0x41, 0xfe, 0xb3, 0x43,
-	0x90, 0xed, 0x7e, 0xa9, 0xfa, 0xb6, 0x94, 0x69, 0x53, 0xb7, 0xf7, 0x42,
-	0xd7, 0x20, 0xef, 0x29, 0x31, 0x7f, 0x1b, 0xcc, 0xf3, 0x1f, 0x45, 0xdc,
-	0xbf, 0xa3, 0x2c, 0xa6, 0x45, 0xce, 0x48, 0xc9, 0xeb, 0x75, 0x0a, 0xaa,
-	0x1f, 0xfd, 0x58, 0xce, 0xaa, 0xfb, 0x8f, 0x5c, 0xaf, 0xf6, 0x1e, 0x21,
-	0x5f, 0xa6, 0x81, 0x57, 0x75, 0x99, 0xcc, 0x52, 0xb7, 0xea, 0x72, 0x22,
-	0x9b, 0x19, 0xaa, 0x48, 0x9b, 0x4c, 0x25, 0xa7, 0xb5, 0xad, 0xb5, 0x73,
-	0x87, 0xb5, 0xbd, 0x2a, 0xbb, 0x78, 0xd6, 0x06, 0x54, 0xe9, 0x08, 0xf7,
-	0xdf, 0x8b, 0x5f, 0x1c, 0xb4, 0x70, 0x7e, 0x5b, 0x86, 0x07, 0x1d, 0xf5,
-	0x40, 0x5f, 0x05, 0x08, 0x96, 0x71, 0xce, 0x62, 0xe5, 0xe2, 0x74, 0x6f,
-	0xaa, 0xa8, 0x6c, 0x19, 0xb3, 0x2d, 0x19, 0x87, 0x7c, 0x0f, 0x67, 0xdf,
-	0xa9, 0x4f, 0x25, 0xd9, 0xbe, 0x4e, 0xbe, 0xae, 0x7d, 0x0e, 0xac, 0x5d,
-	0x3d, 0x8a, 0x75, 0xe3, 0x38, 0x03, 0xae, 0xcb, 0x79, 0x50, 0xae, 0xd9,
-	0x28, 0x67, 0x4e, 0x56, 0xc4, 0x87, 0x9e, 0x6c, 0x94, 0xc2, 0xce, 0x16,
-	0xc9, 0x8f, 0xa4, 0x65, 0x7c, 0xc6, 0x07, 0x4e, 0xe1, 0x1c, 0xdd, 0x56,
-	0x29, 0x8d, 0xa6, 0xe5, 0xd1, 0x19, 0xd6, 0x9d, 0xc6, 0xfe, 0x33, 0x87,
-	0xf2, 0xc2, 0xfd, 0xc7, 0xf5, 0xbe, 0xd2, 0xea, 0xb4, 0xec, 0xf7, 0xde,
-	0x30, 0x7a, 0x14, 0x94, 0xef, 0xc7, 0x99, 0x9e, 0xf0, 0x17, 0xb0, 0x7f,
-	0x57, 0xe6, 0x81, 0xff, 0xc5, 0x23, 0xc0, 0x41, 0xb7, 0x03, 0x98, 0x95,
-	0x59, 0xa0, 0x4d, 0x8d, 0xc1, 0xef, 0xab, 0x6a, 0x5e, 0xf7, 0xc8, 0x91,
-	0x19, 0x25, 0xdf, 0xbe, 0x31, 0x8d, 0x32, 0xb0, 0x31, 0x9b, 0x39, 0x3d,
-	0xa6, 0x7a, 0xe4, 0x86, 0xce, 0x14, 0xc6, 0xe5, 0x54, 0xc9, 0xdb, 0x18,
-	0x03, 0x2f, 0x8f, 0xa7, 0x15, 0xfb, 0x2a, 0x29, 0x66, 0x63, 0x38, 0xff,
-	0x0a, 0xfa, 0xbf, 0x8f, 0xf5, 0x7a, 0x64, 0x16, 0xbe, 0xd6, 0xec, 0x4c,
-	0x1e, 0xe3, 0x88, 0x5d, 0x99, 0xe3, 0x4b, 0x0a, 0x18, 0x33, 0x0b, 0xf9,
-	0x1e, 0x85, 0x2f, 0x33, 0x03, 0xd1, 0x69, 0x4d, 0xe3, 0x4c, 0x7b, 0x9d,
-	0x71, 0xe0, 0x41, 0xbe, 0x87, 0xef, 0x9c, 0xd3, 0x95, 0x13, 0x1e, 0xe5,
-	0x30, 0x2d, 0x4f, 0xf9, 0x1c, 0xd7, 0xbb, 0xf0, 0x1c, 0x7c, 0x9f, 0xdf,
-	0xf5, 0xae, 0x44, 0xff, 0x77, 0xe1, 0x07, 0x3b, 0x52, 0xc5, 0xb9, 0x95,
-	0xc1, 0xcb, 0x7c, 0x2a, 0x28, 0x8f, 0xcf, 0x66, 0x16, 0xde, 0x50, 0x7c,
-	0x77, 0x2b, 0xf3, 0xea, 0x5a, 0x91, 0x4e, 0xf2, 0x33, 0x0b, 0x5e, 0xba,
-	0x8e, 0x52, 0xdb, 0x8d, 0xef, 0x47, 0x3d, 0x72, 0x41, 0x9f, 0x2d, 0xf3,
-	0x03, 0x51, 0x3d, 0xa2, 0x3d, 0x0c, 0xf5, 0x28, 0x93, 0x5a, 0x52, 0x0a,
-	0xed, 0xb6, 0x1c, 0xd6, 0x65, 0x0b, 0xb4, 0x66, 0x52, 0xdc, 0xdf, 0x44,
-	0xad, 0x5f, 0x9e, 0xf2, 0xd8, 0x1f, 0x7c, 0x9e, 0x6e, 0x37, 0xfd, 0x4f,
-	0x83, 0x87, 0xf4, 0xdf, 0xfa, 0x41, 0x73, 0xa0, 0x5b, 0xf3, 0xd3, 0x49,
-	0xdd, 0x36, 0xe5, 0x05, 0x7e, 0x9a, 0x82, 0x2f, 0x37, 0x07, 0x5f, 0xae,
-	0xa8, 0xf5, 0xcc, 0xc9, 0xc3, 0xd7, 0x87, 0x9e, 0x04, 0x3a, 0x56, 0xad,
-	0x91, 0x96, 0xbb, 0x40, 0x5f, 0xa6, 0x02, 0x62, 0x0e, 0xab, 0x1c, 0xce,
-	0x7d, 0x50, 0x2a, 0xf4, 0xf7, 0xce, 0xc6, 0x9e, 0x92, 0xb1, 0x2a, 0xed,
-	0x11, 0x7e, 0x9e, 0xeb, 0x30, 0xbe, 0xc8, 0x6b, 0x5b, 0xd1, 0x0d, 0x39,
-	0x80, 0x1d, 0xc9, 0x6e, 0x32, 0x7e, 0xce, 0x13, 0x38, 0xcf, 0x33, 0x38,
-	0xf7, 0x9a, 0xec, 0x3d, 0xf6, 0x0a, 0x65, 0xba, 0xbf, 0x2a, 0x99, 0xfe,
-	0x29, 0xd9, 0xe1, 0xcc, 0x43, 0x1f, 0xf3, 0xa3, 0xf5, 0x5b, 0x54, 0x8e,
-	0x63, 0x0e, 0x62, 0x0c, 0x9e, 0xd5, 0x57, 0xe4, 0x21, 0x9f, 0x75, 0x0f,
-	0x81, 0x9f, 0xd0, 0x95, 0xc1, 0x27, 0x8c, 0x1e, 0x60, 0x3e, 0x3b, 0x9c,
-	0xef, 0x15, 0x33, 0x1f, 0xfb, 0xb1, 0x0f, 0xc7, 0x2c, 0xcf, 0xbb, 0x8b,
-	0xb6, 0x08, 0x78, 0xb4, 0x4b, 0xd5, 0x6f, 0x89, 0xa3, 0xfd, 0xc4, 0x20,
-	0xdf, 0x31, 0x0f, 0x6c, 0x91, 0xe3, 0x9e, 0x41, 0x5f, 0xf8, 0x7a, 0xde,
-	0x7a, 0x29, 0x74, 0x85, 0xf4, 0x52, 0x06, 0xe8, 0x27, 0x68, 0x1b, 0xbc,
-	0x39, 0xe0, 0xfd, 0x1f, 0xc6, 0x02, 0x99, 0x3c, 0x80, 0x32, 0xf5, 0xef,
-	0x80, 0x14, 0xbd, 0x0c, 0xf6, 0x09, 0x1d, 0xf3, 0x3b, 0xac, 0x60, 0x8f,
-	0xe0, 0xff, 0xc8, 0x39, 0xf0, 0x41, 0x2a, 0x01, 0x6f, 0xc8, 0x17, 0xf2,
-	0xa4, 0x03, 0xb2, 0x0f, 0xb9, 0x87, 0xdc, 0x96, 0x34, 0x0f, 0xfe, 0xbd,
-	0x33, 0xf0, 0x8b, 0x33, 0x95, 0x3c, 0xe3, 0xb9, 0x4e, 0xe2, 0x26, 0x30,
-	0xcc, 0x87, 0x70, 0x60, 0xee, 0x25, 0xb5, 0x9e, 0xf4, 0xa6, 0x97, 0x62,
-	0x7d, 0x2c, 0xf7, 0x2f, 0x41, 0x86, 0xab, 0x38, 0x9f, 0xc2, 0xce, 0x5e,
-	0x83, 0x5b, 0xcf, 0xc6, 0x28, 0xaf, 0x55, 0x60, 0x4c, 0xc9, 0xdb, 0xe1,
-	0xdc, 0x4d, 0xbe, 0x39, 0x8e, 0x3c, 0xe7, 0x45, 0xb1, 0x03, 0xb6, 0xcf,
-	0xa5, 0x1c, 0x26, 0x21, 0x07, 0x36, 0x6c, 0x68, 0x0a, 0x67, 0xfe, 0x6f,
-	0x9d, 0xc1, 0x5e, 0xf8, 0x6e, 0xcb, 0x9c, 0x83, 0x35, 0xbd, 0xc5, 0x8d,
-	0x41, 0x1d, 0xdf, 0xb7, 0xf0, 0x8c, 0x0e, 0xaf, 0xa4, 0x9d, 0xe7, 0xdb,
-	0x7c, 0xa6, 0x27, 0xb0, 0x17, 0xd6, 0xe3, 0x59, 0x3d, 0x2e, 0x7b, 0x89,
-	0x9b, 0x83, 0xdb, 0x52, 0x2f, 0xa2, 0x7f, 0x11, 0x36, 0xa1, 0x62, 0xb3,
-	0xed, 0x6d, 0x6b, 0x79, 0x8c, 0xa2, 0x5f, 0x0a, 0x1f, 0x78, 0xc9, 0xfa,
-	0x92, 0xff, 0x92, 0x55, 0xa8, 0xbe, 0x6d, 0x15, 0x21, 0x27, 0x55, 0x8f,
-	0xf1, 0x0b, 0xf5, 0xc7, 0xc1, 0xda, 0x99, 0xd4, 0x5b, 0xaa, 0x37, 0x3d,
-	0x0f, 0x2c, 0xb8, 0x1f, 0x3a, 0x5d, 0xb4, 0x17, 0xa4, 0xec, 0xd7, 0xa4,
-	0x74, 0x6c, 0x07, 0xf4, 0x2d, 0x1d, 0xa1, 0x8b, 0x78, 0x56, 0xa1, 0x1f,
-	0x6e, 0xed, 0xf2, 0xa4, 0xd2, 0x92, 0x23, 0xae, 0x6d, 0x83, 0xec, 0xa0,
-	0xae, 0xb6, 0x2c, 0x7f, 0xb7, 0xad, 0xa2, 0x15, 0xb1, 0xee, 0xe0, 0x4a,
-	0x7a, 0xab, 0x72, 0x71, 0x7a, 0x77, 0x35, 0xe8, 0x25, 0x66, 0x00, 0xff,
-	0x3d, 0xe0, 0xbf, 0x07, 0xfc, 0xf7, 0x80, 0xff, 0x1e, 0xf0, 0xdf, 0x83,
-	0x6d, 0xf0, 0x60, 0x03, 0x3c, 0xd8, 0x00, 0x0f, 0x36, 0xc0, 0x83, 0x0d,
-	0xf0, 0x0a, 0x38, 0x27, 0xe2, 0x3c, 0x6d, 0xc8, 0x3d, 0x0d, 0xbb, 0x19,
-	0xf8, 0x39, 0x57, 0x1a, 0xdf, 0x01, 0xfa, 0xe7, 0x6c, 0x91, 0xf1, 0xfe,
-	0x2b, 0xb0, 0xb7, 0x56, 0x3c, 0xdb, 0xf0, 0xc4, 0x1a, 0xfd, 0x9f, 0x35,
-	0x7a, 0xf2, 0x55, 0xd0, 0xa5, 0x50, 0xfe, 0x05, 0xc8, 0x61, 0x0b, 0xe8,
-	0xf9, 0x94, 0xf1, 0x31, 0xbe, 0x61, 0x07, 0x72, 0xd8, 0x86, 0xba, 0xcf,
-	0xa0, 0xae, 0x0d, 0x7d, 0xf6, 0xa3, 0x0f, 0x7d, 0x94, 0x0e, 0x53, 0x17,
-	0xed, 0x47, 0x5f, 0xe5, 0x0b, 0x58, 0x2b, 0x83, 0x7e, 0x1d, 0x98, 0xbb,
-	0x07, 0x7d, 0x6e, 0x46, 0x9f, 0xab, 0x50, 0xa6, 0x6f, 0xdb, 0x8d, 0xf2,
-	0xa7, 0x9b, 0xc6, 0x5c, 0x83, 0xba, 0xcf, 0x36, 0xd5, 0x9d, 0x45, 0x1d,
-	0x62, 0x62, 0xe7, 0x45, 0x33, 0xae, 0x82, 0x72, 0x57, 0x53, 0x9f, 0x57,
-	0x50, 0x37, 0x84, 0xba, 0xbf, 0xc2, 0x13, 0xb1, 0xb0, 0x43, 0x9a, 0xc2,
-	0x36, 0xfa, 0xa9, 0x69, 0xd4, 0xc7, 0x8d, 0xaf, 0xf9, 0x24, 0x7d, 0x2f,
-	0xd8, 0xdc, 0x3f, 0xb6, 0x03, 0xdf, 0x0c, 0xde, 0xab, 0x96, 0xc3, 0xb0,
-	0xfc, 0xcd, 0xa6, 0x32, 0xfb, 0x7e, 0xbf, 0xa9, 0xae, 0x6d, 0xd3, 0xca,
-	0xf2, 0x4f, 0xe3, 0xab, 0xc7, 0xdc, 0xdb, 0xd4, 0xe7, 0xeb, 0x9d, 0x2b,
-	0xcb, 0xbb, 0x5b, 0x56, 0x8f, 0xd9, 0xbe, 0x71, 0x65, 0xdd, 0xad, 0x9b,
-	0x57, 0x96, 0xe9, 0x03, 0x26, 0x11, 0xc3, 0x84, 0xfd, 0x77, 0x7e, 0x22,
-	0x68, 0x27, 0x7f, 0x9b, 0x65, 0x49, 0x2b, 0x23, 0xca, 0x0a, 0xe7, 0xb0,
-	0x64, 0x41, 0x9f, 0x1c, 0x95, 0x7b, 0xc9, 0x2a, 0x42, 0xa6, 0x0a, 0x7e,
-	0x38, 0x1f, 0x75, 0xb6, 0x39, 0x4f, 0x10, 0xe6, 0x07, 0xe8, 0x6f, 0xb5,
-	0x43, 0x6e, 0xee, 0xa2, 0x4d, 0x3a, 0x54, 0x91, 0x65, 0xfd, 0xdc, 0xaa,
-	0xce, 0xa7, 0x9f, 0xf7, 0x19, 0x8c, 0x3a, 0x07, 0x3a, 0xeb, 0x32, 0x92,
-	0x5d, 0x47, 0x1b, 0x63, 0xb0, 0x8b, 0xb8, 0x53, 0xaf, 0xc7, 0xb6, 0xd7,
-	0x65, 0x5f, 0xf6, 0xdd, 0xba, 0x68, 0xcc, 0xbb, 0x57, 0xe3, 0x4e, 0x5a,
-	0x75, 0xe3, 0x8c, 0x1c, 0xc4, 0x12, 0x88, 0xed, 0x93, 0xb4, 0x49, 0xc7,
-	0xe9, 0x9f, 0x1c, 0x0c, 0x30, 0x95, 0xb8, 0x83, 0xb2, 0x3f, 0x85, 0x39,
-	0xb9, 0x3e, 0x9e, 0x55, 0xe2, 0xb8, 0xad, 0x6d, 0x4a, 0xc9, 0xe1, 0xbc,
-	0x6b, 0x61, 0xe3, 0xbf, 0xd8, 0xf4, 0x0b, 0x6d, 0xf7, 0x24, 0xec, 0x1b,
-	0xdb, 0xe8, 0x2b, 0x9c, 0xa4, 0x5f, 0x12, 0xc1, 0xaa, 0x9b, 0x62, 0xe2,
-	0x2e, 0x63, 0x66, 0xb0, 0xaf, 0x2d, 0xf4, 0xfb, 0x2f, 0x61, 0xaf, 0x6b,
-	0x63, 0x51, 0xaf, 0xba, 0xb8, 0x6e, 0xef, 0x69, 0xe8, 0x76, 0x28, 0x7b,
-	0x6b, 0xe5, 0x03, 0x5e, 0xd5, 0x67, 0xf1, 0xac, 0x9f, 0x39, 0x5c, 0x81,
-	0x2e, 0x2d, 0xea, 0xd8, 0x37, 0x3c, 0x17, 0xfa, 0x38, 0x99, 0xe3, 0x73,
-	0x90, 0xed, 0xbd, 0x3a, 0x26, 0x60, 0x3c, 0x50, 0x97, 0x5d, 0xd9, 0x4f,
-	0x25, 0xc9, 0x87, 0xbc, 0xfa, 0x71, 0x9c, 0x3e, 0xc3, 0xa2, 0x47, 0x9e,
-	0x65, 0xd1, 0x9e, 0x05, 0x26, 0xfc, 0xab, 0x14, 0x93, 0xac, 0x7b, 0xab,
-	0x3e, 0x0f, 0xbf, 0x4a, 0xfb, 0x47, 0xda, 0xde, 0xd3, 0xbf, 0x83, 0x5d,
-	0xf7, 0xc9, 0xd3, 0x25, 0xf0, 0x39, 0xf4, 0x01, 0x7e, 0x40, 0x1f, 0x55,
-	0x56, 0xfa, 0xd2, 0x22, 0x0f, 0xd5, 0xfe, 0x01, 0x36, 0x47, 0x05, 0xbe,
-	0x0a, 0xe3, 0x65, 0x97, 0xf5, 0x37, 0xc6, 0xe9, 0xcb, 0x05, 0xb6, 0x3e,
-	0x86, 0xf5, 0x10, 0x5f, 0xd7, 0xfe, 0xd3, 0x2a, 0x79, 0x3d, 0xf4, 0xb3,
-	0xb0, 0x7f, 0xf8, 0x50, 0x3e, 0xdb, 0x58, 0x97, 0x30, 0xfe, 0x77, 0xbb,
-	0xf1, 0xb7, 0x1d, 0xe3, 0x6f, 0x6b, 0x3a, 0x12, 0x4e, 0x2e, 0xf4, 0x0b,
-	0x78, 0x66, 0xe9, 0x83, 0x6a, 0x3b, 0xfd, 0x82, 0x0e, 0x59, 0xdb, 0x2f,
-	0x08, 0x69, 0x3a, 0x85, 0x7d, 0xd2, 0xcf, 0xd3, 0x79, 0xa0, 0xce, 0x20,
-	0xf7, 0x44, 0x1a, 0x42, 0xfb, 0xa8, 0xed, 0xf0, 0x21, 0x98, 0x3c, 0xe6,
-	0x24, 0x41, 0xeb, 0x6e, 0x29, 0x4c, 0x9f, 0x32, 0xf6, 0x96, 0x71, 0x04,
-	0x7d, 0xf8, 0x40, 0x66, 0x0b, 0xd9, 0x0e, 0xcb, 0xcc, 0xd3, 0x05, 0x0b,
-	0x19, 0xc9, 0x51, 0x71, 0x2d, 0xfa, 0x31, 0xa1, 0x4f, 0xb3, 0x60, 0x7c,
-	0x9a, 0x33, 0xb2, 0xcf, 0x0b, 0xe2, 0x86, 0x91, 0xda, 0x12, 0xea, 0x34,
-	0xed, 0x29, 0xfa, 0x96, 0x0a, 0x3e, 0x77, 0xfe, 0xde, 0x0c, 0x02, 0x90,
-	0x60, 0x2f, 0x5b, 0xb1, 0x97, 0x6a, 0x63, 0x2f, 0x6d, 0x4b, 0xcd, 0x3e,
-	0x0e, 0xc7, 0x4e, 0xae, 0x1a, 0x2b, 0xd8, 0xc7, 0xdc, 0x79, 0xda, 0xb8,
-	0x47, 0xfa, 0x0d, 0x8e, 0xd9, 0x63, 0x78, 0x4e, 0x8f, 0x63, 0x8f, 0x49,
-	0xab, 0xa4, 0x7d, 0x2d, 0xfa, 0x2d, 0x88, 0xb3, 0x6b, 0x2f, 0xe1, 0x49,
-	0xfd, 0xd0, 0xf3, 0x60, 0x4f, 0xed, 0x7a, 0x4f, 0x53, 0xde, 0x2b, 0x7a,
-	0x1f, 0xf3, 0xb5, 0xbf, 0x91, 0xf2, 0xb1, 0x1f, 0xc0, 0xee, 0x45, 0x73,
-	0x73, 0xcc, 0x6b, 0x92, 0x1f, 0x95, 0x08, 0x7e, 0x72, 0xaf, 0xcc, 0xbb,
-	0xbd, 0x1c, 0x0f, 0xe2, 0x83, 0x69, 0x9c, 0xb1, 0x15, 0xb4, 0xeb, 0xf5,
-	0x43, 0xbe, 0xb6, 0x44, 0xe8, 0xa9, 0xc3, 0xe7, 0x4c, 0x81, 0x86, 0xe8,
-	0x98, 0x03, 0x32, 0xec, 0xf1, 0x3c, 0x7a, 0x53, 0x7b, 0xc5, 0x75, 0x4a,
-	0x12, 0xfa, 0x19, 0x5c, 0x9f, 0x3a, 0x5f, 0x84, 0xe3, 0xcb, 0x5c, 0x6a,
-	0xc8, 0xbb, 0x90, 0x6f, 0xed, 0x4b, 0xcd, 0x32, 0x30, 0x89, 0x58, 0xab,
-	0xec, 0x91, 0x4f, 0xa1, 0x6c, 0x86, 0x6b, 0xbf, 0x6a, 0x71, 0x3f, 0x13,
-	0x3a, 0x7f, 0xf8, 0x4f, 0x0d, 0x19, 0x1d, 0x07, 0x76, 0x04, 0x32, 0xf7,
-	0xf7, 0x86, 0x37, 0xa1, 0x6c, 0xb6, 0x9b, 0x73, 0x66, 0x2c, 0x48, 0xdd,
-	0x09, 0xe5, 0x60, 0x9b, 0x73, 0xa7, 0xe6, 0x05, 0xdb, 0xb4, 0xcf, 0xad,
-	0xcf, 0x72, 0xac, 0x71, 0x96, 0x1b, 0x9a, 0xe4, 0xf2, 0xdd, 0x8d, 0x81,
-	0x1e, 0x52, 0xdf, 0xa0, 0xb7, 0xe0, 0xd7, 0xb3, 0x2b, 0xf4, 0xbb, 0xff,
-	0x3c, 0x39, 0xd9, 0x76, 0x89, 0xcd, 0x7e, 0x0f, 0xbc, 0xbc, 0x06, 0xb1,
-	0x8a, 0x88, 0x3d, 0x43, 0x1c, 0xa2, 0xbf, 0xb1, 0xec, 0xef, 0xce, 0xcb,
-	0x5a, 0xbe, 0xee, 0xc5, 0x7c, 0x8d, 0x4f, 0x5e, 0xa2, 0xaf, 0x31, 0xdc,
-	0x22, 0xad, 0xc4, 0xa2, 0x33, 0xf0, 0x6d, 0x2d, 0x69, 0x71, 0xbf, 0x01,
-	0x1b, 0x76, 0xda, 0x5e, 0xe7, 0x86, 0x98, 0xd0, 0x2e, 0x9b, 0x66, 0xb7,
-	0x68, 0x5c, 0x70, 0x66, 0x96, 0x71, 0x61, 0x1c, 0xbc, 0x1f, 0x09, 0xf2,
-	0xbc, 0xc9, 0x4d, 0x72, 0xa9, 0xf1, 0xf5, 0xb2, 0xdf, 0x3f, 0xd6, 0xf0,
-	0xfb, 0xaf, 0x6c, 0xe2, 0xe3, 0x5a, 0xb8, 0x78, 0x1a, 0x7c, 0xcb, 0x21,
-	0xfe, 0x65, 0x5c, 0x3b, 0x8c, 0x78, 0x98, 0xb1, 0x58, 0x1e, 0x31, 0x71,
-	0xe6, 0xb4, 0xc8, 0x6e, 0xc4, 0xc8, 0x99, 0x1f, 0x31, 0x7f, 0xf5, 0xbc,
-	0x9f, 0x99, 0x13, 0xb9, 0x1d, 0x7c, 0x1d, 0x04, 0x6e, 0x66, 0x81, 0xa3,
-	0x3b, 0xc1, 0xdf, 0x7e, 0x8d, 0x9d, 0xf7, 0x1f, 0x11, 0xeb, 0x0e, 0x9d,
-	0xab, 0xa6, 0x3e, 0x27, 0x61, 0x47, 0xeb, 0xf5, 0xfd, 0xd9, 0x5e, 0xc4,
-	0xf5, 0x69, 0xb9, 0xd5, 0x66, 0x1c, 0x6b, 0xd9, 0x5b, 0x07, 0xe6, 0x63,
-	0x51, 0x9f, 0xb4, 0x70, 0x51, 0x3b, 0xb0, 0x9a, 0xf7, 0x45, 0x6d, 0x0b,
-	0x0e, 0xc7, 0x2e, 0xc4, 0xfb, 0x3b, 0x1a, 0xbc, 0x6f, 0x69, 0x95, 0xd6,
-	0xdb, 0x75, 0x1e, 0x61, 0xeb, 0xc0, 0x7e, 0xe2, 0x55, 0x16, 0x76, 0x1d,
-	0xf6, 0xb7, 0x2e, 0xb7, 0x65, 0xdf, 0xae, 0xbf, 0xe8, 0x6e, 0x94, 0xd2,
-	0xce, 0xfb, 0x0c, 0x66, 0x2f, 0x7d, 0xad, 0xe0, 0x56, 0xa0, 0x1f, 0x41,
-	0xce, 0x70, 0xef, 0x74, 0x02, 0x96, 0x80, 0x7f, 0x9d, 0x32, 0x3f, 0xf4,
-	0x16, 0xce, 0x70, 0xc7, 0x49, 0x26, 0x9c, 0x14, 0x70, 0x78, 0x3e, 0xd9,
-	0xae, 0xf3, 0xc5, 0x9f, 0x70, 0x59, 0xef, 0xe0, 0x4c, 0x47, 0x65, 0x1e,
-	0xfe, 0x43, 0x75, 0x08, 0x34, 0xee, 0xec, 0x42, 0x7f, 0xea, 0x1d, 0x79,
-	0x3e, 0x0a, 0xdb, 0x4b, 0x9e, 0x26, 0xd1, 0x7f, 0x0f, 0xfa, 0x74, 0xe2,
-	0x79, 0x5f, 0x6c, 0xde, 0x61, 0xec, 0xfc, 0x79, 0x94, 0x39, 0x47, 0xd4,
-	0x76, 0x7e, 0x2e, 0x2e, 0x7a, 0x4e, 0x8e, 0xe9, 0xd2, 0xfa, 0xbf, 0xbc,
-	0x16, 0xd7, 0x61, 0xdb, 0xcf, 0xea, 0xd7, 0x0f, 0x0c, 0x45, 0xd6, 0xeb,
-	0x88, 0xac, 0x37, 0x14, 0x59, 0x8f, 0x74, 0x76, 0x46, 0xe8, 0xec, 0xc4,
-	0xf8, 0x22, 0xd6, 0x26, 0x3f, 0xa2, 0x6b, 0x3e, 0x18, 0x59, 0x33, 0xdc,
-	0x5f, 0x57, 0x64, 0xdc, 0xbb, 0x58, 0x8f, 0x75, 0xc9, 0x48, 0x1d, 0x69,
-	0xd8, 0x8c, 0x3a, 0x96, 0x3b, 0x23, 0x74, 0x91, 0xd6, 0x0d, 0xa8, 0xd7,
-	0xfe, 0x13, 0xf8, 0xdc, 0x0a, 0xbb, 0xa5, 0x60, 0x3b, 0x5a, 0xe0, 0x5f,
-	0x35, 0xef, 0xf5, 0x51, 0xac, 0x1b, 0xce, 0x97, 0xc4, 0x1c, 0xec, 0xcf,
-	0xbe, 0x31, 0x33, 0x9e, 0xf5, 0x6c, 0xff, 0xf3, 0xfa, 0x9f, 0x6a, 0xbe,
-	0x6d, 0x06, 0xed, 0x3a, 0xef, 0x22, 0x73, 0x9d, 0x36, 0xce, 0x93, 0xf1,
-	0xb1, 0x25, 0x57, 0xbb, 0xca, 0xea, 0x1d, 0xe0, 0xd9, 0x6f, 0x34, 0x58,
-	0xda, 0x6a, 0x15, 0x8e, 0x30, 0x5f, 0xd0, 0x66, 0x62, 0x3e, 0xc4, 0x1e,
-	0xda, 0xc6, 0xd8, 0xa6, 0x9d, 0x36, 0x86, 0x7e, 0x0b, 0xed, 0xe7, 0x69,
-	0xf3, 0x8e, 0x27, 0x64, 0xf8, 0x81, 0x6a, 0xa7, 0xbc, 0xa8, 0x79, 0xea,
-	0xc8, 0xd9, 0x06, 0x4f, 0xe3, 0xe6, 0xbb, 0xcc, 0x01, 0xf3, 0xcd, 0xa3,
-	0x0f, 0x7e, 0x11, 0xde, 0x6b, 0x79, 0xd0, 0x90, 0x96, 0xde, 0x01, 0xc6,
-	0x6e, 0x15, 0x3c, 0x99, 0xa7, 0xb0, 0xf0, 0x0c, 0xf2, 0x17, 0xbd, 0x03,
-	0xb0, 0x4b, 0xc0, 0xa1, 0xde, 0x81, 0x73, 0x3a, 0x9e, 0xab, 0xfa, 0x8e,
-	0x75, 0x9b, 0x17, 0xe4, 0x88, 0xce, 0xba, 0x17, 0xca, 0x11, 0xdd, 0xb3,
-	0x8e, 0x79, 0x8d, 0x30, 0x47, 0x74, 0x56, 0x74, 0x8e, 0xe8, 0xf8, 0x45,
-	0x72, 0x44, 0xf9, 0x4b, 0xcf, 0x11, 0x71, 0x7e, 0x5b, 0xee, 0x1c, 0x74,
-	0xd4, 0xaf, 0x9a, 0x1c, 0xd1, 0x1b, 0x12, 0xe4, 0x88, 0x5e, 0x94, 0xb5,
-	0x73, 0x44, 0x87, 0x9a, 0x72, 0x44, 0x9b, 0x75, 0x8e, 0x88, 0xf3, 0x04,
-	0x39, 0x22, 0x96, 0x4b, 0x03, 0x43, 0x91, 0x5c, 0x07, 0xf0, 0xd7, 0xbb,
-	0x01, 0x7c, 0x73, 0xac, 0x51, 0x2f, 0xc4, 0x34, 0x62, 0xff, 0x15, 0x0d,
-	0xfb, 0xb5, 0x8c, 0x6f, 0x96, 0x96, 0xb9, 0x8b, 0xe1, 0xdb, 0x68, 0xe0,
-	0x97, 0xac, 0xc0, 0xb6, 0xc9, 0x86, 0xef, 0xe2, 0xad, 0x63, 0x0c, 0x3d,
-	0x51, 0x5b, 0x9e, 0x77, 0x02, 0xbc, 0x1e, 0x6b, 0xe4, 0x49, 0xce, 0xe7,
-	0x1f, 0x25, 0xe5, 0xc0, 0x9a, 0xdf, 0xbd, 0x52, 0xf9, 0xd5, 0xdf, 0xbd,
-	0x2c, 0x49, 0x82, 0xce, 0xd2, 0x40, 0x49, 0xc7, 0x5d, 0xf3, 0xde, 0xaf,
-	0xc8, 0xd2, 0xdd, 0x0e, 0xf0, 0x27, 0xcc, 0x9f, 0xf0, 0x7c, 0x97, 0x6d,
-	0x4a, 0x41, 0x7d, 0x7c, 0x39, 0x94, 0x07, 0x74, 0x0e, 0xe5, 0xc5, 0x75,
-	0xd1, 0x1c, 0xca, 0x59, 0xb9, 0x70, 0x0e, 0xe5, 0x81, 0x35, 0x72, 0x28,
-	0x2f, 0xcb, 0x72, 0x0e, 0xe5, 0x65, 0x09, 0x73, 0x28, 0x31, 0x59, 0xda,
-	0x1c, 0x48, 0xe3, 0x03, 0xfe, 0x12, 0x7e, 0x67, 0xf0, 0x0b, 0x72, 0x2a,
-	0x67, 0x1b, 0xf4, 0xaf, 0x95, 0x53, 0x79, 0x7d, 0xdd, 0x07, 0xc9, 0xa9,
-	0x04, 0x36, 0x20, 0xcc, 0xa9, 0xe0, 0xe7, 0xc0, 0xe6, 0xa8, 0x68, 0x4e,
-	0xe5, 0x27, 0xd4, 0x07, 0xd4, 0xb1, 0xcc, 0x7a, 0xe8, 0x05, 0xec, 0x52,
-	0x5e, 0xe7, 0x38, 0x3e, 0x67, 0x78, 0x38, 0x87, 0x3d, 0xa7, 0x71, 0x16,
-	0xe4, 0x63, 0xaf, 0xf6, 0x2d, 0xf3, 0x76, 0xca, 0x2a, 0xf4, 0xc1, 0x9a,
-	0x4d, 0xf3, 0xbb, 0xb8, 0x6d, 0xed, 0xf5, 0x29, 0xe3, 0x09, 0xab, 0x8c,
-	0xbd, 0x0c, 0x4f, 0xcf, 0xc9, 0x5e, 0x3f, 0xf4, 0xa9, 0x06, 0x1a, 0x73,
-	0x50, 0x37, 0xe7, 0x81, 0xb3, 0xc0, 0x89, 0x4b, 0xb0, 0x51, 0xa7, 0x40,
-	0x73, 0x74, 0x1f, 0x88, 0x89, 0x07, 0x51, 0xa7, 0xcf, 0x9c, 0xbe, 0x65,
-	0x48, 0x4b, 0x9a, 0x7a, 0x7e, 0x09, 0xf3, 0xb1, 0xee, 0x94, 0x8e, 0xc7,
-	0xca, 0x83, 0xdc, 0x2b, 0x6d, 0xdd, 0x22, 0xe8, 0x43, 0x5d, 0x95, 0x31,
-	0x20, 0xed, 0x5e, 0x18, 0xa3, 0xb5, 0xeb, 0x18, 0xad, 0x4b, 0xf3, 0x83,
-	0xbc, 0xbe, 0x35, 0x41, 0xac, 0xec, 0x72, 0xb9, 0x87, 0x33, 0x06, 0xeb,
-	0x58, 0x0e, 0x62, 0xc1, 0xbc, 0xe2, 0xfb, 0xef, 0xe1, 0x5c, 0x99, 0xa7,
-	0x09, 0xcf, 0xef, 0x2b, 0x66, 0xdf, 0x43, 0x52, 0xe9, 0x92, 0xc4, 0x66,
-	0xd0, 0x53, 0x9a, 0xa1, 0xdf, 0xfd, 0x69, 0x1d, 0x83, 0x24, 0xdd, 0xf3,
-	0xeb, 0xed, 0x1d, 0x97, 0xa1, 0xb7, 0x23, 0x17, 0xd4, 0xdb, 0xaf, 0x25,
-	0xa2, 0x7a, 0x7b, 0xc7, 0x65, 0xe8, 0xed, 0xbe, 0xcb, 0xd2, 0x5b, 0xee,
-	0x8d, 0x98, 0x14, 0xe6, 0xc4, 0x56, 0xfb, 0x59, 0xe1, 0xba, 0xe3, 0x58,
-	0x33, 0x7f, 0x9e, 0x35, 0xc7, 0xce, 0x9b, 0x5b, 0x6d, 0xf6, 0xb1, 0x2e,
-	0xe5, 0xbc, 0x19, 0x5b, 0xd1, 0xde, 0xb6, 0x1b, 0xbb, 0x74, 0x9f, 0x89,
-	0xe7, 0xc3, 0xb8, 0x3e, 0xaa, 0x3f, 0x94, 0x0b, 0xca, 0xc2, 0x77, 0xc0,
-	0x2f, 0xca, 0x43, 0xa8, 0x73, 0xdd, 0x4d, 0x32, 0xb8, 0x88, 0x78, 0xbf,
-	0xdb, 0xc8, 0x20, 0xcf, 0xba, 0x4f, 0x7f, 0x67, 0xaa, 0x7a, 0x4f, 0x05,
-	0x71, 0xbe, 0x8b, 0x67, 0x35, 0xd4, 0x35, 0xf0, 0x24, 0x19, 0xb6, 0x91,
-	0x8f, 0x2e, 0x7c, 0x9e, 0x1d, 0xf0, 0xd7, 0xc0, 0x23, 0x5d, 0xbf, 0x32,
-	0x27, 0x7c, 0x61, 0x3c, 0x93, 0x4a, 0x1c, 0x7d, 0x4f, 0x0c, 0x42, 0xc7,
-	0x07, 0x89, 0x51, 0x35, 0xc4, 0x3d, 0x94, 0x43, 0xca, 0xe6, 0xb6, 0xfe,
-	0x5d, 0x8a, 0x3e, 0xd5, 0x13, 0x88, 0x83, 0x29, 0xaf, 0x69, 0xd9, 0xe5,
-	0x6f, 0x3b, 0x7d, 0x56, 0x71, 0x8d, 0x7a, 0xbd, 0xc4, 0x58, 0xd1, 0x11,
-	0xb5, 0x75, 0xe0, 0xbf, 0x13, 0xb4, 0x4b, 0x57, 0xb8, 0x31, 0x23, 0x6b,
-	0x79, 0xbc, 0x53, 0x6e, 0x7f, 0x08, 0x7b, 0xcf, 0xef, 0xfd, 0xaf, 0xa1,
-	0x3e, 0x05, 0x9d, 0xa7, 0x7d, 0x67, 0x3c, 0x72, 0x93, 0xe9, 0xd7, 0xad,
-	0xbf, 0x57, 0x16, 0xb2, 0x37, 0x98, 0x6f, 0x57, 0xb4, 0x3f, 0x19, 0xda,
-	0xec, 0x15, 0xe7, 0xcc, 0xfb, 0x12, 0x45, 0x1d, 0xcf, 0x70, 0xbc, 0x96,
-	0x49, 0xc4, 0x20, 0x76, 0x24, 0x97, 0x9e, 0x30, 0xb1, 0x1b, 0x75, 0xac,
-	0x1d, 0x67, 0xe8, 0x9b, 0x58, 0x85, 0xf1, 0xeb, 0xca, 0x7b, 0x12, 0x6b,
-	0xcb, 0xc0, 0x96, 0x0f, 0x20, 0x03, 0xcd, 0xe7, 0x97, 0x80, 0xee, 0x87,
-	0xe7, 0x17, 0xfa, 0x31, 0x73, 0x66, 0xdf, 0xdd, 0xc1, 0x19, 0xfe, 0xbf,
-	0xd8, 0xa7, 0x15, 0xd9, 0x67, 0x88, 0x47, 0x0f, 0x98, 0x7d, 0xde, 0xd4,
-	0x84, 0x47, 0x23, 0x4d, 0x3a, 0xfb, 0x71, 0xe2, 0xd1, 0x9f, 0xac, 0xff,
-	0xf8, 0xf1, 0x88, 0xfb, 0xea, 0x5e, 0x13, 0x87, 0x82, 0x7d, 0x3c, 0x22,
-	0x2a, 0xf7, 0x51, 0xc6, 0x7b, 0x1f, 0xe4, 0x7c, 0xa2, 0x38, 0xc2, 0x33,
-	0xe9, 0xd0, 0x3e, 0x6c, 0xa0, 0x7b, 0xb0, 0xe5, 0xd5, 0xb8, 0xbc, 0x7e,
-	0x57, 0x42, 0xfe, 0xf7, 0x46, 0x7e, 0x0f, 0xb3, 0x4d, 0x4e, 0x8b, 0xe5,
-	0xd7, 0xd6, 0x07, 0x76, 0xe8, 0xb5, 0x4d, 0x81, 0xdd, 0xe1, 0x98, 0x50,
-	0x9f, 0x1d, 0xb4, 0xb3, 0xad, 0x5b, 0x96, 0x3a, 0x2f, 0x27, 0x06, 0xdc,
-	0xe6, 0xbc, 0xa1, 0xd6, 0x8a, 0x01, 0x2f, 0x9c, 0x0f, 0x5c, 0x8e, 0x01,
-	0x89, 0xb3, 0x9d, 0x5a, 0x36, 0x4a, 0x49, 0xc6, 0x3e, 0x7d, 0x06, 0x3b,
-	0xf9, 0x8e, 0xd8, 0xd6, 0x43, 0xbc, 0xeb, 0x21, 0xd6, 0xf5, 0x10, 0xff,
-	0x7a, 0x88, 0x71, 0x3d, 0xc4, 0xb6, 0x1e, 0x62, 0x5b, 0x0f, 0xb1, 0xad,
-	0xd7, 0x6f, 0x62, 0xe4, 0x11, 0x93, 0xf7, 0xe7, 0x77, 0x72, 0xe6, 0x17,
-	0x2a, 0xb0, 0x25, 0x93, 0xbc, 0xe7, 0xa0, 0x0a, 0xd9, 0xf5, 0x66, 0x7f,
-	0x61, 0x4e, 0xbc, 0xc7, 0xe4, 0x6c, 0x5e, 0xd7, 0x79, 0x43, 0x51, 0xb3,
-	0xad, 0xc1, 0xb7, 0x74, 0xde, 0xc7, 0xf8, 0x2d, 0xf8, 0x25, 0xfa, 0x3e,
-	0x13, 0x75, 0xb4, 0xae, 0x72, 0xcc, 0xc9, 0x88, 0x52, 0xb9, 0xeb, 0x31,
-	0x66, 0x47, 0x10, 0x13, 0x24, 0x25, 0xa6, 0x72, 0x6d, 0xe4, 0xa9, 0xa5,
-	0x72, 0x1b, 0xcc, 0x5c, 0x47, 0x5b, 0x03, 0xdf, 0xaa, 0x8f, 0x65, 0x5b,
-	0xe5, 0x6e, 0xe6, 0x13, 0xe7, 0x1e, 0xd6, 0xf7, 0x74, 0xae, 0x5c, 0x6b,
-	0x4a, 0xe3, 0x7b, 0x21, 0x7b, 0x37, 0xe6, 0xd3, 0xf7, 0x88, 0x1a, 0xfc,
-	0x56, 0xe7, 0xe5, 0xf7, 0x94, 0xe1, 0x77, 0xc0, 0xe3, 0x18, 0xfb, 0xe9,
-	0xbc, 0x30, 0x79, 0x1d, 0xce, 0xa7, 0xf3, 0x7a, 0x58, 0x47, 0xdf, 0xa5,
-	0xc0, 0x53, 0xc5, 0xa5, 0x63, 0xf4, 0x9e, 0xb8, 0x1b, 0x5d, 0x37, 0xfc,
-	0x26, 0x7e, 0x29, 0x6b, 0x76, 0xeb, 0xef, 0x68, 0x81, 0xcd, 0x98, 0xd2,
-	0x32, 0x68, 0xe7, 0xb8, 0xaf, 0xf7, 0x21, 0x7f, 0x53, 0x5a, 0xfe, 0x8a,
-	0x88, 0x63, 0x26, 0x07, 0xb7, 0xa5, 0x6d, 0x75, 0xa0, 0x95, 0xf9, 0xd7,
-	0x61, 0x3f, 0xc4, 0x3d, 0xae, 0xd7, 0x6c, 0xc7, 0x99, 0x57, 0x0b, 0xf1,
-	0x4c, 0xb6, 0x04, 0xf9, 0xb6, 0x0f, 0xa3, 0x4b, 0xad, 0x4d, 0xba, 0x14,
-	0xee, 0x93, 0xfb, 0xe7, 0x73, 0xed, 0x3b, 0x15, 0x8b, 0x7e, 0xe4, 0xfb,
-	0x48, 0x43, 0x36, 0x78, 0xb7, 0xe4, 0x8b, 0x90, 0x41, 0xfd, 0x9d, 0x02,
-	0x7a, 0x54, 0xaf, 0x0f, 0x33, 0xc7, 0xbc, 0xf3, 0x0b, 0xe6, 0xde, 0x82,
-	0x3c, 0xcc, 0xfc, 0x83, 0xbd, 0x2a, 0xff, 0x30, 0x0c, 0x59, 0x81, 0x0f,
-	0xe0, 0x75, 0x68, 0x9f, 0x4e, 0xb9, 0xf4, 0x07, 0x9a, 0xbf, 0xbf, 0x3c,
-	0xda, 0x16, 0xf0, 0xe1, 0xed, 0xd6, 0xe0, 0x1b, 0xc4, 0xdf, 0x26, 0x57,
-	0x96, 0x39, 0xfe, 0x7f, 0x8c, 0xac, 0x1c, 0x86, 0x6d, 0x1e, 0x86, 0x2c,
-	0x22, 0x26, 0xd7, 0xf3, 0x1d, 0x96, 0xd2, 0xd3, 0x0b, 0x9d, 0x2b, 0xfb,
-	0xa3, 0xee, 0x58, 0xd8, 0xff, 0xb1, 0xa6, 0xfe, 0x8f, 0xa1, 0xff, 0x0b,
-	0x4d, 0xfd, 0x1f, 0x8b, 0xf4, 0x3f, 0xda, 0xd4, 0x1f, 0x31, 0xe2, 0xd3,
-	0xff, 0xdc, 0xd4, 0xff, 0x68, 0xa4, 0xff, 0x6c, 0x53, 0xff, 0x59, 0xf4,
-	0x7f, 0xad, 0xa9, 0x3f, 0xea, 0x8e, 0xb5, 0x98, 0xef, 0x62, 0xc4, 0xd8,
-	0x7d, 0x26, 0x16, 0xc7, 0xb3, 0xd6, 0xfc, 0xad, 0x85, 0x72, 0xd7, 0x83,
-	0x33, 0x08, 0xef, 0xb4, 0x51, 0x5f, 0xf3, 0xd0, 0xd7, 0x65, 0x5f, 0x26,
-	0x90, 0xc7, 0xa8, 0x2c, 0x12, 0x1f, 0x2a, 0x12, 0x73, 0x7d, 0xfa, 0x47,
-	0x56, 0xb9, 0x1a, 0xda, 0x24, 0xde, 0x5b, 0xe2, 0x7d, 0xd7, 0xc0, 0xf6,
-	0xc6, 0xdd, 0x45, 0x13, 0x83, 0x5d, 0xd1, 0x06, 0xda, 0x81, 0x97, 0x21,
-	0x66, 0xca, 0xe1, 0x40, 0x6f, 0x28, 0xbf, 0x9c, 0xdf, 0xe8, 0x0f, 0x65,
-	0xd5, 0xac, 0x33, 0xbc, 0x0a, 0xd7, 0xd2, 0xab, 0x72, 0x5b, 0xb1, 0x4b,
-	0xc0, 0xb5, 0x91, 0x06, 0xae, 0x7d, 0x51, 0xe6, 0x1a, 0xf1, 0xf6, 0x19,
-	0xd9, 0xef, 0xed, 0xe1, 0x3d, 0x9d, 0xc3, 0x79, 0xf9, 0x68, 0xe2, 0xed,
-	0x3d, 0x0d, 0x3b, 0xc9, 0x3b, 0x1d, 0xe9, 0x83, 0xbc, 0x83, 0x1b, 0xe6,
-	0x66, 0x27, 0xbd, 0x5f, 0xc7, 0xfe, 0x69, 0x33, 0x2f, 0x37, 0xde, 0xe6,
-	0x7c, 0x49, 0xd9, 0x1f, 0xdc, 0x77, 0x68, 0xcc, 0x5b, 0x69, 0xcc, 0x9b,
-	0x32, 0xfa, 0x46, 0x1b, 0xbc, 0x6c, 0x2f, 0x8b, 0xb0, 0x97, 0x63, 0x88,
-	0xb9, 0x17, 0xbd, 0xb5, 0xf2, 0xa3, 0x97, 0x6b, 0x2f, 0x9b, 0xf3, 0xcc,
-	0xcd, 0xf6, 0x92, 0xeb, 0x34, 0xe7, 0x96, 0xd3, 0x4d, 0xf8, 0x4f, 0x79,
-	0x3a, 0x67, 0x7c, 0x6a, 0x3c, 0xab, 0xe7, 0xa0, 0x8f, 0x4a, 0xc6, 0xb4,
-	0xfc, 0xb2, 0x1c, 0xc6, 0x96, 0xf7, 0x34, 0x62, 0xcb, 0xe5, 0x78, 0x10,
-	0xbe, 0x6b, 0xff, 0x67, 0x0c, 0x3e, 0xd2, 0x47, 0x76, 0xac, 0xb2, 0xb7,
-	0x5b, 0xed, 0xd5, 0x6d, 0xcc, 0x97, 0x5e, 0x2b, 0xb7, 0xea, 0x38, 0xfe,
-	0x8c, 0xc9, 0x4d, 0xcd, 0x69, 0xff, 0x9f, 0xdf, 0x0b, 0xca, 0xd9, 0x4d,
-	0xc6, 0xdf, 0xbb, 0x18, 0xae, 0xae, 0x8c, 0x4d, 0x95, 0x3a, 0x88, 0xb1,
-	0x8c, 0x4d, 0xfb, 0xdb, 0x89, 0xa1, 0x05, 0xff, 0x82, 0xe3, 0x31, 0x8e,
-	0xe3, 0xd9, 0x47, 0xc7, 0xa1, 0xe8, 0xb7, 0x68, 0xc6, 0x07, 0x71, 0x68,
-	0xc1, 0xff, 0x71, 0x5b, 0x80, 0x83, 0x17, 0x8a, 0x59, 0x3e, 0xdf, 0xce,
-	0xbc, 0xde, 0xa2, 0x77, 0x31, 0x5a, 0x57, 0xc7, 0xbd, 0xb1, 0x55, 0x71,
-	0xaf, 0x6d, 0xe2, 0xda, 0x5f, 0xd2, 0x71, 0x6f, 0xc0, 0x63, 0xee, 0x25,
-	0x1a, 0x47, 0xb9, 0xc0, 0x42, 0x7e, 0x53, 0x21, 0x3e, 0xd0, 0x47, 0x81,
-	0x9f, 0x35, 0xfd, 0x8b, 0xe0, 0x73, 0x72, 0x0d, 0xb9, 0xf9, 0xb8, 0xed,
-	0x44, 0xb8, 0xf7, 0x73, 0x12, 0xe4, 0xeb, 0x76, 0x83, 0x16, 0xc6, 0x56,
-	0x71, 0x23, 0x0f, 0x3f, 0x35, 0xf7, 0x2a, 0xc3, 0x7e, 0x61, 0x1c, 0xdf,
-	0xf8, 0xee, 0x5a, 0xc9, 0xaf, 0xc8, 0x9f, 0x74, 0x33, 0x0d, 0x8d, 0x73,
-	0xcf, 0x5f, 0xc6, 0x77, 0x8b, 0x0f, 0x73, 0x3f, 0xa2, 0xd9, 0xae, 0xf1,
-	0xbb, 0x29, 0xbf, 0x95, 0x8a, 0x75, 0x67, 0x9f, 0x0b, 0x1d, 0xe0, 0xbd,
-	0xe1, 0x28, 0xbe, 0x26, 0xa4, 0x34, 0x2b, 0x89, 0x64, 0x8e, 0xdf, 0x00,
-	0x68, 0xff, 0x7f, 0x68, 0xf6, 0x99, 0x92, 0x7d, 0x33, 0x41, 0xce, 0x53,
-	0x5d, 0xf0, 0x5e, 0xdc, 0xe3, 0xe0, 0x43, 0xe6, 0x50, 0x98, 0xf3, 0x54,
-	0xc1, 0xbd, 0xb8, 0x43, 0x1f, 0xdd, 0xbd, 0x38, 0xce, 0x6f, 0xcb, 0x9e,
-	0x35, 0xee, 0xc5, 0xc5, 0x2e, 0xf1, 0x5e, 0xdc, 0x26, 0x9d, 0xf3, 0xe4,
-	0x3c, 0x41, 0xce, 0x93, 0xe5, 0xad, 0x03, 0xcc, 0x95, 0xf0, 0xee, 0xdb,
-	0xa0, 0xbe, 0x2f, 0xbc, 0x75, 0xe0, 0xe7, 0x11, 0xa3, 0xfc, 0x75, 0xfb,
-	0xc7, 0x1f, 0xa3, 0x70, 0x2f, 0xbf, 0x11, 0x7c, 0xdf, 0x95, 0xcb, 0xc9,
-	0x03, 0x7c, 0xb8, 0xbc, 0xe6, 0x3e, 0x9d, 0xd7, 0x7c, 0xa7, 0x3d, 0x9a,
-	0xd7, 0x54, 0x17, 0xb9, 0x1b, 0xb6, 0x6f, 0x8d, 0xbc, 0x66, 0x3c, 0x72,
-	0x37, 0x2c, 0x6e, 0xee, 0x86, 0x6d, 0x72, 0x11, 0x4b, 0x9a, 0x3c, 0xa6,
-	0xba, 0xe0, 0xdd, 0xb0, 0xce, 0x0d, 0x1f, 0x3e, 0x8f, 0xb9, 0xea, 0x6e,
-	0x18, 0x6c, 0xdd, 0x16, 0x49, 0x5f, 0x56, 0xdc, 0xf3, 0x61, 0x62, 0x1e,
-	0xde, 0xab, 0x6f, 0xc1, 0x9e, 0xe3, 0xb2, 0x27, 0x49, 0xf9, 0xe4, 0xdd,
-	0xc6, 0x3e, 0xe8, 0x02, 0x9e, 0x3e, 0xcb, 0xfd, 0x3c, 0x23, 0x6b, 0xa4,
-	0x6f, 0xe5, 0x3d, 0x84, 0xe5, 0x3b, 0xbd, 0x89, 0xc6, 0x9d, 0xde, 0x29,
-	0xc8, 0x8d, 0x9a, 0x49, 0xc8, 0x7c, 0x44, 0xa6, 0x26, 0x3d, 0xf8, 0x4b,
-	0xb3, 0x8e, 0x69, 0xe7, 0xff, 0xef, 0x48, 0x02, 0xf3, 0x78, 0x0f, 0xb8,
-	0x43, 0x62, 0xb3, 0xc1, 0x37, 0xcb, 0xe0, 0xff, 0xb8, 0xa4, 0xd0, 0x87,
-	0x77, 0x3c, 0xe3, 0xb2, 0x5f, 0xe7, 0x2c, 0x42, 0x59, 0xfe, 0x35, 0xf0,
-	0x78, 0x73, 0x7e, 0xb9, 0x9c, 0x5c, 0xc3, 0xee, 0x27, 0xa5, 0x3c, 0x43,
-	0x79, 0xbe, 0xc1, 0xfc, 0xff, 0x82, 0xd3, 0x52, 0xf6, 0x4f, 0x99, 0xf8,
-	0x42, 0x7f, 0xdb, 0x01, 0x2f, 0xb7, 0x18, 0x1b, 0x8c, 0x67, 0x75, 0x0b,
-	0x6d, 0x1e, 0xd6, 0x38, 0x2e, 0xc3, 0xd3, 0x3b, 0x52, 0x7b, 0x81, 0x77,
-	0x63, 0x7a, 0xcd, 0xcb, 0xe1, 0xb9, 0x75, 0x9e, 0xef, 0x8d, 0x97, 0xca,
-	0xf7, 0xd0, 0x3f, 0xae, 0x62, 0x7f, 0x5b, 0x20, 0x1f, 0x5f, 0x95, 0xe2,
-	0xb1, 0x6b, 0x65, 0xf8, 0x68, 0x06, 0xf4, 0xbc, 0x5f, 0x2f, 0x67, 0xe1,
-	0x4b, 0x3f, 0xcd, 0x7b, 0x63, 0xc0, 0x50, 0xf0, 0xed, 0xf9, 0x55, 0xdf,
-	0xb1, 0xa3, 0x77, 0xcd, 0xfa, 0x1b, 0x77, 0x87, 0x9e, 0xf5, 0x25, 0xd1,
-	0x49, 0x9a, 0x67, 0x96, 0xef, 0x8f, 0x2f, 0xfa, 0xbb, 0xb4, 0x6d, 0x7b,
-	0xc6, 0x5f, 0x91, 0xfb, 0xd1, 0x67, 0x38, 0x5e, 0xfb, 0x1e, 0xec, 0xdb,
-	0x39, 0x8b, 0xf6, 0x6d, 0xca, 0x93, 0xab, 0x63, 0xc2, 0xf3, 0x10, 0x0b,
-	0x3c, 0xd0, 0x77, 0x38, 0x82, 0xef, 0xfb, 0x3d, 0xfa, 0x5c, 0x03, 0xac,
-	0x58, 0x88, 0xdc, 0xc1, 0x58, 0x3e, 0xdb, 0xe0, 0x6e, 0x46, 0x70, 0x16,
-	0xc1, 0xfd, 0x11, 0xed, 0x6f, 0x1e, 0xdc, 0xe3, 0x06, 0xf7, 0x47, 0x7a,
-	0x67, 0x59, 0xd7, 0xd5, 0x64, 0xfb, 0x12, 0x90, 0x01, 0xde, 0x3b, 0xe2,
-	0xbd, 0x71, 0xd2, 0xac, 0x73, 0x1d, 0xff, 0x47, 0xdd, 0xd5, 0xc7, 0xb6,
-	0x75, 0x5d, 0xf7, 0xc3, 0x47, 0xea, 0xc3, 0xb4, 0x2c, 0x53, 0x32, 0x25,
-	0xd3, 0x96, 0x2c, 0xbf, 0x27, 0x3d, 0x59, 0x72, 0xac, 0x14, 0xac, 0xab,
-	0xad, 0x02, 0x46, 0xa4, 0x0c, 0x49, 0x7f, 0xb4, 0x08, 0x06, 0xfa, 0xa3,
-	0x99, 0x8b, 0x66, 0xab, 0x4b, 0xd9, 0x4e, 0x0a, 0xf4, 0x0f, 0xb7, 0xc5,
-	0x80, 0x6c, 0x58, 0x60, 0x86, 0xb4, 0x12, 0x63, 0x56, 0x4c, 0xd6, 0x66,
-	0x85, 0x0c, 0xd8, 0x30, 0x4e, 0x54, 0x9c, 0x14, 0x50, 0xc6, 0x04, 0x69,
-	0x83, 0xa2, 0x58, 0x61, 0x45, 0x76, 0x36, 0x6c, 0x7f, 0x65, 0x43, 0xd0,
-	0x05, 0x9b, 0xb3, 0x38, 0x76, 0xb0, 0x06, 0x45, 0xd6, 0x7d, 0x62, 0x18,
-	0xd0, 0x0d, 0xdc, 0xf9, 0xdd, 0x0f, 0xf2, 0xf1, 0xf1, 0x51, 0x1f, 0x89,
-	0x33, 0x60, 0x02, 0x04, 0xbe, 0xf7, 0x78, 0xdf, 0x7b, 0xf7, 0x9e, 0x7b,
-	0xce, 0xb9, 0xbf, 0x73, 0xee, 0x39, 0x87, 0x9e, 0x7b, 0xdb, 0x9b, 0xf3,
-	0xb9, 0xca, 0x77, 0x8e, 0x8a, 0x77, 0x0e, 0x28, 0x9d, 0xa5, 0xe3, 0xc5,
-	0x63, 0xc6, 0x6c, 0x61, 0x22, 0xe2, 0x67, 0xfe, 0x9e, 0xad, 0xc2, 0xbe,
-	0x6e, 0x87, 0xe1, 0xd6, 0xa2, 0x67, 0xbc, 0x85, 0x9e, 0xcd, 0x32, 0xc1,
-	0xf6, 0x78, 0x5d, 0x77, 0x4b, 0xda, 0xc9, 0xeb, 0x88, 0x85, 0xd7, 0x31,
-	0x0e, 0x92, 0x76, 0x75, 0x19, 0xba, 0xe2, 0x8c, 0x6f, 0x68, 0xd0, 0xee,
-	0x74, 0x9d, 0x76, 0x3b, 0xff, 0x1f, 0xd1, 0xee, 0x1d, 0x81, 0x7f, 0x5f,
-	0xad, 0x22, 0x6e, 0x4d, 0x63, 0x00, 0x9d, 0x3b, 0x04, 0x3a, 0x42, 0x9f,
-	0x5a, 0xe5, 0x15, 0x82, 0x4e, 0x45, 0x5c, 0x71, 0xad, 0xf6, 0x5a, 0xb4,
-	0xee, 0xa7, 0x64, 0xbb, 0x04, 0xf6, 0x09, 0xfc, 0x79, 0xed, 0xd7, 0xc8,
-	0x63, 0x1f, 0x6b, 0x8d, 0x04, 0x56, 0x72, 0xdb, 0x27, 0x0c, 0x08, 0x1d,
-	0xf6, 0xc9, 0xb1, 0x4d, 0xda, 0x27, 0xe7, 0xa5, 0x7d, 0x92, 0xdd, 0xb8,
-	0x7d, 0xb2, 0xbb, 0x25, 0xae, 0xab, 0x31, 0x9e, 0xcd, 0xdb, 0x27, 0xc6,
-	0x9a, 0xf6, 0xc9, 0x90, 0xc3, 0x17, 0x83, 0xfe, 0xfe, 0x06, 0x65, 0x8f,
-	0x43, 0xc7, 0x69, 0x3a, 0x83, 0xc6, 0xc7, 0x5d, 0x7e, 0xe1, 0x4f, 0x93,
-	0xd6, 0xbf, 0xf8, 0x3f, 0xa6, 0xf5, 0x50, 0x8b, 0xcf, 0xbb, 0x31, 0x1e,
-	0x0a, 0xef, 0xd8, 0x14, 0x8e, 0x77, 0xd3, 0x7a, 0xa8, 0xad, 0xef, 0xb4,
-	0x7d, 0xcc, 0x62, 0xb3, 0xef, 0x74, 0xd4, 0x68, 0xa7, 0xdb, 0xff, 0xd8,
-	0xe1, 0x53, 0x75, 0xea, 0x77, 0xc8, 0x14, 0xf9, 0x8e, 0x4d, 0xe8, 0x77,
-	0x41, 0x96, 0xac, 0x6c, 0x96, 0x60, 0x33, 0xe1, 0x7d, 0x11, 0x21, 0x6b,
-	0x2e, 0xbc, 0xc5, 0xef, 0x63, 0x7a, 0xbe, 0xf8, 0x87, 0x62, 0x9d, 0x92,
-	0xfe, 0x07, 0xb4, 0x0f, 0xfb, 0xce, 0x88, 0xb6, 0x32, 0xbe, 0x49, 0xf9,
-	0x23, 0x14, 0xf6, 0x6f, 0xe7, 0x87, 0x68, 0x5d, 0xf3, 0x36, 0x67, 0x2b,
-	0x68, 0x19, 0xdf, 0xcb, 0xf3, 0x12, 0x69, 0xb2, 0xb5, 0xa0, 0x3f, 0xcf,
-	0x33, 0x2e, 0x18, 0xad, 0x63, 0x82, 0xe6, 0xb9, 0xb9, 0x28, 0x6c, 0x3a,
-	0xad, 0x3b, 0x57, 0x64, 0xec, 0xa9, 0xb8, 0x0e, 0x9c, 0xa6, 0x75, 0xa7,
-	0x1b, 0x07, 0xef, 0xf5, 0xe0, 0x0b, 0xcf, 0xdc, 0x4f, 0x3d, 0x77, 0x26,
-	0x62, 0xce, 0x53, 0x9e, 0x73, 0x57, 0xcf, 0xe1, 0xca, 0x36, 0xda, 0xca,
-	0xfb, 0x53, 0x62, 0x5c, 0xdf, 0xfc, 0x62, 0x02, 0xb9, 0x6a, 0xf5, 0xfc,
-	0x21, 0x77, 0xce, 0x14, 0xd6, 0x01, 0x2d, 0x87, 0x3a, 0x3f, 0x1b, 0xb4,
-	0x18, 0xf1, 0xc8, 0x99, 0x72, 0xae, 0x25, 0xb8, 0xcf, 0x4d, 0x8b, 0xc6,
-	0x3a, 0x32, 0xa7, 0xd6, 0x91, 0x45, 0x87, 0x1e, 0x6f, 0xc5, 0xed, 0xfd,
-	0x1e, 0xb8, 0xdd, 0x2b, 0x6f, 0x0a, 0x7d, 0x7a, 0x92, 0x71, 0xc8, 0x67,
-	0x80, 0x43, 0x42, 0xc8, 0x5b, 0x92, 0x58, 0x04, 0xdf, 0x17, 0x19, 0x8f,
-	0x44, 0x98, 0x57, 0x7e, 0x44, 0xe7, 0x18, 0x6b, 0x5f, 0xa7, 0xfd, 0xca,
-	0x3e, 0x83, 0xdc, 0xea, 0x38, 0x53, 0xc4, 0xf1, 0xfb, 0x28, 0xfb, 0x98,
-	0x35, 0x19, 0xa7, 0x1f, 0xd1, 0x59, 0x11, 0x33, 0x83, 0xfd, 0x3d, 0xc4,
-	0x1c, 0x3c, 0x20, 0xde, 0x2f, 0x7d, 0x19, 0xf7, 0x23, 0xa6, 0x6e, 0xe3,
-	0xf1, 0xfb, 0x2a, 0xb7, 0x8e, 0xdb, 0xe1, 0x9d, 0x4b, 0x4a, 0xa6, 0xc4,
-	0x35, 0xbe, 0xff, 0x49, 0xa3, 0xf5, 0xfe, 0xb8, 0x91, 0xaa, 0xa6, 0x8c,
-	0x44, 0x05, 0xed, 0x9e, 0x34, 0x92, 0x55, 0xd8, 0x90, 0x9a, 0x47, 0xac,
-	0x28, 0xe4, 0x6d, 0x95, 0xd6, 0xdf, 0x8b, 0x58, 0x24, 0x57, 0x9e, 0xc4,
-	0x06, 0xfa, 0x7d, 0xb8, 0xa9, 0xdf, 0x9a, 0xbe, 0x38, 0x86, 0xbf, 0xe7,
-	0x15, 0xa6, 0xa9, 0xc6, 0xb5, 0x41, 0xf8, 0xd7, 0x27, 0xb3, 0xb4, 0x16,
-	0xae, 0xb5, 0x5a, 0x70, 0xed, 0xe2, 0xba, 0xfd, 0xfe, 0xa4, 0x32, 0x2e,
-	0xf3, 0xa3, 0xfd, 0xb6, 0xc0, 0xaf, 0xdc, 0xef, 0x26, 0x6c, 0xeb, 0xe2,
-	0x29, 0xb4, 0xd1, 0x7e, 0x70, 0xed, 0x07, 0xeb, 0x55, 0xf1, 0xc0, 0x3a,
-	0x3e, 0x21, 0x88, 0x7c, 0xaf, 0x90, 0x8c, 0x6b, 0x85, 0x8d, 0xb5, 0xc2,
-	0xfd, 0x83, 0xbd, 0x05, 0x9f, 0x8f, 0xb0, 0xb7, 0xcc, 0x24, 0x49, 0x5f,
-	0xf7, 0x99, 0xaa, 0xd3, 0xbf, 0xeb, 0x95, 0x4b, 0x39, 0xea, 0x91, 0x4b,
-	0xe9, 0x94, 0xb5, 0x80, 0x43, 0xd6, 0x22, 0x0e, 0xdc, 0x36, 0xcc, 0x76,
-	0x4b, 0x0f, 0xeb, 0x90, 0x1e, 0xb1, 0x6d, 0xe2, 0xbf, 0xea, 0xb4, 0x5b,
-	0xdc, 0x79, 0xf1, 0x90, 0x3b, 0x60, 0x33, 0x69, 0xc3, 0xa4, 0x4a, 0xf5,
-	0x9c, 0x7a, 0x1e, 0x77, 0x23, 0x6f, 0xb1, 0xd2, 0x92, 0x63, 0xe9, 0xd5,
-	0xdf, 0x91, 0x96, 0xfe, 0x62, 0xfd, 0x8a, 0xb7, 0xc5, 0x74, 0x5e, 0x76,
-	0xd5, 0xfd, 0xea, 0x9f, 0x5b, 0x9f, 0xe1, 0x5d, 0xa3, 0xc2, 0xe7, 0x9d,
-	0xad, 0xeb, 0xb2, 0x19, 0xd9, 0xdf, 0x42, 0xb3, 0x9d, 0xe1, 0xbf, 0x42,
-	0x8a, 0x76, 0xde, 0xba, 0x7d, 0x73, 0xfe, 0xb3, 0xad, 0x6e, 0x1c, 0xdc,
-	0x27, 0xfd, 0x62, 0x73, 0x2a, 0x0e, 0x7b, 0x40, 0xd9, 0x7b, 0xeb, 0xf1,
-	0x3b, 0xae, 0xcd, 0x29, 0x5f, 0xa2, 0x65, 0x96, 0x09, 0x7c, 0x7e, 0xfc,
-	0x54, 0x87, 0x1d, 0x52, 0x7b, 0x59, 0xd8, 0xaf, 0x02, 0xdf, 0xeb, 0xe7,
-	0x43, 0x67, 0x6f, 0x64, 0xce, 0xcc, 0x96, 0x39, 0x93, 0x7c, 0x05, 0x5b,
-	0x0b, 0xf1, 0xc5, 0x53, 0xae, 0x18, 0xef, 0x4f, 0x42, 0x8b, 0x5e, 0x8f,
-	0xb8, 0x67, 0xc4, 0x2d, 0xb7, 0xeb, 0xe7, 0x1d, 0x07, 0x2e, 0x47, 0x7f,
-	0x6b, 0xb5, 0x57, 0xa2, 0xbb, 0xe5, 0x5a, 0x5c, 0xf5, 0xc6, 0x48, 0xa1,
-	0x0d, 0xf7, 0xcf, 0xbd, 0xf6, 0xee, 0xda, 0xe0, 0xda, 0x2b, 0xea, 0x8b,
-	0xf8, 0x0e, 0x09, 0x1d, 0xd0, 0x43, 0x95, 0x12, 0xe2, 0xaf, 0x3f, 0x0b,
-	0x99, 0x67, 0x3d, 0xeb, 0xc8, 0x49, 0xf3, 0x9e, 0xc7, 0xfa, 0x9e, 0x4a,
-	0x20, 0x86, 0xbd, 0x3f, 0xc4, 0x96, 0xf4, 0xb3, 0xee, 0x41, 0xfb, 0x71,
-	0xf3, 0x16, 0xfc, 0xbd, 0xca, 0xff, 0x94, 0x52, 0xeb, 0xcb, 0xa1, 0x0d,
-	0xec, 0xad, 0x6c, 0x4e, 0x4f, 0x5b, 0xe6, 0x0a, 0x61, 0xdf, 0x07, 0xf1,
-	0xc2, 0xc7, 0x7a, 0xa9, 0xf7, 0x2b, 0x5d, 0x5d, 0xf6, 0x1f, 0xf4, 0xc9,
-	0xbd, 0x28, 0x7c, 0xd7, 0x43, 0x2f, 0x94, 0x10, 0xcb, 0x8d, 0xef, 0x7e,
-	0x8b, 0xbf, 0xf3, 0xd2, 0x51, 0x3a, 0x16, 0x1d, 0x58, 0x4e, 0xce, 0x4f,
-	0x99, 0x60, 0x2b, 0xd5, 0xe8, 0x6f, 0xa2, 0x9f, 0x93, 0xfb, 0x19, 0xd5,
-	0xfb, 0xbd, 0x57, 0xe3, 0xe5, 0x2f, 0xfc, 0x69, 0xdf, 0xc7, 0x8d, 0x8d,
-	0xfc, 0xd6, 0x86, 0xfc, 0x85, 0xd8, 0xe7, 0xdf, 0xc8, 0x9e, 0x89, 0xde,
-	0x1b, 0x9e, 0x16, 0x39, 0xa7, 0x4e, 0x3e, 0xb8, 0x3f, 0xfb, 0xc3, 0xe0,
-	0x87, 0x91, 0x16, 0x5d, 0xf5, 0xc9, 0xfd, 0xfd, 0x6e, 0xba, 0x06, 0x3d,
-	0x7d, 0x55, 0xde, 0xfb, 0xc0, 0xd8, 0xf3, 0x87, 0x9f, 0xba, 0x4a, 0x67,
-	0xae, 0x81, 0x87, 0x0d, 0xe6, 0xb6, 0x31, 0xca, 0x87, 0x91, 0x57, 0x24,
-	0x72, 0x73, 0xf4, 0xbe, 0xa1, 0xc8, 0x15, 0x3a, 0x23, 0x72, 0x20, 0xc7,
-	0x23, 0xf7, 0x78, 0x3d, 0x3c, 0x53, 0x7d, 0x9b, 0xce, 0x56, 0x82, 0xfc,
-	0xdf, 0xc0, 0xee, 0xad, 0x79, 0x90, 0xcd, 0x3c, 0x7e, 0x4f, 0xf0, 0xf8,
-	0xf0, 0x9a, 0x3c, 0x7e, 0xa4, 0xce, 0xe3, 0x5f, 0xe9, 0x97, 0xfc, 0xdc,
-	0xcb, 0xcf, 0xea, 0xa5, 0x43, 0xe2, 0xb9, 0x6f, 0xf3, 0xf1, 0x56, 0x3a,
-	0x14, 0x92, 0xc7, 0x67, 0x2b, 0xac, 0xe3, 0x0b, 0x6f, 0xd3, 0xb9, 0x6b,
-	0x59, 0x5f, 0x4a, 0xe4, 0x2f, 0x38, 0x6b, 0x69, 0xe8, 0xfb, 0xd1, 0xae,
-	0x1d, 0xff, 0x6b, 0xbd, 0x24, 0x73, 0xae, 0xca, 0x52, 0x3f, 0xd1, 0x5b,
-	0xd1, 0x21, 0x17, 0xff, 0x37, 0xdb, 0x8e, 0xe7, 0xd5, 0x1a, 0x78, 0x7c,
-	0x0d, 0xbf, 0x46, 0x2b, 0x5f, 0xf6, 0x79, 0xe0, 0xe1, 0xa7, 0xfb, 0xe5,
-	0x3e, 0xd5, 0x5a, 0x7e, 0x8d, 0xa6, 0xb8, 0x0e, 0xe7, 0xbe, 0x3d, 0xeb,
-	0xfd, 0x3d, 0x2a, 0x17, 0xf0, 0x87, 0xfd, 0x72, 0xbd, 0x40, 0x7e, 0xe0,
-	0x0a, 0xd3, 0xe1, 0x22, 0x63, 0x95, 0x21, 0xea, 0xbc, 0xaa, 0xc7, 0x3a,
-	0x24, 0xf4, 0xad, 0xd3, 0x4f, 0x73, 0x51, 0xe5, 0x76, 0xe7, 0x1c, 0x63,
-	0xba, 0x28, 0x6c, 0x9c, 0xf6, 0xf2, 0xd6, 0x3e, 0xe6, 0x6a, 0xd8, 0xb5,
-	0x26, 0xb8, 0xf9, 0x0d, 0x75, 0x4a, 0x30, 0xbf, 0x64, 0x48, 0x1c, 0x3c,
-	0xc3, 0xf8, 0x76, 0xb3, 0xfb, 0x45, 0x9f, 0x14, 0x23, 0xba, 0x6b, 0x60,
-	0xb8, 0x8f, 0x31, 0x0f, 0xd2, 0xe6, 0xc8, 0xbc, 0x58, 0x15, 0xba, 0xe0,
-	0xe2, 0x54, 0x8d, 0x92, 0xd1, 0x6d, 0x94, 0x99, 0xe2, 0x77, 0xcf, 0xd8,
-	0x6c, 0x7b, 0xf9, 0x29, 0xcb, 0xf2, 0x9b, 0x99, 0xda, 0xa2, 0xf0, 0xa2,
-	0xf6, 0xa7, 0x77, 0xa9, 0x38, 0x87, 0x5e, 0xb1, 0x2f, 0x29, 0x6b, 0xf5,
-	0xf0, 0x71, 0x45, 0x3f, 0x1b, 0xd7, 0xc1, 0xbb, 0x9d, 0xaa, 0xdd, 0x65,
-	0x47, 0x3b, 0xb4, 0xb9, 0xac, 0xda, 0xe2, 0x99, 0x1a, 0x53, 0x74, 0x2b,
-	0x7d, 0x0b, 0x39, 0x5c, 0x51, 0xb9, 0x7a, 0xc2, 0x7e, 0xa0, 0xd9, 0xfa,
-	0x58, 0x2e, 0x73, 0xdb, 0xff, 0xae, 0xc5, 0x85, 0x2d, 0x77, 0x99, 0x31,
-	0x6f, 0x55, 0xc8, 0x8a, 0xbb, 0x4f, 0x18, 0x8b, 0x5f, 0xec, 0x0f, 0xf1,
-	0xb1, 0x7a, 0xcf, 0xe9, 0x7a, 0x9f, 0x10, 0xa3, 0x61, 0x45, 0xe4, 0xb3,
-	0x74, 0xbb, 0xcb, 0x8e, 0x76, 0x5a, 0x57, 0xe8, 0xfd, 0x87, 0x8f, 0x7c,
-	0xb3, 0x85, 0xdb, 0x3e, 0x19, 0xc3, 0x1b, 0x12, 0xfb, 0xa7, 0x32, 0x46,
-	0x43, 0x1f, 0xc3, 0xbf, 0x8c, 0x98, 0x0a, 0xc4, 0x49, 0x38, 0xf5, 0x8d,
-	0x1c, 0x6f, 0x00, 0x6b, 0x51, 0x15, 0xfb, 0xa6, 0xd8, 0xaf, 0x68, 0x87,
-	0x9d, 0x77, 0x21, 0x36, 0x7f, 0x13, 0x18, 0x74, 0x23, 0xf2, 0x67, 0x7a,
-	0xc8, 0x9f, 0xf3, 0xfd, 0xc8, 0x83, 0x43, 0x3e, 0x5c, 0x76, 0xd2, 0xa0,
-	0x1a, 0xdb, 0x0a, 0x06, 0x95, 0x43, 0x3e, 0x3a, 0x67, 0x5b, 0xd1, 0x8a,
-	0xc0, 0x9a, 0x8f, 0xc0, 0x7f, 0x35, 0xb9, 0x42, 0x07, 0x44, 0xce, 0x38,
-	0x6a, 0x1f, 0x94, 0x79, 0x0d, 0x3e, 0xcd, 0x3c, 0x78, 0x96, 0xed, 0x8f,
-	0xec, 0x49, 0xec, 0xb7, 0xe8, 0x79, 0x41, 0x0e, 0x3c, 0x3e, 0x4d, 0x9e,
-	0xbb, 0xdf, 0xdd, 0x41, 0xc1, 0x38, 0x3f, 0xd3, 0x84, 0x7e, 0xe2, 0xe7,
-	0xa4, 0x29, 0xc1, 0x76, 0x12, 0x6c, 0xd6, 0xd3, 0x27, 0xad, 0x50, 0x99,
-	0x0c, 0x6e, 0x0b, 0xdb, 0x15, 0xcf, 0xc1, 0xfd, 0xf1, 0x50, 0x07, 0xb9,
-	0x73, 0x72, 0x7b, 0x45, 0x9e, 0xe2, 0x5b, 0xd1, 0x07, 0xc9, 0x18, 0x84,
-	0xbe, 0xc2, 0xbc, 0x3d, 0xa0, 0xf6, 0x89, 0xb6, 0xf3, 0xf1, 0x84, 0x3a,
-	0x0e, 0x8a, 0xf9, 0x94, 0xc7, 0x9a, 0xbf, 0xf1, 0xf7, 0xf3, 0x2e, 0xb2,
-	0xfd, 0x6a, 0xfe, 0x9a, 0x62, 0x41, 0x22, 0x63, 0x46, 0x90, 0xce, 0x57,
-	0xd6, 0xf2, 0xbf, 0x78, 0xe5, 0xba, 0x6e, 0xdf, 0x60, 0xae, 0xeb, 0x4f,
-	0x76, 0xc8, 0xdc, 0x32, 0x67, 0x5f, 0xfe, 0x93, 0xfb, 0xe2, 0x85, 0xc9,
-	0x5a, 0x70, 0x22, 0x8f, 0xb7, 0x46, 0x3f, 0x8b, 0x7e, 0x9e, 0xee, 0x84,
-	0x23, 0x2a, 0x66, 0x09, 0x31, 0x4a, 0x0f, 0x2a, 0xbe, 0xd6, 0xba, 0x9f,
-	0x3c, 0x74, 0xff, 0xa3, 0x22, 0x56, 0x53, 0xae, 0x1d, 0x43, 0x8a, 0x1e,
-	0xa0, 0x59, 0xc4, 0x41, 0xb3, 0x01, 0x07, 0xcd, 0x0c, 0x75, 0xbc, 0x4d,
-	0x9c, 0x9f, 0xaf, 0x3c, 0xb5, 0x5d, 0xe6, 0x8b, 0x63, 0x2f, 0xf1, 0x92,
-	0x3a, 0x5e, 0x6f, 0xbc, 0x56, 0x98, 0x82, 0xc2, 0xdf, 0xe4, 0x18, 0xeb,
-	0xcb, 0x44, 0xf6, 0x81, 0x70, 0x2b, 0x0d, 0x5e, 0x73, 0x5c, 0x47, 0x1f,
-	0xc7, 0x1d, 0x7d, 0x1c, 0x75, 0xf4, 0x71, 0x6f, 0x9b, 0x3e, 0xb2, 0x8e,
-	0xe7, 0xf7, 0x9c, 0xad, 0x7e, 0xdc, 0xbe, 0xa2, 0x9f, 0xc8, 0x23, 0x06,
-	0x3d, 0xb7, 0x52, 0x2e, 0x1c, 0x51, 0x6b, 0xc7, 0x2f, 0x55, 0x2e, 0xba,
-	0x57, 0x9f, 0xff, 0x8e, 0xda, 0xcf, 0x9b, 0x93, 0x57, 0x9d, 0xf9, 0xc7,
-	0xdf, 0xa5, 0xa4, 0xcc, 0x23, 0x57, 0xb2, 0x7d, 0xb9, 0x8d, 0x1f, 0x1a,
-	0xf1, 0x1c, 0xc0, 0x20, 0xc2, 0x2e, 0xdc, 0x2d, 0x6b, 0xc1, 0x05, 0x68,
-	0xa9, 0x9e, 0xcb, 0xeb, 0x57, 0xb9, 0x3b, 0xc7, 0xc3, 0xf7, 0x37, 0x8f,
-	0x17, 0xd7, 0xff, 0x4c, 0xf8, 0xf2, 0xe4, 0xfe, 0xd1, 0x8a, 0xca, 0x47,
-	0xb6, 0x4c, 0xc4, 0x06, 0x2c, 0x2e, 0xc3, 0xff, 0xda, 0x2e, 0x77, 0x57,
-	0xea, 0xa2, 0x4c, 0xbd, 0x3e, 0x4a, 0x59, 0xe4, 0x35, 0x48, 0xff, 0x98,
-	0xcc, 0xbf, 0x5d, 0x5c, 0xbe, 0x25, 0x72, 0x5e, 0x13, 0x2a, 0x8f, 0x37,
-	0x43, 0x3d, 0x02, 0xe7, 0x7e, 0xfc, 0xfc, 0xdb, 0x17, 0xc2, 0x9b, 0xcf,
-	0xbf, 0x75, 0xde, 0xb3, 0xb9, 0xfc, 0xdb, 0x10, 0x8f, 0xdd, 0x58, 0x90,
-	0xf9, 0xb7, 0xcd, 0x7b, 0x32, 0x32, 0xff, 0x36, 0xe3, 0xc0, 0x0f, 0x12,
-	0xaf, 0xbf, 0xe5, 0x88, 0xdf, 0x96, 0xb9, 0xb5, 0x8b, 0x75, 0xcc, 0x2a,
-	0x73, 0x6b, 0x65, 0xbc, 0xb7, 0xb3, 0x0e, 0x8c, 0xdc, 0xfb, 0x91, 0xef,
-	0xd9, 0xe6, 0xda, 0xfb, 0x91, 0x39, 0xb5, 0xa6, 0xd1, 0xce, 0x86, 0xc3,
-	0x1a, 0x81, 0x7a, 0x08, 0x71, 0xe6, 0xdd, 0xad, 0x6d, 0xea, 0x21, 0xc4,
-	0xdb, 0xd4, 0x43, 0x70, 0xea, 0x7e, 0x27, 0xc6, 0x02, 0x26, 0xc6, 0xda,
-	0x08, 0x2c, 0x8c, 0x7a, 0x06, 0x51, 0x3a, 0x5f, 0xc7, 0x9e, 0x0f, 0x52,
-	0x5a, 0x61, 0xcf, 0xf3, 0x15, 0xad, 0x8f, 0x46, 0x5d, 0xfa, 0xc8, 0x0b,
-	0x8b, 0x5a, 0x2a, 0xce, 0x47, 0xcb, 0x6b, 0xd6, 0x21, 0xaf, 0x59, 0x0f,
-	0x79, 0xc5, 0x3d, 0xd9, 0x36, 0xfd, 0xfe, 0xa5, 0xba, 0x07, 0xff, 0x4f,
-	0x46, 0x50, 0xb3, 0x85, 0x68, 0xf7, 0x80, 0xc2, 0x7f, 0x0e, 0x79, 0x3d,
-	0xcb, 0xf2, 0xaa, 0xaf, 0xa3, 0xbf, 0xed, 0x6c, 0x00, 0x8d, 0x19, 0x87,
-	0x7c, 0x87, 0xaf, 0xbd, 0x21, 0xe2, 0xa4, 0x9a, 0xed, 0x45, 0x8d, 0x27,
-	0xf6, 0x09, 0x59, 0xba, 0xe3, 0x47, 0xdc, 0x8a, 0xbe, 0x16, 0x52, 0x7e,
-	0x32, 0x4d, 0x8b, 0xce, 0x26, 0xcc, 0xd1, 0xc0, 0x1b, 0x22, 0xc6, 0xd7,
-	0xd1, 0xb7, 0x7f, 0xe5, 0xbe, 0xe9, 0xeb, 0x7a, 0xcd, 0x7c, 0xa7, 0xc9,
-	0x9f, 0x71, 0xa3, 0xa9, 0xee, 0x1f, 0x7c, 0x47, 0xdb, 0xd2, 0x86, 0x9d,
-	0x12, 0x31, 0xa6, 0x7d, 0x36, 0xfc, 0x64, 0x09, 0x96, 0xfd, 0xbe, 0x34,
-	0xe2, 0x99, 0xfb, 0xae, 0x98, 0x74, 0xa2, 0x70, 0x7e, 0x8f, 0xe4, 0x95,
-	0x0b, 0xa2, 0xa6, 0x25, 0x6a, 0x20, 0x26, 0x79, 0x7d, 0x4e, 0x30, 0xe8,
-	0x9c, 0xab, 0x76, 0xd1, 0x22, 0xa3, 0x7b, 0xbf, 0x5d, 0x16, 0xbe, 0x3e,
-	0xd6, 0x49, 0x45, 0xd4, 0x36, 0x35, 0x16, 0x3a, 0xf9, 0xb9, 0x83, 0xb4,
-	0x54, 0x1a, 0x17, 0x35, 0xa1, 0x64, 0x7d, 0x11, 0xb4, 0xf5, 0x51, 0xbf,
-	0xfd, 0x0d, 0xa6, 0xdd, 0xd7, 0x44, 0x8c, 0xe5, 0x62, 0xf1, 0x82, 0xfc,
-	0x2c, 0x3f, 0xa5, 0xde, 0xc1, 0xef, 0xab, 0xfe, 0x98, 0xe2, 0xfd, 0xa6,
-	0xc3, 0x96, 0x73, 0xfe, 0x79, 0xe3, 0x95, 0x63, 0x9b, 0xc2, 0x2b, 0xd9,
-	0x74, 0x03, 0xaf, 0x38, 0x9f, 0xad, 0xb1, 0xcb, 0xe4, 0xa0, 0xac, 0xf7,
-	0x00, 0x1a, 0x6c, 0x05, 0x16, 0x4b, 0x83, 0x96, 0x46, 0xcc, 0x8a, 0x24,
-	0xfc, 0x33, 0x94, 0xaf, 0x5e, 0xa7, 0x4c, 0x11, 0x98, 0x99, 0x3f, 0xcb,
-	0xe7, 0x76, 0x4a, 0x1f, 0x8d, 0xbe, 0x07, 0x7a, 0x65, 0x07, 0xb7, 0xff,
-	0xeb, 0x41, 0x19, 0x97, 0xed, 0xbc, 0xde, 0xcb, 0xd7, 0xbf, 0x10, 0x69,
-	0xbe, 0xbe, 0x85, 0xaf, 0xf7, 0xa7, 0x31, 0x87, 0xc6, 0x15, 0xf8, 0x25,
-	0x27, 0x29, 0xc7, 0xf3, 0x93, 0xaf, 0xf2, 0xda, 0x7a, 0x95, 0xf5, 0x55,
-	0x45, 0xb7, 0x1b, 0x40, 0xce, 0x8e, 0x98, 0x13, 0x83, 0xdb, 0x5c, 0x2c,
-	0x4c, 0x71, 0xbb, 0x21, 0xf2, 0x5f, 0x35, 0x29, 0x5f, 0xd1, 0xbc, 0xaa,
-	0xe3, 0xed, 0xdf, 0x18, 0x90, 0x31, 0x55, 0xef, 0xec, 0x94, 0xf4, 0x9b,
-	0x14, 0x3e, 0x4f, 0xc4, 0x73, 0x3c, 0x23, 0xf8, 0xd0, 0x9a, 0x31, 0xeb,
-	0xef, 0xdf, 0x06, 0xbe, 0x42, 0xdd, 0x54, 0x1e, 0x03, 0xeb, 0xc5, 0x98,
-	0x1d, 0xca, 0xd5, 0x63, 0xd5, 0x9e, 0xdb, 0x2d, 0xef, 0xff, 0xe9, 0x80,
-	0xac, 0x55, 0x7a, 0x5b, 0x9d, 0xeb, 0x35, 0x07, 0xf1, 0xcb, 0x3e, 0x41,
-	0x1b, 0xff, 0x02, 0xf4, 0xa5, 0xc1, 0xc7, 0x3c, 0x9e, 0x34, 0xfa, 0xf8,
-	0xb3, 0x01, 0x5d, 0x9f, 0x50, 0x8e, 0xeb, 0x28, 0xf7, 0x37, 0xc5, 0xe3,
-	0xd2, 0xd7, 0xe3, 0x7c, 0xee, 0x35, 0xbf, 0x78, 0x56, 0x30, 0x2d, 0xeb,
-	0x8b, 0x05, 0xd3, 0x99, 0x49, 0x39, 0xcf, 0x0d, 0x9f, 0x6e, 0xa4, 0xee,
-	0xd3, 0x9d, 0x2b, 0xf4, 0x0f, 0xc2, 0xbf, 0x61, 0x5c, 0xe1, 0xf9, 0x0e,
-	0x3f, 0xc3, 0x6d, 0x91, 0xab, 0x90, 0xe3, 0xcf, 0x1e, 0x15, 0xd7, 0xd3,
-	0xca, 0x2b, 0x32, 0x4e, 0x42, 0xaf, 0x5b, 0xb8, 0x77, 0x80, 0x9f, 0x21,
-	0xd7, 0xae, 0xf6, 0xef, 0xa1, 0x96, 0x38, 0x98, 0x56, 0x1e, 0x5b, 0xcb,
-	0x0f, 0x2b, 0xf6, 0x13, 0x3d, 0xf8, 0x6c, 0xad, 0x7a, 0x06, 0xef, 0x08,
-	0x3f, 0x5a, 0xb2, 0x45, 0x5e, 0x21, 0xc7, 0x01, 0xfa, 0xce, 0x7c, 0x96,
-	0xb6, 0xf0, 0x5c, 0x7d, 0xc3, 0xf8, 0x35, 0xec, 0xb7, 0x93, 0x8c, 0x79,
-	0x62, 0x1a, 0x17, 0xec, 0xc9, 0xb3, 0x06, 0xd3, 0xb9, 0x90, 0xad, 0x05,
-	0xec, 0x1e, 0xea, 0x64, 0x59, 0xfd, 0x22, 0x8d, 0xb1, 0xfd, 0x07, 0x99,
-	0xb5, 0x23, 0x29, 0x82, 0xbc, 0x59, 0xa1, 0xc3, 0xcc, 0x13, 0xc9, 0x2a,
-	0xf8, 0xd9, 0xa0, 0x27, 0x4a, 0x44, 0x8f, 0x97, 0xc6, 0x42, 0xdf, 0x27,
-	0xdb, 0x6c, 0x7c, 0x6f, 0x85, 0x12, 0xdc, 0x8f, 0x54, 0xf5, 0x77, 0xe8,
-	0x43, 0x51, 0xe7, 0x04, 0x74, 0xd4, 0xf3, 0xfe, 0xdb, 0x74, 0x3a, 0x8d,
-	0x7e, 0x6f, 0x5c, 0x3e, 0x4f, 0x6c, 0x4a, 0x3e, 0x83, 0x1e, 0xf2, 0xf9,
-	0xea, 0xa0, 0xe4, 0x9b, 0x1a, 0xf3, 0x68, 0x90, 0x66, 0x8b, 0x88, 0x01,
-	0x7b, 0x18, 0x75, 0xa7, 0x8a, 0x19, 0xd6, 0x4b, 0x99, 0x86, 0x5e, 0xba,
-	0x94, 0xf0, 0xc7, 0x21, 0xe3, 0xa8, 0xcb, 0xa6, 0xe2, 0x7e, 0x30, 0x8e,
-	0xdd, 0x34, 0xb6, 0xb0, 0x95, 0xef, 0xa5, 0x95, 0xc4, 0x74, 0x5c, 0xe5,
-	0xfa, 0x5b, 0x66, 0x92, 0xf5, 0xe3, 0x1c, 0xcb, 0x72, 0xae, 0xf8, 0x00,
-	0x2d, 0x86, 0x87, 0x69, 0x74, 0x41, 0xd7, 0x37, 0xc1, 0x58, 0xff, 0x6d,
-	0x48, 0xea, 0x24, 0x3d, 0xee, 0x5f, 0x11, 0xbe, 0x0b, 0xf3, 0xfa, 0xa7,
-	0x35, 0xee, 0xad, 0xeb, 0xe8, 0xa5, 0xbf, 0x52, 0x32, 0x5b, 0xbb, 0x91,
-	0x88, 0x52, 0x36, 0x31, 0xfd, 0x97, 0x82, 0xff, 0x47, 0xaf, 0xc3, 0x0f,
-	0x07, 0x1d, 0x6d, 0x52, 0xba, 0xe0, 0xa6, 0xc5, 0x30, 0x8f, 0x1b, 0xdf,
-	0xd7, 0xfe, 0x79, 0x36, 0xfa, 0x94, 0x58, 0xfb, 0xc7, 0xae, 0x73, 0x3b,
-	0xb1, 0x36, 0x69, 0xbd, 0xe1, 0xc5, 0x87, 0xba, 0x8e, 0xa5, 0xe6, 0x45,
-	0x19, 0xeb, 0xc9, 0xf8, 0x2d, 0x94, 0xf6, 0xbb, 0x79, 0xf2, 0x23, 0x3a,
-	0x36, 0x6f, 0xd2, 0xf1, 0x82, 0xf5, 0x7c, 0x96, 0x66, 0x58, 0xae, 0x9d,
-	0xeb, 0x05, 0xb7, 0x27, 0xf0, 0x59, 0x8c, 0x65, 0x9f, 0xed, 0xe6, 0xa2,
-	0x29, 0xe3, 0xee, 0x44, 0xed, 0xb9, 0x2e, 0xa1, 0x47, 0x43, 0xf6, 0x3f,
-	0x0d, 0xea, 0xf5, 0x20, 0x53, 0x44, 0x1e, 0x21, 0x7f, 0x96, 0xb9, 0x7d,
-	0x61, 0x90, 0x32, 0x25, 0x3c, 0x07, 0xeb, 0x1d, 0xfa, 0xce, 0xe7, 0x4b,
-	0x72, 0x5e, 0x47, 0xf9, 0xd9, 0xc8, 0xbb, 0x3f, 0x5e, 0x9d, 0x12, 0xb1,
-	0x77, 0xd0, 0xcd, 0x72, 0x3e, 0x63, 0x74, 0xd1, 0x53, 0xaf, 0x28, 0x4c,
-	0xe9, 0x90, 0xef, 0x8c, 0x90, 0xef, 0x98, 0x98, 0x8f, 0x4c, 0xc9, 0x60,
-	0xbc, 0xa6, 0x7d, 0x0f, 0xfd, 0x7c, 0x1e, 0x50, 0x3a, 0x04, 0xdf, 0x0d,
-	0xec, 0x14, 0x71, 0x89, 0x36, 0xae, 0xe3, 0x33, 0x46, 0xcf, 0x30, 0xee,
-	0x7c, 0xb6, 0xd0, 0x45, 0xb7, 0x8a, 0x5d, 0xf4, 0x66, 0x71, 0x98, 0x6e,
-	0xce, 0x6f, 0xa7, 0x8b, 0x8c, 0x99, 0x2f, 0xda, 0x01, 0x33, 0xc7, 0xf6,
-	0xc5, 0x0b, 0x51, 0x11, 0x33, 0xc4, 0x72, 0x87, 0xf6, 0xc0, 0x7f, 0x89,
-	0x5d, 0xcc, 0x73, 0x8c, 0xbd, 0xbb, 0xe9, 0x03, 0x7e, 0x67, 0xae, 0xa0,
-	0x63, 0x1d, 0xe0, 0x93, 0x1f, 0xaf, 0xe3, 0xd7, 0xf5, 0x79, 0x24, 0xb4,
-	0x0e, 0x8f, 0xc4, 0x84, 0xae, 0xcf, 0xcf, 0xf3, 0xf7, 0xf3, 0xf0, 0x9f,
-	0x33, 0xbd, 0x59, 0x3f, 0x7f, 0x3d, 0x80, 0xf6, 0xb8, 0x66, 0xcb, 0x58,
-	0x49, 0x31, 0xb6, 0x08, 0x9f, 0x83, 0xb6, 0x11, 0x45, 0x87, 0x6e, 0x1e,
-	0x9f, 0x4f, 0xb4, 0xcf, 0x2c, 0x75, 0xd3, 0x99, 0x12, 0x63, 0x90, 0x92,
-	0x9f, 0x6d, 0x18, 0xb4, 0x0d, 0xec, 0xd5, 0xf5, 0x5f, 0x2f, 0x72, 0xdf,
-	0x73, 0x25, 0x89, 0x41, 0x72, 0x4b, 0xbd, 0x94, 0x2f, 0xf5, 0xa8, 0xf3,
-	0x07, 0x44, 0x8c, 0xbb, 0xac, 0x63, 0x84, 0xef, 0xd6, 0xd2, 0x6f, 0x6f,
-	0x31, 0x4f, 0x61, 0x4d, 0x95, 0x76, 0x29, 0x74, 0xcd, 0x8d, 0x96, 0xba,
-	0xc4, 0xe0, 0xb9, 0x19, 0xfa, 0x2e, 0xaf, 0xb7, 0xa3, 0x57, 0xe1, 0x3f,
-	0xfe, 0x2a, 0xf8, 0xa6, 0x0c, 0x1e, 0x1b, 0xbd, 0x8a, 0xba, 0x48, 0x7e,
-	0x91, 0xe7, 0x94, 0x0c, 0x4f, 0x8a, 0xdc, 0x10, 0x29, 0xa3, 0x27, 0x45,
-	0x2d, 0xba, 0x1f, 0x0a, 0xdd, 0x64, 0x65, 0x4d, 0x03, 0x78, 0x04, 0x3e,
-	0x18, 0x19, 0x83, 0x75, 0xc2, 0xee, 0x7b, 0x6b, 0x20, 0x36, 0x41, 0xf1,
-	0x41, 0xf0, 0xbd, 0x94, 0x59, 0x55, 0x5f, 0x40, 0xe8, 0xfb, 0xd0, 0x3e,
-	0x9d, 0x2f, 0xa9, 0xcf, 0xf5, 0x5a, 0xa1, 0xcf, 0x7b, 0x5c, 0xdf, 0x87,
-	0x5c, 0xdf, 0xd7, 0xe3, 0xe5, 0x78, 0xcd, 0xe3, 0x75, 0x9e, 0x64, 0x8d,
-	0xa2, 0xcc, 0x82, 0xe4, 0xbf, 0xd0, 0xbe, 0xf1, 0xd0, 0x97, 0x15, 0x06,
-	0xcf, 0x2c, 0x8f, 0x45, 0xfa, 0x8c, 0x1e, 0x7f, 0x66, 0xea, 0xef, 0x6b,
-	0xf1, 0x34, 0x70, 0xd1, 0xdc, 0x4e, 0xa9, 0xe3, 0xd0, 0xaf, 0x6c, 0x14,
-	0xd0, 0xed, 0xe4, 0x72, 0x0f, 0xad, 0x88, 0x9a, 0x5c, 0xc0, 0x18, 0xb8,
-	0x1f, 0xcf, 0xc9, 0x86, 0x3a, 0x08, 0x35, 0xd7, 0x21, 0xe3, 0x07, 0x22,
-	0xd7, 0x79, 0x3e, 0x53, 0xcb, 0xff, 0x55, 0x3b, 0x2d, 0x6a, 0xdc, 0xa0,
-	0x2d, 0x63, 0x48, 0x81, 0xf9, 0x19, 0xbf, 0x34, 0xd9, 0x55, 0x33, 0xe8,
-	0x67, 0x16, 0x7b, 0x2b, 0x86, 0xfd, 0x22, 0xcb, 0x98, 0xdc, 0x2b, 0x4f,
-	0xb9, 0xf6, 0xca, 0x4f, 0x8a, 0xbd, 0x72, 0xec, 0x93, 0x83, 0xae, 0xa0,
-	0xa5, 0x57, 0x4c, 0x0b, 0xe6, 0x31, 0xca, 0xf3, 0x68, 0xd2, 0xc5, 0x6b,
-	0x42, 0xdf, 0x44, 0x93, 0x7e, 0x19, 0x5f, 0x9d, 0xa2, 0xac, 0x88, 0xbf,
-	0x96, 0x9f, 0x71, 0x23, 0x61, 0x5b, 0x93, 0xab, 0x8c, 0x29, 0x2a, 0xc5,
-	0x2d, 0x74, 0xb3, 0xdc, 0xc1, 0x98, 0xef, 0x6f, 0x69, 0xb5, 0x4c, 0x8c,
-	0x0d, 0xb7, 0x53, 0x3e, 0xca, 0xbc, 0x36, 0x19, 0xe4, 0x79, 0x65, 0x7c,
-	0x3b, 0xc9, 0xf2, 0xc7, 0x63, 0xa8, 0x94, 0x6a, 0xef, 0xe7, 0xa2, 0x71,
-	0x33, 0x31, 0xdd, 0xc3, 0xf6, 0x4b, 0x88, 0xff, 0x6d, 0xfe, 0xff, 0x6c,
-	0x04, 0xb4, 0x59, 0x5c, 0xc2, 0xf7, 0x8c, 0x7d, 0x0a, 0xb5, 0xf7, 0x67,
-	0xb9, 0xcd, 0xec, 0x34, 0xec, 0x20, 0xd8, 0x7b, 0x36, 0xff, 0xcb, 0x36,
-	0x15, 0xe6, 0xbb, 0xdc, 0xb5, 0x6c, 0xc4, 0x10, 0x3a, 0x1e, 0x75, 0x5d,
-	0xc6, 0xd4, 0x67, 0xdc, 0x98, 0xe5, 0xbe, 0xdc, 0x24, 0x3c, 0xc3, 0xa4,
-	0x4c, 0x74, 0x1f, 0xcb, 0xc1, 0x76, 0xfe, 0x44, 0x3e, 0xd6, 0x56, 0xca,
-	0x4f, 0x8d, 0xab, 0x7c, 0xac, 0x48, 0x9b, 0x7c, 0x2c, 0xdc, 0xc7, 0x38,
-	0x60, 0xbe, 0x76, 0x6f, 0x36, 0xea, 0x7c, 0x2f, 0x19, 0x99, 0xe8, 0x36,
-	0x81, 0x99, 0x2a, 0x4b, 0xfb, 0xb9, 0x0f, 0x71, 0x33, 0x33, 0xcd, 0x7d,
-	0x2d, 0x39, 0xfb, 0x5f, 0xbb, 0x97, 0x8c, 0xa2, 0x9d, 0xdf, 0xd5, 0x2e,
-	0x4e, 0xa2, 0xed, 0x12, 0xda, 0xd7, 0xfe, 0x27, 0x11, 0xd5, 0xe3, 0x74,
-	0xde, 0x8b, 0xf1, 0x40, 0xbe, 0xf8, 0xb3, 0x72, 0x9b, 0x6e, 0x16, 0x61,
-	0x8f, 0x1b, 0xcc, 0xf7, 0xe8, 0x91, 0x49, 0xd9, 0x0a, 0x63, 0xc0, 0x6b,
-	0x7b, 0x7d, 0xab, 0xc5, 0x37, 0x6a, 0x99, 0xa6, 0xd8, 0x96, 0x66, 0x3f,
-	0xbc, 0xb4, 0xc1, 0x86, 0xc9, 0xbe, 0x82, 0x35, 0x14, 0xeb, 0x67, 0xb6,
-	0xe6, 0xb7, 0x81, 0xf7, 0x60, 0x1b, 0x5d, 0x60, 0xfd, 0x25, 0xe3, 0x93,
-	0x58, 0x97, 0xb2, 0x0e, 0x93, 0xf2, 0x93, 0x6a, 0xfa, 0x39, 0x04, 0xc9,
-	0xc3, 0xa3, 0x8d, 0xb8, 0x48, 0xc7, 0xfe, 0x7a, 0xc0, 0xb1, 0xbf, 0x1e,
-	0x72, 0xc4, 0x45, 0x86, 0x05, 0x3e, 0x6b, 0x60, 0xaa, 0xb0, 0xc2, 0x54,
-	0xc0, 0x5e, 0x52, 0xb7, 0x2d, 0xd6, 0x75, 0xdb, 0x8e, 0x75, 0x74, 0x9b,
-	0x97, 0xad, 0xba, 0xa2, 0xf4, 0x88, 0x15, 0xc5, 0x1a, 0x73, 0x83, 0xf5,
-	0xc5, 0xeb, 0xd5, 0x69, 0xd6, 0x23, 0x51, 0xd6, 0x23, 0x53, 0xac, 0x47,
-	0x26, 0x59, 0x8f, 0xd8, 0x4c, 0x03, 0x93, 0xc7, 0xfe, 0x11, 0xeb, 0x69,
-	0xac, 0x1f, 0x33, 0xf4, 0x4c, 0x15, 0x3a, 0x79, 0x8a, 0x31, 0xd0, 0x47,
-	0xb4, 0x3a, 0xdf, 0xcb, 0xfc, 0x2b, 0x71, 0x4f, 0xb3, 0x5d, 0x83, 0xda,
-	0x2b, 0xf0, 0x17, 0xff, 0x39, 0xf4, 0xce, 0x2b, 0x59, 0x1a, 0xf1, 0xdd,
-	0x2c, 0x82, 0xce, 0xab, 0xa8, 0x55, 0xf1, 0x12, 0x64, 0x1b, 0x35, 0x82,
-	0x7f, 0x30, 0x31, 0xc3, 0x7d, 0x1f, 0xf1, 0xe5, 0x79, 0x5e, 0xbe, 0x1d,
-	0xcd, 0x86, 0xfa, 0x59, 0x06, 0x8e, 0x2b, 0x19, 0x38, 0xde, 0x90, 0x81,
-	0x6c, 0x8e, 0x47, 0xd2, 0xb7, 0xb0, 0x9d, 0xc6, 0x0f, 0x26, 0x76, 0xf5,
-	0xb1, 0xfc, 0x22, 0x66, 0xa2, 0x51, 0xbf, 0xc7, 0x4f, 0xa7, 0xc3, 0x41,
-	0x55, 0xf7, 0xc7, 0x14, 0x39, 0xef, 0xf9, 0xe2, 0xbb, 0x8c, 0x4b, 0x58,
-	0x4e, 0x43, 0x38, 0xbf, 0x0c, 0xbf, 0x28, 0xdb, 0x0d, 0xdd, 0xc2, 0xaf,
-	0xb4, 0x28, 0xda, 0xe2, 0xdc, 0x9a, 0x64, 0x1d, 0x17, 0x5d, 0x31, 0xac,
-	0x99, 0xb8, 0xf1, 0x9b, 0xc3, 0xa8, 0xe1, 0xfe, 0x83, 0xea, 0xe7, 0x86,
-	0xe5, 0xde, 0x5c, 0x72, 0x97, 0xd4, 0x27, 0xcc, 0xa3, 0xe1, 0xb8, 0xb0,
-	0xdd, 0x3a, 0xae, 0xc8, 0xf5, 0x73, 0x91, 0xe7, 0xbb, 0x12, 0x9d, 0xe4,
-	0xf9, 0xee, 0x51, 0x6b, 0x67, 0x96, 0xbf, 0x17, 0xeb, 0x32, 0xaf, 0xa1,
-	0xc3, 0xa8, 0x7f, 0x1f, 0x12, 0x75, 0x22, 0x4e, 0xa2, 0x0e, 0x4f, 0x02,
-	0xcf, 0x63, 0xee, 0x85, 0xfe, 0xf8, 0x07, 0x5e, 0xa3, 0xf1, 0x5e, 0xf0,
-	0x23, 0x1f, 0x97, 0x67, 0xe8, 0x52, 0x41, 0xf7, 0xe1, 0x3d, 0x32, 0xbe,
-	0x8b, 0x7e, 0xf8, 0x68, 0x87, 0xfd, 0x9e, 0xc8, 0x05, 0x31, 0xfe, 0xc4,
-	0xdd, 0xa7, 0xa3, 0xaa, 0x4f, 0xa8, 0x75, 0xd9, 0x85, 0xda, 0x3e, 0x84,
-	0x9a, 0x48, 0x8b, 0xa2, 0x16, 0x65, 0xa7, 0xb0, 0x59, 0x17, 0x85, 0xed,
-	0xb1, 0x7f, 0x57, 0xa3, 0x3e, 0xe6, 0x7e, 0xd7, 0xb5, 0x3b, 0xbc, 0x6e,
-	0x1d, 0x12, 0x18, 0x6d, 0x14, 0xf5, 0xda, 0x45, 0x5e, 0xea, 0x8c, 0xf8,
-	0xce, 0x58, 0xc0, 0x77, 0x0f, 0xa9, 0xef, 0x3e, 0x2f, 0xb0, 0xb1, 0x11,
-	0xeb, 0x66, 0xbd, 0x28, 0xf8, 0x9d, 0xe7, 0xd9, 0x9e, 0x64, 0x7e, 0x8f,
-	0x54, 0xf8, 0xb9, 0xa7, 0x05, 0x3d, 0x35, 0x3d, 0x40, 0x0b, 0xc8, 0x40,
-	0x8f, 0xe2, 0x7f, 0xcb, 0x4c, 0xf9, 0xf5, 0xb8, 0xdb, 0xd1, 0x99, 0xb1,
-	0x4e, 0x01, 0x63, 0xc5, 0x98, 0x4c, 0x5f, 0xbc, 0x1c, 0xf1, 0xe5, 0xe6,
-	0x61, 0xeb, 0x20, 0xdf, 0x65, 0x0f, 0xe2, 0xa9, 0xb8, 0x0f, 0x3b, 0x29,
-	0x9e, 0x46, 0xbf, 0xd0, 0x4e, 0xd3, 0xc0, 0x76, 0xd1, 0xc2, 0x79, 0xdf,
-	0x76, 0x75, 0x5f, 0xb7, 0x98, 0x0b, 0x32, 0xf0, 0x1e, 0xfd, 0x6e, 0xbc,
-	0x17, 0xef, 0xc7, 0x7d, 0x78, 0x9e, 0x7c, 0xee, 0x00, 0xeb, 0xed, 0xc4,
-	0xb4, 0x7c, 0x96, 0x71, 0x5d, 0x7e, 0x37, 0x60, 0x7b, 0xf7, 0x57, 0xce,
-	0x9f, 0x4f, 0xd5, 0xf1, 0xc1, 0xfc, 0x6d, 0xa7, 0xb2, 0xf0, 0x7d, 0xe2,
-	0xbb, 0x11, 0x9f, 0xb0, 0x6b, 0x6d, 0xfe, 0xe4, 0x79, 0x9d, 0xe3, 0xf3,
-	0x33, 0xc5, 0xdb, 0xc2, 0x66, 0xcf, 0xa5, 0x47, 0x7c, 0xe5, 0x32, 0xc6,
-	0x3b, 0xe2, 0x4b, 0xb1, 0x0c, 0x24, 0x8b, 0x89, 0x5a, 0x5e, 0xe2, 0x02,
-	0x3a, 0xdd, 0x6f, 0x85, 0x4e, 0x1b, 0xef, 0x0f, 0xcb, 0x9a, 0xb7, 0x38,
-	0x66, 0x39, 0x2c, 0xb0, 0x1c, 0x16, 0x58, 0x0e, 0x0b, 0x2c, 0x87, 0x6c,
-	0xab, 0xbe, 0x56, 0x60, 0x39, 0xe4, 0xb5, 0xe4, 0x55, 0x5e, 0x4b, 0xa4,
-	0xec, 0xc6, 0x95, 0x7f, 0x53, 0xcb, 0xae, 0x3b, 0x6f, 0x53, 0xcb, 0x2a,
-	0xd6, 0x6f, 0xf2, 0x1d, 0x99, 0x68, 0x96, 0xd9, 0x5b, 0x2c, 0xb3, 0x1d,
-	0xb1, 0x41, 0xba, 0x5b, 0xc2, 0x9c, 0x59, 0xe6, 0x1c, 0xeb, 0xea, 0x94,
-	0x1f, 0x58, 0x2b, 0xc0, 0xf2, 0x04, 0xac, 0x69, 0x31, 0xdd, 0x07, 0xe9,
-	0x1e, 0xeb, 0xeb, 0xbb, 0x25, 0xc8, 0xf0, 0x1e, 0x75, 0x6e, 0xb1, 0x0c,
-	0x63, 0xfd, 0xb3, 0x7d, 0xb7, 0x8a, 0x06, 0x63, 0xb2, 0x40, 0x28, 0x43,
-	0xd0, 0xa7, 0x02, 0xa7, 0xf1, 0xbc, 0xaf, 0xb0, 0xde, 0x87, 0x0f, 0x0f,
-	0xeb, 0xc5, 0x19, 0x1f, 0xaf, 0x17, 0x91, 0x9b, 0xac, 0x4f, 0xcf, 0x97,
-	0x6c, 0x96, 0xfb, 0x7e, 0xfa, 0x56, 0x09, 0xeb, 0x34, 0x68, 0xc4, 0xe7,
-	0x65, 0x12, 0xbe, 0x31, 0x23, 0x86, 0xb1, 0x8f, 0x67, 0x0d, 0xc1, 0x27,
-	0x7f, 0x0a, 0x3a, 0x30, 0xed, 0x5f, 0xdc, 0x85, 0xda, 0xf3, 0x71, 0xa3,
-	0x53, 0xf9, 0x1a, 0x71, 0x8c, 0xf6, 0x68, 0x0b, 0xba, 0xe1, 0xbc, 0xdd,
-	0xbe, 0x24, 0x7e, 0xb3, 0x21, 0x0a, 0xff, 0x9b, 0x4b, 0x7f, 0x5d, 0xe2,
-	0xfb, 0x05, 0xbd, 0x66, 0x12, 0x7e, 0xe4, 0x90, 0xd3, 0xd3, 0xfe, 0xd8,
-	0x0c, 0x3d, 0x5b, 0x45, 0xbf, 0xaf, 0x52, 0x3e, 0x0c, 0x7d, 0x64, 0x45,
-	0xef, 0x90, 0xa4, 0x5d, 0x37, 0xe3, 0xce, 0x27, 0xbc, 0x75, 0x9c, 0x99,
-	0x10, 0x38, 0xb9, 0x8b, 0xf5, 0x0b, 0x68, 0xf3, 0x13, 0xe6, 0x35, 0x7e,
-	0x5f, 0x41, 0xeb, 0xb7, 0x1f, 0xb3, 0xce, 0xc1, 0x9c, 0xe1, 0x7c, 0x6d,
-	0x9d, 0xb6, 0xaa, 0x74, 0x9a, 0xed, 0xd0, 0x69, 0xb9, 0xba, 0x4e, 0x63,
-	0xde, 0x10, 0xba, 0x0c, 0xba, 0xea, 0x51, 0xc6, 0x91, 0xf2, 0x18, 0xf8,
-	0x70, 0x87, 0xd0, 0x5d, 0xac, 0xfb, 0xd9, 0xae, 0x58, 0xac, 0x66, 0x7d,
-	0x87, 0x85, 0x0e, 0xd1, 0xfc, 0xbd, 0x7f, 0xb7, 0x94, 0x8b, 0x6e, 0xa1,
-	0x0f, 0x72, 0x27, 0xa1, 0xb7, 0xbc, 0xda, 0x8f, 0x73, 0x3b, 0xb4, 0xb7,
-	0x23, 0x2f, 0xb1, 0x3e, 0x5b, 0x8c, 0xc2, 0xa6, 0xed, 0x51, 0xb6, 0x0f,
-	0xea, 0x72, 0x61, 0xaf, 0x0b, 0x63, 0xd5, 0xfa, 0x6c, 0x40, 0xf9, 0x35,
-	0xe0, 0x87, 0xc4, 0x9c, 0xb7, 0xc5, 0x08, 0x26, 0x30, 0x02, 0xdf, 0x13,
-	0x60, 0x7a, 0x89, 0x1a, 0xe2, 0x44, 0xef, 0xd2, 0xaa, 0x90, 0x8d, 0x77,
-	0x05, 0x76, 0xc9, 0xf3, 0x77, 0xb3, 0xd3, 0x07, 0x45, 0x3f, 0xf3, 0x4b,
-	0x0d, 0xfd, 0x38, 0x57, 0x78, 0x0f, 0xeb, 0x86, 0xe8, 0x6b, 0x65, 0x42,
-	0xea, 0xc0, 0xc5, 0x32, 0x6a, 0x80, 0x89, 0x3e, 0x73, 0x5f, 0xf5, 0x38,
-	0xd1, 0x0f, 0xad, 0x0f, 0x36, 0x22, 0x7b, 0x8c, 0x6b, 0xfb, 0x31, 0x47,
-	0x59, 0x07, 0x0f, 0x3d, 0xcb, 0xef, 0xc7, 0xb5, 0xf5, 0xc7, 0x73, 0xaf,
-	0x3e, 0x1e, 0xf8, 0xf6, 0x70, 0xcf, 0xbb, 0x74, 0x57, 0x8d, 0xe7, 0x6e,
-	0x7d, 0x3c, 0xcf, 0xa8, 0xf1, 0x50, 0xce, 0x88, 0x0d, 0x28, 0xdc, 0xbf,
-	0xe1, 0x67, 0x77, 0x27, 0x18, 0xc7, 0xe4, 0x96, 0x40, 0xe7, 0xfd, 0x8a,
-	0x9f, 0x9c, 0x7e, 0x54, 0x67, 0x5f, 0xad, 0xc9, 0x3b, 0xac, 0x7f, 0xef,
-	0x09, 0x1c, 0x33, 0xc2, 0x38, 0x06, 0xd7, 0x29, 0x0f, 0x3d, 0x9d, 0x0b,
-	0xa3, 0x4e, 0xed, 0x0c, 0x8f, 0x9b, 0xed, 0xb1, 0x69, 0xfe, 0x14, 0xfe,
-	0x35, 0x3c, 0x47, 0xdf, 0xff, 0x3c, 0xdd, 0x9b, 0x87, 0x2e, 0x07, 0x8e,
-	0x95, 0xb5, 0x6c, 0xef, 0x2d, 0x4b, 0xff, 0x6e, 0xca, 0xd3, 0xbf, 0x0b,
-	0xdf, 0xee, 0x34, 0x70, 0x7e, 0x08, 0x7e, 0xe0, 0xa4, 0xfa, 0xad, 0x8f,
-	0x5c, 0x15, 0xcf, 0xf2, 0xd2, 0x4b, 0x33, 0x8e, 0xd8, 0x38, 0xc4, 0xaa,
-	0x64, 0x59, 0xcf, 0xd8, 0xa1, 0x0e, 0x43, 0xe6, 0xdc, 0xdc, 0xa8, 0x6a,
-	0xec, 0x74, 0x94, 0xe7, 0xcc, 0x8e, 0x1a, 0x46, 0x4a, 0xf8, 0x1a, 0xba,
-	0xed, 0x1e, 0xea, 0xe2, 0x75, 0xf4, 0x2c, 0xa1, 0x96, 0x9a, 0x65, 0x62,
-	0x0f, 0xe0, 0x12, 0xf3, 0x64, 0x3e, 0x6a, 0x45, 0x1e, 0x17, 0x76, 0x29,
-	0xd6, 0x17, 0x03, 0x74, 0x62, 0x5a, 0xa3, 0x0f, 0x7c, 0xbc, 0x84, 0x3a,
-	0x9a, 0x51, 0x1e, 0x3f, 0xfc, 0xc7, 0x63, 0xe6, 0x9b, 0xbc, 0x2e, 0x5d,
-	0x12, 0x7e, 0x99, 0x0b, 0x94, 0x63, 0x39, 0x3d, 0x22, 0xe4, 0xd4, 0x18,
-	0x61, 0x29, 0x62, 0xb9, 0x42, 0x6c, 0xc2, 0xb8, 0xa8, 0xdb, 0x23, 0x6d,
-	0x1d, 0x1e, 0xe5, 0xb2, 0xaa, 0x87, 0x90, 0x86, 0xee, 0xd8, 0xb8, 0x4f,
-	0x22, 0xfd, 0x89, 0x7d, 0x31, 0x4e, 0x4c, 0xe6, 0xf6, 0x7d, 0xc3, 0xae,
-	0x33, 0x45, 0xbd, 0x48, 0xd0, 0x4e, 0xf8, 0x13, 0x8d, 0x29, 0xa6, 0x9b,
-	0xfe, 0xdd, 0x19, 0xa7, 0xdf, 0xe0, 0x9c, 0xc8, 0xeb, 0x7f, 0xa5, 0x2a,
-	0xd7, 0xe0, 0x1c, 0xdb, 0xf4, 0xf9, 0x83, 0x4e, 0x4c, 0x62, 0x15, 0x93,
-	0xc2, 0x97, 0xb3, 0x9b, 0x12, 0x0b, 0x53, 0xf4, 0x68, 0x01, 0x3a, 0x8c,
-	0xee, 0x24, 0x6c, 0xfc, 0xa2, 0x0c, 0x64, 0x7c, 0x8a, 0x52, 0x55, 0xd0,
-	0xc8, 0xc7, 0x58, 0x89, 0x79, 0xaf, 0x88, 0x3d, 0x7f, 0x3e, 0x2e, 0xe3,
-	0x77, 0x54, 0x7e, 0x5d, 0xf9, 0xcb, 0x87, 0x29, 0xb9, 0x40, 0xd9, 0x4c,
-	0xf4, 0x4b, 0xa2, 0xd6, 0x75, 0x26, 0x3a, 0xa1, 0x7c, 0x3b, 0x11, 0xbe,
-	0x0e, 0x7f, 0x99, 0x49, 0x5f, 0x2e, 0x58, 0xd9, 0x0c, 0x49, 0x9f, 0x05,
-	0x71, 0x1f, 0x0c, 0x5e, 0x7b, 0x77, 0xb0, 0x0e, 0x39, 0x21, 0xfc, 0x16,
-	0x8c, 0x54, 0xe6, 0xd1, 0x1e, 0x3e, 0x87, 0x7e, 0x82, 0x9d, 0x96, 0x29,
-	0x3e, 0xa5, 0xda, 0xd6, 0x28, 0xc4, 0xbc, 0x10, 0xfa, 0x55, 0x3b, 0x1b,
-	0x35, 0x1a, 0xf7, 0xc3, 0xe7, 0x71, 0x42, 0xe0, 0xc8, 0x11, 0xb6, 0x79,
-	0x44, 0xbb, 0xda, 0xac, 0xf0, 0x5f, 0xf0, 0x79, 0xf9, 0x81, 0x21, 0xfd,
-	0x9b, 0x08, 0xb8, 0x2e, 0xfd, 0x1a, 0xfc, 0xcc, 0x32, 0xf7, 0xa3, 0x29,
-	0x9e, 0x7e, 0x98, 0xe2, 0x9b, 0xf0, 0x33, 0x9d, 0xbc, 0xaf, 0x7e, 0x26,
-	0xa6, 0x35, 0xaf, 0x3d, 0x37, 0x58, 0x36, 0x5e, 0x5f, 0xd7, 0xfe, 0xfb,
-	0x50, 0xaf, 0xe1, 0x4c, 0xab, 0x90, 0xf8, 0xdd, 0x0c, 0x60, 0xf0, 0x7c,
-	0xf5, 0x71, 0xfc, 0x5e, 0x8c, 0x2f, 0x2d, 0xb0, 0x71, 0x84, 0xb1, 0x0d,
-	0x30, 0xce, 0x98, 0xd8, 0x17, 0x8b, 0x3f, 0x16, 0xf1, 0xe5, 0x97, 0x07,
-	0xc9, 0x0f, 0x7f, 0x9c, 0xad, 0x63, 0x29, 0xba, 0x45, 0xdc, 0xbb, 0xdc,
-	0x8f, 0xc4, 0xfa, 0x0c, 0x9d, 0x78, 0x87, 0xed, 0x86, 0x09, 0x15, 0x87,
-	0xd3, 0x21, 0x6a, 0x53, 0xc9, 0xbd, 0x54, 0xad, 0x53, 0x34, 0xef, 0xe9,
-	0xbd, 0x0e, 0xe7, 0x6f, 0x73, 0x41, 0x76, 0x9d, 0x98, 0x02, 0xfe, 0x29,
-	0x31, 0x47, 0x97, 0x88, 0xe4, 0x1c, 0x37, 0xf6, 0x31, 0xba, 0x78, 0x9e,
-	0x60, 0x0f, 0xc2, 0xef, 0xf7, 0x35, 0xfe, 0xc4, 0x7e, 0xc4, 0xd5, 0x21,
-	0xe0, 0xa8, 0x3e, 0x9b, 0x79, 0x66, 0x1a, 0xe7, 0x83, 0x6c, 0x9f, 0x69,
-	0xdc, 0x2b, 0x7d, 0x51, 0x6c, 0xb3, 0xa9, 0xf9, 0x82, 0x1f, 0x6a, 0x54,
-	0xd5, 0x29, 0xb0, 0xc8, 0xec, 0x07, 0x9d, 0x3e, 0x2d, 0x79, 0x5c, 0x6f,
-	0xef, 0x62, 0x23, 0xb1, 0x4e, 0xf8, 0xdd, 0x30, 0xd4, 0xeb, 0xdc, 0x0b,
-	0xda, 0xf3, 0x1c, 0x39, 0xf7, 0x36, 0x1e, 0xdf, 0xa5, 0x7f, 0xb3, 0xe8,
-	0xfe, 0xcc, 0xdb, 0x16, 0x8f, 0x79, 0xfb, 0xf9, 0x90, 0xdc, 0x3b, 0x7b,
-	0x58, 0xb5, 0xf1, 0x8a, 0x6f, 0x5d, 0xfe, 0x0e, 0xfc, 0x50, 0x8d, 0xfc,
-	0x8b, 0x77, 0x84, 0x5e, 0x69, 0xf5, 0x85, 0x47, 0x58, 0x9f, 0x4a, 0x39,
-	0x3e, 0xe1, 0x21, 0xc7, 0xfd, 0x31, 0xe0, 0x96, 0x8f, 0x2f, 0xc7, 0xc7,
-	0xdb, 0xca, 0xf1, 0x9e, 0x61, 0xe9, 0x8b, 0x6d, 0x95, 0x63, 0xe4, 0x00,
-	0x9d, 0xa8, 0xb6, 0xf3, 0x7b, 0x61, 0x1e, 0x90, 0xcb, 0xee, 0xf4, 0x95,
-	0x80, 0x66, 0xda, 0x5f, 0x82, 0x7d, 0x43, 0xf0, 0x25, 0xf6, 0x5e, 0x4e,
-	0x1a, 0xa9, 0x79, 0xf7, 0x5e, 0xea, 0x46, 0xee, 0xbd, 0xed, 0x71, 0x2f,
-	0xb0, 0x3b, 0x64, 0xc3, 0x8a, 0x48, 0x5f, 0x80, 0xa6, 0xdf, 0xb0, 0xef,
-	0x70, 0xc9, 0xca, 0x96, 0x09, 0xbe, 0xee, 0x30, 0x9d, 0xc3, 0xfe, 0xb4,
-	0xf2, 0x25, 0x1f, 0x2b, 0x48, 0x3a, 0x84, 0x0e, 0x0a, 0xfe, 0x00, 0xbe,
-	0x8d, 0xa4, 0xfd, 0x69, 0x9e, 0x63, 0xe9, 0x47, 0xce, 0x2c, 0x45, 0xd4,
-	0xbc, 0x71, 0x5b, 0x3c, 0xcf, 0x33, 0x5f, 0x10, 0xf3, 0x65, 0x3d, 0xbf,
-	0x52, 0x8f, 0x4f, 0xc6, 0xda, 0x50, 0xa3, 0xff, 0xe0, 0x75, 0xcf, 0x7f,
-	0x30, 0x24, 0x6a, 0x37, 0xdc, 0xa8, 0x1e, 0x64, 0xbc, 0x89, 0x39, 0x85,
-	0x0f, 0x52, 0xfb, 0x88, 0x1f, 0xda, 0x4b, 0xbd, 0x07, 0x18, 0x05, 0x18,
-	0x64, 0x33, 0xbe, 0x34, 0x0e, 0x22, 0xce, 0xdc, 0xe4, 0x7b, 0x50, 0x73,
-	0x6a, 0xdc, 0x4c, 0x51, 0x0f, 0xfc, 0x10, 0xa8, 0x25, 0x6d, 0xe6, 0x9a,
-	0x64, 0xec, 0x94, 0x90, 0xb1, 0xd4, 0xf2, 0x29, 0x25, 0x63, 0xa7, 0x94,
-	0x1f, 0xfe, 0x94, 0x92, 0xb1, 0x53, 0x4a, 0xc6, 0x4e, 0x29, 0x19, 0x3b,
-	0xc5, 0x7c, 0x3e, 0xc6, 0xf8, 0x16, 0x58, 0x44, 0xfb, 0x41, 0x7b, 0x29,
-	0x53, 0xc2, 0x75, 0xac, 0xcf, 0x6e, 0x39, 0x7b, 0x69, 0x44, 0xca, 0x19,
-	0x63, 0x13, 0x19, 0xaf, 0xc7, 0xef, 0xc2, 0x1c, 0xfc, 0x1e, 0xd3, 0xef,
-	0x23, 0x3a, 0x33, 0x8f, 0xbe, 0xfa, 0x28, 0x29, 0x6a, 0xc9, 0x76, 0x50,
-	0xc2, 0x89, 0x85, 0x43, 0xc8, 0x0f, 0x93, 0xb6, 0x5f, 0xb6, 0x6d, 0xae,
-	0x98, 0xe6, 0x93, 0x98, 0x9a, 0x2f, 0xb7, 0x5d, 0xd4, 0x45, 0xe9, 0x22,
-	0xe8, 0x8a, 0x98, 0x4a, 0x93, 0xe7, 0x46, 0xd0, 0x49, 0x86, 0x44, 0xb9,
-	0x68, 0x70, 0x4c, 0xd1, 0xe0, 0xdb, 0x62, 0x8c, 0x88, 0x49, 0x84, 0x2f,
-	0xb3, 0x3d, 0x1d, 0x72, 0x85, 0x31, 0x7e, 0x0e, 0xcb, 0xc2, 0xc1, 0x08,
-	0xeb, 0xa4, 0x8d, 0xd3, 0xa1, 0x31, 0xf6, 0x76, 0xba, 0x67, 0xa3, 0x79,
-	0x39, 0x77, 0x1c, 0x6b, 0x49, 0x44, 0xad, 0x23, 0x12, 0x17, 0x6f, 0xb1,
-	0x6b, 0x74, 0x34, 0xba, 0x97, 0x8f, 0xad, 0x74, 0x96, 0x0e, 0x90, 0xd1,
-	0x57, 0xa3, 0xbf, 0x60, 0x39, 0xe8, 0x66, 0x39, 0x38, 0xaa, 0xec, 0x92,
-	0xa3, 0x75, 0xbb, 0x64, 0xcf, 0x1e, 0xc4, 0x65, 0x64, 0xc4, 0xbe, 0xd7,
-	0x56, 0x55, 0x43, 0x00, 0xbe, 0x6f, 0x9c, 0x77, 0x51, 0x7c, 0x18, 0xe7,
-	0xf8, 0x2d, 0x22, 0x6b, 0x32, 0xee, 0x1b, 0xdf, 0x23, 0xb0, 0xbb, 0xcf,
-	0xc2, 0x3d, 0x47, 0xa5, 0xde, 0xf3, 0x91, 0x7f, 0xfc, 0x36, 0xe3, 0x89,
-	0x1a, 0x3d, 0xc1, 0xef, 0xcc, 0x17, 0xf7, 0xf1, 0xb3, 0x75, 0x4d, 0x09,
-	0x3b, 0x6e, 0xf8, 0xb6, 0x92, 0xbf, 0xaf, 0xdd, 0xbb, 0x2d, 0xc1, 0x8f,
-	0x8c, 0xa7, 0x8d, 0xd9, 0xe8, 0x7b, 0xb5, 0xd3, 0x27, 0xe1, 0x63, 0x87,
-	0x9c, 0x58, 0x21, 0xd3, 0xe7, 0x25, 0x1f, 0x12, 0x2b, 0x35, 0xe2, 0x63,
-	0x21, 0x2f, 0x35, 0xfa, 0x77, 0x1e, 0x5b, 0x88, 0xb0, 0x77, 0x22, 0x9f,
-	0x9f, 0xa6, 0x19, 0x91, 0x83, 0x8d, 0x38, 0xe9, 0x33, 0xf3, 0xfa, 0x5d,
-	0xb6, 0xe2, 0x8d, 0xcf, 0x20, 0xce, 0xad, 0xb8, 0x48, 0x6b, 0xaf, 0x39,
-	0xf0, 0xd7, 0x8d, 0x2d, 0xac, 0xf6, 0x85, 0x45, 0x4e, 0xf8, 0x76, 0xc6,
-	0x48, 0x3a, 0x1e, 0x7a, 0x9c, 0x9f, 0x0f, 0x3f, 0x5e, 0x80, 0x92, 0x57,
-	0xd0, 0xae, 0x93, 0x46, 0x17, 0x6a, 0x5f, 0xe0, 0xef, 0xc5, 0xfe, 0x65,
-	0x86, 0xba, 0xd5, 0xde, 0x44, 0x8f, 0xda, 0xcf, 0x8a, 0xb0, 0xec, 0x35,
-	0x72, 0x9d, 0x47, 0xeb, 0x3e, 0x3d, 0xc8, 0x84, 0xdb, 0xa7, 0xf7, 0xf4,
-	0x3a, 0xeb, 0xd5, 0x7a, 0x72, 0x80, 0x58, 0xd6, 0x2e, 0x52, 0xbe, 0x4a,
-	0x33, 0x4f, 0x1b, 0xcd, 0xe9, 0xdb, 0xf4, 0x3d, 0xdd, 0x9d, 0x31, 0xf3,
-	0xc2, 0x9b, 0x76, 0x50, 0xf1, 0x5f, 0x27, 0x9d, 0x29, 0x05, 0x79, 0xcd,
-	0x87, 0x6e, 0x05, 0xbd, 0xfc, 0xc3, 0xc8, 0x73, 0xf9, 0x7a, 0xa0, 0x93,
-	0x96, 0x96, 0x10, 0x6b, 0xf1, 0x47, 0x7b, 0x64, 0x7c, 0x71, 0x9a, 0xe9,
-	0x72, 0x80, 0xd7, 0x47, 0x43, 0xed, 0x1d, 0xe1, 0x1a, 0x74, 0x89, 0xa8,
-	0x37, 0x1a, 0xf8, 0xd2, 0x44, 0x90, 0xed, 0x02, 0xb9, 0xf7, 0x70, 0x88,
-	0x9f, 0xfd, 0xfd, 0x52, 0x1a, 0xfe, 0xb2, 0xd0, 0x11, 0x7e, 0x7e, 0x92,
-	0xf1, 0x44, 0x9c, 0x3a, 0xa9, 0xb2, 0xd4, 0xc9, 0x76, 0x41, 0x27, 0xe3,
-	0x89, 0xb1, 0xd0, 0xa8, 0x4f, 0xbc, 0x4b, 0xe4, 0xd4, 0x3c, 0x1c, 0x38,
-	0xc0, 0x7c, 0x85, 0x77, 0xbd, 0xae, 0xde, 0xe5, 0x7e, 0xc7, 0x2f, 0x6a,
-	0x38, 0x3f, 0xe2, 0x37, 0x2f, 0xdc, 0xc2, 0xef, 0x51, 0xcd, 0xcf, 0x30,
-	0x76, 0x0e, 0x53, 0x7e, 0xbe, 0x83, 0xc7, 0x10, 0x63, 0x3b, 0x22, 0xca,
-	0xe7, 0x8f, 0x50, 0xb6, 0x7a, 0x92, 0x7e, 0xbf, 0xea, 0xf4, 0x09, 0x3f,
-	0xc2, 0x7d, 0x96, 0x39, 0xfd, 0x5d, 0xdc, 0xaf, 0x0f, 0x6d, 0xb7, 0x8e,
-	0x09, 0x92, 0xff, 0x7b, 0x61, 0xea, 0x7c, 0x0e, 0xbe, 0x97, 0x1a, 0x15,
-	0xa3, 0xd6, 0xa5, 0x3b, 0x24, 0xfd, 0xcf, 0x2f, 0x88, 0xb8, 0x5a, 0xbe,
-	0x9f, 0x9f, 0x39, 0x87, 0x76, 0x2f, 0x98, 0x74, 0xd3, 0x96, 0xf4, 0x7e,
-	0x23, 0x10, 0x26, 0xff, 0xcb, 0x88, 0x7d, 0x02, 0x56, 0x33, 0x2f, 0xd8,
-	0xfb, 0x58, 0xbf, 0x3f, 0x87, 0xfb, 0xf8, 0xf3, 0x65, 0x9c, 0x07, 0x79,
-	0x9c, 0x58, 0xaf, 0x11, 0xef, 0x02, 0xbd, 0x78, 0x20, 0x12, 0x12, 0xfc,
-	0xf7, 0x08, 0xf3, 0x54, 0x87, 0xf0, 0x35, 0xf6, 0xa3, 0xad, 0x3d, 0xc4,
-	0xd8, 0xc2, 0xbc, 0x30, 0xb1, 0x0f, 0xe7, 0xf1, 0x3e, 0x3f, 0xd3, 0x48,
-	0xf2, 0x10, 0xc6, 0xd3, 0xc4, 0xdc, 0x81, 0x43, 0x13, 0xc4, 0xf3, 0x09,
-	0xfc, 0xc1, 0xf3, 0x19, 0x42, 0x7d, 0xa7, 0x20, 0xa5, 0xf8, 0x1d, 0xc9,
-	0x92, 0x1c, 0xf7, 0x5c, 0xd5, 0x4f, 0xd2, 0x4f, 0x75, 0x74, 0x44, 0xff,
-	0x9e, 0x21, 0x0d, 0xe2, 0xd9, 0x5a, 0x56, 0x70, 0xdc, 0x4b, 0x77, 0x4b,
-	0x3d, 0x74, 0x4f, 0xed, 0x69, 0xdd, 0x15, 0x76, 0x19, 0xeb, 0xf0, 0x74,
-	0x2f, 0xdd, 0x59, 0xea, 0x20, 0xea, 0x0f, 0x8a, 0x3d, 0xe7, 0xbb, 0xa5,
-	0x32, 0xbf, 0x3f, 0x31, 0x22, 0xfd, 0x3a, 0x0d, 0x1e, 0xb9, 0xeb, 0xc1,
-	0x23, 0x1f, 0x08, 0x1e, 0xd9, 0x37, 0xb2, 0x36, 0x8f, 0xec, 0x52, 0xb6,
-	0x48, 0x90, 0x3a, 0x15, 0x7f, 0xbc, 0xc4, 0xfc, 0xf1, 0x2c, 0xf3, 0xc7,
-	0xe1, 0x36, 0xfc, 0x61, 0xb8, 0xf8, 0xe3, 0x88, 0xe0, 0x8f, 0x87, 0x46,
-	0xd6, 0xe2, 0x8f, 0xc3, 0xfe, 0xb5, 0x7c, 0x4d, 0xe2, 0xb7, 0x3c, 0x2f,
-	0xcc, 0xd9, 0xbb, 0x99, 0xd7, 0x6d, 0xaa, 0xcc, 0x23, 0x67, 0x61, 0x25,
-	0x6a, 0xd0, 0xbf, 0x08, 0x9b, 0x6c, 0x55, 0xd8, 0xfc, 0x31, 0x11, 0xc3,
-	0xba, 0x28, 0xf8, 0x8b, 0xd7, 0xff, 0x18, 0x72, 0xaa, 0xdc, 0x73, 0xd1,
-	0x4d, 0x37, 0xa3, 0x98, 0x0b, 0x53, 0xcd, 0x05, 0xae, 0x75, 0xe9, 0xfa,
-	0x90, 0x01, 0xbe, 0x7e, 0xe1, 0x03, 0xf0, 0xe8, 0x72, 0x4f, 0x20, 0x59,
-	0xf8, 0xe6, 0x08, 0xf0, 0x5f, 0x7e, 0x99, 0x1c, 0xd7, 0x03, 0x7c, 0x3d,
-	0x2c, 0x7e, 0xfb, 0x09, 0xb2, 0xf2, 0x8f, 0x88, 0x71, 0x64, 0x9e, 0xbc,
-	0x59, 0x1a, 0xa6, 0x5b, 0xa5, 0xdd, 0xb4, 0x5a, 0x1a, 0xa1, 0x37, 0x45,
-	0x2d, 0x0d, 0x99, 0x1b, 0xb9, 0x2a, 0xe6, 0xc8, 0xa0, 0x43, 0x61, 0x6e,
-	0xb3, 0xb4, 0x9b, 0x56, 0x96, 0x34, 0x7f, 0x83, 0xb7, 0xc1, 0x2f, 0xf1,
-	0x3e, 0x99, 0x2f, 0xd7, 0xca, 0x33, 0xc9, 0x26, 0x9e, 0x91, 0xf7, 0x80,
-	0x57, 0xf2, 0xad, 0xb9, 0xbe, 0xdd, 0xa1, 0x18, 0x62, 0xf5, 0x82, 0xd4,
-	0x81, 0xb8, 0x45, 0xc3, 0x9a, 0x3c, 0xe4, 0x07, 0x86, 0xfe, 0x2a, 0xaf,
-	0xb9, 0x3c, 0x67, 0x36, 0xe2, 0x9c, 0x46, 0x18, 0x0f, 0x6f, 0x17, 0xf8,
-	0x37, 0x61, 0x07, 0x22, 0x49, 0xaa, 0x5d, 0x30, 0x6c, 0xd4, 0x73, 0x4c,
-	0xf3, 0xf3, 0x0c, 0xe5, 0x6f, 0xda, 0xe6, 0xe0, 0x3f, 0x37, 0xd6, 0xc5,
-	0x5e, 0xf2, 0x63, 0xdc, 0x67, 0xac, 0xc3, 0x8d, 0xfd, 0x1a, 0xaa, 0xef,
-	0xd7, 0x74, 0xf3, 0xb8, 0xa5, 0xec, 0xcd, 0xda, 0xdc, 0xae, 0xca, 0xed,
-	0xaa, 0xd8, 0xfb, 0xe3, 0xeb, 0x4b, 0xd8, 0x77, 0x1e, 0xa6, 0xd5, 0x79,
-	0xc8, 0x28, 0xfc, 0x21, 0x8d, 0xbd, 0xde, 0xd5, 0x65, 0x5c, 0x87, 0x4f,
-	0xa4, 0xb1, 0xd7, 0xbb, 0xaa, 0xf6, 0x7a, 0x57, 0x97, 0x63, 0x42, 0x6f,
-	0xe7, 0x4b, 0x4c, 0xf7, 0x92, 0x5f, 0xc5, 0x39, 0xee, 0x53, 0xbf, 0x2d,
-	0xf4, 0x98, 0xf0, 0x69, 0xf7, 0xd9, 0x6b, 0xd3, 0xf0, 0x50, 0x0b, 0x0d,
-	0x63, 0x02, 0x67, 0xa5, 0xf8, 0x99, 0xc9, 0xd2, 0x63, 0xff, 0x3b, 0x60,
-	0x78, 0x46, 0x00, 0xf3, 0x9e, 0x30, 0x34, 0xef, 0xc1, 0xe6, 0x8e, 0xf9,
-	0x19, 0x20, 0xf7, 0x14, 0xd9, 0x80, 0xfb, 0x16, 0x90, 0xf2, 0x4a, 0x06,
-	0xad, 0xbc, 0x02, 0xa6, 0x09, 0x75, 0x88, 0xfe, 0xa6, 0xf5, 0x9f, 0xe5,
-	0x60, 0xe3, 0x80, 0x4d, 0x40, 0x73, 0x9b, 0xa7, 0x90, 0x32, 0xf7, 0x0c,
-	0xac, 0x6f, 0xb1, 0xae, 0x6d, 0xb4, 0x01, 0xef, 0xb1, 0x5e, 0x34, 0x85,
-	0x85, 0x61, 0x49, 0x0f, 0x03, 0xb0, 0x7e, 0x00, 0xa5, 0x75, 0x50, 0x1d,
-	0x01, 0x4f, 0xef, 0x02, 0x4d, 0x40, 0xf7, 0x39, 0x01, 0xdb, 0xa2, 0xce,
-	0xfd, 0xca, 0xe0, 0xb5, 0xb2, 0x0d, 0xd0, 0x73, 0xab, 0x16, 0xf5, 0x88,
-	0xc9, 0x83, 0xf2, 0x99, 0x93, 0x0a, 0x03, 0x19, 0x79, 0x81, 0x0d, 0x9a,
-	0x17, 0xc0, 0xe1, 0x04, 0x4c, 0xeb, 0xc0, 0x32, 0x6a, 0x8d, 0x2e, 0xd0,
-	0x3c, 0x1e, 0x16, 0x97, 0x7e, 0x90, 0x18, 0x03, 0x54, 0x8c, 0x05, 0xc8,
-	0x97, 0x01, 0xb6, 0x29, 0x41, 0x7e, 0x05, 0xe5, 0x05, 0x90, 0xd9, 0x20,
-	0xbf, 0x83, 0xca, 0x4e, 0x50, 0x5e, 0x04, 0xb2, 0x97, 0x08, 0x41, 0xfd,
-	0x0c, 0xa4, 0x81, 0xec, 0xe6, 0x29, 0x22, 0x60, 0x7e, 0x52, 0x80, 0x10,
-	0x43, 0x03, 0x3c, 0x1f, 0x10, 0x1b, 0xc6, 0x30, 0xf5, 0x31, 0x64, 0xe4,
-	0x1b, 0x88, 0x19, 0x88, 0x7c, 0xc3, 0xce, 0x70, 0x40, 0x00, 0x16, 0x56,
-	0xff, 0xff, 0x1f, 0x53, 0x61, 0x01, 0xa6, 0x53, 0xd0, 0x3a, 0xd6, 0xdf,
-	0xff, 0x0f, 0x88, 0xb0, 0x30, 0xb4, 0xc0, 0xd7, 0x23, 0xe6, 0xc8, 0x83,
-	0xca, 0xd0, 0x05, 0x40, 0x56, 0x1b, 0xbc, 0x4d, 0xc0, 0x02, 0xbe, 0xef,
-	0x79, 0x01, 0xc3, 0x2f, 0x60, 0x99, 0xf5, 0xff, 0xff, 0x52, 0xb8, 0x5a,
-	0x10, 0x00, 0x00, 0x19, 0x3f, 0x16, 0x21, 0xc4, 0x7d, 0x00, 0x00, 0x00 };
+	0xdc, 0x5b, 0x6b, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x4b, 0xae,
+	0xc8, 0x15, 0x35, 0x22, 0x57, 0xd4, 0x9a, 0xa2, 0xed, 0x5d, 0x72, 0x28,
+	0xb2, 0x96, 0xea, 0xae, 0x29, 0xa6, 0x62, 0xd3, 0x4d, 0xb4, 0xd9, 0xa5,
+	0x5c, 0xb5, 0x75, 0x5a, 0x4a, 0x26, 0xfc, 0x48, 0x55, 0x83, 0xde, 0xa5,
+	0x9c, 0xa0, 0xa8, 0x53, 0xc9, 0x76, 0x85, 0x20, 0x05, 0xaa, 0x05, 0x1f,
+	0x89, 0x52, 0xb0, 0x1c, 0xc5, 0x92, 0x29, 0xb5, 0x71, 0x6b, 0x96, 0xb4,
+	0x6c, 0x15, 0xd8, 0x6a, 0x65, 0xc7, 0x6d, 0x68, 0x54, 0x2e, 0x65, 0xca,
+	0x69, 0x95, 0x26, 0x48, 0x8d, 0xa0, 0x42, 0x95, 0x3f, 0x8e, 0xe1, 0xf4,
+	0x87, 0x5b, 0xf4, 0x87, 0xd1, 0x07, 0x22, 0xd7, 0x8f, 0xed, 0xf7, 0xdd,
+	0xb9, 0x43, 0x0e, 0x97, 0x14, 0x45, 0xf9, 0xf5, 0xa3, 0x04, 0x56, 0x33,
+	0xf7, 0x7d, 0xee, 0xb9, 0xe7, 0x7c, 0xe7, 0x31, 0x57, 0x3f, 0x2f, 0x52,
+	0x27, 0xfa, 0x6f, 0x3d, 0x7e, 0x89, 0x87, 0x7f, 0xaf, 0x70, 0xfb, 0xce,
+	0xdb, 0x77, 0xe0, 0xf5, 0x0e, 0xd3, 0xa8, 0x0d, 0xb1, 0x9e, 0xff, 0xc4,
+	0xf0, 0xeb, 0xd6, 0xef, 0x2b, 0xfd, 0xd9, 0xf8, 0xbd, 0x89, 0xc6, 0xc1,
+	0x7f, 0x17, 0x31, 0xae, 0xd1, 0x27, 0xf8, 0x57, 0xa9, 0xac, 0xde, 0x6e,
+	0x92, 0x96, 0x55, 0xda, 0x43, 0xde, 0x92, 0x8a, 0x66, 0xfe, 0x24, 0x62,
+	0xa6, 0x33, 0x47, 0xb2, 0x8e, 0x11, 0x09, 0xa5, 0xbb, 0x8a, 0x05, 0x47,
+	0x24, 0x53, 0xda, 0x96, 0xc8, 0xc9, 0x7b, 0x95, 0x62, 0xcc, 0x92, 0xac,
+	0x23, 0x91, 0x9b, 0xd3, 0xef, 0x3e, 0xf5, 0xd2, 0xce, 0xe4, 0x5b, 0x53,
+	0x21, 0x89, 0xd8, 0xe9, 0x17, 0xc4, 0xde, 0x2a, 0x91, 0x56, 0x8c, 0x79,
+	0xb2, 0x33, 0x63, 0x48, 0x83, 0x3f, 0xd7, 0x9b, 0x95, 0x97, 0x3a, 0xa5,
+	0xd8, 0x92, 0x8e, 0x88, 0x99, 0xee, 0xb8, 0x92, 0x0d, 0xd9, 0x83, 0xa1,
+	0xb4, 0x2d, 0x73, 0x65, 0xe9, 0x3f, 0x30, 0x2e, 0x91, 0x48, 0xfa, 0x4b,
+	0x91, 0xda, 0x0e, 0x89, 0x58, 0xe9, 0xa9, 0x23, 0x5f, 0x73, 0x8e, 0x54,
+	0x4c, 0xc7, 0xe9, 0x9a, 0x96, 0x68, 0xef, 0xe9, 0x1e, 0xb4, 0x97, 0x92,
+	0x5d, 0x22, 0x3b, 0xc5, 0x74, 0x8a, 0xd1, 0x90, 0x13, 0x91, 0x6c, 0xd9,
+	0x91, 0x5c, 0x59, 0xe4, 0x1f, 0x4a, 0x86, 0x9c, 0x76, 0x9a, 0x65, 0x7a,
+	0xfb, 0xbb, 0x95, 0x0c, 0x68, 0xf9, 0x7b, 0x67, 0xea, 0xc8, 0xa8, 0x43,
+	0x7a, 0x1f, 0x8b, 0x90, 0xae, 0x50, 0x7a, 0xa8, 0xb6, 0xe0, 0x58, 0x32,
+	0x5c, 0x62, 0xdd, 0x80, 0xc9, 0xba, 0x70, 0x3a, 0x52, 0x77, 0xda, 0x89,
+	0xea, 0xba, 0x52, 0x26, 0x8b, 0xf9, 0x46, 0x4a, 0xec, 0x1b, 0xe9, 0x2e,
+	0x38, 0x31, 0x5d, 0x3f, 0xba, 0x33, 0xeb, 0xc4, 0x51, 0xdf, 0xaa, 0xdb,
+	0x7a, 0xbe, 0x5c, 0x70, 0x1c, 0xdd, 0x76, 0x35, 0x94, 0x75, 0xba, 0x74,
+	0xfd, 0xab, 0xbb, 0x0a, 0xce, 0x76, 0x5d, 0xff, 0xd6, 0xae, 0xac, 0x93,
+	0xd2, 0xf5, 0xe3, 0xf7, 0x17, 0x9c, 0x1e, 0x5d, 0xdf, 0x8a, 0xfa, 0x5e,
+	0x5d, 0xff, 0x83, 0xde, 0x82, 0x93, 0x46, 0xfd, 0x97, 0x22, 0x66, 0x87,
+	0x2d, 0x63, 0xa5, 0x04, 0x7e, 0x19, 0xb4, 0xf5, 0xa1, 0x6e, 0x0f, 0x7e,
+	0x77, 0xe1, 0x37, 0xbf, 0x41, 0x1a, 0xfa, 0xf1, 0x6c, 0x6b, 0xf5, 0x78,
+	0x07, 0x1e, 0xb9, 0x11, 0x79, 0x3d, 0x14, 0x97, 0x97, 0x3a, 0x5f, 0x07,
+	0x0f, 0x6d, 0x39, 0x57, 0x16, 0xa3, 0xbf, 0x33, 0x0e, 0xde, 0xc5, 0xe4,
+	0xb9, 0x72, 0xbd, 0x84, 0x1e, 0x0f, 0x81, 0x37, 0x5f, 0x90, 0x7c, 0x2c,
+	0x22, 0x1b, 0x27, 0x0d, 0x69, 0xeb, 0x8e, 0x48, 0xc6, 0xe6, 0xda, 0x38,
+	0xed, 0x89, 0x98, 0x84, 0x26, 0x33, 0x4d, 0xa6, 0x74, 0xd8, 0x39, 0x29,
+	0x82, 0x77, 0x57, 0x28, 0x97, 0x68, 0x4b, 0x48, 0x6e, 0xfc, 0x36, 0x19,
+	0xb4, 0x49, 0xd7, 0xdc, 0xcd, 0xde, 0x5a, 0x11, 0x23, 0x7b, 0x72, 0x40,
+	0xc6, 0xdc, 0xa8, 0x91, 0x3b, 0xf9, 0x59, 0xc9, 0xa6, 0x24, 0x86, 0x71,
+	0xf1, 0x3c, 0x5a, 0x66, 0x4a, 0x03, 0x32, 0xea, 0x8a, 0x91, 0x75, 0xc9,
+	0xcf, 0x66, 0xb4, 0x37, 0xa8, 0xbe, 0xa8, 0x6b, 0x0d, 0xa9, 0xb9, 0x23,
+	0xa8, 0xb7, 0x51, 0xdf, 0x68, 0xf4, 0xa9, 0x39, 0x54, 0x7d, 0x62, 0x44,
+	0xa2, 0xf2, 0x74, 0x29, 0xa6, 0xfb, 0x56, 0x2a, 0xd9, 0x94, 0x8d, 0x7e,
+	0x03, 0x32, 0xe2, 0xc6, 0x64, 0x10, 0xcf, 0x61, 0x97, 0x72, 0x15, 0x87,
+	0x4c, 0x35, 0x14, 0xf3, 0x27, 0xd4, 0x7c, 0x89, 0x50, 0x9a, 0xf3, 0xb5,
+	0xa2, 0xdf, 0xdb, 0xa0, 0xcb, 0x10, 0x4b, 0x9d, 0x65, 0x46, 0xf2, 0xe3,
+	0x06, 0xe4, 0x0d, 0x4f, 0xc5, 0xd7, 0x3e, 0xd0, 0x6f, 0x89, 0xd3, 0x6d,
+	0x48, 0x01, 0x67, 0x55, 0xb4, 0x51, 0x2e, 0xcd, 0x9a, 0x59, 0xb7, 0x56,
+	0x72, 0x56, 0x42, 0x42, 0x13, 0x94, 0xa5, 0x41, 0x19, 0xc1, 0x18, 0xd3,
+	0x61, 0x9f, 0xb7, 0xb1, 0xef, 0x41, 0x75, 0x0e, 0x35, 0xe9, 0xa2, 0x99,
+	0x2b, 0x37, 0x8b, 0x39, 0xb9, 0x5f, 0x5e, 0x19, 0x17, 0x3b, 0x94, 0x7e,
+	0xb7, 0x92, 0x75, 0x46, 0xcd, 0xec, 0xb3, 0x96, 0x84, 0x27, 0x0c, 0x19,
+	0x75, 0x92, 0xd0, 0x80, 0xa3, 0xe6, 0xee, 0xf2, 0x2c, 0xfa, 0x71, 0x1c,
+	0xfa, 0x95, 0x4c, 0xf0, 0x95, 0xef, 0xdb, 0x6c, 0x53, 0xc9, 0x33, 0xfb,
+	0xe0, 0x0c, 0xb0, 0x8f, 0xe7, 0x5c, 0x9c, 0x89, 0x3a, 0xa3, 0x04, 0xce,
+	0x48, 0x8c, 0xbe, 0x4e, 0xc8, 0xd4, 0x09, 0x4b, 0xf2, 0x29, 0xec, 0x0b,
+	0xbd, 0xf3, 0xa9, 0x45, 0xba, 0x46, 0xc6, 0xab, 0xe9, 0xe2, 0x38, 0xd2,
+	0xe5, 0xd1, 0x34, 0x7c, 0x82, 0xf4, 0x2d, 0xd2, 0x33, 0x36, 0xee, 0xd3,
+	0xc8, 0xf5, 0x48, 0x9b, 0x4f, 0x17, 0xc7, 0x91, 0xae, 0x26, 0x9e, 0x35,
+	0xff, 0x8c, 0x3e, 0xd0, 0x31, 0xe2, 0x5a, 0x38, 0xa3, 0xa8, 0xe4, 0xed,
+	0xa2, 0x31, 0xd2, 0xbb, 0x2d, 0x0e, 0x6d, 0x36, 0x86, 0x7b, 0x49, 0xb3,
+	0x83, 0x73, 0xac, 0x51, 0xe7, 0x0d, 0xf9, 0x26, 0xef, 0xd0, 0x9f, 0xeb,
+	0xe3, 0xbd, 0x64, 0xcb, 0xa8, 0x9a, 0x8f, 0x34, 0x7d, 0x14, 0xf3, 0x90,
+	0xd6, 0x4b, 0x90, 0xd5, 0x1e, 0xc8, 0x68, 0x4a, 0xfe, 0xae, 0xbc, 0x5d,
+	0xbe, 0x53, 0xee, 0x92, 0xbf, 0x81, 0xde, 0xfe, 0x75, 0x39, 0x21, 0x2f,
+	0x94, 0x5b, 0xe5, 0xdb, 0xe5, 0xb8, 0x3c, 0xaf, 0xe4, 0xb7, 0x4f, 0xa4,
+	0x81, 0x32, 0x9d, 0x90, 0x46, 0xe8, 0xcf, 0x46, 0xe8, 0xe6, 0x13, 0xe0,
+	0xdf, 0x89, 0x4e, 0xc9, 0x34, 0xa5, 0x25, 0x72, 0x0b, 0x7e, 0x9b, 0xf1,
+	0x6b, 0x4e, 0x43, 0xee, 0x5c, 0xf2, 0x8e, 0x3c, 0xb4, 0x24, 0xa7, 0xf6,
+	0x6c, 0xc9, 0x48, 0x79, 0xfe, 0x16, 0x4f, 0x76, 0x45, 0xfa, 0xc1, 0x63,
+	0xb3, 0xfb, 0x7f, 0x2a, 0x19, 0x1b, 0xfb, 0xe8, 0xde, 0xa6, 0x78, 0x6f,
+	0x76, 0x53, 0x66, 0x13, 0x90, 0x7b, 0xcb, 0xc8, 0xb9, 0x67, 0x80, 0x1b,
+	0xf5, 0x46, 0xf6, 0x78, 0x51, 0x0a, 0xc7, 0x2b, 0x52, 0x48, 0x85, 0xe5,
+	0x11, 0xbb, 0x22, 0x7d, 0xa9, 0x1a, 0x39, 0x64, 0x83, 0xf7, 0xdb, 0x7f,
+	0xdf, 0xf0, 0x31, 0xfb, 0x89, 0xf2, 0x61, 0xbc, 0xb3, 0x4e, 0xe4, 0x84,
+	0x7a, 0xf7, 0xea, 0x8b, 0xe5, 0xb0, 0x64, 0x62, 0xc5, 0xb8, 0x25, 0x2d,
+	0xa6, 0xb7, 0xee, 0xb0, 0xdf, 0x06, 0x7e, 0x4c, 0x01, 0x27, 0x93, 0x4a,
+	0x5f, 0xf2, 0xe3, 0xeb, 0xae, 0x66, 0x54, 0x35, 0xfa, 0xdb, 0x3d, 0x32,
+	0xaf, 0xf8, 0x99, 0x18, 0x34, 0xd2, 0x31, 0x69, 0x2b, 0xb1, 0xdc, 0x6b,
+	0xdc, 0x5d, 0xa6, 0x3c, 0xe3, 0xbd, 0x4c, 0x3a, 0x6f, 0x42, 0x3f, 0x0b,
+	0xcf, 0x8c, 0xa6, 0x37, 0x48, 0x23, 0xe7, 0x21, 0x8d, 0x7c, 0xfe, 0x79,
+	0x80, 0xc6, 0xa7, 0x16, 0xde, 0x4f, 0x04, 0xde, 0x8b, 0xe5, 0x4b, 0x75,
+	0x1e, 0x6d, 0xbd, 0xf2, 0xc6, 0xc4, 0x57, 0xf4, 0x3a, 0x78, 0x3f, 0xcb,
+	0xf9, 0xff, 0xaa, 0xe2, 0xc9, 0x4b, 0xf1, 0x3a, 0xeb, 0xcc, 0x06, 0xd6,
+	0x79, 0x31, 0xb0, 0xce, 0x8b, 0x81, 0x75, 0x8a, 0xe0, 0xa9, 0x6c, 0x30,
+	0x21, 0xc3, 0x79, 0x9a, 0x31, 0x39, 0x8a, 0x39, 0x5f, 0x97, 0x50, 0x9a,
+	0x7a, 0xee, 0xe3, 0xcd, 0x65, 0xf4, 0x4f, 0xcb, 0xfc, 0x44, 0x51, 0xf2,
+	0xc7, 0xc3, 0xb2, 0x4f, 0xf5, 0xdb, 0xa5, 0xe9, 0x0b, 0xb6, 0x45, 0x64,
+	0x6f, 0x8c, 0xef, 0x7e, 0x9b, 0x05, 0x3e, 0xb3, 0xfc, 0xc6, 0x4d, 0x5e,
+	0x99, 0xef, 0xb3, 0x7a, 0x2f, 0x03, 0xde, 0xb8, 0xb3, 0x6f, 0x2a, 0x3c,
+	0x9c, 0x2b, 0x13, 0xb7, 0x24, 0x15, 0x72, 0xe4, 0x60, 0x5f, 0xaa, 0x59,
+	0x46, 0x6c, 0x23, 0x35, 0xdc, 0x55, 0x4b, 0xbd, 0xc8, 0x98, 0x4e, 0x3d,
+	0xb0, 0x41, 0x12, 0x26, 0x31, 0x5f, 0xed, 0xcb, 0x30, 0x3d, 0xfa, 0x6d,
+	0x96, 0xfb, 0x4d, 0xa7, 0xb1, 0xaa, 0x9e, 0xba, 0x1d, 0xc2, 0x3b, 0x65,
+	0x78, 0xb7, 0x3e, 0x63, 0x0b, 0x65, 0xe2, 0xf0, 0xad, 0xba, 0xec, 0xb7,
+	0xe3, 0xc0, 0x96, 0x94, 0x7f, 0xb6, 0x65, 0x69, 0xd9, 0xc7, 0x89, 0x20,
+	0x86, 0x73, 0xaf, 0xc0, 0x27, 0x87, 0x72, 0x17, 0x06, 0xad, 0x29, 0xe8,
+	0x5c, 0xad, 0xa6, 0x61, 0xb3, 0xa6, 0x01, 0xb4, 0x76, 0x42, 0xb2, 0x94,
+	0x2e, 0x29, 0xd1, 0xaa, 0x2a, 0x93, 0xf7, 0xfe, 0xfb, 0x7a, 0xd5, 0xee,
+	0xe9, 0x9c, 0xff, 0xf4, 0xf1, 0xfd, 0xcd, 0x80, 0xbd, 0x68, 0x85, 0xce,
+	0xc6, 0xc0, 0x2b, 0x1f, 0xeb, 0x89, 0xc1, 0x71, 0xd8, 0x07, 0xc8, 0xaa,
+	0xc2, 0xf6, 0x28, 0xf0, 0xd0, 0xd2, 0xd8, 0x1c, 0xd1, 0xd8, 0x1c, 0x05,
+	0x2e, 0xb3, 0x6c, 0xeb, 0x72, 0x4c, 0x97, 0xe3, 0x28, 0xc3, 0x8e, 0x4f,
+	0x12, 0xbb, 0x1b, 0x8a, 0x43, 0x27, 0x14, 0xde, 0xd3, 0x56, 0x00, 0x85,
+	0x89, 0xd7, 0xc4, 0xed, 0x56, 0x99, 0x2e, 0x61, 0xbd, 0x05, 0x6c, 0xe4,
+	0xde, 0x83, 0xf4, 0x90, 0x96, 0x75, 0x62, 0xc2, 0x76, 0x65, 0x62, 0xa4,
+	0xf7, 0x61, 0xec, 0x9d, 0xf8, 0x43, 0xba, 0x6f, 0x06, 0xad, 0xdc, 0xc7,
+	0x27, 0x49, 0x2b, 0xd7, 0xab, 0xa6, 0xf7, 0xc3, 0xe2, 0x20, 0x69, 0x3f,
+	0x83, 0x3d, 0x67, 0x80, 0x79, 0x62, 0x0c, 0x74, 0x0e, 0x60, 0xcf, 0xfd,
+	0xc0, 0xc3, 0xbb, 0x80, 0x87, 0x7b, 0x80, 0x87, 0x7d, 0xc0, 0xc3, 0x34,
+	0xb0, 0xb0, 0x17, 0x58, 0xd8, 0x03, 0x2c, 0x4c, 0x81, 0x37, 0x31, 0x99,
+	0x02, 0x36, 0x4e, 0x01, 0x23, 0xa7, 0x30, 0xc7, 0xf0, 0xa4, 0x18, 0x0f,
+	0x60, 0x0f, 0xdf, 0x9c, 0x48, 0x9e, 0x82, 0x2c, 0xc5, 0x8b, 0x26, 0xe4,
+	0x3f, 0xd5, 0x0b, 0xd9, 0xee, 0x92, 0x99, 0xb2, 0x25, 0x05, 0xd8, 0xd4,
+	0xb6, 0xad, 0xed, 0xd0, 0x35, 0xc8, 0x7b, 0x5c, 0xf4, 0xdf, 0x7a, 0xfd,
+	0xfc, 0xb1, 0x88, 0xf3, 0x4f, 0x94, 0xc5, 0x84, 0xc8, 0x79, 0xc9, 0xbb,
+	0xed, 0x76, 0x9b, 0xd9, 0x85, 0x7e, 0x2c, 0xa7, 0xcc, 0x03, 0xc7, 0xef,
+	0x30, 0x87, 0x8e, 0x2b, 0x7f, 0x05, 0x78, 0x55, 0x91, 0xd1, 0x14, 0x75,
+	0xab, 0x22, 0xa7, 0x53, 0xc9, 0xde, 0xa2, 0xd4, 0xcb, 0x58, 0x6c, 0x5c,
+	0xd9, 0x5a, 0x2b, 0x7d, 0x4c, 0xd9, 0xab, 0x82, 0x83, 0x67, 0xa9, 0xdb,
+	0xcc, 0x1f, 0xe7, 0xfe, 0xdb, 0xf1, 0x0b, 0x83, 0x16, 0xce, 0x6f, 0x49,
+	0x5f, 0x8f, 0x6d, 0x3e, 0xd4, 0x59, 0x84, 0x42, 0x24, 0xed, 0x79, 0xac,
+	0x9c, 0x1b, 0x6f, 0x8f, 0xb7, 0x9b, 0x96, 0x0c, 0x5a, 0x86, 0x0c, 0x43,
+	0xbe, 0xfb, 0x52, 0x6f, 0x57, 0xc6, 0x62, 0x6c, 0xaf, 0x95, 0xaf, 0x2b,
+	0x9f, 0x03, 0x6b, 0xcf, 0x9c, 0xc0, 0xba, 0x61, 0x9c, 0x01, 0xd7, 0xe5,
+	0x3c, 0x28, 0x97, 0x2c, 0x94, 0x93, 0xa7, 0x8a, 0x52, 0x86, 0x9e, 0x6c,
+	0x90, 0xec, 0xf6, 0x1a, 0xc9, 0xf4, 0x27, 0x64, 0x78, 0xa2, 0x0c, 0x9c,
+	0x8a, 0x28, 0x5d, 0xc9, 0x0f, 0x24, 0xe4, 0xf1, 0x09, 0xd6, 0x9d, 0xc3,
+	0xfe, 0x93, 0xc7, 0x32, 0xc2, 0xfd, 0x1b, 0x92, 0xd9, 0x7f, 0x4e, 0x1e,
+	0x71, 0xcf, 0xc9, 0x10, 0xce, 0xf0, 0xe9, 0xf2, 0xac, 0x1c, 0x70, 0x1d,
+	0x39, 0x0d, 0xbc, 0xcf, 0x1d, 0x07, 0xee, 0x39, 0xeb, 0x81, 0x51, 0xc9,
+	0x73, 0xb4, 0xa1, 0x26, 0xfc, 0xbc, 0x69, 0xf0, 0xf7, 0x89, 0x09, 0xf2,
+	0xd7, 0x94, 0x47, 0x7f, 0xd1, 0x80, 0x3e, 0x26, 0xc0, 0xcf, 0x56, 0x39,
+	0xec, 0x26, 0x67, 0x33, 0x26, 0x70, 0x31, 0x65, 0x87, 0xa4, 0x2e, 0x8e,
+	0x7e, 0x5e, 0x9f, 0x5c, 0x2a, 0x84, 0xb3, 0x2e, 0xa2, 0xef, 0xdb, 0xa0,
+	0x93, 0x63, 0x63, 0xf8, 0x65, 0xd0, 0x0f, 0xf2, 0x6b, 0x27, 0x67, 0xa7,
+	0x4c, 0xf6, 0x4f, 0xe0, 0xcc, 0x80, 0x2b, 0x93, 0x00, 0x1e, 0x9b, 0xef,
+	0x69, 0x33, 0x4f, 0x1a, 0x5c, 0xca, 0x59, 0x02, 0x34, 0x11, 0xd3, 0xda,
+	0xcf, 0x7d, 0x47, 0xb8, 0xce, 0x46, 0xf4, 0x7f, 0x07, 0x7e, 0xae, 0x2d,
+	0x33, 0x38, 0x97, 0x9f, 0x82, 0x57, 0x99, 0xb8, 0x57, 0x1e, 0x9e, 0x4c,
+	0x9e, 0x9b, 0x37, 0xf9, 0xee, 0x14, 0xf3, 0xe6, 0x6d, 0x22, 0x8d, 0xe4,
+	0x57, 0x0a, 0xbc, 0x72, 0x6c, 0xd3, 0xdc, 0xaa, 0x7d, 0x3b, 0xea, 0x89,
+	0x03, 0x9a, 0xe0, 0x67, 0x74, 0x07, 0xf5, 0x84, 0xf6, 0xce, 0xd7, 0x93,
+	0x64, 0x7c, 0xca, 0x84, 0xff, 0xd1, 0x6d, 0xc9, 0x31, 0x55, 0x06, 0x8f,
+	0x06, 0x92, 0xf1, 0x8c, 0x49, 0x9f, 0xb7, 0x4b, 0x9e, 0x76, 0xd9, 0x1f,
+	0x7c, 0x1c, 0x8f, 0xea, 0xfe, 0xe7, 0x20, 0x23, 0xf4, 0xcf, 0xba, 0x40,
+	0xb3, 0xa7, 0x3b, 0xd3, 0xe3, 0x31, 0xd5, 0x36, 0xa6, 0xf6, 0x60, 0x60,
+	0x5d, 0xc8, 0x26, 0x7c, 0xb5, 0x9c, 0xd2, 0x23, 0x3b, 0x03, 0x5f, 0x1e,
+	0x7a, 0xe0, 0xe9, 0xd0, 0x4c, 0x89, 0xb4, 0xdc, 0x43, 0x7e, 0x14, 0x41,
+	0xcc, 0x31, 0x33, 0x8d, 0x73, 0xed, 0x91, 0x22, 0xfd, 0xb9, 0xf9, 0xd0,
+	0xd3, 0x32, 0x38, 0x43, 0x7b, 0x83, 0x9f, 0xeb, 0xd8, 0x8c, 0x1f, 0x32,
+	0xca, 0x16, 0x6c, 0xc1, 0x39, 0xc3, 0x4e, 0xa4, 0x36, 0x6a, 0x3f, 0xe6,
+	0x49, 0x9c, 0xdb, 0x79, 0x9c, 0x6b, 0x49, 0x86, 0x4e, 0x5e, 0xa2, 0xcc,
+	0x76, 0xcd, 0x48, 0xb2, 0x6b, 0x4c, 0xb6, 0xd9, 0xd3, 0xd0, 0xb7, 0xcc,
+	0x40, 0x65, 0x97, 0x99, 0xe6, 0x98, 0x23, 0x18, 0x83, 0xe7, 0xcc, 0x25,
+	0x39, 0x54, 0x66, 0xdd, 0xef, 0x80, 0x9f, 0xb0, 0x3b, 0x3d, 0x4f, 0x6a,
+	0x39, 0xc7, 0x7c, 0x96, 0x3f, 0xdf, 0x25, 0x3d, 0x1f, 0xfb, 0xb1, 0x0f,
+	0xc7, 0x2c, 0xce, 0xbb, 0x9b, 0xb6, 0x06, 0x78, 0xd3, 0x61, 0x56, 0x76,
+	0x85, 0xd1, 0x7e, 0xba, 0x87, 0xef, 0x98, 0x07, 0xb6, 0xc6, 0x76, 0xce,
+	0xa3, 0x2f, 0xf6, 0xe5, 0xae, 0x93, 0xb6, 0x66, 0x9f, 0x5e, 0x9e, 0x3b,
+	0xfd, 0x00, 0x96, 0x1f, 0x6e, 0xf2, 0x78, 0x3f, 0x12, 0xf2, 0xb0, 0xfb,
+	0x2f, 0x51, 0xa6, 0x7e, 0x3d, 0x26, 0x39, 0x37, 0x89, 0x7d, 0x42, 0x87,
+	0xca, 0x0d, 0x86, 0xb7, 0x47, 0xf0, 0xbf, 0xff, 0x32, 0xf8, 0x20, 0x45,
+	0x8f, 0x37, 0xe4, 0x0b, 0x79, 0xd2, 0x00, 0xd9, 0xae, 0xc3, 0xbc, 0x58,
+	0x47, 0xf1, 0xe0, 0x96, 0x26, 0xcf, 0xef, 0x4d, 0x16, 0x33, 0x8c, 0xd7,
+	0x1a, 0x29, 0xb3, 0xc0, 0xa8, 0xf2, 0xfd, 0x36, 0xe7, 0x9e, 0x32, 0xd7,
+	0x91, 0xde, 0xc4, 0x85, 0xd0, 0x7e, 0x96, 0xbb, 0xa6, 0x4c, 0xf0, 0x1e,
+	0xe7, 0x93, 0xdd, 0xde, 0xae, 0x71, 0xe9, 0x99, 0x10, 0x65, 0x94, 0xf2,
+	0x9c, 0x77, 0xb7, 0xd9, 0xf7, 0x08, 0x65, 0x34, 0x86, 0xf3, 0x26, 0x2e,
+	0xf0, 0x69, 0xc1, 0x26, 0xc6, 0x71, 0xc6, 0x5b, 0x34, 0xed, 0x7c, 0xb7,
+	0x64, 0xca, 0xc6, 0x1a, 0xee, 0x7f, 0x6f, 0xf0, 0xea, 0xf8, 0xde, 0xc2,
+	0x33, 0x39, 0xb6, 0x94, 0x56, 0x9e, 0x67, 0xf5, 0x19, 0x9e, 0x06, 0xed,
+	0xac, 0xc7, 0x73, 0xe6, 0x14, 0xf4, 0x0f, 0x58, 0xd1, 0xd3, 0x11, 0xbf,
+	0x88, 0xfe, 0x39, 0x60, 0x7c, 0xd1, 0x62, 0xdb, 0x55, 0x63, 0x71, 0x8c,
+	0x49, 0x3f, 0x13, 0x3e, 0xed, 0x05, 0xe3, 0x81, 0xf2, 0x2b, 0x46, 0x76,
+	0xe6, 0xaa, 0x91, 0x83, 0x5c, 0xcc, 0xb8, 0x3b, 0x20, 0xcf, 0xd4, 0x17,
+	0x1b, 0x6b, 0x27, 0xe3, 0xff, 0x62, 0xb6, 0x27, 0xa6, 0xa1, 0xdb, 0x07,
+	0xc0, 0x58, 0xef, 0x2c, 0x5b, 0xd5, 0xd9, 0xce, 0x9b, 0x61, 0x8d, 0x75,
+	0x2c, 0x27, 0xed, 0x7b, 0xe5, 0x35, 0xec, 0x77, 0x16, 0x7c, 0x9e, 0x95,
+	0x42, 0xb9, 0x24, 0xf9, 0x93, 0xdb, 0xec, 0x61, 0xc4, 0xb8, 0x8b, 0xb4,
+	0x13, 0xc3, 0x8a, 0xf4, 0xbd, 0x8d, 0xdd, 0xae, 0x14, 0x6b, 0xd2, 0xc4,
+	0xb2, 0x0e, 0xc8, 0x13, 0xea, 0x4a, 0x8b, 0x32, 0x79, 0xe7, 0xb2, 0xfd,
+	0x20, 0xbe, 0xed, 0x59, 0xba, 0xa7, 0x19, 0xb9, 0xfe, 0x9e, 0x76, 0x2f,
+	0xec, 0x89, 0xd8, 0x01, 0xcc, 0x77, 0x81, 0xf9, 0x2e, 0x30, 0xdf, 0x05,
+	0xe6, 0xbb, 0xc0, 0x7c, 0x17, 0xf6, 0xc0, 0x05, 0xee, 0xbb, 0xc0, 0x7d,
+	0x17, 0xb8, 0xef, 0x02, 0xf7, 0xdd, 0x2c, 0xce, 0x8e, 0xd8, 0x4e, 0xbb,
+	0x71, 0xdf, 0x82, 0xad, 0xf4, 0x7c, 0x9b, 0x9b, 0xb4, 0xbf, 0x00, 0x9d,
+	0xb4, 0x5b, 0x64, 0xb8, 0x6b, 0x33, 0xf6, 0x56, 0x87, 0x67, 0x3d, 0x9e,
+	0x58, 0xa3, 0xeb, 0x33, 0x5a, 0x77, 0xbe, 0x0a, 0xba, 0x4c, 0x94, 0x7f,
+	0x09, 0xb2, 0x59, 0x03, 0x7a, 0x7e, 0x41, 0xfb, 0x15, 0xa7, 0x2c, 0x4f,
+	0x36, 0xeb, 0x51, 0xf7, 0x69, 0xd4, 0xd5, 0xa3, 0xcf, 0x21, 0xf4, 0xa1,
+	0x5f, 0xd2, 0xa0, 0xeb, 0x82, 0xfd, 0xe8, 0x9f, 0xfc, 0x26, 0xd6, 0x4a,
+	0xa2, 0x5f, 0x03, 0xe6, 0x6e, 0x45, 0x9f, 0xcf, 0xa2, 0xcf, 0xcd, 0x28,
+	0xd3, 0x9f, 0xdd, 0x82, 0xf2, 0xa7, 0xaa, 0xc6, 0xdc, 0x8a, 0xba, 0xcf,
+	0x54, 0xd5, 0xcd, 0xa3, 0x0e, 0x71, 0xb0, 0x7d, 0x51, 0x8f, 0x2b, 0xa2,
+	0xdc, 0x5c, 0xd5, 0xe7, 0x12, 0xea, 0x7a, 0x51, 0xf7, 0x3d, 0x3c, 0x11,
+	0xff, 0xda, 0xa4, 0xc9, 0x6f, 0xa3, 0x6f, 0x9a, 0x40, 0x7d, 0x58, 0xfb,
+	0x97, 0x4f, 0xd2, 0xdf, 0x82, 0x9d, 0xfd, 0x53, 0xcb, 0xf3, 0xc7, 0x9e,
+	0xb1, 0x3d, 0x59, 0xf5, 0xcb, 0x3f, 0xaa, 0x2a, 0xb3, 0xef, 0xff, 0x56,
+	0xd5, 0xed, 0xda, 0xb8, 0xb4, 0xfc, 0x7e, 0x78, 0xf9, 0x98, 0xe3, 0x55,
+	0x7d, 0x5e, 0x6e, 0x5c, 0x5a, 0xfe, 0x7c, 0xcd, 0xf2, 0x31, 0xbf, 0xb5,
+	0x61, 0x69, 0xdd, 0xe1, 0xa6, 0xa5, 0x65, 0xfa, 0x7d, 0x31, 0xc4, 0x2d,
+	0x7e, 0xff, 0x07, 0x37, 0x79, 0xed, 0xe4, 0x6f, 0xb5, 0x2c, 0x29, 0xe3,
+	0x8d, 0xb2, 0x89, 0x73, 0xb8, 0x60, 0x40, 0xe7, 0x6c, 0x33, 0xfd, 0x8a,
+	0x91, 0x83, 0x4c, 0x65, 0xcb, 0xfe, 0x7c, 0xd4, 0xe5, 0xea, 0xdc, 0x80,
+	0x9f, 0x13, 0xa0, 0x8f, 0x15, 0x85, 0xdc, 0x00, 0x8b, 0x63, 0xc9, 0xa3,
+	0x45, 0x59, 0xd4, 0xe1, 0x36, 0xf3, 0x5a, 0x3a, 0x3c, 0xa9, 0x71, 0xeb,
+	0x32, 0xe8, 0xac, 0x48, 0x7f, 0xaa, 0x96, 0x76, 0x47, 0xe3, 0x19, 0xb1,
+	0xa8, 0x52, 0x09, 0x6d, 0xad, 0xc8, 0xc1, 0xd4, 0x3b, 0x15, 0x51, 0x38,
+	0xf8, 0x4d, 0xcd, 0x57, 0xe2, 0xa1, 0x0d, 0xb9, 0x8d, 0x29, 0x3f, 0x2e,
+	0x94, 0x3e, 0x45, 0x9f, 0xe4, 0x88, 0x87, 0xb3, 0xc4, 0x22, 0x94, 0xcb,
+	0x63, 0xe8, 0xc3, 0xf5, 0xf1, 0x9c, 0x21, 0xb6, 0x5b, 0xca, 0xce, 0xe4,
+	0x6d, 0xce, 0xbb, 0x12, 0x5e, 0xfe, 0xd8, 0xa2, 0x2f, 0x68, 0x39, 0x67,
+	0x60, 0xf3, 0xd8, 0x46, 0xff, 0xe0, 0x0c, 0x7d, 0x91, 0x80, 0x6f, 0xd3,
+	0x11, 0x12, 0x67, 0x11, 0x47, 0xbd, 0x7d, 0xb5, 0xd0, 0xd7, 0x5f, 0xc3,
+	0x5e, 0x57, 0xc6, 0xab, 0x76, 0xf3, 0xfa, 0xba, 0xbd, 0x77, 0x41, 0xb7,
+	0x7d, 0xd9, 0x5b, 0x29, 0x07, 0x70, 0x45, 0x9d, 0xc5, 0xf3, 0xe5, 0xe4,
+	0xb1, 0x22, 0x74, 0x69, 0x4e, 0xc5, 0xbb, 0xfe, 0xb9, 0xd0, 0xaf, 0x49,
+	0x9e, 0x9a, 0x82, 0x6c, 0x0f, 0xa9, 0x38, 0x80, 0x31, 0x40, 0x45, 0x76,
+	0xa7, 0x86, 0x62, 0xe4, 0x43, 0xc6, 0xbc, 0x1a, 0xa6, 0x1f, 0x31, 0xe7,
+	0x92, 0x67, 0x29, 0xb4, 0xa7, 0xc0, 0xdb, 0x7f, 0x95, 0x5c, 0x8c, 0x75,
+	0xff, 0x55, 0x99, 0x86, 0xff, 0xa3, 0x7c, 0x22, 0xe5, 0x03, 0xd0, 0xa7,
+	0x83, 0xad, 0x2f, 0x93, 0xa7, 0x17, 0xc0, 0x67, 0xdf, 0x2f, 0xb8, 0x4c,
+	0xbf, 0x54, 0x96, 0xfa, 0xcf, 0x22, 0x8f, 0x94, 0xfe, 0x19, 0x76, 0xc8,
+	0xc4, 0x7c, 0xb4, 0x77, 0xb4, 0x29, 0xac, 0xdf, 0x11, 0xa6, 0xff, 0xe6,
+	0xd9, 0xff, 0x10, 0xd6, 0x43, 0x4c, 0x5d, 0xfa, 0x0f, 0x23, 0xef, 0xb6,
+	0xd2, 0xb7, 0xc2, 0xfe, 0x89, 0xab, 0x6c, 0x63, 0x5d, 0x44, 0xfb, 0xdc,
+	0x51, 0xed, 0x63, 0xdb, 0xda, 0xc7, 0x26, 0x1d, 0x46, 0xc4, 0x4e, 0xfb,
+	0xbe, 0x02, 0xcf, 0x0c, 0x67, 0xb3, 0x55, 0xf9, 0x0a, 0xb2, 0xb2, 0xaf,
+	0xe0, 0xd3, 0x74, 0x16, 0xfb, 0xa4, 0x6f, 0xa7, 0x72, 0x3f, 0x8d, 0x5e,
+	0xbe, 0x89, 0x34, 0xf8, 0x36, 0x53, 0xd9, 0xe6, 0xa3, 0x30, 0x83, 0xd8,
+	0xdb, 0x6f, 0x83, 0xd6, 0x3d, 0x92, 0x1d, 0x3f, 0xab, 0x6d, 0x30, 0x63,
+	0x07, 0xfa, 0xed, 0x9e, 0xcc, 0x66, 0x53, 0x0d, 0x86, 0x9e, 0xa7, 0x19,
+	0x56, 0x33, 0x90, 0x97, 0xe2, 0x5a, 0xf4, 0x6d, 0x7c, 0x3f, 0x67, 0x56,
+	0xfb, 0x39, 0xe7, 0xe5, 0xa0, 0xeb, 0xc5, 0x0a, 0xfd, 0xa5, 0x0b, 0xa8,
+	0x53, 0xb4, 0xc7, 0xe9, 0x4f, 0x9a, 0x26, 0xfd, 0xc9, 0x24, 0x82, 0x0e,
+	0x6f, 0x2f, 0x6d, 0xd8, 0xcb, 0xcc, 0xc2, 0x5e, 0xea, 0x2f, 0x2c, 0xdd,
+	0x0b, 0xe9, 0xb7, 0xc1, 0x4f, 0x4b, 0xe3, 0x14, 0xe7, 0xfc, 0x46, 0x98,
+	0x18, 0xd6, 0x4f, 0x9f, 0xc8, 0xf5, 0x7c, 0xb1, 0xa5, 0xf3, 0xc2, 0x63,
+	0x28, 0x4d, 0x5d, 0xa3, 0x8d, 0xfb, 0xf7, 0xf5, 0xca, 0xd2, 0xd8, 0xce,
+	0x3d, 0xfc, 0x09, 0xe6, 0x8c, 0x19, 0x79, 0xe5, 0x9b, 0xd1, 0xcf, 0x41,
+	0xdc, 0x5d, 0x7a, 0x05, 0x4f, 0xea, 0x8e, 0x9a, 0x07, 0xfb, 0x8d, 0xaa,
+	0xfd, 0x8e, 0xb9, 0x97, 0xd4, 0x1e, 0xa7, 0x4b, 0x3f, 0x90, 0xc2, 0xc9,
+	0x1f, 0xc2, 0x26, 0x06, 0x73, 0x75, 0xcc, 0x73, 0x92, 0x57, 0xc5, 0x00,
+	0xb6, 0x92, 0x66, 0xe6, 0xe1, 0xbe, 0x17, 0xf6, 0xe2, 0x85, 0x71, 0x9c,
+	0xbf, 0xe1, 0xb5, 0xab, 0xf5, 0x7d, 0x9e, 0xd7, 0x04, 0xe8, 0xa9, 0xc0,
+	0x47, 0x8d, 0x83, 0x86, 0xe0, 0x98, 0xc7, 0xa4, 0xcf, 0xe5, 0x59, 0xb5,
+	0xc7, 0x87, 0xc4, 0xb1, 0xf3, 0xe2, 0xfb, 0x25, 0x5c, 0x9f, 0x78, 0x90,
+	0x43, 0x0c, 0xc5, 0xdc, 0xaa, 0xcf, 0x57, 0x9f, 0xa7, 0xd1, 0x0b, 0xd5,
+	0xf2, 0x31, 0x8a, 0xd8, 0xab, 0xe0, 0x92, 0x4f, 0xbe, 0xdc, 0xfa, 0x6b,
+	0x5f, 0x31, 0xb8, 0x9f, 0x11, 0x95, 0x4f, 0x7c, 0x6d, 0x41, 0x7e, 0x87,
+	0x81, 0x2b, 0x9e, 0x3c, 0xbe, 0xaa, 0x79, 0xe3, 0xcb, 0x6d, 0x54, 0xcb,
+	0x00, 0x63, 0x43, 0xea, 0x95, 0x2f, 0x23, 0x1d, 0xf6, 0xdd, 0x8a, 0x17,
+	0x6c, 0x53, 0x79, 0x46, 0x75, 0xce, 0x83, 0x0b, 0xe7, 0xbc, 0xbe, 0x4a,
+	0x66, 0x53, 0xb6, 0xa7, 0xa3, 0xd4, 0x45, 0xe8, 0x34, 0xf8, 0xf5, 0xfc,
+	0x12, 0xdd, 0xef, 0xba, 0x46, 0x8e, 0x36, 0x2a, 0xa1, 0xc9, 0x97, 0xc1,
+	0xcb, 0x5b, 0x11, 0xbb, 0x88, 0x58, 0x13, 0xc4, 0x28, 0xfa, 0x22, 0x8b,
+	0xfe, 0xf1, 0xb4, 0xac, 0xe4, 0x1b, 0x5f, 0xcf, 0x0f, 0xb9, 0x7d, 0x8d,
+	0x7e, 0xc8, 0xaf, 0xd6, 0x30, 0x96, 0x99, 0x83, 0x9e, 0x1e, 0xc0, 0xf8,
+	0x1a, 0xe7, 0x47, 0xb0, 0x6f, 0xa7, 0xad, 0x5a, 0xc7, 0xc7, 0x8b, 0xa8,
+	0x6c, 0x9c, 0xdc, 0xa2, 0x30, 0xc3, 0x9e, 0x58, 0xc4, 0x8c, 0x61, 0x97,
+	0xf2, 0xab, 0xf4, 0x34, 0xb6, 0x51, 0x7c, 0x8c, 0x78, 0xd6, 0x62, 0xbe,
+	0x67, 0x65, 0x1c, 0xf0, 0x72, 0xba, 0x2b, 0xc7, 0x0a, 0x37, 0x55, 0xf1,
+	0x72, 0x25, 0xdc, 0x3c, 0x07, 0xde, 0xa5, 0x11, 0x13, 0x27, 0xcf, 0x88,
+	0xec, 0x41, 0x9c, 0x9c, 0x7c, 0x4b, 0xa4, 0x0f, 0xb1, 0x72, 0x72, 0x56,
+	0x24, 0x83, 0x78, 0x99, 0xf1, 0xdb, 0x5d, 0xe0, 0x69, 0x2f, 0xe2, 0xe9,
+	0x1e, 0x60, 0x6a, 0x0a, 0x18, 0xbb, 0x1d, 0xfc, 0xed, 0x02, 0xbf, 0x6d,
+	0xc4, 0x5b, 0x65, 0x39, 0x70, 0x5c, 0x8c, 0x7d, 0x2a, 0x7f, 0x4d, 0x7d,
+	0x8f, 0xc1, 0xce, 0x56, 0x2a, 0x87, 0x52, 0xed, 0x88, 0xf5, 0x13, 0xf2,
+	0x39, 0x8b, 0xb1, 0xad, 0x61, 0xb5, 0x75, 0x7f, 0x3f, 0x14, 0xf4, 0x6b,
+	0xb3, 0xd7, 0xb5, 0x13, 0xcb, 0xf9, 0x9f, 0x53, 0xb6, 0xe2, 0xc5, 0xd0,
+	0x6a, 0xfc, 0xdf, 0xb7, 0xc0, 0xff, 0x9e, 0x3a, 0xa9, 0xbb, 0x4b, 0xe5,
+	0x16, 0xda, 0xba, 0x0f, 0x11, 0xcf, 0x52, 0xb0, 0xfb, 0xb0, 0xcf, 0x15,
+	0xb9, 0x33, 0x75, 0xb5, 0x72, 0xd1, 0xd9, 0x20, 0xf9, 0xed, 0x0f, 0x6a,
+	0x4c, 0x3f, 0xf5, 0x87, 0x59, 0xa7, 0x08, 0x1d, 0xf1, 0xf2, 0x88, 0x43,
+	0xe3, 0x11, 0x58, 0x0a, 0xfe, 0x35, 0xca, 0x74, 0xef, 0x55, 0x9c, 0xe3,
+	0xb6, 0x33, 0x4c, 0x42, 0x11, 0x6b, 0xa6, 0x63, 0x51, 0x95, 0x43, 0xde,
+	0xe4, 0xb0, 0xde, 0xc6, 0xb9, 0x0e, 0xc8, 0x34, 0xfc, 0x8b, 0x99, 0x5e,
+	0xd0, 0xb8, 0xbd, 0x19, 0xfd, 0xa9, 0x7b, 0xe4, 0xf9, 0x80, 0x0c, 0xc6,
+	0xc8, 0xd3, 0x18, 0xfa, 0xef, 0x45, 0x9f, 0x46, 0x3c, 0xff, 0x28, 0x34,
+	0x6d, 0x33, 0x9e, 0xfe, 0x3c, 0xca, 0x9c, 0x23, 0x68, 0x5b, 0x77, 0x85,
+	0x45, 0xcd, 0xc9, 0x31, 0xcd, 0x0a, 0x03, 0x16, 0xd7, 0xe2, 0x3a, 0x6c,
+	0x7b, 0xaf, 0x72, 0x47, 0x77, 0x6f, 0x60, 0xbd, 0x86, 0xc0, 0x7a, 0xbd,
+	0x81, 0xf5, 0x48, 0x67, 0x63, 0x80, 0xce, 0x46, 0x8c, 0xff, 0x5d, 0xac,
+	0x4d, 0x7e, 0x04, 0xd7, 0xcc, 0x07, 0xd6, 0xf4, 0xf7, 0xd7, 0x1c, 0x18,
+	0xf7, 0x0e, 0xd6, 0x63, 0x5d, 0x2c, 0x50, 0x47, 0x1a, 0x9a, 0x50, 0xc7,
+	0x72, 0x63, 0x80, 0xae, 0xa8, 0x8a, 0xf7, 0xa7, 0xd5, 0x19, 0x92, 0xcf,
+	0x75, 0xb0, 0x6b, 0x26, 0x6c, 0x4b, 0x0d, 0xfc, 0xaf, 0xea, 0xbd, 0x7e,
+	0x0d, 0xeb, 0xfa, 0xf3, 0xc5, 0x30, 0x07, 0xfb, 0xb3, 0x6f, 0x48, 0x8f,
+	0x67, 0x3d, 0xdb, 0xff, 0xb6, 0xf2, 0x8c, 0xe2, 0x5b, 0x1a, 0xb4, 0x93,
+	0xc6, 0x36, 0x99, 0x6a, 0xb4, 0x70, 0x9e, 0xa6, 0xb6, 0xa5, 0xc0, 0xda,
+	0xb2, 0x69, 0xb4, 0x77, 0xf3, 0xfc, 0x37, 0x68, 0x4c, 0xad, 0x33, 0xb2,
+	0xc7, 0x99, 0x4b, 0xa8, 0xd7, 0xb1, 0x22, 0xe2, 0x13, 0x65, 0x87, 0x7c,
+	0x3b, 0x41, 0x3b, 0x44, 0xdf, 0x86, 0x36, 0xf6, 0x9c, 0x7e, 0xc7, 0x13,
+	0x72, 0xfc, 0xd0, 0x4c, 0xa3, 0x5c, 0x54, 0x7c, 0xb5, 0x65, 0x7e, 0x81,
+	0xaf, 0x61, 0xfd, 0xbd, 0xe6, 0x31, 0xfd, 0x2d, 0x64, 0x3f, 0x7c, 0x27,
+	0xbc, 0x97, 0x32, 0xa0, 0x23, 0x21, 0xed, 0xdd, 0xcc, 0x61, 0x14, 0xf1,
+	0x74, 0xf0, 0x34, 0xf0, 0x84, 0xcd, 0x42, 0x0c, 0xd2, 0xde, 0xcd, 0x58,
+	0x50, 0x40, 0xdb, 0x15, 0x15, 0x07, 0xce, 0x94, 0x6d, 0xe3, 0x4e, 0xd7,
+	0xcb, 0x1d, 0xcd, 0x3b, 0xab, 0xe5, 0x8e, 0x1e, 0xa8, 0xc5, 0x79, 0x9c,
+	0xf2, 0x73, 0x47, 0xf3, 0xa2, 0x72, 0x47, 0xa7, 0xae, 0x93, 0x3b, 0xca,
+	0xac, 0x3d, 0x77, 0xc4, 0xf9, 0x2d, 0xb9, 0xbb, 0xc7, 0x36, 0xbf, 0xa8,
+	0x73, 0x47, 0x6f, 0x88, 0x97, 0x3b, 0xba, 0x28, 0x2b, 0xe7, 0x8e, 0x8e,
+	0x56, 0xe5, 0x8e, 0x9a, 0x54, 0xee, 0x88, 0xf3, 0x78, 0xb9, 0x23, 0x96,
+	0xf3, 0xdd, 0xbf, 0xac, 0x72, 0xe9, 0xf9, 0x6e, 0x60, 0xb0, 0xeb, 0x63,
+	0x9c, 0x6d, 0x0c, 0xa8, 0xf8, 0xf2, 0x4a, 0xb8, 0xd9, 0xf1, 0x31, 0x8e,
+	0xb6, 0x60, 0xf3, 0x82, 0x3d, 0xf3, 0xf1, 0x6e, 0x54, 0xd9, 0xbd, 0xe5,
+	0xf9, 0xc5, 0x7b, 0xaa, 0xf2, 0x8b, 0x03, 0x9e, 0xdd, 0x50, 0x38, 0x37,
+	0xa8, 0x71, 0x6e, 0x74, 0xc1, 0xcf, 0x39, 0x59, 0xcb, 0x18, 0x7c, 0xa4,
+	0x14, 0xc4, 0x51, 0x4b, 0x8d, 0xf5, 0xf2, 0x2c, 0x8b, 0x18, 0x7a, 0xb8,
+	0x0a, 0x43, 0x1f, 0x5b, 0xf1, 0xbb, 0x58, 0x3c, 0xb3, 0xfc, 0xbb, 0x98,
+	0x21, 0xcd, 0xf4, 0x39, 0xba, 0xf3, 0xd8, 0x03, 0x63, 0xe6, 0xfd, 0x92,
+	0x19, 0xb0, 0x81, 0x45, 0x7e, 0xfe, 0x85, 0xe7, 0xbc, 0x68, 0x63, 0xb2,
+	0xe6, 0xc7, 0x97, 0x83, 0x79, 0x48, 0xe5, 0x60, 0xbe, 0x5f, 0x1b, 0xcc,
+	0xc1, 0xcc, 0x03, 0xb3, 0x32, 0x16, 0xf3, 0x5b, 0x2b, 0xe7, 0x60, 0x1e,
+	0x5a, 0x21, 0x07, 0xf3, 0x5d, 0x59, 0xcc, 0xc1, 0x7c, 0x57, 0xfc, 0x1c,
+	0x0c, 0xe7, 0x08, 0x69, 0x9f, 0x56, 0x30, 0xee, 0x02, 0x7e, 0xe7, 0xf1,
+	0xf3, 0xf2, 0x32, 0xf3, 0x0b, 0x7b, 0x58, 0x29, 0x2f, 0xf3, 0x6f, 0xb5,
+	0x1f, 0x24, 0x2f, 0xe3, 0xd9, 0x04, 0x3f, 0x2f, 0x83, 0x9f, 0x0d, 0x1b,
+	0x64, 0x06, 0xf3, 0x32, 0xef, 0x53, 0x37, 0x50, 0xc7, 0x32, 0xeb, 0xa1,
+	0x23, 0xb0, 0x53, 0x19, 0xd8, 0x99, 0x69, 0xf7, 0xd7, 0xd5, 0x79, 0xcc,
+	0xb8, 0x53, 0xd8, 0x77, 0x02, 0xe7, 0x41, 0x5e, 0xb6, 0x2b, 0x5f, 0x34,
+	0x63, 0xc5, 0x8d, 0x6c, 0x27, 0xac, 0xda, 0x38, 0xbf, 0x9d, 0x5b, 0xc6,
+	0x50, 0x99, 0xf2, 0x1e, 0x31, 0x0a, 0xd8, 0x4b, 0xdf, 0xf8, 0x94, 0x0c,
+	0x95, 0x7d, 0x3f, 0xab, 0x5b, 0x9f, 0xc5, 0x94, 0xd2, 0xd3, 0x69, 0xf0,
+	0x00, 0x98, 0xb1, 0x06, 0x9b, 0x75, 0x16, 0x34, 0x07, 0xf7, 0x81, 0x18,
+	0xba, 0x07, 0x75, 0xea, 0xdc, 0xe9, 0x6f, 0xfa, 0xb4, 0x24, 0xa8, 0xf3,
+	0x6b, 0x98, 0x8f, 0x75, 0x67, 0x55, 0xfc, 0x56, 0xe8, 0xe1, 0x5e, 0x69,
+	0xfb, 0xe6, 0x40, 0x1f, 0xea, 0x66, 0x18, 0x33, 0xd2, 0x0e, 0xfa, 0x31,
+	0x5d, 0x54, 0xc5, 0x74, 0x9b, 0x15, 0x3f, 0xc8, 0xeb, 0x5f, 0x8b, 0x10,
+	0x3b, 0x37, 0x3b, 0xdc, 0xc3, 0x79, 0x8d, 0x7b, 0x2c, 0xfb, 0xb1, 0x23,
+	0xdf, 0xc9, 0xa7, 0xa7, 0x54, 0xde, 0x67, 0xda, 0xf5, 0xcf, 0xf0, 0x5b,
+	0xd8, 0x3b, 0xcb, 0xbd, 0x72, 0xa1, 0x59, 0x22, 0xb1, 0x34, 0x73, 0xbd,
+	0xf4, 0xd5, 0x77, 0x30, 0xf7, 0x50, 0xd3, 0xb4, 0x8a, 0xfe, 0xee, 0x5b,
+	0x45, 0x7f, 0xef, 0xae, 0xd2, 0xdf, 0xfe, 0x55, 0xf5, 0xf7, 0xeb, 0x91,
+	0xa0, 0xfe, 0xee, 0x5b, 0x45, 0x7f, 0x1f, 0xad, 0xd2, 0xdf, 0x83, 0x37,
+	0xa4, 0xbf, 0x3a, 0x36, 0x4e, 0xdd, 0xaa, 0x72, 0xc6, 0xc3, 0x13, 0xc4,
+	0xac, 0x4f, 0xeb, 0xdc, 0xd5, 0x4a, 0xbe, 0x98, 0x4f, 0x43, 0x5b, 0xcd,
+	0x47, 0xe3, 0x87, 0xfd, 0x23, 0xf6, 0xe9, 0xf9, 0xa3, 0xfd, 0xf0, 0x69,
+	0xaf, 0xbd, 0xee, 0x1f, 0x8b, 0x99, 0xf6, 0x7d, 0xc0, 0xad, 0x1f, 0xd1,
+	0xda, 0x6b, 0x91, 0x3f, 0xc6, 0x56, 0xf4, 0x07, 0xa2, 0xda, 0x66, 0x4e,
+	0x6a, 0x1d, 0xf4, 0xf3, 0x12, 0x41, 0x7d, 0xa6, 0x9c, 0x52, 0x36, 0x7f,
+	0x8a, 0x3d, 0x51, 0x3e, 0x7d, 0x0c, 0xd8, 0x52, 0xa5, 0x13, 0x73, 0x52,
+	0x00, 0x6e, 0x79, 0x3a, 0x41, 0x39, 0xeb, 0xc4, 0xbe, 0x61, 0x2b, 0xdd,
+	0xa7, 0xbd, 0xb3, 0x70, 0xf0, 0x9c, 0xf1, 0x75, 0x3f, 0x81, 0x75, 0xfd,
+	0x36, 0xda, 0x1e, 0x07, 0x3e, 0xd9, 0x36, 0xf8, 0x93, 0x2d, 0xc0, 0x19,
+	0xd6, 0x2f, 0xcd, 0x73, 0xaf, 0x8e, 0xb1, 0x52, 0x0c, 0xa3, 0xef, 0xe9,
+	0x1e, 0x60, 0x4e, 0x0f, 0x71, 0xb3, 0x84, 0xd8, 0x8c, 0x7a, 0x41, 0x5d,
+	0xe9, 0xe8, 0xda, 0x6d, 0xd2, 0xe7, 0x7b, 0x12, 0x71, 0xfc, 0x2d, 0x4a,
+	0xaf, 0x76, 0x97, 0x3b, 0x66, 0xdf, 0x30, 0xb9, 0x46, 0xa5, 0x92, 0x57,
+	0xdf, 0x19, 0xc4, 0x6c, 0xeb, 0xde, 0xb2, 0x8e, 0x36, 0xf3, 0x16, 0x27,
+	0xa4, 0xe5, 0x3e, 0x83, 0x77, 0xea, 0xd1, 0xeb, 0xf0, 0x47, 0x78, 0x47,
+	0xe1, 0x27, 0x2a, 0x5f, 0x37, 0xed, 0xd2, 0xf7, 0x60, 0xcc, 0xb4, 0x53,
+	0xf7, 0xdb, 0xa2, 0xbe, 0xb1, 0x66, 0x53, 0x3b, 0xf4, 0xf7, 0x36, 0xda,
+	0xc4, 0x24, 0x31, 0x75, 0xc9, 0x79, 0xf3, 0x8e, 0x47, 0x4e, 0xc5, 0x5c,
+	0x1c, 0xaf, 0x7c, 0x7f, 0xc4, 0x49, 0x56, 0xe0, 0xfb, 0x40, 0x44, 0xc7,
+	0x97, 0xd4, 0xf9, 0xa8, 0x8a, 0x7d, 0xbd, 0x78, 0x8a, 0xf1, 0xf7, 0xd2,
+	0xbb, 0x1d, 0x2b, 0xcb, 0x40, 0xcb, 0x07, 0x90, 0x81, 0xea, 0xf3, 0x8b,
+	0x00, 0x8b, 0xfc, 0xf3, 0xf3, 0x7d, 0xac, 0xbf, 0xd0, 0xfb, 0xde, 0xa2,
+	0xf5, 0xe9, 0xff, 0xc3, 0x3e, 0x8d, 0xc0, 0x3e, 0x7d, 0x6c, 0xfc, 0xa2,
+	0xde, 0xe7, 0xce, 0x2a, 0x6c, 0xec, 0x41, 0xfd, 0xe1, 0x9a, 0x8d, 0x1f,
+	0x10, 0x1b, 0xf7, 0xde, 0x10, 0x36, 0xfe, 0x70, 0xdd, 0x5a, 0xb1, 0xf1,
+	0xd0, 0x07, 0xc6, 0x46, 0xee, 0x6b, 0x65, 0x3c, 0xda, 0xb7, 0x0c, 0x8f,
+	0xfe, 0xe0, 0x13, 0xc4, 0xa3, 0xd5, 0xb0, 0x84, 0xe7, 0xd2, 0xa0, 0x7c,
+	0x6c, 0x4f, 0xff, 0xe0, 0x5f, 0xcc, 0x84, 0xe5, 0xc2, 0xbd, 0x11, 0x79,
+	0x6d, 0x27, 0xfc, 0x6e, 0xf2, 0x48, 0x9d, 0x07, 0xcb, 0xd1, 0x3a, 0xcf,
+	0x36, 0xc6, 0x1b, 0xbd, 0x9c, 0x02, 0xc7, 0xf8, 0x3a, 0x6d, 0xa3, 0x9d,
+	0x6d, 0x5b, 0xe4, 0xf5, 0xc6, 0x1b, 0x89, 0x53, 0xf9, 0x8d, 0x66, 0xa5,
+	0x38, 0x75, 0xf5, 0x9c, 0xe6, 0x62, 0x9c, 0x4a, 0xac, 0x6d, 0xd4, 0x79,
+	0x2c, 0xc6, 0x67, 0xfb, 0x35, 0x7e, 0xf2, 0x1d, 0xf1, 0xb8, 0x8b, 0x58,
+	0xdc, 0x45, 0x1c, 0xee, 0x22, 0x46, 0x87, 0x6d, 0x7e, 0x01, 0x32, 0xf7,
+	0x6d, 0x17, 0x31, 0xb8, 0x8b, 0x18, 0xdc, 0xed, 0xd2, 0x71, 0x7c, 0xbf,
+	0xfe, 0x76, 0xc1, 0xef, 0xfb, 0xcc, 0x83, 0x14, 0x61, 0x57, 0x46, 0x79,
+	0x3f, 0xc3, 0xcc, 0xa6, 0xd6, 0xe9, 0xfd, 0xf9, 0x79, 0xfd, 0x56, 0x9d,
+	0x5b, 0xda, 0xb4, 0x49, 0xf9, 0x0b, 0xe6, 0x2b, 0x75, 0xde, 0x1d, 0x00,
+	0xde, 0x23, 0x79, 0x14, 0xbe, 0x92, 0xba, 0x87, 0x45, 0x3d, 0xad, 0x98,
+	0x69, 0xe6, 0x8e, 0xc4, 0x34, 0xd3, 0x77, 0x60, 0xcc, 0x36, 0x2f, 0x66,
+	0x89, 0x49, 0xc8, 0x4c, 0xd7, 0x93, 0xa7, 0x86, 0x99, 0x5e, 0xaf, 0xe7,
+	0x9a, 0xaf, 0xf3, 0xfc, 0xbd, 0x4e, 0x96, 0x2d, 0x33, 0xfd, 0x59, 0x3e,
+	0x71, 0xee, 0x7e, 0xfd, 0x3d, 0x8d, 0x4b, 0xd7, 0x1a, 0x53, 0x18, 0x9f,
+	0x4d, 0xdd, 0x8b, 0xf9, 0xd4, 0xfd, 0xa7, 0x05, 0x7e, 0x9b, 0xd7, 0xe4,
+	0xf7, 0x98, 0xe6, 0xb7, 0xc7, 0xe3, 0x10, 0xfb, 0xa9, 0xdc, 0x36, 0x79,
+	0xed, 0xcf, 0xa7, 0x72, 0x93, 0x58, 0x47, 0xdd, 0x01, 0xc1, 0xb3, 0x62,
+	0x49, 0xc3, 0xc0, 0x7d, 0x61, 0x27, 0xb8, 0xae, 0xff, 0x2d, 0x7f, 0x2d,
+	0x6b, 0x6e, 0x51, 0xdf, 0x07, 0x3d, 0xbb, 0x31, 0xa6, 0x64, 0xd0, 0x4a,
+	0x73, 0x5f, 0xef, 0x43, 0xfe, 0xc6, 0x94, 0xfc, 0xe5, 0x10, 0x67, 0x8d,
+	0xf6, 0x74, 0x24, 0x2c, 0x73, 0xba, 0x8e, 0x39, 0xe4, 0xbe, 0xb2, 0x8f,
+	0x7d, 0x5c, 0xaf, 0xda, 0xa6, 0x33, 0xff, 0xe7, 0x63, 0x9a, 0xb4, 0x78,
+	0x79, 0xc1, 0xb5, 0xde, 0xa9, 0x58, 0xd4, 0xa5, 0xc1, 0x05, 0x5d, 0xaa,
+	0xab, 0xd2, 0x25, 0x7f, 0x9f, 0xeb, 0xc5, 0xff, 0xe6, 0xbe, 0xd2, 0x5d,
+	0x90, 0xb9, 0x72, 0xe0, 0x1b, 0xcf, 0x82, 0x6c, 0xf0, 0x4e, 0xcc, 0x3d,
+	0x90, 0x41, 0x7e, 0xdf, 0xd8, 0x03, 0x3d, 0xaa, 0x54, 0xfa, 0x98, 0x27,
+	0xdf, 0xde, 0xaf, 0xef, 0x5b, 0x5c, 0x51, 0x39, 0x12, 0x6b, 0x59, 0x8e,
+	0xa4, 0x0f, 0xb2, 0x02, 0x3f, 0x00, 0x3a, 0x98, 0x57, 0x67, 0x49, 0x9f,
+	0xa0, 0xfa, 0x1b, 0xd2, 0xc5, 0x7a, 0x8f, 0x0f, 0x9d, 0xf5, 0xde, 0x77,
+	0x14, 0x73, 0xd3, 0xd2, 0x32, 0xc7, 0x27, 0xea, 0x3d, 0x59, 0x39, 0x06,
+	0xfb, 0xdc, 0x07, 0x59, 0xac, 0x91, 0x9c, 0x9a, 0xef, 0x98, 0xe4, 0x9f,
+	0xfd, 0xcf, 0xc6, 0xa5, 0xfd, 0x51, 0x77, 0xd2, 0xef, 0xff, 0x78, 0x55,
+	0xff, 0xc7, 0xd1, 0xff, 0x67, 0x55, 0xfd, 0x1f, 0x0f, 0xf4, 0x3f, 0xa1,
+	0xfb, 0xd7, 0xa2, 0xbf, 0xd2, 0x83, 0x26, 0xdf, 0x2f, 0x36, 0x1d, 0xc4,
+	0xb3, 0xcf, 0xfa, 0x63, 0x4e, 0x04, 0xc6, 0x4c, 0x56, 0xad, 0x31, 0x89,
+	0x7e, 0xf1, 0xa6, 0xa5, 0x6b, 0xa0, 0xee, 0x64, 0x8d, 0xfe, 0xbe, 0x47,
+	0x9f, 0xe5, 0xa0, 0xce, 0x17, 0xe0, 0x59, 0x0a, 0x7e, 0x33, 0xe2, 0x77,
+	0x0a, 0xca, 0x9e, 0xff, 0x8d, 0xc2, 0xbf, 0x93, 0x47, 0xbd, 0xcd, 0x40,
+	0x6f, 0x17, 0xfd, 0x1a, 0x4f, 0x2e, 0x83, 0x32, 0x49, 0x9c, 0x28, 0x4a,
+	0xc8, 0x29, 0xd3, 0x57, 0x32, 0x0a, 0x33, 0xbe, 0x7d, 0xe2, 0xbd, 0x2b,
+	0xde, 0xd7, 0xf5, 0xec, 0x70, 0xd8, 0x99, 0xd3, 0x31, 0xe2, 0xaf, 0x90,
+	0x7e, 0xe0, 0xa6, 0x8f, 0x9d, 0x72, 0xcc, 0xd3, 0x1f, 0xca, 0x31, 0xe7,
+	0xd7, 0x7a, 0x44, 0x99, 0xd5, 0xeb, 0xf4, 0x2d, 0xc3, 0xb7, 0xc4, 0xb2,
+	0x3c, 0x5c, 0x68, 0x0d, 0xf8, 0xd6, 0xbf, 0x80, 0x6f, 0xf7, 0xca, 0x94,
+	0x9d, 0x50, 0x79, 0xd0, 0x43, 0x0b, 0x79, 0x81, 0xc3, 0x91, 0x46, 0x87,
+	0x79, 0x81, 0xe4, 0xa9, 0x8c, 0x7c, 0xb0, 0xbc, 0xc0, 0xbe, 0x2a, 0x1d,
+	0xd9, 0xbb, 0xaa, 0xed, 0xfc, 0xb3, 0xfa, 0xb5, 0xe6, 0x05, 0x1e, 0xa9,
+	0xb2, 0x63, 0x87, 0x6e, 0xc0, 0x76, 0xe6, 0x95, 0xed, 0xe4, 0x5e, 0xaf,
+	0xe7, 0xcb, 0x7f, 0x25, 0xf2, 0xd1, 0xd8, 0xce, 0xd5, 0x72, 0xe2, 0x41,
+	0x7b, 0x40, 0xb9, 0xba, 0xac, 0xfd, 0x6c, 0x3c, 0x67, 0x2e, 0x43, 0x3f,
+	0x4d, 0x19, 0x54, 0xb2, 0xcc, 0xb2, 0x1f, 0xff, 0xde, 0xb7, 0x10, 0xff,
+	0x2e, 0xc6, 0xac, 0xf0, 0x67, 0xbb, 0xfc, 0xd8, 0x88, 0x7e, 0xb3, 0x6d,
+	0x14, 0xdc, 0x3d, 0xe6, 0x90, 0x6a, 0x63, 0x8e, 0xf7, 0x36, 0xf9, 0x9c,
+	0xba, 0x27, 0x70, 0x5e, 0xe7, 0xd2, 0xa6, 0x54, 0x4c, 0xc0, 0xef, 0x1c,
+	0x85, 0xd4, 0x46, 0xed, 0x03, 0x5e, 0x0f, 0x67, 0x97, 0xc6, 0xcf, 0xa6,
+	0x79, 0x04, 0x63, 0x19, 0x3f, 0x7f, 0x21, 0x4a, 0x4c, 0xcd, 0x96, 0x57,
+	0x1d, 0x8f, 0x71, 0x1c, 0xcf, 0x3e, 0x2a, 0x56, 0x46, 0xbf, 0x39, 0x3d,
+	0xde, 0x8b, 0x95, 0xb3, 0xe5, 0xad, 0x51, 0x0f, 0x17, 0x57, 0x8b, 0x63,
+	0x8e, 0x44, 0x99, 0x8b, 0x9c, 0x73, 0xaf, 0x47, 0xeb, 0xf2, 0xd8, 0x3c,
+	0xb4, 0x2c, 0x36, 0xb7, 0x74, 0xec, 0x7d, 0xbf, 0x8a, 0xcd, 0x3d, 0x1e,
+	0x73, 0x2f, 0xc1, 0xd8, 0xca, 0x01, 0x36, 0xf2, 0x5b, 0x10, 0xb1, 0x82,
+	0x3e, 0x0b, 0xe4, 0x67, 0xfc, 0x37, 0x94, 0x1f, 0xb3, 0x5c, 0x7e, 0x3e,
+	0x6e, 0xbb, 0xe1, 0xef, 0xfd, 0xb2, 0x78, 0xf9, 0xc5, 0x3d, 0xa0, 0x85,
+	0xf1, 0x56, 0x58, 0xcb, 0xc3, 0xcf, 0x69, 0xfc, 0xf6, 0xfb, 0xf9, 0xb9,
+	0x86, 0x85, 0x6f, 0xc9, 0xc5, 0xcc, 0x92, 0x1c, 0xcf, 0x16, 0xa6, 0xce,
+	0x71, 0xee, 0x99, 0x1b, 0xf8, 0xde, 0xf2, 0x61, 0xee, 0x7c, 0x54, 0xdb,
+	0xb9, 0x57, 0x21, 0xfb, 0x09, 0x7d, 0xff, 0xaf, 0x0b, 0x3a, 0xc0, 0x3b,
+	0xd0, 0xd5, 0x58, 0xab, 0xee, 0xf9, 0x45, 0x36, 0xa5, 0xf9, 0xed, 0x82,
+	0x3e, 0xc1, 0x4f, 0xf4, 0x5e, 0xe3, 0x72, 0x6c, 0xc2, 0xcb, 0xd3, 0x9a,
+	0xab, 0xde, 0xf1, 0xbb, 0x04, 0x5e, 0x24, 0x8f, 0xfa, 0x79, 0x5a, 0xd3,
+	0xbb, 0xe3, 0x77, 0xf4, 0xa3, 0xbb, 0xe3, 0xc7, 0xf9, 0x2d, 0xd9, 0xbb,
+	0xc2, 0x1d, 0xbf, 0xd0, 0x1a, 0xef, 0xf8, 0x6d, 0x54, 0x79, 0x5a, 0xce,
+	0xe3, 0xe5, 0x69, 0x59, 0x6e, 0xeb, 0xfe, 0x94, 0xc2, 0xa8, 0xe9, 0x09,
+	0xe6, 0x75, 0x1e, 0x5c, 0xf7, 0xc9, 0xe4, 0x75, 0xde, 0x8b, 0x7e, 0xfc,
+	0x79, 0x1d, 0x7e, 0x17, 0xf8, 0xb2, 0xf7, 0xdd, 0x5a, 0x6e, 0x24, 0x3f,
+	0xf0, 0xe1, 0x72, 0xb0, 0x07, 0x55, 0x0e, 0x76, 0xfb, 0xfa, 0x60, 0x0e,
+	0xd6, 0xbc, 0xce, 0x3d, 0xb8, 0x83, 0x2b, 0xe4, 0x60, 0xc3, 0x81, 0x7b,
+	0x70, 0x61, 0x7d, 0x0f, 0x6e, 0xa3, 0x83, 0x18, 0x53, 0xe7, 0x5b, 0xcd,
+	0x55, 0xef, 0xc1, 0xed, 0x5e, 0xff, 0xe1, 0xf3, 0xad, 0xcb, 0xee, 0xc1,
+	0x1d, 0xcd, 0x48, 0x8b, 0x24, 0x6e, 0x28, 0x16, 0xfa, 0x30, 0x71, 0x10,
+	0xff, 0x8f, 0x40, 0x0d, 0xf6, 0x0c, 0x99, 0x8f, 0x51, 0x3e, 0x29, 0x77,
+	0x69, 0x33, 0x5f, 0xe6, 0x7b, 0x17, 0xcf, 0xc7, 0xe8, 0xef, 0x5c, 0x7a,
+	0xb7, 0x62, 0xf1, 0x6e, 0x72, 0x64, 0xe1, 0x6e, 0xf2, 0x18, 0x64, 0xc6,
+	0x9c, 0x88, 0xc8, 0x74, 0xc0, 0xb6, 0x8e, 0xba, 0xf0, 0x9b, 0x26, 0x6d,
+	0xdd, 0xce, 0xff, 0xa7, 0x82, 0xb8, 0xb0, 0xc4, 0xfb, 0xcc, 0x0d, 0x12,
+	0x9a, 0x54, 0x98, 0x1a, 0xf3, 0xfe, 0xaf, 0x4e, 0x1c, 0x7d, 0x78, 0x77,
+	0x35, 0x2c, 0x87, 0x62, 0x94, 0x65, 0x5f, 0x8e, 0xbf, 0x05, 0xfe, 0x36,
+	0x65, 0x16, 0xcb, 0x31, 0x2d, 0xd7, 0x94, 0x69, 0x5f, 0xfe, 0x62, 0x32,
+	0x32, 0x41, 0x59, 0xde, 0xa1, 0xff, 0x9f, 0xc4, 0x39, 0x29, 0x94, 0xcf,
+	0xea, 0x78, 0x43, 0x7d, 0x8b, 0x02, 0x1f, 0x5b, 0xb4, 0x0d, 0xc6, 0x73,
+	0xa6, 0x85, 0x36, 0x8f, 0xdf, 0x1e, 0xa5, 0x6f, 0x7c, 0x5b, 0x7c, 0x08,
+	0x78, 0x37, 0xa8, 0x72, 0x27, 0x37, 0xc2, 0x6f, 0xe3, 0x1a, 0xdf, 0x48,
+	0xd7, 0xca, 0x73, 0xdf, 0x5f, 0xbe, 0x8c, 0xfd, 0xb5, 0x40, 0x36, 0xbe,
+	0x2a, 0xb9, 0x93, 0xb7, 0x49, 0xdf, 0x89, 0x24, 0xe8, 0x79, 0xbf, 0x52,
+	0x48, 0xc1, 0xb7, 0x7e, 0x96, 0x77, 0xe1, 0x80, 0xa1, 0x2e, 0x30, 0x14,
+	0xbc, 0x7b, 0x61, 0x99, 0xbf, 0x11, 0xbc, 0x43, 0x97, 0x5a, 0xb8, 0x13,
+	0xf5, 0x7c, 0x59, 0x22, 0x8d, 0xa4, 0x7b, 0x62, 0xf1, 0x2e, 0xfc, 0x5c,
+	0x39, 0xa7, 0xec, 0xdb, 0x73, 0xe5, 0x25, 0x39, 0x21, 0x75, 0x8e, 0xc3,
+	0xa5, 0x97, 0x61, 0xe3, 0x2e, 0x1b, 0xb4, 0x71, 0x63, 0xae, 0xdc, 0x12,
+	0x12, 0x9e, 0x89, 0x18, 0xe0, 0x83, 0xba, 0x9b, 0xe2, 0xdd, 0x4d, 0x68,
+	0x55, 0x67, 0xfb, 0x7f, 0xd4, 0x5d, 0x7d, 0x6c, 0x5b, 0xd7, 0x75, 0x3f,
+	0x7c, 0xa4, 0x3e, 0x4c, 0xcb, 0xd2, 0x93, 0x4c, 0xc9, 0xb4, 0x2d, 0xcb,
+	0x8f, 0xd2, 0x93, 0xa5, 0xc4, 0x4a, 0xc1, 0x79, 0xda, 0xaa, 0x01, 0x5a,
+	0xc7, 0x52, 0xf4, 0xc7, 0x82, 0x60, 0xa5, 0x65, 0x25, 0xf3, 0xd2, 0x2c,
+	0x51, 0x29, 0xdb, 0xc9, 0xfe, 0x18, 0xe0, 0x25, 0xd9, 0x9a, 0xfd, 0x51,
+	0xe4, 0x95, 0x94, 0x12, 0x63, 0x56, 0x4d, 0xc6, 0xe6, 0x84, 0x02, 0x0b,
+	0x36, 0x56, 0x92, 0x9d, 0x14, 0x50, 0xc0, 0x24, 0x6d, 0x87, 0x2c, 0x6d,
+	0x11, 0x55, 0x76, 0xda, 0x7f, 0x8d, 0x2d, 0xc0, 0xb2, 0x2e, 0x69, 0x14,
+	0x3b, 0xc8, 0x02, 0x2c, 0x58, 0xbb, 0x6e, 0x28, 0xf6, 0x4f, 0xc7, 0x9d,
+	0xdf, 0xfd, 0x20, 0x1f, 0xc9, 0x47, 0x7d, 0x24, 0x6e, 0x81, 0x09, 0x10,
+	0xc8, 0xf7, 0xde, 0x7d, 0xef, 0xdd, 0x7b, 0xee, 0xf9, 0xf8, 0x9d, 0x73,
+	0xcf, 0xb9, 0x94, 0xba, 0xe2, 0x35, 0x57, 0x6e, 0x49, 0x65, 0x7e, 0x65,
+	0xce, 0x89, 0x9c, 0x0f, 0x95, 0x43, 0x0b, 0x9a, 0x3a, 0x27, 0x6d, 0x99,
+	0x17, 0x33, 0xb0, 0x80, 0x73, 0x3d, 0x35, 0xf6, 0xaf, 0x95, 0xf9, 0xc0,
+	0x14, 0x31, 0x85, 0x69, 0x13, 0x7d, 0xde, 0x2b, 0xf4, 0x81, 0xf7, 0xba,
+	0x7c, 0x40, 0xe9, 0xbc, 0x56, 0xa5, 0xa3, 0x36, 0xc2, 0x6f, 0xf2, 0x9d,
+	0xfd, 0xe2, 0x9d, 0xdd, 0x4a, 0x67, 0xe9, 0xdc, 0xf7, 0x71, 0x63, 0xba,
+	0x08, 0x5f, 0x9b, 0xe9, 0x52, 0x87, 0xdf, 0xac, 0x4d, 0xe8, 0xf8, 0xb9,
+	0x3a, 0x3a, 0x56, 0xcb, 0x03, 0xfb, 0xe6, 0x65, 0x9d, 0x2d, 0x69, 0x26,
+	0xcf, 0x23, 0x9f, 0x5f, 0xe7, 0x65, 0x48, 0x9a, 0x95, 0xe5, 0xe7, 0x92,
+	0x3b, 0x27, 0xa3, 0x42, 0xb3, 0xe9, 0x32, 0xcd, 0xf6, 0xfc, 0x3f, 0xa0,
+	0xd9, 0x4d, 0x81, 0x79, 0x5f, 0x29, 0x22, 0xff, 0x6e, 0x58, 0xe4, 0x2e,
+	0xac, 0xd2, 0x88, 0xb2, 0xff, 0xee, 0x1a, 0x28, 0xd0, 0x12, 0xba, 0x34,
+	0x52, 0x58, 0xa7, 0x98, 0x8c, 0x43, 0x98, 0xa5, 0xd2, 0x77, 0xa2, 0x90,
+	0x3f, 0xf8, 0x24, 0xf0, 0x51, 0x10, 0xdf, 0x3b, 0xc9, 0x63, 0xfb, 0x97,
+	0x60, 0xd7, 0x06, 0x36, 0xf2, 0xe4, 0x36, 0x7c, 0x94, 0x8a, 0x8d, 0x04,
+	0x5e, 0x22, 0x27, 0x6e, 0x57, 0xf2, 0x5e, 0x66, 0xb3, 0x3f, 0x6c, 0x67,
+	0x3f, 0x92, 0x69, 0x5c, 0x79, 0xee, 0xd6, 0x7c, 0x14, 0x3c, 0x4f, 0xda,
+	0xc9, 0xd9, 0x6c, 0xe5, 0xb9, 0x4e, 0xf9, 0xb9, 0x61, 0x0f, 0x5d, 0x65,
+	0xd1, 0xcc, 0xa5, 0x7d, 0x75, 0xf9, 0x6a, 0x95, 0xf1, 0x48, 0x5f, 0x45,
+	0x8f, 0xe7, 0xc9, 0x4d, 0xf1, 0xa5, 0xcc, 0x3b, 0xab, 0xe4, 0xf0, 0xd4,
+	0xfa, 0x29, 0xfb, 0x5d, 0xf1, 0x19, 0xd0, 0xf8, 0x0f, 0x69, 0x75, 0x12,
+	0x7a, 0xae, 0x96, 0xd6, 0xef, 0xff, 0x9a, 0x68, 0x1d, 0xe9, 0xf8, 0xf5,
+	0xd2, 0x7a, 0x7f, 0x5d, 0x2c, 0xbc, 0x32, 0x1e, 0x0a, 0x75, 0x6f, 0x0b,
+	0xcb, 0xd7, 0xd2, 0x7a, 0x7f, 0xc3, 0x78, 0x6a, 0xe3, 0x5c, 0xcc, 0xea,
+	0x78, 0x6a, 0xbf, 0xc1, 0x32, 0x92, 0x65, 0x79, 0x69, 0xa8, 0xe3, 0xff,
+	0xce, 0x15, 0x6f, 0x75, 0xeb, 0x79, 0xc8, 0x1a, 0xf9, 0x4e, 0x0e, 0xe9,
+	0x77, 0x42, 0xae, 0x22, 0x8e, 0x43, 0xf0, 0x9f, 0xf0, 0x5e, 0xe4, 0x62,
+	0xd5, 0xe1, 0x2e, 0x7e, 0x2f, 0xcb, 0xff, 0x0b, 0xcf, 0x0b, 0x9b, 0x25,
+	0x63, 0x12, 0x68, 0x1f, 0xf2, 0x9d, 0x11, 0x6d, 0x65, 0x8e, 0x96, 0x8a,
+	0x51, 0x28, 0x3f, 0xa0, 0x51, 0x6c, 0xa2, 0xde, 0xfe, 0x6d, 0xcf, 0x6f,
+	0xd0, 0xf1, 0x88, 0x83, 0x3c, 0x3f, 0xe1, 0x2a, 0xbf, 0x0b, 0xfa, 0xf4,
+	0x3c, 0x63, 0x84, 0xfe, 0x32, 0x3e, 0xa8, 0x9e, 0xa3, 0x59, 0xe1, 0xdf,
+	0x69, 0x5d, 0xba, 0x2a, 0x73, 0x6b, 0xc5, 0x79, 0xe0, 0xb5, 0xb2, 0x2e,
+	0xad, 0xc1, 0xc3, 0x07, 0x3d, 0xf8, 0xc3, 0xb3, 0x9e, 0x55, 0xcf, 0xa1,
+	0x85, 0x9c, 0xfa, 0x84, 0xe7, 0x1c, 0x96, 0xeb, 0xd2, 0x9c, 0x4a, 0x5b,
+	0x79, 0x7f, 0x42, 0x8c, 0x6b, 0xea, 0xde, 0x38, 0xea, 0xef, 0xca, 0x35,
+	0x51, 0xb5, 0x75, 0x60, 0xb0, 0x0b, 0x5a, 0x1e, 0x75, 0xcd, 0x39, 0x68,
+	0xd1, 0xe7, 0x51, 0x07, 0xe6, 0xb6, 0x2d, 0xb8, 0xaf, 0x96, 0x16, 0x15,
+	0xbb, 0x32, 0xa7, 0xec, 0xca, 0xa2, 0x4b, 0xaf, 0xd7, 0xe3, 0xf7, 0x2e,
+	0x0f, 0xfc, 0xee, 0x55, 0x0b, 0x86, 0x3e, 0x3d, 0xc5, 0x98, 0xe4, 0x33,
+	0xc0, 0x24, 0x26, 0x6a, 0xb1, 0x24, 0x2e, 0xc1, 0xf5, 0x1c, 0x63, 0x93,
+	0x30, 0xf3, 0xca, 0x6b, 0x74, 0x8e, 0x31, 0xf7, 0x35, 0xba, 0x4b, 0xf9,
+	0x69, 0x90, 0x5f, 0x9d, 0x47, 0x8b, 0x5a, 0x06, 0x1f, 0x39, 0x0f, 0x45,
+	0x86, 0x63, 0xf4, 0x1a, 0x9d, 0x15, 0xf9, 0x3e, 0x58, 0xff, 0x43, 0x9e,
+	0xc4, 0xdd, 0xe2, 0xfd, 0x32, 0xae, 0x71, 0x27, 0xf2, 0x02, 0xb7, 0x5e,
+	0x9f, 0xa0, 0xea, 0x05, 0xb9, 0x1d, 0xde, 0xb9, 0xac, 0x64, 0x4a, 0x9c,
+	0xe3, 0xfb, 0x9f, 0x32, 0xea, 0xef, 0x8f, 0x19, 0x89, 0x62, 0xc2, 0x88,
+	0x2f, 0xa1, 0xdd, 0x53, 0xc6, 0x44, 0x11, 0xbe, 0xa4, 0xe6, 0x91, 0x48,
+	0x14, 0xf2, 0xb6, 0x46, 0x9b, 0xaf, 0x53, 0x2c, 0x52, 0x4d, 0xad, 0xc8,
+	0x16, 0xfa, 0x7d, 0xac, 0xaa, 0xdf, 0x9a, 0xbe, 0xf8, 0x8e, 0xd8, 0xcf,
+	0xcb, 0x4c, 0x53, 0x8d, 0x71, 0x83, 0x88, 0xbd, 0x0f, 0x3b, 0xb4, 0x11,
+	0xc6, 0x8d, 0xd4, 0x61, 0xdc, 0xc5, 0x4d, 0xfb, 0xfd, 0x69, 0x65, 0x5c,
+	0xd6, 0x7c, 0xfb, 0x6d, 0x81, 0x65, 0xb9, 0xdf, 0x55, 0x38, 0xb7, 0x86,
+	0xa7, 0xd0, 0x46, 0xc7, 0xc8, 0x75, 0x4c, 0xac, 0x5d, 0xc5, 0x74, 0x75,
+	0x3e, 0x45, 0x50, 0xc5, 0xb4, 0x71, 0x1d, 0xbe, 0xd6, 0x2a, 0xf7, 0x0f,
+	0x7e, 0x17, 0xe2, 0x3f, 0x6e, 0xbf, 0xcb, 0x1d, 0xf3, 0xf5, 0xaa, 0x0d,
+	0xed, 0xf7, 0xa8, 0x0d, 0x75, 0xcb, 0x59, 0xc0, 0x25, 0x67, 0x61, 0x17,
+	0x86, 0xeb, 0x65, 0xff, 0xa5, 0x8d, 0xf5, 0x07, 0xfc, 0x97, 0x20, 0xf9,
+	0x2f, 0xbb, 0xfd, 0x97, 0xda, 0x3a, 0x7f, 0xc8, 0x1c, 0x70, 0x9a, 0xf4,
+	0x65, 0x12, 0xf9, 0xf2, 0x1e, 0x01, 0x3c, 0xe6, 0x4a, 0x1d, 0xe6, 0x52,
+	0x5d, 0xcd, 0xa8, 0x57, 0x7f, 0xfb, 0xea, 0xfa, 0x0b, 0x1b, 0x16, 0x6b,
+	0x88, 0xef, 0xbc, 0xfc, 0xab, 0x3b, 0xd5, 0xbf, 0x5a, 0x5d, 0x86, 0x77,
+	0xf5, 0x8b, 0x18, 0xb8, 0x53, 0xd6, 0x63, 0x63, 0xb2, 0xbf, 0xd9, 0x6a,
+	0x5f, 0xc3, 0x7f, 0x89, 0x14, 0xed, 0xbc, 0xf5, 0xfa, 0xf6, 0xe2, 0x68,
+	0x3b, 0x6b, 0x6c, 0xef, 0x78, 0xa7, 0x8c, 0x8f, 0xcd, 0xa9, 0x3c, 0xf2,
+	0x6e, 0xe5, 0xf7, 0x6d, 0xc6, 0xeb, 0x38, 0x37, 0xa7, 0x62, 0x8a, 0x11,
+	0xab, 0x40, 0xe0, 0xf1, 0xc9, 0xd3, 0x4d, 0xb6, 0xa9, 0xd6, 0xb8, 0xb0,
+	0x8e, 0x05, 0x9e, 0xd7, 0xcf, 0x97, 0x35, 0x65, 0x9b, 0xcf, 0x99, 0x55,
+	0x37, 0x67, 0x92, 0xaf, 0xe0, 0x6f, 0x21, 0x3f, 0x7a, 0xa4, 0x26, 0x47,
+	0xfd, 0xd3, 0xd0, 0xa2, 0xdd, 0x23, 0x6f, 0x1b, 0x79, 0xd7, 0x8d, 0xfa,
+	0xb9, 0xee, 0xc2, 0xea, 0xb2, 0x6e, 0x63, 0x95, 0xd0, 0xef, 0x52, 0xe9,
+	0xe5, 0x28, 0xb0, 0x69, 0x6f, 0x1d, 0xaf, 0x69, 0xbc, 0x64, 0xba, 0xfa,
+	0xf9, 0xf8, 0xc6, 0xfd, 0xac, 0xb1, 0xbf, 0x7b, 0x3d, 0xec, 0x6f, 0x23,
+	0x5f, 0x42, 0xec, 0x9d, 0xe2, 0x3b, 0x2a, 0x74, 0x41, 0x1b, 0x2d, 0xe5,
+	0x91, 0x4b, 0xfe, 0x1b, 0xa8, 0x67, 0x65, 0x7d, 0xeb, 0xaa, 0xcf, 0xf3,
+	0x9e, 0xd3, 0xf2, 0x7a, 0x4b, 0x60, 0x1c, 0xeb, 0x83, 0xc8, 0x41, 0xe9,
+	0x62, 0x1d, 0x84, 0xf6, 0x83, 0xd6, 0x0d, 0xc4, 0x80, 0x55, 0x3c, 0x2a,
+	0xa1, 0xec, 0xcc, 0xd1, 0x2d, 0xac, 0xbb, 0x6c, 0x4f, 0x5f, 0x47, 0xac,
+	0x55, 0xc2, 0x9a, 0x10, 0xf2, 0x9e, 0x9d, 0x76, 0x6a, 0xbf, 0xbf, 0xa5,
+	0xc5, 0xbe, 0xd9, 0x29, 0xd7, 0xaa, 0x70, 0xad, 0x8d, 0xae, 0xe6, 0x91,
+	0x97, 0x8e, 0x6b, 0x0f, 0xf2, 0x35, 0x2f, 0x7d, 0xf5, 0xb6, 0xe2, 0x25,
+	0x60, 0x3a, 0x39, 0x47, 0x05, 0x92, 0x73, 0xb6, 0x4e, 0xf0, 0xa5, 0x4a,
+	0xf4, 0x4f, 0xd1, 0xdf, 0x14, 0xfe, 0x5f, 0x65, 0xae, 0xb6, 0xb7, 0x8e,
+	0x53, 0x9b, 0x03, 0x31, 0xb9, 0x61, 0x1c, 0xb1, 0xa3, 0x6b, 0xab, 0xeb,
+	0x38, 0xb5, 0x39, 0x10, 0x8f, 0x6f, 0x29, 0x8e, 0x18, 0xb1, 0xa6, 0x37,
+	0xac, 0x33, 0x70, 0xaf, 0xa9, 0xe8, 0xb5, 0xe4, 0x51, 0x51, 0x7b, 0xeb,
+	0xe6, 0x89, 0x3b, 0xb3, 0x9e, 0x0c, 0xde, 0xe8, 0xab, 0xd3, 0x61, 0x77,
+	0x60, 0x3d, 0xa0, 0x86, 0xb6, 0x41, 0xcf, 0x58, 0x96, 0xf7, 0xba, 0x31,
+	0x72, 0x04, 0x10, 0xc3, 0x2e, 0xd2, 0x99, 0x2b, 0xe0, 0x67, 0x83, 0x39,
+	0x6f, 0x80, 0x32, 0x21, 0xd4, 0x52, 0x89, 0xba, 0x28, 0xbd, 0xbe, 0x28,
+	0xea, 0xa3, 0xce, 0x88, 0xba, 0xcf, 0xc1, 0xf0, 0x6d, 0xb6, 0x91, 0x67,
+	0x8a, 0x6f, 0xd1, 0xd9, 0xa5, 0x20, 0xff, 0x57, 0xf0, 0x7c, 0x7d, 0xed,
+	0x67, 0x35, 0xbf, 0xdf, 0x16, 0xfc, 0xde, 0xbb, 0x21, 0xbf, 0x1f, 0x2f,
+	0xf3, 0x3b, 0x77, 0x28, 0x28, 0x6b, 0x2b, 0x53, 0x57, 0xda, 0xe9, 0xa8,
+	0x78, 0xee, 0x5b, 0xfc, 0x7d, 0x27, 0x1d, 0x35, 0xe5, 0xf7, 0xb3, 0x4b,
+	0xac, 0xfb, 0xb3, 0x6f, 0xd1, 0xb9, 0x2b, 0x8e, 0x2f, 0x21, 0xea, 0x32,
+	0xdc, 0x7b, 0x86, 0xe8, 0xfb, 0xd1, 0xce, 0x4b, 0x16, 0xea, 0xf5, 0x55,
+	0x41, 0xea, 0x2b, 0xba, 0x29, 0x62, 0x20, 0xde, 0xfa, 0x0a, 0xfc, 0x79,
+	0x5e, 0xd9, 0xc6, 0xc9, 0x0d, 0x62, 0x1f, 0xf5, 0xbc, 0xd9, 0xe9, 0x81,
+	0x91, 0xbf, 0xdb, 0x25, 0xd7, 0xb1, 0x36, 0x8a, 0x81, 0x54, 0xe5, 0x81,
+	0xb8, 0xd7, 0xf9, 0xd9, 0x1e, 0x4c, 0xaa, 0x75, 0xf7, 0x9f, 0x76, 0x49,
+	0x3b, 0x82, 0x9a, 0xc8, 0x55, 0xa6, 0xc3, 0x3f, 0x30, 0x7e, 0xd9, 0x4f,
+	0xcd, 0x97, 0xf5, 0x58, 0xf7, 0x0b, 0x7f, 0xc8, 0x1d, 0xcb, 0x99, 0x55,
+	0x35, 0xee, 0x69, 0xd7, 0x98, 0x66, 0x85, 0xdf, 0xf3, 0x49, 0xd6, 0x31,
+	0x7b, 0x6b, 0x6c, 0x45, 0x2d, 0xbf, 0x61, 0x3f, 0x16, 0xcc, 0x2f, 0x19,
+	0x12, 0x1b, 0x8f, 0x31, 0xe6, 0xdd, 0xee, 0x7a, 0xd2, 0xa7, 0xc5, 0x8d,
+	0xb5, 0x7b, 0x7d, 0xd4, 0x7e, 0xc7, 0x3c, 0x48, 0x3f, 0x24, 0xf5, 0x42,
+	0x51, 0xe8, 0x82, 0xd9, 0x91, 0x12, 0x4d, 0x44, 0x77, 0x51, 0x6a, 0x84,
+	0xdf, 0x3d, 0x66, 0xb3, 0x3f, 0xe6, 0x27, 0x87, 0xe5, 0x37, 0x35, 0xb2,
+	0x43, 0xd5, 0xcc, 0xe9, 0x58, 0x7b, 0x8b, 0xc2, 0x90, 0xed, 0x62, 0xdd,
+	0x52, 0xee, 0x49, 0xc4, 0xdf, 0x97, 0xf4, 0xb3, 0x71, 0x1e, 0xbc, 0xdb,
+	0xac, 0xda, 0x5d, 0x74, 0xb5, 0x43, 0x9b, 0x8b, 0xaa, 0x2d, 0x9e, 0xa9,
+	0xb1, 0x86, 0xae, 0xd3, 0x82, 0x1c, 0xae, 0xaa, 0xfa, 0x44, 0xf9, 0xbc,
+	0x99, 0xe2, 0x45, 0x6e, 0xd3, 0xa5, 0xae, 0x5f, 0x64, 0xfc, 0x5b, 0x14,
+	0x32, 0x22, 0xfb, 0xd2, 0x54, 0xee, 0x8b, 0xc4, 0xed, 0xb8, 0xa7, 0x5d,
+	0xe5, 0x62, 0xbe, 0x25, 0xd7, 0x05, 0x54, 0x1f, 0xe4, 0x75, 0xfe, 0x5c,
+	0xaa, 0xf6, 0x29, 0xdf, 0x28, 0xea, 0x75, 0x88, 0x8f, 0x7d, 0x33, 0xd9,
+	0x77, 0x7c, 0x32, 0xe7, 0xd8, 0x14, 0x6b, 0xa9, 0x32, 0x7f, 0x43, 0x7f,
+	0x47, 0xac, 0x19, 0x39, 0x16, 0xc8, 0x9f, 0x70, 0xeb, 0x16, 0x39, 0xb6,
+	0x00, 0x6c, 0x50, 0x11, 0x6b, 0xa8, 0x1b, 0xe1, 0xe7, 0xbd, 0xcc, 0x9b,
+	0xe6, 0x36, 0x70, 0xe8, 0x56, 0x64, 0xcd, 0xf2, 0x90, 0x35, 0xf7, 0xfb,
+	0x51, 0xcb, 0x87, 0x9a, 0x3e, 0x67, 0xd8, 0xa0, 0x12, 0xfb, 0x0a, 0x06,
+	0x15, 0x4c, 0x1f, 0x9d, 0xb3, 0x23, 0xd1, 0x25, 0x81, 0x37, 0xef, 0x43,
+	0xce, 0xcf, 0xf0, 0x2a, 0x1d, 0x36, 0xcf, 0x92, 0xdc, 0xef, 0xa1, 0xc0,
+	0xb6, 0x77, 0x9a, 0xf9, 0xed, 0x2c, 0xfb, 0x1f, 0xce, 0x14, 0xd6, 0x5d,
+	0x34, 0xcd, 0xb0, 0x0f, 0x00, 0x3e, 0x2d, 0x9e, 0xa7, 0xe2, 0x6e, 0x0a,
+	0xc6, 0xf8, 0x99, 0x16, 0x74, 0x11, 0x3f, 0x27, 0x49, 0x71, 0xf6, 0x93,
+	0xe0, 0xb3, 0x4e, 0x4f, 0x45, 0xcc, 0x02, 0x19, 0xdc, 0x16, 0xbe, 0x2b,
+	0x9e, 0x83, 0xfb, 0x63, 0x66, 0x13, 0xd5, 0xd6, 0x1c, 0xb7, 0x8b, 0x3a,
+	0xcc, 0x9b, 0xd1, 0x7b, 0xc8, 0xe8, 0x81, 0x6e, 0xc2, 0x9c, 0xdd, 0xad,
+	0xd6, 0x8b, 0x3a, 0xf8, 0xfb, 0x90, 0xfa, 0x2e, 0xe7, 0x5a, 0x7e, 0xd7,
+	0xbc, 0x8c, 0xbf, 0x0f, 0x5b, 0xc8, 0xfe, 0x5d, 0x35, 0x7f, 0xd5, 0xeb,
+	0x66, 0xfd, 0x46, 0x90, 0xce, 0x7b, 0xae, 0x9b, 0x6d, 0x54, 0xcb, 0xdb,
+	0xb1, 0xc5, 0x5a, 0xde, 0x9f, 0xef, 0x96, 0xf5, 0x71, 0xee, 0xbe, 0xfc,
+	0x9c, 0xfb, 0xe2, 0x15, 0x0f, 0x71, 0xeb, 0x5e, 0xad, 0x73, 0x4b, 0xf4,
+	0x6f, 0xd1, 0xcf, 0xd2, 0x7a, 0x28, 0xac, 0xf2, 0x99, 0x90, 0xbf, 0x74,
+	0x8f, 0xe2, 0x55, 0xad, 0xe7, 0xc9, 0x43, 0xcf, 0x3f, 0x20, 0xf2, 0x8e,
+	0xa5, 0x9d, 0xd8, 0xaf, 0xe8, 0x01, 0x9a, 0x85, 0x5d, 0x34, 0xeb, 0x76,
+	0xd1, 0xcc, 0x50, 0xdf, 0x77, 0x89, 0xe3, 0xf3, 0x4b, 0xaf, 0x76, 0xc8,
+	0x7a, 0x78, 0xac, 0x29, 0x7e, 0x5f, 0x7d, 0xdf, 0x6c, 0xbc, 0x0f, 0x84,
+	0x28, 0x28, 0xe2, 0x4d, 0xae, 0xb1, 0xbe, 0x44, 0x64, 0xb3, 0x37, 0x5c,
+	0x47, 0x83, 0x6f, 0xb9, 0xce, 0xa3, 0x8f, 0x83, 0xae, 0x3e, 0xf6, 0xbb,
+	0xfa, 0x78, 0xb0, 0x41, 0x1f, 0x59, 0x9f, 0xf3, 0x7b, 0xce, 0x16, 0x3f,
+	0x69, 0x5f, 0xd1, 0x4f, 0xd4, 0x49, 0x83, 0x9e, 0x3b, 0x29, 0x1d, 0x0a,
+	0x2b, 0x3b, 0x11, 0x55, 0xf5, 0x03, 0x5e, 0x7d, 0xfe, 0x31, 0x35, 0x9e,
+	0x37, 0x37, 0xaf, 0xba, 0xeb, 0xab, 0x9f, 0xa3, 0x09, 0x59, 0x27, 0xaf,
+	0x64, 0xfb, 0x62, 0x83, 0x78, 0x34, 0x72, 0x3b, 0x80, 0x37, 0x84, 0x6f,
+	0xb8, 0x4f, 0xee, 0x6f, 0x17, 0xa0, 0xe5, 0x72, 0xad, 0xb2, 0x5f, 0xd5,
+	0xf0, 0x3d, 0x1b, 0xba, 0xb3, 0x75, 0xca, 0x38, 0xff, 0x3d, 0x11, 0xcb,
+	0x93, 0xeb, 0x48, 0xab, 0xaa, 0xde, 0x3a, 0x62, 0x21, 0x47, 0x60, 0x71,
+	0x05, 0x71, 0xd8, 0x46, 0xb5, 0xc9, 0x52, 0x17, 0xa5, 0xca, 0x7b, 0xc2,
+	0x14, 0x44, 0x1d, 0x86, 0x8c, 0x8f, 0xc9, 0x1a, 0xe2, 0xc5, 0x95, 0x1b,
+	0xa2, 0x6e, 0x37, 0xae, 0x6a, 0x91, 0x53, 0xd4, 0x26, 0x70, 0xed, 0x27,
+	0xaf, 0x21, 0xfe, 0x71, 0x68, 0xfb, 0x35, 0xc4, 0xee, 0x7b, 0xb6, 0x57,
+	0x43, 0x6c, 0xf2, 0xd8, 0x8d, 0x05, 0x59, 0x43, 0x5c, 0xbd, 0x46, 0x23,
+	0x6b, 0x88, 0x53, 0x2e, 0xac, 0x20, 0xf1, 0xf9, 0x4d, 0x57, 0x7e, 0xb7,
+	0xac, 0x0f, 0x5e, 0x2c, 0xe3, 0x53, 0x59, 0x1f, 0x2c, 0xf3, 0xc1, 0xdd,
+	0x7b, 0xdf, 0xc8, 0xb5, 0x20, 0xf9, 0x9e, 0x5d, 0x35, 0x6b, 0x41, 0xb2,
+	0x2e, 0xd8, 0x32, 0xbc, 0xf8, 0x4e, 0xdb, 0x25, 0xec, 0xf7, 0x10, 0x63,
+	0xde, 0xdd, 0xd9, 0x60, 0xbf, 0x87, 0x58, 0x83, 0xfd, 0x1e, 0xdc, 0xba,
+	0xdf, 0x8d, 0xa7, 0x80, 0x7f, 0x61, 0x17, 0x81, 0x7b, 0xb1, 0x5f, 0x43,
+	0x94, 0xce, 0x97, 0x71, 0xe6, 0x3d, 0x94, 0x54, 0x38, 0xf3, 0xfc, 0x92,
+	0xd6, 0x47, 0xfd, 0x35, 0xfa, 0xc8, 0x0b, 0x77, 0x46, 0x54, 0xce, 0x8f,
+	0x96, 0x57, 0xc7, 0x25, 0xaf, 0x8e, 0x87, 0xbc, 0xe2, 0x1e, 0xa7, 0x41,
+	0xbf, 0x41, 0x13, 0xdc, 0x83, 0xff, 0x97, 0xc2, 0xd8, 0xa7, 0x86, 0xe8,
+	0x0b, 0xdd, 0x0a, 0xeb, 0xb9, 0xe4, 0xf5, 0x2c, 0xcb, 0xab, 0x3e, 0x8f,
+	0xfe, 0x36, 0xc2, 0xfb, 0x1a, 0x1f, 0xee, 0xf7, 0x1d, 0xbb, 0xf2, 0x0b,
+	0x91, 0x17, 0x50, 0xed, 0x27, 0x6a, 0x0c, 0x71, 0x48, 0xc8, 0xd2, 0xba,
+	0x1f, 0xf9, 0x2b, 0xfa, 0x1c, 0x6a, 0xa7, 0x20, 0x7f, 0x9a, 0x16, 0xcd,
+	0x35, 0x38, 0xa3, 0x5d, 0xe1, 0x08, 0x91, 0xff, 0xeb, 0xea, 0xdb, 0x7f,
+	0x72, 0xdf, 0xf4, 0x79, 0x6d, 0x33, 0xdf, 0xae, 0x8a, 0x69, 0x54, 0xe7,
+	0x4d, 0x22, 0x7e, 0xb4, 0x2b, 0x69, 0xd8, 0x09, 0x91, 0x7f, 0xda, 0x69,
+	0x23, 0x56, 0x16, 0x67, 0xd9, 0xef, 0x4c, 0x22, 0xd7, 0xb9, 0xf3, 0x92,
+	0x45, 0xa7, 0xb2, 0x57, 0x0f, 0x48, 0x5e, 0x79, 0x5a, 0xec, 0xd3, 0x89,
+	0x7d, 0x1d, 0x27, 0xd8, 0x3e, 0xc7, 0x19, 0x60, 0xce, 0x15, 0x5b, 0x68,
+	0x91, 0x91, 0xbc, 0xdf, 0x2e, 0x88, 0x58, 0x1f, 0xeb, 0xa4, 0x1c, 0xf6,
+	0x6b, 0x35, 0x16, 0x9a, 0xf9, 0xb9, 0x3d, 0xb4, 0x9c, 0x07, 0xcf, 0x35,
+	0xa9, 0xfd, 0x53, 0xd0, 0xd6, 0x47, 0x5d, 0xf6, 0xdf, 0x32, 0xed, 0x1e,
+	0x11, 0x79, 0x97, 0x8b, 0xb9, 0xa7, 0xe5, 0x67, 0xe1, 0x55, 0xf5, 0x0e,
+	0x7e, 0x5f, 0xf1, 0x75, 0x8a, 0x75, 0xb9, 0xf3, 0x00, 0xdd, 0x7f, 0xde,
+	0x78, 0xe5, 0xe4, 0xb6, 0xf0, 0x8a, 0x93, 0xac, 0xe0, 0x15, 0xf7, 0xb3,
+	0x35, 0x76, 0xf9, 0xe3, 0x1e, 0xb9, 0x9f, 0x05, 0x68, 0xb0, 0x13, 0x58,
+	0x2c, 0x09, 0x5a, 0x1a, 0xe3, 0x91, 0x70, 0xdc, 0x3f, 0x46, 0x99, 0xe2,
+	0x35, 0x4a, 0xe5, 0x60, 0xe7, 0xf9, 0xb3, 0xf0, 0x37, 0x7b, 0x64, 0x9c,
+	0x46, 0xdf, 0x03, 0xbd, 0xb2, 0x9b, 0xdb, 0x37, 0xef, 0x91, 0x39, 0xdb,
+	0xee, 0xf3, 0xed, 0x7c, 0xfe, 0xc9, 0x70, 0xf5, 0xf9, 0x1d, 0x7c, 0xbe,
+	0x2b, 0x89, 0x39, 0x34, 0x2e, 0x21, 0x36, 0x39, 0x4c, 0x69, 0x9e, 0x9f,
+	0x4c, 0x91, 0x6d, 0xeb, 0x65, 0xd6, 0x57, 0x4b, 0xba, 0x5d, 0x37, 0xb7,
+	0x0b, 0x89, 0x39, 0x31, 0xb8, 0xcd, 0x6c, 0x76, 0x84, 0xdb, 0xed, 0x27,
+	0xff, 0x65, 0x8b, 0x32, 0x4b, 0x9a, 0x57, 0x75, 0x2e, 0xfe, 0x2f, 0xba,
+	0x65, 0x6e, 0xd5, 0xae, 0xb0, 0xa4, 0xdf, 0xb0, 0x88, 0x7b, 0x22, 0xb7,
+	0xe3, 0x19, 0xc1, 0x87, 0x91, 0x31, 0xab, 0xfc, 0x7e, 0xec, 0x31, 0x26,
+	0xf6, 0x7c, 0xe5, 0x31, 0xb0, 0x5e, 0x1c, 0xb7, 0xcd, 0x74, 0x39, 0x6f,
+	0x6d, 0x6d, 0x9f, 0xbc, 0x7f, 0x67, 0x8f, 0xdc, 0x7f, 0xb5, 0x53, 0xed,
+	0x15, 0xa8, 0x6d, 0xce, 0x17, 0x90, 0xa7, 0x2d, 0x68, 0xe3, 0x5f, 0x80,
+	0xbe, 0x34, 0xf8, 0x3b, 0x8f, 0x27, 0x89, 0x3e, 0xf6, 0xf6, 0xe8, 0x3d,
+	0x17, 0xe5, 0xb8, 0x4e, 0x70, 0x7f, 0x13, 0x3c, 0x2e, 0x7d, 0x3e, 0xc6,
+	0xc7, 0x5e, 0xf3, 0x8b, 0x67, 0x05, 0xf9, 0x39, 0x2c, 0x03, 0x53, 0xc1,
+	0x64, 0x6a, 0x58, 0xce, 0x73, 0x25, 0xae, 0x1b, 0x2e, 0xc7, 0x75, 0xe7,
+	0xb2, 0xc7, 0x7b, 0x10, 0xcf, 0x30, 0x2e, 0xf1, 0x7c, 0x87, 0x9e, 0xe1,
+	0xb6, 0xa8, 0x63, 0x48, 0xf3, 0x67, 0x9b, 0xca, 0xef, 0xa9, 0xe7, 0x15,
+	0x99, 0x2f, 0xa1, 0xed, 0x16, 0xee, 0xbd, 0x97, 0x9f, 0x21, 0x6d, 0x57,
+	0xe3, 0xf7, 0x50, 0x5d, 0x4e, 0x4c, 0x3d, 0x8f, 0x6d, 0x14, 0x8b, 0x15,
+	0xeb, 0x8a, 0x1e, 0x7c, 0xb6, 0x51, 0xac, 0x44, 0xe4, 0x39, 0xfb, 0x26,
+	0xea, 0xe4, 0x15, 0x72, 0x1c, 0xa0, 0x27, 0xe6, 0x1d, 0xda, 0xc1, 0x73,
+	0xf5, 0x27, 0x06, 0xea, 0x86, 0x4b, 0x24, 0x73, 0x9f, 0x98, 0xc6, 0x59,
+	0x7b, 0xf8, 0xac, 0xc1, 0x74, 0xce, 0x3a, 0xa5, 0x80, 0xdd, 0x46, 0xcd,
+	0x2c, 0xab, 0xbf, 0x4f, 0x03, 0xec, 0xeb, 0x41, 0x66, 0xed, 0x70, 0x82,
+	0x20, 0x6f, 0x11, 0xf3, 0x18, 0xf3, 0xc4, 0x44, 0x11, 0xfc, 0x6c, 0xd0,
+	0x63, 0x79, 0xa2, 0x47, 0xf3, 0x03, 0xe6, 0x37, 0xc9, 0xb6, 0x2a, 0xd7,
+	0x23, 0x66, 0x9c, 0xfb, 0x91, 0x28, 0xfe, 0x25, 0x7d, 0x24, 0xf6, 0x71,
+	0x01, 0x1d, 0xf5, 0xbc, 0xff, 0x39, 0x4d, 0x27, 0xd1, 0xef, 0xad, 0xcb,
+	0xe7, 0xa9, 0x6d, 0xc9, 0x67, 0xd0, 0x43, 0x3e, 0x3f, 0x54, 0x7c, 0x53,
+	0x62, 0x1e, 0x0d, 0xd2, 0x4c, 0x0e, 0xb9, 0x60, 0x9f, 0x47, 0x0d, 0x66,
+	0x2e, 0xc5, 0x7a, 0x29, 0x55, 0xd1, 0x4b, 0x17, 0xe2, 0xfe, 0x18, 0x64,
+	0x1c, 0x7b, 0xd1, 0xa9, 0x1c, 0x20, 0x8c, 0x63, 0x1f, 0x0d, 0x2c, 0xec,
+	0xe4, 0x7b, 0x69, 0x35, 0x3e, 0x1a, 0x53, 0x7b, 0x15, 0x44, 0xac, 0x09,
+	0xd6, 0x8f, 0x73, 0x2c, 0xcb, 0xe9, 0xdc, 0xdd, 0xb4, 0x18, 0xea, 0xa5,
+	0xfe, 0x05, 0xbd, 0x7f, 0x0b, 0xc6, 0x3a, 0xd4, 0x2b, 0x75, 0x92, 0x1e,
+	0xf7, 0x6f, 0x89, 0x38, 0x85, 0x75, 0xed, 0x57, 0x35, 0xee, 0x9d, 0x9b,
+	0xe8, 0xa5, 0x92, 0x92, 0xd9, 0xd2, 0x1b, 0xf1, 0x28, 0x39, 0xf1, 0xd1,
+	0xff, 0x15, 0xfc, 0xdf, 0x7f, 0x0d, 0xb5, 0x38, 0xd0, 0xd1, 0x16, 0x25,
+	0xb3, 0xb5, 0xb4, 0xe8, 0xe5, 0x71, 0xe3, 0x7a, 0xe9, 0xa7, 0x33, 0xd1,
+	0x57, 0x85, 0xed, 0x1f, 0xb8, 0xc6, 0xed, 0x84, 0x6d, 0xd2, 0x7a, 0xc3,
+	0x8b, 0x0f, 0xf5, 0xde, 0x9c, 0x9a, 0x17, 0x65, 0xce, 0x27, 0xe3, 0x37,
+	0x33, 0xe9, 0xaf, 0xe5, 0xc9, 0x8f, 0xe9, 0xe4, 0xbc, 0x45, 0x93, 0x59,
+	0xec, 0x81, 0x38, 0xc6, 0x72, 0xed, 0xb6, 0x17, 0xdc, 0x9e, 0xc0, 0x67,
+	0xe3, 0x2c, 0xfb, 0xec, 0xb7, 0xe7, 0x2c, 0x99, 0x7f, 0x27, 0xf6, 0xdb,
+	0x6b, 0x11, 0x7a, 0xd4, 0xb4, 0xfb, 0xf7, 0x68, 0x7b, 0x90, 0xca, 0xa1,
+	0xce, 0x90, 0x3f, 0x0b, 0xdc, 0x3e, 0xdb, 0x43, 0xa9, 0x3c, 0x9e, 0x03,
+	0x7b, 0x87, 0xbe, 0xf3, 0xf1, 0xb2, 0x9c, 0xd7, 0x7e, 0x7e, 0x36, 0xf6,
+	0x0e, 0x98, 0x2c, 0x8e, 0x88, 0x1c, 0x3c, 0xe8, 0x66, 0x39, 0x9f, 0xe3,
+	0x34, 0xeb, 0xa9, 0x57, 0x14, 0xa6, 0x74, 0xc9, 0x77, 0x4a, 0xc8, 0xf7,
+	0xb8, 0x98, 0x8f, 0x54, 0xde, 0x60, 0xbc, 0xa6, 0xe3, 0x0c, 0x5d, 0x7c,
+	0x1c, 0x50, 0x3a, 0x04, 0xd7, 0xee, 0xdd, 0x23, 0xf2, 0x13, 0x6d, 0x9c,
+	0xc7, 0xe7, 0x38, 0x3d, 0xc3, 0xb8, 0xf3, 0xd9, 0x6c, 0x0b, 0xdd, 0xc8,
+	0xb5, 0xd0, 0x9b, 0xb9, 0x5e, 0xba, 0x3e, 0xdf, 0x41, 0xb3, 0x8c, 0x99,
+	0x67, 0xed, 0x80, 0x95, 0x66, 0xff, 0xe2, 0x6a, 0x54, 0xe4, 0x10, 0xb1,
+	0xdc, 0xa1, 0x3d, 0xf0, 0x5f, 0x7c, 0x2f, 0xf3, 0x1c, 0x63, 0xef, 0x56,
+	0xfa, 0x80, 0xdf, 0x99, 0xce, 0xea, 0x9c, 0x07, 0xc4, 0xe3, 0x07, 0xcb,
+	0xf8, 0x75, 0x73, 0x1e, 0x31, 0x37, 0xe1, 0x91, 0x71, 0xa1, 0xeb, 0x33,
+	0xf3, 0x7c, 0x7d, 0x1e, 0x71, 0x73, 0x4b, 0xc4, 0x24, 0xbe, 0x14, 0x40,
+	0x7b, 0x9c, 0xb3, 0x65, 0xce, 0xa4, 0x18, 0x5b, 0x98, 0x8f, 0x41, 0xdb,
+	0xb0, 0xa2, 0x43, 0x2b, 0x8f, 0x4f, 0xc6, 0x30, 0x52, 0xcb, 0xad, 0x74,
+	0x26, 0xcf, 0x18, 0x24, 0xef, 0x67, 0x1f, 0x06, 0x6d, 0x7f, 0xe7, 0xa0,
+	0xde, 0xd3, 0x76, 0x96, 0xfb, 0x9e, 0xce, 0x4b, 0x0c, 0x92, 0x5e, 0x6e,
+	0xa7, 0x4c, 0xbe, 0x4d, 0x1d, 0xdf, 0x2d, 0xf2, 0xdd, 0xe5, 0xde, 0x12,
+	0xb8, 0xb6, 0x91, 0x7e, 0x43, 0xae, 0x11, 0x6c, 0xaa, 0xf4, 0x4b, 0xa1,
+	0x6b, 0xbc, 0xf3, 0x8c, 0xc6, 0xe8, 0x39, 0xb6, 0xb7, 0xfd, 0x97, 0x11,
+	0x2b, 0xfe, 0x22, 0xf8, 0xa6, 0x00, 0x1e, 0xeb, 0xbf, 0x8c, 0x7d, 0x9f,
+	0xfc, 0x22, 0xf7, 0x68, 0x22, 0x34, 0x2c, 0x6a, 0x46, 0xa4, 0x8c, 0x4e,
+	0x89, 0xba, 0xec, 0xef, 0x08, 0xdd, 0x14, 0x71, 0x2c, 0x03, 0x78, 0x24,
+	0x12, 0x26, 0x92, 0x39, 0x59, 0xa7, 0xec, 0xce, 0x9b, 0xdd, 0xe3, 0x43,
+	0x14, 0xeb, 0x01, 0xdf, 0x4b, 0x99, 0x95, 0x7b, 0x22, 0x90, 0xd0, 0xf7,
+	0xe6, 0x21, 0x5d, 0x63, 0xa0, 0x8f, 0xb5, 0xad, 0xd0, 0xc7, 0x6d, 0x35,
+	0xd7, 0xcd, 0x9a, 0xeb, 0x1a, 0x7f, 0x63, 0xad, 0x8c, 0xed, 0x3c, 0xc9,
+	0x3d, 0x98, 0x52, 0x0b, 0x92, 0xff, 0xcc, 0x43, 0x83, 0xe6, 0xfd, 0x0a,
+	0x83, 0xa7, 0x56, 0x06, 0xc2, 0x9d, 0x46, 0x9b, 0x3f, 0x35, 0xf2, 0xaf,
+	0xa5, 0x58, 0x12, 0xb8, 0xe8, 0xf5, 0x3d, 0x52, 0xc7, 0xa1, 0x5f, 0x4e,
+	0x14, 0xd0, 0x6d, 0x6a, 0xa5, 0x8d, 0x56, 0xc5, 0x9e, 0x63, 0xc0, 0x18,
+	0xb8, 0x1f, 0xcf, 0x71, 0xcc, 0x26, 0xc2, 0x3e, 0xf2, 0x90, 0xf1, 0xc3,
+	0xe1, 0x6b, 0x3c, 0x9f, 0x89, 0x95, 0xff, 0x29, 0x4d, 0x8b, 0x7d, 0x7a,
+	0xd0, 0x96, 0x31, 0xa4, 0xc0, 0xfc, 0x8c, 0x5f, 0xaa, 0xfc, 0xaa, 0x31,
+	0xf4, 0xd3, 0xc1, 0x9a, 0x8a, 0x61, 0xbf, 0xc0, 0x32, 0x26, 0xd7, 0xca,
+	0x13, 0x35, 0x6b, 0xe5, 0x53, 0x62, 0xad, 0x1c, 0xeb, 0xe4, 0x1b, 0xe5,
+	0x2d, 0xea, 0x3c, 0x16, 0x8b, 0x66, 0xaf, 0x08, 0x7d, 0x13, 0x9d, 0xf0,
+	0xcb, 0x3c, 0xeb, 0x04, 0xbb, 0x37, 0x86, 0xa8, 0x6d, 0xc0, 0x67, 0xcc,
+	0x88, 0xdb, 0x91, 0xe1, 0x35, 0xc6, 0x14, 0x4b, 0xb9, 0x1d, 0x74, 0xbd,
+	0xd0, 0xc4, 0x98, 0xef, 0x9f, 0x69, 0xad, 0x40, 0x8c, 0x0d, 0x3b, 0x28,
+	0x13, 0x65, 0x5e, 0x1b, 0x0e, 0xf2, 0xbc, 0x32, 0xbe, 0x1d, 0x66, 0xf9,
+	0xe3, 0x31, 0x2c, 0xe5, 0x4b, 0xef, 0xa7, 0xa3, 0x31, 0x2b, 0x3e, 0xda,
+	0xc6, 0xfe, 0x8b, 0xc9, 0xff, 0x36, 0xff, 0x9f, 0x0b, 0x83, 0x36, 0x8b,
+	0xcb, 0xb8, 0xce, 0xd8, 0x27, 0x5b, 0x7a, 0x7f, 0x86, 0xdb, 0xcc, 0x8c,
+	0xc2, 0x0f, 0x82, 0xbf, 0x67, 0xf3, 0xbf, 0x6c, 0xb3, 0xc4, 0x7c, 0x97,
+	0xbe, 0xe2, 0x84, 0x0d, 0xa1, 0xe3, 0xb1, 0x2f, 0xcd, 0x80, 0xfa, 0x8c,
+	0x19, 0x33, 0xdc, 0x97, 0xeb, 0x84, 0x67, 0x58, 0x94, 0x8a, 0x1e, 0x62,
+	0x39, 0xe8, 0xe0, 0x4f, 0xd4, 0x6a, 0xed, 0xa4, 0xcc, 0xc8, 0xa0, 0xaa,
+	0xd5, 0xfa, 0x59, 0x83, 0x5a, 0x2d, 0xdc, 0xc7, 0x38, 0x60, 0xbe, 0x74,
+	0x7b, 0x26, 0xea, 0x7e, 0x2f, 0x19, 0xa9, 0xe8, 0x2e, 0x81, 0x99, 0x96,
+	0x96, 0x1f, 0xe6, 0x3e, 0xc4, 0xac, 0xd4, 0x28, 0xf7, 0x35, 0xef, 0xee,
+	0x7f, 0xe9, 0xf6, 0x44, 0x14, 0xed, 0xfc, 0x35, 0xed, 0x62, 0x24, 0xda,
+	0x2e, 0xa3, 0x7d, 0xe9, 0x97, 0xf1, 0xa8, 0x1e, 0xa7, 0xfb, 0x5e, 0x8c,
+	0x07, 0xf2, 0xc5, 0x9f, 0x4b, 0xef, 0xd0, 0xf5, 0x1c, 0xfc, 0x71, 0x43,
+	0xd5, 0x5f, 0x59, 0xe4, 0x2c, 0x31, 0x06, 0xbc, 0x72, 0xd0, 0xb7, 0x96,
+	0xfb, 0x41, 0x29, 0x55, 0x95, 0xdb, 0x52, 0x1d, 0x73, 0x97, 0x3e, 0x58,
+	0x2f, 0xd9, 0x97, 0x60, 0x43, 0x61, 0x3f, 0x9d, 0x92, 0xdf, 0x06, 0xde,
+	0x83, 0x6f, 0xf4, 0x34, 0xeb, 0x2f, 0x99, 0x9f, 0xc4, 0xba, 0x94, 0x75,
+	0x98, 0x94, 0x9f, 0x44, 0xd5, 0x4f, 0x3c, 0x48, 0x1e, 0xee, 0xaf, 0xe4,
+	0x49, 0xba, 0xd6, 0xd8, 0x03, 0xae, 0x35, 0x76, 0xd3, 0x95, 0x27, 0x19,
+	0x12, 0xf8, 0xac, 0x82, 0xa9, 0x42, 0x0a, 0x53, 0x01, 0x7b, 0x49, 0xdd,
+	0xb6, 0x58, 0xd6, 0x6d, 0xbb, 0x37, 0xd1, 0x6d, 0x5e, 0xbe, 0xea, 0xaa,
+	0xd2, 0x23, 0x91, 0x28, 0x6c, 0x0c, 0xf6, 0x59, 0xfa, 0xfb, 0xe2, 0x28,
+	0xeb, 0x91, 0x28, 0xeb, 0x91, 0x11, 0xd6, 0x23, 0xc3, 0xac, 0x47, 0x6c,
+	0xa6, 0x81, 0xc5, 0x63, 0xff, 0x98, 0xf5, 0x34, 0xec, 0xc7, 0x18, 0x3d,
+	0x53, 0x84, 0x4e, 0x1e, 0x61, 0x0c, 0xf4, 0x31, 0xad, 0xcd, 0xb7, 0x33,
+	0xff, 0x4a, 0xdc, 0x53, 0xed, 0xd7, 0x60, 0xdf, 0x18, 0xc4, 0x86, 0x7f,
+	0x08, 0xbd, 0xf3, 0xb2, 0x43, 0x7d, 0xbe, 0xeb, 0x39, 0xd0, 0x79, 0x0d,
+	0x7b, 0x6b, 0xbc, 0x08, 0xd9, 0xc6, 0xbe, 0xc7, 0xdf, 0x1e, 0x1a, 0xe3,
+	0xbe, 0xf7, 0xf9, 0x32, 0x3c, 0x2f, 0x8f, 0x47, 0x1d, 0xb3, 0x8b, 0x65,
+	0x60, 0x52, 0xc9, 0xc0, 0x64, 0x45, 0x06, 0x9c, 0x34, 0x8f, 0xa4, 0x73,
+	0xa1, 0x83, 0x06, 0x8f, 0xc4, 0xf7, 0x76, 0xb2, 0xfc, 0x22, 0x67, 0xa2,
+	0xb2, 0xff, 0x90, 0x9f, 0xa6, 0x43, 0x41, 0xb5, 0x6f, 0x91, 0xc5, 0x76,
+	0xf3, 0x27, 0x94, 0xc9, 0xbd, 0xcb, 0xb8, 0x84, 0xe5, 0xd4, 0xc4, 0xf1,
+	0x45, 0xc4, 0x45, 0xd9, 0x6f, 0x68, 0x15, 0x71, 0xa5, 0x45, 0xd1, 0x16,
+	0xc7, 0x91, 0x61, 0xd6, 0x71, 0xd1, 0x55, 0x23, 0x32, 0x16, 0x33, 0x2e,
+	0xf7, 0x62, 0x5f, 0xfa, 0x6f, 0x17, 0x1f, 0xeb, 0x95, 0xf5, 0xb9, 0x4f,
+	0xed, 0x95, 0xfa, 0x84, 0x79, 0x34, 0x14, 0x13, 0xbe, 0x5b, 0xd3, 0x25,
+	0x69, 0x3f, 0x17, 0x79, 0xbe, 0x97, 0xa2, 0xc3, 0x3c, 0xdf, 0x6d, 0xca,
+	0x76, 0x3a, 0x7c, 0x5d, 0xd8, 0x65, 0xb6, 0xa1, 0xbd, 0xd8, 0xd3, 0xdf,
+	0x8c, 0x47, 0x9f, 0xe2, 0x77, 0x62, 0x1f, 0xa1, 0x2f, 0xe3, 0x79, 0xcc,
+	0xbd, 0xd0, 0x1f, 0x3f, 0x61, 0x1b, 0x8d, 0xf7, 0x82, 0x1f, 0xf9, 0x7b,
+	0x61, 0x8c, 0x2e, 0x64, 0x75, 0x1f, 0xde, 0x23, 0xe3, 0x39, 0xf4, 0xc3,
+	0x47, 0xbb, 0xed, 0xf7, 0x44, 0x4d, 0x88, 0xf1, 0x8d, 0xda, 0x3e, 0x7d,
+	0x45, 0xf5, 0x09, 0x7b, 0x79, 0xb6, 0xf0, 0x18, 0x76, 0x13, 0xf6, 0x74,
+	0x5a, 0x14, 0x7b, 0x6d, 0x36, 0x0b, 0x9f, 0x75, 0x51, 0xf8, 0x1e, 0x0f,
+	0xef, 0xad, 0xec, 0xff, 0x79, 0x57, 0xcd, 0xb9, 0x75, 0xb6, 0x5b, 0x47,
+	0x05, 0x46, 0xeb, 0xc7, 0x1e, 0xf4, 0xa2, 0x66, 0xf5, 0x4f, 0xc5, 0x35,
+	0x63, 0x01, 0xd7, 0x3e, 0xa7, 0xae, 0x7d, 0x56, 0x60, 0x63, 0x63, 0xbc,
+	0x95, 0xf5, 0xa2, 0xe0, 0x77, 0x9e, 0x67, 0x7b, 0x98, 0xf9, 0x3d, 0xbc,
+	0xc4, 0xcf, 0x9d, 0x16, 0xf4, 0xd4, 0xf4, 0x00, 0x2d, 0x20, 0x03, 0x6d,
+	0x8a, 0xff, 0x23, 0x56, 0xc2, 0xaf, 0xc7, 0xdd, 0x88, 0xce, 0x63, 0xb0,
+	0xcf, 0x3c, 0x56, 0x8c, 0xc9, 0xf2, 0xc5, 0x0a, 0x61, 0x5f, 0x7a, 0x1e,
+	0xbe, 0x0e, 0xea, 0x5e, 0x0e, 0x20, 0x9f, 0x8a, 0xfb, 0xb0, 0x87, 0x62,
+	0x49, 0xf4, 0x0b, 0xed, 0x34, 0x0d, 0xfe, 0xa8, 0x86, 0x16, 0xee, 0xfb,
+	0x3a, 0xd4, 0x7d, 0xad, 0x62, 0x2e, 0xc8, 0xc0, 0x7b, 0xf4, 0xbb, 0xf1,
+	0x5e, 0xbc, 0x1f, 0xf7, 0xe1, 0x79, 0xf2, 0xb9, 0xdd, 0xac, 0xb7, 0xe3,
+	0xa3, 0xf2, 0x59, 0xc6, 0x35, 0x79, 0xad, 0xdb, 0xf6, 0xee, 0xaf, 0x9c,
+	0x3f, 0x9f, 0xda, 0x83, 0x08, 0xf3, 0xd7, 0x41, 0x05, 0x11, 0xfb, 0xc4,
+	0xb5, 0x3e, 0x9f, 0xf0, 0x6b, 0x6d, 0xfe, 0xe4, 0x79, 0x9d, 0xe3, 0xe3,
+	0x33, 0xb9, 0x77, 0x84, 0xcf, 0x9e, 0x4e, 0xf6, 0xf9, 0x0a, 0x05, 0x8c,
+	0xb7, 0xcf, 0x97, 0x60, 0x19, 0x98, 0xc8, 0xc5, 0x4b, 0x19, 0xa1, 0x6b,
+	0x18, 0xeb, 0x76, 0x45, 0xcc, 0x69, 0xa3, 0x47, 0x60, 0x3e, 0x7e, 0x1f,
+	0x7f, 0x67, 0x39, 0xcc, 0xb2, 0x1c, 0x66, 0x59, 0x0e, 0xb3, 0x2c, 0x87,
+	0xec, 0xab, 0x7e, 0x2b, 0xcb, 0x72, 0xc8, 0xb6, 0xe4, 0x15, 0xb6, 0x25,
+	0x52, 0x76, 0x63, 0x2a, 0xbe, 0xa9, 0x65, 0x17, 0xeb, 0x7f, 0x6e, 0x1f,
+	0x47, 0xcb, 0x2a, 0xec, 0x37, 0xf9, 0x8e, 0x0f, 0x55, 0xcb, 0xec, 0x0d,
+	0x96, 0xd9, 0xa6, 0xf1, 0x1e, 0xba, 0x95, 0xc7, 0x9c, 0x45, 0xac, 0x39,
+	0xd6, 0xd5, 0x09, 0x3f, 0xb0, 0x56, 0x80, 0xe5, 0x09, 0x58, 0x33, 0xc2,
+	0x74, 0xef, 0xa1, 0xdb, 0xac, 0xaf, 0x6f, 0xe5, 0x21, 0xc3, 0x07, 0xd4,
+	0x71, 0x84, 0x65, 0x18, 0xf6, 0xcf, 0xf6, 0xdd, 0xc8, 0x19, 0x8c, 0xc9,
+	0x02, 0x66, 0x8a, 0xa0, 0x4f, 0x05, 0x4e, 0xe3, 0x79, 0x5f, 0x65, 0xbd,
+	0x8f, 0x18, 0x1e, 0xec, 0xc5, 0x19, 0x1f, 0xdb, 0x8b, 0xf0, 0x75, 0xd6,
+	0xa7, 0xe7, 0xf3, 0x36, 0xcb, 0x7d, 0x17, 0xfd, 0x59, 0x1e, 0x76, 0x1a,
+	0x34, 0xe2, 0xe3, 0x02, 0x89, 0xd8, 0x98, 0x31, 0x8e, 0xb1, 0x0f, 0x3a,
+	0x86, 0xe0, 0x93, 0xdb, 0x98, 0x23, 0xa6, 0xfd, 0x3b, 0x7b, 0xb1, 0x9f,
+	0x7e, 0xcc, 0x68, 0x56, 0xb1, 0x46, 0x7c, 0x47, 0xfb, 0x1e, 0x85, 0x4d,
+	0x71, 0xdc, 0x68, 0x0d, 0x12, 0xbf, 0x43, 0x11, 0x65, 0x7a, 0xd4, 0xea,
+	0xaf, 0x0b, 0x7c, 0xbf, 0xa0, 0xd7, 0x58, 0xdc, 0x8f, 0xfa, 0x72, 0xfa,
+	0xaa, 0x7f, 0x7c, 0x8c, 0x9e, 0x2d, 0xa2, 0xdf, 0x97, 0x29, 0x13, 0x82,
+	0x3e, 0x8a, 0x44, 0xd7, 0x49, 0xd2, 0xae, 0x95, 0x71, 0xe7, 0x63, 0xde,
+	0x3a, 0xce, 0x8a, 0x0b, 0x9c, 0xdc, 0xc2, 0xfa, 0x05, 0xb4, 0xf9, 0x3e,
+	0xf3, 0x5a, 0x14, 0x75, 0x69, 0x4a, 0xbf, 0xbd, 0xce, 0x3a, 0x07, 0x73,
+	0x86, 0xe3, 0x8d, 0x75, 0xda, 0x9a, 0xd2, 0x69, 0xb6, 0x4b, 0xa7, 0xa5,
+	0xcb, 0x3a, 0x8d, 0x79, 0x43, 0xe8, 0xb2, 0xa0, 0xa8, 0x8d, 0x4e, 0xab,
+	0xef, 0xc0, 0x87, 0xbb, 0x85, 0xee, 0x62, 0xdd, 0x3f, 0x84, 0x3d, 0xc8,
+	0x1c, 0xdf, 0x31, 0xa1, 0x43, 0x34, 0x7f, 0x3f, 0xbc, 0x4f, 0xca, 0x45,
+	0xab, 0xd0, 0x07, 0xe9, 0x29, 0xe8, 0x2d, 0xaf, 0xf6, 0x0f, 0x72, 0x3b,
+	0xb4, 0xb7, 0xc3, 0x2f, 0xb2, 0x3e, 0x5b, 0x8c, 0xc2, 0xa7, 0x6d, 0x53,
+	0xbe, 0x0f, 0xf6, 0x14, 0xc3, 0x5a, 0x17, 0xc6, 0xaa, 0xf5, 0x59, 0xb7,
+	0x8a, 0x6b, 0x20, 0x0e, 0x89, 0x39, 0x6f, 0x88, 0x11, 0x2c, 0x60, 0x04,
+	0xbe, 0x27, 0xc0, 0xf4, 0x82, 0x7e, 0x61, 0x3b, 0xf0, 0x2e, 0xad, 0x09,
+	0xd9, 0x78, 0x57, 0x60, 0x97, 0x0c, 0x5f, 0x9b, 0x19, 0x7d, 0x54, 0xf4,
+	0x33, 0xb3, 0x5c, 0xd1, 0x8f, 0x73, 0xd9, 0xf7, 0x60, 0x37, 0x44, 0x5f,
+	0x97, 0x86, 0xa4, 0x0e, 0x5c, 0x2c, 0x98, 0xd8, 0xe3, 0x0c, 0x7d, 0xe6,
+	0xbe, 0xea, 0x71, 0xa2, 0x1f, 0x5a, 0x1f, 0x6c, 0x45, 0xf6, 0x18, 0xd7,
+	0x76, 0x61, 0x8e, 0x1c, 0x17, 0x0f, 0x7d, 0x8f, 0xdf, 0x8f, 0x73, 0x9b,
+	0x8f, 0xe7, 0x76, 0x79, 0x3c, 0x88, 0xed, 0xe1, 0x9e, 0x77, 0xe9, 0x96,
+	0x1a, 0xcf, 0xad, 0xf2, 0x78, 0xbe, 0xab, 0xc6, 0x43, 0x69, 0x63, 0xbc,
+	0x5b, 0xe1, 0xfe, 0x2d, 0x3f, 0xbb, 0x35, 0xce, 0x38, 0x26, 0xbd, 0x0c,
+	0x3a, 0xdf, 0xa5, 0xf8, 0xc9, 0x1d, 0x47, 0x75, 0xf7, 0x35, 0x32, 0xbc,
+	0xce, 0xfa, 0xf7, 0xb6, 0xc0, 0x31, 0x7d, 0x8c, 0x63, 0x70, 0x9e, 0x32,
+	0xd0, 0xd3, 0xe9, 0x10, 0xf6, 0xe1, 0x1d, 0xe3, 0x71, 0xb3, 0x3f, 0x36,
+	0xca, 0x9f, 0x22, 0xbe, 0x26, 0xe2, 0xbe, 0xea, 0xfe, 0xaf, 0xd3, 0xed,
+	0x79, 0xe8, 0x72, 0xe0, 0x58, 0xb9, 0x57, 0xef, 0xed, 0x15, 0x19, 0xdf,
+	0x4d, 0x78, 0xc6, 0x77, 0x11, 0xdb, 0x1d, 0x05, 0xce, 0x37, 0x11, 0x07,
+	0x9e, 0x50, 0xbf, 0x5f, 0x92, 0x2e, 0xe2, 0x59, 0x5e, 0x7a, 0x69, 0xcc,
+	0x95, 0x1f, 0x87, 0xbc, 0x14, 0x87, 0xf5, 0x8c, 0x6d, 0x36, 0x19, 0x47,
+	0x65, 0x9c, 0xb9, 0xa8, 0xb1, 0xd3, 0x09, 0x9e, 0x33, 0x3b, 0x6a, 0x18,
+	0x09, 0x11, 0x6b, 0x68, 0xb5, 0xdb, 0xa8, 0x85, 0xed, 0xe8, 0x59, 0xc2,
+	0x3e, 0x70, 0x11, 0x0b, 0x6b, 0x00, 0x17, 0x98, 0x27, 0x33, 0xd1, 0x48,
+	0xf8, 0x51, 0xe1, 0x97, 0xc2, 0xbe, 0x18, 0xa0, 0x13, 0xd3, 0x1a, 0x7d,
+	0xe0, 0xef, 0xcb, 0xd8, 0x0b, 0x34, 0xca, 0xe3, 0x47, 0xfc, 0x78, 0xc0,
+	0x7a, 0x93, 0xed, 0xd2, 0x05, 0x11, 0x97, 0x79, 0x9a, 0xd2, 0x2c, 0xa7,
+	0xc7, 0x85, 0x9c, 0x1a, 0x7d, 0x2c, 0x45, 0x2c, 0x57, 0xc8, 0x43, 0x18,
+	0x44, 0x0c, 0x50, 0xf9, 0x3a, 0x3c, 0xca, 0x15, 0xb5, 0x57, 0x42, 0x12,
+	0xba, 0x63, 0xeb, 0x31, 0x89, 0xe4, 0xa7, 0x8e, 0xc5, 0xb8, 0x31, 0x59,
+	0xa3, 0xda, 0x51, 0xf8, 0x69, 0x2a, 0x9e, 0x88, 0xfc, 0xf8, 0xf2, 0x6f,
+	0xe9, 0xb8, 0xe3, 0x06, 0xe7, 0x44, 0x6e, 0xe8, 0xcb, 0x45, 0x69, 0x83,
+	0xd3, 0xec, 0xd3, 0x67, 0x8e, 0xb8, 0x31, 0x49, 0x24, 0x37, 0x21, 0x62,
+	0x39, 0xfb, 0x28, 0xbe, 0x30, 0x42, 0x0f, 0x64, 0xa1, 0xc3, 0x68, 0x3d,
+	0x6e, 0xe3, 0x57, 0x72, 0x20, 0xe3, 0x23, 0x94, 0x28, 0x82, 0x46, 0x3e,
+	0xc6, 0x4a, 0xcc, 0x7b, 0x39, 0xac, 0xef, 0xf3, 0xf7, 0x02, 0x7e, 0x1b,
+	0xe6, 0x0f, 0x54, 0xbc, 0xbc, 0x97, 0x26, 0x16, 0xc8, 0x49, 0x45, 0xef,
+	0x15, 0x7b, 0x79, 0xa7, 0xa2, 0x43, 0x2a, 0xb6, 0x13, 0xe6, 0xf3, 0x88,
+	0x97, 0x59, 0x74, 0x7f, 0x36, 0xe2, 0xa4, 0x48, 0xc6, 0x2c, 0x88, 0xfb,
+	0x60, 0xb0, 0xed, 0xdd, 0xcd, 0x3a, 0xe4, 0x94, 0x88, 0x5b, 0x30, 0x52,
+	0x99, 0x47, 0x7b, 0xc4, 0x1c, 0xba, 0x08, 0x7e, 0x5a, 0x2a, 0xf7, 0xaa,
+	0x6a, 0x5b, 0x22, 0x93, 0x79, 0xc1, 0xfc, 0x6d, 0xdb, 0x89, 0x1a, 0x95,
+	0xfb, 0x11, 0xf3, 0x38, 0x25, 0x70, 0x64, 0x1f, 0xfb, 0x3c, 0xa2, 0x5d,
+	0x69, 0x46, 0xc4, 0x2f, 0xf8, 0xb8, 0xf0, 0xc8, 0x7e, 0xa9, 0xdb, 0xe4,
+	0x79, 0x19, 0xd7, 0xe0, 0x67, 0x16, 0xb8, 0x1f, 0x55, 0xf9, 0xf4, 0xbd,
+	0x14, 0xdb, 0x46, 0x9c, 0x69, 0xea, 0x8e, 0xc6, 0x99, 0x98, 0xd6, 0xc5,
+	0xcd, 0x6a, 0x1a, 0xb4, 0xff, 0xf7, 0x91, 0xb6, 0xe1, 0x4c, 0x2b, 0x53,
+	0xfc, 0x16, 0x08, 0x30, 0x78, 0xa6, 0xf8, 0x3c, 0x7e, 0x03, 0xc7, 0x97,
+	0x14, 0xd8, 0x38, 0xcc, 0xd8, 0x06, 0x18, 0x67, 0x40, 0xac, 0x8b, 0xc5,
+	0x1e, 0x0a, 0xfb, 0x32, 0x2b, 0x3d, 0xe4, 0x47, 0x3c, 0xce, 0xd6, 0xb9,
+	0x1c, 0xad, 0x22, 0xef, 0x5d, 0xae, 0x47, 0xc2, 0x3e, 0x43, 0x27, 0xae,
+	0xb3, 0xdf, 0xf0, 0x90, 0xca, 0xb9, 0x41, 0xcd, 0xa6, 0xce, 0xb9, 0xd1,
+	0x3a, 0x45, 0xf3, 0x9e, 0x5e, 0xeb, 0x70, 0xff, 0xde, 0x18, 0x64, 0xd7,
+	0x8d, 0x29, 0x10, 0x9f, 0x12, 0x73, 0x74, 0x81, 0x48, 0xce, 0x71, 0x65,
+	0x1d, 0xa3, 0x85, 0xe7, 0x09, 0xfe, 0x20, 0xe2, 0x7e, 0x8f, 0xf0, 0x27,
+	0xd6, 0x23, 0x7e, 0xb4, 0x1f, 0x38, 0xaa, 0xd3, 0x66, 0x9e, 0x19, 0xc5,
+	0x71, 0x0f, 0xfb, 0x67, 0x1a, 0xf7, 0xca, 0x58, 0x14, 0xfb, 0x6c, 0x6a,
+	0xbe, 0x10, 0x87, 0xea, 0x97, 0x39, 0x4c, 0xd9, 0x08, 0x59, 0x5d, 0xa0,
+	0xd3, 0xaf, 0x4a, 0x1e, 0x37, 0x5b, 0xbb, 0xd8, 0x4a, 0x5e, 0x13, 0x7e,
+	0x0b, 0x0d, 0xfb, 0x8d, 0x1e, 0x04, 0xed, 0x79, 0x8e, 0xdc, 0x6b, 0x1b,
+	0xcf, 0xef, 0xd5, 0xbf, 0xc3, 0x74, 0x67, 0xe6, 0x6d, 0x87, 0xc7, 0xbc,
+	0x1d, 0xec, 0x95, 0x6b, 0x67, 0x7f, 0xa1, 0xda, 0x78, 0xe5, 0xb8, 0x3a,
+	0x4f, 0x22, 0x0e, 0x55, 0xa9, 0xbf, 0x78, 0x5b, 0xe8, 0x95, 0xfa, 0x58,
+	0x78, 0x98, 0xf5, 0xa9, 0x94, 0xe3, 0x53, 0x1e, 0x72, 0xdc, 0x35, 0x0e,
+	0xdc, 0xf2, 0xc9, 0xe5, 0x78, 0xb2, 0xa1, 0x1c, 0x4f, 0xf6, 0xca, 0x58,
+	0x6c, 0xbd, 0x1c, 0xbf, 0x81, 0xbe, 0x14, 0x37, 0xca, 0x81, 0x44, 0x4d,
+	0xbb, 0x3b, 0x56, 0x02, 0x9a, 0xe9, 0x78, 0x09, 0xd6, 0x0d, 0xc1, 0x97,
+	0x58, 0x7b, 0x99, 0x32, 0x12, 0xf3, 0xb5, 0x6b, 0xa9, 0x5b, 0xb9, 0x17,
+	0xeb, 0x34, 0xb5, 0xf7, 0x02, 0xbb, 0x43, 0x36, 0x22, 0x61, 0x19, 0x0b,
+	0xd0, 0xf4, 0xeb, 0xf5, 0x1d, 0xcb, 0x47, 0x9c, 0x02, 0x21, 0xd6, 0x1d,
+	0xa2, 0x73, 0x58, 0x9f, 0x56, 0xb1, 0xe4, 0x93, 0x59, 0x49, 0x07, 0xf3,
+	0x88, 0xe0, 0x0f, 0xe0, 0xdb, 0x70, 0xd2, 0x9f, 0xe4, 0x39, 0x96, 0x71,
+	0xe4, 0xd4, 0x72, 0x58, 0xcd, 0x1b, 0xb7, 0xc5, 0xf3, 0xaa, 0xf6, 0x92,
+	0xd7, 0x71, 0x07, 0xcc, 0x57, 0xe4, 0xeb, 0x95, 0xdc, 0x64, 0xd8, 0x86,
+	0x12, 0xfd, 0x37, 0xdb, 0x3d, 0xff, 0x11, 0x53, 0xec, 0xe3, 0xf0, 0x46,
+	0xf1, 0x08, 0xe3, 0x4d, 0xcc, 0x29, 0x62, 0x90, 0x3a, 0x46, 0xfc, 0xc4,
+	0x41, 0x6a, 0x3f, 0xcc, 0x28, 0xc0, 0x20, 0x9b, 0xf1, 0xa5, 0x71, 0x04,
+	0xb9, 0xe6, 0x16, 0xdf, 0x83, 0xfd, 0xa8, 0x06, 0xad, 0x04, 0xb5, 0x21,
+	0x0e, 0x81, 0xfd, 0xb0, 0xad, 0x74, 0x95, 0x8c, 0x9d, 0x16, 0x32, 0x96,
+	0x58, 0x39, 0xad, 0x64, 0xec, 0xb4, 0x8a, 0xc3, 0x9f, 0x56, 0x32, 0x76,
+	0x5a, 0xc9, 0xd8, 0x69, 0x25, 0x63, 0xa7, 0x99, 0xcf, 0x07, 0x18, 0xdf,
+	0x02, 0x8b, 0xe8, 0x38, 0x68, 0x3b, 0xa5, 0xf2, 0x38, 0x0f, 0xfb, 0x5c,
+	0x2b, 0x67, 0xef, 0xf6, 0x49, 0x39, 0x63, 0x6c, 0x22, 0xeb, 0xc9, 0xf8,
+	0x5d, 0x98, 0x83, 0x57, 0x98, 0xe6, 0x1f, 0xd3, 0x99, 0x79, 0xf4, 0xd5,
+	0x47, 0x13, 0x62, 0x1f, 0xdc, 0x26, 0x8a, 0xbb, 0xb1, 0xb0, 0xc9, 0x63,
+	0xcd, 0x4a, 0xdf, 0xcf, 0x31, 0x6c, 0xc1, 0x27, 0xde, 0x7a, 0x15, 0x7c,
+	0x32, 0xae, 0xe6, 0xab, 0xd6, 0x2f, 0x6a, 0xa1, 0x64, 0x0e, 0x74, 0x45,
+	0xfe, 0xa4, 0xc5, 0x73, 0x23, 0xe8, 0xe4, 0x98, 0x1e, 0x34, 0x38, 0xa9,
+	0x68, 0xf0, 0xb8, 0x18, 0x23, 0xf2, 0x0f, 0x11, 0xcb, 0x6c, 0x4c, 0x87,
+	0x74, 0x76, 0x80, 0x9f, 0xc3, 0xb2, 0x70, 0x24, 0xcc, 0x3a, 0x69, 0xeb,
+	0x74, 0xa8, 0x8c, 0xbd, 0x91, 0xee, 0xd9, 0x6a, 0x5d, 0xce, 0xba, 0xcb,
+	0x96, 0x84, 0x95, 0x1d, 0x91, 0xb8, 0x78, 0x87, 0x5d, 0xa2, 0x13, 0xd1,
+	0x83, 0xfc, 0x3d, 0x92, 0x74, 0xe8, 0x30, 0x19, 0x9d, 0x25, 0xfa, 0x11,
+	0xcb, 0x41, 0x2b, 0xcb, 0xc1, 0x09, 0xe5, 0x97, 0x9c, 0x28, 0xfb, 0x25,
+	0x93, 0x07, 0x90, 0x97, 0x91, 0x12, 0xeb, 0x5e, 0x3b, 0xcb, 0xbf, 0xc3,
+	0x02, 0x3d, 0xb6, 0x88, 0xfd, 0x28, 0x7a, 0x71, 0x6c, 0xd2, 0x55, 0xf6,
+	0xab, 0x63, 0xbe, 0x07, 0x0f, 0x08, 0xec, 0xee, 0x7b, 0x00, 0xf7, 0x9c,
+	0x90, 0x7a, 0xcf, 0x47, 0xfe, 0xc1, 0x77, 0x18, 0x4f, 0x94, 0xe8, 0x31,
+	0x7e, 0x67, 0x26, 0x77, 0x88, 0x9f, 0xad, 0xf7, 0x96, 0xb0, 0x63, 0x86,
+	0x6f, 0x27, 0xf9, 0x3b, 0x1b, 0xbd, 0x3b, 0x22, 0xf8, 0x91, 0xf1, 0xb4,
+	0x31, 0x13, 0x7d, 0xaf, 0x34, 0x3d, 0x85, 0x18, 0x3b, 0xe4, 0x24, 0x62,
+	0x5a, 0x3e, 0x2f, 0xf9, 0x90, 0x58, 0xa9, 0x92, 0x0b, 0x2b, 0xf3, 0xc2,
+	0xff, 0x8b, 0xc7, 0x66, 0x12, 0xd6, 0x4e, 0xe4, 0xf3, 0x93, 0x04, 0x9f,
+	0x00, 0xfb, 0x53, 0x58, 0x4c, 0x67, 0xfd, 0x2e, 0x5b, 0xf1, 0xc6, 0x67,
+	0x90, 0xe7, 0x96, 0x5b, 0xa4, 0x8d, 0x6d, 0x0e, 0xe2, 0x75, 0x03, 0x0b,
+	0x6b, 0x9d, 0x21, 0x51, 0x1b, 0xde, 0xc1, 0x18, 0x49, 0xe7, 0x3e, 0x0f,
+	0xf2, 0xf3, 0x11, 0xc7, 0x0b, 0xd0, 0xc4, 0x25, 0xb4, 0x6b, 0xa6, 0xfe,
+	0x85, 0xd2, 0xef, 0xf1, 0x75, 0xb1, 0x7e, 0x99, 0xa2, 0x56, 0xb5, 0x36,
+	0xa1, 0xf7, 0xad, 0x08, 0xb3, 0xec, 0x55, 0x6a, 0x9f, 0xfb, 0xcb, 0x31,
+	0x3d, 0x21, 0x13, 0x35, 0x31, 0xbd, 0xaf, 0x6e, 0x62, 0xaf, 0x36, 0x93,
+	0x03, 0xe4, 0xd4, 0xb5, 0x90, 0x8a, 0x55, 0x5a, 0x19, 0xda, 0x6a, 0x4d,
+	0xdf, 0x76, 0xef, 0xf1, 0xb5, 0x36, 0x8f, 0x93, 0xf3, 0xa6, 0x1d, 0x54,
+	0xfc, 0xd7, 0x4c, 0x67, 0xf2, 0x41, 0xb6, 0xf9, 0xd0, 0xad, 0xa0, 0x97,
+	0xbf, 0x17, 0xb5, 0x2e, 0x5f, 0x0a, 0x34, 0xd3, 0xf2, 0x32, 0x72, 0x2d,
+	0xfe, 0xf1, 0x80, 0xcc, 0x25, 0x4e, 0x32, 0x5d, 0x0e, 0xb3, 0x7d, 0x34,
+	0xd4, 0xda, 0x11, 0xce, 0x41, 0x97, 0x88, 0xdf, 0x21, 0x0a, 0xdc, 0x3b,
+	0x14, 0x64, 0xbf, 0x40, 0xae, 0x3d, 0x1c, 0xe5, 0x67, 0x7f, 0x33, 0x9f,
+	0x44, 0xbc, 0xcc, 0x3c, 0xce, 0xcf, 0x9f, 0x60, 0x3c, 0x11, 0xa3, 0x66,
+	0x5a, 0x5a, 0x6e, 0x66, 0xbf, 0xa0, 0x99, 0xf1, 0xc4, 0x80, 0xd9, 0xef,
+	0x13, 0xef, 0x12, 0x75, 0x35, 0x9f, 0x0f, 0x1c, 0x66, 0xbe, 0xc2, 0xbb,
+	0xfe, 0x5d, 0xbd, 0xab, 0xf6, 0x1d, 0xff, 0x51, 0xc2, 0xf1, 0x71, 0x3f,
+	0x39, 0x37, 0xf0, 0x1b, 0x5c, 0xf3, 0x63, 0x8c, 0x9d, 0x43, 0x94, 0x99,
+	0x6f, 0xe2, 0x31, 0x8c, 0xb3, 0x1f, 0x11, 0xe5, 0xe3, 0xfb, 0xc8, 0x29,
+	0x4e, 0xd1, 0x5f, 0x15, 0xdd, 0x31, 0xe1, 0xfb, 0xb8, 0xcf, 0xb2, 0xb6,
+	0xbf, 0x85, 0xfb, 0xf5, 0x91, 0x5d, 0xab, 0x63, 0x82, 0xe4, 0xff, 0xeb,
+	0x10, 0x35, 0x7f, 0x0d, 0xb1, 0x97, 0x12, 0xe5, 0xa2, 0xa8, 0x57, 0x90,
+	0xf1, 0xe7, 0xab, 0x22, 0x87, 0x96, 0xef, 0xe7, 0x67, 0xce, 0xa1, 0xdd,
+	0x55, 0x8b, 0xae, 0xdb, 0x92, 0xde, 0x3f, 0x08, 0x84, 0xc8, 0xff, 0x12,
+	0x72, 0x9f, 0xc4, 0xfe, 0x1a, 0x8e, 0x7d, 0x88, 0xf5, 0xfb, 0xd7, 0x70,
+	0x1f, 0x7f, 0xbe, 0x84, 0xe3, 0x20, 0x8f, 0x13, 0xf6, 0x1a, 0xf9, 0x2e,
+	0xd0, 0x8b, 0x87, 0xc3, 0xa6, 0xe0, 0xbf, 0xfb, 0x98, 0xa7, 0x9a, 0x44,
+	0xac, 0xb1, 0x0b, 0x6d, 0xed, 0xfd, 0xc0, 0x16, 0xce, 0xd0, 0x21, 0x1c,
+	0xc7, 0x3a, 0xfd, 0x4c, 0x23, 0xc9, 0x43, 0x18, 0x4f, 0x15, 0x73, 0x07,
+	0x8e, 0x0e, 0x11, 0xcf, 0x27, 0xf0, 0xc7, 0x2f, 0xf1, 0x1b, 0x91, 0x4e,
+	0x3f, 0xbf, 0x23, 0xc1, 0xef, 0x98, 0xc8, 0xcb, 0x71, 0xcf, 0x15, 0xfd,
+	0x24, 0xe3, 0x54, 0x5f, 0xe9, 0xd3, 0xbf, 0xd1, 0x48, 0x3d, 0x78, 0x76,
+	0x59, 0x56, 0xf8, 0x7b, 0x3b, 0xdd, 0xca, 0xb7, 0xd1, 0x6d, 0xb5, 0xa6,
+	0x75, 0x4b, 0xf8, 0x65, 0xac, 0xc3, 0x93, 0xed, 0xb4, 0xbe, 0xdc, 0x44,
+	0xd4, 0x15, 0x14, 0x6b, 0xce, 0xb7, 0xf2, 0x05, 0x7e, 0xff, 0x97, 0xfb,
+	0x64, 0x5c, 0xa7, 0xc2, 0x23, 0xb7, 0x3c, 0x78, 0xe4, 0x03, 0xc1, 0x23,
+	0x5f, 0xec, 0xdb, 0x98, 0x47, 0x50, 0xf3, 0x0f, 0xde, 0x08, 0x52, 0xb3,
+	0xe2, 0x8f, 0x17, 0x99, 0x3f, 0x9e, 0x65, 0xfe, 0x38, 0xd6, 0x80, 0x3f,
+	0x8c, 0x1a, 0xfe, 0x38, 0x2e, 0xf8, 0xe3, 0x89, 0xbe, 0x8d, 0xf8, 0xe3,
+	0x98, 0x7f, 0xa3, 0x58, 0x93, 0xaf, 0x35, 0xc0, 0xef, 0x9e, 0xb3, 0xf7,
+	0x31, 0xaf, 0xdb, 0xb4, 0x34, 0x8f, 0xfa, 0x84, 0xd5, 0xa8, 0x41, 0x3f,
+	0x13, 0x3e, 0xd9, 0x9a, 0xf0, 0xf9, 0xc7, 0x45, 0xcd, 0xc1, 0xa2, 0xe0,
+	0x2f, 0xb6, 0xff, 0xe3, 0xa8, 0xab, 0xaa, 0x9d, 0x8b, 0x56, 0xba, 0x1e,
+	0xc5, 0x5c, 0x58, 0x7a, 0x2e, 0x08, 0xeb, 0xbb, 0x6a, 0xef, 0xc8, 0x40,
+	0x3c, 0x4b, 0xce, 0x07, 0xe0, 0xd1, 0x95, 0xb6, 0xc0, 0x44, 0xf6, 0x1b,
+	0x7d, 0xc0, 0x7f, 0x99, 0x15, 0x72, 0x9d, 0x0f, 0xf0, 0xf9, 0x90, 0xf8,
+	0x6d, 0x2b, 0xc8, 0xca, 0x87, 0xc8, 0x71, 0x64, 0x9e, 0xbc, 0x9e, 0xef,
+	0xa5, 0x1b, 0xf9, 0x7d, 0xb4, 0x96, 0xef, 0xa3, 0x37, 0xc5, 0xbe, 0x1a,
+	0xb2, 0x36, 0x72, 0x4d, 0xcc, 0x91, 0x41, 0x47, 0x43, 0xdc, 0x66, 0x79,
+	0x1f, 0xad, 0x2e, 0x6b, 0xfe, 0x06, 0x6f, 0x83, 0x5f, 0x62, 0x9d, 0xb2,
+	0x66, 0xae, 0x9e, 0x67, 0x26, 0xaa, 0x79, 0x46, 0xdc, 0x03, 0x5e, 0xc9,
+	0xd4, 0xd5, 0xfa, 0x22, 0x5f, 0x11, 0xb9, 0x7a, 0x41, 0x6a, 0x42, 0xde,
+	0xa2, 0x11, 0x19, 0x3e, 0xea, 0x07, 0x86, 0xce, 0xb1, 0xcd, 0xe5, 0x39,
+	0xb3, 0x91, 0xe7, 0xd4, 0xc7, 0x78, 0xb8, 0x43, 0xe0, 0xdf, 0xb8, 0x1d,
+	0x08, 0x4f, 0x50, 0xe9, 0x69, 0xc3, 0xc6, 0x5e, 0x8f, 0x49, 0x7e, 0x9e,
+	0xa1, 0xe2, 0x4d, 0xbb, 0x5c, 0xfc, 0x57, 0x8b, 0x75, 0xb1, 0x96, 0xfc,
+	0x10, 0xf7, 0x19, 0x76, 0xb8, 0xb2, 0x5e, 0x43, 0xe5, 0xf5, 0x9a, 0x56,
+	0x1e, 0xb7, 0x94, 0xbd, 0x19, 0x9b, 0xdb, 0x15, 0xff, 0x6f, 0x40, 0x75,
+	0xeb, 0x41, 0x73, 0x7f, 0x40, 0xf1, 0x25, 0xa0, 0x79, 0x67, 0x19, 0x86,
+	0x43, 0x3d, 0xa0, 0x3c, 0x0a, 0x1a, 0x0f, 0x41, 0xcc, 0xf5, 0x1e, 0x5a,
+	0x03, 0x12, 0x07, 0x8d, 0x89, 0x20, 0xe6, 0x7a, 0x0f, 0x41, 0xe7, 0x7a,
+	0x0f, 0xad, 0xb1, 0x01, 0x97, 0xdb, 0xcd, 0x53, 0x80, 0xe1, 0x3e, 0x85,
+	0x19, 0xba, 0xce, 0x51, 0x0d, 0x7a, 0x77, 0x52, 0x0c, 0x78, 0x4c, 0x5b,
+	0x50, 0x05, 0x7f, 0x18, 0xba, 0x62, 0x84, 0xa1, 0x0d, 0xb8, 0x9d, 0xe5,
+	0x02, 0x34, 0xd3, 0x79, 0x4a, 0x0c, 0x30, 0x3c, 0x23, 0x80, 0x79, 0x4f,
+	0x18, 0x9a, 0xf7, 0x60, 0x73, 0xc7, 0xfc, 0x0c, 0x90, 0x7b, 0x98, 0x6c,
+	0xc0, 0x7d, 0x0b, 0x48, 0x79, 0x25, 0x83, 0x56, 0x5e, 0x01, 0xd3, 0x84,
+	0x3a, 0x44, 0x7f, 0xd3, 0x7a, 0x0d, 0x79, 0xd8, 0x38, 0x60, 0x13, 0xd0,
+	0xdc, 0xe6, 0x29, 0xa4, 0xcc, 0x3d, 0x03, 0xeb, 0x5b, 0xac, 0x6b, 0x1b,
+	0x6d, 0xc0, 0x7b, 0xac, 0x17, 0x4d, 0x61, 0x61, 0x58, 0xd2, 0xc3, 0x00,
+	0xac, 0x1f, 0x40, 0x69, 0x1d, 0x54, 0x47, 0xc0, 0xd3, 0xbb, 0x40, 0x13,
+	0xd0, 0x7d, 0x4e, 0xc0, 0xb6, 0xa8, 0x73, 0xbf, 0x32, 0x78, 0xad, 0x6c,
+	0x03, 0xf4, 0xfc, 0xaa, 0x45, 0x3d, 0xde, 0xf2, 0xa0, 0x7c, 0xe6, 0xa4,
+	0xc2, 0x40, 0x46, 0x5e, 0x60, 0x83, 0xe6, 0x05, 0x70, 0x38, 0x01, 0xd3,
+	0x3a, 0xb0, 0x8c, 0x5a, 0x93, 0x04, 0x34, 0x8f, 0x87, 0xc5, 0xa5, 0x1f,
+	0x24, 0xc6, 0x00, 0x15, 0x63, 0x01, 0xf2, 0x65, 0x80, 0x6d, 0x4a, 0x90,
+	0x5f, 0x41, 0x79, 0x01, 0x64, 0x36, 0xc8, 0xef, 0xa0, 0xb2, 0x13, 0x94,
+	0x17, 0x81, 0xec, 0x25, 0x42, 0x50, 0x3f, 0x03, 0x69, 0x20, 0xbb, 0x79,
+	0x8a, 0x08, 0x98, 0x9f, 0x14, 0x20, 0xc4, 0xd0, 0x00, 0xcf, 0x07, 0xc4,
+	0x86, 0x31, 0x4c, 0x7d, 0x0c, 0x19, 0xf9, 0x06, 0x62, 0x06, 0x22, 0xdf,
+	0xb0, 0x33, 0x1c, 0x10, 0x80, 0x85, 0xd5, 0xff, 0xff, 0xc7, 0x54, 0x58,
+	0x80, 0xe9, 0x14, 0xb4, 0x8e, 0xf5, 0xf7, 0xff, 0x03, 0x22, 0x2c, 0x0c,
+	0x2d, 0xf0, 0xf5, 0x88, 0x0b, 0xe5, 0x41, 0x65, 0xe8, 0x02, 0x20, 0xab,
+	0x0d, 0xde, 0x26, 0x60, 0x01, 0xdf, 0x61, 0xbd, 0x80, 0xe1, 0x17, 0xb0,
+	0xcc, 0xfa, 0xff, 0x7f, 0x29, 0x5c, 0x2d, 0x08, 0x00, 0x00, 0xff, 0x88,
+	0x78, 0xb5, 0x98, 0x7e, 0x00, 0x00, 0x00 };
 
 static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 };
 static const u32 bnx2_COM_b09FwRodata[(0x88/4) + 1] = {
-	0x08001b68, 0x08001ba4, 0x08001ba4, 0x08001ba4, 0x08001ba4, 0x08001ba4,
-	0x08001ab4, 0x08001ba4, 0x08001b28, 0x08001ba4, 0x08001a3c, 0x08001ba4,
-	0x08001ba4, 0x08001ba4, 0x08001a48, 0x00000000, 0x08002abc, 0x08002b0c,
-	0x08002b3c, 0x08002b6c, 0x08002b9c, 0x00000000, 0x0800604c, 0x0800604c,
-	0x0800604c, 0x0800604c, 0x0800604c, 0x08006078, 0x08006078, 0x080060b8,
-	0x080060c4, 0x080060c4, 0x0800604c, 0x00000000, 0x00000000 };
+	0x08001b7c, 0x08001bb8, 0x08001bb8, 0x08001bb8, 0x08001bb8, 0x08001bb8,
+	0x08001ac8, 0x08001bb8, 0x08001b3c, 0x08001bb8, 0x08001a50, 0x08001bb8,
+	0x08001bb8, 0x08001bb8, 0x08001a5c, 0x00000000, 0x08002b74, 0x08002bc4,
+	0x08002bf4, 0x08002c24, 0x08002c58, 0x00000000, 0x08006120, 0x08006120,
+	0x08006120, 0x08006120, 0x08006120, 0x0800614c, 0x0800614c, 0x0800618c,
+	0x08006198, 0x08006198, 0x08006120, 0x00000000, 0x00000000 };
 
 static struct fw_info bnx2_com_fw_09 = {
+	/* Firmware version:  3.7.1 */
 	.ver_major			= 0x3,
-	.ver_minor			= 0x4,
-	.ver_fix			= 0x3,
+	.ver_minor			= 0x7,
+	.ver_fix			= 0x1,
 
 	.start_addr			= 0x080000b4,
 
 	.text_addr			= 0x08000000,
-	.text_len			= 0x7dc0,
+	.text_len			= 0x7e94,
 	.text_index			= 0x0,
 	.gz_text			= bnx2_COM_b09FwText,
 	.gz_text_len			= sizeof(bnx2_COM_b09FwText),
 
-	.data_addr			= 0x08007e60,
+	.data_addr			= 0x08007f40,
 	.data_len			= 0x0,
 	.data_index			= 0x0,
 	.data				= bnx2_COM_b09FwData,
 
-	.sbss_addr			= 0x08007e60,
+	.sbss_addr			= 0x08007f40,
 	.sbss_len			= 0x60,
 	.sbss_index			= 0x0,
 
-	.bss_addr			= 0x08007ec0,
+	.bss_addr			= 0x08007fa0,
 	.bss_len			= 0x88,
 	.bss_index			= 0x0,
 
-	.rodata_addr			= 0x08007dc0,
+	.rodata_addr			= 0x08007e98,
 	.rodata_len			= 0x88,
 	.rodata_index			= 0x0,
 	.rodata				= bnx2_COM_b09FwRodata,
 };
 
 static u8 bnx2_CP_b09FwText[] = {
-/*	0x1f, 0x8b, 0x08, 0x00, 0x0f, 0x34, 0xe7, 0x45, 0x00, 0x03, */
-								    0xbd, 0x7d,
-	0x0d, 0x74, 0x5c, 0x57, 0x7d, 0xe7, 0xff, 0xdd, 0x19, 0x49, 0x63, 0x59,
-	0x96, 0x9f, 0xe5, 0x89, 0x32, 0x51, 0x84, 0x3d, 0x23, 0x3d, 0xd9, 0x22,
-	0x12, 0xe1, 0xc5, 0x11, 0xac, 0xda, 0x2a, 0xe9, 0x30, 0x92, 0x3f, 0x12,
-	0x02, 0xab, 0x10, 0x43, 0xb3, 0x1c, 0x4a, 0xc5, 0x48, 0x4e, 0x02, 0x04,
-	0xea, 0x40, 0xe8, 0x86, 0xdd, 0xec, 0x66, 0x32, 0x92, 0x3f, 0x9a, 0x8e,
-	0x3d, 0x93, 0x44, 0x89, 0xbd, 0xdd, 0x9c, 0xad, 0x90, 0x14, 0x3b, 0x74,
-	0x07, 0x4f, 0xe2, 0x98, 0x96, 0x73, 0x0a, 0x8d, 0x50, 0x8c, 0x9b, 0xe6,
-	0xb0, 0xdd, 0xd0, 0xa6, 0x34, 0xdb, 0x86, 0x22, 0x8c, 0x81, 0xf4, 0x2c,
-	0xdd, 0x86, 0x42, 0x77, 0xd3, 0x36, 0xe5, 0xed, 0xef, 0x77, 0xef, 0x7d,
-	0x9a, 0x91, 0x34, 0xce, 0x07, 0xdd, 0xad, 0xcf, 0x79, 0x7e, 0xf3, 0xee,
-	0xbb, 0x1f, 0xff, 0xfb, 0xbf, 0xff, 0xef, 0xfb, 0xbf, 0x4f, 0x97, 0x8b,
-	0x34, 0x8b, 0xfd, 0xb7, 0x01, 0xd7, 0xd5, 0xc9, 0xfd, 0xe3, 0x57, 0x5f,
-	0x39, 0x70, 0x25, 0x9f, 0xa3, 0x91, 0x68, 0x44, 0xde, 0xc4, 0xbf, 0xe4,
-	0x1b, 0xa8, 0x83, 0x0e, 0xdd, 0x70, 0x2c, 0x5e, 0x12, 0x53, 0x43, 0xde,
-	0xfe, 0x8c, 0x27, 0xb1, 0xc8, 0x50, 0xee, 0xce, 0x71, 0x4f, 0x24, 0x5d,
-	0xee, 0x4b, 0x0e, 0xcb, 0x3f, 0x05, 0xb9, 0x78, 0x54, 0x58, 0xfe, 0x96,
-	0xa1, 0x57, 0x7f, 0xeb, 0x2b, 0xff, 0x2a, 0xf5, 0xf2, 0x4c, 0x44, 0x62,
-	0xee, 0xd0, 0xed, 0xe2, 0x6e, 0x93, 0x58, 0xe7, 0x50, 0x72, 0xff, 0x23,
-	0xdb, 0x97, 0x44, 0x5a, 0xc3, 0xbe, 0x5e, 0x0a, 0xbe, 0xb2, 0x5d, 0x72,
-	0x1d, 0x43, 0x89, 0xb1, 0x86, 0x21, 0x57, 0x9e, 0xaa, 0xc8, 0xe8, 0x89,
-	0xc2, 0xcb, 0x41, 0x74, 0x28, 0x88, 0x4c, 0x0d, 0x38, 0x12, 0x19, 0x92,
-	0xb3, 0xe3, 0x03, 0xf7, 0x04, 0xca, 0xf3, 0xfc, 0x45, 0x69, 0x19, 0x3c,
-	0x37, 0x80, 0xf7, 0x65, 0x41, 0xdd, 0xbd, 0xd7, 0x9c, 0x28, 0xc4, 0x44,
-	0x0d, 0xf5, 0xbc, 0x90, 0x89, 0x5c, 0x25, 0x7c, 0x7f, 0x56, 0x7a, 0xfc,
-	0xa7, 0x05, 0xe5, 0xe5, 0x98, 0x64, 0x2a, 0xd2, 0x82, 0x32, 0xdc, 0x9b,
-	0x51, 0x27, 0xe5, 0x66, 0x22, 0xae, 0xe4, 0x2b, 0x3f, 0x5e, 0x67, 0xc6,
-	0x9d, 0xb3, 0xf7, 0xbf, 0x8e, 0x99, 0x3b, 0xc6, 0x2d, 0xc6, 0x64, 0x29,
-	0x92, 0x10, 0xc0, 0x82, 0x79, 0x25, 0x64, 0xb2, 0x98, 0x94, 0x4c, 0x81,
-	0xb0, 0x45, 0x25, 0xeb, 0x12, 0xae, 0x04, 0xda, 0xb7, 0x39, 0xf5, 0xeb,
-	0xb3, 0xee, 0x0b, 0xa8, 0x9b, 0x44, 0xbd, 0x4e, 0x79, 0x12, 0x75, 0x4f,
-	0x57, 0xe2, 0xf2, 0x44, 0xe5, 0x57, 0x25, 0x8d, 0xb6, 0x8f, 0x57, 0x30,
-	0x76, 0xb1, 0x51, 0x86, 0xa7, 0x9b, 0x25, 0x33, 0xdd, 0x9d, 0xc8, 0x4a,
-	0x10, 0x7c, 0xda, 0xff, 0xa8, 0x8c, 0xb5, 0xa1, 0x7e, 0x91, 0xef, 0x12,
-	0x2b, 0xde, 0x65, 0xfd, 0x3e, 0x37, 0xab, 0x1c, 0x49, 0xef, 0x4d, 0x25,
-	0xc6, 0x14, 0x9f, 0x1b, 0x24, 0xd3, 0x8f, 0xe7, 0xd1, 0xa8, 0x44, 0xbc,
-	0x20, 0xb8, 0xc3, 0xbf, 0x0c, 0x70, 0xa4, 0x92, 0x49, 0xc5, 0xb6, 0x6c,
-	0x97, 0xca, 0x25, 0x55, 0x5c, 0x72, 0x95, 0x2b, 0x25, 0xd9, 0x16, 0x04,
-	0xef, 0xf3, 0x3b, 0x51, 0x2e, 0x32, 0x5c, 0x90, 0xfd, 0x58, 0x23, 0xf4,
-	0x29, 0xbe, 0x1a, 0xda, 0x8c, 0x79, 0xf4, 0xb9, 0xc3, 0xd2, 0x28, 0xe9,
-	0xb8, 0xa4, 0xd5, 0x90, 0x24, 0xd5, 0xd0, 0x3a, 0x94, 0x39, 0xd2, 0xe0,
-	0x7d, 0xc1, 0xd2, 0xd2, 0x46, 0x3c, 0xcb, 0xa8, 0x1a, 0x6a, 0x5b, 0x55,
-	0x9e, 0x4a, 0x8a, 0x5a, 0x07, 0x5c, 0xa5, 0x7a, 0xd3, 0x8a, 0x65, 0xb8,
-	0xeb, 0xb2, 0x0f, 0x36, 0xad, 0x2d, 0xdb, 0xef, 0xac, 0x2c, 0xbb, 0xbd,
-	0x85, 0xb0, 0x8a, 0xe2, 0xef, 0xb8, 0x9e, 0x6b, 0x3a, 0xde, 0xed, 0x36,
-	0x60, 0x5e, 0xa3, 0x7e, 0xca, 0xdd, 0xa9, 0x9e, 0x0f, 0xa4, 0x9d, 0x30,
-	0xf3, 0x9d, 0xc2, 0x3b, 0x54, 0x1d, 0xf2, 0xb1, 0x6e, 0xae, 0x1c, 0xc2,
-	0xdc, 0xce, 0x4f, 0xa7, 0xdc, 0x2e, 0x85, 0xfb, 0x3c, 0x7f, 0x07, 0x41,
-	0xc6, 0xcf, 0xe9, 0x35, 0xfd, 0xee, 0x74, 0x02, 0xcf, 0x80, 0x3f, 0x9e,
-	0x4e, 0x6d, 0x92, 0xab, 0xed, 0xba, 0x7c, 0x13, 0x63, 0x76, 0xbb, 0x77,
-	0xa8, 0x6e, 0xd7, 0x57, 0x29, 0x77, 0x56, 0xce, 0xe0, 0x39, 0x08, 0x6e,
-	0xf4, 0x53, 0x89, 0x1c, 0xd6, 0xec, 0x42, 0x21, 0x2e, 0xdf, 0x2b, 0xa4,
-	0x40, 0xc5, 0xa9, 0xde, 0x39, 0xe9, 0xf3, 0xe7, 0x00, 0x6f, 0x1e, 0xd7,
-	0x41, 0xbe, 0x2b, 0xe3, 0x5d, 0x99, 0x6d, 0x83, 0xe0, 0x26, 0xff, 0x37,
-	0x83, 0xb1, 0x76, 0xc3, 0x17, 0x4f, 0x15, 0xb1, 0x9e, 0x80, 0xf9, 0x74,
-	0x11, 0xeb, 0x89, 0xb5, 0x7a, 0x5c, 0xaf, 0x7b, 0x2f, 0xd6, 0x9d, 0xb4,
-	0x41, 0xba, 0xd8, 0x61, 0x69, 0xf9, 0x03, 0xf6, 0x2e, 0x92, 0x29, 0x3a,
-	0x92, 0xf1, 0xff, 0x31, 0x48, 0x6b, 0x7e, 0x11, 0x67, 0xb8, 0x48, 0x5a,
-	0x6c, 0x00, 0xac, 0x7c, 0xcc, 0xda, 0x7a, 0x1b, 0x1d, 0xe0, 0x96, 0xeb,
-	0xc0, 0xf7, 0x31, 0xe5, 0x35, 0xd9, 0xf7, 0x21, 0x5f, 0xf0, 0xdf, 0x26,
-	0x47, 0xbc, 0x6a, 0xbd, 0x0c, 0x69, 0xb2, 0x92, 0x93, 0xec, 0x83, 0x81,
-	0x0c, 0xfb, 0xc0, 0x13, 0xfb, 0x74, 0x7d, 0xd1, 0x6d, 0x5d, 0xd6, 0xd1,
-	0x75, 0xf1, 0x6f, 0x7d, 0x23, 0xc6, 0x70, 0x46, 0x8a, 0xd5, 0xb6, 0x23,
-	0xc5, 0xfc, 0x66, 0x0b, 0x1f, 0x9e, 0x07, 0x9d, 0x4c, 0xe5, 0x82, 0x5d,
-	0xdb, 0x70, 0x1e, 0x57, 0xd7, 0xa1, 0x6d, 0x17, 0x7c, 0xe0, 0x4a, 0xb6,
-	0x30, 0x88, 0x71, 0xe3, 0xb8, 0x07, 0xc1, 0x94, 0x9f, 0x4e, 0x45, 0x65,
-	0x08, 0xcf, 0xa3, 0xe4, 0x3d, 0xe0, 0x4f, 0xa2, 0x99, 0xed, 0xbe, 0x8c,
-	0x80, 0xee, 0xf3, 0x95, 0xd7, 0x97, 0x22, 0x7a, 0x0e, 0xfe, 0x3f, 0x59,
-	0xdc, 0x70, 0x1c, 0x33, 0xe6, 0x54, 0xb1, 0x43, 0xf2, 0xd3, 0x9e, 0x4c,
-	0x16, 0x16, 0x7a, 0x95, 0xbc, 0x4c, 0x7e, 0xc7, 0xfa, 0xa5, 0x40, 0xbb,
-	0x43, 0x32, 0x5c, 0xf1, 0x24, 0x5f, 0xc0, 0xbd, 0xd8, 0x0d, 0xfa, 0x8d,
-	0x4a, 0x3a, 0x61, 0xd6, 0x26, 0x5f, 0x18, 0xc1, 0xfc, 0x80, 0x6b, 0x8f,
-	0xbf, 0x07, 0x2d, 0x4c, 0xae, 0x64, 0x06, 0x48, 0x3f, 0x6f, 0x06, 0x96,
-	0x98, 0xcc, 0xfa, 0xe0, 0x0b, 0xd7, 0xc0, 0x92, 0x2f, 0xc6, 0xa2, 0xc3,
-	0x98, 0xf7, 0x70, 0xf9, 0x57, 0xd0, 0x7f, 0x8b, 0xfe, 0x0d, 0x7e, 0xb2,
-	0x65, 0x51, 0xdc, 0xe3, 0xb8, 0x13, 0xe6, 0x90, 0x56, 0x21, 0x1b, 0xa6,
-	0x3b, 0x65, 0x12, 0xb4, 0x3a, 0x2c, 0xf8, 0x3d, 0xcf, 0xb9, 0x10, 0xae,
-	0x0e, 0xfd, 0x7b, 0x72, 0x7a, 0x8b, 0x7e, 0xce, 0x8e, 0x76, 0x48, 0x6e,
-	0x3e, 0x9c, 0x33, 0xe5, 0x05, 0x65, 0x44, 0xea, 0xb0, 0x08, 0x65, 0x46,
-	0x10, 0x3c, 0xe8, 0x53, 0x6e, 0x04, 0xc1, 0x69, 0x9f, 0x72, 0xe4, 0x0c,
-	0xe4, 0x03, 0x65, 0x07, 0x79, 0xd9, 0x53, 0x5c, 0xab, 0x4c, 0xa1, 0x17,
-	0xeb, 0xd1, 0x28, 0xd9, 0xfe, 0xe3, 0x84, 0x15, 0x72, 0xe7, 0xa5, 0x4f,
-	0x66, 0xbc, 0x5c, 0x22, 0xa2, 0xf1, 0x04, 0xca, 0x82, 0x3c, 0x4c, 0xeb,
-	0x99, 0x75, 0x49, 0xbe, 0xbf, 0x64, 0xeb, 0xc8, 0xaf, 0xb2, 0x4e, 0x74,
-	0x4d, 0x9d, 0x7f, 0xa7, 0x0c, 0x5f, 0xf6, 0x62, 0xdd, 0x3a, 0x14, 0xf1,
-	0xd8, 0xb5, 0x8d, 0xcf, 0x12, 0x6b, 0x18, 0xfa, 0x3d, 0xbc, 0x7b, 0xee,
-	0x53, 0x8f, 0x7a, 0xf5, 0xde, 0xfd, 0x28, 0xba, 0xf6, 0xdd, 0x94, 0x44,
-	0xbd, 0x54, 0xef, 0x8d, 0xea, 0x4f, 0x1a, 0xa4, 0x35, 0x08, 0x1e, 0xf5,
-	0xc3, 0xf2, 0xc6, 0x86, 0xb5, 0x63, 0x5c, 0x55, 0xa7, 0xec, 0x68, 0x9d,
-	0xb2, 0xcf, 0xd7, 0x29, 0x7b, 0x7b, 0xe3, 0xda, 0xb2, 0xdb, 0xeb, 0x94,
-	0xcd, 0xd6, 0x29, 0xfb, 0x69, 0x9d, 0x32, 0x69, 0x5a, 0x5b, 0x16, 0xa9,
-	0x53, 0xd6, 0x57, 0xa7, 0x2c, 0x0a, 0xbe, 0xdb, 0x26, 0xf9, 0xf8, 0xbd,
-	0x9c, 0xbb, 0xc5, 0x4d, 0x29, 0xb2, 0x16, 0x37, 0x0d, 0xa8, 0xd7, 0xb9,
-	0xaa, 0xde, 0x17, 0xeb, 0xd4, 0x6b, 0x44, 0xbd, 0xb6, 0x55, 0xf5, 0x76,
-	0xd4, 0xc1, 0x75, 0x13, 0xea, 0xc5, 0x56, 0xd5, 0x7b, 0xb0, 0x4e, 0x3d,
-	0x96, 0x7f, 0xc6, 0x8e, 0xd3, 0x07, 0x2d, 0xf4, 0x5a, 0xeb, 0xd5, 0x28,
-	0xd2, 0xce, 0xf2, 0x5e, 0xe8, 0x90, 0x0e, 0x65, 0xe4, 0x02, 0x65, 0x10,
-	0xcb, 0x3a, 0x41, 0xe7, 0x71, 0xd0, 0x1d, 0xe5, 0x28, 0xf8, 0x8c, 0x73,
-	0xa9, 0x6c, 0x90, 0xb1, 0x78, 0x9f, 0x7b, 0xb5, 0x6a, 0x01, 0x8d, 0xa5,
-	0xdc, 0xa4, 0x22, 0xff, 0x49, 0x2e, 0x32, 0xe4, 0xe5, 0x86, 0x45, 0xc5,
-	0x95, 0x04, 0x32, 0xe2, 0xab, 0x36, 0x25, 0xf7, 0x80, 0xbf, 0xd2, 0xd0,
-	0x59, 0x37, 0x06, 0xc3, 0x9a, 0xb7, 0x4c, 0xdd, 0x8b, 0xcb, 0x54, 0x5f,
-	0x0e, 0x52, 0x16, 0x0e, 0x8d, 0x7e, 0x2a, 0xe3, 0x2d, 0x0c, 0x36, 0x82,
-	0x66, 0xcf, 0xa3, 0xcd, 0x6e, 0xb4, 0xdc, 0x57, 0x8e, 0xca, 0x48, 0x79,
-	0x00, 0xbc, 0xe0, 0xc8, 0x39, 0x6f, 0xa3, 0x9c, 0xf3, 0x51, 0xb7, 0x12,
-	0x91, 0xc5, 0xb8, 0x23, 0x8b, 0x78, 0xce, 0xf8, 0x78, 0x57, 0x09, 0x79,
-	0x6b, 0x40, 0x0e, 0x14, 0x7d, 0x39, 0x5c, 0xbc, 0x41, 0x85, 0x7a, 0x6d,
-	0xa7, 0xbf, 0x5e, 0x1e, 0x73, 0x4d, 0xdf, 0xbb, 0xbd, 0x05, 0x68, 0xd4,
-	0xa8, 0x9c, 0xf7, 0x52, 0x89, 0x45, 0xcd, 0x13, 0xff, 0x27, 0x18, 0x41,
-	0x3f, 0xb3, 0x5e, 0xca, 0xfd, 0x03, 0x3c, 0x8f, 0x95, 0x69, 0xcb, 0x54,
-	0xfb, 0x9a, 0x44, 0x5f, 0x87, 0x8a, 0x1b, 0xe4, 0x56, 0xdb, 0x7e, 0x97,
-	0xb7, 0xd0, 0x0b, 0x9e, 0x73, 0x4f, 0x50, 0x86, 0x14, 0x00, 0xd7, 0x5e,
-	0xf0, 0x36, 0xda, 0x7e, 0x4d, 0xcb, 0x33, 0xd8, 0x3e, 0x85, 0x8d, 0x90,
-	0xcf, 0x7f, 0x17, 0xdc, 0x1a, 0x67, 0x7d, 0x96, 0x51, 0xe7, 0x48, 0x49,
-	0x0d, 0x41, 0x26, 0x0c, 0x50, 0x66, 0x26, 0x21, 0x2f, 0x21, 0x7b, 0x8a,
-	0x3f, 0x0d, 0xd2, 0xd1, 0x5a, 0x39, 0x28, 0xb9, 0x6a, 0x1d, 0x96, 0x25,
-	0x8d, 0x5c, 0x2d, 0x2e, 0x2d, 0xcb, 0x8a, 0x1c, 0xe4, 0xcb, 0x53, 0x15,
-	0xca, 0x85, 0x0f, 0x82, 0x47, 0x3b, 0x65, 0xa4, 0x90, 0xca, 0xa5, 0x65,
-	0x1b, 0xd6, 0xef, 0xd7, 0xb1, 0xa6, 0x51, 0x5c, 0x0f, 0xad, 0x97, 0x56,
-	0x1f, 0xba, 0x9b, 0xe5, 0xe8, 0xb4, 0x9d, 0x36, 0xd2, 0x6f, 0x03, 0x0f,
-	0x93, 0x5c, 0xf3, 0x44, 0x26, 0xe2, 0x8c, 0xd2, 0x5e, 0x19, 0x85, 0x7c,
-	0xcc, 0x96, 0xd9, 0x37, 0xe1, 0x4d, 0xd8, 0xdf, 0xb0, 0x9b, 0x0a, 0x9d,
-	0xf6, 0x77, 0x0b, 0x7e, 0x27, 0xed, 0x6f, 0xc8, 0xd4, 0x82, 0x67, 0x7f,
-	0xc7, 0xb5, 0x1c, 0x32, 0xbf, 0x13, 0xf8, 0xdd, 0xaf, 0x7f, 0x4f, 0x15,
-	0x77, 0xed, 0x52, 0xde, 0x95, 0x92, 0x9d, 0xef, 0x94, 0x03, 0x85, 0x77,
-	0x58, 0xd9, 0x82, 0x4b, 0xbe, 0xe4, 0x98, 0x79, 0x26, 0xf4, 0xba, 0xe7,
-	0x8b, 0x39, 0x67, 0x94, 0xf0, 0xe3, 0xf7, 0x70, 0xa1, 0xcf, 0xdd, 0x24,
-	0xa4, 0x81, 0x29, 0x67, 0xb8, 0xe2, 0xa4, 0x23, 0x43, 0x3d, 0x89, 0x49,
-	0x39, 0x8c, 0xdf, 0xe2, 0x46, 0x86, 0xbe, 0x84, 0xbb, 0xc1, 0xc1, 0x57,
-	0xb6, 0x43, 0xb6, 0x16, 0x29, 0x2f, 0x3d, 0xcc, 0x3d, 0x29, 0x67, 0x56,
-	0xd8, 0x58, 0xc4, 0x85, 0x92, 0xec, 0x74, 0xea, 0x78, 0x4e, 0x52, 0xb9,
-	0x19, 0x30, 0xc4, 0x8d, 0x7e, 0x54, 0xde, 0xe7, 0x83, 0x76, 0xaf, 0x74,
-	0x64, 0xd7, 0x95, 0x51, 0xd8, 0x44, 0xde, 0xcc, 0x2e, 0xc8, 0x58, 0xc8,
-	0xbe, 0x08, 0xe9, 0x41, 0x9d, 0x92, 0xb1, 0xe8, 0x10, 0xb0, 0x7d, 0xaa,
-	0x7f, 0x64, 0xb2, 0x90, 0xbd, 0x5d, 0x0d, 0xed, 0xff, 0x6c, 0x66, 0xe0,
-	0xad, 0x92, 0xdd, 0xab, 0x80, 0xa3, 0xf6, 0x31, 0xc8, 0x4c, 0xcc, 0x2b,
-	0x08, 0x40, 0xcf, 0x90, 0xe7, 0x37, 0xdd, 0x14, 0x19, 0x6a, 0x90, 0xe1,
-	0xbd, 0xed, 0x68, 0xc3, 0x77, 0xc4, 0xd7, 0x79, 0xe0, 0x33, 0x95, 0x1c,
-	0x11, 0xb9, 0x7b, 0x6a, 0x60, 0xc9, 0x99, 0x2c, 0x7d, 0x10, 0x3c, 0x79,
-	0x15, 0xda, 0x3f, 0x80, 0xf6, 0x2f, 0x3b, 0xf9, 0xe9, 0x57, 0x9c, 0xc9,
-	0xe9, 0xbf, 0x75, 0xa6, 0xa6, 0xb7, 0x6c, 0xd9, 0x39, 0xb8, 0x65, 0xcb,
-	0xf8, 0x60, 0xd4, 0xea, 0x97, 0x2d, 0x5b, 0xa6, 0x06, 0x07, 0x81, 0x83,
-	0x3e, 0x77, 0x44, 0x3c, 0x77, 0x97, 0x80, 0x7f, 0xe2, 0x1c, 0x93, 0xfa,
-	0x27, 0x85, 0xf7, 0x6c, 0xef, 0xe9, 0xf7, 0xc3, 0xd2, 0x97, 0x68, 0x13,
-	0x8e, 0x1f, 0xb1, 0x75, 0xda, 0x01, 0xfb, 0x03, 0x76, 0x7d, 0x0b, 0xaa,
-	0xc1, 0x63, 0x39, 0xe7, 0xc2, 0x72, 0xae, 0xed, 0x8f, 0xac, 0x2d, 0xbb,
-	0x11, 0xe5, 0x7c, 0x26, 0xce, 0x88, 0x17, 0xda, 0x22, 0x0d, 0xda, 0x76,
-	0xcc, 0x16, 0x48, 0x33, 0x51, 0x99, 0x28, 0xb4, 0xa1, 0x0d, 0xe8, 0xe2,
-	0x94, 0xbd, 0x8e, 0x02, 0xb6, 0xbd, 0xe8, 0xeb, 0xe8, 0x21, 0xb4, 0xa3,
-	0xcc, 0x48, 0xf5, 0x8a, 0xfa, 0x04, 0xea, 0xf4, 0xb9, 0x9b, 0x85, 0x36,
-	0xc7, 0x71, 0xc9, 0x16, 0xc9, 0xdf, 0x3d, 0x80, 0x27, 0x26, 0xc9, 0x76,
-	0x3c, 0x57, 0x0e, 0xc0, 0x0e, 0x69, 0xb0, 0x3a, 0x33, 0x94, 0x17, 0xfc,
-	0x77, 0x87, 0x12, 0xef, 0x80, 0x8c, 0xcd, 0x5d, 0x8e, 0x7a, 0x0e, 0xf0,
-	0x42, 0x3b, 0x05, 0x36, 0xcb, 0x5c, 0x5a, 0x32, 0xdb, 0xee, 0xc5, 0xdd,
-	0xc5, 0x73, 0x1e, 0xf7, 0xb7, 0xe0, 0x3e, 0x89, 0x7b, 0x08, 0x27, 0xf0,
-	0xea, 0x47, 0xac, 0xce, 0xba, 0x06, 0x63, 0xff, 0x6b, 0xc9, 0x94, 0x12,
-	0xb4, 0x39, 0x36, 0x66, 0xbc, 0xb4, 0xab, 0x44, 0x6d, 0x56, 0x32, 0x85,
-	0xfa, 0xf0, 0x09, 0xbc, 0x83, 0x32, 0x7e, 0x12, 0xbf, 0x1f, 0xa4, 0x4d,
-	0x3c, 0x25, 0xe3, 0x73, 0x1c, 0xa7, 0x00, 0x98, 0x4a, 0x92, 0x3d, 0xf9,
-	0x00, 0xae, 0x69, 0x5c, 0x0f, 0xe3, 0xe2, 0xdc, 0xd8, 0xff, 0xe2, 0x26,
-	0x05, 0x5c, 0xf3, 0x39, 0x4b, 0x3a, 0xae, 0xe0, 0x37, 0x69, 0xb8, 0x42,
-	0xdb, 0x06, 0xf4, 0x5b, 0x09, 0xe9, 0xda, 0xb7, 0xbf, 0x13, 0x9a, 0xaf,
-	0x73, 0x6d, 0xa0, 0x99, 0xca, 0xa0, 0x96, 0x39, 0x19, 0x0f, 0xf7, 0x0a,
-	0x6c, 0x8f, 0x36, 0xce, 0xd1, 0xb3, 0x65, 0x9e, 0x2e, 0x4b, 0xea, 0xb2,
-	0x7e, 0x5b, 0x86, 0x7b, 0xa5, 0x41, 0xc6, 0xda, 0x01, 0x31, 0xe5, 0xb3,
-	0x84, 0xf8, 0xa4, 0x0c, 0x00, 0xfd, 0xc2, 0x66, 0x38, 0x73, 0x51, 0xf9,
-	0xb7, 0xa4, 0x6d, 0xb1, 0xc7, 0x2b, 0xa4, 0x63, 0xd2, 0x76, 0x10, 0xdc,
-	0xef, 0x37, 0xa1, 0x7f, 0xf2, 0xbc, 0x48, 0xc3, 0xd1, 0xa8, 0xcc, 0xb8,
-	0xa4, 0x85, 0x77, 0xb4, 0x90, 0x06, 0x1a, 0x3d, 0xd2, 0x70, 0x2d, 0x7f,
-	0x71, 0x0d, 0xd9, 0x5f, 0x0e, 0xf6, 0x1d, 0xed, 0xbc, 0x1e, 0xd8, 0xce,
-	0x1c, 0xe3, 0x30, 0x9f, 0x5d, 0x05, 0x9e, 0xca, 0x2c, 0xf3, 0x94, 0xc8,
-	0x6c, 0x81, 0xb8, 0x09, 0xed, 0x3f, 0xae, 0x33, 0xf1, 0xf3, 0x38, 0xe6,
-	0xcc, 0xfb, 0x19, 0x8b, 0xa7, 0x2f, 0x59, 0x3c, 0x7d, 0xd9, 0xde, 0x5d,
-	0x27, 0xab, 0x6d, 0xc1, 0x05, 0x3c, 0x73, 0x7d, 0xa2, 0x1a, 0x67, 0xd9,
-	0xc2, 0x0c, 0xee, 0xa8, 0x5b, 0x7c, 0x5c, 0xc6, 0xb5, 0x9d, 0x16, 0x91,
-	0x77, 0x69, 0xd9, 0x06, 0x21, 0xdd, 0x5c, 0x00, 0xcc, 0x0d, 0x92, 0x8b,
-	0x47, 0xf4, 0xda, 0x47, 0xbd, 0x03, 0x51, 0x43, 0xab, 0xc4, 0xc9, 0x0a,
-	0x5f, 0xaa, 0x06, 0xa6, 0xb8, 0x95, 0x73, 0x84, 0x8b, 0xb4, 0xfb, 0x88,
-	0x86, 0xeb, 0x16, 0xc8, 0xbb, 0x9c, 0xa8, 0xf6, 0x46, 0xb9, 0x0c, 0xb4,
-	0xa0, 0xe2, 0xd0, 0x5c, 0xc1, 0xd3, 0xb0, 0x9b, 0xb2, 0x73, 0xb4, 0xa1,
-	0xbb, 0xe8, 0xb7, 0xc4, 0xb2, 0xfd, 0xad, 0xa4, 0x23, 0xa5, 0x60, 0x7f,
-	0xe1, 0x59, 0x65, 0xfb, 0x35, 0x9d, 0x3a, 0xca, 0x8b, 0x6b, 0x3b, 0x19,
-	0xbc, 0x12, 0xb1, 0xbe, 0x73, 0x54, 0x79, 0x9b, 0x57, 0x97, 0x25, 0xa9,
-	0x87, 0xd1, 0x2e, 0x99, 0xed, 0x6f, 0x27, 0x8f, 0xb9, 0xca, 0x03, 0x2e,
-	0x3d, 0xed, 0x1b, 0xe5, 0xd4, 0xc0, 0xc6, 0x55, 0xf5, 0xf5, 0xdd, 0xb1,
-	0xcf, 0x51, 0x7b, 0x77, 0xed, 0x3d, 0x69, 0xef, 0xb9, 0xe8, 0x00, 0xef,
-	0x8e, 0x44, 0x87, 0x78, 0xc7, 0x1a, 0x0e, 0xb1, 0x0f, 0xcd, 0x57, 0x56,
-	0xce, 0xf4, 0xb8, 0x79, 0x21, 0x5f, 0xfd, 0xa9, 0xdc, 0x32, 0x67, 0xe4,
-	0xef, 0x2e, 0xc8, 0x20, 0xf8, 0x6f, 0xee, 0xa2, 0x00, 0xfe, 0xbd, 0x65,
-	0xb9, 0xa5, 0x42, 0xbc, 0xfd, 0x06, 0xf0, 0xb7, 0x35, 0x4a, 0xde, 0x74,
-	0x85, 0x72, 0xf7, 0x4e, 0xd1, 0xf6, 0x69, 0x81, 0x38, 0x3f, 0x2b, 0x5c,
-	0x9b, 0x7c, 0xe1, 0x19, 0xbd, 0x36, 0x07, 0x0b, 0x8b, 0xc0, 0xcf, 0xd7,
-	0x41, 0xf7, 0x41, 0xb0, 0xe8, 0xe7, 0x41, 0x39, 0x7f, 0x84, 0xdf, 0xe8,
-	0xbb, 0xf0, 0x1c, 0xde, 0xb7, 0x4a, 0xbe, 0x44, 0x9e, 0x8b, 0x5a, 0x1e,
-	0x3e, 0x05, 0x7e, 0xba, 0x0c, 0xfd, 0xa2, 0x6c, 0x80, 0xbf, 0xff, 0x11,
-	0xef, 0x70, 0x9f, 0xc3, 0x22, 0xb6, 0xd3, 0xd6, 0xe1, 0xd8, 0x5c, 0x3b,
-	0xae, 0x59, 0x5c, 0xfb, 0xad, 0x8f, 0x2f, 0xaf, 0x1b, 0xd7, 0x2b, 0xd5,
-	0x9b, 0x93, 0x70, 0xcd, 0x44, 0x1e, 0x2f, 0xb0, 0x3e, 0xe9, 0xff, 0x1f,
-	0x62, 0x46, 0x17, 0xfc, 0xc9, 0x3a, 0x73, 0x5f, 0xdd, 0x96, 0x6b, 0x5e,
-	0x4b, 0x83, 0xf4, 0x6f, 0x52, 0x83, 0x39, 0xc8, 0x9d, 0xa8, 0xd7, 0x2a,
-	0x23, 0xda, 0x27, 0x22, 0x4d, 0x90, 0x06, 0x6e, 0x56, 0x86, 0x36, 0x3f,
-	0xa4, 0x0c, 0x6d, 0x3e, 0x03, 0x5a, 0xc4, 0x55, 0x5c, 0x72, 0x0c, 0x6d,
-	0x7e, 0x1d, 0x77, 0x5c, 0xc5, 0x0b, 0x4e, 0xc8, 0xc7, 0xc3, 0xf0, 0xf9,
-	0x76, 0x15, 0xa2, 0xce, 0x78, 0x05, 0xf4, 0x5b, 0x8c, 0xa1, 0x7c, 0x81,
-	0x38, 0xc7, 0xfc, 0x39, 0xce, 0x56, 0xdb, 0xff, 0xe3, 0x32, 0x51, 0x0c,
-	0xb4, 0x5d, 0x95, 0x9d, 0xbb, 0x17, 0xf7, 0xf5, 0x5a, 0xce, 0x28, 0x2f,
-	0xad, 0x8c, 0xbc, 0x7a, 0x17, 0xee, 0xdd, 0x89, 0x83, 0xd2, 0xed, 0x46,
-	0xe4, 0x39, 0xf4, 0xf5, 0x43, 0x67, 0xa2, 0xf2, 0x32, 0xae, 0x9f, 0xe0,
-	0x7a, 0x15, 0xd7, 0x2b, 0xe8, 0xf7, 0x45, 0x94, 0xaf, 0x97, 0x05, 0xb7,
-	0x19, 0xf5, 0x45, 0x8d, 0x57, 0x5e, 0x70, 0xc6, 0x4e, 0xbe, 0x84, 0x2b,
-	0xaa, 0x26, 0x2a, 0xcf, 0x3b, 0xd9, 0xb9, 0x60, 0xe3, 0xa2, 0x47, 0x19,
-	0xf6, 0xa7, 0x8e, 0xe9, 0x7b, 0x08, 0x73, 0x00, 0x4d, 0x17, 0x17, 0x30,
-	0xf6, 0x33, 0x9a, 0x67, 0x46, 0x20, 0xf3, 0xb3, 0xb0, 0x4b, 0xc6, 0x34,
-	0x4c, 0x97, 0x03, 0x3e, 0xf8, 0xba, 0x03, 0xb8, 0xcf, 0x35, 0xca, 0x52,
-	0x9c, 0x76, 0xe4, 0x97, 0x75, 0xfd, 0x6c, 0xb1, 0x5b, 0xe3, 0x76, 0x66,
-	0x0d, 0xff, 0xd0, 0x3f, 0x0b, 0xe5, 0x81, 0x91, 0xc6, 0xb3, 0x05, 0xca,
-	0x02, 0xe8, 0x9f, 0xc2, 0x14, 0xee, 0x8d, 0x5a, 0x26, 0xe4, 0x25, 0x94,
-	0x07, 0x6c, 0x47, 0x99, 0x50, 0x2b, 0x77, 0x28, 0x6b, 0x28, 0x7b, 0x28,
-	0x4b, 0xcc, 0x7a, 0x8c, 0x3f, 0x48, 0x19, 0x7e, 0x2d, 0xfc, 0x53, 0xda,
-	0x1f, 0x9d, 0xc6, 0x07, 0x99, 0xce, 0x28, 0x23, 0x4f, 0xf7, 0xe8, 0xb5,
-	0x98, 0x28, 0xa8, 0x38, 0x20, 0x47, 0x19, 0xae, 0x63, 0x7b, 0x71, 0xcf,
-	0xaa, 0x09, 0x5c, 0xd9, 0x63, 0x1f, 0xc0, 0x6f, 0xae, 0xcd, 0x04, 0xea,
-	0xe1, 0x2a, 0x8e, 0xe2, 0x8e, 0x0b, 0xb6, 0x99, 0x91, 0x23, 0x5c, 0xd3,
-	0x84, 0x5d, 0xd3, 0x2f, 0x03, 0x0f, 0x9c, 0x9f, 0xd2, 0xf1, 0x07, 0xe5,
-	0xed, 0x00, 0xde, 0x2b, 0xd6, 0xdf, 0x6d, 0x15, 0xc3, 0x83, 0xb8, 0x7a,
-	0xc9, 0xcf, 0x2d, 0x66, 0xbd, 0x34, 0xed, 0x7e, 0x37, 0x6a, 0x78, 0x31,
-	0x8e, 0xb2, 0x08, 0xca, 0xda, 0x45, 0xf3, 0xfe, 0x32, 0x1e, 0xd3, 0x16,
-	0x8f, 0xfc, 0xad, 0xec, 0x6f, 0xd0, 0x13, 0x6c, 0xda, 0x8c, 0x37, 0x80,
-	0x71, 0x31, 0x97, 0x63, 0x7b, 0xd4, 0x38, 0xe4, 0xf7, 0xb8, 0x47, 0x19,
-	0xce, 0x38, 0x03, 0xe7, 0xc7, 0x7e, 0x51, 0xae, 0x71, 0xe0, 0x4b, 0xd5,
-	0x87, 0xff, 0x32, 0xd6, 0xec, 0x71, 0xd9, 0x57, 0xbc, 0x5a, 0xfb, 0xd4,
-	0x8d, 0x47, 0xcd, 0x7a, 0x88, 0x0a, 0xeb, 0xa1, 0xef, 0x38, 0x6d, 0x9b,
-	0x31, 0xfd, 0x3e, 0x7a, 0x94, 0xbf, 0x29, 0x9f, 0x6b, 0xe5, 0xbd, 0xb1,
-	0x6b, 0xf2, 0x2b, 0x64, 0x1d, 0x6d, 0x0b, 0xac, 0x59, 0xb9, 0x16, 0xef,
-	0xf4, 0xf1, 0x29, 0xf3, 0xc8, 0x4f, 0x07, 0xc1, 0x13, 0xaa, 0xc1, 0xf0,
-	0x3e, 0x7d, 0x8d, 0x7a, 0xfc, 0x04, 0xfb, 0x0b, 0xbc, 0x72, 0x02, 0xb6,
-	0xdb, 0xae, 0xe5, 0x3e, 0x20, 0x2b, 0xe3, 0x31, 0x39, 0x59, 0x68, 0x91,
-	0xb9, 0x82, 0x82, 0xc1, 0x60, 0x64, 0x67, 0x44, 0x12, 0x5a, 0xff, 0xd2,
-	0xbe, 0x1b, 0x9e, 0x8e, 0x58, 0xba, 0x83, 0xc3, 0xd2, 0xfc, 0x1b, 0xd0,
-	0xb1, 0x65, 0xe8, 0xd8, 0x56, 0xe8, 0xe0, 0xd5, 0x32, 0xa2, 0xab, 0x61,
-	0xad, 0x8c, 0x60, 0x9b, 0x14, 0xbc, 0xf2, 0x83, 0x68, 0x17, 0xd2, 0x5f,
-	0x4c, 0xd3, 0x5a, 0x56, 0x72, 0xce, 0xae, 0xca, 0x94, 0xb3, 0xbb, 0xb2,
-	0x5a, 0x07, 0xf5, 0xb9, 0x51, 0x31, 0xb0, 0x9e, 0xd4, 0x71, 0xbc, 0x94,
-	0x9f, 0x01, 0x4e, 0x76, 0x83, 0xee, 0x9e, 0x2e, 0xc1, 0x8f, 0xa7, 0x5c,
-	0x06, 0xcc, 0x8f, 0x01, 0xe6, 0xd9, 0x92, 0x13, 0xda, 0x06, 0xc2, 0xe0,
-	0xc9, 0xec, 0x74, 0xbf, 0x2c, 0xce, 0x93, 0x0e, 0x21, 0x03, 0x4a, 0x58,
-	0x4f, 0x7f, 0x1d, 0xec, 0x00, 0x8e, 0x0f, 0xb9, 0x3d, 0xdd, 0xa1, 0xdf,
-	0x19, 0x7d, 0xde, 0x29, 0x8b, 0xe5, 0xf7, 0x58, 0xd8, 0x0e, 0xd7, 0xc0,
-	0xb6, 0x6e, 0x19, 0xb6, 0xdd, 0x80, 0x6d, 0x4f, 0x5d, 0xd8, 0xea, 0xe9,
-	0xe2, 0x2e, 0xd8, 0x34, 0xe4, 0x8f, 0x10, 0xaf, 0xed, 0x96, 0x1e, 0x6e,
-	0xb7, 0xf6, 0x2e, 0x6d, 0xa2, 0x9f, 0x02, 0x1e, 0xd2, 0x18, 0x7e, 0xcf,
-	0x3d, 0x4a, 0x59, 0x86, 0x72, 0x3e, 0x7f, 0x06, 0x75, 0xf0, 0x3c, 0xf7,
-	0xe7, 0x56, 0x0e, 0xde, 0x65, 0x61, 0xa1, 0x9d, 0x90, 0x86, 0x4d, 0x3c,
-	0xe2, 0x64, 0xe6, 0x08, 0x43, 0x0e, 0xf0, 0xe2, 0x5d, 0xa5, 0xb6, 0x4f,
-	0xde, 0xd9, 0xef, 0x15, 0xb6, 0x1f, 0xf6, 0x1d, 0xce, 0x65, 0xbd, 0xd5,
-	0xf3, 0x21, 0x7d, 0x85, 0xf6, 0xf5, 0x94, 0x93, 0x5e, 0x33, 0xaf, 0x5a,
-	0x9a, 0xa3, 0xbc, 0x8d, 0xca, 0x4e, 0xd0, 0xc9, 0xce, 0x15, 0xb4, 0xa6,
-	0xdd, 0x10, 0x4b, 0xc7, 0xeb, 0xec, 0xfc, 0x0e, 0x18, 0xbe, 0xf1, 0x63,
-	0xd0, 0x87, 0x94, 0x37, 0x37, 0x1b, 0xdf, 0x5c, 0x4e, 0x00, 0xd6, 0xf0,
-	0x99, 0xb4, 0xc9, 0xdf, 0x94, 0x49, 0x55, 0x5a, 0x34, 0xbe, 0x4b, 0xa7,
-	0x8e, 0x9f, 0x56, 0xed, 0xf5, 0xa8, 0x8c, 0x9a, 0x35, 0x3f, 0xcc, 0x35,
-	0xa7, 0x2f, 0xd2, 0xfd, 0xc0, 0xa8, 0xe5, 0xaf, 0x54, 0x29, 0x27, 0xbb,
-	0xed, 0xdc, 0xbf, 0x5c, 0x67, 0xed, 0x5a, 0x97, 0xd7, 0x6e, 0xb4, 0xb2,
-	0x7a, 0x8e, 0x22, 0x5d, 0x0f, 0x44, 0xb5, 0x6f, 0x2b, 0xca, 0x97, 0x46,
-	0x8f, 0xf2, 0x93, 0xb6, 0x12, 0xca, 0x67, 0xfb, 0xdc, 0x36, 0xd0, 0xdb,
-	0x53, 0x6b, 0xec, 0xae, 0xa4, 0x95, 0x9b, 0xf4, 0x83, 0xc3, 0x31, 0x72,
-	0x56, 0x4e, 0xe6, 0xd0, 0xff, 0x94, 0xb3, 0xb3, 0x52, 0x4f, 0x5e, 0x86,
-	0x72, 0x92, 0xf3, 0xb9, 0x57, 0xee, 0x78, 0x90, 0x3c, 0x7a, 0xbb, 0xb6,
-	0xaf, 0xaf, 0xda, 0x71, 0x00, 0xf8, 0x23, 0xfc, 0x8b, 0x9b, 0x60, 0x32,
-	0x40, 0xe7, 0xa6, 0x65, 0xdc, 0xae, 0xdb, 0xf8, 0xf2, 0xfa, 0xf3, 0x6a,
-	0xc7, 0x6f, 0xc6, 0x59, 0x95, 0x85, 0x59, 0xdb, 0xb1, 0xb0, 0xeb, 0x56,
-	0xdb, 0xb2, 0x9c, 0x03, 0xed, 0xd9, 0x46, 0x63, 0x0b, 0x16, 0x69, 0x7f,
-	0x52, 0x76, 0xd1, 0xfe, 0x8c, 0x35, 0x4a, 0x33, 0xe7, 0x33, 0x68, 0xcb,
-	0x68, 0xa7, 0xae, 0x9e, 0xdf, 0x6a, 0xff, 0x91, 0x70, 0x12, 0x6e, 0x43,
-	0x5b, 0x49, 0x45, 0xd8, 0x02, 0x19, 0xf5, 0xaf, 0xd5, 0x6b, 0xa0, 0x68,
-	0xbb, 0xee, 0xf8, 0x76, 0x83, 0x89, 0x31, 0x27, 0xd1, 0x3f, 0xc7, 0x24,
-	0xff, 0xf1, 0x4e, 0x3b, 0xbf, 0x9e, 0x2c, 0xab, 0xd5, 0x3d, 0x97, 0x2d,
-	0xe3, 0x6f, 0xe7, 0x8a, 0x35, 0x0a, 0xf1, 0x17, 0xd2, 0x45, 0x2d, 0x0e,
-	0x49, 0x13, 0xa4, 0x85, 0x90, 0x16, 0xb7, 0x5a, 0x7d, 0x13, 0xd2, 0xde,
-	0xa5, 0xa0, 0xbd, 0xfb, 0x80, 0x27, 0xca, 0x70, 0xc6, 0xed, 0x36, 0xe3,
-	0xf9, 0x08, 0x9e, 0x43, 0x3e, 0xb9, 0x98, 0x0c, 0xa7, 0xfc, 0x66, 0x9b,
-	0x8c, 0x95, 0xfb, 0xa1, 0x9f, 0xcb, 0x36, 0x9c, 0x37, 0xe5, 0xff, 0x57,
-	0xe9, 0x77, 0x35, 0x1a, 0x3b, 0xfd, 0x43, 0x8d, 0x94, 0xaf, 0x9b, 0xe4,
-	0x60, 0x4d, 0xd9, 0xc5, 0xe4, 0x77, 0xed, 0x9c, 0x2f, 0xff, 0x7f, 0x30,
-	0xe7, 0xc4, 0xaa, 0x39, 0xbb, 0x76, 0xce, 0x15, 0xbc, 0x6f, 0xc3, 0xfb,
-	0x16, 0xea, 0x82, 0x64, 0x55, 0xde, 0x58, 0x5c, 0xe8, 0x79, 0xd5, 0xca,
-	0x89, 0x50, 0x46, 0x70, 0x5e, 0x1f, 0xb1, 0x73, 0x78, 0xa0, 0x66, 0x5e,
-	0x1f, 0x79, 0x13, 0xf3, 0xea, 0x5c, 0x31, 0xaf, 0x5d, 0x17, 0x9d, 0x57,
-	0x3d, 0x1e, 0x27, 0x2f, 0x87, 0xf3, 0x8b, 0xc9, 0x8d, 0x05, 0xce, 0x71,
-	0x27, 0xe6, 0x48, 0x18, 0xc2, 0x39, 0x0e, 0xd9, 0x39, 0x8a, 0xea, 0xda,
-	0xf1, 0x73, 0xf8, 0x5d, 0x3b, 0x3f, 0xea, 0xfe, 0x1f, 0x83, 0xa6, 0x9b,
-	0x24, 0xd3, 0xdf, 0x64, 0xe5, 0xff, 0x97, 0xe5, 0xd6, 0x22, 0xd7, 0x3a,
-	0x95, 0x16, 0xd9, 0xa3, 0xf6, 0x15, 0x9f, 0x6d, 0x64, 0x8c, 0x7f, 0x97,
-	0x6f, 0xf5, 0x18, 0xf4, 0xc5, 0x6e, 0xd8, 0x7c, 0x3b, 0x0b, 0x6a, 0x20,
-	0x22, 0x41, 0x70, 0x9b, 0xdf, 0x8c, 0xb1, 0x37, 0x6a, 0x5f, 0x75, 0x6d,
-	0x7c, 0xfd, 0x99, 0x46, 0xf1, 0x68, 0x6f, 0x50, 0x9f, 0x43, 0xdf, 0x1d,
-	0xa3, 0x0d, 0x96, 0x81, 0x9d, 0x9c, 0x4e, 0x44, 0xb4, 0x2d, 0x46, 0x9d,
-	0x98, 0x4a, 0xa4, 0xa5, 0x2c, 0xd9, 0x63, 0xe9, 0x84, 0x12, 0x8e, 0x01,
-	0x5b, 0x0d, 0x36, 0xe4, 0xad, 0x90, 0x35, 0xb7, 0x56, 0xf6, 0xaa, 0x5b,
-	0x60, 0xef, 0xdc, 0x72, 0xf2, 0x03, 0xea, 0x36, 0xd8, 0x3a, 0xb7, 0x9d,
-	0xbc, 0x41, 0xed, 0x83, 0x6d, 0xb3, 0x0f, 0x76, 0xce, 0xbe, 0x0a, 0x6d,
-	0xcf, 0x9b, 0x41, 0x7b, 0x9d, 0x35, 0xb4, 0x46, 0x1b, 0x87, 0xf3, 0x23,
-	0xee, 0x8f, 0x71, 0x0d, 0xfc, 0xa4, 0x7a, 0x45, 0xaf, 0x4b, 0xdb, 0x8a,
-	0xb2, 0xd7, 0x92, 0x55, 0xa1, 0x7e, 0xda, 0x60, 0xe3, 0x46, 0x94, 0xb7,
-	0xaf, 0x45, 0x5b, 0xa4, 0x11, 0x17, 0x78, 0x26, 0xfe, 0x48, 0x5b, 0xb5,
-	0xf3, 0xdf, 0xd4, 0x24, 0x5e, 0x67, 0x93, 0x34, 0xdf, 0x0b, 0xf9, 0x5a,
-	0x4b, 0x53, 0xbc, 0xbb, 0x56, 0xd7, 0x90, 0xb6, 0x28, 0x83, 0x43, 0x7a,
-	0xd8, 0xfa, 0x1a, 0xf2, 0xf7, 0xa2, 0xf4, 0x74, 0x4f, 0x64, 0x28, 0x08,
-	0xc6, 0x07, 0x64, 0x23, 0xe3, 0x01, 0x99, 0x4a, 0x35, 0x26, 0xa0, 0xbc,
-	0xda, 0x98, 0x00, 0xfd, 0xac, 0x47, 0x80, 0xdf, 0x19, 0x5c, 0x22, 0x63,
-	0x8c, 0x3b, 0x54, 0x42, 0xbb, 0xfc, 0x1b, 0xd6, 0x2e, 0x0f, 0xe1, 0x48,
-	0x02, 0x0e, 0x23, 0x9f, 0xd7, 0xea, 0xb9, 0x95, 0xfa, 0x3b, 0xb7, 0x6c,
-	0xd3, 0x26, 0xe5, 0xc6, 0x22, 0xe7, 0x4d, 0x19, 0x4c, 0xdc, 0xd4, 0xca,
-	0xe0, 0x84, 0xb5, 0xa3, 0x50, 0x47, 0xcb, 0xcf, 0xb5, 0xb2, 0x93, 0x72,
-	0x8f, 0xf1, 0xf9, 0x07, 0x7c, 0xd2, 0xfa, 0x7b, 0x24, 0xbd, 0x1c, 0x9f,
-	0x17, 0xd0, 0x9b, 0xf8, 0x91, 0x21, 0xbd, 0xdf, 0xe6, 0xce, 0xca, 0x6e,
-	0x19, 0x8e, 0x33, 0xd6, 0xc9, 0x78, 0x9e, 0x97, 0x9b, 0x05, 0x0f, 0x4c,
-	0x16, 0x15, 0x2c, 0xf8, 0x46, 0x19, 0x73, 0x03, 0xd9, 0xe5, 0x3b, 0x3a,
-	0x76, 0x6c, 0x74, 0xed, 0x4c, 0x93, 0xb1, 0x5d, 0x1d, 0x1d, 0xff, 0x5d,
-	0x04, 0xf5, 0x2d, 0x6a, 0xfb, 0x56, 0x69, 0xfd, 0xbb, 0xa0, 0xeb, 0x7c,
-	0xae, 0x29, 0x8c, 0x63, 0x2e, 0xba, 0x11, 0x5b, 0xaf, 0xb6, 0xfc, 0x8b,
-	0x36, 0x3e, 0x9d, 0x84, 0xec, 0x0f, 0xcb, 0xfe, 0xb0, 0x4e, 0xd9, 0xb7,
-	0xea, 0x94, 0xfd, 0xcf, 0x3a, 0x65, 0x26, 0x2e, 0xb8, 0xb3, 0xf0, 0xf7,
-	0x78, 0x37, 0xa5, 0x7d, 0x77, 0xb1, 0xfb, 0x61, 0xb9, 0xe5, 0x3a, 0x1b,
-	0xac, 0x5f, 0xc6, 0x18, 0xb1, 0x89, 0x0d, 0x67, 0x75, 0x6c, 0xb8, 0xcf,
-	0xdd, 0xa1, 0xf4, 0x5e, 0xca, 0x7e, 0xc6, 0x19, 0xf7, 0x69, 0xbc, 0x10,
-	0x27, 0x5f, 0x61, 0x0c, 0x38, 0xc7, 0xbd, 0xd8, 0xa4, 0xba, 0x18, 0x6d,
-	0x57, 0x6d, 0x13, 0xb3, 0x6e, 0xb4, 0x8b, 0x5b, 0x64, 0x04, 0xb6, 0xc2,
-	0xce, 0x42, 0x9b, 0xec, 0x9a, 0x1e, 0x58, 0x47, 0xbd, 0xb5, 0x7b, 0xda,
-	0xf8, 0x83, 0xfb, 0xc0, 0x57, 0x69, 0x21, 0x8c, 0x29, 0x5f, 0x84, 0x36,
-	0xf1, 0x5a, 0x5b, 0xf8, 0xb5, 0xfb, 0xfb, 0xa5, 0x8b, 0xf4, 0xe7, 0xc0,
-	0x76, 0x78, 0xa3, 0xfd, 0x35, 0xcb, 0xc8, 0x74, 0x88, 0x2b, 0xf5, 0x33,
-	0xb6, 0x8b, 0x5c, 0xa4, 0x9d, 0xb6, 0x4b, 0xe4, 0xe9, 0x65, 0x59, 0xbc,
-	0x15, 0x36, 0x93, 0x04, 0x99, 0x01, 0xe9, 0x8c, 0x88, 0x8e, 0xf1, 0xf8,
-	0x46, 0x36, 0xf7, 0x70, 0x6f, 0x07, 0xf4, 0x6f, 0x6c, 0x15, 0x13, 0x37,
-	0x0d, 0xed, 0x94, 0x7a, 0xb4, 0x7b, 0x9d, 0xa5, 0x5d, 0xee, 0xb9, 0xee,
-	0xa6, 0xcc, 0xd5, 0x6b, 0x42, 0x3a, 0xde, 0x55, 0x90, 0x64, 0x48, 0xc7,
-	0x8b, 0x92, 0x5e, 0x41, 0xc7, 0x8b, 0x32, 0xa4, 0xe9, 0xb8, 0x71, 0x05,
-	0x1d, 0x77, 0x5a, 0x3a, 0xde, 0x13, 0x33, 0x74, 0xa1, 0xb4, 0x9e, 0x22,
-	0x9d, 0x1a, 0x3a, 0x76, 0x34, 0x1d, 0x2f, 0xe2, 0x1e, 0xf5, 0xae, 0xb3,
-	0x75, 0x22, 0xb6, 0x8c, 0xbf, 0xc3, 0x32, 0xca, 0xc5, 0x4f, 0xc6, 0x8c,
-	0x5e, 0x1a, 0x02, 0x1d, 0x85, 0xe5, 0xfb, 0x6d, 0xfc, 0xa0, 0xb6, 0xcc,
-	0xc4, 0x47, 0x76, 0x16, 0xc6, 0x62, 0x2b, 0xe9, 0x73, 0x08, 0xf4, 0x19,
-	0xd6, 0x79, 0x2d, 0xfa, 0x6c, 0xb6, 0xfb, 0x16, 0x71, 0xbd, 0x2f, 0x9f,
-	0x8e, 0x1b, 0x5a, 0xbd, 0x45, 0xcf, 0x9d, 0xf3, 0x3e, 0xfb, 0x06, 0x68,
-	0xd5, 0xac, 0xcd, 0xb9, 0xaa, 0xbf, 0xcd, 0x58, 0x54, 0xd2, 0xc4, 0xb0,
-	0x19, 0x27, 0xbd, 0x98, 0xed, 0x68, 0xe4, 0x53, 0x83, 0x96, 0x4f, 0xad,
-	0x63, 0xcc, 0x35, 0xa8, 0xca, 0xec, 0x01, 0xe8, 0x0a, 0xda, 0xd8, 0x5a,
-	0x4e, 0xe3, 0x5d, 0x67, 0x32, 0x53, 0x78, 0x35, 0x88, 0x78, 0x8c, 0x0f,
-	0x71, 0x5f, 0x40, 0xc6, 0x1c, 0x94, 0x75, 0x95, 0xcd, 0xbc, 0x94, 0xd7,
-	0x8a, 0xe7, 0x01, 0xe9, 0x2a, 0x2b, 0xf9, 0xe8, 0x74, 0x8b, 0xec, 0x2f,
-	0x44, 0xe5, 0xe3, 0x68, 0xff, 0xb1, 0x82, 0x0b, 0x7f, 0xfc, 0x4c, 0x8c,
-	0x76, 0xe1, 0xbe, 0x02, 0xf7, 0x27, 0x59, 0x37, 0xbe, 0x6a, 0x7f, 0x36,
-	0x22, 0x5d, 0x3d, 0x79, 0x78, 0x2a, 0x12, 0xdd, 0x03, 0x38, 0x9a, 0x86,
-	0x86, 0xe4, 0x07, 0x03, 0x1b, 0x51, 0xf6, 0xb2, 0x1d, 0x6f, 0xd4, 0x31,
-	0xf1, 0xde, 0x41, 0x79, 0x77, 0x65, 0x48, 0xae, 0xaf, 0x98, 0x3d, 0xd5,
-	0xea, 0x9e, 0x69, 0xca, 0x5d, 0x80, 0xfe, 0x49, 0xbb, 0x41, 0x70, 0xce,
-	0xc3, 0xaa, 0x1f, 0x89, 0x4a, 0xac, 0x27, 0x95, 0x58, 0x10, 0xf3, 0x7c,
-	0xbe, 0xfc, 0x0f, 0xc1, 0x58, 0x3c, 0x2a, 0x3f, 0xf0, 0x38, 0xc7, 0x41,
-	0xb9, 0xae, 0x5c, 0x3b, 0x36, 0x97, 0xf3, 0x0f, 0x63, 0xdc, 0xa7, 0xc8,
-	0x54, 0x16, 0x62, 0x8c, 0xa5, 0xd3, 0xe7, 0xe8, 0x7a, 0x1b, 0xfc, 0x38,
-	0x48, 0xee, 0xae, 0xb7, 0x81, 0x6e, 0xe2, 0xd0, 0xf9, 0x57, 0x01, 0xc6,
-	0xab, 0x18, 0xfb, 0x62, 0xcc, 0x8b, 0xcf, 0x5f, 0xc7, 0xb8, 0x6c, 0xfb,
-	0x1b, 0xd6, 0x5e, 0xe6, 0xfa, 0x1b, 0xde, 0xa9, 0xaf, 0x77, 0x5a, 0xc7,
-	0x62, 0x43, 0xe2, 0xc4, 0xde, 0x91, 0x90, 0x75, 0x5e, 0xed, 0xf8, 0xdc,
-	0x27, 0x86, 0xc5, 0x38, 0x20, 0xd1, 0xdd, 0xdb, 0x07, 0x65, 0x04, 0xf3,
-	0xdb, 0xb9, 0x66, 0x7e, 0xf7, 0x08, 0xe3, 0xab, 0xe7, 0x0b, 0x9c, 0x43,
-	0x75, 0x5e, 0xea, 0x0b, 0x66, 0x5e, 0xb1, 0x9e, 0xd5, 0xf3, 0xd1, 0xed,
-	0xd5, 0x09, 0xc0, 0xf2, 0x35, 0x9d, 0x57, 0x10, 0x04, 0x6f, 0xed, 0x39,
-	0x1f, 0x24, 0x2f, 0x49, 0xf5, 0x2e, 0x54, 0xf7, 0x77, 0xc6, 0x22, 0x43,
-	0x69, 0xad, 0xcf, 0xf0, 0x9c, 0xcc, 0x96, 0xd3, 0x58, 0x47, 0x89, 0x66,
-	0xfb, 0xa3, 0x9a, 0x4f, 0xb2, 0x5e, 0xda, 0xee, 0x61, 0x85, 0x3e, 0x54,
-	0x10, 0x28, 0x6f, 0xb5, 0xdc, 0xa0, 0xbe, 0xc2, 0xdc, 0xe5, 0xdf, 0xda,
-	0x1c, 0x96, 0x5e, 0xc6, 0xb3, 0xc6, 0xa2, 0x43, 0xb1, 0x64, 0xbe, 0xec,
-	0xe1, 0x77, 0x0b, 0xee, 0x3b, 0x60, 0xaf, 0xf8, 0xb0, 0x67, 0x24, 0xae,
-	0x8c, 0x6c, 0x00, 0x2d, 0xf7, 0xe4, 0x94, 0x22, 0x6f, 0xba, 0xc9, 0xc9,
-	0x72, 0x3c, 0x59, 0x2a, 0x7f, 0x96, 0xed, 0x51, 0xb7, 0x5e, 0x2c, 0xcf,
-	0xc8, 0x86, 0xa7, 0x2a, 0x1c, 0x83, 0xfe, 0xef, 0x1b, 0x19, 0x23, 0x6a,
-	0xfb, 0x66, 0x9f, 0x21, 0x5e, 0xa2, 0x74, 0xc9, 0xf1, 0x2f, 0x6d, 0x7d,
-	0x13, 0xce, 0xef, 0xb3, 0x16, 0xee, 0xd5, 0xe3, 0xbe, 0xa0, 0xed, 0x97,
-	0xd3, 0x15, 0xda, 0x8c, 0xdc, 0xdf, 0x49, 0x1d, 0x9f, 0x11, 0xc2, 0x11,
-	0x04, 0xcf, 0xf9, 0x46, 0x77, 0x3f, 0x55, 0xe1, 0x1e, 0x47, 0x10, 0xfc,
-	0x88, 0x76, 0xf1, 0xde, 0x22, 0xc6, 0x0b, 0x71, 0xb0, 0x35, 0x17, 0x85,
-	0x5c, 0x9c, 0x1a, 0x20, 0x7e, 0x05, 0x1e, 0x6a, 0x8f, 0x7b, 0xa3, 0xc4,
-	0x92, 0x9f, 0x2a, 0xb7, 0x24, 0x3f, 0x5d, 0x76, 0x81, 0x67, 0xce, 0x3b,
-	0x9e, 0x9c, 0xb0, 0x73, 0xce, 0x96, 0x89, 0xdf, 0xd7, 0xda, 0x87, 0x7c,
-	0x61, 0x85, 0xbf, 0x44, 0x98, 0xaa, 0xb0, 0x10, 0xb6, 0xa4, 0xc5, 0x4d,
-	0x10, 0xfc, 0xd8, 0x37, 0x6b, 0x3a, 0x55, 0x94, 0x29, 0x8c, 0x9b, 0xdb,
-	0xac, 0x88, 0x87, 0x58, 0xf2, 0x0e, 0x8c, 0xfd, 0x29, 0x8c, 0xbd, 0xbf,
-	0xcc, 0xf1, 0x20, 0x2b, 0x30, 0xf7, 0xa9, 0x4a, 0x08, 0x6f, 0xbd, 0xb1,
-	0xc3, 0x35, 0xef, 0xb5, 0x36, 0x5e, 0xf8, 0xac, 0x11, 0xd9, 0xae, 0xbc,
-	0x7e, 0xd0, 0xd7, 0xe2, 0xa6, 0xa8, 0xfc, 0x22, 0xe4, 0x6e, 0x20, 0x8f,
-	0x42, 0x9e, 0x2d, 0x6a, 0xba, 0xc9, 0x5c, 0xce, 0xff, 0x23, 0xf2, 0xeb,
-	0xeb, 0x18, 0x5f, 0x1e, 0xf6, 0x68, 0xbb, 0x2e, 0x05, 0x8b, 0x1e, 0xe5,
-	0xf3, 0x06, 0x99, 0x71, 0x73, 0xbd, 0xd0, 0x15, 0x28, 0x6b, 0xa5, 0xbf,
-	0x9d, 0xcc, 0x44, 0x52, 0xc9, 0x49, 0x61, 0x3e, 0x14, 0x73, 0x15, 0x98,
-	0x23, 0x44, 0xd9, 0x10, 0x85, 0xcc, 0xe3, 0x1a, 0x9a, 0xf1, 0x26, 0xcb,
-	0xd5, 0xba, 0x07, 0x84, 0x7b, 0x86, 0xa9, 0xc4, 0x3e, 0x6d, 0x9f, 0x88,
-	0x8c, 0x17, 0x58, 0x77, 0x3b, 0xac, 0x13, 0xaf, 0xa6, 0xbe, 0xce, 0xe1,
-	0x02, 0x9f, 0x87, 0x71, 0xac, 0x58, 0x2c, 0x53, 0x90, 0x97, 0x23, 0x03,
-	0xf2, 0x32, 0xed, 0xce, 0x61, 0xd0, 0xb6, 0xeb, 0xf1, 0xbd, 0x29, 0xcf,
-	0xf8, 0xb2, 0x94, 0x19, 0xec, 0xa3, 0x9d, 0x9d, 0x53, 0x9a, 0x27, 0x44,
-	0xa1, 0x6d, 0x2c, 0x5b, 0x96, 0x91, 0x6c, 0xc1, 0xc6, 0x7a, 0x46, 0x39,
-	0xe7, 0x0d, 0x35, 0x73, 0x6f, 0x95, 0x28, 0x60, 0x1a, 0x89, 0x24, 0x9d,
-	0x06, 0xef, 0x23, 0x2d, 0x46, 0xe7, 0x43, 0xee, 0xb7, 0xdd, 0xdf, 0xce,
-	0x3d, 0x53, 0x05, 0x1f, 0x5a, 0xb5, 0xdf, 0x7e, 0x8d, 0x1a, 0xfa, 0xf3,
-	0x04, 0xf4, 0xa0, 0x95, 0x95, 0xb1, 0x91, 0xae, 0x65, 0xfa, 0xe6, 0xf8,
-	0xd2, 0x1e, 0xf1, 0x92, 0x23, 0xc3, 0x65, 0x51, 0x91, 0x21, 0x37, 0x36,
-	0x5c, 0x5e, 0x49, 0xf3, 0x4f, 0x55, 0xfe, 0xbd, 0xb5, 0x05, 0x6b, 0x63,
-	0xaa, 0xb5, 0xef, 0xc8, 0x77, 0x2b, 0xf6, 0x2b, 0x92, 0x26, 0x07, 0x86,
-	0xfb, 0xb4, 0x5c, 0x93, 0xf4, 0x5b, 0x1b, 0xa0, 0x7c, 0x66, 0xb4, 0x8f,
-	0xc6, 0x9c, 0x8b, 0x98, 0xcd, 0x3d, 0x33, 0xb8, 0x4e, 0x97, 0x1d, 0x99,
-	0x82, 0x7c, 0x38, 0x20, 0x7f, 0x1f, 0xa4, 0xe3, 0xe6, 0xbd, 0x59, 0x5f,
-	0xd6, 0xe7, 0x5e, 0x44, 0xb3, 0xe4, 0x4f, 0x46, 0x25, 0x77, 0x92, 0x7b,
-	0x60, 0xcf, 0xed, 0xaf, 0xe6, 0x6d, 0x50, 0x0e, 0x70, 0xbf, 0xd6, 0x91,
-	0x3c, 0xfc, 0xda, 0x11, 0xee, 0xc3, 0xf7, 0xff, 0x1f, 0xf4, 0xc1, 0x7a,
-	0x61, 0xdb, 0x16, 0xb4, 0x6d, 0xb4, 0x6d, 0x47, 0xef, 0x78, 0x73, 0x6d,
-	0x5b, 0xd1, 0x36, 0x16, 0x8e, 0xfb, 0x06, 0xdb, 0x6a, 0x7c, 0x5e, 0x33,
-	0x5c, 0x28, 0x2e, 0xc1, 0x4f, 0x4e, 0x4c, 0x48, 0xda, 0x19, 0x1f, 0xd0,
-	0xf3, 0xb9, 0x66, 0xb8, 0x0c, 0x38, 0xe2, 0x41, 0x90, 0xf7, 0x43, 0x3d,
-	0xcc, 0x7f, 0xc7, 0x44, 0x3c, 0x96, 0x71, 0xdf, 0x92, 0xfe, 0x04, 0xa3,
-	0xa4, 0x2e, 0xf3, 0xd9, 0x24, 0xcf, 0xfd, 0xc9, 0xf8, 0x46, 0xdc, 0x55,
-	0x17, 0x71, 0x92, 0xf5, 0x18, 0xef, 0xdd, 0x68, 0xcb, 0x23, 0x2c, 0x4f,
-	0x45, 0x21, 0x4b, 0x4c, 0x79, 0xc4, 0x96, 0x03, 0x26, 0x3f, 0x9f, 0x04,
-	0xb7, 0xd9, 0x72, 0x3e, 0x2b, 0x5d, 0x6e, 0x9e, 0x0d, 0x0f, 0x8d, 0x09,
-	0xe3, 0x3a, 0x99, 0xeb, 0x1a, 0x64, 0x2b, 0xd6, 0x87, 0x3e, 0xa3, 0x23,
-	0xcd, 0x80, 0xe3, 0x9c, 0xff, 0x76, 0xd8, 0xd6, 0x81, 0xfc, 0xc0, 0x37,
-	0xf4, 0x3f, 0x2b, 0x3d, 0x69, 0xe5, 0x30, 0x07, 0x20, 0x90, 0x9d, 0xfe,
-	0xb6, 0xc4, 0x2e, 0xfc, 0x1e, 0xef, 0x4f, 0xca, 0xec, 0x20, 0xe8, 0xb1,
-	0x9f, 0xbc, 0xb1, 0x15, 0x36, 0x0f, 0x7e, 0xf7, 0xb4, 0xc8, 0x92, 0x9b,
-	0x73, 0xd7, 0xc1, 0x5f, 0x1b, 0xc1, 0xac, 0xe6, 0x0a, 0x9e, 0x7b, 0x1b,
-	0x84, 0x5c, 0xda, 0xed, 0xc1, 0xbd, 0x76, 0xbe, 0xdf, 0xc2, 0x7c, 0x7f,
-	0xad, 0x59, 0x9a, 0x59, 0x5e, 0x5b, 0xb7, 0x51, 0xf6, 0xb8, 0xdb, 0xdd,
-	0xd8, 0x8a, 0xba, 0xe7, 0x51, 0x97, 0x65, 0x9e, 0xcb, 0x1c, 0x9d, 0xd9,
-	0x32, 0xe9, 0xcc, 0xc0, 0xda, 0xd5, 0x13, 0x04, 0xd7, 0xf9, 0x1c, 0x37,
-	0x08, 0xae, 0xf7, 0xfb, 0xdc, 0x67, 0xe5, 0xf9, 0xc0, 0xd8, 0x54, 0x21,
-	0xed, 0x3c, 0x67, 0xe5, 0x75, 0x10, 0xbc, 0xec, 0xf7, 0xca, 0xef, 0x54,
-	0x52, 0x8f, 0xd3, 0xe7, 0x3e, 0x83, 0xe7, 0x33, 0xbe, 0xc9, 0x2b, 0xfa,
-	0x13, 0xb4, 0x8b, 0xab, 0x7e, 0xd0, 0xb0, 0x27, 0x5f, 0xd4, 0x3e, 0x3a,
-	0xf1, 0x67, 0x62, 0xfc, 0x55, 0x18, 0x30, 0x61, 0x2f, 0xb3, 0xc9, 0x65,
-	0x7e, 0xa0, 0xa6, 0xdf, 0xda, 0x77, 0x0a, 0xef, 0x58, 0x16, 0x04, 0x97,
-	0x0c, 0xfc, 0x31, 0xe6, 0x94, 0x2a, 0x71, 0xef, 0xee, 0x03, 0x9a, 0xff,
-	0x04, 0x7e, 0x3d, 0xe9, 0x24, 0xea, 0x2a, 0xe5, 0x1d, 0xee, 0x52, 0xa9,
-	0x9c, 0xc8, 0x5b, 0xb0, 0xfe, 0x5c, 0x63, 0x30, 0x48, 0x1b, 0x60, 0xdf,
-	0xb6, 0xbd, 0xd9, 0xc4, 0x92, 0xe8, 0x4b, 0xa7, 0x37, 0xc1, 0xd7, 0xd5,
-	0xf6, 0x4c, 0x14, 0x7c, 0x3d, 0xd1, 0x16, 0x04, 0xef, 0xf7, 0xc3, 0x35,
-	0xb3, 0xb1, 0x6a, 0xe8, 0xf8, 0x6c, 0xff, 0xb9, 0x66, 0x63, 0xc7, 0x31,
-	0x4f, 0x30, 0xa9, 0xe3, 0xfa, 0xaa, 0x1d, 0x3a, 0x64, 0xdb, 0x57, 0x39,
-	0x7e, 0x8e, 0xe5, 0xef, 0xf3, 0x43, 0x98, 0xaa, 0xed, 0xb3, 0xfd, 0xeb,
-	0xac, 0xcd, 0x19, 0x05, 0x2e, 0x3d, 0xb7, 0x4b, 0xfd, 0x4d, 0x60, 0x74,
-	0x6b, 0x48, 0xc3, 0x7f, 0x17, 0x3c, 0x18, 0x37, 0xcf, 0x99, 0x6d, 0xec,
-	0x63, 0xab, 0x4c, 0x6e, 0xc3, 0x73, 0xf4, 0x5a, 0xdc, 0x87, 0x2f, 0x8b,
-	0xc8, 0x15, 0x89, 0x61, 0xb5, 0xcd, 0x7d, 0x50, 0xfa, 0xac, 0x8c, 0xfb,
-	0x1a, 0xf4, 0x7d, 0x0e, 0xfe, 0x78, 0x93, 0x3c, 0x08, 0x9a, 0x56, 0x03,
-	0xa9, 0xe4, 0x82, 0x4a, 0xf5, 0xce, 0xa8, 0x94, 0x3f, 0xa6, 0xae, 0xe7,
-	0xbc, 0x06, 0x89, 0x8b, 0x19, 0xe2, 0xb7, 0x08, 0xfc, 0x17, 0x81, 0xe3,
-	0x8b, 0xee, 0xf1, 0xfa, 0x56, 0xb7, 0x18, 0xfd, 0x96, 0xd3, 0xb4, 0x69,
-	0xec, 0xf2, 0x3f, 0xf6, 0xc3, 0x35, 0x84, 0x6d, 0xc8, 0x1c, 0x99, 0xba,
-	0x6b, 0x94, 0xe5, 0x1a, 0x41, 0x31, 0xe4, 0x40, 0xf7, 0xa9, 0xe4, 0x84,
-	0x5a, 0x0a, 0x36, 0xed, 0xe8, 0xee, 0x7d, 0x42, 0xf7, 0x93, 0xf2, 0xd3,
-	0x2a, 0x0f, 0x78, 0xb6, 0x4a, 0xd3, 0x0e, 0xe2, 0x99, 0xb0, 0xc6, 0x18,
-	0x4f, 0x72, 0xef, 0x40, 0xdd, 0x31, 0xa5, 0xf7, 0xa0, 0x6d, 0x1d, 0xc2,
-	0x1c, 0x5f, 0x2f, 0xcd, 0xd4, 0x43, 0x8c, 0x93, 0xbd, 0x96, 0x2e, 0x84,
-	0x4c, 0x3a, 0x46, 0x19, 0x18, 0x31, 0xb1, 0xdf, 0xca, 0xcf, 0xa1, 0x9d,
-	0xce, 0x67, 0x89, 0x45, 0x21, 0xa3, 0xa6, 0xc0, 0xc5, 0x87, 0x8e, 0x49,
-	0xb4, 0xc1, 0xfb, 0x5f, 0xcd, 0xc6, 0x6f, 0xa2, 0x0f, 0xc5, 0xb1, 0x1b,
-	0x24, 0xbf, 0x26, 0xde, 0x52, 0x02, 0xfc, 0xcd, 0x32, 0x79, 0x8c, 0x6b,
-	0x11, 0x85, 0xcc, 0xe1, 0xd8, 0x12, 0xcd, 0xf4, 0x07, 0xc1, 0x38, 0xcb,
-	0x4f, 0x92, 0x7f, 0x25, 0xc5, 0x77, 0xb9, 0x93, 0x0b, 0x9b, 0xd4, 0x0a,
-	0x59, 0xdb, 0x62, 0xe1, 0xd0, 0x78, 0x92, 0x92, 0x96, 0x23, 0xd4, 0x37,
-	0xb7, 0xd5, 0xc0, 0x33, 0x7a, 0xc7, 0x94, 0xd7, 0xf8, 0x26, 0xe0, 0xf9,
-	0x3d, 0xc0, 0xd3, 0x62, 0xe1, 0x69, 0x5c, 0x05, 0x4f, 0x4b, 0x08, 0x0f,
-	0xe4, 0x1c, 0xe5, 0x6a, 0xec, 0x9a, 0x74, 0x59, 0x9c, 0xbc, 0x27, 0x9d,
-	0x4a, 0xfb, 0x2f, 0xd4, 0x37, 0x8d, 0xee, 0xf8, 0x80, 0x2b, 0xe3, 0x5a,
-	0xd7, 0x44, 0xaf, 0xe9, 0x2e, 0x2f, 0xc0, 0x7a, 0x15, 0x27, 0xe3, 0x11,
-	0xf6, 0x7a, 0x76, 0xd5, 0x3d, 0x90, 0xff, 0x8b, 0xa9, 0xa8, 0xb5, 0x25,
-	0x4a, 0x3e, 0xfd, 0x96, 0xb8, 0xde, 0xdb, 0xaf, 0xc2, 0xf4, 0x12, 0x60,
-	0x82, 0x3c, 0x3e, 0xd6, 0xe7, 0x8e, 0xca, 0xa5, 0xda, 0x37, 0xb3, 0xb8,
-	0xc6, 0xdc, 0x62, 0x35, 0x73, 0x83, 0xfe, 0x53, 0xe1, 0xdc, 0x20, 0x13,
-	0x51, 0xaf, 0x24, 0xf7, 0x5b, 0x5c, 0xb4, 0x62, 0x4e, 0xb1, 0x9a, 0xf9,
-	0x74, 0x27, 0xf6, 0xb3, 0xcc, 0xcc, 0xa7, 0x27, 0xef, 0xc5, 0x2c, 0x7e,
-	0x57, 0xc3, 0x58, 0xf5, 0x17, 0x67, 0x24, 0x90, 0x29, 0x1f, 0x6b, 0xd4,
-	0x4b, 0xff, 0x24, 0x66, 0xf3, 0x98, 0x15, 0x9e, 0x37, 0x58, 0xfe, 0x72,
-	0x25, 0xaf, 0xfd, 0xb7, 0x2f, 0xad, 0x37, 0x7c, 0x1a, 0xb5, 0xf9, 0x6b,
-	0xfc, 0xdd, 0xb1, 0xde, 0xee, 0xef, 0xe7, 0xd2, 0xf2, 0xfb, 0xeb, 0x69,
-	0x97, 0x34, 0x78, 0x43, 0xab, 0xca, 0x62, 0x28, 0xbb, 0x7d, 0xbd, 0x95,
-	0x0b, 0x28, 0xbb, 0x07, 0x7e, 0x1a, 0xf3, 0x34, 0xf8, 0x8e, 0x32, 0xb8,
-	0x16, 0x27, 0x7d, 0x60, 0x45, 0xf2, 0x3c, 0xe5, 0x22, 0x6d, 0x4a, 0xcc,
-	0x51, 0x7d, 0x27, 0x8c, 0xa3, 0xe3, 0x77, 0x3d, 0xdb, 0x9f, 0xf8, 0x26,
-	0xae, 0xe5, 0xdb, 0x53, 0xe0, 0xfb, 0x03, 0xbe, 0x13, 0x9d, 0x65, 0x1e,
-	0x80, 0xa6, 0xe1, 0xda, 0xbe, 0xaf, 0x47, 0xdf, 0x21, 0x2d, 0x93, 0x5e,
-	0xae, 0xd7, 0x74, 0xd3, 0x44, 0x5d, 0x7c, 0x8c, 0xf4, 0xc7, 0x58, 0x72,
-	0xb3, 0xd6, 0x8f, 0xd5, 0x75, 0x6c, 0x82, 0xae, 0x89, 0x1b, 0x1e, 0x75,
-	0xcd, 0x7e, 0x77, 0xb5, 0xbf, 0x31, 0xf4, 0x47, 0x3b, 0x0d, 0x7e, 0xba,
-	0xc7, 0x68, 0x0e, 0xe5, 0x97, 0x13, 0x55, 0x57, 0x6a, 0x3f, 0x33, 0xa6,
-	0xf3, 0x8e, 0x96, 0xeb, 0x4e, 0xd8, 0xb1, 0x49, 0xb7, 0x26, 0xfe, 0x5f,
-	0x1d, 0x5f, 0x1c, 0xb5, 0x4d, 0x40, 0x65, 0x8d, 0x32, 0x35, 0x40, 0x1a,
-	0xe5, 0xdc, 0xb5, 0x0d, 0x75, 0x0d, 0xed, 0x08, 0x43, 0x9f, 0xb4, 0x9d,
-	0xa2, 0xd7, 0x64, 0x0b, 0x8d, 0xc6, 0x67, 0x89, 0xcb, 0xe6, 0x06, 0x9d,
-	0x47, 0x80, 0xb2, 0x72, 0xa8, 0xcb, 0xa2, 0x32, 0xdb, 0xff, 0xbf, 0x83,
-	0xf4, 0x5e, 0xd6, 0xad, 0xbb, 0x6f, 0x9f, 0x98, 0x11, 0x8d, 0xa7, 0xbf,
-	0xa8, 0xe2, 0xc9, 0xce, 0x2d, 0xbe, 0x7a, 0x6e, 0x05, 0xc0, 0x7b, 0x0f,
-	0x64, 0x27, 0xd7, 0xc9, 0xe4, 0x6f, 0x3f, 0x2e, 0x4e, 0x34, 0xd3, 0x5b,
-	0x6f, 0x6e, 0xa5, 0x10, 0xaf, 0x9c, 0x1b, 0x68, 0x35, 0x9c, 0x17, 0x69,
-	0x3b, 0xae, 0xf7, 0x89, 0x94, 0x22, 0x2c, 0xad, 0xab, 0x70, 0x1b, 0xd2,
-	0x9d, 0xa1, 0xb9, 0xa7, 0x34, 0xcd, 0xb5, 0x58, 0x9a, 0x43, 0x5d, 0x97,
-	0xfb, 0xde, 0xa3, 0x2d, 0x55, 0x9a, 0xdb, 0x60, 0x69, 0xee, 0x99, 0xf5,
-	0x66, 0x4f, 0xfc, 0xfd, 0x2d, 0x66, 0x4f, 0xea, 0x2f, 0x57, 0x3d, 0x6f,
-	0xa2, 0xcd, 0x08, 0x5f, 0x2c, 0x7c, 0xae, 0x85, 0xf5, 0x0c, 0x60, 0xad,
-	0x95, 0x35, 0x4d, 0x36, 0xee, 0xc6, 0xfd, 0x73, 0xfa, 0x7d, 0x51, 0x79,
-	0x14, 0x76, 0x50, 0xbe, 0xfc, 0x8f, 0xc1, 0x02, 0x7c, 0xbf, 0xa9, 0x65,
-	0xdd, 0x7b, 0x5b, 0x0b, 0xf9, 0x6d, 0x06, 0xbf, 0x0e, 0xd6, 0xf8, 0x3c,
-	0x98, 0x2f, 0xca, 0xfe, 0x01, 0xeb, 0x01, 0xb9, 0xbc, 0x5c, 0x97, 0x31,
-	0x0b, 0xe3, 0xe3, 0x30, 0x66, 0x68, 0xf6, 0x13, 0x29, 0xe7, 0xef, 0x84,
-	0x4f, 0x74, 0x0f, 0xf4, 0x24, 0xe9, 0xfb, 0xa5, 0x16, 0x93, 0xe7, 0x1b,
-	0x87, 0x1e, 0xfb, 0x65, 0x9b, 0x0b, 0x75, 0xf8, 0x57, 0xeb, 0xe7, 0xf8,
-	0x82, 0xf6, 0x1d, 0xd2, 0xcc, 0xdf, 0xb7, 0x98, 0x98, 0xf1, 0xb7, 0x5a,
-	0xc8, 0x67, 0x6a, 0xdb, 0x0f, 0x37, 0x68, 0xbe, 0x70, 0xc2, 0xe7, 0xcf,
-	0xb4, 0xae, 0x7c, 0x0e, 0xdb, 0x3d, 0xd9, 0xba, 0xb2, 0x5d, 0x58, 0xfe,
-	0x73, 0x1b, 0x57, 0x96, 0x5f, 0xe3, 0xae, 0x6c, 0xff, 0xf5, 0x55, 0xcf,
-	0x2d, 0x9b, 0x56, 0x3e, 0x5f, 0xbd, 0xea, 0x79, 0x6a, 0xd5, 0xf3, 0x85,
-	0x55, 0xcf, 0x57, 0xb5, 0xad, 0x7c, 0xbe, 0xbd, 0xad, 0x3e, 0xbc, 0x87,
-	0xdb, 0x56, 0xc2, 0x75, 0xa7, 0x8e, 0xf7, 0xcf, 0x54, 0xa2, 0xb2, 0xab,
-	0x80, 0xf7, 0x4e, 0xe7, 0x66, 0xa3, 0xd7, 0x6a, 0xdf, 0x33, 0xbe, 0xf6,
-	0xd7, 0xab, 0xfa, 0xab, 0xb6, 0xdb, 0x5d, 0x6d, 0xe7, 0x57, 0xdb, 0x19,
-	0xd9, 0x36, 0x5b, 0xe1, 0x3b, 0x96, 0x87, 0xfd, 0x9a, 0xb6, 0x53, 0xc5,
-	0x4e, 0x9d, 0x0b, 0x3b, 0xaa, 0x73, 0x61, 0x93, 0xe0, 0xc3, 0x3b, 0x75,
-	0x4c, 0x69, 0x93, 0x42, 0x79, 0xa5, 0x55, 0xc7, 0x95, 0x74, 0x2c, 0xb5,
-	0x30, 0x0a, 0xdb, 0x96, 0x39, 0xb0, 0x81, 0xec, 0xf1, 0xcd, 0xdd, 0xe4,
-	0xc4, 0x1e, 0x0e, 0x86, 0xdd, 0x20, 0x98, 0xf4, 0x6e, 0xb3, 0xf9, 0x62,
-	0xb8, 0x57, 0x4c, 0x1b, 0xea, 0xe0, 0x27, 0xa0, 0x83, 0xab, 0xba, 0xf7,
-	0x4e, 0x8c, 0xb5, 0x00, 0x9a, 0x19, 0x90, 0xdf, 0xad, 0xa4, 0xbe, 0x24,
-	0xfa, 0xcc, 0x4d, 0x3f, 0x6c, 0xb8, 0xa5, 0x4f, 0xbd, 0xdf, 0xf3, 0x61,
-	0xeb, 0x05, 0xf2, 0xb0, 0x3f, 0x08, 0x1a, 0xea, 0x85, 0xbd, 0xe7, 0x69,
-	0xbf, 0xf4, 0xb4, 0xa6, 0x2d, 0xd2, 0x58, 0x8b, 0xce, 0xd7, 0x7f, 0xd4,
-	0x77, 0x62, 0x99, 0xfe, 0x3f, 0x32, 0x71, 0x1a, 0xbf, 0xdb, 0xfd, 0x1a,
-	0xf8, 0x76, 0xa7, 0xb7, 0x05, 0x3e, 0x0a, 0x69, 0x88, 0xf1, 0xaf, 0xcb,
-	0x75, 0x1e, 0x21, 0x03, 0x68, 0x33, 0x51, 0xc6, 0x09, 0x53, 0x83, 0x63,
-	0xc2, 0x79, 0xa7, 0x12, 0x49, 0xa5, 0xed, 0xaa, 0xe0, 0x46, 0x9f, 0x39,
-	0xb6, 0xdc, 0x63, 0x21, 0x3f, 0xef, 0xff, 0xf4, 0x94, 0x97, 0x73, 0x23,
-	0x36, 0x2f, 0x37, 0x53, 0x30, 0xb4, 0x39, 0x41, 0xda, 0x84, 0x3f, 0xb5,
-	0xd8, 0xff, 0xb7, 0x01, 0xed, 0xfb, 0xa4, 0x22, 0xed, 0xff, 0x4d, 0x30,
-	0x17, 0x65, 0x5f, 0x84, 0x7b, 0xff, 0xa7, 0x33, 0x1a, 0x57, 0x77, 0xca,
-	0x81, 0x22, 0x6d, 0xe1, 0x98, 0xce, 0xe7, 0x18, 0xf7, 0x69, 0xa7, 0xc5,
-	0x80, 0xc7, 0x0f, 0x01, 0x7f, 0x2d, 0xb0, 0xb9, 0x47, 0x50, 0x27, 0x22,
-	0x63, 0x60, 0xf1, 0xd9, 0x02, 0xf9, 0x93, 0xf7, 0x28, 0xea, 0xbb, 0x32,
-	0x5f, 0xb8, 0x59, 0xe7, 0xdb, 0x9d, 0x46, 0xdb, 0x27, 0x71, 0xcd, 0x16,
-	0x26, 0xd0, 0x66, 0xaf, 0xae, 0x3f, 0x5b, 0x62, 0x8e, 0xb2, 0x40, 0x2e,
-	0xed, 0x97, 0xfc, 0x5c, 0x97, 0x8c, 0xc5, 0x17, 0x66, 0xa2, 0xcb, 0x71,
-	0x99, 0x8f, 0x6f, 0xe0, 0x1e, 0x47, 0xfe, 0x4a, 0xee, 0x07, 0x4b, 0x74,
-	0x74, 0xbb, 0xea, 0x6d, 0xd3, 0x3e, 0xd7, 0xa0, 0xec, 0xac, 0x0c, 0xc9,
-	0x4d, 0x95, 0xcf, 0x6e, 0x36, 0xb1, 0xa8, 0x15, 0xf1, 0xad, 0xc3, 0xc4,
-	0x8a, 0x3a, 0x1a, 0xe5, 0xb9, 0x25, 0x99, 0x3d, 0x25, 0x12, 0x39, 0x1a,
-	0xc6, 0x12, 0x59, 0xe6, 0x4a, 0xd7, 0x95, 0x80, 0xeb, 0x14, 0x64, 0x6b,
-	0x3c, 0x26, 0x5f, 0xdc, 0x16, 0x8e, 0x95, 0x0b, 0xa6, 0xb7, 0xe5, 0xe4,
-	0xd3, 0xb8, 0xb2, 0x57, 0xa6, 0x4a, 0x19, 0xc5, 0x71, 0xbf, 0x13, 0x50,
-	0x96, 0xa9, 0x21, 0x4f, 0x72, 0x6d, 0xe1, 0xd8, 0xf0, 0x6f, 0x76, 0x84,
-	0xe3, 0xd3, 0xe6, 0x36, 0x67, 0x1e, 0xf2, 0xdc, 0x77, 0x01, 0xfd, 0x45,
-	0x86, 0xee, 0xde, 0x40, 0xdf, 0x61, 0x58, 0xd8, 0x0e, 0x32, 0x5d, 0xb1,
-	0x6f, 0xc2, 0x49, 0xf8, 0x6b, 0xe1, 0x5c, 0x4c, 0xc6, 0x81, 0xa3, 0xdc,
-	0xeb, 0xc2, 0xdb, 0xe7, 0x7a, 0xaa, 0x1e, 0xbc, 0xa3, 0x36, 0x96, 0xc8,
-	0xf8, 0xe0, 0x3a, 0xe0, 0xad, 0x05, 0xe5, 0x1f, 0x94, 0xa9, 0x63, 0x6f,
-	0xdb, 0xcc, 0xbd, 0xec, 0x06, 0xcf, 0xb1, 0x39, 0xa7, 0x3c, 0xbf, 0x73,
-	0x37, 0xea, 0xf0, 0xfd, 0xcd, 0x68, 0x93, 0xca, 0x65, 0x22, 0x9b, 0xe1,
-	0x13, 0x71, 0xdc, 0x20, 0xd2, 0xb5, 0xa3, 0x59, 0xe7, 0x90, 0xca, 0x29,
-	0xea, 0xf3, 0xb0, 0xed, 0xdd, 0x3a, 0x47, 0x03, 0x7e, 0x7b, 0x6e, 0x24,
-	0x42, 0xf9, 0xd5, 0x2b, 0xc3, 0xd4, 0x27, 0xa7, 0x6e, 0xd6, 0xb4, 0xdf,
-	0xbd, 0x8d, 0x67, 0x99, 0xfa, 0x8c, 0x8d, 0x1e, 0x27, 0x8c, 0xa3, 0x28,
-	0x87, 0xfd, 0xfe, 0x9a, 0x30, 0xdc, 0xf5, 0x26, 0x61, 0xb8, 0xeb, 0x4d,
-	0xc2, 0x40, 0x5c, 0x00, 0x8e, 0xca, 0x5f, 0x6c, 0x08, 0x63, 0xd5, 0x97,
-	0x62, 0x1e, 0x07, 0x8b, 0x77, 0xc9, 0xa1, 0xa2, 0xa3, 0xe3, 0x8e, 0x0b,
-	0x8a, 0x32, 0xc1, 0x05, 0x4f, 0x82, 0xf7, 0x8a, 0xe0, 0xcd, 0x22, 0x78,
-	0xb1, 0x08, 0xbe, 0x84, 0xfd, 0x7f, 0x06, 0xf6, 0xff, 0x93, 0x58, 0x9b,
-	0xd3, 0x2b, 0x78, 0x39, 0xad, 0x79, 0x39, 0x5f, 0xa4, 0xaf, 0xd6, 0x7f,
-	0x11, 0x7e, 0x8d, 0xca, 0x70, 0x21, 0x05, 0x55, 0xe2, 0x44, 0xb3, 0xfd,
-	0x9f, 0x24, 0xbf, 0xca, 0x83, 0xfe, 0x0d, 0x68, 0x73, 0x18, 0x34, 0x9e,
-	0xa2, 0x1d, 0x48, 0xfb, 0x27, 0x07, 0xde, 0x3c, 0x4c, 0x5f, 0x4d, 0x5d,
-	0xb9, 0x49, 0xa8, 0x5f, 0xa2, 0x3b, 0x98, 0x7b, 0xc8, 0xb9, 0x26, 0x57,
-	0xe1, 0xc9, 0xf0, 0xef, 0x84, 0x47, 0x3d, 0x43, 0xbe, 0x7d, 0x99, 0x7c,
-	0x5b, 0xc3, 0xab, 0x01, 0xe7, 0x17, 0xb8, 0xdb, 0xea, 0xb5, 0xad, 0xd6,
-	0xdf, 0xb4, 0x5c, 0x5f, 0x8f, 0x5f, 0x22, 0x3f, 0x42, 0x27, 0x11, 0xf7,
-	0xc9, 0x4c, 0x64, 0x8b, 0xc5, 0x3d, 0x6c, 0xb7, 0x1d, 0x97, 0x00, 0xf7,
-	0x9d, 0x92, 0x9b, 0x0f, 0xc4, 0xdb, 0x11, 0xf6, 0x59, 0xed, 0xc7, 0xb5,
-	0xfd, 0x8c, 0x17, 0x1c, 0x19, 0xd9, 0xc6, 0x7d, 0x08, 0x07, 0x7a, 0x3e,
-	0x5c, 0x0f, 0xd8, 0xfb, 0x7a, 0xcd, 0x29, 0x63, 0x29, 0x5b, 0x5b, 0x6c,
-	0xfc, 0x89, 0xfd, 0x1d, 0x5e, 0xb5, 0x4e, 0x17, 0x02, 0x9e, 0x11, 0x9b,
-	0xf2, 0x6e, 0xa8, 0xa1, 0x95, 0xfb, 0x2c, 0xad, 0xa8, 0x55, 0xf3, 0xb8,
-	0xdd, 0xd2, 0x4a, 0x08, 0x6f, 0x3c, 0xa4, 0x95, 0xa6, 0x90, 0x56, 0x72,
-	0x33, 0x21, 0xad, 0xb0, 0xed, 0xed, 0x21, 0xad, 0x24, 0x6b, 0x69, 0x25,
-	0x37, 0xe3, 0xe0, 0x5a, 0x0d, 0x07, 0xe9, 0x85, 0xfd, 0x90, 0x5e, 0x00,
-	0x4b, 0xe5, 0xd6, 0xd6, 0x90, 0x5e, 0xe2, 0xe8, 0xe7, 0x50, 0xd1, 0xe4,
-	0x74, 0xc0, 0xef, 0xb2, 0x3a, 0xc4, 0xc5, 0x9a, 0x1b, 0x1f, 0xb1, 0x3e,
-	0x8d, 0xf8, 0x96, 0x46, 0xaa, 0x79, 0xee, 0xab, 0x68, 0x03, 0xb8, 0x67,
-	0x2e, 0xeb, 0x76, 0x4d, 0x1b, 0xf7, 0xfb, 0x53, 0xa8, 0xbb, 0x07, 0xb4,
-	0x11, 0xe2, 0xe0, 0x7a, 0x8b, 0x83, 0xd5, 0x6b, 0x39, 0x66, 0x71, 0xb0,
-	0xc7, 0xe2, 0x40, 0xf3, 0x4b, 0x8e, 0x6b, 0xa6, 0x34, 0x0e, 0x9a, 0x34,
-	0x0e, 0x44, 0x85, 0x6d, 0xc7, 0xea, 0xe0, 0x80, 0x75, 0xf6, 0xe8, 0xf9,
-	0x47, 0x30, 0xff, 0xfd, 0x98, 0xbf, 0xd2, 0xf3, 0xe7, 0x3a, 0x70, 0xfe,
-	0x80, 0xa5, 0x72, 0x72, 0x79, 0xfe, 0x6d, 0xe8, 0xe3, 0x60, 0x31, 0xa2,
-	0xe7, 0x0f, 0xdb, 0x7e, 0x30, 0x9c, 0xff, 0xe9, 0x8a, 0xc9, 0x7f, 0x3e,
-	0xbd, 0x46, 0xcf, 0x4d, 0x59, 0xde, 0xf0, 0xb4, 0x5f, 0xcc, 0x98, 0xf6,
-	0x19, 0xe8, 0xb6, 0x69, 0x3f, 0x69, 0xcf, 0x43, 0x19, 0x7b, 0xe9, 0x1b,
-	0x3e, 0x79, 0xe7, 0xe3, 0x3a, 0x0f, 0xe5, 0x71, 0xda, 0x4d, 0xc5, 0x36,
-	0x19, 0x99, 0xae, 0x85, 0x9b, 0xf0, 0xe6, 0xb4, 0x1c, 0xcd, 0x62, 0x7e,
-	0xe3, 0x7e, 0x2f, 0xe4, 0x9b, 0xa6, 0x25, 0x94, 0xa7, 0x72, 0xc3, 0x91,
-	0x26, 0x51, 0x0f, 0x7c, 0x08, 0x73, 0x8e, 0xca, 0x66, 0xaf, 0xdb, 0xdd,
-	0xa1, 0xa8, 0x0b, 0x2f, 0xab, 0xd1, 0x85, 0xed, 0x56, 0x17, 0x6e, 0xa2,
-	0x2e, 0x04, 0xdc, 0x77, 0xca, 0xe1, 0x22, 0xd7, 0x2f, 0x97, 0x6c, 0x82,
-	0xfe, 0xff, 0x81, 0xc7, 0xb3, 0x27, 0x3a, 0x6e, 0x96, 0x38, 0xac, 0x69,
-	0x99, 0x3a, 0x2d, 0xa5, 0xcf, 0x6a, 0x2c, 0xd2, 0xc6, 0x8e, 0x33, 0x16,
-	0x4a, 0xbd, 0xf7, 0xe3, 0xe0, 0x73, 0x75, 0xf4, 0xde, 0x64, 0xd1, 0xd8,
-	0x6f, 0x0d, 0xb0, 0x09, 0xe5, 0x44, 0x3b, 0xae, 0x8d, 0x3c, 0xab, 0xd0,
-	0xdb, 0xa3, 0x9a, 0xa5, 0xe1, 0x44, 0xab, 0x4c, 0x4c, 0x1b, 0x1b, 0x57,
-	0x9d, 0x00, 0xfe, 0x4f, 0x30, 0xdf, 0x55, 0x74, 0x7e, 0x7e, 0xb6, 0x04,
-	0x3b, 0x77, 0xf6, 0x4e, 0x93, 0xb7, 0x32, 0xdd, 0xa0, 0x7f, 0xd3, 0x06,
-	0xc9, 0xfb, 0x69, 0xe8, 0xbb, 0x98, 0x4c, 0xa0, 0xcf, 0xee, 0x6d, 0x8d,
-	0x98, 0x73, 0x1c, 0x6d, 0xe9, 0xf3, 0x31, 0x8e, 0xd6, 0x28, 0xd1, 0xd9,
-	0xb8, 0xce, 0xad, 0xe7, 0xd9, 0xd1, 0xcc, 0x60, 0x1b, 0xde, 0x31, 0x9f,
-	0xc1, 0xc5, 0x58, 0xa1, 0xec, 0x47, 0xbf, 0x47, 0xc5, 0xee, 0xf7, 0x0c,
-	0x69, 0xfd, 0x17, 0x39, 0xea, 0xda, 0x33, 0x74, 0x83, 0x58, 0xf7, 0x7a,
-	0x7a, 0xd1, 0x18, 0xb9, 0x19, 0xac, 0x9f, 0x3a, 0x15, 0xc5, 0xbd, 0x13,
-	0xf7, 0xb0, 0xbf, 0x50, 0x8f, 0x40, 0x37, 0xbe, 0xb3, 0x6f, 0xa3, 0x34,
-	0x03, 0xdf, 0xb3, 0x0a, 0xb8, 0x36, 0x39, 0x59, 0x39, 0xcd, 0x0b, 0x55,
-	0x7a, 0x78, 0xf2, 0x75, 0xf9, 0x81, 0x34, 0x41, 0x5a, 0xa0, 0x5c, 0x24,
-	0x6d, 0x50, 0x26, 0x3a, 0xfa, 0x6c, 0x03, 0xe9, 0xe1, 0x09, 0xdf, 0x8b,
-	0x70, 0xdf, 0xde, 0xc4, 0xe5, 0x49, 0x1b, 0xa4, 0xf9, 0xa4, 0x8e, 0xd7,
-	0xa7, 0xe5, 0x7b, 0x92, 0x6e, 0xeb, 0x86, 0x5d, 0xf6, 0x2f, 0xbb, 0xc6,
-	0xe6, 0xdc, 0xad, 0xa6, 0x39, 0xe8, 0x26, 0xe6, 0xd0, 0xf5, 0xca, 0xfb,
-	0x2a, 0x39, 0xe0, 0xe1, 0x5e, 0x28, 0xe5, 0x3b, 0x75, 0x5e, 0xe2, 0xee,
-	0xc2, 0x46, 0xb9, 0xc5, 0x8f, 0xd9, 0xb8, 0xfb, 0x41, 0xd0, 0xc1, 0xa2,
-	0x23, 0x27, 0xce, 0xe2, 0x3a, 0xe7, 0x70, 0xfd, 0xce, 0xfb, 0xe9, 0x94,
-	0x22, 0xb3, 0x7b, 0xd1, 0xc4, 0xa2, 0xf4, 0xb9, 0x13, 0xfa, 0x0c, 0xc8,
-	0x82, 0xd3, 0x74, 0xe2, 0xd0, 0x46, 0xe3, 0x4b, 0x03, 0x16, 0xaf, 0xd1,
-	0x1d, 0xa1, 0x2d, 0xe7, 0x07, 0x41, 0x96, 0x76, 0x83, 0x28, 0xed, 0x23,
-	0xc1, 0xe7, 0x43, 0x19, 0xe3, 0x13, 0x5b, 0x9d, 0xc6, 0x53, 0x2f, 0x5a,
-	0x5a, 0x91, 0x88, 0x1a, 0x7a, 0xc6, 0x69, 0x38, 0x71, 0x9c, 0x6b, 0xa6,
-	0xf3, 0xa4, 0x0d, 0x5d, 0x3d, 0xe7, 0x54, 0xe9, 0xea, 0x1b, 0xf6, 0xb7,
-	0x1a, 0x6a, 0x92, 0x74, 0xaa, 0x09, 0xf3, 0x1d, 0x2e, 0x84, 0x30, 0x7e,
-	0x1f, 0x70, 0x11, 0x1e, 0xd0, 0xed, 0xec, 0x9f, 0xe1, 0x5a, 0x02, 0x2c,
-	0xf7, 0x01, 0xee, 0xf3, 0x80, 0xf9, 0x02, 0x2e, 0xd5, 0x11, 0x91, 0x3f,
-	0x76, 0x22, 0xb3, 0xb5, 0xf0, 0x12, 0xc6, 0xd3, 0x16, 0xde, 0xd7, 0x82,
-	0xd5, 0x95, 0xc5, 0x81, 0x2e, 0xc0, 0x43, 0x38, 0x5f, 0x02, 0x8c, 0xb4,
-	0x5b, 0x9f, 0xc7, 0xb3, 0x0b, 0xf8, 0x5e, 0xb0, 0x30, 0x81, 0x1e, 0xa7,
-	0xff, 0x47, 0xf5, 0x77, 0x81, 0x76, 0xf4, 0x9f, 0xdb, 0xe7, 0xce, 0x55,
-	0x32, 0xa0, 0xc7, 0x21, 0x9e, 0xa7, 0x8a, 0x4b, 0xb4, 0x03, 0xc0, 0xf7,
-	0x3f, 0x94, 0xc8, 0xa9, 0x84, 0x1c, 0x2a, 0x70, 0x0f, 0xe8, 0x24, 0xf0,
-	0xa1, 0xcf, 0xa4, 0xa0, 0xce, 0x15, 0xb8, 0xa0, 0xec, 0x67, 0xb7, 0xe3,
-	0xea, 0xc5, 0xf5, 0x56, 0x5c, 0x20, 0x87, 0xd9, 0x13, 0xb8, 0xfa, 0xd0,
-	0xb7, 0x8a, 0x37, 0x09, 0x73, 0xa9, 0xbe, 0x8d, 0x36, 0xda, 0xb6, 0xcc,
-	0xa9, 0xa1, 0x01, 0xe0, 0x6f, 0x00, 0xb0, 0x25, 0x70, 0x31, 0xff, 0xf8,
-	0x87, 0x8e, 0x9c, 0x7a, 0x19, 0x17, 0x18, 0xec, 0x14, 0x08, 0xf3, 0xd4,
-	0x20, 0x2e, 0x28, 0xb1, 0x53, 0x69, 0x5c, 0x23, 0xb8, 0xfe, 0xd2, 0x31,
-	0x3c, 0xd7, 0x09, 0x7c, 0x85, 0x3c, 0x02, 0x9c, 0xaf, 0xe0, 0xb9, 0xaf,
-	0x3b, 0x6f, 0x9c, 0xe7, 0x7e, 0xe2, 0x18, 0x9e, 0x7b, 0xc5, 0xa9, 0xf2,
-	0xdc, 0x59, 0x47, 0x3d, 0xfc, 0x8c, 0x13, 0x79, 0x98, 0xbe, 0xc4, 0x59,
-	0xc7, 0xf0, 0x7f, 0x44, 0x86, 0xf7, 0x82, 0x96, 0x1e, 0x5e, 0xc0, 0x45,
-	0xba, 0x7a, 0x16, 0xe5, 0x2f, 0xac, 0x1a, 0xf7, 0xf9, 0x37, 0x31, 0xee,
-	0xab, 0x76, 0x5c, 0x51, 0xd5, 0x71, 0x2f, 0xa0, 0xef, 0x97, 0xec, 0xb8,
-	0x17, 0x6a, 0xc6, 0x05, 0xad, 0x3c, 0xbc, 0x84, 0x8b, 0x74, 0xf1, 0x22,
-	0xca, 0x43, 0x99, 0x80, 0x85, 0x6e, 0x6e, 0xd0, 0x67, 0x9d, 0xe2, 0x5e,
-	0xc3, 0xb2, 0x6e, 0x4c, 0xd7, 0xe8, 0x87, 0x37, 0xa2, 0x1f, 0x27, 0x8b,
-	0xb4, 0x11, 0x17, 0x6a, 0xe4, 0x02, 0x7d, 0xa3, 0x40, 0x8e, 0x69, 0x3f,
-	0x88, 0x3e, 0x11, 0xfd, 0xa3, 0xd5, 0xb6, 0xd5, 0x27, 0x75, 0xee, 0xd8,
-	0xaf, 0x15, 0x3a, 0xe5, 0xd3, 0x05, 0xda, 0x84, 0xa4, 0x97, 0x20, 0x98,
-	0xd8, 0x41, 0xfb, 0x34, 0x17, 0x5c, 0xe2, 0x91, 0x4e, 0x3c, 0xf7, 0x33,
-	0x6b, 0x75, 0x46, 0x69, 0x18, 0xbe, 0x7b, 0xe6, 0xe8, 0xaf, 0x40, 0x67,
-	0x34, 0x00, 0x6e, 0xd2, 0x5b, 0x87, 0xdc, 0x58, 0x52, 0x53, 0x9b, 0x25,
-	0x21, 0x37, 0x15, 0x1a, 0x61, 0xf7, 0x30, 0xaf, 0xaa, 0x59, 0xba, 0x77,
-	0xc4, 0x4c, 0xde, 0xb7, 0x1b, 0xc7, 0x6f, 0xd7, 0xe4, 0xa1, 0xc7, 0x13,
-	0x78, 0xff, 0x7b, 0x2e, 0xe5, 0x60, 0xdc, 0xbb, 0x56, 0xe7, 0xf4, 0x74,
-	0xed, 0xa0, 0xdd, 0x72, 0xbd, 0xd6, 0xe1, 0xd1, 0x35, 0x76, 0x92, 0xea,
-	0x70, 0xa5, 0x6a, 0xa3, 0x8d, 0x17, 0x52, 0x49, 0xc2, 0xf5, 0x90, 0x70,
-	0xff, 0xeb, 0x1e, 0xc9, 0xfb, 0xad, 0xf0, 0x0b, 0x18, 0x3b, 0x4f, 0xf5,
-	0xd2, 0x36, 0x9a, 0x9d, 0x76, 0x6d, 0x5e, 0xf4, 0x46, 0x79, 0x4e, 0x8f,
-	0xd3, 0xa8, 0x61, 0x34, 0x67, 0x25, 0xb8, 0x8f, 0x10, 0xd3, 0xe7, 0x73,
-	0x66, 0xcb, 0x2d, 0x5a, 0xef, 0xcc, 0x96, 0x99, 0x87, 0x0f, 0x7f, 0xaa,
-	0xcc, 0xbc, 0x7b, 0x5f, 0xdc, 0x77, 0xc2, 0xcf, 0x2d, 0x6f, 0x91, 0xf1,
-	0xe9, 0x75, 0xd2, 0xe8, 0xa9, 0xf8, 0x66, 0xc8, 0x47, 0xb6, 0xe9, 0xda,
-	0x01, 0xff, 0x70, 0x66, 0xab, 0x3c, 0x39, 0xc3, 0xbe, 0x3b, 0x64, 0x6e,
-	0x5e, 0x1c, 0xf7, 0x9d, 0xeb, 0x51, 0x07, 0x72, 0x7d, 0x07, 0xcb, 0x92,
-	0xb8, 0x8b, 0x72, 0xdf, 0x19, 0x95, 0x73, 0x03, 0x7c, 0x66, 0xee, 0xbf,
-	0x44, 0xd9, 0xdf, 0xb9, 0x81, 0x4e, 0x79, 0x7c, 0x1e, 0x34, 0x01, 0xb9,
-	0x3f, 0x72, 0x82, 0x30, 0x89, 0xec, 0x9a, 0x65, 0x2c, 0xbd, 0xdb, 0x65,
-	0xdc, 0x94, 0xfb, 0x34, 0xb7, 0x0c, 0x70, 0x2c, 0xe8, 0x25, 0xe8, 0xb8,
-	0xae, 0x1d, 0x46, 0x16, 0xa4, 0x67, 0x1b, 0x50, 0xce, 0x7e, 0xe1, 0x3f,
-	0xee, 0x65, 0x3f, 0x61, 0x5b, 0x85, 0x39, 0x35, 0x6a, 0x7a, 0x59, 0x5a,
-	0xa5, 0x3f, 0xce, 0xfc, 0x4c, 0xf6, 0x37, 0xfb, 0xe8, 0xd5, 0x7b, 0x21,
-	0xdc, 0x53, 0x36, 0xb6, 0x15, 0xd7, 0x44, 0xef, 0x29, 0xc0, 0xae, 0xba,
-	0x42, 0xdb, 0x17, 0x73, 0x15, 0xae, 0x20, 0x63, 0x51, 0xe1, 0x1a, 0x25,
-	0xe4, 0xd1, 0xe2, 0xf2, 0x3a, 0x6d, 0x69, 0x58, 0xb9, 0x4e, 0xa4, 0x15,
-	0x7f, 0xcc, 0xda, 0x1e, 0x8b, 0x92, 0x83, 0x5d, 0xd6, 0xab, 0xd7, 0x6c,
-	0x11, 0xb6, 0xac, 0x5d, 0x33, 0x6d, 0xcf, 0xe6, 0xc3, 0x35, 0x1b, 0x85,
-	0xc6, 0x29, 0xab, 0x4d, 0x5c, 0x33, 0x97, 0xf1, 0x6e, 0xe0, 0x3d, 0x87,
-	0x75, 0xca, 0x61, 0x8d, 0x72, 0xe5, 0x0e, 0x99, 0x3d, 0xa6, 0x3a, 0x1b,
-	0x44, 0x92, 0xe3, 0x5e, 0x87, 0x4c, 0xce, 0x33, 0x96, 0xb0, 0x05, 0x36,
-	0xd8, 0x56, 0x5c, 0x9d, 0x78, 0x66, 0x3b, 0xf0, 0x54, 0x59, 0xa1, 0x6d,
-	0xd3, 0x1a, 0x3b, 0xeb, 0x71, 0x8c, 0xcd, 0x1c, 0xe1, 0x27, 0x80, 0x87,
-	0x2a, 0xef, 0x4c, 0xd5, 0xc4, 0x9f, 0x38, 0x57, 0xad, 0x43, 0x31, 0xdf,
-	0xb8, 0x5e, 0x4f, 0x1d, 0x87, 0x2a, 0x36, 0xbe, 0x19, 0x7b, 0x2a, 0x41,
-	0x7b, 0x2a, 0x5b, 0x72, 0xcd, 0xf9, 0x80, 0x51, 0xf8, 0x4e, 0x5e, 0xef,
-	0x26, 0xd2, 0xfa, 0xd8, 0x0c, 0xe1, 0x8a, 0x85, 0x70, 0xad, 0x58, 0x33,
-	0x9e, 0xe7, 0x5a, 0x1b, 0xe7, 0x98, 0x5a, 0xce, 0x5f, 0x34, 0xb1, 0x7d,
-	0xc6, 0x51, 0x3a, 0xeb, 0xc0, 0x74, 0xa7, 0xb6, 0x61, 0x45, 0x8d, 0xc9,
-	0x81, 0x22, 0xcf, 0x82, 0x31, 0x9e, 0x78, 0x23, 0xe3, 0x49, 0xbd, 0xb3,
-	0xf2, 0x5e, 0x8c, 0xcd, 0x5c, 0x1d, 0x65, 0xe3, 0x37, 0x1b, 0x6c, 0x8e,
-	0x48, 0x6d, 0x0c, 0xc7, 0xe4, 0xf2, 0xac, 0xcc, 0x8b, 0x4e, 0x8d, 0x2e,
-	0x61, 0x9d, 0x7f, 0x5d, 0xef, 0x0d, 0x4a, 0x29, 0x02, 0xed, 0x37, 0x3e,
-	0x90, 0x1a, 0x34, 0xe7, 0x60, 0x92, 0xb2, 0xb3, 0x68, 0xe6, 0x7f, 0x5e,
-	0xe7, 0xf4, 0x98, 0xdc, 0x45, 0x93, 0xef, 0x73, 0x8f, 0x9c, 0x87, 0x0e,
-	0xaf, 0xae, 0x6d, 0x93, 0x4c, 0x02, 0x17, 0x59, 0xbd, 0x2f, 0x91, 0x94,
-	0xec, 0xc0, 0xc7, 0x37, 0xf1, 0x9c, 0x44, 0x0c, 0xeb, 0x93, 0x9f, 0xe1,
-	0xd9, 0x49, 0xf6, 0x7b, 0xb1, 0xbe, 0x28, 0x66, 0x99, 0x87, 0x0f, 0x59,
-	0xf9, 0xb6, 0xbe, 0x44, 0xb3, 0x7e, 0xbf, 0xce, 0xe6, 0x5b, 0x3b, 0x22,
-	0x37, 0x06, 0xf2, 0x87, 0x10, 0x9f, 0x8f, 0xd9, 0x39, 0x25, 0x75, 0xcc,
-	0x4a, 0x82, 0x73, 0x7e, 0xc2, 0xc6, 0x2c, 0x39, 0x97, 0x1b, 0x2c, 0x7d,
-	0x1b, 0xfb, 0xa7, 0x6a, 0x43, 0x9b, 0x7d, 0xbf, 0x27, 0xb5, 0x2c, 0xec,
-	0xb7, 0xb6, 0xb3, 0x8e, 0xf3, 0x1c, 0x17, 0x9d, 0x13, 0x10, 0xfa, 0x46,
-	0x3d, 0x35, 0x7e, 0x81, 0xf1, 0xe5, 0xf2, 0xd3, 0xf5, 0x64, 0x54, 0xd5,
-	0x27, 0xa4, 0x2f, 0x37, 0xb1, 0x8d, 0xdf, 0x2d, 0x08, 0x7d, 0xb9, 0x7e,
-	0xeb, 0xcb, 0xb5, 0x6a, 0x5f, 0xce, 0xc4, 0x1e, 0x5a, 0x97, 0x7d, 0xb9,
-	0xfc, 0x74, 0x0e, 0xb4, 0x12, 0x7e, 0x67, 0xc1, 0xd8, 0x42, 0x93, 0x05,
-	0x9e, 0x79, 0x69, 0x94, 0xec, 0xa8, 0x82, 0xdf, 0x60, 0x7c, 0x2c, 0xc6,
-	0x2a, 0x94, 0xfa, 0x96, 0xf5, 0x2f, 0x3a, 0x25, 0xdd, 0xbe, 0x0e, 0xf3,
-	0xbe, 0x53, 0xaf, 0xf9, 0x5c, 0xc1, 0xec, 0x7d, 0x66, 0xf7, 0x32, 0x26,
-	0xc4, 0x73, 0x4d, 0x9a, 0xbf, 0x92, 0xc3, 0x91, 0x5e, 0x63, 0xcf, 0x7a,
-	0xdf, 0x04, 0xde, 0x4f, 0x02, 0xe7, 0x31, 0x3b, 0x6e, 0x12, 0x30, 0x1d,
-	0xc0, 0xda, 0x5c, 0x6b, 0x65, 0x32, 0xc7, 0xde, 0xd3, 0xc4, 0xd8, 0xc0,
-	0x7c, 0x21, 0x8c, 0x11, 0x46, 0xec, 0x99, 0x4a, 0x2f, 0xd2, 0xe8, 0xad,
-	0xab, 0x6b, 0xab, 0x9e, 0x7e, 0x5d, 0xdd, 0x44, 0x5a, 0xba, 0x53, 0xe7,
-	0xb9, 0xac, 0x1f, 0x48, 0xed, 0xd1, 0x39, 0xf2, 0x3a, 0xc6, 0x98, 0x13,
-	0xe6, 0x94, 0x7d, 0x57, 0xde, 0xa1, 0x65, 0xfe, 0x01, 0x9f, 0xfa, 0x6b,
-	0x87, 0xfe, 0xdd, 0x38, 0x14, 0x04, 0xe7, 0x06, 0xee, 0x86, 0xad, 0xe2,
-	0xb9, 0xdf, 0x97, 0xee, 0xc4, 0xb0, 0xb6, 0x9d, 0xb0, 0x46, 0x7b, 0x9b,
-	0x65, 0x9d, 0x77, 0xb3, 0xcd, 0x99, 0xc9, 0x41, 0x6e, 0xa6, 0x60, 0x33,
-	0xf1, 0x4c, 0x70, 0x8f, 0x7d, 0x97, 0x0b, 0x9a, 0x41, 0x47, 0x1f, 0x13,
-	0x23, 0x63, 0xb2, 0x55, 0x19, 0xc3, 0x5c, 0x83, 0x34, 0x09, 0x39, 0x7a,
-	0x44, 0x52, 0xfc, 0xee, 0x07, 0xc7, 0xce, 0xcb, 0xa5, 0xd0, 0xcb, 0x6c,
-	0xa7, 0xbf, 0xd9, 0x83, 0x67, 0xee, 0xe1, 0x78, 0xee, 0x41, 0xe8, 0x96,
-	0xeb, 0xd7, 0xea, 0x96, 0x04, 0xfd, 0xfa, 0x6c, 0x89, 0xbe, 0xe1, 0x7a,
-	0xb4, 0xe9, 0x90, 0x8f, 0x4f, 0x77, 0xb7, 0x91, 0xb7, 0xc6, 0x20, 0xd7,
-	0xd5, 0xfd, 0xe1, 0x59, 0x20, 0x96, 0xf1, 0x3d, 0xfb, 0x6d, 0x92, 0xe4,
-	0xfb, 0x5d, 0xf9, 0x7c, 0x25, 0x95, 0x5c, 0x82, 0x6e, 0x1a, 0x73, 0x7e,
-	0xf1, 0x72, 0x13, 0x53, 0x7d, 0x7b, 0x9b, 0x39, 0x3b, 0xd0, 0x4c, 0x9b,
-	0xdd, 0xc6, 0x59, 0x6b, 0x69, 0x76, 0xc9, 0xca, 0xe3, 0x20, 0x68, 0x1e,
-	0xd0, 0x32, 0x78, 0x0f, 0x65, 0xf0, 0x01, 0xbf, 0xc7, 0xd0, 0xbe, 0xf6,
-	0x99, 0x02, 0xac, 0x23, 0xf0, 0x30, 0x10, 0x65, 0x7e, 0x9e, 0xe5, 0x4f,
-	0x2f, 0xbd, 0x68, 0xe5, 0x92, 0x72, 0xd6, 0xf2, 0xa5, 0xba, 0x2a, 0xb6,
-	0x42, 0xe6, 0x1e, 0x9a, 0xa6, 0x3e, 0xf6, 0x17, 0xbe, 0x0b, 0x39, 0x95,
-	0xd5, 0x78, 0xe8, 0x90, 0xfb, 0xa6, 0x25, 0x7d, 0x1e, 0xba, 0x2a, 0x3f,
-	0xbf, 0x92, 0x37, 0xd7, 0xf6, 0xc7, 0xb9, 0x7e, 0xb8, 0xcd, 0xf8, 0xb6,
-	0x2b, 0xe7, 0xba, 0x80, 0xb9, 0xa6, 0xf5, 0x5c, 0xb9, 0x6f, 0xf3, 0x31,
-	0x3b, 0xd7, 0xf5, 0xe1, 0x5c, 0x07, 0x57, 0xce, 0x35, 0xf4, 0xed, 0x43,
-	0xb9, 0x9b, 0xd4, 0xf9, 0xf2, 0x3a, 0x4f, 0x7b, 0x7a, 0xbd, 0x0c, 0x97,
-	0x5a, 0xad, 0xbc, 0x74, 0xa1, 0x7b, 0x98, 0xc3, 0xbe, 0x70, 0xaf, 0x2b,
-	0x16, 0x67, 0x8a, 0x78, 0xa0, 0xac, 0x6d, 0xd3, 0x67, 0x6c, 0x66, 0xe1,
-	0x5f, 0xdd, 0x5a, 0x60, 0xdd, 0xf0, 0xfd, 0xc5, 0x62, 0xc7, 0xa1, 0x4f,
-	0x4d, 0xbf, 0xa9, 0x77, 0x4d, 0x4c, 0xc1, 0xc4, 0x87, 0x19, 0x17, 0x36,
-	0x67, 0x7f, 0x99, 0x8b, 0x78, 0x07, 0x78, 0xea, 0x53, 0x85, 0xd4, 0x60,
-	0x26, 0x42, 0x39, 0x7a, 0x5c, 0x0e, 0x55, 0x46, 0xa4, 0x4b, 0x9f, 0xff,
-	0x7c, 0xdd, 0xd8, 0x71, 0xba, 0x36, 0x76, 0xcc, 0x74, 0x02, 0xc6, 0x8e,
-	0xf7, 0xfc, 0x0c, 0xb1, 0x63, 0x71, 0x4c, 0xec, 0xb8, 0x9e, 0x7f, 0x35,
-	0x55, 0x3c, 0x8e, 0x79, 0x35, 0x43, 0x96, 0x2c, 0x3a, 0xd9, 0xf9, 0x16,
-	0xdc, 0xcf, 0xe2, 0x1e, 0xc3, 0xfd, 0x3c, 0xee, 0x2e, 0xee, 0x17, 0x70,
-	0x8f, 0xcb, 0xd4, 0xb2, 0xce, 0x38, 0x0e, 0xb9, 0x41, 0x5d, 0xc6, 0xb6,
-	0xc6, 0x1f, 0x98, 0x2b, 0xb7, 0xf3, 0x7b, 0x2d, 0xce, 0xec, 0x3c, 0xe7,
-	0xd0, 0x2a, 0x93, 0xd3, 0x94, 0xd9, 0x6d, 0x52, 0x9a, 0x0e, 0x6d, 0xdb,
-	0x9f, 0xef, 0xe0, 0x9e, 0xc1, 0x98, 0x84, 0xb6, 0xeb, 0x3d, 0x1d, 0x66,
-	0xaf, 0xf1, 0x3b, 0x58, 0xe3, 0x8d, 0x58, 0x83, 0x93, 0x72, 0x7e, 0x66,
-	0xe3, 0x0a, 0x1b, 0x36, 0x69, 0x63, 0x82, 0x33, 0x56, 0xf7, 0xd6, 0x97,
-	0x11, 0xb5, 0xeb, 0x9f, 0xb0, 0x67, 0xcb, 0xc2, 0x1c, 0xa1, 0xa4, 0x5e,
-	0x9f, 0xd1, 0xca, 0x71, 0x8c, 0x37, 0x28, 0xe9, 0x19, 0xce, 0x73, 0xf9,
-	0x9b, 0x11, 0x90, 0x87, 0x27, 0xa0, 0x57, 0x57, 0xd0, 0x25, 0xe8, 0x96,
-	0x73, 0x73, 0x40, 0xbb, 0x8f, 0xca, 0x6c, 0x89, 0xf0, 0xf5, 0x24, 0x22,
-	0xfa, 0xac, 0x19, 0x9e, 0x67, 0x4c, 0x8e, 0xfb, 0x70, 0x25, 0x3c, 0x67,
-	0xb6, 0x89, 0x67, 0x07, 0x57, 0x9d, 0x35, 0xb3, 0xfa, 0x59, 0xdb, 0x0e,
-	0x3c, 0x73, 0x16, 0xce, 0xa1, 0x1e, 0x3d, 0x05, 0x32, 0xa9, 0xf3, 0xce,
-	0x36, 0xcb, 0x63, 0x0f, 0x2e, 0xe7, 0xbc, 0xb6, 0xc1, 0x46, 0xe9, 0x84,
-	0x89, 0x3c, 0x1a, 0x1d, 0xea, 0x81, 0x8f, 0xc7, 0x3c, 0x99, 0x9e, 0xc4,
-	0x6d, 0x3a, 0x17, 0xb9, 0x7a, 0xee, 0xaf, 0x9a, 0x8f, 0x1c, 0x9e, 0xb3,
-	0x4a, 0xe8, 0xef, 0x5a, 0xec, 0xd4, 0xe5, 0x71, 0xcc, 0x87, 0xfb, 0x7e,
-	0x1a, 0x0f, 0x09, 0x7e, 0xa7, 0xeb, 0x29, 0xe0, 0x60, 0xb2, 0xf2, 0x6d,
-	0xd0, 0xbb, 0x63, 0xcf, 0x9c, 0x91, 0xc6, 0x06, 0x64, 0xa2, 0x9c, 0x70,
-	0x26, 0xca, 0x03, 0xce, 0xbe, 0xb2, 0x7d, 0x37, 0xb0, 0x67, 0xb3, 0x34,
-	0xe3, 0xf7, 0x4c, 0x97, 0x33, 0x06, 0x7c, 0xe5, 0x8b, 0xdd, 0x4e, 0x5a,
-	0xdf, 0x3d, 0x7b, 0x87, 0x1c, 0xc0, 0x5a, 0x0d, 0xcf, 0xc4, 0xb5, 0x9c,
-	0xaf, 0x7e, 0x5b, 0x2a, 0x5c, 0x57, 0x7e, 0x13, 0x89, 0x7c, 0x7c, 0x5c,
-	0x7f, 0xe7, 0xc8, 0xd8, 0x0e, 0x27, 0xd1, 0xdf, 0x71, 0x1b, 0x13, 0xef,
-	0x73, 0xb2, 0xba, 0x1f, 0xb3, 0x1e, 0xf9, 0xe2, 0x09, 0xdc, 0x57, 0x9f,
-	0x79, 0x0e, 0xf5, 0x8c, 0x85, 0xbb, 0x10, 0xdc, 0x63, 0xe4, 0xd5, 0x71,
-	0x99, 0xaa, 0x30, 0x7f, 0xc4, 0xd1, 0x7c, 0x34, 0x59, 0x3e, 0x00, 0x9d,
-	0xb4, 0xf2, 0xcc, 0xdf, 0xce, 0xea, 0x3a, 0x24, 0x67, 0x84, 0xb0, 0x70,
-	0x0d, 0x56, 0x9e, 0x87, 0xbf, 0xf8, 0xbf, 0x70, 0x5f, 0xd1, 0xc8, 0x50,
-	0x0b, 0x47, 0x9a, 0xf2, 0xce, 0xc8, 0x95, 0x69, 0x39, 0x08, 0x78, 0x0e,
-	0xe3, 0x52, 0xf7, 0xf3, 0x3b, 0x2c, 0xf3, 0x92, 0x9f, 0xbb, 0x4f, 0xd4,
-	0x43, 0xe7, 0x9d, 0xe8, 0x43, 0x07, 0x25, 0xf2, 0xd0, 0xa2, 0xd3, 0xf0,
-	0x50, 0xb7, 0xf6, 0xcb, 0x77, 0xfb, 0xdd, 0x89, 0x7d, 0x72, 0x52, 0xa2,
-	0xf7, 0x2b, 0x7d, 0xfe, 0x2b, 0xef, 0x32, 0xc6, 0x77, 0x52, 0x22, 0xf7,
-	0xc7, 0xec, 0xd9, 0x51, 0x13, 0xd7, 0x5b, 0xd2, 0x7c, 0xff, 0x9b, 0x71,
-	0xe2, 0x6c, 0x49, 0x8e, 0x6b, 0xde, 0x19, 0x86, 0x9e, 0xc8, 0x94, 0x92,
-	0xcb, 0x75, 0x4c, 0xbe, 0xe7, 0xf3, 0x9b, 0x0d, 0xbf, 0xb0, 0x4e, 0x8f,
-	0xc3, 0xef, 0x38, 0x18, 0x9d, 0x91, 0xb9, 0x2c, 0xcc, 0xfd, 0x34, 0x6b,
-	0xca, 0xf7, 0x67, 0xb1, 0x86, 0x3d, 0x58, 0x2f, 0x8e, 0xe7, 0xe8, 0xfd,
-	0x5c, 0x9e, 0x9d, 0x75, 0xa5, 0x2f, 0xd1, 0xb4, 0x6c, 0x07, 0xb1, 0xee,
-	0x7d, 0xd2, 0x04, 0xb8, 0xd5, 0x43, 0x79, 0x63, 0xd7, 0x09, 0xe9, 0x54,
-	0x20, 0xb9, 0x49, 0xb3, 0x3d, 0x83, 0xbb, 0xf5, 0x1a, 0xde, 0x6b, 0x69,
-	0x66, 0x9d, 0xb1, 0x1f, 0xf1, 0x6c, 0xe8, 0x22, 0x2f, 0xbb, 0xa6, 0x7f,
-	0x08, 0x3d, 0xcf, 0x7d, 0x17, 0x6d, 0x2f, 0xd6, 0xb1, 0x05, 0xc9, 0x4b,
-	0xcf, 0x58, 0xbf, 0x32, 0x08, 0xa6, 0x7d, 0x1f, 0x78, 0xac, 0xe7, 0x4b,
-	0x6e, 0x71, 0xe6, 0x4a, 0x5b, 0x9d, 0xd9, 0x52, 0x20, 0x13, 0x3e, 0xbf,
-	0xe3, 0xc1, 0x1c, 0x00, 0xda, 0x5b, 0x2c, 0xeb, 0x86, 0x6e, 0xfd, 0xeb,
-	0xcd, 0x3c, 0x8f, 0x74, 0x93, 0xf7, 0xa2, 0x98, 0x7a, 0xc4, 0x31, 0x7d,
-	0xe4, 0xee, 0xe3, 0x59, 0xe1, 0xf7, 0x34, 0xfa, 0x12, 0x71, 0xfd, 0x5d,
-	0x8f, 0xcf, 0xa1, 0x1d, 0xc6, 0x28, 0x72, 0xdc, 0x67, 0x9d, 0x59, 0xc8,
-	0xb3, 0xb9, 0x69, 0x9e, 0xe1, 0x67, 0x3e, 0x6d, 0xa4, 0x53, 0xc9, 0x15,
-	0xee, 0xa4, 0xfd, 0x06, 0x5c, 0x0e, 0x2e, 0x50, 0x44, 0x97, 0xf5, 0xb9,
-	0xe3, 0xcb, 0xdf, 0x85, 0x0b, 0xcb, 0xc2, 0xef, 0xc3, 0x29, 0x9d, 0x3b,
-	0x0d, 0x5f, 0xf6, 0xb1, 0x31, 0xf9, 0x89, 0x33, 0x5f, 0x78, 0xc5, 0x79,
-	0xb4, 0x90, 0xbe, 0xea, 0x12, 0xd0, 0xc7, 0x39, 0xbf, 0x97, 0xf2, 0x0b,
-	0x36, 0x5f, 0x41, 0x72, 0x95, 0x09, 0x99, 0xe9, 0xe8, 0x76, 0xef, 0xd7,
-	0x6b, 0x33, 0x03, 0x9c, 0x7d, 0x1b, 0xeb, 0xf7, 0xc9, 0x38, 0xf5, 0xdb,
-	0x78, 0x41, 0x81, 0x97, 0xd5, 0xcf, 0xe3, 0x82, 0x6d, 0xdb, 0xa8, 0x6d,
-	0x94, 0x7d, 0x3e, 0xeb, 0x6d, 0x75, 0x86, 0x4b, 0x5b, 0xb0, 0x8e, 0x7b,
-	0xa1, 0x3f, 0x1d, 0xd8, 0x69, 0xa0, 0x6d, 0x94, 0x4d, 0x02, 0x07, 0xe3,
-	0xbe, 0x91, 0xe7, 0xc3, 0x92, 0xd3, 0x3e, 0x9e, 0xb9, 0xa7, 0x95, 0x89,
-	0x99, 0x05, 0xc1, 0x1c, 0xec, 0x83, 0x6c, 0x7f, 0x09, 0xbc, 0xf0, 0x08,
-	0xae, 0xb7, 0xdb, 0x3d, 0xed, 0x17, 0x2e, 0xb2, 0xa7, 0xed, 0xca, 0xc9,
-	0x8a, 0x3e, 0xd7, 0xae, 0xf3, 0xab, 0x92, 0xea, 0xbf, 0x5f, 0xa2, 0xd7,
-	0x4a, 0xf5, 0xe8, 0x9c, 0xb4, 0xb4, 0x7c, 0x38, 0x6e, 0xf4, 0x30, 0x61,
-	0x4a, 0x02, 0x9e, 0xad, 0xc0, 0x05, 0xe1, 0x31, 0x6d, 0x44, 0x6d, 0xba,
-	0x94, 0xfa, 0x70, 0x49, 0x3e, 0x12, 0x0f, 0xcf, 0x14, 0xa0, 0x1f, 0xc8,
-	0xb8, 0x8f, 0x5d, 0x6a, 0xf4, 0xe4, 0xe6, 0x3a, 0xfd, 0x84, 0x73, 0x73,
-	0xec, 0xdc, 0x48, 0xb7, 0x7f, 0x96, 0xa0, 0x4f, 0xb1, 0x24, 0x4d, 0xab,
-	0xea, 0x33, 0xa6, 0xbf, 0xe1, 0x72, 0x73, 0x46, 0x81, 0x75, 0x5d, 0xd8,
-	0xa6, 0xb4, 0x73, 0x89, 0x47, 0xbd, 0x6e, 0x05, 0x25, 0x3c, 0x67, 0x00,
-	0x6e, 0xae, 0x5c, 0xe1, 0xbe, 0x43, 0x91, 0x0e, 0x43, 0x5c, 0x7f, 0x5b,
-	0xf3, 0xc9, 0x78, 0x81, 0xb1, 0x95, 0x47, 0x83, 0xf4, 0x28, 0x79, 0x8c,
-	0x7d, 0xf0, 0x7d, 0x41, 0xc7, 0x73, 0xf7, 0xfa, 0x8c, 0x15, 0x75, 0x1f,
-	0xbf, 0x43, 0x85, 0x72, 0x0a, 0xfa, 0xb7, 0xb8, 0xe8, 0xf0, 0x1b, 0x78,
-	0x37, 0x0a, 0xee, 0xf3, 0x8b, 0xce, 0x77, 0xa7, 0x9f, 0xc5, 0x73, 0x83,
-	0xfd, 0xee, 0x9d, 0xd1, 0x53, 0x22, 0xc5, 0x70, 0xbe, 0x89, 0x1c, 0xd6,
-	0xfe, 0x02, 0xd6, 0xbe, 0xfe, 0x77, 0xee, 0xf0, 0xae, 0x8c, 0x77, 0xe5,
-	0x0f, 0x07, 0xe9, 0x36, 0xd2, 0x22, 0xe9, 0xef, 0xb5, 0xfc, 0xe6, 0x41,
-	0xcd, 0x17, 0x93, 0xc5, 0xc7, 0xc1, 0x17, 0x69, 0xee, 0x37, 0x07, 0x0f,
-	0xfb, 0x37, 0x80, 0x2f, 0xf6, 0xc8, 0xef, 0xc3, 0x2e, 0xf8, 0xdd, 0xca,
-	0x10, 0xf8, 0x63, 0x10, 0xfc, 0x32, 0x00, 0x1e, 0xf1, 0xb5, 0x8d, 0xfc,
-	0x04, 0xf4, 0x1f, 0xf4, 0x9a, 0xb3, 0xaf, 0xd4, 0xe5, 0x64, 0x4b, 0x9e,
-	0x33, 0x51, 0xe2, 0xf7, 0x5a, 0xd4, 0x5b, 0x1b, 0x24, 0x9a, 0x98, 0x13,
-	0xf2, 0x42, 0x37, 0x73, 0x1c, 0xdb, 0x81, 0xab, 0x53, 0xc4, 0xd5, 0x5c,
-	0xa5, 0xcf, 0xbd, 0x04, 0x3c, 0xd1, 0xae, 0x79, 0xa2, 0xd5, 0x49, 0xbb,
-	0x37, 0x58, 0x9e, 0x78, 0x11, 0x3c, 0x71, 0x7e, 0x0d, 0x4f, 0x3c, 0x6d,
-	0xe9, 0x7f, 0xa1, 0x86, 0x27, 0xe6, 0x6c, 0xd9, 0xcc, 0x45, 0x78, 0xe2,
-	0x52, 0x2f, 0xf5, 0xa5, 0x31, 0x79, 0x15, 0x3c, 0x21, 0x8a, 0x3c, 0x71,
-	0xa9, 0xe6, 0x09, 0xc6, 0x8e, 0xc8, 0x17, 0x9d, 0x90, 0x23, 0xe4, 0x8b,
-	0xb3, 0xb2, 0x04, 0xbe, 0x78, 0x5e, 0x71, 0xec, 0x19, 0xda, 0x0a, 0x25,
-	0xfa, 0x64, 0x27, 0x8a, 0x5d, 0xe0, 0x77, 0x25, 0xff, 0x65, 0x3a, 0x08,
-	0x16, 0xe1, 0xa7, 0x3f, 0x08, 0x7b, 0x3e, 0xaa, 0xbf, 0xa9, 0xb8, 0x00,
-	0xba, 0x0f, 0xe9, 0x7d, 0xc2, 0x01, 0xbd, 0x1f, 0x9e, 0xc5, 0x1c, 0x26,
-	0xd4, 0x7f, 0x86, 0x2f, 0xec, 0x62, 0x5d, 0x69, 0xe7, 0x1f, 0xd3, 0x3c,
-	0xd4, 0x00, 0x7d, 0xf0, 0xe8, 0x00, 0x63, 0x4d, 0x9e, 0xbb, 0x4f, 0x75,
-	0xe7, 0x46, 0x00, 0x73, 0x44, 0xdd, 0x2f, 0x8c, 0x73, 0xb4, 0xad, 0xb2,
-	0xf3, 0x29, 0x23, 0x46, 0x21, 0xeb, 0xcc, 0xbb, 0x5c, 0xd0, 0x04, 0x9b,
-	0xb4, 0x49, 0x19, 0x1b, 0x5d, 0xed, 0x48, 0xb9, 0x1f, 0x84, 0x00, 0x6d,
-	0x84, 0xbd, 0xb0, 0x0b, 0xab, 0x3d, 0x52, 0xa8, 0xb5, 0xf1, 0xff, 0x03,
-	0x6c, 0x7c, 0xb6, 0x91, 0xa8, 0xb1, 0xf1, 0x7f, 0xcd, 0xf2, 0x1a, 0x7f,
-	0xbb, 0xda, 0xde, 0x3f, 0x00, 0xf8, 0x76, 0x2f, 0xdb, 0xfb, 0xec, 0x83,
-	0x76, 0x87, 0xc8, 0xf5, 0xb0, 0xf9, 0xde, 0x0d, 0x1e, 0xbc, 0x01, 0xbe,
-	0xd4, 0x7b, 0x0a, 0xae, 0xec, 0x29, 0xb4, 0xc3, 0xe7, 0xee, 0x94, 0xf7,
-	0x4e, 0x6f, 0x95, 0x9d, 0x25, 0xff, 0x12, 0x69, 0xee, 0x80, 0x8d, 0x5a,
-	0x00, 0x9c, 0x11, 0x2b, 0xb7, 0xcf, 0x02, 0x6f, 0xdd, 0xc9, 0x9f, 0xa8,
-	0x17, 0xad, 0x5d, 0xc4, 0xb3, 0x8e, 0xf5, 0xfa, 0x89, 0xa3, 0x3d, 0x63,
-	0x29, 0x1d, 0x72, 0xea, 0x18, 0xbd, 0xaf, 0x24, 0xec, 0x72, 0x1f, 0x36,
-	0xc9, 0x16, 0xf4, 0xc7, 0x78, 0xf2, 0x46, 0x79, 0xfa, 0xaa, 0xe8, 0x5d,
-	0x59, 0xcd, 0x87, 0x9d, 0x4e, 0x66, 0x1a, 0x3e, 0xc0, 0xde, 0x18, 0xe6,
-	0xa0, 0xda, 0x37, 0xcb, 0x75, 0xb2, 0x53, 0xcf, 0x67, 0x46, 0x0e, 0x42,
-	0x37, 0xff, 0x41, 0x61, 0xa7, 0x2c, 0x8d, 0xb6, 0xe1, 0x39, 0x26, 0x4f,
-	0x17, 0xfa, 0xe0, 0xfb, 0xbc, 0x0b, 0x38, 0x6a, 0xc4, 0x73, 0xa3, 0x0c,
-	0x5f, 0x42, 0x5e, 0x6d, 0x91, 0x45, 0x94, 0xbf, 0x5b, 0x7e, 0xc1, 0x96,
-	0xb3, 0x8c, 0xbc, 0xd1, 0x82, 0xb6, 0x31, 0x39, 0x57, 0xa0, 0x5d, 0xa9,
-	0x79, 0x62, 0xf0, 0x7b, 0xd2, 0x97, 0xfe, 0x1e, 0xec, 0xd4, 0xb3, 0xb8,
-	0x9e, 0x91, 0xd4, 0x9e, 0x71, 0xa7, 0x2f, 0xd9, 0xed, 0x40, 0x77, 0xe2,
-	0x8a, 0x3a, 0x7d, 0x6e, 0xa3, 0x73, 0x85, 0xed, 0xa3, 0x41, 0x9e, 0xd9,
-	0xab, 0x12, 0x2d, 0x58, 0x93, 0xed, 0x4e, 0x8f, 0x2d, 0xe3, 0x73, 0xca,
-	0x78, 0x40, 0xa7, 0xd4, 0x96, 0x0d, 0x22, 0x5d, 0x2d, 0xb0, 0x79, 0x26,
-	0x44, 0xb5, 0xb7, 0x48, 0x54, 0xba, 0x67, 0x55, 0x27, 0xca, 0x3c, 0x5b,
-	0x16, 0x6f, 0x81, 0x7e, 0x40, 0x59, 0x07, 0xca, 0xb6, 0xd9, 0xb2, 0xb6,
-	0x16, 0x69, 0x44, 0xd9, 0x8c, 0xe6, 0xf9, 0xf3, 0x3d, 0x9e, 0x9b, 0x75,
-	0x9a, 0xa5, 0xeb, 0x44, 0x0b, 0x64, 0xc3, 0x46, 0x59, 0xbc, 0xaa, 0x49,
-	0xba, 0xf0, 0x8e, 0x71, 0x6e, 0xff, 0x44, 0x4c, 0xae, 0x3d, 0xd1, 0x9d,
-	0xf8, 0x38, 0xe6, 0xd0, 0x7d, 0x8a, 0x71, 0xef, 0xfc, 0x25, 0x8c, 0xfb,
-	0x74, 0x9d, 0xe2, 0xbd, 0x49, 0xcb, 0x1f, 0xe2, 0xc3, 0x7c, 0x93, 0x88,
-	0x32, 0xf9, 0x24, 0xfc, 0x5c, 0xea, 0xf0, 0x6e, 0xfb, 0xfd, 0x8c, 0xe3,
-	0x97, 0xd0, 0x6f, 0x9b, 0xa5, 0x5d, 0x52, 0x24, 0x3f, 0x52, 0x0f, 0xe1,
-	0x3e, 0xe3, 0x48, 0xbe, 0x2a, 0xb3, 0xe6, 0xc9, 0x57, 0xc7, 0x14, 0x73,
-	0x59, 0x50, 0x56, 0xf9, 0xc5, 0xc0, 0xac, 0x31, 0x79, 0xc1, 0xc8, 0xa5,
-	0x0f, 0x18, 0xb9, 0xf4, 0xd8, 0x99, 0x15, 0x72, 0xe9, 0xbc, 0x96, 0x4b,
-	0x7b, 0x05, 0xf7, 0xf9, 0xf3, 0x90, 0x4b, 0x2f, 0xe2, 0xd9, 0xd5, 0x72,
-	0x29, 0x2e, 0xd6, 0x5e, 0x96, 0xaf, 0xea, 0xf1, 0xe7, 0x8a, 0x51, 0x6d,
-	0x57, 0xe5, 0x67, 0x60, 0x93, 0x14, 0xa7, 0xac, 0xfe, 0x96, 0xa1, 0x36,
-	0xe9, 0x19, 0xfc, 0xa9, 0x84, 0x36, 0xe7, 0x7f, 0xba, 0x84, 0xdf, 0xee,
-	0x7c, 0x5e, 0x51, 0x86, 0xbd, 0x0a, 0x19, 0x26, 0xaa, 0xbe, 0x0c, 0xc3,
-	0xbb, 0x32, 0xde, 0x95, 0xd9, 0xef, 0x8f, 0x7e, 0x3a, 0xe6, 0x52, 0x7e,
-	0x50, 0x66, 0x40, 0x26, 0x15, 0x21, 0x93, 0x8a, 0x90, 0x53, 0x45, 0xc8,
-	0x25, 0xd8, 0x6c, 0x67, 0x8a, 0x90, 0x4b, 0x45, 0xc8, 0x25, 0xc8, 0xb8,
-	0x27, 0x20, 0xe3, 0x8c, 0x4c, 0x1b, 0x85, 0x4c, 0x9b, 0x91, 0xfb, 0xac,
-	0xae, 0x37, 0xb1, 0x92, 0x7e, 0xeb, 0x23, 0x0d, 0xe8, 0x18, 0xf2, 0x99,
-	0x9a, 0xd8, 0xe0, 0x8d, 0x47, 0x34, 0xbf, 0xbb, 0x9e, 0xba, 0xc2, 0x61,
-	0x0e, 0xcd, 0x4f, 0xb4, 0xff, 0xbe, 0x9d, 0xbf, 0xa5, 0x09, 0x7c, 0xfd,
-	0x03, 0xcb, 0xd7, 0xdb, 0x97, 0xf9, 0x3a, 0xe5, 0x30, 0x56, 0x5c, 0x9f,
-	0xaf, 0x3b, 0xec, 0xbb, 0x5c, 0xb0, 0x0e, 0x7c, 0xbd, 0x6e, 0x15, 0x5f,
-	0xc7, 0xc0, 0xd7, 0x7b, 0xd6, 0xf0, 0xf5, 0x06, 0x67, 0x58, 0xb7, 0xe1,
-	0x19, 0x09, 0x3e, 0x37, 0x3a, 0x55, 0xbe, 0xbe, 0x47, 0xf3, 0xf5, 0x21,
-	0xf0, 0xf5, 0x75, 0x35, 0x7c, 0xbd, 0x47, 0x52, 0x37, 0x67, 0x22, 0x5b,
-	0x65, 0xfc, 0x7e, 0xd5, 0xbe, 0x49, 0xfe, 0x49, 0x4c, 0x7b, 0xc3, 0x63,
-	0xc3, 0xd3, 0xed, 0x92, 0x7d, 0xe8, 0x15, 0x94, 0x91, 0xcf, 0x52, 0x63,
-	0x69, 0xc7, 0x95, 0x83, 0x47, 0x7e, 0x22, 0x0b, 0x9a, 0xb7, 0x44, 0x26,
-	0x8e, 0xc4, 0x64, 0xf2, 0x08, 0xe3, 0x10, 0x7f, 0x63, 0xe9, 0xbd, 0x49,
-	0x26, 0xf7, 0x32, 0x6f, 0x2e, 0x2a, 0xe3, 0x47, 0xe0, 0x6f, 0x1d, 0x61,
-	0x1c, 0xe2, 0xa5, 0x65, 0x1e, 0x5b, 0x80, 0x6c, 0x19, 0x3f, 0xc2, 0xb5,
-	0x8e, 0xa1, 0x9f, 0x16, 0x39, 0x74, 0x44, 0xe4, 0xb6, 0x23, 0x51, 0xf9,
-	0xe8, 0x91, 0x65, 0x5e, 0x1b, 0x0d, 0x79, 0xed, 0x59, 0xf0, 0x5a, 0xb7,
-	0xe5, 0x35, 0xb5, 0xcc, 0x6b, 0x7f, 0x5a, 0xc3, 0x6b, 0x6c, 0x4f, 0x5e,
-	0x7b, 0xce, 0x96, 0xf1, 0x39, 0x2a, 0xfb, 0x8e, 0x74, 0xca, 0xf8, 0x43,
-	0x6f, 0x91, 0x89, 0xfb, 0x09, 0xab, 0xf9, 0x8e, 0x13, 0x6d, 0xb1, 0x99,
-	0x4a, 0x37, 0xfa, 0x0f, 0x73, 0x88, 0xf4, 0xf7, 0x10, 0x7a, 0x67, 0x25,
-	0x95, 0xe3, 0x78, 0x8d, 0xf0, 0xa3, 0x4f, 0xc0, 0xbf, 0xd8, 0x07, 0x98,
-	0x6e, 0x39, 0x22, 0xa9, 0xa8, 0xbc, 0x2c, 0x53, 0xfe, 0x27, 0x2e, 0x37,
-	0xf6, 0x04, 0x6c, 0x11, 0x6d, 0xfb, 0xa4, 0x25, 0xfb, 0xce, 0x40, 0xfb,
-	0x18, 0xa5, 0xb2, 0x30, 0x16, 0xc0, 0xb8, 0xb9, 0x63, 0xbe, 0xc7, 0xc4,
-	0xfc, 0xc7, 0x06, 0x7d, 0xe6, 0x45, 0xc7, 0x6c, 0x07, 0xf8, 0x9e, 0xcf,
-	0xb0, 0x67, 0xf4, 0x59, 0x43, 0xb6, 0x7f, 0x44, 0x7f, 0x1b, 0x91, 0x31,
-	0xf5, 0x7c, 0x99, 0xdf, 0xb0, 0x81, 0xff, 0x59, 0xe6, 0xb7, 0xb0, 0xf6,
-	0xb7, 0x9b, 0xf8, 0x2c, 0xf9, 0xee, 0x87, 0x0e, 0xbf, 0x5d, 0x35, 0xa5,
-	0x73, 0xbd, 0xf0, 0xbb, 0xcc, 0x67, 0xd6, 0x7f, 0x84, 0xf1, 0x8e, 0x64,
-	0x52, 0xbd, 0xf7, 0x72, 0xe6, 0x1e, 0xec, 0x9d, 0x67, 0xdd, 0xad, 0x96,
-	0x47, 0xb7, 0x6a, 0xbf, 0x83, 0x36, 0xd6, 0x78, 0xe9, 0x45, 0xc9, 0xd3,
-	0x36, 0x19, 0xdd, 0xea, 0xe4, 0x66, 0x92, 0x97, 0x1b, 0xfb, 0x79, 0xdd,
-	0xa5, 0xcc, 0x3b, 0x4c, 0xab, 0xb5, 0x32, 0xf9, 0x84, 0x84, 0x32, 0x39,
-	0x75, 0x33, 0xbf, 0xb7, 0x9b, 0x3d, 0xa2, 0xbf, 0x2f, 0x95, 0xec, 0x56,
-	0x9c, 0xd3, 0xa7, 0x21, 0x5f, 0x43, 0x5a, 0x48, 0xc8, 0x27, 0x8f, 0x90,
-	0x1e, 0x54, 0xbc, 0x55, 0x3e, 0x61, 0xe9, 0x61, 0x46, 0x0a, 0x90, 0x3b,
-	0x47, 0x8e, 0x7c, 0x54, 0x66, 0x6e, 0x5c, 0x4d, 0x0f, 0x13, 0x55, 0x7a,
-	0x88, 0xc3, 0x3e, 0x73, 0x6a, 0xe9, 0xe1, 0x97, 0x97, 0xe9, 0x61, 0xc6,
-	0xf9, 0xe7, 0xd2, 0xc3, 0xf5, 0x2b, 0xe8, 0x61, 0x4a, 0xd3, 0xc3, 0xce,
-	0x65, 0x7a, 0x98, 0x3a, 0xc2, 0x71, 0xf5, 0xde, 0xa8, 0xbb, 0xe8, 0x70,
-	0xcd, 0x97, 0x69, 0x21, 0x39, 0xa9, 0xf3, 0xf5, 0x53, 0x39, 0x9e, 0x6f,
-	0xda, 0xa0, 0x18, 0x27, 0xa9, 0xae, 0x7f, 0xeb, 0xbf, 0xe8, 0xfa, 0xbf,
-	0xfc, 0xff, 0x79, 0xfd, 0xd5, 0xa5, 0xcc, 0xdd, 0xe7, 0x99, 0x55, 0x23,
-	0x8f, 0x43, 0x7a, 0x88, 0x5d, 0x6a, 0xf4, 0x02, 0xd7, 0x98, 0xcf, 0x90,
-	0x67, 0x90, 0x7f, 0x67, 0x20, 0xff, 0x9e, 0x84, 0xfc, 0x3b, 0xbd, 0x62,
-	0x4f, 0x60, 0xd0, 0xc6, 0x23, 0x02, 0x39, 0xe8, 0x57, 0xf1, 0xb1, 0x38,
-	0x40, 0x7c, 0x98, 0xfc, 0x13, 0xe6, 0xfe, 0xae, 0xc4, 0x49, 0x54, 0xe7,
-	0x1c, 0x3d, 0xea, 0xd7, 0xe2, 0x84, 0x70, 0xbf, 0x5c, 0x33, 0x47, 0xfc,
-	0x2e, 0xf3, 0x79, 0x46, 0xe7, 0x91, 0xe4, 0xf5, 0x1e, 0x14, 0xf1, 0xc2,
-	0x3d, 0x28, 0xe2, 0x24, 0xaa, 0xed, 0xfd, 0x7c, 0xb9, 0x49, 0xe7, 0xd0,
-	0x1f, 0x98, 0x8f, 0xcb, 0x62, 0x9c, 0x31, 0x3e, 0x7e, 0x97, 0x90, 0x7e,
-	0xb3, 0x97, 0xc8, 0x4b, 0x8e, 0xb9, 0x72, 0xe0, 0xe9, 0x0d, 0x96, 0xb6,
-	0x19, 0x1b, 0xe4, 0x99, 0xdd, 0x70, 0x2f, 0xa2, 0xd7, 0xca, 0xba, 0x96,
-	0x9a, 0x98, 0x25, 0xf0, 0x3e, 0x2d, 0xc9, 0xcc, 0x00, 0xee, 0xf3, 0x1c,
-	0x7b, 0xbf, 0x4c, 0x3d, 0x38, 0x01, 0x5b, 0x6e, 0x2f, 0x74, 0x0e, 0xcf,
-	0x9f, 0x99, 0xef, 0x70, 0x13, 0x86, 0x59, 0xfd, 0xdd, 0x29, 0xfa, 0x80,
-	0xa4, 0x87, 0x04, 0x9e, 0x67, 0x6c, 0x5c, 0x29, 0x21, 0xf9, 0xc2, 0x05,
-	0xf3, 0x6d, 0xcb, 0xc2, 0x4b, 0xb8, 0xbf, 0xde, 0x7a, 0x18, 0x3f, 0x64,
-	0xd4, 0xdc, 0xd1, 0xd7, 0x92, 0xa4, 0xcb, 0x26, 0xc7, 0xa5, 0x1a, 0x37,
-	0x99, 0x91, 0xc3, 0xda, 0x7e, 0x1e, 0xb2, 0xb9, 0x2d, 0xa9, 0xd1, 0x9c,
-	0x18, 0x1b, 0xfa, 0x77, 0x60, 0x43, 0x7f, 0xb1, 0x92, 0xd6, 0xfb, 0x58,
-	0xa7, 0x61, 0x43, 0x3f, 0x01, 0xdd, 0x43, 0x9d, 0x13, 0xb7, 0x3a, 0x67,
-	0x4a, 0xdd, 0xa8, 0x75, 0xce, 0x37, 0xb5, 0xce, 0x79, 0xef, 0x1a, 0x9d,
-	0x73, 0x48, 0x75, 0x97, 0xa8, 0x73, 0x86, 0xd5, 0x1e, 0x87, 0xf6, 0xe2,
-	0xe6, 0x3a, 0x3a, 0xe7, 0x7d, 0xf2, 0x2e, 0xfb, 0xee, 0x1e, 0x79, 0xff,
-	0x0e, 0xbd, 0x77, 0xe3, 0xce, 0x2a, 0x7e, 0x6b, 0xc9, 0xe8, 0xa0, 0xeb,
-	0x54, 0xaf, 0xde, 0xf3, 0xfd, 0x46, 0x8d, 0xce, 0xe9, 0x52, 0x03, 0xce,
-	0xb0, 0x6e, 0xc3, 0xd8, 0x04, 0x9f, 0x7d, 0x27, 0x3d, 0xda, 0x84, 0xe7,
-	0x84, 0x44, 0x8e, 0x60, 0xee, 0xe6, 0x7b, 0x50, 0xca, 0xbc, 0x7b, 0xab,
-	0x7d, 0xa7, 0xc2, 0xf2, 0xa8, 0x29, 0xef, 0xb6, 0xe5, 0x46, 0x57, 0x75,
-	0xa9, 0x4e, 0xad, 0xab, 0xb6, 0x83, 0xa1, 0x66, 0xa1, 0x5f, 0x67, 0x8b,
-	0xa1, 0xce, 0xe2, 0x6f, 0xc6, 0x9e, 0x19, 0xa3, 0x08, 0x63, 0xd8, 0x49,
-	0xd4, 0xc1, 0x55, 0x0c, 0x6d, 0x4a, 0xfe, 0x86, 0xaf, 0x80, 0x6b, 0x1e,
-	0x78, 0xbd, 0x19, 0xfc, 0xf3, 0x6f, 0x0a, 0x8c, 0x81, 0xb6, 0xcb, 0xd1,
-	0xe9, 0xda, 0x77, 0x9d, 0xf2, 0x9e, 0xe9, 0x2d, 0xb2, 0xbf, 0xf4, 0x2d,
-	0xf0, 0xc1, 0x56, 0x99, 0x2a, 0x15, 0xf4, 0x79, 0xf5, 0x4d, 0xfa, 0x3b,
-	0x1e, 0xfc, 0xbe, 0x8d, 0x91, 0x91, 0x3b, 0x1d, 0x23, 0x23, 0xd3, 0xaa,
-	0x6a, 0xb3, 0x86, 0x7d, 0xf2, 0xdb, 0x21, 0x23, 0xa5, 0x84, 0xfe, 0xc6,
-	0xe9, 0x6c, 0xe5, 0x0a, 0xf9, 0xc2, 0x31, 0x75, 0xa7, 0xaa, 0x9e, 0xef,
-	0xd5, 0x36, 0xeb, 0xdc, 0x0a, 0x9b, 0xf5, 0xaf, 0x64, 0xf1, 0xfd, 0x31,
-	0xcc, 0x13, 0x34, 0x7c, 0xe5, 0xf7, 0xb8, 0x17, 0xda, 0x1e, 0x97, 0x0b,
-	0x32, 0xa2, 0xf1, 0x47, 0x79, 0xda, 0x02, 0x39, 0xb8, 0xa4, 0xf5, 0xeb,
-	0x66, 0xd0, 0x20, 0x65, 0xe9, 0xc7, 0xe4, 0x45, 0x2d, 0xcf, 0x36, 0x5b,
-	0xdb, 0x75, 0x81, 0xb1, 0xd4, 0x23, 0xb4, 0x5d, 0xbf, 0x69, 0xcb, 0x59,
-	0x96, 0x4a, 0x2c, 0x09, 0xf5, 0x5d, 0x1c, 0x32, 0x94, 0xf2, 0xf4, 0x8d,
-	0xda, 0xae, 0x5f, 0xb3, 0x7d, 0x50, 0x7e, 0x1a, 0xd9, 0xbd, 0xdd, 0x59,
-	0xb0, 0x65, 0x7c, 0x0e, 0xe3, 0xe9, 0x5e, 0x3a, 0x6b, 0xf9, 0x4c, 0x39,
-	0x5f, 0xc2, 0xfb, 0x4d, 0x78, 0x4f, 0x3e, 0x3b, 0xad, 0xf9, 0x4c, 0xdb,
-	0x27, 0x4e, 0xbf, 0xdd, 0x5f, 0x58, 0xde, 0x1b, 0xc8, 0x91, 0xcf, 0xd4,
-	0x51, 0x77, 0xc1, 0xc8, 0x03, 0xe6, 0xa9, 0x7e, 0x1e, 0xba, 0x83, 0x6d,
-	0x51, 0xfe, 0x70, 0x9a, 0xbe, 0x2d, 0xfc, 0x9f, 0x56, 0x3c, 0xb7, 0xe3,
-	0x79, 0x56, 0xde, 0xbb, 0x37, 0xa6, 0xe7, 0x3d, 0x85, 0x79, 0x1c, 0x38,
-	0x82, 0x39, 0x39, 0xc6, 0x76, 0x8e, 0x9e, 0x8a, 0x4a, 0xc3, 0x29, 0xf2,
-	0x1d, 0xcf, 0xda, 0x04, 0xc1, 0xbe, 0x7e, 0xd2, 0x6d, 0xca, 0xdd, 0xa9,
-	0xcf, 0x96, 0x6e, 0x4f, 0x44, 0x80, 0x93, 0x03, 0x58, 0x8f, 0xa9, 0x82,
-	0xe7, 0x66, 0x1c, 0x2f, 0x81, 0x79, 0xc2, 0x06, 0xec, 0x86, 0x2d, 0xd8,
-	0x0d, 0x3b, 0xb0, 0x1b, 0x76, 0xe0, 0x46, 0x39, 0x71, 0x15, 0x73, 0x4c,
-	0x72, 0xd7, 0xc2, 0x2b, 0x97, 0xef, 0xe8, 0x38, 0x7d, 0xe3, 0xcd, 0x23,
-	0xf0, 0xd9, 0xc5, 0x4d, 0x8d, 0x32, 0x0f, 0x7f, 0xc9, 0x6d, 0xbc, 0x79,
-	0xa7, 0x74, 0x0f, 0xe2, 0xfd, 0xe0, 0x05, 0xe9, 0xb9, 0xf9, 0x56, 0xa7,
-	0x71, 0x74, 0x04, 0x78, 0x4c, 0x3b, 0xa9, 0xc4, 0x98, 0xb3, 0x80, 0x71,
-	0x32, 0xdb, 0x23, 0xc2, 0xb8, 0xe5, 0x02, 0x63, 0x11, 0x37, 0x77, 0x47,
-	0xfa, 0x92, 0xe3, 0x4e, 0x6a, 0x54, 0x45, 0x52, 0xa3, 0x23, 0x4e, 0x58,
-	0x8f, 0xdf, 0x48, 0x85, 0x9c, 0x01, 0xac, 0x07, 0x8a, 0xd3, 0xa0, 0xa7,
-	0xff, 0x28, 0xf9, 0x63, 0x2d, 0x32, 0x5f, 0xe8, 0x76, 0x33, 0x2a, 0xae,
-	0x73, 0x4b, 0xd4, 0x09, 0x10, 0xfd, 0xa9, 0x98, 0xcc, 0x96, 0xb6, 0x8a,
-	0xd2, 0xb6, 0x7b, 0x87, 0x64, 0xa6, 0x4b, 0x72, 0x6e, 0x40, 0xda, 0x14,
-	0xfa, 0xe7, 0xb7, 0x67, 0xd5, 0x09, 0xee, 0x25, 0x86, 0xbc, 0x70, 0x39,
-	0xf9, 0xa4, 0x04, 0x1c, 0x82, 0x6e, 0x19, 0xe3, 0x6d, 0x12, 0xca, 0xbd,
-	0x8f, 0xea, 0xf8, 0x29, 0x63, 0xb6, 0xb5, 0x7b, 0x0f, 0xe4, 0x8f, 0x58,
-	0x5d, 0xfe, 0x98, 0x2b, 0x72, 0x9f, 0x46, 0x72, 0x51, 0xc6, 0x88, 0x3d,
-	0xfc, 0x9e, 0x61, 0xdd, 0x26, 0x99, 0x1a, 0xc8, 0xd9, 0x3c, 0x8f, 0x47,
-	0x12, 0xcc, 0x21, 0x26, 0x4e, 0xc6, 0x07, 0xc8, 0xeb, 0xab, 0xf7, 0x36,
-	0x62, 0x35, 0xf2, 0xc0, 0x91, 0xc5, 0x52, 0xb8, 0x17, 0xc2, 0xfe, 0xf0,
-	0x3c, 0x63, 0xe4, 0x6d, 0x66, 0x4d, 0x3b, 0xc2, 0xc5, 0xfd, 0xca, 0x95,
-	0x32, 0x56, 0x79, 0x94, 0xa9, 0xae, 0x96, 0xaf, 0x8f, 0x55, 0x8c, 0x6c,
-	0x9d, 0xa9, 0x84, 0xba, 0x25, 0x66, 0x74, 0xe9, 0x1a, 0x7d, 0x62, 0xa2,
-	0x99, 0x55, 0x7d, 0x42, 0xbd, 0xa8, 0xe4, 0x03, 0xf3, 0x1d, 0x12, 0x7d,
-	0x58, 0x96, 0xa6, 0xbc, 0xec, 0xe5, 0xcc, 0xd5, 0x98, 0xf2, 0xdf, 0x8c,
-	0x7e, 0xfc, 0x6f, 0x09, 0xea, 0xc3, 0x31, 0xf5, 0x75, 0xdc, 0x37, 0x69,
-	0xfa, 0x03, 0x4f, 0xe1, 0xd9, 0xf8, 0x09, 0xbf, 0x03, 0x3f, 0xe1, 0x8b,
-	0xd0, 0x75, 0x67, 0xe0, 0x27, 0x3c, 0x09, 0x3f, 0xe1, 0x34, 0xfc, 0x84,
-	0x27, 0xa0, 0x27, 0x6b, 0xfd, 0x83, 0xc9, 0x15, 0xfe, 0x41, 0xa0, 0xf9,
-	0x9f, 0xf1, 0xc0, 0x27, 0x6b, 0x7c, 0x83, 0x7d, 0x46, 0x5f, 0xc1, 0xef,
-	0x37, 0x7c, 0xd4, 0xa5, 0x6e, 0xd2, 0xfa, 0xd1, 0xe4, 0xed, 0x8e, 0x2e,
-	0xeb, 0xab, 0x2e, 0x65, 0xf4, 0xd5, 0x6c, 0x55, 0x5f, 0x19, 0x3e, 0x7a,
-	0xb8, 0x24, 0x11, 0xaf, 0xb4, 0x90, 0xf1, 0x77, 0x69, 0x1e, 0x6a, 0xf3,
-	0xb6, 0x4a, 0xe4, 0x01, 0xd5, 0xde, 0x20, 0x19, 0xfb, 0x0c, 0xfa, 0x3a,
-	0x3a, 0x8d, 0xbe, 0xae, 0x95, 0xac, 0xb6, 0xcf, 0x2e, 0x8e, 0xef, 0x27,
-	0x56, 0xe1, 0x3b, 0x5f, 0xbc, 0x5b, 0xe3, 0xfc, 0xfe, 0x32, 0xf7, 0x59,
-	0x5a, 0x64, 0xb2, 0x1c, 0xe2, 0x9c, 0xe7, 0x59, 0x99, 0x8b, 0xd1, 0x29,
-	0x91, 0x87, 0x3b, 0x78, 0xce, 0x4a, 0x65, 0xfd, 0xf5, 0x3a, 0x87, 0xe5,
-	0xc4, 0x80, 0x24, 0xb2, 0x03, 0xa4, 0xd5, 0xfb, 0x64, 0x56, 0xaf, 0x45,
-	0x87, 0x34, 0x3c, 0x4c, 0x1b, 0x25, 0xdc, 0xcf, 0xeb, 0xba, 0xcc, 0x7e,
-	0x23, 0x35, 0x66, 0xea, 0x89, 0x1c, 0xd4, 0xeb, 0x75, 0x5c, 0xe7, 0x19,
-	0xde, 0x34, 0xcf, 0xb8, 0x3c, 0xbf, 0x47, 0xc5, 0x98, 0xfc, 0x3f, 0x67,
-	0xfd, 0x7e, 0xe1, 0x32, 0x63, 0xcf, 0x6c, 0xb2, 0x76, 0x8c, 0x89, 0x53,
-	0xd5, 0xb7, 0x61, 0xd8, 0x4f, 0xed, 0x37, 0x14, 0xb7, 0x38, 0x93, 0xa5,
-	0xad, 0x4e, 0xbe, 0xc4, 0xbd, 0x6c, 0xfb, 0xf7, 0x2e, 0xdc, 0x3d, 0xce,
-	0x01, 0x6f, 0x0b, 0xca, 0x18, 0xb3, 0x64, 0xcc, 0xe6, 0x97, 0x2e, 0x63,
-	0x8c, 0x36, 0xe3, 0x71, 0x6c, 0x96, 0x6d, 0x71, 0xa6, 0x4a, 0xdd, 0xf0,
-	0xcd, 0x79, 0xae, 0x8a, 0xef, 0x77, 0x72, 0xed, 0xa0, 0x83, 0x5d, 0x7d,
-	0x66, 0x77, 0x42, 0xae, 0xb0, 0x31, 0x68, 0xea, 0xe1, 0x9f, 0x5f, 0xb1,
-	0x77, 0x7b, 0x08, 0x7a, 0xec, 0x16, 0xc8, 0x23, 0xea, 0xe1, 0x43, 0x72,
-	0xb5, 0xa5, 0xe7, 0x95, 0x7a, 0xf8, 0xbc, 0x30, 0x4e, 0xdc, 0x8f, 0x77,
-	0xb9, 0x20, 0x06, 0x7a, 0x38, 0x5c, 0xe3, 0xab, 0xd1, 0xef, 0x6b, 0x1a,
-	0x32, 0xfb, 0x61, 0x2b, 0xfd, 0x3e, 0xc8, 0x81, 0x78, 0xe8, 0xe7, 0x35,
-	0x2e, 0xef, 0xd7, 0xee, 0xb1, 0x6d, 0xa7, 0xfc, 0xfb, 0x89, 0xa3, 0xe4,
-	0x21, 0xe9, 0x81, 0x2e, 0x63, 0x0e, 0xc8, 0x6f, 0x69, 0x9c, 0x89, 0x22,
-	0xed, 0x6d, 0xd2, 0x30, 0x5a, 0x39, 0x9f, 0x0c, 0x73, 0x38, 0xf2, 0xb6,
-	0xed, 0x84, 0xdd, 0x93, 0xcf, 0xcb, 0xdc, 0x65, 0xd4, 0x83, 0x23, 0x91,
-	0xf5, 0xfc, 0x7e, 0x22, 0xda, 0xf6, 0x18, 0xbd, 0x28, 0x61, 0x5f, 0x7c,
-	0x6e, 0xa8, 0xe9, 0x9b, 0x76, 0x14, 0xef, 0xab, 0xcf, 0x91, 0x3d, 0xa3,
-	0xf7, 0x19, 0xcd, 0xf7, 0x12, 0x42, 0x3e, 0x21, 0xef, 0x24, 0xf5, 0x59,
-	0x27, 0xef, 0x61, 0xda, 0x3d, 0xdc, 0x83, 0x75, 0x17, 0x26, 0xfd, 0x4f,
-	0xe8, 0x6f, 0xfc, 0xcd, 0x88, 0x38, 0x79, 0xff, 0x36, 0x9d, 0x7b, 0x92,
-	0xd7, 0xb1, 0xe6, 0x1c, 0xee, 0x55, 0x1f, 0xb5, 0xeb, 0x61, 0xfe, 0x4d,
-	0x0b, 0x96, 0x65, 0x01, 0x1b, 0x75, 0x08, 0x65, 0x6f, 0x5c, 0xba, 0x8e,
-	0x7e, 0x58, 0xf3, 0xc2, 0x66, 0xf8, 0x02, 0xc3, 0x47, 0xa1, 0xab, 0x8f,
-	0x26, 0x64, 0xe7, 0x51, 0xad, 0x1b, 0xd3, 0x6b, 0x63, 0x05, 0x7d, 0x6e,
-	0xd4, 0x79, 0x8f, 0x3e, 0xc7, 0xf6, 0xd6, 0xa3, 0x11, 0x39, 0x1c, 0xef,
-	0x73, 0x7b, 0x9c, 0xf7, 0x5a, 0x5d, 0x18, 0xc6, 0xb0, 0x5b, 0xd0, 0xfe,
-	0xf5, 0xe2, 0xd8, 0x61, 0xfc, 0x3a, 0x22, 0x33, 0x7b, 0x3b, 0x01, 0xdb,
-	0x5f, 0x5d, 0x66, 0xce, 0x20, 0x63, 0xad, 0xf4, 0xb7, 0xe7, 0xa3, 0x09,
-	0xca, 0xb2, 0x2e, 0xc0, 0x32, 0x72, 0x94, 0xfa, 0xcc, 0xd3, 0x3c, 0x0e,
-	0x18, 0xdc, 0x06, 0xed, 0x87, 0x90, 0x2f, 0xdf, 0x22, 0xde, 0x03, 0x90,
-	0x71, 0x47, 0x63, 0xd2, 0x73, 0xb4, 0x45, 0xb6, 0x1d, 0xa5, 0x1f, 0x52,
-	0xeb, 0x97, 0xd2, 0x2e, 0x7d, 0x04, 0x73, 0x7c, 0xb7, 0x96, 0x93, 0xdc,
-	0xd3, 0xdc, 0x4f, 0xde, 0x45, 0xdd, 0x2c, 0x6c, 0xe6, 0xcc, 0x51, 0x57,
-	0xef, 0x91, 0x66, 0x30, 0xe7, 0x6c, 0xd9, 0xc5, 0x38, 0x46, 0xe6, 0xe4,
-	0xe9, 0xa7, 0x8c, 0x76, 0x00, 0xc7, 0xef, 0xb5, 0xbc, 0xb3, 0xbe, 0xc3,
-	0xf2, 0xe8, 0xcf, 0xc8, 0x7b, 0x5b, 0x3a, 0x8c, 0xec, 0x7c, 0x4b, 0x07,
-	0x73, 0x93, 0x36, 0x7b, 0xbc, 0x37, 0x69, 0x7b, 0xc2, 0xc8, 0xd0, 0xd7,
-	0xe2, 0x45, 0x01, 0x8e, 0xc2, 0x7d, 0x29, 0x7d, 0x96, 0x2f, 0x38, 0xe7,
-	0xeb, 0xf3, 0x2b, 0xfe, 0xa2, 0xfe, 0x3b, 0x21, 0xdc, 0x23, 0xab, 0x7e,
-	0x6f, 0x65, 0x57, 0x85, 0x71, 0xf2, 0xcf, 0x86, 0x7f, 0x97, 0xa4, 0x26,
-	0xef, 0xb0, 0x76, 0x0f, 0x8c, 0xb1, 0xa6, 0xe5, 0xdc, 0xa0, 0xa0, 0xa4,
-	0xbf, 0x5f, 0xf4, 0x9c, 0x73, 0xbe, 0x70, 0xd6, 0xf9, 0xee, 0xb4, 0x04,
-	0x51, 0xef, 0x27, 0xce, 0xf7, 0x3d, 0xee, 0x99, 0x7f, 0xdd, 0xf9, 0x5e,
-	0xc1, 0x03, 0x1f, 0xde, 0x87, 0x79, 0xbc, 0xe2, 0xfc, 0x00, 0xeb, 0x7b,
-	0xb0, 0x98, 0x4e, 0xb9, 0x36, 0x26, 0x7e, 0xb6, 0xf0, 0x8a, 0xf3, 0xb5,
-	0x6a, 0x3c, 0x69, 0x30, 0xa4, 0x91, 0x43, 0x7c, 0x57, 0xc6, 0xbb, 0xb2,
-	0xde, 0xff, 0x71, 0xe6, 0xa6, 0x6d, 0x7e, 0x89, 0xe6, 0xe3, 0x85, 0xe5,
-	0x7d, 0x99, 0x51, 0xbd, 0x57, 0xf1, 0xac, 0x33, 0x37, 0x7f, 0x77, 0x87,
-	0xc9, 0x33, 0x3a, 0x8b, 0x77, 0x26, 0xe7, 0x72, 0x76, 0xfe, 0x2c, 0xea,
-	0x3c, 0xe3, 0xcc, 0xea, 0xf8, 0x97, 0xf6, 0xc5, 0x9d, 0x99, 0xf9, 0x67,
-	0x9c, 0x79, 0xbd, 0x07, 0x7d, 0xce, 0x79, 0x74, 0x9a, 0x7d, 0x9f, 0x43,
-	0x9d, 0x05, 0xe7, 0x04, 0xfa, 0x9b, 0x9f, 0xe6, 0x79, 0xdc, 0x6e, 0xd8,
-	0x05, 0xfc, 0x7b, 0x3f, 0xfc, 0x1e, 0xc7, 0xb3, 0xce, 0xfc, 0x72, 0xbf,
-	0x8b, 0xe8, 0x87, 0x75, 0x49, 0x8b, 0x1c, 0xf7, 0x59, 0xf4, 0xbf, 0x76,
-	0xaf, 0x6a, 0x2d, 0x4e, 0x5e, 0x00, 0x4e, 0x2e, 0x58, 0x9c, 0xbc, 0x6a,
-	0x71, 0xf2, 0x7c, 0x0d, 0x4e, 0x44, 0xad, 0xc4, 0xc9, 0xab, 0xc0, 0x89,
-	0xa8, 0xfa, 0x38, 0xc1, 0xbb, 0x32, 0xde, 0x69, 0x9c, 0xbc, 0xb4, 0x0a,
-	0x27, 0x4b, 0xcb, 0x71, 0x79, 0x83, 0x93, 0x17, 0x81, 0x93, 0xaf, 0x5a,
-	0xd8, 0x2f, 0x58, 0x9c, 0xe0, 0x3e, 0x7f, 0x01, 0x75, 0x5e, 0xaa, 0xc1,
-	0xc9, 0x05, 0xe0, 0xe4, 0x25, 0x8b, 0x93, 0xef, 0x5b, 0x9c, 0x7c, 0x1f,
-	0x75, 0x96, 0x80, 0x93, 0xf3, 0x75, 0x70, 0xf2, 0x22, 0x70, 0x12, 0xf6,
-	0x7b, 0x1e, 0xfd, 0x7c, 0xbf, 0x06, 0x27, 0x2f, 0xd6, 0xc1, 0x09, 0xf7,
-	0x62, 0xc3, 0x9c, 0xee, 0x99, 0xd7, 0xc9, 0xe9, 0x96, 0x3b, 0x5f, 0x3f,
-	0xa7, 0x9b, 0x75, 0x66, 0xa4, 0xfa, 0x37, 0x25, 0xee, 0xb6, 0x39, 0x6a,
-	0x26, 0x17, 0xb0, 0xfa, 0xcd, 0xa6, 0x6e, 0xf0, 0x79, 0x3e, 0xe7, 0x8a,
-	0xc9, 0x29, 0x8d, 0xee, 0xf8, 0x10, 0x78, 0x6d, 0x97, 0x1c, 0x38, 0xd6,
-	0x78, 0x38, 0x6b, 0xcb, 0xbc, 0x1d, 0xdd, 0x39, 0xa5, 0xf8, 0x2e, 0xcc,
-	0x49, 0xa0, 0x5f, 0xd2, 0xc0, 0x6f, 0x0b, 0xf6, 0xa6, 0xa5, 0x76, 0x4f,
-	0xba, 0xc0, 0x6f, 0x34, 0x61, 0xec, 0x25, 0xfe, 0xfd, 0x8b, 0x24, 0xf3,
-	0xac, 0xf2, 0x1a, 0xde, 0x14, 0xf4, 0xc7, 0xa0, 0xce, 0xad, 0xca, 0x14,
-	0x68, 0x73, 0x27, 0x99, 0xa3, 0x06, 0x5b, 0x79, 0xc8, 0x9e, 0x09, 0xf3,
-	0xf5, 0x39, 0x95, 0x2a, 0xff, 0xd4, 0x9e, 0x87, 0x26, 0xdf, 0x55, 0xe9,
-	0xe6, 0xe0, 0xf2, 0x77, 0x02, 0x4f, 0xca, 0xd3, 0x3a, 0x56, 0xdc, 0x8c,
-	0xf5, 0x09, 0x82, 0xc7, 0x7c, 0x13, 0xa3, 0x5d, 0xd4, 0x31, 0x5a, 0x81,
-	0x37, 0x3e, 0x69, 0xe3, 0xb4, 0x3d, 0x83, 0x2f, 0x2d, 0xc7, 0x68, 0x6b,
-	0xf3, 0x59, 0xcc, 0xfe, 0x7a, 0xa6, 0xf4, 0x88, 0xce, 0xd1, 0x19, 0xe1,
-	0xf7, 0x37, 0x20, 0x23, 0x26, 0x66, 0xe6, 0x65, 0xf2, 0x41, 0x3e, 0x53,
-	0xbf, 0x45, 0xa0, 0xc3, 0x28, 0xc3, 0x73, 0x92, 0x19, 0x64, 0x99, 0x69,
-	0x33, 0xa2, 0xfd, 0xe5, 0x93, 0x32, 0xbc, 0x3c, 0x3e, 0xf1, 0x7b, 0x57,
-	0xcd, 0x77, 0xab, 0x69, 0xf3, 0xa4, 0x9d, 0x4c, 0x85, 0xef, 0xc3, 0x3d,
-	0xf2, 0xbb, 0xec, 0xb7, 0xb3, 0xf8, 0xbe, 0xf6, 0x5b, 0xad, 0x5a, 0x74,
-	0xe0, 0x37, 0xbf, 0x87, 0x36, 0xe5, 0x8c, 0xa0, 0xcd, 0x82, 0xdb, 0x32,
-	0xaa, 0x86, 0x6e, 0x18, 0xe5, 0xb9, 0xb9, 0xd9, 0x35, 0xdf, 0xba, 0xae,
-	0xea, 0xc5, 0xbc, 0x5e, 0x53, 0xe6, 0x67, 0xdd, 0x05, 0x5a, 0xd4, 0xb4,
-	0xa5, 0xe9, 0xff, 0xc0, 0xb2, 0xbe, 0xa4, 0x9e, 0x35, 0xdf, 0x9e, 0x31,
-	0xfa, 0x32, 0x95, 0x18, 0xc1, 0xf8, 0xfa, 0x6f, 0x2a, 0xd8, 0x73, 0xbd,
-	0xd9, 0xf9, 0xdb, 0xb5, 0xae, 0x9f, 0xf2, 0xd3, 0xc9, 0xa8, 0xd4, 0xa9,
-	0x5b, 0xaa, 0xa9, 0xab, 0xe7, 0xed, 0xca, 0x7f, 0xc5, 0xda, 0x7c, 0xbe,
-	0x58, 0x96, 0xe1, 0xe9, 0xbf, 0x84, 0xff, 0x98, 0x90, 0xdf, 0x2e, 0x96,
-	0x40, 0xaf, 0xb9, 0xcd, 0xf6, 0x5b, 0x4d, 0x19, 0xc0, 0xcd, 0x6f, 0xaf,
-	0xe8, 0x7c, 0xe2, 0xc8, 0x17, 0x40, 0x17, 0x9f, 0x2b, 0x71, 0x0c, 0xc0,
-	0x12, 0x81, 0x6d, 0x0f, 0x3b, 0x61, 0xa6, 0xa4, 0x73, 0xe7, 0xae, 0x2b,
-	0x97, 0x74, 0xcc, 0x62, 0x67, 0xb9, 0x53, 0x76, 0x95, 0x5b, 0x64, 0x37,
-	0xf4, 0xc2, 0xee, 0xb2, 0x87, 0x2b, 0x26, 0xef, 0x2e, 0x9b, 0x75, 0xfa,
-	0x58, 0x99, 0xeb, 0xbd, 0x43, 0x66, 0x8f, 0xad, 0xfe, 0x3e, 0xe7, 0x42,
-	0x2e, 0xfc, 0x3b, 0x4b, 0x4a, 0x31, 0xbf, 0x8c, 0xb4, 0x84, 0xab, 0x98,
-	0x3a, 0xbc, 0xa0, 0xf1, 0xc0, 0x0c, 0xd7, 0x54, 0x69, 0x49, 0x98, 0xa7,
-	0xcf, 0xbf, 0xad, 0x34, 0x73, 0x39, 0xcf, 0x4d, 0xf3, 0x5b, 0x5e, 0x3b,
-	0x2b, 0x61, 0xde, 0x78, 0xbd, 0x9c, 0x71, 0xd8, 0xf9, 0x3b, 0xc2, 0x1c,
-	0xbf, 0x18, 0x73, 0xc6, 0xa5, 0xeb, 0x54, 0x0b, 0xee, 0xa7, 0x2f, 0xd7,
-	0x67, 0x9b, 0x4f, 0x89, 0x2d, 0xd3, 0xf9, 0xe4, 0x78, 0x5e, 0xfd, 0x7d,
-	0xb5, 0x90, 0x1f, 0xaa, 0x7f, 0xa7, 0x40, 0xe4, 0xff, 0x02, 0xfb, 0x2e,
-	0x88, 0x71, 0xec, 0x6e, 0x00, 0x00, 0x00 };
+	0xbd, 0x7d, 0x0d, 0x74, 0x5c, 0xd7, 0x5d, 0xe7, 0xff, 0xdd, 0x79, 0x92,
+	0xc6, 0xb2, 0x6c, 0x3f, 0xcb, 0x13, 0x79, 0x62, 0xab, 0xf6, 0x8c, 0xf4,
+	0x64, 0xab, 0x91, 0x08, 0x2f, 0xae, 0x28, 0x82, 0x9d, 0x84, 0xe9, 0x48,
+	0xb2, 0x9d, 0x34, 0xed, 0xca, 0x8d, 0x5b, 0xb2, 0x9c, 0x02, 0x62, 0x24,
+	0x27, 0xe9, 0x77, 0xd2, 0x04, 0xb6, 0xec, 0xc9, 0x6e, 0x26, 0x23, 0xf9,
+	0x83, 0x74, 0xec, 0x51, 0x12, 0x25, 0xce, 0xa1, 0x3d, 0xbb, 0xaa, 0xa4,
+	0xd8, 0x06, 0x06, 0x8f, 0x93, 0xb8, 0xa5, 0xec, 0xa6, 0x54, 0x28, 0xae,
+	0x09, 0xa1, 0x07, 0x52, 0x48, 0xd9, 0x40, 0x53, 0x2a, 0xdc, 0xb4, 0xcd,
+	0x9e, 0x53, 0xb6, 0x01, 0xca, 0x12, 0x68, 0xe8, 0xdb, 0xdf, 0xef, 0xde,
+	0xfb, 0x34, 0xa3, 0x0f, 0xe7, 0xa3, 0xec, 0xe2, 0x73, 0x9e, 0xdf, 0xbc,
+	0xfb, 0xee, 0xc7, 0xff, 0xfe, 0xef, 0xff, 0xfb, 0xfe, 0xef, 0xd3, 0x76,
+	0x91, 0x66, 0xb1, 0xff, 0x36, 0xe0, 0x7a, 0x5b, 0xea, 0xf6, 0xd1, 0x6b,
+	0xae, 0xfe, 0xc9, 0xab, 0xf9, 0xec, 0x3a, 0x4d, 0x31, 0x79, 0x13, 0xff,
+	0x52, 0x6f, 0xa0, 0x0e, 0x3a, 0xf4, 0xa2, 0xb1, 0x78, 0x49, 0x5c, 0x65,
+	0xdc, 0x3b, 0x72, 0xbe, 0xc4, 0x63, 0x99, 0x91, 0x5f, 0x1e, 0xf5, 0x45,
+	0xb2, 0x95, 0x9e, 0xd4, 0x80, 0xfc, 0x4b, 0x58, 0x48, 0xb8, 0xc2, 0xf2,
+	0xb7, 0x64, 0x5e, 0xfd, 0x6f, 0x5f, 0xf8, 0xc9, 0xf4, 0xcb, 0xd3, 0x31,
+	0x89, 0x7b, 0x99, 0x0f, 0x8b, 0xb7, 0x4b, 0xe2, 0xed, 0x19, 0xb9, 0xe3,
+	0xd3, 0xbb, 0xff, 0x46, 0x64, 0x63, 0xd4, 0xd7, 0x4b, 0xe1, 0x17, 0x76,
+	0x4b, 0x61, 0x5b, 0x26, 0x39, 0xd2, 0x90, 0x49, 0xc8, 0x17, 0xab, 0x9e,
+	0x9c, 0xab, 0xca, 0xf0, 0xa9, 0xd2, 0xcb, 0xa1, 0x9b, 0x09, 0x63, 0x13,
+	0x7d, 0x8e, 0xc4, 0x32, 0x72, 0x61, 0xb4, 0xef, 0x9e, 0x50, 0xf9, 0x32,
+	0xe2, 0x65, 0xfc, 0x60, 0x41, 0x5a, 0xfa, 0x2f, 0xf6, 0xa1, 0x4e, 0xe5,
+	0xe0, 0xb5, 0x8d, 0x27, 0xe2, 0xa2, 0x32, 0x5d, 0xcf, 0xe7, 0x62, 0xd7,
+	0x88, 0xf2, 0xfd, 0xe0, 0x82, 0x74, 0x05, 0x4f, 0x09, 0xca, 0xcf, 0xc6,
+	0x25, 0x57, 0x95, 0x16, 0x94, 0xe1, 0xde, 0x8c, 0x3a, 0x69, 0x2f, 0x17,
+	0x4b, 0x48, 0xb1, 0xfa, 0x63, 0xcd, 0x66, 0xec, 0xaf, 0xaf, 0x33, 0xf7,
+	0xdd, 0xf6, 0xbe, 0xee, 0x67, 0xdd, 0x4c, 0x3c, 0xae, 0x4e, 0xc8, 0xcb,
+	0x13, 0x7d, 0x2f, 0x87, 0x31, 0xdf, 0xf7, 0x06, 0xa4, 0x41, 0x06, 0x13,
+	0x80, 0xa9, 0xec, 0xa0, 0xef, 0x14, 0xda, 0xfe, 0x12, 0x70, 0x0e, 0xf8,
+	0xca, 0x29, 0x29, 0x10, 0xce, 0x72, 0x5c, 0x16, 0x63, 0x49, 0x01, 0xfc,
+	0xc0, 0x45, 0xbb, 0x8c, 0xa3, 0x3c, 0x57, 0xe2, 0x7c, 0x5c, 0xc9, 0x7b,
+	0x1e, 0xe6, 0xd2, 0x8e, 0x36, 0x3b, 0x1d, 0xd3, 0x3f, 0x9e, 0x97, 0xd5,
+	0x67, 0xdd, 0xe7, 0x51, 0x37, 0xa5, 0xeb, 0x3d, 0x51, 0x4d, 0xca, 0xe3,
+	0xd5, 0x84, 0x3c, 0x56, 0xfd, 0x98, 0x64, 0x3d, 0xe2, 0x00, 0xb0, 0x96,
+	0x1b, 0x65, 0x60, 0xaa, 0x59, 0x72, 0x53, 0x9d, 0xc9, 0xbc, 0x84, 0xe1,
+	0x9d, 0xc1, 0x07, 0x64, 0xa4, 0x15, 0xf5, 0xcb, 0x7c, 0x97, 0x5c, 0xf6,
+	0x2e, 0x1f, 0xf4, 0x78, 0x79, 0xe5, 0x48, 0xf6, 0x60, 0x3a, 0x39, 0xa2,
+	0xf8, 0xdc, 0x20, 0xb9, 0x5e, 0x3c, 0x0f, 0xbb, 0x12, 0xf3, 0xc3, 0xf0,
+	0x8e, 0x60, 0x17, 0xe0, 0x48, 0xa7, 0x52, 0x8a, 0x6d, 0xd9, 0x2e, 0x5d,
+	0x48, 0xa9, 0x24, 0xe6, 0x71, 0xb5, 0xa4, 0x5a, 0xc3, 0xf0, 0x3d, 0x81,
+	0x8f, 0x72, 0x91, 0x81, 0x92, 0xdc, 0xae, 0x32, 0x3e, 0xfa, 0x94, 0x40,
+	0x65, 0xb6, 0x60, 0x1e, 0x3d, 0xc0, 0x43, 0xa3, 0x64, 0x13, 0x92, 0x55,
+	0x19, 0x49, 0xa9, 0xcc, 0x3a, 0x94, 0x39, 0xd2, 0xe0, 0xff, 0x77, 0x4b,
+	0x7f, 0x9b, 0xf0, 0x2c, 0xc3, 0x2a, 0xd3, 0xba, 0xa2, 0x3c, 0x9d, 0x12,
+	0xf5, 0xe3, 0x71, 0x8c, 0xd9, 0x9d, 0x55, 0x2c, 0xc3, 0x5d, 0x97, 0x15,
+	0x9a, 0x56, 0x97, 0x4d, 0x3a, 0xcb, 0xcb, 0x4e, 0xb5, 0x10, 0x56, 0x51,
+	0xfc, 0x9d, 0xd4, 0x73, 0xcd, 0x26, 0x3a, 0xbd, 0x06, 0xcc, 0x6b, 0x38,
+	0x48, 0x7b, 0x43, 0xea, 0xb9, 0x50, 0xda, 0x08, 0x33, 0xdf, 0x29, 0xbc,
+	0x43, 0xd5, 0x4c, 0x80, 0x75, 0x4e, 0xc8, 0x51, 0xcc, 0xed, 0xd2, 0x54,
+	0xda, 0xeb, 0x50, 0xb8, 0xcf, 0xf1, 0x77, 0x18, 0xe6, 0x82, 0x82, 0xa6,
+	0x81, 0x6f, 0x4e, 0x25, 0xf1, 0x0c, 0xf8, 0x13, 0xd9, 0xf4, 0x66, 0xb9,
+	0xc9, 0xae, 0xcb, 0x37, 0x31, 0x66, 0xa7, 0x77, 0x87, 0xea, 0xf4, 0x02,
+	0x95, 0xf6, 0x66, 0xe4, 0xf7, 0xf1, 0x1c, 0x86, 0x07, 0x82, 0x74, 0xb2,
+	0x80, 0x35, 0x7b, 0xb1, 0x94, 0x90, 0x6f, 0x95, 0xd2, 0xa0, 0xfc, 0x74,
+	0xf7, 0xac, 0xf4, 0x04, 0xb3, 0x80, 0xb7, 0x88, 0xeb, 0x08, 0xdf, 0x55,
+	0xf0, 0xae, 0xc2, 0xb6, 0x61, 0x78, 0x53, 0xf0, 0xeb, 0xe1, 0x48, 0x9b,
+	0xe1, 0xa5, 0x2f, 0x96, 0xb1, 0x9e, 0x80, 0xf9, 0x71, 0xac, 0xd3, 0x63,
+	0xe5, 0x88, 0x4e, 0xba, 0xb1, 0xee, 0xa4, 0x0d, 0xd2, 0xc5, 0x1e, 0x4b,
+	0xff, 0xa3, 0xf6, 0x2e, 0x92, 0x03, 0x8d, 0xe5, 0x82, 0x1f, 0x84, 0x59,
+	0xcd, 0x63, 0xe2, 0x0c, 0x94, 0x49, 0xbb, 0x0d, 0x80, 0x95, 0x8f, 0x1f,
+	0xb3, 0xf5, 0xda, 0x1d, 0xe0, 0x96, 0xeb, 0xc0, 0xf7, 0x71, 0xe5, 0x37,
+	0xd9, 0xf7, 0x11, 0x2f, 0xf1, 0x1f, 0xe8, 0xcd, 0xaf, 0xd5, 0xcb, 0x91,
+	0x26, 0xab, 0x05, 0xc9, 0x3f, 0x18, 0xca, 0x40, 0x00, 0x3c, 0xb1, 0x4f,
+	0x2f, 0x10, 0xdd, 0xd6, 0x63, 0x1d, 0x5d, 0x17, 0xff, 0xae, 0x69, 0xc4,
+	0x18, 0xce, 0x60, 0xb9, 0xd6, 0x76, 0xb0, 0xfc, 0xe4, 0x16, 0x0b, 0x1f,
+	0x9e, 0xfb, 0x9d, 0x5c, 0xf5, 0x6f, 0xed, 0xda, 0x46, 0xf3, 0xb8, 0x69,
+	0x0d, 0xda, 0x0e, 0xc3, 0x89, 0x40, 0x46, 0x54, 0x66, 0x31, 0x9e, 0x2b,
+	0x89, 0xd3, 0x90, 0xf1, 0xbd, 0x21, 0x59, 0x27, 0x76, 0x5e, 0xb6, 0xdc,
+	0x03, 0xaf, 0x74, 0xa1, 0xdc, 0x11, 0xc8, 0x8d, 0x11, 0x07, 0x65, 0x1d,
+	0x15, 0x94, 0x61, 0xfd, 0xc6, 0x81, 0xaf, 0x7c, 0xa9, 0x5f, 0xaf, 0x65,
+	0xbe, 0x34, 0x0c, 0xde, 0xcf, 0xe0, 0x77, 0x76, 0xb3, 0x2b, 0x5d, 0xa0,
+	0x43, 0xae, 0xb1, 0xb8, 0xb9, 0xdd, 0xa0, 0xd5, 0xea, 0xeb, 0x4b, 0x2c,
+	0x3d, 0xf7, 0xe0, 0x5f, 0x88, 0xd3, 0x25, 0x78, 0x62, 0x19, 0xf2, 0xf5,
+	0xf3, 0x21, 0xe8, 0x19, 0x65, 0x84, 0x99, 0x35, 0x13, 0x32, 0x51, 0xde,
+	0x26, 0xc5, 0x29, 0x5f, 0xc6, 0x4b, 0xf3, 0xdd, 0x4a, 0x5e, 0x86, 0xac,
+	0xf1, 0x41, 0x0b, 0x69, 0xf0, 0x41, 0x46, 0x06, 0xaa, 0x18, 0xaf, 0x84,
+	0x7b, 0xb9, 0x13, 0x6d, 0x5d, 0xc9, 0x26, 0xcd, 0x3a, 0x17, 0x4b, 0x63,
+	0xc0, 0x15, 0xd6, 0x8d, 0xb2, 0x41, 0xc3, 0x3c, 0x0c, 0x3a, 0xf4, 0x24,
+	0xd7, 0xa7, 0xe1, 0x7c, 0x13, 0xf0, 0xc5, 0x65, 0x26, 0x68, 0xb4, 0x38,
+	0x22, 0x7f, 0xc6, 0xdd, 0x01, 0xe0, 0x61, 0xa0, 0x72, 0x0f, 0xfa, 0x6f,
+	0xc1, 0x6f, 0x96, 0x89, 0x2d, 0x73, 0xf5, 0xf3, 0x40, 0x85, 0x30, 0x47,
+	0x74, 0x0f, 0x3e, 0x98, 0x82, 0xfc, 0x01, 0xdd, 0x0f, 0x90, 0x5f, 0xe6,
+	0x38, 0x17, 0xc2, 0xb5, 0x4d, 0xff, 0x1e, 0x9f, 0xda, 0xa1, 0x9f, 0xf3,
+	0xc3, 0xdb, 0xa4, 0x30, 0x17, 0xcd, 0x99, 0xb2, 0x87, 0xf2, 0x26, 0x7d,
+	0x0c, 0x74, 0x05, 0xf9, 0x13, 0x86, 0x0f, 0x06, 0x94, 0x41, 0x61, 0xf8,
+	0x78, 0x40, 0x99, 0x74, 0x1e, 0xb2, 0x86, 0x72, 0x88, 0x72, 0x61, 0x50,
+	0x71, 0xdd, 0x73, 0xa5, 0x00, 0xeb, 0xd3, 0x28, 0xf9, 0xde, 0x47, 0x08,
+	0x2b, 0x64, 0xd8, 0xb3, 0x1f, 0xcb, 0xf9, 0x85, 0x64, 0x4c, 0xe3, 0x49,
+	0xb0, 0x5e, 0x71, 0xc9, 0xea, 0x99, 0x75, 0x48, 0xb1, 0x77, 0xd2, 0xd6,
+	0x79, 0x49, 0xd7, 0x71, 0x57, 0xd5, 0xf9, 0x75, 0x65, 0x78, 0x3c, 0xc0,
+	0x5a, 0xfe, 0xb4, 0x22, 0x1e, 0x3b, 0x76, 0xf1, 0x59, 0xe2, 0x0d, 0x99,
+	0xaf, 0xe1, 0xdd, 0xb9, 0x3b, 0x1f, 0xf5, 0xd7, 0x7a, 0xb7, 0xb5, 0x61,
+	0xf5, 0xbb, 0x09, 0x71, 0xfd, 0x74, 0xf7, 0x01, 0xf5, 0x4f, 0x78, 0x17,
+	0x86, 0x8f, 0x06, 0x51, 0x79, 0x6f, 0xc3, 0xea, 0x31, 0x7e, 0x76, 0x8d,
+	0xb2, 0xf3, 0x6b, 0x94, 0xfd, 0xc9, 0x1a, 0x65, 0xef, 0x6d, 0x5c, 0x5d,
+	0xf6, 0xc0, 0x1a, 0x65, 0x4f, 0xaf, 0x51, 0xe6, 0x37, 0xad, 0x2e, 0xdb,
+	0xb5, 0x46, 0xd9, 0x5b, 0xd7, 0x28, 0x3b, 0xb0, 0x46, 0x99, 0x0b, 0x1e,
+	0xde, 0x25, 0xc5, 0xc4, 0xbd, 0x9c, 0xbb, 0xc5, 0xcd, 0xe7, 0x62, 0xab,
+	0x71, 0xd3, 0x80, 0x7a, 0xed, 0x2b, 0xea, 0x7d, 0x6d, 0x8d, 0x7a, 0x8d,
+	0xa8, 0xd7, 0xba, 0xa2, 0xde, 0xcd, 0xee, 0xea, 0x7a, 0x4d, 0xa8, 0x17,
+	0x5f, 0x51, 0xef, 0x77, 0xd7, 0xa8, 0xc7, 0xf2, 0x4f, 0xd9, 0x71, 0x7a,
+	0xa0, 0xd1, 0x5e, 0x6b, 0xbd, 0x1a, 0x45, 0xda, 0x58, 0x1e, 0x40, 0x1f,
+	0xfd, 0xb4, 0x32, 0x32, 0x86, 0xf2, 0x4c, 0xe3, 0x0d, 0x74, 0x9e, 0x04,
+	0xdd, 0x51, 0x26, 0x83, 0xcf, 0x7c, 0xf2, 0xfe, 0x06, 0x19, 0x49, 0xf4,
+	0x78, 0x6f, 0x53, 0x2d, 0xa0, 0xb1, 0xb4, 0x97, 0x52, 0xe4, 0x3f, 0x29,
+	0x80, 0xb7, 0x0b, 0x03, 0xa2, 0x12, 0x4a, 0x42, 0x19, 0x0c, 0x54, 0xab,
+	0x92, 0x7b, 0xc0, 0x5f, 0x59, 0xe8, 0xbf, 0x03, 0xe1, 0x80, 0xe6, 0x2d,
+	0x53, 0xf7, 0xf2, 0xf2, 0xb9, 0x5f, 0x8e, 0x50, 0xae, 0x66, 0x82, 0x3b,
+	0x73, 0xfe, 0x7c, 0x7f, 0x23, 0x68, 0xf6, 0x12, 0xda, 0xec, 0x43, 0xcb,
+	0x43, 0x15, 0x57, 0x06, 0x2b, 0x19, 0xf0, 0x82, 0x23, 0x17, 0xfd, 0x4d,
+	0x72, 0x31, 0x40, 0xdd, 0x6a, 0x4c, 0x16, 0x12, 0x8e, 0x2c, 0xe0, 0x39,
+	0x17, 0xe0, 0x5d, 0x35, 0xe2, 0xad, 0x8c, 0x1c, 0x2e, 0xf7, 0xcb, 0xb1,
+	0xf2, 0x87, 0x55, 0xa4, 0x23, 0x87, 0x82, 0xf5, 0x72, 0xc6, 0x33, 0x7d,
+	0xef, 0xf3, 0xe7, 0xa1, 0x9d, 0x5d, 0xb9, 0xe4, 0xa7, 0x93, 0x0b, 0x9a,
+	0x27, 0xfe, 0x31, 0x1c, 0x44, 0x3f, 0x33, 0x7e, 0xda, 0xfb, 0x03, 0x0a,
+	0xc9, 0x0a, 0x6d, 0xa9, 0x5a, 0x5f, 0xe3, 0xe8, 0xeb, 0x68, 0x79, 0x83,
+	0xdc, 0x6a, 0xdb, 0xef, 0xf5, 0xe7, 0xbb, 0xc1, 0x73, 0xde, 0x29, 0xca,
+	0x90, 0x12, 0xe0, 0x3a, 0x08, 0xde, 0x46, 0xdb, 0x2f, 0x09, 0xdb, 0xc0,
+	0xf6, 0x2a, 0x6d, 0x82, 0xac, 0xff, 0x87, 0xf0, 0xd6, 0x04, 0xeb, 0xb3,
+	0x8c, 0xfa, 0x4b, 0x26, 0x55, 0x06, 0x32, 0xa1, 0xaf, 0x0b, 0xfa, 0x2b,
+	0x25, 0x83, 0x55, 0xc8, 0x9e, 0xf2, 0x0f, 0xc3, 0xac, 0xcb, 0x31, 0xa2,
+	0xb1, 0xa4, 0x50, 0xab, 0xc3, 0x32, 0xd6, 0x23, 0xff, 0x2f, 0x2e, 0xc9,
+	0x8a, 0x02, 0xe4, 0x8b, 0xb1, 0xd1, 0xfe, 0x13, 0x78, 0xb4, 0x5d, 0x06,
+	0x4b, 0xe9, 0x42, 0x56, 0x76, 0x61, 0xfd, 0x7e, 0x0d, 0x6b, 0xea, 0xe2,
+	0xfa, 0x93, 0xf5, 0xb2, 0x31, 0x80, 0x1d, 0xc0, 0x72, 0x74, 0xda, 0x46,
+	0xfb, 0xec, 0x19, 0xe0, 0x61, 0x9c, 0x6b, 0x9e, 0xcc, 0xc5, 0x9c, 0x61,
+	0xda, 0x3e, 0xc3, 0x90, 0x8f, 0xf9, 0x0a, 0xfb, 0x26, 0xbc, 0x49, 0xfb,
+	0x1b, 0x36, 0x5b, 0xa9, 0xdd, 0xfe, 0x6e, 0xc1, 0xef, 0x94, 0xfd, 0x0d,
+	0x99, 0x5a, 0xf2, 0xed, 0xef, 0x04, 0x7e, 0x77, 0xdb, 0xdf, 0x49, 0xfc,
+	0xee, 0xd5, 0xbf, 0x27, 0xca, 0x7b, 0xf7, 0x2a, 0xff, 0x6a, 0xc9, 0xcf,
+	0xb5, 0xcb, 0xe1, 0xd2, 0x7b, 0xad, 0x6c, 0xc1, 0x25, 0x9f, 0x77, 0xcc,
+	0x3c, 0x01, 0x77, 0x99, 0x6d, 0x0a, 0xce, 0xb0, 0xb6, 0xdd, 0xda, 0x61,
+	0xeb, 0xf4, 0x78, 0x9b, 0x85, 0x34, 0x30, 0xe1, 0x0c, 0x54, 0x9d, 0x6c,
+	0x2c, 0xd3, 0x95, 0x1c, 0x97, 0x63, 0xf8, 0x2d, 0x5e, 0x2c, 0xf3, 0x79,
+	0xdc, 0x0d, 0x0e, 0xbe, 0x00, 0x7d, 0x33, 0x5e, 0xa6, 0xbc, 0xf4, 0x31,
+	0xf7, 0x94, 0x9c, 0x5f, 0x66, 0xaf, 0x11, 0x17, 0x4a, 0xf2, 0x53, 0xe9,
+	0x47, 0x0a, 0x92, 0x2e, 0x4c, 0x83, 0x21, 0x0e, 0x04, 0xae, 0xbc, 0x27,
+	0x00, 0xed, 0x5e, 0xed, 0xc8, 0xde, 0xab, 0x5d, 0xd8, 0x57, 0xfe, 0xf4,
+	0x5e, 0xc8, 0xd8, 0x7c, 0xe9, 0xea, 0x18, 0xe9, 0x41, 0x9d, 0x95, 0x11,
+	0x37, 0x03, 0x6c, 0x9f, 0xed, 0x1d, 0x1c, 0x2f, 0xe5, 0x3f, 0xac, 0x32,
+	0xb7, 0xff, 0x6a, 0xae, 0x6f, 0x17, 0x74, 0x79, 0x18, 0xc6, 0x32, 0x6d,
+	0xd0, 0x4b, 0x5c, 0x57, 0xea, 0xa9, 0x9b, 0x6e, 0x8a, 0x65, 0x1a, 0x64,
+	0xe0, 0x60, 0x1b, 0xea, 0xb3, 0x9c, 0xb8, 0x72, 0xd0, 0x47, 0x3a, 0x35,
+	0x28, 0x72, 0xf7, 0x44, 0xdf, 0xa2, 0x33, 0x3e, 0xf9, 0x73, 0xe0, 0xc7,
+	0x7e, 0xc9, 0x1f, 0x7c, 0x00, 0xf8, 0x7d, 0xd9, 0x29, 0x4e, 0xbd, 0xe2,
+	0x8c, 0x4f, 0xfd, 0x9d, 0x33, 0x31, 0xb5, 0x63, 0xc7, 0x50, 0xff, 0x8e,
+	0x1d, 0xa3, 0xfd, 0xae, 0xd5, 0x2d, 0x3b, 0x76, 0x4c, 0xf4, 0x67, 0x31,
+	0xff, 0x1e, 0x6f, 0x50, 0x7c, 0x6f, 0x2f, 0x95, 0x7c, 0xc2, 0xac, 0xfd,
+	0x4c, 0xd0, 0x8d, 0xf7, 0x6c, 0xdf, 0xab, 0xdf, 0x0f, 0x48, 0x4f, 0xb2,
+	0x55, 0x38, 0x7e, 0x87, 0xd5, 0x49, 0x6c, 0x07, 0x7a, 0xe9, 0xa5, 0x1d,
+	0xa8, 0x50, 0x2f, 0x05, 0x7c, 0xd0, 0x26, 0xde, 0x06, 0x1b, 0x82, 0xed,
+	0x94, 0x5d, 0xf7, 0x92, 0x6a, 0xf0, 0x63, 0xba, 0x5f, 0x75, 0x36, 0x13,
+	0x33, 0x6b, 0xde, 0x63, 0xed, 0xeb, 0x4d, 0x28, 0xe7, 0x33, 0x71, 0x49,
+	0x7c, 0xd1, 0xde, 0x69, 0xd0, 0xf6, 0x69, 0xbe, 0x44, 0x5a, 0x72, 0x65,
+	0xac, 0xd4, 0x8f, 0x36, 0xa0, 0x97, 0xb3, 0xf6, 0x3a, 0x81, 0xf1, 0x0e,
+	0xa2, 0xaf, 0x13, 0x47, 0xd1, 0x8e, 0xb2, 0x24, 0xdd, 0x2d, 0xea, 0x41,
+	0xd4, 0xe9, 0xf1, 0xb6, 0x08, 0xed, 0x9a, 0x47, 0x24, 0x5f, 0x26, 0xdf,
+	0xd3, 0x36, 0x88, 0x4b, 0xaa, 0x0d, 0xcf, 0xd5, 0xc3, 0xb0, 0x75, 0x1a,
+	0x22, 0x7b, 0x43, 0x6a, 0x76, 0xd1, 0xaf, 0x2a, 0xf1, 0x0f, 0xcb, 0xc8,
+	0xec, 0x76, 0xd4, 0x33, 0xf6, 0xbc, 0xf2, 0x61, 0x17, 0xcd, 0x66, 0x25,
+	0xb7, 0xeb, 0x5e, 0xdc, 0x3d, 0x3c, 0x17, 0x71, 0x7f, 0x0b, 0xee, 0xe3,
+	0xb8, 0x47, 0x70, 0x02, 0xe7, 0x41, 0xcc, 0xea, 0xb2, 0x51, 0x8c, 0xfd,
+	0xef, 0x25, 0x37, 0x09, 0x7a, 0x2d, 0x85, 0x9b, 0x72, 0x7e, 0xd6, 0x53,
+	0xa2, 0xb6, 0x28, 0x99, 0x40, 0x7d, 0xf8, 0x29, 0xfe, 0x11, 0x19, 0x3d,
+	0x8d, 0xdf, 0x0f, 0xd2, 0xee, 0x9e, 0x90, 0xd1, 0x59, 0x8e, 0x53, 0x02,
+	0x4c, 0x93, 0x92, 0x3f, 0xfd, 0x00, 0xae, 0x29, 0x5c, 0x0f, 0xe3, 0xe2,
+	0xdc, 0xd8, 0xff, 0xc2, 0x66, 0x25, 0x2d, 0xfa, 0x39, 0x4f, 0xfa, 0xae,
+	0xe2, 0x37, 0x69, 0xbb, 0x4a, 0x1b, 0x08, 0x74, 0x5d, 0x8d, 0xe8, 0x3d,
+	0xb0, 0xbf, 0x93, 0x9a, 0xdf, 0x0b, 0xad, 0xa0, 0xa5, 0x6a, 0x56, 0xcb,
+	0x22, 0xc0, 0x00, 0xb9, 0x03, 0x9b, 0xa4, 0x95, 0x73, 0xec, 0xb5, 0x65,
+	0xbd, 0xba, 0x2c, 0xa5, 0xcb, 0xfa, 0x6c, 0x19, 0xee, 0xd5, 0x06, 0x19,
+	0x69, 0x03, 0xc4, 0x94, 0xdb, 0x12, 0xe1, 0x93, 0xb2, 0x01, 0x74, 0x8d,
+	0xf5, 0x3d, 0x7f, 0x59, 0xb9, 0xb8, 0xa8, 0xed, 0xbd, 0x73, 0x55, 0xd2,
+	0x37, 0x69, 0x3e, 0x0c, 0xef, 0x0f, 0x9a, 0xd0, 0x3f, 0x65, 0x81, 0x48,
+	0xc3, 0x09, 0x57, 0xa6, 0x3d, 0xd2, 0xc0, 0xc7, 0x5a, 0x48, 0x03, 0x8d,
+	0x3e, 0x69, 0xbb, 0x9e, 0xef, 0xb8, 0x86, 0xec, 0xaf, 0x00, 0x1b, 0x92,
+	0xb6, 0x64, 0x17, 0xec, 0x73, 0x8e, 0x71, 0x8c, 0xcf, 0x9e, 0x02, 0xaf,
+	0xe5, 0x96, 0x78, 0x4d, 0x64, 0xa6, 0x44, 0xdc, 0x44, 0x36, 0x26, 0xd7,
+	0x99, 0xf8, 0x39, 0x87, 0x39, 0xf3, 0x7e, 0xde, 0xe2, 0xe9, 0xf3, 0x16,
+	0x4f, 0x4f, 0xda, 0xbb, 0xe7, 0xe4, 0xb5, 0xcd, 0x38, 0x8f, 0x67, 0xae,
+	0x0f, 0xe8, 0xaa, 0x4a, 0x9e, 0x9b, 0xc6, 0x1d, 0x75, 0xcb, 0xe7, 0x64,
+	0x54, 0xdb, 0x6f, 0x31, 0x79, 0x87, 0x96, 0x79, 0x5f, 0xc5, 0x5a, 0x96,
+	0x00, 0x73, 0x83, 0x14, 0x12, 0x31, 0xbd, 0xf6, 0xae, 0xff, 0x5b, 0xae,
+	0xa1, 0x55, 0xe2, 0x64, 0x99, 0xbf, 0x56, 0x07, 0x53, 0xe4, 0xa3, 0x12,
+	0x2e, 0xd2, 0xee, 0xa7, 0x35, 0x5c, 0xb7, 0x40, 0x0e, 0x16, 0x44, 0xb5,
+	0x35, 0xca, 0x95, 0xa0, 0x05, 0x95, 0x80, 0x46, 0x0b, 0x9f, 0x82, 0x3d,
+	0x95, 0x9f, 0xa5, 0x9d, 0xde, 0x41, 0xdf, 0x28, 0x9e, 0xef, 0xdd, 0x48,
+	0x3a, 0x52, 0x86, 0x6f, 0x1c, 0x95, 0xef, 0xd5, 0x74, 0xea, 0x28, 0x3f,
+	0xa1, 0x6d, 0x71, 0xd7, 0xdf, 0xea, 0x5a, 0x9f, 0xde, 0x55, 0xfe, 0x96,
+	0x95, 0x65, 0x29, 0xea, 0x67, 0xb4, 0x4b, 0xe5, 0x7b, 0xdb, 0xc8, 0x63,
+	0x1e, 0xfc, 0xe1, 0xac, 0xf2, 0xb5, 0xff, 0x55, 0x50, 0x7d, 0x9b, 0x56,
+	0xd4, 0xd7, 0x77, 0xc7, 0x3e, 0xbb, 0xf6, 0xee, 0xd9, 0x7b, 0xca, 0xde,
+	0x0b, 0x6e, 0x1f, 0xef, 0x8e, 0xb8, 0x19, 0xde, 0xb1, 0x86, 0x19, 0xf6,
+	0xa1, 0xf9, 0x2a, 0x34, 0xb6, 0x72, 0x97, 0x57, 0x14, 0xf2, 0xd5, 0x57,
+	0xe5, 0x96, 0x59, 0x23, 0x97, 0xf7, 0x96, 0xc2, 0x10, 0x3e, 0xa2, 0xb7,
+	0x00, 0xff, 0x38, 0x7b, 0xb0, 0x22, 0xb7, 0x54, 0x89, 0xb7, 0x4f, 0x02,
+	0x7f, 0x43, 0x2e, 0x79, 0xd3, 0x13, 0xca, 0xe3, 0xbb, 0x84, 0xf6, 0x6a,
+	0xb1, 0x44, 0x9c, 0x5f, 0x10, 0xae, 0x4d, 0xb1, 0xf4, 0xb4, 0x5e, 0x9b,
+	0x23, 0xa5, 0x05, 0xe0, 0xe7, 0xcb, 0xa0, 0xfb, 0x30, 0x5c, 0x08, 0x8a,
+	0xa0, 0x9c, 0x3f, 0xc6, 0x6f, 0xd8, 0x28, 0xa5, 0x67, 0xf1, 0x7e, 0xa3,
+	0x14, 0x27, 0xc9, 0x73, 0xae, 0xe5, 0xe1, 0xb3, 0xe0, 0xa7, 0x9f, 0x41,
+	0xbf, 0x28, 0xeb, 0xe3, 0xef, 0x1f, 0xe0, 0x1d, 0xee, 0xb3, 0x58, 0xc4,
+	0x36, 0xda, 0x40, 0x1c, 0x9b, 0x6b, 0xc7, 0x35, 0xa3, 0xaf, 0x5e, 0xef,
+	0x97, 0x73, 0xbd, 0xd2, 0xdd, 0x05, 0x59, 0x8a, 0x2b, 0xc8, 0xb9, 0x12,
+	0xeb, 0x93, 0xfe, 0xfb, 0xd6, 0x19, 0x1d, 0xb1, 0xa1, 0xd9, 0xdc, 0x57,
+	0xb6, 0xe5, 0x9a, 0xd7, 0xd3, 0x20, 0x7d, 0xa8, 0x74, 0x7f, 0x01, 0x72,
+	0xc7, 0xf5, 0x37, 0xca, 0xa0, 0x96, 0x9d, 0xa4, 0x09, 0xd2, 0xc0, 0xcd,
+	0xca, 0xd0, 0xe6, 0xfb, 0x95, 0xa1, 0xcd, 0xa7, 0x41, 0x8b, 0xb8, 0xca,
+	0x8b, 0x8e, 0xa1, 0xcd, 0x2f, 0xe3, 0x8e, 0xab, 0xfc, 0xa2, 0x13, 0xf1,
+	0xf1, 0x00, 0xfc, 0xca, 0xbd, 0x25, 0xd7, 0x19, 0xad, 0x82, 0x7e, 0xcb,
+	0x71, 0x94, 0xcf, 0x13, 0xe7, 0x98, 0x3f, 0xc7, 0xd9, 0x69, 0xfb, 0x3f,
+	0x27, 0x63, 0xe5, 0x50, 0xdb, 0x5b, 0xf9, 0xd9, 0x7b, 0x71, 0x5f, 0xaf,
+	0xe5, 0x8c, 0xf2, 0xb3, 0xca, 0xc8, 0xab, 0x77, 0xe0, 0xde, 0x99, 0x3c,
+	0x22, 0x9d, 0x5e, 0x4c, 0x9e, 0x45, 0x5f, 0xdf, 0x75, 0xc6, 0xaa, 0x2f,
+	0xe3, 0xfa, 0x3e, 0xae, 0x57, 0x71, 0xbd, 0x82, 0x7e, 0x5f, 0x40, 0xf9,
+	0x7a, 0x99, 0xf7, 0x9a, 0x51, 0x5f, 0xd4, 0x68, 0xf5, 0x79, 0x67, 0xe4,
+	0xf4, 0x4b, 0xb8, 0x5c, 0x35, 0x56, 0x7d, 0xce, 0xc9, 0xcf, 0x86, 0x9b,
+	0x16, 0x7c, 0xca, 0xb0, 0xaf, 0x3a, 0xa6, 0xef, 0x0c, 0xe6, 0x00, 0x9a,
+	0x2e, 0xcf, 0x63, 0xec, 0xa7, 0x35, 0xcf, 0x0c, 0x42, 0x1f, 0xe4, 0x61,
+	0xaf, 0x8c, 0x68, 0x98, 0xb6, 0x03, 0x3e, 0xf8, 0xd3, 0x7d, 0xb8, 0xcf,
+	0x36, 0xca, 0x62, 0x82, 0xf6, 0xe5, 0x93, 0xba, 0x7e, 0xbe, 0x7c, 0xbd,
+	0xc6, 0xed, 0xf4, 0x2a, 0xfe, 0xa1, 0x4f, 0x18, 0xc9, 0x03, 0x23, 0x8d,
+	0x67, 0x4a, 0x94, 0x05, 0xd0, 0x4d, 0xa5, 0x09, 0xdc, 0x1b, 0xb5, 0x4c,
+	0x28, 0x4a, 0x24, 0x0f, 0xd8, 0x8e, 0x32, 0xa1, 0x5e, 0xee, 0x50, 0xd6,
+	0x50, 0xf6, 0x50, 0x96, 0x98, 0xf5, 0x18, 0x7d, 0x90, 0x32, 0xfc, 0x3a,
+	0xe8, 0x4d, 0xda, 0x25, 0xbe, 0xf1, 0x4d, 0xa6, 0x72, 0xca, 0xc8, 0xd3,
+	0xfd, 0x7a, 0x2d, 0xc6, 0x4a, 0x2a, 0x01, 0xc8, 0x51, 0x86, 0xeb, 0xe4,
+	0x41, 0xdc, 0xf3, 0x6a, 0x0c, 0x57, 0xfe, 0xe4, 0xfb, 0xf0, 0x9b, 0x6b,
+	0x33, 0x86, 0x7a, 0xb8, 0xca, 0xc3, 0xb8, 0xe3, 0x2a, 0xdf, 0xa8, 0x8c,
+	0x1c, 0xe1, 0x9a, 0x26, 0xed, 0x9a, 0x3e, 0x09, 0x3c, 0x70, 0x7e, 0x4a,
+	0xc7, 0x38, 0x94, 0xbf, 0x07, 0x78, 0xaf, 0x5a, 0x9f, 0x7a, 0xa3, 0x18,
+	0x1e, 0xc4, 0xd5, 0x4d, 0x7e, 0x6e, 0x31, 0xeb, 0xa5, 0x69, 0x77, 0x5d,
+	0x83, 0xe1, 0xc5, 0x04, 0xca, 0x62, 0x28, 0x6b, 0x33, 0x3a, 0x73, 0x09,
+	0x8f, 0x59, 0x8b, 0x47, 0xfe, 0x56, 0xf6, 0x37, 0xe8, 0x09, 0xb6, 0x2e,
+	0xe4, 0x35, 0xc6, 0xc5, 0x5c, 0x4e, 0xee, 0x57, 0xa3, 0x65, 0xfa, 0xc9,
+	0x94, 0xe1, 0x8c, 0x65, 0x70, 0x7e, 0xec, 0x17, 0xe5, 0x1a, 0x07, 0x81,
+	0xd4, 0xe2, 0x04, 0x4f, 0x62, 0xcd, 0xce, 0xc9, 0xa1, 0xf2, 0x47, 0xb4,
+	0xdf, 0xde, 0x78, 0xc2, 0xac, 0x87, 0xa8, 0xa8, 0x1e, 0xfa, 0x4e, 0xd0,
+	0xe6, 0xf9, 0x75, 0xfd, 0xde, 0x3d, 0xc1, 0xdf, 0x49, 0x1d, 0x4f, 0xaa,
+	0xc9, 0x7b, 0x63, 0xef, 0x14, 0x97, 0xc9, 0x3a, 0xda, 0x1d, 0x58, 0xb3,
+	0x4a, 0x3d, 0xde, 0x19, 0x47, 0xa0, 0xcc, 0x23, 0x3f, 0x1d, 0x01, 0x4f,
+	0x60, 0xf2, 0x9a, 0xf7, 0xe9, 0x83, 0xac, 0xc5, 0x4f, 0x3e, 0x6c, 0x62,
+	0x57, 0x4e, 0xc1, 0xa6, 0xdb, 0xbb, 0xd4, 0x07, 0x64, 0x65, 0x22, 0x2e,
+	0xa7, 0x4b, 0x2d, 0x32, 0x5b, 0x52, 0x6d, 0x31, 0x2b, 0x3b, 0x63, 0x92,
+	0xd4, 0xfa, 0x97, 0x76, 0xdf, 0xc0, 0x54, 0xcc, 0xd2, 0xdd, 0x8d, 0xe8,
+	0xff, 0x93, 0xd0, 0xb1, 0x15, 0xe8, 0xd8, 0x8d, 0xd0, 0xc1, 0x2b, 0x65,
+	0xc4, 0xfe, 0x86, 0xd5, 0x32, 0x82, 0x6d, 0xd2, 0xf0, 0xd6, 0x8f, 0xa0,
+	0x5d, 0x44, 0x7f, 0x71, 0x4d, 0x6b, 0x79, 0x29, 0x38, 0x7b, 0xab, 0x13,
+	0xce, 0xbe, 0xea, 0x4a, 0x1d, 0xd4, 0xe3, 0xb9, 0x62, 0x60, 0x3d, 0x5d,
+	0xa2, 0xed, 0x9a, 0x0e, 0x72, 0xc0, 0xc9, 0x3e, 0xd0, 0xdd, 0x53, 0x93,
+	0xf0, 0xef, 0x29, 0x97, 0x01, 0xf3, 0x19, 0xc0, 0x3c, 0x33, 0xe9, 0x44,
+	0xb6, 0x81, 0x30, 0x40, 0x33, 0x33, 0xd5, 0x2b, 0x0b, 0x73, 0xa4, 0x43,
+	0xc8, 0x80, 0x49, 0xac, 0x67, 0xb0, 0x0e, 0x76, 0x00, 0xc7, 0x87, 0xdc,
+	0x9e, 0xda, 0xa6, 0xdf, 0x19, 0x7d, 0xde, 0x2e, 0x0b, 0x95, 0x3b, 0x2d,
+	0x6c, 0xc7, 0xea, 0x60, 0x5b, 0xb7, 0x04, 0xdb, 0x3e, 0xc0, 0xb6, 0x7f,
+	0x4d, 0xd8, 0xd6, 0xd2, 0xc5, 0x1d, 0xb0, 0x69, 0xc8, 0x1f, 0x11, 0x5e,
+	0xdb, 0x2c, 0x3d, 0x94, 0xac, 0x1d, 0x4c, 0x9b, 0xe8, 0x87, 0x80, 0x87,
+	0x34, 0x86, 0xdf, 0xb3, 0x8f, 0x52, 0x96, 0xa1, 0x9c, 0xcf, 0x0f, 0xa1,
+	0x0e, 0x9e, 0x67, 0x13, 0x56, 0x0e, 0x7e, 0xc2, 0xc2, 0x42, 0x3b, 0x21,
+	0x0b, 0x5b, 0x79, 0xd0, 0xc9, 0xcd, 0x12, 0x86, 0x53, 0x80, 0x17, 0xef,
+	0xaa, 0xf5, 0x7d, 0xf2, 0xce, 0x7e, 0xaf, 0xb2, 0xfd, 0xb0, 0xef, 0x68,
+	0x2e, 0xeb, 0xad, 0x9e, 0x8f, 0xe8, 0x2b, 0xb2, 0xbb, 0x27, 0x9c, 0xec,
+	0xaa, 0x79, 0xd5, 0xd3, 0x1c, 0xe5, 0xad, 0x2b, 0x43, 0xa0, 0x93, 0xa1,
+	0x65, 0xb4, 0xa6, 0xdd, 0x13, 0x4b, 0xc7, 0xeb, 0xec, 0xfc, 0x0e, 0x1b,
+	0xbe, 0x09, 0xe2, 0xd0, 0x87, 0x94, 0x37, 0xff, 0xc5, 0xf8, 0xec, 0xf2,
+	0xe5, 0x06, 0xc6, 0x69, 0xcd, 0x33, 0x69, 0x93, 0xbf, 0x29, 0x93, 0x6a,
+	0xb4, 0x68, 0x7c, 0x9a, 0x76, 0x8c, 0x55, 0x6f, 0xc7, 0xbb, 0x32, 0x6c,
+	0xd6, 0xfc, 0x18, 0xd7, 0x9c, 0x3e, 0x4a, 0xe7, 0x03, 0xc3, 0x96, 0xbf,
+	0xd2, 0x93, 0x05, 0xb9, 0xd5, 0xce, 0xfd, 0xd2, 0x1a, 0x6b, 0xb7, 0x71,
+	0x69, 0xed, 0x86, 0xab, 0x2b, 0xe7, 0x28, 0xd2, 0xf1, 0x80, 0xab, 0x7d,
+	0x5e, 0xfa, 0xf0, 0x8d, 0x3e, 0xe5, 0x27, 0x6d, 0x25, 0x94, 0xcf, 0xf4,
+	0x78, 0xad, 0xf0, 0x0d, 0xbe, 0xb8, 0xca, 0xee, 0x4a, 0x59, 0xb9, 0x49,
+	0xff, 0x38, 0x1a, 0xa3, 0x60, 0xe5, 0x64, 0x01, 0xfd, 0x4f, 0x38, 0x43,
+	0xd5, 0xb5, 0xe4, 0x65, 0x24, 0x27, 0x39, 0x9f, 0x7b, 0xe5, 0x8e, 0x07,
+	0xc9, 0xa3, 0x25, 0x6d, 0x5f, 0x5f, 0xb3, 0xe7, 0x30, 0xf0, 0x47, 0xf8,
+	0x17, 0x36, 0xc3, 0x64, 0x80, 0xce, 0xcd, 0xca, 0xa8, 0x5d, 0xb7, 0xd1,
+	0xa5, 0xf5, 0xe7, 0x35, 0x0c, 0xdd, 0xc8, 0x58, 0xae, 0xb2, 0x30, 0x6b,
+	0x3b, 0x16, 0x76, 0xdd, 0x4a, 0x5b, 0x96, 0x73, 0xa0, 0x3d, 0xdb, 0x68,
+	0x6c, 0xc1, 0x32, 0xed, 0x4f, 0xca, 0x2e, 0xda, 0x9f, 0x57, 0x37, 0x4a,
+	0x33, 0xe7, 0x93, 0xb5, 0x65, 0xb4, 0x53, 0x57, 0xce, 0x6f, 0xa5, 0x5f,
+	0x49, 0x38, 0x09, 0xb7, 0xa1, 0xad, 0x94, 0x22, 0x6c, 0xa1, 0x0c, 0x07,
+	0xd7, 0xe9, 0x35, 0x50, 0xb4, 0x5d, 0xf7, 0x34, 0x34, 0x9a, 0x38, 0xf6,
+	0x5e, 0xf4, 0xcf, 0x31, 0xc9, 0x7f, 0xbc, 0xd3, 0xce, 0x5f, 0x4b, 0x96,
+	0xd5, 0xeb, 0x9e, 0x2b, 0x97, 0xf0, 0x37, 0xb4, 0x6c, 0x8d, 0x22, 0xfc,
+	0x45, 0x74, 0x51, 0x8f, 0x43, 0xd2, 0x04, 0x69, 0x21, 0xa2, 0xc5, 0x9d,
+	0x56, 0xdf, 0x44, 0xb4, 0xb7, 0x15, 0xb4, 0x77, 0x1f, 0xf0, 0x44, 0x19,
+	0xce, 0x78, 0xde, 0x16, 0x3c, 0x1f, 0xc7, 0x73, 0xc4, 0x27, 0x91, 0x0c,
+	0xa7, 0x4d, 0xb4, 0x52, 0x8e, 0x53, 0x86, 0xc7, 0x61, 0xf7, 0x50, 0xd6,
+	0x6f, 0xb7, 0xfc, 0x94, 0xb3, 0xbc, 0x44, 0x5d, 0xf0, 0xfb, 0xe8, 0xe7,
+	0x86, 0x46, 0x63, 0xa7, 0x17, 0x1b, 0x29, 0x5f, 0x37, 0xcb, 0x91, 0xba,
+	0xb2, 0xcb, 0xc9, 0xef, 0xfa, 0x39, 0x6f, 0xff, 0x7f, 0x30, 0xe7, 0xe4,
+	0x8a, 0x39, 0x7b, 0x76, 0xce, 0x55, 0xbc, 0x6f, 0xc5, 0xfb, 0x16, 0xea,
+	0x82, 0x54, 0x4d, 0xde, 0x58, 0x5c, 0x68, 0x7d, 0x56, 0x2f, 0x27, 0x22,
+	0x19, 0xc1, 0x79, 0x1d, 0xb5, 0x73, 0xf8, 0x7c, 0xdd, 0xbc, 0x8e, 0xbe,
+	0x89, 0x79, 0xb5, 0x2f, 0x9b, 0xd7, 0xde, 0xcb, 0xce, 0x6b, 0x2d, 0x1e,
+	0x27, 0x2f, 0x47, 0xf3, 0x8b, 0xcb, 0x81, 0x12, 0xe7, 0x38, 0x84, 0x39,
+	0x12, 0x86, 0x68, 0x8e, 0x19, 0x3b, 0x47, 0x51, 0x1d, 0x7b, 0x7e, 0x0a,
+	0xbf, 0xeb, 0xe7, 0x47, 0xdd, 0xff, 0xf7, 0xa0, 0xe9, 0x26, 0xf8, 0xc4,
+	0x4d, 0x56, 0xfe, 0x3f, 0x29, 0xb7, 0x96, 0xb9, 0xd6, 0xe9, 0xac, 0xc8,
+	0x7e, 0x75, 0xa8, 0xfc, 0x72, 0x23, 0xf7, 0x11, 0xf6, 0x06, 0x56, 0x8f,
+	0x41, 0x5f, 0xec, 0x83, 0xcd, 0x37, 0x54, 0x52, 0x7d, 0x31, 0x09, 0xc3,
+	0xdb, 0x82, 0x66, 0x8c, 0xbd, 0x49, 0xfb, 0xaa, 0xab, 0x63, 0xf8, 0xcf,
+	0x36, 0x8a, 0x4f, 0x7b, 0x83, 0xfa, 0x1c, 0xfa, 0xee, 0x24, 0x6d, 0xb0,
+	0x1c, 0xec, 0xe4, 0x6c, 0x32, 0xa6, 0x6d, 0x31, 0xea, 0xc4, 0x74, 0x32,
+	0x2b, 0x15, 0xc9, 0x9f, 0xcc, 0x26, 0xe1, 0xd8, 0x62, 0x0c, 0xd8, 0x6a,
+	0xb0, 0x21, 0x6f, 0x85, 0xac, 0xb9, 0xb5, 0x7a, 0x50, 0xdd, 0x02, 0x7b,
+	0xe7, 0x96, 0xd3, 0xef, 0x53, 0xb7, 0xc1, 0xd6, 0xb9, 0xed, 0xf4, 0x8d,
+	0xea, 0x10, 0x6c, 0x9b, 0x43, 0xb0, 0x73, 0x0e, 0x55, 0x69, 0x7b, 0xde,
+	0x0c, 0xba, 0x6b, 0x87, 0x1e, 0xe2, 0x5c, 0xb8, 0x26, 0xb4, 0x71, 0x38,
+	0x3f, 0xe2, 0xfe, 0x0b, 0x5c, 0x83, 0x20, 0xa5, 0x76, 0x34, 0x71, 0x5d,
+	0x5a, 0x97, 0x95, 0xbd, 0x96, 0xac, 0x8a, 0xf4, 0xd3, 0x06, 0x1b, 0x4f,
+	0x32, 0x7e, 0xe5, 0xe5, 0x69, 0x8b, 0x34, 0xe2, 0x01, 0xcf, 0xc4, 0x1f,
+	0x69, 0xab, 0x7e, 0xfe, 0x57, 0x36, 0x89, 0x9f, 0xc3, 0xf8, 0xf7, 0x42,
+	0xbe, 0xd6, 0xd3, 0x14, 0xef, 0x5e, 0x1d, 0x7f, 0x50, 0x06, 0x47, 0xf4,
+	0xb0, 0xf3, 0x35, 0xe4, 0xef, 0x65, 0xe9, 0xe9, 0x9e, 0x58, 0x26, 0x0c,
+	0x47, 0xfb, 0x64, 0x13, 0xe3, 0x01, 0xb9, 0x6a, 0x2d, 0x26, 0xa0, 0xfc,
+	0xfa, 0x98, 0x00, 0xfd, 0xac, 0x4f, 0x03, 0xbf, 0xd3, 0xb8, 0x44, 0x46,
+	0x18, 0x77, 0xa8, 0x46, 0x76, 0xf9, 0x57, 0xac, 0x5d, 0x1e, 0xc1, 0x91,
+	0x02, 0x1c, 0x46, 0x3e, 0xaf, 0xd6, 0x73, 0xcb, 0xf5, 0x77, 0x61, 0xc9,
+	0xa6, 0x4d, 0xc9, 0x81, 0xb2, 0xb6, 0x13, 0x21, 0x83, 0x89, 0x9b, 0x7a,
+	0x19, 0x9c, 0xb4, 0x76, 0x14, 0xea, 0x68, 0xf9, 0xb9, 0x5a, 0x76, 0x52,
+	0xee, 0x31, 0x6e, 0xff, 0x40, 0x40, 0x5a, 0x7f, 0x97, 0x64, 0x97, 0xe2,
+	0xf6, 0x02, 0x7a, 0x93, 0x20, 0x96, 0xd1, 0x7b, 0x7a, 0xde, 0x8c, 0xec,
+	0x93, 0x81, 0x04, 0x63, 0xa0, 0x8c, 0xf3, 0xf9, 0x85, 0x19, 0xe9, 0x66,
+	0x8c, 0x03, 0x16, 0x7c, 0xa3, 0x8c, 0x78, 0xa1, 0xec, 0x0d, 0x1c, 0x1d,
+	0x53, 0x36, 0xba, 0xf6, 0x62, 0x93, 0xb1, 0x5d, 0x1d, 0x1d, 0x17, 0x5e,
+	0x00, 0xf5, 0x2d, 0x68, 0xfb, 0x56, 0x69, 0xfd, 0x3b, 0xaf, 0xeb, 0xfc,
+	0x41, 0x53, 0x14, 0xdf, 0x5c, 0xf0, 0x62, 0xb6, 0x5e, 0x7d, 0xf9, 0xd7,
+	0x6c, 0xdc, 0xba, 0x1b, 0xb2, 0x3f, 0x2a, 0xfb, 0xde, 0x1a, 0x65, 0xb1,
+	0xf8, 0xea, 0xb2, 0xcd, 0x6b, 0x94, 0x99, 0x78, 0xe1, 0x50, 0x69, 0x27,
+	0xde, 0x4d, 0x68, 0xdf, 0x5d, 0xf4, 0x9e, 0x5b, 0xb7, 0x14, 0x96, 0xea,
+	0x6c, 0xb0, 0x7e, 0x19, 0x63, 0xc7, 0x26, 0x66, 0x9c, 0xd7, 0x31, 0xe3,
+	0x1e, 0x6f, 0x8f, 0xd2, 0x7b, 0x2c, 0xb7, 0x33, 0xfe, 0x78, 0x48, 0xe3,
+	0x85, 0x38, 0xf9, 0x02, 0x63, 0xc3, 0x05, 0xee, 0x0f, 0xa7, 0xd4, 0xe5,
+	0x68, 0xbb, 0x66, 0x9b, 0x98, 0x75, 0xa3, 0x5d, 0xdc, 0x22, 0x83, 0xb0,
+	0x15, 0x86, 0x4a, 0xad, 0xb2, 0x77, 0xea, 0xa3, 0xeb, 0xa8, 0xb7, 0xf6,
+	0x4d, 0x19, 0x7f, 0xf0, 0x10, 0xf8, 0x2a, 0x2b, 0x84, 0x31, 0x1d, 0x88,
+	0xd0, 0x26, 0x5e, 0x6d, 0x0b, 0xbf, 0x76, 0x7f, 0xf7, 0x5f, 0xa6, 0x3f,
+	0x07, 0xb6, 0xc3, 0x1b, 0xed, 0xaf, 0x59, 0x06, 0xa7, 0x22, 0x5c, 0xa9,
+	0x1f, 0xb1, 0x5d, 0xec, 0x32, 0xed, 0xb4, 0x5d, 0x22, 0x4f, 0x2d, 0xc9,
+	0xe2, 0x9d, 0xb0, 0x99, 0x24, 0xcc, 0xf5, 0x49, 0x7b, 0x4c, 0x74, 0x8c,
+	0x27, 0x30, 0xb2, 0xb9, 0x8b, 0x7b, 0x3e, 0xa0, 0x7f, 0x63, 0xab, 0x98,
+	0x78, 0x6a, 0x64, 0xa7, 0xac, 0x45, 0xbb, 0xd7, 0x5b, 0xda, 0xe5, 0xbe,
+	0xee, 0x3e, 0xca, 0x5c, 0xac, 0x89, 0xa1, 0xe3, 0xbd, 0x25, 0x49, 0x45,
+	0x74, 0xbc, 0x20, 0xd9, 0x65, 0x74, 0xbc, 0x20, 0x83, 0x9a, 0x8e, 0x1b,
+	0x97, 0xd1, 0x71, 0xbb, 0xa5, 0xe3, 0x8f, 0xc6, 0x0d, 0x5d, 0x28, 0xad,
+	0xa7, 0x48, 0xa7, 0x86, 0x8e, 0x1d, 0x4d, 0xc7, 0x0b, 0xb8, 0xbb, 0xfe,
+	0xc7, 0x6c, 0x9d, 0x98, 0x2d, 0xe3, 0xef, 0xa8, 0x8c, 0x72, 0x71, 0x2a,
+	0x6e, 0xf4, 0xd2, 0x20, 0xe8, 0x28, 0x2a, 0xff, 0x4d, 0x4b, 0x9f, 0xf5,
+	0x65, 0x26, 0x3e, 0x32, 0x54, 0x3a, 0xb2, 0x82, 0x3e, 0x07, 0x41, 0x9f,
+	0x51, 0x9d, 0xd7, 0xa2, 0xcf, 0x66, 0xbb, 0x9f, 0x91, 0xd4, 0x7b, 0xff,
+	0xd9, 0x84, 0xa1, 0xd5, 0x5b, 0xf4, 0xdc, 0x39, 0xef, 0x0b, 0x6f, 0x80,
+	0x56, 0xcd, 0xda, 0x5c, 0xac, 0xf9, 0xdb, 0x8c, 0x45, 0xa5, 0x4c, 0x6c,
+	0x9b, 0x71, 0xd2, 0xcb, 0xd9, 0x8e, 0x2f, 0xd5, 0xf9, 0x15, 0x1b, 0xa4,
+	0xc0, 0xbc, 0x87, 0xea, 0x46, 0xc6, 0xa2, 0x47, 0xdc, 0x4c, 0x9f, 0x64,
+	0x2b, 0xed, 0xa9, 0x62, 0x89, 0x7e, 0xd1, 0xab, 0x36, 0x37, 0x02, 0xcf,
+	0x95, 0x16, 0x79, 0xb4, 0x44, 0xda, 0x3a, 0x62, 0x70, 0xb1, 0x26, 0xad,
+	0x73, 0xad, 0xd9, 0x4f, 0xbd, 0x0e, 0xe8, 0x83, 0xee, 0xa1, 0xcd, 0xae,
+	0xe5, 0x3e, 0xde, 0xb5, 0xa7, 0x72, 0xa5, 0xa8, 0x5f, 0xee, 0x3f, 0x70,
+	0x4f, 0xb8, 0x3d, 0xd5, 0x51, 0xf1, 0x6d, 0x9c, 0x79, 0x23, 0x9e, 0xfb,
+	0xa4, 0xa3, 0xa2, 0xe4, 0x03, 0x53, 0x2d, 0x72, 0x7b, 0xc9, 0x95, 0x0f,
+	0xa1, 0xfd, 0x07, 0x4b, 0x1e, 0xfc, 0xfb, 0xff, 0x1d, 0xa7, 0x9d, 0x79,
+	0xa8, 0xc4, 0x7d, 0x50, 0x47, 0xdb, 0x2a, 0xcb, 0xf7, 0x86, 0x63, 0xd2,
+	0xd1, 0x55, 0x84, 0xe7, 0x23, 0xee, 0x7e, 0xc0, 0xd1, 0x94, 0xc9, 0xc8,
+	0x77, 0xfa, 0x36, 0xa1, 0x2c, 0xca, 0xf1, 0x18, 0x76, 0x4c, 0xfc, 0xb8,
+	0x5f, 0xde, 0x59, 0xcd, 0xc8, 0x0d, 0x55, 0xb3, 0x77, 0x5b, 0xdb, 0x9b,
+	0x4d, 0x7b, 0xf3, 0xd0, 0x67, 0x59, 0x2f, 0x0c, 0x2f, 0xfa, 0xa0, 0xa2,
+	0xe3, 0xae, 0xc4, 0xbb, 0xd2, 0xc9, 0x79, 0x31, 0xcf, 0x97, 0x2a, 0xff,
+	0x1c, 0x8e, 0x24, 0x5c, 0xf9, 0x8e, 0xcf, 0x39, 0xf6, 0xcb, 0xf5, 0x95,
+	0xfa, 0xb1, 0xb9, 0x3f, 0x1b, 0x5b, 0xc7, 0xfd, 0x90, 0x5c, 0xf5, 0x9f,
+	0xe3, 0x8c, 0xdb, 0xd3, 0x87, 0xe9, 0xf8, 0x31, 0xee, 0x87, 0xbb, 0xb8,
+	0x83, 0x0e, 0x13, 0xb0, 0x21, 0xae, 0x01, 0x8c, 0xd7, 0x30, 0x96, 0xc6,
+	0x18, 0x1a, 0x9f, 0xbf, 0x8c, 0x71, 0xd9, 0xf6, 0x93, 0xd6, 0xfe, 0x3e,
+	0xb2, 0xc4, 0x8b, 0x6b, 0xeb, 0xb1, 0x8d, 0x23, 0xf1, 0x8c, 0x38, 0xf1,
+	0x9f, 0x48, 0xca, 0x3a, 0xbf, 0x7e, 0x7c, 0xee, 0x47, 0xc3, 0xa2, 0xec,
+	0x13, 0x77, 0xdf, 0xee, 0x7e, 0x19, 0xc4, 0xfc, 0x86, 0x56, 0xcd, 0xef,
+	0x1e, 0x61, 0xbc, 0xf6, 0x52, 0x89, 0x73, 0xa8, 0xcd, 0x4b, 0xfd, 0xb6,
+	0x99, 0x57, 0xbc, 0x6b, 0xe5, 0x7c, 0x74, 0x7b, 0x75, 0x0a, 0xb0, 0x7c,
+	0x49, 0xe7, 0x42, 0x84, 0xe1, 0x5b, 0xbb, 0x2e, 0x85, 0xa9, 0x2b, 0xd2,
+	0xdd, 0xf3, 0xb5, 0x7d, 0xa4, 0x91, 0x58, 0x26, 0xab, 0xf5, 0x23, 0x9e,
+	0x53, 0xf9, 0xca, 0x7e, 0xac, 0xa3, 0xb8, 0xf9, 0x5e, 0x57, 0xf3, 0x5d,
+	0xde, 0xdf, 0x6f, 0xf7, 0xca, 0x22, 0x9f, 0x2c, 0x0c, 0x95, 0xbf, 0x52,
+	0x0e, 0x51, 0xff, 0x61, 0xee, 0xf2, 0x98, 0xdd, 0x3f, 0xe8, 0x66, 0x7c,
+	0x0c, 0xb4, 0x18, 0x07, 0xdd, 0xf9, 0xf8, 0xdd, 0x82, 0xfb, 0x1e, 0xd8,
+	0x3f, 0x01, 0xec, 0x23, 0x49, 0x28, 0x23, 0x6b, 0xc0, 0x1b, 0x5d, 0x05,
+	0xa5, 0xc8, 0xeb, 0x5e, 0x6a, 0xbc, 0x92, 0x48, 0x4d, 0x56, 0x9e, 0x60,
+	0x7b, 0xd4, 0x5d, 0x2b, 0x36, 0x68, 0xf2, 0x6c, 0xbe, 0x58, 0xe5, 0x18,
+	0xa4, 0xfb, 0x37, 0x32, 0x86, 0x6b, 0xfb, 0x66, 0x9f, 0x11, 0x5e, 0x5c,
+	0xba, 0xf8, 0xf8, 0xb7, 0xdf, 0xfa, 0x3a, 0x9c, 0xdf, 0x13, 0x16, 0xee,
+	0x95, 0xe3, 0x3e, 0xaf, 0xed, 0xa1, 0xc7, 0xab, 0xb4, 0x41, 0xb9, 0x8f,
+	0x94, 0x7e, 0x64, 0x5a, 0x08, 0x47, 0x18, 0x3e, 0x1b, 0x18, 0x5b, 0xe0,
+	0x8b, 0x55, 0xee, 0x99, 0x84, 0xe1, 0xdf, 0xd2, 0xce, 0x3e, 0x58, 0xc6,
+	0x78, 0x11, 0x0e, 0x76, 0x16, 0x5c, 0xc8, 0xd9, 0x89, 0x3e, 0xe2, 0x57,
+	0xe0, 0xf1, 0x76, 0x79, 0x07, 0x24, 0x9e, 0xfa, 0x78, 0xa5, 0x25, 0x75,
+	0x67, 0xc5, 0x03, 0x9e, 0x39, 0xef, 0x44, 0x6a, 0xcc, 0xce, 0x39, 0x5f,
+	0x21, 0x7e, 0x5f, 0x6b, 0xbf, 0xf3, 0xf9, 0x65, 0xfe, 0x17, 0x61, 0xaa,
+	0xc1, 0x42, 0xd8, 0x52, 0x16, 0x37, 0x61, 0xf8, 0xf7, 0x01, 0xc7, 0xdc,
+	0x0f, 0x1f, 0x46, 0x26, 0x30, 0x6e, 0x61, 0x8b, 0x22, 0x1e, 0xe2, 0xa9,
+	0x3b, 0x30, 0xf6, 0xc7, 0x31, 0xf6, 0xed, 0x15, 0x8e, 0x07, 0xd9, 0x83,
+	0xb9, 0x4f, 0x54, 0x23, 0x78, 0xd7, 0x1a, 0x3b, 0x5a, 0xf3, 0x6e, 0x6b,
+	0x33, 0x46, 0xcf, 0x1a, 0x91, 0x6d, 0x0a, 0xbe, 0x63, 0xae, 0xba, 0xb0,
+	0xd9, 0x95, 0x9f, 0x81, 0x1c, 0x0f, 0xe5, 0x51, 0xc8, 0xc7, 0x05, 0x4d,
+	0x37, 0xb9, 0xed, 0xfc, 0x3f, 0x26, 0x4f, 0xad, 0x63, 0xbc, 0x7a, 0xc0,
+	0xa7, 0x2d, 0xbc, 0x18, 0x2e, 0xf8, 0x94, 0xf7, 0x1b, 0x64, 0xda, 0x2b,
+	0x74, 0x43, 0xf7, 0xa0, 0x6c, 0x23, 0xfd, 0xf7, 0x54, 0x2e, 0x96, 0x4e,
+	0x8d, 0x0b, 0x73, 0xbe, 0x98, 0x13, 0xc1, 0xbc, 0x26, 0xca, 0x06, 0x17,
+	0x32, 0x94, 0x6b, 0x68, 0xc6, 0x1b, 0xaf, 0xd4, 0xea, 0x1e, 0x16, 0xee,
+	0x4d, 0xa6, 0x93, 0x87, 0xb4, 0xbd, 0x23, 0x32, 0x5a, 0x62, 0xdd, 0xdd,
+	0xb0, 0x76, 0xfc, 0xba, 0xfa, 0x3a, 0x57, 0x0d, 0x7c, 0x1e, 0xc5, 0xc5,
+	0xe2, 0xcc, 0x29, 0x79, 0x39, 0xd6, 0x27, 0x2f, 0xd3, 0x8e, 0x1d, 0x00,
+	0x6d, 0x7b, 0xbe, 0xce, 0x2b, 0xd1, 0xe5, 0xb9, 0x40, 0x16, 0x73, 0xfd,
+	0x3d, 0xb4, 0xdb, 0x0b, 0x4a, 0xf3, 0x84, 0x28, 0xb4, 0x8d, 0xe7, 0x2b,
+	0x32, 0x98, 0x2f, 0xd9, 0xd8, 0xd1, 0x30, 0xe7, 0xbc, 0xa1, 0x6e, 0xee,
+	0x1b, 0xc5, 0x05, 0x4c, 0x83, 0xb1, 0x94, 0xd3, 0xe0, 0x7f, 0xaa, 0xc5,
+	0xd8, 0x10, 0xd0, 0x23, 0xad, 0xf7, 0xb7, 0x71, 0x6f, 0x56, 0xc1, 0x27,
+	0x57, 0x6d, 0x1f, 0xbe, 0x56, 0x65, 0xfe, 0x32, 0x09, 0xbd, 0x6a, 0x65,
+	0x65, 0x7c, 0xb0, 0x63, 0x89, 0xbe, 0x39, 0xbe, 0xb4, 0xc5, 0xfc, 0xd4,
+	0xe0, 0x40, 0x45, 0x54, 0x2c, 0xe3, 0xc5, 0x07, 0x2a, 0xcb, 0x69, 0xfe,
+	0x8b, 0xd5, 0xcf, 0x5a, 0xdb, 0xb2, 0x3e, 0x46, 0x5b, 0xff, 0x8e, 0x7c,
+	0xb7, 0x6c, 0xff, 0x23, 0x05, 0xbe, 0xb2, 0xfb, 0xc6, 0x5c, 0x93, 0xec,
+	0x5b, 0x19, 0xd8, 0x9c, 0xd6, 0x3e, 0x1f, 0x73, 0x3b, 0xe2, 0x36, 0xbf,
+	0xce, 0xe0, 0x3a, 0x5b, 0x71, 0x64, 0x02, 0xf2, 0xe1, 0xb0, 0xfc, 0x53,
+	0x98, 0x4d, 0x98, 0xf7, 0x66, 0x7d, 0x59, 0x9f, 0x7b, 0x1b, 0xcd, 0x52,
+	0x3c, 0xed, 0x4a, 0xe1, 0x34, 0xf7, 0xd4, 0xce, 0xdd, 0x51, 0xcb, 0x0f,
+	0xa1, 0x1c, 0xe0, 0xbe, 0xb0, 0x23, 0x45, 0xf8, 0xc8, 0x83, 0xdc, 0xef,
+	0xef, 0xfd, 0x47, 0xe6, 0xea, 0xc4, 0xb9, 0x4e, 0xa6, 0x6d, 0x0b, 0xda,
+	0x36, 0xda, 0xb6, 0xc1, 0xc7, 0xdf, 0x5c, 0xdb, 0x8d, 0x68, 0x1b, 0x8f,
+	0xc6, 0x7d, 0x83, 0x6d, 0x35, 0x3e, 0xaf, 0x1d, 0x28, 0x95, 0x17, 0x5d,
+	0xdf, 0x4f, 0x8e, 0x49, 0xd6, 0x19, 0xed, 0xd3, 0xf3, 0xb9, 0x76, 0xa0,
+	0x02, 0x38, 0x12, 0x61, 0x58, 0x0c, 0x22, 0xbd, 0xce, 0x7f, 0x27, 0xa1,
+	0xde, 0x59, 0xc6, 0x7d, 0x50, 0xfa, 0x27, 0x8c, 0xba, 0x7a, 0xcc, 0xc1,
+	0x93, 0x22, 0xf7, 0x3b, 0x13, 0x9b, 0x70, 0x57, 0x1d, 0xc4, 0x49, 0xde,
+	0x67, 0xfc, 0x78, 0x93, 0x2d, 0x8f, 0xb1, 0x3c, 0xed, 0x42, 0x96, 0x98,
+	0xf2, 0x98, 0x2d, 0x07, 0x4c, 0x41, 0x31, 0x05, 0x6e, 0xb3, 0xe5, 0x7c,
+	0x56, 0xba, 0xdc, 0x3c, 0x1b, 0x1e, 0x1a, 0x11, 0xc6, 0x89, 0x72, 0xd7,
+	0x37, 0xc8, 0x4e, 0xac, 0x0f, 0x7d, 0x50, 0x47, 0x9a, 0x01, 0xc7, 0xc5,
+	0xe0, 0xc7, 0x61, 0xab, 0x87, 0xf2, 0x9d, 0xc0, 0xd0, 0xff, 0x8c, 0x74,
+	0x65, 0x95, 0xc3, 0x5c, 0x83, 0x50, 0x86, 0x82, 0x5d, 0xc9, 0xbd, 0xf8,
+	0x3d, 0xda, 0x9b, 0x92, 0x99, 0x7e, 0xd0, 0x63, 0x2f, 0x79, 0x63, 0x27,
+	0x6c, 0x28, 0xfc, 0xee, 0x6a, 0x91, 0x45, 0xaf, 0xe0, 0xad, 0x83, 0xff,
+	0x37, 0x88, 0x59, 0xcd, 0x96, 0x7c, 0xef, 0x36, 0x08, 0xb9, 0xac, 0xd7,
+	0x85, 0x7b, 0xfd, 0x7c, 0xbf, 0x8e, 0xf9, 0x9e, 0x6b, 0x96, 0x66, 0x96,
+	0xd7, 0xd7, 0x6d, 0x94, 0xfd, 0xde, 0x6e, 0x2f, 0xbe, 0xac, 0xee, 0x25,
+	0xd4, 0x65, 0x99, 0xef, 0x31, 0x17, 0x68, 0xa6, 0x42, 0x3a, 0x33, 0xb0,
+	0x76, 0x74, 0x85, 0xe1, 0xf5, 0x01, 0xc7, 0x0d, 0xc3, 0x1b, 0x82, 0x1e,
+	0xef, 0x19, 0x79, 0x2e, 0x34, 0x36, 0x5a, 0x44, 0x3b, 0xcf, 0x5a, 0x79,
+	0x1d, 0x86, 0x2f, 0x07, 0xdd, 0xf2, 0xb9, 0x6a, 0xfa, 0x1c, 0x7d, 0xf8,
+	0xf3, 0x78, 0x3e, 0x1f, 0x98, 0xfc, 0xa5, 0x3f, 0x43, 0xbb, 0x84, 0xea,
+	0x05, 0x0d, 0xfb, 0xf2, 0x59, 0xed, 0xf3, 0x13, 0x7f, 0x66, 0xcf, 0xa0,
+	0x06, 0x03, 0x26, 0xec, 0xe7, 0x36, 0x7b, 0xcc, 0x69, 0xd4, 0xf4, 0x5b,
+	0xff, 0x4e, 0xe1, 0x1d, 0xcb, 0xc2, 0xf0, 0x8a, 0xbe, 0x96, 0xf5, 0xd0,
+	0xd7, 0x93, 0xdc, 0x0b, 0x7c, 0x9f, 0xe6, 0x3f, 0x91, 0x03, 0xdc, 0xf7,
+	0x02, 0x0e, 0x95, 0xf2, 0x8f, 0x75, 0xa8, 0x74, 0x41, 0xe4, 0x2d, 0x58,
+	0x7f, 0xae, 0x31, 0x18, 0xa4, 0x15, 0xb0, 0xef, 0xfa, 0xa5, 0x66, 0x13,
+	0x9b, 0xa2, 0x6f, 0x9e, 0xdd, 0x0c, 0xdf, 0x59, 0xdb, 0x33, 0xdc, 0x57,
+	0x1f, 0x6b, 0x0d, 0xc3, 0xf7, 0x06, 0xd1, 0x9a, 0xd9, 0xd8, 0x37, 0x74,
+	0x7c, 0xbe, 0x57, 0xd6, 0x1b, 0xbb, 0x90, 0xb9, 0x8d, 0x29, 0xbd, 0x4f,
+	0xa0, 0xda, 0xa0, 0x43, 0x76, 0xfd, 0x00, 0x38, 0xe5, 0x18, 0xcc, 0x73,
+	0x8c, 0x60, 0xaa, 0xb5, 0xcf, 0xf7, 0xae, 0xb3, 0x36, 0xac, 0x0b, 0x5c,
+	0xfa, 0x5e, 0x87, 0xfa, 0x5e, 0x68, 0x74, 0x6b, 0x44, 0xc3, 0xff, 0x10,
+	0x3e, 0x98, 0x30, 0xcf, 0xb9, 0x5d, 0xec, 0x63, 0xa7, 0x8c, 0xef, 0xc2,
+	0xb3, 0x7b, 0x1d, 0xee, 0x03, 0x57, 0xc6, 0xe4, 0xaa, 0xe4, 0x80, 0xda,
+	0xe5, 0x3d, 0x28, 0x3d, 0x56, 0xc6, 0x7d, 0x09, 0xfa, 0xbe, 0x00, 0xff,
+	0xbe, 0x49, 0x1e, 0x04, 0x4d, 0xab, 0xbe, 0x74, 0x6a, 0x5e, 0xa5, 0xbb,
+	0xa7, 0x55, 0x3a, 0x18, 0x51, 0x13, 0x9c, 0x57, 0x3f, 0x71, 0x31, 0x4d,
+	0xfc, 0x96, 0x81, 0xff, 0x32, 0x70, 0x7c, 0xd9, 0x3d, 0xe3, 0xc0, 0xea,
+	0x16, 0xa3, 0xdf, 0x0a, 0x9a, 0x36, 0x8d, 0x9d, 0xff, 0xa7, 0x41, 0xb4,
+	0x86, 0x3d, 0x5e, 0x03, 0x73, 0x71, 0xd6, 0x5c, 0xa3, 0x3c, 0xd7, 0x08,
+	0x8a, 0xa1, 0x00, 0xba, 0x4f, 0xa7, 0xc6, 0xd4, 0x62, 0xb8, 0x79, 0x4f,
+	0x67, 0xf7, 0x63, 0xba, 0x9f, 0x74, 0x90, 0x55, 0x4f, 0x02, 0x9e, 0x9d,
+	0xd2, 0xb4, 0x87, 0x78, 0x26, 0xac, 0x71, 0xc6, 0xa7, 0xbc, 0x3b, 0x50,
+	0x77, 0x44, 0xe9, 0x3d, 0x6d, 0x5b, 0x87, 0x30, 0xbf, 0x1b, 0xf8, 0xa5,
+	0x1e, 0x62, 0xcc, 0xed, 0xb5, 0x74, 0x21, 0x64, 0xd2, 0x49, 0xca, 0xc0,
+	0x98, 0x89, 0x25, 0x57, 0xef, 0xe4, 0xfa, 0xd3, 0x13, 0x88, 0xbb, 0x90,
+	0x51, 0x13, 0xe0, 0xe2, 0xa3, 0x27, 0xc5, 0x6d, 0xf0, 0xbb, 0xd7, 0x1b,
+	0x3f, 0x8c, 0x3e, 0x19, 0xc7, 0x6e, 0x90, 0xe2, 0xaa, 0xf8, 0xcd, 0x24,
+	0xe0, 0x6f, 0x96, 0xf1, 0x93, 0x5c, 0x0b, 0x17, 0x32, 0x87, 0x63, 0x8b,
+	0x9b, 0xeb, 0x0d, 0xc3, 0x51, 0x96, 0x9f, 0x26, 0xff, 0x4a, 0x9a, 0xef,
+	0x0a, 0xa7, 0xe7, 0x37, 0xab, 0x65, 0xb2, 0xb6, 0xc5, 0xc2, 0xa1, 0xf1,
+	0x24, 0x93, 0x5a, 0x8e, 0x50, 0xdf, 0xcc, 0xd4, 0xc1, 0x13, 0x7c, 0x7c,
+	0xc2, 0x6f, 0x7c, 0x13, 0xf0, 0xfc, 0x0f, 0xc0, 0xd3, 0x62, 0xe1, 0x69,
+	0x5c, 0x01, 0x4f, 0x4b, 0x04, 0x0f, 0xe4, 0x1c, 0xe5, 0x6a, 0xfc, 0xda,
+	0x6c, 0x45, 0x9c, 0xa2, 0x2f, 0xed, 0x4a, 0xfb, 0x43, 0xd4, 0x37, 0x8d,
+	0xde, 0x68, 0x9f, 0x27, 0xa3, 0x5a, 0xd7, 0xb8, 0xd7, 0x76, 0x56, 0xe6,
+	0x61, 0xbd, 0x8a, 0x93, 0xf3, 0x09, 0xfb, 0x5a, 0x76, 0xd5, 0x3d, 0x90,
+	0xff, 0x0b, 0x69, 0xd7, 0xda, 0x12, 0x93, 0x01, 0xfd, 0xa0, 0x84, 0xce,
+	0x15, 0xa8, 0xc1, 0xf4, 0x12, 0x60, 0x82, 0x3c, 0x3e, 0xd9, 0xe3, 0x0d,
+	0xcb, 0x56, 0xed, 0xeb, 0x59, 0x5c, 0x63, 0x6e, 0xf1, 0xba, 0xb9, 0x41,
+	0xff, 0xa9, 0x68, 0x6e, 0x90, 0x89, 0xa8, 0x37, 0x29, 0x7f, 0x64, 0x71,
+	0xb1, 0x11, 0x73, 0x8a, 0xd7, 0xcd, 0xa7, 0x33, 0x79, 0x3b, 0xcb, 0xcc,
+	0x7c, 0xba, 0x8a, 0x7e, 0xdc, 0xe2, 0x77, 0x2d, 0x9f, 0xc4, 0xd8, 0x3d,
+	0xd3, 0x12, 0xca, 0x44, 0x80, 0x35, 0xea, 0xa6, 0x7f, 0x12, 0xb7, 0xb9,
+	0xd7, 0x0a, 0xcf, 0x1b, 0x2c, 0x7f, 0x79, 0x52, 0xd4, 0xfe, 0xe0, 0xdf,
+	0x59, 0x3e, 0x75, 0x6d, 0x9e, 0x1c, 0x7f, 0x1f, 0x5c, 0x6f, 0xf3, 0x05,
+	0x0a, 0x59, 0x79, 0x65, 0x3d, 0xed, 0x92, 0x06, 0xff, 0x57, 0x56, 0x94,
+	0xc5, 0x51, 0x76, 0x6a, 0xbd, 0x95, 0x0b, 0x28, 0xbb, 0x07, 0x7e, 0x1f,
+	0xf3, 0x3e, 0xf8, 0x8e, 0x32, 0xb8, 0x1e, 0x27, 0x3d, 0x60, 0x45, 0xf2,
+	0x3c, 0xe5, 0x22, 0x6d, 0x4a, 0xcc, 0x51, 0x6d, 0x8f, 0xe2, 0xf2, 0xf8,
+	0xbd, 0x96, 0xed, 0x4f, 0x7c, 0x13, 0xd7, 0xf2, 0x8d, 0x09, 0xf0, 0xfd,
+	0xe1, 0xc0, 0x71, 0x67, 0x98, 0x57, 0xa0, 0x69, 0xb8, 0xbe, 0xef, 0x1b,
+	0x18, 0x26, 0xb4, 0xb4, 0x4c, 0x7a, 0x21, 0x4f, 0x3b, 0xd2, 0x44, 0x5d,
+	0x7c, 0xd2, 0xd3, 0x39, 0xee, 0x39, 0xad, 0x97, 0xeb, 0xd7, 0xb1, 0x09,
+	0xba, 0x26, 0x61, 0x78, 0xd4, 0x33, 0xfb, 0xe7, 0xb5, 0xfe, 0x46, 0xd0,
+	0x1f, 0xed, 0x34, 0xf8, 0xfd, 0x3e, 0xa3, 0x43, 0x94, 0x5f, 0x8e, 0xab,
+	0xae, 0xd6, 0x7e, 0x6b, 0x5c, 0xe7, 0x37, 0x2d, 0xd5, 0x1d, 0xb3, 0x63,
+	0x93, 0x6e, 0xcd, 0x7e, 0x42, 0x6d, 0x7c, 0x71, 0xd4, 0x2e, 0x01, 0x95,
+	0x35, 0xca, 0x44, 0x1f, 0x69, 0x94, 0x73, 0xd7, 0x36, 0xd4, 0xb5, 0xb4,
+	0x23, 0x0c, 0x7d, 0xd2, 0x76, 0x72, 0xaf, 0xcd, 0x97, 0x1a, 0x8d, 0xcf,
+	0x92, 0x90, 0x2d, 0x0d, 0x3a, 0x2f, 0x01, 0x65, 0x95, 0x48, 0x97, 0xb9,
+	0x32, 0xd3, 0xfb, 0x7f, 0xc2, 0xec, 0x41, 0xd6, 0x5d, 0x33, 0x0f, 0x20,
+	0x39, 0x2d, 0x1a, 0x4f, 0x5f, 0xab, 0xe1, 0xc9, 0xce, 0x2d, 0xb1, 0x72,
+	0x6e, 0x70, 0x6a, 0xfd, 0x7b, 0x20, 0x3b, 0xb9, 0x4e, 0x26, 0xe7, 0xfc,
+	0x9c, 0x38, 0x6e, 0xae, 0x7b, 0xad, 0xb9, 0x4d, 0x46, 0x78, 0xe5, 0xdc,
+	0x40, 0xab, 0xd1, 0xbc, 0x48, 0xdb, 0x09, 0xbd, 0xef, 0xa4, 0x14, 0x61,
+	0xd9, 0xb8, 0x02, 0xb7, 0x11, 0xdd, 0x19, 0x9a, 0xfb, 0xa2, 0xa6, 0xb9,
+	0x16, 0x4b, 0x73, 0xa8, 0xeb, 0x71, 0x1f, 0xfd, 0xbe, 0x96, 0x1a, 0xcd,
+	0x6d, 0xb0, 0x34, 0xa7, 0x5a, 0xcc, 0x1e, 0x7b, 0xb9, 0xc5, 0xec, 0x71,
+	0x25, 0x57, 0x3c, 0xbf, 0x93, 0xcf, 0xf0, 0xc5, 0xa2, 0xe7, 0x7a, 0x58,
+	0xcf, 0x03, 0xd6, 0x7a, 0x59, 0xd3, 0x64, 0xe3, 0x78, 0xdc, 0x8f, 0xa7,
+	0xdf, 0xe7, 0xca, 0xa3, 0xb0, 0x83, 0x8a, 0x95, 0x1f, 0x84, 0xf3, 0xf0,
+	0xfd, 0x26, 0x96, 0x74, 0xef, 0x4c, 0x0b, 0xf9, 0x6d, 0x1a, 0xbf, 0x8e,
+	0xd4, 0xf9, 0x3c, 0x98, 0x2f, 0xca, 0xfe, 0x19, 0xeb, 0x01, 0xb9, 0xbc,
+	0x54, 0x97, 0x31, 0x10, 0xe3, 0xe3, 0x9c, 0xab, 0xb6, 0xdb, 0xfd, 0x49,
+	0xca, 0xf9, 0xbb, 0xe1, 0x13, 0xdd, 0x03, 0x3d, 0x49, 0xfa, 0xee, 0xd8,
+	0x60, 0xf2, 0x89, 0x13, 0xd0, 0x63, 0x3f, 0x6f, 0x73, 0xab, 0x6e, 0xbf,
+	0x7d, 0xed, 0x5c, 0x62, 0xd0, 0xbe, 0x43, 0x9a, 0x79, 0xdb, 0x06, 0x13,
+	0x83, 0xde, 0xba, 0x81, 0x7c, 0xa6, 0x76, 0xed, 0xda, 0xa8, 0xf9, 0xc2,
+	0x89, 0x9e, 0xab, 0x2b, 0x9e, 0xa3, 0x76, 0x7f, 0xb3, 0x71, 0x79, 0xbb,
+	0xa8, 0xfc, 0xce, 0x4d, 0xcb, 0xcb, 0xff, 0xa3, 0xb7, 0xbc, 0x7d, 0xe3,
+	0xe6, 0xe5, 0xcf, 0x7b, 0x57, 0x3c, 0x7f, 0x64, 0xc5, 0xf3, 0xef, 0xad,
+	0x78, 0xde, 0xd1, 0xba, 0xfc, 0xf9, 0x43, 0x2b, 0x9e, 0x4f, 0xb5, 0xae,
+	0x0d, 0xef, 0x42, 0xeb, 0x72, 0xb8, 0xee, 0xd6, 0xfb, 0x07, 0xd3, 0x55,
+	0x57, 0xf6, 0x96, 0xf0, 0xde, 0x79, 0xdf, 0x16, 0xa3, 0xd7, 0xea, 0xdf,
+	0x33, 0x5e, 0xb7, 0x7b, 0xcb, 0xf2, 0xfe, 0x6a, 0xed, 0xf6, 0xd5, 0xda,
+	0x05, 0xb5, 0x76, 0x46, 0xb6, 0xcd, 0x54, 0xf9, 0x8e, 0xe5, 0x51, 0xbf,
+	0xa6, 0xed, 0x44, 0xd9, 0xd7, 0x39, 0xb7, 0xc3, 0x3a, 0xe7, 0x36, 0x05,
+	0x3e, 0xbc, 0x5b, 0xc7, 0xa8, 0x36, 0xc3, 0x50, 0x1e, 0xaf, 0x6e, 0xd4,
+	0x71, 0x2a, 0xd1, 0x79, 0xb7, 0xc3, 0xb0, 0x6d, 0x99, 0x6b, 0x1b, 0xca,
+	0xfe, 0xc0, 0xdc, 0x4d, 0xee, 0xed, 0xb1, 0x70, 0xc0, 0x0b, 0xc3, 0x71,
+	0xff, 0x76, 0x9b, 0x7f, 0x86, 0x7b, 0xd5, 0xb4, 0xa1, 0x0e, 0x7e, 0x0c,
+	0x3a, 0xb8, 0xa6, 0x7b, 0xef, 0xc6, 0x58, 0xf3, 0xa0, 0x99, 0x3e, 0xf9,
+	0x9d, 0x6a, 0xfa, 0xf3, 0xa2, 0xcf, 0x16, 0xf5, 0xc2, 0x86, 0x9b, 0xbf,
+	0xf3, 0xbd, 0x7e, 0x00, 0x5b, 0x2f, 0x94, 0x87, 0x83, 0x7e, 0xd0, 0x50,
+	0x37, 0xec, 0x3d, 0x5f, 0xfb, 0xa5, 0x8f, 0x6b, 0xda, 0x22, 0x8d, 0x31,
+	0xdf, 0x86, 0x76, 0x81, 0x13, 0xcf, 0xf5, 0xfe, 0xb1, 0x89, 0xd3, 0x04,
+	0x9d, 0xde, 0x97, 0xc0, 0xb7, 0x43, 0xfe, 0x0e, 0xf8, 0x28, 0xa4, 0x21,
+	0xc6, 0xd3, 0xb6, 0xdb, 0x7c, 0xc7, 0x36, 0x99, 0x76, 0x19, 0x77, 0x4c,
+	0xf7, 0x8f, 0x08, 0xe7, 0x9d, 0x4e, 0xa6, 0x94, 0xb6, 0xab, 0xc2, 0x03,
+	0x01, 0x73, 0x79, 0xb9, 0x67, 0x43, 0x7e, 0x1e, 0xbe, 0x6b, 0xc2, 0x2f,
+	0x78, 0x31, 0x9b, 0xff, 0x9b, 0x2b, 0x19, 0xda, 0x1c, 0x23, 0x6d, 0xc2,
+	0x9f, 0x5a, 0xe8, 0xfd, 0xbb, 0x90, 0xf6, 0x7d, 0x4a, 0x91, 0xf6, 0xbf,
+	0x17, 0xce, 0xba, 0xec, 0x8b, 0x70, 0x0f, 0xdf, 0x95, 0xd3, 0xb8, 0xba,
+	0x5b, 0x0e, 0x97, 0x69, 0x0b, 0xc7, 0x75, 0x7e, 0xc8, 0x68, 0x40, 0x3b,
+	0x2d, 0x0e, 0x3c, 0x8e, 0x01, 0x7f, 0x2d, 0xb0, 0xb9, 0x6f, 0x44, 0x9d,
+	0x98, 0x8c, 0x0c, 0xb7, 0x80, 0xf7, 0xc8, 0x9f, 0xbc, 0xbb, 0xa8, 0xef,
+	0xc9, 0x5c, 0x69, 0x44, 0xe7, 0xef, 0x3d, 0x8e, 0xb6, 0x4f, 0xe0, 0x9a,
+	0x29, 0x7d, 0x18, 0x6d, 0xde, 0xaf, 0xeb, 0xcf, 0x4c, 0x32, 0x17, 0x5a,
+	0x20, 0x97, 0x3e, 0x21, 0xc5, 0xd9, 0x0e, 0x19, 0x49, 0xcc, 0x4f, 0xbb,
+	0x4b, 0x71, 0x99, 0x47, 0x37, 0x70, 0xcf, 0xa4, 0x78, 0x35, 0xf7, 0x97,
+	0xc5, 0x1d, 0xde, 0xad, 0xba, 0x5b, 0xb5, 0xcf, 0xd5, 0x2f, 0x43, 0xd5,
+	0x8c, 0xdc, 0x54, 0x7d, 0x62, 0x8b, 0x89, 0x45, 0x2d, 0x8b, 0x6f, 0x1d,
+	0xd3, 0x52, 0xe5, 0x84, 0xcb, 0xf3, 0x59, 0x32, 0x73, 0x56, 0x24, 0x76,
+	0x22, 0x8a, 0x4d, 0xb2, 0xcc, 0x93, 0x8e, 0xab, 0x01, 0xd7, 0x59, 0xc8,
+	0xd6, 0x44, 0x5c, 0x3e, 0xbb, 0x2b, 0x1a, 0xab, 0x10, 0x4e, 0xed, 0x2a,
+	0xc8, 0x9d, 0xb8, 0xf2, 0x57, 0xa7, 0x27, 0x73, 0x8a, 0xe3, 0xfe, 0x75,
+	0x48, 0x59, 0xa6, 0x32, 0xbe, 0x14, 0x5a, 0xa3, 0xb1, 0xe1, 0xdf, 0xec,
+	0x89, 0xc6, 0xa7, 0xcd, 0x6d, 0xce, 0x56, 0x14, 0xb9, 0x8f, 0x03, 0xfa,
+	0x8b, 0x65, 0x3e, 0xb7, 0x81, 0xbe, 0xc3, 0x80, 0xb0, 0x1d, 0x64, 0xba,
+	0x62, 0xdf, 0x84, 0x93, 0xf0, 0xd7, 0xc3, 0xb9, 0x90, 0x4a, 0x00, 0x47,
+	0x85, 0xd7, 0x85, 0xb7, 0xc7, 0xf3, 0xd5, 0x5a, 0xf0, 0xde, 0x6c, 0x63,
+	0x89, 0x8c, 0x0f, 0xae, 0x03, 0xde, 0x5a, 0x50, 0x9e, 0x97, 0x89, 0x93,
+	0xb7, 0x6e, 0xe1, 0xde, 0x78, 0x83, 0xef, 0xd8, 0x1c, 0x56, 0x9e, 0x39,
+	0x9a, 0x40, 0x1d, 0xbe, 0x1f, 0x41, 0x9b, 0x74, 0x21, 0x17, 0xdb, 0x02,
+	0x9f, 0x88, 0xe3, 0x86, 0xb1, 0x8e, 0x3d, 0xcd, 0x3a, 0x27, 0x55, 0xce,
+	0x52, 0x9f, 0x47, 0x6d, 0x27, 0x74, 0xce, 0x07, 0xfc, 0xf6, 0xc2, 0x60,
+	0x8c, 0xf2, 0xab, 0x5b, 0x06, 0xa8, 0x4f, 0xce, 0x8e, 0x68, 0xda, 0xef,
+	0xdc, 0xc5, 0xf3, 0x57, 0x3d, 0xc6, 0x46, 0x4f, 0x10, 0xc6, 0x9b, 0x51,
+	0x0e, 0xfb, 0xfd, 0x35, 0x61, 0x28, 0xbc, 0x49, 0x18, 0x0a, 0x6f, 0x12,
+	0x06, 0xe2, 0x02, 0x70, 0x54, 0xaf, 0xd8, 0x18, 0xc5, 0xbe, 0xb7, 0x62,
+	0x1e, 0x47, 0xca, 0x05, 0x39, 0x5a, 0x76, 0x74, 0xdc, 0x71, 0x5e, 0x51,
+	0x26, 0x78, 0xe0, 0x49, 0xf0, 0x5e, 0x19, 0xbc, 0x59, 0x06, 0x2f, 0x96,
+	0xc1, 0x97, 0xb0, 0xff, 0xcf, 0x43, 0x3e, 0x3c, 0x81, 0xb5, 0x79, 0x7c,
+	0x19, 0x2f, 0x67, 0x35, 0x2f, 0x17, 0xcb, 0xf4, 0xd5, 0x7a, 0x2f, 0xc3,
+	0xaf, 0xae, 0x0c, 0x94, 0xd2, 0x50, 0x25, 0x8e, 0x9b, 0xef, 0xfd, 0x28,
+	0xf9, 0x55, 0x1e, 0x0c, 0x0e, 0xa2, 0xcd, 0x24, 0x68, 0x3c, 0x4d, 0x3b,
+	0x90, 0xf6, 0x4f, 0x01, 0xbc, 0x79, 0x8c, 0xbe, 0x9a, 0xba, 0x7a, 0xb3,
+	0x50, 0xbf, 0xb8, 0x7b, 0x98, 0xcb, 0xc8, 0xb9, 0xa6, 0x56, 0xe0, 0xc9,
+	0xf0, 0xef, 0x98, 0x4f, 0x3d, 0x43, 0xbe, 0x7d, 0x96, 0x7c, 0x5b, 0xc7,
+	0xab, 0x3f, 0xc5, 0xf9, 0x85, 0xde, 0xae, 0xb5, 0xda, 0xd6, 0xea, 0x6f,
+	0x5e, 0xaa, 0xaf, 0xc7, 0x9f, 0x24, 0x3f, 0xaa, 0xcc, 0x24, 0x71, 0x9f,
+	0xca, 0xc5, 0x76, 0x58, 0xdc, 0xc3, 0x76, 0xdb, 0x73, 0x05, 0x70, 0xdf,
+	0x2e, 0x85, 0xb9, 0x50, 0xfc, 0x3d, 0x51, 0x9f, 0xb5, 0x7e, 0x3c, 0xdb,
+	0xcf, 0x68, 0xc9, 0x91, 0xc1, 0x5d, 0xdc, 0xd7, 0x70, 0xa0, 0xe7, 0xa3,
+	0xf5, 0x80, 0xbd, 0xaf, 0xd7, 0x9c, 0x32, 0x96, 0xb2, 0xb5, 0xc5, 0xc6,
+	0x9f, 0xd8, 0xdf, 0xe4, 0x8a, 0x75, 0x7a, 0x31, 0xe4, 0xb9, 0xb6, 0x09,
+	0xff, 0x60, 0x1d, 0xad, 0x3c, 0x60, 0x69, 0x45, 0xad, 0x98, 0xc7, 0x5d,
+	0x96, 0x56, 0x22, 0x78, 0x13, 0x11, 0xad, 0x34, 0x45, 0xb4, 0x52, 0x98,
+	0x8e, 0x68, 0x85, 0x6d, 0xef, 0x8a, 0x68, 0x25, 0x55, 0x4f, 0x2b, 0x85,
+	0x69, 0x07, 0xd7, 0x4a, 0x38, 0x48, 0x2f, 0xec, 0x87, 0xf4, 0x02, 0x58,
+	0xaa, 0x9f, 0x59, 0xa2, 0x97, 0x04, 0xfa, 0x39, 0x5a, 0x36, 0x39, 0x22,
+	0xf0, 0xbb, 0xac, 0x0e, 0xf1, 0xb0, 0xe6, 0xc6, 0x47, 0x5c, 0x9b, 0x46,
+	0x02, 0x4b, 0x23, 0xb5, 0x7c, 0xfa, 0x15, 0xb4, 0x01, 0xdc, 0x33, 0x37,
+	0x76, 0xb7, 0xa6, 0x8d, 0xfb, 0x83, 0x12, 0xea, 0x0e, 0x83, 0x36, 0x22,
+	0x1c, 0xbc, 0xc7, 0xe2, 0x60, 0xe5, 0x5a, 0xde, 0x66, 0x71, 0x30, 0x6c,
+	0x71, 0xa0, 0xf9, 0xa5, 0xc0, 0x35, 0x53, 0x1a, 0x07, 0x4d, 0x1a, 0x07,
+	0xa2, 0xa2, 0xb6, 0xb7, 0xad, 0x81, 0x03, 0xd6, 0x19, 0xd6, 0xf3, 0x8f,
+	0x61, 0xfe, 0xb7, 0x63, 0xfe, 0x4a, 0xcf, 0x9f, 0xeb, 0x60, 0x72, 0xb9,
+	0x8b, 0xd5, 0xbf, 0x5e, 0x9a, 0x7f, 0x2b, 0xfa, 0x38, 0x52, 0x8e, 0xe9,
+	0xf9, 0xc3, 0xb6, 0xef, 0x8f, 0xe6, 0xff, 0x78, 0xd5, 0xe4, 0x53, 0x3f,
+	0xbe, 0x4a, 0xcf, 0x95, 0x2c, 0x6f, 0xf8, 0xda, 0x2f, 0x66, 0x4c, 0xfb,
+	0x3c, 0x74, 0xdb, 0x54, 0x90, 0xb2, 0xe7, 0xae, 0x8c, 0xbd, 0xf4, 0x95,
+	0x80, 0xbc, 0xf3, 0x21, 0x9d, 0xd7, 0x72, 0x8e, 0x76, 0x53, 0xb9, 0x55,
+	0x06, 0xa7, 0xea, 0xe1, 0x26, 0xbc, 0x05, 0x2d, 0x47, 0xf3, 0x98, 0xdf,
+	0x68, 0xd0, 0x0d, 0xf9, 0xa6, 0x69, 0x09, 0xe5, 0xe9, 0xc2, 0x40, 0xac,
+	0x49, 0xd4, 0x03, 0xef, 0xc7, 0x9c, 0x5d, 0xd9, 0xe2, 0x77, 0x7a, 0x7b,
+	0x14, 0x75, 0xe1, 0x95, 0x75, 0xba, 0xb0, 0xcd, 0xea, 0xc2, 0xcd, 0xd4,
+	0x85, 0x80, 0xfb, 0x6e, 0x39, 0x56, 0xe6, 0xfa, 0x15, 0x52, 0x4d, 0xd0,
+	0xff, 0xdf, 0xf1, 0x79, 0xc6, 0x45, 0xc7, 0xcd, 0x92, 0xc7, 0x34, 0x2d,
+	0x53, 0xa7, 0xa5, 0xf5, 0x99, 0x90, 0x05, 0xda, 0xd8, 0x09, 0xc6, 0x42,
+	0xa9, 0xf7, 0xfe, 0x3e, 0xfc, 0xcc, 0x1a, 0x7a, 0x6f, 0xbc, 0x6c, 0xec,
+	0xb7, 0x06, 0xd8, 0x84, 0x72, 0xaa, 0x0d, 0xd7, 0x26, 0x9e, 0x89, 0xe8,
+	0xee, 0x52, 0xcd, 0xd2, 0x70, 0x6a, 0xa3, 0x8c, 0x4d, 0x19, 0x1b, 0x57,
+	0x9d, 0x02, 0xfe, 0x4f, 0x31, 0x7f, 0x56, 0x74, 0xbe, 0x7f, 0x7e, 0x12,
+	0x76, 0xee, 0xcc, 0xdd, 0xe6, 0x1c, 0xc8, 0x54, 0x83, 0xfe, 0x4d, 0x1b,
+	0xa4, 0x18, 0x64, 0xa1, 0xef, 0xe2, 0x32, 0x86, 0x3e, 0x3b, 0x77, 0x35,
+	0x62, 0xce, 0x09, 0xb4, 0xa5, 0xcf, 0xc7, 0x38, 0x5a, 0xa3, 0xb8, 0x33,
+	0x49, 0x9d, 0xab, 0xcf, 0xf3, 0xae, 0xb9, 0xfe, 0x56, 0xbc, 0x63, 0x7e,
+	0x84, 0x87, 0xb1, 0x22, 0xd9, 0x8f, 0x7e, 0x4f, 0x88, 0xdd, 0xef, 0xc9,
+	0x68, 0xfd, 0x17, 0x3b, 0xe1, 0xd9, 0xb3, 0x7a, 0xfd, 0x58, 0xf7, 0xb5,
+	0xf4, 0xa2, 0x31, 0x72, 0x73, 0x58, 0x3f, 0x75, 0xd6, 0xc5, 0xbd, 0x1d,
+	0xf7, 0xa8, 0xbf, 0x48, 0x8f, 0x40, 0x37, 0xbe, 0xfd, 0xd0, 0x26, 0x69,
+	0x06, 0xbe, 0x67, 0x14, 0x70, 0x6d, 0x72, 0xbc, 0x0a, 0x9a, 0x17, 0x6a,
+	0xf4, 0xf0, 0xc4, 0xeb, 0xf2, 0x03, 0x69, 0x82, 0xb4, 0x40, 0xb9, 0x48,
+	0xda, 0xa0, 0x4c, 0x24, 0x6d, 0x1b, 0x7a, 0x78, 0x2c, 0xf0, 0x63, 0xcc,
+	0x03, 0x30, 0x71, 0x79, 0xd2, 0x06, 0x69, 0x3e, 0xa5, 0xe3, 0xf5, 0x59,
+	0xf9, 0x96, 0x64, 0x5b, 0x3b, 0x61, 0x97, 0xfd, 0xdb, 0xae, 0xb1, 0x39,
+	0x2b, 0xac, 0x69, 0x0e, 0xba, 0x89, 0x39, 0x79, 0xdd, 0xf2, 0x9e, 0x6a,
+	0x01, 0x78, 0xb8, 0x17, 0x4a, 0xf9, 0x6e, 0x9d, 0xe7, 0xb8, 0xaf, 0xb4,
+	0x49, 0x6e, 0x09, 0xe2, 0x36, 0xee, 0x7e, 0x04, 0x74, 0xb0, 0xe0, 0xc8,
+	0xa9, 0x0b, 0xb8, 0x2e, 0x3a, 0x5c, 0xbf, 0x4b, 0x41, 0x36, 0xad, 0xc8,
+	0xec, 0xbe, 0x9b, 0x5c, 0x90, 0x1e, 0x6f, 0x4c, 0x18, 0xeb, 0x98, 0x77,
+	0x9a, 0x4e, 0xfd, 0xfe, 0x26, 0xe3, 0x4b, 0x03, 0x16, 0xbf, 0xd1, 0x1b,
+	0xa4, 0x2d, 0x17, 0x84, 0x61, 0x9e, 0x76, 0x83, 0x28, 0xed, 0x23, 0xc1,
+	0xe7, 0x43, 0x19, 0xe3, 0x13, 0x3b, 0x9d, 0xc6, 0xb3, 0x2f, 0x58, 0x5a,
+	0x91, 0x98, 0xca, 0x3c, 0xed, 0x34, 0x9c, 0x7a, 0x84, 0x6b, 0xa6, 0xf3,
+	0xae, 0x0d, 0x5d, 0x3d, 0xeb, 0xd4, 0xe8, 0xea, 0x2b, 0xf6, 0xb7, 0xca,
+	0x34, 0x49, 0x36, 0xdd, 0x84, 0xf9, 0x0e, 0x94, 0x22, 0x18, 0xbf, 0x0d,
+	0xb8, 0x08, 0x0f, 0xe8, 0x76, 0xe6, 0x7f, 0xe2, 0x5a, 0x04, 0x2c, 0xf7,
+	0x01, 0xee, 0x4b, 0x80, 0xf9, 0x45, 0x5c, 0x6a, 0x5b, 0x4c, 0xfe, 0xd4,
+	0x89, 0xcd, 0xd4, 0xc3, 0x4b, 0x18, 0xbf, 0x6b, 0xe1, 0x7d, 0x2d, 0x58,
+	0x3d, 0x59, 0xe8, 0xeb, 0x00, 0x3c, 0x84, 0xf3, 0x25, 0xc0, 0x48, 0xbb,
+	0xf5, 0x39, 0x3c, 0x7b, 0x80, 0xef, 0x79, 0x0b, 0x13, 0xe8, 0x71, 0xea,
+	0x2f, 0x6a, 0xbf, 0x4b, 0xb4, 0xa3, 0xff, 0xd2, 0x3e, 0xb7, 0xaf, 0x90,
+	0x01, 0x5d, 0x0e, 0xf1, 0x3c, 0x51, 0x5e, 0xa4, 0x1d, 0x00, 0xbe, 0xff,
+	0xae, 0xc4, 0xce, 0x26, 0xe5, 0x68, 0x89, 0x7b, 0x40, 0xa7, 0x81, 0x0f,
+	0x7d, 0xc6, 0x05, 0x75, 0xae, 0xc2, 0x05, 0x65, 0x3f, 0xb3, 0x1b, 0x57,
+	0x37, 0xae, 0xb7, 0xe2, 0x02, 0x39, 0xcc, 0x9c, 0xc2, 0xd5, 0x83, 0xbe,
+	0x55, 0xa2, 0x49, 0x98, 0x9b, 0xf5, 0x0d, 0xb4, 0xd1, 0xb6, 0x65, 0x41,
+	0x65, 0xfa, 0x80, 0xbf, 0x3e, 0xc0, 0x96, 0xc4, 0xc5, 0x7c, 0xe6, 0xef,
+	0x3a, 0x72, 0xf6, 0x65, 0x5c, 0x60, 0xb0, 0xb3, 0x20, 0xcc, 0xb3, 0xfd,
+	0xb8, 0xa0, 0xc4, 0xce, 0x66, 0x71, 0x0d, 0xe2, 0xfa, 0x2b, 0xc7, 0xf0,
+	0x5c, 0x3b, 0xf0, 0x15, 0xf1, 0x08, 0x70, 0xbe, 0x8c, 0xe7, 0xbe, 0xec,
+	0xbc, 0x71, 0x9e, 0xfb, 0xbe, 0x63, 0x78, 0xee, 0x15, 0xa7, 0xc6, 0x73,
+	0x17, 0x1c, 0xf5, 0xf0, 0xd3, 0x4e, 0xec, 0x61, 0xfa, 0x12, 0x17, 0x1c,
+	0xc3, 0xff, 0x31, 0x19, 0x38, 0x08, 0x5a, 0x7a, 0x78, 0x1e, 0x17, 0xe9,
+	0xea, 0x19, 0x94, 0x3f, 0xbf, 0x62, 0xdc, 0xe7, 0xde, 0xc4, 0xb8, 0xaf,
+	0xda, 0x71, 0x45, 0xd5, 0xc6, 0x7d, 0x11, 0x7d, 0xbf, 0x64, 0xc7, 0x7d,
+	0xb1, 0x6e, 0x5c, 0xd0, 0xca, 0xc3, 0x8b, 0xb8, 0x48, 0x17, 0x2f, 0xa0,
+	0x3c, 0x92, 0x09, 0x1f, 0xf4, 0xa4, 0xb9, 0x01, 0xbc, 0x1b, 0x87, 0x7e,
+	0x6c, 0x58, 0xd2, 0x8d, 0xd9, 0x3a, 0xfd, 0xf0, 0x46, 0xf4, 0xe3, 0x78,
+	0x99, 0x36, 0xe2, 0x7c, 0x9d, 0x5c, 0xa0, 0x6f, 0x14, 0xca, 0x49, 0xed,
+	0x07, 0xd1, 0x27, 0xa2, 0x7f, 0xb4, 0xd2, 0xb6, 0xfa, 0xa8, 0xce, 0x45,
+	0xfb, 0x95, 0x52, 0xbb, 0xdc, 0x59, 0xa2, 0x4d, 0x48, 0x7a, 0x09, 0xc3,
+	0xb1, 0x3d, 0xb4, 0x4f, 0x0b, 0xe1, 0x15, 0x3e, 0xe9, 0xc4, 0xf7, 0x7e,
+	0x79, 0xb5, 0xce, 0x98, 0x1c, 0x80, 0xef, 0x9e, 0x3b, 0xf1, 0x8b, 0xd0,
+	0x19, 0x0d, 0x80, 0x9b, 0xf4, 0xb6, 0x4d, 0x0e, 0x4c, 0xaa, 0x89, 0x2d,
+	0x90, 0x25, 0x37, 0x95, 0x1a, 0x61, 0xf7, 0x30, 0x4f, 0xab, 0x59, 0x3a,
+	0xf7, 0xc4, 0x4d, 0x1e, 0xb9, 0x97, 0xc0, 0x6f, 0xcf, 0xe4, 0xb5, 0x27,
+	0x92, 0x78, 0xff, 0x0f, 0x1e, 0xe5, 0x60, 0xc2, 0xbf, 0x4e, 0xe7, 0x08,
+	0x75, 0xec, 0xa1, 0xdd, 0x72, 0x83, 0xd6, 0xe1, 0xee, 0x2a, 0x3b, 0x49,
+	0x6d, 0xf3, 0xa4, 0x66, 0xa3, 0x8d, 0x96, 0xd2, 0x29, 0xc2, 0xf5, 0x90,
+	0x70, 0xff, 0xeb, 0x1e, 0x29, 0x06, 0x1b, 0xe1, 0x17, 0x30, 0x76, 0x9e,
+	0xee, 0xa6, 0x6d, 0x34, 0x33, 0xe5, 0xd9, 0x3c, 0xeb, 0x4d, 0xf2, 0xac,
+	0x1e, 0xa7, 0x51, 0xc3, 0x68, 0xce, 0x5e, 0x70, 0x1f, 0x21, 0xae, 0xcf,
+	0xfb, 0xcc, 0x54, 0x5a, 0xb4, 0xde, 0x99, 0xa9, 0x30, 0xaf, 0x1f, 0xfe,
+	0x54, 0x85, 0x79, 0xfc, 0x81, 0x78, 0x6f, 0x87, 0x9f, 0x5b, 0xd9, 0x21,
+	0xa3, 0x53, 0xeb, 0xa4, 0xd1, 0x57, 0x89, 0x2d, 0xd0, 0x1f, 0x6c, 0xd3,
+	0xb1, 0x07, 0xfe, 0xe1, 0xf4, 0x4e, 0x79, 0x62, 0x9a, 0x7d, 0x6f, 0x93,
+	0xd9, 0x39, 0x71, 0xbc, 0xb7, 0xaf, 0x47, 0x1d, 0xc8, 0xf5, 0x3d, 0x2c,
+	0x4b, 0xe1, 0x2e, 0xca, 0x7b, 0xbb, 0x2b, 0x17, 0xfb, 0xf8, 0xcc, 0xb3,
+	0x04, 0xe2, 0xb2, 0xbf, 0x8b, 0x7d, 0xed, 0x72, 0x6e, 0x0e, 0x34, 0x01,
+	0xb9, 0x3f, 0x78, 0x8a, 0x30, 0x89, 0xec, 0x9d, 0x61, 0x2c, 0xbd, 0xd3,
+	0x63, 0xdc, 0x94, 0xfb, 0x34, 0xb7, 0xf4, 0x71, 0x2c, 0xe8, 0x25, 0xe8,
+	0xb8, 0x8e, 0x3d, 0x46, 0x16, 0x64, 0x67, 0x1a, 0x50, 0xce, 0x7e, 0xe1,
+	0x3f, 0x1e, 0x64, 0x3f, 0x51, 0x5b, 0x85, 0x39, 0x35, 0x6a, 0x7a, 0x59,
+	0x5c, 0xa1, 0x3f, 0xce, 0xff, 0x48, 0xf6, 0x37, 0xfb, 0xe8, 0xd6, 0x7b,
+	0x21, 0xdc, 0x53, 0x36, 0xb6, 0x15, 0xd7, 0x44, 0xef, 0x29, 0xc0, 0xae,
+	0xba, 0x4a, 0xdb, 0x17, 0xb3, 0x55, 0xae, 0x20, 0x63, 0x51, 0xd1, 0x1a,
+	0x25, 0xe5, 0xd1, 0xf2, 0xd2, 0x3a, 0xed, 0x68, 0x58, 0xbe, 0x4e, 0xa4,
+	0x95, 0x60, 0xc4, 0xda, 0x1e, 0x0b, 0x72, 0x0c, 0x76, 0x59, 0xb7, 0x5e,
+	0xb3, 0x05, 0xd8, 0xb2, 0x76, 0xcd, 0xb4, 0x3d, 0x5b, 0x8c, 0xd6, 0x6c,
+	0x18, 0x1a, 0xa7, 0x92, 0xd9, 0xcc, 0x35, 0xf3, 0x18, 0xef, 0x06, 0xde,
+	0x0b, 0x58, 0xa7, 0x02, 0xd6, 0xa8, 0x50, 0xd9, 0x26, 0x33, 0x27, 0x55,
+	0x7b, 0x83, 0x48, 0x6a, 0xd4, 0xdf, 0x26, 0xe3, 0x73, 0x8c, 0x25, 0xec,
+	0x80, 0x0d, 0xb6, 0x13, 0x57, 0x3b, 0x9e, 0xd9, 0x2e, 0x21, 0xc5, 0x8a,
+	0x42, 0xdb, 0xa6, 0x55, 0x76, 0xd6, 0x39, 0x8c, 0xcd, 0x33, 0x9d, 0x8f,
+	0x01, 0x0f, 0x35, 0xde, 0x29, 0xd5, 0xc5, 0x9f, 0x38, 0x57, 0xad, 0x43,
+	0x31, 0xdf, 0x84, 0x5e, 0x4f, 0x1d, 0x87, 0x2a, 0x37, 0xbe, 0x19, 0x7b,
+	0x2a, 0x49, 0x7b, 0x2a, 0x3f, 0xe9, 0x99, 0xf3, 0x06, 0xc3, 0xf0, 0x9d,
+	0xfc, 0xfc, 0x66, 0xd2, 0xfa, 0xc8, 0x34, 0xe1, 0x8a, 0x47, 0x70, 0x2d,
+	0x5b, 0x33, 0x9e, 0x0f, 0x5b, 0x1d, 0xe7, 0x28, 0x2d, 0xe5, 0x43, 0x9a,
+	0xd8, 0x3e, 0xe3, 0x28, 0xed, 0x6b, 0xc0, 0x74, 0xb7, 0xb6, 0x61, 0x45,
+	0xdd, 0x26, 0x87, 0xcb, 0x3c, 0x5b, 0xc6, 0x78, 0xe2, 0x27, 0x19, 0x5f,
+	0xea, 0x9e, 0x91, 0x63, 0x18, 0x9b, 0xb9, 0x3f, 0xca, 0xc6, 0x6f, 0x36,
+	0xd8, 0x1c, 0x91, 0xfa, 0x18, 0x8e, 0xc9, 0x0d, 0x5a, 0x9e, 0x67, 0x9d,
+	0x1e, 0x5e, 0xc4, 0x3a, 0xff, 0x9a, 0xde, 0x1b, 0x94, 0xc9, 0x18, 0xb4,
+	0xdf, 0x68, 0x5f, 0xba, 0xdf, 0x9c, 0xab, 0x49, 0xc9, 0x50, 0xd9, 0xcc,
+	0xff, 0x92, 0xce, 0x11, 0x32, 0xb9, 0x90, 0x26, 0x7f, 0xe8, 0x1e, 0xb9,
+	0x04, 0x1d, 0x5e, 0x5b, 0xdb, 0x26, 0x19, 0x07, 0x2e, 0xf2, 0x7a, 0x5f,
+	0x22, 0x25, 0xf9, 0xbe, 0x47, 0x37, 0xf3, 0xdc, 0x45, 0x1c, 0xeb, 0x53,
+	0x9c, 0xe6, 0x59, 0x4c, 0xf6, 0x7b, 0xb9, 0xbe, 0x28, 0x66, 0x99, 0xd7,
+	0x0f, 0x59, 0xf9, 0x63, 0x3d, 0xc9, 0x66, 0xfd, 0x7e, 0x9d, 0xcd, 0xdf,
+	0x76, 0x44, 0x0e, 0x84, 0xf2, 0x87, 0xd0, 0x93, 0x67, 0xec, 0x9c, 0x52,
+	0x3a, 0x66, 0x25, 0xe1, 0xc5, 0x20, 0x69, 0x63, 0x96, 0x9c, 0xcb, 0x41,
+	0x4b, 0xdf, 0xc6, 0xfe, 0xa9, 0xd9, 0xd0, 0x66, 0xdf, 0xef, 0x09, 0x2d,
+	0x0b, 0x7b, 0xad, 0xed, 0xac, 0xe3, 0x3c, 0x8f, 0x88, 0xce, 0x09, 0x88,
+	0x7c, 0xa3, 0xae, 0x3a, 0xbf, 0xc0, 0xf8, 0x72, 0xc5, 0xa9, 0xb5, 0x64,
+	0x54, 0xcd, 0x27, 0xa4, 0x2f, 0x37, 0xb6, 0x8b, 0xdf, 0x47, 0x88, 0x7c,
+	0xb9, 0x5e, 0xeb, 0xcb, 0x6d, 0xd4, 0xbe, 0x9c, 0x89, 0x3d, 0x6c, 0x5c,
+	0xf2, 0xe5, 0x8a, 0x53, 0x05, 0xd0, 0x4a, 0xf4, 0x3d, 0x07, 0x63, 0x0b,
+	0x8d, 0x97, 0x78, 0x86, 0xa6, 0x51, 0xf2, 0xc3, 0x0a, 0x7e, 0x83, 0xf1,
+	0xb1, 0x18, 0xab, 0x50, 0xea, 0xeb, 0xd6, 0xbf, 0x68, 0x97, 0x6c, 0xdb,
+	0x3a, 0xcc, 0xfb, 0x6e, 0xbd, 0xe6, 0xb3, 0x25, 0xb3, 0xf7, 0x99, 0x3f,
+	0xc8, 0x98, 0x10, 0xcf, 0x49, 0x69, 0xfe, 0x4a, 0x0d, 0xc4, 0xba, 0x8d,
+	0x3d, 0xeb, 0x7b, 0xad, 0xd2, 0x7c, 0x1a, 0x38, 0x8f, 0xdb, 0x71, 0x53,
+	0x80, 0xe9, 0x30, 0xd6, 0xe6, 0x3a, 0x2b, 0x93, 0x39, 0xf6, 0x47, 0x9b,
+	0x18, 0x1b, 0x98, 0x2b, 0x45, 0x31, 0xc2, 0x98, 0x3d, 0xa3, 0xe9, 0xc7,
+	0x1a, 0xfd, 0x75, 0x6b, 0xda, 0xaa, 0x8f, 0xbf, 0xae, 0x6e, 0x22, 0x2d,
+	0xdd, 0xad, 0xf3, 0x5c, 0xd6, 0xf7, 0xa5, 0xf7, 0xeb, 0x9c, 0x7b, 0x1d,
+	0x63, 0x2c, 0x08, 0x73, 0xd4, 0xbe, 0x29, 0x3f, 0xa1, 0x65, 0xfe, 0xe1,
+	0x80, 0xfa, 0x6b, 0x8f, 0xfe, 0xdd, 0x98, 0x09, 0xc3, 0x8b, 0x7d, 0x13,
+	0x8c, 0x29, 0x7a, 0xdf, 0x96, 0xce, 0xe4, 0x80, 0xb6, 0x9d, 0xb0, 0x46,
+	0x07, 0x9b, 0x65, 0x9d, 0x3f, 0x62, 0x73, 0x66, 0x0a, 0x90, 0x9b, 0x69,
+	0xd8, 0x4c, 0x3c, 0x7f, 0xdc, 0x65, 0xdf, 0x15, 0xc2, 0x66, 0xd0, 0xd1,
+	0x07, 0xc5, 0xc8, 0x98, 0x7c, 0x4d, 0xc6, 0x30, 0xd7, 0x20, 0x4b, 0x42,
+	0x76, 0x8f, 0x4b, 0x9a, 0xdf, 0x2a, 0xe1, 0xd8, 0x45, 0xd9, 0x0a, 0xbd,
+	0xcc, 0x76, 0xb4, 0x55, 0xf9, 0xcc, 0x3d, 0x1c, 0xdf, 0x3b, 0x02, 0xdd,
+	0x72, 0xc3, 0x6a, 0xdd, 0x92, 0xa4, 0x5f, 0x9f, 0x9f, 0xa4, 0x6f, 0xb8,
+	0x1e, 0x6d, 0xb6, 0xc9, 0x87, 0xa6, 0x7e, 0xbe, 0x95, 0xbc, 0x35, 0x02,
+	0xb9, 0xae, 0xee, 0x8f, 0xce, 0x16, 0xb1, 0x8c, 0xef, 0xd9, 0x6f, 0x93,
+	0xa4, 0xde, 0xeb, 0xc9, 0x6f, 0x54, 0xd3, 0xa9, 0x45, 0xe8, 0xa6, 0x11,
+	0xe7, 0x57, 0xb7, 0x9b, 0x98, 0xea, 0x07, 0x5a, 0xcd, 0x59, 0x84, 0x66,
+	0xe0, 0x34, 0x8a, 0xb3, 0xd6, 0xd3, 0xec, 0xa2, 0x95, 0xc7, 0x61, 0xd8,
+	0xdc, 0xa7, 0x65, 0xf0, 0x7e, 0xca, 0xe0, 0xc3, 0x41, 0x97, 0xa1, 0x7d,
+	0xed, 0x33, 0x85, 0x58, 0x47, 0xe0, 0xa1, 0xcf, 0x65, 0xbe, 0x9f, 0xe5,
+	0x4f, 0x3f, 0xbb, 0x60, 0xe5, 0x92, 0x72, 0x56, 0xf3, 0xa5, 0xba, 0x26,
+	0xbe, 0x4c, 0xe6, 0x1e, 0x9d, 0xa2, 0x3e, 0x0e, 0xe6, 0xbf, 0x09, 0x39,
+	0x95, 0xd7, 0x78, 0xd8, 0x26, 0xf7, 0x4d, 0x49, 0xf6, 0x12, 0x74, 0x55,
+	0x71, 0x6e, 0x39, 0x6f, 0xae, 0xee, 0x8f, 0x73, 0x7d, 0xa4, 0xd5, 0xf8,
+	0xb6, 0xcb, 0xe7, 0x3a, 0x8f, 0xb9, 0x66, 0xf5, 0x5c, 0xb9, 0x6f, 0x33,
+	0x67, 0xe7, 0xba, 0x3e, 0x9a, 0x6b, 0xff, 0xf2, 0xb9, 0x46, 0xbe, 0x7d,
+	0x24, 0x77, 0x53, 0x3a, 0xff, 0x5e, 0xe7, 0x7d, 0x4f, 0xad, 0x97, 0x81,
+	0xc9, 0x8d, 0x56, 0x5e, 0x7a, 0xd0, 0x3d, 0xcc, 0x89, 0x9f, 0xbf, 0xd7,
+	0x13, 0x8b, 0x33, 0x45, 0x3c, 0x50, 0xd6, 0xb6, 0xea, 0x33, 0x3b, 0x33,
+	0xf0, 0xaf, 0x6e, 0x2d, 0xb1, 0x6e, 0xf4, 0xfe, 0x72, 0xb1, 0xe3, 0xc8,
+	0xa7, 0xa6, 0xdf, 0xd4, 0xbd, 0x2a, 0xa6, 0x60, 0xe2, 0xc3, 0x8c, 0x0b,
+	0x9b, 0xb3, 0xc4, 0xcc, 0x45, 0xbc, 0x03, 0x3c, 0xf5, 0xf1, 0x52, 0xba,
+	0x3f, 0x17, 0xa3, 0x1c, 0x9d, 0x96, 0xa3, 0xd5, 0x41, 0xe9, 0xd0, 0xe7,
+	0x49, 0x5f, 0x37, 0x76, 0x9c, 0xad, 0x8f, 0x1d, 0x33, 0x9d, 0x80, 0xb1,
+	0xe3, 0xfd, 0x3f, 0x42, 0xec, 0x58, 0x1c, 0x13, 0x3b, 0x5e, 0xcb, 0xbf,
+	0x9a, 0x28, 0x4f, 0x63, 0x5e, 0xcd, 0x90, 0x25, 0x0b, 0x4e, 0x7e, 0xae,
+	0x05, 0xf7, 0x0b, 0xb8, 0xc7, 0x71, 0xbf, 0x84, 0xbb, 0x87, 0xfb, 0x8b,
+	0xb8, 0x27, 0x64, 0x62, 0x49, 0x67, 0x4c, 0x43, 0x6e, 0x50, 0x97, 0xb1,
+	0xad, 0xf1, 0x07, 0x66, 0x2b, 0x6d, 0xfc, 0x2e, 0x8c, 0x33, 0x33, 0xc7,
+	0x39, 0x6c, 0x94, 0xf1, 0x29, 0xca, 0xec, 0x56, 0x99, 0x9c, 0x8a, 0x6c,
+	0xdb, 0xbb, 0xb6, 0x71, 0xcf, 0x60, 0x44, 0x22, 0xdb, 0xf5, 0x77, 0xb7,
+	0xd9, 0x5c, 0xfb, 0x2d, 0xd2, 0xbc, 0x09, 0x6b, 0x70, 0x5a, 0x2e, 0x4d,
+	0x6f, 0x5a, 0x66, 0xc3, 0xa6, 0x6c, 0x4c, 0x70, 0xda, 0xea, 0xde, 0xb5,
+	0x65, 0x44, 0xfd, 0xfa, 0x27, 0x6d, 0x4e, 0x69, 0x94, 0x23, 0x94, 0xd2,
+	0xeb, 0x33, 0x5c, 0x9d, 0xc6, 0x78, 0xfd, 0x92, 0x9d, 0xe6, 0x3c, 0x97,
+	0xbe, 0x4d, 0x01, 0x79, 0x78, 0x0a, 0x7a, 0x75, 0x19, 0x5d, 0x82, 0x6e,
+	0x39, 0x37, 0x07, 0xb4, 0xfb, 0xa8, 0xcc, 0x4c, 0x12, 0xbe, 0xae, 0x64,
+	0x4c, 0x9f, 0x5d, 0xc3, 0xf3, 0xb4, 0xc9, 0x99, 0x1f, 0xa8, 0x46, 0xe7,
+	0xd6, 0x36, 0xeb, 0xef, 0x11, 0x2c, 0x3f, 0xbb, 0x66, 0xf5, 0xb3, 0xb6,
+	0x1d, 0x78, 0x86, 0x2d, 0x9a, 0xc3, 0x5a, 0xf4, 0x14, 0xca, 0xb8, 0xce,
+	0x3b, 0xdb, 0x22, 0x67, 0x1e, 0x5c, 0xca, 0xa1, 0x6d, 0x85, 0x8d, 0xd2,
+	0x0e, 0x13, 0x79, 0xd8, 0xcd, 0x74, 0xc1, 0xc7, 0x63, 0x9e, 0x4c, 0x57,
+	0xf2, 0x36, 0x9d, 0xdb, 0x5c, 0x3b, 0x47, 0x58, 0xcb, 0x6f, 0x8e, 0xce,
+	0x6d, 0x25, 0x65, 0x10, 0x74, 0x38, 0xa4, 0xcb, 0x13, 0x98, 0x0f, 0xf7,
+	0xfd, 0x34, 0x1e, 0x20, 0x7b, 0xb8, 0xe7, 0x87, 0xb9, 0x57, 0xbf, 0x01,
+	0x7a, 0x77, 0xec, 0x19, 0x36, 0xd2, 0x58, 0x9f, 0x8c, 0x55, 0x92, 0xce,
+	0x58, 0xa5, 0xcf, 0x39, 0x54, 0xb1, 0xef, 0xfa, 0x8a, 0x58, 0x0f, 0xfc,
+	0x9e, 0xee, 0x70, 0x46, 0x80, 0xaf, 0x62, 0xb9, 0xd3, 0xc9, 0xea, 0xbb,
+	0x6f, 0xef, 0x90, 0x03, 0x58, 0xab, 0x81, 0xe9, 0xa4, 0x96, 0xf3, 0xb5,
+	0xef, 0x61, 0x45, 0xeb, 0xfa, 0xa4, 0xde, 0x1b, 0x9a, 0x97, 0x69, 0xfd,
+	0x7d, 0x25, 0x63, 0x3b, 0x9c, 0x46, 0x7f, 0xd3, 0x36, 0x26, 0xde, 0xe3,
+	0xe4, 0x75, 0x3f, 0x66, 0x3d, 0x8a, 0xe5, 0x53, 0xb8, 0xaf, 0x3c, 0x43,
+	0x1d, 0xe9, 0x19, 0xc2, 0xfd, 0x08, 0xf4, 0x59, 0x78, 0x8f, 0x91, 0x57,
+	0xd3, 0x32, 0x51, 0x65, 0xfe, 0x08, 0xfb, 0x41, 0x79, 0xe5, 0x30, 0x74,
+	0xd2, 0xf2, 0x33, 0x84, 0x43, 0xb5, 0x75, 0x48, 0x4d, 0x0b, 0x61, 0xe1,
+	0x1a, 0x2c, 0x3f, 0x5f, 0x7f, 0xf9, 0x7f, 0xd1, 0xbe, 0xa2, 0x91, 0xa1,
+	0x16, 0x8e, 0x2c, 0xe5, 0x9d, 0x91, 0x2b, 0x9f, 0x96, 0x23, 0xc0, 0xe3,
+	0x31, 0xc0, 0xa4, 0xee, 0xe7, 0xf7, 0x5e, 0x2a, 0x52, 0x9c, 0xbd, 0x4f,
+	0xd4, 0x43, 0x97, 0x1c, 0xf7, 0xa1, 0x23, 0x12, 0x7b, 0x68, 0xc1, 0x69,
+	0x78, 0xa8, 0x53, 0xfb, 0xe5, 0xfb, 0x82, 0xce, 0xe4, 0x21, 0x39, 0x2d,
+	0xee, 0xfd, 0x4a, 0x9f, 0x27, 0x2b, 0x7a, 0x8c, 0xf1, 0x9d, 0x96, 0xd8,
+	0xfd, 0x71, 0x7b, 0x16, 0xd5, 0xc4, 0xf5, 0x16, 0x35, 0xdf, 0x3f, 0x97,
+	0x20, 0xce, 0x16, 0x65, 0x5a, 0xf3, 0xce, 0x00, 0xf4, 0x44, 0x6e, 0x32,
+	0xb5, 0x54, 0xc7, 0xe4, 0x7b, 0x6e, 0x4c, 0x18, 0x7e, 0x61, 0x9d, 0x2e,
+	0x87, 0xdf, 0x85, 0xb0, 0x3a, 0xff, 0xca, 0x28, 0xf7, 0xd3, 0xac, 0x29,
+	0xdf, 0xff, 0x10, 0x6b, 0xd8, 0x85, 0xf5, 0xe2, 0x78, 0x8e, 0xde, 0xcf,
+	0xe5, 0x59, 0x5c, 0x4f, 0x7a, 0x92, 0x4d, 0x4b, 0x76, 0x10, 0xeb, 0xde,
+	0x27, 0x4d, 0x80, 0x5b, 0x3d, 0x54, 0x34, 0x76, 0x9d, 0x90, 0x4e, 0x05,
+	0x92, 0x9b, 0x34, 0xdb, 0xd5, 0xbf, 0x4f, 0xaf, 0xe1, 0xbd, 0x96, 0x66,
+	0xd6, 0x19, 0xfb, 0x11, 0xcf, 0x86, 0x2e, 0x8a, 0xb2, 0x77, 0xea, 0xbb,
+	0xd0, 0xf3, 0xdc, 0x77, 0xd1, 0xf6, 0xe2, 0x1a, 0xb6, 0x20, 0x79, 0xe9,
+	0x69, 0xeb, 0x57, 0x86, 0xe1, 0x54, 0x10, 0x00, 0x8f, 0x6b, 0xf9, 0x92,
+	0x3b, 0x9c, 0xd9, 0xc9, 0x9d, 0xce, 0xcc, 0x64, 0x28, 0x63, 0x01, 0xbf,
+	0x19, 0xc2, 0x1c, 0x00, 0xda, 0x5b, 0x2c, 0xeb, 0x84, 0x6e, 0xdd, 0x9d,
+	0xe0, 0xf9, 0xa6, 0x9b, 0xfc, 0x17, 0xc4, 0xd4, 0x23, 0x8e, 0xe9, 0x23,
+	0x77, 0x3e, 0x92, 0x17, 0x7e, 0x9f, 0xa3, 0x27, 0x99, 0xd0, 0xdf, 0x10,
+	0xf9, 0x0c, 0xda, 0x61, 0x8c, 0x32, 0xc7, 0x7d, 0xc6, 0x99, 0x81, 0x3c,
+	0x9b, 0x9d, 0xe2, 0x37, 0x01, 0x98, 0x4f, 0x1b, 0x6b, 0x57, 0x72, 0x95,
+	0x37, 0x6e, 0xbf, 0x5b, 0x57, 0x80, 0x0b, 0x14, 0xd3, 0x65, 0x3d, 0xde,
+	0xe8, 0xd2, 0xb7, 0xec, 0xa2, 0xb2, 0xe8, 0x9b, 0x76, 0x4a, 0xe7, 0x4e,
+	0xc3, 0x97, 0x3d, 0x33, 0x22, 0xdf, 0x77, 0xe6, 0x4a, 0xaf, 0x38, 0x8f,
+	0x96, 0xb2, 0xd7, 0x5c, 0x01, 0xfa, 0xb8, 0x18, 0xe4, 0x29, 0xbf, 0x60,
+	0xf3, 0x4d, 0x49, 0xa1, 0x3a, 0x26, 0xd3, 0xdb, 0x3a, 0xbd, 0xfb, 0xf5,
+	0xda, 0x9c, 0x01, 0xce, 0xbe, 0x81, 0xf5, 0x3b, 0x93, 0xa0, 0x7e, 0x1b,
+	0x2d, 0x29, 0xf0, 0xb2, 0xfa, 0x69, 0x5c, 0xb0, 0x6d, 0x1b, 0xb5, 0x8d,
+	0x72, 0x28, 0x60, 0xbd, 0x9d, 0xce, 0xc0, 0xe4, 0x0e, 0xac, 0xe3, 0x41,
+	0xe8, 0x4f, 0x07, 0x76, 0x1a, 0x68, 0x1b, 0x65, 0xe3, 0xc0, 0xc1, 0x68,
+	0x60, 0xe4, 0xf9, 0x80, 0x14, 0xb4, 0x8f, 0x67, 0xee, 0x59, 0x65, 0x62,
+	0x66, 0x61, 0x38, 0x0b, 0xfb, 0x80, 0xdf, 0xc5, 0x9a, 0xa8, 0xce, 0xe1,
+	0xfa, 0x71, 0xbb, 0xa7, 0x3d, 0x7f, 0x99, 0x3d, 0x6d, 0x4f, 0x4e, 0x57,
+	0xf5, 0x39, 0x79, 0x9d, 0x5f, 0x95, 0x52, 0xeb, 0xda, 0xf4, 0x5a, 0xa9,
+	0x2e, 0x9d, 0x93, 0x96, 0x95, 0x47, 0x12, 0x46, 0x0f, 0x13, 0xa6, 0x14,
+	0xe0, 0xd9, 0x09, 0x5c, 0x10, 0x1e, 0xd3, 0x46, 0xd4, 0x3b, 0xb7, 0x52,
+	0x1f, 0x2e, 0xca, 0xa7, 0x12, 0xd1, 0x19, 0x05, 0xf4, 0x03, 0x19, 0x37,
+	0xb7, 0xd5, 0xe8, 0xc9, 0x2d, 0x6b, 0xf4, 0x13, 0xcd, 0xcd, 0xb1, 0x73,
+	0x23, 0xdd, 0x6e, 0xbe, 0x92, 0x3e, 0xc5, 0xa2, 0x34, 0xad, 0xa8, 0xcf,
+	0x98, 0xfe, 0xbe, 0xed, 0xe6, 0xcc, 0x03, 0xeb, 0x7a, 0xb0, 0x4d, 0x69,
+	0xe7, 0x12, 0x8f, 0x7a, 0xdd, 0x4a, 0x4a, 0x78, 0x6e, 0xe1, 0x0c, 0x64,
+	0xcb, 0x55, 0xde, 0x4f, 0x28, 0xd2, 0x61, 0x84, 0xeb, 0x6f, 0x68, 0x3e,
+	0x19, 0x2d, 0x31, 0xb6, 0xf2, 0x68, 0x98, 0x1d, 0x26, 0x8f, 0xb1, 0x0f,
+	0xbe, 0x9f, 0xd2, 0xf1, 0xdc, 0x83, 0x01, 0x63, 0x45, 0x9d, 0x8f, 0xdc,
+	0xa1, 0x22, 0x39, 0x05, 0xfd, 0x5b, 0x5e, 0x70, 0xf8, 0xdd, 0xbe, 0x03,
+	0x82, 0xfb, 0xdc, 0x82, 0xf3, 0xcd, 0xa9, 0x67, 0xf0, 0xdc, 0x60, 0xbf,
+	0xd5, 0x67, 0xf4, 0x94, 0xc8, 0x1f, 0x46, 0xf3, 0x4d, 0x16, 0xb0, 0xf6,
+	0x2f, 0x62, 0xed, 0xd7, 0xfe, 0x36, 0x1f, 0xde, 0x55, 0xf0, 0xae, 0xf2,
+	0x0b, 0x61, 0xb6, 0x95, 0xb4, 0x18, 0xe8, 0xb3, 0xa9, 0x97, 0xf7, 0x9b,
+	0xfb, 0x35, 0x5f, 0x8c, 0x97, 0xcf, 0x81, 0x2f, 0xb2, 0xdc, 0x6f, 0x0e,
+	0x1f, 0x0e, 0x6e, 0x04, 0x5f, 0xec, 0x97, 0xdf, 0x83, 0x5d, 0xf0, 0x3b,
+	0xd5, 0x0c, 0xf8, 0xa3, 0x1f, 0xfc, 0xd2, 0x07, 0x1e, 0x09, 0xb4, 0x8d,
+	0xfc, 0x18, 0xf4, 0x1f, 0xf4, 0x9a, 0x73, 0x68, 0xb2, 0xc3, 0xc9, 0x4f,
+	0xfa, 0xce, 0xd8, 0x24, 0xbf, 0xff, 0xa2, 0xde, 0xda, 0x20, 0x6e, 0x72,
+	0x56, 0xc8, 0x0b, 0x9d, 0xcc, 0x71, 0x6c, 0x03, 0xae, 0xce, 0x12, 0x57,
+	0xb3, 0xd5, 0x1e, 0xef, 0x0a, 0xf0, 0x44, 0x9b, 0xe6, 0x89, 0x8d, 0x4e,
+	0xd6, 0xbb, 0xd1, 0xf2, 0xc4, 0x0b, 0xe0, 0x89, 0x4b, 0xab, 0x78, 0xe2,
+	0x29, 0x4b, 0xff, 0xf3, 0x75, 0x3c, 0x31, 0x6b, 0xcb, 0xa6, 0x2f, 0xc3,
+	0x13, 0x5b, 0xfd, 0xf4, 0xe7, 0x47, 0xe4, 0x55, 0xf0, 0x84, 0x28, 0xf2,
+	0xc4, 0x56, 0xcd, 0x13, 0x8c, 0x1d, 0x91, 0x2f, 0xda, 0x21, 0x47, 0xc8,
+	0x17, 0x17, 0x64, 0x11, 0x7c, 0xf1, 0x9c, 0xe2, 0xd8, 0x67, 0x68, 0x2b,
+	0x4c, 0xd2, 0x27, 0x3b, 0x55, 0xee, 0x00, 0xbf, 0x2b, 0xf9, 0xaf, 0x53,
+	0x61, 0xb8, 0x00, 0x3f, 0xfd, 0x41, 0xd8, 0xf3, 0xae, 0xfe, 0x0e, 0xe4,
+	0x3c, 0xe8, 0x3e, 0xa2, 0xf7, 0x31, 0x07, 0xf4, 0x7e, 0x6c, 0x06, 0x73,
+	0x18, 0x53, 0x9f, 0x82, 0x2f, 0xec, 0x61, 0x5d, 0x69, 0xe7, 0x9f, 0xd4,
+	0x3c, 0xd4, 0x00, 0x7d, 0xf0, 0x68, 0x1f, 0x63, 0x4d, 0xbe, 0x77, 0x48,
+	0x75, 0x16, 0x06, 0x01, 0x73, 0x4c, 0xdd, 0x2f, 0x8c, 0x73, 0xb4, 0xae,
+	0xb0, 0xf3, 0x29, 0x23, 0x86, 0x21, 0xeb, 0xcc, 0xbb, 0x42, 0xd8, 0x04,
+	0x9b, 0xb4, 0x49, 0x19, 0x1b, 0x5d, 0xed, 0x49, 0x7b, 0x3f, 0x07, 0x01,
+	0xda, 0x08, 0x7b, 0x61, 0x2f, 0x56, 0x7b, 0xb0, 0x54, 0x6f, 0xe3, 0xff,
+	0x67, 0xd8, 0xf8, 0x6c, 0x23, 0xae, 0xb1, 0xf1, 0x7f, 0xc5, 0xf2, 0x1a,
+	0x7f, 0x7b, 0xda, 0xde, 0x3f, 0x0c, 0xf8, 0xf6, 0x2d, 0xd9, 0xfb, 0xec,
+	0x83, 0x76, 0x87, 0xc8, 0x0d, 0xb0, 0xf9, 0xde, 0x09, 0x1e, 0xbc, 0x11,
+	0xbe, 0xd4, 0xbb, 0x4a, 0x9e, 0xec, 0x2f, 0xb5, 0xc1, 0xe7, 0x6e, 0x97,
+	0x77, 0x4f, 0xed, 0x94, 0xa1, 0xc9, 0x0f, 0x5e, 0x21, 0xcd, 0xdb, 0x60,
+	0xa3, 0x4e, 0x01, 0xce, 0x98, 0x95, 0xdb, 0x3f, 0x04, 0xde, 0x3a, 0x53,
+	0xdf, 0x57, 0x6d, 0xdb, 0x8d, 0x9c, 0xe7, 0xd9, 0xc9, 0xb5, 0xfa, 0x49,
+	0xa0, 0x3d, 0x63, 0x29, 0xdb, 0xe4, 0xec, 0x49, 0x7a, 0x5f, 0x29, 0xd8,
+	0xe5, 0x01, 0x6c, 0x92, 0x1d, 0xe8, 0x8f, 0xf1, 0xe4, 0x4d, 0xf2, 0xd4,
+	0x35, 0xee, 0x27, 0xf2, 0x9a, 0x0f, 0xdb, 0x9d, 0xdc, 0xd4, 0x8d, 0x52,
+	0x3c, 0x18, 0xc7, 0x1c, 0x54, 0xdb, 0x16, 0xb9, 0x5e, 0x86, 0xf4, 0x7c,
+	0xce, 0xc8, 0x11, 0xe8, 0xe6, 0x3f, 0x28, 0x0d, 0xc9, 0xe2, 0x70, 0x2b,
+	0x9e, 0xe3, 0xf2, 0x54, 0xa9, 0x07, 0xbe, 0xcf, 0x3b, 0x80, 0xa3, 0x46,
+	0x3c, 0x37, 0xca, 0xc0, 0x15, 0xe4, 0xd5, 0x16, 0x59, 0x40, 0xf9, 0x3b,
+	0xe5, 0xdf, 0xd9, 0x72, 0x96, 0x91, 0x37, 0x5a, 0xd0, 0x36, 0x2e, 0x17,
+	0x4b, 0xb4, 0x2b, 0x35, 0x4f, 0xf4, 0x7f, 0x4b, 0x7a, 0xb2, 0xdf, 0x82,
+	0x9d, 0x7a, 0x01, 0xd7, 0xd3, 0x92, 0xde, 0x3f, 0xea, 0xf4, 0xa4, 0x3a,
+	0x1d, 0xe8, 0x4e, 0x5c, 0xae, 0xd3, 0xe3, 0x35, 0x3a, 0x57, 0xd9, 0x3e,
+	0x1a, 0xe4, 0xe9, 0x83, 0x2a, 0xd9, 0x82, 0x35, 0xd9, 0xed, 0x74, 0xd9,
+	0x32, 0x3e, 0xeb, 0x9c, 0x3c, 0xe9, 0x3c, 0xab, 0x76, 0x6c, 0x10, 0xe9,
+	0x68, 0x81, 0xcd, 0x33, 0x26, 0xaa, 0xad, 0x45, 0x5c, 0xe9, 0x9c, 0x51,
+	0xed, 0x28, 0xf3, 0x6d, 0x59, 0xa2, 0x05, 0xfa, 0x01, 0x65, 0xdb, 0x50,
+	0xb6, 0xcb, 0x96, 0xb5, 0xb6, 0x48, 0x23, 0xca, 0xce, 0x68, 0x9e, 0xbf,
+	0xd4, 0xe5, 0x7b, 0x79, 0xa7, 0x59, 0x3a, 0x4e, 0xb5, 0x40, 0x36, 0x6c,
+	0x92, 0x85, 0x6b, 0x9a, 0xa4, 0x03, 0xef, 0x18, 0xe7, 0x0e, 0x4e, 0xc5,
+	0xe5, 0xba, 0x53, 0x9d, 0xc9, 0x0f, 0x61, 0x0e, 0x9d, 0x67, 0x19, 0xf7,
+	0x7e, 0xf2, 0x0a, 0xc6, 0x7d, 0x3a, 0xce, 0xf2, 0xde, 0xa4, 0xe5, 0x0f,
+	0xf1, 0x61, 0xbe, 0x71, 0x44, 0x99, 0x7c, 0x1a, 0x7e, 0x2e, 0x75, 0x78,
+	0xa7, 0xfd, 0x1e, 0xc7, 0x9f, 0x5e, 0x41, 0xbf, 0x6d, 0x86, 0xf6, 0x54,
+	0x99, 0xfc, 0x48, 0x3d, 0x84, 0xfb, 0xb4, 0x23, 0xc5, 0x9a, 0xcc, 0x9a,
+	0x23, 0x5f, 0x9d, 0x54, 0xcc, 0x65, 0x41, 0x59, 0xf5, 0x67, 0x42, 0xb3,
+	0xc6, 0xe4, 0x05, 0x23, 0x97, 0xde, 0x67, 0xe4, 0xd2, 0x99, 0xf3, 0xcb,
+	0xe4, 0xd2, 0x25, 0x2d, 0x97, 0x0e, 0x0a, 0xee, 0x73, 0x97, 0x20, 0x97,
+	0x5e, 0xc0, 0xb3, 0xa7, 0xe5, 0x52, 0x42, 0xac, 0xbd, 0x2c, 0x3f, 0xd0,
+	0xe3, 0xcf, 0x96, 0x5d, 0x6d, 0x57, 0x15, 0xa7, 0x61, 0x93, 0x94, 0x27,
+	0xac, 0xfe, 0x96, 0x4c, 0xab, 0x74, 0xf5, 0xff, 0x50, 0x22, 0x9b, 0xf3,
+	0xcf, 0xae, 0xe0, 0xf7, 0x46, 0x9f, 0x53, 0x94, 0x61, 0xaf, 0x42, 0x86,
+	0x89, 0x5a, 0x5b, 0x86, 0xe1, 0x5d, 0x05, 0xef, 0x2a, 0xec, 0xf7, 0x6f,
+	0x7f, 0x38, 0xe2, 0x51, 0x7e, 0x50, 0x66, 0x40, 0x26, 0x95, 0x21, 0x93,
+	0xca, 0x90, 0x53, 0x65, 0xc8, 0x25, 0xd8, 0x6c, 0xe7, 0xcb, 0x90, 0x4b,
+	0x65, 0xc8, 0x25, 0xc8, 0xb8, 0xc7, 0x20, 0xe3, 0x8c, 0x4c, 0x1b, 0x86,
+	0x4c, 0x3b, 0x23, 0xf7, 0x59, 0x5d, 0x6f, 0x62, 0x25, 0xbd, 0xd6, 0x47,
+	0xea, 0xd3, 0x31, 0xe4, 0xf3, 0x75, 0xb1, 0xc1, 0x03, 0xc7, 0x35, 0xbf,
+	0x7b, 0xbe, 0xba, 0xca, 0x61, 0x0e, 0xcd, 0xf7, 0xb5, 0xff, 0xbe, 0x9b,
+	0xbf, 0xa5, 0x09, 0x7c, 0xfd, 0x1d, 0xcb, 0xd7, 0xbb, 0x97, 0xf8, 0x3a,
+	0xed, 0x30, 0x56, 0xbc, 0x36, 0x5f, 0x6f, 0xb3, 0xef, 0x0a, 0xe1, 0x3a,
+	0xf0, 0xf5, 0xba, 0x15, 0x7c, 0x1d, 0x07, 0x5f, 0xef, 0x5f, 0xc5, 0xd7,
+	0x1b, 0x9c, 0x01, 0xdd, 0x86, 0x67, 0x24, 0xf8, 0xdc, 0xe8, 0xd4, 0xf8,
+	0xfa, 0x1e, 0xcd, 0xd7, 0x47, 0xc1, 0xd7, 0xd7, 0xd7, 0xf1, 0xf5, 0x7e,
+	0x49, 0xdf, 0x9c, 0x8b, 0xed, 0x94, 0xd1, 0xfb, 0x55, 0xdb, 0x66, 0xf9,
+	0x17, 0x31, 0xed, 0x0d, 0x8f, 0x0d, 0x4c, 0xb5, 0x49, 0xfe, 0xa1, 0x57,
+	0x50, 0x46, 0x3e, 0x4b, 0x8f, 0x64, 0x1d, 0x4f, 0x8e, 0x1c, 0xff, 0xbe,
+	0xcc, 0x6b, 0xde, 0x12, 0x19, 0x3b, 0x1e, 0x97, 0xf1, 0xe3, 0x8c, 0x43,
+	0x7c, 0xcf, 0xd2, 0x7b, 0x93, 0x8c, 0x1f, 0x64, 0xde, 0x9c, 0x2b, 0xa3,
+	0xc7, 0xe1, 0x6f, 0x1d, 0x67, 0x1c, 0xe2, 0xa5, 0x25, 0x1e, 0x9b, 0x87,
+	0x6c, 0x19, 0x3d, 0xce, 0xb5, 0x8e, 0xa3, 0x9f, 0x16, 0x39, 0x7a, 0x5c,
+	0xe4, 0xb6, 0xe3, 0xae, 0x7c, 0xe0, 0xf8, 0x12, 0xaf, 0x0d, 0x47, 0xbc,
+	0xf6, 0x0c, 0x78, 0xad, 0xd3, 0xf2, 0x9a, 0x5a, 0xe2, 0xb5, 0xaf, 0xd6,
+	0xf1, 0x1a, 0xdb, 0x93, 0xd7, 0x9e, 0xb5, 0x65, 0x7c, 0x76, 0xe5, 0xd0,
+	0xf1, 0x76, 0x19, 0x7d, 0xe8, 0x2d, 0x32, 0x76, 0x3f, 0x61, 0x35, 0xdf,
+	0x85, 0xa2, 0x2d, 0x36, 0x5d, 0xed, 0x44, 0xff, 0x51, 0x0e, 0x11, 0x71,
+	0xed, 0x77, 0xcf, 0x48, 0xba, 0xc0, 0xf1, 0x1a, 0xe1, 0x47, 0x9f, 0x82,
+	0x7f, 0x71, 0x08, 0x30, 0xdd, 0x72, 0x5c, 0xd2, 0xae, 0xbc, 0x2c, 0x13,
+	0xc1, 0xe9, 0xed, 0xc6, 0x9e, 0x80, 0x2d, 0xa2, 0x6d, 0x9f, 0xac, 0xe4,
+	0xdf, 0x1e, 0x6a, 0x1f, 0x63, 0xb2, 0x22, 0x8c, 0x05, 0x30, 0x6e, 0x6e,
+	0xbf, 0x85, 0xca, 0xfc, 0xc7, 0x06, 0x7d, 0xe6, 0x45, 0xc7, 0x6c, 0xfb,
+	0xf8, 0x9e, 0xcf, 0xb0, 0x67, 0xf4, 0xd9, 0x45, 0xb6, 0x67, 0x3f, 0x09,
+	0x1d, 0x53, 0x2f, 0x56, 0xf8, 0x4d, 0x1c, 0xf8, 0x9f, 0x15, 0x7e, 0x5b,
+	0xeb, 0x37, 0xdb, 0x4c, 0x7c, 0x96, 0x7c, 0xf7, 0x5d, 0x27, 0x5f, 0x9a,
+	0xd3, 0xdf, 0x38, 0xc8, 0xf9, 0xf8, 0x5d, 0xe1, 0x33, 0xeb, 0xcf, 0x31,
+	0xde, 0x91, 0x4a, 0xa9, 0x63, 0xdb, 0x99, 0x7b, 0x70, 0x70, 0x8e, 0x75,
+	0x77, 0x5a, 0x1e, 0xdd, 0xa9, 0xfd, 0x0e, 0xda, 0x58, 0xa3, 0x93, 0x2f,
+	0x48, 0x91, 0xb6, 0xc9, 0xf0, 0x4e, 0xa7, 0x30, 0xfd, 0x73, 0xdb, 0x8d,
+	0xfd, 0x3c, 0xb0, 0x95, 0x79, 0x87, 0x59, 0xb5, 0x5a, 0x26, 0x9f, 0x92,
+	0x48, 0x26, 0xa7, 0x6f, 0xce, 0xc2, 0xce, 0xce, 0x1f, 0xd7, 0xdf, 0xab,
+	0x4a, 0x75, 0x2a, 0xce, 0xe9, 0x4e, 0xc8, 0xd7, 0x88, 0x16, 0x92, 0xf2,
+	0xd1, 0xe3, 0xa4, 0x07, 0x95, 0xd8, 0x28, 0x1f, 0xb1, 0xf4, 0x70, 0x46,
+	0x4a, 0x90, 0x3b, 0xc7, 0x8f, 0x7f, 0x40, 0xa6, 0x0f, 0xac, 0xa4, 0x87,
+	0xb1, 0x1a, 0x3d, 0x24, 0x60, 0x9f, 0x39, 0xf5, 0xf4, 0xf0, 0xf3, 0x4b,
+	0xf4, 0x30, 0xed, 0xfc, 0x6b, 0xe9, 0xe1, 0x86, 0x65, 0xf4, 0x30, 0xa1,
+	0xe9, 0x61, 0x68, 0x89, 0x1e, 0x26, 0x8e, 0x73, 0x5c, 0xbd, 0x37, 0xea,
+	0x2d, 0x38, 0x5c, 0xf3, 0x25, 0x5a, 0x48, 0x8d, 0xeb, 0x7c, 0xfd, 0x74,
+	0x81, 0xe7, 0x9b, 0x36, 0x28, 0xc6, 0x49, 0x6a, 0xeb, 0xbf, 0xf1, 0xdf,
+	0x74, 0xfd, 0xaf, 0xda, 0xfa, 0xff, 0x77, 0xfd, 0x33, 0x5b, 0x99, 0xbb,
+	0xcf, 0x33, 0xb0, 0x46, 0x1e, 0x47, 0xf4, 0x90, 0xdb, 0x6a, 0xf4, 0x02,
+	0xd7, 0x98, 0xcf, 0x90, 0x67, 0x90, 0x7f, 0xe7, 0x21, 0xff, 0x9e, 0x80,
+	0xfc, 0x7b, 0x7c, 0xd9, 0x9e, 0x40, 0xbf, 0x8d, 0x47, 0x84, 0x72, 0x24,
+	0xa8, 0xe1, 0x63, 0xa1, 0x8f, 0xf8, 0x30, 0xf9, 0x27, 0xcc, 0xfd, 0x5d,
+	0x8e, 0x13, 0x57, 0xe7, 0x1c, 0x3d, 0x1a, 0xd4, 0xe3, 0x84, 0x70, 0xbf,
+	0x5c, 0x37, 0x47, 0xfc, 0xae, 0xf0, 0xf9, 0x8c, 0xce, 0x23, 0x29, 0xea,
+	0x3d, 0x28, 0xe2, 0x85, 0x7b, 0x50, 0xc4, 0x89, 0xab, 0xed, 0xfd, 0x62,
+	0xa5, 0x49, 0xe7, 0xd0, 0x1f, 0x9e, 0x4b, 0xc8, 0x42, 0x82, 0x31, 0x3e,
+	0x7e, 0xe7, 0x90, 0x7e, 0xb3, 0x9f, 0x2c, 0x4a, 0x81, 0xb9, 0x72, 0xe0,
+	0xe9, 0x0d, 0x96, 0xb6, 0x19, 0x1b, 0xe4, 0x19, 0xe0, 0x68, 0x2f, 0xa2,
+	0xdb, 0xca, 0xba, 0x96, 0xba, 0x98, 0x25, 0xf0, 0x3e, 0x25, 0xa9, 0x5c,
+	0x1f, 0xee, 0x73, 0x1c, 0xfb, 0x13, 0x32, 0xf1, 0xe0, 0x87, 0x61, 0xcb,
+	0xbd, 0x1f, 0x3a, 0x87, 0xe7, 0xcf, 0xb8, 0xf7, 0xe0, 0x69, 0x18, 0x66,
+	0xf4, 0x77, 0xac, 0xe8, 0x03, 0x92, 0x1e, 0x92, 0x78, 0x3e, 0x63, 0xe3,
+	0x4a, 0x49, 0x29, 0x96, 0x5e, 0x94, 0x7c, 0x85, 0xdf, 0x5c, 0x7b, 0x09,
+	0xf7, 0xd7, 0x5b, 0x0f, 0xe3, 0x87, 0x0c, 0xeb, 0x3b, 0xd7, 0x66, 0x51,
+	0xb2, 0x15, 0x93, 0xe3, 0x52, 0x8b, 0x9b, 0x9c, 0x91, 0x63, 0xda, 0x7e,
+	0xce, 0xd8, 0xdc, 0x96, 0xf4, 0x70, 0x41, 0x8c, 0x0d, 0xfd, 0x39, 0xd8,
+	0xd0, 0x9f, 0xad, 0x66, 0xf5, 0x3e, 0xd6, 0xe3, 0xb0, 0xa1, 0x1f, 0x83,
+	0xee, 0xa1, 0xce, 0x49, 0x58, 0x9d, 0x33, 0xa1, 0x0e, 0x68, 0x9d, 0xf3,
+	0xe7, 0x5a, 0xe7, 0xbc, 0x7b, 0x95, 0xce, 0x39, 0xaa, 0x3a, 0x27, 0xa9,
+	0x73, 0x06, 0xd4, 0x7e, 0x87, 0xf6, 0xe2, 0x96, 0x35, 0x74, 0xce, 0x7b,
+	0xe4, 0x1d, 0xf6, 0xdd, 0x3d, 0xf2, 0xde, 0x3d, 0x7a, 0xef, 0xc6, 0x9b,
+	0x51, 0xfc, 0x76, 0x93, 0xd1, 0x41, 0xd7, 0xab, 0x6e, 0xbd, 0xe7, 0xfb,
+	0x95, 0x3a, 0x9d, 0xd3, 0xa1, 0xfa, 0x9c, 0x01, 0xdd, 0x86, 0xb1, 0x09,
+	0x3e, 0x07, 0x4e, 0x76, 0xb8, 0x09, 0xcf, 0x49, 0x89, 0x1d, 0xc7, 0xdc,
+	0xcd, 0xf7, 0xa5, 0x94, 0x79, 0xf7, 0x56, 0xfb, 0x4e, 0x45, 0xe5, 0xae,
+	0x29, 0xef, 0xb4, 0xe5, 0x46, 0x57, 0x75, 0xa8, 0x76, 0xad, 0xab, 0x76,
+	0x83, 0xa1, 0x66, 0xa0, 0x5f, 0x67, 0xca, 0x91, 0xce, 0xe2, 0x6f, 0xc6,
+	0x9e, 0x19, 0xa3, 0x88, 0x62, 0xd8, 0x29, 0xd4, 0xc1, 0x55, 0x8e, 0x6c,
+	0x4a, 0xfe, 0x86, 0xaf, 0x80, 0x6b, 0x0e, 0x78, 0xbd, 0x19, 0xfc, 0xf3,
+	0x1f, 0x4a, 0x8c, 0x81, 0xb6, 0xc9, 0x89, 0xa9, 0xfa, 0x77, 0xed, 0xf2,
+	0xae, 0xa9, 0x1d, 0x72, 0xfb, 0xe4, 0xd6, 0xa4, 0x34, 0xef, 0x94, 0x89,
+	0xc9, 0x29, 0x7d, 0xfe, 0x7d, 0xb3, 0xfe, 0x2e, 0x08, 0xbf, 0x97, 0x63,
+	0x64, 0xe4, 0x90, 0x63, 0x64, 0x64, 0x56, 0xd5, 0x6c, 0xd6, 0xa8, 0x4f,
+	0x7e, 0x8b, 0x64, 0x70, 0x32, 0xa9, 0xbf, 0xa5, 0x3a, 0x53, 0xbd, 0x4a,
+	0x7e, 0xfb, 0xa4, 0xba, 0x4b, 0xd5, 0xce, 0xf7, 0x6a, 0x9b, 0x75, 0x76,
+	0x99, 0xcd, 0xfa, 0xbf, 0x64, 0xe1, 0xbd, 0x71, 0xcc, 0x13, 0x34, 0x7c,
+	0xf5, 0xb7, 0xb8, 0x17, 0xda, 0x96, 0x90, 0x17, 0x65, 0x50, 0xe3, 0x8f,
+	0xf2, 0xb4, 0x05, 0x72, 0x70, 0x51, 0xeb, 0xd7, 0x2d, 0xa0, 0x41, 0xca,
+	0xd2, 0x0f, 0xca, 0x0b, 0x5a, 0x9e, 0x6d, 0xb1, 0xb6, 0xeb, 0x3c, 0xbf,
+	0x6d, 0x7d, 0x9c, 0xb6, 0xeb, 0x9f, 0xdb, 0x72, 0x96, 0xa5, 0x93, 0x8b,
+	0x42, 0x7d, 0x97, 0x80, 0x0c, 0xa5, 0x3c, 0x7d, 0xa3, 0xb6, 0xeb, 0x97,
+	0x6c, 0x1f, 0x94, 0x9f, 0x46, 0x76, 0xef, 0x76, 0xe6, 0x6d, 0x19, 0x9f,
+	0xa3, 0x78, 0xba, 0x9f, 0xcd, 0x5b, 0x3e, 0x53, 0xce, 0xe7, 0xf1, 0x7e,
+	0x33, 0xde, 0x93, 0xcf, 0x1e, 0xd7, 0x7c, 0xa6, 0xed, 0x13, 0xa7, 0xd7,
+	0xee, 0x2f, 0x2c, 0xed, 0x0d, 0x14, 0xc8, 0x67, 0xea, 0x84, 0x37, 0x6f,
+	0xe4, 0x01, 0xf3, 0x54, 0x7f, 0x03, 0xba, 0x83, 0x6d, 0x51, 0xfe, 0x70,
+	0x96, 0xbe, 0x2d, 0xfc, 0x9f, 0x8d, 0x78, 0x6e, 0xc3, 0xf3, 0x8c, 0xbc,
+	0xfb, 0x60, 0x5c, 0xcf, 0x7b, 0x02, 0xf3, 0x38, 0x7c, 0x1c, 0x73, 0x72,
+	0x8c, 0xed, 0xec, 0x9e, 0x75, 0xa5, 0xe1, 0x2c, 0xf9, 0x8e, 0x67, 0x6d,
+	0xc2, 0xf0, 0x50, 0x2f, 0xe9, 0x36, 0xed, 0x0d, 0xe9, 0xb3, 0xa5, 0xbb,
+	0x93, 0x31, 0xe0, 0xe4, 0x30, 0xd6, 0x63, 0xa2, 0xe4, 0x7b, 0x39, 0xc7,
+	0x4f, 0x62, 0x9e, 0xb0, 0x01, 0x3b, 0x61, 0x0b, 0x76, 0xc2, 0x0e, 0xec,
+	0x84, 0x1d, 0xb8, 0x49, 0x4e, 0x5d, 0xc3, 0x1c, 0x93, 0xc2, 0x75, 0xf0,
+	0xca, 0xe5, 0xaf, 0x75, 0x9c, 0xbe, 0xf1, 0xe6, 0x41, 0xf8, 0xec, 0xe2,
+	0xa5, 0x87, 0x99, 0x87, 0xbf, 0xe8, 0x35, 0xde, 0x3c, 0x24, 0x9d, 0xfd,
+	0x78, 0xdf, 0xff, 0xa2, 0x74, 0xdd, 0x7c, 0xab, 0xd3, 0x38, 0x3c, 0x08,
+	0x3c, 0x66, 0x9d, 0x74, 0x72, 0xc4, 0x99, 0xc7, 0x38, 0xb9, 0xdd, 0x31,
+	0x61, 0xdc, 0x72, 0x9e, 0xb1, 0x88, 0x9b, 0x3b, 0x63, 0x3d, 0xa9, 0x51,
+	0x27, 0x3d, 0xac, 0x62, 0xe9, 0xe1, 0x41, 0x27, 0xaa, 0xc7, 0x6f, 0xae,
+	0x42, 0xce, 0x00, 0xd6, 0xc3, 0xe5, 0x4f, 0x83, 0x9e, 0x8e, 0x48, 0xf1,
+	0x64, 0x8b, 0xcc, 0x95, 0x3a, 0xbd, 0x9c, 0x4a, 0xe8, 0xdc, 0x12, 0x75,
+	0x0a, 0x44, 0x7f, 0x36, 0x2e, 0x33, 0x93, 0x3b, 0x45, 0x69, 0xdb, 0x7d,
+	0x9b, 0xe4, 0xa6, 0x26, 0xe5, 0x62, 0x9f, 0xb4, 0x2a, 0xf4, 0xcf, 0x6f,
+	0xdc, 0xaa, 0x53, 0xdc, 0x4b, 0x8c, 0x78, 0x61, 0x3b, 0xf9, 0x64, 0x12,
+	0x38, 0x04, 0xdd, 0x32, 0xc6, 0xdb, 0x24, 0x94, 0x7b, 0x1f, 0xd0, 0xf1,
+	0x53, 0xc6, 0x6c, 0xeb, 0xf7, 0x1e, 0xc8, 0x1f, 0xf1, 0x35, 0xf9, 0x63,
+	0xb6, 0xcc, 0x7d, 0x1a, 0x29, 0xb8, 0x8c, 0x11, 0xfb, 0xf8, 0x3d, 0xcd,
+	0xba, 0x4d, 0x32, 0xd1, 0x57, 0xb0, 0x79, 0x1e, 0x7f, 0x9e, 0x64, 0x0e,
+	0x31, 0x71, 0x32, 0xda, 0x47, 0x5e, 0x5f, 0xb9, 0xb7, 0x11, 0xaf, 0x93,
+	0x07, 0x8e, 0x2c, 0x4c, 0x46, 0x7b, 0x21, 0xec, 0x0f, 0xcf, 0xd3, 0x46,
+	0xde, 0xe6, 0x56, 0xb5, 0x23, 0x5c, 0xdc, 0xaf, 0x5c, 0x2e, 0x63, 0x95,
+	0x4f, 0x99, 0xea, 0x69, 0xf9, 0x7a, 0xa6, 0x6a, 0x64, 0xeb, 0x74, 0x35,
+	0xd2, 0x2d, 0x71, 0xa3, 0x4b, 0x57, 0xe9, 0x13, 0x13, 0xcd, 0xac, 0xe9,
+	0x13, 0xea, 0x45, 0x25, 0xef, 0x9b, 0xdb, 0x26, 0xee, 0xc3, 0xb2, 0x38,
+	0xe1, 0x7f, 0x7a, 0x3b, 0x73, 0x35, 0x26, 0x82, 0x37, 0xa3, 0x1f, 0x9b,
+	0xae, 0xa4, 0x3e, 0x1c, 0x51, 0x8d, 0xb8, 0x6f, 0xd6, 0xf4, 0x07, 0x9e,
+	0xc2, 0xb3, 0xf1, 0x13, 0x3e, 0x07, 0x3f, 0xe1, 0xb3, 0xd0, 0x75, 0xe7,
+	0xe1, 0x27, 0x3c, 0x01, 0x3f, 0xe1, 0x71, 0xf8, 0x09, 0x8f, 0x41, 0x4f,
+	0xd6, 0xfb, 0x07, 0xe3, 0xcb, 0xfc, 0x83, 0x50, 0xf3, 0x3f, 0xe3, 0x81,
+	0x4f, 0xd4, 0xf9, 0x06, 0x87, 0x8c, 0xbe, 0x82, 0xdf, 0x6f, 0xf8, 0xa8,
+	0x43, 0xdd, 0xa4, 0xf5, 0xa3, 0xc9, 0xdb, 0x1d, 0x5e, 0xd2, 0x57, 0x1d,
+	0xca, 0xe8, 0xab, 0x99, 0x9a, 0xbe, 0x32, 0x7c, 0xf4, 0xf0, 0xa4, 0xc4,
+	0xfc, 0xc9, 0xf9, 0x5c, 0xb0, 0x57, 0xf3, 0x50, 0xab, 0xbf, 0x53, 0x62,
+	0x0f, 0xa8, 0xb6, 0x06, 0xc9, 0xd9, 0x67, 0xd0, 0xd7, 0x89, 0x4f, 0xa3,
+	0xaf, 0xeb, 0x24, 0xaf, 0xed, 0xb3, 0xcb, 0xe3, 0xfb, 0xb1, 0x15, 0xf8,
+	0x2e, 0x96, 0x27, 0x34, 0xce, 0xef, 0xaf, 0x70, 0x9f, 0xa5, 0x45, 0xc6,
+	0x2b, 0x11, 0xce, 0x79, 0x9e, 0x95, 0xb9, 0x18, 0xed, 0x12, 0x7b, 0x78,
+	0x1b, 0xcf, 0x59, 0xa9, 0x7c, 0xb0, 0x5e, 0xe7, 0xb0, 0x9c, 0xea, 0x93,
+	0x64, 0xbe, 0x8f, 0xb4, 0x7a, 0x9f, 0xcc, 0xe8, 0xb5, 0xd8, 0x26, 0x0d,
+	0x0f, 0xd3, 0x46, 0x89, 0xf6, 0xf3, 0xde, 0x7f, 0xa5, 0xfd, 0xe6, 0x6a,
+	0xdc, 0xd4, 0x13, 0x39, 0xa2, 0xd7, 0x6b, 0x5a, 0xe7, 0x19, 0xde, 0x34,
+	0xc7, 0xb8, 0x3c, 0xbf, 0x6f, 0xc5, 0x98, 0xfc, 0xbf, 0x66, 0xfd, 0x7e,
+	0xf9, 0x4a, 0x63, 0xcf, 0x6c, 0xb6, 0x76, 0x8c, 0x89, 0x53, 0xad, 0x6d,
+	0xc3, 0xb0, 0x9f, 0xfa, 0x6f, 0x32, 0xee, 0x70, 0xc6, 0x27, 0x77, 0x3a,
+	0xc5, 0x49, 0xee, 0x65, 0xdb, 0xbf, 0xd1, 0xe1, 0xed, 0x77, 0x0e, 0xfb,
+	0x3b, 0x50, 0xc6, 0x98, 0x25, 0x63, 0x36, 0xf7, 0x5f, 0xc9, 0x18, 0x6d,
+	0xce, 0xe7, 0xd8, 0x2c, 0xdb, 0xe1, 0x4c, 0x4c, 0x76, 0xc2, 0x37, 0xe7,
+	0xb9, 0x2a, 0xbe, 0x1f, 0xe2, 0xda, 0x41, 0x07, 0x7b, 0xfa, 0xcc, 0xee,
+	0x98, 0x5c, 0x65, 0x63, 0xd0, 0xd4, 0xc3, 0x3f, 0xbd, 0x6c, 0xef, 0xf6,
+	0x28, 0xf4, 0xd8, 0x2d, 0x90, 0x47, 0xd4, 0xc3, 0x47, 0xe5, 0x6d, 0x96,
+	0x9e, 0x97, 0xeb, 0xe1, 0x4b, 0xc2, 0x38, 0x71, 0x2f, 0xde, 0x15, 0xc2,
+	0x38, 0xe8, 0xe1, 0x58, 0x9d, 0xaf, 0x46, 0xbf, 0xaf, 0x29, 0x63, 0xf6,
+	0xc3, 0x96, 0xfb, 0x7d, 0x90, 0x03, 0x89, 0xc8, 0xcf, 0x6b, 0x5c, 0xda,
+	0xaf, 0xdd, 0x6f, 0xdb, 0x4e, 0x04, 0x7f, 0x44, 0x1c, 0xa5, 0x8e, 0xca,
+	0x2f, 0x42, 0xa7, 0x31, 0x07, 0xe4, 0x2f, 0x34, 0xce, 0x44, 0x91, 0xf6,
+	0x36, 0x6b, 0x18, 0xad, 0x9c, 0x4f, 0x45, 0x39, 0x1c, 0x45, 0xdb, 0x76,
+	0xcc, 0xee, 0xc9, 0x17, 0xe5, 0xeb, 0x8c, 0x73, 0xa6, 0x06, 0x63, 0xeb,
+	0xf9, 0x3d, 0x46, 0xb4, 0xfd, 0x45, 0xed, 0xb7, 0x67, 0x25, 0xea, 0x8b,
+	0xcf, 0x0d, 0x75, 0x7d, 0xd3, 0x8e, 0xe2, 0x7d, 0xe5, 0x39, 0xb2, 0xa7,
+	0xf5, 0x3e, 0xa3, 0xf9, 0x5e, 0x42, 0xc4, 0x27, 0xe4, 0x9d, 0x94, 0x3e,
+	0xeb, 0xe4, 0x3f, 0x4c, 0xbb, 0x87, 0x7b, 0xb0, 0xde, 0xfc, 0x78, 0xf0,
+	0x11, 0xfd, 0xcd, 0xc0, 0x69, 0x11, 0xa7, 0x18, 0xdc, 0xa6, 0x73, 0x4f,
+	0x8a, 0x3a, 0xd6, 0x5c, 0xc0, 0xbd, 0xe6, 0xa3, 0x76, 0x3c, 0xcc, 0xbf,
+	0xc3, 0xc1, 0xb2, 0x3c, 0x60, 0xa3, 0x0e, 0xa1, 0xec, 0x4d, 0x48, 0xc7,
+	0x89, 0x5f, 0xd0, 0xbc, 0xb0, 0x05, 0xbe, 0xc0, 0xc0, 0x09, 0xe8, 0xea,
+	0x13, 0x49, 0x19, 0x3a, 0xa1, 0x75, 0x63, 0x76, 0x75, 0xac, 0xa0, 0xc7,
+	0x73, 0x9d, 0x77, 0xe9, 0x73, 0x6c, 0x6f, 0x3d, 0x11, 0x93, 0x63, 0x89,
+	0x1e, 0xaf, 0xcb, 0x79, 0xb7, 0xd5, 0x85, 0x51, 0x0c, 0xbb, 0x05, 0xed,
+	0x5f, 0x2f, 0x8e, 0x1d, 0xc5, 0xaf, 0x63, 0x32, 0x7d, 0xb0, 0x1d, 0xb0,
+	0x75, 0x6e, 0x33, 0x67, 0x90, 0xb1, 0x56, 0xfa, 0x1b, 0xf7, 0x6e, 0x92,
+	0xb2, 0xac, 0x03, 0xb0, 0x0c, 0x9e, 0xa0, 0x3e, 0xf3, 0x35, 0x8f, 0x03,
+	0x06, 0xaf, 0x41, 0xfb, 0x21, 0xe4, 0xcb, 0xb7, 0x88, 0xff, 0x00, 0x64,
+	0xdc, 0x89, 0xb8, 0x74, 0x9d, 0x68, 0x91, 0x5d, 0x27, 0xe8, 0x87, 0xd4,
+	0xfb, 0xa5, 0xb4, 0x4b, 0xe7, 0x30, 0xc7, 0x77, 0x6a, 0x39, 0xc9, 0x3d,
+	0xcd, 0xdb, 0xc9, 0xbb, 0xa8, 0x9b, 0x87, 0xcd, 0x9c, 0x3b, 0xe1, 0xe9,
+	0x3d, 0xd2, 0x1c, 0xe6, 0x9c, 0xaf, 0x78, 0x18, 0xc7, 0xc8, 0x9c, 0x22,
+	0xfd, 0x94, 0xe1, 0x6d, 0xc0, 0xf1, 0x31, 0xcb, 0x3b, 0x43, 0xdb, 0x2c,
+	0x8f, 0xfe, 0x88, 0xbc, 0x77, 0xf3, 0x36, 0x23, 0x3b, 0x7f, 0x76, 0x1b,
+	0x73, 0x93, 0xb6, 0xf8, 0xbc, 0x37, 0x69, 0x7b, 0xc2, 0xc8, 0xd0, 0xd7,
+	0xe2, 0x45, 0x01, 0x8e, 0xa2, 0x7d, 0x29, 0x7d, 0x96, 0x2f, 0xbc, 0x18,
+	0xe8, 0xf3, 0x2b, 0xc1, 0x02, 0xf3, 0x08, 0xf5, 0x77, 0x14, 0x6a, 0xdf,
+	0x5b, 0xd9, 0x5b, 0x65, 0x9c, 0xfc, 0x89, 0xe8, 0x6f, 0xa9, 0xd4, 0xe5,
+	0x1d, 0xd6, 0xef, 0x81, 0x31, 0xd6, 0xb4, 0x94, 0x1b, 0x14, 0x4e, 0xea,
+	0xef, 0x21, 0x3d, 0xeb, 0x5c, 0x2a, 0x5d, 0x70, 0xbe, 0x39, 0x25, 0xa1,
+	0xeb, 0x7f, 0xdf, 0xf9, 0xb6, 0xcf, 0x3d, 0xf3, 0x2f, 0x3b, 0xdf, 0x2a,
+	0xf9, 0xe0, 0xc3, 0x0b, 0x98, 0xc7, 0x2b, 0xce, 0x77, 0xb0, 0xbe, 0x47,
+	0xca, 0xd9, 0xb4, 0x67, 0x63, 0xe2, 0x17, 0x4a, 0xaf, 0x38, 0x5f, 0xaa,
+	0xc5, 0x93, 0xfa, 0x23, 0x1a, 0x39, 0xca, 0x77, 0x15, 0xbc, 0xab, 0xe8,
+	0xfd, 0x1f, 0x67, 0x76, 0xca, 0xe6, 0x97, 0x68, 0x3e, 0x9e, 0x5f, 0xda,
+	0x97, 0x19, 0xd6, 0x7b, 0x15, 0xcf, 0x38, 0xb3, 0x73, 0x9f, 0xdb, 0x66,
+	0xf2, 0x8c, 0x2e, 0xe0, 0x9d, 0xc9, 0xb9, 0x9c, 0x99, 0xbb, 0x80, 0x3a,
+	0x4f, 0x3b, 0x33, 0x3a, 0xfe, 0xc5, 0x76, 0x17, 0x9c, 0xe9, 0xb9, 0xa7,
+	0x9d, 0x39, 0xbd, 0x07, 0x7d, 0xd1, 0x79, 0x74, 0x8a, 0x7d, 0x5f, 0x44,
+	0x9d, 0x79, 0xe7, 0x14, 0xfa, 0x9b, 0x9b, 0xe2, 0x79, 0xdc, 0x4e, 0xd8,
+	0x05, 0xfc, 0x1b, 0x45, 0xfc, 0x1e, 0xc7, 0x33, 0xce, 0xdc, 0x52, 0xbf,
+	0x0b, 0xe8, 0x87, 0x75, 0x49, 0x8b, 0x1c, 0xf7, 0x19, 0xf4, 0xbf, 0x7a,
+	0xaf, 0x6a, 0x35, 0x4e, 0x9e, 0x07, 0x4e, 0x5e, 0xb4, 0x38, 0x79, 0xd5,
+	0xe2, 0xe4, 0xb9, 0x3a, 0x9c, 0x88, 0x5a, 0x8e, 0x93, 0x57, 0x81, 0x13,
+	0x51, 0x6b, 0xe3, 0x04, 0xef, 0x2a, 0x78, 0xa7, 0x71, 0xf2, 0xd2, 0x0a,
+	0x9c, 0x2c, 0x2e, 0xc5, 0xe5, 0x0d, 0x4e, 0x5e, 0x00, 0x4e, 0x7e, 0x60,
+	0x61, 0x7f, 0xd1, 0xe2, 0x04, 0xf7, 0xb9, 0x17, 0x51, 0xe7, 0xa5, 0x3a,
+	0x9c, 0xbc, 0x08, 0x9c, 0xbc, 0x64, 0x71, 0xf2, 0x6d, 0x8b, 0x93, 0x6f,
+	0xa3, 0xce, 0x22, 0x70, 0x72, 0x69, 0x0d, 0x9c, 0xbc, 0x00, 0x9c, 0x44,
+	0xfd, 0x5e, 0x42, 0x3f, 0xdf, 0xae, 0xc3, 0xc9, 0x0b, 0x6b, 0xe0, 0x84,
+	0x7b, 0xb1, 0x51, 0x4e, 0xf7, 0x99, 0xd7, 0xc9, 0xe9, 0x5e, 0x7c, 0x03,
+	0x39, 0xdd, 0xac, 0x73, 0x46, 0x6a, 0x7f, 0xbb, 0x62, 0xc2, 0xe6, 0xa8,
+	0x99, 0x5c, 0xc0, 0xda, 0x37, 0x9b, 0x3a, 0xc1, 0xe7, 0xc5, 0x02, 0xbc,
+	0x11, 0x9d, 0x53, 0xea, 0xee, 0x19, 0x03, 0xaf, 0xbd, 0x5b, 0x0e, 0x9f,
+	0x6c, 0x3c, 0x96, 0xb7, 0x65, 0xfe, 0x9e, 0xce, 0x82, 0x52, 0x7c, 0x17,
+	0xe5, 0x24, 0xd0, 0x2f, 0x69, 0xe0, 0xb7, 0x0a, 0xbb, 0xb3, 0x52, 0xbf,
+	0x27, 0x3d, 0xc5, 0x6f, 0x34, 0x71, 0x7f, 0x8c, 0x7f, 0x67, 0x23, 0xc5,
+	0x3c, 0xab, 0xa2, 0x86, 0x37, 0x0d, 0xfd, 0xd1, 0xaf, 0x73, 0xab, 0xf8,
+	0x37, 0x82, 0x62, 0xf0, 0xfb, 0x47, 0xfb, 0x68, 0x2b, 0x67, 0xec, 0x99,
+	0xb0, 0x40, 0x9f, 0x53, 0xa9, 0xf1, 0x4f, 0xfd, 0x79, 0x68, 0xf2, 0x5d,
+	0x8d, 0x6e, 0x8e, 0x2c, 0x7d, 0x77, 0xf0, 0xb4, 0x3c, 0xa5, 0x63, 0xc5,
+	0xcd, 0xfa, 0xef, 0x2b, 0x9c, 0x09, 0x4c, 0x8c, 0x76, 0x41, 0xc7, 0x68,
+	0x05, 0xde, 0xf8, 0xb8, 0x8d, 0xd3, 0x76, 0xf5, 0xbf, 0xb4, 0x14, 0xa3,
+	0xad, 0xcf, 0x67, 0x31, 0xfb, 0xeb, 0xb9, 0xc9, 0x39, 0x9d, 0xa3, 0x33,
+	0xc8, 0xef, 0x6f, 0x40, 0x46, 0x8c, 0x4d, 0x57, 0x64, 0xfc, 0x41, 0x3e,
+	0x53, 0xbf, 0xc5, 0xa0, 0xc3, 0x28, 0xc3, 0x0b, 0x92, 0xeb, 0x67, 0x99,
+	0x69, 0x33, 0xa8, 0xfd, 0xe5, 0xd3, 0x32, 0xb0, 0x34, 0x3e, 0xf1, 0xfb,
+	0x89, 0xba, 0xef, 0x60, 0xd3, 0xe6, 0xc9, 0x3a, 0xb9, 0x2a, 0xdf, 0x47,
+	0x7b, 0xe4, 0x9f, 0xb0, 0xdf, 0x0a, 0xe4, 0xfb, 0xfa, 0x6f, 0xbf, 0x6a,
+	0xd1, 0x81, 0xdf, 0xfc, 0xbe, 0xda, 0x84, 0x33, 0x88, 0x36, 0xf3, 0x5e,
+	0xcb, 0xb0, 0xca, 0xdc, 0x38, 0xcc, 0x73, 0x73, 0x33, 0xab, 0xbe, 0x9d,
+	0x5d, 0xd3, 0x8b, 0x45, 0xbd, 0xa6, 0xcc, 0xcf, 0x2a, 0x80, 0x16, 0x35,
+	0x6d, 0x69, 0xfa, 0x3f, 0xbc, 0xa4, 0x2f, 0xa9, 0x67, 0xcd, 0xb7, 0x67,
+	0x8c, 0xbe, 0x4c, 0x27, 0x07, 0x31, 0xbe, 0xfe, 0x1b, 0x0d, 0xf6, 0x5c,
+	0x6f, 0x7e, 0xee, 0x2e, 0xad, 0xeb, 0x27, 0x82, 0x6c, 0xca, 0x95, 0x35,
+	0xea, 0x4e, 0xd6, 0xd5, 0xd5, 0xf3, 0xf6, 0xe4, 0xb7, 0xb0, 0x36, 0xbf,
+	0x51, 0xae, 0xc8, 0xc0, 0xd4, 0x5f, 0xc1, 0x7f, 0x4c, 0xca, 0x6f, 0x96,
+	0x1f, 0x01, 0xbd, 0x16, 0xb6, 0xd8, 0x6f, 0x35, 0xe5, 0x00, 0x37, 0xbf,
+	0xbd, 0xa2, 0xf3, 0x89, 0x63, 0xbf, 0x0d, 0xba, 0xf8, 0xcc, 0x23, 0x1c,
+	0x03, 0xb0, 0xc4, 0x60, 0xdb, 0xc3, 0x4e, 0x98, 0x7e, 0x44, 0xe7, 0xce,
+	0x5d, 0x5f, 0x79, 0x44, 0xc7, 0x2c, 0x86, 0x2a, 0xed, 0xb2, 0xb7, 0xd2,
+	0x22, 0xfb, 0xa0, 0x17, 0xf6, 0x55, 0x7c, 0x5c, 0x71, 0x79, 0x67, 0xc5,
+	0xac, 0xd3, 0x07, 0x2b, 0x5c, 0xef, 0x3d, 0x32, 0x73, 0x72, 0xe5, 0xf7,
+	0x3e, 0xe7, 0x0b, 0xd1, 0xdf, 0x73, 0x52, 0x8a, 0xf9, 0x65, 0xa4, 0x25,
+	0x5c, 0xe5, 0xf4, 0xb1, 0x79, 0x8d, 0x07, 0x66, 0xb8, 0xa6, 0x27, 0x17,
+	0x85, 0x79, 0xfa, 0xfc, 0x1b, 0x4e, 0x7f, 0xb9, 0x9d, 0xe7, 0xa6, 0xf9,
+	0x2d, 0xaf, 0xa1, 0x6a, 0x94, 0x37, 0xbe, 0x56, 0xce, 0x38, 0xec, 0xfc,
+	0x3d, 0x51, 0x8e, 0x5f, 0x9c, 0x39, 0xe3, 0xd2, 0x71, 0xb6, 0x05, 0xf7,
+	0xef, 0x6e, 0xd7, 0x67, 0x9b, 0xcf, 0x8a, 0x2d, 0xd3, 0xf9, 0xe4, 0x78,
+	0x5e, 0xf9, 0xbd, 0xb6, 0x88, 0x1f, 0x6a, 0x7f, 0xf7, 0x40, 0xe4, 0xff,
+	0x02, 0x06, 0x86, 0xe5, 0x0a, 0xd4, 0x6f, 0x00, 0x00, 0x00 };
 
 static const u32 bnx2_CP_b09FwData[(0x0/4) + 1] = { 0x0 };
 static const u32 bnx2_CP_b09FwRodata[(0x118/4) + 1] = {
-	0x0800061c, 0x0800083c, 0x08000780, 0x080007a8, 0x080007d0, 0x080007f8,
-	0x08000654, 0x08000640, 0x08000864, 0x08000864, 0x08000670, 0x0800068c,
-	0x0800068c, 0x08000864, 0x080006a4, 0x080006b8, 0x08000864, 0x080006cc,
-	0x08000864, 0x08000864, 0x080006e0, 0x08000864, 0x08000864, 0x08000864,
-	0x08000864, 0x08000864, 0x08000864, 0x08000864, 0x08000864, 0x08000864,
-	0x08000864, 0x080006f4, 0x08000864, 0x08000708, 0x0800071c, 0x08000730,
-	0x08000864, 0x08000744, 0x08000758, 0x0800076c, 0x08003200, 0x08003218,
-	0x08003228, 0x08003238, 0x08003250, 0x08003268, 0x08003278, 0x08003288,
-	0x080032a8, 0x080032b8, 0x080032c8, 0x08003358, 0x08003298, 0x080032d8,
-	0x080032e8, 0x08003300, 0x08003320, 0x08003358, 0x08003338, 0x08003338,
-	0x080050d4, 0x080050d4, 0x080050d4, 0x080050d4, 0x080050d4, 0x080050fc,
-	0x080050fc, 0x08005124, 0x08005174, 0x08005144, 0x00000000 };
+	0x0800069c, 0x080008bc, 0x08000800, 0x08000828, 0x08000850, 0x08000878,
+	0x080006d4, 0x080006c0, 0x080008e4, 0x080008e4, 0x080006f0, 0x0800070c,
+	0x0800070c, 0x080008e4, 0x08000724, 0x08000738, 0x080008e4, 0x0800074c,
+	0x080008e4, 0x080008e4, 0x08000760, 0x080008e4, 0x080008e4, 0x080008e4,
+	0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4,
+	0x080008e4, 0x08000774, 0x080008e4, 0x08000788, 0x0800079c, 0x080007b0,
+	0x080008e4, 0x080007c4, 0x080007d8, 0x080007ec, 0x080032e8, 0x08003300,
+	0x08003310, 0x08003320, 0x08003338, 0x08003350, 0x08003360, 0x08003370,
+	0x08003390, 0x080033a0, 0x080033b0, 0x08003440, 0x08003380, 0x080033c0,
+	0x080033d0, 0x080033e8, 0x08003408, 0x08003440, 0x08003420, 0x08003420,
+	0x080051bc, 0x080051bc, 0x080051bc, 0x080051bc, 0x080051bc, 0x080051e4,
+	0x080051e4, 0x0800520c, 0x0800525c, 0x0800522c, 0x00000000 };
 
 static struct fw_info bnx2_cp_fw_09 = {
+	/* Firmware version:  3.7.1 */
 	.ver_major			= 0x3,
-	.ver_minor			= 0x4,
-	.ver_fix			= 0x3,
+	.ver_minor			= 0x7,
+	.ver_fix			= 0x1,
 
 	.start_addr			= 0x0800006c,
 
 	.text_addr			= 0x08000000,
-	.text_len			= 0x6ee8,
+	.text_len			= 0x6fd0,
 	.text_index			= 0x0,
 	.gz_text			= bnx2_CP_b09FwText,
 	.gz_text_len			= sizeof(bnx2_CP_b09FwText),
 
-	.data_addr			= 0x08007020,
+	.data_addr			= 0x08007100,
 	.data_len			= 0x0,
 	.data_index			= 0x0,
 	.data				= bnx2_CP_b09FwData,
 
-	.sbss_addr			= 0x08007024,
-	.sbss_len			= 0xa1,
+	.sbss_addr			= 0x08007104,
+	.sbss_len			= 0xa9,
 	.sbss_index			= 0x0,
 
-	.bss_addr			= 0x080070d0,
+	.bss_addr			= 0x080071b0,
 	.bss_len			= 0x3b0,
 	.bss_index			= 0x0,
 
-	.rodata_addr			= 0x08006ee8,
+	.rodata_addr			= 0x08006fd0,
 	.rodata_len			= 0x118,
 	.rodata_index			= 0x0,
 	.rodata				= bnx2_CP_b09FwRodata,
 };
 
 static u8 bnx2_RXP_b09FwText[] = {
-/*	0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
-								    0xec, 0x5c,
-	0x5d, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0xf3, 0x43, 0x6a, 0x49, 0xf1, 0x67,
-	0xb8, 0x5c, 0xb1, 0x2b, 0x99, 0x96, 0x77, 0xc9, 0x91, 0xc8, 0x58, 0x8a,
-	0x31, 0xa2, 0x09, 0x5b, 0x48, 0x17, 0xf6, 0x76, 0x76, 0x25, 0xb1, 0xb1,
-	0x03, 0x53, 0xb6, 0x62, 0x07, 0x45, 0x6a, 0xb0, 0x4b, 0xb9, 0x0e, 0x8c,
-	0x06, 0x90, 0xff, 0x52, 0xbf, 0xb0, 0xde, 0x2c, 0xa9, 0x58, 0x4d, 0x17,
-	0x9c, 0xb5, 0x4d, 0x9b, 0x0e, 0x60, 0xb7, 0x0b, 0x92, 0x12, 0xf5, 0xb0,
-	0xd0, 0xb2, 0xa9, 0xdb, 0xea, 0xc1, 0x8e, 0x09, 0x56, 0xb1, 0x53, 0xa0,
-	0x2d, 0x5c, 0x27, 0x69, 0xfc, 0x10, 0x14, 0xaa, 0xec, 0xc4, 0x42, 0xd1,
-	0xa2, 0x02, 0x12, 0xd8, 0x29, 0x22, 0x7b, 0xfa, 0x7d, 0x77, 0x66, 0xc8,
-	0x25, 0x2d, 0xdb, 0x41, 0x1f, 0xfa, 0xd2, 0xbd, 0xc0, 0x62, 0xee, 0xbd,
-	0x73, 0xee, 0xb9, 0xe7, 0x9e, 0xff, 0x73, 0x87, 0xd2, 0x1f, 0x74, 0x48,
-	0xbb, 0x84, 0xad, 0x13, 0xbf, 0xd4, 0x89, 0x27, 0x1e, 0xb9, 0x69, 0xf4,
-	0xa6, 0x9b, 0xd1, 0xbd, 0xd9, 0x30, 0x4c, 0x23, 0x9a, 0x6f, 0xb6, 0x66,
-	0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
-	0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
-	0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
-	0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
-	0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
-	0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0xfb, 0xff, 0xde,
-	0x0c, 0x11, 0x8b, 0xcf, 0xce, 0xf0, 0x27, 0x31, 0x3d, 0x23, 0x0f, 0xb9,
-	0xb6, 0xc4, 0x8c, 0xcc, 0xd5, 0xa9, 0x49, 0x5b, 0x24, 0x5b, 0xdb, 0x97,
-	0xca, 0xc9, 0x87, 0x7e, 0x31, 0x61, 0x0a, 0xe7, 0xaf, 0xcf, 0x5c, 0xfd,
-	0x8b, 0x57, 0x6f, 0x4d, 0x5f, 0xa9, 0x1a, 0x12, 0xb3, 0x32, 0x33, 0x07,
-	0xac, 0xbd, 0x12, 0xeb, 0xc7, 0x9a, 0x17, 0x87, 0xfe, 0xa9, 0x4b, 0xba,
-	0x22, 0x5c, 0x22, 0x0b, 0xe5, 0xb4, 0x73, 0x18, 0xcf, 0x33, 0xb5, 0x7d,
-	0xce, 0x9a, 0x98, 0xb2, 0x6a, 0x05, 0x3b, 0x96, 0xca, 0x1a, 0xf1, 0x48,
-	0xa9, 0x16, 0x93, 0x8b, 0xea, 0xdf, 0x79, 0x60, 0x4f, 0x9b, 0xfd, 0xf3,
-	0x9a, 0x5b, 0xf7, 0xfd, 0xd3, 0x8e, 0xef, 0xbf, 0x8e, 0xdf, 0x7b, 0x0e,
-	0xc6, 0xde, 0x47, 0x7e, 0xd6, 0x34, 0x44, 0xb7, 0xff, 0x4c, 0x73, 0x17,
-	0x5b, 0xa5, 0x34, 0x2f, 0x32, 0xed, 0xc5, 0xe4, 0x94, 0x57, 0xd4, 0xf2,
-	0xf5, 0xb2, 0x76, 0x68, 0x79, 0x56, 0x3b, 0xbc, 0x7c, 0x4a, 0x3b, 0xb2,
-	0x5c, 0xd1, 0xdc, 0x65, 0x29, 0xea, 0x07, 0x3a, 0x24, 0x6b, 0x9d, 0xd5,
-	0x72, 0xf5, 0x3e, 0xcd, 0x9d, 0xbf, 0xea, 0xbb, 0x4e, 0xda, 0xfa, 0x3d,
-	0x31, 0xb3, 0xdc, 0xcf, 0x2d, 0xfb, 0x18, 0x9b, 0x92, 0x4d, 0xf8, 0xbe,
-	0x9e, 0xf1, 0x9f, 0x74, 0x47, 0x6d, 0x4b, 0xd7, 0x62, 0x52, 0xaa, 0xb7,
-	0x03, 0x6f, 0x87, 0x96, 0x9b, 0x37, 0xb5, 0xbc, 0xe7, 0xbf, 0xe6, 0x3a,
-	0xd2, 0x6f, 0x88, 0xef, 0xcf, 0x38, 0x7b, 0x92, 0xc7, 0xe5, 0x0c, 0xf0,
-	0xd6, 0x80, 0x4f, 0x2c, 0x3d, 0x43, 0xfa, 0x22, 0x9a, 0x8b, 0x5a, 0x6e,
-	0x28, 0xa2, 0x4f, 0x52, 0xa4, 0xbf, 0xb0, 0xa4, 0x83, 0xce, 0xed, 0x52,
-	0xa8, 0x5a, 0x32, 0xb1, 0xb4, 0x15, 0xfe, 0xa2, 0xff, 0xea, 0x50, 0x42,
-	0xfe, 0xb2, 0x9e, 0x3e, 0x55, 0x04, 0x2f, 0x66, 0xbc, 0x94, 0x80, 0xcf,
-	0x59, 0x77, 0xb4, 0x5f, 0x5e, 0xab, 0x27, 0xe5, 0xbb, 0x75, 0x3b, 0x59,
-	0x92, 0x6d, 0x52, 0x48, 0x58, 0xb2, 0x82, 0x35, 0xd3, 0xa0, 0x43, 0xb7,
-	0x6d, 0xab, 0x04, 0xd8, 0x52, 0xfd, 0x27, 0xfc, 0xb7, 0x32, 0xd6, 0xe4,
-	0xa8, 0x5a, 0x53, 0x04, 0xdd, 0x21, 0x2c, 0xcf, 0xa1, 0x60, 0xd5, 0x59,
-	0x02, 0x58, 0x29, 0x4e, 0x8e, 0x62, 0xae, 0xfe, 0x85, 0x50, 0x16, 0xad,
-	0x38, 0x2f, 0x9f, 0xbb, 0x71, 0xbe, 0xdd, 0xe0, 0x89, 0x24, 0x74, 0xd9,
-	0x93, 0x2c, 0x60, 0x66, 0xba, 0xde, 0x81, 0x31, 0x69, 0xf1, 0xfd, 0x23,
-	0x8e, 0x58, 0x25, 0xa7, 0x1b, 0xbc, 0x4b, 0x49, 0xc9, 0xe9, 0xc2, 0x9a,
-	0x16, 0xb1, 0x6c, 0x9e, 0x81, 0x78, 0xdb, 0x30, 0xef, 0x77, 0x1a, 0x19,
-	0xdf, 0x9f, 0x1c, 0x95, 0xae, 0x60, 0x6e, 0x1f, 0x70, 0x98, 0x32, 0x31,
-	0xae, 0x01, 0xee, 0x03, 0xd2, 0x17, 0x8b, 0x67, 0xd8, 0xe7, 0x73, 0x54,
-	0xdc, 0xd9, 0x54, 0xb8, 0x6f, 0x87, 0x94, 0xbc, 0xeb, 0xc3, 0x3e, 0x78,
-	0xed, 0xe1, 0xcc, 0xce, 0x4e, 0x8c, 0xb5, 0x1b, 0x80, 0xc7, 0x29, 0x09,
-	0xf7, 0xd8, 0x21, 0x6b, 0x09, 0xd1, 0x2f, 0x39, 0xbd, 0x21, 0x5c, 0x17,
-	0x68, 0x8d, 0x64, 0xde, 0x2e, 0x33, 0xf3, 0xad, 0x72, 0x72, 0x9e, 0xbc,
-	0x2d, 0x43, 0x16, 0x78, 0xde, 0x52, 0xd4, 0xb2, 0xf5, 0x53, 0xe8, 0x9b,
-	0x32, 0x69, 0xfb, 0xaf, 0xcd, 0x38, 0xb3, 0x5a, 0x6e, 0xf9, 0x8c, 0x96,
-	0x87, 0x0e, 0x1c, 0x5a, 0x3e, 0xaf, 0x1d, 0xae, 0xaf, 0x76, 0x4a, 0x7b,
-	0x1a, 0xda, 0x66, 0xca, 0x49, 0x4f, 0x13, 0xd2, 0xbb, 0x00, 0x7e, 0x65,
-	0x2d, 0x70, 0xde, 0xee, 0xd2, 0x0e, 0x03, 0x57, 0x8b, 0xfd, 0xad, 0x0e,
-	0xe9, 0x32, 0x64, 0x9b, 0x1d, 0xc1, 0xc6, 0xe4, 0x5b, 0xa0, 0x6d, 0xcd,
-	0x49, 0x00, 0x4e, 0xba, 0x83, 0x35, 0x3d, 0x21, 0x3d, 0xd4, 0x25, 0xea,
-	0x91, 0x9e, 0xcd, 0xcf, 0xfd, 0x69, 0x6f, 0x69, 0xff, 0x76, 0xc2, 0xc0,
-	0x3e, 0x52, 0x0f, 0x4d, 0xda, 0x6e, 0x8f, 0x29, 0x45, 0x4b, 0x97, 0xb4,
-	0x95, 0x93, 0x1b, 0x64, 0xc6, 0x11, 0xc9, 0x41, 0xbf, 0x75, 0xdb, 0x04,
-	0x8f, 0x6c, 0xf0, 0x68, 0xcf, 0xa9, 0x41, 0xfd, 0x0e, 0x49, 0xf5, 0x15,
-	0x35, 0x33, 0xe4, 0xe7, 0x82, 0xdc, 0xa6, 0xd6, 0xeb, 0x19, 0x07, 0x3a,
-	0xd9, 0xce, 0x3e, 0xf6, 0x8d, 0xa9, 0x7d, 0x8d, 0x8c, 0x9d, 0x5c, 0x14,
-	0xd1, 0xf4, 0xcc, 0x3e, 0xe0, 0xa3, 0xae, 0x12, 0xee, 0x29, 0xd0, 0x48,
-	0xda, 0xd9, 0xb7, 0xb1, 0x26, 0x26, 0xae, 0xd3, 0xd9, 0x40, 0x27, 0xe8,
-	0x49, 0x90, 0xe7, 0xe4, 0xa1, 0x3a, 0xa7, 0xb6, 0x71, 0xce, 0x5f, 0xfb,
-	0xdb, 0x46, 0x4c, 0x79, 0x5d, 0x9d, 0x97, 0x76, 0x45, 0x38, 0x75, 0x46,
-	0x21, 0x7f, 0xa6, 0x3d, 0xd1, 0x0a, 0x8e, 0xb5, 0x8e, 0x0b, 0x7a, 0xa1,
-	0x1b, 0x99, 0x0e, 0xc9, 0x29, 0xfa, 0x0e, 0x62, 0x2f, 0xda, 0x1b, 0xec,
-	0xc6, 0xe6, 0x59, 0x38, 0x97, 0x81, 0xed, 0xa6, 0x95, 0xfe, 0x14, 0x2a,
-	0xf4, 0x07, 0xa4, 0x6d, 0x35, 0xad, 0x4b, 0x80, 0xaf, 0xf4, 0x6c, 0x37,
-	0x68, 0xe3, 0x18, 0xb6, 0x67, 0xe3, 0xfd, 0x7e, 0xd8, 0xfa, 0xc1, 0x41,
-	0xf0, 0x87, 0x70, 0x76, 0x0a, 0xf2, 0xce, 0xba, 0xd8, 0xd3, 0x75, 0x6e,
-	0x56, 0x3c, 0xe8, 0xc1, 0x79, 0x06, 0x67, 0xc9, 0xaf, 0x76, 0xe8, 0xb3,
-	0x26, 0x05, 0x27, 0x9d, 0xa2, 0xfc, 0x03, 0xda, 0x75, 0xd9, 0x76, 0x4b,
-	0x23, 0xed, 0x91, 0xac, 0xa8, 0x8f, 0xa6, 0xc4, 0x47, 0x08, 0x4b, 0x38,
-	0xc2, 0xa7, 0x0f, 0x8a, 0xfe, 0x6b, 0xdf, 0xda, 0x74, 0x56, 0x5b, 0x06,
-	0x66, 0x41, 0x43, 0xc0, 0x5b, 0xf0, 0xe4, 0xb3, 0x60, 0xc9, 0xd7, 0xad,
-	0xfc, 0x23, 0x6c, 0x23, 0x1c, 0x74, 0xa2, 0x8f, 0x34, 0xac, 0x74, 0x04,
-	0xf6, 0x15, 0xd1, 0x14, 0xc9, 0x46, 0x0b, 0x71, 0x7c, 0xda, 0x39, 0x08,
-	0x0f, 0xbb, 0xf7, 0x60, 0xf7, 0x1e, 0x7c, 0x82, 0x07, 0x9b, 0xf7, 0xe8,
-	0x27, 0x52, 0xf2, 0xea, 0x10, 0xfc, 0xda, 0x86, 0x5f, 0x41, 0x1b, 0x43,
-	0x5f, 0x17, 0x03, 0x7e, 0x65, 0xba, 0xaa, 0xc3, 0x76, 0x61, 0x43, 0x4b,
-	0x9c, 0xb3, 0xf0, 0xcc, 0xe3, 0x69, 0xc3, 0x8f, 0x52, 0xaf, 0x22, 0xff,
-	0x49, 0x3f, 0x93, 0x84, 0x4f, 0xa1, 0xaf, 0xa1, 0x2f, 0x21, 0xac, 0xef,
-	0xe7, 0x1d, 0xae, 0xf5, 0x65, 0xdc, 0xa1, 0x1d, 0x75, 0x88, 0x1e, 0x2f,
-	0x6a, 0x47, 0x87, 0x60, 0x63, 0x37, 0xb6, 0x80, 0x56, 0xda, 0xda, 0x75,
-	0x74, 0x15, 0x68, 0xbf, 0xe8, 0x0c, 0xfe, 0x5d, 0xde, 0x36, 0xc0, 0x28,
-	0xa1, 0x76, 0x05, 0xe3, 0xb6, 0xd0, 0x9f, 0xf0, 0x7d, 0x3a, 0x95, 0x95,
-	0xdd, 0xe1, 0x98, 0xfd, 0x75, 0x7a, 0x1d, 0xfd, 0x96, 0x98, 0x0c, 0x9c,
-	0x09, 0xfc, 0xe0, 0xc0, 0x82, 0x25, 0xf6, 0x99, 0x80, 0xc6, 0x81, 0x73,
-	0x91, 0x3f, 0x6c, 0x01, 0x3e, 0xd0, 0xe7, 0x6d, 0xc4, 0x09, 0x91, 0xf7,
-	0x34, 0x98, 0x0a, 0xe6, 0xb6, 0xf2, 0x82, 0x3e, 0x98, 0xf6, 0x66, 0x35,
-	0xda, 0xdb, 0x01, 0xd8, 0x9b, 0xd3, 0x2a, 0x69, 0xe7, 0xef, 0x60, 0x6f,
-	0x4f, 0x39, 0x1a, 0x78, 0x23, 0x72, 0xa1, 0xdc, 0x01, 0x5b, 0x37, 0x93,
-	0xef, 0xc8, 0x9e, 0xd4, 0xb4, 0x68, 0x72, 0x9a, 0x73, 0x35, 0xcc, 0x29,
-	0xff, 0x1b, 0xd8, 0xf7, 0x45, 0xe3, 0x69, 0xd0, 0xe5, 0xfb, 0xd3, 0xc0,
-	0x59, 0xd8, 0x6f, 0x84, 0xb6, 0x15, 0xcd, 0xa7, 0x10, 0xf3, 0xdc, 0xcf,
-	0x19, 0x52, 0x1c, 0x6e, 0x91, 0xf4, 0xf0, 0x02, 0x70, 0x4f, 0x3a, 0x81,
-	0x1d, 0x53, 0xd7, 0x17, 0x81, 0x7f, 0xc6, 0x1b, 0x82, 0x1e, 0xd3, 0x0e,
-	0x40, 0x17, 0xf0, 0x2f, 0x02, 0xff, 0x4c, 0xbd, 0x45, 0xbe, 0x69, 0x46,
-	0xb1, 0x34, 0x3a, 0x4f, 0x1b, 0xc0, 0xa2, 0x7d, 0x4f, 0xc8, 0x17, 0xbd,
-	0xb8, 0xe6, 0x3e, 0x4b, 0x3f, 0x5b, 0x1a, 0x86, 0x9d, 0x68, 0x25, 0x87,
-	0x7b, 0x1b, 0xb2, 0xb8, 0x0e, 0x23, 0xd9, 0x52, 0x60, 0x83, 0x59, 0x77,
-	0xa8, 0x98, 0x34, 0x94, 0x2f, 0x11, 0x39, 0x5c, 0x36, 0x01, 0xc3, 0x31,
-	0xe7, 0x83, 0xb9, 0xb1, 0x72, 0x1f, 0x7c, 0x23, 0xc7, 0x57, 0xfd, 0x49,
-	0x27, 0x98, 0xfb, 0xdd, 0x72, 0x81, 0x32, 0x62, 0xdc, 0x4e, 0x95, 0x9c,
-	0x7f, 0xf7, 0xa1, 0xbf, 0x9b, 0xd6, 0x5c, 0x1b, 0x4f, 0x7a, 0x2c, 0x8c,
-	0xf5, 0xda, 0x11, 0x5b, 0xef, 0x6b, 0x0d, 0x7d, 0xd8, 0x11, 0x4c, 0x1e,
-	0x2a, 0x97, 0x7a, 0x5b, 0xe5, 0xaa, 0xc1, 0xd8, 0x79, 0x09, 0x46, 0xed,
-	0x96, 0xf7, 0x82, 0x1f, 0xa5, 0x9e, 0x86, 0xb9, 0x58, 0xbe, 0xec, 0xcb,
-	0x9a, 0x13, 0xac, 0xc1, 0xb8, 0x23, 0x57, 0xd6, 0xfb, 0x62, 0xb2, 0x3e,
-	0xb6, 0xb8, 0x66, 0x49, 0xf6, 0x0e, 0x2f, 0x8a, 0x5a, 0xdb, 0x1b, 0xdb,
-	0x58, 0x9b, 0xc8, 0x97, 0x4b, 0x3d, 0x0d, 0xe3, 0x64, 0x0e, 0xb8, 0xf4,
-	0x03, 0xeb, 0x6b, 0xfb, 0x37, 0xd6, 0xee, 0x90, 0x54, 0x0f, 0xd7, 0xeb,
-	0x7d, 0x6d, 0x1b, 0xb8, 0x53, 0x21, 0x3d, 0xbd, 0x6d, 0x1b, 0x38, 0x6c,
-	0xe2, 0x6c, 0x18, 0x0f, 0x13, 0xe7, 0xc0, 0x06, 0xce, 0xfd, 0x9b, 0xe9,
-	0x39, 0x21, 0xf0, 0x41, 0xb1, 0xd6, 0x8c, 0x1c, 0xb8, 0x50, 0x1e, 0x1c,
-	0xff, 0xa2, 0x20, 0xe6, 0xed, 0xdf, 0x16, 0xfa, 0x64, 0xf3, 0x80, 0x0b,
-	0x5e, 0x99, 0x42, 0x1f, 0xa7, 0x49, 0x09, 0x72, 0x7e, 0xa8, 0x26, 0x07,
-	0xd6, 0x6a, 0x12, 0xea, 0x12, 0x75, 0xe2, 0x32, 0x6c, 0x4c, 0x8a, 0xbb,
-	0x32, 0x1d, 0x13, 0x66, 0xc6, 0x82, 0xad, 0xc9, 0x78, 0x09, 0x3e, 0xd9,
-	0xc8, 0xec, 0x79, 0x3b, 0x67, 0x3c, 0xe9, 0x1b, 0x88, 0xdb, 0x39, 0xe9,
-	0x38, 0xe8, 0x8e, 0x62, 0xbe, 0x46, 0xdb, 0x82, 0x5f, 0xa9, 0x13, 0xf7,
-	0x7c, 0xb7, 0x74, 0x21, 0x2e, 0xd6, 0x5e, 0xda, 0x11, 0xd8, 0x8e, 0x98,
-	0x26, 0x7c, 0xed, 0xcc, 0x28, 0xe3, 0x78, 0x6b, 0x0c, 0xf0, 0x13, 0x46,
-	0x66, 0x6c, 0xe7, 0xf1, 0xda, 0x9d, 0x3b, 0x0b, 0xb5, 0xe2, 0xce, 0x42,
-	0xd9, 0xa2, 0x9d, 0xe8, 0xee, 0x28, 0xfa, 0x2a, 0x57, 0x4a, 0xc2, 0x26,
-	0x2e, 0xab, 0x3c, 0xe2, 0xb5, 0x7a, 0x1d, 0xf6, 0x47, 0xfb, 0x16, 0x19,
-	0xf7, 0xb0, 0xc7, 0xc8, 0x87, 0x90, 0x3b, 0x68, 0x83, 0x4f, 0xcb, 0xe2,
-	0xd4, 0xfa, 0xc8, 0xbf, 0x85, 0xf6, 0xc9, 0xfe, 0xfb, 0x7e, 0xe0, 0xef,
-	0xef, 0xe8, 0x0e, 0xe6, 0xde, 0x0a, 0x6d, 0x3a, 0xc2, 0x45, 0x3c, 0xc3,
-	0xda, 0x38, 0x72, 0x92, 0xf1, 0xba, 0xa9, 0xd1, 0x3f, 0xe7, 0x3c, 0xe6,
-	0x12, 0xcc, 0x23, 0xa6, 0x43, 0x3f, 0x27, 0xd9, 0x1c, 0xfc, 0x88, 0x8e,
-	0xdc, 0xa2, 0x00, 0xbb, 0x31, 0x33, 0x57, 0x64, 0x46, 0xf9, 0x48, 0x89,
-	0xb5, 0x64, 0x9e, 0x00, 0xcc, 0x7f, 0xc0, 0xe6, 0xda, 0xba, 0x43, 0x3d,
-	0x0c, 0x7d, 0xbc, 0xf2, 0xbb, 0x80, 0xbd, 0xbc, 0x05, 0xf6, 0xdd, 0x46,
-	0x58, 0xbc, 0xbf, 0xb8, 0xe5, 0xfd, 0x4f, 0x69, 0xbf, 0x78, 0xb7, 0x0a,
-	0x7f, 0xda, 0x1a, 0xda, 0xfe, 0x05, 0x29, 0xc0, 0xb7, 0x9a, 0x36, 0x73,
-	0xc7, 0xdb, 0xb0, 0x16, 0xe3, 0x1a, 0x68, 0x84, 0xbf, 0x40, 0xcc, 0x04,
-	0xbf, 0x11, 0x13, 0x12, 0x37, 0x30, 0x3f, 0xa2, 0x9f, 0x00, 0x2c, 0xfd,
-	0x2f, 0x61, 0x5f, 0xe9, 0x20, 0xcf, 0x0b, 0x35, 0xae, 0xa1, 0xaf, 0x12,
-	0xdf, 0x1d, 0x6d, 0x83, 0x46, 0xf9, 0xaf, 0x19, 0x76, 0x04, 0x1b, 0xe1,
-	0xdd, 0x0a, 0xcb, 0x7c, 0x85, 0xb8, 0xbb, 0xc3, 0x3c, 0x60, 0x4c, 0xb2,
-	0xf5, 0x2c, 0x7e, 0x45, 0x99, 0x7c, 0x16, 0xb9, 0x98, 0xdd, 0x42, 0x5e,
-	0x90, 0x35, 0x56, 0xc0, 0xa3, 0x68, 0xdd, 0x13, 0xbd, 0x9b, 0xc7, 0xf7,
-	0xc5, 0x37, 0x7c, 0x25, 0x2d, 0x4d, 0xb2, 0x88, 0x15, 0xe0, 0x71, 0x6a,
-	0x42, 0xcf, 0x24, 0x24, 0x57, 0x0b, 0xf8, 0x8b, 0x78, 0x0b, 0xff, 0xc8,
-	0x2e, 0x64, 0xb2, 0xee, 0x07, 0x23, 0x99, 0x53, 0xcf, 0xb2, 0x90, 0x4d,
-	0x0a, 0xba, 0x34, 0x86, 0xb5, 0x72, 0x02, 0x38, 0x18, 0x87, 0x1d, 0x3d,
-	0x13, 0x97, 0x82, 0xc5, 0x7c, 0x41, 0xe5, 0x7a, 0x59, 0xfa, 0x01, 0x3d,
-	0xd3, 0x86, 0x39, 0xf6, 0x1f, 0xee, 0x0e, 0x64, 0xdd, 0xc9, 0xf1, 0xb8,
-	0x9e, 0xe9, 0xde, 0x32, 0xff, 0x7a, 0x67, 0x40, 0x9b, 0x1a, 0x63, 0xfe,
-	0x5f, 0xb6, 0x8c, 0xbf, 0x1e, 0xdf, 0x3c, 0x7e, 0x60, 0x67, 0xa4, 0x0f,
-	0x7a, 0xe6, 0x89, 0x90, 0x5e, 0xea, 0xe9, 0x56, 0x5a, 0x7f, 0x13, 0x7d,
-	0x79, 0x0e, 0x38, 0x95, 0x8e, 0xff, 0x06, 0xfa, 0xb2, 0x0e, 0xfb, 0x09,
-	0xfa, 0xd2, 0x48, 0xc3, 0x7a, 0x5d, 0x51, 0xd1, 0x91, 0x93, 0xba, 0xa3,
-	0x7b, 0x90, 0x77, 0xa4, 0x24, 0x5f, 0x07, 0xef, 0xd6, 0xe3, 0xea, 0x3a,
-	0x4c, 0x71, 0x03, 0x26, 0x88, 0x3b, 0xf9, 0xba, 0x8f, 0x3c, 0xae, 0x31,
-	0x06, 0x0f, 0xa3, 0x5f, 0xc4, 0x59, 0x57, 0x64, 0xd2, 0x5b, 0xcb, 0xea,
-	0xf6, 0xa9, 0x20, 0x0f, 0xb5, 0xbf, 0xad, 0xe5, 0x17, 0x99, 0xa3, 0xc6,
-	0xd0, 0x57, 0xf5, 0x07, 0x62, 0xdc, 0x33, 0x5a, 0x76, 0x79, 0x0e, 0xf9,
-	0xe9, 0x12, 0x7e, 0x67, 0xf1, 0xab, 0xe1, 0x17, 0xd5, 0x01, 0x2f, 0xa0,
-	0x8e, 0x50, 0xfe, 0x1e, 0xb1, 0x29, 0xd8, 0xff, 0x67, 0x4b, 0xc8, 0x8f,
-	0xe7, 0x12, 0xf2, 0x94, 0xad, 0xf7, 0xea, 0x81, 0x8f, 0xcb, 0x22, 0xb7,
-	0xb6, 0x2e, 0xcb, 0x97, 0xc2, 0x1c, 0x4d, 0xe4, 0x9d, 0x0a, 0x64, 0xb9,
-	0xff, 0x48, 0xe8, 0x9f, 0xbe, 0xf6, 0xa0, 0xab, 0x7c, 0x79, 0x98, 0x83,
-	0xc1, 0xef, 0x64, 0x15, 0xd4, 0x1b, 0xe0, 0x8f, 0x26, 0xef, 0x41, 0x8f,
-	0xdf, 0xa9, 0xb4, 0x83, 0x1e, 0x5b, 0x0a, 0xc7, 0x90, 0xbb, 0x68, 0x83,
-	0xd6, 0x36, 0xad, 0x1d, 0x79, 0x18, 0xfc, 0x8e, 0x1a, 0x93, 0x67, 0x17,
-	0xa7, 0x16, 0xca, 0x3a, 0x60, 0xc1, 0xf3, 0x51, 0xf4, 0xa1, 0x7f, 0x97,
-	0x2a, 0x5c, 0xa7, 0xcb, 0xbb, 0x15, 0x43, 0x7e, 0x8e, 0xbc, 0xee, 0x3d,
-	0xfb, 0xe2, 0x14, 0x6c, 0xb0, 0x0f, 0xf1, 0x0a, 0xb5, 0xd0, 0x1e, 0xc6,
-	0x8c, 0x01, 0x13, 0xcf, 0x3c, 0x7e, 0x87, 0x91, 0xe7, 0x5d, 0x7b, 0xcd,
-	0x27, 0xc1, 0x93, 0xb6, 0x18, 0xd6, 0x10, 0xde, 0x04, 0x6d, 0x5d, 0xd0,
-	0xc1, 0xb4, 0x35, 0x21, 0xdd, 0x96, 0xca, 0x9d, 0x34, 0xce, 0x07, 0x7e,
-	0xf2, 0xe3, 0xf3, 0xe4, 0xb3, 0x01, 0x1d, 0xe2, 0x98, 0xef, 0xe8, 0xcf,
-	0x89, 0x2f, 0x7d, 0x30, 0x8b, 0xc3, 0x5c, 0xaa, 0x04, 0xfd, 0x68, 0x4e,
-	0xb4, 0x28, 0xa6, 0xd2, 0x4f, 0xe7, 0x61, 0xab, 0x1c, 0x8f, 0x8b, 0x92,
-	0xc1, 0x26, 0x79, 0x52, 0x8f, 0x56, 0xa7, 0x66, 0x6c, 0xca, 0xd5, 0x92,
-	0xe9, 0x72, 0x24, 0x57, 0xca, 0x08, 0x75, 0x66, 0xe5, 0xdb, 0x90, 0xab,
-	0x1e, 0xd6, 0x20, 0xf0, 0x03, 0x73, 0x94, 0x2f, 0xea, 0xc4, 0x0a, 0xf2,
-	0xb0, 0x8a, 0xc4, 0x83, 0x1a, 0xea, 0x19, 0xd4, 0x1d, 0x90, 0x5f, 0x79,
-	0x0e, 0x38, 0x12, 0x78, 0x2e, 0xe1, 0x99, 0xc4, 0xf3, 0x2c, 0x9e, 0xfd,
-	0x78, 0xd6, 0x68, 0x1f, 0x61, 0xde, 0xf3, 0x31, 0x7a, 0x60, 0x27, 0x79,
-	0xda, 0xb4, 0x7c, 0xaf, 0x9e, 0x91, 0xbf, 0xad, 0x1f, 0x94, 0xbf, 0xa9,
-	0x8f, 0xca, 0x5f, 0xd7, 0x1d, 0x79, 0xb9, 0xbe, 0x5f, 0xfe, 0xaa, 0x3e,
-	0xcc, 0x9a, 0x10, 0x39, 0x5c, 0x0a, 0xbe, 0xf9, 0xbc, 0x3c, 0xe8, 0xd5,
-	0xe1, 0x73, 0x28, 0xff, 0x8b, 0x53, 0xd9, 0xda, 0x75, 0x52, 0x78, 0xd6,
-	0x42, 0x9e, 0x69, 0xb0, 0x2e, 0x93, 0xc7, 0x9c, 0x3b, 0xe2, 0x94, 0xbd,
-	0x6e, 0xb3, 0x4e, 0x39, 0x49, 0x38, 0xd4, 0xbb, 0x1a, 0xf2, 0x97, 0x16,
-	0x99, 0x48, 0xa4, 0x57, 0x5c, 0x23, 0x19, 0xfa, 0xa3, 0x3b, 0x01, 0x87,
-	0x3d, 0xbd, 0x0e, 0x59, 0x7b, 0x1e, 0xb6, 0xe0, 0xa0, 0x56, 0x4e, 0xc4,
-	0xe0, 0xfb, 0x54, 0x7e, 0xa2, 0x7c, 0x4b, 0xe0, 0x4b, 0xa3, 0x9a, 0x91,
-	0x73, 0xd9, 0x70, 0x8e, 0xf1, 0xd1, 0x02, 0xec, 0x72, 0x18, 0x43, 0xb6,
-	0xe2, 0xa4, 0x6f, 0x3c, 0x16, 0xfa, 0xc7, 0x15, 0x39, 0xe1, 0x0d, 0x66,
-	0xaf, 0x20, 0xf6, 0x68, 0x2d, 0x51, 0x5e, 0xb4, 0x0b, 0xb4, 0xf9, 0xfe,
-	0xdd, 0xac, 0xbf, 0xe3, 0xa6, 0xfc, 0x70, 0x36, 0x6d, 0x3d, 0xa2, 0xcf,
-	0x40, 0xce, 0xbe, 0x7f, 0xd4, 0x4e, 0x9f, 0x9a, 0xd0, 0x3b, 0xe5, 0x27,
-	0xcf, 0x30, 0x26, 0xaf, 0x4e, 0x7d, 0x1f, 0x7a, 0x50, 0x5d, 0x6a, 0x95,
-	0x6a, 0xd5, 0x94, 0x4b, 0x23, 0x83, 0x6a, 0xdf, 0x6a, 0x2d, 0x8e, 0x3c,
-	0xaf, 0x4d, 0xa6, 0xfb, 0x94, 0xb2, 0xc3, 0x6f, 0x0f, 0x2b, 0xbf, 0xed,
-	0xda, 0x78, 0xd6, 0x92, 0xd6, 0x66, 0x5a, 0x5e, 0x96, 0x82, 0x07, 0x1d,
-	0x8b, 0xef, 0x02, 0x4f, 0xd8, 0x1f, 0xb4, 0x0a, 0x3a, 0x62, 0xa0, 0x39,
-	0x68, 0x3d, 0xa8, 0xff, 0xd2, 0xff, 0x1d, 0x93, 0x7c, 0x7c, 0x1b, 0xb1,
-	0x85, 0xb1, 0x52, 0x53, 0x7a, 0xb7, 0xb0, 0xf4, 0x53, 0x8b, 0xfe, 0x65,
-	0xa5, 0xb6, 0x2b, 0x1c, 0xd3, 0xbf, 0x73, 0xdc, 0x2e, 0x2f, 0x57, 0xb7,
-	0xcb, 0x62, 0x95, 0xef, 0x5b, 0x65, 0xa1, 0x3a, 0x78, 0xa5, 0x57, 0xef,
-	0x93, 0xd5, 0xeb, 0x6e, 0xb4, 0xee, 0xd7, 0xc1, 0x93, 0x63, 0x1f, 0xc9,
-	0x07, 0x23, 0xdd, 0xf2, 0xd6, 0x7d, 0xe9, 0x17, 0xfe, 0x44, 0x87, 0x3e,
-	0x8e, 0x74, 0xd0, 0xce, 0xd0, 0xe7, 0x7c, 0xfa, 0x4a, 0x56, 0xa7, 0x9e,
-	0xfd, 0x00, 0xfa, 0x95, 0xae, 0x04, 0x3a, 0x49, 0xdc, 0xc4, 0x0b, 0xf9,
-	0xd8, 0x6f, 0x00, 0x27, 0xde, 0xd5, 0x06, 0x81, 0xeb, 0x0d, 0xc5, 0x8b,
-	0xbb, 0x9d, 0xf4, 0x15, 0x84, 0x28, 0xff, 0x92, 0x3d, 0x38, 0x3c, 0xa0,
-	0xef, 0x92, 0x6a, 0xf2, 0x46, 0xeb, 0xbb, 0x88, 0x07, 0xd9, 0x44, 0xfa,
-	0xd4, 0x45, 0x59, 0x9d, 0xba, 0x60, 0x53, 0x17, 0x69, 0xc3, 0xff, 0x80,
-	0x9c, 0xd4, 0x92, 0x4a, 0x8d, 0xbe, 0x8b, 0xb8, 0x58, 0x17, 0xec, 0xb5,
-	0x4e, 0x80, 0x06, 0x77, 0x3f, 0xde, 0x61, 0xde, 0xf8, 0x3c, 0xe5, 0xd6,
-	0xc2, 0xb5, 0xc3, 0x59, 0xbd, 0x7f, 0x0b, 0x8f, 0x06, 0xad, 0x43, 0x3a,
-	0xf7, 0xfb, 0x2f, 0xec, 0xfb, 0x3e, 0x68, 0x1d, 0xc4, 0x5a, 0xc4, 0xd0,
-	0x64, 0xe3, 0x1e, 0x3f, 0x52, 0x7b, 0x3c, 0x5b, 0x43, 0x0e, 0xb8, 0xbe,
-	0x07, 0xe6, 0x6a, 0x3a, 0xce, 0x69, 0x2a, 0xb9, 0x5c, 0x1a, 0x21, 0x7f,
-	0x6f, 0xef, 0x61, 0x2c, 0x37, 0x32, 0x2f, 0x85, 0x79, 0x46, 0x4c, 0x7e,
-	0x8c, 0xba, 0x6b, 0x12, 0xfe, 0x7f, 0x61, 0xef, 0x20, 0x68, 0x40, 0x7d,
-	0x9a, 0x54, 0xf1, 0x7c, 0xca, 0x05, 0x8e, 0x9c, 0xc2, 0xfd, 0xa6, 0x2c,
-	0x01, 0xf7, 0x38, 0xf9, 0x00, 0xdc, 0x33, 0x9c, 0x57, 0x32, 0xc0, 0x7c,
-	0x2d, 0x05, 0xbc, 0xbd, 0xa1, 0xff, 0x8b, 0x43, 0x57, 0xf7, 0x59, 0x77,
-	0x4b, 0x2c, 0xf4, 0x7f, 0x71, 0x79, 0xeb, 0x79, 0xe8, 0x7d, 0x9c, 0xfa,
-	0x93, 0xe8, 0xd9, 0xd0, 0x9f, 0x46, 0xfc, 0xad, 0x92, 0xaf, 0xc4, 0x80,
-	0x17, 0x39, 0xf7, 0x28, 0xf1, 0x62, 0x5c, 0xa5, 0x2e, 0x17, 0x43, 0x5d,
-	0xee, 0x08, 0x71, 0xaf, 0x41, 0x97, 0xd3, 0xa9, 0x55, 0x9d, 0xf5, 0xd5,
-	0x4e, 0x55, 0xf3, 0x1a, 0xb0, 0xaf, 0x42, 0x99, 0xb1, 0x88, 0xb6, 0x75,
-	0x71, 0x6a, 0x12, 0x35, 0x6c, 0xa1, 0x7c, 0x50, 0x2f, 0xd4, 0x47, 0xf5,
-	0x82, 0x47, 0x7d, 0xdb, 0x6b, 0x2d, 0x28, 0x1e, 0x27, 0x65, 0xa1, 0xfe,
-	0x81, 0x5f, 0xda, 0xbb, 0x0d, 0x7d, 0xe8, 0xfe, 0x38, 0xe5, 0x7b, 0x3d,
-	0xe9, 0x42, 0x50, 0x27, 0xbf, 0x13, 0x72, 0x66, 0xe8, 0x7b, 0xdd, 0xcc,
-	0xd1, 0x96, 0x87, 0x88, 0x1f, 0x74, 0x24, 0x12, 0xb2, 0xe8, 0x71, 0x8f,
-	0xd5, 0x29, 0xf2, 0xb2, 0x30, 0x67, 0xc9, 0x09, 0x25, 0x3f, 0x9e, 0x9b,
-	0xf7, 0x47, 0x86, 0x4c, 0xc6, 0x07, 0xad, 0x47, 0x25, 0x7d, 0x65, 0xcd,
-	0x48, 0xbf, 0x30, 0x81, 0xb8, 0xba, 0x30, 0x6f, 0x88, 0xab, 0xea, 0x30,
-	0xca, 0x28, 0x5d, 0x81, 0x35, 0x86, 0x67, 0xbf, 0xa7, 0xe1, 0xec, 0x5d,
-	0x72, 0xe1, 0xf9, 0xcf, 0xc3, 0xee, 0x5f, 0x81, 0x2c, 0xcc, 0xd4, 0x71,
-	0xe4, 0x19, 0xcf, 0xc9, 0xa0, 0x55, 0x42, 0xfe, 0x0c, 0xbe, 0xa3, 0xbd,
-	0xa2, 0x6c, 0x60, 0x41, 0xc7, 0xb8, 0x9f, 0x7c, 0xe2, 0x78, 0xb7, 0x2c,
-	0xf4, 0x05, 0x36, 0xce, 0x77, 0x03, 0xc0, 0x11, 0xbc, 0xe3, 0xf8, 0xb7,
-	0x64, 0x40, 0xbd, 0xab, 0xaa, 0x75, 0x25, 0xe9, 0x0d, 0xe5, 0xf7, 0x18,
-	0xf6, 0x24, 0x8f, 0xa3, 0xf9, 0x4e, 0x09, 0x6c, 0x29, 0xe2, 0xbb, 0x25,
-	0x47, 0x6b, 0x09, 0xb9, 0xa7, 0x96, 0x94, 0x2f, 0xd7, 0xfa, 0x25, 0x0f,
-	0x39, 0x4e, 0x8e, 0x3e, 0xd9, 0xc3, 0xb3, 0xe5, 0x96, 0xd2, 0x2f, 0x88,
-	0x4e, 0x5a, 0xab, 0x72, 0xdc, 0x8b, 0xe8, 0xe9, 0x08, 0xe9, 0x33, 0xc3,
-	0x71, 0x2c, 0xa4, 0xa1, 0x11, 0x5f, 0x07, 0x70, 0x65, 0x81, 0xe7, 0xa5,
-	0x10, 0x0f, 0xfd, 0x08, 0x68, 0x3d, 0x96, 0x94, 0x25, 0x8f, 0x74, 0x6c,
-	0x97, 0x52, 0x82, 0xfd, 0x57, 0xa0, 0x6f, 0xc4, 0xb3, 0x8d, 0xf9, 0xcd,
-	0x26, 0x1e, 0x3f, 0x5c, 0x2b, 0x82, 0xc7, 0xe4, 0x2f, 0xe1, 0xe0, 0xaf,
-	0xbf, 0x40, 0xf9, 0xed, 0x43, 0x8e, 0x6f, 0x07, 0xba, 0x69, 0x6d, 0xec,
-	0x99, 0x9f, 0xeb, 0x82, 0xac, 0xb8, 0x6f, 0xbb, 0x1c, 0x83, 0xdd, 0xe7,
-	0xaa, 0xdc, 0xff, 0x18, 0xf4, 0xe8, 0x2d, 0xb5, 0x7f, 0x7e, 0xa9, 0x2f,
-	0x5c, 0xcf, 0xb5, 0x5d, 0x5b, 0xd6, 0xb6, 0xca, 0xa1, 0x8a, 0x75, 0x8d,
-	0xf5, 0xbf, 0x8f, 0xf5, 0xba, 0x9c, 0x1e, 0xe5, 0x7a, 0xe2, 0x01, 0x5c,
-	0x35, 0xf1, 0x29, 0x78, 0xe2, 0xaa, 0xde, 0xcf, 0x55, 0x5b, 0x25, 0x57,
-	0x89, 0x70, 0x11, 0xcf, 0x47, 0xa8, 0x87, 0xbf, 0xaa, 0x70, 0x4d, 0x2a,
-	0x5c, 0x78, 0x5f, 0xa5, 0xcf, 0xb9, 0x15, 0xeb, 0x3b, 0xe8, 0xff, 0xa5,
-	0x14, 0xef, 0x94, 0x92, 0xaa, 0xe9, 0xdb, 0x95, 0xaf, 0x29, 0xc5, 0xdb,
-	0xf0, 0xbe, 0x13, 0x36, 0xbf, 0x0f, 0xb9, 0x45, 0x17, 0xeb, 0xdc, 0x2d,
-	0x73, 0x5b, 0xe9, 0x8f, 0x6d, 0xa1, 0x3f, 0x06, 0xb8, 0x5e, 0xec, 0x19,
-	0xc0, 0xe5, 0x01, 0x37, 0x3d, 0x07, 0x3e, 0x3b, 0xf4, 0x2b, 0x8c, 0x93,
-	0xd7, 0x29, 0x5a, 0xa6, 0x97, 0xfe, 0x1b, 0xe7, 0xea, 0xc3, 0xda, 0x68,
-	0x1c, 0xf0, 0xe1, 0x69, 0xe0, 0x99, 0xab, 0xaa, 0xbb, 0x0b, 0xc8, 0x60,
-	0x7b, 0x9c, 0x67, 0x2f, 0x55, 0x3f, 0x8b, 0x67, 0xd7, 0x35, 0xf0, 0x8b,
-	0xbc, 0x22, 0xbd, 0xa4, 0x95, 0xf7, 0x48, 0xb0, 0x37, 0x07, 0x7a, 0x1c,
-	0x37, 0x24, 0x3f, 0x6a, 0x21, 0x3f, 0xe7, 0x3d, 0x2c, 0xed, 0xd2, 0xe2,
-	0xdd, 0x67, 0x4c, 0xb7, 0x19, 0x6b, 0x4d, 0x75, 0xf6, 0xe3, 0x4b, 0xbc,
-	0x8b, 0x4d, 0xf1, 0xee, 0x6e, 0x98, 0xd7, 0x18, 0x8f, 0x2c, 0xd9, 0xf2,
-	0x78, 0x6d, 0x58, 0x1e, 0xad, 0xa5, 0xad, 0xfb, 0xe1, 0x03, 0x0a, 0xeb,
-	0x77, 0xb4, 0x43, 0x71, 0xfa, 0x2f, 0x13, 0x79, 0x60, 0x8b, 0x1d, 0xe4,
-	0x05, 0x25, 0xd6, 0x6c, 0x73, 0x69, 0xde, 0xe3, 0x58, 0x55, 0xd9, 0x9a,
-	0x3b, 0xfc, 0x5f, 0xe6, 0x0d, 0xdc, 0x9f, 0xfe, 0x1a, 0x79, 0x82, 0x87,
-	0x3c, 0xc1, 0x43, 0x9e, 0xe0, 0x21, 0x4f, 0xf0, 0x90, 0x27, 0x78, 0xc8,
-	0x13, 0x3c, 0xe4, 0x09, 0x1e, 0xf2, 0x04, 0xc4, 0xee, 0xa0, 0x5e, 0x18,
-	0x43, 0xfe, 0x0b, 0xff, 0xe5, 0xdd, 0x06, 0x3e, 0xf1, 0xfe, 0x92, 0x31,
-	0x87, 0xb1, 0x99, 0x73, 0xab, 0xdb, 0x5c, 0xca, 0x4d, 0xf9, 0xbe, 0x3b,
-	0x31, 0x37, 0x1e, 0xe6, 0x23, 0x84, 0x89, 0x62, 0x37, 0xe1, 0xe4, 0xa0,
-	0xeb, 0x68, 0xb0, 0x31, 0xe6, 0x2b, 0x41, 0xcc, 0x0a, 0x72, 0xe5, 0xb7,
-	0x91, 0xb3, 0xa4, 0x90, 0xb3, 0xf4, 0x23, 0x3f, 0xe1, 0x9d, 0x75, 0x74,
-	0xc7, 0x94, 0xd5, 0x8e, 0x7a, 0x63, 0xda, 0x3d, 0x1e, 0x73, 0x69, 0x3b,
-	0x55, 0xd0, 0xf5, 0xb9, 0x5e, 0xf1, 0x25, 0x37, 0xf2, 0x4d, 0xe4, 0xad,
-	0xcf, 0xa9, 0xfb, 0xb4, 0xf1, 0x21, 0xca, 0xbc, 0xf2, 0x09, 0xb9, 0x6b,
-	0xc4, 0xdf, 0xe0, 0x1e, 0x50, 0x5f, 0x20, 0xff, 0x44, 0x7a, 0xce, 0x81,
-	0xe1, 0xe7, 0x62, 0x12, 0x3f, 0xb3, 0x1d, 0x73, 0x96, 0xf4, 0xaa, 0xbb,
-	0x24, 0x88, 0xf2, 0xdc, 0x55, 0xc8, 0xcb, 0x16, 0xfd, 0x1c, 0x6f, 0x1c,
-	0x88, 0x97, 0xfe, 0x75, 0x65, 0x2a, 0x57, 0x5d, 0x51, 0x3a, 0x75, 0xb4,
-	0x96, 0x47, 0x7d, 0xd4, 0xd3, 0x2b, 0xed, 0x26, 0x6a, 0xab, 0x08, 0x37,
-	0x71, 0xfe, 0x32, 0xae, 0x6a, 0x9e, 0x73, 0xeb, 0xf2, 0x84, 0xac, 0xb9,
-	0xcf, 0xca, 0x54, 0xa9, 0x92, 0x4e, 0xb2, 0x56, 0xce, 0x5a, 0x2b, 0x53,
-	0x27, 0x81, 0x63, 0x11, 0xb9, 0x81, 0xa1, 0xf6, 0x5e, 0x99, 0x9a, 0xae,
-	0x04, 0xf7, 0x59, 0x01, 0x0d, 0x8c, 0x57, 0xed, 0x62, 0x2c, 0x04, 0xf7,
-	0x5a, 0xba, 0x5a, 0xcb, 0x75, 0x5c, 0x6f, 0x62, 0x1d, 0xe5, 0x36, 0x8c,
-	0xb5, 0x94, 0x1d, 0x69, 0x58, 0x99, 0x2a, 0x56, 0x1b, 0x69, 0x20, 0x1e,
-	0xe2, 0x8d, 0xce, 0xc3, 0xb3, 0xc4, 0x45, 0x3f, 0xe3, 0xfb, 0x85, 0x91,
-	0xfe, 0x30, 0xef, 0x3a, 0x89, 0xfc, 0xce, 0x0c, 0xf4, 0x5c, 0x8d, 0xbf,
-	0xa3, 0xe2, 0x54, 0x4a, 0xe7, 0x3c, 0x9f, 0x78, 0x37, 0xba, 0x80, 0x39,
-	0x8c, 0x17, 0x23, 0x58, 0x3d, 0x84, 0xed, 0x6c, 0xe0, 0x67, 0x4b, 0xb8,
-	0x1f, 0x69, 0xe2, 0x39, 0x2f, 0x61, 0x2f, 0xd2, 0x45, 0x98, 0x38, 0x68,
-	0x83, 0x2c, 0xbd, 0xff, 0x2d, 0xef, 0x1b, 0xcf, 0x44, 0x9e, 0x9a, 0x58,
-	0x43, 0x78, 0xe2, 0x88, 0xd6, 0xe0, 0xc5, 0xb9, 0x60, 0x9d, 0xbe, 0x7e,
-	0xff, 0xf7, 0x69, 0xfb, 0x36, 0xd2, 0x1a, 0xed, 0x1f, 0xe1, 0x19, 0x0e,
-	0xe4, 0xb6, 0xbe, 0x5e, 0xfd, 0x9f, 0x61, 0x78, 0x42, 0x17, 0x3f, 0x76,
-	0x8f, 0x3a, 0xdc, 0x50, 0x87, 0x46, 0xf7, 0x17, 0xbc, 0x0f, 0x60, 0x7d,
-	0xcf, 0x6f, 0x07, 0x8d, 0xb5, 0xe2, 0xcb, 0x61, 0x2c, 0xdb, 0x29, 0x59,
-	0x93, 0x75, 0xc3, 0xf9, 0x70, 0xbc, 0x03, 0xb1, 0x8d, 0xe3, 0x3a, 0xf8,
-	0x0b, 0x5d, 0x76, 0xda, 0xc3, 0xba, 0x25, 0x1e, 0x7c, 0xe3, 0x19, 0xa6,
-	0x1d, 0xb1, 0xee, 0x6b, 0x0b, 0xe7, 0x22, 0x3b, 0xa2, 0x1f, 0x36, 0xc3,
-	0x39, 0xfa, 0x5b, 0x1d, 0xb5, 0x0b, 0xfb, 0xc0, 0xb3, 0xd8, 0x68, 0x4b,
-	0xd1, 0x33, 0x2e, 0x67, 0xe7, 0x23, 0xbf, 0x05, 0x9f, 0x32, 0x64, 0x86,
-	0xbe, 0xbf, 0x03, 0xbe, 0xaf, 0x4b, 0x0e, 0xc1, 0x67, 0x1d, 0x86, 0xcf,
-	0x3a, 0x82, 0x7a, 0x71, 0x6c, 0xa9, 0xf1, 0x9e, 0x97, 0x35, 0x6a, 0x97,
-	0x76, 0x5c, 0xc9, 0xbf, 0xe8, 0x1b, 0xf6, 0x47, 0xd0, 0x01, 0xd6, 0x5d,
-	0x91, 0x4e, 0xc0, 0xdf, 0x3a, 0x71, 0xe8, 0xc4, 0xd6, 0xfb, 0xe4, 0x61,
-	0xd8, 0x46, 0x7b, 0x56, 0xc5, 0x86, 0xa5, 0x80, 0xf7, 0xa5, 0x6a, 0xc0,
-	0x7b, 0xf8, 0x65, 0xe0, 0x37, 0xa5, 0x58, 0xb3, 0xa4, 0x88, 0x7d, 0x8b,
-	0xd8, 0xb7, 0x88, 0x3a, 0x6f, 0xba, 0xd6, 0xf8, 0x1d, 0xab, 0x33, 0xa4,
-	0x9d, 0x6b, 0xa3, 0xbe, 0xd5, 0x70, 0xfe, 0xe8, 0x79, 0x0a, 0xfc, 0x7f,
-	0x0c, 0xfc, 0x3f, 0x81, 0xfa, 0xe6, 0x8f, 0x50, 0xdf, 0x7c, 0x0d, 0xf5,
-	0xcd, 0x71, 0xd4, 0x37, 0x13, 0xa8, 0x6f, 0xbe, 0x0a, 0xff, 0xf1, 0x15,
-	0xf8, 0x8f, 0x63, 0xf0, 0x1f, 0xe3, 0xea, 0xee, 0xe9, 0xa8, 0xb7, 0xf5,
-	0x4e, 0x25, 0xda, 0x8b, 0xed, 0x67, 0x22, 0x76, 0x11, 0x67, 0x1a, 0x93,
-	0x6a, 0x9d, 0xf5, 0x8d, 0x23, 0xee, 0x41, 0xd6, 0x37, 0xc7, 0xb4, 0x09,
-	0xe4, 0xef, 0xf7, 0xef, 0x67, 0xdd, 0x13, 0xd7, 0x72, 0xaa, 0xee, 0x49,
-	0x9f, 0x77, 0x91, 0x22, 0x21, 0xf7, 0xc3, 0x99, 0xd3, 0x67, 0x73, 0xa0,
-	0x25, 0xc8, 0xf9, 0x7a, 0x42, 0xbf, 0xd7, 0x21, 0x8b, 0xb3, 0xa8, 0x19,
-	0xbc, 0x1f, 0x6b, 0x05, 0xe5, 0x1b, 0x2d, 0x8c, 0x51, 0x2b, 0x7b, 0xff,
-	0x1c, 0x8e, 0x47, 0x64, 0x72, 0x1e, 0xb5, 0xed, 0xf3, 0xff, 0xa8, 0xe5,
-	0xd4, 0xd8, 0xc1, 0x18, 0xf9, 0xee, 0xf3, 0x7f, 0x1f, 0x8e, 0x8b, 0xa1,
-	0x3e, 0x84, 0xb4, 0x5a, 0x0e, 0x9e, 0xdd, 0x61, 0xce, 0xf1, 0x6a, 0xef,
-	0xe6, 0xff, 0xd3, 0x8e, 0xad, 0x45, 0x13, 0xfb, 0x1b, 0x3b, 0x82, 0xfa,
-	0xac, 0x71, 0xbe, 0xab, 0x61, 0xfe, 0x8a, 0xfa, 0xce, 0x5a, 0x28, 0xb7,
-	0xfd, 0x0a, 0x1e, 0x58, 0x96, 0x86, 0x98, 0xe7, 0x7d, 0xe4, 0xf3, 0xfb,
-	0x9f, 0xab, 0xb7, 0xab, 0x6f, 0x72, 0xae, 0xca, 0xb7, 0x61, 0xe7, 0x23,
-	0xa5, 0x1d, 0x81, 0x2f, 0x60, 0x3f, 0xa1, 0x05, 0xfe, 0xfd, 0x8f, 0x81,
-	0x07, 0xbc, 0xf6, 0x1a, 0x6b, 0x38, 0x2b, 0xbc, 0x4b, 0xb9, 0x32, 0xc5,
-	0xdc, 0xba, 0xa4, 0x70, 0xb3, 0xd6, 0x63, 0xdd, 0x17, 0xc5, 0x80, 0x08,
-	0xd7, 0xcf, 0x13, 0x01, 0xdd, 0xe3, 0xa8, 0xe9, 0x08, 0x13, 0x8d, 0x1b,
-	0xeb, 0xbf, 0x8e, 0xf0, 0x1e, 0xee, 0x4a, 0x90, 0x57, 0x29, 0x7c, 0x66,
-	0x88, 0xef, 0x3f, 0xfd, 0xc0, 0xf7, 0x70, 0xbd, 0xd5, 0xb0, 0xfe, 0x3c,
-	0x72, 0x3d, 0xde, 0x99, 0xec, 0x52, 0xdf, 0x19, 0xdf, 0x9f, 0xed, 0x94,
-	0x5f, 0x3c, 0xe3, 0xfb, 0xe3, 0x4e, 0x7a, 0xf8, 0x4d, 0xd4, 0x1e, 0x67,
-	0x68, 0x27, 0x23, 0xa4, 0x73, 0x30, 0x35, 0x2d, 0x03, 0xbd, 0x41, 0x2e,
-	0xfe, 0x75, 0xed, 0xe3, 0x74, 0xeb, 0xe1, 0x3e, 0x3f, 0x6c, 0xd8, 0x27,
-	0xd5, 0xb0, 0xcf, 0x0a, 0x6d, 0xb6, 0x7a, 0x2f, 0xce, 0x5c, 0xdc, 0x75,
-	0xa3, 0x95, 0x08, 0xeb, 0xb2, 0x47, 0x47, 0xda, 0xa4, 0xd2, 0x97, 0x5e,
-	0xf9, 0x11, 0xf2, 0xf5, 0xc2, 0x08, 0xe6, 0x12, 0x83, 0x78, 0xc7, 0xf9,
-	0x74, 0x15, 0xb9, 0xe8, 0x4a, 0x55, 0x86, 0xb0, 0x3e, 0x5d, 0x14, 0xe1,
-	0x3c, 0xfb, 0x8a, 0xb6, 0x6a, 0xe8, 0x03, 0x92, 0x6b, 0x38, 0xf3, 0x04,
-	0xea, 0xaf, 0x13, 0xeb, 0xf5, 0x30, 0xf7, 0xb9, 0x59, 0x5b, 0x53, 0xb9,
-	0xf1, 0x01, 0xad, 0x98, 0x08, 0xce, 0xf8, 0x87, 0xf0, 0x17, 0x86, 0xce,
-	0xb5, 0xef, 0x03, 0xb7, 0x26, 0x0b, 0xcf, 0x18, 0xea, 0x0e, 0xb6, 0x30,
-	0x42, 0x59, 0xf3, 0x79, 0x2d, 0xde, 0x45, 0x67, 0xfa, 0xf3, 0xf0, 0x4c,
-	0xd9, 0xb0, 0x9e, 0x8e, 0xce, 0x14, 0x93, 0x77, 0x67, 0x2d, 0xac, 0xfd,
-	0x1c, 0xf8, 0x91, 0x97, 0xa5, 0x7a, 0xea, 0x33, 0xf0, 0x94, 0x1b, 0x78,
-	0x63, 0x6e, 0x91, 0x61, 0x71, 0xa3, 0x86, 0x1f, 0x4f, 0xc2, 0x0e, 0xbf,
-	0xd1, 0x1b, 0xdd, 0x0d, 0x1b, 0xb6, 0xcf, 0xba, 0x07, 0x8d, 0xf3, 0xfd,
-	0xb0, 0xc5, 0x14, 0xec, 0x93, 0x39, 0x53, 0x9e, 0xb5, 0x0a, 0xed, 0xc9,
-	0x72, 0x8d, 0xb4, 0x75, 0x4c, 0x86, 0x51, 0xef, 0xf0, 0xfc, 0x19, 0x59,
-	0xac, 0x47, 0x34, 0x8c, 0xc2, 0x1e, 0x0f, 0xe2, 0xb7, 0x1f, 0xef, 0x1c,
-	0xfc, 0x58, 0x2b, 0xad, 0xc8, 0xe3, 0x2a, 0x17, 0x47, 0xae, 0x3d, 0x44,
-	0xfa, 0xee, 0x04, 0x3c, 0xf5, 0x99, 0x7a, 0x7a, 0xa7, 0xb8, 0x7d, 0xf4,
-	0x15, 0x49, 0xe0, 0xc6, 0x1a, 0xef, 0x22, 0x6c, 0xbd, 0x1f, 0xcf, 0xb4,
-	0x55, 0x20, 0x6f, 0x15, 0x7e, 0xdf, 0x37, 0x46, 0xf9, 0x8d, 0xe2, 0x7c,
-	0x38, 0x1e, 0xb4, 0xbe, 0x4c, 0xdd, 0x4b, 0xee, 0x96, 0x95, 0xf9, 0x28,
-	0x0e, 0x9e, 0x86, 0x0d, 0xf2, 0xce, 0x76, 0x0c, 0x7c, 0xe1, 0x58, 0x0b,
-	0xe3, 0x21, 0xe6, 0x17, 0x97, 0x71, 0xee, 0x8c, 0x9c, 0x41, 0xfd, 0x2f,
-	0x7d, 0x7c, 0xa6, 0x80, 0x7f, 0x7b, 0xa8, 0xef, 0x9b, 0xd7, 0x1b, 0x36,
-	0xfb, 0x63, 0xa0, 0xcf, 0x6c, 0x58, 0xcf, 0x35, 0x41, 0x7d, 0xb2, 0x26,
-	0x88, 0xc7, 0x49, 0xff, 0x76, 0x3d, 0xf3, 0xa2, 0x3c, 0xa0, 0xce, 0x54,
-	0x93, 0xe3, 0xf3, 0xbe, 0xef, 0x8e, 0x0e, 0x0e, 0x2f, 0x4a, 0x7a, 0xf8,
-	0xa4, 0xec, 0xb3, 0x0e, 0xb1, 0x1e, 0xb3, 0x88, 0xc7, 0xbf, 0xbd, 0x25,
-	0xe3, 0xfb, 0xa7, 0x41, 0xfb, 0xf7, 0xd5, 0x3e, 0x2f, 0x82, 0x7e, 0xf0,
-	0x4a, 0xd5, 0x24, 0xa4, 0x15, 0xcf, 0x04, 0xe9, 0x2d, 0xcb, 0xf1, 0xfa,
-	0x85, 0x50, 0x36, 0x8f, 0x89, 0xeb, 0x5d, 0x36, 0x5c, 0xbb, 0x0c, 0xd8,
-	0x85, 0x90, 0xb6, 0x0c, 0xe8, 0xc5, 0xfe, 0xf5, 0xb7, 0x13, 0xf4, 0x0d,
-	0x94, 0xb9, 0x8b, 0xac, 0xd1, 0x1d, 0x41, 0x1e, 0x95, 0xf8, 0x24, 0x3f,
-	0x10, 0x97, 0xcd, 0x7e, 0x80, 0xeb, 0xe2, 0xd7, 0xd0, 0x15, 0xd2, 0x51,
-	0x54, 0xfe, 0x53, 0xc5, 0x2d, 0x85, 0xcf, 0xd8, 0xe2, 0x0b, 0x2a, 0xea,
-	0xb9, 0x6a, 0xd0, 0x37, 0x31, 0xfe, 0x51, 0x87, 0xbb, 0xe0, 0xff, 0xa0,
-	0x83, 0xb0, 0xe3, 0xdc, 0x3c, 0xef, 0x27, 0x86, 0x78, 0xaf, 0x74, 0x36,
-	0x0f, 0xd9, 0x2e, 0xf0, 0xfb, 0x63, 0x22, 0xa8, 0x31, 0x83, 0xfa, 0x2b,
-	0x45, 0x5f, 0x88, 0xb6, 0xa4, 0xfc, 0x64, 0x5e, 0x7d, 0x6f, 0x8c, 0x03,
-	0xc6, 0xa7, 0xef, 0x6c, 0xf8, 0x9b, 0x89, 0x1f, 0x64, 0x83, 0xbf, 0x99,
-	0x08, 0xbf, 0xfd, 0x56, 0x83, 0x3c, 0xe2, 0xe1, 0x9a, 0x29, 0x13, 0xb5,
-	0xe8, 0x6f, 0x28, 0x28, 0x07, 0xf8, 0xe6, 0x5a, 0x94, 0x3b, 0xf8, 0x41,
-	0x4d, 0xb3, 0x49, 0x96, 0x4b, 0x61, 0x4e, 0xc4, 0x1a, 0x80, 0x3c, 0xc4,
-	0x78, 0x31, 0xaa, 0x2f, 0x07, 0x20, 0x3f, 0xf0, 0x1c, 0x74, 0xbd, 0x3b,
-	0x1b, 0xd4, 0xb9, 0x25, 0xfa, 0xc5, 0xfe, 0xa8, 0xee, 0xdd, 0x25, 0xa5,
-	0x63, 0x7c, 0x1f, 0x93, 0x77, 0x66, 0x63, 0xea, 0x7d, 0x41, 0x62, 0xe1,
-	0x7b, 0x8e, 0xe3, 0x52, 0x50, 0xef, 0xab, 0x21, 0x3e, 0xd4, 0x69, 0x5f,
-	0x89, 0xc6, 0xa6, 0x76, 0xbc, 0x1e, 0xac, 0x9b, 0xac, 0x57, 0xe5, 0xf1,
-	0xfa, 0x2a, 0xce, 0xaf, 0x49, 0x6e, 0xbc, 0x28, 0xbb, 0x6d, 0x4b, 0xc5,
-	0x7d, 0x37, 0x4e, 0x1d, 0xa3, 0x7e, 0x8d, 0xa9, 0xba, 0xb3, 0x88, 0x7c,
-	0xa1, 0x30, 0xc2, 0x6f, 0x3c, 0xbf, 0xba, 0xab, 0x50, 0x4e, 0x5b, 0x59,
-	0xf9, 0xd0, 0x77, 0x4d, 0x8e, 0x45, 0x47, 0x3d, 0x74, 0xd7, 0xc3, 0xb5,
-	0x0b, 0x77, 0x05, 0x67, 0xc5, 0xfb, 0x1a, 0x61, 0x0d, 0xf5, 0x6d, 0xf6,
-	0x5f, 0x6f, 0x35, 0x65, 0xed, 0x56, 0xdf, 0xbf, 0xdf, 0xb1, 0xc4, 0x0d,
-	0x6b, 0x57, 0x4b, 0xd5, 0xae, 0xed, 0x2a, 0x07, 0x71, 0x47, 0x52, 0x5a,
-	0x1e, 0xf6, 0x7a, 0xc6, 0x43, 0x9d, 0xa3, 0xa7, 0x0f, 0xae, 0xea, 0x16,
-	0x62, 0x6e, 0x3a, 0x35, 0x27, 0x6e, 0x2f, 0xbf, 0x37, 0xcf, 0x38, 0x84,
-	0xd9, 0x19, 0xdc, 0x75, 0xdd, 0x34, 0xae, 0xfc, 0xac, 0x48, 0x18, 0x7b,
-	0x6e, 0x6a, 0xb4, 0x89, 0xc6, 0xdc, 0x92, 0xb6, 0x20, 0x13, 0x26, 0x68,
-	0x29, 0x95, 0xa3, 0x3c, 0x8d, 0x7f, 0x1b, 0xb0, 0x7a, 0xd7, 0xd3, 0xa0,
-	0x73, 0x1a, 0x74, 0xf2, 0x1c, 0xd3, 0xb5, 0x48, 0xe7, 0xa2, 0x5a, 0x81,
-	0x7d, 0xc4, 0x7c, 0x0f, 0x31, 0xdf, 0x43, 0xcc, 0xf7, 0x10, 0xf3, 0x3d,
-	0xc4, 0x7c, 0x0f, 0x31, 0xdf, 0x43, 0xcc, 0xf7, 0x10, 0xf3, 0xbd, 0xf1,
-	0x30, 0x4f, 0x7b, 0x62, 0x3d, 0x4f, 0x5b, 0xa9, 0xf3, 0x3b, 0x94, 0xa2,
-	0xa5, 0x58, 0x94, 0x20, 0xcf, 0x15, 0x9d, 0x39, 0x4d, 0x94, 0xe7, 0x5e,
-	0xfb, 0x9b, 0x48, 0xb0, 0x8e, 0x39, 0x1e, 0xd7, 0x15, 0x35, 0xdd, 0xe6,
-	0xba, 0x20, 0xcf, 0x63, 0x6d, 0xb5, 0x79, 0x0d, 0xf2, 0xb5, 0x0c, 0xfd,
-	0x19, 0xed, 0x22, 0x11, 0xd4, 0x8b, 0x99, 0xf3, 0xf7, 0xba, 0x88, 0xbf,
-	0x85, 0x9a, 0x8a, 0xc1, 0xbc, 0x17, 0xbc, 0x97, 0x7f, 0xb7, 0x00, 0x39,
-	0xf0, 0xdd, 0x7d, 0xac, 0x27, 0x0a, 0xb5, 0xa4, 0x14, 0x17, 0xa3, 0xfc,
-	0x07, 0xeb, 0xbc, 0x7d, 0x5a, 0xbe, 0x42, 0xd9, 0xea, 0x32, 0x9d, 0x00,
-	0x53, 0xec, 0xc6, 0xbc, 0xee, 0x4d, 0x55, 0x23, 0xad, 0xd4, 0x49, 0xcf,
-	0x7e, 0xd0, 0x16, 0xdd, 0xe3, 0x8a, 0x18, 0xb3, 0x09, 0xd1, 0x67, 0x91,
-	0xd3, 0xda, 0x43, 0xea, 0x6f, 0x1d, 0x7a, 0xb0, 0x8f, 0x3e, 0x3b, 0x10,
-	0xfd, 0x2d, 0x06, 0xeb, 0xae, 0xec, 0xc6, 0xfd, 0x2b, 0xcf, 0x91, 0x80,
-	0xbd, 0x7e, 0x69, 0x27, 0xce, 0x06, 0xb9, 0x5e, 0xde, 0xa1, 0xf2, 0x6e,
-	0xf8, 0xce, 0xd3, 0x43, 0xe9, 0x3e, 0xe9, 0xda, 0x25, 0x67, 0x86, 0x58,
-	0xa3, 0xb5, 0x01, 0x1f, 0x61, 0x79, 0xe7, 0xb4, 0x4b, 0x96, 0xe7, 0xe1,
-	0x5b, 0xe7, 0xd3, 0x0e, 0xff, 0xbe, 0x60, 0x01, 0x21, 0x6d, 0xa1, 0x3e,
-	0xd6, 0xc7, 0x98, 0xbc, 0x58, 0xa7, 0xae, 0xf4, 0x60, 0x7d, 0x3f, 0x74,
-	0x71, 0x1b, 0x6c, 0x48, 0xc7, 0xfe, 0x11, 0xee, 0xf7, 0x14, 0xee, 0x1e,
-	0xfb, 0xb7, 0x77, 0x2a, 0xdd, 0xd0, 0xd3, 0x56, 0x4a, 0x07, 0xed, 0x1f,
-	0xab, 0x2d, 0x1d, 0xe1, 0xf7, 0xc2, 0x69, 0xaf, 0xf1, 0xbb, 0xe1, 0x3e,
-	0xad, 0x50, 0xe1, 0xdf, 0x38, 0x0c, 0xc9, 0x21, 0x8b, 0x7f, 0xff, 0xb3,
-	0x4f, 0x7b, 0xa0, 0x4a, 0x18, 0x1b, 0x7d, 0xd6, 0xe1, 0xcb, 0xb0, 0xe5,
-	0xff, 0x29, 0xdc, 0xea, 0x62, 0xdb, 0x3a, 0xcb, 0xf0, 0xfb, 0x1d, 0xe7,
-	0xc7, 0x4d, 0xdd, 0xe4, 0x34, 0x71, 0x12, 0x27, 0xca, 0xc0, 0xc7, 0x39,
-	0x49, 0x3d, 0x39, 0xd5, 0x4e, 0xa2, 0x14, 0x22, 0x88, 0x84, 0xe5, 0xfc,
-	0xcc, 0x63, 0x14, 0x3c, 0xc8, 0xa6, 0x4e, 0x42, 0x55, 0x94, 0x74, 0x5b,
-	0x27, 0xee, 0xb8, 0x40, 0x5c, 0x80, 0x6a, 0x39, 0x69, 0xe9, 0x86, 0x3d,
-	0xa7, 0x5b, 0xba, 0x00, 0x57, 0x9e, 0xe3, 0xa4, 0x4d, 0xe7, 0xcc, 0x1a,
-	0x03, 0x69, 0x70, 0x41, 0x23, 0x33, 0x6d, 0xe3, 0x66, 0x37, 0x48, 0x5c,
-	0x57, 0x29, 0x83, 0x02, 0x6b, 0x2b, 0xb8, 0xe1, 0xef, 0xe2, 0xf0, 0x3c,
-	0xdf, 0x39, 0x76, 0xd3, 0xc0, 0x44, 0x24, 0xeb, 0x7c, 0xe7, 0x3b, 0xdf,
-	0xff, 0xf7, 0xbe, 0xcf, 0xfb, 0x9b, 0x6e, 0xb9, 0x08, 0x3a, 0xce, 0x8d,
-	0xb5, 0xfa, 0xfe, 0xd6, 0x0e, 0x9f, 0x87, 0x07, 0xfb, 0x7c, 0x19, 0xa5,
-	0x75, 0xc9, 0x9c, 0xd6, 0xa7, 0xbb, 0x0e, 0x7d, 0x7b, 0x16, 0x6b, 0x8a,
-	0xe0, 0x1c, 0x1e, 0xe9, 0xd3, 0x78, 0x64, 0xf0, 0xbd, 0xff, 0xd0, 0x7b,
-	0xdf, 0xa1, 0xf7, 0xde, 0xff, 0xd1, 0x9e, 0xe5, 0xc3, 0xf4, 0xc0, 0x75,
-	0x5a, 0x53, 0x1a, 0xfd, 0xf2, 0x93, 0x6a, 0x39, 0x6f, 0x25, 0xa9, 0x0b,
-	0xcc, 0x88, 0xab, 0x66, 0x9c, 0x36, 0x60, 0x5c, 0x9b, 0xac, 0xae, 0x83,
-	0xe6, 0xb1, 0x8f, 0x76, 0x9b, 0xf1, 0xf2, 0x89, 0x3e, 0xf2, 0x4c, 0x10,
-	0xd7, 0x60, 0xd8, 0xc3, 0x11, 0xb4, 0x73, 0x5f, 0x74, 0x12, 0xe6, 0x39,
-	0xed, 0xbf, 0xa1, 0x0e, 0xe3, 0xaa, 0x9c, 0xce, 0xfd, 0x60, 0x9b, 0x16,
-	0xb9, 0x6d, 0xa7, 0xba, 0xfd, 0xdc, 0x20, 0xd8, 0xbb, 0xa9, 0x3e, 0xea,
-	0x17, 0x2f, 0x38, 0xcd, 0x3a, 0x73, 0x5f, 0x98, 0x77, 0x05, 0xa2, 0x79,
-	0x4a, 0xa4, 0x54, 0x11, 0xb9, 0x86, 0xdf, 0x6f, 0x2a, 0x7e, 0xfc, 0x42,
-	0xd1, 0xd6, 0x9e, 0x96, 0x1b, 0xc5, 0x2f, 0x48, 0x15, 0x32, 0x67, 0xc7,
-	0x71, 0xdd, 0x3b, 0x4e, 0x54, 0x9f, 0xf9, 0x0f, 0xf2, 0x4a, 0x62, 0xe3,
-	0x94, 0x69, 0x6d, 0xf2, 0xc3, 0x75, 0xe6, 0xd5, 0x59, 0xe6, 0x1d, 0x61,
-	0x7e, 0x5b, 0x44, 0xd2, 0xe1, 0x80, 0xd6, 0x4b, 0xe5, 0x69, 0x68, 0x12,
-	0xf8, 0xf6, 0x87, 0xf5, 0xb3, 0x7d, 0xf4, 0xb9, 0x7c, 0xbc, 0xce, 0x77,
-	0x03, 0x4f, 0x43, 0xea, 0x76, 0x00, 0xfa, 0x2b, 0x80, 0xc7, 0xe4, 0xb9,
-	0x73, 0xbf, 0xcf, 0x73, 0x6d, 0xa8, 0xa3, 0x0d, 0xdb, 0x26, 0xb9, 0x11,
-	0xe0, 0xa0, 0x1a, 0xd6, 0xf9, 0x47, 0xf5, 0xb0, 0xc6, 0xe5, 0x40, 0x99,
-	0x7e, 0x7b, 0xf3, 0xa8, 0xc6, 0xe8, 0xd4, 0xee, 0xf7, 0xf4, 0x5e, 0x50,
-	0xce, 0x96, 0x1d, 0xd2, 0xaa, 0x29, 0x3b, 0xe0, 0xb5, 0xeb, 0xb5, 0x37,
-	0xfa, 0x79, 0x57, 0x37, 0x6a, 0xdf, 0xef, 0xf3, 0x6c, 0x34, 0xd6, 0x5d,
-	0xe8, 0xf3, 0xea, 0xa2, 0xbe, 0xcd, 0x45, 0xdb, 0xac, 0x84, 0xbd, 0x7d,
-	0x5b, 0x6a, 0x1b, 0xdf, 0x95, 0x77, 0x8b, 0xdf, 0x91, 0x5f, 0x6c, 0x9c,
-	0x81, 0xce, 0x61, 0x95, 0xb2, 0x90, 0x27, 0x6f, 0xd7, 0x5c, 0xf7, 0x6d,
-	0x67, 0x01, 0xf6, 0x81, 0xeb, 0xfe, 0xd6, 0xd9, 0x93, 0xd8, 0xc4, 0x37,
-	0xb1, 0xe7, 0x0c, 0x78, 0x88, 0x58, 0x98, 0x06, 0xbd, 0x7d, 0xb1, 0x5f,
-	0x3a, 0x42, 0x9a, 0x4e, 0x86, 0x27, 0x5a, 0xb1, 0x07, 0xc3, 0xd7, 0xc3,
-	0xb9, 0x97, 0xe9, 0x7e, 0xd2, 0x8c, 0x51, 0xfb, 0x09, 0xe6, 0x6f, 0x05,
-	0x5f, 0x1c, 0xc5, 0x4f, 0xc9, 0x9d, 0x71, 0xac, 0x75, 0x9c, 0xb4, 0xd7,
-	0x2a, 0xb1, 0xc7, 0xb0, 0x8f, 0x4c, 0x8b, 0xdc, 0xcb, 0x6f, 0xf6, 0xd1,
-	0x9f, 0x77, 0x2f, 0xcf, 0xb2, 0xf1, 0xb9, 0x4e, 0x71, 0xa5, 0x05, 0xf2,
-	0x7b, 0x75, 0xd2, 0xd3, 0x95, 0x7e, 0xad, 0x4e, 0xa0, 0xbd, 0x9d, 0x7d,
-	0x4f, 0x51, 0xb7, 0xcb, 0xba, 0xad, 0xd0, 0xc5, 0xe7, 0xa0, 0x03, 0xa5,
-	0x6a, 0x17, 0xa4, 0x3e, 0x1e, 0x42, 0x1b, 0xea, 0x28, 0x1a, 0x4b, 0x64,
-	0x26, 0xcf, 0x7c, 0x2d, 0xe6, 0x4e, 0x61, 0x8d, 0x0b, 0xc4, 0x0d, 0xae,
-	0xb1, 0x8d, 0x31, 0x38, 0xbf, 0xce, 0x06, 0x8d, 0xb0, 0x8e, 0xf4, 0x9d,
-	0x04, 0x4f, 0x26, 0x29, 0x37, 0x31, 0xde, 0x18, 0xc6, 0x63, 0xb9, 0x13,
-	0xe3, 0x5d, 0x90, 0x94, 0xd3, 0x18, 0x73, 0x0a, 0x6d, 0x88, 0x33, 0x53,
-	0xd0, 0x1f, 0x86, 0xd4, 0xec, 0x7a, 0x18, 0xf2, 0xbb, 0x4f, 0x66, 0xcd,
-	0x23, 0x07, 0xf6, 0x98, 0xd5, 0xf6, 0x81, 0x61, 0x8c, 0xf9, 0x6b, 0xea,
-	0x3c, 0xb0, 0x26, 0xf6, 0xc7, 0x0f, 0xb6, 0x71, 0x6a, 0x7d, 0x0d, 0x38,
-	0xb5, 0xf6, 0x61, 0xca, 0x39, 0x2b, 0x33, 0x61, 0xae, 0x89, 0xf5, 0x61,
-	0xac, 0x99, 0x7e, 0xac, 0x67, 0x81, 0x43, 0x47, 0xfc, 0x3a, 0xb6, 0x15,
-	0x23, 0x85, 0xb3, 0xf7, 0xec, 0x5a, 0xd6, 0x7d, 0x56, 0x52, 0x6b, 0x19,
-	0x99, 0xd7, 0xfd, 0x78, 0x86, 0x83, 0x5a, 0xf7, 0x20, 0xaf, 0xc6, 0x7a,
-	0x70, 0x96, 0x89, 0x07, 0x36, 0x70, 0xb4, 0x47, 0xcb, 0xcc, 0x7e, 0x8f,
-	0x67, 0xf1, 0xad, 0x87, 0x77, 0xd4, 0x26, 0xb1, 0x6f, 0x40, 0x46, 0xe6,
-	0x1b, 0xf5, 0x21, 0xf9, 0x24, 0xdf, 0xd1, 0xcf, 0x38, 0xcb, 0xdd, 0xbc,
-	0x29, 0x1f, 0xe7, 0x75, 0x2c, 0x74, 0x31, 0x20, 0xd6, 0x79, 0xcf, 0x3e,
-	0x1f, 0x59, 0x5c, 0x55, 0xfc, 0x3e, 0x72, 0x7e, 0x4b, 0x05, 0xd1, 0x36,
-	0x84, 0x76, 0x5c, 0x87, 0x29, 0x73, 0xf9, 0xbf, 0xb9, 0x4b, 0xa3, 0xae,
-	0x3b, 0xaf, 0xf3, 0xc3, 0x12, 0xe6, 0xaa, 0x6a, 0xe8, 0xe4, 0x71, 0xc9,
-	0x87, 0xdb, 0x31, 0x57, 0xc2, 0xdc, 0x52, 0x23, 0x58, 0x0f, 0xcb, 0x3d,
-	0xe4, 0x89, 0xc8, 0x9e, 0x70, 0x7c, 0x2b, 0xbd, 0xa9, 0x12, 0xd1, 0x61,
-	0x65, 0x25, 0x73, 0xf8, 0xb5, 0x28, 0x1d, 0x47, 0x8c, 0x44, 0x15, 0x78,
-	0x17, 0x7b, 0xb2, 0x4f, 0xba, 0x6e, 0xda, 0x66, 0x7d, 0xc2, 0x0c, 0x29,
-	0xfa, 0x5b, 0x3a, 0x74, 0xbc, 0xf1, 0x72, 0x6f, 0xc2, 0x3c, 0xa9, 0x8e,
-	0xfb, 0xef, 0x53, 0xc0, 0xcc, 0xe6, 0x78, 0x67, 0x36, 0x95, 0x29, 0x2f,
-	0xe5, 0x13, 0xd1, 0x65, 0x65, 0x65, 0x30, 0x66, 0x66, 0x56, 0x11, 0x37,
-	0x12, 0x66, 0x87, 0xa2, 0x4f, 0xb4, 0x5d, 0xef, 0x3b, 0x8d, 0xfe, 0x09,
-	0xd5, 0xe2, 0xaf, 0x87, 0xf7, 0xf5, 0xe3, 0x7e, 0x8f, 0x67, 0x88, 0x39,
-	0xa3, 0xc0, 0x4c, 0xe6, 0x9a, 0xe9, 0xdc, 0x86, 0x64, 0x6c, 0x62, 0x54,
-	0x63, 0xe8, 0xfd, 0x53, 0x7f, 0x47, 0x1d, 0xca, 0x25, 0xd6, 0xc5, 0x7d,
-	0x7e, 0x1b, 0xd5, 0x3a, 0xf3, 0xfd, 0x53, 0x59, 0x9d, 0xc7, 0x58, 0x57,
-	0x31, 0x7f, 0xdf, 0xcd, 0x3b, 0x8b, 0xa6, 0x9c, 0x47, 0x38, 0xce, 0x5a,
-	0x60, 0xba, 0x5d, 0x98, 0x23, 0x3a, 0x57, 0x6c, 0xd0, 0x06, 0xfd, 0x01,
-	0xcc, 0x17, 0x68, 0xc4, 0xbd, 0x2f, 0x88, 0x31, 0x11, 0x3c, 0x40, 0x27,
-	0xd0, 0x35, 0xa1, 0xa3, 0x56, 0x30, 0x4e, 0x6e, 0x5d, 0xb2, 0x5e, 0x7f,
-	0x09, 0x32, 0x27, 0x35, 0x57, 0xf9, 0xb4, 0x31, 0x38, 0x37, 0xe6, 0xc0,
-	0xfb, 0xfd, 0x53, 0xa4, 0x4f, 0x9e, 0x4d, 0x54, 0xcd, 0x6d, 0x70, 0x3d,
-	0x83, 0x32, 0xbf, 0x3e, 0x24, 0xcb, 0xf8, 0xad, 0xae, 0x7b, 0xf7, 0xb6,
-	0x0d, 0xdd, 0x7a, 0x3e, 0x6f, 0x6a, 0x7e, 0x5d, 0x76, 0x18, 0x33, 0x01,
-	0xaf, 0xe8, 0x9c, 0x2a, 0xf6, 0x65, 0x5e, 0xe1, 0x10, 0xe5, 0xa3, 0x53,
-	0x87, 0x5c, 0xdd, 0xae, 0x51, 0x4f, 0x65, 0xbd, 0x35, 0x15, 0x0d, 0x74,
-	0xc9, 0x2a, 0xf0, 0xae, 0x0c, 0xd9, 0x99, 0x7b, 0x25, 0x24, 0xcb, 0x79,
-	0x1d, 0x4f, 0x8e, 0xfe, 0x5e, 0x39, 0x52, 0xad, 0x4d, 0xca, 0x6e, 0x2d,
-	0xae, 0xbf, 0x51, 0xae, 0xe5, 0x5e, 0x37, 0xe4, 0xf9, 0x51, 0x9d, 0x57,
-	0x17, 0x2f, 0x4b, 0xef, 0x00, 0x75, 0x9e, 0x2d, 0x9d, 0x63, 0x07, 0xec,
-	0x80, 0xce, 0xf1, 0x33, 0xe8, 0x1c, 0xef, 0x40, 0xe7, 0xf8, 0x69, 0x11,
-	0xf8, 0x52, 0x4c, 0xfb, 0xf8, 0xbf, 0x08, 0x1c, 0xa2, 0xac, 0xb6, 0xce,
-	0xe0, 0x4e, 0x17, 0xb3, 0xa0, 0xc1, 0x5b, 0x92, 0x06, 0xde, 0xa6, 0xe4,
-	0xfa, 0xc6, 0xbc, 0xec, 0x6c, 0x78, 0x79, 0xc8, 0x1f, 0x30, 0x07, 0x6c,
-	0x9c, 0xf7, 0x14, 0x07, 0x0e, 0x1d, 0x91, 0xd8, 0x49, 0xe2, 0x47, 0x50,
-	0x36, 0x0b, 0xef, 0x68, 0x1c, 0xda, 0x2c, 0xb0, 0x1c, 0x10, 0x9d, 0x4f,
-	0xb6, 0xb0, 0x27, 0x65, 0xe7, 0x97, 0xa8, 0x3f, 0xa6, 0x7d, 0x40, 0x9e,
-	0x4f, 0x9e, 0x78, 0xf9, 0x67, 0xff, 0xee, 0x95, 0xce, 0xb3, 0x5b, 0x32,
-	0xbb, 0xd0, 0xae, 0x81, 0x5d, 0xc3, 0x5e, 0xcc, 0x5b, 0xfd, 0x05, 0x6d,
-	0x30, 0x47, 0xb1, 0x4b, 0xb6, 0x21, 0x43, 0xea, 0xf1, 0x2e, 0xad, 0xfb,
-	0xd5, 0xe3, 0x43, 0x3a, 0x17, 0x97, 0xe3, 0xe4, 0x0a, 0xb6, 0xac, 0x14,
-	0xac, 0x68, 0x16, 0xf4, 0xb7, 0x0b, 0x5b, 0xed, 0x3a, 0xee, 0x60, 0x07,
-	0x67, 0x70, 0xa3, 0x46, 0x39, 0x7f, 0x57, 0x63, 0xef, 0x66, 0xed, 0x4f,
-	0x18, 0xc7, 0x3a, 0x93, 0x94, 0x3f, 0xf6, 0x13, 0x03, 0xe9, 0x8f, 0x9a,
-	0xd1, 0xfd, 0xbd, 0x7e, 0xd7, 0xd1, 0x76, 0xa7, 0x46, 0x3c, 0x16, 0xb9,
-	0x94, 0xb7, 0x21, 0x4b, 0x5e, 0x8f, 0x50, 0x07, 0x28, 0xa9, 0x46, 0x3f,
-	0xd7, 0x5f, 0xb3, 0xeb, 0x1e, 0xb5, 0xb9, 0xae, 0xb8, 0x8f, 0xdb, 0x94,
-	0xfd, 0x7b, 0x5a, 0xee, 0xe7, 0x8b, 0x67, 0xe5, 0x2d, 0xdc, 0xb7, 0xa7,
-	0xe3, 0x64, 0xe4, 0x4d, 0xe8, 0x78, 0xb5, 0x62, 0x23, 0x6f, 0x7b, 0x1a,
-	0xe7, 0x64, 0xa9, 0x95, 0x2b, 0x2f, 0xcb, 0xe5, 0xab, 0xfb, 0xea, 0xa5,
-	0xab, 0x31, 0xf5, 0xf2, 0x95, 0x61, 0x95, 0xbb, 0xe2, 0xba, 0xff, 0x74,
-	0x96, 0xe4, 0xdd, 0x0d, 0x57, 0x4e, 0x3b, 0xc6, 0x40, 0x40, 0x1a, 0xb9,
-	0x75, 0xae, 0x1b, 0x04, 0x36, 0xdf, 0xe8, 0x75, 0xdd, 0x47, 0xc7, 0xc7,
-	0x25, 0xde, 0x4b, 0x1d, 0xe5, 0xf3, 0x11, 0xe6, 0xbb, 0x12, 0x73, 0x52,
-	0xb6, 0x7d, 0xbe, 0xac, 0x14, 0xf0, 0xad, 0xcb, 0xd3, 0x5f, 0x1e, 0x3b,
-	0xe6, 0xc7, 0x4a, 0x7e, 0xf4, 0x22, 0x7d, 0xc9, 0x91, 0xff, 0xf2, 0x25,
-	0x9b, 0x72, 0xae, 0xf0, 0x19, 0xf4, 0x0f, 0xcb, 0xb7, 0x0a, 0xa1, 0x43,
-	0x65, 0x13, 0xcf, 0x31, 0x95, 0x2b, 0xdc, 0x73, 0x87, 0x75, 0xcc, 0x00,
-	0x3a, 0x89, 0xe9, 0xba, 0xcb, 0x0e, 0xe7, 0xeb, 0xc2, 0x7c, 0x7b, 0xe6,
-	0x31, 0xc8, 0xff, 0xd3, 0x5a, 0x3e, 0x9f, 0x53, 0xb0, 0x7d, 0xc1, 0xdf,
-	0x61, 0x99, 0x2d, 0x40, 0xc6, 0x2b, 0xe6, 0x9c, 0x52, 0x57, 0xb0, 0x22,
-	0xcb, 0xc0, 0x8e, 0x25, 0xe0, 0xcd, 0x93, 0x3a, 0xb6, 0xda, 0xa3, 0xb1,
-	0x67, 0x85, 0xe5, 0x8c, 0x24, 0xcb, 0x4e, 0xb7, 0x3e, 0xbf, 0xfd, 0xdd,
-	0x57, 0x23, 0xde, 0x9d, 0x83, 0x8f, 0x33, 0x4a, 0xda, 0x60, 0x03, 0xcd,
-	0x6c, 0x2d, 0x80, 0x27, 0x22, 0x38, 0xdb, 0x56, 0xcd, 0x0f, 0x75, 0xc8,
-	0xef, 0xba, 0xf6, 0x23, 0x7a, 0xf1, 0x8a, 0xba, 0xc9, 0x76, 0xcf, 0xa0,
-	0x5f, 0xbb, 0xa4, 0xae, 0xb4, 0x69, 0x5c, 0x7d, 0xb8, 0x2e, 0x09, 0x3d,
-	0xe4, 0x69, 0x94, 0x03, 0xa8, 0x8b, 0xfa, 0x65, 0x03, 0xe5, 0x45, 0x94,
-	0x5b, 0xf0, 0x64, 0x9b, 0x11, 0xe8, 0x15, 0x78, 0xbe, 0x81, 0xf1, 0xc6,
-	0xb1, 0xe6, 0x8c, 0x29, 0x1f, 0x9d, 0xa2, 0x2c, 0x19, 0x53, 0xcc, 0x4b,
-	0x5e, 0xb6, 0xf1, 0xac, 0x0e, 0xab, 0x99, 0x35, 0x96, 0xf1, 0x2c, 0x79,
-	0xdf, 0x1f, 0xc2, 0x24, 0xf4, 0x49, 0x5d, 0xf5, 0x30, 0xe9, 0xa3, 0x26,
-	0x26, 0xb1, 0xae, 0x5d, 0x66, 0xaf, 0x90, 0xd7, 0x4d, 0xd0, 0x5b, 0x87,
-	0xcc, 0x5c, 0x0d, 0x6b, 0x7d, 0xb4, 0x0c, 0x5a, 0xdc, 0x06, 0x5d, 0x6d,
-	0x82, 0xa6, 0x52, 0x05, 0x6b, 0x6a, 0x51, 0x45, 0xb5, 0x2f, 0xe0, 0x09,
-	0xd0, 0x6b, 0xf0, 0x15, 0xea, 0xa2, 0xe4, 0xe5, 0x38, 0x68, 0x4f, 0xdc,
-	0xa0, 0x6d, 0xa7, 0xe3, 0xca, 0x06, 0x0d, 0x82, 0x2e, 0x0b, 0x1e, 0x4f,
-	0xbf, 0xa7, 0x34, 0xae, 0x4e, 0xdd, 0x96, 0x44, 0xf2, 0xb6, 0x58, 0xc0,
-	0x02, 0xcb, 0xf9, 0x50, 0x1c, 0x8c, 0x39, 0x29, 0xd7, 0x30, 0x8f, 0x01,
-	0xfe, 0x1e, 0x3d, 0xa1, 0xf9, 0x7b, 0x4a, 0x02, 0x87, 0x79, 0x1c, 0xf4,
-	0x06, 0x0c, 0xf2, 0x78, 0x3a, 0xe9, 0xd3, 0xe8, 0xd7, 0xc1, 0xbf, 0x16,
-	0x2c, 0xb1, 0xb0, 0xac, 0x82, 0xff, 0xb7, 0xf1, 0xfd, 0x66, 0x6d, 0x44,
-	0xad, 0xac, 0x29, 0x3f, 0x97, 0xe4, 0x19, 0xe8, 0xc9, 0xb7, 0x70, 0x76,
-	0x9d, 0x5a, 0x77, 0x8f, 0x8d, 0x33, 0x7e, 0x96, 0x56, 0x97, 0xed, 0x93,
-	0xb2, 0x3f, 0x36, 0x89, 0xf2, 0x31, 0x3c, 0x0d, 0x9c, 0x43, 0x48, 0xc7,
-	0xbf, 0x37, 0xf3, 0x8e, 0xf2, 0xfe, 0x67, 0x61, 0x42, 0xe7, 0xe7, 0x1b,
-	0x76, 0x2f, 0xbe, 0xd3, 0x17, 0xc3, 0xbd, 0x41, 0x67, 0x52, 0x11, 0x9d,
-	0x6f, 0x5a, 0x86, 0x2e, 0xb1, 0x85, 0xf1, 0xde, 0xa7, 0x2f, 0xaf, 0x0a,
-	0x1e, 0x1e, 0xfb, 0x97, 0x9b, 0x0c, 0x33, 0x47, 0xfd, 0x6e, 0xc4, 0x93,
-	0x7f, 0x9f, 0xb8, 0xfb, 0xf6, 0xca, 0x94, 0x81, 0x97, 0x5b, 0x66, 0x18,
-	0x6d, 0x21, 0xcb, 0x20, 0x8b, 0x4a, 0x9a, 0x7e, 0xd9, 0xce, 0xeb, 0x9b,
-	0xab, 0x26, 0xcc, 0x0f, 0xc4, 0xeb, 0xbb, 0x6a, 0x53, 0xee, 0xb4, 0x03,
-	0x5f, 0xa2, 0x5a, 0xaf, 0x7c, 0xdf, 0xce, 0x02, 0x15, 0xac, 0x68, 0x1a,
-	0x34, 0xda, 0x26, 0x56, 0x7c, 0x4e, 0x1e, 0xcc, 0xbb, 0xac, 0xfb, 0xb2,
-	0x6d, 0xa3, 0x6f, 0x63, 0x5e, 0xae, 0x9f, 0x7b, 0xe1, 0x1e, 0xe8, 0x9b,
-	0x36, 0x35, 0x8d, 0xd6, 0xab, 0xdd, 0x03, 0x1e, 0x8d, 0x36, 0xf6, 0x11,
-	0xfe, 0x3f, 0xfb, 0x20, 0x9d, 0x38, 0xca, 0xcb, 0xbb, 0xc0, 0xb3, 0xca,
-	0xf3, 0x1c, 0x01, 0x6d, 0x1c, 0xa4, 0x9f, 0x86, 0x6f, 0xd1, 0xa3, 0x9f,
-	0x47, 0x9b, 0xf4, 0x43, 0xba, 0xe9, 0x90, 0xd9, 0xab, 0xb6, 0xcc, 0x17,
-	0xf4, 0x7d, 0x43, 0xd7, 0xa4, 0xcf, 0x68, 0x12, 0x74, 0x43, 0x5a, 0x27,
-	0x6f, 0x99, 0x52, 0x02, 0x1d, 0x95, 0x80, 0x4f, 0x25, 0xd0, 0x54, 0x19,
-	0xf8, 0x56, 0x02, 0xbe, 0x95, 0x6a, 0x56, 0xbc, 0x82, 0x3d, 0x53, 0x66,
-	0x6f, 0x81, 0x8e, 0xb6, 0x6b, 0xbc, 0x7f, 0xbd, 0x66, 0x93, 0x72, 0xf0,
-	0x66, 0xf3, 0xee, 0xff, 0x81, 0xbb, 0x1f, 0x92, 0x5d, 0xd8, 0x2d, 0x6f,
-	0x15, 0xc7, 0x80, 0x49, 0x02, 0x8c, 0x72, 0x40, 0x1b, 0x53, 0x72, 0xbd,
-	0x38, 0x2d, 0x3b, 0x90, 0x4f, 0x37, 0x36, 0x62, 0xd0, 0xa7, 0x23, 0xb2,
-	0xf2, 0xda, 0xa8, 0xbc, 0xb9, 0xa1, 0x64, 0x09, 0xf4, 0x9b, 0xdb, 0xa4,
-	0xdf, 0x1d, 0xf4, 0x5c, 0xea, 0xd0, 0x71, 0xfa, 0xd9, 0x8a, 0xe7, 0x7f,
-	0x9f, 0xab, 0x74, 0xca, 0x7c, 0xc5, 0x94, 0xc7, 0x2b, 0xdd, 0xf2, 0xe5,
-	0x4a, 0x58, 0x4e, 0xc3, 0x0e, 0xfc, 0x4a, 0x65, 0x50, 0x9e, 0xac, 0x0c,
-	0xc9, 0x57, 0xab, 0x51, 0xf9, 0x5a, 0xd5, 0x96, 0x4c, 0x35, 0x2e, 0xe9,
-	0xea, 0x98, 0x3c, 0x51, 0xa5, 0x5f, 0x1d, 0xf3, 0xe1, 0x37, 0xd3, 0xf4,
-	0x57, 0x70, 0x5d, 0x41, 0xac, 0x2b, 0xae, 0xe6, 0x74, 0x9c, 0x52, 0x32,
-	0x9e, 0xcf, 0x43, 0xe4, 0x39, 0x8c, 0x75, 0xf1, 0x35, 0x25, 0x65, 0x3d,
-	0x7f, 0xe3, 0xff, 0x46, 0x42, 0xda, 0x36, 0x7a, 0xae, 0x34, 0x88, 0x36,
-	0x90, 0x7b, 0xf9, 0x86, 0xef, 0xa3, 0xe1, 0xf3, 0x6f, 0xd8, 0x5e, 0x86,
-	0xf6, 0x5b, 0xdf, 0xa4, 0xed, 0xa5, 0xcf, 0x9e, 0xf8, 0x41, 0x3b, 0xe7,
-	0x9a, 0xf6, 0x9b, 0x3c, 0x88, 0x6d, 0x34, 0xe6, 0xbd, 0x98, 0x79, 0xf8,
-	0xff, 0x53, 0xbc, 0x18, 0xd5, 0xb9, 0xea, 0x20, 0xff, 0x4f, 0x05, 0x6b,
-	0xf9, 0xf4, 0xdc, 0xf1, 0xf9, 0xe2, 0xac, 0x7a, 0xbc, 0x48, 0x8d, 0xc6,
-	0x95, 0x8b, 0xcd, 0x9c, 0xb8, 0x2f, 0xc9, 0xa6, 0x13, 0xd2, 0x6b, 0xf0,
-	0xf3, 0x1f, 0x75, 0x7e, 0xdc, 0xec, 0x09, 0xd2, 0x1f, 0x63, 0x6f, 0x9d,
-	0x7e, 0x3c, 0x01, 0xba, 0xad, 0x63, 0xca, 0xa5, 0x8a, 0xe7, 0xb3, 0x5a,
-	0xd1, 0xf4, 0xf2, 0x2b, 0xd0, 0x1c, 0x63, 0x0e, 0xde, 0x33, 0x5b, 0xf2,
-	0xfa, 0xce, 0xe0, 0xde, 0x60, 0x8f, 0x63, 0xbf, 0x46, 0x37, 0xe7, 0xe2,
-	0xff, 0xe9, 0xa0, 0xec, 0xaf, 0x97, 0xb9, 0xc6, 0xb6, 0xa6, 0x45, 0x2f,
-	0xae, 0x1b, 0x97, 0x17, 0x70, 0x7e, 0x65, 0x93, 0xeb, 0x0f, 0x4a, 0x39,
-	0x4e, 0xdb, 0x96, 0xf8, 0x7d, 0x42, 0x4a, 0x98, 0xa7, 0x1c, 0x6f, 0xf8,
-	0xc3, 0x3c, 0x9c, 0x2d, 0x9b, 0x0f, 0xe6, 0x5d, 0x2c, 0x1d, 0xc7, 0x3b,
-	0xea, 0xe2, 0xd0, 0x99, 0x16, 0xf8, 0x7e, 0x11, 0x65, 0xfa, 0x46, 0x56,
-	0xf0, 0x8c, 0xf8, 0x75, 0xd5, 0x01, 0xad, 0xab, 0x4f, 0x3f, 0xe8, 0xb7,
-	0x54, 0xb2, 0xb2, 0xa9, 0x40, 0x42, 0x19, 0xaf, 0xfe, 0x7c, 0x80, 0x98,
-	0x7b, 0xdc, 0xe6, 0x2f, 0x24, 0x7f, 0x35, 0xb5, 0x4f, 0xc1, 0xff, 0x76,
-	0x44, 0x9e, 0x32, 0x99, 0xc7, 0x9e, 0x54, 0xb3, 0xc5, 0x9c, 0x9f, 0xe3,
-	0x9b, 0x50, 0xc7, 0xcb, 0x37, 0x07, 0xbc, 0x9c, 0x77, 0x8e, 0x7d, 0x30,
-	0xcf, 0xfd, 0x20, 0x9d, 0x30, 0xdf, 0xbd, 0xbd, 0xf9, 0x3f, 0x52, 0xe5,
-	0x3c, 0xf0, 0xce, 0x6e, 0xd1, 0xfc, 0x98, 0xab, 0xfe, 0xdb, 0xdd, 0xd3,
-	0xfc, 0xdc, 0xf0, 0x31, 0xfc, 0x6e, 0x80, 0xb6, 0x2d, 0x71, 0xe3, 0x92,
-	0x97, 0x3b, 0xaa, 0x6d, 0x68, 0x60, 0x05, 0xea, 0xc8, 0xab, 0xe0, 0x93,
-	0x66, 0x5b, 0xfe, 0xfd, 0x07, 0x69, 0x3f, 0x51, 0x42, 0x6c, 0x67, 0x00,
-	0x00, 0x00 };
+	0xec, 0x5c, 0x7d, 0x6c, 0x1c, 0xc7, 0x75, 0x7f, 0x3b, 0xbb, 0xa4, 0x8e,
+	0xd4, 0x91, 0x5c, 0x1e, 0x4f, 0xcc, 0x51, 0xa6, 0xed, 0x5b, 0x71, 0x25,
+	0x9e, 0x4d, 0xc6, 0x59, 0xd1, 0x07, 0x9b, 0x28, 0x0e, 0xc9, 0x66, 0xef,
+	0x24, 0xb1, 0x86, 0x5b, 0x53, 0x35, 0x1d, 0x1b, 0x6d, 0xea, 0xb2, 0x47,
+	0xb5, 0x29, 0x8c, 0x06, 0x90, 0xbf, 0x00, 0x17, 0xa8, 0xe4, 0xcb, 0x91,
+	0x8a, 0x55, 0xf7, 0xc0, 0xbd, 0xc8, 0x8c, 0x18, 0x20, 0x6e, 0x7d, 0x25,
+	0x29, 0x4a, 0x08, 0x0e, 0x3a, 0xa6, 0x71, 0x1a, 0xfd, 0x61, 0xd7, 0x04,
+	0x2b, 0x1b, 0x6e, 0x91, 0xd6, 0x72, 0xe3, 0xb6, 0x46, 0x50, 0x04, 0x84,
+	0xec, 0x34, 0x6e, 0xd0, 0x0f, 0xa1, 0x2e, 0x6c, 0x03, 0x96, 0xbd, 0xfd,
+	0xbd, 0xd9, 0x5d, 0xf2, 0x48, 0x5b, 0x76, 0xd0, 0x3f, 0xfa, 0x4f, 0x77,
+	0x80, 0xc3, 0xce, 0xcc, 0xbe, 0xf7, 0xe6, 0xcd, 0x9b, 0xf7, 0x39, 0x4b,
+	0xe9, 0xb7, 0xe3, 0xd4, 0x4e, 0x41, 0xeb, 0xc0, 0x2f, 0x7d, 0xf4, 0xb1,
+	0x87, 0x6e, 0xb9, 0xfd, 0x96, 0x5b, 0xd1, 0xdd, 0xaf, 0x2a, 0x3b, 0xd4,
+	0x70, 0x3e, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45,
+	0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d,
+	0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a,
+	0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51,
+	0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b,
+	0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0xed, 0xff, 0x7b, 0x53, 0x89,
+	0x74, 0x7e, 0x76, 0x04, 0x3f, 0x8a, 0x89, 0x5c, 0xfa, 0x01, 0xc7, 0xa4,
+	0x98, 0x9a, 0xeb, 0x3f, 0x3e, 0x65, 0x12, 0xd9, 0xf5, 0xa1, 0x74, 0x9e,
+	0x3e, 0xf0, 0x4a, 0x49, 0x8d, 0x78, 0xfe, 0xfa, 0xdc, 0xd5, 0x67, 0x9e,
+	0xbf, 0xdd, 0xb8, 0x52, 0x53, 0x29, 0xa6, 0xe7, 0x66, 0xf6, 0xeb, 0xfb,
+	0x28, 0xd6, 0x0f, 0x9c, 0xa7, 0x07, 0xff, 0xb1, 0x93, 0x3a, 0x43, 0x5a,
+	0x44, 0x0b, 0x15, 0xc3, 0x3a, 0x88, 0xe7, 0x72, 0x7d, 0xc8, 0x5a, 0x23,
+	0x8d, 0x56, 0x75, 0x7f, 0xc5, 0x72, 0x45, 0x61, 0x3a, 0x54, 0xae, 0xc7,
+	0x68, 0x5d, 0xfe, 0x3b, 0x0f, 0xac, 0x69, 0x72, 0xff, 0x82, 0xe2, 0x34,
+	0x3c, 0xef, 0x8c, 0xe5, 0x79, 0x2f, 0xe1, 0xf7, 0x33, 0x0b, 0x63, 0xf7,
+	0x43, 0xcf, 0xd6, 0x54, 0x12, 0xe6, 0x1f, 0x2b, 0xce, 0x62, 0x2b, 0x95,
+	0xe7, 0x89, 0xa6, 0xdd, 0x18, 0x9d, 0x74, 0x4b, 0x4a, 0xa1, 0x51, 0x51,
+	0x0e, 0x9c, 0x9d, 0x55, 0x0e, 0x9e, 0x3d, 0xa9, 0x1c, 0x3a, 0x5b, 0x55,
+	0x9c, 0xb3, 0x54, 0x12, 0xfb, 0xe3, 0x64, 0xeb, 0xe7, 0x94, 0x7c, 0xa3,
+	0x57, 0x71, 0xe6, 0xaf, 0x7a, 0x8e, 0x65, 0xe8, 0xbf, 0x4e, 0x9a, 0xcd,
+	0xeb, 0x39, 0x15, 0x0f, 0x63, 0x8d, 0xec, 0xa4, 0xe7, 0x89, 0x9c, 0xf7,
+	0xb8, 0x93, 0x35, 0x75, 0xa1, 0xc4, 0xa8, 0xdc, 0x68, 0x07, 0x5d, 0x4d,
+	0xc9, 0xbb, 0xde, 0x0b, 0x8e, 0xb5, 0x0c, 0x3a, 0x75, 0xe0, 0x93, 0x2e,
+	0x72, 0xcc, 0x4f, 0xc8, 0x63, 0x49, 0xc9, 0x0f, 0x86, 0xfc, 0x50, 0x9a,
+	0xf9, 0x2d, 0x2e, 0x09, 0xf0, 0xb5, 0x93, 0x8a, 0x35, 0x9d, 0x26, 0x97,
+	0xb6, 0xc3, 0xaf, 0x7b, 0xcf, 0x0f, 0xea, 0xb4, 0xd2, 0x30, 0x4a, 0x25,
+	0xec, 0x7d, 0xc6, 0x4d, 0x93, 0xc8, 0x91, 0xed, 0x64, 0xfb, 0xe9, 0x85,
+	0x46, 0x8a, 0xfe, 0xbc, 0x61, 0xa6, 0xca, 0xb4, 0x83, 0x8a, 0xc9, 0x24,
+	0x7d, 0x17, 0x38, 0xd3, 0x58, 0x5b, 0x98, 0xa6, 0x5e, 0x06, 0x6c, 0xb9,
+	0xf1, 0x23, 0xfe, 0xb7, 0x31, 0xfa, 0x54, 0x56, 0xe2, 0x94, 0xc0, 0x67,
+	0x00, 0xcb, 0x7c, 0x4b, 0x58, 0xc9, 0xbb, 0x0f, 0x4b, 0xa5, 0xa9, 0x2c,
+	0xe6, 0x1a, 0x4e, 0x20, 0xfb, 0x56, 0xec, 0x8f, 0x9f, 0x37, 0x28, 0xf9,
+	0xf9, 0x1b, 0x20, 0x03, 0x4a, 0x0a, 0xda, 0x9b, 0x2a, 0x62, 0x66, 0xba,
+	0x11, 0xc7, 0x98, 0x79, 0xf1, 0xbc, 0x43, 0x16, 0xe9, 0x65, 0xab, 0x0b,
+	0xb2, 0x4a, 0x53, 0xd9, 0xea, 0x04, 0x4e, 0x0b, 0x75, 0x9b, 0xbc, 0x07,
+	0xa6, 0xdb, 0x86, 0x79, 0xaf, 0x43, 0xcd, 0x79, 0xde, 0x54, 0x96, 0x3a,
+	0xfd, 0xb9, 0x21, 0xd0, 0xd0, 0x68, 0x72, 0x5c, 0x01, 0xdc, 0xdb, 0xcc,
+	0x5f, 0x2c, 0x91, 0xe3, 0x3e, 0x3f, 0xb3, 0xe4, 0xcc, 0xa6, 0x83, 0x75,
+	0xe3, 0x54, 0x76, 0xaf, 0x0f, 0xfa, 0x90, 0xad, 0x8b, 0x3d, 0x5b, 0x7d,
+	0x18, 0x2b, 0x37, 0x82, 0x8e, 0x55, 0x26, 0x5e, 0x63, 0x17, 0xad, 0x25,
+	0x49, 0x5c, 0xb6, 0x7a, 0x02, 0xb8, 0x4e, 0xf0, 0x1a, 0x9e, 0x71, 0x3b,
+	0xcd, 0xcc, 0xb7, 0xd2, 0x89, 0x79, 0x96, 0x6d, 0x05, 0x67, 0x21, 0x68,
+	0xcf, 0x6d, 0x25, 0xc5, 0x6e, 0x9c, 0x44, 0x5f, 0xa3, 0x29, 0xd3, 0x7b,
+	0x61, 0xc6, 0x9a, 0x55, 0xf2, 0x67, 0x97, 0x95, 0x02, 0xce, 0xfc, 0xc0,
+	0xd9, 0x0b, 0xca, 0xc1, 0xc6, 0xcb, 0x1d, 0xd4, 0x6e, 0x40, 0xbb, 0x34,
+	0x3a, 0xe1, 0x2a, 0xc4, 0xfc, 0x2e, 0x40, 0x5e, 0xb6, 0x0e, 0xc9, 0x9b,
+	0x9d, 0xca, 0x41, 0xd0, 0x6a, 0x31, 0xbf, 0x1e, 0xa7, 0x4e, 0x95, 0x76,
+	0x98, 0x21, 0x6c, 0x8c, 0xbe, 0x0e, 0xde, 0xd6, 0xac, 0x24, 0xe0, 0xa8,
+	0xcb, 0xc7, 0xe9, 0x0e, 0xf8, 0x61, 0xdd, 0x61, 0xbd, 0x11, 0x76, 0x61,
+	0xee, 0x8f, 0x7a, 0xca, 0xc3, 0x3b, 0x19, 0x06, 0xf6, 0x60, 0x3f, 0x30,
+	0x65, 0x3a, 0xdd, 0x1a, 0x95, 0x74, 0x41, 0x86, 0x9e, 0xa7, 0x1b, 0x69,
+	0xc6, 0x22, 0xca, 0x43, 0x9f, 0x85, 0xa9, 0x41, 0x46, 0x26, 0x64, 0xb4,
+	0xb7, 0xa4, 0x8a, 0x7b, 0x41, 0xa2, 0xa4, 0x68, 0x81, 0x3c, 0x17, 0xe8,
+	0x0e, 0x89, 0x2f, 0x72, 0x16, 0x74, 0xb0, 0x9d, 0xfb, 0x58, 0x37, 0x26,
+	0xd7, 0x55, 0x73, 0x66, 0x6a, 0x91, 0x48, 0x11, 0xb9, 0x21, 0xd0, 0x63,
+	0xdd, 0x64, 0x38, 0x17, 0x3c, 0x32, 0xef, 0xdc, 0x37, 0x81, 0x13, 0x23,
+	0xc7, 0xea, 0x68, 0xe2, 0x13, 0xfc, 0x24, 0x59, 0xe6, 0x2c, 0x43, 0xb9,
+	0x4f, 0x65, 0x73, 0x9f, 0xef, 0x7b, 0x83, 0x23, 0x1a, 0xbd, 0x24, 0xf7,
+	0xcb, 0x76, 0xc4, 0x70, 0x72, 0x8f, 0xc4, 0xf2, 0x99, 0x76, 0x49, 0x29,
+	0x5a, 0xfa, 0x06, 0x2d, 0xe8, 0x85, 0x50, 0x73, 0x71, 0xca, 0x4b, 0xfe,
+	0x46, 0xb1, 0x16, 0xdb, 0x17, 0xec, 0xc4, 0xe4, 0xbd, 0xf0, 0x5c, 0x0e,
+	0xb6, 0x6a, 0x48, 0xfd, 0x29, 0x56, 0xd9, 0xfe, 0x99, 0xb7, 0x55, 0x43,
+	0x50, 0x48, 0x4f, 0xf4, 0xaa, 0xd4, 0x45, 0xe3, 0xd6, 0x55, 0x4f, 0xec,
+	0xc3, 0xfb, 0xe1, 0x14, 0x78, 0x33, 0xd2, 0xb0, 0xb6, 0x84, 0x4a, 0xb0,
+	0x73, 0x6b, 0x28, 0xa5, 0x93, 0x89, 0xbd, 0x25, 0xc8, 0x1e, 0x5f, 0x85,
+	0xe0, 0xaf, 0xc5, 0xa7, 0x4f, 0x17, 0x6c, 0xda, 0x0e, 0x78, 0x74, 0xac,
+	0x5b, 0xa5, 0xcc, 0x74, 0xec, 0x5f, 0x9d, 0x65, 0xf9, 0xb6, 0x43, 0xff,
+	0x15, 0x2a, 0x5a, 0x4c, 0x3b, 0xa4, 0x21, 0x68, 0xf0, 0xb6, 0x66, 0x1a,
+	0xe1, 0xd9, 0xb2, 0xfe, 0x6a, 0x34, 0x32, 0xc2, 0xb0, 0x0c, 0xc7, 0xf0,
+	0xc6, 0x68, 0x5a, 0xbc, 0xef, 0xed, 0xdf, 0xb2, 0xa6, 0x49, 0x62, 0x16,
+	0x3c, 0xfb, 0x67, 0x01, 0x19, 0x7e, 0x1a, 0x2c, 0x9f, 0xc3, 0x76, 0x79,
+	0x33, 0x6c, 0x33, 0x1c, 0x74, 0xa8, 0x97, 0x79, 0xa8, 0xc7, 0x7d, 0x7b,
+	0x0c, 0x79, 0x0a, 0xcf, 0x52, 0x09, 0x68, 0x7c, 0xd2, 0x3e, 0x18, 0x1e,
+	0x7e, 0xc2, 0x85, 0x9f, 0x70, 0xe1, 0x1f, 0x5c, 0xf8, 0x11, 0x97, 0xfd,
+	0x4a, 0x9a, 0x9e, 0x1f, 0x84, 0xdf, 0xdb, 0xf4, 0x43, 0x68, 0x63, 0xe8,
+	0x0b, 0x52, 0xe1, 0x87, 0xa6, 0x6b, 0x02, 0xb6, 0x0e, 0x9b, 0x5b, 0xe2,
+	0x39, 0x1d, 0xcf, 0x02, 0x9e, 0x26, 0xfc, 0x2c, 0xeb, 0x61, 0xe8, 0x5f,
+	0xd9, 0x2f, 0xa5, 0xe0, 0x83, 0xd8, 0xef, 0xb0, 0x7f, 0x62, 0x58, 0xcf,
+	0x2b, 0x58, 0x8c, 0xeb, 0xe1, 0x1c, 0xd9, 0xee, 0xe2, 0x24, 0x12, 0x25,
+	0xe5, 0xf0, 0x20, 0x6c, 0xf2, 0xe6, 0x16, 0xf0, 0xca, 0xb6, 0x79, 0x1d,
+	0xbb, 0x16, 0xb4, 0xf7, 0x3b, 0xfc, 0x7f, 0xb7, 0xb7, 0x03, 0x30, 0xd2,
+	0xc6, 0x3b, 0xfd, 0x71, 0x77, 0xe0, 0x7f, 0xf8, 0xbd, 0x91, 0xb6, 0x69,
+	0x5f, 0x30, 0xe6, 0xfe, 0x06, 0xbf, 0x96, 0xb8, 0x2d, 0x46, 0x7b, 0x96,
+	0x7d, 0xbf, 0xb9, 0x67, 0x01, 0x9a, 0xb1, 0xec, 0xf3, 0xb8, 0xe7, 0x7c,
+	0xe8, 0x3f, 0x3b, 0x40, 0x0f, 0xfc, 0xb9, 0x9b, 0x71, 0x84, 0xe8, 0xbf,
+	0x14, 0x98, 0x16, 0xe6, 0xb6, 0xcb, 0xc2, 0xf3, 0x66, 0x2c, 0xb6, 0x4f,
+	0xbd, 0xd9, 0x3e, 0xf7, 0xc3, 0x3e, 0xad, 0x56, 0x32, 0xac, 0xbf, 0x82,
+	0x7d, 0x3e, 0x61, 0x29, 0x90, 0x0d, 0xd1, 0xc5, 0x4a, 0x1c, 0xbe, 0x41,
+	0x4b, 0xbd, 0x41, 0x7b, 0xd3, 0xd3, 0xd0, 0xcb, 0x33, 0x3c, 0x87, 0x23,
+	0x3a, 0x21, 0xfd, 0xb5, 0xef, 0x0f, 0xd6, 0xd5, 0x6f, 0x80, 0x2f, 0xcf,
+	0x9b, 0x06, 0xcd, 0xe2, 0xb0, 0x1a, 0xd8, 0x62, 0x38, 0x6f, 0x23, 0x26,
+	0x3a, 0x37, 0xa9, 0x54, 0xca, 0xb4, 0x90, 0x91, 0x59, 0x00, 0xed, 0x29,
+	0xcb, 0xb7, 0x7b, 0xb6, 0x8d, 0x45, 0xd0, 0x9f, 0x71, 0x07, 0xe1, 0x17,
+	0xd8, 0x6e, 0xc0, 0x17, 0xe8, 0x2f, 0x82, 0xfe, 0x4c, 0xa3, 0x85, 0xbe,
+	0xa6, 0x85, 0xb1, 0x36, 0xdc, 0x0f, 0x44, 0x6d, 0x86, 0xeb, 0x1e, 0xa5,
+	0x3b, 0xdc, 0x84, 0xe2, 0x3c, 0xc5, 0x7e, 0xb9, 0x9c, 0x81, 0x5d, 0x29,
+	0x65, 0x8b, 0xd7, 0x56, 0x69, 0x71, 0x03, 0x86, 0xec, 0xb2, 0x6f, 0xb3,
+	0xb6, 0x33, 0x58, 0x4a, 0xa9, 0xd2, 0xf7, 0x10, 0x1d, 0xac, 0x68, 0x80,
+	0xe1, 0x31, 0xcf, 0xfb, 0x73, 0x63, 0x95, 0x5e, 0xf8, 0x52, 0x1e, 0x5f,
+	0xf5, 0xa6, 0x2c, 0x7f, 0xee, 0x97, 0x2b, 0x0f, 0xf0, 0x19, 0x61, 0x2f,
+	0x94, 0x2e, 0x5b, 0x3f, 0xf7, 0xa0, 0xbf, 0x5b, 0x70, 0x3e, 0x9e, 0x8e,
+	0x31, 0xe6, 0xeb, 0x2c, 0x29, 0x87, 0x4c, 0xd1, 0xdb, 0x1a, 0xf8, 0xbc,
+	0x43, 0x98, 0x3c, 0x50, 0x29, 0xf7, 0xb4, 0xd2, 0x55, 0x95, 0x63, 0xeb,
+	0x65, 0x38, 0x01, 0xa7, 0xb2, 0x0f, 0xf2, 0x28, 0x77, 0x37, 0xcd, 0xc5,
+	0x0a, 0x15, 0x8f, 0xd6, 0x2c, 0x1f, 0x07, 0xe3, 0x78, 0xbe, 0x22, 0x7a,
+	0x63, 0xb4, 0x31, 0xd6, 0x19, 0x67, 0x89, 0xf6, 0x65, 0x16, 0x49, 0xe2,
+	0xf6, 0xc4, 0x36, 0x71, 0x93, 0x85, 0x4a, 0xb9, 0xbb, 0x69, 0x9c, 0xca,
+	0x83, 0x96, 0xd8, 0xbf, 0x81, 0xdb, 0xbf, 0x89, 0xbb, 0x8b, 0xd2, 0xdd,
+	0x8c, 0x2f, 0x7a, 0xdb, 0x36, 0x69, 0xa7, 0x03, 0x7e, 0x7a, 0xda, 0x36,
+	0x69, 0x98, 0x4c, 0xb3, 0x69, 0x9c, 0x61, 0x9a, 0x7b, 0x36, 0x69, 0x0e,
+	0x6f, 0xe5, 0xe7, 0x28, 0xc1, 0x07, 0xc5, 0x5a, 0x73, 0xb4, 0xff, 0x62,
+	0x65, 0x60, 0xfc, 0x0e, 0x42, 0x8c, 0x1c, 0xde, 0x11, 0xf8, 0x70, 0x6d,
+	0xbf, 0x03, 0x59, 0x69, 0xc4, 0x3e, 0x51, 0xa1, 0x32, 0xce, 0xf9, 0x81,
+	0x3a, 0xed, 0x5f, 0xab, 0x53, 0xa0, 0x4b, 0xac, 0x13, 0x6f, 0xc1, 0xc6,
+	0xa8, 0xb4, 0x3b, 0x17, 0x9f, 0xd4, 0x72, 0x3a, 0x6c, 0x8d, 0xc6, 0xcb,
+	0xf0, 0xe1, 0x6a, 0x6e, 0xef, 0xeb, 0x79, 0xf5, 0x71, 0x4f, 0x35, 0xd9,
+	0x1f, 0xc6, 0x47, 0x9d, 0x2c, 0xe6, 0xeb, 0x6c, 0x5b, 0xf0, 0x2b, 0x0d,
+	0xa6, 0xfd, 0x4c, 0x17, 0x75, 0x22, 0x8e, 0xd6, 0xcf, 0xec, 0xf2, 0x6d,
+	0x87, 0x34, 0x0d, 0xbe, 0x79, 0x26, 0xcb, 0x71, 0xbf, 0x35, 0x06, 0xf8,
+	0x49, 0x35, 0x37, 0xd6, 0x77, 0xa4, 0x7e, 0x67, 0x5f, 0xb1, 0x5e, 0xea,
+	0x2b, 0x56, 0x74, 0xb6, 0x13, 0xe1, 0x64, 0xd1, 0x97, 0xb9, 0x54, 0x0a,
+	0x36, 0xc1, 0x6b, 0x27, 0xb1, 0xe6, 0x0f, 0x60, 0x7f, 0x6c, 0xdf, 0x44,
+	0xe3, 0x2e, 0xd6, 0x18, 0xf9, 0x00, 0xe7, 0x0e, 0xde, 0xe0, 0xd3, 0x6c,
+	0xec, 0x5a, 0x8c, 0xfc, 0x6b, 0x60, 0x9f, 0xdc, 0x7f, 0xc7, 0xf3, 0xe3,
+	0xc3, 0xdd, 0x5d, 0xfe, 0xdc, 0x8f, 0x03, 0x9b, 0x0e, 0x69, 0x31, 0x9d,
+	0x8c, 0x32, 0x8e, 0x1c, 0x66, 0xbc, 0xa1, 0x29, 0xec, 0x9f, 0xf3, 0x2e,
+	0xe7, 0x1e, 0x9c, 0x77, 0x4c, 0x07, 0x7e, 0x8e, 0x6c, 0xe4, 0x4f, 0x9e,
+	0x40, 0x2e, 0x52, 0x84, 0xdd, 0x68, 0xb9, 0x2b, 0x34, 0x23, 0x7d, 0x24,
+	0xc5, 0x5a, 0x72, 0x8f, 0x01, 0xe6, 0xdf, 0x60, 0x73, 0xdd, 0x5d, 0x81,
+	0x1e, 0x06, 0x3e, 0x5e, 0xfa, 0x5d, 0xc0, 0xbe, 0xb5, 0x0d, 0xf6, 0xcd,
+	0x66, 0x58, 0xbc, 0x5f, 0xdf, 0xf6, 0xfe, 0x9f, 0xd9, 0x7e, 0xf1, 0x6e,
+	0x15, 0xfe, 0xb4, 0x35, 0xb0, 0xfd, 0x8b, 0x54, 0x84, 0x6f, 0xd5, 0x4c,
+	0xce, 0x2d, 0x0f, 0x02, 0x17, 0xe3, 0x3a, 0x78, 0x84, 0xbf, 0x40, 0x8c,
+	0x85, 0xbc, 0x11, 0x13, 0x92, 0x37, 0x72, 0x3e, 0x05, 0xd8, 0x34, 0x60,
+	0xd9, 0xff, 0x32, 0xec, 0x85, 0x38, 0xcb, 0xbc, 0x58, 0x67, 0x1c, 0xf6,
+	0x55, 0xe4, 0x39, 0xd9, 0x36, 0x68, 0x94, 0xf7, 0x82, 0x6a, 0x86, 0xb0,
+	0x21, 0xdd, 0xed, 0xb0, 0x9c, 0xdf, 0x30, 0xed, 0xae, 0x20, 0x6f, 0x18,
+	0x23, 0xbb, 0x61, 0xe3, 0x57, 0xa2, 0xa9, 0xa7, 0x90, 0xbb, 0x99, 0x2d,
+	0x2c, 0x0b, 0x9e, 0xd7, 0x7d, 0x19, 0x85, 0x78, 0xa5, 0x9e, 0xad, 0xe3,
+	0xdf, 0x4a, 0x6c, 0xfa, 0x4a, 0xb6, 0x34, 0xb2, 0x11, 0x2b, 0x20, 0xe3,
+	0xf4, 0xa4, 0xc8, 0x25, 0x29, 0x5f, 0xf7, 0xe5, 0x8b, 0xf8, 0x0c, 0xff,
+	0x28, 0xfd, 0x07, 0xce, 0x3d, 0xf4, 0x83, 0xe1, 0x99, 0xb3, 0x9e, 0xd9,
+	0x38, 0x9b, 0x34, 0x74, 0x69, 0x0c, 0xb8, 0x74, 0x14, 0x34, 0x38, 0x6e,
+	0x5b, 0x22, 0x97, 0xa0, 0xa2, 0xce, 0xf9, 0x85, 0xcc, 0x0d, 0x6d, 0xf6,
+	0x03, 0x22, 0xd7, 0x86, 0x39, 0xee, 0xff, 0x41, 0x97, 0x7f, 0xd6, 0x1d,
+	0x3c, 0x1e, 0x17, 0xb9, 0xae, 0x6d, 0xf3, 0x7f, 0xd7, 0xe1, 0xf3, 0x26,
+	0xc7, 0x98, 0xff, 0xc9, 0xb6, 0xf1, 0xa3, 0x89, 0xad, 0xe3, 0xaf, 0xf6,
+	0x85, 0xfa, 0x20, 0x72, 0x8f, 0x05, 0xfc, 0xb2, 0x9e, 0x6e, 0xe7, 0xf5,
+	0x17, 0xd1, 0x97, 0x3f, 0x01, 0x4d, 0xa9, 0xe3, 0xbf, 0x80, 0xbe, 0x6c,
+	0xc0, 0x5e, 0x43, 0x5f, 0x9a, 0x79, 0xd8, 0xa8, 0x3b, 0xaa, 0x02, 0x39,
+	0xac, 0x93, 0xdd, 0x9b, 0x2e, 0xc3, 0xc6, 0x0b, 0x0d, 0xc8, 0x6e, 0x23,
+	0xae, 0x6e, 0xc0, 0x94, 0x36, 0x61, 0xfc, 0xb8, 0x53, 0x68, 0x78, 0xc8,
+	0xfb, 0x9a, 0x63, 0x70, 0x06, 0xfd, 0x12, 0xf6, 0xba, 0x42, 0x53, 0xee,
+	0x9a, 0x2d, 0xcc, 0x93, 0x32, 0x6f, 0x15, 0xe6, 0x93, 0x4a, 0x61, 0x91,
+	0x73, 0xda, 0x18, 0xfa, 0xb2, 0x3e, 0x41, 0x8c, 0x3b, 0xa5, 0xd8, 0x67,
+	0xe7, 0x90, 0xcf, 0x2e, 0xe1, 0x77, 0x0e, 0xbf, 0x3a, 0x7e, 0x61, 0xdd,
+	0xf0, 0x2d, 0xd4, 0x1d, 0xd2, 0xdf, 0x23, 0x36, 0xf9, 0xeb, 0xff, 0x74,
+	0x09, 0xf9, 0xf4, 0x5c, 0x92, 0x9e, 0x30, 0x45, 0x8f, 0xf0, 0x7d, 0x9c,
+	0x8d, 0x5c, 0x5c, 0x7f, 0x8b, 0x7e, 0x25, 0xc8, 0xe9, 0x88, 0xde, 0xa8,
+	0xe2, 0x2c, 0x87, 0x0f, 0x05, 0xfe, 0xe9, 0xe4, 0x57, 0x1c, 0xe9, 0xcb,
+	0x83, 0x9c, 0x0d, 0x7e, 0xc7, 0x96, 0x50, 0xaf, 0x40, 0x3e, 0x0a, 0xfd,
+	0x0c, 0x7a, 0xfc, 0x46, 0xb5, 0x1d, 0xfc, 0x98, 0x54, 0x9c, 0x30, 0x46,
+	0x49, 0x19, 0xd0, 0x77, 0x28, 0xed, 0xc8, 0xdb, 0xe0, 0x77, 0xe4, 0x98,
+	0x65, 0x46, 0xc7, 0x17, 0x2a, 0x02, 0xb0, 0x90, 0x79, 0x16, 0x7d, 0xe8,
+	0xdf, 0xe5, 0x2a, 0xe3, 0x09, 0x7a, 0xb3, 0xaa, 0xd2, 0xbf, 0x20, 0x0f,
+	0xc4, 0xbb, 0xe3, 0xb0, 0xc1, 0x5e, 0xc4, 0xab, 0x7e, 0x95, 0xf6, 0x72,
+	0xcc, 0xd8, 0xa3, 0xe1, 0x59, 0xc0, 0xef, 0x20, 0xf2, 0xc2, 0x6b, 0xe0,
+	0x5c, 0x03, 0x9e, 0x79, 0x8b, 0x01, 0x87, 0xe1, 0x35, 0xf0, 0xd6, 0x09,
+	0x1d, 0x34, 0xf4, 0x49, 0xfa, 0x8c, 0x2e, 0x73, 0x27, 0x85, 0xe7, 0x7d,
+	0x3f, 0xf9, 0xd1, 0x79, 0x96, 0xb3, 0x0a, 0x1d, 0xe2, 0x31, 0xbf, 0x63,
+	0x7f, 0xce, 0xf4, 0x8c, 0x51, 0x1b, 0x9b, 0xb9, 0x5c, 0xf5, 0xfb, 0xe1,
+	0x1c, 0x29, 0x61, 0x4c, 0x65, 0x3f, 0x5d, 0x80, 0xad, 0xf2, 0x78, 0x9c,
+	0xe4, 0x19, 0x6c, 0x39, 0x4f, 0xa9, 0x47, 0xc7, 0x66, 0x4c, 0x3e, 0x57,
+	0x9d, 0xa6, 0x2b, 0xe1, 0xb9, 0xf2, 0x19, 0xa1, 0x0e, 0xad, 0x3e, 0x89,
+	0x73, 0x15, 0x41, 0xcd, 0x02, 0x3f, 0x30, 0xc7, 0xe7, 0x8b, 0x3a, 0xb2,
+	0x8a, 0x3c, 0xac, 0x4a, 0x09, 0xbf, 0xe6, 0x3a, 0x85, 0x3a, 0x05, 0xe7,
+	0x57, 0x99, 0x03, 0x8d, 0x24, 0x9e, 0x4b, 0x78, 0xa6, 0xf0, 0x3c, 0x87,
+	0x67, 0x3f, 0x9e, 0x75, 0xb6, 0x8f, 0x20, 0xef, 0xf9, 0x08, 0x3f, 0xb0,
+	0x93, 0x02, 0xdb, 0x34, 0xfd, 0x65, 0x23, 0x47, 0x3f, 0x68, 0x8c, 0xd2,
+	0x5f, 0x34, 0xb2, 0xf4, 0xfd, 0x86, 0x45, 0xcf, 0x36, 0x86, 0xe9, 0x7b,
+	0x8d, 0x0c, 0xd7, 0x90, 0xc8, 0xe1, 0xd2, 0xf0, 0xcd, 0x17, 0xe8, 0x2b,
+	0x6e, 0x03, 0x3e, 0x47, 0xfa, 0xcb, 0xe3, 0x76, 0xfd, 0x3a, 0x2a, 0x3e,
+	0xa5, 0x23, 0xcf, 0x54, 0xb9, 0x8e, 0xa3, 0x47, 0xad, 0xbb, 0x13, 0x7c,
+	0xf6, 0xc2, 0xe4, 0xba, 0xe6, 0x04, 0xc3, 0xa1, 0x1e, 0x56, 0x90, 0xbf,
+	0xb4, 0xd0, 0x64, 0xd2, 0x58, 0x71, 0xd4, 0x74, 0xe0, 0x8f, 0x26, 0x00,
+	0x87, 0x35, 0xdd, 0x38, 0xad, 0x9d, 0x86, 0x2d, 0x58, 0xa8, 0xa5, 0x93,
+	0x31, 0xf8, 0x3e, 0x99, 0x9f, 0x48, 0xdf, 0xe2, 0xfb, 0xd2, 0xb0, 0xc6,
+	0xe4, 0x39, 0x3b, 0x98, 0xe3, 0xf8, 0xa8, 0x03, 0xb6, 0x11, 0xc4, 0x90,
+	0xed, 0x34, 0xd9, 0x37, 0x4e, 0x04, 0xfe, 0x71, 0x85, 0x1e, 0x76, 0x07,
+	0xec, 0xb7, 0x11, 0x7b, 0x94, 0x96, 0x30, 0x2f, 0xda, 0x0d, 0xde, 0x3c,
+	0xef, 0x30, 0xea, 0xf3, 0x74, 0x42, 0xa3, 0xbf, 0x9f, 0x35, 0xf4, 0xc3,
+	0x02, 0x01, 0xae, 0xdd, 0xf3, 0xc6, 0x4d, 0xa3, 0x64, 0x8b, 0x0e, 0xfa,
+	0xa7, 0x53, 0x1c, 0x93, 0xd7, 0x8f, 0xbd, 0x08, 0x3d, 0xa8, 0x2d, 0xb5,
+	0x52, 0xad, 0xa6, 0xd1, 0xe5, 0x91, 0x01, 0xb9, 0x6e, 0xad, 0x9e, 0x40,
+	0x9e, 0xd7, 0x46, 0x8b, 0xbd, 0x52, 0xd9, 0xe1, 0xb7, 0x33, 0xd2, 0x6f,
+	0x3b, 0x26, 0x9e, 0xf5, 0xb4, 0xbe, 0x95, 0x97, 0x67, 0xa9, 0xe8, 0x76,
+	0xa2, 0x42, 0xd9, 0x0d, 0x99, 0x70, 0x7f, 0x40, 0x77, 0x04, 0x62, 0xa0,
+	0x36, 0xa0, 0x1f, 0x12, 0xff, 0xed, 0x7d, 0x51, 0x63, 0x39, 0xbe, 0x8e,
+	0xd8, 0xc2, 0xb1, 0x52, 0x91, 0x7a, 0xb7, 0xb0, 0xf4, 0xa6, 0xce, 0xfe,
+	0xe5, 0x7b, 0xf5, 0xdd, 0xc1, 0x98, 0xfd, 0x3b, 0x8f, 0xdb, 0xe9, 0xfb,
+	0xb5, 0x9d, 0xb4, 0x58, 0xe3, 0xf7, 0xad, 0xb4, 0x50, 0x1b, 0xb8, 0xf2,
+	0x90, 0xe8, 0xa5, 0xd5, 0xeb, 0x6e, 0xd6, 0x3f, 0x2f, 0x20, 0x93, 0x89,
+	0x0f, 0xe9, 0xdd, 0x91, 0x2e, 0x7a, 0xf5, 0x5e, 0xa3, 0x7a, 0xbf, 0x80,
+	0x3e, 0x8e, 0xc4, 0xd9, 0xce, 0xd0, 0xe7, 0x79, 0xe3, 0x4a, 0x5a, 0xb0,
+	0x9e, 0xbd, 0x0c, 0xfd, 0x32, 0x4e, 0xfa, 0x3a, 0xc9, 0xb4, 0x99, 0x2e,
+	0xce, 0xc7, 0x7c, 0x05, 0x34, 0xf1, 0xae, 0x3e, 0x00, 0x5a, 0xaf, 0x48,
+	0x59, 0x1c, 0xb6, 0x8c, 0x2b, 0x08, 0x51, 0xde, 0x65, 0x73, 0x20, 0x23,
+	0xc4, 0x6e, 0xaa, 0xa5, 0x6e, 0xd6, 0xbf, 0x8b, 0x78, 0x80, 0x9a, 0xab,
+	0xb4, 0x4e, 0xeb, 0xc7, 0x2e, 0x9a, 0xac, 0x8b, 0x6c, 0xc3, 0x3f, 0x44,
+	0x4e, 0xaa, 0xd3, 0x53, 0x75, 0xf6, 0x5d, 0x4c, 0x8b, 0xeb, 0x82, 0x7d,
+	0xfa, 0xdd, 0xe0, 0xc1, 0x19, 0xc6, 0x3b, 0xcc, 0xab, 0x9f, 0xe5, 0x73,
+	0x6b, 0x61, 0xdc, 0x4c, 0x9a, 0x37, 0xb3, 0x45, 0x46, 0x03, 0xfa, 0x5e,
+	0xc1, 0xeb, 0xbd, 0x8b, 0x75, 0xdf, 0x01, 0xaf, 0x03, 0xc0, 0x45, 0x0c,
+	0x4d, 0x35, 0xaf, 0xf1, 0x9a, 0x5c, 0xe3, 0x54, 0x1d, 0x39, 0xe0, 0xc6,
+	0x1a, 0x98, 0xab, 0x0b, 0xec, 0xf3, 0x57, 0x65, 0xfe, 0xac, 0x22, 0xff,
+	0xb9, 0x3c, 0xf2, 0x4c, 0x90, 0x5f, 0x3c, 0x07, 0x59, 0xc7, 0xe8, 0xb5,
+	0x59, 0xae, 0x2f, 0x0f, 0x51, 0x39, 0xb1, 0x7e, 0x6c, 0xca, 0x44, 0x4d,
+	0x8f, 0x38, 0x50, 0xde, 0x37, 0xe0, 0xeb, 0x55, 0x3f, 0xe3, 0x3c, 0x27,
+	0xcf, 0xa4, 0x2c, 0x5a, 0xe9, 0x8b, 0x5a, 0x1a, 0xf8, 0x3c, 0x77, 0x29,
+	0x38, 0xcf, 0x6f, 0x83, 0x1f, 0xf4, 0xeb, 0x3d, 0x81, 0xff, 0x4b, 0x40,
+	0x57, 0x87, 0xf4, 0xc3, 0x14, 0x0b, 0xfc, 0x5f, 0x82, 0x5e, 0x3d, 0xad,
+	0x42, 0x87, 0x58, 0x7f, 0xfa, 0xbb, 0x37, 0xf5, 0x87, 0xdf, 0xad, 0x1f,
+	0x73, 0xc0, 0x63, 0x7e, 0xae, 0x95, 0x0a, 0xd5, 0x18, 0x4d, 0x65, 0x91,
+	0x73, 0x23, 0xfe, 0xe4, 0xa1, 0x4b, 0x85, 0x1a, 0xeb, 0x72, 0x29, 0xd0,
+	0xe5, 0x78, 0x40, 0xfb, 0x6f, 0xa0, 0xcb, 0x46, 0x7a, 0x55, 0x70, 0x7d,
+	0xd5, 0x27, 0x6b, 0x64, 0x15, 0xf6, 0x55, 0xac, 0x70, 0x2c, 0x62, 0xdb,
+	0xa2, 0xe3, 0xcc, 0x7f, 0xb1, 0x32, 0x2a, 0x8a, 0x8d, 0xac, 0x28, 0xba,
+	0xcc, 0xdf, 0x3e, 0xf0, 0xad, 0xc8, 0x3a, 0x78, 0xa1, 0xf1, 0xae, 0xb7,
+	0xb0, 0x6f, 0x07, 0xfa, 0xd0, 0xfd, 0x71, 0x3e, 0xdf, 0xeb, 0x99, 0xaf,
+	0xb4, 0x2d, 0x58, 0xde, 0x49, 0x5a, 0x1e, 0x7c, 0xa9, 0x8b, 0x73, 0xb4,
+	0xb3, 0x83, 0x4c, 0x1f, 0x7c, 0x24, 0x93, 0xb4, 0xe8, 0xf2, 0x1a, 0x2c,
+	0x17, 0xf8, 0xba, 0x39, 0x9d, 0x1e, 0x96, 0xe7, 0xc7, 0xba, 0xc5, 0xf7,
+	0x4d, 0x2a, 0xe5, 0x13, 0x03, 0xfa, 0x43, 0x64, 0x5c, 0x59, 0x53, 0x8d,
+	0xea, 0x24, 0xe2, 0xea, 0xc2, 0xbc, 0x4a, 0x7b, 0x64, 0x1d, 0xc6, 0x67,
+	0x64, 0x9c, 0x84, 0x35, 0x06, 0x7b, 0xff, 0x8d, 0xa6, 0xbd, 0x77, 0xd2,
+	0xc5, 0xd3, 0x9f, 0x85, 0xdd, 0xb3, 0x5c, 0xb5, 0xf4, 0x11, 0xe4, 0x19,
+	0x73, 0x04, 0xf9, 0x22, 0x7f, 0xb6, 0x53, 0xe1, 0xb9, 0xb0, 0xbc, 0x77,
+	0x49, 0xf9, 0x0b, 0x29, 0xff, 0x1b, 0xa8, 0xdc, 0xeb, 0xdb, 0x38, 0xbf,
+	0x13, 0xa0, 0xe1, 0xbf, 0xe3, 0xf1, 0x67, 0x90, 0x1f, 0xf1, 0xbb, 0x9a,
+	0x8f, 0x47, 0x3d, 0x4c, 0x07, 0xef, 0xfe, 0x10, 0x6b, 0xb2, 0x8c, 0xc3,
+	0xf9, 0x0e, 0xf2, 0x6d, 0x29, 0x94, 0x3b, 0x12, 0x8c, 0x7a, 0x92, 0x7e,
+	0xad, 0x9e, 0xa2, 0x89, 0x7a, 0x3f, 0x15, 0xea, 0x69, 0x9c, 0xc1, 0x13,
+	0xdd, 0xbc, 0xb7, 0xfc, 0x12, 0xf6, 0x23, 0x98, 0xd7, 0x1a, 0x1d, 0x71,
+	0x43, 0x7e, 0xe2, 0x01, 0x7f, 0x5a, 0x30, 0x8e, 0x05, 0x3c, 0x34, 0xd3,
+	0x8b, 0x83, 0x96, 0x0d, 0x3a, 0x67, 0x02, 0x3a, 0xec, 0x47, 0xc0, 0xeb,
+	0x44, 0x8a, 0x96, 0x5c, 0xe6, 0x63, 0x27, 0x95, 0x93, 0xdc, 0x7f, 0x0e,
+	0x7a, 0xc6, 0x74, 0x76, 0x70, 0x7e, 0xb3, 0x45, 0xc6, 0x47, 0xeb, 0x25,
+	0xc8, 0x98, 0xe5, 0xcb, 0x70, 0x71, 0x5a, 0xf8, 0x25, 0x3e, 0xbf, 0x21,
+	0xe4, 0xf8, 0xac, 0x0b, 0x3b, 0x03, 0xbd, 0xf2, 0xd7, 0x2c, 0xcc, 0x75,
+	0xe2, 0xac, 0x78, 0xdd, 0x76, 0xba, 0x07, 0x76, 0x9f, 0xaf, 0xf1, 0xfa,
+	0x13, 0xd0, 0xa3, 0x1f, 0xcb, 0xf5, 0x0b, 0x4b, 0xbd, 0x01, 0x3e, 0xe3,
+	0x76, 0x6e, 0xc3, 0x6d, 0xa5, 0x03, 0x55, 0xfd, 0x63, 0xf0, 0x7f, 0x13,
+	0xf8, 0x82, 0xce, 0x64, 0x19, 0x9f, 0xe9, 0x00, 0xae, 0x96, 0xfc, 0x04,
+	0x3a, 0x09, 0x59, 0xef, 0xe7, 0x6b, 0xad, 0x94, 0xaf, 0x86, 0xb4, 0x98,
+	0xce, 0x87, 0xa8, 0x87, 0xbf, 0x2c, 0x69, 0x4d, 0x49, 0x5a, 0x78, 0x5f,
+	0x63, 0x9f, 0x73, 0x3b, 0xf0, 0xe3, 0xec, 0xff, 0x69, 0x21, 0xd1, 0x41,
+	0x0b, 0xb2, 0xa6, 0x6f, 0xf7, 0x7d, 0x4d, 0xa2, 0x0d, 0xef, 0x77, 0xc1,
+	0xe6, 0x87, 0x90, 0x5b, 0x74, 0x62, 0x2e, 0xbd, 0x6d, 0x6e, 0x3b, 0xff,
+	0xb1, 0x6d, 0xfc, 0xeb, 0x80, 0xeb, 0xc1, 0x9a, 0x3e, 0x5c, 0x01, 0x70,
+	0xd3, 0x73, 0x90, 0xb3, 0xc5, 0x7e, 0x85, 0xe3, 0xe4, 0x75, 0x92, 0x97,
+	0xe9, 0x25, 0x05, 0x70, 0xbd, 0xc0, 0x0d, 0xc7, 0xbe, 0x1c, 0xaa, 0xa0,
+	0xf3, 0xcd, 0x9a, 0xbc, 0xbb, 0xc0, 0x19, 0xf4, 0x24, 0x78, 0xef, 0xe5,
+	0xda, 0xa7, 0xc9, 0xec, 0xba, 0x26, 0x79, 0xb1, 0xac, 0x98, 0x5f, 0xe6,
+	0x15, 0x7a, 0x8a, 0x38, 0xe4, 0x58, 0xa8, 0x0b, 0x13, 0x2a, 0x15, 0xb2,
+	0x3a, 0xf2, 0x73, 0xbe, 0xb7, 0x65, 0xbb, 0xd4, 0xf9, 0xae, 0x34, 0x26,
+	0x4c, 0x8e, 0xb5, 0x9a, 0xdc, 0xfb, 0x91, 0x25, 0xbe, 0xbb, 0x4d, 0xf3,
+	0x5d, 0x5f, 0x86, 0xb0, 0xf7, 0x07, 0x97, 0x4c, 0x7a, 0xa4, 0x9e, 0xa1,
+	0x87, 0xea, 0x86, 0x7e, 0x3f, 0x7c, 0x40, 0x71, 0xe3, 0x4e, 0xf7, 0x73,
+	0x09, 0xae, 0x45, 0x34, 0xe4, 0x81, 0x2d, 0xa6, 0x9f, 0x17, 0x94, 0xb9,
+	0x66, 0x9b, 0x33, 0xf8, 0x1e, 0x47, 0xaf, 0xd1, 0xf6, 0xdc, 0xe1, 0xff,
+	0x32, 0x6f, 0xe0, 0xf5, 0xd9, 0x5f, 0x23, 0x4f, 0x70, 0x91, 0x27, 0xb8,
+	0xc8, 0x13, 0x5c, 0xe4, 0x09, 0x2e, 0xf2, 0x04, 0x17, 0x79, 0x82, 0x8b,
+	0x3c, 0xc1, 0x45, 0x9e, 0x80, 0xd8, 0xed, 0xd7, 0x0b, 0x63, 0xc8, 0x7f,
+	0xe1, 0xbf, 0xdc, 0xcf, 0x43, 0x4e, 0x7c, 0xdf, 0xc9, 0x31, 0x87, 0x63,
+	0x33, 0xcf, 0xad, 0xee, 0x70, 0xf8, 0xdc, 0xa4, 0xef, 0xbb, 0x13, 0x73,
+	0xe3, 0x41, 0x3e, 0xc2, 0x30, 0x61, 0xec, 0x66, 0x38, 0x1a, 0x75, 0x2c,
+	0x05, 0x36, 0xc6, 0xf9, 0x8a, 0x1f, 0xb3, 0xfc, 0x5c, 0xf9, 0x75, 0xe4,
+	0x2c, 0x69, 0xe4, 0x2c, 0xfd, 0xc8, 0x4f, 0xf8, 0x8e, 0x3b, 0xbc, 0x63,
+	0xb2, 0x95, 0xc3, 0xee, 0x98, 0x72, 0xb7, 0xcb, 0xb9, 0xb4, 0x99, 0x2e,
+	0x0a, 0x31, 0xd7, 0x43, 0x1e, 0xe5, 0x47, 0xbe, 0x86, 0xbc, 0xf5, 0x9b,
+	0xf2, 0x3e, 0x6d, 0x7c, 0x90, 0xcf, 0x7c, 0xe5, 0x1a, 0xb9, 0x6b, 0x28,
+	0x5f, 0xff, 0x1e, 0x50, 0x2c, 0xb0, 0xfc, 0x88, 0xba, 0xcf, 0x43, 0xe0,
+	0xe7, 0x63, 0x94, 0x58, 0xde, 0x89, 0x39, 0x9d, 0x7a, 0xe4, 0x5d, 0x12,
+	0x8e, 0xf2, 0xbc, 0xd6, 0x43, 0xed, 0x26, 0x89, 0xf3, 0x7c, 0xe3, 0xc0,
+	0x74, 0xd9, 0xbf, 0x5e, 0x3a, 0x96, 0xaf, 0x5d, 0x92, 0x3a, 0x75, 0xb8,
+	0x5e, 0x40, 0x7d, 0xd4, 0x07, 0x18, 0x0d, 0xb5, 0x55, 0x48, 0x9b, 0x69,
+	0x5e, 0x4d, 0xc8, 0x9a, 0xe7, 0xfc, 0xc6, 0x79, 0xe2, 0xac, 0x79, 0x9d,
+	0x4b, 0xc7, 0xca, 0x55, 0x23, 0xc5, 0xb5, 0xb2, 0xad, 0x5f, 0x3a, 0x76,
+	0x02, 0x34, 0x16, 0x91, 0x1b, 0xa8, 0x72, 0xed, 0x4b, 0xc7, 0xa6, 0xab,
+	0xfe, 0x7d, 0x96, 0xcf, 0x03, 0xe2, 0x60, 0xb6, 0x9d, 0xd4, 0x05, 0xff,
+	0x5e, 0x4b, 0x48, 0x5c, 0xc6, 0x63, 0x7c, 0x0d, 0x78, 0x7c, 0x6e, 0x19,
+	0xe0, 0xf2, 0xd9, 0x31, 0x0f, 0x97, 0x8e, 0x95, 0x6a, 0xcd, 0x3c, 0x30,
+	0x1d, 0xa6, 0x1b, 0xee, 0x87, 0xf7, 0x92, 0x20, 0xb1, 0xec, 0x79, 0xc5,
+	0x91, 0xfe, 0x20, 0xef, 0x3a, 0x81, 0xfc, 0x4e, 0x93, 0x7a, 0xee, 0x8f,
+	0xff, 0x4c, 0xc6, 0xa9, 0xb4, 0xe0, 0x79, 0x7e, 0xe2, 0x5d, 0xf6, 0x3b,
+	0x98, 0xc3, 0x78, 0x31, 0x84, 0x15, 0x01, 0x6c, 0x47, 0x93, 0x3c, 0x5b,
+	0x82, 0xf5, 0x98, 0x27, 0xde, 0xe7, 0xcf, 0xb1, 0x7f, 0x79, 0x07, 0xc7,
+	0xf9, 0x18, 0xd6, 0xc5, 0x59, 0xba, 0xff, 0x5b, 0xd9, 0x37, 0xef, 0x89,
+	0x65, 0xaa, 0x01, 0x87, 0xe1, 0x99, 0x46, 0x88, 0x83, 0x17, 0xe7, 0x7d,
+	0x3c, 0xb1, 0x71, 0xff, 0xf7, 0x49, 0xeb, 0x36, 0xf3, 0x1a, 0xae, 0x1f,
+	0xd2, 0xc9, 0xf8, 0xe7, 0xb6, 0x81, 0x2f, 0xff, 0x4f, 0x31, 0x3c, 0xa1,
+	0x8b, 0x1f, 0xb9, 0x47, 0xcd, 0x34, 0xd5, 0xa1, 0xe1, 0xfd, 0x05, 0xdf,
+	0x07, 0x70, 0x7d, 0xcf, 0xdf, 0x1a, 0x9a, 0x6b, 0xc5, 0x67, 0x83, 0x58,
+	0xd6, 0x47, 0xb6, 0xc6, 0x75, 0xc3, 0x85, 0x60, 0xbc, 0x0b, 0xb1, 0x8d,
+	0xc7, 0x0d, 0xc8, 0x17, 0xba, 0x6c, 0xb5, 0x07, 0x75, 0x4b, 0xc2, 0xff,
+	0x26, 0x94, 0x61, 0x3b, 0xe2, 0xba, 0xaf, 0x2d, 0x98, 0x0b, 0xed, 0x88,
+	0xfd, 0xb0, 0x16, 0xcc, 0xb1, 0xbf, 0x15, 0xa8, 0x5d, 0xb8, 0x0f, 0x3a,
+	0x8b, 0xcd, 0xb6, 0x14, 0x3e, 0x13, 0x74, 0x6e, 0x3e, 0xf4, 0x5b, 0xf0,
+	0x29, 0x83, 0x5a, 0xe0, 0xfb, 0xe3, 0xf0, 0x7d, 0x9d, 0x74, 0x00, 0x3e,
+	0xeb, 0x20, 0x7c, 0xd6, 0x21, 0xd4, 0x8b, 0x63, 0x4b, 0xcd, 0xf7, 0xbc,
+	0x5c, 0xa3, 0x76, 0x2a, 0x47, 0xe4, 0xf9, 0x97, 0x3c, 0xd5, 0xfc, 0x10,
+	0x3a, 0xc0, 0x75, 0x57, 0xa8, 0x13, 0xf0, 0xb7, 0x56, 0x02, 0x3a, 0xb1,
+	0xfd, 0x3e, 0x39, 0x03, 0xdb, 0x68, 0xb7, 0x85, 0xcc, 0xe5, 0x7c, 0xd9,
+	0x97, 0x6b, 0xbe, 0xec, 0xe1, 0x97, 0x41, 0x5f, 0xa3, 0x52, 0x5d, 0xa7,
+	0x12, 0xd6, 0x2d, 0x61, 0xdd, 0x12, 0xea, 0xbc, 0xe9, 0x7a, 0xf3, 0x77,
+	0xaf, 0x8e, 0x80, 0x77, 0xc6, 0x0d, 0xfb, 0x7a, 0xd3, 0xfe, 0xc3, 0xe7,
+	0x49, 0xc8, 0xff, 0x11, 0xc8, 0xff, 0x28, 0xea, 0x9b, 0xdf, 0x47, 0x7d,
+	0xf3, 0x7b, 0xa8, 0x6f, 0x8e, 0xa0, 0xbe, 0x99, 0x44, 0x7d, 0xf3, 0x65,
+	0xf8, 0x8f, 0xfb, 0xe0, 0x3f, 0x26, 0xe0, 0x3f, 0xc6, 0xe5, 0xdd, 0xd3,
+	0x61, 0x77, 0xfb, 0x9d, 0x4a, 0xb8, 0x16, 0xb7, 0x9f, 0x12, 0x99, 0x25,
+	0xec, 0x69, 0x8c, 0x6a, 0x0d, 0xae, 0x6f, 0x2c, 0x72, 0x46, 0xb9, 0xbe,
+	0x99, 0x50, 0x26, 0x91, 0xbf, 0xdf, 0x3f, 0xcc, 0x75, 0x4f, 0x42, 0xc9,
+	0xcb, 0xba, 0xc7, 0xb8, 0xe0, 0x20, 0x75, 0x43, 0xee, 0x87, 0x3d, 0x1b,
+	0xe7, 0xf2, 0xe0, 0xc5, 0xcf, 0xf9, 0xba, 0x03, 0xbf, 0x17, 0xa7, 0xc5,
+	0x59, 0xd4, 0x0c, 0xee, 0x3f, 0x28, 0x45, 0xe9, 0x1b, 0x75, 0x8c, 0x51,
+	0x2b, 0xbb, 0xaf, 0x06, 0xe3, 0x11, 0x9a, 0x9a, 0x47, 0x6d, 0x7b, 0xfa,
+	0x6f, 0x95, 0xbc, 0x1c, 0x5b, 0x18, 0x23, 0xdf, 0x3d, 0xfd, 0xd7, 0xc1,
+	0xb8, 0x14, 0xe8, 0x43, 0xc0, 0xab, 0x6e, 0xe1, 0xd9, 0x15, 0xe4, 0x1c,
+	0x2f, 0xf6, 0x6c, 0xfd, 0x3f, 0xef, 0xb8, 0xb5, 0x28, 0x64, 0x1e, 0xdf,
+	0xe5, 0xd7, 0x67, 0xcd, 0xf3, 0x9d, 0x4d, 0xf3, 0xba, 0xfc, 0x0e, 0x5b,
+	0xac, 0xb4, 0xbd, 0x07, 0x0f, 0x4c, 0x4b, 0x83, 0x46, 0xd5, 0xa6, 0x0f,
+	0x3d, 0xfe, 0x5e, 0xe8, 0x88, 0x76, 0xf9, 0x0d, 0xcf, 0x91, 0xf7, 0x7a,
+	0xb0, 0xf3, 0x91, 0x27, 0x77, 0xf9, 0xbe, 0x80, 0xfb, 0x49, 0xc5, 0xf7,
+	0xef, 0x8f, 0x83, 0x0e, 0x64, 0xed, 0x36, 0xd7, 0x70, 0x7a, 0x70, 0x97,
+	0xa2, 0x1f, 0x9f, 0xe1, 0xb3, 0x96, 0xb4, 0xb9, 0xd6, 0xe3, 0xba, 0x2f,
+	0x8c, 0x01, 0x21, 0xad, 0xff, 0x48, 0xfa, 0x7c, 0xdf, 0x87, 0x9a, 0x8e,
+	0x61, 0xc2, 0x71, 0x73, 0xfd, 0x17, 0x0f, 0xee, 0xe1, 0x98, 0xd7, 0x58,
+	0xc0, 0xab, 0x16, 0xd0, 0xfb, 0x77, 0xcf, 0xf7, 0x3d, 0x8c, 0xaf, 0x37,
+	0xe1, 0x5f, 0x40, 0xae, 0xc7, 0x77, 0x26, 0xbb, 0xe5, 0x77, 0xc9, 0x77,
+	0x66, 0x3b, 0xe8, 0xed, 0x53, 0xc8, 0x59, 0x2d, 0x23, 0x73, 0x09, 0xb5,
+	0xc7, 0x32, 0xdb, 0xc9, 0x08, 0xf3, 0x39, 0x90, 0x9e, 0xa6, 0x9b, 0x7b,
+	0xfc, 0x5c, 0xfc, 0xab, 0xca, 0x47, 0xf9, 0x16, 0xc1, 0x3a, 0x3f, 0x6a,
+	0x5a, 0x27, 0xdd, 0xb4, 0xce, 0x0a, 0xdb, 0x6c, 0xed, 0x4b, 0xd8, 0x73,
+	0x69, 0xf7, 0xcd, 0x7a, 0x32, 0xa8, 0xcb, 0x1e, 0x1e, 0x69, 0xa3, 0x6a,
+	0xaf, 0xb1, 0xf2, 0x1a, 0xf2, 0xf5, 0xe2, 0x08, 0xe6, 0x92, 0x03, 0x78,
+	0xc7, 0xf3, 0x46, 0x8d, 0x84, 0xb1, 0x52, 0xa3, 0xcf, 0x01, 0xdf, 0x28,
+	0x11, 0xf1, 0x3c, 0xf7, 0x25, 0x6f, 0xb5, 0xc0, 0x07, 0xa4, 0xd6, 0xb0,
+	0xe7, 0x49, 0xd4, 0x5f, 0x47, 0x37, 0xea, 0x61, 0x5e, 0xe7, 0x56, 0x65,
+	0x4d, 0xe6, 0xc6, 0xfb, 0x95, 0x52, 0xd2, 0xdf, 0xe3, 0xef, 0xc2, 0x5f,
+	0xa8, 0x82, 0x71, 0xdf, 0x01, 0x6d, 0x85, 0x16, 0x4e, 0xa9, 0xf2, 0x0e,
+	0xb6, 0x38, 0xc2, 0x67, 0xcd, 0xcf, 0x8f, 0x93, 0x5d, 0xb8, 0xa7, 0x3f,
+	0x0d, 0xf6, 0x34, 0x16, 0xd4, 0xd3, 0xe1, 0x9e, 0x62, 0xf4, 0xe6, 0xac,
+	0x0e, 0xdc, 0x9b, 0x20, 0x8f, 0x02, 0x2d, 0x35, 0xd2, 0x9f, 0x42, 0xa7,
+	0xd2, 0x24, 0x1b, 0x6d, 0xdb, 0x19, 0x96, 0x36, 0x6b, 0xf8, 0xf1, 0x14,
+	0xec, 0xf0, 0x78, 0x4f, 0x78, 0x37, 0xac, 0x9a, 0x1e, 0xd7, 0x3d, 0x68,
+	0x3c, 0xdf, 0x0f, 0x5b, 0x4c, 0xc3, 0x3e, 0x39, 0x67, 0x2a, 0x70, 0xad,
+	0xc2, 0xf6, 0xa4, 0x3b, 0xaa, 0xa1, 0x4f, 0x50, 0x06, 0xf5, 0x0e, 0xef,
+	0x3f, 0x47, 0x8b, 0x8d, 0x90, 0x87, 0x2c, 0xec, 0x71, 0x14, 0xbf, 0x61,
+	0xbc, 0xb3, 0xf0, 0xe3, 0x5a, 0x69, 0x85, 0x1e, 0x95, 0xb9, 0x38, 0x72,
+	0xed, 0x41, 0xe6, 0xef, 0x4e, 0xc0, 0xb3, 0x3e, 0xb3, 0x9e, 0xde, 0x49,
+	0x4e, 0x2f, 0xfb, 0x8a, 0x14, 0x68, 0x03, 0xc7, 0x5d, 0x87, 0xad, 0xf7,
+	0xe3, 0x69, 0xe8, 0x45, 0x96, 0xad, 0xa4, 0xef, 0x79, 0x6a, 0x96, 0xbf,
+	0x51, 0x5c, 0x08, 0xc6, 0x03, 0xfa, 0x3d, 0xac, 0x7b, 0xa9, 0x1b, 0x68,
+	0x65, 0x3e, 0x8c, 0x83, 0x67, 0x60, 0x83, 0x7c, 0x67, 0x3b, 0x06, 0xb9,
+	0xf0, 0x58, 0x09, 0xe2, 0x21, 0xe6, 0x17, 0x91, 0x94, 0xb4, 0xe7, 0x68,
+	0x19, 0xf5, 0x3f, 0xf5, 0xf2, 0x13, 0xf9, 0xae, 0xbb, 0x33, 0xd0, 0xf7,
+	0xad, 0xf8, 0xaa, 0xc9, 0xfd, 0x31, 0xf0, 0xa7, 0x35, 0xe1, 0x33, 0x8e,
+	0x5f, 0x9f, 0xac, 0x11, 0xe2, 0x71, 0xca, 0xfb, 0x82, 0xc8, 0x3d, 0x4d,
+	0xbf, 0x23, 0xf7, 0x54, 0xa7, 0x23, 0xf3, 0xa8, 0x6d, 0xb3, 0x03, 0x99,
+	0x45, 0x32, 0x32, 0x27, 0x68, 0x48, 0x3f, 0x40, 0xaa, 0xfc, 0xd6, 0x97,
+	0x16, 0xde, 0x17, 0x5a, 0x72, 0x9e, 0x77, 0x06, 0xbc, 0xbf, 0x28, 0xd7,
+	0x79, 0x1a, 0xfc, 0x43, 0x56, 0xb2, 0x26, 0x61, 0x5e, 0xf1, 0x4c, 0x32,
+	0xbf, 0x15, 0x3a, 0xd2, 0xf8, 0x61, 0x70, 0x36, 0x8f, 0x90, 0xe3, 0xbe,
+	0xa5, 0x3a, 0x66, 0x05, 0xb0, 0xdf, 0x09, 0x78, 0xcb, 0x81, 0x5f, 0xac,
+	0xdf, 0x58, 0x4f, 0xb2, 0x6f, 0xe0, 0x33, 0x77, 0x90, 0x35, 0x3a, 0x23,
+	0xc8, 0xa3, 0x92, 0xd7, 0xf2, 0x03, 0x09, 0xda, 0xea, 0x07, 0x18, 0x2f,
+	0xf1, 0x31, 0xba, 0xc2, 0x7c, 0x94, 0xa4, 0xff, 0x94, 0x71, 0x4b, 0xd2,
+	0x53, 0xb7, 0xf9, 0x82, 0x6f, 0xc9, 0xe7, 0xaa, 0xca, 0xbe, 0x89, 0xe3,
+	0x1f, 0xeb, 0x70, 0x27, 0xfc, 0x1f, 0x74, 0x10, 0x76, 0x9c, 0x9f, 0xe7,
+	0xfb, 0x89, 0x41, 0xbe, 0x57, 0x3a, 0x57, 0xc0, 0xd9, 0x2e, 0xf0, 0xf7,
+	0xc7, 0xa4, 0x5f, 0x63, 0xfa, 0xf5, 0x57, 0x9a, 0x7d, 0x21, 0xda, 0x92,
+	0xf4, 0x93, 0x05, 0xf9, 0xbd, 0x31, 0x01, 0x18, 0x8f, 0x7d, 0x67, 0xd3,
+	0xdf, 0x58, 0xbc, 0x6c, 0xfb, 0x7f, 0x63, 0x11, 0x7c, 0xfb, 0xad, 0xf9,
+	0x79, 0xc4, 0x83, 0x75, 0x8d, 0x26, 0xeb, 0xe1, 0xdf, 0x5c, 0xf0, 0x39,
+	0xc0, 0x37, 0xd7, 0xc3, 0xdc, 0xc1, 0x93, 0xf1, 0xa5, 0xbc, 0xe5, 0x2c,
+	0x97, 0x82, 0x9c, 0x88, 0x6b, 0x00, 0x96, 0x21, 0xc6, 0x8b, 0xfe, 0xf9,
+	0x2d, 0x88, 0x3d, 0x38, 0x3f, 0xc8, 0x1c, 0x7c, 0xbd, 0x39, 0xeb, 0xd7,
+	0xb9, 0x65, 0xf6, 0x8b, 0xfd, 0x61, 0xdd, 0xbb, 0x9b, 0xca, 0x13, 0xfc,
+	0x3e, 0x46, 0x6f, 0xcc, 0xc6, 0xe4, 0xfb, 0x22, 0xc5, 0x82, 0xf7, 0x3c,
+	0x4e, 0x50, 0x51, 0xbe, 0xaf, 0x05, 0xf4, 0x50, 0xa7, 0xdd, 0x17, 0x8e,
+	0x35, 0xe5, 0x48, 0xc3, 0xc7, 0x9b, 0x6a, 0xd4, 0xe8, 0xd1, 0xc6, 0x2a,
+	0xf6, 0xaf, 0x50, 0x7e, 0xbc, 0x44, 0x37, 0x98, 0xba, 0x8c, 0xfb, 0x4e,
+	0x82, 0x75, 0x8c, 0xf5, 0x6b, 0x4c, 0xd6, 0x9d, 0x25, 0xe4, 0x0b, 0xc5,
+	0x11, 0xfe, 0xc6, 0xf3, 0xde, 0x5d, 0xc5, 0x8a, 0xa1, 0xdb, 0xf4, 0x81,
+	0xe7, 0x68, 0x3c, 0x26, 0x21, 0x72, 0xab, 0x77, 0x3d, 0x58, 0xbf, 0x78,
+	0x97, 0xbf, 0x57, 0xbc, 0xaf, 0x33, 0xac, 0x2a, 0xbf, 0xcd, 0xfe, 0xe4,
+	0x76, 0x8d, 0xd6, 0x6e, 0xf7, 0xbc, 0xfb, 0x2d, 0x9d, 0x9c, 0xa0, 0x76,
+	0xf5, 0xbf, 0xb9, 0xb7, 0xcb, 0x1c, 0xc4, 0x19, 0x49, 0x2b, 0x05, 0xd8,
+	0xeb, 0xb2, 0x8b, 0x3a, 0x47, 0x18, 0xa3, 0xab, 0x42, 0x47, 0xcc, 0xe5,
+	0x3b, 0x80, 0x3b, 0x7a, 0xf8, 0x7b, 0xf3, 0x8c, 0xc5, 0x30, 0x7d, 0xfe,
+	0x5d, 0xd7, 0x2d, 0xf7, 0x49, 0x3f, 0x4b, 0x14, 0xc4, 0x9e, 0x5b, 0x9a,
+	0x6d, 0xa2, 0x39, 0xb7, 0x64, 0x5b, 0xa0, 0x49, 0x0d, 0xbc, 0x94, 0x2b,
+	0x61, 0x9e, 0xc6, 0x7f, 0x4b, 0xb0, 0x7a, 0xd7, 0x37, 0xc0, 0xe7, 0x34,
+	0xf8, 0xe4, 0x7d, 0x4c, 0xd7, 0x43, 0x9d, 0x0b, 0x6b, 0x05, 0xee, 0x23,
+	0xe6, 0xbb, 0x88, 0xf9, 0x2e, 0x62, 0xbe, 0x8b, 0x98, 0xef, 0x22, 0xe6,
+	0xbb, 0x88, 0xf9, 0x2e, 0x62, 0xbe, 0x8b, 0x98, 0xef, 0x8e, 0x07, 0x79,
+	0xda, 0x63, 0x1b, 0x79, 0xda, 0x4a, 0x83, 0xbf, 0x43, 0x49, 0x5e, 0x4a,
+	0x25, 0xf2, 0xf3, 0x5c, 0x12, 0x9c, 0xd3, 0x84, 0x79, 0xee, 0xc7, 0x7f,
+	0x13, 0xf1, 0xf1, 0x38, 0xc7, 0x63, 0xbc, 0x92, 0x22, 0x4c, 0xc6, 0xf3,
+	0xf3, 0x3c, 0xae, 0xad, 0xb6, 0xe2, 0x20, 0x5f, 0xcb, 0xb1, 0x3f, 0x63,
+	0xbb, 0x48, 0xfa, 0xf5, 0x62, 0xee, 0xf5, 0x2f, 0xa1, 0x76, 0x3c, 0x5e,
+	0xac, 0xcb, 0x18, 0x8c, 0xf1, 0x7b, 0x18, 0x6b, 0xac, 0x73, 0xfc, 0xee,
+	0x5e, 0xae, 0x27, 0x8a, 0xf5, 0x14, 0x95, 0x16, 0xc3, 0xfc, 0x07, 0x78,
+	0xee, 0x90, 0x52, 0xa8, 0xf2, 0xd9, 0x0a, 0x9a, 0x4e, 0x42, 0x28, 0x66,
+	0x73, 0x5e, 0x77, 0x49, 0xd6, 0x48, 0xfe, 0xdf, 0x05, 0x0d, 0x83, 0xb7,
+	0xf0, 0x1e, 0x97, 0x48, 0x9d, 0x4d, 0xca, 0xbf, 0x31, 0x48, 0x98, 0x83,
+	0xf2, 0x6f, 0x1d, 0xba, 0xb1, 0x8e, 0x98, 0xdd, 0x13, 0xfe, 0xed, 0x06,
+	0xd7, 0x5d, 0xf6, 0xe6, 0xfd, 0x2b, 0xef, 0x23, 0x09, 0x7b, 0xbd, 0xa7,
+	0x0f, 0x7b, 0xc3, 0xb9, 0x5e, 0xd9, 0x25, 0xf3, 0x6e, 0xf8, 0xce, 0x33,
+	0x83, 0x37, 0xf5, 0x52, 0xe7, 0x6e, 0x5a, 0x1e, 0xe4, 0x1a, 0xad, 0x0d,
+	0xf4, 0x18, 0xd6, 0xc8, 0xd8, 0x62, 0x37, 0x9d, 0x9d, 0x87, 0x6f, 0x9d,
+	0x37, 0x2c, 0xfe, 0xfb, 0x82, 0x85, 0xc1, 0x24, 0x7c, 0xf2, 0x78, 0x2f,
+	0xc7, 0xe4, 0xc5, 0x06, 0xeb, 0x4a, 0x37, 0xf0, 0xfb, 0xa1, 0x8b, 0x3b,
+	0x60, 0x43, 0x02, 0xeb, 0x87, 0xb4, 0xff, 0x53, 0xd2, 0xee, 0x36, 0xf3,
+	0x7d, 0x52, 0x37, 0x84, 0xa1, 0xa7, 0x05, 0x78, 0xff, 0x48, 0x6d, 0x69,
+	0x11, 0x7f, 0x2f, 0x9c, 0x76, 0x9b, 0xbf, 0x1b, 0x0e, 0x29, 0xc5, 0x2a,
+	0xff, 0x8d, 0xc3, 0x20, 0xfd, 0x4f, 0xe1, 0x56, 0x17, 0xd3, 0xd6, 0x79,
+	0x86, 0xdf, 0xcf, 0xe6, 0x2f, 0xc4, 0x81, 0x13, 0xe2, 0x80, 0x41, 0x54,
+	0xf3, 0x31, 0x07, 0xe2, 0xca, 0x44, 0x3d, 0x20, 0x32, 0x59, 0x15, 0x52,
+	0x2d, 0xdb, 0x50, 0xb7, 0x5d, 0x36, 0x77, 0xcb, 0xa6, 0x4c, 0xda, 0x22,
+	0x06, 0x49, 0x9b, 0x6a, 0xd2, 0x2e, 0x76, 0x31, 0xed, 0x2e, 0x96, 0x81,
+	0x34, 0xcd, 0xec, 0x1a, 0x56, 0x32, 0xa4, 0x5d, 0x4c, 0xae, 0x31, 0x04,
+	0x88, 0x53, 0xab, 0x5b, 0x2f, 0x32, 0x4d, 0x53, 0x90, 0x57, 0x25, 0xdd,
+	0x4d, 0x6f, 0x76, 0x3f, 0x55, 0x64, 0xad, 0x72, 0xd1, 0x25, 0x6a, 0xa7,
+	0x6a, 0x7f, 0x17, 0x67, 0xcf, 0xf3, 0x9d, 0x63, 0x20, 0x6c, 0xd5, 0x90,
+	0xac, 0xf3, 0x9d, 0xef, 0x7c, 0xff, 0xdf, 0xfb, 0x3e, 0xef, 0x2f, 0x53,
+	0xa0, 0x2f, 0xc3, 0x8a, 0xa9, 0x4b, 0x65, 0xb6, 0xb1, 0x50, 0xa6, 0x1d,
+	0x7e, 0x13, 0xbc, 0xdc, 0x23, 0x8b, 0xa0, 0xe3, 0xfc, 0x68, 0xab, 0xe7,
+	0x6f, 0xed, 0xf4, 0x78, 0x38, 0xd2, 0xeb, 0xc9, 0x28, 0xad, 0x4b, 0xe6,
+	0xb5, 0x3e, 0xdd, 0x7d, 0xe8, 0xdb, 0x0f, 0xb0, 0xa6, 0x10, 0xce, 0x61,
+	0xb8, 0x57, 0xe3, 0x91, 0x8f, 0xef, 0x7d, 0x87, 0xde, 0x7b, 0x0f, 0xbd,
+	0x9f, 0xfc, 0x1f, 0xed, 0x59, 0x3e, 0x4c, 0x0f, 0x5c, 0xa7, 0x19, 0xe7,
+	0x2c, 0xf9, 0xc2, 0x84, 0x9a, 0x2b, 0x98, 0x09, 0xea, 0x02, 0x29, 0x71,
+	0x54, 0xca, 0x6e, 0x03, 0xc6, 0xb5, 0xc9, 0xc2, 0x0a, 0x68, 0x1e, 0xfb,
+	0x68, 0xb7, 0x18, 0x2f, 0x7f, 0xb6, 0x97, 0x3c, 0xd3, 0x81, 0x6b, 0xf0,
+	0x59, 0x43, 0x21, 0xb4, 0x73, 0x5e, 0xb3, 0x63, 0xc6, 0x45, 0xed, 0xbf,
+	0xa1, 0x0e, 0xe3, 0xa8, 0xbc, 0xce, 0xfd, 0x60, 0x9b, 0x16, 0x79, 0x60,
+	0x25, 0x7b, 0xbc, 0x5c, 0x22, 0xd8, 0xbb, 0x2f, 0xf6, 0x52, 0xbf, 0x78,
+	0xd5, 0xde, 0xab, 0x33, 0x76, 0x85, 0x79, 0x5a, 0x20, 0x9a, 0x97, 0x45,
+	0xca, 0x55, 0x91, 0x9b, 0xf8, 0xfd, 0xb1, 0xea, 0xc5, 0x2f, 0x14, 0x6d,
+	0xed, 0x49, 0xd9, 0x2e, 0x3d, 0x2b, 0x35, 0xc8, 0x9c, 0x2d, 0xdb, 0x71,
+	0x1e, 0xda, 0x61, 0x7d, 0xe6, 0xaf, 0x17, 0x94, 0x44, 0xc6, 0x28, 0xd3,
+	0xda, 0xe4, 0x67, 0x2b, 0xcc, 0xbb, 0x33, 0x8d, 0x87, 0xc2, 0xfc, 0xb7,
+	0x90, 0x64, 0x82, 0x7e, 0xad, 0x97, 0xca, 0xb7, 0x45, 0x3e, 0xc1, 0xb7,
+	0x4f, 0x56, 0x5e, 0xe9, 0xa5, 0xcf, 0xe5, 0xe3, 0x15, 0xbe, 0xfb, 0xf0,
+	0xf4, 0x49, 0xc3, 0xf2, 0x43, 0x7f, 0x05, 0xf0, 0x18, 0x3c, 0x77, 0xee,
+	0xf7, 0x47, 0x5c, 0x1b, 0xea, 0x68, 0xc3, 0xb6, 0x49, 0x7e, 0x18, 0x38,
+	0xa8, 0x86, 0x74, 0xbe, 0x52, 0x23, 0xa8, 0x71, 0xd9, 0x5f, 0x61, 0x5e,
+	0x9d, 0x71, 0x54, 0x63, 0x74, 0xf2, 0xf6, 0x82, 0xde, 0x0b, 0xca, 0xb9,
+	0x8a, 0x4d, 0x5a, 0x35, 0x64, 0x0b, 0xbc, 0xb6, 0x59, 0xdf, 0xea, 0xe3,
+	0x5d, 0x6d, 0xd7, 0x17, 0x7b, 0x5d, 0x1b, 0x8d, 0x75, 0xaf, 0xf7, 0xba,
+	0x75, 0x61, 0xcf, 0xe6, 0xa2, 0x6d, 0x56, 0xc6, 0xde, 0x7e, 0x2c, 0xf5,
+	0xd5, 0x9f, 0xca, 0x9d, 0xd2, 0x4f, 0xe4, 0xb7, 0xab, 0xe7, 0xa1, 0x73,
+	0x98, 0xe5, 0x1c, 0xe4, 0xc9, 0xbb, 0x75, 0xc7, 0x79, 0xd7, 0x3e, 0x07,
+	0xfb, 0xc0, 0x71, 0xfe, 0x64, 0xef, 0x48, 0x64, 0xfc, 0x7b, 0xd8, 0x73,
+	0x16, 0x3c, 0x44, 0x2c, 0xcc, 0x80, 0xde, 0x52, 0x7d, 0xd2, 0x19, 0xd0,
+	0x74, 0x32, 0x34, 0xde, 0x8a, 0x3d, 0xf8, 0x3c, 0x3d, 0x9c, 0x7b, 0x49,
+	0xf7, 0x91, 0x66, 0x7c, 0xf5, 0x0a, 0xe6, 0x6f, 0x05, 0x5f, 0x1c, 0xc5,
+	0x4f, 0xc9, 0xc3, 0x31, 0xac, 0x75, 0x8c, 0xb4, 0xd7, 0x2a, 0x91, 0x67,
+	0xb0, 0x8f, 0x6c, 0x8b, 0x3c, 0x2a, 0xdc, 0xea, 0xa5, 0x3f, 0xef, 0x51,
+	0x81, 0x65, 0xdf, 0x57, 0xbb, 0xc4, 0x91, 0x16, 0xc8, 0xef, 0x85, 0x09,
+	0x57, 0x57, 0xfa, 0x83, 0x3a, 0x85, 0xf6, 0x56, 0xee, 0x7d, 0x45, 0xdd,
+	0x2e, 0xe7, 0xb4, 0x42, 0x17, 0x9f, 0x82, 0x0e, 0x94, 0xac, 0x5f, 0x91,
+	0xc6, 0x58, 0x00, 0x6d, 0xa8, 0xa3, 0x68, 0x2c, 0x91, 0x54, 0x81, 0xf9,
+	0x5d, 0xcc, 0xb5, 0xc2, 0x1a, 0xcf, 0x11, 0x37, 0xb8, 0xc6, 0x36, 0xc6,
+	0xe0, 0xbc, 0x3a, 0x0b, 0x34, 0xc2, 0x3a, 0xd2, 0x77, 0x02, 0x3c, 0x99,
+	0xa0, 0xdc, 0xc4, 0x78, 0xa3, 0x18, 0x8f, 0xe5, 0x2e, 0x8c, 0x77, 0x45,
+	0x92, 0x76, 0x73, 0xcc, 0x38, 0xda, 0x10, 0x67, 0xe2, 0xd0, 0x1f, 0x06,
+	0x55, 0x7a, 0x25, 0x08, 0xf9, 0xdd, 0x2b, 0x69, 0xe3, 0xc8, 0x81, 0x3d,
+	0xe6, 0xb4, 0x7d, 0xe0, 0xf3, 0x8d, 0x7a, 0x6b, 0xea, 0x3a, 0xb0, 0x26,
+	0xf6, 0xc7, 0x0f, 0xb6, 0x71, 0x72, 0x65, 0x09, 0x38, 0xb5, 0xf4, 0x41,
+	0xd2, 0xbe, 0x20, 0xa9, 0x20, 0xd7, 0xc4, 0xfa, 0x20, 0xd6, 0x4c, 0x3f,
+	0xd6, 0x77, 0x81, 0x43, 0x47, 0xbc, 0x3a, 0xb6, 0x15, 0x5f, 0x12, 0x67,
+	0xef, 0xda, 0xb5, 0xac, 0xfb, 0x8a, 0x24, 0x97, 0xb2, 0x32, 0xad, 0xfb,
+	0xf1, 0x0c, 0x07, 0xb4, 0xee, 0x41, 0x5e, 0x8d, 0x9c, 0xc0, 0x59, 0xc6,
+	0xf6, 0x6d, 0xe0, 0xf0, 0x09, 0x72, 0x91, 0xd1, 0xe7, 0xf2, 0x2c, 0xbe,
+	0x9d, 0xe0, 0x1d, 0xb5, 0x49, 0xe4, 0x5b, 0x90, 0x91, 0x85, 0x66, 0x7d,
+	0x40, 0x3e, 0x2d, 0xf4, 0xf4, 0x31, 0xce, 0xf2, 0xd7, 0x82, 0x21, 0x1f,
+	0x17, 0x74, 0x2c, 0x74, 0xc6, 0x2f, 0xe6, 0x65, 0xd7, 0x3e, 0x1f, 0x9e,
+	0x59, 0x50, 0xfc, 0x3e, 0x7c, 0x79, 0x5d, 0x75, 0xa0, 0x6d, 0x00, 0xed,
+	0xb8, 0x0e, 0x43, 0xa6, 0x0a, 0x9f, 0x3b, 0xb3, 0x23, 0x8e, 0x33, 0xad,
+	0xf3, 0xc3, 0x62, 0xc6, 0x82, 0x6a, 0xea, 0xe4, 0x51, 0x29, 0x04, 0xdb,
+	0x31, 0x57, 0xcc, 0x58, 0x57, 0xc3, 0x58, 0x0f, 0xcb, 0x27, 0xc8, 0x13,
+	0xa1, 0x1d, 0xe1, 0xf8, 0x66, 0x66, 0x4d, 0xc5, 0xc2, 0x43, 0xca, 0x4c,
+	0xe4, 0xf1, 0x6b, 0x51, 0x3a, 0x8e, 0x18, 0x0a, 0x2b, 0xf0, 0x2e, 0xf6,
+	0x64, 0x9d, 0x76, 0x9c, 0x8c, 0xc5, 0xfa, 0x98, 0x11, 0x50, 0xf4, 0xb7,
+	0x74, 0xea, 0x78, 0xe3, 0xb5, 0x93, 0x31, 0xe3, 0xb4, 0x3a, 0xee, 0xbd,
+	0xc7, 0x81, 0x99, 0x7b, 0xe3, 0x9d, 0x5f, 0x53, 0x86, 0xbc, 0x51, 0x88,
+	0x85, 0xe7, 0x94, 0x99, 0xc5, 0x98, 0xd9, 0xb4, 0x22, 0x6e, 0xc4, 0x8c,
+	0x4e, 0x45, 0x9f, 0x68, 0xbb, 0xde, 0x77, 0x06, 0xfd, 0x63, 0xaa, 0xc5,
+	0x5b, 0x0f, 0xef, 0xeb, 0xed, 0x3e, 0x97, 0x67, 0x88, 0x39, 0x23, 0xc0,
+	0x4c, 0xe6, 0x9a, 0xe9, 0xdc, 0x86, 0x44, 0x64, 0x7c, 0x44, 0x63, 0xe8,
+	0xe3, 0x33, 0x7f, 0x47, 0x1d, 0xca, 0x65, 0xd6, 0x45, 0x3d, 0x7e, 0x1b,
+	0xd1, 0x3a, 0xf3, 0xe3, 0x33, 0x39, 0x9d, 0xf7, 0xd8, 0x50, 0x11, 0x6f,
+	0xdf, 0x7b, 0x77, 0x16, 0x4e, 0xda, 0x4f, 0x71, 0x9c, 0x25, 0xff, 0x64,
+	0xbb, 0x30, 0xa7, 0x74, 0xaa, 0xd4, 0xa4, 0x0d, 0xfa, 0x03, 0x98, 0x2f,
+	0xd0, 0x8c, 0x7b, 0x5f, 0x11, 0xdf, 0x78, 0xc7, 0x01, 0x3a, 0x81, 0xae,
+	0x09, 0x1d, 0xb5, 0x8a, 0x71, 0xf2, 0x2b, 0x92, 0x73, 0xfb, 0x4b, 0x07,
+	0x73, 0x58, 0xf3, 0xd5, 0x2f, 0x1b, 0x83, 0x73, 0x63, 0x0e, 0xbc, 0x3f,
+	0x3e, 0x43, 0xfa, 0xe4, 0xd9, 0x84, 0xd5, 0xd4, 0x2a, 0xd7, 0x33, 0x20,
+	0xd3, 0x2b, 0x83, 0x32, 0x87, 0xdf, 0xc2, 0x8a, 0x7b, 0x6f, 0x1b, 0xd0,
+	0xad, 0xa7, 0x0b, 0x86, 0xe6, 0xd7, 0x39, 0x9b, 0x31, 0x13, 0xf0, 0x8a,
+	0xce, 0xa9, 0x62, 0x5f, 0xc6, 0x89, 0x06, 0x29, 0x1f, 0xed, 0x06, 0xe4,
+	0xea, 0x46, 0x9d, 0x7a, 0x2a, 0xeb, 0xcd, 0x78, 0xd8, 0xdf, 0x2d, 0x0b,
+	0xc0, 0xbb, 0x0a, 0x64, 0x67, 0xfe, 0xcd, 0x80, 0xcc, 0x15, 0x74, 0x3c,
+	0x39, 0xfc, 0x17, 0x65, 0x4b, 0xad, 0x3e, 0x21, 0xb7, 0xeb, 0x51, 0xfd,
+	0x8d, 0x72, 0x2d, 0xff, 0x0b, 0x9f, 0xbc, 0x32, 0xa2, 0xf3, 0xea, 0xa2,
+	0x15, 0x79, 0xaa, 0x9f, 0x3a, 0xcf, 0xba, 0xce, 0xb1, 0x03, 0x76, 0x40,
+	0xe7, 0x78, 0x0f, 0x3a, 0xc7, 0x6f, 0xa0, 0x73, 0xfc, 0xba, 0x04, 0x7c,
+	0x29, 0x65, 0x3c, 0xfc, 0x9f, 0x01, 0x0e, 0x51, 0x56, 0x9b, 0xe7, 0x71,
+	0xa7, 0x33, 0x39, 0xd0, 0xe0, 0x47, 0x92, 0x01, 0xde, 0x26, 0x65, 0x73,
+	0x75, 0x5a, 0xb6, 0x56, 0xdd, 0x3c, 0xe5, 0xfb, 0xcc, 0x01, 0x1b, 0xe3,
+	0x3d, 0x45, 0x81, 0x43, 0x47, 0x24, 0x72, 0x9a, 0xf8, 0xd1, 0x21, 0x6b,
+	0xc5, 0xdf, 0x69, 0x1c, 0x5a, 0x2b, 0xb2, 0xec, 0x17, 0x9d, 0x4f, 0x76,
+	0x6e, 0x47, 0x2a, 0x76, 0x03, 0xf5, 0xc7, 0xb4, 0x0f, 0xc8, 0xf5, 0xc9,
+	0x13, 0x2f, 0x3f, 0xf7, 0xee, 0x5e, 0xe9, 0x3c, 0xbb, 0x59, 0xa3, 0x1b,
+	0xed, 0x9a, 0xd8, 0x35, 0xe4, 0xc6, 0xbc, 0xd5, 0xdf, 0xd0, 0x06, 0x73,
+	0x94, 0xba, 0x65, 0x03, 0x32, 0xa4, 0x11, 0xed, 0xd6, 0xba, 0x5f, 0x23,
+	0x3a, 0xa8, 0x73, 0x77, 0x39, 0x4e, 0xbe, 0x68, 0xc9, 0x7c, 0xd1, 0x0c,
+	0xe7, 0x40, 0x7f, 0xb7, 0x61, 0xab, 0x6d, 0xe2, 0x0e, 0xb6, 0x70, 0x06,
+	0xdb, 0x75, 0xca, 0xf9, 0x2f, 0x34, 0xf6, 0xae, 0xd5, 0x3f, 0xc3, 0x38,
+	0xe6, 0xf9, 0x84, 0x3c, 0xee, 0x23, 0x06, 0xd2, 0x1f, 0x95, 0xd2, 0xfd,
+	0xdd, 0x7e, 0x9b, 0x68, 0xbb, 0x55, 0x27, 0x1e, 0x8b, 0x5c, 0x2d, 0x58,
+	0x90, 0x25, 0xbf, 0x0a, 0x51, 0x07, 0x28, 0xab, 0x66, 0x3f, 0xc7, 0x5b,
+	0xb3, 0xe3, 0x1c, 0xb5, 0xb8, 0xae, 0xa8, 0x87, 0xdb, 0x94, 0xfd, 0x3b,
+	0x5a, 0xee, 0x17, 0x4a, 0x17, 0xe4, 0x1d, 0xdc, 0xb7, 0xab, 0xe3, 0x64,
+	0xe5, 0x16, 0x74, 0xbc, 0x7a, 0xa9, 0x99, 0xd7, 0x3d, 0x89, 0x73, 0x32,
+	0xd5, 0xfc, 0xf2, 0x75, 0xb9, 0x76, 0x63, 0x57, 0xbd, 0x71, 0x23, 0xa2,
+	0xae, 0x2f, 0x0f, 0xa9, 0xfc, 0xb2, 0xe3, 0xfc, 0xd3, 0x9e, 0x95, 0x3b,
+	0xab, 0x8e, 0x9c, 0xb5, 0x7d, 0xfd, 0x7e, 0x69, 0xe6, 0xd6, 0x39, 0x4e,
+	0x07, 0xb0, 0x79, 0xfb, 0xa4, 0xe3, 0x3c, 0x3d, 0x36, 0x26, 0xd1, 0x93,
+	0xd4, 0x51, 0x9e, 0x0b, 0x31, 0x3f, 0x96, 0x98, 0x93, 0xb4, 0xac, 0xcb,
+	0x15, 0xa5, 0x80, 0x6f, 0xdd, 0xae, 0xfe, 0xf2, 0xcc, 0x31, 0x2f, 0x56,
+	0x72, 0xe7, 0x35, 0xfa, 0x92, 0x43, 0xff, 0xe5, 0x4b, 0x36, 0xe4, 0x62,
+	0x71, 0x04, 0xfd, 0x83, 0xf2, 0xc3, 0x62, 0xe0, 0x50, 0xd9, 0xc0, 0x73,
+	0x54, 0xe5, 0x8b, 0x8f, 0x9c, 0x21, 0x1d, 0x33, 0x80, 0x4e, 0x62, 0x38,
+	0xce, 0x9c, 0xcd, 0xf9, 0xba, 0x31, 0xdf, 0x8e, 0x71, 0x0c, 0xf2, 0xff,
+	0xac, 0x96, 0xcf, 0x17, 0x15, 0x6c, 0x5f, 0xf0, 0x77, 0x50, 0xd2, 0x45,
+	0xc8, 0x78, 0xc5, 0x9c, 0x53, 0xea, 0x0a, 0x66, 0x68, 0x0e, 0xd8, 0x31,
+	0x0b, 0xbc, 0x79, 0x49, 0xc7, 0x56, 0x4f, 0x68, 0xec, 0x99, 0x67, 0x39,
+	0x2b, 0x89, 0x8a, 0xdd, 0xa3, 0xcf, 0x6f, 0xf7, 0xf6, 0x2f, 0x43, 0xee,
+	0x9d, 0x83, 0x8f, 0xb3, 0x4a, 0xda, 0x60, 0x03, 0xa5, 0xd6, 0xcf, 0x81,
+	0x27, 0x42, 0x38, 0xdb, 0x56, 0xcd, 0x0f, 0x0d, 0xc8, 0xef, 0x86, 0xf6,
+	0x23, 0xba, 0xf1, 0x8a, 0x86, 0xc1, 0x76, 0x17, 0xd0, 0xaf, 0x5d, 0x92,
+	0xcb, 0x6d, 0x1a, 0x57, 0x9f, 0xac, 0x4b, 0x40, 0x0f, 0xf9, 0x3e, 0xca,
+	0x7e, 0xd4, 0x85, 0xbd, 0xb2, 0x0f, 0xe5, 0x19, 0x94, 0x5b, 0xf0, 0x64,
+	0x9b, 0x61, 0xe8, 0x15, 0x78, 0xbe, 0x8d, 0xf1, 0xc6, 0xb0, 0xe6, 0xac,
+	0x21, 0x1f, 0x9e, 0xa1, 0x2c, 0x19, 0x55, 0xcc, 0x63, 0x9e, 0xb3, 0xf0,
+	0xac, 0x0d, 0xa9, 0xd4, 0x12, 0xcb, 0x78, 0x96, 0xdd, 0xef, 0x4f, 0x60,
+	0x12, 0xfa, 0x24, 0x6f, 0xb8, 0x98, 0xf4, 0xe1, 0x1e, 0x26, 0xb1, 0xae,
+	0x5d, 0xd2, 0xcb, 0xe4, 0x75, 0x03, 0xf4, 0xd6, 0x29, 0xa9, 0x1b, 0x41,
+	0xad, 0x8f, 0x56, 0x40, 0x8b, 0x1b, 0xa0, 0xab, 0x35, 0xd0, 0x54, 0xb2,
+	0x68, 0xc6, 0x67, 0x54, 0x58, 0xfb, 0x02, 0x5e, 0x00, 0xbd, 0x76, 0xbc,
+	0x49, 0x5d, 0x94, 0xbc, 0x1c, 0x05, 0xed, 0x89, 0xd3, 0x61, 0x59, 0x99,
+	0xa8, 0xb2, 0x40, 0x83, 0xa0, 0xcb, 0xa2, 0xcb, 0xd3, 0xef, 0x2b, 0x8d,
+	0xab, 0xf1, 0x07, 0x12, 0x4b, 0x3c, 0x10, 0x13, 0x58, 0x60, 0xda, 0x1f,
+	0x88, 0x8d, 0x31, 0x27, 0xe4, 0x26, 0xe6, 0xf1, 0x81, 0xbf, 0x47, 0x4e,
+	0x69, 0xfe, 0x8e, 0x8b, 0xff, 0x30, 0x8f, 0x83, 0xde, 0x80, 0x41, 0x2e,
+	0x4f, 0x27, 0x3c, 0x1a, 0xfd, 0x26, 0xf8, 0xd7, 0x84, 0x25, 0x16, 0x94,
+	0x05, 0xf0, 0xff, 0x06, 0xbe, 0xdf, 0xad, 0x0f, 0xab, 0xf9, 0x25, 0xe5,
+	0xe5, 0x92, 0x7c, 0x07, 0x7a, 0xf2, 0x43, 0x9c, 0x5d, 0x97, 0xd6, 0xdd,
+	0x23, 0x63, 0x8c, 0x9f, 0x65, 0xd4, 0x35, 0xeb, 0xb4, 0xec, 0x8e, 0x4e,
+	0xa0, 0x7c, 0x0c, 0x4f, 0x1f, 0xce, 0x21, 0xa0, 0xe3, 0xdf, 0x6b, 0x05,
+	0x5b, 0xb9, 0xff, 0xd3, 0x30, 0x8e, 0xbe, 0xc4, 0xb2, 0x93, 0xf8, 0x4e,
+	0x5f, 0x0c, 0xf7, 0x06, 0x9d, 0x49, 0x85, 0x74, 0xbe, 0x69, 0x05, 0xba,
+	0xc4, 0x3a, 0xc6, 0xbb, 0x47, 0x5f, 0x5e, 0x0d, 0x3c, 0x3c, 0xfa, 0x2f,
+	0x27, 0x11, 0x64, 0x4e, 0xfb, 0x17, 0x21, 0x57, 0xfe, 0x7d, 0xea, 0xec,
+	0x5a, 0xf3, 0x71, 0x1f, 0x5e, 0x3e, 0x32, 0x82, 0x68, 0x0b, 0x59, 0x06,
+	0x59, 0x54, 0xd6, 0xf4, 0xcb, 0x76, 0x6e, 0xdf, 0x7c, 0x2d, 0x66, 0xdc,
+	0x17, 0xb7, 0xef, 0x82, 0x45, 0xb9, 0xd3, 0x0e, 0x7c, 0x09, 0x6b, 0xbd,
+	0xf2, 0x9e, 0x95, 0x03, 0x2a, 0x98, 0xe1, 0x0c, 0x68, 0xb4, 0x4d, 0xcc,
+	0xe8, 0x94, 0xec, 0xcf, 0x3b, 0xa7, 0xfb, 0xb2, 0x6d, 0xb3, 0x6f, 0x73,
+	0x5e, 0xae, 0x9f, 0x7b, 0xe1, 0x1e, 0xe8, 0x9b, 0x36, 0x34, 0x8d, 0x36,
+	0x6a, 0x03, 0xfd, 0x2e, 0x8d, 0x36, 0xf7, 0x11, 0xfc, 0x3f, 0xfb, 0x20,
+	0x9d, 0xd8, 0xca, 0x8d, 0xd3, 0xe3, 0x59, 0xe3, 0x79, 0x0e, 0x83, 0x36,
+	0x0e, 0xd2, 0x4f, 0xd3, 0xb7, 0xe8, 0xd2, 0xcf, 0xd3, 0x7b, 0xf4, 0x43,
+	0xba, 0xe9, 0x94, 0xf4, 0x0d, 0x4b, 0xa6, 0x8b, 0xfa, 0xbe, 0xa1, 0x6b,
+	0xd2, 0x67, 0x34, 0x01, 0xba, 0x21, 0xad, 0x93, 0xb7, 0x0c, 0x29, 0x83,
+	0x8e, 0xca, 0xc0, 0xa7, 0x32, 0x68, 0xaa, 0x02, 0x7c, 0x2b, 0x03, 0xdf,
+	0xca, 0x75, 0x33, 0x5a, 0xc5, 0x9e, 0x29, 0xb3, 0xd7, 0x41, 0x47, 0x1b,
+	0x75, 0xde, 0xbf, 0x5e, 0xb3, 0x41, 0x39, 0x78, 0x77, 0xef, 0xee, 0xff,
+	0x81, 0xbb, 0x1f, 0x94, 0xdb, 0xb0, 0x5b, 0xde, 0x29, 0x8d, 0x02, 0x93,
+	0x04, 0x18, 0x65, 0x83, 0x36, 0xe2, 0xb2, 0x59, 0x9a, 0x94, 0x2d, 0xc8,
+	0xa7, 0xed, 0xd5, 0x08, 0xf4, 0xe9, 0x90, 0xcc, 0xbf, 0x35, 0x22, 0xb7,
+	0x56, 0x95, 0xcc, 0x82, 0x7e, 0xf3, 0x6b, 0xf4, 0xbb, 0x83, 0x9e, 0xcb,
+	0x9d, 0x3a, 0x4e, 0x9f, 0xae, 0xba, 0xfe, 0xf7, 0xa9, 0x6a, 0x97, 0x4c,
+	0x57, 0x0d, 0x79, 0xbe, 0xda, 0x23, 0x2f, 0x56, 0x83, 0x72, 0x16, 0x76,
+	0xe0, 0xd7, 0xaa, 0x03, 0xf2, 0x52, 0x75, 0x50, 0xbe, 0x5e, 0x0b, 0xcb,
+	0x37, 0x6a, 0x96, 0x64, 0x6b, 0x51, 0xc9, 0xd4, 0x46, 0xe5, 0x85, 0x1a,
+	0xfd, 0xea, 0x98, 0x0f, 0xbf, 0xd4, 0x9e, 0xbf, 0x82, 0xeb, 0xea, 0xc0,
+	0xba, 0xa2, 0x6a, 0x4a, 0xc7, 0x29, 0x25, 0xeb, 0xfa, 0x3c, 0x44, 0x2e,
+	0x61, 0xac, 0xc5, 0xb7, 0x94, 0x54, 0xf4, 0xfc, 0xcd, 0xff, 0x33, 0x09,
+	0x68, 0xdb, 0xe8, 0x52, 0x79, 0x00, 0x6d, 0x20, 0xf7, 0x0a, 0x4d, 0xdf,
+	0x47, 0xd3, 0xe7, 0xdf, 0xb4, 0xbd, 0x7c, 0xda, 0x6f, 0x7d, 0x97, 0xb6,
+	0x97, 0x3e, 0x7b, 0xe2, 0x07, 0xed, 0x9c, 0x9b, 0xda, 0x6f, 0xb2, 0x1f,
+	0xdb, 0x68, 0xce, 0xbb, 0x98, 0x7d, 0xf2, 0xff, 0x59, 0xdc, 0x18, 0xd5,
+	0xc5, 0xda, 0x00, 0xff, 0xaf, 0x05, 0x6b, 0xf9, 0xf2, 0xdc, 0xf1, 0xe9,
+	0x52, 0x5a, 0x3d, 0x5f, 0xa2, 0x46, 0xe3, 0xc8, 0xe2, 0x5e, 0x4e, 0xdc,
+	0x73, 0xb2, 0x66, 0x07, 0xf4, 0x1a, 0x5c, 0x5f, 0x7d, 0x42, 0xe7, 0xc7,
+	0xa5, 0x4f, 0x91, 0xfe, 0x18, 0x7b, 0xeb, 0xf2, 0xe2, 0x09, 0xd0, 0x6d,
+	0x6d, 0x43, 0xae, 0x56, 0x5d, 0x9f, 0xd5, 0xbc, 0xa6, 0x97, 0x7b, 0xa0,
+	0x39, 0xc6, 0x1c, 0xdc, 0x67, 0xae, 0xec, 0xf6, 0x4d, 0xe1, 0xde, 0x60,
+	0x8f, 0x63, 0xbf, 0xbe, 0x1e, 0xce, 0xc5, 0xff, 0xe3, 0x41, 0xd9, 0x5b,
+	0x2f, 0x73, 0x8d, 0x2d, 0x4d, 0x8b, 0x6e, 0x5c, 0x37, 0x2a, 0xaf, 0xe2,
+	0xfc, 0x2a, 0x06, 0xd7, 0xdf, 0x21, 0x95, 0x28, 0x6d, 0x5b, 0xe2, 0xf7,
+	0x29, 0x29, 0x63, 0x9e, 0x4a, 0xb4, 0xe9, 0x0f, 0x73, 0x71, 0xb6, 0x62,
+	0xec, 0xcf, 0x3b, 0x53, 0x3e, 0x8e, 0x77, 0xd4, 0x45, 0xa1, 0x33, 0x9d,
+	0xe3, 0xfb, 0x22, 0xca, 0xf4, 0x8d, 0xcc, 0xe3, 0x19, 0xf2, 0xea, 0xde,
+	0xeb, 0xd7, 0xba, 0xfa, 0xe4, 0x7e, 0xbf, 0xd9, 0xb2, 0x99, 0x4b, 0xfa,
+	0x63, 0xca, 0xf7, 0xf3, 0xdf, 0xf7, 0x13, 0x73, 0x8f, 0x5b, 0xfc, 0x05,
+	0xe4, 0x33, 0x43, 0xfb, 0x14, 0xbc, 0x6f, 0x47, 0xe4, 0x65, 0x83, 0x79,
+	0xec, 0x09, 0x95, 0x2e, 0x5d, 0xf7, 0x72, 0x7c, 0x63, 0xea, 0x78, 0xe5,
+	0x7e, 0xbf, 0x9b, 0xf3, 0xce, 0xb1, 0x0f, 0xe6, 0xb9, 0x1f, 0xa4, 0x13,
+	0xe6, 0xbb, 0xb7, 0xef, 0xfd, 0x0f, 0x55, 0xa5, 0x00, 0xbc, 0xb3, 0x5a,
+	0x34, 0x3f, 0xe6, 0x6b, 0xff, 0x76, 0x76, 0x34, 0x3f, 0x37, 0x7d, 0x0c,
+	0x7f, 0xee, 0xa7, 0x6d, 0x4b, 0xdc, 0xb8, 0xea, 0xe6, 0x8e, 0x6a, 0x1b,
+	0x1a, 0x58, 0x81, 0x3a, 0xf2, 0x2a, 0xf8, 0x64, 0xaf, 0x2d, 0xff, 0xfe,
+	0x03, 0x9a, 0xb8, 0x8a, 0x6c, 0x8c, 0x67, 0x00, 0x00, 0x00 };
 
 static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 };
 static const u32 bnx2_RXP_b09FwRodata[(0x278/4) + 1] = {
-	0x08004050, 0x08003f50, 0x08003ff4, 0x0800400c, 0x08004024, 0x08004044,
-	0x08004050, 0x08004050, 0x08003f58, 0x00000000, 0x08004a0c, 0x08004a44,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004a7c, 0x08004c40,
-	0x08004b88, 0x08004bc0, 0x08004c40, 0x08004b10, 0x08004c40, 0x08004c40,
-	0x08004bc0, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c00,
-	0x08004c40, 0x08004c00, 0x08004b88, 0x08004c40, 0x08004c40, 0x08004c00,
-	0x08004c00, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
-	0x08004aec, 0x00000000, 0x08006058, 0x08006070, 0x08006070, 0x08006070,
-	0x08006058, 0x08006070, 0x08006070, 0x08006070, 0x08006058, 0x08006070,
-	0x08006070, 0x08006070, 0x08006058, 0x08006070, 0x08006070, 0x08006070,
-	0x08006064, 0x00000000, 0x00000000 };
+	0x08004070, 0x08003f70, 0x08004014, 0x0800402c, 0x08004044, 0x08004064,
+	0x08004070, 0x08004070, 0x08003f78, 0x00000000, 0x08004a2c, 0x08004a64,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004a9c, 0x08004c60,
+	0x08004ba8, 0x08004be0, 0x08004c60, 0x08004b30, 0x08004c60, 0x08004c60,
+	0x08004be0, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c20,
+	0x08004c60, 0x08004c20, 0x08004ba8, 0x08004c60, 0x08004c60, 0x08004c20,
+	0x08004c20, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+	0x08004b0c, 0x00000000, 0x08006078, 0x08006090, 0x08006090, 0x08006090,
+	0x08006078, 0x08006090, 0x08006090, 0x08006090, 0x08006078, 0x08006090,
+	0x08006090, 0x08006090, 0x08006078, 0x08006090, 0x08006090, 0x08006090,
+	0x08006084, 0x00000000, 0x00000000 };
 
 static struct fw_info bnx2_rxp_fw_09 = {
+	/* Firmware version:  3.7.1 */
 	.ver_major			= 0x3,
-	.ver_minor			= 0x4,
-	.ver_fix			= 0x3,
+	.ver_minor			= 0x7,
+	.ver_fix			= 0x1,
 
 	.start_addr			= 0x08003184,
 
 	.text_addr			= 0x08000000,
-	.text_len			= 0x6768,
+	.text_len			= 0x6788,
 	.text_index			= 0x0,
 	.gz_text			= bnx2_RXP_b09FwText,
 	.gz_text_len			= sizeof(bnx2_RXP_b09FwText),
 
-	.data_addr			= 0x08006a00,
+	.data_addr			= 0x08006a20,
 	.data_len			= 0x0,
 	.data_index			= 0x0,
 	.data				= bnx2_RXP_b09FwData,
 
-	.sbss_addr			= 0x08006a00,
+	.sbss_addr			= 0x08006a20,
 	.sbss_len			= 0x20,
 	.sbss_index			= 0x0,
 
-	.bss_addr			= 0x08006a20,
+	.bss_addr			= 0x08006a40,
 	.bss_len			= 0x13dc,
 	.bss_index			= 0x0,
 
-	.rodata_addr			= 0x08006768,
+	.rodata_addr			= 0x08006788,
 	.rodata_len			= 0x278,
 	.rodata_index			= 0x0,
 	.rodata				= bnx2_RXP_b09FwRodata,
 };
 
 static u8 bnx2_TPAT_b09FwText[] = {
-/*	0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
-								    0xcd, 0x58,
-	0x5d, 0x68, 0x1c, 0xd7, 0x15, 0x3e, 0xf3, 0xb7, 0x3b, 0x52, 0x24, 0xeb,
-	0x5a, 0xd9, 0xa6, 0xeb, 0xa0, 0x34, 0x33, 0xda, 0x91, 0xac, 0x22, 0x13,
-	0x4f, 0x9d, 0x25, 0x16, 0x65, 0x21, 0x93, 0xd9, 0x91, 0xac, 0x98, 0x3c,
-	0x28, 0xc5, 0x90, 0x87, 0x52, 0x50, 0x57, 0x32, 0x09, 0x79, 0x69, 0xda,
-	0xc6, 0x90, 0x3e, 0x79, 0x3b, 0x2b, 0xc7, 0x0e, 0x6c, 0xbc, 0x8d, 0x52,
-	0xe4, 0x52, 0xfa, 0x60, 0xd6, 0xb1, 0x05, 0xcd, 0x46, 0x93, 0xd4, 0x7e,
-	0x35, 0x36, 0x4e, 0x93, 0xa7, 0x42, 0x9f, 0x52, 0xf4, 0x18, 0xd2, 0x12,
-	0xda, 0x52, 0x8a, 0x69, 0xa1, 0x09, 0x8d, 0xeb, 0xdb, 0xef, 0xdc, 0x99,
-	0x91, 0x57, 0xb6, 0xec, 0xa4, 0x25, 0x85, 0x0a, 0x56, 0x77, 0xe6, 0xce,
-	0x3d, 0xe7, 0x9e, 0x7b, 0xee, 0x77, 0xbe, 0x73, 0xee, 0x2d, 0xeb, 0x34,
-	0x48, 0xd9, 0xdf, 0x30, 0x7e, 0x2f, 0x7e, 0xf7, 0x85, 0x17, 0xab, 0x8f,
-	0x3c, 0xea, 0x10, 0x3d, 0xfa, 0x88, 0x66, 0x98, 0x06, 0x7d, 0x09, 0x7f,
-	0x50, 0x22, 0x72, 0xfd, 0xfc, 0x23, 0x5b, 0xaf, 0x9d, 0x72, 0x42, 0x8f,
-	0x6c, 0xa3, 0x26, 0xbe, 0xbe, 0xe4, 0x11, 0x05, 0xbd, 0x69, 0xa7, 0x4e,
-	0xff, 0x92, 0xcd, 0x92, 0x49, 0xdc, 0xff, 0x50, 0xed, 0xc6, 0xfe, 0xcb,
-	0x07, 0xdd, 0xeb, 0x67, 0x0d, 0xb2, 0x45, 0x6d, 0xd1, 0x16, 0x93, 0x64,
-	0x8f, 0xd5, 0x9a, 0xce, 0x2f, 0xf6, 0x1e, 0x28, 0xd0, 0xae, 0x5c, 0x97,
-	0xa0, 0xb8, 0x43, 0x4d, 0xab, 0x66, 0x53, 0xd4, 0x7e, 0x49, 0x0b, 0x3b,
-	0x9e, 0x98, 0x85, 0x8e, 0xa0, 0x04, 0xfd, 0x1e, 0xde, 0x13, 0x53, 0x8b,
-	0xce, 0xd8, 0xa4, 0xd7, 0x02, 0x3c, 0x4f, 0x51, 0xab, 0x23, 0xe5, 0x2b,
-	0xbe, 0x46, 0x4b, 0xbe, 0x4d, 0x8b, 0xc2, 0x0d, 0x1c, 0xed, 0xa6, 0xac,
-	0x4c, 0x48, 0xf9, 0x9c, 0xaf, 0x93, 0xee, 0xcd, 0x69, 0xe1, 0xfa, 0xbc,
-	0x56, 0x5f, 0x9f, 0x67, 0x7f, 0xc0, 0xbe, 0x39, 0x2d, 0x58, 0xe7, 0xb6,
-	0x66, 0xd7, 0xdb, 0xbb, 0x68, 0xb1, 0x44, 0x23, 0xba, 0x37, 0x85, 0xf9,
-	0x4a, 0xd0, 0xe3, 0x50, 0xe8, 0x4f, 0x0b, 0x9d, 0x2a, 0xf8, 0x0d, 0xd0,
-	0xac, 0x4f, 0x03, 0xba, 0xa7, 0x53, 0xa3, 0xa4, 0xd1, 0x1b, 0x55, 0x0b,
-	0xbf, 0xc3, 0x5a, 0xb4, 0xfe, 0x7c, 0xa6, 0x87, 0xc7, 0xdb, 0xf8, 0xc6,
-	0x36, 0xb3, 0x7c, 0xbf, 0xec, 0x30, 0x9e, 0x9f, 0xc3, 0x38, 0x8b, 0xc2,
-	0xea, 0xed, 0xdf, 0x06, 0xf0, 0xac, 0xa1, 0xff, 0x30, 0xec, 0x62, 0x3d,
-	0x0e, 0xec, 0x28, 0xd3, 0x4a, 0x67, 0x1e, 0xeb, 0x29, 0x50, 0x53, 0x4c,
-	0x4c, 0x35, 0xc8, 0x84, 0x8c, 0x41, 0x41, 0xe9, 0x8a, 0xd4, 0x6b, 0x52,
-	0x86, 0x55, 0x6f, 0xaa, 0xab, 0xe6, 0xd0, 0xc9, 0xf0, 0x0a, 0x14, 0xf9,
-	0xc3, 0xd4, 0x12, 0x06, 0xc5, 0xfb, 0x2c, 0x0a, 0x16, 0x4c, 0xac, 0x71,
-	0x14, 0x72, 0x1a, 0xe4, 0x5f, 0xcb, 0xf6, 0xbc, 0x48, 0xb1, 0x28, 0xa0,
-	0x7f, 0x84, 0xe2, 0xd2, 0x6e, 0x4d, 0xaf, 0xbd, 0x82, 0xfe, 0x09, 0xd1,
-	0xa5, 0x53, 0x68, 0x35, 0xbc, 0xef, 0xc6, 0x58, 0x7e, 0xd7, 0xa0, 0x8f,
-	0x44, 0x98, 0x78, 0xd4, 0x4a, 0x72, 0x59, 0xee, 0x4f, 0xfb, 0x9a, 0xc9,
-	0xed, 0xfb, 0xed, 0xc1, 0x4e, 0x41, 0x27, 0x3a, 0xb3, 0x98, 0x8f, 0x9a,
-	0x46, 0x0d, 0xe3, 0xb0, 0x37, 0xbc, 0xbf, 0x81, 0xc2, 0xc1, 0xe3, 0xdc,
-	0xcf, 0x7f, 0xe8, 0x77, 0xc8, 0xa8, 0xf1, 0xb7, 0x6f, 0x52, 0xfa, 0x2d,
-	0xb5, 0x3f, 0xf4, 0x1f, 0xcb, 0xde, 0x4b, 0x22, 0x3c, 0xf3, 0x28, 0xd6,
-	0xa8, 0x60, 0x83, 0xe7, 0x02, 0xf0, 0x11, 0xcf, 0xe8, 0xd4, 0x2c, 0x17,
-	0xc9, 0xf5, 0x8f, 0xa2, 0xf7, 0xd7, 0x6d, 0x83, 0xea, 0xec, 0x2b, 0xdf,
-	0xcc, 0x64, 0x18, 0x1b, 0x1f, 0x64, 0x76, 0x0a, 0x5a, 0x3c, 0x22, 0xe5,
-	0x8a, 0x2f, 0xa5, 0x55, 0xf3, 0x9c, 0x13, 0x34, 0x5d, 0x36, 0x69, 0x52,
-	0xa0, 0x85, 0x8f, 0xbd, 0x72, 0x83, 0x2c, 0x60, 0xa1, 0x1f, 0xff, 0xfc,
-	0xf7, 0xa6, 0x86, 0x25, 0xd0, 0xb5, 0x36, 0xeb, 0x98, 0x70, 0x66, 0x95,
-	0x8c, 0x94, 0xf1, 0xcc, 0xbd, 0x64, 0x2e, 0x65, 0x32, 0x52, 0x46, 0x55,
-	0x81, 0x3d, 0x6f, 0x0a, 0xd8, 0x87, 0x75, 0x31, 0xc6, 0x89, 0xa2, 0x9e,
-	0x6f, 0x37, 0xda, 0xb0, 0xd1, 0x43, 0xdb, 0x13, 0xf0, 0x0f, 0x51, 0x0b,
-	0x63, 0xf5, 0xea, 0x7d, 0x8c, 0x0d, 0xec, 0xef, 0x82, 0x1d, 0xb5, 0xdd,
-	0xf2, 0x29, 0x5a, 0xb0, 0xeb, 0xbd, 0xe9, 0xf2, 0x32, 0x3d, 0xc4, 0x73,
-	0xd8, 0x56, 0xed, 0x88, 0xdd, 0x55, 0x72, 0x88, 0xc4, 0x41, 0x3c, 0xf7,
-	0x88, 0xe2, 0x36, 0x69, 0xa1, 0x7f, 0x1f, 0xaf, 0x15, 0x72, 0xf3, 0x99,
-	0xdc, 0x7c, 0x26, 0x37, 0x92, 0xc9, 0x3d, 0xd5, 0x27, 0xf7, 0x14, 0xcb,
-	0x61, 0x6c, 0x90, 0x8d, 0x0d, 0xb2, 0xb1, 0x66, 0x36, 0x36, 0xca, 0xc6,
-	0xa2, 0xed, 0x8d, 0xc1, 0x36, 0x77, 0xca, 0xd1, 0x6c, 0x8a, 0x3d, 0xf9,
-	0x70, 0xe8, 0x53, 0x50, 0xf7, 0xdc, 0xcd, 0xba, 0x31, 0x42, 0xe7, 0xfc,
-	0x21, 0x5a, 0x49, 0xc6, 0x28, 0x4e, 0x56, 0x28, 0x4c, 0x74, 0xc8, 0x8e,
-	0x50, 0xd7, 0xbb, 0x2e, 0x67, 0x7d, 0x1f, 0x7b, 0x66, 0xb3, 0x5c, 0x79,
-	0x96, 0x1c, 0x7c, 0x9f, 0x16, 0xcb, 0xe4, 0x03, 0x2b, 0x3a, 0xf6, 0xad,
-	0xa2, 0x9e, 0xe3, 0xc4, 0xe7, 0x35, 0x37, 0xf5, 0xaa, 0x2b, 0x62, 0x72,
-	0xcb, 0xa1, 0x41, 0x42, 0xaf, 0xc1, 0x4f, 0x49, 0x93, 0xa2, 0xc4, 0xa6,
-	0x0f, 0x8d, 0x97, 0x54, 0x8c, 0xc6, 0x9d, 0x4d, 0x79, 0x79, 0xaf, 0x43,
-	0x57, 0x30, 0xcf, 0xc5, 0xa4, 0x4c, 0xbf, 0x4a, 0x4a, 0xf4, 0x4e, 0x42,
-	0x7a, 0xe8, 0x03, 0xc3, 0x25, 0x41, 0x6f, 0x27, 0xfd, 0x3e, 0xff, 0x88,
-	0x7d, 0x6e, 0xdf, 0x5f, 0x23, 0x7b, 0xb4, 0xc6, 0x38, 0x4b, 0x39, 0xa0,
-	0x9e, 0x72, 0x80, 0xc2, 0x52, 0xab, 0x13, 0x3f, 0x68, 0x80, 0x7f, 0x96,
-	0xfc, 0x60, 0xb7, 0xa1, 0xf6, 0xa3, 0x89, 0x3d, 0xcc, 0x5b, 0xde, 0x9b,
-	0xab, 0xce, 0x92, 0xe7, 0x9e, 0xaa, 0x33, 0x6a, 0x4f, 0x5b, 0x39, 0x2e,
-	0xfb, 0xe6, 0xf8, 0x33, 0xe6, 0x18, 0xa2, 0x06, 0xe2, 0xec, 0x09, 0x13,
-	0xb1, 0xe3, 0xfd, 0xdd, 0x60, 0x5c, 0x39, 0x1b, 0x8c, 0x6f, 0xa2, 0xf1,
-	0x0d, 0x9b, 0xd6, 0xdb, 0x45, 0x72, 0xba, 0x43, 0xb4, 0xd4, 0x19, 0xa4,
-	0xca, 0x05, 0x13, 0x63, 0xef, 0xa3, 0xca, 0xaa, 0x5e, 0xe2, 0x38, 0xae,
-	0xc3, 0xc7, 0xe3, 0x5d, 0x09, 0x7c, 0x0e, 0xd2, 0xf8, 0x9a, 0xab, 0xb0,
-	0xb3, 0xe4, 0xb5, 0x7c, 0x83, 0x7e, 0x4c, 0xd7, 0xf6, 0x15, 0xb0, 0xa6,
-	0x12, 0xf9, 0x93, 0xfd, 0xf3, 0xe9, 0x80, 0x18, 0xf7, 0xc5, 0x45, 0xda,
-	0xe5, 0x3a, 0xa4, 0xb3, 0x3e, 0x9b, 0xc6, 0x2f, 0xd8, 0x5a, 0xbd, 0xc3,
-	0x3e, 0x63, 0xfc, 0xd9, 0x19, 0xfe, 0x4c, 0x2d, 0x3c, 0x53, 0xc4, 0x5c,
-	0x7f, 0x91, 0xa1, 0x27, 0xb1, 0x0f, 0x3a, 0x2d, 0x55, 0x7f, 0x04, 0xfb,
-	0xd0, 0xd7, 0xe5, 0x6f, 0xd7, 0xb3, 0x7e, 0xd6, 0x01, 0x7e, 0xf0, 0xef,
-	0xa7, 0x90, 0xb9, 0xe0, 0x08, 0xcb, 0x14, 0x69, 0x7c, 0x95, 0xf9, 0x05,
-	0x6d, 0x97, 0xdf, 0x79, 0x6d, 0x03, 0xd4, 0x80, 0x57, 0x1a, 0x53, 0x25,
-	0xd8, 0xa5, 0x2b, 0xbe, 0x68, 0x80, 0x3f, 0x74, 0x6f, 0x10, 0x2d, 0xcf,
-	0xf7, 0x73, 0x23, 0x8f, 0xa9, 0xb8, 0x33, 0x44, 0x75, 0xe0, 0xd7, 0x84,
-	0x3d, 0xcb, 0x34, 0x51, 0x3e, 0xaa, 0xbe, 0xa1, 0xaf, 0xc7, 0xdf, 0xc4,
-	0x6d, 0xdf, 0xf0, 0xde, 0xcb, 0x6d, 0x40, 0x6c, 0x7b, 0x2d, 0xcc, 0x62,
-	0x65, 0x7e, 0xe1, 0xf1, 0xcd, 0x32, 0xf6, 0x06, 0x7c, 0x46, 0xf0, 0x25,
-	0x51, 0xb7, 0x6d, 0x82, 0x6f, 0xf4, 0xaf, 0xea, 0x2c, 0x57, 0x62, 0x3d,
-	0x58, 0xff, 0x9a, 0xa9, 0xd5, 0xcf, 0x78, 0xce, 0x1f, 0x88, 0xe5, 0x2b,
-	0xf0, 0xc1, 0xc4, 0x4c, 0x8b, 0xc7, 0xf7, 0x2c, 0xf2, 0x56, 0x9b, 0xc2,
-	0xc4, 0x9e, 0xc2, 0x73, 0x54, 0xff, 0xc9, 0x08, 0xf6, 0xda, 0x75, 0x5a,
-	0xf4, 0x5b, 0xd8, 0x53, 0x20, 0xaf, 0x6b, 0xd2, 0x1b, 0x6d, 0xf6, 0x85,
-	0x4d, 0x95, 0x35, 0x29, 0x4f, 0xfa, 0xbc, 0x27, 0xbf, 0x83, 0x5f, 0x08,
-	0x2b, 0x9c, 0x98, 0xf9, 0x08, 0xfb, 0xb3, 0xde, 0xe3, 0xbd, 0xb1, 0x94,
-	0x4f, 0xbc, 0xd5, 0x29, 0xec, 0xeb, 0x54, 0x66, 0x23, 0xef, 0x97, 0x49,
-	0x2b, 0x55, 0x9d, 0xce, 0x57, 0x3f, 0x93, 0xba, 0xc7, 0xfc, 0x5a, 0x80,
-	0x6f, 0x31, 0xae, 0x8b, 0x71, 0x49, 0x01, 0x3e, 0xfc, 0x07, 0x78, 0x45,
-	0xca, 0xf3, 0x55, 0xf4, 0xaf, 0x1e, 0x87, 0xad, 0x06, 0x64, 0x53, 0x8c,
-	0xb1, 0x3d, 0x73, 0xed, 0x7c, 0x7d, 0xde, 0xcc, 0x7b, 0x4a, 0xdf, 0x10,
-	0x4d, 0x6e, 0x0c, 0xd1, 0xb3, 0xbd, 0x21, 0x1a, 0x3f, 0xcd, 0x32, 0xe0,
-	0xa6, 0xaa, 0x27, 0x22, 0xc6, 0xa8, 0xa7, 0xfc, 0x50, 0x36, 0x74, 0x5e,
-	0x27, 0xbe, 0x6f, 0x10, 0x2d, 0xf7, 0x78, 0x0e, 0xb3, 0x4f, 0xa7, 0x4e,
-	0x87, 0x7e, 0x4a, 0x74, 0xa8, 0xc7, 0xb2, 0x5b, 0xbe, 0x83, 0x5e, 0x01,
-	0x9d, 0x82, 0x38, 0x0f, 0x19, 0x1e, 0xf2, 0xdd, 0x7a, 0x88, 0xfc, 0x15,
-	0xe1, 0x37, 0x87, 0x9c, 0xc6, 0xeb, 0x9f, 0x42, 0xfc, 0x31, 0x8f, 0xdf,
-	0xc4, 0xda, 0x0b, 0xb4, 0xe2, 0xcf, 0x63, 0x0c, 0xef, 0xf1, 0x61, 0x7c,
-	0x1f, 0x46, 0x1e, 0xc8, 0xf2, 0x84, 0xe0, 0x3c, 0xb1, 0x1b, 0x71, 0x30,
-	0x00, 0xee, 0xdf, 0x63, 0x6e, 0xcf, 0x13, 0x18, 0x57, 0xda, 0x83, 0xbc,
-	0x70, 0x3f, 0xfa, 0x59, 0xd7, 0x28, 0xda, 0x01, 0xbc, 0xef, 0xc1, 0xd8,
-	0xfe, 0x1c, 0x91, 0xcb, 0xdd, 0x2d, 0x3f, 0x20, 0x26, 0x56, 0x11, 0x2b,
-	0x6b, 0x9c, 0x27, 0x38, 0x16, 0x79, 0x4f, 0x8b, 0xe0, 0x6f, 0x1b, 0x3a,
-	0x78, 0x6f, 0x8b, 0xd8, 0x43, 0xce, 0x71, 0x82, 0x2a, 0x1b, 0x3b, 0xe5,
-	0x0f, 0x5e, 0x0f, 0x38, 0xec, 0x34, 0xaf, 0xc5, 0x15, 0x0d, 0xf0, 0x59,
-	0xb8, 0x31, 0x8d, 0xef, 0xc8, 0x85, 0x22, 0xb2, 0x1b, 0xa7, 0x53, 0x2e,
-	0x6b, 0x6c, 0x8c, 0x29, 0x9c, 0xc6, 0x89, 0xc0, 0x3b, 0x73, 0x59, 0xce,
-	0x5d, 0x8c, 0x25, 0x0a, 0x20, 0xbb, 0x19, 0x1a, 0x52, 0x2e, 0xf9, 0x23,
-	0xd4, 0x00, 0x2e, 0x03, 0xf0, 0x59, 0x03, 0x7c, 0x56, 0xef, 0xe3, 0xb3,
-	0xfa, 0xe7, 0xf2, 0x19, 0xb8, 0xaa, 0x03, 0xae, 0xea, 0x80, 0xab, 0x50,
-	0x1b, 0xbc, 0x03, 0xec, 0xbf, 0xdd, 0xd9, 0x89, 0xe3, 0x98, 0xdf, 0x98,
-	0xe7, 0xa6, 0xe8, 0xf2, 0xde, 0xff, 0x94, 0xe7, 0x8e, 0x83, 0x13, 0x6c,
-	0xfa, 0xfe, 0xde, 0x7b, 0x73, 0xdd, 0x09, 0x70, 0x9d, 0xf5, 0xf9, 0x5c,
-	0xd7, 0x64, 0xae, 0x33, 0x81, 0xbd, 0x26, 0x78, 0x40, 0x5f, 0xed, 0x9f,
-	0xe7, 0x24, 0xe6, 0xe1, 0x3e, 0x33, 0xcb, 0xa5, 0x3a, 0x75, 0x81, 0x7b,
-	0xc3, 0xe3, 0x79, 0x60, 0x73, 0x92, 0x72, 0xd1, 0x13, 0x66, 0x89, 0xac,
-	0x49, 0xe0, 0x61, 0x75, 0x88, 0x8c, 0xd3, 0xb7, 0xf0, 0x8e, 0x7a, 0x00,
-	0x71, 0x8e, 0x7f, 0x1b, 0xb9, 0x8e, 0x41, 0x70, 0x8d, 0x49, 0x85, 0x55,
-	0x0b, 0xef, 0xda, 0xb6, 0x71, 0x87, 0x90, 0x6f, 0x8c, 0x9a, 0x3b, 0xf3,
-	0x7b, 0x7e, 0xee, 0xf1, 0x98, 0x41, 0xd2, 0xd7, 0x5c, 0xc7, 0xd1, 0x5d,
-	0xff, 0x1a, 0xb8, 0xe1, 0x7d, 0x8f, 0xf9, 0x2f, 0x06, 0x0a, 0x0a, 0x64,
-	0xae, 0xca, 0xe3, 0x56, 0x8d, 0xe7, 0x6e, 0x3a, 0x88, 0x73, 0xe7, 0x35,
-	0xe0, 0x87, 0x73, 0xe7, 0xf9, 0x2a, 0xd7, 0x7b, 0x69, 0x8c, 0xb6, 0x7a,
-	0xf9, 0x9c, 0xa3, 0xb0, 0xdb, 0x82, 0x4c, 0xff, 0x58, 0xc6, 0x8b, 0x94,
-	0xcf, 0x62, 0x4d, 0x06, 0xe6, 0xb1, 0xd6, 0x6c, 0x2a, 0xac, 0xb1, 0x5f,
-	0x5c, 0xc8, 0x57, 0xc4, 0x1c, 0x6d, 0x6e, 0xe3, 0x83, 0x93, 0xbd, 0x0f,
-	0x4c, 0xe6, 0x50, 0x03, 0xb1, 0x59, 0xc4, 0xbc, 0xd6, 0x96, 0x2e, 0xca,
-	0x74, 0xb1, 0xbc, 0x57, 0x7e, 0x76, 0x4b, 0x9e, 0x79, 0x6d, 0xa2, 0xcc,
-	0xfc, 0xc5, 0x76, 0x18, 0x8a, 0x4b, 0x07, 0x33, 0x2e, 0xad, 0x60, 0x3f,
-	0x07, 0x55, 0x5c, 0xea, 0xde, 0xc3, 0x19, 0x9f, 0xee, 0x46, 0xcb, 0x7d,
-	0x37, 0xb2, 0x38, 0x31, 0x61, 0x2f, 0xeb, 0x1d, 0x24, 0x03, 0x76, 0x45,
-	0x6a, 0x4d, 0x7f, 0x93, 0x4b, 0x1e, 0x73, 0x04, 0xe3, 0x53, 0x71, 0x29,
-	0xfa, 0x27, 0x60, 0x33, 0xf3, 0x02, 0xcb, 0xb1, 0xfc, 0x4e, 0x72, 0x7f,
-	0x85, 0x9c, 0xd8, 0x41, 0x0e, 0x7d, 0x1b, 0x2c, 0xc3, 0xdc, 0x30, 0x8a,
-	0xf1, 0x21, 0xf3, 0x02, 0x7c, 0xc6, 0xb2, 0xe5, 0x2c, 0x0e, 0x23, 0x7c,
-	0xe3, 0xba, 0x97, 0xe3, 0x23, 0x20, 0xab, 0xc6, 0xeb, 0xe0, 0x9a, 0x98,
-	0xf3, 0x22, 0xd7, 0xa1, 0x5c, 0x6f, 0xe6, 0xf5, 0xa9, 0x37, 0x35, 0x7b,
-	0xb7, 0x5a, 0x53, 0xf4, 0xd7, 0x9a, 0xe8, 0xd8, 0xb1, 0xd6, 0xf4, 0xac,
-	0xb4, 0xd6, 0xac, 0x58, 0x77, 0xaf, 0x35, 0x73, 0xd9, 0x7b, 0xd7, 0x9a,
-	0x71, 0x87, 0xf7, 0x08, 0xb9, 0x54, 0xf0, 0x5a, 0xa8, 0x69, 0x66, 0x7c,
-	0x11, 0xdd, 0xc6, 0x17, 0xd1, 0x69, 0xb7, 0x7c, 0x8e, 0x38, 0xa6, 0xdd,
-	0x72, 0x8b, 0x6b, 0xa0, 0x0d, 0xae, 0x81, 0x0c, 0xe4, 0xd2, 0x7e, 0xce,
-	0xc8, 0x7d, 0xc2, 0xbe, 0x1c, 0x04, 0x27, 0xb3, 0x1f, 0x8b, 0x19, 0x3f,
-	0xa0, 0xf5, 0x3e, 0x05, 0x3f, 0xe4, 0xbc, 0xc2, 0x3e, 0xfb, 0x7f, 0xe2,
-	0x15, 0xb2, 0x07, 0xc0, 0x0f, 0x36, 0xea, 0xcd, 0x46, 0x47, 0xd9, 0x02,
-	0x5f, 0x48, 0x39, 0xe7, 0x33, 0xf6, 0x53, 0xbe, 0x50, 0x3e, 0x51, 0x78,
-	0x2c, 0xd2, 0xbb, 0x3e, 0x63, 0x01, 0xe7, 0x23, 0x8f, 0x73, 0x22, 0xf3,
-	0xef, 0x4d, 0xf9, 0xae, 0x17, 0xa2, 0x2f, 0xc2, 0x9e, 0x33, 0x0e, 0xe6,
-	0xb5, 0x43, 0xeb, 0x36, 0xe4, 0x18, 0x0b, 0xe5, 0x3b, 0xce, 0x3d, 0xe9,
-	0xf9, 0x84, 0x6b, 0xe1, 0xff, 0x16, 0x1b, 0x17, 0xef, 0x82, 0x8d, 0x37,
-	0x33, 0x6c, 0xfc, 0xf2, 0x1e, 0xd8, 0xb8, 0xf8, 0x05, 0xb1, 0xe1, 0x3a,
-	0x1f, 0xa3, 0x5e, 0x7a, 0xcf, 0x63, 0x7c, 0x48, 0xf9, 0xb1, 0xbf, 0x53,
-	0x3e, 0x09, 0x6c, 0xe3, 0xd5, 0x9b, 0x32, 0xce, 0x72, 0x89, 0xfe, 0xd6,
-	0xad, 0x5c, 0x32, 0xfe, 0x6a, 0x8a, 0x8b, 0xf1, 0xb7, 0xa4, 0x3c, 0xb7,
-	0x03, 0x0e, 0xb8, 0x56, 0xbe, 0x0a, 0x1e, 0x68, 0xd1, 0xff, 0xa2, 0x56,
-	0x66, 0xce, 0xae, 0xda, 0x47, 0xdb, 0xf9, 0xbe, 0xe7, 0x7b, 0x5e, 0xa0,
-	0xb3, 0x62, 0x17, 0xfc, 0xb5, 0x9f, 0x5a, 0xaf, 0x9b, 0x7c, 0x7e, 0x00,
-	0x1e, 0x1e, 0x37, 0x39, 0x56, 0x71, 0x56, 0xc4, 0x73, 0x7f, 0x3d, 0x0d,
-	0x3c, 0xfa, 0xbc, 0x76, 0xb5, 0xee, 0x3e, 0xae, 0xff, 0x1e, 0x4a, 0x92,
-	0x3b, 0xf2, 0xc8, 0xb6, 0x73, 0xb3, 0x81, 0x73, 0x73, 0x5d, 0xe9, 0xe0,
-	0xb3, 0x55, 0xea, 0xbf, 0x13, 0xea, 0xac, 0x7c, 0x53, 0x9e, 0x53, 0xe7,
-	0xe5, 0xd1, 0x02, 0x0d, 0xce, 0x67, 0x58, 0x61, 0x5f, 0x0c, 0xab, 0x7a,
-	0x82, 0x31, 0xd5, 0x42, 0xbe, 0x5d, 0x82, 0x3f, 0x1a, 0x2a, 0x16, 0xb0,
-	0xf6, 0xcc, 0x1f, 0x2d, 0xf8, 0xa3, 0x9e, 0xa4, 0x31, 0xf1, 0xe5, 0x9e,
-	0x1d, 0xfe, 0x88, 0x7c, 0x6a, 0x2f, 0x9a, 0x38, 0x6f, 0x5f, 0x49, 0x54,
-	0xfe, 0x5c, 0x68, 0xb5, 0xa9, 0xf9, 0x60, 0xed, 0x38, 0xd7, 0x6d, 0x5c,
-	0x77, 0xcd, 0x2c, 0x55, 0xd1, 0xd7, 0xb3, 0x29, 0x84, 0x4f, 0xbe, 0x7d,
-	0x90, 0x16, 0x8d, 0x1a, 0xe3, 0x17, 0xef, 0x09, 0x35, 0xc3, 0x83, 0xa8,
-	0xa5, 0x92, 0xb1, 0x45, 0xbd, 0x36, 0x06, 0x1c, 0x35, 0x29, 0x80, 0x9d,
-	0x01, 0x74, 0xcf, 0xb5, 0x6d, 0x7b, 0xb9, 0xcd, 0x67, 0xa4, 0x26, 0xf1,
-	0x19, 0xbc, 0xdb, 0xbb, 0x0e, 0x7d, 0x03, 0xcf, 0xe0, 0xcc, 0xea, 0xc4,
-	0xc0, 0xd5, 0xcb, 0x89, 0x45, 0xad, 0x12, 0xdf, 0x51, 0x30, 0x57, 0x96,
-	0xa1, 0xe3, 0x99, 0x42, 0x8a, 0xcb, 0x32, 0xf4, 0x70, 0xcc, 0x10, 0xe6,
-	0x63, 0xff, 0xe5, 0x58, 0x2b, 0xf7, 0xd5, 0xee, 0x85, 0xec, 0xbc, 0x4a,
-	0xca, 0x07, 0xec, 0xdf, 0xd0, 0x7b, 0xbe, 0x90, 0xdf, 0xc7, 0xb4, 0x10,
-	0xf3, 0x8d, 0x7d, 0x8c, 0x43, 0x0d, 0x78, 0xc3, 0x98, 0x84, 0xfb, 0x90,
-	0x57, 0xf6, 0x21, 0x37, 0x97, 0x8a, 0xaa, 0x6d, 0x26, 0xc7, 0xb2, 0xf1,
-	0xba, 0x1a, 0xc7, 0x39, 0x21, 0x4e, 0xd4, 0x59, 0x41, 0x8b, 0x3a, 0xe4,
-	0x34, 0x7c, 0x9c, 0x81, 0x50, 0x5b, 0xac, 0x24, 0x9c, 0xcf, 0xf7, 0xd9,
-	0xba, 0xe2, 0xb9, 0x4d, 0xc8, 0xe0, 0x79, 0x83, 0xf4, 0x86, 0xcf, 0xf7,
-	0x07, 0xd9, 0xdd, 0x46, 0x89, 0x86, 0x21, 0x0f, 0xbb, 0xc6, 0xd8, 0xae,
-	0xa0, 0xa1, 0x6a, 0x11, 0xd6, 0xbd, 0x5f, 0x4f, 0xef, 0x5c, 0x7e, 0x93,
-	0xcd, 0x65, 0x83, 0x5f, 0x08, 0xe7, 0x1d, 0x9f, 0xf3, 0xda, 0xd7, 0x0c,
-	0xba, 0x4e, 0x8a, 0x23, 0xc5, 0x37, 0x90, 0xef, 0x0e, 0x42, 0x26, 0x50,
-	0xfc, 0x92, 0x9e, 0x19, 0x72, 0x99, 0x8a, 0xb1, 0x5d, 0xc7, 0x77, 0xcc,
-	0xed, 0xef, 0x01, 0x62, 0xab, 0x9a, 0xcd, 0xd7, 0x8f, 0xd3, 0x4d, 0xe0,
-	0x74, 0xb3, 0xb0, 0x75, 0xee, 0x28, 0x15, 0x30, 0x8e, 0x6d, 0x64, 0x2e,
-	0x61, 0x99, 0x4f, 0xac, 0xed, 0x7a, 0x2a, 0x3b, 0xe8, 0xf8, 0x53, 0x9f,
-	0x8e, 0x12, 0xaf, 0x4d, 0x34, 0xd2, 0xf3, 0xb3, 0xfa, 0x6b, 0xc0, 0xcf,
-	0x38, 0x6f, 0x3c, 0xa0, 0x63, 0x1d, 0x5c, 0x7f, 0xd5, 0x55, 0x3f, 0x0e,
-	0x56, 0xdb, 0xf4, 0xfe, 0x30, 0x9b, 0x67, 0x5f, 0x1a, 0x0f, 0x1e, 0xda,
-	0x64, 0xb3, 0xcf, 0x76, 0x6b, 0x87, 0x79, 0x91, 0xd8, 0xbd, 0x19, 0x8d,
-	0xf1, 0x66, 0xd4, 0x38, 0x07, 0xe3, 0x79, 0x0b, 0x1f, 0x8c, 0xd5, 0xcf,
-	0xc7, 0xa8, 0xf5, 0x05, 0x31, 0xfa, 0x46, 0x9b, 0xb9, 0x22, 0xc5, 0x68,
-	0xe3, 0x0e, 0x8c, 0xa2, 0x06, 0x2a, 0xe5, 0xf8, 0xe4, 0x78, 0xc9, 0xf1,
-	0x99, 0x3f, 0xf3, 0xfd, 0x08, 0x38, 0x38, 0xe3, 0xb6, 0x18, 0xdc, 0x16,
-	0xa9, 0x1c, 0xe7, 0x96, 0x23, 0x4a, 0xe3, 0x78, 0x19, 0x71, 0x1c, 0x19,
-	0x9c, 0xf3, 0x38, 0x86, 0x59, 0x8e, 0xe3, 0x98, 0xe5, 0x46, 0x32, 0x39,
-	0xb4, 0x88, 0xe7, 0x28, 0x8b, 0xe7, 0x16, 0x78, 0x37, 0xca, 0xe2, 0xb9,
-	0x85, 0x18, 0x5e, 0xc9, 0xe2, 0xb9, 0x95, 0xc5, 0x33, 0xdf, 0xdb, 0x19,
-	0x55, 0x95, 0x8b, 0x9d, 0x3a, 0x78, 0x6d, 0x45, 0xe9, 0x6c, 0x62, 0x9d,
-	0xb0, 0xb1, 0x93, 0xc7, 0xc5, 0x1d, 0xf7, 0x5b, 0x58, 0xcf, 0xad, 0xbc,
-	0x32, 0x8b, 0xbc, 0x72, 0x0e, 0x79, 0xa5, 0xdb, 0x77, 0xbf, 0x75, 0x56,
-	0xe5, 0x95, 0x27, 0x8b, 0x79, 0x5e, 0xe9, 0x66, 0x79, 0xa5, 0xab, 0xf2,
-	0xca, 0x13, 0x45, 0xce, 0x2b, 0x31, 0x05, 0xc5, 0xfe, 0xbc, 0x12, 0x6f,
-	0xcb, 0x2b, 0xb9, 0x2c, 0xf7, 0xef, 0x94, 0x57, 0x72, 0x9f, 0x71, 0x6e,
-	0xb1, 0x72, 0x5e, 0xbd, 0x2d, 0x9f, 0xe4, 0x63, 0xd8, 0x56, 0xe6, 0x25,
-	0xe6, 0xe0, 0xb4, 0xae, 0xbf, 0x92, 0xe4, 0xb1, 0x74, 0x0c, 0xf3, 0xe0,
-	0xbd, 0xb3, 0x53, 0x2c, 0xd9, 0x59, 0x2c, 0x0d, 0xa7, 0x32, 0x9d, 0xfe,
-	0x78, 0x3a, 0x56, 0xdc, 0x1e, 0x4f, 0xb9, 0x9e, 0x3c, 0x9e, 0x52, 0x9d,
-	0x1f, 0x1a, 0x65, 0xae, 0x07, 0x70, 0x96, 0x76, 0xfd, 0x39, 0xf4, 0x5e,
-	0xe8, 0x4d, 0xa3, 0xae, 0x36, 0xe9, 0x6a, 0xce, 0x37, 0xea, 0xbe, 0x07,
-	0x6d, 0x2f, 0xb7, 0xb5, 0xb8, 0xf5, 0xad, 0x8b, 0xda, 0xfa, 0x7d, 0xf0,
-	0xc8, 0x79, 0xf5, 0xfd, 0x33, 0x79, 0xb5, 0x84, 0x33, 0xb0, 0x97, 0x8f,
-	0x7b, 0x1d, 0xf3, 0xb9, 0xe2, 0x2c, 0x9e, 0x5e, 0xee, 0xdd, 0x82, 0xf9,
-	0x8a, 0xc7, 0x7d, 0xff, 0x44, 0x0e, 0x41, 0x5d, 0xbe, 0x35, 0x96, 0xcf,
-	0x38, 0x1e, 0xd6, 0xec, 0xd0, 0xa5, 0x6d, 0xe7, 0x9c, 0xf4, 0x7c, 0x83,
-	0x75, 0xa3, 0x3e, 0xe1, 0x3a, 0x25, 0xfc, 0x8a, 0x4e, 0x2f, 0xd1, 0xb7,
-	0x7c, 0xee, 0xd3, 0x69, 0xf6, 0x31, 0x29, 0x5f, 0x40, 0xcd, 0xf2, 0xf4,
-	0xb6, 0x9a, 0xa5, 0x48, 0xe3, 0x07, 0xfa, 0xcf, 0x87, 0x37, 0xe5, 0xf8,
-	0xa4, 0x7b, 0x36, 0xa0, 0x40, 0x9b, 0x5d, 0xe7, 0x5a, 0x76, 0xab, 0x76,
-	0x25, 0x1a, 0xbd, 0x21, 0xf5, 0x49, 0xce, 0x85, 0x57, 0x33, 0x5f, 0xe1,
-	0xdb, 0x99, 0x1b, 0xe0, 0xd6, 0x48, 0xdd, 0xf1, 0x06, 0xeb, 0x3c, 0x0f,
-	0xbf, 0xa3, 0x4d, 0xb8, 0xbe, 0xb9, 0xdb, 0xbd, 0xab, 0x89, 0x7d, 0x71,
-	0x9d, 0xa3, 0x06, 0xa9, 0xbb, 0x8b, 0x25, 0xdf, 0xfd, 0x59, 0x8b, 0x52,
-	0x9e, 0x88, 0xfc, 0x05, 0xd8, 0x02, 0x9c, 0x8b, 0x45, 0xec, 0xcd, 0x24,
-	0x78, 0xc9, 0x75, 0x0e, 0xe8, 0x42, 0x61, 0x7f, 0x19, 0xba, 0x8d, 0x03,
-	0x5c, 0x3f, 0x7e, 0x2a, 0x97, 0x7b, 0x2a, 0x07, 0xfb, 0x8c, 0x91, 0x7a,
-	0xb2, 0x5b, 0xe7, 0x36, 0x48, 0xf8, 0xb9, 0x80, 0x79, 0x9c, 0xbb, 0xe0,
-	0xa7, 0x24, 0xa2, 0x33, 0x8e, 0x98, 0xed, 0x38, 0x62, 0xae, 0xa3, 0x03,
-	0xdd, 0xb6, 0x4d, 0xbb, 0xb0, 0x27, 0xc8, 0xc1, 0xf4, 0x00, 0x6c, 0xb9,
-	0xe0, 0x88, 0x3a, 0x6a, 0xc1, 0x1f, 0x18, 0xae, 0x78, 0x9a, 0x3e, 0xc1,
-	0x1a, 0x6f, 0xc8, 0xf4, 0xde, 0xc5, 0x11, 0xd1, 0xd6, 0xdc, 0x37, 0x30,
-	0x37, 0xdb, 0xc4, 0x31, 0xca, 0xf9, 0x72, 0x5e, 0x5b, 0x80, 0x8f, 0x8e,
-	0xac, 0x6b, 0xe0, 0x35, 0xce, 0x97, 0x23, 0xd9, 0xfd, 0x12, 0xf6, 0x07,
-	0xeb, 0xbf, 0x74, 0x47, 0xad, 0x99, 0xd7, 0x94, 0xe9, 0xdd, 0x69, 0x3c,
-	0xc3, 0xf3, 0x13, 0x6c, 0x99, 0x98, 0xba, 0xa0, 0xce, 0x3d, 0xd3, 0xa8,
-	0xf1, 0xb8, 0x95, 0xa8, 0x83, 0xf8, 0xae, 0x8b, 0x6b, 0x27, 0x89, 0xf8,
-	0x4f, 0x9f, 0x63, 0x3e, 0x13, 0xcd, 0xb0, 0x0e, 0x3e, 0x1b, 0x71, 0xfc,
-	0xfc, 0x1b, 0x2f, 0xf3, 0x0a, 0xbd, 0x68, 0x18, 0x00, 0x00, 0x00 };
+	0xcd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0xf3, 0xb7, 0x3b, 0xde,
+	0x38, 0xf1, 0x24, 0x19, 0xca, 0xa6, 0x72, 0xe9, 0x8c, 0x3d, 0x76, 0x8c,
+	0x6c, 0x35, 0xd3, 0x76, 0xd5, 0x58, 0x68, 0xa4, 0x4e, 0x67, 0x76, 0x1d,
+	0x2b, 0xf4, 0xc1, 0x85, 0x48, 0x3c, 0xf0, 0xe2, 0xae, 0x1d, 0x05, 0x78,
+	0x2a, 0x28, 0x0f, 0x11, 0x2f, 0x59, 0x76, 0x37, 0xfd, 0x41, 0xdb, 0x2c,
+	0x35, 0xc8, 0x41, 0x02, 0xa4, 0xb0, 0x69, 0xe2, 0x97, 0xad, 0x27, 0x2d,
+	0x45, 0xea, 0x4b, 0x95, 0x28, 0x55, 0x2b, 0xc4, 0x13, 0x2f, 0x54, 0x79,
+	0xac, 0x52, 0x5a, 0xf1, 0x00, 0x28, 0x42, 0x15, 0xaa, 0x68, 0xf0, 0xe5,
+	0x3b, 0x77, 0x66, 0xdc, 0xdd, 0xc4, 0x49, 0xcb, 0x9f, 0x84, 0xa5, 0xf5,
+	0x9d, 0xb9, 0xf7, 0x9e, 0x73, 0xcf, 0x3d, 0x3f, 0xdf, 0x39, 0x67, 0xca,
+	0x2a, 0x95, 0x28, 0xfb, 0xdb, 0x8d, 0xdf, 0xc9, 0xa7, 0x9f, 0x39, 0x79,
+	0xf8, 0xa1, 0x47, 0x1d, 0xa2, 0x87, 0x1f, 0x52, 0x94, 0xa2, 0x46, 0xff,
+	0x85, 0x3f, 0x30, 0xb1, 0x72, 0xfe, 0xfc, 0x23, 0x53, 0x0d, 0x7e, 0xe3,
+	0x44, 0x1e, 0x99, 0x5a, 0xb0, 0xf4, 0xe5, 0x15, 0x8f, 0x28, 0xec, 0xcf,
+	0x3a, 0x31, 0xfd, 0x43, 0x34, 0x6c, 0x9d, 0x78, 0xfe, 0x81, 0xe0, 0xd6,
+	0xa1, 0x37, 0x0f, 0xbb, 0x37, 0xcf, 0x6b, 0x64, 0x5a, 0xc1, 0xb2, 0x69,
+	0x4d, 0x93, 0x39, 0x1e, 0x5c, 0x75, 0x7e, 0x7e, 0x30, 0x28, 0xd0, 0x9e,
+	0x9c, 0x97, 0x4d, 0xcd, 0x2e, 0x35, 0xf4, 0xc0, 0xa4, 0x5a, 0xe7, 0x94,
+	0x12, 0x75, 0x3d, 0xab, 0x0a, 0x1e, 0xa1, 0x0d, 0xfe, 0x1e, 0xde, 0x13,
+	0x5d, 0xa9, 0x9e, 0x33, 0x49, 0x0d, 0x42, 0x3c, 0xcf, 0x51, 0xab, 0x2b,
+	0xc4, 0x0f, 0x7d, 0x85, 0x56, 0x7c, 0x93, 0x96, 0x2d, 0x77, 0x31, 0x54,
+	0xb6, 0x44, 0x3c, 0x25, 0xc4, 0xb7, 0x7d, 0x95, 0x54, 0x6f, 0x41, 0x89,
+	0x36, 0x16, 0x95, 0x78, 0x63, 0x91, 0xf5, 0x01, 0xf9, 0x16, 0x94, 0x70,
+	0x83, 0xc7, 0xc0, 0x8c, 0x3b, 0x7b, 0x68, 0xd9, 0xa6, 0x31, 0xd5, 0x9b,
+	0xc3, 0x79, 0x65, 0xf0, 0x71, 0x28, 0xf2, 0x67, 0x2d, 0x95, 0x26, 0xf1,
+	0x1b, 0xa1, 0x9a, 0x4f, 0x23, 0xaa, 0xa7, 0x52, 0xdd, 0x56, 0xe8, 0xe5,
+	0x8a, 0x81, 0xdf, 0x51, 0xa5, 0xba, 0xf1, 0x9d, 0x8c, 0x0f, 0xef, 0x37,
+	0xb1, 0xc6, 0x32, 0x33, 0xfd, 0x20, 0xed, 0x6e, 0x3c, 0x7f, 0x0b, 0xfb,
+	0x0c, 0x8a, 0x2a, 0xb7, 0xaf, 0x8d, 0xe0, 0x59, 0xc1, 0xfc, 0x51, 0xc8,
+	0xc5, 0x7c, 0x1c, 0xc8, 0x31, 0x4e, 0xed, 0xee, 0x22, 0xee, 0x53, 0xa0,
+	0x86, 0x35, 0x35, 0x53, 0x27, 0x1d, 0x34, 0x1a, 0x85, 0xf6, 0x15, 0xa1,
+	0x06, 0x42, 0x44, 0x15, 0x6f, 0xa6, 0x27, 0xcf, 0x50, 0x49, 0xf3, 0x0a,
+	0x54, 0xf5, 0x77, 0x53, 0xcb, 0xd2, 0xa8, 0x39, 0x67, 0x50, 0xb8, 0xa4,
+	0xe3, 0x8e, 0xfb, 0x40, 0xa7, 0x80, 0xfe, 0xa5, 0xcc, 0xe6, 0x45, 0x6a,
+	0x5a, 0x05, 0xcc, 0x8f, 0x51, 0xd3, 0xde, 0xab, 0xa8, 0xc1, 0x0b, 0x98,
+	0x9f, 0xb2, 0x7a, 0xf4, 0x3c, 0x46, 0x05, 0xef, 0x7b, 0xb1, 0x97, 0xdf,
+	0x15, 0xf0, 0x23, 0x2b, 0x4a, 0x66, 0xa8, 0x95, 0xe4, 0xb4, 0x3c, 0x9f,
+	0xce, 0x35, 0x92, 0xdb, 0xed, 0x8d, 0x7d, 0xdd, 0x1a, 0x74, 0xcc, 0xb6,
+	0xc1, 0x9e, 0xdc, 0x2e, 0xd2, 0x07, 0x1e, 0xe7, 0x79, 0xfe, 0xc3, 0xbc,
+	0x43, 0x5a, 0xe0, 0x59, 0x31, 0x7d, 0x85, 0xd2, 0xb5, 0x54, 0xf6, 0xc8,
+	0x7f, 0x2c, 0x7b, 0xb7, 0xad, 0xe8, 0xdc, 0xa3, 0xb8, 0x9f, 0x74, 0x19,
+	0x3c, 0xdb, 0xb8, 0x7f, 0x01, 0xfe, 0xd1, 0x0c, 0x55, 0x6a, 0x94, 0x4d,
+	0x72, 0xe7, 0x57, 0xb1, 0xf2, 0x41, 0x47, 0xa3, 0x98, 0x75, 0xe5, 0xeb,
+	0x19, 0x1d, 0xfb, 0xc6, 0xbb, 0x90, 0xb3, 0x61, 0x99, 0x70, 0xbc, 0xe5,
+	0x63, 0x42, 0x5c, 0xf4, 0x85, 0x28, 0x04, 0xde, 0xcc, 0x25, 0x9a, 0x2d,
+	0x1b, 0x34, 0x6d, 0x61, 0x84, 0x8e, 0xbd, 0x72, 0x9d, 0x8c, 0x5c, 0x9e,
+	0xdc, 0x37, 0xf1, 0xd7, 0x57, 0x08, 0x3e, 0x79, 0xa3, 0xf3, 0x7b, 0xd6,
+	0xc7, 0xcc, 0x82, 0xa4, 0x11, 0xa2, 0x37, 0x7f, 0x2f, 0x9a, 0x5f, 0x67,
+	0x34, 0x42, 0xd4, 0x2a, 0x7c, 0xae, 0x8b, 0x3b, 0xb3, 0x7f, 0x13, 0xd5,
+	0xfa, 0xbe, 0x59, 0xef, 0x40, 0x3e, 0x0f, 0x63, 0x9f, 0xa8, 0xde, 0xe5,
+	0x7b, 0x98, 0xd4, 0x84, 0xde, 0x5a, 0xd8, 0xaf, 0x56, 0x76, 0xb1, 0x7f,
+	0xc0, 0xc6, 0x4b, 0x66, 0xb5, 0xe3, 0x96, 0x5f, 0xa0, 0x25, 0x33, 0xee,
+	0xcf, 0x96, 0x57, 0xe9, 0x01, 0x3e, 0xc7, 0x34, 0x82, 0x63, 0x66, 0x4f,
+	0xd2, 0x1b, 0x1a, 0x95, 0xf0, 0x0c, 0x1e, 0xcd, 0x0e, 0x29, 0x91, 0xbf,
+	0x8b, 0xef, 0x0b, 0xba, 0xc5, 0x8c, 0x6e, 0x31, 0xa3, 0x1b, 0xcb, 0xe8,
+	0x9e, 0x1c, 0xa0, 0x7b, 0x92, 0xe9, 0xb0, 0x37, 0xcc, 0xf6, 0x86, 0xd9,
+	0x5e, 0x3d, 0xdb, 0x5b, 0xcd, 0xf6, 0x62, 0xec, 0x3b, 0x90, 0xcf, 0x9d,
+	0x09, 0x15, 0xc8, 0xe8, 0x89, 0x07, 0x23, 0x9f, 0xc2, 0xd8, 0x73, 0xaf,
+	0xc7, 0xda, 0x18, 0x5d, 0xf0, 0x2d, 0x6a, 0x27, 0x0e, 0x64, 0x6f, 0x53,
+	0x94, 0xa8, 0xa0, 0x1d, 0xa3, 0x9e, 0x77, 0x53, 0xd4, 0xfc, 0x0a, 0x6c,
+	0x37, 0xca, 0x74, 0xe5, 0x1a, 0x14, 0xd1, 0x4c, 0x66, 0xad, 0x55, 0xaa,
+	0xc0, 0x5f, 0x54, 0xd8, 0x6f, 0x52, 0x3e, 0x37, 0x93, 0x0a, 0xd6, 0xa9,
+	0xa1, 0x56, 0x5c, 0xab, 0x49, 0x6e, 0x39, 0xd2, 0xc8, 0x52, 0x03, 0x1b,
+	0x7b, 0x1a, 0x54, 0x4d, 0x4c, 0x7a, 0x4f, 0x3b, 0x25, 0xe3, 0xb4, 0xd9,
+	0xbd, 0x2e, 0xde, 0x3c, 0xe8, 0xd0, 0x95, 0x64, 0x9c, 0x7e, 0x95, 0x94,
+	0xe9, 0xb5, 0xc4, 0xa6, 0x57, 0x13, 0x52, 0x23, 0x1f, 0x7e, 0x6c, 0x5b,
+	0x74, 0x39, 0x19, 0xd4, 0xfb, 0x07, 0xac, 0x77, 0x73, 0x7f, 0x40, 0xe6,
+	0xbe, 0x80, 0x1a, 0x5a, 0x90, 0xe2, 0x40, 0x9c, 0xe2, 0x80, 0xf4, 0xa9,
+	0x56, 0xb7, 0x79, 0xbf, 0x06, 0x0c, 0x5a, 0xf1, 0xc3, 0xbd, 0x1a, 0xec,
+	0x12, 0x23, 0x0a, 0xd4, 0xed, 0x51, 0xda, 0xc8, 0x5d, 0xf1, 0xdc, 0xe7,
+	0x63, 0xec, 0xf6, 0xce, 0x1a, 0x98, 0xbd, 0xdd, 0xb6, 0x7f, 0xc6, 0x19,
+	0xa3, 0xb0, 0x9b, 0x46, 0x4f, 0xe8, 0x88, 0x1f, 0xef, 0x23, 0x8d, 0x63,
+	0xc0, 0xd9, 0xb4, 0xe9, 0x4c, 0x97, 0x68, 0x62, 0xd3, 0xa4, 0x8d, 0x4e,
+	0x91, 0x9c, 0xde, 0x28, 0xad, 0x74, 0x4b, 0x34, 0x79, 0x49, 0xc7, 0xde,
+	0x5d, 0x34, 0xb9, 0xa6, 0xda, 0x1c, 0xcb, 0x31, 0x74, 0x3c, 0xd1, 0x13,
+	0xf0, 0xd1, 0x12, 0x4d, 0xac, 0xbb, 0xd2, 0x7f, 0x56, 0xbc, 0x96, 0xaf,
+	0xd1, 0x0f, 0xe8, 0xda, 0x5c, 0x01, 0x77, 0xb2, 0xc9, 0x9f, 0x1e, 0x3c,
+	0xcf, 0x80, 0x9b, 0xf1, 0x1c, 0x98, 0xee, 0x71, 0x1d, 0x52, 0x99, 0x9f,
+	0x49, 0x13, 0x97, 0x4c, 0x25, 0xee, 0xb2, 0xce, 0xd8, 0x07, 0xcd, 0xcc,
+	0x07, 0x75, 0x25, 0x3a, 0x57, 0xc4, 0x59, 0x7f, 0x12, 0x91, 0x07, 0xdf,
+	0x03, 0x96, 0xad, 0x54, 0xbe, 0x0f, 0xf9, 0x30, 0xd7, 0xe3, 0xb5, 0x9b,
+	0xd9, 0x3c, 0xf3, 0x00, 0x46, 0xf8, 0xfb, 0x29, 0x62, 0x3c, 0x38, 0xc6,
+	0x34, 0x45, 0x9a, 0x58, 0x63, 0x8c, 0xc1, 0xd8, 0xe3, 0x77, 0xbe, 0xdb,
+	0x08, 0xd5, 0xa1, 0x95, 0xfa, 0x8c, 0x0d, 0xb9, 0x54, 0x89, 0x19, 0x75,
+	0x60, 0x88, 0xea, 0x95, 0x30, 0xf2, 0x79, 0x3f, 0xd3, 0xd2, 0xf8, 0xb7,
+	0xa5, 0xbd, 0x63, 0xf8, 0xaf, 0x0e, 0x79, 0x56, 0x69, 0xaa, 0x7c, 0x5c,
+	0xae, 0x61, 0xae, 0xcf, 0x6b, 0xd6, 0x6d, 0x6b, 0x78, 0xef, 0xe7, 0x32,
+	0x20, 0xc6, 0xbd, 0x16, 0x4e, 0x31, 0x32, 0xbd, 0xf0, 0xfe, 0x46, 0x19,
+	0xb6, 0x01, 0xa6, 0x11, 0x74, 0x49, 0xd4, 0xeb, 0xe8, 0xc0, 0x1c, 0xf5,
+	0x8b, 0x2a, 0xd3, 0xd9, 0xcc, 0x07, 0xf7, 0x5f, 0xd7, 0x95, 0xf8, 0x9c,
+	0xe7, 0xfc, 0x81, 0x98, 0x7e, 0x12, 0x3a, 0x98, 0x9a, 0x6f, 0xf1, 0xfe,
+	0xbe, 0x41, 0xde, 0x5a, 0xc3, 0xd2, 0x61, 0x53, 0x15, 0x06, 0x8d, 0x7f,
+	0x34, 0x06, 0x5b, 0xbb, 0x4e, 0x8b, 0x7e, 0x07, 0x79, 0x0a, 0xe4, 0xf5,
+	0x74, 0x7a, 0xb9, 0xc3, 0xba, 0x30, 0x69, 0x72, 0x5d, 0x88, 0xe7, 0x7c,
+	0xb6, 0xc9, 0xbb, 0xd0, 0x0b, 0xe1, 0x86, 0x53, 0xf3, 0x37, 0x60, 0x9f,
+	0x8d, 0x3e, 0xdb, 0xc6, 0x90, 0x3a, 0xf1, 0xd6, 0xe6, 0x60, 0xd7, 0x99,
+	0x4c, 0x46, 0xb6, 0x97, 0x4e, 0xed, 0x8a, 0x4a, 0x17, 0x2b, 0x9f, 0x08,
+	0xd5, 0x63, 0x8c, 0x2d, 0x40, 0xb7, 0xd8, 0xd7, 0xc3, 0xbe, 0xa4, 0x00,
+	0x1d, 0xfe, 0x4d, 0x18, 0xc0, 0xdf, 0x8b, 0x15, 0xcc, 0xaf, 0x9d, 0x86,
+	0xac, 0x1a, 0x68, 0x53, 0x1f, 0x63, 0x79, 0x16, 0x3a, 0xf9, 0xfd, 0xbc,
+	0xf9, 0xb7, 0x25, 0xbf, 0x51, 0x9a, 0xde, 0x1c, 0xa5, 0x13, 0xfd, 0x51,
+	0x9a, 0x38, 0xcb, 0x34, 0x42, 0xb4, 0x2b, 0x8c, 0x91, 0xf0, 0x51, 0x4f,
+	0xea, 0xa1, 0xac, 0xa9, 0x7c, 0x4f, 0xac, 0x6f, 0x12, 0xad, 0xf6, 0xf9,
+	0x0c, 0x7d, 0x80, 0xa7, 0x4a, 0x47, 0x7e, 0x42, 0x74, 0xa4, 0xcf, 0xb4,
+	0xdb, 0xba, 0x03, 0x5f, 0x0b, 0x3c, 0x2d, 0xe2, 0x5c, 0xa4, 0x79, 0xc8,
+	0x79, 0x1b, 0x11, 0x72, 0x58, 0x15, 0xbf, 0x05, 0xe4, 0x35, 0xbe, 0xff,
+	0x1c, 0xe2, 0x8f, 0xb1, 0x7c, 0x0b, 0x77, 0x2f, 0x50, 0xdb, 0x5f, 0xc4,
+	0x1e, 0xb6, 0xf1, 0x51, 0xac, 0xef, 0x46, 0x2e, 0xc8, 0x72, 0x85, 0xc5,
+	0xb9, 0x62, 0x2f, 0xe2, 0x60, 0x04, 0xf8, 0x7f, 0xbf, 0x3e, 0x9c, 0x2b,
+	0xb0, 0xcf, 0x3e, 0x80, 0xdc, 0x80, 0x44, 0x5d, 0x62, 0x5e, 0xfb, 0x31,
+	0x8e, 0xe0, 0xfd, 0x00, 0xf6, 0x0e, 0xe6, 0x89, 0x9c, 0xee, 0x6e, 0x39,
+	0x02, 0x31, 0xb1, 0x86, 0x58, 0x59, 0x9f, 0x61, 0xcc, 0x80, 0x3d, 0xd8,
+	0xa6, 0x45, 0x60, 0xb8, 0x09, 0x1e, 0x6c, 0xdb, 0x22, 0x6c, 0xc8, 0x79,
+	0xce, 0xa2, 0xc9, 0x4d, 0x8e, 0xeb, 0x34, 0x8f, 0xc4, 0xdb, 0x79, 0x84,
+	0x64, 0x4c, 0x34, 0x13, 0xf6, 0x89, 0xd0, 0x8c, 0xce, 0x6e, 0x09, 0xc4,
+	0x70, 0x39, 0x66, 0x5c, 0xdb, 0x9c, 0x05, 0xbd, 0x86, 0xf8, 0xa8, 0x9a,
+	0xf5, 0xb3, 0x29, 0xa6, 0xd5, 0x37, 0x1d, 0xe9, 0x93, 0xcd, 0xc4, 0xc2,
+	0x3b, 0x63, 0x5a, 0x8e, 0x61, 0x4c, 0x4f, 0x61, 0x04, 0x7c, 0x8b, 0x34,
+	0x21, 0x56, 0xfc, 0x31, 0xaa, 0xc3, 0x3f, 0x43, 0xe0, 0x5a, 0x1d, 0xb8,
+	0x16, 0x0f, 0xe0, 0x5a, 0xfc, 0x99, 0xb8, 0x06, 0xcc, 0xea, 0x02, 0xb3,
+	0x50, 0x23, 0xbc, 0x06, 0x8c, 0x7f, 0x15, 0xe7, 0x5d, 0xee, 0xee, 0x84,
+	0x75, 0x8c, 0x73, 0x8c, 0x77, 0x33, 0xf4, 0xe6, 0xc1, 0x7f, 0x15, 0xef,
+	0xda, 0xc0, 0x06, 0x93, 0xbe, 0x7b, 0xf0, 0xde, 0x98, 0x77, 0x06, 0x98,
+	0x67, 0x7c, 0x36, 0xe6, 0x35, 0x18, 0xf3, 0x74, 0xf8, 0x60, 0x03, 0x78,
+	0xa0, 0xae, 0x0d, 0x9e, 0xd3, 0xc1, 0x39, 0x3c, 0xa7, 0x67, 0x79, 0x55,
+	0xa5, 0x1e, 0xfc, 0x5f, 0xf3, 0xf8, 0x9c, 0x39, 0xd6, 0xbb, 0xd4, 0xff,
+	0x13, 0xba, 0x4d, 0xc6, 0x34, 0xfc, 0x62, 0x6d, 0x94, 0xb4, 0xb3, 0x9f,
+	0xfa, 0x3d, 0x6a, 0x03, 0xc4, 0x3b, 0xfe, 0x6d, 0xe6, 0x3c, 0x4a, 0xc0,
+	0x1c, 0x9d, 0x0a, 0x6b, 0x06, 0xde, 0x95, 0xa1, 0x7d, 0x47, 0x90, 0x77,
+	0xb4, 0xc0, 0x9d, 0x7f, 0x9f, 0x9f, 0xfb, 0xbc, 0xa7, 0x44, 0xea, 0xba,
+	0xeb, 0x38, 0xaa, 0xeb, 0x5f, 0x03, 0x46, 0xbc, 0xe3, 0x31, 0x0e, 0x36,
+	0xe1, 0x0d, 0x05, 0xd2, 0xd7, 0xc4, 0x69, 0x23, 0xe0, 0xb3, 0x1b, 0x0e,
+	0xe2, 0xdd, 0x79, 0x09, 0x7e, 0xc4, 0x39, 0xf4, 0x22, 0xe2, 0xa7, 0x96,
+	0xc5, 0x6a, 0xab, 0x9f, 0x9f, 0xb9, 0x0f, 0x72, 0x1b, 0xa0, 0x19, 0xdc,
+	0xcb, 0x71, 0x20, 0xc4, 0x09, 0xdc, 0x49, 0xc3, 0x39, 0xc6, 0xba, 0x49,
+	0x85, 0x75, 0xd6, 0x8b, 0x0b, 0xfa, 0x49, 0x6b, 0x81, 0xae, 0x0f, 0xe1,
+	0xc2, 0x73, 0xfd, 0xeb, 0x3a, 0x63, 0xa9, 0x86, 0x18, 0x2d, 0xe2, 0x5c,
+	0x63, 0x9b, 0x17, 0x65, 0xbc, 0x98, 0xde, 0x2b, 0x9f, 0xd8, 0xa6, 0x67,
+	0x7c, 0x9b, 0x2a, 0x33, 0x8e, 0xb1, 0x1c, 0x9a, 0xc4, 0xd4, 0x52, 0x86,
+	0xa9, 0x93, 0xb0, 0x67, 0x49, 0xc6, 0xa7, 0xea, 0x3d, 0x98, 0xe1, 0xea,
+	0x5e, 0x8c, 0x3c, 0x27, 0xb2, 0x78, 0xd1, 0x21, 0x2f, 0xf3, 0x2d, 0x91,
+	0xb6, 0xce, 0x35, 0x04, 0xdf, 0xe9, 0xaf, 0xf0, 0x6d, 0xc6, 0x0a, 0xf6,
+	0x4f, 0x89, 0xa9, 0x98, 0x9f, 0x82, 0xcc, 0x8c, 0x0f, 0x4c, 0xc7, 0xf4,
+	0x3b, 0xd1, 0xfd, 0x05, 0x74, 0xd6, 0x0e, 0x74, 0x98, 0xdb, 0x64, 0x1a,
+	0xc6, 0x88, 0x7d, 0xd8, 0x1f, 0x31, 0x3e, 0x40, 0x67, 0x4c, 0x3b, 0x9e,
+	0xc5, 0x63, 0x15, 0x6b, 0x5c, 0x03, 0xcb, 0xf8, 0x22, 0x23, 0xe0, 0x7b,
+	0x70, 0x7d, 0xcc, 0xf9, 0x91, 0x6b, 0x52, 0xae, 0x3d, 0xf3, 0x5a, 0xd5,
+	0x9b, 0xa9, 0xdd, 0xad, 0xee, 0xb4, 0x06, 0xeb, 0xce, 0x43, 0xc6, 0xce,
+	0x75, 0xe7, 0x41, 0x23, 0xad, 0x3b, 0xa7, 0x8d, 0xbb, 0xd7, 0x9d, 0x39,
+	0xed, 0xbd, 0xeb, 0xce, 0x66, 0x97, 0xcf, 0xdc, 0x19, 0x2f, 0x56, 0xe0,
+	0xaf, 0xad, 0x24, 0xbf, 0x27, 0xf7, 0x06, 0xa1, 0x59, 0x3b, 0x9b, 0xda,
+	0xbe, 0x29, 0x7d, 0x11, 0x38, 0xb2, 0x39, 0x0b, 0x3b, 0xa2, 0xa6, 0x1e,
+	0xc2, 0x8e, 0x9c, 0x86, 0x75, 0x5a, 0x02, 0x46, 0xb3, 0x3e, 0x8b, 0x19,
+	0x4e, 0x60, 0xf4, 0x3e, 0x06, 0x4e, 0xe4, 0xf8, 0xc2, 0xfc, 0xfe, 0x9f,
+	0xf0, 0x85, 0xcc, 0x11, 0xe0, 0x84, 0x19, 0x30, 0x5e, 0x4a, 0x59, 0x50,
+	0x93, 0x0b, 0xb1, 0xe0, 0x73, 0x0c, 0x0c, 0xf6, 0x4c, 0xec, 0x0f, 0x45,
+	0x7a, 0xcb, 0x67, 0x9f, 0x40, 0xcf, 0xe4, 0x71, 0x8e, 0x64, 0x3c, 0xde,
+	0x12, 0x6f, 0x79, 0x11, 0xe6, 0xaa, 0xb0, 0x3d, 0xfb, 0xc3, 0xa2, 0x72,
+	0x64, 0xc3, 0x04, 0x1d, 0xfb, 0xc4, 0xf8, 0x1d, 0xbd, 0x50, 0xda, 0xb3,
+	0x70, 0x7d, 0xfc, 0xef, 0xfa, 0xc8, 0x1b, 0x77, 0xf1, 0x91, 0xcb, 0x99,
+	0x8f, 0x24, 0xf7, 0xf0, 0x91, 0x37, 0x3e, 0xa7, 0x8f, 0xb8, 0xe5, 0x0f,
+	0x51, 0x3f, 0xbd, 0x0d, 0x39, 0x42, 0x4b, 0x88, 0x0f, 0xfd, 0x9d, 0xfa,
+	0x94, 0xd0, 0xd4, 0x5f, 0x64, 0x9d, 0xa5, 0x79, 0xa5, 0x85, 0x77, 0xed,
+	0x15, 0xae, 0x97, 0x39, 0xe7, 0xa4, 0xb9, 0x65, 0xe2, 0xc5, 0xd4, 0x3f,
+	0x26, 0x5e, 0x11, 0xe2, 0xc2, 0x0e, 0xfe, 0xc0, 0x35, 0xf4, 0x55, 0xf8,
+	0x55, 0x8b, 0xfe, 0x17, 0x35, 0x34, 0x63, 0x78, 0xc5, 0x3c, 0xde, 0xc9,
+	0xed, 0x9f, 0xdb, 0xbe, 0x40, 0xe7, 0xad, 0x3d, 0xd0, 0xdb, 0xa3, 0xd4,
+	0xfa, 0xb1, 0xce, 0x7d, 0x05, 0xfc, 0xe2, 0x71, 0x9d, 0x63, 0x17, 0x7d,
+	0x24, 0x9e, 0x07, 0xeb, 0x6c, 0xf8, 0xa5, 0x5f, 0xc8, 0xe3, 0x65, 0x00,
+	0xfb, 0x4f, 0xa1, 0x54, 0xb9, 0x23, 0xaf, 0x0c, 0xf5, 0xd4, 0x1a, 0x7a,
+	0xea, 0x58, 0xf2, 0xe0, 0xbe, 0x2b, 0xd5, 0x63, 0x5b, 0xf6, 0xd1, 0x5b,
+	0xa2, 0x25, 0x7b, 0xe9, 0x03, 0x05, 0x2a, 0x2d, 0x66, 0x3e, 0xe3, 0x20,
+	0x1f, 0xb9, 0x7e, 0x03, 0xfc, 0xb9, 0xd6, 0x80, 0x1c, 0xb4, 0x8a, 0x58,
+	0xbc, 0x80, 0x3c, 0xbc, 0x02, 0xbd, 0xd4, 0x65, 0x6c, 0x8c, 0xd1, 0x35,
+	0xe4, 0xfe, 0x36, 0xf2, 0xf3, 0x19, 0xe8, 0xa6, 0x05, 0xdd, 0xc4, 0x49,
+	0x1a, 0x27, 0xd7, 0xa0, 0x9b, 0x85, 0x01, 0xdd, 0x2c, 0xfc, 0x47, 0xfd,
+	0xc5, 0x1f, 0x91, 0x6b, 0xcd, 0x65, 0x1d, 0xf3, 0x57, 0x12, 0x99, 0x5b,
+	0x97, 0x5a, 0x1d, 0x6a, 0xdc, 0x1f, 0x9c, 0xe6, 0xda, 0x8e, 0x6b, 0xb3,
+	0xf9, 0x95, 0x0a, 0xe6, 0xfa, 0x26, 0x45, 0xd0, 0xcf, 0x37, 0x0f, 0xd3,
+	0xb2, 0x16, 0xb0, 0x4f, 0xe3, 0x3d, 0xa1, 0x46, 0x74, 0x18, 0xf5, 0x56,
+	0x32, 0xbe, 0x8c, 0x7e, 0x1c, 0xbe, 0xd5, 0xa0, 0x10, 0x72, 0x86, 0xe0,
+	0xbd, 0xd0, 0x31, 0xcd, 0xd5, 0x0e, 0xf7, 0x51, 0x0d, 0xe2, 0x5e, 0xbd,
+	0xd7, 0xbf, 0x09, 0x7e, 0x23, 0xdf, 0x40, 0x7f, 0xeb, 0x34, 0x81, 0xd3,
+	0xcf, 0xc2, 0x6d, 0x5b, 0x36, 0x7f, 0xcb, 0x60, 0x1c, 0x1d, 0x07, 0x8f,
+	0xa7, 0x0b, 0xa9, 0xaf, 0x8e, 0x83, 0x0f, 0xc7, 0x11, 0xe1, 0x3c, 0xd6,
+	0x65, 0xee, 0x7f, 0xe5, 0x81, 0xfa, 0xbe, 0x40, 0x39, 0x86, 0x35, 0xa1,
+	0x37, 0xd6, 0x75, 0xe4, 0x9d, 0x2c, 0xe4, 0xdf, 0x6d, 0x5a, 0xc0, 0x81,
+	0xfa, 0x1c, 0x63, 0x96, 0x02, 0xdf, 0xa3, 0xb4, 0xaf, 0x44, 0x1f, 0x52,
+	0x9f, 0x43, 0xde, 0xb6, 0x8b, 0x72, 0x6c, 0x24, 0xa7, 0xb3, 0xfd, 0xaa,
+	0xdc, 0xc7, 0xf9, 0xa2, 0x99, 0xc8, 0x7e, 0x42, 0xa9, 0x76, 0xc9, 0xa9,
+	0xfb, 0xe8, 0x93, 0x50, 0x7b, 0xb4, 0x13, 0xce, 0xf5, 0x73, 0xa6, 0x2a,
+	0xb1, 0xef, 0x06, 0x68, 0xf0, 0xbc, 0x49, 0x6a, 0xdd, 0xe7, 0xef, 0x0c,
+	0xfc, 0x0d, 0x04, 0xf1, 0x63, 0xd3, 0x6e, 0xd0, 0x43, 0xae, 0x71, 0x96,
+	0x2b, 0xac, 0xcb, 0x3a, 0x85, 0x79, 0x1f, 0x52, 0xd3, 0x6f, 0x33, 0xef,
+	0x66, 0x67, 0x99, 0x88, 0x1f, 0xc6, 0x5d, 0x9f, 0x73, 0xde, 0x97, 0x34,
+	0xba, 0x49, 0x12, 0x37, 0xad, 0x87, 0x91, 0x0b, 0x0f, 0x83, 0x26, 0x94,
+	0x98, 0x93, 0xf6, 0x15, 0x39, 0x8d, 0xa7, 0x0d, 0xf3, 0x58, 0xd6, 0x87,
+	0xdf, 0x43, 0xc4, 0x59, 0x25, 0x3b, 0x6f, 0xd0, 0x67, 0xdf, 0x87, 0xcf,
+	0xde, 0xc8, 0xf6, 0x00, 0x87, 0xed, 0x02, 0xf6, 0xb1, 0x8c, 0x8c, 0x2f,
+	0x4c, 0xb3, 0x65, 0x0c, 0xf3, 0x99, 0xdc, 0x81, 0xc7, 0x47, 0x03, 0x3c,
+	0x6c, 0xbe, 0x9b, 0x55, 0x4f, 0x7b, 0x6c, 0xf9, 0x57, 0x87, 0x9e, 0xd1,
+	0x93, 0xdc, 0xa7, 0xe2, 0x1e, 0x5c, 0x9b, 0xc5, 0x72, 0xfe, 0x97, 0xc5,
+	0x61, 0xbe, 0xa7, 0xb2, 0x73, 0xfc, 0x34, 0x36, 0x3c, 0x8c, 0xc9, 0x8d,
+	0x01, 0xd9, 0x8d, 0x1d, 0xce, 0xdd, 0xa5, 0xa3, 0x35, 0x50, 0xd8, 0xdf,
+	0xb4, 0x80, 0xf3, 0x33, 0x9e, 0xb7, 0xfd, 0x83, 0x7d, 0xf5, 0xb3, 0x7d,
+	0xd4, 0xf8, 0x9c, 0x3e, 0xfa, 0x72, 0x87, 0x71, 0x23, 0xf5, 0xd1, 0xfa,
+	0x1d, 0x3e, 0x8a, 0xfa, 0xc8, 0xce, 0xfd, 0x93, 0xe3, 0x25, 0xf7, 0xcf,
+	0xfc, 0x99, 0x63, 0x1c, 0xb8, 0x9c, 0xe1, 0x5c, 0x13, 0x38, 0x57, 0x95,
+	0x79, 0xcf, 0x2d, 0x57, 0x29, 0x8d, 0xe5, 0x55, 0xc4, 0x72, 0x55, 0xe3,
+	0x3c, 0xc8, 0x31, 0xcc, 0x74, 0x1c, 0xc7, 0x4c, 0x37, 0x96, 0xd1, 0x61,
+	0x44, 0x3c, 0x57, 0xb3, 0x78, 0x6e, 0x75, 0x5d, 0xa7, 0x9a, 0xc5, 0x73,
+	0x0b, 0x31, 0xdc, 0xce, 0xe2, 0xb9, 0x95, 0xc5, 0x33, 0x7f, 0xdf, 0xd3,
+	0x2a, 0x9c, 0x1b, 0x5d, 0x27, 0x06, 0xc6, 0xb5, 0x25, 0xcf, 0x06, 0xee,
+	0x09, 0x19, 0xbb, 0x79, 0x5c, 0xdc, 0xf1, 0x1d, 0x0c, 0xf7, 0xf9, 0x34,
+	0xd7, 0xd4, 0x90, 0x6b, 0x2e, 0x20, 0xd7, 0xf4, 0x06, 0xbe, 0x83, 0x9d,
+	0x97, 0xb9, 0xe6, 0xeb, 0xc5, 0x3c, 0xd7, 0xf4, 0xb2, 0x5c, 0xd3, 0x93,
+	0xb9, 0xe6, 0xab, 0x45, 0xce, 0x35, 0x4d, 0x3a, 0x5a, 0x1c, 0xcc, 0x35,
+	0xcd, 0xa1, 0x5c, 0x93, 0xd3, 0xf2, 0xfc, 0x4e, 0xb9, 0x26, 0xd7, 0xd9,
+	0xbd, 0x6a, 0x92, 0x7c, 0x0f, 0xcb, 0xca, 0xb8, 0xc4, 0x78, 0x9c, 0xd6,
+	0xfc, 0x57, 0x92, 0x3c, 0x96, 0x4e, 0xe3, 0x1c, 0xbc, 0x77, 0x77, 0x8a,
+	0x25, 0x33, 0x8b, 0xa5, 0xdd, 0x29, 0x4d, 0x77, 0x30, 0x9e, 0x4e, 0x17,
+	0x87, 0xe3, 0x29, 0xe7, 0x93, 0xc7, 0x53, 0xca, 0xf3, 0x3d, 0xad, 0xcc,
+	0x35, 0x02, 0xfa, 0x6d, 0xd7, 0x5f, 0xc0, 0xec, 0xa5, 0xfe, 0x2c, 0x6a,
+	0x6e, 0x9d, 0xae, 0xe6, 0x78, 0x23, 0xbf, 0x09, 0x61, 0xec, 0xe7, 0xb2,
+	0x16, 0xb7, 0xd7, 0x7a, 0xa8, 0xbb, 0xdf, 0x01, 0x8e, 0x5c, 0x94, 0xeb,
+	0x9f, 0x88, 0xab, 0x68, 0x09, 0xdb, 0x5e, 0xbe, 0xef, 0x17, 0x38, 0xcf,
+	0xb5, 0xce, 0xe3, 0xe9, 0xd9, 0x7e, 0xae, 0x13, 0x5e, 0xe7, 0xb9, 0xbf,
+	0x23, 0x9f, 0xa0, 0x66, 0xdf, 0xde, 0xcb, 0xfd, 0x8f, 0x87, 0x3b, 0x3b,
+	0xf4, 0xfa, 0x50, 0x0f, 0x94, 0xf6, 0x3e, 0x75, 0xf9, 0x8d, 0x97, 0x6b,
+	0x97, 0xe8, 0x0b, 0x2a, 0x9d, 0xa2, 0xaf, 0xf9, 0x3c, 0xa7, 0x52, 0xed,
+	0x31, 0x21, 0x9e, 0x41, 0x1d, 0xf3, 0xd4, 0x50, 0x1d, 0x53, 0xa4, 0x89,
+	0x47, 0x06, 0x7b, 0xc8, 0x2d, 0x31, 0x31, 0xed, 0x9e, 0x0f, 0x29, 0x54,
+	0x6a, 0x1b, 0x5c, 0xe7, 0x6e, 0xd7, 0xb5, 0x44, 0xfb, 0x6e, 0x09, 0x75,
+	0x9a, 0xf3, 0xe2, 0x6f, 0x33, 0x5d, 0x61, 0xed, 0xdc, 0x2d, 0x60, 0x6b,
+	0x55, 0x7e, 0x0b, 0x0e, 0x37, 0xf8, 0x1c, 0x7e, 0xc7, 0x98, 0x70, 0xcd,
+	0x73, 0xb7, 0xef, 0xb3, 0x3a, 0xec, 0xe2, 0x3a, 0xc7, 0x35, 0x92, 0xdf,
+	0x37, 0x56, 0x7c, 0xf7, 0xa7, 0x2d, 0x4a, 0x71, 0xa2, 0xea, 0x2f, 0x41,
+	0x16, 0xd4, 0x9d, 0xd6, 0x32, 0x6c, 0x33, 0x0d, 0x5c, 0x72, 0x9d, 0x47,
+	0x54, 0x5b, 0xe2, 0xf8, 0x2a, 0x78, 0x6b, 0x8f, 0x70, 0x4d, 0xf9, 0xb1,
+	0x58, 0xed, 0xcb, 0x7c, 0xec, 0xb3, 0x8f, 0xc4, 0xc9, 0x5e, 0x95, 0xc7,
+	0x30, 0xe1, 0xe7, 0x02, 0x71, 0x2d, 0xb9, 0xb3, 0xff, 0xd8, 0x56, 0xf5,
+	0x9c, 0x63, 0xd5, 0xba, 0x8e, 0xb5, 0xd0, 0x55, 0xe1, 0xdd, 0xfb, 0x4c,
+	0xda, 0x03, 0x9b, 0x20, 0x1f, 0xd3, 0x7d, 0x90, 0xe5, 0x92, 0x63, 0xc5,
+	0xa8, 0x0f, 0xbf, 0xa7, 0xb9, 0xd6, 0x53, 0xa4, 0x98, 0x54, 0xba, 0x25,
+	0xd2, 0x6f, 0x33, 0x8e, 0x55, 0xdd, 0x3e, 0xfb, 0x16, 0xce, 0x66, 0x99,
+	0x38, 0x46, 0x39, 0x5f, 0x2e, 0x2a, 0x4b, 0xd0, 0xd1, 0xb1, 0x8d, 0x5d,
+	0xc0, 0x35, 0xce, 0x97, 0x07, 0xb2, 0x6f, 0x50, 0xb0, 0x0f, 0xee, 0xff,
+	0xfa, 0x1d, 0xf5, 0x67, 0x5e, 0x67, 0x32, 0xbd, 0x10, 0xcd, 0x79, 0x3e,
+	0x9f, 0x20, 0xcb, 0xd4, 0xcc, 0x25, 0xd9, 0x13, 0xcd, 0xa2, 0xee, 0xe3,
+	0x51, 0xa0, 0x26, 0xe2, 0xef, 0x61, 0xae, 0x55, 0xc7, 0x73, 0x35, 0x7b,
+	0x6e, 0x72, 0xbf, 0x34, 0xcf, 0x3c, 0xb8, 0x6f, 0xe2, 0xf8, 0xf9, 0x27,
+	0x6e, 0xb7, 0x92, 0x82, 0x90, 0x18, 0x00, 0x00, 0x00 };
 
 static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 };
 static const u32 bnx2_TPAT_b09FwRodata[(0x0/4) + 1] = { 0x0 };
 
 static struct fw_info bnx2_tpat_fw_09 = {
+	/* Firmware version:  3.7.1 */
 	.ver_major			= 0x3,
-	.ver_minor			= 0x4,
-	.ver_fix			= 0x3,
+	.ver_minor			= 0x7,
+	.ver_fix			= 0x1,
 
 	.start_addr			= 0x08000860,
 
 	.text_addr			= 0x08000800,
-	.text_len			= 0x1864,
+	.text_len			= 0x188c,
 	.text_index			= 0x0,
 	.gz_text			= bnx2_TPAT_b09FwText,
 	.gz_text_len			= sizeof(bnx2_TPAT_b09FwText),
 
-	.data_addr			= 0x08002080,
+	.data_addr			= 0x080020c0,
 	.data_len			= 0x0,
 	.data_index			= 0x0,
 	.data				= bnx2_TPAT_b09FwData,
 
-	.sbss_addr			= 0x08002088,
-	.sbss_len			= 0x2c,
+	.sbss_addr			= 0x080020c8,
+	.sbss_len			= 0x30,
 	.sbss_index			= 0x0,
 
-	.bss_addr			= 0x080020c0,
+	.bss_addr			= 0x08002100,
 	.bss_len			= 0x850,
 	.bss_index			= 0x0,
 
@@ -3267,768 +3289,770 @@
 };
 
 static u8 bnx2_TXP_b09FwText[] = {
-/*	0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
-								    0xcd, 0x7c,
-	0x6f, 0x70, 0x5b, 0xd7, 0x95, 0xdf, 0x79, 0xef, 0x81, 0x24, 0x48, 0xd1,
-	0xd4, 0x13, 0x17, 0x56, 0x60, 0x87, 0x71, 0x00, 0xf1, 0x81, 0x66, 0x42,
-	0xae, 0x04, 0x2b, 0x4c, 0xc2, 0x6d, 0xd1, 0xf8, 0x05, 0x00, 0x29, 0x48,
-	0xd1, 0x6c, 0x68, 0x95, 0x49, 0x94, 0x54, 0xe3, 0x62, 0x41, 0x52, 0xf1,
-	0xb6, 0xce, 0x54, 0x9b, 0x78, 0x5a, 0x4d, 0xeb, 0xad, 0x11, 0x90, 0xfa,
-	0xe7, 0x85, 0x04, 0xda, 0x62, 0x44, 0x7f, 0xc8, 0x07, 0x18, 0x80, 0x24,
-	0x6f, 0xf2, 0x44, 0x28, 0x9b, 0x7f, 0xfd, 0xd0, 0xac, 0x50, 0x4a, 0xd6,
-	0xba, 0x9b, 0xb4, 0xa3, 0xed, 0x66, 0x67, 0x3b, 0xd3, 0x2f, 0x1c, 0x49,
-	0xf6, 0x7a, 0x77, 0x67, 0x36, 0xda, 0x6e, 0xb6, 0xab, 0xb6, 0xb2, 0xd1,
-	0xdf, 0xef, 0xbe, 0xf7, 0x28, 0x90, 0xa6, 0x6c, 0xcb, 0xb3, 0xed, 0x94,
-	0x33, 0x18, 0xe0, 0xdd, 0x77, 0xdf, 0xb9, 0xe7, 0x9e, 0x73, 0xee, 0x39,
-	0xe7, 0x77, 0xee, 0x7d, 0x0c, 0x8b, 0x74, 0x89, 0xf7, 0xf7, 0x00, 0x3e,
-	0x91, 0x43, 0x87, 0x9f, 0xd9, 0x3e, 0xb2, 0xfd, 0x13, 0xf8, 0xf9, 0x09,
-	0x31, 0x02, 0x06, 0x6f, 0xbe, 0x69, 0x88, 0x64, 0xff, 0x42, 0x3e, 0xf0,
-	0x1f, 0x1e, 0x37, 0x7d, 0xfa, 0xfc, 0x48, 0x50, 0x4f, 0x4c, 0xec, 0x4a,
-	0x5a, 0x12, 0x34, 0x12, 0xb2, 0x6f, 0xca, 0x12, 0xb1, 0x9d, 0xa1, 0x48,
-	0x4a, 0xde, 0x6a, 0xe6, 0x43, 0x01, 0x61, 0xfb, 0x47, 0x12, 0x77, 0x9e,
-	0xfb, 0xc9, 0xa7, 0xa3, 0xb7, 0xca, 0x86, 0x04, 0xcd, 0x44, 0x56, 0xcc,
-	0x01, 0x09, 0xf6, 0xe1, 0x99, 0x6f, 0x3f, 0x6a, 0x18, 0xd2, 0xb3, 0xca,
-	0xab, 0xcc, 0x95, 0x56, 0x9a, 0x3f, 0x79, 0x34, 0x2c, 0xbf, 0x57, 0x0f,
-	0xc9, 0xf7, 0xea, 0xa6, 0x5c, 0xac, 0x07, 0xb4, 0xf1, 0x92, 0x29, 0xb3,
-	0xa5, 0x69, 0xfd, 0x48, 0x31, 0x2f, 0xa9, 0x7a, 0x56, 0x2f, 0x2c, 0x98,
-	0x3d, 0xc9, 0xf3, 0x39, 0x7d, 0x76, 0xa1, 0xb7, 0x27, 0x75, 0x7e, 0x5a,
-	0x2f, 0x14, 0xc3, 0x3d, 0xc9, 0xba, 0xd9, 0x93, 0x5a, 0x0c, 0xe1, 0xba,
-	0xb7, 0x27, 0xb9, 0x18, 0x9d, 0x17, 0xd9, 0x8a, 0x3e, 0xe1, 0x9e, 0x54,
-	0x29, 0x9a, 0x15, 0xe9, 0x8f, 0xbf, 0x2a, 0x7d, 0x3d, 0xa9, 0xfa, 0x3f,
-	0xd1, 0x1b, 0xa6, 0x26, 0x85, 0x5f, 0x15, 0x33, 0x9c, 0xb8, 0xd5, 0x7c,
-	0xc8, 0xd2, 0xc4, 0xb4, 0x6e, 0x37, 0xb7, 0x58, 0x41, 0xc9, 0x9d, 0xee,
-	0x14, 0x5b, 0xcd, 0xc9, 0x94, 0xdc, 0xe2, 0x90, 0xb9, 0x2c, 0x6d, 0x62,
-	0x87, 0xfc, 0xeb, 0x66, 0x33, 0x19, 0xff, 0x32, 0xe5, 0x8a, 0x71, 0xa4,
-	0x67, 0xbc, 0x2e, 0x92, 0x2c, 0x05, 0x25, 0x19, 0x7f, 0xab, 0xe9, 0x3e,
-	0x13, 0xc4, 0x98, 0x81, 0x9e, 0xb1, 0x52, 0xb3, 0x99, 0x8e, 0x83, 0x7e,
-	0xdc, 0x7f, 0xb6, 0x4d, 0xca, 0x21, 0xbb, 0x3c, 0x1b, 0xff, 0x6f, 0xba,
-	0xab, 0x13, 0xce, 0x91, 0xd7, 0xb6, 0xe8, 0x56, 0x5e, 0x72, 0x21, 0x29,
-	0x17, 0xe2, 0x9f, 0x92, 0x13, 0xf1, 0x30, 0xe6, 0x17, 0x94, 0x63, 0x71,
-	0xc8, 0xd1, 0x3a, 0xac, 0x25, 0xeb, 0xd1, 0x48, 0x56, 0x9e, 0x97, 0xe4,
-	0x62, 0xbf, 0x99, 0x16, 0x8c, 0x6d, 0x35, 0x3f, 0x9a, 0x8c, 0x63, 0xbc,
-	0xe1, 0xff, 0xd5, 0xb4, 0x43, 0xd1, 0x6c, 0x59, 0x06, 0xa5, 0x50, 0xea,
-	0x8f, 0xff, 0x4c, 0x34, 0x09, 0x5a, 0x62, 0x4f, 0x59, 0x26, 0xe4, 0x16,
-	0x1d, 0x4c, 0x19, 0x4d, 0xd9, 0x83, 0xf1, 0x93, 0x16, 0xee, 0xd7, 0x65,
-	0xb3, 0x6e, 0xb5, 0x4b, 0xc1, 0x94, 0x50, 0x97, 0x3c, 0x22, 0x85, 0xd3,
-	0x68, 0x8f, 0xdb, 0xbd, 0x3a, 0x9e, 0xc9, 0x8c, 0xb0, 0x4d, 0x34, 0x23,
-	0x11, 0x33, 0x53, 0xe0, 0xa8, 0xe2, 0x0c, 0x62, 0xfc, 0x98, 0xdd, 0xa9,
-	0x99, 0xb2, 0x62, 0x06, 0xa4, 0xea, 0xc4, 0xec, 0xb0, 0xd6, 0x2e, 0xc7,
-	0x62, 0x5d, 0x90, 0x69, 0x18, 0xb4, 0xe5, 0x9b, 0x7a, 0x22, 0x16, 0xce,
-	0x41, 0x51, 0x3a, 0x64, 0x35, 0x07, 0x7e, 0xe6, 0xe2, 0x59, 0x2d, 0x55,
-	0xff, 0x8a, 0x96, 0x3c, 0xbf, 0x5f, 0xdb, 0x75, 0x1e, 0x7d, 0xea, 0xe7,
-	0x3c, 0xbb, 0x0b, 0x83, 0x37, 0x1d, 0xcf, 0xb2, 0x1d, 0x3c, 0x2b, 0xde,
-	0xd1, 0x06, 0x5d, 0x36, 0x26, 0x43, 0x3d, 0x49, 0xa5, 0x4b, 0xf2, 0xa6,
-	0x4b, 0x6e, 0x42, 0x93, 0x5e, 0xcb, 0x96, 0xe0, 0x27, 0xa1, 0xcf, 0x45,
-	0xe8, 0x72, 0x31, 0x22, 0x47, 0x4a, 0x12, 0xd2, 0x85, 0x63, 0x65, 0xf5,
-	0xaa, 0x43, 0x7b, 0x80, 0x6e, 0xa1, 0xfb, 0x82, 0xc3, 0x67, 0xa1, 0xc3,
-	0x52, 0x1a, 0xf2, 0xc9, 0x60, 0xec, 0x7d, 0xda, 0x9e, 0xea, 0xa4, 0x96,
-	0x81, 0x9d, 0x14, 0x4e, 0x0f, 0x41, 0x77, 0xd1, 0xc8, 0x8a, 0x6c, 0x96,
-	0x82, 0x65, 0x45, 0xbe, 0x2c, 0xdd, 0x72, 0x6c, 0xd1, 0x92, 0x23, 0x8b,
-	0x21, 0xc9, 0x9b, 0x51, 0xb3, 0x26, 0x7d, 0xd9, 0x4d, 0x89, 0x1e, 0x79,
-	0xfe, 0x74, 0x34, 0x53, 0x96, 0x7e, 0xfb, 0x75, 0xdc, 0xcf, 0x9d, 0xa4,
-	0x4e, 0x25, 0x9f, 0x8a, 0x1b, 0x92, 0x85, 0x4d, 0x18, 0xd6, 0x1f, 0x81,
-	0xff, 0xe6, 0x73, 0xc9, 0x78, 0x34, 0x2c, 0xa2, 0x4b, 0xea, 0x0b, 0xfd,
-	0xe6, 0x6e, 0x89, 0x9a, 0x19, 0xca, 0x3f, 0x3e, 0x04, 0x3d, 0xfc, 0x77,
-	0xca, 0x1e, 0xb4, 0xa8, 0xe3, 0xa1, 0xf0, 0x31, 0xe8, 0x32, 0xab, 0x74,
-	0xdc, 0x83, 0xf1, 0x03, 0x9e, 0xed, 0xf4, 0x48, 0xbe, 0x7a, 0xc3, 0x93,
-	0x43, 0x8f, 0xcc, 0x57, 0xbb, 0xa5, 0x00, 0x1d, 0x16, 0xc4, 0x92, 0xc2,
-	0xf9, 0x3f, 0xf7, 0xda, 0x2d, 0x99, 0x3b, 0xff, 0x32, 0xec, 0xe1, 0xb0,
-	0xb6, 0xbf, 0xfe, 0x0b, 0xcd, 0xb3, 0x1f, 0xd8, 0x5f, 0x50, 0xec, 0x89,
-	0xa0, 0x9c, 0xab, 0xbb, 0xf6, 0x57, 0xc1, 0x1a, 0xb3, 0x4d, 0x1b, 0xb6,
-	0xf4, 0xc6, 0x6a, 0x9f, 0x73, 0xf5, 0x3e, 0x3c, 0x1b, 0x94, 0x23, 0x75,
-	0xf6, 0xcf, 0xc3, 0xc6, 0x82, 0xb2, 0xf4, 0x68, 0xb7, 0x64, 0xd1, 0x5e,
-	0x58, 0x14, 0x3b, 0x19, 0xd7, 0xf1, 0x4c, 0x0f, 0xe6, 0xb2, 0x15, 0x9f,
-	0x2e, 0x99, 0xaa, 0x76, 0xd8, 0x86, 0x15, 0x92, 0xa9, 0x3a, 0xf5, 0x8f,
-	0xef, 0x92, 0x6f, 0x03, 0x94, 0x2f, 0xdb, 0xf9, 0x1c, 0xdb, 0x4d, 0xb4,
-	0xb7, 0xb6, 0xd1, 0xb6, 0x37, 0x53, 0xa6, 0x83, 0x82, 0xb6, 0x5c, 0x29,
-	0x66, 0xee, 0xe7, 0x77, 0x9d, 0xf6, 0xd0, 0x6a, 0x0b, 0x01, 0xf4, 0x87,
-	0x1e, 0xab, 0x18, 0xeb, 0xf4, 0x9d, 0x66, 0xdb, 0x08, 0xae, 0x2d, 0x2c,
-	0xaa, 0x2e, 0x8e, 0x1d, 0x00, 0x5f, 0xba, 0x64, 0xab, 0x8a, 0xb7, 0x08,
-	0x6d, 0xc0, 0x9d, 0x47, 0x9f, 0xcc, 0x2e, 0x76, 0xf7, 0xa4, 0x17, 0xd9,
-	0x9e, 0x0c, 0x1b, 0x98, 0xe7, 0x54, 0x5c, 0x1a, 0x73, 0x71, 0xbd, 0x3f,
-	0x00, 0xbe, 0xa6, 0xb1, 0xe0, 0x30, 0x0f, 0x8f, 0xc7, 0x06, 0xee, 0xf7,
-	0xca, 0xd4, 0x79, 0xf6, 0xe5, 0x18, 0x85, 0x2d, 0xba, 0x24, 0xc0, 0x1b,
-	0x3e, 0x56, 0x14, 0xf7, 0x3b, 0x31, 0x4e, 0x37, 0x6c, 0x27, 0x83, 0x31,
-	0x9b, 0x8f, 0x27, 0xe3, 0xbd, 0x92, 0x5d, 0xed, 0x2b, 0xb0, 0x3b, 0xf6,
-	0x1f, 0x5c, 0xd7, 0x17, 0xf2, 0x3d, 0x0f, 0x9a, 0x8b, 0x9d, 0x90, 0x21,
-	0xdb, 0x75, 0xf0, 0xdc, 0x01, 0x1e, 0x82, 0x98, 0x4f, 0x3f, 0xd6, 0x43,
-	0x07, 0xe8, 0x6f, 0xc2, 0x9c, 0x3a, 0x65, 0xfa, 0x74, 0x2f, 0x74, 0x61,
-	0xa2, 0x6f, 0x50, 0x9e, 0x2f, 0x45, 0x61, 0x03, 0xec, 0x0f, 0x1d, 0x2c,
-	0x46, 0xc3, 0x55, 0xb1, 0x65, 0x2e, 0xde, 0x01, 0xfb, 0x6a, 0x36, 0x67,
-	0x60, 0x1f, 0xdf, 0x51, 0xfe, 0x62, 0xc8, 0x1c, 0xd3, 0x24, 0xdf, 0x91,
-	0x38, 0x0c, 0x7e, 0xa2, 0x4f, 0x89, 0xf0, 0x7a, 0x87, 0xc6, 0x35, 0x0b,
-	0x39, 0x72, 0x6c, 0xf8, 0xa4, 0xad, 0x90, 0x21, 0xfd, 0x56, 0x1f, 0xec,
-	0x39, 0xac, 0xfc, 0xc9, 0xd8, 0x86, 0xfe, 0x24, 0x3a, 0x51, 0xc6, 0x58,
-	0x85, 0xf3, 0x01, 0xfa, 0xb0, 0x51, 0x2c, 0x57, 0x79, 0x00, 0x6b, 0x6f,
-	0x56, 0xd9, 0xc7, 0x09, 0xce, 0xb7, 0xf9, 0xf9, 0x38, 0xf9, 0xe2, 0x7c,
-	0x6d, 0x3c, 0x4b, 0x1b, 0x8c, 0x1e, 0xb6, 0xd5, 0xf8, 0x27, 0xbc, 0xf1,
-	0x5d, 0xde, 0x0b, 0xa5, 0x1e, 0x2d, 0xa5, 0x78, 0xf0, 0xe9, 0x88, 0x2c,
-	0x9f, 0xec, 0x37, 0xf7, 0xc0, 0x86, 0xe9, 0xa7, 0x96, 0x2f, 0x50, 0xc7,
-	0xa0, 0x31, 0x42, 0x1d, 0x9b, 0x8a, 0xbf, 0xe4, 0x22, 0xd7, 0x9e, 0xf4,
-	0x19, 0x42, 0x1f, 0x01, 0x9f, 0x8b, 0xb5, 0x38, 0xeb, 0xad, 0xc5, 0x9c,
-	0x43, 0xfb, 0x7b, 0x06, 0xcf, 0xea, 0x32, 0x16, 0xa3, 0x7f, 0x78, 0x5e,
-	0x52, 0xf0, 0x91, 0xd0, 0xa3, 0x54, 0x31, 0x97, 0x4a, 0xa9, 0xd5, 0x6f,
-	0xc1, 0xb6, 0x86, 0xff, 0xae, 0xe9, 0xfa, 0x43, 0xfa, 0x06, 0xfa, 0x9a,
-	0x82, 0xa9, 0x43, 0x72, 0x3a, 0x9c, 0x21, 0x74, 0x13, 0x4f, 0x1a, 0xd1,
-	0x4c, 0x16, 0x7c, 0x4d, 0x59, 0x4d, 0xb1, 0x1e, 0x13, 0x44, 0x0c, 0xf4,
-	0xa9, 0xcb, 0x4e, 0xdf, 0x3f, 0x2d, 0x3b, 0xbe, 0x2e, 0xa8, 0x57, 0xea,
-	0xc1, 0xf7, 0x11, 0x01, 0xb9, 0x0c, 0xdf, 0x35, 0x57, 0xea, 0x96, 0x06,
-	0x78, 0xba, 0xe2, 0xf8, 0xb6, 0x66, 0x78, 0xb6, 0xc6, 0x67, 0xba, 0xf1,
-	0x7c, 0x00, 0x7e, 0x4d, 0xf2, 0x46, 0x02, 0xbf, 0x8b, 0xa4, 0xc9, 0x36,
-	0xdf, 0xce, 0xb9, 0x66, 0xa2, 0x76, 0x59, 0xda, 0x25, 0x13, 0x43, 0xfc,
-	0x58, 0xd4, 0x31, 0x56, 0x1f, 0x7c, 0x79, 0x40, 0x0e, 0x96, 0x42, 0xf2,
-	0xd5, 0x12, 0xe7, 0x95, 0xd6, 0x52, 0xd0, 0x5b, 0x72, 0xb1, 0x09, 0x9d,
-	0x8f, 0xc3, 0xe7, 0x65, 0xb4, 0x31, 0xf8, 0x9f, 0xdd, 0xd5, 0xaf, 0x68,
-	0xe9, 0xf3, 0x59, 0x6d, 0xbc, 0xbe, 0x5f, 0xcb, 0x9c, 0x9f, 0xd4, 0x76,
-	0xb5, 0xf8, 0x22, 0xd1, 0xde, 0xdd, 0x17, 0x9d, 0x38, 0xcd, 0x31, 0xfb,
-	0xe3, 0x1b, 0xfb, 0xa2, 0x5f, 0x6a, 0xad, 0xbe, 0xa8, 0x1f, 0xbe, 0x28,
-	0x03, 0x5f, 0x34, 0x7e, 0xdf, 0xbe, 0xa8, 0x5d, 0xdf, 0xd8, 0x17, 0x75,
-	0xeb, 0x77, 0x7d, 0x11, 0x63, 0xcf, 0xbf, 0xc6, 0xb5, 0x29, 0xdb, 0x76,
-	0xfa, 0x72, 0x0e, 0xc3, 0x0f, 0x6f, 0x82, 0xac, 0xbb, 0xb8, 0x76, 0x22,
-	0x05, 0xd8, 0xfd, 0x34, 0xc6, 0xfa, 0x4d, 0xd8, 0xfb, 0xb6, 0x98, 0x65,
-	0x3e, 0xa1, 0xc6, 0x7d, 0xa7, 0xce, 0xc7, 0x56, 0x75, 0x4e, 0x1e, 0xdf,
-	0x53, 0xe7, 0xb6, 0xab, 0x73, 0xea, 0xba, 0x53, 0x66, 0xd4, 0xb8, 0x4d,
-	0x09, 0x3c, 0x26, 0xf0, 0x2a, 0xf2, 0x59, 0x23, 0x11, 0x05, 0x3d, 0x1d,
-	0xe3, 0x53, 0x5f, 0x31, 0xf0, 0x20, 0xd0, 0x6f, 0xb7, 0xf2, 0x45, 0xbb,
-	0xa0, 0xf7, 0x65, 0xe7, 0xfe, 0x74, 0x95, 0x69, 0xd1, 0xd5, 0x9e, 0x35,
-	0xba, 0xea, 0x90, 0xe1, 0x98, 0xaf, 0xa3, 0xcd, 0x92, 0x8c, 0x51, 0x67,
-	0xf7, 0xa3, 0xab, 0x7f, 0xaa, 0xff, 0xfd, 0xe8, 0xea, 0xb7, 0xee, 0xa1,
-	0xab, 0x7f, 0xb5, 0x4e, 0x57, 0x96, 0xf9, 0x82, 0x46, 0xda, 0x8c, 0x1f,
-	0xf4, 0x47, 0xcd, 0x8f, 0x4e, 0x31, 0x7f, 0xa8, 0x73, 0x4d, 0xfb, 0x79,
-	0x07, 0xd7, 0xf3, 0xa5, 0xa6, 0x61, 0x59, 0x90, 0x1d, 0xd7, 0x34, 0xe5,
-	0x16, 0x35, 0x3f, 0x4f, 0xfe, 0x11, 0x3b, 0xa6, 0x10, 0x6b, 0x5c, 0x1e,
-	0xda, 0xa5, 0xbc, 0xc5, 0xed, 0x3f, 0x55, 0x6a, 0xfe, 0x42, 0x4f, 0xbc,
-	0xdd, 0x4c, 0x8e, 0x58, 0x5e, 0x1c, 0x08, 0xca, 0xd7, 0xaa, 0xd1, 0xac,
-	0xad, 0x75, 0x4b, 0xfe, 0x41, 0xc4, 0x9e, 0x12, 0xfd, 0xd7, 0xd6, 0x7b,
-	0xc4, 0xe8, 0x3e, 0x2f, 0x46, 0x57, 0xc1, 0x2b, 0xf3, 0xab, 0xef, 0xbe,
-	0xd5, 0x08, 0xf1, 0x3b, 0x66, 0xee, 0x93, 0x2f, 0x73, 0x8e, 0x88, 0xf7,
-	0x8c, 0xfb, 0x16, 0x73, 0x9e, 0x7c, 0x20, 0xd1, 0x25, 0xf9, 0x2d, 0x5c,
-	0x8f, 0xf4, 0x73, 0xf4, 0x5d, 0xed, 0x1e, 0xdf, 0x7e, 0x8e, 0xa4, 0x78,
-	0x33, 0x30, 0x65, 0xf4, 0x41, 0x3e, 0x54, 0xe2, 0x3c, 0xde, 0xf2, 0xec,
-	0x89, 0xb9, 0x82, 0xb4, 0xb9, 0xbe, 0x61, 0x2f, 0x72, 0x01, 0xda, 0x81,
-	0xaf, 0x73, 0xea, 0x9b, 0x39, 0x82, 0x44, 0x74, 0x8b, 0x39, 0x82, 0x98,
-	0x46, 0x62, 0x9f, 0x66, 0x43, 0xf7, 0x36, 0x74, 0x6f, 0x43, 0xf7, 0x36,
-	0x74, 0x9f, 0xac, 0x1f, 0xc6, 0x3d, 0x95, 0x87, 0x80, 0x17, 0x97, 0x7e,
-	0xda, 0xa5, 0x0f, 0x3e, 0xb7, 0x4a, 0x4e, 0xe9, 0x84, 0xf3, 0x45, 0xae,
-	0xa1, 0xfc, 0xf5, 0xb8, 0xe6, 0xfa, 0x6b, 0xd2, 0xcb, 0xe0, 0xf9, 0xdb,
-	0x98, 0xa7, 0xad, 0xeb, 0xd6, 0x5d, 0x99, 0xcc, 0xb5, 0xc8, 0x64, 0xd6,
-	0xa1, 0x8c, 0xd8, 0x9f, 0x3e, 0x77, 0x5a, 0xaf, 0xac, 0xca, 0x65, 0x2f,
-	0x78, 0xe8, 0xe0, 0xdc, 0xbd, 0x79, 0x90, 0x7e, 0xaf, 0x47, 0xff, 0x6f,
-	0xd1, 0x87, 0xfe, 0x75, 0xa3, 0x71, 0x39, 0x26, 0x73, 0xc6, 0x77, 0x9b,
-	0x0f, 0x72, 0x66, 0xac, 0x81, 0xef, 0x21, 0x96, 0x5f, 0x44, 0x2c, 0x59,
-	0x31, 0x22, 0xf2, 0x93, 0x47, 0xaf, 0x21, 0x97, 0x96, 0xfc, 0xc3, 0x89,
-	0x66, 0x24, 0x90, 0x78, 0xab, 0x39, 0x37, 0x82, 0x18, 0x97, 0x88, 0x86,
-	0x93, 0xc6, 0xb0, 0x5c, 0xaa, 0x0f, 0xca, 0x8f, 0xea, 0x96, 0xfc, 0xb0,
-	0x1e, 0x91, 0x1f, 0x20, 0xe6, 0x7f, 0xbf, 0xde, 0x9a, 0x73, 0x47, 0x68,
-	0x4f, 0x3d, 0xe9, 0xfa, 0x46, 0xb9, 0x7f, 0x13, 0x34, 0xde, 0x82, 0x9d,
-	0x04, 0xb2, 0xc8, 0xf5, 0x19, 0xbf, 0x26, 0x0e, 0x15, 0x9f, 0x6b, 0x82,
-	0xb7, 0x6c, 0x5b, 0xc2, 0xca, 0xeb, 0x7a, 0xf7, 0xa8, 0xf9, 0x29, 0xb4,
-	0x39, 0xa3, 0x81, 0x6a, 0xb1, 0x53, 0xe5, 0x8b, 0xd0, 0x91, 0xd8, 0xf5,
-	0x60, 0xb0, 0x56, 0xbc, 0x85, 0x7e, 0xcd, 0xe6, 0xa1, 0xf8, 0x6f, 0xed,
-	0x30, 0xff, 0x81, 0x85, 0x35, 0xdd, 0xf9, 0x25, 0x23, 0xb1, 0x49, 0x66,
-	0x43, 0xdf, 0x6f, 0x98, 0x03, 0x7d, 0x59, 0x3d, 0x11, 0x94, 0x74, 0x91,
-	0x6b, 0x2a, 0x24, 0xb3, 0x55, 0x28, 0xff, 0x3c, 0xd7, 0x85, 0x3c, 0x3b,
-	0x17, 0xef, 0x86, 0xed, 0xff, 0x9a, 0xe1, 0xae, 0x03, 0x18, 0x50, 0x75,
-	0x50, 0xf2, 0xe0, 0x37, 0x5f, 0x7f, 0xcb, 0xc3, 0x0e, 0xf0, 0x2a, 0x5b,
-	0x21, 0xf8, 0xc4, 0x70, 0xda, 0x76, 0xfe, 0x30, 0x88, 0xb6, 0xe0, 0x56,
-	0xeb, 0xce, 0x26, 0x7c, 0x3f, 0x10, 0xb2, 0x88, 0x4d, 0x24, 0xf3, 0x05,
-	0x7c, 0xff, 0x4a, 0x42, 0x36, 0xf7, 0xe2, 0x7b, 0x4b, 0x02, 0x26, 0x99,
-	0x60, 0xcc, 0xd5, 0x5a, 0x62, 0xae, 0x68, 0x69, 0xc8, 0x6e, 0x0e, 0x73,
-	0x4f, 0x43, 0x9e, 0x5f, 0xac, 0x07, 0xb5, 0xd4, 0xe9, 0x47, 0xc0, 0x87,
-	0x9f, 0x3b, 0x23, 0x3f, 0x33, 0x97, 0xb7, 0x04, 0xe4, 0x16, 0x7c, 0x5c,
-	0x12, 0x7e, 0xcc, 0x46, 0x6e, 0xb1, 0x03, 0xcb, 0x35, 0xfa, 0x5f, 0xbf,
-	0x20, 0x5f, 0xf3, 0x78, 0x6b, 0x93, 0x05, 0x65, 0xa3, 0x6c, 0xcf, 0x67,
-	0xfe, 0xcd, 0xc0, 0xdd, 0xf6, 0x17, 0x57, 0xdb, 0xcb, 0x99, 0x7f, 0xb8,
-	0xda, 0xde, 0xdb, 0xe6, 0xf2, 0x3f, 0xaa, 0x4d, 0xd4, 0xf7, 0x78, 0x6d,
-	0xb7, 0xa1, 0xb3, 0x66, 0x93, 0xb9, 0x45, 0x01, 0xd8, 0x24, 0x1d, 0xa7,
-	0x2f, 0xbe, 0x1f, 0x5f, 0xbb, 0xc6, 0xcf, 0x9a, 0x49, 0x83, 0xb6, 0x10,
-	0x14, 0x97, 0x26, 0xef, 0x77, 0x20, 0x7f, 0xbf, 0x8d, 0xdf, 0x8c, 0xa3,
-	0x7e, 0x6e, 0xce, 0x3e, 0x7c, 0xfe, 0xcd, 0x7b, 0xd8, 0x4b, 0x08, 0xf6,
-	0xf2, 0xff, 0xab, 0x5d, 0x5c, 0xba, 0x1f, 0xbb, 0xc0, 0x9f, 0xb2, 0x0b,
-	0xd5, 0xff, 0xd2, 0xea, 0x5a, 0x09, 0x43, 0x3e, 0x8c, 0x07, 0x83, 0xd0,
-	0xf1, 0x66, 0x99, 0xb5, 0xc8, 0x8f, 0x15, 0xc9, 0xc1, 0x5f, 0x9e, 0x58,
-	0x17, 0xbb, 0xbb, 0x10, 0x0f, 0x8e, 0x9f, 0x8e, 0x8e, 0x32, 0x1e, 0xc4,
-	0xe0, 0x1b, 0x93, 0xef, 0x88, 0x07, 0x37, 0x8c, 0xd6, 0x78, 0x60, 0x20,
-	0x1e, 0xec, 0x7a, 0x97, 0x78, 0x70, 0xe2, 0x1d, 0xf1, 0x40, 0x83, 0x6c,
-	0x38, 0xbf, 0xbf, 0x35, 0xfc, 0x78, 0x50, 0x58, 0x13, 0x0f, 0x7c, 0x5d,
-	0x59, 0x0a, 0x0b, 0xdc, 0xd5, 0x5b, 0x97, 0xa7, 0x2b, 0x09, 0x06, 0x12,
-	0x8d, 0xcc, 0x9c, 0xf5, 0xb0, 0xb4, 0xc1, 0xe7, 0x5e, 0xaa, 0x8f, 0x40,
-	0x67, 0x97, 0x30, 0xf7, 0x68, 0x9c, 0x89, 0x65, 0x5b, 0x82, 0xeb, 0xe1,
-	0xcd, 0x08, 0x30, 0xe2, 0x6e, 0xe0, 0xbe, 0xdd, 0x67, 0xd5, 0xfa, 0x78,
-	0x33, 0xea, 0x61, 0xf7, 0x6d, 0xc0, 0xee, 0x78, 0x3e, 0x00, 0x4c, 0xc8,
-	0xf6, 0x2b, 0x66, 0x12, 0x7a, 0xaa, 0x3a, 0xf6, 0xee, 0x02, 0x3e, 0x73,
-	0xaa, 0xef, 0xad, 0x08, 0xfb, 0x76, 0x24, 0x12, 0xd1, 0x3f, 0xc3, 0x77,
-	0x7b, 0x22, 0xbc, 0xed, 0xaa, 0x45, 0xba, 0x87, 0xa2, 0x67, 0x15, 0x8d,
-	0x80, 0x14, 0xd4, 0xb3, 0x91, 0x6d, 0x7c, 0xf6, 0x18, 0x62, 0xf6, 0x51,
-	0xc7, 0x94, 0x23, 0x4e, 0x76, 0x77, 0x0e, 0x1f, 0x62, 0xd5, 0x4b, 0x25,
-	0xde, 0x1f, 0xc5, 0xfd, 0x80, 0x30, 0x97, 0xfc, 0x2a, 0xfa, 0x1c, 0x44,
-	0x9f, 0x19, 0xc7, 0xd7, 0x05, 0xef, 0x37, 0x32, 0x29, 0xdc, 0x9f, 0x29,
-	0x36, 0x32, 0xe9, 0x22, 0xf3, 0xd6, 0xa1, 0xf0, 0x11, 0xc8, 0x33, 0x8b,
-	0x5c, 0xcd, 0x96, 0xe8, 0x60, 0x5e, 0x9e, 0xee, 0x1c, 0x07, 0x4e, 0x3a,
-	0x87, 0x1c, 0xc2, 0x9e, 0x8c, 0xc6, 0xcb, 0xf2, 0xe1, 0xce, 0xe4, 0x69,
-	0xe4, 0x0b, 0xf1, 0xed, 0x90, 0x61, 0x23, 0xa3, 0xc7, 0x04, 0xb6, 0x1e,
-	0x87, 0x5f, 0x1e, 0xd1, 0x53, 0xc5, 0x7e, 0x73, 0x56, 0x1e, 0x95, 0x86,
-	0x19, 0x0d, 0x8f, 0xcb, 0x26, 0x49, 0x05, 0xd0, 0x6f, 0xf0, 0x43, 0x92,
-	0x0d, 0x53, 0xd6, 0x0f, 0xc2, 0xdf, 0x6b, 0xd2, 0x61, 0xb5, 0xc6, 0x9e,
-	0x5b, 0x10, 0x6f, 0x2e, 0x40, 0x9f, 0xdd, 0x61, 0x75, 0x7a, 0x3a, 0xd9,
-	0x24, 0xcb, 0xef, 0xe8, 0x77, 0xbb, 0xa5, 0x5f, 0x6b, 0xfb, 0xdb, 0x68,
-	0xdf, 0x84, 0x9c, 0xb3, 0x91, 0x09, 0xc4, 0x20, 0x7f, 0xcc, 0xa1, 0x0d,
-	0x76, 0x72, 0x15, 0xf3, 0x61, 0x1c, 0x2c, 0x94, 0x99, 0xf7, 0x18, 0x52,
-	0x36, 0x71, 0xcf, 0x69, 0x36, 0x2b, 0x16, 0xf8, 0xbd, 0x40, 0x9e, 0x83,
-	0x32, 0xee, 0x0c, 0x88, 0x5d, 0xa3, 0x1c, 0xa2, 0xf0, 0x4a, 0x0f, 0x77,
-	0xa5, 0x16, 0xa3, 0x76, 0x1e, 0x14, 0x8d, 0x0b, 0x7d, 0x5d, 0x49, 0xe4,
-	0x39, 0xfa, 0x85, 0x48, 0x57, 0x0a, 0x36, 0x6b, 0x5c, 0x78, 0xa8, 0x2b,
-	0x7d, 0x9a, 0x7c, 0x19, 0xc8, 0x73, 0x3e, 0x0a, 0x9c, 0xdf, 0x94, 0xdf,
-	0x45, 0x2e, 0x5b, 0x18, 0x44, 0x0e, 0x80, 0xd5, 0xaf, 0x83, 0xef, 0xbc,
-	0x29, 0xc1, 0xae, 0xc4, 0xab, 0xe0, 0x6f, 0x18, 0xb2, 0xd9, 0x84, 0x3e,
-	0x06, 0xda, 0x07, 0x58, 0x13, 0x68, 0x69, 0xb7, 0xba, 0x10, 0x4f, 0x11,
-	0xbb, 0x24, 0x98, 0x1c, 0xe9, 0x06, 0xfd, 0x2b, 0x01, 0xe6, 0x82, 0xc1,
-	0xd8, 0x6a, 0xfb, 0x37, 0xdd, 0xf6, 0x41, 0xf0, 0xc2, 0xe7, 0x88, 0x09,
-	0x24, 0x38, 0x35, 0x62, 0x82, 0x07, 0xf6, 0x0d, 0xa9, 0xbe, 0xe9, 0x45,
-	0xda, 0x40, 0x23, 0x53, 0xb1, 0x1e, 0x91, 0xd4, 0xc2, 0x56, 0x19, 0x5f,
-	0xe8, 0x95, 0x5d, 0x0b, 0xc4, 0x30, 0xac, 0x69, 0x60, 0x2a, 0xc0, 0x18,
-	0xfa, 0x05, 0xe6, 0x76, 0xd1, 0xf0, 0x41, 0xe9, 0x0f, 0x7f, 0x15, 0xeb,
-	0x60, 0xca, 0x8a, 0x45, 0x66, 0xb1, 0xc6, 0x02, 0x8a, 0x4e, 0xd8, 0x1f,
-	0x93, 0x36, 0xba, 0x66, 0xdc, 0xf4, 0xe2, 0xbd, 0xe8, 0x62, 0xe1, 0x5c,
-	0x08, 0xaf, 0xa3, 0xfb, 0x57, 0x1e, 0x5d, 0x13, 0x74, 0xfb, 0x40, 0x93,
-	0x73, 0x7c, 0xa8, 0x73, 0xec, 0xb4, 0xd8, 0x1d, 0xe0, 0x2f, 0x1d, 0x7b,
-	0x58, 0x66, 0x41, 0xe7, 0xe8, 0x02, 0xfd, 0xa4, 0x6c, 0xc5, 0x67, 0xb8,
-	0x4d, 0x62, 0x83, 0xe7, 0x81, 0x73, 0xc6, 0x14, 0x0d, 0x17, 0x73, 0xe8,
-	0x17, 0x12, 0xc0, 0xa9, 0x1f, 0x07, 0x3f, 0xcc, 0xb1, 0x38, 0xe7, 0x00,
-	0xe6, 0x9b, 0xc0, 0x3a, 0x64, 0x7d, 0x85, 0xeb, 0x1b, 0xbf, 0xcf, 0x87,
-	0x3b, 0x53, 0xa7, 0xdb, 0xb1, 0xee, 0xe4, 0x11, 0x43, 0xc5, 0x7e, 0xea,
-	0xc5, 0xea, 0x4c, 0x96, 0x14, 0xdf, 0x9d, 0xa9, 0x12, 0x65, 0x14, 0xef,
-	0x4c, 0x97, 0x28, 0x23, 0x01, 0x3f, 0x71, 0xd8, 0x64, 0x40, 0x22, 0x5b,
-	0xa8, 0xc7, 0x43, 0xe8, 0xf7, 0x57, 0x01, 0xe2, 0xb8, 0xa4, 0xc5, 0xdf,
-	0xf0, 0xb5, 0x17, 0x0e, 0xa3, 0x2f, 0x7f, 0x6f, 0x07, 0xdd, 0xfe, 0xc1,
-	0x82, 0xb4, 0x0f, 0xce, 0xc0, 0x4f, 0xe8, 0x23, 0xc0, 0x91, 0xca, 0xce,
-	0x9b, 0xc0, 0xd8, 0x3b, 0x30, 0x1f, 0xac, 0x8d, 0x98, 0x25, 0xd3, 0xf3,
-	0x94, 0xab, 0x7c, 0x08, 0x73, 0xc0, 0xfc, 0x63, 0xf0, 0x2d, 0x9c, 0x03,
-	0xc7, 0x16, 0xe4, 0x36, 0x4b, 0x92, 0x9b, 0x0f, 0x2a, 0x2c, 0x6b, 0x9b,
-	0x1c, 0x5f, 0xd3, 0xf4, 0x44, 0x17, 0x74, 0xcc, 0xb9, 0xcd, 0x81, 0xb7,
-	0x67, 0x10, 0xff, 0xa2, 0x0a, 0x43, 0x19, 0x17, 0xb8, 0x56, 0x46, 0xb1,
-	0x4e, 0xc8, 0xbf, 0x67, 0x7b, 0x5a, 0x03, 0x3e, 0x45, 0xf9, 0x7f, 0xe4,
-	0xea, 0x09, 0xf8, 0x91, 0x51, 0xf9, 0x7d, 0xf8, 0x92, 0x1f, 0xd7, 0xe3,
-	0xc8, 0x1b, 0x86, 0x91, 0x37, 0x0c, 0x22, 0x6f, 0xb0, 0x90, 0x37, 0x44,
-	0x90, 0x37, 0xf4, 0x21, 0x6f, 0x08, 0x23, 0x3e, 0x88, 0x1c, 0xad, 0xe7,
-	0x61, 0x63, 0x0d, 0xf8, 0x41, 0x33, 0x68, 0xd7, 0x43, 0xc1, 0x64, 0x3d,
-	0x1c, 0x4c, 0xd5, 0x03, 0x98, 0xd3, 0x01, 0x8e, 0x89, 0xf9, 0xe5, 0x3b,
-	0xc7, 0x4a, 0xc3, 0x88, 0x39, 0x36, 0xfc, 0x52, 0x1a, 0xf1, 0x36, 0x2e,
-	0x47, 0xf0, 0xcc, 0xf2, 0x7c, 0x04, 0xcf, 0x34, 0x25, 0x1d, 0x6f, 0x93,
-	0x59, 0x33, 0x0e, 0x1a, 0x5b, 0x94, 0x9d, 0x22, 0xdf, 0x6a, 0x83, 0x9d,
-	0x4a, 0xae, 0xc8, 0x7c, 0xab, 0x0f, 0xf4, 0x3a, 0x11, 0x97, 0xe9, 0x1f,
-	0xe8, 0x0b, 0xec, 0xdd, 0x5f, 0xb2, 0xb8, 0xe6, 0xba, 0xb4, 0xe4, 0xe9,
-	0xbc, 0x10, 0x6b, 0x22, 0x0e, 0xc2, 0x2e, 0xd8, 0x36, 0x81, 0xe7, 0xf8,
-	0xfb, 0x6d, 0xcf, 0xef, 0x7f, 0x24, 0x28, 0x30, 0xde, 0x4b, 0x8c, 0xf9,
-	0x16, 0xe8, 0x39, 0xad, 0xeb, 0xb5, 0xa6, 0x8b, 0xe5, 0xdf, 0x67, 0xfd,
-	0x8d, 0x35, 0xc7, 0xd7, 0xc0, 0x73, 0xbf, 0xb9, 0x8c, 0x1c, 0xd9, 0xde,
-	0xbf, 0x82, 0xdf, 0xad, 0xfd, 0xeb, 0xe8, 0xaf, 0xda, 0x82, 0x66, 0x22,
-	0xce, 0x7c, 0x18, 0x3e, 0x73, 0x10, 0xfe, 0xf1, 0x56, 0x46, 0x5f, 0xba,
-	0x89, 0x79, 0x42, 0x9e, 0xc5, 0x5b, 0x99, 0xc0, 0xc0, 0xb5, 0xe6, 0x8b,
-	0xc0, 0x37, 0x63, 0x4b, 0x23, 0x92, 0x5a, 0xea, 0x0f, 0x5f, 0x96, 0xce,
-	0xdb, 0xb6, 0x5c, 0x6b, 0xce, 0x3a, 0xd1, 0xe3, 0xb6, 0x10, 0x6f, 0x99,
-	0x52, 0x01, 0xa9, 0x6d, 0x3b, 0x3b, 0x88, 0x19, 0x2f, 0x8a, 0x1e, 0x91,
-	0xe4, 0x29, 0x5b, 0x46, 0x76, 0xfa, 0xb9, 0xfb, 0x9d, 0x0e, 0xe9, 0x42,
-	0xdb, 0x52, 0x04, 0x7d, 0x88, 0x53, 0x39, 0xef, 0x2c, 0xe6, 0xac, 0xb9,
-	0xcf, 0x78, 0xf5, 0xc9, 0x42, 0x09, 0x73, 0xaf, 0xdf, 0xca, 0x5c, 0x3e,
-	0x05, 0xec, 0x0e, 0x1d, 0x25, 0x4f, 0xb1, 0xae, 0xb0, 0x09, 0x72, 0x1a,
-	0x83, 0xad, 0xd0, 0x06, 0xfa, 0xf1, 0x6c, 0x53, 0xbe, 0x11, 0xa7, 0x5d,
-	0xbc, 0x04, 0x59, 0x82, 0x56, 0xc0, 0x9f, 0x0f, 0x70, 0xde, 0x3c, 0xe5,
-	0x17, 0x46, 0x6e, 0xce, 0xb1, 0x25, 0xd8, 0x99, 0x58, 0x9f, 0x77, 0xdf,
-	0xca, 0x2c, 0x9f, 0x02, 0xfd, 0x01, 0xd6, 0xde, 0xe0, 0xb3, 0x8b, 0xac,
-	0x1d, 0x32, 0x27, 0xdd, 0x05, 0x3d, 0xed, 0x55, 0xb5, 0xb8, 0x64, 0x35,
-	0x2e, 0xd6, 0x49, 0xfa, 0x2c, 0x89, 0x18, 0xd6, 0x7e, 0xe4, 0xaf, 0x62,
-	0xea, 0x89, 0x49, 0xdc, 0xa3, 0x3c, 0x35, 0xe4, 0x1c, 0xb8, 0x7f, 0x61,
-	0x45, 0xe9, 0xc4, 0x80, 0xee, 0x72, 0x3b, 0x99, 0x84, 0xc9, 0xbc, 0x91,
-	0x80, 0x2f, 0x1c, 0xe1, 0x1c, 0xd4, 0xd8, 0xc8, 0xc7, 0xb9, 0xfe, 0x30,
-	0x67, 0xd8, 0x55, 0x4b, 0x5e, 0xae, 0xfe, 0x66, 0x4b, 0x47, 0x60, 0xd3,
-	0x92, 0x6f, 0x43, 0x3e, 0x90, 0x1c, 0xc1, 0x6f, 0x38, 0x81, 0xa3, 0xd0,
-	0xe7, 0xd9, 0x11, 0xd6, 0x3f, 0x5f, 0x02, 0xb6, 0x27, 0xdf, 0xb1, 0xc8,
-	0x11, 0xb5, 0x86, 0x71, 0xed, 0x30, 0x97, 0xdb, 0x24, 0x97, 0xd5, 0xfc,
-	0x1e, 0x22, 0xf6, 0x80, 0x9e, 0xee, 0x67, 0x7e, 0xe3, 0xf7, 0x39, 0x3f,
-	0x97, 0x3e, 0x63, 0x57, 0xd2, 0x8a, 0x48, 0xaa, 0x78, 0xa9, 0x19, 0xb0,
-	0x2c, 0x60, 0x67, 0x57, 0x8f, 0x29, 0x27, 0x08, 0x3e, 0x58, 0x6b, 0xdb,
-	0xa9, 0x74, 0x09, 0x3e, 0x68, 0x3b, 0xf9, 0x60, 0x62, 0xb3, 0x9c, 0x9b,
-	0xef, 0x91, 0xca, 0xfc, 0xcf, 0xa5, 0x3a, 0xdf, 0x25, 0xe7, 0xe7, 0x9b,
-	0x72, 0x35, 0xae, 0x7c, 0x93, 0xd5, 0xae, 0xd6, 0xb5, 0x3c, 0xec, 0xd6,
-	0x61, 0x62, 0xa3, 0xd7, 0xe5, 0x79, 0x39, 0x57, 0x76, 0x79, 0xcf, 0xb4,
-	0xf0, 0x7e, 0x15, 0xb6, 0xf6, 0xaa, 0x45, 0xfe, 0x47, 0xa4, 0x52, 0x24,
-	0xef, 0xfb, 0x14, 0xef, 0xbb, 0x56, 0x79, 0x97, 0xac, 0x61, 0x91, 0xff,
-	0x8d, 0x78, 0xef, 0x90, 0xec, 0x56, 0xf2, 0x1f, 0xc1, 0xb3, 0xef, 0xb4,
-	0xbf, 0x8a, 0x73, 0xad, 0xb9, 0x5c, 0x6c, 0x53, 0x3c, 0x1b, 0x89, 0x11,
-	0xc8, 0xe7, 0x5a, 0xb3, 0xe1, 0x70, 0x1d, 0xe1, 0xb7, 0xf3, 0x2f, 0xe0,
-	0xab, 0x7a, 0x55, 0xce, 0x92, 0x9b, 0xec, 0xee, 0x4c, 0x2e, 0x8e, 0x42,
-	0xb7, 0x9d, 0x6a, 0x1d, 0xc2, 0x6d, 0x40, 0x67, 0xff, 0x1e, 0xfd, 0xbf,
-	0xcd, 0xf5, 0xa6, 0xe4, 0x92, 0x86, 0x5c, 0x0a, 0xc5, 0xf1, 0x76, 0xe0,
-	0x27, 0x8c, 0xd3, 0xc8, 0x64, 0x1d, 0x3e, 0xd3, 0x07, 0xdf, 0xc6, 0xef,
-	0xf7, 0x6d, 0x0f, 0x79, 0xf8, 0x5c, 0xe8, 0x1c, 0x79, 0x05, 0xd7, 0xf3,
-	0x48, 0x03, 0x31, 0x36, 0x36, 0x58, 0x51, 0xfb, 0x10, 0x71, 0x85, 0x85,
-	0x67, 0x9d, 0x6f, 0xe3, 0xe3, 0x8e, 0x37, 0x56, 0xe7, 0x98, 0x6b, 0xe7,
-	0x54, 0x70, 0x1a, 0xc8, 0xdf, 0x2d, 0xd0, 0xe5, 0xb8, 0x79, 0x31, 0x12,
-	0x06, 0xc6, 0x65, 0x5b, 0x37, 0x7c, 0x4c, 0x04, 0x3e, 0x6b, 0x18, 0xbe,
-	0x9f, 0x6b, 0x99, 0x7e, 0xde, 0xe7, 0x7d, 0x18, 0x34, 0xe9, 0x7f, 0x87,
-	0x31, 0x67, 0xe6, 0xd8, 0xf4, 0x9f, 0x88, 0x27, 0xb5, 0x70, 0x57, 0xf2,
-	0xb4, 0x5b, 0x1b, 0x74, 0x7f, 0xf3, 0xbe, 0x04, 0x1f, 0x49, 0x44, 0xcb,
-	0x79, 0xe4, 0x7e, 0x29, 0xac, 0xd1, 0xa4, 0x85, 0x3c, 0xbb, 0x16, 0x7d,
-	0x85, 0x98, 0x5b, 0xa7, 0x0c, 0x96, 0x28, 0x27, 0xd6, 0xa9, 0x4c, 0xc9,
-	0x57, 0xbe, 0x0b, 0x79, 0x04, 0x65, 0x8b, 0x95, 0x85, 0x4f, 0x01, 0xff,
-	0x98, 0xfb, 0x5c, 0x89, 0xb5, 0xc8, 0x7e, 0xc4, 0x31, 0x03, 0x42, 0x40,
-	0x4e, 0xb5, 0x64, 0xc8, 0x67, 0x03, 0x43, 0xc8, 0x01, 0x9f, 0x45, 0xdf,
-	0x80, 0xe4, 0x97, 0x18, 0x0f, 0x02, 0x32, 0xb7, 0x24, 0x72, 0xfd, 0x14,
-	0xfd, 0x8a, 0xfa, 0x83, 0xcc, 0x1b, 0x99, 0x69, 0x62, 0xed, 0x79, 0xfa,
-	0x18, 0xfa, 0x89, 0x07, 0xa1, 0x8b, 0xd8, 0x4b, 0xdf, 0x40, 0x6c, 0x9a,
-	0x2d, 0xf6, 0xc3, 0x67, 0x4a, 0x43, 0x87, 0x4c, 0x11, 0xd3, 0x98, 0xa3,
-	0x6f, 0x50, 0x77, 0xf4, 0x6b, 0x8e, 0x41, 0x29, 0x9c, 0x62, 0xbd, 0x31,
-	0x08, 0x5e, 0x98, 0xb7, 0x1a, 0x2a, 0x0f, 0x7a, 0x50, 0xf9, 0x56, 0x7e,
-	0x07, 0x5a, 0xc6, 0x8d, 0x1d, 0xdf, 0xa6, 0xd3, 0x8f, 0x3d, 0x22, 0xf6,
-	0xc4, 0xa1, 0xce, 0x5d, 0xa5, 0x76, 0x29, 0xf7, 0xd2, 0x2e, 0xa9, 0xff,
-	0xac, 0x4e, 0x5f, 0x8b, 0x3c, 0x0c, 0xf4, 0x58, 0x23, 0x08, 0xa0, 0x5f,
-	0xc8, 0xeb, 0x47, 0xb9, 0xfe, 0xb6, 0x4c, 0xed, 0xfc, 0x3b, 0xf0, 0xe5,
-	0xfa, 0xb5, 0xdc, 0x4e, 0xf8, 0xdb, 0x09, 0x5d, 0x1e, 0xfb, 0x54, 0x1a,
-	0xcf, 0x32, 0x16, 0xde, 0xf2, 0xf0, 0x38, 0xdb, 0x58, 0xa3, 0x45, 0x9e,
-	0x7e, 0xce, 0xc4, 0x77, 0xaf, 0xe4, 0xcf, 0x05, 0x21, 0x07, 0xe4, 0xc4,
-	0x15, 0x97, 0x16, 0xf3, 0xde, 0xe3, 0xd0, 0x91, 0x7e, 0x32, 0x28, 0x6d,
-	0x27, 0x7b, 0x25, 0xf0, 0xad, 0x2e, 0x69, 0xff, 0xd6, 0x80, 0x18, 0xdf,
-	0x62, 0x2d, 0x29, 0x1a, 0x39, 0xaa, 0xea, 0x58, 0x69, 0x39, 0x86, 0xf8,
-	0xa5, 0x23, 0x16, 0x2b, 0x3b, 0x35, 0xb7, 0x8a, 0x81, 0xc4, 0x55, 0x7f,
-	0xc1, 0x96, 0xaf, 0xef, 0xfc, 0x85, 0xaa, 0xa3, 0x26, 0x47, 0x70, 0xfd,
-	0x72, 0x06, 0xd8, 0x44, 0x83, 0xad, 0x34, 0x32, 0xd7, 0x1e, 0xf5, 0x73,
-	0xcb, 0x41, 0x55, 0x93, 0xff, 0xfa, 0x4e, 0x37, 0xb7, 0x9c, 0x45, 0x6e,
-	0x99, 0x56, 0xb9, 0x25, 0xfc, 0x6b, 0x80, 0xfd, 0xb6, 0x8a, 0x8e, 0xb1,
-	0x72, 0xc2, 0x5c, 0xfd, 0xa3, 0x62, 0x1f, 0xc0, 0xba, 0x38, 0x23, 0xf3,
-	0x7a, 0x42, 0x53, 0x34, 0x8d, 0x17, 0xe8, 0xa7, 0xe8, 0xbf, 0x68, 0xe3,
-	0xac, 0x69, 0xa1, 0xed, 0x65, 0xfa, 0x28, 0xd7, 0xb6, 0xc7, 0x5a, 0x7c,
-	0xdd, 0x5c, 0xa9, 0x0e, 0x1d, 0x22, 0xa7, 0xb7, 0xda, 0x30, 0x7f, 0xc4,
-	0x74, 0x8b, 0xd7, 0x9c, 0x3f, 0x7c, 0x67, 0x28, 0xa4, 0xae, 0x0b, 0x65,
-	0xb7, 0x86, 0xe1, 0xd2, 0x67, 0xfe, 0x01, 0x1f, 0x53, 0x27, 0x1f, 0x1c,
-	0xb7, 0x4f, 0x8c, 0x33, 0x21, 0x09, 0x9c, 0xa1, 0xfd, 0x45, 0x23, 0x69,
-	0xc8, 0x6f, 0xce, 0x22, 0x06, 0x3c, 0x04, 0x6c, 0xf4, 0x88, 0xe8, 0xe7,
-	0x06, 0xb1, 0x76, 0xa2, 0xe1, 0xb2, 0xc4, 0xc4, 0xa8, 0x04, 0xe5, 0x8d,
-	0x53, 0xd1, 0x08, 0xed, 0xe5, 0x2c, 0xe2, 0xd5, 0x91, 0x7a, 0xe7, 0xed,
-	0x86, 0xe2, 0x82, 0x6d, 0xdf, 0x08, 0x00, 0x3b, 0x0c, 0xda, 0x7a, 0xb7,
-	0xdc, 0x80, 0xbe, 0xb3, 0xaa, 0xed, 0x11, 0xd0, 0x05, 0x0f, 0x67, 0x58,
-	0x1b, 0x24, 0xdd, 0xa3, 0xa0, 0x49, 0xda, 0x8d, 0xcc, 0x32, 0x73, 0xd3,
-	0x53, 0xb4, 0xdd, 0x5e, 0xd8, 0x1d, 0xae, 0xeb, 0xed, 0x92, 0x9d, 0x8c,
-	0x88, 0x7e, 0x6a, 0x8f, 0xf4, 0xef, 0xd4, 0xdd, 0xf9, 0xa8, 0x39, 0xb2,
-	0x8d, 0x35, 0xe7, 0x11, 0xb5, 0x1e, 0xf5, 0x25, 0xd8, 0xcc, 0x3e, 0xea,
-	0x18, 0xb1, 0x1f, 0x71, 0x8c, 0x7e, 0xcc, 0x40, 0x1c, 0x4b, 0xd5, 0x5d,
-	0xbd, 0x97, 0xf7, 0x6d, 0x95, 0x63, 0x67, 0x68, 0x4f, 0xb8, 0xb7, 0x6a,
-	0x53, 0xfe, 0xde, 0x10, 0xef, 0x59, 0x72, 0xfc, 0x45, 0xe6, 0x1e, 0xcc,
-	0x39, 0x98, 0x67, 0x45, 0xc3, 0xbb, 0x30, 0x1f, 0xfd, 0x31, 0xfa, 0x03,
-	0x5d, 0xd9, 0x6e, 0x0e, 0x3e, 0xba, 0x50, 0xa7, 0xde, 0x86, 0xb9, 0x7f,
-	0x66, 0x32, 0x5f, 0xb3, 0xc3, 0xae, 0xbc, 0x0b, 0x68, 0x9b, 0x85, 0xef,
-	0x4f, 0x39, 0x6d, 0xb2, 0x32, 0x69, 0x43, 0xf7, 0x5f, 0x02, 0x5f, 0x07,
-	0x3a, 0x59, 0x23, 0x58, 0x99, 0x4c, 0xe3, 0xfa, 0x80, 0xca, 0xd1, 0x8c,
-	0xc7, 0x6c, 0xd0, 0xd8, 0xca, 0x75, 0xe4, 0xe9, 0x29, 0xae, 0x17, 0xe6,
-	0x1f, 0xd3, 0x67, 0xe1, 0xb3, 0xc7, 0xe3, 0x8c, 0xf1, 0xdc, 0x4b, 0xe8,
-	0x00, 0x1f, 0xdd, 0x0a, 0x57, 0xe8, 0xd6, 0x4e, 0xbd, 0x50, 0xa6, 0x9f,
-	0xcf, 0x87, 0xdb, 0x85, 0x78, 0xc4, 0xd4, 0x2b, 0x16, 0x75, 0xa2, 0xc9,
-	0x65, 0xb5, 0xef, 0x20, 0x92, 0x76, 0x0e, 0x61, 0xac, 0xb8, 0x5e, 0x2d,
-	0xef, 0xd4, 0xf3, 0x65, 0x43, 0x56, 0x42, 0xe4, 0x3b, 0xa2, 0xf2, 0xf8,
-	0x9d, 0xca, 0xd6, 0x8a, 0x88, 0x25, 0xb0, 0x99, 0xf8, 0x87, 0x31, 0xae,
-	0x6a, 0x83, 0x4d, 0x51, 0xf7, 0xd4, 0xbb, 0xf2, 0x91, 0x9e, 0xee, 0x37,
-	0x8a, 0x99, 0x45, 0xf8, 0x5f, 0xd6, 0x2f, 0x3a, 0xbc, 0x5a, 0xe3, 0x4b,
-	0x5e, 0x3e, 0xf4, 0x8c, 0x30, 0x4f, 0x99, 0x2b, 0x91, 0x97, 0x22, 0xfc,
-	0xe1, 0x46, 0xb6, 0x44, 0x39, 0xba, 0x3e, 0xe5, 0x10, 0xec, 0x42, 0x5f,
-	0x32, 0x3d, 0x1b, 0xe0, 0xdf, 0x28, 0xee, 0x31, 0x06, 0xe0, 0xbb, 0xde,
-	0x86, 0xf5, 0xbe, 0x17, 0x32, 0xa2, 0x6e, 0xa0, 0xbf, 0x25, 0xee, 0xbb,
-	0x42, 0x7f, 0x4b, 0x57, 0xde, 0xb6, 0x7b, 0xe9, 0xf3, 0x46, 0xe4, 0x18,
-	0xfc, 0xe8, 0xd1, 0x45, 0xf2, 0x93, 0xf6, 0x70, 0xd9, 0x30, 0x64, 0x42,
-	0x1f, 0x3f, 0x2c, 0x6f, 0xd4, 0x7e, 0xa0, 0x70, 0xe0, 0xb6, 0x9d, 0x0d,
-	0x99, 0x86, 0x7f, 0x98, 0x71, 0x20, 0x7f, 0x33, 0x82, 0xf5, 0x19, 0x56,
-	0xfe, 0x71, 0xe6, 0xfd, 0xe5, 0x24, 0x01, 0x37, 0x66, 0x7f, 0xf6, 0x3e,
-	0x63, 0xf6, 0x03, 0xc0, 0x61, 0xef, 0x8b, 0xbe, 0xe1, 0xd2, 0xff, 0x33,
-	0xe8, 0xea, 0xd7, 0x55, 0xfd, 0x22, 0xb7, 0x73, 0x2b, 0x65, 0xfa, 0x5e,
-	0xcf, 0xe9, 0xee, 0x73, 0x9f, 0xbb, 0x4f, 0xbe, 0x4c, 0xa9, 0x01, 0x2b,
-	0xe4, 0x55, 0x1c, 0x65, 0xae, 0xd8, 0xe6, 0xe9, 0x6f, 0x10, 0x18, 0x9a,
-	0x74, 0x7d, 0xdf, 0xdb, 0x21, 0xf9, 0x5e, 0x3f, 0xff, 0x84, 0xcf, 0x5e,
-	0x6d, 0xf7, 0xf3, 0x59, 0x3e, 0xbf, 0x92, 0x41, 0xfe, 0x0c, 0x1b, 0x60,
-	0x2c, 0x60, 0x5b, 0x5c, 0xf9, 0xa1, 0x77, 0xe7, 0x9b, 0xf5, 0x0b, 0xf2,
-	0xbd, 0x5b, 0xf1, 0x9d, 0x56, 0x7c, 0xb3, 0x06, 0xb9, 0x5f, 0x4b, 0x9d,
-	0x67, 0x1d, 0xd2, 0xaf, 0x3b, 0x92, 0x1e, 0xb0, 0x01, 0xf4, 0xfd, 0x63,
-	0xd0, 0xfd, 0x11, 0xf4, 0xfa, 0xc3, 0x12, 0xb0, 0x41, 0x09, 0xd8, 0xa0,
-	0x04, 0x6c, 0x50, 0x02, 0x36, 0x28, 0x85, 0xbd, 0x3a, 0x8b, 0x4d, 0x6c,
-	0xff, 0x3e, 0x6d, 0xd7, 0xaf, 0x6d, 0xac, 0xb7, 0x4b, 0xb7, 0xb6, 0x99,
-	0xaa, 0xfb, 0x18, 0x39, 0xc8, 0x5a, 0x2b, 0xb0, 0x9a, 0x5f, 0xf7, 0xf0,
-	0x62, 0x44, 0x8d, 0xfb, 0x5e, 0x88, 0x11, 0x35, 0x1b, 0xeb, 0x66, 0x28,
-	0x6c, 0x00, 0x1b, 0x1a, 0x12, 0xc6, 0x6f, 0x13, 0xbe, 0x17, 0xb4, 0x86,
-	0xfb, 0xb1, 0x92, 0xda, 0x55, 0x5d, 0xef, 0x88, 0xaa, 0x3b, 0x58, 0x32,
-	0x5b, 0xf6, 0x73, 0xb7, 0x98, 0x8c, 0xcd, 0x13, 0x6f, 0xca, 0x16, 0x3d,
-	0x01, 0x1d, 0x38, 0xc4, 0x88, 0xdc, 0x27, 0xe4, 0xf8, 0xb1, 0xc1, 0x2a,
-	0xc6, 0x2c, 0x58, 0x2e, 0x7f, 0x47, 0x9c, 0xbb, 0xcf, 0xec, 0x82, 0x7f,
-	0xce, 0x14, 0x23, 0x32, 0x5e, 0x74, 0x31, 0x01, 0xf2, 0x9f, 0x75, 0xf5,
-	0xe5, 0x5b, 0xd0, 0xc3, 0xad, 0xcc, 0x94, 0xb5, 0x6a, 0x1b, 0x91, 0xcb,
-	0x71, 0xca, 0x98, 0xfa, 0xdf, 0xab, 0xf6, 0x29, 0x76, 0x55, 0xdd, 0xbd,
-	0xa4, 0x71, 0x65, 0x0b, 0x01, 0xfa, 0x19, 0xd0, 0x89, 0xbb, 0x6b, 0x18,
-	0x76, 0x91, 0x73, 0x7c, 0xb9, 0xb4, 0xe2, 0x91, 0x2f, 0x6a, 0x62, 0x6d,
-	0xd4, 0xfe, 0x1b, 0x2d, 0xed, 0xab, 0xf7, 0x3d, 0x7e, 0xe1, 0xfb, 0x56,
-	0x6b, 0x0d, 0xf4, 0x53, 0x77, 0xdb, 0x81, 0xdd, 0x24, 0xa0, 0xee, 0xc3,
-	0x87, 0xd7, 0x42, 0x92, 0xaa, 0x59, 0x92, 0x2e, 0xb3, 0x1f, 0xeb, 0x17,
-	0xf4, 0x47, 0x7f, 0x22, 0x29, 0xe4, 0xab, 0xd9, 0x50, 0x34, 0x6e, 0xcb,
-	0x7f, 0x96, 0xe5, 0x85, 0x7c, 0x84, 0xe7, 0x0a, 0xf2, 0x13, 0x1a, 0x9e,
-	0xfb, 0x19, 0xae, 0xc9, 0xb3, 0x25, 0x33, 0x45, 0xc6, 0x9d, 0xa1, 0x70,
-	0x0d, 0xf7, 0xb2, 0x93, 0xac, 0xd9, 0x7c, 0x07, 0x36, 0x19, 0x8d, 0x94,
-	0xa1, 0xef, 0x2b, 0x45, 0x8e, 0x07, 0x6c, 0x54, 0x64, 0x5d, 0xc7, 0xbf,
-	0xff, 0x27, 0xc0, 0x81, 0xf0, 0xd5, 0x21, 0xaf, 0x8f, 0x9a, 0xab, 0x6d,
-	0x06, 0x60, 0xe3, 0x0d, 0xcf, 0xdf, 0x56, 0x8a, 0x6e, 0x1d, 0xe5, 0x2c,
-	0xf9, 0x70, 0xfe, 0x77, 0xb3, 0x11, 0x42, 0x0e, 0xb4, 0x3a, 0xc7, 0xab,
-	0xa4, 0x6f, 0xc2, 0xdd, 0xca, 0x51, 0xc7, 0x97, 0x05, 0xef, 0xb3, 0x8d,
-	0x67, 0x27, 0x9a, 0xcd, 0xb3, 0xd6, 0x07, 0xad, 0x99, 0xf5, 0x6d, 0x4f,
-	0x5a, 0xf9, 0xdd, 0x15, 0x27, 0xef, 0xd5, 0xcc, 0xbe, 0xbd, 0xc3, 0xad,
-	0x99, 0xd5, 0x76, 0xac, 0xad, 0x99, 0x59, 0xdb, 0xdd, 0x9a, 0xd9, 0xfc,
-	0xee, 0x02, 0x3e, 0x6e, 0xcd, 0x2c, 0xbb, 0xdd, 0xad, 0x99, 0x95, 0xb7,
-	0xbb, 0x35, 0x33, 0x67, 0x87, 0x5b, 0x33, 0xfb, 0xf9, 0xf6, 0xb5, 0x35,
-	0xb3, 0x1f, 0xec, 0x58, 0x5b, 0x33, 0xbb, 0xb8, 0x3b, 0x87, 0xcf, 0xdd,
-	0x9a, 0xd9, 0xcf, 0x76, 0xdc, 0xbb, 0x66, 0xf6, 0x9a, 0x8f, 0xd7, 0x31,
-	0x9f, 0x11, 0xcc, 0x21, 0x0e, 0xbc, 0x3e, 0x0c, 0xbc, 0xfe, 0x6e, 0x75,
-	0xfe, 0x00, 0xe6, 0x39, 0xe8, 0xc5, 0x83, 0x0f, 0x82, 0xdb, 0x47, 0xbc,
-	0x67, 0x6d, 0xe4, 0xbb, 0x11, 0x2f, 0x57, 0x21, 0x76, 0xdf, 0xec, 0xe5,
-	0x6c, 0xff, 0xa8, 0xf3, 0xee, 0xb9, 0x97, 0xd6, 0xef, 0x0f, 0x21, 0xf5,
-	0xf6, 0xf1, 0x3c, 0xe7, 0x95, 0x47, 0xee, 0x47, 0x39, 0xd8, 0xe8, 0x3f,
-	0xbf, 0xfb, 0x1b, 0x16, 0x31, 0xfe, 0x73, 0x58, 0xab, 0xf6, 0x16, 0x43,
-	0x9d, 0x01, 0x60, 0x8c, 0x3a, 0x2e, 0x29, 0xf4, 0x4f, 0xa9, 0xfe, 0xd7,
-	0x5a, 0xfa, 0xaf, 0xa0, 0x3f, 0xe9, 0x46, 0xff, 0x1d, 0x3e, 0x2f, 0x29,
-	0xfb, 0xb6, 0x5c, 0x0c, 0x9f, 0x2e, 0xf9, 0x78, 0x2b, 0xe0, 0x61, 0xe7,
-	0x46, 0xc6, 0x76, 0x3e, 0x8f, 0x67, 0xa2, 0x17, 0x6d, 0xb9, 0xa9, 0xf0,
-	0xbb, 0x91, 0x88, 0x5e, 0xcc, 0xaa, 0x7c, 0xad, 0x91, 0xc9, 0x39, 0x7e,
-	0xfe, 0x8d, 0x1c, 0x6a, 0x80, 0x39, 0x0c, 0xec, 0x7d, 0x69, 0x10, 0x71,
-	0xac, 0x35, 0xc7, 0x66, 0x5e, 0xad, 0x7b, 0x79, 0xb5, 0x29, 0x9f, 0xd9,
-	0xd9, 0x8a, 0xcd, 0x2f, 0xee, 0xfe, 0xc7, 0x0a, 0x9b, 0x6f, 0x42, 0x6e,
-	0x4e, 0xec, 0x4d, 0x1c, 0x43, 0x0c, 0x41, 0x7c, 0xce, 0x7a, 0x01, 0xf3,
-	0x19, 0xc6, 0x46, 0xe6, 0x37, 0x21, 0x7c, 0x78, 0x26, 0xc9, 0xc7, 0xe8,
-	0xed, 0x9e, 0x7f, 0x67, 0x5e, 0xe4, 0x63, 0x95, 0xe4, 0x26, 0x37, 0x37,
-	0xda, 0xa4, 0xb9, 0xf9, 0x67, 0xc4, 0xeb, 0x13, 0x58, 0xc5, 0xc2, 0x81,
-	0x55, 0x2c, 0xbc, 0x66, 0x1f, 0x4b, 0xd4, 0xf9, 0x27, 0xb5, 0x1f, 0xc6,
-	0xfd, 0xb1, 0x46, 0xe6, 0xca, 0x80, 0x68, 0x7a, 0x82, 0xfb, 0x64, 0xc0,
-	0x3a, 0x16, 0xf7, 0xcd, 0xe8, 0x3b, 0xf7, 0x69, 0xa9, 0x2a, 0xe3, 0x0f,
-	0xf1, 0x91, 0xbf, 0x17, 0xee, 0xeb, 0x89, 0xb2, 0x63, 0xdb, 0x1f, 0x6b,
-	0xc8, 0x79, 0xe3, 0xed, 0xd6, 0x53, 0xe0, 0x25, 0x83, 0x6f, 0x5f, 0xa6,
-	0x9f, 0x55, 0xb1, 0xaf, 0x03, 0xb6, 0x7b, 0xa4, 0x44, 0xec, 0xba, 0x59,
-	0x6a, 0x1e, 0x7e, 0x3d, 0x37, 0xef, 0x62, 0xd7, 0xc0, 0x5a, 0xec, 0x1a,
-	0x5f, 0x16, 0x97, 0xc7, 0x5d, 0x1b, 0xf2, 0x48, 0xbc, 0x4a, 0xfe, 0x18,
-	0x77, 0xf6, 0xc2, 0xff, 0x35, 0x80, 0x69, 0x19, 0x73, 0x18, 0x6f, 0x22,
-	0xc0, 0xf6, 0xf7, 0xe2, 0x4f, 0xb5, 0x1d, 0xea, 0xb0, 0x82, 0xf8, 0x4c,
-	0xc3, 0x7f, 0x4c, 0xe0, 0x99, 0x8c, 0xcc, 0x9e, 0xfe, 0x1a, 0xe6, 0x36,
-	0x2d, 0x57, 0xe6, 0x27, 0xc1, 0xdf, 0x73, 0x32, 0x17, 0xcf, 0xc3, 0x8f,
-	0x70, 0xcf, 0x83, 0xb8, 0xad, 0xdf, 0xfb, 0x9e, 0xd6, 0xcf, 0x5a, 0x51,
-	0xe2, 0x46, 0xa9, 0x16, 0xe9, 0x83, 0xb9, 0x67, 0xc8, 0xbd, 0x61, 0xda,
-	0x0f, 0xeb, 0x27, 0xc8, 0x5d, 0x99, 0xc3, 0x9e, 0xe2, 0xf8, 0x6b, 0x75,
-	0xb2, 0xec, 0x10, 0x7f, 0x35, 0x32, 0x8d, 0x25, 0xe2, 0xc7, 0xf7, 0x8b,
-	0x25, 0xa9, 0x07, 0xe2, 0xc9, 0xfb, 0xc1, 0x91, 0xd1, 0x79, 0x60, 0xc8,
-	0x57, 0x1a, 0x7a, 0x2b, 0x8e, 0x74, 0x31, 0x64, 0x72, 0x29, 0x0b, 0x9a,
-	0x71, 0x85, 0x95, 0x91, 0xc7, 0xc1, 0xed, 0xf5, 0xe3, 0xd9, 0x7e, 0xe4,
-	0xe4, 0x2e, 0x66, 0x4c, 0x01, 0x33, 0xfe, 0x06, 0x30, 0xe3, 0xac, 0x74,
-	0x76, 0x11, 0x33, 0xda, 0x1e, 0x66, 0x4c, 0xc3, 0x9e, 0x73, 0x6b, 0xec,
-	0x59, 0x53, 0xb5, 0x28, 0xde, 0xcb, 0x01, 0xf3, 0xa5, 0x4e, 0x45, 0xef,
-	0x03, 0x27, 0x6a, 0x12, 0x52, 0xe7, 0x52, 0x02, 0x2d, 0x34, 0x7d, 0x3c,
-	0xb8, 0x4d, 0xe1, 0xbc, 0xdd, 0xa5, 0x4d, 0xc8, 0x51, 0x14, 0xee, 0xf3,
-	0xf6, 0x4b, 0x03, 0xeb, 0xf6, 0x90, 0x03, 0x2d, 0x7b, 0xc8, 0x77, 0xf1,
-	0x21, 0x9e, 0xf3, 0x6a, 0x7d, 0x6d, 0xf0, 0x05, 0xff, 0x13, 0x3c, 0x71,
-	0x7d, 0x71, 0x2d, 0x68, 0xee, 0x7a, 0x59, 0x83, 0x13, 0xff, 0x7a, 0x1d,
-	0x4e, 0x44, 0xec, 0x3a, 0x17, 0x92, 0x24, 0x30, 0xa2, 0xbd, 0x44, 0x5a,
-	0x5c, 0xd3, 0xc3, 0xd2, 0x8e, 0xf9, 0x75, 0x9c, 0xea, 0x05, 0x36, 0xea,
-	0x92, 0x20, 0x30, 0x52, 0x9b, 0xc2, 0x48, 0x03, 0xc4, 0x32, 0x83, 0x33,
-	0xc0, 0x36, 0xb5, 0x55, 0x9c, 0x14, 0x8d, 0xff, 0x01, 0xf4, 0xf2, 0x94,
-	0xf2, 0x3d, 0x69, 0x39, 0x01, 0x5f, 0xda, 0xbe, 0x04, 0x7c, 0x77, 0xce,
-	0xc5, 0x4f, 0x6d, 0xeb, 0xf0, 0xd3, 0xc1, 0x0d, 0xf1, 0x93, 0xaa, 0xdf,
-	0x8f, 0x52, 0x26, 0x37, 0x1c, 0xb7, 0x7e, 0x7f, 0xdd, 0x71, 0xeb, 0xf7,
-	0x37, 0x9c, 0xd6, 0xfa, 0xfd, 0x47, 0xa4, 0x60, 0x46, 0xed, 0x15, 0x59,
-	0x57, 0xbf, 0x9f, 0x60, 0x3d, 0xdc, 0xe9, 0x72, 0xeb, 0xf4, 0x5d, 0x5e,
-	0xfd, 0x3e, 0x2a, 0x85, 0x35, 0xed, 0xa6, 0xbc, 0x69, 0xf9, 0xf5, 0xfb,
-	0xef, 0xa2, 0xad, 0x1b, 0x63, 0xac, 0xad, 0xdd, 0x5f, 0x77, 0x58, 0xbb,
-	0x0f, 0xb1, 0x9f, 0x57, 0xbb, 0x67, 0x3f, 0xe4, 0xf2, 0x0e, 0xeb, 0xf6,
-	0x8f, 0x40, 0x16, 0x5b, 0x21, 0x87, 0x5e, 0x69, 0x3f, 0x13, 0x66, 0x1f,
-	0x55, 0xaf, 0x5f, 0x71, 0x42, 0x78, 0xce, 0xad, 0xab, 0xcf, 0xc0, 0xae,
-	0x0e, 0xae, 0xd6, 0xeb, 0xdd, 0x31, 0x6e, 0x3a, 0x6b, 0xe9, 0xaf, 0xa5,
-	0xd3, 0xe7, 0xd1, 0x09, 0x81, 0x4e, 0x78, 0x1d, 0x9d, 0xbb, 0xf5, 0xf9,
-	0x9b, 0x8e, 0x5b, 0x9b, 0x4f, 0x9f, 0x16, 0xbb, 0x1d, 0xbe, 0xf9, 0xe2,
-	0xc0, 0xc3, 0x1e, 0x8d, 0xd5, 0xda, 0x3c, 0x7d, 0x08, 0x70, 0x7b, 0x4c,
-	0x9d, 0xbd, 0x9a, 0xf9, 0x7f, 0x50, 0x9b, 0x67, 0x5d, 0xde, 0xdd, 0x5f,
-	0xe1, 0xfa, 0x04, 0x3e, 0x7f, 0xd1, 0xad, 0xc9, 0x8f, 0x95, 0xfc, 0x5a,
-	0x3b, 0xf3, 0x47, 0xff, 0x5c, 0x54, 0x7f, 0xe4, 0x88, 0xd0, 0x56, 0xc8,
-	0x1f, 0xe9, 0x76, 0xcb, 0x94, 0xc2, 0x47, 0xb0, 0xa9, 0xd8, 0xbd, 0x31,
-	0x72, 0xe5, 0x94, 0x8f, 0x91, 0x43, 0x0a, 0x23, 0x57, 0x96, 0x7c, 0x8c,
-	0x9c, 0xbc, 0x07, 0x46, 0x6e, 0x76, 0xb9, 0x71, 0x20, 0x28, 0x79, 0x85,
-	0x91, 0xef, 0x75, 0x96, 0x8c, 0xf7, 0xba, 0x88, 0x07, 0xc4, 0x3d, 0x5f,
-	0xd0, 0x7b, 0x8f, 0xb5, 0xe6, 0xe3, 0x66, 0xc6, 0xfe, 0xad, 0x32, 0x71,
-	0xe6, 0x2e, 0x6e, 0x76, 0xb1, 0x71, 0x34, 0x72, 0x48, 0xc5, 0x44, 0xe0,
-	0x84, 0x3a, 0xeb, 0xdf, 0xc4, 0xbe, 0x8c, 0x39, 0x01, 0x85, 0xcf, 0x72,
-	0x45, 0xe6, 0x01, 0x6c, 0x23, 0x16, 0xee, 0xe4, 0x31, 0x2b, 0x2f, 0x26,
-	0xf9, 0x58, 0xd3, 0x3f, 0xd7, 0xc2, 0x3d, 0x86, 0x37, 0x8d, 0xa4, 0x85,
-	0x76, 0xc7, 0xcf, 0x15, 0xe2, 0xea, 0x3c, 0x50, 0x12, 0x58, 0x72, 0x6a,
-	0x15, 0x4b, 0xd2, 0x57, 0xfc, 0xf4, 0x6d, 0xdb, 0xa4, 0x5f, 0xf3, 0xb1,
-	0x22, 0x72, 0xa2, 0x12, 0xd7, 0xb6, 0x8f, 0x15, 0x5d, 0x9c, 0x98, 0x72,
-	0x1a, 0xc0, 0xcb, 0x01, 0x19, 0x03, 0x4e, 0x6f, 0x7c, 0x89, 0x35, 0x28,
-	0x1f, 0x1b, 0xd9, 0xf8, 0x6e, 0xad, 0x49, 0xf1, 0xba, 0x5d, 0xed, 0x05,
-	0x5e, 0x1e, 0x08, 0xb6, 0xb4, 0x3f, 0x0b, 0xff, 0x8d, 0xfc, 0x08, 0xd8,
-	0xc4, 0xc5, 0x44, 0x3b, 0xa0, 0x83, 0x91, 0x7b, 0x60, 0xa2, 0xf5, 0x31,
-	0x8a, 0x31, 0xf3, 0x6e, 0x8c, 0x4a, 0xd7, 0xe9, 0xcf, 0xef, 0xc6, 0xa8,
-	0x7b, 0xc7, 0x50, 0xb6, 0x61, 0x76, 0x56, 0x06, 0x9f, 0x69, 0x29, 0xac,
-	0x8b, 0x51, 0x73, 0x1f, 0x20, 0x46, 0xb9, 0xf8, 0xc0, 0xe5, 0xfb, 0xf7,
-	0x21, 0x9b, 0x1f, 0x43, 0xa6, 0x3f, 0x02, 0xe6, 0xfa, 0x21, 0xe6, 0xf5,
-	0x03, 0xe0, 0xa1, 0xef, 0x97, 0xd6, 0x9f, 0x07, 0x19, 0x15, 0xe6, 0x87,
-	0x2e, 0x66, 0x72, 0x31, 0xfd, 0x0c, 0x56, 0x57, 0xad, 0xd8, 0xc8, 0x4c,
-	0x15, 0x87, 0xcc, 0x69, 0x77, 0x1f, 0x35, 0x92, 0x95, 0xa7, 0x3b, 0x53,
-	0x8b, 0x8c, 0x19, 0xea, 0x3a, 0xcc, 0xfa, 0x25, 0xb1, 0x43, 0x55, 0xe5,
-	0x99, 0x03, 0x52, 0xae, 0xb9, 0x78, 0x6b, 0x6e, 0xd1, 0xa5, 0x31, 0xe5,
-	0xe1, 0xad, 0x9c, 0x87, 0xb7, 0xb2, 0xb5, 0xe5, 0x48, 0x00, 0xfd, 0xe7,
-	0xe2, 0x6b, 0x31, 0xd6, 0x8c, 0x87, 0xb1, 0xa6, 0x3f, 0x20, 0xc6, 0xe2,
-	0x58, 0x39, 0x3c, 0x33, 0x3e, 0x1f, 0x91, 0x5d, 0x90, 0xf3, 0x58, 0x91,
-	0xfa, 0xe2, 0x19, 0xb2, 0xf7, 0xd2, 0x19, 0xf5, 0xe5, 0xea, 0x2a, 0x10,
-	0xdb, 0xa7, 0x8d, 0x43, 0x57, 0x63, 0xef, 0xa9, 0x2b, 0x31, 0xdf, 0x18,
-	0x09, 0xe2, 0xf3, 0xf7, 0xa5, 0x2b, 0xce, 0x83, 0xfa, 0x5a, 0x8f, 0xc5,
-	0xee, 0x07, 0x93, 0xad, 0xc5, 0x63, 0xb6, 0xc2, 0x63, 0xed, 0x5e, 0x1f,
-	0xd9, 0x33, 0x0e, 0x5d, 0xfe, 0x27, 0xf4, 0xf9, 0x99, 0xd5, 0x2d, 0x3f,
-	0x85, 0xff, 0xfe, 0x43, 0xe8, 0xe4, 0x3f, 0x22, 0x57, 0x78, 0xcd, 0xea,
-	0x93, 0x3f, 0x40, 0xdb, 0x5d, 0x9c, 0xc3, 0xfe, 0xc1, 0xc7, 0x92, 0xd6,
-	0x35, 0xe0, 0x93, 0x6b, 0x1e, 0x3e, 0x79, 0x3a, 0x99, 0xb4, 0x26, 0x59,
-	0x37, 0x87, 0x9c, 0x0f, 0xa4, 0xa6, 0x14, 0x36, 0xf1, 0x31, 0xc9, 0xed,
-	0x34, 0xc7, 0x9f, 0x75, 0x56, 0x80, 0x7d, 0x56, 0x3c, 0xec, 0x73, 0x60,
-	0xcc, 0xc5, 0x3e, 0xc1, 0xcf, 0x50, 0xff, 0x2e, 0xee, 0x59, 0xb1, 0x93,
-	0x18, 0xa7, 0x0a, 0x4c, 0x52, 0x71, 0x0e, 0x48, 0xbe, 0xbe, 0x57, 0x7d,
-	0x8e, 0x94, 0xec, 0x68, 0x1b, 0xe4, 0xc4, 0xda, 0xeb, 0x49, 0xae, 0x4a,
-	0x27, 0x6a, 0x16, 0xf1, 0x9d, 0x75, 0xa2, 0xe1, 0xdf, 0xf1, 0xae, 0x9f,
-	0xf7, 0xae, 0x4f, 0x78, 0xd7, 0xc7, 0x11, 0x87, 0x8f, 0xa9, 0x58, 0xca,
-	0x76, 0xb6, 0x41, 0xc9, 0x0e, 0x68, 0x01, 0x7b, 0x9c, 0x1d, 0xfe, 0x8b,
-	0x66, 0x59, 0xe9, 0x98, 0xf4, 0x27, 0xf0, 0x39, 0x8e, 0xcf, 0x34, 0x3e,
-	0xfb, 0xf1, 0xc9, 0xe3, 0xb3, 0x2a, 0x53, 0x2d, 0x55, 0x9a, 0x84, 0x8d,
-	0x0c, 0x4a, 0xaa, 0xfe, 0x12, 0xf4, 0xf8, 0x1c, 0x74, 0x7b, 0x58, 0x0a,
-	0xd5, 0x3f, 0x95, 0xd9, 0x79, 0x4d, 0xba, 0x2c, 0xe8, 0xb4, 0x0a, 0x5b,
-	0x9e, 0x77, 0xf7, 0x13, 0x3b, 0x13, 0x7b, 0xd1, 0xb7, 0x29, 0x4f, 0xc5,
-	0x9f, 0x13, 0xfd, 0xb1, 0x39, 0xf4, 0x13, 0xbd, 0x30, 0xfc, 0x31, 0xb5,
-	0x6f, 0x56, 0x8d, 0xbb, 0x32, 0xde, 0x65, 0xd9, 0x51, 0xe8, 0x7c, 0xf0,
-	0x18, 0x68, 0x27, 0xd5, 0xd9, 0xd8, 0x8c, 0x1c, 0x3d, 0xbd, 0xbc, 0xc5,
-	0xf5, 0xad, 0x51, 0xf3, 0x26, 0xf5, 0x8e, 0x79, 0xd8, 0xf0, 0x85, 0x19,
-	0xd8, 0xfb, 0x41, 0x27, 0xa0, 0x8d, 0x21, 0xde, 0x8c, 0x39, 0x37, 0x55,
-	0xbc, 0x81, 0xef, 0xca, 0xc4, 0x4e, 0x86, 0x70, 0xcd, 0xb3, 0x45, 0x88,
-	0x8b, 0xea, 0x6c, 0xe5, 0x32, 0xf0, 0x8d, 0xa6, 0xea, 0x80, 0xb3, 0xab,
-	0xfb, 0x43, 0x86, 0xf2, 0x5b, 0xb1, 0x98, 0x2e, 0xb9, 0x11, 0xe2, 0xdc,
-	0xbd, 0x2a, 0x36, 0xd5, 0x8a, 0xf6, 0x43, 0xcc, 0x15, 0x6f, 0x08, 0xe3,
-	0xdc, 0xe3, 0xe8, 0xd7, 0x07, 0x7f, 0x8c, 0x7b, 0x75, 0xda, 0x27, 0xe7,
-	0xca, 0x67, 0xa6, 0xa5, 0x5a, 0x1e, 0xc5, 0x7c, 0xbd, 0x1c, 0x49, 0xe5,
-	0x12, 0x11, 0xd8, 0xa3, 0xbf, 0x17, 0xe5, 0xd6, 0x4f, 0xaa, 0x8e, 0x8f,
-	0x29, 0xba, 0xd1, 0x87, 0x79, 0x05, 0x64, 0xe4, 0xee, 0x9f, 0xa9, 0xbd,
-	0xb3, 0x82, 0x33, 0x0a, 0x39, 0x25, 0xd1, 0xce, 0x5a, 0x35, 0x7e, 0x97,
-	0x75, 0x55, 0x13, 0x58, 0x31, 0x66, 0xa4, 0x56, 0x6e, 0x82, 0x5f, 0xc4,
-	0xdc, 0x2d, 0x33, 0x52, 0x29, 0x4f, 0xcb, 0x2b, 0xe5, 0x9f, 0x77, 0x03,
-	0x53, 0x41, 0xa6, 0xe4, 0xbf, 0x5b, 0xee, 0x9e, 0xbf, 0xf5, 0xdb, 0x21,
-	0xcf, 0xd3, 0xf9, 0xb0, 0x9b, 0xe7, 0xe6, 0x55, 0x2d, 0xc6, 0xfd, 0xb6,
-	0xf5, 0x29, 0x2b, 0x1a, 0x9e, 0x45, 0xcf, 0x83, 0x0b, 0xb4, 0xcd, 0xfc,
-	0xf8, 0x9c, 0xb5, 0x43, 0xae, 0xc6, 0x37, 0xcb, 0x72, 0x5c, 0xe5, 0xc5,
-	0xc4, 0x0f, 0x58, 0xeb, 0x51, 0xb3, 0x21, 0x7b, 0xe4, 0x28, 0xd6, 0xed,
-	0xd5, 0xf8, 0xd3, 0xb0, 0xd3, 0x67, 0x61, 0x0b, 0xac, 0x01, 0x1c, 0x62,
-	0xae, 0x25, 0x0d, 0x55, 0x23, 0x6b, 0x36, 0xc7, 0xd5, 0x19, 0xee, 0x76,
-	0x59, 0x56, 0x58, 0xcc, 0xad, 0x9d, 0x2f, 0x4f, 0xba, 0x6b, 0xc4, 0x50,
-	0x76, 0xff, 0xc7, 0xe0, 0xc7, 0x84, 0xed, 0xb6, 0xa9, 0x3e, 0x46, 0xa2,
-	0xc3, 0xeb, 0xa3, 0xf4, 0xdb, 0xd2, 0xe7, 0x95, 0x44, 0xd2, 0xda, 0xff,
-	0x89, 0xa4, 0x75, 0x73, 0xb7, 0x5b, 0x6f, 0x89, 0x9a, 0xb6, 0xc6, 0xf7,
-	0x52, 0xdc, 0xf5, 0x98, 0xc1, 0xba, 0xba, 0xb4, 0x8a, 0xa1, 0x61, 0xa4,
-	0x2f, 0x5f, 0x81, 0x7e, 0x03, 0xd2, 0x7e, 0xb2, 0xf9, 0xf8, 0x54, 0x7c,
-	0x28, 0x72, 0x50, 0x78, 0x02, 0x8b, 0x79, 0x75, 0x34, 0x9e, 0x95, 0x2b,
-	0x88, 0x93, 0x77, 0x88, 0x1d, 0x06, 0x2f, 0xcb, 0x9d, 0xc7, 0x93, 0xf1,
-	0x51, 0xad, 0x32, 0x89, 0xac, 0xe5, 0xe5, 0x49, 0xc6, 0xd9, 0x43, 0x22,
-	0xc0, 0x97, 0x27, 0x47, 0x24, 0x5d, 0x54, 0xef, 0xa9, 0xf0, 0x9c, 0xad,
-	0x36, 0x0d, 0xf9, 0xe1, 0xf9, 0x09, 0x06, 0x46, 0xdd, 0xea, 0x8f, 0xa4,
-	0xe5, 0x69, 0xd6, 0xc0, 0x24, 0xb7, 0x20, 0xdb, 0x92, 0xf0, 0xab, 0xf6,
-	0x44, 0xbb, 0x4c, 0xd7, 0x1a, 0x99, 0xfe, 0x53, 0xcf, 0x82, 0xc6, 0x14,
-	0x68, 0xed, 0x45, 0x6e, 0x92, 0x45, 0xac, 0xa6, 0x7c, 0xe9, 0xbb, 0x9f,
-	0x81, 0x8c, 0x3e, 0xc2, 0x3d, 0xe5, 0xd1, 0xac, 0x44, 0x27, 0xf2, 0x8a,
-	0xee, 0x5b, 0x5a, 0x6e, 0xf8, 0x57, 0x10, 0xeb, 0x02, 0xb2, 0x2b, 0x26,
-	0xfa, 0xde, 0x58, 0xe0, 0xed, 0x29, 0x8b, 0x6d, 0x41, 0xb6, 0xe9, 0x68,
-	0x0b, 0xfc, 0x7a, 0x2c, 0xa8, 0x27, 0x63, 0xd1, 0x51, 0x9e, 0x8f, 0x36,
-	0xac, 0x29, 0xee, 0x4d, 0x3c, 0x20, 0x5d, 0x7b, 0xa5, 0xe7, 0x42, 0x74,
-	0xf4, 0x06, 0x78, 0x09, 0x28, 0x5f, 0x3f, 0x25, 0xba, 0xd7, 0xde, 0xbd,
-	0xda, 0x1e, 0xf0, 0xda, 0xf7, 0x4a, 0xd7, 0x85, 0x21, 0xf3, 0x75, 0x99,
-	0x01, 0x4d, 0x43, 0xae, 0x23, 0xd7, 0xb1, 0x06, 0xa6, 0x60, 0x8b, 0x4f,
-	0x92, 0x97, 0xfd, 0xc0, 0x1a, 0x58, 0x1b, 0xc8, 0xbf, 0xad, 0x0f, 0xcb,
-	0x57, 0xcd, 0x4e, 0xc9, 0xa9, 0x5c, 0x37, 0xe0, 0xd6, 0x52, 0x61, 0xef,
-	0x8f, 0x0e, 0x1c, 0xec, 0x71, 0xeb, 0x05, 0xdc, 0xef, 0x18, 0x46, 0xdb,
-	0x9d, 0xe6, 0x39, 0x8b, 0x6d, 0xbc, 0x77, 0xa7, 0x59, 0xb5, 0x86, 0xcc,
-	0x94, 0x16, 0xf4, 0xf6, 0xbd, 0x0f, 0xa9, 0xb9, 0xe7, 0xcb, 0xfd, 0x66,
-	0x45, 0x1e, 0xd5, 0x52, 0x0f, 0x22, 0x5e, 0x38, 0xd3, 0xe8, 0x7b, 0x87,
-	0xe7, 0x29, 0x54, 0x7d, 0xbf, 0x22, 0xfe, 0x35, 0xe9, 0x0c, 0x99, 0xe3,
-	0xea, 0xd9, 0x21, 0xf3, 0xa8, 0xd6, 0xfa, 0x6c, 0x58, 0x1b, 0x5f, 0xf3,
-	0x6c, 0x97, 0x92, 0x91, 0x61, 0xb9, 0x7d, 0x66, 0xcb, 0x7b, 0xe5, 0x79,
-	0x87, 0xfd, 0xee, 0x34, 0x53, 0xd6, 0x03, 0xda, 0xd1, 0x07, 0xe9, 0x0b,
-	0xd9, 0xf7, 0xf6, 0xba, 0x71, 0x78, 0x7d, 0xaf, 0x31, 0x9a, 0xb2, 0x76,
-	0x8c, 0x4d, 0xaa, 0xcf, 0x55, 0xd5, 0x27, 0xa0, 0x64, 0xbd, 0x76, 0x9c,
-	0xbf, 0x91, 0xb5, 0xe3, 0x74, 0xad, 0xce, 0x79, 0x16, 0x34, 0x8f, 0xa1,
-	0x6f, 0xd1, 0xe9, 0x0f, 0x57, 0xe5, 0x76, 0x33, 0x67, 0xbd, 0x29, 0x57,
-	0x57, 0x69, 0xff, 0x12, 0xd7, 0xad, 0x3c, 0xfd, 0xd2, 0xe3, 0x91, 0xbf,
-	0xd9, 0xf6, 0x2f, 0x95, 0xbc, 0x1f, 0xb0, 0xfa, 0xf7, 0x57, 0xb4, 0xe8,
-	0xe8, 0x5f, 0x0a, 0x75, 0xf5, 0xcf, 0x94, 0xaf, 0xf9, 0x18, 0xf4, 0xb4,
-	0xed, 0x05, 0xac, 0xdd, 0xe1, 0xa4, 0xea, 0x73, 0xdd, 0xda, 0x2b, 0xdb,
-	0x4e, 0xf6, 0x9b, 0xd7, 0xe5, 0x33, 0x92, 0x0e, 0xf1, 0x1a, 0x39, 0x94,
-	0xc5, 0xf7, 0x52, 0x3e, 0xc1, 0xbc, 0x00, 0xba, 0xec, 0x1f, 0xfc, 0x4b,
-	0x79, 0x56, 0x8e, 0x96, 0xe6, 0xe0, 0x7b, 0xa6, 0x64, 0xf0, 0x05, 0xfa,
-	0x9f, 0xbc, 0xe9, 0xd6, 0x6a, 0xdc, 0x98, 0x98, 0xf2, 0x62, 0xe2, 0x9c,
-	0xf2, 0x73, 0xaf, 0x79, 0xe7, 0x22, 0xfa, 0x07, 0xcf, 0xe1, 0xd9, 0x57,
-	0x94, 0x0f, 0xf8, 0x3d, 0xa9, 0x62, 0x2d, 0x44, 0x5e, 0xde, 0x2c, 0x0f,
-	0x3c, 0x41, 0x9b, 0x44, 0x06, 0xf0, 0xb1, 0x36, 0xf5, 0x1e, 0x8c, 0x6e,
-	0x75, 0x88, 0x6c, 0xa1, 0xfd, 0x5c, 0x86, 0xad, 0x4d, 0xb9, 0x7b, 0x5f,
-	0x6b, 0xae, 0xa3, 0x13, 0x2b, 0xf2, 0x1f, 0x94, 0x1d, 0x7e, 0xfc, 0x82,
-	0xfb, 0x3d, 0x7c, 0x01, 0xe9, 0x72, 0x6c, 0xaf, 0x6c, 0xbf, 0xe0, 0xda,
-	0xdd, 0xec, 0xfc, 0xb3, 0x4a, 0xbe, 0x53, 0x4a, 0xbe, 0x4d, 0x99, 0x89,
-	0x53, 0xf6, 0x9c, 0x13, 0xcf, 0x4f, 0xba, 0x32, 0xf9, 0x9c, 0x67, 0x47,
-	0xfd, 0x2f, 0xf0, 0x3d, 0x35, 0xca, 0x88, 0x7c, 0xcf, 0xf4, 0x70, 0x3f,
-	0x76, 0xdb, 0x05, 0xce, 0xb7, 0x6f, 0xcd, 0x7c, 0x4f, 0xc0, 0xc7, 0x0e,
-	0x0c, 0xb8, 0x73, 0x7e, 0x6d, 0xfe, 0xfd, 0xcf, 0xf9, 0x77, 0x57, 0xe7,
-	0x6c, 0x48, 0x55, 0xe5, 0xb9, 0xb1, 0xcd, 0xd2, 0x95, 0x93, 0x06, 0xec,
-	0xe3, 0xcf, 0x85, 0x67, 0xc6, 0xc9, 0x8b, 0x3b, 0xee, 0xb2, 0x43, 0x9e,
-	0xfc, 0x39, 0x90, 0xaf, 0x29, 0x4f, 0x7f, 0xe4, 0xe3, 0xd9, 0x0d, 0xef,
-	0x5d, 0x97, 0x46, 0x66, 0x10, 0x6d, 0xba, 0xd2, 0xe1, 0x98, 0xb7, 0xde,
-	0xf6, 0x8a, 0xae, 0x74, 0x98, 0x5c, 0xd5, 0xe1, 0x0d, 0xe8, 0xb0, 0x2a,
-	0x9f, 0xc6, 0x9c, 0xb0, 0xbe, 0x5f, 0x18, 0x32, 0x67, 0x64, 0xab, 0xd2,
-	0xbf, 0x35, 0x00, 0x9f, 0xea, 0xe9, 0xb2, 0xfd, 0x3e, 0x74, 0xf9, 0xba,
-	0x28, 0x7d, 0xaa, 0x73, 0x44, 0x55, 0x45, 0x87, 0xbe, 0x8d, 0x73, 0x6b,
-	0x57, 0x3e, 0x81, 0x3c, 0xaa, 0xb3, 0x01, 0x13, 0xae, 0x7e, 0xd5, 0x9a,
-	0xf7, 0xf4, 0x9b, 0x9d, 0xa0, 0x0e, 0x7f, 0xad, 0xc7, 0xd5, 0x67, 0x87,
-	0xea, 0x73, 0x2a, 0x36, 0xaa, 0xd6, 0xbb, 0x35, 0xf0, 0xe9, 0x1e, 0xea,
-	0xf4, 0x79, 0xc7, 0xfd, 0x2e, 0x22, 0xce, 0x9d, 0x72, 0xde, 0x4b, 0xaf,
-	0xae, 0x4e, 0xc7, 0xc4, 0x5d, 0x57, 0xeb, 0xf5, 0xa9, 0x5f, 0x08, 0x28,
-	0x1b, 0x1e, 0x83, 0x0c, 0x8f, 0x97, 0x1e, 0xf4, 0xec, 0xde, 0x9d, 0xf3,
-	0xc0, 0xfb, 0x9c, 0xf3, 0x91, 0x62, 0xbf, 0xf9, 0x26, 0xee, 0x8d, 0x63,
-	0xce, 0x33, 0xd2, 0x26, 0x29, 0x6f, 0xce, 0x91, 0xd5, 0x39, 0xfb, 0x3c,
-	0xba, 0xfd, 0x52, 0xcc, 0x63, 0x1d, 0xfa, 0xaf, 0x7f, 0xab, 0xde, 0x37,
-	0xb9, 0x59, 0xa4, 0xdf, 0x06, 0x56, 0x0a, 0xf5, 0xca, 0xf5, 0x5a, 0x44,
-	0xae, 0x13, 0x83, 0x8c, 0xe0, 0xdb, 0x99, 0xf3, 0x62, 0x78, 0x50, 0x5e,
-	0x2f, 0x6e, 0xc4, 0xc7, 0xb0, 0xdc, 0x28, 0xfa, 0xbc, 0x10, 0x0b, 0x33,
-	0x5f, 0x98, 0x92, 0x37, 0xe6, 0xfb, 0xa5, 0x31, 0x81, 0xb8, 0x3f, 0x40,
-	0x99, 0x0c, 0x99, 0x7b, 0xd4, 0x7b, 0x48, 0x77, 0x9a, 0x97, 0x2d, 0xd0,
-	0x5f, 0x68, 0xca, 0x41, 0xee, 0x67, 0xf3, 0x77, 0xed, 0x21, 0x69, 0x30,
-	0xa7, 0x18, 0xe8, 0x95, 0xca, 0x02, 0xf2, 0xf9, 0x22, 0xe9, 0x53, 0x6e,
-	0x7b, 0xd5, 0xef, 0x71, 0x8c, 0xf7, 0x39, 0xbe, 0x1f, 0x10, 0xa2, 0x6e,
-	0xee, 0x34, 0x97, 0x2d, 0xee, 0x67, 0x4e, 0x49, 0x0d, 0xfa, 0xfb, 0xe7,
-	0x31, 0xee, 0xb7, 0xe7, 0xd4, 0xf9, 0xdb, 0x4a, 0x6d, 0x02, 0xb9, 0xc3,
-	0x9d, 0xe6, 0x9c, 0x75, 0x56, 0xe9, 0xad, 0x56, 0x7e, 0xc2, 0x6b, 0xe7,
-	0x35, 0xef, 0x35, 0x32, 0xdb, 0x06, 0x98, 0xaf, 0x3e, 0x81, 0x7c, 0x81,
-	0xb9, 0xea, 0x04, 0xf0, 0x1a, 0x65, 0x12, 0x91, 0xd9, 0x22, 0x69, 0x49,
-	0x68, 0x13, 0xf2, 0xfb, 0x9c, 0x8c, 0x83, 0x9f, 0x08, 0x72, 0x7b, 0xc6,
-	0x87, 0x47, 0x65, 0x39, 0xe4, 0xc6, 0x01, 0x9e, 0xfb, 0x5a, 0x46, 0x6c,
-	0x58, 0x5e, 0x8d, 0x0d, 0x5b, 0x71, 0xdd, 0xc8, 0xc4, 0x07, 0xfe, 0x06,
-	0xf4, 0x59, 0xb7, 0x61, 0x6c, 0x18, 0x45, 0x7f, 0xb6, 0xf5, 0xca, 0xec,
-	0x02, 0x92, 0x08, 0xe4, 0x2c, 0x15, 0xe1, 0x99, 0x8e, 0xac, 0x9c, 0xaa,
-	0xf5, 0x87, 0x2f, 0x6b, 0x69, 0x75, 0xf6, 0x23, 0x36, 0xc0, 0xf3, 0x2c,
-	0xbd, 0x52, 0x5b, 0x90, 0x88, 0x91, 0x78, 0x52, 0x9c, 0x9a, 0x8b, 0xd9,
-	0xe7, 0x34, 0x9e, 0x69, 0xb1, 0xa5, 0xb6, 0xb6, 0x8f, 0x89, 0xdc, 0x57,
-	0xbe, 0xe3, 0xf5, 0x49, 0xab, 0x3e, 0x7f, 0xdd, 0xc3, 0x3d, 0xb4, 0x9a,
-	0xd3, 0x03, 0x1e, 0xc8, 0xdb, 0xc3, 0xad, 0xe3, 0x46, 0xee, 0x8e, 0xcb,
-	0x31, 0x91, 0xcd, 0x6c, 0xb1, 0x31, 0xee, 0x4d, 0x3c, 0xf3, 0x24, 0xf8,
-	0xb8, 0x63, 0xe8, 0xd6, 0x93, 0x52, 0xa8, 0xad, 0x1f, 0xa3, 0x95, 0x07,
-	0x3e, 0x43, 0xfa, 0x1c, 0xe7, 0x00, 0xf8, 0xbb, 0xa3, 0xe9, 0xd6, 0x01,
-	0xc8, 0xd2, 0x1d, 0xc3, 0x38, 0x13, 0x35, 0x7f, 0x2a, 0x03, 0xa2, 0x9f,
-	0xd3, 0x94, 0xfc, 0xf5, 0xca, 0x30, 0x16, 0x48, 0x46, 0xba, 0x96, 0x26,
-	0xc5, 0x58, 0x62, 0x0d, 0xe1, 0xb5, 0xce, 0xb4, 0xda, 0xbf, 0xdd, 0x84,
-	0xf5, 0x2d, 0x76, 0xc0, 0x62, 0xbd, 0x80, 0xf5, 0xe0, 0x9f, 0x6e, 0x96,
-	0x1e, 0xd6, 0x0b, 0x98, 0x37, 0xec, 0xc7, 0x37, 0x73, 0x87, 0x4b, 0x4d,
-	0xe4, 0x7a, 0x9b, 0x19, 0x5f, 0x73, 0x35, 0xde, 0x8f, 0x46, 0x44, 0x78,
-	0x8f, 0x7e, 0xa3, 0x57, 0xda, 0xbe, 0x35, 0x08, 0x5f, 0xf1, 0x34, 0xb0,
-	0x37, 0xe8, 0x9e, 0x1c, 0x90, 0x80, 0x7b, 0x66, 0x42, 0xd5, 0x5b, 0xde,
-	0x58, 0x88, 0x7a, 0xef, 0x73, 0xc9, 0xb6, 0xcb, 0x71, 0xd6, 0x44, 0xfb,
-	0x58, 0xf3, 0x41, 0x3f, 0xd1, 0x97, 0x91, 0x9f, 0x5e, 0xaf, 0x59, 0x9b,
-	0x79, 0x7e, 0xf3, 0x86, 0x83, 0x6b, 0x62, 0xff, 0x90, 0xc2, 0x98, 0xde,
-	0x3d, 0xfe, 0x46, 0xbe, 0xf4, 0x8e, 0x77, 0x13, 0x98, 0x4f, 0x4d, 0x7a,
-	0x67, 0xe7, 0x1a, 0x99, 0xa3, 0x6b, 0x72, 0xaa, 0x41, 0x55, 0xef, 0x6d,
-	0x38, 0x16, 0xfc, 0xe3, 0x08, 0xec, 0x93, 0x6b, 0xa0, 0xa9, 0x3d, 0x01,
-	0x6c, 0x16, 0xe9, 0x55, 0x39, 0xd1, 0xf1, 0x27, 0xc4, 0xb5, 0x77, 0x58,
-	0x99, 0xf2, 0x65, 0x8d, 0xb2, 0x9b, 0x83, 0x2c, 0x97, 0x33, 0xf2, 0x47,
-	0xce, 0x15, 0x55, 0x6b, 0x9d, 0x47, 0x5e, 0x12, 0x38, 0xa5, 0x72, 0xb2,
-	0x16, 0x7c, 0x0b, 0xbf, 0xf7, 0xe2, 0xd7, 0xb1, 0x16, 0xa3, 0xea, 0x8c,
-	0x82, 0x7e, 0xae, 0xd9, 0x4c, 0xc1, 0x7f, 0xe8, 0x96, 0x65, 0x16, 0x10,
-	0x0f, 0x53, 0xea, 0x9c, 0x0b, 0xd7, 0xf1, 0x6f, 0x2b, 0xff, 0x2c, 0x15,
-	0xc8, 0xe6, 0x4c, 0x04, 0x74, 0x34, 0x65, 0x9f, 0x86, 0xd2, 0xc3, 0x13,
-	0x0a, 0xf3, 0x1a, 0xe7, 0xe0, 0xb0, 0x96, 0x06, 0x44, 0xce, 0x65, 0x64,
-	0x0e, 0x6b, 0x38, 0xb0, 0x44, 0x1d, 0x50, 0xb6, 0x93, 0xd2, 0x06, 0xd9,
-	0x1f, 0x01, 0xf6, 0x30, 0x4e, 0x51, 0xc6, 0x61, 0xac, 0x8b, 0x5e, 0x09,
-	0x9c, 0x81, 0x8c, 0x4f, 0x01, 0x23, 0x2c, 0xb4, 0xcb, 0xf7, 0x6a, 0xbe,
-	0x4c, 0x2f, 0xf1, 0x5c, 0xbf, 0x3e, 0x35, 0xd2, 0x47, 0x1c, 0x25, 0xd5,
-	0xda, 0x9c, 0xcc, 0x9d, 0x66, 0xce, 0x3e, 0xa9, 0xce, 0x0c, 0x04, 0xd4,
-	0x99, 0x15, 0x37, 0x67, 0x76, 0xbf, 0x5d, 0x8c, 0x59, 0x15, 0xee, 0xb5,
-	0x09, 0x6c, 0x67, 0x18, 0xe3, 0x6e, 0x24, 0x5f, 0x37, 0x57, 0x1d, 0x07,
-	0xbf, 0x97, 0xe7, 0xa3, 0x99, 0xbc, 0xc4, 0x79, 0x76, 0x7a, 0xc2, 0xc6,
-	0xfc, 0x97, 0xe1, 0x3f, 0xe7, 0x4a, 0x3c, 0x27, 0x5d, 0xc0, 0x0a, 0xcb,
-	0xc8, 0xe5, 0x22, 0x73, 0xc6, 0x8f, 0x43, 0x6f, 0xbc, 0x2e, 0x8c, 0x1a,
-	0xf0, 0x03, 0x2b, 0xea, 0xdd, 0xcf, 0xa8, 0xdd, 0x40, 0x0e, 0x1b, 0xd1,
-	0xf6, 0x43, 0xd7, 0x79, 0xb3, 0xcd, 0xb3, 0x07, 0x9e, 0xc5, 0x3f, 0x0b,
-	0x3f, 0x7a, 0x5e, 0xf8, 0x4e, 0xd6, 0xed, 0x26, 0xf3, 0xa5, 0xab, 0xf0,
-	0x7b, 0x99, 0x58, 0x06, 0x36, 0x94, 0x0f, 0x77, 0x80, 0xe7, 0xdf, 0xc4,
-	0xbd, 0x9c, 0xc3, 0x71, 0xa2, 0xf1, 0x15, 0x29, 0x44, 0x02, 0x32, 0x14,
-	0xb9, 0x22, 0x9b, 0xe1, 0xc9, 0x34, 0x79, 0xdd, 0x8a, 0x8e, 0x8a, 0xa6,
-	0xe8, 0x0d, 0xee, 0x86, 0x0d, 0xde, 0x84, 0xbf, 0x6b, 0xf7, 0x72, 0xfd,
-	0x54, 0x91, 0x18, 0xea, 0x59, 0x75, 0xb6, 0xe0, 0xaa, 0xc5, 0x3a, 0x20,
-	0xdf, 0xc5, 0xfe, 0x1f, 0x6a, 0x8c, 0xbb, 0x7b, 0x77, 0xac, 0x43, 0x93,
-	0x3f, 0x77, 0x8e, 0xbb, 0x2c, 0x97, 0x47, 0xd2, 0x69, 0x6b, 0xa1, 0x73,
-	0xd9, 0xa3, 0x73, 0xd6, 0xa3, 0x53, 0xf1, 0xe8, 0x5c, 0x5d, 0xa5, 0xb3,
-	0x07, 0x76, 0xd0, 0x6c, 0x9e, 0x00, 0xde, 0x48, 0xc6, 0x9b, 0xcd, 0x34,
-	0xf2, 0xb2, 0xd9, 0xe1, 0x69, 0xb5, 0xe7, 0xaa, 0x27, 0x46, 0xc7, 0x93,
-	0x96, 0x2b, 0x7f, 0x58, 0x81, 0x4c, 0xc3, 0x1e, 0xf3, 0xe2, 0x62, 0x75,
-	0xee, 0x07, 0xba, 0xfb, 0x85, 0x5d, 0xf0, 0x03, 0x4f, 0x23, 0x96, 0x5c,
-	0x1c, 0x3f, 0x6f, 0x49, 0x7e, 0xdb, 0x27, 0x75, 0xd8, 0x7b, 0x0f, 0xdf,
-	0x27, 0x35, 0xa5, 0xeb, 0xe2, 0x78, 0xb5, 0xf6, 0x34, 0xf2, 0x23, 0xf6,
-	0xdf, 0x4e, 0x0c, 0xb6, 0xab, 0x52, 0x8b, 0xec, 0x3a, 0xcb, 0xfd, 0x21,
-	0xf4, 0xab, 0xd4, 0xba, 0x21, 0xf7, 0x6e, 0x55, 0x57, 0xb9, 0x52, 0x0c,
-	0x41, 0x8f, 0x26, 0x6c, 0x3e, 0x84, 0xb6, 0x30, 0xec, 0xa0, 0x0f, 0xed,
-	0x3f, 0xc7, 0xda, 0x8e, 0xa0, 0x7d, 0xa5, 0x73, 0x5c, 0xe1, 0x58, 0x4b,
-	0xce, 0x39, 0x37, 0x11, 0x73, 0xdf, 0x84, 0x1f, 0x1d, 0x44, 0x9f, 0x61,
-	0xf4, 0xf9, 0x14, 0xc6, 0xe1, 0x3b, 0xcd, 0x1b, 0xf1, 0xd4, 0x00, 0x4f,
-	0x7a, 0x0b, 0x4f, 0x0d, 0xf0, 0x03, 0xdf, 0x79, 0x92, 0x35, 0xe8, 0x61,
-	0x39, 0x5a, 0xe4, 0x19, 0x29, 0xbe, 0x17, 0x6f, 0x4a, 0x00, 0x98, 0xb4,
-	0xed, 0x64, 0x34, 0xdc, 0x50, 0xb5, 0x1e, 0xda, 0xd6, 0x50, 0xbc, 0x2a,
-	0x2a, 0xce, 0x44, 0x8e, 0x22, 0x7e, 0xdd, 0x74, 0xba, 0xe5, 0x75, 0x6f,
-	0xac, 0x15, 0xe1, 0xfe, 0xe5, 0xda, 0xb1, 0x8e, 0x95, 0xae, 0x8d, 0xbf,
-	0x6a, 0x19, 0xde, 0xbc, 0x7a, 0x31, 0xd6, 0xaf, 0xa2, 0xef, 0xb5, 0xf1,
-	0xcb, 0xb5, 0x8d, 0xfa, 0xde, 0x44, 0xdf, 0xb6, 0x96, 0xbe, 0x37, 0xd1,
-	0xaf, 0x1b, 0x71, 0xb0, 0x5b, 0xcd, 0x69, 0x16, 0x7c, 0x5d, 0x2f, 0xaa,
-	0xf7, 0xb4, 0x21, 0x77, 0x8e, 0x69, 0x12, 0x53, 0x67, 0xdc, 0x5a, 0x49,
-	0xd4, 0x8c, 0x68, 0xef, 0xa8, 0xf7, 0x28, 0x1b, 0x18, 0xb3, 0x80, 0x7b,
-	0xe7, 0x27, 0xb4, 0x54, 0x35, 0x87, 0x98, 0xf5, 0x30, 0xf1, 0x53, 0xdc,
-	0x46, 0xcc, 0xac, 0x80, 0x5e, 0xad, 0xd8, 0xe0, 0x79, 0x6a, 0xd8, 0xc5,
-	0x2d, 0xe2, 0xec, 0x87, 0x0d, 0x75, 0xae, 0x21, 0xad, 0x6a, 0x76, 0x95,
-	0xa2, 0x98, 0xc9, 0x11, 0x9e, 0x65, 0xf8, 0x0c, 0xd6, 0xe5, 0x57, 0xd0,
-	0x96, 0x44, 0x7c, 0x3c, 0xa0, 0x25, 0xcf, 0x8f, 0xe3, 0xfa, 0x49, 0x5c,
-	0xc3, 0x1f, 0x2f, 0x64, 0x71, 0xff, 0x49, 0x5c, 0x4f, 0x6b, 0xa9, 0x7a,
-	0x16, 0xd7, 0x4f, 0xe1, 0x7a, 0xca, 0x64, 0x9e, 0xf2, 0xaa, 0x95, 0xd1,
-	0x6c, 0xd0, 0xb2, 0xcf, 0x8f, 0xe3, 0xd3, 0x4a, 0x8f, 0xf7, 0xa0, 0xa7,
-	0x22, 0xf7, 0xda, 0x62, 0xe0, 0x69, 0x9f, 0x96, 0xae, 0x76, 0x81, 0xc6,
-	0x00, 0x9e, 0xa7, 0x4d, 0xed, 0xf7, 0xc6, 0x67, 0xcd, 0xe9, 0x63, 0xaa,
-	0xe6, 0x64, 0x24, 0x32, 0xc0, 0xc9, 0x87, 0x91, 0x07, 0x68, 0x92, 0xb6,
-	0x9e, 0x93, 0x42, 0x1c, 0x7e, 0xa5, 0x6a, 0x48, 0x2a, 0x94, 0xc7, 0xef,
-	0xbc, 0x24, 0x47, 0x71, 0xbf, 0x4a, 0x5b, 0x60, 0xbf, 0x3f, 0x95, 0x42,
-	0x99, 0xb8, 0x9f, 0x75, 0x26, 0xd6, 0xa6, 0x58, 0x5f, 0xca, 0x41, 0x06,
-	0x21, 0xda, 0xef, 0x06, 0x35, 0x31, 0xf7, 0x8c, 0x34, 0xe2, 0xb2, 0x96,
-	0xac, 0x72, 0xdf, 0xaf, 0x91, 0xb9, 0x6c, 0xf1, 0xfd, 0xb1, 0x69, 0xee,
-	0x23, 0x16, 0x8c, 0x04, 0xeb, 0x23, 0xaa, 0xbe, 0x1e, 0x77, 0xf7, 0x07,
-	0x5b, 0xcf, 0xa4, 0xf8, 0xeb, 0x85, 0xe3, 0x7e, 0x0d, 0xcf, 0xbb, 0xf5,
-	0xac, 0x54, 0xfd, 0x9d, 0xba, 0xe0, 0x3b, 0x00, 0xe7, 0xa0, 0x8b, 0xcb,
-	0x2a, 0x37, 0xe6, 0x1e, 0xee, 0xbb, 0xe5, 0x54, 0xc8, 0x61, 0x8a, 0xac,
-	0x91, 0xf9, 0xfb, 0x76, 0xbe, 0x1c, 0xd7, 0xf3, 0x4a, 0x3e, 0x67, 0x40,
-	0x53, 0xe2, 0xf4, 0xbb, 0xd9, 0x10, 0xf7, 0xdf, 0xf8, 0x8c, 0x7c, 0xf3,
-	0x2e, 0xdf, 0xe4, 0x99, 0xf2, 0x38, 0x0c, 0xff, 0xc9, 0xf7, 0x2b, 0x9e,
-	0x93, 0x5c, 0x9c, 0x35, 0x1e, 0x03, 0xb1, 0x31, 0x8f, 0xdf, 0x77, 0xe5,
-	0x37, 0xeb, 0xc9, 0x2f, 0x57, 0xfe, 0x2f, 0x4a, 0x87, 0x15, 0x8b, 0xe3,
-	0xf9, 0xb5, 0x8f, 0xbd, 0x4a, 0x77, 0x15, 0x75, 0x7e, 0xd7, 0x97, 0x81,
-	0x5f, 0xbf, 0xdb, 0xd8, 0xf6, 0xc6, 0x2d, 0xf2, 0xf6, 0x10, 0xcf, 0x43,
-	0x0c, 0xda, 0x42, 0xfe, 0x39, 0x0f, 0xc6, 0x30, 0x7f, 0xaf, 0xd5, 0x9f,
-	0x83, 0x3f, 0xcf, 0xfb, 0x95, 0x0f, 0xf9, 0xfd, 0xe4, 0x16, 0xe9, 0xca,
-	0x98, 0x86, 0xc5, 0xd8, 0xf0, 0xb8, 0xb7, 0x3f, 0xf0, 0x7f, 0x43, 0xce,
-	0xae, 0x2c, 0x02, 0x09, 0x99, 0xf5, 0xde, 0xbf, 0xde, 0xc0, 0x1e, 0xd6,
-	0xef, 0x35, 0x37, 0x32, 0x67, 0xad, 0xbb, 0xf3, 0xae, 0x6c, 0x30, 0xef,
-	0x8a, 0x37, 0xef, 0xea, 0x7d, 0xf2, 0x5b, 0x99, 0xb7, 0x31, 0x67, 0xda,
-	0xdc, 0x46, 0xf6, 0x28, 0xea, 0xdd, 0xb0, 0x15, 0x23, 0x18, 0xb4, 0x9d,
-	0x7b, 0xd5, 0x50, 0x99, 0x57, 0xbb, 0x76, 0x79, 0x16, 0xb1, 0xb0, 0x5c,
-	0x76, 0x73, 0xec, 0xb2, 0xc3, 0x5a, 0xf6, 0xbb, 0xf1, 0xc0, 0x77, 0xb9,
-	0xbe, 0xa8, 0xce, 0xbb, 0xcc, 0x3a, 0x6e, 0xdd, 0xab, 0x5c, 0x6e, 0x8d,
-	0xa9, 0x0f, 0x32, 0x9e, 0x0e, 0xe6, 0x65, 0x82, 0xef, 0x94, 0xe3, 0xfa,
-	0x11, 0xb9, 0xb2, 0xa0, 0xf6, 0xac, 0xbc, 0xbd, 0x21, 0xee, 0xf9, 0xa8,
-	0xfd, 0x6f, 0xf8, 0xb5, 0x49, 0xe5, 0xd7, 0x97, 0x17, 0xd4, 0x3d, 0x17,
-	0x2b, 0x39, 0x13, 0xf0, 0xfb, 0xc8, 0x25, 0xac, 0x07, 0xa4, 0x80, 0x9c,
-	0xfb, 0xac, 0x75, 0x78, 0x0b, 0x71, 0x0e, 0x69, 0x2d, 0x83, 0xd6, 0xe5,
-	0x05, 0xd9, 0xc2, 0x33, 0x25, 0x65, 0xb5, 0xcf, 0xe6, 0xd6, 0xc5, 0xa7,
-	0xc5, 0xff, 0x7f, 0x1d, 0x41, 0x2f, 0x16, 0xf2, 0x5c, 0x0b, 0xdf, 0x73,
-	0xa6, 0xaf, 0x40, 0x1e, 0x34, 0xc1, 0x7d, 0x9c, 0x66, 0xd3, 0xad, 0x9b,
-	0x37, 0xb1, 0x2e, 0xda, 0xf8, 0x0e, 0x05, 0xfe, 0x0e, 0xc3, 0x7e, 0xb0,
-	0x4e, 0x56, 0xdb, 0x79, 0xcd, 0xdc, 0xc3, 0xbf, 0x66, 0x60, 0xfb, 0x3f,
-	0xe8, 0xf3, 0x49, 0x14, 0x38, 0x46, 0x00, 0x00, 0x00 };
+	0xbd, 0x7c, 0x7d, 0x70, 0x1c, 0xe7, 0x79, 0xdf, 0xb3, 0xbb, 0x07, 0xe0,
+	0x00, 0x82, 0xe0, 0x12, 0x39, 0x52, 0x27, 0x0a, 0xa6, 0x6e, 0x89, 0x3d,
+	0x08, 0x32, 0x20, 0x71, 0xc5, 0x20, 0x36, 0x26, 0xb9, 0xca, 0xab, 0xbb,
+	0x03, 0x78, 0x94, 0x31, 0x31, 0xc4, 0xc2, 0x16, 0xed, 0x70, 0xd4, 0xeb,
+	0x01, 0xa4, 0x95, 0x54, 0x9e, 0xb2, 0xb6, 0xda, 0x72, 0x5a, 0x35, 0x3a,
+	0x1f, 0xc0, 0x0f, 0x29, 0x47, 0x1c, 0x24, 0xc0, 0x84, 0xfe, 0x70, 0x93,
+	0x13, 0x0e, 0x24, 0x64, 0xf7, 0x88, 0x93, 0xfc, 0xd9, 0x3f, 0x62, 0x0b,
+	0x03, 0xd2, 0xb4, 0x5a, 0xbb, 0xb5, 0xda, 0x28, 0x13, 0xcf, 0xf4, 0x63,
+	0x30, 0x14, 0xa5, 0x28, 0x71, 0xa7, 0x56, 0x9b, 0x4c, 0xa2, 0x36, 0x94,
+	0xaf, 0xbf, 0xdf, 0xbb, 0xbb, 0xe0, 0x01, 0x22, 0x65, 0x51, 0x93, 0x14,
+	0x33, 0x37, 0x77, 0xfb, 0xee, 0xbb, 0xef, 0xfb, 0x7c, 0xbd, 0xcf, 0xf3,
+	0xfc, 0x9e, 0xf7, 0x5d, 0x44, 0x45, 0xda, 0xc4, 0xff, 0xdb, 0x8a, 0x4f,
+	0xec, 0xd8, 0xf1, 0xc7, 0xef, 0xfd, 0xf8, 0xbd, 0xbf, 0x8a, 0x9f, 0xf7,
+	0x89, 0xd6, 0x62, 0xf0, 0xe6, 0x5b, 0x86, 0x48, 0xf6, 0xcf, 0xe5, 0x43,
+	0xff, 0xe1, 0x71, 0x33, 0x18, 0x9f, 0x1f, 0x09, 0xeb, 0x89, 0x57, 0x87,
+	0x93, 0xb6, 0x84, 0x8d, 0x44, 0xfe, 0xa1, 0x71, 0x5b, 0xc4, 0xad, 0xf6,
+	0xc5, 0x52, 0xf2, 0x6e, 0x3d, 0x1f, 0x09, 0x09, 0xdb, 0x3f, 0x92, 0xb8,
+	0xf6, 0xe4, 0xf7, 0x3e, 0x6e, 0xbd, 0x5d, 0x36, 0x24, 0x6c, 0x26, 0xb2,
+	0x62, 0xf6, 0x48, 0xb8, 0x0b, 0xcf, 0x7c, 0xf5, 0xae, 0x47, 0x0d, 0xe9,
+	0x08, 0xc6, 0x7a, 0xab, 0xfe, 0xbd, 0xbb, 0x24, 0xbf, 0x2b, 0x51, 0x8f,
+	0x85, 0x12, 0xef, 0xd6, 0xa7, 0x06, 0xc2, 0xa2, 0x27, 0xac, 0x68, 0xd2,
+	0x88, 0xc8, 0xcb, 0x35, 0x53, 0x5e, 0xac, 0xc5, 0x64, 0xb2, 0x26, 0x1d,
+	0xe9, 0xda, 0x8d, 0x68, 0xaa, 0xa3, 0xef, 0xbb, 0xf5, 0xe4, 0x40, 0x28,
+	0x6b, 0x24, 0xa4, 0x23, 0x59, 0x93, 0xd1, 0x63, 0xc5, 0xd6, 0x87, 0x9b,
+	0x12, 0x4f, 0xd6, 0x75, 0x5b, 0xb2, 0xa1, 0x84, 0x9d, 0xd7, 0xf5, 0xf6,
+	0x41, 0xf3, 0x63, 0x68, 0xaf, 0x0e, 0x86, 0x26, 0x8b, 0xa6, 0x9c, 0x1b,
+	0x68, 0x15, 0xdd, 0x0e, 0x4b, 0xb2, 0xd6, 0xfa, 0xb0, 0x9e, 0x88, 0x88,
+	0x5b, 0xab, 0xd7, 0x8f, 0x39, 0xff, 0x64, 0xaf, 0xf9, 0xeb, 0xe1, 0xf0,
+	0x64, 0x51, 0xde, 0x0e, 0xd9, 0x76, 0x74, 0x42, 0x7a, 0xcc, 0x9c, 0x68,
+	0x92, 0xec, 0xef, 0x89, 0x1e, 0xc1, 0xf7, 0x78, 0x7f, 0xdc, 0x4c, 0xc9,
+	0x16, 0x71, 0xcd, 0x6f, 0xae, 0x98, 0x3d, 0x5d, 0x59, 0x3d, 0x11, 0x96,
+	0x74, 0x51, 0x13, 0xc3, 0x8e, 0xc8, 0x64, 0xc5, 0x96, 0xfc, 0x52, 0x87,
+	0xe4, 0x2b, 0xf2, 0xc4, 0x94, 0xd3, 0x2e, 0x53, 0x4b, 0x47, 0x7d, 0x5d,
+	0x44, 0xd0, 0xd6, 0x2b, 0xf9, 0x5a, 0x14, 0x9f, 0x9f, 0xf8, 0xfc, 0xea,
+	0x22, 0x3b, 0x05, 0xcf, 0xf7, 0xa7, 0xdd, 0xea, 0xd7, 0xc2, 0x5e, 0xdb,
+	0x7f, 0xd9, 0xe2, 0x7d, 0x83, 0xdf, 0x12, 0xf8, 0x2d, 0x85, 0x65, 0xcd,
+	0x88, 0xca, 0xf7, 0xee, 0x8a, 0xc9, 0x54, 0x69, 0x0d, 0xb2, 0x89, 0xca,
+	0x37, 0x6a, 0x11, 0x79, 0x49, 0xc9, 0x22, 0xa4, 0x0d, 0xa3, 0xcf, 0x64,
+	0x69, 0x42, 0x3f, 0x51, 0xcc, 0x4b, 0xaa, 0x96, 0xd5, 0x0b, 0x73, 0x66,
+	0x47, 0x72, 0x29, 0xa7, 0x4f, 0xce, 0x75, 0x76, 0xa4, 0x96, 0x26, 0xf4,
+	0x42, 0x31, 0x0a, 0x39, 0x98, 0x1d, 0xa9, 0xf9, 0x08, 0xae, 0x3b, 0x3b,
+	0x92, 0xf3, 0xd6, 0x0c, 0x26, 0x45, 0x9f, 0x68, 0x47, 0xaa, 0x64, 0x65,
+	0x45, 0xba, 0x9d, 0x1f, 0x48, 0x57, 0x47, 0xaa, 0xf6, 0x5b, 0xfa, 0x8a,
+	0xa9, 0x49, 0xe1, 0x1e, 0x31, 0xa3, 0x89, 0xb7, 0xeb, 0xb7, 0xdb, 0x9a,
+	0x98, 0xf6, 0x3b, 0xf5, 0xed, 0x90, 0x4d, 0x6e, 0xb6, 0x15, 0xbc, 0x92,
+	0x26, 0x53, 0x72, 0xf3, 0x7d, 0xe6, 0xaa, 0x34, 0x89, 0x1b, 0x09, 0xae,
+	0xeb, 0xf5, 0xa4, 0xf3, 0x07, 0xe4, 0x91, 0xf2, 0xee, 0x18, 0x86, 0x5e,
+	0x92, 0xa0, 0x39, 0xe9, 0xbc, 0x5b, 0xf7, 0x9e, 0x09, 0x63, 0xce, 0x50,
+	0xc7, 0x50, 0xa9, 0x5e, 0x4f, 0x3b, 0x18, 0xdf, 0x09, 0x9e, 0x6d, 0x92,
+	0x72, 0xc4, 0x2d, 0x4f, 0x3a, 0x96, 0xe1, 0xc9, 0x87, 0xba, 0xe7, 0xb5,
+	0x0b, 0x7d, 0xe4, 0x25, 0x17, 0x91, 0x72, 0xc1, 0xf9, 0x98, 0x3c, 0xe5,
+	0x44, 0xc1, 0x5f, 0x58, 0x4e, 0x39, 0xb0, 0x2f, 0xfb, 0xb8, 0x96, 0xac,
+	0x59, 0xb1, 0xac, 0x3c, 0x2d, 0xc9, 0xf9, 0x6e, 0x33, 0x2d, 0x98, 0xdb,
+	0xae, 0xdf, 0x99, 0x74, 0x30, 0x5f, 0xff, 0xff, 0xad, 0xbb, 0x11, 0x2b,
+	0x5b, 0x96, 0x5e, 0x29, 0x94, 0xba, 0x9d, 0x1f, 0x43, 0x4f, 0x61, 0x5b,
+	0xdc, 0x71, 0xdb, 0x84, 0xdc, 0xac, 0xde, 0x94, 0x51, 0x97, 0x07, 0x31,
+	0x7f, 0xd2, 0xc6, 0xfd, 0x9a, 0x6c, 0xd3, 0xed, 0x66, 0x29, 0x98, 0x12,
+	0x69, 0x93, 0xdd, 0x52, 0x98, 0x45, 0xbb, 0xe3, 0x76, 0xea, 0x78, 0x26,
+	0x33, 0xc0, 0x36, 0xd1, 0x8c, 0x04, 0x75, 0x2c, 0xb2, 0x50, 0xed, 0xc5,
+	0xfc, 0x71, 0xb7, 0x55, 0x33, 0x65, 0xcd, 0x0c, 0x49, 0xa5, 0x1a, 0x77,
+	0xa3, 0x5a, 0xb3, 0x9c, 0x8a, 0xb7, 0x41, 0xa6, 0x51, 0x8c, 0x2d, 0x5f,
+	0xd6, 0x13, 0xf1, 0x68, 0x0e, 0x4a, 0xa3, 0x1d, 0x4d, 0x81, 0x9e, 0x29,
+	0x27, 0xab, 0xa5, 0x6a, 0x9f, 0xd3, 0x92, 0x4b, 0x87, 0xb4, 0xfd, 0x4b,
+	0xe8, 0x53, 0xfb, 0x1f, 0xbe, 0x0d, 0x44, 0x41, 0x9b, 0x8e, 0x67, 0xd9,
+	0x0e, 0x9a, 0x15, 0xed, 0x68, 0x83, 0x2e, 0x57, 0xc6, 0x22, 0x1d, 0x49,
+	0xa5, 0x4b, 0xd2, 0xa6, 0x4b, 0x6e, 0x54, 0x93, 0x4e, 0xdb, 0x95, 0xf0,
+	0xaf, 0x41, 0x9f, 0xf3, 0xd0, 0xe5, 0x7c, 0x4c, 0x4e, 0x94, 0x24, 0xa2,
+	0x0b, 0xe7, 0xca, 0xea, 0x95, 0x2a, 0xed, 0x01, 0xba, 0x85, 0xee, 0x0b,
+	0x55, 0x3e, 0x0b, 0x1d, 0x96, 0xd2, 0x90, 0x4f, 0x06, 0x73, 0x1f, 0xd4,
+	0x1e, 0xac, 0x8c, 0x69, 0x19, 0xd8, 0x49, 0x61, 0xb6, 0x0f, 0xba, 0xb3,
+	0x62, 0x6b, 0xb2, 0x4d, 0x0a, 0xb6, 0x1d, 0xfb, 0xac, 0xb4, 0xcb, 0xa9,
+	0x79, 0x5b, 0x4e, 0xcc, 0xc3, 0x1e, 0x4d, 0xcb, 0x5c, 0x94, 0xae, 0xec,
+	0x96, 0x44, 0x87, 0x3c, 0x3d, 0x6b, 0x65, 0xca, 0xd2, 0xed, 0xbe, 0x81,
+	0xfb, 0xb9, 0x33, 0xd4, 0xa9, 0xe4, 0x53, 0x8e, 0x21, 0x59, 0x93, 0x76,
+	0x7d, 0x9b, 0x26, 0x6d, 0xf5, 0x27, 0x93, 0x8e, 0x15, 0xa5, 0xcd, 0xa6,
+	0x3e, 0xdd, 0x6d, 0x1e, 0x10, 0xcb, 0xcc, 0x50, 0xfe, 0x4e, 0x1f, 0xf4,
+	0xf0, 0xbf, 0x29, 0x7b, 0x8c, 0x45, 0x1d, 0xf7, 0x45, 0x4f, 0x41, 0x97,
+	0x59, 0xa5, 0xe3, 0x0e, 0xcc, 0x1f, 0xf2, 0x6d, 0x87, 0x6b, 0xe2, 0x6e,
+	0xcd, 0x93, 0x43, 0x87, 0xcc, 0x54, 0xda, 0xa5, 0x00, 0x1d, 0x16, 0xc4,
+	0x96, 0xc2, 0xd2, 0x5e, 0xbf, 0xdd, 0xc6, 0x7a, 0xf9, 0x53, 0x5d, 0xda,
+	0x8e, 0x6b, 0x87, 0x6a, 0x3f, 0xd7, 0x7c, 0xfb, 0x81, 0xfd, 0x85, 0xc5,
+	0x1d, 0x0d, 0xcb, 0xf9, 0x9a, 0x67, 0x7f, 0x0b, 0xf0, 0x3d, 0xae, 0xe9,
+	0xc2, 0x96, 0xde, 0x5c, 0xef, 0x73, 0xbe, 0xd6, 0x85, 0x67, 0xc3, 0x72,
+	0xa2, 0xc6, 0xfe, 0x79, 0xd8, 0x58, 0x58, 0x96, 0xef, 0x6a, 0x97, 0x2c,
+	0xda, 0x0b, 0xf3, 0xe2, 0x26, 0x1d, 0x1d, 0xcf, 0x74, 0x80, 0x97, 0x9d,
+	0xf8, 0xb4, 0xc9, 0x78, 0xa5, 0xc5, 0xe5, 0x7a, 0x1d, 0xaf, 0x51, 0xff,
+	0xf8, 0x2e, 0x05, 0x36, 0x40, 0xf9, 0xb2, 0x9d, 0xcf, 0xb1, 0xdd, 0x44,
+	0x7b, 0x63, 0x1b, 0x6d, 0x7b, 0x1b, 0x65, 0xda, 0xcb, 0x35, 0x9a, 0x2b,
+	0xc5, 0xcd, 0x43, 0xfc, 0xae, 0xd1, 0x1e, 0x1a, 0x6d, 0x21, 0x84, 0xfe,
+	0xd0, 0x63, 0x05, 0x73, 0xcd, 0x5e, 0xab, 0x37, 0x0d, 0xe0, 0xda, 0xfe,
+	0x1d, 0xf0, 0xc9, 0xb9, 0x43, 0xa0, 0x4b, 0x97, 0x6c, 0x45, 0xd1, 0x16,
+	0xa3, 0x0d, 0x78, 0x7c, 0x74, 0xc9, 0xe4, 0x7c, 0x7b, 0x47, 0x7a, 0x9e,
+	0xed, 0xc9, 0xa8, 0x01, 0x3e, 0xc7, 0x1d, 0x59, 0x99, 0x72, 0xf4, 0xee,
+	0x10, 0xe8, 0x9a, 0xc0, 0x82, 0x03, 0x1f, 0x3e, 0x8d, 0x2b, 0xb8, 0xdf,
+	0x29, 0xe3, 0x4b, 0xec, 0xcb, 0x39, 0x0a, 0xdb, 0x75, 0x49, 0x80, 0x36,
+	0x7c, 0x6c, 0x0b, 0xf7, 0x5b, 0x31, 0x4f, 0x3b, 0x6c, 0x67, 0x9a, 0xba,
+	0xfb, 0x44, 0xd2, 0xe9, 0x94, 0xec, 0x7a, 0x5f, 0x81, 0xdd, 0xb1, 0x7f,
+	0xef, 0xa6, 0xbe, 0x90, 0xef, 0x12, 0xc6, 0x9c, 0x6f, 0x85, 0x0c, 0xd9,
+	0xae, 0x83, 0xe6, 0x16, 0xd0, 0x00, 0x1f, 0x6c, 0x77, 0x63, 0x3d, 0xb4,
+	0x60, 0xfc, 0x2d, 0xe0, 0xa9, 0x55, 0x26, 0x66, 0x3b, 0xa1, 0x0b, 0x13,
+	0x7d, 0xc3, 0xf2, 0x74, 0xc9, 0x82, 0x0d, 0xb0, 0x3f, 0x74, 0x30, 0x6f,
+	0x45, 0x2b, 0xe2, 0xca, 0x94, 0xd3, 0x02, 0xfb, 0xaa, 0xd7, 0x8f, 0xc0,
+	0x3e, 0xbe, 0xae, 0xfc, 0x45, 0x9f, 0x39, 0xa4, 0x49, 0xbe, 0x25, 0xf1,
+	0x7d, 0xd0, 0x63, 0x3d, 0x2a, 0xc2, 0xeb, 0xbd, 0x1a, 0xd7, 0x2c, 0xe4,
+	0xc8, 0xb9, 0xe1, 0x93, 0x76, 0x42, 0x86, 0xf4, 0x5b, 0x5d, 0xb0, 0xe7,
+	0xa8, 0xf2, 0x27, 0x43, 0x37, 0xf4, 0x27, 0xd6, 0x68, 0x19, 0x73, 0x15,
+	0x96, 0x42, 0xf4, 0x61, 0x83, 0x58, 0xae, 0xb2, 0x15, 0x6b, 0x6f, 0x52,
+	0xd9, 0xc7, 0x4f, 0xc8, 0x6f, 0xfd, 0x53, 0x0e, 0xe9, 0x22, 0xbf, 0x2e,
+	0x9e, 0xa5, 0x0d, 0x5a, 0xc7, 0x5d, 0x35, 0xff, 0x4f, 0xfc, 0xf9, 0x3d,
+	0xda, 0x0b, 0xa5, 0x0e, 0x2d, 0xa5, 0x68, 0x08, 0xc6, 0x11, 0x59, 0x3d,
+	0xd3, 0x6d, 0x3e, 0x08, 0x1b, 0xa6, 0x9f, 0x5a, 0xbd, 0x40, 0x1d, 0x63,
+	0x8c, 0x01, 0xea, 0xd8, 0x54, 0xf4, 0x25, 0xe7, 0xb9, 0xf6, 0xa4, 0xcb,
+	0x10, 0xfa, 0x08, 0xf8, 0x5c, 0xac, 0xc5, 0x49, 0x7f, 0x2d, 0xe6, 0xaa,
+	0xb4, 0xbf, 0xc7, 0xf1, 0xac, 0x2e, 0x43, 0x71, 0xfa, 0x87, 0xa7, 0x25,
+	0x05, 0x1f, 0x09, 0x3d, 0x4a, 0x05, 0xbc, 0x2c, 0x94, 0x1a, 0xfd, 0x16,
+	0x6c, 0xab, 0xff, 0xaf, 0xeb, 0x9e, 0x3f, 0xa4, 0x6f, 0xa0, 0xaf, 0x29,
+	0x98, 0x3a, 0x24, 0x87, 0xc8, 0xe0, 0x42, 0x37, 0x4e, 0xd2, 0xb0, 0x32,
+	0x59, 0xc6, 0x1c, 0xbb, 0x2e, 0xf6, 0x7d, 0x82, 0x48, 0xda, 0xcb, 0xf8,
+	0xb7, 0x2f, 0xf0, 0x4f, 0xab, 0xd5, 0x40, 0x17, 0xd4, 0x2b, 0xf5, 0x10,
+	0xf8, 0x88, 0x90, 0x5c, 0x84, 0xef, 0x9a, 0x2a, 0xb5, 0xcb, 0x0a, 0x68,
+	0xba, 0x54, 0x0d, 0x6c, 0xcd, 0xf0, 0x6d, 0x8d, 0xcf, 0xb4, 0xe3, 0xf9,
+	0x10, 0xfc, 0x9a, 0xe4, 0x8d, 0x04, 0x7e, 0x17, 0x39, 0x26, 0xdb, 0x02,
+	0x3b, 0xe7, 0x9a, 0xb1, 0xdc, 0xb2, 0x34, 0x4b, 0x26, 0x8e, 0xf8, 0x31,
+	0xaf, 0x63, 0xae, 0x2e, 0xf8, 0xf2, 0x90, 0x1c, 0x2d, 0x45, 0xe4, 0xf3,
+	0x25, 0xf2, 0x95, 0xd6, 0x52, 0xd0, 0x5b, 0x72, 0xbe, 0x0e, 0x9d, 0x0f,
+	0xc3, 0xe7, 0x65, 0xb4, 0x21, 0xf8, 0x9f, 0x03, 0x95, 0xcf, 0x69, 0xe9,
+	0xa5, 0xac, 0x36, 0x5c, 0x3b, 0xa4, 0x65, 0x96, 0xc6, 0xb4, 0xfd, 0x0d,
+	0xbe, 0x48, 0xb4, 0xf7, 0xf7, 0x45, 0x4f, 0xcd, 0x72, 0xce, 0x6e, 0xe7,
+	0xc6, 0xbe, 0xe8, 0xd7, 0xf5, 0x46, 0x5f, 0xd4, 0x0d, 0x5f, 0x94, 0x81,
+	0x2f, 0x1a, 0xbe, 0x65, 0x5f, 0x34, 0xa2, 0xdf, 0xd8, 0x17, 0x1d, 0xd4,
+	0xaf, 0xfb, 0x22, 0xc6, 0x9e, 0x15, 0x5c, 0x9b, 0xb2, 0x67, 0x5f, 0x20,
+	0xe7, 0x28, 0xfc, 0xf0, 0x16, 0xc8, 0xba, 0x8d, 0x6b, 0x27, 0x56, 0x80,
+	0xdd, 0x4f, 0x60, 0xae, 0xdf, 0x86, 0xbd, 0xef, 0x89, 0xdb, 0xe6, 0x43,
+	0x6a, 0xde, 0xf7, 0xea, 0x7c, 0x68, 0x5d, 0xe7, 0xa4, 0xf1, 0x97, 0xea,
+	0xdc, 0xf5, 0x74, 0x4e, 0x5d, 0xb7, 0xca, 0x11, 0x35, 0x6f, 0x5d, 0x42,
+	0xf7, 0x09, 0xbc, 0x8a, 0x3c, 0x60, 0x24, 0x2c, 0x8c, 0xa7, 0x63, 0x7e,
+	0xea, 0x2b, 0x0e, 0x1a, 0x04, 0xfa, 0x6d, 0x57, 0xbe, 0x68, 0x3f, 0xf4,
+	0xbe, 0x5a, 0xbd, 0x35, 0x5d, 0x65, 0x1a, 0x74, 0xf5, 0xe0, 0x06, 0x5d,
+	0xb5, 0x48, 0x7f, 0x3c, 0xd0, 0xd1, 0x36, 0x49, 0xc6, 0xa9, 0xb3, 0x5b,
+	0xd1, 0xd5, 0xb9, 0xbf, 0x25, 0x5d, 0x7d, 0xf7, 0x26, 0xba, 0xfa, 0xde,
+	0x26, 0x5d, 0xd9, 0xe6, 0x33, 0x1a, 0xc7, 0x66, 0xfc, 0xa0, 0x3f, 0xaa,
+	0xdf, 0x39, 0xce, 0xfc, 0xa1, 0xc6, 0x35, 0x1d, 0xe4, 0x1d, 0x5c, 0xcf,
+	0x2f, 0xd7, 0x0d, 0xdb, 0x86, 0xec, 0xb8, 0xa6, 0x29, 0x37, 0xcb, 0xfc,
+	0x14, 0xe9, 0x47, 0xec, 0x18, 0x47, 0xac, 0xf1, 0x68, 0x68, 0x96, 0xf2,
+	0x76, 0xaf, 0xff, 0x78, 0xa9, 0xfe, 0x73, 0x3d, 0xf1, 0x0b, 0xe4, 0x95,
+	0xb6, 0x1f, 0x07, 0xc2, 0xf2, 0x85, 0x8a, 0x95, 0x75, 0xb5, 0x76, 0xc9,
+	0xef, 0x40, 0xec, 0x29, 0xd1, 0x7f, 0xed, 0xbc, 0x49, 0x8c, 0xee, 0xf2,
+	0x63, 0xf4, 0x9f, 0x81, 0x56, 0xe6, 0x57, 0xff, 0xe6, 0xdd, 0x95, 0x08,
+	0xbf, 0xe3, 0xe6, 0x41, 0xf9, 0x2c, 0x79, 0x44, 0xbc, 0x67, 0xdc, 0xb7,
+	0x99, 0xf3, 0xe4, 0x43, 0x89, 0x36, 0xc9, 0x6f, 0xe7, 0x7a, 0xa4, 0x9f,
+	0xa3, 0xef, 0x6a, 0xf6, 0xe9, 0x0e, 0x72, 0x24, 0xfe, 0xb5, 0x18, 0x60,
+	0x19, 0x7d, 0x90, 0x0f, 0x95, 0xc8, 0xc7, 0xbb, 0xbe, 0x3d, 0x31, 0x57,
+	0x90, 0x26, 0xcf, 0x37, 0x8c, 0x20, 0x17, 0xa0, 0x1d, 0x04, 0x3a, 0xa7,
+	0xbe, 0x99, 0x23, 0x48, 0x4c, 0xb7, 0x99, 0x23, 0x88, 0x69, 0x24, 0x0e,
+	0x6a, 0x2e, 0x74, 0xef, 0x42, 0xf7, 0x2e, 0x74, 0xef, 0x42, 0xf7, 0xc9,
+	0xda, 0x71, 0xdc, 0x53, 0x79, 0x08, 0x68, 0xf1, 0xc6, 0x4f, 0x7b, 0xe3,
+	0x83, 0xce, 0x9d, 0x92, 0x53, 0x3a, 0x21, 0xbf, 0xc8, 0x35, 0x94, 0xbf,
+	0x1e, 0xd6, 0x3c, 0x7f, 0xcd, 0xf1, 0x32, 0x78, 0xfe, 0x7e, 0xe4, 0x73,
+	0xae, 0xae, 0xdb, 0xd7, 0x65, 0x32, 0xd5, 0x20, 0x93, 0xc9, 0x2a, 0x65,
+	0xc4, 0xfe, 0xf4, 0xb9, 0x13, 0xfa, 0xc2, 0xba, 0x5c, 0x46, 0x40, 0x43,
+	0x0b, 0x79, 0xf7, 0xf9, 0xe0, 0xf8, 0x9d, 0xfe, 0xf8, 0xbf, 0x81, 0x31,
+	0xe9, 0x5f, 0x6f, 0x34, 0x2f, 0xe7, 0x64, 0xce, 0xf8, 0x7e, 0xfc, 0x20,
+	0x67, 0xc6, 0x1a, 0x78, 0x69, 0x3d, 0x9f, 0x8e, 0x21, 0x9f, 0x7e, 0x07,
+	0xb9, 0x74, 0xbd, 0xce, 0x38, 0x55, 0x40, 0x9e, 0x9b, 0x76, 0xb8, 0xae,
+	0x6f, 0x65, 0xdd, 0x6e, 0x58, 0xb3, 0x66, 0xd2, 0xe0, 0xb8, 0x61, 0xf1,
+	0xc6, 0xe4, 0xfd, 0x16, 0xe4, 0x82, 0xef, 0xe0, 0x37, 0x7d, 0x72, 0x90,
+	0xe7, 0xb1, 0x0f, 0x9f, 0x7f, 0x15, 0x73, 0xf7, 0x03, 0xcf, 0xf4, 0xca,
+	0x77, 0x6a, 0xb6, 0x7c, 0x1b, 0x98, 0xe6, 0x5b, 0xc8, 0x2d, 0xbe, 0x59,
+	0x0b, 0x72, 0xfb, 0xbd, 0x30, 0x75, 0xe6, 0xf7, 0x12, 0xde, 0x69, 0x13,
+	0x57, 0xe5, 0xf7, 0x7f, 0xda, 0x96, 0xad, 0x11, 0xfc, 0xfe, 0x95, 0x84,
+	0x6c, 0xeb, 0xc4, 0xf7, 0xf6, 0x04, 0x4c, 0x27, 0xc1, 0xd8, 0xa8, 0x35,
+	0xc4, 0x46, 0xd1, 0xd2, 0xe0, 0x71, 0x0a, 0xe3, 0xa5, 0xc1, 0xf7, 0x67,
+	0x6a, 0x61, 0x2d, 0x35, 0xbb, 0x1b, 0x98, 0x24, 0xc8, 0x71, 0x91, 0x47,
+	0x99, 0xab, 0xdb, 0x43, 0xf2, 0x36, 0x78, 0x4a, 0x82, 0x76, 0x17, 0x39,
+	0xc0, 0x3f, 0xc5, 0x5c, 0xd6, 0x4f, 0x3f, 0x2d, 0xff, 0xda, 0xcf, 0xc3,
+	0x9b, 0x64, 0x4e, 0xf1, 0xc8, 0x76, 0xc9, 0xfc, 0xcb, 0x9e, 0xeb, 0xed,
+	0xcf, 0xae, 0xb7, 0xc7, 0x32, 0xbf, 0xb1, 0xde, 0x7e, 0x35, 0xe4, 0xe1,
+	0x95, 0x41, 0x6d, 0xb4, 0xf6, 0x2f, 0x8c, 0x00, 0xeb, 0x14, 0x66, 0x7b,
+	0x31, 0xd7, 0x36, 0x99, 0xb4, 0xdf, 0x06, 0xf6, 0xb2, 0x63, 0x39, 0xac,
+	0xaf, 0xa7, 0x36, 0xf9, 0xfa, 0x36, 0xf8, 0x8f, 0xd3, 0xb3, 0xd6, 0x20,
+	0xfd, 0x47, 0x1c, 0x6b, 0x29, 0xf9, 0x1e, 0xff, 0xf1, 0x6d, 0xa3, 0xd1,
+	0x7f, 0x18, 0xf0, 0x1f, 0xfb, 0xdf, 0xc7, 0x7f, 0x3c, 0xf5, 0x1e, 0xff,
+	0xa1, 0xc1, 0x2e, 0xe8, 0x3f, 0x7e, 0x68, 0x04, 0xfe, 0xa3, 0xb0, 0xc1,
+	0x7f, 0x04, 0xfa, 0xb0, 0x55, 0xee, 0xe8, 0xfd, 0x26, 0xfe, 0x6c, 0xf3,
+	0x31, 0xa7, 0x84, 0x43, 0x09, 0x37, 0x33, 0x65, 0xef, 0x92, 0x26, 0xac,
+	0xd1, 0x97, 0x6b, 0x03, 0xf0, 0x25, 0xbf, 0x0f, 0x9c, 0x66, 0x39, 0x4c,
+	0x44, 0x9a, 0x12, 0xd4, 0xcd, 0x48, 0x2c, 0x69, 0xbf, 0x90, 0x59, 0xa8,
+	0xbe, 0x90, 0x39, 0xa7, 0x74, 0x35, 0x61, 0x79, 0x18, 0xf8, 0x09, 0x0b,
+	0x18, 0x18, 0xcf, 0x87, 0x80, 0x21, 0xd8, 0xde, 0x6e, 0x26, 0x91, 0xa3,
+	0x54, 0xaa, 0x2b, 0x99, 0x02, 0x3e, 0x53, 0xaa, 0xef, 0x58, 0x8c, 0x7d,
+	0x5b, 0x12, 0xe5, 0xd8, 0x9f, 0xe2, 0xbb, 0x39, 0x31, 0x67, 0x5d, 0xb6,
+	0x39, 0xee, 0x6b, 0xb1, 0x73, 0x6a, 0x8c, 0x90, 0x14, 0xd4, 0xb3, 0x5f,
+	0xb5, 0xf8, 0xec, 0x29, 0xf8, 0xf8, 0x93, 0x55, 0x53, 0x4e, 0x54, 0xd7,
+	0x32, 0x39, 0x7c, 0x88, 0x6d, 0x5e, 0x2e, 0xf1, 0xfe, 0xb7, 0x70, 0x3f,
+	0x24, 0xcc, 0x3d, 0x3e, 0x8f, 0x3e, 0x47, 0xd1, 0xe7, 0x48, 0x35, 0xc0,
+	0x8d, 0xbc, 0xef, 0x66, 0x52, 0xb8, 0x7f, 0xa4, 0xe8, 0x66, 0xd2, 0x45,
+	0xe6, 0x39, 0x7d, 0xd1, 0x13, 0x90, 0x67, 0x16, 0xb1, 0xdd, 0x15, 0xab,
+	0x37, 0x2f, 0x8f, 0xb5, 0x0e, 0x23, 0xaf, 0x3e, 0x8f, 0x98, 0xe3, 0x8e,
+	0x59, 0x4e, 0x19, 0xcc, 0x4d, 0x95, 0xee, 0x90, 0xc2, 0x0c, 0x62, 0x8c,
+	0x73, 0x0f, 0x73, 0xed, 0x8c, 0x1e, 0x77, 0xe0, 0x13, 0x06, 0x80, 0x27,
+	0xbb, 0x81, 0x85, 0xef, 0x92, 0x15, 0xd3, 0x8a, 0x0e, 0x03, 0x03, 0xa7,
+	0x42, 0xe8, 0xd3, 0x7b, 0x9b, 0x64, 0xa3, 0x94, 0xf5, 0x0e, 0xf8, 0x07,
+	0x4d, 0x5a, 0xec, 0x46, 0x5f, 0xf5, 0x17, 0x10, 0x2f, 0x92, 0xdf, 0x36,
+	0xb6, 0xb7, 0xfa, 0x3a, 0xd9, 0x22, 0xab, 0xef, 0xe9, 0xf7, 0x37, 0x0d,
+	0xfd, 0x1a, 0xdb, 0x35, 0x4d, 0xd0, 0x7f, 0x0d, 0x34, 0x84, 0xe2, 0x90,
+	0x3f, 0x78, 0x68, 0x82, 0x9d, 0x5c, 0x06, 0x3f, 0xf4, 0x9b, 0x85, 0x32,
+	0xe3, 0xa4, 0x21, 0x65, 0x13, 0xf7, 0xaa, 0xf5, 0xfa, 0x82, 0x0d, 0x5a,
+	0x2f, 0x90, 0xde, 0xb0, 0x0c, 0x57, 0x7b, 0xc4, 0x5d, 0xa4, 0x1c, 0x2c,
+	0xac, 0x8e, 0x5d, 0x6d, 0xa9, 0x79, 0xcb, 0xcd, 0x63, 0x44, 0xe3, 0x42,
+	0x57, 0x5b, 0x12, 0x71, 0x51, 0xbf, 0x10, 0x6b, 0x4b, 0xc1, 0x1f, 0x18,
+	0x17, 0x6e, 0x6f, 0x4b, 0xcf, 0x92, 0x2e, 0x03, 0x71, 0xf1, 0x4e, 0xe0,
+	0xc2, 0xba, 0x7c, 0x0d, 0xb9, 0x4f, 0xa1, 0x17, 0x31, 0x03, 0xab, 0x44,
+	0x07, 0xdd, 0x79, 0x53, 0xc2, 0x6d, 0x89, 0x79, 0xd0, 0xd7, 0xdf, 0x9a,
+	0x9c, 0xdd, 0x82, 0x3e, 0x06, 0xda, 0x7b, 0x88, 0x21, 0x1b, 0xda, 0xed,
+	0x36, 0xf8, 0x5f, 0xf8, 0x3a, 0x09, 0x27, 0x07, 0xda, 0x31, 0xfe, 0xd9,
+	0x10, 0x73, 0x87, 0x70, 0x7c, 0xbd, 0xfd, 0xcb, 0x5e, 0x7b, 0x2f, 0x68,
+	0xe1, 0x73, 0xcc, 0x21, 0x25, 0x3c, 0x3e, 0x60, 0x82, 0x06, 0xf6, 0x8d,
+	0xa8, 0xbe, 0xe9, 0x79, 0xda, 0x80, 0x9b, 0x59, 0xb0, 0x77, 0x4b, 0x6a,
+	0x6e, 0xa7, 0x0c, 0xcf, 0x75, 0xca, 0xfe, 0x39, 0xe6, 0xbc, 0xc4, 0xc0,
+	0x60, 0x05, 0x39, 0xa9, 0x7e, 0x81, 0xb9, 0x80, 0x15, 0x3d, 0x2a, 0xdd,
+	0xd1, 0xcf, 0x63, 0x1d, 0x8c, 0xdb, 0xf1, 0xd8, 0x24, 0xd6, 0x58, 0x48,
+	0x8d, 0x13, 0x0d, 0xe6, 0xa4, 0x8d, 0x6e, 0x98, 0x37, 0x3d, 0x7f, 0xb3,
+	0x71, 0xb1, 0x70, 0x2e, 0x44, 0x37, 0x8d, 0xfb, 0x3f, 0xfd, 0x71, 0x4d,
+	0x8c, 0xdb, 0x85, 0x31, 0xc9, 0xe3, 0xed, 0xad, 0x43, 0xb3, 0xe2, 0xb6,
+	0x80, 0xbe, 0x74, 0x7c, 0x97, 0x4c, 0x62, 0x9c, 0x93, 0x73, 0xf4, 0x85,
+	0xb2, 0x13, 0x9f, 0xfe, 0x26, 0x89, 0xf7, 0x2e, 0x21, 0x2f, 0x1e, 0x52,
+	0x63, 0x78, 0x39, 0xaa, 0x7e, 0x21, 0x01, 0x5c, 0xf3, 0x51, 0xd0, 0xc3,
+	0x98, 0x4c, 0x9e, 0x43, 0xe0, 0x37, 0x81, 0x75, 0x48, 0x3c, 0xce, 0xf5,
+	0x8d, 0xdf, 0x4b, 0xd1, 0xd6, 0xd4, 0x6c, 0x33, 0xd6, 0x9d, 0xec, 0x36,
+	0x54, 0xac, 0xa0, 0x5e, 0xec, 0xd6, 0x64, 0x49, 0xd1, 0xdd, 0x9a, 0x2a,
+	0x51, 0x46, 0x4e, 0x6b, 0xba, 0x44, 0x19, 0x09, 0xe8, 0x71, 0xe0, 0x63,
+	0x43, 0x12, 0xdb, 0x4e, 0x3d, 0x1e, 0x43, 0xbf, 0x95, 0x10, 0xf3, 0xfe,
+	0xa4, 0xcd, 0xdf, 0xc0, 0x2b, 0x17, 0x8e, 0xa3, 0x2f, 0x7f, 0xdf, 0x8b,
+	0x71, 0xbb, 0x7b, 0x0b, 0xd2, 0xdc, 0x7b, 0x04, 0x7e, 0x42, 0x1f, 0x00,
+	0xee, 0x50, 0x76, 0x5e, 0x07, 0x26, 0xdb, 0x0b, 0x7e, 0xb0, 0x36, 0xe2,
+	0xb6, 0x4c, 0xcc, 0x50, 0xae, 0x72, 0x1b, 0x78, 0x00, 0xff, 0x71, 0xf8,
+	0x16, 0xf2, 0xc0, 0xb9, 0x05, 0x76, 0xbf, 0x2c, 0xb9, 0x99, 0xb0, 0xc2,
+	0x3e, 0xae, 0xc9, 0xf9, 0x35, 0x4d, 0x4f, 0xb4, 0x41, 0xc7, 0xe4, 0x6d,
+	0x0a, 0xb4, 0x3d, 0x0e, 0x3f, 0x6c, 0xa9, 0x9c, 0xdb, 0x40, 0xff, 0x42,
+	0x69, 0x50, 0x4f, 0x15, 0x49, 0xbf, 0x6f, 0x7b, 0xda, 0x0a, 0x7c, 0x8a,
+	0xaa, 0x63, 0x21, 0xb7, 0x4b, 0xc0, 0x8f, 0x0c, 0xca, 0xf7, 0xe1, 0x4b,
+	0xbe, 0x5b, 0x73, 0xe0, 0xff, 0xfb, 0xe1, 0xff, 0x7b, 0xe1, 0xff, 0x6d,
+	0xf8, 0xff, 0x18, 0xfc, 0x7f, 0x17, 0xfc, 0x7f, 0x94, 0xbe, 0x5f, 0x4e,
+	0xd6, 0xf2, 0xb0, 0xb1, 0x15, 0xf8, 0x41, 0x33, 0xec, 0xd6, 0x22, 0xe1,
+	0x64, 0x2d, 0x1a, 0x4e, 0xd5, 0x42, 0xe0, 0xe9, 0x30, 0xe7, 0x04, 0x7f,
+	0xf9, 0xd6, 0xa1, 0x52, 0x3f, 0xe2, 0x8a, 0x0b, 0xbf, 0x94, 0x86, 0xdf,
+	0x77, 0x80, 0x7f, 0xf3, 0xb2, 0x3a, 0x13, 0xc3, 0x33, 0x75, 0x49, 0x3b,
+	0x4d, 0x32, 0x69, 0x3a, 0x18, 0x63, 0xbb, 0xb2, 0x53, 0x23, 0xb1, 0xab,
+	0x09, 0x76, 0x2a, 0xb9, 0x22, 0xe3, 0x73, 0x17, 0xc6, 0x6b, 0x45, 0x7c,
+	0xa0, 0x7f, 0xa0, 0x2f, 0x58, 0xc9, 0x3c, 0x6c, 0x73, 0xcd, 0xb5, 0x69,
+	0x49, 0xe0, 0x67, 0x62, 0x13, 0xc4, 0x3a, 0xd8, 0x05, 0xdb, 0xf6, 0xe0,
+	0x39, 0xfe, 0xfe, 0x6f, 0x7e, 0x8d, 0xea, 0xaf, 0x5a, 0x04, 0xc6, 0xfb,
+	0x32, 0x63, 0x8f, 0x8d, 0xf1, 0xaa, 0x8d, 0xeb, 0x75, 0x49, 0x17, 0x3b,
+	0xb8, 0xcf, 0x7a, 0x0d, 0x6b, 0x54, 0xaf, 0x80, 0xde, 0x7a, 0x7d, 0x55,
+	0x61, 0x48, 0xe4, 0x33, 0x87, 0xd6, 0xc0, 0x43, 0xe3, 0x33, 0xdf, 0xc0,
+	0x33, 0xaa, 0x2d, 0x6c, 0x26, 0x1c, 0xe6, 0x50, 0xf0, 0x9b, 0x2f, 0xc0,
+	0x47, 0x1e, 0xcb, 0xe8, 0xcb, 0x57, 0xf1, 0x2c, 0x64, 0x5a, 0x3c, 0x96,
+	0x09, 0xf5, 0xbc, 0x5a, 0x7f, 0x16, 0x39, 0xf1, 0xd0, 0xf2, 0x80, 0xa4,
+	0x96, 0xbb, 0xa3, 0x17, 0xa5, 0xf5, 0x1d, 0x17, 0xb1, 0x74, 0xb2, 0x6a,
+	0x9d, 0x76, 0x85, 0x39, 0xba, 0x29, 0x0b, 0xc0, 0xd5, 0x7b, 0xf6, 0x3d,
+	0x0f, 0xda, 0xad, 0x17, 0x45, 0x8f, 0xe1, 0x37, 0x31, 0x0c, 0x79, 0x5c,
+	0x03, 0x7f, 0x1a, 0xae, 0x5b, 0xd6, 0x6b, 0x57, 0x85, 0x12, 0xf8, 0xac,
+	0x1d, 0xcb, 0x5c, 0x9c, 0x06, 0xae, 0x83, 0x3e, 0x92, 0xd3, 0xc4, 0x9c,
+	0x5b, 0x20, 0x93, 0x21, 0xd8, 0x05, 0xf5, 0x1d, 0xc7, 0xb3, 0x75, 0xf9,
+	0x92, 0x43, 0x1b, 0x78, 0x0e, 0x72, 0xc3, 0x58, 0xa1, 0x80, 0x6e, 0x60,
+	0x80, 0x19, 0xca, 0x6a, 0x17, 0xf2, 0x36, 0x57, 0x06, 0xf6, 0x49, 0x78,
+	0x47, 0x62, 0x73, 0x4e, 0x76, 0x2c, 0xb3, 0x3a, 0x8d, 0xf1, 0x7b, 0x80,
+	0x79, 0x84, 0xb5, 0x19, 0xfa, 0x60, 0x81, 0xed, 0xec, 0x87, 0x7e, 0x98,
+	0x7b, 0x33, 0x47, 0xa3, 0x6f, 0x3a, 0xa8, 0xa5, 0x2a, 0x65, 0x43, 0x3a,
+	0x0e, 0x21, 0xb7, 0x71, 0x64, 0x71, 0x9a, 0x39, 0x1a, 0xf3, 0x99, 0x20,
+	0x7f, 0xd1, 0x90, 0x4b, 0xa0, 0x7d, 0xf9, 0x25, 0xa5, 0x07, 0x03, 0xfa,
+	0xca, 0xed, 0xbb, 0x9f, 0x7c, 0xcd, 0x18, 0x09, 0xf8, 0xbf, 0x01, 0xf2,
+	0xa2, 0x68, 0x40, 0xce, 0xc6, 0x35, 0x17, 0x03, 0x5f, 0xf8, 0x5c, 0xcf,
+	0xdd, 0xd4, 0xdf, 0x64, 0xe9, 0x04, 0xec, 0x58, 0xf2, 0x4d, 0x09, 0xf0,
+	0x36, 0x80, 0xdf, 0x58, 0xf8, 0x27, 0xa1, 0xc3, 0x73, 0x03, 0xac, 0x91,
+	0x3d, 0x07, 0xfc, 0x47, 0xfa, 0xe3, 0xb1, 0x13, 0x6a, 0xdd, 0xe2, 0xba,
+	0xca, 0x3c, 0x62, 0x8b, 0x5c, 0x54, 0x7c, 0xde, 0xc1, 0xfc, 0x14, 0x7a,
+	0xb9, 0x15, 0x3e, 0x87, 0x3f, 0x24, 0x9f, 0xde, 0x3c, 0x8c, 0x5b, 0x49,
+	0x3b, 0x26, 0xa9, 0xe2, 0xcb, 0x75, 0xaf, 0x0e, 0xfb, 0x47, 0xb0, 0x2b,
+	0x5c, 0x57, 0xc3, 0xa0, 0x87, 0x75, 0x99, 0x01, 0xa5, 0x5b, 0xd0, 0x43,
+	0x9b, 0xc9, 0x87, 0x13, 0xdb, 0xe4, 0xfc, 0x4c, 0x87, 0x2c, 0xcc, 0xbc,
+	0x26, 0x95, 0x99, 0x36, 0x59, 0x9a, 0xa9, 0xcb, 0x65, 0x47, 0xf9, 0x25,
+	0xbb, 0x59, 0xad, 0x69, 0xd9, 0xe5, 0x61, 0xf6, 0xf8, 0xe0, 0x15, 0x79,
+	0x5a, 0xce, 0x97, 0x3d, 0x1e, 0x32, 0x0d, 0x3c, 0xbc, 0x0a, 0x1b, 0xeb,
+	0xec, 0x21, 0x0f, 0xb4, 0x07, 0xf2, 0xc3, 0xdc, 0x83, 0x39, 0xe6, 0x41,
+	0xac, 0xa3, 0x11, 0x60, 0xa3, 0x83, 0x5a, 0xd2, 0xe7, 0x21, 0xe5, 0xf1,
+	0x90, 0x7d, 0x2f, 0x0f, 0x2d, 0x92, 0xdd, 0x49, 0x3e, 0xa0, 0x83, 0x69,
+	0xea, 0x25, 0xc0, 0x1b, 0x1e, 0xfd, 0xc9, 0xe5, 0x57, 0xeb, 0xfa, 0x74,
+	0x93, 0xa2, 0xdd, 0x48, 0x0c, 0xc0, 0xae, 0x5e, 0xad, 0xcb, 0x32, 0xd7,
+	0x12, 0x7e, 0x57, 0xff, 0x31, 0xfc, 0x55, 0xa7, 0xca, 0x5b, 0x72, 0x63,
+	0xed, 0xad, 0xc9, 0xf9, 0x41, 0xe8, 0xba, 0x55, 0xad, 0x45, 0xb8, 0x0e,
+	0xe8, 0xf0, 0x0f, 0xd1, 0xff, 0xab, 0x5c, 0x73, 0x4a, 0x3e, 0x69, 0xc8,
+	0xa7, 0x50, 0xbc, 0xbd, 0x19, 0x39, 0x37, 0xe6, 0x71, 0x33, 0xd9, 0x2a,
+	0x9f, 0xe9, 0x82, 0x7f, 0xe3, 0xf7, 0x07, 0xb6, 0x8f, 0x3c, 0xfc, 0x2e,
+	0x6c, 0x00, 0xb9, 0x05, 0xd7, 0xf4, 0xc0, 0x0a, 0xe2, 0x6c, 0xbc, 0x77,
+	0x41, 0xd5, 0xf4, 0x1d, 0x85, 0x9f, 0x26, 0xab, 0x5f, 0xc5, 0xc7, 0x9b,
+	0x6f, 0xa8, 0xc6, 0x39, 0x37, 0xf2, 0x84, 0x9c, 0x06, 0xb9, 0xa4, 0x8d,
+	0x71, 0x39, 0x6f, 0x5e, 0x8c, 0x84, 0x81, 0x79, 0xd9, 0xd6, 0x0e, 0x3f,
+	0x13, 0x83, 0xdf, 0xea, 0x87, 0xff, 0xe7, 0x5a, 0xa6, 0xaf, 0x0f, 0x68,
+	0xef, 0xc7, 0x98, 0xf4, 0xc1, 0xfd, 0xe0, 0x99, 0xb9, 0x34, 0x7d, 0x28,
+	0x62, 0xca, 0x62, 0xb4, 0x2d, 0x39, 0xeb, 0xd5, 0x93, 0xbc, 0xdf, 0xbc,
+	0x2f, 0xe1, 0xdd, 0x09, 0xab, 0x9c, 0x47, 0xfe, 0x97, 0xc2, 0xda, 0x4d,
+	0xda, 0xc8, 0xa7, 0x17, 0xad, 0x17, 0x88, 0xd3, 0x74, 0xca, 0x60, 0x99,
+	0x72, 0x62, 0x6d, 0xc3, 0x94, 0xfc, 0xc2, 0xef, 0x42, 0x1e, 0x61, 0xd9,
+	0x6e, 0x67, 0xe1, 0x53, 0x98, 0xb7, 0xb8, 0xe0, 0x8d, 0xbe, 0xa7, 0x1b,
+	0xb1, 0xcc, 0x80, 0x10, 0x90, 0x57, 0x2d, 0x1b, 0xf2, 0x40, 0xa8, 0x0f,
+	0x79, 0xe0, 0xa7, 0xd0, 0x37, 0x24, 0xf9, 0x65, 0xc6, 0x84, 0x90, 0x4c,
+	0x2d, 0x8b, 0x5c, 0x99, 0xa6, 0x5f, 0x51, 0x7f, 0x90, 0xb9, 0x9b, 0x99,
+	0x20, 0x3e, 0x9b, 0xa1, 0x8f, 0xa1, 0xff, 0xd8, 0x01, 0x5d, 0xc4, 0x9f,
+	0xfb, 0x12, 0xe2, 0xd3, 0x64, 0xb1, 0x1b, 0x7e, 0x53, 0x56, 0x74, 0xc8,
+	0x14, 0x71, 0x8d, 0xf5, 0xaa, 0x1b, 0xd4, 0xaa, 0x82, 0x3a, 0x55, 0x58,
+	0x0a, 0xd3, 0xac, 0x51, 0x85, 0x41, 0x0b, 0x73, 0x57, 0x43, 0xe5, 0x42,
+	0x3b, 0x94, 0x7f, 0xe5, 0x77, 0xa8, 0x61, 0xde, 0xf8, 0xe9, 0x3d, 0x3a,
+	0xfd, 0xd8, 0x6e, 0x71, 0x47, 0x8f, 0xb5, 0xee, 0x2f, 0x01, 0x8b, 0x76,
+	0xd2, 0x3e, 0xa9, 0xff, 0xac, 0x4e, 0x7f, 0x3b, 0x55, 0x1a, 0xc0, 0x78,
+	0xc4, 0x95, 0x21, 0xf4, 0x8b, 0xf8, 0xfd, 0x28, 0xd7, 0x7f, 0x25, 0xe3,
+	0xfb, 0xfe, 0x1a, 0x74, 0x79, 0xfe, 0x8e, 0x75, 0xee, 0xdc, 0x67, 0x74,
+	0xb9, 0xef, 0x63, 0x69, 0x3c, 0xcb, 0x78, 0xf8, 0xb6, 0x8f, 0xe1, 0xd8,
+	0xc6, 0xba, 0x1e, 0x72, 0xf5, 0xf3, 0x26, 0xbe, 0x3b, 0x25, 0x7f, 0x3e,
+	0x0c, 0x39, 0x20, 0x2f, 0x5e, 0xf0, 0xc6, 0x62, 0xee, 0x7b, 0x1a, 0x3a,
+	0xd2, 0xcf, 0x84, 0xa5, 0xe9, 0x4c, 0xa7, 0x84, 0xbe, 0xd2, 0x26, 0xcd,
+	0x5f, 0xe9, 0x11, 0xe3, 0x2b, 0xac, 0x3f, 0x58, 0xb1, 0x93, 0xaa, 0xf6,
+	0x91, 0x96, 0x53, 0x88, 0x61, 0x3a, 0xe2, 0xb1, 0xb2, 0x53, 0x73, 0xa7,
+	0x18, 0x48, 0x5e, 0xf5, 0x67, 0x5c, 0xf9, 0xe2, 0xbe, 0x9f, 0xab, 0xda,
+	0x1b, 0x70, 0xb3, 0xe8, 0xcf, 0x67, 0xc4, 0xad, 0xbd, 0x46, 0x3b, 0xcd,
+	0xbc, 0x7a, 0xd7, 0x1d, 0xd0, 0x39, 0x73, 0xcb, 0x5e, 0x55, 0xc7, 0xfd,
+	0xe2, 0x3e, 0xc6, 0x4c, 0x2f, 0xbf, 0x4c, 0x23, 0xbf, 0x9c, 0x94, 0x6e,
+	0xf8, 0x59, 0xf6, 0xdb, 0x29, 0x3a, 0xe6, 0xca, 0x09, 0xf3, 0xf5, 0x3b,
+	0xc5, 0x3d, 0x8c, 0x75, 0x71, 0x56, 0x66, 0xf4, 0x84, 0xa6, 0xc6, 0x34,
+	0x9e, 0xa1, 0xdf, 0xa2, 0x3f, 0xa3, 0x8d, 0xb3, 0x0e, 0x82, 0xb6, 0xe7,
+	0xe9, 0xb3, 0x3c, 0xdb, 0x1e, 0x6a, 0xf0, 0x7d, 0x53, 0xa5, 0x1a, 0x74,
+	0x88, 0xbc, 0xde, 0x6e, 0x02, 0xff, 0x88, 0xeb, 0x36, 0xaf, 0xc9, 0x3f,
+	0x7c, 0x69, 0x24, 0xa2, 0xae, 0x0b, 0x65, 0x0f, 0xf7, 0x7a, 0xe3, 0x33,
+	0x07, 0x81, 0xaf, 0xa9, 0x91, 0x0e, 0xce, 0xdb, 0x25, 0xc6, 0xd9, 0x88,
+	0x84, 0xce, 0xd2, 0xfe, 0xac, 0x58, 0x1a, 0xf2, 0x9b, 0xb2, 0x89, 0xf5,
+	0x0e, 0xc0, 0x17, 0xec, 0x16, 0xfd, 0x7c, 0x2f, 0xd6, 0x8e, 0x15, 0x2d,
+	0x4b, 0x5c, 0x8c, 0x85, 0xb0, 0xbc, 0x09, 0xdf, 0x41, 0x7b, 0x39, 0x87,
+	0x78, 0x75, 0xa2, 0xd6, 0xfa, 0xce, 0x8a, 0xa2, 0x82, 0x6d, 0x43, 0xc0,
+	0x4b, 0x56, 0xaf, 0xab, 0xb7, 0xcb, 0xeb, 0xd0, 0x77, 0x56, 0xb5, 0xed,
+	0xc6, 0xb8, 0xa0, 0xe1, 0x2c, 0xeb, 0x49, 0x1c, 0xf7, 0x1f, 0x60, 0x4c,
+	0x8e, 0xed, 0x66, 0x56, 0x99, 0x9f, 0x4e, 0xd3, 0x76, 0x3b, 0x61, 0x77,
+	0xb8, 0xae, 0x35, 0x4b, 0x76, 0x2c, 0x26, 0xfa, 0xf4, 0x83, 0xd2, 0xbd,
+	0x4f, 0xf7, 0xf8, 0x51, 0x3c, 0xb2, 0x8d, 0x75, 0xca, 0x16, 0xb5, 0x1e,
+	0xf5, 0x65, 0xd8, 0xcc, 0x41, 0xea, 0x18, 0xf1, 0x1f, 0xf1, 0x8d, 0xfe,
+	0xcc, 0x40, 0x7c, 0x4b, 0xd5, 0x3c, 0xbd, 0x97, 0x0f, 0xee, 0x94, 0x53,
+	0x67, 0x69, 0x4f, 0xb8, 0xb7, 0x6e, 0x53, 0xc1, 0x7e, 0x02, 0xef, 0xd9,
+	0x72, 0xfa, 0x59, 0xe6, 0x1f, 0xcc, 0x3b, 0x98, 0x6b, 0x59, 0xd1, 0xfd,
+	0xe0, 0x47, 0xbf, 0x8f, 0xfe, 0x40, 0x57, 0xb6, 0x9b, 0x83, 0xaf, 0x2e,
+	0xd4, 0xa8, 0xb7, 0x7e, 0xee, 0xb9, 0x98, 0xcc, 0xd9, 0xdc, 0xa8, 0x27,
+	0xef, 0x02, 0xda, 0x26, 0x11, 0x07, 0x52, 0xd5, 0x26, 0x59, 0x1b, 0x73,
+	0xa1, 0xfb, 0x8f, 0x82, 0xae, 0xc3, 0xad, 0xc4, 0xab, 0x6b, 0x63, 0x69,
+	0x5c, 0x1f, 0x56, 0x79, 0x9a, 0x71, 0x9f, 0x8b, 0x31, 0x76, 0x72, 0x1d,
+	0xf9, 0x7a, 0x72, 0xf4, 0xc2, 0xcc, 0x7d, 0xfa, 0x24, 0x7c, 0xf7, 0xb0,
+	0xc3, 0x18, 0xcf, 0xfa, 0x73, 0x0b, 0xe8, 0x68, 0x57, 0xd8, 0x42, 0xb7,
+	0xf7, 0xe9, 0x85, 0x32, 0xfd, 0x7d, 0x3e, 0xda, 0x2c, 0x0e, 0x7d, 0x96,
+	0xbe, 0x60, 0x53, 0x27, 0x9a, 0x5c, 0x54, 0xb5, 0x6a, 0x44, 0xa0, 0x6a,
+	0x0a, 0x73, 0x39, 0x7a, 0xa5, 0xbc, 0x4f, 0xcf, 0xc3, 0x55, 0xaf, 0x45,
+	0x48, 0x77, 0x4c, 0xe5, 0xf2, 0xfb, 0x94, 0xad, 0x15, 0x11, 0x53, 0x60,
+	0x33, 0xce, 0x1d, 0x98, 0x57, 0xb5, 0xc1, 0xa6, 0xa8, 0x7b, 0xea, 0x5d,
+	0xf9, 0x48, 0x5f, 0xf7, 0x37, 0x8a, 0xa1, 0x45, 0xf8, 0x5f, 0x62, 0xe9,
+	0x16, 0xbf, 0x3e, 0xf5, 0xcf, 0xfd, 0x9c, 0xe8, 0x71, 0x61, 0x9e, 0x32,
+	0x55, 0x22, 0x2d, 0x45, 0xf8, 0xc3, 0x1b, 0xd9, 0x12, 0xe5, 0xe8, 0xf9,
+	0x94, 0x63, 0xb0, 0x0b, 0x7d, 0xd9, 0xf4, 0x6d, 0x40, 0xe1, 0x67, 0xdc,
+	0x63, 0x0c, 0xc0, 0x77, 0xad, 0x09, 0xeb, 0x7d, 0x04, 0x32, 0xa2, 0x6e,
+	0xa0, 0xbf, 0x65, 0xee, 0xd5, 0x41, 0x7f, 0xcb, 0x97, 0x7e, 0xe1, 0x76,
+	0xd2, 0xe7, 0x0d, 0xc8, 0x29, 0xf8, 0xd1, 0x93, 0xf3, 0xa4, 0x27, 0xad,
+	0xd6, 0xce, 0x14, 0xe4, 0x7d, 0x42, 0xf9, 0xf8, 0x7e, 0x79, 0x73, 0xf1,
+	0x5b, 0x0a, 0x0b, 0xee, 0xd9, 0xb7, 0x22, 0x13, 0xf0, 0x0f, 0x47, 0xaa,
+	0x90, 0xb7, 0x19, 0xc3, 0xfa, 0xdc, 0xa5, 0xfc, 0xe3, 0x17, 0x3f, 0x78,
+	0xae, 0x12, 0xd2, 0x13, 0x0f, 0x7c, 0xc8, 0x18, 0xbe, 0x55, 0xdc, 0xce,
+	0x0f, 0x3c, 0x8f, 0xa1, 0x27, 0xfe, 0x10, 0x3a, 0xfb, 0x4d, 0xcc, 0x15,
+	0x06, 0x9d, 0x6a, 0x3f, 0xe4, 0x83, 0x3c, 0xa7, 0xeb, 0x89, 0x4f, 0x7e,
+	0x48, 0xfa, 0x4c, 0x59, 0x04, 0x7e, 0xc8, 0xab, 0xb8, 0xca, 0xdc, 0xb1,
+	0xc9, 0xd7, 0xe7, 0x0b, 0xc0, 0xd5, 0xc0, 0xd2, 0xc5, 0xc0, 0x17, 0xb7,
+	0x48, 0xbe, 0x33, 0xc8, 0x47, 0xe1, 0xc3, 0xd7, 0xdb, 0x83, 0x1c, 0x97,
+	0xcf, 0x67, 0x33, 0xc8, 0xa9, 0x61, 0x13, 0xb7, 0x61, 0x8d, 0xb2, 0x4d,
+	0xe5, 0xb0, 0x37, 0xa1, 0xdf, 0xa3, 0x3d, 0x57, 0x6c, 0xcc, 0x2d, 0x0e,
+	0xa8, 0xdc, 0x62, 0x68, 0x43, 0x6e, 0x11, 0xd4, 0xb4, 0x02, 0xba, 0x39,
+	0x2e, 0x70, 0x03, 0xec, 0xe0, 0xbb, 0x18, 0xff, 0x3b, 0xd0, 0xf7, 0xb7,
+	0x4b, 0xc0, 0x0d, 0x25, 0xe0, 0x86, 0x12, 0x70, 0x43, 0x09, 0xb8, 0xa1,
+	0x14, 0xf5, 0xeb, 0x5b, 0x2e, 0x71, 0xff, 0x07, 0xb4, 0xe9, 0xa0, 0xee,
+	0xb1, 0xd9, 0x5e, 0xbd, 0x3a, 0x59, 0xaa, 0x16, 0xe0, 0xe7, 0x30, 0xeb,
+	0x76, 0xc0, 0x71, 0x41, 0x4d, 0xc4, 0x8f, 0x1d, 0x8b, 0xdc, 0x43, 0x41,
+	0xec, 0x58, 0x74, 0xb1, 0x9e, 0xfa, 0xa2, 0x06, 0x70, 0xa3, 0x21, 0x51,
+	0xfc, 0x36, 0xe1, 0x93, 0xb9, 0x67, 0xde, 0x8d, 0x15, 0xd6, 0xac, 0x6a,
+	0x4f, 0x27, 0x54, 0x4d, 0xc2, 0x96, 0xc9, 0x72, 0x90, 0xdb, 0xc5, 0x65,
+	0x68, 0x86, 0x58, 0x54, 0xb6, 0xeb, 0x09, 0xe8, 0xa2, 0x4a, 0xfc, 0xc8,
+	0x3d, 0x27, 0xce, 0x1f, 0xef, 0xad, 0x60, 0xce, 0x82, 0xed, 0xd1, 0x77,
+	0xa2, 0xaa, 0xce, 0x05, 0xf8, 0xcf, 0x05, 0x67, 0x01, 0xe2, 0xb2, 0x7f,
+	0x86, 0x7b, 0xef, 0x31, 0x19, 0x2d, 0x3a, 0xc8, 0x65, 0x55, 0x8e, 0x84,
+	0x78, 0xe0, 0xc9, 0x7d, 0xc8, 0x97, 0x7b, 0x0e, 0xd8, 0x61, 0xdc, 0x0e,
+	0xe4, 0x4e, 0x79, 0x8f, 0x68, 0xc3, 0x90, 0xf5, 0x7e, 0x5f, 0xd6, 0xe9,
+	0x25, 0x31, 0x91, 0xff, 0xc4, 0x8c, 0x7d, 0x63, 0xda, 0x68, 0x4d, 0x61,
+	0x16, 0xfa, 0x23, 0x8c, 0xe5, 0x78, 0x6b, 0x1d, 0xf6, 0x92, 0xab, 0x6e,
+	0xde, 0x8f, 0x6f, 0xc4, 0x2f, 0x9f, 0xd5, 0xc4, 0x0e, 0xe4, 0xd8, 0xd8,
+	0x3e, 0xd1, 0xd0, 0xbe, 0x7e, 0xdf, 0xe7, 0x01, 0xbe, 0x72, 0xbd, 0x3e,
+	0x41, 0xbf, 0x76, 0xbd, 0x1d, 0x78, 0x4f, 0x42, 0xea, 0x3e, 0x7c, 0xfe,
+	0x62, 0x44, 0x52, 0x8b, 0xb6, 0xa4, 0xcb, 0xec, 0xc7, 0x9a, 0x07, 0xfd,
+	0xd7, 0x1f, 0x4b, 0x0a, 0x79, 0x6e, 0x36, 0x62, 0x39, 0xae, 0xfc, 0x47,
+	0x59, 0x9d, 0xcb, 0xc7, 0xb8, 0x77, 0x9d, 0x1f, 0xd5, 0xf0, 0xdc, 0x8f,
+	0x71, 0x4d, 0xda, 0x6d, 0xac, 0x0f, 0xc6, 0xa9, 0xbe, 0xe8, 0x22, 0xee,
+	0x65, 0xc7, 0x58, 0xe7, 0x79, 0x2a, 0x2c, 0x6d, 0x56, 0xac, 0x0c, 0x3b,
+	0xb8, 0x54, 0xe4, 0x7c, 0xc0, 0x52, 0x45, 0xd6, 0x82, 0x82, 0xfb, 0x7f,
+	0x0c, 0xec, 0xa8, 0x13, 0x3b, 0x79, 0x7d, 0x94, 0xbe, 0x5c, 0x33, 0x84,
+	0x35, 0xb0, 0xe2, 0xfb, 0xe7, 0x85, 0xa2, 0x57, 0x7b, 0x39, 0x47, 0x3a,
+	0xaa, 0x7f, 0x53, 0x5f, 0x89, 0x20, 0x67, 0x5a, 0xe7, 0xf1, 0x1c, 0xc7,
+	0x37, 0xe1, 0x9e, 0xe5, 0x64, 0x35, 0x90, 0x05, 0xef, 0xb3, 0x8d, 0xfb,
+	0xf3, 0xf5, 0xfa, 0x39, 0xfb, 0xc3, 0xd6, 0xd9, 0x9e, 0xbb, 0x27, 0x69,
+	0xcb, 0x81, 0x85, 0xaa, 0x1c, 0xf0, 0xea, 0x6c, 0xd1, 0xbd, 0x5e, 0x9d,
+	0x2d, 0xb6, 0x77, 0x63, 0x9d, 0xad, 0x7c, 0x8f, 0x57, 0x67, 0x33, 0x0f,
+	0xc0, 0x07, 0x1f, 0xf0, 0xea, 0x6c, 0xff, 0xf5, 0x1e, 0xaf, 0xce, 0xd6,
+	0x75, 0xaf, 0x57, 0x67, 0xeb, 0xdd, 0xeb, 0xd5, 0xd9, 0x46, 0xef, 0xdd,
+	0x58, 0x67, 0x73, 0xf6, 0x6e, 0xac, 0xb3, 0x39, 0x07, 0x72, 0xf8, 0x5c,
+	0xaf, 0xb3, 0x65, 0xf6, 0xde, 0xbc, 0xce, 0xf6, 0x4a, 0x80, 0xf1, 0xc1,
+	0xcf, 0x00, 0x78, 0x70, 0x80, 0xf1, 0xfb, 0x81, 0xf1, 0x6f, 0x56, 0xe3,
+	0x55, 0xe7, 0x37, 0xc0, 0xa7, 0xe6, 0xc7, 0x8f, 0x0f, 0x83, 0xf5, 0xb7,
+	0xfa, 0xcf, 0xba, 0xc8, 0x8f, 0x63, 0x7e, 0x6e, 0x43, 0xbc, 0xbf, 0xcd,
+	0xcf, 0xf1, 0xba, 0x5a, 0xaf, 0x9f, 0xad, 0x68, 0xfc, 0xbe, 0x0d, 0xa9,
+	0x7a, 0x50, 0x03, 0x20, 0x5f, 0x72, 0xe0, 0x61, 0x25, 0x87, 0x3b, 0xd1,
+	0xdf, 0x3c, 0xf0, 0x25, 0x9b, 0x75, 0x81, 0x27, 0xb1, 0x86, 0xdd, 0xed,
+	0x86, 0xda, 0x67, 0x66, 0x4c, 0x3b, 0x2d, 0x29, 0xf4, 0x4f, 0xa9, 0xfe,
+	0xa3, 0x0d, 0xfd, 0xb3, 0xe8, 0xcf, 0x71, 0xad, 0x7f, 0x8b, 0xcf, 0x73,
+	0xca, 0xbe, 0x6d, 0x0f, 0xf7, 0xa7, 0x4b, 0x01, 0x4e, 0x0b, 0xf9, 0x18,
+	0xdc, 0xcd, 0xb8, 0xd5, 0x7b, 0xf1, 0x8c, 0xf5, 0xa2, 0x2b, 0x57, 0x15,
+	0xde, 0x37, 0x12, 0xd6, 0x8b, 0x59, 0x95, 0xdf, 0xb9, 0x99, 0x5c, 0x75,
+	0x3d, 0x5f, 0x07, 0x0e, 0x63, 0xce, 0x03, 0x7b, 0x5f, 0xee, 0x45, 0xdc,
+	0x6b, 0xcc, 0xc9, 0x99, 0x87, 0xeb, 0x7e, 0x1e, 0x6e, 0xca, 0xfd, 0xfb,
+	0x1a, 0x31, 0xbe, 0x73, 0xe0, 0xef, 0x2b, 0x8c, 0xbf, 0x05, 0xb9, 0x3c,
+	0x31, 0x3c, 0x71, 0x0f, 0x31, 0x07, 0x71, 0x3e, 0xeb, 0x0b, 0xcc, 0x7f,
+	0x18, 0x4b, 0x99, 0x0f, 0x45, 0xf0, 0xe1, 0xb9, 0x97, 0x00, 0xeb, 0x37,
+	0xfb, 0xfe, 0x9f, 0x79, 0x54, 0x80, 0x6d, 0xac, 0x2d, 0x5e, 0x2e, 0xb5,
+	0x45, 0xf3, 0xf2, 0xd5, 0x98, 0xdf, 0x27, 0xb4, 0x8e, 0xa5, 0x43, 0xeb,
+	0x58, 0x7a, 0xc3, 0x5e, 0x89, 0xa8, 0x33, 0x36, 0x6a, 0xcf, 0x85, 0x7b,
+	0x30, 0x6e, 0xe6, 0x52, 0x0f, 0xf1, 0x30, 0xf7, 0x62, 0x80, 0x8d, 0xec,
+	0xc6, 0x58, 0xc5, 0x38, 0x45, 0x3c, 0x15, 0xec, 0xb7, 0x06, 0x7a, 0xa2,
+	0xec, 0xd8, 0xf6, 0x47, 0x1a, 0x72, 0x64, 0xa7, 0xd9, 0xde, 0x0f, 0x5a,
+	0x32, 0xf8, 0x0e, 0x64, 0xfa, 0x80, 0x8a, 0x91, 0x2d, 0xb0, 0xdd, 0x13,
+	0x25, 0x62, 0xde, 0x6d, 0xb2, 0xe8, 0xe3, 0xde, 0xf3, 0x33, 0x1e, 0xe6,
+	0x0d, 0x6d, 0xc4, 0xbc, 0xce, 0xaa, 0x78, 0x34, 0xee, 0xbf, 0x21, 0x8d,
+	0xc4, 0xb7, 0xa4, 0x8f, 0x31, 0x89, 0xfe, 0xd1, 0xcd, 0x5c, 0xee, 0x61,
+	0x3c, 0x62, 0x2c, 0x8a, 0xc9, 0xea, 0x4d, 0xe9, 0x53, 0x6d, 0xc7, 0x5a,
+	0xec, 0x30, 0x3e, 0x13, 0xf0, 0x1f, 0xa3, 0x78, 0x26, 0x23, 0x93, 0xb3,
+	0x5f, 0x00, 0x6f, 0x13, 0x72, 0x69, 0x66, 0x0c, 0xf4, 0x3d, 0x29, 0x53,
+	0x4e, 0x1e, 0x7e, 0x84, 0x7b, 0x21, 0xc4, 0x79, 0xdd, 0xfe, 0xf7, 0x84,
+	0x7e, 0xce, 0xb6, 0x88, 0x33, 0xa5, 0x52, 0xa4, 0x0f, 0xe6, 0xbe, 0x14,
+	0xf7, 0x1f, 0x69, 0x3f, 0xac, 0xc3, 0x20, 0xd7, 0x65, 0xce, 0x3b, 0xcd,
+	0xf9, 0x37, 0xea, 0x64, 0xb5, 0x4a, 0xbc, 0xe6, 0x66, 0x56, 0x96, 0x89,
+	0x37, 0x3f, 0x28, 0xf6, 0xa4, 0x1e, 0x88, 0x3f, 0x6f, 0x05, 0x77, 0x5a,
+	0x33, 0xc0, 0x9c, 0x2f, 0xac, 0xe8, 0x8d, 0xb8, 0xd3, 0xc3, 0x9c, 0xc9,
+	0xe5, 0x2c, 0xc6, 0x74, 0x14, 0xb6, 0x46, 0xde, 0x07, 0xb7, 0xd7, 0x8d,
+	0x67, 0xbb, 0x91, 0xc3, 0x7b, 0x18, 0x33, 0x05, 0x8c, 0xf9, 0x0f, 0x81,
+	0x31, 0x27, 0xe5, 0xad, 0x56, 0x62, 0x4c, 0xd7, 0xc7, 0x98, 0x69, 0xd8,
+	0x73, 0x6e, 0x83, 0x3d, 0x6b, 0xaa, 0x76, 0xc5, 0x7b, 0x39, 0x60, 0xc4,
+	0xd4, 0xb4, 0x75, 0x0b, 0xb8, 0x52, 0x93, 0x88, 0x3a, 0xfb, 0x10, 0x6a,
+	0x18, 0x33, 0xc0, 0x8f, 0x7b, 0x14, 0x2e, 0x3c, 0x50, 0xda, 0x82, 0x1c,
+	0x46, 0xe1, 0x44, 0x7f, 0x4f, 0x2e, 0xb4, 0x69, 0x9f, 0x32, 0xd4, 0xb0,
+	0x4f, 0x79, 0x1d, 0x4f, 0xe2, 0x39, 0xbf, 0x3e, 0xd8, 0x04, 0x5f, 0xf0,
+	0x7f, 0x40, 0x13, 0xd7, 0x17, 0xd7, 0x82, 0xe6, 0xad, 0x97, 0xd1, 0x46,
+	0x5c, 0xf9, 0xbf, 0x36, 0xe1, 0x4a, 0xc4, 0xae, 0xf3, 0x11, 0x49, 0x02,
+	0x53, 0xba, 0xcb, 0x1c, 0x8b, 0x6b, 0xba, 0x5f, 0x9a, 0xc1, 0x5f, 0xcb,
+	0x74, 0x27, 0xb0, 0x54, 0x9b, 0x84, 0x81, 0xa9, 0x9a, 0x14, 0xa6, 0xea,
+	0x21, 0xf6, 0xe9, 0x3d, 0x02, 0x2c, 0xb4, 0xb8, 0x8e, 0xab, 0x2c, 0xe7,
+	0x87, 0xd0, 0xcb, 0xa3, 0xca, 0xf7, 0xa4, 0xe5, 0x29, 0xf8, 0xd2, 0xe6,
+	0x65, 0xe0, 0xc1, 0xf3, 0x1e, 0xde, 0x6a, 0xda, 0x84, 0xb7, 0x8e, 0xde,
+	0x10, 0x6f, 0xa9, 0x9a, 0xff, 0x20, 0x65, 0xf2, 0x7a, 0xd5, 0xab, 0xf9,
+	0x5f, 0xa9, 0x7a, 0x35, 0xff, 0xd7, 0xab, 0x8d, 0x35, 0xff, 0x8f, 0x48,
+	0xc1, 0xb4, 0xdc, 0x35, 0xd9, 0x54, 0xf3, 0x1f, 0x65, 0x0d, 0xfd, 0xf7,
+	0xda, 0xbc, 0xda, 0x7e, 0x9b, 0x5f, 0xf3, 0xb7, 0xa4, 0xb0, 0xa1, 0xdd,
+	0x94, 0xb7, 0xec, 0xa0, 0xe6, 0xff, 0x34, 0xda, 0xda, 0x31, 0xc7, 0xc6,
+	0x7a, 0xff, 0x95, 0x2a, 0xeb, 0xfd, 0x11, 0xf6, 0xf3, 0xeb, 0xfd, 0xec,
+	0x87, 0xdc, 0xbf, 0xca, 0x5a, 0xff, 0x6e, 0xc8, 0x62, 0x27, 0xe4, 0xd0,
+	0x29, 0xcd, 0x67, 0xa3, 0xec, 0xa3, 0x6a, 0xfc, 0x6b, 0xc8, 0x37, 0xae,
+	0x54, 0xbd, 0x5a, 0xfc, 0x11, 0xd8, 0xd5, 0xd1, 0xf5, 0x1a, 0xbf, 0x37,
+	0xc7, 0xd5, 0xea, 0xc6, 0xf1, 0x37, 0x8e, 0xd3, 0xe5, 0x8f, 0x13, 0xc1,
+	0x38, 0xd1, 0x4d, 0xe3, 0x5c, 0xaf, 0xe9, 0x5f, 0xad, 0x7a, 0xf5, 0xfc,
+	0xf4, 0xac, 0xb8, 0xcd, 0xf0, 0xcd, 0x2f, 0xf6, 0xec, 0xf2, 0xc7, 0x58,
+	0xaf, 0xe7, 0xd3, 0x87, 0x00, 0xe7, 0xc7, 0xd5, 0xf9, 0x9e, 0x23, 0xff,
+	0x1f, 0xea, 0xf9, 0xac, 0xe5, 0x7b, 0x7b, 0x32, 0x5c, 0x9f, 0xc0, 0xf3,
+	0xcf, 0x7a, 0x75, 0xfc, 0xa1, 0x52, 0x50, 0x9f, 0x67, 0x5e, 0x19, 0x9c,
+	0xbd, 0xe9, 0x8e, 0x9d, 0x10, 0xda, 0x0a, 0xe9, 0xe3, 0xb8, 0xed, 0x32,
+	0xae, 0xf0, 0x14, 0x6c, 0x2a, 0x7e, 0x73, 0x4c, 0xbd, 0x30, 0x1d, 0x60,
+	0xea, 0x88, 0xc2, 0xd4, 0x0b, 0xcb, 0x01, 0xa6, 0x4e, 0xde, 0x04, 0x53,
+	0xff, 0xf7, 0x36, 0x2f, 0x0e, 0x84, 0x25, 0xaf, 0x30, 0xf5, 0xcd, 0xce,
+	0x2b, 0xf1, 0x5e, 0x1b, 0xf1, 0x82, 0x78, 0x7b, 0xd8, 0x9d, 0x37, 0x59,
+	0x6b, 0x01, 0xce, 0x66, 0xec, 0xdf, 0x29, 0xa3, 0x67, 0xaf, 0xe3, 0x6c,
+	0x0f, 0x4b, 0x5b, 0xb1, 0x63, 0x2a, 0x26, 0x02, 0xd7, 0xd5, 0x58, 0x2f,
+	0x27, 0x56, 0x66, 0xcc, 0x09, 0x29, 0x3c, 0x97, 0x2b, 0x32, 0x0f, 0x60,
+	0x1b, 0xb1, 0x73, 0x2b, 0x8f, 0xf2, 0xf8, 0x31, 0x29, 0xc0, 0xa6, 0xc1,
+	0xd9, 0x09, 0xee, 0x4b, 0xbc, 0x65, 0x24, 0x6d, 0xb4, 0x57, 0x83, 0x5c,
+	0xc1, 0x51, 0x67, 0x4e, 0x92, 0xc0, 0x3f, 0xe3, 0xeb, 0xd8, 0x93, 0xbe,
+	0xe2, 0x47, 0xbf, 0x70, 0x4d, 0xfa, 0xb5, 0x00, 0x5b, 0x22, 0x27, 0x2a,
+	0x71, 0x6d, 0x07, 0xd8, 0xd2, 0xc3, 0x95, 0xa9, 0xea, 0x0a, 0xf0, 0x75,
+	0x48, 0x86, 0x80, 0xeb, 0x57, 0x1e, 0x66, 0xcd, 0x2a, 0xc0, 0x4e, 0x2e,
+	0xbe, 0x1b, 0x6b, 0x58, 0xbc, 0x6e, 0x56, 0x7b, 0x87, 0x17, 0x7b, 0xc2,
+	0x0d, 0xed, 0xbf, 0x05, 0xff, 0x8d, 0xfc, 0x08, 0x98, 0xc5, 0xc3, 0x4c,
+	0x7b, 0xa1, 0x83, 0x01, 0x85, 0x99, 0xa6, 0xde, 0x83, 0x99, 0x36, 0xc7,
+	0x28, 0xc6, 0xcc, 0xeb, 0x31, 0x2a, 0x5d, 0xa3, 0x3f, 0xbf, 0x1e, 0xa3,
+	0x6e, 0x1e, 0x43, 0xd9, 0x06, 0xee, 0xec, 0x0c, 0x3e, 0x13, 0x52, 0xd8,
+	0x14, 0xa3, 0xa6, 0x3e, 0x44, 0x8c, 0x1a, 0x56, 0x31, 0xca, 0xa3, 0xfb,
+	0xfb, 0x90, 0xcd, 0x77, 0x21, 0xd3, 0xef, 0x00, 0x8b, 0x7d, 0x1b, 0x7c,
+	0x7d, 0x0b, 0x38, 0xe9, 0x9b, 0xa5, 0xcd, 0x67, 0x0e, 0x06, 0x85, 0xf9,
+	0xa1, 0x87, 0xa5, 0xbc, 0x1a, 0xc0, 0x11, 0xac, 0xae, 0xc5, 0xa2, 0x9b,
+	0x19, 0x2f, 0xf6, 0x99, 0x13, 0xde, 0xde, 0x6b, 0x2c, 0x2b, 0x8f, 0xb5,
+	0xa6, 0xe6, 0x19, 0x33, 0xd4, 0x75, 0x94, 0xf5, 0x4e, 0x62, 0x87, 0x8a,
+	0xca, 0x33, 0x7b, 0xa4, 0xbc, 0xe8, 0xe1, 0xb0, 0xa9, 0x79, 0x6f, 0x8c,
+	0x71, 0x1f, 0x87, 0xe5, 0x7c, 0x1c, 0x96, 0x5d, 0x5c, 0x8d, 0x85, 0xd0,
+	0x7f, 0xca, 0xd9, 0x88, 0xbd, 0x8e, 0xf8, 0xd8, 0x6b, 0xe2, 0x43, 0x61,
+	0x2f, 0x6f, 0xae, 0x1c, 0x9e, 0x19, 0x9e, 0x89, 0xc9, 0x7e, 0xc8, 0x79,
+	0xa8, 0x48, 0x7d, 0xf1, 0x9c, 0xd2, 0x2f, 0xd3, 0x19, 0xf5, 0xe5, 0xe9,
+	0x2a, 0x14, 0x3f, 0xa8, 0x0d, 0x43, 0x57, 0x43, 0xbf, 0x54, 0x57, 0x62,
+	0xbe, 0x39, 0x10, 0xc6, 0xe7, 0x6f, 0x4b, 0x57, 0xe4, 0x83, 0xfa, 0xda,
+	0x8c, 0xc5, 0x6e, 0x05, 0x93, 0x6d, 0xc4, 0x63, 0xae, 0xc2, 0x63, 0xcd,
+	0x7e, 0x9f, 0xfc, 0x81, 0x61, 0xe8, 0xf2, 0x3f, 0xa0, 0xcf, 0x8f, 0xed,
+	0x76, 0xf9, 0x11, 0xfc, 0xf7, 0xbf, 0x87, 0x4e, 0xfe, 0x1d, 0x72, 0x85,
+	0x57, 0xec, 0x2e, 0xf9, 0x21, 0xda, 0xae, 0xe3, 0x1c, 0xf6, 0x9f, 0x72,
+	0x92, 0xf6, 0x28, 0xf0, 0xc9, 0xa8, 0x8f, 0x4f, 0xde, 0x7a, 0x20, 0x69,
+	0x8f, 0xb1, 0xce, 0x0e, 0x39, 0xff, 0x34, 0x39, 0xae, 0xb0, 0x49, 0x80,
+	0x49, 0x1e, 0x4f, 0x73, 0xfe, 0xc9, 0x6a, 0x16, 0xd8, 0x27, 0xeb, 0x63,
+	0x9f, 0x9f, 0xa6, 0x3d, 0xec, 0x33, 0xf5, 0xf7, 0xa8, 0x7f, 0x0f, 0xf7,
+	0x1c, 0x76, 0x93, 0x98, 0x07, 0xb8, 0x07, 0xd7, 0x87, 0x25, 0x5f, 0x1b,
+	0x51, 0x9f, 0x13, 0x25, 0xd7, 0x6a, 0x82, 0x9c, 0x58, 0xab, 0x3d, 0xc3,
+	0x55, 0x59, 0xb5, 0xcc, 0x22, 0xbe, 0xb3, 0x55, 0x2b, 0xfa, 0x7b, 0xfe,
+	0xf5, 0xd3, 0xfe, 0xf5, 0x53, 0xfe, 0xf5, 0x69, 0xc4, 0xe1, 0x53, 0x2a,
+	0x96, 0xb2, 0x9d, 0x6d, 0x50, 0x72, 0x15, 0x63, 0x01, 0x7b, 0x9c, 0xeb,
+	0xff, 0xf3, 0x7a, 0x59, 0xe9, 0x98, 0xe3, 0x8f, 0xe2, 0x73, 0x1a, 0x9f,
+	0x09, 0x7c, 0x0e, 0xe1, 0x93, 0xc7, 0x67, 0x5d, 0xa6, 0x5a, 0xaa, 0x34,
+	0x06, 0x1b, 0xe9, 0x95, 0x54, 0xed, 0x39, 0xe8, 0xf1, 0x49, 0xe8, 0xf6,
+	0xb8, 0x14, 0x2a, 0x7f, 0x22, 0x93, 0x33, 0x9a, 0xb4, 0xd9, 0xd0, 0x69,
+	0x05, 0xb6, 0x3c, 0xe3, 0xed, 0x41, 0xb6, 0x26, 0x46, 0xd0, 0xb7, 0x2e,
+	0x8f, 0x3a, 0x4f, 0x8a, 0x7e, 0xdf, 0x14, 0xfa, 0x89, 0x5e, 0xe8, 0xbf,
+	0x5b, 0xed, 0xbf, 0x55, 0x1c, 0x4f, 0xc6, 0xfb, 0x6d, 0xd7, 0x82, 0xce,
+	0x7b, 0x4f, 0x61, 0xec, 0xa4, 0x3a, 0x7f, 0x99, 0x91, 0x93, 0xb3, 0xab,
+	0xdb, 0x3d, 0xdf, 0x6a, 0x99, 0x57, 0xa9, 0x77, 0xf0, 0xe1, 0xc2, 0x17,
+	0x66, 0x60, 0xef, 0x47, 0xab, 0x21, 0x6d, 0x08, 0xf1, 0x66, 0xa8, 0x7a,
+	0x55, 0xc5, 0x9b, 0x54, 0xd5, 0xcd, 0xc4, 0xcf, 0x44, 0x70, 0xcd, 0x73,
+	0x31, 0x88, 0x8b, 0xea, 0xfc, 0xde, 0x2a, 0xf0, 0x8d, 0xa6, 0xea, 0x86,
+	0x93, 0xeb, 0xfb, 0x4a, 0xea, 0x7c, 0x71, 0x26, 0x1e, 0xd7, 0x25, 0x37,
+	0x40, 0x9c, 0x3b, 0xa2, 0x62, 0x13, 0xd6, 0xea, 0xed, 0xcc, 0x15, 0x5f,
+	0xe7, 0xbb, 0x00, 0xf6, 0x27, 0xd0, 0xaf, 0x0b, 0xfe, 0x18, 0xf7, 0x6a,
+	0xb4, 0x4f, 0xf2, 0xca, 0x67, 0x26, 0xa4, 0x52, 0x1e, 0x04, 0xbf, 0x7e,
+	0x8e, 0xa4, 0x72, 0x89, 0x18, 0xec, 0x31, 0xd8, 0xc3, 0xf2, 0xea, 0x2a,
+	0x95, 0x6a, 0x80, 0x29, 0xda, 0xd1, 0x87, 0x79, 0x05, 0x64, 0xe4, 0xed,
+	0xbf, 0xa9, 0xbd, 0xb7, 0x42, 0x75, 0x10, 0x72, 0x4a, 0xa2, 0x9d, 0xb5,
+	0x6d, 0xfc, 0x2e, 0xeb, 0xaa, 0x26, 0xb0, 0x66, 0x1c, 0x91, 0xc5, 0x72,
+	0x1d, 0xf4, 0x22, 0xe6, 0x6e, 0x3f, 0x22, 0x0b, 0xe5, 0x09, 0x79, 0xa1,
+	0xfc, 0xcd, 0x76, 0x60, 0x2a, 0xc8, 0x94, 0xf4, 0xb7, 0xcb, 0xf5, 0x33,
+	0x9e, 0x41, 0x3b, 0xe4, 0x39, 0x9b, 0x8f, 0x7a, 0x79, 0x6e, 0x5e, 0xd5,
+	0x68, 0xbc, 0x6f, 0x57, 0x1f, 0xb7, 0xad, 0xe8, 0x24, 0x7a, 0x1e, 0x9d,
+	0x53, 0xb6, 0x39, 0x3c, 0x65, 0xef, 0x95, 0xcb, 0xce, 0x36, 0x59, 0x75,
+	0x54, 0x5e, 0x4c, 0xfc, 0x80, 0xb5, 0x6e, 0x99, 0x2b, 0xf2, 0xa0, 0x9c,
+	0xc4, 0xba, 0xbd, 0xec, 0x3c, 0x06, 0x3b, 0x7d, 0x02, 0xb6, 0xc0, 0x1a,
+	0xc0, 0x31, 0xe6, 0x5a, 0xb2, 0xa2, 0x6a, 0x68, 0xf5, 0xfa, 0xb0, 0x3a,
+	0x27, 0xdc, 0x2c, 0xab, 0x0a, 0x8b, 0x79, 0xb5, 0xf6, 0xd5, 0x31, 0x6f,
+	0x8d, 0x18, 0xca, 0xee, 0xbf, 0x01, 0x7a, 0x8a, 0xb0, 0xdd, 0x26, 0xd5,
+	0xc7, 0x48, 0xb4, 0xf8, 0x7d, 0x14, 0x06, 0x6d, 0xe8, 0x63, 0x27, 0x92,
+	0xf6, 0x6b, 0xfb, 0x92, 0xf6, 0xc4, 0x81, 0x5c, 0xd5, 0xf3, 0x99, 0xae,
+	0xb6, 0xb6, 0x5e, 0xff, 0xc9, 0x60, 0x5d, 0xbd, 0xbc, 0x8e, 0xa1, 0x61,
+	0xa4, 0xcf, 0x5f, 0x82, 0x7e, 0x43, 0xd2, 0x7c, 0xa6, 0xfe, 0x89, 0x71,
+	0xa7, 0x2f, 0x76, 0x54, 0x78, 0x32, 0x8b, 0x79, 0xb5, 0xe5, 0x64, 0xe5,
+	0x12, 0xe2, 0xe4, 0x35, 0x62, 0x87, 0xde, 0x8b, 0x72, 0xed, 0x13, 0x49,
+	0x67, 0x50, 0x5b, 0x18, 0x43, 0xd6, 0xf2, 0xfc, 0x18, 0xe3, 0xec, 0x31,
+	0x11, 0xe0, 0xcb, 0x33, 0x03, 0x92, 0x2e, 0xaa, 0x77, 0x21, 0x78, 0x96,
+	0x53, 0x9b, 0x80, 0xfc, 0xf0, 0xfc, 0x28, 0x03, 0xa3, 0x6e, 0x77, 0xc7,
+	0xd2, 0xf2, 0x18, 0x6b, 0x63, 0x92, 0x9b, 0x93, 0x3d, 0x49, 0xf8, 0x55,
+	0x77, 0xb4, 0x59, 0x26, 0x16, 0xdd, 0x4c, 0xf7, 0xf4, 0x13, 0x18, 0x63,
+	0x1c, 0x63, 0x8d, 0x20, 0x37, 0xc9, 0x22, 0x56, 0x53, 0xbe, 0xf4, 0xdd,
+	0x8f, 0x43, 0x46, 0x1f, 0xe1, 0x59, 0xd7, 0xc1, 0xac, 0x58, 0xa3, 0x79,
+	0x35, 0xee, 0xbb, 0x5a, 0xae, 0xff, 0x57, 0x10, 0xeb, 0x42, 0xb2, 0x3f,
+	0x2e, 0xfa, 0x48, 0x3c, 0xf4, 0x8b, 0x71, 0x9b, 0x6d, 0x61, 0xb6, 0xe9,
+	0x68, 0x0b, 0xfd, 0x66, 0x3c, 0xac, 0x27, 0xe3, 0xd6, 0x20, 0xcf, 0xe0,
+	0x1a, 0xf6, 0xb8, 0x18, 0xcf, 0xd7, 0x21, 0x8b, 0x11, 0xe9, 0xb8, 0x60,
+	0x0d, 0xbe, 0x0e, 0x5a, 0x42, 0xca, 0xd7, 0x8f, 0x8b, 0xee, 0xb7, 0xb7,
+	0xaf, 0xb7, 0x87, 0xfc, 0xf6, 0x11, 0x69, 0xbb, 0xd0, 0x67, 0xbe, 0x21,
+	0x47, 0x30, 0xa6, 0x21, 0x57, 0x90, 0xeb, 0xd8, 0x3d, 0xe3, 0xb0, 0xc5,
+	0x47, 0x48, 0xcb, 0x21, 0xd6, 0x1b, 0x5d, 0xd8, 0x5f, 0x8b, 0x7d, 0x87,
+	0x7c, 0xde, 0x6c, 0x95, 0x9c, 0xca, 0x75, 0x43, 0xea, 0xbd, 0x85, 0x1c,
+	0xec, 0xfd, 0xae, 0x9e, 0xa1, 0x0e, 0xaf, 0x5e, 0xc0, 0xfd, 0x91, 0x7e,
+	0xb4, 0x5d, 0xab, 0x9f, 0xb7, 0xd9, 0xc6, 0x7b, 0xd7, 0xea, 0x15, 0xbb,
+	0xcf, 0x4c, 0x69, 0x61, 0x7f, 0xff, 0xfc, 0x98, 0xe2, 0x3d, 0x5f, 0xee,
+	0x36, 0x17, 0xe4, 0x2e, 0x2d, 0xb5, 0x03, 0xf1, 0xa2, 0x9a, 0x42, 0xdf,
+	0x6b, 0x3c, 0x83, 0xa1, 0xf6, 0x03, 0x16, 0x24, 0xb8, 0xe6, 0x38, 0x7d,
+	0xe6, 0xb0, 0x7a, 0xb6, 0xcf, 0x3c, 0xa9, 0x35, 0x3e, 0x1b, 0xd5, 0x86,
+	0x37, 0x3c, 0xdb, 0xa6, 0x64, 0x64, 0xd8, 0x5e, 0x9f, 0xc9, 0xf2, 0x88,
+	0x3c, 0x5d, 0x65, 0xbf, 0x6b, 0xf5, 0x94, 0xbd, 0x55, 0x3b, 0xb9, 0x83,
+	0xbe, 0x90, 0x7d, 0xdf, 0xd9, 0x34, 0x0f, 0xaf, 0x6f, 0x36, 0x47, 0x5d,
+	0x36, 0xce, 0xb1, 0x45, 0xf5, 0xb9, 0xac, 0xfa, 0x84, 0x94, 0xac, 0x37,
+	0xce, 0xf3, 0x17, 0xb2, 0x71, 0x9e, 0xb6, 0x75, 0x9e, 0x27, 0x31, 0xe6,
+	0x29, 0xf4, 0x2d, 0x56, 0xbb, 0xa3, 0x15, 0x79, 0xa7, 0x9e, 0xb3, 0xdf,
+	0x92, 0xcb, 0xeb, 0x63, 0xff, 0x25, 0xae, 0x1b, 0x69, 0xfa, 0x4b, 0x9f,
+	0x46, 0xfe, 0x66, 0xdb, 0x3f, 0x53, 0xf2, 0xde, 0x6a, 0x77, 0x1f, 0x5a,
+	0xd0, 0xac, 0xc1, 0x9f, 0x09, 0x75, 0xf5, 0x3b, 0xca, 0xd7, 0xdc, 0x0d,
+	0x3d, 0xed, 0x79, 0x06, 0x6b, 0xb7, 0x3f, 0xa9, 0xfa, 0x5c, 0xb1, 0x47,
+	0x64, 0xcf, 0x99, 0x6e, 0xf3, 0x8a, 0xdc, 0x2f, 0xe9, 0x08, 0xaf, 0x91,
+	0x43, 0xd9, 0x7c, 0xf7, 0xe1, 0x57, 0x99, 0x17, 0x40, 0x97, 0xdd, 0xbd,
+	0x3f, 0x93, 0x27, 0xe4, 0x64, 0x69, 0x0a, 0xbe, 0x67, 0x5c, 0x7a, 0x9f,
+	0xa1, 0xff, 0xc9, 0x9b, 0x5e, 0xad, 0xc6, 0x8b, 0x89, 0x29, 0x3f, 0x26,
+	0x4e, 0x29, 0x3f, 0xf7, 0x8a, 0x7f, 0x8e, 0xa2, 0xbb, 0xf7, 0x3c, 0x9e,
+	0x7d, 0x41, 0xf9, 0x80, 0x6f, 0x48, 0x05, 0x6b, 0x21, 0xf6, 0xfc, 0x36,
+	0xd9, 0xfa, 0x10, 0x6d, 0x12, 0x19, 0xc0, 0xdd, 0x4d, 0xea, 0x5d, 0x0b,
+	0xdd, 0x6e, 0x11, 0xd9, 0x4e, 0xfb, 0x59, 0xd8, 0x2a, 0x6d, 0xe3, 0xde,
+	0x5e, 0xd9, 0x86, 0x6b, 0x6b, 0x74, 0x4d, 0xca, 0x5b, 0x69, 0x87, 0x1f,
+	0xbd, 0xe0, 0x7d, 0xf7, 0x5f, 0x40, 0xba, 0x1c, 0x1f, 0x91, 0x7b, 0x2f,
+	0x78, 0x76, 0x37, 0x39, 0xf3, 0x84, 0x92, 0xef, 0xb8, 0x92, 0x6f, 0x5d,
+	0x8e, 0x38, 0x94, 0x3d, 0x79, 0xe2, 0xb9, 0x4a, 0x4f, 0x26, 0x9f, 0xf4,
+	0xed, 0xa8, 0xfb, 0x19, 0xbe, 0x23, 0x46, 0x19, 0x91, 0xee, 0x74, 0x07,
+	0xf7, 0x6f, 0xf7, 0x5c, 0x20, 0xbf, 0x5d, 0x1b, 0xf8, 0x7d, 0x0a, 0x3e,
+	0xb6, 0xa7, 0xc7, 0xe3, 0xf9, 0x95, 0x99, 0x0f, 0xce, 0xf3, 0xd7, 0xd6,
+	0x79, 0x36, 0xa4, 0xa2, 0xf2, 0xdc, 0xd0, 0x36, 0x69, 0xcb, 0xc9, 0x0a,
+	0xec, 0xe3, 0xcf, 0x84, 0xe7, 0x92, 0x49, 0x8b, 0x37, 0xef, 0x6a, 0x95,
+	0x34, 0x05, 0x3c, 0x90, 0xae, 0xa4, 0xaf, 0x3f, 0xd2, 0xf1, 0xc4, 0x0d,
+	0xef, 0x5d, 0x11, 0x37, 0xd3, 0x8b, 0x36, 0x5d, 0xe9, 0x70, 0xc8, 0x5f,
+	0x6f, 0x23, 0xa2, 0x2b, 0x1d, 0x26, 0xd7, 0x75, 0xf8, 0x3a, 0x74, 0x58,
+	0x91, 0x8f, 0x83, 0x27, 0xac, 0xef, 0x67, 0xfa, 0xcc, 0x23, 0xb2, 0x53,
+	0xe9, 0xdf, 0xee, 0x81, 0x4f, 0xf5, 0x75, 0xd9, 0x7c, 0x0b, 0xba, 0x7c,
+	0x43, 0x94, 0x3e, 0xd5, 0xd9, 0xa3, 0x8a, 0x1a, 0x87, 0xbe, 0x8d, 0xbc,
+	0x35, 0x2b, 0x9f, 0x40, 0x1a, 0xd5, 0x59, 0x82, 0x51, 0x4f, 0xbf, 0x6a,
+	0xcd, 0xfb, 0xfa, 0xcd, 0x8e, 0x52, 0x87, 0xd1, 0x0e, 0x4f, 0x9f, 0x2d,
+	0xaa, 0xcf, 0x74, 0xfc, 0x36, 0xb5, 0xde, 0xed, 0x9e, 0x9d, 0x1d, 0xd4,
+	0xe9, 0xd3, 0x55, 0xef, 0xbb, 0x88, 0x38, 0x37, 0x5d, 0xfd, 0x65, 0x7a,
+	0xf5, 0x74, 0x3a, 0x24, 0xde, 0xba, 0xda, 0xac, 0x4f, 0xfd, 0x42, 0x48,
+	0xd9, 0xf0, 0x10, 0x64, 0x78, 0xba, 0xb4, 0xc3, 0xb7, 0x7b, 0x8f, 0xe7,
+	0x9e, 0x0f, 0xc8, 0xf3, 0x89, 0x62, 0xb7, 0xf9, 0x16, 0xee, 0x0d, 0x83,
+	0xe7, 0x23, 0xd2, 0x24, 0x29, 0x9f, 0xe7, 0xd8, 0x3a, 0xcf, 0x01, 0x8d,
+	0x5e, 0xbf, 0x14, 0xf3, 0xd8, 0x2a, 0xfd, 0xd7, 0xef, 0xaa, 0x77, 0x1a,
+	0xae, 0x16, 0xe9, 0xb7, 0x81, 0x95, 0x22, 0x9d, 0x72, 0x65, 0x31, 0x26,
+	0x57, 0x88, 0x41, 0x06, 0xf0, 0x5d, 0x9d, 0xf2, 0x63, 0x78, 0x58, 0xde,
+	0x28, 0xde, 0x88, 0x8e, 0x7e, 0x79, 0xbd, 0x18, 0xd0, 0x42, 0x2c, 0xcc,
+	0x7c, 0x61, 0x5c, 0xde, 0x9c, 0xe9, 0x96, 0x95, 0x51, 0xc4, 0xfd, 0x1e,
+	0xca, 0xa4, 0xcf, 0x7c, 0x50, 0xbd, 0xeb, 0x72, 0xad, 0x7e, 0xd1, 0xc6,
+	0xf8, 0x73, 0x75, 0x39, 0xca, 0xfd, 0x6f, 0xfe, 0x5e, 0xbc, 0x5d, 0x56,
+	0x98, 0x53, 0xf4, 0x74, 0xca, 0xc2, 0x1c, 0xf2, 0xf9, 0x22, 0xc7, 0xa7,
+	0xdc, 0x46, 0xd4, 0xef, 0x61, 0xcc, 0xf7, 0x49, 0x9e, 0x41, 0x8f, 0x50,
+	0x37, 0xd7, 0xea, 0xab, 0x36, 0xf7, 0x3f, 0xc7, 0x65, 0x11, 0xfa, 0xfb,
+	0x47, 0x71, 0xee, 0xcf, 0xe7, 0xd4, 0xfb, 0x85, 0x0b, 0x8b, 0xa3, 0xc8,
+	0x1d, 0xae, 0xd5, 0xa7, 0xec, 0x29, 0xa5, 0xb7, 0xc5, 0xf2, 0x43, 0x7e,
+	0x3b, 0xaf, 0x79, 0xcf, 0xcd, 0xec, 0xe9, 0x61, 0xbe, 0xfa, 0x10, 0xf2,
+	0x05, 0xe6, 0xaa, 0xa3, 0xc0, 0x6b, 0x94, 0x49, 0x4c, 0x26, 0x8b, 0x1c,
+	0x4b, 0x22, 0x5b, 0x90, 0xdf, 0xe7, 0x64, 0x18, 0xf4, 0xc4, 0x90, 0xdb,
+	0x33, 0x3e, 0xdc, 0x25, 0xab, 0x11, 0x2f, 0x0e, 0xf0, 0xac, 0xd8, 0x2a,
+	0x62, 0xc3, 0xea, 0x7a, 0x6c, 0xd8, 0x89, 0x6b, 0x37, 0xe3, 0xf4, 0xfc,
+	0x67, 0x8c, 0xcf, 0xba, 0x0d, 0x63, 0xc3, 0x20, 0xfa, 0xb3, 0xad, 0x53,
+	0x26, 0xe7, 0x90, 0x44, 0x20, 0x67, 0x59, 0x10, 0x9e, 0x01, 0xc9, 0xca,
+	0xf4, 0x62, 0x77, 0xf4, 0xa2, 0x96, 0x56, 0x67, 0x45, 0xe2, 0x98, 0x73,
+	0xa1, 0xd8, 0x29, 0x8b, 0x73, 0x12, 0x33, 0x12, 0x8f, 0x48, 0x75, 0xd1,
+	0xc3, 0xec, 0x53, 0x1a, 0xda, 0xab, 0xae, 0x2c, 0x6e, 0xec, 0x63, 0x1a,
+	0x89, 0xc3, 0xf2, 0x75, 0xbf, 0x4f, 0x5a, 0xf5, 0x79, 0xb5, 0x83, 0x7b,
+	0x6c, 0x8b, 0xd5, 0x0e, 0xd0, 0x40, 0xda, 0x76, 0x35, 0xce, 0x1b, 0xbb,
+	0x3e, 0x2f, 0xe7, 0x44, 0x36, 0xb3, 0xdd, 0xc5, 0xbc, 0x17, 0xf1, 0xcc,
+	0x23, 0xa0, 0xe3, 0x9a, 0xa1, 0xdb, 0x8f, 0x48, 0x61, 0x71, 0xf3, 0x1c,
+	0x8d, 0x34, 0xf0, 0x19, 0x8e, 0xcf, 0x79, 0x0e, 0x83, 0xbe, 0x6b, 0x9a,
+	0x6e, 0x1f, 0x86, 0x2c, 0xbd, 0x39, 0x8c, 0xb3, 0x96, 0xf9, 0x23, 0xe9,
+	0x11, 0xfd, 0xbc, 0xa6, 0xe4, 0xaf, 0x2f, 0xf4, 0x63, 0x81, 0x64, 0xa4,
+	0x6d, 0x79, 0x4c, 0x8c, 0x65, 0xd6, 0x10, 0x5e, 0x69, 0x4d, 0xab, 0xfd,
+	0xde, 0x2d, 0x58, 0xdf, 0xe2, 0x86, 0x6c, 0xd6, 0x0b, 0x58, 0x0f, 0xfe,
+	0xfa, 0x36, 0xe9, 0x60, 0xbd, 0x80, 0x79, 0xc3, 0x21, 0x7c, 0x33, 0x77,
+	0x78, 0xb9, 0x9e, 0x74, 0x7e, 0xa6, 0xe2, 0x6b, 0x6e, 0x91, 0xf7, 0xad,
+	0x98, 0x08, 0xef, 0xd1, 0x6f, 0x74, 0x4a, 0xd3, 0x57, 0x7a, 0xe1, 0x2b,
+	0x1e, 0x03, 0xf6, 0xc6, 0xb8, 0x67, 0x7a, 0x24, 0xe4, 0x9d, 0xb1, 0x50,
+	0xf5, 0x96, 0x37, 0xe7, 0x2c, 0xff, 0x9d, 0x21, 0xd9, 0x73, 0xd1, 0x61,
+	0x4d, 0xb4, 0x8b, 0x35, 0x1f, 0xf4, 0x13, 0x7d, 0x15, 0xf9, 0xe9, 0x95,
+	0x45, 0x63, 0x1b, 0xcf, 0x7c, 0xbe, 0x5e, 0xc5, 0x35, 0xb1, 0x7f, 0x44,
+	0x61, 0x4c, 0xff, 0x1e, 0x7f, 0x23, 0x5f, 0x7a, 0xcf, 0xf9, 0x77, 0xe6,
+	0x53, 0x63, 0xfe, 0x59, 0x3b, 0x37, 0x73, 0x72, 0x43, 0x4e, 0xd5, 0xab,
+	0xea, 0xbd, 0x2b, 0x55, 0x1b, 0xfe, 0x71, 0x00, 0xf6, 0xc9, 0x35, 0x50,
+	0xd7, 0x1e, 0x02, 0x36, 0x8b, 0x75, 0xaa, 0x9c, 0xe8, 0xf4, 0x43, 0xe2,
+	0xd9, 0x3b, 0xac, 0x4c, 0xf9, 0xb2, 0x95, 0xb2, 0x97, 0x83, 0xac, 0x96,
+	0x33, 0xf2, 0x9f, 0xaa, 0x97, 0x54, 0xad, 0x75, 0x06, 0x79, 0x49, 0x68,
+	0x5a, 0xe5, 0x64, 0x0d, 0xf8, 0x16, 0x7e, 0xef, 0xd9, 0x2f, 0x62, 0x2d,
+	0x5a, 0xea, 0x4c, 0x83, 0x7e, 0xbe, 0x5e, 0x4f, 0xc1, 0x7f, 0xe8, 0xb6,
+	0x6d, 0x16, 0x10, 0x0f, 0x53, 0xea, 0x5c, 0x0c, 0xd7, 0xf1, 0x61, 0xe5,
+	0x9f, 0x65, 0x01, 0xb2, 0x39, 0x1b, 0xc3, 0x38, 0x9a, 0xb2, 0x4f, 0x43,
+	0xe9, 0xe1, 0x21, 0x85, 0x79, 0x8d, 0xf3, 0x70, 0x58, 0xcb, 0x3d, 0x22,
+	0xe7, 0x33, 0x32, 0x85, 0x35, 0x1c, 0x5a, 0xa6, 0x0e, 0x28, 0xdb, 0x31,
+	0x69, 0x82, 0xec, 0x4f, 0x00, 0x7b, 0x18, 0xd3, 0x94, 0x71, 0x14, 0xeb,
+	0xa2, 0x53, 0x42, 0x67, 0x21, 0xe3, 0x69, 0x60, 0x84, 0xb9, 0x66, 0x79,
+	0x69, 0x31, 0x90, 0xe9, 0xcb, 0x3c, 0xef, 0xaf, 0x8f, 0x0f, 0x74, 0x11,
+	0x47, 0x49, 0x65, 0x71, 0x4a, 0xa6, 0x66, 0x99, 0xb3, 0x8f, 0xa9, 0x33,
+	0x06, 0x21, 0x75, 0xc6, 0xc5, 0xcb, 0x99, 0xbd, 0x6f, 0x0f, 0x63, 0x56,
+	0x84, 0x7b, 0x6d, 0x02, 0xdb, 0xe9, 0xc7, 0xbc, 0x37, 0x92, 0xaf, 0x97,
+	0xab, 0x0e, 0x83, 0xde, 0x8b, 0x33, 0x56, 0x26, 0x2f, 0x0e, 0xcf, 0x5b,
+	0x8f, 0xba, 0xe0, 0x7f, 0x15, 0xfe, 0x73, 0xaa, 0x74, 0x2f, 0xf8, 0x2c,
+	0x60, 0x85, 0x65, 0xe4, 0x62, 0x91, 0x39, 0xe3, 0x47, 0xa1, 0x37, 0x5e,
+	0x17, 0x06, 0x0d, 0xf8, 0x81, 0x35, 0xf5, 0x7e, 0xa1, 0xe5, 0xae, 0x20,
+	0x87, 0x8d, 0x69, 0x87, 0xa0, 0xeb, 0xbc, 0xd9, 0xe4, 0xdb, 0x03, 0xdf,
+	0x35, 0x3e, 0x07, 0x3f, 0xba, 0x24, 0x7c, 0xef, 0xe7, 0x9d, 0x3a, 0xf3,
+	0xa5, 0xcb, 0xf0, 0x7b, 0x99, 0x78, 0x06, 0x36, 0x94, 0x8f, 0xb6, 0x80,
+	0xe6, 0xdf, 0xc6, 0xbd, 0x5c, 0x95, 0xf3, 0x58, 0xce, 0x9a, 0x14, 0x62,
+	0x21, 0xe9, 0x8b, 0x5d, 0x92, 0x6d, 0xf0, 0x64, 0x9a, 0xbc, 0x61, 0x5b,
+	0x83, 0xa2, 0xa9, 0xf1, 0x7a, 0x0f, 0xc0, 0x06, 0xaf, 0xc2, 0xdf, 0x35,
+	0xfb, 0xb9, 0x7e, 0xaa, 0x48, 0x0c, 0xf5, 0x84, 0x3a, 0x8b, 0x70, 0xd9,
+	0x66, 0x1d, 0x90, 0xef, 0xfb, 0xfe, 0x95, 0x9a, 0xe3, 0xfa, 0xde, 0x1d,
+	0xeb, 0xd0, 0xa4, 0xcf, 0xe3, 0x71, 0xbf, 0xed, 0xd1, 0xc8, 0x71, 0x9a,
+	0x1a, 0xc6, 0xb9, 0xe8, 0x8f, 0x73, 0xce, 0x1f, 0x67, 0xc1, 0x1f, 0xe7,
+	0xf2, 0xfa, 0x38, 0x0f, 0xc2, 0x0e, 0xea, 0xf5, 0xa7, 0x80, 0x37, 0x92,
+	0x4e, 0xbd, 0x9e, 0x46, 0x5e, 0x36, 0xd9, 0x3f, 0xa1, 0xf6, 0x5e, 0xf5,
+	0xc4, 0x8b, 0x43, 0x49, 0xdb, 0x93, 0x3f, 0xac, 0x40, 0x26, 0x60, 0x8f,
+	0x79, 0xf1, 0xb0, 0x3a, 0xf7, 0x03, 0xbd, 0xfd, 0xc2, 0x36, 0xf8, 0x81,
+	0xc7, 0x10, 0x4b, 0x9c, 0xe1, 0x25, 0x5b, 0xf2, 0x7b, 0x7e, 0x4d, 0x87,
+	0xbd, 0x77, 0x20, 0x2e, 0xbd, 0x09, 0xdb, 0x71, 0x86, 0x2b, 0x8b, 0x8f,
+	0xa9, 0x3d, 0xe1, 0xa6, 0xc4, 0xbd, 0xd0, 0x67, 0x79, 0x78, 0x61, 0xb1,
+	0x3c, 0x7c, 0x8e, 0xfb, 0x43, 0xe8, 0xb7, 0xb0, 0xd8, 0x0e, 0xb9, 0xb7,
+	0xab, 0xba, 0xca, 0xa5, 0x62, 0x04, 0x7a, 0x34, 0x61, 0xf3, 0x11, 0xb4,
+	0x45, 0x61, 0x07, 0x5d, 0x68, 0x7f, 0x0d, 0x6b, 0x3b, 0x86, 0xf6, 0xb5,
+	0xd6, 0x61, 0x85, 0x63, 0x6d, 0x39, 0x5f, 0xbd, 0x8a, 0x98, 0xfb, 0x16,
+	0xfc, 0x68, 0x2f, 0xfa, 0xf4, 0xa3, 0xcf, 0x0e, 0x13, 0xf8, 0x2a, 0x53,
+	0xbe, 0x21, 0x4d, 0x2e, 0x68, 0xd2, 0x1b, 0x68, 0x72, 0x41, 0x0f, 0x7c,
+	0xe7, 0x19, 0xd6, 0xa0, 0xfb, 0xe5, 0x64, 0x91, 0x67, 0xaa, 0xf8, 0xee,
+	0xb5, 0x29, 0x21, 0x60, 0xd2, 0xa6, 0x33, 0x56, 0x74, 0x45, 0xd5, 0x7a,
+	0x68, 0x5b, 0x7d, 0x4e, 0x45, 0x54, 0x9c, 0x89, 0x9d, 0x44, 0xfc, 0xba,
+	0x5a, 0x6d, 0x97, 0x37, 0xfc, 0xb9, 0xd6, 0x84, 0xfb, 0x97, 0x1b, 0xe7,
+	0x3a, 0x55, 0x1a, 0x1d, 0xfe, 0x81, 0x6d, 0xf8, 0x7c, 0x75, 0x62, 0xae,
+	0x76, 0xf4, 0x1d, 0x1d, 0xbe, 0xb8, 0x78, 0xa3, 0xbe, 0x13, 0xe8, 0xdb,
+	0xd4, 0xd0, 0x77, 0x02, 0xfd, 0xda, 0x11, 0x07, 0xdb, 0x15, 0x4f, 0x93,
+	0xa0, 0xeb, 0x4a, 0x51, 0xbd, 0x0b, 0x0c, 0xb9, 0x73, 0x4e, 0x93, 0x98,
+	0x3a, 0xe3, 0xd5, 0x4a, 0x2c, 0x33, 0xa6, 0xbd, 0xa7, 0xde, 0xa3, 0x6c,
+	0x60, 0xc8, 0x06, 0xee, 0x9d, 0x19, 0xd5, 0x52, 0x95, 0x1c, 0x62, 0xd6,
+	0x2e, 0xe2, 0x27, 0xc7, 0x45, 0xcc, 0x5c, 0xc0, 0x78, 0x8b, 0xc5, 0x15,
+	0x9e, 0xc1, 0x86, 0x5d, 0xbc, 0x4d, 0x9c, 0xbd, 0xcb, 0x50, 0x67, 0x1e,
+	0xd2, 0xaa, 0x66, 0xb7, 0x50, 0x14, 0x33, 0x39, 0xc0, 0x33, 0x0e, 0xf7,
+	0x63, 0x5d, 0x7e, 0x0e, 0x6d, 0x49, 0xc4, 0xc7, 0xc3, 0x5a, 0x72, 0x69,
+	0x18, 0xd7, 0x8f, 0xe0, 0x1a, 0xfe, 0x78, 0x2e, 0x8b, 0xfb, 0x8f, 0xe0,
+	0x7a, 0x42, 0x4b, 0xd5, 0xb2, 0xb8, 0x7e, 0x14, 0xd7, 0x49, 0x93, 0x79,
+	0xca, 0x0f, 0xec, 0x8c, 0xe6, 0x62, 0x2c, 0x77, 0x69, 0x18, 0x9f, 0xc6,
+	0xf1, 0x78, 0x0f, 0x7a, 0x2a, 0x72, 0xaf, 0x2d, 0x0e, 0x9a, 0x0e, 0x6a,
+	0xe9, 0x4a, 0x1b, 0xc6, 0xe8, 0xc1, 0xf3, 0xb4, 0xa9, 0x43, 0xfe, 0xfc,
+	0xac, 0x39, 0xdd, 0xad, 0x6a, 0x4e, 0x46, 0x22, 0x03, 0x9c, 0x7c, 0x1c,
+	0x79, 0x80, 0x26, 0x69, 0xfb, 0x49, 0x29, 0x38, 0xf0, 0x2b, 0x15, 0x43,
+	0x52, 0x91, 0x3c, 0x7e, 0xe7, 0x25, 0x39, 0x88, 0xfb, 0x15, 0xda, 0x02,
+	0xfb, 0xfd, 0x89, 0x14, 0xca, 0xc4, 0xfd, 0xac, 0x33, 0xb1, 0x36, 0xc5,
+	0xfa, 0x52, 0x0e, 0x32, 0x88, 0xd0, 0x7e, 0x6f, 0x50, 0x13, 0xf3, 0xce,
+	0x55, 0x23, 0x2e, 0x6b, 0xc9, 0x0a, 0xf7, 0xfd, 0xdc, 0xcc, 0x45, 0x9b,
+	0xef, 0x28, 0x4d, 0x70, 0x1f, 0xb1, 0x60, 0x24, 0x58, 0x1f, 0x51, 0xf5,
+	0x75, 0xc7, 0xdb, 0x1f, 0xe4, 0xb8, 0x63, 0xe0, 0xb7, 0xb1, 0x6e, 0xc5,
+	0x79, 0xbf, 0x80, 0xe7, 0xbd, 0x7a, 0x56, 0xaa, 0xf6, 0x5e, 0x5d, 0xf0,
+	0xbd, 0x81, 0xf3, 0xd0, 0xc5, 0x45, 0x95, 0x1b, 0x73, 0x0f, 0xf7, 0xfd,
+	0x72, 0x2a, 0xe4, 0x30, 0x45, 0xd6, 0xc8, 0x82, 0x7d, 0xbb, 0x40, 0x8e,
+	0x9b, 0x69, 0x25, 0x9d, 0x47, 0x30, 0xa6, 0x38, 0xf4, 0xbb, 0xd9, 0x08,
+	0xf7, 0xdf, 0xf8, 0x8c, 0x7c, 0xf9, 0x3a, 0xdd, 0xa4, 0x99, 0xf2, 0x38,
+	0x0e, 0xff, 0xc9, 0x77, 0x32, 0x9e, 0x94, 0x9c, 0xc3, 0x1a, 0x8f, 0x81,
+	0xd8, 0x98, 0xc7, 0xef, 0xeb, 0xf2, 0x9b, 0xf4, 0xe5, 0x97, 0x2b, 0xbf,
+	0xa4, 0x74, 0xb8, 0x60, 0x73, 0xbe, 0xa0, 0xf6, 0x31, 0xa2, 0x74, 0xb7,
+	0xa0, 0xce, 0xfd, 0x06, 0x32, 0x08, 0xea, 0x77, 0x37, 0xb6, 0xbd, 0x61,
+	0x9b, 0xb4, 0xdd, 0xce, 0xf3, 0x10, 0xbd, 0xae, 0x90, 0x7e, 0xf2, 0xc1,
+	0x18, 0x16, 0xec, 0xb5, 0x06, 0x3c, 0x04, 0x7c, 0xde, 0xaa, 0x7c, 0x48,
+	0x6f, 0x64, 0xbb, 0xb4, 0x65, 0x4c, 0xc3, 0x66, 0x6c, 0xf8, 0x84, 0xbf,
+	0x3f, 0xf0, 0x77, 0x21, 0x67, 0x4f, 0x16, 0xa1, 0x84, 0x4c, 0xfa, 0xef,
+	0xf8, 0xde, 0xc0, 0x1e, 0x36, 0xef, 0x35, 0xbb, 0x99, 0x73, 0xf6, 0x75,
+	0xbe, 0x17, 0x6e, 0xc0, 0xf7, 0x82, 0xcf, 0x77, 0xe5, 0x16, 0xe9, 0x5d,
+	0x98, 0x71, 0xc1, 0x33, 0x6d, 0xee, 0x46, 0xf6, 0x28, 0xea, 0x7f, 0x5f,
+	0xac, 0x19, 0xe1, 0xb0, 0x5b, 0xbd, 0x59, 0x0d, 0x95, 0x79, 0xb5, 0x67,
+	0x97, 0xe7, 0x10, 0x0b, 0xcb, 0x65, 0x2f, 0xc7, 0x2e, 0x57, 0x59, 0xcb,
+	0x7e, 0x3f, 0x1a, 0xf8, 0xfe, 0xd7, 0x67, 0xd4, 0x79, 0x97, 0xc9, 0xaa,
+	0x57, 0xf7, 0x2a, 0x97, 0x1b, 0x63, 0xea, 0x0e, 0xc6, 0xd3, 0xde, 0xbc,
+	0x8c, 0xf2, 0xbd, 0x65, 0x5c, 0xef, 0x96, 0x4b, 0x73, 0x6a, 0xcf, 0xca,
+	0xdf, 0x1b, 0xe2, 0x9e, 0x8f, 0xda, 0xff, 0x86, 0x5f, 0x1b, 0x53, 0x7e,
+	0x7d, 0x75, 0x4e, 0xdd, 0xf3, 0xb0, 0x52, 0x75, 0x14, 0x7e, 0x1f, 0xb9,
+	0x84, 0xbd, 0x55, 0x0a, 0xc8, 0xb9, 0xcf, 0xd9, 0x0f, 0x6f, 0x27, 0xce,
+	0xe1, 0x58, 0xab, 0x18, 0xeb, 0xe2, 0x9c, 0x6c, 0xe7, 0x99, 0x92, 0xb2,
+	0xda, 0x67, 0xf3, 0xea, 0xe2, 0x13, 0x12, 0xfc, 0x4f, 0x88, 0xb0, 0x1f,
+	0x0b, 0x79, 0xae, 0x85, 0xef, 0xd2, 0xd2, 0x57, 0x20, 0x0f, 0x1a, 0xe5,
+	0x3e, 0x4e, 0xbd, 0xee, 0xd5, 0xcd, 0xeb, 0x58, 0x17, 0x4d, 0x7c, 0xef,
+	0x02, 0x7f, 0xc7, 0x61, 0x3f, 0x58, 0x27, 0xeb, 0xed, 0xbc, 0x66, 0xee,
+	0x11, 0x5c, 0x33, 0xb0, 0xfd, 0x3f, 0xd4, 0x46, 0x90, 0x7c, 0xb4, 0x45,
+	0x00, 0x00, 0x00 };
 
 static const u32 bnx2_TXP_b09FwData[(0xd0/4) + 1] = {
 	0x00000000, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000010,
@@ -4041,37 +4065,38 @@
 	0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
 static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
-	0x08004060, 0x0800408c, 0x080040d4, 0x080040d4, 0x08003f60, 0x08003f8c,
-	0x08003f8c, 0x080040d4, 0x080040d4, 0x080040d4, 0x08003ff4, 0x00000000,
+	0x08003fdc, 0x08004008, 0x08004050, 0x08004050, 0x08003edc, 0x08003f08,
+	0x08003f08, 0x08004050, 0x08004050, 0x08004050, 0x08003f70, 0x00000000,
 	0x00000000 };
 
 static struct fw_info bnx2_txp_fw_09 = {
+	/* Firmware version:  3.7.1 */
 	.ver_major			= 0x3,
-	.ver_minor			= 0x4,
-	.ver_fix			= 0x3,
+	.ver_minor			= 0x7,
+	.ver_fix			= 0x1,
 
 	.start_addr			= 0x08000060,
 
 	.text_addr			= 0x08000000,
-	.text_len			= 0x4634,
+	.text_len			= 0x45b0,
 	.text_index			= 0x0,
 	.gz_text			= bnx2_TXP_b09FwText,
 	.gz_text_len			= sizeof(bnx2_TXP_b09FwText),
 
-	.data_addr			= 0x08004680,
+	.data_addr			= 0x08004600,
 	.data_len			= 0xd0,
 	.data_index			= 0x0,
 	.data				= bnx2_TXP_b09FwData,
 
-	.sbss_addr			= 0x08004750,
+	.sbss_addr			= 0x080046d0,
 	.sbss_len			= 0x8c,
 	.sbss_index			= 0x0,
 
-	.bss_addr			= 0x080047e0,
+	.bss_addr			= 0x08004760,
 	.bss_len			= 0xa20,
 	.bss_index			= 0x0,
 
-	.rodata_addr			= 0x08004638,
+	.rodata_addr			= 0x080045b0,
 	.rodata_len			= 0x30,
 	.rodata_index			= 0x0,
 	.rodata				= bnx2_TXP_b09FwRodata,
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 7a045a3..084f029 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -126,7 +126,7 @@
 
 // ================= main 802.3ad protocol functions ==================
 static int ad_lacpdu_send(struct port *port);
-static int ad_marker_send(struct port *port, struct marker *marker);
+static int ad_marker_send(struct port *port, struct bond_marker *marker);
 static void ad_mux_machine(struct port *port);
 static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port);
 static void ad_tx_machine(struct port *port);
@@ -139,8 +139,8 @@
 static void ad_initialize_lacpdu(struct lacpdu *Lacpdu);
 static void ad_enable_collecting_distributing(struct port *port);
 static void ad_disable_collecting_distributing(struct port *port);
-static void ad_marker_info_received(struct marker *marker_info, struct port *port);
-static void ad_marker_response_received(struct marker *marker, struct port *port);
+static void ad_marker_info_received(struct bond_marker *marker_info, struct port *port);
+static void ad_marker_response_received(struct bond_marker *marker, struct port *port);
 
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -889,12 +889,12 @@
  * Returns:   0 on success
  *          < 0 on error
  */
-static int ad_marker_send(struct port *port, struct marker *marker)
+static int ad_marker_send(struct port *port, struct bond_marker *marker)
 {
 	struct slave *slave = port->slave;
 	struct sk_buff *skb;
-	struct marker_header *marker_header;
-	int length = sizeof(struct marker_header);
+	struct bond_marker_header *marker_header;
+	int length = sizeof(struct bond_marker_header);
 	struct mac_addr lacpdu_multicast_address = AD_MULTICAST_LACPDU_ADDR;
 
 	skb = dev_alloc_skb(length + 16);
@@ -909,7 +909,7 @@
 	skb->network_header = skb->mac_header + ETH_HLEN;
 	skb->protocol = PKT_TYPE_LACPDU;
 
-	marker_header = (struct marker_header *)skb_put(skb, length);
+	marker_header = (struct bond_marker_header *)skb_put(skb, length);
 
 	marker_header->ad_header.destination_address = lacpdu_multicast_address;
 	/* Note: source addres is set to be the member's PERMANENT address, because we use it
@@ -1709,7 +1709,7 @@
  */
 static void ad_marker_info_send(struct port *port)
 {
-	struct marker marker;
+	struct bond_marker marker;
 	u16 index;
 
 	// fill the marker PDU with the appropriate values
@@ -1742,13 +1742,14 @@
  * @port: the port we're looking at
  *
  */
-static void ad_marker_info_received(struct marker *marker_info,struct port *port)
+static void ad_marker_info_received(struct bond_marker *marker_info,
+	struct port *port)
 {
-	struct marker marker;
+	struct bond_marker marker;
 
 	// copy the received marker data to the response marker
 	//marker = *marker_info;
-	memcpy(&marker, marker_info, sizeof(struct marker));
+	memcpy(&marker, marker_info, sizeof(struct bond_marker));
 	// change the marker subtype to marker response
 	marker.tlv_type=AD_MARKER_RESPONSE_SUBTYPE;
 	// send the marker response
@@ -1767,7 +1768,8 @@
  * response for marker PDU's, in this stage, but only to respond to marker
  * information.
  */
-static void ad_marker_response_received(struct marker *marker, struct port *port)
+static void ad_marker_response_received(struct bond_marker *marker,
+	struct port *port)
 {
 	marker=NULL; // just to satisfy the compiler
 	port=NULL;  // just to satisfy the compiler
@@ -2164,15 +2166,15 @@
 		case AD_TYPE_MARKER:
 			// No need to convert fields to Little Endian since we don't use the marker's fields.
 
-			switch (((struct marker *)lacpdu)->tlv_type) {
+			switch (((struct bond_marker *)lacpdu)->tlv_type) {
 			case AD_MARKER_INFORMATION_SUBTYPE:
 				dprintk("Received Marker Information on port %d\n", port->actor_port_number);
-				ad_marker_info_received((struct marker *)lacpdu, port);
+				ad_marker_info_received((struct bond_marker *)lacpdu, port);
 				break;
 
 			case AD_MARKER_RESPONSE_SUBTYPE:
 				dprintk("Received Marker Response on port %d\n", port->actor_port_number);
-				ad_marker_response_received((struct marker *)lacpdu, port);
+				ad_marker_response_received((struct bond_marker *)lacpdu, port);
 				break;
 
 			default:
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index 862952f..f165572 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -92,7 +92,7 @@
 typedef enum {
 	AD_MARKER_INFORMATION_SUBTYPE = 1, // marker imformation subtype
 	AD_MARKER_RESPONSE_SUBTYPE     // marker response subtype
-} marker_subtype_t;
+} bond_marker_subtype_t;
 
 // timers types(43.4.9 in the 802.3ad standard)
 typedef enum {
@@ -148,7 +148,7 @@
 } lacpdu_header_t;
 
 // Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard)
-typedef struct marker {
+typedef struct bond_marker {
 	u8 subtype;		 //  = 0x02  (marker PDU)
 	u8 version_number;	 //  = 0x01
 	u8 tlv_type;		 //  = 0x01  (marker information)
@@ -161,12 +161,12 @@
 	u8 tlv_type_terminator;	     //  = 0x00
 	u8 terminator_length;	     //  = 0x00
 	u8 reserved_90[90];	     //  = 0
-} marker_t;
+} bond_marker_t;
 
-typedef struct marker_header {
+typedef struct bond_marker_header {
 	struct ad_header ad_header;
-	struct marker marker;
-} marker_header_t;
+	struct bond_marker marker;
+} bond_marker_header_t;
 
 #pragma pack()
 
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 80c0c8c..855dc10 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -55,7 +55,7 @@
 static struct class *netdev_class;
 /*--------------------------- Data Structures -----------------------------*/
 
-/* Bonding sysfs lock.  Why can't we just use the subsytem lock?
+/* Bonding sysfs lock.  Why can't we just use the subsystem lock?
  * Because kobject_register tries to acquire the subsystem lock.  If
  * we already hold the lock (which we would if the user was creating
  * a new bond through the sysfs interface), we deadlock.
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index ed53aaa..ae41973 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -471,7 +471,7 @@
 	}
 
 	len = max(skb->len, ETH_ZLEN);
-	queue = skb->queue_mapping;
+	queue = skb_get_queue_mapping(skb);
 #ifdef CONFIG_NETDEVICES_MULTIQUEUE
 	netif_stop_subqueue(dev, queue);
 #else
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 314b2f6..edd6828 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -234,6 +234,7 @@
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/bitops.h>
 
 #include <linux/if.h>
 #include <linux/mii.h>
@@ -247,7 +248,6 @@
 #include <asm/irq.h>
 #include <asm/dma.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/ethernet.h>
 #include <asm/cache.h>
 
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 0442617..2a3df14 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -41,9 +41,9 @@
 #include <linux/timer.h>
 #include <linux/cache.h>
 #include <linux/mutex.h>
+#include <linux/bitops.h>
 #include "t3cdev.h"
 #include <asm/semaphore.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 
 typedef irqreturn_t(*intr_handler_t) (int, void *);
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 27ac010..3286d2a 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -542,7 +542,8 @@
 
 	if (id_val != DM9000_ID) {
 		printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val);
-		goto release;
+		ret = -ENODEV;
+		goto out;
 	}
 
 	/* from this point we assume that we have found a DM9000 */
@@ -602,8 +603,7 @@
 	}
 	return 0;
 
- release:
- out:
+out:
 	printk("%s: not found (%d).\n", CARDNAME, ret);
 
 	dm9000_release_board(pdev, db);
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 64f35e2..3dbaec6 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1324,7 +1324,7 @@
 		if (!--counter) break;
 	}
 
-	/* ack any interupts, something could have been set */
+	/* ack any interrupts, something could have been set */
 	iowrite8(~0, &nic->csr->scb.stat_ack);
 
 	/* if the command failed, or is not OK, notify and return */
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 0472638..f1ce348 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3590,7 +3590,7 @@
 
 	spin_lock_irqsave(&adapter->stats_lock, flags);
 
-	/* these counters are modified from e1000_adjust_tbi_stats,
+	/* these counters are modified from e1000_tbi_adjust_stats,
 	 * called from the interrupt context, so they must only
 	 * be written while holding adapter->stats_lock
 	 */
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index fe5ffac..2809c99 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -3218,7 +3218,7 @@
 	/* get adapter properties */
 	ret = ehea_sense_adapter_attr(adapter);
 	if (ret) {
-		dev_err(&dev->dev, "sense_adapter_attr failed: %d", ret);
+		dev_err(&dev->dev, "sense_adapter_attr failed: %d\n", ret);
 		goto out_free_ad;
 	}
 
@@ -3226,7 +3226,7 @@
 				      EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1);
 	if (!adapter->neq) {
 		ret = -EIO;
-		dev_err(&dev->dev, "NEQ creation failed");
+		dev_err(&dev->dev, "NEQ creation failed\n");
 		goto out_free_ad;
 	}
 
@@ -3237,7 +3237,7 @@
 				  ehea_interrupt_neq, IRQF_DISABLED,
 				  "ehea_neq", adapter);
 	if (ret) {
-		dev_err(&dev->dev, "requesting NEQ IRQ failed");
+		dev_err(&dev->dev, "requesting NEQ IRQ failed\n");
 		goto out_kill_eq;
 	}
 
@@ -3247,7 +3247,7 @@
 
 	ret = ehea_setup_ports(adapter);
 	if (ret) {
-		dev_err(&dev->dev, "setup_ports failed");
+		dev_err(&dev->dev, "setup_ports failed\n");
 		goto out_rem_dev_sysfs;
 	}
 
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
index 243fc6b..e3dd8b1 100644
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -170,7 +170,6 @@
 
 
 /* Few macros */
-#define BIT(a)		       ( (1 << (a)) )
 #define BITSET(ioaddr, bnum)   ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
 #define BITCLR(ioaddr, bnum)   ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
 
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index 43f7647..7bb9c72 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -111,7 +111,6 @@
 MODULE_DESCRIPTION("Myson MTD-8xx 100/10M Ethernet PCI Adapter Driver");
 MODULE_LICENSE("GPL");
 module_param(max_interrupt_work, int, 0);
-//MODULE_PARM(min_pci_latency, "i");
 module_param(debug, int, 0);
 module_param(rx_copybreak, int, 0);
 module_param(multicast_filter_limit, int, 0);
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 2b57820..0fbf1bb 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -751,13 +751,11 @@
 		if (mii_head) {
 			mii_tail->mii_next = mip;
 			mii_tail = mip;
-		}
-		else {
+		} else {
 			mii_head = mii_tail = mip;
 			fep->hwp->fec_mii_data = regval;
 		}
-	}
-	else {
+	} else {
 		retval = 1;
 	}
 
@@ -768,14 +766,11 @@
 
 static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c)
 {
-	int k;
-
 	if(!c)
 		return;
 
-	for(k = 0; (c+k)->mii_data != mk_mii_end; k++) {
-		mii_queue(dev, (c+k)->mii_data, (c+k)->funct);
-	}
+	for (; c->mii_data != mk_mii_end; c++)
+		mii_queue(dev, c->mii_data, c->funct);
 }
 
 static void mii_parse_sr(uint mii_reg, struct net_device *dev)
@@ -792,7 +787,6 @@
 		status |= PHY_STAT_FAULT;
 	if (mii_reg & 0x0020)
 		status |= PHY_STAT_ANC;
-
 	*s = status;
 }
 
@@ -1239,7 +1233,6 @@
 #endif
 
 #if defined(CONFIG_M5272)
-
 /*
  *	Code specific to Coldfire 5272 setup.
  */
@@ -2020,8 +2013,7 @@
 		    & (PHY_STAT_100FDX | PHY_STAT_10FDX))
 			duplex = 1;
 		fec_restart(dev, duplex);
-	}
-	else
+	} else
 		fec_stop(dev);
 
 #if 0
@@ -2119,8 +2111,7 @@
 			fep->phy_id = phytype << 16;
 			mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
 							mii_discover_phy3);
-		}
-		else {
+		} else {
 			fep->phy_addr++;
 			mii_queue(dev, mk_mii_read(MII_REG_PHYIR1),
 							mii_discover_phy);
@@ -2574,8 +2565,7 @@
 	if (duplex) {
 		fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */
 		fecp->fec_x_cntrl = 0x04;		  /* FD enable */
-	}
-	else {
+	} else {
 		/* MII enable|No Rcv on Xmit */
 		fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06;
 		fecp->fec_x_cntrl = 0x00;
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index cfbb7aa..70ddf1a 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -992,7 +992,7 @@
 		if (np->msi_flags & NV_MSI_X_ENABLED)
 			enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
 		else
-			enable_irq(dev->irq);
+			enable_irq(np->pci_dev->irq);
 	} else {
 		enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
 		enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1008,7 +1008,7 @@
 		if (np->msi_flags & NV_MSI_X_ENABLED)
 			disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
 		else
-			disable_irq(dev->irq);
+			disable_irq(np->pci_dev->irq);
 	} else {
 		disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
 		disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1607,7 +1607,7 @@
 		if (np->msi_flags & NV_MSI_X_ENABLED)
 			disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
 		else
-			disable_irq(dev->irq);
+			disable_irq(np->pci_dev->irq);
 	} else {
 		disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
 	}
@@ -1625,7 +1625,7 @@
 		if (np->msi_flags & NV_MSI_X_ENABLED)
 			enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
 		else
-			enable_irq(dev->irq);
+			enable_irq(np->pci_dev->irq);
 	} else {
 		enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
 	}
@@ -2408,13 +2408,13 @@
 	struct fe_priv *np = netdev_priv(dev);
 	u32 flags;
 	u32 vlanflags = 0;
-	u32 rx_processed_cnt = 0;
+	int rx_work = 0;
 	struct sk_buff *skb;
 	int len;
 
 	while((np->get_rx.ex != np->put_rx.ex) &&
 	      !((flags = le32_to_cpu(np->get_rx.ex->flaglen)) & NV_RX2_AVAIL) &&
-	      (rx_processed_cnt++ < limit)) {
+	      (rx_work < limit)) {
 
 		dprintk(KERN_DEBUG "%s: nv_rx_process_optimized: flags 0x%x.\n",
 					dev->name, flags);
@@ -2517,9 +2517,11 @@
 			np->get_rx.ex = np->first_rx.ex;
 		if (unlikely(np->get_rx_ctx++ == np->last_rx_ctx))
 			np->get_rx_ctx = np->first_rx_ctx;
+
+		rx_work++;
 	}
 
-	return rx_processed_cnt;
+	return rx_work;
 }
 
 static void set_bufsize(struct net_device *dev)
@@ -3558,10 +3560,12 @@
 	if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
 		if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
 			np->msi_flags |= NV_MSI_ENABLED;
+			dev->irq = np->pci_dev->irq;
 			if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) {
 				printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
 				pci_disable_msi(np->pci_dev);
 				np->msi_flags &= ~NV_MSI_ENABLED;
+				dev->irq = np->pci_dev->irq;
 				goto out_err;
 			}
 
@@ -3624,7 +3628,7 @@
 		if (np->msi_flags & NV_MSI_X_ENABLED)
 			disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
 		else
-			disable_irq_lockdep(dev->irq);
+			disable_irq_lockdep(np->pci_dev->irq);
 		mask = np->irqmask;
 	} else {
 		if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
@@ -3642,6 +3646,8 @@
 	}
 	np->nic_poll_irq = 0;
 
+	/* disable_irq() contains synchronize_irq, thus no irq handler can run now */
+
 	if (np->recover_error) {
 		np->recover_error = 0;
 		printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
@@ -3678,7 +3684,6 @@
 		}
 	}
 
-	/* FIXME: Do we need synchronize_irq(dev->irq) here? */
 
 	writel(mask, base + NvRegIrqMask);
 	pci_push(base);
@@ -3691,7 +3696,7 @@
 		if (np->msi_flags & NV_MSI_X_ENABLED)
 			enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
 		else
-			enable_irq_lockdep(dev->irq);
+			enable_irq_lockdep(np->pci_dev->irq);
 	} else {
 		if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
 			nv_nic_irq_rx(0, dev);
@@ -4948,7 +4953,7 @@
 #ifdef CONFIG_FORCEDETH_NAPI
 	napi_disable(&np->napi);
 #endif
-	synchronize_irq(dev->irq);
+	synchronize_irq(np->pci_dev->irq);
 
 	del_timer_sync(&np->oom_kick);
 	del_timer_sync(&np->nic_poll);
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 04c6fae..f2a4d39 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -88,7 +88,7 @@
 static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
 {
 	struct fs_enet_private *fep = container_of(napi, struct fs_enet_private, napi);
-	struct net_device *dev = to_net_dev(fep->dev);
+	struct net_device *dev = fep->ndev;
 	const struct fs_platform_info *fpi = fep->fpi;
 	cbd_t __iomem *bdp;
 	struct sk_buff *skb, *skbn, *skbt;
@@ -217,7 +217,7 @@
 
 	fep->cur_rx = bdp;
 
-	if (received >= budget) {
+	if (received < budget) {
 		/* done */
 		netif_rx_complete(dev, napi);
 		(*fep->ops->napi_enable_rx)(dev);
@@ -807,20 +807,23 @@
 	int r;
 	int err;
 
-	napi_enable(&fep->napi);
+	if (fep->fpi->use_napi)
+		napi_enable(&fep->napi);
 
 	/* Install our interrupt handler. */
 	r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt);
 	if (r != 0) {
 		printk(KERN_ERR DRV_MODULE_NAME
 		       ": %s Could not allocate FS_ENET IRQ!", dev->name);
-		napi_disable(&fep->napi);
+		if (fep->fpi->use_napi)
+			napi_disable(&fep->napi);
 		return -EINVAL;
 	}
 
 	err = fs_init_phy(dev);
-	if(err) {
-		napi_disable(&fep->napi);
+	if (err) {
+		if (fep->fpi->use_napi)
+			napi_disable(&fep->napi);
 		return err;
 	}
 	phy_start(fep->phydev);
@@ -1232,7 +1235,7 @@
 	fpi->rx_ring = 32;
 	fpi->tx_ring = 32;
 	fpi->rx_copybreak = 240;
-	fpi->use_napi = 0;
+	fpi->use_napi = 1;
 	fpi->napi_weight = 17;
 
 	ret = find_phy(ofdev->node, fpi);
@@ -1249,11 +1252,11 @@
 		goto out_free_fpi;
 	}
 
-	SET_MODULE_OWNER(ndev);
 	dev_set_drvdata(&ofdev->dev, ndev);
 
 	fep = netdev_priv(ndev);
 	fep->dev = &ofdev->dev;
+	fep->ndev = ndev;
 	fep->fpi = fpi;
 	fep->ops = match->data;
 
@@ -1288,10 +1291,11 @@
 	ndev->stop = fs_enet_close;
 	ndev->get_stats = fs_enet_get_stats;
 	ndev->set_multicast_list = fs_set_multicast_list;
-	if (fpi->use_napi) {
-		ndev->poll = fs_enet_rx_napi;
-		ndev->weight = fpi->napi_weight;
-	}
+
+	if (fpi->use_napi)
+		netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi,
+		               fpi->napi_weight);
+
 	ndev->ethtool_ops = &fs_ethtool_ops;
 	ndev->do_ioctl = fs_ioctl;
 
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index baf6477..c675e29 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -75,6 +75,7 @@
 struct fs_enet_private {
 	struct napi_struct napi;
 	struct device *dev;	/* pointer back to the device (must be initialized first) */
+	struct net_device *ndev;
 	spinlock_t lock;	/* during all ops except TX pckt processing */
 	spinlock_t tx_lock;	/* during fs_start_xmit and fs_tx         */
 	struct fs_platform_info *fpi;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index cc288d8..38268d7 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -956,10 +956,12 @@
 	}
 
 	err = startup_gfar(dev);
-	if (err)
+	if (err) {
 #ifdef CONFIG_GFAR_NAPI
 		napi_disable(&priv->napi);
 #endif
+		return err;
+	}
 
 	netif_start_queue(dev);
 
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index c16cc8b..46cd773 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -749,7 +749,6 @@
 	uint32_t msg_enable;
 
 	/* Network Statistics */
-	struct net_device_stats stats;
 	struct gfar_extra_stats extra_stats;
 };
 
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index ad9e327..e0119f6 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -3,7 +3,7 @@
  *		devices like TTY. It interfaces between a raw TTY and the
  *		kernel's AX.25 protocol layers.
  *
- * Authors:	Andreas Könsgen <ajk@iehk.rwth-aachen.de>
+ * Authors:	Andreas Könsgen <ajk@iehk.rwth-aachen.de>
  *              Ralf Baechle DL5RB <ralf@linux-mips.org>
  *
  * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index 36d2c7d..62d5d5c 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -64,7 +64,7 @@
 	  dmascc. If you don't pass any parameter to the driver, all
 	  possible I/O addresses are probed. This could irritate other devices
 	  that are currently not in use. You may specify the list of addresses
-	  to be probed by "dmascc=addr1,addr2,..." (when compiled into the
+	  to be probed by "dmascc.io=addr1,addr2,..." (when compiled into the
 	  kernel image) or "io=addr1,addr2,..." (when loaded as a module). The
 	  network interfaces will be called dmascc0 and dmascc1 for the board
 	  detected first, dmascc2 and dmascc3 for the second one, and so on.
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index bc02e46..11b83da 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -21,6 +21,7 @@
 
 
 #include <linux/module.h>
+#include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/if_arp.h>
@@ -35,7 +36,6 @@
 #include <linux/sockios.h>
 #include <linux/workqueue.h>
 #include <asm/atomic.h>
-#include <asm/bitops.h>
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/irq.h>
diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c
index a680eb0..9a88f71d 100644
--- a/drivers/net/ibm_newemac/mal.c
+++ b/drivers/net/ibm_newemac/mal.c
@@ -322,7 +322,7 @@
 		msleep(1);
 
 	/* Synchronize with the MAL NAPI poller */
-	__napi_synchronize(&mal->napi);
+	napi_synchronize(&mal->napi);
 }
 
 void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac)
diff --git a/drivers/net/irda/actisys-sir.c b/drivers/net/irda/actisys-sir.c
index ccf6ec5..736d247 100644
--- a/drivers/net/irda/actisys-sir.c
+++ b/drivers/net/irda/actisys-sir.c
@@ -21,7 +21,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
diff --git a/drivers/net/irda/actisys.c b/drivers/net/irda/actisys.c
index b2e31f4..ae0b80a 100644
--- a/drivers/net/irda/actisys.c
+++ b/drivers/net/irda/actisys.c
@@ -19,7 +19,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index a82d8f9..1257e1a 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -595,7 +595,7 @@
   OUTB ((physaddr >> 18) & 0xff, OBOE_RING_BASE1);
   OUTB ((physaddr >> 26) & 0x3f, OBOE_RING_BASE2);
 
-  /*Enable DMA controler in byte mode and RX */
+  /*Enable DMA controller in byte mode and RX */
   OUTB (CONFIG0H_DMA_ON, OBOE_CONFIG0H);
 
   /* Start up the clocks */
diff --git a/drivers/net/irda/girbil-sir.c b/drivers/net/irda/girbil-sir.c
index 0d2fe87f..738531b 100644
--- a/drivers/net/irda/girbil-sir.c
+++ b/drivers/net/irda/girbil-sir.c
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  * 
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/drivers/net/irda/girbil.c b/drivers/net/irda/girbil.c
index 248aeb0c..1f57391 100644
--- a/drivers/net/irda/girbil.c
+++ b/drivers/net/irda/girbil.c
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
diff --git a/drivers/net/irda/irport.h b/drivers/net/irda/irport.h
index 3f46b84..66fc243 100644
--- a/drivers/net/irda/irport.h
+++ b/drivers/net/irda/irport.h
@@ -17,7 +17,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 6f5f697..2c6f7be 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -20,7 +20,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index 12b9378..a873d2b 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -20,7 +20,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *
diff --git a/drivers/net/irda/nsc-ircc.h b/drivers/net/irda/nsc-ircc.h
index dacf671..bbdc97f 100644
--- a/drivers/net/irda/nsc-ircc.h
+++ b/drivers/net/irda/nsc-ircc.h
@@ -19,7 +19,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
diff --git a/drivers/net/irda/tekram-sir.c b/drivers/net/irda/tekram-sir.c
index 0dd6bc7..d1ce5ae 100644
--- a/drivers/net/irda/tekram-sir.c
+++ b/drivers/net/irda/tekram-sir.c
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
diff --git a/drivers/net/irda/tekram.c b/drivers/net/irda/tekram.c
index 8f62582..9bfd244 100644
--- a/drivers/net/irda/tekram.c
+++ b/drivers/net/irda/tekram.c
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
diff --git a/drivers/net/irda/w83977af_ir.h b/drivers/net/irda/w83977af_ir.h
index 0b7661d..87c3975 100644
--- a/drivers/net/irda/w83977af_ir.h
+++ b/drivers/net/irda/w83977af_ir.h
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
  *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *     
diff --git a/drivers/net/lguest_net.c b/drivers/net/lguest_net.c
deleted file mode 100644
index abce2ee..0000000
--- a/drivers/net/lguest_net.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*D:500
- * The Guest network driver.
- *
- * This is very simple a virtual network driver, and our last Guest driver.
- * The only trick is that it can talk directly to multiple other recipients
- * (ie. other Guests on the same network).  It can also be used with only the
- * Host on the network.
- :*/
-
-/* Copyright 2006 Rusty Russell <rusty@rustcorp.com.au> IBM 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
- */
-//#define DEBUG
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/module.h>
-#include <linux/mm_types.h>
-#include <linux/io.h>
-#include <linux/lguest_bus.h>
-
-#define SHARED_SIZE		PAGE_SIZE
-#define MAX_LANS		4
-#define NUM_SKBS		8
-
-/*M:011 Network code master Jeff Garzik points out numerous shortcomings in
- * this driver if it aspires to greatness.
- *
- * Firstly, it doesn't use "NAPI": the networking's New API, and is poorer for
- * it.  As he says "NAPI means system-wide load leveling, across multiple
- * network interfaces.  Lack of NAPI can mean competition at higher loads."
- *
- * He also points out that we don't implement set_mac_address, so users cannot
- * change the devices hardware address.  When I asked why one would want to:
- * "Bonding, and situations where you /do/ want the MAC address to "leak" out
- * of the host onto the wider net."
- *
- * Finally, he would like module unloading: "It is not unrealistic to think of
- * [un|re|]loading the net support module in an lguest guest.  And, adding
- * module support makes the programmer more responsible, because they now have
- * to learn to clean up after themselves.  Any driver that cannot clean up
- * after itself is an incomplete driver in my book."
- :*/
-
-/*D:530 The "struct lguestnet_info" contains all the information we need to
- * know about the network device. */
-struct lguestnet_info
-{
-	/* The mapped device page(s) (an array of "struct lguest_net"). */
-	struct lguest_net *peer;
-	/* The physical address of the device page(s) */
-	unsigned long peer_phys;
-	/* The size of the device page(s). */
-	unsigned long mapsize;
-
-	/* The lguest_device I come from */
-	struct lguest_device *lgdev;
-
-	/* My peerid (ie. my slot in the array). */
-	unsigned int me;
-
-	/* Receive queue: the network packets waiting to be filled. */
-	struct sk_buff *skb[NUM_SKBS];
-	struct lguest_dma dma[NUM_SKBS];
-};
-/*:*/
-
-/* How many bytes left in this page. */
-static unsigned int rest_of_page(void *data)
-{
-	return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
-}
-
-/*D:570 Each peer (ie. Guest or Host) on the network binds their receive
- * buffers to a different key: we simply use the physical address of the
- * device's memory page plus the peer number.  The Host insists that all keys
- * be a multiple of 4, so we multiply the peer number by 4. */
-static unsigned long peer_key(struct lguestnet_info *info, unsigned peernum)
-{
-	return info->peer_phys + 4 * peernum;
-}
-
-/* This is the routine which sets up a "struct lguest_dma" to point to a
- * network packet, similar to req_to_dma() in lguest_blk.c.  The structure of a
- * "struct sk_buff" has grown complex over the years: it consists of a "head"
- * linear section pointed to by "skb->data", and possibly an array of
- * "fragments" in the case of a non-linear packet.
- *
- * Our receive buffers don't use fragments at all but outgoing skbs might, so
- * we handle it. */
-static void skb_to_dma(const struct sk_buff *skb, unsigned int headlen,
-		       struct lguest_dma *dma)
-{
-	unsigned int i, seg;
-
-	/* First, we put the linear region into the "struct lguest_dma".  Each
-	 * entry can't go over a page boundary, so even though all our packets
-	 * are 1514 bytes or less, we might need to use two entries here: */
-	for (i = seg = 0; i < headlen; seg++, i += rest_of_page(skb->data+i)) {
-		dma->addr[seg] = virt_to_phys(skb->data + i);
-		dma->len[seg] = min((unsigned)(headlen - i),
-				    rest_of_page(skb->data + i));
-	}
-
-	/* Now we handle the fragments: at least they're guaranteed not to go
-	 * over a page.  skb_shinfo(skb) returns a pointer to the structure
-	 * which tells us about the number of fragments and the fragment
-	 * array. */
-	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++, seg++) {
-		const skb_frag_t *f = &skb_shinfo(skb)->frags[i];
-		/* Should not happen with MTU less than 64k - 2 * PAGE_SIZE. */
-		if (seg == LGUEST_MAX_DMA_SECTIONS) {
-			/* We will end up sending a truncated packet should
-			 * this ever happen.  Plus, a cool log message! */
-			printk("Woah dude!  Megapacket!\n");
-			break;
-		}
-		dma->addr[seg] = page_to_phys(f->page) + f->page_offset;
-		dma->len[seg] = f->size;
-	}
-
-	/* If after all that we didn't use the entire "struct lguest_dma"
-	 * array, we terminate it with a 0 length. */
-	if (seg < LGUEST_MAX_DMA_SECTIONS)
-		dma->len[seg] = 0;
-}
-
-/*
- * Packet transmission.
- *
- * Our packet transmission is a little unusual.  A real network card would just
- * send out the packet and leave the receivers to decide if they're interested.
- * Instead, we look through the network device memory page and see if any of
- * the ethernet addresses match the packet destination, and if so we send it to
- * that Guest.
- *
- * This is made a little more complicated in two cases.  The first case is
- * broadcast packets: for that we send the packet to all Guests on the network,
- * one at a time.  The second case is "promiscuous" mode, where a Guest wants
- * to see all the packets on the network.  We need a way for the Guest to tell
- * us it wants to see all packets, so it sets the "multicast" bit on its
- * published MAC address, which is never valid in a real ethernet address.
- */
-#define PROMISC_BIT		0x01
-
-/* This is the callback which is summoned whenever the network device's
- * multicast or promiscuous state changes.  If the card is in promiscuous mode,
- * we advertise that in our ethernet address in the device's memory.  We do the
- * same if Linux wants any or all multicast traffic.  */
-static void lguestnet_set_multicast(struct net_device *dev)
-{
-	struct lguestnet_info *info = netdev_priv(dev);
-
-	if ((dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) || dev->mc_count)
-		info->peer[info->me].mac[0] |= PROMISC_BIT;
-	else
-		info->peer[info->me].mac[0] &= ~PROMISC_BIT;
-}
-
-/* A simple test function to see if a peer wants to see all packets.*/
-static int promisc(struct lguestnet_info *info, unsigned int peer)
-{
-	return info->peer[peer].mac[0] & PROMISC_BIT;
-}
-
-/* Another simple function to see if a peer's advertised ethernet address
- * matches a packet's destination ethernet address. */
-static int mac_eq(const unsigned char mac[ETH_ALEN],
-		  struct lguestnet_info *info, unsigned int peer)
-{
-	/* Ignore multicast bit, which peer turns on to mean promisc. */
-	if ((info->peer[peer].mac[0] & (~PROMISC_BIT)) != mac[0])
-		return 0;
-	return memcmp(mac+1, info->peer[peer].mac+1, ETH_ALEN-1) == 0;
-}
-
-/* This is the function which actually sends a packet once we've decided a
- * peer wants it: */
-static void transfer_packet(struct net_device *dev,
-			    struct sk_buff *skb,
-			    unsigned int peernum)
-{
-	struct lguestnet_info *info = netdev_priv(dev);
-	struct lguest_dma dma;
-
-	/* We use our handy "struct lguest_dma" packing function to prepare
-	 * the skb for sending. */
-	skb_to_dma(skb, skb_headlen(skb), &dma);
-	pr_debug("xfer length %04x (%u)\n", htons(skb->len), skb->len);
-
-	/* This is the actual send call which copies the packet. */
-	lguest_send_dma(peer_key(info, peernum), &dma);
-
-	/* Check that the entire packet was transmitted.  If not, it could mean
-	 * that the other Guest registered a short receive buffer, but this
-	 * driver should never do that.  More likely, the peer is dead. */
-	if (dma.used_len != skb->len) {
-		dev->stats.tx_carrier_errors++;
-		pr_debug("Bad xfer to peer %i: %i of %i (dma %p/%i)\n",
-			 peernum, dma.used_len, skb->len,
-			 (void *)dma.addr[0], dma.len[0]);
-	} else {
-		/* On success we update the stats. */
-		dev->stats.tx_bytes += skb->len;
-		dev->stats.tx_packets++;
-	}
-}
-
-/* Another helper function to tell is if a slot in the device memory is unused.
- * Since we always set the Local Assignment bit in the ethernet address, the
- * first byte can never be 0. */
-static int unused_peer(const struct lguest_net peer[], unsigned int num)
-{
-	return peer[num].mac[0] == 0;
-}
-
-/* Finally, here is the routine which handles an outgoing packet.  It's called
- * "start_xmit" for traditional reasons. */
-static int lguestnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	unsigned int i;
-	int broadcast;
-	struct lguestnet_info *info = netdev_priv(dev);
-	/* Extract the destination ethernet address from the packet. */
-	const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
-	DECLARE_MAC_BUF(mac);
-
-	pr_debug("%s: xmit %s\n", dev->name, print_mac(mac, dest));
-
-	/* If it's a multicast packet, we broadcast to everyone.  That's not
-	 * very efficient, but there are very few applications which actually
-	 * use multicast, which is a shame really.
-	 *
-	 * As etherdevice.h points out: "By definition the broadcast address is
-	 * also a multicast address."  So we don't have to test for broadcast
-	 * packets separately. */
-	broadcast = is_multicast_ether_addr(dest);
-
-	/* Look through all the published ethernet addresses to see if we
-	 * should send this packet. */
-	for (i = 0; i < info->mapsize/sizeof(struct lguest_net); i++) {
-		/* We don't send to ourselves (we actually can't SEND_DMA to
-		 * ourselves anyway), and don't send to unused slots.*/
-		if (i == info->me || unused_peer(info->peer, i))
-			continue;
-
-		/* If it's broadcast we send it.  If they want every packet we
-		 * send it.  If the destination matches their address we send
-		 * it.  Otherwise we go to the next peer. */
-		if (!broadcast && !promisc(info, i) && !mac_eq(dest, info, i))
-			continue;
-
-		pr_debug("lguestnet %s: sending from %i to %i\n",
-			 dev->name, info->me, i);
-		/* Our routine which actually does the transfer. */
-		transfer_packet(dev, skb, i);
-	}
-
-	/* An xmit routine is expected to dispose of the packet, so we do. */
-	dev_kfree_skb(skb);
-
-	/* As per kernel convention, 0 means success.  This is why I love
-	 * networking: even if we never sent to anyone, that's still
-	 * success! */
-	return 0;
-}
-
-/*D:560
- * Packet receiving.
- *
- * First, here's a helper routine which fills one of our array of receive
- * buffers: */
-static int fill_slot(struct net_device *dev, unsigned int slot)
-{
-	struct lguestnet_info *info = netdev_priv(dev);
-
-	/* We can receive ETH_DATA_LEN (1500) byte packets, plus a standard
-	 * ethernet header of ETH_HLEN (14) bytes. */
-	info->skb[slot] = netdev_alloc_skb(dev, ETH_HLEN + ETH_DATA_LEN);
-	if (!info->skb[slot]) {
-		printk("%s: could not fill slot %i\n", dev->name, slot);
-		return -ENOMEM;
-	}
-
-	/* skb_to_dma() is a helper which sets up the "struct lguest_dma" to
-	 * point to the data in the skb: we also use it for sending out a
-	 * packet. */
-	skb_to_dma(info->skb[slot], ETH_HLEN + ETH_DATA_LEN, &info->dma[slot]);
-
-	/* This is a Write Memory Barrier: it ensures that the entry in the
-	 * receive buffer array is written *before* we set the "used_len" entry
-	 * to 0.  If the Host were looking at the receive buffer array from a
-	 * different CPU, it could potentially see "used_len = 0" and not see
-	 * the updated receive buffer information.  This would be a horribly
-	 * nasty bug, so make sure the compiler and CPU know this has to happen
-	 * first. */
-	wmb();
-	/* Writing 0 to "used_len" tells the Host it can use this receive
-	 * buffer now. */
-	info->dma[slot].used_len = 0;
-	return 0;
-}
-
-/* This is the actual receive routine.  When we receive an interrupt from the
- * Host to tell us a packet has been delivered, we arrive here: */
-static irqreturn_t lguestnet_rcv(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct lguestnet_info *info = netdev_priv(dev);
-	unsigned int i, done = 0;
-
-	/* Look through our entire receive array for an entry which has data
-	 * in it. */
-	for (i = 0; i < ARRAY_SIZE(info->dma); i++) {
-		unsigned int length;
-		struct sk_buff *skb;
-
-		length = info->dma[i].used_len;
-		if (length == 0)
-			continue;
-
-		/* We've found one!  Remember the skb (we grabbed the length
-		 * above), and immediately refill the slot we've taken it
-		 * from. */
-		done++;
-		skb = info->skb[i];
-		fill_slot(dev, i);
-
-		/* This shouldn't happen: micropackets could be sent by a
-		 * badly-behaved Guest on the network, but the Host will never
-		 * stuff more data in the buffer than the buffer length. */
-		if (length < ETH_HLEN || length > ETH_HLEN + ETH_DATA_LEN) {
-			pr_debug(KERN_WARNING "%s: unbelievable skb len: %i\n",
-				 dev->name, length);
-			dev_kfree_skb(skb);
-			continue;
-		}
-
-		/* skb_put(), what a great function!  I've ranted about this
-		 * function before (http://lkml.org/lkml/1999/9/26/24).  You
-		 * call it after you've added data to the end of an skb (in
-		 * this case, it was the Host which wrote the data). */
-		skb_put(skb, length);
-
-		/* The ethernet header contains a protocol field: we use the
-		 * standard helper to extract it, and place the result in
-		 * skb->protocol.  The helper also sets up skb->pkt_type and
-		 * eats up the ethernet header from the front of the packet. */
-		skb->protocol = eth_type_trans(skb, dev);
-
-		/* If this device doesn't need checksums for sending, we also
-		 * don't need to check the packets when they come in. */
-		if (dev->features & NETIF_F_NO_CSUM)
-			skb->ip_summed = CHECKSUM_UNNECESSARY;
-
-		/* As a last resort for debugging the driver or the lguest I/O
-		 * subsystem, you can uncomment the "#define DEBUG" at the top
-		 * of this file, which turns all the pr_debug() into printk()
-		 * and floods the logs. */
-		pr_debug("Receiving skb proto 0x%04x len %i type %i\n",
-			 ntohs(skb->protocol), skb->len, skb->pkt_type);
-
-		/* Update the packet and byte counts (visible from ifconfig,
-		 * and good for debugging). */
-		dev->stats.rx_bytes += skb->len;
-		dev->stats.rx_packets++;
-
-		/* Hand our fresh network packet into the stack's "network
-		 * interface receive" routine.  That will free the packet
-		 * itself when it's finished. */
-		netif_rx(skb);
-	}
-
-	/* If we found any packets, we assume the interrupt was for us. */
-	return done ? IRQ_HANDLED : IRQ_NONE;
-}
-
-/*D:550 This is where we start: when the device is brought up by dhcpd or
- * ifconfig.  At this point we advertise our MAC address to the rest of the
- * network, and register receive buffers ready for incoming packets. */
-static int lguestnet_open(struct net_device *dev)
-{
-	int i;
-	struct lguestnet_info *info = netdev_priv(dev);
-
-	/* Copy our MAC address into the device page, so others on the network
-	 * can find us. */
-	memcpy(info->peer[info->me].mac, dev->dev_addr, ETH_ALEN);
-
-	/* We might already be in promisc mode (dev->flags & IFF_PROMISC).  Our
-	 * set_multicast callback handles this already, so we call it now. */
-	lguestnet_set_multicast(dev);
-
-	/* Allocate packets and put them into our "struct lguest_dma" array.
-	 * If we fail to allocate all the packets we could still limp along,
-	 * but it's a sign of real stress so we should probably give up now. */
-	for (i = 0; i < ARRAY_SIZE(info->dma); i++) {
-		if (fill_slot(dev, i) != 0)
-			goto cleanup;
-	}
-
-	/* Finally we tell the Host where our array of "struct lguest_dma"
-	 * receive buffers is, binding it to the key corresponding to the
-	 * device's physical memory plus our peerid. */
-	if (lguest_bind_dma(peer_key(info,info->me), info->dma,
-			    NUM_SKBS, lgdev_irq(info->lgdev)) != 0)
-		goto cleanup;
-	return 0;
-
-cleanup:
-	while (--i >= 0)
-		dev_kfree_skb(info->skb[i]);
-	return -ENOMEM;
-}
-/*:*/
-
-/* The close routine is called when the device is no longer in use: we clean up
- * elegantly. */
-static int lguestnet_close(struct net_device *dev)
-{
-	unsigned int i;
-	struct lguestnet_info *info = netdev_priv(dev);
-
-	/* Clear all trace of our existence out of the device memory by setting
-	 * the slot which held our MAC address to 0 (unused). */
-	memset(&info->peer[info->me], 0, sizeof(info->peer[info->me]));
-
-	/* Unregister our array of receive buffers */
-	lguest_unbind_dma(peer_key(info, info->me), info->dma);
-	for (i = 0; i < ARRAY_SIZE(info->dma); i++)
-		dev_kfree_skb(info->skb[i]);
-	return 0;
-}
-
-/*D:510 The network device probe function is basically a standard ethernet
- * device setup.  It reads the "struct lguest_device_desc" and sets the "struct
- * net_device".  Oh, the line-by-line excitement!  Let's skip over it. :*/
-static int lguestnet_probe(struct lguest_device *lgdev)
-{
-	int err, irqf = IRQF_SHARED;
-	struct net_device *dev;
-	struct lguestnet_info *info;
-	struct lguest_device_desc *desc = &lguest_devices[lgdev->index];
-
-	pr_debug("lguest_net: probing for device %i\n", lgdev->index);
-
-	dev = alloc_etherdev(sizeof(struct lguestnet_info));
-	if (!dev)
-		return -ENOMEM;
-
-	/* Ethernet defaults with some changes */
-	ether_setup(dev);
-	dev->set_mac_address = NULL;
-
-	dev->dev_addr[0] = 0x02; /* set local assignment bit (IEEE802) */
-	dev->dev_addr[1] = 0x00;
-	memcpy(&dev->dev_addr[2], &lguest_data.guestid, 2);
-	dev->dev_addr[4] = 0x00;
-	dev->dev_addr[5] = 0x00;
-
-	dev->open = lguestnet_open;
-	dev->stop = lguestnet_close;
-	dev->hard_start_xmit = lguestnet_start_xmit;
-
-	/* We don't actually support multicast yet, but turning on/off
-	 * promisc also calls dev->set_multicast_list. */
-	dev->set_multicast_list = lguestnet_set_multicast;
-	SET_NETDEV_DEV(dev, &lgdev->dev);
-
-	/* The network code complains if you have "scatter-gather" capability
-	 * if you don't also handle checksums (it seem that would be
-	 * "illogical").  So we use a lie of omission and don't tell it that we
-	 * can handle scattered packets unless we also don't want checksums,
-	 * even though to us they're completely independent. */
-	if (desc->features & LGUEST_NET_F_NOCSUM)
-		dev->features = NETIF_F_SG|NETIF_F_NO_CSUM;
-
-	info = netdev_priv(dev);
-	info->mapsize = PAGE_SIZE * desc->num_pages;
-	info->peer_phys = ((unsigned long)desc->pfn << PAGE_SHIFT);
-	info->lgdev = lgdev;
-	info->peer = lguest_map(info->peer_phys, desc->num_pages);
-	if (!info->peer) {
-		err = -ENOMEM;
-		goto free;
-	}
-
-	/* This stores our peerid (upper bits reserved for future). */
-	info->me = (desc->features & (info->mapsize-1));
-
-	err = register_netdev(dev);
-	if (err) {
-		pr_debug("lguestnet: registering device failed\n");
-		goto unmap;
-	}
-
-	if (lguest_devices[lgdev->index].features & LGUEST_DEVICE_F_RANDOMNESS)
-		irqf |= IRQF_SAMPLE_RANDOM;
-	if (request_irq(lgdev_irq(lgdev), lguestnet_rcv, irqf, "lguestnet",
-			dev) != 0) {
-		pr_debug("lguestnet: cannot get irq %i\n", lgdev_irq(lgdev));
-		goto unregister;
-	}
-
-	pr_debug("lguestnet: registered device %s\n", dev->name);
-	/* Finally, we put the "struct net_device" in the generic "struct
-	 * lguest_device"s private pointer.  Again, it's not necessary, but
-	 * makes sure the cool kernel kids don't tease us. */
-	lgdev->private = dev;
-	return 0;
-
-unregister:
-	unregister_netdev(dev);
-unmap:
-	lguest_unmap(info->peer);
-free:
-	free_netdev(dev);
-	return err;
-}
-
-static struct lguest_driver lguestnet_drv = {
-	.name = "lguestnet",
-	.owner = THIS_MODULE,
-	.device_type = LGUEST_DEVICE_T_NET,
-	.probe = lguestnet_probe,
-};
-
-static __init int lguestnet_init(void)
-{
-	return register_lguest_driver(&lguestnet_drv);
-}
-module_init(lguestnet_init);
-
-MODULE_DESCRIPTION("Lguest network driver");
-MODULE_LICENSE("GPL");
-
-/*D:580
- * This is the last of the Drivers, and with this we have covered the many and
- * wonderous and fine (and boring) details of the Guest.
- *
- * "make Launcher" beckons, where we answer questions like "Where do Guests
- * come from?", and "What do you do when someone asks for optimization?"
- */
diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c
index 30854f0..a19b595 100644
--- a/drivers/net/mac89x0.c
+++ b/drivers/net/mac89x0.c
@@ -99,9 +99,9 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/hwtest.h>
 #include <asm/macints.h>
diff --git a/drivers/net/meth.h b/drivers/net/meth.h
index ea3b8fc..a78dc1c 100644
--- a/drivers/net/meth.h
+++ b/drivers/net/meth.h
@@ -28,9 +28,6 @@
 #define RX_BUFFER_OFFSET (sizeof(rx_status_vector)+2) /* staus vector + 2 bytes of padding */
 #define RX_BUCKET_SIZE 256
 
-#undef BIT
-#define BIT(x)	(1UL << (x))
-
 /* For more detailed explanations of what each field menas,
    see Nick's great comments to #defines below (or docs, if
    you are lucky enough toget hold of them :)*/
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index 6471d33..5064873 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -736,7 +736,7 @@
 	MLX4_PUT(inbox, (u8) (PAGE_SHIFT - 12), INIT_HCA_UAR_PAGE_SZ_OFFSET);
 	MLX4_PUT(inbox, param->log_uar_sz,      INIT_HCA_LOG_UAR_SZ_OFFSET);
 
-	err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_INIT_HCA, 1000);
+	err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_INIT_HCA, 10000);
 
 	if (err)
 		mlx4_err(dev, "INIT_HCA returns %d\n", err);
diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c
index 4b3c109d..887633b 100644
--- a/drivers/net/mlx4/icm.c
+++ b/drivers/net/mlx4/icm.c
@@ -60,7 +60,7 @@
 			     PCI_DMA_BIDIRECTIONAL);
 
 	for (i = 0; i < chunk->npages; ++i)
-		__free_pages(chunk->mem[i].page,
+		__free_pages(sg_page(&chunk->mem[i]),
 			     get_order(chunk->mem[i].length));
 }
 
@@ -70,7 +70,7 @@
 
 	for (i = 0; i < chunk->npages; ++i)
 		dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
-				  lowmem_page_address(chunk->mem[i].page),
+				  lowmem_page_address(sg_page(&chunk->mem[i])),
 				  sg_dma_address(&chunk->mem[i]));
 }
 
@@ -95,10 +95,13 @@
 
 static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
 {
-	mem->page = alloc_pages(gfp_mask, order);
-	if (!mem->page)
+	struct page *page;
+
+	page = alloc_pages(gfp_mask, order);
+	if (!page)
 		return -ENOMEM;
 
+	sg_set_page(mem, page);
 	mem->length = PAGE_SIZE << order;
 	mem->offset = 0;
 	return 0;
@@ -145,6 +148,7 @@
 			if (!chunk)
 				goto fail;
 
+			sg_init_table(chunk->mem, MLX4_ICM_CHUNK_LEN);
 			chunk->npages = 0;
 			chunk->nsg    = 0;
 			list_add_tail(&chunk->list, &icm->chunk_list);
@@ -334,7 +338,7 @@
 			 * been assigned to.
 			 */
 			if (chunk->mem[i].length > offset) {
-				page = chunk->mem[i].page;
+				page = sg_page(&chunk->mem[i]);
 				goto out;
 			}
 			offset -= chunk->mem[i].length;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 64c8151..366e62a 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -3058,7 +3058,8 @@
 	if (status != 0) {
 		dac_enabled = 0;
 		dev_err(&pdev->dev,
-			"64-bit pci address mask was refused, trying 32-bit");
+			"64-bit pci address mask was refused, "
+			"trying 32-bit\n");
 		status = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 	}
 	if (status != 0) {
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 50e1ec6..9531171 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -996,7 +996,7 @@
    a delay.  Note that pre-2.0.34 kernels had a cache-alignment bug that
    made udelay() unreliable.
    The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
-   depricated.
+   deprecated.
 */
 #define eeprom_delay(ee_addr)	readl(ee_addr)
 
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 2a1d6d7..601051c 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -53,9 +53,6 @@
 #define NETXEN_ADAPTER_UP_MAGIC 777
 #define NETXEN_NIC_PEG_TUNE 0
 
-#define DMA_32BIT_MASK	0x00000000ffffffffULL
-#define DMA_35BIT_MASK	0x00000007ffffffffULL
-
 /* Local functions to NetXen NIC driver */
 static int __devinit netxen_nic_probe(struct pci_dev *pdev,
 				      const struct pci_device_id *ent);
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index ed1f9bb..112ab07 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -3103,31 +3103,12 @@
 
 static void niu_size_rbr(struct niu *np, struct rx_ring_info *rp)
 {
-	u16 bs;
+	u16 bss;
 
-	switch (PAGE_SIZE) {
-	case 4 * 1024:
-	case 8 * 1024:
-	case 16 * 1024:
-	case 32 * 1024:
-		rp->rbr_block_size = PAGE_SIZE;
-		rp->rbr_blocks_per_page = 1;
-		break;
+	bss = min(PAGE_SHIFT, 15);
 
-	default:
-		if (PAGE_SIZE % (32 * 1024) == 0)
-			bs = 32 * 1024;
-		else if (PAGE_SIZE % (16 * 1024) == 0)
-			bs = 16 * 1024;
-		else if (PAGE_SIZE % (8 * 1024) == 0)
-			bs = 8 * 1024;
-		else if (PAGE_SIZE % (4 * 1024) == 0)
-			bs = 4 * 1024;
-		else
-			BUG();
-		rp->rbr_block_size = bs;
-		rp->rbr_blocks_per_page = PAGE_SIZE / bs;
-	}
+	rp->rbr_block_size = 1 << bss;
+	rp->rbr_blocks_per_page = 1 << (PAGE_SHIFT-bss);
 
 	rp->rbr_sizes[0] = 256;
 	rp->rbr_sizes[1] = 1024;
@@ -7902,12 +7883,7 @@
 {
 	int err = 0;
 
-	BUILD_BUG_ON((PAGE_SIZE < 4 * 1024) ||
-		     ((PAGE_SIZE > 32 * 1024) &&
-		      ((PAGE_SIZE % (32 * 1024)) != 0 &&
-		       (PAGE_SIZE % (16 * 1024)) != 0 &&
-		       (PAGE_SIZE % (8 * 1024)) != 0 &&
-		       (PAGE_SIZE % (4 * 1024)) != 0)));
+	BUILD_BUG_ON(PAGE_SIZE < 4 * 1024);
 
 	niu_debug = netif_msg_init(debug, NIU_MSG_DEFAULT);
 
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 5f994b5..ff92aca 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -282,7 +282,6 @@
 
 	struct net_device	*dev;
 	struct napi_struct	napi;
-	struct net_device_stats	stats;
 	char			tx_full;
 	char			phycount;	/* number of phys found */
 	int			options;
@@ -442,7 +441,9 @@
 
 static void pcnet32_netif_stop(struct net_device *dev)
 {
+#ifdef CONFIG_PCNET32_NAPI
 	struct pcnet32_private *lp = netdev_priv(dev);
+#endif
 	dev->trans_start = jiffies;
 #ifdef CONFIG_PCNET32_NAPI
 	napi_disable(&lp->napi);
@@ -452,7 +453,9 @@
 
 static void pcnet32_netif_start(struct net_device *dev)
 {
+#ifdef CONFIG_PCNET32_NAPI
 	struct pcnet32_private *lp = netdev_priv(dev);
+#endif
 	netif_wake_queue(dev);
 #ifdef CONFIG_PCNET32_NAPI
 	napi_enable(&lp->napi);
@@ -1178,15 +1181,15 @@
 		 * buffers, with only the last correctly noting the error.
 		 */
 		if (status & 0x01)	/* Only count a general error at the */
-			lp->stats.rx_errors++;	/* end of a packet. */
+			dev->stats.rx_errors++;	/* end of a packet. */
 		if (status & 0x20)
-			lp->stats.rx_frame_errors++;
+			dev->stats.rx_frame_errors++;
 		if (status & 0x10)
-			lp->stats.rx_over_errors++;
+			dev->stats.rx_over_errors++;
 		if (status & 0x08)
-			lp->stats.rx_crc_errors++;
+			dev->stats.rx_crc_errors++;
 		if (status & 0x04)
-			lp->stats.rx_fifo_errors++;
+			dev->stats.rx_fifo_errors++;
 		return;
 	}
 
@@ -1197,13 +1200,13 @@
 		if (netif_msg_drv(lp))
 			printk(KERN_ERR "%s: Impossible packet size %d!\n",
 			       dev->name, pkt_len);
-		lp->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		return;
 	}
 	if (pkt_len < 60) {
 		if (netif_msg_rx_err(lp))
 			printk(KERN_ERR "%s: Runt packet!\n", dev->name);
-		lp->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		return;
 	}
 
@@ -1237,7 +1240,7 @@
 			printk(KERN_ERR
 			       "%s: Memory squeeze, dropping packet.\n",
 			       dev->name);
-		lp->stats.rx_dropped++;
+		dev->stats.rx_dropped++;
 		return;
 	}
 	skb->dev = dev;
@@ -1256,7 +1259,7 @@
 					       pkt_len,
 					       PCI_DMA_FROMDEVICE);
 	}
-	lp->stats.rx_bytes += skb->len;
+	dev->stats.rx_bytes += skb->len;
 	skb->protocol = eth_type_trans(skb, dev);
 #ifdef CONFIG_PCNET32_NAPI
 	netif_receive_skb(skb);
@@ -1264,7 +1267,7 @@
 	netif_rx(skb);
 #endif
 	dev->last_rx = jiffies;
-	lp->stats.rx_packets++;
+	dev->stats.rx_packets++;
 	return;
 }
 
@@ -1312,21 +1315,21 @@
 		if (status & 0x4000) {
 			/* There was a major error, log it. */
 			int err_status = le32_to_cpu(lp->tx_ring[entry].misc);
-			lp->stats.tx_errors++;
+			dev->stats.tx_errors++;
 			if (netif_msg_tx_err(lp))
 				printk(KERN_ERR
 				       "%s: Tx error status=%04x err_status=%08x\n",
 				       dev->name, status,
 				       err_status);
 			if (err_status & 0x04000000)
-				lp->stats.tx_aborted_errors++;
+				dev->stats.tx_aborted_errors++;
 			if (err_status & 0x08000000)
-				lp->stats.tx_carrier_errors++;
+				dev->stats.tx_carrier_errors++;
 			if (err_status & 0x10000000)
-				lp->stats.tx_window_errors++;
+				dev->stats.tx_window_errors++;
 #ifndef DO_DXSUFLO
 			if (err_status & 0x40000000) {
-				lp->stats.tx_fifo_errors++;
+				dev->stats.tx_fifo_errors++;
 				/* Ackk!  On FIFO errors the Tx unit is turned off! */
 				/* Remove this verbosity later! */
 				if (netif_msg_tx_err(lp))
@@ -1337,7 +1340,7 @@
 			}
 #else
 			if (err_status & 0x40000000) {
-				lp->stats.tx_fifo_errors++;
+				dev->stats.tx_fifo_errors++;
 				if (!lp->dxsuflo) {	/* If controller doesn't recover ... */
 					/* Ackk!  On FIFO errors the Tx unit is turned off! */
 					/* Remove this verbosity later! */
@@ -1351,8 +1354,8 @@
 #endif
 		} else {
 			if (status & 0x1800)
-				lp->stats.collisions++;
-			lp->stats.tx_packets++;
+				dev->stats.collisions++;
+			dev->stats.tx_packets++;
 		}
 
 		/* We must free the original skb */
@@ -1849,6 +1852,9 @@
 	lp->mii_if.mdio_read = mdio_read;
 	lp->mii_if.mdio_write = mdio_write;
 
+	/* napi.weight is used in both the napi and non-napi cases */
+	lp->napi.weight = lp->rx_ring_size / 2;
+
 #ifdef CONFIG_PCNET32_NAPI
 	netif_napi_add(dev, &lp->napi, pcnet32_poll, lp->rx_ring_size / 2);
 #endif
@@ -2471,7 +2477,7 @@
 		       "%s: transmit timed out, status %4.4x, resetting.\n",
 		       dev->name, lp->a.read_csr(ioaddr, CSR0));
 	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
-	lp->stats.tx_errors++;
+	dev->stats.tx_errors++;
 	if (netif_msg_tx_err(lp)) {
 		int i;
 		printk(KERN_DEBUG
@@ -2541,7 +2547,7 @@
 	lp->tx_ring[entry].status = cpu_to_le16(status);
 
 	lp->cur_tx++;
-	lp->stats.tx_bytes += skb->len;
+	dev->stats.tx_bytes += skb->len;
 
 	/* Trigger an immediate send poll. */
 	lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_TXPOLL);
@@ -2586,7 +2592,7 @@
 
 		/* Log misc errors. */
 		if (csr0 & 0x4000)
-			lp->stats.tx_errors++;	/* Tx babble. */
+			dev->stats.tx_errors++;	/* Tx babble. */
 		if (csr0 & 0x1000) {
 			/*
 			 * This happens when our receive ring is full. This
@@ -2599,7 +2605,7 @@
 			 * don't get a rx interrupt, but a missed frame
 			 * interrupt sooner or later.
 			 */
-			lp->stats.rx_errors++;	/* Missed a Rx frame. */
+			dev->stats.rx_errors++;	/* Missed a Rx frame. */
 		}
 		if (csr0 & 0x0800) {
 			if (netif_msg_drv(lp))
@@ -2661,7 +2667,7 @@
 
 	spin_lock_irqsave(&lp->lock, flags);
 
-	lp->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
+	dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
 
 	if (netif_msg_ifdown(lp))
 		printk(KERN_DEBUG
@@ -2698,10 +2704,10 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&lp->lock, flags);
-	lp->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
+	dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
 	spin_unlock_irqrestore(&lp->lock, flags);
 
-	return &lp->stats;
+	return &dev->stats;
 }
 
 /* taken from the sunlance driver, which it took from the depca driver */
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
index 8cd243d..2747b1f 100644
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -185,3 +185,5 @@
 	module_put(ctrl->ops->owner);
 	kfree(bus);
 }
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
index c0b6d19..bcb0885 100644
--- a/drivers/net/ppp_mppe.c
+++ b/drivers/net/ppp_mppe.c
@@ -55,7 +55,7 @@
 #include <linux/mm.h>
 #include <linux/ppp_defs.h>
 #include <linux/ppp-comp.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 #include "ppp_mppe.h"
 
@@ -68,9 +68,7 @@
 static unsigned int
 setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
 {
-	sg[0].page = virt_to_page(address);
-	sg[0].offset = offset_in_page(address);
-	sg[0].length = length;
+	sg_init_one(sg, address, length);
 	return length;
 }
 
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
index aef66e2..01f08d7 100644
--- a/drivers/net/s2io-regs.h
+++ b/drivers/net/s2io-regs.h
@@ -20,17 +20,17 @@
 
 /* General Control-Status Registers */
 	u64 general_int_status;
-#define GEN_INTR_TXPIC             BIT(0)
-#define GEN_INTR_TXDMA             BIT(1)
-#define GEN_INTR_TXMAC             BIT(2)
-#define GEN_INTR_TXXGXS            BIT(3)
-#define GEN_INTR_TXTRAFFIC         BIT(8)
-#define GEN_INTR_RXPIC             BIT(32)
-#define GEN_INTR_RXDMA             BIT(33)
-#define GEN_INTR_RXMAC             BIT(34)
-#define GEN_INTR_MC                BIT(35)
-#define GEN_INTR_RXXGXS            BIT(36)
-#define GEN_INTR_RXTRAFFIC         BIT(40)
+#define GEN_INTR_TXPIC             s2BIT(0)
+#define GEN_INTR_TXDMA             s2BIT(1)
+#define GEN_INTR_TXMAC             s2BIT(2)
+#define GEN_INTR_TXXGXS            s2BIT(3)
+#define GEN_INTR_TXTRAFFIC         s2BIT(8)
+#define GEN_INTR_RXPIC             s2BIT(32)
+#define GEN_INTR_RXDMA             s2BIT(33)
+#define GEN_INTR_RXMAC             s2BIT(34)
+#define GEN_INTR_MC                s2BIT(35)
+#define GEN_INTR_RXXGXS            s2BIT(36)
+#define GEN_INTR_RXTRAFFIC         s2BIT(40)
 #define GEN_ERROR_INTR             GEN_INTR_TXPIC | GEN_INTR_RXPIC | \
                                    GEN_INTR_TXDMA | GEN_INTR_RXDMA | \
                                    GEN_INTR_TXMAC | GEN_INTR_RXMAC | \
@@ -54,36 +54,36 @@
 
 
 	u64 adapter_status;
-#define ADAPTER_STATUS_TDMA_READY          BIT(0)
-#define ADAPTER_STATUS_RDMA_READY          BIT(1)
-#define ADAPTER_STATUS_PFC_READY           BIT(2)
-#define ADAPTER_STATUS_TMAC_BUF_EMPTY      BIT(3)
-#define ADAPTER_STATUS_PIC_QUIESCENT       BIT(5)
-#define ADAPTER_STATUS_RMAC_REMOTE_FAULT   BIT(6)
-#define ADAPTER_STATUS_RMAC_LOCAL_FAULT    BIT(7)
+#define ADAPTER_STATUS_TDMA_READY          s2BIT(0)
+#define ADAPTER_STATUS_RDMA_READY          s2BIT(1)
+#define ADAPTER_STATUS_PFC_READY           s2BIT(2)
+#define ADAPTER_STATUS_TMAC_BUF_EMPTY      s2BIT(3)
+#define ADAPTER_STATUS_PIC_QUIESCENT       s2BIT(5)
+#define ADAPTER_STATUS_RMAC_REMOTE_FAULT   s2BIT(6)
+#define ADAPTER_STATUS_RMAC_LOCAL_FAULT    s2BIT(7)
 #define ADAPTER_STATUS_RMAC_PCC_IDLE       vBIT(0xFF,8,8)
 #define ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE  vBIT(0x0F,8,8)
 #define ADAPTER_STATUS_RC_PRC_QUIESCENT    vBIT(0xFF,16,8)
-#define ADAPTER_STATUS_MC_DRAM_READY       BIT(24)
-#define ADAPTER_STATUS_MC_QUEUES_READY     BIT(25)
-#define ADAPTER_STATUS_M_PLL_LOCK          BIT(30)
-#define ADAPTER_STATUS_P_PLL_LOCK          BIT(31)
+#define ADAPTER_STATUS_MC_DRAM_READY       s2BIT(24)
+#define ADAPTER_STATUS_MC_QUEUES_READY     s2BIT(25)
+#define ADAPTER_STATUS_M_PLL_LOCK          s2BIT(30)
+#define ADAPTER_STATUS_P_PLL_LOCK          s2BIT(31)
 
 	u64 adapter_control;
-#define ADAPTER_CNTL_EN                    BIT(7)
-#define ADAPTER_EOI_TX_ON                  BIT(15)
-#define ADAPTER_LED_ON                     BIT(23)
+#define ADAPTER_CNTL_EN                    s2BIT(7)
+#define ADAPTER_EOI_TX_ON                  s2BIT(15)
+#define ADAPTER_LED_ON                     s2BIT(23)
 #define ADAPTER_UDPI(val)                  vBIT(val,36,4)
-#define ADAPTER_WAIT_INT                   BIT(48)
-#define ADAPTER_ECC_EN                     BIT(55)
+#define ADAPTER_WAIT_INT                   s2BIT(48)
+#define ADAPTER_ECC_EN                     s2BIT(55)
 
 	u64 serr_source;
-#define SERR_SOURCE_PIC			BIT(0)
-#define SERR_SOURCE_TXDMA		BIT(1)
-#define SERR_SOURCE_RXDMA		BIT(2)
-#define SERR_SOURCE_MAC                 BIT(3)
-#define SERR_SOURCE_MC                  BIT(4)
-#define SERR_SOURCE_XGXS                BIT(5)
+#define SERR_SOURCE_PIC			s2BIT(0)
+#define SERR_SOURCE_TXDMA		s2BIT(1)
+#define SERR_SOURCE_RXDMA		s2BIT(2)
+#define SERR_SOURCE_MAC                 s2BIT(3)
+#define SERR_SOURCE_MC                  s2BIT(4)
+#define SERR_SOURCE_XGXS                s2BIT(5)
 #define	SERR_SOURCE_ANY			(SERR_SOURCE_PIC	| \
 					SERR_SOURCE_TXDMA	| \
 					SERR_SOURCE_RXDMA	| \
@@ -101,41 +101,41 @@
 #define	PCI_MODE_PCIX_M2_66		0x5
 #define	PCI_MODE_PCIX_M2_100		0x6
 #define	PCI_MODE_PCIX_M2_133		0x7
-#define	PCI_MODE_UNSUPPORTED		BIT(0)
-#define	PCI_MODE_32_BITS		BIT(8)
-#define	PCI_MODE_UNKNOWN_MODE		BIT(9)
+#define	PCI_MODE_UNSUPPORTED		s2BIT(0)
+#define	PCI_MODE_32_BITS		s2BIT(8)
+#define	PCI_MODE_UNKNOWN_MODE		s2BIT(9)
 
 	u8 unused_0[0x800 - 0x128];
 
 /* PCI-X Controller registers */
 	u64 pic_int_status;
 	u64 pic_int_mask;
-#define PIC_INT_TX                     BIT(0)
-#define PIC_INT_FLSH                   BIT(1)
-#define PIC_INT_MDIO                   BIT(2)
-#define PIC_INT_IIC                    BIT(3)
-#define PIC_INT_GPIO                   BIT(4)
-#define PIC_INT_RX                     BIT(32)
+#define PIC_INT_TX                     s2BIT(0)
+#define PIC_INT_FLSH                   s2BIT(1)
+#define PIC_INT_MDIO                   s2BIT(2)
+#define PIC_INT_IIC                    s2BIT(3)
+#define PIC_INT_GPIO                   s2BIT(4)
+#define PIC_INT_RX                     s2BIT(32)
 
 	u64 txpic_int_reg;
 	u64 txpic_int_mask;
-#define PCIX_INT_REG_ECC_SG_ERR                BIT(0)
-#define PCIX_INT_REG_ECC_DB_ERR                BIT(1)
-#define PCIX_INT_REG_FLASHR_R_FSM_ERR          BIT(8)
-#define PCIX_INT_REG_FLASHR_W_FSM_ERR          BIT(9)
-#define PCIX_INT_REG_INI_TX_FSM_SERR           BIT(10)
-#define PCIX_INT_REG_INI_TXO_FSM_ERR           BIT(11)
-#define PCIX_INT_REG_TRT_FSM_SERR              BIT(13)
-#define PCIX_INT_REG_SRT_FSM_SERR              BIT(14)
-#define PCIX_INT_REG_PIFR_FSM_SERR             BIT(15)
-#define PCIX_INT_REG_WRC_TX_SEND_FSM_SERR      BIT(21)
-#define PCIX_INT_REG_RRC_TX_REQ_FSM_SERR       BIT(23)
-#define PCIX_INT_REG_INI_RX_FSM_SERR           BIT(48)
-#define PCIX_INT_REG_RA_RX_FSM_SERR            BIT(50)
+#define PCIX_INT_REG_ECC_SG_ERR                s2BIT(0)
+#define PCIX_INT_REG_ECC_DB_ERR                s2BIT(1)
+#define PCIX_INT_REG_FLASHR_R_FSM_ERR          s2BIT(8)
+#define PCIX_INT_REG_FLASHR_W_FSM_ERR          s2BIT(9)
+#define PCIX_INT_REG_INI_TX_FSM_SERR           s2BIT(10)
+#define PCIX_INT_REG_INI_TXO_FSM_ERR           s2BIT(11)
+#define PCIX_INT_REG_TRT_FSM_SERR              s2BIT(13)
+#define PCIX_INT_REG_SRT_FSM_SERR              s2BIT(14)
+#define PCIX_INT_REG_PIFR_FSM_SERR             s2BIT(15)
+#define PCIX_INT_REG_WRC_TX_SEND_FSM_SERR      s2BIT(21)
+#define PCIX_INT_REG_RRC_TX_REQ_FSM_SERR       s2BIT(23)
+#define PCIX_INT_REG_INI_RX_FSM_SERR           s2BIT(48)
+#define PCIX_INT_REG_RA_RX_FSM_SERR            s2BIT(50)
 /*
-#define PCIX_INT_REG_WRC_RX_SEND_FSM_SERR      BIT(52)
-#define PCIX_INT_REG_RRC_RX_REQ_FSM_SERR       BIT(54)
-#define PCIX_INT_REG_RRC_RX_SPLIT_FSM_SERR     BIT(58)
+#define PCIX_INT_REG_WRC_RX_SEND_FSM_SERR      s2BIT(52)
+#define PCIX_INT_REG_RRC_RX_REQ_FSM_SERR       s2BIT(54)
+#define PCIX_INT_REG_RRC_RX_SPLIT_FSM_SERR     s2BIT(58)
 */
 	u64 txpic_alarms;
 	u64 rxpic_int_reg;
@@ -144,92 +144,92 @@
 
 	u64 flsh_int_reg;
 	u64 flsh_int_mask;
-#define PIC_FLSH_INT_REG_CYCLE_FSM_ERR         BIT(63)
-#define PIC_FLSH_INT_REG_ERR                   BIT(62)
+#define PIC_FLSH_INT_REG_CYCLE_FSM_ERR         s2BIT(63)
+#define PIC_FLSH_INT_REG_ERR                   s2BIT(62)
 	u64 flash_alarms;
 
 	u64 mdio_int_reg;
 	u64 mdio_int_mask;
-#define MDIO_INT_REG_MDIO_BUS_ERR              BIT(0)
-#define MDIO_INT_REG_DTX_BUS_ERR               BIT(8)
-#define MDIO_INT_REG_LASI                      BIT(39)
+#define MDIO_INT_REG_MDIO_BUS_ERR              s2BIT(0)
+#define MDIO_INT_REG_DTX_BUS_ERR               s2BIT(8)
+#define MDIO_INT_REG_LASI                      s2BIT(39)
 	u64 mdio_alarms;
 
 	u64 iic_int_reg;
 	u64 iic_int_mask;
-#define IIC_INT_REG_BUS_FSM_ERR                BIT(4)
-#define IIC_INT_REG_BIT_FSM_ERR                BIT(5)
-#define IIC_INT_REG_CYCLE_FSM_ERR              BIT(6)
-#define IIC_INT_REG_REQ_FSM_ERR                BIT(7)
-#define IIC_INT_REG_ACK_ERR                    BIT(8)
+#define IIC_INT_REG_BUS_FSM_ERR                s2BIT(4)
+#define IIC_INT_REG_BIT_FSM_ERR                s2BIT(5)
+#define IIC_INT_REG_CYCLE_FSM_ERR              s2BIT(6)
+#define IIC_INT_REG_REQ_FSM_ERR                s2BIT(7)
+#define IIC_INT_REG_ACK_ERR                    s2BIT(8)
 	u64 iic_alarms;
 
 	u8 unused4[0x08];
 
 	u64 gpio_int_reg;
-#define GPIO_INT_REG_DP_ERR_INT                BIT(0)
-#define GPIO_INT_REG_LINK_DOWN                 BIT(1)
-#define GPIO_INT_REG_LINK_UP                   BIT(2)
+#define GPIO_INT_REG_DP_ERR_INT                s2BIT(0)
+#define GPIO_INT_REG_LINK_DOWN                 s2BIT(1)
+#define GPIO_INT_REG_LINK_UP                   s2BIT(2)
 	u64 gpio_int_mask;
-#define GPIO_INT_MASK_LINK_DOWN                BIT(1)
-#define GPIO_INT_MASK_LINK_UP                  BIT(2)
+#define GPIO_INT_MASK_LINK_DOWN                s2BIT(1)
+#define GPIO_INT_MASK_LINK_UP                  s2BIT(2)
 	u64 gpio_alarms;
 
 	u8 unused5[0x38];
 
 	u64 tx_traffic_int;
-#define TX_TRAFFIC_INT_n(n)                    BIT(n)
+#define TX_TRAFFIC_INT_n(n)                    s2BIT(n)
 	u64 tx_traffic_mask;
 
 	u64 rx_traffic_int;
-#define RX_TRAFFIC_INT_n(n)                    BIT(n)
+#define RX_TRAFFIC_INT_n(n)                    s2BIT(n)
 	u64 rx_traffic_mask;
 
 /* PIC Control registers */
 	u64 pic_control;
-#define PIC_CNTL_RX_ALARM_MAP_1                BIT(0)
+#define PIC_CNTL_RX_ALARM_MAP_1                s2BIT(0)
 #define PIC_CNTL_SHARED_SPLITS(n)              vBIT(n,11,5)
 
 	u64 swapper_ctrl;
-#define SWAPPER_CTRL_PIF_R_FE                  BIT(0)
-#define SWAPPER_CTRL_PIF_R_SE                  BIT(1)
-#define SWAPPER_CTRL_PIF_W_FE                  BIT(8)
-#define SWAPPER_CTRL_PIF_W_SE                  BIT(9)
-#define SWAPPER_CTRL_TXP_FE                    BIT(16)
-#define SWAPPER_CTRL_TXP_SE                    BIT(17)
-#define SWAPPER_CTRL_TXD_R_FE                  BIT(18)
-#define SWAPPER_CTRL_TXD_R_SE                  BIT(19)
-#define SWAPPER_CTRL_TXD_W_FE                  BIT(20)
-#define SWAPPER_CTRL_TXD_W_SE                  BIT(21)
-#define SWAPPER_CTRL_TXF_R_FE                  BIT(22)
-#define SWAPPER_CTRL_TXF_R_SE                  BIT(23)
-#define SWAPPER_CTRL_RXD_R_FE                  BIT(32)
-#define SWAPPER_CTRL_RXD_R_SE                  BIT(33)
-#define SWAPPER_CTRL_RXD_W_FE                  BIT(34)
-#define SWAPPER_CTRL_RXD_W_SE                  BIT(35)
-#define SWAPPER_CTRL_RXF_W_FE                  BIT(36)
-#define SWAPPER_CTRL_RXF_W_SE                  BIT(37)
-#define SWAPPER_CTRL_XMSI_FE                   BIT(40)
-#define SWAPPER_CTRL_XMSI_SE                   BIT(41)
-#define SWAPPER_CTRL_STATS_FE                  BIT(48)
-#define SWAPPER_CTRL_STATS_SE                  BIT(49)
+#define SWAPPER_CTRL_PIF_R_FE                  s2BIT(0)
+#define SWAPPER_CTRL_PIF_R_SE                  s2BIT(1)
+#define SWAPPER_CTRL_PIF_W_FE                  s2BIT(8)
+#define SWAPPER_CTRL_PIF_W_SE                  s2BIT(9)
+#define SWAPPER_CTRL_TXP_FE                    s2BIT(16)
+#define SWAPPER_CTRL_TXP_SE                    s2BIT(17)
+#define SWAPPER_CTRL_TXD_R_FE                  s2BIT(18)
+#define SWAPPER_CTRL_TXD_R_SE                  s2BIT(19)
+#define SWAPPER_CTRL_TXD_W_FE                  s2BIT(20)
+#define SWAPPER_CTRL_TXD_W_SE                  s2BIT(21)
+#define SWAPPER_CTRL_TXF_R_FE                  s2BIT(22)
+#define SWAPPER_CTRL_TXF_R_SE                  s2BIT(23)
+#define SWAPPER_CTRL_RXD_R_FE                  s2BIT(32)
+#define SWAPPER_CTRL_RXD_R_SE                  s2BIT(33)
+#define SWAPPER_CTRL_RXD_W_FE                  s2BIT(34)
+#define SWAPPER_CTRL_RXD_W_SE                  s2BIT(35)
+#define SWAPPER_CTRL_RXF_W_FE                  s2BIT(36)
+#define SWAPPER_CTRL_RXF_W_SE                  s2BIT(37)
+#define SWAPPER_CTRL_XMSI_FE                   s2BIT(40)
+#define SWAPPER_CTRL_XMSI_SE                   s2BIT(41)
+#define SWAPPER_CTRL_STATS_FE                  s2BIT(48)
+#define SWAPPER_CTRL_STATS_SE                  s2BIT(49)
 
 	u64 pif_rd_swapper_fb;
 #define IF_RD_SWAPPER_FB                            0x0123456789ABCDEF
 
 	u64 scheduled_int_ctrl;
-#define SCHED_INT_CTRL_TIMER_EN                BIT(0)
-#define SCHED_INT_CTRL_ONE_SHOT                BIT(1)
+#define SCHED_INT_CTRL_TIMER_EN                s2BIT(0)
+#define SCHED_INT_CTRL_ONE_SHOT                s2BIT(1)
 #define SCHED_INT_CTRL_INT2MSI(val)		vBIT(val,10,6)
 #define SCHED_INT_PERIOD                       TBD
 
 	u64 txreqtimeout;
 #define TXREQTO_VAL(val)						vBIT(val,0,32)
-#define TXREQTO_EN								BIT(63)
+#define TXREQTO_EN								s2BIT(63)
 
 	u64 statsreqtimeout;
 #define STATREQTO_VAL(n)                       TBD
-#define STATREQTO_EN                           BIT(63)
+#define STATREQTO_EN                           s2BIT(63)
 
 	u64 read_retry_delay;
 	u64 read_retry_acceleration;
@@ -255,10 +255,10 @@
 
 	/* Automated statistics collection */
 	u64 stat_cfg;
-#define STAT_CFG_STAT_EN           BIT(0)
-#define STAT_CFG_ONE_SHOT_EN       BIT(1)
-#define STAT_CFG_STAT_NS_EN        BIT(8)
-#define STAT_CFG_STAT_RO           BIT(9)
+#define STAT_CFG_STAT_EN           s2BIT(0)
+#define STAT_CFG_ONE_SHOT_EN       s2BIT(1)
+#define STAT_CFG_STAT_NS_EN        s2BIT(8)
+#define STAT_CFG_STAT_RO           s2BIT(9)
 #define STAT_TRSF_PER(n)           TBD
 #define	PER_SEC					   0x208d5
 #define	SET_UPDT_PERIOD(n)		   vBIT((PER_SEC*n),32,32)
@@ -290,18 +290,18 @@
 #define	I2C_CONTROL_DEV_ID(id)		vBIT(id,1,3)
 #define	I2C_CONTROL_ADDR(addr)		vBIT(addr,5,11)
 #define	I2C_CONTROL_BYTE_CNT(cnt)	vBIT(cnt,22,2)
-#define	I2C_CONTROL_READ			BIT(24)
-#define	I2C_CONTROL_NACK			BIT(25)
+#define	I2C_CONTROL_READ			s2BIT(24)
+#define	I2C_CONTROL_NACK			s2BIT(25)
 #define	I2C_CONTROL_CNTL_START		vBIT(0xE,28,4)
 #define	I2C_CONTROL_CNTL_END(val)	(val & vBIT(0x1,28,4))
 #define	I2C_CONTROL_GET_DATA(val)	(u32)(val & 0xFFFFFFFF)
 #define	I2C_CONTROL_SET_DATA(val)	vBIT(val,32,32)
 
 	u64 gpio_control;
-#define GPIO_CTRL_GPIO_0		BIT(8)
+#define GPIO_CTRL_GPIO_0		s2BIT(8)
 	u64 misc_control;
-#define FAULT_BEHAVIOUR			BIT(0)
-#define EXT_REQ_EN			BIT(1)
+#define FAULT_BEHAVIOUR			s2BIT(0)
+#define EXT_REQ_EN			s2BIT(1)
 #define MISC_LINK_STABILITY_PRD(val)   vBIT(val,29,3)
 
 	u8 unused7_1[0x230 - 0x208];
@@ -317,29 +317,29 @@
 /* TxDMA registers */
 	u64 txdma_int_status;
 	u64 txdma_int_mask;
-#define TXDMA_PFC_INT                  BIT(0)
-#define TXDMA_TDA_INT                  BIT(1)
-#define TXDMA_PCC_INT                  BIT(2)
-#define TXDMA_TTI_INT                  BIT(3)
-#define TXDMA_LSO_INT                  BIT(4)
-#define TXDMA_TPA_INT                  BIT(5)
-#define TXDMA_SM_INT                   BIT(6)
+#define TXDMA_PFC_INT                  s2BIT(0)
+#define TXDMA_TDA_INT                  s2BIT(1)
+#define TXDMA_PCC_INT                  s2BIT(2)
+#define TXDMA_TTI_INT                  s2BIT(3)
+#define TXDMA_LSO_INT                  s2BIT(4)
+#define TXDMA_TPA_INT                  s2BIT(5)
+#define TXDMA_SM_INT                   s2BIT(6)
 	u64 pfc_err_reg;
-#define PFC_ECC_SG_ERR			BIT(7)
-#define PFC_ECC_DB_ERR			BIT(15)
-#define PFC_SM_ERR_ALARM		BIT(23)
-#define PFC_MISC_0_ERR			BIT(31)
-#define PFC_MISC_1_ERR			BIT(32)
-#define PFC_PCIX_ERR			BIT(39)
+#define PFC_ECC_SG_ERR			s2BIT(7)
+#define PFC_ECC_DB_ERR			s2BIT(15)
+#define PFC_SM_ERR_ALARM		s2BIT(23)
+#define PFC_MISC_0_ERR			s2BIT(31)
+#define PFC_MISC_1_ERR			s2BIT(32)
+#define PFC_PCIX_ERR			s2BIT(39)
 	u64 pfc_err_mask;
 	u64 pfc_err_alarm;
 
 	u64 tda_err_reg;
 #define TDA_Fn_ECC_SG_ERR		vBIT(0xff,0,8)
 #define TDA_Fn_ECC_DB_ERR		vBIT(0xff,8,8)
-#define TDA_SM0_ERR_ALARM		BIT(22)
-#define TDA_SM1_ERR_ALARM		BIT(23)
-#define TDA_PCIX_ERR			BIT(39)
+#define TDA_SM0_ERR_ALARM		s2BIT(22)
+#define TDA_SM1_ERR_ALARM		s2BIT(23)
+#define TDA_PCIX_ERR			s2BIT(39)
 	u64 tda_err_mask;
 	u64 tda_err_alarm;
 
@@ -351,40 +351,40 @@
 #define PCC_SM_ERR_ALARM		vBIT(0xff,32,8)
 #define PCC_WR_ERR_ALARM		vBIT(0xff,40,8)
 #define PCC_N_SERR			vBIT(0xff,48,8)
-#define PCC_6_COF_OV_ERR		BIT(56)
-#define PCC_7_COF_OV_ERR		BIT(57)
-#define PCC_6_LSO_OV_ERR		BIT(58)
-#define PCC_7_LSO_OV_ERR		BIT(59)
+#define PCC_6_COF_OV_ERR		s2BIT(56)
+#define PCC_7_COF_OV_ERR		s2BIT(57)
+#define PCC_6_LSO_OV_ERR		s2BIT(58)
+#define PCC_7_LSO_OV_ERR		s2BIT(59)
 #define PCC_ENABLE_FOUR			vBIT(0x0F,0,8)
 	u64 pcc_err_mask;
 	u64 pcc_err_alarm;
 
 	u64 tti_err_reg;
-#define TTI_ECC_SG_ERR			BIT(7)
-#define TTI_ECC_DB_ERR			BIT(15)
-#define TTI_SM_ERR_ALARM		BIT(23)
+#define TTI_ECC_SG_ERR			s2BIT(7)
+#define TTI_ECC_DB_ERR			s2BIT(15)
+#define TTI_SM_ERR_ALARM		s2BIT(23)
 	u64 tti_err_mask;
 	u64 tti_err_alarm;
 
 	u64 lso_err_reg;
-#define LSO6_SEND_OFLOW			BIT(12)
-#define LSO7_SEND_OFLOW			BIT(13)
-#define LSO6_ABORT			BIT(14)
-#define LSO7_ABORT			BIT(15)
-#define LSO6_SM_ERR_ALARM		BIT(22)
-#define LSO7_SM_ERR_ALARM		BIT(23)
+#define LSO6_SEND_OFLOW			s2BIT(12)
+#define LSO7_SEND_OFLOW			s2BIT(13)
+#define LSO6_ABORT			s2BIT(14)
+#define LSO7_ABORT			s2BIT(15)
+#define LSO6_SM_ERR_ALARM		s2BIT(22)
+#define LSO7_SM_ERR_ALARM		s2BIT(23)
 	u64 lso_err_mask;
 	u64 lso_err_alarm;
 
 	u64 tpa_err_reg;
-#define TPA_TX_FRM_DROP			BIT(7)
-#define TPA_SM_ERR_ALARM		BIT(23)
+#define TPA_TX_FRM_DROP			s2BIT(7)
+#define TPA_SM_ERR_ALARM		s2BIT(23)
 
 	u64 tpa_err_mask;
 	u64 tpa_err_alarm;
 
 	u64 sm_err_reg;
-#define SM_SM_ERR_ALARM			BIT(15)
+#define SM_SM_ERR_ALARM			s2BIT(15)
 	u64 sm_err_mask;
 	u64 sm_err_alarm;
 
@@ -397,7 +397,7 @@
 #define X_MAX_FIFOS                        8
 #define X_FIFO_MAX_LEN                     0x1FFF	/*8191 */
 	u64 tx_fifo_partition_0;
-#define TX_FIFO_PARTITION_EN               BIT(0)
+#define TX_FIFO_PARTITION_EN               s2BIT(0)
 #define TX_FIFO_PARTITION_0_PRI(val)       vBIT(val,5,3)
 #define TX_FIFO_PARTITION_0_LEN(val)       vBIT(val,19,13)
 #define TX_FIFO_PARTITION_1_PRI(val)       vBIT(val,37,3)
@@ -437,16 +437,16 @@
 	u64 tx_w_round_robin_4;
 
 	u64 tti_command_mem;
-#define TTI_CMD_MEM_WE                     BIT(7)
-#define TTI_CMD_MEM_STROBE_NEW_CMD         BIT(15)
-#define TTI_CMD_MEM_STROBE_BEING_EXECUTED  BIT(15)
+#define TTI_CMD_MEM_WE                     s2BIT(7)
+#define TTI_CMD_MEM_STROBE_NEW_CMD         s2BIT(15)
+#define TTI_CMD_MEM_STROBE_BEING_EXECUTED  s2BIT(15)
 #define TTI_CMD_MEM_OFFSET(n)              vBIT(n,26,6)
 
 	u64 tti_data1_mem;
 #define TTI_DATA1_MEM_TX_TIMER_VAL(n)      vBIT(n,6,26)
 #define TTI_DATA1_MEM_TX_TIMER_AC_CI(n)    vBIT(n,38,2)
-#define TTI_DATA1_MEM_TX_TIMER_AC_EN       BIT(38)
-#define TTI_DATA1_MEM_TX_TIMER_CI_EN       BIT(39)
+#define TTI_DATA1_MEM_TX_TIMER_AC_EN       s2BIT(38)
+#define TTI_DATA1_MEM_TX_TIMER_CI_EN       s2BIT(39)
 #define TTI_DATA1_MEM_TX_URNG_A(n)         vBIT(n,41,7)
 #define TTI_DATA1_MEM_TX_URNG_B(n)         vBIT(n,49,7)
 #define TTI_DATA1_MEM_TX_URNG_C(n)         vBIT(n,57,7)
@@ -459,11 +459,11 @@
 
 /* Tx Protocol assist */
 	u64 tx_pa_cfg;
-#define TX_PA_CFG_IGNORE_FRM_ERR           BIT(1)
-#define TX_PA_CFG_IGNORE_SNAP_OUI          BIT(2)
-#define TX_PA_CFG_IGNORE_LLC_CTRL          BIT(3)
-#define	TX_PA_CFG_IGNORE_L2_ERR			   BIT(6)
-#define RX_PA_CFG_STRIP_VLAN_TAG		BIT(15)
+#define TX_PA_CFG_IGNORE_FRM_ERR           s2BIT(1)
+#define TX_PA_CFG_IGNORE_SNAP_OUI          s2BIT(2)
+#define TX_PA_CFG_IGNORE_LLC_CTRL          s2BIT(3)
+#define	TX_PA_CFG_IGNORE_L2_ERR			   s2BIT(6)
+#define RX_PA_CFG_STRIP_VLAN_TAG		s2BIT(15)
 
 /* Recent add, used only debug purposes. */
 	u64 pcc_enable;
@@ -477,31 +477,31 @@
 /* RxDMA Registers */
 	u64 rxdma_int_status;
 	u64 rxdma_int_mask;
-#define RXDMA_INT_RC_INT_M             BIT(0)
-#define RXDMA_INT_RPA_INT_M            BIT(1)
-#define RXDMA_INT_RDA_INT_M            BIT(2)
-#define RXDMA_INT_RTI_INT_M            BIT(3)
+#define RXDMA_INT_RC_INT_M             s2BIT(0)
+#define RXDMA_INT_RPA_INT_M            s2BIT(1)
+#define RXDMA_INT_RDA_INT_M            s2BIT(2)
+#define RXDMA_INT_RTI_INT_M            s2BIT(3)
 
 	u64 rda_err_reg;
 #define RDA_RXDn_ECC_SG_ERR		vBIT(0xFF,0,8)
 #define RDA_RXDn_ECC_DB_ERR		vBIT(0xFF,8,8)
-#define RDA_FRM_ECC_SG_ERR		BIT(23)
-#define RDA_FRM_ECC_DB_N_AERR		BIT(31)
-#define RDA_SM1_ERR_ALARM		BIT(38)
-#define RDA_SM0_ERR_ALARM		BIT(39)
-#define RDA_MISC_ERR			BIT(47)
-#define RDA_PCIX_ERR			BIT(55)
-#define RDA_RXD_ECC_DB_SERR		BIT(63)
+#define RDA_FRM_ECC_SG_ERR		s2BIT(23)
+#define RDA_FRM_ECC_DB_N_AERR		s2BIT(31)
+#define RDA_SM1_ERR_ALARM		s2BIT(38)
+#define RDA_SM0_ERR_ALARM		s2BIT(39)
+#define RDA_MISC_ERR			s2BIT(47)
+#define RDA_PCIX_ERR			s2BIT(55)
+#define RDA_RXD_ECC_DB_SERR		s2BIT(63)
 	u64 rda_err_mask;
 	u64 rda_err_alarm;
 
 	u64 rc_err_reg;
 #define RC_PRCn_ECC_SG_ERR		vBIT(0xFF,0,8)
 #define RC_PRCn_ECC_DB_ERR		vBIT(0xFF,8,8)
-#define RC_FTC_ECC_SG_ERR		BIT(23)
-#define RC_FTC_ECC_DB_ERR		BIT(31)
+#define RC_FTC_ECC_SG_ERR		s2BIT(23)
+#define RC_FTC_ECC_DB_ERR		s2BIT(31)
 #define RC_PRCn_SM_ERR_ALARM		vBIT(0xFF,32,8)
-#define RC_FTC_SM_ERR_ALARM		BIT(47)
+#define RC_FTC_SM_ERR_ALARM		s2BIT(47)
 #define RC_RDA_FAIL_WR_Rn		vBIT(0xFF,48,8)
 	u64 rc_err_mask;
 	u64 rc_err_alarm;
@@ -517,18 +517,18 @@
 	u64 prc_pcix_err_alarm;
 
 	u64 rpa_err_reg;
-#define RPA_ECC_SG_ERR			BIT(7)
-#define RPA_ECC_DB_ERR			BIT(15)
-#define RPA_FLUSH_REQUEST		BIT(22)
-#define RPA_SM_ERR_ALARM		BIT(23)
-#define RPA_CREDIT_ERR			BIT(31)
+#define RPA_ECC_SG_ERR			s2BIT(7)
+#define RPA_ECC_DB_ERR			s2BIT(15)
+#define RPA_FLUSH_REQUEST		s2BIT(22)
+#define RPA_SM_ERR_ALARM		s2BIT(23)
+#define RPA_CREDIT_ERR			s2BIT(31)
 	u64 rpa_err_mask;
 	u64 rpa_err_alarm;
 
 	u64 rti_err_reg;
-#define RTI_ECC_SG_ERR			BIT(7)
-#define RTI_ECC_DB_ERR			BIT(15)
-#define RTI_SM_ERR_ALARM		BIT(23)
+#define RTI_ECC_SG_ERR			s2BIT(7)
+#define RTI_ECC_DB_ERR			s2BIT(15)
+#define RTI_SM_ERR_ALARM		s2BIT(23)
 	u64 rti_err_mask;
 	u64 rti_err_alarm;
 
@@ -568,49 +568,49 @@
 #endif
 	u64 prc_rxd0_n[RX_MAX_RINGS];
 	u64 prc_ctrl_n[RX_MAX_RINGS];
-#define PRC_CTRL_RC_ENABLED                    BIT(7)
-#define PRC_CTRL_RING_MODE                     (BIT(14)|BIT(15))
+#define PRC_CTRL_RC_ENABLED                    s2BIT(7)
+#define PRC_CTRL_RING_MODE                     (s2BIT(14)|s2BIT(15))
 #define PRC_CTRL_RING_MODE_1                   vBIT(0,14,2)
 #define PRC_CTRL_RING_MODE_3                   vBIT(1,14,2)
 #define PRC_CTRL_RING_MODE_5                   vBIT(2,14,2)
 #define PRC_CTRL_RING_MODE_x                   vBIT(3,14,2)
-#define PRC_CTRL_NO_SNOOP                      (BIT(22)|BIT(23))
-#define PRC_CTRL_NO_SNOOP_DESC                 BIT(22)
-#define PRC_CTRL_NO_SNOOP_BUFF                 BIT(23)
-#define PRC_CTRL_BIMODAL_INTERRUPT             BIT(37)
-#define PRC_CTRL_GROUP_READS                   BIT(38)
+#define PRC_CTRL_NO_SNOOP                      (s2BIT(22)|s2BIT(23))
+#define PRC_CTRL_NO_SNOOP_DESC                 s2BIT(22)
+#define PRC_CTRL_NO_SNOOP_BUFF                 s2BIT(23)
+#define PRC_CTRL_BIMODAL_INTERRUPT             s2BIT(37)
+#define PRC_CTRL_GROUP_READS                   s2BIT(38)
 #define PRC_CTRL_RXD_BACKOFF_INTERVAL(val)     vBIT(val,40,24)
 
 	u64 prc_alarm_action;
-#define PRC_ALARM_ACTION_RR_R0_STOP            BIT(3)
-#define PRC_ALARM_ACTION_RW_R0_STOP            BIT(7)
-#define PRC_ALARM_ACTION_RR_R1_STOP            BIT(11)
-#define PRC_ALARM_ACTION_RW_R1_STOP            BIT(15)
-#define PRC_ALARM_ACTION_RR_R2_STOP            BIT(19)
-#define PRC_ALARM_ACTION_RW_R2_STOP            BIT(23)
-#define PRC_ALARM_ACTION_RR_R3_STOP            BIT(27)
-#define PRC_ALARM_ACTION_RW_R3_STOP            BIT(31)
-#define PRC_ALARM_ACTION_RR_R4_STOP            BIT(35)
-#define PRC_ALARM_ACTION_RW_R4_STOP            BIT(39)
-#define PRC_ALARM_ACTION_RR_R5_STOP            BIT(43)
-#define PRC_ALARM_ACTION_RW_R5_STOP            BIT(47)
-#define PRC_ALARM_ACTION_RR_R6_STOP            BIT(51)
-#define PRC_ALARM_ACTION_RW_R6_STOP            BIT(55)
-#define PRC_ALARM_ACTION_RR_R7_STOP            BIT(59)
-#define PRC_ALARM_ACTION_RW_R7_STOP            BIT(63)
+#define PRC_ALARM_ACTION_RR_R0_STOP            s2BIT(3)
+#define PRC_ALARM_ACTION_RW_R0_STOP            s2BIT(7)
+#define PRC_ALARM_ACTION_RR_R1_STOP            s2BIT(11)
+#define PRC_ALARM_ACTION_RW_R1_STOP            s2BIT(15)
+#define PRC_ALARM_ACTION_RR_R2_STOP            s2BIT(19)
+#define PRC_ALARM_ACTION_RW_R2_STOP            s2BIT(23)
+#define PRC_ALARM_ACTION_RR_R3_STOP            s2BIT(27)
+#define PRC_ALARM_ACTION_RW_R3_STOP            s2BIT(31)
+#define PRC_ALARM_ACTION_RR_R4_STOP            s2BIT(35)
+#define PRC_ALARM_ACTION_RW_R4_STOP            s2BIT(39)
+#define PRC_ALARM_ACTION_RR_R5_STOP            s2BIT(43)
+#define PRC_ALARM_ACTION_RW_R5_STOP            s2BIT(47)
+#define PRC_ALARM_ACTION_RR_R6_STOP            s2BIT(51)
+#define PRC_ALARM_ACTION_RW_R6_STOP            s2BIT(55)
+#define PRC_ALARM_ACTION_RR_R7_STOP            s2BIT(59)
+#define PRC_ALARM_ACTION_RW_R7_STOP            s2BIT(63)
 
 /* Receive traffic interrupts */
 	u64 rti_command_mem;
-#define RTI_CMD_MEM_WE                          BIT(7)
-#define RTI_CMD_MEM_STROBE                      BIT(15)
-#define RTI_CMD_MEM_STROBE_NEW_CMD              BIT(15)
-#define RTI_CMD_MEM_STROBE_CMD_BEING_EXECUTED   BIT(15)
+#define RTI_CMD_MEM_WE                          s2BIT(7)
+#define RTI_CMD_MEM_STROBE                      s2BIT(15)
+#define RTI_CMD_MEM_STROBE_NEW_CMD              s2BIT(15)
+#define RTI_CMD_MEM_STROBE_CMD_BEING_EXECUTED   s2BIT(15)
 #define RTI_CMD_MEM_OFFSET(n)                   vBIT(n,29,3)
 
 	u64 rti_data1_mem;
 #define RTI_DATA1_MEM_RX_TIMER_VAL(n)      vBIT(n,3,29)
-#define RTI_DATA1_MEM_RX_TIMER_AC_EN       BIT(38)
-#define RTI_DATA1_MEM_RX_TIMER_CI_EN       BIT(39)
+#define RTI_DATA1_MEM_RX_TIMER_AC_EN       s2BIT(38)
+#define RTI_DATA1_MEM_RX_TIMER_CI_EN       s2BIT(39)
 #define RTI_DATA1_MEM_RX_URNG_A(n)         vBIT(n,41,7)
 #define RTI_DATA1_MEM_RX_URNG_B(n)         vBIT(n,49,7)
 #define RTI_DATA1_MEM_RX_URNG_C(n)         vBIT(n,57,7)
@@ -622,10 +622,10 @@
 #define RTI_DATA2_MEM_RX_UFC_D(n)          vBIT(n,48,16)
 
 	u64 rx_pa_cfg;
-#define RX_PA_CFG_IGNORE_FRM_ERR           BIT(1)
-#define RX_PA_CFG_IGNORE_SNAP_OUI          BIT(2)
-#define RX_PA_CFG_IGNORE_LLC_CTRL          BIT(3)
-#define RX_PA_CFG_IGNORE_L2_ERR            BIT(6)
+#define RX_PA_CFG_IGNORE_FRM_ERR           s2BIT(1)
+#define RX_PA_CFG_IGNORE_SNAP_OUI          s2BIT(2)
+#define RX_PA_CFG_IGNORE_LLC_CTRL          s2BIT(3)
+#define RX_PA_CFG_IGNORE_L2_ERR            s2BIT(6)
 
 	u64 unused_11_1;
 
@@ -641,64 +641,64 @@
 /* Media Access Controller Register */
 	u64 mac_int_status;
 	u64 mac_int_mask;
-#define MAC_INT_STATUS_TMAC_INT            BIT(0)
-#define MAC_INT_STATUS_RMAC_INT            BIT(1)
+#define MAC_INT_STATUS_TMAC_INT            s2BIT(0)
+#define MAC_INT_STATUS_RMAC_INT            s2BIT(1)
 
 	u64 mac_tmac_err_reg;
-#define TMAC_ECC_SG_ERR				BIT(7)
-#define TMAC_ECC_DB_ERR				BIT(15)
-#define TMAC_TX_BUF_OVRN			BIT(23)
-#define TMAC_TX_CRI_ERR				BIT(31)
-#define TMAC_TX_SM_ERR				BIT(39)
-#define TMAC_DESC_ECC_SG_ERR			BIT(47)
-#define TMAC_DESC_ECC_DB_ERR			BIT(55)
+#define TMAC_ECC_SG_ERR				s2BIT(7)
+#define TMAC_ECC_DB_ERR				s2BIT(15)
+#define TMAC_TX_BUF_OVRN			s2BIT(23)
+#define TMAC_TX_CRI_ERR				s2BIT(31)
+#define TMAC_TX_SM_ERR				s2BIT(39)
+#define TMAC_DESC_ECC_SG_ERR			s2BIT(47)
+#define TMAC_DESC_ECC_DB_ERR			s2BIT(55)
 
 	u64 mac_tmac_err_mask;
 	u64 mac_tmac_err_alarm;
 
 	u64 mac_rmac_err_reg;
-#define RMAC_RX_BUFF_OVRN			BIT(0)
-#define RMAC_FRM_RCVD_INT			BIT(1)
-#define RMAC_UNUSED_INT				BIT(2)
-#define RMAC_RTS_PNUM_ECC_SG_ERR		BIT(5)
-#define RMAC_RTS_DS_ECC_SG_ERR			BIT(6)
-#define RMAC_RD_BUF_ECC_SG_ERR			BIT(7)
-#define RMAC_RTH_MAP_ECC_SG_ERR			BIT(8)
-#define RMAC_RTH_SPDM_ECC_SG_ERR		BIT(9)
-#define RMAC_RTS_VID_ECC_SG_ERR			BIT(10)
-#define RMAC_DA_SHADOW_ECC_SG_ERR		BIT(11)
-#define RMAC_RTS_PNUM_ECC_DB_ERR		BIT(13)
-#define RMAC_RTS_DS_ECC_DB_ERR			BIT(14)
-#define RMAC_RD_BUF_ECC_DB_ERR			BIT(15)
-#define RMAC_RTH_MAP_ECC_DB_ERR			BIT(16)
-#define RMAC_RTH_SPDM_ECC_DB_ERR		BIT(17)
-#define RMAC_RTS_VID_ECC_DB_ERR			BIT(18)
-#define RMAC_DA_SHADOW_ECC_DB_ERR		BIT(19)
-#define RMAC_LINK_STATE_CHANGE_INT		BIT(31)
-#define RMAC_RX_SM_ERR				BIT(39)
-#define RMAC_SINGLE_ECC_ERR			(BIT(5) | BIT(6) | BIT(7) |\
-						BIT(8)  | BIT(9) | BIT(10)|\
-						BIT(11))
-#define RMAC_DOUBLE_ECC_ERR			(BIT(13) | BIT(14) | BIT(15) |\
-						BIT(16)  | BIT(17) | BIT(18)|\
-						BIT(19))
+#define RMAC_RX_BUFF_OVRN			s2BIT(0)
+#define RMAC_FRM_RCVD_INT			s2BIT(1)
+#define RMAC_UNUSED_INT				s2BIT(2)
+#define RMAC_RTS_PNUM_ECC_SG_ERR		s2BIT(5)
+#define RMAC_RTS_DS_ECC_SG_ERR			s2BIT(6)
+#define RMAC_RD_BUF_ECC_SG_ERR			s2BIT(7)
+#define RMAC_RTH_MAP_ECC_SG_ERR			s2BIT(8)
+#define RMAC_RTH_SPDM_ECC_SG_ERR		s2BIT(9)
+#define RMAC_RTS_VID_ECC_SG_ERR			s2BIT(10)
+#define RMAC_DA_SHADOW_ECC_SG_ERR		s2BIT(11)
+#define RMAC_RTS_PNUM_ECC_DB_ERR		s2BIT(13)
+#define RMAC_RTS_DS_ECC_DB_ERR			s2BIT(14)
+#define RMAC_RD_BUF_ECC_DB_ERR			s2BIT(15)
+#define RMAC_RTH_MAP_ECC_DB_ERR			s2BIT(16)
+#define RMAC_RTH_SPDM_ECC_DB_ERR		s2BIT(17)
+#define RMAC_RTS_VID_ECC_DB_ERR			s2BIT(18)
+#define RMAC_DA_SHADOW_ECC_DB_ERR		s2BIT(19)
+#define RMAC_LINK_STATE_CHANGE_INT		s2BIT(31)
+#define RMAC_RX_SM_ERR				s2BIT(39)
+#define RMAC_SINGLE_ECC_ERR			(s2BIT(5) | s2BIT(6) | s2BIT(7) |\
+						s2BIT(8)  | s2BIT(9) | s2BIT(10)|\
+						s2BIT(11))
+#define RMAC_DOUBLE_ECC_ERR			(s2BIT(13) | s2BIT(14) | s2BIT(15) |\
+						s2BIT(16)  | s2BIT(17) | s2BIT(18)|\
+						s2BIT(19))
 	u64 mac_rmac_err_mask;
 	u64 mac_rmac_err_alarm;
 
 	u8 unused14[0x100 - 0x40];
 
 	u64 mac_cfg;
-#define MAC_CFG_TMAC_ENABLE             BIT(0)
-#define MAC_CFG_RMAC_ENABLE             BIT(1)
-#define MAC_CFG_LAN_NOT_WAN             BIT(2)
-#define MAC_CFG_TMAC_LOOPBACK           BIT(3)
-#define MAC_CFG_TMAC_APPEND_PAD         BIT(4)
-#define MAC_CFG_RMAC_STRIP_FCS          BIT(5)
-#define MAC_CFG_RMAC_STRIP_PAD          BIT(6)
-#define MAC_CFG_RMAC_PROM_ENABLE        BIT(7)
-#define MAC_RMAC_DISCARD_PFRM           BIT(8)
-#define MAC_RMAC_BCAST_ENABLE           BIT(9)
-#define MAC_RMAC_ALL_ADDR_ENABLE        BIT(10)
+#define MAC_CFG_TMAC_ENABLE             s2BIT(0)
+#define MAC_CFG_RMAC_ENABLE             s2BIT(1)
+#define MAC_CFG_LAN_NOT_WAN             s2BIT(2)
+#define MAC_CFG_TMAC_LOOPBACK           s2BIT(3)
+#define MAC_CFG_TMAC_APPEND_PAD         s2BIT(4)
+#define MAC_CFG_RMAC_STRIP_FCS          s2BIT(5)
+#define MAC_CFG_RMAC_STRIP_PAD          s2BIT(6)
+#define MAC_CFG_RMAC_PROM_ENABLE        s2BIT(7)
+#define MAC_RMAC_DISCARD_PFRM           s2BIT(8)
+#define MAC_RMAC_BCAST_ENABLE           s2BIT(9)
+#define MAC_RMAC_ALL_ADDR_ENABLE        s2BIT(10)
 #define MAC_RMAC_INVLD_IPG_THR(val)     vBIT(val,16,8)
 
 	u64 tmac_avg_ipg;
@@ -710,14 +710,14 @@
 #define RMAC_MAX_PYLD_LEN_JUMBO_DEF vBIT(9600,2,14)
 
 	u64 rmac_err_cfg;
-#define RMAC_ERR_FCS                    BIT(0)
-#define RMAC_ERR_FCS_ACCEPT             BIT(1)
-#define RMAC_ERR_TOO_LONG               BIT(1)
-#define RMAC_ERR_TOO_LONG_ACCEPT        BIT(1)
-#define RMAC_ERR_RUNT                   BIT(2)
-#define RMAC_ERR_RUNT_ACCEPT            BIT(2)
-#define RMAC_ERR_LEN_MISMATCH           BIT(3)
-#define RMAC_ERR_LEN_MISMATCH_ACCEPT    BIT(3)
+#define RMAC_ERR_FCS                    s2BIT(0)
+#define RMAC_ERR_FCS_ACCEPT             s2BIT(1)
+#define RMAC_ERR_TOO_LONG               s2BIT(1)
+#define RMAC_ERR_TOO_LONG_ACCEPT        s2BIT(1)
+#define RMAC_ERR_RUNT                   s2BIT(2)
+#define RMAC_ERR_RUNT_ACCEPT            s2BIT(2)
+#define RMAC_ERR_LEN_MISMATCH           s2BIT(3)
+#define RMAC_ERR_LEN_MISMATCH_ACCEPT    s2BIT(3)
 
 	u64 rmac_cfg_key;
 #define RMAC_CFG_KEY(val)               vBIT(val,0,16)
@@ -728,15 +728,15 @@
 #define MAC_MC_ADDR_START_OFFSET    16
 #define MAC_MC_ALL_MC_ADDR_OFFSET   63	/* enables all multicast pkts */
 	u64 rmac_addr_cmd_mem;
-#define RMAC_ADDR_CMD_MEM_WE                    BIT(7)
+#define RMAC_ADDR_CMD_MEM_WE                    s2BIT(7)
 #define RMAC_ADDR_CMD_MEM_RD                    0
-#define RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD        BIT(15)
-#define RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING  BIT(15)
+#define RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD        s2BIT(15)
+#define RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING  s2BIT(15)
 #define RMAC_ADDR_CMD_MEM_OFFSET(n)             vBIT(n,26,6)
 
 	u64 rmac_addr_data0_mem;
 #define RMAC_ADDR_DATA0_MEM_ADDR(n)    vBIT(n,0,48)
-#define RMAC_ADDR_DATA0_MEM_USER       BIT(48)
+#define RMAC_ADDR_DATA0_MEM_USER       s2BIT(48)
 
 	u64 rmac_addr_data1_mem;
 #define RMAC_ADDR_DATA1_MEM_MASK(n)    vBIT(n,0,48)
@@ -753,10 +753,10 @@
 	u64 tmac_ipg_cfg;
 
 	u64 rmac_pause_cfg;
-#define RMAC_PAUSE_GEN             BIT(0)
-#define RMAC_PAUSE_GEN_ENABLE      BIT(0)
-#define RMAC_PAUSE_RX              BIT(1)
-#define RMAC_PAUSE_RX_ENABLE       BIT(1)
+#define RMAC_PAUSE_GEN             s2BIT(0)
+#define RMAC_PAUSE_GEN_ENABLE      s2BIT(0)
+#define RMAC_PAUSE_RX              s2BIT(1)
+#define RMAC_PAUSE_RX_ENABLE       s2BIT(1)
 #define RMAC_PAUSE_HG_PTIME_DEF    vBIT(0xFFFF,16,16)
 #define RMAC_PAUSE_HG_PTIME(val)    vBIT(val,16,16)
 
@@ -787,29 +787,29 @@
 #define MAX_DIX_MAP                         4
 	u64 rts_dix_map_n[MAX_DIX_MAP];
 #define RTS_DIX_MAP_ETYPE(val)             vBIT(val,0,16)
-#define RTS_DIX_MAP_SCW(val)               BIT(val,21)
+#define RTS_DIX_MAP_SCW(val)               s2BIT(val,21)
 
 	u64 rts_q_alternates;
 	u64 rts_default_q;
 
 	u64 rts_ctrl;
-#define RTS_CTRL_IGNORE_SNAP_OUI           BIT(2)
-#define RTS_CTRL_IGNORE_LLC_CTRL           BIT(3)
+#define RTS_CTRL_IGNORE_SNAP_OUI           s2BIT(2)
+#define RTS_CTRL_IGNORE_LLC_CTRL           s2BIT(3)
 
 	u64 rts_pn_cam_ctrl;
-#define RTS_PN_CAM_CTRL_WE                 BIT(7)
-#define RTS_PN_CAM_CTRL_STROBE_NEW_CMD     BIT(15)
-#define RTS_PN_CAM_CTRL_STROBE_BEING_EXECUTED   BIT(15)
+#define RTS_PN_CAM_CTRL_WE                 s2BIT(7)
+#define RTS_PN_CAM_CTRL_STROBE_NEW_CMD     s2BIT(15)
+#define RTS_PN_CAM_CTRL_STROBE_BEING_EXECUTED   s2BIT(15)
 #define RTS_PN_CAM_CTRL_OFFSET(n)          vBIT(n,24,8)
 	u64 rts_pn_cam_data;
-#define RTS_PN_CAM_DATA_TCP_SELECT         BIT(7)
+#define RTS_PN_CAM_DATA_TCP_SELECT         s2BIT(7)
 #define RTS_PN_CAM_DATA_PORT(val)          vBIT(val,8,16)
 #define RTS_PN_CAM_DATA_SCW(val)           vBIT(val,24,8)
 
 	u64 rts_ds_mem_ctrl;
-#define RTS_DS_MEM_CTRL_WE                 BIT(7)
-#define RTS_DS_MEM_CTRL_STROBE_NEW_CMD     BIT(15)
-#define RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED   BIT(15)
+#define RTS_DS_MEM_CTRL_WE                 s2BIT(7)
+#define RTS_DS_MEM_CTRL_STROBE_NEW_CMD     s2BIT(15)
+#define RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED   s2BIT(15)
 #define RTS_DS_MEM_CTRL_OFFSET(n)          vBIT(n,26,6)
 	u64 rts_ds_mem_data;
 #define RTS_DS_MEM_DATA(n)                 vBIT(n,0,8)
@@ -823,23 +823,23 @@
 
 /* memory controller registers */
 	u64 mc_int_status;
-#define MC_INT_STATUS_MC_INT               BIT(0)
+#define MC_INT_STATUS_MC_INT               s2BIT(0)
 	u64 mc_int_mask;
-#define MC_INT_MASK_MC_INT                 BIT(0)
+#define MC_INT_MASK_MC_INT                 s2BIT(0)
 
 	u64 mc_err_reg;
-#define MC_ERR_REG_ECC_DB_ERR_L            BIT(14)
-#define MC_ERR_REG_ECC_DB_ERR_U            BIT(15)
-#define MC_ERR_REG_MIRI_ECC_DB_ERR_0       BIT(18)
-#define MC_ERR_REG_MIRI_ECC_DB_ERR_1       BIT(20)
-#define MC_ERR_REG_MIRI_CRI_ERR_0          BIT(22)
-#define MC_ERR_REG_MIRI_CRI_ERR_1          BIT(23)
-#define MC_ERR_REG_SM_ERR                  BIT(31)
-#define MC_ERR_REG_ECC_ALL_SNG		   (BIT(2) | BIT(3) | BIT(4) | BIT(5) |\
-					BIT(17) | BIT(19))
-#define MC_ERR_REG_ECC_ALL_DBL		   (BIT(10) | BIT(11) | BIT(12) |\
-					BIT(13) | BIT(18) | BIT(20))
-#define PLL_LOCK_N			BIT(39)
+#define MC_ERR_REG_ECC_DB_ERR_L            s2BIT(14)
+#define MC_ERR_REG_ECC_DB_ERR_U            s2BIT(15)
+#define MC_ERR_REG_MIRI_ECC_DB_ERR_0       s2BIT(18)
+#define MC_ERR_REG_MIRI_ECC_DB_ERR_1       s2BIT(20)
+#define MC_ERR_REG_MIRI_CRI_ERR_0          s2BIT(22)
+#define MC_ERR_REG_MIRI_CRI_ERR_1          s2BIT(23)
+#define MC_ERR_REG_SM_ERR                  s2BIT(31)
+#define MC_ERR_REG_ECC_ALL_SNG		   (s2BIT(2) | s2BIT(3) | s2BIT(4) | s2BIT(5) |\
+					s2BIT(17) | s2BIT(19))
+#define MC_ERR_REG_ECC_ALL_DBL		   (s2BIT(10) | s2BIT(11) | s2BIT(12) |\
+					s2BIT(13) | s2BIT(18) | s2BIT(20))
+#define PLL_LOCK_N			s2BIT(39)
 	u64 mc_err_mask;
 	u64 mc_err_alarm;
 
@@ -857,8 +857,8 @@
 #define RX_QUEUE_CFG_Q7_SZ(n)              vBIT(n,56,8)
 
 	u64 mc_rldram_mrs;
-#define	MC_RLDRAM_QUEUE_SIZE_ENABLE			BIT(39)
-#define	MC_RLDRAM_MRS_ENABLE				BIT(47)
+#define	MC_RLDRAM_QUEUE_SIZE_ENABLE			s2BIT(39)
+#define	MC_RLDRAM_MRS_ENABLE				s2BIT(47)
 
 	u64 mc_rldram_interleave;
 
@@ -871,11 +871,11 @@
 	u64 mc_rldram_ref_per;
 	u8 unused20[0x220 - 0x208];
 	u64 mc_rldram_test_ctrl;
-#define MC_RLDRAM_TEST_MODE		BIT(47)
-#define MC_RLDRAM_TEST_WRITE	BIT(7)
-#define MC_RLDRAM_TEST_GO		BIT(15)
-#define MC_RLDRAM_TEST_DONE		BIT(23)
-#define MC_RLDRAM_TEST_PASS		BIT(31)
+#define MC_RLDRAM_TEST_MODE		s2BIT(47)
+#define MC_RLDRAM_TEST_WRITE	s2BIT(7)
+#define MC_RLDRAM_TEST_GO		s2BIT(15)
+#define MC_RLDRAM_TEST_DONE		s2BIT(23)
+#define MC_RLDRAM_TEST_PASS		s2BIT(31)
 
 	u8 unused21[0x240 - 0x228];
 	u64 mc_rldram_test_add;
@@ -888,7 +888,7 @@
 
 	u8 unused24_1[0x360 - 0x308];
 	u64 mc_rldram_ctrl;
-#define	MC_RLDRAM_ENABLE_ODT		BIT(7)
+#define	MC_RLDRAM_ENABLE_ODT		s2BIT(7)
 
 	u8 unused24_2[0x640 - 0x368];
 	u64 mc_rldram_ref_per_herc;
@@ -906,24 +906,24 @@
 	/* XGXS control registers */
 
 	u64 xgxs_int_status;
-#define XGXS_INT_STATUS_TXGXS              BIT(0)
-#define XGXS_INT_STATUS_RXGXS              BIT(1)
+#define XGXS_INT_STATUS_TXGXS              s2BIT(0)
+#define XGXS_INT_STATUS_RXGXS              s2BIT(1)
 	u64 xgxs_int_mask;
-#define XGXS_INT_MASK_TXGXS                BIT(0)
-#define XGXS_INT_MASK_RXGXS                BIT(1)
+#define XGXS_INT_MASK_TXGXS                s2BIT(0)
+#define XGXS_INT_MASK_RXGXS                s2BIT(1)
 
 	u64 xgxs_txgxs_err_reg;
-#define TXGXS_ECC_SG_ERR		BIT(7)
-#define TXGXS_ECC_DB_ERR		BIT(15)
-#define TXGXS_ESTORE_UFLOW		BIT(31)
-#define TXGXS_TX_SM_ERR			BIT(39)
+#define TXGXS_ECC_SG_ERR		s2BIT(7)
+#define TXGXS_ECC_DB_ERR		s2BIT(15)
+#define TXGXS_ESTORE_UFLOW		s2BIT(31)
+#define TXGXS_TX_SM_ERR			s2BIT(39)
 
 	u64 xgxs_txgxs_err_mask;
 	u64 xgxs_txgxs_err_alarm;
 
 	u64 xgxs_rxgxs_err_reg;
-#define RXGXS_ESTORE_OFLOW		BIT(7)
-#define RXGXS_RX_SM_ERR			BIT(39)
+#define RXGXS_ESTORE_OFLOW		s2BIT(7)
+#define RXGXS_RX_SM_ERR			s2BIT(39)
 	u64 xgxs_rxgxs_err_mask;
 	u64 xgxs_rxgxs_err_alarm;
 
@@ -942,10 +942,10 @@
 #define SPI_CONTROL_BYTECNT(cnt)	vBIT(cnt,29,3)
 #define SPI_CONTROL_CMD(cmd)		vBIT(cmd,32,8)
 #define SPI_CONTROL_ADDR(addr)		vBIT(addr,40,24)
-#define SPI_CONTROL_SEL1		BIT(4)
-#define SPI_CONTROL_REQ			BIT(7)
-#define SPI_CONTROL_NACK		BIT(5)
-#define SPI_CONTROL_DONE		BIT(6)
+#define SPI_CONTROL_SEL1		s2BIT(4)
+#define SPI_CONTROL_REQ			s2BIT(7)
+#define SPI_CONTROL_NACK		s2BIT(5)
+#define SPI_CONTROL_DONE		s2BIT(6)
 	u64 spi_data;
 #define SPI_DATA_WRITE(data,len)	vBIT(data,0,len)
 };
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 22e4054..b8c0e7b 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -1716,7 +1716,7 @@
 			MISC_LINK_STABILITY_PRD(3);
 		writeq(val64, &bar0->misc_control);
 		val64 = readq(&bar0->pic_control2);
-		val64 &= ~(BIT(13)|BIT(14)|BIT(15));
+		val64 &= ~(s2BIT(13)|s2BIT(14)|s2BIT(15));
 		writeq(val64, &bar0->pic_control2);
 	}
 	if (strstr(nic->product_name, "CX4")) {
@@ -2427,7 +2427,7 @@
 		}
 		if ((rxdp->Control_1 & RXD_OWN_XENA) &&
 			((nic->rxd_mode == RXD_MODE_3B) &&
-				(rxdp->Control_2 & BIT(0)))) {
+				(rxdp->Control_2 & s2BIT(0)))) {
 			mac_control->rings[ring_no].rx_curr_put_info.
 					offset = off;
 			goto end;
@@ -2540,7 +2540,7 @@
 				rxdp->Control_2 |= SET_BUFFER2_SIZE_3
 								(dev->mtu + 4);
 			}
-			rxdp->Control_2 |= BIT(0);
+			rxdp->Control_2 |= s2BIT(0);
 		}
 		rxdp->Host_Control = (unsigned long) (skb);
 		if (alloc_tab & ((1 << rxsync_frequency) - 1))
@@ -3377,7 +3377,7 @@
 		pci_write_config_dword(sp->pdev, 0x68, 0x7C);
 
 		/* Clearing PCI_STATUS error reflected here */
-		writeq(BIT(62), &bar0->txpic_int_reg);
+		writeq(s2BIT(62), &bar0->txpic_int_reg);
 	}
 
 	/* Reset device statistics maintained by OS */
@@ -3575,7 +3575,7 @@
 
 	do {
 		val64 = readq(&bar0->xmsi_access);
-		if (!(val64 & BIT(15)))
+		if (!(val64 & s2BIT(15)))
 			break;
 		mdelay(1);
 		cnt++;
@@ -3597,7 +3597,7 @@
 	for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
 		writeq(nic->msix_info[i].addr, &bar0->xmsi_address);
 		writeq(nic->msix_info[i].data, &bar0->xmsi_data);
-		val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6));
+		val64 = (s2BIT(7) | s2BIT(15) | vBIT(i, 26, 6));
 		writeq(val64, &bar0->xmsi_access);
 		if (wait_for_msix_trans(nic, i)) {
 			DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
@@ -3614,7 +3614,7 @@
 
 	/* Store and display */
 	for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
-		val64 = (BIT(15) | vBIT(i, 26, 6));
+		val64 = (s2BIT(15) | vBIT(i, 26, 6));
 		writeq(val64, &bar0->xmsi_access);
 		if (wait_for_msix_trans(nic, i)) {
 			DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
@@ -4634,7 +4634,7 @@
 		do {
 			udelay(100);
 			val64 = readq(&bar0->stat_cfg);
-			if (!(val64 & BIT(0)))
+			if (!(val64 & s2BIT(0)))
 				break;
 			cnt++;
 			if (cnt == 5)
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index f6b4556..cc1797a 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -14,7 +14,7 @@
 #define _S2IO_H
 
 #define TBD 0
-#define BIT(loc)		(0x8000000000000000ULL >> (loc))
+#define s2BIT(loc)		(0x8000000000000000ULL >> (loc))
 #define vBIT(val, loc, sz)	(((u64)val) << (64-loc-sz))
 #define INV(d)  ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff)
 
@@ -473,42 +473,42 @@
 
 	u64 List_Control;
 #define TX_FIFO_LAST_TXD_NUM( val)     vBIT(val,0,8)
-#define TX_FIFO_FIRST_LIST             BIT(14)
-#define TX_FIFO_LAST_LIST              BIT(15)
+#define TX_FIFO_FIRST_LIST             s2BIT(14)
+#define TX_FIFO_LAST_LIST              s2BIT(15)
 #define TX_FIFO_FIRSTNLAST_LIST        vBIT(3,14,2)
-#define TX_FIFO_SPECIAL_FUNC           BIT(23)
-#define TX_FIFO_DS_NO_SNOOP            BIT(31)
-#define TX_FIFO_BUFF_NO_SNOOP          BIT(30)
+#define TX_FIFO_SPECIAL_FUNC           s2BIT(23)
+#define TX_FIFO_DS_NO_SNOOP            s2BIT(31)
+#define TX_FIFO_BUFF_NO_SNOOP          s2BIT(30)
 };
 
 /* Tx descriptor structure */
 struct TxD {
 	u64 Control_1;
 /* bit mask */
-#define TXD_LIST_OWN_XENA       BIT(7)
-#define TXD_T_CODE              (BIT(12)|BIT(13)|BIT(14)|BIT(15))
+#define TXD_LIST_OWN_XENA       s2BIT(7)
+#define TXD_T_CODE              (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15))
 #define TXD_T_CODE_OK(val)      (|(val & TXD_T_CODE))
 #define GET_TXD_T_CODE(val)     ((val & TXD_T_CODE)<<12)
-#define TXD_GATHER_CODE         (BIT(22) | BIT(23))
-#define TXD_GATHER_CODE_FIRST   BIT(22)
-#define TXD_GATHER_CODE_LAST    BIT(23)
-#define TXD_TCP_LSO_EN          BIT(30)
-#define TXD_UDP_COF_EN          BIT(31)
-#define TXD_UFO_EN		BIT(31) | BIT(30)
+#define TXD_GATHER_CODE         (s2BIT(22) | s2BIT(23))
+#define TXD_GATHER_CODE_FIRST   s2BIT(22)
+#define TXD_GATHER_CODE_LAST    s2BIT(23)
+#define TXD_TCP_LSO_EN          s2BIT(30)
+#define TXD_UDP_COF_EN          s2BIT(31)
+#define TXD_UFO_EN		s2BIT(31) | s2BIT(30)
 #define TXD_TCP_LSO_MSS(val)    vBIT(val,34,14)
 #define TXD_UFO_MSS(val)	vBIT(val,34,14)
 #define TXD_BUFFER0_SIZE(val)   vBIT(val,48,16)
 
 	u64 Control_2;
-#define TXD_TX_CKO_CONTROL      (BIT(5)|BIT(6)|BIT(7))
-#define TXD_TX_CKO_IPV4_EN      BIT(5)
-#define TXD_TX_CKO_TCP_EN       BIT(6)
-#define TXD_TX_CKO_UDP_EN       BIT(7)
-#define TXD_VLAN_ENABLE         BIT(15)
+#define TXD_TX_CKO_CONTROL      (s2BIT(5)|s2BIT(6)|s2BIT(7))
+#define TXD_TX_CKO_IPV4_EN      s2BIT(5)
+#define TXD_TX_CKO_TCP_EN       s2BIT(6)
+#define TXD_TX_CKO_UDP_EN       s2BIT(7)
+#define TXD_VLAN_ENABLE         s2BIT(15)
 #define TXD_VLAN_TAG(val)       vBIT(val,16,16)
 #define TXD_INT_NUMBER(val)     vBIT(val,34,6)
-#define TXD_INT_TYPE_PER_LIST   BIT(47)
-#define TXD_INT_TYPE_UTILZ      BIT(46)
+#define TXD_INT_TYPE_PER_LIST   s2BIT(47)
+#define TXD_INT_TYPE_UTILZ      s2BIT(46)
 #define TXD_SET_MARKER         vBIT(0x6,0,4)
 
 	u64 Buffer_Pointer;
@@ -525,14 +525,14 @@
 struct RxD_t {
 	u64 Host_Control;	/* reserved for host */
 	u64 Control_1;
-#define RXD_OWN_XENA            BIT(7)
-#define RXD_T_CODE              (BIT(12)|BIT(13)|BIT(14)|BIT(15))
+#define RXD_OWN_XENA            s2BIT(7)
+#define RXD_T_CODE              (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15))
 #define RXD_FRAME_PROTO         vBIT(0xFFFF,24,8)
-#define RXD_FRAME_PROTO_IPV4    BIT(27)
-#define RXD_FRAME_PROTO_IPV6    BIT(28)
-#define RXD_FRAME_IP_FRAG	BIT(29)
-#define RXD_FRAME_PROTO_TCP     BIT(30)
-#define RXD_FRAME_PROTO_UDP     BIT(31)
+#define RXD_FRAME_PROTO_IPV4    s2BIT(27)
+#define RXD_FRAME_PROTO_IPV6    s2BIT(28)
+#define RXD_FRAME_IP_FRAG	s2BIT(29)
+#define RXD_FRAME_PROTO_TCP     s2BIT(30)
+#define RXD_FRAME_PROTO_UDP     s2BIT(31)
 #define TCP_OR_UDP_FRAME        (RXD_FRAME_PROTO_TCP | RXD_FRAME_PROTO_UDP)
 #define RXD_GET_L3_CKSUM(val)   ((u16)(val>> 16) & 0xFFFF)
 #define RXD_GET_L4_CKSUM(val)   ((u16)(val) & 0xFFFF)
@@ -998,26 +998,26 @@
 /*  Interrupt masks for the general interrupt mask register */
 #define DISABLE_ALL_INTRS   0xFFFFFFFFFFFFFFFFULL
 
-#define TXPIC_INT_M         BIT(0)
-#define TXDMA_INT_M         BIT(1)
-#define TXMAC_INT_M         BIT(2)
-#define TXXGXS_INT_M        BIT(3)
-#define TXTRAFFIC_INT_M     BIT(8)
-#define PIC_RX_INT_M        BIT(32)
-#define RXDMA_INT_M         BIT(33)
-#define RXMAC_INT_M         BIT(34)
-#define MC_INT_M            BIT(35)
-#define RXXGXS_INT_M        BIT(36)
-#define RXTRAFFIC_INT_M     BIT(40)
+#define TXPIC_INT_M         s2BIT(0)
+#define TXDMA_INT_M         s2BIT(1)
+#define TXMAC_INT_M         s2BIT(2)
+#define TXXGXS_INT_M        s2BIT(3)
+#define TXTRAFFIC_INT_M     s2BIT(8)
+#define PIC_RX_INT_M        s2BIT(32)
+#define RXDMA_INT_M         s2BIT(33)
+#define RXMAC_INT_M         s2BIT(34)
+#define MC_INT_M            s2BIT(35)
+#define RXXGXS_INT_M        s2BIT(36)
+#define RXTRAFFIC_INT_M     s2BIT(40)
 
 /*  PIC level Interrupts TODO*/
 
 /*  DMA level Inressupts */
-#define TXDMA_PFC_INT_M     BIT(0)
-#define TXDMA_PCC_INT_M     BIT(2)
+#define TXDMA_PFC_INT_M     s2BIT(0)
+#define TXDMA_PCC_INT_M     s2BIT(2)
 
 /*  PFC block interrupts */
-#define PFC_MISC_ERR_1      BIT(0)	/* Interrupt to indicate FIFO full */
+#define PFC_MISC_ERR_1      s2BIT(0)	/* Interrupt to indicate FIFO full */
 
 /* PCC block interrupts. */
 #define	PCC_FB_ECC_ERR	   vBIT(0xff, 16, 8)	/* Interrupt to indicate
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 7967240..24cfb62 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1384,13 +1384,9 @@
 	sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
 			   TX_RING_SIZE - 1);
 
-	napi_enable(&hw->napi);
-
 	err = sky2_rx_start(sky2);
-	if (err) {
-		napi_disable(&hw->napi);
+	if (err)
 		goto err_out;
-	}
 
 	/* Enable interrupts from phy/mac for port */
 	imask = sky2_read32(hw, B0_IMSK);
@@ -1679,13 +1675,13 @@
 	/* Stop more packets from being queued */
 	netif_stop_queue(dev);
 
-	napi_disable(&hw->napi);
-
 	/* Disable port IRQ */
 	imask = sky2_read32(hw, B0_IMSK);
 	imask &= ~portirq_msk[port];
 	sky2_write32(hw, B0_IMSK, imask);
 
+	synchronize_irq(hw->pdev->irq);
+
 	sky2_gmac_reset(hw, port);
 
 	/* Stop transmitter */
@@ -1699,6 +1695,9 @@
 	ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
 	gma_write16(hw, port, GM_GP_CTRL, ctrl);
 
+	/* Make sure no packets are pending */
+	napi_synchronize(&hw->napi);
+
 	sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
 
 	/* Workaround shared GMAC reset */
@@ -1736,8 +1735,6 @@
 	/* turn off LED's */
 	sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
 
-	synchronize_irq(hw->pdev->irq);
-
 	sky2_tx_clean(dev);
 	sky2_rx_clean(sky2);
 
@@ -2048,9 +2045,6 @@
 	err = sky2_rx_start(sky2);
 	sky2_write32(hw, B0_IMSK, imask);
 
-	/* Unconditionally re-enable NAPI because even if we
-	 * call dev_close() that will do a napi_disable().
-	 */
 	napi_enable(&hw->napi);
 
 	if (err)
@@ -2915,6 +2909,7 @@
 	rtnl_lock();
 	sky2_write32(hw, B0_IMSK, 0);
 	sky2_read32(hw, B0_IMSK);
+	napi_disable(&hw->napi);
 
 	for (i = 0; i < hw->ports; i++) {
 		dev = hw->dev[i];
@@ -2924,6 +2919,7 @@
 
 	sky2_reset(hw);
 	sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+	napi_enable(&hw->napi);
 
 	for (i = 0; i < hw->ports; i++) {
 		dev = hw->dev[i];
@@ -3961,7 +3957,7 @@
 	struct net_device *dev = alloc_etherdev(sizeof(*sky2));
 
 	if (!dev) {
-		dev_err(&hw->pdev->dev, "etherdev alloc failed");
+		dev_err(&hw->pdev->dev, "etherdev alloc failed\n");
 		return NULL;
 	}
 
@@ -4191,7 +4187,6 @@
 		err = -ENOMEM;
 		goto err_out_free_pci;
 	}
-	netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT);
 
 	if (!disable_msi && pci_enable_msi(pdev) == 0) {
 		err = sky2_test_msi(hw);
@@ -4207,6 +4202,8 @@
 		goto err_out_free_netdev;
 	}
 
+	netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT);
+
 	err = request_irq(pdev->irq, sky2_intr,
 			  (hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED,
 			  dev->name, hw);
@@ -4215,6 +4212,7 @@
 		goto err_out_unregister;
 	}
 	sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+	napi_enable(&hw->napi);
 
 	sky2_show_addr(dev);
 
@@ -4265,23 +4263,18 @@
 static void __devexit sky2_remove(struct pci_dev *pdev)
 {
 	struct sky2_hw *hw = pci_get_drvdata(pdev);
-	struct net_device *dev0, *dev1;
+	int i;
 
 	if (!hw)
 		return;
 
 	del_timer_sync(&hw->watchdog_timer);
+	cancel_work_sync(&hw->restart_work);
 
-	flush_scheduled_work();
+	for (i = hw->ports; i >= 0; --i)
+		unregister_netdev(hw->dev[i]);
 
 	sky2_write32(hw, B0_IMSK, 0);
-	synchronize_irq(hw->pdev->irq);
-
-	dev0 = hw->dev[0];
-	dev1 = hw->dev[1];
-	if (dev1)
-		unregister_netdev(dev1);
-	unregister_netdev(dev0);
 
 	sky2_power_aux(hw);
 
@@ -4296,9 +4289,9 @@
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 
-	if (dev1)
-		free_netdev(dev1);
-	free_netdev(dev0);
+	for (i = hw->ports; i >= 0; --i)
+		free_netdev(hw->dev[i]);
+
 	iounmap(hw->regs);
 	kfree(hw);
 
@@ -4328,6 +4321,7 @@
 	}
 
 	sky2_write32(hw, B0_IMSK, 0);
+	napi_disable(&hw->napi);
 	sky2_power_aux(hw);
 
 	pci_save_state(pdev);
@@ -4362,8 +4356,8 @@
 		pci_write_config_dword(pdev, PCI_DEV_REG3, 0);
 
 	sky2_reset(hw);
-
 	sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+	napi_enable(&hw->napi);
 
 	for (i = 0; i < hw->ports; i++) {
 		struct net_device *dev = hw->dev[i];
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 7c60df4..dd18af0 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -1223,7 +1223,7 @@
 		}
 #endif
 
-		/* Handle PHY interupt condition */
+		/* Handle PHY interrupt condition */
 		if (status & INT_STS_PHY_INT_) {
 			DBG(SMC_DEBUG_MISC, "%s: PHY irq\n", dev->name);
 			smc911x_phy_interrupt(dev);
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index fab055f..bccae7e 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -46,7 +46,7 @@
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
 #include <linux/workqueue.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/pci-bridge.h>
 #include <net/checksum.h>
 
@@ -1639,7 +1639,7 @@
 
 /**
  * spider_net_interrupt - interrupt handler for spider_net
- * @irq: interupt number
+ * @irq: interrupt number
  * @ptr: pointer to net_device
  * @regs: PU registers
  *
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index 8038f28..d887c05 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -1654,7 +1654,7 @@
 					panic_queues(dev);
 				}
 #endif
-				/* pass BD to controler */
+				/* pass BD to controller */
 #ifndef TC35815_USE_PACKEDBUFFER
 				if (!lp->rx_skbs[curid].skb) {
 					lp->rx_skbs[curid].skb =
@@ -1694,7 +1694,7 @@
 		}
 #endif
 		for (i = 0; i < (bd_count + 1) / 2 + 1; i++) {
-			/* pass FD to controler */
+			/* pass FD to controller */
 #ifdef DEBUG
 			lp->rfd_cur->fd.FDNext = cpu_to_le32(0xdeaddead);
 #else
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 014dc2c..09440d7 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.84"
-#define DRV_MODULE_RELDATE	"October 12, 2007"
+#define DRV_MODULE_VERSION	"3.85"
+#define DRV_MODULE_RELDATE	"October 18, 2007"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -200,6 +200,7 @@
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906M)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5784)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5764)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5723)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)},
 	{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
@@ -5028,10 +5029,7 @@
 /* Save PCI command register before chip reset */
 static void tg3_save_pci_state(struct tg3 *tp)
 {
-	u32 val;
-
-	pci_read_config_dword(tp->pdev, TG3PCI_COMMAND, &val);
-	tp->pci_cmd = val;
+	pci_read_config_word(tp->pdev, PCI_COMMAND, &tp->pci_cmd);
 }
 
 /* Restore PCI state after chip reset */
@@ -5054,7 +5052,7 @@
 		       PCISTATE_ALLOW_APE_SHMEM_WR;
 	pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val);
 
-	pci_write_config_dword(tp->pdev, TG3PCI_COMMAND, tp->pci_cmd);
+	pci_write_config_word(tp->pdev, PCI_COMMAND, tp->pci_cmd);
 
 	if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
 		pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
@@ -10820,9 +10818,24 @@
 		strcpy(tp->board_part_number, "none");
 }
 
+static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
+{
+	u32 val;
+
+	if (tg3_nvram_read_swab(tp, offset, &val) ||
+	    (val & 0xfc000000) != 0x0c000000 ||
+	    tg3_nvram_read_swab(tp, offset + 4, &val) ||
+	    val != 0)
+		return 0;
+
+	return 1;
+}
+
 static void __devinit tg3_read_fw_ver(struct tg3 *tp)
 {
 	u32 val, offset, start;
+	u32 ver_offset;
+	int i, bcnt;
 
 	if (tg3_nvram_read_swab(tp, 0, &val))
 		return;
@@ -10835,29 +10848,71 @@
 		return;
 
 	offset = tg3_nvram_logical_addr(tp, offset);
-	if (tg3_nvram_read_swab(tp, offset, &val))
+
+	if (!tg3_fw_img_is_valid(tp, offset) ||
+	    tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
 		return;
 
-	if ((val & 0xfc000000) == 0x0c000000) {
-		u32 ver_offset, addr;
-		int i;
-
-		if (tg3_nvram_read_swab(tp, offset + 4, &val) ||
-		    tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
+	offset = offset + ver_offset - start;
+	for (i = 0; i < 16; i += 4) {
+		if (tg3_nvram_read(tp, offset + i, &val))
 			return;
 
-		if (val != 0)
-			return;
-
-		addr = offset + ver_offset - start;
-		for (i = 0; i < 16; i += 4) {
-			if (tg3_nvram_read(tp, addr + i, &val))
-				return;
-
-			val = cpu_to_le32(val);
-			memcpy(tp->fw_ver + i, &val, 4);
-		}
+		val = le32_to_cpu(val);
+		memcpy(tp->fw_ver + i, &val, 4);
 	}
+
+	if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
+	     (tp->tg3_flags & TG3_FLG3_ENABLE_APE))
+		return;
+
+	for (offset = TG3_NVM_DIR_START;
+	     offset < TG3_NVM_DIR_END;
+	     offset += TG3_NVM_DIRENT_SIZE) {
+		if (tg3_nvram_read_swab(tp, offset, &val))
+			return;
+
+		if ((val >> TG3_NVM_DIRTYPE_SHIFT) == TG3_NVM_DIRTYPE_ASFINI)
+			break;
+	}
+
+	if (offset == TG3_NVM_DIR_END)
+		return;
+
+	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+		start = 0x08000000;
+	else if (tg3_nvram_read_swab(tp, offset - 4, &start))
+		return;
+
+	if (tg3_nvram_read_swab(tp, offset + 4, &offset) ||
+	    !tg3_fw_img_is_valid(tp, offset) ||
+	    tg3_nvram_read_swab(tp, offset + 8, &val))
+		return;
+
+	offset += val - start;
+
+	bcnt = strlen(tp->fw_ver);
+
+	tp->fw_ver[bcnt++] = ',';
+	tp->fw_ver[bcnt++] = ' ';
+
+	for (i = 0; i < 4; i++) {
+		if (tg3_nvram_read(tp, offset, &val))
+			return;
+
+		val = le32_to_cpu(val);
+		offset += sizeof(val);
+
+		if (bcnt > TG3_VER_SIZE - sizeof(val)) {
+			memcpy(&tp->fw_ver[bcnt], &val, TG3_VER_SIZE - bcnt);
+			break;
+		}
+
+		memcpy(&tp->fw_ver[bcnt], &val, sizeof(val));
+		bcnt += sizeof(val);
+	}
+
+	tp->fw_ver[TG3_VER_SIZE - 1] = 0;
 }
 
 static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 6dbdad2..1d5b2a3 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1540,6 +1540,12 @@
 #define TG3_EEPROM_MAGIC_HW		0xabcd
 #define TG3_EEPROM_MAGIC_HW_MSK		0xffff
 
+#define TG3_NVM_DIR_START		0x18
+#define TG3_NVM_DIR_END			0x78
+#define TG3_NVM_DIRENT_SIZE		0xc
+#define TG3_NVM_DIRTYPE_SHIFT		24
+#define TG3_NVM_DIRTYPE_ASFINI		1
+
 /* 32K Window into NIC internal memory */
 #define NIC_SRAM_WIN_BASE		0x00008000
 
@@ -2415,10 +2421,11 @@
 #define PHY_REV_BCM5411_X0		0x1 /* Found on Netgear GA302T */
 
 	u32				led_ctrl;
-	u32				pci_cmd;
+	u16				pci_cmd;
 
 	char				board_part_number[24];
-	char				fw_ver[16];
+#define TG3_VER_SIZE 32
+	char				fw_ver[TG3_VER_SIZE];
 	u32				nic_sram_data_cfg;
 	u32				pci_clock_ctrl;
 	struct pci_dev			*pdev_peer;
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index df10af7..35d15e8 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -1629,7 +1629,7 @@
 		goto register_fail;
 	}
 
-	printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %s\n"
+	printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %s\n",
 	       dev->name, print_mac(mac, dev->dev_addr));
 #ifdef DEBUG
 	data->msg_enable = DEBUG;
diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig
index 1c537d5..49d7a29 100644
--- a/drivers/net/tulip/Kconfig
+++ b/drivers/net/tulip/Kconfig
@@ -67,7 +67,7 @@
 	  If in doubt, say N.
 
 config TULIP_NAPI
-	bool "Use NAPI RX polling "
+	bool "Use RX polling (NAPI)"
 	depends on TULIP
 	help
 	  NAPI is a new driver API designed to reduce CPU and interrupt load
@@ -78,18 +78,16 @@
 	  deployed on potentially unfriendly networks (e.g. in a firewall),
 	  then say Y here.
 
-	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more
-	  information.
-
 	  If in doubt, say N.
 
 config TULIP_NAPI_HW_MITIGATION
-	bool "Use Interrupt Mitigation "
+	bool "Use Interrupt Mitigation"
 	depends on TULIP_NAPI
 	---help---
-	  Use HW to reduce RX interrupts. Not strict necessary since NAPI reduces
-	  RX interrupts but itself. Although this reduces RX interrupts even at
-	  low levels traffic at the cost of a small latency.
+	  Use HW to reduce RX interrupts. Not strictly necessary since NAPI
+	  reduces RX interrupts by itself. Interrupt mitigation reduces RX
+	  interrupts even at low levels of traffic at the cost of a small
+	  latency.
 
 	  If in doubt, say Y.
 
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 76e5561..a7afeea 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -34,9 +34,9 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/dma-mapping.h>
+#include <linux/bitops.h>
 
 #include <asm/processor.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 3c8e3b6..35d0cfc 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -483,7 +483,7 @@
    a delay.  Note that pre-2.0.34 kernels had a cache-alignment bug that
    made udelay() unreliable.
    The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
-   depricated.
+   deprecated.
 */
 #define eeprom_delay(ee_addr)	ioread32(ee_addr)
 
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 8dc09a3..5a96d74 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -71,7 +71,7 @@
 	select MII
 	---help---
 	  Say Y here if you know you have Pegasus or Pegasus-II based adapter.
-	  If in doubt then look at <file:drivers/usb/net/pegasus.h> for the
+	  If in doubt then look at <file:drivers/net/usb/pegasus.h> for the
 	  complete list of supported devices.
 
 	  If your particular adapter is not in the list and you are _sure_ it
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index 6240b97..f55a595 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -114,8 +114,8 @@
 	struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
 
 	if (urb->status < 0)
-		printk(KERN_DEBUG "mcs7830_async_cmd_callback() failed with %d",
-			urb->status);
+		printk(KERN_DEBUG "%s() failed with %d\n",
+		       __FUNCTION__, urb->status);
 
 	kfree(req);
 	usb_free_urb(urb);
@@ -129,15 +129,15 @@
 
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!urb) {
-		dev_dbg(&dev->udev->dev, "Error allocating URB "
-				"in write_cmd_async!");
+		dev_dbg(&dev->udev->dev,
+			"Error allocating URB in write_cmd_async!\n");
 		return;
 	}
 
 	req = kmalloc(sizeof *req, GFP_ATOMIC);
 	if (!req) {
-		dev_err(&dev->udev->dev, "Failed to allocate memory for "
-				"control request");
+		dev_err(&dev->udev->dev,
+			"Failed to allocate memory for control request\n");
 		goto out;
 	}
 	req->bRequestType = MCS7830_WR_BMREQ;
@@ -153,8 +153,8 @@
 
 	ret = usb_submit_urb(urb, GFP_ATOMIC);
 	if (ret < 0) {
-		dev_err(&dev->udev->dev, "Error submitting the control "
-				"message: ret=%d", ret);
+		dev_err(&dev->udev->dev,
+			"Error submitting the control message: ret=%d\n", ret);
 		goto out;
 	}
 	return;
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 4ae0579..5c4a92d 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1648,7 +1648,7 @@
  *
  *	Scan the queues looking for transmitted packets that
  *	we can complete and clean up. Update any statistics as
- *	neccessary/
+ *	necessary/
  */
 
 static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
new file mode 100644
index 0000000..e396c9d
--- /dev/null
+++ b/drivers/net/virtio_net.c
@@ -0,0 +1,435 @@
+/* A simple network driver using virtio.
+ *
+ * Copyright 2007 Rusty Russell <rusty@rustcorp.com.au> IBM 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
+ */
+//#define DEBUG
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/module.h>
+#include <linux/virtio.h>
+#include <linux/virtio_net.h>
+#include <linux/scatterlist.h>
+
+/* FIXME: MTU in config. */
+#define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN)
+
+struct virtnet_info
+{
+	struct virtio_device *vdev;
+	struct virtqueue *rvq, *svq;
+	struct net_device *dev;
+	struct napi_struct napi;
+
+	/* Number of input buffers, and max we've ever had. */
+	unsigned int num, max;
+
+	/* Receive & send queues. */
+	struct sk_buff_head recv;
+	struct sk_buff_head send;
+};
+
+static inline struct virtio_net_hdr *skb_vnet_hdr(struct sk_buff *skb)
+{
+	return (struct virtio_net_hdr *)skb->cb;
+}
+
+static inline void vnet_hdr_to_sg(struct scatterlist *sg, struct sk_buff *skb)
+{
+	sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr));
+}
+
+static bool skb_xmit_done(struct virtqueue *rvq)
+{
+	struct virtnet_info *vi = rvq->vdev->priv;
+
+	/* In case we were waiting for output buffers. */
+	netif_wake_queue(vi->dev);
+	return true;
+}
+
+static void receive_skb(struct net_device *dev, struct sk_buff *skb,
+			unsigned len)
+{
+	struct virtio_net_hdr *hdr = skb_vnet_hdr(skb);
+
+	if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
+		pr_debug("%s: short packet %i\n", dev->name, len);
+		dev->stats.rx_length_errors++;
+		goto drop;
+	}
+	len -= sizeof(struct virtio_net_hdr);
+	BUG_ON(len > MAX_PACKET_LEN);
+
+	skb_trim(skb, len);
+	skb->protocol = eth_type_trans(skb, dev);
+	pr_debug("Receiving skb proto 0x%04x len %i type %i\n",
+		 ntohs(skb->protocol), skb->len, skb->pkt_type);
+	dev->stats.rx_bytes += skb->len;
+	dev->stats.rx_packets++;
+
+	if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+		pr_debug("Needs csum!\n");
+		skb->ip_summed = CHECKSUM_PARTIAL;
+		skb->csum_start = hdr->csum_start;
+		skb->csum_offset = hdr->csum_offset;
+		if (skb->csum_start > skb->len - 2
+		    || skb->csum_offset > skb->len - 2) {
+			if (net_ratelimit())
+				printk(KERN_WARNING "%s: csum=%u/%u len=%u\n",
+				       dev->name, skb->csum_start,
+				       skb->csum_offset, skb->len);
+			goto frame_err;
+		}
+	}
+
+	if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+		pr_debug("GSO!\n");
+		switch (hdr->gso_type) {
+		case VIRTIO_NET_HDR_GSO_TCPV4:
+			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+			break;
+		case VIRTIO_NET_HDR_GSO_TCPV4_ECN:
+			skb_shinfo(skb)->gso_type = SKB_GSO_TCP_ECN;
+			break;
+		case VIRTIO_NET_HDR_GSO_UDP:
+			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+			break;
+		case VIRTIO_NET_HDR_GSO_TCPV6:
+			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
+			break;
+		default:
+			if (net_ratelimit())
+				printk(KERN_WARNING "%s: bad gso type %u.\n",
+				       dev->name, hdr->gso_type);
+			goto frame_err;
+		}
+
+		skb_shinfo(skb)->gso_size = hdr->gso_size;
+		if (skb_shinfo(skb)->gso_size == 0) {
+			if (net_ratelimit())
+				printk(KERN_WARNING "%s: zero gso size.\n",
+				       dev->name);
+			goto frame_err;
+		}
+
+		/* Header must be checked, and gso_segs computed. */
+		skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+		skb_shinfo(skb)->gso_segs = 0;
+	}
+
+	netif_receive_skb(skb);
+	return;
+
+frame_err:
+	dev->stats.rx_frame_errors++;
+drop:
+	dev_kfree_skb(skb);
+}
+
+static void try_fill_recv(struct virtnet_info *vi)
+{
+	struct sk_buff *skb;
+	struct scatterlist sg[1+MAX_SKB_FRAGS];
+	int num, err;
+
+	for (;;) {
+		skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN);
+		if (unlikely(!skb))
+			break;
+
+		skb_put(skb, MAX_PACKET_LEN);
+		vnet_hdr_to_sg(sg, skb);
+		num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
+		skb_queue_head(&vi->recv, skb);
+
+		err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb);
+		if (err) {
+			skb_unlink(skb, &vi->recv);
+			kfree_skb(skb);
+			break;
+		}
+		vi->num++;
+	}
+	if (unlikely(vi->num > vi->max))
+		vi->max = vi->num;
+	vi->rvq->vq_ops->kick(vi->rvq);
+}
+
+static bool skb_recv_done(struct virtqueue *rvq)
+{
+	struct virtnet_info *vi = rvq->vdev->priv;
+	netif_rx_schedule(vi->dev, &vi->napi);
+	/* Suppress further interrupts. */
+	return false;
+}
+
+static int virtnet_poll(struct napi_struct *napi, int budget)
+{
+	struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi);
+	struct sk_buff *skb = NULL;
+	unsigned int len, received = 0;
+
+again:
+	while (received < budget &&
+	       (skb = vi->rvq->vq_ops->get_buf(vi->rvq, &len)) != NULL) {
+		__skb_unlink(skb, &vi->recv);
+		receive_skb(vi->dev, skb, len);
+		vi->num--;
+		received++;
+	}
+
+	/* FIXME: If we oom and completely run out of inbufs, we need
+	 * to start a timer trying to fill more. */
+	if (vi->num < vi->max / 2)
+		try_fill_recv(vi);
+
+	/* All done? */
+	if (!skb) {
+		netif_rx_complete(vi->dev, napi);
+		if (unlikely(!vi->rvq->vq_ops->restart(vi->rvq))
+		    && netif_rx_reschedule(vi->dev, napi))
+			goto again;
+	}
+
+	return received;
+}
+
+static void free_old_xmit_skbs(struct virtnet_info *vi)
+{
+	struct sk_buff *skb;
+	unsigned int len;
+
+	while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) {
+		pr_debug("Sent skb %p\n", skb);
+		__skb_unlink(skb, &vi->send);
+		vi->dev->stats.tx_bytes += len;
+		vi->dev->stats.tx_packets++;
+		kfree_skb(skb);
+	}
+}
+
+static int start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+	int num, err;
+	struct scatterlist sg[1+MAX_SKB_FRAGS];
+	struct virtio_net_hdr *hdr;
+	const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
+	DECLARE_MAC_BUF(mac);
+
+	pr_debug("%s: xmit %p %s\n", dev->name, skb, print_mac(mac, dest));
+
+	free_old_xmit_skbs(vi);
+
+	/* Encode metadata header at front. */
+	hdr = skb_vnet_hdr(skb);
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+		hdr->csum_start = skb->csum_start - skb_headroom(skb);
+		hdr->csum_offset = skb->csum_offset;
+	} else {
+		hdr->flags = 0;
+		hdr->csum_offset = hdr->csum_start = 0;
+	}
+
+	if (skb_is_gso(skb)) {
+		hdr->gso_size = skb_shinfo(skb)->gso_size;
+		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
+			hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4_ECN;
+		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
+			hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+			hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+		else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
+			hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
+		else
+			BUG();
+	} else {
+		hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
+		hdr->gso_size = 0;
+	}
+
+	vnet_hdr_to_sg(sg, skb);
+	num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
+	__skb_queue_head(&vi->send, skb);
+	err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb);
+	if (err) {
+		pr_debug("%s: virtio not prepared to send\n", dev->name);
+		skb_unlink(skb, &vi->send);
+		netif_stop_queue(dev);
+		return NETDEV_TX_BUSY;
+	}
+	vi->svq->vq_ops->kick(vi->svq);
+
+	return 0;
+}
+
+static int virtnet_open(struct net_device *dev)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+
+	try_fill_recv(vi);
+
+	/* If we didn't even get one input buffer, we're useless. */
+	if (vi->num == 0)
+		return -ENOMEM;
+
+	napi_enable(&vi->napi);
+	return 0;
+}
+
+static int virtnet_close(struct net_device *dev)
+{
+	struct virtnet_info *vi = netdev_priv(dev);
+	struct sk_buff *skb;
+
+	napi_disable(&vi->napi);
+
+	/* networking core has neutered skb_xmit_done/skb_recv_done, so don't
+	 * worry about races vs. get(). */
+	vi->rvq->vq_ops->shutdown(vi->rvq);
+	while ((skb = __skb_dequeue(&vi->recv)) != NULL) {
+		kfree_skb(skb);
+		vi->num--;
+	}
+	vi->svq->vq_ops->shutdown(vi->svq);
+	while ((skb = __skb_dequeue(&vi->send)) != NULL)
+		kfree_skb(skb);
+
+	BUG_ON(vi->num != 0);
+	return 0;
+}
+
+static int virtnet_probe(struct virtio_device *vdev)
+{
+	int err;
+	unsigned int len;
+	struct net_device *dev;
+	struct virtnet_info *vi;
+	void *token;
+
+	/* Allocate ourselves a network device with room for our info */
+	dev = alloc_etherdev(sizeof(struct virtnet_info));
+	if (!dev)
+		return -ENOMEM;
+
+	/* Set up network device as normal. */
+	ether_setup(dev);
+	dev->open = virtnet_open;
+	dev->stop = virtnet_close;
+	dev->hard_start_xmit = start_xmit;
+	dev->features = NETIF_F_HIGHDMA;
+	SET_NETDEV_DEV(dev, &vdev->dev);
+
+	/* Do we support "hardware" checksums? */
+	token = vdev->config->find(vdev, VIRTIO_CONFIG_NET_F, &len);
+	if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_NO_CSUM)) {
+		/* This opens up the world of extra features. */
+		dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
+		if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO4))
+			dev->features |= NETIF_F_TSO;
+		if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_UFO))
+			dev->features |= NETIF_F_UFO;
+		if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO4_ECN))
+			dev->features |= NETIF_F_TSO_ECN;
+		if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO6))
+			dev->features |= NETIF_F_TSO6;
+	}
+
+	/* Configuration may specify what MAC to use.  Otherwise random. */
+	token = vdev->config->find(vdev, VIRTIO_CONFIG_NET_MAC_F, &len);
+	if (token) {
+		dev->addr_len = len;
+		vdev->config->get(vdev, token, dev->dev_addr, len);
+	} else
+		random_ether_addr(dev->dev_addr);
+
+	/* Set up our device-specific information */
+	vi = netdev_priv(dev);
+	netif_napi_add(dev, &vi->napi, virtnet_poll, 16);
+	vi->dev = dev;
+	vi->vdev = vdev;
+
+	/* We expect two virtqueues, receive then send. */
+	vi->rvq = vdev->config->find_vq(vdev, skb_recv_done);
+	if (IS_ERR(vi->rvq)) {
+		err = PTR_ERR(vi->rvq);
+		goto free;
+	}
+
+	vi->svq = vdev->config->find_vq(vdev, skb_xmit_done);
+	if (IS_ERR(vi->svq)) {
+		err = PTR_ERR(vi->svq);
+		goto free_recv;
+	}
+
+	/* Initialize our empty receive and send queues. */
+	skb_queue_head_init(&vi->recv);
+	skb_queue_head_init(&vi->send);
+
+	err = register_netdev(dev);
+	if (err) {
+		pr_debug("virtio_net: registering device failed\n");
+		goto free_send;
+	}
+	pr_debug("virtnet: registered device %s\n", dev->name);
+	vdev->priv = vi;
+	return 0;
+
+free_send:
+	vdev->config->del_vq(vi->svq);
+free_recv:
+	vdev->config->del_vq(vi->rvq);
+free:
+	free_netdev(dev);
+	return err;
+}
+
+static void virtnet_remove(struct virtio_device *vdev)
+{
+	unregister_netdev(vdev->priv);
+	free_netdev(vdev->priv);
+}
+
+static struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_NET, VIRTIO_DEV_ANY_ID },
+	{ 0 },
+};
+
+static struct virtio_driver virtio_net = {
+	.driver.name =	KBUILD_MODNAME,
+	.driver.owner =	THIS_MODULE,
+	.id_table =	id_table,
+	.probe =	virtnet_probe,
+	.remove =	__devexit_p(virtnet_remove),
+};
+
+static int __init init(void)
+{
+	return register_virtio_driver(&virtio_net);
+}
+
+static void __exit fini(void)
+{
+	unregister_virtio_driver(&virtio_net);
+}
+module_init(init);
+module_exit(fini);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_DESCRIPTION("Virtio network driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index c141a26..9d9ff76 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -49,7 +49,6 @@
 #include "pio.h"
 #include "sysfs.h"
 #include "xmit.h"
-#include "sysfs.h"
 #include "lo.h"
 #include "pcmcia.h"
 
@@ -3495,7 +3494,7 @@
 	struct b43_wl *wl = hw_to_b43_wl(hw);
 	struct b43_wldev *dev = wl->current_dev;
 	int did_init = 0;
-	int err;
+	int err = 0;
 
 	mutex_lock(&wl->mutex);
 
@@ -3521,7 +3520,7 @@
 	return err;
 }
 
-void b43_stop(struct ieee80211_hw *hw)
+static void b43_stop(struct ieee80211_hw *hw)
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
 	struct b43_wldev *dev = wl->current_dev;
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index f074951..d09479e 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -3306,7 +3306,7 @@
 	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
 	struct b43legacy_wldev *dev = wl->current_dev;
 	int did_init = 0;
-	int err;
+	int err = 0;
 
 	mutex_lock(&wl->mutex);
 
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
index 8f198be..cb51dc5 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
@@ -29,7 +29,7 @@
 #include "bcm43xx_radio.h"
 #include "bcm43xx.h"
 
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 
 static void bcm43xx_led_changestate(struct bcm43xx_led *led)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
index 9ecf2bf..47c135a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
@@ -87,7 +87,7 @@
 
 /* RX header as received from the hardware. */
 struct bcm43xx_rxhdr {
-	/* Frame Length. Must be generated explicitely in PIO mode. */
+	/* Frame Length. Must be generated explicitly in PIO mode. */
 	__le16 frame_length;
 	PAD_BYTES(2);
 	/* Flags field 1 */
diff --git a/drivers/net/wireless/hostap/hostap_common.h b/drivers/net/wireless/hostap/hostap_common.h
index ceb7f1e..517f898 100644
--- a/drivers/net/wireless/hostap/hostap_common.h
+++ b/drivers/net/wireless/hostap/hostap_common.h
@@ -4,9 +4,6 @@
 #include <linux/types.h>
 #include <linux/if_ether.h>
 
-#define BIT(x) (1 << (x))
-
-
 /* IEEE 802.11 defines */
 
 /* Information Element IDs */
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 40f516d..d8f5efc 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -2920,7 +2920,7 @@
 
 	printk(KERN_DEBUG "%s: process %d (%s) used deprecated iwpriv monitor "
 	       "- update software to use iwconfig mode monitor\n",
-	       dev->name, current->pid, current->comm);
+	       dev->name, task_pid_nr(current), current->comm);
 
 	/* Backward compatibility code - this can be removed at some point */
 
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 2d46a16..a6c7904 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -1858,14 +1858,6 @@
 
 	modify_acceptable_latency("ipw2100", INFINITE_LATENCY);
 
-#ifdef ACPI_CSTATE_LIMIT_DEFINED
-	if (priv->config & CFG_C3_DISABLED) {
-		IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
-		acpi_set_cstate_limit(priv->cstate_limit);
-		priv->config &= ~CFG_C3_DISABLED;
-	}
-#endif
-
 	/* We have to signal any supplicant if we are disassociating */
 	if (associated)
 		wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
@@ -2091,26 +2083,52 @@
 	/* RF_KILL is now enabled (else we wouldn't be here) */
 	priv->status |= STATUS_RF_KILL_HW;
 
-#ifdef ACPI_CSTATE_LIMIT_DEFINED
-	if (priv->config & CFG_C3_DISABLED) {
-		IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
-		acpi_set_cstate_limit(priv->cstate_limit);
-		priv->config &= ~CFG_C3_DISABLED;
-	}
-#endif
-
 	/* Make sure the RF Kill check timer is running */
 	priv->stop_rf_kill = 0;
 	cancel_delayed_work(&priv->rf_kill);
 	queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ));
 }
 
+static void send_scan_event(void *data)
+{
+	struct ipw2100_priv *priv = data;
+	union iwreq_data wrqu;
+
+	wrqu.data.length = 0;
+	wrqu.data.flags = 0;
+	wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
+}
+
+static void ipw2100_scan_event_later(struct work_struct *work)
+{
+	send_scan_event(container_of(work, struct ipw2100_priv,
+					scan_event_later.work));
+}
+
+static void ipw2100_scan_event_now(struct work_struct *work)
+{
+	send_scan_event(container_of(work, struct ipw2100_priv,
+					scan_event_now));
+}
+
 static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
 {
 	IPW_DEBUG_SCAN("scan complete\n");
 	/* Age the scan results... */
 	priv->ieee->scans++;
 	priv->status &= ~STATUS_SCANNING;
+
+	/* Only userspace-requested scan completion events go out immediately */
+	if (!priv->user_requested_scan) {
+		if (!delayed_work_pending(&priv->scan_event_later))
+			queue_delayed_work(priv->workqueue,
+					&priv->scan_event_later,
+					round_jiffies(msecs_to_jiffies(4000)));
+	} else {
+		priv->user_requested_scan = 0;
+		cancel_delayed_work(&priv->scan_event_later);
+		queue_work(priv->workqueue, &priv->scan_event_now);
+	}
 }
 
 #ifdef CONFIG_IPW2100_DEBUG
@@ -2329,23 +2347,10 @@
 	u32 match, reg;
 	int j;
 #endif
-#ifdef ACPI_CSTATE_LIMIT_DEFINED
-	int limit;
-#endif
 
 	IPW_DEBUG_INFO(": PCI latency error detected at 0x%04zX.\n",
 		       i * sizeof(struct ipw2100_status));
 
-#ifdef ACPI_CSTATE_LIMIT_DEFINED
-	IPW_DEBUG_INFO(": Disabling C3 transitions.\n");
-	limit = acpi_get_cstate_limit();
-	if (limit > 2) {
-		priv->cstate_limit = limit;
-		acpi_set_cstate_limit(2);
-		priv->config |= CFG_C3_DISABLED;
-	}
-#endif
-
 #ifdef IPW2100_DEBUG_C3
 	/* Halt the fimrware so we can get a good image */
 	write_register(priv->net_dev, IPW_REG_RESET_REG,
@@ -4378,6 +4383,7 @@
 		cancel_delayed_work(&priv->wx_event_work);
 		cancel_delayed_work(&priv->hang_check);
 		cancel_delayed_work(&priv->rf_kill);
+		cancel_delayed_work(&priv->scan_event_later);
 		destroy_workqueue(priv->workqueue);
 		priv->workqueue = NULL;
 	}
@@ -6041,7 +6047,7 @@
 	 * ends up causing problems.  So, we just handle
 	 * the WX extensions through the ipw2100_ioctl interface */
 
-	/* memset() puts everything to 0, so we only have explicitely set
+	/* memset() puts everything to 0, so we only have explicitly set
 	 * those values that need to be something else */
 
 	/* If power management is turned on, default to AUTO mode */
@@ -6121,6 +6127,8 @@
 	INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work);
 	INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check);
 	INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill);
+	INIT_WORK(&priv->scan_event_now, ipw2100_scan_event_now);
+	INIT_DELAYED_WORK(&priv->scan_event_later, ipw2100_scan_event_later);
 
 	tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
 		     ipw2100_irq_tasklet, (unsigned long)priv);
@@ -7425,6 +7433,8 @@
 	}
 
 	IPW_DEBUG_WX("Initiating scan...\n");
+
+	priv->user_requested_scan = 1;
 	if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
 		IPW_DEBUG_WX("Start scan failed.\n");
 
@@ -7499,7 +7509,7 @@
 	switch (wrqu->power.flags & IW_POWER_MODE) {
 	case IW_POWER_ON:	/* If not specified */
 	case IW_POWER_MODE:	/* If set all mask */
-	case IW_POWER_ALL_R:	/* If explicitely state all */
+	case IW_POWER_ALL_R:	/* If explicitly state all */
 		break;
 	default:		/* Otherwise we don't support it */
 		IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index de7d384..bbf1ddc 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -479,7 +479,6 @@
 #define CFG_ASSOCIATE           (1<<6)
 #define CFG_FIXED_RATE          (1<<7)
 #define CFG_ADHOC_CREATE        (1<<8)
-#define CFG_C3_DISABLED         (1<<9)
 #define CFG_PASSIVE_SCAN        (1<<10)
 #ifdef CONFIG_IPW2100_MONITOR
 #define CFG_CRC_CHECK           (1<<11)
@@ -508,7 +507,6 @@
 	u8 bssid[ETH_ALEN];
 	u8 channel;
 	int last_mode;
-	int cstate_limit;
 
 	unsigned long connect_start;
 	unsigned long last_reset;
@@ -588,6 +586,10 @@
 	struct delayed_work wx_event_work;
 	struct delayed_work hang_check;
 	struct delayed_work rf_kill;
+	struct work_struct scan_event_now;
+	struct delayed_work scan_event_later;
+
+	int user_requested_scan;
 
 	u32 interrupts;
 	int tx_interrupts;
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index feb8fcb..e3c8284 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -9603,7 +9603,7 @@
 	switch (wrqu->power.flags & IW_POWER_MODE) {
 	case IW_POWER_ON:	/* If not specified */
 	case IW_POWER_MODE:	/* If set all mask */
-	case IW_POWER_ALL_R:	/* If explicitely state all */
+	case IW_POWER_ALL_R:	/* If explicitly state all */
 		break;
 	default:		/* Otherwise we don't support it */
 		IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index f4aabcf..262ab0b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -37,9 +37,6 @@
 
 #include <linux/workqueue.h>
 
-#include <net/mac80211.h>
-#include <linux/wireless.h>
-
 #define IWL 3945
 
 #include "../net/mac80211/ieee80211_rate.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index acb3875..19bcb01 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -38,7 +38,6 @@
 #include <net/mac80211.h>
 
 #include <linux/etherdevice.h>
-#include <linux/delay.h>
 
 #define IWL 3945
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 287c757..8dc78c0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -36,9 +36,6 @@
 
 #include <linux/workqueue.h>
 
-#include <net/mac80211.h>
-#include <linux/wireless.h>
-
 #define IWL 4965
 
 #include "../net/mac80211/ieee80211_rate.h"
@@ -2024,12 +2021,18 @@
 static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
 				struct iwl_rate *mcs, int index)
 {
-	const u32 cck_rate = 0x820A;
+	u32 base_rate;
+
+	if (rs_priv->phymode == (u8) MODE_IEEE80211A)
+		base_rate = 0x800D;
+	else
+		base_rate = 0x820A;
+
 	if (rs_priv->dbg_fixed.rate_n_flags) {
 		if (index < 12)
 			mcs->rate_n_flags = rs_priv->dbg_fixed.rate_n_flags;
 		else
-			mcs->rate_n_flags = cck_rate;
+			mcs->rate_n_flags = base_rate;
 		IWL_DEBUG_RATE("Fixed rate ON\n");
 		return;
 	}
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index b50d202..557deeb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -35,9 +35,7 @@
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
 #include <net/mac80211.h>
-#include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/delay.h>
 
 #define IWL 4965
 
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 75e3b5c..83019d1 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -48,8 +48,6 @@
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
 #include <linux/firmware.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 
@@ -1749,21 +1747,22 @@
  * return : set the bit for each supported rate insert in ie
  */
 static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
-				    u16 basic_rate, int max_count)
+				    u16 basic_rate, int *left)
 {
 	u16 ret_rates = 0, bit;
 	int i;
-	u8 *rates;
-
-	rates = &(ie[1]);
+	u8 *cnt = ie;
+	u8 *rates = ie + 1;
 
 	for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
 		if (bit & supported_rate) {
 			ret_rates |= bit;
-			rates[*ie] = iwl_rates[i].ieee |
-			    ((bit & basic_rate) ? 0x80 : 0x00);
-			*ie = *ie + 1;
-			if (*ie >= max_count)
+			rates[*cnt] = iwl_rates[i].ieee |
+				((bit & basic_rate) ? 0x80 : 0x00);
+			(*cnt)++;
+			(*left)--;
+			if ((*left <= 0) ||
+			    (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
 				break;
 		}
 	}
@@ -1780,7 +1779,7 @@
 {
 	int len = 0;
 	u8 *pos = NULL;
-	u16 ret_rates;
+	u16 active_rates, ret_rates, cck_rates;
 
 	/* Make sure there is enough space for the probe request,
 	 * two mandatory IEs and the data */
@@ -1825,19 +1824,27 @@
 	left -= 2;
 	if (left < 0)
 		return 0;
+
 	/* ... fill it in... */
 	*pos++ = WLAN_EID_SUPP_RATES;
 	*pos = 0;
-	ret_rates = priv->active_rate = priv->rates_mask;
+
+	priv->active_rate = priv->rates_mask;
+	active_rates = priv->active_rate;
 	priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
 
-	iwl_supported_rate_to_ie(pos, priv->active_rate,
-				 priv->active_rate_basic, left);
+	cck_rates = IWL_CCK_RATES_MASK & active_rates;
+	ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
+			priv->active_rate_basic, &left);
+	active_rates &= ~ret_rates;
+
+	ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
+				 priv->active_rate_basic, &left);
+	active_rates &= ~ret_rates;
+
 	len += 2 + *pos;
 	pos += (*pos) + 1;
-	ret_rates = ~ret_rates & priv->active_rate;
-
-	if (ret_rates == 0)
+	if (active_rates == 0)
 		goto fill_end;
 
 	/* fill in supported extended rate */
@@ -1848,7 +1855,8 @@
 	/* ... fill it in... */
 	*pos++ = WLAN_EID_EXT_SUPP_RATES;
 	*pos = 0;
-	iwl_supported_rate_to_ie(pos, ret_rates, priv->active_rate_basic, left);
+	iwl_supported_rate_to_ie(pos, active_rates,
+				 priv->active_rate_basic, &left);
 	if (*pos > 0)
 		len += 2 + *pos;
 
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index b1a6e39..5e12792 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -48,8 +48,6 @@
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
 #include <linux/firmware.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 
@@ -1802,21 +1800,22 @@
  * return : set the bit for each supported rate insert in ie
  */
 static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
-				    u16 basic_rate, int max_count)
+				    u16 basic_rate, int *left)
 {
 	u16 ret_rates = 0, bit;
 	int i;
-	u8 *rates;
-
-	rates = &(ie[1]);
+	u8 *cnt = ie;
+	u8 *rates = ie + 1;
 
 	for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
 		if (bit & supported_rate) {
 			ret_rates |= bit;
-			rates[*ie] = iwl_rates[i].ieee |
-			    ((bit & basic_rate) ? 0x80 : 0x00);
-			*ie = *ie + 1;
-			if (*ie >= max_count)
+			rates[*cnt] = iwl_rates[i].ieee |
+				((bit & basic_rate) ? 0x80 : 0x00);
+			(*cnt)++;
+			(*left)--;
+			if ((*left <= 0) ||
+			    (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
 				break;
 		}
 	}
@@ -1839,7 +1838,7 @@
 {
 	int len = 0;
 	u8 *pos = NULL;
-	u16 ret_rates;
+	u16 active_rates, ret_rates, cck_rates;
 
 	/* Make sure there is enough space for the probe request,
 	 * two mandatory IEs and the data */
@@ -1884,19 +1883,27 @@
 	left -= 2;
 	if (left < 0)
 		return 0;
+
 	/* ... fill it in... */
 	*pos++ = WLAN_EID_SUPP_RATES;
 	*pos = 0;
-	ret_rates = priv->active_rate = priv->rates_mask;
+
+	priv->active_rate = priv->rates_mask;
+	active_rates = priv->active_rate;
 	priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
 
-	iwl_supported_rate_to_ie(pos, priv->active_rate,
-				 priv->active_rate_basic, left);
+	cck_rates = IWL_CCK_RATES_MASK & active_rates;
+	ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
+			priv->active_rate_basic, &left);
+	active_rates &= ~ret_rates;
+
+	ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
+				 priv->active_rate_basic, &left);
+	active_rates &= ~ret_rates;
+
 	len += 2 + *pos;
 	pos += (*pos) + 1;
-	ret_rates = ~ret_rates & priv->active_rate;
-
-	if (ret_rates == 0)
+	if (active_rates == 0)
 		goto fill_end;
 
 	/* fill in supported extended rate */
@@ -1907,7 +1914,8 @@
 	/* ... fill it in... */
 	*pos++ = WLAN_EID_EXT_SUPP_RATES;
 	*pos = 0;
-	iwl_supported_rate_to_ie(pos, ret_rates, priv->active_rate_basic, left);
+	iwl_supported_rate_to_ie(pos, active_rates,
+				 priv->active_rate_basic, &left);
 	if (*pos > 0)
 		len += 2 + *pos;
 
@@ -4494,13 +4502,13 @@
  * Conversion assumes that levels are voltages (20*log), not powers (10*log). */
 int iwl_calc_db_from_ratio(int sig_ratio)
 {
-	/* Anything above 1000:1 just report as 60 dB */
-	if (sig_ratio > 1000)
+	/* 1000:1 or higher just report as 60 dB */
+	if (sig_ratio >= 1000)
 		return 60;
 
-	/* Above 100:1, divide by 10 and use table,
+	/* 100:1 or higher, divide by 10 and use table,
 	 *   add 20 dB to make up for divide by 10 */
-	if (sig_ratio > 100)
+	if (sig_ratio >= 100)
 		return (20 + (int)ratio2dB[sig_ratio/10]);
 
 	/* We shouldn't see this */
diff --git a/drivers/net/wireless/iwlwifi/iwlwifi.h b/drivers/net/wireless/iwlwifi/iwlwifi.h
index e0b97c3..432ce88 100644
--- a/drivers/net/wireless/iwlwifi/iwlwifi.h
+++ b/drivers/net/wireless/iwlwifi/iwlwifi.h
@@ -39,18 +39,13 @@
 /* Hardware specific file defines the PCI IDs table for that hardware module */
 extern struct pci_device_id iwl_hw_card_ids[];
 
+#include "iwl-hw.h"
 #if IWL == 3945
-
 #define DRV_NAME	"iwl3945"
-#include "iwl-hw.h"
 #include "iwl-3945-hw.h"
-
 #elif IWL == 4965
-
 #define DRV_NAME        "iwl4965"
-#include "iwl-hw.h"
 #include "iwl-4965-hw.h"
-
 #endif
 
 #include "iwl-prph.h"
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index c2d71af..2402cb8 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -4,18 +4,18 @@
  * Version:       0.4.1
  * Description:   Netwave AirSurfer Wireless LAN PC Card driver
  * Status:        Experimental.
- * Authors:       John Markus Bjørndalen <johnm@cs.uit.no>
+ * Authors:       John Markus Bjørndalen <johnm@cs.uit.no>
  *                Dag Brattli <dagb@cs.uit.no>
  *                David Hinds <dahinds@users.sourceforge.net>
  * Created at:    A long time ago!
  * Modified at:   Mon Nov 10 11:54:37 1997
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997 University of Tromsø, Norway
+ *     Copyright (c) 1997 University of Tromsø, Norway
  *
  * Revision History:
  *
- *   08-Nov-97 15:14:47   John Markus Bjørndalen <johnm@cs.uit.no>
+ *   08-Nov-97 15:14:47   John Markus Bjørndalen <johnm@cs.uit.no>
  *    - Fixed some bugs in netwave_rx and cleaned it up a bit. 
  *      (One of the bugs would have destroyed packets when receiving
  *      multiple packets per interrupt). 
@@ -158,7 +158,7 @@
 module_param(pc_debug, int, 0);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjørndalen)\n";
+"netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjørndalen)\n";
 #else
 #define DEBUG(n, args...)
 #endif
diff --git a/drivers/net/wireless/p54common.c b/drivers/net/wireless/p54common.c
index 2c63cf0..1437db0 100644
--- a/drivers/net/wireless/p54common.c
+++ b/drivers/net/wireless/p54common.c
@@ -577,7 +577,7 @@
 	struct p54_tx_control_filter *filter;
 
 	hdr = kzalloc(sizeof(*hdr) + sizeof(*filter) +
-		      priv->tx_hdr_len, GFP_KERNEL);
+		      priv->tx_hdr_len, GFP_ATOMIC);
 	if (!hdr)
 		return -ENOMEM;
 
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index bb6f46c..ff399f8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -550,7 +550,7 @@
 			/*
 			 * Check if we need to set the Length Extension
 			 */
-			if (bitrate == 110 && residual <= 3)
+			if (bitrate == 110 && residual <= 30)
 				desc.service |= 0x80;
 		}
 
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 3e42759..46c8c08 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2029,6 +2029,7 @@
 	{ USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x050d, 0x905b), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* Billionton */
 	{ USB_DEVICE(0x1631, 0xc019), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* Buffalo */
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 0ef887d..de61c8f 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -131,7 +131,8 @@
 	struct rtl8187_tx_hdr *hdr;
 	struct rtl8187_tx_info *info;
 	struct urb *urb;
-	u32 tmp;
+	__le16 rts_dur = 0;
+	u32 flags;
 
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!urb) {
@@ -139,24 +140,24 @@
 		return 0;
 	}
 
-	hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
-	tmp = skb->len - sizeof(*hdr);
-	tmp |= RTL8187_TX_FLAG_NO_ENCRYPT;
-	tmp |= control->rts_cts_rate << 19;
-	tmp |= control->tx_rate << 24;
-	if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb))
-		tmp |= RTL8187_TX_FLAG_MORE_FRAG;
+	flags = skb->len;
+	flags |= RTL8187_TX_FLAG_NO_ENCRYPT;
+	flags |= control->rts_cts_rate << 19;
+	flags |= control->tx_rate << 24;
+	if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data))
+		flags |= RTL8187_TX_FLAG_MORE_FRAG;
 	if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
-		tmp |= RTL8187_TX_FLAG_RTS;
-		hdr->rts_duration =
-			ieee80211_rts_duration(dev, priv->if_id, skb->len, control);
+		flags |= RTL8187_TX_FLAG_RTS;
+		rts_dur = ieee80211_rts_duration(dev, priv->if_id, skb->len, control);
 	}
 	if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
-		tmp |= RTL8187_TX_FLAG_CTS;
-	hdr->flags = cpu_to_le32(tmp);
+		flags |= RTL8187_TX_FLAG_CTS;
+
+	hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
+	hdr->flags = cpu_to_le32(flags);
 	hdr->len = 0;
-	tmp = control->retry_limit << 8;
-	hdr->retry = cpu_to_le32(tmp);
+	hdr->rts_duration = rts_dur;
+	hdr->retry = cpu_to_le32(control->retry_limit << 8);
 
 	info = (struct rtl8187_tx_info *)skb->cb;
 	info->control = kmemdup(control, sizeof(*control), GFP_ATOMIC);
@@ -587,8 +588,6 @@
 
 	*total_flags = 0;
 
-	if (changed_flags & FIF_PROMISC_IN_BSS)
-		priv->rx_conf ^= RTL818X_RX_CONF_NICMAC;
 	if (changed_flags & FIF_ALLMULTI)
 		priv->rx_conf ^= RTL818X_RX_CONF_MULTICAST;
 	if (changed_flags & FIF_FCSFAIL)
@@ -601,8 +600,6 @@
 	if (mc_count > 0)
 		priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
 
-	if (priv->rx_conf & RTL818X_RX_CONF_NICMAC)
-		*total_flags |= FIF_PROMISC_IN_BSS;
 	if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
 		*total_flags |= FIF_ALLMULTI;
 	if (priv->rx_conf & RTL818X_RX_CONF_FCS)
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 935b144..d5c0c66 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -327,8 +327,8 @@
 			memcpy(skb_put(skb, 6), &data[datalen-8], 6);
 			memcpy(skb_put(skb, 2), &data[datalen-24], 2);
 			memcpy(skb_put(skb, len), data, len);
-			skb->dev->last_rx = jiffies;
 			skb->protocol = eth_type_trans(skb, zd->dev);
+			skb->dev->last_rx = jiffies;
 			zd->stats.rx_packets++;
 			zd->stats.rx_bytes += skb->len;
 			netif_rx(skb);
@@ -384,8 +384,8 @@
 			memcpy(skb_put(skb, 2), &data[6], 2);
 			memcpy(skb_put(skb, len), data+8, len);
 		}
-		skb->dev->last_rx = jiffies;
 		skb->protocol = eth_type_trans(skb, zd->dev);
+		skb->dev->last_rx = jiffies;
 		zd->stats.rx_packets++;
 		zd->stats.rx_bytes += skb->len;
 		netif_rx(skb);
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index b0684f9..c755b69 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -1044,14 +1044,17 @@
 static void disconnect(struct usb_interface *intf)
 {
 	struct net_device *netdev = zd_intf_to_netdev(intf);
-	struct zd_mac *mac = zd_netdev_mac(netdev);
-	struct zd_usb *usb = &mac->chip.usb;
+	struct zd_mac *mac;
+	struct zd_usb *usb;
 
 	/* Either something really bad happened, or we're just dealing with
 	 * a DEVICE_INSTALLER. */
 	if (netdev == NULL)
 		return;
 
+	mac = zd_netdev_mac(netdev);
+	usb = &mac->chip.usb;
+
 	dev_dbg_f(zd_usb_dev(usb), "\n");
 
 	zd_netdev_disconnect(netdev);
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 7fd505c..2a8fc43 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1526,7 +1526,7 @@
 
 	if (!feature_rx_copy) {
 		dev_info(&dev->dev,
-			 "backend does not support copying recieve path");
+			 "backend does not support copying receive path\n");
 		return -ENODEV;
 	}
 
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 864f09f..b47bb2d 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -12,6 +12,7 @@
  *
  */
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
@@ -94,3 +95,23 @@
 	bus->resume = of_platform_device_resume;
 	return bus_register(bus);
 }
+
+int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
+{
+	/* initialize common driver fields */
+	if (!drv->driver.name)
+		drv->driver.name = drv->name;
+	if (!drv->driver.owner)
+		drv->driver.owner = drv->owner;
+	drv->driver.bus = bus;
+
+	/* register with core */
+	return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL(of_register_driver);
+
+void of_unregister_driver(struct of_platform_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(of_unregister_driver);
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index b3c4dbf..7c60cbd 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -42,6 +42,7 @@
 #include <linux/reboot.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/scatterlist.h>
 
 #include <asm/byteorder.h>
 #include <asm/cache.h>		/* for L1_CACHE_BYTES */
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 5b86ee5..5eace9e 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -557,44 +557,6 @@
 #ifdef CONFIG_64BIT
 
 /*
-** Determine if a device is already configured.
-** If so, reserve it resources.
-**
-** Read PCI cfg command register and see if I/O or MMIO is enabled.
-** PAT has to enable the devices it's using.
-**
-** Note: resources are fixed up before we try to claim them.
-*/
-static void
-lba_claim_dev_resources(struct pci_dev *dev)
-{
-	u16 cmd;
-	int i, srch_flags;
-
-	(void) pci_read_config_word(dev, PCI_COMMAND, &cmd);
-
-	srch_flags  = (cmd & PCI_COMMAND_IO) ? IORESOURCE_IO : 0;
-	if (cmd & PCI_COMMAND_MEMORY)
-		srch_flags |= IORESOURCE_MEM;
-
-	if (!srch_flags)
-		return;
-
-	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-		if (dev->resource[i].flags & srch_flags) {
-			pci_claim_resource(dev, i);
-			DBG("   claimed %s %d [%lx,%lx]/%lx\n",
-				pci_name(dev), i,
-				dev->resource[i].start,
-				dev->resource[i].end,
-				dev->resource[i].flags
-				);
-		}
-	}
-}
-
-
-/*
  * truncate_pat_collision:  Deal with overlaps or outright collisions
  *			between PAT PDC reported ranges.
  *
@@ -653,7 +615,6 @@
 }
 
 #else
-#define lba_claim_dev_resources(dev) do { } while (0)
 #define truncate_pat_collision(r,n)  (0)
 #endif
 
@@ -684,8 +645,12 @@
 	** pci_alloc_primary_bus() mangles this.
 	*/
 	if (bus->self) {
+		int i;
 		/* PCI-PCI Bridge */
 		pci_read_bridge_bases(bus);
+		for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
+			pci_claim_resource(bus->self, i);
+		}
 	} else {
 		/* Host-PCI Bridge */
 		int err, i;
@@ -803,6 +768,9 @@
 				DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX",
 					res->flags, res->start, res->end);
 			}
+			if ((i != PCI_ROM_RESOURCE) ||
+			    (res->flags & IORESOURCE_ROM_ENABLE))
+				pci_claim_resource(dev, i);
 		}
 
 #ifdef FBB_SUPPORT
@@ -814,11 +782,6 @@
 		bus->bridge_ctl &= ~(status & PCI_STATUS_FAST_BACK);
 #endif
 
-		if (is_pdc_pat()) {
-			/* Claim resources for PDC's devices */
-			lba_claim_dev_resources(dev);
-		}
-
                 /*
 		** P2PB's have no IRQs. ignore them.
 		*/
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
index fc4bde2..ebb09e9 100644
--- a/drivers/parisc/pdc_stable.c
+++ b/drivers/parisc/pdc_stable.c
@@ -282,6 +282,7 @@
 	unsigned short i;
 	char in[count+1], *temp;
 	struct device *dev;
+	int ret;
 
 	if (!entry || !buf || !count)
 		return -EINVAL;
@@ -333,7 +334,9 @@
 	
 	/* Update the symlink to the real device */
 	sysfs_remove_link(&entry->kobj, "device");
-	sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+	ret = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+	WARN_ON(ret);
+
 	write_unlock(&entry->rw_lock);
 	
 	printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" path to \"%s\"\n",
@@ -1003,8 +1006,10 @@
 		entry->ready = 2;
 		
 		/* Add a nice symlink to the real device */
-		if (entry->dev)
-			sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+		if (entry->dev) {
+			err = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+			WARN_ON(err);
+		}
 
 		write_unlock(&entry->rw_lock);
 	}
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index d044c48..e527a0e 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -28,6 +28,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/pci.h>
+#include <linux/scatterlist.h>
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
@@ -1909,8 +1910,8 @@
 			global_ioc_cnt *= 2;
 	}
 
-	printk(KERN_INFO "%s found %s at 0x%lx\n",
-		MODULE_NAME, version, dev->hpa.start);
+	printk(KERN_INFO "%s found %s at 0x%llx\n",
+		MODULE_NAME, version, (unsigned long long)dev->hpa.start);
 
 	sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL);
 	if (!sba_dev) {
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index 38cdf9f..1e8d2d1 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -155,6 +155,7 @@
 	struct superio_device *sio = &sio_dev;
 	struct pci_dev *pdev = sio->lio_pdev;
 	u16 word;
+	int ret;
 
 	if (sio->suckyio_irq_enabled)
 		return;
@@ -200,7 +201,8 @@
 	pci_write_config_word (pdev, PCI_COMMAND, word);
 
 	pci_set_master (pdev);
-	pci_enable_device(pdev);
+	ret = pci_enable_device(pdev);
+	BUG_ON(ret < 0);	/* not too much we can do about this... */
 
 	/*
 	 * Next project is programming the onboard interrupt controllers.
diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c
index ff9f344..5bbff20 100644
--- a/drivers/parport/daisy.c
+++ b/drivers/parport/daisy.c
@@ -275,35 +275,6 @@
 	parport_unregister_device(dev);
 }
 
-/**
- *	parport_device_num - convert device coordinates
- *	@parport: parallel port number
- *	@mux: multiplexor port number (-1 for no multiplexor)
- *	@daisy: daisy chain address (-1 for no daisy chain address)
- *
- *	This tries to locate a device on the given parallel port,
- *	multiplexor port and daisy chain address, and returns its
- *	device number or %-ENXIO if no device with those coordinates
- *	exists.
- **/
-
-int parport_device_num(int parport, int mux, int daisy)
-{
-	int res = -ENXIO;
-	struct daisydev *dev;
-
-	spin_lock(&topology_lock);
-	dev = topology;
-	while (dev && dev->port->portnum != parport &&
-	       dev->port->muxport != mux && dev->daisy != daisy)
-		dev = dev->next;
-	if (dev)
-		res = dev->devnum;
-	spin_unlock(&topology_lock);
-
-	return res;
-}
-
 /* Send a daisy-chain-style CPP command packet. */
 static int cpp_daisy(struct parport *port, int cmd)
 {
diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c
index bdbdab9..ed82e41 100644
--- a/drivers/parport/procfs.c
+++ b/drivers/parport/procfs.c
@@ -237,7 +237,7 @@
 #define PARPORT_PARPORT_DIR(CHILD) { .ctl_name = DEV_PARPORT, .procname = "parport", \
                                      .mode = 0555, .child = CHILD }
 #define PARPORT_DEV_DIR(CHILD) { .ctl_name = CTL_DEV, .procname = "dev", .mode = 0555, .child = CHILD }
-#define PARPORT_DEVICES_ROOT_DIR  { .ctl_name = DEV_PARPORT_DEVICES, .procname = "devices", \
+#define PARPORT_DEVICES_ROOT_DIR  {  .procname = "devices", \
                                     .mode = 0555, .child = NULL }
 
 static const unsigned long parport_min_timeslice_value =
@@ -266,7 +266,6 @@
 	.sysctl_header = NULL,
         {
 		{
-			.ctl_name	= DEV_PARPORT_SPINTIME,
 			.procname	= "spintime",
 			.data		= NULL,
 			.maxlen		= sizeof(int),
@@ -276,7 +275,6 @@
 			.extra2		= (void*) &parport_max_spintime_value
 		},
 		{
-			.ctl_name	= DEV_PARPORT_BASE_ADDR,
 			.procname	= "base-addr",
 			.data		= NULL,
 			.maxlen		= 0,
@@ -284,7 +282,6 @@
 			.proc_handler	= &do_hardware_base_addr
 		},
 		{
-			.ctl_name	= DEV_PARPORT_IRQ,
 			.procname	= "irq",
 			.data		= NULL,
 			.maxlen		= 0,
@@ -292,7 +289,6 @@
 			.proc_handler	= &do_hardware_irq
 		},
 		{
-			.ctl_name	= DEV_PARPORT_DMA,
 			.procname	= "dma",
 			.data		= NULL,
 			.maxlen		= 0,
@@ -300,7 +296,6 @@
 			.proc_handler	= &do_hardware_dma
 		},
 		{
-			.ctl_name	= DEV_PARPORT_MODES,
 			.procname	= "modes",
 			.data		= NULL,
 			.maxlen		= 0,
@@ -310,7 +305,6 @@
 		PARPORT_DEVICES_ROOT_DIR,
 #ifdef CONFIG_PARPORT_1284
 		{
-			.ctl_name	= DEV_PARPORT_AUTOPROBE,
 			.procname	= "autoprobe",
 			.data		= NULL,
 			.maxlen		= 0,
@@ -318,7 +312,6 @@
 			.proc_handler	= &do_autoprobe
 		},
 		{
-			.ctl_name	= DEV_PARPORT_AUTOPROBE + 1,
 			.procname	= "autoprobe0",
 			.data		= NULL,
 			.maxlen		= 0,
@@ -326,7 +319,6 @@
 			.proc_handler	=  &do_autoprobe
 		},
 		{
-			.ctl_name	= DEV_PARPORT_AUTOPROBE + 2,
 			.procname	= "autoprobe1",
 			.data		= NULL,
 			.maxlen		= 0,
@@ -334,7 +326,6 @@
 			.proc_handler	= &do_autoprobe
 		},
 		{
-			.ctl_name	= DEV_PARPORT_AUTOPROBE + 3,
 			.procname	= "autoprobe2",
 			.data		= NULL,
 			.maxlen		= 0,
@@ -342,7 +333,6 @@
 			.proc_handler	= &do_autoprobe
 		},
 		{
-			.ctl_name	= DEV_PARPORT_AUTOPROBE + 4,
 			.procname	= "autoprobe3",
 			.data		= NULL,
 			.maxlen		= 0,
@@ -354,7 +344,6 @@
 	},
 	{
 		{
-			.ctl_name	= DEV_PARPORT_DEVICES_ACTIVE,
 			.procname	= "active",
 			.data		= NULL,
 			.maxlen		= 0,
@@ -393,7 +382,6 @@
 	.sysctl_header = NULL,
 	{
 		{
-			.ctl_name 	= DEV_PARPORT_DEVICE_TIMESLICE,
 			.procname 	= "timeslice",
 			.data		= NULL,
 			.maxlen		= sizeof(int),
@@ -449,7 +437,6 @@
 	.sysctl_header	= NULL,
 	{
 		{
-			.ctl_name	= DEV_PARPORT_DEFAULT_TIMESLICE,
 			.procname	= "timeslice",
 			.data		= &parport_default_timeslice,
 			.maxlen		= sizeof(parport_default_timeslice),
@@ -459,7 +446,6 @@
 			.extra2		= (void*) &parport_max_timeslice_value
 		},
 		{
-			.ctl_name	= DEV_PARPORT_DEFAULT_SPINTIME,
 			.procname	= "spintime",
 			.data		= &parport_default_spintime,
 			.maxlen		= sizeof(parport_default_spintime),
@@ -502,7 +488,7 @@
 
 	t->device_dir[0].extra1 = port;
 
-	for (i = 0; i < 8; i++)
+	for (i = 0; i < 5; i++)
 		t->vars[i].extra1 = port;
 
 	t->vars[0].data = &port->spintime;
@@ -512,7 +498,7 @@
 		t->vars[6 + i].extra2 = &port->probe_info[i];
 
 	t->port_dir[0].procname = port->name;
-	t->port_dir[0].ctl_name = port->number + 1; /* nb 0 isn't legal here */
+	t->port_dir[0].ctl_name = 0;
 
 	t->port_dir[0].child = t->vars;
 	t->parport_dir[0].child = t->port_dir;
@@ -551,26 +537,12 @@
 	t->dev_dir[0].child = t->parport_dir;
 	t->parport_dir[0].child = t->port_dir;
 	t->port_dir[0].procname = port->name;
-	t->port_dir[0].ctl_name = port->number + 1; /* nb 0 isn't legal here */
+	t->port_dir[0].ctl_name = 0;
 	t->port_dir[0].child = t->devices_root_dir;
 	t->devices_root_dir[0].child = t->device_dir;
 
-#ifdef CONFIG_PARPORT_1284
-
-	t->device_dir[0].ctl_name =
-		parport_device_num(port->number, port->muxport,
-				   device->daisy)
-		+ 1;  /* nb 0 isn't legal here */ 
-
-#else /* No IEEE 1284 support */
-
-	/* parport_device_num isn't available. */
-	t->device_dir[0].ctl_name = 1;
-	
-#endif /* IEEE 1284 support or not */
-
+	t->device_dir[0].ctl_name = 0;
 	t->device_dir[0].procname = device->name;
-	t->device_dir[0].extra1 = device;
 	t->device_dir[0].child = t->vars;
 	t->vars[0].data = &device->timeslice;
 
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 006054a..5550556 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -20,6 +20,9 @@
 # Build the Hypertransport interrupt support
 obj-$(CONFIG_HT_IRQ) += htirq.o
 
+# Build Intel IOMMU support
+obj-$(CONFIG_DMAR) += dmar.o iova.o intel-iommu.o
+
 #
 # Some architectures use the generic PCI setup functions
 #
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
new file mode 100644
index 0000000..5dfdfda
--- /dev/null
+++ b/drivers/pci/dmar.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * 	Copyright (C) Ashok Raj <ashok.raj@intel.com>
+ *	Copyright (C) Shaohua Li <shaohua.li@intel.com>
+ *	Copyright (C) Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *
+ * 	This file implements early detection/parsing of DMA Remapping Devices
+ * reported to OS through BIOS via DMA remapping reporting (DMAR) ACPI
+ * tables.
+ */
+
+#include <linux/pci.h>
+#include <linux/dmar.h>
+
+#undef PREFIX
+#define PREFIX "DMAR:"
+
+/* No locks are needed as DMA remapping hardware unit
+ * list is constructed at boot time and hotplug of
+ * these units are not supported by the architecture.
+ */
+LIST_HEAD(dmar_drhd_units);
+LIST_HEAD(dmar_rmrr_units);
+
+static struct acpi_table_header * __initdata dmar_tbl;
+
+static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
+{
+	/*
+	 * add INCLUDE_ALL at the tail, so scan the list will find it at
+	 * the very end.
+	 */
+	if (drhd->include_all)
+		list_add_tail(&drhd->list, &dmar_drhd_units);
+	else
+		list_add(&drhd->list, &dmar_drhd_units);
+}
+
+static void __init dmar_register_rmrr_unit(struct dmar_rmrr_unit *rmrr)
+{
+	list_add(&rmrr->list, &dmar_rmrr_units);
+}
+
+static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope,
+					   struct pci_dev **dev, u16 segment)
+{
+	struct pci_bus *bus;
+	struct pci_dev *pdev = NULL;
+	struct acpi_dmar_pci_path *path;
+	int count;
+
+	bus = pci_find_bus(segment, scope->bus);
+	path = (struct acpi_dmar_pci_path *)(scope + 1);
+	count = (scope->length - sizeof(struct acpi_dmar_device_scope))
+		/ sizeof(struct acpi_dmar_pci_path);
+
+	while (count) {
+		if (pdev)
+			pci_dev_put(pdev);
+		/*
+		 * Some BIOSes list non-exist devices in DMAR table, just
+		 * ignore it
+		 */
+		if (!bus) {
+			printk(KERN_WARNING
+			PREFIX "Device scope bus [%d] not found\n",
+			scope->bus);
+			break;
+		}
+		pdev = pci_get_slot(bus, PCI_DEVFN(path->dev, path->fn));
+		if (!pdev) {
+			printk(KERN_WARNING PREFIX
+			"Device scope device [%04x:%02x:%02x.%02x] not found\n",
+				segment, bus->number, path->dev, path->fn);
+			break;
+		}
+		path ++;
+		count --;
+		bus = pdev->subordinate;
+	}
+	if (!pdev) {
+		printk(KERN_WARNING PREFIX
+		"Device scope device [%04x:%02x:%02x.%02x] not found\n",
+		segment, scope->bus, path->dev, path->fn);
+		*dev = NULL;
+		return 0;
+	}
+	if ((scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT && \
+			pdev->subordinate) || (scope->entry_type == \
+			ACPI_DMAR_SCOPE_TYPE_BRIDGE && !pdev->subordinate)) {
+		pci_dev_put(pdev);
+		printk(KERN_WARNING PREFIX
+			"Device scope type does not match for %s\n",
+			 pci_name(pdev));
+		return -EINVAL;
+	}
+	*dev = pdev;
+	return 0;
+}
+
+static int __init dmar_parse_dev_scope(void *start, void *end, int *cnt,
+				       struct pci_dev ***devices, u16 segment)
+{
+	struct acpi_dmar_device_scope *scope;
+	void * tmp = start;
+	int index;
+	int ret;
+
+	*cnt = 0;
+	while (start < end) {
+		scope = start;
+		if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
+		    scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
+			(*cnt)++;
+		else
+			printk(KERN_WARNING PREFIX
+				"Unsupported device scope\n");
+		start += scope->length;
+	}
+	if (*cnt == 0)
+		return 0;
+
+	*devices = kcalloc(*cnt, sizeof(struct pci_dev *), GFP_KERNEL);
+	if (!*devices)
+		return -ENOMEM;
+
+	start = tmp;
+	index = 0;
+	while (start < end) {
+		scope = start;
+		if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
+		    scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) {
+			ret = dmar_parse_one_dev_scope(scope,
+				&(*devices)[index], segment);
+			if (ret) {
+				kfree(*devices);
+				return ret;
+			}
+			index ++;
+		}
+		start += scope->length;
+	}
+
+	return 0;
+}
+
+/**
+ * dmar_parse_one_drhd - parses exactly one DMA remapping hardware definition
+ * structure which uniquely represent one DMA remapping hardware unit
+ * present in the platform
+ */
+static int __init
+dmar_parse_one_drhd(struct acpi_dmar_header *header)
+{
+	struct acpi_dmar_hardware_unit *drhd;
+	struct dmar_drhd_unit *dmaru;
+	int ret = 0;
+	static int include_all;
+
+	dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL);
+	if (!dmaru)
+		return -ENOMEM;
+
+	drhd = (struct acpi_dmar_hardware_unit *)header;
+	dmaru->reg_base_addr = drhd->address;
+	dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
+
+	if (!dmaru->include_all)
+		ret = dmar_parse_dev_scope((void *)(drhd + 1),
+				((void *)drhd) + header->length,
+				&dmaru->devices_cnt, &dmaru->devices,
+				drhd->segment);
+	else {
+		/* Only allow one INCLUDE_ALL */
+		if (include_all) {
+			printk(KERN_WARNING PREFIX "Only one INCLUDE_ALL "
+				"device scope is allowed\n");
+			ret = -EINVAL;
+		}
+		include_all = 1;
+	}
+
+	if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all))
+		kfree(dmaru);
+	else
+		dmar_register_drhd_unit(dmaru);
+	return ret;
+}
+
+static int __init
+dmar_parse_one_rmrr(struct acpi_dmar_header *header)
+{
+	struct acpi_dmar_reserved_memory *rmrr;
+	struct dmar_rmrr_unit *rmrru;
+	int ret = 0;
+
+	rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
+	if (!rmrru)
+		return -ENOMEM;
+
+	rmrr = (struct acpi_dmar_reserved_memory *)header;
+	rmrru->base_address = rmrr->base_address;
+	rmrru->end_address = rmrr->end_address;
+	ret = dmar_parse_dev_scope((void *)(rmrr + 1),
+		((void *)rmrr) + header->length,
+		&rmrru->devices_cnt, &rmrru->devices, rmrr->segment);
+
+	if (ret || (rmrru->devices_cnt == 0))
+		kfree(rmrru);
+	else
+		dmar_register_rmrr_unit(rmrru);
+	return ret;
+}
+
+static void __init
+dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
+{
+	struct acpi_dmar_hardware_unit *drhd;
+	struct acpi_dmar_reserved_memory *rmrr;
+
+	switch (header->type) {
+	case ACPI_DMAR_TYPE_HARDWARE_UNIT:
+		drhd = (struct acpi_dmar_hardware_unit *)header;
+		printk (KERN_INFO PREFIX
+			"DRHD (flags: 0x%08x)base: 0x%016Lx\n",
+			drhd->flags, drhd->address);
+		break;
+	case ACPI_DMAR_TYPE_RESERVED_MEMORY:
+		rmrr = (struct acpi_dmar_reserved_memory *)header;
+
+		printk (KERN_INFO PREFIX
+			"RMRR base: 0x%016Lx end: 0x%016Lx\n",
+			rmrr->base_address, rmrr->end_address);
+		break;
+	}
+}
+
+/**
+ * parse_dmar_table - parses the DMA reporting table
+ */
+static int __init
+parse_dmar_table(void)
+{
+	struct acpi_table_dmar *dmar;
+	struct acpi_dmar_header *entry_header;
+	int ret = 0;
+
+	dmar = (struct acpi_table_dmar *)dmar_tbl;
+	if (!dmar)
+		return -ENODEV;
+
+	if (!dmar->width) {
+		printk (KERN_WARNING PREFIX "Zero: Invalid DMAR haw\n");
+		return -EINVAL;
+	}
+
+	printk (KERN_INFO PREFIX "Host address width %d\n",
+		dmar->width + 1);
+
+	entry_header = (struct acpi_dmar_header *)(dmar + 1);
+	while (((unsigned long)entry_header) <
+			(((unsigned long)dmar) + dmar_tbl->length)) {
+		dmar_table_print_dmar_entry(entry_header);
+
+		switch (entry_header->type) {
+		case ACPI_DMAR_TYPE_HARDWARE_UNIT:
+			ret = dmar_parse_one_drhd(entry_header);
+			break;
+		case ACPI_DMAR_TYPE_RESERVED_MEMORY:
+			ret = dmar_parse_one_rmrr(entry_header);
+			break;
+		default:
+			printk(KERN_WARNING PREFIX
+				"Unknown DMAR structure type\n");
+			ret = 0; /* for forward compatibility */
+			break;
+		}
+		if (ret)
+			break;
+
+		entry_header = ((void *)entry_header + entry_header->length);
+	}
+	return ret;
+}
+
+
+int __init dmar_table_init(void)
+{
+
+	parse_dmar_table();
+	if (list_empty(&dmar_drhd_units)) {
+		printk(KERN_INFO PREFIX "No DMAR devices found\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+/**
+ * early_dmar_detect - checks to see if the platform supports DMAR devices
+ */
+int __init early_dmar_detect(void)
+{
+	acpi_status status = AE_OK;
+
+	/* if we could find DMAR table, then there are DMAR devices */
+	status = acpi_get_table(ACPI_SIG_DMAR, 0,
+				(struct acpi_table_header **)&dmar_tbl);
+
+	if (ACPI_SUCCESS(status) && !dmar_tbl) {
+		printk (KERN_WARNING PREFIX "Unable to map DMAR\n");
+		status = AE_NOT_FOUND;
+	}
+
+	return (ACPI_SUCCESS(status) ? 1 : 0);
+}
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
new file mode 100644
index 0000000..0c4ab3b
--- /dev/null
+++ b/drivers/pci/intel-iommu.c
@@ -0,0 +1,2271 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * Copyright (C) Ashok Raj <ashok.raj@intel.com>
+ * Copyright (C) Shaohua Li <shaohua.li@intel.com>
+ * Copyright (C) Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ */
+
+#include <linux/init.h>
+#include <linux/bitmap.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/spinlock.h>
+#include <linux/pci.h>
+#include <linux/dmar.h>
+#include <linux/dma-mapping.h>
+#include <linux/mempool.h>
+#include "iova.h"
+#include "intel-iommu.h"
+#include <asm/proto.h> /* force_iommu in this header in x86-64*/
+#include <asm/cacheflush.h>
+#include <asm/iommu.h>
+#include "pci.h"
+
+#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
+#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
+
+#define IOAPIC_RANGE_START	(0xfee00000)
+#define IOAPIC_RANGE_END	(0xfeefffff)
+#define IOVA_START_ADDR		(0x1000)
+
+#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
+
+#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */
+
+#define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1)
+
+static void domain_remove_dev_info(struct dmar_domain *domain);
+
+static int dmar_disabled;
+static int __initdata dmar_map_gfx = 1;
+static int dmar_forcedac;
+
+#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
+static DEFINE_SPINLOCK(device_domain_lock);
+static LIST_HEAD(device_domain_list);
+
+static int __init intel_iommu_setup(char *str)
+{
+	if (!str)
+		return -EINVAL;
+	while (*str) {
+		if (!strncmp(str, "off", 3)) {
+			dmar_disabled = 1;
+			printk(KERN_INFO"Intel-IOMMU: disabled\n");
+		} else if (!strncmp(str, "igfx_off", 8)) {
+			dmar_map_gfx = 0;
+			printk(KERN_INFO
+				"Intel-IOMMU: disable GFX device mapping\n");
+		} else if (!strncmp(str, "forcedac", 8)) {
+			printk (KERN_INFO
+				"Intel-IOMMU: Forcing DAC for PCI devices\n");
+			dmar_forcedac = 1;
+		}
+
+		str += strcspn(str, ",");
+		while (*str == ',')
+			str++;
+	}
+	return 0;
+}
+__setup("intel_iommu=", intel_iommu_setup);
+
+static struct kmem_cache *iommu_domain_cache;
+static struct kmem_cache *iommu_devinfo_cache;
+static struct kmem_cache *iommu_iova_cache;
+
+static inline void *iommu_kmem_cache_alloc(struct kmem_cache *cachep)
+{
+	unsigned int flags;
+	void *vaddr;
+
+	/* trying to avoid low memory issues */
+	flags = current->flags & PF_MEMALLOC;
+	current->flags |= PF_MEMALLOC;
+	vaddr = kmem_cache_alloc(cachep, GFP_ATOMIC);
+	current->flags &= (~PF_MEMALLOC | flags);
+	return vaddr;
+}
+
+
+static inline void *alloc_pgtable_page(void)
+{
+	unsigned int flags;
+	void *vaddr;
+
+	/* trying to avoid low memory issues */
+	flags = current->flags & PF_MEMALLOC;
+	current->flags |= PF_MEMALLOC;
+	vaddr = (void *)get_zeroed_page(GFP_ATOMIC);
+	current->flags &= (~PF_MEMALLOC | flags);
+	return vaddr;
+}
+
+static inline void free_pgtable_page(void *vaddr)
+{
+	free_page((unsigned long)vaddr);
+}
+
+static inline void *alloc_domain_mem(void)
+{
+	return iommu_kmem_cache_alloc(iommu_domain_cache);
+}
+
+static inline void free_domain_mem(void *vaddr)
+{
+	kmem_cache_free(iommu_domain_cache, vaddr);
+}
+
+static inline void * alloc_devinfo_mem(void)
+{
+	return iommu_kmem_cache_alloc(iommu_devinfo_cache);
+}
+
+static inline void free_devinfo_mem(void *vaddr)
+{
+	kmem_cache_free(iommu_devinfo_cache, vaddr);
+}
+
+struct iova *alloc_iova_mem(void)
+{
+	return iommu_kmem_cache_alloc(iommu_iova_cache);
+}
+
+void free_iova_mem(struct iova *iova)
+{
+	kmem_cache_free(iommu_iova_cache, iova);
+}
+
+static inline void __iommu_flush_cache(
+	struct intel_iommu *iommu, void *addr, int size)
+{
+	if (!ecap_coherent(iommu->ecap))
+		clflush_cache_range(addr, size);
+}
+
+/* Gets context entry for a given bus and devfn */
+static struct context_entry * device_to_context_entry(struct intel_iommu *iommu,
+		u8 bus, u8 devfn)
+{
+	struct root_entry *root;
+	struct context_entry *context;
+	unsigned long phy_addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iommu->lock, flags);
+	root = &iommu->root_entry[bus];
+	context = get_context_addr_from_root(root);
+	if (!context) {
+		context = (struct context_entry *)alloc_pgtable_page();
+		if (!context) {
+			spin_unlock_irqrestore(&iommu->lock, flags);
+			return NULL;
+		}
+		__iommu_flush_cache(iommu, (void *)context, PAGE_SIZE_4K);
+		phy_addr = virt_to_phys((void *)context);
+		set_root_value(root, phy_addr);
+		set_root_present(root);
+		__iommu_flush_cache(iommu, root, sizeof(*root));
+	}
+	spin_unlock_irqrestore(&iommu->lock, flags);
+	return &context[devfn];
+}
+
+static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
+{
+	struct root_entry *root;
+	struct context_entry *context;
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iommu->lock, flags);
+	root = &iommu->root_entry[bus];
+	context = get_context_addr_from_root(root);
+	if (!context) {
+		ret = 0;
+		goto out;
+	}
+	ret = context_present(context[devfn]);
+out:
+	spin_unlock_irqrestore(&iommu->lock, flags);
+	return ret;
+}
+
+static void clear_context_table(struct intel_iommu *iommu, u8 bus, u8 devfn)
+{
+	struct root_entry *root;
+	struct context_entry *context;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iommu->lock, flags);
+	root = &iommu->root_entry[bus];
+	context = get_context_addr_from_root(root);
+	if (context) {
+		context_clear_entry(context[devfn]);
+		__iommu_flush_cache(iommu, &context[devfn], \
+			sizeof(*context));
+	}
+	spin_unlock_irqrestore(&iommu->lock, flags);
+}
+
+static void free_context_table(struct intel_iommu *iommu)
+{
+	struct root_entry *root;
+	int i;
+	unsigned long flags;
+	struct context_entry *context;
+
+	spin_lock_irqsave(&iommu->lock, flags);
+	if (!iommu->root_entry) {
+		goto out;
+	}
+	for (i = 0; i < ROOT_ENTRY_NR; i++) {
+		root = &iommu->root_entry[i];
+		context = get_context_addr_from_root(root);
+		if (context)
+			free_pgtable_page(context);
+	}
+	free_pgtable_page(iommu->root_entry);
+	iommu->root_entry = NULL;
+out:
+	spin_unlock_irqrestore(&iommu->lock, flags);
+}
+
+/* page table handling */
+#define LEVEL_STRIDE		(9)
+#define LEVEL_MASK		(((u64)1 << LEVEL_STRIDE) - 1)
+
+static inline int agaw_to_level(int agaw)
+{
+	return agaw + 2;
+}
+
+static inline int agaw_to_width(int agaw)
+{
+	return 30 + agaw * LEVEL_STRIDE;
+
+}
+
+static inline int width_to_agaw(int width)
+{
+	return (width - 30) / LEVEL_STRIDE;
+}
+
+static inline unsigned int level_to_offset_bits(int level)
+{
+	return (12 + (level - 1) * LEVEL_STRIDE);
+}
+
+static inline int address_level_offset(u64 addr, int level)
+{
+	return ((addr >> level_to_offset_bits(level)) & LEVEL_MASK);
+}
+
+static inline u64 level_mask(int level)
+{
+	return ((u64)-1 << level_to_offset_bits(level));
+}
+
+static inline u64 level_size(int level)
+{
+	return ((u64)1 << level_to_offset_bits(level));
+}
+
+static inline u64 align_to_level(u64 addr, int level)
+{
+	return ((addr + level_size(level) - 1) & level_mask(level));
+}
+
+static struct dma_pte * addr_to_dma_pte(struct dmar_domain *domain, u64 addr)
+{
+	int addr_width = agaw_to_width(domain->agaw);
+	struct dma_pte *parent, *pte = NULL;
+	int level = agaw_to_level(domain->agaw);
+	int offset;
+	unsigned long flags;
+
+	BUG_ON(!domain->pgd);
+
+	addr &= (((u64)1) << addr_width) - 1;
+	parent = domain->pgd;
+
+	spin_lock_irqsave(&domain->mapping_lock, flags);
+	while (level > 0) {
+		void *tmp_page;
+
+		offset = address_level_offset(addr, level);
+		pte = &parent[offset];
+		if (level == 1)
+			break;
+
+		if (!dma_pte_present(*pte)) {
+			tmp_page = alloc_pgtable_page();
+
+			if (!tmp_page) {
+				spin_unlock_irqrestore(&domain->mapping_lock,
+					flags);
+				return NULL;
+			}
+			__iommu_flush_cache(domain->iommu, tmp_page,
+					PAGE_SIZE_4K);
+			dma_set_pte_addr(*pte, virt_to_phys(tmp_page));
+			/*
+			 * high level table always sets r/w, last level page
+			 * table control read/write
+			 */
+			dma_set_pte_readable(*pte);
+			dma_set_pte_writable(*pte);
+			__iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
+		}
+		parent = phys_to_virt(dma_pte_addr(*pte));
+		level--;
+	}
+
+	spin_unlock_irqrestore(&domain->mapping_lock, flags);
+	return pte;
+}
+
+/* return address's pte at specific level */
+static struct dma_pte *dma_addr_level_pte(struct dmar_domain *domain, u64 addr,
+		int level)
+{
+	struct dma_pte *parent, *pte = NULL;
+	int total = agaw_to_level(domain->agaw);
+	int offset;
+
+	parent = domain->pgd;
+	while (level <= total) {
+		offset = address_level_offset(addr, total);
+		pte = &parent[offset];
+		if (level == total)
+			return pte;
+
+		if (!dma_pte_present(*pte))
+			break;
+		parent = phys_to_virt(dma_pte_addr(*pte));
+		total--;
+	}
+	return NULL;
+}
+
+/* clear one page's page table */
+static void dma_pte_clear_one(struct dmar_domain *domain, u64 addr)
+{
+	struct dma_pte *pte = NULL;
+
+	/* get last level pte */
+	pte = dma_addr_level_pte(domain, addr, 1);
+
+	if (pte) {
+		dma_clear_pte(*pte);
+		__iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
+	}
+}
+
+/* clear last level pte, a tlb flush should be followed */
+static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
+{
+	int addr_width = agaw_to_width(domain->agaw);
+
+	start &= (((u64)1) << addr_width) - 1;
+	end &= (((u64)1) << addr_width) - 1;
+	/* in case it's partial page */
+	start = PAGE_ALIGN_4K(start);
+	end &= PAGE_MASK_4K;
+
+	/* we don't need lock here, nobody else touches the iova range */
+	while (start < end) {
+		dma_pte_clear_one(domain, start);
+		start += PAGE_SIZE_4K;
+	}
+}
+
+/* free page table pages. last level pte should already be cleared */
+static void dma_pte_free_pagetable(struct dmar_domain *domain,
+	u64 start, u64 end)
+{
+	int addr_width = agaw_to_width(domain->agaw);
+	struct dma_pte *pte;
+	int total = agaw_to_level(domain->agaw);
+	int level;
+	u64 tmp;
+
+	start &= (((u64)1) << addr_width) - 1;
+	end &= (((u64)1) << addr_width) - 1;
+
+	/* we don't need lock here, nobody else touches the iova range */
+	level = 2;
+	while (level <= total) {
+		tmp = align_to_level(start, level);
+		if (tmp >= end || (tmp + level_size(level) > end))
+			return;
+
+		while (tmp < end) {
+			pte = dma_addr_level_pte(domain, tmp, level);
+			if (pte) {
+				free_pgtable_page(
+					phys_to_virt(dma_pte_addr(*pte)));
+				dma_clear_pte(*pte);
+				__iommu_flush_cache(domain->iommu,
+						pte, sizeof(*pte));
+			}
+			tmp += level_size(level);
+		}
+		level++;
+	}
+	/* free pgd */
+	if (start == 0 && end >= ((((u64)1) << addr_width) - 1)) {
+		free_pgtable_page(domain->pgd);
+		domain->pgd = NULL;
+	}
+}
+
+/* iommu handling */
+static int iommu_alloc_root_entry(struct intel_iommu *iommu)
+{
+	struct root_entry *root;
+	unsigned long flags;
+
+	root = (struct root_entry *)alloc_pgtable_page();
+	if (!root)
+		return -ENOMEM;
+
+	__iommu_flush_cache(iommu, root, PAGE_SIZE_4K);
+
+	spin_lock_irqsave(&iommu->lock, flags);
+	iommu->root_entry = root;
+	spin_unlock_irqrestore(&iommu->lock, flags);
+
+	return 0;
+}
+
+#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
+{\
+	unsigned long start_time = jiffies;\
+	while (1) {\
+		sts = op (iommu->reg + offset);\
+		if (cond)\
+			break;\
+		if (time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT))\
+			panic("DMAR hardware is malfunctioning\n");\
+		cpu_relax();\
+	}\
+}
+
+static void iommu_set_root_entry(struct intel_iommu *iommu)
+{
+	void *addr;
+	u32 cmd, sts;
+	unsigned long flag;
+
+	addr = iommu->root_entry;
+
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	dmar_writeq(iommu->reg + DMAR_RTADDR_REG, virt_to_phys(addr));
+
+	cmd = iommu->gcmd | DMA_GCMD_SRTP;
+	writel(cmd, iommu->reg + DMAR_GCMD_REG);
+
+	/* Make sure hardware complete it */
+	IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+		readl, (sts & DMA_GSTS_RTPS), sts);
+
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+static void iommu_flush_write_buffer(struct intel_iommu *iommu)
+{
+	u32 val;
+	unsigned long flag;
+
+	if (!cap_rwbf(iommu->cap))
+		return;
+	val = iommu->gcmd | DMA_GCMD_WBF;
+
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	writel(val, iommu->reg + DMAR_GCMD_REG);
+
+	/* Make sure hardware complete it */
+	IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+			readl, (!(val & DMA_GSTS_WBFS)), val);
+
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+/* return value determine if we need a write buffer flush */
+static int __iommu_flush_context(struct intel_iommu *iommu,
+	u16 did, u16 source_id, u8 function_mask, u64 type,
+	int non_present_entry_flush)
+{
+	u64 val = 0;
+	unsigned long flag;
+
+	/*
+	 * In the non-present entry flush case, if hardware doesn't cache
+	 * non-present entry we do nothing and if hardware cache non-present
+	 * entry, we flush entries of domain 0 (the domain id is used to cache
+	 * any non-present entries)
+	 */
+	if (non_present_entry_flush) {
+		if (!cap_caching_mode(iommu->cap))
+			return 1;
+		else
+			did = 0;
+	}
+
+	switch (type) {
+	case DMA_CCMD_GLOBAL_INVL:
+		val = DMA_CCMD_GLOBAL_INVL;
+		break;
+	case DMA_CCMD_DOMAIN_INVL:
+		val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
+		break;
+	case DMA_CCMD_DEVICE_INVL:
+		val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
+			| DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
+		break;
+	default:
+		BUG();
+	}
+	val |= DMA_CCMD_ICC;
+
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
+
+	/* Make sure hardware complete it */
+	IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
+		dmar_readq, (!(val & DMA_CCMD_ICC)), val);
+
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+
+	/* flush context entry will implictly flush write buffer */
+	return 0;
+}
+
+static int inline iommu_flush_context_global(struct intel_iommu *iommu,
+	int non_present_entry_flush)
+{
+	return __iommu_flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL,
+		non_present_entry_flush);
+}
+
+static int inline iommu_flush_context_domain(struct intel_iommu *iommu, u16 did,
+	int non_present_entry_flush)
+{
+	return __iommu_flush_context(iommu, did, 0, 0, DMA_CCMD_DOMAIN_INVL,
+		non_present_entry_flush);
+}
+
+static int inline iommu_flush_context_device(struct intel_iommu *iommu,
+	u16 did, u16 source_id, u8 function_mask, int non_present_entry_flush)
+{
+	return __iommu_flush_context(iommu, did, source_id, function_mask,
+		DMA_CCMD_DEVICE_INVL, non_present_entry_flush);
+}
+
+/* return value determine if we need a write buffer flush */
+static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
+	u64 addr, unsigned int size_order, u64 type,
+	int non_present_entry_flush)
+{
+	int tlb_offset = ecap_iotlb_offset(iommu->ecap);
+	u64 val = 0, val_iva = 0;
+	unsigned long flag;
+
+	/*
+	 * In the non-present entry flush case, if hardware doesn't cache
+	 * non-present entry we do nothing and if hardware cache non-present
+	 * entry, we flush entries of domain 0 (the domain id is used to cache
+	 * any non-present entries)
+	 */
+	if (non_present_entry_flush) {
+		if (!cap_caching_mode(iommu->cap))
+			return 1;
+		else
+			did = 0;
+	}
+
+	switch (type) {
+	case DMA_TLB_GLOBAL_FLUSH:
+		/* global flush doesn't need set IVA_REG */
+		val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
+		break;
+	case DMA_TLB_DSI_FLUSH:
+		val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
+		break;
+	case DMA_TLB_PSI_FLUSH:
+		val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
+		/* Note: always flush non-leaf currently */
+		val_iva = size_order | addr;
+		break;
+	default:
+		BUG();
+	}
+	/* Note: set drain read/write */
+#if 0
+	/*
+	 * This is probably to be super secure.. Looks like we can
+	 * ignore it without any impact.
+	 */
+	if (cap_read_drain(iommu->cap))
+		val |= DMA_TLB_READ_DRAIN;
+#endif
+	if (cap_write_drain(iommu->cap))
+		val |= DMA_TLB_WRITE_DRAIN;
+
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	/* Note: Only uses first TLB reg currently */
+	if (val_iva)
+		dmar_writeq(iommu->reg + tlb_offset, val_iva);
+	dmar_writeq(iommu->reg + tlb_offset + 8, val);
+
+	/* Make sure hardware complete it */
+	IOMMU_WAIT_OP(iommu, tlb_offset + 8,
+		dmar_readq, (!(val & DMA_TLB_IVT)), val);
+
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+
+	/* check IOTLB invalidation granularity */
+	if (DMA_TLB_IAIG(val) == 0)
+		printk(KERN_ERR"IOMMU: flush IOTLB failed\n");
+	if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
+		pr_debug("IOMMU: tlb flush request %Lx, actual %Lx\n",
+			DMA_TLB_IIRG(type), DMA_TLB_IAIG(val));
+	/* flush context entry will implictly flush write buffer */
+	return 0;
+}
+
+static int inline iommu_flush_iotlb_global(struct intel_iommu *iommu,
+	int non_present_entry_flush)
+{
+	return __iommu_flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH,
+		non_present_entry_flush);
+}
+
+static int inline iommu_flush_iotlb_dsi(struct intel_iommu *iommu, u16 did,
+	int non_present_entry_flush)
+{
+	return __iommu_flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH,
+		non_present_entry_flush);
+}
+
+static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
+	u64 addr, unsigned int pages, int non_present_entry_flush)
+{
+	unsigned int mask;
+
+	BUG_ON(addr & (~PAGE_MASK_4K));
+	BUG_ON(pages == 0);
+
+	/* Fallback to domain selective flush if no PSI support */
+	if (!cap_pgsel_inv(iommu->cap))
+		return iommu_flush_iotlb_dsi(iommu, did,
+			non_present_entry_flush);
+
+	/*
+	 * PSI requires page size to be 2 ^ x, and the base address is naturally
+	 * aligned to the size
+	 */
+	mask = ilog2(__roundup_pow_of_two(pages));
+	/* Fallback to domain selective flush if size is too big */
+	if (mask > cap_max_amask_val(iommu->cap))
+		return iommu_flush_iotlb_dsi(iommu, did,
+			non_present_entry_flush);
+
+	return __iommu_flush_iotlb(iommu, did, addr, mask,
+		DMA_TLB_PSI_FLUSH, non_present_entry_flush);
+}
+
+static int iommu_enable_translation(struct intel_iommu *iommu)
+{
+	u32 sts;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iommu->register_lock, flags);
+	writel(iommu->gcmd|DMA_GCMD_TE, iommu->reg + DMAR_GCMD_REG);
+
+	/* Make sure hardware complete it */
+	IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+		readl, (sts & DMA_GSTS_TES), sts);
+
+	iommu->gcmd |= DMA_GCMD_TE;
+	spin_unlock_irqrestore(&iommu->register_lock, flags);
+	return 0;
+}
+
+static int iommu_disable_translation(struct intel_iommu *iommu)
+{
+	u32 sts;
+	unsigned long flag;
+
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	iommu->gcmd &= ~DMA_GCMD_TE;
+	writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
+
+	/* Make sure hardware complete it */
+	IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+		readl, (!(sts & DMA_GSTS_TES)), sts);
+
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+	return 0;
+}
+
+/* iommu interrupt handling. Most stuff are MSI-like. */
+
+static char *fault_reason_strings[] =
+{
+	"Software",
+	"Present bit in root entry is clear",
+	"Present bit in context entry is clear",
+	"Invalid context entry",
+	"Access beyond MGAW",
+	"PTE Write access is not set",
+	"PTE Read access is not set",
+	"Next page table ptr is invalid",
+	"Root table address invalid",
+	"Context table ptr is invalid",
+	"non-zero reserved fields in RTP",
+	"non-zero reserved fields in CTP",
+	"non-zero reserved fields in PTE",
+	"Unknown"
+};
+#define MAX_FAULT_REASON_IDX 	ARRAY_SIZE(fault_reason_strings)
+
+char *dmar_get_fault_reason(u8 fault_reason)
+{
+	if (fault_reason > MAX_FAULT_REASON_IDX)
+		return fault_reason_strings[MAX_FAULT_REASON_IDX];
+	else
+		return fault_reason_strings[fault_reason];
+}
+
+void dmar_msi_unmask(unsigned int irq)
+{
+	struct intel_iommu *iommu = get_irq_data(irq);
+	unsigned long flag;
+
+	/* unmask it */
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	writel(0, iommu->reg + DMAR_FECTL_REG);
+	/* Read a reg to force flush the post write */
+	readl(iommu->reg + DMAR_FECTL_REG);
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_mask(unsigned int irq)
+{
+	unsigned long flag;
+	struct intel_iommu *iommu = get_irq_data(irq);
+
+	/* mask it */
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG);
+	/* Read a reg to force flush the post write */
+	readl(iommu->reg + DMAR_FECTL_REG);
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_write(int irq, struct msi_msg *msg)
+{
+	struct intel_iommu *iommu = get_irq_data(irq);
+	unsigned long flag;
+
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	writel(msg->data, iommu->reg + DMAR_FEDATA_REG);
+	writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG);
+	writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG);
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_read(int irq, struct msi_msg *msg)
+{
+	struct intel_iommu *iommu = get_irq_data(irq);
+	unsigned long flag;
+
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	msg->data = readl(iommu->reg + DMAR_FEDATA_REG);
+	msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG);
+	msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG);
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type,
+		u8 fault_reason, u16 source_id, u64 addr)
+{
+	char *reason;
+
+	reason = dmar_get_fault_reason(fault_reason);
+
+	printk(KERN_ERR
+		"DMAR:[%s] Request device [%02x:%02x.%d] "
+		"fault addr %llx \n"
+		"DMAR:[fault reason %02d] %s\n",
+		(type ? "DMA Read" : "DMA Write"),
+		(source_id >> 8), PCI_SLOT(source_id & 0xFF),
+		PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
+	return 0;
+}
+
+#define PRIMARY_FAULT_REG_LEN (16)
+static irqreturn_t iommu_page_fault(int irq, void *dev_id)
+{
+	struct intel_iommu *iommu = dev_id;
+	int reg, fault_index;
+	u32 fault_status;
+	unsigned long flag;
+
+	spin_lock_irqsave(&iommu->register_lock, flag);
+	fault_status = readl(iommu->reg + DMAR_FSTS_REG);
+
+	/* TBD: ignore advanced fault log currently */
+	if (!(fault_status & DMA_FSTS_PPF))
+		goto clear_overflow;
+
+	fault_index = dma_fsts_fault_record_index(fault_status);
+	reg = cap_fault_reg_offset(iommu->cap);
+	while (1) {
+		u8 fault_reason;
+		u16 source_id;
+		u64 guest_addr;
+		int type;
+		u32 data;
+
+		/* highest 32 bits */
+		data = readl(iommu->reg + reg +
+				fault_index * PRIMARY_FAULT_REG_LEN + 12);
+		if (!(data & DMA_FRCD_F))
+			break;
+
+		fault_reason = dma_frcd_fault_reason(data);
+		type = dma_frcd_type(data);
+
+		data = readl(iommu->reg + reg +
+				fault_index * PRIMARY_FAULT_REG_LEN + 8);
+		source_id = dma_frcd_source_id(data);
+
+		guest_addr = dmar_readq(iommu->reg + reg +
+				fault_index * PRIMARY_FAULT_REG_LEN);
+		guest_addr = dma_frcd_page_addr(guest_addr);
+		/* clear the fault */
+		writel(DMA_FRCD_F, iommu->reg + reg +
+			fault_index * PRIMARY_FAULT_REG_LEN + 12);
+
+		spin_unlock_irqrestore(&iommu->register_lock, flag);
+
+		iommu_page_fault_do_one(iommu, type, fault_reason,
+				source_id, guest_addr);
+
+		fault_index++;
+		if (fault_index > cap_num_fault_regs(iommu->cap))
+			fault_index = 0;
+		spin_lock_irqsave(&iommu->register_lock, flag);
+	}
+clear_overflow:
+	/* clear primary fault overflow */
+	fault_status = readl(iommu->reg + DMAR_FSTS_REG);
+	if (fault_status & DMA_FSTS_PFO)
+		writel(DMA_FSTS_PFO, iommu->reg + DMAR_FSTS_REG);
+
+	spin_unlock_irqrestore(&iommu->register_lock, flag);
+	return IRQ_HANDLED;
+}
+
+int dmar_set_interrupt(struct intel_iommu *iommu)
+{
+	int irq, ret;
+
+	irq = create_irq();
+	if (!irq) {
+		printk(KERN_ERR "IOMMU: no free vectors\n");
+		return -EINVAL;
+	}
+
+	set_irq_data(irq, iommu);
+	iommu->irq = irq;
+
+	ret = arch_setup_dmar_msi(irq);
+	if (ret) {
+		set_irq_data(irq, NULL);
+		iommu->irq = 0;
+		destroy_irq(irq);
+		return 0;
+	}
+
+	/* Force fault register is cleared */
+	iommu_page_fault(irq, iommu);
+
+	ret = request_irq(irq, iommu_page_fault, 0, iommu->name, iommu);
+	if (ret)
+		printk(KERN_ERR "IOMMU: can't request irq\n");
+	return ret;
+}
+
+static int iommu_init_domains(struct intel_iommu *iommu)
+{
+	unsigned long ndomains;
+	unsigned long nlongs;
+
+	ndomains = cap_ndoms(iommu->cap);
+	pr_debug("Number of Domains supportd <%ld>\n", ndomains);
+	nlongs = BITS_TO_LONGS(ndomains);
+
+	/* TBD: there might be 64K domains,
+	 * consider other allocation for future chip
+	 */
+	iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
+	if (!iommu->domain_ids) {
+		printk(KERN_ERR "Allocating domain id array failed\n");
+		return -ENOMEM;
+	}
+	iommu->domains = kcalloc(ndomains, sizeof(struct dmar_domain *),
+			GFP_KERNEL);
+	if (!iommu->domains) {
+		printk(KERN_ERR "Allocating domain array failed\n");
+		kfree(iommu->domain_ids);
+		return -ENOMEM;
+	}
+
+	/*
+	 * if Caching mode is set, then invalid translations are tagged
+	 * with domainid 0. Hence we need to pre-allocate it.
+	 */
+	if (cap_caching_mode(iommu->cap))
+		set_bit(0, iommu->domain_ids);
+	return 0;
+}
+
+static struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd)
+{
+	struct intel_iommu *iommu;
+	int ret;
+	int map_size;
+	u32 ver;
+
+	iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
+	if (!iommu)
+		return NULL;
+	iommu->reg = ioremap(drhd->reg_base_addr, PAGE_SIZE_4K);
+	if (!iommu->reg) {
+		printk(KERN_ERR "IOMMU: can't map the region\n");
+		goto error;
+	}
+	iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG);
+	iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
+
+	/* the registers might be more than one page */
+	map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
+		cap_max_fault_reg_offset(iommu->cap));
+	map_size = PAGE_ALIGN_4K(map_size);
+	if (map_size > PAGE_SIZE_4K) {
+		iounmap(iommu->reg);
+		iommu->reg = ioremap(drhd->reg_base_addr, map_size);
+		if (!iommu->reg) {
+			printk(KERN_ERR "IOMMU: can't map the region\n");
+			goto error;
+		}
+	}
+
+	ver = readl(iommu->reg + DMAR_VER_REG);
+	pr_debug("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n",
+		drhd->reg_base_addr, DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver),
+		iommu->cap, iommu->ecap);
+	ret = iommu_init_domains(iommu);
+	if (ret)
+		goto error_unmap;
+	spin_lock_init(&iommu->lock);
+	spin_lock_init(&iommu->register_lock);
+
+	drhd->iommu = iommu;
+	return iommu;
+error_unmap:
+	iounmap(iommu->reg);
+	iommu->reg = 0;
+error:
+	kfree(iommu);
+	return NULL;
+}
+
+static void domain_exit(struct dmar_domain *domain);
+static void free_iommu(struct intel_iommu *iommu)
+{
+	struct dmar_domain *domain;
+	int i;
+
+	if (!iommu)
+		return;
+
+	i = find_first_bit(iommu->domain_ids, cap_ndoms(iommu->cap));
+	for (; i < cap_ndoms(iommu->cap); ) {
+		domain = iommu->domains[i];
+		clear_bit(i, iommu->domain_ids);
+		domain_exit(domain);
+		i = find_next_bit(iommu->domain_ids,
+			cap_ndoms(iommu->cap), i+1);
+	}
+
+	if (iommu->gcmd & DMA_GCMD_TE)
+		iommu_disable_translation(iommu);
+
+	if (iommu->irq) {
+		set_irq_data(iommu->irq, NULL);
+		/* This will mask the irq */
+		free_irq(iommu->irq, iommu);
+		destroy_irq(iommu->irq);
+	}
+
+	kfree(iommu->domains);
+	kfree(iommu->domain_ids);
+
+	/* free context mapping */
+	free_context_table(iommu);
+
+	if (iommu->reg)
+		iounmap(iommu->reg);
+	kfree(iommu);
+}
+
+static struct dmar_domain * iommu_alloc_domain(struct intel_iommu *iommu)
+{
+	unsigned long num;
+	unsigned long ndomains;
+	struct dmar_domain *domain;
+	unsigned long flags;
+
+	domain = alloc_domain_mem();
+	if (!domain)
+		return NULL;
+
+	ndomains = cap_ndoms(iommu->cap);
+
+	spin_lock_irqsave(&iommu->lock, flags);
+	num = find_first_zero_bit(iommu->domain_ids, ndomains);
+	if (num >= ndomains) {
+		spin_unlock_irqrestore(&iommu->lock, flags);
+		free_domain_mem(domain);
+		printk(KERN_ERR "IOMMU: no free domain ids\n");
+		return NULL;
+	}
+
+	set_bit(num, iommu->domain_ids);
+	domain->id = num;
+	domain->iommu = iommu;
+	iommu->domains[num] = domain;
+	spin_unlock_irqrestore(&iommu->lock, flags);
+
+	return domain;
+}
+
+static void iommu_free_domain(struct dmar_domain *domain)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&domain->iommu->lock, flags);
+	clear_bit(domain->id, domain->iommu->domain_ids);
+	spin_unlock_irqrestore(&domain->iommu->lock, flags);
+}
+
+static struct iova_domain reserved_iova_list;
+
+static void dmar_init_reserved_ranges(void)
+{
+	struct pci_dev *pdev = NULL;
+	struct iova *iova;
+	int i;
+	u64 addr, size;
+
+	init_iova_domain(&reserved_iova_list);
+
+	/* IOAPIC ranges shouldn't be accessed by DMA */
+	iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
+		IOVA_PFN(IOAPIC_RANGE_END));
+	if (!iova)
+		printk(KERN_ERR "Reserve IOAPIC range failed\n");
+
+	/* Reserve all PCI MMIO to avoid peer-to-peer access */
+	for_each_pci_dev(pdev) {
+		struct resource *r;
+
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			r = &pdev->resource[i];
+			if (!r->flags || !(r->flags & IORESOURCE_MEM))
+				continue;
+			addr = r->start;
+			addr &= PAGE_MASK_4K;
+			size = r->end - addr;
+			size = PAGE_ALIGN_4K(size);
+			iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr),
+				IOVA_PFN(size + addr) - 1);
+			if (!iova)
+				printk(KERN_ERR "Reserve iova failed\n");
+		}
+	}
+
+}
+
+static void domain_reserve_special_ranges(struct dmar_domain *domain)
+{
+	copy_reserved_iova(&reserved_iova_list, &domain->iovad);
+}
+
+static inline int guestwidth_to_adjustwidth(int gaw)
+{
+	int agaw;
+	int r = (gaw - 12) % 9;
+
+	if (r == 0)
+		agaw = gaw;
+	else
+		agaw = gaw + 9 - r;
+	if (agaw > 64)
+		agaw = 64;
+	return agaw;
+}
+
+static int domain_init(struct dmar_domain *domain, int guest_width)
+{
+	struct intel_iommu *iommu;
+	int adjust_width, agaw;
+	unsigned long sagaw;
+
+	init_iova_domain(&domain->iovad);
+	spin_lock_init(&domain->mapping_lock);
+
+	domain_reserve_special_ranges(domain);
+
+	/* calculate AGAW */
+	iommu = domain->iommu;
+	if (guest_width > cap_mgaw(iommu->cap))
+		guest_width = cap_mgaw(iommu->cap);
+	domain->gaw = guest_width;
+	adjust_width = guestwidth_to_adjustwidth(guest_width);
+	agaw = width_to_agaw(adjust_width);
+	sagaw = cap_sagaw(iommu->cap);
+	if (!test_bit(agaw, &sagaw)) {
+		/* hardware doesn't support it, choose a bigger one */
+		pr_debug("IOMMU: hardware doesn't support agaw %d\n", agaw);
+		agaw = find_next_bit(&sagaw, 5, agaw);
+		if (agaw >= 5)
+			return -ENODEV;
+	}
+	domain->agaw = agaw;
+	INIT_LIST_HEAD(&domain->devices);
+
+	/* always allocate the top pgd */
+	domain->pgd = (struct dma_pte *)alloc_pgtable_page();
+	if (!domain->pgd)
+		return -ENOMEM;
+	__iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE_4K);
+	return 0;
+}
+
+static void domain_exit(struct dmar_domain *domain)
+{
+	u64 end;
+
+	/* Domain 0 is reserved, so dont process it */
+	if (!domain)
+		return;
+
+	domain_remove_dev_info(domain);
+	/* destroy iovas */
+	put_iova_domain(&domain->iovad);
+	end = DOMAIN_MAX_ADDR(domain->gaw);
+	end = end & (~PAGE_MASK_4K);
+
+	/* clear ptes */
+	dma_pte_clear_range(domain, 0, end);
+
+	/* free page tables */
+	dma_pte_free_pagetable(domain, 0, end);
+
+	iommu_free_domain(domain);
+	free_domain_mem(domain);
+}
+
+static int domain_context_mapping_one(struct dmar_domain *domain,
+		u8 bus, u8 devfn)
+{
+	struct context_entry *context;
+	struct intel_iommu *iommu = domain->iommu;
+	unsigned long flags;
+
+	pr_debug("Set context mapping for %02x:%02x.%d\n",
+		bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+	BUG_ON(!domain->pgd);
+	context = device_to_context_entry(iommu, bus, devfn);
+	if (!context)
+		return -ENOMEM;
+	spin_lock_irqsave(&iommu->lock, flags);
+	if (context_present(*context)) {
+		spin_unlock_irqrestore(&iommu->lock, flags);
+		return 0;
+	}
+
+	context_set_domain_id(*context, domain->id);
+	context_set_address_width(*context, domain->agaw);
+	context_set_address_root(*context, virt_to_phys(domain->pgd));
+	context_set_translation_type(*context, CONTEXT_TT_MULTI_LEVEL);
+	context_set_fault_enable(*context);
+	context_set_present(*context);
+	__iommu_flush_cache(iommu, context, sizeof(*context));
+
+	/* it's a non-present to present mapping */
+	if (iommu_flush_context_device(iommu, domain->id,
+			(((u16)bus) << 8) | devfn, DMA_CCMD_MASK_NOBIT, 1))
+		iommu_flush_write_buffer(iommu);
+	else
+		iommu_flush_iotlb_dsi(iommu, 0, 0);
+	spin_unlock_irqrestore(&iommu->lock, flags);
+	return 0;
+}
+
+static int
+domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
+{
+	int ret;
+	struct pci_dev *tmp, *parent;
+
+	ret = domain_context_mapping_one(domain, pdev->bus->number,
+		pdev->devfn);
+	if (ret)
+		return ret;
+
+	/* dependent device mapping */
+	tmp = pci_find_upstream_pcie_bridge(pdev);
+	if (!tmp)
+		return 0;
+	/* Secondary interface's bus number and devfn 0 */
+	parent = pdev->bus->self;
+	while (parent != tmp) {
+		ret = domain_context_mapping_one(domain, parent->bus->number,
+			parent->devfn);
+		if (ret)
+			return ret;
+		parent = parent->bus->self;
+	}
+	if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+		return domain_context_mapping_one(domain,
+			tmp->subordinate->number, 0);
+	else /* this is a legacy PCI bridge */
+		return domain_context_mapping_one(domain,
+			tmp->bus->number, tmp->devfn);
+}
+
+static int domain_context_mapped(struct dmar_domain *domain,
+	struct pci_dev *pdev)
+{
+	int ret;
+	struct pci_dev *tmp, *parent;
+
+	ret = device_context_mapped(domain->iommu,
+		pdev->bus->number, pdev->devfn);
+	if (!ret)
+		return ret;
+	/* dependent device mapping */
+	tmp = pci_find_upstream_pcie_bridge(pdev);
+	if (!tmp)
+		return ret;
+	/* Secondary interface's bus number and devfn 0 */
+	parent = pdev->bus->self;
+	while (parent != tmp) {
+		ret = device_context_mapped(domain->iommu, parent->bus->number,
+			parent->devfn);
+		if (!ret)
+			return ret;
+		parent = parent->bus->self;
+	}
+	if (tmp->is_pcie)
+		return device_context_mapped(domain->iommu,
+			tmp->subordinate->number, 0);
+	else
+		return device_context_mapped(domain->iommu,
+			tmp->bus->number, tmp->devfn);
+}
+
+static int
+domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova,
+			u64 hpa, size_t size, int prot)
+{
+	u64 start_pfn, end_pfn;
+	struct dma_pte *pte;
+	int index;
+
+	if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
+		return -EINVAL;
+	iova &= PAGE_MASK_4K;
+	start_pfn = ((u64)hpa) >> PAGE_SHIFT_4K;
+	end_pfn = (PAGE_ALIGN_4K(((u64)hpa) + size)) >> PAGE_SHIFT_4K;
+	index = 0;
+	while (start_pfn < end_pfn) {
+		pte = addr_to_dma_pte(domain, iova + PAGE_SIZE_4K * index);
+		if (!pte)
+			return -ENOMEM;
+		/* We don't need lock here, nobody else
+		 * touches the iova range
+		 */
+		BUG_ON(dma_pte_addr(*pte));
+		dma_set_pte_addr(*pte, start_pfn << PAGE_SHIFT_4K);
+		dma_set_pte_prot(*pte, prot);
+		__iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
+		start_pfn++;
+		index++;
+	}
+	return 0;
+}
+
+static void detach_domain_for_dev(struct dmar_domain *domain, u8 bus, u8 devfn)
+{
+	clear_context_table(domain->iommu, bus, devfn);
+	iommu_flush_context_global(domain->iommu, 0);
+	iommu_flush_iotlb_global(domain->iommu, 0);
+}
+
+static void domain_remove_dev_info(struct dmar_domain *domain)
+{
+	struct device_domain_info *info;
+	unsigned long flags;
+
+	spin_lock_irqsave(&device_domain_lock, flags);
+	while (!list_empty(&domain->devices)) {
+		info = list_entry(domain->devices.next,
+			struct device_domain_info, link);
+		list_del(&info->link);
+		list_del(&info->global);
+		if (info->dev)
+			info->dev->dev.archdata.iommu = NULL;
+		spin_unlock_irqrestore(&device_domain_lock, flags);
+
+		detach_domain_for_dev(info->domain, info->bus, info->devfn);
+		free_devinfo_mem(info);
+
+		spin_lock_irqsave(&device_domain_lock, flags);
+	}
+	spin_unlock_irqrestore(&device_domain_lock, flags);
+}
+
+/*
+ * find_domain
+ * Note: we use struct pci_dev->dev.archdata.iommu stores the info
+ */
+struct dmar_domain *
+find_domain(struct pci_dev *pdev)
+{
+	struct device_domain_info *info;
+
+	/* No lock here, assumes no domain exit in normal case */
+	info = pdev->dev.archdata.iommu;
+	if (info)
+		return info->domain;
+	return NULL;
+}
+
+static int dmar_pci_device_match(struct pci_dev *devices[], int cnt,
+     struct pci_dev *dev)
+{
+	int index;
+
+	while (dev) {
+		for (index = 0; index < cnt; index ++)
+			if (dev == devices[index])
+				return 1;
+
+		/* Check our parent */
+		dev = dev->bus->self;
+	}
+
+	return 0;
+}
+
+static struct dmar_drhd_unit *
+dmar_find_matched_drhd_unit(struct pci_dev *dev)
+{
+	struct dmar_drhd_unit *drhd = NULL;
+
+	list_for_each_entry(drhd, &dmar_drhd_units, list) {
+		if (drhd->include_all || dmar_pci_device_match(drhd->devices,
+						drhd->devices_cnt, dev))
+			return drhd;
+	}
+
+	return NULL;
+}
+
+/* domain is initialized */
+static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
+{
+	struct dmar_domain *domain, *found = NULL;
+	struct intel_iommu *iommu;
+	struct dmar_drhd_unit *drhd;
+	struct device_domain_info *info, *tmp;
+	struct pci_dev *dev_tmp;
+	unsigned long flags;
+	int bus = 0, devfn = 0;
+
+	domain = find_domain(pdev);
+	if (domain)
+		return domain;
+
+	dev_tmp = pci_find_upstream_pcie_bridge(pdev);
+	if (dev_tmp) {
+		if (dev_tmp->is_pcie) {
+			bus = dev_tmp->subordinate->number;
+			devfn = 0;
+		} else {
+			bus = dev_tmp->bus->number;
+			devfn = dev_tmp->devfn;
+		}
+		spin_lock_irqsave(&device_domain_lock, flags);
+		list_for_each_entry(info, &device_domain_list, global) {
+			if (info->bus == bus && info->devfn == devfn) {
+				found = info->domain;
+				break;
+			}
+		}
+		spin_unlock_irqrestore(&device_domain_lock, flags);
+		/* pcie-pci bridge already has a domain, uses it */
+		if (found) {
+			domain = found;
+			goto found_domain;
+		}
+	}
+
+	/* Allocate new domain for the device */
+	drhd = dmar_find_matched_drhd_unit(pdev);
+	if (!drhd) {
+		printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n",
+			pci_name(pdev));
+		return NULL;
+	}
+	iommu = drhd->iommu;
+
+	domain = iommu_alloc_domain(iommu);
+	if (!domain)
+		goto error;
+
+	if (domain_init(domain, gaw)) {
+		domain_exit(domain);
+		goto error;
+	}
+
+	/* register pcie-to-pci device */
+	if (dev_tmp) {
+		info = alloc_devinfo_mem();
+		if (!info) {
+			domain_exit(domain);
+			goto error;
+		}
+		info->bus = bus;
+		info->devfn = devfn;
+		info->dev = NULL;
+		info->domain = domain;
+		/* This domain is shared by devices under p2p bridge */
+		domain->flags |= DOMAIN_FLAG_MULTIPLE_DEVICES;
+
+		/* pcie-to-pci bridge already has a domain, uses it */
+		found = NULL;
+		spin_lock_irqsave(&device_domain_lock, flags);
+		list_for_each_entry(tmp, &device_domain_list, global) {
+			if (tmp->bus == bus && tmp->devfn == devfn) {
+				found = tmp->domain;
+				break;
+			}
+		}
+		if (found) {
+			free_devinfo_mem(info);
+			domain_exit(domain);
+			domain = found;
+		} else {
+			list_add(&info->link, &domain->devices);
+			list_add(&info->global, &device_domain_list);
+		}
+		spin_unlock_irqrestore(&device_domain_lock, flags);
+	}
+
+found_domain:
+	info = alloc_devinfo_mem();
+	if (!info)
+		goto error;
+	info->bus = pdev->bus->number;
+	info->devfn = pdev->devfn;
+	info->dev = pdev;
+	info->domain = domain;
+	spin_lock_irqsave(&device_domain_lock, flags);
+	/* somebody is fast */
+	found = find_domain(pdev);
+	if (found != NULL) {
+		spin_unlock_irqrestore(&device_domain_lock, flags);
+		if (found != domain) {
+			domain_exit(domain);
+			domain = found;
+		}
+		free_devinfo_mem(info);
+		return domain;
+	}
+	list_add(&info->link, &domain->devices);
+	list_add(&info->global, &device_domain_list);
+	pdev->dev.archdata.iommu = info;
+	spin_unlock_irqrestore(&device_domain_lock, flags);
+	return domain;
+error:
+	/* recheck it here, maybe others set it */
+	return find_domain(pdev);
+}
+
+static int iommu_prepare_identity_map(struct pci_dev *pdev, u64 start, u64 end)
+{
+	struct dmar_domain *domain;
+	unsigned long size;
+	u64 base;
+	int ret;
+
+	printk(KERN_INFO
+		"IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
+		pci_name(pdev), start, end);
+	/* page table init */
+	domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
+	if (!domain)
+		return -ENOMEM;
+
+	/* The address might not be aligned */
+	base = start & PAGE_MASK_4K;
+	size = end - base;
+	size = PAGE_ALIGN_4K(size);
+	if (!reserve_iova(&domain->iovad, IOVA_PFN(base),
+			IOVA_PFN(base + size) - 1)) {
+		printk(KERN_ERR "IOMMU: reserve iova failed\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	pr_debug("Mapping reserved region %lx@%llx for %s\n",
+		size, base, pci_name(pdev));
+	/*
+	 * RMRR range might have overlap with physical memory range,
+	 * clear it first
+	 */
+	dma_pte_clear_range(domain, base, base + size);
+
+	ret = domain_page_mapping(domain, base, base, size,
+		DMA_PTE_READ|DMA_PTE_WRITE);
+	if (ret)
+		goto error;
+
+	/* context entry init */
+	ret = domain_context_mapping(domain, pdev);
+	if (!ret)
+		return 0;
+error:
+	domain_exit(domain);
+	return ret;
+
+}
+
+static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
+	struct pci_dev *pdev)
+{
+	if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+		return 0;
+	return iommu_prepare_identity_map(pdev, rmrr->base_address,
+		rmrr->end_address + 1);
+}
+
+#ifdef CONFIG_DMAR_GFX_WA
+extern int arch_get_ram_range(int slot, u64 *addr, u64 *size);
+static void __init iommu_prepare_gfx_mapping(void)
+{
+	struct pci_dev *pdev = NULL;
+	u64 base, size;
+	int slot;
+	int ret;
+
+	for_each_pci_dev(pdev) {
+		if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO ||
+				!IS_GFX_DEVICE(pdev))
+			continue;
+		printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n",
+			pci_name(pdev));
+		slot = arch_get_ram_range(0, &base, &size);
+		while (slot >= 0) {
+			ret = iommu_prepare_identity_map(pdev,
+					base, base + size);
+			if (ret)
+				goto error;
+			slot = arch_get_ram_range(slot, &base, &size);
+		}
+		continue;
+error:
+		printk(KERN_ERR "IOMMU: mapping reserved region failed\n");
+	}
+}
+#endif
+
+#ifdef CONFIG_DMAR_FLOPPY_WA
+static inline void iommu_prepare_isa(void)
+{
+	struct pci_dev *pdev;
+	int ret;
+
+	pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
+	if (!pdev)
+		return;
+
+	printk(KERN_INFO "IOMMU: Prepare 0-16M unity mapping for LPC\n");
+	ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);
+
+	if (ret)
+		printk("IOMMU: Failed to create 0-64M identity map, "
+			"floppy might not work\n");
+
+}
+#else
+static inline void iommu_prepare_isa(void)
+{
+	return;
+}
+#endif /* !CONFIG_DMAR_FLPY_WA */
+
+int __init init_dmars(void)
+{
+	struct dmar_drhd_unit *drhd;
+	struct dmar_rmrr_unit *rmrr;
+	struct pci_dev *pdev;
+	struct intel_iommu *iommu;
+	int ret, unit = 0;
+
+	/*
+	 * for each drhd
+	 *    allocate root
+	 *    initialize and program root entry to not present
+	 * endfor
+	 */
+	for_each_drhd_unit(drhd) {
+		if (drhd->ignored)
+			continue;
+		iommu = alloc_iommu(drhd);
+		if (!iommu) {
+			ret = -ENOMEM;
+			goto error;
+		}
+
+		/*
+		 * TBD:
+		 * we could share the same root & context tables
+		 * amoung all IOMMU's. Need to Split it later.
+		 */
+		ret = iommu_alloc_root_entry(iommu);
+		if (ret) {
+			printk(KERN_ERR "IOMMU: allocate root entry failed\n");
+			goto error;
+		}
+	}
+
+	/*
+	 * For each rmrr
+	 *   for each dev attached to rmrr
+	 *   do
+	 *     locate drhd for dev, alloc domain for dev
+	 *     allocate free domain
+	 *     allocate page table entries for rmrr
+	 *     if context not allocated for bus
+	 *           allocate and init context
+	 *           set present in root table for this bus
+	 *     init context with domain, translation etc
+	 *    endfor
+	 * endfor
+	 */
+	for_each_rmrr_units(rmrr) {
+		int i;
+		for (i = 0; i < rmrr->devices_cnt; i++) {
+			pdev = rmrr->devices[i];
+			/* some BIOS lists non-exist devices in DMAR table */
+			if (!pdev)
+				continue;
+			ret = iommu_prepare_rmrr_dev(rmrr, pdev);
+			if (ret)
+				printk(KERN_ERR
+				 "IOMMU: mapping reserved region failed\n");
+		}
+	}
+
+	iommu_prepare_gfx_mapping();
+
+	iommu_prepare_isa();
+
+	/*
+	 * for each drhd
+	 *   enable fault log
+	 *   global invalidate context cache
+	 *   global invalidate iotlb
+	 *   enable translation
+	 */
+	for_each_drhd_unit(drhd) {
+		if (drhd->ignored)
+			continue;
+		iommu = drhd->iommu;
+		sprintf (iommu->name, "dmar%d", unit++);
+
+		iommu_flush_write_buffer(iommu);
+
+		ret = dmar_set_interrupt(iommu);
+		if (ret)
+			goto error;
+
+		iommu_set_root_entry(iommu);
+
+		iommu_flush_context_global(iommu, 0);
+		iommu_flush_iotlb_global(iommu, 0);
+
+		ret = iommu_enable_translation(iommu);
+		if (ret)
+			goto error;
+	}
+
+	return 0;
+error:
+	for_each_drhd_unit(drhd) {
+		if (drhd->ignored)
+			continue;
+		iommu = drhd->iommu;
+		free_iommu(iommu);
+	}
+	return ret;
+}
+
+static inline u64 aligned_size(u64 host_addr, size_t size)
+{
+	u64 addr;
+	addr = (host_addr & (~PAGE_MASK_4K)) + size;
+	return PAGE_ALIGN_4K(addr);
+}
+
+struct iova *
+iommu_alloc_iova(struct dmar_domain *domain, size_t size, u64 end)
+{
+	struct iova *piova;
+
+	/* Make sure it's in range */
+	end = min_t(u64, DOMAIN_MAX_ADDR(domain->gaw), end);
+	if (!size || (IOVA_START_ADDR + size > end))
+		return NULL;
+
+	piova = alloc_iova(&domain->iovad,
+			size >> PAGE_SHIFT_4K, IOVA_PFN(end), 1);
+	return piova;
+}
+
+static struct iova *
+__intel_alloc_iova(struct device *dev, struct dmar_domain *domain,
+		size_t size)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct iova *iova = NULL;
+
+	if ((pdev->dma_mask <= DMA_32BIT_MASK) || (dmar_forcedac)) {
+		iova = iommu_alloc_iova(domain, size, pdev->dma_mask);
+	} else  {
+		/*
+		 * First try to allocate an io virtual address in
+		 * DMA_32BIT_MASK and if that fails then try allocating
+		 * from higer range
+		 */
+		iova = iommu_alloc_iova(domain, size, DMA_32BIT_MASK);
+		if (!iova)
+			iova = iommu_alloc_iova(domain, size, pdev->dma_mask);
+	}
+
+	if (!iova) {
+		printk(KERN_ERR"Allocating iova for %s failed", pci_name(pdev));
+		return NULL;
+	}
+
+	return iova;
+}
+
+static struct dmar_domain *
+get_valid_domain_for_dev(struct pci_dev *pdev)
+{
+	struct dmar_domain *domain;
+	int ret;
+
+	domain = get_domain_for_dev(pdev,
+			DEFAULT_DOMAIN_ADDRESS_WIDTH);
+	if (!domain) {
+		printk(KERN_ERR
+			"Allocating domain for %s failed", pci_name(pdev));
+		return 0;
+	}
+
+	/* make sure context mapping is ok */
+	if (unlikely(!domain_context_mapped(domain, pdev))) {
+		ret = domain_context_mapping(domain, pdev);
+		if (ret) {
+			printk(KERN_ERR
+				"Domain context map for %s failed",
+				pci_name(pdev));
+			return 0;
+		}
+	}
+
+	return domain;
+}
+
+static dma_addr_t intel_map_single(struct device *hwdev, void *addr,
+	size_t size, int dir)
+{
+	struct pci_dev *pdev = to_pci_dev(hwdev);
+	int ret;
+	struct dmar_domain *domain;
+	unsigned long start_addr;
+	struct iova *iova;
+	int prot = 0;
+
+	BUG_ON(dir == DMA_NONE);
+	if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+		return virt_to_bus(addr);
+
+	domain = get_valid_domain_for_dev(pdev);
+	if (!domain)
+		return 0;
+
+	addr = (void *)virt_to_phys(addr);
+	size = aligned_size((u64)addr, size);
+
+	iova = __intel_alloc_iova(hwdev, domain, size);
+	if (!iova)
+		goto error;
+
+	start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+
+	/*
+	 * Check if DMAR supports zero-length reads on write only
+	 * mappings..
+	 */
+	if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
+			!cap_zlr(domain->iommu->cap))
+		prot |= DMA_PTE_READ;
+	if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
+		prot |= DMA_PTE_WRITE;
+	/*
+	 * addr - (addr + size) might be partial page, we should map the whole
+	 * page.  Note: if two part of one page are separately mapped, we
+	 * might have two guest_addr mapping to the same host addr, but this
+	 * is not a big problem
+	 */
+	ret = domain_page_mapping(domain, start_addr,
+		((u64)addr) & PAGE_MASK_4K, size, prot);
+	if (ret)
+		goto error;
+
+	pr_debug("Device %s request: %lx@%llx mapping: %lx@%llx, dir %d\n",
+		pci_name(pdev), size, (u64)addr,
+		size, (u64)start_addr, dir);
+
+	/* it's a non-present to present mapping */
+	ret = iommu_flush_iotlb_psi(domain->iommu, domain->id,
+			start_addr, size >> PAGE_SHIFT_4K, 1);
+	if (ret)
+		iommu_flush_write_buffer(domain->iommu);
+
+	return (start_addr + ((u64)addr & (~PAGE_MASK_4K)));
+
+error:
+	if (iova)
+		__free_iova(&domain->iovad, iova);
+	printk(KERN_ERR"Device %s request: %lx@%llx dir %d --- failed\n",
+		pci_name(pdev), size, (u64)addr, dir);
+	return 0;
+}
+
+static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr,
+	size_t size, int dir)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct dmar_domain *domain;
+	unsigned long start_addr;
+	struct iova *iova;
+
+	if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+		return;
+	domain = find_domain(pdev);
+	BUG_ON(!domain);
+
+	iova = find_iova(&domain->iovad, IOVA_PFN(dev_addr));
+	if (!iova)
+		return;
+
+	start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+	size = aligned_size((u64)dev_addr, size);
+
+	pr_debug("Device %s unmapping: %lx@%llx\n",
+		pci_name(pdev), size, (u64)start_addr);
+
+	/*  clear the whole page */
+	dma_pte_clear_range(domain, start_addr, start_addr + size);
+	/* free page tables */
+	dma_pte_free_pagetable(domain, start_addr, start_addr + size);
+
+	if (iommu_flush_iotlb_psi(domain->iommu, domain->id, start_addr,
+			size >> PAGE_SHIFT_4K, 0))
+		iommu_flush_write_buffer(domain->iommu);
+
+	/* free iova */
+	__free_iova(&domain->iovad, iova);
+}
+
+static void * intel_alloc_coherent(struct device *hwdev, size_t size,
+		       dma_addr_t *dma_handle, gfp_t flags)
+{
+	void *vaddr;
+	int order;
+
+	size = PAGE_ALIGN_4K(size);
+	order = get_order(size);
+	flags &= ~(GFP_DMA | GFP_DMA32);
+
+	vaddr = (void *)__get_free_pages(flags, order);
+	if (!vaddr)
+		return NULL;
+	memset(vaddr, 0, size);
+
+	*dma_handle = intel_map_single(hwdev, vaddr, size, DMA_BIDIRECTIONAL);
+	if (*dma_handle)
+		return vaddr;
+	free_pages((unsigned long)vaddr, order);
+	return NULL;
+}
+
+static void intel_free_coherent(struct device *hwdev, size_t size,
+	void *vaddr, dma_addr_t dma_handle)
+{
+	int order;
+
+	size = PAGE_ALIGN_4K(size);
+	order = get_order(size);
+
+	intel_unmap_single(hwdev, dma_handle, size, DMA_BIDIRECTIONAL);
+	free_pages((unsigned long)vaddr, order);
+}
+
+#define SG_ENT_VIRT_ADDRESS(sg)	(sg_virt((sg)))
+static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
+	int nelems, int dir)
+{
+	int i;
+	struct pci_dev *pdev = to_pci_dev(hwdev);
+	struct dmar_domain *domain;
+	unsigned long start_addr;
+	struct iova *iova;
+	size_t size = 0;
+	void *addr;
+	struct scatterlist *sg;
+
+	if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+		return;
+
+	domain = find_domain(pdev);
+
+	iova = find_iova(&domain->iovad, IOVA_PFN(sglist[0].dma_address));
+	if (!iova)
+		return;
+	for_each_sg(sglist, sg, nelems, i) {
+		addr = SG_ENT_VIRT_ADDRESS(sg);
+		size += aligned_size((u64)addr, sg->length);
+	}
+
+	start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+
+	/*  clear the whole page */
+	dma_pte_clear_range(domain, start_addr, start_addr + size);
+	/* free page tables */
+	dma_pte_free_pagetable(domain, start_addr, start_addr + size);
+
+	if (iommu_flush_iotlb_psi(domain->iommu, domain->id, start_addr,
+			size >> PAGE_SHIFT_4K, 0))
+		iommu_flush_write_buffer(domain->iommu);
+
+	/* free iova */
+	__free_iova(&domain->iovad, iova);
+}
+
+static int intel_nontranslate_map_sg(struct device *hddev,
+	struct scatterlist *sglist, int nelems, int dir)
+{
+	int i;
+	struct scatterlist *sg;
+
+	for_each_sg(sglist, sg, nelems, i) {
+		BUG_ON(!sg_page(sg));
+		sg->dma_address = virt_to_bus(SG_ENT_VIRT_ADDRESS(sg));
+		sg->dma_length = sg->length;
+	}
+	return nelems;
+}
+
+static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist,
+				int nelems, int dir)
+{
+	void *addr;
+	int i;
+	struct pci_dev *pdev = to_pci_dev(hwdev);
+	struct dmar_domain *domain;
+	size_t size = 0;
+	int prot = 0;
+	size_t offset = 0;
+	struct iova *iova = NULL;
+	int ret;
+	struct scatterlist *sg;
+	unsigned long start_addr;
+
+	BUG_ON(dir == DMA_NONE);
+	if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+		return intel_nontranslate_map_sg(hwdev, sglist, nelems, dir);
+
+	domain = get_valid_domain_for_dev(pdev);
+	if (!domain)
+		return 0;
+
+	for_each_sg(sglist, sg, nelems, i) {
+		addr = SG_ENT_VIRT_ADDRESS(sg);
+		addr = (void *)virt_to_phys(addr);
+		size += aligned_size((u64)addr, sg->length);
+	}
+
+	iova = __intel_alloc_iova(hwdev, domain, size);
+	if (!iova) {
+		sglist->dma_length = 0;
+		return 0;
+	}
+
+	/*
+	 * Check if DMAR supports zero-length reads on write only
+	 * mappings..
+	 */
+	if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
+			!cap_zlr(domain->iommu->cap))
+		prot |= DMA_PTE_READ;
+	if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
+		prot |= DMA_PTE_WRITE;
+
+	start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+	offset = 0;
+	for_each_sg(sglist, sg, nelems, i) {
+		addr = SG_ENT_VIRT_ADDRESS(sg);
+		addr = (void *)virt_to_phys(addr);
+		size = aligned_size((u64)addr, sg->length);
+		ret = domain_page_mapping(domain, start_addr + offset,
+			((u64)addr) & PAGE_MASK_4K,
+			size, prot);
+		if (ret) {
+			/*  clear the page */
+			dma_pte_clear_range(domain, start_addr,
+				  start_addr + offset);
+			/* free page tables */
+			dma_pte_free_pagetable(domain, start_addr,
+				  start_addr + offset);
+			/* free iova */
+			__free_iova(&domain->iovad, iova);
+			return 0;
+		}
+		sg->dma_address = start_addr + offset +
+				((u64)addr & (~PAGE_MASK_4K));
+		sg->dma_length = sg->length;
+		offset += size;
+	}
+
+	/* it's a non-present to present mapping */
+	if (iommu_flush_iotlb_psi(domain->iommu, domain->id,
+			start_addr, offset >> PAGE_SHIFT_4K, 1))
+		iommu_flush_write_buffer(domain->iommu);
+	return nelems;
+}
+
+static struct dma_mapping_ops intel_dma_ops = {
+	.alloc_coherent = intel_alloc_coherent,
+	.free_coherent = intel_free_coherent,
+	.map_single = intel_map_single,
+	.unmap_single = intel_unmap_single,
+	.map_sg = intel_map_sg,
+	.unmap_sg = intel_unmap_sg,
+};
+
+static inline int iommu_domain_cache_init(void)
+{
+	int ret = 0;
+
+	iommu_domain_cache = kmem_cache_create("iommu_domain",
+					 sizeof(struct dmar_domain),
+					 0,
+					 SLAB_HWCACHE_ALIGN,
+
+					 NULL);
+	if (!iommu_domain_cache) {
+		printk(KERN_ERR "Couldn't create iommu_domain cache\n");
+		ret = -ENOMEM;
+	}
+
+	return ret;
+}
+
+static inline int iommu_devinfo_cache_init(void)
+{
+	int ret = 0;
+
+	iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
+					 sizeof(struct device_domain_info),
+					 0,
+					 SLAB_HWCACHE_ALIGN,
+
+					 NULL);
+	if (!iommu_devinfo_cache) {
+		printk(KERN_ERR "Couldn't create devinfo cache\n");
+		ret = -ENOMEM;
+	}
+
+	return ret;
+}
+
+static inline int iommu_iova_cache_init(void)
+{
+	int ret = 0;
+
+	iommu_iova_cache = kmem_cache_create("iommu_iova",
+					 sizeof(struct iova),
+					 0,
+					 SLAB_HWCACHE_ALIGN,
+
+					 NULL);
+	if (!iommu_iova_cache) {
+		printk(KERN_ERR "Couldn't create iova cache\n");
+		ret = -ENOMEM;
+	}
+
+	return ret;
+}
+
+static int __init iommu_init_mempool(void)
+{
+	int ret;
+	ret = iommu_iova_cache_init();
+	if (ret)
+		return ret;
+
+	ret = iommu_domain_cache_init();
+	if (ret)
+		goto domain_error;
+
+	ret = iommu_devinfo_cache_init();
+	if (!ret)
+		return ret;
+
+	kmem_cache_destroy(iommu_domain_cache);
+domain_error:
+	kmem_cache_destroy(iommu_iova_cache);
+
+	return -ENOMEM;
+}
+
+static void __init iommu_exit_mempool(void)
+{
+	kmem_cache_destroy(iommu_devinfo_cache);
+	kmem_cache_destroy(iommu_domain_cache);
+	kmem_cache_destroy(iommu_iova_cache);
+
+}
+
+void __init detect_intel_iommu(void)
+{
+	if (swiotlb || no_iommu || iommu_detected || dmar_disabled)
+		return;
+	if (early_dmar_detect()) {
+		iommu_detected = 1;
+	}
+}
+
+static void __init init_no_remapping_devices(void)
+{
+	struct dmar_drhd_unit *drhd;
+
+	for_each_drhd_unit(drhd) {
+		if (!drhd->include_all) {
+			int i;
+			for (i = 0; i < drhd->devices_cnt; i++)
+				if (drhd->devices[i] != NULL)
+					break;
+			/* ignore DMAR unit if no pci devices exist */
+			if (i == drhd->devices_cnt)
+				drhd->ignored = 1;
+		}
+	}
+
+	if (dmar_map_gfx)
+		return;
+
+	for_each_drhd_unit(drhd) {
+		int i;
+		if (drhd->ignored || drhd->include_all)
+			continue;
+
+		for (i = 0; i < drhd->devices_cnt; i++)
+			if (drhd->devices[i] &&
+				!IS_GFX_DEVICE(drhd->devices[i]))
+				break;
+
+		if (i < drhd->devices_cnt)
+			continue;
+
+		/* bypass IOMMU if it is just for gfx devices */
+		drhd->ignored = 1;
+		for (i = 0; i < drhd->devices_cnt; i++) {
+			if (!drhd->devices[i])
+				continue;
+			drhd->devices[i]->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
+		}
+	}
+}
+
+int __init intel_iommu_init(void)
+{
+	int ret = 0;
+
+	if (no_iommu || swiotlb || dmar_disabled)
+		return -ENODEV;
+
+	if (dmar_table_init())
+		return 	-ENODEV;
+
+	iommu_init_mempool();
+	dmar_init_reserved_ranges();
+
+	init_no_remapping_devices();
+
+	ret = init_dmars();
+	if (ret) {
+		printk(KERN_ERR "IOMMU: dmar init failed\n");
+		put_iova_domain(&reserved_iova_list);
+		iommu_exit_mempool();
+		return ret;
+	}
+	printk(KERN_INFO
+	"PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n");
+
+	force_iommu = 1;
+	dma_ops = &intel_dma_ops;
+	return 0;
+}
+
diff --git a/drivers/pci/intel-iommu.h b/drivers/pci/intel-iommu.h
new file mode 100644
index 0000000..ee88dd2
--- /dev/null
+++ b/drivers/pci/intel-iommu.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * Copyright (C) Ashok Raj <ashok.raj@intel.com>
+ * Copyright (C) Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ */
+
+#ifndef _INTEL_IOMMU_H_
+#define _INTEL_IOMMU_H_
+
+#include <linux/types.h>
+#include <linux/msi.h>
+#include "iova.h"
+#include <linux/io.h>
+
+/*
+ * Intel IOMMU register specification per version 1.0 public spec.
+ */
+
+#define	DMAR_VER_REG	0x0	/* Arch version supported by this IOMMU */
+#define	DMAR_CAP_REG	0x8	/* Hardware supported capabilities */
+#define	DMAR_ECAP_REG	0x10	/* Extended capabilities supported */
+#define	DMAR_GCMD_REG	0x18	/* Global command register */
+#define	DMAR_GSTS_REG	0x1c	/* Global status register */
+#define	DMAR_RTADDR_REG	0x20	/* Root entry table */
+#define	DMAR_CCMD_REG	0x28	/* Context command reg */
+#define	DMAR_FSTS_REG	0x34	/* Fault Status register */
+#define	DMAR_FECTL_REG	0x38	/* Fault control register */
+#define	DMAR_FEDATA_REG	0x3c	/* Fault event interrupt data register */
+#define	DMAR_FEADDR_REG	0x40	/* Fault event interrupt addr register */
+#define	DMAR_FEUADDR_REG 0x44	/* Upper address register */
+#define	DMAR_AFLOG_REG	0x58	/* Advanced Fault control */
+#define	DMAR_PMEN_REG	0x64	/* Enable Protected Memory Region */
+#define	DMAR_PLMBASE_REG 0x68	/* PMRR Low addr */
+#define	DMAR_PLMLIMIT_REG 0x6c	/* PMRR low limit */
+#define	DMAR_PHMBASE_REG 0x70	/* pmrr high base addr */
+#define	DMAR_PHMLIMIT_REG 0x78	/* pmrr high limit */
+
+#define OFFSET_STRIDE		(9)
+/*
+#define dmar_readl(dmar, reg) readl(dmar + reg)
+#define dmar_readq(dmar, reg) ({ \
+		u32 lo, hi; \
+		lo = readl(dmar + reg); \
+		hi = readl(dmar + reg + 4); \
+		(((u64) hi) << 32) + lo; })
+*/
+static inline u64 dmar_readq(void *addr)
+{
+	u32 lo, hi;
+	lo = readl(addr);
+	hi = readl(addr + 4);
+	return (((u64) hi) << 32) + lo;
+}
+
+static inline void dmar_writeq(void __iomem *addr, u64 val)
+{
+	writel((u32)val, addr);
+	writel((u32)(val >> 32), addr + 4);
+}
+
+#define DMAR_VER_MAJOR(v)		(((v) & 0xf0) >> 4)
+#define DMAR_VER_MINOR(v)		((v) & 0x0f)
+
+/*
+ * Decoding Capability Register
+ */
+#define cap_read_drain(c)	(((c) >> 55) & 1)
+#define cap_write_drain(c)	(((c) >> 54) & 1)
+#define cap_max_amask_val(c)	(((c) >> 48) & 0x3f)
+#define cap_num_fault_regs(c)	((((c) >> 40) & 0xff) + 1)
+#define cap_pgsel_inv(c)	(((c) >> 39) & 1)
+
+#define cap_super_page_val(c)	(((c) >> 34) & 0xf)
+#define cap_super_offset(c)	(((find_first_bit(&cap_super_page_val(c), 4)) \
+					* OFFSET_STRIDE) + 21)
+
+#define cap_fault_reg_offset(c)	((((c) >> 24) & 0x3ff) * 16)
+#define cap_max_fault_reg_offset(c) \
+	(cap_fault_reg_offset(c) + cap_num_fault_regs(c) * 16)
+
+#define cap_zlr(c)		(((c) >> 22) & 1)
+#define cap_isoch(c)		(((c) >> 23) & 1)
+#define cap_mgaw(c)		((((c) >> 16) & 0x3f) + 1)
+#define cap_sagaw(c)		(((c) >> 8) & 0x1f)
+#define cap_caching_mode(c)	(((c) >> 7) & 1)
+#define cap_phmr(c)		(((c) >> 6) & 1)
+#define cap_plmr(c)		(((c) >> 5) & 1)
+#define cap_rwbf(c)		(((c) >> 4) & 1)
+#define cap_afl(c)		(((c) >> 3) & 1)
+#define cap_ndoms(c)		(((unsigned long)1) << (4 + 2 * ((c) & 0x7)))
+/*
+ * Extended Capability Register
+ */
+
+#define ecap_niotlb_iunits(e)	((((e) >> 24) & 0xff) + 1)
+#define ecap_iotlb_offset(e) 	((((e) >> 8) & 0x3ff) * 16)
+#define ecap_max_iotlb_offset(e) \
+	(ecap_iotlb_offset(e) + ecap_niotlb_iunits(e) * 16)
+#define ecap_coherent(e)	((e) & 0x1)
+
+
+/* IOTLB_REG */
+#define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60)
+#define DMA_TLB_DSI_FLUSH (((u64)2) << 60)
+#define DMA_TLB_PSI_FLUSH (((u64)3) << 60)
+#define DMA_TLB_IIRG(type) ((type >> 60) & 7)
+#define DMA_TLB_IAIG(val) (((val) >> 57) & 7)
+#define DMA_TLB_READ_DRAIN (((u64)1) << 49)
+#define DMA_TLB_WRITE_DRAIN (((u64)1) << 48)
+#define DMA_TLB_DID(id)	(((u64)((id) & 0xffff)) << 32)
+#define DMA_TLB_IVT (((u64)1) << 63)
+#define DMA_TLB_IH_NONLEAF (((u64)1) << 6)
+#define DMA_TLB_MAX_SIZE (0x3f)
+
+/* GCMD_REG */
+#define DMA_GCMD_TE (((u32)1) << 31)
+#define DMA_GCMD_SRTP (((u32)1) << 30)
+#define DMA_GCMD_SFL (((u32)1) << 29)
+#define DMA_GCMD_EAFL (((u32)1) << 28)
+#define DMA_GCMD_WBF (((u32)1) << 27)
+
+/* GSTS_REG */
+#define DMA_GSTS_TES (((u32)1) << 31)
+#define DMA_GSTS_RTPS (((u32)1) << 30)
+#define DMA_GSTS_FLS (((u32)1) << 29)
+#define DMA_GSTS_AFLS (((u32)1) << 28)
+#define DMA_GSTS_WBFS (((u32)1) << 27)
+
+/* CCMD_REG */
+#define DMA_CCMD_ICC (((u64)1) << 63)
+#define DMA_CCMD_GLOBAL_INVL (((u64)1) << 61)
+#define DMA_CCMD_DOMAIN_INVL (((u64)2) << 61)
+#define DMA_CCMD_DEVICE_INVL (((u64)3) << 61)
+#define DMA_CCMD_FM(m) (((u64)((m) & 0x3)) << 32)
+#define DMA_CCMD_MASK_NOBIT 0
+#define DMA_CCMD_MASK_1BIT 1
+#define DMA_CCMD_MASK_2BIT 2
+#define DMA_CCMD_MASK_3BIT 3
+#define DMA_CCMD_SID(s) (((u64)((s) & 0xffff)) << 16)
+#define DMA_CCMD_DID(d) ((u64)((d) & 0xffff))
+
+/* FECTL_REG */
+#define DMA_FECTL_IM (((u32)1) << 31)
+
+/* FSTS_REG */
+#define DMA_FSTS_PPF ((u32)2)
+#define DMA_FSTS_PFO ((u32)1)
+#define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff)
+
+/* FRCD_REG, 32 bits access */
+#define DMA_FRCD_F (((u32)1) << 31)
+#define dma_frcd_type(d) ((d >> 30) & 1)
+#define dma_frcd_fault_reason(c) (c & 0xff)
+#define dma_frcd_source_id(c) (c & 0xffff)
+#define dma_frcd_page_addr(d) (d & (((u64)-1) << 12)) /* low 64 bit */
+
+/*
+ * 0: Present
+ * 1-11: Reserved
+ * 12-63: Context Ptr (12 - (haw-1))
+ * 64-127: Reserved
+ */
+struct root_entry {
+	u64	val;
+	u64	rsvd1;
+};
+#define ROOT_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct root_entry))
+static inline bool root_present(struct root_entry *root)
+{
+	return (root->val & 1);
+}
+static inline void set_root_present(struct root_entry *root)
+{
+	root->val |= 1;
+}
+static inline void set_root_value(struct root_entry *root, unsigned long value)
+{
+	root->val |= value & PAGE_MASK_4K;
+}
+
+struct context_entry;
+static inline struct context_entry *
+get_context_addr_from_root(struct root_entry *root)
+{
+	return (struct context_entry *)
+		(root_present(root)?phys_to_virt(
+		root->val & PAGE_MASK_4K):
+		NULL);
+}
+
+/*
+ * low 64 bits:
+ * 0: present
+ * 1: fault processing disable
+ * 2-3: translation type
+ * 12-63: address space root
+ * high 64 bits:
+ * 0-2: address width
+ * 3-6: aval
+ * 8-23: domain id
+ */
+struct context_entry {
+	u64 lo;
+	u64 hi;
+};
+#define context_present(c) ((c).lo & 1)
+#define context_fault_disable(c) (((c).lo >> 1) & 1)
+#define context_translation_type(c) (((c).lo >> 2) & 3)
+#define context_address_root(c) ((c).lo & PAGE_MASK_4K)
+#define context_address_width(c) ((c).hi &  7)
+#define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1))
+
+#define context_set_present(c) do {(c).lo |= 1;} while (0)
+#define context_set_fault_enable(c) \
+	do {(c).lo &= (((u64)-1) << 2) | 1;} while (0)
+#define context_set_translation_type(c, val) \
+	do { \
+		(c).lo &= (((u64)-1) << 4) | 3; \
+		(c).lo |= ((val) & 3) << 2; \
+	} while (0)
+#define CONTEXT_TT_MULTI_LEVEL 0
+#define context_set_address_root(c, val) \
+	do {(c).lo |= (val) & PAGE_MASK_4K;} while (0)
+#define context_set_address_width(c, val) do {(c).hi |= (val) & 7;} while (0)
+#define context_set_domain_id(c, val) \
+	do {(c).hi |= ((val) & ((1 << 16) - 1)) << 8;} while (0)
+#define context_clear_entry(c) do {(c).lo = 0; (c).hi = 0;} while (0)
+
+/*
+ * 0: readable
+ * 1: writable
+ * 2-6: reserved
+ * 7: super page
+ * 8-11: available
+ * 12-63: Host physcial address
+ */
+struct dma_pte {
+	u64 val;
+};
+#define dma_clear_pte(p)	do {(p).val = 0;} while (0)
+
+#define DMA_PTE_READ (1)
+#define DMA_PTE_WRITE (2)
+
+#define dma_set_pte_readable(p) do {(p).val |= DMA_PTE_READ;} while (0)
+#define dma_set_pte_writable(p) do {(p).val |= DMA_PTE_WRITE;} while (0)
+#define dma_set_pte_prot(p, prot) \
+		do {(p).val = ((p).val & ~3) | ((prot) & 3); } while (0)
+#define dma_pte_addr(p) ((p).val & PAGE_MASK_4K)
+#define dma_set_pte_addr(p, addr) do {\
+		(p).val |= ((addr) & PAGE_MASK_4K); } while (0)
+#define dma_pte_present(p) (((p).val & 3) != 0)
+
+struct intel_iommu;
+
+struct dmar_domain {
+	int	id;			/* domain id */
+	struct intel_iommu *iommu;	/* back pointer to owning iommu */
+
+	struct list_head devices; 	/* all devices' list */
+	struct iova_domain iovad;	/* iova's that belong to this domain */
+
+	struct dma_pte	*pgd;		/* virtual address */
+	spinlock_t	mapping_lock;	/* page table lock */
+	int		gaw;		/* max guest address width */
+
+	/* adjusted guest address width, 0 is level 2 30-bit */
+	int		agaw;
+
+#define DOMAIN_FLAG_MULTIPLE_DEVICES 1
+	int		flags;
+};
+
+/* PCI domain-device relationship */
+struct device_domain_info {
+	struct list_head link;	/* link to domain siblings */
+	struct list_head global; /* link to global list */
+	u8 bus;			/* PCI bus numer */
+	u8 devfn;		/* PCI devfn number */
+	struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */
+	struct dmar_domain *domain; /* pointer to domain */
+};
+
+extern int init_dmars(void);
+
+struct intel_iommu {
+	void __iomem	*reg; /* Pointer to hardware regs, virtual addr */
+	u64		cap;
+	u64		ecap;
+	unsigned long 	*domain_ids; /* bitmap of domains */
+	struct dmar_domain **domains; /* ptr to domains */
+	int		seg;
+	u32		gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */
+	spinlock_t	lock; /* protect context, domain ids */
+	spinlock_t	register_lock; /* protect register handling */
+	struct root_entry *root_entry; /* virtual address */
+
+	unsigned int irq;
+	unsigned char name[7];    /* Device Name */
+	struct msi_msg saved_msg;
+	struct sys_device sysdev;
+};
+
+#ifndef CONFIG_DMAR_GFX_WA
+static inline void iommu_prepare_gfx_mapping(void)
+{
+	return;
+}
+#endif /* !CONFIG_DMAR_GFX_WA */
+
+#endif
diff --git a/drivers/pci/iova.c b/drivers/pci/iova.c
new file mode 100644
index 0000000..a84571c
--- /dev/null
+++ b/drivers/pci/iova.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This file is released under the GPLv2.
+ *
+ * Copyright (C) 2006 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ */
+
+#include "iova.h"
+
+void
+init_iova_domain(struct iova_domain *iovad)
+{
+	spin_lock_init(&iovad->iova_alloc_lock);
+	spin_lock_init(&iovad->iova_rbtree_lock);
+	iovad->rbroot = RB_ROOT;
+	iovad->cached32_node = NULL;
+
+}
+
+static struct rb_node *
+__get_cached_rbnode(struct iova_domain *iovad, unsigned long *limit_pfn)
+{
+	if ((*limit_pfn != DMA_32BIT_PFN) ||
+		(iovad->cached32_node == NULL))
+		return rb_last(&iovad->rbroot);
+	else {
+		struct rb_node *prev_node = rb_prev(iovad->cached32_node);
+		struct iova *curr_iova =
+			container_of(iovad->cached32_node, struct iova, node);
+		*limit_pfn = curr_iova->pfn_lo - 1;
+		return prev_node;
+	}
+}
+
+static void
+__cached_rbnode_insert_update(struct iova_domain *iovad,
+	unsigned long limit_pfn, struct iova *new)
+{
+	if (limit_pfn != DMA_32BIT_PFN)
+		return;
+	iovad->cached32_node = &new->node;
+}
+
+static void
+__cached_rbnode_delete_update(struct iova_domain *iovad, struct iova *free)
+{
+	struct iova *cached_iova;
+	struct rb_node *curr;
+
+	if (!iovad->cached32_node)
+		return;
+	curr = iovad->cached32_node;
+	cached_iova = container_of(curr, struct iova, node);
+
+	if (free->pfn_lo >= cached_iova->pfn_lo)
+		iovad->cached32_node = rb_next(&free->node);
+}
+
+/* Computes the padding size required, to make the
+ * the start address naturally aligned on its size
+ */
+static int
+iova_get_pad_size(int size, unsigned int limit_pfn)
+{
+	unsigned int pad_size = 0;
+	unsigned int order = ilog2(size);
+
+	if (order)
+		pad_size = (limit_pfn + 1) % (1 << order);
+
+	return pad_size;
+}
+
+static int __alloc_iova_range(struct iova_domain *iovad, unsigned long size,
+		unsigned long limit_pfn, struct iova *new, bool size_aligned)
+{
+	struct rb_node *curr = NULL;
+	unsigned long flags;
+	unsigned long saved_pfn;
+	unsigned int pad_size = 0;
+
+	/* Walk the tree backwards */
+	spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+	saved_pfn = limit_pfn;
+	curr = __get_cached_rbnode(iovad, &limit_pfn);
+	while (curr) {
+		struct iova *curr_iova = container_of(curr, struct iova, node);
+		if (limit_pfn < curr_iova->pfn_lo)
+			goto move_left;
+		else if (limit_pfn < curr_iova->pfn_hi)
+			goto adjust_limit_pfn;
+		else {
+			if (size_aligned)
+				pad_size = iova_get_pad_size(size, limit_pfn);
+			if ((curr_iova->pfn_hi + size + pad_size) <= limit_pfn)
+				break;	/* found a free slot */
+		}
+adjust_limit_pfn:
+		limit_pfn = curr_iova->pfn_lo - 1;
+move_left:
+		curr = rb_prev(curr);
+	}
+
+	if (!curr) {
+		if (size_aligned)
+			pad_size = iova_get_pad_size(size, limit_pfn);
+		if ((IOVA_START_PFN + size + pad_size) > limit_pfn) {
+			spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+			return -ENOMEM;
+		}
+	}
+
+	/* pfn_lo will point to size aligned address if size_aligned is set */
+	new->pfn_lo = limit_pfn - (size + pad_size) + 1;
+	new->pfn_hi = new->pfn_lo + size - 1;
+
+	spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+	return 0;
+}
+
+static void
+iova_insert_rbtree(struct rb_root *root, struct iova *iova)
+{
+	struct rb_node **new = &(root->rb_node), *parent = NULL;
+	/* Figure out where to put new node */
+	while (*new) {
+		struct iova *this = container_of(*new, struct iova, node);
+		parent = *new;
+
+		if (iova->pfn_lo < this->pfn_lo)
+			new = &((*new)->rb_left);
+		else if (iova->pfn_lo > this->pfn_lo)
+			new = &((*new)->rb_right);
+		else
+			BUG(); /* this should not happen */
+	}
+	/* Add new node and rebalance tree. */
+	rb_link_node(&iova->node, parent, new);
+	rb_insert_color(&iova->node, root);
+}
+
+/**
+ * alloc_iova - allocates an iova
+ * @iovad - iova domain in question
+ * @size - size of page frames to allocate
+ * @limit_pfn - max limit address
+ * @size_aligned - set if size_aligned address range is required
+ * This function allocates an iova in the range limit_pfn to IOVA_START_PFN
+ * looking from limit_pfn instead from IOVA_START_PFN. If the size_aligned
+ * flag is set then the allocated address iova->pfn_lo will be naturally
+ * aligned on roundup_power_of_two(size).
+ */
+struct iova *
+alloc_iova(struct iova_domain *iovad, unsigned long size,
+	unsigned long limit_pfn,
+	bool size_aligned)
+{
+	unsigned long flags;
+	struct iova *new_iova;
+	int ret;
+
+	new_iova = alloc_iova_mem();
+	if (!new_iova)
+		return NULL;
+
+	/* If size aligned is set then round the size to
+	 * to next power of two.
+	 */
+	if (size_aligned)
+		size = __roundup_pow_of_two(size);
+
+	spin_lock_irqsave(&iovad->iova_alloc_lock, flags);
+	ret = __alloc_iova_range(iovad, size, limit_pfn, new_iova,
+			size_aligned);
+
+	if (ret) {
+		spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags);
+		free_iova_mem(new_iova);
+		return NULL;
+	}
+
+	/* Insert the new_iova into domain rbtree by holding writer lock */
+	spin_lock(&iovad->iova_rbtree_lock);
+	iova_insert_rbtree(&iovad->rbroot, new_iova);
+	__cached_rbnode_insert_update(iovad, limit_pfn, new_iova);
+	spin_unlock(&iovad->iova_rbtree_lock);
+
+	spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags);
+
+	return new_iova;
+}
+
+/**
+ * find_iova - find's an iova for a given pfn
+ * @iovad - iova domain in question.
+ * pfn - page frame number
+ * This function finds and returns an iova belonging to the
+ * given doamin which matches the given pfn.
+ */
+struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn)
+{
+	unsigned long flags;
+	struct rb_node *node;
+
+	/* Take the lock so that no other thread is manipulating the rbtree */
+	spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+	node = iovad->rbroot.rb_node;
+	while (node) {
+		struct iova *iova = container_of(node, struct iova, node);
+
+		/* If pfn falls within iova's range, return iova */
+		if ((pfn >= iova->pfn_lo) && (pfn <= iova->pfn_hi)) {
+			spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+			/* We are not holding the lock while this iova
+			 * is referenced by the caller as the same thread
+			 * which called this function also calls __free_iova()
+			 * and it is by desing that only one thread can possibly
+			 * reference a particular iova and hence no conflict.
+			 */
+			return iova;
+		}
+
+		if (pfn < iova->pfn_lo)
+			node = node->rb_left;
+		else if (pfn > iova->pfn_lo)
+			node = node->rb_right;
+	}
+
+	spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+	return NULL;
+}
+
+/**
+ * __free_iova - frees the given iova
+ * @iovad: iova domain in question.
+ * @iova: iova in question.
+ * Frees the given iova belonging to the giving domain
+ */
+void
+__free_iova(struct iova_domain *iovad, struct iova *iova)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+	__cached_rbnode_delete_update(iovad, iova);
+	rb_erase(&iova->node, &iovad->rbroot);
+	spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+	free_iova_mem(iova);
+}
+
+/**
+ * free_iova - finds and frees the iova for a given pfn
+ * @iovad: - iova domain in question.
+ * @pfn: - pfn that is allocated previously
+ * This functions finds an iova for a given pfn and then
+ * frees the iova from that domain.
+ */
+void
+free_iova(struct iova_domain *iovad, unsigned long pfn)
+{
+	struct iova *iova = find_iova(iovad, pfn);
+	if (iova)
+		__free_iova(iovad, iova);
+
+}
+
+/**
+ * put_iova_domain - destroys the iova doamin
+ * @iovad: - iova domain in question.
+ * All the iova's in that domain are destroyed.
+ */
+void put_iova_domain(struct iova_domain *iovad)
+{
+	struct rb_node *node;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+	node = rb_first(&iovad->rbroot);
+	while (node) {
+		struct iova *iova = container_of(node, struct iova, node);
+		rb_erase(node, &iovad->rbroot);
+		free_iova_mem(iova);
+		node = rb_first(&iovad->rbroot);
+	}
+	spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+}
+
+static int
+__is_range_overlap(struct rb_node *node,
+	unsigned long pfn_lo, unsigned long pfn_hi)
+{
+	struct iova *iova = container_of(node, struct iova, node);
+
+	if ((pfn_lo <= iova->pfn_hi) && (pfn_hi >= iova->pfn_lo))
+		return 1;
+	return 0;
+}
+
+static struct iova *
+__insert_new_range(struct iova_domain *iovad,
+	unsigned long pfn_lo, unsigned long pfn_hi)
+{
+	struct iova *iova;
+
+	iova = alloc_iova_mem();
+	if (!iova)
+		return iova;
+
+	iova->pfn_hi = pfn_hi;
+	iova->pfn_lo = pfn_lo;
+	iova_insert_rbtree(&iovad->rbroot, iova);
+	return iova;
+}
+
+static void
+__adjust_overlap_range(struct iova *iova,
+	unsigned long *pfn_lo, unsigned long *pfn_hi)
+{
+	if (*pfn_lo < iova->pfn_lo)
+		iova->pfn_lo = *pfn_lo;
+	if (*pfn_hi > iova->pfn_hi)
+		*pfn_lo = iova->pfn_hi + 1;
+}
+
+/**
+ * reserve_iova - reserves an iova in the given range
+ * @iovad: - iova domain pointer
+ * @pfn_lo: - lower page frame address
+ * @pfn_hi:- higher pfn adderss
+ * This function allocates reserves the address range from pfn_lo to pfn_hi so
+ * that this address is not dished out as part of alloc_iova.
+ */
+struct iova *
+reserve_iova(struct iova_domain *iovad,
+	unsigned long pfn_lo, unsigned long pfn_hi)
+{
+	struct rb_node *node;
+	unsigned long flags;
+	struct iova *iova;
+	unsigned int overlap = 0;
+
+	spin_lock_irqsave(&iovad->iova_alloc_lock, flags);
+	spin_lock(&iovad->iova_rbtree_lock);
+	for (node = rb_first(&iovad->rbroot); node; node = rb_next(node)) {
+		if (__is_range_overlap(node, pfn_lo, pfn_hi)) {
+			iova = container_of(node, struct iova, node);
+			__adjust_overlap_range(iova, &pfn_lo, &pfn_hi);
+			if ((pfn_lo >= iova->pfn_lo) &&
+				(pfn_hi <= iova->pfn_hi))
+				goto finish;
+			overlap = 1;
+
+		} else if (overlap)
+				break;
+	}
+
+	/* We are here either becasue this is the first reserver node
+	 * or need to insert remaining non overlap addr range
+	 */
+	iova = __insert_new_range(iovad, pfn_lo, pfn_hi);
+finish:
+
+	spin_unlock(&iovad->iova_rbtree_lock);
+	spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags);
+	return iova;
+}
+
+/**
+ * copy_reserved_iova - copies the reserved between domains
+ * @from: - source doamin from where to copy
+ * @to: - destination domin where to copy
+ * This function copies reserved iova's from one doamin to
+ * other.
+ */
+void
+copy_reserved_iova(struct iova_domain *from, struct iova_domain *to)
+{
+	unsigned long flags;
+	struct rb_node *node;
+
+	spin_lock_irqsave(&from->iova_alloc_lock, flags);
+	spin_lock(&from->iova_rbtree_lock);
+	for (node = rb_first(&from->rbroot); node; node = rb_next(node)) {
+		struct iova *iova = container_of(node, struct iova, node);
+		struct iova *new_iova;
+		new_iova = reserve_iova(to, iova->pfn_lo, iova->pfn_hi);
+		if (!new_iova)
+			printk(KERN_ERR "Reserve iova range %lx@%lx failed\n",
+				iova->pfn_lo, iova->pfn_lo);
+	}
+	spin_unlock(&from->iova_rbtree_lock);
+	spin_unlock_irqrestore(&from->iova_alloc_lock, flags);
+}
diff --git a/drivers/pci/iova.h b/drivers/pci/iova.h
new file mode 100644
index 0000000..ae3028d
--- /dev/null
+++ b/drivers/pci/iova.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This file is released under the GPLv2.
+ *
+ * Copyright (C) 2006 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *
+ */
+
+#ifndef _IOVA_H_
+#define _IOVA_H_
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/rbtree.h>
+#include <linux/dma-mapping.h>
+
+/*
+ * We need a fixed PAGE_SIZE of 4K irrespective of
+ * arch PAGE_SIZE for IOMMU page tables.
+ */
+#define PAGE_SHIFT_4K		(12)
+#define PAGE_SIZE_4K		(1UL << PAGE_SHIFT_4K)
+#define PAGE_MASK_4K		(((u64)-1) << PAGE_SHIFT_4K)
+#define PAGE_ALIGN_4K(addr)	(((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K)
+
+/* IO virtual address start page frame number */
+#define IOVA_START_PFN		(1)
+
+#define IOVA_PFN(addr)		((addr) >> PAGE_SHIFT_4K)
+#define DMA_32BIT_PFN	IOVA_PFN(DMA_32BIT_MASK)
+#define DMA_64BIT_PFN	IOVA_PFN(DMA_64BIT_MASK)
+
+/* iova structure */
+struct iova {
+	struct rb_node	node;
+	unsigned long	pfn_hi; /* IOMMU dish out addr hi */
+	unsigned long	pfn_lo; /* IOMMU dish out addr lo */
+};
+
+/* holds all the iova translations for a domain */
+struct iova_domain {
+	spinlock_t	iova_alloc_lock;/* Lock to protect iova  allocation */
+	spinlock_t	iova_rbtree_lock; /* Lock to protect update of rbtree */
+	struct rb_root	rbroot;		/* iova domain rbtree root */
+	struct rb_node	*cached32_node; /* Save last alloced node */
+};
+
+struct iova *alloc_iova_mem(void);
+void free_iova_mem(struct iova *iova);
+void free_iova(struct iova_domain *iovad, unsigned long pfn);
+void __free_iova(struct iova_domain *iovad, struct iova *iova);
+struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size,
+	unsigned long limit_pfn,
+	bool size_aligned);
+struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo,
+	unsigned long pfn_hi);
+void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to);
+void init_iova_domain(struct iova_domain *iovad);
+struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
+void put_iova_domain(struct iova_domain *iovad);
+
+#endif
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 6fda33d..fc87e14 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -90,3 +90,4 @@
 	return NULL;
 }
 
+struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 5db6b66..463a5a9 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -837,6 +837,19 @@
 	kfree(pci_dev);
 }
 
+static void set_pcie_port_type(struct pci_dev *pdev)
+{
+	int pos;
+	u16 reg16;
+
+	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	if (!pos)
+		return;
+	pdev->is_pcie = 1;
+	pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
+	pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
+}
+
 /**
  * pci_cfg_space_size - get the configuration space size of the PCI device.
  * @dev: PCI device
@@ -951,6 +964,7 @@
 	dev->device = (l >> 16) & 0xffff;
 	dev->cfg_size = pci_cfg_space_size(dev);
 	dev->error_state = pci_channel_io_normal;
+	set_pcie_port_type(dev);
 
 	/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
 	   set this higher, assuming the system even supports it.  */
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index c6e79d0..b001b59 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -14,6 +14,40 @@
 #include "pci.h"
 
 DECLARE_RWSEM(pci_bus_sem);
+/*
+ * find the upstream PCIE-to-PCI bridge of a PCI device
+ * if the device is PCIE, return NULL
+ * if the device isn't connected to a PCIE bridge (that is its parent is a
+ * legacy PCI bridge and the bridge is directly connected to bus 0), return its
+ * parent
+ */
+struct pci_dev *
+pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
+{
+	struct pci_dev *tmp = NULL;
+
+	if (pdev->is_pcie)
+		return NULL;
+	while (1) {
+		if (!pdev->bus->self)
+			break;
+		pdev = pdev->bus->self;
+		/* a p2p bridge */
+		if (!pdev->is_pcie) {
+			tmp = pdev;
+			continue;
+		}
+		/* PCI device should connect to a PCIE bridge */
+		if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) {
+			/* Busted hardware? */
+			WARN_ON_ONCE(1);
+			return NULL;
+		}
+		return pdev;
+	}
+
+	return tmp;
+}
 
 static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
 {
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 67d28ee..c5e0d89 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -22,9 +22,9 @@
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/bitops.h>
 #include <asm/irq.h>
 #include <asm/io.h>
-#include <asm/bitops.h>
 #include <asm/system.h>
 #include <asm/addrspace.h>
 
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index b019854..d182760 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -48,9 +48,9 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/fsl_devices.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
-#include <asm/bitops.h>
 #include <asm/system.h>
 #include <asm/time.h>
 #include <asm/mpc8xx.h>
diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c
index 39a90a6..bbf3ee1 100644
--- a/drivers/power/apm_power.c
+++ b/drivers/power/apm_power.c
@@ -26,52 +26,79 @@
 static void find_main_battery(void)
 {
 	struct device *dev;
-	struct power_supply *bat, *batm;
+	struct power_supply *bat = NULL;
+	struct power_supply *max_charge_bat = NULL;
+	struct power_supply *max_energy_bat = NULL;
 	union power_supply_propval full;
 	int max_charge = 0;
+	int max_energy = 0;
 
 	main_battery = NULL;
-	batm = NULL;
+
 	list_for_each_entry(dev, &power_supply_class->devices, node) {
 		bat = dev_get_drvdata(dev);
-		/* If none of battery devices cantains 'use_for_apm' flag,
-		   choice one with maximum design charge */
-		if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full)) {
-			if (full.intval > max_charge) {
-				batm = bat;
-				max_charge = full.intval;
-			}
+
+		if (bat->use_for_apm) {
+			/* nice, we explicitly asked to report this battery. */
+			main_battery = bat;
+			return;
 		}
 
-		if (bat->use_for_apm)
-			main_battery = bat;
+		if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full) ||
+				!PSY_PROP(bat, CHARGE_FULL, &full)) {
+			if (full.intval > max_charge) {
+				max_charge_bat = bat;
+				max_charge = full.intval;
+			}
+		} else if (!PSY_PROP(bat, ENERGY_FULL_DESIGN, &full) ||
+				!PSY_PROP(bat, ENERGY_FULL, &full)) {
+			if (full.intval > max_energy) {
+				max_energy_bat = bat;
+				max_energy = full.intval;
+			}
+		}
 	}
-	if (!main_battery)
-		main_battery = batm;
+
+	if ((max_energy_bat && max_charge_bat) &&
+			(max_energy_bat != max_charge_bat)) {
+		/* try guess battery with more capacity */
+		if (!PSY_PROP(max_charge_bat, VOLTAGE_MAX_DESIGN, &full)) {
+			if (max_energy > max_charge * full.intval)
+				main_battery = max_energy_bat;
+			else
+				main_battery = max_charge_bat;
+		} else if (!PSY_PROP(max_energy_bat, VOLTAGE_MAX_DESIGN,
+								  &full)) {
+			if (max_charge > max_energy / full.intval)
+				main_battery = max_charge_bat;
+			else
+				main_battery = max_energy_bat;
+		} else {
+			/* give up, choice any */
+			main_battery = max_energy_bat;
+		}
+	} else if (max_charge_bat) {
+		main_battery = max_charge_bat;
+	} else if (max_energy_bat) {
+		main_battery = max_energy_bat;
+	} else {
+		/* give up, try the last if any */
+		main_battery = bat;
+	}
 }
 
-static int calculate_time(int status)
+static int calculate_time(int status, int using_charge)
 {
-	union power_supply_propval charge_full, charge_empty;
-	union power_supply_propval charge, I;
-
-	if (MPSY_PROP(CHARGE_FULL, &charge_full)) {
-		/* if battery can't report this property, use design value */
-		if (MPSY_PROP(CHARGE_FULL_DESIGN, &charge_full))
-			return -1;
-	}
-
-	if (MPSY_PROP(CHARGE_EMPTY, &charge_empty)) {
-		/* if battery can't report this property, use design value */
-		if (MPSY_PROP(CHARGE_EMPTY_DESIGN, &charge_empty))
-			charge_empty.intval = 0;
-	}
-
-	if (MPSY_PROP(CHARGE_AVG, &charge)) {
-		/* if battery can't report average value, use momentary */
-		if (MPSY_PROP(CHARGE_NOW, &charge))
-			return -1;
-	}
+	union power_supply_propval full;
+	union power_supply_propval empty;
+	union power_supply_propval cur;
+	union power_supply_propval I;
+	enum power_supply_property full_prop;
+	enum power_supply_property full_design_prop;
+	enum power_supply_property empty_prop;
+	enum power_supply_property empty_design_prop;
+	enum power_supply_property cur_avg_prop;
+	enum power_supply_property cur_now_prop;
 
 	if (MPSY_PROP(CURRENT_AVG, &I)) {
 		/* if battery can't report average value, use momentary */
@@ -79,12 +106,44 @@
 			return -1;
 	}
 
+	if (using_charge) {
+		full_prop = POWER_SUPPLY_PROP_CHARGE_FULL;
+		full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
+		empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+		empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+		cur_avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG;
+		cur_now_prop = POWER_SUPPLY_PROP_CHARGE_NOW;
+	} else {
+		full_prop = POWER_SUPPLY_PROP_ENERGY_FULL;
+		full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
+		empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
+		empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+		cur_avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG;
+		cur_now_prop = POWER_SUPPLY_PROP_ENERGY_NOW;
+	}
+
+	if (_MPSY_PROP(full_prop, &full)) {
+		/* if battery can't report this property, use design value */
+		if (_MPSY_PROP(full_design_prop, &full))
+			return -1;
+	}
+
+	if (_MPSY_PROP(empty_prop, &empty)) {
+		/* if battery can't report this property, use design value */
+		if (_MPSY_PROP(empty_design_prop, &empty))
+			empty.intval = 0;
+	}
+
+	if (_MPSY_PROP(cur_avg_prop, &cur)) {
+		/* if battery can't report average value, use momentary */
+		if (_MPSY_PROP(cur_now_prop, &cur))
+			return -1;
+	}
+
 	if (status == POWER_SUPPLY_STATUS_CHARGING)
-		return ((charge.intval - charge_full.intval) * 60L) /
-		       I.intval;
+		return ((cur.intval - full.intval) * 60L) / I.intval;
 	else
-		return -((charge.intval - charge_empty.intval) * 60L) /
-			I.intval;
+		return -((cur.intval - empty.intval) * 60L) / I.intval;
 }
 
 static int calculate_capacity(int using_charge)
@@ -200,18 +259,22 @@
 	info->units = APM_UNITS_MINS;
 
 	if (status.intval == POWER_SUPPLY_STATUS_CHARGING) {
-		if (MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full)) {
-			if (MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full))
-				info->time = calculate_time(status.intval);
-			else
-				info->time = time_to_full.intval / 60;
+		if (!MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full) ||
+				!MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) {
+			info->time = time_to_full.intval / 60;
+		} else {
+			info->time = calculate_time(status.intval, 0);
+			if (info->time == -1)
+				info->time = calculate_time(status.intval, 1);
 		}
 	} else {
-		if (MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty)) {
-			if (MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty))
-				info->time = calculate_time(status.intval);
-			else
-				info->time = time_to_empty.intval / 60;
+		if (!MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty) ||
+			      !MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) {
+			info->time = time_to_empty.intval / 60;
+		} else {
+			info->time = calculate_time(status.intval, 0);
+			if (info->time == -1)
+				info->time = calculate_time(status.intval, 1);
 		}
 	}
 
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c
index be7021e..bdb9b72 100644
--- a/drivers/power/ds2760_battery.c
+++ b/drivers/power/ds2760_battery.c
@@ -366,7 +366,7 @@
 
 	retval = power_supply_register(&pdev->dev, &di->bat);
 	if (retval) {
-		dev_err(di->dev, "failed to register battery");
+		dev_err(di->dev, "failed to register battery\n");
 		goto batt_failed;
 	}
 
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 397f4ce..87b3493 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -729,7 +729,7 @@
 
 static const struct ps3av_monitor_quirk {
 	const char *monitor_name;
-	u32 clear_60, clear_50, clear_vesa;
+	u32 clear_60;
 } ps3av_monitor_quirks[] = {
 	{
 		.monitor_name	= "DELL 2007WFP",
@@ -757,10 +757,6 @@
 				quirk->monitor_name);
 			info->res_60.res_bits &= ~quirk->clear_60;
 			info->res_60.native &= ~quirk->clear_60;
-			info->res_50.res_bits &= ~quirk->clear_50;
-			info->res_50.native &= ~quirk->clear_50;
-			info->res_vesa.res_bits &= ~quirk->clear_vesa;
-			info->res_vesa.native &= ~quirk->clear_vesa;
 			break;
 		}
 	}
diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c
index 3a9824e..55955f1 100644
--- a/drivers/ps3/ps3stor_lib.c
+++ b/drivers/ps3/ps3stor_lib.c
@@ -66,7 +66,7 @@
 	if (n > 1)
 		dev_info(&dev->sbd.core,
 			 "%s:%u: %lu accessible regions found. Only the first "
-			 "one will be used",
+			 "one will be used\n",
 			 __func__, __LINE__, n);
 	dev->region_idx = __ffs(dev->accessible_regions);
 	dev_info(&dev->sbd.core,
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index bea25a1..9dea585 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/vuart.c
@@ -22,11 +22,11 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
+#include <linux/bitops.h>
 #include <asm/ps3.h>
 
 #include <asm/firmware.h>
 #include <asm/lv1call.h>
-#include <asm/bitops.h>
 
 #include "vuart.h"
 
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 6420a90..cbde770 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -240,7 +240,7 @@
 	depends on MENELAUS
 	help
 	  If you say yes here you get support for the RTC on the
-	  TWL92330 "Menelaus" power mangement chip, used with OMAP2
+	  TWL92330 "Menelaus" power management chip, used with OMAP2
 	  platforms.  The support is integrated with the rest of
 	  the Menelaus driver; it's not separate module.
 
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index e4bf68c..2fd49ed 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -21,11 +21,11 @@
 #include <linux/interrupt.h>
 #include <linux/string.h>
 #include <linux/pm.h>
+#include <linux/bitops.h>
 
 #include <linux/amba/bus.h>
 
 #include <asm/io.h>
-#include <asm/bitops.h>
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/rtc.h>
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 0918b78..6f1e9a9 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -29,8 +29,8 @@
 #include <linux/interrupt.h>
 #include <linux/string.h>
 #include <linux/pm.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/rtc.h>
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 6cad084..2ae0e83 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -200,9 +200,8 @@
 
 	err = device_create_file(&rtc->dev, &dev_attr_wakealarm);
 	if (err)
-		dev_err(rtc->dev.parent, "failed to create "
-				"alarm attribute, %d",
-				err);
+		dev_err(rtc->dev.parent,
+			"failed to create alarm attribute, %d\n", err);
 }
 
 void rtc_sysfs_del_device(struct rtc_device *rtc)
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 8b9d68f..5b7385e 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -40,7 +40,7 @@
  *
  *   Each bit configuration leading to an action code 2 (Exit with
  *   programming error or unusual condition indication)
- *   are handled as fatal error´s.
+ *   are handled as fatal errors.
  *
  *   All other configurations are handled as recoverable errors.
  *
@@ -2001,7 +2001,7 @@
 		switch (sense[28]) {
 		case 0x17:
 			/* issue a Diagnostic Control command with an
-			 * Inhibit Write subcommand and controler modifier */
+			 * Inhibit Write subcommand and controller modifier */
 			erp = dasd_3990_erp_DCTL(erp, 0x20);
 			break;
 
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 2edd5fb..8d1c64a 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -48,8 +48,8 @@
 	struct timer_list timer;	/* Device timer. */
 
 	unsigned char *ascebc;		/* ascii -> ebcdic table */
-	struct class_device *clttydev;	/* 3270-class tty device ptr */
-	struct class_device *cltubdev;	/* 3270-class tub device ptr */
+	struct device *clttydev;	/* 3270-class tty device ptr */
+	struct device *cltubdev;	/* 3270-class tub device ptr */
 
 	struct raw3270_request init_request;
 	unsigned char init_data[256];
@@ -1107,11 +1107,9 @@
 	/* Remove from device chain. */
 	mutex_lock(&raw3270_mutex);
 	if (rp->clttydev && !IS_ERR(rp->clttydev))
-		class_device_destroy(class3270,
-				     MKDEV(IBM_TTY3270_MAJOR, rp->minor));
+		device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
 	if (rp->cltubdev && !IS_ERR(rp->cltubdev))
-		class_device_destroy(class3270,
-				     MKDEV(IBM_FS3270_MAJOR, rp->minor));
+		device_destroy(class3270, MKDEV(IBM_FS3270_MAJOR, rp->minor));
 	list_del_init(&rp->list);
 	mutex_unlock(&raw3270_mutex);
 
@@ -1181,24 +1179,22 @@
 	if (rc)
 		goto out;
 
-	rp->clttydev = class_device_create(class3270, NULL,
-					   MKDEV(IBM_TTY3270_MAJOR, rp->minor),
-					   &rp->cdev->dev, "tty%s",
-					   rp->cdev->dev.bus_id);
+	rp->clttydev = device_create(class3270, &rp->cdev->dev,
+				     MKDEV(IBM_TTY3270_MAJOR, rp->minor),
+				     "tty%s", rp->cdev->dev.bus_id);
 	if (IS_ERR(rp->clttydev)) {
 		rc = PTR_ERR(rp->clttydev);
 		goto out_ttydev;
 	}
 
-	rp->cltubdev = class_device_create(class3270, NULL,
-					   MKDEV(IBM_FS3270_MAJOR, rp->minor),
-					   &rp->cdev->dev, "tub%s",
-					   rp->cdev->dev.bus_id);
+	rp->cltubdev = device_create(class3270, &rp->cdev->dev,
+				     MKDEV(IBM_FS3270_MAJOR, rp->minor),
+				     "tub%s", rp->cdev->dev.bus_id);
 	if (!IS_ERR(rp->cltubdev))
 		goto out;
 
 	rc = PTR_ERR(rp->cltubdev);
-	class_device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
+	device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
 
 out_ttydev:
 	sysfs_remove_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
diff --git a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c
index 29fe2a5..82a13d9 100644
--- a/drivers/s390/char/sclp_cpi.c
+++ b/drivers/s390/char/sclp_cpi.c
@@ -157,7 +157,7 @@
 	sclp_ascebc_str(evb->system_name, CPI_LENGTH_SYSTEM_NAME);
 	EBC_TOUPPER(evb->system_name, CPI_LENGTH_SYSTEM_NAME);
 
-	/* set sytem level */
+	/* set system level */
 	evb->system_level = LINUX_VERSION_CODE;
 
 	/* set sysplex name */
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
index 2e0d297..aa7f166 100644
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -69,12 +69,9 @@
 	if (rc)
 		goto fail_with_cdev;
 
-	tcd->class_device = class_device_create(
-				tape_class,
-				NULL,
-				tcd->char_device->dev,
-				device,
-				"%s", tcd->device_name
+	tcd->class_device = device_create(tape_class, device,
+					  tcd->char_device->dev,
+					  "%s", tcd->device_name
 			);
 	rc = IS_ERR(tcd->class_device) ? PTR_ERR(tcd->class_device) : 0;
 	if (rc)
@@ -90,7 +87,7 @@
 	return tcd;
 
 fail_with_class_device:
-	class_device_destroy(tape_class, tcd->char_device->dev);
+	device_destroy(tape_class, tcd->char_device->dev);
 
 fail_with_cdev:
 	cdev_del(tcd->char_device);
@@ -105,11 +102,9 @@
 void unregister_tape_dev(struct tape_class_device *tcd)
 {
 	if (tcd != NULL && !IS_ERR(tcd)) {
-		sysfs_remove_link(
-			&tcd->class_device->dev->kobj,
-			tcd->mode_name
-		);
-		class_device_destroy(tape_class, tcd->char_device->dev);
+		sysfs_remove_link(&tcd->class_device->kobj,
+				  tcd->mode_name);
+		device_destroy(tape_class, tcd->char_device->dev);
 		cdev_del(tcd->char_device);
 		kfree(tcd);
 	}
diff --git a/drivers/s390/char/tape_class.h b/drivers/s390/char/tape_class.h
index a8bd9b4..e2b5ac9 100644
--- a/drivers/s390/char/tape_class.h
+++ b/drivers/s390/char/tape_class.h
@@ -24,8 +24,8 @@
 #define TAPECLASS_NAME_LEN	32
 
 struct tape_class_device {
-	struct cdev *		char_device;
-	struct class_device *	class_device;
+	struct cdev		*char_device;
+	struct device		*class_device;
 	char			device_name[TAPECLASS_NAME_LEN];
 	char			mode_name[TAPECLASS_NAME_LEN];
 };
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 12f7a4c..e0c4c50 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -74,7 +74,7 @@
 	int dev_in_use; /* 1: already opened, 0: not opened*/
 	spinlock_t priv_lock;
 	struct device  *device;
-	struct class_device  *class_device;
+	struct device  *class_device;
 	int autorecording;
 	int autopurge;
 };
@@ -762,12 +762,10 @@
 		device_unregister(dev);
 		return ret;
 	}
-	priv->class_device = class_device_create(
-				vmlogrdr_class,
-				NULL,
-				MKDEV(vmlogrdr_major, priv->minor_num),
-				dev,
-				"%s", dev->bus_id );
+	priv->class_device = device_create(vmlogrdr_class, dev,
+					   MKDEV(vmlogrdr_major,
+						 priv->minor_num),
+					   "%s", dev->bus_id);
 	if (IS_ERR(priv->class_device)) {
 		ret = PTR_ERR(priv->class_device);
 		priv->class_device=NULL;
@@ -783,8 +781,7 @@
 
 static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv)
 {
-	class_device_destroy(vmlogrdr_class,
-			     MKDEV(vmlogrdr_major, priv->minor_num));
+	device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num));
 	if (priv->device != NULL) {
 		sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group);
 		device_unregister(priv->device);
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 42c1f46..297cdce 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -246,7 +246,7 @@
 static ssize_t chp_status_show(struct device *dev,
 			       struct device_attribute *attr, char *buf)
 {
-	struct channel_path *chp = container_of(dev, struct channel_path, dev);
+	struct channel_path *chp = to_channelpath(dev);
 
 	if (!chp)
 		return 0;
@@ -258,7 +258,7 @@
 				struct device_attribute *attr,
 				const char *buf, size_t count)
 {
-	struct channel_path *cp = container_of(dev, struct channel_path, dev);
+	struct channel_path *cp = to_channelpath(dev);
 	char cmd[10];
 	int num_args;
 	int error;
@@ -286,7 +286,7 @@
 	struct channel_path *cp;
 	int status;
 
-	cp = container_of(dev, struct channel_path, dev);
+	cp = to_channelpath(dev);
 	status = chp_info_get_status(cp->chpid);
 	if (status < 0)
 		return status;
@@ -308,7 +308,7 @@
 		return -EINVAL;
 	if (val != 0 && val != 1)
 		return -EINVAL;
-	cp = container_of(dev, struct channel_path, dev);
+	cp = to_channelpath(dev);
 	chp_cfg_schedule(cp->chpid, val);
 	cfg_wait_idle();
 
@@ -320,7 +320,7 @@
 static ssize_t chp_type_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)
 {
-	struct channel_path *chp = container_of(dev, struct channel_path, dev);
+	struct channel_path *chp = to_channelpath(dev);
 
 	if (!chp)
 		return 0;
@@ -374,7 +374,7 @@
 {
 	struct channel_path *cp;
 
-	cp = container_of(dev, struct channel_path, dev);
+	cp = to_channelpath(dev);
 	kfree(cp);
 }
 
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index b960f66..725b0dd 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -158,7 +158,7 @@
 	if (count == 0)
 		return 0;
 
-	/* value comes in units of 128 µsec */
+	/* value comes in units of 128 µsec */
 	ret = time_to_nsec(value);
 	do_div(ret, count);
 
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 5d83dd4..838f7ac 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -182,6 +182,15 @@
 	sch->dev.bus = &css_bus_type;
 	sch->dev.release = &css_subchannel_release;
 	sch->dev.groups = subch_attr_groups;
+	/*
+	 * We don't want to generate uevents for I/O subchannels that don't
+	 * have a working ccw device behind them since they will be
+	 * unregistered before they can be used anyway, so we delay the add
+	 * uevent until after device recognition was successful.
+	 */
+	if (!cio_is_console(sch->schid))
+		/* Console is special, no need to suppress. */
+		sch->dev.uevent_suppress = 1;
 	css_update_ssd_info(sch);
 	/* make it known to the system */
 	ret = css_sch_device_register(sch);
diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c
index 16ea828..ef7bc0a 100644
--- a/drivers/s390/cio/idset.c
+++ b/drivers/s390/cio/idset.c
@@ -6,7 +6,7 @@
  */
 
 #include <linux/slab.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include "idset.h"
 #include "css.h"
 
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 399695f..3561982 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -59,13 +59,13 @@
  *    1.15  Changed for 2.6 Kernel  No longer compiles on 2.4 or lower
  *    1.25  Added Packing support
  */
-#include <asm/bitops.h>
 #include <asm/ccwdev.h>
 #include <asm/ccwgroup.h>
 #include <asm/debug.h>
 #include <asm/idals.h>
 #include <asm/io.h>
 
+#include <linux/bitops.h>
 #include <linux/ctype.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index 4499372..6bf3ebb 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
  * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
- * Fixes by : Jochen Röhrig (roehrig@de.ibm.com)
+ * Fixes by : Jochen Röhrig (roehrig@de.ibm.com)
  *            Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 	      Peter Tiedemann (ptiedem@de.ibm.com)
  * Driver Model stuff by : Cornelia Huck <cornelia.huck@de.ibm.com>
@@ -19,7 +19,7 @@
  *  Dieter Wellerdiek (wel@de.ibm.com)
  *  Martin Schwidefsky (schwidefsky@de.ibm.com)
  *  Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
- *  Jochen Röhrig (roehrig@de.ibm.com)
+ *  Jochen Röhrig (roehrig@de.ibm.com)
  *
  * 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
@@ -885,7 +885,7 @@
 	}
 
 	/**
-	 * Don´t setup a timer for receiving the initial RX frame
+	 * Don't setup a timer for receiving the initial RX frame
 	 * if in compatibility mode, since VM TCP delays the initial
 	 * frame until it has some data to send.
 	 */
@@ -905,10 +905,10 @@
 		ccw_check_return_code(ch, rc, "init IO");
 	}
 	/**
-	 * If in compatibility mode since we don´t setup a timer, we
+	 * If in compatibility mode since we don't setup a timer, we
 	 * also signal RX channel up immediately. This enables us
 	 * to send packets early which in turn usually triggers some
-	 * reply from VM TCP which brings up the RX channel to it´s
+	 * reply from VM TCP which brings up the RX channel to it's
 	 * final state.
 	 */
 	if ((CHANNEL_DIRECTION(ch->flags) == READ) &&
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index a2d08c9..ff999ff 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -6643,7 +6643,8 @@
 	dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
 	dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid;
 #endif
-	dev->header_ops = &qeth_null_ops;
+	if (qeth_get_netdev_flags(card) & IFF_NOARP)
+		dev->header_ops = &qeth_null_ops;
 
 #ifdef CONFIG_QETH_IPV6
 	/*IPv6 address autoconfiguration stuff*/
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 7507067..fd5d0c1 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -559,6 +559,7 @@
 		retval = -ENOMEM;
 		goto out;
 	}
+	sg_init_table(sg_list->sg, sg_list->count);
 
 	for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) {
 		sg->length = min(size, PAGE_SIZE);
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 57cac70..326e7ee 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -63,7 +63,7 @@
 static inline void *
 zfcp_sg_to_address(struct scatterlist *list)
 {
-	return (void *) (page_address(list->page) + list->offset);
+	return sg_virt(list);
 }
 
 /**
@@ -74,7 +74,7 @@
 static inline void
 zfcp_address_to_sg(void *address, struct scatterlist *list)
 {
-	list->page = virt_to_page(address);
+	sg_set_page(list, virt_to_page(address));
 	list->offset = ((unsigned long) address) & (PAGE_SIZE - 1);
 }
 
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index a6475a2b..9438d0b 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -308,13 +308,15 @@
 	if (send_els == NULL)
 		goto nomem;
 
-	send_els->req = kzalloc(sizeof(struct scatterlist), GFP_ATOMIC);
+	send_els->req = kmalloc(sizeof(struct scatterlist), GFP_ATOMIC);
 	if (send_els->req == NULL)
 		goto nomem;
+	sg_init_table(send_els->req, 1);
 
-	send_els->resp = kzalloc(sizeof(struct scatterlist), GFP_ATOMIC);
+	send_els->resp = kmalloc(sizeof(struct scatterlist), GFP_ATOMIC);
 	if (send_els->resp == NULL)
 		goto nomem;
+	sg_init_table(send_els->resp, 1);
 
 	address = (void *) get_zeroed_page(GFP_ATOMIC);
 	if (address == NULL)
@@ -363,7 +365,7 @@
 	retval = -ENOMEM;
  freemem:
 	if (address != NULL)
-		__free_pages(send_els->req->page, 0);
+		__free_pages(sg_page(send_els->req), 0);
 	if (send_els != NULL) {
 		kfree(send_els->req);
 		kfree(send_els->resp);
@@ -437,7 +439,7 @@
 
  out:
 	zfcp_port_put(port);
-	__free_pages(send_els->req->page, 0);
+	__free_pages(sg_page(send_els->req), 0);
 	kfree(send_els->req);
 	kfree(send_els->resp);
 	kfree(send_els);
diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h
index 63941a2..f1aa138 100644
--- a/drivers/sbus/char/vfc.h
+++ b/drivers/sbus/char/vfc.h
@@ -126,7 +126,7 @@
 	volatile struct vfc_regs __iomem *regs;
 	struct vfc_regs *phys_regs;
 	unsigned int control_reg;
-	struct semaphore device_lock_sem;
+	struct mutex device_lock_mtx;
 	int instance;
 	int busy;
 	unsigned long which_io;
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index 9269f7f..d4f8fcd 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -22,6 +22,7 @@
 #include <linux/fs.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include <linux/mm.h>
 
 #include <asm/openprom.h>
@@ -54,12 +55,12 @@
 
 void vfc_lock_device(struct vfc_dev *dev)
 {
-	down(&dev->device_lock_sem);
+	mutex_lock(&dev->device_lock_mtx);
 }
 
 void vfc_unlock_device(struct vfc_dev *dev)
 {
-	up(&dev->device_lock_sem);
+	mutex_unlock(&dev->device_lock_mtx);
 }
 
 
@@ -133,7 +134,7 @@
 int init_vfc_devstruct(struct vfc_dev *dev, int instance) 
 {
 	dev->instance=instance;
-	init_MUTEX(&dev->device_lock_sem);
+	mutex_init(&dev->device_lock_mtx);
 	dev->control_reg=0;
 	dev->busy=0;
 	return 0;
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index fb14014..afb262b 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1840,7 +1840,7 @@
 			    (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
 				if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) {
 					struct scatterlist *sg = scsi_sglist(srb);
-					char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+					char *buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 					memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
 					kunmap_atomic(buf - sg->offset, KM_IRQ0);
 				}
@@ -1919,7 +1919,7 @@
 			char *buf;
 			unsigned long flags = 0;
 			local_irq_save(flags);
-			buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 			memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
 			kunmap_atomic(buf - sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index a64153b..59716eb 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1469,7 +1469,7 @@
 	struct scatterlist *sg = scsi_sglist(cmd);
 
 	local_irq_save(flags);
-	buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	transfer_len = min(sg->length, len);
 
 	memcpy(buf, data, transfer_len);
diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c
index a7f916c..1c90781 100644
--- a/drivers/scsi/FlashPoint.c
+++ b/drivers/scsi/FlashPoint.c
@@ -25,9 +25,6 @@
 
 #define FAILURE         0xFFFFFFFFL
 
-#define BIT(x)          ((unsigned char)(1<<(x)))	/* single-bit mask in bit position x */
-#define BITW(x)          ((unsigned short)(1<<(x)))	/* single-bit mask in bit position x */
-
 struct sccb;
 typedef void (*CALL_BK_FN) (struct sccb *);
 
@@ -374,9 +371,9 @@
 #define  SCAM_ENABLED   BIT(2)
 #define  SCAM_LEVEL2    BIT(3)
 
-#define	RENEGO_ENA		BITW(10)
-#define	CONNIO_ENA		BITW(11)
-#define  GREEN_PC_ENA   BITW(12)
+#define	RENEGO_ENA		BIT(10)
+#define	CONNIO_ENA		BIT(11)
+#define  GREEN_PC_ENA   BIT(12)
 
 #define  AUTO_RATE_00   00
 #define  AUTO_RATE_05   01
@@ -511,23 +508,23 @@
 
 #define  hp_intena		 0x40
 
-#define  RESET		 BITW(7)
-#define  PROG_HLT		 BITW(6)
-#define  PARITY		 BITW(5)
-#define  FIFO		 BITW(4)
-#define  SEL		 BITW(3)
-#define  SCAM_SEL		 BITW(2)
-#define  RSEL		 BITW(1)
-#define  TIMEOUT		 BITW(0)
-#define  BUS_FREE		 BITW(15)
-#define  XFER_CNT_0	 BITW(14)
-#define  PHASE		 BITW(13)
-#define  IUNKWN		 BITW(12)
-#define  ICMD_COMP	 BITW(11)
-#define  ITICKLE		 BITW(10)
-#define  IDO_STRT		 BITW(9)
-#define  ITAR_DISC	 BITW(8)
-#define  AUTO_INT		 (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
+#define  RESET		 BIT(7)
+#define  PROG_HLT		 BIT(6)
+#define  PARITY		 BIT(5)
+#define  FIFO		 BIT(4)
+#define  SEL		 BIT(3)
+#define  SCAM_SEL		 BIT(2)
+#define  RSEL		 BIT(1)
+#define  TIMEOUT		 BIT(0)
+#define  BUS_FREE		 BIT(15)
+#define  XFER_CNT_0	 BIT(14)
+#define  PHASE		 BIT(13)
+#define  IUNKWN		 BIT(12)
+#define  ICMD_COMP	 BIT(11)
+#define  ITICKLE		 BIT(10)
+#define  IDO_STRT		 BIT(9)
+#define  ITAR_DISC	 BIT(8)
+#define  AUTO_INT		 (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
 #define  CLR_ALL_INT	 0xFFFF
 #define  CLR_ALL_INT_1	 0xFF00
 
@@ -674,37 +671,37 @@
 #define  BIOS_DATA_OFFSET     0x60
 #define  BIOS_RELATIVE_CARD   0x64
 
-#define  AR3      (BITW(9) + BITW(8))
-#define  SDATA    BITW(10)
+#define  AR3      (BIT(9) + BIT(8))
+#define  SDATA    BIT(10)
 
-#define  CRD_OP   BITW(11)	/* Cmp Reg. w/ Data */
+#define  CRD_OP   BIT(11)	/* Cmp Reg. w/ Data */
 
-#define  CRR_OP   BITW(12)	/* Cmp Reg. w. Reg. */
+#define  CRR_OP   BIT(12)	/* Cmp Reg. w. Reg. */
 
-#define  CPE_OP   (BITW(14)+BITW(11))	/* Cmp SCSI phs & Branch EQ */
+#define  CPE_OP   (BIT(14)+BIT(11))	/* Cmp SCSI phs & Branch EQ */
 
-#define  CPN_OP   (BITW(14)+BITW(12))	/* Cmp SCSI phs & Branch NOT EQ */
+#define  CPN_OP   (BIT(14)+BIT(12))	/* Cmp SCSI phs & Branch NOT EQ */
 
 #define  ADATA_OUT   0x00
-#define  ADATA_IN    BITW(8)
-#define  ACOMMAND    BITW(10)
-#define  ASTATUS     (BITW(10)+BITW(8))
-#define  AMSG_OUT    (BITW(10)+BITW(9))
-#define  AMSG_IN     (BITW(10)+BITW(9)+BITW(8))
+#define  ADATA_IN    BIT(8)
+#define  ACOMMAND    BIT(10)
+#define  ASTATUS     (BIT(10)+BIT(8))
+#define  AMSG_OUT    (BIT(10)+BIT(9))
+#define  AMSG_IN     (BIT(10)+BIT(9)+BIT(8))
 
-#define  BRH_OP   BITW(13)	/* Branch */
+#define  BRH_OP   BIT(13)	/* Branch */
 
 #define  ALWAYS   0x00
-#define  EQUAL    BITW(8)
-#define  NOT_EQ   BITW(9)
+#define  EQUAL    BIT(8)
+#define  NOT_EQ   BIT(9)
 
-#define  TCB_OP   (BITW(13)+BITW(11))	/* Test condition & branch */
+#define  TCB_OP   (BIT(13)+BIT(11))	/* Test condition & branch */
 
-#define  FIFO_0      BITW(10)
+#define  FIFO_0      BIT(10)
 
-#define  MPM_OP   BITW(15)	/* Match phase and move data */
+#define  MPM_OP   BIT(15)	/* Match phase and move data */
 
-#define  MRR_OP   BITW(14)	/* Move DReg. to Reg. */
+#define  MRR_OP   BIT(14)	/* Move DReg. to Reg. */
 
 #define  S_IDREG  (BIT(2)+BIT(1)+BIT(0))
 
@@ -712,9 +709,9 @@
 #define  D_AR1    BIT(0)
 #define  D_BUCKET (BIT(2) + BIT(1) + BIT(0))
 
-#define  RAT_OP      (BITW(14)+BITW(13)+BITW(11))
+#define  RAT_OP      (BIT(14)+BIT(13)+BIT(11))
 
-#define  SSI_OP      (BITW(15)+BITW(11))
+#define  SSI_OP      (BIT(15)+BIT(11))
 
 #define  SSI_ITAR_DISC	(ITAR_DISC >> 8)
 #define  SSI_IDO_STRT	(IDO_STRT >> 8)
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 30905ce..a5763c6 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -521,7 +521,7 @@
 
 config SCSI_ADVANSYS
 	tristate "AdvanSys SCSI support"
-	depends on SCSI
+	depends on SCSI && VIRT_TO_BUS
 	depends on ISA || EISA || PCI
 	help
 	  This is a driver for all SCSI host adapters manufactured by
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 988f0bc..2597209 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -298,8 +298,7 @@
 	if (cmd->use_sg) {
 		cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 		cmd->SCp.buffers_residual = cmd->use_sg - 1;
-		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
-			       cmd->SCp.buffer->offset;
+		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	} else {
 		cmd->SCp.buffer = NULL;
@@ -2143,8 +2142,7 @@
 					++cmd->SCp.buffer;
 					--cmd->SCp.buffers_residual;
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
-					cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
-						       cmd->SCp.buffer->offset;
+					cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 					dprintk(NDEBUG_INFORMATION, ("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
 				}
 				/*
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
index 96e8e29..5b0efc9 100644
--- a/drivers/scsi/NCR53C9x.c
+++ b/drivers/scsi/NCR53C9x.c
@@ -927,7 +927,7 @@
 			esp->dma_mmu_get_scsi_sgl(esp, sp);
 		else
 			sp->SCp.ptr =
-				(char *) virt_to_phys((page_address(sp->SCp.buffer->page) + sp->SCp.buffer->offset));
+				(char *) virt_to_phys(sg_virt(sp->SCp.buffer));
 	}
 }
 
@@ -1748,7 +1748,7 @@
 	if (esp->dma_advance_sg)
 		esp->dma_advance_sg (sp);
 	else
-		sp->SCp.ptr = (char *) virt_to_phys((page_address(sp->SCp.buffer->page) + sp->SCp.buffer->offset));
+		sp->SCp.ptr = (char *) virt_to_phys(sg_virt(sp->SCp.buffer));
 
 }
 
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index 3168a17..137d065 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -875,8 +875,7 @@
 			outb(TRANSFER_INFO | DMA_OP, CMD_REG);
 #if USE_PIO
                         scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
-                                NCR53c406a_pio_write(page_address(sg->page) + sg->offset,
-                                                     sg->length);
+                                NCR53c406a_pio_write(sg_virt(sg), sg->length);
                         }
 			REG0;
 #endif				/* USE_PIO */
@@ -897,8 +896,7 @@
 			outb(TRANSFER_INFO | DMA_OP, CMD_REG);
 #if USE_PIO
                         scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
-                                NCR53c406a_pio_read(page_address(sg->page) + sg->offset,
-                                                    sg->length);
+                                NCR53c406a_pio_read(sg_virt(sg), sg->length);
                         }
 			REG0;
 #endif				/* USE_PIO */
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 80e448d..a77ab8d 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -356,7 +356,7 @@
 	int transfer_len;
 	struct scatterlist *sg = scsi_sglist(scsicmd);
 
-	buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	transfer_len = min(sg->length, len + offset);
 
 	transfer_len -= offset;
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 03b5102..9abba8b 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1526,7 +1526,7 @@
 	__le32			capacityhigh;
 };
 
-#define FSCS_NOTCLEAN	0x0001  /* fsck is neccessary before mounting */
+#define FSCS_NOTCLEAN	0x0001  /* fsck is necessary before mounting */
 #define FSCS_READONLY	0x0002	/* possible result of broken mirror */
 #define FSCS_HIDDEN	0x0004	/* should be ignored - set during a clear */
 
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index f08e71e..ea8c699 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -1,6 +1,6 @@
 /* aha152x.c -- Adaptec AHA-152x driver
- * Author: Jürgen E. Fischer, fischer@norbit.de
- * Copyright 1993-2004 Jürgen E. Fischer
+ * Author: Jürgen E. Fischer, fischer@norbit.de
+ * Copyright 1993-2004 Jürgen E. Fischer
  *
  * 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
@@ -357,7 +357,7 @@
 	check_condition = 0x0800,	/* requesting sense after CHECK CONDITION */
 };
 
-MODULE_AUTHOR("Jürgen Fischer");
+MODULE_AUTHOR("Jürgen Fischer");
 MODULE_DESCRIPTION(AHA152X_REVID);
 MODULE_LICENSE("GPL");
 
@@ -613,7 +613,7 @@
 #define SCNEXT(SCpnt)		SCDATA(SCpnt)->next
 #define SCSEM(SCpnt)		SCDATA(SCpnt)->done
 
-#define SG_ADDRESS(buffer)	((char *) (page_address((buffer)->page)+(buffer)->offset))
+#define SG_ADDRESS(buffer)	((char *) sg_virt((buffer)))
 
 /* state handling */
 static void seldi_run(struct Scsi_Host *shpnt);
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 961a188..bbcc2c5 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -49,7 +49,7 @@
 #include "aha1542.h"
 
 #define SCSI_BUF_PA(address)	isa_virt_to_bus(address)
-#define SCSI_SG_PA(sgent)	(isa_page_to_bus((sgent)->page) + (sgent)->offset)
+#define SCSI_SG_PA(sgent)	(isa_page_to_bus(sg_page((sgent))) + (sgent)->offset)
 
 static void BAD_DMA(void *address, unsigned int length)
 {
@@ -66,8 +66,7 @@
 		       int badseg)
 {
 	printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%llx length %u\n",
-	       badseg, nseg,
-	       page_address(sgp->page) + sgp->offset,
+	       badseg, nseg, sg_virt(sgp),
 	       (unsigned long long)SCSI_SG_PA(sgp),
 	       sgp->length);
 
@@ -712,8 +711,7 @@
 				printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
 				scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
 					printk(KERN_CRIT "%d: %p %d\n", i,
-					       (page_address(sg->page) +
-						sg->offset), sg->length);
+					       sg_virt(sg), sg->length);
 				};
 				printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr);
 				ptr = (unsigned char *) &cptr[i];
diff --git a/drivers/scsi/aic7xxx/cam.h b/drivers/scsi/aic7xxx/cam.h
index 26f17e3..687aef6 100644
--- a/drivers/scsi/aic7xxx/cam.h
+++ b/drivers/scsi/aic7xxx/cam.h
@@ -48,7 +48,7 @@
 	CAM_REQ_ABORTED,	/* CCB request aborted by the host */
 	CAM_UA_ABORT,		/* Unable to abort CCB request */
 	CAM_REQ_CMP_ERR,	/* CCB request completed with an error */
-	CAM_BUSY,		/* CAM subsytem is busy */
+	CAM_BUSY,		/* CAM subsystem is busy */
 	CAM_REQ_INVALID,	/* CCB request was invalid */
 	CAM_PATH_INVALID,	/* Supplied Path ID is invalid */
 	CAM_SEL_TIMEOUT,	/* Target Selection Timeout */
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index f817775..f7a2528 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1343,7 +1343,7 @@
 						/* 4 bytes: Areca io control code */
 
 	sg = scsi_sglist(cmd);
-	buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+	buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 	if (scsi_sg_count(cmd) > 1) {
 		retvalue = ARCMSR_MESSAGE_FAIL;
 		goto message_out;
@@ -1593,7 +1593,7 @@
 		strncpy(&inqdata[32], "R001", 4); /* Product Revision */
 
 		sg = scsi_sglist(cmd);
-		buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 		memcpy(buffer, inqdata, sizeof(inqdata));
 		sg = scsi_sglist(cmd);
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index 52d0b87..d178098 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -515,8 +515,7 @@
 	if (cmd->use_sg) {
 		cmd->SCp.buffer = (struct scatterlist *)cmd->request_buffer;
 		cmd->SCp.buffers_residual = cmd->use_sg - 1;
-		cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page) +
-			       cmd->SCp.buffer->offset;
+		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 		/* ++roman: Try to merge some scatter-buffers if they are at
 		 * contiguous physical addresses.
@@ -2054,8 +2053,7 @@
 					++cmd->SCp.buffer;
 					--cmd->SCp.buffers_residual;
 					cmd->SCp.this_residual = cmd->SCp.buffer->length;
-					cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
-						   cmd->SCp.buffer->offset;
+					cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 					/* ++roman: Try to merge some scatter-buffers if
 					 * they are at contiguous physical addresses.
 					 */
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index fd42d47..a9def6e 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -1808,12 +1808,12 @@
 	irqreturn_t handled = IRQ_NONE;
 
 	/*
-	 * Check for pending interupt
+	 * Check for pending interrupt
 	 */
 	scsi_status = DC395x_read16(acb, TRM_S1040_SCSI_STATUS);
 	dma_status = DC395x_read8(acb, TRM_S1040_DMA_STATUS);
 	if (scsi_status & SCSIINTERRUPT) {
-		/* interupt pending - let's process it! */
+		/* interrupt pending - let's process it! */
 		dc395x_handle_interrupt(acb, scsi_status);
 		handled = IRQ_HANDLED;
 	}
@@ -4579,7 +4579,7 @@
 	if (acb->config & HCC_SCSI_RESET)
 		reset_scsi_bus(acb);
 
-	/* clear any pending interupt state */
+	/* clear any pending interrupt state */
 	DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS);
 }
 
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
index 96180bb..982c509 100644
--- a/drivers/scsi/eata_pio.c
+++ b/drivers/scsi/eata_pio.c
@@ -172,7 +172,7 @@
 			SCp->Status = 0;
 		else {
 			SCp->buffer++;
-			SCp->ptr = page_address(SCp->buffer->page) + SCp->buffer->offset;
+			SCp->ptr = sg_virt(SCp->buffer);
 			SCp->this_residual = SCp->buffer->length;
 		}
 	}
@@ -410,7 +410,7 @@
 	} else {
 		cmd->SCp.buffer = cmd->request_buffer;
 		cmd->SCp.buffers_residual = cmd->use_sg;
-		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
+		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	}
 	cmd->SCp.Status = (cmd->SCp.this_residual != 0);	/* TRUE as long as bytes 
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
index 668569e..8335b60 100644
--- a/drivers/scsi/fd_mcs.c
+++ b/drivers/scsi/fd_mcs.c
@@ -973,7 +973,7 @@
 				if (current_SC->SCp.buffers_residual) {
 					--current_SC->SCp.buffers_residual;
 					++current_SC->SCp.buffer;
-					current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+					current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
 					current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 				} else
 					break;
@@ -1006,7 +1006,7 @@
 			if (!current_SC->SCp.this_residual && current_SC->SCp.buffers_residual) {
 				--current_SC->SCp.buffers_residual;
 				++current_SC->SCp.buffer;
-				current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+				current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
 				current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 			}
 		}
@@ -1109,7 +1109,7 @@
 
 	if (current_SC->use_sg) {
 		current_SC->SCp.buffer = (struct scatterlist *) current_SC->request_buffer;
-		current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+		current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
 		current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 		current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
 	} else {
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index 5d282e6..2cd6b49 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -1321,7 +1321,7 @@
 	    if (current_SC->SCp.buffers_residual) {
 	       --current_SC->SCp.buffers_residual;
 	       ++current_SC->SCp.buffer;
-	       current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+	       current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
 	       current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 	    } else
 		  break;
@@ -1354,7 +1354,7 @@
 	     && current_SC->SCp.buffers_residual) {
 	    --current_SC->SCp.buffers_residual;
 	    ++current_SC->SCp.buffer;
-	    current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+	    current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
 	    current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
 	 }
       }
@@ -1439,8 +1439,7 @@
 
    if (scsi_sg_count(current_SC)) {
 	   current_SC->SCp.buffer = scsi_sglist(current_SC);
-	   current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page)
-		   + current_SC->SCp.buffer->offset;
+	   current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
 	   current_SC->SCp.this_residual    = current_SC->SCp.buffer->length;
 	   current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
    } else {
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 56de5a6..b253b8c 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -2374,18 +2374,18 @@
             if (cpsum+cpnow > cpcount) 
                 cpnow = cpcount - cpsum;
             cpsum += cpnow;
-            if (!sl->page) {
+            if (!sg_page(sl)) {
                 printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n",
                        ha->hanum);
                 return;
             }
             local_irq_save(flags);
-            address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
+            address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
             if (to_buffer)
                 memcpy(buffer, address, cpnow);
             else
                 memcpy(address, buffer, cpnow);
-            flush_dcache_page(sl->page);
+            flush_dcache_page(sg_page(sl));
             kunmap_atomic(address, KM_BIO_SRC_IRQ);
             local_irq_restore(flags);
             if (cpsum == cpcount)
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 714e627..db004a4 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -1828,7 +1828,7 @@
 		BUG_ON(scsi_sg_count(cmd) > 16);
 
 		scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) {
-			ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg->page) + sg->offset);
+			ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg_page(sg)) + sg->offset);
 			ld(shpnt)[ldn].sge[i].byte_length = sg->length;
 		}
 		scb->enable |= IM_POINTER_TO_LIST;
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index fa7ba64..8d0244c 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -47,9 +47,9 @@
 #include <linux/scatterlist.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 
 #include <scsi/scsi.h>
@@ -175,18 +175,18 @@
 
 	while (bcount) {
 		count = min(pc->sg->length - pc->b_count, bcount);
-		if (PageHighMem(pc->sg->page)) {
+		if (PageHighMem(sg_page(pc->sg))) {
 			unsigned long flags;
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
 					pc->sg->offset;
 			drive->hwif->atapi_input_bytes(drive,
 						buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
-			buf = page_address(pc->sg->page) + pc->sg->offset;
+			buf = sg_virt(pc->sg);
 			drive->hwif->atapi_input_bytes(drive,
 						buf + pc->b_count, count);
 		}
@@ -212,18 +212,18 @@
 
 	while (bcount) {
 		count = min(pc->sg->length - pc->b_count, bcount);
-		if (PageHighMem(pc->sg->page)) {
+		if (PageHighMem(sg_page(pc->sg))) {
 			unsigned long flags;
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+			buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
 						pc->sg->offset;
 			drive->hwif->atapi_output_bytes(drive,
 						buf + pc->b_count, count);
 			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
 			local_irq_restore(flags);
 		} else {
-			buf = page_address(pc->sg->page) + pc->sg->offset;
+			buf = sg_virt(pc->sg);
 			drive->hwif->atapi_output_bytes(drive,
 						buf + pc->b_count, count);
 		}
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 74cdc1f..a3d0c6b 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -705,9 +705,7 @@
 				cmd->SCp.buffer++;
 				cmd->SCp.this_residual =
 				    cmd->SCp.buffer->length;
-				cmd->SCp.ptr =
-				    page_address(cmd->SCp.buffer->page) +
-				    cmd->SCp.buffer->offset;
+				cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 
 				/*
 				 * Make sure that we transfer even number of bytes
@@ -844,9 +842,7 @@
 			cmd->SCp.buffer =
 			    (struct scatterlist *) cmd->request_buffer;
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
-			cmd->SCp.ptr =
-			    page_address(cmd->SCp.buffer->page) +
-			    cmd->SCp.buffer->offset;
+			cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		} else {
 			/* else fill the only available buffer */
 			cmd->SCp.buffer = NULL;
diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
index ab7cbf3..c8b452f 100644
--- a/drivers/scsi/in2000.c
+++ b/drivers/scsi/in2000.c
@@ -372,7 +372,7 @@
 	if (cmd->use_sg) {
 		cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 		cmd->SCp.buffers_residual = cmd->use_sg - 1;
-		cmd->SCp.ptr = (char *) page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
+		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	} else {
 		cmd->SCp.buffer = NULL;
@@ -764,7 +764,7 @@
 		++cmd->SCp.buffer;
 		--cmd->SCp.buffers_residual;
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
-		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
+		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 	}
 
 /* Set up hardware registers */
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b41dfb5..439b97a 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2872,6 +2872,7 @@
 	}
 
 	scatterlist = sglist->scatterlist;
+	sg_init_table(scatterlist, num_elem);
 
 	sglist->order = order;
 	sglist->num_sg = num_elem;
@@ -2884,12 +2885,12 @@
 
 			/* Free up what we already allocated */
 			for (j = i - 1; j >= 0; j--)
-				__free_pages(scatterlist[j].page, order);
+				__free_pages(sg_page(&scatterlist[j]), order);
 			kfree(sglist);
 			return NULL;
 		}
 
-		scatterlist[i].page = page;
+		sg_set_page(&scatterlist[i], page);
 	}
 
 	return sglist;
@@ -2910,7 +2911,7 @@
 	int i;
 
 	for (i = 0; i < sglist->num_sg; i++)
-		__free_pages(sglist->scatterlist[i].page, sglist->order);
+		__free_pages(sg_page(&sglist->scatterlist[i]), sglist->order);
 
 	kfree(sglist);
 }
@@ -2940,9 +2941,11 @@
 	scatterlist = sglist->scatterlist;
 
 	for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
-		kaddr = kmap(scatterlist[i].page);
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
 		memcpy(kaddr, buffer, bsize_elem);
-		kunmap(scatterlist[i].page);
+		kunmap(page);
 
 		scatterlist[i].length = bsize_elem;
 
@@ -2953,9 +2956,11 @@
 	}
 
 	if (len % bsize_elem) {
-		kaddr = kmap(scatterlist[i].page);
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
 		memcpy(kaddr, buffer, len % bsize_elem);
-		kunmap(scatterlist[i].page);
+		kunmap(page);
 
 		scatterlist[i].length = len % bsize_elem;
 	}
@@ -5134,6 +5139,7 @@
 	u32 ioadl_flags = 0;
 	struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
 	struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+	struct ipr_ioadl_desc *last_ioadl = NULL;
 	int len = qc->nbytes + qc->pad_len;
 	struct scatterlist *sg;
 
@@ -5156,11 +5162,13 @@
 	ata_for_each_sg(sg, qc) {
 		ioadl->flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(sg));
 		ioadl->address = cpu_to_be32(sg_dma_address(sg));
-		if (ata_sg_is_last(sg, qc))
-			ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
-		else
-			ioadl++;
+
+		last_ioadl = ioadl;
+		ioadl++;
 	}
+
+	if (likely(last_ioadl))
+		last_ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
 }
 
 /**
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index edaac27..5c5a9b2 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -1515,7 +1515,7 @@
                 /* kmap_atomic() ensures addressability of the user buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+                buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
                 if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
                     buffer[2] == 'P' && buffer[3] == 'P') {
                         kunmap_atomic(buffer - sg->offset, KM_IRQ0);
@@ -3523,7 +3523,7 @@
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(buffer, &cdata[xfer_cnt], min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
@@ -3556,7 +3556,7 @@
                 /* kmap_atomic() ensures addressability of the data buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
                 memcpy(&cdata[xfer_cnt], buffer, min_cnt);
                 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
                 local_irq_restore(flags);
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index a21455d..6ce4109 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -70,9 +70,7 @@
 static inline void
 iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
 {
-	ibuf->sg.page = virt_to_page(vbuf);
-	ibuf->sg.offset = offset_in_page(vbuf);
-	ibuf->sg.length = size;
+	sg_init_one(&ibuf->sg, vbuf, size);
 	ibuf->sent = 0;
 	ibuf->use_sendmsg = 1;
 }
@@ -80,13 +78,14 @@
 static inline void
 iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
 {
-	ibuf->sg.page = sg->page;
+	sg_init_table(&ibuf->sg, 1);
+	sg_set_page(&ibuf->sg, sg_page(sg));
 	ibuf->sg.offset = sg->offset;
 	ibuf->sg.length = sg->length;
 	/*
 	 * Fastpath: sg element fits into single page
 	 */
-	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
+	if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg_page(sg)))
 		ibuf->use_sendmsg = 0;
 	else
 		ibuf->use_sendmsg = 1;
@@ -716,7 +715,7 @@
 	for (i = tcp_ctask->sg_count; i < scsi_sg_count(sc); i++) {
 		char *dest;
 
-		dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
+		dest = kmap_atomic(sg_page(&sg[i]), KM_SOFTIRQ0);
 		rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset,
 				      sg[i].length, offset);
 		kunmap_atomic(dest, KM_SOFTIRQ0);
@@ -1103,9 +1102,9 @@
 	 * slab case.
 	 */
 	if (buf->use_sendmsg)
-		res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
+		res = sock_no_sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 	else
-		res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags);
+		res = tcp_conn->sendpage(sk, sg_page(&buf->sg), offset, size, flags);
 
 	if (res >= 0) {
 		conn->txdata_octets += res;
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index 7ef0afc..5f3a0d7 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -285,7 +285,7 @@
 	dev = port->port_dev;
 
 	SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id,
-		    current->pid);
+		    task_pid_nr(current));
 
 	switch (dev->dev_type) {
 	case SAS_END_DEV:
@@ -320,7 +320,7 @@
 	}
 
 	SAS_DPRINTK("DONE DISCOVERY on port %d, pid:%d, result:%d\n", port->id,
-		    current->pid, error);
+		    task_pid_nr(current), error);
 }
 
 static void sas_revalidate_domain(struct work_struct *work)
@@ -334,12 +334,12 @@
 			&port->disc.pending);
 
 	SAS_DPRINTK("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id,
-		    current->pid);
+		    task_pid_nr(current));
 	if (port->port_dev)
 		res = sas_ex_revalidate_domain(port->port_dev);
 
 	SAS_DPRINTK("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n",
-		    port->id, current->pid, res);
+		    port->id, task_pid_nr(current), res);
 }
 
 /* ---------- Events ---------- */
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index e5337ad..ce348c5 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1243,7 +1243,8 @@
 				memset(adaptermsg, 0, LPFC_MAX_ADPTMSG);
 				memcpy(&adaptermsg[0], (uint8_t *) irsp,
 				       MAX_MSG_DATA);
-				dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s",
+				dev_warn(&((phba->pcidev)->dev),
+					 "lpfc%d: %s\n",
 					 phba->brd_no, adaptermsg);
 			} else {
 				/* Unknown IOCB command */
@@ -1430,7 +1431,8 @@
 				memset(adaptermsg, 0, LPFC_MAX_ADPTMSG);
 				memcpy(&adaptermsg[0], (uint8_t *) irsp,
 				       MAX_MSG_DATA);
-				dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s",
+				dev_warn(&((phba->pcidev)->dev),
+					 "lpfc%d: %s\n",
 					 phba->brd_no, adaptermsg);
 			} else {
 				/* Unknown IOCB command */
@@ -1681,7 +1683,7 @@
 					memcpy(&adaptermsg[0], (uint8_t *) irsp,
 					       MAX_MSG_DATA);
 					dev_warn(&((phba->pcidev)->dev),
-						 "lpfc%d: %s",
+						 "lpfc%d: %s\n",
 						 phba->brd_no, adaptermsg);
 				} else {
 					/* Unknown IOCB command */
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 10d1aff..66c6520 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -658,7 +658,7 @@
 			struct scatterlist *sg;
 
 			sg = scsi_sglist(cmd);
-			buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
 
 			memset(buf, 0, cmd->cmnd[4]);
 			kunmap_atomic(buf - sg->offset, KM_IRQ0);
@@ -1542,10 +1542,8 @@
 		if( cmd->cmnd[0] == INQUIRY && !islogical ) {
 
 			sgl = scsi_sglist(cmd);
-			if( sgl->page ) {
-				c = *(unsigned char *)
-					page_address((&sgl[0])->page) +
-					(&sgl[0])->offset; 
+			if( sg_page(sgl) ) {
+				c = *(unsigned char *) sg_virt(&sgl[0]);
 			} else {
 				printk(KERN_WARNING
 				       "megaraid: invalid sg.\n");
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index e4e4c6a..c892310 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -427,7 +427,7 @@
  * @id		: pci device id of the class of controllers
  *
  * This routine should be called whenever a new adapter is detected by the
- * PCI hotplug susbsytem.
+ * PCI hotplug susbsystem.
  */
 static int __devinit
 megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -1584,10 +1584,8 @@
 			caddr_t			vaddr;
 
 			sgl = scsi_sglist(scp);
-			if (sgl->page) {
-				vaddr = (caddr_t)
-					(page_address((&sgl[0])->page)
-					 + (&sgl[0])->offset);
+			if (sg_page(sgl)) {
+				vaddr = (caddr_t) sg_virt(&sgl[0]);
 
 				memset(vaddr, 0, scp->cmnd[4]);
 			}
@@ -2328,10 +2326,8 @@
 				&& IS_RAID_CH(raid_dev, scb->dev_channel)) {
 
 			sgl = scsi_sglist(scp);
-			if (sgl->page) {
-				c = *(unsigned char *)
-					(page_address((&sgl[0])->page) +
-					 (&sgl[0])->offset);
+			if (sg_page(sgl)) {
+				c = *(unsigned char *) sg_virt(&sgl[0]);
 			} else {
 				con_log(CL_ANN, (KERN_WARNING
 						 "megaraid mailbox: invalid sg:%d\n",
diff --git a/drivers/scsi/nsp32.h b/drivers/scsi/nsp32.h
index a976e81..6715ecb 100644
--- a/drivers/scsi/nsp32.h
+++ b/drivers/scsi/nsp32.h
@@ -69,11 +69,6 @@
 typedef u16 u16_le;
 
 /*
- * MACRO
- */
-#define BIT(x)      (1UL << (x))
-
-/*
  * BASIC Definitions
  */
 #ifndef TRUE
diff --git a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c
index 26a6d55..8e5eadb 100644
--- a/drivers/scsi/oktagon_esp.c
+++ b/drivers/scsi/oktagon_esp.c
@@ -550,8 +550,7 @@
 
 void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp)
 {
-        sp->SCp.ptr = page_address(sp->SCp.buffer->page)+
-		      sp->SCp.buffer->offset;
+        sp->SCp.ptr = sg_virt(sp->SCp.buffer);
 }
 
 void dma_mmu_release_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp)
@@ -564,8 +563,7 @@
 
 void dma_advance_sg(Scsi_Cmnd *sp)
 {
-	sp->SCp.ptr = page_address(sp->SCp.buffer->page)+
-		      sp->SCp.buffer->offset;
+	sp->SCp.ptr = sg_virt(sp->SCp.buffer);
 }
 
 
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 331b789..1c5c4b6 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -542,7 +542,7 @@
 	if (STp->raw) {
 		if (STp->buffer->syscall_result) {
 			for (i=0; i < STp->buffer->sg_segs; i++)
-				memset(page_address(STp->buffer->sg[i].page),
+				memset(page_address(sg_page(&STp->buffer->sg[i])),
 				       0, STp->buffer->sg[i].length);
 			strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
                 } else
@@ -4437,7 +4437,7 @@
 		for (i = 0, b_size = 0; 
 		     (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE); 
 		     b_size += STp->buffer->sg[i++].length);
-		STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
+		STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
 			STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
@@ -5252,25 +5252,26 @@
 	/* Try to allocate the first segment up to OS_DATA_SIZE and the others
 	   big enough to reach the goal (code assumes no segments in place) */
 	for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
-		STbuffer->sg[0].page = alloc_pages(priority, order);
+		struct page *page = alloc_pages(priority, order);
+
 		STbuffer->sg[0].offset = 0;
-		if (STbuffer->sg[0].page != NULL) {
+		if (page != NULL) {
+		    sg_set_page(&STbuffer->sg[0], page);
 		    STbuffer->sg[0].length = b_size;
-		    STbuffer->b_data = page_address(STbuffer->sg[0].page);
+		    STbuffer->b_data = page_address(page);
 		    break;
 		}
 	}
-	if (STbuffer->sg[0].page == NULL) {
+	if (sg_page(&STbuffer->sg[0]) == NULL) {
 		printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
 		return 0;
 	}
 	/* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
 	for (segs=STbuffer->sg_segs=1, got=b_size;
 	     segs < max_segs && got < OS_FRAME_SIZE; ) {
-		STbuffer->sg[segs].page =
-				alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
+		struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
 		STbuffer->sg[segs].offset = 0;
-		if (STbuffer->sg[segs].page == NULL) {
+		if (page == NULL) {
 			if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
 				b_size /= 2;  /* Large enough for the rest of the buffers */
 				order--;
@@ -5284,6 +5285,7 @@
 			normalize_buffer(STbuffer);
 			return 0;
 		}
+		sg_set_page(&STbuffer->sg[segs], page);
 		STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
 		got += STbuffer->sg[segs].length;
 		STbuffer->buffer_size = got;
@@ -5316,7 +5318,7 @@
 		     b_size < STbuffer->sg[i].length;
 		     b_size *= 2, order++);
 
-		__free_pages(STbuffer->sg[i].page, order);
+		__free_pages(sg_page(&STbuffer->sg[i]), order);
 		STbuffer->buffer_size -= STbuffer->sg[i].length;
 	}
 #if DEBUG
@@ -5344,7 +5346,7 @@
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count;
-		res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
+		res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -5377,7 +5379,7 @@
 	for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count;
-		res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
+		res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
 		if (res)
 			return (-EFAULT);
 		do_count -= cnt;
@@ -5410,7 +5412,7 @@
 	     i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length - offset < do_count ?
 		      st_bp->sg[i].length - offset : do_count ;
-		memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
+		memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
 		do_count -= cnt;
 		offset = 0;
 	}
@@ -5430,7 +5432,7 @@
 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length < do_count ?
 		      st_bp->sg[i].length : do_count ;
-		memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
+		memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
 		do_count -= cnt;
 		ptr      += cnt;
 	}
@@ -5451,7 +5453,7 @@
 	for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
 		cnt = st_bp->sg[i].length < do_count ?
 		      st_bp->sg[i].length : do_count ;
-		memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
+		memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
 		do_count -= cnt;
 		ptr      += cnt;
 	}
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index b7f0fa2..7db28cd 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -24,7 +24,6 @@
 /************************************
  * Some useful macros...
  */
-#define BIT(x)      (1L << (x))
 
 /* SCSI initiator must be ID 7 */
 #define NSP_INITIATOR_ID  7
@@ -394,7 +393,7 @@
 #define MSG_EXT_SDTR         0x01
 
 /* scatter-gather table */
-#  define BUFFER_ADDR ((char *)((unsigned int)(SCpnt->SCp.buffer->page) + SCpnt->SCp.buffer->offset))
+#  define BUFFER_ADDR ((char *)((sg_virt(SCpnt->SCp.buffer))))
 
 #endif  /*__nsp_cs__*/
 /* end */
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 190e2a7..969b938 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -443,8 +443,7 @@
 
 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
 				SYM53C500_pio_write(fast_pio, port_base,
-						    page_address(sg->page) + sg->offset,
-						    sg->length);
+				    sg_virt(sg), sg->length);
 			}
 			REG0(port_base);
 		}
@@ -463,8 +462,7 @@
 
 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
 				SYM53C500_pio_read(fast_pio, port_base,
-						   page_address(sg->page) + sg->offset,
-						   sg->length);
+					sg_virt(sg), sg->length);
 			}
 			REG0(port_base);
 		}
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 67b6d76..67ee51a 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -608,9 +608,7 @@
 				cmd->SCp.buffer++;
 				cmd->SCp.this_residual =
 				    cmd->SCp.buffer->length;
-				cmd->SCp.ptr =
-				    page_address(cmd->SCp.buffer->page) +
-				    cmd->SCp.buffer->offset;
+				cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 			}
 		}
 		/* Now check to see if the drive is ready to comunicate */
@@ -756,8 +754,7 @@
 			/* if many buffers are available, start filling the first */
 			cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
-			cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
-			    cmd->SCp.buffer->offset;
+			cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		} else {
 			/* else fill the only available buffer */
 			cmd->SCp.buffer = NULL;
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c
index 0f43d1d..17b4a7c 100644
--- a/drivers/scsi/ps3rom.c
+++ b/drivers/scsi/ps3rom.c
@@ -111,14 +111,14 @@
 	req_len = act_len = 0;
 	scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
 		if (active) {
-			kaddr = kmap_atomic(sgpnt->page, KM_IRQ0);
+			kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
 			len = sgpnt->length;
 			if ((req_len + len) > buflen) {
 				active = 0;
 				len = buflen - req_len;
 			}
 			memcpy(kaddr + sgpnt->offset, buf + req_len, len);
-			flush_kernel_dcache_page(sgpnt->page);
+			flush_kernel_dcache_page(sg_page(sgpnt));
 			kunmap_atomic(kaddr, KM_IRQ0);
 			act_len += len;
 		}
@@ -147,7 +147,7 @@
 
 	req_len = fin = 0;
 	scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
-		kaddr = kmap_atomic(sgpnt->page, KM_IRQ0);
+		kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
 		len = sgpnt->length;
 		if ((req_len + len) > buflen) {
 			len = buflen - req_len;
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index 9bb3d1d..fe415ec 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -671,7 +671,7 @@
 #define ET_CONTINUE	ET_CONT_T1
 
 /* Marker entry structure*/
-struct marker_entry {
+struct qla4_marker_entry {
 	struct qla4_header hdr;	/* 00-03 */
 
 	uint32_t system_defined; /* 04-07 */
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 1e29f51..d692c71 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -1006,7 +1006,7 @@
  * qla4xxx_start_firmware - starts qla4xxx firmware
  * @ha: Pointer to host adapter structure.
  *
- * This routine performs the neccessary steps to start the firmware for
+ * This routine performs the necessary steps to start the firmware for
  * the QLA4010 adapter.
  **/
 static int qla4xxx_start_firmware(struct scsi_qla_host *ha)
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c
index 5006ecb..e4461b5 100644
--- a/drivers/scsi/qla4xxx/ql4_iocb.c
+++ b/drivers/scsi/qla4xxx/ql4_iocb.c
@@ -69,7 +69,7 @@
 static int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha,
 				    struct ddb_entry *ddb_entry, int lun)
 {
-	struct marker_entry *marker_entry;
+	struct qla4_marker_entry *marker_entry;
 	unsigned long flags = 0;
 	uint8_t status = QLA_SUCCESS;
 
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 03b68d4..89460d2 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -1286,7 +1286,7 @@
 
         ret = scsi_init_shared_tag_map(host, MAX_SRBS);
         if (ret) {
-                dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed");
+                dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed\n");
                 goto probe_failed;
         }
 
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index 2bfbf26..de7b3bc 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -317,7 +317,7 @@
 				return ((priv->qabort == 1 ?
 					 DID_ABORT : DID_RESET) << 16);
 			}
-			buf = page_address(sg->page) + sg->offset;
+			buf = sg_virt(sg);
 			if (ql_pdma(priv, phase, buf, sg->length))
 				break;
 		}
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 72ee4c9..46cae5a 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -625,7 +625,7 @@
 	scsi_for_each_sg(scp, sg, scp->use_sg, k) {
 		if (active) {
 			kaddr = (unsigned char *)
-				kmap_atomic(sg->page, KM_USER0);
+				kmap_atomic(sg_page(sg), KM_USER0);
 			if (NULL == kaddr)
 				return (DID_ERROR << 16);
 			kaddr_off = (unsigned char *)kaddr + sg->offset;
@@ -672,7 +672,7 @@
 	sg = scsi_sglist(scp);
 	req_len = fin = 0;
 	for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
-		kaddr = (unsigned char *)kmap_atomic(sg->page, KM_USER0);
+		kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
 		if (NULL == kaddr)
 			return -1;
 		kaddr_off = (unsigned char *)kaddr + sg->offset;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index aac8a02..61fdaf0 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -295,7 +295,7 @@
 	int i, err, nr_vecs = 0;
 
 	for_each_sg(sgl, sg, nsegs, i) {
-		page = sg->page;
+		page = sg_page(sg);
 		off = sg->offset;
 		len = sg->length;
  		data_len += len;
@@ -764,7 +764,7 @@
 		if (unlikely(!sgl))
 			goto enomem;
 
-		memset(sgl, 0, sizeof(*sgl) * sgp->size);
+		sg_init_table(sgl, sgp->size);
 
 		/*
 		 * first loop through, set initial index and return value
@@ -781,6 +781,13 @@
 			sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
 
 		/*
+		 * if we have nothing left, mark the last segment as
+		 * end-of-list
+		 */
+		if (!left)
+			sg_mark_end(sgl, this);
+
+		/*
 		 * don't allow subsequent mempool allocs to sleep, it would
 		 * violate the mempool principle.
 		 */
@@ -2353,7 +2360,7 @@
 	*offset = *offset - len_complete + sg->offset;
 
 	/* Assumption: contiguous pages can be accessed as "page + i" */
-	page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
+	page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
 	*offset &= ~PAGE_MASK;
 
 	/* Bytes in this sg-entry from *offset to the end of the page */
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 69f542c..a69b155 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -676,7 +676,7 @@
  *	success as well). Returns a negated errno value in case of error.
  *
  *	Note: most ioctls are forward onto the block subsystem or further
- *	down in the scsi subsytem.
+ *	down in the scsi subsystem.
  **/
 static int sd_ioctl(struct inode * inode, struct file * filp, 
 		    unsigned int cmd, unsigned long arg)
diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c
index ce80fa9..b113244 100644
--- a/drivers/scsi/seagate.c
+++ b/drivers/scsi/seagate.c
@@ -999,14 +999,14 @@
 				for (i = 0; i < nobuffs; ++i)
 					printk("scsi%d : buffer %d address = %p length = %d\n",
 					     hostno, i,
-					     page_address(buffer[i].page) + buffer[i].offset,
+					     sg_virt(&buffer[i]),
 					     buffer[i].length);
 			}
 #endif
 
 			buffer = (struct scatterlist *) SCint->request_buffer;
 			len = buffer->length;
-			data = page_address(buffer->page) + buffer->offset;
+			data = sg_virt(buffer);
 		} else {
 			DPRINTK (DEBUG_SG, "scsi%d : scatter gather not requested.\n", hostno);
 			buffer = NULL;
@@ -1239,7 +1239,7 @@
 					--nobuffs;
 					++buffer;
 					len = buffer->length;
-					data = page_address(buffer->page) + buffer->offset;
+					data = sg_virt(buffer);
 					DPRINTK (DEBUG_SG,
 						 "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
 						 hostno, len, data);
@@ -1396,7 +1396,7 @@
 					--nobuffs;
 					++buffer;
 					len = buffer->length;
-					data = page_address(buffer->page) + buffer->offset;
+					data = sg_virt(buffer);
 					DPRINTK (DEBUG_SG, "scsi%d : next scatter-gather buffer len = %d address = %08x\n", hostno, len, data);
 				}
 				break;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 7238b2d..cc19710 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1169,7 +1169,7 @@
 		len = vma->vm_end - sa;
 		len = (len < sg->length) ? len : sg->length;
 		if (offset < len) {
-			page = virt_to_page(page_address(sg->page) + offset);
+			page = virt_to_page(page_address(sg_page(sg)) + offset);
 			get_page(page);	/* increment page count */
 			break;
 		}
@@ -1717,13 +1717,13 @@
 		   goto out_unlock; */
         }
 
-	sgl[0].page = pages[0];
+	sg_set_page(sgl, pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
-			sgl[i].page = pages[i]; 
+			sg_set_page(&sgl[i], pages[i]);
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -1754,7 +1754,7 @@
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
@@ -1854,7 +1854,7 @@
 				scatter_elem_sz_prev = ret_sz;
 			}
 		}
-		sg->page = p;
+		sg_set_page(sg, p);
 		sg->length = (ret_sz > num) ? num : ret_sz;
 
 		SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
@@ -1907,14 +1907,14 @@
 		onum = 1;
 
 	ksglen = sg->length;
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
 		if (res)
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -1991,12 +1991,12 @@
 		} else {
 			int k;
 
-			for (k = 0; (k < schp->k_use_sg) && sg->page;
+			for (k = 0; (k < schp->k_use_sg) && sg_page(sg);
 			     ++k, sg = sg_next(sg)) {
 				SCSI_LOG_TIMEOUT(5, printk(
 				    "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
-				    k, sg->page, sg->length));
-				sg_page_free(sg->page, sg->length);
+				    k, sg_page(sg), sg->length));
+				sg_page_free(sg_page(sg), sg->length);
 			}
 		}
 		kfree(schp->buffer);
@@ -2038,7 +2038,7 @@
 	} else
 		onum = 1;
 
-	p = page_address(sg->page);
+	p = page_address(sg_page(sg));
 	ksglen = sg->length;
 	for (j = 0, k = 0; j < onum; ++j) {
 		res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
@@ -2046,7 +2046,7 @@
 			return res;
 
 		for (; p; sg = sg_next(sg), ksglen = sg->length,
-		     p = page_address(sg->page)) {
+		     p = page_address(sg_page(sg))) {
 			if (usglen <= 0)
 				break;
 			if (ksglen > usglen) {
@@ -2092,15 +2092,15 @@
 	if ((!outp) || (num_read_xfer <= 0))
 		return 0;
 
-	for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
+	for (k = 0; (k < schp->k_use_sg) && sg_page(sg); ++k, sg = sg_next(sg)) {
 		num = sg->length;
 		if (num > num_read_xfer) {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num_read_xfer))
 				return -EFAULT;
 			break;
 		} else {
-			if (__copy_to_user(outp, page_address(sg->page),
+			if (__copy_to_user(outp, page_address(sg_page(sg)),
 					   num))
 				return -EFAULT;
 			num_read_xfer -= num;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 73c44cb..ce69b9e 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3797,7 +3797,7 @@
 	sg = &(STbp->sg[0]);
 	frp = STbp->frp;
 	for (i=count=0; count < length; i++) {
-		sg[i].page = frp[i].page;
+		sg_set_page(&sg[i], frp[i].page);
 		if (length - count > frp[i].length)
 			sg[i].length = frp[i].length;
 		else
@@ -4446,14 +4446,14 @@
         }
 
 	/* Populate the scatter/gather list */
-	sgl[0].page = pages[0]; 
+	sg_set_page(&sgl[0], pages[0]);
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
+			sg_set_page(&sgl[i], pages[i]);;
 			sgl[i].offset = 0;
-			sgl[i].page = pages[i]; 
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
 		}
@@ -4483,7 +4483,7 @@
 	int i;
 
 	for (i=0; i < nr_pages; i++) {
-		struct page *page = sgl[i].page;
+		struct page *page = sg_page(&sgl[i]);
 
 		if (dirtied)
 			SetPageDirty(page);
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index dc15a22..2dcde37 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -272,8 +272,7 @@
 #define	HOSTNO		instance->host_no
 #define	H_NO(cmd)	(cmd)->device->host->host_no
 
-#define SGADDR(buffer) (void *)(((unsigned long)page_address((buffer)->page)) + \
-			(buffer)->offset)
+#define SGADDR(buffer) (void *)(((unsigned long)sg_virt(((buffer)))))
 
 #ifdef SUPPORT_TAGS
 
@@ -1596,7 +1595,7 @@
      * IO while SEL is true. But again, there are some disks out the in the
      * world that do that nevertheless. (Somebody claimed that this announces
      * reselection capability of the target.) So we better skip that test and
-     * only wait for BSY... (Famous german words: Der Klügere gibt nach :-)
+     * only wait for BSY... (Famous german words: Der Klügere gibt nach :-)
      */
 
     while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & 
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
index 8befab7..90cee94 100644
--- a/drivers/scsi/sym53c416.c
+++ b/drivers/scsi/sym53c416.c
@@ -196,7 +196,7 @@
 
 #define MAXHOSTS 4
 
-#define SG_ADDRESS(buffer)     ((char *) (page_address((buffer)->page)+(buffer)->offset))
+#define SG_ADDRESS(buffer)     ((char *) sg_virt((buffer)))
 
 enum phases
 {
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw2.h b/drivers/scsi/sym53c8xx_2/sym_fw2.h
index 6e5b952..ae1fb17 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw2.h
+++ b/drivers/scsi/sym53c8xx_2/sym_fw2.h
@@ -1781,7 +1781,7 @@
 	 *  While testing with bogus QUANTUM drives, the C1010 
 	 *  sometimes raised a spurious phase mismatch with 
 	 *  WSR and the CHMOV(1) triggered another PM.
-	 *  Waiting explicitely for the PHASE seemed to avoid 
+	 *  Waiting explicitly for the PHASE seemed to avoid
 	 *  the nested phase mismatch. Btw, this didn't happen 
 	 *  using my IBM drives.
 	 */
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index 5c72ca3..4419304 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -430,10 +430,7 @@
 
 static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length)
 {
-	memset(sg, 0, sizeof(struct scatterlist));
-	sg->page	= virt_to_page(addr);
-	sg->length	= length;
-	sg->offset	= (unsigned long)addr & ~PAGE_MASK;
+	sg_init_one(sg, addr, length);
 	return sg;
 }
 
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
index ea72bbe..6d1f0ed 100644
--- a/drivers/scsi/ultrastor.c
+++ b/drivers/scsi/ultrastor.c
@@ -681,7 +681,7 @@
 
 	max = scsi_sg_count(SCpnt);
 	scsi_for_each_sg(SCpnt, sg, max, i) {
-		mscp->sglist[i].address = isa_page_to_bus(sg->page) + sg->offset;
+		mscp->sglist[i].address = isa_page_to_bus(sg_page(sg)) + sg->offset;
 		mscp->sglist[i].num_bytes = sg->length;
 		transfer_length += sg->length;
 	}
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index 0e8e642..fdbb92d 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -410,8 +410,7 @@
 	if (cmd->use_sg) {
 		cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
 		cmd->SCp.buffers_residual = cmd->use_sg - 1;
-		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
-		    cmd->SCp.buffer->offset;
+		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
 	} else {
 		cmd->SCp.buffer = NULL;
@@ -745,8 +744,7 @@
 		++cmd->SCp.buffer;
 		--cmd->SCp.buffers_residual;
 		cmd->SCp.this_residual = cmd->SCp.buffer->length;
-		cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
-		    cmd->SCp.buffer->offset;
+		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
 	}
 	if (!cmd->SCp.this_residual) /* avoid bogus setups */
 		return;
diff --git a/drivers/scsi/wd33c93.h b/drivers/scsi/wd33c93.h
index 61ffb86..00123f2 100644
--- a/drivers/scsi/wd33c93.h
+++ b/drivers/scsi/wd33c93.h
@@ -155,7 +155,7 @@
 #define WD33C93_FS_12_15 OWNID_FS_12
 #define WD33C93_FS_16_20 OWNID_FS_16
 
-   /* pass input-clock explicitely. accepted mhz values are 8-10,12-20 */
+   /* pass input-clock explicitly. accepted mhz values are 8-10,12-20 */
 #define WD33C93_FS_MHZ(mhz) (mhz)
 
    /* Control register */
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
index 255c611..03cd44f 100644
--- a/drivers/scsi/wd7000.c
+++ b/drivers/scsi/wd7000.c
@@ -1123,7 +1123,7 @@
 		any2scsi(scb->maxlen, nseg * sizeof(Sgb));
 
 		scsi_for_each_sg(SCpnt, sg, nseg, i) {
-			any2scsi(sgb[i].ptr, isa_page_to_bus(sg->page) + sg->offset);
+			any2scsi(sgb[i].ptr, isa_page_to_bus(sg_page(sg)) + sg->offset);
 			any2scsi(sgb[i].len, sg->length);
 		}
 	} else {
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d6ae38e..ed438bc 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -62,11 +62,11 @@
 	  kernel will automatically use the first serial line, /dev/ttyS0, as
 	  system console.
 
-	  you can set that using a kernel command line option such as
+	  You can set that using a kernel command line option such as
 	  "console=uart8250,io,0x3f8,9600n8"
 	  "console=uart8250,mmio,0xff5e0000,115200n8".
-	  and it will switch to normal serial console when correponding port is
-	  ready.
+	  and it will switch to normal serial console when the corresponding 
+	  port is ready.
 	  "earlycon=uart8250,io,0x3f8,9600n8"
 	  "earlycon=uart8250,mmio,0xff5e0000,115200n8".
 	  it will not only setup early console.
@@ -624,7 +624,7 @@
 
 config SERIAL_BFIN_DMA
 	bool "DMA mode"
-	depends on DMA_UNCACHED_1M && !KGDB_UART
+	depends on !DMA_UNCACHED_NONE && !KGDB_UART
 	help
 	  This driver works under DMA mode. If this option is selected, the
 	  blackfin simple dma driver is also enabled.
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 72229df..40604a0 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -263,15 +263,15 @@
 	unsigned int result = 0;
 	unsigned int status = readw(uap->port.membase + UART01x_FR);
 
-#define BIT(uartbit, tiocmbit)		\
+#define TIOCMBIT(uartbit, tiocmbit)	\
 	if (status & uartbit)		\
 		result |= tiocmbit
 
-	BIT(UART01x_FR_DCD, TIOCM_CAR);
-	BIT(UART01x_FR_DSR, TIOCM_DSR);
-	BIT(UART01x_FR_CTS, TIOCM_CTS);
-	BIT(UART011_FR_RI, TIOCM_RNG);
-#undef BIT
+	TIOCMBIT(UART01x_FR_DCD, TIOCM_CAR);
+	TIOCMBIT(UART01x_FR_DSR, TIOCM_DSR);
+	TIOCMBIT(UART01x_FR_CTS, TIOCM_CTS);
+	TIOCMBIT(UART011_FR_RI, TIOCM_RNG);
+#undef TIOCMBIT
 	return result;
 }
 
@@ -282,18 +282,18 @@
 
 	cr = readw(uap->port.membase + UART011_CR);
 
-#define	BIT(tiocmbit, uartbit)		\
+#define	TIOCMBIT(tiocmbit, uartbit)		\
 	if (mctrl & tiocmbit)		\
 		cr |= uartbit;		\
 	else				\
 		cr &= ~uartbit
 
-	BIT(TIOCM_RTS, UART011_CR_RTS);
-	BIT(TIOCM_DTR, UART011_CR_DTR);
-	BIT(TIOCM_OUT1, UART011_CR_OUT1);
-	BIT(TIOCM_OUT2, UART011_CR_OUT2);
-	BIT(TIOCM_LOOP, UART011_CR_LBE);
-#undef BIT
+	TIOCMBIT(TIOCM_RTS, UART011_CR_RTS);
+	TIOCMBIT(TIOCM_DTR, UART011_CR_DTR);
+	TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1);
+	TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2);
+	TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE);
+#undef TIOCMBIT
 
 	writew(cr, uap->port.membase + UART011_CR);
 }
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 7e8724d..f523cdf 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -442,11 +442,11 @@
 #include <asm/uaccess.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <linux/delay.h>
 
 #include <asm/arch/svinto.h>
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
new file mode 100644
index 0000000..a7d4360
--- /dev/null
+++ b/drivers/serial/mcf.c
@@ -0,0 +1,653 @@
+/****************************************************************************/
+
+/*
+ *	mcf.c -- Freescale ColdFire UART driver
+ *
+ *	(C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com>
+ *
+ * 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/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfuart.h>
+#include <asm/nettel.h>
+
+/****************************************************************************/
+
+/*
+ *	Some boards implement the DTR/DCD lines using GPIO lines, most
+ *	don't. Dummy out the access macros for those that don't. Those
+ *	that do should define these macros somewhere in there board
+ *	specific inlude files.
+ */
+#if !defined(mcf_getppdcd)
+#define	mcf_getppdcd(p)		(1)
+#endif
+#if !defined(mcf_getppdtr)
+#define	mcf_getppdtr(p)		(1)
+#endif
+#if !defined(mcf_setppdtr)
+#define	mcf_setppdtr(p, v)	do { } while (0)
+#endif
+
+/****************************************************************************/
+
+/*
+ *	Local per-uart structure.
+ */
+struct mcf_uart {
+	struct uart_port	port;
+	unsigned int		sigs;		/* Local copy of line sigs */
+	unsigned char		imr;		/* Local IMR mirror */
+};
+
+/****************************************************************************/
+
+static unsigned int mcf_tx_empty(struct uart_port *port)
+{
+	return (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXEMPTY) ?
+		TIOCSER_TEMT : 0;
+}
+
+/****************************************************************************/
+
+static unsigned int mcf_get_mctrl(struct uart_port *port)
+{
+	struct mcf_uart *pp = (struct mcf_uart *) port;
+	unsigned long flags;
+	unsigned int sigs;
+
+	spin_lock_irqsave(&port->lock, flags);
+	sigs = (readb(port->membase + MCFUART_UIPR) & MCFUART_UIPR_CTS) ?
+		0 : TIOCM_CTS;
+	sigs |= (pp->sigs & TIOCM_RTS);
+	sigs |= (mcf_getppdcd(port->line) ? TIOCM_CD : 0);
+	sigs |= (mcf_getppdtr(port->line) ? TIOCM_DTR : 0);
+	spin_unlock_irqrestore(&port->lock, flags);
+	return sigs;
+}
+
+/****************************************************************************/
+
+static void mcf_set_mctrl(struct uart_port *port, unsigned int sigs)
+{
+	struct mcf_uart *pp = (struct mcf_uart *) port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	pp->sigs = sigs;
+	mcf_setppdtr(port->line, (sigs & TIOCM_DTR));
+	if (sigs & TIOCM_RTS)
+		writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1);
+	else
+		writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP0);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_start_tx(struct uart_port *port)
+{
+	struct mcf_uart *pp = (struct mcf_uart *) port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	pp->imr |= MCFUART_UIR_TXREADY;
+	writeb(pp->imr, port->membase + MCFUART_UIMR);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_stop_tx(struct uart_port *port)
+{
+	struct mcf_uart *pp = (struct mcf_uart *) port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	pp->imr &= ~MCFUART_UIR_TXREADY;
+	writeb(pp->imr, port->membase + MCFUART_UIMR);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_stop_rx(struct uart_port *port)
+{
+	struct mcf_uart *pp = (struct mcf_uart *) port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	pp->imr &= ~MCFUART_UIR_RXREADY;
+	writeb(pp->imr, port->membase + MCFUART_UIMR);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	if (break_state == -1)
+		writeb(MCFUART_UCR_CMDBREAKSTART, port->membase + MCFUART_UCR);
+	else
+		writeb(MCFUART_UCR_CMDBREAKSTOP, port->membase + MCFUART_UCR);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_enable_ms(struct uart_port *port)
+{
+}
+
+/****************************************************************************/
+
+static int mcf_startup(struct uart_port *port)
+{
+	struct mcf_uart *pp = (struct mcf_uart *) port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	/* Reset UART, get it into known state... */
+	writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
+	writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
+
+	/* Enable the UART transmitter and receiver */
+	writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE,
+		port->membase + MCFUART_UCR);
+
+	/* Enable RX interrupts now */
+	pp->imr = MCFUART_UIR_RXREADY;
+	writeb(pp->imr, port->membase + MCFUART_UIMR);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	return 0;
+}
+
+/****************************************************************************/
+
+static void mcf_shutdown(struct uart_port *port)
+{
+	struct mcf_uart *pp = (struct mcf_uart *) port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	/* Disable all interrupts now */
+	pp->imr = 0;
+	writeb(pp->imr, port->membase + MCFUART_UIMR);
+
+	/* Disable UART transmitter and receiver */
+	writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
+	writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
+	struct ktermios *old)
+{
+	unsigned long flags;
+	unsigned int baud, baudclk;
+	unsigned char mr1, mr2;
+
+	baud = uart_get_baud_rate(port, termios, old, 0, 230400);
+	baudclk = ((MCF_BUSCLK / baud) + 16) / 32;
+
+	mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR;
+	mr2 = 0;
+
+	switch (termios->c_cflag & CSIZE) {
+	case CS5: mr1 |= MCFUART_MR1_CS5; break;
+	case CS6: mr1 |= MCFUART_MR1_CS6; break;
+	case CS7: mr1 |= MCFUART_MR1_CS7; break;
+	case CS8:
+	default:  mr1 |= MCFUART_MR1_CS8; break;
+	}
+
+	if (termios->c_cflag & PARENB) {
+		if (termios->c_cflag & CMSPAR) {
+			if (termios->c_cflag & PARODD)
+				mr1 |= MCFUART_MR1_PARITYMARK;
+			else
+				mr1 |= MCFUART_MR1_PARITYSPACE;
+		} else {
+			if (termios->c_cflag & PARODD)
+				mr1 |= MCFUART_MR1_PARITYODD;
+			else
+				mr1 |= MCFUART_MR1_PARITYEVEN;
+		}
+	} else {
+		mr1 |= MCFUART_MR1_PARITYNONE;
+	}
+
+	if (termios->c_cflag & CSTOPB)
+		mr2 |= MCFUART_MR2_STOP2;
+	else
+		mr2 |= MCFUART_MR2_STOP1;
+
+	if (termios->c_cflag & CRTSCTS) {
+		mr1 |= MCFUART_MR1_RXRTS;
+		mr2 |= MCFUART_MR2_TXCTS;
+	}
+
+	spin_lock_irqsave(&port->lock, flags);
+	writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
+	writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
+	writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR);
+	writeb(mr1, port->membase + MCFUART_UMR);
+	writeb(mr2, port->membase + MCFUART_UMR);
+	writeb((baudclk & 0xff00) >> 8, port->membase + MCFUART_UBG1);
+	writeb((baudclk & 0xff), port->membase + MCFUART_UBG2);
+	writeb(MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER,
+		port->membase + MCFUART_UCSR);
+	writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE,
+		port->membase + MCFUART_UCR);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/****************************************************************************/
+
+static void mcf_rx_chars(struct mcf_uart *pp)
+{
+	struct uart_port *port = (struct uart_port *) pp;
+	unsigned char status, ch, flag;
+
+	while ((status = readb(port->membase + MCFUART_USR)) & MCFUART_USR_RXREADY) {
+		ch = readb(port->membase + MCFUART_URB);
+		flag = TTY_NORMAL;
+		port->icount.rx++;
+
+		if (status & MCFUART_USR_RXERR) {
+			writeb(MCFUART_UCR_CMDRESETERR,
+				port->membase + MCFUART_UCR);
+
+			if (status & MCFUART_USR_RXBREAK) {
+				port->icount.brk++;
+				if (uart_handle_break(port))
+					continue;
+			} else if (status & MCFUART_USR_RXPARITY) {
+				port->icount.parity++;
+			} else if (status & MCFUART_USR_RXOVERRUN) {
+				port->icount.overrun++;
+			} else if (status & MCFUART_USR_RXFRAMING) {
+				port->icount.frame++;
+			}
+
+			status &= port->read_status_mask;
+
+			if (status & MCFUART_USR_RXBREAK)
+				flag = TTY_BREAK;
+			else if (status & MCFUART_USR_RXPARITY)
+				flag = TTY_PARITY;
+			else if (status & MCFUART_USR_RXFRAMING)
+				flag = TTY_FRAME;
+		}
+
+		if (uart_handle_sysrq_char(port, ch))
+			continue;
+		uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag);
+	}
+
+	tty_flip_buffer_push(port->info->tty);
+}
+
+/****************************************************************************/
+
+static void mcf_tx_chars(struct mcf_uart *pp)
+{
+	struct uart_port *port = (struct uart_port *) pp;
+	struct circ_buf *xmit = &port->info->xmit;
+
+	if (port->x_char) {
+		/* Send special char - probably flow control */
+		writeb(port->x_char, port->membase + MCFUART_UTB);
+		port->x_char = 0;
+		port->icount.tx++;
+		return;
+	}
+
+	while (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) {
+		if (xmit->head == xmit->tail)
+			break;
+		writeb(xmit->buf[xmit->tail], port->membase + MCFUART_UTB);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1);
+		port->icount.tx++;
+	}
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (xmit->head == xmit->tail) {
+		pp->imr &= ~MCFUART_UIR_TXREADY;
+		writeb(pp->imr, port->membase + MCFUART_UIMR);
+	}
+}
+
+/****************************************************************************/
+
+static irqreturn_t mcf_interrupt(int irq, void *data)
+{
+	struct uart_port *port = data;
+	struct mcf_uart *pp = (struct mcf_uart *) port;
+	unsigned int isr;
+
+	isr = readb(port->membase + MCFUART_UISR) & pp->imr;
+	if (isr & MCFUART_UIR_RXREADY)
+		mcf_rx_chars(pp);
+	if (isr & MCFUART_UIR_TXREADY)
+		mcf_tx_chars(pp);
+	return IRQ_HANDLED;
+}
+
+/****************************************************************************/
+
+static void mcf_config_port(struct uart_port *port, int flags)
+{
+	port->type = PORT_MCF;
+
+	/* Clear mask, so no surprise interrupts. */
+	writeb(0, port->membase + MCFUART_UIMR);
+
+	if (request_irq(port->irq, mcf_interrupt, IRQF_DISABLED, "UART", port))
+		printk(KERN_ERR "MCF: unable to attach ColdFire UART %d "
+			"interrupt vector=%d\n", port->line, port->irq);
+}
+
+/****************************************************************************/
+
+static const char *mcf_type(struct uart_port *port)
+{
+	return (port->type == PORT_MCF) ? "ColdFire UART" : NULL;
+}
+
+/****************************************************************************/
+
+static int mcf_request_port(struct uart_port *port)
+{
+	/* UARTs always present */
+	return 0;
+}
+
+/****************************************************************************/
+
+static void mcf_release_port(struct uart_port *port)
+{
+	/* Nothing to release... */
+}
+
+/****************************************************************************/
+
+static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_MCF))
+		return -EINVAL;
+	return 0;
+}
+
+/****************************************************************************/
+
+/*
+ *	Define the basic serial functions we support.
+ */
+static struct uart_ops mcf_uart_ops = {
+	.tx_empty	= mcf_tx_empty,
+	.get_mctrl	= mcf_get_mctrl,
+	.set_mctrl	= mcf_set_mctrl,
+	.start_tx	= mcf_start_tx,
+	.stop_tx	= mcf_stop_tx,
+	.stop_rx	= mcf_stop_rx,
+	.enable_ms	= mcf_enable_ms,
+	.break_ctl	= mcf_break_ctl,
+	.startup	= mcf_startup,
+	.shutdown	= mcf_shutdown,
+	.set_termios	= mcf_set_termios,
+	.type		= mcf_type,
+	.request_port	= mcf_request_port,
+	.release_port	= mcf_release_port,
+	.config_port	= mcf_config_port,
+	.verify_port	= mcf_verify_port,
+};
+
+static struct mcf_uart mcf_ports[3];
+
+#define	MCF_MAXPORTS	(sizeof(mcf_ports) / sizeof(struct mcf_uart))
+
+/****************************************************************************/
+#if defined(CONFIG_SERIAL_MCF_CONSOLE)
+/****************************************************************************/
+
+int __init early_mcf_setup(struct mcf_platform_uart *platp)
+{
+	struct uart_port *port;
+	int i;
+
+	for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) {
+		port = &mcf_ports[i].port;
+
+		port->line = i;
+		port->type = PORT_MCF;
+		port->mapbase = platp[i].mapbase;
+		port->membase = (platp[i].membase) ? platp[i].membase :
+			(unsigned char __iomem *) port->mapbase;
+		port->iotype = SERIAL_IO_MEM;
+		port->irq = platp[i].irq;
+		port->uartclk = MCF_BUSCLK;
+		port->flags = ASYNC_BOOT_AUTOCONF;
+		port->ops = &mcf_uart_ops;
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+
+static void mcf_console_putc(struct console *co, const char c)
+{
+	struct uart_port *port = &(mcf_ports + co->index)->port;
+	int i;
+
+	for (i = 0; (i < 0x10000); i++) {
+		if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY)
+			break;
+	}
+	writeb(c, port->membase + MCFUART_UTB);
+	for (i = 0; (i < 0x10000); i++) {
+		if (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY)
+			break;
+	}
+}
+
+/****************************************************************************/
+
+static void mcf_console_write(struct console *co, const char *s, unsigned int count)
+{
+	for (; (count); count--, s++) {
+		mcf_console_putc(co, *s);
+		if (*s == '\n')
+			mcf_console_putc(co, '\r');
+	}
+}
+
+/****************************************************************************/
+
+static int __init mcf_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = CONFIG_SERIAL_MCF_BAUDRATE;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	if ((co->index >= 0) && (co->index <= MCF_MAXPORTS))
+		co->index = 0;
+	port = &mcf_ports[co->index].port;
+	if (port->membase == 0)
+		return -ENODEV;
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+/****************************************************************************/
+
+static struct uart_driver mcf_driver;
+
+static struct console mcf_console = {
+	.name		= "ttyS",
+	.write		= mcf_console_write,
+	.device		= uart_console_device,
+	.setup		= mcf_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+	.data		= &mcf_driver,
+};
+
+static int __init mcf_console_init(void)
+{
+	register_console(&mcf_console);
+	return 0;
+}
+
+console_initcall(mcf_console_init);
+
+#define	MCF_CONSOLE	&mcf_console
+
+/****************************************************************************/
+#else
+/****************************************************************************/
+
+#define	MCF_CONSOLE	NULL
+
+/****************************************************************************/
+#endif /* CONFIG_MCF_CONSOLE */
+/****************************************************************************/
+
+/*
+ *	Define the mcf UART driver structure.
+ */
+static struct uart_driver mcf_driver = {
+	.owner		= THIS_MODULE,
+	.driver_name	= "mcf",
+	.dev_name	= "ttyS",
+	.major		= TTY_MAJOR,
+	.minor		= 64,
+	.nr		= MCF_MAXPORTS,
+	.cons		= MCF_CONSOLE,
+};
+
+/****************************************************************************/
+
+static int __devinit mcf_probe(struct platform_device *pdev)
+{
+	struct mcf_platform_uart *platp = pdev->dev.platform_data;
+	struct uart_port *port;
+	int i;
+
+	for (i = 0; ((i < MCF_MAXPORTS) && (platp[i].mapbase)); i++) {
+		port = &mcf_ports[i].port;
+
+		port->line = i;
+		port->type = PORT_MCF;
+		port->mapbase = platp[i].mapbase;
+		port->membase = (platp[i].membase) ? platp[i].membase :
+			(unsigned char __iomem *) platp[i].mapbase;
+		port->iotype = SERIAL_IO_MEM;
+		port->irq = platp[i].irq;
+		port->uartclk = MCF_BUSCLK;
+		port->ops = &mcf_uart_ops;
+		port->flags = ASYNC_BOOT_AUTOCONF;
+
+		uart_add_one_port(&mcf_driver, port);
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+
+static int mcf_remove(struct platform_device *pdev)
+{
+	struct uart_port *port;
+	int i;
+
+	for (i = 0; (i < MCF_MAXPORTS); i++) {
+		port = &mcf_ports[i].port;
+		if (port)
+			uart_remove_one_port(&mcf_driver, port);
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+
+static struct platform_driver mcf_platform_driver = {
+	.probe		= mcf_probe,
+	.remove		= __devexit_p(mcf_remove),
+	.driver		= {
+		.name	= "mcfuart",
+		.owner	= THIS_MODULE,
+	},
+};
+
+/****************************************************************************/
+
+static int __init mcf_init(void)
+{
+	int rc;
+
+	printk("ColdFire internal UART serial driver\n");
+
+	rc = uart_register_driver(&mcf_driver);
+	if (rc)
+		return rc;
+	rc = platform_driver_register(&mcf_platform_driver);
+	if (rc)
+		return rc;
+	return 0;
+}
+
+/****************************************************************************/
+
+static void __exit mcf_exit(void)
+{
+	platform_driver_unregister(&mcf_platform_driver);
+	uart_unregister_driver(&mcf_driver);
+}
+
+/****************************************************************************/
+
+module_init(mcf_init);
+module_exit(mcf_exit);
+
+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
+MODULE_DESCRIPTION("Freescale ColdFire UART driver");
+MODULE_LICENSE("GPL");
+
+/****************************************************************************/
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 3f26c4b..e773c8e 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -20,8 +20,8 @@
  *		     - S3C2410 and S3C2440 serial support
  *		     - Power Management support
  *		     - Fix console via IrDA devices
- *		     - SysReq (Herbert Pötzl)
- *		     - Break character handling (Herbert Pötzl)
+ *		     - SysReq (Herbert Pötzl)
+ *		     - Break character handling (Herbert Pötzl)
  *		     - spin-lock initialisation (Dimitry Andric)
  *		     - added clock control
  *		     - updated init code to use platform_device info
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 68aa4da..1031890 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1959,12 +1959,11 @@
 
 	mutex_lock(&state->mutex);
 
-#ifdef CONFIG_DISABLE_CONSOLE_SUSPEND
-	if (uart_console(port)) {
+	if (!console_suspend_enabled && uart_console(port)) {
+		/* we're going to avoid suspending serial console */
 		mutex_unlock(&state->mutex);
 		return 0;
 	}
-#endif
 
 	tty_dev = device_find_child(port->dev, &match, serial_match_port);
 	if (device_may_wakeup(tty_dev)) {
@@ -2016,12 +2015,11 @@
 
 	mutex_lock(&state->mutex);
 
-#ifdef CONFIG_DISABLE_CONSOLE_SUSPEND
-	if (uart_console(port)) {
+	if (!console_suspend_enabled && uart_console(port)) {
+		/* no need to resume serial console, it wasn't suspended */
 		mutex_unlock(&state->mutex);
 		return 0;
 	}
-#endif
 
 	if (!port->suspended) {
 		disable_irq_wake(port->irq);
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index e9aba93..7051e6c 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -181,7 +181,7 @@
 		}
 
 
-		/* enable interupts and wait for wake up
+		/* enable interrupts and wait for wake up
 		 * if just one byte is expected the Rx FIFO genererates no
 		 * FFULL interrupt, so activate the RxRDY interrupt
 		 */
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 6cb71d7..2ef11bb 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -1070,7 +1070,7 @@
 		return -ENODEV;
 	}
 
-	dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d,",
+	dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d\n",
 			spi->modalias, chip->width, chip->enable_dma);
 	dev_dbg(&spi->dev, "ctl_reg is 0x%x, flag_reg is 0x%x\n",
 			chip->ctl_reg, chip->flag);
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index 3b4650a..7686ba3 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -1194,7 +1194,7 @@
 		chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
 		if (!chip) {
 			dev_err(&spi->dev,
-				"setup - cannot allocate controller state");
+				"setup - cannot allocate controller state\n");
 			return -ENOMEM;
 		}
 		chip->control = SPI_DEFAULT_CONTROL;
@@ -1206,7 +1206,7 @@
 			if (!chip_info) {
 				dev_err(&spi->dev,
 					"setup - "
-					"cannot allocate controller data");
+					"cannot allocate controller data\n");
 				status = -ENOMEM;
 				goto err_first_setup;
 			}
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index b4a5e5e..d976660c 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -22,7 +22,7 @@
 
 config SSB_PCIHOST_POSSIBLE
 	bool
-	depends on SSB && PCI
+	depends on SSB && (PCI = y || PCI = SSB)
 	default y
 
 config SSB_PCIHOST
@@ -37,7 +37,7 @@
 
 config SSB_PCMCIAHOST_POSSIBLE
 	bool
-	depends on SSB && PCMCIA && EXPERIMENTAL
+	depends on SSB && (PCMCIA = y || PCMCIA = SSB) && EXPERIMENTAL
 	default y
 
 config SSB_PCMCIAHOST
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c
index ab8691a..3d3dd32 100644
--- a/drivers/ssb/driver_mipscore.c
+++ b/drivers/ssb/driver_mipscore.c
@@ -173,7 +173,7 @@
 
 void ssb_mipscore_init(struct ssb_mipscore *mcore)
 {
-	struct ssb_bus *bus = mcore->dev->bus;
+	struct ssb_bus *bus;
 	struct ssb_device *dev;
 	unsigned long hz, ns;
 	unsigned int irq, i;
@@ -183,6 +183,7 @@
 
 	ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n");
 
+	bus = mcore->dev->bus;
 	hz = ssb_clockspeed(bus);
 	if (!hz)
 		hz = 100000000;
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index f51e224..912d97a 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -332,7 +332,7 @@
 		return;
 
 	if (status)
-		dev_dbg(&acm->data->dev, "bulk rx status %d", status);
+		dev_dbg(&acm->data->dev, "bulk rx status %d\n", status);
 
 	buf = rcv->buffer;
 	buf->size = urb->actual_length;
@@ -831,13 +831,13 @@
 	
 	/* normal probing*/
 	if (!buffer) {
-		err("Wierd descriptor references\n");
+		err("Weird descriptor references\n");
 		return -EINVAL;
 	}
 
 	if (!buflen) {
 		if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) {
-			dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint");
+			dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint\n");
 			buflen = intf->cur_altsetting->endpoint->extralen;
 			buffer = intf->cur_altsetting->endpoint->extra;
 		} else {
@@ -887,24 +887,24 @@
 
 	if (!union_header) {
 		if (call_interface_num > 0) {
-			dev_dbg(&intf->dev,"No union descriptor, using call management descriptor");
+			dev_dbg(&intf->dev,"No union descriptor, using call management descriptor\n");
 			data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num));
 			control_interface = intf;
 		} else {
-			dev_dbg(&intf->dev,"No union descriptor, giving up");
+			dev_dbg(&intf->dev,"No union descriptor, giving up\n");
 			return -ENODEV;
 		}
 	} else {
 		control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
 		data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0));
 		if (!control_interface || !data_interface) {
-			dev_dbg(&intf->dev,"no interfaces");
+			dev_dbg(&intf->dev,"no interfaces\n");
 			return -ENODEV;
 		}
 	}
 	
 	if (data_interface_num != call_interface_num)
-		dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.");
+		dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.\n");
 
 skip_normal_probe:
 
@@ -912,7 +912,7 @@
 	if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) {
 		if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) {
 			struct usb_interface *t;
-			dev_dbg(&intf->dev,"Your device has switched interfaces.");
+			dev_dbg(&intf->dev,"Your device has switched interfaces.\n");
 
 			t = control_interface;
 			control_interface = data_interface;
@@ -927,7 +927,7 @@
 		return -ENODEV;
 	
 	if (usb_interface_claimed(data_interface)) { /* valid in this context */
-		dev_dbg(&intf->dev,"The data interface isn't available");
+		dev_dbg(&intf->dev,"The data interface isn't available\n");
 		return -EBUSY;
 	}
 
@@ -944,7 +944,7 @@
 	if (!usb_endpoint_dir_in(epread)) {
 		/* descriptors are swapped */
 		struct usb_endpoint_descriptor *t;
-		dev_dbg(&intf->dev,"The data interface has switched endpoints");
+		dev_dbg(&intf->dev,"The data interface has switched endpoints\n");
 		
 		t = epread;
 		epread = epwrite;
@@ -959,7 +959,7 @@
 	}
 
 	if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) {
-		dev_dbg(&intf->dev, "out of memory (acm kzalloc)");
+		dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n");
 		goto alloc_fail;
 	}
 
@@ -985,26 +985,26 @@
 
 	buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
 	if (!buf) {
-		dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)");
+		dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n");
 		goto alloc_fail2;
 	}
 	acm->ctrl_buffer = buf;
 
 	if (acm_write_buffers_alloc(acm) < 0) {
-		dev_dbg(&intf->dev, "out of memory (write buffer alloc)");
+		dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n");
 		goto alloc_fail4;
 	}
 
 	acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!acm->ctrlurb) {
-		dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)");
+		dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n");
 		goto alloc_fail5;
 	}
 	for (i = 0; i < num_rx_buf; i++) {
 		struct acm_ru *rcv = &(acm->ru[i]);
 
 		if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
-			dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)");
+			dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n");
 			goto alloc_fail7;
 		}
 
@@ -1015,13 +1015,13 @@
 		struct acm_rb *buf = &(acm->rb[i]);
 
 		if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) {
-			dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)");
+			dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
 			goto alloc_fail7;
 		}
 	}
 	acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!acm->writeurb) {
-		dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)");
+		dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n");
 		goto alloc_fail7;
 	}
 
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index f013b40..1f4f6d0 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -460,7 +460,7 @@
 		return 0;
 	/* if not yet claimed, claim it for the driver */
 	dev_warn(&ps->dev->dev, "usbfs: process %d (%s) did not claim interface %u before use\n",
-	       current->pid, current->comm, ifnum);
+	       task_pid_nr(current), current->comm, ifnum);
 	return claimintf(ps, ifnum);
 }
 
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
index 7dc123d..99e5a68 100644
--- a/drivers/usb/core/endpoint.c
+++ b/drivers/usb/core/endpoint.c
@@ -291,7 +291,7 @@
 
 	retval = endpoint_get_minor(ep_dev);
 	if (retval) {
-		dev_err(parent, "can not allocate minor number for %s",
+		dev_err(parent, "can not allocate minor number for %s\n",
 			ep_dev->dev.bus_id);
 		goto error_register;
 	}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 60a8f55..036c3de 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2870,10 +2870,9 @@
 	set_freezable();
 	do {
 		hub_events();
-		wait_event_interruptible(khubd_wait,
+		wait_event_freezable(khubd_wait,
 				!list_empty(&hub_event_list) ||
 				kthread_should_stop());
-		try_to_freeze();
 	} while (!kthread_should_stop() || !list_empty(&hub_event_list));
 
 	pr_debug("%s: khubd exiting\n", usbcore_name);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index c021af3..8bdaa15 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -11,9 +11,9 @@
 #include <linux/timer.h>
 #include <linux/ctype.h>
 #include <linux/device.h>
+#include <linux/scatterlist.h>
 #include <linux/usb/quirks.h>
 #include <asm/byteorder.h>
-#include <asm/scatterlist.h>
 
 #include "hcd.h"	/* for usbcore internals */
 #include "usb.h"
@@ -437,13 +437,11 @@
 #if defined(CONFIG_HIGHMEM) || defined(CONFIG_IOMMU)
 			io->urbs[i]->transfer_buffer = NULL;
 #else
-			io->urbs[i]->transfer_buffer =
-				page_address(sg[i].page) + sg[i].offset;
+			io->urbs[i]->transfer_buffer = sg_virt(&sg[i]);
 #endif
 		} else {
 			/* hc may use _only_ transfer_buffer */
-			io->urbs [i]->transfer_buffer =
-				page_address (sg [i].page) + sg [i].offset;
+			io->urbs [i]->transfer_buffer = sg_virt(&sg[i]);
 			len = sg [i].length;
 		}
 
@@ -1526,7 +1524,7 @@
 		new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
 				GFP_KERNEL);
 		if (!new_interfaces) {
-			dev_err(&dev->dev, "Out of memory");
+			dev_err(&dev->dev, "Out of memory\n");
 			return -ENOMEM;
 		}
 
@@ -1535,7 +1533,7 @@
 					sizeof(struct usb_interface),
 					GFP_KERNEL);
 			if (!new_interfaces[n]) {
-				dev_err(&dev->dev, "Out of memory");
+				dev_err(&dev->dev, "Out of memory\n");
 				ret = -ENOMEM;
 free_interfaces:
 				while (--n >= 0)
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 73726c5..1d174dc 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -4006,7 +4006,7 @@
 	DBG(fsg, "removable=%d, stall=%d, buflen=%u\n",
 			mod_data.removable, mod_data.can_stall,
 			mod_data.buflen);
-	DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid);
+	DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task));
 
 	set_bit(REGISTERED, &fsg->atomic_bitflags);
 
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index e78c2dd..367b75c 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -1272,7 +1272,7 @@
 			/*
 			 * Attempts to halt IN endpoints will fail (returning -EAGAIN)
 			 * if any transfer requests are still queued, or if the controller
-			 * FIFO still holds bytes that the host hasnÂ’t collected.
+			 * FIFO still holds bytes that the host hasn't collected.
 			 */
 			spin_unlock_irqrestore(&ep->dev->lock, flags);
 			DEBUG
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 0dcb416..735db4a 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -451,7 +451,7 @@
 
 	/* Some boards (mostly VIA?) report bogus overcurrent indications,
 	 * causing massive log spam unless we completely ignore them.  It
-	 * may be relevant that VIA VT8235 controlers, where PORT_POWER is
+	 * may be relevant that VIA VT8235 controllers, where PORT_POWER is
 	 * always set, seem to clear PORT_OCC and PORT_CSC when writing to
 	 * PORT_POWER; that's surprising, but maybe within-spec.
 	 */
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 6829814..44b79e8 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -358,7 +358,7 @@
 	hcd->rsrc_len   = dev->resource[0].end - dev->resource[0].start + 1;
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-		dev_err(&dev->dev, "request_mem_region failed");
+		dev_err(&dev->dev, "request_mem_region failed\n");
 		retval = -EBUSY;
 		goto err_put;
 	}
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 94d859a..ba370c5 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1556,7 +1556,7 @@
 		hcd->power_budget = sl811->board->power * 2;
 	}
 
-	/* enable power and interupts */
+	/* enable power and interrupts */
 	port_power(sl811, 1);
 
 	return 0;
diff --git a/drivers/usb/image/Kconfig b/drivers/usb/image/Kconfig
index 95ce703..7595dfb 100644
--- a/drivers/usb/image/Kconfig
+++ b/drivers/usb/image/Kconfig
@@ -1,5 +1,5 @@
 #
-# USB Imageing devices configuration
+# USB Imaging devices configuration
 #
 comment "USB Imaging devices"
 	depends on USB
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index e7d982a..91e999c 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -519,8 +519,7 @@
 	context->fragment++;
 	mts_int_submit_urb(transfer,
 			   context->data_pipe,
-			   page_address(sg[context->fragment].page) +
-			   sg[context->fragment].offset,
+			   sg_virt(&sg[context->fragment]),
 			   sg[context->fragment].length,
 			   context->fragment + 1 == scsi_sg_count(context->srb) ?
 			   mts_data_done : mts_do_sg);
@@ -557,7 +556,7 @@
 		return;
 	} else {
 		sg = scsi_sglist(srb);
-		desc->context.data = page_address(sg[0].page) + sg[0].offset;
+		desc->context.data = sg_virt(&sg[0]);
 		desc->context.data_length = sg[0].length;
 	}
 
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c
index 5131cbf..c567aa7 100644
--- a/drivers/usb/misc/adutux.c
+++ b/drivers/usb/misc/adutux.c
@@ -805,7 +805,7 @@
 	dev->minor = interface->minor;
 
 	/* let the user know what node this device is now attached to */
-	dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d",
+	dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d\n",
 		 udev->descriptor.idProduct, dev->serial_number,
 		 (dev->minor - ADU_MINOR_BASE));
 exit:
@@ -851,7 +851,7 @@
 		mutex_unlock(&dev->mtx);
 	}
 
-	dev_info(&interface->dev, "ADU device adutux%d now disconnected",
+	dev_info(&interface->dev, "ADU device adutux%d now disconnected\n",
 		 (minor - ADU_MINOR_BASE));
 
 	dbg(2," %s : leave", __FUNCTION__);
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c
index 04e87ac..2677fea 100644
--- a/drivers/usb/misc/cytherm.c
+++ b/drivers/usb/misc/cytherm.c
@@ -118,7 +118,7 @@
 				cytherm->brightness, buffer, 8);
 	if (retval)
 		dev_dbg(&cytherm->udev->dev, "retval = %d\n", retval);
-	/* Inform µC that we have changed the brightness setting */
+	/* Inform µC that we have changed the brightness setting */
 	retval = vendor_command(cytherm->udev, WRITE_RAM, BRIGHTNESS_SEM,
 				0x01, buffer, 8);
 	if (retval)
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c
index 5c0a26c..cd13757 100644
--- a/drivers/usb/misc/emi26.c
+++ b/drivers/usb/misc/emi26.c
@@ -1,7 +1,7 @@
 /* 
  * Emagic EMI 2|6 usb audio interface firmware loader.
  * Copyright (C) 2002
- * 	Tapio Laxström (tapio.laxstrom@iptime.fi)
+ * 	Tapio Laxström (tapio.laxstrom@iptime.fi)
  *
  * 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
@@ -249,7 +249,7 @@
 module_init(emi26_init);
 module_exit(emi26_exit);
 
-MODULE_AUTHOR("tapio laxström");
+MODULE_AUTHOR("Tapio Laxström");
 MODULE_DESCRIPTION("Emagic EMI 2|6 firmware loader.");
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c
index 23153ea..4758cc5 100644
--- a/drivers/usb/misc/emi62.c
+++ b/drivers/usb/misc/emi62.c
@@ -1,7 +1,7 @@
 /* 
  * Emagic EMI 2|6 usb audio interface firmware loader.
  * Copyright (C) 2002
- * 	Tapio Laxström (tapio.laxstrom@iptime.fi)
+ * 	Tapio Laxström (tapio.laxstrom@iptime.fi)
  *
  * 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
@@ -292,7 +292,7 @@
 module_init(emi62_init);
 module_exit(emi62_exit);
 
-MODULE_AUTHOR("tapio laxström");
+MODULE_AUTHOR("Tapio Laxström");
 MODULE_DESCRIPTION("Emagic EMI 6|2m firmware loader.");
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 46d9f27..d372fbc 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -216,7 +216,7 @@
 exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
-		dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d",
+		dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d\n",
 			__FUNCTION__, retval);
 
 }
@@ -451,7 +451,7 @@
 		break;
 	default:
 		/* what do we have here ? An unsupported Product-ID ? */
-		dev_err(&dev->interface->dev, "%s - not supported for product=0x%x",
+		dev_err(&dev->interface->dev, "%s - not supported for product=0x%x\n",
 			__FUNCTION__, dev->product_id);
 		retval = -EFAULT;
 		goto exit;
@@ -526,7 +526,7 @@
 		} else {
 			retval = -EINVAL;
 			dev_err(&dev->interface->dev,
-				"ioctl 'IOW_WRITE' is not supported for product=0x%x.",
+				"ioctl 'IOW_WRITE' is not supported for product=0x%x.\n",
 				dev->product_id);
 		}
 		break;
@@ -752,7 +752,7 @@
 	/* allocate memory for our device state and intialize it */
 	dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
 	if (dev == NULL) {
-		dev_err(&interface->dev, "Out of memory");
+		dev_err(&interface->dev, "Out of memory\n");
 		return retval;
 	}
 
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c
index df0ebcd..2ad09b1 100644
--- a/drivers/usb/misc/phidgetmotorcontrol.c
+++ b/drivers/usb/misc/phidgetmotorcontrol.c
@@ -155,7 +155,7 @@
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
 		dev_err(&mc->intf->dev,
-			"can't resubmit intr, %s-%s/motorcontrol0, retval %d",
+			"can't resubmit intr, %s-%s/motorcontrol0, retval %d\n",
 			mc->udev->bus->bus_name,
 			mc->udev->devpath, retval);
 }
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index e901d31..ea31621 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -360,9 +360,9 @@
 	if (!sg)
 		return;
 	for (i = 0; i < nents; i++) {
-		if (!sg [i].page)
+		if (!sg_page(&sg[i]))
 			continue;
-		kfree (page_address (sg [i].page) + sg [i].offset);
+		kfree (sg_virt(&sg[i]));
 	}
 	kfree (sg);
 }
diff --git a/drivers/usb/serial/ChangeLog.history b/drivers/usb/serial/ChangeLog.history
index 52c4f7b..c1b2799 100644
--- a/drivers/usb/serial/ChangeLog.history
+++ b/drivers/usb/serial/ChangeLog.history
@@ -400,7 +400,7 @@
 
  (11/11/2001) gkh
 	Added support for the m125 devices, and added check to prevent oopses
-	for Clié devices that lie about the number of ports they have.
+	for Clié devices that lie about the number of ports they have.
 
  (08/30/2001) gkh
 	Added support for the Clie devices, both the 3.5 and 4.0 os versions.
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 99fefed..4a86696 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -527,7 +527,7 @@
 	depends on USB_SERIAL && EXPERIMENTAL
 	---help---
 	  Say Y here if you want to use a cyberJack pinpad/e-com USB chipcard
-	  reader. This is an interface to ISO 7816 compatible contactbased
+	  reader. This is an interface to ISO 7816 compatible contact-based
 	  chipcards, e.g. GSM SIMs.
 
 	  To compile this driver as a module, choose M here: the
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index e4c248c..8a8a6b9 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -83,7 +83,7 @@
  *
  * (18/Jun/2003) Ian Abbott
  *      Added Device ID of the USB relais from Rudolf Gugler (backported from
- *      Philipp Gühring's patch for 2.5.x kernel).
+ *      Philipp Gühring's patch for 2.5.x kernel).
  *      Moved read transfer buffer reallocation into startup function.
  *      Free existing write urb and transfer buffer in startup function.
  *      Only use urbs in write urb pool that were successfully allocated.
@@ -1071,7 +1071,7 @@
 			     (char*) &latency, 1, WDR_TIMEOUT);
 
 	if (rv < 0) {
-		dev_err(dev, "Unable to read latency timer: %i", rv);
+		dev_err(dev, "Unable to read latency timer: %i\n", rv);
 		return -EIO;
 	}
 	return sprintf(buf, "%i\n", latency);
@@ -1098,7 +1098,7 @@
 			     buf, 0, WDR_TIMEOUT);
 
 	if (rv < 0) {
-		dev_err(dev, "Unable to write latency timer: %i", rv);
+		dev_err(dev, "Unable to write latency timer: %i\n", rv);
 		return -EIO;
 	}
 
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index b57b90a..b51cbb0 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -17,7 +17,7 @@
  * Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the 
  * FTDI_SIO implementation.
  *
- * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais
+ * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais
  * from Rudolf Gugler
  *
  */
@@ -44,7 +44,7 @@
 #define FTDI_ACTZWAVE_PID	0xF2D0
 
 
-/* www.starting-point-systems.com µChameleon device */
+/* www.starting-point-systems.com µChameleon device */
 #define FTDI_MICRO_CHAMELEON_PID	0xCAA0	/* Product Id */
 
 /* www.irtrans.de device */
@@ -419,7 +419,7 @@
 
 /*
  * Teratronik product ids.
- * Submitted by O. Wölfelschneider.
+ * Submitted by O. Wölfelschneider.
  */
 #define FTDI_TERATRONIK_VCP_PID	 0xEC88	/* Teratronik device (preferring VCP driver on windows) */
 #define FTDI_TERATRONIK_D2XX_PID 0xEC89	/* Teratronik device (preferring D2XX driver on windows) */
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 2ecb1d2..8dd3abc 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -2882,7 +2882,7 @@
 	    (edge_serial->product_info.NumPorts != serial->num_ports)) {
 		dev_warn(&serial->dev->dev, "Device Reported %d serial ports "
 			 "vs. core thinking we have %d ports, email "
-			 "greg@kroah.com this information.",
+			 "greg@kroah.com this information.\n",
 			 edge_serial->product_info.NumPorts,
 			 serial->num_ports);
 	}
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index e836ad0..9b38a08 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -306,7 +306,7 @@
 	{ USB_DEVICE(0x0930, 0x0705) }, /* TOSHIBA Pocket PC e310 */
 	{ USB_DEVICE(0x0930, 0x0706) }, /* TOSHIBA Pocket PC e740 */
 	{ USB_DEVICE(0x0930, 0x0707) }, /* TOSHIBA Pocket PC e330 Series */
-	{ USB_DEVICE(0x0930, 0x0708) }, /* TOSHIBA Pocket PC e350 Series */
+	{ USB_DEVICE(0x0930, 0x0708) }, /* TOSHIBA Pocket PC e350 Series */
 	{ USB_DEVICE(0x0930, 0x0709) }, /* TOSHIBA Pocket PC e750 Series */
 	{ USB_DEVICE(0x0930, 0x070A) }, /* TOSHIBA Pocket PC e400 Series */
 	{ USB_DEVICE(0x0930, 0x070B) }, /* TOSHIBA Pocket PC e800 Series */
@@ -488,7 +488,7 @@
 	{ USB_DEVICE(0x0BF8, 0x1001) }, /* Fujitsu Siemens Computers USB Sync */
 	{ USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */
 	{ USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */
-	{ USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */
+	{ USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */
 	{ USB_DEVICE(0x0F4E, 0x0200) }, /* Freedom Scientific USB Sync */
 	{ USB_DEVICE(0x0F98, 0x0201) }, /* Cyberbank USB Sync */
 	{ USB_DEVICE(0x0FB8, 0x3001) }, /* Wistron USB Sync */
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 1b94daa..cbe5530 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -227,7 +227,7 @@
 				 0,
 				 100000);
 	if (result < 0)
-		dev_err(&port->dev, "Init of modem failed (error = %d)", result);
+		dev_err(&port->dev, "Init of modem failed (error = %d)\n", result);
 
 	/* reset the bulk pipes */
 	usb_clear_halt(dev, usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress));
@@ -255,7 +255,7 @@
 				 0,
 				 100000);
 	if (result < 0) 
-		dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)", result);
+		dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)\n", result);
 
 	/*--4: setup the initial flowcontrol */
 	dbg("%s:setting init flowcontrol (%s)",__FUNCTION__,buf_flow_init);
@@ -268,7 +268,7 @@
 				 0x10,
 				 200000);
 	if (result < 0)
-		dev_err(&port->dev, "initial flowcontrol failed (error = %d)", result);
+		dev_err(&port->dev, "initial flowcontrol failed (error = %d)\n", result);
 
 
 	/*--5: raise the dtr */
@@ -282,7 +282,7 @@
 				 0,
 				 200000);
 	if (result < 0)
-		dev_err(&port->dev, "setting dtr failed (error = %d)", result);
+		dev_err(&port->dev, "setting dtr failed (error = %d)\n", result);
 
 	/*--6: raise the rts */
 	dbg("%s:raising rts",__FUNCTION__);
@@ -295,7 +295,7 @@
 				 0,
 				 200000);
 	if (result < 0)
-		dev_err(&port->dev, "setting dtr failed (error = %d)", result);
+		dev_err(&port->dev, "setting dtr failed (error = %d)\n", result);
 	
 	kfree(buf_flow_init);
 	return 0;
@@ -322,7 +322,7 @@
 				 0,
 				 200000);
 	if (result < 0)
-		dev_err(&port->dev, "dropping dtr failed (error = %d)", result);
+		dev_err(&port->dev, "dropping dtr failed (error = %d)\n", result);
 
 	/*--2: drop the rts */
 	dbg("%s:dropping rts",__FUNCTION__);
@@ -334,7 +334,7 @@
 				 0,
 				 200000);
 	if (result < 0)
-		dev_err(&port->dev, "dropping rts failed (error = %d)", result);
+		dev_err(&port->dev, "dropping rts failed (error = %d)\n", result);
 
 
 	/*--3: purge */
@@ -347,7 +347,7 @@
 				 0,
 				 200000);
 	if (result < 0)
-		dev_err(&port->dev, "purge failed (error = %d)", result);
+		dev_err(&port->dev, "purge failed (error = %d)\n", result);
 
 
 	/* send RXBULK_off (tell modem to stop transmitting bulk data on rx chan) */
@@ -361,7 +361,7 @@
 				 100000);
 
 	if (result < 0)
-		dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)", result);
+		dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)\n", result);
 
 	/* shutdown any in-flight urbs that we know about */
 	usb_kill_urb(port->read_urb);
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 01e811b..e02c198 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -478,7 +478,7 @@
 		response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL);
 		if (response)
 			dev_err(&port->dev,
-				"%s - Error %d submitting control urb",
+				"%s - Error %d submitting control urb\n",
 				__FUNCTION__, response);
 	}
 
@@ -492,7 +492,7 @@
 	response = usb_submit_urb(port->read_urb, GFP_KERNEL);
 	if (response)
 		dev_err(&port->dev,
-			"%s - Error %d submitting read urb", __FUNCTION__, response);
+			"%s - Error %d submitting read urb\n", __FUNCTION__, response);
 
 	/* initialize our icount structure */
 	memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount));
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index d198611..eea226ae 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -256,7 +256,7 @@
 				100);
 
 	if (result != OTI6858_CTRL_PKT_SIZE) {
-		dev_err(&port->dev, "%s(): error reading status", __FUNCTION__);
+		dev_err(&port->dev, "%s(): error reading status\n", __FUNCTION__);
 		kfree(new_setup);
 		/* we will try again */
 		schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2));
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 0bb8de4..959b3e4 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -48,7 +48,7 @@
 static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
 {
 	int result;
-	dev_dbg(&udev->dev, "%s", "SET POWER STATE");
+	dev_dbg(&udev->dev, "%s", "SET POWER STATE\n");
 	result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			0x00,			/* __u8 request      */
 			0x40,			/* __u8 request type */
@@ -63,7 +63,7 @@
 static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode)
 {
 	int result;
-	dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH");
+	dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH\n");
 	result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			SWIMS_USB_REQUEST_SetMode,	/* __u8 request      */
 			SWIMS_USB_REQUEST_TYPE_SetMode,	/* __u8 request type */
@@ -397,7 +397,7 @@
 			err = usb_submit_urb(urb, GFP_ATOMIC);
 			if (err)
 				dev_err(&port->dev, "resubmit read urb failed."
-					"(%d)", err);
+					"(%d)\n", err);
 		}
 	}
 	return;
@@ -525,7 +525,7 @@
 
 		result = usb_submit_urb(urb, GFP_KERNEL);
 		if (result) {
-			dev_err(&port->dev, "submit urb %d failed (%d) %d",
+			dev_err(&port->dev, "submit urb %d failed (%d) %d\n",
 				i, result, urb->transfer_buffer_length);
 		}
 	}
@@ -538,7 +538,7 @@
 	if (port->interrupt_in_urb) {
 		result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 		if (result)
-			dev_err(&port->dev, "submit irq_in urb failed %d",
+			dev_err(&port->dev, "submit irq_in urb failed %d\n",
 				result);
 	}
 	return 0;
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 6831dca..93a7724 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -3,7 +3,7 @@
  * $Id: isd200.c,v 1.16 2002/04/22 03:39:43 mdharm Exp $
  *
  * Current development and maintenance:
- *   (C) 2001-2002 Björn Stenberg (bjorn@haxx.se)
+ *   (C) 2001-2002 Björn Stenberg (bjorn@haxx.se)
  *
  * Developed with the assistance of:
  *   (C) 2002 Alan Stern <stern@rowland.org>
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index cc8f7c5..889622b 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -195,7 +195,7 @@
 		 * the *offset and *index values for the next loop. */
 		cnt = 0;
 		while (cnt < buflen) {
-			struct page *page = sg->page +
+			struct page *page = sg_page(sg) +
 					((sg->offset + *offset) >> PAGE_SHIFT);
 			unsigned int poff =
 					(sg->offset + *offset) & (PAGE_SIZE-1);
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 9b656ec..22ab238 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -407,7 +407,7 @@
 		"FinePix 1400Zoom",
 		US_SC_UFI, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY | US_FL_SINGLE_LUN),
 
-/* Reported by Peter Wächtler <pwaechtler@loewe-komp.de>
+/* Reported by Peter Wächtler <pwaechtler@loewe-komp.de>
  * The device needs the flags only.
  */
 UNUSUAL_DEV(  0x04ce, 0x0002, 0x0074, 0x0074,
@@ -1551,7 +1551,7 @@
 		US_FL_GO_SLOW ),
 
 /*
- * David Härdeman <david@2gen.com>
+ * David Härdeman <david@2gen.com>
  * The key makes the SCSI stack print confusing (but harmless) messages
  */
 UNUSUAL_DEV(  0x4146, 0xba01, 0x0100, 0x0100,
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 3451e8d0..ac6114e 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -907,12 +907,9 @@
 	if (delay_use > 0) {
 		printk(KERN_DEBUG "usb-storage: waiting for device "
 				"to settle before scanning\n");
-retry:
-		wait_event_interruptible_timeout(us->delay_wait,
+		wait_event_freezable_timeout(us->delay_wait,
 				test_bit(US_FLIDX_DISCONNECTING, &us->flags),
 				delay_use * HZ);
-		if (try_to_freeze())
-			goto retry;
 	}
 
 	/* If the device is still connected, perform the scanning */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index b3bf4ec..fb9d8d0 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -661,7 +661,7 @@
        help
          This enables support for the Hecuba board. This driver was tested
          with an E-Ink 800x600 display and x86 SBCs through a 16 bit GPIO
-         interface (8 bit data, 4 bit control). If you anticpate using
+         interface (8 bit data, 4 bit control). If you anticipate using
          this driver, say Y or M; otherwise say N. You must specify the
          GPIO IO address to be used for setting control and data.
 
@@ -815,7 +815,7 @@
 	help
 	  This is the framebuffer device for the Sun XVR-500 and similar
 	  graphics cards based upon the 3DLABS Wildcat chipset.  The driver
-	  only works on sparc64 systems where the system firwmare has
+	  only works on sparc64 systems where the system firmware has
 	  mostly initialized the card already.  It is treated as a
 	  completely dumb framebuffer device.
 
@@ -828,7 +828,7 @@
 	help
 	  This is the framebuffer device for the Sun XVR-2500 and similar
 	  graphics cards based upon the 3DLABS Wildcat chipset.  The driver
-	  only works on sparc64 systems where the system firwmare has
+	  only works on sparc64 systems where the system firmware has
 	  mostly initialized the card already.  It is treated as a
 	  completely dumb framebuffer device.
 
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index f2e243c..4c9ec3f 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -112,7 +112,7 @@
    +----------+---------------------------------------------+----------+-------+
    |          |                ^                            |          |       |
    |          |                |upper_margin                |          |       |
-   |          |                ¥                            |          |       |
+   |          |                v                            |          |       |
    +----------###############################################----------+-------+
    |          #                ^                            #          |       |
    |          #                |                            #          |       |
@@ -133,15 +133,15 @@
    |          #                |                            #          |       |
    |          #                |                            #          |       |
    |          #                |                            #          |       |
-   |          #                ¥                            #          |       |
+   |          #                v                            #          |       |
    +----------###############################################----------+-------+
    |          |                ^                            |          |       |
    |          |                |lower_margin                |          |       |
-   |          |                ¥                            |          |       |
+   |          |                v                            |          |       |
    +----------+---------------------------------------------+----------+-------+
    |          |                ^                            |          |       |
    |          |                |vsync_len                   |          |       |
-   |          |                ¥                            |          |       |
+   |          |                v                            |          |       |
    +----------+---------------------------------------------+----------+-------+
 
 
@@ -325,7 +325,7 @@
    CCIR -> PAL
    -----------
 
-      - a scanline is 64 µs long, of which 52.48 µs are visible. This is about
+      - a scanline is 64 µs long, of which 52.48 µs are visible. This is about
         736 visible 70 ns pixels per line.
       - we have 625 scanlines, of which 575 are visible (interlaced); after
         rounding this becomes 576.
@@ -333,7 +333,7 @@
    RETMA -> NTSC
    -------------
 
-      - a scanline is 63.5 µs long, of which 53.5 µs are visible.  This is about
+      - a scanline is 63.5 µs long, of which 53.5 µs are visible.  This is about
         736 visible 70 ns pixels per line.
       - we have 525 scanlines, of which 485 are visible (interlaced); after
         rounding this becomes 484.
@@ -802,7 +802,7 @@
 
 static u_short do_vmode_full = 0;	/* Change the Video Mode */
 static u_short do_vmode_pan = 0;	/* Update the Video Mode */
-static short do_blank = 0;		/* (Un)Blank the Screen (±1) */
+static short do_blank = 0;		/* (Un)Blank the Screen (±1) */
 static u_short do_cursor = 0;		/* Move the Cursor */
 
 
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index abe0c43..d775eb6 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -26,7 +26,7 @@
  *			   Anthony Tong <atong@uiuc.edu>
  *
  *  Generic LCD support written by Daniel Mantione, ported from 2.4.20 by Alex Kern
- *  Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug.
+ *  Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug.
  *
  *  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
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index 832e461..62bd444 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -457,7 +457,7 @@
 
 /* AU1100 LCD controller device driver */
 
-int au1100fb_drv_probe(struct device *dev)
+static int __init au1100fb_drv_probe(struct device *dev)
 {
 	struct au1100fb_device *fbdev = NULL;
 	struct resource *regs_res;
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index a22ccf9..267422f 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -27,7 +27,7 @@
          The scrollback buffer of the standard VGA console is located in
 	 the VGA RAM.  The size of this RAM is fixed and is quite small.
 	 If you require a larger scrollback buffer, this can be placed in
-	 System RAM which is dynamically allocated during intialization.
+	 System RAM which is dynamically allocated during initialization.
 	 Placing the scrollback buffer in System RAM will slightly slow
 	 down the console.
 
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index f57d7b2..d31b203 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -98,7 +98,7 @@
 	}
 }
 
-static struct linux_logo *newport_show_logo(void)
+static const struct linux_logo *newport_show_logo(void)
 {
 #ifdef CONFIG_LOGO_SGI_CLUT224
 	const struct linux_logo *logo = fb_find_logo(8);
@@ -108,8 +108,8 @@
 
 	if (!logo)
 		return NULL;
-	*clut = logo->clut;
-	*data = logo->data;
+	clut = logo->clut;
+	data = logo->data;
 
 	for (i = 0; i < logo->clutsize; i++) {
 		newport_bfwait(npregs);
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 9bb2cbf..5fb8675 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -62,7 +62,7 @@
 	struct display_switch	*dispsw;
 	struct display		*display;
 	struct pci_dev		*dev;
-	unsigned char 		__iomem *region;
+	unsigned char		__iomem *region;
 	unsigned char		__iomem *regs;
 	u_int			id;
 	int			func_use_count;
@@ -97,11 +97,11 @@
 /*
  * Our access methods.
  */
-#define cyber2000fb_writel(val,reg,cfb)	writel(val, (cfb)->regs + (reg))
-#define cyber2000fb_writew(val,reg,cfb)	writew(val, (cfb)->regs + (reg))
-#define cyber2000fb_writeb(val,reg,cfb)	writeb(val, (cfb)->regs + (reg))
+#define cyber2000fb_writel(val, reg, cfb)	writel(val, (cfb)->regs + (reg))
+#define cyber2000fb_writew(val, reg, cfb)	writew(val, (cfb)->regs + (reg))
+#define cyber2000fb_writeb(val, reg, cfb)	writeb(val, (cfb)->regs + (reg))
 
-#define cyber2000fb_readb(reg,cfb)	readb((cfb)->regs + (reg))
+#define cyber2000fb_readb(reg, cfb)		readb((cfb)->regs + (reg))
 
 static inline void
 cyber2000_crtcw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
@@ -221,12 +221,8 @@
 static void
 cyber2000fb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
-//	struct cfb_info *cfb = (struct cfb_info *)info;
-
-//	if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
-		cfb_imageblit(info, image);
-		return;
-//	}
+	cfb_imageblit(info, image);
+	return;
 }
 
 static int cyber2000fb_sync(struct fb_info *info)
@@ -277,12 +273,12 @@
 
 	/*
 	 * Pseudocolour:
-	 *         8     8
+	 *	   8     8
 	 * pixel --/--+--/-->  red lut  --> red dac
-	 *            |  8
-	 *            +--/--> green lut --> green dac
-	 *            |  8
-	 *            +--/-->  blue lut --> blue dac
+	 *	      |  8
+	 *	      +--/--> green lut --> green dac
+	 *	      |  8
+	 *	      +--/-->  blue lut --> blue dac
 	 */
 	case FB_VISUAL_PSEUDOCOLOR:
 		if (regno >= NR_PALETTE)
@@ -292,9 +288,9 @@
 		green >>= 8;
 		blue >>= 8;
 
-		cfb->palette[regno].red   = red;
+		cfb->palette[regno].red = red;
 		cfb->palette[regno].green = green;
-		cfb->palette[regno].blue  = blue;
+		cfb->palette[regno].blue = blue;
 
 		cyber2000fb_writeb(regno, 0x3c8, cfb);
 		cyber2000fb_writeb(red, 0x3c9, cfb);
@@ -304,12 +300,12 @@
 
 	/*
 	 * Direct colour:
-	 *          n     rl
-	 *  pixel --/--+--/-->  red lut  --> red dac
-	 *             |  gl
-	 *             +--/--> green lut --> green dac
-	 *             |  bl
-	 *             +--/-->  blue lut --> blue dac
+	 *	   n     rl
+	 * pixel --/--+--/-->  red lut  --> red dac
+	 *	      |  gl
+	 *	      +--/--> green lut --> green dac
+	 *	      |  bl
+	 *	      +--/-->  blue lut --> blue dac
 	 * n = bpp, rl = red length, gl = green length, bl = blue length
 	 */
 	case FB_VISUAL_DIRECTCOLOR:
@@ -325,9 +321,11 @@
 			 * to the high 6 bits of the LUT.
 			 */
 			cyber2000fb_writeb(regno << 2, 0x3c8, cfb);
-			cyber2000fb_writeb(cfb->palette[regno >> 1].red, 0x3c9, cfb);
+			cyber2000fb_writeb(cfb->palette[regno >> 1].red,
+					   0x3c9, cfb);
 			cyber2000fb_writeb(green, 0x3c9, cfb);
-			cyber2000fb_writeb(cfb->palette[regno >> 1].blue, 0x3c9, cfb);
+			cyber2000fb_writeb(cfb->palette[regno >> 1].blue,
+					   0x3c9, cfb);
 
 			green = cfb->palette[regno << 3].green;
 
@@ -335,9 +333,9 @@
 		}
 
 		if (var->green.length >= 5 && regno < 32) {
-			cfb->palette[regno << 3].red   = red;
+			cfb->palette[regno << 3].red = red;
 			cfb->palette[regno << 3].green = green;
-			cfb->palette[regno << 3].blue  = blue;
+			cfb->palette[regno << 3].blue = blue;
 
 			/*
 			 * The 5 bits of each colour component are
@@ -351,9 +349,9 @@
 		}
 
 		if (var->green.length == 4 && regno < 16) {
-			cfb->palette[regno << 4].red   = red;
+			cfb->palette[regno << 4].red = red;
 			cfb->palette[regno << 4].green = green;
-			cfb->palette[regno << 4].blue  = blue;
+			cfb->palette[regno << 4].blue = blue;
 
 			/*
 			 * The 5 bits of each colour component are
@@ -377,12 +375,12 @@
 
 	/*
 	 * True colour:
-	 *          n     rl
-	 *  pixel --/--+--/--> red dac
-	 *             |  gl
-	 *             +--/--> green dac
-	 *             |  bl
-	 *             +--/--> blue dac
+	 *	   n     rl
+	 * pixel --/--+--/--> red dac
+	 *	      |  gl
+	 *	      +--/--> green dac
+	 *	      |  bl
+	 *	      +--/--> blue dac
 	 * n = bpp, rl = red length, gl = green length, bl = blue length
 	 */
 	case FB_VISUAL_TRUECOLOR:
@@ -494,9 +492,9 @@
 
 	/* PLL registers */
 	cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb);
-	cyber2000_grphw(EXT_DCLK_DIV,  hw->clock_div, cfb);
+	cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb);
 	cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb);
-	cyber2000_grphw(EXT_MCLK_DIV,  cfb->mclk_div, cfb);
+	cyber2000_grphw(EXT_MCLK_DIV, cfb->mclk_div, cfb);
 	cyber2000_grphw(0x90, 0x01, cfb);
 	cyber2000_grphw(0xb9, 0x80, cfb);
 	cyber2000_grphw(0xb9, 0x00, cfb);
@@ -515,8 +513,8 @@
 	/*
 	 * Set up accelerator registers
 	 */
-	cyber2000fb_writew(hw->width,     CO_REG_SRC_WIDTH,  cfb);
-	cyber2000fb_writew(hw->width,     CO_REG_DEST_WIDTH, cfb);
+	cyber2000fb_writew(hw->width, CO_REG_SRC_WIDTH, cfb);
+	cyber2000fb_writew(hw->width, CO_REG_DEST_WIDTH, cfb);
 	cyber2000fb_writeb(hw->co_pixfmt, CO_REG_PIXFMT, cfb);
 }
 
@@ -549,15 +547,15 @@
 {
 	u_int Htotal, Hblankend, Hsyncend;
 	u_int Vtotal, Vdispend, Vblankstart, Vblankend, Vsyncstart, Vsyncend;
-#define BIT(v,b1,m,b2) (((v >> b1) & m) << b2)
+#define ENCODE_BIT(v, b1, m, b2) ((((v) >> (b1)) & (m)) << (b2))
 
 	hw->crtc[13] = hw->pitch;
 	hw->crtc[17] = 0xe3;
 	hw->crtc[14] = 0;
 	hw->crtc[8]  = 0;
 
-	Htotal      = var->xres + var->right_margin +
-		      var->hsync_len + var->left_margin;
+	Htotal     = var->xres + var->right_margin +
+		     var->hsync_len + var->left_margin;
 
 	if (Htotal > 2080)
 		return -EINVAL;
@@ -567,15 +565,15 @@
 	hw->crtc[2] = var->xres >> 3;
 	hw->crtc[4] = (var->xres + var->right_margin) >> 3;
 
-	Hblankend   = (Htotal - 4*8) >> 3;
+	Hblankend   = (Htotal - 4 * 8) >> 3;
 
-	hw->crtc[3] = BIT(Hblankend,  0, 0x1f,  0) |
-		      BIT(1,          0, 0x01,  7);
+	hw->crtc[3] = ENCODE_BIT(Hblankend,  0, 0x1f,  0) |
+		      ENCODE_BIT(1,          0, 0x01,  7);
 
 	Hsyncend    = (var->xres + var->right_margin + var->hsync_len) >> 3;
 
-	hw->crtc[5] = BIT(Hsyncend,   0, 0x1f,  0) |
-		      BIT(Hblankend,  5, 0x01,  7);
+	hw->crtc[5] = ENCODE_BIT(Hsyncend,   0, 0x1f,  0) |
+		      ENCODE_BIT(Hblankend,  5, 0x01,  7);
 
 	Vdispend    = var->yres - 1;
 	Vsyncstart  = var->yres + var->lower_margin;
@@ -590,20 +588,20 @@
 	Vblankend   = Vtotal - 10;
 
 	hw->crtc[6]  = Vtotal;
-	hw->crtc[7]  = BIT(Vtotal,     8, 0x01,  0) |
-			BIT(Vdispend,   8, 0x01,  1) |
-			BIT(Vsyncstart, 8, 0x01,  2) |
-			BIT(Vblankstart,8, 0x01,  3) |
-			BIT(1,          0, 0x01,  4) |
-	        	BIT(Vtotal,     9, 0x01,  5) |
-			BIT(Vdispend,   9, 0x01,  6) |
-			BIT(Vsyncstart, 9, 0x01,  7);
-	hw->crtc[9]  = BIT(0,          0, 0x1f,  0) |
-		        BIT(Vblankstart,9, 0x01,  5) |
-			BIT(1,          0, 0x01,  6);
+	hw->crtc[7]  = ENCODE_BIT(Vtotal,     8, 0x01,  0) |
+			ENCODE_BIT(Vdispend,   8, 0x01,  1) |
+			ENCODE_BIT(Vsyncstart, 8, 0x01,  2) |
+			ENCODE_BIT(Vblankstart, 8, 0x01,  3) |
+			ENCODE_BIT(1,          0, 0x01,  4) |
+			ENCODE_BIT(Vtotal,     9, 0x01,  5) |
+			ENCODE_BIT(Vdispend,   9, 0x01,  6) |
+			ENCODE_BIT(Vsyncstart, 9, 0x01,  7);
+	hw->crtc[9]  = ENCODE_BIT(0,          0, 0x1f,  0) |
+			ENCODE_BIT(Vblankstart, 9, 0x01,  5) |
+			ENCODE_BIT(1,          0, 0x01,  6);
 	hw->crtc[10] = Vsyncstart;
-	hw->crtc[11] = BIT(Vsyncend,   0, 0x0f,  0) |
-		       BIT(1,          0, 0x01,  7);
+	hw->crtc[11] = ENCODE_BIT(Vsyncend,   0, 0x0f,  0) |
+		       ENCODE_BIT(1,          0, 0x01,  7);
 	hw->crtc[12] = Vdispend;
 	hw->crtc[15] = Vblankstart;
 	hw->crtc[16] = Vblankend;
@@ -615,10 +613,10 @@
 	 * 4=LINECOMP:10 5-IVIDEO 6=FIXCNT
 	 */
 	hw->crtc_ofl =
-		BIT(Vtotal,     10, 0x01,  0) |
-		BIT(Vdispend,   10, 0x01,  1) |
-		BIT(Vsyncstart, 10, 0x01,  2) |
-		BIT(Vblankstart,10, 0x01,  3) |
+		ENCODE_BIT(Vtotal, 10, 0x01, 0) |
+		ENCODE_BIT(Vdispend, 10, 0x01, 1) |
+		ENCODE_BIT(Vsyncstart, 10, 0x01, 2) |
+		ENCODE_BIT(Vblankstart, 10, 0x01, 3) |
 		EXT_CRT_VRTOFL_LINECOMP10;
 
 	/* woody: set the interlaced bit... */
@@ -750,11 +748,11 @@
 	var->red.msb_right	= 0;
 	var->green.msb_right	= 0;
 	var->blue.msb_right	= 0;
+	var->transp.offset	= 0;
+	var->transp.length	= 0;
 
 	switch (var->bits_per_pixel) {
 	case 8:	/* PSEUDOCOLOUR, 256 */
-		var->transp.offset	= 0;
-		var->transp.length	= 0;
 		var->red.offset		= 0;
 		var->red.length		= 8;
 		var->green.offset	= 0;
@@ -766,8 +764,6 @@
 	case 16:/* DIRECTCOLOUR, 64k or 32k */
 		switch (var->green.length) {
 		case 6: /* RGB565, 64k */
-			var->transp.offset	= 0;
-			var->transp.length	= 0;
 			var->red.offset		= 11;
 			var->red.length		= 5;
 			var->green.offset	= 5;
@@ -778,8 +774,6 @@
 
 		default:
 		case 5: /* RGB555, 32k */
-			var->transp.offset	= 0;
-			var->transp.length	= 0;
 			var->red.offset		= 10;
 			var->red.length		= 5;
 			var->green.offset	= 5;
@@ -802,8 +796,6 @@
 		break;
 
 	case 24:/* TRUECOLOUR, 16m */
-		var->transp.offset	= 0;
-		var->transp.length	= 0;
 		var->red.offset		= 16;
 		var->red.length		= 8;
 		var->green.offset	= 8;
@@ -830,7 +822,7 @@
 	mem = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8);
 	if (mem > cfb->fb.fix.smem_len)
 		var->yres_virtual = cfb->fb.fix.smem_len * 8 /
-			(var->bits_per_pixel * var->xres_virtual);
+				    (var->bits_per_pixel * var->xres_virtual);
 
 	if (var->yres > var->yres_virtual)
 		var->yres = var->yres_virtual;
@@ -921,7 +913,7 @@
 		hw.fetch <<= 1;
 	hw.fetch += 1;
 
-	cfb->fb.fix.line_length	= var->xres_virtual * var->bits_per_pixel / 8;
+	cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
 
 	/*
 	 * Same here - if the size of the video mode exceeds the
@@ -952,7 +944,6 @@
 	return 0;
 }
 
-
 /*
  *    Pan or Wrap the Display
  */
@@ -1002,15 +993,15 @@
 	switch (blank) {
 	case FB_BLANK_POWERDOWN:	/* powerdown - both sync lines down */
 		sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_0;
-		break;	
+		break;
 	case FB_BLANK_HSYNC_SUSPEND:	/* hsync off */
 		sync = EXT_SYNC_CTL_VS_NORMAL | EXT_SYNC_CTL_HS_0;
-		break;	
+		break;
 	case FB_BLANK_VSYNC_SUSPEND:	/* vsync off */
 		sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_NORMAL;
 		break;
-	case FB_BLANK_NORMAL:	        /* soft blank */
-	default: /* unblank */
+	case FB_BLANK_NORMAL:		/* soft blank */
+	default:			/* unblank */
 		break;
 	}
 
@@ -1018,7 +1009,8 @@
 
 	if (blank <= 1) {
 		/* turn on ramdacs */
-		cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
+		cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS |
+					   RAMDAC_RAMPWRDN);
 		cyber2000fb_write_ramdac_ctrl(cfb);
 	}
 
@@ -1043,7 +1035,8 @@
 
 	if (blank >= 2) {
 		/* turn off ramdacs */
-		cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS | RAMDAC_RAMPWRDN;
+		cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS |
+					 RAMDAC_RAMPWRDN;
 		cyber2000fb_write_ramdac_ctrl(cfb);
 	}
 
@@ -1068,7 +1061,7 @@
  * of this driver.  It is here solely at the moment to support the other
  * CyberPro modules external to this driver.
  */
-static struct cfb_info		*int_cfb_info;
+static struct cfb_info *int_cfb_info;
 
 /*
  * Enable access to the extended registers
@@ -1085,6 +1078,7 @@
 		cyber2000_grphw(EXT_FUNC_CTL, old, cfb);
 	}
 }
+EXPORT_SYMBOL(cyber2000fb_enable_extregs);
 
 /*
  * Disable access to the extended registers
@@ -1104,11 +1098,13 @@
 	else
 		cfb->func_use_count -= 1;
 }
+EXPORT_SYMBOL(cyber2000fb_disable_extregs);
 
 void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var)
 {
 	memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo));
 }
+EXPORT_SYMBOL(cyber2000fb_get_fb_var);
 
 /*
  * Attach a capture/tv driver to the core CyberX0X0 driver.
@@ -1122,13 +1118,15 @@
 		info->fb_size	      = int_cfb_info->fb.fix.smem_len;
 		info->enable_extregs  = cyber2000fb_enable_extregs;
 		info->disable_extregs = cyber2000fb_disable_extregs;
-		info->info            = int_cfb_info;
+		info->info	      = int_cfb_info;
 
-		strlcpy(info->dev_name, int_cfb_info->fb.fix.id, sizeof(info->dev_name));
+		strlcpy(info->dev_name, int_cfb_info->fb.fix.id,
+			sizeof(info->dev_name));
 	}
 
 	return int_cfb_info != NULL;
 }
+EXPORT_SYMBOL(cyber2000fb_attach);
 
 /*
  * Detach a capture/tv driver from the core CyberX0X0 driver.
@@ -1136,12 +1134,7 @@
 void cyber2000fb_detach(int idx)
 {
 }
-
-EXPORT_SYMBOL(cyber2000fb_attach);
 EXPORT_SYMBOL(cyber2000fb_detach);
-EXPORT_SYMBOL(cyber2000fb_enable_extregs);
-EXPORT_SYMBOL(cyber2000fb_disable_extregs);
-EXPORT_SYMBOL(cyber2000fb_get_fb_var);
 
 /*
  * These parameters give
@@ -1205,7 +1198,7 @@
 	int i;
 
 	for (i = 0; i < sizeof(igs_regs); i += 2)
-		cyber2000_grphw(igs_regs[i], igs_regs[i+1], cfb);
+		cyber2000_grphw(igs_regs[i], igs_regs[i + 1], cfb);
 
 	if (cfb->id == ID_CYBERPRO_5000) {
 		unsigned char val;
@@ -1215,8 +1208,8 @@
 	}
 }
 
-static struct cfb_info * __devinit
-cyberpro_alloc_fb_info(unsigned int id, char *name)
+static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id,
+							 char *name)
 {
 	struct cfb_info *cfb;
 
@@ -1228,9 +1221,9 @@
 	cfb->id			= id;
 
 	if (id == ID_CYBERPRO_5000)
-		cfb->ref_ps	= 40690; // 24.576 MHz
+		cfb->ref_ps	= 40690; /* 24.576 MHz */
 	else
-		cfb->ref_ps	= 69842; // 14.31818 MHz (69841?)
+		cfb->ref_ps	= 69842; /* 14.31818 MHz (69841?) */
 
 	cfb->divisors[0]	= 1;
 	cfb->divisors[1]	= 2;
@@ -1282,8 +1275,7 @@
 	return cfb;
 }
 
-static void
-cyberpro_free_fb_info(struct cfb_info *cfb)
+static void cyberpro_free_fb_info(struct cfb_info *cfb)
 {
 	if (cfb) {
 		/*
@@ -1300,8 +1292,7 @@
  *  video=cyber2000:font:fontname
  */
 #ifndef MODULE
-static int
-cyber2000fb_setup(char *options)
+static int cyber2000fb_setup(char *options)
 {
 	char *opt;
 
@@ -1315,7 +1306,8 @@
 		if (strncmp(opt, "font:", 5) == 0) {
 			static char default_font_storage[40];
 
-			strlcpy(default_font_storage, opt + 5, sizeof(default_font_storage));
+			strlcpy(default_font_storage, opt + 5,
+				sizeof(default_font_storage));
 			default_font = default_font_storage;
 			continue;
 		}
@@ -1354,10 +1346,18 @@
 	 * Determine the size of the memory.
 	 */
 	switch (cfb->mem_ctl2 & MEM_CTL2_SIZE_MASK) {
-	case MEM_CTL2_SIZE_4MB:	smem_size = 0x00400000; break;
-	case MEM_CTL2_SIZE_2MB:	smem_size = 0x00200000; break;
-	case MEM_CTL2_SIZE_1MB: smem_size = 0x00100000; break;
-	default:		smem_size = 0x00100000; break;
+	case MEM_CTL2_SIZE_4MB:
+		smem_size = 0x00400000;
+		break;
+	case MEM_CTL2_SIZE_2MB:
+		smem_size = 0x00200000;
+		break;
+	case MEM_CTL2_SIZE_1MB:
+		smem_size = 0x00100000;
+		break;
+	default:
+		smem_size = 0x00100000;
+		break;
 	}
 
 	cfb->fb.fix.smem_len   = smem_size;
@@ -1366,8 +1366,8 @@
 
 	err = -EINVAL;
 	if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
-	    		  &cyber2000fb_default_mode, 8)) {
-		printk("%s: no valid mode found\n", cfb->fb.fix.id);
+			  &cyber2000fb_default_mode, 8)) {
+		printk(KERN_ERR "%s: no valid mode found\n", cfb->fb.fix.id);
 		goto failed;
 	}
 
@@ -1377,7 +1377,7 @@
 	if (cfb->fb.var.yres_virtual < cfb->fb.var.yres)
 		cfb->fb.var.yres_virtual = cfb->fb.var.yres;
 
-//	fb_set_var(&cfb->fb.var, -1, &cfb->fb);
+/*	fb_set_var(&cfb->fb.var, -1, &cfb->fb); */
 
 	/*
 	 * Calculate the hsync and vsync frequencies.  Note that
@@ -1425,20 +1425,20 @@
 
 #include <asm/arch/hardware.h>
 
-static int __devinit
-cyberpro_vl_probe(void)
+static int __devinit cyberpro_vl_probe(void)
 {
 	struct cfb_info *cfb;
 	int err = -ENOMEM;
 
-	if (!request_mem_region(FB_START,FB_SIZE,"CyberPro2010")) return err;
+	if (!request_mem_region(FB_START, FB_SIZE, "CyberPro2010"))
+		return err;
 
 	cfb = cyberpro_alloc_fb_info(ID_CYBERPRO_2010, "CyberPro2010");
 	if (!cfb)
 		goto failed_release;
 
 	cfb->dev = NULL;
-	cfb->region = ioremap(FB_START,FB_SIZE);
+	cfb->region = ioremap(FB_START, FB_SIZE);
 	if (!cfb->region)
 		goto failed_ioremap;
 
@@ -1475,7 +1475,7 @@
 failed_ioremap:
 	cyberpro_free_fb_info(cfb);
 failed_release:
-	release_mem_region(FB_START,FB_SIZE);
+	release_mem_region(FB_START, FB_SIZE);
 
 	return err;
 }
@@ -1538,7 +1538,8 @@
 	 * Allow the CyberPro to accept PCI burst accesses
 	 */
 	if (cfb->id == ID_CYBERPRO_2010) {
-		printk(KERN_INFO "%s: NOT enabling PCI bursts\n", cfb->fb.fix.id);
+		printk(KERN_INFO "%s: NOT enabling PCI bursts\n",
+		       cfb->fb.fix.id);
 	} else {
 		val = cyber2000_grphr(EXT_BUS_CTL, cfb);
 		if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) {
@@ -1688,9 +1689,10 @@
 }
 
 static struct pci_device_id cyberpro_pci_table[] = {
-//	Not yet
-//	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
-//		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
+/*	Not yet
+ *	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
+ *		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
+ */
 	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2000 },
 	{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010,
@@ -1700,7 +1702,7 @@
 	{ 0, }
 };
 
-MODULE_DEVICE_TABLE(pci,cyberpro_pci_table);
+MODULE_DEVICE_TABLE(pci, cyberpro_pci_table);
 
 static struct pci_driver cyberpro_driver = {
 	.name		= "CyberPro",
diff --git a/drivers/video/geode/video_gx.c b/drivers/video/geode/video_gx.c
index 7f3f18d..febf09c 100644
--- a/drivers/video/geode/video_gx.c
+++ b/drivers/video/geode/video_gx.c
@@ -127,7 +127,7 @@
 	int timeout = 1000;
 
 	/* Rev. 1 Geode GXs use a 14 MHz reference clock instead of 48 MHz. */
-	if (cpu_data->x86_mask == 1) {
+	if (cpu_data(0).x86_mask == 1) {
 		pll_table = gx_pll_table_14MHz;
 		pll_table_len = ARRAY_SIZE(gx_pll_table_14MHz);
 	} else {
diff --git a/drivers/video/gxt4500.c b/drivers/video/gxt4500.c
index 23a6bcc..e92337b 100644
--- a/drivers/video/gxt4500.c
+++ b/drivers/video/gxt4500.c
@@ -636,7 +636,7 @@
 
 	info = framebuffer_alloc(sizeof(struct gxt4500_par), &pdev->dev);
 	if (!info) {
-		dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record");
+		dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record\n");
 		goto err_free_fb;
 	}
 	par = info->par;
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index e8e38ed..481d58f7 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -4,7 +4,7 @@
  * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
  * 945G/945GM integrated graphics chips.
  *
- * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
+ * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
  *                   2004 Sylvain Meyer
  *                   2006 David Airlie
  *
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 2a0e320..5f6fb7d 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -3,7 +3,7 @@
  *
  * Linux framebuffer driver for Intel(R) 865G integrated graphics chips.
  *
- * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
+ * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
  *                   2004 Sylvain Meyer
  *
  * This driver consists of two parts.  The first part (intelfbdrv.c) provides
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index a9283ba..fc72684 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -78,10 +78,7 @@
 #endif
 #ifdef CONFIG_LOGO_DEC_CLUT224
 		/* DEC Linux logo on MIPS/MIPS64 or ALPHA */
-#ifndef CONFIG_ALPHA
-		if (mips_machgroup == MACH_GROUP_DEC)
-#endif
-			logo = &logo_dec_clut224;
+		logo = &logo_dec_clut224;
 #endif
 #ifdef CONFIG_LOGO_MAC_CLUT224
 		/* Macintosh Linux logo on m68k */
@@ -94,10 +91,7 @@
 #endif
 #ifdef CONFIG_LOGO_SGI_CLUT224
 		/* SGI Linux logo on MIPS/MIPS64 and VISWS */
-#ifndef CONFIG_X86_VISWS
-		if (mips_machgroup == MACH_GROUP_SGI)
-#endif
-			logo = &logo_sgi_clut224;
+		logo = &logo_sgi_clut224;
 #endif
 #ifdef CONFIG_LOGO_SUN_CLUT224
 		/* Sun Linux logo */
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 42f5d76..8d81ef0 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -510,7 +510,9 @@
 	default_bpp = 8;
 
     /* Did the user specify a video mode? */
-    if (mode_option || (mode_option = fb_mode_option)) {
+    if (!mode_option)
+	mode_option = fb_mode_option;
+    if (mode_option) {
 	const char *name = mode_option;
 	unsigned int namelen = strlen(name);
 	int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index 7f4d25b..f4fcf11 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -8,7 +8,7 @@
           Frame buffer driver for OMAP based boards.
 
 config FB_OMAP_BOOTLOADER_INIT
-	bool "Check bootloader initializaion"
+	bool "Check bootloader initialization"
 	depends on FB_OMAP
 	help
 	  Say Y here if you want to enable checking if the bootloader has
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
index e682940..4d8ad9c 100644
--- a/drivers/video/omap/blizzard.c
+++ b/drivers/video/omap/blizzard.c
@@ -225,7 +225,7 @@
 	while (!(blizzard_read_reg(BLIZZARD_MEM_BANK0_STATUS) & 0x01)) {
 		if (time_after(jiffies, tmo)) {
 			dev_err(blizzard.fbdev->dev,
-					"s1d1374x: SDRAM not ready");
+					"s1d1374x: SDRAM not ready\n");
 			break;
 		}
 		msleep(1);
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index f4c2343..ab32ceb 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -880,19 +880,19 @@
 static int get_dss_clocks(void)
 {
 	if (IS_ERR((dispc.dss_ick = clk_get(dispc.fbdev->dev, "dss_ick")))) {
-		dev_err(dispc.fbdev->dev, "can't get dss_ick");
+		dev_err(dispc.fbdev->dev, "can't get dss_ick\n");
 		return PTR_ERR(dispc.dss_ick);
 	}
 
 	if (IS_ERR((dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck")))) {
-		dev_err(dispc.fbdev->dev, "can't get dss1_fck");
+		dev_err(dispc.fbdev->dev, "can't get dss1_fck\n");
 		clk_put(dispc.dss_ick);
 		return PTR_ERR(dispc.dss1_fck);
 	}
 
 	if (IS_ERR((dispc.dss_54m_fck =
 				clk_get(dispc.fbdev->dev, "dss_54m_fck")))) {
-		dev_err(dispc.fbdev->dev, "can't get dss_54m_fck");
+		dev_err(dispc.fbdev->dev, "can't get dss_54m_fck\n");
 		clk_put(dispc.dss_ick);
 		clk_put(dispc.dss1_fck);
 		return PTR_ERR(dispc.dss_54m_fck);
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index dc48e02..1e642b7 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -508,7 +508,7 @@
 	if (unlikely(win->format &
 	    ~(0x03 | OMAPFB_FORMAT_FLAG_DOUBLE |
 	    OMAPFB_FORMAT_FLAG_TEARSYNC | OMAPFB_FORMAT_FLAG_FORCE_VSYNC))) {
-		dev_dbg(hwa742.fbdev->dev, "invalid window flag");
+		dev_dbg(hwa742.fbdev->dev, "invalid window flag\n");
 		r = -EINVAL;
 		goto out;
 	}
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c
index 2b42698..789cfd2 100644
--- a/drivers/video/omap/rfbi.c
+++ b/drivers/video/omap/rfbi.c
@@ -84,12 +84,12 @@
 static int rfbi_get_clocks(void)
 {
 	if (IS_ERR((rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "dss_ick")))) {
-		dev_err(rfbi.fbdev->dev, "can't get dss_ick");
+		dev_err(rfbi.fbdev->dev, "can't get dss_ick\n");
 		return PTR_ERR(rfbi.dss_ick);
 	}
 
 	if (IS_ERR((rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck")))) {
-		dev_err(rfbi.fbdev->dev, "can't get dss1_fck");
+		dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n");
 		clk_put(rfbi.dss_ick);
 		return PTR_ERR(rfbi.dss1_fck);
 	}
diff --git a/drivers/video/pnx4008/sdum.h b/drivers/video/pnx4008/sdum.h
index e8c5dcd..189c3d6 100644
--- a/drivers/video/pnx4008/sdum.h
+++ b/drivers/video/pnx4008/sdum.h
@@ -77,9 +77,6 @@
 #define CONF_DIRTYDETECTION_OFF	(0x600)
 #define CONF_DIRTYDETECTION_ON	(0x601)
 
-/* Set the corresponding bit. */
-#define BIT(n) (0x1U << (n))
-
 struct dumchannel_uf {
 	int channelnr;
 	u32 *dirty;
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index ae08d45..5857ccf 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -56,7 +56,7 @@
  *	- Add support for different devices
  *	- Backlight support
  *
- * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
+ * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
  *	- added clock (de-)allocation code
  *	- added fixem fbmem option
  *
@@ -64,7 +64,7 @@
  *	- code cleanup
  *	- added a forgotten return in h1940fb_init
  *
- * 2004-07-19: Herbert Pötzl <herbert@13thfloor.at>
+ * 2004-07-19: Herbert Pötzl <herbert@13thfloor.at>
  *	- code cleanup and extended debugging
  *
  * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index ff9e805..c31f549 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -23,8 +23,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  * Authors:
- *   Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- *   Michel Dänzer <michel-at-tungstengraphics-dot-com>
+ *   Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ *   Michel Dänzer <michel-at-tungstengraphics-dot-com>
  *   Alan Hourihane <alanh-at-tungstengraphics-dot-com>
  */
 
diff --git a/drivers/video/vermilion/vermilion.h b/drivers/video/vermilion/vermilion.h
index 1fc6695..c4aba59 100644
--- a/drivers/video/vermilion/vermilion.h
+++ b/drivers/video/vermilion/vermilion.h
@@ -23,7 +23,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  * Authors:
- *   Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ *   Thomas Hellström <thomas-at-tungstengraphics-dot-com>
  */
 
 #ifndef _VERMILION_H_
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
new file mode 100644
index 0000000..9e33fc4
--- /dev/null
+++ b/drivers/virtio/Kconfig
@@ -0,0 +1,8 @@
+# Virtio always gets selected by whoever wants it.
+config VIRTIO
+	bool
+
+# Similarly the virtio ring implementation.
+config VIRTIO_RING
+	bool
+	depends on VIRTIO
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
new file mode 100644
index 0000000..f70e409
--- /dev/null
+++ b/drivers/virtio/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_VIRTIO) += virtio.o
+obj-$(CONFIG_VIRTIO_RING) += virtio_ring.o
diff --git a/drivers/virtio/config.c b/drivers/virtio/config.c
new file mode 100644
index 0000000..983d482
--- /dev/null
+++ b/drivers/virtio/config.c
@@ -0,0 +1,13 @@
+/* Configuration space parsing helpers for virtio.
+ *
+ * The configuration is [type][len][... len bytes ...] fields.
+ *
+ * Copyright 2007 Rusty Russell, IBM Corporation.
+ * GPL v2 or later.
+ */
+#include <linux/err.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/bug.h>
+#include <asm/system.h>
+
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
new file mode 100644
index 0000000..15d7787
--- /dev/null
+++ b/drivers/virtio/virtio.c
@@ -0,0 +1,189 @@
+#include <linux/virtio.h>
+#include <linux/spinlock.h>
+#include <linux/virtio_config.h>
+
+static ssize_t device_show(struct device *_d,
+			   struct device_attribute *attr, char *buf)
+{
+	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+	return sprintf(buf, "%hu", dev->id.device);
+}
+static ssize_t vendor_show(struct device *_d,
+			   struct device_attribute *attr, char *buf)
+{
+	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+	return sprintf(buf, "%hu", dev->id.vendor);
+}
+static ssize_t status_show(struct device *_d,
+			   struct device_attribute *attr, char *buf)
+{
+	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+	return sprintf(buf, "0x%08x", dev->config->get_status(dev));
+}
+static ssize_t modalias_show(struct device *_d,
+			     struct device_attribute *attr, char *buf)
+{
+	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+
+	return sprintf(buf, "virtio:d%08Xv%08X\n",
+		       dev->id.device, dev->id.vendor);
+}
+static struct device_attribute virtio_dev_attrs[] = {
+	__ATTR_RO(device),
+	__ATTR_RO(vendor),
+	__ATTR_RO(status),
+	__ATTR_RO(modalias),
+	__ATTR_NULL
+};
+
+static inline int virtio_id_match(const struct virtio_device *dev,
+				  const struct virtio_device_id *id)
+{
+	if (id->device != dev->id.device)
+		return 0;
+
+	return id->vendor == VIRTIO_DEV_ANY_ID || id->vendor != dev->id.vendor;
+}
+
+/* This looks through all the IDs a driver claims to support.  If any of them
+ * match, we return 1 and the kernel will call virtio_dev_probe(). */
+static int virtio_dev_match(struct device *_dv, struct device_driver *_dr)
+{
+	unsigned int i;
+	struct virtio_device *dev = container_of(_dv,struct virtio_device,dev);
+	const struct virtio_device_id *ids;
+
+	ids = container_of(_dr, struct virtio_driver, driver)->id_table;
+	for (i = 0; ids[i].device; i++)
+		if (virtio_id_match(dev, &ids[i]))
+			return 1;
+	return 0;
+}
+
+static int virtio_uevent(struct device *_dv, struct kobj_uevent_env *env)
+{
+	struct virtio_device *dev = container_of(_dv,struct virtio_device,dev);
+
+	return add_uevent_var(env, "MODALIAS=virtio:d%08Xv%08X",
+			      dev->id.device, dev->id.vendor);
+}
+
+static struct bus_type virtio_bus = {
+	.name  = "virtio",
+	.match = virtio_dev_match,
+	.dev_attrs = virtio_dev_attrs,
+	.uevent = virtio_uevent,
+};
+
+static void add_status(struct virtio_device *dev, unsigned status)
+{
+	dev->config->set_status(dev, dev->config->get_status(dev) | status);
+}
+
+static int virtio_dev_probe(struct device *_d)
+{
+	int err;
+	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
+	struct virtio_driver *drv = container_of(dev->dev.driver,
+						 struct virtio_driver, driver);
+
+	add_status(dev, VIRTIO_CONFIG_S_DRIVER);
+	err = drv->probe(dev);
+	if (err)
+		add_status(dev, VIRTIO_CONFIG_S_FAILED);
+	else
+		add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
+	return err;
+}
+
+int register_virtio_driver(struct virtio_driver *driver)
+{
+	driver->driver.bus = &virtio_bus;
+	driver->driver.probe = virtio_dev_probe;
+	return driver_register(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(register_virtio_driver);
+
+void unregister_virtio_driver(struct virtio_driver *driver)
+{
+	driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(unregister_virtio_driver);
+
+int register_virtio_device(struct virtio_device *dev)
+{
+	int err;
+
+	dev->dev.bus = &virtio_bus;
+	sprintf(dev->dev.bus_id, "%u", dev->index);
+
+	/* Acknowledge that we've seen the device. */
+	add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
+
+	/* device_register() causes the bus infrastructure to look for a
+	 * matching driver. */
+	err = device_register(&dev->dev);
+	if (err)
+		add_status(dev, VIRTIO_CONFIG_S_FAILED);
+	return err;
+}
+EXPORT_SYMBOL_GPL(register_virtio_device);
+
+void unregister_virtio_device(struct virtio_device *dev)
+{
+	device_unregister(&dev->dev);
+}
+EXPORT_SYMBOL_GPL(unregister_virtio_device);
+
+int __virtio_config_val(struct virtio_device *vdev,
+			u8 type, void *val, size_t size)
+{
+	void *token;
+	unsigned int len;
+
+	token = vdev->config->find(vdev, type, &len);
+	if (!token)
+		return -ENOENT;
+
+	if (len != size)
+		return -EIO;
+
+	vdev->config->get(vdev, token, val, size);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__virtio_config_val);
+
+int virtio_use_bit(struct virtio_device *vdev,
+		   void *token, unsigned int len, unsigned int bitnum)
+{
+	unsigned long bits[16];
+
+	/* This makes it convenient to pass-through find() results. */
+	if (!token)
+		return 0;
+
+	/* bit not in range of this bitfield? */
+	if (bitnum * 8 >= len / 2)
+		return 0;
+
+	/* Giant feature bitfields are silly. */
+	BUG_ON(len > sizeof(bits));
+	vdev->config->get(vdev, token, bits, len);
+
+	if (!test_bit(bitnum, bits))
+		return 0;
+
+	/* Set acknowledge bit, and write it back. */
+	set_bit(bitnum + len * 8 / 2, bits);
+	vdev->config->set(vdev, token, bits, len);
+	return 1;
+}
+EXPORT_SYMBOL_GPL(virtio_use_bit);
+
+static int virtio_init(void)
+{
+	if (bus_register(&virtio_bus) != 0)
+		panic("virtio bus registration failed");
+	return 0;
+}
+core_initcall(virtio_init);
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
new file mode 100644
index 0000000..0e4baca
--- /dev/null
+++ b/drivers/virtio/virtio_ring.c
@@ -0,0 +1,313 @@
+/* Virtio ring implementation.
+ *
+ *  Copyright 2007 Rusty Russell IBM 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/virtio.h>
+#include <linux/virtio_ring.h>
+#include <linux/device.h>
+
+#ifdef DEBUG
+/* For development, we want to crash whenever the ring is screwed. */
+#define BAD_RING(vq, fmt...)			\
+	do { dev_err(&vq->vq.vdev->dev, fmt); BUG(); } while(0)
+#define START_USE(vq) \
+	do { if ((vq)->in_use) panic("in_use = %i\n", (vq)->in_use); (vq)->in_use = __LINE__; mb(); } while(0)
+#define END_USE(vq) \
+	do { BUG_ON(!(vq)->in_use); (vq)->in_use = 0; mb(); } while(0)
+#else
+#define BAD_RING(vq, fmt...)			\
+	do { dev_err(&vq->vq.vdev->dev, fmt); (vq)->broken = true; } while(0)
+#define START_USE(vq)
+#define END_USE(vq)
+#endif
+
+struct vring_virtqueue
+{
+	struct virtqueue vq;
+
+	/* Actual memory layout for this queue */
+	struct vring vring;
+
+	/* Other side has made a mess, don't try any more. */
+	bool broken;
+
+	/* Number of free buffers */
+	unsigned int num_free;
+	/* Head of free buffer list. */
+	unsigned int free_head;
+	/* Number we've added since last sync. */
+	unsigned int num_added;
+
+	/* Last used index we've seen. */
+	unsigned int last_used_idx;
+
+	/* How to notify other side. FIXME: commonalize hcalls! */
+	void (*notify)(struct virtqueue *vq);
+
+#ifdef DEBUG
+	/* They're supposed to lock for us. */
+	unsigned int in_use;
+#endif
+
+	/* Tokens for callbacks. */
+	void *data[];
+};
+
+#define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
+
+static int vring_add_buf(struct virtqueue *_vq,
+			 struct scatterlist sg[],
+			 unsigned int out,
+			 unsigned int in,
+			 void *data)
+{
+	struct vring_virtqueue *vq = to_vvq(_vq);
+	unsigned int i, avail, head, uninitialized_var(prev);
+
+	BUG_ON(data == NULL);
+	BUG_ON(out + in > vq->vring.num);
+	BUG_ON(out + in == 0);
+
+	START_USE(vq);
+
+	if (vq->num_free < out + in) {
+		pr_debug("Can't add buf len %i - avail = %i\n",
+			 out + in, vq->num_free);
+		END_USE(vq);
+		return -ENOSPC;
+	}
+
+	/* We're about to use some buffers from the free list. */
+	vq->num_free -= out + in;
+
+	head = vq->free_head;
+	for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) {
+		vq->vring.desc[i].flags = VRING_DESC_F_NEXT;
+		vq->vring.desc[i].addr = (page_to_pfn(sg_page(sg))<<PAGE_SHIFT)
+			+ sg->offset;
+		vq->vring.desc[i].len = sg->length;
+		prev = i;
+		sg++;
+	}
+	for (; in; i = vq->vring.desc[i].next, in--) {
+		vq->vring.desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
+		vq->vring.desc[i].addr = (page_to_pfn(sg_page(sg))<<PAGE_SHIFT)
+			+ sg->offset;
+		vq->vring.desc[i].len = sg->length;
+		prev = i;
+		sg++;
+	}
+	/* Last one doesn't continue. */
+	vq->vring.desc[prev].flags &= ~VRING_DESC_F_NEXT;
+
+	/* Update free pointer */
+	vq->free_head = i;
+
+	/* Set token. */
+	vq->data[head] = data;
+
+	/* Put entry in available array (but don't update avail->idx until they
+	 * do sync).  FIXME: avoid modulus here? */
+	avail = (vq->vring.avail->idx + vq->num_added++) % vq->vring.num;
+	vq->vring.avail->ring[avail] = head;
+
+	pr_debug("Added buffer head %i to %p\n", head, vq);
+	END_USE(vq);
+	return 0;
+}
+
+static void vring_kick(struct virtqueue *_vq)
+{
+	struct vring_virtqueue *vq = to_vvq(_vq);
+	START_USE(vq);
+	/* Descriptors and available array need to be set before we expose the
+	 * new available array entries. */
+	wmb();
+
+	vq->vring.avail->idx += vq->num_added;
+	vq->num_added = 0;
+
+	/* Need to update avail index before checking if we should notify */
+	mb();
+
+	if (!(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY))
+		/* Prod other side to tell it about changes. */
+		vq->notify(&vq->vq);
+
+	END_USE(vq);
+}
+
+static void detach_buf(struct vring_virtqueue *vq, unsigned int head)
+{
+	unsigned int i;
+
+	/* Clear data ptr. */
+	vq->data[head] = NULL;
+
+	/* Put back on free list: find end */
+	i = head;
+	while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) {
+		i = vq->vring.desc[i].next;
+		vq->num_free++;
+	}
+
+	vq->vring.desc[i].next = vq->free_head;
+	vq->free_head = head;
+	/* Plus final descriptor */
+	vq->num_free++;
+}
+
+/* FIXME: We need to tell other side about removal, to synchronize. */
+static void vring_shutdown(struct virtqueue *_vq)
+{
+	struct vring_virtqueue *vq = to_vvq(_vq);
+	unsigned int i;
+
+	for (i = 0; i < vq->vring.num; i++)
+		detach_buf(vq, i);
+}
+
+static inline bool more_used(const struct vring_virtqueue *vq)
+{
+	return vq->last_used_idx != vq->vring.used->idx;
+}
+
+static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len)
+{
+	struct vring_virtqueue *vq = to_vvq(_vq);
+	void *ret;
+	unsigned int i;
+
+	START_USE(vq);
+
+	if (!more_used(vq)) {
+		pr_debug("No more buffers in queue\n");
+		END_USE(vq);
+		return NULL;
+	}
+
+	i = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].id;
+	*len = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].len;
+
+	if (unlikely(i >= vq->vring.num)) {
+		BAD_RING(vq, "id %u out of range\n", i);
+		return NULL;
+	}
+	if (unlikely(!vq->data[i])) {
+		BAD_RING(vq, "id %u is not a head!\n", i);
+		return NULL;
+	}
+
+	/* detach_buf clears data, so grab it now. */
+	ret = vq->data[i];
+	detach_buf(vq, i);
+	vq->last_used_idx++;
+	END_USE(vq);
+	return ret;
+}
+
+static bool vring_restart(struct virtqueue *_vq)
+{
+	struct vring_virtqueue *vq = to_vvq(_vq);
+
+	START_USE(vq);
+	BUG_ON(!(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT));
+
+	/* We optimistically turn back on interrupts, then check if there was
+	 * more to do. */
+	vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
+	mb();
+	if (unlikely(more_used(vq))) {
+		vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+		END_USE(vq);
+		return false;
+	}
+
+	END_USE(vq);
+	return true;
+}
+
+irqreturn_t vring_interrupt(int irq, void *_vq)
+{
+	struct vring_virtqueue *vq = to_vvq(_vq);
+
+	if (!more_used(vq)) {
+		pr_debug("virtqueue interrupt with no work for %p\n", vq);
+		return IRQ_NONE;
+	}
+
+	if (unlikely(vq->broken))
+		return IRQ_HANDLED;
+
+	pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback);
+	if (vq->vq.callback && !vq->vq.callback(&vq->vq))
+		vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+
+	return IRQ_HANDLED;
+}
+
+static struct virtqueue_ops vring_vq_ops = {
+	.add_buf = vring_add_buf,
+	.get_buf = vring_get_buf,
+	.kick = vring_kick,
+	.restart = vring_restart,
+	.shutdown = vring_shutdown,
+};
+
+struct virtqueue *vring_new_virtqueue(unsigned int num,
+				      struct virtio_device *vdev,
+				      void *pages,
+				      void (*notify)(struct virtqueue *),
+				      bool (*callback)(struct virtqueue *))
+{
+	struct vring_virtqueue *vq;
+	unsigned int i;
+
+	vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL);
+	if (!vq)
+		return NULL;
+
+	vring_init(&vq->vring, num, pages);
+	vq->vq.callback = callback;
+	vq->vq.vdev = vdev;
+	vq->vq.vq_ops = &vring_vq_ops;
+	vq->notify = notify;
+	vq->broken = false;
+	vq->last_used_idx = 0;
+	vq->num_added = 0;
+#ifdef DEBUG
+	vq->in_use = false;
+#endif
+
+	/* No callback?  Tell other side not to bother us. */
+	if (!callback)
+		vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+
+	/* Put everything in free lists. */
+	vq->num_free = num;
+	vq->free_head = 0;
+	for (i = 0; i < num-1; i++)
+		vq->vring.desc[i].next = i+1;
+
+	return &vq->vq;
+}
+
+void vring_del_virtqueue(struct virtqueue *vq)
+{
+	kfree(to_vvq(vq));
+}
+
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 4b69664..5747997 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -307,7 +307,7 @@
 		rom_id |= (unsigned long long) r << (i * 4);
 
 	}
-	dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX", rom_id);
+	dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX\n", rom_id);
 
 	ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA);
 	ds1wm_reset(ds1wm_data);
diff --git a/drivers/char/watchdog/Kconfig b/drivers/watchdog/Kconfig
similarity index 98%
rename from drivers/char/watchdog/Kconfig
rename to drivers/watchdog/Kconfig
index 37bddc1..81db48f 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -343,11 +343,12 @@
 	  module will be called ibmasr.
 
 config WAFER_WDT
-	tristate "ICP Wafer 5823 Single Board Computer Watchdog"
+	tristate "ICP Single Board Computer Watchdog Timer"
 	depends on X86
 	help
-	  This is a driver for the hardware watchdog on the ICP Wafer 5823
-	  Single Board Computer (and probably other similar models).
+	  This is a driver for the hardware watchdog on the ICP Single
+	  Board Computer. This driver is working on (at least) the following
+	  IPC SBC's: Wafer 5823, Rocky 4783, Rocky 3703 and Rocky 3782.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called wafer5823wdt.
@@ -609,6 +610,12 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called rm9k_wdt.
 
+config AR7_WDT
+	tristate "TI AR7 Watchdog Timer"
+	depends on AR7
+	help
+	  Hardware driver for the TI AR7 Watchdog Timer.
+
 # PARISC Architecture
 
 # POWERPC Architecture
diff --git a/drivers/char/watchdog/Makefile b/drivers/watchdog/Makefile
similarity index 98%
rename from drivers/char/watchdog/Makefile
rename to drivers/watchdog/Makefile
index 389f8b1..7d9e573 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -90,6 +90,7 @@
 obj-$(CONFIG_INDYDOG) += indydog.o
 obj-$(CONFIG_WDT_MTX1)	+= mtx-1_wdt.o
 obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
+obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
 
 # PARISC Architecture
 
diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c
similarity index 100%
rename from drivers/char/watchdog/acquirewdt.c
rename to drivers/watchdog/acquirewdt.c
diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c
similarity index 100%
rename from drivers/char/watchdog/advantechwdt.c
rename to drivers/watchdog/advantechwdt.c
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c
similarity index 100%
rename from drivers/char/watchdog/alim1535_wdt.c
rename to drivers/watchdog/alim1535_wdt.c
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
similarity index 100%
rename from drivers/char/watchdog/alim7101_wdt.c
rename to drivers/watchdog/alim7101_wdt.c
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
new file mode 100644
index 0000000..cdaab8c
--- /dev/null
+++ b/drivers/watchdog/ar7_wdt.c
@@ -0,0 +1,349 @@
+/*
+ * drivers/watchdog/ar7_wdt.c
+ *
+ * Copyright (C) 2007 Nicolas Thill <nico@openwrt.org>
+ * Copyright (c) 2005 Enrik Berkhan <Enrik.Berkhan@akk.org>
+ *
+ * Some code taken from:
+ * National Semiconductor SCx200 Watchdog support
+ * Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <asm/addrspace.h>
+#include <asm/ar7/ar7.h>
+
+#define DRVNAME "ar7_wdt"
+#define LONGNAME "TI AR7 Watchdog Timer"
+
+MODULE_AUTHOR("Nicolas Thill <nico@openwrt.org>");
+MODULE_DESCRIPTION(LONGNAME);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+
+static int margin = 60;
+module_param(margin, int, 0);
+MODULE_PARM_DESC(margin, "Watchdog margin in seconds");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
+
+#define READ_REG(x) readl((void __iomem *)&(x))
+#define WRITE_REG(x, v) writel((v), (void __iomem *)&(x))
+
+struct ar7_wdt {
+	u32 kick_lock;
+	u32 kick;
+	u32 change_lock;
+	u32 change;
+	u32 disable_lock;
+	u32 disable;
+	u32 prescale_lock;
+	u32 prescale;
+};
+
+static struct semaphore open_semaphore;
+static unsigned expect_close;
+
+/* XXX currently fixed, allows max margin ~68.72 secs */
+#define prescale_value 0xffff
+
+/* Offset of the WDT registers */
+static unsigned long ar7_regs_wdt;
+/* Pointer to the remapped WDT IO space */
+static struct ar7_wdt *ar7_wdt;
+static void ar7_wdt_get_regs(void)
+{
+	u16 chip_id = ar7_chip_id();
+	switch (chip_id) {
+	case AR7_CHIP_7100:
+	case AR7_CHIP_7200:
+		ar7_regs_wdt = AR7_REGS_WDT;
+		break;
+	default:
+		ar7_regs_wdt = UR8_REGS_WDT;
+		break;
+	}
+}
+
+
+static void ar7_wdt_kick(u32 value)
+{
+	WRITE_REG(ar7_wdt->kick_lock, 0x5555);
+	if ((READ_REG(ar7_wdt->kick_lock) & 3) == 1) {
+		WRITE_REG(ar7_wdt->kick_lock, 0xaaaa);
+		if ((READ_REG(ar7_wdt->kick_lock) & 3) == 3) {
+			WRITE_REG(ar7_wdt->kick, value);
+			return;
+		}
+	}
+	printk(KERN_ERR DRVNAME ": failed to unlock WDT kick reg\n");
+}
+
+static void ar7_wdt_prescale(u32 value)
+{
+	WRITE_REG(ar7_wdt->prescale_lock, 0x5a5a);
+	if ((READ_REG(ar7_wdt->prescale_lock) & 3) == 1) {
+		WRITE_REG(ar7_wdt->prescale_lock, 0xa5a5);
+		if ((READ_REG(ar7_wdt->prescale_lock) & 3) == 3) {
+			WRITE_REG(ar7_wdt->prescale, value);
+			return;
+		}
+	}
+	printk(KERN_ERR DRVNAME ": failed to unlock WDT prescale reg\n");
+}
+
+static void ar7_wdt_change(u32 value)
+{
+	WRITE_REG(ar7_wdt->change_lock, 0x6666);
+	if ((READ_REG(ar7_wdt->change_lock) & 3) == 1) {
+		WRITE_REG(ar7_wdt->change_lock, 0xbbbb);
+		if ((READ_REG(ar7_wdt->change_lock) & 3) == 3) {
+			WRITE_REG(ar7_wdt->change, value);
+			return;
+		}
+	}
+	printk(KERN_ERR DRVNAME ": failed to unlock WDT change reg\n");
+}
+
+static void ar7_wdt_disable(u32 value)
+{
+	WRITE_REG(ar7_wdt->disable_lock, 0x7777);
+	if ((READ_REG(ar7_wdt->disable_lock) & 3) == 1) {
+		WRITE_REG(ar7_wdt->disable_lock, 0xcccc);
+		if ((READ_REG(ar7_wdt->disable_lock) & 3) == 2) {
+			WRITE_REG(ar7_wdt->disable_lock, 0xdddd);
+			if ((READ_REG(ar7_wdt->disable_lock) & 3) == 3) {
+				WRITE_REG(ar7_wdt->disable, value);
+				return;
+			}
+		}
+	}
+	printk(KERN_ERR DRVNAME ": failed to unlock WDT disable reg\n");
+}
+
+static void ar7_wdt_update_margin(int new_margin)
+{
+	u32 change;
+
+	change = new_margin * (ar7_vbus_freq() / prescale_value);
+	if (change < 1) change = 1;
+	if (change > 0xffff) change = 0xffff;
+	ar7_wdt_change(change);
+	margin = change * prescale_value / ar7_vbus_freq();
+	printk(KERN_INFO DRVNAME
+	       ": timer margin %d seconds (prescale %d, change %d, freq %d)\n",
+	       margin, prescale_value, change, ar7_vbus_freq());
+}
+
+static void ar7_wdt_enable_wdt(void)
+{
+	printk(KERN_DEBUG DRVNAME ": enabling watchdog timer\n");
+	ar7_wdt_disable(1);
+	ar7_wdt_kick(1);
+}
+
+static void ar7_wdt_disable_wdt(void)
+{
+	printk(KERN_DEBUG DRVNAME ": disabling watchdog timer\n");
+	ar7_wdt_disable(0);
+}
+
+static int ar7_wdt_open(struct inode *inode, struct file *file)
+{
+	/* only allow one at a time */
+	if (down_trylock(&open_semaphore))
+		return -EBUSY;
+	ar7_wdt_enable_wdt();
+	expect_close = 0;
+
+	return nonseekable_open(inode, file);
+}
+
+static int ar7_wdt_release(struct inode *inode, struct file *file)
+{
+	if (!expect_close)
+		printk(KERN_WARNING DRVNAME
+		": watchdog device closed unexpectedly,"
+		"will not disable the watchdog timer\n");
+	else if (!nowayout)
+		ar7_wdt_disable_wdt();
+
+	up(&open_semaphore);
+
+	return 0;
+}
+
+static int ar7_wdt_notify_sys(struct notifier_block *this,
+			      unsigned long code, void *unused)
+{
+	if (code == SYS_HALT || code == SYS_POWER_OFF)
+		if (!nowayout)
+			ar7_wdt_disable_wdt();
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block ar7_wdt_notifier = {
+	.notifier_call = ar7_wdt_notify_sys
+};
+
+static ssize_t ar7_wdt_write(struct file *file, const char *data,
+			     size_t len, loff_t *ppos)
+{
+	/* check for a magic close character */
+	if (len) {
+		size_t i;
+
+		ar7_wdt_kick(1);
+
+		expect_close = 0;
+		for (i = 0; i < len; ++i) {
+			char c;
+			if (get_user(c, data+i))
+				return -EFAULT;
+			if (c == 'V')
+				expect_close = 1;
+		}
+
+	}
+	return len;
+}
+
+static int ar7_wdt_ioctl(struct inode *inode, struct file *file,
+			 unsigned int cmd, unsigned long arg)
+{
+	static struct watchdog_info ident = {
+		.identity = LONGNAME,
+		.firmware_version = 1,
+		.options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING),
+	};
+	int new_margin;
+
+	switch (cmd) {
+	default:
+		return -ENOTTY;
+	case WDIOC_GETSUPPORT:
+		if (copy_to_user((struct watchdog_info *)arg, &ident,
+				sizeof(ident)))
+			return -EFAULT;
+		return 0;
+	case WDIOC_GETSTATUS:
+	case WDIOC_GETBOOTSTATUS:
+		if (put_user(0, (int *)arg))
+			return -EFAULT;
+		return 0;
+	case WDIOC_KEEPALIVE:
+		ar7_wdt_kick(1);
+		return 0;
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_margin, (int *)arg))
+			return -EFAULT;
+		if (new_margin < 1)
+			return -EINVAL;
+
+		ar7_wdt_update_margin(new_margin);
+		ar7_wdt_kick(1);
+
+	case WDIOC_GETTIMEOUT:
+		if (put_user(margin, (int *)arg))
+			return -EFAULT;
+		return 0;
+	}
+}
+
+static struct file_operations ar7_wdt_fops = {
+	.owner		= THIS_MODULE,
+	.write		= ar7_wdt_write,
+	.ioctl		= ar7_wdt_ioctl,
+	.open		= ar7_wdt_open,
+	.release	= ar7_wdt_release,
+};
+
+static struct miscdevice ar7_wdt_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &ar7_wdt_fops,
+};
+
+static int __init ar7_wdt_init(void)
+{
+	int rc;
+
+	ar7_wdt_get_regs();
+
+	if (!request_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt),
+							LONGNAME)) {
+		printk(KERN_WARNING DRVNAME ": watchdog I/O region busy\n");
+		return -EBUSY;
+	}
+
+	ar7_wdt = (struct ar7_wdt *)
+			ioremap(ar7_regs_wdt, sizeof(struct ar7_wdt));
+
+	ar7_wdt_disable_wdt();
+	ar7_wdt_prescale(prescale_value);
+	ar7_wdt_update_margin(margin);
+
+	sema_init(&open_semaphore, 1);
+
+	rc = register_reboot_notifier(&ar7_wdt_notifier);
+	if (rc) {
+		printk(KERN_ERR DRVNAME
+			": unable to register reboot notifier\n");
+		goto out_alloc;
+	}
+
+	rc = misc_register(&ar7_wdt_miscdev);
+	if (rc) {
+		printk(KERN_ERR DRVNAME ": unable to register misc device\n");
+		goto out_register;
+	}
+	goto out;
+
+out_register:
+	unregister_reboot_notifier(&ar7_wdt_notifier);
+out_alloc:
+	iounmap(ar7_wdt);
+	release_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt));
+out:
+	return rc;
+}
+
+static void __exit ar7_wdt_cleanup(void)
+{
+	misc_deregister(&ar7_wdt_miscdev);
+	unregister_reboot_notifier(&ar7_wdt_notifier);
+	iounmap(ar7_wdt);
+	release_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt));
+}
+
+module_init(ar7_wdt_init);
+module_exit(ar7_wdt_cleanup);
diff --git a/drivers/char/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
similarity index 100%
rename from drivers/char/watchdog/at32ap700x_wdt.c
rename to drivers/watchdog/at32ap700x_wdt.c
diff --git a/drivers/char/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
similarity index 99%
rename from drivers/char/watchdog/at91rm9200_wdt.c
rename to drivers/watchdog/at91rm9200_wdt.c
index 38bd373..a684b1e 100644
--- a/drivers/char/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/init.h>
@@ -19,7 +20,6 @@
 #include <linux/platform_device.h>
 #include <linux/types.h>
 #include <linux/watchdog.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 #include <asm/arch/at91_st.h>
 
diff --git a/drivers/char/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
similarity index 100%
rename from drivers/char/watchdog/bfin_wdt.c
rename to drivers/watchdog/bfin_wdt.c
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
similarity index 100%
rename from drivers/char/watchdog/booke_wdt.c
rename to drivers/watchdog/booke_wdt.c
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c
similarity index 100%
rename from drivers/char/watchdog/cpu5wdt.c
rename to drivers/watchdog/cpu5wdt.c
diff --git a/drivers/char/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
similarity index 100%
rename from drivers/char/watchdog/davinci_wdt.c
rename to drivers/watchdog/davinci_wdt.c
diff --git a/drivers/char/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
similarity index 100%
rename from drivers/char/watchdog/ep93xx_wdt.c
rename to drivers/watchdog/ep93xx_wdt.c
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
similarity index 100%
rename from drivers/char/watchdog/eurotechwdt.c
rename to drivers/watchdog/eurotechwdt.c
diff --git a/drivers/char/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
similarity index 98%
rename from drivers/char/watchdog/i6300esb.c
rename to drivers/watchdog/i6300esb.c
index c598250..f236954 100644
--- a/drivers/char/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -2,7 +2,7 @@
  *	i6300esb:	Watchdog timer driver for Intel 6300ESB chipset
  *
  *	(c) Copyright 2004 Google Inc.
- *	(c) Copyright 2005 David Härdeman <david@2gen.com>
+ *	(c) Copyright 2005 David Härdeman <david@2gen.com>
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -19,7 +19,7 @@
  *	Initial version 0.01
  *  2004YYZZ Ross Biro
  *  	Version 0.02
- *  20050210 David Härdeman <david@2gen.com>
+ *  20050210 David Härdeman <david@2gen.com>
  *      Ported driver to kernel 2.6
  */
 
@@ -521,7 +521,7 @@
 module_init(watchdog_init);
 module_exit(watchdog_cleanup);
 
-MODULE_AUTHOR("Ross Biro and David Härdeman");
+MODULE_AUTHOR("Ross Biro and David Härdeman");
 MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c
similarity index 98%
rename from drivers/char/watchdog/iTCO_vendor_support.c
rename to drivers/watchdog/iTCO_vendor_support.c
index 4150839..cafc465 100644
--- a/drivers/char/watchdog/iTCO_vendor_support.c
+++ b/drivers/watchdog/iTCO_vendor_support.c
@@ -115,7 +115,7 @@
  *	  For P4DPx:
  *	  BIOS setup -> Advanced -> I/O Device Configuration -> Watch Dog
  *	 This setting enables or disables Watchdog function. When enabled, the
- *	 default watchdog timer is set to be 5 minutes (about 4’35”). It is
+ *	 default watchdog timer is set to be 5 minutes (about 4m35s). It is
  *	 enough to load and run the OS. The application (service or driver) has
  *	 to take over the control once OS is running up and before watchdog
  *	 expires.
diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
similarity index 100%
rename from drivers/char/watchdog/iTCO_wdt.c
rename to drivers/watchdog/iTCO_wdt.c
diff --git a/drivers/char/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c
similarity index 100%
rename from drivers/char/watchdog/ib700wdt.c
rename to drivers/watchdog/ib700wdt.c
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c
similarity index 100%
rename from drivers/char/watchdog/ibmasr.c
rename to drivers/watchdog/ibmasr.c
diff --git a/drivers/char/watchdog/indydog.c b/drivers/watchdog/indydog.c
similarity index 100%
rename from drivers/char/watchdog/indydog.c
rename to drivers/watchdog/indydog.c
diff --git a/drivers/char/watchdog/iop_wdt.c b/drivers/watchdog/iop_wdt.c
similarity index 100%
rename from drivers/char/watchdog/iop_wdt.c
rename to drivers/watchdog/iop_wdt.c
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c
similarity index 100%
rename from drivers/char/watchdog/ixp2000_wdt.c
rename to drivers/watchdog/ixp2000_wdt.c
diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c
similarity index 100%
rename from drivers/char/watchdog/ixp4xx_wdt.c
rename to drivers/watchdog/ixp4xx_wdt.c
diff --git a/drivers/char/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
similarity index 99%
rename from drivers/char/watchdog/ks8695_wdt.c
rename to drivers/watchdog/ks8695_wdt.c
index 7150fb9..e3a29c3 100644
--- a/drivers/char/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/init.h>
@@ -18,7 +19,6 @@
 #include <linux/platform_device.h>
 #include <linux/types.h>
 #include <linux/watchdog.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/arch/regs-timer.h>
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/watchdog/machzwd.c
similarity index 100%
rename from drivers/char/watchdog/machzwd.c
rename to drivers/watchdog/machzwd.c
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c
similarity index 100%
rename from drivers/char/watchdog/mixcomwd.c
rename to drivers/watchdog/mixcomwd.c
diff --git a/drivers/char/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c
similarity index 98%
rename from drivers/char/watchdog/mpc5200_wdt.c
rename to drivers/watchdog/mpc5200_wdt.c
index 9cfb975..11f6a11 100644
--- a/drivers/char/watchdog/mpc5200_wdt.c
+++ b/drivers/watchdog/mpc5200_wdt.c
@@ -176,6 +176,8 @@
 
 	has_wdt = of_get_property(op->node, "has-wdt", NULL);
 	if (!has_wdt)
+		has_wdt = of_get_property(op->node, "fsl,has-wdt", NULL);
+	if (!has_wdt)
 		return -ENODEV;
 
 	wdt = kzalloc(sizeof(*wdt), GFP_KERNEL);
@@ -254,6 +256,7 @@
 
 static struct of_device_id mpc5200_wdt_match[] = {
 	{ .compatible = "mpc5200-gpt", },
+	{ .compatible = "fsl,mpc5200-gpt", },
 	{},
 };
 static struct of_platform_driver mpc5200_wdt_driver = {
diff --git a/drivers/char/watchdog/mpc83xx_wdt.c b/drivers/watchdog/mpc83xx_wdt.c
similarity index 100%
rename from drivers/char/watchdog/mpc83xx_wdt.c
rename to drivers/watchdog/mpc83xx_wdt.c
diff --git a/drivers/char/watchdog/mpc8xx_wdt.c b/drivers/watchdog/mpc8xx_wdt.c
similarity index 100%
rename from drivers/char/watchdog/mpc8xx_wdt.c
rename to drivers/watchdog/mpc8xx_wdt.c
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
similarity index 100%
rename from drivers/char/watchdog/mpcore_wdt.c
rename to drivers/watchdog/mpcore_wdt.c
diff --git a/drivers/char/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
similarity index 100%
rename from drivers/char/watchdog/mtx-1_wdt.c
rename to drivers/watchdog/mtx-1_wdt.c
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c
similarity index 100%
rename from drivers/char/watchdog/mv64x60_wdt.c
rename to drivers/watchdog/mv64x60_wdt.c
diff --git a/drivers/char/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
similarity index 99%
rename from drivers/char/watchdog/omap_wdt.c
rename to drivers/watchdog/omap_wdt.c
index 719b066..635ca45 100644
--- a/drivers/char/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -39,11 +39,11 @@
 #include <linux/platform_device.h>
 #include <linux/moduleparam.h>
 #include <linux/clk.h>
+#include <linux/bitops.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/hardware.h>
-#include <asm/bitops.h>
 
 #include <asm/arch/prcm.h>
 
diff --git a/drivers/char/watchdog/omap_wdt.h b/drivers/watchdog/omap_wdt.h
similarity index 100%
rename from drivers/char/watchdog/omap_wdt.h
rename to drivers/watchdog/omap_wdt.h
diff --git a/drivers/char/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c
similarity index 100%
rename from drivers/char/watchdog/pc87413_wdt.c
rename to drivers/watchdog/pc87413_wdt.c
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/watchdog/pcwd.c
similarity index 100%
rename from drivers/char/watchdog/pcwd.c
rename to drivers/watchdog/pcwd.c
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
similarity index 100%
rename from drivers/char/watchdog/pcwd_pci.c
rename to drivers/watchdog/pcwd_pci.c
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
similarity index 100%
rename from drivers/char/watchdog/pcwd_usb.c
rename to drivers/watchdog/pcwd_usb.c
diff --git a/drivers/char/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
similarity index 100%
rename from drivers/char/watchdog/pnx4008_wdt.c
rename to drivers/watchdog/pnx4008_wdt.c
diff --git a/drivers/char/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c
similarity index 100%
rename from drivers/char/watchdog/rm9k_wdt.c
rename to drivers/watchdog/rm9k_wdt.c
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
similarity index 100%
rename from drivers/char/watchdog/s3c2410_wdt.c
rename to drivers/watchdog/s3c2410_wdt.c
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c
similarity index 99%
rename from drivers/char/watchdog/sa1100_wdt.c
rename to drivers/watchdog/sa1100_wdt.c
index 3475f47..34a2b3b 100644
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/watchdog/sa1100_wdt.c
@@ -25,13 +25,13 @@
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
+#include <linux/bitops.h>
 
 #ifdef CONFIG_ARCH_PXA
 #include <asm/arch/pxa-regs.h>
 #endif
 
 #include <asm/hardware.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 
 #define OSCR_FREQ		CLOCK_TICK_RATE
diff --git a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c
similarity index 100%
rename from drivers/char/watchdog/sbc60xxwdt.c
rename to drivers/watchdog/sbc60xxwdt.c
diff --git a/drivers/char/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c
similarity index 100%
rename from drivers/char/watchdog/sbc8360.c
rename to drivers/watchdog/sbc8360.c
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/watchdog/sbc_epx_c3.c
similarity index 100%
rename from drivers/char/watchdog/sbc_epx_c3.c
rename to drivers/watchdog/sbc_epx_c3.c
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c
similarity index 100%
rename from drivers/char/watchdog/sc1200wdt.c
rename to drivers/watchdog/sc1200wdt.c
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c
similarity index 100%
rename from drivers/char/watchdog/sc520_wdt.c
rename to drivers/watchdog/sc520_wdt.c
diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/watchdog/scx200_wdt.c
similarity index 100%
rename from drivers/char/watchdog/scx200_wdt.c
rename to drivers/watchdog/scx200_wdt.c
diff --git a/drivers/char/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
similarity index 100%
rename from drivers/char/watchdog/shwdt.c
rename to drivers/watchdog/shwdt.c
diff --git a/drivers/char/watchdog/smsc37b787_wdt.c b/drivers/watchdog/smsc37b787_wdt.c
similarity index 100%
rename from drivers/char/watchdog/smsc37b787_wdt.c
rename to drivers/watchdog/smsc37b787_wdt.c
diff --git a/drivers/char/watchdog/softdog.c b/drivers/watchdog/softdog.c
similarity index 100%
rename from drivers/char/watchdog/softdog.c
rename to drivers/watchdog/softdog.c
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
similarity index 100%
rename from drivers/char/watchdog/w83627hf_wdt.c
rename to drivers/watchdog/w83627hf_wdt.c
diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c
similarity index 99%
rename from drivers/char/watchdog/w83697hf_wdt.c
rename to drivers/watchdog/w83697hf_wdt.c
index d9e821d..51826c2 100644
--- a/drivers/char/watchdog/w83697hf_wdt.c
+++ b/drivers/watchdog/w83697hf_wdt.c
@@ -8,7 +8,7 @@
  *	which is based on wdt.c.
  *	Original copyright messages:
  *
- *	(c) Copyright 2003 Pádraig Brady <P@draigBrady.com>
+ *	(c) Copyright 2003 Pádraig Brady <P@draigBrady.com>
  *
  *	(c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
  *
diff --git a/drivers/char/watchdog/w83877f_wdt.c b/drivers/watchdog/w83877f_wdt.c
similarity index 100%
rename from drivers/char/watchdog/w83877f_wdt.c
rename to drivers/watchdog/w83877f_wdt.c
diff --git a/drivers/char/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c
similarity index 100%
rename from drivers/char/watchdog/w83977f_wdt.c
rename to drivers/watchdog/w83977f_wdt.c
diff --git a/drivers/char/watchdog/wafer5823wdt.c b/drivers/watchdog/wafer5823wdt.c
similarity index 100%
rename from drivers/char/watchdog/wafer5823wdt.c
rename to drivers/watchdog/wafer5823wdt.c
diff --git a/drivers/char/watchdog/wd501p.h b/drivers/watchdog/wd501p.h
similarity index 100%
rename from drivers/char/watchdog/wd501p.h
rename to drivers/watchdog/wd501p.h
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
similarity index 100%
rename from drivers/char/watchdog/wdrtas.c
rename to drivers/watchdog/wdrtas.c
diff --git a/drivers/char/watchdog/wdt.c b/drivers/watchdog/wdt.c
similarity index 100%
rename from drivers/char/watchdog/wdt.c
rename to drivers/watchdog/wdt.c
diff --git a/drivers/char/watchdog/wdt285.c b/drivers/watchdog/wdt285.c
similarity index 100%
rename from drivers/char/watchdog/wdt285.c
rename to drivers/watchdog/wdt285.c
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/watchdog/wdt977.c
similarity index 100%
rename from drivers/char/watchdog/wdt977.c
rename to drivers/watchdog/wdt977.c
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
similarity index 100%
rename from drivers/char/watchdog/wdt_pci.c
rename to drivers/watchdog/wdt_pci.c
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 0b769f7..4750de3 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -185,13 +185,14 @@
 	if (!dev->otherend ||
 	    strncmp(dev->otherend, vec[XS_WATCH_PATH],
 		    strlen(dev->otherend))) {
-		dev_dbg(&dev->dev, "Ignoring watch at %s", vec[XS_WATCH_PATH]);
+		dev_dbg(&dev->dev, "Ignoring watch at %s\n",
+			vec[XS_WATCH_PATH]);
 		return;
 	}
 
 	state = xenbus_read_driver_state(dev->otherend);
 
-	dev_dbg(&dev->dev, "state is %d, (%s), %s, %s",
+	dev_dbg(&dev->dev, "state is %d, (%s), %s, %s\n",
 		state, xenbus_strstate(state), dev->otherend_watch.node,
 		vec[XS_WATCH_PATH]);
 
diff --git a/drivers/zorro/zorro.ids b/drivers/zorro/zorro.ids
index 5bd4b05d..560fef2 100644
--- a/drivers/zorro/zorro.ids
+++ b/drivers/zorro/zorro.ids
@@ -295,7 +295,7 @@
 	0100  RH 800C [HD Controller]
 	0200  RH 800C [RAM Expansion]
 0861  Kato
-# The Rainbow II and III are actually made by Ingenieurbüro Helfrich
+# The Rainbow II and III are actually made by Ingenieurbüro Helfrich
 	2000  Rainbow II [Graphics Card]
 	2100  Rainbow III [Graphics Card]
 	8000  Melody MPEG [Audio Card]
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 873802d..756f7e9 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -162,6 +162,7 @@
 				if (*e != '\0')
 					v9ses->uid = ~0;
 			}
+			kfree(s);
 			break;
 
 		default:
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 175b4d9..23581bc 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -687,10 +687,10 @@
 	retval = p9_client_wstat(oldfid, &wstat);
 
 clunk_newdir:
-	p9_client_clunk(olddirfid);
+	p9_client_clunk(newdirfid);
 
 clunk_olddir:
-	p9_client_clunk(newdirfid);
+	p9_client_clunk(olddirfid);
 
 done:
 	return retval;
diff --git a/fs/Kconfig b/fs/Kconfig
index d806274..cc28a69 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -140,6 +140,7 @@
 	tristate "Ext4dev/ext4 extended fs support development (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
 	select JBD2
+	select CRC16
 	help
 	  Ext4dev is a predecessor filesystem of the next generation
 	  extended fs ext4, based on ext3 filesystem code. It will be
@@ -219,7 +220,7 @@
 
 config JBD_DEBUG
 	bool "JBD (ext3) debugging support"
-	depends on JBD
+	depends on JBD && DEBUG_FS
 	help
 	  If you are using the ext3 journaled file system (or potentially any
 	  other file system/device using JBD), this option allows you to
@@ -228,10 +229,10 @@
 	  debugging output will be turned off.
 
 	  If you select Y here, then you will be able to turn on debugging
-	  with "echo N > /proc/sys/fs/jbd-debug", where N is a number between
-	  1 and 5, the higher the number, the more debugging output is
-	  generated.  To turn debugging off again, do
-	  "echo 0 > /proc/sys/fs/jbd-debug".
+	  with "echo N > /sys/kernel/debug/jbd/jbd-debug", where N is a
+	  number between 1 and 5, the higher the number, the more debugging
+	  output is generated.  To turn debugging off again, do
+	  "echo 0 > /sys/kernel/debug/jbd/jbd-debug".
 
 config JBD2
 	tristate
diff --git a/fs/aio.c b/fs/aio.c
index d02f43b..f12db41 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -710,18 +710,9 @@
 
 	/*
 	 * Now we are all set to call the retry method in async
-	 * context. By setting this thread's io_wait context
-	 * to point to the wait queue entry inside the currently
-	 * running iocb for the duration of the retry, we ensure
-	 * that async notification wakeups are queued by the
-	 * operation instead of blocking waits, and when notified,
-	 * cause the iocb to be kicked for continuation (through
-	 * the aio_wake_function callback).
+	 * context.
 	 */
-	BUG_ON(current->io_wait != NULL);
-	current->io_wait = &iocb->ki_wait;
 	ret = retry(iocb);
-	current->io_wait = NULL;
 
 	if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) {
 		BUG_ON(!list_empty(&iocb->ki_wait.task_list));
@@ -1508,10 +1499,7 @@
  * 	Simply triggers a retry of the operation via kick_iocb.
  *
  * 	This callback is specified in the wait queue entry in
- *	a kiocb	(current->io_wait points to this wait queue
- *	entry when an aio operation executes; it is used
- * 	instead of a synchronous wait when an i/o blocking
- *	condition is encountered during aio).
+ *	a kiocb.
  *
  * Note:
  * This routine is executed with the wait queue lock held.
diff --git a/fs/attr.c b/fs/attr.c
index ae58bd3..966b73e 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -103,12 +103,11 @@
 int notify_change(struct dentry * dentry, struct iattr * attr)
 {
 	struct inode *inode = dentry->d_inode;
-	mode_t mode;
+	mode_t mode = inode->i_mode;
 	int error;
 	struct timespec now;
 	unsigned int ia_valid = attr->ia_valid;
 
-	mode = inode->i_mode;
 	now = current_fs_time(inode->i_sb);
 
 	attr->ia_ctime = now;
@@ -125,18 +124,25 @@
 		if (error)
 			return error;
 	}
+
+	/*
+	 * We now pass ATTR_KILL_S*ID to the lower level setattr function so
+	 * that the function has the ability to reinterpret a mode change
+	 * that's due to these bits. This adds an implicit restriction that
+	 * no function will ever call notify_change with both ATTR_MODE and
+	 * ATTR_KILL_S*ID set.
+	 */
+	if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) &&
+	    (ia_valid & ATTR_MODE))
+		BUG();
+
 	if (ia_valid & ATTR_KILL_SUID) {
-		attr->ia_valid &= ~ATTR_KILL_SUID;
 		if (mode & S_ISUID) {
-			if (!(ia_valid & ATTR_MODE)) {
-				ia_valid = attr->ia_valid |= ATTR_MODE;
-				attr->ia_mode = inode->i_mode;
-			}
-			attr->ia_mode &= ~S_ISUID;
+			ia_valid = attr->ia_valid |= ATTR_MODE;
+			attr->ia_mode = (inode->i_mode & ~S_ISUID);
 		}
 	}
 	if (ia_valid & ATTR_KILL_SGID) {
-		attr->ia_valid &= ~ ATTR_KILL_SGID;
 		if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
 			if (!(ia_valid & ATTR_MODE)) {
 				ia_valid = attr->ia_valid |= ATTR_MODE;
@@ -145,7 +151,7 @@
 			attr->ia_mode &= ~S_ISGID;
 		}
 	}
-	if (!attr->ia_valid)
+	if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID)))
 		return 0;
 
 	if (ia_valid & ATTR_SIZE)
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index e7204d7..45f5992 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -80,7 +80,7 @@
 
 	*uid = current->uid;
 	*gid = current->gid;
-	*pgrp = process_group(current);
+	*pgrp = task_pgrp_nr(current);
 
 	*minproto = *maxproto = AUTOFS_PROTO_VERSION;
 
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
index c148953..5efff3c 100644
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -214,8 +214,8 @@
 
 	oz_mode = autofs_oz_mode(sbi);
 	DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, "
-				"oz_mode = %d\n", pid_nr(task_pid(current)),
-				process_group(current), sbi->catatonic,
+				"oz_mode = %d\n", task_pid_nr(current),
+				task_pgrp_nr(current), sbi->catatonic,
 				oz_mode));
 
 	/*
@@ -536,7 +536,7 @@
 	struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
 	void __user *argp = (void __user *)arg;
 
-	DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,process_group(current)));
+	DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,task_pgrp_nr(current)));
 
 	if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
 	     _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT)
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c
index 19a9caf..be46805 100644
--- a/fs/autofs/waitq.c
+++ b/fs/autofs/waitq.c
@@ -182,7 +182,7 @@
 {
 	struct autofs_wait_queue *wq, **wql;
 
-	for ( wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next ) {
+	for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) {
 		if ( wq->wait_queue_token == wait_queue_token )
 			break;
 	}
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index d85f42f..2d4ae40 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -131,7 +131,7 @@
    filesystem without "magic".) */
 
 static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) {
-	return sbi->catatonic || process_group(current) == sbi->oz_pgrp;
+	return sbi->catatonic || task_pgrp_nr(current) == sbi->oz_pgrp;
 }
 
 /* Does a dentry have some pending activity? */
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index cd81f08..7f05d6c 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -226,7 +226,7 @@
 
 	*uid = current->uid;
 	*gid = current->gid;
-	*pgrp = process_group(current);
+	*pgrp = task_pgrp_nr(current);
 
 	*minproto = AUTOFS_MIN_PROTO_VERSION;
 	*maxproto = AUTOFS_MAX_PROTO_VERSION;
@@ -323,7 +323,7 @@
 	sbi->pipe = NULL;
 	sbi->catatonic = 1;
 	sbi->exp_timeout = 0;
-	sbi->oz_pgrp = process_group(current);
+	sbi->oz_pgrp = task_pgrp_nr(current);
 	sbi->sb = s;
 	sbi->version = 0;
 	sbi->sub_version = 0;
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 45ff3d6..2bbcc81 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -582,7 +582,7 @@
 	oz_mode = autofs4_oz_mode(sbi);
 
 	DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d",
-		 current->pid, process_group(current), sbi->catatonic, oz_mode);
+		 current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode);
 
 	unhashed = autofs4_lookup_unhashed(sbi, dentry->d_parent, &dentry->d_name);
 	if (!unhashed) {
@@ -976,7 +976,7 @@
 	void __user *p = (void __user *)arg;
 
 	DPRINTK("cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u",
-		cmd,arg,sbi,process_group(current));
+		cmd,arg,sbi,task_pgrp_nr(current));
 
 	if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
 	     _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT)
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 0d041a9..1fe28e4 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -376,7 +376,7 @@
 	struct autofs_wait_queue *wq, **wql;
 
 	mutex_lock(&sbi->wq_mutex);
-	for (wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next) {
+	for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) {
 		if (wq->wait_queue_token == wait_queue_token)
 			break;
 	}
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 6e2f3b8..ba8de7c 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1383,10 +1383,10 @@
 	prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
 	prstatus->pr_sigpend = p->pending.signal.sig[0];
 	prstatus->pr_sighold = p->blocked.sig[0];
-	prstatus->pr_pid = p->pid;
-	prstatus->pr_ppid = p->parent->pid;
-	prstatus->pr_pgrp = process_group(p);
-	prstatus->pr_sid = process_session(p);
+	prstatus->pr_pid = task_pid_vnr(p);
+	prstatus->pr_ppid = task_pid_vnr(p->parent);
+	prstatus->pr_pgrp = task_pgrp_vnr(p);
+	prstatus->pr_sid = task_session_vnr(p);
 	if (thread_group_leader(p)) {
 		/*
 		 * This is the record for the group leader.  Add in the
@@ -1429,10 +1429,10 @@
 			psinfo->pr_psargs[i] = ' ';
 	psinfo->pr_psargs[len] = 0;
 
-	psinfo->pr_pid = p->pid;
-	psinfo->pr_ppid = p->parent->pid;
-	psinfo->pr_pgrp = process_group(p);
-	psinfo->pr_sid = process_session(p);
+	psinfo->pr_pid = task_pid_vnr(p);
+	psinfo->pr_ppid = task_pid_vnr(p->parent);
+	psinfo->pr_pgrp = task_pgrp_vnr(p);
+	psinfo->pr_sid = task_session_vnr(p);
 
 	i = p->state ? ffz(~p->state) + 1 : 0;
 	psinfo->pr_state = i;
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 033861c..32649f2 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1342,10 +1342,10 @@
 	prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
 	prstatus->pr_sigpend = p->pending.signal.sig[0];
 	prstatus->pr_sighold = p->blocked.sig[0];
-	prstatus->pr_pid = p->pid;
-	prstatus->pr_ppid = p->parent->pid;
-	prstatus->pr_pgrp = process_group(p);
-	prstatus->pr_sid = process_session(p);
+	prstatus->pr_pid = task_pid_vnr(p);
+	prstatus->pr_ppid = task_pid_vnr(p->parent);
+	prstatus->pr_pgrp = task_pgrp_vnr(p);
+	prstatus->pr_sid = task_session_vnr(p);
 	if (thread_group_leader(p)) {
 		/*
 		 * This is the record for the group leader.  Add in the
@@ -1391,10 +1391,10 @@
 			psinfo->pr_psargs[i] = ' ';
 	psinfo->pr_psargs[len] = 0;
 
-	psinfo->pr_pid = p->pid;
-	psinfo->pr_ppid = p->parent->pid;
-	psinfo->pr_pgrp = process_group(p);
-	psinfo->pr_sid = process_session(p);
+	psinfo->pr_pid = task_pid_vnr(p);
+	psinfo->pr_ppid = task_pid_vnr(p->parent);
+	psinfo->pr_pgrp = task_pgrp_vnr(p);
+	psinfo->pr_sid = task_session_vnr(p);
 
 	i = p->state ? ffz(~p->state) + 1 : 0;
 	psinfo->pr_state = i;
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c
index 576dd7d..f95ae97 100644
--- a/fs/binfmt_em86.c
+++ b/fs/binfmt_em86.c
@@ -2,7 +2,7 @@
  *  linux/fs/binfmt_em86.c
  *
  *  Based on linux/fs/binfmt_script.c
- *  Copyright (C) 1996  Martin von Löwis
+ *  Copyright (C) 1996  Martin von Löwis
  *  original #!-checking implemented by tytso.
  *
  *  em86 changes Copyright (C) 1997  Jim Paradis
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 42e94b3..b53c7e5 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -1,7 +1,7 @@
 /*
  *  binfmt_misc.c
  *
- *  Copyright (C) 1997 Richard Günther
+ *  Copyright (C) 1997 Richard Günther
  *
  *  binfmt_misc detects binaries via a magic or filename extension and invokes
  *  a specified wrapper. This should obsolete binfmt_java, binfmt_em86 and
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 4d0e0f6..ab33939 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -1,7 +1,7 @@
 /*
  *  linux/fs/binfmt_script.c
  *
- *  Copyright (C) 1996  Martin von Löwis
+ *  Copyright (C) 1996  Martin von Löwis
  *  original #!-checking implemented by tytso.
  */
 
diff --git a/fs/buffer.c b/fs/buffer.c
index 76403b1..7249e01 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2563,7 +2563,7 @@
 			struct page *page, void *fsdata)
 {
 	struct inode *inode = page->mapping->host;
-	struct buffer_head *head = NULL;
+	struct buffer_head *head = fsdata;
 	struct buffer_head *bh;
 
 	if (!PageMappedToDisk(page)) {
@@ -2584,7 +2584,6 @@
 	unlock_page(page);
 	page_cache_release(page);
 
-	head = fsdata;
 	while (head) {
 		bh = head;
 		head = head->b_this_page;
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index bed6215..3d41916 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,19 @@
+Version 1.51
+------------
+Fix memory leak in statfs when mounted to very old servers (e.g.
+Windows 9x).  Add new feature "POSIX open" which allows servers
+which support the current POSIX Extensions to provide better semantics
+(e.g. delete for open files opened with posix open).  Take into
+account umask on posix mkdir not just older style mkdir.  Add
+ability to mount to IPC$ share (which allows CIFS named pipes to be
+opened, read and written as if they were files).  When 1st tree
+connect fails (e.g. due to signing negotiation failure) fix
+leak that causes cifsd not to stop and rmmod to fail to cleanup
+cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on
+bigendian architectures. Fix possible memory corruption when
+EAGAIN returned on kern_recvmsg. Return better error if server
+requires packet signing but client has disabled it.
+
 Version 1.50
 ------------
 Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is
@@ -6,7 +22,10 @@
 Samba supports newer POSIX CIFS Protocol Extensions). Add "nounix"
 mount option to allow disabling the CIFS Unix Extensions for just
 that mount. Fix hang on spinlock in find_writable_file (race when
-reopening file after session crash).
+reopening file after session crash).  Byte range unlock request to
+windows server could unlock more bytes (on server copy of file)
+than intended if start of unlock request is well before start of
+a previous byte range lock that we issued.
 
 Version 1.49
 ------------
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index 6ecd9d6..ff6ba8d 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -3,4 +3,4 @@
 #
 obj-$(CONFIG_CIFS) += cifs.o
 
-cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o
+cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o cifsacl.o
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index f50a88d..2a01f3e 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -385,10 +385,9 @@
 	unsigned long *optr;
 
 	size = eoc - ctx->pointer + 1;
-	*oid = kmalloc(size * sizeof (unsigned long), GFP_ATOMIC);
-	if (*oid == NULL) {
+	*oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
+	if (*oid == NULL)
 		return 0;
-	}
 
 	optr = *oid;
 
@@ -581,9 +580,8 @@
 			return 0;
 		} else if ((cls != ASN1_UNI) || (con != ASN1_CON)
 			   || (tag != ASN1_SEQ)) {
-			cFYI(1,
-			     ("Exit 6 cls = %d con = %d tag = %d end = %p (%d)",
-			      cls, con, tag, end, *end));
+			cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d)",
+				cls, con, tag, end, *end));
 		}
 
 		if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 1bf8cf5..73c4c41 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -209,13 +209,16 @@
 		i++;
 		tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
 		dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
-		length =
-		    sprintf(buf,
-			    "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x "
-			    "Attributes: 0x%x\nPathComponentMax: %d Status: %d",
-			    i, tcon->treeName,
-			    atomic_read(&tcon->useCount),
-			    tcon->nativeFileSystem,
+		length = sprintf(buf, "\n%d) %s Uses: %d ", i,
+				 tcon->treeName, atomic_read(&tcon->useCount));
+		buf += length;
+		if (tcon->nativeFileSystem) {
+			length = sprintf(buf, "Type: %s ",
+					 tcon->nativeFileSystem);
+			buf += length;
+		}
+		length = sprintf(buf, "DevInfo: 0x%x Attributes: 0x%x"
+				 "\nPathComponentMax: %d Status: %d",
 			    le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
 			    le32_to_cpu(tcon->fsAttrInfo.Attributes),
 			    le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
@@ -876,11 +879,16 @@
 	if (count < 3) {
 		/* single char or single char followed by null */
 		c = flags_string[0];
-		if (c == '0' || c == 'n' || c == 'N')
+		if (c == '0' || c == 'n' || c == 'N') {
 			extended_security = CIFSSEC_DEF; /* default */
-		else if (c == '1' || c == 'y' || c == 'Y')
+			return count;
+		} else if (c == '1' || c == 'y' || c == 'Y') {
 			extended_security = CIFSSEC_MAX;
-		return count;
+			return count;
+		} else if (!isdigit(c)) {
+			cERROR(1, ("invalid flag %c", c));
+			return -EINVAL;
+		}
 	}
 	/* else we have a number */
 
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
new file mode 100644
index 0000000..e8e5635
--- /dev/null
+++ b/fs/cifs/cifsacl.c
@@ -0,0 +1,333 @@
+/*
+ *   fs/cifs/cifsacl.c
+ *
+ *   Copyright (C) International Business Machines  Corp., 2007
+ *   Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ *   Contains the routines for mapping CIFS/NTFS ACLs
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/fs.h>
+#include "cifspdu.h"
+#include "cifsglob.h"
+#include "cifsacl.h"
+#include "cifsproto.h"
+#include "cifs_debug.h"
+
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+
+static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
+	{{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
+	{{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
+	{{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"},
+	{{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(18), 0, 0, 0, 0} }, "sys"},
+	{{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(544), 0, 0, 0} }, "root"},
+	{{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(545), 0, 0, 0} }, "users"},
+	{{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"}
+};
+
+
+/* security id for everyone */
+static const struct cifs_sid sid_everyone =
+		{1, 1, {0, 0, 0, 0, 0, 0}, {} };
+/* group users */
+static const struct cifs_sid sid_user =
+		{1, 2 , {0, 0, 0, 0, 0, 5}, {} };
+
+
+int match_sid(struct cifs_sid *ctsid)
+{
+	int i, j;
+	int num_subauth, num_sat, num_saw;
+	struct cifs_sid *cwsid;
+
+	if (!ctsid)
+		return (-1);
+
+	for (i = 0; i < NUM_WK_SIDS; ++i) {
+		cwsid = &(wksidarr[i].cifssid);
+
+		/* compare the revision */
+		if (ctsid->revision != cwsid->revision)
+			continue;
+
+		/* compare all of the six auth values */
+		for (j = 0; j < 6; ++j) {
+			if (ctsid->authority[j] != cwsid->authority[j])
+				break;
+		}
+		if (j < 6)
+			continue; /* all of the auth values did not match */
+
+		/* compare all of the subauth values if any */
+		num_sat = ctsid->num_subauth;
+		num_saw = cwsid->num_subauth;
+		num_subauth = num_sat < num_saw ? num_sat : num_saw;
+		if (num_subauth) {
+			for (j = 0; j < num_subauth; ++j) {
+				if (ctsid->sub_auth[j] != cwsid->sub_auth[j])
+					break;
+			}
+			if (j < num_subauth)
+				continue; /* all sub_auth values do not match */
+		}
+
+		cFYI(1, ("matching sid: %s\n", wksidarr[i].sidname));
+		return (0); /* sids compare/match */
+	}
+
+	cFYI(1, ("No matching sid"));
+	return (-1);
+}
+
+/* if the two SIDs (roughly equivalent to a UUID for a user or group) are
+   the same returns 1, if they do not match returns 0 */
+int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid)
+{
+	int i;
+	int num_subauth, num_sat, num_saw;
+
+	if ((!ctsid) || (!cwsid))
+		return (0);
+
+	/* compare the revision */
+	if (ctsid->revision != cwsid->revision)
+		return (0);
+
+	/* compare all of the six auth values */
+	for (i = 0; i < 6; ++i) {
+		if (ctsid->authority[i] != cwsid->authority[i])
+			return (0);
+	}
+
+	/* compare all of the subauth values if any */
+	num_sat = ctsid->num_subauth;
+	num_saw = cwsid->num_subauth;
+	num_subauth = num_sat < num_saw ? num_sat : num_saw;
+	if (num_subauth) {
+		for (i = 0; i < num_subauth; ++i) {
+			if (ctsid->sub_auth[i] != cwsid->sub_auth[i])
+				return (0);
+		}
+	}
+
+	return (1); /* sids compare/match */
+}
+
+
+static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
+{
+	int num_subauth;
+
+	/* validate that we do not go past end of acl */
+
+	/* XXX this if statement can be removed
+	if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) {
+		cERROR(1, ("ACL too small to parse ACE"));
+		return;
+	} */
+
+	num_subauth = pace->num_subauth;
+	if (num_subauth) {
+#ifdef CONFIG_CIFS_DEBUG2
+		int i;
+		cFYI(1, ("ACE revision %d num_subauth %d",
+			pace->revision, pace->num_subauth));
+		for (i = 0; i < num_subauth; ++i) {
+			cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
+				le32_to_cpu(pace->sub_auth[i])));
+		}
+
+		/* BB add length check to make sure that we do not have huge
+			num auths and therefore go off the end */
+
+		cFYI(1, ("RID %d", le32_to_cpu(pace->sub_auth[num_subauth-1])));
+#endif
+	}
+
+	return;
+}
+
+static void parse_ntace(struct cifs_ntace *pntace, char *end_of_acl)
+{
+	/* validate that we do not go past end of acl */
+	if (end_of_acl < (char *)pntace + sizeof(struct cifs_ntace)) {
+		cERROR(1, ("ACL too small to parse NT ACE"));
+		return;
+	}
+
+#ifdef CONFIG_CIFS_DEBUG2
+	cFYI(1, ("NTACE type %d flags 0x%x size %d, access Req 0x%x",
+		pntace->type, pntace->flags, pntace->size,
+		pntace->access_req));
+#endif
+	return;
+}
+
+
+
+static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
+		       struct cifs_sid *pownersid, struct cifs_sid *pgrpsid)
+{
+	int i;
+	int num_aces = 0;
+	int acl_size;
+	char *acl_base;
+	struct cifs_ntace **ppntace;
+	struct cifs_ace **ppace;
+
+	/* BB need to add parm so we can store the SID BB */
+
+	/* validate that we do not go past end of acl */
+	if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
+		cERROR(1, ("ACL too small to parse DACL"));
+		return;
+	}
+
+#ifdef CONFIG_CIFS_DEBUG2
+	cFYI(1, ("DACL revision %d size %d num aces %d",
+		le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
+		le32_to_cpu(pdacl->num_aces)));
+#endif
+
+	acl_base = (char *)pdacl;
+	acl_size = sizeof(struct cifs_acl);
+
+	num_aces = le32_to_cpu(pdacl->num_aces);
+	if (num_aces  > 0) {
+		ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *),
+				GFP_KERNEL);
+		ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
+				GFP_KERNEL);
+
+/*		cifscred->cecount = pdacl->num_aces;
+		cifscred->ntaces = kmalloc(num_aces *
+			sizeof(struct cifs_ntace *), GFP_KERNEL);
+		cifscred->aces = kmalloc(num_aces *
+			sizeof(struct cifs_ace *), GFP_KERNEL);*/
+
+		for (i = 0; i < num_aces; ++i) {
+			ppntace[i] = (struct cifs_ntace *)
+					(acl_base + acl_size);
+			ppace[i] = (struct cifs_ace *) ((char *)ppntace[i] +
+					sizeof(struct cifs_ntace));
+
+			parse_ntace(ppntace[i], end_of_acl);
+			if (end_of_acl < ((char *)ppace[i] +
+					(le16_to_cpu(ppntace[i]->size) -
+					sizeof(struct cifs_ntace)))) {
+				cERROR(1, ("ACL too small to parse ACE"));
+				break;
+			} else
+				parse_ace(ppace[i], end_of_acl);
+
+/*			memcpy((void *)(&(cifscred->ntaces[i])),
+				(void *)ppntace[i],
+				sizeof(struct cifs_ntace));
+			memcpy((void *)(&(cifscred->aces[i])),
+				(void *)ppace[i],
+				sizeof(struct cifs_ace)); */
+
+			acl_base = (char *)ppntace[i];
+			acl_size = le16_to_cpu(ppntace[i]->size);
+		}
+
+		kfree(ppace);
+		kfree(ppntace);
+	}
+
+	return;
+}
+
+
+static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
+{
+
+	/* BB need to add parm so we can store the SID BB */
+
+	/* validate that we do not go past end of acl */
+	if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) {
+		cERROR(1, ("ACL too small to parse SID"));
+		return -EINVAL;
+	}
+
+	if (psid->num_subauth) {
+#ifdef CONFIG_CIFS_DEBUG2
+		int i;
+		cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x",
+			psid->revision, psid->num_subauth, psid->sub_auth[0]));
+
+		for (i = 0; i < psid->num_subauth; i++) {
+			cFYI(1, ("SID sub_auth[%d]: 0x%x ", i,
+				le32_to_cpu(psid->sub_auth[i])));
+		}
+
+		/* BB add length check to make sure that we do not have huge
+			num auths and therefore go off the end */
+		cFYI(1, ("RID 0x%x",
+			le32_to_cpu(psid->sub_auth[psid->num_subauth-1])));
+#endif
+	}
+
+	return 0;
+}
+
+
+/* Convert CIFS ACL to POSIX form */
+int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
+{
+	int rc;
+	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
+	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
+	char *end_of_acl = ((char *)pntsd) + acl_len;
+
+	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+				le32_to_cpu(pntsd->osidoffset));
+	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+				le32_to_cpu(pntsd->gsidoffset));
+	dacl_ptr = (struct cifs_acl *)((char *)pntsd +
+				le32_to_cpu(pntsd->dacloffset));
+#ifdef CONFIG_CIFS_DEBUG2
+	cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x "
+		 "sacloffset 0x%x dacloffset 0x%x",
+		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
+		 le32_to_cpu(pntsd->gsidoffset),
+		 le32_to_cpu(pntsd->sacloffset),
+		 le32_to_cpu(pntsd->dacloffset)));
+#endif
+	rc = parse_sid(owner_sid_ptr, end_of_acl);
+	if (rc)
+		return rc;
+
+	rc = parse_sid(group_sid_ptr, end_of_acl);
+	if (rc)
+		return rc;
+
+	parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr);
+
+/*	cifscred->uid = owner_sid_ptr->rid;
+	cifscred->gid = group_sid_ptr->rid;
+	memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr,
+			sizeof (struct cifs_sid));
+	memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
+			sizeof (struct cifs_sid)); */
+
+
+	return (0);
+}
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index 5eff35d..420f878 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/cifsacl.h
  *
- *   Copyright (c) International Business Machines  Corp., 2005
+ *   Copyright (c) International Business Machines  Corp., 2007
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -22,17 +22,65 @@
 #ifndef _CIFSACL_H
 #define _CIFSACL_H
 
-struct cifs_sid {
-	__u8 revision; /* revision level */
-	__u8 num_subauths;
-	__u8 authority[6];
-	__u32 sub_auth[4];
-	/* next sub_auth if any ... */
+
+#define NUM_AUTHS 6 /* number of authority fields */
+#define NUM_SUBAUTHS 5 /* number of sub authority fields */
+#define NUM_WK_SIDS 7 /* number of well known sids */
+#define SIDNAMELENGTH 20 /* long enough for the ones we care about */
+
+#define READ_BIT        0x4
+#define WRITE_BIT       0x2
+#define EXEC_BIT        0x1
+
+#define UBITSHIFT	6
+#define GBITSHIFT	3
+
+struct cifs_ntsd {
+	__le16 revision; /* revision level */
+	__le16 type;
+	__le32 osidoffset;
+	__le32 gsidoffset;
+	__le32 sacloffset;
+	__le32 dacloffset;
 } __attribute__((packed));
 
-/* everyone */
-/* extern const struct cifs_sid sid_everyone;*/
-/* group users */
-/* extern const struct cifs_sid sid_user;*/
+struct cifs_sid {
+	__u8 revision; /* revision level */
+	__u8 num_subauth;
+	__u8 authority[6];
+	__le32 sub_auth[5]; /* sub_auth[num_subauth] */ /* BB FIXME endianness BB */
+} __attribute__((packed));
+
+struct cifs_acl {
+	__le16 revision; /* revision level */
+	__le16 size;
+	__le32 num_aces;
+} __attribute__((packed));
+
+struct cifs_ntace { /* first part of ACE which contains perms */
+	__u8 type;
+	__u8 flags;
+	__le16 size;
+	__le32 access_req;
+} __attribute__((packed));
+
+struct cifs_ace { /* last part of ACE which includes user info */
+	__u8 revision; /* revision level */
+	__u8 num_subauth;
+	__u8 authority[6];
+	__le32 sub_auth[5];
+} __attribute__((packed));
+
+struct cifs_wksid {
+	struct cifs_sid cifssid;
+	char sidname[SIDNAMELENGTH];
+} __attribute__((packed));
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+
+extern int match_sid(struct cifs_sid *);
+extern int compare_sids(struct cifs_sid *, struct cifs_sid *);
+
+#endif /*  CONFIG_CIFS_EXPERIMENTAL */
 
 #endif /* _CIFSACL_H */
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 3627229..632070b 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -345,7 +345,7 @@
 	user = kmalloc(2 + (len * 2), GFP_KERNEL);
 	if (user == NULL)
 		goto calc_exit_2;
-	len = cifs_strtoUCS(user, ses->userName, len, nls_cp);
+	len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
 	UniStrupr(user);
 	hmac_md5_update((char *)user, 2*len, pctxt);
 
@@ -356,7 +356,8 @@
 		domain = kmalloc(2 + (len * 2), GFP_KERNEL);
 		if (domain == NULL)
 			goto calc_exit_1;
-		len = cifs_strtoUCS(domain, ses->domainName, len, nls_cp);
+		len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
+					nls_cp);
 		/* the following line was removed since it didn't work well
 		   with lower cased domain name that passed as an option.
 		   Maybe converting the domain name earlier makes sense */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index ba8f786..a6fbea5 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -49,10 +49,6 @@
 static struct quotactl_ops cifs_quotactl_ops;
 #endif /* QUOTA */
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-extern struct export_operations cifs_export_ops;
-#endif /* EXPERIMENTAL */
-
 int cifsFYI = 0;
 int cifsERROR = 1;
 int traceSMB = 0;
@@ -240,9 +236,9 @@
 
 	cifs_sb = CIFS_SB(inode->i_sb);
 
-	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
+	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
 		return 0;
-	} else /* file mode might have been restricted at mount time
+	else /* file mode might have been restricted at mount time
 		on the client (above and beyond ACL on servers) for
 		servers which do not support setting and viewing mode bits,
 		so allowing client to check permissions is useful */
@@ -312,15 +308,15 @@
 					seq_printf(s, ",domain=%s",
 					   cifs_sb->tcon->ses->domainName);
 			}
+			if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
+			   !(cifs_sb->tcon->unix_ext))
+				seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
+			if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
+			   !(cifs_sb->tcon->unix_ext))
+				seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
 		}
 		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
 			seq_printf(s, ",posixpaths");
-		if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
-		   !(cifs_sb->tcon->unix_ext))
-			seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
-		if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
-		   !(cifs_sb->tcon->unix_ext))
-			seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
 		seq_printf(s, ",rsize=%d", cifs_sb->rsize);
 		seq_printf(s, ",wsize=%d", cifs_sb->wsize);
 	}
@@ -346,7 +342,7 @@
 	if (pTcon) {
 		cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
 	} else {
-		return -EIO;
+		rc = -EIO;
 	}
 
 	FreeXid(xid);
@@ -716,7 +712,7 @@
 cifs_init_inodecache(void)
 {
 	cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
-					      sizeof (struct cifsInodeInfo),
+					      sizeof(struct cifsInodeInfo),
 					      0, (SLAB_RECLAIM_ACCOUNT|
 						SLAB_MEM_SPREAD),
 					      cifs_init_once);
@@ -816,8 +812,8 @@
 cifs_init_mids(void)
 {
 	cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
-				sizeof (struct mid_q_entry), 0,
-				SLAB_HWCACHE_ALIGN, NULL);
+					    sizeof(struct mid_q_entry), 0,
+					    SLAB_HWCACHE_ALIGN, NULL);
 	if (cifs_mid_cachep == NULL)
 		return -ENOMEM;
 
@@ -829,8 +825,8 @@
 	}
 
 	cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",
-				sizeof (struct oplock_q_entry), 0,
-				SLAB_HWCACHE_ALIGN, NULL);
+					sizeof(struct oplock_q_entry), 0,
+					SLAB_HWCACHE_ALIGN, NULL);
 	if (cifs_oplock_cachep == NULL) {
 		mempool_destroy(cifs_mid_poolp);
 		kmem_cache_destroy(cifs_mid_cachep);
@@ -882,7 +878,8 @@
 				the call */
 				/* mutex_lock(&inode->i_mutex);*/
 				if (S_ISREG(inode->i_mode)) {
-					rc = filemap_fdatawrite(inode->i_mapping);
+					rc =
+					   filemap_fdatawrite(inode->i_mapping);
 					if (CIFS_I(inode)->clientCanCacheRead
 									 == 0) {
 						filemap_fdatawait(inode->i_mapping);
@@ -907,8 +904,7 @@
 					    0 /* len */ , 0 /* offset */, 0,
 					    0, LOCKING_ANDX_OPLOCK_RELEASE,
 					    0 /* wait flag */);
-					cFYI(1, 
-					      ("Oplock release rc = %d ", rc));
+					cFYI(1, ("Oplock release rc = %d", rc));
 				}
 			} else
 				spin_unlock(&GlobalMid_Lock);
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index a20de77..5574ba3 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/cifsfs.h
  *
- *   Copyright (c) International Business Machines  Corp., 2002, 2005
+ *   Copyright (c) International Business Machines  Corp., 2002, 2007
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -99,7 +99,12 @@
 			size_t, int);
 extern ssize_t	cifs_getxattr(struct dentry *, const char *, void *, size_t);
 extern ssize_t	cifs_listxattr(struct dentry *, char *, size_t);
-extern int cifs_ioctl (struct inode *inode, struct file *filep,
+extern int cifs_ioctl(struct inode *inode, struct file *filep,
 		       unsigned int command, unsigned long arg);
-#define CIFS_VERSION   "1.50"
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+extern const struct export_operations cifs_export_ops;
+#endif /* EXPERIMENTAL */
+
+#define CIFS_VERSION   "1.51"
 #endif				/* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index b98742f..87f51f2 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -19,6 +19,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include "cifs_fs_sb.h"
+#include "cifsacl.h"
 /*
  * The sizes of various internal tables and strings
  */
@@ -89,7 +90,8 @@
 };
 
 enum securityEnum {
-	LANMAN = 0,             /* Legacy LANMAN auth */
+	PLAINTXT = 0, 		/* Legacy with Plaintext passwords */
+	LANMAN,			/* Legacy LANMAN auth */
 	NTLM,			/* Legacy NTLM012 auth with NTLM hash */
 	NTLMv2,			/* Legacy NTLM auth with NTLMv2 hash */
 	RawNTLMSSP,		/* NTLMSSP without SPNEGO */
@@ -115,6 +117,17 @@
 	} data;
 };
 
+struct cifs_cred {
+	int uid;
+	int gid;
+	int mode;
+	int cecount;
+	struct cifs_sid osid;
+	struct cifs_sid gsid;
+	struct cifs_ntace *ntaces;
+	struct cifs_ace *aces;
+};
+
 /*
  *****************************************************************
  * Except the CIFS PDUs themselves all the
@@ -279,6 +292,7 @@
 	FILE_SYSTEM_DEVICE_INFO fsDevInfo;
 	FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
 	FILE_SYSTEM_UNIX_INFO fsUnixInfo;
+	unsigned ipc:1;		/* set if connection to IPC$ eg for RPC/PIPES */
 	unsigned retry:1;
 	unsigned nocase:1;
 	unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol
@@ -329,6 +343,7 @@
 	struct list_head llist; /* list of byte range locks we have. */
 	unsigned closePend:1;	/* file is marked to close */
 	unsigned invalidHandle:1;  /* file closed via session abend */
+	unsigned messageMode:1;    /* for pipes: message vs byte mode */
 	atomic_t wrtPending;   /* handle in use - defer close */
 	struct semaphore fh_sem; /* prevents reopen race after dead ses*/
 	char *search_resume_name; /* BB removeme BB */
@@ -464,6 +479,9 @@
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 #define   CIFSSEC_MAY_LANMAN	0x00010
 #define   CIFSSEC_MAY_PLNTXT	0x00020
+#else
+#define   CIFSSEC_MAY_LANMAN    0
+#define   CIFSSEC_MAY_PLNTXT    0
 #endif /* weak passwords */
 #define   CIFSSEC_MAY_SEAL	0x00040 /* not supported yet */
 
@@ -477,14 +495,23 @@
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 #define   CIFSSEC_MUST_LANMAN	0x10010
 #define   CIFSSEC_MUST_PLNTXT	0x20020
-#define   CIFSSEC_MASK          0x37037 /* current flags supported if weak */
+#ifdef CONFIG_CIFS_UPCALL
+#define   CIFSSEC_MASK          0x3F03F /* allows weak security but also krb5 */
 #else
-#define	  CIFSSEC_MASK          0x07007 /* flags supported if no weak config */
+#define   CIFSSEC_MASK          0x37037 /* current flags supported if weak */
+#endif /* UPCALL */
+#else /* do not allow weak pw hash */
+#ifdef CONFIG_CIFS_UPCALL
+#define   CIFSSEC_MASK          0x0F00F /* flags supported if no weak allowed */
+#else
+#define	  CIFSSEC_MASK          0x07007 /* flags supported if no weak allowed */
+#endif /* UPCALL */
 #endif /* WEAK_PW_HASH */
 #define   CIFSSEC_MUST_SEAL	0x40040 /* not supported yet */
 
 #define   CIFSSEC_DEF  CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2
 #define   CIFSSEC_MAX  CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2
+#define   CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5)
 /*
  *****************************************************************
  * All constants go here
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 6a2056e..c41ff74 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -215,6 +215,12 @@
 					 /* file_execute, file_read_attributes*/
 					 /* write_dac, and delete.           */
 
+#define FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES)
+#define FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
+				| FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
+#define FILE_EXEC_RIGHTS (FILE_EXECUTE)
+
+
 /*
  * Invalid readdir handle
  */
@@ -360,10 +366,10 @@
 	__u8 WordCount;
 } __attribute__((packed));
 /* given a pointer to an smb_hdr retrieve the value of byte count */
-#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
-#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
+#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount)))
+#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount)))
 /* given a pointer to an smb_hdr retrieve the pointer to the byte area */
-#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) + 2 )
+#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount) + 2)
 
 /*
  * Computer Name Length (since Netbios name was length 16 with last byte 0x20)
@@ -716,6 +722,14 @@
 #define REQ_OPENDIRONLY    0x00000008
 #define REQ_EXTENDED_INFO  0x00000010
 
+/* File type */
+#define DISK_TYPE		0x0000
+#define BYTE_PIPE_TYPE		0x0001
+#define MESSAGE_PIPE_TYPE	0x0002
+#define PRINTER_TYPE		0x0003
+#define COMM_DEV_TYPE		0x0004
+#define UNKNOWN_TYPE		0xFFFF
+
 typedef struct smb_com_open_req {	/* also handles create */
 	struct smb_hdr hdr;	/* wct = 24 */
 	__u8 AndXCommand;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 04a69da..1a88366 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -50,7 +50,8 @@
 			int * /* bytes returned */ , const int long_op);
 extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
 			struct kvec *, int /* nvec to send */,
-			int * /* type of buf returned */ , const int long_op);
+			int * /* type of buf returned */ , const int long_op,
+			const int logError /* whether to log status code*/ );
 extern int SendReceiveBlockingLock(const unsigned int /* xid */ ,
 					struct cifsTconInfo *,
 				struct smb_hdr * /* input */ ,
@@ -65,7 +66,7 @@
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
 			enum securityEnum *secType);
 extern int cifs_inet_pton(int, char *source, void *dst);
-extern int map_smb_to_linux_error(struct smb_hdr *smb);
+extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
 extern void header_assemble(struct smb_hdr *, char /* command */ ,
 			    const struct cifsTconInfo *, int /* length of
 			    fixed section (word count) in two byte units */);
@@ -304,12 +305,13 @@
 				 const char *pass);
 extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *,
 			const struct nls_table *);
-extern void CalcNTLMv2_response(const struct cifsSesInfo *, char * );
+extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *);
 extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
 			     const struct nls_table *);
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key);
 #endif /* CIFS_WEAK_PW_HASH */
+extern int parse_sec_desc(struct cifs_ntsd *, int);
 extern int CIFSSMBCopy(int xid,
 			struct cifsTconInfo *source_tcon,
 			const char *fromName,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 8eb102f..f0d9a48 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -34,10 +34,10 @@
 #include <asm/uaccess.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
+#include "cifsacl.h"
 #include "cifsproto.h"
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
-#include "cifsacl.h"
 
 #ifdef CONFIG_CIFS_POSIX
 static struct {
@@ -94,9 +94,8 @@
 	write_lock(&GlobalSMBSeslock);
 	list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
 		open_file = list_entry(tmp, struct cifsFileInfo, tlist);
-		if (open_file) {
+		if (open_file)
 			open_file->invalidHandle = TRUE;
-		}
 	}
 	write_unlock(&GlobalSMBSeslock);
 	/* BB Add call to invalidate_inodes(sb) for all superblocks mounted
@@ -439,8 +438,13 @@
 
 	pSMB->hdr.Mid = GetNextMid(server);
 	pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
+
 	if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
 		pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
+	else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
+		cFYI(1, ("Kerberos only mechanism, enable extended security"));
+		pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
+	}
 
 	count = 0;
 	for (i = 0; i < CIFS_NUM_PROT; i++) {
@@ -513,7 +517,7 @@
 				(int)ts.tv_sec, (int)utc.tv_sec,
 				(int)(utc.tv_sec - ts.tv_sec)));
 			val = (int)(utc.tv_sec - ts.tv_sec);
-			seconds = val < 0 ? -val : val;
+			seconds = abs(val);
 			result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
 			remain = seconds % MIN_TZ_ADJ;
 			if (remain >= (MIN_TZ_ADJ / 2))
@@ -574,7 +578,20 @@
 		server->secType = NTLM;
 	else if (secFlags & CIFSSEC_MAY_NTLMV2)
 		server->secType = NTLMv2;
-	/* else krb5 ... any others ... */
+	else if (secFlags & CIFSSEC_MAY_KRB5)
+		server->secType = Kerberos;
+	else if (secFlags & CIFSSEC_MAY_LANMAN)
+		server->secType = LANMAN;
+/* #ifdef CONFIG_CIFS_EXPERIMENTAL
+	else if (secFlags & CIFSSEC_MAY_PLNTXT)
+		server->secType = ??
+#endif */
+	else {
+		rc = -EOPNOTSUPP;
+		cERROR(1, ("Invalid security type"));
+		goto neg_err_exit;
+	}
+	/* else ... any others ...? */
 
 	/* one byte, so no need to convert this or EncryptionKeyLen from
 	   little endian */
@@ -604,22 +621,26 @@
 	if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
 		(server->capabilities & CAP_EXTENDED_SECURITY)) {
 		count = pSMBr->ByteCount;
-		if (count < 16)
+		if (count < 16) {
 			rc = -EIO;
-		else if (count == 16) {
-			server->secType = RawNTLMSSP;
-			if (server->socketUseCount.counter > 1) {
-				if (memcmp(server->server_GUID,
-					   pSMBr->u.extended_response.
-					   GUID, 16) != 0) {
-					cFYI(1, ("server UID changed"));
-					memcpy(server->server_GUID,
-						pSMBr->u.extended_response.GUID,
-						16);
-				}
-			} else
+			goto neg_err_exit;
+		}
+
+		if (server->socketUseCount.counter > 1) {
+			if (memcmp(server->server_GUID,
+				   pSMBr->u.extended_response.
+				   GUID, 16) != 0) {
+				cFYI(1, ("server UID changed"));
 				memcpy(server->server_GUID,
-				       pSMBr->u.extended_response.GUID, 16);
+					pSMBr->u.extended_response.GUID,
+					16);
+			}
+		} else
+			memcpy(server->server_GUID,
+			       pSMBr->u.extended_response.GUID, 16);
+
+		if (count == 16) {
+			server->secType = RawNTLMSSP;
 		} else {
 			rc = decode_negTokenInit(pSMBr->u.extended_response.
 						 SecurityBlob,
@@ -642,10 +663,12 @@
 		/* MUST_SIGN already includes the MAY_SIGN FLAG
 		   so if this is zero it means that signing is disabled */
 		cFYI(1, ("Signing disabled"));
-		if (server->secMode & SECMODE_SIGN_REQUIRED)
+		if (server->secMode & SECMODE_SIGN_REQUIRED) {
 			cERROR(1, ("Server requires "
-				   "/proc/fs/cifs/PacketSigningEnabled "
-				   "to be on"));
+				   "packet signing to be enabled in "
+				   "/proc/fs/cifs/SecurityFlags."));
+			rc = -EOPNOTSUPP;
+		}
 		server->secMode &=
 			~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
 	} else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
@@ -1052,7 +1075,7 @@
 				InformationLevel) - 4;
 	offset = param_offset + params;
 	pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
-	pdata->Level = SMB_QUERY_FILE_UNIX_BASIC;
+	pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
 	pdata->Permissions = cpu_to_le64(mode);
 	pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
 	pdata->OpenFlags =  cpu_to_le32(*pOplock);
@@ -1098,8 +1121,8 @@
 	if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
 		*pOplock |= CIFS_CREATE_ACTION;
 	/* check to make sure response data is there */
-	if (psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) {
-		pRetData->Type = -1; /* unknown */
+	if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
+		pRetData->Type = cpu_to_le32(-1); /* unknown */
 #ifdef CONFIG_CIFS_DEBUG2
 		cFYI(1, ("unknown type"));
 #endif
@@ -1107,12 +1130,12 @@
 		if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP)
 					+ sizeof(FILE_UNIX_BASIC_INFO)) {
 			cERROR(1, ("Open response data too small"));
-			pRetData->Type = -1;
+			pRetData->Type = cpu_to_le32(-1);
 			goto psx_create_err;
 		}
 		memcpy((char *) pRetData,
 			(char *)psx_rsp + sizeof(OPEN_PSX_RSP),
-			sizeof (FILE_UNIX_BASIC_INFO));
+			sizeof(FILE_UNIX_BASIC_INFO));
 	}
 
 psx_create_err:
@@ -1193,9 +1216,9 @@
 	}
 	if (*pOplock & REQ_OPLOCK)
 		pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
-	else if (*pOplock & REQ_BATCHOPLOCK) {
+	else if (*pOplock & REQ_BATCHOPLOCK)
 		pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
-	}
+
 	pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
 	/* BB fixme add conversion for access_flags to bits 0 - 2 of mode */
 	/* 0 = read
@@ -1310,9 +1333,8 @@
 	}
 	if (*pOplock & REQ_OPLOCK)
 		pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
-	else if (*pOplock & REQ_BATCHOPLOCK) {
+	else if (*pOplock & REQ_BATCHOPLOCK)
 		pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
-	}
 	pSMB->DesiredAccess = cpu_to_le32(access_flags);
 	pSMB->AllocationSize = 0;
 	/* set file as system file if special file such
@@ -1424,9 +1446,8 @@
 
 	iov[0].iov_base = (char *)pSMB;
 	iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
-	rc = SendReceive2(xid, tcon->ses, iov,
-			  1 /* num iovecs */,
-			  &resp_buf_type, 0);
+	rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
+			 &resp_buf_type, 0 /* not long op */, 1 /* log err */ );
 	cifs_stats_inc(&tcon->num_reads);
 	pSMBr = (READ_RSP *)iov[0].iov_base;
 	if (rc) {
@@ -1446,11 +1467,11 @@
 			*nbytes = 0;
 		} else {
 			pReadData = (char *) (&pSMBr->hdr.Protocol) +
-			    le16_to_cpu(pSMBr->DataOffset);
-/*                      if (rc = copy_to_user(buf, pReadData, data_length)) {
+					le16_to_cpu(pSMBr->DataOffset);
+/*			if (rc = copy_to_user(buf, pReadData, data_length)) {
 				cERROR(1,("Faulting on read rc = %d",rc));
 				rc = -EFAULT;
-                        }*/ /* can not use copy_to_user when using page cache*/
+			}*/ /* can not use copy_to_user when using page cache*/
 			if (*buf)
 				memcpy(*buf, pReadData, data_length);
 		}
@@ -1645,7 +1666,7 @@
 
 
 	rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
-			  long_op);
+			  long_op, 0 /* do not log STATUS code */ );
 	cifs_stats_inc(&tcon->num_writes);
 	if (rc) {
 		cFYI(1, ("Send error Write2 = %d", rc));
@@ -2538,7 +2559,7 @@
 		cFYI(1, ("data starts after end of smb"));
 		return -EINVAL;
 	} else if (data_count + *ppdata > end_of_smb) {
-		cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p",
+		cFYI(1, ("data %p + count %d (%p) ends after end of smb %p start %p",
 			*ppdata, data_count, (data_count + *ppdata),
 			end_of_smb, pSMBr));
 		return -EINVAL;
@@ -2615,7 +2636,7 @@
 					reparse_buf->TargetNameOffset +
 					reparse_buf->TargetNameLen) >
 						end_of_smb) {
-					cFYI(1,("reparse buf goes beyond SMB"));
+					cFYI(1, ("reparse buf beyond SMB"));
 					rc = -EIO;
 					goto qreparse_out;
 				}
@@ -3042,25 +3063,12 @@
 
 #endif /* CONFIG_POSIX */
 
-
-/* security id for everyone */
-static const struct cifs_sid sid_everyone =
-		{1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
-/* group users */
-static const struct cifs_sid sid_user =
-		{1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
-
-/* Convert CIFS ACL to POSIX form */
-static int parse_sec_desc(struct cifs_sid *psec_desc, int acl_len)
-{
-	return 0;
-}
-
+#ifdef CONFIG_CIFS_EXPERIMENTAL
 /* Get Security Descriptor (by handle) from remote server for a file or dir */
 int
 CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
 		/* BB fix up return info */ char *acl_inf, const int buflen,
-		  const int acl_type /* ACCESS/DEFAULT not sure implication */)
+		  const int acl_type)
 {
 	int rc = 0;
 	int buf_type = 0;
@@ -3085,12 +3093,13 @@
 	iov[0].iov_base = (char *)pSMB;
 	iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
 
-	rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0);
+	rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
+			 0 /* not long op */, 0 /* do not log STATUS codes */ );
 	cifs_stats_inc(&tcon->num_acl_get);
 	if (rc) {
 		cFYI(1, ("Send error in QuerySecDesc = %d", rc));
 	} else {                /* decode response */
-		struct cifs_sid *psec_desc;
+		struct cifs_ntsd *psec_desc;
 		__le32 * parm;
 		int parm_len;
 		int data_len;
@@ -3105,8 +3114,7 @@
 			goto qsec_out;
 		pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
 
-		cERROR(1, ("smb %p parm %p data %p",
-			  pSMBr, parm, psec_desc));  /* BB removeme BB */
+		cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc));
 
 		if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
 			rc = -EIO;      /* bad smb */
@@ -3115,7 +3123,7 @@
 
 /* BB check that data area is minimum length and as big as acl_len */
 
-		acl_len = le32_to_cpu(*(__le32 *)parm);
+		acl_len = le32_to_cpu(*parm);
 		/* BB check if (acl_len > bufsize) */
 
 		parse_sec_desc(psec_desc, acl_len);
@@ -3128,6 +3136,7 @@
 /*	cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
 	return rc;
 }
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
 
 /* Legacy Query Path Information call for lookup to old servers such
    as Win9x/WinME */
@@ -3363,6 +3372,9 @@
 		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
 		if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
+			cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n"
+				   "Unix Extensions can be disabled on mount "
+				   "by specifying the nosfu mount option."));
 			rc = -EIO;	/* bad smb */
 		} else {
 			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -3883,12 +3895,10 @@
 	pSMB->hdr.Mid = GetNextMid(ses->server);
 	pSMB->hdr.Tid = ses->ipc_tid;
 	pSMB->hdr.Uid = ses->Suid;
-	if (ses->capabilities & CAP_STATUS32) {
+	if (ses->capabilities & CAP_STATUS32)
 		pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
-	}
-	if (ses->capabilities & CAP_DFS) {
+	if (ses->capabilities & CAP_DFS)
 		pSMB->hdr.Flags2 |= SMBFLG2_DFS;
-	}
 
 	if (ses->capabilities & CAP_UNICODE) {
 		pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
@@ -4060,10 +4070,6 @@
 		(void **) &pSMBr);
 	if (rc)
 		return rc;
-	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-		      (void **) &pSMBr);
-	if (rc)
-		return rc;
 
 	params = 2;     /* level */
 	pSMB->TotalDataCount = 0;
@@ -4265,7 +4271,7 @@
 			     *) (((char *) &pSMBr->hdr.Protocol) +
 				 data_offset);
 			memcpy(&tcon->fsAttrInfo, response_data,
-			       sizeof (FILE_SYSTEM_ATTRIBUTE_INFO));
+			       sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
 		}
 	}
 	cifs_buf_release(pSMB);
@@ -4334,7 +4340,7 @@
 				(((char *) &pSMBr->hdr.Protocol) +
 				 data_offset);
 			memcpy(&tcon->fsDevInfo, response_data,
-			       sizeof (FILE_SYSTEM_DEVICE_INFO));
+			       sizeof(FILE_SYSTEM_DEVICE_INFO));
 		}
 	}
 	cifs_buf_release(pSMB);
@@ -4402,7 +4408,7 @@
 			     *) (((char *) &pSMBr->hdr.Protocol) +
 				 data_offset);
 			memcpy(&tcon->fsUnixInfo, response_data,
-			       sizeof (FILE_SYSTEM_UNIX_INFO));
+			       sizeof(FILE_SYSTEM_UNIX_INFO));
 		}
 	}
 	cifs_buf_release(pSMB);
@@ -4612,7 +4618,7 @@
 		strncpy(pSMB->FileName, fileName, name_len);
 	}
 	params = 6 + name_len;
-	data_count = sizeof (struct file_end_of_file_info);
+	data_count = sizeof(struct file_end_of_file_info);
 	pSMB->MaxParameterCount = cpu_to_le16(2);
 	pSMB->MaxDataCount = cpu_to_le16(4100);
 	pSMB->MaxSetupCount = 0;
@@ -4800,7 +4806,7 @@
 
 	data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
 
-	count = sizeof (FILE_BASIC_INFO);
+	count = sizeof(FILE_BASIC_INFO);
 	pSMB->MaxParameterCount = cpu_to_le16(2);
 	pSMB->MaxDataCount = cpu_to_le16(1000);	/* BB find max SMB PDU from sess */
 	pSMB->SetupCount = 1;
@@ -4871,7 +4877,7 @@
 	}
 
 	params = 6 + name_len;
-	count = sizeof (FILE_BASIC_INFO);
+	count = sizeof(FILE_BASIC_INFO);
 	pSMB->MaxParameterCount = cpu_to_le16(2);
 	pSMB->MaxDataCount = cpu_to_le16(1000);	/* BB find exact max SMB PDU from sess structure BB */
 	pSMB->MaxSetupCount = 0;
@@ -4900,7 +4906,7 @@
 		pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
 	pSMB->Reserved4 = 0;
 	pSMB->hdr.smb_buf_length += byte_count;
-	memcpy(data_offset, data, sizeof (FILE_BASIC_INFO));
+	memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
 	pSMB->ByteCount = cpu_to_le16(byte_count);
 	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
 			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -5003,7 +5009,7 @@
 	}
 
 	params = 6 + name_len;
-	count = sizeof (FILE_UNIX_BASIC_INFO);
+	count = sizeof(FILE_UNIX_BASIC_INFO);
 	pSMB->MaxParameterCount = cpu_to_le16(2);
 	pSMB->MaxDataCount = cpu_to_le16(1000);	/* BB find exact max SMB PDU from sess structure BB */
 	pSMB->MaxSetupCount = 0;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 4af3588..19ee11f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -124,7 +124,7 @@
 	struct mid_q_entry *mid_entry;
 
 	spin_lock(&GlobalMid_Lock);
-	if ( kthread_should_stop() ) {
+	if (kthread_should_stop()) {
 		/* the demux thread will exit normally
 		next time through the loop */
 		spin_unlock(&GlobalMid_Lock);
@@ -151,9 +151,8 @@
 	}
 	list_for_each(tmp, &GlobalTreeConnectionList) {
 		tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
-		if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
+		if ((tcon) && (tcon->ses) && (tcon->ses->server == server))
 			tcon->tidStatus = CifsNeedReconnect;
-		}
 	}
 	read_unlock(&GlobalSMBSeslock);
 	/* do not want to be sending data on a socket we are freeing */
@@ -187,7 +186,7 @@
 	spin_unlock(&GlobalMid_Lock);
 	up(&server->tcpSem);
 
-	while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
+	while ((!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
 		try_to_freeze();
 		if (server->protocolType == IPV6) {
 			rc = ipv6_connect(&server->addr.sockAddr6,
@@ -204,7 +203,7 @@
 		} else {
 			atomic_inc(&tcpSesReconnectCount);
 			spin_lock(&GlobalMid_Lock);
-			if ( !kthread_should_stop() )
+			if (!kthread_should_stop())
 				server->tcpStatus = CifsGood;
 			server->sequence_number = 0;
 			spin_unlock(&GlobalMid_Lock);
@@ -352,17 +351,15 @@
 
 	current->flags |= PF_MEMALLOC;
 	server->tsk = current;	/* save process info to wake at shutdown */
-	cFYI(1, ("Demultiplex PID: %d", current->pid));
+	cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
 	write_lock(&GlobalSMBSeslock);
 	atomic_inc(&tcpSesAllocCount);
 	length = tcpSesAllocCount.counter;
 	write_unlock(&GlobalSMBSeslock);
 	complete(&cifsd_complete);
-	if (length  > 1) {
-		mempool_resize(cifs_req_poolp,
-			length + cifs_min_rcv,
-			GFP_KERNEL);
-	}
+	if (length  > 1)
+		mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
+				GFP_KERNEL);
 
 	set_freezable();
 	while (!kthread_should_stop()) {
@@ -378,7 +375,7 @@
 			}
 		} else if (isLargeBuf) {
 			/* we are reusing a dirty large buf, clear its start */
-			memset(bigbuf, 0, sizeof (struct smb_hdr));
+			memset(bigbuf, 0, sizeof(struct smb_hdr));
 		}
 
 		if (smallbuf == NULL) {
@@ -391,7 +388,7 @@
 			}
 			/* beginning of smb buffer is cleared in our buf_get */
 		} else /* if existing small buf clear beginning */
-			memset(smallbuf, 0, sizeof (struct smb_hdr));
+			memset(smallbuf, 0, sizeof(struct smb_hdr));
 
 		isLargeBuf = FALSE;
 		isMultiRsp = FALSE;
@@ -400,11 +397,13 @@
 		iov.iov_len = 4;
 		smb_msg.msg_control = NULL;
 		smb_msg.msg_controllen = 0;
+		pdu_length = 4; /* enough to get RFC1001 header */
+incomplete_rcv:
 		length =
 		    kernel_recvmsg(csocket, &smb_msg,
-				 &iov, 1, 4, 0 /* BB see socket.h flags */);
+				&iov, 1, pdu_length, 0 /* BB other flags? */);
 
-		if ( kthread_should_stop() ) {
+		if (kthread_should_stop()) {
 			break;
 		} else if (server->tcpStatus == CifsNeedReconnect) {
 			cFYI(1, ("Reconnect after server stopped responding"));
@@ -416,7 +415,10 @@
 			msleep(1); /* minimum sleep to prevent looping
 				allowing socket to clear and app threads to set
 				tcpStatus CifsNeedReconnect if server hung */
-			continue;
+			if (pdu_length < 4)
+				goto incomplete_rcv;
+			else
+				continue;
 		} else if (length <= 0) {
 			if (server->tcpStatus == CifsNew) {
 				cFYI(1, ("tcp session abend after SMBnegprot"));
@@ -437,13 +439,11 @@
 			wake_up(&server->response_q);
 			continue;
 		} else if (length < 4) {
-			cFYI(1,
-			    ("Frame under four bytes received (%d bytes long)",
+			cFYI(1, ("less than four bytes received (%d bytes)",
 			      length));
-			cifs_reconnect(server);
-			csocket = server->ssocket;
-			wake_up(&server->response_q);
-			continue;
+			pdu_length -= length;
+			msleep(1);
+			goto incomplete_rcv;
 		}
 
 		/* The right amount was read from socket - 4 bytes */
@@ -504,7 +504,7 @@
 
 		/* else we have an SMB response */
 		if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
-			    (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
+			    (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
 			cERROR(1, ("Invalid size SMB length %d pdu_length %d",
 					length, pdu_length+4));
 			cifs_reconnect(server);
@@ -528,7 +528,7 @@
 		     total_read += length) {
 			length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
 						pdu_length - total_read, 0);
-			if ( kthread_should_stop() ||
+			if (kthread_should_stop() ||
 			    (length == -EINTR)) {
 				/* then will exit */
 				reconnect = 2;
@@ -546,6 +546,7 @@
 					      allowing socket to clear and app
 					      threads to set tcpStatus
 					      CifsNeedReconnect if server hung*/
+				length = 0;
 				continue;
 			} else if (length <= 0) {
 				cERROR(1, ("Received no data, expecting %d",
@@ -631,9 +632,9 @@
 			/* Was previous buf put in mpx struct for multi-rsp? */
 			if (!isMultiRsp) {
 				/* smb buffer will be freed by user thread */
-				if (isLargeBuf) {
+				if (isLargeBuf)
 					bigbuf = NULL;
-				} else
+				else
 					smallbuf = NULL;
 			}
 			wake_up_process(task_to_wake);
@@ -676,9 +677,8 @@
 		server->ssocket = NULL;
 	}
 	/* buffer usuallly freed in free_mid - need to free it here on exit */
-	if (bigbuf != NULL)
-		cifs_buf_release(bigbuf);
-	if (smallbuf != NULL)
+	cifs_buf_release(bigbuf);
+	if (smallbuf) /* no sense logging a debug message if NULL */
 		cifs_small_buf_release(smallbuf);
 
 	read_lock(&GlobalSMBSeslock);
@@ -702,9 +702,8 @@
 		list_for_each(tmp, &GlobalSMBSessionList) {
 			ses = list_entry(tmp, struct cifsSesInfo,
 					 cifsSessionList);
-			if (ses->server == server) {
+			if (ses->server == server)
 				ses->status = CifsExiting;
-			}
 		}
 
 		spin_lock(&GlobalMid_Lock);
@@ -714,9 +713,8 @@
 				cFYI(1, ("Clearing Mid 0x%x - waking up ",
 					 mid_entry->mid));
 				task_to_wake = mid_entry->tsk;
-				if (task_to_wake) {
+				if (task_to_wake)
 					wake_up_process(task_to_wake);
-				}
 			}
 		}
 		spin_unlock(&GlobalMid_Lock);
@@ -749,18 +747,15 @@
 	list_for_each(tmp, &GlobalSMBSessionList) {
 		ses = list_entry(tmp, struct cifsSesInfo,
 				cifsSessionList);
-		if (ses->server == server) {
+		if (ses->server == server)
 			ses->server = NULL;
-		}
 	}
 	write_unlock(&GlobalSMBSeslock);
 
 	kfree(server);
-	if (length  > 0) {
-		mempool_resize(cifs_req_poolp,
-			length + cifs_min_rcv,
-			GFP_KERNEL);
-	}
+	if (length  > 0)
+		mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
+				GFP_KERNEL);
 
 	return 0;
 }
@@ -1477,7 +1472,7 @@
 	if (psin_server->sin_port) { /* user overrode default port */
 		rc = (*csocket)->ops->connect(*csocket,
 				(struct sockaddr *) psin_server,
-				sizeof (struct sockaddr_in), 0);
+				sizeof(struct sockaddr_in), 0);
 		if (rc >= 0)
 			connected = 1;
 	}
@@ -1493,7 +1488,7 @@
 
 			rc = (*csocket)->ops->connect(*csocket,
 					(struct sockaddr *) psin_server,
-					sizeof (struct sockaddr_in), 0);
+					sizeof(struct sockaddr_in), 0);
 			if (rc >= 0)
 				connected = 1;
 		}
@@ -1502,7 +1497,7 @@
 		psin_server->sin_port = htons(RFC1001_PORT);
 		rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
 					      psin_server,
-					      sizeof (struct sockaddr_in), 0);
+					      sizeof(struct sockaddr_in), 0);
 		if (rc >= 0)
 			connected = 1;
 	}
@@ -1610,7 +1605,7 @@
 	if (psin_server->sin6_port) { /* user overrode default port */
 		rc = (*csocket)->ops->connect(*csocket,
 				(struct sockaddr *) psin_server,
-				sizeof (struct sockaddr_in6), 0);
+				sizeof(struct sockaddr_in6), 0);
 		if (rc >= 0)
 			connected = 1;
 	}
@@ -1626,7 +1621,7 @@
 
 			rc = (*csocket)->ops->connect(*csocket,
 					(struct sockaddr *) psin_server,
-					sizeof (struct sockaddr_in6), 0);
+					sizeof(struct sockaddr_in6), 0);
 			if (rc >= 0)
 				connected = 1;
 		}
@@ -1634,7 +1629,7 @@
 	if (!connected) {
 		psin_server->sin6_port = htons(RFC1001_PORT);
 		rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
-				 psin_server, sizeof (struct sockaddr_in6), 0);
+				 psin_server, sizeof(struct sockaddr_in6), 0);
 		if (rc >= 0)
 			connected = 1;
 	}
@@ -1750,7 +1745,16 @@
 			cFYI(1, ("very large write cap"));
 #endif /* CIFS_DEBUG2 */
 		if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
-			cFYI(1, ("setting capabilities failed"));
+			if (vol_info == NULL) {
+				cFYI(1, ("resetting capabilities failed"));
+			} else
+				cERROR(1, ("Negotiating Unix capabilities "
+					   "with the server failed.  Consider "
+					   "mounting with the Unix Extensions\n"
+					   "disabled, if problems are found, "
+					   "by specifying the nounix mount "
+					   "option."));
+
 		}
 	}
 }
@@ -1909,8 +1913,8 @@
 			return rc;
 		}
 
-		srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
-		if (srvTcp == NULL) {
+		srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
+		if (!srvTcp) {
 			rc = -ENOMEM;
 			sock_release(csocket);
 			kfree(volume_info.UNC);
@@ -1919,9 +1923,8 @@
 			FreeXid(xid);
 			return rc;
 		} else {
-			memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
 			memcpy(&srvTcp->addr.sockAddr, &sin_server,
-				sizeof (struct sockaddr_in));
+				sizeof(struct sockaddr_in));
 			atomic_set(&srvTcp->inFlight, 0);
 			/* BB Add code for ipv6 case too */
 			srvTcp->ssocket = csocket;
@@ -2173,8 +2176,18 @@
 						if (tsk)
 							kthread_stop(tsk);
 					}
-				} else
+				} else {
 					cFYI(1, ("No session or bad tcon"));
+					if ((pSesInfo->server) &&
+					    (pSesInfo->server->tsk)) {
+						struct task_struct *tsk;
+						force_sig(SIGKILL,
+							pSesInfo->server->tsk);
+						tsk = pSesInfo->server->tsk;
+						if (tsk)
+							kthread_stop(tsk);
+					}
+				}
 				sesInfoFree(pSesInfo);
 				/* pSesInfo = NULL; */
 			}
@@ -2185,8 +2198,10 @@
 		tcon->ses = pSesInfo;
 
 		/* do not care if following two calls succeed - informational */
-		CIFSSMBQFSDeviceInfo(xid, tcon);
-		CIFSSMBQFSAttributeInfo(xid, tcon);
+		if (!tcon->ipc) {
+			CIFSSMBQFSDeviceInfo(xid, tcon);
+			CIFSSMBQFSAttributeInfo(xid, tcon);
+		}
 
 		/* tell server which Unix caps we support */
 		if (tcon->ses->capabilities & CAP_UNIX)
@@ -2526,8 +2541,7 @@
 sesssetup_nomem:	/* do not return an error on nomem for the info strings,
 			   since that could make reconnection harder, and
 			   reconnection might be needed to free memory */
-	if (smb_buffer)
-		cifs_buf_release(smb_buffer);
+	cifs_buf_release(smb_buffer);
 
 	return rc;
 }
@@ -2547,7 +2561,7 @@
 	int remaining_words = 0;
 	int bytes_returned = 0;
 	int len;
-	int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
+	int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
 	PNEGOTIATE_MESSAGE SecurityBlob;
 	PCHALLENGE_MESSAGE SecurityBlob2;
 	__u32 negotiate_flags, capabilities;
@@ -2865,15 +2879,14 @@
 		rc = -EIO;
 	}
 
-	if (smb_buffer)
-		cifs_buf_release(smb_buffer);
+	cifs_buf_release(smb_buffer);
 
 	return rc;
 }
 static int
 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
-		char *ntlm_session_key, int ntlmv2_flag,
-		const struct nls_table *nls_codepage)
+			char *ntlm_session_key, int ntlmv2_flag,
+			const struct nls_table *nls_codepage)
 {
 	struct smb_hdr *smb_buffer;
 	struct smb_hdr *smb_buffer_response;
@@ -2886,7 +2899,7 @@
 	int remaining_words = 0;
 	int bytes_returned = 0;
 	int len;
-	int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
+	int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
 	PAUTHENTICATE_MESSAGE SecurityBlob;
 	__u32 negotiate_flags, capabilities;
 	__u16 count;
@@ -2901,8 +2914,8 @@
 		return -ENOMEM;
 	}
 	smb_buffer_response = smb_buffer;
-	pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
-	pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
+	pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
+	pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
 
 	/* send SMBsessionSetup here */
 	header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
@@ -2921,7 +2934,7 @@
 		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 
 	capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
-	    CAP_EXTENDED_SECURITY;
+			CAP_EXTENDED_SECURITY;
 	if (ses->capabilities & CAP_UNICODE) {
 		smb_buffer->Flags2 |= SMBFLG2_UNICODE;
 		capabilities |= CAP_UNICODE;
@@ -2936,15 +2949,14 @@
 	}
 	pSMB->req.Capabilities = cpu_to_le32(capabilities);
 
-	bcc_ptr = (char *) &pSMB->req.SecurityBlob;
-	SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
+	bcc_ptr = (char *)&pSMB->req.SecurityBlob;
+	SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
 	strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
 	SecurityBlob->MessageType = NtLmAuthenticate;
 	bcc_ptr += SecurityBlobLength;
-	negotiate_flags =
-	    NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
-	    NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
-	    0x80000000 | NTLMSSP_NEGOTIATE_128;
+	negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
+			NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
+			0x80000000 | NTLMSSP_NEGOTIATE_128;
 	if (sign_CIFS_PDUs)
 		negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
 	if (ntlmv2_flag)
@@ -2979,36 +2991,32 @@
 			SecurityBlob->DomainName.Length = 0;
 			SecurityBlob->DomainName.MaximumLength = 0;
 		} else {
-			__u16 len =
-			    cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
+			__u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
 					  nls_codepage);
-			len *= 2;
+			ln *= 2;
 			SecurityBlob->DomainName.MaximumLength =
-			    cpu_to_le16(len);
+			    cpu_to_le16(ln);
 			SecurityBlob->DomainName.Buffer =
 			    cpu_to_le32(SecurityBlobLength);
-			bcc_ptr += len;
-			SecurityBlobLength += len;
-			SecurityBlob->DomainName.Length =
-			    cpu_to_le16(len);
+			bcc_ptr += ln;
+			SecurityBlobLength += ln;
+			SecurityBlob->DomainName.Length = cpu_to_le16(ln);
 		}
 		if (user == NULL) {
 			SecurityBlob->UserName.Buffer = 0;
 			SecurityBlob->UserName.Length = 0;
 			SecurityBlob->UserName.MaximumLength = 0;
 		} else {
-			__u16 len =
-			    cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
+			__u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
 					  nls_codepage);
-			len *= 2;
+			ln *= 2;
 			SecurityBlob->UserName.MaximumLength =
-			    cpu_to_le16(len);
+			    cpu_to_le16(ln);
 			SecurityBlob->UserName.Buffer =
 			    cpu_to_le32(SecurityBlobLength);
-			bcc_ptr += len;
-			SecurityBlobLength += len;
-			SecurityBlob->UserName.Length =
-			    cpu_to_le16(len);
+			bcc_ptr += ln;
+			SecurityBlobLength += ln;
+			SecurityBlob->UserName.Length = cpu_to_le16(ln);
 		}
 
 		/* SecurityBlob->WorkstationName.Length =
@@ -3052,33 +3060,32 @@
 			SecurityBlob->DomainName.Length = 0;
 			SecurityBlob->DomainName.MaximumLength = 0;
 		} else {
-			__u16 len;
+			__u16 ln;
 			negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
 			strncpy(bcc_ptr, domain, 63);
-			len = strnlen(domain, 64);
+			ln = strnlen(domain, 64);
 			SecurityBlob->DomainName.MaximumLength =
-			    cpu_to_le16(len);
+			    cpu_to_le16(ln);
 			SecurityBlob->DomainName.Buffer =
 			    cpu_to_le32(SecurityBlobLength);
-			bcc_ptr += len;
-			SecurityBlobLength += len;
-			SecurityBlob->DomainName.Length = cpu_to_le16(len);
+			bcc_ptr += ln;
+			SecurityBlobLength += ln;
+			SecurityBlob->DomainName.Length = cpu_to_le16(ln);
 		}
 		if (user == NULL) {
 			SecurityBlob->UserName.Buffer = 0;
 			SecurityBlob->UserName.Length = 0;
 			SecurityBlob->UserName.MaximumLength = 0;
 		} else {
-			__u16 len;
+			__u16 ln;
 			strncpy(bcc_ptr, user, 63);
-			len = strnlen(user, 64);
-			SecurityBlob->UserName.MaximumLength =
-			    cpu_to_le16(len);
+			ln = strnlen(user, 64);
+			SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
 			SecurityBlob->UserName.Buffer =
-			    cpu_to_le32(SecurityBlobLength);
-			bcc_ptr += len;
-			SecurityBlobLength += len;
-			SecurityBlob->UserName.Length = cpu_to_le16(len);
+						cpu_to_le32(SecurityBlobLength);
+			bcc_ptr += ln;
+			SecurityBlobLength += ln;
+			SecurityBlob->UserName.Length = cpu_to_le16(ln);
 		}
 		/* BB fill in our workstation name if known BB */
 
@@ -3100,12 +3107,11 @@
 	rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
 			 &bytes_returned, 1);
 	if (rc) {
-/*    rc = map_smb_to_linux_error(smb_buffer_response);  *//* done in SendReceive now */
-	} else if ((smb_buffer_response->WordCount == 3)
-		   || (smb_buffer_response->WordCount == 4)) {
+/*   rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
+	} else if ((smb_buffer_response->WordCount == 3) ||
+		   (smb_buffer_response->WordCount == 4)) {
 		__u16 action = le16_to_cpu(pSMBr->resp.Action);
-		__u16 blob_len =
-		    le16_to_cpu(pSMBr->resp.SecurityBlobLength);
+		__u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
 		if (action & GUEST_LOGIN)
 			cFYI(1, (" Guest login")); /* BB Should we set anything
 							 in SesInfo struct ? */
@@ -3145,8 +3151,8 @@
 					} else {
 						remaining_words = BCC(smb_buffer_response) / 2;
 					}
-					len =
-					    UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
+					len = UniStrnlen((wchar_t *) bcc_ptr,
+							remaining_words - 1);
 /* We look for obvious messed up bcc or strings in response so we do not go off
   the end since (at least) WIN2K and Windows XP have a major bug in not null
   terminating last Unicode string in response  */
@@ -3230,7 +3236,7 @@
 						<= BCC(smb_buffer_response)) {
 						if (ses->serverOS)
 							kfree(ses->serverOS);
-						ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
+						ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
 						strncpy(ses->serverOS,bcc_ptr, len);
 
 						bcc_ptr += len;
@@ -3259,28 +3265,24 @@
 						bcc_ptr[0] = 0;
 						bcc_ptr++;
 					} else
-						cFYI(1,
-						     ("field of length %d "
+						cFYI(1, ("field of length %d "
 						   "extends beyond end of smb ",
 						      len));
 				}
 			} else {
-				cERROR(1,
-				       (" Security Blob extends beyond end "
+				cERROR(1, ("Security Blob extends beyond end "
 					"of SMB"));
 			}
 		} else {
 			cERROR(1, ("No session structure passed in."));
 		}
 	} else {
-		cERROR(1,
-		       (" Invalid Word count %d: ",
+		cERROR(1, ("Invalid Word count %d: ",
 			smb_buffer_response->WordCount));
 		rc = -EIO;
 	}
 
-	if (smb_buffer)
-		cifs_buf_release(smb_buffer);
+	cifs_buf_release(smb_buffer);
 
 	return rc;
 }
@@ -3389,6 +3391,18 @@
 		bcc_ptr = pByteArea(smb_buffer_response);
 		length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
 		/* skip service field (NB: this field is always ASCII) */
+		if (length == 3) {
+			if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
+			    (bcc_ptr[2] == 'C')) {
+				cFYI(1, ("IPC connection"));
+				tcon->ipc = 1;
+			}
+		} else if (length == 2) {
+			if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
+				/* the most common case */
+				cFYI(1, ("disk share connection"));
+			}
+		}
 		bcc_ptr += length + 1;
 		strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
 		if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
@@ -3399,9 +3413,11 @@
 				kfree(tcon->nativeFileSystem);
 				tcon->nativeFileSystem =
 				    kzalloc(length + 2, GFP_KERNEL);
-				cifs_strfromUCS_le(tcon->nativeFileSystem,
-						   (__le16 *) bcc_ptr,
-						   length, nls_codepage);
+				if (tcon->nativeFileSystem)
+					cifs_strfromUCS_le(
+						tcon->nativeFileSystem,
+						(__le16 *) bcc_ptr,
+						length, nls_codepage);
 				bcc_ptr += 2 * length;
 				bcc_ptr[0] = 0;	/* null terminate the string */
 				bcc_ptr[1] = 0;
@@ -3416,8 +3432,9 @@
 				kfree(tcon->nativeFileSystem);
 				tcon->nativeFileSystem =
 				    kzalloc(length + 1, GFP_KERNEL);
-				strncpy(tcon->nativeFileSystem, bcc_ptr,
-					length);
+				if (tcon->nativeFileSystem)
+					strncpy(tcon->nativeFileSystem, bcc_ptr,
+						length);
 			}
 			/* else do not bother copying these information fields*/
 		}
@@ -3433,8 +3450,7 @@
 		ses->ipc_tid = smb_buffer_response->Tid;
 	}
 
-	if (smb_buffer)
-		cifs_buf_release(smb_buffer);
+	cifs_buf_release(smb_buffer);
 	return rc;
 }
 
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 4830acc..793404b 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -3,7 +3,7 @@
  *
  *   vfs operations that deal with dentries
  *
- *   Copyright (C) International Business Machines  Corp., 2002,2005
+ *   Copyright (C) International Business Machines  Corp., 2002,2007
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -269,7 +269,7 @@
 			CIFSSMBClose(xid, pTcon, fileHandle);
 		} else if (newinode) {
 			pCifsFile =
-			   kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
+			   kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
 
 			if (pCifsFile == NULL)
 				goto cifs_create_out;
@@ -397,7 +397,7 @@
 				/* BB Do not bother to decode buf since no
 				   local inode yet to put timestamps in,
 				   but we can reuse it safely */
-				int bytes_written;
+				unsigned int bytes_written;
 				struct win_dev *pdev;
 				pdev = (struct win_dev *)buf;
 				if (S_ISCHR(mode)) {
@@ -450,8 +450,7 @@
 
 	xid = GetXid();
 
-	cFYI(1,
-	     (" parent inode = 0x%p name is: %s and dentry = 0x%p",
+	cFYI(1, (" parent inode = 0x%p name is: %s and dentry = 0x%p",
 	      parent_dir_inode, direntry->d_name.name, direntry));
 
 	/* check whether path exists */
diff --git a/fs/cifs/export.c b/fs/cifs/export.c
index 893fd0a..75949d6 100644
--- a/fs/cifs/export.c
+++ b/fs/cifs/export.c
@@ -43,6 +43,7 @@
 #include <linux/exportfs.h>
 #include "cifsglob.h"
 #include "cifs_debug.h"
+#include "cifsfs.h"
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 static struct dentry *cifs_get_parent(struct dentry *dentry)
@@ -52,7 +53,7 @@
 	return ERR_PTR(-EACCES);
 }
 
-struct export_operations cifs_export_ops = {
+const struct export_operations cifs_export_ops = {
 	.get_parent = cifs_get_parent,
 /*	Following five export operations are unneeded so far and can default:
 	.get_dentry =
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 894b1f7..1e7e4c0 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -467,7 +467,7 @@
 int cifs_close(struct inode *inode, struct file *file)
 {
 	int rc = 0;
-	int xid;
+	int xid, timeout;
 	struct cifs_sb_info *cifs_sb;
 	struct cifsTconInfo *pTcon;
 	struct cifsFileInfo *pSMBFile =
@@ -485,9 +485,9 @@
 			/* no sense reconnecting to close a file that is
 			   already closed */
 			if (pTcon->tidStatus != CifsNeedReconnect) {
-				int timeout = 2;
+				timeout = 2;
 				while ((atomic_read(&pSMBFile->wrtPending) != 0)
-					 && (timeout < 1000) ) {
+					&& (timeout <= 2048)) {
 					/* Give write a better chance to get to
 					server ahead of the close.  We do not
 					want to add a wait_q here as it would
@@ -522,12 +522,30 @@
 		list_del(&pSMBFile->flist);
 		list_del(&pSMBFile->tlist);
 		write_unlock(&GlobalSMBSeslock);
+		timeout = 10;
+		/* We waited above to give the SMBWrite a chance to issue
+		   on the wire (so we do not get SMBWrite returning EBADF
+		   if writepages is racing with close.  Note that writepages
+		   does not specify a file handle, so it is possible for a file
+		   to be opened twice, and the application close the "wrong"
+		   file handle - in these cases we delay long enough to allow
+		   the SMBWrite to get on the wire before the SMB Close.
+		   We allow total wait here over 45 seconds, more than
+		   oplock break time, and more than enough to allow any write
+		   to complete on the server, or to time out on the client */
+		while ((atomic_read(&pSMBFile->wrtPending) != 0)
+				&& (timeout <= 50000)) {
+			cERROR(1, ("writes pending, delay free of handle"));
+			msleep(timeout);
+			timeout *= 8;
+		}
 		kfree(pSMBFile->search_resume_name);
 		kfree(file->private_data);
 		file->private_data = NULL;
 	} else
 		rc = -EBADF;
 
+	read_lock(&GlobalSMBSeslock);
 	if (list_empty(&(CIFS_I(inode)->openFileList))) {
 		cFYI(1, ("closing last open instance for inode %p", inode));
 		/* if the file is not open we do not know if we can cache info
@@ -535,6 +553,7 @@
 		CIFS_I(inode)->clientCanCacheRead = FALSE;
 		CIFS_I(inode)->clientCanCacheAll  = FALSE;
 	}
+	read_unlock(&GlobalSMBSeslock);
 	if ((rc == 0) && CIFS_I(inode)->write_behind_rc)
 		rc = CIFS_I(inode)->write_behind_rc;
 	FreeXid(xid);
@@ -767,7 +786,8 @@
 			mutex_lock(&fid->lock_mutex);
 			list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
 				if (pfLock->fl_start <= li->offset &&
-						length >= li->length) {
+						(pfLock->fl_start + length) >=
+						(li->offset + li->length)) {
 					stored_rc = CIFSSMBLock(xid, pTcon,
 							netfid,
 							li->length, li->offset,
@@ -1022,6 +1042,7 @@
 	}
 
 	read_lock(&GlobalSMBSeslock);
+refind_writable:
 	list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
 		if (open_file->closePend)
 			continue;
@@ -1029,24 +1050,49 @@
 		    ((open_file->pfile->f_flags & O_RDWR) ||
 		     (open_file->pfile->f_flags & O_WRONLY))) {
 			atomic_inc(&open_file->wrtPending);
+
+			if (!open_file->invalidHandle) {
+				/* found a good writable file */
+				read_unlock(&GlobalSMBSeslock);
+				return open_file;
+			}
+	
 			read_unlock(&GlobalSMBSeslock);
-			if ((open_file->invalidHandle) &&
-			   (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) {
-				rc = cifs_reopen_file(open_file->pfile, FALSE);
-				/* if it fails, try another handle - might be */
-				/* dangerous to hold up writepages with retry */
-				if (rc) {
-					cFYI(1,
-					      ("failed on reopen file in wp"));
+			/* Had to unlock since following call can block */
+			rc = cifs_reopen_file(open_file->pfile, FALSE);
+			if (!rc) { 
+				if (!open_file->closePend)
+					return open_file;
+				else { /* start over in case this was deleted */
+				       /* since the list could be modified */
 					read_lock(&GlobalSMBSeslock);
-					/* can not use this handle, no write
-					pending on this one after all */
-					atomic_dec
-					     (&open_file->wrtPending);
-					continue;
+					atomic_dec(&open_file->wrtPending);
+					goto refind_writable;
 				}
 			}
-			return open_file;
+
+			/* if it fails, try another handle if possible -
+			(we can not do this if closePending since
+			loop could be modified - in which case we
+			have to start at the beginning of the list
+			again. Note that it would be bad
+			to hold up writepages here (rather than
+			in caller) with continuous retries */
+			cFYI(1, ("wp failed on reopen file"));
+			read_lock(&GlobalSMBSeslock);
+			/* can not use this handle, no write
+			   pending on this one after all */
+			atomic_dec(&open_file->wrtPending);
+			
+			if (open_file->closePend) /* list could have changed */
+				goto refind_writable;
+			/* else we simply continue to the next entry. Thus
+			   we do not loop on reopen errors.  If we
+			   can not reopen the file, for example if we
+			   reconnected to a server with another client
+			   racing to delete or lock the file we would not
+			   make progress if we restarted before the beginning
+			   of the loop here. */
 		}
 	}
 	read_unlock(&GlobalSMBSeslock);
@@ -1709,7 +1755,7 @@
 	struct page *page;
 	struct cifs_sb_info *cifs_sb;
 	struct cifsTconInfo *pTcon;
-	int bytes_read = 0;
+	unsigned int bytes_read = 0;
 	unsigned int read_size, i;
 	char *smb_read_data = NULL;
 	struct smb_com_read_rsp *pSMBr;
@@ -1803,7 +1849,7 @@
 
 			i +=  bytes_read >> PAGE_CACHE_SHIFT;
 			cifs_stats_bytes_read(pTcon, bytes_read);
-			if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
+			if ((bytes_read & PAGE_CACHE_MASK) != bytes_read) {
 				i++; /* account for partial page */
 
 				/* server copy of file can have smaller size
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index dd41677..5e8b388 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -115,7 +115,7 @@
 		inode->i_mode = le64_to_cpu(findData.Permissions);
 		/* since we set the inode type below we need to mask off
 		   to avoid strange results if bits set above */
-			inode->i_mode &= ~S_IFMT;
+		inode->i_mode &= ~S_IFMT;
 		if (type == UNIX_FILE) {
 			inode->i_mode |= S_IFREG;
 		} else if (type == UNIX_SYMLINK) {
@@ -575,19 +575,33 @@
 	return rc;
 }
 
+static const struct inode_operations cifs_ipc_inode_ops = {
+	.lookup = cifs_lookup,
+};
+
 /* gets root inode */
 void cifs_read_inode(struct inode *inode)
 {
-	int xid;
+	int xid, rc;
 	struct cifs_sb_info *cifs_sb;
 
 	cifs_sb = CIFS_SB(inode->i_sb);
 	xid = GetXid();
 
 	if (cifs_sb->tcon->unix_ext)
-		cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
+		rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
 	else
-		cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
+		rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
+	if (rc && cifs_sb->tcon->ipc) {
+		cFYI(1, ("ipc connection - fake read inode"));
+		inode->i_mode |= S_IFDIR;
+		inode->i_nlink = 2;
+		inode->i_op = &cifs_ipc_inode_ops;
+		inode->i_fop = &simple_dir_operations;
+		inode->i_uid = cifs_sb->mnt_uid;
+		inode->i_gid = cifs_sb->mnt_gid;
+	}
+
 	/* can not call macro FreeXid here since in a void func */
 	_FreeXid(xid);
 }
@@ -919,18 +933,25 @@
 			goto mkdir_out;
 		}
 
+		mode &= ~current->fs->umask;
 		rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
 				mode, NULL /* netfid */, pInfo, &oplock,
 				full_path, cifs_sb->local_nls,
 				cifs_sb->mnt_cifs_flags &
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
-		if (rc) {
+		if (rc == -EOPNOTSUPP) {
+			kfree(pInfo);
+			goto mkdir_retry_old;
+		} else if (rc) {
 			cFYI(1, ("posix mkdir returned 0x%x", rc));
 			d_drop(direntry);
 		} else {
 			int obj_type;
-			if (pInfo->Type == -1) /* no return info - go query */
+			if (pInfo->Type == cpu_to_le32(-1)) {
+				/* no return info, go query for it */
+				kfree(pInfo);
 				goto mkdir_get_info;
+			}
 /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
 	to set uid/gid */
 			inc_nlink(inode);
@@ -940,8 +961,10 @@
 				direntry->d_op = &cifs_dentry_ops;
 
 			newinode = new_inode(inode->i_sb);
-			if (newinode == NULL)
+			if (newinode == NULL) {
+				kfree(pInfo);
 				goto mkdir_get_info;
+			}
 			/* Is an i_ino of zero legal? */
 			/* Are there sanity checks we can use to ensure that
 			   the server is really filling in that field? */
@@ -972,7 +995,7 @@
 		kfree(pInfo);
 		goto mkdir_out;
 	}
-
+mkdir_retry_old:
 	/* BB add setting the equivalent of mode via CreateX w/ACLs */
 	rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
 			  cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -1377,8 +1400,17 @@
 	}
 	i_size_write(inode, offset);
 	spin_unlock(&inode->i_lock);
+	/*
+	 * unmap_mapping_range is called twice, first simply for efficiency
+	 * so that truncate_inode_pages does fewer single-page unmaps. However
+	 * after this first call, and before truncate_inode_pages finishes,
+	 * it is possible for private pages to be COWed, which remain after
+	 * truncate_inode_pages finishes, hence the second unmap_mapping_range
+	 * call must be made for correctness.
+	 */
 	unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
 	truncate_inode_pages(mapping, offset);
+	unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
 	goto out_truncate;
 
 do_expand:
@@ -1469,7 +1501,7 @@
 			atomic_dec(&open_file->wrtPending);
 			cFYI(1, ("SetFSize for attrs rc = %d", rc));
 			if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
-				int bytes_written;
+				unsigned int bytes_written;
 				rc = CIFSSMBWrite(xid, pTcon,
 						  nfid, 0, attrs->ia_size,
 						  &bytes_written, NULL, NULL,
@@ -1502,7 +1534,7 @@
 					cifs_sb->mnt_cifs_flags &
 						CIFS_MOUNT_MAP_SPECIAL_CHR);
 				if (rc == 0) {
-					int bytes_written;
+					unsigned int bytes_written;
 					rc = CIFSSMBWrite(xid, pTcon,
 							netfid, 0,
 							attrs->ia_size,
@@ -1538,6 +1570,11 @@
 	}
 
 	time_buf.Attributes = 0;
+
+	/* skip mode change if it's just for clearing setuid/setgid */
+	if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
+		attrs->ia_valid &= ~ATTR_MODE;
+
 	if (attrs->ia_valid & ATTR_MODE) {
 		cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode));
 		mode = attrs->ia_mode;
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 6a85ef7..11f2657 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -237,7 +237,7 @@
 	char *tmp_path = NULL;
 	char *tmpbuffer;
 	unsigned char *referrals = NULL;
-	int num_referrals = 0;
+	unsigned int num_referrals = 0;
 	int len;
 	__u16 fid;
 
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 0bcec08..51ec681 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -169,7 +169,6 @@
 void
 cifs_buf_release(void *buf_to_free)
 {
-
 	if (buf_to_free == NULL) {
 		/* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/
 		return;
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 2bfed3f..f06359c 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -114,10 +114,16 @@
 	{ERRusempx, -EIO},
 	{ERRusestd, -EIO},
 	{ERR_NOTIFY_ENUM_DIR, -ENOBUFS},
-	{ERRaccountexpired, -EACCES},
+	{ERRnoSuchUser, -EACCES},
+/*	{ERRaccountexpired, -EACCES},
 	{ERRbadclient, -EACCES},
 	{ERRbadLogonTime, -EACCES},
-	{ERRpasswordExpired, -EACCES},
+	{ERRpasswordExpired, -EACCES},*/
+	{ERRaccountexpired, -EKEYEXPIRED},
+	{ERRbadclient, -EACCES},
+	{ERRbadLogonTime, -EACCES},
+	{ERRpasswordExpired, -EKEYEXPIRED},
+
 	{ERRnosupport, -EINVAL},
 	{0, 0}
 };
@@ -270,7 +276,7 @@
 	 from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE
 	 during the session setup } */
 	{
-	ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, {
+	ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { /* could map to 2238 */
 	ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, {
 	ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, {
 	ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, {
@@ -285,10 +291,10 @@
 	ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, {
 	ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, {
 	ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, {
-	ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, {
-	ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, {
+	ERRSRV, ERRbadLogonTime, NT_STATUS_INVALID_LOGON_HOURS}, {
+	ERRSRV, ERRbadclient, NT_STATUS_INVALID_WORKSTATION}, {
 	ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_EXPIRED}, {
-	ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, {
+	ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_DISABLED}, {
 	ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, {
 	ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, {
 	ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, {
@@ -585,7 +591,7 @@
 	ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, {
 	ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, {
 	ERRDOS, ERRnetlogonNotStarted, NT_STATUS_NETLOGON_NOT_STARTED}, {
-	ERRSRV, 2239, NT_STATUS_ACCOUNT_EXPIRED}, {
+	ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_EXPIRED}, {
 	ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, {
 	ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, {
 	ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, {
@@ -754,7 +760,7 @@
 }
 
 int
-map_smb_to_linux_error(struct smb_hdr *smb)
+map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
 {
 	unsigned int i;
 	int rc = -EIO;	/* if transport error smb error may not be set */
@@ -771,7 +777,9 @@
 		/* translate the newer STATUS codes to old style SMB errors
 		 * and then to POSIX errors */
 		__u32 err = le32_to_cpu(smb->Status.CifsError);
-		if (cifsFYI & CIFS_RC)
+		if (logErr && (err != (NT_STATUS_MORE_PROCESSING_REQUIRED)))
+			cifs_print_status(err);
+		else if (cifsFYI & CIFS_RC)
 			cifs_print_status(err);
 		ntstatus_to_dos(err, &smberrclass, &smberrcode);
 	} else {
@@ -813,7 +821,7 @@
 	}
 	/* else ERRHRD class errors or junk  - return EIO */
 
-	cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!",
+	cFYI(1, ("Mapping smb error code %d to POSIX err %d",
 		 smberrcode, rc));
 
 	/* generic corrective action e.g. reconnect SMB session on
@@ -899,8 +907,11 @@
 		cERROR(1, ("illegal hours %d", st->Hours));
 	days = sd->Day;
 	month = sd->Month;
-	if ((days > 31) || (month > 12))
+	if ((days > 31) || (month > 12)) {
 		cERROR(1, ("illegal date, month %d day: %d", month, days));
+		if (month > 12)
+			month = 12;
+	}
 	month -= 1;
 	days += total_days_of_prev_months[month];
 	days += 3652; /* account for difference in days between 1980 and 1970 */
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 916df94..3746580 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -121,7 +121,7 @@
 
 
 static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
-			  char *buf, int *pobject_type, int isNewInode)
+			  char *buf, unsigned int *pobject_type, int isNewInode)
 {
 	loff_t local_size;
 	struct timespec local_mtime;
@@ -294,7 +294,7 @@
 }
 
 static void unix_fill_in_inode(struct inode *tmp_inode,
-	FILE_UNIX_INFO *pfindData, int *pobject_type, int isNewInode)
+	FILE_UNIX_INFO *pfindData, unsigned int *pobject_type, int isNewInode)
 {
 	loff_t local_size;
 	struct timespec local_mtime;
@@ -826,7 +826,7 @@
 	int rc = 0;
 	struct qstr qstring;
 	struct cifsFileInfo *pCifsF;
-	unsigned obj_type;
+	unsigned int obj_type;
 	ino_t  inum;
 	struct cifs_sb_info *cifs_sb;
 	struct inode *tmp_inode;
@@ -1067,7 +1067,7 @@
 		for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
 			if (current_entry == NULL) {
 				/* evaluate whether this case is an error */
-				cERROR(1,("past end of SMB num to fill %d i %d",
+				cERROR(1, ("past SMB end,  num to fill %d i %d",
 					  num_to_fill, i));
 				break;
 			}
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 892be9b..899dc60 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -67,14 +67,59 @@
 		pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
 		capabilities |= CAP_DFS;
 	}
-	if (ses->capabilities & CAP_UNIX) {
+	if (ses->capabilities & CAP_UNIX)
 		capabilities |= CAP_UNIX;
-	}
 
 	/* BB check whether to init vcnum BB */
 	return capabilities;
 }
 
+static void
+unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
+{
+	char *bcc_ptr = *pbcc_area;
+	int bytes_ret = 0;
+
+	/* Copy OS version */
+	bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
+				  nls_cp);
+	bcc_ptr += 2 * bytes_ret;
+	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
+				  32, nls_cp);
+	bcc_ptr += 2 * bytes_ret;
+	bcc_ptr += 2; /* trailing null */
+
+	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
+				  32, nls_cp);
+	bcc_ptr += 2 * bytes_ret;
+	bcc_ptr += 2; /* trailing null */
+
+	*pbcc_area = bcc_ptr;
+}
+
+static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
+				   const struct nls_table *nls_cp)
+{
+	char *bcc_ptr = *pbcc_area;
+	int bytes_ret = 0;
+
+	/* copy domain */
+	if (ses->domainName == NULL) {
+		/* Sending null domain better than using a bogus domain name (as
+		we did briefly in 2.6.18) since server will use its default */
+		*bcc_ptr = 0;
+		*(bcc_ptr+1) = 0;
+		bytes_ret = 0;
+	} else
+		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
+					  256, nls_cp);
+	bcc_ptr += 2 * bytes_ret;
+	bcc_ptr += 2;  /* account for null terminator */
+
+	*pbcc_area = bcc_ptr;
+}
+
+
 static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
 				   const struct nls_table *nls_cp)
 {
@@ -100,32 +145,9 @@
 	}
 	bcc_ptr += 2 * bytes_ret;
 	bcc_ptr += 2; /* account for null termination */
-	/* copy domain */
-	if (ses->domainName == NULL) {
-		/* Sending null domain better than using a bogus domain name (as
-		we did briefly in 2.6.18) since server will use its default */
-		*bcc_ptr = 0;
-		*(bcc_ptr+1) = 0;
-		bytes_ret = 0;
-	} else
-		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
-					  256, nls_cp);
-	bcc_ptr += 2 * bytes_ret;
-	bcc_ptr += 2;  /* account for null terminator */
 
-	/* Copy OS version */
-	bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
-				  nls_cp);
-	bcc_ptr += 2 * bytes_ret;
-	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
-				  32, nls_cp);
-	bcc_ptr += 2 * bytes_ret;
-	bcc_ptr += 2; /* trailing null */
-
-	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
-				  32, nls_cp);
-	bcc_ptr += 2 * bytes_ret;
-	bcc_ptr += 2; /* trailing null */
+	unicode_domain_string(&bcc_ptr, ses, nls_cp);
+	unicode_oslm_strings(&bcc_ptr, nls_cp);
 
 	*pbcc_area = bcc_ptr;
 }
@@ -203,14 +225,11 @@
 	if (len >= words_left)
 		return rc;
 
-	if (ses->serverOS)
-		kfree(ses->serverOS);
+	kfree(ses->serverOS);
 	/* UTF-8 string will not grow more than four times as big as UCS-16 */
 	ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
-	if (ses->serverOS != NULL) {
-		cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len,
-				   nls_cp);
-	}
+	if (ses->serverOS != NULL)
+		cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
 	data += 2 * (len + 1);
 	words_left -= len + 1;
 
@@ -220,8 +239,7 @@
 	if (len >= words_left)
 		return rc;
 
-	if (ses->serverNOS)
-		kfree(ses->serverNOS);
+	kfree(ses->serverNOS);
 	ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
 	if (ses->serverNOS != NULL) {
 		cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
@@ -240,8 +258,7 @@
 	if (len > words_left)
 		return rc;
 
-	if (ses->serverDomain)
-		kfree(ses->serverDomain);
+	kfree(ses->serverDomain);
 	ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
 	if (ses->serverDomain != NULL) {
 		cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
@@ -271,8 +288,7 @@
 	if (len >= bleft)
 		return rc;
 
-	if (ses->serverOS)
-		kfree(ses->serverOS);
+	kfree(ses->serverOS);
 
 	ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
 	if (ses->serverOS)
@@ -289,8 +305,7 @@
 	if (len >= bleft)
 		return rc;
 
-	if (ses->serverNOS)
-		kfree(ses->serverNOS);
+	kfree(ses->serverNOS);
 
 	ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
 	if (ses->serverNOS)
@@ -479,7 +494,8 @@
 		if (ses->capabilities & CAP_UNICODE) {
 			if (iov[0].iov_len % 2) {
 				*bcc_ptr = 0;
-			}	bcc_ptr++;
+				bcc_ptr++;
+			}
 			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
 		} else
 			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
@@ -497,7 +513,8 @@
 
 	iov[1].iov_base = str_area;
 	iov[1].iov_len = count;
-	rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
+	rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
+			  0 /* not long op */, 1 /* log NT STATUS if any */ );
 	/* SMB request buf freed in SendReceive2 */
 
 	cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
diff --git a/fs/cifs/smberr.h b/fs/cifs/smberr.h
index 2ef0be2..7f50e85 100644
--- a/fs/cifs/smberr.h
+++ b/fs/cifs/smberr.h
@@ -173,9 +173,10 @@
 #define ERRusestd		251	/* temporarily unable to use either raw
 					   or mpx */
 #define ERR_NOTIFY_ENUM_DIR	1024
+#define ERRnoSuchUser		2238	/* user account does not exist */
 #define ERRaccountexpired	2239
-#define ERRbadclient		2240
-#define ERRbadLogonTime		2241
+#define ERRbadclient		2240	/* can not logon from this client */
+#define ERRbadLogonTime		2241	/* logon hours do not allow this */
 #define ERRpasswordExpired	2242
 #define ERRnetlogonNotStarted	2455
 #define ERRnosupport		0xFFFF
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 746bc94..7ed32b3 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -55,7 +55,7 @@
 	if (temp == NULL)
 		return temp;
 	else {
-		memset(temp, 0, sizeof (struct mid_q_entry));
+		memset(temp, 0, sizeof(struct mid_q_entry));
 		temp->mid = smb_buffer->Mid;	/* always LE */
 		temp->pid = current->pid;
 		temp->command = smb_buffer->Command;
@@ -158,7 +158,7 @@
 	iov.iov_len = len;
 
 	smb_msg.msg_name = sin;
-	smb_msg.msg_namelen = sizeof (struct sockaddr);
+	smb_msg.msg_namelen = sizeof(struct sockaddr);
 	smb_msg.msg_control = NULL;
 	smb_msg.msg_controllen = 0;
 	smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
@@ -228,7 +228,7 @@
 		return -ENOTSOCK; /* BB eventually add reconnect code here */
 
 	smb_msg.msg_name = sin;
-	smb_msg.msg_namelen = sizeof (struct sockaddr);
+	smb_msg.msg_namelen = sizeof(struct sockaddr);
 	smb_msg.msg_control = NULL;
 	smb_msg.msg_controllen = 0;
 	smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
@@ -363,9 +363,8 @@
 		} /* else ok - we are setting up session */
 	}
 	*ppmidQ = AllocMidQEntry(in_buf, ses);
-	if (*ppmidQ == NULL) {
+	if (*ppmidQ == NULL)
 		return -ENOMEM;
-	}
 	return 0;
 }
 
@@ -419,7 +418,7 @@
 int
 SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
 	     struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
-	     const int long_op)
+	     const int long_op, const int logError)
 {
 	int rc = 0;
 	unsigned int receive_len;
@@ -465,7 +464,6 @@
 		wake_up(&ses->server->request_q);
 		return rc;
 	}
-
 	rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
 
 	midQ->midState = MID_REQUEST_SUBMITTED;
@@ -568,13 +566,11 @@
 			}
 
 			/* BB special case reconnect tid and uid here? */
-			/* BB special case Errbadpassword and pwdexpired here */
-			rc = map_smb_to_linux_error(midQ->resp_buf);
+			rc = map_smb_to_linux_error(midQ->resp_buf, logError);
 
 			/* convert ByteCount if necessary */
-			if (receive_len >=
-			    sizeof (struct smb_hdr) -
-			    4 /* do not count RFC1001 header */  +
+			if (receive_len >= sizeof(struct smb_hdr) - 4
+			    /* do not count RFC1001 header */  +
 			    (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
 				BCC(midQ->resp_buf) =
 					le16_to_cpu(BCC_LE(midQ->resp_buf));
@@ -749,12 +745,11 @@
 			*pbytes_returned = out_buf->smb_buf_length;
 
 			/* BB special case reconnect tid and uid here? */
-			rc = map_smb_to_linux_error(out_buf);
+			rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
 
 			/* convert ByteCount if necessary */
-			if (receive_len >=
-			    sizeof (struct smb_hdr) -
-			    4 /* do not count RFC1001 header */  +
+			if (receive_len >= sizeof(struct smb_hdr) - 4
+			    /* do not count RFC1001 header */  +
 			    (2 * out_buf->WordCount) + 2 /* bcc */ )
 				BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
 		} else {
@@ -993,12 +988,11 @@
 			*pbytes_returned = out_buf->smb_buf_length;
 
 			/* BB special case reconnect tid and uid here? */
-			rc = map_smb_to_linux_error(out_buf);
+			rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
 
 			/* convert ByteCount if necessary */
-			if (receive_len >=
-			    sizeof (struct smb_hdr) -
-			    4 /* do not count RFC1001 header */  +
+			if (receive_len >= sizeof(struct smb_hdr) - 4
+			    /* do not count RFC1001 header */  +
 			    (2 * out_buf->WordCount) + 2 /* bcc */ )
 				BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
 		} else {
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index f61e433..369e838 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -261,21 +261,26 @@
 				cifs_sb->local_nls,
 				cifs_sb->mnt_cifs_flags &
 					CIFS_MOUNT_MAP_SPECIAL_CHR);
-/*		else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+		else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
 			__u16 fid;
 			int oplock = FALSE;
-			rc = CIFSSMBOpen(xid, pTcon, full_path,
-					 FILE_OPEN, GENERIC_READ, 0, &fid,
-					 &oplock, NULL, cifs_sb->local_nls,
-					 cifs_sb->mnt_cifs_flags &
-					 CIFS_MOUNT_MAP_SPECIAL_CHR);
+			if (experimEnabled) 
+				rc = CIFSSMBOpen(xid, pTcon, full_path,
+					FILE_OPEN, GENERIC_READ, 0, &fid,
+					&oplock, NULL, cifs_sb->local_nls,
+					cifs_sb->mnt_cifs_flags &
+					CIFS_MOUNT_MAP_SPECIAL_CHR);
+			/* else rc is EOPNOTSUPP from above */
+
 			if(rc == 0) {
 				rc = CIFSSMBGetCIFSACL(xid, pTcon, fid,
 					ea_value, buf_size,
 					ACL_TYPE_ACCESS);
 				CIFSSMBClose(xid, pTcon, fid);
 			}
-		} */  /* BB enable after fixing up return data */
+		}
+#endif /* EXPERIMENTAL */
 #else
 		cFYI(1, ("query POSIX ACL not supported yet"));
 #endif /* CONFIG_CIFS_POSIX */
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index cdb4c07..359e531 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -51,7 +51,7 @@
 
         inp->ih.opcode = opcode;
 	inp->ih.pid = current->pid;
-	inp->ih.pgid = process_group(current);
+	inp->ih.pgid = task_pgrp_nr(current);
 #ifdef CONFIG_CODA_FS_OLD_API
 	memset(&inp->ih.cred, 0, sizeof(struct coda_cred));
 	inp->ih.cred.cr_fsuid = current->fsuid;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 6dacd39..a4284cc 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -3001,7 +3001,7 @@
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(ioctl_start); i++) {
-		if (ioctl_start[i].next != 0) {
+		if (ioctl_start[i].next) {
 			printk("ioctl translation %d bad\n",i);
 			return -1;
 		}
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 5c817bd..350680f 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -148,7 +148,7 @@
 {
 	struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
 	struct page *pages[BLKS_PER_BUF];
-	unsigned i, blocknr, buffer, unread;
+	unsigned i, blocknr, buffer;
 	unsigned long devsize;
 	char *data;
 
@@ -175,7 +175,6 @@
 	devsize = mapping->host->i_size >> PAGE_CACHE_SHIFT;
 
 	/* Ok, read in BLKS_PER_BUF pages completely first. */
-	unread = 0;
 	for (i = 0; i < BLKS_PER_BUF; i++) {
 		struct page *page = NULL;
 
@@ -362,7 +361,7 @@
 	if (offset & 3)
 		return -EINVAL;
 
-	buf = kmalloc(256, GFP_KERNEL);
+	buf = kmalloc(CRAMFS_MAXPATHLEN, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
@@ -376,7 +375,7 @@
 		int namelen, error;
 
 		mutex_lock(&read_mutex);
-		de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+256);
+		de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN);
 		name = (char *)(de+1);
 
 		/*
@@ -426,7 +425,7 @@
 		char *name;
 		int namelen, retval;
 
-		de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+256);
+		de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN);
 		name = (char *)(de+1);
 
 		/* Try to take advantage of sorted directories */
diff --git a/fs/dcache.c b/fs/dcache.c
index 5489b2d..d9ca1e5 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -38,7 +38,7 @@
 EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
 
  __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock);
-static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
+__cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
 
 EXPORT_SYMBOL(dcache_lock);
 
@@ -1479,6 +1479,8 @@
 			 * dentry:internal, target:external.  Steal target's
 			 * storage and make target internal.
 			 */
+			memcpy(target->d_iname, dentry->d_name.name,
+					dentry->d_name.len + 1);
 			dentry->d_name.name = target->d_name.name;
 			target->d_name.name = target->d_iname;
 		}
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 11be8a3..6a713b3 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -413,7 +413,7 @@
 	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);
+		NULL, old_dentry);
 	fsnotify_oldname_free(old_name);
 	unlock_rename(new_dir, old_dir);
 	dput(dentry);
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 6438941..4f74154 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -456,7 +456,7 @@
 		printk(KERN_DEBUG "dlm: process %s (%d) version mismatch "
 		       "user (%d.%d.%d) kernel (%d.%d.%d)\n",
 		       current->comm,
-		       current->pid,
+		       task_pid_nr(current),
 		       req->version[0],
 		       req->version[1],
 		       req->version[2],
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 1ae90ef..0a9882e 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -283,7 +283,7 @@
 		pg = virt_to_page(addr);
 		offset = offset_in_page(addr);
 		if (sg) {
-			sg[i].page = pg;
+			sg_set_page(&sg[i], pg);
 			sg[i].offset = offset;
 		}
 		remainder_of_page = PAGE_CACHE_SIZE - offset;
@@ -713,10 +713,13 @@
 {
 	struct scatterlist src_sg, dst_sg;
 
-	src_sg.page = src_page;
+	sg_init_table(&src_sg, 1);
+	sg_init_table(&dst_sg, 1);
+
+	sg_set_page(&src_sg, src_page);
 	src_sg.offset = src_offset;
 	src_sg.length = size;
-	dst_sg.page = dst_page;
+	sg_set_page(&dst_sg, dst_page);
 	dst_sg.offset = dst_offset;
 	dst_sg.length = size;
 	return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
@@ -742,10 +745,13 @@
 {
 	struct scatterlist src_sg, dst_sg;
 
-	src_sg.page = src_page;
+	sg_init_table(&src_sg, 1);
+	sg_init_table(&dst_sg, 1);
+
+	sg_set_page(&src_sg, src_page);
 	src_sg.offset = src_offset;
 	src_sg.length = size;
-	dst_sg.page = dst_page;
+	sg_set_page(&dst_sg, dst_page);
 	dst_sg.offset = dst_offset;
 	dst_sg.length = size;
 	return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 5701f81..0b1ab01 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -914,6 +914,14 @@
 		if (rc < 0)
 			goto out;
 	}
+
+	/*
+	 * mode change is for clearing setuid/setgid bits. Allow lower fs
+	 * to interpret this in its own way.
+	 */
+	if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
+		ia->ia_valid &= ~ATTR_MODE;
+
 	rc = notify_change(lower_dentry, ia);
 out:
 	fsstack_copy_attr_all(inode, lower_inode, NULL);
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 89d9710..263fed8 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1040,6 +1040,9 @@
 	};
 	int rc = 0;
 
+	sg_init_table(&dst_sg, 1);
+	sg_init_table(&src_sg, 1);
+
 	if (unlikely(ecryptfs_verbosity > 0)) {
 		ecryptfs_printk(
 			KERN_DEBUG, "Session key encryption key (size [%d]):\n",
diff --git a/fs/efs/namei.c b/fs/efs/namei.c
index 5276b19..f7f4070 100644
--- a/fs/efs/namei.c
+++ b/fs/efs/namei.c
@@ -10,6 +10,8 @@
 #include <linux/string.h>
 #include <linux/efs_fs.h>
 #include <linux/smp_lock.h>
+#include <linux/exportfs.h>
+
 
 static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) {
 	struct buffer_head *bh;
@@ -75,13 +77,10 @@
 	return NULL;
 }
 
-struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *efs_nfs_get_inode(struct super_block *sb, u64 ino,
+		u32 generation)
 {
-	__u32 *objp = vobjp;
-	unsigned long ino = objp[0];
-	__u32 generation = objp[1];
 	struct inode *inode;
-	struct dentry *result;
 
 	if (ino == 0)
 		return ERR_PTR(-ESTALE);
@@ -91,20 +90,25 @@
 
 	if (is_bad_inode(inode) ||
 	    (generation && inode->i_generation != generation)) {
-	    	result = ERR_PTR(-ESTALE);
-		goto out_iput;
+		iput(inode);
+		return ERR_PTR(-ESTALE);
 	}
 
-	result = d_alloc_anon(inode);
-	if (!result) {
-		result = ERR_PTR(-ENOMEM);
-		goto out_iput;
-	}
-	return result;
+	return inode;
+}
 
- out_iput:
-	iput(inode);
-	return result;
+struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+				    efs_nfs_get_inode);
+}
+
+struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+				    efs_nfs_get_inode);
 }
 
 struct dentry *efs_get_parent(struct dentry *child)
diff --git a/fs/efs/super.c b/fs/efs/super.c
index 25d0326..c79bc62 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -113,8 +113,9 @@
 	.remount_fs	= efs_remount,
 };
 
-static struct export_operations efs_export_ops = {
-	.get_dentry	= efs_get_dentry,
+static const struct export_operations efs_export_ops = {
+	.fh_to_dentry	= efs_fh_to_dentry,
+	.fh_to_parent	= efs_fh_to_parent,
 	.get_parent	= efs_get_parent,
 };
 
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 77b9953..34f68f3 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -325,15 +325,14 @@
 	int wake_nests = 0;
 	unsigned long flags;
 	struct task_struct *this_task = current;
-	struct list_head *lsthead = &psw->wake_task_list, *lnk;
+	struct list_head *lsthead = &psw->wake_task_list;
 	struct wake_task_node *tncur;
 	struct wake_task_node tnode;
 
 	spin_lock_irqsave(&psw->lock, flags);
 
 	/* Try to see if the current task is already inside this wakeup call */
-	list_for_each(lnk, lsthead) {
-		tncur = list_entry(lnk, struct wake_task_node, llink);
+	list_for_each_entry(tncur, lsthead, llink) {
 
 		if (tncur->wq == wq ||
 		    (tncur->task == this_task && ++wake_nests > EP_MAX_POLLWAKE_NESTS)) {
@@ -463,7 +462,7 @@
 	 * holding "epmutex" we can be sure that no file cleanup code will hit
 	 * us during this operation. So we can avoid the lock on "ep->lock".
 	 */
-	while ((rbp = rb_first(&ep->rbr)) != 0) {
+	while ((rbp = rb_first(&ep->rbr)) != NULL) {
 		epi = rb_entry(rbp, struct epitem, rbn);
 		ep_remove(ep, epi);
 	}
diff --git a/fs/exec.c b/fs/exec.c
index 070ddf1..2c942e2 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -234,7 +234,7 @@
 	vma->vm_start = vma->vm_end - PAGE_SIZE;
 
 	vma->vm_flags = VM_STACK_FLAGS;
-	vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
+	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
 	err = insert_vm_struct(mm, vma);
 	if (err) {
 		up_write(&mm->mmap_sem);
@@ -775,8 +775,8 @@
 	 * Reparenting needs write_lock on tasklist_lock,
 	 * so it is safe to do it under read_lock.
 	 */
-	if (unlikely(tsk->group_leader == child_reaper(tsk)))
-		tsk->nsproxy->pid_ns->child_reaper = tsk;
+	if (unlikely(tsk->group_leader == task_child_reaper(tsk)))
+		task_active_pid_ns(tsk)->child_reaper = tsk;
 
 	zap_other_threads(tsk);
 	read_unlock(&tasklist_lock);
@@ -841,8 +841,8 @@
 		 */
 		tsk->start_time = leader->start_time;
 
-		BUG_ON(leader->tgid != tsk->tgid);
-		BUG_ON(tsk->pid == tsk->tgid);
+		BUG_ON(!same_thread_group(leader, tsk));
+		BUG_ON(has_group_leader_pid(tsk));
 		/*
 		 * An exec() starts a new thread group with the
 		 * TGID of the previous thread group. Rehash the
@@ -857,7 +857,7 @@
 		 */
 		detach_pid(tsk, PIDTYPE_PID);
 		tsk->pid = leader->pid;
-		attach_pid(tsk, PIDTYPE_PID,  find_pid(tsk->pid));
+		attach_pid(tsk, PIDTYPE_PID,  task_pid(leader));
 		transfer_pid(leader, tsk, PIDTYPE_PGID);
 		transfer_pid(leader, tsk, PIDTYPE_SID);
 		list_replace_rcu(&leader->tasks, &tsk->tasks);
@@ -1433,7 +1433,7 @@
 			case 'p':
 				pid_in_pattern = 1;
 				rc = snprintf(out_ptr, out_end - out_ptr,
-					      "%d", current->tgid);
+					      "%d", task_tgid_vnr(current));
 				if (rc > out_end - out_ptr)
 					goto out;
 				out_ptr += rc;
@@ -1513,7 +1513,7 @@
 	if (!ispipe && !pid_in_pattern
             && (core_uses_pid || atomic_read(&current->mm->mm_users) != 1)) {
 		rc = snprintf(out_ptr, out_end - out_ptr,
-			      ".%d", current->tgid);
+			      ".%d", task_tgid_vnr(current));
 		if (rc > out_end - out_ptr)
 			goto out;
 		out_ptr += rc;
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 8adb32a..109ab5e 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -1,4 +1,13 @@
-
+/*
+ * Copyright (C) Neil Brown 2002
+ * Copyright (C) Christoph Hellwig 2007
+ *
+ * This file contains the code mapping from inodes to NFS file handles,
+ * and for mapping back from file handles to dentries.
+ *
+ * For details on why we do all the strange and hairy things in here
+ * take a look at Documentation/filesystems/Exporting.
+ */
 #include <linux/exportfs.h>
 #include <linux/fs.h>
 #include <linux/file.h>
@@ -9,32 +18,19 @@
 #define dprintk(fmt, args...) do{}while(0)
 
 
-static int get_name(struct dentry *dentry, char *name,
+static int get_name(struct vfsmount *mnt, struct dentry *dentry, char *name,
 		struct dentry *child);
 
 
-static struct dentry *exportfs_get_dentry(struct super_block *sb, void *obj)
+static int exportfs_get_name(struct vfsmount *mnt, struct dentry *dir,
+		char *name, struct dentry *child)
 {
-	struct dentry *result = ERR_PTR(-ESTALE);
-
-	if (sb->s_export_op->get_dentry) {
-		result = sb->s_export_op->get_dentry(sb, obj);
-		if (!result)
-			result = ERR_PTR(-ESTALE);
-	}
-
-	return result;
-}
-
-static int exportfs_get_name(struct dentry *dir, char *name,
-		struct dentry *child)
-{
-	struct export_operations *nop = dir->d_sb->s_export_op;
+	const struct export_operations *nop = dir->d_sb->s_export_op;
 
 	if (nop->get_name)
 		return nop->get_name(dir, name, child);
 	else
-		return get_name(dir, name, child);
+		return get_name(mnt, dir, name, child);
 }
 
 /*
@@ -98,7 +94,7 @@
  * It may already be, as the flag isn't always updated when connection happens.
  */
 static int
-reconnect_path(struct super_block *sb, struct dentry *target_dir)
+reconnect_path(struct vfsmount *mnt, struct dentry *target_dir)
 {
 	char nbuf[NAME_MAX+1];
 	int noprogress = 0;
@@ -121,7 +117,7 @@
 			pd->d_flags &= ~DCACHE_DISCONNECTED;
 			spin_unlock(&pd->d_lock);
 			noprogress = 0;
-		} else if (pd == sb->s_root) {
+		} else if (pd == mnt->mnt_sb->s_root) {
 			printk(KERN_ERR "export: Eeek filesystem root is not connected, impossible\n");
 			spin_lock(&pd->d_lock);
 			pd->d_flags &= ~DCACHE_DISCONNECTED;
@@ -147,8 +143,8 @@
 			struct dentry *npd;
 
 			mutex_lock(&pd->d_inode->i_mutex);
-			if (sb->s_export_op->get_parent)
-				ppd = sb->s_export_op->get_parent(pd);
+			if (mnt->mnt_sb->s_export_op->get_parent)
+				ppd = mnt->mnt_sb->s_export_op->get_parent(pd);
 			mutex_unlock(&pd->d_inode->i_mutex);
 
 			if (IS_ERR(ppd)) {
@@ -161,7 +157,7 @@
 
 			dprintk("%s: find name of %lu in %lu\n", __FUNCTION__,
 				pd->d_inode->i_ino, ppd->d_inode->i_ino);
-			err = exportfs_get_name(ppd, nbuf, pd);
+			err = exportfs_get_name(mnt, ppd, nbuf, pd);
 			if (err) {
 				dput(ppd);
 				dput(pd);
@@ -214,125 +210,6 @@
 	return 0;
 }
 
-/**
- * find_exported_dentry - helper routine to implement export_operations->decode_fh
- * @sb:		The &super_block identifying the filesystem
- * @obj:	An opaque identifier of the object to be found - passed to
- *		get_inode
- * @parent:	An optional opqaue identifier of the parent of the object.
- * @acceptable:	A function used to test possible &dentries to see if they are
- *		acceptable
- * @context:	A parameter to @acceptable so that it knows on what basis to
- *		judge.
- *
- * find_exported_dentry is the central helper routine to enable file systems
- * to provide the decode_fh() export_operation.  It's main task is to take
- * an &inode, find or create an appropriate &dentry structure, and possibly
- * splice this into the dcache in the correct place.
- *
- * The decode_fh() operation provided by the filesystem should call
- * find_exported_dentry() with the same parameters that it received except
- * that instead of the file handle fragment, pointers to opaque identifiers
- * for the object and optionally its parent are passed.  The default decode_fh
- * routine passes one pointer to the start of the filehandle fragment, and
- * one 8 bytes into the fragment.  It is expected that most filesystems will
- * take this approach, though the offset to the parent identifier may well be
- * different.
- *
- * find_exported_dentry() will call get_dentry to get an dentry pointer from
- * the file system.  If any &dentry in the d_alias list is acceptable, it will
- * be returned.  Otherwise find_exported_dentry() will attempt to splice a new
- * &dentry into the dcache using get_name() and get_parent() to find the
- * appropriate place.
- */
-
-struct dentry *
-find_exported_dentry(struct super_block *sb, void *obj, void *parent,
-		     int (*acceptable)(void *context, struct dentry *de),
-		     void *context)
-{
-	struct dentry *result, *alias;
-	int err = -ESTALE;
-
-	/*
-	 * Attempt to find the inode.
-	 */
-	result = exportfs_get_dentry(sb, obj);
-	if (IS_ERR(result))
-		return result;
-
-	if (S_ISDIR(result->d_inode->i_mode)) {
-		if (!(result->d_flags & DCACHE_DISCONNECTED)) {
-			if (acceptable(context, result))
-				return result;
-			err = -EACCES;
-			goto err_result;
-		}
-
-		err = reconnect_path(sb, result);
-		if (err)
-			goto err_result;
-	} else {
-		struct dentry *target_dir, *nresult;
-		char nbuf[NAME_MAX+1];
-
-		alias = find_acceptable_alias(result, acceptable, context);
-		if (alias)
-			return alias;
-
-		if (parent == NULL)
-			goto err_result;
-
-		target_dir = exportfs_get_dentry(sb,parent);
-		if (IS_ERR(target_dir)) {
-			err = PTR_ERR(target_dir);
-			goto err_result;
-		}
-
-		err = reconnect_path(sb, target_dir);
-		if (err) {
-			dput(target_dir);
-			goto err_result;
-		}
-
-		/*
-		 * As we weren't after a directory, have one more step to go.
-		 */
-		err = exportfs_get_name(target_dir, nbuf, result);
-		if (!err) {
-			mutex_lock(&target_dir->d_inode->i_mutex);
-			nresult = lookup_one_len(nbuf, target_dir,
-						 strlen(nbuf));
-			mutex_unlock(&target_dir->d_inode->i_mutex);
-			if (!IS_ERR(nresult)) {
-				if (nresult->d_inode) {
-					dput(result);
-					result = nresult;
-				} else
-					dput(nresult);
-			}
-		}
-		dput(target_dir);
-	}
-
-	alias = find_acceptable_alias(result, acceptable, context);
-	if (alias)
-		return alias;
-
-	/* drat - I just cannot find anything acceptable */
-	dput(result);
-	/* It might be justifiable to return ESTALE here,
-	 * but the filehandle at-least looks reasonable good
-	 * and it may just be a permission problem, so returning
-	 * -EACCESS is safer
-	 */
-	return ERR_PTR(-EACCES);
-
- err_result:
-	dput(result);
-	return ERR_PTR(err);
-}
-
 struct getdents_callback {
 	char *name;		/* name that was found. It already points to a
 				   buffer NAME_MAX+1 is size */
@@ -370,8 +247,8 @@
  * calls readdir on the parent until it finds an entry with
  * the same inode number as the child, and returns that.
  */
-static int get_name(struct dentry *dentry, char *name,
-			struct dentry *child)
+static int get_name(struct vfsmount *mnt, struct dentry *dentry,
+		char *name, struct dentry *child)
 {
 	struct inode *dir = dentry->d_inode;
 	int error;
@@ -387,7 +264,7 @@
 	/*
 	 * Open the directory ...
 	 */
-	file = dentry_open(dget(dentry), NULL, O_RDONLY);
+	file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY);
 	error = PTR_ERR(file);
 	if (IS_ERR(file))
 		goto out;
@@ -434,100 +311,177 @@
  * can be used to check that it is still valid.  It places them in the
  * filehandle fragment where export_decode_fh expects to find them.
  */
-static int export_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
-		   int connectable)
+static int export_encode_fh(struct dentry *dentry, struct fid *fid,
+		int *max_len, int connectable)
 {
 	struct inode * inode = dentry->d_inode;
 	int len = *max_len;
-	int type = 1;
+	int type = FILEID_INO32_GEN;
 	
 	if (len < 2 || (connectable && len < 4))
 		return 255;
 
 	len = 2;
-	fh[0] = inode->i_ino;
-	fh[1] = inode->i_generation;
+	fid->i32.ino = inode->i_ino;
+	fid->i32.gen = inode->i_generation;
 	if (connectable && !S_ISDIR(inode->i_mode)) {
 		struct inode *parent;
 
 		spin_lock(&dentry->d_lock);
 		parent = dentry->d_parent->d_inode;
-		fh[2] = parent->i_ino;
-		fh[3] = parent->i_generation;
+		fid->i32.parent_ino = parent->i_ino;
+		fid->i32.parent_gen = parent->i_generation;
 		spin_unlock(&dentry->d_lock);
 		len = 4;
-		type = 2;
+		type = FILEID_INO32_GEN_PARENT;
 	}
 	*max_len = len;
 	return type;
 }
 
-
-/**
- * export_decode_fh - default export_operations->decode_fh function
- * @sb:  The superblock
- * @fh:  pointer to the file handle fragment
- * @fh_len: length of file handle fragment
- * @acceptable: function for testing acceptability of dentrys
- * @context:   context for @acceptable
- *
- * This is the default decode_fh() function.
- * a fileid_type of 1 indicates that the filehandlefragment
- * just contains an object identifier understood by  get_dentry.
- * a fileid_type of 2 says that there is also a directory
- * identifier 8 bytes in to the filehandlefragement.
- */
-static struct dentry *export_decode_fh(struct super_block *sb, __u32 *fh, int fh_len,
-			      int fileid_type,
-			 int (*acceptable)(void *context, struct dentry *de),
-			 void *context)
-{
-	__u32 parent[2];
-	parent[0] = parent[1] = 0;
-	if (fh_len < 2 || fileid_type > 2)
-		return NULL;
-	if (fileid_type == 2) {
-		if (fh_len > 2) parent[0] = fh[2];
-		if (fh_len > 3) parent[1] = fh[3];
-	}
-	return find_exported_dentry(sb, fh, parent,
-				   acceptable, context);
-}
-
-int exportfs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
+int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len,
 		int connectable)
 {
- 	struct export_operations *nop = dentry->d_sb->s_export_op;
+	const struct export_operations *nop = dentry->d_sb->s_export_op;
 	int error;
 
 	if (nop->encode_fh)
-		error = nop->encode_fh(dentry, fh, max_len, connectable);
+		error = nop->encode_fh(dentry, fid->raw, max_len, connectable);
 	else
-		error = export_encode_fh(dentry, fh, max_len, connectable);
+		error = export_encode_fh(dentry, fid, max_len, connectable);
 
 	return error;
 }
 EXPORT_SYMBOL_GPL(exportfs_encode_fh);
 
-struct dentry *exportfs_decode_fh(struct vfsmount *mnt, __u32 *fh, int fh_len,
-		int fileid_type, int (*acceptable)(void *, struct dentry *),
-		void *context)
+struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
+		int fh_len, int fileid_type,
+		int (*acceptable)(void *, struct dentry *), void *context)
 {
-	struct export_operations *nop = mnt->mnt_sb->s_export_op;
-	struct dentry *result;
+	const struct export_operations *nop = mnt->mnt_sb->s_export_op;
+	struct dentry *result, *alias;
+	int err;
 
-	if (nop->decode_fh) {
-		result = nop->decode_fh(mnt->mnt_sb, fh, fh_len, fileid_type,
-			acceptable, context);
+	/*
+	 * Try to get any dentry for the given file handle from the filesystem.
+	 */
+	result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
+	if (!result)
+		result = ERR_PTR(-ESTALE);
+	if (IS_ERR(result))
+		return result;
+
+	if (S_ISDIR(result->d_inode->i_mode)) {
+		/*
+		 * This request is for a directory.
+		 *
+		 * On the positive side there is only one dentry for each
+		 * directory inode.  On the negative side this implies that we
+		 * to ensure our dentry is connected all the way up to the
+		 * filesystem root.
+		 */
+		if (result->d_flags & DCACHE_DISCONNECTED) {
+			err = reconnect_path(mnt, result);
+			if (err)
+				goto err_result;
+		}
+
+		if (!acceptable(context, result)) {
+			err = -EACCES;
+			goto err_result;
+		}
+
+		return result;
 	} else {
-		result = export_decode_fh(mnt->mnt_sb, fh, fh_len, fileid_type,
-			acceptable, context);
+		/*
+		 * It's not a directory.  Life is a little more complicated.
+		 */
+		struct dentry *target_dir, *nresult;
+		char nbuf[NAME_MAX+1];
+
+		/*
+		 * See if either the dentry we just got from the filesystem
+		 * or any alias for it is acceptable.  This is always true
+		 * if this filesystem is exported without the subtreecheck
+		 * option.  If the filesystem is exported with the subtree
+		 * check option there's a fair chance we need to look at
+		 * the parent directory in the file handle and make sure
+		 * it's connected to the filesystem root.
+		 */
+		alias = find_acceptable_alias(result, acceptable, context);
+		if (alias)
+			return alias;
+
+		/*
+		 * Try to extract a dentry for the parent directory from the
+		 * file handle.  If this fails we'll have to give up.
+		 */
+		err = -ESTALE;
+		if (!nop->fh_to_parent)
+			goto err_result;
+
+		target_dir = nop->fh_to_parent(mnt->mnt_sb, fid,
+				fh_len, fileid_type);
+		if (!target_dir)
+			goto err_result;
+		err = PTR_ERR(target_dir);
+		if (IS_ERR(target_dir))
+			goto err_result;
+
+		/*
+		 * And as usual we need to make sure the parent directory is
+		 * connected to the filesystem root.  The VFS really doesn't
+		 * like disconnected directories..
+		 */
+		err = reconnect_path(mnt, target_dir);
+		if (err) {
+			dput(target_dir);
+			goto err_result;
+		}
+
+		/*
+		 * Now that we've got both a well-connected parent and a
+		 * dentry for the inode we're after, make sure that our
+		 * inode is actually connected to the parent.
+		 */
+		err = exportfs_get_name(mnt, target_dir, nbuf, result);
+		if (!err) {
+			mutex_lock(&target_dir->d_inode->i_mutex);
+			nresult = lookup_one_len(nbuf, target_dir,
+						 strlen(nbuf));
+			mutex_unlock(&target_dir->d_inode->i_mutex);
+			if (!IS_ERR(nresult)) {
+				if (nresult->d_inode) {
+					dput(result);
+					result = nresult;
+				} else
+					dput(nresult);
+			}
+		}
+
+		/*
+		 * At this point we are done with the parent, but it's pinned
+		 * by the child dentry anyway.
+		 */
+		dput(target_dir);
+
+		/*
+		 * And finally make sure the dentry is actually acceptable
+		 * to NFSD.
+		 */
+		alias = find_acceptable_alias(result, acceptable, context);
+		if (!alias) {
+			err = -EACCES;
+			goto err_result;
+		}
+
+		return alias;
 	}
 
-	return result;
+ err_result:
+	dput(result);
+	return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(exportfs_decode_fh);
 
-EXPORT_SYMBOL(find_exported_dentry);
-
 MODULE_LICENSE("GPL");
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 05d9342..d868e26 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -28,6 +28,24 @@
 
 typedef struct ext2_dir_entry_2 ext2_dirent;
 
+static inline unsigned ext2_rec_len_from_disk(__le16 dlen)
+{
+	unsigned len = le16_to_cpu(dlen);
+
+	if (len == EXT2_MAX_REC_LEN)
+		return 1 << 16;
+	return len;
+}
+
+static inline __le16 ext2_rec_len_to_disk(unsigned len)
+{
+	if (len == (1 << 16))
+		return cpu_to_le16(EXT2_MAX_REC_LEN);
+	else if (len > (1 << 16))
+		BUG();
+	return cpu_to_le16(len);
+}
+
 /*
  * ext2 uses block-sized chunks. Arguably, sector-sized ones would be
  * more robust, but we have what we have
@@ -106,7 +124,7 @@
 	}
 	for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
 		p = (ext2_dirent *)(kaddr + offs);
-		rec_len = le16_to_cpu(p->rec_len);
+		rec_len = ext2_rec_len_from_disk(p->rec_len);
 
 		if (rec_len < EXT2_DIR_REC_LEN(1))
 			goto Eshort;
@@ -204,7 +222,8 @@
  */
 static inline ext2_dirent *ext2_next_entry(ext2_dirent *p)
 {
-	return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len));
+	return (ext2_dirent *)((char *)p +
+			ext2_rec_len_from_disk(p->rec_len));
 }
 
 static inline unsigned 
@@ -316,7 +335,7 @@
 					return 0;
 				}
 			}
-			filp->f_pos += le16_to_cpu(de->rec_len);
+			filp->f_pos += ext2_rec_len_from_disk(de->rec_len);
 		}
 		ext2_put_page(page);
 	}
@@ -425,7 +444,7 @@
 {
 	loff_t pos = page_offset(page) +
 			(char *) de - (char *) page_address(page);
-	unsigned len = le16_to_cpu(de->rec_len);
+	unsigned len = ext2_rec_len_from_disk(de->rec_len);
 	int err;
 
 	lock_page(page);
@@ -482,7 +501,7 @@
 				/* We hit i_size */
 				name_len = 0;
 				rec_len = chunk_size;
-				de->rec_len = cpu_to_le16(chunk_size);
+				de->rec_len = ext2_rec_len_to_disk(chunk_size);
 				de->inode = 0;
 				goto got_it;
 			}
@@ -496,7 +515,7 @@
 			if (ext2_match (namelen, name, de))
 				goto out_unlock;
 			name_len = EXT2_DIR_REC_LEN(de->name_len);
-			rec_len = le16_to_cpu(de->rec_len);
+			rec_len = ext2_rec_len_from_disk(de->rec_len);
 			if (!de->inode && rec_len >= reclen)
 				goto got_it;
 			if (rec_len >= name_len + reclen)
@@ -518,8 +537,8 @@
 		goto out_unlock;
 	if (de->inode) {
 		ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
-		de1->rec_len = cpu_to_le16(rec_len - name_len);
-		de->rec_len = cpu_to_le16(name_len);
+		de1->rec_len = ext2_rec_len_to_disk(rec_len - name_len);
+		de->rec_len = ext2_rec_len_to_disk(name_len);
 		de = de1;
 	}
 	de->name_len = namelen;
@@ -550,7 +569,8 @@
 	struct inode *inode = mapping->host;
 	char *kaddr = page_address(page);
 	unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
-	unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
+	unsigned to = ((char *)dir - kaddr) +
+				ext2_rec_len_from_disk(dir->rec_len);
 	loff_t pos;
 	ext2_dirent * pde = NULL;
 	ext2_dirent * de = (ext2_dirent *) (kaddr + from);
@@ -574,7 +594,7 @@
 							&page, NULL);
 	BUG_ON(err);
 	if (pde)
-		pde->rec_len = cpu_to_le16(to - from);
+		pde->rec_len = ext2_rec_len_to_disk(to - from);
 	dir->inode = 0;
 	err = ext2_commit_chunk(page, pos, to - from);
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
@@ -610,14 +630,14 @@
 	memset(kaddr, 0, chunk_size);
 	de = (struct ext2_dir_entry_2 *)kaddr;
 	de->name_len = 1;
-	de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
+	de->rec_len = ext2_rec_len_to_disk(EXT2_DIR_REC_LEN(1));
 	memcpy (de->name, ".\0\0", 4);
 	de->inode = cpu_to_le32(inode->i_ino);
 	ext2_set_de_type (de, inode);
 
 	de = (struct ext2_dir_entry_2 *)(kaddr + EXT2_DIR_REC_LEN(1));
 	de->name_len = 2;
-	de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
+	de->rec_len = ext2_rec_len_to_disk(chunk_size - EXT2_DIR_REC_LEN(1));
 	de->inode = cpu_to_le32(parent->i_ino);
 	memcpy (de->name, "..\0", 4);
 	ext2_set_de_type (de, inode);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 77bd5f9..154e25f 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -311,13 +311,10 @@
 #endif
 };
 
-static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *ext2_nfs_get_inode(struct super_block *sb,
+		u64 ino, u32 generation)
 {
-	__u32 *objp = vobjp;
-	unsigned long ino = objp[0];
-	__u32 generation = objp[1];
 	struct inode *inode;
-	struct dentry *result;
 
 	if (ino < EXT2_FIRST_INO(sb) && ino != EXT2_ROOT_INO)
 		return ERR_PTR(-ESTALE);
@@ -338,15 +335,21 @@
 		iput(inode);
 		return ERR_PTR(-ESTALE);
 	}
-	/* now to find a dentry.
-	 * If possible, get a well-connected one
-	 */
-	result = d_alloc_anon(inode);
-	if (!result) {
-		iput(inode);
-		return ERR_PTR(-ENOMEM);
-	}
-	return result;
+	return inode;
+}
+
+static struct dentry *ext2_fh_to_dentry(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+				    ext2_nfs_get_inode);
+}
+
+static struct dentry *ext2_fh_to_parent(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+				    ext2_nfs_get_inode);
 }
 
 /* Yes, most of these are left as NULL!!
@@ -354,9 +357,10 @@
  * systems, but can be improved upon.
  * Currently only get_parent is required.
  */
-static struct export_operations ext2_export_ops = {
+static const struct export_operations ext2_export_ops = {
+	.fh_to_dentry = ext2_fh_to_dentry,
+	.fh_to_parent = ext2_fh_to_parent,
 	.get_parent = ext2_get_parent,
-	.get_dentry = ext2_get_dentry,
 };
 
 static unsigned long get_sb_block(void **data)
diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c
index dd1fd3c..a588e23 100644
--- a/fs/ext3/fsync.c
+++ b/fs/ext3/fsync.c
@@ -47,7 +47,7 @@
 	struct inode *inode = dentry->d_inode;
 	int ret = 0;
 
-	J_ASSERT(ext3_journal_current_handle() == 0);
+	J_ASSERT(ext3_journal_current_handle() == NULL);
 
 	/*
 	 * data=writeback:
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 2f2b686..9b162cd 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1028,7 +1028,7 @@
 		}
 		if (buffer_new(&dummy)) {
 			J_ASSERT(create != 0);
-			J_ASSERT(handle != 0);
+			J_ASSERT(handle != NULL);
 
 			/*
 			 * Now that we do not always journal data, we should
@@ -2954,7 +2954,7 @@
 		return 0;
 
 	if (ext3_journal_current_handle()) {
-		jbd_debug(0, "called recursively, non-PF_MEMALLOC!\n");
+		jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n");
 		dump_stack();
 		return -EIO;
 	}
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 771f7ad..44de145 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -245,10 +245,10 @@
 			brelse(gdb);
 			goto exit_bh;
 		}
-		lock_buffer(bh);
-		memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size);
+		lock_buffer(gdb);
+		memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size);
 		set_buffer_uptodate(gdb);
-		unlock_buffer(bh);
+		unlock_buffer(gdb);
 		ext3_journal_dirty_metadata(handle, gdb);
 		ext3_set_bit(bit, bh->b_data);
 		brelse(gdb);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 141573d..de55da9 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -631,13 +631,10 @@
 }
 
 
-static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *ext3_nfs_get_inode(struct super_block *sb,
+		u64 ino, u32 generation)
 {
-	__u32 *objp = vobjp;
-	unsigned long ino = objp[0];
-	__u32 generation = objp[1];
 	struct inode *inode;
-	struct dentry *result;
 
 	if (ino < EXT3_FIRST_INO(sb) && ino != EXT3_ROOT_INO)
 		return ERR_PTR(-ESTALE);
@@ -660,15 +657,22 @@
 		iput(inode);
 		return ERR_PTR(-ESTALE);
 	}
-	/* now to find a dentry.
-	 * If possible, get a well-connected one
-	 */
-	result = d_alloc_anon(inode);
-	if (!result) {
-		iput(inode);
-		return ERR_PTR(-ENOMEM);
-	}
-	return result;
+
+	return inode;
+}
+
+static struct dentry *ext3_fh_to_dentry(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+				    ext3_nfs_get_inode);
+}
+
+static struct dentry *ext3_fh_to_parent(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+				    ext3_nfs_get_inode);
 }
 
 #ifdef CONFIG_QUOTA
@@ -737,9 +741,10 @@
 #endif
 };
 
-static struct export_operations ext3_export_ops = {
+static const struct export_operations ext3_export_ops = {
+	.fh_to_dentry = ext3_fh_to_dentry,
+	.fh_to_parent = ext3_fh_to_parent,
 	.get_parent = ext3_get_parent,
-	.get_dentry = ext3_get_dentry,
 };
 
 enum {
@@ -1620,7 +1625,11 @@
 		}
 
 		brelse (bh);
-		sb_set_blocksize(sb, blocksize);
+		if (!sb_set_blocksize(sb, blocksize)) {
+			printk(KERN_ERR "EXT3-fs: bad blocksize %d.\n",
+				blocksize);
+			goto out_fail;
+		}
 		logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize;
 		offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize;
 		bh = sb_bread(sb, logic_sb_block);
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index f58cbb2..4083738 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -741,12 +741,11 @@
 		}
 	} else {
 		/* Allocate a buffer where we construct the new block. */
-		s->base = kmalloc(sb->s_blocksize, GFP_KERNEL);
+		s->base = kzalloc(sb->s_blocksize, GFP_KERNEL);
 		/* assert(header == s->base) */
 		error = -ENOMEM;
 		if (s->base == NULL)
 			goto cleanup;
-		memset(s->base, 0, sb->s_blocksize);
 		header(s->base)->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
 		header(s->base)->h_blocks = cpu_to_le32(1);
 		header(s->base)->h_refcount = cpu_to_le32(1);
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index b74bf43..e906b65 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -20,6 +20,7 @@
 #include <linux/quotaops.h>
 #include <linux/buffer_head.h>
 
+#include "group.h"
 /*
  * balloc.c contains the blocks allocation and deallocation routines
  */
@@ -42,6 +43,94 @@
 
 }
 
+/* Initializes an uninitialized block bitmap if given, and returns the
+ * number of blocks free in the group. */
+unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
+				int block_group, struct ext4_group_desc *gdp)
+{
+	unsigned long start;
+	int bit, bit_max;
+	unsigned free_blocks, group_blocks;
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+	if (bh) {
+		J_ASSERT_BH(bh, buffer_locked(bh));
+
+		/* If checksum is bad mark all blocks used to prevent allocation
+		 * essentially implementing a per-group read-only flag. */
+		if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
+			ext4_error(sb, __FUNCTION__,
+				   "Checksum bad for group %u\n", block_group);
+			gdp->bg_free_blocks_count = 0;
+			gdp->bg_free_inodes_count = 0;
+			gdp->bg_itable_unused = 0;
+			memset(bh->b_data, 0xff, sb->s_blocksize);
+			return 0;
+		}
+		memset(bh->b_data, 0, sb->s_blocksize);
+	}
+
+	/* Check for superblock and gdt backups in this group */
+	bit_max = ext4_bg_has_super(sb, block_group);
+
+	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) ||
+	    block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) *
+			  sbi->s_desc_per_block) {
+		if (bit_max) {
+			bit_max += ext4_bg_num_gdb(sb, block_group);
+			bit_max +=
+				le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks);
+		}
+	} else { /* For META_BG_BLOCK_GROUPS */
+		int group_rel = (block_group -
+				 le32_to_cpu(sbi->s_es->s_first_meta_bg)) %
+				EXT4_DESC_PER_BLOCK(sb);
+		if (group_rel == 0 || group_rel == 1 ||
+		    (group_rel == EXT4_DESC_PER_BLOCK(sb) - 1))
+			bit_max += 1;
+	}
+
+	if (block_group == sbi->s_groups_count - 1) {
+		/*
+		 * Even though mke2fs always initialize first and last group
+		 * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need
+		 * to make sure we calculate the right free blocks
+		 */
+		group_blocks = ext4_blocks_count(sbi->s_es) -
+			le32_to_cpu(sbi->s_es->s_first_data_block) -
+			(EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count -1));
+	} else {
+		group_blocks = EXT4_BLOCKS_PER_GROUP(sb);
+	}
+
+	free_blocks = group_blocks - bit_max;
+
+	if (bh) {
+		for (bit = 0; bit < bit_max; bit++)
+			ext4_set_bit(bit, bh->b_data);
+
+		start = block_group * EXT4_BLOCKS_PER_GROUP(sb) +
+			le32_to_cpu(sbi->s_es->s_first_data_block);
+
+		/* Set bits for block and inode bitmaps, and inode table */
+		ext4_set_bit(ext4_block_bitmap(sb, gdp) - start, bh->b_data);
+		ext4_set_bit(ext4_inode_bitmap(sb, gdp) - start, bh->b_data);
+		for (bit = (ext4_inode_table(sb, gdp) - start),
+		     bit_max = bit + sbi->s_itb_per_group; bit < bit_max; bit++)
+			ext4_set_bit(bit, bh->b_data);
+
+		/*
+		 * Also if the number of blocks within the group is
+		 * less than the blocksize * 8 ( which is the size
+		 * of bitmap ), set rest of the block bitmap to 1
+		 */
+		mark_bitmap_end(group_blocks, sb->s_blocksize * 8, bh->b_data);
+	}
+
+	return free_blocks - sbi->s_itb_per_group - 2;
+}
+
+
 /*
  * The free blocks are managed by bitmaps.  A file system contains several
  * blocks groups.  Each group contains 1 bitmap block for blocks, 1 bitmap
@@ -119,7 +208,7 @@
  *
  * Return buffer_head on success or NULL in case of failure.
  */
-static struct buffer_head *
+struct buffer_head *
 read_block_bitmap(struct super_block *sb, unsigned int block_group)
 {
 	int i;
@@ -127,11 +216,24 @@
 	struct buffer_head * bh = NULL;
 	ext4_fsblk_t bitmap_blk;
 
-	desc = ext4_get_group_desc (sb, block_group, NULL);
+	desc = ext4_get_group_desc(sb, block_group, NULL);
 	if (!desc)
 		return NULL;
 	bitmap_blk = ext4_block_bitmap(sb, desc);
-	bh = sb_bread(sb, bitmap_blk);
+	if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+		bh = sb_getblk(sb, bitmap_blk);
+		if (!buffer_uptodate(bh)) {
+			lock_buffer(bh);
+			if (!buffer_uptodate(bh)) {
+				ext4_init_block_bitmap(sb, bh, block_group,
+						       desc);
+				set_buffer_uptodate(bh);
+			}
+			unlock_buffer(bh);
+		}
+	} else {
+		bh = sb_bread(sb, bitmap_blk);
+	}
 	if (!bh)
 		ext4_error (sb, __FUNCTION__,
 			    "Cannot read block bitmap - "
@@ -627,6 +729,7 @@
 	desc->bg_free_blocks_count =
 		cpu_to_le16(le16_to_cpu(desc->bg_free_blocks_count) +
 			group_freed);
+	desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
 	spin_unlock(sb_bgl_lock(sbi, block_group));
 	percpu_counter_add(&sbi->s_freeblocks_counter, count);
 
@@ -1685,8 +1788,11 @@
 			ret_block, goal_hits, goal_attempts);
 
 	spin_lock(sb_bgl_lock(sbi, group_no));
+	if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))
+		gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
 	gdp->bg_free_blocks_count =
 			cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)-num);
+	gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp);
 	spin_unlock(sb_bgl_lock(sbi, group_no));
 	percpu_counter_sub(&sbi->s_freeblocks_counter, num);
 
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 0fb1e62..f612bef 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -47,9 +47,7 @@
 	.compat_ioctl	= ext4_compat_ioctl,
 #endif
 	.fsync		= ext4_sync_file,	/* BKL held */
-#ifdef CONFIG_EXT4_INDEX
 	.release	= ext4_release_dir,
-#endif
 };
 
 
@@ -107,7 +105,6 @@
 
 	sb = inode->i_sb;
 
-#ifdef CONFIG_EXT4_INDEX
 	if (EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
 				    EXT4_FEATURE_COMPAT_DIR_INDEX) &&
 	    ((EXT4_I(inode)->i_flags & EXT4_INDEX_FL) ||
@@ -123,7 +120,6 @@
 		 */
 		EXT4_I(filp->f_path.dentry->d_inode)->i_flags &= ~EXT4_INDEX_FL;
 	}
-#endif
 	stored = 0;
 	offset = filp->f_pos & (sb->s_blocksize - 1);
 
@@ -232,7 +228,6 @@
 	return ret;
 }
 
-#ifdef CONFIG_EXT4_INDEX
 /*
  * These functions convert from the major/minor hash to an f_pos
  * value.
@@ -518,5 +513,3 @@
 
 	return 0;
 }
-
-#endif
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 78beb09..8528774 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -33,7 +33,7 @@
 #include <linux/fs.h>
 #include <linux/time.h>
 #include <linux/ext4_jbd2.h>
-#include <linux/jbd.h>
+#include <linux/jbd2.h>
 #include <linux/highuid.h>
 #include <linux/pagemap.h>
 #include <linux/quotaops.h>
@@ -52,7 +52,7 @@
 {
 	ext4_fsblk_t block;
 
-	block = le32_to_cpu(ex->ee_start);
+	block = le32_to_cpu(ex->ee_start_lo);
 	block |= ((ext4_fsblk_t) le16_to_cpu(ex->ee_start_hi) << 31) << 1;
 	return block;
 }
@@ -65,7 +65,7 @@
 {
 	ext4_fsblk_t block;
 
-	block = le32_to_cpu(ix->ei_leaf);
+	block = le32_to_cpu(ix->ei_leaf_lo);
 	block |= ((ext4_fsblk_t) le16_to_cpu(ix->ei_leaf_hi) << 31) << 1;
 	return block;
 }
@@ -77,7 +77,7 @@
  */
 static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb)
 {
-	ex->ee_start = cpu_to_le32((unsigned long) (pb & 0xffffffff));
+	ex->ee_start_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
 	ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff);
 }
 
@@ -88,7 +88,7 @@
  */
 static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb)
 {
-	ix->ei_leaf = cpu_to_le32((unsigned long) (pb & 0xffffffff));
+	ix->ei_leaf_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
 	ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff);
 }
 
@@ -1409,8 +1409,7 @@
 	eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)+1);
 	nearex = path[depth].p_ext;
 	nearex->ee_block = newext->ee_block;
-	nearex->ee_start = newext->ee_start;
-	nearex->ee_start_hi = newext->ee_start_hi;
+	ext4_ext_store_pblock(nearex, ext_pblock(newext));
 	nearex->ee_len = newext->ee_len;
 
 merge:
@@ -2177,7 +2176,6 @@
 	}
 	/* ex2: iblock to iblock + maxblocks-1 : initialised */
 	ex2->ee_block = cpu_to_le32(iblock);
-	ex2->ee_start = cpu_to_le32(newblock);
 	ext4_ext_store_pblock(ex2, newblock);
 	ex2->ee_len = cpu_to_le16(allocated);
 	if (ex2 != ex)
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index 2a167d7..8d50879 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -47,7 +47,7 @@
 	struct inode *inode = dentry->d_inode;
 	int ret = 0;
 
-	J_ASSERT(ext4_journal_current_handle() == 0);
+	J_ASSERT(ext4_journal_current_handle() == NULL);
 
 	/*
 	 * data=writeback:
diff --git a/fs/ext4/group.h b/fs/ext4/group.h
new file mode 100644
index 0000000..1577910
--- /dev/null
+++ b/fs/ext4/group.h
@@ -0,0 +1,27 @@
+/*
+ *  linux/fs/ext4/group.h
+ *
+ * Copyright (C) 2007 Cluster File Systems, Inc
+ *
+ * Author: Andreas Dilger <adilger@clusterfs.com>
+ */
+
+#ifndef _LINUX_EXT4_GROUP_H
+#define _LINUX_EXT4_GROUP_H
+
+extern __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 group,
+				   struct ext4_group_desc *gdp);
+extern int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 group,
+				       struct ext4_group_desc *gdp);
+struct buffer_head *read_block_bitmap(struct super_block *sb,
+				      unsigned int block_group);
+extern unsigned ext4_init_block_bitmap(struct super_block *sb,
+				       struct buffer_head *bh, int group,
+				       struct ext4_group_desc *desc);
+#define ext4_free_blocks_after_init(sb, group, desc)			\
+		ext4_init_block_bitmap(sb, NULL, group, desc)
+extern unsigned ext4_init_inode_bitmap(struct super_block *sb,
+				       struct buffer_head *bh, int group,
+				       struct ext4_group_desc *desc);
+extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap);
+#endif /* _LINUX_EXT4_GROUP_H */
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index d0c7793..c61f37f 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -28,6 +28,7 @@
 
 #include "xattr.h"
 #include "acl.h"
+#include "group.h"
 
 /*
  * ialloc.c contains the inodes allocation and deallocation routines
@@ -43,6 +44,52 @@
  * the free blocks count in the block.
  */
 
+/*
+ * To avoid calling the atomic setbit hundreds or thousands of times, we only
+ * need to use it within a single byte (to ensure we get endianness right).
+ * We can use memset for the rest of the bitmap as there are no other users.
+ */
+void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
+{
+	int i;
+
+	if (start_bit >= end_bit)
+		return;
+
+	ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit);
+	for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
+		ext4_set_bit(i, bitmap);
+	if (i < end_bit)
+		memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
+}
+
+/* Initializes an uninitialized inode bitmap */
+unsigned ext4_init_inode_bitmap(struct super_block *sb,
+				struct buffer_head *bh, int block_group,
+				struct ext4_group_desc *gdp)
+{
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+	J_ASSERT_BH(bh, buffer_locked(bh));
+
+	/* If checksum is bad mark all blocks and inodes use to prevent
+	 * allocation, essentially implementing a per-group read-only flag. */
+	if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
+		ext4_error(sb, __FUNCTION__, "Checksum bad for group %u\n",
+			   block_group);
+		gdp->bg_free_blocks_count = 0;
+		gdp->bg_free_inodes_count = 0;
+		gdp->bg_itable_unused = 0;
+		memset(bh->b_data, 0xff, sb->s_blocksize);
+		return 0;
+	}
+
+	memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8);
+	mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb),
+			bh->b_data);
+
+	return EXT4_INODES_PER_GROUP(sb);
+}
 
 /*
  * Read the inode allocation bitmap for a given block_group, reading
@@ -59,8 +106,20 @@
 	desc = ext4_get_group_desc(sb, block_group, NULL);
 	if (!desc)
 		goto error_out;
-
-	bh = sb_bread(sb, ext4_inode_bitmap(sb, desc));
+	if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
+		bh = sb_getblk(sb, ext4_inode_bitmap(sb, desc));
+		if (!buffer_uptodate(bh)) {
+			lock_buffer(bh);
+			if (!buffer_uptodate(bh)) {
+				ext4_init_inode_bitmap(sb, bh, block_group,
+						       desc);
+				set_buffer_uptodate(bh);
+			}
+			unlock_buffer(bh);
+		}
+	} else {
+		bh = sb_bread(sb, ext4_inode_bitmap(sb, desc));
+	}
 	if (!bh)
 		ext4_error(sb, "read_inode_bitmap",
 			    "Cannot read inode bitmap - "
@@ -169,6 +228,8 @@
 			if (is_directory)
 				gdp->bg_used_dirs_count = cpu_to_le16(
 				  le16_to_cpu(gdp->bg_used_dirs_count) - 1);
+			gdp->bg_checksum = ext4_group_desc_csum(sbi,
+							block_group, gdp);
 			spin_unlock(sb_bgl_lock(sbi, block_group));
 			percpu_counter_inc(&sbi->s_freeinodes_counter);
 			if (is_directory)
@@ -435,7 +496,7 @@
 	struct ext4_sb_info *sbi;
 	int err = 0;
 	struct inode *ret;
-	int i;
+	int i, free = 0;
 
 	/* Cannot create files in a deleted directory */
 	if (!dir || !dir->i_nlink)
@@ -517,11 +578,13 @@
 	goto out;
 
 got:
-	ino += group * EXT4_INODES_PER_GROUP(sb) + 1;
-	if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
-		ext4_error (sb, "ext4_new_inode",
-			    "reserved inode or inode > inodes count - "
-			    "block_group = %d, inode=%lu", group, ino);
+	ino++;
+	if ((group == 0 && ino < EXT4_FIRST_INO(sb)) ||
+	    ino > EXT4_INODES_PER_GROUP(sb)) {
+		ext4_error(sb, __FUNCTION__,
+			   "reserved inode or inode > inodes count - "
+			   "block_group = %d, inode=%lu", group,
+			   ino + group * EXT4_INODES_PER_GROUP(sb));
 		err = -EIO;
 		goto fail;
 	}
@@ -529,13 +592,78 @@
 	BUFFER_TRACE(bh2, "get_write_access");
 	err = ext4_journal_get_write_access(handle, bh2);
 	if (err) goto fail;
+
+	/* We may have to initialize the block bitmap if it isn't already */
+	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM) &&
+	    gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+		struct buffer_head *block_bh = read_block_bitmap(sb, group);
+
+		BUFFER_TRACE(block_bh, "get block bitmap access");
+		err = ext4_journal_get_write_access(handle, block_bh);
+		if (err) {
+			brelse(block_bh);
+			goto fail;
+		}
+
+		free = 0;
+		spin_lock(sb_bgl_lock(sbi, group));
+		/* recheck and clear flag under lock if we still need to */
+		if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+			gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
+			free = ext4_free_blocks_after_init(sb, group, gdp);
+			gdp->bg_free_blocks_count = cpu_to_le16(free);
+		}
+		spin_unlock(sb_bgl_lock(sbi, group));
+
+		/* Don't need to dirty bitmap block if we didn't change it */
+		if (free) {
+			BUFFER_TRACE(block_bh, "dirty block bitmap");
+			err = ext4_journal_dirty_metadata(handle, block_bh);
+		}
+
+		brelse(block_bh);
+		if (err)
+			goto fail;
+	}
+
 	spin_lock(sb_bgl_lock(sbi, group));
+	/* If we didn't allocate from within the initialized part of the inode
+	 * table then we need to initialize up to this inode. */
+	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+		if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
+			gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
+
+			/* When marking the block group with
+			 * ~EXT4_BG_INODE_UNINIT we don't want to depend
+			 * on the value of bg_itable_unsed even though
+			 * mke2fs could have initialized the same for us.
+			 * Instead we calculated the value below
+			 */
+
+			free = 0;
+		} else {
+			free = EXT4_INODES_PER_GROUP(sb) -
+				le16_to_cpu(gdp->bg_itable_unused);
+		}
+
+		/*
+		 * Check the relative inode number against the last used
+		 * relative inode number in this group. if it is greater
+		 * we need to  update the bg_itable_unused count
+		 *
+		 */
+		if (ino > free)
+			gdp->bg_itable_unused =
+				cpu_to_le16(EXT4_INODES_PER_GROUP(sb) - ino);
+	}
+
 	gdp->bg_free_inodes_count =
 		cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1);
 	if (S_ISDIR(mode)) {
 		gdp->bg_used_dirs_count =
 			cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1);
 	}
+	gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
 	spin_unlock(sb_bgl_lock(sbi, group));
 	BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata");
 	err = ext4_journal_dirty_metadata(handle, bh2);
@@ -557,7 +685,7 @@
 		inode->i_gid = current->fsgid;
 	inode->i_mode = mode;
 
-	inode->i_ino = ino;
+	inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb);
 	/* This is the optimal IO size (for stat), not the fs block size */
 	inode->i_blocks = 0;
 	inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
@@ -573,11 +701,6 @@
 	/* dirsync only applies to directories */
 	if (!S_ISDIR(mode))
 		ei->i_flags &= ~EXT4_DIRSYNC_FL;
-#ifdef EXT4_FRAGMENTS
-	ei->i_faddr = 0;
-	ei->i_frag_no = 0;
-	ei->i_frag_size = 0;
-#endif
 	ei->i_file_acl = 0;
 	ei->i_dir_acl = 0;
 	ei->i_dtime = 0;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 0df2b1e..5489703 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1027,7 +1027,7 @@
 		}
 		if (buffer_new(&dummy)) {
 			J_ASSERT(create != 0);
-			J_ASSERT(handle != 0);
+			J_ASSERT(handle != NULL);
 
 			/*
 			 * Now that we do not always journal data, we should
@@ -2711,11 +2711,6 @@
 	}
 	inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
 	ei->i_flags = le32_to_cpu(raw_inode->i_flags);
-#ifdef EXT4_FRAGMENTS
-	ei->i_faddr = le32_to_cpu(raw_inode->i_faddr);
-	ei->i_frag_no = raw_inode->i_frag;
-	ei->i_frag_size = raw_inode->i_fsize;
-#endif
 	ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
 	if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
 	    cpu_to_le32(EXT4_OS_HURD))
@@ -2860,11 +2855,6 @@
 	raw_inode->i_blocks = cpu_to_le32(inode->i_blocks);
 	raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
 	raw_inode->i_flags = cpu_to_le32(ei->i_flags);
-#ifdef EXT4_FRAGMENTS
-	raw_inode->i_faddr = cpu_to_le32(ei->i_faddr);
-	raw_inode->i_frag = ei->i_frag_no;
-	raw_inode->i_fsize = ei->i_frag_size;
-#endif
 	if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
 	    cpu_to_le32(EXT4_OS_HURD))
 		raw_inode->i_file_acl_high =
@@ -3243,12 +3233,14 @@
 						      iloc, handle);
 			if (ret) {
 				EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND;
-				if (mnt_count != sbi->s_es->s_mnt_count) {
+				if (mnt_count !=
+					le16_to_cpu(sbi->s_es->s_mnt_count)) {
 					ext4_warning(inode->i_sb, __FUNCTION__,
 					"Unable to expand inode %lu. Delete"
 					" some EAs or run e2fsck.",
 					inode->i_ino);
-					mnt_count = sbi->s_es->s_mnt_count;
+					mnt_count =
+					  le16_to_cpu(sbi->s_es->s_mnt_count);
 				}
 			}
 		}
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 5fdb862..94ee6f3 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -144,7 +144,6 @@
 	u16 size;
 };
 
-#ifdef CONFIG_EXT4_INDEX
 static inline unsigned dx_get_block (struct dx_entry *entry);
 static void dx_set_block (struct dx_entry *entry, unsigned value);
 static inline unsigned dx_get_hash (struct dx_entry *entry);
@@ -766,8 +765,6 @@
 	dx_set_block(new, block);
 	dx_set_count(entries, count + 1);
 }
-#endif
-
 
 static void ext4_update_dx_flag(struct inode *inode)
 {
@@ -869,7 +866,6 @@
 	name = dentry->d_name.name;
 	if (namelen > EXT4_NAME_LEN)
 		return NULL;
-#ifdef CONFIG_EXT4_INDEX
 	if (is_dx(dir)) {
 		bh = ext4_dx_find_entry(dentry, res_dir, &err);
 		/*
@@ -881,7 +877,6 @@
 			return bh;
 		dxtrace(printk("ext4_find_entry: dx failed, falling back\n"));
 	}
-#endif
 	nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb);
 	start = EXT4_I(dir)->i_dir_start_lookup;
 	if (start >= nblocks)
@@ -957,7 +952,6 @@
 	return ret;
 }
 
-#ifdef CONFIG_EXT4_INDEX
 static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
 		       struct ext4_dir_entry_2 **res_dir, int *err)
 {
@@ -1025,7 +1019,6 @@
 	dx_release (frames);
 	return NULL;
 }
-#endif
 
 static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
 {
@@ -1121,7 +1114,6 @@
 		de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
 }
 
-#ifdef CONFIG_EXT4_INDEX
 /*
  * Move count entries from end of map between two memory locations.
  * Returns pointer to last entry moved.
@@ -1266,8 +1258,6 @@
 	*error = err;
 	return NULL;
 }
-#endif
-
 
 /*
  * Add a new entry into a directory (leaf) block.  If de is non-NULL,
@@ -1364,7 +1354,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_EXT4_INDEX
 /*
  * This converts a one block unindexed directory to a 3 block indexed
  * directory, and adds the dentry to the indexed directory.
@@ -1443,7 +1432,6 @@
 
 	return add_dirent_to_buf(handle, dentry, inode, de, bh);
 }
-#endif
 
 /*
  *	ext4_add_entry()
@@ -1464,9 +1452,7 @@
 	struct ext4_dir_entry_2 *de;
 	struct super_block * sb;
 	int	retval;
-#ifdef CONFIG_EXT4_INDEX
 	int	dx_fallback=0;
-#endif
 	unsigned blocksize;
 	u32 block, blocks;
 
@@ -1474,7 +1460,6 @@
 	blocksize = sb->s_blocksize;
 	if (!dentry->d_name.len)
 		return -EINVAL;
-#ifdef CONFIG_EXT4_INDEX
 	if (is_dx(dir)) {
 		retval = ext4_dx_add_entry(handle, dentry, inode);
 		if (!retval || (retval != ERR_BAD_DX_DIR))
@@ -1483,7 +1468,6 @@
 		dx_fallback++;
 		ext4_mark_inode_dirty(handle, dir);
 	}
-#endif
 	blocks = dir->i_size >> sb->s_blocksize_bits;
 	for (block = 0, offset = 0; block < blocks; block++) {
 		bh = ext4_bread(handle, dir, block, 0, &retval);
@@ -1493,11 +1477,9 @@
 		if (retval != -ENOSPC)
 			return retval;
 
-#ifdef CONFIG_EXT4_INDEX
 		if (blocks == 1 && !dx_fallback &&
 		    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
 			return make_indexed_dir(handle, dentry, inode, bh);
-#endif
 		brelse(bh);
 	}
 	bh = ext4_append(handle, dir, &block, &retval);
@@ -1509,7 +1491,6 @@
 	return add_dirent_to_buf(handle, dentry, inode, de, bh);
 }
 
-#ifdef CONFIG_EXT4_INDEX
 /*
  * Returns 0 for success, or a negative error value
  */
@@ -1644,7 +1625,6 @@
 	dx_release(frames);
 	return err;
 }
-#endif
 
 /*
  * ext4_delete_entry deletes a directory entry by merging it with the
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 472fc0d..bd8a52b 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -16,6 +16,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 
+#include "group.h"
 
 #define outside(b, first, last)	((b) < (first) || (b) >= (last))
 #define inside(b, first, last)	((b) >= (first) && (b) < (last))
@@ -140,22 +141,29 @@
 }
 
 /*
- * To avoid calling the atomic setbit hundreds or thousands of times, we only
- * need to use it within a single byte (to ensure we get endianness right).
- * We can use memset for the rest of the bitmap as there are no other users.
+ * If we have fewer than thresh credits, extend by EXT4_MAX_TRANS_DATA.
+ * If that fails, restart the transaction & regain write access for the
+ * buffer head which is used for block_bitmap modifications.
  */
-static void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
+static int extend_or_restart_transaction(handle_t *handle, int thresh,
+					 struct buffer_head *bh)
 {
-	int i;
+	int err;
 
-	if (start_bit >= end_bit)
-		return;
+	if (handle->h_buffer_credits >= thresh)
+		return 0;
 
-	ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit);
-	for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
-		ext4_set_bit(i, bitmap);
-	if (i < end_bit)
-		memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
+	err = ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA);
+	if (err < 0)
+		return err;
+	if (err) {
+		if ((err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA)))
+			return err;
+	        if ((err = ext4_journal_get_write_access(handle, bh)))
+			return err;
+        }
+
+	return 0;
 }
 
 /*
@@ -180,8 +188,9 @@
 	int i;
 	int err = 0, err2;
 
-	handle = ext4_journal_start_sb(sb, reserved_gdb + gdblocks +
-				       2 + sbi->s_itb_per_group);
+	/* This transaction may be extended/restarted along the way */
+	handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA);
+
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 
@@ -208,6 +217,9 @@
 
 		ext4_debug("update backup group %#04lx (+%d)\n", block, bit);
 
+		if ((err = extend_or_restart_transaction(handle, 1, bh)))
+			goto exit_bh;
+
 		gdb = sb_getblk(sb, block);
 		if (!gdb) {
 			err = -EIO;
@@ -217,10 +229,10 @@
 			brelse(gdb);
 			goto exit_bh;
 		}
-		lock_buffer(bh);
-		memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size);
+		lock_buffer(gdb);
+		memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size);
 		set_buffer_uptodate(gdb);
-		unlock_buffer(bh);
+		unlock_buffer(gdb);
 		ext4_journal_dirty_metadata(handle, gdb);
 		ext4_set_bit(bit, bh->b_data);
 		brelse(gdb);
@@ -233,6 +245,9 @@
 
 		ext4_debug("clear reserved block %#04lx (+%d)\n", block, bit);
 
+		if ((err = extend_or_restart_transaction(handle, 1, bh)))
+			goto exit_bh;
+
 		if (IS_ERR(gdb = bclean(handle, sb, block))) {
 			err = PTR_ERR(bh);
 			goto exit_bh;
@@ -254,6 +269,10 @@
 		struct buffer_head *it;
 
 		ext4_debug("clear inode block %#04lx (+%d)\n", block, bit);
+
+		if ((err = extend_or_restart_transaction(handle, 1, bh)))
+			goto exit_bh;
+
 		if (IS_ERR(it = bclean(handle, sb, block))) {
 			err = PTR_ERR(it);
 			goto exit_bh;
@@ -262,6 +281,10 @@
 		brelse(it);
 		ext4_set_bit(bit, bh->b_data);
 	}
+
+	if ((err = extend_or_restart_transaction(handle, 2, bh)))
+		goto exit_bh;
+
 	mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb),
 			bh->b_data);
 	ext4_journal_dirty_metadata(handle, bh);
@@ -289,7 +312,6 @@
 	return err;
 }
 
-
 /*
  * Iterate through the groups which hold BACKUP superblock/GDT copies in an
  * ext4 filesystem.  The counters should be initialized to 1, 5, and 7 before
@@ -842,6 +864,7 @@
 	ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */
 	gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count);
 	gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb));
+	gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp);
 
 	/*
 	 * Make the new blocks and inodes valid next.  We do this before
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 4c8d31c..8031dc0 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -37,12 +37,14 @@
 #include <linux/quotaops.h>
 #include <linux/seq_file.h>
 #include <linux/log2.h>
+#include <linux/crc16.h>
 
 #include <asm/uaccess.h>
 
 #include "xattr.h"
 #include "acl.h"
 #include "namei.h"
+#include "group.h"
 
 static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
 			     unsigned long journal_devnum);
@@ -68,31 +70,31 @@
 ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
 			       struct ext4_group_desc *bg)
 {
-	return le32_to_cpu(bg->bg_block_bitmap) |
+	return le32_to_cpu(bg->bg_block_bitmap_lo) |
 		(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
-		 (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0);
+		(ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0);
 }
 
 ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb,
 			       struct ext4_group_desc *bg)
 {
-	return le32_to_cpu(bg->bg_inode_bitmap) |
+	return le32_to_cpu(bg->bg_inode_bitmap_lo) |
 		(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
-		 (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0);
+		(ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0);
 }
 
 ext4_fsblk_t ext4_inode_table(struct super_block *sb,
 			      struct ext4_group_desc *bg)
 {
-	return le32_to_cpu(bg->bg_inode_table) |
+	return le32_to_cpu(bg->bg_inode_table_lo) |
 		(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
-		 (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
+		(ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
 }
 
 void ext4_block_bitmap_set(struct super_block *sb,
 			   struct ext4_group_desc *bg, ext4_fsblk_t blk)
 {
-	bg->bg_block_bitmap = cpu_to_le32((u32)blk);
+	bg->bg_block_bitmap_lo = cpu_to_le32((u32)blk);
 	if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
 		bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32);
 }
@@ -100,7 +102,7 @@
 void ext4_inode_bitmap_set(struct super_block *sb,
 			   struct ext4_group_desc *bg, ext4_fsblk_t blk)
 {
-	bg->bg_inode_bitmap  = cpu_to_le32((u32)blk);
+	bg->bg_inode_bitmap_lo  = cpu_to_le32((u32)blk);
 	if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
 		bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32);
 }
@@ -108,7 +110,7 @@
 void ext4_inode_table_set(struct super_block *sb,
 			  struct ext4_group_desc *bg, ext4_fsblk_t blk)
 {
-	bg->bg_inode_table = cpu_to_le32((u32)blk);
+	bg->bg_inode_table_lo = cpu_to_le32((u32)blk);
 	if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
 		bg->bg_inode_table_hi = cpu_to_le32(blk >> 32);
 }
@@ -684,13 +686,10 @@
 }
 
 
-static struct dentry *ext4_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *ext4_nfs_get_inode(struct super_block *sb,
+		u64 ino, u32 generation)
 {
-	__u32 *objp = vobjp;
-	unsigned long ino = objp[0];
-	__u32 generation = objp[1];
 	struct inode *inode;
-	struct dentry *result;
 
 	if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
 		return ERR_PTR(-ESTALE);
@@ -713,15 +712,22 @@
 		iput(inode);
 		return ERR_PTR(-ESTALE);
 	}
-	/* now to find a dentry.
-	 * If possible, get a well-connected one
-	 */
-	result = d_alloc_anon(inode);
-	if (!result) {
-		iput(inode);
-		return ERR_PTR(-ENOMEM);
-	}
-	return result;
+
+	return inode;
+}
+
+static struct dentry *ext4_fh_to_dentry(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+				    ext4_nfs_get_inode);
+}
+
+static struct dentry *ext4_fh_to_parent(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+				    ext4_nfs_get_inode);
 }
 
 #ifdef CONFIG_QUOTA
@@ -790,9 +796,10 @@
 #endif
 };
 
-static struct export_operations ext4_export_ops = {
+static const struct export_operations ext4_export_ops = {
+	.fh_to_dentry = ext4_fh_to_dentry,
+	.fh_to_parent = ext4_fh_to_parent,
 	.get_parent = ext4_get_parent,
-	.get_dentry = ext4_get_dentry,
 };
 
 enum {
@@ -1037,7 +1044,7 @@
 			if (option < 0)
 				return 0;
 			if (option == 0)
-				option = JBD_DEFAULT_MAX_COMMIT_AGE;
+				option = JBD2_DEFAULT_MAX_COMMIT_AGE;
 			sbi->s_commit_interval = HZ * option;
 			break;
 		case Opt_data_journal:
@@ -1308,6 +1315,43 @@
 	return res;
 }
 
+__le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
+			    struct ext4_group_desc *gdp)
+{
+	__u16 crc = 0;
+
+	if (sbi->s_es->s_feature_ro_compat &
+	    cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+		int offset = offsetof(struct ext4_group_desc, bg_checksum);
+		__le32 le_group = cpu_to_le32(block_group);
+
+		crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));
+		crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group));
+		crc = crc16(crc, (__u8 *)gdp, offset);
+		offset += sizeof(gdp->bg_checksum); /* skip checksum */
+		/* for checksum of struct ext4_group_desc do the rest...*/
+		if ((sbi->s_es->s_feature_incompat &
+		     cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT)) &&
+		    offset < le16_to_cpu(sbi->s_es->s_desc_size))
+			crc = crc16(crc, (__u8 *)gdp + offset,
+				    le16_to_cpu(sbi->s_es->s_desc_size) -
+					offset);
+	}
+
+	return cpu_to_le16(crc);
+}
+
+int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 block_group,
+				struct ext4_group_desc *gdp)
+{
+	if ((sbi->s_es->s_feature_ro_compat &
+	     cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) &&
+	    (gdp->bg_checksum != ext4_group_desc_csum(sbi, block_group, gdp)))
+		return 0;
+
+	return 1;
+}
+
 /* Called at mount-time, super-block is locked */
 static int ext4_check_descriptors (struct super_block * sb)
 {
@@ -1319,13 +1363,17 @@
 	ext4_fsblk_t inode_table;
 	struct ext4_group_desc * gdp = NULL;
 	int desc_block = 0;
+	int flexbg_flag = 0;
 	int i;
 
+	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
+		flexbg_flag = 1;
+
 	ext4_debug ("Checking group descriptors");
 
 	for (i = 0; i < sbi->s_groups_count; i++)
 	{
-		if (i == sbi->s_groups_count - 1)
+		if (i == sbi->s_groups_count - 1 || flexbg_flag)
 			last_block = ext4_blocks_count(sbi->s_es) - 1;
 		else
 			last_block = first_block +
@@ -1362,7 +1410,16 @@
 				    i, inode_table);
 			return 0;
 		}
-		first_block += EXT4_BLOCKS_PER_GROUP(sb);
+		if (!ext4_group_desc_csum_verify(sbi, i, gdp)) {
+			ext4_error(sb, __FUNCTION__,
+				   "Checksum for group %d failed (%u!=%u)\n", i,
+				   le16_to_cpu(ext4_group_desc_csum(sbi, i,
+								    gdp)),
+				   le16_to_cpu(gdp->bg_checksum));
+			return 0;
+		}
+		if (!flexbg_flag)
+			first_block += EXT4_BLOCKS_PER_GROUP(sb);
 		gdp = (struct ext4_group_desc *)
 			((__u8 *)gdp + EXT4_DESC_SIZE(sb));
 	}
@@ -1726,14 +1783,6 @@
 		if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE)
 			sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2);
 	}
-	sbi->s_frag_size = EXT4_MIN_FRAG_SIZE <<
-				   le32_to_cpu(es->s_log_frag_size);
-	if (blocksize != sbi->s_frag_size) {
-		printk(KERN_ERR
-		       "EXT4-fs: fragsize %lu != blocksize %u (unsupported)\n",
-		       sbi->s_frag_size, blocksize);
-		goto failed_mount;
-	}
 	sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
 	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) {
 		if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT ||
@@ -1747,7 +1796,6 @@
 	} else
 		sbi->s_desc_size = EXT4_MIN_DESC_SIZE;
 	sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
-	sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
 	sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
 	if (EXT4_INODE_SIZE(sb) == 0)
 		goto cantfind_ext4;
@@ -1771,12 +1819,6 @@
 			sbi->s_blocks_per_group);
 		goto failed_mount;
 	}
-	if (sbi->s_frags_per_group > blocksize * 8) {
-		printk (KERN_ERR
-			"EXT4-fs: #fragments per group too big: %lu\n",
-			sbi->s_frags_per_group);
-		goto failed_mount;
-	}
 	if (sbi->s_inodes_per_group > blocksize * 8) {
 		printk (KERN_ERR
 			"EXT4-fs: #inodes per group too big: %lu\n",
@@ -2630,7 +2672,7 @@
 
 	if (test_opt(sb, MINIX_DF)) {
 		sbi->s_overhead_last = 0;
-	} else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) {
+	} else if (sbi->s_blocks_last != ext4_blocks_count(es)) {
 		unsigned long ngroups = sbi->s_groups_count, i;
 		ext4_fsblk_t overhead = 0;
 		smp_rmb();
@@ -2665,14 +2707,14 @@
 		overhead += ngroups * (2 + sbi->s_itb_per_group);
 		sbi->s_overhead_last = overhead;
 		smp_wmb();
-		sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
+		sbi->s_blocks_last = ext4_blocks_count(es);
 	}
 
 	buf->f_type = EXT4_SUPER_MAGIC;
 	buf->f_bsize = sb->s_blocksize;
 	buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last;
 	buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter);
-	es->s_free_blocks_count = cpu_to_le32(buf->f_bfree);
+	ext4_free_blocks_count_set(es, buf->f_bfree);
 	buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es);
 	if (buf->f_bfree < ext4_r_blocks_count(es))
 		buf->f_bavail = 0;
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index b10d68f..8638730 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -750,12 +750,11 @@
 		}
 	} else {
 		/* Allocate a buffer where we construct the new block. */
-		s->base = kmalloc(sb->s_blocksize, GFP_KERNEL);
+		s->base = kzalloc(sb->s_blocksize, GFP_KERNEL);
 		/* assert(header == s->base) */
 		error = -ENOMEM;
 		if (s->base == NULL)
 			goto cleanup;
-		memset(s->base, 0, sb->s_blocksize);
 		header(s->base)->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
 		header(s->base)->h_blocks = cpu_to_le32(1);
 		header(s->base)->h_refcount = cpu_to_le32(1);
@@ -1121,7 +1120,7 @@
 	int total_ino, total_blk;
 	void *base, *start, *end;
 	int extra_isize = 0, error = 0, tried_min_extra_isize = 0;
-	int s_min_extra_isize = EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize;
+	int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
 
 	down_write(&EXT4_I(inode)->xattr_sem);
 retry:
@@ -1293,7 +1292,7 @@
 
 		i.name = b_entry_name;
 		i.value = buffer;
-		i.value_len = cpu_to_le32(size);
+		i.value_len = size;
 		error = ext4_xattr_block_find(inode, &i, bs);
 		if (error)
 			goto cleanup;
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index c0c5e9c..920a576e 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -653,24 +653,15 @@
  * of i_logstart is used to store the directory entry offset.
  */
 
-static struct dentry *
-fat_decode_fh(struct super_block *sb, __u32 *fh, int len, int fhtype,
-	      int (*acceptable)(void *context, struct dentry *de),
-	      void *context)
-{
-	if (fhtype != 3)
-		return ERR_PTR(-ESTALE);
-	if (len < 5)
-		return ERR_PTR(-ESTALE);
-
-	return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, context);
-}
-
-static struct dentry *fat_get_dentry(struct super_block *sb, void *inump)
+static struct dentry *fat_fh_to_dentry(struct super_block *sb,
+		struct fid *fid, int fh_len, int fh_type)
 {
 	struct inode *inode = NULL;
 	struct dentry *result;
-	__u32 *fh = inump;
+	u32 *fh = fid->raw;
+
+	if (fh_len < 5 || fh_type != 3)
+		return NULL;
 
 	inode = iget(sb, fh[0]);
 	if (!inode || is_bad_inode(inode) || inode->i_generation != fh[1]) {
@@ -783,10 +774,9 @@
 	return parent;
 }
 
-static struct export_operations fat_export_ops = {
-	.decode_fh	= fat_decode_fh,
+static const struct export_operations fat_export_ops = {
 	.encode_fh	= fat_encode_fh,
-	.get_dentry	= fat_get_dentry,
+	.fh_to_dentry	= fat_fh_to_dentry,
 	.get_parent	= fat_get_parent,
 };
 
diff --git a/fs/fcntl.c b/fs/fcntl.c
index c9db73f..8685263 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -18,6 +18,7 @@
 #include <linux/ptrace.h>
 #include <linux/signal.h>
 #include <linux/rcupdate.h>
+#include <linux/pid_namespace.h>
 
 #include <asm/poll.h>
 #include <asm/siginfo.h>
@@ -292,7 +293,7 @@
 		who = -who;
 	}
 	rcu_read_lock();
-	pid = find_pid(who);
+	pid = find_vpid(who);
 	result = __f_setown(filp, pid, type, force);
 	rcu_read_unlock();
 	return result;
@@ -308,7 +309,7 @@
 {
 	pid_t pid;
 	read_lock(&filp->f_owner.lock);
-	pid = pid_nr(filp->f_owner.pid);
+	pid = pid_nr_ns(filp->f_owner.pid, current->nsproxy->pid_ns);
 	if (filp->f_owner.pid_type == PIDTYPE_PGID)
 		pid = -pid;
 	read_unlock(&filp->f_owner.lock);
diff --git a/fs/file_table.c b/fs/file_table.c
index 3176fef..664e3f2 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -323,12 +323,11 @@
 
 int fs_may_remount_ro(struct super_block *sb)
 {
-	struct list_head *p;
+	struct file *file;
 
 	/* Check that no files are currently opened for writing. */
 	file_list_lock();
-	list_for_each(p, &sb->s_files) {
-		struct file *file = list_entry(p, struct file, f_u.fu_list);
+	list_for_each_entry(file, &sb->s_files, f_u.fu_list) {
 		struct inode *inode = file->f_path.dentry->d_inode;
 
 		/* File with pending delete? */
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 686734f..0fca820 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -89,7 +89,7 @@
 		if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev"))
 			printk(KERN_DEBUG
 			       "%s(%d): dirtied inode %lu (%s) on %s\n",
-			       current->comm, current->pid, inode->i_ino,
+			       current->comm, task_pid_nr(current), inode->i_ino,
 			       name, inode->i_sb->s_id);
 	}
 
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index d1acab9..3763757 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -63,13 +63,21 @@
  * Set dentry and possibly attribute timeouts from the lookup/mk*
  * replies
  */
-static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
+static void fuse_change_entry_timeout(struct dentry *entry,
+				      struct fuse_entry_out *o)
 {
 	fuse_dentry_settime(entry,
 		time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
-	if (entry->d_inode)
-		get_fuse_inode(entry->d_inode)->i_time =
-			time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
+}
+
+static u64 attr_timeout(struct fuse_attr_out *o)
+{
+	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
+}
+
+static u64 entry_attr_timeout(struct fuse_entry_out *o)
+{
+	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
 }
 
 /*
@@ -108,13 +116,19 @@
 			     struct dentry *entry,
 			     struct fuse_entry_out *outarg)
 {
+	struct fuse_conn *fc = get_fuse_conn(dir);
+
+	memset(outarg, 0, sizeof(struct fuse_entry_out));
 	req->in.h.opcode = FUSE_LOOKUP;
 	req->in.h.nodeid = get_node_id(dir);
 	req->in.numargs = 1;
 	req->in.args[0].size = entry->d_name.len + 1;
 	req->in.args[0].value = entry->d_name.name;
 	req->out.numargs = 1;
-	req->out.args[0].size = sizeof(struct fuse_entry_out);
+	if (fc->minor < 9)
+		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
+	else
+		req->out.args[0].size = sizeof(struct fuse_entry_out);
 	req->out.args[0].value = outarg;
 }
 
@@ -140,6 +154,7 @@
 		struct fuse_req *req;
 		struct fuse_req *forget_req;
 		struct dentry *parent;
+		u64 attr_version;
 
 		/* For negative dentries, always do a fresh lookup */
 		if (!inode)
@@ -156,6 +171,10 @@
 			return 0;
 		}
 
+		spin_lock(&fc->lock);
+		attr_version = fc->attr_version;
+		spin_unlock(&fc->lock);
+
 		parent = dget_parent(entry);
 		fuse_lookup_init(req, parent->d_inode, entry, &outarg);
 		request_send(fc, req);
@@ -180,8 +199,10 @@
 		if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
 			return 0;
 
-		fuse_change_attributes(inode, &outarg.attr);
-		fuse_change_timeout(entry, &outarg);
+		fuse_change_attributes(inode, &outarg.attr,
+				       entry_attr_timeout(&outarg),
+				       attr_version);
+		fuse_change_entry_timeout(entry, &outarg);
 	}
 	return 1;
 }
@@ -228,6 +249,7 @@
 	struct fuse_conn *fc = get_fuse_conn(dir);
 	struct fuse_req *req;
 	struct fuse_req *forget_req;
+	u64 attr_version;
 
 	if (entry->d_name.len > FUSE_NAME_MAX)
 		return ERR_PTR(-ENAMETOOLONG);
@@ -242,6 +264,10 @@
 		return ERR_PTR(PTR_ERR(forget_req));
 	}
 
+	spin_lock(&fc->lock);
+	attr_version = fc->attr_version;
+	spin_unlock(&fc->lock);
+
 	fuse_lookup_init(req, dir, entry, &outarg);
 	request_send(fc, req);
 	err = req->out.h.error;
@@ -253,7 +279,8 @@
 		err = -EIO;
 	if (!err && outarg.nodeid) {
 		inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
-				  &outarg.attr);
+				  &outarg.attr, entry_attr_timeout(&outarg),
+				  attr_version);
 		if (!inode) {
 			fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
 			return ERR_PTR(-ENOMEM);
@@ -276,7 +303,7 @@
 
 	entry->d_op = &fuse_dentry_operations;
 	if (!err)
-		fuse_change_timeout(entry, &outarg);
+		fuse_change_entry_timeout(entry, &outarg);
 	else
 		fuse_invalidate_entry_cache(entry);
 	return NULL;
@@ -335,6 +362,7 @@
 
 	flags &= ~O_NOCTTY;
 	memset(&inarg, 0, sizeof(inarg));
+	memset(&outentry, 0, sizeof(outentry));
 	inarg.flags = flags;
 	inarg.mode = mode;
 	req->in.h.opcode = FUSE_CREATE;
@@ -345,7 +373,10 @@
 	req->in.args[1].size = entry->d_name.len + 1;
 	req->in.args[1].value = entry->d_name.name;
 	req->out.numargs = 2;
-	req->out.args[0].size = sizeof(outentry);
+	if (fc->minor < 9)
+		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
+	else
+		req->out.args[0].size = sizeof(outentry);
 	req->out.args[0].value = &outentry;
 	req->out.args[1].size = sizeof(outopen);
 	req->out.args[1].value = &outopen;
@@ -363,7 +394,7 @@
 
 	fuse_put_request(fc, req);
 	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
-			  &outentry.attr);
+			  &outentry.attr, entry_attr_timeout(&outentry), 0);
 	if (!inode) {
 		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
 		ff->fh = outopen.fh;
@@ -373,7 +404,7 @@
 	}
 	fuse_put_request(fc, forget_req);
 	d_instantiate(entry, inode);
-	fuse_change_timeout(entry, &outentry);
+	fuse_change_entry_timeout(entry, &outentry);
 	file = lookup_instantiate_filp(nd, entry, generic_file_open);
 	if (IS_ERR(file)) {
 		ff->fh = outopen.fh;
@@ -410,9 +441,13 @@
 		return PTR_ERR(forget_req);
 	}
 
+	memset(&outarg, 0, sizeof(outarg));
 	req->in.h.nodeid = get_node_id(dir);
 	req->out.numargs = 1;
-	req->out.args[0].size = sizeof(outarg);
+	if (fc->minor < 9)
+		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
+	else
+		req->out.args[0].size = sizeof(outarg);
 	req->out.args[0].value = &outarg;
 	request_send(fc, req);
 	err = req->out.h.error;
@@ -428,7 +463,7 @@
 		goto out_put_forget_req;
 
 	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
-			  &outarg.attr);
+			  &outarg.attr, entry_attr_timeout(&outarg), 0);
 	if (!inode) {
 		fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
 		return -ENOMEM;
@@ -451,7 +486,7 @@
 	} else
 		d_instantiate(entry, inode);
 
-	fuse_change_timeout(entry, &outarg);
+	fuse_change_entry_timeout(entry, &outarg);
 	fuse_invalidate_attr(dir);
 	return 0;
 
@@ -663,52 +698,84 @@
 	return err;
 }
 
-static int fuse_do_getattr(struct inode *inode)
+static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
+			  struct kstat *stat)
+{
+	stat->dev = inode->i_sb->s_dev;
+	stat->ino = attr->ino;
+	stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
+	stat->nlink = attr->nlink;
+	stat->uid = attr->uid;
+	stat->gid = attr->gid;
+	stat->rdev = inode->i_rdev;
+	stat->atime.tv_sec = attr->atime;
+	stat->atime.tv_nsec = attr->atimensec;
+	stat->mtime.tv_sec = attr->mtime;
+	stat->mtime.tv_nsec = attr->mtimensec;
+	stat->ctime.tv_sec = attr->ctime;
+	stat->ctime.tv_nsec = attr->ctimensec;
+	stat->size = attr->size;
+	stat->blocks = attr->blocks;
+	stat->blksize = (1 << inode->i_blkbits);
+}
+
+static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
+			   struct file *file)
 {
 	int err;
-	struct fuse_attr_out arg;
+	struct fuse_getattr_in inarg;
+	struct fuse_attr_out outarg;
 	struct fuse_conn *fc = get_fuse_conn(inode);
-	struct fuse_req *req = fuse_get_req(fc);
+	struct fuse_req *req;
+	u64 attr_version;
+
+	req = fuse_get_req(fc);
 	if (IS_ERR(req))
 		return PTR_ERR(req);
 
+	spin_lock(&fc->lock);
+	attr_version = fc->attr_version;
+	spin_unlock(&fc->lock);
+
+	memset(&inarg, 0, sizeof(inarg));
+	memset(&outarg, 0, sizeof(outarg));
+	/* Directories have separate file-handle space */
+	if (file && S_ISREG(inode->i_mode)) {
+		struct fuse_file *ff = file->private_data;
+
+		inarg.getattr_flags |= FUSE_GETATTR_FH;
+		inarg.fh = ff->fh;
+	}
 	req->in.h.opcode = FUSE_GETATTR;
 	req->in.h.nodeid = get_node_id(inode);
+	req->in.numargs = 1;
+	req->in.args[0].size = sizeof(inarg);
+	req->in.args[0].value = &inarg;
 	req->out.numargs = 1;
-	req->out.args[0].size = sizeof(arg);
-	req->out.args[0].value = &arg;
+	if (fc->minor < 9)
+		req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
+	else
+		req->out.args[0].size = sizeof(outarg);
+	req->out.args[0].value = &outarg;
 	request_send(fc, req);
 	err = req->out.h.error;
 	fuse_put_request(fc, req);
 	if (!err) {
-		if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
+		if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
 			make_bad_inode(inode);
 			err = -EIO;
 		} else {
-			struct fuse_inode *fi = get_fuse_inode(inode);
-			fuse_change_attributes(inode, &arg.attr);
-			fi->i_time = time_to_jiffies(arg.attr_valid,
-						     arg.attr_valid_nsec);
+			fuse_change_attributes(inode, &outarg.attr,
+					       attr_timeout(&outarg),
+					       attr_version);
+			if (stat)
+				fuse_fillattr(inode, &outarg.attr, stat);
 		}
 	}
 	return err;
 }
 
 /*
- * Check if attributes are still valid, and if not send a GETATTR
- * request to refresh them.
- */
-static int fuse_refresh_attributes(struct inode *inode)
-{
-	struct fuse_inode *fi = get_fuse_inode(inode);
-
-	if (fi->i_time < get_jiffies_64())
-		return fuse_do_getattr(inode);
-	else
-		return 0;
-}
-
-/*
  * Calling into a user-controlled filesystem gives the filesystem
  * daemon ptrace-like capabilities over the requester process.  This
  * means, that the filesystem daemon is able to record the exact
@@ -721,7 +788,7 @@
  * for which the owner of the mount has ptrace privilege.  This
  * excludes processes started by other users, suid or sgid processes.
  */
-static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
+int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
 {
 	if (fc->flags & FUSE_ALLOW_OTHER)
 		return 1;
@@ -795,11 +862,14 @@
 	 */
 	if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
 	    ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
-		err = fuse_refresh_attributes(inode);
-		if (err)
-			return err;
+		struct fuse_inode *fi = get_fuse_inode(inode);
+		if (fi->i_time < get_jiffies_64()) {
+			err = fuse_do_getattr(inode, NULL, NULL);
+			if (err)
+				return err;
 
-		refreshed = true;
+			refreshed = true;
+		}
 	}
 
 	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
@@ -809,7 +879,7 @@
 		   attributes.  This is also needed, because the root
 		   node will at first have no permissions */
 		if (err == -EACCES && !refreshed) {
-		 	err = fuse_do_getattr(inode);
+			err = fuse_do_getattr(inode, NULL, NULL);
 			if (!err)
 				err = generic_permission(inode, mask, NULL);
 		}
@@ -825,7 +895,7 @@
 			if (refreshed)
 				return -EACCES;
 
-			err = fuse_do_getattr(inode);
+			err = fuse_do_getattr(inode, NULL, NULL);
 			if (!err && !(inode->i_mode & S_IXUGO))
 				return -EACCES;
 		}
@@ -962,6 +1032,20 @@
 	return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
 }
 
+static bool update_mtime(unsigned ivalid)
+{
+	/* Always update if mtime is explicitly set  */
+	if (ivalid & ATTR_MTIME_SET)
+		return true;
+
+	/* If it's an open(O_TRUNC) or an ftruncate(), don't update */
+	if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
+		return false;
+
+	/* In all other cases update */
+	return true;
+}
+
 static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
 {
 	unsigned ivalid = iattr->ia_valid;
@@ -974,16 +1058,19 @@
 		arg->valid |= FATTR_GID,    arg->gid = iattr->ia_gid;
 	if (ivalid & ATTR_SIZE)
 		arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
-	/* You can only _set_ these together (they may change by themselves) */
-	if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
-		arg->valid |= FATTR_ATIME | FATTR_MTIME;
+	if (ivalid & ATTR_ATIME) {
+		arg->valid |= FATTR_ATIME;
 		arg->atime = iattr->ia_atime.tv_sec;
-		arg->mtime = iattr->ia_mtime.tv_sec;
+		arg->atimensec = iattr->ia_atime.tv_nsec;
+		if (!(ivalid & ATTR_ATIME_SET))
+			arg->valid |= FATTR_ATIME_NOW;
 	}
-	if (ivalid & ATTR_FILE) {
-		struct fuse_file *ff = iattr->ia_file->private_data;
-		arg->valid |= FATTR_FH;
-		arg->fh = ff->fh;
+	if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
+		arg->valid |= FATTR_MTIME;
+		arg->mtime = iattr->ia_mtime.tv_sec;
+		arg->mtimensec = iattr->ia_mtime.tv_nsec;
+		if (!(ivalid & ATTR_MTIME_SET))
+			arg->valid |= FATTR_MTIME_NOW;
 	}
 }
 
@@ -995,22 +1082,28 @@
  * vmtruncate() doesn't allow for this case, so do the rlimit checking
  * and the actual truncation by hand.
  */
-static int fuse_setattr(struct dentry *entry, struct iattr *attr)
+static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
+			   struct file *file)
 {
 	struct inode *inode = entry->d_inode;
 	struct fuse_conn *fc = get_fuse_conn(inode);
-	struct fuse_inode *fi = get_fuse_inode(inode);
 	struct fuse_req *req;
 	struct fuse_setattr_in inarg;
 	struct fuse_attr_out outarg;
 	int err;
 
+	if (!fuse_allow_task(fc, current))
+		return -EACCES;
+
 	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
 		err = inode_change_ok(inode, attr);
 		if (err)
 			return err;
 	}
 
+	if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc)
+		return 0;
+
 	if (attr->ia_valid & ATTR_SIZE) {
 		unsigned long limit;
 		if (IS_SWAPFILE(inode))
@@ -1027,14 +1120,28 @@
 		return PTR_ERR(req);
 
 	memset(&inarg, 0, sizeof(inarg));
+	memset(&outarg, 0, sizeof(outarg));
 	iattr_to_fattr(attr, &inarg);
+	if (file) {
+		struct fuse_file *ff = file->private_data;
+		inarg.valid |= FATTR_FH;
+		inarg.fh = ff->fh;
+	}
+	if (attr->ia_valid & ATTR_SIZE) {
+		/* For mandatory locking in truncate */
+		inarg.valid |= FATTR_LOCKOWNER;
+		inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
+	}
 	req->in.h.opcode = FUSE_SETATTR;
 	req->in.h.nodeid = get_node_id(inode);
 	req->in.numargs = 1;
 	req->in.args[0].size = sizeof(inarg);
 	req->in.args[0].value = &inarg;
 	req->out.numargs = 1;
-	req->out.args[0].size = sizeof(outarg);
+	if (fc->minor < 9)
+		req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
+	else
+		req->out.args[0].size = sizeof(outarg);
 	req->out.args[0].value = &outarg;
 	request_send(fc, req);
 	err = req->out.h.error;
@@ -1050,11 +1157,18 @@
 		return -EIO;
 	}
 
-	fuse_change_attributes(inode, &outarg.attr);
-	fi->i_time = time_to_jiffies(outarg.attr_valid, outarg.attr_valid_nsec);
+	fuse_change_attributes(inode, &outarg.attr, attr_timeout(&outarg), 0);
 	return 0;
 }
 
+static int fuse_setattr(struct dentry *entry, struct iattr *attr)
+{
+	if (attr->ia_valid & ATTR_FILE)
+		return fuse_do_setattr(entry, attr, attr->ia_file);
+	else
+		return fuse_do_setattr(entry, attr, NULL);
+}
+
 static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
 			struct kstat *stat)
 {
@@ -1066,8 +1180,10 @@
 	if (!fuse_allow_task(fc, current))
 		return -EACCES;
 
-	err = fuse_refresh_attributes(inode);
-	if (!err) {
+	if (fi->i_time < get_jiffies_64())
+		err = fuse_do_getattr(inode, stat, NULL);
+	else {
+		err = 0;
 		generic_fillattr(inode, stat);
 		stat->mode = fi->orig_i_mode;
 	}
@@ -1172,6 +1288,9 @@
 	struct fuse_getxattr_out outarg;
 	ssize_t ret;
 
+	if (!fuse_allow_task(fc, current))
+		return -EACCES;
+
 	if (fc->no_listxattr)
 		return -EOPNOTSUPP;
 
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index c4b98c0..0fcdba9 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -28,7 +28,9 @@
 		return PTR_ERR(req);
 
 	memset(&inarg, 0, sizeof(inarg));
-	inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+	inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
+	if (!fc->atomic_o_trunc)
+		inarg.flags &= ~O_TRUNC;
 	req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
 	req->in.h.nodeid = get_node_id(inode);
 	req->in.numargs = 1;
@@ -54,6 +56,7 @@
 			kfree(ff);
 			ff = NULL;
 		}
+		INIT_LIST_HEAD(&ff->write_entry);
 		atomic_set(&ff->count, 0);
 	}
 	return ff;
@@ -148,12 +151,18 @@
 {
 	struct fuse_file *ff = file->private_data;
 	if (ff) {
+		struct fuse_conn *fc = get_fuse_conn(inode);
+
 		fuse_release_fill(ff, get_node_id(inode), file->f_flags,
 				  isdir ? FUSE_RELEASEDIR : FUSE_RELEASE);
 
 		/* Hold vfsmount and dentry until release is finished */
 		ff->reserved_req->vfsmount = mntget(file->f_path.mnt);
 		ff->reserved_req->dentry = dget(file->f_path.dentry);
+
+		spin_lock(&fc->lock);
+		list_del(&ff->write_entry);
+		spin_unlock(&fc->lock);
 		/*
 		 * Normally this will send the RELEASE request,
 		 * however if some asynchronous READ or WRITE requests
@@ -180,7 +189,7 @@
  * Scramble the ID space with XTEA, so that the value of the files_struct
  * pointer is not exposed to userspace.
  */
-static u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id)
+u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id)
 {
 	u32 *k = fc->scramble_key;
 	u64 v = (unsigned long) id;
@@ -299,11 +308,19 @@
 }
 
 static size_t fuse_send_read(struct fuse_req *req, struct file *file,
-			     struct inode *inode, loff_t pos, size_t count)
+			     struct inode *inode, loff_t pos, size_t count,
+			     fl_owner_t owner)
 {
 	struct fuse_conn *fc = get_fuse_conn(inode);
 	struct fuse_file *ff = file->private_data;
+
 	fuse_read_fill(req, ff, inode, pos, count, FUSE_READ);
+	if (owner != NULL) {
+		struct fuse_read_in *inarg = &req->misc.read_in;
+
+		inarg->read_flags |= FUSE_READ_LOCKOWNER;
+		inarg->lock_owner = fuse_lock_owner_id(fc, owner);
+	}
 	request_send(fc, req);
 	return req->out.args[0].size;
 }
@@ -327,7 +344,8 @@
 	req->out.page_zeroing = 1;
 	req->num_pages = 1;
 	req->pages[0] = page;
-	fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE);
+	fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE,
+		       NULL);
 	err = req->out.h.error;
 	fuse_put_request(fc, req);
 	if (!err)
@@ -434,30 +452,47 @@
 	return err;
 }
 
-static size_t fuse_send_write(struct fuse_req *req, struct file *file,
-			      struct inode *inode, loff_t pos, size_t count)
+static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff,
+			    struct inode *inode, loff_t pos, size_t count,
+			    int writepage)
 {
 	struct fuse_conn *fc = get_fuse_conn(inode);
-	struct fuse_file *ff = file->private_data;
-	struct fuse_write_in inarg;
-	struct fuse_write_out outarg;
+	struct fuse_write_in *inarg = &req->misc.write.in;
+	struct fuse_write_out *outarg = &req->misc.write.out;
 
-	memset(&inarg, 0, sizeof(struct fuse_write_in));
-	inarg.fh = ff->fh;
-	inarg.offset = pos;
-	inarg.size = count;
+	memset(inarg, 0, sizeof(struct fuse_write_in));
+	inarg->fh = ff->fh;
+	inarg->offset = pos;
+	inarg->size = count;
+	inarg->write_flags = writepage ? FUSE_WRITE_CACHE : 0;
 	req->in.h.opcode = FUSE_WRITE;
 	req->in.h.nodeid = get_node_id(inode);
 	req->in.argpages = 1;
 	req->in.numargs = 2;
-	req->in.args[0].size = sizeof(struct fuse_write_in);
-	req->in.args[0].value = &inarg;
+	if (fc->minor < 9)
+		req->in.args[0].size = FUSE_COMPAT_WRITE_IN_SIZE;
+	else
+		req->in.args[0].size = sizeof(struct fuse_write_in);
+	req->in.args[0].value = inarg;
 	req->in.args[1].size = count;
 	req->out.numargs = 1;
 	req->out.args[0].size = sizeof(struct fuse_write_out);
-	req->out.args[0].value = &outarg;
+	req->out.args[0].value = outarg;
+}
+
+static size_t fuse_send_write(struct fuse_req *req, struct file *file,
+			      struct inode *inode, loff_t pos, size_t count,
+			      fl_owner_t owner)
+{
+	struct fuse_conn *fc = get_fuse_conn(inode);
+	fuse_write_fill(req, file->private_data, inode, pos, count, 0);
+	if (owner != NULL) {
+		struct fuse_write_in *inarg = &req->misc.write.in;
+		inarg->write_flags |= FUSE_WRITE_LOCKOWNER;
+		inarg->lock_owner = fuse_lock_owner_id(fc, owner);
+	}
 	request_send(fc, req);
-	return outarg.size;
+	return req->misc.write.out.size;
 }
 
 static int fuse_write_begin(struct file *file, struct address_space *mapping,
@@ -478,6 +513,7 @@
 	int err;
 	size_t nres;
 	struct fuse_conn *fc = get_fuse_conn(inode);
+	struct fuse_inode *fi = get_fuse_inode(inode);
 	unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
 	struct fuse_req *req;
 
@@ -491,7 +527,7 @@
 	req->num_pages = 1;
 	req->pages[0] = page;
 	req->page_offset = offset;
-	nres = fuse_send_write(req, file, inode, pos, count);
+	nres = fuse_send_write(req, file, inode, pos, count, NULL);
 	err = req->out.h.error;
 	fuse_put_request(fc, req);
 	if (!err && !nres)
@@ -499,6 +535,7 @@
 	if (!err) {
 		pos += nres;
 		spin_lock(&fc->lock);
+		fi->attr_version = ++fc->attr_version;
 		if (pos > inode->i_size)
 			i_size_write(inode, pos);
 		spin_unlock(&fc->lock);
@@ -591,9 +628,11 @@
 		nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
 		nbytes = min(count, nbytes);
 		if (write)
-			nres = fuse_send_write(req, file, inode, pos, nbytes);
+			nres = fuse_send_write(req, file, inode, pos, nbytes,
+					       current->files);
 		else
-			nres = fuse_send_read(req, file, inode, pos, nbytes);
+			nres = fuse_send_read(req, file, inode, pos, nbytes,
+					      current->files);
 		fuse_release_user_pages(req, !write);
 		if (req->out.h.error) {
 			if (!res)
@@ -695,7 +734,8 @@
 }
 
 static void fuse_lk_fill(struct fuse_req *req, struct file *file,
-			 const struct file_lock *fl, int opcode, pid_t pid)
+			 const struct file_lock *fl, int opcode, pid_t pid,
+			 int flock)
 {
 	struct inode *inode = file->f_path.dentry->d_inode;
 	struct fuse_conn *fc = get_fuse_conn(inode);
@@ -708,6 +748,8 @@
 	arg->lk.end = fl->fl_end;
 	arg->lk.type = fl->fl_type;
 	arg->lk.pid = pid;
+	if (flock)
+		arg->lk_flags |= FUSE_LK_FLOCK;
 	req->in.h.opcode = opcode;
 	req->in.h.nodeid = get_node_id(inode);
 	req->in.numargs = 1;
@@ -727,7 +769,7 @@
 	if (IS_ERR(req))
 		return PTR_ERR(req);
 
-	fuse_lk_fill(req, file, fl, FUSE_GETLK, 0);
+	fuse_lk_fill(req, file, fl, FUSE_GETLK, 0, 0);
 	req->out.numargs = 1;
 	req->out.args[0].size = sizeof(outarg);
 	req->out.args[0].value = &outarg;
@@ -740,7 +782,7 @@
 	return err;
 }
 
-static int fuse_setlk(struct file *file, struct file_lock *fl)
+static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
 {
 	struct inode *inode = file->f_path.dentry->d_inode;
 	struct fuse_conn *fc = get_fuse_conn(inode);
@@ -757,7 +799,7 @@
 	if (IS_ERR(req))
 		return PTR_ERR(req);
 
-	fuse_lk_fill(req, file, fl, opcode, pid);
+	fuse_lk_fill(req, file, fl, opcode, pid, flock);
 	request_send(fc, req);
 	err = req->out.h.error;
 	/* locking is restartable */
@@ -783,11 +825,28 @@
 		if (fc->no_lock)
 			err = posix_lock_file_wait(file, fl);
 		else
-			err = fuse_setlk(file, fl);
+			err = fuse_setlk(file, fl, 0);
 	}
 	return err;
 }
 
+static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl)
+{
+	struct inode *inode = file->f_path.dentry->d_inode;
+	struct fuse_conn *fc = get_fuse_conn(inode);
+	int err;
+
+	if (fc->no_lock) {
+		err = flock_lock_file_wait(file, fl);
+	} else {
+		/* emulate flock with POSIX locks */
+		fl->fl_owner = (fl_owner_t) file;
+		err = fuse_setlk(file, fl, 1);
+	}
+
+	return err;
+}
+
 static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
 {
 	struct inode *inode = mapping->host;
@@ -836,6 +895,7 @@
 	.release	= fuse_release,
 	.fsync		= fuse_fsync,
 	.lock		= fuse_file_lock,
+	.flock		= fuse_file_flock,
 	.splice_read	= generic_file_splice_read,
 };
 
@@ -848,6 +908,7 @@
 	.release	= fuse_release,
 	.fsync		= fuse_fsync,
 	.lock		= fuse_file_lock,
+	.flock		= fuse_file_flock,
 	/* no mmap and splice_read */
 };
 
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 1764506..6c5461d 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -67,6 +67,12 @@
 	/** The sticky bit in inode->i_mode may have been removed, so
 	    preserve the original mode */
 	mode_t orig_i_mode;
+
+	/** Version of last attribute change */
+	u64 attr_version;
+
+	/** Files usable in writepage.  Protected by fc->lock */
+	struct list_head write_files;
 };
 
 /** FUSE specific file data */
@@ -79,6 +85,9 @@
 
 	/** Refcount */
 	atomic_t count;
+
+	/** Entry on inode's write_files list */
+	struct list_head write_entry;
 };
 
 /** One input argument of a request */
@@ -210,6 +219,10 @@
 		struct fuse_init_in init_in;
 		struct fuse_init_out init_out;
 		struct fuse_read_in read_in;
+		struct {
+			struct fuse_write_in in;
+			struct fuse_write_out out;
+		} write;
 		struct fuse_lk_in lk_in;
 	} misc;
 
@@ -317,6 +330,9 @@
 	/** Do readpages asynchronously?  Only set in INIT */
 	unsigned async_read : 1;
 
+	/** Do not send separate SETATTR request before open(O_TRUNC)  */
+	unsigned atomic_o_trunc : 1;
+
 	/*
 	 * The following bitfields are only for optimization purposes
 	 * and hence races in setting them will not cause malfunction
@@ -387,6 +403,9 @@
 
 	/** Reserved request for the DESTROY message */
 	struct fuse_req *destroy_req;
+
+	/** Version counter for attribute changes */
+	u64 attr_version;
 };
 
 static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
@@ -416,7 +435,8 @@
  * Get a filled in inode
  */
 struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
-			int generation, struct fuse_attr *attr);
+			int generation, struct fuse_attr *attr,
+			u64 attr_valid, u64 attr_version);
 
 /**
  * Send FORGET command
@@ -477,7 +497,8 @@
 /**
  * Change attributes of an inode
  */
-void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr);
+void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
+			    u64 attr_valid, u64 attr_version);
 
 /**
  * Initialize the client device
@@ -565,3 +586,10 @@
  * Is file type valid?
  */
 int fuse_valid_type(int m);
+
+/**
+ * Is task allowed to perform filesystem operation?
+ */
+int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task);
+
+u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index fd07357..9a68d69 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -56,6 +56,7 @@
 	fi->i_time = 0;
 	fi->nodeid = 0;
 	fi->nlookup = 0;
+	INIT_LIST_HEAD(&fi->write_files);
 	fi->forget_req = fuse_request_alloc();
 	if (!fi->forget_req) {
 		kmem_cache_free(fuse_inode_cachep, inode);
@@ -68,6 +69,7 @@
 static void fuse_destroy_inode(struct inode *inode)
 {
 	struct fuse_inode *fi = get_fuse_inode(inode);
+	BUG_ON(!list_empty(&fi->write_files));
 	if (fi->forget_req)
 		fuse_request_free(fi->forget_req);
 	kmem_cache_free(fuse_inode_cachep, inode);
@@ -117,12 +119,22 @@
 	unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
 }
 
-void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
+
+void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
+			    u64 attr_valid, u64 attr_version)
 {
 	struct fuse_conn *fc = get_fuse_conn(inode);
 	struct fuse_inode *fi = get_fuse_inode(inode);
 	loff_t oldsize;
 
+	spin_lock(&fc->lock);
+	if (attr_version != 0 && fi->attr_version > attr_version) {
+		spin_unlock(&fc->lock);
+		return;
+	}
+	fi->attr_version = ++fc->attr_version;
+	fi->i_time = attr_valid;
+
 	inode->i_ino     = attr->ino;
 	inode->i_mode    = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
 	inode->i_nlink   = attr->nlink;
@@ -136,6 +148,11 @@
 	inode->i_ctime.tv_sec   = attr->ctime;
 	inode->i_ctime.tv_nsec  = attr->ctimensec;
 
+	if (attr->blksize != 0)
+		inode->i_blkbits = ilog2(attr->blksize);
+	else
+		inode->i_blkbits = inode->i_sb->s_blocksize_bits;
+
 	/*
 	 * Don't set the sticky bit in i_mode, unless we want the VFS
 	 * to check permissions.  This prevents failures due to the
@@ -145,7 +162,6 @@
 	if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
 		inode->i_mode &= ~S_ISVTX;
 
-	spin_lock(&fc->lock);
 	oldsize = inode->i_size;
 	i_size_write(inode, attr->size);
 	spin_unlock(&fc->lock);
@@ -194,7 +210,8 @@
 }
 
 struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
-			int generation, struct fuse_attr *attr)
+			int generation, struct fuse_attr *attr,
+			u64 attr_valid, u64 attr_version)
 {
 	struct inode *inode;
 	struct fuse_inode *fi;
@@ -222,7 +239,8 @@
 	spin_lock(&fc->lock);
 	fi->nlookup ++;
 	spin_unlock(&fc->lock);
-	fuse_change_attributes(inode, attr);
+	fuse_change_attributes(inode, attr, attr_valid, attr_version);
+
 	return inode;
 }
 
@@ -287,6 +305,11 @@
 	struct fuse_statfs_out outarg;
 	int err;
 
+	if (!fuse_allow_task(fc, current)) {
+		buf->f_type = FUSE_SUPER_MAGIC;
+		return 0;
+	}
+
 	req = fuse_get_req(fc);
 	if (IS_ERR(req))
 		return PTR_ERR(req);
@@ -452,6 +475,7 @@
 		}
 		fc->reqctr = 0;
 		fc->blocked = 1;
+		fc->attr_version = 1;
 		get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
 	}
 out:
@@ -483,7 +507,7 @@
 	attr.mode = mode;
 	attr.ino = FUSE_ROOT_ID;
 	attr.nlink = 1;
-	return fuse_iget(sb, 1, 0, &attr);
+	return fuse_iget(sb, 1, 0, &attr, 0, 0);
 }
 
 static const struct super_operations fuse_super_operations = {
@@ -514,6 +538,8 @@
 				fc->async_read = 1;
 			if (!(arg->flags & FUSE_POSIX_LOCKS))
 				fc->no_lock = 1;
+			if (arg->flags & FUSE_ATOMIC_O_TRUNC)
+				fc->atomic_o_trunc = 1;
 		} else {
 			ra_pages = fc->max_read / PAGE_CACHE_SIZE;
 			fc->no_lock = 1;
@@ -536,7 +562,8 @@
 	arg->major = FUSE_KERNEL_VERSION;
 	arg->minor = FUSE_KERNEL_MINOR_VERSION;
 	arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
-	arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS;
+	arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_FILE_OPS |
+		FUSE_ATOMIC_O_TRUNC;
 	req->in.h.opcode = FUSE_INIT;
 	req->in.numargs = 1;
 	req->in.args[0].size = sizeof(*arg);
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index e2d1347..b9da623 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -31,40 +31,6 @@
 #define GFS2_LARGE_FH_SIZE 8
 #define GFS2_OLD_FH_SIZE 10
 
-static struct dentry *gfs2_decode_fh(struct super_block *sb,
-				     __u32 *p,
-				     int fh_len,
-				     int fh_type,
-				     int (*acceptable)(void *context,
-						       struct dentry *dentry),
-				     void *context)
-{
-	__be32 *fh = (__force __be32 *)p;
-	struct gfs2_inum_host inum, parent;
-
-	memset(&parent, 0, sizeof(struct gfs2_inum));
-
-	switch (fh_len) {
-	case GFS2_LARGE_FH_SIZE:
-	case GFS2_OLD_FH_SIZE:
-		parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
-		parent.no_formal_ino |= be32_to_cpu(fh[5]);
-		parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
-		parent.no_addr |= be32_to_cpu(fh[7]);
-	case GFS2_SMALL_FH_SIZE:
-		inum.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
-		inum.no_formal_ino |= be32_to_cpu(fh[1]);
-		inum.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
-		inum.no_addr |= be32_to_cpu(fh[3]);
-		break;
-	default:
-		return NULL;
-	}
-
-	return gfs2_export_ops.find_exported_dentry(sb, &inum, &parent,
-						    acceptable, context);
-}
-
 static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
 			  int connectable)
 {
@@ -189,10 +155,10 @@
 	return dentry;
 }
 
-static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
+static struct dentry *gfs2_get_dentry(struct super_block *sb,
+		struct gfs2_inum_host *inum)
 {
 	struct gfs2_sbd *sdp = sb->s_fs_info;
-	struct gfs2_inum_host *inum = inum_obj;
 	struct gfs2_holder i_gh, ri_gh, rgd_gh;
 	struct gfs2_rgrpd *rgd;
 	struct inode *inode;
@@ -289,11 +255,50 @@
 	return ERR_PTR(error);
 }
 
-struct export_operations gfs2_export_ops = {
-	.decode_fh = gfs2_decode_fh,
+static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	struct gfs2_inum_host this;
+	__be32 *fh = (__force __be32 *)fid->raw;
+
+	switch (fh_type) {
+	case GFS2_SMALL_FH_SIZE:
+	case GFS2_LARGE_FH_SIZE:
+	case GFS2_OLD_FH_SIZE:
+		this.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
+		this.no_formal_ino |= be32_to_cpu(fh[1]);
+		this.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
+		this.no_addr |= be32_to_cpu(fh[3]);
+		return gfs2_get_dentry(sb, &this);
+	default:
+		return NULL;
+	}
+}
+
+static struct dentry *gfs2_fh_to_parent(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	struct gfs2_inum_host parent;
+	__be32 *fh = (__force __be32 *)fid->raw;
+
+	switch (fh_type) {
+	case GFS2_LARGE_FH_SIZE:
+	case GFS2_OLD_FH_SIZE:
+		parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
+		parent.no_formal_ino |= be32_to_cpu(fh[5]);
+		parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
+		parent.no_addr |= be32_to_cpu(fh[7]);
+		return gfs2_get_dentry(sb, &parent);
+	default:
+		return NULL;
+	}
+}
+
+const struct export_operations gfs2_export_ops = {
 	.encode_fh = gfs2_encode_fh,
+	.fh_to_dentry = gfs2_fh_to_dentry,
+	.fh_to_parent = gfs2_fh_to_parent,
 	.get_name = gfs2_get_name,
 	.get_parent = gfs2_get_parent,
-	.get_dentry = gfs2_get_dentry,
 };
 
diff --git a/fs/gfs2/ops_fstype.h b/fs/gfs2/ops_fstype.h
index 407029b..da84905 100644
--- a/fs/gfs2/ops_fstype.h
+++ b/fs/gfs2/ops_fstype.h
@@ -14,6 +14,6 @@
 
 extern struct file_system_type gfs2_fs_type;
 extern struct file_system_type gfs2meta_fs_type;
-extern struct export_operations gfs2_export_ops;
+extern const struct export_operations gfs2_export_ops;
 
 #endif /* __OPS_FSTYPE_DOT_H__ */
diff --git a/fs/inotify.c b/fs/inotify.c
index 7457501..2c5b921 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -667,6 +667,49 @@
 EXPORT_SYMBOL_GPL(inotify_add_watch);
 
 /**
+ * inotify_clone_watch - put the watch next to existing one
+ * @old: already installed watch
+ * @new: new watch
+ *
+ * Caller must hold the inotify_mutex of inode we are dealing with;
+ * it is expected to remove the old watch before unlocking the inode.
+ */
+s32 inotify_clone_watch(struct inotify_watch *old, struct inotify_watch *new)
+{
+	struct inotify_handle *ih = old->ih;
+	int ret = 0;
+
+	new->mask = old->mask;
+	new->ih = ih;
+
+	mutex_lock(&ih->mutex);
+
+	/* Initialize a new watch */
+	ret = inotify_handle_get_wd(ih, new);
+	if (unlikely(ret))
+		goto out;
+	ret = new->wd;
+
+	get_inotify_handle(ih);
+
+	new->inode = igrab(old->inode);
+
+	list_add(&new->h_list, &ih->watches);
+	list_add(&new->i_list, &old->inode->inotify_watches);
+out:
+	mutex_unlock(&ih->mutex);
+	return ret;
+}
+
+void inotify_evict_watch(struct inotify_watch *watch)
+{
+	get_inotify_watch(watch);
+	mutex_lock(&watch->ih->mutex);
+	inotify_remove_watch_locked(watch->ih, watch);
+	mutex_unlock(&watch->ih->mutex);
+}
+
+/**
  * inotify_rm_wd - remove a watch from an inotify instance
  * @ih: inotify handle
  * @wd: watch descriptor to remove
diff --git a/fs/ioprio.c b/fs/ioprio.c
index 10d2c21..d6ff77e 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -25,6 +25,7 @@
 #include <linux/capability.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
+#include <linux/pid_namespace.h>
 
 static int set_task_ioprio(struct task_struct *task, int ioprio)
 {
@@ -93,7 +94,7 @@
 			if (!who)
 				p = current;
 			else
-				p = find_task_by_pid(who);
+				p = find_task_by_vpid(who);
 			if (p)
 				ret = set_task_ioprio(p, ioprio);
 			break;
@@ -101,7 +102,7 @@
 			if (!who)
 				pgrp = task_pgrp(current);
 			else
-				pgrp = find_pid(who);
+				pgrp = find_vpid(who);
 			do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
 				ret = set_task_ioprio(p, ioprio);
 				if (ret)
@@ -180,7 +181,7 @@
 			if (!who)
 				p = current;
 			else
-				p = find_task_by_pid(who);
+				p = find_task_by_vpid(who);
 			if (p)
 				ret = get_task_ioprio(p);
 			break;
@@ -188,7 +189,7 @@
 			if (!who)
 				pgrp = task_pgrp(current);
 			else
-				pgrp = find_pid(who);
+				pgrp = find_vpid(who);
 			do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
 				tmpio = get_task_ioprio(p);
 				if (tmpio < 0)
diff --git a/fs/isofs/export.c b/fs/isofs/export.c
index 4af856a..29f9753 100644
--- a/fs/isofs/export.c
+++ b/fs/isofs/export.c
@@ -42,16 +42,6 @@
 	return result;
 }
 
-static struct dentry *
-isofs_export_get_dentry(struct super_block *sb, void *vobjp)
-{
-	__u32 *objp = vobjp;
-	unsigned long block = objp[0];
-	unsigned long offset = objp[1];
-	__u32 generation = objp[2];
-	return isofs_export_iget(sb, block, offset, generation);
-}
-
 /* This function is surprisingly simple.  The trick is understanding
  * that "child" is always a directory. So, to find its parent, you
  * simply need to find its ".." entry, normalize its block and offset,
@@ -182,43 +172,44 @@
 	return type;
 }
 
+struct isofs_fid {
+	u32 block;
+	u16 offset;
+	u16 parent_offset;
+	u32 generation;
+	u32 parent_block;
+	u32 parent_generation;
+};
 
-static struct dentry *
-isofs_export_decode_fh(struct super_block *sb,
-		       __u32 *fh32,
-		       int fh_len,
-		       int fileid_type,
-		       int (*acceptable)(void *context, struct dentry *de),
-		       void *context)
+static struct dentry *isofs_fh_to_dentry(struct super_block *sb,
+	struct fid *fid, int fh_len, int fh_type)
 {
-	__u16 *fh16 = (__u16*)fh32;
-	__u32 child[3];   /* The child is what triggered all this. */
-	__u32 parent[3];  /* The parent is just along for the ride. */
+	struct isofs_fid *ifid = (struct isofs_fid *)fid;
 
-	if (fh_len < 3 || fileid_type > 2)
+	if (fh_len < 3 || fh_type > 2)
 		return NULL;
 
-	child[0] = fh32[0];
-	child[1] = fh16[2];  /* fh16 [sic] */
-	child[2] = fh32[2];
-
-	parent[0] = 0;
-	parent[1] = 0;
-	parent[2] = 0;
-	if (fileid_type == 2) {
-		if (fh_len > 2) parent[0] = fh32[3];
-		parent[1] = fh16[3];  /* fh16 [sic] */
-		if (fh_len > 4) parent[2] = fh32[4];
-	}
-
-	return sb->s_export_op->find_exported_dentry(sb, child, parent,
-						     acceptable, context);
+	return isofs_export_iget(sb, ifid->block, ifid->offset,
+			ifid->generation);
 }
 
+static struct dentry *isofs_fh_to_parent(struct super_block *sb,
+		struct fid *fid, int fh_len, int fh_type)
+{
+	struct isofs_fid *ifid = (struct isofs_fid *)fid;
 
-struct export_operations isofs_export_ops = {
-	.decode_fh	= isofs_export_decode_fh,
+	if (fh_type != 2)
+		return NULL;
+
+	return isofs_export_iget(sb,
+			fh_len > 2 ? ifid->parent_block : 0,
+			ifid->parent_offset,
+			fh_len > 4 ? ifid->parent_generation : 0);
+}
+
+const struct export_operations isofs_export_ops = {
 	.encode_fh	= isofs_export_encode_fh,
-	.get_dentry	= isofs_export_get_dentry,
+	.fh_to_dentry	= isofs_fh_to_dentry,
+	.fh_to_parent	= isofs_fh_to_parent,
 	.get_parent     = isofs_export_get_parent,
 };
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index aa359a2..09e3d30 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -3,7 +3,7 @@
  *
  *  (C) 1991  Linus Torvalds - minix filesystem
  *      1992, 1993, 1994  Eric Youngdale Modified for ISO 9660 filesystem.
- *      1994  Eberhard Moenkeberg - multi session handling.
+ *      1994  Eberhard Mönkeberg - multi session handling.
  *      1995  Mark Dobie - allow mounting of some weird VideoCDs and PhotoCDs.
  *	1997  Gordon Chaffee - Joliet CDs
  *	1998  Eric Lammerts - ISO 9660 Level 3
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h
index a07e67b..f3213f9 100644
--- a/fs/isofs/isofs.h
+++ b/fs/isofs/isofs.h
@@ -178,4 +178,4 @@
 extern const struct inode_operations isofs_dir_inode_operations;
 extern const struct file_operations isofs_dir_operations;
 extern const struct address_space_operations isofs_symlink_aops;
-extern struct export_operations isofs_export_ops;
+extern const struct export_operations isofs_export_ops;
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index a003d50..8f1f2aa 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -375,7 +375,7 @@
 			struct buffer_head *bh = jh2bh(jh);
 
 			jbd_lock_bh_state(bh);
-			jbd_slab_free(jh->b_committed_data, bh->b_size);
+			jbd_free(jh->b_committed_data, bh->b_size);
 			jh->b_committed_data = NULL;
 			jbd_unlock_bh_state(bh);
 		}
@@ -466,7 +466,7 @@
 	spin_unlock(&journal->j_list_lock);
 
 	if (err)
-		__journal_abort_hard(journal);
+		journal_abort(journal, err);
 
 	journal_write_revoke_records(journal, commit_transaction);
 
@@ -524,7 +524,7 @@
 
 			descriptor = journal_get_descriptor_buffer(journal);
 			if (!descriptor) {
-				__journal_abort_hard(journal);
+				journal_abort(journal, -EIO);
 				continue;
 			}
 
@@ -557,7 +557,7 @@
 		   and repeat this loop: we'll fall into the
 		   refile-on-abort condition above. */
 		if (err) {
-			__journal_abort_hard(journal);
+			journal_abort(journal, err);
 			continue;
 		}
 
@@ -748,7 +748,7 @@
 		err = -EIO;
 
 	if (err)
-		__journal_abort_hard(journal);
+		journal_abort(journal, err);
 
 	/* End of a transaction!  Finally, we can do checkpoint
            processing: any buffers committed as a result of this
@@ -792,14 +792,14 @@
 		 * Otherwise, we can just throw away the frozen data now.
 		 */
 		if (jh->b_committed_data) {
-			jbd_slab_free(jh->b_committed_data, bh->b_size);
+			jbd_free(jh->b_committed_data, bh->b_size);
 			jh->b_committed_data = NULL;
 			if (jh->b_frozen_data) {
 				jh->b_committed_data = jh->b_frozen_data;
 				jh->b_frozen_data = NULL;
 			}
 		} else if (jh->b_frozen_data) {
-			jbd_slab_free(jh->b_frozen_data, bh->b_size);
+			jbd_free(jh->b_frozen_data, bh->b_size);
 			jh->b_frozen_data = NULL;
 		}
 
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index a6be78c..5d14243 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -35,6 +35,7 @@
 #include <linux/kthread.h>
 #include <linux/poison.h>
 #include <linux/proc_fs.h>
+#include <linux/debugfs.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -83,7 +84,6 @@
 
 static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
 static void __journal_abort_soft (journal_t *journal, int errno);
-static int journal_create_jbd_slab(size_t slab_size);
 
 /*
  * Helper function used to manage commit timeouts
@@ -218,7 +218,7 @@
 	if (IS_ERR(t))
 		return PTR_ERR(t);
 
-	wait_event(journal->j_wait_done_commit, journal->j_task != 0);
+	wait_event(journal->j_wait_done_commit, journal->j_task != NULL);
 	return 0;
 }
 
@@ -230,7 +230,8 @@
 	while (journal->j_task) {
 		wake_up(&journal->j_wait_commit);
 		spin_unlock(&journal->j_state_lock);
-		wait_event(journal->j_wait_done_commit, journal->j_task == 0);
+		wait_event(journal->j_wait_done_commit,
+				journal->j_task == NULL);
 		spin_lock(&journal->j_state_lock);
 	}
 	spin_unlock(&journal->j_state_lock);
@@ -334,10 +335,10 @@
 		char *tmp;
 
 		jbd_unlock_bh_state(bh_in);
-		tmp = jbd_slab_alloc(bh_in->b_size, GFP_NOFS);
+		tmp = jbd_alloc(bh_in->b_size, GFP_NOFS);
 		jbd_lock_bh_state(bh_in);
 		if (jh_in->b_frozen_data) {
-			jbd_slab_free(tmp, bh_in->b_size);
+			jbd_free(tmp, bh_in->b_size);
 			goto repeat;
 		}
 
@@ -654,10 +655,9 @@
 	journal_t *journal;
 	int err;
 
-	journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL);
+	journal = kzalloc(sizeof(*journal), GFP_KERNEL);
 	if (!journal)
 		goto fail;
-	memset(journal, 0, sizeof(*journal));
 
 	init_waitqueue_head(&journal->j_wait_transaction_locked);
 	init_waitqueue_head(&journal->j_wait_logspace);
@@ -1095,13 +1095,6 @@
 		}
 	}
 
-	/*
-	 * Create a slab for this blocksize
-	 */
-	err = journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize));
-	if (err)
-		return err;
-
 	/* Let the recovery code check whether it needs to recover any
 	 * data from the journal. */
 	if (journal_recover(journal))
@@ -1615,86 +1608,6 @@
 }
 
 /*
- * Simple support for retrying memory allocations.  Introduced to help to
- * debug different VM deadlock avoidance strategies.
- */
-void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry)
-{
-	return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
-}
-
-/*
- * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed
- * and allocate frozen and commit buffers from these slabs.
- *
- * Reason for doing this is to avoid, SLAB_DEBUG - since it could
- * cause bh to cross page boundary.
- */
-
-#define JBD_MAX_SLABS 5
-#define JBD_SLAB_INDEX(size)  (size >> 11)
-
-static struct kmem_cache *jbd_slab[JBD_MAX_SLABS];
-static const char *jbd_slab_names[JBD_MAX_SLABS] = {
-	"jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k"
-};
-
-static void journal_destroy_jbd_slabs(void)
-{
-	int i;
-
-	for (i = 0; i < JBD_MAX_SLABS; i++) {
-		if (jbd_slab[i])
-			kmem_cache_destroy(jbd_slab[i]);
-		jbd_slab[i] = NULL;
-	}
-}
-
-static int journal_create_jbd_slab(size_t slab_size)
-{
-	int i = JBD_SLAB_INDEX(slab_size);
-
-	BUG_ON(i >= JBD_MAX_SLABS);
-
-	/*
-	 * Check if we already have a slab created for this size
-	 */
-	if (jbd_slab[i])
-		return 0;
-
-	/*
-	 * Create a slab and force alignment to be same as slabsize -
-	 * this will make sure that allocations won't cross the page
-	 * boundary.
-	 */
-	jbd_slab[i] = kmem_cache_create(jbd_slab_names[i],
-				slab_size, slab_size, 0, NULL);
-	if (!jbd_slab[i]) {
-		printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n");
-		return -ENOMEM;
-	}
-	return 0;
-}
-
-void * jbd_slab_alloc(size_t size, gfp_t flags)
-{
-	int idx;
-
-	idx = JBD_SLAB_INDEX(size);
-	BUG_ON(jbd_slab[idx] == NULL);
-	return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL);
-}
-
-void jbd_slab_free(void *ptr,  size_t size)
-{
-	int idx;
-
-	idx = JBD_SLAB_INDEX(size);
-	BUG_ON(jbd_slab[idx] == NULL);
-	kmem_cache_free(jbd_slab[idx], ptr);
-}
-
-/*
  * Journal_head storage management
  */
 static struct kmem_cache *journal_head_cache;
@@ -1739,14 +1652,14 @@
 	atomic_inc(&nr_journal_heads);
 #endif
 	ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS);
-	if (ret == 0) {
+	if (ret == NULL) {
 		jbd_debug(1, "out of memory for journal_head\n");
 		if (time_after(jiffies, last_warning + 5*HZ)) {
 			printk(KERN_NOTICE "ENOMEM in %s, retrying.\n",
 			       __FUNCTION__);
 			last_warning = jiffies;
 		}
-		while (ret == 0) {
+		while (ret == NULL) {
 			yield();
 			ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS);
 		}
@@ -1881,13 +1794,13 @@
 				printk(KERN_WARNING "%s: freeing "
 						"b_frozen_data\n",
 						__FUNCTION__);
-				jbd_slab_free(jh->b_frozen_data, bh->b_size);
+				jbd_free(jh->b_frozen_data, bh->b_size);
 			}
 			if (jh->b_committed_data) {
 				printk(KERN_WARNING "%s: freeing "
 						"b_committed_data\n",
 						__FUNCTION__);
-				jbd_slab_free(jh->b_committed_data, bh->b_size);
+				jbd_free(jh->b_committed_data, bh->b_size);
 			}
 			bh->b_private = NULL;
 			jh->b_bh = NULL;	/* debug, really */
@@ -1939,63 +1852,40 @@
 }
 
 /*
- * /proc tunables
+ * debugfs tunables
  */
-#if defined(CONFIG_JBD_DEBUG)
-int journal_enable_debug;
+#ifdef CONFIG_JBD_DEBUG
+
+u8 journal_enable_debug __read_mostly;
 EXPORT_SYMBOL(journal_enable_debug);
-#endif
 
-#if defined(CONFIG_JBD_DEBUG) && defined(CONFIG_PROC_FS)
+static struct dentry *jbd_debugfs_dir;
+static struct dentry *jbd_debug;
 
-static struct proc_dir_entry *proc_jbd_debug;
-
-static int read_jbd_debug(char *page, char **start, off_t off,
-			  int count, int *eof, void *data)
+static void __init jbd_create_debugfs_entry(void)
 {
-	int ret;
-
-	ret = sprintf(page + off, "%d\n", journal_enable_debug);
-	*eof = 1;
-	return ret;
+	jbd_debugfs_dir = debugfs_create_dir("jbd", NULL);
+	if (jbd_debugfs_dir)
+		jbd_debug = debugfs_create_u8("jbd-debug", S_IRUGO,
+					       jbd_debugfs_dir,
+					       &journal_enable_debug);
 }
 
-static int write_jbd_debug(struct file *file, const char __user *buffer,
-			   unsigned long count, void *data)
+static void __exit jbd_remove_debugfs_entry(void)
 {
-	char buf[32];
-
-	if (count > ARRAY_SIZE(buf) - 1)
-		count = ARRAY_SIZE(buf) - 1;
-	if (copy_from_user(buf, buffer, count))
-		return -EFAULT;
-	buf[ARRAY_SIZE(buf) - 1] = '\0';
-	journal_enable_debug = simple_strtoul(buf, NULL, 10);
-	return count;
-}
-
-#define JBD_PROC_NAME "sys/fs/jbd-debug"
-
-static void __init create_jbd_proc_entry(void)
-{
-	proc_jbd_debug = create_proc_entry(JBD_PROC_NAME, 0644, NULL);
-	if (proc_jbd_debug) {
-		/* Why is this so hard? */
-		proc_jbd_debug->read_proc = read_jbd_debug;
-		proc_jbd_debug->write_proc = write_jbd_debug;
-	}
-}
-
-static void __exit remove_jbd_proc_entry(void)
-{
-	if (proc_jbd_debug)
-		remove_proc_entry(JBD_PROC_NAME, NULL);
+	debugfs_remove(jbd_debug);
+	debugfs_remove(jbd_debugfs_dir);
 }
 
 #else
 
-#define create_jbd_proc_entry() do {} while (0)
-#define remove_jbd_proc_entry() do {} while (0)
+static inline void jbd_create_debugfs_entry(void)
+{
+}
+
+static inline void jbd_remove_debugfs_entry(void)
+{
+}
 
 #endif
 
@@ -2042,7 +1932,6 @@
 	journal_destroy_revoke_caches();
 	journal_destroy_journal_head_cache();
 	journal_destroy_handle_cache();
-	journal_destroy_jbd_slabs();
 }
 
 static int __init journal_init(void)
@@ -2054,7 +1943,7 @@
 	ret = journal_init_caches();
 	if (ret != 0)
 		journal_destroy_caches();
-	create_jbd_proc_entry();
+	jbd_create_debugfs_entry();
 	return ret;
 }
 
@@ -2065,7 +1954,7 @@
 	if (n)
 		printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n);
 #endif
-	remove_jbd_proc_entry();
+	jbd_remove_debugfs_entry();
 	journal_destroy_caches();
 }
 
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
index 2a5f4b8..c5d9694 100644
--- a/fs/jbd/recovery.c
+++ b/fs/jbd/recovery.c
@@ -250,10 +250,10 @@
 	if (!err)
 		err = do_one_pass(journal, &info, PASS_REPLAY);
 
-	jbd_debug(0, "JBD: recovery, exit status %d, "
+	jbd_debug(1, "JBD: recovery, exit status %d, "
 		  "recovered transactions %u to %u\n",
 		  err, info.start_transaction, info.end_transaction);
-	jbd_debug(0, "JBD: Replayed %d and revoked %d/%d blocks\n",
+	jbd_debug(1, "JBD: Replayed %d and revoked %d/%d blocks\n",
 		  info.nr_replays, info.nr_revoke_hits, info.nr_revokes);
 
 	/* Restart the log at the next transaction ID, thus invalidating
@@ -297,7 +297,7 @@
 #ifdef CONFIG_JBD_DEBUG
 		int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence);
 #endif
-		jbd_debug(0,
+		jbd_debug(1,
 			  "JBD: ignoring %d transaction%s from the journal.\n",
 			  dropped, (dropped == 1) ? "" : "s");
 		journal->j_transaction_sequence = ++info.end_transaction;
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 8df5bac..08ff6c7 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -96,13 +96,12 @@
 
 alloc_transaction:
 	if (!journal->j_running_transaction) {
-		new_transaction = jbd_kmalloc(sizeof(*new_transaction),
-						GFP_NOFS);
+		new_transaction = kzalloc(sizeof(*new_transaction),
+						GFP_NOFS|__GFP_NOFAIL);
 		if (!new_transaction) {
 			ret = -ENOMEM;
 			goto out;
 		}
-		memset(new_transaction, 0, sizeof(*new_transaction));
 	}
 
 	jbd_debug(3, "New handle %p going live.\n", handle);
@@ -675,7 +674,7 @@
 				JBUFFER_TRACE(jh, "allocate memory for buffer");
 				jbd_unlock_bh_state(bh);
 				frozen_buffer =
-					jbd_slab_alloc(jh2bh(jh)->b_size,
+					jbd_alloc(jh2bh(jh)->b_size,
 							 GFP_NOFS);
 				if (!frozen_buffer) {
 					printk(KERN_EMERG
@@ -735,7 +734,7 @@
 
 out:
 	if (unlikely(frozen_buffer))	/* It's usually NULL */
-		jbd_slab_free(frozen_buffer, bh->b_size);
+		jbd_free(frozen_buffer, bh->b_size);
 
 	JBUFFER_TRACE(jh, "exit");
 	return error;
@@ -888,7 +887,7 @@
 
 repeat:
 	if (!jh->b_committed_data) {
-		committed_data = jbd_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS);
+		committed_data = jbd_alloc(jh2bh(jh)->b_size, GFP_NOFS);
 		if (!committed_data) {
 			printk(KERN_EMERG "%s: No memory for committed data\n",
 				__FUNCTION__);
@@ -915,7 +914,7 @@
 out:
 	journal_put_journal_head(jh);
 	if (unlikely(committed_data))
-		jbd_slab_free(committed_data, bh->b_size);
+		jbd_free(committed_data, bh->b_size);
 	return err;
 }
 
@@ -1172,7 +1171,7 @@
 	}
 
 	/* That test should have eliminated the following case: */
-	J_ASSERT_JH(jh, jh->b_frozen_data == 0);
+	J_ASSERT_JH(jh, jh->b_frozen_data == NULL);
 
 	JBUFFER_TRACE(jh, "file as BJ_Metadata");
 	spin_lock(&journal->j_list_lock);
@@ -1522,7 +1521,7 @@
 
 	J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
 	if (jh->b_jlist != BJ_None)
-		J_ASSERT_JH(jh, transaction != 0);
+		J_ASSERT_JH(jh, transaction != NULL);
 
 	switch (jh->b_jlist) {
 	case BJ_None:
@@ -1591,11 +1590,11 @@
 	if (buffer_locked(bh) || buffer_dirty(bh))
 		goto out;
 
-	if (jh->b_next_transaction != 0)
+	if (jh->b_next_transaction != NULL)
 		goto out;
 
 	spin_lock(&journal->j_list_lock);
-	if (jh->b_transaction != 0 && jh->b_cp_transaction == 0) {
+	if (jh->b_transaction != NULL && jh->b_cp_transaction == NULL) {
 		if (jh->b_jlist == BJ_SyncData || jh->b_jlist == BJ_Locked) {
 			/* A written-back ordered data buffer */
 			JBUFFER_TRACE(jh, "release data");
@@ -1603,7 +1602,7 @@
 			journal_remove_journal_head(bh);
 			__brelse(bh);
 		}
-	} else if (jh->b_cp_transaction != 0 && jh->b_transaction == 0) {
+	} else if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) {
 		/* written-back checkpointed metadata buffer */
 		if (jh->b_jlist == BJ_None) {
 			JBUFFER_TRACE(jh, "remove from checkpoint list");
@@ -1963,7 +1962,7 @@
 
 	J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
 	J_ASSERT_JH(jh, jh->b_transaction == transaction ||
-				jh->b_transaction == 0);
+				jh->b_transaction == NULL);
 
 	if (jh->b_transaction && jh->b_jlist == jlist)
 		return;
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index c0f59d1..6986f33 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -278,7 +278,7 @@
 				   unsigned long long block)
 {
 	tag->t_blocknr = cpu_to_be32(block & (u32)~0);
-	if (tag_bytes > JBD_TAG_SIZE32)
+	if (tag_bytes > JBD2_TAG_SIZE32)
 		tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1);
 }
 
@@ -384,7 +384,7 @@
 			struct buffer_head *bh = jh2bh(jh);
 
 			jbd_lock_bh_state(bh);
-			jbd2_slab_free(jh->b_committed_data, bh->b_size);
+			jbd2_free(jh->b_committed_data, bh->b_size);
 			jh->b_committed_data = NULL;
 			jbd_unlock_bh_state(bh);
 		}
@@ -475,7 +475,7 @@
 	spin_unlock(&journal->j_list_lock);
 
 	if (err)
-		__jbd2_journal_abort_hard(journal);
+		jbd2_journal_abort(journal, err);
 
 	jbd2_journal_write_revoke_records(journal, commit_transaction);
 
@@ -533,7 +533,7 @@
 
 			descriptor = jbd2_journal_get_descriptor_buffer(journal);
 			if (!descriptor) {
-				__jbd2_journal_abort_hard(journal);
+				jbd2_journal_abort(journal, -EIO);
 				continue;
 			}
 
@@ -566,7 +566,7 @@
 		   and repeat this loop: we'll fall into the
 		   refile-on-abort condition above. */
 		if (err) {
-			__jbd2_journal_abort_hard(journal);
+			jbd2_journal_abort(journal, err);
 			continue;
 		}
 
@@ -757,7 +757,7 @@
 		err = -EIO;
 
 	if (err)
-		__jbd2_journal_abort_hard(journal);
+		jbd2_journal_abort(journal, err);
 
 	/* End of a transaction!  Finally, we can do checkpoint
            processing: any buffers committed as a result of this
@@ -801,14 +801,14 @@
 		 * Otherwise, we can just throw away the frozen data now.
 		 */
 		if (jh->b_committed_data) {
-			jbd2_slab_free(jh->b_committed_data, bh->b_size);
+			jbd2_free(jh->b_committed_data, bh->b_size);
 			jh->b_committed_data = NULL;
 			if (jh->b_frozen_data) {
 				jh->b_committed_data = jh->b_frozen_data;
 				jh->b_frozen_data = NULL;
 			}
 		} else if (jh->b_frozen_data) {
-			jbd2_slab_free(jh->b_frozen_data, bh->b_size);
+			jbd2_free(jh->b_frozen_data, bh->b_size);
 			jh->b_frozen_data = NULL;
 		}
 
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index f37324a..6ddc553 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -84,7 +84,6 @@
 
 static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
 static void __journal_abort_soft (journal_t *journal, int errno);
-static int jbd2_journal_create_jbd_slab(size_t slab_size);
 
 /*
  * Helper function used to manage commit timeouts
@@ -335,10 +334,10 @@
 		char *tmp;
 
 		jbd_unlock_bh_state(bh_in);
-		tmp = jbd2_slab_alloc(bh_in->b_size, GFP_NOFS);
+		tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS);
 		jbd_lock_bh_state(bh_in);
 		if (jh_in->b_frozen_data) {
-			jbd2_slab_free(tmp, bh_in->b_size);
+			jbd2_free(tmp, bh_in->b_size);
 			goto repeat;
 		}
 
@@ -655,10 +654,9 @@
 	journal_t *journal;
 	int err;
 
-	journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL);
+	journal = kzalloc(sizeof(*journal), GFP_KERNEL|__GFP_NOFAIL);
 	if (!journal)
 		goto fail;
-	memset(journal, 0, sizeof(*journal));
 
 	init_waitqueue_head(&journal->j_wait_transaction_locked);
 	init_waitqueue_head(&journal->j_wait_logspace);
@@ -672,7 +670,7 @@
 	spin_lock_init(&journal->j_list_lock);
 	spin_lock_init(&journal->j_state_lock);
 
-	journal->j_commit_interval = (HZ * JBD_DEFAULT_MAX_COMMIT_AGE);
+	journal->j_commit_interval = (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE);
 
 	/* The journal is marked for error until we succeed with recovery! */
 	journal->j_flags = JBD2_ABORT;
@@ -1096,13 +1094,6 @@
 		}
 	}
 
-	/*
-	 * Create a slab for this blocksize
-	 */
-	err = jbd2_journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize));
-	if (err)
-		return err;
-
 	/* Let the recovery code check whether it needs to recover any
 	 * data from the journal. */
 	if (jbd2_journal_recover(journal))
@@ -1621,89 +1612,9 @@
 size_t journal_tag_bytes(journal_t *journal)
 {
 	if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
-		return JBD_TAG_SIZE64;
+		return JBD2_TAG_SIZE64;
 	else
-		return JBD_TAG_SIZE32;
-}
-
-/*
- * Simple support for retrying memory allocations.  Introduced to help to
- * debug different VM deadlock avoidance strategies.
- */
-void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry)
-{
-	return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
-}
-
-/*
- * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed
- * and allocate frozen and commit buffers from these slabs.
- *
- * Reason for doing this is to avoid, SLAB_DEBUG - since it could
- * cause bh to cross page boundary.
- */
-
-#define JBD_MAX_SLABS 5
-#define JBD_SLAB_INDEX(size)  (size >> 11)
-
-static struct kmem_cache *jbd_slab[JBD_MAX_SLABS];
-static const char *jbd_slab_names[JBD_MAX_SLABS] = {
-	"jbd2_1k", "jbd2_2k", "jbd2_4k", NULL, "jbd2_8k"
-};
-
-static void jbd2_journal_destroy_jbd_slabs(void)
-{
-	int i;
-
-	for (i = 0; i < JBD_MAX_SLABS; i++) {
-		if (jbd_slab[i])
-			kmem_cache_destroy(jbd_slab[i]);
-		jbd_slab[i] = NULL;
-	}
-}
-
-static int jbd2_journal_create_jbd_slab(size_t slab_size)
-{
-	int i = JBD_SLAB_INDEX(slab_size);
-
-	BUG_ON(i >= JBD_MAX_SLABS);
-
-	/*
-	 * Check if we already have a slab created for this size
-	 */
-	if (jbd_slab[i])
-		return 0;
-
-	/*
-	 * Create a slab and force alignment to be same as slabsize -
-	 * this will make sure that allocations won't cross the page
-	 * boundary.
-	 */
-	jbd_slab[i] = kmem_cache_create(jbd_slab_names[i],
-				slab_size, slab_size, 0, NULL);
-	if (!jbd_slab[i]) {
-		printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n");
-		return -ENOMEM;
-	}
-	return 0;
-}
-
-void * jbd2_slab_alloc(size_t size, gfp_t flags)
-{
-	int idx;
-
-	idx = JBD_SLAB_INDEX(size);
-	BUG_ON(jbd_slab[idx] == NULL);
-	return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL);
-}
-
-void jbd2_slab_free(void *ptr,  size_t size)
-{
-	int idx;
-
-	idx = JBD_SLAB_INDEX(size);
-	BUG_ON(jbd_slab[idx] == NULL);
-	kmem_cache_free(jbd_slab[idx], ptr);
+		return JBD2_TAG_SIZE32;
 }
 
 /*
@@ -1770,7 +1681,7 @@
 {
 #ifdef CONFIG_JBD2_DEBUG
 	atomic_dec(&nr_journal_heads);
-	memset(jh, JBD_POISON_FREE, sizeof(*jh));
+	memset(jh, JBD2_POISON_FREE, sizeof(*jh));
 #endif
 	kmem_cache_free(jbd2_journal_head_cache, jh);
 }
@@ -1893,13 +1804,13 @@
 				printk(KERN_WARNING "%s: freeing "
 						"b_frozen_data\n",
 						__FUNCTION__);
-				jbd2_slab_free(jh->b_frozen_data, bh->b_size);
+				jbd2_free(jh->b_frozen_data, bh->b_size);
 			}
 			if (jh->b_committed_data) {
 				printk(KERN_WARNING "%s: freeing "
 						"b_committed_data\n",
 						__FUNCTION__);
-				jbd2_slab_free(jh->b_committed_data, bh->b_size);
+				jbd2_free(jh->b_committed_data, bh->b_size);
 			}
 			bh->b_private = NULL;
 			jh->b_bh = NULL;	/* debug, really */
@@ -1953,16 +1864,14 @@
 /*
  * debugfs tunables
  */
-#if defined(CONFIG_JBD2_DEBUG)
-u8 jbd2_journal_enable_debug;
+#ifdef CONFIG_JBD2_DEBUG
+u8 jbd2_journal_enable_debug __read_mostly;
 EXPORT_SYMBOL(jbd2_journal_enable_debug);
-#endif
-
-#if defined(CONFIG_JBD2_DEBUG) && defined(CONFIG_DEBUG_FS)
 
 #define JBD2_DEBUG_NAME "jbd2-debug"
 
-struct dentry *jbd2_debugfs_dir, *jbd2_debug;
+static struct dentry *jbd2_debugfs_dir;
+static struct dentry *jbd2_debug;
 
 static void __init jbd2_create_debugfs_entry(void)
 {
@@ -1975,24 +1884,18 @@
 
 static void __exit jbd2_remove_debugfs_entry(void)
 {
-	if (jbd2_debug)
-		debugfs_remove(jbd2_debug);
-	if (jbd2_debugfs_dir)
-		debugfs_remove(jbd2_debugfs_dir);
+	debugfs_remove(jbd2_debug);
+	debugfs_remove(jbd2_debugfs_dir);
 }
 
 #else
 
 static void __init jbd2_create_debugfs_entry(void)
 {
-	do {
-	} while (0);
 }
 
 static void __exit jbd2_remove_debugfs_entry(void)
 {
-	do {
-	} while (0);
 }
 
 #endif
@@ -2040,7 +1943,6 @@
 	jbd2_journal_destroy_revoke_caches();
 	jbd2_journal_destroy_jbd2_journal_head_cache();
 	jbd2_journal_destroy_handle_cache();
-	jbd2_journal_destroy_jbd_slabs();
 }
 
 static int __init journal_init(void)
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
index b50be8a..d0ce627 100644
--- a/fs/jbd2/recovery.c
+++ b/fs/jbd2/recovery.c
@@ -311,7 +311,7 @@
 static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag_t *tag)
 {
 	unsigned long long block = be32_to_cpu(tag->t_blocknr);
-	if (tag_bytes > JBD_TAG_SIZE32)
+	if (tag_bytes > JBD2_TAG_SIZE32)
 		block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32;
 	return block;
 }
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c
index 01d8897..3595fd4 100644
--- a/fs/jbd2/revoke.c
+++ b/fs/jbd2/revoke.c
@@ -352,7 +352,7 @@
 		if (bh)
 			BUFFER_TRACE(bh, "found on hash");
 	}
-#ifdef JBD_EXPENSIVE_CHECKING
+#ifdef JBD2_EXPENSIVE_CHECKING
 	else {
 		struct buffer_head *bh2;
 
@@ -453,7 +453,7 @@
 		}
 	}
 
-#ifdef JBD_EXPENSIVE_CHECKING
+#ifdef JBD2_EXPENSIVE_CHECKING
 	/* There better not be one left behind by now! */
 	record = find_revoke_record(journal, bh->b_blocknr);
 	J_ASSERT_JH(jh, record == NULL);
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 7946ff4..b1fcf2b 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -96,13 +96,12 @@
 
 alloc_transaction:
 	if (!journal->j_running_transaction) {
-		new_transaction = jbd_kmalloc(sizeof(*new_transaction),
-						GFP_NOFS);
+		new_transaction = kzalloc(sizeof(*new_transaction),
+						GFP_NOFS|__GFP_NOFAIL);
 		if (!new_transaction) {
 			ret = -ENOMEM;
 			goto out;
 		}
-		memset(new_transaction, 0, sizeof(*new_transaction));
 	}
 
 	jbd_debug(3, "New handle %p going live.\n", handle);
@@ -236,7 +235,7 @@
 /* Allocate a new handle.  This should probably be in a slab... */
 static handle_t *new_handle(int nblocks)
 {
-	handle_t *handle = jbd_alloc_handle(GFP_NOFS);
+	handle_t *handle = jbd2_alloc_handle(GFP_NOFS);
 	if (!handle)
 		return NULL;
 	memset(handle, 0, sizeof(*handle));
@@ -282,7 +281,7 @@
 
 	err = start_this_handle(journal, handle);
 	if (err < 0) {
-		jbd_free_handle(handle);
+		jbd2_free_handle(handle);
 		current->journal_info = NULL;
 		handle = ERR_PTR(err);
 	}
@@ -668,7 +667,7 @@
 				JBUFFER_TRACE(jh, "allocate memory for buffer");
 				jbd_unlock_bh_state(bh);
 				frozen_buffer =
-					jbd2_slab_alloc(jh2bh(jh)->b_size,
+					jbd2_alloc(jh2bh(jh)->b_size,
 							 GFP_NOFS);
 				if (!frozen_buffer) {
 					printk(KERN_EMERG
@@ -728,7 +727,7 @@
 
 out:
 	if (unlikely(frozen_buffer))	/* It's usually NULL */
-		jbd2_slab_free(frozen_buffer, bh->b_size);
+		jbd2_free(frozen_buffer, bh->b_size);
 
 	JBUFFER_TRACE(jh, "exit");
 	return error;
@@ -881,7 +880,7 @@
 
 repeat:
 	if (!jh->b_committed_data) {
-		committed_data = jbd2_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS);
+		committed_data = jbd2_alloc(jh2bh(jh)->b_size, GFP_NOFS);
 		if (!committed_data) {
 			printk(KERN_EMERG "%s: No memory for committed data\n",
 				__FUNCTION__);
@@ -908,7 +907,7 @@
 out:
 	jbd2_journal_put_journal_head(jh);
 	if (unlikely(committed_data))
-		jbd2_slab_free(committed_data, bh->b_size);
+		jbd2_free(committed_data, bh->b_size);
 	return err;
 }
 
@@ -1411,7 +1410,7 @@
 		spin_unlock(&journal->j_state_lock);
 	}
 
-	jbd_free_handle(handle);
+	jbd2_free_handle(handle);
 	return err;
 }
 
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
index 8ec9323..9728614 100644
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -228,11 +228,28 @@
 	return acl;
 }
 
+static int __jffs2_set_acl(struct inode *inode, int xprefix, struct posix_acl *acl)
+{
+	char *value = NULL;
+	size_t size = 0;
+	int rc;
+
+	if (acl) {
+		value = jffs2_acl_to_medium(acl, &size);
+		if (IS_ERR(value))
+			return PTR_ERR(value);
+	}
+	rc = do_jffs2_setxattr(inode, xprefix, "", value, size, 0);
+	if (!value && rc == -ENODATA)
+		rc = 0;
+	kfree(value);
+
+	return rc;
+}
+
 static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
 {
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-	size_t size = 0;
-	char *value = NULL;
 	int rc, xprefix;
 
 	if (S_ISLNK(inode->i_mode))
@@ -267,17 +284,7 @@
 	default:
 		return -EINVAL;
 	}
-	if (acl) {
-		value = jffs2_acl_to_medium(acl, &size);
-		if (IS_ERR(value))
-			return PTR_ERR(value);
-	}
-
-	rc = do_jffs2_setxattr(inode, xprefix, "", value, size, 0);
-	if (!value && rc == -ENODATA)
-		rc = 0;
-	if (value)
-		kfree(value);
+	rc = __jffs2_set_acl(inode, xprefix, acl);
 	if (!rc) {
 		switch(type) {
 		case ACL_TYPE_ACCESS:
@@ -312,37 +319,59 @@
 	return generic_permission(inode, mask, jffs2_check_acl);
 }
 
-int jffs2_init_acl(struct inode *inode, struct posix_acl *acl)
+int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
 {
 	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-	struct posix_acl *clone;
-	mode_t mode;
-	int rc = 0;
+	struct posix_acl *acl, *clone;
+	int rc;
 
-	f->i_acl_access = JFFS2_ACL_NOT_CACHED;
-	f->i_acl_default = JFFS2_ACL_NOT_CACHED;
+	f->i_acl_default = NULL;
+	f->i_acl_access = NULL;
 
-	if (acl) {
-		if (S_ISDIR(inode->i_mode)) {
-			rc = jffs2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
-			if (rc)
-				goto cleanup;
-		}
+	if (S_ISLNK(*i_mode))
+		return 0;	/* Symlink always has no-ACL */
+
+	acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT);
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+
+	if (!acl) {
+		*i_mode &= ~current->fs->umask;
+	} else {
+		if (S_ISDIR(*i_mode))
+			jffs2_iset_acl(inode, &f->i_acl_default, acl);
+
 		clone = posix_acl_clone(acl, GFP_KERNEL);
-		rc = -ENOMEM;
 		if (!clone)
-			goto cleanup;
-		mode = inode->i_mode;
-		rc = posix_acl_create_masq(clone, &mode);
-		if (rc >= 0) {
-			inode->i_mode = mode;
-			if (rc > 0)
-				rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
-		}
+			return -ENOMEM;
+		rc = posix_acl_create_masq(clone, (mode_t *)i_mode);
+		if (rc < 0)
+			return rc;
+		if (rc > 0)
+			jffs2_iset_acl(inode, &f->i_acl_access, clone);
+
 		posix_acl_release(clone);
 	}
- cleanup:
-	posix_acl_release(acl);
+	return 0;
+}
+
+int jffs2_init_acl_post(struct inode *inode)
+{
+	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+	int rc;
+
+	if (f->i_acl_default) {
+		rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, f->i_acl_default);
+		if (rc)
+			return rc;
+	}
+
+	if (f->i_acl_access) {
+		rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, f->i_acl_access);
+		if (rc)
+			return rc;
+	}
+
 	return rc;
 }
 
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h
index 90a2dbf..76c6ebd1 100644
--- a/fs/jffs2/acl.h
+++ b/fs/jffs2/acl.h
@@ -31,7 +31,8 @@
 extern struct posix_acl *jffs2_get_acl(struct inode *inode, int type);
 extern int jffs2_permission(struct inode *, int, struct nameidata *);
 extern int jffs2_acl_chmod(struct inode *);
-extern int jffs2_init_acl(struct inode *, struct posix_acl *);
+extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *);
+extern int jffs2_init_acl_post(struct inode *);
 extern void jffs2_clear_acl(struct jffs2_inode_info *);
 
 extern struct xattr_handler jffs2_acl_access_xattr_handler;
@@ -39,10 +40,11 @@
 
 #else
 
-#define jffs2_get_acl(inode, type)	(NULL)
-#define jffs2_permission NULL
-#define jffs2_acl_chmod(inode)		(0)
-#define jffs2_init_acl(inode,dir)	(0)
+#define jffs2_get_acl(inode, type)		(NULL)
+#define jffs2_permission			(NULL)
+#define jffs2_acl_chmod(inode)			(0)
+#define jffs2_init_acl_pre(dir_i,inode,mode)	(0)
+#define jffs2_init_acl_post(inode)		(0)
 #define jffs2_clear_acl(f)
 
 #endif	/* CONFIG_JFFS2_FS_POSIX_ACL */
diff --git a/fs/jffs2/debug.h b/fs/jffs2/debug.h
index 2a49f2c..4130ada 100644
--- a/fs/jffs2/debug.h
+++ b/fs/jffs2/debug.h
@@ -80,28 +80,28 @@
 #define JFFS2_ERROR(fmt, ...)						\
 	do {								\
 		printk(JFFS2_ERR_MSG_PREFIX				\
-			" (%d) %s: " fmt, current->pid,			\
+			" (%d) %s: " fmt, task_pid_nr(current),		\
 			__FUNCTION__ , ##__VA_ARGS__);			\
 	} while(0)
 
 #define JFFS2_WARNING(fmt, ...)						\
 	do {								\
 		printk(JFFS2_WARN_MSG_PREFIX				\
-			" (%d) %s: " fmt, current->pid,			\
+			" (%d) %s: " fmt, task_pid_nr(current),		\
 			__FUNCTION__ , ##__VA_ARGS__);			\
 	} while(0)
 
 #define JFFS2_NOTICE(fmt, ...)						\
 	do {								\
 		printk(JFFS2_NOTICE_MSG_PREFIX				\
-			" (%d) %s: " fmt, current->pid,			\
+			" (%d) %s: " fmt, task_pid_nr(current),		\
 			__FUNCTION__ , ##__VA_ARGS__);			\
 	} while(0)
 
 #define JFFS2_DEBUG(fmt, ...)						\
 	do {								\
 		printk(JFFS2_DBG_MSG_PREFIX				\
-			" (%d) %s: " fmt, current->pid,			\
+			" (%d) %s: " fmt, task_pid_nr(current),		\
 			__FUNCTION__ , ##__VA_ARGS__);			\
 	} while(0)
 
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 8353eb9..787e392 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -182,7 +182,6 @@
 	struct jffs2_inode_info *f, *dir_f;
 	struct jffs2_sb_info *c;
 	struct inode *inode;
-	struct posix_acl *acl;
 	int ret;
 
 	ri = jffs2_alloc_raw_inode();
@@ -193,7 +192,7 @@
 
 	D1(printk(KERN_DEBUG "jffs2_create()\n"));
 
-	inode = jffs2_new_inode(dir_i, mode, ri, &acl);
+	inode = jffs2_new_inode(dir_i, mode, ri);
 
 	if (IS_ERR(inode)) {
 		D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n"));
@@ -211,14 +210,6 @@
 
 	ret = jffs2_do_create(c, dir_f, f, ri,
 			      dentry->d_name.name, dentry->d_name.len);
-
-	if (ret)
-		goto fail_acl;
-
-	ret = jffs2_init_security(inode, dir_i);
-	if (ret)
-		goto fail_acl;
-	ret = jffs2_init_acl(inode, acl);
 	if (ret)
 		goto fail;
 
@@ -231,8 +222,6 @@
 		  inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages));
 	return 0;
 
- fail_acl:
-	posix_acl_release(acl);
  fail:
 	make_bad_inode(inode);
 	iput(inode);
@@ -309,7 +298,6 @@
 	struct jffs2_full_dirent *fd;
 	int namelen;
 	uint32_t alloclen;
-	struct posix_acl *acl;
 	int ret, targetlen = strlen(target);
 
 	/* FIXME: If you care. We'd need to use frags for the target
@@ -336,7 +324,7 @@
 		return ret;
 	}
 
-	inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri, &acl);
+	inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri);
 
 	if (IS_ERR(inode)) {
 		jffs2_free_raw_inode(ri);
@@ -366,7 +354,6 @@
 		up(&f->sem);
 		jffs2_complete_reservation(c);
 		jffs2_clear_inode(inode);
-		posix_acl_release(acl);
 		return PTR_ERR(fn);
 	}
 
@@ -377,7 +364,6 @@
 		up(&f->sem);
 		jffs2_complete_reservation(c);
 		jffs2_clear_inode(inode);
-		posix_acl_release(acl);
 		return -ENOMEM;
 	}
 
@@ -395,10 +381,9 @@
 	ret = jffs2_init_security(inode, dir_i);
 	if (ret) {
 		jffs2_clear_inode(inode);
-		posix_acl_release(acl);
 		return ret;
 	}
-	ret = jffs2_init_acl(inode, acl);
+	ret = jffs2_init_acl_post(inode);
 	if (ret) {
 		jffs2_clear_inode(inode);
 		return ret;
@@ -476,7 +461,6 @@
 	struct jffs2_full_dirent *fd;
 	int namelen;
 	uint32_t alloclen;
-	struct posix_acl *acl;
 	int ret;
 
 	mode |= S_IFDIR;
@@ -499,7 +483,7 @@
 		return ret;
 	}
 
-	inode = jffs2_new_inode(dir_i, mode, ri, &acl);
+	inode = jffs2_new_inode(dir_i, mode, ri);
 
 	if (IS_ERR(inode)) {
 		jffs2_free_raw_inode(ri);
@@ -526,7 +510,6 @@
 		up(&f->sem);
 		jffs2_complete_reservation(c);
 		jffs2_clear_inode(inode);
-		posix_acl_release(acl);
 		return PTR_ERR(fn);
 	}
 	/* No data here. Only a metadata node, which will be
@@ -540,10 +523,9 @@
 	ret = jffs2_init_security(inode, dir_i);
 	if (ret) {
 		jffs2_clear_inode(inode);
-		posix_acl_release(acl);
 		return ret;
 	}
-	ret = jffs2_init_acl(inode, acl);
+	ret = jffs2_init_acl_post(inode);
 	if (ret) {
 		jffs2_clear_inode(inode);
 		return ret;
@@ -639,7 +621,6 @@
 	union jffs2_device_node dev;
 	int devlen = 0;
 	uint32_t alloclen;
-	struct posix_acl *acl;
 	int ret;
 
 	if (!new_valid_dev(rdev))
@@ -666,7 +647,7 @@
 		return ret;
 	}
 
-	inode = jffs2_new_inode(dir_i, mode, ri, &acl);
+	inode = jffs2_new_inode(dir_i, mode, ri);
 
 	if (IS_ERR(inode)) {
 		jffs2_free_raw_inode(ri);
@@ -695,7 +676,6 @@
 		up(&f->sem);
 		jffs2_complete_reservation(c);
 		jffs2_clear_inode(inode);
-		posix_acl_release(acl);
 		return PTR_ERR(fn);
 	}
 	/* No data here. Only a metadata node, which will be
@@ -709,10 +689,9 @@
 	ret = jffs2_init_security(inode, dir_i);
 	if (ret) {
 		jffs2_clear_inode(inode);
-		posix_acl_release(acl);
 		return ret;
 	}
-	ret = jffs2_init_acl(inode, acl);
+	ret = jffs2_init_acl_post(inode);
 	if (ret) {
 		jffs2_clear_inode(inode);
 		return ret;
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 023a175..f9c5dd6 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -255,7 +255,7 @@
 		   _whole_ page. This helps to reduce the number of
 		   nodes in files which have many short writes, like
 		   syslog files. */
-		start = aligned_start = 0;
+		aligned_start = 0;
 	}
 
 	ri = jffs2_alloc_raw_inode();
@@ -291,14 +291,11 @@
 	}
 
 	/* Adjust writtenlen for the padding we did, so we don't confuse our caller */
-	if (writtenlen < (start&3))
-		writtenlen = 0;
-	else
-		writtenlen -= (start&3);
+	writtenlen -= min(writtenlen, (start - aligned_start));
 
 	if (writtenlen) {
-		if (inode->i_size < (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen) {
-			inode->i_size = (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen;
+		if (inode->i_size < pos + writtenlen) {
+			inode->i_size = pos + writtenlen;
 			inode->i_blocks = (inode->i_size + 511) >> 9;
 
 			inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime));
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index ed85f9a..d2e06f7 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -402,8 +402,7 @@
 
 /* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
    fill in the raw_inode while you're at it. */
-struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri,
-			       struct posix_acl **acl)
+struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
 {
 	struct inode *inode;
 	struct super_block *sb = dir_i->i_sb;
@@ -438,19 +437,11 @@
 
 	/* POSIX ACLs have to be processed now, at least partly.
 	   The umask is only applied if there's no default ACL */
-	if (!S_ISLNK(mode)) {
-		*acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT);
-		if (IS_ERR(*acl)) {
-			make_bad_inode(inode);
-			iput(inode);
-			inode = (void *)*acl;
-			*acl = NULL;
-			return inode;
-		}
-		if (!(*acl))
-			mode &= ~current->fs->umask;
-	} else {
-		*acl = NULL;
+	ret = jffs2_init_acl_pre(dir_i, inode, &mode);
+	if (ret) {
+	    make_bad_inode(inode);
+	    iput(inode);
+	    return ERR_PTR(ret);
 	}
 	ret = jffs2_do_new_inode (c, f, mode, ri);
 	if (ret) {
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index f6743a9..bf64686 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -173,15 +173,13 @@
 extern const struct inode_operations jffs2_symlink_inode_operations;
 
 /* fs.c */
-struct posix_acl;
-
 int jffs2_setattr (struct dentry *, struct iattr *);
 int jffs2_do_setattr (struct inode *, struct iattr *);
 void jffs2_read_inode (struct inode *);
 void jffs2_clear_inode (struct inode *);
 void jffs2_dirty_inode(struct inode *inode);
 struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
-			       struct jffs2_raw_inode *ri, struct posix_acl **acl);
+			       struct jffs2_raw_inode *ri);
 int jffs2_statfs (struct dentry *, struct kstatfs *);
 void jffs2_write_super (struct super_block *);
 int jffs2_remount_fs (struct super_block *, int *, char *);
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index 2f56954..147e2cb 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -465,6 +465,14 @@
 
 	up(&f->sem);
 	jffs2_complete_reservation(c);
+
+	ret = jffs2_init_security(&f->vfs_inode, &dir_f->vfs_inode);
+	if (ret)
+		return ret;
+	ret = jffs2_init_acl_post(&f->vfs_inode);
+	if (ret)
+		return ret;
+
 	ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
 				ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
 
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index df0b853..df25ecc 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -773,7 +773,7 @@
 	      getChild:
 		/* update max. number of pages to split */
 		if (BT_STACK_FULL(btstack)) {
-			/* Something's corrupted, mark filesytem dirty so
+			/* Something's corrupted, mark filesystem dirty so
 			 * chkdsk will fix it.
 			 */
 			jfs_error(sb, "stack overrun in dtSearch!");
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index f0ec72b..8e2cf2c 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -18,6 +18,8 @@
 #ifndef	_H_JFS_INODE
 #define _H_JFS_INODE
 
+struct fid;
+
 extern struct inode *ialloc(struct inode *, umode_t);
 extern int jfs_fsync(struct file *, struct dentry *, int);
 extern int jfs_ioctl(struct inode *, struct file *,
@@ -32,7 +34,10 @@
 extern void jfs_free_zero_link(struct inode *);
 extern struct dentry *jfs_get_parent(struct dentry *dentry);
 extern void jfs_get_inode_flags(struct jfs_inode_info *);
-extern struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp);
+extern struct dentry *jfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+	int fh_len, int fh_type);
+extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+	int fh_len, int fh_type);
 extern void jfs_set_inode_flags(struct inode *);
 extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
 
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 932797b..4e0a849 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -20,6 +20,7 @@
 #include <linux/fs.h>
 #include <linux/ctype.h>
 #include <linux/quotaops.h>
+#include <linux/exportfs.h>
 #include "jfs_incore.h"
 #include "jfs_superblock.h"
 #include "jfs_inode.h"
@@ -1477,13 +1478,10 @@
 	return dentry;
 }
 
-struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *jfs_nfs_get_inode(struct super_block *sb,
+		u64 ino, u32 generation)
 {
-	__u32 *objp = vobjp;
-	unsigned long ino = objp[0];
-	__u32 generation = objp[1];
 	struct inode *inode;
-	struct dentry *result;
 
 	if (ino == 0)
 		return ERR_PTR(-ESTALE);
@@ -1493,20 +1491,25 @@
 
 	if (is_bad_inode(inode) ||
 	    (generation && inode->i_generation != generation)) {
-	    	result = ERR_PTR(-ESTALE);
-		goto out_iput;
+		iput(inode);
+		return ERR_PTR(-ESTALE);
 	}
 
-	result = d_alloc_anon(inode);
-	if (!result) {
-		result = ERR_PTR(-ENOMEM);
-		goto out_iput;
-	}
-	return result;
+	return inode;
+}
 
- out_iput:
-	iput(inode);
-	return result;
+struct dentry *jfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+				    jfs_nfs_get_inode);
+}
+
+struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+				    jfs_nfs_get_inode);
 }
 
 struct dentry *jfs_get_parent(struct dentry *dentry)
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index cff60c1..314bb4f 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -48,7 +48,7 @@
 static struct kmem_cache * jfs_inode_cachep;
 
 static const struct super_operations jfs_super_operations;
-static struct export_operations jfs_export_operations;
+static const struct export_operations jfs_export_operations;
 static struct file_system_type jfs_fs_type;
 
 #define MAX_COMMIT_THREADS 64
@@ -737,8 +737,9 @@
 #endif
 };
 
-static struct export_operations jfs_export_operations = {
-	.get_dentry	= jfs_get_dentry,
+static const struct export_operations jfs_export_operations = {
+	.fh_to_dentry	= jfs_fh_to_dentry,
+	.fh_to_parent	= jfs_fh_to_parent,
 	.get_parent	= jfs_get_parent,
 };
 
diff --git a/fs/libfs.c b/fs/libfs.c
index ae51481..6e68b70 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -8,6 +8,7 @@
 #include <linux/mount.h>
 #include <linux/vfs.h>
 #include <linux/mutex.h>
+#include <linux/exportfs.h>
 
 #include <asm/uaccess.h>
 
@@ -678,6 +679,93 @@
 	return ret;
 }
 
+/*
+ * This is what d_alloc_anon should have been.  Once the exportfs
+ * argument transition has been finished I will update d_alloc_anon
+ * to this prototype and this wrapper will go away.   --hch
+ */
+static struct dentry *exportfs_d_alloc(struct inode *inode)
+{
+	struct dentry *dentry;
+
+	if (!inode)
+		return NULL;
+	if (IS_ERR(inode))
+		return ERR_PTR(PTR_ERR(inode));
+
+	dentry = d_alloc_anon(inode);
+	if (!dentry) {
+		iput(inode);
+		dentry = ERR_PTR(-ENOMEM);
+	}
+	return dentry;
+}
+
+/**
+ * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
+ * @sb:		filesystem to do the file handle conversion on
+ * @fid:	file handle to convert
+ * @fh_len:	length of the file handle in bytes
+ * @fh_type:	type of file handle
+ * @get_inode:	filesystem callback to retrieve inode
+ *
+ * This function decodes @fid as long as it has one of the well-known
+ * Linux filehandle types and calls @get_inode on it to retrieve the
+ * inode for the object specified in the file handle.
+ */
+struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type, struct inode *(*get_inode)
+			(struct super_block *sb, u64 ino, u32 gen))
+{
+	struct inode *inode = NULL;
+
+	if (fh_len < 2)
+		return NULL;
+
+	switch (fh_type) {
+	case FILEID_INO32_GEN:
+	case FILEID_INO32_GEN_PARENT:
+		inode = get_inode(sb, fid->i32.ino, fid->i32.gen);
+		break;
+	}
+
+	return exportfs_d_alloc(inode);
+}
+EXPORT_SYMBOL_GPL(generic_fh_to_dentry);
+
+/**
+ * generic_fh_to_dentry - generic helper for the fh_to_parent export operation
+ * @sb:		filesystem to do the file handle conversion on
+ * @fid:	file handle to convert
+ * @fh_len:	length of the file handle in bytes
+ * @fh_type:	type of file handle
+ * @get_inode:	filesystem callback to retrieve inode
+ *
+ * This function decodes @fid as long as it has one of the well-known
+ * Linux filehandle types and calls @get_inode on it to retrieve the
+ * inode for the _parent_ object specified in the file handle if it
+ * is specified in the file handle, or NULL otherwise.
+ */
+struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type, struct inode *(*get_inode)
+			(struct super_block *sb, u64 ino, u32 gen))
+{
+	struct inode *inode = NULL;
+
+	if (fh_len <= 2)
+		return NULL;
+
+	switch (fh_type) {
+	case FILEID_INO32_GEN_PARENT:
+		inode = get_inode(sb, fid->i32.parent_ino,
+				  (fh_len > 3 ? fid->i32.parent_gen : 0));
+		break;
+	}
+
+	return exportfs_d_alloc(inode);
+}
+EXPORT_SYMBOL_GPL(generic_fh_to_parent);
+
 EXPORT_SYMBOL(dcache_dir_close);
 EXPORT_SYMBOL(dcache_dir_lseek);
 EXPORT_SYMBOL(dcache_dir_open);
diff --git a/fs/namei.c b/fs/namei.c
index 464eecc..3b993db 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1174,7 +1174,7 @@
 out:
 	if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
 				nd->dentry->d_inode))
-		audit_inode(name, nd->dentry->d_inode);
+		audit_inode(name, nd->dentry);
 out_fail:
 	return retval;
 
@@ -1214,7 +1214,7 @@
 	retval = path_walk(name, nd);
 	if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
 				nd->dentry->d_inode))
-		audit_inode(name, nd->dentry->d_inode);
+		audit_inode(name, nd->dentry);
 
 	return retval;
 
@@ -1469,7 +1469,7 @@
 		return -ENOENT;
 
 	BUG_ON(victim->d_parent->d_inode != dir);
-	audit_inode_child(victim->d_name.name, victim->d_inode, dir);
+	audit_inode_child(victim->d_name.name, victim, dir);
 
 	error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
 	if (error)
@@ -1659,8 +1659,10 @@
 		error = locks_verify_locked(inode);
 		if (!error) {
 			DQUOT_INIT(inode);
-			
-			error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL);
+
+			error = do_truncate(dentry, 0,
+					    ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
+					    NULL);
 		}
 		put_write_access(inode);
 		if (error)
@@ -1781,7 +1783,7 @@
 	 * It already exists.
 	 */
 	mutex_unlock(&dir->d_inode->i_mutex);
-	audit_inode(pathname, path.dentry->d_inode);
+	audit_inode(pathname, path.dentry);
 
 	error = -EEXIST;
 	if (flag & O_EXCL)
@@ -2560,7 +2562,7 @@
 	if (!error) {
 		const char *new_name = old_dentry->d_name.name;
 		fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
-			      new_dentry->d_inode, old_dentry->d_inode);
+			      new_dentry->d_inode, old_dentry);
 	}
 	fsnotify_oldname_free(old_name);
 
diff --git a/fs/namespace.c b/fs/namespace.c
index 07daa79..0608388 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -246,7 +246,7 @@
 			list_add(&mnt->mnt_slave, &old->mnt_slave_list);
 			mnt->mnt_master = old;
 			CLEAR_MNT_SHARED(mnt);
-		} else {
+		} else if (!(flag & CL_PRIVATE)) {
 			if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old))
 				list_add(&mnt->mnt_share, &old->mnt_share);
 			if (IS_MNT_SLAVE(old))
@@ -746,6 +746,26 @@
 	return NULL;
 }
 
+struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry)
+{
+	struct vfsmount *tree;
+	down_read(&namespace_sem);
+	tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE);
+	up_read(&namespace_sem);
+	return tree;
+}
+
+void drop_collected_mounts(struct vfsmount *mnt)
+{
+	LIST_HEAD(umount_list);
+	down_read(&namespace_sem);
+	spin_lock(&vfsmount_lock);
+	umount_tree(mnt, 0, &umount_list);
+	spin_unlock(&vfsmount_lock);
+	up_read(&namespace_sem);
+	release_mounts(&umount_list);
+}
+
 /*
  *  @source_mnt : mount tree to be attached
  *  @nd         : place the mount tree @source_mnt is attached
@@ -1411,7 +1431,7 @@
 		mnt_flags |= MNT_RELATIME;
 
 	flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
-		   MS_NOATIME | MS_NODIRATIME | MS_RELATIME);
+		   MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT);
 
 	/* ... and get the mountpoint */
 	retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index af8b235..11833f4 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -168,7 +168,8 @@
 	spin_unlock(&inode->i_lock);
 
 	spin_unlock(&clp->cl_lock);
-	kfree(delegation);
+	if (delegation != NULL)
+		nfs_free_delegation(delegation);
 	return status;
 }
 
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 8ec7fbd..3533453 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -562,6 +562,7 @@
 	nfs_fattr_init(&fattr);
 	desc->entry = &my_entry;
 
+	nfs_block_sillyrename(dentry);
 	while(!desc->entry->eof) {
 		res = readdir_search_pagecache(desc);
 
@@ -592,6 +593,7 @@
 			break;
 		}
 	}
+	nfs_unblock_sillyrename(dentry);
 	unlock_kernel();
 	if (res > 0)
 		res = 0;
@@ -866,6 +868,7 @@
 static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
 {
 	struct dentry *res;
+	struct dentry *parent;
 	struct inode *inode = NULL;
 	int error;
 	struct nfs_fh fhandle;
@@ -894,26 +897,31 @@
 		goto out_unlock;
 	}
 
+	parent = dentry->d_parent;
+	/* Protect against concurrent sillydeletes */
+	nfs_block_sillyrename(parent);
 	error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
 	if (error == -ENOENT)
 		goto no_entry;
 	if (error < 0) {
 		res = ERR_PTR(error);
-		goto out_unlock;
+		goto out_unblock_sillyrename;
 	}
 	inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr);
 	res = (struct dentry *)inode;
 	if (IS_ERR(res))
-		goto out_unlock;
+		goto out_unblock_sillyrename;
 
 no_entry:
 	res = d_materialise_unique(dentry, inode);
 	if (res != NULL) {
 		if (IS_ERR(res))
-			goto out_unlock;
+			goto out_unblock_sillyrename;
 		dentry = res;
 	}
 	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+out_unblock_sillyrename:
+	nfs_unblock_sillyrename(parent);
 out_unlock:
 	unlock_kernel();
 out:
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index d29f90d..b3bb89f 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -131,7 +131,7 @@
 {
 	/* Ensure that dirty pages are flushed out with the right creds */
 	if (filp->f_mode & FMODE_WRITE)
-		filemap_fdatawrite(filp->f_mapping);
+		nfs_wb_all(filp->f_path.dentry->d_inode);
 	nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
 	return NFS_PROTO(inode)->file_release(inode, filp);
 }
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 6c22453..db5d96d 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -357,6 +357,10 @@
 
 	nfs_inc_stats(inode, NFSIOS_VFSSETATTR);
 
+	/* skip mode change if it's just for clearing setuid/setgid */
+	if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
+		attr->ia_valid &= ~ATTR_MODE;
+
 	if (attr->ia_valid & ATTR_SIZE) {
 		if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode))
 			attr->ia_valid &= ~ATTR_SIZE;
@@ -510,7 +514,7 @@
 	return ctx;
 }
 
-void put_nfs_open_context(struct nfs_open_context *ctx)
+static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait)
 {
 	struct inode *inode = ctx->path.dentry->d_inode;
 
@@ -518,8 +522,12 @@
 		return;
 	list_del(&ctx->list);
 	spin_unlock(&inode->i_lock);
-	if (ctx->state != NULL)
-		nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
+	if (ctx->state != NULL) {
+		if (wait)
+			nfs4_close_sync(&ctx->path, ctx->state, ctx->mode);
+		else
+			nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
+	}
 	if (ctx->cred != NULL)
 		put_rpccred(ctx->cred);
 	dput(ctx->path.dentry);
@@ -527,6 +535,16 @@
 	kfree(ctx);
 }
 
+void put_nfs_open_context(struct nfs_open_context *ctx)
+{
+	__put_nfs_open_context(ctx, 0);
+}
+
+static void put_nfs_open_context_sync(struct nfs_open_context *ctx)
+{
+	__put_nfs_open_context(ctx, 1);
+}
+
 /*
  * Ensure that mmap has a recent RPC credential for use when writing out
  * shared pages
@@ -573,7 +591,7 @@
 		spin_lock(&inode->i_lock);
 		list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
 		spin_unlock(&inode->i_lock);
-		put_nfs_open_context(ctx);
+		put_nfs_open_context_sync(ctx);
 	}
 }
 
@@ -1165,6 +1183,9 @@
 	INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);
 	nfsi->ncommit = 0;
 	nfsi->npages = 0;
+	atomic_set(&nfsi->silly_count, 1);
+	INIT_HLIST_HEAD(&nfsi->silly_list);
+	init_waitqueue_head(&nfsi->waitqueue);
 	nfs4_init_once(nfsi);
 }
 
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index d2802b1..b35069a 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -178,7 +178,7 @@
 extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
 extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
 extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
-extern int nfs4_do_close(struct path *path, struct nfs4_state *state);
+extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait);
 extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
 extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
 extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
@@ -209,6 +209,7 @@
 extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
 extern void nfs4_put_open_state(struct nfs4_state *);
 extern void nfs4_close_state(struct path *, struct nfs4_state *, mode_t);
+extern void nfs4_close_sync(struct path *, struct nfs4_state *, mode_t);
 extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t);
 extern void nfs4_schedule_state_recovery(struct nfs_client *);
 extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
@@ -235,6 +236,7 @@
 #else
 
 #define nfs4_close_state(a, b, c) do { } while (0)
+#define nfs4_close_sync(a, b, c) do { } while (0)
 
 #endif /* CONFIG_NFS_V4 */
 #endif /* __LINUX_FS_NFS_NFS4_FS.H */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index cb99fd9..f03d9d5 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1305,7 +1305,7 @@
  *
  * NOTE: Caller must be holding the sp->so_owner semaphore!
  */
-int nfs4_do_close(struct path *path, struct nfs4_state *state)
+int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
 {
 	struct nfs_server *server = NFS_SERVER(state->inode);
 	struct nfs4_closedata *calldata;
@@ -1333,8 +1333,11 @@
 	task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_close_ops, calldata);
 	if (IS_ERR(task))
 		return PTR_ERR(task);
+	status = 0;
+	if (wait)
+		status = rpc_wait_for_completion_task(task);
 	rpc_put_task(task);
-	return 0;
+	return status;
 out_free_calldata:
 	kfree(calldata);
 out:
@@ -1365,13 +1368,14 @@
 	}
 	ret = PTR_ERR(filp);
 out_close:
-	nfs4_close_state(path, state, nd->intent.open.flags);
+	nfs4_close_sync(path, state, nd->intent.open.flags);
 	return ret;
 }
 
 struct dentry *
 nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 {
+	struct dentry *parent;
 	struct path path = {
 		.mnt = nd->mnt,
 		.dentry = dentry,
@@ -1394,6 +1398,9 @@
 	cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
 	if (IS_ERR(cred))
 		return (struct dentry *)cred;
+	parent = dentry->d_parent;
+	/* Protect against concurrent sillydeletes */
+	nfs_block_sillyrename(parent);
 	state = nfs4_do_open(dir, &path, nd->intent.open.flags, &attr, cred);
 	put_rpccred(cred);
 	if (IS_ERR(state)) {
@@ -1401,12 +1408,14 @@
 			d_add(dentry, NULL);
 			nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 		}
+		nfs_unblock_sillyrename(parent);
 		return (struct dentry *)state;
 	}
 	res = d_add_unique(dentry, igrab(state->inode));
 	if (res != NULL)
 		path.dentry = res;
 	nfs_set_verifier(path.dentry, nfs_save_change_attribute(dir));
+	nfs_unblock_sillyrename(parent);
 	nfs4_intent_set_file(nd, &path, state);
 	return res;
 }
@@ -1444,7 +1453,7 @@
 		nfs4_intent_set_file(nd, &path, state);
 		return 1;
 	}
-	nfs4_close_state(&path, state, openflags);
+	nfs4_close_sync(&path, state, openflags);
 out_drop:
 	d_drop(dentry);
 	return 0;
@@ -1898,7 +1907,7 @@
 	if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0)
 		status = nfs4_intent_set_file(nd, &path, state);
 	else
-		nfs4_close_state(&path, state, flags);
+		nfs4_close_sync(&path, state, flags);
 out:
 	return status;
 }
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index bfb3626..23a9a36 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -425,7 +425,7 @@
 /*
  * Close the current file.
  */
-void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
+static void __nfs4_close(struct path *path, struct nfs4_state *state, mode_t mode, int wait)
 {
 	struct nfs4_state_owner *owner = state->owner;
 	int call_close = 0;
@@ -466,7 +466,17 @@
 		nfs4_put_open_state(state);
 		nfs4_put_state_owner(owner);
 	} else
-		nfs4_do_close(path, state);
+		nfs4_do_close(path, state, wait);
+}
+
+void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
+{
+	__nfs4_close(path, state, mode, 0);
+}
+
+void nfs4_close_sync(struct path *path, struct nfs4_state *state, mode_t mode)
+{
+	__nfs4_close(path, state, mode, 1);
 }
 
 /*
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index e87b44e..4b03345 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -43,7 +43,7 @@
  *				from being used (thanks to Leo Spiekman)
  *	Andy Walker	:	Allow to specify the NFS server in nfs_root
  *				without giving a path name
- *	Swen Thümmler	:	Allow to specify the NFS options in nfs_root
+ *	Swen Thümmler	:	Allow to specify the NFS options in nfs_root
  *				without giving a path name. Fix BOOTP request
  *				for domainname (domainname is NIS domain, not
  *				DNS domain!). Skip dummy devices for BOOTP.
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 97669ed..4f80d88 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -211,6 +211,7 @@
 	nfs_fattr_init(&fattr);
 	dprintk("NFS call  create %s\n", dentry->d_name.name);
 	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+	nfs_mark_for_revalidate(dir);
 	if (status == 0)
 		status = nfs_instantiate(dentry, &fhandle, &fattr);
 	dprintk("NFS reply create: %d\n", status);
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 1aed850..233ad38 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -11,9 +11,11 @@
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs_fs.h>
-
+#include <linux/sched.h>
+#include <linux/wait.h>
 
 struct nfs_unlinkdata {
+	struct hlist_node list;
 	struct nfs_removeargs args;
 	struct nfs_removeres res;
 	struct inode *dir;
@@ -52,6 +54,20 @@
 	return 0;
 }
 
+static void nfs_free_dname(struct nfs_unlinkdata *data)
+{
+	kfree(data->args.name.name);
+	data->args.name.name = NULL;
+	data->args.name.len = 0;
+}
+
+static void nfs_dec_sillycount(struct inode *dir)
+{
+	struct nfs_inode *nfsi = NFS_I(dir);
+	if (atomic_dec_return(&nfsi->silly_count) == 1)
+		wake_up(&nfsi->waitqueue);
+}
+
 /**
  * nfs_async_unlink_init - Initialize the RPC info
  * task: rpc_task of the sillydelete
@@ -95,6 +111,8 @@
 static void nfs_async_unlink_release(void *calldata)
 {
 	struct nfs_unlinkdata	*data = calldata;
+
+	nfs_dec_sillycount(data->dir);
 	nfs_free_unlinkdata(data);
 }
 
@@ -104,24 +122,35 @@
 	.rpc_release = nfs_async_unlink_release,
 };
 
-static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
+static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct nfs_unlinkdata *data)
 {
 	struct rpc_task *task;
-	struct dentry *parent;
-	struct inode *dir;
+	struct dentry *alias;
 
-	if (nfs_copy_dname(dentry, data) < 0)
-		goto out_free;
-
-	parent = dget_parent(dentry);
-	if (parent == NULL)
-		goto out_free;
-	dir = igrab(parent->d_inode);
-	dput(parent);
-	if (dir == NULL)
-		goto out_free;
-
-	data->dir = dir;
+	alias = d_lookup(parent, &data->args.name);
+	if (alias != NULL) {
+		int ret = 0;
+		/*
+		 * Hey, we raced with lookup... See if we need to transfer
+		 * the sillyrename information to the aliased dentry.
+		 */
+		nfs_free_dname(data);
+		spin_lock(&alias->d_lock);
+		if (!(alias->d_flags & DCACHE_NFSFS_RENAMED)) {
+			alias->d_fsdata = data;
+			alias->d_flags ^= DCACHE_NFSFS_RENAMED;
+			ret = 1;
+		}
+		spin_unlock(&alias->d_lock);
+		nfs_dec_sillycount(dir);
+		dput(alias);
+		return ret;
+	}
+	data->dir = igrab(dir);
+	if (!data->dir) {
+		nfs_dec_sillycount(dir);
+		return 0;
+	}
 	data->args.fh = NFS_FH(dir);
 	nfs_fattr_init(&data->res.dir_attr);
 
@@ -129,8 +158,64 @@
 	if (!IS_ERR(task))
 		rpc_put_task(task);
 	return 1;
+}
+
+static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
+{
+	struct dentry *parent;
+	struct inode *dir;
+	int ret = 0;
+
+
+	parent = dget_parent(dentry);
+	if (parent == NULL)
+		goto out_free;
+	dir = parent->d_inode;
+	if (nfs_copy_dname(dentry, data) != 0)
+		goto out_dput;
+	/* Non-exclusive lock protects against concurrent lookup() calls */
+	spin_lock(&dir->i_lock);
+	if (atomic_inc_not_zero(&NFS_I(dir)->silly_count) == 0) {
+		/* Deferred delete */
+		hlist_add_head(&data->list, &NFS_I(dir)->silly_list);
+		spin_unlock(&dir->i_lock);
+		ret = 1;
+		goto out_dput;
+	}
+	spin_unlock(&dir->i_lock);
+	ret = nfs_do_call_unlink(parent, dir, data);
+out_dput:
+	dput(parent);
 out_free:
-	return 0;
+	return ret;
+}
+
+void nfs_block_sillyrename(struct dentry *dentry)
+{
+	struct nfs_inode *nfsi = NFS_I(dentry->d_inode);
+
+	wait_event(nfsi->waitqueue, atomic_cmpxchg(&nfsi->silly_count, 1, 0) == 1);
+}
+
+void nfs_unblock_sillyrename(struct dentry *dentry)
+{
+	struct inode *dir = dentry->d_inode;
+	struct nfs_inode *nfsi = NFS_I(dir);
+	struct nfs_unlinkdata *data;
+
+	atomic_inc(&nfsi->silly_count);
+	spin_lock(&dir->i_lock);
+	while (!hlist_empty(&nfsi->silly_list)) {
+		if (!atomic_inc_not_zero(&nfsi->silly_count))
+			break;
+		data = hlist_entry(nfsi->silly_list.first, struct nfs_unlinkdata, list);
+		hlist_del(&data->list);
+		spin_unlock(&dir->i_lock);
+		if (nfs_do_call_unlink(dentry, dir, data) == 0)
+			nfs_free_unlinkdata(data);
+		spin_lock(&dir->i_lock);
+	}
+	spin_unlock(&dir->i_lock);
 }
 
 /**
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 0cf9d1c..89527a4 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -174,8 +174,6 @@
 		return;
 	if (count != nfs_page_length(page))
 		return;
-	if (count != PAGE_CACHE_SIZE)
-		zero_user_page(page, count, PAGE_CACHE_SIZE - count, KM_USER0);
 	SetPageUptodate(page);
 }
 
@@ -627,7 +625,8 @@
 				return ERR_PTR(error);
 			}
 			spin_unlock(&inode->i_lock);
-			return new;
+			req = new;
+			goto zero_page;
 		}
 		spin_unlock(&inode->i_lock);
 
@@ -655,13 +654,23 @@
 	if (offset < req->wb_offset) {
 		req->wb_offset = offset;
 		req->wb_pgbase = offset;
-		req->wb_bytes = rqend - req->wb_offset;
+		req->wb_bytes = max(end, rqend) - req->wb_offset;
+		goto zero_page;
 	}
 
 	if (end > rqend)
 		req->wb_bytes = end - req->wb_offset;
 
 	return req;
+zero_page:
+	/* If this page might potentially be marked as up to date,
+	 * then we need to zero any uninitalised data. */
+	if (req->wb_pgbase == 0 && req->wb_bytes != PAGE_CACHE_SIZE
+			&& !PageUptodate(req->wb_page))
+		zero_user_page(req->wb_page, req->wb_bytes,
+				PAGE_CACHE_SIZE - req->wb_bytes,
+				KM_USER0);
+	return req;
 }
 
 int nfs_flush_incompatible(struct file *file, struct page *page)
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 04b2667..66d0aeb 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -386,15 +386,13 @@
 		dprintk("exp_export: export of non-dev fs without fsid\n");
 		return -EINVAL;
 	}
-	if (!inode->i_sb->s_export_op) {
+
+	if (!inode->i_sb->s_export_op ||
+	    !inode->i_sb->s_export_op->fh_to_dentry) {
 		dprintk("exp_export: export of invalid fs type.\n");
 		return -EINVAL;
 	}
 
-	/* Ok, we can export it */;
-	if (!inode->i_sb->s_export_op->find_exported_dentry)
-		inode->i_sb->s_export_op->find_exported_dentry =
-			find_exported_dentry;
 	return 0;
 
 }
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ebd03cc..6f03918 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -88,7 +88,7 @@
 {
 	struct xdr_netobj cksum;
 	struct hash_desc desc;
-	struct scatterlist sg[1];
+	struct scatterlist sg;
 	__be32 status = nfserr_resource;
 
 	dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
@@ -102,11 +102,9 @@
 	if (cksum.data == NULL)
  		goto out;
 
-	sg[0].page = virt_to_page(clname->data);
-	sg[0].offset = offset_in_page(clname->data);
-	sg[0].length = clname->len;
+	sg_init_one(&sg, clname->data, clname->len);
 
-	if (crypto_hash_digest(&desc, sg, sg->length, cksum.data))
+	if (crypto_hash_digest(&desc, &sg, sg.length, cksum.data))
 		goto out;
 
 	md5_to_hex(dname, cksum.data);
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 7011d62a..4f712e9 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -115,8 +115,7 @@
 	dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
 
 	if (!fhp->fh_dentry) {
-		__u32 *datap=NULL;
-		__u32 tfh[3];		/* filehandle fragment for oldstyle filehandles */
+		struct fid *fid = NULL, sfid;
 		int fileid_type;
 		int data_left = fh->fh_size/4;
 
@@ -128,7 +127,6 @@
 
 		if (fh->fh_version == 1) {
 			int len;
-			datap = fh->fh_auth;
 			if (--data_left<0) goto out;
 			switch (fh->fh_auth_type) {
 			case 0: break;
@@ -144,9 +142,11 @@
 				fh->fh_fsid[1] = fh->fh_fsid[2];
 			}
 			if ((data_left -= len)<0) goto out;
-			exp = rqst_exp_find(rqstp, fh->fh_fsid_type, datap);
-			datap += len;
+			exp = rqst_exp_find(rqstp, fh->fh_fsid_type,
+					    fh->fh_auth);
+			fid = (struct fid *)(fh->fh_auth + len);
 		} else {
+			__u32 tfh[2];
 			dev_t xdev;
 			ino_t xino;
 			if (fh->fh_size != NFS_FHSIZE)
@@ -190,22 +190,22 @@
 			error = nfserr_badhandle;
 
 		if (fh->fh_version != 1) {
-			tfh[0] = fh->ofh_ino;
-			tfh[1] = fh->ofh_generation;
-			tfh[2] = fh->ofh_dirino;
-			datap = tfh;
+			sfid.i32.ino = fh->ofh_ino;
+			sfid.i32.gen = fh->ofh_generation;
+			sfid.i32.parent_ino = fh->ofh_dirino;
+			fid = &sfid;
 			data_left = 3;
 			if (fh->ofh_dirino == 0)
-				fileid_type = 1;
+				fileid_type = FILEID_INO32_GEN;
 			else
-				fileid_type = 2;
+				fileid_type = FILEID_INO32_GEN_PARENT;
 		} else
 			fileid_type = fh->fh_fileid_type;
 
-		if (fileid_type == 0)
+		if (fileid_type == FILEID_ROOT)
 			dentry = dget(exp->ex_dentry);
 		else {
-			dentry = exportfs_decode_fh(exp->ex_mnt, datap,
+			dentry = exportfs_decode_fh(exp->ex_mnt, fid,
 					data_left, fileid_type,
 					nfsd_acceptable, exp);
 		}
@@ -286,16 +286,21 @@
  * an inode.  In this case a call to fh_update should be made
  * before the fh goes out on the wire ...
  */
-static inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
-			     __u32 *datap, int *maxsize)
+static void _fh_update(struct svc_fh *fhp, struct svc_export *exp,
+		struct dentry *dentry)
 {
-	if (dentry == exp->ex_dentry) {
-		*maxsize = 0;
-		return 0;
-	}
+	if (dentry != exp->ex_dentry) {
+		struct fid *fid = (struct fid *)
+			(fhp->fh_handle.fh_auth + fhp->fh_handle.fh_size/4 - 1);
+		int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
+		int subtreecheck = !(exp->ex_flags & NFSEXP_NOSUBTREECHECK);
 
-	return exportfs_encode_fh(dentry, datap, maxsize,
-			  !(exp->ex_flags & NFSEXP_NOSUBTREECHECK));
+		fhp->fh_handle.fh_fileid_type =
+			exportfs_encode_fh(dentry, fid, &maxsize, subtreecheck);
+		fhp->fh_handle.fh_size += maxsize * 4;
+	} else {
+		fhp->fh_handle.fh_fileid_type = FILEID_ROOT;
+	}
 }
 
 /*
@@ -457,12 +462,8 @@
 		datap += len/4;
 		fhp->fh_handle.fh_size = 4 + len;
 
-		if (inode) {
-			int size = (fhp->fh_maxsize-len-4)/4;
-			fhp->fh_handle.fh_fileid_type =
-				_fh_update(dentry, exp, datap, &size);
-			fhp->fh_handle.fh_size += size*4;
-		}
+		if (inode)
+			_fh_update(fhp, exp, dentry);
 		if (fhp->fh_handle.fh_fileid_type == 255)
 			return nfserr_opnotsupp;
 	}
@@ -479,7 +480,6 @@
 fh_update(struct svc_fh *fhp)
 {
 	struct dentry *dentry;
-	__u32 *datap;
 
 	if (!fhp->fh_dentry)
 		goto out_bad;
@@ -490,15 +490,10 @@
 	if (fhp->fh_handle.fh_version != 1) {
 		_fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle);
 	} else {
-		int size;
-		if (fhp->fh_handle.fh_fileid_type != 0)
+		if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT)
 			goto out;
-		datap = fhp->fh_handle.fh_auth+
-			fhp->fh_handle.fh_size/4 -1;
-		size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
-		fhp->fh_handle.fh_fileid_type =
-			_fh_update(dentry, fhp->fh_export, datap, &size);
-		fhp->fh_handle.fh_size += size*4;
+
+		_fh_update(fhp, fhp->fh_export, dentry);
 		if (fhp->fh_handle.fh_fileid_type == 255)
 			return nfserr_opnotsupp;
 	}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 819545d..d019918 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -364,14 +364,23 @@
 	if (iap->ia_valid & ATTR_MODE) {
 		iap->ia_mode &= S_IALLUGO;
 		imode = iap->ia_mode |= (imode & ~S_IALLUGO);
+		/* if changing uid/gid revoke setuid/setgid in mode */
+		if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) {
+			iap->ia_valid |= ATTR_KILL_PRIV;
+			iap->ia_mode &= ~S_ISUID;
+		}
+		if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)
+			iap->ia_mode &= ~S_ISGID;
+	} else {
+		/*
+		 * Revoke setuid/setgid bit on chown/chgrp
+		 */
+		if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid)
+			iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV;
+		if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)
+			iap->ia_valid |= ATTR_KILL_SGID;
 	}
 
-	/* Revoke setuid/setgid bit on chown/chgrp */
-	if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid)
-		iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV;
-	if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)
-		iap->ia_valid |= ATTR_KILL_SGID;
-
 	/* Change the attributes. */
 
 	iap->ia_valid |= ATTR_CTIME;
@@ -1020,13 +1029,13 @@
 		if (EX_WGATHER(exp)) {
 			if (atomic_read(&inode->i_writecount) > 1
 			    || (last_ino == inode->i_ino && last_dev == inode->i_sb->s_dev)) {
-				dprintk("nfsd: write defer %d\n", current->pid);
+				dprintk("nfsd: write defer %d\n", task_pid_nr(current));
 				msleep(10);
-				dprintk("nfsd: write resume %d\n", current->pid);
+				dprintk("nfsd: write resume %d\n", task_pid_nr(current));
 			}
 
 			if (inode->i_state & I_DIRTY) {
-				dprintk("nfsd: write sync %d\n", current->pid);
+				dprintk("nfsd: write sync %d\n", task_pid_nr(current));
 				host_err=nfsd_sync(file);
 			}
 #if 0
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c
index e790581..64965e1 100644
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -111,7 +111,7 @@
 	int c, nc;
 	const struct utf8_table *t;
   
-	if (s == 0)
+	if (!s)
 		return 0;
   
 	l = wc;
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 345798e..37c11e1 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -382,7 +382,7 @@
 	  own locking so it does not matter if the vfs inode is locked.
 	- Fix bug in mft record writing where we forgot to set the device in
 	  the buffers when mapping them after the VM had discarded them.
-	  Thanks to Martin MOKREJŠ for the bug report.
+	  Thanks to Martin MOKREJÅ for the bug report.
 
 2.1.22 - Many bug and race fixes and error handling improvements.
 
@@ -1585,7 +1585,7 @@
 	  for reading $MFT (ntfs_mft_readpage). In the process create dedicated
 	  address space operations (ntfs_mft_aops) for $MFT inode mapping. Also
 	  removed the now superfluous exports from the kernel core patch.
-	- Fix a bug where kfree() was used insted of ntfs_free().
+	- Fix a bug where kfree() was used instead of ntfs_free().
 	- Change map_mft_record() to take ntfs_inode as argument instead of
 	  vfs inode. Dito for unmap_mft_record(). Adapt all callers.
 	- Add pointer to ntfs_volume to ntfs_inode.
diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c
index e93c614..e1781c8 100644
--- a/fs/ntfs/namei.c
+++ b/fs/ntfs/namei.c
@@ -450,58 +450,40 @@
 	return parent_dent;
 }
 
-/**
- * ntfs_get_dentry - find a dentry for the inode from a file handle sub-fragment
- * @sb:		super block identifying the mounted ntfs volume
- * @fh:		the file handle sub-fragment
- *
- * Find a dentry for the inode given a file handle sub-fragment.  This function
- * is called from fs/exportfs/expfs.c::find_exported_dentry() which in turn is
- * called from the default ->decode_fh() which is export_decode_fh() in the
- * same file.  The code is closely based on the default ->get_dentry() helper
- * fs/exportfs/expfs.c::get_object().
- *
- * The @fh contains two 32-bit unsigned values, the first one is the inode
- * number and the second one is the inode generation.
- *
- * Return the dentry on success or the error code on error (IS_ERR() is true).
- */
-static struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)
+static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
+		u64 ino, u32 generation)
 {
-	struct inode *vi;
-	struct dentry *dent;
-	unsigned long ino = ((u32 *)fh)[0];
-	u32 gen = ((u32 *)fh)[1];
+	struct inode *inode;
 
-	ntfs_debug("Entering for inode 0x%lx, generation 0x%x.", ino, gen);
-	vi = ntfs_iget(sb, ino);
-	if (IS_ERR(vi)) {
-		ntfs_error(sb, "Failed to get inode 0x%lx.", ino);
-		return (struct dentry *)vi;
+	inode = ntfs_iget(sb, ino);
+	if (!IS_ERR(inode)) {
+		if (is_bad_inode(inode) || inode->i_generation != generation) {
+			iput(inode);
+			inode = ERR_PTR(-ESTALE);
+		}
 	}
-	if (unlikely(is_bad_inode(vi) || vi->i_generation != gen)) {
-		/* We didn't find the right inode. */
-		ntfs_error(sb, "Inode 0x%lx, bad count: %d %d or version 0x%x "
-				"0x%x.", vi->i_ino, vi->i_nlink,
-				atomic_read(&vi->i_count), vi->i_generation,
-				gen);
-		iput(vi);
-		return ERR_PTR(-ESTALE);
-	}
-	/* Now find a dentry.  If possible, get a well-connected one. */
-	dent = d_alloc_anon(vi);
-	if (unlikely(!dent)) {
-		iput(vi);
-		return ERR_PTR(-ENOMEM);
-	}
-	ntfs_debug("Done for inode 0x%lx, generation 0x%x.", ino, gen);
-	return dent;
+
+	return inode;
+}
+
+static struct dentry *ntfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+				    ntfs_nfs_get_inode);
+}
+
+static struct dentry *ntfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+				    ntfs_nfs_get_inode);
 }
 
 /**
  * Export operations allowing NFS exporting of mounted NTFS partitions.
  *
- * We use the default ->decode_fh() and ->encode_fh() for now.  Note that they
+ * We use the default ->encode_fh() for now.  Note that they
  * use 32 bits to store the inode number which is an unsigned long so on 64-bit
  * architectures is usually 64 bits so it would all fail horribly on huge
  * volumes.  I guess we need to define our own encode and decode fh functions
@@ -517,10 +499,9 @@
  * allowing the inode number 0 which is used in NTFS for the system file $MFT
  * and due to using iget() whereas NTFS needs ntfs_iget().
  */
-struct export_operations ntfs_export_ops = {
+const struct export_operations ntfs_export_ops = {
 	.get_parent	= ntfs_get_parent,	/* Find the parent of a given
 						   directory. */
-	.get_dentry	= ntfs_get_dentry,	/* Find a dentry for the inode
-						   given a file handle
-						   sub-fragment. */
+	.fh_to_dentry	= ntfs_fh_to_dentry,
+	.fh_to_parent	= ntfs_fh_to_parent,
 };
diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h
index d73f5a9..d6a340bf 100644
--- a/fs/ntfs/ntfs.h
+++ b/fs/ntfs/ntfs.h
@@ -69,7 +69,7 @@
 extern const struct  file_operations ntfs_empty_file_ops;
 extern const struct inode_operations ntfs_empty_inode_ops;
 
-extern struct export_operations ntfs_export_ops;
+extern const struct export_operations ntfs_export_ops;
 
 /**
  * NTFS_SB - return the ntfs volume given a vfs super block
diff --git a/fs/ntfs/sysctl.c b/fs/ntfs/sysctl.c
index 4847fbf..9ef85e6 100644
--- a/fs/ntfs/sysctl.c
+++ b/fs/ntfs/sysctl.c
@@ -1,7 +1,7 @@
 /*
  * sysctl.c - Code for sysctl handling in NTFS Linux kernel driver. Part of
  *	      the Linux-NTFS project. Adapted from the old NTFS driver,
- *	      Copyright (C) 1997 Martin von Löwis, Régis Duchesne
+ *	      Copyright (C) 1997 Martin von Löwis, Régis Duchesne
  *
  * Copyright (c) 2002-2005 Anton Altaparmakov
  *
diff --git a/fs/ntfs/sysctl.h b/fs/ntfs/sysctl.h
index beda5bf9..d4f8ce9 100644
--- a/fs/ntfs/sysctl.h
+++ b/fs/ntfs/sysctl.h
@@ -1,7 +1,7 @@
 /*
  * sysctl.h - Defines for sysctl handling in NTFS Linux kernel driver. Part of
  *	      the Linux-NTFS project. Adapted from the old NTFS driver,
- *	      Copyright (C) 1997 Martin von Löwis, Régis Duchesne
+ *	      Copyright (C) 1997 Martin von Löwis, Régis Duchesne
  *
  * Copyright (c) 2002-2004 Anton Altaparmakov
  *
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index f14b541..9cc7c04 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -1372,7 +1372,7 @@
 
 	spin_lock(&o2hb_live_lock);
 	if (reg->hr_task)
-		pid = reg->hr_task->pid;
+		pid = task_pid_nr(reg->hr_task);
 	spin_unlock(&o2hb_live_lock);
 
 	if (!pid)
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
index 75cd877..cd04606 100644
--- a/fs/ocfs2/cluster/masklog.h
+++ b/fs/ocfs2/cluster/masklog.h
@@ -192,7 +192,7 @@
  * previous token if args expands to nothing.
  */
 #define __mlog_printk(level, fmt, args...)				\
-	printk(level "(%u,%lu):%s:%d " fmt, current->pid,		\
+	printk(level "(%u,%lu):%s:%d " fmt, task_pid_nr(current),	\
 	       __mlog_cpu_guess, __PRETTY_FUNCTION__, __LINE__ ,	\
 	       ##args)
 
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index 014e739..3094ddb 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -376,7 +376,7 @@
  * directory locks. The dentries have already been deleted on other
  * nodes via ocfs2_remote_dentry_delete().
  *
- * Normally, the VFS handles the d_move() for the file sytem, after
+ * Normally, the VFS handles the d_move() for the file system, after
  * the ->rename() callback. OCFS2 wants to handle this internally, so
  * the new lock can be created atomically with respect to the cluster.
  */
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c
index a2c3316..2fde7bf 100644
--- a/fs/ocfs2/dlm/dlmrecovery.c
+++ b/fs/ocfs2/dlm/dlmrecovery.c
@@ -259,7 +259,7 @@
 	struct dlm_lock_resource *res;
 
 	mlog(ML_NOTICE, "%s(%d): recovery info, state=%s, dead=%u, master=%u\n",
-	     dlm->name, dlm->dlm_reco_thread_task->pid,
+	     dlm->name, task_pid_nr(dlm->dlm_reco_thread_task),
 	     dlm->reco.state & DLM_RECO_STATE_ACTIVE ? "ACTIVE" : "inactive",
 	     dlm->reco.dead_node, dlm->reco.new_master);
 
@@ -420,7 +420,7 @@
 	if (dlm_in_recovery(dlm)) {
 		mlog(0, "%s: reco thread %d in recovery: "
 		     "state=%d, master=%u, dead=%u\n",
-		     dlm->name, dlm->dlm_reco_thread_task->pid,
+		     dlm->name, task_pid_nr(dlm->dlm_reco_thread_task),
 		     dlm->reco.state, dlm->reco.new_master,
 		     dlm->reco.dead_node);
 	}
@@ -483,7 +483,7 @@
 		return 0;
 	}
 	mlog(0, "%s(%d):recovery thread found node %u in the recovery map!\n",
-	     dlm->name, dlm->dlm_reco_thread_task->pid,
+	     dlm->name, task_pid_nr(dlm->dlm_reco_thread_task),
 	     dlm->reco.dead_node);
 	spin_unlock(&dlm->spinlock);
 
@@ -507,7 +507,7 @@
 		mlog(0, "another node will master this recovery session.\n");
 	}
 	mlog(0, "dlm=%s (%d), new_master=%u, this node=%u, dead_node=%u\n",
-	     dlm->name, dlm->dlm_reco_thread_task->pid, dlm->reco.new_master,
+	     dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), dlm->reco.new_master,
 	     dlm->node_num, dlm->reco.dead_node);
 
 	/* it is safe to start everything back up here
@@ -520,7 +520,7 @@
 
 master_here:
 	mlog(0, "(%d) mastering recovery of %s:%u here(this=%u)!\n",
-	     dlm->dlm_reco_thread_task->pid,
+	     task_pid_nr(dlm->dlm_reco_thread_task),
 	     dlm->name, dlm->reco.dead_node, dlm->node_num);
 
 	status = dlm_remaster_locks(dlm, dlm->reco.dead_node);
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index c3bbc19..535bfa9 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -45,9 +45,9 @@
 	u32 ih_generation;
 };
 
-static struct dentry *ocfs2_get_dentry(struct super_block *sb, void *vobjp)
+static struct dentry *ocfs2_get_dentry(struct super_block *sb,
+		struct ocfs2_inode_handle *handle)
 {
-	struct ocfs2_inode_handle *handle = vobjp;
 	struct inode *inode;
 	struct dentry *result;
 
@@ -194,54 +194,37 @@
 	return type;
 }
 
-static struct dentry *ocfs2_decode_fh(struct super_block *sb, u32 *fh_in,
-				      int fh_len, int fileid_type,
-				      int (*acceptable)(void *context,
-						        struct dentry *de),
-				      void *context)
+static struct dentry *ocfs2_fh_to_dentry(struct super_block *sb,
+		struct fid *fid, int fh_len, int fh_type)
 {
-	struct ocfs2_inode_handle handle, parent;
-	struct dentry *ret = NULL;
-	__le32 *fh = (__force __le32 *) fh_in;
+	struct ocfs2_inode_handle handle;
 
-	mlog_entry("(0x%p, 0x%p, %d, %d, 0x%p, 0x%p)\n",
-		   sb, fh, fh_len, fileid_type, acceptable, context);
+	if (fh_len < 3 || fh_type > 2)
+		return NULL;
 
-	if (fh_len < 3 || fileid_type > 2)
-		goto bail;
-
-	if (fileid_type == 2) {
-		if (fh_len < 6)
-			goto bail;
-
-		parent.ih_blkno = (u64)le32_to_cpu(fh[3]) << 32;
-		parent.ih_blkno |= (u64)le32_to_cpu(fh[4]);
-		parent.ih_generation = le32_to_cpu(fh[5]);
-
-		mlog(0, "Decoding parent: blkno: %llu, generation: %u\n",
-		     (unsigned long long)parent.ih_blkno,
-		     parent.ih_generation);
-	}
-
-	handle.ih_blkno = (u64)le32_to_cpu(fh[0]) << 32;
-	handle.ih_blkno |= (u64)le32_to_cpu(fh[1]);
-	handle.ih_generation = le32_to_cpu(fh[2]);
-
-	mlog(0, "Encoding fh: blkno: %llu, generation: %u\n",
-	     (unsigned long long)handle.ih_blkno, handle.ih_generation);
-
-	ret = ocfs2_export_ops.find_exported_dentry(sb, &handle, &parent,
-						    acceptable, context);
-
-bail:
-	mlog_exit_ptr(ret);
-	return ret;
+	handle.ih_blkno = (u64)le32_to_cpu(fid->raw[0]) << 32;
+	handle.ih_blkno |= (u64)le32_to_cpu(fid->raw[1]);
+	handle.ih_generation = le32_to_cpu(fid->raw[2]);
+	return ocfs2_get_dentry(sb, &handle);
 }
 
-struct export_operations ocfs2_export_ops = {
-	.decode_fh	= ocfs2_decode_fh,
-	.encode_fh	= ocfs2_encode_fh,
+static struct dentry *ocfs2_fh_to_parent(struct super_block *sb,
+		struct fid *fid, int fh_len, int fh_type)
+{
+	struct ocfs2_inode_handle parent;
 
+	if (fh_type != 2 || fh_len < 6)
+		return NULL;
+
+	parent.ih_blkno = (u64)le32_to_cpu(fid->raw[3]) << 32;
+	parent.ih_blkno |= (u64)le32_to_cpu(fid->raw[4]);
+	parent.ih_generation = le32_to_cpu(fid->raw[5]);
+	return ocfs2_get_dentry(sb, &parent);
+}
+
+const struct export_operations ocfs2_export_ops = {
+	.encode_fh	= ocfs2_encode_fh,
+	.fh_to_dentry	= ocfs2_fh_to_dentry,
+	.fh_to_parent	= ocfs2_fh_to_parent,
 	.get_parent	= ocfs2_get_parent,
-	.get_dentry	= ocfs2_get_dentry,
 };
diff --git a/fs/ocfs2/export.h b/fs/ocfs2/export.h
index e08bed9..41a7386 100644
--- a/fs/ocfs2/export.h
+++ b/fs/ocfs2/export.h
@@ -28,6 +28,6 @@
 
 #include <linux/exportfs.h>
 
-extern struct export_operations ocfs2_export_ops;
+extern const struct export_operations ocfs2_export_ops;
 
 #endif /* OCFS2_EXPORT_H */
diff --git a/fs/open.c b/fs/open.c
index 7538514..3b69c53 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -569,7 +569,7 @@
 	dentry = file->f_path.dentry;
 	inode = dentry->d_inode;
 
-	audit_inode(NULL, inode);
+	audit_inode(NULL, dentry);
 
 	err = -EROFS;
 	if (IS_RDONLY(inode))
@@ -727,7 +727,7 @@
 		goto out;
 
 	dentry = file->f_path.dentry;
-	audit_inode(NULL, dentry->d_inode);
+	audit_inode(NULL, dentry);
 	error = chown_common(dentry, user, group);
 	fput(file);
 out:
diff --git a/fs/pnode.h b/fs/pnode.h
index d45bd8e..f249be2 100644
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -22,6 +22,7 @@
 #define CL_COPY_ALL 		0x04
 #define CL_MAKE_SHARED 		0x08
 #define CL_PROPAGATION 		0x10
+#define CL_PRIVATE 		0x20
 
 static inline void set_mnt_shared(struct vfsmount *mnt)
 {
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 27b59f5..63c95af 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -77,6 +77,7 @@
 #include <linux/cpuset.h>
 #include <linux/rcupdate.h>
 #include <linux/delayacct.h>
+#include <linux/pid_namespace.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -145,8 +146,7 @@
 					    TASK_UNINTERRUPTIBLE |
 					    TASK_STOPPED |
 					    TASK_TRACED)) |
-			(tsk->exit_state & (EXIT_ZOMBIE |
-					    EXIT_DEAD));
+					   tsk->exit_state;
 	const char **p = &task_state_array[0];
 
 	while (state) {
@@ -161,8 +161,15 @@
 	struct group_info *group_info;
 	int g;
 	struct fdtable *fdt = NULL;
+	struct pid_namespace *ns;
+	pid_t ppid, tpid;
 
+	ns = current->nsproxy->pid_ns;
 	rcu_read_lock();
+	ppid = pid_alive(p) ?
+		task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
+	tpid = pid_alive(p) && p->ptrace ?
+		task_ppid_nr_ns(rcu_dereference(p->parent), ns) : 0;
 	buffer += sprintf(buffer,
 		"State:\t%s\n"
 		"Tgid:\t%d\n"
@@ -172,9 +179,9 @@
 		"Uid:\t%d\t%d\t%d\t%d\n"
 		"Gid:\t%d\t%d\t%d\t%d\n",
 		get_task_state(p),
-		p->tgid, p->pid,
-		pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
-		pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
+		task_tgid_nr_ns(p, ns),
+		task_pid_nr_ns(p, ns),
+		ppid, tpid,
 		p->uid, p->euid, p->suid, p->fsuid,
 		p->gid, p->egid, p->sgid, p->fsgid);
 
@@ -394,6 +401,9 @@
 	unsigned long rsslim = 0;
 	char tcomm[sizeof(task->comm)];
 	unsigned long flags;
+	struct pid_namespace *ns;
+
+	ns = current->nsproxy->pid_ns;
 
 	state = *get_task_state(task);
 	vsize = eip = esp = 0;
@@ -416,7 +426,7 @@
 		struct signal_struct *sig = task->signal;
 
 		if (sig->tty) {
-			tty_pgrp = pid_nr(sig->tty->pgrp);
+			tty_pgrp = pid_nr_ns(sig->tty->pgrp, ns);
 			tty_nr = new_encode_dev(tty_devnum(sig->tty));
 		}
 
@@ -446,12 +456,12 @@
 			maj_flt += sig->maj_flt;
 			utime = cputime_add(utime, sig->utime);
 			stime = cputime_add(stime, sig->stime);
-			gtime += cputime_add(gtime, sig->gtime);
+			gtime = cputime_add(gtime, sig->gtime);
 		}
 
-		sid = signal_session(sig);
-		pgid = process_group(task);
-		ppid = rcu_dereference(task->real_parent)->tgid;
+		sid = task_session_nr_ns(task, ns);
+		pgid = task_pgrp_nr_ns(task, ns);
+		ppid = task_ppid_nr_ns(task, ns);
 
 		unlock_task_sighand(task, &flags);
 	}
@@ -483,7 +493,7 @@
 	res = sprintf(buffer, "%d (%s) %c %d %d %d %d %d %u %lu \
 %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
 %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n",
-		task->pid,
+		task_pid_nr_ns(task, ns),
 		tcomm,
 		state,
 		ppid,
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 4fe74d1..aeaf0d0 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -63,16 +63,19 @@
 #include <linux/mm.h>
 #include <linux/rcupdate.h>
 #include <linux/kallsyms.h>
+#include <linux/resource.h>
 #include <linux/module.h>
 #include <linux/mount.h>
 #include <linux/security.h>
 #include <linux/ptrace.h>
+#include <linux/cgroup.h>
 #include <linux/cpuset.h>
 #include <linux/audit.h>
 #include <linux/poll.h>
 #include <linux/nsproxy.h>
 #include <linux/oom.h>
 #include <linux/elf.h>
+#include <linux/pid_namespace.h>
 #include "internal.h"
 
 /* NOTE:
@@ -301,6 +304,78 @@
 	return sprintf(buffer, "%lu\n", points);
 }
 
+struct limit_names {
+	char *name;
+	char *unit;
+};
+
+static const struct limit_names lnames[RLIM_NLIMITS] = {
+	[RLIMIT_CPU] = {"Max cpu time", "ms"},
+	[RLIMIT_FSIZE] = {"Max file size", "bytes"},
+	[RLIMIT_DATA] = {"Max data size", "bytes"},
+	[RLIMIT_STACK] = {"Max stack size", "bytes"},
+	[RLIMIT_CORE] = {"Max core file size", "bytes"},
+	[RLIMIT_RSS] = {"Max resident set", "bytes"},
+	[RLIMIT_NPROC] = {"Max processes", "processes"},
+	[RLIMIT_NOFILE] = {"Max open files", "files"},
+	[RLIMIT_MEMLOCK] = {"Max locked memory", "bytes"},
+	[RLIMIT_AS] = {"Max address space", "bytes"},
+	[RLIMIT_LOCKS] = {"Max file locks", "locks"},
+	[RLIMIT_SIGPENDING] = {"Max pending signals", "signals"},
+	[RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"},
+	[RLIMIT_NICE] = {"Max nice priority", NULL},
+	[RLIMIT_RTPRIO] = {"Max realtime priority", NULL},
+};
+
+/* Display limits for a process */
+static int proc_pid_limits(struct task_struct *task, char *buffer)
+{
+	unsigned int i;
+	int count = 0;
+	unsigned long flags;
+	char *bufptr = buffer;
+
+	struct rlimit rlim[RLIM_NLIMITS];
+
+	rcu_read_lock();
+	if (!lock_task_sighand(task,&flags)) {
+		rcu_read_unlock();
+		return 0;
+	}
+	memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS);
+	unlock_task_sighand(task, &flags);
+	rcu_read_unlock();
+
+	/*
+	 * print the file header
+	 */
+	count += sprintf(&bufptr[count], "%-25s %-20s %-20s %-10s\n",
+			"Limit", "Soft Limit", "Hard Limit", "Units");
+
+	for (i = 0; i < RLIM_NLIMITS; i++) {
+		if (rlim[i].rlim_cur == RLIM_INFINITY)
+			count += sprintf(&bufptr[count], "%-25s %-20s ",
+					 lnames[i].name, "unlimited");
+		else
+			count += sprintf(&bufptr[count], "%-25s %-20lu ",
+					 lnames[i].name, rlim[i].rlim_cur);
+
+		if (rlim[i].rlim_max == RLIM_INFINITY)
+			count += sprintf(&bufptr[count], "%-20s ", "unlimited");
+		else
+			count += sprintf(&bufptr[count], "%-20lu ",
+					 rlim[i].rlim_max);
+
+		if (lnames[i].unit)
+			count += sprintf(&bufptr[count], "%-10s\n",
+					 lnames[i].unit);
+		else
+			count += sprintf(&bufptr[count], "\n");
+	}
+
+	return count;
+}
+
 /************************************************************************/
 /*                       Here the fs part begins                        */
 /************************************************************************/
@@ -349,18 +424,21 @@
 static int mounts_open(struct inode *inode, struct file *file)
 {
 	struct task_struct *task = get_proc_task(inode);
+	struct nsproxy *nsp;
 	struct mnt_namespace *ns = NULL;
 	struct proc_mounts *p;
 	int ret = -EINVAL;
 
 	if (task) {
-		task_lock(task);
-		if (task->nsproxy) {
-			ns = task->nsproxy->mnt_ns;
+		rcu_read_lock();
+		nsp = task_nsproxy(task);
+		if (nsp) {
+			ns = nsp->mnt_ns;
 			if (ns)
 				get_mnt_ns(ns);
 		}
-		task_unlock(task);
+		rcu_read_unlock();
+
 		put_task_struct(task);
 	}
 
@@ -423,16 +501,20 @@
 
 	if (!ret) {
 		struct seq_file *m = file->private_data;
+		struct nsproxy *nsp;
 		struct mnt_namespace *mnt_ns = NULL;
 		struct task_struct *task = get_proc_task(inode);
 
 		if (task) {
-			task_lock(task);
-			if (task->nsproxy)
-				mnt_ns = task->nsproxy->mnt_ns;
-			if (mnt_ns)
-				get_mnt_ns(mnt_ns);
-			task_unlock(task);
+			rcu_read_lock();
+			nsp = task_nsproxy(task);
+			if (nsp) {
+				mnt_ns = nsp->mnt_ns;
+				if (mnt_ns)
+					get_mnt_ns(mnt_ns);
+			}
+			rcu_read_unlock();
+
 			put_task_struct(task);
 		}
 
@@ -1437,7 +1519,7 @@
 	struct dentry *dentry = filp->f_path.dentry;
 	struct inode *inode = dentry->d_inode;
 	struct task_struct *p = get_proc_task(inode);
-	unsigned int fd, tid, ino;
+	unsigned int fd, ino;
 	int retval;
 	struct files_struct * files;
 	struct fdtable *fdt;
@@ -1446,7 +1528,6 @@
 	if (!p)
 		goto out_no_task;
 	retval = 0;
-	tid = p->pid;
 
 	fd = filp->f_pos;
 	switch (fd) {
@@ -1681,7 +1762,6 @@
 		const struct pid_entry *ents, unsigned int nents)
 {
 	int i;
-	int pid;
 	struct dentry *dentry = filp->f_path.dentry;
 	struct inode *inode = dentry->d_inode;
 	struct task_struct *task = get_proc_task(inode);
@@ -1694,7 +1774,6 @@
 		goto out_no_task;
 
 	ret = 0;
-	pid = task->pid;
 	i = filp->f_pos;
 	switch (i) {
 	case 0:
@@ -1928,14 +2007,14 @@
 			      int buflen)
 {
 	char tmp[PROC_NUMBUF];
-	sprintf(tmp, "%d", current->tgid);
+	sprintf(tmp, "%d", task_tgid_vnr(current));
 	return vfs_readlink(dentry,buffer,buflen,tmp);
 }
 
 static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	char tmp[PROC_NUMBUF];
-	sprintf(tmp, "%d", current->tgid);
+	sprintf(tmp, "%d", task_tgid_vnr(current));
 	return ERR_PTR(vfs_follow_link(nd,tmp));
 }
 
@@ -2101,6 +2180,7 @@
 	REG("environ",    S_IRUSR, environ),
 	INF("auxv",       S_IRUSR, pid_auxv),
 	INF("status",     S_IRUGO, pid_status),
+	INF("limits",	  S_IRUSR, pid_limits),
 #ifdef CONFIG_SCHED_DEBUG
 	REG("sched",      S_IRUGO|S_IWUSR, pid_sched),
 #endif
@@ -2130,9 +2210,12 @@
 #ifdef CONFIG_SCHEDSTATS
 	INF("schedstat",  S_IRUGO, pid_schedstat),
 #endif
-#ifdef CONFIG_CPUSETS
+#ifdef CONFIG_PROC_PID_CPUSET
 	REG("cpuset",     S_IRUGO, cpuset),
 #endif
+#ifdef CONFIG_CGROUPS
+	REG("cgroup",  S_IRUGO, cgroup),
+#endif
 	INF("oom_score",  S_IRUGO, oom_score),
 	REG("oom_adj",    S_IRUGO|S_IWUSR, oom_adjust),
 #ifdef CONFIG_AUDITSYSCALL
@@ -2172,11 +2255,60 @@
 	.setattr	= proc_setattr,
 };
 
+static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
+{
+	struct dentry *dentry, *leader, *dir;
+	char buf[PROC_NUMBUF];
+	struct qstr name;
+
+	name.name = buf;
+	name.len = snprintf(buf, sizeof(buf), "%d", pid);
+	dentry = d_hash_and_lookup(mnt->mnt_root, &name);
+	if (dentry) {
+		shrink_dcache_parent(dentry);
+		d_drop(dentry);
+		dput(dentry);
+	}
+
+	if (tgid == 0)
+		goto out;
+
+	name.name = buf;
+	name.len = snprintf(buf, sizeof(buf), "%d", tgid);
+	leader = d_hash_and_lookup(mnt->mnt_root, &name);
+	if (!leader)
+		goto out;
+
+	name.name = "task";
+	name.len = strlen(name.name);
+	dir = d_hash_and_lookup(leader, &name);
+	if (!dir)
+		goto out_put_leader;
+
+	name.name = buf;
+	name.len = snprintf(buf, sizeof(buf), "%d", pid);
+	dentry = d_hash_and_lookup(dir, &name);
+	if (dentry) {
+		shrink_dcache_parent(dentry);
+		d_drop(dentry);
+		dput(dentry);
+	}
+
+	dput(dir);
+out_put_leader:
+	dput(leader);
+out:
+	return;
+}
+
 /**
  * proc_flush_task -  Remove dcache entries for @task from the /proc dcache.
- *
  * @task: task that should be flushed.
  *
+ * When flushing dentries from proc, one needs to flush them from global
+ * proc (proc_mnt) and from all the namespaces' procs this task was seen
+ * in. This call is supposed to do all of this job.
+ *
  * Looks in the dcache for
  * /proc/@pid
  * /proc/@tgid/task/@pid
@@ -2193,50 +2325,29 @@
  *       that no dcache entries will exist at process exit time it
  *       just makes it very unlikely that any will persist.
  */
+
 void proc_flush_task(struct task_struct *task)
 {
-	struct dentry *dentry, *leader, *dir;
-	char buf[PROC_NUMBUF];
-	struct qstr name;
+	int i, leader;
+	struct pid *pid, *tgid;
+	struct upid *upid;
 
-	name.name = buf;
-	name.len = snprintf(buf, sizeof(buf), "%d", task->pid);
-	dentry = d_hash_and_lookup(proc_mnt->mnt_root, &name);
-	if (dentry) {
-		shrink_dcache_parent(dentry);
-		d_drop(dentry);
-		dput(dentry);
+	leader = thread_group_leader(task);
+	proc_flush_task_mnt(proc_mnt, task->pid, leader ? task->tgid : 0);
+	pid = task_pid(task);
+	if (pid->level == 0)
+		return;
+
+	tgid = task_tgid(task);
+	for (i = 1; i <= pid->level; i++) {
+		upid = &pid->numbers[i];
+		proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr,
+				leader ? 0 : tgid->numbers[i].nr);
 	}
 
-	if (thread_group_leader(task))
-		goto out;
-
-	name.name = buf;
-	name.len = snprintf(buf, sizeof(buf), "%d", task->tgid);
-	leader = d_hash_and_lookup(proc_mnt->mnt_root, &name);
-	if (!leader)
-		goto out;
-
-	name.name = "task";
-	name.len = strlen(name.name);
-	dir = d_hash_and_lookup(leader, &name);
-	if (!dir)
-		goto out_put_leader;
-
-	name.name = buf;
-	name.len = snprintf(buf, sizeof(buf), "%d", task->pid);
-	dentry = d_hash_and_lookup(dir, &name);
-	if (dentry) {
-		shrink_dcache_parent(dentry);
-		d_drop(dentry);
-		dput(dentry);
-	}
-
-	dput(dir);
-out_put_leader:
-	dput(leader);
-out:
-	return;
+	upid = &pid->numbers[pid->level];
+	if (upid->nr == 1)
+		pid_ns_release_proc(upid->ns);
 }
 
 static struct dentry *proc_pid_instantiate(struct inode *dir,
@@ -2274,6 +2385,7 @@
 	struct dentry *result = ERR_PTR(-ENOENT);
 	struct task_struct *task;
 	unsigned tgid;
+	struct pid_namespace *ns;
 
 	result = proc_base_lookup(dir, dentry);
 	if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT)
@@ -2283,8 +2395,9 @@
 	if (tgid == ~0U)
 		goto out;
 
+	ns = dentry->d_sb->s_fs_info;
 	rcu_read_lock();
-	task = find_task_by_pid(tgid);
+	task = find_task_by_pid_ns(tgid, ns);
 	if (task)
 		get_task_struct(task);
 	rcu_read_unlock();
@@ -2301,7 +2414,8 @@
  * Find the first task with tgid >= tgid
  *
  */
-static struct task_struct *next_tgid(unsigned int tgid)
+static struct task_struct *next_tgid(unsigned int tgid,
+		struct pid_namespace *ns)
 {
 	struct task_struct *task;
 	struct pid *pid;
@@ -2309,9 +2423,9 @@
 	rcu_read_lock();
 retry:
 	task = NULL;
-	pid = find_ge_pid(tgid);
+	pid = find_ge_pid(tgid, ns);
 	if (pid) {
-		tgid = pid->nr + 1;
+		tgid = pid_nr_ns(pid, ns) + 1;
 		task = pid_task(pid, PIDTYPE_PID);
 		/* What we to know is if the pid we have find is the
 		 * pid of a thread_group_leader.  Testing for task
@@ -2351,6 +2465,7 @@
 	struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
 	struct task_struct *task;
 	int tgid;
+	struct pid_namespace *ns;
 
 	if (!reaper)
 		goto out_no_task;
@@ -2361,11 +2476,12 @@
 			goto out;
 	}
 
+	ns = filp->f_dentry->d_sb->s_fs_info;
 	tgid = filp->f_pos - TGID_OFFSET;
-	for (task = next_tgid(tgid);
+	for (task = next_tgid(tgid, ns);
 	     task;
-	     put_task_struct(task), task = next_tgid(tgid + 1)) {
-		tgid = task->pid;
+	     put_task_struct(task), task = next_tgid(tgid + 1, ns)) {
+		tgid = task_pid_nr_ns(task, ns);
 		filp->f_pos = tgid + TGID_OFFSET;
 		if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
 			put_task_struct(task);
@@ -2388,6 +2504,7 @@
 	REG("environ",   S_IRUSR, environ),
 	INF("auxv",      S_IRUSR, pid_auxv),
 	INF("status",    S_IRUGO, pid_status),
+	INF("limits",	 S_IRUSR, pid_limits),
 #ifdef CONFIG_SCHED_DEBUG
 	REG("sched",     S_IRUGO|S_IWUSR, pid_sched),
 #endif
@@ -2416,9 +2533,12 @@
 #ifdef CONFIG_SCHEDSTATS
 	INF("schedstat", S_IRUGO, pid_schedstat),
 #endif
-#ifdef CONFIG_CPUSETS
+#ifdef CONFIG_PROC_PID_CPUSET
 	REG("cpuset",    S_IRUGO, cpuset),
 #endif
+#ifdef CONFIG_CGROUPS
+	REG("cgroup",  S_IRUGO, cgroup),
+#endif
 	INF("oom_score", S_IRUGO, oom_score),
 	REG("oom_adj",   S_IRUGO|S_IWUSR, oom_adjust),
 #ifdef CONFIG_AUDITSYSCALL
@@ -2486,6 +2606,7 @@
 	struct task_struct *task;
 	struct task_struct *leader = get_proc_task(dir);
 	unsigned tid;
+	struct pid_namespace *ns;
 
 	if (!leader)
 		goto out_no_task;
@@ -2494,14 +2615,15 @@
 	if (tid == ~0U)
 		goto out;
 
+	ns = dentry->d_sb->s_fs_info;
 	rcu_read_lock();
-	task = find_task_by_pid(tid);
+	task = find_task_by_pid_ns(tid, ns);
 	if (task)
 		get_task_struct(task);
 	rcu_read_unlock();
 	if (!task)
 		goto out;
-	if (leader->tgid != task->tgid)
+	if (!same_thread_group(leader, task))
 		goto out_drop_task;
 
 	result = proc_task_instantiate(dir, dentry, task, NULL);
@@ -2526,14 +2648,14 @@
  * threads past it.
  */
 static struct task_struct *first_tid(struct task_struct *leader,
-					int tid, int nr)
+		int tid, int nr, struct pid_namespace *ns)
 {
 	struct task_struct *pos;
 
 	rcu_read_lock();
 	/* Attempt to start with the pid of a thread */
 	if (tid && (nr > 0)) {
-		pos = find_task_by_pid(tid);
+		pos = find_task_by_pid_ns(tid, ns);
 		if (pos && (pos->group_leader == leader))
 			goto found;
 	}
@@ -2602,6 +2724,7 @@
 	ino_t ino;
 	int tid;
 	unsigned long pos = filp->f_pos;  /* avoiding "long long" filp->f_pos */
+	struct pid_namespace *ns;
 
 	task = get_proc_task(inode);
 	if (!task)
@@ -2635,12 +2758,13 @@
 	/* f_version caches the tgid value that the last readdir call couldn't
 	 * return. lseek aka telldir automagically resets f_version to 0.
 	 */
+	ns = filp->f_dentry->d_sb->s_fs_info;
 	tid = (int)filp->f_version;
 	filp->f_version = 0;
-	for (task = first_tid(leader, tid, pos - 2);
+	for (task = first_tid(leader, tid, pos - 2, ns);
 	     task;
 	     task = next_tid(task), pos++) {
-		tid = task->pid;
+		tid = task_pid_nr_ns(task, ns);
 		if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
 			/* returning this tgid failed, save it as the first
 			 * pid for the next readir call */
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 99ca004..abe6a3f 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -448,7 +448,7 @@
 	return NULL;
 }			
 
-int proc_fill_super(struct super_block *s, void *data, int silent)
+int proc_fill_super(struct super_block *s)
 {
 	struct inode * root_inode;
 
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index d6dc72c..e0d064e 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -91,7 +91,8 @@
 		LOAD_INT(a), LOAD_FRAC(a),
 		LOAD_INT(b), LOAD_FRAC(b),
 		LOAD_INT(c), LOAD_FRAC(c),
-		nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid);
+		nr_running(), nr_threads,
+		task_active_pid_ns(current)->last_pid);
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
diff --git a/fs/proc/root.c b/fs/proc/root.c
index cf30466..ec9cb3b 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -18,32 +18,90 @@
 #include <linux/bitops.h>
 #include <linux/smp_lock.h>
 #include <linux/mount.h>
+#include <linux/pid_namespace.h>
 
 #include "internal.h"
 
 struct proc_dir_entry *proc_bus, *proc_root_fs, *proc_root_driver;
 
+static int proc_test_super(struct super_block *sb, void *data)
+{
+	return sb->s_fs_info == data;
+}
+
+static int proc_set_super(struct super_block *sb, void *data)
+{
+	struct pid_namespace *ns;
+
+	ns = (struct pid_namespace *)data;
+	sb->s_fs_info = get_pid_ns(ns);
+	return set_anon_super(sb, NULL);
+}
+
 static int proc_get_sb(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
+	int err;
+	struct super_block *sb;
+	struct pid_namespace *ns;
+	struct proc_inode *ei;
+
 	if (proc_mnt) {
 		/* Seed the root directory with a pid so it doesn't need
 		 * to be special in base.c.  I would do this earlier but
 		 * the only task alive when /proc is mounted the first time
 		 * is the init_task and it doesn't have any pids.
 		 */
-		struct proc_inode *ei;
 		ei = PROC_I(proc_mnt->mnt_sb->s_root->d_inode);
 		if (!ei->pid)
 			ei->pid = find_get_pid(1);
 	}
-	return get_sb_single(fs_type, flags, data, proc_fill_super, mnt);
+
+	if (flags & MS_KERNMOUNT)
+		ns = (struct pid_namespace *)data;
+	else
+		ns = current->nsproxy->pid_ns;
+
+	sb = sget(fs_type, proc_test_super, proc_set_super, ns);
+	if (IS_ERR(sb))
+		return PTR_ERR(sb);
+
+	if (!sb->s_root) {
+		sb->s_flags = flags;
+		err = proc_fill_super(sb);
+		if (err) {
+			up_write(&sb->s_umount);
+			deactivate_super(sb);
+			return err;
+		}
+
+		ei = PROC_I(sb->s_root->d_inode);
+		if (!ei->pid) {
+			rcu_read_lock();
+			ei->pid = get_pid(find_pid_ns(1, ns));
+			rcu_read_unlock();
+		}
+
+		sb->s_flags |= MS_ACTIVE;
+		ns->proc_mnt = mnt;
+	}
+
+	return simple_set_mnt(mnt, sb);
+}
+
+static void proc_kill_sb(struct super_block *sb)
+{
+	struct pid_namespace *ns;
+
+	ns = (struct pid_namespace *)sb->s_fs_info;
+	kill_anon_super(sb);
+	put_pid_ns(ns);
 }
 
 static struct file_system_type proc_fs_type = {
 	.name		= "proc",
 	.get_sb		= proc_get_sb,
-	.kill_sb	= kill_anon_super,
+	.kill_sb	= proc_kill_sb,
 };
 
 void __init proc_root_init(void)
@@ -54,12 +112,13 @@
 	err = register_filesystem(&proc_fs_type);
 	if (err)
 		return;
-	proc_mnt = kern_mount(&proc_fs_type);
+	proc_mnt = kern_mount_data(&proc_fs_type, &init_pid_ns);
 	err = PTR_ERR(proc_mnt);
 	if (IS_ERR(proc_mnt)) {
 		unregister_filesystem(&proc_fs_type);
 		return;
 	}
+
 	proc_misc_init();
 
 	proc_net_init();
@@ -153,6 +212,22 @@
 	.parent		= &proc_root,
 };
 
+int pid_ns_prepare_proc(struct pid_namespace *ns)
+{
+	struct vfsmount *mnt;
+
+	mnt = kern_mount_data(&proc_fs_type, ns);
+	if (IS_ERR(mnt))
+		return PTR_ERR(mnt);
+
+	return 0;
+}
+
+void pid_ns_release_proc(struct pid_namespace *ns)
+{
+	mntput(ns->proc_mnt);
+}
+
 EXPORT_SYMBOL(proc_symlink);
 EXPORT_SYMBOL(proc_mkdir);
 EXPORT_SYMBOL(create_proc_entry);
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
index 2a5dd34..16b331d 100644
--- a/fs/reiserfs/bitmap.c
+++ b/fs/reiserfs/bitmap.c
@@ -47,7 +47,9 @@
     test_bit(_ALLOC_ ## optname , &SB_ALLOC_OPTS(s))
 
 static inline void get_bit_address(struct super_block *s,
-				   b_blocknr_t block, int *bmap_nr, int *offset)
+				   b_blocknr_t block,
+				   unsigned int *bmap_nr,
+				   unsigned int *offset)
 {
 	/* It is in the bitmap block number equal to the block
 	 * number divided by the number of bits in a block. */
@@ -56,10 +58,10 @@
 	*offset = block & ((s->s_blocksize << 3) - 1);
 }
 
-#ifdef CONFIG_REISERFS_CHECK
 int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
 {
-	int bmap, offset;
+	unsigned int bmap, offset;
+	unsigned int bmap_count = reiserfs_bmap_count(s);
 
 	if (block == 0 || block >= SB_BLOCK_COUNT(s)) {
 		reiserfs_warning(s,
@@ -75,25 +77,26 @@
 	if (unlikely(test_bit(REISERFS_OLD_FORMAT,
 			      &(REISERFS_SB(s)->s_properties)))) {
 		b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1;
-		if (block >= bmap1 && block <= bmap1 + SB_BMAP_NR(s)) {
+		if (block >= bmap1 &&
+		    block <= bmap1 + bmap_count) {
 			reiserfs_warning(s, "vs: 4019: is_reusable: "
 					 "bitmap block %lu(%u) can't be freed or reused",
-					 block, SB_BMAP_NR(s));
+					 block, bmap_count);
 			return 0;
 		}
 	} else {
 		if (offset == 0) {
 			reiserfs_warning(s, "vs: 4020: is_reusable: "
 					 "bitmap block %lu(%u) can't be freed or reused",
-					 block, SB_BMAP_NR(s));
+					 block, bmap_count);
 			return 0;
 		}
 	}
 
-	if (bmap >= SB_BMAP_NR(s)) {
+	if (bmap >= bmap_count) {
 		reiserfs_warning(s,
 				 "vs-4030: is_reusable: there is no so many bitmap blocks: "
-				 "block=%lu, bitmap_nr=%d", block, bmap);
+				 "block=%lu, bitmap_nr=%u", block, bmap);
 		return 0;
 	}
 
@@ -106,12 +109,11 @@
 
 	return 1;
 }
-#endif				/* CONFIG_REISERFS_CHECK */
 
 /* searches in journal structures for a given block number (bmap, off). If block
    is found in reiserfs journal it suggests next free block candidate to test. */
-static inline int is_block_in_journal(struct super_block *s, int bmap, int
-				      off, int *next)
+static inline int is_block_in_journal(struct super_block *s, unsigned int bmap,
+				      int off, int *next)
 {
 	b_blocknr_t tmp;
 
@@ -132,8 +134,8 @@
 /* it searches for a window of zero bits with given minimum and maximum lengths in one bitmap
  * block; */
 static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
-			     int bmap_n, int *beg, int boundary, int min,
-			     int max, int unfm)
+			     unsigned int bmap_n, int *beg, int boundary,
+			     int min, int max, int unfm)
 {
 	struct super_block *s = th->t_super;
 	struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n];
@@ -143,8 +145,8 @@
 
 	BUG_ON(!th->t_trans_id);
 
-	RFALSE(bmap_n >= SB_BMAP_NR(s), "Bitmap %d is out of range (0..%d)",
-	       bmap_n, SB_BMAP_NR(s) - 1);
+	RFALSE(bmap_n >= reiserfs_bmap_count(s), "Bitmap %u is out of "
+	       "range (0..%u)", bmap_n, reiserfs_bmap_count(s) - 1);
 	PROC_INFO_INC(s, scan_bitmap.bmap);
 /* this is unclear and lacks comments, explain how journal bitmaps
    work here for the reader.  Convey a sense of the design here. What
@@ -249,12 +251,12 @@
 	} else {
 		hash_in = (char *)(&id);
 		hash = keyed_hash(hash_in, 4);
-		bm = hash % SB_BMAP_NR(s);
+		bm = hash % reiserfs_bmap_count(s);
 		if (!bm)
 			bm = 1;
 	}
 	/* this can only be true when SB_BMAP_NR = 1 */
-	if (bm >= SB_BMAP_NR(s))
+	if (bm >= reiserfs_bmap_count(s))
 		bm = 0;
 	return bm;
 }
@@ -273,7 +275,7 @@
 	 * to make a better decision. This favors long-term performace gain
 	 * with a better on-disk layout vs. a short term gain of skipping the
 	 * read and potentially having a bad placement. */
-	if (info->first_zero_hint == 0) {
+	if (info->free_count == UINT_MAX) {
 		struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm);
 		brelse(bh);
 	}
@@ -309,16 +311,16 @@
  * bitmap and place new blocks there. Returns number of allocated blocks. */
 static int scan_bitmap(struct reiserfs_transaction_handle *th,
 		       b_blocknr_t * start, b_blocknr_t finish,
-		       int min, int max, int unfm, unsigned long file_block)
+		       int min, int max, int unfm, sector_t file_block)
 {
 	int nr_allocated = 0;
 	struct super_block *s = th->t_super;
 	/* find every bm and bmap and bmap_nr in this file, and change them all to bitmap_blocknr
 	 * - Hans, it is not a block number - Zam. */
 
-	int bm, off;
-	int end_bm, end_off;
-	int off_max = s->s_blocksize << 3;
+	unsigned int bm, off;
+	unsigned int end_bm, end_off;
+	unsigned int off_max = s->s_blocksize << 3;
 
 	BUG_ON(!th->t_trans_id);
 
@@ -328,10 +330,10 @@
 
 	get_bit_address(s, *start, &bm, &off);
 	get_bit_address(s, finish, &end_bm, &end_off);
-	if (bm > SB_BMAP_NR(s))
+	if (bm > reiserfs_bmap_count(s))
 		return 0;
-	if (end_bm > SB_BMAP_NR(s))
-		end_bm = SB_BMAP_NR(s);
+	if (end_bm > reiserfs_bmap_count(s))
+		end_bm = reiserfs_bmap_count(s);
 
 	/* When the bitmap is more than 10% free, anyone can allocate.
 	 * When it's less than 10% free, only files that already use the
@@ -385,7 +387,7 @@
 	struct reiserfs_super_block *rs;
 	struct buffer_head *sbh, *bmbh;
 	struct reiserfs_bitmap_info *apbi;
-	int nr, offset;
+	unsigned int nr, offset;
 
 	BUG_ON(!th->t_trans_id);
 
@@ -397,10 +399,12 @@
 
 	get_bit_address(s, block, &nr, &offset);
 
-	if (nr >= sb_bmap_nr(rs)) {
+	if (nr >= reiserfs_bmap_count(s)) {
 		reiserfs_warning(s, "vs-4075: reiserfs_free_block: "
-				 "block %lu is out of range on %s",
-				 block, reiserfs_bdevname(s));
+				 "block %lu is out of range on %s "
+				 "(nr=%u,max=%u)", block,
+				 reiserfs_bdevname(s), nr,
+				 reiserfs_bmap_count(s));
 		return;
 	}
 
@@ -434,12 +438,19 @@
 			 int for_unformatted)
 {
 	struct super_block *s = th->t_super;
-
 	BUG_ON(!th->t_trans_id);
 
 	RFALSE(!s, "vs-4061: trying to free block on nonexistent device");
-	RFALSE(is_reusable(s, block, 1) == 0,
-	       "vs-4071: can not free such block");
+	if (!is_reusable(s, block, 1))
+		return;
+
+	if (block > sb_block_count(REISERFS_SB(s)->s_rs)) {
+		reiserfs_panic(th->t_super, "bitmap-4072",
+			       "Trying to free block outside file system "
+			       "boundaries (%lu > %lu)",
+			       block, sb_block_count(REISERFS_SB(s)->s_rs));
+		return;
+	}
 	/* mark it before we clear it, just in case */
 	journal_mark_freed(th, s, block);
 	_reiserfs_free_block(th, inode, block, for_unformatted);
@@ -449,11 +460,11 @@
 static void reiserfs_free_prealloc_block(struct reiserfs_transaction_handle *th,
 					 struct inode *inode, b_blocknr_t block)
 {
+	BUG_ON(!th->t_trans_id);
 	RFALSE(!th->t_super,
 	       "vs-4060: trying to free block on nonexistent device");
-	RFALSE(is_reusable(th->t_super, block, 1) == 0,
-	       "vs-4070: can not free such block");
-	BUG_ON(!th->t_trans_id);
+	if (!is_reusable(th->t_super, block, 1))
+		return;
 	_reiserfs_free_block(th, inode, block, 1);
 }
 
@@ -1207,27 +1218,22 @@
 {
 	unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size);
 
-	info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3);
+	/* The first bit must ALWAYS be 1 */
+	BUG_ON(!reiserfs_test_le_bit(0, (unsigned long *)bh->b_data));
+
+	info->free_count = 0;
 
 	while (--cur >= (unsigned long *)bh->b_data) {
-		int base = ((char *)cur - bh->b_data) << 3;
+		int i;
 
 		/* 0 and ~0 are special, we can optimize for them */
-		if (*cur == 0) {
-			info->first_zero_hint = base;
+		if (*cur == 0)
 			info->free_count += BITS_PER_LONG;
-		} else if (*cur != ~0L) {       /* A mix, investigate */
-			int b;
-			for (b = BITS_PER_LONG - 1; b >= 0; b--) {
-				if (!reiserfs_test_le_bit(b, cur)) {
-					info->first_zero_hint = base + b;
+		else if (*cur != ~0L)	/* A mix, investigate */
+			for (i = BITS_PER_LONG - 1; i >= 0; i--)
+				if (!reiserfs_test_le_bit(i, cur))
 					info->free_count++;
-				}
-			}
-		}
 	}
-	/* The first bit must ALWAYS be 1 */
-	BUG_ON(info->first_zero_hint == 0);
 }
 
 struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
@@ -1257,7 +1263,7 @@
 		BUG_ON(!buffer_uptodate(bh));
 		BUG_ON(atomic_read(&bh->b_count) == 0);
 
-		if (info->first_zero_hint == 0)
+		if (info->free_count == UINT_MAX)
 			reiserfs_cache_bitmap_metadata(sb, bh, info);
 	}
 
@@ -1267,12 +1273,13 @@
 int reiserfs_init_bitmap_cache(struct super_block *sb)
 {
 	struct reiserfs_bitmap_info *bitmap;
+	unsigned int bmap_nr = reiserfs_bmap_count(sb);
 
-	bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb));
+	bitmap = vmalloc(sizeof(*bitmap) * bmap_nr);
 	if (bitmap == NULL)
 		return -ENOMEM;
 
-	memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb));
+	memset(bitmap, 0xff, sizeof(*bitmap) * bmap_nr);
 
 	SB_AP_BITMAP(sb) = bitmap;
 
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 9ea1200..231fd5c 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -199,7 +199,7 @@
 // files which were created in the earlier version can not be longer,
 // than 2 gb
 //
-static int file_capable(struct inode *inode, long block)
+static int file_capable(struct inode *inode, sector_t block)
 {
 	if (get_inode_item_key_version(inode) != KEY_FORMAT_3_5 ||	// it is new file.
 	    block < (1 << (31 - inode->i_sb->s_blocksize_bits)))	// old file, but 'block' is inside of 2gb
@@ -242,7 +242,7 @@
 // Please improve the english/clarity in the comment above, as it is
 // hard to understand.
 
-static int _get_block_create_0(struct inode *inode, long block,
+static int _get_block_create_0(struct inode *inode, sector_t block,
 			       struct buffer_head *bh_result, int args)
 {
 	INITIALIZE_PATH(path);
@@ -250,7 +250,7 @@
 	struct buffer_head *bh;
 	struct item_head *ih, tmp_ih;
 	int fs_gen;
-	int blocknr;
+	b_blocknr_t blocknr;
 	char *p = NULL;
 	int chars;
 	int ret;
@@ -569,7 +569,7 @@
 }
 
 static inline int _allocate_block(struct reiserfs_transaction_handle *th,
-				  long block,
+				  sector_t block,
 				  struct inode *inode,
 				  b_blocknr_t * allocated_block_nr,
 				  struct treepath *path, int flags)
@@ -1515,19 +1515,20 @@
 	return inode;
 }
 
-struct dentry *reiserfs_get_dentry(struct super_block *sb, void *vobjp)
+static struct dentry *reiserfs_get_dentry(struct super_block *sb,
+	u32 objectid, u32 dir_id, u32 generation)
+
 {
-	__u32 *data = vobjp;
 	struct cpu_key key;
 	struct dentry *result;
 	struct inode *inode;
 
-	key.on_disk_key.k_objectid = data[0];
-	key.on_disk_key.k_dir_id = data[1];
+	key.on_disk_key.k_objectid = objectid;
+	key.on_disk_key.k_dir_id = dir_id;
 	reiserfs_write_lock(sb);
 	inode = reiserfs_iget(sb, &key);
-	if (inode && !IS_ERR(inode) && data[2] != 0 &&
-	    data[2] != inode->i_generation) {
+	if (inode && !IS_ERR(inode) && generation != 0 &&
+	    generation != inode->i_generation) {
 		iput(inode);
 		inode = NULL;
 	}
@@ -1544,14 +1545,9 @@
 	return result;
 }
 
-struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 * data,
-				  int len, int fhtype,
-				  int (*acceptable) (void *contect,
-						     struct dentry * de),
-				  void *context)
+struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
 {
-	__u32 obj[3], parent[3];
-
 	/* fhtype happens to reflect the number of u32s encoded.
 	 * due to a bug in earlier code, fhtype might indicate there
 	 * are more u32s then actually fitted.
@@ -1564,32 +1560,28 @@
 	 *   6 - as above plus generation of directory
 	 * 6 does not fit in NFSv2 handles
 	 */
-	if (fhtype > len) {
-		if (fhtype != 6 || len != 5)
+	if (fh_type > fh_len) {
+		if (fh_type != 6 || fh_len != 5)
 			reiserfs_warning(sb,
-					 "nfsd/reiserfs, fhtype=%d, len=%d - odd",
-					 fhtype, len);
-		fhtype = 5;
+				"nfsd/reiserfs, fhtype=%d, len=%d - odd",
+				fh_type, fh_len);
+		fh_type = 5;
 	}
 
-	obj[0] = data[0];
-	obj[1] = data[1];
-	if (fhtype == 3 || fhtype >= 5)
-		obj[2] = data[2];
-	else
-		obj[2] = 0;	/* generation number */
+	return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1],
+		(fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0);
+}
 
-	if (fhtype >= 4) {
-		parent[0] = data[fhtype >= 5 ? 3 : 2];
-		parent[1] = data[fhtype >= 5 ? 4 : 3];
-		if (fhtype == 6)
-			parent[2] = data[5];
-		else
-			parent[2] = 0;
-	}
-	return sb->s_export_op->find_exported_dentry(sb, obj,
-						     fhtype < 4 ? NULL : parent,
-						     acceptable, context);
+struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type)
+{
+	if (fh_type < 4)
+		return NULL;
+
+	return reiserfs_get_dentry(sb,
+		(fh_type >= 5) ? fid->raw[3] : fid->raw[2],
+		(fh_type >= 5) ? fid->raw[4] : fid->raw[3],
+		(fh_type == 6) ? fid->raw[5] : 0);
 }
 
 int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
@@ -3061,7 +3053,11 @@
 {
 	struct inode *inode = dentry->d_inode;
 	int error;
-	unsigned int ia_valid = attr->ia_valid;
+	unsigned int ia_valid;
+
+	/* must be turned off for recursive notify_change calls */
+	ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
+
 	reiserfs_write_lock(inode->i_sb);
 	if (attr->ia_valid & ATTR_SIZE) {
 		/* version 2 items will be caught by the s_maxbytes check
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 4cad9e7..bb05a3e 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -219,11 +219,12 @@
 	}
 }
 
-static int set_bit_in_list_bitmap(struct super_block *p_s_sb, int block,
+static int set_bit_in_list_bitmap(struct super_block *p_s_sb,
+				  b_blocknr_t block,
 				  struct reiserfs_list_bitmap *jb)
 {
-	int bmap_nr = block / (p_s_sb->s_blocksize << 3);
-	int bit_nr = block % (p_s_sb->s_blocksize << 3);
+	unsigned int bmap_nr = block / (p_s_sb->s_blocksize << 3);
+	unsigned int bit_nr = block % (p_s_sb->s_blocksize << 3);
 
 	if (!jb->bitmaps[bmap_nr]) {
 		jb->bitmaps[bmap_nr] = get_bitmap_node(p_s_sb);
@@ -239,7 +240,7 @@
 	if (jb->bitmaps == NULL)
 		return;
 
-	for (i = 0; i < SB_BMAP_NR(p_s_sb); i++) {
+	for (i = 0; i < reiserfs_bmap_count(p_s_sb); i++) {
 		if (jb->bitmaps[i]) {
 			free_bitmap_node(p_s_sb, jb->bitmaps[i]);
 			jb->bitmaps[i] = NULL;
@@ -289,7 +290,7 @@
 */
 int reiserfs_allocate_list_bitmaps(struct super_block *p_s_sb,
 				   struct reiserfs_list_bitmap *jb_array,
-				   int bmap_nr)
+				   unsigned int bmap_nr)
 {
 	int i;
 	int failed = 0;
@@ -483,7 +484,7 @@
 **
 */
 int reiserfs_in_journal(struct super_block *p_s_sb,
-			int bmap_nr, int bit_nr, int search_all,
+			unsigned int bmap_nr, int bit_nr, int search_all,
 			b_blocknr_t * next_zero_bit)
 {
 	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
@@ -1013,7 +1014,7 @@
 			     struct reiserfs_journal_list *jl, int flushall)
 {
 	int i;
-	int bn;
+	b_blocknr_t bn;
 	struct buffer_head *tbh = NULL;
 	unsigned long trans_id = jl->j_trans_id;
 	struct reiserfs_journal *journal = SB_JOURNAL(s);
@@ -2307,8 +2308,9 @@
    Right now it is only used from journal code. But later we might use it
    from other places.
    Note: Do not use journal_getblk/sb_getblk functions here! */
-static struct buffer_head *reiserfs_breada(struct block_device *dev, int block,
-					   int bufsize, unsigned int max_block)
+static struct buffer_head *reiserfs_breada(struct block_device *dev,
+					   b_blocknr_t block, int bufsize,
+					   b_blocknr_t max_block)
 {
 	struct buffer_head *bhlist[BUFNR];
 	unsigned int blocks = BUFNR;
@@ -2732,7 +2734,7 @@
 	journal->j_persistent_trans = 0;
 	if (reiserfs_allocate_list_bitmaps(p_s_sb,
 					   journal->j_list_bitmap,
-					   SB_BMAP_NR(p_s_sb)))
+					   reiserfs_bmap_count(p_s_sb)))
 		goto free_and_return;
 	allocate_bitmap_nodes(p_s_sb);
 
@@ -2740,7 +2742,7 @@
 	SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ?
 						 REISERFS_OLD_DISK_OFFSET_IN_BYTES
 						 / p_s_sb->s_blocksize +
-						 SB_BMAP_NR(p_s_sb) +
+						 reiserfs_bmap_count(p_s_sb) +
 						 1 :
 						 REISERFS_DISK_OFFSET_IN_BYTES /
 						 p_s_sb->s_blocksize + 2);
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
index bc808a9..5e7388b 100644
--- a/fs/reiserfs/prints.c
+++ b/fs/reiserfs/prints.c
@@ -356,13 +356,11 @@
 void reiserfs_panic(struct super_block *sb, const char *fmt, ...)
 {
 	do_reiserfs_warning(fmt);
-	printk(KERN_EMERG "REISERFS: panic (device %s): %s\n",
-	       reiserfs_bdevname(sb), error_buf);
-	BUG();
 
-	/* this is not actually called, but makes reiserfs_panic() "noreturn" */
-	panic("REISERFS: panic (device %s): %s\n",
-	      reiserfs_bdevname(sb), error_buf);
+	dump_stack();
+
+	panic(KERN_EMERG "REISERFS: panic (device %s): %s\n",
+	       reiserfs_bdevname(sb), error_buf);
 }
 
 void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...)
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
index 976cc78..f71c394 100644
--- a/fs/reiserfs/resize.c
+++ b/fs/reiserfs/resize.c
@@ -61,7 +61,8 @@
 	}
 
 	/* count used bits in last bitmap block */
-	block_r = SB_BLOCK_COUNT(s) - (SB_BMAP_NR(s) - 1) * s->s_blocksize * 8;
+	block_r = SB_BLOCK_COUNT(s) -
+			(reiserfs_bmap_count(s) - 1) * s->s_blocksize * 8;
 
 	/* count bitmap blocks in new fs */
 	bmap_nr_new = block_count_new / (s->s_blocksize * 8);
@@ -73,7 +74,7 @@
 
 	/* save old values */
 	block_count = SB_BLOCK_COUNT(s);
-	bmap_nr = SB_BMAP_NR(s);
+	bmap_nr = reiserfs_bmap_count(s);
 
 	/* resizing of reiserfs bitmaps (journal and real), if needed */
 	if (bmap_nr_new > bmap_nr) {
@@ -119,7 +120,7 @@
 			return -ENOMEM;
 		}
 		memset(bitmap, 0,
-		       sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
+		       sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
 		for (i = 0; i < bmap_nr; i++)
 			bitmap[i] = old_bitmap[i];
 
@@ -143,7 +144,6 @@
 			mark_buffer_dirty(bh);
 			sync_dirty_buffer(bh);
 			// update bitmap_info stuff
-			bitmap[i].first_zero_hint = 1;
 			bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
 			brelse(bh);
 		}
@@ -173,8 +173,6 @@
 	for (i = block_r; i < s->s_blocksize * 8; i++)
 		reiserfs_test_and_clear_le_bit(i, bh->b_data);
 	info->free_count += s->s_blocksize * 8 - block_r;
-	if (!info->first_zero_hint)
-		info->first_zero_hint = block_r;
 
 	journal_mark_dirty(&th, s, bh);
 	brelse(bh);
@@ -196,9 +194,6 @@
 	brelse(bh);
 
 	info->free_count -= s->s_blocksize * 8 - block_r_new;
-	/* Extreme case where last bitmap is the only valid block in itself. */
-	if (!info->free_count)
-		info->first_zero_hint = 0;
 	/* update super */
 	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
 	free_blocks = SB_FREE_BLOCKS(s);
@@ -206,7 +201,7 @@
 			   free_blocks + (block_count_new - block_count -
 					  (bmap_nr_new - bmap_nr)));
 	PUT_SB_BLOCK_COUNT(s, block_count_new);
-	PUT_SB_BMAP_NR(s, bmap_nr_new);
+	PUT_SB_BMAP_NR(s, bmap_would_wrap(bmap_nr_new) ? : bmap_nr_new);
 	s->s_dirt = 1;
 
 	journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index 981027d..ca41567 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -559,7 +559,7 @@
 /* The function is NOT SCHEDULE-SAFE! */
 static void search_by_key_reada(struct super_block *s,
 				struct buffer_head **bh,
-				unsigned long *b, int num)
+				b_blocknr_t *b, int num)
 {
 	int i, j;
 
@@ -611,7 +611,7 @@
 					   DISK_LEAF_NODE_LEVEL */
     )
 {
-	int n_block_number;
+	b_blocknr_t n_block_number;
 	int expected_level;
 	struct buffer_head *p_s_bh;
 	struct path_element *p_s_last_element;
@@ -619,7 +619,7 @@
 	int right_neighbor_of_leaf_node;
 	int fs_gen;
 	struct buffer_head *reada_bh[SEARCH_BY_KEY_READA];
-	unsigned long reada_blocks[SEARCH_BY_KEY_READA];
+	b_blocknr_t reada_blocks[SEARCH_BY_KEY_READA];
 	int reada_count = 0;
 
 #ifdef CONFIG_REISERFS_CHECK
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index b82897a..5cd85fe 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -319,7 +319,7 @@
 
 /* to protect file being unlinked from getting lost we "safe" link files
    being unlinked. This link will be deleted in the same transaction with last
-   item of file. mounting the filesytem we scan all these links and remove
+   item of file. mounting the filesystem we scan all these links and remove
    files which almost got lost */
 void add_save_link(struct reiserfs_transaction_handle *th,
 		   struct inode *inode, int truncate)
@@ -661,11 +661,11 @@
 };
 #endif
 
-static struct export_operations reiserfs_export_ops = {
+static const struct export_operations reiserfs_export_ops = {
 	.encode_fh = reiserfs_encode_fh,
-	.decode_fh = reiserfs_decode_fh,
+	.fh_to_dentry = reiserfs_fh_to_dentry,
+	.fh_to_parent = reiserfs_fh_to_parent,
 	.get_parent = reiserfs_get_parent,
-	.get_dentry = reiserfs_get_dentry,
 };
 
 /* this struct is used in reiserfs_getopt () for containing the value for those
@@ -1725,6 +1725,21 @@
 		set_sb_umount_state(rs, REISERFS_ERROR_FS);
 		set_sb_fs_state(rs, 0);
 
+		/* Clear out s_bmap_nr if it would wrap. We can handle this
+		 * case, but older revisions can't. This will cause the
+		 * file system to fail mount on those older implementations,
+		 * avoiding corruption. -jeffm */
+		if (bmap_would_wrap(reiserfs_bmap_count(s)) &&
+		    sb_bmap_nr(rs) != 0) {
+			reiserfs_warning(s, "super-2030: This file system "
+					"claims to use %u bitmap blocks in "
+					"its super block, but requires %u. "
+					"Clearing to zero.", sb_bmap_nr(rs),
+					reiserfs_bmap_count(s));
+
+			set_sb_bmap_nr(rs, 0);
+		}
+
 		if (old_format_only(s)) {
 			/* filesystem of format 3.5 either with standard or non-standard
 			   journal */
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index fab4b9b..1597f6b 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -484,7 +484,7 @@
 	/* Resize it so we're ok to write there */
 	newattrs.ia_size = buffer_size;
 	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
-	mutex_lock(&xinode->i_mutex);
+	mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR);
 	err = notify_change(fp->f_path.dentry, &newattrs);
 	if (err)
 		goto out_filp;
@@ -1223,7 +1223,8 @@
 		if (!IS_ERR(dentry)) {
 			if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) {
 				struct inode *inode = dentry->d_parent->d_inode;
-				mutex_lock(&inode->i_mutex);
+				mutex_lock_nested(&inode->i_mutex,
+						  I_MUTEX_XATTR);
 				err = inode->i_op->mkdir(inode, dentry, 0700);
 				mutex_unlock(&inode->i_mutex);
 				if (err) {
diff --git a/fs/select.c b/fs/select.c
index 7dede89..47f4792 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -177,11 +177,6 @@
 	return max;
 }
 
-#define BIT(i)		(1UL << ((i)&(__NFDBITS-1)))
-#define MEM(i,m)	((m)+(unsigned)(i)/__NFDBITS)
-#define ISSET(i,m)	(((i)&*(m)) != 0)
-#define SET(i,m)	(*(m) |= (i))
-
 #define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR)
 #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
 #define POLLEX_SET (POLLPRI)
diff --git a/fs/super.c b/fs/super.c
index 1bfcca2..ceaf2e3 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -15,7 +15,7 @@
  *  Added kerneld support: Jacques Gelinas and Bjorn Ekwall
  *  Added change_root: Werner Almesberger & Hans Lermen, Feb '96
  *  Added options to /proc/mounts:
- *    Torbjörn Lindh (torbjorn.lindh@gopta.se), April 14, 1996.
+ *    Torbjörn Lindh (torbjorn.lindh@gopta.se), April 14, 1996.
  *  Added devfs support: Richard Gooch <rgooch@atnf.csiro.au>, 13-JAN-1998
  *  Heavily rewritten for 'one fs - one tree' dcache architecture. AV, Mar 2000
  */
@@ -40,10 +40,6 @@
 #include <asm/uaccess.h>
 
 
-void get_filesystem(struct file_system_type *fs);
-void put_filesystem(struct file_system_type *fs);
-struct file_system_type *get_fs_type(const char *name);
-
 LIST_HEAD(super_blocks);
 DEFINE_SPINLOCK(sb_lock);
 
@@ -336,21 +332,21 @@
 			void *data)
 {
 	struct super_block *s = NULL;
-	struct list_head *p;
+	struct super_block *old;
 	int err;
 
 retry:
 	spin_lock(&sb_lock);
-	if (test) list_for_each(p, &type->fs_supers) {
-		struct super_block *old;
-		old = list_entry(p, struct super_block, s_instances);
-		if (!test(old, data))
-			continue;
-		if (!grab_super(old))
-			goto retry;
-		if (s)
-			destroy_super(s);
-		return old;
+	if (test) {
+		list_for_each_entry(old, &type->fs_supers, s_instances) {
+			if (!test(old, data))
+				continue;
+			if (!grab_super(old))
+				goto retry;
+			if (s)
+				destroy_super(s);
+			return old;
+		}
 	}
 	if (!s) {
 		spin_unlock(&sb_lock);
@@ -421,7 +417,7 @@
 }
 
 /*
- * Call the ->sync_fs super_op against all filesytems which are r/w and
+ * Call the ->sync_fs super_op against all filesystems which are r/w and
  * which implement it.
  *
  * This operation is careful to avoid the livelock which could easily happen
@@ -429,7 +425,7 @@
  * is used only here.  We set it against all filesystems and then clear it as
  * we sync them.  So redirtied filesystems are skipped.
  *
- * But if process A is currently running sync_filesytems and then process B
+ * But if process A is currently running sync_filesystems and then process B
  * calls sync_filesystems as well, process B will set all the s_need_sync_fs
  * flags again, which will cause process A to resync everything.  Fix that with
  * a local mutex.
@@ -948,9 +944,9 @@
 	return mnt;
 }
 
-struct vfsmount *kern_mount(struct file_system_type *type)
+struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
 {
-	return vfs_kern_mount(type, 0, type->name, NULL);
+	return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
 }
 
-EXPORT_SYMBOL(kern_mount);
+EXPORT_SYMBOL_GPL(kern_mount_data);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index d3be1e7..27d1785 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -540,7 +540,7 @@
 /**
  *	sysfs_create_file - create an attribute file for an object.
  *	@kobj:	object we're creating for. 
- *	@attr:	atrribute descriptor.
+ *	@attr:	attribute descriptor.
  */
 
 int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
diff --git a/fs/xattr.c b/fs/xattr.c
index a44fd92..6645b73 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -267,7 +267,7 @@
 	if (!f)
 		return error;
 	dentry = f->f_path.dentry;
-	audit_inode(NULL, dentry->d_inode);
+	audit_inode(NULL, dentry);
 	error = setxattr(dentry, name, value, size, flags);
 	fput(f);
 	return error;
@@ -349,7 +349,7 @@
 	f = fget(fd);
 	if (!f)
 		return error;
-	audit_inode(NULL, f->f_path.dentry->d_inode);
+	audit_inode(NULL, f->f_path.dentry);
 	error = getxattr(f->f_path.dentry, name, value, size);
 	fput(f);
 	return error;
@@ -422,7 +422,7 @@
 	f = fget(fd);
 	if (!f)
 		return error;
-	audit_inode(NULL, f->f_path.dentry->d_inode);
+	audit_inode(NULL, f->f_path.dentry);
 	error = listxattr(f->f_path.dentry, list, size);
 	fput(f);
 	return error;
@@ -485,7 +485,7 @@
 	if (!f)
 		return error;
 	dentry = f->f_path.dentry;
-	audit_inode(NULL, dentry->d_inode);
+	audit_inode(NULL, dentry);
 	error = removexattr(dentry, name);
 	fput(f);
 	return error;
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index 726449d..15bd494 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -33,62 +33,25 @@
 static struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, };
 
 /*
- * XFS encodes and decodes the fileid portion of NFS filehandles
- * itself instead of letting the generic NFS code do it.  This
- * allows filesystems with 64 bit inode numbers to be exported.
- *
- * Note that a side effect is that xfs_vget() won't be passed a
- * zero inode/generation pair under normal circumstances.  As
- * however a malicious client could send us such data, the check
- * remains in that code.
+ * Note that we only accept fileids which are long enough rather than allow
+ * the parent generation number to default to zero.  XFS considers zero a
+ * valid generation number not an invalid/wildcard value.
  */
-
-STATIC struct dentry *
-xfs_fs_decode_fh(
-	struct super_block	*sb,
-	__u32			*fh,
-	int			fh_len,
-	int			fileid_type,
-	int (*acceptable)(
-		void		*context,
-		struct dentry	*de),
-	void			*context)
+static int xfs_fileid_length(int fileid_type)
 {
-	xfs_fid2_t		ifid;
-	xfs_fid2_t		pfid;
-	void			*parent = NULL;
-	int			is64 = 0;
-	__u32			*p = fh;
-
-#if XFS_BIG_INUMS
-	is64 = (fileid_type & XFS_FILEID_TYPE_64FLAG);
-	fileid_type &= ~XFS_FILEID_TYPE_64FLAG;
-#endif
-
-	/*
-	 * Note that we only accept fileids which are long enough
-	 * rather than allow the parent generation number to default
-	 * to zero.  XFS considers zero a valid generation number not
-	 * an invalid/wildcard value.  There's little point printk'ing
-	 * a warning here as we don't have the client information
-	 * which would make such a warning useful.
-	 */
-	if (fileid_type > 2 ||
-	    fh_len < xfs_fileid_length((fileid_type == 2), is64))
-		return NULL;
-
-	p = xfs_fileid_decode_fid2(p, &ifid, is64);
-
-	if (fileid_type == 2) {
-		p = xfs_fileid_decode_fid2(p, &pfid, is64);
-		parent = &pfid;
+	switch (fileid_type) {
+	case FILEID_INO32_GEN:
+		return 2;
+	case FILEID_INO32_GEN_PARENT:
+		return 4;
+	case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
+		return 3;
+	case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
+		return 6;
 	}
-
-	fh = (__u32 *)&ifid;
-	return sb->s_export_op->find_exported_dentry(sb, fh, parent, acceptable, context);
+	return 255; /* invalid */
 }
 
-
 STATIC int
 xfs_fs_encode_fh(
 	struct dentry		*dentry,
@@ -96,21 +59,21 @@
 	int			*max_len,
 	int			connectable)
 {
+	struct fid		*fid = (struct fid *)fh;
+	struct xfs_fid64	*fid64 = (struct xfs_fid64 *)fh;
 	struct inode		*inode = dentry->d_inode;
-	int			type = 1;
-	__u32			*p = fh;
+	int			fileid_type;
 	int			len;
-	int			is64 = 0;
-#if XFS_BIG_INUMS
-	if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS)) {
-		/* filesystem may contain 64bit inode numbers */
-		is64 = XFS_FILEID_TYPE_64FLAG;
-	}
-#endif
 
 	/* Directories don't need their parent encoded, they have ".." */
 	if (S_ISDIR(inode->i_mode))
-	    connectable = 0;
+		fileid_type = FILEID_INO32_GEN;
+	else
+		fileid_type = FILEID_INO32_GEN_PARENT;
+
+	/* filesystem may contain 64bit inode numbers */
+	if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS))
+		fileid_type |= XFS_FILEID_TYPE_64FLAG;
 
 	/*
 	 * Only encode if there is enough space given.  In practice
@@ -118,39 +81,118 @@
 	 * over NFSv2 with the subtree_check export option; the other
 	 * seven combinations work.  The real answer is "don't use v2".
 	 */
-	len = xfs_fileid_length(connectable, is64);
+	len = xfs_fileid_length(fileid_type);
 	if (*max_len < len)
 		return 255;
 	*max_len = len;
 
-	p = xfs_fileid_encode_inode(p, inode, is64);
-	if (connectable) {
+	switch (fileid_type) {
+	case FILEID_INO32_GEN_PARENT:
 		spin_lock(&dentry->d_lock);
-		p = xfs_fileid_encode_inode(p, dentry->d_parent->d_inode, is64);
+		fid->i32.parent_ino = dentry->d_parent->d_inode->i_ino;
+		fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation;
 		spin_unlock(&dentry->d_lock);
-		type = 2;
+		/*FALLTHRU*/
+	case FILEID_INO32_GEN:
+		fid->i32.ino = inode->i_ino;
+		fid->i32.gen = inode->i_generation;
+		break;
+	case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
+		spin_lock(&dentry->d_lock);
+		fid64->parent_ino = dentry->d_parent->d_inode->i_ino;
+		fid64->parent_gen = dentry->d_parent->d_inode->i_generation;
+		spin_unlock(&dentry->d_lock);
+		/*FALLTHRU*/
+	case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
+		fid64->ino = inode->i_ino;
+		fid64->gen = inode->i_generation;
+		break;
 	}
-	BUG_ON((p - fh) != len);
-	return type | is64;
+
+	return fileid_type;
+}
+
+STATIC struct inode *
+xfs_nfs_get_inode(
+	struct super_block	*sb,
+	u64			ino,
+	u32			generation)
+ {
+	xfs_fid_t		xfid;
+	bhv_vnode_t		*vp;
+	int			error;
+
+	xfid.fid_len = sizeof(xfs_fid_t) - sizeof(xfid.fid_len);
+	xfid.fid_pad = 0;
+	xfid.fid_ino = ino;
+	xfid.fid_gen = generation;
+
+	error = xfs_vget(XFS_M(sb), &vp, &xfid);
+	if (error)
+		return ERR_PTR(-error);
+
+	return vp ? vn_to_inode(vp) : NULL;
 }
 
 STATIC struct dentry *
-xfs_fs_get_dentry(
-	struct super_block	*sb,
-	void			*data)
+xfs_fs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+		 int fh_len, int fileid_type)
 {
-	bhv_vnode_t		*vp;
-	struct inode		*inode;
+	struct xfs_fid64	*fid64 = (struct xfs_fid64 *)fid;
+	struct inode		*inode = NULL;
 	struct dentry		*result;
-	int			error;
 
-	error = xfs_vget(XFS_M(sb), &vp, (fid_t *)data);
-	if (error || vp == NULL)
-		return ERR_PTR(-ESTALE) ;
+	if (fh_len < xfs_fileid_length(fileid_type))
+		return NULL;
 
-	inode = vn_to_inode(vp);
+	switch (fileid_type) {
+	case FILEID_INO32_GEN_PARENT:
+	case FILEID_INO32_GEN:
+		inode = xfs_nfs_get_inode(sb, fid->i32.ino, fid->i32.gen);
+		break;
+	case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
+	case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
+		inode = xfs_nfs_get_inode(sb, fid64->ino, fid64->gen);
+		break;
+	}
+
+	if (!inode)
+		return NULL;
+	if (IS_ERR(inode))
+		return ERR_PTR(PTR_ERR(inode));
 	result = d_alloc_anon(inode);
-        if (!result) {
+	if (!result) {
+		iput(inode);
+		return ERR_PTR(-ENOMEM);
+	}
+	return result;
+}
+
+STATIC struct dentry *
+xfs_fs_fh_to_parent(struct super_block *sb, struct fid *fid,
+		 int fh_len, int fileid_type)
+{
+	struct xfs_fid64	*fid64 = (struct xfs_fid64 *)fid;
+	struct inode		*inode = NULL;
+	struct dentry		*result;
+
+	switch (fileid_type) {
+	case FILEID_INO32_GEN_PARENT:
+		inode = xfs_nfs_get_inode(sb, fid->i32.parent_ino,
+					      fid->i32.parent_gen);
+		break;
+	case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
+		inode = xfs_nfs_get_inode(sb, fid64->parent_ino,
+					      fid64->parent_gen);
+		break;
+	}
+
+	if (!inode)
+		return NULL;
+	if (IS_ERR(inode))
+		return ERR_PTR(PTR_ERR(inode));
+	result = d_alloc_anon(inode);
+	if (!result) {
 		iput(inode);
 		return ERR_PTR(-ENOMEM);
 	}
@@ -178,9 +220,9 @@
 	return parent;
 }
 
-struct export_operations xfs_export_operations = {
-	.decode_fh		= xfs_fs_decode_fh,
+const struct export_operations xfs_export_operations = {
 	.encode_fh		= xfs_fs_encode_fh,
+	.fh_to_dentry		= xfs_fs_fh_to_dentry,
+	.fh_to_parent		= xfs_fs_fh_to_parent,
 	.get_parent		= xfs_fs_get_parent,
-	.get_dentry		= xfs_fs_get_dentry,
 };
diff --git a/fs/xfs/linux-2.6/xfs_export.h b/fs/xfs/linux-2.6/xfs_export.h
index e794ca4..3272b6a 100644
--- a/fs/xfs/linux-2.6/xfs_export.h
+++ b/fs/xfs/linux-2.6/xfs_export.h
@@ -59,50 +59,14 @@
  * a subdirectory) or use the "fsid" export option.
  */
 
+struct xfs_fid64 {
+	u64 ino;
+	u32 gen;
+	u64 parent_ino;
+	u32 parent_gen;
+} __attribute__((packed));
+
 /* This flag goes on the wire.  Don't play with it. */
 #define XFS_FILEID_TYPE_64FLAG	0x80	/* NFS fileid has 64bit inodes */
 
-/* Calculate the length in u32 units of the fileid data */
-static inline int
-xfs_fileid_length(int hasparent, int is64)
-{
-	return hasparent ? (is64 ? 6 : 4) : (is64 ? 3 : 2);
-}
-
-/*
- * Decode encoded inode information (either for the inode itself
- * or the parent) into an xfs_fid2_t structure.  Advances and
- * returns the new data pointer
- */
-static inline __u32 *
-xfs_fileid_decode_fid2(__u32 *p, xfs_fid2_t *fid, int is64)
-{
-	fid->fid_len = sizeof(xfs_fid2_t) - sizeof(fid->fid_len);
-	fid->fid_pad = 0;
-	fid->fid_ino = *p++;
-#if XFS_BIG_INUMS
-	if (is64)
-		fid->fid_ino |= (((__u64)(*p++)) << 32);
-#endif
-	fid->fid_gen = *p++;
-	return p;
-}
-
-/*
- * Encode inode information (either for the inode itself or the
- * parent) into a fileid buffer.  Advances and returns the new
- * data pointer.
- */
-static inline __u32 *
-xfs_fileid_encode_inode(__u32 *p, struct inode *inode, int is64)
-{
-	*p++ = (__u32)inode->i_ino;
-#if XFS_BIG_INUMS
-	if (is64)
-		*p++ = (__u32)(inode->i_ino >> 32);
-#endif
-	*p++ = inode->i_generation;
-	return p;
-}
-
 #endif	/* __XFS_EXPORT_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index ffec630..2b34bad 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -152,11 +152,11 @@
 		lock_mode = xfs_ilock_map_shared(ip);
 
 		/* fill in fid section of handle from inode */
-		handle.ha_fid.xfs_fid_len = sizeof(xfs_fid_t) -
-					    sizeof(handle.ha_fid.xfs_fid_len);
-		handle.ha_fid.xfs_fid_pad = 0;
-		handle.ha_fid.xfs_fid_gen = ip->i_d.di_gen;
-		handle.ha_fid.xfs_fid_ino = ip->i_ino;
+		handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
+					sizeof(handle.ha_fid.fid_len);
+		handle.ha_fid.fid_pad = 0;
+		handle.ha_fid.fid_gen = ip->i_d.di_gen;
+		handle.ha_fid.fid_ino = ip->i_ino;
 
 		xfs_iunlock_map_shared(ip, lock_mode);
 
@@ -222,10 +222,10 @@
 	if (hlen < sizeof(*handlep))
 		memset(((char *)handlep) + hlen, 0, sizeof(*handlep) - hlen);
 	if (hlen > sizeof(handlep->ha_fsid)) {
-		if (handlep->ha_fid.xfs_fid_len !=
-				(hlen - sizeof(handlep->ha_fsid)
-					- sizeof(handlep->ha_fid.xfs_fid_len))
-		    || handlep->ha_fid.xfs_fid_pad)
+		if (handlep->ha_fid.fid_len !=
+		    (hlen - sizeof(handlep->ha_fsid) -
+		            sizeof(handlep->ha_fid.fid_len)) ||
+		    handlep->ha_fid.fid_pad)
 			return XFS_ERROR(EINVAL);
 	}
 
@@ -233,9 +233,9 @@
 	 * Crack the handle, obtain the inode # & generation #
 	 */
 	xfid = (struct xfs_fid *)&handlep->ha_fid;
-	if (xfid->xfs_fid_len == sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) {
-		ino  = xfid->xfs_fid_ino;
-		igen = xfid->xfs_fid_gen;
+	if (xfid->fid_len == sizeof(*xfid) - sizeof(xfid->fid_len)) {
+		ino  = xfid->fid_ino;
+		igen = xfid->fid_gen;
 	} else {
 		return XFS_ERROR(EINVAL);
 	}
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index c78c233..3efcf45 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -118,7 +118,7 @@
 extern void xfs_blkdev_put(struct block_device *);
 extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
 
-extern struct export_operations xfs_export_operations;
+extern const struct export_operations xfs_export_operations;
 
 #define XFS_M(sb)		((struct xfs_mount *)((sb)->s_fs_info))
 
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c
index 6cd5704..a1e55fb 100644
--- a/fs/xfs/xfs_dmops.c
+++ b/fs/xfs/xfs_dmops.c
@@ -41,29 +41,16 @@
 xfs_dmops_get(struct xfs_mount *mp, struct xfs_mount_args *args)
 {
 	if (args->flags & XFSMNT_DMAPI) {
-		struct xfs_dmops *ops;
-
-		ops = symbol_get(xfs_dmcore_xfs);
-		if (!ops) {
-			request_module("xfs_dmapi");
-			ops = symbol_get(xfs_dmcore_xfs);
-		}
-
-		if (!ops) {
-			cmn_err(CE_WARN, "XFS: no dmapi support available.");
-			return EINVAL;
-		}
-		mp->m_dm_ops = ops;
-	} else {
-		mp->m_dm_ops = &xfs_dmcore_stub;
+		cmn_err(CE_WARN,
+			"XFS: dmapi support not available in this kernel.");
+		return EINVAL;
 	}
 
+	mp->m_dm_ops = &xfs_dmcore_stub;
 	return 0;
 }
 
 void
 xfs_dmops_put(struct xfs_mount *mp)
 {
-	if (mp->m_dm_ops != &xfs_dmcore_stub)
-		symbol_put(xfs_dmcore_xfs);
 }
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index ec3c9c2..aab9662 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -389,30 +389,13 @@
  */
 typedef struct { __u32 val[2]; } xfs_fsid_t; /* file system id type */
 
-
-#ifndef HAVE_FID
-#define MAXFIDSZ	46
-
-typedef struct fid {
-	__u16		fid_len;		/* length of data in bytes */
-	unsigned char	fid_data[MAXFIDSZ];	/* data (fid_len worth)  */
-} fid_t;
-#endif
-
 typedef struct xfs_fid {
-	__u16	xfs_fid_len;		/* length of remainder	*/
-	__u16	xfs_fid_pad;
-	__u32	xfs_fid_gen;		/* generation number	*/
-	__u64	xfs_fid_ino;		/* 64 bits inode number */
+	__u16	fid_len;		/* length of remainder	*/
+	__u16	fid_pad;
+	__u32	fid_gen;		/* generation number	*/
+	__u64	fid_ino;		/* 64 bits inode number */
 } xfs_fid_t;
 
-typedef struct xfs_fid2 {
-	__u16	fid_len;	/* length of remainder */
-	__u16	fid_pad;	/* padding, must be zero */
-	__u32	fid_gen;	/* generation number */
-	__u64	fid_ino;	/* inode number */
-} xfs_fid2_t;
-
 typedef struct xfs_handle {
 	union {
 		__s64	    align;	/* force alignment of ha_fid	 */
@@ -422,9 +405,9 @@
 } xfs_handle_t;
 #define ha_fsid ha_u._ha_fsid
 
-#define XFS_HSIZE(handle)	(((char *) &(handle).ha_fid.xfs_fid_pad	 \
+#define XFS_HSIZE(handle)	(((char *) &(handle).ha_fid.fid_pad	 \
 				 - (char *) &(handle))			  \
-				 + (handle).ha_fid.xfs_fid_len)
+				 + (handle).ha_fid.fid_len)
 
 /*
  * Flags for going down operation
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index c266a01..2ec1d8a 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -135,19 +135,13 @@
 xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args)
 {
 	if (args->flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA)) {
-		struct xfs_qmops *ops;
-
-		ops = symbol_get(xfs_qmcore_xfs);
-		if (!ops) {
-			request_module("xfs_quota");
-			ops = symbol_get(xfs_qmcore_xfs);
-		}
-
-		if (!ops) {
-			cmn_err(CE_WARN, "XFS: no quota support available.");
-			return EINVAL;
-		}
-		mp->m_qm_ops = ops;
+#ifdef CONFIG_XFS_QUOTA
+		mp->m_qm_ops = &xfs_qmcore_xfs;
+#else
+		cmn_err(CE_WARN,
+			"XFS: qouta support not available in this kernel.");
+		return EINVAL;
+#endif
 	} else {
 		mp->m_qm_ops = &xfs_qmcore_stub;
 	}
@@ -158,6 +152,4 @@
 void
 xfs_qmops_put(struct xfs_mount *mp)
 {
-	if (mp->m_qm_ops != &xfs_qmcore_stub)
-		symbol_put(xfs_qmcore_xfs);
 }
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index a5a8454..a154459 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -1635,9 +1635,8 @@
 xfs_vget(
 	xfs_mount_t	*mp,
 	bhv_vnode_t	**vpp,
-	fid_t		*fidp)
+	xfs_fid_t	*xfid)
 {
-	xfs_fid_t	*xfid = (struct xfs_fid *)fidp;
 	xfs_inode_t	*ip;
 	int		error;
 	xfs_ino_t	ino;
@@ -1647,11 +1646,11 @@
 	 * Invalid.  Since handles can be created in user space and passed in
 	 * via gethandle(), this is not cause for a panic.
 	 */
-	if (xfid->xfs_fid_len != sizeof(*xfid) - sizeof(xfid->xfs_fid_len))
+	if (xfid->fid_len != sizeof(*xfid) - sizeof(xfid->fid_len))
 		return XFS_ERROR(EINVAL);
 
-	ino  = xfid->xfs_fid_ino;
-	igen = xfid->xfs_fid_gen;
+	ino  = xfid->fid_ino;
+	igen = xfid->fid_gen;
 
 	/*
 	 * NFS can sometimes send requests for ino 0.  Fail them gracefully.
diff --git a/fs/xfs/xfs_vfsops.h b/fs/xfs/xfs_vfsops.h
index bc99e3e..a592fe0 100644
--- a/fs/xfs/xfs_vfsops.h
+++ b/fs/xfs/xfs_vfsops.h
@@ -2,7 +2,7 @@
 #define _XFS_VFSOPS_H 1
 
 struct cred;
-struct fid;
+struct xfs_fid;
 struct inode;
 struct kstatfs;
 struct xfs_mount;
@@ -17,7 +17,7 @@
 int xfs_statvfs(struct xfs_mount *mp, struct kstatfs *statp,
 		bhv_vnode_t *vp);
 int xfs_sync(struct xfs_mount *mp, int flags);
-int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct fid *fidp);
+int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct xfs_fid *xfid);
 int xfs_parseargs(struct xfs_mount *mp, char *options,
 		struct xfs_mount_args *args, int update);
 int xfs_showargs(struct xfs_mount *mp, struct seq_file *m);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 5e3c57c..efd5aff 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -3466,23 +3466,14 @@
 }
 
 
-/*
- * xfs_fid2
- *
- * A fid routine that takes a pointer to a previously allocated
- * fid structure (like xfs_fast_fid) but uses a 64 bit inode number.
- */
 int
 xfs_fid2(
 	xfs_inode_t	*ip,
-	fid_t		*fidp)
+	xfs_fid_t	*xfid)
 {
-	xfs_fid2_t	*xfid = (xfs_fid2_t *)fidp;
-
 	vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
-	ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t));
 
-	xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len);
+	xfid->fid_len = sizeof(xfs_fid_t) - sizeof(xfid->fid_len);
 	xfid->fid_pad = 0;
 	/*
 	 * use memcpy because the inode is a long long and there's no
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index f36e74f..b7e461c 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -39,7 +39,7 @@
 int xfs_symlink(struct xfs_inode *dp, bhv_vname_t *dentry,
 		char *target_path, mode_t mode, bhv_vnode_t **vpp,
 		struct cred *credp);
-int xfs_fid2(struct xfs_inode *ip, fid_t	*fidp);
+int xfs_fid2(struct xfs_inode *ip, struct xfs_fid *xfid);
 int xfs_rwlock(struct xfs_inode *ip, bhv_vrwlock_t locktype);
 void xfs_rwunlock(struct xfs_inode *ip, bhv_vrwlock_t locktype);
 int xfs_inode_flush(struct xfs_inode *ip, int flags);
diff --git a/include/acpi/achware.h b/include/acpi/achware.h
index 9df275c..4053df9 100644
--- a/include/acpi/achware.h
+++ b/include/acpi/achware.h
@@ -71,9 +71,9 @@
 struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id);
 
 acpi_status
-acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value);
+acpi_hw_register_read(u32 register_id, u32 * return_value);
 
-acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value);
+acpi_status acpi_hw_register_write(u32 register_id, u32 value);
 
 acpi_status
 acpi_hw_low_level_read(u32 width,
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 86aea44..7b74b60 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -264,7 +264,6 @@
 
 struct acpi_device_wakeup_state {
 	u8 enabled:1;
-	u8 active:1;
 };
 
 struct acpi_device_wakeup {
@@ -333,6 +332,7 @@
 int acpi_bus_set_power(acpi_handle handle, int state);
 #ifdef CONFIG_ACPI_PROC_EVENT
 int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);
+int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data);
 int acpi_bus_receive_event(struct acpi_bus_event *event);
 #else
 static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 3d7ab9e..9512f04 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -314,6 +314,8 @@
  */
 acpi_status acpi_get_register(u32 register_id, u32 * return_value);
 
+acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value);
+
 acpi_status acpi_set_register(u32 register_id, u32 value);
 
 acpi_status
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index 4e5d3ca..a1b1b2e 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -257,7 +257,8 @@
 struct acpi_table_dmar {
 	struct acpi_table_header header;	/* Common ACPI table header */
 	u8 width;		/* Host Address Width */
-	u8 reserved[11];
+	u8 flags;
+	u8 reserved[10];
 };
 
 /* DMAR subtable header */
@@ -265,8 +266,6 @@
 struct acpi_dmar_header {
 	u16 type;
 	u16 length;
-	u8 flags;
-	u8 reserved[3];
 };
 
 /* Values for subtable type in struct acpi_dmar_header */
@@ -274,13 +273,15 @@
 enum acpi_dmar_type {
 	ACPI_DMAR_TYPE_HARDWARE_UNIT = 0,
 	ACPI_DMAR_TYPE_RESERVED_MEMORY = 1,
-	ACPI_DMAR_TYPE_RESERVED = 2	/* 2 and greater are reserved */
+	ACPI_DMAR_TYPE_ATSR = 2,
+	ACPI_DMAR_TYPE_RESERVED = 3	/* 3 and greater are reserved */
 };
 
 struct acpi_dmar_device_scope {
 	u8 entry_type;
 	u8 length;
-	u8 segment;
+	u16 reserved;
+	u8 enumeration_id;
 	u8 bus;
 };
 
@@ -290,7 +291,14 @@
 	ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0,
 	ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1,
 	ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2,
-	ACPI_DMAR_SCOPE_TYPE_RESERVED = 3	/* 3 and greater are reserved */
+	ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3,
+	ACPI_DMAR_SCOPE_TYPE_HPET = 4,
+	ACPI_DMAR_SCOPE_TYPE_RESERVED = 5	/* 5 and greater are reserved */
+};
+
+struct acpi_dmar_pci_path {
+	u8 dev;
+	u8 fn;
 };
 
 /*
@@ -301,6 +309,9 @@
 
 struct acpi_dmar_hardware_unit {
 	struct acpi_dmar_header header;
+	u8 flags;
+	u8 reserved;
+	u16 segment;
 	u64 address;		/* Register Base Address */
 };
 
@@ -312,7 +323,9 @@
 
 struct acpi_dmar_reserved_memory {
 	struct acpi_dmar_header header;
-	u64 address;		/* 4_k aligned base address */
+	u16 reserved;
+	u16 segment;
+	u64 base_address;		/* 4_k aligned base address */
 	u64 end_address;	/* 4_k aligned limit address */
 };
 
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 99934a9..26d79f6 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -3,6 +3,7 @@
 
 #include <linux/kernel.h>
 #include <linux/cpu.h>
+#include <linux/cpuidle.h>
 
 #include <asm/acpi.h>
 
@@ -75,7 +76,9 @@
 };
 
 struct acpi_processor_power {
+	struct cpuidle_device dev;
 	struct acpi_processor_cx *state;
+	struct acpi_processor_cx *bm_state;
 	unsigned long bm_check_timestamp;
 	u32 default_state;
 	u32 bm_activity;
@@ -199,6 +202,7 @@
 	u8 bm_check:1;
 	u8 has_cst:1;
 	u8 power_setup_done:1;
+	u8 bm_rld_set:1;
 };
 
 struct acpi_processor {
@@ -322,6 +326,7 @@
 			      struct acpi_device *device);
 int acpi_processor_suspend(struct acpi_device * device, pm_message_t state);
 int acpi_processor_resume(struct acpi_device * device);
+extern struct cpuidle_driver acpi_idle_driver;
 
 /* in processor_thermal.c */
 int acpi_processor_get_limit_info(struct acpi_processor *pr);
diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
index 9e71201..9e19a70 100644
--- a/include/asm-alpha/bitops.h
+++ b/include/asm-alpha/bitops.h
@@ -1,7 +1,12 @@
 #ifndef _ALPHA_BITOPS_H
 #define _ALPHA_BITOPS_H
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm/compiler.h>
+#include <asm/barrier.h>
 
 /*
  * Copyright 1994, Linus Torvalds.
@@ -69,6 +74,13 @@
 	:"Ir" (1UL << (nr & 31)), "m" (*m));
 }
 
+static inline void
+clear_bit_unlock(unsigned long nr, volatile void * addr)
+{
+	smp_mb();
+	clear_bit(nr, addr);
+}
+
 /*
  * WARNING: non atomic version.
  */
@@ -81,6 +93,13 @@
 }
 
 static inline void
+__clear_bit_unlock(unsigned long nr, volatile void * addr)
+{
+	smp_mb();
+	__clear_bit(nr, addr);
+}
+
+static inline void
 change_bit(unsigned long nr, volatile void * addr)
 {
 	unsigned long temp;
@@ -117,6 +136,36 @@
 	int *m = ((int *) addr) + (nr >> 5);
 
 	__asm__ __volatile__(
+#ifdef CONFIG_SMP
+	"	mb\n"
+#endif
+	"1:	ldl_l %0,%4\n"
+	"	and %0,%3,%2\n"
+	"	bne %2,2f\n"
+	"	xor %0,%3,%0\n"
+	"	stl_c %0,%1\n"
+	"	beq %0,3f\n"
+	"2:\n"
+#ifdef CONFIG_SMP
+	"	mb\n"
+#endif
+	".subsection 2\n"
+	"3:	br 1b\n"
+	".previous"
+	:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
+	:"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
+
+	return oldbit != 0;
+}
+
+static inline int
+test_and_set_bit_lock(unsigned long nr, volatile void *addr)
+{
+	unsigned long oldbit;
+	unsigned long temp;
+	int *m = ((int *) addr) + (nr >> 5);
+
+	__asm__ __volatile__(
 	"1:	ldl_l %0,%4\n"
 	"	and %0,%3,%2\n"
 	"	bne %2,2f\n"
@@ -158,6 +207,9 @@
 	int *m = ((int *) addr) + (nr >> 5);
 
 	__asm__ __volatile__(
+#ifdef CONFIG_SMP
+	"	mb\n"
+#endif
 	"1:	ldl_l %0,%4\n"
 	"	and %0,%3,%2\n"
 	"	beq %2,2f\n"
@@ -199,6 +251,9 @@
 	int *m = ((int *) addr) + (nr >> 5);
 
 	__asm__ __volatile__(
+#ifdef CONFIG_SMP
+	"	mb\n"
+#endif
 	"1:	ldl_l %0,%4\n"
 	"	and %0,%3,%2\n"
 	"	xor %0,%3,%0\n"
diff --git a/include/asm-alpha/ide.h b/include/asm-alpha/ide.h
index 2a5cc0b..b7bf68d 100644
--- a/include/asm-alpha/ide.h
+++ b/include/asm-alpha/ide.h
@@ -40,7 +40,6 @@
 	}
 }
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)	((base) + 0x206) /* obsolete */
 
 #ifdef CONFIG_PCI
diff --git a/include/asm-alpha/scatterlist.h b/include/asm-alpha/scatterlist.h
index 9173654..440747c 100644
--- a/include/asm-alpha/scatterlist.h
+++ b/include/asm-alpha/scatterlist.h
@@ -5,7 +5,10 @@
 #include <asm/types.h>
   
 struct scatterlist {
-	struct page *page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long sg_magic;
+#endif
+	unsigned long page_link;
 	unsigned int offset;
 
 	unsigned int length;
diff --git a/include/asm-alpha/tlbflush.h b/include/asm-alpha/tlbflush.h
index 1ca3ed3..eefab3f 100644
--- a/include/asm-alpha/tlbflush.h
+++ b/include/asm-alpha/tlbflush.h
@@ -92,17 +92,6 @@
 	if (*mmc) *mmc = 0;
 }
 
-/* Flush a specified range of user mapping page tables from TLB.
-   Although Alpha uses VPTE caches, this can be a nop, as Alpha does
-   not have finegrained tlb flushing, so it will flush VPTE stuff
-   during next flush_tlb_range.  */
-
-static inline void
-flush_tlb_pgtables(struct mm_struct *mm, unsigned long start,
-		   unsigned long end)
-{
-}
-
 #ifndef CONFIG_SMP
 /* Flush everything (kernel mapping may also have changed
    due to vmalloc/vfree).  */
diff --git a/include/asm-arm/arch-aaec2000/aaec2000.h b/include/asm-arm/arch-aaec2000/aaec2000.h
index 0022279..a6d1ee0 100644
--- a/include/asm-arm/arch-aaec2000/aaec2000.h
+++ b/include/asm-arm/arch-aaec2000/aaec2000.h
@@ -140,11 +140,11 @@
 #define TIMER3_CLEAR	__REG(0x80000e0c)	/* Timer 3 Clear Register */
 
 /* Timer Control register bits */
-#define TIMER_CTRL_ENABLE	(1 << 7) /* Enable (Start° Timer */
+#define TIMER_CTRL_ENABLE	(1 << 7) /* Enable (Start Timer) */
 #define TIMER_CTRL_PERIODIC	(1 << 6) /* Periodic Running Mode */
 #define TIMER_CTRL_FREE_RUNNING (0 << 6) /* Normal Running Mode */
 #define TIMER_CTRL_CLKSEL_508K	(1 << 3) /* 508KHz Clock select (Timer 1, 2) */
-#define TIMER_CTRL_CLKSEL_2K	(0 << 3) /* 2KHz Clock Select (Timer 1, 2)*/
+#define TIMER_CTRL_CLKSEL_2K	(0 << 3) /* 2KHz Clock Select (Timer 1, 2) */
 
 /* Power and State Control */
 #define POWER_BASE	__REG(0x80000400)
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h
index c72f9d7..eeeea90 100644
--- a/include/asm-arm/arch-ixp4xx/io.h
+++ b/include/asm-arm/arch-ixp4xx/io.h
@@ -17,9 +17,6 @@
 
 #define IO_SPACE_LIMIT 0xffff0000
 
-#define	BIT(x)	((1)<<(x))
-
-
 extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
 extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
 
diff --git a/include/asm-arm/arch-pxa/pm.h b/include/asm-arm/arch-pxa/pm.h
index 6903db7..9d9f4b5 100644
--- a/include/asm-arm/arch-pxa/pm.h
+++ b/include/asm-arm/arch-pxa/pm.h
@@ -7,6 +7,8 @@
  *
  */
 
+#include <linux/suspend.h>
+
 struct pxa_cpu_pm_fns {
 	int	save_size;
 	void	(*save)(unsigned long *);
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
index b41831b6..47a6b08 100644
--- a/include/asm-arm/bitops.h
+++ b/include/asm-arm/bitops.h
@@ -19,6 +19,10 @@
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/system.h>
 
@@ -286,6 +290,7 @@
 
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 /*
  * Ext2 is defined to use little-endian byte ordering.
diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
index 678134b..e99406a 100644
--- a/include/asm-arm/dma-mapping.h
+++ b/include/asm-arm/dma-mapping.h
@@ -5,7 +5,7 @@
 
 #include <linux/mm.h> /* need struct page */
 
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 /*
  * DMA-consistent mapping functions.  These allocate/free a region of
@@ -274,8 +274,8 @@
 	for (i = 0; i < nents; i++, sg++) {
 		char *virt;
 
-		sg->dma_address = page_to_dma(dev, sg->page) + sg->offset;
-		virt = page_address(sg->page) + sg->offset;
+		sg->dma_address = page_to_dma(dev, sg_page(sg)) + sg->offset;
+		virt = sg_virt(sg);
 
 		if (!arch_is_coherent())
 			dma_cache_maint(virt, sg->length, dir);
@@ -371,7 +371,7 @@
 	int i;
 
 	for (i = 0; i < nents; i++, sg++) {
-		char *virt = page_address(sg->page) + sg->offset;
+		char *virt = sg_virt(sg);
 		if (!arch_is_coherent())
 			dma_cache_maint(virt, sg->length, dir);
 	}
@@ -384,7 +384,7 @@
 	int i;
 
 	for (i = 0; i < nents; i++, sg++) {
-		char *virt = page_address(sg->page) + sg->offset;
+		char *virt = sg_virt(sg);
 		if (!arch_is_coherent())
 			dma_cache_maint(virt, sg->length, dir);
 	}
@@ -401,7 +401,7 @@
  *
  * On the SA-1111, a bug limits DMA to only certain regions of RAM.
  * On the IXP425, the PCI inbound window is 64MB (256MB total RAM)
- * On some ADI engineering sytems, PCI inbound window is 32MB (12MB total RAM)
+ * On some ADI engineering systems, PCI inbound window is 32MB (12MB total RAM)
  *
  * The following are helper functions used by the dmabounce subystem
  *
diff --git a/include/asm-arm/ide.h b/include/asm-arm/ide.h
index 4f68c8a..f348fcf 100644
--- a/include/asm-arm/ide.h
+++ b/include/asm-arm/ide.h
@@ -18,7 +18,6 @@
 #endif
 
 #if !defined(CONFIG_ARCH_L7200)
-# define IDE_ARCH_OBSOLETE_INIT
 # ifdef CONFIG_ARCH_CLPS7500
 #  define ide_default_io_ctl(base)	((base) + 0x206) /* obsolete */
 # else
diff --git a/include/asm-arm/scatterlist.h b/include/asm-arm/scatterlist.h
index de2f65e..ca0a37d 100644
--- a/include/asm-arm/scatterlist.h
+++ b/include/asm-arm/scatterlist.h
@@ -5,7 +5,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;		/* buffer page			 */
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;		/* buffer offset		 */
 	dma_addr_t	dma_address;	/* dma address			 */
 	unsigned int	length;		/* length			 */
diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h
index 71be4fd..8c6bc1b 100644
--- a/include/asm-arm/tlbflush.h
+++ b/include/asm-arm/tlbflush.h
@@ -463,11 +463,6 @@
  */
 extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte);
 
-/*
- * ARM processors do not cache TLB tables in RAM.
- */
-#define flush_tlb_pgtables(mm,start,end)	do { } while (0)
-
 #endif
 
 #endif /* CONFIG_MMU */
diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h
index 7dbd603..d6993a6 100644
--- a/include/asm-avr32/arch-at32ap/board.h
+++ b/include/asm-avr32/arch-at32ap/board.h
@@ -44,6 +44,13 @@
 struct platform_device *
 at32_add_device_usba(unsigned int id, struct usba_platform_data *data);
 
+struct ide_platform_data {
+	u8      cs;
+};
+struct platform_device *
+at32_add_device_ide(unsigned int id, unsigned int extint,
+		    struct ide_platform_data *data);
+
 /* depending on what's hooked up, not all SSC pins will be used */
 #define	ATMEL_SSC_TK		0x01
 #define	ATMEL_SSC_TF		0x02
@@ -58,4 +65,20 @@
 struct platform_device *
 at32_add_device_ssc(unsigned int id, unsigned int flags);
 
+struct platform_device *at32_add_device_twi(unsigned int id);
+struct platform_device *at32_add_device_mci(unsigned int id);
+struct platform_device *at32_add_device_ac97c(unsigned int id);
+struct platform_device *at32_add_device_abdac(unsigned int id);
+
+struct cf_platform_data {
+	int	detect_pin;
+	int	reset_pin;
+	int	vcc_pin;
+	int	ready_pin;
+	u8	cs;
+};
+struct platform_device *
+at32_add_device_cf(unsigned int id, unsigned int extint,
+		struct cf_platform_data *data);
+
 #endif /* __ASM_ARCH_BOARD_H */
diff --git a/include/asm-avr32/bitops.h b/include/asm-avr32/bitops.h
index 5299f8c..1a50b69 100644
--- a/include/asm-avr32/bitops.h
+++ b/include/asm-avr32/bitops.h
@@ -8,6 +8,10 @@
 #ifndef __ASM_AVR32_BITOPS_H
 #define __ASM_AVR32_BITOPS_H
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm/byteorder.h>
 #include <asm/system.h>
 
@@ -288,6 +292,7 @@
 #include <asm-generic/bitops/fls64.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
diff --git a/include/asm-avr32/dma-mapping.h b/include/asm-avr32/dma-mapping.h
index 81e3426..a713163 100644
--- a/include/asm-avr32/dma-mapping.h
+++ b/include/asm-avr32/dma-mapping.h
@@ -217,8 +217,8 @@
 	for (i = 0; i < nents; i++) {
 		char *virt;
 
-		sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset;
-		virt = page_address(sg[i].page) + sg[i].offset;
+		sg[i].dma_address = page_to_bus(sg_page(&sg[i])) + sg[i].offset;
+		virt = sg_virt(&sg[i]);
 		dma_cache_sync(dev, virt, sg[i].length, direction);
 	}
 
@@ -327,8 +327,7 @@
 	int i;
 
 	for (i = 0; i < nents; i++) {
-		dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
-			       sg[i].length, direction);
+		dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, direction);
 	}
 }
 
diff --git a/include/asm-avr32/scatterlist.h b/include/asm-avr32/scatterlist.h
index c6d5ce3..377320e 100644
--- a/include/asm-avr32/scatterlist.h
+++ b/include/asm-avr32/scatterlist.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+   unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     dma_addr_t		dma_address;
     unsigned int	length;
diff --git a/include/asm-avr32/tlbflush.h b/include/asm-avr32/tlbflush.h
index 730e268..5bc7c88 100644
--- a/include/asm-avr32/tlbflush.h
+++ b/include/asm-avr32/tlbflush.h
@@ -19,7 +19,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 extern void flush_tlb(void);
 extern void flush_tlb_all(void);
@@ -29,12 +28,6 @@
 extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
 extern void __flush_tlb_page(unsigned long asid, unsigned long page);
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-	/* Nothing to do */
-}
-
 extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
 
 #endif /* __ASM_AVR32_TLBFLUSH_H */
diff --git a/include/asm-blackfin/bf5xx_timers.h b/include/asm-blackfin/bf5xx_timers.h
deleted file mode 100644
index 86c7703..0000000
--- a/include/asm-blackfin/bf5xx_timers.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * include/asm/bf5xx_timers.h
- *
- * This file contains the major Data structures and constants
- * used for General Purpose Timer Implementation in BF5xx
- *
- * Copyright (C) 2005 John DeHority
- * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
- *
- */
-
-#ifndef _BLACKFIN_TIMERS_H_
-#define _BLACKFIN_TIMERS_H_
-
-#undef MAX_BLACKFIN_GPTIMERS
-/*
- * BF537: 8 timers:
- */
-#if defined(CONFIG_BF537)
-#  define MAX_BLACKFIN_GPTIMERS 8
-#  define TIMER0_GROUP_REG     TIMER_ENABLE
-#endif
-/*
- * BF561: 12 timers:
- */
-#if defined(CONFIG_BF561)
-#  define MAX_BLACKFIN_GPTIMERS 12
-#  define TIMER0_GROUP_REG     TMRS8_ENABLE
-#  define TIMER8_GROUP_REG     TMRS4_ENABLE
-#endif
-/*
- * All others: 3 timers:
- */
-#if !defined(MAX_BLACKFIN_GPTIMERS)
-#  define MAX_BLACKFIN_GPTIMERS 3
-#  define TIMER0_GROUP_REG     TIMER_ENABLE
-#endif
-
-#define BLACKFIN_GPTIMER_IDMASK ((1UL << MAX_BLACKFIN_GPTIMERS) - 1)
-#define BFIN_TIMER_OCTET(x) ((x) >> 3)
-
-/* used in masks for timer_enable() and timer_disable() */
-#define TIMER0bit  0x0001  /*  0001b */
-#define TIMER1bit  0x0002  /*  0010b */
-#define TIMER2bit  0x0004  /*  0100b */
-
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-#  define TIMER3bit  0x0008
-#  define TIMER4bit  0x0010
-#  define TIMER5bit  0x0020
-#  define TIMER6bit  0x0040
-#  define TIMER7bit  0x0080
-#endif
-
-#if (MAX_BLACKFIN_GPTIMERS > 8)
-#  define TIMER8bit  0x0100
-#  define TIMER9bit  0x0200
-#  define TIMER10bit 0x0400
-#  define TIMER11bit 0x0800
-#endif
-
-#define TIMER0_id   0
-#define TIMER1_id   1
-#define TIMER2_id   2
-
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-#  define TIMER3_id   3
-#  define TIMER4_id   4
-#  define TIMER5_id   5
-#  define TIMER6_id   6
-#  define TIMER7_id   7
-#endif
-
-#if (MAX_BLACKFIN_GPTIMERS > 8)
-#  define TIMER8_id   8
-#  define TIMER9_id   9
-#  define TIMER10_id 10
-#  define TIMER11_id 11
-#endif
-
-/* associated timers for ppi framesync: */
-
-#if defined(CONFIG_BF561)
-#  define FS0_1_TIMER_ID   TIMER8_id
-#  define FS0_2_TIMER_ID   TIMER9_id
-#  define FS1_1_TIMER_ID   TIMER10_id
-#  define FS1_2_TIMER_ID   TIMER11_id
-#  define FS0_1_TIMER_BIT  TIMER8bit
-#  define FS0_2_TIMER_BIT  TIMER9bit
-#  define FS1_1_TIMER_BIT  TIMER10bit
-#  define FS1_2_TIMER_BIT  TIMER11bit
-#  undef FS1_TIMER_ID
-#  undef FS2_TIMER_ID
-#  undef FS1_TIMER_BIT
-#  undef FS2_TIMER_BIT
-#else
-#  define FS1_TIMER_ID  TIMER0_id
-#  define FS2_TIMER_ID  TIMER1_id
-#  define FS1_TIMER_BIT TIMER0bit
-#  define FS2_TIMER_BIT TIMER1bit
-#endif
-
-/*
-** Timer Configuration Register Bits
-*/
-#define TIMER_ERR           0xC000
-#define TIMER_ERR_OVFL      0x4000
-#define TIMER_ERR_PROG_PER  0x8000
-#define TIMER_ERR_PROG_PW   0xC000
-#define TIMER_EMU_RUN       0x0200
-#define	TIMER_TOGGLE_HI     0x0100
-#define	TIMER_CLK_SEL       0x0080
-#define TIMER_OUT_DIS       0x0040
-#define TIMER_TIN_SEL       0x0020
-#define TIMER_IRQ_ENA       0x0010
-#define TIMER_PERIOD_CNT    0x0008
-#define TIMER_PULSE_HI      0x0004
-#define TIMER_MODE          0x0003
-#define TIMER_MODE_PWM      0x0001
-#define TIMER_MODE_WDTH     0x0002
-#define TIMER_MODE_EXT_CLK  0x0003
-
-/*
-** Timer Status Register Bits
-*/
-#define TIMER_STATUS_TIMIL0 0x0001
-#define TIMER_STATUS_TIMIL1 0x0002
-#define TIMER_STATUS_TIMIL2 0x0004
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-#  define TIMER_STATUS_TIMIL3 0x00000008
-#  define TIMER_STATUS_TIMIL4 0x00010000
-#  define TIMER_STATUS_TIMIL5 0x00020000
-#  define TIMER_STATUS_TIMIL6 0x00040000
-#  define TIMER_STATUS_TIMIL7 0x00080000
-#  if (MAX_BLACKFIN_GPTIMERS > 8)
-#    define TIMER_STATUS_TIMIL8  0x0001
-#    define TIMER_STATUS_TIMIL9  0x0002
-#    define TIMER_STATUS_TIMIL10 0x0004
-#    define TIMER_STATUS_TIMIL11 0x0008
-#  endif
-#  define TIMER_STATUS_INTR   0x000F000F
-#else
-#  define TIMER_STATUS_INTR   0x0007	/* any timer interrupt */
-#endif
-
-#define TIMER_STATUS_TOVF0  0x0010	/* timer 0 overflow error */
-#define TIMER_STATUS_TOVF1  0x0020
-#define TIMER_STATUS_TOVF2  0x0040
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-#  define TIMER_STATUS_TOVF3  0x00000080
-#  define TIMER_STATUS_TOVF4  0x00100000
-#  define TIMER_STATUS_TOVF5  0x00200000
-#  define TIMER_STATUS_TOVF6  0x00400000
-#  define TIMER_STATUS_TOVF7  0x00800000
-#  if (MAX_BLACKFIN_GPTIMERS > 8)
-#    define TIMER_STATUS_TOVF8   0x0010
-#    define TIMER_STATUS_TOVF9   0x0020
-#    define TIMER_STATUS_TOVF10  0x0040
-#    define TIMER_STATUS_TOVF11  0x0080
-#  endif
-#  define TIMER_STATUS_OFLOW  0x00F000F0
-#else
-#  define TIMER_STATUS_OFLOW  0x0070	/* any timer overflow */
-#endif
-
-/*
-** Timer Slave Enable Status : write 1 to clear
-*/
-#define TIMER_STATUS_TRUN0  0x1000
-#define TIMER_STATUS_TRUN1  0x2000
-#define TIMER_STATUS_TRUN2  0x4000
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-#  define TIMER_STATUS_TRUN3  0x00008000
-#  define TIMER_STATUS_TRUN4  0x10000000
-#  define TIMER_STATUS_TRUN5  0x20000000
-#  define TIMER_STATUS_TRUN6  0x40000000
-#  define TIMER_STATUS_TRUN7  0x80000000
-#  define TIMER_STATUS_TRUN   0xF000F000
-#  if (MAX_BLACKFIN_GPTIMERS > 8)
-#    define TIMER_STATUS_TRUN8  0x1000
-#    define TIMER_STATUS_TRUN9  0x2000
-#    define TIMER_STATUS_TRUN10 0x4000
-#    define TIMER_STATUS_TRUN11 0x8000
-#  endif
-#else
-#  define TIMER_STATUS_TRUN   0x7000
-#endif
-
-/*******************************************************************************
-*	GP_TIMER API's
-*******************************************************************************/
-
-void  set_gptimer_pwidth    (int timer_id, int width);
-int   get_gptimer_pwidth    (int timer_id);
-void  set_gptimer_period    (int timer_id, int period);
-int   get_gptimer_period    (int timer_id);
-int   get_gptimer_count     (int timer_id);
-short get_gptimer_intr      (int timer_id);
-void  set_gptimer_config    (int timer_id, short config);
-short get_gptimer_config    (int timer_id);
-void  set_gptimer_pulse_hi  (int timer_id);
-void  clear_gptimer_pulse_hi(int timer_id);
-void  enable_gptimers       (short mask);
-void  disable_gptimers      (short mask);
-short get_enabled_timers    (void);
-int   get_gptimer_status    (int octet);
-void  set_gptimer_status    (int octet, int value);
-
-#endif
diff --git a/include/asm-blackfin/bfin-global.h b/include/asm-blackfin/bfin-global.h
index a970781..14cb8d3 100644
--- a/include/asm-blackfin/bfin-global.h
+++ b/include/asm-blackfin/bfin-global.h
@@ -47,6 +47,8 @@
 
 extern unsigned long get_cclk(void);
 extern unsigned long get_sclk(void);
+extern unsigned long sclk_to_usecs(unsigned long sclk);
+extern unsigned long usecs_to_sclk(unsigned long usecs);
 
 extern void dump_thread(struct pt_regs *regs, struct user *dump);
 extern void dump_bfin_regs(struct pt_regs *fp, void *retaddr);
@@ -105,7 +107,7 @@
 extern void led_toggle_num(int);
 extern void init_leds(void);
 
-extern char *bfin_board_name __attribute__ ((weak));
+extern const char bfin_board_name[];
 extern unsigned long wall_jiffies;
 extern unsigned long ipdt_table[];
 extern unsigned long dpdt_table[];
diff --git a/include/asm-blackfin/bitops.h b/include/asm-blackfin/bitops.h
index 27c2d0e..b39a175 100644
--- a/include/asm-blackfin/bitops.h
+++ b/include/asm-blackfin/bitops.h
@@ -11,6 +11,10 @@
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/__ffs.h>
 #include <asm-generic/bitops/sched.h>
@@ -199,6 +203,7 @@
 
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #include <asm-generic/bitops/ext2-atomic.h>
 #include <asm-generic/bitops/ext2-non-atomic.h>
diff --git a/include/asm-blackfin/dma.h b/include/asm-blackfin/dma.h
index b42a531e..b469505 100644
--- a/include/asm-blackfin/dma.h
+++ b/include/asm-blackfin/dma.h
@@ -109,9 +109,7 @@
 
 	unsigned long curr_desc_ptr;	/* DMA Current Descriptor Pointer
 					   register */
-	unsigned short curr_addr_ptr_lo;	/* DMA Current Address Pointer
-						   register */
-	unsigned short curr_addr_ptr_hi;	/* DMA Current Address Pointer
+	unsigned long curr_addr_ptr;	/* DMA Current Address Pointer
 						   register */
 	unsigned short irq_status;	/* DMA irq status register */
 	unsigned short dummy6;
@@ -166,6 +164,9 @@
 unsigned short get_dma_curr_irqstat(unsigned int channel);
 unsigned short get_dma_curr_xcount(unsigned int channel);
 unsigned short get_dma_curr_ycount(unsigned int channel);
+unsigned long get_dma_next_desc_ptr(unsigned int channel);
+unsigned long get_dma_curr_desc_ptr(unsigned int channel);
+unsigned long get_dma_curr_addr(unsigned int channel);
 
 /* set large DMA mode descriptor */
 void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg);
diff --git a/include/asm-blackfin/gpio.h b/include/asm-blackfin/gpio.h
index dd203cd..33ce98e 100644
--- a/include/asm-blackfin/gpio.h
+++ b/include/asm-blackfin/gpio.h
@@ -29,6 +29,7 @@
 
 /*
 *  Number     BF537/6/4    BF561    BF533/2/1
+*             BF527/5/2
 *
 *  GPIO_0       PF0         PF0        PF0
 *  GPIO_1       PF1         PF1        PF1
@@ -164,7 +165,7 @@
 
 #endif
 
-#ifdef BF537_FAMILY
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
 #define MAX_BLACKFIN_GPIOS 48
 
 #define	GPIO_PF0	0
diff --git a/include/asm-blackfin/gptimers.h b/include/asm-blackfin/gptimers.h
new file mode 100644
index 0000000..c97ab03
--- /dev/null
+++ b/include/asm-blackfin/gptimers.h
@@ -0,0 +1,210 @@
+/*
+ * include/asm/bf5xx_timers.h
+ *
+ * This file contains the major Data structures and constants
+ * used for General Purpose Timer Implementation in BF5xx
+ *
+ * Copyright (C) 2005 John DeHority
+ * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
+ *
+ */
+
+#ifndef _BLACKFIN_TIMERS_H_
+#define _BLACKFIN_TIMERS_H_
+
+#include <linux/types.h>
+#include <asm/blackfin.h>
+
+/*
+ * BF537/BF527: 8 timers:
+ */
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
+# define MAX_BLACKFIN_GPTIMERS 8
+# define TIMER0_GROUP_REG      TIMER_ENABLE
+#endif
+/*
+ * BF561: 12 timers:
+ */
+#if defined(CONFIG_BF561)
+# define MAX_BLACKFIN_GPTIMERS 12
+# define TIMER0_GROUP_REG      TMRS8_ENABLE
+# define TIMER8_GROUP_REG      TMRS4_ENABLE
+#endif
+/*
+ * All others: 3 timers:
+ */
+#if !defined(MAX_BLACKFIN_GPTIMERS)
+# define MAX_BLACKFIN_GPTIMERS 3
+# define TIMER0_GROUP_REG      TIMER_ENABLE
+#endif
+
+#define BLACKFIN_GPTIMER_IDMASK ((1UL << MAX_BLACKFIN_GPTIMERS) - 1)
+#define BFIN_TIMER_OCTET(x) ((x) >> 3)
+
+/* used in masks for timer_enable() and timer_disable() */
+#define TIMER0bit  0x0001  /*  0001b */
+#define TIMER1bit  0x0002  /*  0010b */
+#define TIMER2bit  0x0004  /*  0100b */
+
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER3bit  0x0008
+# define TIMER4bit  0x0010
+# define TIMER5bit  0x0020
+# define TIMER6bit  0x0040
+# define TIMER7bit  0x0080
+#endif
+
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER8bit  0x0100
+# define TIMER9bit  0x0200
+# define TIMER10bit 0x0400
+# define TIMER11bit 0x0800
+#endif
+
+#define TIMER0_id   0
+#define TIMER1_id   1
+#define TIMER2_id   2
+
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER3_id   3
+# define TIMER4_id   4
+# define TIMER5_id   5
+# define TIMER6_id   6
+# define TIMER7_id   7
+#endif
+
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER8_id   8
+# define TIMER9_id   9
+# define TIMER10_id 10
+# define TIMER11_id 11
+#endif
+
+/* associated timers for ppi framesync: */
+
+#if defined(CONFIG_BF561)
+# define FS0_1_TIMER_ID   TIMER8_id
+# define FS0_2_TIMER_ID   TIMER9_id
+# define FS1_1_TIMER_ID   TIMER10_id
+# define FS1_2_TIMER_ID   TIMER11_id
+# define FS0_1_TIMER_BIT  TIMER8bit
+# define FS0_2_TIMER_BIT  TIMER9bit
+# define FS1_1_TIMER_BIT  TIMER10bit
+# define FS1_2_TIMER_BIT  TIMER11bit
+# undef FS1_TIMER_ID
+# undef FS2_TIMER_ID
+# undef FS1_TIMER_BIT
+# undef FS2_TIMER_BIT
+#else
+# define FS1_TIMER_ID  TIMER0_id
+# define FS2_TIMER_ID  TIMER1_id
+# define FS1_TIMER_BIT TIMER0bit
+# define FS2_TIMER_BIT TIMER1bit
+#endif
+
+/*
+ * Timer Configuration Register Bits
+ */
+#define TIMER_ERR           0xC000
+#define TIMER_ERR_OVFL      0x4000
+#define TIMER_ERR_PROG_PER  0x8000
+#define TIMER_ERR_PROG_PW   0xC000
+#define TIMER_EMU_RUN       0x0200
+#define	TIMER_TOGGLE_HI     0x0100
+#define	TIMER_CLK_SEL       0x0080
+#define TIMER_OUT_DIS       0x0040
+#define TIMER_TIN_SEL       0x0020
+#define TIMER_IRQ_ENA       0x0010
+#define TIMER_PERIOD_CNT    0x0008
+#define TIMER_PULSE_HI      0x0004
+#define TIMER_MODE          0x0003
+#define TIMER_MODE_PWM      0x0001
+#define TIMER_MODE_WDTH     0x0002
+#define TIMER_MODE_EXT_CLK  0x0003
+
+/*
+ * Timer Status Register Bits
+ */
+#define TIMER_STATUS_TIMIL0 0x0001
+#define TIMER_STATUS_TIMIL1 0x0002
+#define TIMER_STATUS_TIMIL2 0x0004
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER_STATUS_TIMIL3 0x00000008
+# define TIMER_STATUS_TIMIL4 0x00010000
+# define TIMER_STATUS_TIMIL5 0x00020000
+# define TIMER_STATUS_TIMIL6 0x00040000
+# define TIMER_STATUS_TIMIL7 0x00080000
+# if (MAX_BLACKFIN_GPTIMERS > 8)
+#  define TIMER_STATUS_TIMIL8  0x0001
+#  define TIMER_STATUS_TIMIL9  0x0002
+#  define TIMER_STATUS_TIMIL10 0x0004
+#  define TIMER_STATUS_TIMIL11 0x0008
+# endif
+# define TIMER_STATUS_INTR   0x000F000F
+#else
+# define TIMER_STATUS_INTR   0x0007	/* any timer interrupt */
+#endif
+
+#define TIMER_STATUS_TOVF0  0x0010	/* timer 0 overflow error */
+#define TIMER_STATUS_TOVF1  0x0020
+#define TIMER_STATUS_TOVF2  0x0040
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER_STATUS_TOVF3  0x00000080
+# define TIMER_STATUS_TOVF4  0x00100000
+# define TIMER_STATUS_TOVF5  0x00200000
+# define TIMER_STATUS_TOVF6  0x00400000
+# define TIMER_STATUS_TOVF7  0x00800000
+# if (MAX_BLACKFIN_GPTIMERS > 8)
+#  define TIMER_STATUS_TOVF8   0x0010
+#  define TIMER_STATUS_TOVF9   0x0020
+#  define TIMER_STATUS_TOVF10  0x0040
+#  define TIMER_STATUS_TOVF11  0x0080
+# endif
+# define TIMER_STATUS_OFLOW  0x00F000F0
+#else
+# define TIMER_STATUS_OFLOW  0x0070	/* any timer overflow */
+#endif
+
+/*
+ * Timer Slave Enable Status : write 1 to clear
+ */
+#define TIMER_STATUS_TRUN0  0x1000
+#define TIMER_STATUS_TRUN1  0x2000
+#define TIMER_STATUS_TRUN2  0x4000
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER_STATUS_TRUN3  0x00008000
+# define TIMER_STATUS_TRUN4  0x10000000
+# define TIMER_STATUS_TRUN5  0x20000000
+# define TIMER_STATUS_TRUN6  0x40000000
+# define TIMER_STATUS_TRUN7  0x80000000
+# define TIMER_STATUS_TRUN   0xF000F000
+# if (MAX_BLACKFIN_GPTIMERS > 8)
+#  define TIMER_STATUS_TRUN8  0x1000
+#  define TIMER_STATUS_TRUN9  0x2000
+#  define TIMER_STATUS_TRUN10 0x4000
+#  define TIMER_STATUS_TRUN11 0x8000
+# endif
+#else
+# define TIMER_STATUS_TRUN   0x7000
+#endif
+
+/* The actual gptimer API */
+
+void     set_gptimer_pwidth    (int timer_id, uint32_t width);
+uint32_t get_gptimer_pwidth    (int timer_id);
+void     set_gptimer_period    (int timer_id, uint32_t period);
+uint32_t get_gptimer_period    (int timer_id);
+uint32_t get_gptimer_count     (int timer_id);
+uint16_t get_gptimer_intr      (int timer_id);
+void     clear_gptimer_intr    (int timer_id);
+void     set_gptimer_config    (int timer_id, uint16_t config);
+uint16_t get_gptimer_config    (int timer_id);
+void     set_gptimer_pulse_hi  (int timer_id);
+void     clear_gptimer_pulse_hi(int timer_id);
+void     enable_gptimers       (uint16_t mask);
+void     disable_gptimers      (uint16_t mask);
+uint16_t get_enabled_gptimers  (void);
+uint32_t get_gptimer_status    (int group);
+void     set_gptimer_status    (int group, uint32_t value);
+
+#endif
diff --git a/include/asm-blackfin/ide.h b/include/asm-blackfin/ide.h
index 41b2db4..121e272 100644
--- a/include/asm-blackfin/ide.h
+++ b/include/asm-blackfin/ide.h
@@ -20,7 +20,6 @@
 #define MAX_HWIFS	1
 
 /* Legacy ... BLK_DEV_IDECS */
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)	((base) + 0x206) /* obsolete */
 
 
diff --git a/include/asm-blackfin/mach-bf527/anomaly.h b/include/asm-blackfin/mach-bf527/anomaly.h
index 991db98..a891204 100644
--- a/include/asm-blackfin/mach-bf527/anomaly.h
+++ b/include/asm-blackfin/mach-bf527/anomaly.h
@@ -38,4 +38,12 @@
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000323 (0)
+#define ANOMALY_05000244 (0)
+#define ANOMALY_05000198 (0)
+#define ANOMALY_05000125 (0)
+#define ANOMALY_05000158 (0)
+#define ANOMALY_05000273 (0)
+#define ANOMALY_05000263 (0)
+#define ANOMALY_05000311 (0)
+#define ANOMALY_05000230 (0)
 #endif
diff --git a/include/asm-blackfin/mach-bf527/bf527.h b/include/asm-blackfin/mach-bf527/bf527.h
new file mode 100644
index 0000000..056eb4b
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/bf527.h
@@ -0,0 +1,127 @@
+/*
+ * File:         include/asm-blackfin/mach-bf527/bf527.h
+ * Based on:	include/asm-blackfin/mach-bf537/bf537.h
+ * Author:	Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * Created:
+ * Description:  SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF527
+ *
+ * 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_BF527_H__
+#define __MACH_BF527_H__
+
+#define SUPPORTED_REVID 2
+
+#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 BFIN_DSUBBANKS	4
+#define BFIN_DWAYS		2
+#define BFIN_DLINES		64
+#define BFIN_ISUBBANKS	4
+#define BFIN_IWAYS		4
+#define BFIN_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
+#ifdef CONFIG_C_CDPRIO
+#define V_CDPRIO 0x100
+#else
+#define V_CDPRIO 0x0
+#endif
+
+#define AMGCTLVAL	(V_AMBEN | V_AMCKEN | V_CDPRIO)
+
+#ifdef CONFIG_BF527
+#define CPU "BF527"
+#endif
+#ifdef CONFIG_BF525
+#define CPU "BF525"
+#endif
+#ifdef CONFIG_BF522
+#define CPU "BF522"
+#endif
+#ifndef CPU
+#define	CPU "UNKNOWN"
+#define CPUID 0x0
+#endif
+
+#endif				/* __MACH_BF527_H__  */
diff --git a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
new file mode 100644
index 0000000..0b867e6
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
@@ -0,0 +1,152 @@
+#include <linux/serial.h>
+#include <asm/dma.h>
+#include <asm/portmux.h>
+
+#define NR_PORTS		2
+
+#define OFFSET_THR              0x00	/* Transmit Holding register            */
+#define OFFSET_RBR              0x00	/* Receive Buffer register              */
+#define OFFSET_DLL              0x00	/* Divisor Latch (Low-Byte)             */
+#define OFFSET_IER              0x04	/* Interrupt Enable Register            */
+#define OFFSET_DLH              0x04	/* Divisor Latch (High-Byte)            */
+#define OFFSET_IIR              0x08	/* Interrupt Identification 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_GCTL             0x24	/* Global Control 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_IER(uart)      bfin_read16(((uart)->port.membase + OFFSET_IER))
+#define UART_GET_DLH(uart)	bfin_read16(((uart)->port.membase + OFFSET_DLH))
+#define UART_GET_IIR(uart)      bfin_read16(((uart)->port.membase + OFFSET_IIR))
+#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_PUT_IER(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_IER), v)
+#define UART_PUT_DLH(uart, v)    bfin_write16(((uart)->port.membase + OFFSET_DLH), 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
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+	 CONFIG_UART1_CTS_PIN,
+	 CONFIG_UART1_RTS_PIN,
+#endif
+	 },
+#endif
+};
+
+int nr_ports = ARRAY_SIZE(bfin_serial_resource);
+
+#define DRIVER_NAME "bfin-uart"
+
+static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+{
+
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	peripheral_request(P_UART0_TX, DRIVER_NAME);
+	peripheral_request(P_UART0_RX, DRIVER_NAME);
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	peripheral_request(P_UART1_TX, DRIVER_NAME);
+	peripheral_request(P_UART1_RX, DRIVER_NAME);
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+	if (uart->cts_pin >= 0) {
+		gpio_request(uart->cts_pin, DRIVER_NAME);
+		gpio_direction_input(uart->cts_pin);
+	}
+
+	if (uart->rts_pin >= 0) {
+		gpio_request(uart->rts_pin, DRIVER_NAME);
+		gpio_direction_output(uart->rts_pin);
+	}
+#endif
+}
diff --git a/include/asm-blackfin/mach-bf527/blackfin.h b/include/asm-blackfin/mach-bf527/blackfin.h
new file mode 100644
index 0000000..1bd07e3
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/blackfin.h
@@ -0,0 +1,78 @@
+/*
+ * File:         include/asm-blackfin/mach-bf527/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 BF527_FAMILY
+
+#include "bf527.h"
+#include "mem_map.h"
+#include "defBF522.h"
+#include "anomaly.h"
+
+#if defined(CONFIG_BF527)
+#include "defBF527.h"
+#endif
+
+#if defined(CONFIG_BF525)
+#include "defBF525.h"
+#endif
+
+#if !defined(__ASSEMBLY__)
+#include "cdefBF522.h"
+
+#if defined(CONFIG_BF527)
+#include "cdefBF527.h"
+#endif
+
+#if defined(CONFIG_BF525)
+#include "cdefBF525.h"
+#endif
+#endif
+
+/* UART_IIR Register */
+#define STATUS(x)	((x << 1) & 0x06)
+#define STATUS_P1	0x02
+#define STATUS_P0	0x01
+
+/* DPMC*/
+#define bfin_read_STOPCK_OFF() bfin_read_STOPCK()
+#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
+#define STOPCK_OFF STOPCK
+
+/* 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-bf527/cdefBF52x_base.h b/include/asm-blackfin/mach-bf527/cdefBF52x_base.h
index 5f801a0..3f4de5d 100644
--- a/include/asm-blackfin/mach-bf527/cdefBF52x_base.h
+++ b/include/asm-blackfin/mach-bf527/cdefBF52x_base.h
@@ -45,8 +45,8 @@
 #define bfin_write_PLL_STAT(val)		bfin_write16(PLL_STAT, val)
 #define bfin_read_PLL_LOCKCNT()			bfin_read16(PLL_LOCKCNT)
 #define bfin_write_PLL_LOCKCNT(val)		bfin_write16(PLL_LOCKCNT, val)
-#define bfin_read_CHIPID()			bfin_read16(CHIPID)
-#define bfin_write_CHIPID(val)			bfin_write16(CHIPID, val)
+#define bfin_read_CHIPID()			bfin_read32(CHIPID)
+#define bfin_write_CHIPID(val)			bfin_write32(CHIPID, val)
 
 
 /* System Interrupt Controller (0xFFC00100 - 0xFFC001FF)							*/
@@ -59,9 +59,8 @@
 #define bfin_write_SIC_RVECT(val)		bfin_write32(SIC_RVECT, val)
 #define bfin_read_SIC_IMASK0()			bfin_read32(SIC_IMASK0)
 #define bfin_write_SIC_IMASK0(val)		bfin_write32(SIC_IMASK0, val)
-/* legacy register name (below) provided for backwards code compatibility */
-#define bfin_read_SIC_IMASK()			bfin_read32(SIC_IMASK)
-#define bfin_write_SIC_IMASK(val)		bfin_write32(SIC_IMASK, val)
+#define bfin_read_SIC_IMASK(x)			bfin_read32(SIC_IMASK0 + (x << 6))
+#define bfin_write_SIC_IMASK(x, val)		bfin_write32((SIC_IMASK0 + (x << 6)), val)
 
 #define bfin_read_SIC_IAR0()			bfin_read32(SIC_IAR0)
 #define bfin_write_SIC_IAR0(val)		bfin_write32(SIC_IAR0, val)
@@ -74,15 +73,13 @@
 
 #define bfin_read_SIC_ISR0()			bfin_read32(SIC_ISR0)
 #define bfin_write_SIC_ISR0(val)		bfin_write32(SIC_ISR0, val)
-/* legacy register name (below) provided for backwards code compatibility */
-#define bfin_read_SIC_ISR()			bfin_read32(SIC_ISR)
-#define bfin_write_SIC_ISR(val)			bfin_write32(SIC_ISR, val)
+#define bfin_read_SIC_ISR(x)			bfin_read32(SIC_ISR0 + (x << 6))
+#define bfin_write_SIC_ISR(x, val)		bfin_write32((SIC_ISR0 + (x << 6)), val)
 
 #define bfin_read_SIC_IWR0()			bfin_read32(SIC_IWR0)
 #define bfin_write_SIC_IWR0(val)		bfin_write32(SIC_IWR0, val)
-/* legacy register name (below) provided for backwards code compatibility */
-#define bfin_read_SIC_IWR()			bfin_read32(SIC_IWR)
-#define bfin_write_SIC_IWR(val)			bfin_write32(SIC_IWR, val)
+#define bfin_read_SIC_IWR(x)			bfin_read32(SIC_IWR0 + (x << 6))
+#define bfin_write_SIC_IWR(x, val)		bfin_write32((SIC_IWR0 + (x << 6)), val)
 
 /* SIC Additions to ADSP-BF52x (0xFFC0014C - 0xFFC00162) */
 
diff --git a/include/asm-blackfin/mach-bf527/defBF527.h b/include/asm-blackfin/mach-bf527/defBF527.h
index 2be3293..82134f5 100644
--- a/include/asm-blackfin/mach-bf527/defBF527.h
+++ b/include/asm-blackfin/mach-bf527/defBF527.h
@@ -32,12 +32,12 @@
 #define _DEF_BF527_H
 
 /* Include all Core registers and bit definitions */
-#include <def_LPBlackfin.h>
+#include <asm/mach-common/def_LPBlackfin.h>
 
 /* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF527 */
 
 /* Include defBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */
-#include <defBF52x_base.h>
+#include "defBF52x_base.h"
 
 /* The following are the #defines needed by ADSP-BF527 that are not in the common header */
 /* 10/100 Ethernet Controller	(0xFFC03000 - 0xFFC031FF) */
diff --git a/include/asm-blackfin/mach-bf527/defBF52x_base.h b/include/asm-blackfin/mach-bf527/defBF52x_base.h
index b1ff67db..d6c24c54 100644
--- a/include/asm-blackfin/mach-bf527/defBF52x_base.h
+++ b/include/asm-blackfin/mach-bf527/defBF52x_base.h
@@ -52,13 +52,13 @@
 #define SYSCR				0xFFC00104	/* System Configuration Register			*/
 #define SIC_RVECT			0xFFC00108	/* Interrupt Reset Vector Address Register	*/
 
-#define SIC_IMASK			0xFFC0010C	/* Interrupt Mask Register					*/
+#define SIC_IMASK0			0xFFC0010C	/* Interrupt Mask Register					*/
 #define SIC_IAR0			0xFFC00110	/* Interrupt Assignment Register 0			*/
 #define SIC_IAR1			0xFFC00114	/* Interrupt Assignment Register 1			*/
 #define SIC_IAR2			0xFFC00118	/* Interrupt Assignment Register 2			*/
 #define SIC_IAR3			0xFFC0011C	/* Interrupt Assignment Register 3			*/
-#define SIC_ISR				0xFFC00120	/* Interrupt Status Register				*/
-#define SIC_IWR				0xFFC00124	/* Interrupt Wakeup Register				*/
+#define SIC_ISR0				0xFFC00120	/* Interrupt Status Register				*/
+#define SIC_IWR0				0xFFC00124	/* Interrupt Wakeup Register				*/
 
 /* SIC Additions to ADSP-BF52x (0xFFC0014C - 0xFFC00162) */
 #define SIC_IMASK1                      0xFFC0014C     /* Interrupt Mask register of SIC2 */
@@ -691,6 +691,8 @@
 
 /* *************  SYSTEM INTERRUPT CONTROLLER MASKS *************************************/
 /* Peripheral Masks For SIC_ISR, SIC_IWR, SIC_IMASK										*/
+
+#if 0
 #define IRQ_PLL_WAKEUP	0x00000001	/* PLL Wakeup Interrupt			 					*/
 
 #define IRQ_ERROR1      0x00000002  /* Error Interrupt (DMA, DMARx Block, DMARx Overflow) */
@@ -732,6 +734,7 @@
 #define IRQ_DMA15		0x40000000	/* DMA Channels 15 (MDMA0 Destination) TX Interrupt */
 #define IRQ_WDOG		0x80000000	/* Software Watchdog Timer Interrupt 				*/
 #define IRQ_PFB_PORTG	0x10000000	/* PF Port G (PF31:16) Interrupt B 					*/
+#endif
 
 /* SIC_IAR0 Macros															*/
 #define P0_IVG(x)		(((x)&0xF)-7)			/* Peripheral #0 assigned IVG #x 	*/
diff --git a/include/asm-blackfin/mach-bf527/dma.h b/include/asm-blackfin/mach-bf527/dma.h
new file mode 100644
index 0000000..a41627a
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/dma.h
@@ -0,0 +1,60 @@
+/*
+ * file:        include/asm-blackfin/mach-bf527/dma.h
+ * based on:	include/asm-blackfin/mach-bf537/dma.h
+ * author:	Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * created:
+ * description:
+ *	system DMA 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 MAX_BLACKFIN_DMA_CHANNEL 16
+
+#define CH_PPI 			0	/* PPI receive/transmit or NFC */
+#define CH_NFC			0	/* PPI receive/transmit or NFC */
+#define CH_EMAC_RX 		1	/* Ethernet MAC receive or HOSTDP */
+#define CH_EMAC_HOSTDP 		1	/* Ethernet MAC receive or HOSTDP */
+#define CH_EMAC_TX 		2	/* Ethernet MAC transmit or NFC */
+#define CH_SPORT0_RX 		3	/* SPORT0 receive */
+#define CH_SPORT0_TX 		4	/* SPORT0 transmit */
+#define CH_SPORT1_RX 		5	/* SPORT1 receive */
+#define CH_SPORT1_TX 		6	/* SPORT1 transmit */
+#define CH_SPI 			7	/* SPI transmit/receive */
+#define CH_UART0_RX 		8	/* UART0 receive */
+#define CH_UART0_TX 		9	/* UART0 transmit */
+#define CH_UART1_RX 		10	/* UART1 receive */
+#define CH_UART1_TX 		11	/* UART1 transmit */
+
+#define CH_MEM_STREAM0_DEST	12	/* TX */
+#define CH_MEM_STREAM0_SRC  	13	/* RX */
+#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-bf527/irq.h b/include/asm-blackfin/mach-bf527/irq.h
new file mode 100644
index 0000000..304f5bc
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/irq.h
@@ -0,0 +1,263 @@
+/*
+ * file:	include/asm-blackfin/mach-bf527/irq.h
+ * based on:	include/asm-blackfin/mach-bf537/irq.h
+ * author:	Michael Hennerich (michael.hennerich@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 _BF527_IRQ_H_
+#define _BF527_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    (2 * 32)
+
+/* 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_DMA0_ERROR		BFIN_IRQ(1)	/* DMA Error 0 (generic) */
+#define IRQ_DMAR0_BLK		BFIN_IRQ(2)	/* DMAR0 Block Interrupt */
+#define IRQ_DMAR1_BLK		BFIN_IRQ(3)	/* DMAR1 Block Interrupt */
+#define IRQ_DMAR0_OVR		BFIN_IRQ(4)	/* DMAR0 Overflow Error */
+#define IRQ_DMAR1_OVR		BFIN_IRQ(5)	/* DMAR1 Overflow Error */
+#define IRQ_PPI_ERROR		BFIN_IRQ(6)	/* PPI Error */
+#define IRQ_MAC_ERROR		BFIN_IRQ(7)	/* MAC Status */
+#define IRQ_SPORT0_ERROR	BFIN_IRQ(8)	/* SPORT0 Status */
+#define IRQ_SPORT1_ERROR	BFIN_IRQ(9)	/* SPORT1 Status */
+#define IRQ_UART0_ERROR		BFIN_IRQ(12)	/* UART0 Status */
+#define IRQ_UART1_ERROR		BFIN_IRQ(13)	/* UART1 Status */
+#define IRQ_RTC			BFIN_IRQ(14)	/* RTC */
+#define IRQ_PPI      		BFIN_IRQ(15)	/* DMA Channel 0 (PPI/NAND) */
+#define IRQ_SPORT0_RX		BFIN_IRQ(16)	/* DMA 3 Channel (SPORT0 RX) */
+#define IRQ_SPORT0_TX		BFIN_IRQ(17)	/* DMA 4 Channel (SPORT0 TX) */
+#define IRQ_SPORT1_RX		BFIN_IRQ(18)	/* DMA 5 Channel (SPORT1 RX) */
+#define IRQ_SPORT1_TX		BFIN_IRQ(19)	/* DMA 6 Channel (SPORT1 TX) */
+#define IRQ_TWI      		BFIN_IRQ(20)	/* TWI */
+#define IRQ_SPI      		BFIN_IRQ(21)	/* DMA 7 Channel (SPI) */
+#define IRQ_UART0_RX 		BFIN_IRQ(22)	/* DMA8 Channel (UART0 RX) */
+#define IRQ_UART0_TX 		BFIN_IRQ(23)	/* DMA9 Channel (UART0 TX) */
+#define IRQ_UART1_RX 		BFIN_IRQ(24)	/* DMA10 Channel (UART1 RX) */
+#define IRQ_UART1_TX 		BFIN_IRQ(25)	/* DMA11 Channel (UART1 TX) */
+#define IRQ_OPTSEC   		BFIN_IRQ(26)	/* OTPSEC Interrupt */
+#define IRQ_CNT   		BFIN_IRQ(27)	/* GP Counter */
+#define IRQ_MAC_RX   		BFIN_IRQ(28)	/* DMA1 Channel (MAC RX/HDMA) */
+#define IRQ_PORTH_INTA   	BFIN_IRQ(29)	/* Port H Interrupt A */
+#define IRQ_MAC_TX		BFIN_IRQ(30)	/* DMA2 Channel (MAC TX/NAND) */
+#define IRQ_NFC			BFIN_IRQ(30)	/* DMA2 Channel (MAC TX/NAND) */
+#define IRQ_PORTH_INTB		BFIN_IRQ(31)	/* Port H Interrupt B */
+#define IRQ_TMR0		BFIN_IRQ(32)	/* Timer 0 */
+#define IRQ_TMR1		BFIN_IRQ(33)	/* Timer 1 */
+#define IRQ_TMR2		BFIN_IRQ(34)	/* Timer 2 */
+#define IRQ_TMR3		BFIN_IRQ(35)	/* Timer 3 */
+#define IRQ_TMR4		BFIN_IRQ(36)	/* Timer 4 */
+#define IRQ_TMR5		BFIN_IRQ(37)	/* Timer 5 */
+#define IRQ_TMR6		BFIN_IRQ(38)	/* Timer 6 */
+#define IRQ_TMR7		BFIN_IRQ(39)	/* Timer 7 */
+#define IRQ_PORTG_INTA		BFIN_IRQ(40)	/* Port G Interrupt A */
+#define IRQ_PORTG_INTB		BFIN_IRQ(41)	/* Port G Interrupt B */
+#define IRQ_MEM_DMA0		BFIN_IRQ(42)	/* MDMA Stream 0 */
+#define IRQ_MEM_DMA1		BFIN_IRQ(43)	/* MDMA Stream 1 */
+#define IRQ_WATCH		BFIN_IRQ(44)	/* Software Watchdog Timer */
+#define IRQ_PORTF_INTA		BFIN_IRQ(45)	/* Port F Interrupt A */
+#define IRQ_PORTF_INTB		BFIN_IRQ(46)	/* Port F Interrupt B */
+#define IRQ_SPI_ERROR		BFIN_IRQ(47)	/* SPI Status */
+#define IRQ_NFC_ERROR		BFIN_IRQ(48)	/* NAND Error */
+#define IRQ_HDMA_ERROR		BFIN_IRQ(49)	/* HDMA Error */
+#define IRQ_HDMA		BFIN_IRQ(50)	/* HDMA (TFI) */
+#define IRQ_USB_EINT		BFIN_IRQ(51)	/* USB_EINT Interrupt */
+#define IRQ_USB_INT0		BFIN_IRQ(52)	/* USB_INT0 Interrupt */
+#define IRQ_USB_INT1		BFIN_IRQ(53)	/* USB_INT1 Interrupt */
+#define IRQ_USB_INT2		BFIN_IRQ(54)	/* USB_INT2 Interrupt */
+#define IRQ_USB_DMA		BFIN_IRQ(55)	/* USB_DMAINT Interrupt */
+
+#define SYS_IRQS        	BFIN_IRQ(63)	/* 70 */
+
+#define IRQ_PF0         71
+#define IRQ_PF1         72
+#define IRQ_PF2         73
+#define IRQ_PF3         74
+#define IRQ_PF4         75
+#define IRQ_PF5         76
+#define IRQ_PF6         77
+#define IRQ_PF7         78
+#define IRQ_PF8         79
+#define IRQ_PF9         80
+#define IRQ_PF10        81
+#define IRQ_PF11        82
+#define IRQ_PF12        83
+#define IRQ_PF13        84
+#define IRQ_PF14        85
+#define IRQ_PF15        86
+
+#define IRQ_PG0         87
+#define IRQ_PG1         88
+#define IRQ_PG2         89
+#define IRQ_PG3         90
+#define IRQ_PG4         91
+#define IRQ_PG5         92
+#define IRQ_PG6         93
+#define IRQ_PG7         94
+#define IRQ_PG8         95
+#define IRQ_PG9         96
+#define IRQ_PG10        97
+#define IRQ_PG11        98
+#define IRQ_PG12        99
+#define IRQ_PG13        100
+#define IRQ_PG14        101
+#define IRQ_PG15        102
+
+#define IRQ_PH0         103
+#define IRQ_PH1         104
+#define IRQ_PH2         105
+#define IRQ_PH3         106
+#define IRQ_PH4         107
+#define IRQ_PH5         108
+#define IRQ_PH6         109
+#define IRQ_PH7         110
+#define IRQ_PH8         111
+#define IRQ_PH9         112
+#define IRQ_PH10        113
+#define IRQ_PH11        114
+#define IRQ_PH12        115
+#define IRQ_PH13        116
+#define IRQ_PH14        117
+#define IRQ_PH15        118
+
+#define GPIO_IRQ_BASE	IRQ_PF0
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+#define NR_IRQS     (IRQ_PH15+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_DMA0_ERROR_POS	4
+#define IRQ_DMAR0_BLK_POS 	8
+#define IRQ_DMAR1_BLK_POS 	12
+#define IRQ_DMAR0_OVR_POS 	16
+#define IRQ_DMAR1_OVR_POS 	20
+#define IRQ_PPI_ERROR_POS 	24
+#define IRQ_MAC_ERROR_POS 	28
+
+/* IAR1 BIT FIELDS */
+#define IRQ_SPORT0_ERROR_POS	0
+#define IRQ_SPORT1_ERROR_POS	4
+#define IRQ_UART0_ERROR_POS 	16
+#define IRQ_UART1_ERROR_POS 	20
+#define IRQ_RTC_POS         	24
+#define IRQ_PPI_POS         	28
+
+/* IAR2 BIT FIELDS */
+#define IRQ_SPORT0_RX_POS	0
+#define IRQ_SPORT0_TX_POS	4
+#define IRQ_SPORT1_RX_POS	8
+#define IRQ_SPORT1_TX_POS	12
+#define IRQ_TWI_POS      	16
+#define IRQ_SPI_POS      	20
+#define IRQ_UART0_RX_POS 	24
+#define IRQ_UART0_TX_POS 	28
+
+/* IAR3 BIT FIELDS */
+#define IRQ_UART1_RX_POS  	0
+#define IRQ_UART1_TX_POS  	4
+#define IRQ_OPTSEC_POS    	8
+#define IRQ_CNT_POS       	12
+#define IRQ_MAC_RX_POS    	16
+#define IRQ_PORTH_INTA_POS	20
+#define IRQ_MAC_TX_POS    	24
+#define IRQ_PORTH_INTB_POS	28
+
+/* IAR4 BIT FIELDS */
+#define IRQ_TMR0_POS		0
+#define IRQ_TMR1_POS		4
+#define IRQ_TMR2_POS		8
+#define IRQ_TMR3_POS		12
+#define IRQ_TMR4_POS		16
+#define IRQ_TMR5_POS		20
+#define IRQ_TMR6_POS		24
+#define IRQ_TMR7_POS		28
+
+/* IAR5 BIT FIELDS */
+#define IRQ_PORTG_INTA_POS	0
+#define IRQ_PORTG_INTB_POS	4
+#define IRQ_MEM_DMA0_POS  	8
+#define IRQ_MEM_DMA1_POS  	12
+#define IRQ_WATCH_POS     	16
+#define IRQ_PORTF_INTA_POS	20
+#define IRQ_PORTF_INTB_POS	24
+#define IRQ_SPI_ERROR_POS 	28
+
+/* IAR6 BIT FIELDS */
+#define IRQ_NFC_ERROR_POS  	0
+#define IRQ_HDMA_ERROR_POS 	4
+#define IRQ_HDMA_POS       	8
+#define IRQ_USB_EINT_POS   	12
+#define IRQ_USB_INT0_POS   	16
+#define IRQ_USB_INT1_POS   	20
+#define IRQ_USB_INT2_POS   	24
+#define IRQ_USB_DMA_POS    	28
+
+#endif				/* _BF527_IRQ_H_ */
diff --git a/include/asm-blackfin/mach-bf527/mem_init.h b/include/asm-blackfin/mach-bf527/mem_init.h
new file mode 100644
index 0000000..008ca66
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/mem_init.h
@@ -0,0 +1,337 @@
+/*
+ * File:         include/asm-blackfin/mach-bf527/mem_init.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * 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, 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_MT48LC16M16A2TG_75 || CONFIG_MEM_MT48LC64M4A2FB_7E || CONFIG_MEM_MT48LC16M8A2TG_75 || CONFIG_MEM_GENERIC_BOARD || CONFIG_MEM_MT48LC32M8A2_75 || CONFIG_MEM_MT48LC32M16A2TG_75)
+#if (CONFIG_SCLK_HZ > 119402985)
+#define SDRAM_tRP       TRP_2
+#define SDRAM_tRP_num   2
+#define SDRAM_tRAS      TRAS_7
+#define SDRAM_tRAS_num  7
+#define SDRAM_tRCD      TRCD_2
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 104477612) && (CONFIG_SCLK_HZ <= 119402985)
+#define SDRAM_tRP       TRP_2
+#define SDRAM_tRP_num   2
+#define SDRAM_tRAS      TRAS_6
+#define SDRAM_tRAS_num  6
+#define SDRAM_tRCD      TRCD_2
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 89552239) && (CONFIG_SCLK_HZ <= 104477612)
+#define SDRAM_tRP       TRP_2
+#define SDRAM_tRP_num   2
+#define SDRAM_tRAS      TRAS_5
+#define SDRAM_tRAS_num  5
+#define SDRAM_tRCD      TRCD_2
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 74626866) && (CONFIG_SCLK_HZ <= 89552239)
+#define SDRAM_tRP       TRP_2
+#define SDRAM_tRP_num   2
+#define SDRAM_tRAS      TRAS_4
+#define SDRAM_tRAS_num  4
+#define SDRAM_tRCD      TRCD_2
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 66666667) && (CONFIG_SCLK_HZ <= 74626866)
+#define SDRAM_tRP       TRP_2
+#define SDRAM_tRP_num   2
+#define SDRAM_tRAS      TRAS_3
+#define SDRAM_tRAS_num  3
+#define SDRAM_tRCD      TRCD_2
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 59701493) && (CONFIG_SCLK_HZ <= 66666667)
+#define SDRAM_tRP       TRP_1
+#define SDRAM_tRP_num   1
+#define SDRAM_tRAS      TRAS_4
+#define SDRAM_tRAS_num  3
+#define SDRAM_tRCD      TRCD_1
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 44776119) && (CONFIG_SCLK_HZ <= 59701493)
+#define SDRAM_tRP       TRP_1
+#define SDRAM_tRP_num   1
+#define SDRAM_tRAS      TRAS_3
+#define SDRAM_tRAS_num  3
+#define SDRAM_tRCD      TRCD_1
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 29850746) && (CONFIG_SCLK_HZ <= 44776119)
+#define SDRAM_tRP       TRP_1
+#define SDRAM_tRP_num   1
+#define SDRAM_tRAS      TRAS_2
+#define SDRAM_tRAS_num  2
+#define SDRAM_tRCD      TRCD_1
+#define SDRAM_tWR       TWR_2
+#endif
+#if (CONFIG_SCLK_HZ <= 29850746)
+#define SDRAM_tRP       TRP_1
+#define SDRAM_tRP_num   1
+#define SDRAM_tRAS      TRAS_1
+#define SDRAM_tRAS_num  1
+#define SDRAM_tRCD      TRCD_1
+#define SDRAM_tWR       TWR_2
+#endif
+#endif
+
+#if (CONFIG_MEM_MT48LC16M16A2TG_75)
+  /*SDRAM INFORMATION: */
+#define SDRAM_Tref  64		/* Refresh period in milliseconds   */
+#define SDRAM_NRA   8192	/* Number of row addresses in SDRAM */
+#define SDRAM_CL    CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC16M8A2TG_75)
+  /*SDRAM INFORMATION: */
+#define SDRAM_Tref  64		/* Refresh period in milliseconds   */
+#define SDRAM_NRA   4096	/* Number of row addresses in SDRAM */
+#define SDRAM_CL    CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC32M8A2_75)
+  /*SDRAM INFORMATION: */
+#define SDRAM_Tref  64		/* Refresh period in milliseconds   */
+#define SDRAM_NRA   8192	/* Number of row addresses in SDRAM */
+#define SDRAM_CL    CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC64M4A2FB_7E)
+  /*SDRAM INFORMATION: */
+#define SDRAM_Tref  64		/* Refresh period in milliseconds   */
+#define SDRAM_NRA   8192	/* Number of row addresses in SDRAM */
+#define SDRAM_CL    CL_3
+#endif
+
+#if (CONFIG_MEM_GENERIC_BOARD)
+  /*SDRAM INFORMATION: Modify this for your board */
+#define SDRAM_Tref  64		/* Refresh period in milliseconds   */
+#define SDRAM_NRA   8192	/* Number of row addresses in SDRAM */
+#define SDRAM_CL    CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC32M16A2TG_75)
+  /*SDRAM INFORMATION: */
+#define SDRAM_Tref  64		/* Refresh period in milliseconds   */
+#define SDRAM_NRA   8192	/* Number of row addresses in SDRAM */
+#define SDRAM_CL    CL_3
+#endif
+
+#if (CONFIG_MEM_SIZE == 128)
+#define SDRAM_SIZE      EBSZ_128
+#endif
+#if (CONFIG_MEM_SIZE == 64)
+#define SDRAM_SIZE      EBSZ_64
+#endif
+#if (CONFIG_MEM_SIZE == 32)
+#define SDRAM_SIZE      EBSZ_32
+#endif
+#if (CONFIG_MEM_SIZE == 16)
+#define SDRAM_SIZE      EBSZ_16
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 11)
+#define SDRAM_WIDTH     EBCAW_11
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 10)
+#define SDRAM_WIDTH     EBCAW_10
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 9)
+#define SDRAM_WIDTH     EBCAW_9
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 8)
+#define SDRAM_WIDTH     EBCAW_8
+#endif
+
+#define mem_SDBCTL      (SDRAM_WIDTH | SDRAM_SIZE | EBE)
+
+/* Equation from section 17 (p17-46) of BF533 HRM */
+#define mem_SDRRC       (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num)
+
+/* Enable SCLK Out */
+#define mem_SDGCTL        (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS)
+
+#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-bf527/mem_map.h b/include/asm-blackfin/mach-bf527/mem_map.h
new file mode 100644
index 0000000..c5aa201
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/mem_map.h
@@ -0,0 +1,98 @@
+/*
+ * file:         include/asm-blackfin/mach-bf527/mem_map.h
+ * based on:	include/asm-blackfin/mach-bf537/mem_map.h
+ * author:	Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * created:
+ * description:
+ *	Memory MAP Common header file for blackfin BF527/5/2 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_527_H_
+#define _MEM_MAP_527_H_
+
+#define COREMMR_BASE           0xFFE00000	/* Core MMRs */
+#define SYSMMR_BASE            0xFFC00000	/* System MMRs */
+
+/* Async Memory Banks */
+#define ASYNC_BANK3_BASE	0x20300000	/* Async Bank 3 */
+#define ASYNC_BANK3_SIZE	0x00100000	/* 1M */
+#define ASYNC_BANK2_BASE	0x20200000	/* Async Bank 2 */
+#define ASYNC_BANK2_SIZE	0x00100000	/* 1M */
+#define ASYNC_BANK1_BASE	0x20100000	/* Async Bank 1 */
+#define ASYNC_BANK1_SIZE	0x00100000	/* 1M */
+#define ASYNC_BANK0_BASE	0x20000000	/* Async Bank 0 */
+#define ASYNC_BANK0_SIZE	0x00100000	/* 1M */
+
+/* Boot ROM Memory */
+
+#define BOOT_ROM_START		0xEF000000
+
+/* Level 1 Memory */
+
+/* Memory Map for ADSP-BF527 ADSP-BF525 ADSP-BF522 processors */
+
+#ifdef CONFIG_BFIN_ICACHE
+#define BFIN_ICACHESIZE	(16*1024)
+#else
+#define BFIN_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_BFIN_DCACHE
+
+#ifdef CONFIG_BFIN_DCACHE_BANKA
+#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH      0x8000
+#define BFIN_DCACHESIZE	(16*1024)
+#define BFIN_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 BFIN_DCACHESIZE	(32*1024)
+#define BFIN_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 BFIN_DCACHESIZE	(0*1024)
+#define BFIN_DSUPBANKS	0
+#endif				/*CONFIG_BFIN_DCACHE */
+
+/* Scratch Pad Memory */
+
+#if defined(CONFIG_BF527) || defined(CONFIG_BF536) || defined(CONFIG_BF534)
+#define L1_SCRATCH_START	0xFFB00000
+#define L1_SCRATCH_LENGTH	0x1000
+#endif
+
+#endif				/* _MEM_MAP_527_H_ */
diff --git a/include/asm-blackfin/mach-bf527/portmux.h b/include/asm-blackfin/mach-bf527/portmux.h
new file mode 100644
index 0000000..dcf001a
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/portmux.h
@@ -0,0 +1,205 @@
+#ifndef _MACH_PORTMUX_H_
+#define _MACH_PORTMUX_H_
+
+#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))
+
+#if defined(CONFIG_BF527_SPORT0_PORTF)
+#define P_SPORT0_DRPRI	(P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(1))
+#define P_SPORT0_RFS	(P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(1))
+#define P_SPORT0_RSCLK	(P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(1))
+#define P_SPORT0_DTPRI	(P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(1))
+#define P_SPORT0_TFS	(P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(1))
+#define P_SPORT0_TSCLK	(P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(1))
+#define P_SPORT0_DTSEC	(P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(1))
+#define P_SPORT0_DRSEC	(P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(1))
+#elif defined(CONFIG_BF527_SPORT0_PORTG)
+#define P_SPORT0_DTPRI	(P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(0))
+#define P_SPORT0_DRSEC	(P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(1))
+#define P_SPORT0_DTSEC	(P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(1))
+#define P_SPORT0_DRPRI	(P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(1))
+#define P_SPORT0_RFS	(P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(1))
+#define P_SPORT0_RSCLK	(P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(1))
+#if defined(CONFIG_BF527_SPORT0_TSCLK_PG10)
+#define P_SPORT0_TSCLK	(P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(1))
+#elif defined(CONFIG_BF527_SPORT0_TSCLK_PG14)
+#define P_SPORT0_TSCLK	(P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(0))
+#endif
+#define P_SPORT0_TFS	(P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(0))
+#endif
+
+#define P_SPORT1_DRPRI	(P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(1))
+#define P_SPORT1_RSCLK	(P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(1))
+#define P_SPORT1_RFS	(P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(1))
+#define P_SPORT1_TFS	(P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(1))
+#define P_SPORT1_DTPRI	(P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(1))
+#define P_SPORT1_TSCLK	(P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(1))
+#define P_SPORT1_DTSEC	(P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(1))
+#define P_SPORT1_DRSEC	(P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(1))
+
+#define P_SPI0_SSEL6	(P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(2))
+#define P_SPI0_SSEL7	(P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(2))
+
+#define P_SPI0_SSEL2	(P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(2))
+#define P_SPI0_SSEL3	(P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(2))
+
+#if defined(CONFIG_BF527_UART1_PORTF)
+#define P_UART1_TX	(P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(2))
+#define P_UART1_RX	(P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(2))
+#elif defined(CONFIG_BF527_UART1_PORTG)
+#define P_UART1_TX	(P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(1))
+#define P_UART1_RX	(P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(1))
+#endif
+
+#define P_HWAIT		(P_DONTCARE)
+
+#define P_SPI0_SS	(P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0))
+#define P_SPI0_SSEL1	(P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(2))
+#define P_SPI0_SCK	(P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(2))
+#define P_SPI0_MISO	(P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(2))
+#define P_SPI0_MOSI	(P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(2))
+#define P_TMR1		(P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(0))
+#define P_PPI0_FS2	(P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(0))
+#define P_TMR3		(P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(0))
+#define P_TMR4		(P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(0))
+#define P_TMR5		(P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(0))
+#define P_TMR6		(P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(0))
+/* #define P_TMR7		(P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(0)) */
+#define P_DMAR1		(P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(0))
+#define P_DMAR0		(P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(0))
+#define P_TMR2		(P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(1))
+#define P_TMR7		(P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(1))
+#define P_MDC		(P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(1))
+#define P_RMII0_MDINT	(P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(1))
+#define P_MII0_PHYINT	(P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(1))
+
+#define P_PPI0_FS3	(P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(2))
+#define P_UART0_TX	(P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(2))
+#define P_UART0_RX	(P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(2))
+
+#define P_HOST_WR	(P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(2))
+#define P_HOST_ACK	(P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(2))
+#define P_HOST_ADDR	(P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(2))
+#define P_HOST_RD	(P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(2))
+#define P_HOST_CE	(P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(2))
+
+#if defined(CONFIG_BF527_NAND_D_PORTF)
+#define P_NAND_D0	(P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(2))
+#define P_NAND_D1	(P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(2))
+#define P_NAND_D2	(P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(2))
+#define P_NAND_D3	(P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(2))
+#define P_NAND_D4	(P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(2))
+#define P_NAND_D5	(P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(2))
+#define P_NAND_D6	(P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(2))
+#define P_NAND_D7	(P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(2))
+#elif defined(CONFIG_BF527_NAND_D_PORTH)
+#define P_NAND_D0	(P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(0))
+#define P_NAND_D1	(P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(0))
+#define P_NAND_D2	(P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(0))
+#define P_NAND_D3	(P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(0))
+#define P_NAND_D4	(P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(0))
+#define P_NAND_D5	(P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(0))
+#define P_NAND_D6	(P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(0))
+#define P_NAND_D7	(P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(0))
+#endif
+
+#define P_SPI0_SSEL4	(P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(0))
+#define P_SPI0_SSEL5	(P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(0))
+#define P_NAND_CE	(P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(0))
+#define P_NAND_WE	(P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(0))
+#define P_NAND_RE	(P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(0))
+#define P_NAND_RB	(P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(0))
+#define P_NAND_CLE	(P_DEFINED | P_IDENT(GPIO_PH14) | P_FUNCT(0))
+#define P_NAND_ALE	(P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(0))
+
+#define P_HOST_D0	(P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(2))
+#define P_HOST_D1	(P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(2))
+#define P_HOST_D2	(P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(2))
+#define P_HOST_D3	(P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(2))
+#define P_HOST_D4	(P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(2))
+#define P_HOST_D5	(P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(2))
+#define P_HOST_D6	(P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(2))
+#define P_HOST_D7	(P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(2))
+#define P_HOST_D8	(P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(2))
+#define P_HOST_D9	(P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(2))
+#define P_HOST_D10	(P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(2))
+#define P_HOST_D11	(P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(2))
+#define P_HOST_D12	(P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(2))
+#define P_HOST_D13	(P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(2))
+#define P_HOST_D14	(P_DEFINED | P_IDENT(GPIO_PH14) | P_FUNCT(2))
+#define P_HOST_D15	(P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(2))
+
+#define P_MII0_ETxD0	(P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(1))
+#define P_MII0_ETxD1	(P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(1))
+#define P_MII0_ETxD2	(P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(1))
+#define P_MII0_ETxD3	(P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(1))
+#define P_MII0_ETxEN	(P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(1))
+#define P_MII0_TxCLK	(P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(1))
+#define P_MII0_COL	(P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(1))
+#define P_MII0_ERxD0	(P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(1))
+#define P_MII0_ERxD1	(P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(1))
+#define P_MII0_ERxD2	(P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(1))
+#define P_MII0_ERxD3	(P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(1))
+#define P_MII0_ERxDV	(P_DEFINED | P_IDENT(GPIO_PH14) | P_FUNCT(1))
+#define P_MII0_ERxCLK	(P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(1))
+#define P_MII0_ERxER	(P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(1))
+#define P_MII0_CRS	(P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(1))
+#define P_RMII0_REF_CLK	(P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(1))
+#define P_RMII0_CRS_DV	(P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(1))
+#define P_MDIO		(P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(1))
+
+#define P_TWI0_SCL	(P_DONTCARE)
+#define P_TWI0_SDA	(P_DONTCARE)
+#define P_PPI0_FS1	(P_DONTCARE)
+#define P_TMR0		(P_DONTCARE)
+#define P_TMRCLK	(P_DONTCARE)
+#define P_PPI0_CLK	(P_DONTCARE)
+
+#define P_MII0 {\
+	P_MII0_ETxD0, \
+	P_MII0_ETxD1, \
+	P_MII0_ETxD2, \
+	P_MII0_ETxD3, \
+	P_MII0_ETxEN, \
+	P_MII0_TxCLK, \
+	P_MII0_PHYINT, \
+	P_MII0_COL, \
+	P_MII0_ERxD0, \
+	P_MII0_ERxD1, \
+	P_MII0_ERxD2, \
+	P_MII0_ERxD3, \
+	P_MII0_ERxDV, \
+	P_MII0_ERxCLK, \
+	P_MII0_ERxER, \
+	P_MII0_CRS, \
+	P_MDC, \
+	P_MDIO, 0}
+
+#define P_RMII0 {\
+	P_MII0_ETxD0, \
+	P_MII0_ETxD1, \
+	P_MII0_ETxEN, \
+	P_MII0_ERxD0, \
+	P_MII0_ERxD1, \
+	P_MII0_ERxER, \
+	P_RMII0_REF_CLK, \
+	P_RMII0_MDINT, \
+	P_RMII0_CRS_DV, \
+	P_MDC, \
+	P_MDIO, 0}
+
+#endif				/* _MACH_PORTMUX_H_ */
diff --git a/include/asm-blackfin/mach-bf548/defBF549.h b/include/asm-blackfin/mach-bf548/defBF549.h
index 50b3fe5..4e46d65 100644
--- a/include/asm-blackfin/mach-bf548/defBF549.h
+++ b/include/asm-blackfin/mach-bf548/defBF549.h
@@ -1178,7 +1178,7 @@
 
 /* Bit masks for HOST_STATUS */
 
-#define                     READY  0x1        /* DMA Ready */
+#define                 DMA_READY  0x1        /* DMA Ready */
 #define                  FIFOFULL  0x2        /* FIFO Full */
 #define                 FIFOEMPTY  0x4        /* FIFO Empty */
 #define              DMA_COMPLETE  0x8        /* DMA Complete */
diff --git a/include/asm-blackfin/mach-bf548/defBF54x_base.h b/include/asm-blackfin/mach-bf548/defBF54x_base.h
index e2632db..1d365c8 100644
--- a/include/asm-blackfin/mach-bf548/defBF54x_base.h
+++ b/include/asm-blackfin/mach-bf548/defBF54x_base.h
@@ -47,6 +47,10 @@
 /* Debug/MP/Emulation Registers (0xFFC00014 - 0xFFC00014) */
 
 #define                           CHIPID  0xffc00014
+/* CHIPID Masks */
+#define                   CHIPID_VERSION  0xF0000000
+#define                    CHIPID_FAMILY  0x0FFFF000
+#define               CHIPID_MANUFACTURE  0x00000FFE
 
 /* System Reset and Interrupt Controller (0xFFC00100 - 0xFFC00104) */
 
@@ -3299,7 +3303,7 @@
 
 #define                       MFD  0xf000     /* Multi channel Frame Delay */
 #define                      FSDR  0x80       /* Frame Sync to Data Relationship */
-#define                     MCMEM  0x10       /* Multi channel Frame Mode Enable */
+#define                  MCMEN  0x10       /* Multi channel Frame Mode Enable */
 #define                   MCDRXPE  0x8        /* Multi channel DMA Receive Packing */
 #define                   MCDTXPE  0x4        /* Multi channel DMA Transmit Packing */
 #define                     MCCRM  0x3        /* 2X Clock Recovery Mode */
diff --git a/include/asm-blackfin/mach-bf548/dma.h b/include/asm-blackfin/mach-bf548/dma.h
index 14cb10c..4d97d3a 100644
--- a/include/asm-blackfin/mach-bf548/dma.h
+++ b/include/asm-blackfin/mach-bf548/dma.h
@@ -70,5 +70,5 @@
 #define MAX_BLACKFIN_DMA_CHANNEL 32
 
 extern int channel2irq(unsigned int channel);
-extern struct dma_register *base_addr[];
+extern struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL];
 #endif
diff --git a/include/asm-blackfin/processor.h b/include/asm-blackfin/processor.h
index 6bb3e0d..c571e95 100644
--- a/include/asm-blackfin/processor.h
+++ b/include/asm-blackfin/processor.h
@@ -104,13 +104,13 @@
 #define cpu_relax()    	barrier()
 
 /* Get the Silicon Revision of the chip */
-static inline __attribute_pure__ uint32_t bfin_revid(void)
+static inline uint32_t __pure bfin_revid(void)
 {
 	/* stored in the upper 4 bits */
 	return bfin_read_CHIPID() >> 28;
 }
 
-static inline __attribute_pure__ uint32_t bfin_compiled_revid(void)
+static inline uint32_t __pure bfin_compiled_revid(void)
 {
 #if defined(CONFIG_BF_REV_0_0)
 	return 0;
diff --git a/include/asm-blackfin/scatterlist.h b/include/asm-blackfin/scatterlist.h
index 60e07b9..04f4487 100644
--- a/include/asm-blackfin/scatterlist.h
+++ b/include/asm-blackfin/scatterlist.h
@@ -4,7 +4,10 @@
 #include <linux/mm.h>
 
 struct scatterlist {
-	struct page *page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long sg_magic;
+#endif
+	unsigned long page_link;
 	unsigned int offset;
 	dma_addr_t dma_address;
 	unsigned int length;
@@ -17,7 +20,6 @@
  * returns, or alternatively stop on the first sg_dma_len(sg) which
  * is 0.
  */
-#define sg_address(sg) (page_address((sg)->page) + (sg)->offset)
 #define sg_dma_address(sg)      ((sg)->dma_address)
 #define sg_dma_len(sg)          ((sg)->length)
 
diff --git a/include/asm-blackfin/system.h b/include/asm-blackfin/system.h
index 2b3d47d..4a92737 100644
--- a/include/asm-blackfin/system.h
+++ b/include/asm-blackfin/system.h
@@ -128,9 +128,7 @@
 #define mb()   asm volatile (""   : : :"memory")
 #define rmb()  asm volatile (""   : : :"memory")
 #define wmb()  asm volatile (""   : : :"memory")
-#define set_rmb(var, value)    do { (void) xchg(&var, value); } while (0)
-#define set_mb(var, value)     set_rmb(var, value)
-#define set_wmb(var, value)    do { var = value; wmb(); } while (0)
+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
 
 #define read_barrier_depends() 		do { } while(0)
 
diff --git a/include/asm-blackfin/tlbflush.h b/include/asm-blackfin/tlbflush.h
index 10a07ba..277b400 100644
--- a/include/asm-blackfin/tlbflush.h
+++ b/include/asm-blackfin/tlbflush.h
@@ -53,10 +53,4 @@
 	BUG();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-	BUG();
-}
-
 #endif
diff --git a/include/asm-cris/arch-v32/ide.h b/include/asm-cris/arch-v32/ide.h
index 6590f65..1129617 100644
--- a/include/asm-cris/arch-v32/ide.h
+++ b/include/asm-cris/arch-v32/ide.h
@@ -54,7 +54,7 @@
 #define SUPPORT_VLB_SYNC 0
 
 #define IDE_ARCH_ACK_INTR
-#define ide_ack_intr(hwif)	(hwif)->hw.ack_intr(hwif)
+#define ide_ack_intr(hwif)	((hwif)->ack_intr(hwif))
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h
index a569065..e2f49c2 100644
--- a/include/asm-cris/bitops.h
+++ b/include/asm-cris/bitops.h
@@ -14,6 +14,10 @@
 /* Currently this is unsuitable for consumption outside the kernel.  */
 #ifdef __KERNEL__ 
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm/arch/bitops.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
@@ -154,6 +158,7 @@
 #include <asm-generic/bitops/fls64.h>
 #include <asm-generic/bitops/hweight.h>
 #include <asm-generic/bitops/find.h>
+#include <asm-generic/bitops/lock.h>
 
 #include <asm-generic/bitops/ext2-non-atomic.h>
 
diff --git a/include/asm-cris/posix_types.h b/include/asm-cris/posix_types.h
index 7b9ed22..92000d0 100644
--- a/include/asm-cris/posix_types.h
+++ b/include/asm-cris/posix_types.h
@@ -52,7 +52,7 @@
 } __kernel_fsid_t;
 
 #ifdef __KERNEL__
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 #undef	__FD_SET
 #define __FD_SET(fd,fdsetp) set_bit(fd, (void *)(fdsetp))
diff --git a/include/asm-cris/scatterlist.h b/include/asm-cris/scatterlist.h
index 4bdc44c..faff53a 100644
--- a/include/asm-cris/scatterlist.h
+++ b/include/asm-cris/scatterlist.h
@@ -2,11 +2,14 @@
 #define __ASM_CRIS_SCATTERLIST_H
 
 struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+	unsigned long sg_magic;
+#endif
 	char *  address;    /* Location data is to be transferred to */
 	unsigned int length;
 
 	/* The following is i386 highmem junk - not used by us */
-	struct page * page; /* Location for highmem page, if any */
+	unsigned long page_link;
 	unsigned int offset;/* for highmem, page offset */
 
 };
diff --git a/include/asm-cris/tlbflush.h b/include/asm-cris/tlbflush.h
index 0569612..20697e7 100644
--- a/include/asm-cris/tlbflush.h
+++ b/include/asm-cris/tlbflush.h
@@ -38,13 +38,6 @@
 	flush_tlb_mm(vma->vm_mm);
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                      unsigned long start, unsigned long end)
-{
-        /* CRIS does not keep any page table caches in TLB */
-}
-
-
 static inline void flush_tlb(void)
 {
 	flush_tlb_mm(current->mm);
diff --git a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h
index f8560ed..e29de71 100644
--- a/include/asm-frv/bitops.h
+++ b/include/asm-frv/bitops.h
@@ -21,6 +21,10 @@
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm-generic/bitops/ffz.h>
 
 /*
@@ -302,6 +306,7 @@
 
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #include <asm-generic/bitops/ext2-non-atomic.h>
 
diff --git a/include/asm-frv/scatterlist.h b/include/asm-frv/scatterlist.h
index 8e827fa..99ba76e 100644
--- a/include/asm-frv/scatterlist.h
+++ b/include/asm-frv/scatterlist.h
@@ -4,25 +4,28 @@
 #include <asm/types.h>
 
 /*
- * Drivers must set either ->address or (preferred) ->page and ->offset
+ * Drivers must set either ->address or (preferred) page and ->offset
  * to indicate where data must be transferred to/from.
  *
- * Using ->page is recommended since it handles highmem data as well as
+ * Using page is recommended since it handles highmem data as well as
  * low mem. ->address is restricted to data which has a virtual mapping, and
- * it will go away in the future. Updating to ->page can be automated very
+ * it will go away in the future. Updating to page can be automated very
  * easily -- something like
  *
  * sg->address = some_ptr;
  *
  * can be rewritten as
  *
- * sg->page = virt_to_page(some_ptr);
+ * sg_set_page(virt_to_page(some_ptr));
  * sg->offset = (unsigned long) some_ptr & ~PAGE_MASK;
  *
  * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
  */
 struct scatterlist {
-	struct page	*page;		/* Location for highmem page, if any */
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;		/* for highmem, page offset */
 
 	dma_addr_t	dma_address;
diff --git a/include/asm-frv/tlbflush.h b/include/asm-frv/tlbflush.h
index 8370f97..7ac5eaf 100644
--- a/include/asm-frv/tlbflush.h
+++ b/include/asm-frv/tlbflush.h
@@ -57,7 +57,6 @@
 #define __flush_tlb_global()			flush_tlb_all()
 #define flush_tlb()				flush_tlb_all()
 #define flush_tlb_kernel_range(start, end)	flush_tlb_all()
-#define flush_tlb_pgtables(mm,start,end)	do { } while(0)
 
 #else
 
@@ -66,7 +65,6 @@
 #define flush_tlb_mm(mm)			BUG()
 #define flush_tlb_page(vma,addr)		BUG()
 #define flush_tlb_range(mm,start,end)		BUG()
-#define flush_tlb_pgtables(mm,start,end)	BUG()
 #define flush_tlb_kernel_range(start, end)	BUG()
 
 #endif
diff --git a/include/asm-generic/bitops.h b/include/asm-generic/bitops.h
index 1f9d991..15e6f25 100644
--- a/include/asm-generic/bitops.h
+++ b/include/asm-generic/bitops.h
@@ -19,9 +19,14 @@
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
diff --git a/include/asm-generic/bitops/atomic.h b/include/asm-generic/bitops/atomic.h
index cd8a964..4657f3e 100644
--- a/include/asm-generic/bitops/atomic.h
+++ b/include/asm-generic/bitops/atomic.h
@@ -3,9 +3,6 @@
 
 #include <asm/types.h>
 
-#define BITOP_MASK(nr)		(1UL << ((nr) % BITS_PER_LONG))
-#define BITOP_WORD(nr)		((nr) / BITS_PER_LONG)
-
 #ifdef CONFIG_SMP
 #include <asm/spinlock.h>
 #include <asm/cache.h>		/* we use L1_CACHE_BYTES */
@@ -66,8 +63,8 @@
  */
 static inline void set_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 	unsigned long flags;
 
 	_atomic_spin_lock_irqsave(p, flags);
@@ -87,8 +84,8 @@
  */
 static inline void clear_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 	unsigned long flags;
 
 	_atomic_spin_lock_irqsave(p, flags);
@@ -108,8 +105,8 @@
  */
 static inline void change_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 	unsigned long flags;
 
 	_atomic_spin_lock_irqsave(p, flags);
@@ -128,8 +125,8 @@
  */
 static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 	unsigned long old;
 	unsigned long flags;
 
@@ -152,8 +149,8 @@
  */
 static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 	unsigned long old;
 	unsigned long flags;
 
@@ -175,8 +172,8 @@
  */
 static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 	unsigned long old;
 	unsigned long flags;
 
diff --git a/include/asm-generic/bitops/lock.h b/include/asm-generic/bitops/lock.h
new file mode 100644
index 0000000..308a9e2
--- /dev/null
+++ b/include/asm-generic/bitops/lock.h
@@ -0,0 +1,45 @@
+#ifndef _ASM_GENERIC_BITOPS_LOCK_H_
+#define _ASM_GENERIC_BITOPS_LOCK_H_
+
+/**
+ * test_and_set_bit_lock - Set a bit and return its old value, for lock
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and provides acquire barrier semantics.
+ * It can be used to implement bit locks.
+ */
+#define test_and_set_bit_lock(nr, addr)	test_and_set_bit(nr, addr)
+
+/**
+ * clear_bit_unlock - Clear a bit in memory, for unlock
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This operation is atomic and provides release barrier semantics.
+ */
+#define clear_bit_unlock(nr, addr)	\
+do {					\
+	smp_mb__before_clear_bit();	\
+	clear_bit(nr, addr);		\
+} while (0)
+
+/**
+ * __clear_bit_unlock - Clear a bit in memory, for unlock
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This operation is like clear_bit_unlock, however it is not atomic.
+ * It does provide release barrier semantics so it can be used to unlock
+ * a bit lock, however it would only be used if no other CPU can modify
+ * any bits in the memory until the lock is released (a good example is
+ * if the bit lock itself protects access to the other bits in the word).
+ */
+#define __clear_bit_unlock(nr, addr)	\
+do {					\
+	smp_mb();			\
+	__clear_bit(nr, addr);		\
+} while (0)
+
+#endif /* _ASM_GENERIC_BITOPS_LOCK_H_ */
+
diff --git a/include/asm-generic/bitops/non-atomic.h b/include/asm-generic/bitops/non-atomic.h
index 46a825c..697cc2b 100644
--- a/include/asm-generic/bitops/non-atomic.h
+++ b/include/asm-generic/bitops/non-atomic.h
@@ -3,9 +3,6 @@
 
 #include <asm/types.h>
 
-#define BITOP_MASK(nr)		(1UL << ((nr) % BITS_PER_LONG))
-#define BITOP_WORD(nr)		((nr) / BITS_PER_LONG)
-
 /**
  * __set_bit - Set a bit in memory
  * @nr: the bit to set
@@ -17,16 +14,16 @@
  */
 static inline void __set_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 
 	*p  |= mask;
 }
 
 static inline void __clear_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 
 	*p &= ~mask;
 }
@@ -42,8 +39,8 @@
  */
 static inline void __change_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 
 	*p ^= mask;
 }
@@ -59,8 +56,8 @@
  */
 static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 	unsigned long old = *p;
 
 	*p = old | mask;
@@ -78,8 +75,8 @@
  */
 static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 	unsigned long old = *p;
 
 	*p = old & ~mask;
@@ -90,8 +87,8 @@
 static inline int __test_and_change_bit(int nr,
 					    volatile unsigned long *addr)
 {
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+	unsigned long mask = BIT_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 	unsigned long old = *p;
 
 	*p = old ^ mask;
@@ -105,7 +102,7 @@
  */
 static inline int test_bit(int nr, const volatile unsigned long *addr)
 {
-	return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+	return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
 }
 
 #endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 5615440..9f584cc 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -12,7 +12,11 @@
 /* .data section */
 #define DATA_DATA							\
 	*(.data)							\
-	*(.data.init.refok)
+	*(.data.init.refok)						\
+	. = ALIGN(8);							\
+	VMLINUX_SYMBOL(__start___markers) = .;				\
+	*(__markers)							\
+	VMLINUX_SYMBOL(__stop___markers) = .;
 
 #define RO_DATA(align)							\
 	. = ALIGN((align));						\
@@ -20,6 +24,7 @@
 		VMLINUX_SYMBOL(__start_rodata) = .;			\
 		*(.rodata) *(.rodata.*)					\
 		*(__vermagic)		/* Kernel version magic */	\
+		*(__markers_strings)	/* Markers: strings */		\
 	}								\
 									\
 	.rodata1          : AT(ADDR(.rodata1) - LOAD_OFFSET) {		\
diff --git a/include/asm-h8300/bitops.h b/include/asm-h8300/bitops.h
index d76299c..cb18e3b 100644
--- a/include/asm-h8300/bitops.h
+++ b/include/asm-h8300/bitops.h
@@ -10,6 +10,11 @@
 #include <asm/system.h>
 
 #ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 /*
  * Function prototypes to keep gcc -Wall happy
  */
@@ -194,6 +199,7 @@
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
 #include <asm-generic/bitops/minix.h>
diff --git a/include/asm-h8300/scatterlist.h b/include/asm-h8300/scatterlist.h
index 985fdf5..d3ecdd8 100644
--- a/include/asm-h8300/scatterlist.h
+++ b/include/asm-h8300/scatterlist.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/asm-h8300/system.h b/include/asm-h8300/system.h
index 7807018..2c1e83f 100644
--- a/include/asm-h8300/system.h
+++ b/include/asm-h8300/system.h
@@ -82,8 +82,7 @@
 #define mb()   asm volatile (""   : : :"memory")
 #define rmb()  asm volatile (""   : : :"memory")
 #define wmb()  asm volatile (""   : : :"memory")
-#define set_rmb(var, value)    do { xchg(&var, value); } while (0)
-#define set_mb(var, value)     set_rmb(var, value)
+#define set_mb(var, value) do { xchg(&var, value); } while (0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()
diff --git a/include/asm-h8300/tlbflush.h b/include/asm-h8300/tlbflush.h
index 9a2c5c9..41c148a 100644
--- a/include/asm-h8300/tlbflush.h
+++ b/include/asm-h8300/tlbflush.h
@@ -52,10 +52,4 @@
 	BUG();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-	BUG();
-}
-
 #endif /* _H8300_TLBFLUSH_H */
diff --git a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h
index 6cc517e..a977aff 100644
--- a/include/asm-ia64/bitops.h
+++ b/include/asm-ia64/bitops.h
@@ -9,6 +9,10 @@
  * O(1) scheduler patch
  */
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <linux/types.h>
 #include <asm/intrinsics.h>
@@ -94,6 +98,38 @@
 }
 
 /**
+ * clear_bit_unlock - Clears a bit in memory with release
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit_unlock() is atomic and may not be reordered.  It does
+ * contain a memory barrier suitable for unlock type operations.
+ */
+static __inline__ void
+clear_bit_unlock (int nr, volatile void *addr)
+{
+	__u32 mask, old, new;
+	volatile __u32 *m;
+	CMPXCHG_BUGCHECK_DECL
+
+	m = (volatile __u32 *) addr + (nr >> 5);
+	mask = ~(1 << (nr & 31));
+	do {
+		CMPXCHG_BUGCHECK(m);
+		old = *m;
+		new = old & mask;
+	} while (cmpxchg_rel(m, old, new) != old);
+}
+
+/**
+ * __clear_bit_unlock - Non-atomically clear a bit with release
+ *
+ * This is like clear_bit_unlock, but the implementation may use a non-atomic
+ * store (this one uses an atomic, however).
+ */
+#define __clear_bit_unlock clear_bit_unlock
+
+/**
  * __clear_bit - Clears a bit in memory (non-atomic version)
  */
 static __inline__ void
@@ -170,6 +206,15 @@
 }
 
 /**
+ * test_and_set_bit_lock - Set a bit and return its old value for lock
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This is the same as test_and_set_bit on ia64
+ */
+#define test_and_set_bit_lock test_and_set_bit
+
+/**
  * __test_and_set_bit - Set a bit and return its old value
  * @nr: Bit to set
  * @addr: Address to count from
diff --git a/include/asm-ia64/cacheflush.h b/include/asm-ia64/cacheflush.h
index 4906916..afcfbda 100644
--- a/include/asm-ia64/cacheflush.h
+++ b/include/asm-ia64/cacheflush.h
@@ -7,8 +7,8 @@
  */
 
 #include <linux/page-flags.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/page.h>
 
 /*
diff --git a/include/asm-ia64/ide.h b/include/asm-ia64/ide.h
index e928675..1ccf238 100644
--- a/include/asm-ia64/ide.h
+++ b/include/asm-ia64/ide.h
@@ -46,7 +46,6 @@
 	}
 }
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)	((base) + 0x206) /* obsolete */
 
 #ifdef CONFIG_PCI
diff --git a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h
index 3a62878..f93308f 100644
--- a/include/asm-ia64/meminit.h
+++ b/include/asm-ia64/meminit.h
@@ -35,7 +35,7 @@
 extern void reserve_memory (void);
 extern void find_initrd (void);
 extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
-extern void efi_memmap_init(unsigned long *, unsigned long *);
+extern unsigned long efi_memmap_init(unsigned long *s, unsigned long *e);
 extern int find_max_min_low_pfn (unsigned long , unsigned long, void *);
 
 extern unsigned long vmcore_find_descriptor_size(unsigned long address);
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index 0971ec9..e6204f14 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -150,7 +150,7 @@
 # ifndef __ASSEMBLY__
 
 #include <linux/sched.h>	/* for mm_struct */
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
 #include <asm/processor.h>
diff --git a/include/asm-ia64/scatterlist.h b/include/asm-ia64/scatterlist.h
index 7d5234d..d6f5787 100644
--- a/include/asm-ia64/scatterlist.h
+++ b/include/asm-ia64/scatterlist.h
@@ -9,7 +9,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page *page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long sg_magic;
+#endif
+	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;	/* buffer length */
 
diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h
index 1703c9d..471cc2e 100644
--- a/include/asm-ia64/smp.h
+++ b/include/asm-ia64/smp.h
@@ -14,8 +14,8 @@
 #include <linux/threads.h>
 #include <linux/kernel.h>
 #include <linux/cpumask.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/param.h>
 #include <asm/processor.h>
diff --git a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h
index ff857e3..0229fb9 100644
--- a/include/asm-ia64/spinlock.h
+++ b/include/asm-ia64/spinlock.h
@@ -11,9 +11,9 @@
 
 #include <linux/compiler.h>
 #include <linux/kernel.h>
+#include <linux/bitops.h>
 
 #include <asm/atomic.h>
-#include <asm/bitops.h>
 #include <asm/intrinsics.h>
 #include <asm/system.h>
 
diff --git a/include/asm-ia64/tlbflush.h b/include/asm-ia64/tlbflush.h
index e37f9fb..80bcb0a 100644
--- a/include/asm-ia64/tlbflush.h
+++ b/include/asm-ia64/tlbflush.h
@@ -84,19 +84,6 @@
 }
 
 /*
- * Flush the TLB entries mapping the virtually mapped linear page
- * table corresponding to address range [START-END).
- */
-static inline void
-flush_tlb_pgtables (struct mm_struct *mm, unsigned long start, unsigned long end)
-{
-	/*
-	 * Deprecated.  The virtual page table is now flushed via the normal gather/flush
-	 * interface (see tlb.h).
-	 */
-}
-
-/*
  * Flush the local TLB. Invoked from another cpu using an IPI.
  */
 #ifdef CONFIG_SMP
diff --git a/include/asm-m32r/bitops.h b/include/asm-m32r/bitops.h
index 66ab672..6dc9b81 100644
--- a/include/asm-m32r/bitops.h
+++ b/include/asm-m32r/bitops.h
@@ -11,6 +11,10 @@
  *    Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
  */
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/assembler.h>
 #include <asm/system.h>
@@ -255,6 +259,7 @@
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-m32r/ide.h b/include/asm-m32r/ide.h
index 4672a49..5d2044e 100644
--- a/include/asm-m32r/ide.h
+++ b/include/asm-m32r/ide.h
@@ -65,7 +65,6 @@
 	}
 }
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)	((base) + 0x206) /* obsolete */
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
index 92d7266..8650538 100644
--- a/include/asm-m32r/pgtable.h
+++ b/include/asm-m32r/pgtable.h
@@ -21,9 +21,9 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/threads.h>
+#include <linux/bitops.h>
 #include <asm/processor.h>
 #include <asm/addrspace.h>
-#include <asm/bitops.h>
 #include <asm/page.h>
 
 struct mm_struct;
diff --git a/include/asm-m32r/scatterlist.h b/include/asm-m32r/scatterlist.h
index 352415f..1ed372c 100644
--- a/include/asm-m32r/scatterlist.h
+++ b/include/asm-m32r/scatterlist.h
@@ -4,9 +4,12 @@
 #include <asm/types.h>
 
 struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+    unsigned long sg_magic;
+#endif
     char *  address;    /* Location data is to be transferred to, NULL for
                          * highmem page */
-    struct page * page; /* Location for highmem page, if any */
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
 
     dma_addr_t dma_address;
diff --git a/include/asm-m32r/tlbflush.h b/include/asm-m32r/tlbflush.h
index 3d37ac0..0ef9530 100644
--- a/include/asm-m32r/tlbflush.h
+++ b/include/asm-m32r/tlbflush.h
@@ -12,7 +12,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 
 extern void local_flush_tlb_all(void);
@@ -93,8 +92,6 @@
 	);
 }
 
-#define flush_tlb_pgtables(mm, start, end)	do { } while (0)
-
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
 #endif	/* _ASM_M32R_TLBFLUSH_H */
diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h
index 1a61fdb..2976b5d 100644
--- a/include/asm-m68k/bitops.h
+++ b/include/asm-m68k/bitops.h
@@ -8,6 +8,10 @@
  * for more details.
  */
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 
 /*
@@ -314,6 +318,7 @@
 #include <asm-generic/bitops/fls64.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 /* Bitmap functions for the minix filesystem */
 
diff --git a/include/asm-m68k/ide.h b/include/asm-m68k/ide.h
index f9ffb2c..909c6df 100644
--- a/include/asm-m68k/ide.h
+++ b/include/asm-m68k/ide.h
@@ -137,7 +137,7 @@
 #endif /* CONFIG_BLK_DEV_FALCON_IDE */
 
 #define IDE_ARCH_ACK_INTR
-#define ide_ack_intr(hwif)	((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
+#define ide_ack_intr(hwif)	((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1)
 
 #endif /* __KERNEL__ */
 #endif /* _M68K_IDE_H */
diff --git a/include/asm-m68k/scatterlist.h b/include/asm-m68k/scatterlist.h
index 24887a2..d3a7a0e 100644
--- a/include/asm-m68k/scatterlist.h
+++ b/include/asm-m68k/scatterlist.h
@@ -4,7 +4,10 @@
 #include <linux/types.h>
 
 struct scatterlist {
-	struct page *page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long sg_magic;
+#endif
+	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;
 
diff --git a/include/asm-m68k/tlbflush.h b/include/asm-m68k/tlbflush.h
index 3167883..17707ec 100644
--- a/include/asm-m68k/tlbflush.h
+++ b/include/asm-m68k/tlbflush.h
@@ -92,11 +92,6 @@
 	flush_tlb_all();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-}
-
 #else
 
 
@@ -219,11 +214,6 @@
 	sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-}
-
 #endif
 
 #endif /* _M68K_TLBFLUSH_H */
diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h
index 7d6075d..f8dfb7b 100644
--- a/include/asm-m68knommu/bitops.h
+++ b/include/asm-m68knommu/bitops.h
@@ -10,6 +10,10 @@
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/__ffs.h>
 #include <asm-generic/bitops/sched.h>
@@ -160,6 +164,7 @@
 
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 static __inline__ int ext2_set_bit(int nr, volatile void * addr)
 {
diff --git a/include/asm-m68knommu/module.h b/include/asm-m68knommu/module.h
index 57e95cc..2e45ab5 100644
--- a/include/asm-m68knommu/module.h
+++ b/include/asm-m68knommu/module.h
@@ -1 +1,11 @@
-#include <asm-m68k/module.h>
+#ifndef ASM_M68KNOMMU_MODULE_H
+#define ASM_M68KNOMMU_MODULE_H
+
+struct mod_arch_specific {
+};
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+
+#endif /* ASM_M68KNOMMU_MODULE_H */
diff --git a/include/asm-m68knommu/scatterlist.h b/include/asm-m68knommu/scatterlist.h
index 4da79d3..afc4788 100644
--- a/include/asm-m68knommu/scatterlist.h
+++ b/include/asm-m68knommu/scatterlist.h
@@ -5,13 +5,15 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
 };
 
-#define sg_address(sg)		(page_address((sg)->page) + (sg)->offset)
 #define sg_dma_address(sg)      ((sg)->dma_address)
 #define sg_dma_len(sg)          ((sg)->length)
 
diff --git a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
index 1bd1142..15b4c7d 100644
--- a/include/asm-m68knommu/system.h
+++ b/include/asm-m68knommu/system.h
@@ -104,8 +104,7 @@
 #define mb()   asm volatile (""   : : :"memory")
 #define rmb()  asm volatile (""   : : :"memory")
 #define wmb()  asm volatile (""   : : :"memory")
-#define set_rmb(var, value)    do { xchg(&var, value); } while (0)
-#define set_mb(var, value)     set_rmb(var, value)
+#define set_mb(var, value) do { xchg(&var, value); } while (0)
 
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()
diff --git a/include/asm-m68knommu/tlbflush.h b/include/asm-m68knommu/tlbflush.h
index de858db..a470cfb 100644
--- a/include/asm-m68knommu/tlbflush.h
+++ b/include/asm-m68knommu/tlbflush.h
@@ -52,10 +52,4 @@
 	BUG();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-	BUG();
-}
-
 #endif /* _M68KNOMMU_TLBFLUSH_H */
diff --git a/include/asm-m68knommu/uaccess.h b/include/asm-m68knommu/uaccess.h
index 9ed9169..68bbe9b 100644
--- a/include/asm-m68knommu/uaccess.h
+++ b/include/asm-m68knommu/uaccess.h
@@ -170,10 +170,12 @@
  */
 
 static inline unsigned long
-clear_user(void *to, unsigned long n)
+__clear_user(void *to, unsigned long n)
 {
 	memset(to, 0, n);
 	return 0;
 }
 
+#define	clear_user(to,n)	__clear_user(to,n)
+
 #endif /* _M68KNOMMU_UACCESS_H */
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index 899357a..ec75ce4 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -9,6 +9,10 @@
 #ifndef _ASM_BITOPS_H
 #define _ASM_BITOPS_H
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <linux/irqflags.h>
 #include <linux/types.h>
@@ -172,6 +176,20 @@
 }
 
 /*
+ * clear_bit_unlock - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit() is atomic and implies release semantics before the memory
+ * operation. It can be used for an unlock.
+ */
+static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
+{
+	smp_mb__before_clear_bit();
+	clear_bit(nr, addr);
+}
+
+/*
  * change_bit - Toggle a bit in memory
  * @nr: Bit to change
  * @addr: Address to start counting from
@@ -240,6 +258,8 @@
 	unsigned short bit = nr & SZLONG_MASK;
 	unsigned long res;
 
+	smp_llsc_mb();
+
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
@@ -295,6 +315,73 @@
 }
 
 /*
+ * test_and_set_bit_lock - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and implies acquire ordering semantics
+ * after the memory operation.
+ */
+static inline int test_and_set_bit_lock(unsigned long nr,
+	volatile unsigned long *addr)
+{
+	unsigned short bit = nr & SZLONG_MASK;
+	unsigned long res;
+
+	if (cpu_has_llsc && R10000_LLSC_WAR) {
+		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+		unsigned long temp;
+
+		__asm__ __volatile__(
+		"	.set	mips3					\n"
+		"1:	" __LL "%0, %1		# test_and_set_bit	\n"
+		"	or	%2, %0, %3				\n"
+		"	" __SC	"%2, %1					\n"
+		"	beqzl	%2, 1b					\n"
+		"	and	%2, %0, %3				\n"
+		"	.set	mips0					\n"
+		: "=&r" (temp), "=m" (*m), "=&r" (res)
+		: "r" (1UL << bit), "m" (*m)
+		: "memory");
+	} else if (cpu_has_llsc) {
+		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+		unsigned long temp;
+
+		__asm__ __volatile__(
+		"	.set	push					\n"
+		"	.set	noreorder				\n"
+		"	.set	mips3					\n"
+		"1:	" __LL "%0, %1		# test_and_set_bit	\n"
+		"	or	%2, %0, %3				\n"
+		"	" __SC	"%2, %1					\n"
+		"	beqz	%2, 2f					\n"
+		"	 and	%2, %0, %3				\n"
+		"	.subsection 2					\n"
+		"2:	b	1b					\n"
+		"	 nop						\n"
+		"	.previous					\n"
+		"	.set	pop					\n"
+		: "=&r" (temp), "=m" (*m), "=&r" (res)
+		: "r" (1UL << bit), "m" (*m)
+		: "memory");
+	} else {
+		volatile unsigned long *a = addr;
+		unsigned long mask;
+		unsigned long flags;
+
+		a += nr >> SZLONG_LOG;
+		mask = 1UL << bit;
+		raw_local_irq_save(flags);
+		res = (mask & *a);
+		*a |= mask;
+		raw_local_irq_restore(flags);
+	}
+
+	smp_llsc_mb();
+
+	return res != 0;
+}
+/*
  * test_and_clear_bit - Clear a bit and return its old value
  * @nr: Bit to clear
  * @addr: Address to count from
@@ -308,6 +395,8 @@
 	unsigned short bit = nr & SZLONG_MASK;
 	unsigned long res;
 
+	smp_llsc_mb();
+
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
@@ -396,6 +485,8 @@
 	unsigned short bit = nr & SZLONG_MASK;
 	unsigned long res;
 
+	smp_llsc_mb();
+
 	if (cpu_has_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
@@ -453,6 +544,21 @@
 #include <asm-generic/bitops/non-atomic.h>
 
 /*
+ * __clear_bit_unlock - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * __clear_bit() is non-atomic and implies release semantics before the memory
+ * operation. It can be used for an unlock if no other CPUs can concurrently
+ * modify other bits in the word.
+ */
+static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
+{
+	smp_mb();
+	__clear_bit(nr, addr);
+}
+
+/*
  * Return the bit position (0..63) of the most significant 1 bit in a word
  * Returns -1 if no 1 bit exists
  */
diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h
index 483685b..e59d4c0 100644
--- a/include/asm-mips/fpu.h
+++ b/include/asm-mips/fpu.h
@@ -12,12 +12,12 @@
 
 #include <linux/sched.h>
 #include <linux/thread_info.h>
+#include <linux/bitops.h>
 
 #include <asm/mipsregs.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
 #include <asm/hazards.h>
-#include <asm/bitops.h>
 #include <asm/processor.h>
 #include <asm/current.h>
 
diff --git a/include/asm-mips/gt64120.h b/include/asm-mips/gt64120.h
index 4bf8e28..e64b410 100644
--- a/include/asm-mips/gt64120.h
+++ b/include/asm-mips/gt64120.h
@@ -21,6 +21,8 @@
 #ifndef _ASM_GT64120_H
 #define _ASM_GT64120_H
 
+#include <linux/clocksource.h>
+
 #include <asm/addrspace.h>
 #include <asm/byteorder.h>
 
@@ -572,4 +574,7 @@
 #define GT_READ(ofs)		le32_to_cpu(__GT_READ(ofs))
 #define GT_WRITE(ofs, data)	__GT_WRITE(ofs, cpu_to_le32(data))
 
+extern void gt641xx_set_base_clock(unsigned int clock);
+extern int gt641xx_timer0_state(void);
+
 #endif /* _ASM_GT64120_H */
diff --git a/include/asm-mips/i8253.h b/include/asm-mips/i8253.h
index 8f689d7..affb32c 100644
--- a/include/asm-mips/i8253.h
+++ b/include/asm-mips/i8253.h
@@ -2,8 +2,8 @@
  *  Machine specific IO port address definition for generic.
  *  Written by Osamu Tomita <tomita@cinet.co.jp>
  */
-#ifndef _MACH_IO_PORTS_H
-#define _MACH_IO_PORTS_H
+#ifndef __ASM_I8253_H
+#define __ASM_I8253_H
 
 /* i8253A PIT registers */
 #define PIT_MODE		0x43
@@ -27,4 +27,4 @@
 
 extern void setup_pit_timer(void);
 
-#endif /* !_MACH_IO_PORTS_H */
+#endif /* __ASM_I8253_H */
diff --git a/include/asm-mips/ip32/crime.h b/include/asm-mips/ip32/crime.h
index a13702f..7c36b0e 100644
--- a/include/asm-mips/ip32/crime.h
+++ b/include/asm-mips/ip32/crime.h
@@ -17,9 +17,6 @@
  */
 #define CRIME_BASE	0x14000000	/* physical */
 
-#undef BIT
-#define BIT(x)	(1UL << (x))
-
 struct sgi_crime {
 	volatile unsigned long id;
 #define CRIME_ID_MASK			0xff
diff --git a/include/asm-mips/ip32/mace.h b/include/asm-mips/ip32/mace.h
index 990082c..d08d7c6 100644
--- a/include/asm-mips/ip32/mace.h
+++ b/include/asm-mips/ip32/mace.h
@@ -17,9 +17,6 @@
  */
 #define MACE_BASE	0x1f000000	/* physical */
 
-#undef BIT
-#define BIT(x) (1UL << (x))
-
 /*
  * PCI interface
  */
diff --git a/include/asm-mips/mach-generic/ide.h b/include/asm-mips/mach-generic/ide.h
index a771283..4ec2b93 100644
--- a/include/asm-mips/mach-generic/ide.h
+++ b/include/asm-mips/mach-generic/ide.h
@@ -98,7 +98,6 @@
 	}
 }
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)	((base) + 0x206) /* obsolete */
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/include/asm-mips/mach-ip27/kernel-entry-init.h b/include/asm-mips/mach-ip27/kernel-entry-init.h
index c1a1031..624d66c 100644
--- a/include/asm-mips/mach-ip27/kernel-entry-init.h
+++ b/include/asm-mips/mach-ip27/kernel-entry-init.h
@@ -46,7 +46,14 @@
 	lh	t1, KV_RO_NASID_OFFSET(t0)
 	lh	t2, KV_RW_NASID_OFFSET(t0)
 	MAPPED_KERNEL_SETUP_TLB
-	ARC64_TWIDDLE_PC
+
+	/*
+	 * We might not get launched at the address the kernel is linked to,
+	 * so we jump there.
+	 */
+	PTR_LA  t0, 0f
+	jr      t0
+0:
 	.endm
 
 #endif /* __ASM_MACH_IP27_KERNEL_ENTRY_H */
diff --git a/include/asm-mips/pci/bridge.h b/include/asm-mips/pci/bridge.h
index b84feeb..5f4b9d4 100644
--- a/include/asm-mips/pci/bridge.h
+++ b/include/asm-mips/pci/bridge.h
@@ -538,7 +538,7 @@
 		 BRIDGE_ISR_PMU_ESIZE_FAULT)
 
 /*
- * List of Errors which are fatal and kill the sytem
+ * List of Errors which are fatal and kill the system
  */
 #define BRIDGE_ISR_ERROR_FATAL		\
 		((BRIDGE_ISR_XTALK_ERROR & ~BRIDGE_ISR_XREAD_REQ_TIMEOUT)|\
diff --git a/include/asm-mips/scatterlist.h b/include/asm-mips/scatterlist.h
index 7af104c..83d69fe 100644
--- a/include/asm-mips/scatterlist.h
+++ b/include/asm-mips/scatterlist.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page *	page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h
index 494aa65..0dad844 100644
--- a/include/asm-mips/sibyte/sb1250.h
+++ b/include/asm-mips/sibyte/sb1250.h
@@ -45,13 +45,11 @@
 extern unsigned int periph_rev;
 extern unsigned int zbbus_mhz;
 
-extern void sb1250_hpt_setup(void);
 extern void sb1250_time_init(void);
 extern void sb1250_mask_irq(int cpu, int irq);
 extern void sb1250_unmask_irq(int cpu, int irq);
 extern void sb1250_smp_finish(void);
 
-extern void bcm1480_hpt_setup(void);
 extern void bcm1480_time_init(void);
 extern void bcm1480_mask_irq(int cpu, int irq);
 extern void bcm1480_unmask_irq(int cpu, int irq);
diff --git a/include/asm-mips/sni.h b/include/asm-mips/sni.h
index 4d43dbb..af08145 100644
--- a/include/asm-mips/sni.h
+++ b/include/asm-mips/sni.h
@@ -141,8 +141,6 @@
 #define A20R_PT_TIM0_ACK        0xbc050000
 #define A20R_PT_TIM1_ACK        0xbc060000
 
-#define SNI_MIPS_IRQ_CPU_TIMER  (MIPS_CPU_IRQ_BASE+7)
-
 #define SNI_A20R_IRQ_BASE       MIPS_CPU_IRQ_BASE
 #define SNI_A20R_IRQ_TIMER      (SNI_A20R_IRQ_BASE+5)
 
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h
index 35555bd..bc47af3 100644
--- a/include/asm-mips/time.h
+++ b/include/asm-mips/time.h
@@ -21,6 +21,7 @@
 #include <linux/ptrace.h>
 #include <linux/rtc.h>
 #include <linux/spinlock.h>
+#include <linux/clockchips.h>
 #include <linux/clocksource.h>
 
 extern spinlock_t rtc_lock;
@@ -40,7 +41,6 @@
  * mips_timer_ack may be NULL if the interrupt is self-recoverable.
  */
 extern int (*mips_timer_state)(void);
-extern void (*mips_timer_ack)(void);
 
 /*
  * High precision timer clocksource.
@@ -76,6 +76,16 @@
 /*
  * Initialize the calling CPU's compare interrupt as clockevent device
  */
+#ifdef CONFIG_CEVT_R4K
 extern void mips_clockevent_init(void);
+#else
+static inline void mips_clockevent_init(void)
+{
+}
+#endif
+
+extern void clocksource_set_clock(struct clocksource *cs, unsigned int clock);
+extern void clockevent_set_clock(struct clock_event_device *cd,
+		unsigned int clock);
 
 #endif /* _ASM_TIME_H */
diff --git a/include/asm-mips/tlbflush.h b/include/asm-mips/tlbflush.h
index 730e841f..86b21de 100644
--- a/include/asm-mips/tlbflush.h
+++ b/include/asm-mips/tlbflush.h
@@ -11,7 +11,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 extern void local_flush_tlb_all(void);
 extern void local_flush_tlb_mm(struct mm_struct *mm);
@@ -45,10 +44,4 @@
 
 #endif /* CONFIG_SMP */
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-	unsigned long start, unsigned long end)
-{
-	/* Nothing to do on MIPS.  */
-}
-
 #endif /* __ASM_TLBFLUSH_H */
diff --git a/include/asm-parisc/Kbuild b/include/asm-parisc/Kbuild
index c68e168..f88b252 100644
--- a/include/asm-parisc/Kbuild
+++ b/include/asm-parisc/Kbuild
@@ -1 +1,3 @@
 include include/asm-generic/Kbuild.asm
+
+unifdef-y += pdc.h
diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h
index 015cb0d..f8eebcb 100644
--- a/include/asm-parisc/bitops.h
+++ b/include/asm-parisc/bitops.h
@@ -1,6 +1,10 @@
 #ifndef _PARISC_BITOPS_H
 #define _PARISC_BITOPS_H
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/types.h>		/* for BITS_PER_LONG/SHIFT_PER_LONG */
 #include <asm/byteorder.h>
@@ -208,6 +212,7 @@
 
 #include <asm-generic/bitops/fls64.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/sched.h>
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-parisc/ide.h b/include/asm-parisc/ide.h
index b27bf7a..be8760f 100644
--- a/include/asm-parisc/ide.h
+++ b/include/asm-parisc/ide.h
@@ -17,7 +17,6 @@
 #define MAX_HWIFS	2
 #endif
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)	((base) + 0x206) /* obsolete */
 
 #define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
diff --git a/include/asm-parisc/io.h b/include/asm-parisc/io.h
index 95f00e1..55ddb18 100644
--- a/include/asm-parisc/io.h
+++ b/include/asm-parisc/io.h
@@ -138,7 +138,7 @@
 /* Most machines react poorly to I/O-space being cacheable... Instead let's
  * define ioremap() in terms of ioremap_nocache().
  */
-extern inline void __iomem * ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap(unsigned long offset, unsigned long size)
 {
 	return __ioremap(offset, size, _PAGE_NO_CACHE);
 }
diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h
index f6bba4c..b59a150 100644
--- a/include/asm-parisc/page.h
+++ b/include/asm-parisc/page.h
@@ -3,6 +3,8 @@
 
 #ifdef __KERNEL__
 
+#include <linux/const.h>
+
 #if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
 # define PAGE_SHIFT	12
 #elif defined(CONFIG_PARISC_PAGE_SIZE_16KB)
@@ -12,7 +14,7 @@
 #else
 # error "unknown default kernel page size"
 #endif
-#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK	(~(PAGE_SIZE-1))
 
 
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
index 61fbd57..4ba868f 100644
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -207,7 +207,7 @@
 extern void pcibios_register_hba(struct pci_hba_data *);
 extern void pcibios_set_master(struct pci_dev *);
 #else
-extern inline void pcibios_register_hba(struct pci_hba_data *x)
+static inline void pcibios_register_hba(struct pci_hba_data *x)
 {
 }
 #endif
diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h
index 876fd81..5e0c3ca 100644
--- a/include/asm-parisc/pdc.h
+++ b/include/asm-parisc/pdc.h
@@ -1,7 +1,6 @@
 #ifndef _PARISC_PDC_H
 #define _PARISC_PDC_H
 
-
 /*
  *	PDC return values ...
  *	All PDC calls return a subset of these errors. 
@@ -20,7 +19,6 @@
 #define PDC_BUS_POW_WARN	-12	/* Call could not complete in allowed power budget */
 #define PDC_NOT_NARROW		-17	/* Narrow mode not supported	*/
 
-
 /*
  *	PDC entry points...
  */
@@ -50,6 +48,12 @@
 #define PDC_MODEL_DISPEC	5	/* disable specific option	*/
 #define PDC_MODEL_CPU_ID	6	/* returns cpu-id (only newer machines!) */
 #define PDC_MODEL_CAPABILITIES	7	/* returns OS32/OS64-flags	*/
+/* Values for PDC_MODEL_CAPABILITIES non-equivalent virtual aliasing support */
+#define  PDC_MODEL_IOPDIR_FDC		(1 << 2)
+#define  PDC_MODEL_NVA_MASK		(3 << 4)
+#define  PDC_MODEL_NVA_SUPPORTED	(0 << 4)
+#define  PDC_MODEL_NVA_SLOW		(1 << 4)
+#define  PDC_MODEL_NVA_UNSUPPORTED	(3 << 4)
 #define PDC_MODEL_GET_BOOT__OP	8	/* returns boot test options	*/
 #define PDC_MODEL_SET_BOOT__OP	9	/* set boot test options	*/
 
@@ -91,7 +95,7 @@
 #define PDC_TOD		9		/* time-of-day clock (TOD)	*/
 #define PDC_TOD_READ		0	/* read TOD			*/
 #define PDC_TOD_WRITE		1	/* write TOD			*/
-#define PDC_TOD_ITIMER		2	/* calibrate Interval Timer (CR16) */
+
 
 #define PDC_STABLE	10		/* stable storage (sprockets)	*/
 #define PDC_STABLE_READ		0
@@ -143,15 +147,6 @@
 #define PDC_MEM_RET_PDT_FULL		-11
 #define PDC_MEM_RET_INVALID_PHYSICAL_LOCATION ~0ULL
 
-#ifndef __ASSEMBLY__
-typedef struct {
-    unsigned long long	baseAddr;
-    unsigned int	pages;
-    unsigned int	reserved;
-} MemAddrTable_t;
-#endif
-
-
 #define PDC_PSW		21		/* Get/Set default System Mask  */
 #define PDC_PSW_MASK		0	/* Return mask                  */
 #define PDC_PSW_GET_DEFAULTS	1	/* Return defaults              */
@@ -274,6 +269,43 @@
 #define PDC_LINK_PCI_ENTRY_POINTS	0  /* list (Arg1) = 0 */
 #define PDC_LINK_USB_ENTRY_POINTS	1  /* list (Arg1) = 1 */
 
+/* cl_class
+ * page 3-33 of IO-Firmware ARS
+ * IODC ENTRY_INIT(Search first) RET[1]
+ */
+#define	CL_NULL		0	/* invalid */
+#define	CL_RANDOM	1	/* random access (as disk) */
+#define	CL_SEQU		2	/* sequential access (as tape) */
+#define	CL_DUPLEX	7	/* full-duplex point-to-point (RS-232, Net) */
+#define	CL_KEYBD	8	/* half-duplex console (HIL Keyboard) */
+#define	CL_DISPL	9	/* half-duplex console (display) */
+#define	CL_FC		10	/* FiberChannel access media */
+
+/* IODC ENTRY_INIT() */
+#define ENTRY_INIT_SRCH_FRST	2
+#define ENTRY_INIT_SRCH_NEXT	3
+#define ENTRY_INIT_MOD_DEV	4
+#define ENTRY_INIT_DEV		5
+#define ENTRY_INIT_MOD		6
+#define ENTRY_INIT_MSG		9
+
+/* IODC ENTRY_IO() */
+#define ENTRY_IO_BOOTIN		0
+#define ENTRY_IO_BOOTOUT	1
+#define ENTRY_IO_CIN		2
+#define ENTRY_IO_COUT		3
+#define ENTRY_IO_CLOSE		4
+#define ENTRY_IO_GETMSG		9
+#define ENTRY_IO_BBLOCK_IN	16
+#define ENTRY_IO_BBLOCK_OUT	17
+
+/* IODC ENTRY_SPA() */
+
+/* IODC ENTRY_CONFIG() */
+
+/* IODC ENTRY_TEST() */
+
+/* IODC ENTRY_TLB() */
 
 /* constants for OS (NVM...) */
 #define OS_ID_NONE		0	/* Undefined OS ID	*/
@@ -295,7 +327,13 @@
 #define OSTAT_RUN		6
 #define OSTAT_ON		7
 
-#ifndef __ASSEMBLY__
+/* Page Zero constant offsets used by the HPMC handler */
+#define BOOT_CONSOLE_HPA_OFFSET  0x3c0
+#define BOOT_CONSOLE_SPA_OFFSET  0x3c4
+#define BOOT_CONSOLE_PATH_OFFSET 0x3a8
+
+#if !defined(__ASSEMBLY__)
+#ifdef __KERNEL__
 
 #include <linux/types.h>
 
@@ -331,14 +369,6 @@
 	unsigned long curr_key;
 };
 
-/* Values for PDC_MODEL_CAPABILITIES non-equivalent virtual aliasing support */
-
-#define PDC_MODEL_IOPDIR_FDC            (1 << 2)        /* see sba_iommu.c */
-#define PDC_MODEL_NVA_MASK		(3 << 4)
-#define PDC_MODEL_NVA_SUPPORTED		(0 << 4)
-#define PDC_MODEL_NVA_SLOW		(1 << 4)
-#define PDC_MODEL_NVA_UNSUPPORTED	(3 << 4)
-
 struct pdc_cache_cf {		/* for PDC_CACHE  (I/D-caches) */
     unsigned long
 #ifdef CONFIG_64BIT
@@ -558,156 +588,6 @@
 	__u64 fr[32];
 };
 
-#endif /* __ASSEMBLY__ */
-
-/* flags of the device_path (see below) */
-#define	PF_AUTOBOOT	0x80
-#define	PF_AUTOSEARCH	0x40
-#define	PF_TIMER	0x0F
-
-#ifndef __ASSEMBLY__
-
-struct device_path {		/* page 1-69 */
-	unsigned char flags;	/* flags see above! */
-	unsigned char bc[6];	/* bus converter routing info */
-	unsigned char mod;
-	unsigned int  layers[6];/* device-specific layer-info */
-} __attribute__((aligned(8))) ;
-
-struct pz_device {
-	struct	device_path dp;	/* see above */
-	/* struct	iomod *hpa; */
-	unsigned int hpa;	/* HPA base address */
-	/* char	*spa; */
-	unsigned int spa;	/* SPA base address */
-	/* int	(*iodc_io)(struct iomod*, ...); */
-	unsigned int iodc_io;	/* device entry point */
-	short	pad;		/* reserved */
-	unsigned short cl_class;/* see below */
-} __attribute__((aligned(8))) ;
-
-#endif /* __ASSEMBLY__ */
-
-/* cl_class
- * page 3-33 of IO-Firmware ARS
- * IODC ENTRY_INIT(Search first) RET[1]
- */
-#define	CL_NULL		0	/* invalid */
-#define	CL_RANDOM	1	/* random access (as disk) */
-#define	CL_SEQU		2	/* sequential access (as tape) */
-#define	CL_DUPLEX	7	/* full-duplex point-to-point (RS-232, Net) */
-#define	CL_KEYBD	8	/* half-duplex console (HIL Keyboard) */
-#define	CL_DISPL	9	/* half-duplex console (display) */
-#define	CL_FC		10	/* FiberChannel access media */
-
-#if 0
-/* FIXME: DEVCLASS_* duplicates CL_* (above).  Delete DEVCLASS_*? */
-#define DEVCLASS_RANDOM		1
-#define DEVCLASS_SEQU		2
-#define DEVCLASS_DUPLEX		7
-#define DEVCLASS_KEYBD		8
-#define DEVCLASS_DISP		9
-#endif
-
-/* IODC ENTRY_INIT() */
-#define ENTRY_INIT_SRCH_FRST	2
-#define ENTRY_INIT_SRCH_NEXT	3
-#define ENTRY_INIT_MOD_DEV	4
-#define ENTRY_INIT_DEV		5
-#define ENTRY_INIT_MOD		6
-#define ENTRY_INIT_MSG		9
-
-/* IODC ENTRY_IO() */
-#define ENTRY_IO_BOOTIN		0
-#define ENTRY_IO_BOOTOUT	1
-#define ENTRY_IO_CIN		2
-#define ENTRY_IO_COUT		3
-#define ENTRY_IO_CLOSE		4
-#define ENTRY_IO_GETMSG		9
-#define ENTRY_IO_BBLOCK_IN	16
-#define ENTRY_IO_BBLOCK_OUT	17
-
-/* IODC ENTRY_SPA() */
-
-/* IODC ENTRY_CONFIG() */
-
-/* IODC ENTRY_TEST() */
-
-/* IODC ENTRY_TLB() */
-
-
-/* DEFINITION OF THE ZERO-PAGE (PAG0) */
-/* based on work by Jason Eckhardt (jason@equator.com) */
-
-#ifndef __ASSEMBLY__
-
-#define PAGE0   ((struct zeropage *)__PAGE_OFFSET)
-
-struct zeropage {
-	/* [0x000] initialize vectors (VEC) */
-	unsigned int	vec_special;		/* must be zero */
-	/* int	(*vec_pow_fail)(void);*/
-	unsigned int	vec_pow_fail; /* power failure handler */
-	/* int	(*vec_toc)(void); */
-	unsigned int	vec_toc;
-	unsigned int	vec_toclen;
-	/* int	(*vec_rendz)(void); */
-	unsigned int vec_rendz;
-	int	vec_pow_fail_flen;
-	int	vec_pad[10];		
-	
-	/* [0x040] reserved processor dependent */
-	int	pad0[112];
-
-	/* [0x200] reserved */
-	int	pad1[84];
-
-	/* [0x350] memory configuration (MC) */
-	int	memc_cont;		/* contiguous mem size (bytes) */
-	int	memc_phsize;		/* physical memory size */
-	int	memc_adsize;		/* additional mem size, bytes of SPA space used by PDC */
-	unsigned int mem_pdc_hi;	/* used for 64-bit */
-
-	/* [0x360] various parameters for the boot-CPU */
-	/* unsigned int *mem_booterr[8]; */
-	unsigned int mem_booterr[8];	/* ptr to boot errors */
-	unsigned int mem_free;		/* first location, where OS can be loaded */
-	/* struct iomod *mem_hpa; */
-	unsigned int mem_hpa;		/* HPA of the boot-CPU */
-	/* int (*mem_pdc)(int, ...); */
-	unsigned int mem_pdc;		/* PDC entry point */
-	unsigned int mem_10msec;	/* number of clock ticks in 10msec */
-
-	/* [0x390] initial memory module (IMM) */
-	/* struct iomod *imm_hpa; */
-	unsigned int imm_hpa;		/* HPA of the IMM */
-	int	imm_soft_boot;		/* 0 = was hard boot, 1 = was soft boot */
-	unsigned int	imm_spa_size;		/* SPA size of the IMM in bytes */
-	unsigned int	imm_max_mem;		/* bytes of mem in IMM */
-
-	/* [0x3A0] boot console, display device and keyboard */
-	struct pz_device mem_cons;	/* description of console device */
-	struct pz_device mem_boot;	/* description of boot device */
-	struct pz_device mem_kbd;	/* description of keyboard device */
-
-	/* [0x430] reserved */
-	int	pad430[116];
-
-	/* [0x600] processor dependent */
-	__u32	pad600[1];
-	__u32	proc_sti;		/* pointer to STI ROM */
-	__u32	pad608[126];
-};
-
-#endif /* __ASSEMBLY__ */
-
-/* Page Zero constant offsets used by the HPMC handler */
-
-#define BOOT_CONSOLE_HPA_OFFSET  0x3c0
-#define BOOT_CONSOLE_SPA_OFFSET  0x3c4
-#define BOOT_CONSOLE_PATH_OFFSET 0x3a8
-
-#ifndef __ASSEMBLY__
 void pdc_console_init(void);	/* in pdc_console.c */
 void pdc_console_restart(void);
 
@@ -724,7 +604,7 @@
 		  void *iodc_data, unsigned int iodc_data_size);
 int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
 			     struct pdc_module_path *mod_path, long mod_index);
-int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info, 
+int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info,
 			      long mod_index, long addr_index);
 int pdc_model_info(struct pdc_model *model);
 int pdc_model_sysmodel(char *name);
@@ -786,6 +666,94 @@
 	default:	return "Unknown";
 	}
 }
-#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#define PAGE0   ((struct zeropage *)__PAGE_OFFSET)
+
+/* DEFINITION OF THE ZERO-PAGE (PAG0) */
+/* based on work by Jason Eckhardt (jason@equator.com) */
+
+/* flags of the device_path */
+#define	PF_AUTOBOOT	0x80
+#define	PF_AUTOSEARCH	0x40
+#define	PF_TIMER	0x0F
+
+struct device_path {		/* page 1-69 */
+	unsigned char flags;	/* flags see above! */
+	unsigned char bc[6];	/* bus converter routing info */
+	unsigned char mod;
+	unsigned int  layers[6];/* device-specific layer-info */
+} __attribute__((aligned(8))) ;
+
+struct pz_device {
+	struct	device_path dp;	/* see above */
+	/* struct	iomod *hpa; */
+	unsigned int hpa;	/* HPA base address */
+	/* char	*spa; */
+	unsigned int spa;	/* SPA base address */
+	/* int	(*iodc_io)(struct iomod*, ...); */
+	unsigned int iodc_io;	/* device entry point */
+	short	pad;		/* reserved */
+	unsigned short cl_class;/* see below */
+} __attribute__((aligned(8))) ;
+
+struct zeropage {
+	/* [0x000] initialize vectors (VEC) */
+	unsigned int	vec_special;		/* must be zero */
+	/* int	(*vec_pow_fail)(void);*/
+	unsigned int	vec_pow_fail; /* power failure handler */
+	/* int	(*vec_toc)(void); */
+	unsigned int	vec_toc;
+	unsigned int	vec_toclen;
+	/* int	(*vec_rendz)(void); */
+	unsigned int vec_rendz;
+	int	vec_pow_fail_flen;
+	int	vec_pad[10];		
+	
+	/* [0x040] reserved processor dependent */
+	int	pad0[112];
+
+	/* [0x200] reserved */
+	int	pad1[84];
+
+	/* [0x350] memory configuration (MC) */
+	int	memc_cont;		/* contiguous mem size (bytes) */
+	int	memc_phsize;		/* physical memory size */
+	int	memc_adsize;		/* additional mem size, bytes of SPA space used by PDC */
+	unsigned int mem_pdc_hi;	/* used for 64-bit */
+
+	/* [0x360] various parameters for the boot-CPU */
+	/* unsigned int *mem_booterr[8]; */
+	unsigned int mem_booterr[8];	/* ptr to boot errors */
+	unsigned int mem_free;		/* first location, where OS can be loaded */
+	/* struct iomod *mem_hpa; */
+	unsigned int mem_hpa;		/* HPA of the boot-CPU */
+	/* int (*mem_pdc)(int, ...); */
+	unsigned int mem_pdc;		/* PDC entry point */
+	unsigned int mem_10msec;	/* number of clock ticks in 10msec */
+
+	/* [0x390] initial memory module (IMM) */
+	/* struct iomod *imm_hpa; */
+	unsigned int imm_hpa;		/* HPA of the IMM */
+	int	imm_soft_boot;		/* 0 = was hard boot, 1 = was soft boot */
+	unsigned int	imm_spa_size;		/* SPA size of the IMM in bytes */
+	unsigned int	imm_max_mem;		/* bytes of mem in IMM */
+
+	/* [0x3A0] boot console, display device and keyboard */
+	struct pz_device mem_cons;	/* description of console device */
+	struct pz_device mem_boot;	/* description of boot device */
+	struct pz_device mem_kbd;	/* description of keyboard device */
+
+	/* [0x430] reserved */
+	int	pad430[116];
+
+	/* [0x600] processor dependent */
+	__u32	pad600[1];
+	__u32	proc_sti;		/* pointer to STI ROM */
+	__u32	pad608[126];
+};
+
+#endif /* !defined(__ASSEMBLY__) */
 
 #endif /* _PARISC_PDC_H */
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
index e88cacd..cd0fa4f 100644
--- a/include/asm-parisc/pgtable.h
+++ b/include/asm-parisc/pgtable.h
@@ -11,9 +11,9 @@
  */
 
 #include <linux/mm.h>		/* for vm_area_struct */
+#include <linux/bitops.h>
 #include <asm/processor.h>
 #include <asm/cache.h>
-#include <asm/bitops.h>
 
 /*
  * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel
@@ -49,14 +49,6 @@
 #define pgd_ERROR(e) \
 	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
 
- /* Note: If you change ISTACK_SIZE, you need to change the corresponding
-  * values in vmlinux.lds and vmlinux64.lds (init_istack section). Also,
-  * the "order" and size need to agree.
-  */
-
-#define  ISTACK_SIZE  32768 /* Interrupt Stack Size */
-#define  ISTACK_ORDER 3
-
 /* This is the size of the initially mapped kernel memory */
 #ifdef CONFIG_64BIT
 #define KERNEL_INITIAL_ORDER	24	/* 0 to 1<<24 = 16MB */
@@ -325,27 +317,27 @@
  * setup: the pgd is never bad, and a pmd always exists (as it's folded
  * into the pgd entry)
  */
-extern inline int pgd_none(pgd_t pgd)		{ return 0; }
-extern inline int pgd_bad(pgd_t pgd)		{ return 0; }
-extern inline int pgd_present(pgd_t pgd)	{ return 1; }
-extern inline void pgd_clear(pgd_t * pgdp)	{ }
+static inline int pgd_none(pgd_t pgd)		{ return 0; }
+static inline int pgd_bad(pgd_t pgd)		{ return 0; }
+static inline int pgd_present(pgd_t pgd)	{ return 1; }
+static inline void pgd_clear(pgd_t * pgdp)	{ }
 #endif
 
 /*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
-extern inline int pte_dirty(pte_t pte)		{ return pte_val(pte) & _PAGE_DIRTY; }
-extern inline int pte_young(pte_t pte)		{ return pte_val(pte) & _PAGE_ACCESSED; }
-extern inline int pte_write(pte_t pte)		{ return pte_val(pte) & _PAGE_WRITE; }
-extern inline int pte_file(pte_t pte)		{ return pte_val(pte) & _PAGE_FILE; }
+static inline int pte_dirty(pte_t pte)		{ return pte_val(pte) & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte)		{ return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_write(pte_t pte)		{ return pte_val(pte) & _PAGE_WRITE; }
+static inline int pte_file(pte_t pte)		{ return pte_val(pte) & _PAGE_FILE; }
 
-extern inline pte_t pte_mkclean(pte_t pte)	{ pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkold(pte_t pte)	{ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_wrprotect(pte_t pte)	{ pte_val(pte) &= ~_PAGE_WRITE; return pte; }
-extern inline pte_t pte_mkdirty(pte_t pte)	{ pte_val(pte) |= _PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkyoung(pte_t pte)	{ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_mkwrite(pte_t pte)	{ pte_val(pte) |= _PAGE_WRITE; return pte; }
+static inline pte_t pte_mkclean(pte_t pte)	{ pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkold(pte_t pte)	{ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_wrprotect(pte_t pte)	{ pte_val(pte) &= ~_PAGE_WRITE; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte)	{ pte_val(pte) |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte)	{ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte)	{ pte_val(pte) |= _PAGE_WRITE; return pte; }
 
 /*
  * Conversion functions: convert a page and protection to a page entry,
@@ -369,7 +361,7 @@
 	return pte;
 }
 
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
 
 /* Permanent address of a page.  On parisc we don't have highmem. */
diff --git a/include/asm-parisc/prefetch.h b/include/asm-parisc/prefetch.h
index 5d02172..c5edc60 100644
--- a/include/asm-parisc/prefetch.h
+++ b/include/asm-parisc/prefetch.h
@@ -19,7 +19,7 @@
 #ifdef CONFIG_PREFETCH
 
 #define ARCH_HAS_PREFETCH
-extern inline void prefetch(const void *addr)
+static inline void prefetch(const void *addr)
 {
 	__asm__("ldw 0(%0), %%r0" : : "r" (addr));
 }
@@ -27,7 +27,7 @@
 /* LDD is a PA2.0 addition. */
 #ifdef CONFIG_PA20
 #define ARCH_HAS_PREFETCHW
-extern inline void prefetchw(const void *addr)
+static inline void prefetchw(const void *addr)
 {
 	__asm__("ldd 0(%0), %%r0" : : "r" (addr));
 }
diff --git a/include/asm-parisc/rtc.h b/include/asm-parisc/rtc.h
index f4ebff1..099d641 100644
--- a/include/asm-parisc/rtc.h
+++ b/include/asm-parisc/rtc.h
@@ -50,10 +50,10 @@
 	long int days, rem, y;
 	const unsigned short int *ip;
 
-	if(pdc_tod_read(&tod_data) < 0)
+	memset(wtime, 0, sizeof(*wtime));
+	if (pdc_tod_read(&tod_data) < 0)
 		return RTC_24H | RTC_BATT_BAD;
 
-
 	// most of the remainder of this function is:
 //	Copyright (C) 1991, 1993, 1997, 1998 Free Software Foundation, Inc.
 //	This was originally a part of the GNU C Library.
diff --git a/include/asm-parisc/scatterlist.h b/include/asm-parisc/scatterlist.h
index e7211c7..62269b3 100644
--- a/include/asm-parisc/scatterlist.h
+++ b/include/asm-parisc/scatterlist.h
@@ -5,7 +5,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page *page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long sg_magic;
+#endif
+	unsigned long page_link;
 	unsigned int offset;
 
 	unsigned int length;
@@ -15,7 +18,7 @@
 	__u32      iova_length; /* bytes mapped */
 };
 
-#define sg_virt_addr(sg) ((unsigned long)(page_address(sg->page) + sg->offset))
+#define sg_virt_addr(sg) ((unsigned long)sg_virt(sg))
 #define sg_dma_address(sg) ((sg)->iova)
 #define sg_dma_len(sg)     ((sg)->iova_length)
 
diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h
index b771dcf..a16271c 100644
--- a/include/asm-parisc/semaphore.h
+++ b/include/asm-parisc/semaphore.h
@@ -54,7 +54,7 @@
 
 #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
 
-extern inline void sema_init (struct semaphore *sem, int val)
+static inline void sema_init (struct semaphore *sem, int val)
 {
 	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
 }
@@ -82,7 +82,7 @@
  * interrupts while we're messing with the semaphore.  Sorry.
  */
 
-extern __inline__ void down(struct semaphore * sem)
+static inline void down(struct semaphore * sem)
 {
 	might_sleep();
 	spin_lock_irq(&sem->sentry);
@@ -94,7 +94,7 @@
 	spin_unlock_irq(&sem->sentry);
 }
 
-extern __inline__ int down_interruptible(struct semaphore * sem)
+static inline int down_interruptible(struct semaphore * sem)
 {
 	int ret = 0;
 	might_sleep();
@@ -112,7 +112,7 @@
  * down_trylock returns 0 on success, 1 if we failed to get the lock.
  * May not sleep, but must preserve irq state
  */
-extern __inline__ int down_trylock(struct semaphore * sem)
+static inline int down_trylock(struct semaphore * sem)
 {
 	unsigned long flags;
 	int count;
@@ -129,7 +129,7 @@
  * Note! This is subtle. We jump to wake people up only if
  * the semaphore was negative (== somebody was waiting on it).
  */
-extern __inline__ void up(struct semaphore * sem)
+static inline void up(struct semaphore * sem)
 {
 	unsigned long flags;
 
diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h
index 270cf30..b72ec66 100644
--- a/include/asm-parisc/tlbflush.h
+++ b/include/asm-parisc/tlbflush.h
@@ -57,10 +57,6 @@
 #endif
 }
 
-extern __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end)
-{
-}
- 
 static inline void flush_tlb_page(struct vm_area_struct *vma,
 	unsigned long addr)
 {
diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
index f74099b..081b4ae 100644
--- a/include/asm-parisc/unistd.h
+++ b/include/asm-parisc/unistd.h
@@ -797,8 +797,9 @@
 #define __NR_signalfd		(__NR_Linux + 302)
 #define __NR_timerfd		(__NR_Linux + 303)
 #define __NR_eventfd		(__NR_Linux + 304)
+#define __NR_fallocate		(__NR_Linux + 305)
 
-#define __NR_Linux_syscalls	(__NR_eventfd + 1)
+#define __NR_Linux_syscalls	(__NR_fallocate + 1)
 
 
 #define __IGNORE_select		/* newselect */
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
index 8144a27..733b4af 100644
--- a/include/asm-powerpc/bitops.h
+++ b/include/asm-powerpc/bitops.h
@@ -38,6 +38,10 @@
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/asm-compat.h>
 #include <asm/synch.h>
@@ -86,6 +90,24 @@
 	: "cc" );
 }
 
+static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
+{
+	unsigned long old;
+	unsigned long mask = BITOP_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+	__asm__ __volatile__(
+	LWSYNC_ON_SMP
+"1:"	PPC_LLARX "%0,0,%3	# clear_bit_unlock\n"
+	"andc	%0,%0,%2\n"
+	PPC405_ERR77(0,%3)
+	PPC_STLCX "%0,0,%3\n"
+	"bne-	1b"
+	: "=&r" (old), "+m" (*p)
+	: "r" (mask), "r" (p)
+	: "cc", "memory");
+}
+
 static __inline__ void change_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned long old;
@@ -125,6 +147,27 @@
 	return (old & mask) != 0;
 }
 
+static __inline__ int test_and_set_bit_lock(unsigned long nr,
+				       volatile unsigned long *addr)
+{
+	unsigned long old, t;
+	unsigned long mask = BITOP_MASK(nr);
+	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+	__asm__ __volatile__(
+"1:"	PPC_LLARX "%0,0,%3		# test_and_set_bit_lock\n"
+	"or	%1,%0,%2 \n"
+	PPC405_ERR77(0,%3)
+	PPC_STLCX "%1,0,%3 \n"
+	"bne-	1b"
+	ISYNC_ON_SMP
+	: "=&r" (old), "=&r" (t)
+	: "r" (mask), "r" (p)
+	: "cc", "memory");
+
+	return (old & mask) != 0;
+}
+
 static __inline__ int test_and_clear_bit(unsigned long nr,
 					 volatile unsigned long *addr)
 {
@@ -185,6 +228,12 @@
 
 #include <asm-generic/bitops/non-atomic.h>
 
+static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)
+{
+	__asm__ __volatile__(LWSYNC_ON_SMP "" ::: "memory");
+	__clear_bit(nr, addr);
+}
+
 /*
  * Return the zero-based bit position (LE, not IBM bit numbering) of
  * the most significant 1-bit in a double word.
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 65be95d..ff52013 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -285,9 +285,9 @@
 	BUG_ON(direction == DMA_NONE);
 
 	for_each_sg(sgl, sg, nents, i) {
-		BUG_ON(!sg->page);
-		__dma_sync_page(sg->page, sg->offset, sg->length, direction);
-		sg->dma_address = page_to_bus(sg->page) + sg->offset;
+		BUG_ON(!sg_page(sg));
+		__dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
+		sg->dma_address = page_to_bus(sg_page(sg)) + sg->offset;
 	}
 
 	return nents;
@@ -328,7 +328,7 @@
 	BUG_ON(direction == DMA_NONE);
 
 	for_each_sg(sgl, sg, nents, i)
-		__dma_sync_page(sg->page, sg->offset, sg->length, direction);
+		__dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
 }
 
 static inline void dma_sync_sg_for_device(struct device *dev,
@@ -341,7 +341,7 @@
 	BUG_ON(direction == DMA_NONE);
 
 	for_each_sg(sgl, sg, nents, i)
-		__dma_sync_page(sg->page, sg->offset, sg->length, direction);
+		__dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
 }
 
 static inline int dma_mapping_error(dma_addr_t dma_addr)
diff --git a/include/asm-powerpc/ide.h b/include/asm-powerpc/ide.h
index 1644e44..fd7f5a4 100644
--- a/include/asm-powerpc/ide.h
+++ b/include/asm-powerpc/ide.h
@@ -69,12 +69,11 @@
 
 #ifdef CONFIG_BLK_DEV_MPC8xx_IDE
 #define IDE_ARCH_ACK_INTR  1
-#define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1)
+#define ide_ack_intr(hwif) ((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1)
 #endif
 
 #endif /* __powerpc64__ */
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)	((base) + 0x206) /* obsolete */
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index bf14ab4..e44cdfc 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -522,7 +522,7 @@
 #else
 /*
  * Enforce synchronisation of stores vs. spin_unlock
- * (this does it explicitely, though our implementation of spin_unlock
+ * (this does it explicitly, though our implementation of spin_unlock
  * does it implicitely too)
  */
 static inline void mmiowb(void)
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index 870967e..4a82fdc 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -26,9 +26,9 @@
 #include <linux/spinlock.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <linux/bitops.h>
 #include <asm/machdep.h>
 #include <asm/types.h>
-#include <asm/bitops.h>
 
 #define IOMMU_PAGE_SHIFT      12
 #define IOMMU_PAGE_SIZE       (ASM_CONST(1) << IOMMU_PAGE_SHIFT)
diff --git a/include/asm-powerpc/mmu_context.h b/include/asm-powerpc/mmu_context.h
index f863ac2..9102b8b 100644
--- a/include/asm-powerpc/mmu_context.h
+++ b/include/asm-powerpc/mmu_context.h
@@ -8,7 +8,7 @@
 
 #ifndef CONFIG_PPC64
 #include <asm/atomic.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 /*
  * On 32-bit PowerPC 6xx/7xx/7xxx CPUs, we use a set of 16 VSIDs
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
index 24751df..fcb2ebb 100644
--- a/include/asm-powerpc/mpc52xx.h
+++ b/include/asm-powerpc/mpc52xx.h
@@ -18,6 +18,13 @@
 #include <asm/prom.h>
 #endif /* __ASSEMBLY__ */
 
+#include <linux/suspend.h>
+
+/* Variants of the 5200(B) */
+#define MPC5200_SVR		0x80110010
+#define MPC5200_SVR_MASK	0xfffffff0
+#define MPC5200B_SVR		0x80110020
+#define MPC5200B_SVR_MASK	0xfffffff0
 
 /* ======================================================================== */
 /* Structures mapping of some unit register set                             */
@@ -242,6 +249,7 @@
 #ifndef __ASSEMBLY__
 
 extern void __iomem * mpc52xx_find_and_map(const char *);
+extern void __iomem * mpc52xx_find_and_map_path(const char *path);
 extern unsigned int mpc52xx_find_ipb_freq(struct device_node *node);
 extern void mpc5200_setup_xlb_arbiter(void);
 extern void mpc52xx_declare_of_platform_devices(void);
@@ -251,6 +259,9 @@
 
 extern int __init mpc52xx_add_bridge(struct device_node *node);
 
+extern void __init mpc52xx_map_wdt(void);
+extern void mpc52xx_restart(char *cmd);
+
 #endif /* __ASSEMBLY__ */
 
 #ifdef CONFIG_PM
@@ -267,9 +278,9 @@
 extern int __init lite5200_pm_init(void);
 
 /* lite5200 calls mpc5200 suspend functions, so here they are */
-extern int mpc52xx_pm_prepare(suspend_state_t);
+extern int mpc52xx_pm_prepare(void);
 extern int mpc52xx_pm_enter(suspend_state_t);
-extern int mpc52xx_pm_finish(suspend_state_t);
+extern void mpc52xx_pm_finish(void);
 extern char saved_sram[0x4000]; /* reuse buffer from mpc52xx suspend */
 #endif
 #endif /* CONFIG_PM */
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index fcd7b42..f6dfce0 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -114,11 +114,12 @@
 	u64 user_time;			/* accumulated usermode TB ticks */
 	u64 system_time;		/* accumulated system TB ticks */
 	u64 startpurr;			/* PURR/TB value snapshot */
+	u64 startspurr;			/* SPURR value snapshot */
+	u64 purrdelta;			/* FIXME: document */
+	u64 spurrdelta;			/* FIXME: document */
 };
 
 extern struct paca_struct paca[];
 
-void setup_boot_paca(void);
-
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_PACA_H */
diff --git a/include/asm-powerpc/scatterlist.h b/include/asm-powerpc/scatterlist.h
index b075f61..fcf7d55 100644
--- a/include/asm-powerpc/scatterlist.h
+++ b/include/asm-powerpc/scatterlist.h
@@ -14,7 +14,10 @@
 #include <asm/dma.h>
 
 struct scatterlist {
-	struct page *page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long sg_magic;
+#endif
+	unsigned long page_link;
 	unsigned int offset;
 	unsigned int length;
 
diff --git a/include/asm-powerpc/tlbflush.h b/include/asm-powerpc/tlbflush.h
index a022f80..b6b036c 100644
--- a/include/asm-powerpc/tlbflush.h
+++ b/include/asm-powerpc/tlbflush.h
@@ -8,7 +8,6 @@
  *  - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  *
  *  This program is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU General Public License
@@ -174,15 +173,5 @@
  */
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
-/*
- * This is called in munmap when we have freed up some page-table
- * pages.  We don't need to do anything here, there's nothing special
- * about our page-table pages.  -- paulus
- */
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-}
-
 #endif /*__KERNEL__ */
 #endif /* _ASM_POWERPC_TLBFLUSH_H */
diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h
index a6441a0..b2e25d8 100644
--- a/include/asm-ppc/mmu_context.h
+++ b/include/asm-ppc/mmu_context.h
@@ -2,8 +2,9 @@
 #ifndef __PPC_MMU_CONTEXT_H
 #define __PPC_MMU_CONTEXT_H
 
+#include <linux/bitops.h>
+
 #include <asm/atomic.h>
-#include <asm/bitops.h>
 #include <asm/mmu.h>
 #include <asm/cputable.h>
 #include <asm-generic/mm_hooks.h>
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index cc45780..51df94c 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -33,6 +33,7 @@
 
 #define set_mb(var, value)	do { var = value; mb(); } while (0)
 
+#define AT_VECTOR_SIZE_ARCH 6 /* entries in ARCH_DLINFO */
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()
 #define smp_rmb()	rmb()
diff --git a/include/asm-ppc/time.h b/include/asm-ppc/time.h
index f7eadf6..81dbcd4 100644
--- a/include/asm-ppc/time.h
+++ b/include/asm-ppc/time.h
@@ -57,7 +57,7 @@
 /* Accessor functions for the timebase (RTC on 601) registers. */
 /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
 #ifdef CONFIG_6xx
-extern __inline__ int __attribute_pure__ __USE_RTC(void) {
+extern __inline__ int __pure __USE_RTC(void) {
 	return (mfspr(SPRN_PVR)>>16) == 1;
 }
 #else
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index f79c9b7..34d9a63 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -15,6 +15,10 @@
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 
 /*
@@ -746,6 +750,7 @@
 #include <asm-generic/bitops/fls64.h>
 
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 /*
  * ATTENTION: intel byte ordering convention for ext2 and minix !!
diff --git a/include/asm-s390/cpu.h b/include/asm-s390/cpu.h
new file mode 100644
index 0000000..352dde1
--- /dev/null
+++ b/include/asm-s390/cpu.h
@@ -0,0 +1,25 @@
+/*
+ *  include/asm-s390/cpu.h
+ *
+ *    Copyright IBM Corp. 2007
+ *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ */
+
+#ifndef _ASM_S390_CPU_H_
+#define _ASM_S390_CPU_H_
+
+#include <linux/types.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
+
+struct s390_idle_data {
+	spinlock_t lock;
+	unsigned int in_idle;
+	unsigned long long idle_count;
+	unsigned long long idle_enter;
+	unsigned long long idle_time;
+};
+
+DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
+
+#endif /* _ASM_S390_CPU_H_ */
diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h
index 501cb9b..05b8421 100644
--- a/include/asm-s390/mmu_context.h
+++ b/include/asm-s390/mmu_context.h
@@ -21,45 +21,43 @@
 
 #ifndef __s390x__
 #define LCTL_OPCODE "lctl"
-#define PGTABLE_BITS (_SEGMENT_TABLE|USER_STD_MASK)
 #else
 #define LCTL_OPCODE "lctlg"
-#define PGTABLE_BITS (_REGION_TABLE|USER_STD_MASK)
 #endif
 
-static inline void enter_lazy_tlb(struct mm_struct *mm,
-                                  struct task_struct *tsk)
+static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk)
 {
+	pgd_t *pgd = mm->pgd;
+	unsigned long asce_bits;
+
+	/* Calculate asce bits from the first pgd table entry. */
+	asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
+#ifdef CONFIG_64BIT
+	asce_bits |= _ASCE_TYPE_REGION3;
+#endif
+	S390_lowcore.user_asce = asce_bits | __pa(pgd);
+	if (switch_amode) {
+		/* Load primary space page table origin. */
+		pgd_t *shadow_pgd = get_shadow_table(pgd) ? : pgd;
+		S390_lowcore.user_exec_asce = asce_bits | __pa(shadow_pgd);
+		asm volatile(LCTL_OPCODE" 1,1,%0\n"
+			     : : "m" (S390_lowcore.user_exec_asce) );
+	} else
+		/* Load home space page table origin. */
+		asm volatile(LCTL_OPCODE" 13,13,%0"
+			     : : "m" (S390_lowcore.user_asce) );
 }
 
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
 			     struct task_struct *tsk)
 {
-	pgd_t *shadow_pgd = get_shadow_pgd(next->pgd);
-
-	if (prev != next) {
-		S390_lowcore.user_asce = (__pa(next->pgd) & PAGE_MASK) |
-					 PGTABLE_BITS;
-		if (shadow_pgd) {
-			/* Load primary/secondary space page table origin. */
-			S390_lowcore.user_exec_asce =
-				(__pa(shadow_pgd) & PAGE_MASK) | PGTABLE_BITS;
-			asm volatile(LCTL_OPCODE" 1,1,%0\n"
-				     LCTL_OPCODE" 7,7,%1"
-				     : : "m" (S390_lowcore.user_exec_asce),
-					 "m" (S390_lowcore.user_asce) );
-		} else if (switch_amode) {
-			/* Load primary space page table origin. */
-			asm volatile(LCTL_OPCODE" 1,1,%0"
-				     : : "m" (S390_lowcore.user_asce) );
-		} else
-			/* Load home space page table origin. */
-			asm volatile(LCTL_OPCODE" 13,13,%0"
-				     : : "m" (S390_lowcore.user_asce) );
-	}
+	if (unlikely(prev == next))
+		return;
 	cpu_set(smp_processor_id(), next->cpu_vm_mask);
+	update_mm(next, tsk);
 }
 
+#define enter_lazy_tlb(mm,tsk)	do { } while (0)
 #define deactivate_mm(tsk,mm)	do { } while (0)
 
 static inline void activate_mm(struct mm_struct *prev,
diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h
index ceec382..584d0ee 100644
--- a/include/asm-s390/page.h
+++ b/include/asm-s390/page.h
@@ -82,6 +82,7 @@
 #ifndef __s390x__
 
 typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pud; } pud_t;
 typedef struct {
         unsigned long pgd0;
         unsigned long pgd1;
@@ -90,6 +91,7 @@
         } pgd_t;
 
 #define pmd_val(x)      ((x).pmd)
+#define pud_val(x)	((x).pud)
 #define pgd_val(x)      ((x).pgd0)
 
 #else /* __s390x__ */
@@ -98,10 +100,12 @@
         unsigned long pmd0;
         unsigned long pmd1; 
         } pmd_t;
+typedef struct { unsigned long pud; } pud_t;
 typedef struct { unsigned long pgd; } pgd_t;
 
 #define pmd_val(x)      ((x).pmd0)
 #define pmd_val1(x)     ((x).pmd1)
+#define pud_val(x)	((x).pud)
 #define pgd_val(x)      ((x).pgd)
 
 #endif /* __s390x__ */
diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h
index e45d3c9..709dd17 100644
--- a/include/asm-s390/pgalloc.h
+++ b/include/asm-s390/pgalloc.h
@@ -19,140 +19,115 @@
 
 #define check_pgt_cache()	do {} while (0)
 
-/*
- * Page allocation orders.
- */
-#ifndef __s390x__
-# define PTE_ALLOC_ORDER	0
-# define PMD_ALLOC_ORDER	0
-# define PGD_ALLOC_ORDER	1
-#else /* __s390x__ */
-# define PTE_ALLOC_ORDER	0
-# define PMD_ALLOC_ORDER	2
-# define PGD_ALLOC_ORDER	2
-#endif /* __s390x__ */
+unsigned long *crst_table_alloc(struct mm_struct *, int);
+void crst_table_free(unsigned long *);
 
-/*
- * Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any.
- */
+unsigned long *page_table_alloc(int);
+void page_table_free(unsigned long *);
+
+static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
+{
+	*s = val;
+	n = (n / 256) - 1;
+	asm volatile(
+#ifdef CONFIG_64BIT
+		"	mvc	8(248,%0),0(%0)\n"
+#else
+		"	mvc	4(252,%0),0(%0)\n"
+#endif
+		"0:	mvc	256(256,%0),0(%0)\n"
+		"	la	%0,256(%0)\n"
+		"	brct	%1,0b\n"
+		: "+a" (s), "+d" (n));
+}
+
+static inline void crst_table_init(unsigned long *crst, unsigned long entry)
+{
+	clear_table(crst, entry, sizeof(unsigned long)*2048);
+	crst = get_shadow_table(crst);
+	if (crst)
+		clear_table(crst, entry, sizeof(unsigned long)*2048);
+}
+
+#ifndef __s390x__
+
+static inline unsigned long pgd_entry_type(struct mm_struct *mm)
+{
+	return _SEGMENT_ENTRY_EMPTY;
+}
+
+#define pud_alloc_one(mm,address)		({ BUG(); ((pud_t *)2); })
+#define pud_free(x)				do { } while (0)
+
+#define pmd_alloc_one(mm,address)		({ BUG(); ((pmd_t *)2); })
+#define pmd_free(x)				do { } while (0)
+
+#define pgd_populate(mm, pgd, pud)		BUG()
+#define pgd_populate_kernel(mm, pgd, pud)	BUG()
+
+#define pud_populate(mm, pud, pmd)		BUG()
+#define pud_populate_kernel(mm, pud, pmd)	BUG()
+
+#else /* __s390x__ */
+
+static inline unsigned long pgd_entry_type(struct mm_struct *mm)
+{
+	return _REGION3_ENTRY_EMPTY;
+}
+
+#define pud_alloc_one(mm,address)		({ BUG(); ((pud_t *)2); })
+#define pud_free(x)				do { } while (0)
+
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
+{
+	unsigned long *crst = crst_table_alloc(mm, s390_noexec);
+	if (crst)
+		crst_table_init(crst, _SEGMENT_ENTRY_EMPTY);
+	return (pmd_t *) crst;
+}
+#define pmd_free(pmd) crst_table_free((unsigned long *) pmd)
+
+#define pgd_populate(mm, pgd, pud)		BUG()
+#define pgd_populate_kernel(mm, pgd, pud)	BUG()
+
+static inline void pud_populate_kernel(struct mm_struct *mm,
+				       pud_t *pud, pmd_t *pmd)
+{
+	pud_val(*pud) = _REGION3_ENTRY | __pa(pmd);
+}
+
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+	pud_t *shadow_pud = get_shadow_table(pud);
+	pmd_t *shadow_pmd = get_shadow_table(pmd);
+
+	if (shadow_pud && shadow_pmd)
+		pud_populate_kernel(mm, shadow_pud, shadow_pmd);
+	pud_populate_kernel(mm, pud, pmd);
+}
+
+#endif /* __s390x__ */
 
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-	pgd_t *pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ALLOC_ORDER);
-	int i;
-
-	if (!pgd)
-		return NULL;
-	if (s390_noexec) {
-		pgd_t *shadow_pgd = (pgd_t *)
-			__get_free_pages(GFP_KERNEL, PGD_ALLOC_ORDER);
-		struct page *page = virt_to_page(pgd);
-
-		if (!shadow_pgd) {
-			free_pages((unsigned long) pgd, PGD_ALLOC_ORDER);
-			return NULL;
-		}
-		page->lru.next = (void *) shadow_pgd;
-	}
-	for (i = 0; i < PTRS_PER_PGD; i++)
-#ifndef __s390x__
-		pmd_clear(pmd_offset(pgd + i, i*PGDIR_SIZE));
-#else
-		pgd_clear(pgd + i);
-#endif
-	return pgd;
+	unsigned long *crst = crst_table_alloc(mm, s390_noexec);
+	if (crst)
+		crst_table_init(crst, pgd_entry_type(mm));
+	return (pgd_t *) crst;
 }
-
-static inline void pgd_free(pgd_t *pgd)
-{
-	pgd_t *shadow_pgd = get_shadow_pgd(pgd);
-
-	if (shadow_pgd)
-		free_pages((unsigned long) shadow_pgd, PGD_ALLOC_ORDER);
-	free_pages((unsigned long) pgd, PGD_ALLOC_ORDER);
-}
-
-#ifndef __s390x__
-/*
- * page middle directory allocation/free routines.
- * We use pmd cache only on s390x, so these are dummy routines. This
- * code never triggers because the pgd will always be present.
- */
-#define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
-#define pmd_free(x)                     do { } while (0)
-#define __pmd_free_tlb(tlb,x)		do { } while (0)
-#define pgd_populate(mm, pmd, pte)      BUG()
-#define pgd_populate_kernel(mm, pmd, pte)	BUG()
-#else /* __s390x__ */
-static inline pmd_t * pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
-{
-	pmd_t *pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, PMD_ALLOC_ORDER);
-	int i;
-
-	if (!pmd)
-		return NULL;
-	if (s390_noexec) {
-		pmd_t *shadow_pmd = (pmd_t *)
-			__get_free_pages(GFP_KERNEL, PMD_ALLOC_ORDER);
-		struct page *page = virt_to_page(pmd);
-
-		if (!shadow_pmd) {
-			free_pages((unsigned long) pmd, PMD_ALLOC_ORDER);
-			return NULL;
-		}
-		page->lru.next = (void *) shadow_pmd;
-	}
-	for (i=0; i < PTRS_PER_PMD; i++)
-		pmd_clear(pmd + i);
-	return pmd;
-}
-
-static inline void pmd_free (pmd_t *pmd)
-{
-	pmd_t *shadow_pmd = get_shadow_pmd(pmd);
-
-	if (shadow_pmd)
-		free_pages((unsigned long) shadow_pmd, PMD_ALLOC_ORDER);
-	free_pages((unsigned long) pmd, PMD_ALLOC_ORDER);
-}
-
-#define __pmd_free_tlb(tlb,pmd)			\
-	do {					\
-		tlb_flush_mmu(tlb, 0, 0);	\
-		pmd_free(pmd);			\
-	 } while (0)
-
-static inline void
-pgd_populate_kernel(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
-{
-	pgd_val(*pgd) = _PGD_ENTRY | __pa(pmd);
-}
-
-static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
-{
-	pgd_t *shadow_pgd = get_shadow_pgd(pgd);
-	pmd_t *shadow_pmd = get_shadow_pmd(pmd);
-
-	if (shadow_pgd && shadow_pmd)
-		pgd_populate_kernel(mm, shadow_pgd, shadow_pmd);
-	pgd_populate_kernel(mm, pgd, pmd);
-}
-
-#endif /* __s390x__ */
+#define pgd_free(pgd) crst_table_free((unsigned long *) pgd)
 
 static inline void 
 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
 {
 #ifndef __s390x__
-	pmd_val(pmd[0]) = _PAGE_TABLE + __pa(pte);
-	pmd_val(pmd[1]) = _PAGE_TABLE + __pa(pte+256);
-	pmd_val(pmd[2]) = _PAGE_TABLE + __pa(pte+512);
-	pmd_val(pmd[3]) = _PAGE_TABLE + __pa(pte+768);
+	pmd_val(pmd[0]) = _SEGMENT_ENTRY + __pa(pte);
+	pmd_val(pmd[1]) = _SEGMENT_ENTRY + __pa(pte+256);
+	pmd_val(pmd[2]) = _SEGMENT_ENTRY + __pa(pte+512);
+	pmd_val(pmd[3]) = _SEGMENT_ENTRY + __pa(pte+768);
 #else /* __s390x__ */
-	pmd_val(*pmd) = _PMD_ENTRY + __pa(pte);
-	pmd_val1(*pmd) = _PMD_ENTRY + __pa(pte+256);
+	pmd_val(*pmd) = _SEGMENT_ENTRY + __pa(pte);
+	pmd_val1(*pmd) = _SEGMENT_ENTRY + __pa(pte+256);
 #endif /* __s390x__ */
 }
 
@@ -160,7 +135,7 @@
 pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *page)
 {
 	pte_t *pte = (pte_t *)page_to_phys(page);
-	pmd_t *shadow_pmd = get_shadow_pmd(pmd);
+	pmd_t *shadow_pmd = get_shadow_table(pmd);
 	pte_t *shadow_pte = get_shadow_pte(pte);
 
 	pmd_populate_kernel(mm, pmd, pte);
@@ -171,67 +146,14 @@
 /*
  * page table entry allocation/free routines.
  */
-static inline pte_t *
-pte_alloc_one_kernel(struct mm_struct *mm, unsigned long vmaddr)
-{
-	pte_t *pte = (pte_t *) __get_free_page(GFP_KERNEL|__GFP_REPEAT);
-	int i;
+#define pte_alloc_one_kernel(mm, vmaddr) \
+	((pte_t *) page_table_alloc(s390_noexec))
+#define pte_alloc_one(mm, vmaddr) \
+	virt_to_page(page_table_alloc(s390_noexec))
 
-	if (!pte)
-		return NULL;
-	if (s390_noexec) {
-		pte_t *shadow_pte = (pte_t *)
-			__get_free_page(GFP_KERNEL|__GFP_REPEAT);
-		struct page *page = virt_to_page(pte);
-
-		if (!shadow_pte) {
-			free_page((unsigned long) pte);
-			return NULL;
-		}
-		page->lru.next = (void *) shadow_pte;
-	}
-	for (i=0; i < PTRS_PER_PTE; i++) {
-		pte_clear(mm, vmaddr, pte + i);
-		vmaddr += PAGE_SIZE;
-	}
-	return pte;
-}
-
-static inline struct page *
-pte_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
-{
-	pte_t *pte = pte_alloc_one_kernel(mm, vmaddr);
-	if (pte)
-		return virt_to_page(pte);
-	return NULL;
-}
-
-static inline void pte_free_kernel(pte_t *pte)
-{
-	pte_t *shadow_pte = get_shadow_pte(pte);
-
-	if (shadow_pte)
-		free_page((unsigned long) shadow_pte);
-	free_page((unsigned long) pte);
-}
-
-static inline void pte_free(struct page *pte)
-{
-	struct page *shadow_page = get_shadow_page(pte);
-
-	if (shadow_page)
-		__free_page(shadow_page);
-	__free_page(pte);
-}
-
-#define __pte_free_tlb(tlb, pte)					\
-({									\
-	struct mmu_gather *__tlb = (tlb);				\
-	struct page *__pte = (pte);					\
-	struct page *shadow_page = get_shadow_page(__pte);		\
-	if (shadow_page)						\
-		tlb_remove_page(__tlb, shadow_page);			\
-	tlb_remove_page(__tlb, __pte);					\
-})
+#define pte_free_kernel(pte) \
+	page_table_free((unsigned long *) pte)
+#define pte_free(pte) \
+	page_table_free((unsigned long *) page_to_phys((struct page *) pte))
 
 #endif /* _S390_PGALLOC_H */
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index 39bb519..f2cc25b 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -13,8 +13,6 @@
 #ifndef _ASM_S390_PGTABLE_H
 #define _ASM_S390_PGTABLE_H
 
-#include <asm-generic/4level-fixup.h>
-
 /*
  * The Linux memory management assumes a three-level page table setup. For
  * s390 31 bit we "fold" the mid level into the top-level page table, so
@@ -35,9 +33,6 @@
 #include <asm/bug.h>
 #include <asm/processor.h>
 
-struct vm_area_struct; /* forward declaration (include/linux/mm.h) */
-struct mm_struct;
-
 extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
 extern void paging_init(void);
 extern void vmem_map_init(void);
@@ -63,14 +58,18 @@
  */
 #ifndef __s390x__
 # define PMD_SHIFT	22
+# define PUD_SHIFT	22
 # define PGDIR_SHIFT	22
 #else /* __s390x__ */
 # define PMD_SHIFT	21
+# define PUD_SHIFT	31
 # define PGDIR_SHIFT	31
 #endif /* __s390x__ */
 
 #define PMD_SIZE        (1UL << PMD_SHIFT)
 #define PMD_MASK        (~(PMD_SIZE-1))
+#define PUD_SIZE	(1UL << PUD_SHIFT)
+#define PUD_MASK	(~(PUD_SIZE-1))
 #define PGDIR_SIZE      (1UL << PGDIR_SHIFT)
 #define PGDIR_MASK      (~(PGDIR_SIZE-1))
 
@@ -83,10 +82,12 @@
 #ifndef __s390x__
 # define PTRS_PER_PTE    1024
 # define PTRS_PER_PMD    1
+# define PTRS_PER_PUD	1
 # define PTRS_PER_PGD    512
 #else /* __s390x__ */
 # define PTRS_PER_PTE    512
 # define PTRS_PER_PMD    1024
+# define PTRS_PER_PUD	1
 # define PTRS_PER_PGD    2048
 #endif /* __s390x__ */
 
@@ -96,6 +97,8 @@
 	printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e))
 #define pmd_ERROR(e) \
 	printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e))
+#define pud_ERROR(e) \
+	printk("%s:%d: bad pud %p.\n", __FILE__, __LINE__, (void *) pud_val(e))
 #define pgd_ERROR(e) \
 	printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e))
 
@@ -195,7 +198,7 @@
  * I Segment-Invalid Bit:    Segment is not available for address-translation
  * TT Type 01
  * TF
- * TL Table lenght
+ * TL Table length
  *
  * The 64 bit regiontable origin of S390 has following format:
  * |      region table origon                          |       DTTL
@@ -221,6 +224,8 @@
 /* Hardware bits in the page table entry */
 #define _PAGE_RO	0x200		/* HW read-only bit  */
 #define _PAGE_INVALID	0x400		/* HW invalid bit    */
+
+/* Software bits in the page table entry */
 #define _PAGE_SWT	0x001		/* SW pte type bit t */
 #define _PAGE_SWX	0x002		/* SW pte type bit x */
 
@@ -264,60 +269,75 @@
 
 #ifndef __s390x__
 
+/* Bits in the segment table address-space-control-element */
+#define _ASCE_SPACE_SWITCH	0x80000000UL	/* space switch event	    */
+#define _ASCE_ORIGIN_MASK	0x7ffff000UL	/* segment table origin	    */
+#define _ASCE_PRIVATE_SPACE	0x100	/* private space control	    */
+#define _ASCE_ALT_EVENT		0x80	/* storage alteration event control */
+#define _ASCE_TABLE_LENGTH	0x7f	/* 128 x 64 entries = 8k	    */
+
 /* Bits in the segment table entry */
-#define _PAGE_TABLE_LEN 0xf            /* only full page-tables            */
-#define _PAGE_TABLE_COM 0x10           /* common page-table                */
-#define _PAGE_TABLE_INV 0x20           /* invalid page-table               */
-#define _SEG_PRESENT    0x001          /* Software (overlap with PTL)      */
+#define _SEGMENT_ENTRY_ORIGIN	0x7fffffc0UL	/* page table origin	    */
+#define _SEGMENT_ENTRY_INV	0x20	/* invalid segment table entry	    */
+#define _SEGMENT_ENTRY_COMMON	0x10	/* common segment bit		    */
+#define _SEGMENT_ENTRY_PTL	0x0f	/* page table length		    */
+
+#define _SEGMENT_ENTRY		(_SEGMENT_ENTRY_PTL)
+#define _SEGMENT_ENTRY_EMPTY	(_SEGMENT_ENTRY_INV)
+
+#else /* __s390x__ */
+
+/* Bits in the segment/region table address-space-control-element */
+#define _ASCE_ORIGIN		~0xfffUL/* segment table origin		    */
+#define _ASCE_PRIVATE_SPACE	0x100	/* private space control	    */
+#define _ASCE_ALT_EVENT		0x80	/* storage alteration event control */
+#define _ASCE_SPACE_SWITCH	0x40	/* space switch event		    */
+#define _ASCE_REAL_SPACE	0x20	/* real space control		    */
+#define _ASCE_TYPE_MASK		0x0c	/* asce table type mask		    */
+#define _ASCE_TYPE_REGION1	0x0c	/* region first table type	    */
+#define _ASCE_TYPE_REGION2	0x08	/* region second table type	    */
+#define _ASCE_TYPE_REGION3	0x04	/* region third table type	    */
+#define _ASCE_TYPE_SEGMENT	0x00	/* segment table type		    */
+#define _ASCE_TABLE_LENGTH	0x03	/* region table length		    */
+
+/* Bits in the region table entry */
+#define _REGION_ENTRY_ORIGIN	~0xfffUL/* region/segment table origin	    */
+#define _REGION_ENTRY_INV	0x20	/* invalid region table entry	    */
+#define _REGION_ENTRY_TYPE_MASK	0x0c	/* region/segment table type mask   */
+#define _REGION_ENTRY_TYPE_R1	0x0c	/* region first table type	    */
+#define _REGION_ENTRY_TYPE_R2	0x08	/* region second table type	    */
+#define _REGION_ENTRY_TYPE_R3	0x04	/* region third table type	    */
+#define _REGION_ENTRY_LENGTH	0x03	/* region third length		    */
+
+#define _REGION1_ENTRY		(_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_LENGTH)
+#define _REGION1_ENTRY_EMPTY	(_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_INV)
+#define _REGION2_ENTRY		(_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_LENGTH)
+#define _REGION2_ENTRY_EMPTY	(_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_INV)
+#define _REGION3_ENTRY		(_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH)
+#define _REGION3_ENTRY_EMPTY	(_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV)
+
+/* Bits in the segment table entry */
+#define _SEGMENT_ENTRY_ORIGIN	~0x7ffUL/* segment table origin		    */
+#define _SEGMENT_ENTRY_RO	0x200	/* page protection bit		    */
+#define _SEGMENT_ENTRY_INV	0x20	/* invalid segment table entry	    */
+
+#define _SEGMENT_ENTRY		(0)
+#define _SEGMENT_ENTRY_EMPTY	(_SEGMENT_ENTRY_INV)
+
+#endif /* __s390x__ */
+
+/*
+ * A user page table pointer has the space-switch-event bit, the
+ * private-space-control bit and the storage-alteration-event-control
+ * bit set. A kernel page table pointer doesn't need them.
+ */
+#define _ASCE_USER_BITS		(_ASCE_SPACE_SWITCH | _ASCE_PRIVATE_SPACE | \
+				 _ASCE_ALT_EVENT)
 
 /* Bits int the storage key */
 #define _PAGE_CHANGED    0x02          /* HW changed bit                   */
 #define _PAGE_REFERENCED 0x04          /* HW referenced bit                */
 
-#define _USER_SEG_TABLE_LEN    0x7f    /* user-segment-table up to 2 GB    */
-#define _KERNEL_SEG_TABLE_LEN  0x7f    /* kernel-segment-table up to 2 GB  */
-
-/*
- * User and Kernel pagetables are identical
- */
-#define _PAGE_TABLE	_PAGE_TABLE_LEN
-#define _KERNPG_TABLE	_PAGE_TABLE_LEN
-
-/*
- * The Kernel segment-tables includes the User segment-table
- */
-
-#define _SEGMENT_TABLE	(_USER_SEG_TABLE_LEN|0x80000000|0x100)
-#define _KERNSEG_TABLE	_KERNEL_SEG_TABLE_LEN
-
-#define USER_STD_MASK	0x00000080UL
-
-#else /* __s390x__ */
-
-/* Bits in the segment table entry */
-#define _PMD_ENTRY_INV   0x20          /* invalid segment table entry      */
-#define _PMD_ENTRY       0x00        
-
-/* Bits in the region third table entry */
-#define _PGD_ENTRY_INV   0x20          /* invalid region table entry       */
-#define _PGD_ENTRY       0x07
-
-/*
- * User and kernel page directory
- */
-#define _REGION_THIRD       0x4
-#define _REGION_THIRD_LEN   0x3 
-#define _REGION_TABLE       (_REGION_THIRD|_REGION_THIRD_LEN|0x40|0x100)
-#define _KERN_REGION_TABLE  (_REGION_THIRD|_REGION_THIRD_LEN)
-
-#define USER_STD_MASK           0x0000000000000080UL
-
-/* Bits in the storage key */
-#define _PAGE_CHANGED    0x02          /* HW changed bit                   */
-#define _PAGE_REFERENCED 0x04          /* HW referenced bit                */
-
-#endif /* __s390x__ */
-
 /*
  * Page protection definitions.
  */
@@ -358,65 +378,38 @@
 #define __S111	PAGE_EX_RW
 
 #ifndef __s390x__
-# define PMD_SHADOW_SHIFT	1
-# define PGD_SHADOW_SHIFT	1
+# define PxD_SHADOW_SHIFT	1
 #else /* __s390x__ */
-# define PMD_SHADOW_SHIFT	2
-# define PGD_SHADOW_SHIFT	2
+# define PxD_SHADOW_SHIFT	2
 #endif /* __s390x__ */
 
 static inline struct page *get_shadow_page(struct page *page)
 {
-	if (s390_noexec && !list_empty(&page->lru))
-		return virt_to_page(page->lru.next);
+	if (s390_noexec && page->index)
+		return virt_to_page((void *)(addr_t) page->index);
 	return NULL;
 }
 
-static inline pte_t *get_shadow_pte(pte_t *ptep)
+static inline void *get_shadow_pte(void *table)
 {
-	unsigned long pteptr = (unsigned long) (ptep);
+	unsigned long addr, offset;
+	struct page *page;
 
-	if (s390_noexec) {
-		unsigned long offset = pteptr & (PAGE_SIZE - 1);
-		void *addr = (void *) (pteptr ^ offset);
-		struct page *page = virt_to_page(addr);
-		if (!list_empty(&page->lru))
-			return (pte_t *) ((unsigned long) page->lru.next |
-								offset);
-	}
-	return NULL;
+	addr = (unsigned long) table;
+	offset = addr & (PAGE_SIZE - 1);
+	page = virt_to_page((void *)(addr ^ offset));
+	return (void *)(addr_t)(page->index ? (page->index | offset) : 0UL);
 }
 
-static inline pmd_t *get_shadow_pmd(pmd_t *pmdp)
+static inline void *get_shadow_table(void *table)
 {
-	unsigned long pmdptr = (unsigned long) (pmdp);
+	unsigned long addr, offset;
+	struct page *page;
 
-	if (s390_noexec) {
-		unsigned long offset = pmdptr &
-				((PAGE_SIZE << PMD_SHADOW_SHIFT) - 1);
-		void *addr = (void *) (pmdptr ^ offset);
-		struct page *page = virt_to_page(addr);
-		if (!list_empty(&page->lru))
-			return (pmd_t *) ((unsigned long) page->lru.next |
-								offset);
-	}
-	return NULL;
-}
-
-static inline pgd_t *get_shadow_pgd(pgd_t *pgdp)
-{
-	unsigned long pgdptr = (unsigned long) (pgdp);
-
-	if (s390_noexec) {
-		unsigned long offset = pgdptr &
-				((PAGE_SIZE << PGD_SHADOW_SHIFT) - 1);
-		void *addr = (void *) (pgdptr ^ offset);
-		struct page *page = virt_to_page(addr);
-		if (!list_empty(&page->lru))
-			return (pgd_t *) ((unsigned long) page->lru.next |
-								offset);
-	}
-	return NULL;
+	addr = (unsigned long) table;
+	offset = addr & ((PAGE_SIZE << PxD_SHADOW_SHIFT) - 1);
+	page = virt_to_page((void *)(addr ^ offset));
+	return (void *)(addr_t)(page->index ? (page->index | offset) : 0UL);
 }
 
 /*
@@ -424,7 +417,8 @@
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
  */
-static inline void set_pte(pte_t *pteptr, pte_t pteval)
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+			      pte_t *pteptr, pte_t pteval)
 {
 	pte_t *shadow_pte = get_shadow_pte(pteptr);
 
@@ -437,7 +431,6 @@
 			pte_val(*shadow_pte) = _PAGE_TYPE_EMPTY;
 	}
 }
-#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
 
 /*
  * pgd/pmd/pte query functions
@@ -448,47 +441,50 @@
 static inline int pgd_none(pgd_t pgd)    { return 0; }
 static inline int pgd_bad(pgd_t pgd)     { return 0; }
 
-static inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _SEG_PRESENT; }
-static inline int pmd_none(pmd_t pmd)    { return pmd_val(pmd) & _PAGE_TABLE_INV; }
-static inline int pmd_bad(pmd_t pmd)
-{
-	return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE;
-}
+static inline int pud_present(pud_t pud) { return 1; }
+static inline int pud_none(pud_t pud)	 { return 0; }
+static inline int pud_bad(pud_t pud)	 { return 0; }
 
 #else /* __s390x__ */
 
-static inline int pgd_present(pgd_t pgd)
+static inline int pgd_present(pgd_t pgd) { return 1; }
+static inline int pgd_none(pgd_t pgd)	 { return 0; }
+static inline int pgd_bad(pgd_t pgd)	 { return 0; }
+
+static inline int pud_present(pud_t pud)
 {
-	return (pgd_val(pgd) & ~PAGE_MASK) == _PGD_ENTRY;
+	return pud_val(pud) & _REGION_ENTRY_ORIGIN;
 }
 
-static inline int pgd_none(pgd_t pgd)
+static inline int pud_none(pud_t pud)
 {
-	return pgd_val(pgd) & _PGD_ENTRY_INV;
+	return pud_val(pud) & _REGION_ENTRY_INV;
 }
 
-static inline int pgd_bad(pgd_t pgd)
+static inline int pud_bad(pud_t pud)
 {
-	return (pgd_val(pgd) & (~PAGE_MASK & ~_PGD_ENTRY_INV)) != _PGD_ENTRY;
+	unsigned long mask = ~_REGION_ENTRY_ORIGIN & ~_REGION_ENTRY_INV;
+	return (pud_val(pud) & mask) != _REGION3_ENTRY;
 }
 
+#endif /* __s390x__ */
+
 static inline int pmd_present(pmd_t pmd)
 {
-	return (pmd_val(pmd) & ~PAGE_MASK) == _PMD_ENTRY;
+	return pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN;
 }
 
 static inline int pmd_none(pmd_t pmd)
 {
-	return pmd_val(pmd) & _PMD_ENTRY_INV;
+	return pmd_val(pmd) & _SEGMENT_ENTRY_INV;
 }
 
 static inline int pmd_bad(pmd_t pmd)
 {
-	return (pmd_val(pmd) & (~PAGE_MASK & ~_PMD_ENTRY_INV)) != _PMD_ENTRY;
+	unsigned long mask = ~_SEGMENT_ENTRY_ORIGIN & ~_SEGMENT_ENTRY_INV;
+	return (pmd_val(pmd) & mask) != _SEGMENT_ENTRY;
 }
 
-#endif /* __s390x__ */
-
 static inline int pte_none(pte_t pte)
 {
 	return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT);
@@ -508,7 +504,8 @@
 	return (pte_val(pte) & mask) == _PAGE_TYPE_FILE;
 }
 
-#define pte_same(a,b)	(pte_val(a) == pte_val(b))
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(a,b)  (pte_val(a) == pte_val(b))
 
 /*
  * query functions pte_write/pte_dirty/pte_young only work if
@@ -543,58 +540,52 @@
 
 #ifndef __s390x__
 
-static inline void pgd_clear(pgd_t * pgdp)      { }
+#define pgd_clear(pgd)		do { } while (0)
+#define pud_clear(pud)		do { } while (0)
 
 static inline void pmd_clear_kernel(pmd_t * pmdp)
 {
-	pmd_val(pmdp[0]) = _PAGE_TABLE_INV;
-	pmd_val(pmdp[1]) = _PAGE_TABLE_INV;
-	pmd_val(pmdp[2]) = _PAGE_TABLE_INV;
-	pmd_val(pmdp[3]) = _PAGE_TABLE_INV;
-}
-
-static inline void pmd_clear(pmd_t * pmdp)
-{
-	pmd_t *shadow_pmd = get_shadow_pmd(pmdp);
-
-	pmd_clear_kernel(pmdp);
-	if (shadow_pmd)
-		pmd_clear_kernel(shadow_pmd);
+	pmd_val(pmdp[0]) = _SEGMENT_ENTRY_EMPTY;
+	pmd_val(pmdp[1]) = _SEGMENT_ENTRY_EMPTY;
+	pmd_val(pmdp[2]) = _SEGMENT_ENTRY_EMPTY;
+	pmd_val(pmdp[3]) = _SEGMENT_ENTRY_EMPTY;
 }
 
 #else /* __s390x__ */
 
-static inline void pgd_clear_kernel(pgd_t * pgdp)
+#define pgd_clear(pgd)		do { } while (0)
+
+static inline void pud_clear_kernel(pud_t *pud)
 {
-	pgd_val(*pgdp) = _PGD_ENTRY_INV | _PGD_ENTRY;
+	pud_val(*pud) = _REGION3_ENTRY_EMPTY;
 }
 
-static inline void pgd_clear(pgd_t * pgdp)
+static inline void pud_clear(pud_t * pud)
 {
-	pgd_t *shadow_pgd = get_shadow_pgd(pgdp);
+	pud_t *shadow = get_shadow_table(pud);
 
-	pgd_clear_kernel(pgdp);
-	if (shadow_pgd)
-		pgd_clear_kernel(shadow_pgd);
+	pud_clear_kernel(pud);
+	if (shadow)
+		pud_clear_kernel(shadow);
 }
 
 static inline void pmd_clear_kernel(pmd_t * pmdp)
 {
-	pmd_val(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
-	pmd_val1(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
+	pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY;
+	pmd_val1(*pmdp) = _SEGMENT_ENTRY_EMPTY;
 }
 
+#endif /* __s390x__ */
+
 static inline void pmd_clear(pmd_t * pmdp)
 {
-	pmd_t *shadow_pmd = get_shadow_pmd(pmdp);
+	pmd_t *shadow_pmd = get_shadow_table(pmdp);
 
 	pmd_clear_kernel(pmdp);
 	if (shadow_pmd)
 		pmd_clear_kernel(shadow_pmd);
 }
 
-#endif /* __s390x__ */
-
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
 	pte_t *shadow_pte = get_shadow_pte(ptep);
@@ -663,24 +654,19 @@
 	return pte;
 }
 
-static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
+					    unsigned long addr, pte_t *ptep)
 {
 	return 0;
 }
 
-static inline int
-ptep_clear_flush_young(struct vm_area_struct *vma,
-			unsigned long address, pte_t *ptep)
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
+					 unsigned long address, pte_t *ptep)
 {
 	/* No need to flush TLB; bits are in storage key */
-	return ptep_test_and_clear_young(vma, address, ptep);
-}
-
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
-	pte_t pte = *ptep;
-	pte_clear(mm, addr, ptep);
-	return pte;
+	return 0;
 }
 
 static inline void __ptep_ipte(unsigned long address, pte_t *ptep)
@@ -709,6 +695,32 @@
 		__ptep_ipte(address, ptep);
 }
 
+/*
+ * This is hard to understand. ptep_get_and_clear and ptep_clear_flush
+ * both clear the TLB for the unmapped pte. The reason is that
+ * ptep_get_and_clear is used in common code (e.g. change_pte_range)
+ * to modify an active pte. The sequence is
+ *   1) ptep_get_and_clear
+ *   2) set_pte_at
+ *   3) flush_tlb_range
+ * On s390 the tlb needs to get flushed with the modification of the pte
+ * if the pte is active. The only way how this can be implemented is to
+ * have ptep_get_and_clear do the tlb flush. In exchange flush_tlb_range
+ * is a nop.
+ */
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define ptep_get_and_clear(__mm, __address, __ptep)			\
+({									\
+	pte_t __pte = *(__ptep);					\
+	if (atomic_read(&(__mm)->mm_users) > 1 ||			\
+	    (__mm) != current->active_mm)				\
+		ptep_invalidate(__address, __ptep);			\
+	else								\
+		pte_clear((__mm), (__address), (__ptep));		\
+	__pte;								\
+})
+
+#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
 static inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
 				     unsigned long address, pte_t *ptep)
 {
@@ -717,12 +729,40 @@
 	return pte;
 }
 
-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+/*
+ * The batched pte unmap code uses ptep_get_and_clear_full to clear the
+ * ptes. Here an optimization is possible. tlb_gather_mmu flushes all
+ * tlbs of an mm if it can guarantee that the ptes of the mm_struct
+ * cannot be accessed while the batched unmap is running. In this case
+ * full==1 and a simple pte_clear is enough. See tlb.h.
+ */
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
+static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
+					    unsigned long addr,
+					    pte_t *ptep, int full)
 {
-	pte_t old_pte = *ptep;
-	set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
+	pte_t pte = *ptep;
+
+	if (full)
+		pte_clear(mm, addr, ptep);
+	else
+		ptep_invalidate(addr, ptep);
+	return pte;
 }
 
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define ptep_set_wrprotect(__mm, __addr, __ptep)			\
+({									\
+	pte_t __pte = *(__ptep);					\
+	if (pte_write(__pte)) {						\
+		if (atomic_read(&(__mm)->mm_users) > 1 ||		\
+		    (__mm) != current->active_mm)			\
+			ptep_invalidate(__addr, __ptep);		\
+		set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte));	\
+	}								\
+})
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty)	\
 ({									\
 	int __changed = !pte_same(*(__ptep), __entry);			\
@@ -740,11 +780,13 @@
  * should therefore only be called if it is not mapped in any
  * address space.
  */
+#define __HAVE_ARCH_PAGE_TEST_DIRTY
 static inline int page_test_dirty(struct page *page)
 {
 	return (page_get_storage_key(page_to_phys(page)) & _PAGE_CHANGED) != 0;
 }
 
+#define __HAVE_ARCH_PAGE_CLEAR_DIRTY
 static inline void page_clear_dirty(struct page *page)
 {
 	page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY);
@@ -753,6 +795,7 @@
 /*
  * Test and clear referenced bit in storage key.
  */
+#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
 static inline int page_test_and_clear_young(struct page *page)
 {
 	unsigned long physpage = page_to_phys(page);
@@ -784,63 +827,48 @@
 	return mk_pte_phys(physpage, pgprot);
 }
 
-static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
-{
-	unsigned long physpage = __pa((pfn) << PAGE_SHIFT);
-
-	return mk_pte_phys(physpage, pgprot);
-}
-
-#ifdef __s390x__
-
-static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot)
-{
-	unsigned long physpage = __pa((pfn) << PAGE_SHIFT);
-
-	return __pmd(physpage + pgprot_val(pgprot));
-}
-
-#endif /* __s390x__ */
-
-#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
-#define pte_page(x) pfn_to_page(pte_pfn(x))
-
-#define pmd_page_vaddr(pmd) (pmd_val(pmd) & PAGE_MASK)
-
-#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
-
-#define pgd_page_vaddr(pgd) (pgd_val(pgd) & PAGE_MASK)
-
-#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT)
-
-/* to find an entry in a page-table-directory */
 #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
-#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
+#define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
 
-/* to find an entry in a kernel page-table-directory */
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
 #ifndef __s390x__
 
-/* Find an entry in the second-level page table.. */
-static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
-{
-        return (pmd_t *) dir;
-}
+#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN)
+#define pud_deref(pmd) ({ BUG(); 0UL; })
+#define pgd_deref(pmd) ({ BUG(); 0UL; })
+
+#define pud_offset(pgd, address) ((pud_t *) pgd)
+#define pmd_offset(pud, address) ((pmd_t *) pud + pmd_index(address))
 
 #else /* __s390x__ */
 
-/* Find an entry in the second-level page table.. */
-#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
-#define pmd_offset(dir,addr) \
-	((pmd_t *) pgd_page_vaddr(*(dir)) + pmd_index(addr))
+#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN)
+#define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN)
+#define pgd_deref(pgd) ({ BUG(); 0UL; })
+
+#define pud_offset(pgd, address) ((pud_t *) pgd)
+
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
+{
+	pmd_t *pmd = (pmd_t *) pud_deref(*pud);
+	return pmd + pmd_index(address);
+}
 
 #endif /* __s390x__ */
 
-/* Find an entry in the third-level page table.. */
-#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
-#define pte_offset_kernel(pmd, address) \
-	((pte_t *) pmd_page_vaddr(*(pmd)) + pte_index(address))
+#define pfn_pte(pfn,pgprot) mk_pte_phys(__pa((pfn) << PAGE_SHIFT),(pgprot))
+#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
+#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
+
+/* Find an entry in the lowest level page table.. */
+#define pte_offset(pmd, addr) ((pte_t *) pmd_deref(*(pmd)) + pte_index(addr))
+#define pte_offset_kernel(pmd, address) pte_offset(pmd,address)
 #define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
 #define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address)
 #define pte_unmap(pte) do { } while (0)
@@ -930,17 +958,6 @@
 #define __HAVE_ARCH_MEMMAP_INIT
 extern void memmap_init(unsigned long, int, unsigned long, unsigned long);
 
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-#define __HAVE_ARCH_PTE_SAME
-#define __HAVE_ARCH_PAGE_TEST_DIRTY
-#define __HAVE_ARCH_PAGE_CLEAR_DIRTY
-#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
 #include <asm-generic/pgtable.h>
 
 #endif /* _S390_PAGE_H */
-
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h
index 3b972d4..21d40a1 100644
--- a/include/asm-s390/processor.h
+++ b/include/asm-s390/processor.h
@@ -93,7 +93,6 @@
 	s390_fp_regs fp_regs;
 	unsigned int  acrs[NUM_ACRS];
         unsigned long ksp;              /* kernel stack pointer             */
-        unsigned long user_seg;         /* HSTD                             */
 	mm_segment_t mm_segment;
         unsigned long prot_addr;        /* address of protection-excep.     */
         unsigned int error_code;        /* error-code of last prog-excep.   */
@@ -128,22 +127,9 @@
 
 #define ARCH_MIN_TASKALIGN	8
 
-#ifndef __s390x__
-# define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _SEGMENT_TABLE
-#else /* __s390x__ */
-# define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _REGION_TABLE
-#endif /* __s390x__ */
-
-#define INIT_THREAD {{0,{{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},	       \
-			    {0},{0},{0},{0},{0},{0}}},			       \
-		     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},	       \
-		     sizeof(init_stack) + (unsigned long) &init_stack,	       \
-		     __SWAPPER_PG_DIR,					       \
-		     {0},						       \
-		     0,0,0,						       \
-		     (per_struct) {{{{0,}}},0,0,0,0,{{0,}}},		       \
-		     0, 0						       \
-} 
+#define INIT_THREAD {							\
+	.ksp = sizeof(init_stack) + (unsigned long) &init_stack,	\
+}
 
 /*
  * Do necessary setup to start up a new thread.
diff --git a/include/asm-s390/scatterlist.h b/include/asm-s390/scatterlist.h
index a43b3af..29ec8e2 100644
--- a/include/asm-s390/scatterlist.h
+++ b/include/asm-s390/scatterlist.h
@@ -2,7 +2,10 @@
 #define _ASMS390_SCATTERLIST_H
 
 struct scatterlist {
-    struct page *page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long sg_magic;
+#endif
+    unsigned long page_link;
     unsigned int offset;
     unsigned int length;
 };
diff --git a/include/asm-s390/tlb.h b/include/asm-s390/tlb.h
index 51bd957..618693cf 100644
--- a/include/asm-s390/tlb.h
+++ b/include/asm-s390/tlb.h
@@ -2,19 +2,130 @@
 #define _S390_TLB_H
 
 /*
- * s390 doesn't need any special per-pte or
- * per-vma handling..
+ * TLB flushing on s390 is complicated. The following requirement
+ * from the principles of operation is the most arduous:
+ *
+ * "A valid table entry must not be changed while it is attached
+ * to any CPU and may be used for translation by that CPU except to
+ * (1) invalidate the entry by using INVALIDATE PAGE TABLE ENTRY,
+ * or INVALIDATE DAT TABLE ENTRY, (2) alter bits 56-63 of a page
+ * table entry, or (3) make a change by means of a COMPARE AND SWAP
+ * AND PURGE instruction that purges the TLB."
+ *
+ * The modification of a pte of an active mm struct therefore is
+ * a two step process: i) invalidate the pte, ii) store the new pte.
+ * This is true for the page protection bit as well.
+ * The only possible optimization is to flush at the beginning of
+ * a tlb_gather_mmu cycle if the mm_struct is currently not in use.
+ *
+ * Pages used for the page tables is a different story. FIXME: more
  */
-#define tlb_start_vma(tlb, vma) do { } while (0)
-#define tlb_end_vma(tlb, vma) do { } while (0)
-#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
+
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <asm/processor.h>
+#include <asm/pgalloc.h>
+#include <asm/smp.h>
+#include <asm/tlbflush.h>
+
+#ifndef CONFIG_SMP
+#define TLB_NR_PTRS	1
+#else
+#define TLB_NR_PTRS	508
+#endif
+
+struct mmu_gather {
+	struct mm_struct *mm;
+	unsigned int fullmm;
+	unsigned int nr_ptes;
+	unsigned int nr_pmds;
+	void *array[TLB_NR_PTRS];
+};
+
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm,
+						unsigned int full_mm_flush)
+{
+	struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+
+	tlb->mm = mm;
+	tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) ||
+		(atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm);
+	tlb->nr_ptes = 0;
+	tlb->nr_pmds = TLB_NR_PTRS;
+	if (tlb->fullmm)
+		__tlb_flush_mm(mm);
+	return tlb;
+}
+
+static inline void tlb_flush_mmu(struct mmu_gather *tlb,
+				 unsigned long start, unsigned long end)
+{
+	if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pmds < TLB_NR_PTRS))
+		__tlb_flush_mm(tlb->mm);
+	while (tlb->nr_ptes > 0)
+		pte_free(tlb->array[--tlb->nr_ptes]);
+	while (tlb->nr_pmds < TLB_NR_PTRS)
+		pmd_free((pmd_t *) tlb->array[tlb->nr_pmds++]);
+}
+
+static inline void tlb_finish_mmu(struct mmu_gather *tlb,
+				  unsigned long start, unsigned long end)
+{
+	tlb_flush_mmu(tlb, start, end);
+
+	/* keep the page table cache within bounds */
+	check_pgt_cache();
+
+	put_cpu_var(mmu_gathers);
+}
 
 /*
- * .. because we flush the whole mm when it
- * fills up.
+ * Release the page cache reference for a pte removed by
+ * tlb_ptep_clear_flush. In both flush modes the tlb fo a page cache page
+ * has already been freed, so just do free_page_and_swap_cache.
  */
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+	free_page_and_swap_cache(page);
+}
 
-#include <asm-generic/tlb.h>
+/*
+ * pte_free_tlb frees a pte table and clears the CRSTE for the
+ * page table from the tlb.
+ */
+static inline void pte_free_tlb(struct mmu_gather *tlb, struct page *page)
+{
+	if (!tlb->fullmm) {
+		tlb->array[tlb->nr_ptes++] = page;
+		if (tlb->nr_ptes >= tlb->nr_pmds)
+			tlb_flush_mmu(tlb, 0, 0);
+	} else
+		pte_free(page);
+}
 
+/*
+ * pmd_free_tlb frees a pmd table and clears the CRSTE for the
+ * segment table entry from the tlb.
+ */
+static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
+{
+#ifdef __s390x__
+	if (!tlb->fullmm) {
+		tlb->array[--tlb->nr_pmds] = (struct page *) pmd;
+		if (tlb->nr_ptes >= tlb->nr_pmds)
+			tlb_flush_mmu(tlb, 0, 0);
+	} else
+		pmd_free(pmd);
 #endif
+}
+
+#define pud_free_tlb(tlb, pud)			do { } while (0)
+
+#define tlb_start_vma(tlb, vma)			do { } while (0)
+#define tlb_end_vma(tlb, vma)			do { } while (0)
+#define tlb_remove_tlb_entry(tlb, ptep, addr)	do { } while (0)
+#define tlb_migrate_finish(mm)			do { } while (0)
+
+#endif /* _S390_TLB_H */
diff --git a/include/asm-s390/tlbflush.h b/include/asm-s390/tlbflush.h
index 66793f5..a69bd24 100644
--- a/include/asm-s390/tlbflush.h
+++ b/include/asm-s390/tlbflush.h
@@ -6,69 +6,19 @@
 #include <asm/pgalloc.h>
 
 /*
- * TLB flushing:
- *
- *  - flush_tlb() flushes the current mm struct TLBs
- *  - flush_tlb_all() flushes all processes TLBs 
- *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
- *  - flush_tlb_page(vma, vmaddr) flushes one page
- *  - flush_tlb_range(vma, start, end) flushes a range of pages
- *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
+ * Flush all tlb entries on the local cpu.
  */
+static inline void __tlb_flush_local(void)
+{
+	asm volatile("ptlb" : : : "memory");
+}
 
 /*
- * S/390 has three ways of flushing TLBs
- * 'ptlb' does a flush of the local processor
- * 'csp' flushes the TLBs on all PUs of a SMP
- * 'ipte' invalidates a pte in a page table and flushes that out of
- * the TLBs of all PUs of a SMP
+ * Flush all tlb entries on all cpus.
  */
-
-#define local_flush_tlb() \
-do {  asm volatile("ptlb": : :"memory"); } while (0)
-
-#ifndef CONFIG_SMP
-
-/*
- * We always need to flush, since s390 does not flush tlb
- * on each context switch
- */
-
-static inline void flush_tlb(void)
+static inline void __tlb_flush_global(void)
 {
-	local_flush_tlb();
-}
-static inline void flush_tlb_all(void)
-{
-	local_flush_tlb();
-}
-static inline void flush_tlb_mm(struct mm_struct *mm) 
-{
-	local_flush_tlb();
-}
-static inline void flush_tlb_page(struct vm_area_struct *vma,
-				  unsigned long addr)
-{
-	local_flush_tlb();
-}
-static inline void flush_tlb_range(struct vm_area_struct *vma,
-				   unsigned long start, unsigned long end)
-{
-	local_flush_tlb();
-}
-
-#define flush_tlb_kernel_range(start, end) \
-	local_flush_tlb();
-
-#else
-
-#include <asm/smp.h>
-
-extern void smp_ptlb_all(void);
-
-static inline void global_flush_tlb(void)
-{
+	extern void smp_ptlb_all(void);
 	register unsigned long reg2 asm("2");
 	register unsigned long reg3 asm("3");
 	register unsigned long reg4 asm("4");
@@ -90,72 +40,75 @@
 }
 
 /*
- * We only have to do global flush of tlb if process run since last
- * flush on any other pu than current. 
- * If we have threads (mm->count > 1) we always do a global flush, 
- * since the process runs on more than one processor at the same time.
+ * Flush all tlb entries of a page table on all cpus.
  */
+static inline void __tlb_flush_idte(pgd_t *pgd)
+{
+	asm volatile(
+		"	.insn	rrf,0xb98e0000,0,%0,%1,0"
+		: : "a" (2048), "a" (__pa(pgd) & PAGE_MASK) : "cc" );
+}
 
-static inline void __flush_tlb_mm(struct mm_struct * mm)
+static inline void __tlb_flush_mm(struct mm_struct * mm)
 {
 	cpumask_t local_cpumask;
 
 	if (unlikely(cpus_empty(mm->cpu_vm_mask)))
 		return;
+	/*
+	 * If the machine has IDTE we prefer to do a per mm flush
+	 * on all cpus instead of doing a local flush if the mm
+	 * only ran on the local cpu.
+	 */
 	if (MACHINE_HAS_IDTE) {
-		pgd_t *shadow_pgd = get_shadow_pgd(mm->pgd);
+		pgd_t *shadow_pgd = get_shadow_table(mm->pgd);
 
-		if (shadow_pgd) {
-			asm volatile(
-				"	.insn	rrf,0xb98e0000,0,%0,%1,0"
-				: : "a" (2048),
-				"a" (__pa(shadow_pgd) & PAGE_MASK) : "cc" );
-		}
-		asm volatile(
-			"	.insn	rrf,0xb98e0000,0,%0,%1,0"
-			: : "a" (2048), "a" (__pa(mm->pgd)&PAGE_MASK) : "cc");
+		if (shadow_pgd)
+			__tlb_flush_idte(shadow_pgd);
+		__tlb_flush_idte(mm->pgd);
 		return;
 	}
 	preempt_disable();
+	/*
+	 * If the process only ran on the local cpu, do a local flush.
+	 */
 	local_cpumask = cpumask_of_cpu(smp_processor_id());
 	if (cpus_equal(mm->cpu_vm_mask, local_cpumask))
-		local_flush_tlb();
+		__tlb_flush_local();
 	else
-		global_flush_tlb();
+		__tlb_flush_global();
 	preempt_enable();
 }
 
-static inline void flush_tlb(void)
+static inline void __tlb_flush_mm_cond(struct mm_struct * mm)
 {
-	__flush_tlb_mm(current->mm);
-}
-static inline void flush_tlb_all(void)
-{
-	global_flush_tlb();
-}
-static inline void flush_tlb_mm(struct mm_struct *mm) 
-{
-	__flush_tlb_mm(mm); 
-}
-static inline void flush_tlb_page(struct vm_area_struct *vma,
-				  unsigned long addr)
-{
-	__flush_tlb_mm(vma->vm_mm);
-}
-static inline void flush_tlb_range(struct vm_area_struct *vma,
-				   unsigned long start, unsigned long end)
-{
-	__flush_tlb_mm(vma->vm_mm); 
+	if (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm)
+		__tlb_flush_mm(mm);
 }
 
-#define flush_tlb_kernel_range(start, end) global_flush_tlb()
+/*
+ * TLB flushing:
+ *  flush_tlb() - flushes the current mm struct TLBs
+ *  flush_tlb_all() - flushes all processes TLBs
+ *  flush_tlb_mm(mm) - flushes the specified mm context TLB's
+ *  flush_tlb_page(vma, vmaddr) - flushes one page
+ *  flush_tlb_range(vma, start, end) - flushes a range of pages
+ *  flush_tlb_kernel_range(start, end) - flushes a range of kernel pages
+ */
 
-#endif
-
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                      unsigned long start, unsigned long end)
-{
-        /* S/390 does not keep any page table caches in TLB */
-}
+/*
+ * flush_tlb_mm goes together with ptep_set_wrprotect for the
+ * copy_page_range operation and flush_tlb_range is related to
+ * ptep_get_and_clear for change_protection. ptep_set_wrprotect and
+ * ptep_get_and_clear do not flush the TLBs directly if the mm has
+ * only one user. At the end of the update the flush_tlb_mm and
+ * flush_tlb_range functions need to do the flush.
+ */
+#define flush_tlb()				do { } while (0)
+#define flush_tlb_all()				do { } while (0)
+#define flush_tlb_mm(mm)			__tlb_flush_mm_cond(mm)
+#define flush_tlb_page(vma, addr)		do { } while (0)
+#define flush_tlb_range(vma, start, end)	__tlb_flush_mm_cond(mm)
+#define flush_tlb_kernel_range(start, end)	__tlb_flush_mm(&init_mm)
 
 #endif /* _S390_TLBFLUSH_H */
diff --git a/include/asm-sh/bitops.h b/include/asm-sh/bitops.h
index 1c16792..df805f2 100644
--- a/include/asm-sh/bitops.h
+++ b/include/asm-sh/bitops.h
@@ -2,6 +2,11 @@
 #define __ASM_SH_BITOPS_H
 
 #ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm/system.h>
 /* For __swab32 */
 #include <asm/byteorder.h>
@@ -137,6 +142,7 @@
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h
index 84fefda..fcea067 100644
--- a/include/asm-sh/dma-mapping.h
+++ b/include/asm-sh/dma-mapping.h
@@ -2,7 +2,7 @@
 #define __ASM_SH_DMA_MAPPING_H
 
 #include <linux/mm.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <asm/cacheflush.h>
 #include <asm/io.h>
 
@@ -85,10 +85,9 @@
 
 	for (i = 0; i < nents; i++) {
 #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-		dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
-			       sg[i].length, dir);
+		dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
 #endif
-		sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
+		sg[i].dma_address = sg_phys(&sg[i]);
 	}
 
 	return nents;
@@ -138,10 +137,9 @@
 
 	for (i = 0; i < nelems; i++) {
 #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-		dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
-			       sg[i].length, dir);
+		dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
 #endif
-		sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
+		sg[i].dma_address = sg_phys(&sg[i]);
 	}
 }
 
diff --git a/include/asm-sh/scatterlist.h b/include/asm-sh/scatterlist.h
index b9ae53c..a7d0d18 100644
--- a/include/asm-sh/scatterlist.h
+++ b/include/asm-sh/scatterlist.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page * page; /* Location for highmem page, if any */
+#ifdef CONFIG_DEBUG_SG
+    unsigned long sg_magic;
+#endif
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
     dma_addr_t dma_address;
     unsigned int length;
diff --git a/include/asm-sh/se7751.h b/include/asm-sh/se7751.h
index 02ca934..b36792a 100644
--- a/include/asm-sh/se7751.h
+++ b/include/asm-sh/se7751.h
@@ -36,7 +36,7 @@
 #define PA_LED		0xba000000	/* LED */
 #define	PA_BCR		0xbb000000	/* FPGA on the MS7751SE01 */
 
-#define PA_MRSHPC	0xb83fffe0	/* MR-SHPC-01 PCMCIA controler */
+#define PA_MRSHPC	0xb83fffe0	/* MR-SHPC-01 PCMCIA controller */
 #define PA_MRSHPC_MW1	0xb8400000	/* MR-SHPC-01 memory window base */
 #define PA_MRSHPC_MW2	0xb8500000	/* MR-SHPC-01 attribute window base */
 #define PA_MRSHPC_IO	0xb8600000	/* MR-SHPC-01 I/O window base */
diff --git a/include/asm-sh/systemh7751.h b/include/asm-sh/systemh7751.h
index b143bb2..4161122 100644
--- a/include/asm-sh/systemh7751.h
+++ b/include/asm-sh/systemh7751.h
@@ -36,7 +36,7 @@
 #define PA_LED		0xba000000	/* LED */
 #define	PA_BCR		0xbb000000	/* FPGA on the MS7751SE01 */
 
-#define PA_MRSHPC	0xb83fffe0	/* MR-SHPC-01 PCMCIA controler */
+#define PA_MRSHPC	0xb83fffe0	/* MR-SHPC-01 PCMCIA controller */
 #define PA_MRSHPC_MW1	0xb8400000	/* MR-SHPC-01 memory window base */
 #define PA_MRSHPC_MW2	0xb8500000	/* MR-SHPC-01 attribute window base */
 #define PA_MRSHPC_IO	0xb8600000	/* MR-SHPC-01 I/O window base */
diff --git a/include/asm-sh/tlbflush.h b/include/asm-sh/tlbflush.h
index 455fb8d..e0ac972 100644
--- a/include/asm-sh/tlbflush.h
+++ b/include/asm-sh/tlbflush.h
@@ -9,7 +9,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 extern void local_flush_tlb_all(void);
 extern void local_flush_tlb_mm(struct mm_struct *mm);
@@ -47,9 +46,4 @@
 
 #endif /* CONFIG_SMP */
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-	/* Nothing to do */
-}
 #endif /* __ASM_SH_TLBFLUSH_H */
diff --git a/include/asm-sh64/bitops.h b/include/asm-sh64/bitops.h
index f3bdcdb..600c59e 100644
--- a/include/asm-sh64/bitops.h
+++ b/include/asm-sh64/bitops.h
@@ -13,6 +13,11 @@
  */
 
 #ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/system.h>
 /* For __swab32 */
@@ -136,6 +141,7 @@
 #include <asm-generic/bitops/__ffs.h>
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/ffs.h>
 #include <asm-generic/bitops/ext2-non-atomic.h>
diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h
index e661857..1438b76 100644
--- a/include/asm-sh64/dma-mapping.h
+++ b/include/asm-sh64/dma-mapping.h
@@ -2,7 +2,7 @@
 #define __ASM_SH_DMA_MAPPING_H
 
 #include <linux/mm.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <asm/io.h>
 
 struct pci_dev;
@@ -71,10 +71,9 @@
 
 	for (i = 0; i < nents; i++) {
 #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-		dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
-			       sg[i].length, dir);
+		dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
 #endif
-		sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
+		sg[i].dma_address = sg_phys(&sg[i]);
 	}
 
 	return nents;
@@ -124,10 +123,9 @@
 
 	for (i = 0; i < nelems; i++) {
 #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
-		dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
-			       sg[i].length, dir);
+		dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
 #endif
-		sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
+		sg[i].dma_address = sg_phys(&sg[i]);
 	}
 }
 
diff --git a/include/asm-sh64/ide.h b/include/asm-sh64/ide.h
index c9d84d5..b6e31e8 100644
--- a/include/asm-sh64/ide.h
+++ b/include/asm-sh64/ide.h
@@ -19,7 +19,6 @@
 /* Without this, the initialisation of PCI IDE cards end up calling
  * ide_init_hwif_ports, which won't work. */
 #ifdef CONFIG_BLK_DEV_IDEPCI
-#define IDE_ARCH_OBSOLETE_INIT 1
 #define ide_default_io_ctl(base)	(0)
 #endif
 
diff --git a/include/asm-sh64/scatterlist.h b/include/asm-sh64/scatterlist.h
index 1c723f2..5109251 100644
--- a/include/asm-sh64/scatterlist.h
+++ b/include/asm-sh64/scatterlist.h
@@ -14,7 +14,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page * page; /* Location for highmem page, if any */
+#ifdef CONFIG_DEBUG_SG
+    unsigned long sg_magic;
+#endif
+    unsigned long page_link;
     unsigned int offset;/* for highmem, page offset */
     dma_addr_t dma_address;
     unsigned int length;
diff --git a/include/asm-sh64/system.h b/include/asm-sh64/system.h
index 5ff9464..be2a15f 100644
--- a/include/asm-sh64/system.h
+++ b/include/asm-sh64/system.h
@@ -62,8 +62,7 @@
 #define smp_read_barrier_depends()	do { } while (0)
 #endif /* CONFIG_SMP */
 
-#define set_rmb(var, value) do { (void)xchg(&var, value); } while (0)
-#define set_mb(var, value) set_rmb(var, value)
+#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
 
 /* Interrupt Control */
 #ifndef HARD_CLI
diff --git a/include/asm-sh64/tlbflush.h b/include/asm-sh64/tlbflush.h
index e45bead..16a164a 100644
--- a/include/asm-sh64/tlbflush.h
+++ b/include/asm-sh64/tlbflush.h
@@ -20,10 +20,6 @@
 extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 			    unsigned long end);
 extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-}
 
 extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
 
diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h
index 329e696..cb3cefa 100644
--- a/include/asm-sparc/bitops.h
+++ b/include/asm-sparc/bitops.h
@@ -14,6 +14,10 @@
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 extern unsigned long ___set_bit(unsigned long *addr, unsigned long mask);
 extern unsigned long ___clear_bit(unsigned long *addr, unsigned long mask);
 extern unsigned long ___change_bit(unsigned long *addr, unsigned long mask);
@@ -96,6 +100,7 @@
 #include <asm-generic/bitops/fls.h>
 #include <asm-generic/bitops/fls64.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
diff --git a/include/asm-sparc/ide.h b/include/asm-sparc/ide.h
index a6d735a..4040227 100644
--- a/include/asm-sparc/ide.h
+++ b/include/asm-sparc/ide.h
@@ -18,7 +18,6 @@
 #undef  MAX_HWIFS
 #define MAX_HWIFS	2
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)	((base) + 0x206) /* obsolete */
 
 #define __ide_insl(data_reg, buffer, wcount) \
diff --git a/include/asm-sparc/ioctls.h b/include/asm-sparc/ioctls.h
index bdf77b0..058c206 100644
--- a/include/asm-sparc/ioctls.h
+++ b/include/asm-sparc/ioctls.h
@@ -15,6 +15,10 @@
 #define TCSETS		_IOW('T', 9, struct termios)
 #define TCSETSW		_IOW('T', 10, struct termios)
 #define TCSETSF		_IOW('T', 11, struct termios)
+#define TCGETS2		_IOR('T', 12, struct termios2)
+#define TCSETS2		_IOW('T', 13, struct termios2)
+#define TCSETSW2	_IOW('T', 14, struct termios2)
+#define TCSETSF2	_IOW('T', 15, struct termios2)
 
 /* Note that all the ioctls that are not available in Linux have a 
  * double underscore on the front to: a) avoid some programs to
diff --git a/include/asm-sparc/of_platform.h b/include/asm-sparc/of_platform.h
index 64a2300..d638737 100644
--- a/include/asm-sparc/of_platform.h
+++ b/include/asm-sparc/of_platform.h
@@ -18,12 +18,9 @@
 
 extern struct bus_type ebus_bus_type;
 extern struct bus_type sbus_bus_type;
-extern struct bus_type of_platform_bus_type;
+
 #define of_bus_type	of_platform_bus_type	/* for compatibility */
 
-extern int of_register_driver(struct of_platform_driver *drv,
-			      struct bus_type *bus);
-extern void of_unregister_driver(struct of_platform_driver *drv);
 extern struct of_device *of_platform_device_create(struct device_node *np,
 						   const char *bus_id,
 						   struct device *parent,
diff --git a/include/asm-sparc/scatterlist.h b/include/asm-sparc/scatterlist.h
index 4055af9..e08d3d7 100644
--- a/include/asm-sparc/scatterlist.h
+++ b/include/asm-sparc/scatterlist.h
@@ -5,7 +5,10 @@
 #include <linux/types.h>
 
 struct scatterlist {
-	struct page *page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long sg_magic;
+#endif
+	unsigned long page_link;
 	unsigned int offset;
 
 	unsigned int length;
diff --git a/include/asm-sparc/termbits.h b/include/asm-sparc/termbits.h
index 5eb00a1..90cf221 100644
--- a/include/asm-sparc/termbits.h
+++ b/include/asm-sparc/termbits.h
@@ -31,6 +31,18 @@
 #endif
 };
 
+struct termios2 {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+	cc_t _x_cc[2];                  /* padding to match ktermios */
+	speed_t c_ispeed;		/* input speed */
+	speed_t c_ospeed;		/* output speed */
+};
+
 struct ktermios {
 	tcflag_t c_iflag;		/* input mode flags */
 	tcflag_t c_oflag;		/* output mode flags */
@@ -160,6 +172,7 @@
 #define CLOCAL	  0x00000800
 #define CBAUDEX   0x00001000
 /* We'll never see these speeds with the Zilogs, but for completeness... */
+#define  BOTHER   0x00001000
 #define  B57600   0x00001001
 #define  B115200  0x00001002
 #define  B230400  0x00001003
@@ -189,6 +202,8 @@
 #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
 #define CRTSCTS	  0x80000000  /* flow control */
 
+#define IBSHIFT	  16		/* Shift from CBAUD to CIBAUD */
+
 /* c_lflag bits */
 #define ISIG	0x00000001
 #define ICANON	0x00000002
diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h
index d767f20..4333232 100644
--- a/include/asm-sparc/termios.h
+++ b/include/asm-sparc/termios.h
@@ -108,13 +108,55 @@
 
 #define user_termios_to_kernel_termios(k, u) \
 ({ \
+	int err; \
+	err  = get_user((k)->c_iflag, &(u)->c_iflag); \
+	err |= get_user((k)->c_oflag, &(u)->c_oflag); \
+	err |= get_user((k)->c_cflag, &(u)->c_cflag); \
+	err |= get_user((k)->c_lflag, &(u)->c_lflag); \
+	err |= get_user((k)->c_line,  &(u)->c_line); \
+	err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+	if ((k)->c_lflag & ICANON) { \
+		err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+		err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+	} else { \
+		err |= get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+		err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+	} \
+	err |= get_user((k)->c_ispeed,  &(u)->c_ispeed); \
+	err |= get_user((k)->c_ospeed,  &(u)->c_ospeed); \
+	err; \
+})
+
+#define kernel_termios_to_user_termios(u, k) \
+({ \
+	int err; \
+	err  = put_user((k)->c_iflag, &(u)->c_iflag); \
+	err |= put_user((k)->c_oflag, &(u)->c_oflag); \
+	err |= put_user((k)->c_cflag, &(u)->c_cflag); \
+	err |= put_user((k)->c_lflag, &(u)->c_lflag); \
+	err |= put_user((k)->c_line, &(u)->c_line); \
+	err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+	if (!((k)->c_lflag & ICANON)) { \
+		err |= put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+		err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+	} else { \
+		err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+		err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+	} \
+	err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \
+	err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \
+	err; \
+})
+
+#define user_termios_to_kernel_termios_1(k, u) \
+({ \
 	get_user((k)->c_iflag, &(u)->c_iflag); \
 	get_user((k)->c_oflag, &(u)->c_oflag); \
 	get_user((k)->c_cflag, &(u)->c_cflag); \
 	get_user((k)->c_lflag, &(u)->c_lflag); \
 	get_user((k)->c_line,  &(u)->c_line); \
 	copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
-	if((k)->c_lflag & ICANON) { \
+	if ((k)->c_lflag & ICANON) { \
 		get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
 		get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
 	} else { \
@@ -124,7 +166,7 @@
 	0; \
 })
 
-#define kernel_termios_to_user_termios(u, k) \
+#define kernel_termios_to_user_termios_1(u, k) \
 ({ \
 	put_user((k)->c_iflag, &(u)->c_iflag); \
 	put_user((k)->c_oflag, &(u)->c_oflag); \
@@ -132,7 +174,7 @@
 	put_user((k)->c_lflag, &(u)->c_lflag); \
 	put_user((k)->c_line, &(u)->c_line); \
 	copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
-	if(!((k)->c_lflag & ICANON)) { \
+	if (!((k)->c_lflag & ICANON)) { \
 		put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
 		put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
 	} else { \
diff --git a/include/asm-sparc/tlbflush.h b/include/asm-sparc/tlbflush.h
index a619da5..b957e29 100644
--- a/include/asm-sparc/tlbflush.h
+++ b/include/asm-sparc/tlbflush.h
@@ -13,7 +13,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 
 #ifdef CONFIG_SMP
@@ -42,11 +41,6 @@
 BTFIXUPDEF_CALL(void, flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
 BTFIXUPDEF_CALL(void, flush_tlb_page, struct vm_area_struct *, unsigned long)
 
-// Thanks to Anton Blanchard, our pagetables became uncached in 2.4. Wee!
-// extern void flush_tlb_pgtables(struct mm_struct *mm,
-//     unsigned long start, unsigned long end);
-#define flush_tlb_pgtables(mm, start, end)	do{ }while(0)
-
 #define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)()
 #define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm)
 #define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end)
diff --git a/include/asm-sparc64/backoff.h b/include/asm-sparc64/backoff.h
new file mode 100644
index 0000000..0e32f8b
--- /dev/null
+++ b/include/asm-sparc64/backoff.h
@@ -0,0 +1,28 @@
+#ifndef _SPARC64_BACKOFF_H
+#define _SPARC64_BACKOFF_H
+
+#define BACKOFF_LIMIT	(4 * 1024)
+
+#ifdef CONFIG_SMP
+
+#define BACKOFF_SETUP(reg)	\
+	mov	1, reg
+
+#define BACKOFF_SPIN(reg, tmp, label)	\
+	mov	reg, tmp; \
+88:	brnz,pt	tmp, 88b; \
+	 sub	tmp, 1, tmp; \
+	cmp	reg, BACKOFF_LIMIT; \
+	bg,pn	%xcc, label; \
+	 nop; \
+	ba,pt	%xcc, label; \
+	 sllx	reg, 1, reg;
+
+#else
+
+#define BACKOFF_SETUP(reg)
+#define BACKOFF_SPIN(reg, tmp, label)
+
+#endif
+
+#endif /* _SPARC64_BACKOFF_H */
diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h
index 3d5e1af..982ce89 100644
--- a/include/asm-sparc64/bitops.h
+++ b/include/asm-sparc64/bitops.h
@@ -7,6 +7,10 @@
 #ifndef _SPARC64_BITOPS_H
 #define _SPARC64_BITOPS_H
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/byteorder.h>
 
@@ -81,6 +85,7 @@
 #include <asm-generic/bitops/hweight.h>
 
 #endif
+#include <asm-generic/bitops/lock.h>
 #endif /* __KERNEL__ */
 
 #include <asm-generic/bitops/find.h>
diff --git a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h
index 55149cf..ac7eb21 100644
--- a/include/asm-sparc64/ide.h
+++ b/include/asm-sparc64/ide.h
@@ -24,7 +24,6 @@
 # endif
 #endif
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)	((base) + 0x206) /* obsolete */
 
 #define __ide_insl(data_reg, buffer, wcount) \
diff --git a/include/asm-sparc64/ioctls.h b/include/asm-sparc64/ioctls.h
index 2223b6d..083c9a0 100644
--- a/include/asm-sparc64/ioctls.h
+++ b/include/asm-sparc64/ioctls.h
@@ -16,6 +16,10 @@
 #define TCSETS		_IOW('T', 9, struct termios)
 #define TCSETSW		_IOW('T', 10, struct termios)
 #define TCSETSF		_IOW('T', 11, struct termios)
+#define TCGETS2		_IOR('T', 12, struct termios2)
+#define TCSETS2		_IOW('T', 13, struct termios2)
+#define TCSETSW2	_IOW('T', 14, struct termios2)
+#define TCSETSF2	_IOW('T', 15, struct termios2)
 
 /* Note that all the ioctls that are not available in Linux have a 
  * double underscore on the front to: a) avoid some programs to
diff --git a/include/asm-sparc64/of_platform.h b/include/asm-sparc64/of_platform.h
index f7c1f17..f15cfa7 100644
--- a/include/asm-sparc64/of_platform.h
+++ b/include/asm-sparc64/of_platform.h
@@ -19,12 +19,9 @@
 extern struct bus_type isa_bus_type;
 extern struct bus_type ebus_bus_type;
 extern struct bus_type sbus_bus_type;
-extern struct bus_type of_platform_bus_type;
+
 #define of_bus_type	of_platform_bus_type	/* for compatibility */
 
-extern int of_register_driver(struct of_platform_driver *drv,
-			      struct bus_type *bus);
-extern void of_unregister_driver(struct of_platform_driver *drv);
 extern struct of_device *of_platform_device_create(struct device_node *np,
 						   const char *bus_id,
 						   struct device *parent,
diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h
index 703c5bb..6df23f0 100644
--- a/include/asm-sparc64/scatterlist.h
+++ b/include/asm-sparc64/scatterlist.h
@@ -6,7 +6,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;
 
 	unsigned int	length;
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
index 42c0994..1c1c5ea 100644
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -26,7 +26,7 @@
  *	Private routines/data
  */
  
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/atomic.h>
 #include <asm/percpu.h>
 
diff --git a/include/asm-sparc64/termbits.h b/include/asm-sparc64/termbits.h
index 705cd44..ebe31c1 100644
--- a/include/asm-sparc64/termbits.h
+++ b/include/asm-sparc64/termbits.h
@@ -5,8 +5,6 @@
 
 typedef unsigned char   cc_t;
 typedef unsigned int    speed_t;
-
-/* XXX is this right for sparc64?  it was an unsigned long... XXX */
 typedef unsigned int    tcflag_t;
 
 #define NCC 8
@@ -33,6 +31,18 @@
 #endif
 };
 
+struct termios2 {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+	cc_t _x_cc[2];                  /* padding to match ktermios */
+	speed_t c_ispeed;		/* input speed */
+	speed_t c_ospeed;		/* output speed */
+};
+
 struct ktermios {
 	tcflag_t c_iflag;		/* input mode flags */
 	tcflag_t c_oflag;		/* output mode flags */
@@ -161,6 +171,7 @@
 #define HUPCL	  0x00000400
 #define CLOCAL	  0x00000800
 #define CBAUDEX   0x00001000
+#define  BOTHER   0x00001000
 #define  B57600   0x00001001
 #define  B115200  0x00001002
 #define  B230400  0x00001003
@@ -190,6 +201,8 @@
 #define CMSPAR    0x40000000  /* mark or space (stick) parity */
 #define CRTSCTS	  0x80000000  /* flow control */
 
+#define IBSHIFT	  16		/* Shift from CBAUD to CIBAUD */
+
 /* c_lflag bits */
 #define ISIG	0x00000001
 #define ICANON	0x00000002
diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h
index f05d390..ef52721 100644
--- a/include/asm-sparc64/termios.h
+++ b/include/asm-sparc64/termios.h
@@ -123,6 +123,8 @@
 		err |= get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
 		err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
 	} \
+	err |= get_user((k)->c_ispeed,  &(u)->c_ispeed); \
+	err |= get_user((k)->c_ospeed,  &(u)->c_ospeed); \
 	err; \
 })
 
@@ -142,6 +144,46 @@
 		err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
 		err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
 	} \
+	err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \
+	err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \
+	err; \
+})
+
+#define user_termios_to_kernel_termios_1(k, u) \
+({ \
+	int err; \
+	err  = get_user((k)->c_iflag, &(u)->c_iflag); \
+	err |= get_user((k)->c_oflag, &(u)->c_oflag); \
+	err |= get_user((k)->c_cflag, &(u)->c_cflag); \
+	err |= get_user((k)->c_lflag, &(u)->c_lflag); \
+	err |= get_user((k)->c_line,  &(u)->c_line); \
+	err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+	if((k)->c_lflag & ICANON) { \
+		err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+		err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+	} else { \
+		err |= get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+		err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+	} \
+	err; \
+})
+
+#define kernel_termios_to_user_termios_1(u, k) \
+({ \
+	int err; \
+	err  = put_user((k)->c_iflag, &(u)->c_iflag); \
+	err |= put_user((k)->c_oflag, &(u)->c_oflag); \
+	err |= put_user((k)->c_cflag, &(u)->c_cflag); \
+	err |= put_user((k)->c_lflag, &(u)->c_lflag); \
+	err |= put_user((k)->c_line, &(u)->c_line); \
+	err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+	if(!((k)->c_lflag & ICANON)) { \
+		err |= put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+		err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+	} else { \
+		err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+		err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+	} \
 	err; \
 })
 
diff --git a/include/asm-sparc64/tlbflush.h b/include/asm-sparc64/tlbflush.h
index 3487328..fbb675d 100644
--- a/include/asm-sparc64/tlbflush.h
+++ b/include/asm-sparc64/tlbflush.h
@@ -41,11 +41,4 @@
 
 #endif /* ! CONFIG_SMP */
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end)
-{
-	/* We don't use virtual page tables for TLB miss processing
-	 * any more.  Nowadays we use the TSB.
-	 */
-}
-
 #endif /* _SPARC64_TLBFLUSH_H */
diff --git a/include/asm-um/bitops.h b/include/asm-um/bitops.h
index 46d7819..e4d38d4 100644
--- a/include/asm-um/bitops.h
+++ b/include/asm-um/bitops.h
@@ -1,6 +1,10 @@
 #ifndef __UM_BITOPS_H
 #define __UM_BITOPS_H
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include "asm/arch/bitops.h"
 
 #endif
diff --git a/include/asm-um/tlbflush.h b/include/asm-um/tlbflush.h
index 9d647c5..614f2c0 100644
--- a/include/asm-um/tlbflush.h
+++ b/include/asm-um/tlbflush.h
@@ -17,7 +17,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_kernel_vm() flushes the kernel vm area
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  */
 
 extern void flush_tlb_all(void);
@@ -29,9 +28,4 @@
 extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
 extern void __flush_tlb_one(unsigned long addr);
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-}
-
 #endif
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h
index 1fa99ba..f82f5b4 100644
--- a/include/asm-v850/bitops.h
+++ b/include/asm-v850/bitops.h
@@ -13,6 +13,9 @@
 #ifndef __V850_BITOPS_H__
 #define __V850_BITOPS_H__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
 
 #include <linux/compiler.h>	/* unlikely  */
 #include <asm/byteorder.h>	/* swab32 */
@@ -145,6 +148,7 @@
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #include <asm-generic/bitops/ext2-non-atomic.h>
 #define ext2_set_bit_atomic(l,n,a)      test_and_set_bit(n,a)
diff --git a/include/asm-v850/scatterlist.h b/include/asm-v850/scatterlist.h
index 56f4029..02d27b3 100644
--- a/include/asm-v850/scatterlist.h
+++ b/include/asm-v850/scatterlist.h
@@ -17,7 +17,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page	*page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned	offset;
 	dma_addr_t	dma_address;
 	unsigned	length;
diff --git a/include/asm-v850/system.h b/include/asm-v850/system.h
index 0de2481..a34ddfa 100644
--- a/include/asm-v850/system.h
+++ b/include/asm-v850/system.h
@@ -66,8 +66,7 @@
 #define rmb()			mb ()
 #define wmb()			mb ()
 #define read_barrier_depends()	((void)0)
-#define set_rmb(var, value)	do { xchg (&var, value); } while (0)
-#define set_mb(var, value)	set_rmb (var, value)
+#define set_mb(var, value)	do { xchg (&var, value); } while (0)
 
 #define smp_mb()	mb ()
 #define smp_rmb()	rmb ()
diff --git a/include/asm-v850/tlbflush.h b/include/asm-v850/tlbflush.h
index 5f2f85f..c44aa64 100644
--- a/include/asm-v850/tlbflush.h
+++ b/include/asm-v850/tlbflush.h
@@ -61,10 +61,4 @@
 	BUG ();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-	BUG ();
-}
-
 #endif /* __V850_TLBFLUSH_H__ */
diff --git a/include/asm-x86/Kbuild b/include/asm-x86/Kbuild
index 559830e..5e3539c 100644
--- a/include/asm-x86/Kbuild
+++ b/include/asm-x86/Kbuild
@@ -1,6 +1,7 @@
 include include/asm-generic/Kbuild.asm
 
 header-y += boot.h
+header-y += bootparam.h
 header-y += debugreg.h
 header-y += ldt.h
 header-y += msr-index.h
@@ -14,8 +15,10 @@
 unifdef-y += a.out_64.h
 unifdef-y += byteorder_32.h
 unifdef-y += byteorder_64.h
+unifdef-y += e820.h
 unifdef-y += elf_32.h
 unifdef-y += elf_64.h
+unifdef-y += ist.h
 unifdef-y += mce.h
 unifdef-y += msgbuf_32.h
 unifdef-y += msgbuf_64.h
diff --git a/include/asm-x86/acpi_32.h b/include/asm-x86/acpi_32.h
index 125179ad..723493e 100644
--- a/include/asm-x86/acpi_32.h
+++ b/include/asm-x86/acpi_32.h
@@ -81,11 +81,7 @@
         :"=r"(n_hi), "=r"(n_lo)     \
         :"0"(n_hi), "1"(n_lo))
 
-#ifdef CONFIG_X86_IO_APIC
-extern void check_acpi_pci(void);
-#else
-static inline void check_acpi_pci(void) { }
-#endif
+extern void early_quirks(void);
 
 #ifdef CONFIG_ACPI
 extern int acpi_lapic;
diff --git a/include/asm-x86/bitops_32.h b/include/asm-x86/bitops_32.h
index a20fe98..3268a34 100644
--- a/include/asm-x86/bitops_32.h
+++ b/include/asm-x86/bitops_32.h
@@ -5,6 +5,10 @@
  * Copyright 1992, Linus Torvalds.
  */
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <linux/compiler.h>
 #include <asm/alternative.h>
 
@@ -402,6 +406,7 @@
 }
 
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-x86/bitops_64.h b/include/asm-x86/bitops_64.h
index 1d7d9b4..dacaa5f 100644
--- a/include/asm-x86/bitops_64.h
+++ b/include/asm-x86/bitops_64.h
@@ -5,6 +5,10 @@
  * Copyright 1992, Linus Torvalds.
  */
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm/alternative.h>
 
 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
@@ -408,6 +412,7 @@
 #define ARCH_HAS_FAST_MULTIPLIER 1
 
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-x86/bootparam.h b/include/asm-x86/bootparam.h
index ef67b59..19f3ddf 100644
--- a/include/asm-x86/bootparam.h
+++ b/include/asm-x86/bootparam.h
@@ -10,80 +10,85 @@
 #include <video/edid.h>
 
 struct setup_header {
-	u8	setup_sects;
-	u16	root_flags;
-	u32	syssize;
-	u16	ram_size;
+	__u8	setup_sects;
+	__u16	root_flags;
+	__u32	syssize;
+	__u16	ram_size;
 #define RAMDISK_IMAGE_START_MASK	0x07FF
 #define RAMDISK_PROMPT_FLAG		0x8000
 #define RAMDISK_LOAD_FLAG		0x4000
-	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;
+	__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	(1<<0)
+#define KEEP_SEGMENTS	(1<<6)
+#define CAN_USE_HEAP	(1<<7)
+	__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;
+	__u8	_pad2[3];
+	__u32	cmdline_size;
+	__u32	hardware_subarch;
+	__u64	hardware_subarch_data;
 } __attribute__((packed));
 
 struct sys_desc_table {
-	u16 length;
-	u8  table[14];
+	__u16 length;
+	__u8  table[14];
 };
 
 struct efi_info {
-	u32 _pad1;
-	u32 efi_systab;
-	u32 efi_memdesc_size;
-	u32 efi_memdesc_version;
-	u32 efi_memmap;
-	u32 efi_memmap_size;
-	u32 _pad2[2];
+	__u32 _pad1;
+	__u32 efi_systab;
+	__u32 efi_memdesc_size;
+	__u32 efi_memdesc_version;
+	__u32 efi_memmap;
+	__u32 efi_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 */
+	__u8  _pad2[12];				/* 0x054 */
 	struct ist_info ist_info;			/* 0x060 */
-	u8  _pad3[16];					/* 0x070 */
-	u8  hd0_info[16];	/* obsolete! */		/* 0x080 */
-	u8  hd1_info[16];	/* obsolete! */		/* 0x090 */
+	__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 */
+	__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 */
+	__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 */
+	__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 */
+	__u8  _pad8[48];				/* 0xcd0 */
 	struct edd_info eddbuf[EDDMAXNR];		/* 0xd00 */
-	u8  _pad9[276];					/* 0xeec */
+	__u8  _pad9[276];				/* 0xeec */
 } __attribute__((packed));
 
 #endif /* _ASM_BOOTPARAM_H */
diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h
index b3d43de..9411a2d 100644
--- a/include/asm-x86/cacheflush.h
+++ b/include/asm-x86/cacheflush.h
@@ -27,6 +27,7 @@
 void global_flush_tlb(void);
 int change_page_attr(struct page *page, int numpages, pgprot_t prot);
 int change_page_attr_addr(unsigned long addr, int numpages, pgprot_t prot);
+void clflush_cache_range(void *addr, int size);
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
 /* internal debugging function */
diff --git a/include/asm-x86/compat.h b/include/asm-x86/compat.h
index 53cb96b..66ba798 100644
--- a/include/asm-x86/compat.h
+++ b/include/asm-x86/compat.h
@@ -6,6 +6,7 @@
  */
 #include <linux/types.h>
 #include <linux/sched.h>
+#include <asm/user32.h>
 
 #define COMPAT_USER_HZ	100
 
@@ -181,6 +182,11 @@
 };
 
 /*
+ * The type of struct elf_prstatus.pr_reg in compatible core dumps.
+ */
+typedef struct user_regs_struct32 compat_elf_gregset_t;
+
+/*
  * A pointer passed in from user mode. This should not
  * be used for syscall parameters, just declare them
  * as pointers because the syscall entry code will have
diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h
index ac991b5..7d9c938 100644
--- a/include/asm-x86/desc_64.h
+++ b/include/asm-x86/desc_64.h
@@ -20,6 +20,16 @@
 #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
 #define clear_LDT()  asm volatile("lldt %w0"::"r" (0))
 
+static inline unsigned long __store_tr(void)
+{
+       unsigned long tr;
+
+       asm volatile ("str %w0":"=r" (tr));
+       return tr;
+}
+
+#define store_tr(tr) (tr) = __store_tr()
+
 /*
  * This is the ldt that every process will get unless we need
  * something other than this.
@@ -31,6 +41,16 @@
 /* the cpu gdt accessor */
 #define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address)
 
+static inline void load_gdt(const struct desc_ptr *ptr)
+{
+	asm volatile("lgdt %w0"::"m" (*ptr));
+}
+
+static inline void store_gdt(struct desc_ptr *ptr)
+{
+       asm("sgdt %w0":"=m" (*ptr));
+}
+
 static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)  
 {
 	struct gate_struct s; 	
@@ -71,6 +91,16 @@
 	_set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist);
 }
 
+static inline void load_idt(const struct desc_ptr *ptr)
+{
+	asm volatile("lidt %w0"::"m" (*ptr));
+}
+
+static inline void store_idt(struct desc_ptr *dtr)
+{
+       asm("sidt %w0":"=m" (*dtr));
+}
+
 static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, 
 					 unsigned size) 
 { 
diff --git a/include/asm-x86/device.h b/include/asm-x86/device.h
index d9ee5e5..87a7153 100644
--- a/include/asm-x86/device.h
+++ b/include/asm-x86/device.h
@@ -5,6 +5,9 @@
 #ifdef CONFIG_ACPI
 	void	*acpi_handle;
 #endif
+#ifdef CONFIG_DMAR
+	void *iommu; /* hook for IOMMU specific extension */
+#endif
 };
 
 #endif /* _ASM_X86_DEVICE_H */
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index 6a2d26c..55f01bd 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -45,9 +45,9 @@
 	WARN_ON(nents == 0 || sglist[0].length == 0);
 
 	for_each_sg(sglist, sg, nents, i) {
-		BUG_ON(!sg->page);
+		BUG_ON(!sg_page(sg));
 
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_address = sg_phys(sg);
 	}
 
 	flush_write_buffers();
diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h
index 5d4d218..3e214f3 100644
--- a/include/asm-x86/e820.h
+++ b/include/asm-x86/e820.h
@@ -1,5 +1,33 @@
+#ifndef __ASM_E820_H
+#define __ASM_E820_H
+#define E820MAP	0x2d0		/* our map */
+#define E820MAX	128		/* number of entries in E820MAP */
+#define E820NR	0x1e8		/* # entries in E820MAP */
+
+#define E820_RAM	1
+#define E820_RESERVED	2
+#define E820_ACPI	3
+#define E820_NVS	4
+
+#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 {
+	__u32 nr_map;
+	struct e820entry map[E820MAX];
+};
+#endif /* __ASSEMBLY__ */
+
+#ifdef __KERNEL__
 #ifdef CONFIG_X86_32
 # include "e820_32.h"
 #else
 # include "e820_64.h"
 #endif
+#endif /* __KERNEL__ */
+
+#endif  /* __ASM_E820_H */
diff --git a/include/asm-x86/e820_32.h b/include/asm-x86/e820_32.h
index cf67dbb..03f60c6 100644
--- a/include/asm-x86/e820_32.h
+++ b/include/asm-x86/e820_32.h
@@ -12,30 +12,10 @@
 #ifndef __E820_HEADER
 #define __E820_HEADER
 
-#define E820MAP	0x2d0		/* our map */
-#define E820MAX	128		/* number of entries in E820MAP */
-#define E820NR	0x1e8		/* # entries in E820MAP */
-
-#define E820_RAM	1
-#define E820_RESERVED	2
-#define E820_ACPI	3
-#define E820_NVS	4
-
 #define HIGH_MEMORY	(1024*1024)
 
 #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 {
-	u32 nr_map;
-	struct e820entry map[E820MAX];
-};
-
 extern struct e820map e820;
 
 extern int e820_all_mapped(unsigned long start, unsigned long end,
@@ -56,5 +36,4 @@
 #endif
 
 #endif/*!__ASSEMBLY__*/
-
 #endif/*__E820_HEADER*/
diff --git a/include/asm-x86/e820_64.h b/include/asm-x86/e820_64.h
index 3486e70..0bd4787 100644
--- a/include/asm-x86/e820_64.h
+++ b/include/asm-x86/e820_64.h
@@ -11,27 +11,7 @@
 #ifndef __E820_HEADER
 #define __E820_HEADER
 
-#define E820MAP	0x2d0		/* our map */
-#define E820MAX	128		/* number of entries in E820MAP */
-#define E820NR	0x1e8		/* # entries in E820MAP */
-
-#define E820_RAM	1
-#define E820_RESERVED	2
-#define E820_ACPI	3
-#define E820_NVS	4
-
 #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 {
-	u32 nr_map;
-	struct e820entry map[E820MAX];
-};
-
 extern unsigned long find_e820_area(unsigned long start, unsigned long end, 
 				    unsigned size);
 extern void add_memory_region(unsigned long start, unsigned long size, 
diff --git a/include/asm-x86/geode.h b/include/asm-x86/geode.h
index d948988..771af33 100644
--- a/include/asm-x86/geode.h
+++ b/include/asm-x86/geode.h
@@ -38,6 +38,8 @@
 #define MSR_LBAR_ACPI		0x5140000E
 #define MSR_LBAR_PMS		0x5140000F
 
+#define MSR_DIVIL_SOFT_RESET	0x51400017
+
 #define MSR_PIC_YSEL_LOW	0x51400020
 #define MSR_PIC_YSEL_HIGH	0x51400021
 #define MSR_PIC_ZSEL_LOW	0x51400022
diff --git a/include/asm-x86/hpet.h b/include/asm-x86/hpet.h
index d4ab6db..b1f3c1e 100644
--- a/include/asm-x86/hpet.h
+++ b/include/asm-x86/hpet.h
@@ -3,12 +3,6 @@
 
 #ifdef CONFIG_HPET_TIMER
 
-/*
- * Documentation on HPET can be found at:
- *      http://www.intel.com/ial/home/sp/pcmmspec.htm
- *      ftp://download.intel.com/ial/home/sp/mmts098.pdf
- */
-
 #define HPET_MMAP_SIZE		1024
 
 #define HPET_ID			0x000
@@ -64,6 +58,7 @@
 /* hpet memory map physical address */
 extern unsigned long hpet_address;
 extern unsigned long force_hpet_address;
+extern int hpet_force_user;
 extern int is_hpet_enabled(void);
 extern int hpet_enable(void);
 extern unsigned long hpet_readl(unsigned long a);
diff --git a/include/asm-x86/ide.h b/include/asm-x86/ide.h
index e7817a3..42130ad 100644
--- a/include/asm-x86/ide.h
+++ b/include/asm-x86/ide.h
@@ -62,7 +62,6 @@
 	}
 }
 
-#define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)	((base) + 0x206) /* obsolete */
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/include/asm-x86/io_apic_64.h b/include/asm-x86/io_apic_64.h
index d9f2e54..e2c1367 100644
--- a/include/asm-x86/io_apic_64.h
+++ b/include/asm-x86/io_apic_64.h
@@ -133,4 +133,6 @@
 
 extern spinlock_t i8259A_lock;
 
+extern int timer_over_8254;
+
 #endif
diff --git a/include/asm-x86/ipi.h b/include/asm-x86/ipi.h
index a7c75ea..6d011bd 100644
--- a/include/asm-x86/ipi.h
+++ b/include/asm-x86/ipi.h
@@ -119,7 +119,7 @@
 	 */
 	local_irq_save(flags);
 	for_each_cpu_mask(query_cpu, mask) {
-		__send_IPI_dest_field(x86_cpu_to_apicid[query_cpu],
+		__send_IPI_dest_field(per_cpu(x86_cpu_to_apicid, query_cpu),
 				      vector, APIC_DEST_PHYSICAL);
 	}
 	local_irq_restore(flags);
diff --git a/include/asm-x86/irq_32.h b/include/asm-x86/irq_32.h
index 36f3106..aca9c96 100644
--- a/include/asm-x86/irq_32.h
+++ b/include/asm-x86/irq_32.h
@@ -45,4 +45,7 @@
 void init_IRQ(void);
 void __init native_init_IRQ(void);
 
+/* Interrupt vector management */
+extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
+
 #endif /* _ASM_IRQ_H */
diff --git a/include/asm-x86/ist.h b/include/asm-x86/ist.h
index ef2003e..6ec6cee 100644
--- a/include/asm-x86/ist.h
+++ b/include/asm-x86/ist.h
@@ -17,17 +17,17 @@
  */
 
 
-#ifdef __KERNEL__
-
 #include <linux/types.h>
 
 struct ist_info {
-	u32 signature;
-	u32 command;
-	u32 event;
-	u32 perf_level;
+	__u32 signature;
+	__u32 command;
+	__u32 event;
+	__u32 perf_level;
 };
 
+#ifdef __KERNEL__
+
 extern struct ist_info ist_info;
 
 #endif	/* __KERNEL__ */
diff --git a/include/asm-x86/lguest.h b/include/asm-x86/lguest.h
new file mode 100644
index 0000000..ccd3384
--- /dev/null
+++ b/include/asm-x86/lguest.h
@@ -0,0 +1,86 @@
+#ifndef _X86_LGUEST_H
+#define _X86_LGUEST_H
+
+#define GDT_ENTRY_LGUEST_CS	10
+#define GDT_ENTRY_LGUEST_DS	11
+#define LGUEST_CS		(GDT_ENTRY_LGUEST_CS * 8)
+#define LGUEST_DS		(GDT_ENTRY_LGUEST_DS * 8)
+
+#ifndef __ASSEMBLY__
+#include <asm/desc.h>
+
+#define GUEST_PL 1
+
+/* Every guest maps the core switcher code. */
+#define SHARED_SWITCHER_PAGES \
+	DIV_ROUND_UP(end_switcher_text - start_switcher_text, PAGE_SIZE)
+/* Pages for switcher itself, then two pages per cpu */
+#define TOTAL_SWITCHER_PAGES (SHARED_SWITCHER_PAGES + 2 * NR_CPUS)
+
+/* We map at -4M for ease of mapping into the guest (one PTE page). */
+#define SWITCHER_ADDR 0xFFC00000
+
+/* Found in switcher.S */
+extern unsigned long default_idt_entries[];
+
+struct lguest_regs
+{
+	/* Manually saved part. */
+	unsigned long eax, ebx, ecx, edx;
+	unsigned long esi, edi, ebp;
+	unsigned long gs;
+	unsigned long fs, ds, es;
+	unsigned long trapnum, errcode;
+	/* Trap pushed part */
+	unsigned long eip;
+	unsigned long cs;
+	unsigned long eflags;
+	unsigned long esp;
+	unsigned long ss;
+};
+
+/* This is a guest-specific page (mapped ro) into the guest. */
+struct lguest_ro_state
+{
+	/* Host information we need to restore when we switch back. */
+	u32 host_cr3;
+	struct Xgt_desc_struct host_idt_desc;
+	struct Xgt_desc_struct host_gdt_desc;
+	u32 host_sp;
+
+	/* Fields which are used when guest is running. */
+	struct Xgt_desc_struct guest_idt_desc;
+	struct Xgt_desc_struct guest_gdt_desc;
+	struct i386_hw_tss guest_tss;
+	struct desc_struct guest_idt[IDT_ENTRIES];
+	struct desc_struct guest_gdt[GDT_ENTRIES];
+};
+
+struct lguest_arch
+{
+	/* The GDT entries copied into lguest_ro_state when running. */
+	struct desc_struct gdt[GDT_ENTRIES];
+
+	/* The IDT entries: some copied into lguest_ro_state when running. */
+	struct desc_struct idt[IDT_ENTRIES];
+
+	/* The address of the last guest-visible pagefault (ie. cr2). */
+	unsigned long last_pagefault;
+};
+
+static inline void lguest_set_ts(void)
+{
+	u32 cr0;
+
+	cr0 = read_cr0();
+	if (!(cr0 & 8))
+		write_cr0(cr0|8);
+}
+
+/* Full 4G segment descriptors, suitable for CS and DS. */
+#define FULL_EXEC_SEGMENT ((struct desc_struct){0x0000ffff, 0x00cf9b00})
+#define FULL_SEGMENT ((struct desc_struct){0x0000ffff, 0x00cf9300})
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/include/asm-x86/lguest_hcall.h b/include/asm-x86/lguest_hcall.h
new file mode 100644
index 0000000..f948491
--- /dev/null
+++ b/include/asm-x86/lguest_hcall.h
@@ -0,0 +1,71 @@
+/* Architecture specific portion of the lguest hypercalls */
+#ifndef _X86_LGUEST_HCALL_H
+#define _X86_LGUEST_HCALL_H
+
+#define LHCALL_FLUSH_ASYNC	0
+#define LHCALL_LGUEST_INIT	1
+#define LHCALL_CRASH		2
+#define LHCALL_LOAD_GDT		3
+#define LHCALL_NEW_PGTABLE	4
+#define LHCALL_FLUSH_TLB	5
+#define LHCALL_LOAD_IDT_ENTRY	6
+#define LHCALL_SET_STACK	7
+#define LHCALL_TS		8
+#define LHCALL_SET_CLOCKEVENT	9
+#define LHCALL_HALT		10
+#define LHCALL_SET_PTE		14
+#define LHCALL_SET_PMD		15
+#define LHCALL_LOAD_TLS		16
+#define LHCALL_NOTIFY		17
+
+/*G:031 First, how does our Guest contact the Host to ask for privileged
+ * operations?  There are two ways: the direct way is to make a "hypercall",
+ * to make requests of the Host Itself.
+ *
+ * Our hypercall mechanism uses the highest unused trap code (traps 32 and
+ * above are used by real hardware interrupts).  Seventeen hypercalls are
+ * available: the hypercall number is put in the %eax register, and the
+ * arguments (when required) are placed in %edx, %ebx and %ecx.  If a return
+ * value makes sense, it's returned in %eax.
+ *
+ * Grossly invalid calls result in Sudden Death at the hands of the vengeful
+ * Host, rather than returning failure.  This reflects Winston Churchill's
+ * definition of a gentleman: "someone who is only rude intentionally". */
+#define LGUEST_TRAP_ENTRY 0x1F
+
+#ifndef __ASSEMBLY__
+#include <asm/hw_irq.h>
+
+static inline unsigned long
+hcall(unsigned long call,
+      unsigned long arg1, unsigned long arg2, unsigned long arg3)
+{
+	/* "int" is the Intel instruction to trigger a trap. */
+	asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
+		       /* The call is in %eax (aka "a"), and can be replaced */
+		     : "=a"(call)
+		       /* The other arguments are in %eax, %edx, %ebx & %ecx */
+		     : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3)
+		       /* "memory" means this might write somewhere in memory.
+			* This isn't true for all calls, but it's safe to tell
+			* gcc that it might happen so it doesn't get clever. */
+		     : "memory");
+	return call;
+}
+/*:*/
+
+void async_hcall(unsigned long call,
+		 unsigned long arg1, unsigned long arg2, unsigned long arg3);
+
+/* Can't use our min() macro here: needs to be a constant */
+#define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32)
+
+#define LHCALL_RING_SIZE 64
+struct hcall_args
+{
+	/* These map directly onto eax, ebx, ecx, edx in struct lguest_regs */
+	unsigned long arg0, arg2, arg3, arg1;
+};
+
+#endif /* !__ASSEMBLY__ */
+#endif	/* _I386_LGUEST_HCALL_H */
diff --git a/include/asm-x86/msr-index.h b/include/asm-x86/msr-index.h
index a02eb29..a494473 100644
--- a/include/asm-x86/msr-index.h
+++ b/include/asm-x86/msr-index.h
@@ -73,8 +73,32 @@
 #define MSR_P6_EVNTSEL0			0x00000186
 #define MSR_P6_EVNTSEL1			0x00000187
 
-/* K7/K8 MSRs. Not complete. See the architecture manual for a more
+/* AMD64 MSRs. Not complete. See the architecture manual for a more
    complete list. */
+
+#define MSR_AMD64_IBSFETCHCTL		0xc0011030
+#define MSR_AMD64_IBSFETCHLINAD		0xc0011031
+#define MSR_AMD64_IBSFETCHPHYSAD	0xc0011032
+#define MSR_AMD64_IBSOPCTL		0xc0011033
+#define MSR_AMD64_IBSOPRIP		0xc0011034
+#define MSR_AMD64_IBSOPDATA		0xc0011035
+#define MSR_AMD64_IBSOPDATA2		0xc0011036
+#define MSR_AMD64_IBSOPDATA3		0xc0011037
+#define MSR_AMD64_IBSDCLINAD		0xc0011038
+#define MSR_AMD64_IBSDCPHYSAD		0xc0011039
+#define MSR_AMD64_IBSCTL		0xc001103a
+
+/* K8 MSRs */
+#define MSR_K8_TOP_MEM1			0xc001001a
+#define MSR_K8_TOP_MEM2			0xc001001d
+#define MSR_K8_SYSCFG			0xc0010010
+#define MSR_K8_HWCR			0xc0010015
+#define MSR_K8_ENABLE_C1E		0xc0010055
+#define K8_MTRRFIXRANGE_DRAM_ENABLE	0x00040000 /* MtrrFixDramEn bit    */
+#define K8_MTRRFIXRANGE_DRAM_MODIFY	0x00080000 /* MtrrFixDramModEn bit */
+#define K8_MTRR_RDMEM_WRMEM_MASK	0x18181818 /* Mask: RdMem|WrMem    */
+
+/* K7 MSRs */
 #define MSR_K7_EVNTSEL0			0xc0010000
 #define MSR_K7_PERFCTR0			0xc0010004
 #define MSR_K7_EVNTSEL1			0xc0010001
@@ -83,20 +107,10 @@
 #define MSR_K7_PERFCTR2			0xc0010006
 #define MSR_K7_EVNTSEL3			0xc0010003
 #define MSR_K7_PERFCTR3			0xc0010007
-#define MSR_K8_TOP_MEM1			0xc001001a
 #define MSR_K7_CLK_CTL			0xc001001b
-#define MSR_K8_TOP_MEM2			0xc001001d
-#define MSR_K8_SYSCFG			0xc0010010
-
-#define K8_MTRRFIXRANGE_DRAM_ENABLE	0x00040000 /* MtrrFixDramEn bit    */
-#define K8_MTRRFIXRANGE_DRAM_MODIFY	0x00080000 /* MtrrFixDramModEn bit */
-#define K8_MTRR_RDMEM_WRMEM_MASK	0x18181818 /* Mask: RdMem|WrMem    */
-
 #define MSR_K7_HWCR			0xc0010015
-#define MSR_K8_HWCR			0xc0010015
 #define MSR_K7_FID_VID_CTL		0xc0010041
 #define MSR_K7_FID_VID_STATUS		0xc0010042
-#define MSR_K8_ENABLE_C1E		0xc0010055
 
 /* K6 MSRs */
 #define MSR_K6_EFER			0xc0000080
diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h
index acd4b33..ed3e70d 100644
--- a/include/asm-x86/pgtable_32.h
+++ b/include/asm-x86/pgtable_32.h
@@ -17,10 +17,7 @@
 #include <linux/threads.h>
 #include <asm/paravirt.h>
 
-#ifndef _I386_BITOPS_H
-#include <asm/bitops.h>
-#endif
-
+#include <linux/bitops.h>
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h
index a79f535..9b0ff47 100644
--- a/include/asm-x86/pgtable_64.h
+++ b/include/asm-x86/pgtable_64.h
@@ -9,7 +9,7 @@
  * the x86-64 page table tree.
  */
 #include <asm/processor.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <linux/threads.h>
 #include <asm/pda.h>
 
diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h
index 83800e7..13976b0 100644
--- a/include/asm-x86/processor_32.h
+++ b/include/asm-x86/processor_32.h
@@ -79,6 +79,7 @@
 	unsigned char booted_cores;	/* number of cores as seen by OS */
 	__u8 phys_proc_id; 		/* Physical processor id. */
 	__u8 cpu_core_id;  		/* Core id */
+	__u8 cpu_index;			/* index into per_cpu list */
 #endif
 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
 
@@ -103,14 +104,19 @@
 DECLARE_PER_CPU(struct tss_struct, init_tss);
 
 #ifdef CONFIG_SMP
-extern struct cpuinfo_x86 cpu_data[];
-#define current_cpu_data cpu_data[smp_processor_id()]
+DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
+#define cpu_data(cpu)		per_cpu(cpu_info, cpu)
+#define current_cpu_data	cpu_data(smp_processor_id())
 #else
-#define cpu_data (&boot_cpu_data)
-#define current_cpu_data boot_cpu_data
+#define cpu_data(cpu)		boot_cpu_data
+#define current_cpu_data	boot_cpu_data
 #endif
 
-extern	int cpu_llc_id[NR_CPUS];
+/*
+ * the following now lives in the per cpu area:
+ * extern	int cpu_llc_id[NR_CPUS];
+ */
+DECLARE_PER_CPU(u8, cpu_llc_id);
 extern char ignore_fpu_irq;
 
 void __init cpu_detect(struct cpuinfo_x86 *c);
diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h
index f422bec..e4f1997 100644
--- a/include/asm-x86/processor_64.h
+++ b/include/asm-x86/processor_64.h
@@ -74,6 +74,7 @@
 	__u8	booted_cores;	/* number of cores as seen by OS */
 	__u8	phys_proc_id;	/* Physical Processor id. */
 	__u8	cpu_core_id;	/* Core id. */
+	__u8	cpu_index;	/* index into per_cpu list */
 #endif
 } ____cacheline_aligned;
 
@@ -88,11 +89,12 @@
 #define X86_VENDOR_UNKNOWN 0xff
 
 #ifdef CONFIG_SMP
-extern struct cpuinfo_x86 cpu_data[];
-#define current_cpu_data cpu_data[smp_processor_id()]
+DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
+#define cpu_data(cpu)		per_cpu(cpu_info, cpu)
+#define current_cpu_data	cpu_data(smp_processor_id())
 #else
-#define cpu_data (&boot_cpu_data)
-#define current_cpu_data boot_cpu_data
+#define cpu_data(cpu)		boot_cpu_data
+#define current_cpu_data	boot_cpu_data
 #endif
 
 extern char ignore_irq13;
@@ -390,12 +392,6 @@
 	asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
 } 
 
-#define ARCH_HAS_PREFETCH
-static inline void prefetch(void *x) 
-{ 
-	asm volatile("prefetcht0 (%0)" :: "r" (x));
-} 
-
 #define ARCH_HAS_PREFETCHW 1
 static inline void prefetchw(void *x) 
 { 
diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h
index c44a3a9..dabba55 100644
--- a/include/asm-x86/proto.h
+++ b/include/asm-x86/proto.h
@@ -83,8 +83,6 @@
 extern int reboot_force;
 extern int notsc_setup(char *);
 
-extern int timer_over_8254;
-
 extern int gsi_irq_sharing(int gsi);
 
 extern int force_mwait;
diff --git a/include/asm-x86/ptrace_32.h b/include/asm-x86/ptrace_32.h
index 6002597..78d063d 100644
--- a/include/asm-x86/ptrace_32.h
+++ b/include/asm-x86/ptrace_32.h
@@ -55,6 +55,8 @@
 }
 
 #define instruction_pointer(regs) ((regs)->eip)
+#define frame_pointer(regs) ((regs)->ebp)
+#define stack_pointer(regs) ((regs)->esp)
 #define regs_return_value(regs) ((regs)->eax)
 
 extern unsigned long profile_pc(struct pt_regs *regs);
diff --git a/include/asm-x86/ptrace_64.h b/include/asm-x86/ptrace_64.h
index 7f166cc..7bfe61e 100644
--- a/include/asm-x86/ptrace_64.h
+++ b/include/asm-x86/ptrace_64.h
@@ -40,6 +40,8 @@
 #define user_mode(regs) (!!((regs)->cs & 3))
 #define user_mode_vm(regs) user_mode(regs)
 #define instruction_pointer(regs) ((regs)->rip)
+#define frame_pointer(regs) ((regs)->rbp)
+#define stack_pointer(regs) ((regs)->rsp)
 #define regs_return_value(regs) ((regs)->rax)
 
 extern unsigned long profile_pc(struct pt_regs *regs);
diff --git a/include/asm-x86/scatterlist_32.h b/include/asm-x86/scatterlist_32.h
index bd5164a..0e7d997 100644
--- a/include/asm-x86/scatterlist_32.h
+++ b/include/asm-x86/scatterlist_32.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     dma_addr_t		dma_address;
     unsigned int	length;
diff --git a/include/asm-x86/scatterlist_64.h b/include/asm-x86/scatterlist_64.h
index ef3986b..1847c72 100644
--- a/include/asm-x86/scatterlist_64.h
+++ b/include/asm-x86/scatterlist_64.h
@@ -4,7 +4,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-    struct page		*page;
+#ifdef CONFIG_DEBUG_SG
+    unsigned long	sg_magic;
+#endif
+    unsigned long	page_link;
     unsigned int	offset;
     unsigned int	length;
     dma_addr_t		dma_address;
diff --git a/include/asm-x86/smp_32.h b/include/asm-x86/smp_32.h
index ee46038..7056d86 100644
--- a/include/asm-x86/smp_32.h
+++ b/include/asm-x86/smp_32.h
@@ -11,7 +11,7 @@
 #endif
 
 #if defined(CONFIG_X86_LOCAL_APIC) && !defined(__ASSEMBLY__)
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/mpspec.h>
 #include <asm/apic.h>
 #ifdef CONFIG_X86_IO_APIC
@@ -39,9 +39,11 @@
 extern void unlock_ipi_call_lock(void);
 
 #define MAX_APICID 256
-extern u8 x86_cpu_to_apicid[];
+extern u8 __initdata x86_cpu_to_apicid_init[];
+extern void *x86_cpu_to_apicid_ptr;
+DECLARE_PER_CPU(u8, x86_cpu_to_apicid);
 
-#define cpu_physical_id(cpu)	x86_cpu_to_apicid[cpu]
+#define cpu_physical_id(cpu)	per_cpu(x86_cpu_to_apicid, cpu)
 
 extern void set_cpu_sibling_map(int cpu);
 
diff --git a/include/asm-x86/smp_64.h b/include/asm-x86/smp_64.h
index d30e9b6..6f0e027 100644
--- a/include/asm-x86/smp_64.h
+++ b/include/asm-x86/smp_64.h
@@ -37,6 +37,8 @@
 extern void unlock_ipi_call_lock(void);
 extern int smp_num_siblings;
 extern void smp_send_reschedule(int cpu);
+extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *),
+				  void *info, int wait);
 
 /*
  * cpu_sibling_map and cpu_core_map now live
@@ -47,7 +49,7 @@
  */
 DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
 DECLARE_PER_CPU(cpumask_t, cpu_core_map);
-extern u8 cpu_llc_id[NR_CPUS];
+DECLARE_PER_CPU(u8, cpu_llc_id);
 
 #define SMP_TRAMPOLINE_BASE 0x6000
 
@@ -84,7 +86,9 @@
  * Some lowlevel functions might want to know about
  * the real APIC ID <-> CPU # mapping.
  */
-extern u8 x86_cpu_to_apicid[NR_CPUS];	/* physical ID */
+extern u8 __initdata x86_cpu_to_apicid_init[];
+extern void *x86_cpu_to_apicid_ptr;
+DECLARE_PER_CPU(u8, x86_cpu_to_apicid);	/* physical ID */
 extern u8 bios_cpu_apicid[];
 
 static inline int cpu_present_to_apicid(int mps_cpu)
@@ -115,8 +119,9 @@
 }
 
 #ifdef CONFIG_SMP
-#define cpu_physical_id(cpu)		x86_cpu_to_apicid[cpu]
+#define cpu_physical_id(cpu)		per_cpu(x86_cpu_to_apicid, cpu)
 #else
+extern unsigned int boot_cpu_id;
 #define cpu_physical_id(cpu)		boot_cpu_id
 #endif /* !CONFIG_SMP */
 #endif
diff --git a/include/asm-x86/suspend_64.h b/include/asm-x86/suspend_64.h
index b897e8c..9440a7a 100644
--- a/include/asm-x86/suspend_64.h
+++ b/include/asm-x86/suspend_64.h
@@ -53,3 +53,5 @@
 
 /* routines for saving/restoring kernel state */
 extern int acpi_save_state_mem(void);
+extern char core_restore_code;
+extern char restore_registers;
diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h
index db6283e..ef84688 100644
--- a/include/asm-x86/system_32.h
+++ b/include/asm-x86/system_32.h
@@ -315,5 +315,6 @@
 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
 
 void default_idle(void);
+void __show_registers(struct pt_regs *, int all);
 
 #endif
diff --git a/include/asm-x86/tlbflush_32.h b/include/asm-x86/tlbflush_32.h
index a50fa67..2bd5b95 100644
--- a/include/asm-x86/tlbflush_32.h
+++ b/include/asm-x86/tlbflush_32.h
@@ -78,7 +78,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  *  - flush_tlb_others(cpumask, mm, va) flushes a TLBs on other cpus
  *
  * ..but the i386 has somewhat limited tlb flushing capabilities,
@@ -166,10 +165,4 @@
 	flush_tlb_all();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-	/* i386 does not keep any page table caches in TLB */
-}
-
 #endif /* _I386_TLBFLUSH_H */
diff --git a/include/asm-x86/tlbflush_64.h b/include/asm-x86/tlbflush_64.h
index 888eb4a..7731fd2 100644
--- a/include/asm-x86/tlbflush_64.h
+++ b/include/asm-x86/tlbflush_64.h
@@ -31,7 +31,6 @@
  *  - flush_tlb_page(vma, vmaddr) flushes one page
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  *
  * x86-64 can only flush individual pages or full VMs. For a range flush
  * we always do the full VM. Might be worth trying if for a small
@@ -98,12 +97,4 @@
 	flush_tlb_all();
 }
 
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-				      unsigned long start, unsigned long end)
-{
-	/* x86_64 does not keep any page table caches in a software TLB.
-	   The CPUs do in their hardware TLBs, but they are handled
-	   by the normal TLB flushing algorithms. */
-}
-
 #endif /* _X8664_TLBFLUSH_H */
diff --git a/include/asm-x86/topology_32.h b/include/asm-x86/topology_32.h
index ae10746..9040f5a 100644
--- a/include/asm-x86/topology_32.h
+++ b/include/asm-x86/topology_32.h
@@ -28,8 +28,8 @@
 #define _ASM_I386_TOPOLOGY_H
 
 #ifdef CONFIG_X86_HT
-#define topology_physical_package_id(cpu)	(cpu_data[cpu].phys_proc_id)
-#define topology_core_id(cpu)			(cpu_data[cpu].cpu_core_id)
+#define topology_physical_package_id(cpu)	(cpu_data(cpu).phys_proc_id)
+#define topology_core_id(cpu)			(cpu_data(cpu).cpu_core_id)
 #define topology_core_siblings(cpu)		(per_cpu(cpu_core_map, cpu))
 #define topology_thread_siblings(cpu)		(per_cpu(cpu_sibling_map, cpu))
 #endif
diff --git a/include/asm-x86/topology_64.h b/include/asm-x86/topology_64.h
index 848c17f..a718dda 100644
--- a/include/asm-x86/topology_64.h
+++ b/include/asm-x86/topology_64.h
@@ -5,7 +5,7 @@
 #ifdef CONFIG_NUMA
 
 #include <asm/mpspec.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 
 extern cpumask_t cpu_online_map;
 
@@ -56,8 +56,8 @@
 #endif
 
 #ifdef CONFIG_SMP
-#define topology_physical_package_id(cpu)	(cpu_data[cpu].phys_proc_id)
-#define topology_core_id(cpu)			(cpu_data[cpu].cpu_core_id)
+#define topology_physical_package_id(cpu)	(cpu_data(cpu).phys_proc_id)
+#define topology_core_id(cpu)			(cpu_data(cpu).cpu_core_id)
 #define topology_core_siblings(cpu)		(per_cpu(cpu_core_map, cpu))
 #define topology_thread_siblings(cpu)		(per_cpu(cpu_sibling_map, cpu))
 #define mc_capable()			(boot_cpu_data.x86_max_cores > 1)
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h
index 1c1e0d9..23261e8 100644
--- a/include/asm-xtensa/bitops.h
+++ b/include/asm-xtensa/bitops.h
@@ -15,6 +15,10 @@
 
 #ifdef __KERNEL__
 
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
 #include <asm/processor.h>
 #include <asm/byteorder.h>
 #include <asm/system.h>
@@ -108,6 +112,7 @@
 #endif
 
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/sched.h>
 #include <asm-generic/bitops/minix.h>
 
diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
index 82b03b3..8bd9d2c 100644
--- a/include/asm-xtensa/dma-mapping.h
+++ b/include/asm-xtensa/dma-mapping.h
@@ -58,11 +58,10 @@
 	BUG_ON(direction == DMA_NONE);
 
 	for (i = 0; i < nents; i++, sg++ ) {
-		BUG_ON(!sg->page);
+		BUG_ON(!sg_page(sg));
 
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
-		consistent_sync(page_address(sg->page) + sg->offset,
-				sg->length, direction);
+		sg->dma_address = sg_phys(sg);
+		consistent_sync(sg_virt(sg), sg->length, direction);
 	}
 
 	return nents;
@@ -128,8 +127,7 @@
 {
 	int i;
 	for (i = 0; i < nelems; i++, sg++)
-		consistent_sync(page_address(sg->page) + sg->offset,
-				sg->length, dir);
+		consistent_sync(sg_virt(sg), sg->length, dir);
 }
 
 static inline void
@@ -138,8 +136,7 @@
 {
 	int i;
 	for (i = 0; i < nelems; i++, sg++)
-		consistent_sync(page_address(sg->page) + sg->offset,
-				sg->length, dir);
+		consistent_sync(sg_virt(sg), sg->length, dir);
 }
 static inline int
 dma_mapping_error(dma_addr_t dma_addr)
diff --git a/include/asm-xtensa/scatterlist.h b/include/asm-xtensa/scatterlist.h
index ca337a2..810080b 100644
--- a/include/asm-xtensa/scatterlist.h
+++ b/include/asm-xtensa/scatterlist.h
@@ -14,7 +14,10 @@
 #include <asm/types.h>
 
 struct scatterlist {
-	struct page 	*page;
+#ifdef CONFIG_DEBUG_SG
+	unsigned long	sg_magic;
+#endif
+	unsigned long	page_link;
 	unsigned int	offset;
 	dma_addr_t	dma_address;
 	unsigned int	length;
diff --git a/include/asm-xtensa/tlbflush.h b/include/asm-xtensa/tlbflush.h
index 7c637b3..46d2400 100644
--- a/include/asm-xtensa/tlbflush.h
+++ b/include/asm-xtensa/tlbflush.h
@@ -41,17 +41,6 @@
 
 #define flush_tlb_kernel_range(start,end) flush_tlb_all()
 
-
-/* This is calld in munmap when we have freed up some page-table pages.
- * We don't need to do anything here, there's nothing special about our
- * page-table pages.
- */
-
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
-                                      unsigned long start, unsigned long end)
-{
-}
-
 /* TLB operations. */
 
 static inline unsigned long itlb_probe(unsigned long addr)
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 7ac8303..6a65231 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -47,6 +47,7 @@
 header-y += coff.h
 header-y += comstats.h
 header-y += const.h
+header-y += cgroupstats.h
 header-y += cycx_cfm.h
 header-y += dlm_device.h
 header-y += dlm_netlink.h
@@ -185,6 +186,7 @@
 unifdef-y += dccp.h
 unifdef-y += dirent.h
 unifdef-y += dlm.h
+unifdef-y += edd.h
 unifdef-y += elfcore.h
 unifdef-y += errno.h
 unifdef-y += errqueue.h
@@ -305,6 +307,7 @@
 unifdef-y += rtnetlink.h
 unifdef-y += scc.h
 unifdef-y += sched.h
+unifdef-y += screen_info.h
 unifdef-y += sdla.h
 unifdef-y += selinux_netlink.h
 unifdef-y += sem.h
@@ -340,6 +343,9 @@
 unifdef-y += utsname.h
 unifdef-y += videodev2.h
 unifdef-y += videodev.h
+unifdef-y += virtio_config.h
+unifdef-y += virtio_blk.h
+unifdef-y += virtio_net.h
 unifdef-y += wait.h
 unifdef-y += wanrouter.h
 unifdef-y += watchdog.h
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index bf5e000..8ccedf7 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -189,32 +189,6 @@
 extern int acpi_blacklisted(void);
 extern void acpi_bios_year(char *s);
 
-#define	ACPI_CSTATE_LIMIT_DEFINED	/* for driver builds */
-#ifdef	CONFIG_ACPI
-
-/*
- * Set highest legal C-state
- * 0: C0 okay, but not C1
- * 1: C1 okay, but not C2
- * 2: C2 okay, but not C3 etc.
- */
-
-extern unsigned int max_cstate;
-
-static inline unsigned int acpi_get_cstate_limit(void)
-{
-	return max_cstate;
-}
-static inline void acpi_set_cstate_limit(unsigned int new_limit)
-{
-	max_cstate = new_limit;
-	return;
-}
-#else
-static inline unsigned int acpi_get_cstate_limit(void) { return 0; }
-static inline void acpi_set_cstate_limit(unsigned int new_limit) { return; }
-#endif
-
 #ifdef CONFIG_ACPI_NUMA
 int acpi_get_pxm(acpi_handle handle);
 int acpi_get_node(acpi_handle *handle);
diff --git a/include/linux/aio.h b/include/linux/aio.h
index d10e608..7ef8de6 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -232,18 +232,6 @@
 		__put_ioctx(kioctx);					\
 } while (0)
 
-#define in_aio() (unlikely(!is_sync_wait(current->io_wait)))
-
-/* may be used for debugging */
-#define warn_if_async()							\
-do {									\
-	if (in_aio()) {							\
-		printk(KERN_ERR "%s(%s:%d) called in async context!\n",	\
-			__FUNCTION__, __FILE__, __LINE__);		\
-		dump_stack();						\
-	}								\
-} while (0)
-
 #define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait)
 
 #include <linux/aio_abi.h>
diff --git a/include/linux/apm_bios.h b/include/linux/apm_bios.h
index 5f921c8..9754baa 100644
--- a/include/linux/apm_bios.h
+++ b/include/linux/apm_bios.h
@@ -16,29 +16,29 @@
  * General Public License for more details.
  */
 
-typedef unsigned short	apm_event_t;
-typedef unsigned short	apm_eventinfo_t;
+#include <linux/types.h>
+
+struct apm_bios_info {
+	__u16	version;
+	__u16	cseg;
+	__u32	offset;
+	__u16	cseg_16;
+	__u16	dseg;
+	__u16	flags;
+	__u16	cseg_len;
+	__u16	cseg_16_len;
+	__u16	dseg_len;
+};
 
 #ifdef __KERNEL__
 
-#include <linux/types.h>
+typedef unsigned short	apm_event_t;
+typedef unsigned short	apm_eventinfo_t;
 
 #define APM_CS		(GDT_ENTRY_APMBIOS_BASE * 8)
 #define APM_CS_16	(APM_CS + 8)
 #define APM_DS		(APM_CS_16 + 8)
 
-struct apm_bios_info {
-	u16	version;
-	u16	cseg;
-	u32	offset;
-	u16	cseg_16;
-	u16	dseg;
-	u16	flags;
-	u16	cseg_len;
-	u16	cseg_16_len;
-	u16	dseg_len;
-};
-
 /* Results of APM Installation Check */
 #define APM_16_BIT_SUPPORT	0x0001
 #define APM_32_BIT_SUPPORT	0x0002
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 9ae7409..c687816 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -63,6 +63,8 @@
 #define AUDIT_ADD_RULE		1011	/* Add syscall filtering rule */
 #define AUDIT_DEL_RULE		1012	/* Delete syscall filtering rule */
 #define AUDIT_LIST_RULES	1013	/* List syscall filtering rules */
+#define AUDIT_TRIM		1014	/* Trim junk from watched tree */
+#define AUDIT_MAKE_EQUIV	1015	/* Append to watched tree */
 #define AUDIT_TTY_GET		1016	/* Get TTY auditing status */
 #define AUDIT_TTY_SET		1017	/* Set TTY auditing status */
 
@@ -203,6 +205,7 @@
 #define AUDIT_SUCCESS   104	/* exit >= 0; value ignored */
 #define AUDIT_WATCH	105
 #define AUDIT_PERM	106
+#define AUDIT_DIR	107
 
 #define AUDIT_ARG0      200
 #define AUDIT_ARG1      (AUDIT_ARG0+1)
@@ -366,8 +369,8 @@
 extern void audit_syscall_exit(int failed, long return_code);
 extern void __audit_getname(const char *name);
 extern void audit_putname(const char *name);
-extern void __audit_inode(const char *name, const struct inode *inode);
-extern void __audit_inode_child(const char *dname, const struct inode *inode,
+extern void __audit_inode(const char *name, const struct dentry *dentry);
+extern void __audit_inode_child(const char *dname, const struct dentry *dentry,
 				const struct inode *parent);
 extern void __audit_ptrace(struct task_struct *t);
 
@@ -381,15 +384,15 @@
 	if (unlikely(!audit_dummy_context()))
 		__audit_getname(name);
 }
-static inline void audit_inode(const char *name, const struct inode *inode) {
+static inline void audit_inode(const char *name, const struct dentry *dentry) {
 	if (unlikely(!audit_dummy_context()))
-		__audit_inode(name, inode);
+		__audit_inode(name, dentry);
 }
 static inline void audit_inode_child(const char *dname, 
-				     const struct inode *inode,
+				     const struct dentry *dentry,
 				     const struct inode *parent) {
 	if (unlikely(!audit_dummy_context()))
-		__audit_inode_child(dname, inode, parent);
+		__audit_inode_child(dname, dentry, parent);
 }
 void audit_core_dumps(long signr);
 
@@ -477,9 +480,9 @@
 #define audit_dummy_context() 1
 #define audit_getname(n) do { ; } while (0)
 #define audit_putname(n) do { ; } while (0)
-#define __audit_inode(n,i) do { ; } while (0)
+#define __audit_inode(n,d) do { ; } while (0)
 #define __audit_inode_child(d,i,p) do { ; } while (0)
-#define audit_inode(n,i) do { ; } while (0)
+#define audit_inode(n,d) do { ; } while (0)
 #define audit_inode_child(d,i,p) do { ; } while (0)
 #define audit_core_dumps(i) do { ; } while (0)
 #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h
index 6b20af0..7113a32 100644
--- a/include/linux/bit_spinlock.h
+++ b/include/linux/bit_spinlock.h
@@ -18,7 +18,7 @@
 	 */
 	preempt_disable();
 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-	while (test_and_set_bit(bitnum, addr)) {
+	while (unlikely(test_and_set_bit_lock(bitnum, addr))) {
 		while (test_bit(bitnum, addr)) {
 			preempt_enable();
 			cpu_relax();
@@ -36,7 +36,7 @@
 {
 	preempt_disable();
 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-	if (test_and_set_bit(bitnum, addr)) {
+	if (unlikely(test_and_set_bit_lock(bitnum, addr))) {
 		preempt_enable();
 		return 0;
 	}
@@ -50,10 +50,28 @@
  */
 static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
 {
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+#ifdef CONFIG_DEBUG_SPINLOCK
 	BUG_ON(!test_bit(bitnum, addr));
-	smp_mb__before_clear_bit();
-	clear_bit(bitnum, addr);
+#endif
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+	clear_bit_unlock(bitnum, addr);
+#endif
+	preempt_enable();
+	__release(bitlock);
+}
+
+/*
+ *  bit-based spin_unlock()
+ *  non-atomic version, which can be used eg. if the bit lock itself is
+ *  protecting the rest of the flags in the word.
+ */
+static inline void __bit_spin_unlock(int bitnum, unsigned long *addr)
+{
+#ifdef CONFIG_DEBUG_SPINLOCK
+	BUG_ON(!test_bit(bitnum, addr));
+#endif
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+	__clear_bit_unlock(bitnum, addr);
 #endif
 	preempt_enable();
 	__release(bitlock);
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 64b4641..acad110 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -6,6 +6,7 @@
 #include <linux/types.h>
 #include <linux/bitops.h>
 #include <linux/string.h>
+#include <linux/kernel.h>
 
 /*
  * bitmaps provide bit arrays that consume one or more unsigned
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index b9fb8ee..69c1edb 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -2,6 +2,14 @@
 #define _LINUX_BITOPS_H
 #include <asm/types.h>
 
+#ifdef	__KERNEL__
+#define BIT(nr)			(1UL << (nr))
+#define BIT_MASK(nr)		(1UL << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(nr)		((nr) / BITS_PER_LONG)
+#define BITS_TO_LONGS(nr)	DIV_ROUND_UP(nr, BITS_PER_LONG)
+#define BITS_PER_BYTE		8
+#endif
+
 /*
  * Include this here because some architectures need generic_ffs/fls in
  * scope
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 8961e7f..bb017ed 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -56,10 +56,8 @@
 
 struct vfs_cap_data {
 	__u32 magic_etc;  /* Little endian */
-	struct {
-		__u32 permitted;    /* Little endian */
-		__u32 inheritable;  /* Little endian */
-	} data[1];
+	__u32 permitted;    /* Little endian */
+	__u32 inheritable;  /* Little endian */
 };
 
 #ifdef __KERNEL__
@@ -310,10 +308,6 @@
 #define CAP_SETFCAP	     31
 
 #ifdef __KERNEL__
-/*
- * Bounding set
- */
-extern kernel_cap_t cap_bset;
 
 /*
  * Internal kernel functions only
diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h
index 2b641b1..c6d3e22 100644
--- a/include/linux/cdrom.h
+++ b/include/linux/cdrom.h
@@ -2,7 +2,7 @@
  * -- <linux/cdrom.h>
  * General header file for linux CD-ROM drivers 
  * Copyright (C) 1992         David Giller, rafetmad@oxy.edu
- *               1994, 1995   Eberhard Moenkeberg, emoenke@gwdg.de
+ *               1994, 1995   Eberhard Mönkeberg, emoenke@gwdg.de
  *               1996         David van Leeuwen, david@tm.tno.nl
  *               1997, 1998   Erik Andersen, andersee@debian.org
  *               1998-2002    Jens Axboe, axboe@suse.de
@@ -76,7 +76,7 @@
                                            (struct cdrom_multisession) */
 #define CDROM_GET_MCN		0x5311 /* Obtain the "Universal Product Code" 
                                            if available (struct cdrom_mcn) */
-#define CDROM_GET_UPC		CDROM_GET_MCN  /* This one is depricated, 
+#define CDROM_GET_UPC		CDROM_GET_MCN  /* This one is deprecated, 
                                           but here anyway for compatibility */
 #define CDROMRESET		0x5312 /* hard-reset the drive */
 #define CDROMVOLREAD		0x5313 /* Get the drive's volume setting 
@@ -506,7 +506,7 @@
 #define GPMODE_TO_PROTECT_PAGE		0x1d
 #define GPMODE_CAPABILITIES_PAGE	0x2a
 #define GPMODE_ALL_PAGES		0x3f
-/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
+/* Not in Mt. Fuji, but in ATAPI 2.6 -- deprecated now in favor
  * of MODE_SENSE_POWER_PAGE */
 #define GPMODE_CDROM_PAGE		0x0d
 
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
new file mode 100644
index 0000000..8747932
--- /dev/null
+++ b/include/linux/cgroup.h
@@ -0,0 +1,327 @@
+#ifndef _LINUX_CGROUP_H
+#define _LINUX_CGROUP_H
+/*
+ *  cgroup interface
+ *
+ *  Copyright (C) 2003 BULL SA
+ *  Copyright (C) 2004-2006 Silicon Graphics, Inc.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/kref.h>
+#include <linux/cpumask.h>
+#include <linux/nodemask.h>
+#include <linux/rcupdate.h>
+#include <linux/cgroupstats.h>
+
+#ifdef CONFIG_CGROUPS
+
+struct cgroupfs_root;
+struct cgroup_subsys;
+struct inode;
+
+extern int cgroup_init_early(void);
+extern int cgroup_init(void);
+extern void cgroup_init_smp(void);
+extern void cgroup_lock(void);
+extern void cgroup_unlock(void);
+extern void cgroup_fork(struct task_struct *p);
+extern void cgroup_fork_callbacks(struct task_struct *p);
+extern void cgroup_post_fork(struct task_struct *p);
+extern void cgroup_exit(struct task_struct *p, int run_callbacks);
+extern int cgroupstats_build(struct cgroupstats *stats,
+				struct dentry *dentry);
+
+extern struct file_operations proc_cgroup_operations;
+
+/* Define the enumeration of all cgroup subsystems */
+#define SUBSYS(_x) _x ## _subsys_id,
+enum cgroup_subsys_id {
+#include <linux/cgroup_subsys.h>
+	CGROUP_SUBSYS_COUNT
+};
+#undef SUBSYS
+
+/* Per-subsystem/per-cgroup state maintained by the system. */
+struct cgroup_subsys_state {
+	/* The cgroup that this subsystem is attached to. Useful
+	 * for subsystems that want to know about the cgroup
+	 * hierarchy structure */
+	struct cgroup *cgroup;
+
+	/* State maintained by the cgroup system to allow
+	 * subsystems to be "busy". Should be accessed via css_get()
+	 * and css_put() */
+
+	atomic_t refcnt;
+
+	unsigned long flags;
+};
+
+/* bits in struct cgroup_subsys_state flags field */
+enum {
+	CSS_ROOT, /* This CSS is the root of the subsystem */
+};
+
+/*
+ * Call css_get() to hold a reference on the cgroup;
+ *
+ */
+
+static inline void css_get(struct cgroup_subsys_state *css)
+{
+	/* We don't need to reference count the root state */
+	if (!test_bit(CSS_ROOT, &css->flags))
+		atomic_inc(&css->refcnt);
+}
+/*
+ * css_put() should be called to release a reference taken by
+ * css_get()
+ */
+
+extern void __css_put(struct cgroup_subsys_state *css);
+static inline void css_put(struct cgroup_subsys_state *css)
+{
+	if (!test_bit(CSS_ROOT, &css->flags))
+		__css_put(css);
+}
+
+struct cgroup {
+	unsigned long flags;		/* "unsigned long" so bitops work */
+
+	/* count users of this cgroup. >0 means busy, but doesn't
+	 * necessarily indicate the number of tasks in the
+	 * cgroup */
+	atomic_t count;
+
+	/*
+	 * We link our 'sibling' struct into our parent's 'children'.
+	 * Our children link their 'sibling' into our 'children'.
+	 */
+	struct list_head sibling;	/* my parent's children */
+	struct list_head children;	/* my children */
+
+	struct cgroup *parent;	/* my parent */
+	struct dentry *dentry;	  	/* cgroup fs entry */
+
+	/* Private pointers for each registered subsystem */
+	struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
+
+	struct cgroupfs_root *root;
+	struct cgroup *top_cgroup;
+
+	/*
+	 * List of cg_cgroup_links pointing at css_sets with
+	 * tasks in this cgroup. Protected by css_set_lock
+	 */
+	struct list_head css_sets;
+
+	/*
+	 * Linked list running through all cgroups that can
+	 * potentially be reaped by the release agent. Protected by
+	 * release_list_lock
+	 */
+	struct list_head release_list;
+};
+
+/* A css_set is a structure holding pointers to a set of
+ * cgroup_subsys_state objects. This saves space in the task struct
+ * object and speeds up fork()/exit(), since a single inc/dec and a
+ * list_add()/del() can bump the reference count on the entire
+ * cgroup set for a task.
+ */
+
+struct css_set {
+
+	/* Reference count */
+	struct kref ref;
+
+	/*
+	 * List running through all cgroup groups. Protected by
+	 * css_set_lock
+	 */
+	struct list_head list;
+
+	/*
+	 * List running through all tasks using this cgroup
+	 * group. Protected by css_set_lock
+	 */
+	struct list_head tasks;
+
+	/*
+	 * List of cg_cgroup_link objects on link chains from
+	 * cgroups referenced from this css_set. Protected by
+	 * css_set_lock
+	 */
+	struct list_head cg_links;
+
+	/*
+	 * Set of subsystem states, one for each subsystem. This array
+	 * is immutable after creation apart from the init_css_set
+	 * during subsystem registration (at boot time).
+	 */
+	struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
+
+};
+
+/* struct cftype:
+ *
+ * The files in the cgroup filesystem mostly have a very simple read/write
+ * handling, some common function will take care of it. Nevertheless some cases
+ * (read tasks) are special and therefore I define this structure for every
+ * kind of file.
+ *
+ *
+ * When reading/writing to a file:
+ *	- the cgroup to use in file->f_dentry->d_parent->d_fsdata
+ *	- the 'cftype' of the file is file->f_dentry->d_fsdata
+ */
+
+#define MAX_CFTYPE_NAME 64
+struct cftype {
+	/* By convention, the name should begin with the name of the
+	 * subsystem, followed by a period */
+	char name[MAX_CFTYPE_NAME];
+	int private;
+	int (*open) (struct inode *inode, struct file *file);
+	ssize_t (*read) (struct cgroup *cont, struct cftype *cft,
+			 struct file *file,
+			 char __user *buf, size_t nbytes, loff_t *ppos);
+	/*
+	 * read_uint() is a shortcut for the common case of returning a
+	 * single integer. Use it in place of read()
+	 */
+	u64 (*read_uint) (struct cgroup *cont, struct cftype *cft);
+	ssize_t (*write) (struct cgroup *cont, struct cftype *cft,
+			  struct file *file,
+			  const char __user *buf, size_t nbytes, loff_t *ppos);
+
+	/*
+	 * write_uint() is a shortcut for the common case of accepting
+	 * a single integer (as parsed by simple_strtoull) from
+	 * userspace. Use in place of write(); return 0 or error.
+	 */
+	int (*write_uint) (struct cgroup *cont, struct cftype *cft, u64 val);
+
+	int (*release) (struct inode *inode, struct file *file);
+};
+
+/* Add a new file to the given cgroup directory. Should only be
+ * called by subsystems from within a populate() method */
+int cgroup_add_file(struct cgroup *cont, struct cgroup_subsys *subsys,
+		       const struct cftype *cft);
+
+/* Add a set of new files to the given cgroup directory. Should
+ * only be called by subsystems from within a populate() method */
+int cgroup_add_files(struct cgroup *cont,
+			struct cgroup_subsys *subsys,
+			const struct cftype cft[],
+			int count);
+
+int cgroup_is_removed(const struct cgroup *cont);
+
+int cgroup_path(const struct cgroup *cont, char *buf, int buflen);
+
+int cgroup_task_count(const struct cgroup *cont);
+
+/* Return true if the cgroup is a descendant of the current cgroup */
+int cgroup_is_descendant(const struct cgroup *cont);
+
+/* Control Group subsystem type. See Documentation/cgroups.txt for details */
+
+struct cgroup_subsys {
+	struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss,
+						  struct cgroup *cont);
+	void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cont);
+	int (*can_attach)(struct cgroup_subsys *ss,
+			  struct cgroup *cont, struct task_struct *tsk);
+	void (*attach)(struct cgroup_subsys *ss, struct cgroup *cont,
+			struct cgroup *old_cont, struct task_struct *tsk);
+	void (*fork)(struct cgroup_subsys *ss, struct task_struct *task);
+	void (*exit)(struct cgroup_subsys *ss, struct task_struct *task);
+	int (*populate)(struct cgroup_subsys *ss,
+			struct cgroup *cont);
+	void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cont);
+	void (*bind)(struct cgroup_subsys *ss, struct cgroup *root);
+	int subsys_id;
+	int active;
+	int early_init;
+#define MAX_CGROUP_TYPE_NAMELEN 32
+	const char *name;
+
+	/* Protected by RCU */
+	struct cgroupfs_root *root;
+
+	struct list_head sibling;
+
+	void *private;
+};
+
+#define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys;
+#include <linux/cgroup_subsys.h>
+#undef SUBSYS
+
+static inline struct cgroup_subsys_state *cgroup_subsys_state(
+	struct cgroup *cont, int subsys_id)
+{
+	return cont->subsys[subsys_id];
+}
+
+static inline struct cgroup_subsys_state *task_subsys_state(
+	struct task_struct *task, int subsys_id)
+{
+	return rcu_dereference(task->cgroups->subsys[subsys_id]);
+}
+
+static inline struct cgroup* task_cgroup(struct task_struct *task,
+					       int subsys_id)
+{
+	return task_subsys_state(task, subsys_id)->cgroup;
+}
+
+int cgroup_path(const struct cgroup *cont, char *buf, int buflen);
+
+int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *ss);
+
+/* A cgroup_iter should be treated as an opaque object */
+struct cgroup_iter {
+	struct list_head *cg_link;
+	struct list_head *task;
+};
+
+/* To iterate across the tasks in a cgroup:
+ *
+ * 1) call cgroup_iter_start to intialize an iterator
+ *
+ * 2) call cgroup_iter_next() to retrieve member tasks until it
+ *    returns NULL or until you want to end the iteration
+ *
+ * 3) call cgroup_iter_end() to destroy the iterator.
+ */
+void cgroup_iter_start(struct cgroup *cont, struct cgroup_iter *it);
+struct task_struct *cgroup_iter_next(struct cgroup *cont,
+					struct cgroup_iter *it);
+void cgroup_iter_end(struct cgroup *cont, struct cgroup_iter *it);
+
+#else /* !CONFIG_CGROUPS */
+
+static inline int cgroup_init_early(void) { return 0; }
+static inline int cgroup_init(void) { return 0; }
+static inline void cgroup_init_smp(void) {}
+static inline void cgroup_fork(struct task_struct *p) {}
+static inline void cgroup_fork_callbacks(struct task_struct *p) {}
+static inline void cgroup_post_fork(struct task_struct *p) {}
+static inline void cgroup_exit(struct task_struct *p, int callbacks) {}
+
+static inline void cgroup_lock(void) {}
+static inline void cgroup_unlock(void) {}
+static inline int cgroupstats_build(struct cgroupstats *stats,
+					struct dentry *dentry)
+{
+	return -EINVAL;
+}
+
+#endif /* !CONFIG_CGROUPS */
+
+#endif /* _LINUX_CGROUP_H */
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
new file mode 100644
index 0000000..0b9bfbd
--- /dev/null
+++ b/include/linux/cgroup_subsys.h
@@ -0,0 +1,38 @@
+/* Add subsystem definitions of the form SUBSYS(<name>) in this
+ * file. Surround each one by a line of comment markers so that
+ * patches don't collide
+ */
+
+/* */
+
+/* */
+
+#ifdef CONFIG_CPUSETS
+SUBSYS(cpuset)
+#endif
+
+/* */
+
+#ifdef CONFIG_CGROUP_CPUACCT
+SUBSYS(cpuacct)
+#endif
+
+/* */
+
+#ifdef CONFIG_CGROUP_DEBUG
+SUBSYS(debug)
+#endif
+
+/* */
+
+#ifdef CONFIG_CGROUP_NS
+SUBSYS(ns)
+#endif
+
+/* */
+
+#ifdef CONFIG_FAIR_CGROUP_SCHED
+SUBSYS(cpu_cgroup)
+#endif
+
+/* */
diff --git a/include/linux/cgroupstats.h b/include/linux/cgroupstats.h
new file mode 100644
index 0000000..4f53abf
--- /dev/null
+++ b/include/linux/cgroupstats.h
@@ -0,0 +1,70 @@
+/* cgroupstats.h - exporting per-cgroup statistics
+ *
+ * Copyright IBM Corporation, 2007
+ * Author Balbir Singh <balbir@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _LINUX_CGROUPSTATS_H
+#define _LINUX_CGROUPSTATS_H
+
+#include <linux/taskstats.h>
+
+/*
+ * Data shared between user space and kernel space on a per cgroup
+ * basis. This data is shared using taskstats.
+ *
+ * Most of these states are derived by looking at the task->state value
+ * For the nr_io_wait state, a flag in the delay accounting structure
+ * indicates that the task is waiting on IO
+ *
+ * Each member is aligned to a 8 byte boundary.
+ */
+struct cgroupstats {
+	__u64	nr_sleeping;		/* Number of tasks sleeping */
+	__u64	nr_running;		/* Number of tasks running */
+	__u64	nr_stopped;		/* Number of tasks in stopped state */
+	__u64	nr_uninterruptible;	/* Number of tasks in uninterruptible */
+					/* state */
+	__u64	nr_io_wait;		/* Number of tasks waiting on IO */
+};
+
+/*
+ * Commands sent from userspace
+ * Not versioned. New commands should only be inserted at the enum's end
+ * prior to __CGROUPSTATS_CMD_MAX
+ */
+
+enum {
+	CGROUPSTATS_CMD_UNSPEC = __TASKSTATS_CMD_MAX,	/* Reserved */
+	CGROUPSTATS_CMD_GET,		/* user->kernel request/get-response */
+	CGROUPSTATS_CMD_NEW,		/* kernel->user event */
+	__CGROUPSTATS_CMD_MAX,
+};
+
+#define CGROUPSTATS_CMD_MAX (__CGROUPSTATS_CMD_MAX - 1)
+
+enum {
+	CGROUPSTATS_TYPE_UNSPEC = 0,	/* Reserved */
+	CGROUPSTATS_TYPE_CGROUP_STATS,	/* contains name + stats */
+	__CGROUPSTATS_TYPE_MAX,
+};
+
+#define CGROUPSTATS_TYPE_MAX (__CGROUPSTATS_TYPE_MAX - 1)
+
+enum {
+	CGROUPSTATS_CMD_ATTR_UNSPEC = 0,
+	CGROUPSTATS_CMD_ATTR_FD,
+	__CGROUPSTATS_CMD_ATTR_MAX,
+};
+
+#define CGROUPSTATS_CMD_ATTR_MAX (__CGROUPSTATS_CMD_ATTR_MAX - 1)
+
+#endif /* _LINUX_CGROUPSTATS_H */
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 16ea337..107787a 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -221,10 +221,15 @@
 
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL
 extern void update_vsyscall(struct timespec *ts, struct clocksource *c);
+extern void update_vsyscall_tz(void);
 #else
 static inline void update_vsyscall(struct timespec *ts, struct clocksource *c)
 {
 }
+
+static inline void update_vsyscall_tz(void)
+{
+}
 #endif
 
 #endif /* _LINUX_CLOCKSOURCE_H */
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index acd5833..fe23792 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -36,10 +36,20 @@
 #define __weak				__attribute__((weak))
 #define __naked				__attribute__((naked))
 #define __noreturn			__attribute__((noreturn))
+
+/*
+ * From the GCC manual:
+ *
+ * Many functions have no effects except the return value and their
+ * return value depends only on the parameters and/or global
+ * variables.  Such a function can be subject to common subexpression
+ * elimination and loop optimization just as an arithmetic operator
+ * would be.
+ * [...]
+ */
 #define __pure				__attribute__((pure))
 #define __aligned(x)			__attribute__((aligned(x)))
 #define __printf(a,b)			__attribute__((format(printf,a,b)))
 #define  noinline			__attribute__((noinline))
-#define __attribute_pure__		__attribute__((pure))
 #define __attribute_const__		__attribute__((__const__))
 #define __maybe_unused			__attribute__((unused))
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 86f9a3a..c811c8b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -132,20 +132,6 @@
 # define __maybe_unused		/* unimplemented */
 #endif
 
-/*
- * From the GCC manual:
- *
- * Many functions have no effects except the return value and their
- * return value depends only on the parameters and/or global
- * variables.  Such a function can be subject to common subexpression
- * elimination and loop optimization just as an arithmetic operator
- * would be.
- * [...]
- */
-#ifndef __attribute_pure__
-# define __attribute_pure__	/* unimplemented */
-#endif
-
 #ifndef noinline
 #define noinline
 #endif
diff --git a/include/linux/console.h b/include/linux/console.h
index 0a4542d..a5f88a6 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -122,14 +122,11 @@
 extern void console_start(struct console *);
 extern int is_console_locked(void);
 
-#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
+extern int console_suspend_enabled;
+
 /* Suspend and resume console messages over PM events */
 extern void suspend_console(void);
 extern void resume_console(void);
-#else
-static inline void suspend_console(void) {}
-static inline void resume_console(void) {}
-#endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
 
 int mda_console_init(void);
 void prom_con_init(void);
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 0ad72c4..b79c575 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -119,8 +119,9 @@
 #define lock_cpu_hotplug()	do { } while (0)
 #define unlock_cpu_hotplug()	do { } while (0)
 #define hotcpu_notifier(fn, pri)	do { (void)(fn); } while (0)
-#define register_hotcpu_notifier(nb)	do { (void)(nb); } while (0)
-#define unregister_hotcpu_notifier(nb)	do { (void)(nb); } while (0)
+/* These aren't inline functions due to a GCC bug. */
+#define register_hotcpu_notifier(nb)	({ (void)(nb); 0; })
+#define unregister_hotcpu_notifier(nb)	({ (void)(nb); })
 
 /* CPUs don't go offline once they're online w/o CONFIG_HOTPLUG_CPU */
 static inline int cpu_is_offline(int cpu) { return 0; }
diff --git a/include/linux/cpu_acct.h b/include/linux/cpu_acct.h
new file mode 100644
index 0000000..6b5fd8a
--- /dev/null
+++ b/include/linux/cpu_acct.h
@@ -0,0 +1,14 @@
+
+#ifndef _LINUX_CPU_ACCT_H
+#define _LINUX_CPU_ACCT_H
+
+#include <linux/cgroup.h>
+#include <asm/cputime.h>
+
+#ifdef CONFIG_CGROUP_CPUACCT
+extern void cpuacct_charge(struct task_struct *, cputime_t cputime);
+#else
+static void inline cpuacct_charge(struct task_struct *p, cputime_t cputime) {}
+#endif
+
+#endif
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
new file mode 100644
index 0000000..16a5154
--- /dev/null
+++ b/include/linux/cpuidle.h
@@ -0,0 +1,180 @@
+/*
+ * cpuidle.h - a generic framework for CPU idle power management
+ *
+ * (C) 2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *          Shaohua Li <shaohua.li@intel.com>
+ *          Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#ifndef _LINUX_CPUIDLE_H
+#define _LINUX_CPUIDLE_H
+
+#include <linux/percpu.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kobject.h>
+#include <linux/completion.h>
+
+#define CPUIDLE_STATE_MAX	8
+#define CPUIDLE_NAME_LEN	16
+
+struct cpuidle_device;
+
+
+/****************************
+ * CPUIDLE DEVICE INTERFACE *
+ ****************************/
+
+struct cpuidle_state {
+	char		name[CPUIDLE_NAME_LEN];
+	void		*driver_data;
+
+	unsigned int	flags;
+	unsigned int	exit_latency; /* in US */
+	unsigned int	power_usage; /* in mW */
+	unsigned int	target_residency; /* in US */
+
+	unsigned int	usage;
+	unsigned int	time; /* in US */
+
+	int (*enter)	(struct cpuidle_device *dev,
+			 struct cpuidle_state *state);
+};
+
+/* Idle State Flags */
+#define CPUIDLE_FLAG_TIME_VALID	(0x01) /* is residency time measurable? */
+#define CPUIDLE_FLAG_CHECK_BM	(0x02) /* BM activity will exit state */
+#define CPUIDLE_FLAG_SHALLOW	(0x10) /* low latency, minimal savings */
+#define CPUIDLE_FLAG_BALANCED	(0x20) /* medium latency, moderate savings */
+#define CPUIDLE_FLAG_DEEP	(0x40) /* high latency, large savings */
+
+#define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
+
+/**
+ * cpuidle_get_statedata - retrieves private driver state data
+ * @state: the state
+ */
+static inline void * cpuidle_get_statedata(struct cpuidle_state *state)
+{
+	return state->driver_data;
+}
+
+/**
+ * cpuidle_set_statedata - stores private driver state data
+ * @state: the state
+ * @data: the private data
+ */
+static inline void
+cpuidle_set_statedata(struct cpuidle_state *state, void *data)
+{
+	state->driver_data = data;
+}
+
+struct cpuidle_state_kobj {
+	struct cpuidle_state *state;
+	struct completion kobj_unregister;
+	struct kobject kobj;
+};
+
+struct cpuidle_device {
+	int			enabled:1;
+	unsigned int		cpu;
+
+	int			last_residency;
+	int			state_count;
+	struct cpuidle_state	states[CPUIDLE_STATE_MAX];
+	struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
+	struct cpuidle_state	*last_state;
+
+	struct list_head 	device_list;
+	struct kobject		kobj;
+	struct completion	kobj_unregister;
+	void			*governor_data;
+};
+
+DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
+
+/**
+ * cpuidle_get_last_residency - retrieves the last state's residency time
+ * @dev: the target CPU
+ *
+ * NOTE: this value is invalid if CPUIDLE_FLAG_TIME_VALID isn't set
+ */
+static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
+{
+	return dev->last_residency;
+}
+
+
+/****************************
+ * CPUIDLE DRIVER INTERFACE *
+ ****************************/
+
+struct cpuidle_driver {
+	char			name[CPUIDLE_NAME_LEN];
+	struct module 		*owner;
+};
+
+#ifdef CONFIG_CPU_IDLE
+
+extern int cpuidle_register_driver(struct cpuidle_driver *drv);
+extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
+extern int cpuidle_register_device(struct cpuidle_device *dev);
+extern void cpuidle_unregister_device(struct cpuidle_device *dev);
+
+extern void cpuidle_pause_and_lock(void);
+extern void cpuidle_resume_and_unlock(void);
+extern int cpuidle_enable_device(struct cpuidle_device *dev);
+extern void cpuidle_disable_device(struct cpuidle_device *dev);
+
+#else
+
+static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
+{return 0;}
+static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
+static inline int cpuidle_register_device(struct cpuidle_device *dev)
+{return 0;}
+static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { }
+
+static inline void cpuidle_pause_and_lock(void) { }
+static inline void cpuidle_resume_and_unlock(void) { }
+static inline int cpuidle_enable_device(struct cpuidle_device *dev)
+{return 0;}
+static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
+
+#endif
+
+/******************************
+ * CPUIDLE GOVERNOR INTERFACE *
+ ******************************/
+
+struct cpuidle_governor {
+	char			name[CPUIDLE_NAME_LEN];
+	struct list_head 	governor_list;
+	unsigned int		rating;
+
+	int  (*enable)		(struct cpuidle_device *dev);
+	void (*disable)		(struct cpuidle_device *dev);
+
+	int  (*select)		(struct cpuidle_device *dev);
+	void (*reflect)		(struct cpuidle_device *dev);
+
+	struct module 		*owner;
+};
+
+#ifdef CONFIG_CPU_IDLE
+
+extern int cpuidle_register_governor(struct cpuidle_governor *gov);
+extern void cpuidle_unregister_governor(struct cpuidle_governor *gov);
+
+#else
+
+static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
+{return 0;}
+static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { }
+
+#endif
+
+#endif /* _LINUX_CPUIDLE_H */
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index ea44d2e..ecae585 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <linux/cpumask.h>
 #include <linux/nodemask.h>
+#include <linux/cgroup.h>
 
 #ifdef CONFIG_CPUSETS
 
@@ -19,9 +20,8 @@
 extern int cpuset_init_early(void);
 extern int cpuset_init(void);
 extern void cpuset_init_smp(void);
-extern void cpuset_fork(struct task_struct *p);
-extern void cpuset_exit(struct task_struct *p);
 extern cpumask_t cpuset_cpus_allowed(struct task_struct *p);
+extern cpumask_t cpuset_cpus_allowed_locked(struct task_struct *p);
 extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
 #define cpuset_current_mems_allowed (current->mems_allowed)
 void cpuset_init_current_mems_allowed(void);
@@ -76,18 +76,22 @@
 
 extern void cpuset_track_online_nodes(void);
 
+extern int current_cpuset_is_being_rebound(void);
+
 #else /* !CONFIG_CPUSETS */
 
 static inline int cpuset_init_early(void) { return 0; }
 static inline int cpuset_init(void) { return 0; }
 static inline void cpuset_init_smp(void) {}
-static inline void cpuset_fork(struct task_struct *p) {}
-static inline void cpuset_exit(struct task_struct *p) {}
 
 static inline cpumask_t cpuset_cpus_allowed(struct task_struct *p)
 {
 	return cpu_possible_map;
 }
+static inline cpumask_t cpuset_cpus_allowed_locked(struct task_struct *p)
+{
+	return cpu_possible_map;
+}
 
 static inline nodemask_t cpuset_mems_allowed(struct task_struct *p)
 {
@@ -148,6 +152,11 @@
 
 static inline void cpuset_track_online_nodes(void) {}
 
+static inline int current_cpuset_is_being_rebound(void)
+{
+	return 0;
+}
+
 #endif /* !CONFIG_CPUSETS */
 
 #endif /* _LINUX_CPUSET_H */
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index fc32694..f3110eb 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -6,7 +6,7 @@
  * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
- * and Nettle, by Niels Möller.
+ * and Nettle, by Niels Möller.
  * 
  * 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
diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h
index 72aa00c..8f3dcd3 100644
--- a/include/linux/cyclades.h
+++ b/include/linux/cyclades.h
@@ -512,11 +512,11 @@
     void __iomem *base_addr;
     void __iomem *ctl_addr;
     int irq;
-    int num_chips;	/* 0 if card absent, -1 if Z/PCI, else Y */
-    int first_line;	/* minor number of first channel on card */
-    int nports;		/* Number of ports in the card */
-    int bus_index;	/* address shift - 0 for ISA, 1 for PCI */
-    int	intr_enabled;	/* FW Interrupt flag - 0 disabled, 1 enabled */
+    unsigned int num_chips;	/* 0 if card absent, -1 if Z/PCI, else Y */
+    unsigned int first_line;	/* minor number of first channel on card */
+    unsigned int nports;	/* Number of ports in the card */
+    int bus_index;		/* address shift - 0 for ISA, 1 for PCI */
+    int intr_enabled;		/* FW Interrupt flag - 0 disabled, 1 enabled */
     spinlock_t card_lock;
     struct cyclades_port *ports;
 };
@@ -566,10 +566,9 @@
 	int			rtsdtr_inv;
 	int			chip_rev;
 	int			custom_divisor;
-	int                     x_char; /* to be pushed out ASAP */
+	u8			x_char; /* to be pushed out ASAP */
 	int			close_delay;
 	unsigned short		closing_wait;
-	unsigned long		event;
 	int			count;	/* # of fd on device */
 	int                     breakon;
 	int                     breakoff;
@@ -584,7 +583,6 @@
 	struct cyclades_monitor	mon;
 	struct cyclades_idle_stats	idle_stats;
 	struct cyclades_icount	icount;
-	struct work_struct	tqueue;
 	wait_queue_head_t       open_wait;
 	wait_queue_head_t       close_wait;
 	struct completion       shutdown_wait;
@@ -592,19 +590,6 @@
 	int throttle;
 };
 
-/*
- * Events are used to schedule things to happen at timer-interrupt
- * time, instead of at cy interrupt time.
- */
-#define Cy_EVENT_READ_PROCESS		0
-#define Cy_EVENT_WRITE_WAKEUP		1
-#define Cy_EVENT_HANGUP			2
-#define Cy_EVENT_BREAK			3
-#define Cy_EVENT_OPEN_WAKEUP		4
-#define Cy_EVENT_SHUTDOWN_WAKEUP	5
-#define	Cy_EVENT_DELTA_WAKEUP		6
-#define	Cy_EVENT_Z_RX_FULL		7
-
 #define	CLOSING_WAIT_DELAY	30*HZ
 #define CY_CLOSING_WAIT_NONE	65535
 #define CY_CLOSING_WAIT_INF	0
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index aab53df..c2c153f 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -178,6 +178,7 @@
 #define DCACHE_INOTIFY_PARENT_WATCHED	0x0020 /* Parent inode is watched */
 
 extern spinlock_t dcache_lock;
+extern seqlock_t rename_lock;
 
 /**
  * d_drop - drop a dentry
diff --git a/include/linux/delayacct.h b/include/linux/delayacct.h
index 55d1ca5..ab94bc0 100644
--- a/include/linux/delayacct.h
+++ b/include/linux/delayacct.h
@@ -26,6 +26,7 @@
  * Used to set current->delays->flags
  */
 #define DELAYACCT_PF_SWAPIN	0x00000001	/* I am doing a swapin */
+#define DELAYACCT_PF_BLKIO	0x00000002	/* I am waiting on IO */
 
 #ifdef CONFIG_TASK_DELAY_ACCT
 
@@ -39,6 +40,14 @@
 extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *);
 extern __u64 __delayacct_blkio_ticks(struct task_struct *);
 
+static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
+{
+	if (p->delays)
+		return (p->delays->flags & DELAYACCT_PF_BLKIO);
+	else
+		return 0;
+}
+
 static inline void delayacct_set_flag(int flag)
 {
 	if (current->delays)
@@ -71,6 +80,7 @@
 
 static inline void delayacct_blkio_start(void)
 {
+	delayacct_set_flag(DELAYACCT_PF_BLKIO);
 	if (current->delays)
 		__delayacct_blkio_start();
 }
@@ -79,6 +89,7 @@
 {
 	if (current->delays)
 		__delayacct_blkio_end();
+	delayacct_clear_flag(DELAYACCT_PF_BLKIO);
 }
 
 static inline int delayacct_add_tsk(struct taskstats *d,
@@ -116,6 +127,8 @@
 { return 0; }
 static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
 { return 0; }
+static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
+{ return 0; }
 #endif /* CONFIG_TASK_DELAY_ACCT */
 
 #endif
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 499f537..37c66d1 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -183,11 +183,14 @@
  */
 uint32_t dm_get_event_nr(struct mapped_device *md);
 int dm_wait_event(struct mapped_device *md, int event_nr);
+uint32_t dm_next_uevent_seq(struct mapped_device *md);
+void dm_uevent_add(struct mapped_device *md, struct list_head *elist);
 
 /*
  * Info functions.
  */
 const char *dm_device_name(struct mapped_device *md);
+int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid);
 struct gendisk *dm_disk(struct mapped_device *md);
 int dm_suspended(struct mapped_device *md);
 int dm_noflush_suspending(struct dm_target *ti);
diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h
index b934861..523281c 100644
--- a/include/linux/dm-ioctl.h
+++ b/include/linux/dm-ioctl.h
@@ -131,6 +131,7 @@
 	char name[DM_NAME_LEN];	/* device name */
 	char uuid[DM_UUID_LEN];	/* unique identifier for
 				 * the block device */
+	char data[7];		/* padding or data */
 };
 
 /*
@@ -285,9 +286,9 @@
 #define DM_DEV_SET_GEOMETRY	_IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR	4
-#define DM_VERSION_MINOR	11
+#define DM_VERSION_MINOR	12
 #define DM_VERSION_PATCHLEVEL	0
-#define DM_VERSION_EXTRA	"-ioctl (2006-10-12)"
+#define DM_VERSION_EXTRA	"-ioctl (2007-10-02)"
 
 /* Status bits */
 #define DM_READONLY_FLAG	(1 << 0) /* In/Out */
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 0ebfafb..101a2d4 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -13,16 +13,26 @@
 	DMA_NONE = 3,
 };
 
-#define DMA_64BIT_MASK	0xffffffffffffffffULL
-#define DMA_48BIT_MASK	0x0000ffffffffffffULL
-#define DMA_40BIT_MASK	0x000000ffffffffffULL
-#define DMA_39BIT_MASK	0x0000007fffffffffULL
-#define DMA_32BIT_MASK	0x00000000ffffffffULL
-#define DMA_31BIT_MASK	0x000000007fffffffULL
-#define DMA_30BIT_MASK	0x000000003fffffffULL
-#define DMA_29BIT_MASK	0x000000001fffffffULL
-#define DMA_28BIT_MASK	0x000000000fffffffULL
-#define DMA_24BIT_MASK	0x0000000000ffffffULL
+#define DMA_BIT_MASK(n)	(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
+
+/*
+ * NOTE: do not use the below macros in new code and do not add new definitions
+ * here.
+ *
+ * Instead, just open-code DMA_BIT_MASK(n) within your driver
+ */
+#define DMA_64BIT_MASK	DMA_BIT_MASK(64)
+#define DMA_48BIT_MASK	DMA_BIT_MASK(48)
+#define DMA_47BIT_MASK	DMA_BIT_MASK(47)
+#define DMA_40BIT_MASK	DMA_BIT_MASK(40)
+#define DMA_39BIT_MASK	DMA_BIT_MASK(39)
+#define DMA_35BIT_MASK	DMA_BIT_MASK(35)
+#define DMA_32BIT_MASK	DMA_BIT_MASK(32)
+#define DMA_31BIT_MASK	DMA_BIT_MASK(31)
+#define DMA_30BIT_MASK	DMA_BIT_MASK(30)
+#define DMA_29BIT_MASK	DMA_BIT_MASK(29)
+#define DMA_28BIT_MASK	DMA_BIT_MASK(28)
+#define DMA_24BIT_MASK	DMA_BIT_MASK(24)
 
 #define DMA_MASK_NONE	0x0ULL
 
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
new file mode 100644
index 0000000..ffb6439
--- /dev/null
+++ b/include/linux/dmar.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * Copyright (C) Ashok Raj <ashok.raj@intel.com>
+ * Copyright (C) Shaohua Li <shaohua.li@intel.com>
+ */
+
+#ifndef __DMAR_H__
+#define __DMAR_H__
+
+#include <linux/acpi.h>
+#include <linux/types.h>
+#include <linux/msi.h>
+
+#ifdef CONFIG_DMAR
+struct intel_iommu;
+
+extern char *dmar_get_fault_reason(u8 fault_reason);
+
+/* Can't use the common MSI interrupt functions
+ * since DMAR is not a pci device
+ */
+extern void dmar_msi_unmask(unsigned int irq);
+extern void dmar_msi_mask(unsigned int irq);
+extern void dmar_msi_read(int irq, struct msi_msg *msg);
+extern void dmar_msi_write(int irq, struct msi_msg *msg);
+extern int dmar_set_interrupt(struct intel_iommu *iommu);
+extern int arch_setup_dmar_msi(unsigned int irq);
+
+/* Intel IOMMU detection and initialization functions */
+extern void detect_intel_iommu(void);
+extern int intel_iommu_init(void);
+
+extern int dmar_table_init(void);
+extern int early_dmar_detect(void);
+
+extern struct list_head dmar_drhd_units;
+extern struct list_head dmar_rmrr_units;
+
+struct dmar_drhd_unit {
+	struct list_head list;		/* list of drhd units	*/
+	u64	reg_base_addr;		/* register base address*/
+	struct	pci_dev **devices; 	/* target device array	*/
+	int	devices_cnt;		/* target device count	*/
+	u8	ignored:1; 		/* ignore drhd		*/
+	u8	include_all:1;
+	struct intel_iommu *iommu;
+};
+
+struct dmar_rmrr_unit {
+	struct list_head list;		/* list of rmrr units	*/
+	u64	base_address;		/* reserved base address*/
+	u64	end_address;		/* reserved end address */
+	struct pci_dev **devices;	/* target devices */
+	int	devices_cnt;		/* target device count */
+};
+
+#define for_each_drhd_unit(drhd) \
+	list_for_each_entry(drhd, &dmar_drhd_units, list)
+#define for_each_rmrr_units(rmrr) \
+	list_for_each_entry(rmrr, &dmar_rmrr_units, list)
+#else
+static inline void detect_intel_iommu(void)
+{
+	return;
+}
+static inline int intel_iommu_init(void)
+{
+	return -ENODEV;
+}
+
+#endif /* !CONFIG_DMAR */
+#endif /* __DMAR_H__ */
diff --git a/include/linux/edd.h b/include/linux/edd.h
index 7b64782..5d747c5 100644
--- a/include/linux/edd.h
+++ b/include/linux/edd.h
@@ -67,113 +67,113 @@
 #define EDD_INFO_USE_INT13_FN50                (1 << 7)
 
 struct edd_device_params {
-	u16 length;
-	u16 info_flags;
-	u32 num_default_cylinders;
-	u32 num_default_heads;
-	u32 sectors_per_track;
-	u64 number_of_sectors;
-	u16 bytes_per_sector;
-	u32 dpte_ptr;		/* 0xFFFFFFFF for our purposes */
-	u16 key;		/* = 0xBEDD */
-	u8 device_path_info_length;	/* = 44 */
-	u8 reserved2;
-	u16 reserved3;
-	u8 host_bus_type[4];
-	u8 interface_type[8];
+	__u16 length;
+	__u16 info_flags;
+	__u32 num_default_cylinders;
+	__u32 num_default_heads;
+	__u32 sectors_per_track;
+	__u64 number_of_sectors;
+	__u16 bytes_per_sector;
+	__u32 dpte_ptr;		/* 0xFFFFFFFF for our purposes */
+	__u16 key;		/* = 0xBEDD */
+	__u8 device_path_info_length;	/* = 44 */
+	__u8 reserved2;
+	__u16 reserved3;
+	__u8 host_bus_type[4];
+	__u8 interface_type[8];
 	union {
 		struct {
-			u16 base_address;
-			u16 reserved1;
-			u32 reserved2;
+			__u16 base_address;
+			__u16 reserved1;
+			__u32 reserved2;
 		} __attribute__ ((packed)) isa;
 		struct {
-			u8 bus;
-			u8 slot;
-			u8 function;
-			u8 channel;
-			u32 reserved;
+			__u8 bus;
+			__u8 slot;
+			__u8 function;
+			__u8 channel;
+			__u32 reserved;
 		} __attribute__ ((packed)) pci;
 		/* pcix is same as pci */
 		struct {
-			u64 reserved;
+			__u64 reserved;
 		} __attribute__ ((packed)) ibnd;
 		struct {
-			u64 reserved;
+			__u64 reserved;
 		} __attribute__ ((packed)) xprs;
 		struct {
-			u64 reserved;
+			__u64 reserved;
 		} __attribute__ ((packed)) htpt;
 		struct {
-			u64 reserved;
+			__u64 reserved;
 		} __attribute__ ((packed)) unknown;
 	} interface_path;
 	union {
 		struct {
-			u8 device;
-			u8 reserved1;
-			u16 reserved2;
-			u32 reserved3;
-			u64 reserved4;
+			__u8 device;
+			__u8 reserved1;
+			__u16 reserved2;
+			__u32 reserved3;
+			__u64 reserved4;
 		} __attribute__ ((packed)) ata;
 		struct {
-			u8 device;
-			u8 lun;
-			u8 reserved1;
-			u8 reserved2;
-			u32 reserved3;
-			u64 reserved4;
+			__u8 device;
+			__u8 lun;
+			__u8 reserved1;
+			__u8 reserved2;
+			__u32 reserved3;
+			__u64 reserved4;
 		} __attribute__ ((packed)) atapi;
 		struct {
-			u16 id;
-			u64 lun;
-			u16 reserved1;
-			u32 reserved2;
+			__u16 id;
+			__u64 lun;
+			__u16 reserved1;
+			__u32 reserved2;
 		} __attribute__ ((packed)) scsi;
 		struct {
-			u64 serial_number;
-			u64 reserved;
+			__u64 serial_number;
+			__u64 reserved;
 		} __attribute__ ((packed)) usb;
 		struct {
-			u64 eui;
-			u64 reserved;
+			__u64 eui;
+			__u64 reserved;
 		} __attribute__ ((packed)) i1394;
 		struct {
-			u64 wwid;
-			u64 lun;
+			__u64 wwid;
+			__u64 lun;
 		} __attribute__ ((packed)) fibre;
 		struct {
-			u64 identity_tag;
-			u64 reserved;
+			__u64 identity_tag;
+			__u64 reserved;
 		} __attribute__ ((packed)) i2o;
 		struct {
-			u32 array_number;
-			u32 reserved1;
-			u64 reserved2;
+			__u32 array_number;
+			__u32 reserved1;
+			__u64 reserved2;
 		} __attribute__ ((packed)) raid;
 		struct {
-			u8 device;
-			u8 reserved1;
-			u16 reserved2;
-			u32 reserved3;
-			u64 reserved4;
+			__u8 device;
+			__u8 reserved1;
+			__u16 reserved2;
+			__u32 reserved3;
+			__u64 reserved4;
 		} __attribute__ ((packed)) sata;
 		struct {
-			u64 reserved1;
-			u64 reserved2;
+			__u64 reserved1;
+			__u64 reserved2;
 		} __attribute__ ((packed)) unknown;
 	} device_path;
-	u8 reserved4;
-	u8 checksum;
+	__u8 reserved4;
+	__u8 checksum;
 } __attribute__ ((packed));
 
 struct edd_info {
-	u8 device;
-	u8 version;
-	u16 interface_support;
-	u16 legacy_max_cylinder;
-	u8 legacy_max_head;
-	u8 legacy_sectors_per_track;
+	__u8 device;
+	__u8 version;
+	__u16 interface_support;
+	__u16 legacy_max_cylinder;
+	__u8 legacy_max_head;
+	__u8 legacy_sectors_per_track;
 	struct edd_device_params params;
 } __attribute__ ((packed));
 
@@ -184,8 +184,9 @@
 	unsigned char edd_info_nr;
 };
 
+#ifdef __KERNEL__
 extern struct edd edd;
-
+#endif /* __KERNEL__ */
 #endif				/*!__ASSEMBLY__ */
 
 #endif				/* _LINUX_EDD_H */
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 0b9579a..14813b5 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -298,7 +298,7 @@
 				    u64 attr);
 extern int __init efi_uart_console_only (void);
 extern void efi_initialize_iomem_resources(struct resource *code_resource,
-					struct resource *data_resource);
+		struct resource *data_resource, struct resource *bss_resource);
 extern unsigned long efi_get_time(void);
 extern int efi_set_rtc_mmss(unsigned long nowtime);
 extern int is_available_memory(efi_memory_desc_t * md);
diff --git a/include/linux/efs_fs.h b/include/linux/efs_fs.h
index 16cb25c..dd57fe5 100644
--- a/include/linux/efs_fs.h
+++ b/include/linux/efs_fs.h
@@ -35,6 +35,7 @@
 }
 
 struct statfs;
+struct fid;
 
 extern const struct inode_operations efs_dir_inode_operations;
 extern const struct file_operations efs_dir_operations;
@@ -45,7 +46,10 @@
 extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int);
 
 extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *);
-extern struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp);
+extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type);
+extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
+		int fh_len, int fh_type);
 extern struct dentry *efs_get_parent(struct dentry *);
 extern int efs_bmap(struct inode *, int);
 
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
index 8872fe8..51d2141 100644
--- a/include/linux/exportfs.h
+++ b/include/linux/exportfs.h
@@ -4,9 +4,48 @@
 #include <linux/types.h>
 
 struct dentry;
+struct inode;
 struct super_block;
 struct vfsmount;
 
+/*
+ * The fileid_type identifies how the file within the filesystem is encoded.
+ * In theory this is freely set and parsed by the filesystem, but we try to
+ * stick to conventions so we can share some generic code and don't confuse
+ * sniffers like ethereal/wireshark.
+ *
+ * The filesystem must not use the value '0' or '0xff'.
+ */
+enum fid_type {
+	/*
+	 * The root, or export point, of the filesystem.
+	 * (Never actually passed down to the filesystem.
+	 */
+	FILEID_ROOT = 0,
+
+	/*
+	 * 32bit inode number, 32 bit generation number.
+	 */
+	FILEID_INO32_GEN = 1,
+
+	/*
+	 * 32bit inode number, 32 bit generation number,
+	 * 32 bit parent directory inode number.
+	 */
+	FILEID_INO32_GEN_PARENT = 2,
+};
+
+struct fid {
+	union {
+		struct {
+			u32 ino;
+			u32 gen;
+			u32 parent_ino;
+			u32 parent_gen;
+		} i32;
+		__u32 raw[6];
+	};
+};
 
 /**
  * struct export_operations - for nfsd to communicate with file systems
@@ -15,43 +54,9 @@
  * @get_name:       find the name for a given inode in a given directory
  * @get_parent:     find the parent of a given directory
  * @get_dentry:     find a dentry for the inode given a file handle sub-fragment
- * @find_exported_dentry:
- *	set by the exporting module to a standard helper function.
  *
- * Description:
- *    The export_operations structure provides a means for nfsd to communicate
- *    with a particular exported file system  - particularly enabling nfsd and
- *    the filesystem to co-operate when dealing with file handles.
- *
- *    export_operations contains two basic operation for dealing with file
- *    handles, decode_fh() and encode_fh(), and allows for some other
- *    operations to be defined which standard helper routines use to get
- *    specific information from the filesystem.
- *
- *    nfsd encodes information use to determine which filesystem a filehandle
- *    applies to in the initial part of the file handle.  The remainder, termed
- *    a file handle fragment, is controlled completely by the filesystem.  The
- *    standard helper routines assume that this fragment will contain one or
- *    two sub-fragments, one which identifies the file, and one which may be
- *    used to identify the (a) directory containing the file.
- *
- *    In some situations, nfsd needs to get a dentry which is connected into a
- *    specific part of the file tree.  To allow for this, it passes the
- *    function acceptable() together with a @context which can be used to see
- *    if the dentry is acceptable.  As there can be multiple dentrys for a
- *    given file, the filesystem should check each one for acceptability before
- *    looking for the next.  As soon as an acceptable one is found, it should
- *    be returned.
- *
- * decode_fh:
- *    @decode_fh is given a &struct super_block (@sb), a file handle fragment
- *    (@fh, @fh_len) and an acceptability testing function (@acceptable,
- *    @context).  It should return a &struct dentry which refers to the same
- *    file that the file handle fragment refers to,  and which passes the
- *    acceptability test.  If it cannot, it should return a %NULL pointer if
- *    the file was found but no acceptable &dentries were available, or a
- *    %ERR_PTR error code indicating why it couldn't be found (e.g. %ENOENT or
- *    %ENOMEM).
+ * See Documentation/filesystems/Exporting for details on how to use
+ * this interface correctly.
  *
  * encode_fh:
  *    @encode_fh should store in the file handle fragment @fh (using at most
@@ -63,6 +68,21 @@
  *    the filehandle fragment.  encode_fh() should return the number of bytes
  *    stored or a negative error code such as %-ENOSPC
  *
+ * fh_to_dentry:
+ *    @fh_to_dentry is given a &struct super_block (@sb) and a file handle
+ *    fragment (@fh, @fh_len). It should return a &struct dentry which refers
+ *    to the same file that the file handle fragment refers to.  If it cannot,
+ *    it should return a %NULL pointer if the file was found but no acceptable
+ *    &dentries were available, or an %ERR_PTR error code indicating why it
+ *    couldn't be found (e.g. %ENOENT or %ENOMEM).  Any suitable dentry can be
+ *    returned including, if necessary, a new dentry created with d_alloc_root.
+ *    The caller can then find any other extant dentries by following the
+ *    d_alias links.
+ *
+ * fh_to_parent:
+ *    Same as @fh_to_dentry, except that it returns a pointer to the parent
+ *    dentry if it was encoded into the filehandle fragment by @encode_fh.
+ *
  * get_name:
  *    @get_name should find a name for the given @child in the given @parent
  *    directory.  The name should be stored in the @name (with the
@@ -75,52 +95,37 @@
  *    is also a directory.  In the event that it cannot be found, or storage
  *    space cannot be allocated, a %ERR_PTR should be returned.
  *
- * get_dentry:
- *    Given a &super_block (@sb) and a pointer to a file-system specific inode
- *    identifier, possibly an inode number, (@inump) get_dentry() should find
- *    the identified inode and return a dentry for that inode.  Any suitable
- *    dentry can be returned including, if necessary, a new dentry created with
- *    d_alloc_root.  The caller can then find any other extant dentrys by
- *    following the d_alias links.  If a new dentry was created using
- *    d_alloc_root, DCACHE_NFSD_DISCONNECTED should be set, and the dentry
- *    should be d_rehash()ed.
- *
- *    If the inode cannot be found, either a %NULL pointer or an %ERR_PTR code
- *    can be returned.  The @inump will be whatever was passed to
- *    nfsd_find_fh_dentry() in either the @obj or @parent parameters.
- *
  * Locking rules:
  *    get_parent is called with child->d_inode->i_mutex down
  *    get_name is not (which is possibly inconsistent)
  */
 
 struct export_operations {
-	struct dentry *(*decode_fh)(struct super_block *sb, __u32 *fh,
-			int fh_len, int fh_type,
-			int (*acceptable)(void *context, struct dentry *de),
-			void *context);
 	int (*encode_fh)(struct dentry *de, __u32 *fh, int *max_len,
 			int connectable);
+	struct dentry * (*fh_to_dentry)(struct super_block *sb, struct fid *fid,
+			int fh_len, int fh_type);
+	struct dentry * (*fh_to_parent)(struct super_block *sb, struct fid *fid,
+			int fh_len, int fh_type);
 	int (*get_name)(struct dentry *parent, char *name,
 			struct dentry *child);
 	struct dentry * (*get_parent)(struct dentry *child);
-	struct dentry * (*get_dentry)(struct super_block *sb, void *inump);
-
-	/* This is set by the exporting module to a standard helper */
-	struct dentry * (*find_exported_dentry)(
-			struct super_block *sb, void *obj, void *parent,
-			int (*acceptable)(void *context, struct dentry *de),
-			void *context);
 };
 
-extern struct dentry *find_exported_dentry(struct super_block *sb, void *obj,
-	void *parent, int (*acceptable)(void *context, struct dentry *de),
-	void *context);
-
-extern int exportfs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
-	int connectable);
-extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, __u32 *fh,
+extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
+	int *max_len, int connectable);
+extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
 	int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *),
 	void *context);
 
+/*
+ * Generic helpers for filesystems.
+ */
+extern struct dentry *generic_fh_to_dentry(struct super_block *sb,
+	struct fid *fid, int fh_len, int fh_type,
+	struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
+extern struct dentry *generic_fh_to_parent(struct super_block *sb,
+	struct fid *fid, int fh_len, int fh_type,
+	struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
+
 #endif /* LINUX_EXPORTFS_H */
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
index c77c3bb..0f6c86c 100644
--- a/include/linux/ext2_fs.h
+++ b/include/linux/ext2_fs.h
@@ -561,6 +561,7 @@
 #define EXT2_DIR_ROUND 			(EXT2_DIR_PAD - 1)
 #define EXT2_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT2_DIR_ROUND) & \
 					 ~EXT2_DIR_ROUND)
+#define EXT2_MAX_REC_LEN		((1<<16)-1)
 
 static inline ext2_fsblk_t
 ext2_group_first_block_no(struct super_block *sb, unsigned long group_no)
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 589b0b3..6413445 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -72,8 +72,8 @@
  * Macro-instructions used to manage several block sizes
  */
 #define EXT3_MIN_BLOCK_SIZE		1024
-#define	EXT3_MAX_BLOCK_SIZE		4096
-#define EXT3_MIN_BLOCK_LOG_SIZE		  10
+#define	EXT3_MAX_BLOCK_SIZE		65536
+#define EXT3_MIN_BLOCK_LOG_SIZE		10
 #ifdef __KERNEL__
 # define EXT3_BLOCK_SIZE(s)		((s)->s_blocksize)
 #else
diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h
index cdee7aa..97dd409 100644
--- a/include/linux/ext4_fs.h
+++ b/include/linux/ext4_fs.h
@@ -36,10 +36,6 @@
 /*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */
 #define EXT4_MAX_RESERVE_BLOCKS		1027
 #define EXT4_RESERVE_WINDOW_NOT_ALLOCATED 0
-/*
- * Always enable hashed directories
- */
-#define CONFIG_EXT4_INDEX
 
 /*
  * Debug code
@@ -105,37 +101,29 @@
 #define EXT4_BLOCK_ALIGN(size, blkbits)		ALIGN((size), (1 << (blkbits)))
 
 /*
- * Macro-instructions used to manage fragments
- */
-#define EXT4_MIN_FRAG_SIZE		1024
-#define	EXT4_MAX_FRAG_SIZE		4096
-#define EXT4_MIN_FRAG_LOG_SIZE		  10
-#ifdef __KERNEL__
-# define EXT4_FRAG_SIZE(s)		(EXT4_SB(s)->s_frag_size)
-# define EXT4_FRAGS_PER_BLOCK(s)	(EXT4_SB(s)->s_frags_per_block)
-#else
-# define EXT4_FRAG_SIZE(s)		(EXT4_MIN_FRAG_SIZE << (s)->s_log_frag_size)
-# define EXT4_FRAGS_PER_BLOCK(s)	(EXT4_BLOCK_SIZE(s) / EXT4_FRAG_SIZE(s))
-#endif
-
-/*
  * Structure of a blocks group descriptor
  */
 struct ext4_group_desc
 {
-	__le32	bg_block_bitmap;		/* Blocks bitmap block */
-	__le32	bg_inode_bitmap;		/* Inodes bitmap block */
-	__le32	bg_inode_table;		/* Inodes table block */
+	__le32	bg_block_bitmap_lo;	/* Blocks bitmap block */
+	__le32	bg_inode_bitmap_lo;	/* Inodes bitmap block */
+	__le32	bg_inode_table_lo;	/* Inodes table block */
 	__le16	bg_free_blocks_count;	/* Free blocks count */
 	__le16	bg_free_inodes_count;	/* Free inodes count */
 	__le16	bg_used_dirs_count;	/* Directories count */
-	__u16	bg_flags;
-	__u32	bg_reserved[3];
+	__le16	bg_flags;		/* EXT4_BG_flags (INODE_UNINIT, etc) */
+	__u32	bg_reserved[2];		/* Likely block/inode bitmap checksum */
+	__le16  bg_itable_unused;	/* Unused inodes count */
+	__le16  bg_checksum;		/* crc16(sb_uuid+group+desc) */
 	__le32	bg_block_bitmap_hi;	/* Blocks bitmap block MSB */
 	__le32	bg_inode_bitmap_hi;	/* Inodes bitmap block MSB */
 	__le32	bg_inode_table_hi;	/* Inodes table block MSB */
 };
 
+#define EXT4_BG_INODE_UNINIT	0x0001 /* Inode table/bitmap not in use */
+#define EXT4_BG_BLOCK_UNINIT	0x0002 /* Block bitmap not in use */
+#define EXT4_BG_INODE_ZEROED	0x0004 /* On-disk itable initialized to zero */
+
 #ifdef __KERNEL__
 #include <linux/ext4_fs_i.h>
 #include <linux/ext4_fs_sb.h>
@@ -311,27 +299,24 @@
 	__le32	i_generation;	/* File version (for NFS) */
 	__le32	i_file_acl;	/* File ACL */
 	__le32	i_dir_acl;	/* Directory ACL */
-	__le32	i_faddr;	/* Fragment address */
+	__le32	i_obso_faddr;	/* Obsoleted fragment address */
 	union {
 		struct {
-			__u8	l_i_frag;	/* Fragment number */
-			__u8	l_i_fsize;	/* Fragment size */
+			__le16	l_i_reserved1;	/* Obsoleted fragment number/size which are removed in ext4 */
 			__le16	l_i_file_acl_high;
 			__le16	l_i_uid_high;	/* these 2 fields */
 			__le16	l_i_gid_high;	/* were reserved2[0] */
 			__u32	l_i_reserved2;
 		} linux2;
 		struct {
-			__u8	h_i_frag;	/* Fragment number */
-			__u8	h_i_fsize;	/* Fragment size */
+			__le16	h_i_reserved1;	/* Obsoleted fragment number/size which are removed in ext4 */
 			__u16	h_i_mode_high;
 			__u16	h_i_uid_high;
 			__u16	h_i_gid_high;
 			__u32	h_i_author;
 		} hurd2;
 		struct {
-			__u8	m_i_frag;	/* Fragment number */
-			__u8	m_i_fsize;	/* Fragment size */
+			__le16	h_i_reserved1;	/* Obsoleted fragment number/size which are removed in ext4 */
 			__le16	m_i_file_acl_high;
 			__u32	m_i_reserved2[2];
 		} masix2;
@@ -419,8 +404,6 @@
 
 #if defined(__KERNEL__) || defined(__linux__)
 #define i_reserved1	osd1.linux1.l_i_reserved1
-#define i_frag		osd2.linux2.l_i_frag
-#define i_fsize		osd2.linux2.l_i_fsize
 #define i_file_acl_high	osd2.linux2.l_i_file_acl_high
 #define i_uid_low	i_uid
 #define i_gid_low	i_gid
@@ -431,8 +414,6 @@
 #elif defined(__GNU__)
 
 #define i_translator	osd1.hurd1.h_i_translator
-#define i_frag		osd2.hurd2.h_i_frag;
-#define i_fsize		osd2.hurd2.h_i_fsize;
 #define i_uid_high	osd2.hurd2.h_i_uid_high
 #define i_gid_high	osd2.hurd2.h_i_gid_high
 #define i_author	osd2.hurd2.h_i_author
@@ -440,8 +421,6 @@
 #elif defined(__masix__)
 
 #define i_reserved1	osd1.masix1.m_i_reserved1
-#define i_frag		osd2.masix2.m_i_frag
-#define i_fsize		osd2.masix2.m_i_fsize
 #define i_file_acl_high	osd2.masix2.m_i_file_acl_high
 #define i_reserved2	osd2.masix2.m_i_reserved2
 
@@ -522,15 +501,15 @@
  */
 struct ext4_super_block {
 /*00*/	__le32	s_inodes_count;		/* Inodes count */
-	__le32	s_blocks_count;		/* Blocks count */
-	__le32	s_r_blocks_count;	/* Reserved blocks count */
-	__le32	s_free_blocks_count;	/* Free blocks count */
+	__le32	s_blocks_count_lo;	/* Blocks count */
+	__le32	s_r_blocks_count_lo;	/* Reserved blocks count */
+	__le32	s_free_blocks_count_lo;	/* Free blocks count */
 /*10*/	__le32	s_free_inodes_count;	/* Free inodes count */
 	__le32	s_first_data_block;	/* First Data Block */
 	__le32	s_log_block_size;	/* Block size */
-	__le32	s_log_frag_size;	/* Fragment size */
+	__le32	s_obso_log_frag_size;	/* Obsoleted fragment size */
 /*20*/	__le32	s_blocks_per_group;	/* # Blocks per group */
-	__le32	s_frags_per_group;	/* # Fragments per group */
+	__le32	s_obso_frags_per_group;	/* Obsoleted fragments per group */
 	__le32	s_inodes_per_group;	/* # Inodes per group */
 	__le32	s_mtime;		/* Mount time */
 /*30*/	__le32	s_wtime;		/* Write time */
@@ -595,13 +574,13 @@
 /*150*/	__le32	s_blocks_count_hi;	/* Blocks count */
 	__le32	s_r_blocks_count_hi;	/* Reserved blocks count */
 	__le32	s_free_blocks_count_hi;	/* Free blocks count */
-	__u16	s_min_extra_isize;	/* All inodes have at least # bytes */
-	__u16	s_want_extra_isize; 	/* New inodes should reserve # bytes */
-	__u32	s_flags;		/* Miscellaneous flags */
-	__u16   s_raid_stride;		/* RAID stride */
-	__u16   s_mmp_interval;         /* # seconds to wait in MMP checking */
-	__u64   s_mmp_block;            /* Block for multi-mount protection */
-	__u32   s_raid_stripe_width;    /* blocks on all data disks (N*stride)*/
+	__le16	s_min_extra_isize;	/* All inodes have at least # bytes */
+	__le16	s_want_extra_isize; 	/* New inodes should reserve # bytes */
+	__le32	s_flags;		/* Miscellaneous flags */
+	__le16  s_raid_stride;		/* RAID stride */
+	__le16  s_mmp_interval;         /* # seconds to wait in MMP checking */
+	__le64  s_mmp_block;            /* Block for multi-mount protection */
+	__le32  s_raid_stripe_width;    /* blocks on all data disks (N*stride)*/
 	__u32   s_reserved[163];        /* Padding to the end of the block */
 };
 
@@ -692,6 +671,7 @@
 #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER	0x0001
 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE	0x0002
 #define EXT4_FEATURE_RO_COMPAT_BTREE_DIR	0x0004
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM		0x0010
 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK	0x0020
 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE	0x0040
 
@@ -702,15 +682,18 @@
 #define EXT4_FEATURE_INCOMPAT_META_BG		0x0010
 #define EXT4_FEATURE_INCOMPAT_EXTENTS		0x0040 /* extents support */
 #define EXT4_FEATURE_INCOMPAT_64BIT		0x0080
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG		0x0200
 
 #define EXT4_FEATURE_COMPAT_SUPP	EXT2_FEATURE_COMPAT_EXT_ATTR
 #define EXT4_FEATURE_INCOMPAT_SUPP	(EXT4_FEATURE_INCOMPAT_FILETYPE| \
 					 EXT4_FEATURE_INCOMPAT_RECOVER| \
 					 EXT4_FEATURE_INCOMPAT_META_BG| \
 					 EXT4_FEATURE_INCOMPAT_EXTENTS| \
-					 EXT4_FEATURE_INCOMPAT_64BIT)
+					 EXT4_FEATURE_INCOMPAT_64BIT| \
+					 EXT4_FEATURE_INCOMPAT_FLEX_BG)
 #define EXT4_FEATURE_RO_COMPAT_SUPP	(EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
 					 EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
+					 EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \
 					 EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \
 					 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \
 					 EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
@@ -789,17 +772,11 @@
  * (c) Daniel Phillips, 2001
  */
 
-#ifdef CONFIG_EXT4_INDEX
-  #define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \
-					      EXT4_FEATURE_COMPAT_DIR_INDEX) && \
+#define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \
+				      EXT4_FEATURE_COMPAT_DIR_INDEX) && \
 		      (EXT4_I(dir)->i_flags & EXT4_INDEX_FL))
 #define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX)
 #define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
-#else
-  #define is_dx(dir) 0
-#define EXT4_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT4_LINK_MAX)
-#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
-#endif
 
 /* Legal values for the dx_root hash_version field: */
 
@@ -1004,39 +981,39 @@
 static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
 {
 	return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
-		le32_to_cpu(es->s_blocks_count);
+		le32_to_cpu(es->s_blocks_count_lo);
 }
 
 static inline ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es)
 {
 	return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
-		le32_to_cpu(es->s_r_blocks_count);
+		le32_to_cpu(es->s_r_blocks_count_lo);
 }
 
 static inline ext4_fsblk_t ext4_free_blocks_count(struct ext4_super_block *es)
 {
 	return ((ext4_fsblk_t)le32_to_cpu(es->s_free_blocks_count_hi) << 32) |
-		le32_to_cpu(es->s_free_blocks_count);
+		le32_to_cpu(es->s_free_blocks_count_lo);
 }
 
 static inline void ext4_blocks_count_set(struct ext4_super_block *es,
 					 ext4_fsblk_t blk)
 {
-	es->s_blocks_count = cpu_to_le32((u32)blk);
+	es->s_blocks_count_lo = cpu_to_le32((u32)blk);
 	es->s_blocks_count_hi = cpu_to_le32(blk >> 32);
 }
 
 static inline void ext4_free_blocks_count_set(struct ext4_super_block *es,
 					      ext4_fsblk_t blk)
 {
-	es->s_free_blocks_count = cpu_to_le32((u32)blk);
+	es->s_free_blocks_count_lo = cpu_to_le32((u32)blk);
 	es->s_free_blocks_count_hi = cpu_to_le32(blk >> 32);
 }
 
 static inline void ext4_r_blocks_count_set(struct ext4_super_block *es,
 					   ext4_fsblk_t blk)
 {
-	es->s_r_blocks_count = cpu_to_le32((u32)blk);
+	es->s_r_blocks_count_lo = cpu_to_le32((u32)blk);
 	es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32);
 }
 
diff --git a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h
index 81406f3..d2045a2 100644
--- a/include/linux/ext4_fs_extents.h
+++ b/include/linux/ext4_fs_extents.h
@@ -74,7 +74,7 @@
 	__le32	ee_block;	/* first logical block extent covers */
 	__le16	ee_len;		/* number of blocks covered by extent */
 	__le16	ee_start_hi;	/* high 16 bits of physical block */
-	__le32	ee_start;	/* low 32 bits of physical block */
+	__le32	ee_start_lo;	/* low 32 bits of physical block */
 };
 
 /*
@@ -83,7 +83,7 @@
  */
 struct ext4_extent_idx {
 	__le32	ei_block;	/* index covers logical blocks from 'block' */
-	__le32	ei_leaf;	/* pointer to the physical block of the next *
+	__le32	ei_leaf_lo;	/* pointer to the physical block of the next *
 				 * level. leaf or next index could be there */
 	__le16	ei_leaf_hi;	/* high 16 bits of physical block */
 	__u16	ei_unused;
diff --git a/include/linux/ext4_fs_i.h b/include/linux/ext4_fs_i.h
index 1a511e99..86ddfe2 100644
--- a/include/linux/ext4_fs_i.h
+++ b/include/linux/ext4_fs_i.h
@@ -78,11 +78,6 @@
 struct ext4_inode_info {
 	__le32	i_data[15];	/* unconverted */
 	__u32	i_flags;
-#ifdef EXT4_FRAGMENTS
-	__u32	i_faddr;
-	__u8	i_frag_no;
-	__u8	i_frag_size;
-#endif
 	ext4_fsblk_t	i_file_acl;
 	__u32	i_dir_acl;
 	__u32	i_dtime;
diff --git a/include/linux/ext4_fs_sb.h b/include/linux/ext4_fs_sb.h
index 0a8e47d..b40e827 100644
--- a/include/linux/ext4_fs_sb.h
+++ b/include/linux/ext4_fs_sb.h
@@ -28,11 +28,8 @@
  * third extended-fs super-block data in memory
  */
 struct ext4_sb_info {
-	unsigned long s_frag_size;	/* Size of a fragment in bytes */
 	unsigned long s_desc_size;	/* Size of a group descriptor in bytes */
-	unsigned long s_frags_per_block;/* Number of fragments per block */
 	unsigned long s_inodes_per_block;/* Number of inodes per block */
-	unsigned long s_frags_per_group;/* Number of fragments in a group */
 	unsigned long s_blocks_per_group;/* Number of blocks in a group */
 	unsigned long s_inodes_per_group;/* Number of inodes in a group */
 	unsigned long s_itb_per_group;	/* Number of inode table blocks per group */
diff --git a/include/linux/ext4_jbd2.h b/include/linux/ext4_jbd2.h
index d716e63..38c71d3 100644
--- a/include/linux/ext4_jbd2.h
+++ b/include/linux/ext4_jbd2.h
@@ -12,8 +12,8 @@
  * Ext4-specific journaling extensions.
  */
 
-#ifndef _LINUX_EXT4_JBD_H
-#define _LINUX_EXT4_JBD_H
+#ifndef _LINUX_EXT4_JBD2_H
+#define _LINUX_EXT4_JBD2_H
 
 #include <linux/fs.h>
 #include <linux/jbd2.h>
@@ -228,4 +228,4 @@
 	return 0;
 }
 
-#endif	/* _LINUX_EXT4_JBD_H */
+#endif	/* _LINUX_EXT4_JBD2_H */
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 91b2e3b..ddfa037 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -146,6 +146,7 @@
 
 extern unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen);
 extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
+extern int sk_detach_filter(struct sock *sk);
 extern int sk_chk_filter(struct sock_filter *filter, int flen);
 #endif /* __KERNEL__ */
 
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index efded00..0893499 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -4,6 +4,7 @@
 #define FREEZER_H_INCLUDED
 
 #include <linux/sched.h>
+#include <linux/wait.h>
 
 #ifdef CONFIG_PM_SLEEP
 /*
@@ -126,6 +127,36 @@
 	current->flags &= ~PF_NOFREEZE;
 }
 
+/*
+ * Freezer-friendly wrappers around wait_event_interruptible() and
+ * wait_event_interruptible_timeout(), originally defined in <linux/wait.h>
+ */
+
+#define wait_event_freezable(wq, condition)				\
+({									\
+	int __retval;							\
+	do {								\
+		__retval = wait_event_interruptible(wq, 		\
+				(condition) || freezing(current));	\
+		if (__retval && !freezing(current))			\
+			break;						\
+		else if (!(condition))					\
+			__retval = -ERESTARTSYS;			\
+	} while (try_to_freeze());					\
+	__retval;							\
+})
+
+
+#define wait_event_freezable_timeout(wq, condition, timeout)		\
+({									\
+	long __retval = timeout;					\
+	do {								\
+		__retval = wait_event_interruptible_timeout(wq,		\
+				(condition) || freezing(current),	\
+				__retval); 				\
+	} while (try_to_freeze());					\
+	__retval;							\
+})
 #else /* !CONFIG_PM_SLEEP */
 static inline int frozen(struct task_struct *p) { return 0; }
 static inline int freezing(struct task_struct *p) { return 0; }
@@ -143,6 +174,13 @@
 static inline void freezer_count(void) {}
 static inline int freezer_should_skip(struct task_struct *p) { return 0; }
 static inline void set_freezable(void) {}
+
+#define wait_event_freezable(wq, condition)				\
+		wait_event_interruptible(wq, condition)
+
+#define wait_event_freezable_timeout(wq, condition, timeout)		\
+		wait_event_interruptible_timeout(wq, condition, timeout)
+
 #endif /* !CONFIG_PM_SLEEP */
 
 #endif	/* FREEZER_H_INCLUDED */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e3fc5db..b3ec4a4 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -123,6 +123,7 @@
 #define MS_SLAVE	(1<<19)	/* change to slave */
 #define MS_SHARED	(1<<20)	/* change to shared */
 #define MS_RELATIME	(1<<21)	/* Update atime relative to mtime/ctime. */
+#define MS_KERNMOUNT	(1<<22) /* this is a kern_mount call */
 #define MS_ACTIVE	(1<<30)
 #define MS_NOUSER	(1<<31)
 
@@ -330,6 +331,7 @@
 #define ATTR_KILL_SGID	4096
 #define ATTR_FILE	8192
 #define ATTR_KILL_PRIV	16384
+#define ATTR_OPEN	32768	/* Truncating from open(O_TRUNC) */
 
 /*
  * This is the Inode Attributes structure, used for notify_change().  It
@@ -985,7 +987,7 @@
 	const struct super_operations	*s_op;
 	struct dquot_operations	*dq_op;
  	struct quotactl_ops	*s_qcop;
-	struct export_operations *s_export_op;
+	const struct export_operations *s_export_op;
 	unsigned long		s_flags;
 	unsigned long		s_magic;
 	struct dentry		*s_root;
@@ -1458,7 +1460,8 @@
 
 extern int register_filesystem(struct file_system_type *);
 extern int unregister_filesystem(struct file_system_type *);
-extern struct vfsmount *kern_mount(struct file_system_type *);
+extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
+#define kern_mount(type) kern_mount_data(type, NULL)
 extern int may_umount_tree(struct vfsmount *);
 extern int may_umount(struct vfsmount *);
 extern void umount_tree(struct vfsmount *, int, struct list_head *);
@@ -1467,6 +1470,8 @@
 extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
 extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
 				  struct vfsmount *);
+extern struct vfsmount *collect_mounts(struct vfsmount *, struct dentry *);
+extern void drop_collected_mounts(struct vfsmount *);
 
 extern int vfs_statfs(struct dentry *, struct kstatfs *);
 
@@ -1533,7 +1538,7 @@
 
 extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
 		       struct file *filp);
-extern long do_sys_open(int fdf, const char __user *filename, int flags,
+extern long do_sys_open(int dfd, const char __user *filename, int flags,
 			int mode);
 extern struct file *filp_open(const char *, int, int);
 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
@@ -1921,6 +1926,8 @@
 
 extern int vfs_ioctl(struct file *, unsigned int, unsigned int, unsigned long);
 
+extern void get_filesystem(struct file_system_type *fs);
+extern void put_filesystem(struct file_system_type *fs);
 extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(struct block_device *);
 extern struct super_block *user_get_super(dev_t);
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index dfc4e4f..2bd31fa 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -41,8 +41,9 @@
  */
 static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
 				 const char *old_name, const char *new_name,
-				 int isdir, struct inode *target, struct inode *source)
+				 int isdir, struct inode *target, struct dentry *moved)
 {
+	struct inode *source = moved->d_inode;
 	u32 cookie = inotify_get_cookie();
 
 	if (old_dir == new_dir)
@@ -67,7 +68,7 @@
 	if (source) {
 		inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL);
 	}
-	audit_inode_child(new_name, source, new_dir);
+	audit_inode_child(new_name, moved, new_dir);
 }
 
 /*
@@ -98,7 +99,7 @@
 	inode_dir_notify(inode, DN_CREATE);
 	inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name,
 				  dentry->d_inode);
-	audit_inode_child(dentry->d_name.name, dentry->d_inode, inode);
+	audit_inode_child(dentry->d_name.name, dentry, inode);
 }
 
 /*
@@ -109,7 +110,7 @@
 	inode_dir_notify(inode, DN_CREATE);
 	inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0, 
 				  dentry->d_name.name, dentry->d_inode);
-	audit_inode_child(dentry->d_name.name, dentry->d_inode, inode);
+	audit_inode_child(dentry->d_name.name, dentry, inode);
 }
 
 /*
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 9fbe9d2..d0c4370 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -6,7 +6,17 @@
     See the file COPYING.
 */
 
-/* This file defines the kernel interface of FUSE */
+/*
+ * This file defines the kernel interface of FUSE
+ *
+ * Protocol changelog:
+ *
+ * 7.9:
+ *  - new fuse_getattr_in input argument of GETATTR
+ *  - add lk_flags in fuse_lk_in
+ *  - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
+ *  - add blksize field to fuse_attr
+ */
 
 #include <asm/types.h>
 #include <linux/major.h>
@@ -15,7 +25,7 @@
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 8
+#define FUSE_KERNEL_MINOR_VERSION 9
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -44,6 +54,8 @@
 	__u32	uid;
 	__u32	gid;
 	__u32	rdev;
+	__u32	blksize;
+	__u32	padding;
 };
 
 struct fuse_kstatfs {
@@ -76,6 +88,9 @@
 #define FATTR_ATIME	(1 << 4)
 #define FATTR_MTIME	(1 << 5)
 #define FATTR_FH	(1 << 6)
+#define FATTR_ATIME_NOW	(1 << 7)
+#define FATTR_MTIME_NOW	(1 << 8)
+#define FATTR_LOCKOWNER	(1 << 9)
 
 /**
  * Flags returned by the OPEN request
@@ -91,12 +106,38 @@
  */
 #define FUSE_ASYNC_READ		(1 << 0)
 #define FUSE_POSIX_LOCKS	(1 << 1)
+#define FUSE_FILE_OPS		(1 << 2)
+#define FUSE_ATOMIC_O_TRUNC	(1 << 3)
 
 /**
  * Release flags
  */
 #define FUSE_RELEASE_FLUSH	(1 << 0)
 
+/**
+ * Getattr flags
+ */
+#define FUSE_GETATTR_FH		(1 << 0)
+
+/**
+ * Lock flags
+ */
+#define FUSE_LK_FLOCK		(1 << 0)
+
+/**
+ * WRITE flags
+ *
+ * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
+ * FUSE_WRITE_LOCKOWNER: lock_owner field is valid
+ */
+#define FUSE_WRITE_CACHE	(1 << 0)
+#define FUSE_WRITE_LOCKOWNER	(1 << 1)
+
+/**
+ * Read flags
+ */
+#define FUSE_READ_LOCKOWNER	(1 << 1)
+
 enum fuse_opcode {
 	FUSE_LOOKUP	   = 1,
 	FUSE_FORGET	   = 2,  /* no reply */
@@ -139,6 +180,8 @@
 /* The read buffer is required to be at least 8k, but may be much larger */
 #define FUSE_MIN_READ_BUFFER 8192
 
+#define FUSE_COMPAT_ENTRY_OUT_SIZE 120
+
 struct fuse_entry_out {
 	__u64	nodeid;		/* Inode ID */
 	__u64	generation;	/* Inode generation: nodeid:gen must
@@ -154,6 +197,14 @@
 	__u64	nlookup;
 };
 
+struct fuse_getattr_in {
+	__u32	getattr_flags;
+	__u32	dummy;
+	__u64	fh;
+};
+
+#define FUSE_COMPAT_ATTR_OUT_SIZE 96
+
 struct fuse_attr_out {
 	__u64	attr_valid;	/* Cache timeout for the attributes */
 	__u32	attr_valid_nsec;
@@ -184,7 +235,7 @@
 	__u32	padding;
 	__u64	fh;
 	__u64	size;
-	__u64	unused1;
+	__u64	lock_owner;
 	__u64	atime;
 	__u64	mtime;
 	__u64	unused2;
@@ -227,14 +278,18 @@
 	__u64	fh;
 	__u64	offset;
 	__u32	size;
-	__u32	padding;
+	__u32	read_flags;
+	__u64	lock_owner;
 };
 
+#define FUSE_COMPAT_WRITE_IN_SIZE 24
+
 struct fuse_write_in {
 	__u64	fh;
 	__u64	offset;
 	__u32	size;
 	__u32	write_flags;
+	__u64	lock_owner;
 };
 
 struct fuse_write_out {
@@ -273,6 +328,8 @@
 	__u64	fh;
 	__u64	owner;
 	struct fuse_file_lock lk;
+	__u32	lk_flags;
+	__u32	padding;
 };
 
 struct fuse_lk_out {
diff --git a/include/linux/hid.h b/include/linux/hid.h
index edb8024..6e35b92 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -469,8 +469,8 @@
 	/* handler for raw output data, used by hidraw */
 	int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t);
 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK
-	unsigned long pb_pressed_fn[NBITS(KEY_MAX)];
-	unsigned long pb_pressed_numlock[NBITS(KEY_MAX)];
+	unsigned long pb_pressed_fn[BITS_TO_LONGS(KEY_CNT)];
+	unsigned long pb_pressed_numlock[BITS_TO_LONGS(KEY_CNT)];
 #endif
 };
 
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 540799b..7a9398e 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -300,7 +300,7 @@
 
 /* Precise sleep: */
 extern long hrtimer_nanosleep(struct timespec *rqtp,
-			      struct timespec __user *rmtp,
+			      struct timespec *rmtp,
 			      const enum hrtimer_mode mode,
 			      const clockid_t clockid);
 extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
diff --git a/include/linux/i8042.h b/include/linux/i8042.h
new file mode 100644
index 0000000..7907a72
--- /dev/null
+++ b/include/linux/i8042.h
@@ -0,0 +1,35 @@
+#ifndef _LINUX_I8042_H
+#define _LINUX_I8042_H
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+
+/*
+ * Standard commands.
+ */
+
+#define I8042_CMD_CTL_RCTR	0x0120
+#define I8042_CMD_CTL_WCTR	0x1060
+#define I8042_CMD_CTL_TEST	0x01aa
+
+#define I8042_CMD_KBD_DISABLE	0x00ad
+#define I8042_CMD_KBD_ENABLE	0x00ae
+#define I8042_CMD_KBD_TEST	0x01ab
+#define I8042_CMD_KBD_LOOP	0x11d2
+
+#define I8042_CMD_AUX_DISABLE	0x00a7
+#define I8042_CMD_AUX_ENABLE	0x00a8
+#define I8042_CMD_AUX_TEST	0x01a9
+#define I8042_CMD_AUX_SEND	0x10d4
+#define I8042_CMD_AUX_LOOP	0x11d3
+
+#define I8042_CMD_MUX_PFX	0x0090
+#define I8042_CMD_MUX_SEND	0x1090
+
+int i8042_command(unsigned char *param, int command);
+
+#endif
diff --git a/include/linux/ide.h b/include/linux/ide.h
index e39ee2f..4ed4777 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -192,22 +192,20 @@
 struct hwif_s;
 typedef int (ide_ack_intr_t)(struct hwif_s *);
 
-#ifndef NO_DMA
-#define NO_DMA  255
-#endif
-
 /*
  * hwif_chipset_t is used to keep track of the specific hardware
  * chipset used by each IDE interface, if known.
  */
-typedef enum {	ide_unknown,	ide_generic,	ide_pci,
+enum {		ide_unknown,	ide_generic,	ide_pci,
 		ide_cmd640,	ide_dtc2278,	ide_ali14xx,
 		ide_qd65xx,	ide_umc8672,	ide_ht6560b,
 		ide_rz1000,	ide_trm290,
 		ide_cmd646,	ide_cy82c693,	ide_4drives,
 		ide_pmac,	ide_etrax100,	ide_acorn,
 		ide_au1xxx, ide_forced
-} hwif_chipset_t;
+};
+
+typedef u8 hwif_chipset_t;
 
 /*
  * Structure to hold all information about the location of this port
@@ -215,22 +213,16 @@
 typedef struct hw_regs_s {
 	unsigned long	io_ports[IDE_NR_PORTS];	/* task file registers */
 	int		irq;			/* our irq number */
-	int		dma;			/* our dma entry */
 	ide_ack_intr_t	*ack_intr;		/* acknowledge interrupt */
 	hwif_chipset_t  chipset;
 	struct device	*dev;
 } hw_regs_t;
 
-/*
- * Register new hardware with ide
- */
-int ide_register_hw(hw_regs_t *, int, struct hwif_s **);
-int ide_register_hw_with_fixup(hw_regs_t *, int, struct hwif_s **,
-			       void (*)(struct hwif_s *));
+struct hwif_s * ide_find_port(unsigned long);
 
-/*
- * Set up hw_regs_t structure before calling ide_register_hw (optional)
- */
+int ide_register_hw(hw_regs_t *, void (*)(struct hwif_s *), int,
+		    struct hwif_s **);
+
 void ide_setup_ports(	hw_regs_t *hw,
 			unsigned long base,
 			int *offsets,
@@ -268,11 +260,7 @@
 # define ide_init_default_irq(base)	(0)
 #endif
 
-/*
- * ide_init_hwif_ports() is OBSOLETE and will be removed in 2.7 series.
- * New ports shouldn't define IDE_ARCH_OBSOLETE_INIT in <asm/ide.h>.
- */
-#ifdef IDE_ARCH_OBSOLETE_INIT
+#ifdef CONFIG_IDE_ARCH_OBSOLETE_INIT
 static inline void ide_init_hwif_ports(hw_regs_t *hw,
 				       unsigned long io_addr,
 				       unsigned long ctl_addr,
@@ -302,7 +290,7 @@
 	if (io_addr || ctl_addr)
 		printk(KERN_WARNING "%s: must not be called\n", __FUNCTION__);
 }
-#endif /* IDE_ARCH_OBSOLETE_INIT */
+#endif /* CONFIG_IDE_ARCH_OBSOLETE_INIT */
 
 /* Currently only m68k, apus and m8xx need it */
 #ifndef IDE_ARCH_ACK_INTR
@@ -363,7 +351,6 @@
  * ATA DATA Register Special.
  * ATA NSECTOR Count Register().
  * ATAPI Byte Count Register.
- * Channel index ordering pairs.
  */
 typedef union {
 	unsigned all			:16;
@@ -378,7 +365,7 @@
 #error "Please fix <asm/byteorder.h>"
 #endif
 	} b;
-} ata_nsector_t, ata_data_t, atapi_bcount_t, ata_index_t;
+} ata_nsector_t, ata_data_t, atapi_bcount_t;
 
 /*
  * ATA-IDE Select Register, aka Device-Head
@@ -657,7 +644,7 @@
     ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
 #define IDE_CHIPSET_IS_PCI(c)	((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
 
-struct ide_pci_device_s;
+struct ide_port_info;
 
 typedef struct hwif_s {
 	struct hwif_s *next;		/* for linked-list in ide_hwgroup_t */
@@ -672,7 +659,6 @@
 	unsigned long	sata_scr[SATA_NR_PORTS];
 	unsigned long	sata_misc[SATA_NR_PORTS];
 
-	hw_regs_t	hw;		/* Hardware info */
 	ide_drive_t	drives[MAX_DRIVES];	/* drive info */
 
 	u8 major;	/* our major number */
@@ -681,11 +667,10 @@
 	u8 straight8;	/* Alan's straight 8 check */
 	u8 bus_state;	/* power state of the IDE bus */
 
-	u16 host_flags;
+	u32 host_flags;
 
 	u8 pio_mask;
 
-	u8 atapi_dma;	/* host supports atapi_dma */
 	u8 ultra_mask;
 	u8 mwdma_mask;
 	u8 swdma_mask;
@@ -695,7 +680,9 @@
 	hwif_chipset_t chipset;	/* sub-module for tuning.. */
 
 	struct pci_dev  *pci_dev;	/* for pci chipsets */
-	struct ide_pci_device_s	*cds;	/* chipset device struct */
+	const struct ide_port_info *cds;	/* chipset device struct */
+
+	ide_ack_intr_t *ack_intr;
 
 	void (*rw_disk)(ide_drive_t *, struct request *);
 
@@ -726,6 +713,8 @@
 	u8 (*mdma_filter)(ide_drive_t *);
 	u8 (*udma_filter)(ide_drive_t *);
 
+	void (*fixup)(struct hwif_s *);
+
 	void (*ata_input_data)(ide_drive_t *, void *, u32);
 	void (*ata_output_data)(ide_drive_t *, void *, u32);
 
@@ -797,12 +786,9 @@
 	unsigned	serialized : 1;	/* serialized all channel operation */
 	unsigned	sharing_irq: 1;	/* 1 = sharing irq with another hwif */
 	unsigned	reset      : 1;	/* reset after probe */
-	unsigned	no_lba48   : 1; /* 1 = cannot do LBA48 */
-	unsigned	no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */
 	unsigned	auto_poll  : 1; /* supports nop auto-poll */
 	unsigned	sg_mapped  : 1;	/* sg_table and sg_nents are ready */
 	unsigned	no_io_32bit : 1; /* 1 = can not do 32-bit IO ops */
-	unsigned	err_stops_fifo : 1; /* 1=data FIFO is cleared by an error */
 	unsigned	mmio       : 1; /* host uses MMIO */
 
 	struct device	gendev;
@@ -845,8 +831,6 @@
 
 		/* for pci chipsets */
 	struct pci_dev *pci_dev;
-		/* chipset device struct */
-	struct ide_pci_device_s *cds;
 
 		/* current request */
 	struct request *rq;
@@ -1034,36 +1018,16 @@
 int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
 			     int uptodate, int nr_sectors);
 
-/*
- * This is used on exit from the driver to designate the next irq handler
- * and also to start the safety timer.
- */
 extern void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry);
 
-/*
- * This is used on exit from the driver to designate the next irq handler
- * and start the safety time safely and atomically from the IRQ handler
- * with respect to the command issue (which it also does)
- */
 extern void ide_execute_command(ide_drive_t *, task_ioreg_t cmd, ide_handler_t *, unsigned int, ide_expiry_t *);
 
 ide_startstop_t __ide_error(ide_drive_t *, struct request *, u8, u8);
 
-/*
- * ide_error() takes action based on the error returned by the controller.
- * The caller should return immediately after invoking this.
- *
- * (drive, msg, status)
- */
 ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat);
 
 ide_startstop_t __ide_abort(ide_drive_t *, struct request *);
 
-/*
- * Abort a running command on the controller triggering the abort
- * from a host side, non error situation
- * (drive, msg)
- */
 extern ide_startstop_t ide_abort(ide_drive_t *, const char *);
 
 extern void ide_fix_driveid(struct hd_driveid *);
@@ -1079,15 +1043,8 @@
 
 int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
 
-/*
- * Start a reset operation for an IDE interface.
- * The caller should return immediately after invoking this.
- */
 extern ide_startstop_t ide_do_reset (ide_drive_t *);
 
-/*
- * This function is intended to be used prior to invoking ide_do_drive_cmd().
- */
 extern void ide_init_drive_cmd (struct request *rq);
 
 /*
@@ -1102,13 +1059,6 @@
 
 extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t);
 
-/*
- * Clean up after success/failure of an explicit drive cmd.
- * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_CMD).
- * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASK_MASK).
- *
- * (ide_drive_t *drive, u8 stat, u8 err)
- */
 extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
 
 /*
@@ -1181,10 +1131,6 @@
 
 extern int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout);
 
-/*
- * ide_stall_queue() can be used by a drive to give excess bandwidth back
- * to the hwgroup by sleeping for timeout jiffies.
- */
 extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
 
 extern int ide_spin_wait_hwgroup(ide_drive_t *);
@@ -1204,26 +1150,13 @@
 #define ide_pci_register_driver(d) pci_register_driver(d)
 #endif
 
-void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *);
-extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d);
+void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, u8 *);
+void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *);
 
 extern void default_hwif_iops(ide_hwif_t *);
 extern void default_hwif_mmiops(ide_hwif_t *);
 extern void default_hwif_transport(ide_hwif_t *);
 
-#define ON_BOARD		1
-#define NEVER_BOARD		0
-
-#ifdef CONFIG_BLK_DEV_OFFBOARD
-#  define OFF_BOARD		ON_BOARD
-#else /* CONFIG_BLK_DEV_OFFBOARD */
-#  define OFF_BOARD		NEVER_BOARD
-#endif /* CONFIG_BLK_DEV_OFFBOARD */
-
-#define NODMA 0
-#define NOAUTODMA 1
-#define AUTODMA 2
-
 typedef struct ide_pci_enablebit_s {
 	u8	reg;	/* byte pci reg holding the enable-bit */
 	u8	mask;	/* mask to isolate the enable-bit */
@@ -1258,29 +1191,61 @@
 	IDE_HFLAG_TRUST_BIOS_FOR_DMA	= (1 << 10),
 	/* host uses VDMA */
 	IDE_HFLAG_VDMA			= (1 << 11),
+	/* ATAPI DMA is unsupported */
+	IDE_HFLAG_NO_ATAPI_DMA		= (1 << 12),
+	/* set if host is a "bootable" controller */
+	IDE_HFLAG_BOOTABLE		= (1 << 13),
+	/* host doesn't support DMA */
+	IDE_HFLAG_NO_DMA		= (1 << 14),
+	/* check if host is PCI IDE device before allowing DMA */
+	IDE_HFLAG_NO_AUTODMA		= (1 << 15),
+	/* host is CS5510/CS5520 */
+	IDE_HFLAG_CS5520		= (1 << 16),
+	/* no LBA48 */
+	IDE_HFLAG_NO_LBA48		= (1 << 17),
+	/* no LBA48 DMA */
+	IDE_HFLAG_NO_LBA48_DMA		= (1 << 18),
+	/* data FIFO is cleared by an error */
+	IDE_HFLAG_ERROR_STOPS_FIFO	= (1 << 19),
+	/* serialize ports */
+	IDE_HFLAG_SERIALIZE		= (1 << 20),
+	/* use legacy IRQs */
+	IDE_HFLAG_LEGACY_IRQS		= (1 << 21),
+	/* force use of legacy IRQs */
+	IDE_HFLAG_FORCE_LEGACY_IRQS	= (1 << 22),
+	/* limit LBA48 requests to 256 sectors */
+	IDE_HFLAG_RQSIZE_256		= (1 << 23),
+	/* use 32-bit I/O ops */
+	IDE_HFLAG_IO_32BIT		= (1 << 24),
+	/* unmask IRQs */
+	IDE_HFLAG_UNMASK_IRQS		= (1 << 25),
 };
 
-typedef struct ide_pci_device_s {
+#ifdef CONFIG_BLK_DEV_OFFBOARD
+# define IDE_HFLAG_OFF_BOARD	IDE_HFLAG_BOOTABLE
+#else
+# define IDE_HFLAG_OFF_BOARD	0
+#endif
+
+struct ide_port_info {
 	char			*name;
-	int			(*init_setup)(struct pci_dev *, struct ide_pci_device_s *);
-	void			(*init_setup_dma)(struct pci_dev *, struct ide_pci_device_s *, ide_hwif_t *);
 	unsigned int		(*init_chipset)(struct pci_dev *, const char *);
 	void			(*init_iops)(ide_hwif_t *);
 	void                    (*init_hwif)(ide_hwif_t *);
 	void			(*init_dma)(ide_hwif_t *, unsigned long);
 	void			(*fixup)(ide_hwif_t *);
-	u8			autodma;
 	ide_pci_enablebit_t	enablebits[2];
-	u8			bootable;
+	hwif_chipset_t		chipset;
 	unsigned int		extra;
-	struct ide_pci_device_s	*next;
-	u16			host_flags;
+	u32			host_flags;
 	u8			pio_mask;
+	u8			swdma_mask;
+	u8			mwdma_mask;
 	u8			udma_mask;
-} ide_pci_device_t;
+};
 
-extern int ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
-extern int ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, ide_pci_device_t *);
+int ide_setup_pci_device(struct pci_dev *, const struct ide_port_info *);
+int ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, const struct ide_port_info *);
 
 void ide_map_sg(ide_drive_t *, struct request *);
 void ide_init_sg_cmd(ide_drive_t *, struct request *);
@@ -1363,8 +1328,7 @@
 
 void ide_undecoded_slave(ide_hwif_t *);
 
-int probe_hwif_init_with_fixup(ide_hwif_t *, void (*)(ide_hwif_t *));
-extern int probe_hwif_init(ide_hwif_t *);
+int ide_device_add(u8 idx[4]);
 
 static inline void *ide_get_hwifdata (ide_hwif_t * hwif)
 {
@@ -1454,4 +1418,11 @@
 	return dev ? pcibus_to_node(dev->bus) : -1;
 }
 
+static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif	= HWIF(drive);
+
+	return &hwif->drives[(drive->dn ^ 1) & 1];
+}
+
 #endif /* _IDE_H */
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index d4b2f1c7..cae35b6 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -67,9 +67,6 @@
 	.posix_timers	 = LIST_HEAD_INIT(sig.posix_timers),		\
 	.cpu_timers	= INIT_CPU_TIMERS(sig.cpu_timers),		\
 	.rlim		= INIT_RLIMITS,					\
-	.pgrp		= 0,						\
-	.tty_old_pgrp   = NULL,						\
-	{ .__session      = 0},						\
 }
 
 extern struct nsproxy init_nsproxy;
@@ -94,15 +91,18 @@
 
 #define INIT_STRUCT_PID {						\
 	.count 		= ATOMIC_INIT(1),				\
-	.nr		= 0, 						\
-	/* Don't put this struct pid in pid_hash */			\
-	.pid_chain	= { .next = NULL, .pprev = NULL },		\
 	.tasks		= {						\
 		{ .first = &init_task.pids[PIDTYPE_PID].node },		\
 		{ .first = &init_task.pids[PIDTYPE_PGID].node },	\
 		{ .first = &init_task.pids[PIDTYPE_SID].node },		\
 	},								\
 	.rcu		= RCU_HEAD_INIT,				\
+	.level		= 0,						\
+	.numbers	= { {						\
+		.nr		= 0,					\
+		.ns		= &init_pid_ns,				\
+		.pid_chain	= { .next = NULL, .pprev = NULL },	\
+	}, }								\
 }
 
 #define INIT_PID_LINK(type) 					\
diff --git a/include/linux/inotify.h b/include/linux/inotify.h
index d4f48c6..742b917 100644
--- a/include/linux/inotify.h
+++ b/include/linux/inotify.h
@@ -120,6 +120,8 @@
 				       u32);
 extern __s32 inotify_add_watch(struct inotify_handle *, struct inotify_watch *,
 			       struct inode *, __u32);
+extern __s32 inotify_clone_watch(struct inotify_watch *, struct inotify_watch *);
+extern void inotify_evict_watch(struct inotify_watch *);
 extern int inotify_rm_watch(struct inotify_handle *, struct inotify_watch *);
 extern int inotify_rm_wd(struct inotify_handle *, __u32);
 extern void inotify_remove_watch_locked(struct inotify_handle *,
diff --git a/include/linux/input.h b/include/linux/input.h
index f30da6f..6226892 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -98,6 +98,7 @@
 #define EV_PWR			0x16
 #define EV_FF_STATUS		0x17
 #define EV_MAX			0x1f
+#define EV_CNT			(EV_MAX+1)
 
 /*
  * Synchronization events.
@@ -567,6 +568,7 @@
 /* We avoid low common keys in module aliases so they don't get huge. */
 #define KEY_MIN_INTERESTING	KEY_MUTE
 #define KEY_MAX			0x1ff
+#define KEY_CNT			(KEY_MAX+1)
 
 /*
  * Relative axes
@@ -583,6 +585,7 @@
 #define REL_WHEEL		0x08
 #define REL_MISC		0x09
 #define REL_MAX			0x0f
+#define REL_CNT			(REL_MAX+1)
 
 /*
  * Absolute axes
@@ -615,6 +618,7 @@
 #define ABS_VOLUME		0x20
 #define ABS_MISC		0x28
 #define ABS_MAX			0x3f
+#define ABS_CNT			(ABS_MAX+1)
 
 /*
  * Switch events
@@ -625,6 +629,7 @@
 #define SW_HEADPHONE_INSERT	0x02  /* set = inserted */
 #define SW_RADIO		0x03  /* set = radio enabled */
 #define SW_MAX			0x0f
+#define SW_CNT			(SW_MAX+1)
 
 /*
  * Misc events
@@ -636,6 +641,7 @@
 #define MSC_RAW			0x03
 #define MSC_SCAN		0x04
 #define MSC_MAX			0x07
+#define MSC_CNT			(MSC_MAX+1)
 
 /*
  * LEDs
@@ -653,6 +659,7 @@
 #define LED_MAIL		0x09
 #define LED_CHARGING		0x0a
 #define LED_MAX			0x0f
+#define LED_CNT			(LED_MAX+1)
 
 /*
  * Autorepeat values
@@ -670,6 +677,7 @@
 #define SND_BELL		0x01
 #define SND_TONE		0x02
 #define SND_MAX			0x07
+#define SND_CNT			(SND_MAX+1)
 
 /*
  * IDs.
@@ -920,6 +928,7 @@
 #define FF_AUTOCENTER	0x61
 
 #define FF_MAX		0x7f
+#define FF_CNT		(FF_MAX+1)
 
 #ifdef __KERNEL__
 
@@ -932,10 +941,6 @@
 #include <linux/timer.h>
 #include <linux/mod_devicetable.h>
 
-#define NBITS(x) (((x)/BITS_PER_LONG)+1)
-#define BIT(x)	(1UL<<((x)%BITS_PER_LONG))
-#define LONG(x) ((x)/BITS_PER_LONG)
-
 /**
  * struct input_dev - represents an input device
  * @name: name of the device
@@ -1005,28 +1010,30 @@
  * @going_away: marks devices that are in a middle of unregistering and
  *	causes input_open_device*() fail with -ENODEV.
  * @dev: driver model's view of this device
+ * @cdev: union for struct device pointer
  * @h_list: list of input handles associated with the device. When
  *	accessing the list dev->mutex must be held
  * @node: used to place the device onto input_dev_list
  */
 struct input_dev {
-
+	/* private: */
 	void *private;	/* do not use */
+	/* public: */
 
 	const char *name;
 	const char *phys;
 	const char *uniq;
 	struct input_id id;
 
-	unsigned long evbit[NBITS(EV_MAX)];
-	unsigned long keybit[NBITS(KEY_MAX)];
-	unsigned long relbit[NBITS(REL_MAX)];
-	unsigned long absbit[NBITS(ABS_MAX)];
-	unsigned long mscbit[NBITS(MSC_MAX)];
-	unsigned long ledbit[NBITS(LED_MAX)];
-	unsigned long sndbit[NBITS(SND_MAX)];
-	unsigned long ffbit[NBITS(FF_MAX)];
-	unsigned long swbit[NBITS(SW_MAX)];
+	unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
+	unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
+	unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
+	unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
+	unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
+	unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
+	unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
+	unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
+	unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
 
 	unsigned int keycodemax;
 	unsigned int keycodesize;
@@ -1044,10 +1051,10 @@
 	int abs[ABS_MAX + 1];
 	int rep[REP_MAX + 1];
 
-	unsigned long key[NBITS(KEY_MAX)];
-	unsigned long led[NBITS(LED_MAX)];
-	unsigned long snd[NBITS(SND_MAX)];
-	unsigned long sw[NBITS(SW_MAX)];
+	unsigned long key[BITS_TO_LONGS(KEY_CNT)];
+	unsigned long led[BITS_TO_LONGS(LED_CNT)];
+	unsigned long snd[BITS_TO_LONGS(SND_CNT)];
+	unsigned long sw[BITS_TO_LONGS(SW_CNT)];
 
 	int absmax[ABS_MAX + 1];
 	int absmin[ABS_MAX + 1];
@@ -1291,7 +1298,7 @@
 	dev->absfuzz[axis] = fuzz;
 	dev->absflat[axis] = flat;
 
-	dev->absbit[LONG(axis)] |= BIT(axis);
+	dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
 }
 
 extern struct class input_class;
@@ -1332,7 +1339,7 @@
 
 	void *private;
 
-	unsigned long ffbit[NBITS(FF_MAX)];
+	unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
 
 	struct mutex mutex;
 
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index ee11183..408696e 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -89,6 +89,7 @@
 {
 	spinlock_t	lock;
 	int		deleted;
+	int		id;
 	key_t		key;
 	uid_t		uid;
 	gid_t		gid;
@@ -110,6 +111,8 @@
 	int		msg_ctlmax;
 	int		msg_ctlmnb;
 	int		msg_ctlmni;
+	atomic_t	msg_bytes;
+	atomic_t	msg_hdrs;
 
 	size_t		shm_ctlmax;
 	size_t		shm_ctlall;
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index 7a9db390..c5bd28b 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -365,6 +365,16 @@
 			     int                  priority);
 
 /*
+ * Poll the IPMI interface for the user.  This causes the IPMI code to
+ * do an immediate check for information from the driver and handle
+ * anything that is immediately pending.  This will not block in any
+ * way.  This is useful if you need to implement polling from the user
+ * for things like modifying the watchdog timeout when a panic occurs
+ * or disabling the watchdog timer on a reboot.
+ */
+void ipmi_poll_interface(ipmi_user_t user);
+
+/*
  * When commands come in to the SMS, the user can register to receive
  * them.  Only one user can be listening on a specific netfn/cmd/chan tuple
  * at a time, you will get an EBUSY error if the command is already
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h
index c063310..56ae438 100644
--- a/include/linux/ipmi_smi.h
+++ b/include/linux/ipmi_smi.h
@@ -118,7 +118,7 @@
 	/* Enable/disable firmware maintenance mode.  Note that this
 	   is *not* the modes defined, this is simply an on/off
 	   setting.  The message handler does the mode handling.  Note
-	   that this is called from interupt context, so it cannot
+	   that this is called from interrupt context, so it cannot
 	   block. */
 	void (*set_maintenance_mode)(void *send_info, int enable);
 
@@ -148,26 +148,46 @@
 
 /* Take a pointer to a raw data buffer and a length and extract device
    id information from it.  The first byte of data must point to the
-   byte from the get device id response after the completion code.
-   The caller is responsible for making sure the length is at least
-   11 and the command completed without error. */
-static inline void ipmi_demangle_device_id(unsigned char *data,
-					   unsigned int  data_len,
-					   struct ipmi_device_id *id)
+   netfn << 2, the data should be of the format:
+      netfn << 2, cmd, completion code, data
+   as normally comes from a device interface. */
+static inline int ipmi_demangle_device_id(const unsigned char *data,
+					  unsigned int data_len,
+					  struct ipmi_device_id *id)
 {
+	if (data_len < 9)
+		return -EINVAL;
+	if (data[0] != IPMI_NETFN_APP_RESPONSE << 2 ||
+	    data[1] != IPMI_GET_DEVICE_ID_CMD)
+		/* Strange, didn't get the response we expected. */
+		return -EINVAL;
+	if (data[2] != 0)
+		/* That's odd, it shouldn't be able to fail. */
+		return -EINVAL;
+
+	data += 3;
+	data_len -= 3;
 	id->device_id = data[0];
 	id->device_revision = data[1];
 	id->firmware_revision_1 = data[2];
 	id->firmware_revision_2 = data[3];
 	id->ipmi_version = data[4];
 	id->additional_device_support = data[5];
-	id->manufacturer_id = data[6] | (data[7] << 8) | (data[8] << 16);
-	id->product_id = data[9] | (data[10] << 8);
+	if (data_len >= 6) {
+		id->manufacturer_id = (data[6] | (data[7] << 8) |
+				       (data[8] << 16));
+		id->product_id = data[9] | (data[10] << 8);
+	} else {
+		id->manufacturer_id = 0;
+		id->product_id = 0;
+	}
 	if (data_len >= 15) {
 		memcpy(id->aux_firmware_revision, data+11, 4);
 		id->aux_firmware_revision_set = 1;
 	} else
 		id->aux_firmware_revision_set = 0;
+
+	return 0;
 }
 
 /* Add a low-level interface to the IPMI driver.  Note that if the
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 72f5223..16e7ed8 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -58,7 +58,7 @@
  * CONFIG_JBD_DEBUG is on.
  */
 #define JBD_EXPENSIVE_CHECKING
-extern int journal_enable_debug;
+extern u8 journal_enable_debug;
 
 #define jbd_debug(n, f, a...)						\
 	do {								\
@@ -72,14 +72,15 @@
 #define jbd_debug(f, a...)	/**/
 #endif
 
-extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
-extern void * jbd_slab_alloc(size_t size, gfp_t flags);
-extern void jbd_slab_free(void *ptr, size_t size);
+static inline void *jbd_alloc(size_t size, gfp_t flags)
+{
+	return (void *)__get_free_pages(flags, get_order(size));
+}
 
-#define jbd_kmalloc(size, flags) \
-	__jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
-#define jbd_rep_kmalloc(size, flags) \
-	__jbd_kmalloc(__FUNCTION__, (size), (flags), 1)
+static inline void jbd_free(void *ptr, size_t size)
+{
+	free_pages((unsigned long)ptr, get_order(size));
+};
 
 #define JFS_MIN_JOURNAL_BLOCKS 1024
 
@@ -247,17 +248,7 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 
-#define JBD_ASSERTIONS
-#ifdef JBD_ASSERTIONS
-#define J_ASSERT(assert)						\
-do {									\
-	if (!(assert)) {						\
-		printk (KERN_EMERG					\
-			"Assertion failure in %s() at %s:%d: \"%s\"\n",	\
-			__FUNCTION__, __FILE__, __LINE__, # assert);	\
-		BUG();							\
-	}								\
-} while (0)
+#define J_ASSERT(assert)	BUG_ON(!(assert))
 
 #if defined(CONFIG_BUFFER_DEBUG)
 void buffer_assertion_failure(struct buffer_head *bh);
@@ -273,10 +264,6 @@
 #define J_ASSERT_JH(jh, expr)	J_ASSERT(expr)
 #endif
 
-#else
-#define J_ASSERT(assert)	do { } while (0)
-#endif		/* JBD_ASSERTIONS */
-
 #if defined(JBD_PARANOID_IOFAIL)
 #define J_EXPECT(expr, why...)		J_ASSERT(expr)
 #define J_EXPECT_BH(bh, expr, why...)	J_ASSERT_BH(bh, expr)
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 260d6d7..06ef114 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -13,8 +13,8 @@
  * filesystem journaling support.
  */
 
-#ifndef _LINUX_JBD_H
-#define _LINUX_JBD_H
+#ifndef _LINUX_JBD2_H
+#define _LINUX_JBD2_H
 
 /* Allow this file to be included directly into e2fsprogs */
 #ifndef __KERNEL__
@@ -37,26 +37,26 @@
 #define journal_oom_retry 1
 
 /*
- * Define JBD_PARANIOD_IOFAIL to cause a kernel BUG() if ext3 finds
+ * Define JBD2_PARANIOD_IOFAIL to cause a kernel BUG() if ext4 finds
  * certain classes of error which can occur due to failed IOs.  Under
- * normal use we want ext3 to continue after such errors, because
+ * normal use we want ext4 to continue after such errors, because
  * hardware _can_ fail, but for debugging purposes when running tests on
  * known-good hardware we may want to trap these errors.
  */
-#undef JBD_PARANOID_IOFAIL
+#undef JBD2_PARANOID_IOFAIL
 
 /*
  * The default maximum commit age, in seconds.
  */
-#define JBD_DEFAULT_MAX_COMMIT_AGE 5
+#define JBD2_DEFAULT_MAX_COMMIT_AGE 5
 
 #ifdef CONFIG_JBD2_DEBUG
 /*
- * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal
+ * Define JBD2_EXPENSIVE_CHECKING to enable more expensive internal
  * consistency checks.  By default we don't do this unless
  * CONFIG_JBD2_DEBUG is on.
  */
-#define JBD_EXPENSIVE_CHECKING
+#define JBD2_EXPENSIVE_CHECKING
 extern u8 jbd2_journal_enable_debug;
 
 #define jbd_debug(n, f, a...)						\
@@ -71,14 +71,15 @@
 #define jbd_debug(f, a...)	/**/
 #endif
 
-extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
-extern void * jbd2_slab_alloc(size_t size, gfp_t flags);
-extern void jbd2_slab_free(void *ptr, size_t size);
+static inline void *jbd2_alloc(size_t size, gfp_t flags)
+{
+	return (void *)__get_free_pages(flags, get_order(size));
+}
 
-#define jbd_kmalloc(size, flags) \
-	__jbd2_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
-#define jbd_rep_kmalloc(size, flags) \
-	__jbd2_kmalloc(__FUNCTION__, (size), (flags), 1)
+static inline void jbd2_free(void *ptr, size_t size)
+{
+	free_pages((unsigned long)ptr, get_order(size));
+};
 
 #define JBD2_MIN_JOURNAL_BLOCKS 1024
 
@@ -162,8 +163,8 @@
 	__be32		t_blocknr_high; /* most-significant high 32bits. */
 } journal_block_tag_t;
 
-#define JBD_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high))
-#define JBD_TAG_SIZE64 (sizeof(journal_block_tag_t))
+#define JBD2_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high))
+#define JBD2_TAG_SIZE64 (sizeof(journal_block_tag_t))
 
 /*
  * The revoke descriptor: used on disk to describe a series of blocks to
@@ -255,8 +256,8 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 
-#define JBD_ASSERTIONS
-#ifdef JBD_ASSERTIONS
+#define JBD2_ASSERTIONS
+#ifdef JBD2_ASSERTIONS
 #define J_ASSERT(assert)						\
 do {									\
 	if (!(assert)) {						\
@@ -283,9 +284,9 @@
 
 #else
 #define J_ASSERT(assert)	do { } while (0)
-#endif		/* JBD_ASSERTIONS */
+#endif		/* JBD2_ASSERTIONS */
 
-#if defined(JBD_PARANOID_IOFAIL)
+#if defined(JBD2_PARANOID_IOFAIL)
 #define J_EXPECT(expr, why...)		J_ASSERT(expr)
 #define J_EXPECT_BH(bh, expr, why...)	J_ASSERT_BH(bh, expr)
 #define J_EXPECT_JH(jh, expr, why...)	J_ASSERT_JH(jh, expr)
@@ -959,12 +960,12 @@
  */
 extern struct kmem_cache *jbd2_handle_cache;
 
-static inline handle_t *jbd_alloc_handle(gfp_t gfp_flags)
+static inline handle_t *jbd2_alloc_handle(gfp_t gfp_flags)
 {
 	return kmem_cache_alloc(jbd2_handle_cache, gfp_flags);
 }
 
-static inline void jbd_free_handle(handle_t *handle)
+static inline void jbd2_free_handle(handle_t *handle)
 {
 	kmem_cache_free(jbd2_handle_cache, handle);
 }
@@ -1103,4 +1104,4 @@
 
 #endif	/* __KERNEL__ */
 
-#endif	/* _LINUX_JBD_H */
+#endif	/* _LINUX_JBD2_H */
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 12bf44f..e8ffce8 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -53,7 +53,9 @@
 }
 
 extern void account_user_time(struct task_struct *, cputime_t);
+extern void account_user_time_scaled(struct task_struct *, cputime_t);
 extern void account_system_time(struct task_struct *, int, cputime_t);
+extern void account_system_time_scaled(struct task_struct *, cputime_t);
 extern void account_steal_time(struct task_struct *, cputime_t);
 
 #endif /* _LINUX_KERNEL_STAT_H */
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index ad4b82c..2d9c448 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -187,6 +187,8 @@
 extern size_t vmcoreinfo_size;
 extern size_t vmcoreinfo_max_size;
 
+int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
+		unsigned long long *crash_size, unsigned long long *crash_base);
 
 #else /* !CONFIG_KEXEC */
 struct pt_regs;
diff --git a/include/linux/keyboard.h b/include/linux/keyboard.h
index 33b5c2e..65c2d70 100644
--- a/include/linux/keyboard.h
+++ b/include/linux/keyboard.h
@@ -23,10 +23,21 @@
 #define MAX_NR_OF_USER_KEYMAPS 256 	/* should be at least 7 */
 
 #ifdef __KERNEL__
+struct notifier_block;
 extern const int NR_TYPES;
 extern const int max_vals[];
 extern unsigned short *key_maps[MAX_NR_KEYMAPS];
 extern unsigned short plain_map[NR_KEYS];
+
+struct keyboard_notifier_param {
+	struct vc_data *vc;	/* VC on which the keyboard press was done */
+	int down;		/* Pressure of the key? */
+	int shift;		/* Current shift mask */
+	unsigned int value;	/* keycode, unicode value or keysym */
+};
+
+extern int register_keyboard_notifier(struct notifier_block *nb);
+extern int unregister_keyboard_notifier(struct notifier_block *nb);
 #endif
 
 #define MAX_NR_FUNC	256	/* max nr of strings assigned to keys */
diff --git a/include/linux/lguest.h b/include/linux/lguest.h
index 157ad64..8beb291 100644
--- a/include/linux/lguest.h
+++ b/include/linux/lguest.h
@@ -1,76 +1,16 @@
 /* Things the lguest guest needs to know.  Note: like all lguest interfaces,
  * this is subject to wild and random change between versions. */
-#ifndef _ASM_LGUEST_H
-#define _ASM_LGUEST_H
+#ifndef _LINUX_LGUEST_H
+#define _LINUX_LGUEST_H
 
 #ifndef __ASSEMBLY__
+#include <linux/time.h>
 #include <asm/irq.h>
-
-#define LHCALL_FLUSH_ASYNC	0
-#define LHCALL_LGUEST_INIT	1
-#define LHCALL_CRASH		2
-#define LHCALL_LOAD_GDT		3
-#define LHCALL_NEW_PGTABLE	4
-#define LHCALL_FLUSH_TLB	5
-#define LHCALL_LOAD_IDT_ENTRY	6
-#define LHCALL_SET_STACK	7
-#define LHCALL_TS		8
-#define LHCALL_SET_CLOCKEVENT	9
-#define LHCALL_HALT		10
-#define LHCALL_BIND_DMA		12
-#define LHCALL_SEND_DMA		13
-#define LHCALL_SET_PTE		14
-#define LHCALL_SET_PMD		15
-#define LHCALL_LOAD_TLS		16
+#include <asm/lguest_hcall.h>
 
 #define LG_CLOCK_MIN_DELTA	100UL
 #define LG_CLOCK_MAX_DELTA	ULONG_MAX
 
-/*G:031 First, how does our Guest contact the Host to ask for privileged
- * operations?  There are two ways: the direct way is to make a "hypercall",
- * to make requests of the Host Itself.
- *
- * Our hypercall mechanism uses the highest unused trap code (traps 32 and
- * above are used by real hardware interrupts).  Seventeen hypercalls are
- * available: the hypercall number is put in the %eax register, and the
- * arguments (when required) are placed in %edx, %ebx and %ecx.  If a return
- * value makes sense, it's returned in %eax.
- *
- * Grossly invalid calls result in Sudden Death at the hands of the vengeful
- * Host, rather than returning failure.  This reflects Winston Churchill's
- * definition of a gentleman: "someone who is only rude intentionally". */
-#define LGUEST_TRAP_ENTRY 0x1F
-
-static inline unsigned long
-hcall(unsigned long call,
-      unsigned long arg1, unsigned long arg2, unsigned long arg3)
-{
-	/* "int" is the Intel instruction to trigger a trap. */
-	asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
-		       /* The call is in %eax (aka "a"), and can be replaced */
-		     : "=a"(call)
-		       /* The other arguments are in %eax, %edx, %ebx & %ecx */
-		     : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3)
-		       /* "memory" means this might write somewhere in memory.
-			* This isn't true for all calls, but it's safe to tell
-			* gcc that it might happen so it doesn't get clever. */
-		     : "memory");
-	return call;
-}
-/*:*/
-
-void async_hcall(unsigned long call,
-		 unsigned long arg1, unsigned long arg2, unsigned long arg3);
-
-/* Can't use our min() macro here: needs to be a constant */
-#define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32)
-
-#define LHCALL_RING_SIZE 64
-struct hcall_ring
-{
-	u32 eax, edx, ebx, ecx;
-};
-
 /*G:032 The second method of communicating with the Host is to via "struct
  * lguest_data".  The Guest's very first hypercall is to tell the Host where
  * this is, and then the Guest and Host both publish information in it. :*/
@@ -97,20 +37,24 @@
 	/* 0xFF == done (set by Host), 0 == pending (set by Guest). */
 	u8 hcall_status[LHCALL_RING_SIZE];
 	/* The actual registers for the hypercalls. */
-	struct hcall_ring hcalls[LHCALL_RING_SIZE];
+	struct hcall_args hcalls[LHCALL_RING_SIZE];
 
 /* Fields initialized by the Host at boot: */
 	/* Memory not to try to access */
 	unsigned long reserve_mem;
-	/* ID of this Guest (used by network driver to set ethernet address) */
-	u16 guestid;
 	/* KHz for the TSC clock. */
 	u32 tsc_khz;
+	/* Page where the top-level pagetable is */
+	unsigned long pgdir;
 
 /* Fields initialized by the Guest at boot: */
 	/* Instruction range to suppress interrupts even if enabled */
 	unsigned long noirq_start, noirq_end;
+	/* Address above which page tables are all identical. */
+	unsigned long kernel_address;
+	/* The vector to try to use for system calls (0x40 or 0x80). */
+	unsigned int syscall_vec;
 };
 extern struct lguest_data lguest_data;
 #endif /* __ASSEMBLY__ */
-#endif	/* _ASM_LGUEST_H */
+#endif	/* _LINUX_LGUEST_H */
diff --git a/include/linux/lguest_bus.h b/include/linux/lguest_bus.h
deleted file mode 100644
index d27853d..0000000
--- a/include/linux/lguest_bus.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _ASM_LGUEST_DEVICE_H
-#define _ASM_LGUEST_DEVICE_H
-/* Everything you need to know about lguest devices. */
-#include <linux/device.h>
-#include <linux/lguest.h>
-#include <linux/lguest_launcher.h>
-
-struct lguest_device {
-	/* Unique busid, and index into lguest_page->devices[] */
-	unsigned int index;
-
-	struct device dev;
-
-	/* Driver can hang data off here. */
-	void *private;
-};
-
-/*D:380 Since interrupt numbers are arbitrary, we use a convention: each device
- * can use the interrupt number corresponding to its index.  The +1 is because
- * interrupt 0 is not usable (it's actually the timer interrupt). */
-static inline int lgdev_irq(const struct lguest_device *dev)
-{
-	return dev->index + 1;
-}
-/*:*/
-
-/* dma args must not be vmalloced! */
-void lguest_send_dma(unsigned long key, struct lguest_dma *dma);
-int lguest_bind_dma(unsigned long key, struct lguest_dma *dmas,
-		    unsigned int num, u8 irq);
-void lguest_unbind_dma(unsigned long key, struct lguest_dma *dmas);
-
-/* Map the virtual device space */
-void *lguest_map(unsigned long phys_addr, unsigned long pages);
-void lguest_unmap(void *);
-
-struct lguest_driver {
-	const char *name;
-	struct module *owner;
-	u16 device_type;
-	int (*probe)(struct lguest_device *dev);
-	void (*remove)(struct lguest_device *dev);
-
-	struct device_driver drv;
-};
-
-extern int register_lguest_driver(struct lguest_driver *drv);
-extern void unregister_lguest_driver(struct lguest_driver *drv);
-
-extern struct lguest_device_desc *lguest_devices; /* Just past max_pfn */
-#endif /* _ASM_LGUEST_DEVICE_H */
diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h
index 6416705..61e1e3e 100644
--- a/include/linux/lguest_launcher.h
+++ b/include/linux/lguest_launcher.h
@@ -1,6 +1,7 @@
 #ifndef _ASM_LGUEST_USER
 #define _ASM_LGUEST_USER
 /* Everything the "lguest" userspace program needs to know. */
+#include <linux/types.h>
 /* They can register up to 32 arrays of lguest_dma. */
 #define LGUEST_MAX_DMA		32
 /* At most we can dma 16 lguest_dma in one op. */
@@ -9,66 +10,6 @@
 /* How many devices?  Assume each one wants up to two dma arrays per device. */
 #define LGUEST_MAX_DEVICES (LGUEST_MAX_DMA/2)
 
-/*D:200
- * Lguest I/O
- *
- * The lguest I/O mechanism is the only way Guests can talk to devices.  There
- * are two hypercalls involved: SEND_DMA for output and BIND_DMA for input.  In
- * each case, "struct lguest_dma" describes the buffer: this contains 16
- * addr/len pairs, and if there are fewer buffer elements the len array is
- * terminated with a 0.
- *
- * I/O is organized by keys: BIND_DMA attaches buffers to a particular key, and
- * SEND_DMA transfers to buffers bound to particular key.  By convention, keys
- * correspond to a physical address within the device's page.  This means that
- * devices will never accidentally end up with the same keys, and allows the
- * Host use The Futex Trick (as we'll see later in our journey).
- *
- * SEND_DMA simply indicates a key to send to, and the physical address of the
- * "struct lguest_dma" to send.  The Host will write the number of bytes
- * transferred into the "struct lguest_dma"'s used_len member.
- *
- * BIND_DMA indicates a key to bind to, a pointer to an array of "struct
- * lguest_dma"s ready for receiving, the size of that array, and an interrupt
- * to trigger when data is received.  The Host will only allow transfers into
- * buffers with a used_len of zero: it then sets used_len to the number of
- * bytes transferred and triggers the interrupt for the Guest to process the
- * new input. */
-struct lguest_dma
-{
-	/* 0 if free to be used, filled by the Host. */
- 	u32 used_len;
-	unsigned long addr[LGUEST_MAX_DMA_SECTIONS];
-	u16 len[LGUEST_MAX_DMA_SECTIONS];
-};
-/*:*/
-
-/*D:460 This is the layout of a block device memory page.  The Launcher sets up
- * the num_sectors initially to tell the Guest the size of the disk.  The Guest
- * puts the type, sector and length of the request in the first three fields,
- * then DMAs to the Host.  The Host processes the request, sets up the result,
- * then DMAs back to the Guest. */
-struct lguest_block_page
-{
-	/* 0 is a read, 1 is a write. */
-	int type;
-	u32 sector; 	/* Offset in device = sector * 512. */
-	u32 bytes;	/* Length expected to be read/written in bytes */
-	/* 0 = pending, 1 = done, 2 = done, error */
-	int result;
-	u32 num_sectors; /* Disk length = num_sectors * 512 */
-};
-
-/*D:520 The network device is basically a memory page where all the Guests on
- * the network publish their MAC (ethernet) addresses: it's an array of "struct
- * lguest_net": */
-struct lguest_net
-{
-	/* Simply the mac address (with multicast bit meaning promisc). */
-	unsigned char mac[6];
-};
-/*:*/
-
 /* Where the Host expects the Guest to SEND_DMA console output to. */
 #define LGUEST_CONSOLE_DMA_KEY 0
 
@@ -81,38 +22,29 @@
  * complex burden for the Host and suboptimal for the Guest, so we have our own
  * "lguest" bus and simple drivers.
  *
- * Devices are described by an array of LGUEST_MAX_DEVICES of these structs,
- * placed by the Launcher just above the top of physical memory:
+ * Devices are described by a simplified ID, a status byte, and some "config"
+ * bytes which describe this device's configuration.  This is placed by the
+ * Launcher just above the top of physical memory:
  */
 struct lguest_device_desc {
-	/* The device type: console, network, disk etc. */
-	u16 type;
-#define LGUEST_DEVICE_T_CONSOLE	1
-#define LGUEST_DEVICE_T_NET	2
-#define LGUEST_DEVICE_T_BLOCK	3
+	/* The device type: console, network, disk etc.  Type 0 terminates. */
+	__u8 type;
+	/* The number of bytes of the config array. */
+	__u8 config_len;
+	/* A status byte, written by the Guest. */
+	__u8 status;
+	__u8 config[0];
+};
 
-	/* The specific features of this device: these depends on device type
-	 * except for LGUEST_DEVICE_F_RANDOMNESS. */
-	u16 features;
-#define LGUEST_NET_F_NOCSUM		0x4000 /* Don't bother checksumming */
-#define LGUEST_DEVICE_F_RANDOMNESS	0x8000 /* IRQ is fairly random */
-
-	/* This is how the Guest reports status of the device: the Host can set
-	 * LGUEST_DEVICE_S_REMOVED to indicate removal, but the rest are only
-	 * ever manipulated by the Guest, and only ever set. */
-	u16 status;
-/* 256 and above are device specific. */
-#define LGUEST_DEVICE_S_ACKNOWLEDGE	1 /* We have seen device. */
-#define LGUEST_DEVICE_S_DRIVER		2 /* We have found a driver */
-#define LGUEST_DEVICE_S_DRIVER_OK	4 /* Driver says OK! */
-#define LGUEST_DEVICE_S_REMOVED		8 /* Device has gone away. */
-#define LGUEST_DEVICE_S_REMOVED_ACK	16 /* Driver has been told. */
-#define LGUEST_DEVICE_S_FAILED		128 /* Something actually failed */
-
-	/* Each device exists somewhere in Guest physical memory, over some
-	 * number of pages. */
-	u16 num_pages;
-	u32 pfn;
+/*D:135 This is how we expect the device configuration field for a virtqueue
+ * (type VIRTIO_CONFIG_F_VIRTQUEUE) to be laid out: */
+struct lguest_vqconfig {
+	/* The number of entries in the virtio_ring */
+	__u16 num;
+	/* The interrupt we get when something happens. */
+	__u16 irq;
+	/* The page number of the virtio ring for this device. */
+	__u32 pfn;
 };
 /*:*/
 
@@ -120,7 +52,7 @@
 enum lguest_req
 {
 	LHREQ_INITIALIZE, /* + pfnlimit, pgdir, start, pageoffset */
-	LHREQ_GETDMA, /* + addr (returns &lguest_dma, irq in ->used_len) */
+	LHREQ_GETDMA, /* No longer used */
 	LHREQ_IRQ, /* + irq */
 	LHREQ_BREAK, /* + on/off flag (on blocks until someone does off) */
 };
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 377e6d4..bc3b6fc 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1037,18 +1037,6 @@
 /*
  * qc helpers
  */
-static inline int
-ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
-{
-	if (sg == &qc->pad_sgent)
-		return 1;
-	if (qc->pad_len)
-		return 0;
-	if (qc->n_iter == qc->n_elem)
-		return 1;
-	return 0;
-}
-
 static inline struct scatterlist *
 ata_qc_first_sg(struct ata_queued_cmd *qc)
 {
diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index 6c9873f..ff203dd 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -34,6 +34,12 @@
   name:
 #endif
 
+#ifndef WEAK
+#define WEAK(name)	   \
+	.weak name;	   \
+	name:
+#endif
+
 #define KPROBE_ENTRY(name) \
   .pushsection .kprobes.text, "ax"; \
   ENTRY(name)
diff --git a/include/linux/list.h b/include/linux/list.h
index b0cf0135..75ce2cb 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -478,8 +478,7 @@
 		pos = n, n = pos->next)
 
 /**
- * list_for_each_prev_safe - iterate over a list backwards safe against removal
-			of list entry
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
  * @pos:	the &struct list_head to use as a loop cursor.
  * @n:		another &struct list_head to use as temporary storage
  * @head:	the head for your list.
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index f6279f6..4c4d236 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -276,6 +276,14 @@
 				 (lock)->dep_map.key, sub)
 
 /*
+ * To initialize a lockdep_map statically use this macro.
+ * Note that _name must not be NULL.
+ */
+#define STATIC_LOCKDEP_MAP_INIT(_name, _key) \
+	{ .name = (_name), .key = (void *)(_key), }
+
+
+/*
  * Acquire a lock.
  *
  * Values for "read":
diff --git a/include/linux/magic.h b/include/linux/magic.h
index 722d475..1fa0c2c 100644
--- a/include/linux/magic.h
+++ b/include/linux/magic.h
@@ -37,6 +37,7 @@
 
 #define SMB_SUPER_MAGIC		0x517B
 #define USBDEVICE_SUPER_MAGIC	0x9fa2
+#define CGROUP_SUPER_MAGIC	0x27e0eb
 
 #define FUTEXFS_SUPER_MAGIC	0xBAD1DEA
 #define INOTIFYFS_SUPER_MAGIC	0x2BAD1DEA
diff --git a/include/linux/marker.h b/include/linux/marker.h
new file mode 100644
index 0000000..5f36cf9
--- /dev/null
+++ b/include/linux/marker.h
@@ -0,0 +1,129 @@
+#ifndef _LINUX_MARKER_H
+#define _LINUX_MARKER_H
+
+/*
+ * Code markup for dynamic and static tracing.
+ *
+ * See Documentation/marker.txt.
+ *
+ * (C) Copyright 2006 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/types.h>
+
+struct module;
+struct marker;
+
+/**
+ * marker_probe_func - Type of a marker probe function
+ * @mdata: pointer of type struct marker
+ * @private_data: caller site private data
+ * @fmt: format string
+ * @...: variable argument list
+ *
+ * Type of marker probe functions. They receive the mdata and need to parse the
+ * format string to recover the variable argument list.
+ */
+typedef void marker_probe_func(const struct marker *mdata,
+	void *private_data, const char *fmt, ...);
+
+struct marker {
+	const char *name;	/* Marker name */
+	const char *format;	/* Marker format string, describing the
+				 * variable argument list.
+				 */
+	char state;		/* Marker state. */
+	marker_probe_func *call;/* Probe handler function pointer */
+	void *private;		/* Private probe data */
+} __attribute__((aligned(8)));
+
+#ifdef CONFIG_MARKERS
+
+/*
+ * Note : the empty asm volatile with read constraint is used here instead of a
+ * "used" attribute to fix a gcc 4.1.x bug.
+ * Make sure the alignment of the structure in the __markers section will
+ * not add unwanted padding between the beginning of the section and the
+ * structure. Force alignment to the same alignment as the section start.
+ */
+#define __trace_mark(name, call_data, format, args...)			\
+	do {								\
+		static const char __mstrtab_name_##name[]		\
+		__attribute__((section("__markers_strings")))		\
+		= #name;						\
+		static const char __mstrtab_format_##name[]		\
+		__attribute__((section("__markers_strings")))		\
+		= format;						\
+		static struct marker __mark_##name			\
+		__attribute__((section("__markers"), aligned(8))) =	\
+		{ __mstrtab_name_##name, __mstrtab_format_##name,	\
+		0, __mark_empty_function, NULL };			\
+		__mark_check_format(format, ## args);			\
+		if (unlikely(__mark_##name.state)) {			\
+			preempt_disable();				\
+			(*__mark_##name.call)				\
+				(&__mark_##name, call_data,		\
+				format, ## args);			\
+			preempt_enable();				\
+		}							\
+	} while (0)
+
+extern void marker_update_probe_range(struct marker *begin,
+	struct marker *end, struct module *probe_module, int *refcount);
+#else /* !CONFIG_MARKERS */
+#define __trace_mark(name, call_data, format, args...) \
+		__mark_check_format(format, ## args)
+static inline void marker_update_probe_range(struct marker *begin,
+	struct marker *end, struct module *probe_module, int *refcount)
+{ }
+#endif /* CONFIG_MARKERS */
+
+/**
+ * trace_mark - Marker
+ * @name: marker name, not quoted.
+ * @format: format string
+ * @args...: variable argument list
+ *
+ * Places a marker.
+ */
+#define trace_mark(name, format, args...) \
+	__trace_mark(name, NULL, format, ## args)
+
+#define MARK_MAX_FORMAT_LEN	1024
+
+/**
+ * MARK_NOARGS - Format string for a marker with no argument.
+ */
+#define MARK_NOARGS " "
+
+/* To be used for string format validity checking with gcc */
+static inline void __printf(1, 2) __mark_check_format(const char *fmt, ...)
+{
+}
+
+extern marker_probe_func __mark_empty_function;
+
+/*
+ * Connect a probe to a marker.
+ * private data pointer must be a valid allocated memory address, or NULL.
+ */
+extern int marker_probe_register(const char *name, const char *format,
+				marker_probe_func *probe, void *private);
+
+/*
+ * Returns the private data given to marker_probe_register.
+ */
+extern void *marker_probe_unregister(const char *name);
+/*
+ * Unregister a marker by providing the registered private data.
+ */
+extern void *marker_probe_unregister_private_data(void *private);
+
+extern int marker_arm(const char *name);
+extern int marker_disarm(const char *name);
+extern void *marker_get_private_data(const char *name);
+
+#endif
diff --git a/include/linux/memory.h b/include/linux/memory.h
index 654ef55..33f0ff0 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -41,18 +41,15 @@
 #define	MEM_ONLINE		(1<<0) /* exposed to userspace */
 #define	MEM_GOING_OFFLINE	(1<<1) /* exposed to userspace */
 #define	MEM_OFFLINE		(1<<2) /* exposed to userspace */
+#define	MEM_GOING_ONLINE	(1<<3)
+#define	MEM_CANCEL_ONLINE	(1<<4)
+#define	MEM_CANCEL_OFFLINE	(1<<5)
 
-/*
- * All of these states are currently kernel-internal for notifying
- * kernel components and architectures.
- *
- * For MEM_MAPPING_INVALID, all notifier chains with priority >0
- * are called before pfn_to_page() becomes invalid.  The priority=0
- * entry is reserved for the function that actually makes
- * pfn_to_page() stop working.  Any notifiers that want to be called
- * after that should have priority <0.
- */
-#define	MEM_MAPPING_INVALID	(1<<3)
+struct memory_notify {
+	unsigned long start_pfn;
+	unsigned long nr_pages;
+	int status_change_nid;
+};
 
 struct notifier_block;
 struct mem_section;
@@ -69,21 +66,31 @@
 static inline void unregister_memory_notifier(struct notifier_block *nb)
 {
 }
+static inline int memory_notify(unsigned long val, void *v)
+{
+	return 0;
+}
 #else
+extern int register_memory_notifier(struct notifier_block *nb);
+extern void unregister_memory_notifier(struct notifier_block *nb);
 extern int register_new_memory(struct mem_section *);
 extern int unregister_memory_section(struct mem_section *);
 extern int memory_dev_init(void);
 extern int remove_memory_block(unsigned long, struct mem_section *, int);
-
+extern int memory_notify(unsigned long val, void *v);
 #define CONFIG_MEM_BLOCK_SIZE	(PAGES_PER_SECTION<<PAGE_SHIFT)
 
 
 #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
 
+#ifdef CONFIG_MEMORY_HOTPLUG
 #define hotplug_memory_notifier(fn, pri) {			\
 	static struct notifier_block fn##_mem_nb =		\
 		{ .notifier_call = fn, .priority = pri };	\
 	register_memory_notifier(&fn##_mem_nb);			\
 }
+#else
+#define hotplug_memory_notifier(fn, pri) do { } while (0)
+#endif
 
 #endif /* _LINUX_MEMORY_H_ */
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 38c04d6..59c4865 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -148,14 +148,6 @@
 					const nodemask_t *new);
 extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new);
 extern void mpol_fix_fork_child_flag(struct task_struct *p);
-#define set_cpuset_being_rebound(x) (cpuset_being_rebound = (x))
-
-#ifdef CONFIG_CPUSETS
-#define current_cpuset_is_being_rebound() \
-				(cpuset_being_rebound == current->cpuset)
-#else
-#define current_cpuset_is_being_rebound() 0
-#endif
 
 extern struct mempolicy default_policy;
 extern struct zonelist *huge_zonelist(struct vm_area_struct *vma,
@@ -173,8 +165,6 @@
 int do_migrate_pages(struct mm_struct *mm,
 	const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags);
 
-extern void *cpuset_being_rebound;	/* Trigger mpol_copy vma rebind */
-
 #else
 
 struct mempolicy {};
@@ -248,8 +238,6 @@
 {
 }
 
-#define set_cpuset_being_rebound(x) do {} while (0)
-
 static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma,
  		unsigned long addr, gfp_t gfp_flags, struct mempolicy **mpol)
 {
diff --git a/include/linux/mlx4/doorbell.h b/include/linux/mlx4/doorbell.h
index 3f2da44..f31bba2 100644
--- a/include/linux/mlx4/doorbell.h
+++ b/include/linux/mlx4/doorbell.h
@@ -52,11 +52,6 @@
 #define MLX4_INIT_DOORBELL_LOCK(ptr)    do { } while (0)
 #define MLX4_GET_DOORBELL_LOCK(ptr)      (NULL)
 
-static inline void mlx4_write64_raw(__be64 val, void __iomem *dest)
-{
-	__raw_writeq((__force u64) val, dest);
-}
-
 static inline void mlx4_write64(__be32 val[2], void __iomem *dest,
 				spinlock_t *doorbell_lock)
 {
@@ -75,12 +70,6 @@
 #define MLX4_INIT_DOORBELL_LOCK(ptr)     spin_lock_init(ptr)
 #define MLX4_GET_DOORBELL_LOCK(ptr)      (ptr)
 
-static inline void mlx4_write64_raw(__be64 val, void __iomem *dest)
-{
-	__raw_writel(((__force u32 *) &val)[0], dest);
-	__raw_writel(((__force u32 *) &val)[1], dest + 4);
-}
-
 static inline void mlx4_write64(__be32 val[2], void __iomem *dest,
 				spinlock_t *doorbell_lock)
 {
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 522b0dd..e9fddb4 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -361,4 +361,10 @@
 #define SSB_ANY_ID		0xFFFF
 #define SSB_ANY_REV		0xFF
 
+struct virtio_device_id {
+	__u32 device;
+	__u32 vendor;
+};
+#define VIRTIO_DEV_ANY_ID	0xffffffff
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/module.h b/include/linux/module.h
index 642f325..2cbc0b8 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -15,6 +15,7 @@
 #include <linux/stringify.h>
 #include <linux/kobject.h>
 #include <linux/moduleparam.h>
+#include <linux/marker.h>
 #include <asm/local.h>
 
 #include <asm/module.h>
@@ -354,6 +355,10 @@
 	/* The command line arguments (may be mangled).  People like
 	   keeping pointers to this stuff */
 	char *args;
+#ifdef CONFIG_MARKERS
+	struct marker *markers;
+	unsigned int num_markers;
+#endif
 };
 #ifndef MODULE_ARCH_INIT
 #define MODULE_ARCH_INIT {}
@@ -457,6 +462,8 @@
 
 extern void print_modules(void);
 
+extern void module_update_markers(struct module *probe_module, int *refcount);
+
 #else /* !CONFIG_MODULES... */
 #define EXPORT_SYMBOL(sym)
 #define EXPORT_SYMBOL_GPL(sym)
@@ -556,6 +563,11 @@
 {
 }
 
+static inline void module_update_markers(struct module *probe_module,
+		int *refcount)
+{
+}
+
 #endif /* CONFIG_MODULES */
 
 struct device_driver;
diff --git a/include/linux/msg.h b/include/linux/msg.h
index f1b6074..10a3d5a 100644
--- a/include/linux/msg.h
+++ b/include/linux/msg.h
@@ -77,7 +77,6 @@
 /* one msq_queue structure for each present queue on the system */
 struct msg_queue {
 	struct kern_ipc_perm q_perm;
-	int q_id;
 	time_t q_stime;			/* last msgsnd time */
 	time_t q_rtime;			/* last msgrcv time */
 	time_t q_ctime;			/* last change time */
diff --git a/include/linux/net.h b/include/linux/net.h
index c136abc..dd79cdb 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -313,6 +313,10 @@
 #define MODULE_ALIAS_NET_PF_PROTO(pf, proto) \
 	MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto))
 
+#define MODULE_ALIAS_NET_PF_PROTO_TYPE(pf, proto, type) \
+	MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto) \
+		     "-type-" __stringify(type))
+
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
 extern ctl_table net_table[];
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 39dd83b..4a3f54e3 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -407,6 +407,24 @@
 	clear_bit(NAPI_STATE_SCHED, &n->state);
 }
 
+#ifdef CONFIG_SMP
+/**
+ *	napi_synchronize - wait until NAPI is not running
+ *	@n: napi context
+ *
+ * Wait until NAPI is done being scheduled on this context.
+ * Waits till any outstanding processing completes but
+ * does not disable future activations.
+ */
+static inline void napi_synchronize(const struct napi_struct *n)
+{
+	while (test_bit(NAPI_STATE_SCHED, &n->state))
+		msleep(1);
+}
+#else
+# define napi_synchronize(n)	barrier()
+#endif
+
 /*
  *	The DEVICE structure.
  *	Actually, this whole structure is a big mistake.  It mixes I/O
@@ -827,7 +845,7 @@
 {
 	const struct net_device *dev = skb->dev;
 
-	if (!dev->header_ops->parse)
+	if (!dev->header_ops || !dev->header_ops->parse)
 		return 0;
 	return dev->header_ops->parse(skb, haddr);
 }
@@ -978,7 +996,7 @@
  *
  * Check individual transmit queue of a device with multiple transmit queues.
  */
-static inline int netif_subqueue_stopped(const struct net_device *dev,
+static inline int __netif_subqueue_stopped(const struct net_device *dev,
 					 u16 queue_index)
 {
 #ifdef CONFIG_NETDEVICES_MULTIQUEUE
@@ -989,6 +1007,11 @@
 #endif
 }
 
+static inline int netif_subqueue_stopped(const struct net_device *dev,
+					 struct sk_buff *skb)
+{
+	return __netif_subqueue_stopped(dev, skb_get_queue_mapping(skb));
+}
 
 /**
  *	netif_wake_subqueue - allow sending packets on subqueue
diff --git a/include/linux/netfilter/xt_sctp.h b/include/linux/netfilter/xt_sctp.h
index b157897..dd5a4fd 100644
--- a/include/linux/netfilter/xt_sctp.h
+++ b/include/linux/netfilter/xt_sctp.h
@@ -7,9 +7,6 @@
 
 #define XT_SCTP_VALID_FLAGS		0x07
 
-#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
-
-
 struct xt_sctp_flag_info {
 	u_int8_t chunktype;
 	u_int8_t flag;
@@ -59,21 +56,21 @@
 #define SCTP_CHUNKMAP_RESET(chunkmap) 				\
 	do {							\
 		int i; 						\
-		for (i = 0; i < ELEMCOUNT(chunkmap); i++)	\
+		for (i = 0; i < ARRAY_SIZE(chunkmap); i++)	\
 			chunkmap[i] = 0;			\
 	} while (0)
 
 #define SCTP_CHUNKMAP_SET_ALL(chunkmap) 			\
 	do {							\
 		int i; 						\
-		for (i = 0; i < ELEMCOUNT(chunkmap); i++) 	\
+		for (i = 0; i < ARRAY_SIZE(chunkmap); i++) 	\
 			chunkmap[i] = ~0;			\
 	} while (0)
 
 #define SCTP_CHUNKMAP_COPY(destmap, srcmap) 			\
 	do {							\
 		int i; 						\
-		for (i = 0; i < ELEMCOUNT(chunkmap); i++) 	\
+		for (i = 0; i < ARRAY_SIZE(srcmap); i++) 	\
 			destmap[i] = srcmap[i];			\
 	} while (0)
 
@@ -81,7 +78,7 @@
 ({							\
 	int i; 						\
 	int flag = 1;					\
-	for (i = 0; i < ELEMCOUNT(chunkmap); i++) {	\
+	for (i = 0; i < ARRAY_SIZE(chunkmap); i++) {	\
 		if (chunkmap[i]) {			\
 			flag = 0;			\
 			break;				\
@@ -94,7 +91,7 @@
 ({							\
 	int i; 						\
 	int flag = 1;					\
-	for (i = 0; i < ELEMCOUNT(chunkmap); i++) {	\
+	for (i = 0; i < ARRAY_SIZE(chunkmap); i++) {	\
 		if (chunkmap[i] != ~0) {		\
 			flag = 0;			\
 				break;			\
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index c5164c2..e82a6eb 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -160,6 +160,12 @@
 	/* Open contexts for shared mmap writes */
 	struct list_head	open_files;
 
+	/* Number of in-flight sillydelete RPC calls */
+	atomic_t		silly_count;
+	/* List of deferred sillydelete requests */
+	struct hlist_head	silly_list;
+	wait_queue_head_t	waitqueue;
+
 #ifdef CONFIG_NFS_V4
 	struct nfs4_cached_acl	*nfs4_acl;
         /* NFSv4 state */
@@ -394,6 +400,8 @@
  */
 extern int  nfs_async_unlink(struct inode *dir, struct dentry *dentry);
 extern void nfs_complete_unlink(struct dentry *dentry, struct inode *);
+extern void nfs_block_sillyrename(struct dentry *dentry);
+extern void nfs_unblock_sillyrename(struct dentry *dentry);
 
 /*
  * linux/fs/nfs/write.c
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index fad7ff1..0c40cc0 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -231,5 +231,22 @@
 #define PM_SUSPEND_PREPARE	0x0003 /* Going to suspend the system */
 #define PM_POST_SUSPEND		0x0004 /* Suspend finished */
 
+/* Console keyboard events.
+ * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and
+ * KBD_KEYSYM. */
+#define KBD_KEYCODE		0x0001 /* Keyboard keycode, called before any other */
+#define KBD_UNBOUND_KEYCODE	0x0002 /* Keyboard keycode which is not bound to any other */
+#define KBD_UNICODE		0x0003 /* Keyboard unicode */
+#define KBD_KEYSYM		0x0004 /* Keyboard keysym */
+#define KBD_POST_KEYSYM		0x0005 /* Called after keyboard keysym interpretation */
+
+extern struct blocking_notifier_head reboot_notifier_list;
+
+/* Virtual Terminal events. */
+#define VT_ALLOCATE		0x0001 /* Console got allocated */
+#define VT_DEALLOCATE		0x0002 /* Console will be deallocated */
+#define VT_WRITE		0x0003 /* A char got output */
+#define VT_UPDATE		0x0004 /* A bigger update occurred */
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_NOTIFIER_H */
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index 033a648..0e66b57 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -32,8 +32,39 @@
 };
 extern struct nsproxy init_nsproxy;
 
+/*
+ * the namespaces access rules are:
+ *
+ *  1. only current task is allowed to change tsk->nsproxy pointer or
+ *     any pointer on the nsproxy itself
+ *
+ *  2. when accessing (i.e. reading) current task's namespaces - no
+ *     precautions should be taken - just dereference the pointers
+ *
+ *  3. the access to other task namespaces is performed like this
+ *     rcu_read_lock();
+ *     nsproxy = task_nsproxy(tsk);
+ *     if (nsproxy != NULL) {
+ *             / *
+ *               * work with the namespaces here
+ *               * e.g. get the reference on one of them
+ *               * /
+ *     } / *
+ *         * NULL task_nsproxy() means that this task is
+ *         * almost dead (zombie)
+ *         * /
+ *     rcu_read_unlock();
+ *
+ */
+
+static inline struct nsproxy *task_nsproxy(struct task_struct *tsk)
+{
+	return rcu_dereference(tsk->nsproxy);
+}
+
 int copy_namespaces(unsigned long flags, struct task_struct *tsk);
-void get_task_namespaces(struct task_struct *tsk);
+void exit_task_namespaces(struct task_struct *tsk);
+void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
 void free_nsproxy(struct nsproxy *ns);
 int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **,
 	struct fs_struct *);
@@ -45,14 +76,15 @@
 	}
 }
 
-static inline void exit_task_namespaces(struct task_struct *p)
+static inline void get_nsproxy(struct nsproxy *ns)
 {
-	struct nsproxy *ns = p->nsproxy;
-	if (ns) {
-		task_lock(p);
-		p->nsproxy = NULL;
-		task_unlock(p);
-		put_nsproxy(ns);
-	}
+	atomic_inc(&ns->count);
 }
+
+#ifdef CONFIG_CGROUP_NS
+int ns_cgroup_clone(struct task_struct *tsk);
+#else
+static inline int ns_cgroup_clone(struct task_struct *tsk) { return 0; }
+#endif
+
 #endif
diff --git a/include/linux/of.h b/include/linux/of.h
index 6df80e9..5c39b92 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -16,8 +16,8 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/types.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/prom.h>
 
 /* flag descriptions */
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index 448f70b..a8efcfe 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -48,6 +48,10 @@
 #define	to_of_platform_driver(drv) \
 	container_of(drv,struct of_platform_driver, driver)
 
+extern int of_register_driver(struct of_platform_driver *drv,
+			      struct bus_type *bus);
+extern void of_unregister_driver(struct of_platform_driver *drv);
+
 #include <asm/of_platform.h>
 
 extern struct of_device *of_find_device_by_node(struct device_node *np);
diff --git a/include/linux/parport.h b/include/linux/parport.h
index 9cdd694..ec3f765 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -510,7 +510,6 @@
 				       int flags, void *handle);
 extern void parport_close (struct pardevice *dev);
 extern ssize_t parport_device_id (int devnum, char *buffer, size_t len);
-extern int parport_device_num (int parport, int mux, int daisy);
 extern void parport_daisy_deselect_all (struct parport *port);
 extern int parport_daisy_select (struct parport *port, int daisy, int mode);
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 768b933..5d2281f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -141,6 +141,7 @@
 	unsigned int	class;		/* 3 bytes: (base,sub,prog-if) */
 	u8		revision;	/* PCI revision, low byte of class word */
 	u8		hdr_type;	/* PCI header type (`multi' flag masked out) */
+	u8		pcie_type;	/* PCI-E device/port type */
 	u8		rom_base_reg;	/* which config register controls the ROM */
 	u8		pin;  		/* which interrupt pin this device uses */
 
@@ -183,6 +184,7 @@
 	unsigned int 	msi_enabled:1;
 	unsigned int	msix_enabled:1;
 	unsigned int	is_managed:1;
+	unsigned int	is_pcie:1;
 	atomic_t	enable_cnt;	/* pci_enable_device has been called */
 
 	u32		saved_config_space[16]; /* config space saved at suspend time */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index df948b4..4e10a07 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1943,6 +1943,7 @@
 #define PCI_DEVICE_ID_TIGON3_5720	0x1658
 #define PCI_DEVICE_ID_TIGON3_5721	0x1659
 #define PCI_DEVICE_ID_TIGON3_5722	0x165a
+#define PCI_DEVICE_ID_TIGON3_5723	0x165b
 #define PCI_DEVICE_ID_TIGON3_5705M	0x165d
 #define PCI_DEVICE_ID_TIGON3_5705M_2	0x165e
 #define PCI_DEVICE_ID_TIGON3_5714	0x1668
diff --git a/include/linux/phantom.h b/include/linux/phantom.h
index d3ebbfa..96f4048 100644
--- a/include/linux/phantom.h
+++ b/include/linux/phantom.h
@@ -30,7 +30,11 @@
 #define PHN_SET_REG		_IOW (PH_IOC_MAGIC, 1, struct phm_reg *)
 #define PHN_GET_REGS		_IOWR(PH_IOC_MAGIC, 2, struct phm_regs *)
 #define PHN_SET_REGS		_IOW (PH_IOC_MAGIC, 3, struct phm_regs *)
-#define PH_IOC_MAXNR		3
+/* this ioctl tells the driver, that the caller is not OpenHaptics and might
+ * use improved registers update (no more phantom switchoffs when using
+ * libphantom) */
+#define PHN_NOT_OH		_IO  (PH_IOC_MAGIC, 4)
+#define PH_IOC_MAXNR		4
 
 #define PHN_CONTROL		0x6     /* control byte in iaddr space */
 #define PHN_CTL_AMP		0x1     /*   switch after torques change */
diff --git a/include/linux/pid.h b/include/linux/pid.h
index 1e0e4e3..e29a900 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -40,15 +40,28 @@
  * processes.
  */
 
+
+/*
+ * struct upid is used to get the id of the struct pid, as it is
+ * seen in particular namespace. Later the struct pid is found with
+ * find_pid_ns() using the int nr and struct pid_namespace *ns.
+ */
+
+struct upid {
+	/* Try to keep pid_chain in the same cacheline as nr for find_pid */
+	int nr;
+	struct pid_namespace *ns;
+	struct hlist_node pid_chain;
+};
+
 struct pid
 {
 	atomic_t count;
-	/* Try to keep pid_chain in the same cacheline as nr for find_pid */
-	int nr;
-	struct hlist_node pid_chain;
 	/* lists of tasks that use this pid */
 	struct hlist_head tasks[PIDTYPE_MAX];
 	struct rcu_head rcu;
+	int level;
+	struct upid numbers[1];
 };
 
 extern struct pid init_struct_pid;
@@ -83,26 +96,60 @@
 extern void FASTCALL(transfer_pid(struct task_struct *old,
 				  struct task_struct *new, enum pid_type));
 
+struct pid_namespace;
+extern struct pid_namespace init_pid_ns;
+
 /*
  * look up a PID in the hash table. Must be called with the tasklist_lock
  * or rcu_read_lock() held.
+ *
+ * find_pid_ns() finds the pid in the namespace specified
+ * find_pid() find the pid by its global id, i.e. in the init namespace
+ * find_vpid() finr the pid by its virtual id, i.e. in the current namespace
+ *
+ * see also find_task_by_pid() set in include/linux/sched.h
  */
-extern struct pid *FASTCALL(find_pid(int nr));
+extern struct pid *FASTCALL(find_pid_ns(int nr, struct pid_namespace *ns));
+extern struct pid *find_vpid(int nr);
+extern struct pid *find_pid(int nr);
 
 /*
  * Lookup a PID in the hash table, and return with it's count elevated.
  */
 extern struct pid *find_get_pid(int nr);
-extern struct pid *find_ge_pid(int nr);
+extern struct pid *find_ge_pid(int nr, struct pid_namespace *);
 
-extern struct pid *alloc_pid(void);
+extern struct pid *alloc_pid(struct pid_namespace *ns);
 extern void FASTCALL(free_pid(struct pid *pid));
+extern void zap_pid_ns_processes(struct pid_namespace *pid_ns);
+
+/*
+ * the helpers to get the pid's id seen from different namespaces
+ *
+ * pid_nr()    : global id, i.e. the id seen from the init namespace;
+ * pid_vnr()   : virtual id, i.e. the id seen from the namespace this pid
+ *               belongs to. this only makes sence when called in the
+ *               context of the task that belongs to the same namespace;
+ * pid_nr_ns() : id seen from the ns specified.
+ *
+ * see also task_xid_nr() etc in include/linux/sched.h
+ */
 
 static inline pid_t pid_nr(struct pid *pid)
 {
 	pid_t nr = 0;
 	if (pid)
-		nr = pid->nr;
+		nr = pid->numbers[0].nr;
+	return nr;
+}
+
+pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
+
+static inline pid_t pid_vnr(struct pid *pid)
+{
+	pid_t nr = 0;
+	if (pid)
+		nr = pid->numbers[pid->level].nr;
 	return nr;
 }
 
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index b9a17e0..0135c76 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -4,7 +4,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/threads.h>
-#include <linux/pid.h>
 #include <linux/nsproxy.h>
 #include <linux/kref.h>
 
@@ -20,13 +19,21 @@
 	struct pidmap pidmap[PIDMAP_ENTRIES];
 	int last_pid;
 	struct task_struct *child_reaper;
+	struct kmem_cache *pid_cachep;
+	int level;
+	struct pid_namespace *parent;
+#ifdef CONFIG_PROC_FS
+	struct vfsmount *proc_mnt;
+#endif
 };
 
 extern struct pid_namespace init_pid_ns;
 
-static inline void get_pid_ns(struct pid_namespace *ns)
+static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
 {
-	kref_get(&ns->kref);
+	if (ns != &init_pid_ns)
+		kref_get(&ns->kref);
+	return ns;
 }
 
 extern struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *ns);
@@ -34,12 +41,19 @@
 
 static inline void put_pid_ns(struct pid_namespace *ns)
 {
-	kref_put(&ns->kref, free_pid_ns);
+	if (ns != &init_pid_ns)
+		kref_put(&ns->kref, free_pid_ns);
 }
 
-static inline struct task_struct *child_reaper(struct task_struct *tsk)
+static inline struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
 {
-	return init_pid_ns.child_reaper;
+	return tsk->nsproxy->pid_ns;
+}
+
+static inline struct task_struct *task_child_reaper(struct task_struct *tsk)
+{
+	BUG_ON(tsk != current);
+	return tsk->nsproxy->pid_ns->child_reaper;
 }
 
 #endif /* _LINUX_PID_NS_H */
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 48b71ba..09a309b 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -104,104 +104,6 @@
 extern void (*pm_power_off)(void);
 extern void (*pm_power_off_prepare)(void);
 
-typedef int __bitwise suspend_state_t;
-
-#define PM_SUSPEND_ON		((__force suspend_state_t) 0)
-#define PM_SUSPEND_STANDBY	((__force suspend_state_t) 1)
-#define PM_SUSPEND_MEM		((__force suspend_state_t) 3)
-#define PM_SUSPEND_MAX		((__force suspend_state_t) 4)
-
-/**
- * struct pm_ops - Callbacks for managing platform dependent system sleep
- *	states.
- *
- * @valid: Callback to determine if given system sleep state is supported by
- *	the platform.
- *	Valid (ie. supported) states are advertised in /sys/power/state.  Note
- *	that it still may be impossible to enter given system sleep state if the
- *	conditions aren't right.
- *	There is the %pm_valid_only_mem function available that can be assigned
- *	to this if the platform only supports mem sleep.
- *
- * @set_target: Tell the platform which system sleep state is going to be
- *	entered.
- *	@set_target() is executed right prior to suspending devices.  The
- *	information conveyed to the platform code by @set_target() should be
- *	disregarded by the platform as soon as @finish() is executed and if
- *	@prepare() fails.  If @set_target() fails (ie. returns nonzero),
- *	@prepare(), @enter() and @finish() will not be called by the PM core.
- *	This callback is optional.  However, if it is implemented, the argument
- *	passed to @prepare(), @enter() and @finish() is meaningless and should
- *	be ignored.
- *
- * @prepare: Prepare the platform for entering the system sleep state indicated
- *	by @set_target() or represented by the argument if @set_target() is not
- *	implemented.
- *	@prepare() is called right after devices have been suspended (ie. the
- *	appropriate .suspend() method has been executed for each device) and
- *	before the nonboot CPUs are disabled (it is executed with IRQs enabled).
- *	This callback is optional.  It returns 0 on success or a negative
- *	error code otherwise, in which case the system cannot enter the desired
- *	sleep state (@enter() and @finish() will not be called in that case).
- *
- * @enter: Enter the system sleep state indicated by @set_target() or
- *	represented by the argument if @set_target() is not implemented.
- *	This callback is mandatory.  It returns 0 on success or a negative
- *	error code otherwise, in which case the system cannot enter the desired
- *	sleep state.
- *
- * @finish: Called when the system has just left a sleep state, right after
- *	the nonboot CPUs have been enabled and before devices are resumed (it is
- *	executed with IRQs enabled).  If @set_target() is not implemented, the
- *	argument represents the sleep state being left.
- *	This callback is optional, but should be implemented by the platforms
- *	that implement @prepare().  If implemented, it is always called after
- *	@enter() (even if @enter() fails).
- */
-struct pm_ops {
-	int (*valid)(suspend_state_t state);
-	int (*set_target)(suspend_state_t state);
-	int (*prepare)(suspend_state_t state);
-	int (*enter)(suspend_state_t state);
-	int (*finish)(suspend_state_t state);
-};
-
-#ifdef CONFIG_SUSPEND
-extern struct pm_ops *pm_ops;
-
-/**
- * pm_set_ops - set platform dependent power management ops
- * @pm_ops: The new power management operations to set.
- */
-extern void pm_set_ops(struct pm_ops *pm_ops);
-extern int pm_valid_only_mem(suspend_state_t state);
-
-/**
- * arch_suspend_disable_irqs - disable IRQs for suspend
- *
- * Disables IRQs (in the default case). This is a weak symbol in the common
- * code and thus allows architectures to override it if more needs to be
- * done. Not called for suspend to disk.
- */
-extern void arch_suspend_disable_irqs(void);
-
-/**
- * arch_suspend_enable_irqs - enable IRQs after suspend
- *
- * Enables IRQs (in the default case). This is a weak symbol in the common
- * code and thus allows architectures to override it if more needs to be
- * done. Not called for suspend to disk.
- */
-extern void arch_suspend_enable_irqs(void);
-
-extern int pm_suspend(suspend_state_t state);
-#else /* !CONFIG_SUSPEND */
-#define suspend_valid_only_mem	NULL
-
-static inline void pm_set_ops(struct pm_ops *pm_ops) {}
-static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }
-#endif /* !CONFIG_SUSPEND */
-
 /*
  * Device power management
  */
diff --git a/include/linux/poison.h b/include/linux/poison.h
index d93c300..a9c31be 100644
--- a/include/linux/poison.h
+++ b/include/linux/poison.h
@@ -36,7 +36,8 @@
  */
 
 /********** fs/jbd/journal.c **********/
-#define JBD_POISON_FREE	0x5b
+#define JBD_POISON_FREE		0x5b
+#define JBD2_POISON_FREE	0x5c
 
 /********** drivers/base/dmapool.c **********/
 #define	POOL_POISON_FREED	0xa7	/* !inuse */
diff --git a/include/linux/prefetch.h b/include/linux/prefetch.h
index 1adfe66..af7c36a 100644
--- a/include/linux/prefetch.h
+++ b/include/linux/prefetch.h
@@ -34,17 +34,12 @@
 	
 */
 
-/*
- *	These cannot be do{}while(0) macros. See the mental gymnastics in
- *	the loop macro.
- */
- 
 #ifndef ARCH_HAS_PREFETCH
-static inline void prefetch(const void *x) {;}
+#define prefetch(x) __builtin_prefetch(x)
 #endif
 
 #ifndef ARCH_HAS_PREFETCHW
-static inline void prefetchw(const void *x) {;}
+#define prefetchw(x) __builtin_prefetch(x,1)
 #endif
 
 #ifndef ARCH_HAS_SPINLOCK_PREFETCH
diff --git a/include/linux/prio_heap.h b/include/linux/prio_heap.h
new file mode 100644
index 0000000..0809435
--- /dev/null
+++ b/include/linux/prio_heap.h
@@ -0,0 +1,58 @@
+#ifndef _LINUX_PRIO_HEAP_H
+#define _LINUX_PRIO_HEAP_H
+
+/*
+ * Simple insertion-only static-sized priority heap containing
+ * pointers, based on CLR, chapter 7
+ */
+
+#include <linux/gfp.h>
+
+/**
+ * struct ptr_heap - simple static-sized priority heap
+ * @ptrs - pointer to data area
+ * @max - max number of elements that can be stored in @ptrs
+ * @size - current number of valid elements in @ptrs (in the range 0..@size-1
+ * @gt: comparison operator, which should implement "greater than"
+ */
+struct ptr_heap {
+	void **ptrs;
+	int max;
+	int size;
+	int (*gt)(void *, void *);
+};
+
+/**
+ * heap_init - initialize an empty heap with a given memory size
+ * @heap: the heap structure to be initialized
+ * @size: amount of memory to use in bytes
+ * @gfp_mask: mask to pass to kmalloc()
+ * @gt: comparison operator, which should implement "greater than"
+ */
+extern int heap_init(struct ptr_heap *heap, size_t size, gfp_t gfp_mask,
+		     int (*gt)(void *, void *));
+
+/**
+ * heap_free - release a heap's storage
+ * @heap: the heap structure whose data should be released
+ */
+void heap_free(struct ptr_heap *heap);
+
+/**
+ * heap_insert - insert a value into the heap and return any overflowed value
+ * @heap: the heap to be operated on
+ * @p: the pointer to be inserted
+ *
+ * Attempts to insert the given value into the priority heap. If the
+ * heap is full prior to the insertion, then the resulting heap will
+ * consist of the smallest @max elements of the original heap and the
+ * new element; the greatest element will be removed from the heap and
+ * returned. Note that the returned element will be the new element
+ * (i.e. no change to the heap) if the new element is greater than all
+ * elements currently in the heap.
+ */
+extern void *heap_insert(struct ptr_heap *heap, void *p);
+
+
+
+#endif /* _LINUX_PRIO_HEAP_H */
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 20741f6..1ff4616 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -125,7 +125,8 @@
 extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
 
 extern struct vfsmount *proc_mnt;
-extern int proc_fill_super(struct super_block *,void *,int);
+struct pid_namespace;
+extern int proc_fill_super(struct super_block *);
 extern struct inode *proc_get_inode(struct super_block *, unsigned int, struct proc_dir_entry *);
 
 /*
@@ -142,6 +143,9 @@
 extern const struct file_operations proc_kmsg_operations;
 extern const struct file_operations ppc_htab_operations;
 
+extern int pid_ns_prepare_proc(struct pid_namespace *ns);
+extern void pid_ns_release_proc(struct pid_namespace *ns);
+
 /*
  * proc_tty.c
  */
@@ -207,7 +211,9 @@
 #define proc_net_create(net, name, mode, info)	({ (void)(mode), NULL; })
 static inline void proc_net_remove(struct net *net, const char *name) {}
 
-static inline void proc_flush_task(struct task_struct *task) { }
+static inline void proc_flush_task(struct task_struct *task)
+{
+}
 
 static inline struct proc_dir_entry *create_proc_entry(const char *name,
 	mode_t mode, struct proc_dir_entry *parent) { return NULL; }
@@ -232,6 +238,15 @@
 
 extern struct proc_dir_entry proc_root;
 
+static inline int pid_ns_prepare_proc(struct pid_namespace *ns)
+{
+	return 0;
+}
+
+static inline void pid_ns_release_proc(struct pid_namespace *ns)
+{
+}
+
 #endif /* CONFIG_PROC_FS */
 
 #if !defined(CONFIG_PROC_KCORE)
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 8dcf237..422eab4 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -28,6 +28,8 @@
 #include <linux/reiserfs_fs_sb.h>
 #endif
 
+struct fid;
+
 /*
  *  include/linux/reiser_fs.h
  *
@@ -85,7 +87,7 @@
 if( !( cond ) ) 								\
   reiserfs_panic( NULL, "reiserfs[%i]: assertion " scond " failed at "	\
 		  __FILE__ ":%i:%s: " format "\n",		\
-		  in_interrupt() ? -1 : current -> pid, __LINE__ , __FUNCTION__ , ##args )
+		  in_interrupt() ? -1 : task_pid_nr(current), __LINE__ , __FUNCTION__ , ##args )
 
 #define RASSERT(cond, format, args...) __RASSERT(cond, #cond, format, ##args)
 
@@ -283,6 +285,18 @@
 	return sb->s_fs_info;
 }
 
+/* Don't trust REISERFS_SB(sb)->s_bmap_nr, it's a u16
+ * which overflows on large file systems. */
+static inline u32 reiserfs_bmap_count(struct super_block *sb)
+{
+	return (SB_BLOCK_COUNT(sb) - 1) / (sb->s_blocksize * 8) + 1;
+}
+
+static inline int bmap_would_wrap(unsigned bmap_nr)
+{
+	return bmap_nr > ((1LL << 16) - 1);
+}
+
 /** this says about version of key of all items (but stat data) the
     object consists of */
 #define get_inode_item_key_version( inode )                                    \
@@ -1734,8 +1748,8 @@
 int journal_mark_freed(struct reiserfs_transaction_handle *,
 		       struct super_block *, b_blocknr_t blocknr);
 int journal_transaction_should_end(struct reiserfs_transaction_handle *, int);
-int reiserfs_in_journal(struct super_block *p_s_sb, int bmap_nr, int bit_nr,
-			int searchall, b_blocknr_t * next);
+int reiserfs_in_journal(struct super_block *p_s_sb, unsigned int bmap_nr,
+			int bit_nr, int searchall, b_blocknr_t *next);
 int journal_begin(struct reiserfs_transaction_handle *,
 		  struct super_block *p_s_sb, unsigned long);
 int journal_join_abort(struct reiserfs_transaction_handle *,
@@ -1743,7 +1757,7 @@
 void reiserfs_journal_abort(struct super_block *sb, int errno);
 void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...);
 int reiserfs_allocate_list_bitmaps(struct super_block *s,
-				   struct reiserfs_list_bitmap *, int);
+				   struct reiserfs_list_bitmap *, unsigned int);
 
 void add_save_link(struct reiserfs_transaction_handle *th,
 		   struct inode *inode, int truncate);
@@ -1865,12 +1879,10 @@
 int reiserfs_write_inode(struct inode *inode, int);
 int reiserfs_get_block(struct inode *inode, sector_t block,
 		       struct buffer_head *bh_result, int create);
-struct dentry *reiserfs_get_dentry(struct super_block *, void *);
-struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 * data,
-				  int len, int fhtype,
-				  int (*acceptable) (void *contect,
-						     struct dentry * de),
-				  void *context);
+struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+				     int fh_len, int fh_type);
+struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+				     int fh_len, int fh_type);
 int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
 		       int connectable);
 
@@ -2041,7 +2053,7 @@
  * arguments, such as node, search path, transaction_handle, etc. */
 struct __reiserfs_blocknr_hint {
 	struct inode *inode;	/* inode passed to allocator, if we allocate unf. nodes */
-	long block;		/* file offset, in blocks */
+	sector_t block;		/* file offset, in blocks */
 	struct in_core_key key;
 	struct treepath *path;	/* search path, used by allocator to deternine search_start by
 				 * various ways */
@@ -2099,7 +2111,8 @@
 static inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle
 					    *th, struct inode *inode,
 					    b_blocknr_t * new_blocknrs,
-					    struct treepath *path, long block)
+					    struct treepath *path,
+					    sector_t block)
 {
 	reiserfs_blocknr_hint_t hint = {
 		.th = th,
@@ -2116,7 +2129,8 @@
 static inline int reiserfs_new_unf_blocknrs2(struct reiserfs_transaction_handle
 					     *th, struct inode *inode,
 					     b_blocknr_t * new_blocknrs,
-					     struct treepath *path, long block)
+					     struct treepath *path,
+					     sector_t block)
 {
 	reiserfs_blocknr_hint_t hint = {
 		.th = th,
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index ff9e923..10fa0c8 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -265,9 +265,7 @@
 typedef __u32(*hashf_t) (const signed char *, int);
 
 struct reiserfs_bitmap_info {
-	// FIXME: Won't work with block sizes > 8K
-	__u16 first_zero_hint;
-	__u16 free_count;
+	__u32 free_count;
 };
 
 struct proc_dir_entry;
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 2dc7464..df7ddce 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -4,47 +4,100 @@
 #include <asm/scatterlist.h>
 #include <linux/mm.h>
 #include <linux/string.h>
+#include <asm/io.h>
 
+/*
+ * Notes on SG table design.
+ *
+ * Architectures must provide an unsigned long page_link field in the
+ * scatterlist struct. We use that to place the page pointer AND encode
+ * information about the sg table as well. The two lower bits are reserved
+ * for this information.
+ *
+ * If bit 0 is set, then the page_link contains a pointer to the next sg
+ * table list. Otherwise the next entry is at sg + 1.
+ *
+ * If bit 1 is set, then this sg entry is the last element in a list.
+ *
+ * See sg_next().
+ *
+ */
+
+#define SG_MAGIC	0x87654321
+
+/**
+ * sg_set_page - Set sg entry to point at given page
+ * @sg:		 SG entry
+ * @page:	 The page
+ *
+ * Description:
+ *   Use this function to set an sg entry pointing at a page, never assign
+ *   the page directly. We encode sg table information in the lower bits
+ *   of the page pointer. See sg_page() for looking up the page belonging
+ *   to an sg entry.
+ *
+ **/
+static inline void sg_set_page(struct scatterlist *sg, struct page *page)
+{
+	unsigned long page_link = sg->page_link & 0x3;
+
+	/*
+	 * In order for the low bit stealing approach to work, pages
+	 * must be aligned at a 32-bit boundary as a minimum.
+	 */
+	BUG_ON((unsigned long) page & 0x03);
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	sg->page_link = page_link | (unsigned long) page;
+}
+
+#define sg_page(sg)	((struct page *) ((sg)->page_link & ~0x3))
+
+/**
+ * sg_set_buf - Set sg entry to point at given data
+ * @sg:		 SG entry
+ * @buf:	 Data
+ * @buflen:	 Data length
+ *
+ **/
 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
 			      unsigned int buflen)
 {
-	sg->page = virt_to_page(buf);
+	sg_set_page(sg, virt_to_page(buf));
 	sg->offset = offset_in_page(buf);
 	sg->length = buflen;
 }
 
-static inline void sg_init_one(struct scatterlist *sg, const void *buf,
-			       unsigned int buflen)
-{
-	memset(sg, 0, sizeof(*sg));
-	sg_set_buf(sg, buf, buflen);
-}
-
 /*
  * We overload the LSB of the page pointer to indicate whether it's
  * a valid sg entry, or whether it points to the start of a new scatterlist.
  * Those low bits are there for everyone! (thanks mason :-)
  */
-#define sg_is_chain(sg)		((unsigned long) (sg)->page & 0x01)
+#define sg_is_chain(sg)		((sg)->page_link & 0x01)
+#define sg_is_last(sg)		((sg)->page_link & 0x02)
 #define sg_chain_ptr(sg)	\
-	((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01))
+	((struct scatterlist *) ((sg)->page_link & ~0x03))
 
 /**
  * sg_next - return the next scatterlist entry in a list
  * @sg:		The current sg entry
  *
- * Usually the next entry will be @sg@ + 1, but if this sg element is part
- * of a chained scatterlist, it could jump to the start of a new
- * scatterlist array.
+ * Description:
+ *   Usually the next entry will be @sg@ + 1, but if this sg element is part
+ *   of a chained scatterlist, it could jump to the start of a new
+ *   scatterlist array.
  *
- * Note that the caller must ensure that there are further entries after
- * the current entry, this function will NOT return NULL for an end-of-list.
- *
- */
+ **/
 static inline struct scatterlist *sg_next(struct scatterlist *sg)
 {
-	sg++;
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+	if (sg_is_last(sg))
+		return NULL;
 
+	sg++;
 	if (unlikely(sg_is_chain(sg)))
 		sg = sg_chain_ptr(sg);
 
@@ -62,14 +115,15 @@
  * @sgl:	First entry in the scatterlist
  * @nents:	Number of entries in the scatterlist
  *
- * Should only be used casually, it (currently) scan the entire list
- * to get the last entry.
+ * Description:
+ *   Should only be used casually, it (currently) scan the entire list
+ *   to get the last entry.
  *
- * Note that the @sgl@ pointer passed in need not be the first one,
- * the important bit is that @nents@ denotes the number of entries that
- * exist from @sgl@.
+ *   Note that the @sgl@ pointer passed in need not be the first one,
+ *   the important bit is that @nents@ denotes the number of entries that
+ *   exist from @sgl@.
  *
- */
+ **/
 static inline struct scatterlist *sg_last(struct scatterlist *sgl,
 					  unsigned int nents)
 {
@@ -83,6 +137,10 @@
 		ret = sg;
 
 #endif
+#ifdef CONFIG_DEBUG_SG
+	BUG_ON(sgl[0].sg_magic != SG_MAGIC);
+	BUG_ON(!sg_is_last(ret));
+#endif
 	return ret;
 }
 
@@ -92,16 +150,111 @@
  * @prv_nents:	Number of entries in prv
  * @sgl:	Second scatterlist
  *
- * Links @prv@ and @sgl@ together, to form a longer scatterlist.
+ * Description:
+ *   Links @prv@ and @sgl@ together, to form a longer scatterlist.
  *
- */
+ **/
 static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
 			    struct scatterlist *sgl)
 {
 #ifndef ARCH_HAS_SG_CHAIN
 	BUG();
 #endif
-	prv[prv_nents - 1].page = (struct page *) ((unsigned long) sgl | 0x01);
+	prv[prv_nents - 1].page_link = (unsigned long) sgl | 0x01;
+}
+
+/**
+ * sg_mark_end - Mark the end of the scatterlist
+ * @sgl:	Scatterlist
+ * @nents:	Number of entries in sgl
+ *
+ * Description:
+ *   Marks the last entry as the termination point for sg_next()
+ *
+ **/
+static inline void sg_mark_end(struct scatterlist *sgl, unsigned int nents)
+{
+	sgl[nents - 1].page_link = 0x02;
+}
+
+static inline void __sg_mark_end(struct scatterlist *sg)
+{
+	sg->page_link |= 0x02;
+}
+
+/**
+ * sg_init_one - Initialize a single entry sg list
+ * @sg:		 SG entry
+ * @buf:	 Virtual address for IO
+ * @buflen:	 IO length
+ *
+ * Notes:
+ *   This should not be used on a single entry that is part of a larger
+ *   table. Use sg_init_table() for that.
+ *
+ **/
+static inline void sg_init_one(struct scatterlist *sg, const void *buf,
+			       unsigned int buflen)
+{
+	memset(sg, 0, sizeof(*sg));
+#ifdef CONFIG_DEBUG_SG
+	sg->sg_magic = SG_MAGIC;
+#endif
+	sg_mark_end(sg, 1);
+	sg_set_buf(sg, buf, buflen);
+}
+
+/**
+ * sg_init_table - Initialize SG table
+ * @sgl:	   The SG table
+ * @nents:	   Number of entries in table
+ *
+ * Notes:
+ *   If this is part of a chained sg table, sg_mark_end() should be
+ *   used only on the last table part.
+ *
+ **/
+static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
+{
+	memset(sgl, 0, sizeof(*sgl) * nents);
+	sg_mark_end(sgl, nents);
+#ifdef CONFIG_DEBUG_SG
+	{
+		int i;
+		for (i = 0; i < nents; i++)
+			sgl[i].sg_magic = SG_MAGIC;
+	}
+#endif
+}
+
+/**
+ * sg_phys - Return physical address of an sg entry
+ * @sg:	     SG entry
+ *
+ * Description:
+ *   This calls page_to_phys() on the page in this sg entry, and adds the
+ *   sg offset. The caller must know that it is legal to call page_to_phys()
+ *   on the sg page.
+ *
+ **/
+static inline unsigned long sg_phys(struct scatterlist *sg)
+{
+	return page_to_phys(sg_page(sg)) + sg->offset;
+}
+
+/**
+ * sg_virt - Return virtual address of an sg entry
+ * @sg:      SG entry
+ *
+ * Description:
+ *   This calls page_address() on the page in this sg entry, and adds the
+ *   sg offset. The caller must know that the sg page has a valid virtual
+ *   mapping.
+ *
+ **/
+static inline void *sg_virt(struct scatterlist *sg)
+{
+	return page_address(sg_page(sg)) + sg->offset;
 }
 
 #endif /* _LINUX_SCATTERLIST_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index c204ab0..13df99f 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -25,6 +25,7 @@
 #define CLONE_NEWUTS		0x04000000	/* New utsname group? */
 #define CLONE_NEWIPC		0x08000000	/* New ipcs */
 #define CLONE_NEWUSER		0x10000000	/* New user namespace */
+#define CLONE_NEWPID		0x20000000	/* New pid namespace */
 #define CLONE_NEWNET		0x40000000	/* New network namespace */
 
 /*
@@ -428,7 +429,17 @@
 	cputime_t it_prof_incr, it_virt_incr;
 
 	/* job control IDs */
-	pid_t pgrp;
+
+	/*
+	 * pgrp and session fields are deprecated.
+	 * use the task_session_Xnr and task_pgrp_Xnr routines below
+	 */
+
+	union {
+		pid_t pgrp __deprecated;
+		pid_t __pgrp;
+	};
+
 	struct pid *tty_old_pgrp;
 
 	union {
@@ -569,7 +580,7 @@
 			   last_queued;	/* when we were last queued to run */
 #ifdef CONFIG_SCHEDSTATS
 	/* BKL stats */
-	unsigned long bkl_count;
+	unsigned int bkl_count;
 #endif
 };
 #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */
@@ -705,37 +716,39 @@
 
 #ifdef CONFIG_SCHEDSTATS
 	/* load_balance() stats */
-	unsigned long lb_count[CPU_MAX_IDLE_TYPES];
-	unsigned long lb_failed[CPU_MAX_IDLE_TYPES];
-	unsigned long lb_balanced[CPU_MAX_IDLE_TYPES];
-	unsigned long lb_imbalance[CPU_MAX_IDLE_TYPES];
-	unsigned long lb_gained[CPU_MAX_IDLE_TYPES];
-	unsigned long lb_hot_gained[CPU_MAX_IDLE_TYPES];
-	unsigned long lb_nobusyg[CPU_MAX_IDLE_TYPES];
-	unsigned long lb_nobusyq[CPU_MAX_IDLE_TYPES];
+	unsigned int lb_count[CPU_MAX_IDLE_TYPES];
+	unsigned int lb_failed[CPU_MAX_IDLE_TYPES];
+	unsigned int lb_balanced[CPU_MAX_IDLE_TYPES];
+	unsigned int lb_imbalance[CPU_MAX_IDLE_TYPES];
+	unsigned int lb_gained[CPU_MAX_IDLE_TYPES];
+	unsigned int lb_hot_gained[CPU_MAX_IDLE_TYPES];
+	unsigned int lb_nobusyg[CPU_MAX_IDLE_TYPES];
+	unsigned int lb_nobusyq[CPU_MAX_IDLE_TYPES];
 
 	/* Active load balancing */
-	unsigned long alb_count;
-	unsigned long alb_failed;
-	unsigned long alb_pushed;
+	unsigned int alb_count;
+	unsigned int alb_failed;
+	unsigned int alb_pushed;
 
 	/* SD_BALANCE_EXEC stats */
-	unsigned long sbe_count;
-	unsigned long sbe_balanced;
-	unsigned long sbe_pushed;
+	unsigned int sbe_count;
+	unsigned int sbe_balanced;
+	unsigned int sbe_pushed;
 
 	/* SD_BALANCE_FORK stats */
-	unsigned long sbf_count;
-	unsigned long sbf_balanced;
-	unsigned long sbf_pushed;
+	unsigned int sbf_count;
+	unsigned int sbf_balanced;
+	unsigned int sbf_pushed;
 
 	/* try_to_wake_up() stats */
-	unsigned long ttwu_wake_remote;
-	unsigned long ttwu_move_affine;
-	unsigned long ttwu_move_balance;
+	unsigned int ttwu_wake_remote;
+	unsigned int ttwu_move_affine;
+	unsigned int ttwu_move_balance;
 #endif
 };
 
+extern void partition_sched_domains(int ndoms_new, cpumask_t *doms_new);
+
 #endif	/* CONFIG_SMP */
 
 /*
@@ -756,8 +769,6 @@
 }
 
 struct io_context;			/* See blkdev.h */
-struct cpuset;
-
 #define NGROUPS_SMALL		32
 #define NGROUPS_PER_BLOCK	((int)(PAGE_SIZE / sizeof(gid_t)))
 struct group_info {
@@ -991,7 +1002,7 @@
 	int __user *clear_child_tid;		/* CLONE_CHILD_CLEARTID */
 
 	unsigned int rt_priority;
-	cputime_t utime, stime;
+	cputime_t utime, stime, utimescaled, stimescaled;
 	cputime_t gtime;
 	unsigned long nvcsw, nivcsw; /* context switch counts */
 	struct timespec start_time; 		/* monotonic time */
@@ -1110,13 +1121,6 @@
 
 	unsigned long ptrace_message;
 	siginfo_t *last_siginfo; /* For ptrace use.  */
-/*
- * current io wait handle: wait queue entry to use for io waits
- * If this thread is processing aio, this points at the waitqueue
- * inside the currently handled kiocb. It may be NULL (i.e. default
- * to a stack based synchronous wait) if its doing sync IO.
- */
-	wait_queue_t *io_wait;
 #ifdef CONFIG_TASK_XACCT
 /* i/o counters(bytes read/written, #syscalls */
 	u64 rchar, wchar, syscr, syscw;
@@ -1132,11 +1136,16 @@
 	short il_next;
 #endif
 #ifdef CONFIG_CPUSETS
-	struct cpuset *cpuset;
 	nodemask_t mems_allowed;
 	int cpuset_mems_generation;
 	int cpuset_mem_spread_rotor;
 #endif
+#ifdef CONFIG_CGROUPS
+	/* Control Group info protected by css_set_lock */
+	struct css_set *cgroups;
+	/* cg_list protected by css_set_lock and tsk->alloc_lock */
+	struct list_head cg_list;
+#endif
 #ifdef CONFIG_FUTEX
 	struct robust_list_head __user *robust_list;
 #ifdef CONFIG_COMPAT
@@ -1192,24 +1201,14 @@
 	return rt_prio(p->prio);
 }
 
-static inline pid_t process_group(struct task_struct *tsk)
+static inline void set_task_session(struct task_struct *tsk, pid_t session)
 {
-	return tsk->signal->pgrp;
+	tsk->signal->__session = session;
 }
 
-static inline pid_t signal_session(struct signal_struct *sig)
+static inline void set_task_pgrp(struct task_struct *tsk, pid_t pgrp)
 {
-	return sig->__session;
-}
-
-static inline pid_t process_session(struct task_struct *tsk)
-{
-	return signal_session(tsk->signal);
-}
-
-static inline void set_signal_session(struct signal_struct *sig, pid_t session)
-{
-	sig->__session = session;
+	tsk->signal->__pgrp = pgrp;
 }
 
 static inline struct pid *task_pid(struct task_struct *task)
@@ -1232,6 +1231,88 @@
 	return task->group_leader->pids[PIDTYPE_SID].pid;
 }
 
+struct pid_namespace;
+
+/*
+ * the helpers to get the task's different pids as they are seen
+ * from various namespaces
+ *
+ * task_xid_nr()     : global id, i.e. the id seen from the init namespace;
+ * task_xid_vnr()    : virtual id, i.e. the id seen from the namespace the task
+ *                     belongs to. this only makes sence when called in the
+ *                     context of the task that belongs to the same namespace;
+ * task_xid_nr_ns()  : id seen from the ns specified;
+ *
+ * set_task_vxid()   : assigns a virtual id to a task;
+ *
+ * task_ppid_nr_ns() : the parent's id as seen from the namespace specified.
+ *                     the result depends on the namespace and whether the
+ *                     task in question is the namespace's init. e.g. for the
+ *                     namespace's init this will return 0 when called from
+ *                     the namespace of this init, or appropriate id otherwise.
+ *
+ *
+ * see also pid_nr() etc in include/linux/pid.h
+ */
+
+static inline pid_t task_pid_nr(struct task_struct *tsk)
+{
+	return tsk->pid;
+}
+
+pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+
+static inline pid_t task_pid_vnr(struct task_struct *tsk)
+{
+	return pid_vnr(task_pid(tsk));
+}
+
+
+static inline pid_t task_tgid_nr(struct task_struct *tsk)
+{
+	return tsk->tgid;
+}
+
+pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+
+static inline pid_t task_tgid_vnr(struct task_struct *tsk)
+{
+	return pid_vnr(task_tgid(tsk));
+}
+
+
+static inline pid_t task_pgrp_nr(struct task_struct *tsk)
+{
+	return tsk->signal->__pgrp;
+}
+
+pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+
+static inline pid_t task_pgrp_vnr(struct task_struct *tsk)
+{
+	return pid_vnr(task_pgrp(tsk));
+}
+
+
+static inline pid_t task_session_nr(struct task_struct *tsk)
+{
+	return tsk->signal->__session;
+}
+
+pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+
+static inline pid_t task_session_vnr(struct task_struct *tsk)
+{
+	return pid_vnr(task_session(tsk));
+}
+
+
+static inline pid_t task_ppid_nr_ns(struct task_struct *tsk,
+		struct pid_namespace *ns)
+{
+	return pid_nr_ns(task_pid(rcu_dereference(tsk->real_parent)), ns);
+}
+
 /**
  * pid_alive - check that a task structure is not stale
  * @p: Task structure to be checked.
@@ -1246,16 +1327,22 @@
 }
 
 /**
- * is_init - check if a task structure is init
+ * is_global_init - check if a task structure is init
  * @tsk: Task structure to be checked.
  *
  * Check if a task structure is the first user space task the kernel created.
  */
-static inline int is_init(struct task_struct *tsk)
+static inline int is_global_init(struct task_struct *tsk)
 {
 	return tsk->pid == 1;
 }
 
+/*
+ * is_container_init:
+ * check whether in the task is init in its own pid namespace.
+ */
+extern int is_container_init(struct task_struct *tsk);
+
 extern struct pid *cad_pid;
 
 extern void free_task(struct task_struct *tsk);
@@ -1427,8 +1514,32 @@
 
 extern struct   mm_struct init_mm;
 
-#define find_task_by_pid(nr)	find_task_by_pid_type(PIDTYPE_PID, nr)
-extern struct task_struct *find_task_by_pid_type(int type, int pid);
+extern struct pid_namespace init_pid_ns;
+
+/*
+ * find a task by one of its numerical ids
+ *
+ * find_task_by_pid_type_ns():
+ *      it is the most generic call - it finds a task by all id,
+ *      type and namespace specified
+ * find_task_by_pid_ns():
+ *      finds a task by its pid in the specified namespace
+ * find_task_by_vpid():
+ *      finds a task by its virtual pid
+ * find_task_by_pid():
+ *      finds a task by its global pid
+ *
+ * see also find_pid() etc in include/linux/pid.h
+ */
+
+extern struct task_struct *find_task_by_pid_type_ns(int type, int pid,
+		struct pid_namespace *ns);
+
+extern struct task_struct *find_task_by_pid(pid_t nr);
+extern struct task_struct *find_task_by_vpid(pid_t nr);
+extern struct task_struct *find_task_by_pid_ns(pid_t nr,
+		struct pid_namespace *ns);
+
 extern void __set_special_pids(pid_t session, pid_t pgrp);
 
 /* per-UID process charging. */
@@ -1615,6 +1726,12 @@
 	return p->pid == p->tgid;
 }
 
+static inline
+int same_thread_group(struct task_struct *p1, struct task_struct *p2)
+{
+	return p1->tgid == p2->tgid;
+}
+
 static inline struct task_struct *next_thread(const struct task_struct *p)
 {
 	return list_entry(rcu_dereference(p->thread_group.next),
@@ -1632,7 +1749,8 @@
 /*
  * Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring
  * subscriptions and synchronises with wait4().  Also used in procfs.  Also
- * pins the final release of task.io_context.  Also protects ->cpuset.
+ * pins the final release of task.io_context.  Also protects ->cpuset and
+ * ->cgroup.subsys[].
  *
  * Nests both inside and outside of read_lock(&tasklist_lock).
  * It must not be nested with write_lock_irq(&tasklist_lock),
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
index ba81ffe..827b85b 100644
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -8,45 +8,43 @@
  */
 
 struct screen_info {
-	u8  orig_x;		/* 0x00 */
-	u8  orig_y;		/* 0x01 */
-	u16 ext_mem_k;		/* 0x02 */
-	u16 orig_video_page;	/* 0x04 */
-	u8  orig_video_mode;	/* 0x06 */
-	u8  orig_video_cols;	/* 0x07 */
-	u16 unused2;		/* 0x08 */
-	u16 orig_video_ega_bx;	/* 0x0a */
-	u16 unused3;		/* 0x0c */
-	u8  orig_video_lines;	/* 0x0e */
-	u8  orig_video_isVGA;	/* 0x0f */
-	u16 orig_video_points;	/* 0x10 */
+	__u8  orig_x;		/* 0x00 */
+	__u8  orig_y;		/* 0x01 */
+	__u16 ext_mem_k;	/* 0x02 */
+	__u16 orig_video_page;	/* 0x04 */
+	__u8  orig_video_mode;	/* 0x06 */
+	__u8  orig_video_cols;	/* 0x07 */
+	__u16 unused2;		/* 0x08 */
+	__u16 orig_video_ega_bx;/* 0x0a */
+	__u16 unused3;		/* 0x0c */
+	__u8  orig_video_lines;	/* 0x0e */
+	__u8  orig_video_isVGA;	/* 0x0f */
+	__u16 orig_video_points;/* 0x10 */
 
 	/* VESA graphic mode -- linear frame buffer */
-	u16 lfb_width;		/* 0x12 */
-	u16 lfb_height;		/* 0x14 */
-	u16 lfb_depth;		/* 0x16 */
-	u32 lfb_base;		/* 0x18 */
-	u32 lfb_size;		/* 0x1c */
-	u16 cl_magic, cl_offset; /* 0x20 */
-	u16 lfb_linelength;	/* 0x24 */
-	u8  red_size;		/* 0x26 */
-	u8  red_pos;		/* 0x27 */
-	u8  green_size;		/* 0x28 */
-	u8  green_pos;		/* 0x29 */
-	u8  blue_size;		/* 0x2a */
-	u8  blue_pos;		/* 0x2b */
-	u8  rsvd_size;		/* 0x2c */
-	u8  rsvd_pos;		/* 0x2d */
-	u16 vesapm_seg;		/* 0x2e */
-	u16 vesapm_off;		/* 0x30 */
-	u16 pages;		/* 0x32 */
-	u16 vesa_attributes;	/* 0x34 */
-	u32 capabilities;       /* 0x36 */
-	u8  _reserved[6];	/* 0x3a */
+	__u16 lfb_width;	/* 0x12 */
+	__u16 lfb_height;	/* 0x14 */
+	__u16 lfb_depth;	/* 0x16 */
+	__u32 lfb_base;		/* 0x18 */
+	__u32 lfb_size;		/* 0x1c */
+	__u16 cl_magic, cl_offset; /* 0x20 */
+	__u16 lfb_linelength;	/* 0x24 */
+	__u8  red_size;		/* 0x26 */
+	__u8  red_pos;		/* 0x27 */
+	__u8  green_size;	/* 0x28 */
+	__u8  green_pos;	/* 0x29 */
+	__u8  blue_size;	/* 0x2a */
+	__u8  blue_pos;		/* 0x2b */
+	__u8  rsvd_size;	/* 0x2c */
+	__u8  rsvd_pos;		/* 0x2d */
+	__u16 vesapm_seg;	/* 0x2e */
+	__u16 vesapm_off;	/* 0x30 */
+	__u16 pages;		/* 0x32 */
+	__u16 vesa_attributes;	/* 0x34 */
+	__u32 capabilities;     /* 0x36 */
+	__u8  _reserved[6];	/* 0x3a */
 } __attribute__((packed));
 
-extern struct screen_info screen_info;
-
 #define VIDEO_TYPE_MDA		0x10	/* Monochrome Text Display	*/
 #define VIDEO_TYPE_CGA		0x11	/* CGA Display 			*/
 #define VIDEO_TYPE_EGAM		0x20	/* EGA/VGA in Monochrome Mode	*/
@@ -65,4 +63,17 @@
 
 #define VIDEO_TYPE_PMAC		0x60	/* PowerMacintosh frame buffer. */
 
+#ifdef __KERNEL__
+extern struct screen_info screen_info;
+
+#define ORIG_X			(screen_info.orig_x)
+#define ORIG_Y			(screen_info.orig_y)
+#define ORIG_VIDEO_MODE		(screen_info.orig_video_mode)
+#define ORIG_VIDEO_COLS 	(screen_info.orig_video_cols)
+#define ORIG_VIDEO_EGA_BX	(screen_info.orig_video_ega_bx)
+#define ORIG_VIDEO_LINES	(screen_info.orig_video_lines)
+#define ORIG_VIDEO_ISVGA	(screen_info.orig_video_isVGA)
+#define ORIG_VIDEO_POINTS       (screen_info.orig_video_points)
+#endif /* __KERNEL__ */
+
 #endif /* _SCREEN_INFO_H */
diff --git a/include/linux/security.h b/include/linux/security.h
index 9b0b63c..ac05083 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -34,6 +34,13 @@
 #include <linux/xfrm.h>
 #include <net/flow.h>
 
+/*
+ * Bounding set
+ */
+extern kernel_cap_t cap_bset;
+
+extern unsigned securebits;
+
 struct ctl_table;
 
 /*
@@ -825,9 +832,11 @@
  *	incoming sk_buff @skb has been associated with a particular socket, @sk.
  *	@sk contains the sock (not socket) associated with the incoming sk_buff.
  *	@skb contains the incoming network data.
- * @socket_getpeersec:
+ * @socket_getpeersec_stream:
  *	This hook allows the security module to provide peer socket security
- *	state to userspace via getsockopt SO_GETPEERSEC.
+ *	state for unix or connected tcp sockets to userspace via getsockopt
+ *	SO_GETPEERSEC.  For tcp sockets this can be meaningful if the
+ *	socket is associated with an ipsec SA.
  *	@sock is the local socket.
  *	@optval userspace memory where the security state is to be copied.
  *	@optlen userspace int where the module should copy the actual length
@@ -836,6 +845,17 @@
  *	by the caller.
  *	Return 0 if all is well, otherwise, typical getsockopt return
  *	values.
+ * @socket_getpeersec_dgram:
+ * 	This hook allows the security module to provide peer socket security
+ * 	state for udp sockets on a per-packet basis to userspace via
+ * 	getsockopt SO_GETPEERSEC.  The application must first have indicated
+ * 	the IP_PASSSEC option via getsockopt.  It can then retrieve the
+ * 	security state returned by this hook for a packet via the SCM_SECURITY
+ * 	ancillary message type.
+ * 	@skb is the skbuff for the packet being queried
+ * 	@secdata is a pointer to a buffer in which to copy the security data
+ * 	@seclen is the maximum length for @secdata
+ * 	Return 0 on success, error on failure.
  * @sk_alloc_security:
  *      Allocate and attach a security structure to the sk->sk_security field,
  *      which is used to copy security attributes between local stream sockets.
diff --git a/include/linux/sem.h b/include/linux/sem.h
index 9aaffb0..c8eaad9 100644
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -90,7 +90,6 @@
 /* One sem_array data structure for each set of semaphores in the system. */
 struct sem_array {
 	struct kern_ipc_perm	sem_perm;	/* permissions .. see ipc.h */
-	int			sem_id;
 	time_t			sem_otime;	/* last semop time */
 	time_t			sem_ctime;	/* last change time */
 	struct sem		*sem_base;	/* ptr to first semaphore in array */
diff --git a/include/linux/shm.h b/include/linux/shm.h
index bea65d9..eeaed92 100644
--- a/include/linux/shm.h
+++ b/include/linux/shm.h
@@ -79,7 +79,6 @@
 {	
 	struct kern_ipc_perm	shm_perm;
 	struct file *		shm_file;
-	int			id;
 	unsigned long		shm_nattch;
 	unsigned long		shm_segsz;
 	time_t			shm_atim;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index f93f22b..fd4e12f 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -41,8 +41,7 @@
 #define SKB_DATA_ALIGN(X)	(((X) + (SMP_CACHE_BYTES - 1)) & \
 				 ~(SMP_CACHE_BYTES - 1))
 #define SKB_WITH_OVERHEAD(X)	\
-	(((X) - sizeof(struct skb_shared_info)) & \
-	 ~(SMP_CACHE_BYTES - 1))
+	((X) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
 #define SKB_MAX_ORDER(X, ORDER) \
 	SKB_WITH_OVERHEAD((PAGE_SIZE << (ORDER)) - (X))
 #define SKB_MAX_HEAD(X)		(SKB_MAX_ORDER((X), 0))
@@ -301,8 +300,9 @@
 #endif
 
 	int			iif;
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
 	__u16			queue_mapping;
-
+#endif
 #ifdef CONFIG_NET_SCHED
 	__u16			tc_index;	/* traffic control index */
 #ifdef CONFIG_NET_CLS_ACT
@@ -1770,6 +1770,15 @@
 #endif
 }
 
+static inline u16 skb_get_queue_mapping(struct sk_buff *skb)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	return skb->queue_mapping;
+#else
+	return 0;
+#endif
+}
+
 static inline void skb_copy_queue_mapping(struct sk_buff *to, const struct sk_buff *from)
 {
 #ifdef CONFIG_NETDEVICES_MULTIQUEUE
diff --git a/include/linux/socket.h b/include/linux/socket.h
index f852e1a..c22ef1c 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -291,6 +291,7 @@
 #define SOL_TIPC	271
 #define SOL_RXRPC	272
 #define SOL_PPPOL2TP	273
+#define SOL_BLUETOOTH	274
 
 /* IPX options */
 #define IPX_TYPE	1
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 388cace..4360e08 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -1,5 +1,5 @@
-#ifndef _LINUX_SWSUSP_H
-#define _LINUX_SWSUSP_H
+#ifndef _LINUX_SUSPEND_H
+#define _LINUX_SUSPEND_H
 
 #if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
 #include <asm/suspend.h>
@@ -9,6 +9,108 @@
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/mm.h>
+#include <asm/errno.h>
+
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
+extern int pm_prepare_console(void);
+extern void pm_restore_console(void);
+#else
+static inline int pm_prepare_console(void) { return 0; }
+static inline void pm_restore_console(void) {}
+#endif
+
+typedef int __bitwise suspend_state_t;
+
+#define PM_SUSPEND_ON		((__force suspend_state_t) 0)
+#define PM_SUSPEND_STANDBY	((__force suspend_state_t) 1)
+#define PM_SUSPEND_MEM		((__force suspend_state_t) 3)
+#define PM_SUSPEND_MAX		((__force suspend_state_t) 4)
+
+/**
+ * struct platform_suspend_ops - Callbacks for managing platform dependent
+ *	system sleep states.
+ *
+ * @valid: Callback to determine if given system sleep state is supported by
+ *	the platform.
+ *	Valid (ie. supported) states are advertised in /sys/power/state.  Note
+ *	that it still may be impossible to enter given system sleep state if the
+ *	conditions aren't right.
+ *	There is the %suspend_valid_only_mem function available that can be
+ *	assigned to this if the platform only supports mem sleep.
+ *
+ * @set_target: Tell the platform which system sleep state is going to be
+ *	entered.
+ *	@set_target() is executed right prior to suspending devices.  The
+ *	information conveyed to the platform code by @set_target() should be
+ *	disregarded by the platform as soon as @finish() is executed and if
+ *	@prepare() fails.  If @set_target() fails (ie. returns nonzero),
+ *	@prepare(), @enter() and @finish() will not be called by the PM core.
+ *	This callback is optional.  However, if it is implemented, the argument
+ *	passed to @enter() is meaningless and should be ignored.
+ *
+ * @prepare: Prepare the platform for entering the system sleep state indicated
+ *	by @set_target().
+ *	@prepare() is called right after devices have been suspended (ie. the
+ *	appropriate .suspend() method has been executed for each device) and
+ *	before the nonboot CPUs are disabled (it is executed with IRQs enabled).
+ *	This callback is optional.  It returns 0 on success or a negative
+ *	error code otherwise, in which case the system cannot enter the desired
+ *	sleep state (@enter() and @finish() will not be called in that case).
+ *
+ * @enter: Enter the system sleep state indicated by @set_target() or
+ *	represented by the argument if @set_target() is not implemented.
+ *	This callback is mandatory.  It returns 0 on success or a negative
+ *	error code otherwise, in which case the system cannot enter the desired
+ *	sleep state.
+ *
+ * @finish: Called when the system has just left a sleep state, right after
+ *	the nonboot CPUs have been enabled and before devices are resumed (it is
+ *	executed with IRQs enabled).
+ *	This callback is optional, but should be implemented by the platforms
+ *	that implement @prepare().  If implemented, it is always called after
+ *	@enter() (even if @enter() fails).
+ */
+struct platform_suspend_ops {
+	int (*valid)(suspend_state_t state);
+	int (*set_target)(suspend_state_t state);
+	int (*prepare)(void);
+	int (*enter)(suspend_state_t state);
+	void (*finish)(void);
+};
+
+#ifdef CONFIG_SUSPEND
+/**
+ * suspend_set_ops - set platform dependent suspend operations
+ * @ops: The new suspend operations to set.
+ */
+extern void suspend_set_ops(struct platform_suspend_ops *ops);
+extern int suspend_valid_only_mem(suspend_state_t state);
+
+/**
+ * arch_suspend_disable_irqs - disable IRQs for suspend
+ *
+ * Disables IRQs (in the default case). This is a weak symbol in the common
+ * code and thus allows architectures to override it if more needs to be
+ * done. Not called for suspend to disk.
+ */
+extern void arch_suspend_disable_irqs(void);
+
+/**
+ * arch_suspend_enable_irqs - enable IRQs after suspend
+ *
+ * Enables IRQs (in the default case). This is a weak symbol in the common
+ * code and thus allows architectures to override it if more needs to be
+ * done. Not called for suspend to disk.
+ */
+extern void arch_suspend_enable_irqs(void);
+
+extern int pm_suspend(suspend_state_t state);
+#else /* !CONFIG_SUSPEND */
+#define suspend_valid_only_mem	NULL
+
+static inline void suspend_set_ops(struct platform_suspend_ops *ops) {}
+static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }
+#endif /* !CONFIG_SUSPEND */
 
 /* struct pbe is used for creating lists of pages that should be restored
  * atomically during the resume from disk, because the page frames they have
@@ -24,32 +126,57 @@
 extern void drain_local_pages(void);
 extern void mark_free_pages(struct zone *zone);
 
-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
-extern int pm_prepare_console(void);
-extern void pm_restore_console(void);
-#else
-static inline int pm_prepare_console(void) { return 0; }
-static inline void pm_restore_console(void) {}
-#endif
-
 /**
- * struct hibernation_ops - hibernation platform support
+ * struct platform_hibernation_ops - hibernation platform support
  *
  * The methods in this structure allow a platform to override the default
  * mechanism of shutting down the machine during a hibernation transition.
  *
  * All three methods must be assigned.
  *
- * @prepare: prepare system for hibernation
- * @enter: shut down system after state has been saved to disk
- * @finish: finish/clean up after state has been reloaded
- * @pre_restore: prepare system for the restoration from a hibernation image
- * @restore_cleanup: clean up after a failing image restoration
+ * @start: Tell the platform driver that we're starting hibernation.
+ *	Called right after shrinking memory and before freezing devices.
+ *
+ * @pre_snapshot: Prepare the platform for creating the hibernation image.
+ *	Called right after devices have been frozen and before the nonboot
+ *	CPUs are disabled (runs with IRQs on).
+ *
+ * @finish: Restore the previous state of the platform after the hibernation
+ *	image has been created *or* put the platform into the normal operation
+ *	mode after the hibernation (the same method is executed in both cases).
+ *	Called right after the nonboot CPUs have been enabled and before
+ *	thawing devices (runs with IRQs on).
+ *
+ * @prepare: Prepare the platform for entering the low power state.
+ *	Called right after the hibernation image has been saved and before
+ *	devices are prepared for entering the low power state.
+ *
+ * @enter: Put the system into the low power state after the hibernation image
+ *	has been saved to disk.
+ *	Called after the nonboot CPUs have been disabled and all of the low
+ *	level devices have been shut down (runs with IRQs off).
+ *
+ * @leave: Perform the first stage of the cleanup after the system sleep state
+ *	indicated by @set_target() has been left.
+ *	Called right after the control has been passed from the boot kernel to
+ *	the image kernel, before the nonboot CPUs are enabled and before devices
+ *	are resumed.  Executed with interrupts disabled.
+ *
+ * @pre_restore: Prepare system for the restoration from a hibernation image.
+ *	Called right after devices have been frozen and before the nonboot
+ *	CPUs are disabled (runs with IRQs on).
+ *
+ * @restore_cleanup: Clean up after a failing image restoration.
+ *	Called right after the nonboot CPUs have been enabled and before
+ *	thawing devices (runs with IRQs on).
  */
-struct hibernation_ops {
+struct platform_hibernation_ops {
+	int (*start)(void);
+	int (*pre_snapshot)(void);
+	void (*finish)(void);
 	int (*prepare)(void);
 	int (*enter)(void);
-	void (*finish)(void);
+	void (*leave)(void);
 	int (*pre_restore)(void);
 	void (*restore_cleanup)(void);
 };
@@ -70,14 +197,14 @@
 extern void swsusp_unset_page_free(struct page *);
 extern unsigned long get_safe_page(gfp_t gfp_mask);
 
-extern void hibernation_set_ops(struct hibernation_ops *ops);
+extern void hibernation_set_ops(struct platform_hibernation_ops *ops);
 extern int hibernate(void);
 #else /* CONFIG_HIBERNATION */
 static inline int swsusp_page_is_forbidden(struct page *p) { return 0; }
 static inline void swsusp_set_page_free(struct page *p) {}
 static inline void swsusp_unset_page_free(struct page *p) {}
 
-static inline void hibernation_set_ops(struct hibernation_ops *ops) {}
+static inline void hibernation_set_ops(struct platform_hibernation_ops *ops) {}
 static inline int hibernate(void) { return -ENOSYS; }
 #endif /* CONFIG_HIBERNATION */
 
@@ -130,4 +257,4 @@
 }
 #endif
 
-#endif /* _LINUX_SWSUSP_H */
+#endif /* _LINUX_SUSPEND_H */
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 483050c..e99171f 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -238,6 +238,7 @@
 	NET_LLC=18,
 	NET_NETFILTER=19,
 	NET_DCCP=20,
+	NET_IRDA=412,
 };
 
 /* /proc/sys/kernel/random */
@@ -795,6 +796,25 @@
 	NET_BRIDGE_NF_FILTER_PPPOE_TAGGED = 5,
 };
 
+/* proc/sys/net/irda */
+enum {
+	NET_IRDA_DISCOVERY=1,
+	NET_IRDA_DEVNAME=2,
+	NET_IRDA_DEBUG=3,
+	NET_IRDA_FAST_POLL=4,
+	NET_IRDA_DISCOVERY_SLOTS=5,
+	NET_IRDA_DISCOVERY_TIMEOUT=6,
+	NET_IRDA_SLOT_TIMEOUT=7,
+	NET_IRDA_MAX_BAUD_RATE=8,
+	NET_IRDA_MIN_TX_TURN_TIME=9,
+	NET_IRDA_MAX_TX_DATA_SIZE=10,
+	NET_IRDA_MAX_TX_WINDOW=11,
+	NET_IRDA_MAX_NOREPLY_TIME=12,
+	NET_IRDA_WARN_NOREPLY_TIME=13,
+	NET_IRDA_LAP_KEEPALIVE_TIME=14,
+};
+
+
 /* CTL_FS names: */
 enum
 {
@@ -937,41 +957,42 @@
 
 typedef struct ctl_table ctl_table;
 
-typedef int ctl_handler (ctl_table *table, int __user *name, int nlen,
+typedef int ctl_handler (struct ctl_table *table, int __user *name, int nlen,
 			 void __user *oldval, size_t __user *oldlenp,
 			 void __user *newval, size_t newlen);
 
-typedef int proc_handler (ctl_table *ctl, int write, struct file * filp,
+typedef int proc_handler (struct ctl_table *ctl, int write, struct file * filp,
 			  void __user *buffer, size_t *lenp, loff_t *ppos);
 
-extern int proc_dostring(ctl_table *, int, struct file *,
+extern int proc_dostring(struct ctl_table *, int, struct file *,
 			 void __user *, size_t *, loff_t *);
-extern int proc_dointvec(ctl_table *, int, struct file *,
+extern int proc_dointvec(struct ctl_table *, int, struct file *,
 			 void __user *, size_t *, loff_t *);
-extern int proc_dointvec_bset(ctl_table *, int, struct file *,
+extern int proc_dointvec_bset(struct ctl_table *, int, struct file *,
 			      void __user *, size_t *, loff_t *);
-extern int proc_dointvec_minmax(ctl_table *, int, struct file *,
+extern int proc_dointvec_minmax(struct ctl_table *, int, struct file *,
 				void __user *, size_t *, loff_t *);
-extern int proc_dointvec_jiffies(ctl_table *, int, struct file *,
+extern int proc_dointvec_jiffies(struct ctl_table *, int, struct file *,
 				 void __user *, size_t *, loff_t *);
-extern int proc_dointvec_userhz_jiffies(ctl_table *, int, struct file *,
+extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int, struct file *,
 					void __user *, size_t *, loff_t *);
-extern int proc_dointvec_ms_jiffies(ctl_table *, int, struct file *,
+extern int proc_dointvec_ms_jiffies(struct ctl_table *, int, struct file *,
 				    void __user *, size_t *, loff_t *);
-extern int proc_doulongvec_minmax(ctl_table *, int, struct file *,
+extern int proc_doulongvec_minmax(struct ctl_table *, int, struct file *,
 				  void __user *, size_t *, loff_t *);
-extern int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int,
+extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int,
 				      struct file *, void __user *, size_t *, loff_t *);
 
 extern int do_sysctl (int __user *name, int nlen,
 		      void __user *oldval, size_t __user *oldlenp,
 		      void __user *newval, size_t newlen);
 
-extern int do_sysctl_strategy (ctl_table *table, 
+extern int do_sysctl_strategy (struct ctl_table *table,
 			       int __user *name, int nlen,
 			       void __user *oldval, size_t __user *oldlenp,
 			       void __user *newval, size_t newlen);
 
+extern ctl_handler sysctl_data;
 extern ctl_handler sysctl_string;
 extern ctl_handler sysctl_intvec;
 extern ctl_handler sysctl_jiffies;
@@ -980,7 +1001,7 @@
 
 /*
  * Register a set of sysctl names by calling register_sysctl_table
- * with an initialised array of ctl_table's.  An entry with zero
+ * with an initialised array of struct ctl_table's.  An entry with zero
  * ctl_name and NULL procname terminates the table.  table->de will be
  * set up by the registration and need not be initialised in advance.
  *
@@ -1026,8 +1047,8 @@
 	void *data;
 	int maxlen;
 	mode_t mode;
-	ctl_table *child;
-	ctl_table *parent;		/* Automatically set */
+	struct ctl_table *child;
+	struct ctl_table *parent;	/* Automatically set */
 	proc_handler *proc_handler;	/* Callback for text formatting */
 	ctl_handler *strategy;		/* Callback function for all r/w */
 	void *extra1;
@@ -1035,18 +1056,19 @@
 };
 
 /* struct ctl_table_header is used to maintain dynamic lists of
-   ctl_table trees. */
+   struct ctl_table trees. */
 struct ctl_table_header
 {
-	ctl_table *ctl_table;
+	struct ctl_table *ctl_table;
 	struct list_head ctl_entry;
 	int used;
 	struct completion *unregistering;
 };
 
-struct ctl_table_header * register_sysctl_table(ctl_table * table);
+struct ctl_table_header *register_sysctl_table(struct ctl_table * table);
 
 void unregister_sysctl_table(struct ctl_table_header * table);
+int sysctl_check_table(struct ctl_table *table);
 
 #else /* __KERNEL__ */
 
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h
index dce1ed204..5d69c07 100644
--- a/include/linux/taskstats.h
+++ b/include/linux/taskstats.h
@@ -31,7 +31,7 @@
  */
 
 
-#define TASKSTATS_VERSION	5
+#define TASKSTATS_VERSION	6
 #define TS_COMM_LEN		32	/* should be >= TASK_COMM_LEN
 					 * in linux/sched.h */
 
@@ -152,6 +152,11 @@
 
 	__u64  nvcsw;			/* voluntary_ctxt_switches */
 	__u64  nivcsw;			/* nonvoluntary_ctxt_switches */
+
+	/* time accounting for SMT machines */
+	__u64	ac_utimescaled;		/* utime scaled on frequency etc */
+	__u64	ac_stimescaled;		/* stime scaled on frequency etc */
+	__u64	cpu_scaled_run_real_total; /* scaled cpu_run_real_total */
 };
 
 
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 9a7252e..f4a1395 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -40,6 +40,7 @@
  * @idle_sleeps:	Number of idle calls, where the sched tick was stopped
  * @idle_entrytime:	Time when the idle call was entered
  * @idle_sleeptime:	Sum of the time slept in idle with sched tick stopped
+ * @sleep_length:	Duration of the current idle sleep
  */
 struct tick_sched {
 	struct hrtimer			sched_timer;
@@ -52,6 +53,7 @@
 	unsigned long			idle_sleeps;
 	ktime_t				idle_entrytime;
 	ktime_t				idle_sleeptime;
+	ktime_t				sleep_length;
 	unsigned long			last_jiffies;
 	unsigned long			next_jiffies;
 	ktime_t				idle_expires;
@@ -100,10 +102,17 @@
 extern void tick_nohz_stop_sched_tick(void);
 extern void tick_nohz_restart_sched_tick(void);
 extern void tick_nohz_update_jiffies(void);
+extern ktime_t tick_nohz_get_sleep_length(void);
 # else
 static inline void tick_nohz_stop_sched_tick(void) { }
 static inline void tick_nohz_restart_sched_tick(void) { }
 static inline void tick_nohz_update_jiffies(void) { }
+static inline ktime_t tick_nohz_get_sleep_length(void)
+{
+	ktime_t len = { .tv64 = NSEC_PER_SEC/HZ };
+
+	return len;
+}
 # endif /* !NO_HZ */
 
 #endif
diff --git a/include/linux/types.h b/include/linux/types.h
index 0351bf2f..4f0dad2 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -3,12 +3,9 @@
 
 #ifdef	__KERNEL__
 
-#define BITS_TO_LONGS(bits) \
-	(((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
 #define DECLARE_BITMAP(name,bits) \
 	unsigned long name[BITS_TO_LONGS(bits)]
 
-#define BITS_PER_BYTE 8
 #endif
 
 #include <linux/posix_types.h>
diff --git a/include/linux/uinput.h b/include/linux/uinput.h
index a6c1e8e..15ddd44 100644
--- a/include/linux/uinput.h
+++ b/include/linux/uinput.h
@@ -162,10 +162,6 @@
 #define UI_FF_UPLOAD		1
 #define UI_FF_ERASE		2
 
-#ifndef NBITS
-#define NBITS(x) ((((x)-1)/(sizeof(long)*8))+1)
-#endif	/* NBITS */
-
 #define UINPUT_MAX_NAME_SIZE	80
 struct uinput_user_dev {
 	char name[UINPUT_MAX_NAME_SIZE];
diff --git a/include/linux/videodev.h b/include/linux/videodev.h
index 8dba97a..52e3d5f 100644
--- a/include/linux/videodev.h
+++ b/include/linux/videodev.h
@@ -294,48 +294,6 @@
 #define VID_PLAY_RESET			13
 #define VID_PLAY_END_MARK		14
 
-
-
-#define VID_HARDWARE_BT848	1
-#define VID_HARDWARE_QCAM_BW	2
-#define VID_HARDWARE_PMS	3
-#define VID_HARDWARE_QCAM_C	4
-#define VID_HARDWARE_PSEUDO	5
-#define VID_HARDWARE_SAA5249	6
-#define VID_HARDWARE_AZTECH	7
-#define VID_HARDWARE_SF16MI	8
-#define VID_HARDWARE_RTRACK	9
-#define VID_HARDWARE_ZOLTRIX	10
-#define VID_HARDWARE_SAA7146    11
-#define VID_HARDWARE_VIDEUM	12	/* Reserved for Winnov videum */
-#define VID_HARDWARE_RTRACK2	13
-#define VID_HARDWARE_PERMEDIA2	14	/* Reserved for Permedia2 */
-#define VID_HARDWARE_RIVA128	15	/* Reserved for RIVA 128 */
-#define VID_HARDWARE_PLANB	16	/* PowerMac motherboard video-in */
-#define VID_HARDWARE_BROADWAY	17	/* Broadway project */
-#define VID_HARDWARE_GEMTEK	18
-#define VID_HARDWARE_TYPHOON	19
-#define VID_HARDWARE_VINO	20	/* SGI Indy Vino */
-#define VID_HARDWARE_CADET	21	/* Cadet radio */
-#define VID_HARDWARE_TRUST	22	/* Trust FM Radio */
-#define VID_HARDWARE_TERRATEC	23	/* TerraTec ActiveRadio */
-#define VID_HARDWARE_CPIA	24
-#define VID_HARDWARE_ZR36120	25	/* Zoran ZR36120/ZR36125 */
-#define VID_HARDWARE_ZR36067	26	/* Zoran ZR36067/36060 */
-#define VID_HARDWARE_OV511	27
-#define VID_HARDWARE_ZR356700	28	/* Zoran 36700 series */
-#define VID_HARDWARE_W9966	29
-#define VID_HARDWARE_SE401	30	/* SE401 USB webcams */
-#define VID_HARDWARE_PWC	31	/* Philips webcams */
-#define VID_HARDWARE_MEYE	32	/* Sony Vaio MotionEye cameras */
-#define VID_HARDWARE_CPIA2	33
-#define VID_HARDWARE_VICAM      34
-#define VID_HARDWARE_SF16FMR2	35
-#define VID_HARDWARE_W9968CF	36
-#define VID_HARDWARE_SAA7114H   37
-#define VID_HARDWARE_SN9C102	38
-#define VID_HARDWARE_ARV	39
-
 #endif /* CONFIG_VIDEO_V4L1_COMPAT */
 
 #endif /* __LINUX_VIDEODEV_H */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 1f503e9..439474f 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -441,94 +441,6 @@
 #define V4L2_TC_USERBITS_8BITCHARS	0x0008
 /* The above is based on SMPTE timecodes */
 
-#ifdef __KERNEL__
-/*
- *	M P E G   C O M P R E S S I O N   P A R A M E T E R S
- *
- *  ### WARNING: This experimental MPEG compression API is obsolete.
- *  ###          It is replaced by the MPEG controls API.
- *  ###          This old API will disappear in the near future!
- *
- */
-enum v4l2_bitrate_mode {
-	V4L2_BITRATE_NONE = 0,	/* not specified */
-	V4L2_BITRATE_CBR,	/* constant bitrate */
-	V4L2_BITRATE_VBR,	/* variable bitrate */
-};
-struct v4l2_bitrate {
-	/* rates are specified in kbit/sec */
-	enum v4l2_bitrate_mode	mode;
-	__u32			min;
-	__u32			target;  /* use this one for CBR */
-	__u32			max;
-};
-
-enum v4l2_mpeg_streamtype {
-	V4L2_MPEG_SS_1,		/* MPEG-1 system stream */
-	V4L2_MPEG_PS_2,		/* MPEG-2 program stream */
-	V4L2_MPEG_TS_2,		/* MPEG-2 transport stream */
-	V4L2_MPEG_PS_DVD,      	/* MPEG-2 program stream with DVD header fixups */
-};
-enum v4l2_mpeg_audiotype {
-	V4L2_MPEG_AU_2_I,	/* MPEG-2 layer 1 */
-	V4L2_MPEG_AU_2_II,	/* MPEG-2 layer 2 */
-	V4L2_MPEG_AU_2_III,	/* MPEG-2 layer 3 */
-	V4L2_MPEG_AC3,		/* AC3 */
-	V4L2_MPEG_LPCM,		/* LPCM */
-};
-enum v4l2_mpeg_videotype {
-	V4L2_MPEG_VI_1,		/* MPEG-1 */
-	V4L2_MPEG_VI_2,		/* MPEG-2 */
-};
-enum v4l2_mpeg_aspectratio {
-	V4L2_MPEG_ASPECT_SQUARE = 1,   /* square pixel */
-	V4L2_MPEG_ASPECT_4_3    = 2,   /*  4 : 3       */
-	V4L2_MPEG_ASPECT_16_9   = 3,   /* 16 : 9       */
-	V4L2_MPEG_ASPECT_1_221  = 4,   /*  1 : 2,21    */
-};
-
-struct v4l2_mpeg_compression {
-	/* general */
-	enum v4l2_mpeg_streamtype	st_type;
-	struct v4l2_bitrate		st_bitrate;
-
-	/* transport streams */
-	__u16				ts_pid_pmt;
-	__u16				ts_pid_audio;
-	__u16				ts_pid_video;
-	__u16				ts_pid_pcr;
-
-	/* program stream */
-	__u16				ps_size;
-	__u16				reserved_1;    /* align */
-
-	/* audio */
-	enum v4l2_mpeg_audiotype	au_type;
-	struct v4l2_bitrate		au_bitrate;
-	__u32				au_sample_rate;
-	__u8                            au_pesid;
-	__u8                            reserved_2[3]; /* align */
-
-	/* video */
-	enum v4l2_mpeg_videotype	vi_type;
-	enum v4l2_mpeg_aspectratio	vi_aspect_ratio;
-	struct v4l2_bitrate		vi_bitrate;
-	__u32				vi_frame_rate;
-	__u16				vi_frames_per_gop;
-	__u16				vi_bframes_count;
-	__u8                            vi_pesid;
-	__u8                            reserved_3[3]; /* align */
-
-	/* misc flags */
-	__u32                           closed_gops:1;
-	__u32                           pulldown:1;
-	__u32                           reserved_4:30; /* align */
-
-	/* I don't expect the above being perfect yet ;) */
-	__u32				reserved_5[8];
-};
-#endif
-
 struct v4l2_jpegcompression
 {
 	int quality;
@@ -1420,10 +1332,6 @@
 #define VIDIOC_ENUM_FMT         _IOWR ('V',  2, struct v4l2_fmtdesc)
 #define VIDIOC_G_FMT		_IOWR ('V',  4, struct v4l2_format)
 #define VIDIOC_S_FMT		_IOWR ('V',  5, struct v4l2_format)
-#ifdef __KERNEL__
-#define VIDIOC_G_MPEGCOMP       _IOR  ('V',  6, struct v4l2_mpeg_compression)
-#define VIDIOC_S_MPEGCOMP     	_IOW  ('V',  7, struct v4l2_mpeg_compression)
-#endif
 #define VIDIOC_REQBUFS		_IOWR ('V',  8, struct v4l2_requestbuffers)
 #define VIDIOC_QUERYBUF		_IOWR ('V',  9, struct v4l2_buffer)
 #define VIDIOC_G_FBUF		_IOR  ('V', 10, struct v4l2_framebuffer)
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
new file mode 100644
index 0000000..14e1379
--- /dev/null
+++ b/include/linux/virtio.h
@@ -0,0 +1,110 @@
+#ifndef _LINUX_VIRTIO_H
+#define _LINUX_VIRTIO_H
+/* Everything a virtio driver needs to work with any particular virtio
+ * implementation. */
+#include <linux/types.h>
+#include <linux/scatterlist.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+
+/**
+ * virtqueue - a queue to register buffers for sending or receiving.
+ * @callback: the function to call when buffers are consumed (can be NULL).
+ *    If this returns false, callbacks are suppressed until vq_ops->restart
+ *    is called.
+ * @vdev: the virtio device this queue was created for.
+ * @vq_ops: the operations for this virtqueue (see below).
+ * @priv: a pointer for the virtqueue implementation to use.
+ */
+struct virtqueue
+{
+	bool (*callback)(struct virtqueue *vq);
+	struct virtio_device *vdev;
+	struct virtqueue_ops *vq_ops;
+	void *priv;
+};
+
+/**
+ * virtqueue_ops - operations for virtqueue abstraction layer
+ * @add_buf: expose buffer to other end
+ *	vq: the struct virtqueue we're talking about.
+ *	sg: the description of the buffer(s).
+ *	out_num: the number of sg readable by other side
+ *	in_num: the number of sg which are writable (after readable ones)
+ *	data: the token identifying the buffer.
+ *      Returns 0 or an error.
+ * @kick: update after add_buf
+ *	vq: the struct virtqueue
+ *	After one or more add_buf calls, invoke this to kick the other side.
+ * @get_buf: get the next used buffer
+ *	vq: the struct virtqueue we're talking about.
+ *	len: the length written into the buffer
+ *	Returns NULL or the "data" token handed to add_buf.
+ * @restart: restart callbacks after callback returned false.
+ *	vq: the struct virtqueue we're talking about.
+ *	This returns "false" (and doesn't re-enable) if there are pending
+ *	buffers in the queue, to avoid a race.
+ * @shutdown: "unadd" all buffers.
+ *	vq: the struct virtqueue we're talking about.
+ *	Remove everything from the queue.
+ *
+ * Locking rules are straightforward: the driver is responsible for
+ * locking.  No two operations may be invoked simultaneously.
+ *
+ * All operations can be called in any context.
+ */
+struct virtqueue_ops {
+	int (*add_buf)(struct virtqueue *vq,
+		       struct scatterlist sg[],
+		       unsigned int out_num,
+		       unsigned int in_num,
+		       void *data);
+
+	void (*kick)(struct virtqueue *vq);
+
+	void *(*get_buf)(struct virtqueue *vq, unsigned int *len);
+
+	bool (*restart)(struct virtqueue *vq);
+
+	void (*shutdown)(struct virtqueue *vq);
+};
+
+/**
+ * virtio_device - representation of a device using virtio
+ * @index: unique position on the virtio bus
+ * @dev: underlying device.
+ * @id: the device type identification (used to match it with a driver).
+ * @config: the configuration ops for this device.
+ * @priv: private pointer for the driver's use.
+ */
+struct virtio_device
+{
+	int index;
+	struct device dev;
+	struct virtio_device_id id;
+	struct virtio_config_ops *config;
+	void *priv;
+};
+
+int register_virtio_device(struct virtio_device *dev);
+void unregister_virtio_device(struct virtio_device *dev);
+
+/**
+ * virtio_driver - operations for a virtio I/O driver
+ * @driver: underlying device driver (populate name and owner).
+ * @id_table: the ids serviced by this driver.
+ * @probe: the function to call when a device is found.  Returns a token for
+ *    remove, or PTR_ERR().
+ * @remove: the function when a device is removed.
+ */
+struct virtio_driver {
+	struct device_driver driver;
+	const struct virtio_device_id *id_table;
+	int (*probe)(struct virtio_device *dev);
+	void (*remove)(struct virtio_device *dev);
+};
+
+int register_virtio_driver(struct virtio_driver *drv);
+void unregister_virtio_driver(struct virtio_driver *drv);
+#endif /* _LINUX_VIRTIO_H */
diff --git a/include/linux/virtio_9p.h b/include/linux/virtio_9p.h
new file mode 100644
index 0000000..8eff0b5
--- /dev/null
+++ b/include/linux/virtio_9p.h
@@ -0,0 +1,10 @@
+#ifndef _LINUX_VIRTIO_9P_H
+#define _LINUX_VIRTIO_9P_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio console */
+#define VIRTIO_ID_9P	9
+/* Maximum number of virtio channels per partition (1 for now) */
+#define MAX_9P_CHAN	1
+
+#endif /* _LINUX_VIRTIO_9P_H */
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h
new file mode 100644
index 0000000..7bd2bce
--- /dev/null
+++ b/include/linux/virtio_blk.h
@@ -0,0 +1,51 @@
+#ifndef _LINUX_VIRTIO_BLK_H
+#define _LINUX_VIRTIO_BLK_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio_block */
+#define VIRTIO_ID_BLOCK	2
+
+/* Feature bits */
+#define VIRTIO_CONFIG_BLK_F	0x40
+#define VIRTIO_BLK_F_BARRIER	1	/* Does host support barriers? */
+
+/* The capacity (in 512-byte sectors). */
+#define VIRTIO_CONFIG_BLK_F_CAPACITY	0x41
+/* The maximum segment size. */
+#define VIRTIO_CONFIG_BLK_F_SIZE_MAX	0x42
+/* The maximum number of segments. */
+#define VIRTIO_CONFIG_BLK_F_SEG_MAX	0x43
+
+/* These two define direction. */
+#define VIRTIO_BLK_T_IN		0
+#define VIRTIO_BLK_T_OUT	1
+
+/* This bit says it's a scsi command, not an actual read or write. */
+#define VIRTIO_BLK_T_SCSI_CMD	2
+
+/* Barrier before this op. */
+#define VIRTIO_BLK_T_BARRIER	0x80000000
+
+/* This is the first element of the read scatter-gather list. */
+struct virtio_blk_outhdr
+{
+	/* VIRTIO_BLK_T* */
+	__u32 type;
+	/* io priority. */
+	__u32 ioprio;
+	/* Sector (ie. 512 byte offset) */
+	__u64 sector;
+	/* Where to put reply. */
+	__u64 id;
+};
+
+#define VIRTIO_BLK_S_OK		0
+#define VIRTIO_BLK_S_IOERR	1
+#define VIRTIO_BLK_S_UNSUPP	2
+
+/* This is the first element of the write scatter-gather list */
+struct virtio_blk_inhdr
+{
+	unsigned char status;
+};
+#endif /* _LINUX_VIRTIO_BLK_H */
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
new file mode 100644
index 0000000..bcc0188
--- /dev/null
+++ b/include/linux/virtio_config.h
@@ -0,0 +1,111 @@
+#ifndef _LINUX_VIRTIO_CONFIG_H
+#define _LINUX_VIRTIO_CONFIG_H
+/* Virtio devices use a standardized configuration space to define their
+ * features and pass configuration information, but each implementation can
+ * store and access that space differently. */
+#include <linux/types.h>
+
+/* Status byte for guest to report progress, and synchronize config. */
+/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
+#define VIRTIO_CONFIG_S_ACKNOWLEDGE	1
+/* We have found a driver for the device. */
+#define VIRTIO_CONFIG_S_DRIVER		2
+/* Driver has used its parts of the config, and is happy */
+#define VIRTIO_CONFIG_S_DRIVER_OK	4
+/* We've given up on this device. */
+#define VIRTIO_CONFIG_S_FAILED		0x80
+
+/* Feature byte (actually 7 bits availabe): */
+/* Requirements/features of the virtio implementation. */
+#define VIRTIO_CONFIG_F_VIRTIO 1
+/* Requirements/features of the virtqueue (may have more than one). */
+#define VIRTIO_CONFIG_F_VIRTQUEUE 2
+
+#ifdef __KERNEL__
+struct virtio_device;
+
+/**
+ * virtio_config_ops - operations for configuring a virtio device
+ * @find: search for the next configuration field of the given type.
+ *	vdev: the virtio_device
+ *	type: the feature type
+ *	len: the (returned) length of the field if found.
+ *	Returns a token if found, or NULL.  Never returnes the same field twice
+ *	(ie. it's used up).
+ * @get: read the value of a configuration field after find().
+ *	vdev: the virtio_device
+ *	token: the token returned from find().
+ *	buf: the buffer to write the field value into.
+ *	len: the length of the buffer (given by find()).
+ *	Note that contents are conventionally little-endian.
+ * @set: write the value of a configuration field after find().
+ *	vdev: the virtio_device
+ *	token: the token returned from find().
+ *	buf: the buffer to read the field value from.
+ *	len: the length of the buffer (given by find()).
+ *	Note that contents are conventionally little-endian.
+ * @get_status: read the status byte
+ *	vdev: the virtio_device
+ *	Returns the status byte
+ * @set_status: write the status byte
+ *	vdev: the virtio_device
+ *	status: the new status byte
+ * @find_vq: find the first VIRTIO_CONFIG_F_VIRTQUEUE and create a virtqueue.
+ *	vdev: the virtio_device
+ *	callback: the virqtueue callback
+ *	Returns the new virtqueue or ERR_PTR().
+ * @del_vq: free a virtqueue found by find_vq().
+ */
+struct virtio_config_ops
+{
+	void *(*find)(struct virtio_device *vdev, u8 type, unsigned *len);
+	void (*get)(struct virtio_device *vdev, void *token,
+		    void *buf, unsigned len);
+	void (*set)(struct virtio_device *vdev, void *token,
+		    const void *buf, unsigned len);
+	u8 (*get_status)(struct virtio_device *vdev);
+	void (*set_status)(struct virtio_device *vdev, u8 status);
+	struct virtqueue *(*find_vq)(struct virtio_device *vdev,
+				     bool (*callback)(struct virtqueue *));
+	void (*del_vq)(struct virtqueue *vq);
+};
+
+/**
+ * virtio_config_val - get a single virtio config and mark it used.
+ * @config: the virtio config space
+ * @type: the type to search for.
+ * @val: a pointer to the value to fill in.
+ *
+ * Once used, the config type is marked with VIRTIO_CONFIG_F_USED so it can't
+ * be found again.  This version does endian conversion. */
+#define virtio_config_val(vdev, type, v) ({				\
+	int _err = __virtio_config_val((vdev),(type),(v),sizeof(*(v))); \
+									\
+	BUILD_BUG_ON(sizeof(*(v)) != 1 && sizeof(*(v)) != 2		\
+		     && sizeof(*(v)) != 4 && sizeof(*(v)) != 8);	\
+	if (!_err) {							\
+		switch (sizeof(*(v))) {					\
+		case 2: le16_to_cpus((__u16 *) v); break;		\
+		case 4: le32_to_cpus((__u32 *) v); break;		\
+		case 8: le64_to_cpus((__u64 *) v); break;		\
+		}							\
+	}								\
+	_err;								\
+})
+
+int __virtio_config_val(struct virtio_device *dev,
+			u8 type, void *val, size_t size);
+
+/**
+ * virtio_use_bit - helper to use a feature bit in a bitfield value.
+ * @dev: the virtio device
+ * @token: the token as returned from vdev->config->find().
+ * @len: the length of the field.
+ * @bitnum: the bit to test.
+ *
+ * If handed a NULL token, it returns false, otherwise returns bit status.
+ * If it's one, it sets the mirroring acknowledgement bit. */
+int virtio_use_bit(struct virtio_device *vdev,
+		   void *token, unsigned int len, unsigned int bitnum);
+#endif /* __KERNEL__ */
+#endif /* _LINUX_VIRTIO_CONFIG_H */
diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h
new file mode 100644
index 0000000..ed2d4ea
--- /dev/null
+++ b/include/linux/virtio_console.h
@@ -0,0 +1,12 @@
+#ifndef _LINUX_VIRTIO_CONSOLE_H
+#define _LINUX_VIRTIO_CONSOLE_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio console */
+#define VIRTIO_ID_CONSOLE	3
+
+#ifdef __KERNEL__
+int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int));
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_VIRTIO_CONSOLE_H */
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
new file mode 100644
index 0000000..ae469ae
--- /dev/null
+++ b/include/linux/virtio_net.h
@@ -0,0 +1,36 @@
+#ifndef _LINUX_VIRTIO_NET_H
+#define _LINUX_VIRTIO_NET_H
+#include <linux/virtio_config.h>
+
+/* The ID for virtio_net */
+#define VIRTIO_ID_NET	1
+
+/* The bitmap of config for virtio net */
+#define VIRTIO_CONFIG_NET_F	0x40
+#define VIRTIO_NET_F_NO_CSUM	0
+#define VIRTIO_NET_F_TSO4	1
+#define VIRTIO_NET_F_UFO	2
+#define VIRTIO_NET_F_TSO4_ECN	3
+#define VIRTIO_NET_F_TSO6	4
+
+/* The config defining mac address. */
+#define VIRTIO_CONFIG_NET_MAC_F	0x41
+
+/* This is the first element of the scatter-gather list.  If you don't
+ * specify GSO or CSUM features, you can simply ignore the header. */
+struct virtio_net_hdr
+{
+#define VIRTIO_NET_HDR_F_NEEDS_CSUM	1	// Use csum_start, csum_offset
+      __u8 flags;
+#define VIRTIO_NET_HDR_GSO_NONE		0	// Not a GSO frame
+#define VIRTIO_NET_HDR_GSO_TCPV4	1	// GSO frame, IPv4 TCP (TSO)
+/* FIXME: Do we need this?  If they said they can handle ECN, do they care? */
+#define VIRTIO_NET_HDR_GSO_TCPV4_ECN	2	// GSO frame, IPv4 TCP w/ ECN
+#define VIRTIO_NET_HDR_GSO_UDP		3	// GSO frame, IPv4 UDP (UFO)
+#define VIRTIO_NET_HDR_GSO_TCPV6	4	// GSO frame, IPv6 TCP
+      __u8 gso_type;
+      __u16 gso_size;
+      __u16 csum_start;
+      __u16 csum_offset;
+};
+#endif /* _LINUX_VIRTIO_NET_H */
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h
new file mode 100644
index 0000000..ac69e7bb
--- /dev/null
+++ b/include/linux/virtio_ring.h
@@ -0,0 +1,119 @@
+#ifndef _LINUX_VIRTIO_RING_H
+#define _LINUX_VIRTIO_RING_H
+/* An interface for efficient virtio implementation, currently for use by KVM
+ * and lguest, but hopefully others soon.  Do NOT change this since it will
+ * break existing servers and clients.
+ *
+ * This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * Copyright Rusty Russell IBM Corporation 2007. */
+#include <linux/types.h>
+
+/* This marks a buffer as continuing via the next field. */
+#define VRING_DESC_F_NEXT	1
+/* This marks a buffer as write-only (otherwise read-only). */
+#define VRING_DESC_F_WRITE	2
+
+/* This means don't notify other side when buffer added. */
+#define VRING_USED_F_NO_NOTIFY	1
+/* This means don't interrupt guest when buffer consumed. */
+#define VRING_AVAIL_F_NO_INTERRUPT	1
+
+/* Virtio ring descriptors: 16 bytes.  These can chain together via "next". */
+struct vring_desc
+{
+	/* Address (guest-physical). */
+	__u64 addr;
+	/* Length. */
+	__u32 len;
+	/* The flags as indicated above. */
+	__u16 flags;
+	/* We chain unused descriptors via this, too */
+	__u16 next;
+};
+
+struct vring_avail
+{
+	__u16 flags;
+	__u16 idx;
+	__u16 ring[];
+};
+
+/* u32 is used here for ids for padding reasons. */
+struct vring_used_elem
+{
+	/* Index of start of used descriptor chain. */
+	__u32 id;
+	/* Total length of the descriptor chain which was used (written to) */
+	__u32 len;
+};
+
+struct vring_used
+{
+	__u16 flags;
+	__u16 idx;
+	struct vring_used_elem ring[];
+};
+
+struct vring {
+	unsigned int num;
+
+	struct vring_desc *desc;
+
+	struct vring_avail *avail;
+
+	struct vring_used *used;
+};
+
+/* The standard layout for the ring is a continuous chunk of memory which looks
+ * like this.  The used fields will be aligned to a "num+1" boundary.
+ *
+ * struct vring
+ * {
+ *	// The actual descriptors (16 bytes each)
+ *	struct vring_desc desc[num];
+ *
+ *	// A ring of available descriptor heads with free-running index.
+ *	__u16 avail_flags;
+ *	__u16 avail_idx;
+ *	__u16 available[num];
+ *
+ *	// Padding so a correctly-chosen num value will cache-align used_idx.
+ *	char pad[sizeof(struct vring_desc) - sizeof(avail_flags)];
+ *
+ *	// A ring of used descriptor heads with free-running index.
+ *	__u16 used_flags;
+ *	__u16 used_idx;
+ *	struct vring_used_elem used[num];
+ * };
+ */
+static inline void vring_init(struct vring *vr, unsigned int num, void *p)
+{
+	vr->num = num;
+	vr->desc = p;
+	vr->avail = p + num*sizeof(struct vring);
+	vr->used = p + (num+1)*(sizeof(struct vring) + sizeof(__u16));
+}
+
+static inline unsigned vring_size(unsigned int num)
+{
+	return (num + 1) * (sizeof(struct vring_desc) + sizeof(__u16))
+		+ sizeof(__u32) + num * sizeof(struct vring_used_elem);
+}
+
+#ifdef __KERNEL__
+#include <linux/irqreturn.h>
+struct virtio_device;
+struct virtqueue;
+
+struct virtqueue *vring_new_virtqueue(unsigned int num,
+				      struct virtio_device *vdev,
+				      void *pages,
+				      void (*notify)(struct virtqueue *vq),
+				      bool (*callback)(struct virtqueue *vq));
+void vring_del_virtqueue(struct virtqueue *vq);
+
+irqreturn_t vring_interrupt(int irq, void *_vq);
+#endif /* __KERNEL__ */
+#endif /* _LINUX_VIRTIO_RING_H */
diff --git a/include/linux/vt.h b/include/linux/vt.h
index ba806e8..02c1c02 100644
--- a/include/linux/vt.h
+++ b/include/linux/vt.h
@@ -1,6 +1,18 @@
 #ifndef _LINUX_VT_H
 #define _LINUX_VT_H
 
+#ifdef __KERNEL__
+struct notifier_block;
+
+struct vt_notifier_param {
+	struct vc_data *vc;	/* VC on which the update happened */
+	unsigned int c;		/* Printed char */
+};
+
+extern int register_vt_notifier(struct notifier_block *nb);
+extern int unregister_vt_notifier(struct notifier_block *nb);
+#endif
+
 /*
  * These constants are also useful for user-level apps (e.g., VC
  * resizing).
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index ce6badc..7daafdc 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -8,6 +8,7 @@
 #include <linux/timer.h>
 #include <linux/linkage.h>
 #include <linux/bitops.h>
+#include <linux/lockdep.h>
 #include <asm/atomic.h>
 
 struct workqueue_struct;
@@ -28,6 +29,9 @@
 #define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
 	struct list_head entry;
 	work_func_t func;
+#ifdef CONFIG_LOCKDEP
+	struct lockdep_map lockdep_map;
+#endif
 };
 
 #define WORK_DATA_INIT()	ATOMIC_LONG_INIT(0)
@@ -41,10 +45,23 @@
 	struct work_struct work;
 };
 
+#ifdef CONFIG_LOCKDEP
+/*
+ * NB: because we have to copy the lockdep_map, setting _key
+ * here is required, otherwise it could get initialised to the
+ * copy of the lockdep_map!
+ */
+#define __WORK_INIT_LOCKDEP_MAP(n, k) \
+	.lockdep_map = STATIC_LOCKDEP_MAP_INIT(n, k),
+#else
+#define __WORK_INIT_LOCKDEP_MAP(n, k)
+#endif
+
 #define __WORK_INITIALIZER(n, f) {				\
 	.data = WORK_DATA_INIT(),				\
 	.entry	= { &(n).entry, &(n).entry },			\
 	.func = (f),						\
+	__WORK_INIT_LOCKDEP_MAP(#n, &(n))			\
 	}
 
 #define __DELAYED_WORK_INITIALIZER(n, f) {			\
@@ -76,12 +93,24 @@
  * assignment of the work data initializer allows the compiler
  * to generate better code.
  */
+#ifdef CONFIG_LOCKDEP
+#define INIT_WORK(_work, _func)						\
+	do {								\
+		static struct lock_class_key __key;			\
+									\
+		(_work)->data = (atomic_long_t) WORK_DATA_INIT();	\
+		lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0);\
+		INIT_LIST_HEAD(&(_work)->entry);			\
+		PREPARE_WORK((_work), (_func));				\
+	} while (0)
+#else
 #define INIT_WORK(_work, _func)						\
 	do {								\
 		(_work)->data = (atomic_long_t) WORK_DATA_INIT();	\
 		INIT_LIST_HEAD(&(_work)->entry);			\
 		PREPARE_WORK((_work), (_func));				\
 	} while (0)
+#endif
 
 #define INIT_DELAYED_WORK(_work, _func)				\
 	do {							\
@@ -118,9 +147,23 @@
 	clear_bit(WORK_STRUCT_PENDING, work_data_bits(work))
 
 
-extern struct workqueue_struct *__create_workqueue(const char *name,
-						    int singlethread,
-						    int freezeable);
+extern struct workqueue_struct *
+__create_workqueue_key(const char *name, int singlethread,
+		       int freezeable, struct lock_class_key *key);
+
+#ifdef CONFIG_LOCKDEP
+#define __create_workqueue(name, singlethread, freezeable)	\
+({								\
+	static struct lock_class_key __key;			\
+								\
+	__create_workqueue_key((name), (singlethread),		\
+			       (freezeable), &__key);		\
+})
+#else
+#define __create_workqueue(name, singlethread, freezeable)	\
+	__create_workqueue_key((name), (singlethread), (freezeable), NULL)
+#endif
+
 #define create_workqueue(name) __create_workqueue((name), 0, 0)
 #define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1)
 #define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0)
diff --git a/include/media/saa7146.h b/include/media/saa7146.h
index cd3ff2c..88b2b5a 100644
--- a/include/media/saa7146.h
+++ b/include/media/saa7146.h
@@ -12,6 +12,7 @@
 #include <asm/io.h>		/* for accessing devices */
 #include <linux/stringify.h>
 #include <linux/mutex.h>
+#include <linux/scatterlist.h>
 
 #include <linux/vmalloc.h>	/* for vmalloc() */
 #include <linux/mm.h>		/* for vmalloc_to_page() */
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index e75d5e6..c544c6f 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -94,7 +94,6 @@
 	char name[32];
 	int type;       /* v4l1 */
 	int type2;      /* v4l2 */
-	int hardware;
 	int minor;
 
 	int debug;	/* Activates debug level*/
@@ -272,10 +271,6 @@
 	int (*vidioc_s_crop)           (struct file *file, void *fh,
 					struct v4l2_crop *a);
 	/* Compression ioctls */
-	int (*vidioc_g_mpegcomp)       (struct file *file, void *fh,
-					struct v4l2_mpeg_compression *a);
-	int (*vidioc_s_mpegcomp)       (struct file *file, void *fh,
-					struct v4l2_mpeg_compression *a);
 	int (*vidioc_g_jpegcomp)       (struct file *file, void *fh,
 					struct v4l2_jpegcompression *a);
 	int (*vidioc_s_jpegcomp)       (struct file *file, void *fh,
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index 686425a..625346c 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -44,7 +44,7 @@
 do {  \
 	if ((p9_debug_level & level) == level) \
 		printk(KERN_NOTICE "-- %s (%d): " \
-		format , __FUNCTION__, current->pid , ## arg); \
+		format , __FUNCTION__, task_pid_nr(current) , ## arg); \
 } while (0)
 
 #define PRINT_FCALL_ERROR(s, fcall) P9_DPRINTK(P9_DEBUG_ERROR,   \
@@ -59,7 +59,7 @@
 #define P9_EPRINTK(level, format, arg...) \
 do { \
 	printk(level "9p: %s (%d): " \
-		format , __FUNCTION__, current->pid , ## arg); \
+		format , __FUNCTION__, task_pid_nr(current), ## arg); \
 } while (0)
 
 
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index ebfb96b..a8a9eb6 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -200,65 +200,224 @@
 #define HCI_LM_SECURE	0x0020
 
 /* -----  HCI Commands ---- */
-/* OGF & OCF values */
-
-/* Informational Parameters */
-#define OGF_INFO_PARAM	0x04
-
-#define OCF_READ_LOCAL_VERSION	0x0001
-struct hci_rp_read_loc_version {
-	__u8     status;
-	__u8     hci_ver;
-	__le16   hci_rev;
-	__u8     lmp_ver;
-	__le16   manufacturer;
-	__le16   lmp_subver;
+#define HCI_OP_INQUIRY			0x0401
+struct hci_cp_inquiry {
+	__u8     lap[3];
+	__u8     length;
+	__u8     num_rsp;
 } __attribute__ ((packed));
 
-#define OCF_READ_LOCAL_FEATURES	0x0003
-struct hci_rp_read_local_features {
-	__u8 status;
-	__u8 features[8];
+#define HCI_OP_INQUIRY_CANCEL		0x0402
+
+#define HCI_OP_EXIT_PERIODIC_INQ	0x0404
+
+#define HCI_OP_CREATE_CONN		0x0405
+struct hci_cp_create_conn {
+	bdaddr_t bdaddr;
+	__le16   pkt_type;
+	__u8     pscan_rep_mode;
+	__u8     pscan_mode;
+	__le16   clock_offset;
+	__u8     role_switch;
 } __attribute__ ((packed));
 
-#define OCF_READ_BUFFER_SIZE	0x0005
-struct hci_rp_read_buffer_size {
-	__u8     status;
-	__le16   acl_mtu;
-	__u8     sco_mtu;
-	__le16   acl_max_pkt;
-	__le16   sco_max_pkt;
+#define HCI_OP_DISCONNECT		0x0406
+struct hci_cp_disconnect {
+	__le16   handle;
+	__u8     reason;
 } __attribute__ ((packed));
 
-#define OCF_READ_BD_ADDR	0x0009
-struct hci_rp_read_bd_addr {
-	__u8     status;
+#define HCI_OP_ADD_SCO			0x0407
+struct hci_cp_add_sco {
+	__le16   handle;
+	__le16   pkt_type;
+} __attribute__ ((packed));
+
+#define HCI_OP_CREATE_CONN_CANCEL	0x0408
+struct hci_cp_create_conn_cancel {
 	bdaddr_t bdaddr;
 } __attribute__ ((packed));
 
-/* Host Controller and Baseband */
-#define OGF_HOST_CTL	0x03
-#define OCF_RESET		0x0003
-#define OCF_READ_AUTH_ENABLE	0x001F
-#define OCF_WRITE_AUTH_ENABLE	0x0020
-	#define AUTH_DISABLED		0x00
-	#define AUTH_ENABLED		0x01
+#define HCI_OP_ACCEPT_CONN_REQ		0x0409
+struct hci_cp_accept_conn_req {
+	bdaddr_t bdaddr;
+	__u8     role;
+} __attribute__ ((packed));
 
-#define OCF_READ_ENCRYPT_MODE	0x0021
-#define OCF_WRITE_ENCRYPT_MODE	0x0022
-	#define ENCRYPT_DISABLED	0x00
-	#define ENCRYPT_P2P		0x01
-	#define ENCRYPT_BOTH		0x02
+#define HCI_OP_REJECT_CONN_REQ		0x040a
+struct hci_cp_reject_conn_req {
+	bdaddr_t bdaddr;
+	__u8     reason;
+} __attribute__ ((packed));
 
-#define OCF_WRITE_CA_TIMEOUT  	0x0016	
-#define OCF_WRITE_PG_TIMEOUT  	0x0018
+#define HCI_OP_LINK_KEY_REPLY		0x040b
+struct hci_cp_link_key_reply {
+	bdaddr_t bdaddr;
+	__u8     link_key[16];
+} __attribute__ ((packed));
 
-#define OCF_WRITE_SCAN_ENABLE 	0x001A
-	#define SCAN_DISABLED		0x00
-	#define SCAN_INQUIRY		0x01
-	#define SCAN_PAGE		0x02
+#define HCI_OP_LINK_KEY_NEG_REPLY	0x040c
+struct hci_cp_link_key_neg_reply {
+	bdaddr_t bdaddr;
+} __attribute__ ((packed));
 
-#define OCF_SET_EVENT_FLT	0x0005
+#define HCI_OP_PIN_CODE_REPLY		0x040d
+struct hci_cp_pin_code_reply {
+	bdaddr_t bdaddr;
+	__u8     pin_len;
+	__u8     pin_code[16];
+} __attribute__ ((packed));
+
+#define HCI_OP_PIN_CODE_NEG_REPLY	0x040e
+struct hci_cp_pin_code_neg_reply {
+	bdaddr_t bdaddr;
+} __attribute__ ((packed));
+
+#define HCI_OP_CHANGE_CONN_PTYPE	0x040f
+struct hci_cp_change_conn_ptype {
+	__le16   handle;
+	__le16   pkt_type;
+} __attribute__ ((packed));
+
+#define HCI_OP_AUTH_REQUESTED		0x0411
+struct hci_cp_auth_requested {
+	__le16   handle;
+} __attribute__ ((packed));
+
+#define HCI_OP_SET_CONN_ENCRYPT		0x0413
+struct hci_cp_set_conn_encrypt {
+	__le16   handle;
+	__u8     encrypt;
+} __attribute__ ((packed));
+
+#define HCI_OP_CHANGE_CONN_LINK_KEY	0x0415
+struct hci_cp_change_conn_link_key {
+	__le16   handle;
+} __attribute__ ((packed));
+
+#define HCI_OP_REMOTE_NAME_REQ		0x0419
+struct hci_cp_remote_name_req {
+	bdaddr_t bdaddr;
+	__u8     pscan_rep_mode;
+	__u8     pscan_mode;
+	__le16   clock_offset;
+} __attribute__ ((packed));
+
+#define HCI_OP_REMOTE_NAME_REQ_CANCEL	0x041a
+struct hci_cp_remote_name_req_cancel {
+	bdaddr_t bdaddr;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_REMOTE_FEATURES	0x041b
+struct hci_cp_read_remote_features {
+	__le16   handle;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_REMOTE_EXT_FEATURES	0x041c
+struct hci_cp_read_remote_ext_features {
+	__le16   handle;
+	__u8     page;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_REMOTE_VERSION	0x041d
+struct hci_cp_read_remote_version {
+	__le16   handle;
+} __attribute__ ((packed));
+
+#define HCI_OP_SETUP_SYNC_CONN		0x0428
+struct hci_cp_setup_sync_conn {
+	__le16   handle;
+	__le32   tx_bandwidth;
+	__le32   rx_bandwidth;
+	__le16   max_latency;
+	__le16   voice_setting;
+	__u8     retrans_effort;
+	__le16   pkt_type;
+} __attribute__ ((packed));
+
+#define HCI_OP_ACCEPT_SYNC_CONN_REQ	0x0429
+struct hci_cp_accept_sync_conn_req {
+	bdaddr_t bdaddr;
+	__le32   tx_bandwidth;
+	__le32   rx_bandwidth;
+	__le16   max_latency;
+	__le16   content_format;
+	__u8     retrans_effort;
+	__le16   pkt_type;
+} __attribute__ ((packed));
+
+#define HCI_OP_REJECT_SYNC_CONN_REQ	0x042a
+struct hci_cp_reject_sync_conn_req {
+	bdaddr_t bdaddr;
+	__u8     reason;
+} __attribute__ ((packed));
+
+#define HCI_OP_SNIFF_MODE		0x0803
+struct hci_cp_sniff_mode {
+	__le16   handle;
+	__le16   max_interval;
+	__le16   min_interval;
+	__le16   attempt;
+	__le16   timeout;
+} __attribute__ ((packed));
+
+#define HCI_OP_EXIT_SNIFF_MODE		0x0804
+struct hci_cp_exit_sniff_mode {
+	__le16   handle;
+} __attribute__ ((packed));
+
+#define HCI_OP_ROLE_DISCOVERY		0x0809
+struct hci_cp_role_discovery {
+	__le16   handle;
+} __attribute__ ((packed));
+struct hci_rp_role_discovery {
+	__u8     status;
+	__le16   handle;
+	__u8     role;
+} __attribute__ ((packed));
+
+#define HCI_OP_SWITCH_ROLE		0x080b
+struct hci_cp_switch_role {
+	bdaddr_t bdaddr;
+	__u8     role;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LINK_POLICY		0x080c
+struct hci_cp_read_link_policy {
+	__le16   handle;
+} __attribute__ ((packed));
+struct hci_rp_read_link_policy {
+	__u8     status;
+	__le16   handle;
+	__le16   policy;
+} __attribute__ ((packed));
+
+#define HCI_OP_WRITE_LINK_POLICY	0x080d
+struct hci_cp_write_link_policy {
+	__le16   handle;
+	__le16   policy;
+} __attribute__ ((packed));
+struct hci_rp_write_link_policy {
+	__u8     status;
+	__le16   handle;
+} __attribute__ ((packed));
+
+#define HCI_OP_SNIFF_SUBRATE		0x0811
+struct hci_cp_sniff_subrate {
+	__le16   handle;
+	__le16   max_latency;
+	__le16   min_remote_timeout;
+	__le16   min_local_timeout;
+} __attribute__ ((packed));
+
+#define HCI_OP_SET_EVENT_MASK		0x0c01
+struct hci_cp_set_event_mask {
+	__u8     mask[8];
+} __attribute__ ((packed));
+
+#define HCI_OP_RESET			0x0c03
+
+#define HCI_OP_SET_EVENT_FLT		0x0c05
 struct hci_cp_set_event_flt {
 	__u8     flt_type;
 	__u8     cond_type;
@@ -279,29 +438,62 @@
 #define HCI_CONN_SETUP_AUTO_OFF	0x01
 #define HCI_CONN_SETUP_AUTO_ON	0x02
 
-#define OCF_READ_CLASS_OF_DEV	0x0023
-struct hci_rp_read_dev_class {
+#define HCI_OP_WRITE_LOCAL_NAME		0x0c13
+struct hci_cp_write_local_name {
+	__u8     name[248];
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LOCAL_NAME		0x0c14
+struct hci_rp_read_local_name {
+	__u8     status;
+	__u8     name[248];
+} __attribute__ ((packed));
+
+#define HCI_OP_WRITE_CA_TIMEOUT		0x0c16
+
+#define HCI_OP_WRITE_PG_TIMEOUT		0x0c18
+
+#define HCI_OP_WRITE_SCAN_ENABLE 	0x0c1a
+	#define SCAN_DISABLED		0x00
+	#define SCAN_INQUIRY		0x01
+	#define SCAN_PAGE		0x02
+
+#define HCI_OP_READ_AUTH_ENABLE		0x0c1f
+
+#define HCI_OP_WRITE_AUTH_ENABLE	0x0c20
+	#define AUTH_DISABLED		0x00
+	#define AUTH_ENABLED		0x01
+
+#define HCI_OP_READ_ENCRYPT_MODE	0x0c21
+
+#define HCI_OP_WRITE_ENCRYPT_MODE	0x0c22
+	#define ENCRYPT_DISABLED	0x00
+	#define ENCRYPT_P2P		0x01
+	#define ENCRYPT_BOTH		0x02
+
+#define HCI_OP_READ_CLASS_OF_DEV	0x0c23
+struct hci_rp_read_class_of_dev {
 	__u8     status;
 	__u8     dev_class[3];
 } __attribute__ ((packed));
 
-#define OCF_WRITE_CLASS_OF_DEV	0x0024
-struct hci_cp_write_dev_class {
+#define HCI_OP_WRITE_CLASS_OF_DEV	0x0c24
+struct hci_cp_write_class_of_dev {
 	__u8     dev_class[3];
 } __attribute__ ((packed));
 
-#define OCF_READ_VOICE_SETTING	0x0025
+#define HCI_OP_READ_VOICE_SETTING	0x0c25
 struct hci_rp_read_voice_setting {
 	__u8     status;
 	__le16   voice_setting;
 } __attribute__ ((packed));
 
-#define OCF_WRITE_VOICE_SETTING	0x0026
+#define HCI_OP_WRITE_VOICE_SETTING	0x0c26
 struct hci_cp_write_voice_setting {
 	__le16   voice_setting;
 } __attribute__ ((packed));
 
-#define OCF_HOST_BUFFER_SIZE	0x0033
+#define HCI_OP_HOST_BUFFER_SIZE		0x0c33
 struct hci_cp_host_buffer_size {
 	__le16   acl_mtu;
 	__u8     sco_mtu;
@@ -309,188 +501,55 @@
 	__le16   sco_max_pkt;
 } __attribute__ ((packed));
 
-/* Link Control */
-#define OGF_LINK_CTL	0x01 
-
-#define OCF_CREATE_CONN		0x0005
-struct hci_cp_create_conn {
-	bdaddr_t bdaddr;
-	__le16   pkt_type;
-	__u8     pscan_rep_mode;
-	__u8     pscan_mode;
-	__le16   clock_offset;
-	__u8     role_switch;
-} __attribute__ ((packed));
-
-#define OCF_CREATE_CONN_CANCEL	0x0008
-struct hci_cp_create_conn_cancel {
-	bdaddr_t bdaddr;
-} __attribute__ ((packed));
-
-#define OCF_ACCEPT_CONN_REQ	0x0009
-struct hci_cp_accept_conn_req {
-	bdaddr_t bdaddr;
-	__u8     role;
-} __attribute__ ((packed));
-
-#define OCF_REJECT_CONN_REQ	0x000a
-struct hci_cp_reject_conn_req {
-	bdaddr_t bdaddr;
-	__u8     reason;
-} __attribute__ ((packed));
-
-#define OCF_DISCONNECT	0x0006
-struct hci_cp_disconnect {
-	__le16   handle;
-	__u8     reason;
-} __attribute__ ((packed));
-
-#define OCF_ADD_SCO	0x0007
-struct hci_cp_add_sco {
-	__le16   handle;
-	__le16   pkt_type;
-} __attribute__ ((packed));
-
-#define OCF_INQUIRY		0x0001
-struct hci_cp_inquiry {
-	__u8     lap[3];
-	__u8     length;
-	__u8     num_rsp;
-} __attribute__ ((packed));
-
-#define OCF_INQUIRY_CANCEL	0x0002
-
-#define OCF_EXIT_PERIODIC_INQ	0x0004
-
-#define OCF_LINK_KEY_REPLY	0x000B
-struct hci_cp_link_key_reply {
-	bdaddr_t bdaddr;
-	__u8     link_key[16];
-} __attribute__ ((packed));
-
-#define OCF_LINK_KEY_NEG_REPLY	0x000C
-struct hci_cp_link_key_neg_reply {
-	bdaddr_t bdaddr;
-} __attribute__ ((packed));
-
-#define OCF_PIN_CODE_REPLY	0x000D
-struct hci_cp_pin_code_reply {
-	bdaddr_t bdaddr;
-	__u8     pin_len;
-	__u8     pin_code[16];
-} __attribute__ ((packed));
-
-#define OCF_PIN_CODE_NEG_REPLY	0x000E
-struct hci_cp_pin_code_neg_reply {
-	bdaddr_t bdaddr;
-} __attribute__ ((packed));
-
-#define OCF_CHANGE_CONN_PTYPE	0x000F
-struct hci_cp_change_conn_ptype {
-	__le16   handle;
-	__le16   pkt_type;
-} __attribute__ ((packed));
-
-#define OCF_AUTH_REQUESTED	0x0011
-struct hci_cp_auth_requested {
-	__le16   handle;
-} __attribute__ ((packed));
-
-#define OCF_SET_CONN_ENCRYPT	0x0013
-struct hci_cp_set_conn_encrypt {
-	__le16   handle;
-	__u8     encrypt;
-} __attribute__ ((packed));
-
-#define OCF_CHANGE_CONN_LINK_KEY 0x0015
-struct hci_cp_change_conn_link_key {
-	__le16   handle;
-} __attribute__ ((packed));
-
-#define OCF_READ_REMOTE_FEATURES 0x001B
-struct hci_cp_read_remote_features {
-	__le16   handle;
-} __attribute__ ((packed));
-
-#define OCF_READ_REMOTE_VERSION 0x001D
-struct hci_cp_read_remote_version {
-	__le16   handle;
-} __attribute__ ((packed));
-
-/* Link Policy */
-#define OGF_LINK_POLICY	0x02   
-
-#define OCF_SNIFF_MODE		0x0003
-struct hci_cp_sniff_mode {
-	__le16   handle;
-	__le16   max_interval;
-	__le16   min_interval;
-	__le16   attempt;
-	__le16   timeout;
-} __attribute__ ((packed));
-
-#define OCF_EXIT_SNIFF_MODE	0x0004
-struct hci_cp_exit_sniff_mode {
-	__le16   handle;
-} __attribute__ ((packed));
-
-#define OCF_ROLE_DISCOVERY	0x0009
-struct hci_cp_role_discovery {
-	__le16   handle;
-} __attribute__ ((packed));
-struct hci_rp_role_discovery {
+#define HCI_OP_READ_LOCAL_VERSION	0x1001
+struct hci_rp_read_local_version {
 	__u8     status;
-	__le16   handle;
-	__u8     role;
+	__u8     hci_ver;
+	__le16   hci_rev;
+	__u8     lmp_ver;
+	__le16   manufacturer;
+	__le16   lmp_subver;
 } __attribute__ ((packed));
 
-#define OCF_READ_LINK_POLICY	0x000C
-struct hci_cp_read_link_policy {
-	__le16   handle;
-} __attribute__ ((packed));
-struct hci_rp_read_link_policy {
+#define HCI_OP_READ_LOCAL_COMMANDS	0x1002
+struct hci_rp_read_local_commands {
 	__u8     status;
-	__le16   handle;
-	__le16   policy;
+	__u8     commands[64];
 } __attribute__ ((packed));
 
-#define OCF_SWITCH_ROLE		0x000B
-struct hci_cp_switch_role {
+#define HCI_OP_READ_LOCAL_FEATURES	0x1003
+struct hci_rp_read_local_features {
+	__u8     status;
+	__u8     features[8];
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LOCAL_EXT_FEATURES	0x1004
+struct hci_rp_read_local_ext_features {
+	__u8     status;
+	__u8     page;
+	__u8     max_page;
+	__u8     features[8];
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_BUFFER_SIZE		0x1005
+struct hci_rp_read_buffer_size {
+	__u8     status;
+	__le16   acl_mtu;
+	__u8     sco_mtu;
+	__le16   acl_max_pkt;
+	__le16   sco_max_pkt;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_BD_ADDR		0x1009
+struct hci_rp_read_bd_addr {
+	__u8     status;
 	bdaddr_t bdaddr;
-	__u8     role;
 } __attribute__ ((packed));
 
-#define OCF_WRITE_LINK_POLICY	0x000D
-struct hci_cp_write_link_policy {
-	__le16   handle;
-	__le16   policy;
-} __attribute__ ((packed));
-struct hci_rp_write_link_policy {
-	__u8     status;
-	__le16   handle;
-} __attribute__ ((packed));
-
-#define OCF_SNIFF_SUBRATE	0x0011
-struct hci_cp_sniff_subrate {
-	__le16   handle;
-	__le16   max_latency;
-	__le16   min_remote_timeout;
-	__le16   min_local_timeout;
-} __attribute__ ((packed));
-
-/* Status params */
-#define OGF_STATUS_PARAM	0x05
-
-/* Testing commands */
-#define OGF_TESTING_CMD		0x3E
-
-/* Vendor specific commands */
-#define OGF_VENDOR_CMD		0x3F
-
 /* ---- HCI Events ---- */
-#define HCI_EV_INQUIRY_COMPLETE	0x01
+#define HCI_EV_INQUIRY_COMPLETE		0x01
 
-#define HCI_EV_INQUIRY_RESULT	0x02
+#define HCI_EV_INQUIRY_RESULT		0x02
 struct inquiry_info {
 	bdaddr_t bdaddr;
 	__u8     pscan_rep_mode;
@@ -500,6 +559,149 @@
 	__le16   clock_offset;
 } __attribute__ ((packed));
 
+#define HCI_EV_CONN_COMPLETE		0x03
+struct hci_ev_conn_complete {
+	__u8     status;
+	__le16   handle;
+	bdaddr_t bdaddr;
+	__u8     link_type;
+	__u8     encr_mode;
+} __attribute__ ((packed));
+
+#define HCI_EV_CONN_REQUEST		0x04
+struct hci_ev_conn_request {
+	bdaddr_t bdaddr;
+	__u8     dev_class[3];
+	__u8     link_type;
+} __attribute__ ((packed));
+
+#define HCI_EV_DISCONN_COMPLETE		0x05
+struct hci_ev_disconn_complete {
+	__u8     status;
+	__le16   handle;
+	__u8     reason;
+} __attribute__ ((packed));
+
+#define HCI_EV_AUTH_COMPLETE		0x06
+struct hci_ev_auth_complete {
+	__u8     status;
+	__le16   handle;
+} __attribute__ ((packed));
+
+#define HCI_EV_REMOTE_NAME		0x07
+struct hci_ev_remote_name {
+	__u8     status;
+	bdaddr_t bdaddr;
+	__u8     name[248];
+} __attribute__ ((packed));
+
+#define HCI_EV_ENCRYPT_CHANGE		0x08
+struct hci_ev_encrypt_change {
+	__u8     status;
+	__le16   handle;
+	__u8     encrypt;
+} __attribute__ ((packed));
+
+#define HCI_EV_CHANGE_LINK_KEY_COMPLETE	0x09
+struct hci_ev_change_link_key_complete {
+	__u8     status;
+	__le16   handle;
+} __attribute__ ((packed));
+
+#define HCI_EV_REMOTE_FEATURES		0x0b
+struct hci_ev_remote_features {
+	__u8     status;
+	__le16   handle;
+	__u8     features[8];
+} __attribute__ ((packed));
+
+#define HCI_EV_REMOTE_VERSION		0x0c
+struct hci_ev_remote_version {
+	__u8     status;
+	__le16   handle;
+	__u8     lmp_ver;
+	__le16   manufacturer;
+	__le16   lmp_subver;
+} __attribute__ ((packed));
+
+#define HCI_EV_QOS_SETUP_COMPLETE	0x0d
+struct hci_qos {
+	__u8     service_type;
+	__u32    token_rate;
+	__u32    peak_bandwidth;
+	__u32    latency;
+	__u32    delay_variation;
+} __attribute__ ((packed));
+struct hci_ev_qos_setup_complete {
+	__u8     status;
+	__le16   handle;
+	struct   hci_qos qos;
+} __attribute__ ((packed));
+
+#define HCI_EV_CMD_COMPLETE		0x0e
+struct hci_ev_cmd_complete {
+	__u8     ncmd;
+	__le16   opcode;
+} __attribute__ ((packed));
+
+#define HCI_EV_CMD_STATUS		0x0f
+struct hci_ev_cmd_status {
+	__u8     status;
+	__u8     ncmd;
+	__le16   opcode;
+} __attribute__ ((packed));
+
+#define HCI_EV_ROLE_CHANGE		0x12
+struct hci_ev_role_change {
+	__u8     status;
+	bdaddr_t bdaddr;
+	__u8     role;
+} __attribute__ ((packed));
+
+#define HCI_EV_NUM_COMP_PKTS		0x13
+struct hci_ev_num_comp_pkts {
+	__u8     num_hndl;
+	/* variable length part */
+} __attribute__ ((packed));
+
+#define HCI_EV_MODE_CHANGE		0x14
+struct hci_ev_mode_change {
+	__u8     status;
+	__le16   handle;
+	__u8     mode;
+	__le16   interval;
+} __attribute__ ((packed));
+
+#define HCI_EV_PIN_CODE_REQ		0x16
+struct hci_ev_pin_code_req {
+	bdaddr_t bdaddr;
+} __attribute__ ((packed));
+
+#define HCI_EV_LINK_KEY_REQ		0x17
+struct hci_ev_link_key_req {
+	bdaddr_t bdaddr;
+} __attribute__ ((packed));
+
+#define HCI_EV_LINK_KEY_NOTIFY		0x18
+struct hci_ev_link_key_notify {
+	bdaddr_t bdaddr;
+	__u8     link_key[16];
+	__u8     key_type;
+} __attribute__ ((packed));
+
+#define HCI_EV_CLOCK_OFFSET		0x1c
+struct hci_ev_clock_offset {
+	__u8     status;
+	__le16   handle;
+	__le16   clock_offset;
+} __attribute__ ((packed));
+
+#define HCI_EV_PSCAN_REP_MODE		0x20
+struct hci_ev_pscan_rep_mode {
+	bdaddr_t bdaddr;
+	__u8     pscan_rep_mode;
+} __attribute__ ((packed));
+
 #define HCI_EV_INQUIRY_RESULT_WITH_RSSI	0x22
 struct inquiry_info_with_rssi {
 	bdaddr_t bdaddr;
@@ -519,7 +721,49 @@
 	__s8     rssi;
 } __attribute__ ((packed));
 
-#define HCI_EV_EXTENDED_INQUIRY_RESULT	0x2F
+#define HCI_EV_REMOTE_EXT_FEATURES	0x23
+struct hci_ev_remote_ext_features {
+	__u8     status;
+	__le16   handle;
+	__u8     page;
+	__u8     max_page;
+	__u8     features[8];
+} __attribute__ ((packed));
+
+#define HCI_EV_SYNC_CONN_COMPLETE	0x2c
+struct hci_ev_sync_conn_complete {
+	__u8     status;
+	__le16   handle;
+	bdaddr_t bdaddr;
+	__u8     link_type;
+	__u8     tx_interval;
+	__u8     retrans_window;
+	__le16   rx_pkt_len;
+	__le16   tx_pkt_len;
+	__u8     air_mode;
+} __attribute__ ((packed));
+
+#define HCI_EV_SYNC_CONN_CHANGED	0x2d
+struct hci_ev_sync_conn_changed {
+	__u8     status;
+	__le16   handle;
+	__u8     tx_interval;
+	__u8     retrans_window;
+	__le16   rx_pkt_len;
+	__le16   tx_pkt_len;
+} __attribute__ ((packed));
+
+#define HCI_EV_SNIFF_SUBRATE		0x2e
+struct hci_ev_sniff_subrate {
+	__u8     status;
+	__le16   handle;
+	__le16   max_tx_latency;
+	__le16   max_rx_latency;
+	__le16   max_remote_timeout;
+	__le16   max_local_timeout;
+} __attribute__ ((packed));
+
+#define HCI_EV_EXTENDED_INQUIRY_RESULT	0x2f
 struct extended_inquiry_info {
 	bdaddr_t bdaddr;
 	__u8     pscan_rep_mode;
@@ -530,160 +774,14 @@
 	__u8     data[240];
 } __attribute__ ((packed));
 
-#define HCI_EV_CONN_COMPLETE 	0x03
-struct hci_ev_conn_complete {
-	__u8     status;
-	__le16   handle;
-	bdaddr_t bdaddr;
-	__u8     link_type;
-	__u8     encr_mode;
-} __attribute__ ((packed));
-
-#define HCI_EV_CONN_REQUEST	0x04
-struct hci_ev_conn_request {
-	bdaddr_t bdaddr;
-	__u8     dev_class[3];
-	__u8     link_type;
-} __attribute__ ((packed));
-
-#define HCI_EV_DISCONN_COMPLETE	0x05
-struct hci_ev_disconn_complete {
-	__u8     status;
-	__le16   handle;
-	__u8     reason;
-} __attribute__ ((packed));
-
-#define HCI_EV_AUTH_COMPLETE	0x06
-struct hci_ev_auth_complete {
-	__u8     status;
-	__le16   handle;
-} __attribute__ ((packed));
-
-#define HCI_EV_ENCRYPT_CHANGE	0x08
-struct hci_ev_encrypt_change {
-	__u8     status;
-	__le16   handle;
-	__u8     encrypt;
-} __attribute__ ((packed));
-
-#define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE	0x09
-struct hci_ev_change_conn_link_key_complete {
-	__u8     status;
-	__le16   handle;
-} __attribute__ ((packed));
-
-#define HCI_EV_QOS_SETUP_COMPLETE	0x0D
-struct hci_qos {
-	__u8     service_type;
-	__u32    token_rate;
-	__u32    peak_bandwidth;
-	__u32    latency;
-	__u32    delay_variation;
-} __attribute__ ((packed));
-struct hci_ev_qos_setup_complete {
-	__u8     status;
-	__le16   handle;
-	struct   hci_qos qos;
-} __attribute__ ((packed));
-
-#define HCI_EV_CMD_COMPLETE 	0x0E
-struct hci_ev_cmd_complete {
-	__u8     ncmd;
-	__le16   opcode;
-} __attribute__ ((packed));
-
-#define HCI_EV_CMD_STATUS 	0x0F
-struct hci_ev_cmd_status {
-	__u8     status;
-	__u8     ncmd;
-	__le16   opcode;
-} __attribute__ ((packed));
-
-#define HCI_EV_NUM_COMP_PKTS	0x13
-struct hci_ev_num_comp_pkts {
-	__u8     num_hndl;
-	/* variable length part */
-} __attribute__ ((packed));
-
-#define HCI_EV_ROLE_CHANGE	0x12
-struct hci_ev_role_change {
-	__u8     status;
-	bdaddr_t bdaddr;
-	__u8     role;
-} __attribute__ ((packed));
-
-#define HCI_EV_MODE_CHANGE	0x14
-struct hci_ev_mode_change {
-	__u8     status;
-	__le16   handle;
-	__u8     mode;
-	__le16   interval;
-} __attribute__ ((packed));
-
-#define HCI_EV_PIN_CODE_REQ	0x16
-struct hci_ev_pin_code_req {
-	bdaddr_t bdaddr;
-} __attribute__ ((packed));
-
-#define HCI_EV_LINK_KEY_REQ	0x17
-struct hci_ev_link_key_req {
-	bdaddr_t bdaddr;
-} __attribute__ ((packed));
-
-#define HCI_EV_LINK_KEY_NOTIFY	0x18
-struct hci_ev_link_key_notify {
-	bdaddr_t bdaddr;
-	__u8	 link_key[16];
-	__u8	 key_type;
-} __attribute__ ((packed));
-
-#define HCI_EV_REMOTE_FEATURES	0x0B
-struct hci_ev_remote_features {
-	__u8     status;
-	__le16   handle;
-	__u8     features[8];
-} __attribute__ ((packed));
-
-#define HCI_EV_REMOTE_VERSION	0x0C
-struct hci_ev_remote_version {
-	__u8     status;
-	__le16   handle;
-	__u8     lmp_ver;
-	__le16   manufacturer;
-	__le16   lmp_subver;
-} __attribute__ ((packed));
-
-#define HCI_EV_CLOCK_OFFSET	0x01C
-struct hci_ev_clock_offset {
-	__u8     status;
-	__le16   handle;
-	__le16   clock_offset;
-} __attribute__ ((packed));
-
-#define HCI_EV_PSCAN_REP_MODE	0x20
-struct hci_ev_pscan_rep_mode {
-	bdaddr_t bdaddr;
-	__u8     pscan_rep_mode;
-} __attribute__ ((packed));
-
-#define HCI_EV_SNIFF_SUBRATE	0x2E
-struct hci_ev_sniff_subrate {
-	__u8     status;
-	__le16   handle;
-	__le16   max_tx_latency;
-	__le16   max_rx_latency;
-	__le16   max_remote_timeout;
-	__le16   max_local_timeout;
-} __attribute__ ((packed));
-
 /* Internal events generated by Bluetooth stack */
-#define HCI_EV_STACK_INTERNAL	0xFD
+#define HCI_EV_STACK_INTERNAL	0xfd
 struct hci_ev_stack_internal {
 	__u16    type;
 	__u8     data[0];
 } __attribute__ ((packed));
 
-#define HCI_EV_SI_DEVICE  	0x01
+#define HCI_EV_SI_DEVICE	0x01
 struct hci_ev_si_device {
 	__u16    event;
 	__u16    dev_id;
@@ -704,40 +802,40 @@
 #define HCI_SCO_HDR_SIZE     3
 
 struct hci_command_hdr {
-	__le16 	opcode;		/* OCF & OGF */
+	__le16	opcode;		/* OCF & OGF */
 	__u8 	plen;
 } __attribute__ ((packed));
 
 struct hci_event_hdr {
-	__u8 	evt;
-	__u8 	plen;
+	__u8	evt;
+	__u8	plen;
 } __attribute__ ((packed));
 
 struct hci_acl_hdr {
-	__le16 	handle;		/* Handle & Flags(PB, BC) */
-	__le16 	dlen;
+	__le16	handle;		/* Handle & Flags(PB, BC) */
+	__le16	dlen;
 } __attribute__ ((packed));
 
 struct hci_sco_hdr {
-	__le16 	handle;
-	__u8 	dlen;
+	__le16	handle;
+	__u8	dlen;
 } __attribute__ ((packed));
 
 #ifdef __KERNEL__
 #include <linux/skbuff.h>
 static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb)
 {
-	return (struct hci_event_hdr *)skb->data;
+	return (struct hci_event_hdr *) skb->data;
 }
 
 static inline struct hci_acl_hdr *hci_acl_hdr(const struct sk_buff *skb)
 {
-	return (struct hci_acl_hdr *)skb->data;
+	return (struct hci_acl_hdr *) skb->data;
 }
 
 static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb)
 {
-	return (struct hci_sco_hdr *)skb->data;
+	return (struct hci_sco_hdr *) skb->data;
 }
 #endif
 
@@ -771,13 +869,13 @@
 struct hci_filter {
 	unsigned long type_mask;
 	unsigned long event_mask[2];
-	__le16   opcode;
+	__le16 opcode;
 };
 
 struct hci_ufilter {
-	__u32   type_mask;
-	__u32   event_mask[2];
-	__le16   opcode;
+	__u32  type_mask;
+	__u32  event_mask[2];
+	__le16 opcode;
 };
 
 #define HCI_FLT_TYPE_BITS	31
@@ -825,15 +923,15 @@
 struct hci_conn_info {
 	__u16    handle;
 	bdaddr_t bdaddr;
-	__u8	 type;
-	__u8	 out;
-	__u16	 state;
-	__u32	 link_mode;
+	__u8     type;
+	__u8     out;
+	__u16    state;
+	__u32    link_mode;
 };
 
 struct hci_dev_req {
-	__u16 dev_id;
-	__u32 dev_opt;
+	__u16  dev_id;
+	__u32  dev_opt;
 };
 
 struct hci_dev_list_req {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 8f67c8a..ea13baa 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -71,7 +71,10 @@
 	__u16		id;
 	__u8		type;
 	bdaddr_t	bdaddr;
+	__u8		dev_name[248];
+	__u8		dev_class[3];
 	__u8		features[8];
+	__u8		commands[64];
 	__u8		hci_ver;
 	__u16		hci_rev;
 	__u16		manufacturer;
@@ -310,10 +313,12 @@
 void hci_acl_connect(struct hci_conn *conn);
 void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
 void hci_add_sco(struct hci_conn *conn, __u16 handle);
+void hci_setup_sync(struct hci_conn *conn, __u16 handle);
 
 struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
-int    hci_conn_del(struct hci_conn *conn);
-void   hci_conn_hash_flush(struct hci_dev *hdev);
+int hci_conn_del(struct hci_conn *conn);
+void hci_conn_hash_flush(struct hci_dev *hdev);
+void hci_conn_check_pending(struct hci_dev *hdev);
 
 struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
 int hci_conn_auth(struct hci_conn *conn);
@@ -617,11 +622,11 @@
 int hci_register_notifier(struct notifier_block *nb);
 int hci_unregister_notifier(struct notifier_block *nb);
 
-int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param);
+int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
 int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
 int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
 
-void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf);
+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
 
 void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
 
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 70e70f5d3..73e115b 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -29,7 +29,8 @@
 #define L2CAP_DEFAULT_MTU	672
 #define L2CAP_DEFAULT_FLUSH_TO	0xFFFF
 
-#define L2CAP_CONN_TIMEOUT	(HZ * 40)
+#define L2CAP_CONN_TIMEOUT	(40000) /* 40 seconds */
+#define L2CAP_INFO_TIMEOUT	(4000)  /*  4 seconds */
 
 /* L2CAP socket address */
 struct sockaddr_l2 {
@@ -148,6 +149,19 @@
 
 #define L2CAP_CONF_MAX_SIZE	22
 
+struct l2cap_conf_rfc {
+	__u8       mode;
+	__u8       txwin_size;
+	__u8       max_transmit;
+	__le16     retrans_timeout;
+	__le16     monitor_timeout;
+	__le16     max_pdu_size;
+} __attribute__ ((packed));
+
+#define L2CAP_MODE_BASIC	0x00
+#define L2CAP_MODE_RETRANS	0x01
+#define L2CAP_MODE_FLOWCTL	0x02
+
 struct l2cap_disconn_req {
 	__le16     dcid;
 	__le16     scid;
@@ -160,7 +174,6 @@
 
 struct l2cap_info_req {
 	__le16      type;
-	__u8        data[0];
 } __attribute__ ((packed));
 
 struct l2cap_info_rsp {
@@ -192,6 +205,13 @@
 
 	unsigned int	mtu;
 
+	__u32		feat_mask;
+
+	__u8		info_state;
+	__u8		info_ident;
+
+	struct timer_list info_timer;
+
 	spinlock_t	lock;
 
 	struct sk_buff *rx_skb;
@@ -202,6 +222,9 @@
 	struct l2cap_chan_list chan_list;
 };
 
+#define L2CAP_INFO_CL_MTU_REQ_SENT	0x01
+#define L2CAP_INFO_FEAT_MASK_REQ_SENT	0x02
+
 /* ----- L2CAP channel and socket info ----- */
 #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
 
@@ -221,7 +244,6 @@
 	__u8		conf_len;
 	__u8		conf_state;
 	__u8		conf_retry;
-	__u16		conf_mtu;
 
 	__u8		ident;
 
@@ -232,10 +254,11 @@
 	struct sock		*prev_c;
 };
 
-#define L2CAP_CONF_REQ_SENT    0x01
-#define L2CAP_CONF_INPUT_DONE  0x02
-#define L2CAP_CONF_OUTPUT_DONE 0x04
-#define L2CAP_CONF_MAX_RETRIES 2
+#define L2CAP_CONF_REQ_SENT	0x01
+#define L2CAP_CONF_INPUT_DONE	0x02
+#define L2CAP_CONF_OUTPUT_DONE	0x04
+
+#define L2CAP_CONF_MAX_RETRIES	2
 
 void l2cap_load(void);
 
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 911c2cd..954def4 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -39,8 +39,13 @@
 	struct inet_frags_ctl	*ctl;
 
 	unsigned int		(*hashfn)(struct inet_frag_queue *);
+	void			(*constructor)(struct inet_frag_queue *q,
+						void *arg);
 	void			(*destructor)(struct inet_frag_queue *);
 	void			(*skb_free)(struct sk_buff *);
+	int			(*match)(struct inet_frag_queue *q,
+						void *arg);
+	void			(*frag_expire)(unsigned long data);
 };
 
 void inet_frags_init(struct inet_frags *);
@@ -50,6 +55,8 @@
 void inet_frag_destroy(struct inet_frag_queue *q,
 				struct inet_frags *f, int *work);
 int inet_frag_evictor(struct inet_frags *f);
+struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key,
+		unsigned int hash);
 
 static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
 {
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index cc796cb..ae328b6 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -377,6 +377,17 @@
 				   prefixlen);
 }
 
+struct inet_frag_queue;
+
+struct ip6_create_arg {
+	__be32 id;
+	struct in6_addr *src;
+	struct in6_addr *dst;
+};
+
+void ip6_frag_init(struct inet_frag_queue *q, void *a);
+int ip6_frag_match(struct inet_frag_queue *q, void *a);
+
 static inline int ipv6_addr_any(const struct in6_addr *a)
 {
 	return ((a->s6_addr32[0] | a->s6_addr32[1] | 
diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h
index cf80c1a..32c385d 100644
--- a/include/net/irda/irttp.h
+++ b/include/net/irda/irttp.h
@@ -56,7 +56,7 @@
 
 /* Receive queue sizes */
 /* Minimum of credit that the peer should hold.
- * If the peer has less credits than 9 frames, we will explicitely send
+ * If the peer has less credits than 9 frames, we will explicitly send
  * him some credits (through irttp_give_credit() and a specific frame).
  * Note that when we give credits it's likely that it won't be sent in
  * this LAP window, but in the next one. So, we make sure that the peer
@@ -66,7 +66,7 @@
 /* This is the default maximum number of credits held by the peer, so the
  * default maximum number of frames he can send us before needing flow
  * control answer from us (this may be negociated differently at TSAP setup).
- * We want to minimise the number of times we have to explicitely send some
+ * We want to minimise the number of times we have to explicitly send some
  * credit to the peer, hoping we can piggyback it on the return data. In
  * particular, it doesn't make sense for us to send credit more than once
  * per LAP window.
diff --git a/include/net/scm.h b/include/net/scm.h
index 423cb1d..06df126 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -4,6 +4,8 @@
 #include <linux/limits.h>
 #include <linux/net.h>
 #include <linux/security.h>
+#include <linux/pid.h>
+#include <linux/nsproxy.h>
 
 /* Well, we should have at least one descriptor open
  * to accept passed FDs 8)
@@ -54,7 +56,7 @@
 	struct task_struct *p = current;
 	scm->creds.uid = p->uid;
 	scm->creds.gid = p->gid;
-	scm->creds.pid = p->tgid;
+	scm->creds.pid = task_tgid_vnr(p);
 	scm->fp = NULL;
 	scm->seq = 0;
 	unix_get_peersec_dgram(sock, scm);
diff --git a/include/net/sock.h b/include/net/sock.h
index 453c79d..43fc3fa 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -905,16 +905,6 @@
 }
 
 /**
- * 	sk_filter_rcu_free: Free a socket filter
- *	@rcu: rcu_head that contains the sk_filter to free
- */
-static inline void sk_filter_rcu_free(struct rcu_head *rcu)
-{
-	struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
-	kfree(fp);
-}
-
-/**
  *	sk_filter_release: Release a socket filter
  *	@sk: socket
  *	@fp: filter to remove
@@ -922,14 +912,18 @@
  *	Remove a filter from a socket and release its resources.
  */
 
-static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp)
+static inline void sk_filter_release(struct sk_filter *fp)
+{
+	if (atomic_dec_and_test(&fp->refcnt))
+		kfree(fp);
+}
+
+static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)
 {
 	unsigned int size = sk_filter_len(fp);
 
 	atomic_sub(size, &sk->sk_omem_alloc);
-
-	if (atomic_dec_and_test(&fp->refcnt))
-		call_rcu_bh(&fp->rcu, sk_filter_rcu_free);
+	sk_filter_release(fp);
 }
 
 static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 0e84484..688f6f5 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -186,7 +186,8 @@
 	/* Reference to data common to all the instances of this
 	 * transformer. */
 	struct xfrm_type	*type;
-	struct xfrm_mode	*mode;
+	struct xfrm_mode	*inner_mode;
+	struct xfrm_mode	*outer_mode;
 
 	/* Security context */
 	struct xfrm_sec_ctx	*security;
@@ -228,8 +229,6 @@
 struct xfrm_dst;
 struct xfrm_policy_afinfo {
 	unsigned short		family;
-	struct xfrm_type	*type_map[IPPROTO_MAX];
-	struct xfrm_mode	*mode_map[XFRM_MODE_MAX];
 	struct dst_ops		*dst_ops;
 	void			(*garbage_collect)(void);
 	int			(*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl);
@@ -255,7 +254,10 @@
 extern int __xfrm_state_delete(struct xfrm_state *x);
 
 struct xfrm_state_afinfo {
-	unsigned short		family;
+	unsigned int		family;
+	struct module		*owner;
+	struct xfrm_type	*type_map[IPPROTO_MAX];
+	struct xfrm_mode	*mode_map[XFRM_MODE_MAX];
 	int			(*init_flags)(struct xfrm_state *x);
 	void			(*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
 						struct xfrm_tmpl *tmpl,
@@ -267,8 +269,6 @@
 
 extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
 extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
-extern struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family);
-extern void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
 
 extern void xfrm_state_delete_tunnel(struct xfrm_state *x);
 
@@ -295,8 +295,6 @@
 
 extern int xfrm_register_type(struct xfrm_type *type, unsigned short family);
 extern int xfrm_unregister_type(struct xfrm_type *type, unsigned short family);
-extern struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family);
-extern void xfrm_put_type(struct xfrm_type *type);
 
 struct xfrm_mode {
 	int (*input)(struct xfrm_state *x, struct sk_buff *skb);
@@ -314,14 +312,19 @@
 	 */
 	int (*output)(struct xfrm_state *x,struct sk_buff *skb);
 
+	struct xfrm_state_afinfo *afinfo;
 	struct module *owner;
 	unsigned int encap;
+	int flags;
+};
+
+/* Flags for xfrm_mode. */
+enum {
+	XFRM_MODE_FLAG_TUNNEL = 1,
 };
 
 extern int xfrm_register_mode(struct xfrm_mode *mode, int family);
 extern int xfrm_unregister_mode(struct xfrm_mode *mode, int family);
-extern struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family);
-extern void xfrm_put_mode(struct xfrm_mode *mode);
 
 struct xfrm_tmpl
 {
@@ -1046,11 +1049,19 @@
 extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
 extern int xfrm_init_state(struct xfrm_state *x);
 extern int xfrm_output(struct sk_buff *skb);
+extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
+			   int encap_type);
 extern int xfrm4_rcv(struct sk_buff *skb);
+
+static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
+{
+	return xfrm4_rcv_encap(skb, nexthdr, spi, 0);
+}
+
 extern int xfrm4_output(struct sk_buff *skb);
 extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
 extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
-extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi);
+extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
 extern int xfrm6_rcv(struct sk_buff *skb);
 extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 			    xfrm_address_t *saddr, u8 proto);
diff --git a/include/sound/version.h b/include/sound/version.h
index 8d4a8dd..a2be8ad 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by alsa/ksync script.  */
 #define CONFIG_SND_VERSION "1.0.15"
-#define CONFIG_SND_DATE " (Tue Oct 16 14:57:44 2007 UTC)"
+#define CONFIG_SND_DATE " (Tue Oct 23 06:09:18 2007 UTC)"
diff --git a/include/video/Kbuild b/include/video/Kbuild
index 53a6c73..0e406f7 100644
--- a/include/video/Kbuild
+++ b/include/video/Kbuild
@@ -1 +1,2 @@
 unifdef-y += sisfb.h uvesafb.h
+unifdef-y += edid.h
diff --git a/include/video/edid.h b/include/video/edid.h
index f6a42d6..928c342 100644
--- a/include/video/edid.h
+++ b/include/video/edid.h
@@ -1,17 +1,16 @@
 #ifndef __linux_video_edid_h__
 #define __linux_video_edid_h__
 
-#ifdef __KERNEL__
+#if !defined(__KERNEL__) || defined(CONFIG_X86)
 
-
-#ifdef CONFIG_X86
 struct edid_info {
 	unsigned char dummy[128];
 };
 
+#ifdef __KERNEL__
 extern struct edid_info edid_info;
-#endif /* CONFIG_X86 */
-
 #endif /* __KERNEL__ */
 
+#endif
+
 #endif /* __linux_video_edid_h__ */
diff --git a/include/video/sstfb.h b/include/video/sstfb.h
index baa163f..b52f073 100644
--- a/include/video/sstfb.h
+++ b/include/video/sstfb.h
@@ -68,7 +68,6 @@
 #  define print_var(X,Y...)
 #endif
 
-#define BIT(x)		(1ul<<(x))
 #define POW2(x)		(1ul<<(x))
 
 /*
diff --git a/include/video/tdfx.h b/include/video/tdfx.h
index 05b63c2..7431d96 100644
--- a/include/video/tdfx.h
+++ b/include/video/tdfx.h
@@ -79,8 +79,6 @@
 
 /* register bitfields (not all, only as needed) */
 
-#define BIT(x)	(1UL << (x))
-
 /* COMMAND_2D reg. values */
 #define TDFX_ROP_COPY		0xcc	/* src */
 #define TDFX_ROP_INVERT		0x55	/* NOT dst */
diff --git a/init/Kconfig b/init/Kconfig
index a29a688..b7dffa8 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -234,6 +234,10 @@
 	  such as SELinux.  To use audit's filesystem watch feature, please
 	  ensure that INOTIFY is configured.
 
+config AUDIT_TREE
+	def_bool y
+	depends on AUDITSYSCALL && INOTIFY
+
 config IKCONFIG
 	tristate "Kernel .config support"
 	---help---
@@ -270,9 +274,43 @@
 		     13 =>  8 KB
 		     12 =>  4 KB
 
+config CGROUPS
+	bool "Control Group support"
+	help
+	  This option will let you use process cgroup subsystems
+	  such as Cpusets
+
+	  Say N if unsure.
+
+config CGROUP_DEBUG
+	bool "Example debug cgroup subsystem"
+	depends on CGROUPS
+	help
+	  This option enables a simple cgroup subsystem that
+	  exports useful debugging information about the cgroups
+	  framework
+
+	  Say N if unsure
+
+config CGROUP_NS
+        bool "Namespace cgroup subsystem"
+        depends on CGROUPS
+        help
+          Provides a simple namespace cgroup subsystem to
+          provide hierarchical naming of sets of namespaces,
+          for instance virtual servers and checkpoint/restart
+          jobs.
+
+config CGROUP_CPUACCT
+	bool "Simple CPU accounting cgroup subsystem"
+	depends on CGROUPS
+	help
+	  Provides a simple Resource Controller for monitoring the
+	  total CPU consumed by the tasks in a cgroup
+
 config CPUSETS
 	bool "Cpuset support"
-	depends on SMP
+	depends on SMP && CGROUPS
 	help
 	  This option will let you create and manage CPUSETs which
 	  allow dynamically partitioning a system into sets of CPUs and
@@ -300,6 +338,16 @@
 	  This option will choose userid as the basis for grouping
 	  tasks, thus providing equal CPU bandwidth to each user.
 
+config FAIR_CGROUP_SCHED
+	bool "Control groups"
+ 	depends on CGROUPS
+ 	help
+	  This option allows you to create arbitrary task groups
+	  using the "cgroup" pseudo filesystem and control
+	  the cpu bandwidth allocated to each such task group.
+	  Refer to Documentation/cgroups.txt for more information
+	  on "cgroup" pseudo filesystem.
+
 endchoice
 
 config SYSFS_DEPRECATED
@@ -322,6 +370,11 @@
 	  If you are using a distro that was released in 2006 or later,
 	  it should be safe to say N here.
 
+config PROC_PID_CPUSET
+	bool "Include legacy /proc/<pid>/cpuset file"
+	depends on CPUSETS
+	default y
+
 config RELAY
 	bool "Kernel->user space relay support (formerly relayfs)"
 	help
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index ed652f4..3ac5904 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -57,7 +57,7 @@
 	unsigned char *buf;
 
 	buf = kmalloc(size, GFP_KERNEL);
-	if (buf == 0)
+	if (!buf)
 		return -1;
 
 	minixsb = (struct minix_super_block *) buf;
@@ -407,12 +407,12 @@
 	crd_infd = in_fd;
 	crd_outfd = out_fd;
 	inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
-	if (inbuf == 0) {
+	if (!inbuf) {
 		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
 		return -1;
 	}
 	window = kmalloc(WSIZE, GFP_KERNEL);
-	if (window == 0) {
+	if (!window) {
 		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
 		kfree(inbuf);
 		return -1;
diff --git a/init/main.c b/init/main.c
index 9def935..f605a96 100644
--- a/init/main.c
+++ b/init/main.c
@@ -39,6 +39,7 @@
 #include <linux/writeback.h>
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
+#include <linux/cgroup.h>
 #include <linux/efi.h>
 #include <linux/tick.h>
 #include <linux/interrupt.h>
@@ -69,15 +70,7 @@
 /*
  * This is one of the first .c files built. Error out early if we have compiler
  * trouble.
- *
- * Versions of gcc older than that listed below may actually compile and link
- * okay, but the end product can have subtle run time bugs.  To avoid associated
- * bogus bug reports, we flatly refuse to compile with a gcc that is known to be
- * too old from the very beginning.
  */
-#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
-#error Sorry, your GCC is too old. It builds incorrect kernels.
-#endif
 
 #if __GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 0
 #warning gcc-4.1.0 is known to miscompile the kernel.  A different compiler version is recommended.
@@ -287,7 +280,7 @@
 		return 0;
 
 	/*
-	 * Preemptive maintenance for "why didn't my mispelled command
+	 * Preemptive maintenance for "why didn't my misspelled command
 	 * line work?"
 	 */
 	if (strchr(param, '.') && (!val || strchr(param, '.') < val)) {
@@ -523,6 +516,7 @@
 	 */
 	unwind_init();
 	lockdep_init();
+	cgroup_init_early();
 
 	local_irq_disable();
 	early_boot_irqs_off();
@@ -640,6 +634,7 @@
 #ifdef CONFIG_PROC_FS
 	proc_root_init();
 #endif
+	cgroup_init();
 	cpuset_init();
 	taskstats_init_early();
 	delayacct_init();
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 774843c..bfa274b 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -29,6 +29,8 @@
 #include <linux/audit.h>
 #include <linux/signal.h>
 #include <linux/mutex.h>
+#include <linux/nsproxy.h>
+#include <linux/pid.h>
 
 #include <net/sock.h>
 #include "util.h"
@@ -44,12 +46,6 @@
 #define STATE_PENDING	1
 #define STATE_READY	2
 
-/* used by sysctl */
-#define FS_MQUEUE 	1
-#define CTL_QUEUESMAX 	2
-#define CTL_MSGMAX 	3
-#define CTL_MSGSIZEMAX 	4
-
 /* default values */
 #define DFLT_QUEUESMAX	256	/* max number of message queues */
 #define DFLT_MSGMAX 	10	/* max number of messages in each queue */
@@ -336,7 +332,8 @@
 			(info->notify_owner &&
 			 info->notify.sigev_notify == SIGEV_SIGNAL) ?
 				info->notify.sigev_signo : 0,
-			pid_nr(info->notify_owner));
+			pid_nr_ns(info->notify_owner,
+				current->nsproxy->pid_ns));
 	spin_unlock(&info->lock);
 	buffer[sizeof(buffer)-1] = '\0';
 	slen = strlen(buffer)+1;
@@ -513,7 +510,7 @@
 			sig_i.si_errno = 0;
 			sig_i.si_code = SI_MESGQ;
 			sig_i.si_value = info->notify.sigev_value;
-			sig_i.si_pid = current->tgid;
+			sig_i.si_pid = task_pid_vnr(current);
 			sig_i.si_uid = current->uid;
 
 			kill_pid_info(info->notify.sigev_signo,
@@ -679,7 +676,7 @@
 
 	if (oflag & O_CREAT) {
 		if (dentry->d_inode) {	/* entry already exists */
-			audit_inode(name, dentry->d_inode);
+			audit_inode(name, dentry);
 			error = -EEXIST;
 			if (oflag & O_EXCL)
 				goto out;
@@ -692,7 +689,7 @@
 		error = -ENOENT;
 		if (!dentry->d_inode)
 			goto out;
-		audit_inode(name, dentry->d_inode);
+		audit_inode(name, dentry);
 		filp = do_open(dentry, oflag);
 	}
 
@@ -840,7 +837,7 @@
 	if (unlikely(filp->f_op != &mqueue_file_operations))
 		goto out_fput;
 	info = MQUEUE_I(inode);
-	audit_inode(NULL, inode);
+	audit_inode(NULL, filp->f_path.dentry);
 
 	if (unlikely(!(filp->f_mode & FMODE_WRITE)))
 		goto out_fput;
@@ -924,7 +921,7 @@
 	if (unlikely(filp->f_op != &mqueue_file_operations))
 		goto out_fput;
 	info = MQUEUE_I(inode);
-	audit_inode(NULL, inode);
+	audit_inode(NULL, filp->f_path.dentry);
 
 	if (unlikely(!(filp->f_mode & FMODE_READ)))
 		goto out_fput;
@@ -1196,7 +1193,6 @@
 
 static ctl_table mq_sysctls[] = {
 	{
-		.ctl_name	= CTL_QUEUESMAX,
 		.procname	= "queues_max",
 		.data		= &queues_max,
 		.maxlen		= sizeof(int),
@@ -1204,7 +1200,6 @@
 		.proc_handler	= &proc_dointvec,
 	},
 	{
-		.ctl_name	= CTL_MSGMAX,
 		.procname	= "msg_max",
 		.data		= &msg_max,
 		.maxlen		= sizeof(int),
@@ -1214,7 +1209,6 @@
 		.extra2		= &msg_max_limit_max,
 	},
 	{
-		.ctl_name	= CTL_MSGSIZEMAX,
 		.procname	= "msgsize_max",
 		.data		= &msgsize_max,
 		.maxlen		= sizeof(int),
@@ -1228,7 +1222,6 @@
 
 static ctl_table mq_sysctl_dir[] = {
 	{
-		.ctl_name	= FS_MQUEUE,
 		.procname	= "mqueue",
 		.mode		= 0555,
 		.child		= mq_sysctls,
diff --git a/ipc/msg.c b/ipc/msg.c
index a03fcb52..fdf3db5 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -34,7 +34,7 @@
 #include <linux/syscalls.h>
 #include <linux/audit.h>
 #include <linux/seq_file.h>
-#include <linux/mutex.h>
+#include <linux/rwsem.h>
 #include <linux/nsproxy.h>
 
 #include <asm/current.h>
@@ -66,23 +66,15 @@
 #define SEARCH_NOTEQUAL		3
 #define SEARCH_LESSEQUAL	4
 
-static atomic_t msg_bytes =	ATOMIC_INIT(0);
-static atomic_t msg_hdrs =	ATOMIC_INIT(0);
-
 static struct ipc_ids init_msg_ids;
 
 #define msg_ids(ns)	(*((ns)->ids[IPC_MSG_IDS]))
 
-#define msg_lock(ns, id)	((struct msg_queue*)ipc_lock(&msg_ids(ns), id))
 #define msg_unlock(msq)		ipc_unlock(&(msq)->q_perm)
-#define msg_rmid(ns, id)	((struct msg_queue*)ipc_rmid(&msg_ids(ns), id))
-#define msg_checkid(ns, msq, msgid)	\
-	ipc_checkid(&msg_ids(ns), &msq->q_perm, msgid)
-#define msg_buildid(ns, id, seq) \
-	ipc_buildid(&msg_ids(ns), id, seq)
+#define msg_buildid(id, seq)	ipc_buildid(id, seq)
 
-static void freeque (struct ipc_namespace *ns, struct msg_queue *msq, int id);
-static int newque (struct ipc_namespace *ns, key_t key, int msgflg);
+static void freeque(struct ipc_namespace *, struct msg_queue *);
+static int newque(struct ipc_namespace *, struct ipc_params *);
 #ifdef CONFIG_PROC_FS
 static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
 #endif
@@ -93,7 +85,9 @@
 	ns->msg_ctlmax = MSGMAX;
 	ns->msg_ctlmnb = MSGMNB;
 	ns->msg_ctlmni = MSGMNI;
-	ipc_init_ids(ids, ns->msg_ctlmni);
+	atomic_set(&ns->msg_bytes, 0);
+	atomic_set(&ns->msg_hdrs, 0);
+	ipc_init_ids(ids);
 }
 
 int msg_init_ns(struct ipc_namespace *ns)
@@ -110,20 +104,25 @@
 
 void msg_exit_ns(struct ipc_namespace *ns)
 {
-	int i;
 	struct msg_queue *msq;
+	int next_id;
+	int total, in_use;
 
-	mutex_lock(&msg_ids(ns).mutex);
-	for (i = 0; i <= msg_ids(ns).max_id; i++) {
-		msq = msg_lock(ns, i);
+	down_write(&msg_ids(ns).rw_mutex);
+
+	in_use = msg_ids(ns).in_use;
+
+	for (total = 0, next_id = 0; total < in_use; next_id++) {
+		msq = idr_find(&msg_ids(ns).ipcs_idr, next_id);
 		if (msq == NULL)
 			continue;
-
-		freeque(ns, msq, i);
+		ipc_lock_by_ptr(&msq->q_perm);
+		freeque(ns, msq);
+		total++;
 	}
-	mutex_unlock(&msg_ids(ns).mutex);
 
-	ipc_fini_ids(ns->ids[IPC_MSG_IDS]);
+	up_write(&msg_ids(ns).rw_mutex);
+
 	kfree(ns->ids[IPC_MSG_IDS]);
 	ns->ids[IPC_MSG_IDS] = NULL;
 }
@@ -136,10 +135,55 @@
 				IPC_MSG_IDS, sysvipc_msg_proc_show);
 }
 
-static int newque (struct ipc_namespace *ns, key_t key, int msgflg)
+/*
+ * This routine is called in the paths where the rw_mutex is held to protect
+ * access to the idr tree.
+ */
+static inline struct msg_queue *msg_lock_check_down(struct ipc_namespace *ns,
+						int id)
+{
+	struct kern_ipc_perm *ipcp = ipc_lock_check_down(&msg_ids(ns), id);
+
+	return container_of(ipcp, struct msg_queue, q_perm);
+}
+
+/*
+ * msg_lock_(check_) routines are called in the paths where the rw_mutex
+ * is not held.
+ */
+static inline struct msg_queue *msg_lock(struct ipc_namespace *ns, int id)
+{
+	struct kern_ipc_perm *ipcp = ipc_lock(&msg_ids(ns), id);
+
+	return container_of(ipcp, struct msg_queue, q_perm);
+}
+
+static inline struct msg_queue *msg_lock_check(struct ipc_namespace *ns,
+						int id)
+{
+	struct kern_ipc_perm *ipcp = ipc_lock_check(&msg_ids(ns), id);
+
+	return container_of(ipcp, struct msg_queue, q_perm);
+}
+
+static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s)
+{
+	ipc_rmid(&msg_ids(ns), &s->q_perm);
+}
+
+/**
+ * newque - Create a new msg queue
+ * @ns: namespace
+ * @params: ptr to the structure that contains the key and msgflg
+ *
+ * Called with msg_ids.rw_mutex held (writer)
+ */
+static int newque(struct ipc_namespace *ns, struct ipc_params *params)
 {
 	struct msg_queue *msq;
 	int id, retval;
+	key_t key = params->key;
+	int msgflg = params->flg;
 
 	msq = ipc_rcu_alloc(sizeof(*msq));
 	if (!msq)
@@ -155,14 +199,17 @@
 		return retval;
 	}
 
+	/*
+	 * ipc_addid() locks msq
+	 */
 	id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
-	if (id == -1) {
+	if (id < 0) {
 		security_msg_queue_free(msq);
 		ipc_rcu_putref(msq);
-		return -ENOSPC;
+		return id;
 	}
 
-	msq->q_id = msg_buildid(ns, id, msq->q_perm.seq);
+	msq->q_perm.id = msg_buildid(id, msq->q_perm.seq);
 	msq->q_stime = msq->q_rtime = 0;
 	msq->q_ctime = get_seconds();
 	msq->q_cbytes = msq->q_qnum = 0;
@@ -171,9 +218,10 @@
 	INIT_LIST_HEAD(&msq->q_messages);
 	INIT_LIST_HEAD(&msq->q_receivers);
 	INIT_LIST_HEAD(&msq->q_senders);
+
 	msg_unlock(msq);
 
-	return msq->q_id;
+	return msq->q_perm.id;
 }
 
 static inline void ss_add(struct msg_queue *msq, struct msg_sender *mss)
@@ -224,19 +272,19 @@
 
 /*
  * freeque() wakes up waiters on the sender and receiver waiting queue,
- * removes the message queue from message queue ID
- * array, and cleans up all the messages associated with this queue.
+ * removes the message queue from message queue ID IDR, and cleans up all the
+ * messages associated with this queue.
  *
- * msg_ids.mutex and the spinlock for this message queue is hold
- * before freeque() is called. msg_ids.mutex remains locked on exit.
+ * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held
+ * before freeque() is called. msg_ids.rw_mutex remains locked on exit.
  */
-static void freeque(struct ipc_namespace *ns, struct msg_queue *msq, int id)
+static void freeque(struct ipc_namespace *ns, struct msg_queue *msq)
 {
 	struct list_head *tmp;
 
 	expunge_all(msq, -EIDRM);
 	ss_wakeup(&msq->q_senders, 1);
-	msq = msg_rmid(ns, id);
+	msg_rmid(ns, msq);
 	msg_unlock(msq);
 
 	tmp = msq->q_messages.next;
@@ -244,49 +292,40 @@
 		struct msg_msg *msg = list_entry(tmp, struct msg_msg, m_list);
 
 		tmp = tmp->next;
-		atomic_dec(&msg_hdrs);
+		atomic_dec(&ns->msg_hdrs);
 		free_msg(msg);
 	}
-	atomic_sub(msq->q_cbytes, &msg_bytes);
+	atomic_sub(msq->q_cbytes, &ns->msg_bytes);
 	security_msg_queue_free(msq);
 	ipc_rcu_putref(msq);
 }
 
+/*
+ * Called with msg_ids.rw_mutex and ipcp locked.
+ */
+static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
+{
+	struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm);
+
+	return security_msg_queue_associate(msq, msgflg);
+}
+
 asmlinkage long sys_msgget(key_t key, int msgflg)
 {
-	struct msg_queue *msq;
-	int id, ret = -EPERM;
 	struct ipc_namespace *ns;
+	struct ipc_ops msg_ops;
+	struct ipc_params msg_params;
 
 	ns = current->nsproxy->ipc_ns;
-	
-	mutex_lock(&msg_ids(ns).mutex);
-	if (key == IPC_PRIVATE) 
-		ret = newque(ns, key, msgflg);
-	else if ((id = ipc_findkey(&msg_ids(ns), key)) == -1) { /* key not used */
-		if (!(msgflg & IPC_CREAT))
-			ret = -ENOENT;
-		else
-			ret = newque(ns, key, msgflg);
-	} else if (msgflg & IPC_CREAT && msgflg & IPC_EXCL) {
-		ret = -EEXIST;
-	} else {
-		msq = msg_lock(ns, id);
-		BUG_ON(msq == NULL);
-		if (ipcperms(&msq->q_perm, msgflg))
-			ret = -EACCES;
-		else {
-			int qid = msg_buildid(ns, id, msq->q_perm.seq);
 
-			ret = security_msg_queue_associate(msq, msgflg);
-			if (!ret)
-				ret = qid;
-		}
-		msg_unlock(msq);
-	}
-	mutex_unlock(&msg_ids(ns).mutex);
+	msg_ops.getnew = newque;
+	msg_ops.associate = msg_security;
+	msg_ops.more_checks = NULL;
 
-	return ret;
+	msg_params.key = key;
+	msg_params.flg = msgflg;
+
+	return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
 }
 
 static inline unsigned long
@@ -420,23 +459,23 @@
 		msginfo.msgmnb = ns->msg_ctlmnb;
 		msginfo.msgssz = MSGSSZ;
 		msginfo.msgseg = MSGSEG;
-		mutex_lock(&msg_ids(ns).mutex);
+		down_read(&msg_ids(ns).rw_mutex);
 		if (cmd == MSG_INFO) {
 			msginfo.msgpool = msg_ids(ns).in_use;
-			msginfo.msgmap = atomic_read(&msg_hdrs);
-			msginfo.msgtql = atomic_read(&msg_bytes);
+			msginfo.msgmap = atomic_read(&ns->msg_hdrs);
+			msginfo.msgtql = atomic_read(&ns->msg_bytes);
 		} else {
 			msginfo.msgmap = MSGMAP;
 			msginfo.msgpool = MSGPOOL;
 			msginfo.msgtql = MSGTQL;
 		}
-		max_id = msg_ids(ns).max_id;
-		mutex_unlock(&msg_ids(ns).mutex);
+		max_id = ipc_get_maxid(&msg_ids(ns));
+		up_read(&msg_ids(ns).rw_mutex);
 		if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
 			return -EFAULT;
 		return (max_id < 0) ? 0 : max_id;
 	}
-	case MSG_STAT:
+	case MSG_STAT:	/* msqid is an index rather than a msg queue id */
 	case IPC_STAT:
 	{
 		struct msqid64_ds tbuf;
@@ -444,21 +483,16 @@
 
 		if (!buf)
 			return -EFAULT;
-		if (cmd == MSG_STAT && msqid >= msg_ids(ns).entries->size)
-			return -EINVAL;
-
-		memset(&tbuf, 0, sizeof(tbuf));
-
-		msq = msg_lock(ns, msqid);
-		if (msq == NULL)
-			return -EINVAL;
 
 		if (cmd == MSG_STAT) {
-			success_return = msg_buildid(ns, msqid, msq->q_perm.seq);
+			msq = msg_lock(ns, msqid);
+			if (IS_ERR(msq))
+				return PTR_ERR(msq);
+			success_return = msq->q_perm.id;
 		} else {
-			err = -EIDRM;
-			if (msg_checkid(ns, msq, msqid))
-				goto out_unlock;
+			msq = msg_lock_check(ns, msqid);
+			if (IS_ERR(msq))
+				return PTR_ERR(msq);
 			success_return = 0;
 		}
 		err = -EACCES;
@@ -469,6 +503,8 @@
 		if (err)
 			goto out_unlock;
 
+		memset(&tbuf, 0, sizeof(tbuf));
+
 		kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm);
 		tbuf.msg_stime  = msq->q_stime;
 		tbuf.msg_rtime  = msq->q_rtime;
@@ -495,15 +531,13 @@
 		return  -EINVAL;
 	}
 
-	mutex_lock(&msg_ids(ns).mutex);
-	msq = msg_lock(ns, msqid);
-	err = -EINVAL;
-	if (msq == NULL)
+	down_write(&msg_ids(ns).rw_mutex);
+	msq = msg_lock_check_down(ns, msqid);
+	if (IS_ERR(msq)) {
+		err = PTR_ERR(msq);
 		goto out_up;
+	}
 
-	err = -EIDRM;
-	if (msg_checkid(ns, msq, msqid))
-		goto out_unlock_up;
 	ipcp = &msq->q_perm;
 
 	err = audit_ipc_obj(ipcp);
@@ -552,12 +586,12 @@
 		break;
 	}
 	case IPC_RMID:
-		freeque(ns, msq, msqid);
+		freeque(ns, msq);
 		break;
 	}
 	err = 0;
 out_up:
-	mutex_unlock(&msg_ids(ns).mutex);
+	up_write(&msg_ids(ns).rw_mutex);
 	return err;
 out_unlock_up:
 	msg_unlock(msq);
@@ -611,7 +645,7 @@
 				msr->r_msg = ERR_PTR(-E2BIG);
 			} else {
 				msr->r_msg = NULL;
-				msq->q_lrpid = msr->r_tsk->pid;
+				msq->q_lrpid = task_pid_vnr(msr->r_tsk);
 				msq->q_rtime = get_seconds();
 				wake_up_process(msr->r_tsk);
 				smp_mb();
@@ -646,14 +680,11 @@
 	msg->m_type = mtype;
 	msg->m_ts = msgsz;
 
-	msq = msg_lock(ns, msqid);
-	err = -EINVAL;
-	if (msq == NULL)
+	msq = msg_lock_check(ns, msqid);
+	if (IS_ERR(msq)) {
+		err = PTR_ERR(msq);
 		goto out_free;
-
-	err= -EIDRM;
-	if (msg_checkid(ns, msq, msqid))
-		goto out_unlock_free;
+	}
 
 	for (;;) {
 		struct msg_sender s;
@@ -695,7 +726,7 @@
 		}
 	}
 
-	msq->q_lspid = current->tgid;
+	msq->q_lspid = task_tgid_vnr(current);
 	msq->q_stime = get_seconds();
 
 	if (!pipelined_send(msq, msg)) {
@@ -703,8 +734,8 @@
 		list_add_tail(&msg->m_list, &msq->q_messages);
 		msq->q_cbytes += msgsz;
 		msq->q_qnum++;
-		atomic_add(msgsz, &msg_bytes);
-		atomic_inc(&msg_hdrs);
+		atomic_add(msgsz, &ns->msg_bytes);
+		atomic_inc(&ns->msg_hdrs);
 	}
 
 	err = 0;
@@ -760,13 +791,9 @@
 	mode = convert_mode(&msgtyp, msgflg);
 	ns = current->nsproxy->ipc_ns;
 
-	msq = msg_lock(ns, msqid);
-	if (msq == NULL)
-		return -EINVAL;
-
-	msg = ERR_PTR(-EIDRM);
-	if (msg_checkid(ns, msq, msqid))
-		goto out_unlock;
+	msq = msg_lock_check(ns, msqid);
+	if (IS_ERR(msq))
+		return PTR_ERR(msq);
 
 	for (;;) {
 		struct msg_receiver msr_d;
@@ -810,10 +837,10 @@
 			list_del(&msg->m_list);
 			msq->q_qnum--;
 			msq->q_rtime = get_seconds();
-			msq->q_lrpid = current->tgid;
+			msq->q_lrpid = task_tgid_vnr(current);
 			msq->q_cbytes -= msg->m_ts;
-			atomic_sub(msg->m_ts, &msg_bytes);
-			atomic_dec(&msg_hdrs);
+			atomic_sub(msg->m_ts, &ns->msg_bytes);
+			atomic_dec(&ns->msg_hdrs);
 			ss_wakeup(&msq->q_senders, 0);
 			msg_unlock(msq);
 			break;
@@ -926,7 +953,7 @@
 	return seq_printf(s,
 			"%10d %10d  %4o  %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
 			msq->q_perm.key,
-			msq->q_id,
+			msq->q_perm.id,
 			msq->q_perm.mode,
 			msq->q_cbytes,
 			msq->q_qnum,
diff --git a/ipc/sem.c b/ipc/sem.c
index b676fef..35952c0 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -80,7 +80,7 @@
 #include <linux/audit.h>
 #include <linux/capability.h>
 #include <linux/seq_file.h>
-#include <linux/mutex.h>
+#include <linux/rwsem.h>
 #include <linux/nsproxy.h>
 
 #include <asm/uaccess.h>
@@ -88,18 +88,14 @@
 
 #define sem_ids(ns)	(*((ns)->ids[IPC_SEM_IDS]))
 
-#define sem_lock(ns, id)	((struct sem_array*)ipc_lock(&sem_ids(ns), id))
 #define sem_unlock(sma)		ipc_unlock(&(sma)->sem_perm)
-#define sem_rmid(ns, id)	((struct sem_array*)ipc_rmid(&sem_ids(ns), id))
-#define sem_checkid(ns, sma, semid)	\
-	ipc_checkid(&sem_ids(ns),&sma->sem_perm,semid)
-#define sem_buildid(ns, id, seq) \
-	ipc_buildid(&sem_ids(ns), id, seq)
+#define sem_checkid(sma, semid)	ipc_checkid(&sma->sem_perm, semid)
+#define sem_buildid(id, seq)	ipc_buildid(id, seq)
 
 static struct ipc_ids init_sem_ids;
 
-static int newary(struct ipc_namespace *, key_t, int, int);
-static void freeary(struct ipc_namespace *ns, struct sem_array *sma, int id);
+static int newary(struct ipc_namespace *, struct ipc_params *);
+static void freeary(struct ipc_namespace *, struct sem_array *);
 #ifdef CONFIG_PROC_FS
 static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
 #endif
@@ -129,7 +125,7 @@
 	ns->sc_semopm = SEMOPM;
 	ns->sc_semmni = SEMMNI;
 	ns->used_sems = 0;
-	ipc_init_ids(ids, ns->sc_semmni);
+	ipc_init_ids(ids);
 }
 
 int sem_init_ns(struct ipc_namespace *ns)
@@ -146,20 +142,24 @@
 
 void sem_exit_ns(struct ipc_namespace *ns)
 {
-	int i;
 	struct sem_array *sma;
+	int next_id;
+	int total, in_use;
 
-	mutex_lock(&sem_ids(ns).mutex);
-	for (i = 0; i <= sem_ids(ns).max_id; i++) {
-		sma = sem_lock(ns, i);
+	down_write(&sem_ids(ns).rw_mutex);
+
+	in_use = sem_ids(ns).in_use;
+
+	for (total = 0, next_id = 0; total < in_use; next_id++) {
+		sma = idr_find(&sem_ids(ns).ipcs_idr, next_id);
 		if (sma == NULL)
 			continue;
-
-		freeary(ns, sma, i);
+		ipc_lock_by_ptr(&sma->sem_perm);
+		freeary(ns, sma);
+		total++;
 	}
-	mutex_unlock(&sem_ids(ns).mutex);
+	up_write(&sem_ids(ns).rw_mutex);
 
-	ipc_fini_ids(ns->ids[IPC_SEM_IDS]);
 	kfree(ns->ids[IPC_SEM_IDS]);
 	ns->ids[IPC_SEM_IDS] = NULL;
 }
@@ -173,6 +173,42 @@
 }
 
 /*
+ * This routine is called in the paths where the rw_mutex is held to protect
+ * access to the idr tree.
+ */
+static inline struct sem_array *sem_lock_check_down(struct ipc_namespace *ns,
+						int id)
+{
+	struct kern_ipc_perm *ipcp = ipc_lock_check_down(&sem_ids(ns), id);
+
+	return container_of(ipcp, struct sem_array, sem_perm);
+}
+
+/*
+ * sem_lock_(check_) routines are called in the paths where the rw_mutex
+ * is not held.
+ */
+static inline struct sem_array *sem_lock(struct ipc_namespace *ns, int id)
+{
+	struct kern_ipc_perm *ipcp = ipc_lock(&sem_ids(ns), id);
+
+	return container_of(ipcp, struct sem_array, sem_perm);
+}
+
+static inline struct sem_array *sem_lock_check(struct ipc_namespace *ns,
+						int id)
+{
+	struct kern_ipc_perm *ipcp = ipc_lock_check(&sem_ids(ns), id);
+
+	return container_of(ipcp, struct sem_array, sem_perm);
+}
+
+static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
+{
+	ipc_rmid(&sem_ids(ns), &s->sem_perm);
+}
+
+/*
  * Lockless wakeup algorithm:
  * Without the check/retry algorithm a lockless wakeup is possible:
  * - queue.status is initialized to -EINTR before blocking.
@@ -206,12 +242,23 @@
  */
 #define IN_WAKEUP	1
 
-static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg)
+/**
+ * newary - Create a new semaphore set
+ * @ns: namespace
+ * @params: ptr to the structure that contains key, semflg and nsems
+ *
+ * Called with sem_ids.rw_mutex held (as a writer)
+ */
+
+static int newary(struct ipc_namespace *ns, struct ipc_params *params)
 {
 	int id;
 	int retval;
 	struct sem_array *sma;
 	int size;
+	key_t key = params->key;
+	int nsems = params->u.nsems;
+	int semflg = params->flg;
 
 	if (!nsems)
 		return -EINVAL;
@@ -236,14 +283,14 @@
 	}
 
 	id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
-	if(id == -1) {
+	if (id < 0) {
 		security_sem_free(sma);
 		ipc_rcu_putref(sma);
-		return -ENOSPC;
+		return id;
 	}
 	ns->used_sems += nsems;
 
-	sma->sem_id = sem_buildid(ns, id, sma->sem_perm.seq);
+	sma->sem_perm.id = sem_buildid(id, sma->sem_perm.seq);
 	sma->sem_base = (struct sem *) &sma[1];
 	/* sma->sem_pending = NULL; */
 	sma->sem_pending_last = &sma->sem_pending;
@@ -252,48 +299,56 @@
 	sma->sem_ctime = get_seconds();
 	sem_unlock(sma);
 
-	return sma->sem_id;
+	return sma->sem_perm.id;
 }
 
-asmlinkage long sys_semget (key_t key, int nsems, int semflg)
+
+/*
+ * Called with sem_ids.rw_mutex and ipcp locked.
+ */
+static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
 {
-	int id, err = -EINVAL;
 	struct sem_array *sma;
+
+	sma = container_of(ipcp, struct sem_array, sem_perm);
+	return security_sem_associate(sma, semflg);
+}
+
+/*
+ * Called with sem_ids.rw_mutex and ipcp locked.
+ */
+static inline int sem_more_checks(struct kern_ipc_perm *ipcp,
+				struct ipc_params *params)
+{
+	struct sem_array *sma;
+
+	sma = container_of(ipcp, struct sem_array, sem_perm);
+	if (params->u.nsems > sma->sem_nsems)
+		return -EINVAL;
+
+	return 0;
+}
+
+asmlinkage long sys_semget(key_t key, int nsems, int semflg)
+{
 	struct ipc_namespace *ns;
+	struct ipc_ops sem_ops;
+	struct ipc_params sem_params;
 
 	ns = current->nsproxy->ipc_ns;
 
 	if (nsems < 0 || nsems > ns->sc_semmsl)
 		return -EINVAL;
-	mutex_lock(&sem_ids(ns).mutex);
-	
-	if (key == IPC_PRIVATE) {
-		err = newary(ns, key, nsems, semflg);
-	} else if ((id = ipc_findkey(&sem_ids(ns), key)) == -1) {  /* key not used */
-		if (!(semflg & IPC_CREAT))
-			err = -ENOENT;
-		else
-			err = newary(ns, key, nsems, semflg);
-	} else if (semflg & IPC_CREAT && semflg & IPC_EXCL) {
-		err = -EEXIST;
-	} else {
-		sma = sem_lock(ns, id);
-		BUG_ON(sma==NULL);
-		if (nsems > sma->sem_nsems)
-			err = -EINVAL;
-		else if (ipcperms(&sma->sem_perm, semflg))
-			err = -EACCES;
-		else {
-			int semid = sem_buildid(ns, id, sma->sem_perm.seq);
-			err = security_sem_associate(sma, semflg);
-			if (!err)
-				err = semid;
-		}
-		sem_unlock(sma);
-	}
 
-	mutex_unlock(&sem_ids(ns).mutex);
-	return err;
+	sem_ops.getnew = newary;
+	sem_ops.associate = sem_security;
+	sem_ops.more_checks = sem_more_checks;
+
+	sem_params.key = key;
+	sem_params.flg = semflg;
+	sem_params.u.nsems = nsems;
+
+	return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
 }
 
 /* Manage the doubly linked list sma->sem_pending as a FIFO:
@@ -487,15 +542,14 @@
 	return semzcnt;
 }
 
-/* Free a semaphore set. freeary() is called with sem_ids.mutex locked and
- * the spinlock for this semaphore set hold. sem_ids.mutex remains locked
- * on exit.
+/* Free a semaphore set. freeary() is called with sem_ids.rw_mutex locked
+ * as a writer and the spinlock for this semaphore set hold. sem_ids.rw_mutex
+ * remains locked on exit.
  */
-static void freeary (struct ipc_namespace *ns, struct sem_array *sma, int id)
+static void freeary(struct ipc_namespace *ns, struct sem_array *sma)
 {
 	struct sem_undo *un;
 	struct sem_queue *q;
-	int size;
 
 	/* Invalidate the existing undo structures for this semaphore set.
 	 * (They will be freed without any further action in exit_sem()
@@ -518,12 +572,11 @@
 		q = n;
 	}
 
-	/* Remove the semaphore set from the ID array*/
-	sma = sem_rmid(ns, id);
+	/* Remove the semaphore set from the IDR */
+	sem_rmid(ns, sma);
 	sem_unlock(sma);
 
 	ns->used_sems -= sma->sem_nsems;
-	size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem);
 	security_sem_free(sma);
 	ipc_rcu_putref(sma);
 }
@@ -576,7 +629,7 @@
 		seminfo.semmnu = SEMMNU;
 		seminfo.semmap = SEMMAP;
 		seminfo.semume = SEMUME;
-		mutex_lock(&sem_ids(ns).mutex);
+		down_read(&sem_ids(ns).rw_mutex);
 		if (cmd == SEM_INFO) {
 			seminfo.semusz = sem_ids(ns).in_use;
 			seminfo.semaem = ns->used_sems;
@@ -584,8 +637,8 @@
 			seminfo.semusz = SEMUSZ;
 			seminfo.semaem = SEMAEM;
 		}
-		max_id = sem_ids(ns).max_id;
-		mutex_unlock(&sem_ids(ns).mutex);
+		max_id = ipc_get_maxid(&sem_ids(ns));
+		up_read(&sem_ids(ns).rw_mutex);
 		if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo))) 
 			return -EFAULT;
 		return (max_id < 0) ? 0: max_id;
@@ -595,14 +648,9 @@
 		struct semid64_ds tbuf;
 		int id;
 
-		if(semid >= sem_ids(ns).entries->size)
-			return -EINVAL;
-
-		memset(&tbuf,0,sizeof(tbuf));
-
 		sma = sem_lock(ns, semid);
-		if(sma == NULL)
-			return -EINVAL;
+		if (IS_ERR(sma))
+			return PTR_ERR(sma);
 
 		err = -EACCES;
 		if (ipcperms (&sma->sem_perm, S_IRUGO))
@@ -612,7 +660,9 @@
 		if (err)
 			goto out_unlock;
 
-		id = sem_buildid(ns, semid, sma->sem_perm.seq);
+		id = sma->sem_perm.id;
+
+		memset(&tbuf, 0, sizeof(tbuf));
 
 		kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
 		tbuf.sem_otime  = sma->sem_otime;
@@ -642,16 +692,12 @@
 	ushort* sem_io = fast_sem_io;
 	int nsems;
 
-	sma = sem_lock(ns, semid);
-	if(sma==NULL)
-		return -EINVAL;
+	sma = sem_lock_check(ns, semid);
+	if (IS_ERR(sma))
+		return PTR_ERR(sma);
 
 	nsems = sma->sem_nsems;
 
-	err=-EIDRM;
-	if (sem_checkid(ns,sma,semid))
-		goto out_unlock;
-
 	err = -EACCES;
 	if (ipcperms (&sma->sem_perm, (cmd==SETVAL||cmd==SETALL)?S_IWUGO:S_IRUGO))
 		goto out_unlock;
@@ -795,7 +841,7 @@
 		for (un = sma->undo; un; un = un->id_next)
 			un->semadj[semnum] = 0;
 		curr->semval = val;
-		curr->sempid = current->tgid;
+		curr->sempid = task_tgid_vnr(current);
 		sma->sem_ctime = get_seconds();
 		/* maybe some queued-up processes were waiting for this */
 		update_queue(sma);
@@ -863,14 +909,10 @@
 		if(copy_semid_from_user (&setbuf, arg.buf, version))
 			return -EFAULT;
 	}
-	sma = sem_lock(ns, semid);
-	if(sma==NULL)
-		return -EINVAL;
+	sma = sem_lock_check_down(ns, semid);
+	if (IS_ERR(sma))
+		return PTR_ERR(sma);
 
-	if (sem_checkid(ns,sma,semid)) {
-		err=-EIDRM;
-		goto out_unlock;
-	}	
 	ipcp = &sma->sem_perm;
 
 	err = audit_ipc_obj(ipcp);
@@ -894,7 +936,7 @@
 
 	switch(cmd){
 	case IPC_RMID:
-		freeary(ns, sma, semid);
+		freeary(ns, sma);
 		err = 0;
 		break;
 	case IPC_SET:
@@ -948,45 +990,15 @@
 		return err;
 	case IPC_RMID:
 	case IPC_SET:
-		mutex_lock(&sem_ids(ns).mutex);
+		down_write(&sem_ids(ns).rw_mutex);
 		err = semctl_down(ns,semid,semnum,cmd,version,arg);
-		mutex_unlock(&sem_ids(ns).mutex);
+		up_write(&sem_ids(ns).rw_mutex);
 		return err;
 	default:
 		return -EINVAL;
 	}
 }
 
-static inline void lock_semundo(void)
-{
-	struct sem_undo_list *undo_list;
-
-	undo_list = current->sysvsem.undo_list;
-	if (undo_list)
-		spin_lock(&undo_list->lock);
-}
-
-/* This code has an interaction with copy_semundo().
- * Consider; two tasks are sharing the undo_list. task1
- * acquires the undo_list lock in lock_semundo().  If task2 now
- * exits before task1 releases the lock (by calling
- * unlock_semundo()), then task1 will never call spin_unlock().
- * This leave the sem_undo_list in a locked state.  If task1 now creats task3
- * and once again shares the sem_undo_list, the sem_undo_list will still be
- * locked, and future SEM_UNDO operations will deadlock.  This case is
- * dealt with in copy_semundo() by having it reinitialize the spin lock when 
- * the refcnt goes from 1 to 2.
- */
-static inline void unlock_semundo(void)
-{
-	struct sem_undo_list *undo_list;
-
-	undo_list = current->sysvsem.undo_list;
-	if (undo_list)
-		spin_unlock(&undo_list->lock);
-}
-
-
 /* If the task doesn't already have a undo_list, then allocate one
  * here.  We guarantee there is only one thread using this undo list,
  * and current is THE ONE
@@ -1047,22 +1059,17 @@
 	if (error)
 		return ERR_PTR(error);
 
-	lock_semundo();
+	spin_lock(&ulp->lock);
 	un = lookup_undo(ulp, semid);
-	unlock_semundo();
+	spin_unlock(&ulp->lock);
 	if (likely(un!=NULL))
 		goto out;
 
 	/* no undo structure around - allocate one. */
-	sma = sem_lock(ns, semid);
-	un = ERR_PTR(-EINVAL);
-	if(sma==NULL)
-		goto out;
-	un = ERR_PTR(-EIDRM);
-	if (sem_checkid(ns,sma,semid)) {
-		sem_unlock(sma);
-		goto out;
-	}
+	sma = sem_lock_check(ns, semid);
+	if (IS_ERR(sma))
+		return ERR_PTR(PTR_ERR(sma));
+
 	nsems = sma->sem_nsems;
 	ipc_rcu_getref(sma);
 	sem_unlock(sma);
@@ -1077,10 +1084,10 @@
 	new->semadj = (short *) &new[1];
 	new->semid = semid;
 
-	lock_semundo();
+	spin_lock(&ulp->lock);
 	un = lookup_undo(ulp, semid);
 	if (un) {
-		unlock_semundo();
+		spin_unlock(&ulp->lock);
 		kfree(new);
 		ipc_lock_by_ptr(&sma->sem_perm);
 		ipc_rcu_putref(sma);
@@ -1091,7 +1098,7 @@
 	ipc_rcu_putref(sma);
 	if (sma->sem_perm.deleted) {
 		sem_unlock(sma);
-		unlock_semundo();
+		spin_unlock(&ulp->lock);
 		kfree(new);
 		un = ERR_PTR(-EIDRM);
 		goto out;
@@ -1102,7 +1109,7 @@
 	sma->undo = new;
 	sem_unlock(sma);
 	un = new;
-	unlock_semundo();
+	spin_unlock(&ulp->lock);
 out:
 	return un;
 }
@@ -1168,15 +1175,14 @@
 	} else
 		un = NULL;
 
-	sma = sem_lock(ns, semid);
-	error=-EINVAL;
-	if(sma==NULL)
+	sma = sem_lock_check(ns, semid);
+	if (IS_ERR(sma)) {
+		error = PTR_ERR(sma);
 		goto out_free;
-	error = -EIDRM;
-	if (sem_checkid(ns,sma,semid))
-		goto out_unlock_free;
+	}
+
 	/*
-	 * semid identifies are not unique - find_undo may have
+	 * semid identifiers are not unique - find_undo may have
 	 * allocated an undo structure, it was invalidated by an RMID
 	 * and now a new array with received the same id. Check and retry.
 	 */
@@ -1196,7 +1202,7 @@
 	if (error)
 		goto out_unlock_free;
 
-	error = try_atomic_semop (sma, sops, nsops, un, current->tgid);
+	error = try_atomic_semop (sma, sops, nsops, un, task_tgid_vnr(current));
 	if (error <= 0) {
 		if (alter && error == 0)
 			update_queue (sma);
@@ -1211,7 +1217,7 @@
 	queue.sops = sops;
 	queue.nsops = nsops;
 	queue.undo = un;
-	queue.pid = current->tgid;
+	queue.pid = task_tgid_vnr(current);
 	queue.id = semid;
 	queue.alter = alter;
 	if (alter)
@@ -1242,7 +1248,7 @@
 	}
 
 	sma = sem_lock(ns, semid);
-	if(sma==NULL) {
+	if (IS_ERR(sma)) {
 		BUG_ON(queue.prev != NULL);
 		error = -EIDRM;
 		goto out_free;
@@ -1279,10 +1285,6 @@
 
 /* If CLONE_SYSVSEM is set, establish sharing of SEM_UNDO state between
  * parent and child tasks.
- *
- * See the notes above unlock_semundo() regarding the spin_lock_init()
- * in this code.  Initialize the undo_list->lock here instead of get_undo_list()
- * because of the reasoning in the comment above unlock_semundo.
  */
 
 int copy_semundo(unsigned long clone_flags, struct task_struct *tsk)
@@ -1342,13 +1344,13 @@
 		if(semid == -1)
 			continue;
 		sma = sem_lock(ns, semid);
-		if (sma == NULL)
+		if (IS_ERR(sma))
 			continue;
 
 		if (u->semid == -1)
 			goto next_entry;
 
-		BUG_ON(sem_checkid(ns,sma,u->semid));
+		BUG_ON(sem_checkid(sma, u->semid));
 
 		/* remove u from the sma->undo list */
 		for (unp = &sma->undo; (un = *unp); unp = &un->id_next) {
@@ -1382,7 +1384,7 @@
 					semaphore->semval = 0;
 				if (semaphore->semval > SEMVMX)
 					semaphore->semval = SEMVMX;
-				semaphore->sempid = current->tgid;
+				semaphore->sempid = task_tgid_vnr(current);
 			}
 		}
 		sma->sem_otime = get_seconds();
@@ -1402,7 +1404,7 @@
 	return seq_printf(s,
 			  "%10d %10d  %4o %10lu %5u %5u %5u %5u %10lu %10lu\n",
 			  sma->sem_perm.key,
-			  sma->sem_id,
+			  sma->sem_perm.id,
 			  sma->sem_perm.mode,
 			  sma->sem_nsems,
 			  sma->sem_perm.uid,
diff --git a/ipc/shm.c b/ipc/shm.c
index 5fc5cf5..3818fae 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -35,7 +35,7 @@
 #include <linux/capability.h>
 #include <linux/ptrace.h>
 #include <linux/seq_file.h>
-#include <linux/mutex.h>
+#include <linux/rwsem.h>
 #include <linux/nsproxy.h>
 #include <linux/mount.h>
 
@@ -59,17 +59,11 @@
 
 #define shm_ids(ns)	(*((ns)->ids[IPC_SHM_IDS]))
 
-#define shm_lock(ns, id)		\
-	((struct shmid_kernel*)ipc_lock(&shm_ids(ns),id))
 #define shm_unlock(shp)			\
 	ipc_unlock(&(shp)->shm_perm)
-#define shm_get(ns, id)			\
-	((struct shmid_kernel*)ipc_get(&shm_ids(ns),id))
-#define shm_buildid(ns, id, seq)	\
-	ipc_buildid(&shm_ids(ns), id, seq)
+#define shm_buildid(id, seq)	ipc_buildid(id, seq)
 
-static int newseg (struct ipc_namespace *ns, key_t key,
-		int shmflg, size_t size);
+static int newseg(struct ipc_namespace *, struct ipc_params *);
 static void shm_open(struct vm_area_struct *vma);
 static void shm_close(struct vm_area_struct *vma);
 static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp);
@@ -84,9 +78,13 @@
 	ns->shm_ctlall = SHMALL;
 	ns->shm_ctlmni = SHMMNI;
 	ns->shm_tot = 0;
-	ipc_init_ids(ids, 1);
+	ipc_init_ids(ids);
 }
 
+/*
+ * Called with shm_ids.rw_mutex (writer) and the shp structure locked.
+ * Only shm_ids.rw_mutex remains locked on exit.
+ */
 static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
 {
 	if (shp->shm_nattch){
@@ -112,20 +110,24 @@
 
 void shm_exit_ns(struct ipc_namespace *ns)
 {
-	int i;
 	struct shmid_kernel *shp;
+	int next_id;
+	int total, in_use;
 
-	mutex_lock(&shm_ids(ns).mutex);
-	for (i = 0; i <= shm_ids(ns).max_id; i++) {
-		shp = shm_lock(ns, i);
+	down_write(&shm_ids(ns).rw_mutex);
+
+	in_use = shm_ids(ns).in_use;
+
+	for (total = 0, next_id = 0; total < in_use; next_id++) {
+		shp = idr_find(&shm_ids(ns).ipcs_idr, next_id);
 		if (shp == NULL)
 			continue;
-
+		ipc_lock_by_ptr(&shp->shm_perm);
 		do_shm_rmid(ns, shp);
+		total++;
 	}
-	mutex_unlock(&shm_ids(ns).mutex);
+	up_write(&shm_ids(ns).rw_mutex);
 
-	ipc_fini_ids(ns->ids[IPC_SHM_IDS]);
 	kfree(ns->ids[IPC_SHM_IDS]);
 	ns->ids[IPC_SHM_IDS] = NULL;
 }
@@ -138,17 +140,49 @@
 				IPC_SHM_IDS, sysvipc_shm_proc_show);
 }
 
-static inline int shm_checkid(struct ipc_namespace *ns,
-		struct shmid_kernel *s, int id)
+/*
+ * shm_lock_(check_)down routines are called in the paths where the rw_mutex
+ * is held to protect access to the idr tree.
+ */
+static inline struct shmid_kernel *shm_lock_down(struct ipc_namespace *ns,
+						int id)
 {
-	if (ipc_checkid(&shm_ids(ns), &s->shm_perm, id))
-		return -EIDRM;
-	return 0;
+	struct kern_ipc_perm *ipcp = ipc_lock_down(&shm_ids(ns), id);
+
+	return container_of(ipcp, struct shmid_kernel, shm_perm);
 }
 
-static inline struct shmid_kernel *shm_rmid(struct ipc_namespace *ns, int id)
+static inline struct shmid_kernel *shm_lock_check_down(
+						struct ipc_namespace *ns,
+						int id)
 {
-	return (struct shmid_kernel *)ipc_rmid(&shm_ids(ns), id);
+	struct kern_ipc_perm *ipcp = ipc_lock_check_down(&shm_ids(ns), id);
+
+	return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+/*
+ * shm_lock_(check_) routines are called in the paths where the rw_mutex
+ * is not held.
+ */
+static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id)
+{
+	struct kern_ipc_perm *ipcp = ipc_lock(&shm_ids(ns), id);
+
+	return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+static inline struct shmid_kernel *shm_lock_check(struct ipc_namespace *ns,
+						int id)
+{
+	struct kern_ipc_perm *ipcp = ipc_lock_check(&shm_ids(ns), id);
+
+	return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s)
+{
+	ipc_rmid(&shm_ids(ns), &s->shm_perm);
 }
 
 static inline int shm_addid(struct ipc_namespace *ns, struct shmid_kernel *shp)
@@ -166,9 +200,9 @@
 	struct shmid_kernel *shp;
 
 	shp = shm_lock(sfd->ns, sfd->id);
-	BUG_ON(!shp);
+	BUG_ON(IS_ERR(shp));
 	shp->shm_atim = get_seconds();
-	shp->shm_lprid = current->tgid;
+	shp->shm_lprid = task_tgid_vnr(current);
 	shp->shm_nattch++;
 	shm_unlock(shp);
 }
@@ -176,15 +210,16 @@
 /*
  * shm_destroy - free the struct shmid_kernel
  *
+ * @ns: namespace
  * @shp: struct to free
  *
- * It has to be called with shp and shm_ids.mutex locked,
+ * It has to be called with shp and shm_ids.rw_mutex (writer) locked,
  * but returns with shp unlocked and freed.
  */
 static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
 {
 	ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	shm_rmid(ns, shp->id);
+	shm_rmid(ns, shp);
 	shm_unlock(shp);
 	if (!is_file_hugepages(shp->shm_file))
 		shmem_lock(shp->shm_file, 0, shp->mlock_user);
@@ -209,11 +244,11 @@
 	struct shmid_kernel *shp;
 	struct ipc_namespace *ns = sfd->ns;
 
-	mutex_lock(&shm_ids(ns).mutex);
+	down_write(&shm_ids(ns).rw_mutex);
 	/* remove from the list of attaches of the shm segment */
-	shp = shm_lock(ns, sfd->id);
-	BUG_ON(!shp);
-	shp->shm_lprid = current->tgid;
+	shp = shm_lock_down(ns, sfd->id);
+	BUG_ON(IS_ERR(shp));
+	shp->shm_lprid = task_tgid_vnr(current);
 	shp->shm_dtim = get_seconds();
 	shp->shm_nattch--;
 	if(shp->shm_nattch == 0 &&
@@ -221,7 +256,7 @@
 		shm_destroy(ns, shp);
 	else
 		shm_unlock(shp);
-	mutex_unlock(&shm_ids(ns).mutex);
+	up_write(&shm_ids(ns).rw_mutex);
 }
 
 static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -337,8 +372,19 @@
 #endif
 };
 
-static int newseg (struct ipc_namespace *ns, key_t key, int shmflg, size_t size)
+/**
+ * newseg - Create a new shared memory segment
+ * @ns: namespace
+ * @params: ptr to the structure that contains key, size and shmflg
+ *
+ * Called with shm_ids.rw_mutex held as a writer.
+ */
+
+static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
 {
+	key_t key = params->key;
+	int shmflg = params->flg;
+	size_t size = params->u.size;
 	int error;
 	struct shmid_kernel *shp;
 	int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
@@ -387,28 +433,30 @@
 	if (IS_ERR(file))
 		goto no_file;
 
-	error = -ENOSPC;
 	id = shm_addid(ns, shp);
-	if(id == -1) 
+	if (id < 0) {
+		error = id;
 		goto no_id;
+	}
 
-	shp->shm_cprid = current->tgid;
+	shp->shm_cprid = task_tgid_vnr(current);
 	shp->shm_lprid = 0;
 	shp->shm_atim = shp->shm_dtim = 0;
 	shp->shm_ctim = get_seconds();
 	shp->shm_segsz = size;
 	shp->shm_nattch = 0;
-	shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
+	shp->shm_perm.id = shm_buildid(id, shp->shm_perm.seq);
 	shp->shm_file = file;
 	/*
 	 * shmid gets reported as "inode#" in /proc/pid/maps.
 	 * proc-ps tools use this. Changing this will break them.
 	 */
-	file->f_dentry->d_inode->i_ino = shp->id;
+	file->f_dentry->d_inode->i_ino = shp->shm_perm.id;
 
 	ns->shm_tot += numpages;
+	error = shp->shm_perm.id;
 	shm_unlock(shp);
-	return shp->id;
+	return error;
 
 no_id:
 	fput(file);
@@ -418,42 +466,49 @@
 	return error;
 }
 
-asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
+/*
+ * Called with shm_ids.rw_mutex and ipcp locked.
+ */
+static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
 {
 	struct shmid_kernel *shp;
-	int err, id = 0;
+
+	shp = container_of(ipcp, struct shmid_kernel, shm_perm);
+	return security_shm_associate(shp, shmflg);
+}
+
+/*
+ * Called with shm_ids.rw_mutex and ipcp locked.
+ */
+static inline int shm_more_checks(struct kern_ipc_perm *ipcp,
+				struct ipc_params *params)
+{
+	struct shmid_kernel *shp;
+
+	shp = container_of(ipcp, struct shmid_kernel, shm_perm);
+	if (shp->shm_segsz < params->u.size)
+		return -EINVAL;
+
+	return 0;
+}
+
+asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
+{
 	struct ipc_namespace *ns;
+	struct ipc_ops shm_ops;
+	struct ipc_params shm_params;
 
 	ns = current->nsproxy->ipc_ns;
 
-	mutex_lock(&shm_ids(ns).mutex);
-	if (key == IPC_PRIVATE) {
-		err = newseg(ns, key, shmflg, size);
-	} else if ((id = ipc_findkey(&shm_ids(ns), key)) == -1) {
-		if (!(shmflg & IPC_CREAT))
-			err = -ENOENT;
-		else
-			err = newseg(ns, key, shmflg, size);
-	} else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
-		err = -EEXIST;
-	} else {
-		shp = shm_lock(ns, id);
-		BUG_ON(shp==NULL);
-		if (shp->shm_segsz < size)
-			err = -EINVAL;
-		else if (ipcperms(&shp->shm_perm, shmflg))
-			err = -EACCES;
-		else {
-			int shmid = shm_buildid(ns, id, shp->shm_perm.seq);
-			err = security_shm_associate(shp, shmflg);
-			if (!err)
-				err = shmid;
-		}
-		shm_unlock(shp);
-	}
-	mutex_unlock(&shm_ids(ns).mutex);
+	shm_ops.getnew = newseg;
+	shm_ops.associate = shm_security;
+	shm_ops.more_checks = shm_more_checks;
 
-	return err;
+	shm_params.key = key;
+	shm_params.flg = shmflg;
+	shm_params.u.size = size;
+
+	return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
 }
 
 static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
@@ -547,20 +602,26 @@
 	}
 }
 
+/*
+ * Called with shm_ids.rw_mutex held as a reader
+ */
 static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
 		unsigned long *swp)
 {
-	int i;
+	int next_id;
+	int total, in_use;
 
 	*rss = 0;
 	*swp = 0;
 
-	for (i = 0; i <= shm_ids(ns).max_id; i++) {
+	in_use = shm_ids(ns).in_use;
+
+	for (total = 0, next_id = 0; total < in_use; next_id++) {
 		struct shmid_kernel *shp;
 		struct inode *inode;
 
-		shp = shm_get(ns, i);
-		if(!shp)
+		shp = idr_find(&shm_ids(ns).ipcs_idr, next_id);
+		if (shp == NULL)
 			continue;
 
 		inode = shp->shm_file->f_path.dentry->d_inode;
@@ -575,6 +636,8 @@
 			*swp += info->swapped;
 			spin_unlock(&info->lock);
 		}
+
+		total++;
 	}
 }
 
@@ -610,8 +673,11 @@
 		shminfo.shmmin = SHMMIN;
 		if(copy_shminfo_to_user (buf, &shminfo, version))
 			return -EFAULT;
-		/* reading a integer is always atomic */
-		err= shm_ids(ns).max_id;
+
+		down_read(&shm_ids(ns).rw_mutex);
+		err = ipc_get_maxid(&shm_ids(ns));
+		up_read(&shm_ids(ns).rw_mutex);
+
 		if(err<0)
 			err = 0;
 		goto out;
@@ -625,14 +691,14 @@
 			return err;
 
 		memset(&shm_info,0,sizeof(shm_info));
-		mutex_lock(&shm_ids(ns).mutex);
+		down_read(&shm_ids(ns).rw_mutex);
 		shm_info.used_ids = shm_ids(ns).in_use;
 		shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
 		shm_info.shm_tot = ns->shm_tot;
 		shm_info.swap_attempts = 0;
 		shm_info.swap_successes = 0;
-		err = shm_ids(ns).max_id;
-		mutex_unlock(&shm_ids(ns).mutex);
+		err = ipc_get_maxid(&shm_ids(ns));
+		up_read(&shm_ids(ns).rw_mutex);
 		if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
 			err = -EFAULT;
 			goto out;
@@ -646,20 +712,25 @@
 	{
 		struct shmid64_ds tbuf;
 		int result;
-		memset(&tbuf, 0, sizeof(tbuf));
-		shp = shm_lock(ns, shmid);
-		if(shp==NULL) {
-			err = -EINVAL;
+
+		if (!buf) {
+			err = -EFAULT;
 			goto out;
-		} else if(cmd==SHM_STAT) {
-			err = -EINVAL;
-			if (shmid > shm_ids(ns).max_id)
-				goto out_unlock;
-			result = shm_buildid(ns, shmid, shp->shm_perm.seq);
+		}
+
+		if (cmd == SHM_STAT) {
+			shp = shm_lock(ns, shmid);
+			if (IS_ERR(shp)) {
+				err = PTR_ERR(shp);
+				goto out;
+			}
+			result = shp->shm_perm.id;
 		} else {
-			err = shm_checkid(ns, shp,shmid);
-			if(err)
-				goto out_unlock;
+			shp = shm_lock_check(ns, shmid);
+			if (IS_ERR(shp)) {
+				err = PTR_ERR(shp);
+				goto out;
+			}
 			result = 0;
 		}
 		err=-EACCES;
@@ -668,6 +739,7 @@
 		err = security_shm_shmctl(shp, cmd);
 		if (err)
 			goto out_unlock;
+		memset(&tbuf, 0, sizeof(tbuf));
 		kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
 		tbuf.shm_segsz	= shp->shm_segsz;
 		tbuf.shm_atime	= shp->shm_atim;
@@ -686,14 +758,11 @@
 	case SHM_LOCK:
 	case SHM_UNLOCK:
 	{
-		shp = shm_lock(ns, shmid);
-		if(shp==NULL) {
-			err = -EINVAL;
+		shp = shm_lock_check(ns, shmid);
+		if (IS_ERR(shp)) {
+			err = PTR_ERR(shp);
 			goto out;
 		}
-		err = shm_checkid(ns, shp,shmid);
-		if(err)
-			goto out_unlock;
 
 		err = audit_ipc_obj(&(shp->shm_perm));
 		if (err)
@@ -742,14 +811,12 @@
 		 *	Instead we set a destroyed flag, and then blow
 		 *	the name away when the usage hits zero.
 		 */
-		mutex_lock(&shm_ids(ns).mutex);
-		shp = shm_lock(ns, shmid);
-		err = -EINVAL;
-		if (shp == NULL) 
+		down_write(&shm_ids(ns).rw_mutex);
+		shp = shm_lock_check_down(ns, shmid);
+		if (IS_ERR(shp)) {
+			err = PTR_ERR(shp);
 			goto out_up;
-		err = shm_checkid(ns, shp, shmid);
-		if(err)
-			goto out_unlock_up;
+		}
 
 		err = audit_ipc_obj(&(shp->shm_perm));
 		if (err)
@@ -767,24 +834,27 @@
 			goto out_unlock_up;
 
 		do_shm_rmid(ns, shp);
-		mutex_unlock(&shm_ids(ns).mutex);
+		up_write(&shm_ids(ns).rw_mutex);
 		goto out;
 	}
 
 	case IPC_SET:
 	{
+		if (!buf) {
+			err = -EFAULT;
+			goto out;
+		}
+
 		if (copy_shmid_from_user (&setbuf, buf, version)) {
 			err = -EFAULT;
 			goto out;
 		}
-		mutex_lock(&shm_ids(ns).mutex);
-		shp = shm_lock(ns, shmid);
-		err=-EINVAL;
-		if(shp==NULL)
+		down_write(&shm_ids(ns).rw_mutex);
+		shp = shm_lock_check_down(ns, shmid);
+		if (IS_ERR(shp)) {
+			err = PTR_ERR(shp);
 			goto out_up;
-		err = shm_checkid(ns, shp,shmid);
-		if(err)
-			goto out_unlock_up;
+		}
 		err = audit_ipc_obj(&(shp->shm_perm));
 		if (err)
 			goto out_unlock_up;
@@ -819,7 +889,7 @@
 out_unlock_up:
 	shm_unlock(shp);
 out_up:
-	mutex_unlock(&shm_ids(ns).mutex);
+	up_write(&shm_ids(ns).rw_mutex);
 	goto out;
 out_unlock:
 	shm_unlock(shp);
@@ -890,13 +960,11 @@
 	 * additional creator id...
 	 */
 	ns = current->nsproxy->ipc_ns;
-	shp = shm_lock(ns, shmid);
-	if(shp == NULL)
+	shp = shm_lock_check(ns, shmid);
+	if (IS_ERR(shp)) {
+		err = PTR_ERR(shp);
 		goto out;
-
-	err = shm_checkid(ns, shp,shmid);
-	if (err)
-		goto out_unlock;
+	}
 
 	err = -EACCES;
 	if (ipcperms(&shp->shm_perm, acc_mode))
@@ -925,7 +993,7 @@
 
 	file->private_data = sfd;
 	file->f_mapping = shp->shm_file->f_mapping;
-	sfd->id = shp->id;
+	sfd->id = shp->shm_perm.id;
 	sfd->ns = get_ipc_ns(ns);
 	sfd->file = shp->shm_file;
 	sfd->vm_ops = NULL;
@@ -955,16 +1023,16 @@
 	fput(file);
 
 out_nattch:
-	mutex_lock(&shm_ids(ns).mutex);
-	shp = shm_lock(ns, shmid);
-	BUG_ON(!shp);
+	down_write(&shm_ids(ns).rw_mutex);
+	shp = shm_lock_down(ns, shmid);
+	BUG_ON(IS_ERR(shp));
 	shp->shm_nattch--;
 	if(shp->shm_nattch == 0 &&
 	   shp->shm_perm.mode & SHM_DEST)
 		shm_destroy(ns, shp);
 	else
 		shm_unlock(shp);
-	mutex_unlock(&shm_ids(ns).mutex);
+	up_write(&shm_ids(ns).rw_mutex);
 
 out:
 	return err;
@@ -1094,7 +1162,7 @@
 		format = BIG_STRING;
 	return seq_printf(s, format,
 			  shp->shm_perm.key,
-			  shp->id,
+			  shp->shm_perm.id,
 			  shp->shm_perm.mode,
 			  shp->shm_segsz,
 			  shp->shm_cprid,
diff --git a/ipc/util.c b/ipc/util.c
index 44e5135..1aa0ebf 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -32,6 +32,7 @@
 #include <linux/proc_fs.h>
 #include <linux/audit.h>
 #include <linux/nsproxy.h>
+#include <linux/rwsem.h>
 
 #include <asm/unistd.h>
 
@@ -129,23 +130,16 @@
 /**
  *	ipc_init_ids		-	initialise IPC identifiers
  *	@ids: Identifier set
- *	@size: Number of identifiers
  *
- *	Given a size for the ipc identifier range (limited below IPCMNI)
- *	set up the sequence range to use then allocate and initialise the
- *	array itself. 
+ *	Set up the sequence range to use for the ipc identifier range (limited
+ *	below IPCMNI) then initialise the ids idr.
  */
  
-void ipc_init_ids(struct ipc_ids* ids, int size)
+void ipc_init_ids(struct ipc_ids *ids)
 {
-	int i;
+	init_rwsem(&ids->rw_mutex);
 
-	mutex_init(&ids->mutex);
-
-	if(size > IPCMNI)
-		size = IPCMNI;
 	ids->in_use = 0;
-	ids->max_id = -1;
 	ids->seq = 0;
 	{
 		int seq_limit = INT_MAX/SEQ_MULTIPLIER;
@@ -155,17 +149,7 @@
 		 	ids->seq_max = seq_limit;
 	}
 
-	ids->entries = ipc_rcu_alloc(sizeof(struct kern_ipc_perm *)*size +
-				     sizeof(struct ipc_id_ary));
-
-	if(ids->entries == NULL) {
-		printk(KERN_ERR "ipc_init_ids() failed, ipc service disabled.\n");
-		size = 0;
-		ids->entries = &ids->nullentry;
-	}
-	ids->entries->size = size;
-	for(i=0;i<size;i++)
-		ids->entries->p[i] = NULL;
+	idr_init(&ids->ipcs_idr);
 }
 
 #ifdef CONFIG_PROC_FS
@@ -208,99 +192,96 @@
  *	@ids: Identifier set
  *	@key: The key to find
  *	
- *	Requires ipc_ids.mutex locked.
- *	Returns the identifier if found or -1 if not.
+ *	Requires ipc_ids.rw_mutex locked.
+ *	Returns the LOCKED pointer to the ipc structure if found or NULL
+ *	if not.
+ *	If key is found ipc points to the owning ipc structure
  */
  
-int ipc_findkey(struct ipc_ids* ids, key_t key)
+static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
 {
-	int id;
-	struct kern_ipc_perm* p;
-	int max_id = ids->max_id;
+	struct kern_ipc_perm *ipc;
+	int next_id;
+	int total;
 
-	/*
-	 * rcu_dereference() is not needed here
-	 * since ipc_ids.mutex is held
-	 */
-	for (id = 0; id <= max_id; id++) {
-		p = ids->entries->p[id];
-		if(p==NULL)
+	for (total = 0, next_id = 0; total < ids->in_use; next_id++) {
+		ipc = idr_find(&ids->ipcs_idr, next_id);
+
+		if (ipc == NULL)
 			continue;
-		if (key == p->key)
-			return id;
+
+		if (ipc->key != key) {
+			total++;
+			continue;
+		}
+
+		ipc_lock_by_ptr(ipc);
+		return ipc;
 	}
-	return -1;
+
+	return NULL;
 }
 
-/*
- * Requires ipc_ids.mutex locked
+/**
+ *	ipc_get_maxid 	-	get the last assigned id
+ *	@ids: IPC identifier set
+ *
+ *	Called with ipc_ids.rw_mutex held.
  */
-static int grow_ary(struct ipc_ids* ids, int newsize)
+
+int ipc_get_maxid(struct ipc_ids *ids)
 {
-	struct ipc_id_ary* new;
-	struct ipc_id_ary* old;
-	int i;
-	int size = ids->entries->size;
+	struct kern_ipc_perm *ipc;
+	int max_id = -1;
+	int total, id;
 
-	if(newsize > IPCMNI)
-		newsize = IPCMNI;
-	if(newsize <= size)
-		return newsize;
+	if (ids->in_use == 0)
+		return -1;
 
-	new = ipc_rcu_alloc(sizeof(struct kern_ipc_perm *)*newsize +
-			    sizeof(struct ipc_id_ary));
-	if(new == NULL)
-		return size;
-	new->size = newsize;
-	memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size);
-	for(i=size;i<newsize;i++) {
-		new->p[i] = NULL;
+	if (ids->in_use == IPCMNI)
+		return IPCMNI - 1;
+
+	/* Look for the last assigned id */
+	total = 0;
+	for (id = 0; id < IPCMNI && total < ids->in_use; id++) {
+		ipc = idr_find(&ids->ipcs_idr, id);
+		if (ipc != NULL) {
+			max_id = id;
+			total++;
+		}
 	}
-	old = ids->entries;
-
-	/*
-	 * Use rcu_assign_pointer() to make sure the memcpyed contents
-	 * of the new array are visible before the new array becomes visible.
-	 */
-	rcu_assign_pointer(ids->entries, new);
-
-	__ipc_fini_ids(ids, old);
-	return newsize;
+	return max_id;
 }
 
 /**
  *	ipc_addid 	-	add an IPC identifier
  *	@ids: IPC identifier set
  *	@new: new IPC permission set
- *	@size: new size limit for the id array
+ *	@size: limit for the number of used ids
  *
- *	Add an entry 'new' to the IPC arrays. The permissions object is
+ *	Add an entry 'new' to the IPC ids idr. The permissions object is
  *	initialised and the first free entry is set up and the id assigned
- *	is returned. The list is returned in a locked state on success.
- *	On failure the list is not locked and -1 is returned.
+ *	is returned. The 'new' entry is returned in a locked state on success.
+ *	On failure the entry is not locked and a negative err-code is returned.
  *
- *	Called with ipc_ids.mutex held.
+ *	Called with ipc_ids.rw_mutex held as a writer.
  */
  
 int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
 {
-	int id;
+	int id, err;
 
-	size = grow_ary(ids,size);
+	if (size > IPCMNI)
+		size = IPCMNI;
 
-	/*
-	 * rcu_dereference()() is not needed here since
-	 * ipc_ids.mutex is held
-	 */
-	for (id = 0; id < size; id++) {
-		if(ids->entries->p[id] == NULL)
-			goto found;
-	}
-	return -1;
-found:
+	if (ids->in_use >= size)
+		return -ENOSPC;
+
+	err = idr_get_new(&ids->ipcs_idr, new, &id);
+	if (err)
+		return err;
+
 	ids->in_use++;
-	if (id > ids->max_id)
-		ids->max_id = id;
 
 	new->cuid = new->uid = current->euid;
 	new->gid = new->cgid = current->egid;
@@ -313,48 +294,153 @@
 	new->deleted = 0;
 	rcu_read_lock();
 	spin_lock(&new->lock);
-	ids->entries->p[id] = new;
 	return id;
 }
 
 /**
- *	ipc_rmid	-	remove an IPC identifier
- *	@ids: identifier set
- *	@id: Identifier to remove
+ *	ipcget_new	-	create a new ipc object
+ *	@ns: namespace
+ *	@ids: IPC identifer set
+ *	@ops: the actual creation routine to call
+ *	@params: its parameters
  *
- *	The identifier must be valid, and in use. The kernel will panic if
- *	fed an invalid identifier. The entry is removed and internal
- *	variables recomputed. The object associated with the identifier
- *	is returned.
- *	ipc_ids.mutex and the spinlock for this ID is hold before this function
- *	is called, and remain locked on the exit.
+ *	This routine is called by sys_msgget, sys_semget() and sys_shmget()
+ *	when the key is IPC_PRIVATE.
+ */
+int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
+		struct ipc_ops *ops, struct ipc_params *params)
+{
+	int err;
+retry:
+	err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
+
+	if (!err)
+		return -ENOMEM;
+
+	down_write(&ids->rw_mutex);
+	err = ops->getnew(ns, params);
+	up_write(&ids->rw_mutex);
+
+	if (err == -EAGAIN)
+		goto retry;
+
+	return err;
+}
+
+/**
+ *	ipc_check_perms	-	check security and permissions for an IPC
+ *	@ipcp: ipc permission set
+ *	@ops: the actual security routine to call
+ *	@params: its parameters
+ *
+ *	This routine is called by sys_msgget(), sys_semget() and sys_shmget()
+ *      when the key is not IPC_PRIVATE and that key already exists in the
+ *      ids IDR.
+ *
+ *	On success, the IPC id is returned.
+ *
+ *	It is called with ipc_ids.rw_mutex and ipcp->lock held.
+ */
+static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops,
+			struct ipc_params *params)
+{
+	int err;
+
+	if (ipcperms(ipcp, params->flg))
+		err = -EACCES;
+	else {
+		err = ops->associate(ipcp, params->flg);
+		if (!err)
+			err = ipcp->id;
+	}
+
+	return err;
+}
+
+/**
+ *	ipcget_public	-	get an ipc object or create a new one
+ *	@ns: namespace
+ *	@ids: IPC identifer set
+ *	@ops: the actual creation routine to call
+ *	@params: its parameters
+ *
+ *	This routine is called by sys_msgget, sys_semget() and sys_shmget()
+ *	when the key is not IPC_PRIVATE.
+ *	It adds a new entry if the key is not found and does some permission
+ *      / security checkings if the key is found.
+ *
+ *	On success, the ipc id is returned.
+ */
+int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
+		struct ipc_ops *ops, struct ipc_params *params)
+{
+	struct kern_ipc_perm *ipcp;
+	int flg = params->flg;
+	int err;
+retry:
+	err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
+
+	/*
+	 * Take the lock as a writer since we are potentially going to add
+	 * a new entry + read locks are not "upgradable"
+	 */
+	down_write(&ids->rw_mutex);
+	ipcp = ipc_findkey(ids, params->key);
+	if (ipcp == NULL) {
+		/* key not used */
+		if (!(flg & IPC_CREAT))
+			err = -ENOENT;
+		else if (!err)
+			err = -ENOMEM;
+		else
+			err = ops->getnew(ns, params);
+	} else {
+		/* ipc object has been locked by ipc_findkey() */
+
+		if (flg & IPC_CREAT && flg & IPC_EXCL)
+			err = -EEXIST;
+		else {
+			err = 0;
+			if (ops->more_checks)
+				err = ops->more_checks(ipcp, params);
+			if (!err)
+				/*
+				 * ipc_check_perms returns the IPC id on
+				 * success
+				 */
+				err = ipc_check_perms(ipcp, ops, params);
+		}
+		ipc_unlock(ipcp);
+	}
+	up_write(&ids->rw_mutex);
+
+	if (err == -EAGAIN)
+		goto retry;
+
+	return err;
+}
+
+
+/**
+ *	ipc_rmid	-	remove an IPC identifier
+ *	@ids: IPC identifier set
+ *	@ipcp: ipc perm structure containing the identifier to remove
+ *
+ *	ipc_ids.rw_mutex (as a writer) and the spinlock for this ID are held
+ *	before this function is called, and remain locked on the exit.
  */
  
-struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id)
+void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
 {
-	struct kern_ipc_perm* p;
-	int lid = id % SEQ_MULTIPLIER;
-	BUG_ON(lid >= ids->entries->size);
+	int lid = ipcid_to_idx(ipcp->id);
 
-	/* 
-	 * do not need a rcu_dereference()() here to force ordering
-	 * on Alpha, since the ipc_ids.mutex is held.
-	 */	
-	p = ids->entries->p[lid];
-	ids->entries->p[lid] = NULL;
-	BUG_ON(p==NULL);
+	idr_remove(&ids->ipcs_idr, lid);
+
 	ids->in_use--;
 
-	if (lid == ids->max_id) {
-		do {
-			lid--;
-			if(lid == -1)
-				break;
-		} while (ids->entries->p[lid] == NULL);
-		ids->max_id = lid;
-	}
-	p->deleted = 1;
-	return p;
+	ipcp->deleted = 1;
+
+	return;
 }
 
 /**
@@ -491,10 +577,12 @@
  */
 static void ipc_schedule_free(struct rcu_head *head)
 {
-	struct ipc_rcu_grace *grace =
-		container_of(head, struct ipc_rcu_grace, rcu);
-	struct ipc_rcu_sched *sched =
-			container_of(&(grace->data[0]), struct ipc_rcu_sched, data[0]);
+	struct ipc_rcu_grace *grace;
+	struct ipc_rcu_sched *sched;
+
+	grace = container_of(head, struct ipc_rcu_grace, rcu);
+	sched = container_of(&(grace->data[0]), struct ipc_rcu_sched,
+				data[0]);
 
 	INIT_WORK(&sched->work, ipc_do_vfree);
 	schedule_work(&sched->work);
@@ -583,7 +671,7 @@
 }
 
 /**
- *	ipc64_perm_to_ipc_perm	-	convert old ipc permissions to new
+ *	ipc64_perm_to_ipc_perm	-	convert new ipc permissions to old
  *	@in: new style IPC permissions
  *	@out: old style IPC permissions
  *
@@ -602,44 +690,37 @@
 	out->seq	= in->seq;
 }
 
-/*
- * So far only shm_get_stat() calls ipc_get() via shm_get(), so ipc_get()
- * is called with shm_ids.mutex locked.  Since grow_ary() is also called with
- * shm_ids.mutex down(for Shared Memory), there is no need to add read
- * barriers here to gurantee the writes in grow_ary() are seen in order 
- * here (for Alpha).
+/**
+ * ipc_lock - Lock an ipc structure without rw_mutex held
+ * @ids: IPC identifier set
+ * @id: ipc id to look for
  *
- * However ipc_get() itself does not necessary require ipc_ids.mutex down. So
- * if in the future ipc_get() is used by other places without ipc_ids.mutex
- * down, then ipc_get() needs read memery barriers as ipc_lock() does.
+ * Look for an id in the ipc ids idr and lock the associated ipc object.
+ *
+ * The ipc object is locked on exit.
+ *
+ * This is the routine that should be called when the rw_mutex is not already
+ * held, i.e. idr tree not protected: it protects the idr tree in read mode
+ * during the idr_find().
  */
-struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id)
-{
-	struct kern_ipc_perm* out;
-	int lid = id % SEQ_MULTIPLIER;
-	if(lid >= ids->entries->size)
-		return NULL;
-	out = ids->entries->p[lid];
-	return out;
-}
 
-struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id)
+struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id)
 {
-	struct kern_ipc_perm* out;
-	int lid = id % SEQ_MULTIPLIER;
-	struct ipc_id_ary* entries;
+	struct kern_ipc_perm *out;
+	int lid = ipcid_to_idx(id);
+
+	down_read(&ids->rw_mutex);
 
 	rcu_read_lock();
-	entries = rcu_dereference(ids->entries);
-	if(lid >= entries->size) {
+	out = idr_find(&ids->ipcs_idr, lid);
+	if (out == NULL) {
 		rcu_read_unlock();
-		return NULL;
+		up_read(&ids->rw_mutex);
+		return ERR_PTR(-EINVAL);
 	}
-	out = entries->p[lid];
-	if(out == NULL) {
-		rcu_read_unlock();
-		return NULL;
-	}
+
+	up_read(&ids->rw_mutex);
+
 	spin_lock(&out->lock);
 	
 	/* ipc_rmid() may have already freed the ID while ipc_lock
@@ -648,33 +729,44 @@
 	if (out->deleted) {
 		spin_unlock(&out->lock);
 		rcu_read_unlock();
-		return NULL;
+		return ERR_PTR(-EINVAL);
 	}
+
 	return out;
 }
 
-void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
+/**
+ * ipc_lock_down - Lock an ipc structure with rw_sem held
+ * @ids: IPC identifier set
+ * @id: ipc id to look for
+ *
+ * Look for an id in the ipc ids idr and lock the associated ipc object.
+ *
+ * The ipc object is locked on exit.
+ *
+ * This is the routine that should be called when the rw_mutex is already
+ * held, i.e. idr tree protected.
+ */
+
+struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *ids, int id)
 {
+	struct kern_ipc_perm *out;
+	int lid = ipcid_to_idx(id);
+
 	rcu_read_lock();
-	spin_lock(&perm->lock);
-}
+	out = idr_find(&ids->ipcs_idr, lid);
+	if (out == NULL) {
+		rcu_read_unlock();
+		return ERR_PTR(-EINVAL);
+	}
 
-void ipc_unlock(struct kern_ipc_perm* perm)
-{
-	spin_unlock(&perm->lock);
-	rcu_read_unlock();
-}
+	spin_lock(&out->lock);
 
-int ipc_buildid(struct ipc_ids* ids, int id, int seq)
-{
-	return SEQ_MULTIPLIER*seq + id;
-}
-
-int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid)
-{
-	if(uid/SEQ_MULTIPLIER != ipcp->seq)
-		return 1;
-	return 0;
+	/*
+	 * No need to verify that the structure is still valid since the
+	 * rw_mutex is held.
+	 */
+	return out;
 }
 
 #ifdef __ARCH_WANT_IPC_PARSE_VERSION
@@ -707,27 +799,30 @@
 	struct ipc_proc_iface *iface;
 };
 
-static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
+/*
+ * This routine locks the ipc structure found at least at position pos.
+ */
+struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos,
+					loff_t *new_pos)
 {
-	struct ipc_proc_iter *iter = s->private;
-	struct ipc_proc_iface *iface = iter->iface;
-	struct kern_ipc_perm *ipc = it;
-	loff_t p;
-	struct ipc_ids *ids;
+	struct kern_ipc_perm *ipc;
+	int total, id;
 
-	ids = iter->ns->ids[iface->ids];
+	total = 0;
+	for (id = 0; id < pos && total < ids->in_use; id++) {
+		ipc = idr_find(&ids->ipcs_idr, id);
+		if (ipc != NULL)
+			total++;
+	}
 
-	/* If we had an ipc id locked before, unlock it */
-	if (ipc && ipc != SEQ_START_TOKEN)
-		ipc_unlock(ipc);
+	if (total >= ids->in_use)
+		return NULL;
 
-	/*
-	 * p = *pos - 1 (because id 0 starts at position 1)
-	 *          + 1 (because we increment the position by one)
-	 */
-	for (p = *pos; p <= ids->max_id; p++) {
-		if ((ipc = ipc_lock(ids, p)) != NULL) {
-			*pos = p + 1;
+	for ( ; pos < IPCMNI; pos++) {
+		ipc = idr_find(&ids->ipcs_idr, pos);
+		if (ipc != NULL) {
+			*new_pos = pos + 1;
+			ipc_lock_by_ptr(ipc);
 			return ipc;
 		}
 	}
@@ -736,16 +831,27 @@
 	return NULL;
 }
 
+static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
+{
+	struct ipc_proc_iter *iter = s->private;
+	struct ipc_proc_iface *iface = iter->iface;
+	struct kern_ipc_perm *ipc = it;
+
+	/* If we had an ipc id locked before, unlock it */
+	if (ipc && ipc != SEQ_START_TOKEN)
+		ipc_unlock(ipc);
+
+	return sysvipc_find_ipc(iter->ns->ids[iface->ids], *pos, pos);
+}
+
 /*
- * File positions: pos 0 -> header, pos n -> ipc id + 1.
- * SeqFile iterator: iterator value locked shp or SEQ_TOKEN_START.
+ * File positions: pos 0 -> header, pos n -> ipc id = n - 1.
+ * SeqFile iterator: iterator value locked ipc pointer or SEQ_TOKEN_START.
  */
 static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
 {
 	struct ipc_proc_iter *iter = s->private;
 	struct ipc_proc_iface *iface = iter->iface;
-	struct kern_ipc_perm *ipc;
-	loff_t p;
 	struct ipc_ids *ids;
 
 	ids = iter->ns->ids[iface->ids];
@@ -754,7 +860,7 @@
 	 * Take the lock - this will be released by the corresponding
 	 * call to stop().
 	 */
-	mutex_lock(&ids->mutex);
+	down_read(&ids->rw_mutex);
 
 	/* pos < 0 is invalid */
 	if (*pos < 0)
@@ -765,13 +871,7 @@
 		return SEQ_START_TOKEN;
 
 	/* Find the (pos-1)th ipc */
-	for (p = *pos - 1; p <= ids->max_id; p++) {
-		if ((ipc = ipc_lock(ids, p)) != NULL) {
-			*pos = p + 1;
-			return ipc;
-		}
-	}
-	return NULL;
+	return sysvipc_find_ipc(ids, *pos - 1, pos);
 }
 
 static void sysvipc_proc_stop(struct seq_file *s, void *it)
@@ -781,13 +881,13 @@
 	struct ipc_proc_iface *iface = iter->iface;
 	struct ipc_ids *ids;
 
-	/* If we had a locked segment, release it */
+	/* If we had a locked structure, release it */
 	if (ipc && ipc != SEQ_START_TOKEN)
 		ipc_unlock(ipc);
 
 	ids = iter->ns->ids[iface->ids];
 	/* Release the lock we took in start() */
-	mutex_unlock(&ids->mutex);
+	up_read(&ids->rw_mutex);
 }
 
 static int sysvipc_proc_show(struct seq_file *s, void *it)
diff --git a/ipc/util.h b/ipc/util.h
index 333e891..9ffea40 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -10,6 +10,9 @@
 #ifndef _IPC_UTIL_H
 #define _IPC_UTIL_H
 
+#include <linux/idr.h>
+#include <linux/err.h>
+
 #define USHRT_MAX 0xffff
 #define SEQ_MULTIPLIER	(IPCMNI)
 
@@ -25,24 +28,46 @@
 void msg_exit_ns(struct ipc_namespace *ns);
 void shm_exit_ns(struct ipc_namespace *ns);
 
-struct ipc_id_ary {
-	int size;
-	struct kern_ipc_perm *p[0];
-};
-
 struct ipc_ids {
 	int in_use;
-	int max_id;
 	unsigned short seq;
 	unsigned short seq_max;
-	struct mutex mutex;
-	struct ipc_id_ary nullentry;
-	struct ipc_id_ary* entries;
+	struct rw_semaphore rw_mutex;
+	struct idr ipcs_idr;
+};
+
+/*
+ * Structure that holds the parameters needed by the ipc operations
+ * (see after)
+ */
+struct ipc_params {
+	key_t key;
+	int flg;
+	union {
+		size_t size;	/* for shared memories */
+		int nsems;	/* for semaphores */
+	} u;			/* holds the getnew() specific param */
+};
+
+/*
+ * Structure that holds some ipc operations. This structure is used to unify
+ * the calls to sys_msgget(), sys_semget(), sys_shmget()
+ *      . routine to call to create a new ipc object. Can be one of newque,
+ *        newary, newseg
+ *      . routine to call to check permissions for a new ipc object.
+ *        Can be one of security_msg_associate, security_sem_associate,
+ *        security_shm_associate
+ *      . routine to call for an extra check if needed
+ */
+struct ipc_ops {
+	int (*getnew) (struct ipc_namespace *, struct ipc_params *);
+	int (*associate) (struct kern_ipc_perm *, int);
+	int (*more_checks) (struct kern_ipc_perm *, struct ipc_params *);
 };
 
 struct seq_file;
 
-void ipc_init_ids(struct ipc_ids *ids, int size);
+void ipc_init_ids(struct ipc_ids *);
 #ifdef CONFIG_PROC_FS
 void __init ipc_init_proc_interface(const char *path, const char *header,
 		int ids, int (*show)(struct seq_file *, void *));
@@ -54,14 +79,19 @@
 #define IPC_MSG_IDS	1
 #define IPC_SHM_IDS	2
 
-/* must be called with ids->mutex acquired.*/
-int ipc_findkey(struct ipc_ids* ids, key_t key);
-int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size);
+#define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
+
+/* must be called with ids->rw_mutex acquired for writing */
+int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
+
+/* must be called with ids->rw_mutex acquired for reading */
+int ipc_get_maxid(struct ipc_ids *);
 
 /* must be called with both locks acquired. */
-struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id);
+void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *);
 
-int ipcperms (struct kern_ipc_perm *ipcp, short flg);
+/* must be called with ipcp locked */
+int ipcperms(struct kern_ipc_perm *ipcp, short flg);
 
 /* for rare, potentially huge allocations.
  * both function can sleep
@@ -79,24 +109,12 @@
 void ipc_rcu_getref(void *ptr);
 void ipc_rcu_putref(void *ptr);
 
-static inline void __ipc_fini_ids(struct ipc_ids *ids,
-		struct ipc_id_ary *entries)
-{
-	if (entries != &ids->nullentry)
-		ipc_rcu_putref(entries);
-}
-
-static inline void ipc_fini_ids(struct ipc_ids *ids)
-{
-	__ipc_fini_ids(ids, ids->entries);
-}
-
-struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id);
-struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id);
-void ipc_lock_by_ptr(struct kern_ipc_perm *ipcp);
-void ipc_unlock(struct kern_ipc_perm* perm);
-int ipc_buildid(struct ipc_ids* ids, int id, int seq);
-int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid);
+/*
+ * ipc_lock_down: called with rw_mutex held
+ * ipc_lock: called without that lock held
+ */
+struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *, int);
+struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int);
 
 void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out);
 void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out);
@@ -111,5 +129,89 @@
 extern void free_msg(struct msg_msg *msg);
 extern struct msg_msg *load_msg(const void __user *src, int len);
 extern int store_msg(void __user *dest, struct msg_msg *msg, int len);
+extern int ipcget_new(struct ipc_namespace *, struct ipc_ids *,
+			struct ipc_ops *, struct ipc_params *);
+extern int ipcget_public(struct ipc_namespace *, struct ipc_ids *,
+			struct ipc_ops *, struct ipc_params *);
+
+static inline int ipc_buildid(int id, int seq)
+{
+	return SEQ_MULTIPLIER * seq + id;
+}
+
+/*
+ * Must be called with ipcp locked
+ */
+static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid)
+{
+	if (uid / SEQ_MULTIPLIER != ipcp->seq)
+		return 1;
+	return 0;
+}
+
+static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
+{
+	rcu_read_lock();
+	spin_lock(&perm->lock);
+}
+
+static inline void ipc_unlock(struct kern_ipc_perm *perm)
+{
+	spin_unlock(&perm->lock);
+	rcu_read_unlock();
+}
+
+static inline struct kern_ipc_perm *ipc_lock_check_down(struct ipc_ids *ids,
+						int id)
+{
+	struct kern_ipc_perm *out;
+
+	out = ipc_lock_down(ids, id);
+	if (IS_ERR(out))
+		return out;
+
+	if (ipc_checkid(out, id)) {
+		ipc_unlock(out);
+		return ERR_PTR(-EIDRM);
+	}
+
+	return out;
+}
+
+static inline struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids,
+						int id)
+{
+	struct kern_ipc_perm *out;
+
+	out = ipc_lock(ids, id);
+	if (IS_ERR(out))
+		return out;
+
+	if (ipc_checkid(out, id)) {
+		ipc_unlock(out);
+		return ERR_PTR(-EIDRM);
+	}
+
+	return out;
+}
+
+/**
+ * ipcget - Common sys_*get() code
+ * @ns : namsepace
+ * @ids : IPC identifier set
+ * @ops : operations to be called on ipc object creation, permission checks
+ *        and further checks
+ * @params : the parameters needed by the previous operations.
+ *
+ * Common routine called by sys_msgget(), sys_semget() and sys_shmget().
+ */
+static inline int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
+			struct ipc_ops *ops, struct ipc_params *params)
+{
+	if (params->key == IPC_PRIVATE)
+		return ipcget_new(ns, ids, ops, params);
+	else
+		return ipcget_public(ns, ids, ops, params);
+}
 
 #endif
diff --git a/kernel/Kconfig.instrumentation b/kernel/Kconfig.instrumentation
new file mode 100644
index 0000000..f5f2c76
--- /dev/null
+++ b/kernel/Kconfig.instrumentation
@@ -0,0 +1,49 @@
+menuconfig INSTRUMENTATION
+	bool "Instrumentation Support"
+	default y
+	---help---
+	  Say Y here to get to see options related to performance measurement,
+	  system-wide debugging, and testing. This option alone does not add any
+	  kernel code.
+
+	  If you say N, all options in this submenu will be skipped and
+	  disabled. If you're trying to debug the kernel itself, go see the
+	  Kernel Hacking menu.
+
+if INSTRUMENTATION
+
+config PROFILING
+	bool "Profiling support (EXPERIMENTAL)"
+	help
+	  Say Y here to enable the extended profiling support mechanisms used
+	  by profilers such as OProfile.
+
+config OPROFILE
+	tristate "OProfile system profiling (EXPERIMENTAL)"
+	depends on PROFILING
+	depends on ALPHA || ARM || BLACKFIN || X86_32 || IA64 || M32R || MIPS || PARISC || PPC || S390 || SUPERH || SPARC || X86_64
+	help
+	  OProfile is a profiling system capable of profiling the
+	  whole system, include the kernel, kernel modules, libraries,
+	  and applications.
+
+	  If unsure, say N.
+
+config KPROBES
+	bool "Kprobes"
+	depends on KALLSYMS && MODULES
+	depends on X86_32 || IA64 || PPC || S390 || SPARC64 || X86_64 || AVR32
+	help
+	  Kprobes allows you to trap at almost any kernel address and
+	  execute a callback function.  register_kprobe() establishes
+	  a probepoint and specifies the callback.  Kprobes is useful
+	  for kernel debugging, non-intrusive instrumentation and testing.
+	  If in doubt, say "N".
+
+config MARKERS
+	bool "Activate markers"
+	help
+	  Place an empty function call at each marker site. Can be
+	  dynamically changed for a probe function.
+
+endif # INSTRUMENTATION
diff --git a/kernel/Makefile b/kernel/Makefile
index 2a99983..f60afe7 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -8,9 +8,10 @@
 	    signal.o sys.o kmod.o workqueue.o pid.o \
 	    rcupdate.o extable.o params.o posix-timers.o \
 	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
-	    hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o \
-	    utsname.o
+	    hrtimer.o rwsem.o latency.o nsproxy.o srcu.o \
+	    utsname.o notifier.o
 
+obj-$(CONFIG_SYSCTL) += sysctl_check.o
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-y += time/
 obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
@@ -36,11 +37,16 @@
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
 obj-$(CONFIG_KEXEC) += kexec.o
 obj-$(CONFIG_COMPAT) += compat.o
+obj-$(CONFIG_CGROUPS) += cgroup.o
+obj-$(CONFIG_CGROUP_DEBUG) += cgroup_debug.o
 obj-$(CONFIG_CPUSETS) += cpuset.o
+obj-$(CONFIG_CGROUP_CPUACCT) += cpu_acct.o
+obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o
 obj-$(CONFIG_IKCONFIG) += configs.o
 obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
 obj-$(CONFIG_AUDIT) += audit.o auditfilter.o
 obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
+obj-$(CONFIG_AUDIT_TREE) += audit_tree.o
 obj-$(CONFIG_KPROBES) += kprobes.o
 obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
@@ -51,6 +57,7 @@
 obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
 obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
 obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
+obj-$(CONFIG_MARKERS) += marker.o
 
 ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/acct.c b/kernel/acct.c
index 24f0f8b..fce53d8 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -329,16 +329,16 @@
 	}
 
 	/*
-         * If we need to round up, do it (and handle overflow correctly).
-         */
+	 * If we need to round up, do it (and handle overflow correctly).
+	 */
 	if (rnd && (++value > MAXFRACT)) {
 		value >>= EXPSIZE;
 		exp++;
 	}
 
 	/*
-         * Clean it up and polish it off.
-         */
+	 * Clean it up and polish it off.
+	 */
 	exp <<= MANTSIZE;		/* Shift the exponent into place */
 	exp += value;			/* and add on the mantissa. */
 	return exp;
@@ -361,30 +361,30 @@
 
 static comp2_t encode_comp2_t(u64 value)
 {
-        int exp, rnd;
+	int exp, rnd;
 
-        exp = (value > (MAXFRACT2>>1));
-        rnd = 0;
-        while (value > MAXFRACT2) {
-                rnd = value & 1;
-                value >>= 1;
-                exp++;
-        }
+	exp = (value > (MAXFRACT2>>1));
+	rnd = 0;
+	while (value > MAXFRACT2) {
+		rnd = value & 1;
+		value >>= 1;
+		exp++;
+	}
 
-        /*
-         * If we need to round up, do it (and handle overflow correctly).
-         */
-        if (rnd && (++value > MAXFRACT2)) {
-                value >>= 1;
-                exp++;
-        }
+	/*
+	 * If we need to round up, do it (and handle overflow correctly).
+	 */
+	if (rnd && (++value > MAXFRACT2)) {
+		value >>= 1;
+		exp++;
+	}
 
-        if (exp > MAXEXP2) {
-                /* Overflow. Return largest representable number instead. */
-                return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;
-        } else {
-                return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));
-        }
+	if (exp > MAXEXP2) {
+		/* Overflow. Return largest representable number instead. */
+		return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;
+	} else {
+		return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));
+	}
 }
 #endif
 
@@ -501,14 +501,14 @@
 	ac.ac_swaps = encode_comp_t(0);
 
 	/*
-         * Kernel segment override to datasegment and write it
-         * to the accounting file.
-         */
+	 * Kernel segment override to datasegment and write it
+	 * to the accounting file.
+	 */
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 	/*
- 	 * Accounting records are not subject to resource limits.
- 	 */
+	 * Accounting records are not subject to resource limits.
+	 */
 	flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
 	current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 	file->f_op->write(file, (char *)&ac,
diff --git a/kernel/audit.c b/kernel/audit.c
index 2924251..f93c271 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -468,6 +468,21 @@
 	return 0;
 }
 
+#ifdef CONFIG_AUDIT_TREE
+static int prune_tree_thread(void *unused)
+{
+	mutex_lock(&audit_cmd_mutex);
+	audit_prune_trees();
+	mutex_unlock(&audit_cmd_mutex);
+	return 0;
+}
+
+void audit_schedule_prune(void)
+{
+	kthread_run(prune_tree_thread, NULL, "audit_prune_tree");
+}
+#endif
+
 struct sk_buff *audit_make_reply(int pid, int seq, int type, int done,
 				 int multi, void *payload, int size)
 {
@@ -540,6 +555,8 @@
 	case AUDIT_SIGNAL_INFO:
 	case AUDIT_TTY_GET:
 	case AUDIT_TTY_SET:
+	case AUDIT_TRIM:
+	case AUDIT_MAKE_EQUIV:
 		if (security_netlink_recv(skb, CAP_AUDIT_CONTROL))
 			err = -EPERM;
 		break;
@@ -664,11 +681,11 @@
 				if (sid) {
 					if (selinux_sid_to_string(
 							sid, &ctx, &len)) {
-						audit_log_format(ab, 
+						audit_log_format(ab,
 							" ssid=%u", sid);
 						/* Maybe call audit_panic? */
 					} else
-						audit_log_format(ab, 
+						audit_log_format(ab,
 							" subj=%s", ctx);
 					kfree(ctx);
 				}
@@ -756,6 +773,76 @@
 					   uid, seq, data, nlmsg_len(nlh),
 					   loginuid, sid);
 		break;
+	case AUDIT_TRIM:
+		audit_trim_trees();
+		ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+		if (!ab)
+			break;
+		audit_log_format(ab, "auid=%u", loginuid);
+		if (sid) {
+			u32 len;
+			ctx = NULL;
+			if (selinux_sid_to_string(sid, &ctx, &len))
+				audit_log_format(ab, " ssid=%u", sid);
+			else
+				audit_log_format(ab, " subj=%s", ctx);
+			kfree(ctx);
+		}
+		audit_log_format(ab, " op=trim res=1");
+		audit_log_end(ab);
+		break;
+	case AUDIT_MAKE_EQUIV: {
+		void *bufp = data;
+		u32 sizes[2];
+		size_t len = nlmsg_len(nlh);
+		char *old, *new;
+
+		err = -EINVAL;
+		if (len < 2 * sizeof(u32))
+			break;
+		memcpy(sizes, bufp, 2 * sizeof(u32));
+		bufp += 2 * sizeof(u32);
+		len -= 2 * sizeof(u32);
+		old = audit_unpack_string(&bufp, &len, sizes[0]);
+		if (IS_ERR(old)) {
+			err = PTR_ERR(old);
+			break;
+		}
+		new = audit_unpack_string(&bufp, &len, sizes[1]);
+		if (IS_ERR(new)) {
+			err = PTR_ERR(new);
+			kfree(old);
+			break;
+		}
+		/* OK, here comes... */
+		err = audit_tag_tree(old, new);
+
+		ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+		if (!ab) {
+			kfree(old);
+			kfree(new);
+			break;
+		}
+		audit_log_format(ab, "auid=%u", loginuid);
+		if (sid) {
+			u32 len;
+			ctx = NULL;
+			if (selinux_sid_to_string(sid, &ctx, &len))
+				audit_log_format(ab, " ssid=%u", sid);
+			else
+				audit_log_format(ab, " subj=%s", ctx);
+			kfree(ctx);
+		}
+		audit_log_format(ab, " op=make_equiv old=");
+		audit_log_untrustedstring(ab, old);
+		audit_log_format(ab, " new=");
+		audit_log_untrustedstring(ab, new);
+		audit_log_format(ab, " res=%d", !err);
+		audit_log_end(ab);
+		kfree(old);
+		kfree(new);
+		break;
+	}
 	case AUDIT_SIGNAL_INFO:
 		err = selinux_sid_to_string(audit_sig_sid, &ctx, &len);
 		if (err)
@@ -769,7 +856,7 @@
 		sig_data->pid = audit_sig_pid;
 		memcpy(sig_data->ctx, ctx, len);
 		kfree(ctx);
-		audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, 
+		audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO,
 				0, 0, sig_data, sizeof(*sig_data) + len);
 		kfree(sig_data);
 		break;
@@ -1005,7 +1092,7 @@
 	return ret;
 }
 
-static inline void audit_get_stamp(struct audit_context *ctx, 
+static inline void audit_get_stamp(struct audit_context *ctx,
 				   struct timespec *t, unsigned int *serial)
 {
 	if (ctx)
@@ -1056,7 +1143,7 @@
 	if (gfp_mask & __GFP_WAIT)
 		reserve = 0;
 	else
-		reserve = 5; /* Allow atomic callers to go up to five 
+		reserve = 5; /* Allow atomic callers to go up to five
 				entries over the normal backlog limit */
 
 	while (audit_backlog_limit
@@ -1319,7 +1406,7 @@
 	if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
 		/* FIXME: can we save some information here? */
 		audit_log_format(ab, "<too long>");
-	} else 
+	} else
 		audit_log_untrustedstring(ab, p);
 	kfree(path);
 }
@@ -1365,7 +1452,7 @@
  * audit_log_vformat, and audit_log_end.  It may be called
  * in any context.
  */
-void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, 
+void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
 	       const char *fmt, ...)
 {
 	struct audit_buffer *ab;
diff --git a/kernel/audit.h b/kernel/audit.h
index 9587743..2554bd5 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -73,6 +73,9 @@
 	struct selinux_audit_rule	*se_rule;
 };
 
+struct audit_tree;
+struct audit_chunk;
+
 struct audit_krule {
 	int			vers_ops;
 	u32			flags;
@@ -86,7 +89,8 @@
 	struct audit_field	*arch_f; /* quick access to arch field */
 	struct audit_field	*inode_f; /* quick access to an inode field */
 	struct audit_watch	*watch;	/* associated watch */
-	struct list_head	rlist;	/* entry in audit_watch.rules list */
+	struct audit_tree	*tree;	/* associated watched tree */
+	struct list_head	rlist;	/* entry in audit_{watch,tree}.rules list */
 };
 
 struct audit_entry {
@@ -130,6 +134,34 @@
 				const char *, struct inode *);
 extern int selinux_audit_rule_update(void);
 
+extern struct mutex audit_filter_mutex;
+extern void audit_free_rule_rcu(struct rcu_head *);
+
+#ifdef CONFIG_AUDIT_TREE
+extern struct audit_chunk *audit_tree_lookup(const struct inode *);
+extern void audit_put_chunk(struct audit_chunk *);
+extern int audit_tree_match(struct audit_chunk *, struct audit_tree *);
+extern int audit_make_tree(struct audit_krule *, char *, u32);
+extern int audit_add_tree_rule(struct audit_krule *);
+extern int audit_remove_tree_rule(struct audit_krule *);
+extern void audit_trim_trees(void);
+extern int audit_tag_tree(char *old, char *new);
+extern void audit_schedule_prune(void);
+extern void audit_prune_trees(void);
+extern const char *audit_tree_path(struct audit_tree *);
+extern void audit_put_tree(struct audit_tree *);
+#else
+#define audit_remove_tree_rule(rule) BUG()
+#define audit_add_tree_rule(rule) -EINVAL
+#define audit_make_tree(rule, str, op) -EINVAL
+#define audit_trim_trees() (void)0
+#define audit_put_tree(tree) (void)0
+#define audit_tag_tree(old, new) -EINVAL
+#define audit_tree_path(rule) ""	/* never called */
+#endif
+
+extern char *audit_unpack_string(void **, size_t *, size_t);
+
 #ifdef CONFIG_AUDITSYSCALL
 extern int __audit_signal_info(int sig, struct task_struct *t);
 static inline int audit_signal_info(int sig, struct task_struct *t)
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
new file mode 100644
index 0000000..f4fcf58
--- /dev/null
+++ b/kernel/audit_tree.c
@@ -0,0 +1,903 @@
+#include "audit.h"
+#include <linux/inotify.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+
+struct audit_tree;
+struct audit_chunk;
+
+struct audit_tree {
+	atomic_t count;
+	int goner;
+	struct audit_chunk *root;
+	struct list_head chunks;
+	struct list_head rules;
+	struct list_head list;
+	struct list_head same_root;
+	struct rcu_head head;
+	char pathname[];
+};
+
+struct audit_chunk {
+	struct list_head hash;
+	struct inotify_watch watch;
+	struct list_head trees;		/* with root here */
+	int dead;
+	int count;
+	struct rcu_head head;
+	struct node {
+		struct list_head list;
+		struct audit_tree *owner;
+		unsigned index;		/* index; upper bit indicates 'will prune' */
+	} owners[];
+};
+
+static LIST_HEAD(tree_list);
+static LIST_HEAD(prune_list);
+
+/*
+ * One struct chunk is attached to each inode of interest.
+ * We replace struct chunk on tagging/untagging.
+ * Rules have pointer to struct audit_tree.
+ * Rules have struct list_head rlist forming a list of rules over
+ * the same tree.
+ * References to struct chunk are collected at audit_inode{,_child}()
+ * time and used in AUDIT_TREE rule matching.
+ * These references are dropped at the same time we are calling
+ * audit_free_names(), etc.
+ *
+ * Cyclic lists galore:
+ * tree.chunks anchors chunk.owners[].list			hash_lock
+ * tree.rules anchors rule.rlist				audit_filter_mutex
+ * chunk.trees anchors tree.same_root				hash_lock
+ * chunk.hash is a hash with middle bits of watch.inode as
+ * a hash function.						RCU, hash_lock
+ *
+ * tree is refcounted; one reference for "some rules on rules_list refer to
+ * it", one for each chunk with pointer to it.
+ *
+ * chunk is refcounted by embedded inotify_watch.
+ *
+ * node.index allows to get from node.list to containing chunk.
+ * MSB of that sucker is stolen to mark taggings that we might have to
+ * revert - several operations have very unpleasant cleanup logics and
+ * that makes a difference.  Some.
+ */
+
+static struct inotify_handle *rtree_ih;
+
+static struct audit_tree *alloc_tree(const char *s)
+{
+	struct audit_tree *tree;
+
+	tree = kmalloc(sizeof(struct audit_tree) + strlen(s) + 1, GFP_KERNEL);
+	if (tree) {
+		atomic_set(&tree->count, 1);
+		tree->goner = 0;
+		INIT_LIST_HEAD(&tree->chunks);
+		INIT_LIST_HEAD(&tree->rules);
+		INIT_LIST_HEAD(&tree->list);
+		INIT_LIST_HEAD(&tree->same_root);
+		tree->root = NULL;
+		strcpy(tree->pathname, s);
+	}
+	return tree;
+}
+
+static inline void get_tree(struct audit_tree *tree)
+{
+	atomic_inc(&tree->count);
+}
+
+static void __put_tree(struct rcu_head *rcu)
+{
+	struct audit_tree *tree = container_of(rcu, struct audit_tree, head);
+	kfree(tree);
+}
+
+static inline void put_tree(struct audit_tree *tree)
+{
+	if (atomic_dec_and_test(&tree->count))
+		call_rcu(&tree->head, __put_tree);
+}
+
+/* to avoid bringing the entire thing in audit.h */
+const char *audit_tree_path(struct audit_tree *tree)
+{
+	return tree->pathname;
+}
+
+static struct audit_chunk *alloc_chunk(int count)
+{
+	struct audit_chunk *chunk;
+	size_t size;
+	int i;
+
+	size = offsetof(struct audit_chunk, owners) + count * sizeof(struct node);
+	chunk = kzalloc(size, GFP_KERNEL);
+	if (!chunk)
+		return NULL;
+
+	INIT_LIST_HEAD(&chunk->hash);
+	INIT_LIST_HEAD(&chunk->trees);
+	chunk->count = count;
+	for (i = 0; i < count; i++) {
+		INIT_LIST_HEAD(&chunk->owners[i].list);
+		chunk->owners[i].index = i;
+	}
+	inotify_init_watch(&chunk->watch);
+	return chunk;
+}
+
+static void __free_chunk(struct rcu_head *rcu)
+{
+	struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
+	int i;
+
+	for (i = 0; i < chunk->count; i++) {
+		if (chunk->owners[i].owner)
+			put_tree(chunk->owners[i].owner);
+	}
+	kfree(chunk);
+}
+
+static inline void free_chunk(struct audit_chunk *chunk)
+{
+	call_rcu(&chunk->head, __free_chunk);
+}
+
+void audit_put_chunk(struct audit_chunk *chunk)
+{
+	put_inotify_watch(&chunk->watch);
+}
+
+enum {HASH_SIZE = 128};
+static struct list_head chunk_hash_heads[HASH_SIZE];
+static __cacheline_aligned_in_smp DEFINE_SPINLOCK(hash_lock);
+
+static inline struct list_head *chunk_hash(const struct inode *inode)
+{
+	unsigned long n = (unsigned long)inode / L1_CACHE_BYTES;
+	return chunk_hash_heads + n % HASH_SIZE;
+}
+
+/* hash_lock is held by caller */
+static void insert_hash(struct audit_chunk *chunk)
+{
+	struct list_head *list = chunk_hash(chunk->watch.inode);
+	list_add_rcu(&chunk->hash, list);
+}
+
+/* called under rcu_read_lock */
+struct audit_chunk *audit_tree_lookup(const struct inode *inode)
+{
+	struct list_head *list = chunk_hash(inode);
+	struct list_head *pos;
+
+	list_for_each_rcu(pos, list) {
+		struct audit_chunk *p = container_of(pos, struct audit_chunk, hash);
+		if (p->watch.inode == inode) {
+			get_inotify_watch(&p->watch);
+			return p;
+		}
+	}
+	return NULL;
+}
+
+int audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree)
+{
+	int n;
+	for (n = 0; n < chunk->count; n++)
+		if (chunk->owners[n].owner == tree)
+			return 1;
+	return 0;
+}
+
+/* tagging and untagging inodes with trees */
+
+static void untag_chunk(struct audit_chunk *chunk, struct node *p)
+{
+	struct audit_chunk *new;
+	struct audit_tree *owner;
+	int size = chunk->count - 1;
+	int i, j;
+
+	mutex_lock(&chunk->watch.inode->inotify_mutex);
+	if (chunk->dead) {
+		mutex_unlock(&chunk->watch.inode->inotify_mutex);
+		return;
+	}
+
+	owner = p->owner;
+
+	if (!size) {
+		chunk->dead = 1;
+		spin_lock(&hash_lock);
+		list_del_init(&chunk->trees);
+		if (owner->root == chunk)
+			owner->root = NULL;
+		list_del_init(&p->list);
+		list_del_rcu(&chunk->hash);
+		spin_unlock(&hash_lock);
+		inotify_evict_watch(&chunk->watch);
+		mutex_unlock(&chunk->watch.inode->inotify_mutex);
+		put_inotify_watch(&chunk->watch);
+		return;
+	}
+
+	new = alloc_chunk(size);
+	if (!new)
+		goto Fallback;
+	if (inotify_clone_watch(&chunk->watch, &new->watch) < 0) {
+		free_chunk(new);
+		goto Fallback;
+	}
+
+	chunk->dead = 1;
+	spin_lock(&hash_lock);
+	list_replace_init(&chunk->trees, &new->trees);
+	if (owner->root == chunk) {
+		list_del_init(&owner->same_root);
+		owner->root = NULL;
+	}
+
+	for (i = j = 0; i < size; i++, j++) {
+		struct audit_tree *s;
+		if (&chunk->owners[j] == p) {
+			list_del_init(&p->list);
+			i--;
+			continue;
+		}
+		s = chunk->owners[j].owner;
+		new->owners[i].owner = s;
+		new->owners[i].index = chunk->owners[j].index - j + i;
+		if (!s) /* result of earlier fallback */
+			continue;
+		get_tree(s);
+		list_replace_init(&chunk->owners[i].list, &new->owners[j].list);
+	}
+
+	list_replace_rcu(&chunk->hash, &new->hash);
+	list_for_each_entry(owner, &new->trees, same_root)
+		owner->root = new;
+	spin_unlock(&hash_lock);
+	inotify_evict_watch(&chunk->watch);
+	mutex_unlock(&chunk->watch.inode->inotify_mutex);
+	put_inotify_watch(&chunk->watch);
+	return;
+
+Fallback:
+	// do the best we can
+	spin_lock(&hash_lock);
+	if (owner->root == chunk) {
+		list_del_init(&owner->same_root);
+		owner->root = NULL;
+	}
+	list_del_init(&p->list);
+	p->owner = NULL;
+	put_tree(owner);
+	spin_unlock(&hash_lock);
+	mutex_unlock(&chunk->watch.inode->inotify_mutex);
+}
+
+static int create_chunk(struct inode *inode, struct audit_tree *tree)
+{
+	struct audit_chunk *chunk = alloc_chunk(1);
+	if (!chunk)
+		return -ENOMEM;
+
+	if (inotify_add_watch(rtree_ih, &chunk->watch, inode, IN_IGNORED | IN_DELETE_SELF) < 0) {
+		free_chunk(chunk);
+		return -ENOSPC;
+	}
+
+	mutex_lock(&inode->inotify_mutex);
+	spin_lock(&hash_lock);
+	if (tree->goner) {
+		spin_unlock(&hash_lock);
+		chunk->dead = 1;
+		inotify_evict_watch(&chunk->watch);
+		mutex_unlock(&inode->inotify_mutex);
+		put_inotify_watch(&chunk->watch);
+		return 0;
+	}
+	chunk->owners[0].index = (1U << 31);
+	chunk->owners[0].owner = tree;
+	get_tree(tree);
+	list_add(&chunk->owners[0].list, &tree->chunks);
+	if (!tree->root) {
+		tree->root = chunk;
+		list_add(&tree->same_root, &chunk->trees);
+	}
+	insert_hash(chunk);
+	spin_unlock(&hash_lock);
+	mutex_unlock(&inode->inotify_mutex);
+	return 0;
+}
+
+/* the first tagged inode becomes root of tree */
+static int tag_chunk(struct inode *inode, struct audit_tree *tree)
+{
+	struct inotify_watch *watch;
+	struct audit_tree *owner;
+	struct audit_chunk *chunk, *old;
+	struct node *p;
+	int n;
+
+	if (inotify_find_watch(rtree_ih, inode, &watch) < 0)
+		return create_chunk(inode, tree);
+
+	old = container_of(watch, struct audit_chunk, watch);
+
+	/* are we already there? */
+	spin_lock(&hash_lock);
+	for (n = 0; n < old->count; n++) {
+		if (old->owners[n].owner == tree) {
+			spin_unlock(&hash_lock);
+			put_inotify_watch(watch);
+			return 0;
+		}
+	}
+	spin_unlock(&hash_lock);
+
+	chunk = alloc_chunk(old->count + 1);
+	if (!chunk)
+		return -ENOMEM;
+
+	mutex_lock(&inode->inotify_mutex);
+	if (inotify_clone_watch(&old->watch, &chunk->watch) < 0) {
+		mutex_unlock(&inode->inotify_mutex);
+		free_chunk(chunk);
+		return -ENOSPC;
+	}
+	spin_lock(&hash_lock);
+	if (tree->goner) {
+		spin_unlock(&hash_lock);
+		chunk->dead = 1;
+		inotify_evict_watch(&chunk->watch);
+		mutex_unlock(&inode->inotify_mutex);
+		put_inotify_watch(&chunk->watch);
+		return 0;
+	}
+	list_replace_init(&old->trees, &chunk->trees);
+	for (n = 0, p = chunk->owners; n < old->count; n++, p++) {
+		struct audit_tree *s = old->owners[n].owner;
+		p->owner = s;
+		p->index = old->owners[n].index;
+		if (!s) /* result of fallback in untag */
+			continue;
+		get_tree(s);
+		list_replace_init(&old->owners[n].list, &p->list);
+	}
+	p->index = (chunk->count - 1) | (1U<<31);
+	p->owner = tree;
+	get_tree(tree);
+	list_add(&p->list, &tree->chunks);
+	list_replace_rcu(&old->hash, &chunk->hash);
+	list_for_each_entry(owner, &chunk->trees, same_root)
+		owner->root = chunk;
+	old->dead = 1;
+	if (!tree->root) {
+		tree->root = chunk;
+		list_add(&tree->same_root, &chunk->trees);
+	}
+	spin_unlock(&hash_lock);
+	inotify_evict_watch(&old->watch);
+	mutex_unlock(&inode->inotify_mutex);
+	put_inotify_watch(&old->watch);
+	return 0;
+}
+
+static struct audit_chunk *find_chunk(struct node *p)
+{
+	int index = p->index & ~(1U<<31);
+	p -= index;
+	return container_of(p, struct audit_chunk, owners[0]);
+}
+
+static void kill_rules(struct audit_tree *tree)
+{
+	struct audit_krule *rule, *next;
+	struct audit_entry *entry;
+	struct audit_buffer *ab;
+
+	list_for_each_entry_safe(rule, next, &tree->rules, rlist) {
+		entry = container_of(rule, struct audit_entry, rule);
+
+		list_del_init(&rule->rlist);
+		if (rule->tree) {
+			/* not a half-baked one */
+			ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+			audit_log_format(ab, "op=remove rule dir=");
+			audit_log_untrustedstring(ab, rule->tree->pathname);
+			if (rule->filterkey) {
+				audit_log_format(ab, " key=");
+				audit_log_untrustedstring(ab, rule->filterkey);
+			} else
+				audit_log_format(ab, " key=(null)");
+			audit_log_format(ab, " list=%d res=1", rule->listnr);
+			audit_log_end(ab);
+			rule->tree = NULL;
+			list_del_rcu(&entry->list);
+			call_rcu(&entry->rcu, audit_free_rule_rcu);
+		}
+	}
+}
+
+/*
+ * finish killing struct audit_tree
+ */
+static void prune_one(struct audit_tree *victim)
+{
+	spin_lock(&hash_lock);
+	while (!list_empty(&victim->chunks)) {
+		struct node *p;
+		struct audit_chunk *chunk;
+
+		p = list_entry(victim->chunks.next, struct node, list);
+		chunk = find_chunk(p);
+		get_inotify_watch(&chunk->watch);
+		spin_unlock(&hash_lock);
+
+		untag_chunk(chunk, p);
+
+		put_inotify_watch(&chunk->watch);
+		spin_lock(&hash_lock);
+	}
+	spin_unlock(&hash_lock);
+	put_tree(victim);
+}
+
+/* trim the uncommitted chunks from tree */
+
+static void trim_marked(struct audit_tree *tree)
+{
+	struct list_head *p, *q;
+	spin_lock(&hash_lock);
+	if (tree->goner) {
+		spin_unlock(&hash_lock);
+		return;
+	}
+	/* reorder */
+	for (p = tree->chunks.next; p != &tree->chunks; p = q) {
+		struct node *node = list_entry(p, struct node, list);
+		q = p->next;
+		if (node->index & (1U<<31)) {
+			list_del_init(p);
+			list_add(p, &tree->chunks);
+		}
+	}
+
+	while (!list_empty(&tree->chunks)) {
+		struct node *node;
+		struct audit_chunk *chunk;
+
+		node = list_entry(tree->chunks.next, struct node, list);
+
+		/* have we run out of marked? */
+		if (!(node->index & (1U<<31)))
+			break;
+
+		chunk = find_chunk(node);
+		get_inotify_watch(&chunk->watch);
+		spin_unlock(&hash_lock);
+
+		untag_chunk(chunk, node);
+
+		put_inotify_watch(&chunk->watch);
+		spin_lock(&hash_lock);
+	}
+	if (!tree->root && !tree->goner) {
+		tree->goner = 1;
+		spin_unlock(&hash_lock);
+		mutex_lock(&audit_filter_mutex);
+		kill_rules(tree);
+		list_del_init(&tree->list);
+		mutex_unlock(&audit_filter_mutex);
+		prune_one(tree);
+	} else {
+		spin_unlock(&hash_lock);
+	}
+}
+
+/* called with audit_filter_mutex */
+int audit_remove_tree_rule(struct audit_krule *rule)
+{
+	struct audit_tree *tree;
+	tree = rule->tree;
+	if (tree) {
+		spin_lock(&hash_lock);
+		list_del_init(&rule->rlist);
+		if (list_empty(&tree->rules) && !tree->goner) {
+			tree->root = NULL;
+			list_del_init(&tree->same_root);
+			tree->goner = 1;
+			list_move(&tree->list, &prune_list);
+			rule->tree = NULL;
+			spin_unlock(&hash_lock);
+			audit_schedule_prune();
+			return 1;
+		}
+		rule->tree = NULL;
+		spin_unlock(&hash_lock);
+		return 1;
+	}
+	return 0;
+}
+
+void audit_trim_trees(void)
+{
+	struct list_head cursor;
+
+	mutex_lock(&audit_filter_mutex);
+	list_add(&cursor, &tree_list);
+	while (cursor.next != &tree_list) {
+		struct audit_tree *tree;
+		struct nameidata nd;
+		struct vfsmount *root_mnt;
+		struct node *node;
+		struct list_head list;
+		int err;
+
+		tree = container_of(cursor.next, struct audit_tree, list);
+		get_tree(tree);
+		list_del(&cursor);
+		list_add(&cursor, &tree->list);
+		mutex_unlock(&audit_filter_mutex);
+
+		err = path_lookup(tree->pathname, 0, &nd);
+		if (err)
+			goto skip_it;
+
+		root_mnt = collect_mounts(nd.mnt, nd.dentry);
+		path_release(&nd);
+		if (!root_mnt)
+			goto skip_it;
+
+		list_add_tail(&list, &root_mnt->mnt_list);
+		spin_lock(&hash_lock);
+		list_for_each_entry(node, &tree->chunks, list) {
+			struct audit_chunk *chunk = find_chunk(node);
+			struct inode *inode = chunk->watch.inode;
+			struct vfsmount *mnt;
+			node->index |= 1U<<31;
+			list_for_each_entry(mnt, &list, mnt_list) {
+				if (mnt->mnt_root->d_inode == inode) {
+					node->index &= ~(1U<<31);
+					break;
+				}
+			}
+		}
+		spin_unlock(&hash_lock);
+		trim_marked(tree);
+		put_tree(tree);
+		list_del_init(&list);
+		drop_collected_mounts(root_mnt);
+skip_it:
+		mutex_lock(&audit_filter_mutex);
+	}
+	list_del(&cursor);
+	mutex_unlock(&audit_filter_mutex);
+}
+
+static int is_under(struct vfsmount *mnt, struct dentry *dentry,
+		    struct nameidata *nd)
+{
+	if (mnt != nd->mnt) {
+		for (;;) {
+			if (mnt->mnt_parent == mnt)
+				return 0;
+			if (mnt->mnt_parent == nd->mnt)
+					break;
+			mnt = mnt->mnt_parent;
+		}
+		dentry = mnt->mnt_mountpoint;
+	}
+	return is_subdir(dentry, nd->dentry);
+}
+
+int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op)
+{
+
+	if (pathname[0] != '/' ||
+	    rule->listnr != AUDIT_FILTER_EXIT ||
+	    op & ~AUDIT_EQUAL ||
+	    rule->inode_f || rule->watch || rule->tree)
+		return -EINVAL;
+	rule->tree = alloc_tree(pathname);
+	if (!rule->tree)
+		return -ENOMEM;
+	return 0;
+}
+
+void audit_put_tree(struct audit_tree *tree)
+{
+	put_tree(tree);
+}
+
+/* called with audit_filter_mutex */
+int audit_add_tree_rule(struct audit_krule *rule)
+{
+	struct audit_tree *seed = rule->tree, *tree;
+	struct nameidata nd;
+	struct vfsmount *mnt, *p;
+	struct list_head list;
+	int err;
+
+	list_for_each_entry(tree, &tree_list, list) {
+		if (!strcmp(seed->pathname, tree->pathname)) {
+			put_tree(seed);
+			rule->tree = tree;
+			list_add(&rule->rlist, &tree->rules);
+			return 0;
+		}
+	}
+	tree = seed;
+	list_add(&tree->list, &tree_list);
+	list_add(&rule->rlist, &tree->rules);
+	/* do not set rule->tree yet */
+	mutex_unlock(&audit_filter_mutex);
+
+	err = path_lookup(tree->pathname, 0, &nd);
+	if (err)
+		goto Err;
+	mnt = collect_mounts(nd.mnt, nd.dentry);
+	path_release(&nd);
+	if (!mnt) {
+		err = -ENOMEM;
+		goto Err;
+	}
+	list_add_tail(&list, &mnt->mnt_list);
+
+	get_tree(tree);
+	list_for_each_entry(p, &list, mnt_list) {
+		err = tag_chunk(p->mnt_root->d_inode, tree);
+		if (err)
+			break;
+	}
+
+	list_del(&list);
+	drop_collected_mounts(mnt);
+
+	if (!err) {
+		struct node *node;
+		spin_lock(&hash_lock);
+		list_for_each_entry(node, &tree->chunks, list)
+			node->index &= ~(1U<<31);
+		spin_unlock(&hash_lock);
+	} else {
+		trim_marked(tree);
+		goto Err;
+	}
+
+	mutex_lock(&audit_filter_mutex);
+	if (list_empty(&rule->rlist)) {
+		put_tree(tree);
+		return -ENOENT;
+	}
+	rule->tree = tree;
+	put_tree(tree);
+
+	return 0;
+Err:
+	mutex_lock(&audit_filter_mutex);
+	list_del_init(&tree->list);
+	list_del_init(&tree->rules);
+	put_tree(tree);
+	return err;
+}
+
+int audit_tag_tree(char *old, char *new)
+{
+	struct list_head cursor, barrier;
+	int failed = 0;
+	struct nameidata nd;
+	struct vfsmount *tagged;
+	struct list_head list;
+	struct vfsmount *mnt;
+	struct dentry *dentry;
+	int err;
+
+	err = path_lookup(new, 0, &nd);
+	if (err)
+		return err;
+	tagged = collect_mounts(nd.mnt, nd.dentry);
+	path_release(&nd);
+	if (!tagged)
+		return -ENOMEM;
+
+	err = path_lookup(old, 0, &nd);
+	if (err) {
+		drop_collected_mounts(tagged);
+		return err;
+	}
+	mnt = mntget(nd.mnt);
+	dentry = dget(nd.dentry);
+	path_release(&nd);
+
+	if (dentry == tagged->mnt_root && dentry == mnt->mnt_root)
+		follow_up(&mnt, &dentry);
+
+	list_add_tail(&list, &tagged->mnt_list);
+
+	mutex_lock(&audit_filter_mutex);
+	list_add(&barrier, &tree_list);
+	list_add(&cursor, &barrier);
+
+	while (cursor.next != &tree_list) {
+		struct audit_tree *tree;
+		struct vfsmount *p;
+
+		tree = container_of(cursor.next, struct audit_tree, list);
+		get_tree(tree);
+		list_del(&cursor);
+		list_add(&cursor, &tree->list);
+		mutex_unlock(&audit_filter_mutex);
+
+		err = path_lookup(tree->pathname, 0, &nd);
+		if (err) {
+			put_tree(tree);
+			mutex_lock(&audit_filter_mutex);
+			continue;
+		}
+
+		spin_lock(&vfsmount_lock);
+		if (!is_under(mnt, dentry, &nd)) {
+			spin_unlock(&vfsmount_lock);
+			path_release(&nd);
+			put_tree(tree);
+			mutex_lock(&audit_filter_mutex);
+			continue;
+		}
+		spin_unlock(&vfsmount_lock);
+		path_release(&nd);
+
+		list_for_each_entry(p, &list, mnt_list) {
+			failed = tag_chunk(p->mnt_root->d_inode, tree);
+			if (failed)
+				break;
+		}
+
+		if (failed) {
+			put_tree(tree);
+			mutex_lock(&audit_filter_mutex);
+			break;
+		}
+
+		mutex_lock(&audit_filter_mutex);
+		spin_lock(&hash_lock);
+		if (!tree->goner) {
+			list_del(&tree->list);
+			list_add(&tree->list, &tree_list);
+		}
+		spin_unlock(&hash_lock);
+		put_tree(tree);
+	}
+
+	while (barrier.prev != &tree_list) {
+		struct audit_tree *tree;
+
+		tree = container_of(barrier.prev, struct audit_tree, list);
+		get_tree(tree);
+		list_del(&tree->list);
+		list_add(&tree->list, &barrier);
+		mutex_unlock(&audit_filter_mutex);
+
+		if (!failed) {
+			struct node *node;
+			spin_lock(&hash_lock);
+			list_for_each_entry(node, &tree->chunks, list)
+				node->index &= ~(1U<<31);
+			spin_unlock(&hash_lock);
+		} else {
+			trim_marked(tree);
+		}
+
+		put_tree(tree);
+		mutex_lock(&audit_filter_mutex);
+	}
+	list_del(&barrier);
+	list_del(&cursor);
+	list_del(&list);
+	mutex_unlock(&audit_filter_mutex);
+	dput(dentry);
+	mntput(mnt);
+	drop_collected_mounts(tagged);
+	return failed;
+}
+
+/*
+ * That gets run when evict_chunk() ends up needing to kill audit_tree.
+ * Runs from a separate thread, with audit_cmd_mutex held.
+ */
+void audit_prune_trees(void)
+{
+	mutex_lock(&audit_filter_mutex);
+
+	while (!list_empty(&prune_list)) {
+		struct audit_tree *victim;
+
+		victim = list_entry(prune_list.next, struct audit_tree, list);
+		list_del_init(&victim->list);
+
+		mutex_unlock(&audit_filter_mutex);
+
+		prune_one(victim);
+
+		mutex_lock(&audit_filter_mutex);
+	}
+
+	mutex_unlock(&audit_filter_mutex);
+}
+
+/*
+ *  Here comes the stuff asynchronous to auditctl operations
+ */
+
+/* inode->inotify_mutex is locked */
+static void evict_chunk(struct audit_chunk *chunk)
+{
+	struct audit_tree *owner;
+	int n;
+
+	if (chunk->dead)
+		return;
+
+	chunk->dead = 1;
+	mutex_lock(&audit_filter_mutex);
+	spin_lock(&hash_lock);
+	while (!list_empty(&chunk->trees)) {
+		owner = list_entry(chunk->trees.next,
+				   struct audit_tree, same_root);
+		owner->goner = 1;
+		owner->root = NULL;
+		list_del_init(&owner->same_root);
+		spin_unlock(&hash_lock);
+		kill_rules(owner);
+		list_move(&owner->list, &prune_list);
+		audit_schedule_prune();
+		spin_lock(&hash_lock);
+	}
+	list_del_rcu(&chunk->hash);
+	for (n = 0; n < chunk->count; n++)
+		list_del_init(&chunk->owners[n].list);
+	spin_unlock(&hash_lock);
+	mutex_unlock(&audit_filter_mutex);
+}
+
+static void handle_event(struct inotify_watch *watch, u32 wd, u32 mask,
+                         u32 cookie, const char *dname, struct inode *inode)
+{
+	struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch);
+
+	if (mask & IN_IGNORED) {
+		evict_chunk(chunk);
+		put_inotify_watch(watch);
+	}
+}
+
+static void destroy_watch(struct inotify_watch *watch)
+{
+	struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch);
+	free_chunk(chunk);
+}
+
+static const struct inotify_operations rtree_inotify_ops = {
+	.handle_event	= handle_event,
+	.destroy_watch	= destroy_watch,
+};
+
+static int __init audit_tree_init(void)
+{
+	int i;
+
+	rtree_ih = inotify_init(&rtree_inotify_ops);
+	if (IS_ERR(rtree_ih))
+		audit_panic("cannot initialize inotify handle for rectree watches");
+
+	for (i = 0; i < HASH_SIZE; i++)
+		INIT_LIST_HEAD(&chunk_hash_heads[i]);
+
+	return 0;
+}
+__initcall(audit_tree_init);
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 359645c..5d96f2c 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -87,7 +87,7 @@
 #endif
 };
 
-static DEFINE_MUTEX(audit_filter_mutex);
+DEFINE_MUTEX(audit_filter_mutex);
 
 /* Inotify handle */
 extern struct inotify_handle *audit_ih;
@@ -145,7 +145,7 @@
 	kfree(e);
 }
 
-static inline void audit_free_rule_rcu(struct rcu_head *head)
+void audit_free_rule_rcu(struct rcu_head *head)
 {
 	struct audit_entry *e = container_of(head, struct audit_entry, rcu);
 	audit_free_rule(e);
@@ -217,7 +217,7 @@
 
 /* Unpack a filter field's string representation from user-space
  * buffer. */
-static char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
+char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
 {
 	char *str;
 
@@ -247,7 +247,7 @@
 				 struct audit_field *f)
 {
 	if (krule->listnr != AUDIT_FILTER_EXIT ||
-	    krule->watch || krule->inode_f)
+	    krule->watch || krule->inode_f || krule->tree)
 		return -EINVAL;
 
 	krule->inode_f = f;
@@ -266,7 +266,7 @@
 	if (path[0] != '/' || path[len-1] == '/' ||
 	    krule->listnr != AUDIT_FILTER_EXIT ||
 	    op & ~AUDIT_EQUAL ||
-	    krule->inode_f || krule->watch) /* 1 inode # per rule, for hash */
+	    krule->inode_f || krule->watch || krule->tree)
 		return -EINVAL;
 
 	watch = audit_init_watch(path);
@@ -622,6 +622,17 @@
 				goto exit_free;
 			}
 			break;
+		case AUDIT_DIR:
+			str = audit_unpack_string(&bufp, &remain, f->val);
+			if (IS_ERR(str))
+				goto exit_free;
+			entry->rule.buflen += f->val;
+
+			err = audit_make_tree(&entry->rule, str, f->op);
+			kfree(str);
+			if (err)
+				goto exit_free;
+			break;
 		case AUDIT_INODE:
 			err = audit_to_inode(&entry->rule, f);
 			if (err)
@@ -668,7 +679,7 @@
 }
 
 /* Pack a filter field's string representation into data block. */
-static inline size_t audit_pack_string(void **bufp, char *str)
+static inline size_t audit_pack_string(void **bufp, const char *str)
 {
 	size_t len = strlen(str);
 
@@ -747,6 +758,11 @@
 			data->buflen += data->values[i] =
 				audit_pack_string(&bufp, krule->watch->path);
 			break;
+		case AUDIT_DIR:
+			data->buflen += data->values[i] =
+				audit_pack_string(&bufp,
+						  audit_tree_path(krule->tree));
+			break;
 		case AUDIT_FILTERKEY:
 			data->buflen += data->values[i] =
 				audit_pack_string(&bufp, krule->filterkey);
@@ -795,6 +811,11 @@
 			if (strcmp(a->watch->path, b->watch->path))
 				return 1;
 			break;
+		case AUDIT_DIR:
+			if (strcmp(audit_tree_path(a->tree),
+				   audit_tree_path(b->tree)))
+				return 1;
+			break;
 		case AUDIT_FILTERKEY:
 			/* both filterkeys exist based on above type compare */
 			if (strcmp(a->filterkey, b->filterkey))
@@ -897,6 +918,14 @@
 	new->inode_f = old->inode_f;
 	new->watch = NULL;
 	new->field_count = old->field_count;
+	/*
+	 * note that we are OK with not refcounting here; audit_match_tree()
+	 * never dereferences tree and we can't get false positives there
+	 * since we'd have to have rule gone from the list *and* removed
+	 * before the chunks found by lookup had been allocated, i.e. before
+	 * the beginning of list scan.
+	 */
+	new->tree = old->tree;
 	memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);
 
 	/* deep copy this information, updating the se_rule fields, because
@@ -1217,6 +1246,7 @@
 	struct audit_entry *e;
 	struct audit_field *inode_f = entry->rule.inode_f;
 	struct audit_watch *watch = entry->rule.watch;
+	struct audit_tree *tree = entry->rule.tree;
 	struct nameidata *ndp = NULL, *ndw = NULL;
 	int h, err;
 #ifdef CONFIG_AUDITSYSCALL
@@ -1238,6 +1268,9 @@
 	mutex_unlock(&audit_filter_mutex);
 	if (e) {
 		err = -EEXIST;
+		/* normally audit_add_tree_rule() will free it on failure */
+		if (tree)
+			audit_put_tree(tree);
 		goto error;
 	}
 
@@ -1259,6 +1292,13 @@
 		h = audit_hash_ino((u32)watch->ino);
 		list = &audit_inode_hash[h];
 	}
+	if (tree) {
+		err = audit_add_tree_rule(&entry->rule);
+		if (err) {
+			mutex_unlock(&audit_filter_mutex);
+			goto error;
+		}
+	}
 
 	if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
 		list_add_rcu(&entry->list, list);
@@ -1292,6 +1332,7 @@
 	struct audit_entry  *e;
 	struct audit_field *inode_f = entry->rule.inode_f;
 	struct audit_watch *watch, *tmp_watch = entry->rule.watch;
+	struct audit_tree *tree = entry->rule.tree;
 	LIST_HEAD(inotify_list);
 	int h, ret = 0;
 #ifdef CONFIG_AUDITSYSCALL
@@ -1336,6 +1377,9 @@
 		}
 	}
 
+	if (e->rule.tree)
+		audit_remove_tree_rule(&e->rule);
+
 	list_del_rcu(&e->list);
 	call_rcu(&e->rcu, audit_free_rule_rcu);
 
@@ -1354,6 +1398,8 @@
 out:
 	if (tmp_watch)
 		audit_put_watch(tmp_watch); /* match initial get */
+	if (tree)
+		audit_put_tree(tree);	/* that's the temporary one */
 
 	return ret;
 }
@@ -1498,7 +1544,7 @@
 		 * auditctl to read from it... which isn't ever going to
 		 * happen if we're actually running in the context of auditctl
 		 * trying to _send_ the stuff */
-		 
+
 		dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
 		if (!dest)
 			return -ENOMEM;
@@ -1678,7 +1724,7 @@
 {
 	struct audit_entry *e;
 	int result = 0;
-	
+
 	rcu_read_lock();
 	if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE]))
 		goto unlock_and_return;
@@ -1737,6 +1783,7 @@
 {
 	struct audit_entry *entry, *n, *nentry;
 	struct audit_watch *watch;
+	struct audit_tree *tree;
 	int i, err = 0;
 
 	/* audit_filter_mutex synchronizes the writers */
@@ -1748,6 +1795,7 @@
 				continue;
 
 			watch = entry->rule.watch;
+			tree = entry->rule.tree;
 			nentry = audit_dupe_rule(&entry->rule, watch);
 			if (unlikely(IS_ERR(nentry))) {
 				/* save the first error encountered for the
@@ -1763,7 +1811,9 @@
 					list_add(&nentry->rule.rlist,
 						 &watch->rules);
 					list_del(&entry->rule.rlist);
-				}
+				} else if (tree)
+					list_replace_init(&entry->rule.rlist,
+						     &nentry->rule.rlist);
 				list_replace_rcu(&entry->list, &nentry->list);
 			}
 			call_rcu(&entry->rcu, audit_free_rule_rcu);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 938e60a..bce9ecd 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -65,6 +65,7 @@
 #include <linux/binfmts.h>
 #include <linux/highmem.h>
 #include <linux/syscalls.h>
+#include <linux/inotify.h>
 
 #include "audit.h"
 
@@ -179,6 +180,11 @@
 	int			pid_count;
 };
 
+struct audit_tree_refs {
+	struct audit_tree_refs *next;
+	struct audit_chunk *c[31];
+};
+
 /* The per-task audit context. */
 struct audit_context {
 	int		    dummy;	/* must be the first element */
@@ -211,6 +217,9 @@
 	pid_t		    target_pid;
 	u32		    target_sid;
 
+	struct audit_tree_refs *trees, *first_trees;
+	int tree_count;
+
 #if AUDIT_DEBUG
 	int		    put_count;
 	int		    ino_count;
@@ -265,6 +274,117 @@
 	}
 }
 
+/*
+ * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *;
+ * ->first_trees points to its beginning, ->trees - to the current end of data.
+ * ->tree_count is the number of free entries in array pointed to by ->trees.
+ * Original condition is (NULL, NULL, 0); as soon as it grows we never revert to NULL,
+ * "empty" becomes (p, p, 31) afterwards.  We don't shrink the list (and seriously,
+ * it's going to remain 1-element for almost any setup) until we free context itself.
+ * References in it _are_ dropped - at the same time we free/drop aux stuff.
+ */
+
+#ifdef CONFIG_AUDIT_TREE
+static int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk)
+{
+	struct audit_tree_refs *p = ctx->trees;
+	int left = ctx->tree_count;
+	if (likely(left)) {
+		p->c[--left] = chunk;
+		ctx->tree_count = left;
+		return 1;
+	}
+	if (!p)
+		return 0;
+	p = p->next;
+	if (p) {
+		p->c[30] = chunk;
+		ctx->trees = p;
+		ctx->tree_count = 30;
+		return 1;
+	}
+	return 0;
+}
+
+static int grow_tree_refs(struct audit_context *ctx)
+{
+	struct audit_tree_refs *p = ctx->trees;
+	ctx->trees = kzalloc(sizeof(struct audit_tree_refs), GFP_KERNEL);
+	if (!ctx->trees) {
+		ctx->trees = p;
+		return 0;
+	}
+	if (p)
+		p->next = ctx->trees;
+	else
+		ctx->first_trees = ctx->trees;
+	ctx->tree_count = 31;
+	return 1;
+}
+#endif
+
+static void unroll_tree_refs(struct audit_context *ctx,
+		      struct audit_tree_refs *p, int count)
+{
+#ifdef CONFIG_AUDIT_TREE
+	struct audit_tree_refs *q;
+	int n;
+	if (!p) {
+		/* we started with empty chain */
+		p = ctx->first_trees;
+		count = 31;
+		/* if the very first allocation has failed, nothing to do */
+		if (!p)
+			return;
+	}
+	n = count;
+	for (q = p; q != ctx->trees; q = q->next, n = 31) {
+		while (n--) {
+			audit_put_chunk(q->c[n]);
+			q->c[n] = NULL;
+		}
+	}
+	while (n-- > ctx->tree_count) {
+		audit_put_chunk(q->c[n]);
+		q->c[n] = NULL;
+	}
+	ctx->trees = p;
+	ctx->tree_count = count;
+#endif
+}
+
+static void free_tree_refs(struct audit_context *ctx)
+{
+	struct audit_tree_refs *p, *q;
+	for (p = ctx->first_trees; p; p = q) {
+		q = p->next;
+		kfree(p);
+	}
+}
+
+static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree)
+{
+#ifdef CONFIG_AUDIT_TREE
+	struct audit_tree_refs *p;
+	int n;
+	if (!tree)
+		return 0;
+	/* full ones */
+	for (p = ctx->first_trees; p != ctx->trees; p = p->next) {
+		for (n = 0; n < 31; n++)
+			if (audit_tree_match(p->c[n], tree))
+				return 1;
+	}
+	/* partial */
+	if (p) {
+		for (n = ctx->tree_count; n < 31; n++)
+			if (audit_tree_match(p->c[n], tree))
+				return 1;
+	}
+#endif
+	return 0;
+}
+
 /* Determine if any context name data matches a rule's watch data */
 /* Compare a task_struct with an audit_rule.  Return 1 on match, 0
  * otherwise. */
@@ -320,7 +440,7 @@
 			result = audit_comparator(tsk->personality, f->op, f->val);
 			break;
 		case AUDIT_ARCH:
- 			if (ctx)
+			if (ctx)
 				result = audit_comparator(ctx->arch, f->op, f->val);
 			break;
 
@@ -379,6 +499,10 @@
 				result = (name->dev == rule->watch->dev &&
 					  name->ino == rule->watch->ino);
 			break;
+		case AUDIT_DIR:
+			if (ctx)
+				result = match_tree_refs(ctx, rule->tree);
+			break;
 		case AUDIT_LOGINUID:
 			result = 0;
 			if (ctx)
@@ -727,6 +851,8 @@
 			       context->name_count, count);
 		}
 		audit_free_names(context);
+		unroll_tree_refs(context, NULL, 0);
+		free_tree_refs(context);
 		audit_free_aux(context);
 		kfree(context->filterkey);
 		kfree(context);
@@ -898,7 +1024,7 @@
 	if (context->personality != PER_LINUX)
 		audit_log_format(ab, " per=%lx", context->personality);
 	if (context->return_valid)
-		audit_log_format(ab, " success=%s exit=%ld", 
+		audit_log_format(ab, " success=%s exit=%ld",
 				 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
 				 context->return_code);
 
@@ -1135,8 +1261,8 @@
 		return;
 
 	/* Check for system calls that do not go through the exit
-	 * function (e.g., exit_group), then free context block. 
-	 * We use GFP_ATOMIC here because we might be doing this 
+	 * function (e.g., exit_group), then free context block.
+	 * We use GFP_ATOMIC here because we might be doing this
 	 * in the context of the idle thread */
 	/* that can happen only if we are called from do_exit() */
 	if (context->in_syscall && context->auditable)
@@ -1270,6 +1396,7 @@
 		tsk->audit_context = new_context;
 	} else {
 		audit_free_names(context);
+		unroll_tree_refs(context, NULL, 0);
 		audit_free_aux(context);
 		context->aux = NULL;
 		context->aux_pids = NULL;
@@ -1281,6 +1408,95 @@
 	}
 }
 
+static inline void handle_one(const struct inode *inode)
+{
+#ifdef CONFIG_AUDIT_TREE
+	struct audit_context *context;
+	struct audit_tree_refs *p;
+	struct audit_chunk *chunk;
+	int count;
+	if (likely(list_empty(&inode->inotify_watches)))
+		return;
+	context = current->audit_context;
+	p = context->trees;
+	count = context->tree_count;
+	rcu_read_lock();
+	chunk = audit_tree_lookup(inode);
+	rcu_read_unlock();
+	if (!chunk)
+		return;
+	if (likely(put_tree_ref(context, chunk)))
+		return;
+	if (unlikely(!grow_tree_refs(context))) {
+		printk(KERN_WARNING "out of memory, audit has lost a tree reference");
+		audit_set_auditable(context);
+		audit_put_chunk(chunk);
+		unroll_tree_refs(context, p, count);
+		return;
+	}
+	put_tree_ref(context, chunk);
+#endif
+}
+
+static void handle_path(const struct dentry *dentry)
+{
+#ifdef CONFIG_AUDIT_TREE
+	struct audit_context *context;
+	struct audit_tree_refs *p;
+	const struct dentry *d, *parent;
+	struct audit_chunk *drop;
+	unsigned long seq;
+	int count;
+
+	context = current->audit_context;
+	p = context->trees;
+	count = context->tree_count;
+retry:
+	drop = NULL;
+	d = dentry;
+	rcu_read_lock();
+	seq = read_seqbegin(&rename_lock);
+	for(;;) {
+		struct inode *inode = d->d_inode;
+		if (inode && unlikely(!list_empty(&inode->inotify_watches))) {
+			struct audit_chunk *chunk;
+			chunk = audit_tree_lookup(inode);
+			if (chunk) {
+				if (unlikely(!put_tree_ref(context, chunk))) {
+					drop = chunk;
+					break;
+				}
+			}
+		}
+		parent = d->d_parent;
+		if (parent == d)
+			break;
+		d = parent;
+	}
+	if (unlikely(read_seqretry(&rename_lock, seq) || drop)) {  /* in this order */
+		rcu_read_unlock();
+		if (!drop) {
+			/* just a race with rename */
+			unroll_tree_refs(context, p, count);
+			goto retry;
+		}
+		audit_put_chunk(drop);
+		if (grow_tree_refs(context)) {
+			/* OK, got more space */
+			unroll_tree_refs(context, p, count);
+			goto retry;
+		}
+		/* too bad */
+		printk(KERN_WARNING
+			"out of memory, audit has lost a tree reference");
+		unroll_tree_refs(context, p, count);
+		audit_set_auditable(context);
+		return;
+	}
+	rcu_read_unlock();
+#endif
+}
+
 /**
  * audit_getname - add a name to the list
  * @name: name to add
@@ -1316,7 +1532,7 @@
 		context->pwdmnt = mntget(current->fs->pwdmnt);
 		read_unlock(&current->fs->lock);
 	}
-		
+
 }
 
 /* audit_putname - intercept a putname request
@@ -1399,14 +1615,15 @@
 /**
  * audit_inode - store the inode and device from a lookup
  * @name: name being audited
- * @inode: inode being audited
+ * @dentry: dentry being audited
  *
  * Called from fs/namei.c:path_lookup().
  */
-void __audit_inode(const char *name, const struct inode *inode)
+void __audit_inode(const char *name, const struct dentry *dentry)
 {
 	int idx;
 	struct audit_context *context = current->audit_context;
+	const struct inode *inode = dentry->d_inode;
 
 	if (!context->in_syscall)
 		return;
@@ -1426,13 +1643,14 @@
 		idx = context->name_count - 1;
 		context->names[idx].name = NULL;
 	}
+	handle_path(dentry);
 	audit_copy_inode(&context->names[idx], inode);
 }
 
 /**
  * audit_inode_child - collect inode info for created/removed objects
  * @dname: inode's dentry name
- * @inode: inode being audited
+ * @dentry: dentry being audited
  * @parent: inode of dentry parent
  *
  * For syscalls that create or remove filesystem objects, audit_inode
@@ -1443,17 +1661,20 @@
  * must be hooked prior, in order to capture the target inode during
  * unsuccessful attempts.
  */
-void __audit_inode_child(const char *dname, const struct inode *inode,
+void __audit_inode_child(const char *dname, const struct dentry *dentry,
 			 const struct inode *parent)
 {
 	int idx;
 	struct audit_context *context = current->audit_context;
 	const char *found_parent = NULL, *found_child = NULL;
+	const struct inode *inode = dentry->d_inode;
 	int dirlen = 0;
 
 	if (!context->in_syscall)
 		return;
 
+	if (inode)
+		handle_one(inode);
 	/* determine matching parent */
 	if (!dname)
 		goto add_names;
diff --git a/kernel/capability.c b/kernel/capability.c
index 4e350a3..efbd9cd 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -3,20 +3,18 @@
  *
  * Copyright (C) 1997  Andrew Main <zefram@fysh.org>
  *
- * Integrated into 2.1.97+,  Andrew G. Morgan <morgan@transmeta.com>
+ * Integrated into 2.1.97+,  Andrew G. Morgan <morgan@kernel.org>
  * 30 May 2002:	Cleanup, Robert M. Love <rml@tech9.net>
- */ 
+ */
 
 #include <linux/capability.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
+#include <linux/pid_namespace.h>
 #include <asm/uaccess.h>
 
-unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
-kernel_cap_t cap_bset = CAP_INIT_EFF_SET;
-
 /*
  * This lock protects task->cap_* for all tasks including current.
  * Locking rule: acquire this prior to tasklist_lock.
@@ -40,49 +38,49 @@
  */
 asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
 {
-     int ret = 0;
-     pid_t pid;
-     __u32 version;
-     struct task_struct *target;
-     struct __user_cap_data_struct data;
+	int ret = 0;
+	pid_t pid;
+	__u32 version;
+	struct task_struct *target;
+	struct __user_cap_data_struct data;
 
-     if (get_user(version, &header->version))
-	     return -EFAULT;
+	if (get_user(version, &header->version))
+		return -EFAULT;
 
-     if (version != _LINUX_CAPABILITY_VERSION) {
-	     if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
-		     return -EFAULT; 
-             return -EINVAL;
-     }
+	if (version != _LINUX_CAPABILITY_VERSION) {
+		if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
+			return -EFAULT;
+		return -EINVAL;
+	}
 
-     if (get_user(pid, &header->pid))
-	     return -EFAULT;
+	if (get_user(pid, &header->pid))
+		return -EFAULT;
 
-     if (pid < 0) 
-             return -EINVAL;
+	if (pid < 0)
+		return -EINVAL;
 
-     spin_lock(&task_capability_lock);
-     read_lock(&tasklist_lock); 
+	spin_lock(&task_capability_lock);
+	read_lock(&tasklist_lock);
 
-     if (pid && pid != current->pid) {
-	     target = find_task_by_pid(pid);
-	     if (!target) {
-	          ret = -ESRCH;
-	          goto out;
-	     }
-     } else
-	     target = current;
+	if (pid && pid != task_pid_vnr(current)) {
+		target = find_task_by_vpid(pid);
+		if (!target) {
+			ret = -ESRCH;
+			goto out;
+		}
+	} else
+		target = current;
 
-     ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted);
+	ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted);
 
 out:
-     read_unlock(&tasklist_lock); 
-     spin_unlock(&task_capability_lock);
+	read_unlock(&tasklist_lock);
+	spin_unlock(&task_capability_lock);
 
-     if (!ret && copy_to_user(dataptr, &data, sizeof data))
-          return -EFAULT; 
+	if (!ret && copy_to_user(dataptr, &data, sizeof data))
+		return -EFAULT;
 
-     return ret;
+	return ret;
 }
 
 /*
@@ -98,7 +96,7 @@
 	int found = 0;
 	struct pid *pgrp;
 
-	pgrp = find_pid(pgrp_nr);
+	pgrp = find_vpid(pgrp_nr);
 	do_each_pid_task(pgrp, PIDTYPE_PGID, g) {
 		target = g;
 		while_each_thread(g, target) {
@@ -115,7 +113,7 @@
 	} while_each_pid_task(pgrp, PIDTYPE_PGID, g);
 
 	if (!found)
-	     ret = 0;
+		ret = 0;
 	return ret;
 }
 
@@ -132,7 +130,7 @@
      int found = 0;
 
      do_each_thread(g, target) {
-             if (target == current || is_init(target))
+             if (target == current || is_container_init(target->group_leader))
                      continue;
              found = 1;
 	     if (security_capset_check(target, effective, inheritable,
@@ -169,68 +167,68 @@
  */
 asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
 {
-     kernel_cap_t inheritable, permitted, effective;
-     __u32 version;
-     struct task_struct *target;
-     int ret;
-     pid_t pid;
+	kernel_cap_t inheritable, permitted, effective;
+	__u32 version;
+	struct task_struct *target;
+	int ret;
+	pid_t pid;
 
-     if (get_user(version, &header->version))
-	     return -EFAULT; 
+	if (get_user(version, &header->version))
+		return -EFAULT;
 
-     if (version != _LINUX_CAPABILITY_VERSION) {
-	     if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
-		     return -EFAULT; 
-             return -EINVAL;
-     }
+	if (version != _LINUX_CAPABILITY_VERSION) {
+		if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
+			return -EFAULT;
+		return -EINVAL;
+	}
 
-     if (get_user(pid, &header->pid))
-	     return -EFAULT; 
+	if (get_user(pid, &header->pid))
+		return -EFAULT;
 
-     if (pid && pid != current->pid && !capable(CAP_SETPCAP))
-             return -EPERM;
+	if (pid && pid != task_pid_vnr(current) && !capable(CAP_SETPCAP))
+		return -EPERM;
 
-     if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
-	 copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) ||
-	 copy_from_user(&permitted, &data->permitted, sizeof(permitted)))
-	     return -EFAULT; 
+	if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
+	    copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) ||
+	    copy_from_user(&permitted, &data->permitted, sizeof(permitted)))
+		return -EFAULT;
 
-     spin_lock(&task_capability_lock);
-     read_lock(&tasklist_lock);
+	spin_lock(&task_capability_lock);
+	read_lock(&tasklist_lock);
 
-     if (pid > 0 && pid != current->pid) {
-          target = find_task_by_pid(pid);
-          if (!target) {
-               ret = -ESRCH;
-               goto out;
-          }
-     } else
-               target = current;
+	if (pid > 0 && pid != task_pid_vnr(current)) {
+		target = find_task_by_vpid(pid);
+		if (!target) {
+			ret = -ESRCH;
+			goto out;
+		}
+	} else
+		target = current;
 
-     ret = 0;
+	ret = 0;
 
-     /* having verified that the proposed changes are legal,
-           we now put them into effect. */
-     if (pid < 0) {
-             if (pid == -1)  /* all procs other than current and init */
-                     ret = cap_set_all(&effective, &inheritable, &permitted);
+	/* having verified that the proposed changes are legal,
+	   we now put them into effect. */
+	if (pid < 0) {
+		if (pid == -1)	/* all procs other than current and init */
+			ret = cap_set_all(&effective, &inheritable, &permitted);
 
-             else            /* all procs in process group */
-                     ret = cap_set_pg(-pid, &effective, &inheritable,
-		     					&permitted);
-     } else {
-	     ret = security_capset_check(target, &effective, &inheritable,
-	     						&permitted);
-	     if (!ret)
-		     security_capset_set(target, &effective, &inheritable,
-		     					&permitted);
-     }
+		else		/* all procs in process group */
+			ret = cap_set_pg(-pid, &effective, &inheritable,
+					 &permitted);
+	} else {
+		ret = security_capset_check(target, &effective, &inheritable,
+					    &permitted);
+		if (!ret)
+			security_capset_set(target, &effective, &inheritable,
+					    &permitted);
+	}
 
 out:
-     read_unlock(&tasklist_lock);
-     spin_unlock(&task_capability_lock);
+	read_unlock(&tasklist_lock);
+	spin_unlock(&task_capability_lock);
 
-     return ret;
+	return ret;
 }
 
 int __capable(struct task_struct *t, int cap)
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
new file mode 100644
index 0000000..5987dcc
--- /dev/null
+++ b/kernel/cgroup.c
@@ -0,0 +1,2805 @@
+/*
+ *  kernel/cgroup.c
+ *
+ *  Generic process-grouping system.
+ *
+ *  Based originally on the cpuset system, extracted by Paul Menage
+ *  Copyright (C) 2006 Google, Inc
+ *
+ *  Copyright notices from the original cpuset code:
+ *  --------------------------------------------------
+ *  Copyright (C) 2003 BULL SA.
+ *  Copyright (C) 2004-2006 Silicon Graphics, Inc.
+ *
+ *  Portions derived from Patrick Mochel's sysfs code.
+ *  sysfs is Copyright (c) 2001-3 Patrick Mochel
+ *
+ *  2003-10-10 Written by Simon Derr.
+ *  2003-10-22 Updates by Stephen Hemminger.
+ *  2004 May-July Rework by Paul Jackson.
+ *  ---------------------------------------------------
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of the Linux
+ *  distribution for more details.
+ */
+
+#include <linux/cgroup.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/proc_fs.h>
+#include <linux/rcupdate.h>
+#include <linux/sched.h>
+#include <linux/backing-dev.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/magic.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/sort.h>
+#include <linux/kmod.h>
+#include <linux/delayacct.h>
+#include <linux/cgroupstats.h>
+
+#include <asm/atomic.h>
+
+static DEFINE_MUTEX(cgroup_mutex);
+
+/* Generate an array of cgroup subsystem pointers */
+#define SUBSYS(_x) &_x ## _subsys,
+
+static struct cgroup_subsys *subsys[] = {
+#include <linux/cgroup_subsys.h>
+};
+
+/*
+ * A cgroupfs_root represents the root of a cgroup hierarchy,
+ * and may be associated with a superblock to form an active
+ * hierarchy
+ */
+struct cgroupfs_root {
+	struct super_block *sb;
+
+	/*
+	 * The bitmask of subsystems intended to be attached to this
+	 * hierarchy
+	 */
+	unsigned long subsys_bits;
+
+	/* The bitmask of subsystems currently attached to this hierarchy */
+	unsigned long actual_subsys_bits;
+
+	/* A list running through the attached subsystems */
+	struct list_head subsys_list;
+
+	/* The root cgroup for this hierarchy */
+	struct cgroup top_cgroup;
+
+	/* Tracks how many cgroups are currently defined in hierarchy.*/
+	int number_of_cgroups;
+
+	/* A list running through the mounted hierarchies */
+	struct list_head root_list;
+
+	/* Hierarchy-specific flags */
+	unsigned long flags;
+
+	/* The path to use for release notifications. No locking
+	 * between setting and use - so if userspace updates this
+	 * while child cgroups exist, you could miss a
+	 * notification. We ensure that it's always a valid
+	 * NUL-terminated string */
+	char release_agent_path[PATH_MAX];
+};
+
+
+/*
+ * The "rootnode" hierarchy is the "dummy hierarchy", reserved for the
+ * subsystems that are otherwise unattached - it never has more than a
+ * single cgroup, and all tasks are part of that cgroup.
+ */
+static struct cgroupfs_root rootnode;
+
+/* The list of hierarchy roots */
+
+static LIST_HEAD(roots);
+static int root_count;
+
+/* dummytop is a shorthand for the dummy hierarchy's top cgroup */
+#define dummytop (&rootnode.top_cgroup)
+
+/* This flag indicates whether tasks in the fork and exit paths should
+ * take callback_mutex and check for fork/exit handlers to call. This
+ * avoids us having to do extra work in the fork/exit path if none of the
+ * subsystems need to be called.
+ */
+static int need_forkexit_callback;
+
+/* bits in struct cgroup flags field */
+enum {
+	/* Control Group is dead */
+	CGRP_REMOVED,
+	/* Control Group has previously had a child cgroup or a task,
+	 * but no longer (only if CGRP_NOTIFY_ON_RELEASE is set) */
+	CGRP_RELEASABLE,
+	/* Control Group requires release notifications to userspace */
+	CGRP_NOTIFY_ON_RELEASE,
+};
+
+/* convenient tests for these bits */
+inline int cgroup_is_removed(const struct cgroup *cgrp)
+{
+	return test_bit(CGRP_REMOVED, &cgrp->flags);
+}
+
+/* bits in struct cgroupfs_root flags field */
+enum {
+	ROOT_NOPREFIX, /* mounted subsystems have no named prefix */
+};
+
+inline int cgroup_is_releasable(const struct cgroup *cgrp)
+{
+	const int bits =
+		(1 << CGRP_RELEASABLE) |
+		(1 << CGRP_NOTIFY_ON_RELEASE);
+	return (cgrp->flags & bits) == bits;
+}
+
+inline int notify_on_release(const struct cgroup *cgrp)
+{
+	return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
+}
+
+/*
+ * for_each_subsys() allows you to iterate on each subsystem attached to
+ * an active hierarchy
+ */
+#define for_each_subsys(_root, _ss) \
+list_for_each_entry(_ss, &_root->subsys_list, sibling)
+
+/* for_each_root() allows you to iterate across the active hierarchies */
+#define for_each_root(_root) \
+list_for_each_entry(_root, &roots, root_list)
+
+/* the list of cgroups eligible for automatic release. Protected by
+ * release_list_lock */
+static LIST_HEAD(release_list);
+static DEFINE_SPINLOCK(release_list_lock);
+static void cgroup_release_agent(struct work_struct *work);
+static DECLARE_WORK(release_agent_work, cgroup_release_agent);
+static void check_for_release(struct cgroup *cgrp);
+
+/* Link structure for associating css_set objects with cgroups */
+struct cg_cgroup_link {
+	/*
+	 * List running through cg_cgroup_links associated with a
+	 * cgroup, anchored on cgroup->css_sets
+	 */
+	struct list_head cgrp_link_list;
+	/*
+	 * List running through cg_cgroup_links pointing at a
+	 * single css_set object, anchored on css_set->cg_links
+	 */
+	struct list_head cg_link_list;
+	struct css_set *cg;
+};
+
+/* The default css_set - used by init and its children prior to any
+ * hierarchies being mounted. It contains a pointer to the root state
+ * for each subsystem. Also used to anchor the list of css_sets. Not
+ * reference-counted, to improve performance when child cgroups
+ * haven't been created.
+ */
+
+static struct css_set init_css_set;
+static struct cg_cgroup_link init_css_set_link;
+
+/* css_set_lock protects the list of css_set objects, and the
+ * chain of tasks off each css_set.  Nests outside task->alloc_lock
+ * due to cgroup_iter_start() */
+static DEFINE_RWLOCK(css_set_lock);
+static int css_set_count;
+
+/* We don't maintain the lists running through each css_set to its
+ * task until after the first call to cgroup_iter_start(). This
+ * reduces the fork()/exit() overhead for people who have cgroups
+ * compiled into their kernel but not actually in use */
+static int use_task_css_set_links;
+
+/* When we create or destroy a css_set, the operation simply
+ * takes/releases a reference count on all the cgroups referenced
+ * by subsystems in this css_set. This can end up multiple-counting
+ * some cgroups, but that's OK - the ref-count is just a
+ * busy/not-busy indicator; ensuring that we only count each cgroup
+ * once would require taking a global lock to ensure that no
+ * subsystems moved between hierarchies while we were doing so.
+ *
+ * Possible TODO: decide at boot time based on the number of
+ * registered subsystems and the number of CPUs or NUMA nodes whether
+ * it's better for performance to ref-count every subsystem, or to
+ * take a global lock and only add one ref count to each hierarchy.
+ */
+
+/*
+ * unlink a css_set from the list and free it
+ */
+static void unlink_css_set(struct css_set *cg)
+{
+	write_lock(&css_set_lock);
+	list_del(&cg->list);
+	css_set_count--;
+	while (!list_empty(&cg->cg_links)) {
+		struct cg_cgroup_link *link;
+		link = list_entry(cg->cg_links.next,
+				  struct cg_cgroup_link, cg_link_list);
+		list_del(&link->cg_link_list);
+		list_del(&link->cgrp_link_list);
+		kfree(link);
+	}
+	write_unlock(&css_set_lock);
+}
+
+static void __release_css_set(struct kref *k, int taskexit)
+{
+	int i;
+	struct css_set *cg = container_of(k, struct css_set, ref);
+
+	unlink_css_set(cg);
+
+	rcu_read_lock();
+	for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+		struct cgroup *cgrp = cg->subsys[i]->cgroup;
+		if (atomic_dec_and_test(&cgrp->count) &&
+		    notify_on_release(cgrp)) {
+			if (taskexit)
+				set_bit(CGRP_RELEASABLE, &cgrp->flags);
+			check_for_release(cgrp);
+		}
+	}
+	rcu_read_unlock();
+	kfree(cg);
+}
+
+static void release_css_set(struct kref *k)
+{
+	__release_css_set(k, 0);
+}
+
+static void release_css_set_taskexit(struct kref *k)
+{
+	__release_css_set(k, 1);
+}
+
+/*
+ * refcounted get/put for css_set objects
+ */
+static inline void get_css_set(struct css_set *cg)
+{
+	kref_get(&cg->ref);
+}
+
+static inline void put_css_set(struct css_set *cg)
+{
+	kref_put(&cg->ref, release_css_set);
+}
+
+static inline void put_css_set_taskexit(struct css_set *cg)
+{
+	kref_put(&cg->ref, release_css_set_taskexit);
+}
+
+/*
+ * find_existing_css_set() is a helper for
+ * find_css_set(), and checks to see whether an existing
+ * css_set is suitable. This currently walks a linked-list for
+ * simplicity; a later patch will use a hash table for better
+ * performance
+ *
+ * oldcg: the cgroup group that we're using before the cgroup
+ * transition
+ *
+ * cgrp: the cgroup that we're moving into
+ *
+ * template: location in which to build the desired set of subsystem
+ * state objects for the new cgroup group
+ */
+
+static struct css_set *find_existing_css_set(
+	struct css_set *oldcg,
+	struct cgroup *cgrp,
+	struct cgroup_subsys_state *template[])
+{
+	int i;
+	struct cgroupfs_root *root = cgrp->root;
+	struct list_head *l = &init_css_set.list;
+
+	/* Built the set of subsystem state objects that we want to
+	 * see in the new css_set */
+	for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+		if (root->subsys_bits & (1ull << i)) {
+			/* Subsystem is in this hierarchy. So we want
+			 * the subsystem state from the new
+			 * cgroup */
+			template[i] = cgrp->subsys[i];
+		} else {
+			/* Subsystem is not in this hierarchy, so we
+			 * don't want to change the subsystem state */
+			template[i] = oldcg->subsys[i];
+		}
+	}
+
+	/* Look through existing cgroup groups to find one to reuse */
+	do {
+		struct css_set *cg =
+			list_entry(l, struct css_set, list);
+
+		if (!memcmp(template, cg->subsys, sizeof(cg->subsys))) {
+			/* All subsystems matched */
+			return cg;
+		}
+		/* Try the next cgroup group */
+		l = l->next;
+	} while (l != &init_css_set.list);
+
+	/* No existing cgroup group matched */
+	return NULL;
+}
+
+/*
+ * allocate_cg_links() allocates "count" cg_cgroup_link structures
+ * and chains them on tmp through their cgrp_link_list fields. Returns 0 on
+ * success or a negative error
+ */
+
+static int allocate_cg_links(int count, struct list_head *tmp)
+{
+	struct cg_cgroup_link *link;
+	int i;
+	INIT_LIST_HEAD(tmp);
+	for (i = 0; i < count; i++) {
+		link = kmalloc(sizeof(*link), GFP_KERNEL);
+		if (!link) {
+			while (!list_empty(tmp)) {
+				link = list_entry(tmp->next,
+						  struct cg_cgroup_link,
+						  cgrp_link_list);
+				list_del(&link->cgrp_link_list);
+				kfree(link);
+			}
+			return -ENOMEM;
+		}
+		list_add(&link->cgrp_link_list, tmp);
+	}
+	return 0;
+}
+
+static void free_cg_links(struct list_head *tmp)
+{
+	while (!list_empty(tmp)) {
+		struct cg_cgroup_link *link;
+		link = list_entry(tmp->next,
+				  struct cg_cgroup_link,
+				  cgrp_link_list);
+		list_del(&link->cgrp_link_list);
+		kfree(link);
+	}
+}
+
+/*
+ * find_css_set() takes an existing cgroup group and a
+ * cgroup object, and returns a css_set object that's
+ * equivalent to the old group, but with the given cgroup
+ * substituted into the appropriate hierarchy. Must be called with
+ * cgroup_mutex held
+ */
+
+static struct css_set *find_css_set(
+	struct css_set *oldcg, struct cgroup *cgrp)
+{
+	struct css_set *res;
+	struct cgroup_subsys_state *template[CGROUP_SUBSYS_COUNT];
+	int i;
+
+	struct list_head tmp_cg_links;
+	struct cg_cgroup_link *link;
+
+	/* First see if we already have a cgroup group that matches
+	 * the desired set */
+	write_lock(&css_set_lock);
+	res = find_existing_css_set(oldcg, cgrp, template);
+	if (res)
+		get_css_set(res);
+	write_unlock(&css_set_lock);
+
+	if (res)
+		return res;
+
+	res = kmalloc(sizeof(*res), GFP_KERNEL);
+	if (!res)
+		return NULL;
+
+	/* Allocate all the cg_cgroup_link objects that we'll need */
+	if (allocate_cg_links(root_count, &tmp_cg_links) < 0) {
+		kfree(res);
+		return NULL;
+	}
+
+	kref_init(&res->ref);
+	INIT_LIST_HEAD(&res->cg_links);
+	INIT_LIST_HEAD(&res->tasks);
+
+	/* Copy the set of subsystem state objects generated in
+	 * find_existing_css_set() */
+	memcpy(res->subsys, template, sizeof(res->subsys));
+
+	write_lock(&css_set_lock);
+	/* Add reference counts and links from the new css_set. */
+	for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+		struct cgroup *cgrp = res->subsys[i]->cgroup;
+		struct cgroup_subsys *ss = subsys[i];
+		atomic_inc(&cgrp->count);
+		/*
+		 * We want to add a link once per cgroup, so we
+		 * only do it for the first subsystem in each
+		 * hierarchy
+		 */
+		if (ss->root->subsys_list.next == &ss->sibling) {
+			BUG_ON(list_empty(&tmp_cg_links));
+			link = list_entry(tmp_cg_links.next,
+					  struct cg_cgroup_link,
+					  cgrp_link_list);
+			list_del(&link->cgrp_link_list);
+			list_add(&link->cgrp_link_list, &cgrp->css_sets);
+			link->cg = res;
+			list_add(&link->cg_link_list, &res->cg_links);
+		}
+	}
+	if (list_empty(&rootnode.subsys_list)) {
+		link = list_entry(tmp_cg_links.next,
+				  struct cg_cgroup_link,
+				  cgrp_link_list);
+		list_del(&link->cgrp_link_list);
+		list_add(&link->cgrp_link_list, &dummytop->css_sets);
+		link->cg = res;
+		list_add(&link->cg_link_list, &res->cg_links);
+	}
+
+	BUG_ON(!list_empty(&tmp_cg_links));
+
+	/* Link this cgroup group into the list */
+	list_add(&res->list, &init_css_set.list);
+	css_set_count++;
+	INIT_LIST_HEAD(&res->tasks);
+	write_unlock(&css_set_lock);
+
+	return res;
+}
+
+/*
+ * There is one global cgroup mutex. We also require taking
+ * task_lock() when dereferencing a task's cgroup subsys pointers.
+ * See "The task_lock() exception", at the end of this comment.
+ *
+ * A task must hold cgroup_mutex to modify cgroups.
+ *
+ * Any task can increment and decrement the count field without lock.
+ * So in general, code holding cgroup_mutex can't rely on the count
+ * field not changing.  However, if the count goes to zero, then only
+ * attach_task() can increment it again.  Because a count of zero
+ * means that no tasks are currently attached, therefore there is no
+ * way a task attached to that cgroup can fork (the other way to
+ * increment the count).  So code holding cgroup_mutex can safely
+ * assume that if the count is zero, it will stay zero. Similarly, if
+ * a task holds cgroup_mutex on a cgroup with zero count, it
+ * knows that the cgroup won't be removed, as cgroup_rmdir()
+ * needs that mutex.
+ *
+ * The cgroup_common_file_write handler for operations that modify
+ * the cgroup hierarchy holds cgroup_mutex across the entire operation,
+ * single threading all such cgroup modifications across the system.
+ *
+ * The fork and exit callbacks cgroup_fork() and cgroup_exit(), don't
+ * (usually) take cgroup_mutex.  These are the two most performance
+ * critical pieces of code here.  The exception occurs on cgroup_exit(),
+ * when a task in a notify_on_release cgroup exits.  Then cgroup_mutex
+ * is taken, and if the cgroup count is zero, a usermode call made
+ * to /sbin/cgroup_release_agent with the name of the cgroup (path
+ * relative to the root of cgroup file system) as the argument.
+ *
+ * A cgroup can only be deleted if both its 'count' of using tasks
+ * is zero, and its list of 'children' cgroups is empty.  Since all
+ * tasks in the system use _some_ cgroup, and since there is always at
+ * least one task in the system (init, pid == 1), therefore, top_cgroup
+ * always has either children cgroups and/or using tasks.  So we don't
+ * need a special hack to ensure that top_cgroup cannot be deleted.
+ *
+ *	The task_lock() exception
+ *
+ * The need for this exception arises from the action of
+ * attach_task(), which overwrites one tasks cgroup pointer with
+ * another.  It does so using cgroup_mutexe, however there are
+ * several performance critical places that need to reference
+ * task->cgroup without the expense of grabbing a system global
+ * mutex.  Therefore except as noted below, when dereferencing or, as
+ * in attach_task(), modifying a task'ss cgroup pointer we use
+ * task_lock(), which acts on a spinlock (task->alloc_lock) already in
+ * the task_struct routinely used for such matters.
+ *
+ * P.S.  One more locking exception.  RCU is used to guard the
+ * update of a tasks cgroup pointer by attach_task()
+ */
+
+/**
+ * cgroup_lock - lock out any changes to cgroup structures
+ *
+ */
+
+void cgroup_lock(void)
+{
+	mutex_lock(&cgroup_mutex);
+}
+
+/**
+ * cgroup_unlock - release lock on cgroup changes
+ *
+ * Undo the lock taken in a previous cgroup_lock() call.
+ */
+
+void cgroup_unlock(void)
+{
+	mutex_unlock(&cgroup_mutex);
+}
+
+/*
+ * A couple of forward declarations required, due to cyclic reference loop:
+ * cgroup_mkdir -> cgroup_create -> cgroup_populate_dir ->
+ * cgroup_add_file -> cgroup_create_file -> cgroup_dir_inode_operations
+ * -> cgroup_mkdir.
+ */
+
+static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode);
+static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
+static int cgroup_populate_dir(struct cgroup *cgrp);
+static struct inode_operations cgroup_dir_inode_operations;
+static struct file_operations proc_cgroupstats_operations;
+
+static struct backing_dev_info cgroup_backing_dev_info = {
+	.capabilities	= BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
+};
+
+static struct inode *cgroup_new_inode(mode_t mode, struct super_block *sb)
+{
+	struct inode *inode = new_inode(sb);
+
+	if (inode) {
+		inode->i_mode = mode;
+		inode->i_uid = current->fsuid;
+		inode->i_gid = current->fsgid;
+		inode->i_blocks = 0;
+		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		inode->i_mapping->backing_dev_info = &cgroup_backing_dev_info;
+	}
+	return inode;
+}
+
+static void cgroup_diput(struct dentry *dentry, struct inode *inode)
+{
+	/* is dentry a directory ? if so, kfree() associated cgroup */
+	if (S_ISDIR(inode->i_mode)) {
+		struct cgroup *cgrp = dentry->d_fsdata;
+		BUG_ON(!(cgroup_is_removed(cgrp)));
+		/* It's possible for external users to be holding css
+		 * reference counts on a cgroup; css_put() needs to
+		 * be able to access the cgroup after decrementing
+		 * the reference count in order to know if it needs to
+		 * queue the cgroup to be handled by the release
+		 * agent */
+		synchronize_rcu();
+		kfree(cgrp);
+	}
+	iput(inode);
+}
+
+static void remove_dir(struct dentry *d)
+{
+	struct dentry *parent = dget(d->d_parent);
+
+	d_delete(d);
+	simple_rmdir(parent->d_inode, d);
+	dput(parent);
+}
+
+static void cgroup_clear_directory(struct dentry *dentry)
+{
+	struct list_head *node;
+
+	BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
+	spin_lock(&dcache_lock);
+	node = dentry->d_subdirs.next;
+	while (node != &dentry->d_subdirs) {
+		struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
+		list_del_init(node);
+		if (d->d_inode) {
+			/* This should never be called on a cgroup
+			 * directory with child cgroups */
+			BUG_ON(d->d_inode->i_mode & S_IFDIR);
+			d = dget_locked(d);
+			spin_unlock(&dcache_lock);
+			d_delete(d);
+			simple_unlink(dentry->d_inode, d);
+			dput(d);
+			spin_lock(&dcache_lock);
+		}
+		node = dentry->d_subdirs.next;
+	}
+	spin_unlock(&dcache_lock);
+}
+
+/*
+ * NOTE : the dentry must have been dget()'ed
+ */
+static void cgroup_d_remove_dir(struct dentry *dentry)
+{
+	cgroup_clear_directory(dentry);
+
+	spin_lock(&dcache_lock);
+	list_del_init(&dentry->d_u.d_child);
+	spin_unlock(&dcache_lock);
+	remove_dir(dentry);
+}
+
+static int rebind_subsystems(struct cgroupfs_root *root,
+			      unsigned long final_bits)
+{
+	unsigned long added_bits, removed_bits;
+	struct cgroup *cgrp = &root->top_cgroup;
+	int i;
+
+	removed_bits = root->actual_subsys_bits & ~final_bits;
+	added_bits = final_bits & ~root->actual_subsys_bits;
+	/* Check that any added subsystems are currently free */
+	for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+		unsigned long long bit = 1ull << i;
+		struct cgroup_subsys *ss = subsys[i];
+		if (!(bit & added_bits))
+			continue;
+		if (ss->root != &rootnode) {
+			/* Subsystem isn't free */
+			return -EBUSY;
+		}
+	}
+
+	/* Currently we don't handle adding/removing subsystems when
+	 * any child cgroups exist. This is theoretically supportable
+	 * but involves complex error handling, so it's being left until
+	 * later */
+	if (!list_empty(&cgrp->children))
+		return -EBUSY;
+
+	/* Process each subsystem */
+	for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+		struct cgroup_subsys *ss = subsys[i];
+		unsigned long bit = 1UL << i;
+		if (bit & added_bits) {
+			/* We're binding this subsystem to this hierarchy */
+			BUG_ON(cgrp->subsys[i]);
+			BUG_ON(!dummytop->subsys[i]);
+			BUG_ON(dummytop->subsys[i]->cgroup != dummytop);
+			cgrp->subsys[i] = dummytop->subsys[i];
+			cgrp->subsys[i]->cgroup = cgrp;
+			list_add(&ss->sibling, &root->subsys_list);
+			rcu_assign_pointer(ss->root, root);
+			if (ss->bind)
+				ss->bind(ss, cgrp);
+
+		} else if (bit & removed_bits) {
+			/* We're removing this subsystem */
+			BUG_ON(cgrp->subsys[i] != dummytop->subsys[i]);
+			BUG_ON(cgrp->subsys[i]->cgroup != cgrp);
+			if (ss->bind)
+				ss->bind(ss, dummytop);
+			dummytop->subsys[i]->cgroup = dummytop;
+			cgrp->subsys[i] = NULL;
+			rcu_assign_pointer(subsys[i]->root, &rootnode);
+			list_del(&ss->sibling);
+		} else if (bit & final_bits) {
+			/* Subsystem state should already exist */
+			BUG_ON(!cgrp->subsys[i]);
+		} else {
+			/* Subsystem state shouldn't exist */
+			BUG_ON(cgrp->subsys[i]);
+		}
+	}
+	root->subsys_bits = root->actual_subsys_bits = final_bits;
+	synchronize_rcu();
+
+	return 0;
+}
+
+static int cgroup_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+	struct cgroupfs_root *root = vfs->mnt_sb->s_fs_info;
+	struct cgroup_subsys *ss;
+
+	mutex_lock(&cgroup_mutex);
+	for_each_subsys(root, ss)
+		seq_printf(seq, ",%s", ss->name);
+	if (test_bit(ROOT_NOPREFIX, &root->flags))
+		seq_puts(seq, ",noprefix");
+	if (strlen(root->release_agent_path))
+		seq_printf(seq, ",release_agent=%s", root->release_agent_path);
+	mutex_unlock(&cgroup_mutex);
+	return 0;
+}
+
+struct cgroup_sb_opts {
+	unsigned long subsys_bits;
+	unsigned long flags;
+	char *release_agent;
+};
+
+/* Convert a hierarchy specifier into a bitmask of subsystems and
+ * flags. */
+static int parse_cgroupfs_options(char *data,
+				     struct cgroup_sb_opts *opts)
+{
+	char *token, *o = data ?: "all";
+
+	opts->subsys_bits = 0;
+	opts->flags = 0;
+	opts->release_agent = NULL;
+
+	while ((token = strsep(&o, ",")) != NULL) {
+		if (!*token)
+			return -EINVAL;
+		if (!strcmp(token, "all")) {
+			opts->subsys_bits = (1 << CGROUP_SUBSYS_COUNT) - 1;
+		} else if (!strcmp(token, "noprefix")) {
+			set_bit(ROOT_NOPREFIX, &opts->flags);
+		} else if (!strncmp(token, "release_agent=", 14)) {
+			/* Specifying two release agents is forbidden */
+			if (opts->release_agent)
+				return -EINVAL;
+			opts->release_agent = kzalloc(PATH_MAX, GFP_KERNEL);
+			if (!opts->release_agent)
+				return -ENOMEM;
+			strncpy(opts->release_agent, token + 14, PATH_MAX - 1);
+			opts->release_agent[PATH_MAX - 1] = 0;
+		} else {
+			struct cgroup_subsys *ss;
+			int i;
+			for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+				ss = subsys[i];
+				if (!strcmp(token, ss->name)) {
+					set_bit(i, &opts->subsys_bits);
+					break;
+				}
+			}
+			if (i == CGROUP_SUBSYS_COUNT)
+				return -ENOENT;
+		}
+	}
+
+	/* We can't have an empty hierarchy */
+	if (!opts->subsys_bits)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int cgroup_remount(struct super_block *sb, int *flags, char *data)
+{
+	int ret = 0;
+	struct cgroupfs_root *root = sb->s_fs_info;
+	struct cgroup *cgrp = &root->top_cgroup;
+	struct cgroup_sb_opts opts;
+
+	mutex_lock(&cgrp->dentry->d_inode->i_mutex);
+	mutex_lock(&cgroup_mutex);
+
+	/* See what subsystems are wanted */
+	ret = parse_cgroupfs_options(data, &opts);
+	if (ret)
+		goto out_unlock;
+
+	/* Don't allow flags to change at remount */
+	if (opts.flags != root->flags) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	ret = rebind_subsystems(root, opts.subsys_bits);
+
+	/* (re)populate subsystem files */
+	if (!ret)
+		cgroup_populate_dir(cgrp);
+
+	if (opts.release_agent)
+		strcpy(root->release_agent_path, opts.release_agent);
+ out_unlock:
+	if (opts.release_agent)
+		kfree(opts.release_agent);
+	mutex_unlock(&cgroup_mutex);
+	mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
+	return ret;
+}
+
+static struct super_operations cgroup_ops = {
+	.statfs = simple_statfs,
+	.drop_inode = generic_delete_inode,
+	.show_options = cgroup_show_options,
+	.remount_fs = cgroup_remount,
+};
+
+static void init_cgroup_root(struct cgroupfs_root *root)
+{
+	struct cgroup *cgrp = &root->top_cgroup;
+	INIT_LIST_HEAD(&root->subsys_list);
+	INIT_LIST_HEAD(&root->root_list);
+	root->number_of_cgroups = 1;
+	cgrp->root = root;
+	cgrp->top_cgroup = cgrp;
+	INIT_LIST_HEAD(&cgrp->sibling);
+	INIT_LIST_HEAD(&cgrp->children);
+	INIT_LIST_HEAD(&cgrp->css_sets);
+	INIT_LIST_HEAD(&cgrp->release_list);
+}
+
+static int cgroup_test_super(struct super_block *sb, void *data)
+{
+	struct cgroupfs_root *new = data;
+	struct cgroupfs_root *root = sb->s_fs_info;
+
+	/* First check subsystems */
+	if (new->subsys_bits != root->subsys_bits)
+	    return 0;
+
+	/* Next check flags */
+	if (new->flags != root->flags)
+		return 0;
+
+	return 1;
+}
+
+static int cgroup_set_super(struct super_block *sb, void *data)
+{
+	int ret;
+	struct cgroupfs_root *root = data;
+
+	ret = set_anon_super(sb, NULL);
+	if (ret)
+		return ret;
+
+	sb->s_fs_info = root;
+	root->sb = sb;
+
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = CGROUP_SUPER_MAGIC;
+	sb->s_op = &cgroup_ops;
+
+	return 0;
+}
+
+static int cgroup_get_rootdir(struct super_block *sb)
+{
+	struct inode *inode =
+		cgroup_new_inode(S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR, sb);
+	struct dentry *dentry;
+
+	if (!inode)
+		return -ENOMEM;
+
+	inode->i_op = &simple_dir_inode_operations;
+	inode->i_fop = &simple_dir_operations;
+	inode->i_op = &cgroup_dir_inode_operations;
+	/* directories start off with i_nlink == 2 (for "." entry) */
+	inc_nlink(inode);
+	dentry = d_alloc_root(inode);
+	if (!dentry) {
+		iput(inode);
+		return -ENOMEM;
+	}
+	sb->s_root = dentry;
+	return 0;
+}
+
+static int cgroup_get_sb(struct file_system_type *fs_type,
+			 int flags, const char *unused_dev_name,
+			 void *data, struct vfsmount *mnt)
+{
+	struct cgroup_sb_opts opts;
+	int ret = 0;
+	struct super_block *sb;
+	struct cgroupfs_root *root;
+	struct list_head tmp_cg_links, *l;
+	INIT_LIST_HEAD(&tmp_cg_links);
+
+	/* First find the desired set of subsystems */
+	ret = parse_cgroupfs_options(data, &opts);
+	if (ret) {
+		if (opts.release_agent)
+			kfree(opts.release_agent);
+		return ret;
+	}
+
+	root = kzalloc(sizeof(*root), GFP_KERNEL);
+	if (!root)
+		return -ENOMEM;
+
+	init_cgroup_root(root);
+	root->subsys_bits = opts.subsys_bits;
+	root->flags = opts.flags;
+	if (opts.release_agent) {
+		strcpy(root->release_agent_path, opts.release_agent);
+		kfree(opts.release_agent);
+	}
+
+	sb = sget(fs_type, cgroup_test_super, cgroup_set_super, root);
+
+	if (IS_ERR(sb)) {
+		kfree(root);
+		return PTR_ERR(sb);
+	}
+
+	if (sb->s_fs_info != root) {
+		/* Reusing an existing superblock */
+		BUG_ON(sb->s_root == NULL);
+		kfree(root);
+		root = NULL;
+	} else {
+		/* New superblock */
+		struct cgroup *cgrp = &root->top_cgroup;
+		struct inode *inode;
+
+		BUG_ON(sb->s_root != NULL);
+
+		ret = cgroup_get_rootdir(sb);
+		if (ret)
+			goto drop_new_super;
+		inode = sb->s_root->d_inode;
+
+		mutex_lock(&inode->i_mutex);
+		mutex_lock(&cgroup_mutex);
+
+		/*
+		 * We're accessing css_set_count without locking
+		 * css_set_lock here, but that's OK - it can only be
+		 * increased by someone holding cgroup_lock, and
+		 * that's us. The worst that can happen is that we
+		 * have some link structures left over
+		 */
+		ret = allocate_cg_links(css_set_count, &tmp_cg_links);
+		if (ret) {
+			mutex_unlock(&cgroup_mutex);
+			mutex_unlock(&inode->i_mutex);
+			goto drop_new_super;
+		}
+
+		ret = rebind_subsystems(root, root->subsys_bits);
+		if (ret == -EBUSY) {
+			mutex_unlock(&cgroup_mutex);
+			mutex_unlock(&inode->i_mutex);
+			goto drop_new_super;
+		}
+
+		/* EBUSY should be the only error here */
+		BUG_ON(ret);
+
+		list_add(&root->root_list, &roots);
+		root_count++;
+
+		sb->s_root->d_fsdata = &root->top_cgroup;
+		root->top_cgroup.dentry = sb->s_root;
+
+		/* Link the top cgroup in this hierarchy into all
+		 * the css_set objects */
+		write_lock(&css_set_lock);
+		l = &init_css_set.list;
+		do {
+			struct css_set *cg;
+			struct cg_cgroup_link *link;
+			cg = list_entry(l, struct css_set, list);
+			BUG_ON(list_empty(&tmp_cg_links));
+			link = list_entry(tmp_cg_links.next,
+					  struct cg_cgroup_link,
+					  cgrp_link_list);
+			list_del(&link->cgrp_link_list);
+			link->cg = cg;
+			list_add(&link->cgrp_link_list,
+				 &root->top_cgroup.css_sets);
+			list_add(&link->cg_link_list, &cg->cg_links);
+			l = l->next;
+		} while (l != &init_css_set.list);
+		write_unlock(&css_set_lock);
+
+		free_cg_links(&tmp_cg_links);
+
+		BUG_ON(!list_empty(&cgrp->sibling));
+		BUG_ON(!list_empty(&cgrp->children));
+		BUG_ON(root->number_of_cgroups != 1);
+
+		cgroup_populate_dir(cgrp);
+		mutex_unlock(&inode->i_mutex);
+		mutex_unlock(&cgroup_mutex);
+	}
+
+	return simple_set_mnt(mnt, sb);
+
+ drop_new_super:
+	up_write(&sb->s_umount);
+	deactivate_super(sb);
+	free_cg_links(&tmp_cg_links);
+	return ret;
+}
+
+static void cgroup_kill_sb(struct super_block *sb) {
+	struct cgroupfs_root *root = sb->s_fs_info;
+	struct cgroup *cgrp = &root->top_cgroup;
+	int ret;
+
+	BUG_ON(!root);
+
+	BUG_ON(root->number_of_cgroups != 1);
+	BUG_ON(!list_empty(&cgrp->children));
+	BUG_ON(!list_empty(&cgrp->sibling));
+
+	mutex_lock(&cgroup_mutex);
+
+	/* Rebind all subsystems back to the default hierarchy */
+	ret = rebind_subsystems(root, 0);
+	/* Shouldn't be able to fail ... */
+	BUG_ON(ret);
+
+	/*
+	 * Release all the links from css_sets to this hierarchy's
+	 * root cgroup
+	 */
+	write_lock(&css_set_lock);
+	while (!list_empty(&cgrp->css_sets)) {
+		struct cg_cgroup_link *link;
+		link = list_entry(cgrp->css_sets.next,
+				  struct cg_cgroup_link, cgrp_link_list);
+		list_del(&link->cg_link_list);
+		list_del(&link->cgrp_link_list);
+		kfree(link);
+	}
+	write_unlock(&css_set_lock);
+
+	if (!list_empty(&root->root_list)) {
+		list_del(&root->root_list);
+		root_count--;
+	}
+	mutex_unlock(&cgroup_mutex);
+
+	kfree(root);
+	kill_litter_super(sb);
+}
+
+static struct file_system_type cgroup_fs_type = {
+	.name = "cgroup",
+	.get_sb = cgroup_get_sb,
+	.kill_sb = cgroup_kill_sb,
+};
+
+static inline struct cgroup *__d_cgrp(struct dentry *dentry)
+{
+	return dentry->d_fsdata;
+}
+
+static inline struct cftype *__d_cft(struct dentry *dentry)
+{
+	return dentry->d_fsdata;
+}
+
+/*
+ * Called with cgroup_mutex held.  Writes path of cgroup into buf.
+ * Returns 0 on success, -errno on error.
+ */
+int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
+{
+	char *start;
+
+	if (cgrp == dummytop) {
+		/*
+		 * Inactive subsystems have no dentry for their root
+		 * cgroup
+		 */
+		strcpy(buf, "/");
+		return 0;
+	}
+
+	start = buf + buflen;
+
+	*--start = '\0';
+	for (;;) {
+		int len = cgrp->dentry->d_name.len;
+		if ((start -= len) < buf)
+			return -ENAMETOOLONG;
+		memcpy(start, cgrp->dentry->d_name.name, len);
+		cgrp = cgrp->parent;
+		if (!cgrp)
+			break;
+		if (!cgrp->parent)
+			continue;
+		if (--start < buf)
+			return -ENAMETOOLONG;
+		*start = '/';
+	}
+	memmove(buf, start, buf + buflen - start);
+	return 0;
+}
+
+/*
+ * Return the first subsystem attached to a cgroup's hierarchy, and
+ * its subsystem id.
+ */
+
+static void get_first_subsys(const struct cgroup *cgrp,
+			struct cgroup_subsys_state **css, int *subsys_id)
+{
+	const struct cgroupfs_root *root = cgrp->root;
+	const struct cgroup_subsys *test_ss;
+	BUG_ON(list_empty(&root->subsys_list));
+	test_ss = list_entry(root->subsys_list.next,
+			     struct cgroup_subsys, sibling);
+	if (css) {
+		*css = cgrp->subsys[test_ss->subsys_id];
+		BUG_ON(!*css);
+	}
+	if (subsys_id)
+		*subsys_id = test_ss->subsys_id;
+}
+
+/*
+ * Attach task 'tsk' to cgroup 'cgrp'
+ *
+ * Call holding cgroup_mutex.  May take task_lock of
+ * the task 'pid' during call.
+ */
+static int attach_task(struct cgroup *cgrp, struct task_struct *tsk)
+{
+	int retval = 0;
+	struct cgroup_subsys *ss;
+	struct cgroup *oldcgrp;
+	struct css_set *cg = tsk->cgroups;
+	struct css_set *newcg;
+	struct cgroupfs_root *root = cgrp->root;
+	int subsys_id;
+
+	get_first_subsys(cgrp, NULL, &subsys_id);
+
+	/* Nothing to do if the task is already in that cgroup */
+	oldcgrp = task_cgroup(tsk, subsys_id);
+	if (cgrp == oldcgrp)
+		return 0;
+
+	for_each_subsys(root, ss) {
+		if (ss->can_attach) {
+			retval = ss->can_attach(ss, cgrp, tsk);
+			if (retval) {
+				return retval;
+			}
+		}
+	}
+
+	/*
+	 * Locate or allocate a new css_set for this task,
+	 * based on its final set of cgroups
+	 */
+	newcg = find_css_set(cg, cgrp);
+	if (!newcg) {
+		return -ENOMEM;
+	}
+
+	task_lock(tsk);
+	if (tsk->flags & PF_EXITING) {
+		task_unlock(tsk);
+		put_css_set(newcg);
+		return -ESRCH;
+	}
+	rcu_assign_pointer(tsk->cgroups, newcg);
+	task_unlock(tsk);
+
+	/* Update the css_set linked lists if we're using them */
+	write_lock(&css_set_lock);
+	if (!list_empty(&tsk->cg_list)) {
+		list_del(&tsk->cg_list);
+		list_add(&tsk->cg_list, &newcg->tasks);
+	}
+	write_unlock(&css_set_lock);
+
+	for_each_subsys(root, ss) {
+		if (ss->attach) {
+			ss->attach(ss, cgrp, oldcgrp, tsk);
+		}
+	}
+	set_bit(CGRP_RELEASABLE, &oldcgrp->flags);
+	synchronize_rcu();
+	put_css_set(cg);
+	return 0;
+}
+
+/*
+ * Attach task with pid 'pid' to cgroup 'cgrp'. Call with
+ * cgroup_mutex, may take task_lock of task
+ */
+static int attach_task_by_pid(struct cgroup *cgrp, char *pidbuf)
+{
+	pid_t pid;
+	struct task_struct *tsk;
+	int ret;
+
+	if (sscanf(pidbuf, "%d", &pid) != 1)
+		return -EIO;
+
+	if (pid) {
+		rcu_read_lock();
+		tsk = find_task_by_pid(pid);
+		if (!tsk || tsk->flags & PF_EXITING) {
+			rcu_read_unlock();
+			return -ESRCH;
+		}
+		get_task_struct(tsk);
+		rcu_read_unlock();
+
+		if ((current->euid) && (current->euid != tsk->uid)
+		    && (current->euid != tsk->suid)) {
+			put_task_struct(tsk);
+			return -EACCES;
+		}
+	} else {
+		tsk = current;
+		get_task_struct(tsk);
+	}
+
+	ret = attach_task(cgrp, tsk);
+	put_task_struct(tsk);
+	return ret;
+}
+
+/* The various types of files and directories in a cgroup file system */
+
+enum cgroup_filetype {
+	FILE_ROOT,
+	FILE_DIR,
+	FILE_TASKLIST,
+	FILE_NOTIFY_ON_RELEASE,
+	FILE_RELEASABLE,
+	FILE_RELEASE_AGENT,
+};
+
+static ssize_t cgroup_write_uint(struct cgroup *cgrp, struct cftype *cft,
+				 struct file *file,
+				 const char __user *userbuf,
+				 size_t nbytes, loff_t *unused_ppos)
+{
+	char buffer[64];
+	int retval = 0;
+	u64 val;
+	char *end;
+
+	if (!nbytes)
+		return -EINVAL;
+	if (nbytes >= sizeof(buffer))
+		return -E2BIG;
+	if (copy_from_user(buffer, userbuf, nbytes))
+		return -EFAULT;
+
+	buffer[nbytes] = 0;     /* nul-terminate */
+
+	/* strip newline if necessary */
+	if (nbytes && (buffer[nbytes-1] == '\n'))
+		buffer[nbytes-1] = 0;
+	val = simple_strtoull(buffer, &end, 0);
+	if (*end)
+		return -EINVAL;
+
+	/* Pass to subsystem */
+	retval = cft->write_uint(cgrp, cft, val);
+	if (!retval)
+		retval = nbytes;
+	return retval;
+}
+
+static ssize_t cgroup_common_file_write(struct cgroup *cgrp,
+					   struct cftype *cft,
+					   struct file *file,
+					   const char __user *userbuf,
+					   size_t nbytes, loff_t *unused_ppos)
+{
+	enum cgroup_filetype type = cft->private;
+	char *buffer;
+	int retval = 0;
+
+	if (nbytes >= PATH_MAX)
+		return -E2BIG;
+
+	/* +1 for nul-terminator */
+	buffer = kmalloc(nbytes + 1, GFP_KERNEL);
+	if (buffer == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(buffer, userbuf, nbytes)) {
+		retval = -EFAULT;
+		goto out1;
+	}
+	buffer[nbytes] = 0;	/* nul-terminate */
+
+	mutex_lock(&cgroup_mutex);
+
+	if (cgroup_is_removed(cgrp)) {
+		retval = -ENODEV;
+		goto out2;
+	}
+
+	switch (type) {
+	case FILE_TASKLIST:
+		retval = attach_task_by_pid(cgrp, buffer);
+		break;
+	case FILE_NOTIFY_ON_RELEASE:
+		clear_bit(CGRP_RELEASABLE, &cgrp->flags);
+		if (simple_strtoul(buffer, NULL, 10) != 0)
+			set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
+		else
+			clear_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
+		break;
+	case FILE_RELEASE_AGENT:
+	{
+		struct cgroupfs_root *root = cgrp->root;
+		/* Strip trailing newline */
+		if (nbytes && (buffer[nbytes-1] == '\n')) {
+			buffer[nbytes-1] = 0;
+		}
+		if (nbytes < sizeof(root->release_agent_path)) {
+			/* We never write anything other than '\0'
+			 * into the last char of release_agent_path,
+			 * so it always remains a NUL-terminated
+			 * string */
+			strncpy(root->release_agent_path, buffer, nbytes);
+			root->release_agent_path[nbytes] = 0;
+		} else {
+			retval = -ENOSPC;
+		}
+		break;
+	}
+	default:
+		retval = -EINVAL;
+		goto out2;
+	}
+
+	if (retval == 0)
+		retval = nbytes;
+out2:
+	mutex_unlock(&cgroup_mutex);
+out1:
+	kfree(buffer);
+	return retval;
+}
+
+static ssize_t cgroup_file_write(struct file *file, const char __user *buf,
+						size_t nbytes, loff_t *ppos)
+{
+	struct cftype *cft = __d_cft(file->f_dentry);
+	struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent);
+
+	if (!cft)
+		return -ENODEV;
+	if (cft->write)
+		return cft->write(cgrp, cft, file, buf, nbytes, ppos);
+	if (cft->write_uint)
+		return cgroup_write_uint(cgrp, cft, file, buf, nbytes, ppos);
+	return -EINVAL;
+}
+
+static ssize_t cgroup_read_uint(struct cgroup *cgrp, struct cftype *cft,
+				   struct file *file,
+				   char __user *buf, size_t nbytes,
+				   loff_t *ppos)
+{
+	char tmp[64];
+	u64 val = cft->read_uint(cgrp, cft);
+	int len = sprintf(tmp, "%llu\n", (unsigned long long) val);
+
+	return simple_read_from_buffer(buf, nbytes, ppos, tmp, len);
+}
+
+static ssize_t cgroup_common_file_read(struct cgroup *cgrp,
+					  struct cftype *cft,
+					  struct file *file,
+					  char __user *buf,
+					  size_t nbytes, loff_t *ppos)
+{
+	enum cgroup_filetype type = cft->private;
+	char *page;
+	ssize_t retval = 0;
+	char *s;
+
+	if (!(page = (char *)__get_free_page(GFP_KERNEL)))
+		return -ENOMEM;
+
+	s = page;
+
+	switch (type) {
+	case FILE_RELEASE_AGENT:
+	{
+		struct cgroupfs_root *root;
+		size_t n;
+		mutex_lock(&cgroup_mutex);
+		root = cgrp->root;
+		n = strnlen(root->release_agent_path,
+			    sizeof(root->release_agent_path));
+		n = min(n, (size_t) PAGE_SIZE);
+		strncpy(s, root->release_agent_path, n);
+		mutex_unlock(&cgroup_mutex);
+		s += n;
+		break;
+	}
+	default:
+		retval = -EINVAL;
+		goto out;
+	}
+	*s++ = '\n';
+
+	retval = simple_read_from_buffer(buf, nbytes, ppos, page, s - page);
+out:
+	free_page((unsigned long)page);
+	return retval;
+}
+
+static ssize_t cgroup_file_read(struct file *file, char __user *buf,
+				   size_t nbytes, loff_t *ppos)
+{
+	struct cftype *cft = __d_cft(file->f_dentry);
+	struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent);
+
+	if (!cft)
+		return -ENODEV;
+
+	if (cft->read)
+		return cft->read(cgrp, cft, file, buf, nbytes, ppos);
+	if (cft->read_uint)
+		return cgroup_read_uint(cgrp, cft, file, buf, nbytes, ppos);
+	return -EINVAL;
+}
+
+static int cgroup_file_open(struct inode *inode, struct file *file)
+{
+	int err;
+	struct cftype *cft;
+
+	err = generic_file_open(inode, file);
+	if (err)
+		return err;
+
+	cft = __d_cft(file->f_dentry);
+	if (!cft)
+		return -ENODEV;
+	if (cft->open)
+		err = cft->open(inode, file);
+	else
+		err = 0;
+
+	return err;
+}
+
+static int cgroup_file_release(struct inode *inode, struct file *file)
+{
+	struct cftype *cft = __d_cft(file->f_dentry);
+	if (cft->release)
+		return cft->release(inode, file);
+	return 0;
+}
+
+/*
+ * cgroup_rename - Only allow simple rename of directories in place.
+ */
+static int cgroup_rename(struct inode *old_dir, struct dentry *old_dentry,
+			    struct inode *new_dir, struct dentry *new_dentry)
+{
+	if (!S_ISDIR(old_dentry->d_inode->i_mode))
+		return -ENOTDIR;
+	if (new_dentry->d_inode)
+		return -EEXIST;
+	if (old_dir != new_dir)
+		return -EIO;
+	return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
+}
+
+static struct file_operations cgroup_file_operations = {
+	.read = cgroup_file_read,
+	.write = cgroup_file_write,
+	.llseek = generic_file_llseek,
+	.open = cgroup_file_open,
+	.release = cgroup_file_release,
+};
+
+static struct inode_operations cgroup_dir_inode_operations = {
+	.lookup = simple_lookup,
+	.mkdir = cgroup_mkdir,
+	.rmdir = cgroup_rmdir,
+	.rename = cgroup_rename,
+};
+
+static int cgroup_create_file(struct dentry *dentry, int mode,
+				struct super_block *sb)
+{
+	static struct dentry_operations cgroup_dops = {
+		.d_iput = cgroup_diput,
+	};
+
+	struct inode *inode;
+
+	if (!dentry)
+		return -ENOENT;
+	if (dentry->d_inode)
+		return -EEXIST;
+
+	inode = cgroup_new_inode(mode, sb);
+	if (!inode)
+		return -ENOMEM;
+
+	if (S_ISDIR(mode)) {
+		inode->i_op = &cgroup_dir_inode_operations;
+		inode->i_fop = &simple_dir_operations;
+
+		/* start off with i_nlink == 2 (for "." entry) */
+		inc_nlink(inode);
+
+		/* start with the directory inode held, so that we can
+		 * populate it without racing with another mkdir */
+		mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
+	} else if (S_ISREG(mode)) {
+		inode->i_size = 0;
+		inode->i_fop = &cgroup_file_operations;
+	}
+	dentry->d_op = &cgroup_dops;
+	d_instantiate(dentry, inode);
+	dget(dentry);	/* Extra count - pin the dentry in core */
+	return 0;
+}
+
+/*
+ *	cgroup_create_dir - create a directory for an object.
+ *	cgrp:	the cgroup we create the directory for.
+ *		It must have a valid ->parent field
+ *		And we are going to fill its ->dentry field.
+ *	dentry: dentry of the new cgroup
+ *	mode:	mode to set on new directory.
+ */
+static int cgroup_create_dir(struct cgroup *cgrp, struct dentry *dentry,
+				int mode)
+{
+	struct dentry *parent;
+	int error = 0;
+
+	parent = cgrp->parent->dentry;
+	error = cgroup_create_file(dentry, S_IFDIR | mode, cgrp->root->sb);
+	if (!error) {
+		dentry->d_fsdata = cgrp;
+		inc_nlink(parent->d_inode);
+		cgrp->dentry = dentry;
+		dget(dentry);
+	}
+	dput(dentry);
+
+	return error;
+}
+
+int cgroup_add_file(struct cgroup *cgrp,
+		       struct cgroup_subsys *subsys,
+		       const struct cftype *cft)
+{
+	struct dentry *dir = cgrp->dentry;
+	struct dentry *dentry;
+	int error;
+
+	char name[MAX_CGROUP_TYPE_NAMELEN + MAX_CFTYPE_NAME + 2] = { 0 };
+	if (subsys && !test_bit(ROOT_NOPREFIX, &cgrp->root->flags)) {
+		strcpy(name, subsys->name);
+		strcat(name, ".");
+	}
+	strcat(name, cft->name);
+	BUG_ON(!mutex_is_locked(&dir->d_inode->i_mutex));
+	dentry = lookup_one_len(name, dir, strlen(name));
+	if (!IS_ERR(dentry)) {
+		error = cgroup_create_file(dentry, 0644 | S_IFREG,
+						cgrp->root->sb);
+		if (!error)
+			dentry->d_fsdata = (void *)cft;
+		dput(dentry);
+	} else
+		error = PTR_ERR(dentry);
+	return error;
+}
+
+int cgroup_add_files(struct cgroup *cgrp,
+			struct cgroup_subsys *subsys,
+			const struct cftype cft[],
+			int count)
+{
+	int i, err;
+	for (i = 0; i < count; i++) {
+		err = cgroup_add_file(cgrp, subsys, &cft[i]);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
+/* Count the number of tasks in a cgroup. */
+
+int cgroup_task_count(const struct cgroup *cgrp)
+{
+	int count = 0;
+	struct list_head *l;
+
+	read_lock(&css_set_lock);
+	l = cgrp->css_sets.next;
+	while (l != &cgrp->css_sets) {
+		struct cg_cgroup_link *link =
+			list_entry(l, struct cg_cgroup_link, cgrp_link_list);
+		count += atomic_read(&link->cg->ref.refcount);
+		l = l->next;
+	}
+	read_unlock(&css_set_lock);
+	return count;
+}
+
+/*
+ * Advance a list_head iterator.  The iterator should be positioned at
+ * the start of a css_set
+ */
+static void cgroup_advance_iter(struct cgroup *cgrp,
+					  struct cgroup_iter *it)
+{
+	struct list_head *l = it->cg_link;
+	struct cg_cgroup_link *link;
+	struct css_set *cg;
+
+	/* Advance to the next non-empty css_set */
+	do {
+		l = l->next;
+		if (l == &cgrp->css_sets) {
+			it->cg_link = NULL;
+			return;
+		}
+		link = list_entry(l, struct cg_cgroup_link, cgrp_link_list);
+		cg = link->cg;
+	} while (list_empty(&cg->tasks));
+	it->cg_link = l;
+	it->task = cg->tasks.next;
+}
+
+void cgroup_iter_start(struct cgroup *cgrp, struct cgroup_iter *it)
+{
+	/*
+	 * The first time anyone tries to iterate across a cgroup,
+	 * we need to enable the list linking each css_set to its
+	 * tasks, and fix up all existing tasks.
+	 */
+	if (!use_task_css_set_links) {
+		struct task_struct *p, *g;
+		write_lock(&css_set_lock);
+		use_task_css_set_links = 1;
+ 		do_each_thread(g, p) {
+			task_lock(p);
+			if (list_empty(&p->cg_list))
+				list_add(&p->cg_list, &p->cgroups->tasks);
+			task_unlock(p);
+ 		} while_each_thread(g, p);
+		write_unlock(&css_set_lock);
+	}
+	read_lock(&css_set_lock);
+	it->cg_link = &cgrp->css_sets;
+	cgroup_advance_iter(cgrp, it);
+}
+
+struct task_struct *cgroup_iter_next(struct cgroup *cgrp,
+					struct cgroup_iter *it)
+{
+	struct task_struct *res;
+	struct list_head *l = it->task;
+
+	/* If the iterator cg is NULL, we have no tasks */
+	if (!it->cg_link)
+		return NULL;
+	res = list_entry(l, struct task_struct, cg_list);
+	/* Advance iterator to find next entry */
+	l = l->next;
+	if (l == &res->cgroups->tasks) {
+		/* We reached the end of this task list - move on to
+		 * the next cg_cgroup_link */
+		cgroup_advance_iter(cgrp, it);
+	} else {
+		it->task = l;
+	}
+	return res;
+}
+
+void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it)
+{
+	read_unlock(&css_set_lock);
+}
+
+/*
+ * Stuff for reading the 'tasks' file.
+ *
+ * Reading this file can return large amounts of data if a cgroup has
+ * *lots* of attached tasks. So it may need several calls to read(),
+ * but we cannot guarantee that the information we produce is correct
+ * unless we produce it entirely atomically.
+ *
+ * Upon tasks file open(), a struct ctr_struct is allocated, that
+ * will have a pointer to an array (also allocated here).  The struct
+ * ctr_struct * is stored in file->private_data.  Its resources will
+ * be freed by release() when the file is closed.  The array is used
+ * to sprintf the PIDs and then used by read().
+ */
+struct ctr_struct {
+	char *buf;
+	int bufsz;
+};
+
+/*
+ * Load into 'pidarray' up to 'npids' of the tasks using cgroup
+ * 'cgrp'.  Return actual number of pids loaded.  No need to
+ * task_lock(p) when reading out p->cgroup, since we're in an RCU
+ * read section, so the css_set can't go away, and is
+ * immutable after creation.
+ */
+static int pid_array_load(pid_t *pidarray, int npids, struct cgroup *cgrp)
+{
+	int n = 0;
+	struct cgroup_iter it;
+	struct task_struct *tsk;
+	cgroup_iter_start(cgrp, &it);
+	while ((tsk = cgroup_iter_next(cgrp, &it))) {
+		if (unlikely(n == npids))
+			break;
+		pidarray[n++] = task_pid_nr(tsk);
+	}
+	cgroup_iter_end(cgrp, &it);
+	return n;
+}
+
+/**
+ * Build and fill cgroupstats so that taskstats can export it to user
+ * space.
+ *
+ * @stats: cgroupstats to fill information into
+ * @dentry: A dentry entry belonging to the cgroup for which stats have
+ * been requested.
+ */
+int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry)
+{
+	int ret = -EINVAL;
+	struct cgroup *cgrp;
+	struct cgroup_iter it;
+	struct task_struct *tsk;
+	/*
+	 * Validate dentry by checking the superblock operations
+	 */
+	if (dentry->d_sb->s_op != &cgroup_ops)
+		 goto err;
+
+	ret = 0;
+	cgrp = dentry->d_fsdata;
+	rcu_read_lock();
+
+	cgroup_iter_start(cgrp, &it);
+	while ((tsk = cgroup_iter_next(cgrp, &it))) {
+		switch (tsk->state) {
+		case TASK_RUNNING:
+			stats->nr_running++;
+			break;
+		case TASK_INTERRUPTIBLE:
+			stats->nr_sleeping++;
+			break;
+		case TASK_UNINTERRUPTIBLE:
+			stats->nr_uninterruptible++;
+			break;
+		case TASK_STOPPED:
+			stats->nr_stopped++;
+			break;
+		default:
+			if (delayacct_is_task_waiting_on_io(tsk))
+				stats->nr_io_wait++;
+			break;
+		}
+	}
+	cgroup_iter_end(cgrp, &it);
+
+	rcu_read_unlock();
+err:
+	return ret;
+}
+
+static int cmppid(const void *a, const void *b)
+{
+	return *(pid_t *)a - *(pid_t *)b;
+}
+
+/*
+ * Convert array 'a' of 'npids' pid_t's to a string of newline separated
+ * decimal pids in 'buf'.  Don't write more than 'sz' chars, but return
+ * count 'cnt' of how many chars would be written if buf were large enough.
+ */
+static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids)
+{
+	int cnt = 0;
+	int i;
+
+	for (i = 0; i < npids; i++)
+		cnt += snprintf(buf + cnt, max(sz - cnt, 0), "%d\n", a[i]);
+	return cnt;
+}
+
+/*
+ * Handle an open on 'tasks' file.  Prepare a buffer listing the
+ * process id's of tasks currently attached to the cgroup being opened.
+ *
+ * Does not require any specific cgroup mutexes, and does not take any.
+ */
+static int cgroup_tasks_open(struct inode *unused, struct file *file)
+{
+	struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent);
+	struct ctr_struct *ctr;
+	pid_t *pidarray;
+	int npids;
+	char c;
+
+	if (!(file->f_mode & FMODE_READ))
+		return 0;
+
+	ctr = kmalloc(sizeof(*ctr), GFP_KERNEL);
+	if (!ctr)
+		goto err0;
+
+	/*
+	 * If cgroup gets more users after we read count, we won't have
+	 * enough space - tough.  This race is indistinguishable to the
+	 * caller from the case that the additional cgroup users didn't
+	 * show up until sometime later on.
+	 */
+	npids = cgroup_task_count(cgrp);
+	if (npids) {
+		pidarray = kmalloc(npids * sizeof(pid_t), GFP_KERNEL);
+		if (!pidarray)
+			goto err1;
+
+		npids = pid_array_load(pidarray, npids, cgrp);
+		sort(pidarray, npids, sizeof(pid_t), cmppid, NULL);
+
+		/* Call pid_array_to_buf() twice, first just to get bufsz */
+		ctr->bufsz = pid_array_to_buf(&c, sizeof(c), pidarray, npids) + 1;
+		ctr->buf = kmalloc(ctr->bufsz, GFP_KERNEL);
+		if (!ctr->buf)
+			goto err2;
+		ctr->bufsz = pid_array_to_buf(ctr->buf, ctr->bufsz, pidarray, npids);
+
+		kfree(pidarray);
+	} else {
+		ctr->buf = 0;
+		ctr->bufsz = 0;
+	}
+	file->private_data = ctr;
+	return 0;
+
+err2:
+	kfree(pidarray);
+err1:
+	kfree(ctr);
+err0:
+	return -ENOMEM;
+}
+
+static ssize_t cgroup_tasks_read(struct cgroup *cgrp,
+				    struct cftype *cft,
+				    struct file *file, char __user *buf,
+				    size_t nbytes, loff_t *ppos)
+{
+	struct ctr_struct *ctr = file->private_data;
+
+	return simple_read_from_buffer(buf, nbytes, ppos, ctr->buf, ctr->bufsz);
+}
+
+static int cgroup_tasks_release(struct inode *unused_inode,
+					struct file *file)
+{
+	struct ctr_struct *ctr;
+
+	if (file->f_mode & FMODE_READ) {
+		ctr = file->private_data;
+		kfree(ctr->buf);
+		kfree(ctr);
+	}
+	return 0;
+}
+
+static u64 cgroup_read_notify_on_release(struct cgroup *cgrp,
+					    struct cftype *cft)
+{
+	return notify_on_release(cgrp);
+}
+
+static u64 cgroup_read_releasable(struct cgroup *cgrp, struct cftype *cft)
+{
+	return test_bit(CGRP_RELEASABLE, &cgrp->flags);
+}
+
+/*
+ * for the common functions, 'private' gives the type of file
+ */
+static struct cftype files[] = {
+	{
+		.name = "tasks",
+		.open = cgroup_tasks_open,
+		.read = cgroup_tasks_read,
+		.write = cgroup_common_file_write,
+		.release = cgroup_tasks_release,
+		.private = FILE_TASKLIST,
+	},
+
+	{
+		.name = "notify_on_release",
+		.read_uint = cgroup_read_notify_on_release,
+		.write = cgroup_common_file_write,
+		.private = FILE_NOTIFY_ON_RELEASE,
+	},
+
+	{
+		.name = "releasable",
+		.read_uint = cgroup_read_releasable,
+		.private = FILE_RELEASABLE,
+	}
+};
+
+static struct cftype cft_release_agent = {
+	.name = "release_agent",
+	.read = cgroup_common_file_read,
+	.write = cgroup_common_file_write,
+	.private = FILE_RELEASE_AGENT,
+};
+
+static int cgroup_populate_dir(struct cgroup *cgrp)
+{
+	int err;
+	struct cgroup_subsys *ss;
+
+	/* First clear out any existing files */
+	cgroup_clear_directory(cgrp->dentry);
+
+	err = cgroup_add_files(cgrp, NULL, files, ARRAY_SIZE(files));
+	if (err < 0)
+		return err;
+
+	if (cgrp == cgrp->top_cgroup) {
+		if ((err = cgroup_add_file(cgrp, NULL, &cft_release_agent)) < 0)
+			return err;
+	}
+
+	for_each_subsys(cgrp->root, ss) {
+		if (ss->populate && (err = ss->populate(ss, cgrp)) < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static void init_cgroup_css(struct cgroup_subsys_state *css,
+			       struct cgroup_subsys *ss,
+			       struct cgroup *cgrp)
+{
+	css->cgroup = cgrp;
+	atomic_set(&css->refcnt, 0);
+	css->flags = 0;
+	if (cgrp == dummytop)
+		set_bit(CSS_ROOT, &css->flags);
+	BUG_ON(cgrp->subsys[ss->subsys_id]);
+	cgrp->subsys[ss->subsys_id] = css;
+}
+
+/*
+ *	cgroup_create - create a cgroup
+ *	parent:	cgroup that will be parent of the new cgroup.
+ *	name:		name of the new cgroup. Will be strcpy'ed.
+ *	mode:		mode to set on new inode
+ *
+ *	Must be called with the mutex on the parent inode held
+ */
+
+static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
+			     int mode)
+{
+	struct cgroup *cgrp;
+	struct cgroupfs_root *root = parent->root;
+	int err = 0;
+	struct cgroup_subsys *ss;
+	struct super_block *sb = root->sb;
+
+	cgrp = kzalloc(sizeof(*cgrp), GFP_KERNEL);
+	if (!cgrp)
+		return -ENOMEM;
+
+	/* Grab a reference on the superblock so the hierarchy doesn't
+	 * get deleted on unmount if there are child cgroups.  This
+	 * can be done outside cgroup_mutex, since the sb can't
+	 * disappear while someone has an open control file on the
+	 * fs */
+	atomic_inc(&sb->s_active);
+
+	mutex_lock(&cgroup_mutex);
+
+	cgrp->flags = 0;
+	INIT_LIST_HEAD(&cgrp->sibling);
+	INIT_LIST_HEAD(&cgrp->children);
+	INIT_LIST_HEAD(&cgrp->css_sets);
+	INIT_LIST_HEAD(&cgrp->release_list);
+
+	cgrp->parent = parent;
+	cgrp->root = parent->root;
+	cgrp->top_cgroup = parent->top_cgroup;
+
+	for_each_subsys(root, ss) {
+		struct cgroup_subsys_state *css = ss->create(ss, cgrp);
+		if (IS_ERR(css)) {
+			err = PTR_ERR(css);
+			goto err_destroy;
+		}
+		init_cgroup_css(css, ss, cgrp);
+	}
+
+	list_add(&cgrp->sibling, &cgrp->parent->children);
+	root->number_of_cgroups++;
+
+	err = cgroup_create_dir(cgrp, dentry, mode);
+	if (err < 0)
+		goto err_remove;
+
+	/* The cgroup directory was pre-locked for us */
+	BUG_ON(!mutex_is_locked(&cgrp->dentry->d_inode->i_mutex));
+
+	err = cgroup_populate_dir(cgrp);
+	/* If err < 0, we have a half-filled directory - oh well ;) */
+
+	mutex_unlock(&cgroup_mutex);
+	mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
+
+	return 0;
+
+ err_remove:
+
+	list_del(&cgrp->sibling);
+	root->number_of_cgroups--;
+
+ err_destroy:
+
+	for_each_subsys(root, ss) {
+		if (cgrp->subsys[ss->subsys_id])
+			ss->destroy(ss, cgrp);
+	}
+
+	mutex_unlock(&cgroup_mutex);
+
+	/* Release the reference count that we took on the superblock */
+	deactivate_super(sb);
+
+	kfree(cgrp);
+	return err;
+}
+
+static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	struct cgroup *c_parent = dentry->d_parent->d_fsdata;
+
+	/* the vfs holds inode->i_mutex already */
+	return cgroup_create(c_parent, dentry, mode | S_IFDIR);
+}
+
+static inline int cgroup_has_css_refs(struct cgroup *cgrp)
+{
+	/* Check the reference count on each subsystem. Since we
+	 * already established that there are no tasks in the
+	 * cgroup, if the css refcount is also 0, then there should
+	 * be no outstanding references, so the subsystem is safe to
+	 * destroy. We scan across all subsystems rather than using
+	 * the per-hierarchy linked list of mounted subsystems since
+	 * we can be called via check_for_release() with no
+	 * synchronization other than RCU, and the subsystem linked
+	 * list isn't RCU-safe */
+	int i;
+	for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+		struct cgroup_subsys *ss = subsys[i];
+		struct cgroup_subsys_state *css;
+		/* Skip subsystems not in this hierarchy */
+		if (ss->root != cgrp->root)
+			continue;
+		css = cgrp->subsys[ss->subsys_id];
+		/* When called from check_for_release() it's possible
+		 * that by this point the cgroup has been removed
+		 * and the css deleted. But a false-positive doesn't
+		 * matter, since it can only happen if the cgroup
+		 * has been deleted and hence no longer needs the
+		 * release agent to be called anyway. */
+		if (css && atomic_read(&css->refcnt)) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
+{
+	struct cgroup *cgrp = dentry->d_fsdata;
+	struct dentry *d;
+	struct cgroup *parent;
+	struct cgroup_subsys *ss;
+	struct super_block *sb;
+	struct cgroupfs_root *root;
+
+	/* the vfs holds both inode->i_mutex already */
+
+	mutex_lock(&cgroup_mutex);
+	if (atomic_read(&cgrp->count) != 0) {
+		mutex_unlock(&cgroup_mutex);
+		return -EBUSY;
+	}
+	if (!list_empty(&cgrp->children)) {
+		mutex_unlock(&cgroup_mutex);
+		return -EBUSY;
+	}
+
+	parent = cgrp->parent;
+	root = cgrp->root;
+	sb = root->sb;
+
+	if (cgroup_has_css_refs(cgrp)) {
+		mutex_unlock(&cgroup_mutex);
+		return -EBUSY;
+	}
+
+	for_each_subsys(root, ss) {
+		if (cgrp->subsys[ss->subsys_id])
+			ss->destroy(ss, cgrp);
+	}
+
+	spin_lock(&release_list_lock);
+	set_bit(CGRP_REMOVED, &cgrp->flags);
+	if (!list_empty(&cgrp->release_list))
+		list_del(&cgrp->release_list);
+	spin_unlock(&release_list_lock);
+	/* delete my sibling from parent->children */
+	list_del(&cgrp->sibling);
+	spin_lock(&cgrp->dentry->d_lock);
+	d = dget(cgrp->dentry);
+	cgrp->dentry = NULL;
+	spin_unlock(&d->d_lock);
+
+	cgroup_d_remove_dir(d);
+	dput(d);
+	root->number_of_cgroups--;
+
+	set_bit(CGRP_RELEASABLE, &parent->flags);
+	check_for_release(parent);
+
+	mutex_unlock(&cgroup_mutex);
+	/* Drop the active superblock reference that we took when we
+	 * created the cgroup */
+	deactivate_super(sb);
+	return 0;
+}
+
+static void cgroup_init_subsys(struct cgroup_subsys *ss)
+{
+	struct cgroup_subsys_state *css;
+	struct list_head *l;
+	printk(KERN_ERR "Initializing cgroup subsys %s\n", ss->name);
+
+	/* Create the top cgroup state for this subsystem */
+	ss->root = &rootnode;
+	css = ss->create(ss, dummytop);
+	/* We don't handle early failures gracefully */
+	BUG_ON(IS_ERR(css));
+	init_cgroup_css(css, ss, dummytop);
+
+	/* Update all cgroup groups to contain a subsys
+	 * pointer to this state - since the subsystem is
+	 * newly registered, all tasks and hence all cgroup
+	 * groups are in the subsystem's top cgroup. */
+	write_lock(&css_set_lock);
+	l = &init_css_set.list;
+	do {
+		struct css_set *cg =
+			list_entry(l, struct css_set, list);
+		cg->subsys[ss->subsys_id] = dummytop->subsys[ss->subsys_id];
+		l = l->next;
+	} while (l != &init_css_set.list);
+	write_unlock(&css_set_lock);
+
+ 	/* If this subsystem requested that it be notified with fork
+ 	 * events, we should send it one now for every process in the
+ 	 * system */
+	if (ss->fork) {
+		struct task_struct *g, *p;
+
+		read_lock(&tasklist_lock);
+		do_each_thread(g, p) {
+			ss->fork(ss, p);
+		} while_each_thread(g, p);
+		read_unlock(&tasklist_lock);
+	}
+
+	need_forkexit_callback |= ss->fork || ss->exit;
+
+	ss->active = 1;
+}
+
+/**
+ * cgroup_init_early - initialize cgroups at system boot, and
+ * initialize any subsystems that request early init.
+ */
+int __init cgroup_init_early(void)
+{
+	int i;
+	kref_init(&init_css_set.ref);
+	kref_get(&init_css_set.ref);
+	INIT_LIST_HEAD(&init_css_set.list);
+	INIT_LIST_HEAD(&init_css_set.cg_links);
+	INIT_LIST_HEAD(&init_css_set.tasks);
+	css_set_count = 1;
+	init_cgroup_root(&rootnode);
+	list_add(&rootnode.root_list, &roots);
+	root_count = 1;
+	init_task.cgroups = &init_css_set;
+
+	init_css_set_link.cg = &init_css_set;
+	list_add(&init_css_set_link.cgrp_link_list,
+		 &rootnode.top_cgroup.css_sets);
+	list_add(&init_css_set_link.cg_link_list,
+		 &init_css_set.cg_links);
+
+	for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+		struct cgroup_subsys *ss = subsys[i];
+
+		BUG_ON(!ss->name);
+		BUG_ON(strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN);
+		BUG_ON(!ss->create);
+		BUG_ON(!ss->destroy);
+		if (ss->subsys_id != i) {
+			printk(KERN_ERR "Subsys %s id == %d\n",
+			       ss->name, ss->subsys_id);
+			BUG();
+		}
+
+		if (ss->early_init)
+			cgroup_init_subsys(ss);
+	}
+	return 0;
+}
+
+/**
+ * cgroup_init - register cgroup filesystem and /proc file, and
+ * initialize any subsystems that didn't request early init.
+ */
+int __init cgroup_init(void)
+{
+	int err;
+	int i;
+	struct proc_dir_entry *entry;
+
+	err = bdi_init(&cgroup_backing_dev_info);
+	if (err)
+		return err;
+
+	for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+		struct cgroup_subsys *ss = subsys[i];
+		if (!ss->early_init)
+			cgroup_init_subsys(ss);
+	}
+
+	err = register_filesystem(&cgroup_fs_type);
+	if (err < 0)
+		goto out;
+
+	entry = create_proc_entry("cgroups", 0, NULL);
+	if (entry)
+		entry->proc_fops = &proc_cgroupstats_operations;
+
+out:
+	if (err)
+		bdi_destroy(&cgroup_backing_dev_info);
+
+	return err;
+}
+
+/*
+ * proc_cgroup_show()
+ *  - Print task's cgroup paths into seq_file, one line for each hierarchy
+ *  - Used for /proc/<pid>/cgroup.
+ *  - No need to task_lock(tsk) on this tsk->cgroup reference, as it
+ *    doesn't really matter if tsk->cgroup changes after we read it,
+ *    and we take cgroup_mutex, keeping attach_task() from changing it
+ *    anyway.  No need to check that tsk->cgroup != NULL, thanks to
+ *    the_top_cgroup_hack in cgroup_exit(), which sets an exiting tasks
+ *    cgroup to top_cgroup.
+ */
+
+/* TODO: Use a proper seq_file iterator */
+static int proc_cgroup_show(struct seq_file *m, void *v)
+{
+	struct pid *pid;
+	struct task_struct *tsk;
+	char *buf;
+	int retval;
+	struct cgroupfs_root *root;
+
+	retval = -ENOMEM;
+	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!buf)
+		goto out;
+
+	retval = -ESRCH;
+	pid = m->private;
+	tsk = get_pid_task(pid, PIDTYPE_PID);
+	if (!tsk)
+		goto out_free;
+
+	retval = 0;
+
+	mutex_lock(&cgroup_mutex);
+
+	for_each_root(root) {
+		struct cgroup_subsys *ss;
+		struct cgroup *cgrp;
+		int subsys_id;
+		int count = 0;
+
+		/* Skip this hierarchy if it has no active subsystems */
+		if (!root->actual_subsys_bits)
+			continue;
+		for_each_subsys(root, ss)
+			seq_printf(m, "%s%s", count++ ? "," : "", ss->name);
+		seq_putc(m, ':');
+		get_first_subsys(&root->top_cgroup, NULL, &subsys_id);
+		cgrp = task_cgroup(tsk, subsys_id);
+		retval = cgroup_path(cgrp, buf, PAGE_SIZE);
+		if (retval < 0)
+			goto out_unlock;
+		seq_puts(m, buf);
+		seq_putc(m, '\n');
+	}
+
+out_unlock:
+	mutex_unlock(&cgroup_mutex);
+	put_task_struct(tsk);
+out_free:
+	kfree(buf);
+out:
+	return retval;
+}
+
+static int cgroup_open(struct inode *inode, struct file *file)
+{
+	struct pid *pid = PROC_I(inode)->pid;
+	return single_open(file, proc_cgroup_show, pid);
+}
+
+struct file_operations proc_cgroup_operations = {
+	.open		= cgroup_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+/* Display information about each subsystem and each hierarchy */
+static int proc_cgroupstats_show(struct seq_file *m, void *v)
+{
+	int i;
+	struct cgroupfs_root *root;
+
+	seq_puts(m, "#subsys_name\thierarchy\tnum_cgroups\n");
+	mutex_lock(&cgroup_mutex);
+	for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+		struct cgroup_subsys *ss = subsys[i];
+		seq_printf(m, "%s\t%lu\t%d\n",
+			   ss->name, ss->root->subsys_bits,
+			   ss->root->number_of_cgroups);
+	}
+	mutex_unlock(&cgroup_mutex);
+	return 0;
+}
+
+static int cgroupstats_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_cgroupstats_show, 0);
+}
+
+static struct file_operations proc_cgroupstats_operations = {
+	.open = cgroupstats_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+/**
+ * cgroup_fork - attach newly forked task to its parents cgroup.
+ * @tsk: pointer to task_struct of forking parent process.
+ *
+ * Description: A task inherits its parent's cgroup at fork().
+ *
+ * A pointer to the shared css_set was automatically copied in
+ * fork.c by dup_task_struct().  However, we ignore that copy, since
+ * it was not made under the protection of RCU or cgroup_mutex, so
+ * might no longer be a valid cgroup pointer.  attach_task() might
+ * have already changed current->cgroups, allowing the previously
+ * referenced cgroup group to be removed and freed.
+ *
+ * At the point that cgroup_fork() is called, 'current' is the parent
+ * task, and the passed argument 'child' points to the child task.
+ */
+void cgroup_fork(struct task_struct *child)
+{
+	task_lock(current);
+	child->cgroups = current->cgroups;
+	get_css_set(child->cgroups);
+	task_unlock(current);
+	INIT_LIST_HEAD(&child->cg_list);
+}
+
+/**
+ * cgroup_fork_callbacks - called on a new task very soon before
+ * adding it to the tasklist. No need to take any locks since no-one
+ * can be operating on this task
+ */
+void cgroup_fork_callbacks(struct task_struct *child)
+{
+	if (need_forkexit_callback) {
+		int i;
+		for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+			struct cgroup_subsys *ss = subsys[i];
+			if (ss->fork)
+				ss->fork(ss, child);
+		}
+	}
+}
+
+/**
+ * cgroup_post_fork - called on a new task after adding it to the
+ * task list. Adds the task to the list running through its css_set
+ * if necessary. Has to be after the task is visible on the task list
+ * in case we race with the first call to cgroup_iter_start() - to
+ * guarantee that the new task ends up on its list. */
+void cgroup_post_fork(struct task_struct *child)
+{
+	if (use_task_css_set_links) {
+		write_lock(&css_set_lock);
+		if (list_empty(&child->cg_list))
+			list_add(&child->cg_list, &child->cgroups->tasks);
+		write_unlock(&css_set_lock);
+	}
+}
+/**
+ * cgroup_exit - detach cgroup from exiting task
+ * @tsk: pointer to task_struct of exiting process
+ *
+ * Description: Detach cgroup from @tsk and release it.
+ *
+ * Note that cgroups marked notify_on_release force every task in
+ * them to take the global cgroup_mutex mutex when exiting.
+ * This could impact scaling on very large systems.  Be reluctant to
+ * use notify_on_release cgroups where very high task exit scaling
+ * is required on large systems.
+ *
+ * the_top_cgroup_hack:
+ *
+ *    Set the exiting tasks cgroup to the root cgroup (top_cgroup).
+ *
+ *    We call cgroup_exit() while the task is still competent to
+ *    handle notify_on_release(), then leave the task attached to the
+ *    root cgroup in each hierarchy for the remainder of its exit.
+ *
+ *    To do this properly, we would increment the reference count on
+ *    top_cgroup, and near the very end of the kernel/exit.c do_exit()
+ *    code we would add a second cgroup function call, to drop that
+ *    reference.  This would just create an unnecessary hot spot on
+ *    the top_cgroup reference count, to no avail.
+ *
+ *    Normally, holding a reference to a cgroup without bumping its
+ *    count is unsafe.   The cgroup could go away, or someone could
+ *    attach us to a different cgroup, decrementing the count on
+ *    the first cgroup that we never incremented.  But in this case,
+ *    top_cgroup isn't going away, and either task has PF_EXITING set,
+ *    which wards off any attach_task() attempts, or task is a failed
+ *    fork, never visible to attach_task.
+ *
+ */
+void cgroup_exit(struct task_struct *tsk, int run_callbacks)
+{
+	int i;
+	struct css_set *cg;
+
+	if (run_callbacks && need_forkexit_callback) {
+		for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+			struct cgroup_subsys *ss = subsys[i];
+			if (ss->exit)
+				ss->exit(ss, tsk);
+		}
+	}
+
+	/*
+	 * Unlink from the css_set task list if necessary.
+	 * Optimistically check cg_list before taking
+	 * css_set_lock
+	 */
+	if (!list_empty(&tsk->cg_list)) {
+		write_lock(&css_set_lock);
+		if (!list_empty(&tsk->cg_list))
+			list_del(&tsk->cg_list);
+		write_unlock(&css_set_lock);
+	}
+
+	/* Reassign the task to the init_css_set. */
+	task_lock(tsk);
+	cg = tsk->cgroups;
+	tsk->cgroups = &init_css_set;
+	task_unlock(tsk);
+	if (cg)
+		put_css_set_taskexit(cg);
+}
+
+/**
+ * cgroup_clone - duplicate the current cgroup in the hierarchy
+ * that the given subsystem is attached to, and move this task into
+ * the new child
+ */
+int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys)
+{
+	struct dentry *dentry;
+	int ret = 0;
+	char nodename[MAX_CGROUP_TYPE_NAMELEN];
+	struct cgroup *parent, *child;
+	struct inode *inode;
+	struct css_set *cg;
+	struct cgroupfs_root *root;
+	struct cgroup_subsys *ss;
+
+	/* We shouldn't be called by an unregistered subsystem */
+	BUG_ON(!subsys->active);
+
+	/* First figure out what hierarchy and cgroup we're dealing
+	 * with, and pin them so we can drop cgroup_mutex */
+	mutex_lock(&cgroup_mutex);
+ again:
+	root = subsys->root;
+	if (root == &rootnode) {
+		printk(KERN_INFO
+		       "Not cloning cgroup for unused subsystem %s\n",
+		       subsys->name);
+		mutex_unlock(&cgroup_mutex);
+		return 0;
+	}
+	cg = tsk->cgroups;
+	parent = task_cgroup(tsk, subsys->subsys_id);
+
+	snprintf(nodename, MAX_CGROUP_TYPE_NAMELEN, "node_%d", tsk->pid);
+
+	/* Pin the hierarchy */
+	atomic_inc(&parent->root->sb->s_active);
+
+	/* Keep the cgroup alive */
+	get_css_set(cg);
+	mutex_unlock(&cgroup_mutex);
+
+	/* Now do the VFS work to create a cgroup */
+	inode = parent->dentry->d_inode;
+
+	/* Hold the parent directory mutex across this operation to
+	 * stop anyone else deleting the new cgroup */
+	mutex_lock(&inode->i_mutex);
+	dentry = lookup_one_len(nodename, parent->dentry, strlen(nodename));
+	if (IS_ERR(dentry)) {
+		printk(KERN_INFO
+		       "Couldn't allocate dentry for %s: %ld\n", nodename,
+		       PTR_ERR(dentry));
+		ret = PTR_ERR(dentry);
+		goto out_release;
+	}
+
+	/* Create the cgroup directory, which also creates the cgroup */
+	ret = vfs_mkdir(inode, dentry, S_IFDIR | 0755);
+	child = __d_cgrp(dentry);
+	dput(dentry);
+	if (ret) {
+		printk(KERN_INFO
+		       "Failed to create cgroup %s: %d\n", nodename,
+		       ret);
+		goto out_release;
+	}
+
+	if (!child) {
+		printk(KERN_INFO
+		       "Couldn't find new cgroup %s\n", nodename);
+		ret = -ENOMEM;
+		goto out_release;
+	}
+
+	/* The cgroup now exists. Retake cgroup_mutex and check
+	 * that we're still in the same state that we thought we
+	 * were. */
+	mutex_lock(&cgroup_mutex);
+	if ((root != subsys->root) ||
+	    (parent != task_cgroup(tsk, subsys->subsys_id))) {
+		/* Aargh, we raced ... */
+		mutex_unlock(&inode->i_mutex);
+		put_css_set(cg);
+
+		deactivate_super(parent->root->sb);
+		/* The cgroup is still accessible in the VFS, but
+		 * we're not going to try to rmdir() it at this
+		 * point. */
+		printk(KERN_INFO
+		       "Race in cgroup_clone() - leaking cgroup %s\n",
+		       nodename);
+		goto again;
+	}
+
+	/* do any required auto-setup */
+	for_each_subsys(root, ss) {
+		if (ss->post_clone)
+			ss->post_clone(ss, child);
+	}
+
+	/* All seems fine. Finish by moving the task into the new cgroup */
+	ret = attach_task(child, tsk);
+	mutex_unlock(&cgroup_mutex);
+
+ out_release:
+	mutex_unlock(&inode->i_mutex);
+
+	mutex_lock(&cgroup_mutex);
+	put_css_set(cg);
+	mutex_unlock(&cgroup_mutex);
+	deactivate_super(parent->root->sb);
+	return ret;
+}
+
+/*
+ * See if "cgrp" is a descendant of the current task's cgroup in
+ * the appropriate hierarchy
+ *
+ * If we are sending in dummytop, then presumably we are creating
+ * the top cgroup in the subsystem.
+ *
+ * Called only by the ns (nsproxy) cgroup.
+ */
+int cgroup_is_descendant(const struct cgroup *cgrp)
+{
+	int ret;
+	struct cgroup *target;
+	int subsys_id;
+
+	if (cgrp == dummytop)
+		return 1;
+
+	get_first_subsys(cgrp, NULL, &subsys_id);
+	target = task_cgroup(current, subsys_id);
+	while (cgrp != target && cgrp!= cgrp->top_cgroup)
+		cgrp = cgrp->parent;
+	ret = (cgrp == target);
+	return ret;
+}
+
+static void check_for_release(struct cgroup *cgrp)
+{
+	/* All of these checks rely on RCU to keep the cgroup
+	 * structure alive */
+	if (cgroup_is_releasable(cgrp) && !atomic_read(&cgrp->count)
+	    && list_empty(&cgrp->children) && !cgroup_has_css_refs(cgrp)) {
+		/* Control Group is currently removeable. If it's not
+		 * already queued for a userspace notification, queue
+		 * it now */
+		int need_schedule_work = 0;
+		spin_lock(&release_list_lock);
+		if (!cgroup_is_removed(cgrp) &&
+		    list_empty(&cgrp->release_list)) {
+			list_add(&cgrp->release_list, &release_list);
+			need_schedule_work = 1;
+		}
+		spin_unlock(&release_list_lock);
+		if (need_schedule_work)
+			schedule_work(&release_agent_work);
+	}
+}
+
+void __css_put(struct cgroup_subsys_state *css)
+{
+	struct cgroup *cgrp = css->cgroup;
+	rcu_read_lock();
+	if (atomic_dec_and_test(&css->refcnt) && notify_on_release(cgrp)) {
+		set_bit(CGRP_RELEASABLE, &cgrp->flags);
+		check_for_release(cgrp);
+	}
+	rcu_read_unlock();
+}
+
+/*
+ * Notify userspace when a cgroup is released, by running the
+ * configured release agent with the name of the cgroup (path
+ * relative to the root of cgroup file system) as the argument.
+ *
+ * Most likely, this user command will try to rmdir this cgroup.
+ *
+ * This races with the possibility that some other task will be
+ * attached to this cgroup before it is removed, or that some other
+ * user task will 'mkdir' a child cgroup of this cgroup.  That's ok.
+ * The presumed 'rmdir' will fail quietly if this cgroup is no longer
+ * unused, and this cgroup will be reprieved from its death sentence,
+ * to continue to serve a useful existence.  Next time it's released,
+ * we will get notified again, if it still has 'notify_on_release' set.
+ *
+ * The final arg to call_usermodehelper() is UMH_WAIT_EXEC, which
+ * means only wait until the task is successfully execve()'d.  The
+ * separate release agent task is forked by call_usermodehelper(),
+ * then control in this thread returns here, without waiting for the
+ * release agent task.  We don't bother to wait because the caller of
+ * this routine has no use for the exit status of the release agent
+ * task, so no sense holding our caller up for that.
+ *
+ */
+
+static void cgroup_release_agent(struct work_struct *work)
+{
+	BUG_ON(work != &release_agent_work);
+	mutex_lock(&cgroup_mutex);
+	spin_lock(&release_list_lock);
+	while (!list_empty(&release_list)) {
+		char *argv[3], *envp[3];
+		int i;
+		char *pathbuf;
+		struct cgroup *cgrp = list_entry(release_list.next,
+						    struct cgroup,
+						    release_list);
+		list_del_init(&cgrp->release_list);
+		spin_unlock(&release_list_lock);
+		pathbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+		if (!pathbuf) {
+			spin_lock(&release_list_lock);
+			continue;
+		}
+
+		if (cgroup_path(cgrp, pathbuf, PAGE_SIZE) < 0) {
+			kfree(pathbuf);
+			spin_lock(&release_list_lock);
+			continue;
+		}
+
+		i = 0;
+		argv[i++] = cgrp->root->release_agent_path;
+		argv[i++] = (char *)pathbuf;
+		argv[i] = NULL;
+
+		i = 0;
+		/* minimal command environment */
+		envp[i++] = "HOME=/";
+		envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+		envp[i] = NULL;
+
+		/* Drop the lock while we invoke the usermode helper,
+		 * since the exec could involve hitting disk and hence
+		 * be a slow process */
+		mutex_unlock(&cgroup_mutex);
+		call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
+		kfree(pathbuf);
+		mutex_lock(&cgroup_mutex);
+		spin_lock(&release_list_lock);
+	}
+	spin_unlock(&release_list_lock);
+	mutex_unlock(&cgroup_mutex);
+}
diff --git a/kernel/cgroup_debug.c b/kernel/cgroup_debug.c
new file mode 100644
index 0000000..37301e8
--- /dev/null
+++ b/kernel/cgroup_debug.c
@@ -0,0 +1,97 @@
+/*
+ * kernel/ccontainer_debug.c - Example cgroup subsystem that
+ * exposes debug info
+ *
+ * Copyright (C) Google Inc, 2007
+ *
+ * Developed by Paul Menage (menage@google.com)
+ *
+ */
+
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/rcupdate.h>
+
+#include <asm/atomic.h>
+
+static struct cgroup_subsys_state *debug_create(struct cgroup_subsys *ss,
+						   struct cgroup *cont)
+{
+	struct cgroup_subsys_state *css = kzalloc(sizeof(*css), GFP_KERNEL);
+
+	if (!css)
+		return ERR_PTR(-ENOMEM);
+
+	return css;
+}
+
+static void debug_destroy(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+	kfree(cont->subsys[debug_subsys_id]);
+}
+
+static u64 cgroup_refcount_read(struct cgroup *cont, struct cftype *cft)
+{
+	return atomic_read(&cont->count);
+}
+
+static u64 taskcount_read(struct cgroup *cont, struct cftype *cft)
+{
+	u64 count;
+
+	cgroup_lock();
+	count = cgroup_task_count(cont);
+	cgroup_unlock();
+	return count;
+}
+
+static u64 current_css_set_read(struct cgroup *cont, struct cftype *cft)
+{
+	return (u64)(long)current->cgroups;
+}
+
+static u64 current_css_set_refcount_read(struct cgroup *cont,
+					   struct cftype *cft)
+{
+	u64 count;
+
+	rcu_read_lock();
+	count = atomic_read(&current->cgroups->ref.refcount);
+	rcu_read_unlock();
+	return count;
+}
+
+static struct cftype files[] =  {
+	{
+		.name = "cgroup_refcount",
+		.read_uint = cgroup_refcount_read,
+	},
+	{
+		.name = "taskcount",
+		.read_uint = taskcount_read,
+	},
+
+	{
+		.name = "current_css_set",
+		.read_uint = current_css_set_read,
+	},
+
+	{
+		.name = "current_css_set_refcount",
+		.read_uint = current_css_set_refcount_read,
+	},
+};
+
+static int debug_populate(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+	return cgroup_add_files(cont, ss, files, ARRAY_SIZE(files));
+}
+
+struct cgroup_subsys debug_subsys = {
+	.name = "debug",
+	.create = debug_create,
+	.destroy = debug_destroy,
+	.populate = debug_populate,
+	.subsys_id = debug_subsys_id,
+};
diff --git a/kernel/compat.c b/kernel/compat.c
index 3bae374..42a1ed4 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -40,62 +40,27 @@
 			__put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
 }
 
-static long compat_nanosleep_restart(struct restart_block *restart)
-{
-	unsigned long expire = restart->arg0, now = jiffies;
-	struct compat_timespec __user *rmtp;
-
-	/* Did it expire while we handled signals? */
-	if (!time_after(expire, now))
-		return 0;
-
-	expire = schedule_timeout_interruptible(expire - now);
-	if (expire == 0)
-		return 0;
-
-	rmtp = (struct compat_timespec __user *)restart->arg1;
-	if (rmtp) {
-		struct compat_timespec ct;
-		struct timespec t;
-
-		jiffies_to_timespec(expire, &t);
-		ct.tv_sec = t.tv_sec;
-		ct.tv_nsec = t.tv_nsec;
-		if (copy_to_user(rmtp, &ct, sizeof(ct)))
-			return -EFAULT;
-	}
-	/* The 'restart' block is already filled in */
-	return -ERESTART_RESTARTBLOCK;
-}
-
 asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
-		struct compat_timespec __user *rmtp)
+				     struct compat_timespec __user *rmtp)
 {
-	struct timespec t;
-	struct restart_block *restart;
-	unsigned long expire;
+	struct timespec tu, rmt;
+	long ret;
 
-	if (get_compat_timespec(&t, rqtp))
+	if (get_compat_timespec(&tu, rqtp))
 		return -EFAULT;
 
-	if ((t.tv_nsec >= 1000000000L) || (t.tv_nsec < 0) || (t.tv_sec < 0))
+	if (!timespec_valid(&tu))
 		return -EINVAL;
 
-	expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
-	expire = schedule_timeout_interruptible(expire);
-	if (expire == 0)
-		return 0;
+	ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL,
+				CLOCK_MONOTONIC);
 
-	if (rmtp) {
-		jiffies_to_timespec(expire, &t);
-		if (put_compat_timespec(&t, rmtp))
+	if (ret && rmtp) {
+		if (put_compat_timespec(&rmt, rmtp))
 			return -EFAULT;
 	}
-	restart = &current_thread_info()->restart_block;
-	restart->fn = compat_nanosleep_restart;
-	restart->arg0 = jiffies + expire;
-	restart->arg1 = (unsigned long) rmtp;
-	return -ERESTART_RESTARTBLOCK;
+
+	return ret;
 }
 
 static inline long get_compat_itimerval(struct itimerval *o,
@@ -247,8 +212,8 @@
 	int ret;
 	mm_segment_t old_fs = get_fs ();
 
-	if (resource >= RLIM_NLIMITS) 
-		return -EINVAL;	
+	if (resource >= RLIM_NLIMITS)
+		return -EINVAL;
 
 	if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) ||
 	    __get_user(r.rlim_cur, &rlim->rlim_cur) ||
@@ -477,21 +442,21 @@
 
 int get_compat_itimerspec(struct itimerspec *dst,
 			  const struct compat_itimerspec __user *src)
-{ 
+{
 	if (get_compat_timespec(&dst->it_interval, &src->it_interval) ||
 	    get_compat_timespec(&dst->it_value, &src->it_value))
 		return -EFAULT;
 	return 0;
-} 
+}
 
 int put_compat_itimerspec(struct compat_itimerspec __user *dst,
 			  const struct itimerspec *src)
-{ 
+{
 	if (put_compat_timespec(&src->it_interval, &dst->it_interval) ||
 	    put_compat_timespec(&src->it_value, &dst->it_value))
 		return -EFAULT;
 	return 0;
-} 
+}
 
 long compat_sys_timer_create(clockid_t which_clock,
 			struct compat_sigevent __user *timer_event_spec,
@@ -512,9 +477,9 @@
 }
 
 long compat_sys_timer_settime(timer_t timer_id, int flags,
-			  struct compat_itimerspec __user *new, 
+			  struct compat_itimerspec __user *new,
 			  struct compat_itimerspec __user *old)
-{ 
+{
 	long err;
 	mm_segment_t oldfs;
 	struct itimerspec newts, oldts;
@@ -522,58 +487,58 @@
 	if (!new)
 		return -EINVAL;
 	if (get_compat_itimerspec(&newts, new))
-		return -EFAULT;	
+		return -EFAULT;
 	oldfs = get_fs();
 	set_fs(KERNEL_DS);
 	err = sys_timer_settime(timer_id, flags,
 				(struct itimerspec __user *) &newts,
 				(struct itimerspec __user *) &oldts);
-	set_fs(oldfs); 
+	set_fs(oldfs);
 	if (!err && old && put_compat_itimerspec(old, &oldts))
 		return -EFAULT;
 	return err;
-} 
+}
 
 long compat_sys_timer_gettime(timer_t timer_id,
 		struct compat_itimerspec __user *setting)
-{ 
+{
 	long err;
 	mm_segment_t oldfs;
-	struct itimerspec ts; 
+	struct itimerspec ts;
 
 	oldfs = get_fs();
 	set_fs(KERNEL_DS);
 	err = sys_timer_gettime(timer_id,
-				(struct itimerspec __user *) &ts); 
-	set_fs(oldfs); 
+				(struct itimerspec __user *) &ts);
+	set_fs(oldfs);
 	if (!err && put_compat_itimerspec(setting, &ts))
 		return -EFAULT;
 	return err;
-} 
+}
 
 long compat_sys_clock_settime(clockid_t which_clock,
 		struct compat_timespec __user *tp)
 {
 	long err;
 	mm_segment_t oldfs;
-	struct timespec ts; 
+	struct timespec ts;
 
 	if (get_compat_timespec(&ts, tp))
-		return -EFAULT; 
+		return -EFAULT;
 	oldfs = get_fs();
-	set_fs(KERNEL_DS);	
+	set_fs(KERNEL_DS);
 	err = sys_clock_settime(which_clock,
 				(struct timespec __user *) &ts);
 	set_fs(oldfs);
 	return err;
-} 
+}
 
 long compat_sys_clock_gettime(clockid_t which_clock,
 		struct compat_timespec __user *tp)
 {
 	long err;
 	mm_segment_t oldfs;
-	struct timespec ts; 
+	struct timespec ts;
 
 	oldfs = get_fs();
 	set_fs(KERNEL_DS);
@@ -581,16 +546,16 @@
 				(struct timespec __user *) &ts);
 	set_fs(oldfs);
 	if (!err && put_compat_timespec(&ts, tp))
-		return -EFAULT; 
+		return -EFAULT;
 	return err;
-} 
+}
 
 long compat_sys_clock_getres(clockid_t which_clock,
 		struct compat_timespec __user *tp)
 {
 	long err;
 	mm_segment_t oldfs;
-	struct timespec ts; 
+	struct timespec ts;
 
 	oldfs = get_fs();
 	set_fs(KERNEL_DS);
@@ -598,9 +563,9 @@
 			       (struct timespec __user *) &ts);
 	set_fs(oldfs);
 	if (!err && tp && put_compat_timespec(&ts, tp))
-		return -EFAULT; 
+		return -EFAULT;
 	return err;
-} 
+}
 
 static long compat_clock_nanosleep_restart(struct restart_block *restart)
 {
@@ -632,10 +597,10 @@
 {
 	long err;
 	mm_segment_t oldfs;
-	struct timespec in, out; 
+	struct timespec in, out;
 	struct restart_block *restart;
 
-	if (get_compat_timespec(&in, rqtp)) 
+	if (get_compat_timespec(&in, rqtp))
 		return -EFAULT;
 
 	oldfs = get_fs();
@@ -654,8 +619,8 @@
 		restart->fn = compat_clock_nanosleep_restart;
 		restart->arg1 = (unsigned long) rmtp;
 	}
-	return err;	
-} 
+	return err;
+}
 
 /*
  * We currently only need the following fields from the sigevent
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 38033db..6b3a0c1 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -98,7 +98,8 @@
 		     !cputime_eq(p->stime, cputime_zero)))
 			printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d\
 				(state = %ld, flags = %x) \n",
-				 p->comm, p->pid, cpu, p->state, p->flags);
+				 p->comm, task_pid_nr(p), cpu,
+				 p->state, p->flags);
 	}
 	write_unlock_irq(&tasklist_lock);
 }
@@ -150,6 +151,7 @@
 	err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
 					hcpu, -1, &nr_calls);
 	if (err == NOTIFY_BAD) {
+		nr_calls--;
 		__raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod,
 					  hcpu, nr_calls, NULL);
 		printk("%s: attempt to take down CPU %u failed\n",
@@ -233,6 +235,7 @@
 	ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu,
 							-1, &nr_calls);
 	if (ret == NOTIFY_BAD) {
+		nr_calls--;
 		printk("%s: attempt to bring up CPU %u failed\n",
 				__FUNCTION__, cpu);
 		ret = -EINVAL;
@@ -262,6 +265,15 @@
 int __cpuinit cpu_up(unsigned int cpu)
 {
 	int err = 0;
+	if (!cpu_isset(cpu, cpu_possible_map)) {
+		printk(KERN_ERR "can't online cpu %d because it is not "
+			"configured as may-hotadd at boot time\n", cpu);
+#if defined(CONFIG_IA64) || defined(CONFIG_X86_64) || defined(CONFIG_S390)
+		printk(KERN_ERR "please check additional_cpus= boot "
+				"parameter\n");
+#endif
+		return -EINVAL;
+	}
 
 	mutex_lock(&cpu_add_remove_lock);
 	if (cpu_hotplug_disabled)
diff --git a/kernel/cpu_acct.c b/kernel/cpu_acct.c
new file mode 100644
index 0000000..731e47e
--- /dev/null
+++ b/kernel/cpu_acct.c
@@ -0,0 +1,186 @@
+/*
+ * kernel/cpu_acct.c - CPU accounting cgroup subsystem
+ *
+ * Copyright (C) Google Inc, 2006
+ *
+ * Developed by Paul Menage (menage@google.com) and Balbir Singh
+ * (balbir@in.ibm.com)
+ *
+ */
+
+/*
+ * Example cgroup subsystem for reporting total CPU usage of tasks in a
+ * cgroup, along with percentage load over a time interval
+ */
+
+#include <linux/module.h>
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+#include <linux/rcupdate.h>
+
+#include <asm/div64.h>
+
+struct cpuacct {
+	struct cgroup_subsys_state css;
+	spinlock_t lock;
+	/* total time used by this class */
+	cputime64_t time;
+
+	/* time when next load calculation occurs */
+	u64 next_interval_check;
+
+	/* time used in current period */
+	cputime64_t current_interval_time;
+
+	/* time used in last period */
+	cputime64_t last_interval_time;
+};
+
+struct cgroup_subsys cpuacct_subsys;
+
+static inline struct cpuacct *cgroup_ca(struct cgroup *cont)
+{
+	return container_of(cgroup_subsys_state(cont, cpuacct_subsys_id),
+			    struct cpuacct, css);
+}
+
+static inline struct cpuacct *task_ca(struct task_struct *task)
+{
+	return container_of(task_subsys_state(task, cpuacct_subsys_id),
+			    struct cpuacct, css);
+}
+
+#define INTERVAL (HZ * 10)
+
+static inline u64 next_interval_boundary(u64 now)
+{
+	/* calculate the next interval boundary beyond the
+	 * current time */
+	do_div(now, INTERVAL);
+	return (now + 1) * INTERVAL;
+}
+
+static struct cgroup_subsys_state *cpuacct_create(
+	struct cgroup_subsys *ss, struct cgroup *cont)
+{
+	struct cpuacct *ca = kzalloc(sizeof(*ca), GFP_KERNEL);
+
+	if (!ca)
+		return ERR_PTR(-ENOMEM);
+	spin_lock_init(&ca->lock);
+	ca->next_interval_check = next_interval_boundary(get_jiffies_64());
+	return &ca->css;
+}
+
+static void cpuacct_destroy(struct cgroup_subsys *ss,
+			    struct cgroup *cont)
+{
+	kfree(cgroup_ca(cont));
+}
+
+/* Lazily update the load calculation if necessary. Called with ca locked */
+static void cpuusage_update(struct cpuacct *ca)
+{
+	u64 now = get_jiffies_64();
+
+	/* If we're not due for an update, return */
+	if (ca->next_interval_check > now)
+		return;
+
+	if (ca->next_interval_check <= (now - INTERVAL)) {
+		/* If it's been more than an interval since the last
+		 * check, then catch up - the last interval must have
+		 * been zero load */
+		ca->last_interval_time = 0;
+		ca->next_interval_check = next_interval_boundary(now);
+	} else {
+		/* If a steal takes the last interval time negative,
+		 * then we just ignore it */
+		if ((s64)ca->current_interval_time > 0)
+			ca->last_interval_time = ca->current_interval_time;
+		else
+			ca->last_interval_time = 0;
+		ca->next_interval_check += INTERVAL;
+	}
+	ca->current_interval_time = 0;
+}
+
+static u64 cpuusage_read(struct cgroup *cont, struct cftype *cft)
+{
+	struct cpuacct *ca = cgroup_ca(cont);
+	u64 time;
+
+	spin_lock_irq(&ca->lock);
+	cpuusage_update(ca);
+	time = cputime64_to_jiffies64(ca->time);
+	spin_unlock_irq(&ca->lock);
+
+	/* Convert 64-bit jiffies to seconds */
+	time *= 1000;
+	do_div(time, HZ);
+	return time;
+}
+
+static u64 load_read(struct cgroup *cont, struct cftype *cft)
+{
+	struct cpuacct *ca = cgroup_ca(cont);
+	u64 time;
+
+	/* Find the time used in the previous interval */
+	spin_lock_irq(&ca->lock);
+	cpuusage_update(ca);
+	time = cputime64_to_jiffies64(ca->last_interval_time);
+	spin_unlock_irq(&ca->lock);
+
+	/* Convert time to a percentage, to give the load in the
+	 * previous period */
+	time *= 100;
+	do_div(time, INTERVAL);
+
+	return time;
+}
+
+static struct cftype files[] = {
+	{
+		.name = "usage",
+		.read_uint = cpuusage_read,
+	},
+	{
+		.name = "load",
+		.read_uint = load_read,
+	}
+};
+
+static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+	return cgroup_add_files(cont, ss, files, ARRAY_SIZE(files));
+}
+
+void cpuacct_charge(struct task_struct *task, cputime_t cputime)
+{
+
+	struct cpuacct *ca;
+	unsigned long flags;
+
+	if (!cpuacct_subsys.active)
+		return;
+	rcu_read_lock();
+	ca = task_ca(task);
+	if (ca) {
+		spin_lock_irqsave(&ca->lock, flags);
+		cpuusage_update(ca);
+		ca->time = cputime64_add(ca->time, cputime);
+		ca->current_interval_time =
+			cputime64_add(ca->current_interval_time, cputime);
+		spin_unlock_irqrestore(&ca->lock, flags);
+	}
+	rcu_read_unlock();
+}
+
+struct cgroup_subsys cpuacct_subsys = {
+	.name = "cpuacct",
+	.create = cpuacct_create,
+	.destroy = cpuacct_destroy,
+	.populate = cpuacct_populate,
+	.subsys_id = cpuacct_subsys_id,
+};
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 2eb2e50..50f5dc4 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -4,7 +4,8 @@
  *  Processor and Memory placement constraints for sets of tasks.
  *
  *  Copyright (C) 2003 BULL SA.
- *  Copyright (C) 2004-2006 Silicon Graphics, Inc.
+ *  Copyright (C) 2004-2007 Silicon Graphics, Inc.
+ *  Copyright (C) 2006 Google, Inc
  *
  *  Portions derived from Patrick Mochel's sysfs code.
  *  sysfs is Copyright (c) 2001-3 Patrick Mochel
@@ -12,6 +13,7 @@
  *  2003-10-10 Written by Simon Derr.
  *  2003-10-22 Updates by Stephen Hemminger.
  *  2004 May-July Rework by Paul Jackson.
+ *  2006 Rework by Paul Menage to use generic cgroups
  *
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License.  See the file COPYING in the main directory of the Linux
@@ -36,6 +38,7 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/pagemap.h>
+#include <linux/prio_heap.h>
 #include <linux/proc_fs.h>
 #include <linux/rcupdate.h>
 #include <linux/sched.h>
@@ -52,8 +55,7 @@
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
 #include <linux/mutex.h>
-
-#define CPUSET_SUPER_MAGIC		0x27e0eb
+#include <linux/kfifo.h>
 
 /*
  * Tracks how many cpusets are currently defined in system.
@@ -62,6 +64,10 @@
  */
 int number_of_cpusets __read_mostly;
 
+/* Retrieve the cpuset from a cgroup */
+struct cgroup_subsys cpuset_subsys;
+struct cpuset;
+
 /* See "Frequency meter" comments, below. */
 
 struct fmeter {
@@ -72,24 +78,13 @@
 };
 
 struct cpuset {
+	struct cgroup_subsys_state css;
+
 	unsigned long flags;		/* "unsigned long" so bitops work */
 	cpumask_t cpus_allowed;		/* CPUs allowed to tasks in cpuset */
 	nodemask_t mems_allowed;	/* Memory Nodes allowed to tasks */
 
-	/*
-	 * Count is atomic so can incr (fork) or decr (exit) without a lock.
-	 */
-	atomic_t count;			/* count tasks using this cpuset */
-
-	/*
-	 * We link our 'sibling' struct into our parents 'children'.
-	 * Our children link their 'sibling' into our 'children'.
-	 */
-	struct list_head sibling;	/* my parents children */
-	struct list_head children;	/* my children */
-
 	struct cpuset *parent;		/* my parent */
-	struct dentry *dentry;		/* cpuset fs entry */
 
 	/*
 	 * Copy of global cpuset_mems_generation as of the most
@@ -98,15 +93,32 @@
 	int mems_generation;
 
 	struct fmeter fmeter;		/* memory_pressure filter */
+
+	/* partition number for rebuild_sched_domains() */
+	int pn;
 };
 
+/* Retrieve the cpuset for a cgroup */
+static inline struct cpuset *cgroup_cs(struct cgroup *cont)
+{
+	return container_of(cgroup_subsys_state(cont, cpuset_subsys_id),
+			    struct cpuset, css);
+}
+
+/* Retrieve the cpuset for a task */
+static inline struct cpuset *task_cs(struct task_struct *task)
+{
+	return container_of(task_subsys_state(task, cpuset_subsys_id),
+			    struct cpuset, css);
+}
+
+
 /* bits in struct cpuset flags field */
 typedef enum {
 	CS_CPU_EXCLUSIVE,
 	CS_MEM_EXCLUSIVE,
 	CS_MEMORY_MIGRATE,
-	CS_REMOVED,
-	CS_NOTIFY_ON_RELEASE,
+	CS_SCHED_LOAD_BALANCE,
 	CS_SPREAD_PAGE,
 	CS_SPREAD_SLAB,
 } cpuset_flagbits_t;
@@ -122,14 +134,9 @@
 	return test_bit(CS_MEM_EXCLUSIVE, &cs->flags);
 }
 
-static inline int is_removed(const struct cpuset *cs)
+static inline int is_sched_load_balance(const struct cpuset *cs)
 {
-	return test_bit(CS_REMOVED, &cs->flags);
-}
-
-static inline int notify_on_release(const struct cpuset *cs)
-{
-	return test_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
+	return test_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
 }
 
 static inline int is_memory_migrate(const struct cpuset *cs)
@@ -172,14 +179,8 @@
 	.flags = ((1 << CS_CPU_EXCLUSIVE) | (1 << CS_MEM_EXCLUSIVE)),
 	.cpus_allowed = CPU_MASK_ALL,
 	.mems_allowed = NODE_MASK_ALL,
-	.count = ATOMIC_INIT(0),
-	.sibling = LIST_HEAD_INIT(top_cpuset.sibling),
-	.children = LIST_HEAD_INIT(top_cpuset.children),
 };
 
-static struct vfsmount *cpuset_mount;
-static struct super_block *cpuset_sb;
-
 /*
  * We have two global cpuset mutexes below.  They can nest.
  * It is ok to first take manage_mutex, then nest callback_mutex.  We also
@@ -263,297 +264,33 @@
  * the routine cpuset_update_task_memory_state().
  */
 
-static DEFINE_MUTEX(manage_mutex);
 static DEFINE_MUTEX(callback_mutex);
 
-/*
- * A couple of forward declarations required, due to cyclic reference loop:
- *  cpuset_mkdir -> cpuset_create -> cpuset_populate_dir -> cpuset_add_file
- *  -> cpuset_create_file -> cpuset_dir_inode_operations -> cpuset_mkdir.
- */
-
-static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode);
-static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry);
-
-static struct backing_dev_info cpuset_backing_dev_info = {
-	.ra_pages = 0,		/* No readahead */
-	.capabilities	= BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
-};
-
-static struct inode *cpuset_new_inode(mode_t mode)
-{
-	struct inode *inode = new_inode(cpuset_sb);
-
-	if (inode) {
-		inode->i_mode = mode;
-		inode->i_uid = current->fsuid;
-		inode->i_gid = current->fsgid;
-		inode->i_blocks = 0;
-		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-		inode->i_mapping->backing_dev_info = &cpuset_backing_dev_info;
-	}
-	return inode;
-}
-
-static void cpuset_diput(struct dentry *dentry, struct inode *inode)
-{
-	/* is dentry a directory ? if so, kfree() associated cpuset */
-	if (S_ISDIR(inode->i_mode)) {
-		struct cpuset *cs = dentry->d_fsdata;
-		BUG_ON(!(is_removed(cs)));
-		kfree(cs);
-	}
-	iput(inode);
-}
-
-static struct dentry_operations cpuset_dops = {
-	.d_iput = cpuset_diput,
-};
-
-static struct dentry *cpuset_get_dentry(struct dentry *parent, const char *name)
-{
-	struct dentry *d = lookup_one_len(name, parent, strlen(name));
-	if (!IS_ERR(d))
-		d->d_op = &cpuset_dops;
-	return d;
-}
-
-static void remove_dir(struct dentry *d)
-{
-	struct dentry *parent = dget(d->d_parent);
-
-	d_delete(d);
-	simple_rmdir(parent->d_inode, d);
-	dput(parent);
-}
-
-/*
- * NOTE : the dentry must have been dget()'ed
- */
-static void cpuset_d_remove_dir(struct dentry *dentry)
-{
-	struct list_head *node;
-
-	spin_lock(&dcache_lock);
-	node = dentry->d_subdirs.next;
-	while (node != &dentry->d_subdirs) {
-		struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
-		list_del_init(node);
-		if (d->d_inode) {
-			d = dget_locked(d);
-			spin_unlock(&dcache_lock);
-			d_delete(d);
-			simple_unlink(dentry->d_inode, d);
-			dput(d);
-			spin_lock(&dcache_lock);
-		}
-		node = dentry->d_subdirs.next;
-	}
-	list_del_init(&dentry->d_u.d_child);
-	spin_unlock(&dcache_lock);
-	remove_dir(dentry);
-}
-
-static struct super_operations cpuset_ops = {
-	.statfs = simple_statfs,
-	.drop_inode = generic_delete_inode,
-};
-
-static int cpuset_fill_super(struct super_block *sb, void *unused_data,
-							int unused_silent)
-{
-	struct inode *inode;
-	struct dentry *root;
-
-	sb->s_blocksize = PAGE_CACHE_SIZE;
-	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-	sb->s_magic = CPUSET_SUPER_MAGIC;
-	sb->s_op = &cpuset_ops;
-	cpuset_sb = sb;
-
-	inode = cpuset_new_inode(S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR);
-	if (inode) {
-		inode->i_op = &simple_dir_inode_operations;
-		inode->i_fop = &simple_dir_operations;
-		/* directories start off with i_nlink == 2 (for "." entry) */
-		inc_nlink(inode);
-	} else {
-		return -ENOMEM;
-	}
-
-	root = d_alloc_root(inode);
-	if (!root) {
-		iput(inode);
-		return -ENOMEM;
-	}
-	sb->s_root = root;
-	return 0;
-}
-
+/* This is ugly, but preserves the userspace API for existing cpuset
+ * users. If someone tries to mount the "cpuset" filesystem, we
+ * silently switch it to mount "cgroup" instead */
 static int cpuset_get_sb(struct file_system_type *fs_type,
 			 int flags, const char *unused_dev_name,
 			 void *data, struct vfsmount *mnt)
 {
-	return get_sb_single(fs_type, flags, data, cpuset_fill_super, mnt);
+	struct file_system_type *cgroup_fs = get_fs_type("cgroup");
+	int ret = -ENODEV;
+	if (cgroup_fs) {
+		char mountopts[] =
+			"cpuset,noprefix,"
+			"release_agent=/sbin/cpuset_release_agent";
+		ret = cgroup_fs->get_sb(cgroup_fs, flags,
+					   unused_dev_name, mountopts, mnt);
+		put_filesystem(cgroup_fs);
+	}
+	return ret;
 }
 
 static struct file_system_type cpuset_fs_type = {
 	.name = "cpuset",
 	.get_sb = cpuset_get_sb,
-	.kill_sb = kill_litter_super,
 };
 
-/* struct cftype:
- *
- * The files in the cpuset filesystem mostly have a very simple read/write
- * handling, some common function will take care of it. Nevertheless some cases
- * (read tasks) are special and therefore I define this structure for every
- * kind of file.
- *
- *
- * When reading/writing to a file:
- *	- the cpuset to use in file->f_path.dentry->d_parent->d_fsdata
- *	- the 'cftype' of the file is file->f_path.dentry->d_fsdata
- */
-
-struct cftype {
-	char *name;
-	int private;
-	int (*open) (struct inode *inode, struct file *file);
-	ssize_t (*read) (struct file *file, char __user *buf, size_t nbytes,
-							loff_t *ppos);
-	int (*write) (struct file *file, const char __user *buf, size_t nbytes,
-							loff_t *ppos);
-	int (*release) (struct inode *inode, struct file *file);
-};
-
-static inline struct cpuset *__d_cs(struct dentry *dentry)
-{
-	return dentry->d_fsdata;
-}
-
-static inline struct cftype *__d_cft(struct dentry *dentry)
-{
-	return dentry->d_fsdata;
-}
-
-/*
- * Call with manage_mutex held.  Writes path of cpuset into buf.
- * Returns 0 on success, -errno on error.
- */
-
-static int cpuset_path(const struct cpuset *cs, char *buf, int buflen)
-{
-	char *start;
-
-	start = buf + buflen;
-
-	*--start = '\0';
-	for (;;) {
-		int len = cs->dentry->d_name.len;
-		if ((start -= len) < buf)
-			return -ENAMETOOLONG;
-		memcpy(start, cs->dentry->d_name.name, len);
-		cs = cs->parent;
-		if (!cs)
-			break;
-		if (!cs->parent)
-			continue;
-		if (--start < buf)
-			return -ENAMETOOLONG;
-		*start = '/';
-	}
-	memmove(buf, start, buf + buflen - start);
-	return 0;
-}
-
-/*
- * Notify userspace when a cpuset is released, by running
- * /sbin/cpuset_release_agent with the name of the cpuset (path
- * relative to the root of cpuset file system) as the argument.
- *
- * Most likely, this user command will try to rmdir this cpuset.
- *
- * This races with the possibility that some other task will be
- * attached to this cpuset before it is removed, or that some other
- * user task will 'mkdir' a child cpuset of this cpuset.  That's ok.
- * The presumed 'rmdir' will fail quietly if this cpuset is no longer
- * unused, and this cpuset will be reprieved from its death sentence,
- * to continue to serve a useful existence.  Next time it's released,
- * we will get notified again, if it still has 'notify_on_release' set.
- *
- * The final arg to call_usermodehelper() is 0, which means don't
- * wait.  The separate /sbin/cpuset_release_agent task is forked by
- * call_usermodehelper(), then control in this thread returns here,
- * without waiting for the release agent task.  We don't bother to
- * wait because the caller of this routine has no use for the exit
- * status of the /sbin/cpuset_release_agent task, so no sense holding
- * our caller up for that.
- *
- * When we had only one cpuset mutex, we had to call this
- * without holding it, to avoid deadlock when call_usermodehelper()
- * allocated memory.  With two locks, we could now call this while
- * holding manage_mutex, but we still don't, so as to minimize
- * the time manage_mutex is held.
- */
-
-static void cpuset_release_agent(const char *pathbuf)
-{
-	char *argv[3], *envp[3];
-	int i;
-
-	if (!pathbuf)
-		return;
-
-	i = 0;
-	argv[i++] = "/sbin/cpuset_release_agent";
-	argv[i++] = (char *)pathbuf;
-	argv[i] = NULL;
-
-	i = 0;
-	/* minimal command environment */
-	envp[i++] = "HOME=/";
-	envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-	envp[i] = NULL;
-
-	call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
-	kfree(pathbuf);
-}
-
-/*
- * Either cs->count of using tasks transitioned to zero, or the
- * cs->children list of child cpusets just became empty.  If this
- * cs is notify_on_release() and now both the user count is zero and
- * the list of children is empty, prepare cpuset path in a kmalloc'd
- * buffer, to be returned via ppathbuf, so that the caller can invoke
- * cpuset_release_agent() with it later on, once manage_mutex is dropped.
- * Call here with manage_mutex held.
- *
- * This check_for_release() routine is responsible for kmalloc'ing
- * pathbuf.  The above cpuset_release_agent() is responsible for
- * kfree'ing pathbuf.  The caller of these routines is responsible
- * for providing a pathbuf pointer, initialized to NULL, then
- * calling check_for_release() with manage_mutex held and the address
- * of the pathbuf pointer, then dropping manage_mutex, then calling
- * cpuset_release_agent() with pathbuf, as set by check_for_release().
- */
-
-static void check_for_release(struct cpuset *cs, char **ppathbuf)
-{
-	if (notify_on_release(cs) && atomic_read(&cs->count) == 0 &&
-	    list_empty(&cs->children)) {
-		char *buf;
-
-		buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-		if (!buf)
-			return;
-		if (cpuset_path(cs, buf, PAGE_SIZE) < 0)
-			kfree(buf);
-		else
-			*ppathbuf = buf;
-	}
-}
-
 /*
  * Return in *pmask the portion of a cpusets's cpus_allowed that
  * are online.  If none are online, walk up the cpuset hierarchy
@@ -653,20 +390,19 @@
 	struct task_struct *tsk = current;
 	struct cpuset *cs;
 
-	if (tsk->cpuset == &top_cpuset) {
+	if (task_cs(tsk) == &top_cpuset) {
 		/* Don't need rcu for top_cpuset.  It's never freed. */
 		my_cpusets_mem_gen = top_cpuset.mems_generation;
 	} else {
 		rcu_read_lock();
-		cs = rcu_dereference(tsk->cpuset);
-		my_cpusets_mem_gen = cs->mems_generation;
+		my_cpusets_mem_gen = task_cs(current)->mems_generation;
 		rcu_read_unlock();
 	}
 
 	if (my_cpusets_mem_gen != tsk->cpuset_mems_generation) {
 		mutex_lock(&callback_mutex);
 		task_lock(tsk);
-		cs = tsk->cpuset;	/* Maybe changed when task not locked */
+		cs = task_cs(tsk); /* Maybe changed when task not locked */
 		guarantee_online_mems(cs, &tsk->mems_allowed);
 		tsk->cpuset_mems_generation = cs->mems_generation;
 		if (is_spread_page(cs))
@@ -721,11 +457,12 @@
 
 static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
 {
+	struct cgroup *cont;
 	struct cpuset *c, *par;
 
 	/* Each of our child cpusets must be a subset of us */
-	list_for_each_entry(c, &cur->children, sibling) {
-		if (!is_cpuset_subset(c, trial))
+	list_for_each_entry(cont, &cur->css.cgroup->children, sibling) {
+		if (!is_cpuset_subset(cgroup_cs(cont), trial))
 			return -EBUSY;
 	}
 
@@ -740,7 +477,8 @@
 		return -EACCES;
 
 	/* If either I or some sibling (!= me) is exclusive, we can't overlap */
-	list_for_each_entry(c, &par->children, sibling) {
+	list_for_each_entry(cont, &par->css.cgroup->children, sibling) {
+		c = cgroup_cs(cont);
 		if ((is_cpu_exclusive(trial) || is_cpu_exclusive(c)) &&
 		    c != cur &&
 		    cpus_intersects(trial->cpus_allowed, c->cpus_allowed))
@@ -751,17 +489,265 @@
 			return -EINVAL;
 	}
 
+	/* Cpusets with tasks can't have empty cpus_allowed or mems_allowed */
+	if (cgroup_task_count(cur->css.cgroup)) {
+		if (cpus_empty(trial->cpus_allowed) ||
+		    nodes_empty(trial->mems_allowed)) {
+			return -ENOSPC;
+		}
+	}
+
 	return 0;
 }
 
 /*
+ * Helper routine for rebuild_sched_domains().
+ * Do cpusets a, b have overlapping cpus_allowed masks?
+ */
+
+static int cpusets_overlap(struct cpuset *a, struct cpuset *b)
+{
+	return cpus_intersects(a->cpus_allowed, b->cpus_allowed);
+}
+
+/*
+ * rebuild_sched_domains()
+ *
+ * If the flag 'sched_load_balance' of any cpuset with non-empty
+ * 'cpus' changes, or if the 'cpus' allowed changes in any cpuset
+ * which has that flag enabled, or if any cpuset with a non-empty
+ * 'cpus' is removed, then call this routine to rebuild the
+ * scheduler's dynamic sched domains.
+ *
+ * This routine builds a partial partition of the systems CPUs
+ * (the set of non-overlappping cpumask_t's in the array 'part'
+ * below), and passes that partial partition to the kernel/sched.c
+ * partition_sched_domains() routine, which will rebuild the
+ * schedulers load balancing domains (sched domains) as specified
+ * by that partial partition.  A 'partial partition' is a set of
+ * non-overlapping subsets whose union is a subset of that set.
+ *
+ * See "What is sched_load_balance" in Documentation/cpusets.txt
+ * for a background explanation of this.
+ *
+ * Does not return errors, on the theory that the callers of this
+ * routine would rather not worry about failures to rebuild sched
+ * domains when operating in the severe memory shortage situations
+ * that could cause allocation failures below.
+ *
+ * Call with cgroup_mutex held.  May take callback_mutex during
+ * call due to the kfifo_alloc() and kmalloc() calls.  May nest
+ * a call to the lock_cpu_hotplug()/unlock_cpu_hotplug() pair.
+ * Must not be called holding callback_mutex, because we must not
+ * call lock_cpu_hotplug() while holding callback_mutex.  Elsewhere
+ * the kernel nests callback_mutex inside lock_cpu_hotplug() calls.
+ * So the reverse nesting would risk an ABBA deadlock.
+ *
+ * The three key local variables below are:
+ *    q  - a kfifo queue of cpuset pointers, used to implement a
+ *	   top-down scan of all cpusets.  This scan loads a pointer
+ *	   to each cpuset marked is_sched_load_balance into the
+ *	   array 'csa'.  For our purposes, rebuilding the schedulers
+ *	   sched domains, we can ignore !is_sched_load_balance cpusets.
+ *  csa  - (for CpuSet Array) Array of pointers to all the cpusets
+ *	   that need to be load balanced, for convenient iterative
+ *	   access by the subsequent code that finds the best partition,
+ *	   i.e the set of domains (subsets) of CPUs such that the
+ *	   cpus_allowed of every cpuset marked is_sched_load_balance
+ *	   is a subset of one of these domains, while there are as
+ *	   many such domains as possible, each as small as possible.
+ * doms  - Conversion of 'csa' to an array of cpumasks, for passing to
+ *	   the kernel/sched.c routine partition_sched_domains() in a
+ *	   convenient format, that can be easily compared to the prior
+ *	   value to determine what partition elements (sched domains)
+ *	   were changed (added or removed.)
+ *
+ * Finding the best partition (set of domains):
+ *	The triple nested loops below over i, j, k scan over the
+ *	load balanced cpusets (using the array of cpuset pointers in
+ *	csa[]) looking for pairs of cpusets that have overlapping
+ *	cpus_allowed, but which don't have the same 'pn' partition
+ *	number and gives them in the same partition number.  It keeps
+ *	looping on the 'restart' label until it can no longer find
+ *	any such pairs.
+ *
+ *	The union of the cpus_allowed masks from the set of
+ *	all cpusets having the same 'pn' value then form the one
+ *	element of the partition (one sched domain) to be passed to
+ *	partition_sched_domains().
+ */
+
+static void rebuild_sched_domains(void)
+{
+	struct kfifo *q;	/* queue of cpusets to be scanned */
+	struct cpuset *cp;	/* scans q */
+	struct cpuset **csa;	/* array of all cpuset ptrs */
+	int csn;		/* how many cpuset ptrs in csa so far */
+	int i, j, k;		/* indices for partition finding loops */
+	cpumask_t *doms;	/* resulting partition; i.e. sched domains */
+	int ndoms;		/* number of sched domains in result */
+	int nslot;		/* next empty doms[] cpumask_t slot */
+
+	q = NULL;
+	csa = NULL;
+	doms = NULL;
+
+	/* Special case for the 99% of systems with one, full, sched domain */
+	if (is_sched_load_balance(&top_cpuset)) {
+		ndoms = 1;
+		doms = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
+		if (!doms)
+			goto rebuild;
+		*doms = top_cpuset.cpus_allowed;
+		goto rebuild;
+	}
+
+	q = kfifo_alloc(number_of_cpusets * sizeof(cp), GFP_KERNEL, NULL);
+	if (IS_ERR(q))
+		goto done;
+	csa = kmalloc(number_of_cpusets * sizeof(cp), GFP_KERNEL);
+	if (!csa)
+		goto done;
+	csn = 0;
+
+	cp = &top_cpuset;
+	__kfifo_put(q, (void *)&cp, sizeof(cp));
+	while (__kfifo_get(q, (void *)&cp, sizeof(cp))) {
+		struct cgroup *cont;
+		struct cpuset *child;   /* scans child cpusets of cp */
+		if (is_sched_load_balance(cp))
+			csa[csn++] = cp;
+		list_for_each_entry(cont, &cp->css.cgroup->children, sibling) {
+			child = cgroup_cs(cont);
+			__kfifo_put(q, (void *)&child, sizeof(cp));
+		}
+  	}
+
+	for (i = 0; i < csn; i++)
+		csa[i]->pn = i;
+	ndoms = csn;
+
+restart:
+	/* Find the best partition (set of sched domains) */
+	for (i = 0; i < csn; i++) {
+		struct cpuset *a = csa[i];
+		int apn = a->pn;
+
+		for (j = 0; j < csn; j++) {
+			struct cpuset *b = csa[j];
+			int bpn = b->pn;
+
+			if (apn != bpn && cpusets_overlap(a, b)) {
+				for (k = 0; k < csn; k++) {
+					struct cpuset *c = csa[k];
+
+					if (c->pn == bpn)
+						c->pn = apn;
+				}
+				ndoms--;	/* one less element */
+				goto restart;
+			}
+		}
+	}
+
+	/* Convert <csn, csa> to <ndoms, doms> */
+	doms = kmalloc(ndoms * sizeof(cpumask_t), GFP_KERNEL);
+	if (!doms)
+		goto rebuild;
+
+	for (nslot = 0, i = 0; i < csn; i++) {
+		struct cpuset *a = csa[i];
+		int apn = a->pn;
+
+		if (apn >= 0) {
+			cpumask_t *dp = doms + nslot;
+
+			if (nslot == ndoms) {
+				static int warnings = 10;
+				if (warnings) {
+					printk(KERN_WARNING
+					 "rebuild_sched_domains confused:"
+					  " nslot %d, ndoms %d, csn %d, i %d,"
+					  " apn %d\n",
+					  nslot, ndoms, csn, i, apn);
+					warnings--;
+				}
+				continue;
+			}
+
+			cpus_clear(*dp);
+			for (j = i; j < csn; j++) {
+				struct cpuset *b = csa[j];
+
+				if (apn == b->pn) {
+					cpus_or(*dp, *dp, b->cpus_allowed);
+					b->pn = -1;
+				}
+			}
+			nslot++;
+		}
+	}
+	BUG_ON(nslot != ndoms);
+
+rebuild:
+	/* Have scheduler rebuild sched domains */
+	lock_cpu_hotplug();
+	partition_sched_domains(ndoms, doms);
+	unlock_cpu_hotplug();
+
+done:
+	if (q && !IS_ERR(q))
+		kfifo_free(q);
+	kfree(csa);
+	/* Don't kfree(doms) -- partition_sched_domains() does that. */
+}
+
+static inline int started_after_time(struct task_struct *t1,
+				     struct timespec *time,
+				     struct task_struct *t2)
+{
+	int start_diff = timespec_compare(&t1->start_time, time);
+	if (start_diff > 0) {
+		return 1;
+	} else if (start_diff < 0) {
+		return 0;
+	} else {
+		/*
+		 * Arbitrarily, if two processes started at the same
+		 * time, we'll say that the lower pointer value
+		 * started first. Note that t2 may have exited by now
+		 * so this may not be a valid pointer any longer, but
+		 * that's fine - it still serves to distinguish
+		 * between two tasks started (effectively)
+		 * simultaneously.
+		 */
+		return t1 > t2;
+	}
+}
+
+static inline int started_after(void *p1, void *p2)
+{
+	struct task_struct *t1 = p1;
+	struct task_struct *t2 = p2;
+	return started_after_time(t1, &t2->start_time, t2);
+}
+
+/*
  * Call with manage_mutex held.  May take callback_mutex during call.
  */
 
 static int update_cpumask(struct cpuset *cs, char *buf)
 {
 	struct cpuset trialcs;
-	int retval;
+	int retval, i;
+	int is_load_balanced;
+	struct cgroup_iter it;
+	struct cgroup *cgrp = cs->css.cgroup;
+	struct task_struct *p, *dropped;
+	/* Never dereference latest_task, since it's not refcounted */
+	struct task_struct *latest_task = NULL;
+	struct ptr_heap heap;
+	struct timespec latest_time = { 0, 0 };
 
 	/* top_cpuset.cpus_allowed tracks cpu_online_map; it's read-only */
 	if (cs == &top_cpuset)
@@ -770,11 +756,13 @@
 	trialcs = *cs;
 
 	/*
-	 * We allow a cpuset's cpus_allowed to be empty; if it has attached
-	 * tasks, we'll catch it later when we validate the change and return
-	 * -ENOSPC.
+	 * An empty cpus_allowed is ok iff there are no tasks in the cpuset.
+	 * Since cpulist_parse() fails on an empty mask, we special case
+	 * that parsing.  The validate_change() call ensures that cpusets
+	 * with tasks have cpus.
 	 */
-	if (!buf[0] || (buf[0] == '\n' && !buf[1])) {
+	buf = strstrip(buf);
+	if (!*buf) {
 		cpus_clear(trialcs.cpus_allowed);
 	} else {
 		retval = cpulist_parse(buf, trialcs.cpus_allowed);
@@ -782,15 +770,79 @@
 			return retval;
 	}
 	cpus_and(trialcs.cpus_allowed, trialcs.cpus_allowed, cpu_online_map);
-	/* cpus_allowed cannot be empty for a cpuset with attached tasks. */
-	if (atomic_read(&cs->count) && cpus_empty(trialcs.cpus_allowed))
-		return -ENOSPC;
 	retval = validate_change(cs, &trialcs);
 	if (retval < 0)
 		return retval;
+
+	/* Nothing to do if the cpus didn't change */
+	if (cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed))
+		return 0;
+	retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, &started_after);
+	if (retval)
+		return retval;
+
+	is_load_balanced = is_sched_load_balance(&trialcs);
+
 	mutex_lock(&callback_mutex);
 	cs->cpus_allowed = trialcs.cpus_allowed;
 	mutex_unlock(&callback_mutex);
+
+ again:
+	/*
+	 * Scan tasks in the cpuset, and update the cpumasks of any
+	 * that need an update. Since we can't call set_cpus_allowed()
+	 * while holding tasklist_lock, gather tasks to be processed
+	 * in a heap structure. If the statically-sized heap fills up,
+	 * overflow tasks that started later, and in future iterations
+	 * only consider tasks that started after the latest task in
+	 * the previous pass. This guarantees forward progress and
+	 * that we don't miss any tasks
+	 */
+	heap.size = 0;
+	cgroup_iter_start(cgrp, &it);
+	while ((p = cgroup_iter_next(cgrp, &it))) {
+		/* Only affect tasks that don't have the right cpus_allowed */
+		if (cpus_equal(p->cpus_allowed, cs->cpus_allowed))
+			continue;
+		/*
+		 * Only process tasks that started after the last task
+		 * we processed
+		 */
+		if (!started_after_time(p, &latest_time, latest_task))
+			continue;
+		dropped = heap_insert(&heap, p);
+		if (dropped == NULL) {
+			get_task_struct(p);
+		} else if (dropped != p) {
+			get_task_struct(p);
+			put_task_struct(dropped);
+		}
+	}
+	cgroup_iter_end(cgrp, &it);
+	if (heap.size) {
+		for (i = 0; i < heap.size; i++) {
+			struct task_struct *p = heap.ptrs[i];
+			if (i == 0) {
+				latest_time = p->start_time;
+				latest_task = p;
+			}
+			set_cpus_allowed(p, cs->cpus_allowed);
+			put_task_struct(p);
+		}
+		/*
+		 * If we had to process any tasks at all, scan again
+		 * in case some of them were in the middle of forking
+		 * children that didn't notice the new cpumask
+		 * restriction.  Not the most efficient way to do it,
+		 * but it avoids having to take callback_mutex in the
+		 * fork path
+		 */
+		goto again;
+	}
+	heap_free(&heap);
+	if (is_load_balanced)
+		rebuild_sched_domains();
+
 	return 0;
 }
 
@@ -839,7 +891,7 @@
 	do_migrate_pages(mm, from, to, MPOL_MF_MOVE_ALL);
 
 	mutex_lock(&callback_mutex);
-	guarantee_online_mems(tsk->cpuset, &tsk->mems_allowed);
+	guarantee_online_mems(task_cs(tsk),&tsk->mems_allowed);
 	mutex_unlock(&callback_mutex);
 }
 
@@ -857,16 +909,19 @@
  * their mempolicies to the cpusets new mems_allowed.
  */
 
+static void *cpuset_being_rebound;
+
 static int update_nodemask(struct cpuset *cs, char *buf)
 {
 	struct cpuset trialcs;
 	nodemask_t oldmem;
-	struct task_struct *g, *p;
+	struct task_struct *p;
 	struct mm_struct **mmarray;
 	int i, n, ntasks;
 	int migrate;
 	int fudge;
 	int retval;
+	struct cgroup_iter it;
 
 	/*
 	 * top_cpuset.mems_allowed tracks node_stats[N_HIGH_MEMORY];
@@ -878,29 +933,19 @@
 	trialcs = *cs;
 
 	/*
-	 * We allow a cpuset's mems_allowed to be empty; if it has attached
-	 * tasks, we'll catch it later when we validate the change and return
-	 * -ENOSPC.
+	 * An empty mems_allowed is ok iff there are no tasks in the cpuset.
+	 * Since nodelist_parse() fails on an empty mask, we special case
+	 * that parsing.  The validate_change() call ensures that cpusets
+	 * with tasks have memory.
 	 */
-	if (!buf[0] || (buf[0] == '\n' && !buf[1])) {
+	buf = strstrip(buf);
+	if (!*buf) {
 		nodes_clear(trialcs.mems_allowed);
 	} else {
 		retval = nodelist_parse(buf, trialcs.mems_allowed);
 		if (retval < 0)
 			goto done;
-		if (!nodes_intersects(trialcs.mems_allowed,
-						node_states[N_HIGH_MEMORY])) {
-			/*
-			 * error if only memoryless nodes specified.
-			 */
-			retval = -ENOSPC;
-			goto done;
-		}
 	}
-	/*
-	 * Exclude memoryless nodes.  We know that trialcs.mems_allowed
-	 * contains at least one node with memory.
-	 */
 	nodes_and(trialcs.mems_allowed, trialcs.mems_allowed,
 						node_states[N_HIGH_MEMORY]);
 	oldmem = cs->mems_allowed;
@@ -908,11 +953,6 @@
 		retval = 0;		/* Too easy - nothing to do */
 		goto done;
 	}
-	/* mems_allowed cannot be empty for a cpuset with attached tasks. */
-	if (atomic_read(&cs->count) && nodes_empty(trialcs.mems_allowed)) {
-		retval = -ENOSPC;
-		goto done;
-	}
 	retval = validate_change(cs, &trialcs);
 	if (retval < 0)
 		goto done;
@@ -922,7 +962,7 @@
 	cs->mems_generation = cpuset_mems_generation++;
 	mutex_unlock(&callback_mutex);
 
-	set_cpuset_being_rebound(cs);		/* causes mpol_copy() rebind */
+	cpuset_being_rebound = cs;		/* causes mpol_copy() rebind */
 
 	fudge = 10;				/* spare mmarray[] slots */
 	fudge += cpus_weight(cs->cpus_allowed);	/* imagine one fork-bomb/cpu */
@@ -936,13 +976,13 @@
 	 * enough mmarray[] w/o using GFP_ATOMIC.
 	 */
 	while (1) {
-		ntasks = atomic_read(&cs->count);	/* guess */
+		ntasks = cgroup_task_count(cs->css.cgroup);  /* guess */
 		ntasks += fudge;
 		mmarray = kmalloc(ntasks * sizeof(*mmarray), GFP_KERNEL);
 		if (!mmarray)
 			goto done;
 		read_lock(&tasklist_lock);		/* block fork */
-		if (atomic_read(&cs->count) <= ntasks)
+		if (cgroup_task_count(cs->css.cgroup) <= ntasks)
 			break;				/* got enough */
 		read_unlock(&tasklist_lock);		/* try again */
 		kfree(mmarray);
@@ -951,21 +991,21 @@
 	n = 0;
 
 	/* Load up mmarray[] with mm reference for each task in cpuset. */
-	do_each_thread(g, p) {
+	cgroup_iter_start(cs->css.cgroup, &it);
+	while ((p = cgroup_iter_next(cs->css.cgroup, &it))) {
 		struct mm_struct *mm;
 
 		if (n >= ntasks) {
 			printk(KERN_WARNING
 				"Cpuset mempolicy rebind incomplete.\n");
-			continue;
+			break;
 		}
-		if (p->cpuset != cs)
-			continue;
 		mm = get_task_mm(p);
 		if (!mm)
 			continue;
 		mmarray[n++] = mm;
-	} while_each_thread(g, p);
+	}
+	cgroup_iter_end(cs->css.cgroup, &it);
 	read_unlock(&tasklist_lock);
 
 	/*
@@ -993,12 +1033,17 @@
 
 	/* We're done rebinding vma's to this cpusets new mems_allowed. */
 	kfree(mmarray);
-	set_cpuset_being_rebound(NULL);
+	cpuset_being_rebound = NULL;
 	retval = 0;
 done:
 	return retval;
 }
 
+int current_cpuset_is_being_rebound(void)
+{
+	return task_cs(current) == cpuset_being_rebound;
+}
+
 /*
  * Call with manage_mutex held.
  */
@@ -1015,6 +1060,7 @@
 /*
  * update_flag - read a 0 or a 1 in a file and update associated flag
  * bit:	the bit to update (CS_CPU_EXCLUSIVE, CS_MEM_EXCLUSIVE,
+ *				CS_SCHED_LOAD_BALANCE,
  *				CS_NOTIFY_ON_RELEASE, CS_MEMORY_MIGRATE,
  *				CS_SPREAD_PAGE, CS_SPREAD_SLAB)
  * cs:	the cpuset to update
@@ -1028,6 +1074,7 @@
 	int turning_on;
 	struct cpuset trialcs;
 	int err;
+	int cpus_nonempty, balance_flag_changed;
 
 	turning_on = (simple_strtoul(buf, NULL, 10) != 0);
 
@@ -1040,10 +1087,18 @@
 	err = validate_change(cs, &trialcs);
 	if (err < 0)
 		return err;
+
+	cpus_nonempty = !cpus_empty(trialcs.cpus_allowed);
+	balance_flag_changed = (is_sched_load_balance(cs) !=
+		 			is_sched_load_balance(&trialcs));
+
 	mutex_lock(&callback_mutex);
 	cs->flags = trialcs.flags;
 	mutex_unlock(&callback_mutex);
 
+	if (cpus_nonempty && balance_flag_changed)
+		rebuild_sched_domains();
+
 	return 0;
 }
 
@@ -1145,85 +1200,34 @@
 	return val;
 }
 
-/*
- * Attack task specified by pid in 'pidbuf' to cpuset 'cs', possibly
- * writing the path of the old cpuset in 'ppathbuf' if it needs to be
- * notified on release.
- *
- * Call holding manage_mutex.  May take callback_mutex and task_lock of
- * the task 'pid' during call.
- */
-
-static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
+static int cpuset_can_attach(struct cgroup_subsys *ss,
+			     struct cgroup *cont, struct task_struct *tsk)
 {
-	pid_t pid;
-	struct task_struct *tsk;
-	struct cpuset *oldcs;
-	cpumask_t cpus;
-	nodemask_t from, to;
-	struct mm_struct *mm;
-	int retval;
+	struct cpuset *cs = cgroup_cs(cont);
 
-	if (sscanf(pidbuf, "%d", &pid) != 1)
-		return -EIO;
 	if (cpus_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))
 		return -ENOSPC;
 
-	if (pid) {
-		read_lock(&tasklist_lock);
+	return security_task_setscheduler(tsk, 0, NULL);
+}
 
-		tsk = find_task_by_pid(pid);
-		if (!tsk || tsk->flags & PF_EXITING) {
-			read_unlock(&tasklist_lock);
-			return -ESRCH;
-		}
-
-		get_task_struct(tsk);
-		read_unlock(&tasklist_lock);
-
-		if ((current->euid) && (current->euid != tsk->uid)
-		    && (current->euid != tsk->suid)) {
-			put_task_struct(tsk);
-			return -EACCES;
-		}
-	} else {
-		tsk = current;
-		get_task_struct(tsk);
-	}
-
-	retval = security_task_setscheduler(tsk, 0, NULL);
-	if (retval) {
-		put_task_struct(tsk);
-		return retval;
-	}
+static void cpuset_attach(struct cgroup_subsys *ss,
+			  struct cgroup *cont, struct cgroup *oldcont,
+			  struct task_struct *tsk)
+{
+	cpumask_t cpus;
+	nodemask_t from, to;
+	struct mm_struct *mm;
+	struct cpuset *cs = cgroup_cs(cont);
+	struct cpuset *oldcs = cgroup_cs(oldcont);
 
 	mutex_lock(&callback_mutex);
-
-	task_lock(tsk);
-	oldcs = tsk->cpuset;
-	/*
-	 * After getting 'oldcs' cpuset ptr, be sure still not exiting.
-	 * If 'oldcs' might be the top_cpuset due to the_top_cpuset_hack
-	 * then fail this attach_task(), to avoid breaking top_cpuset.count.
-	 */
-	if (tsk->flags & PF_EXITING) {
-		task_unlock(tsk);
-		mutex_unlock(&callback_mutex);
-		put_task_struct(tsk);
-		return -ESRCH;
-	}
-	atomic_inc(&cs->count);
-	rcu_assign_pointer(tsk->cpuset, cs);
-	task_unlock(tsk);
-
 	guarantee_online_cpus(cs, &cpus);
 	set_cpus_allowed(tsk, cpus);
+	mutex_unlock(&callback_mutex);
 
 	from = oldcs->mems_allowed;
 	to = cs->mems_allowed;
-
-	mutex_unlock(&callback_mutex);
-
 	mm = get_task_mm(tsk);
 	if (mm) {
 		mpol_rebind_mm(mm, &to);
@@ -1232,44 +1236,36 @@
 		mmput(mm);
 	}
 
-	put_task_struct(tsk);
-	synchronize_rcu();
-	if (atomic_dec_and_test(&oldcs->count))
-		check_for_release(oldcs, ppathbuf);
-	return 0;
 }
 
 /* The various types of files and directories in a cpuset file system */
 
 typedef enum {
-	FILE_ROOT,
-	FILE_DIR,
 	FILE_MEMORY_MIGRATE,
 	FILE_CPULIST,
 	FILE_MEMLIST,
 	FILE_CPU_EXCLUSIVE,
 	FILE_MEM_EXCLUSIVE,
-	FILE_NOTIFY_ON_RELEASE,
+	FILE_SCHED_LOAD_BALANCE,
 	FILE_MEMORY_PRESSURE_ENABLED,
 	FILE_MEMORY_PRESSURE,
 	FILE_SPREAD_PAGE,
 	FILE_SPREAD_SLAB,
-	FILE_TASKLIST,
 } cpuset_filetype_t;
 
-static ssize_t cpuset_common_file_write(struct file *file,
+static ssize_t cpuset_common_file_write(struct cgroup *cont,
+					struct cftype *cft,
+					struct file *file,
 					const char __user *userbuf,
 					size_t nbytes, loff_t *unused_ppos)
 {
-	struct cpuset *cs = __d_cs(file->f_path.dentry->d_parent);
-	struct cftype *cft = __d_cft(file->f_path.dentry);
+	struct cpuset *cs = cgroup_cs(cont);
 	cpuset_filetype_t type = cft->private;
 	char *buffer;
-	char *pathbuf = NULL;
 	int retval = 0;
 
 	/* Crude upper limit on largest legitimate cpulist user might write. */
-	if (nbytes > 100 + 6 * max(NR_CPUS, MAX_NUMNODES))
+	if (nbytes > 100U + 6 * max(NR_CPUS, MAX_NUMNODES))
 		return -E2BIG;
 
 	/* +1 for nul-terminator */
@@ -1282,9 +1278,9 @@
 	}
 	buffer[nbytes] = 0;	/* nul-terminate */
 
-	mutex_lock(&manage_mutex);
+	cgroup_lock();
 
-	if (is_removed(cs)) {
+	if (cgroup_is_removed(cont)) {
 		retval = -ENODEV;
 		goto out2;
 	}
@@ -1302,8 +1298,8 @@
 	case FILE_MEM_EXCLUSIVE:
 		retval = update_flag(CS_MEM_EXCLUSIVE, cs, buffer);
 		break;
-	case FILE_NOTIFY_ON_RELEASE:
-		retval = update_flag(CS_NOTIFY_ON_RELEASE, cs, buffer);
+	case FILE_SCHED_LOAD_BALANCE:
+		retval = update_flag(CS_SCHED_LOAD_BALANCE, cs, buffer);
 		break;
 	case FILE_MEMORY_MIGRATE:
 		retval = update_flag(CS_MEMORY_MIGRATE, cs, buffer);
@@ -1322,9 +1318,6 @@
 		retval = update_flag(CS_SPREAD_SLAB, cs, buffer);
 		cs->mems_generation = cpuset_mems_generation++;
 		break;
-	case FILE_TASKLIST:
-		retval = attach_task(cs, buffer, &pathbuf);
-		break;
 	default:
 		retval = -EINVAL;
 		goto out2;
@@ -1333,30 +1326,12 @@
 	if (retval == 0)
 		retval = nbytes;
 out2:
-	mutex_unlock(&manage_mutex);
-	cpuset_release_agent(pathbuf);
+	cgroup_unlock();
 out1:
 	kfree(buffer);
 	return retval;
 }
 
-static ssize_t cpuset_file_write(struct file *file, const char __user *buf,
-						size_t nbytes, loff_t *ppos)
-{
-	ssize_t retval = 0;
-	struct cftype *cft = __d_cft(file->f_path.dentry);
-	if (!cft)
-		return -ENODEV;
-
-	/* special function ? */
-	if (cft->write)
-		retval = cft->write(file, buf, nbytes, ppos);
-	else
-		retval = cpuset_common_file_write(file, buf, nbytes, ppos);
-
-	return retval;
-}
-
 /*
  * These ascii lists should be read in a single call, by using a user
  * buffer large enough to hold the entire map.  If read in smaller
@@ -1391,11 +1366,13 @@
 	return nodelist_scnprintf(page, PAGE_SIZE, mask);
 }
 
-static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
-				size_t nbytes, loff_t *ppos)
+static ssize_t cpuset_common_file_read(struct cgroup *cont,
+				       struct cftype *cft,
+				       struct file *file,
+				       char __user *buf,
+				       size_t nbytes, loff_t *ppos)
 {
-	struct cftype *cft = __d_cft(file->f_path.dentry);
-	struct cpuset *cs = __d_cs(file->f_path.dentry->d_parent);
+	struct cpuset *cs = cgroup_cs(cont);
 	cpuset_filetype_t type = cft->private;
 	char *page;
 	ssize_t retval = 0;
@@ -1419,8 +1396,8 @@
 	case FILE_MEM_EXCLUSIVE:
 		*s++ = is_mem_exclusive(cs) ? '1' : '0';
 		break;
-	case FILE_NOTIFY_ON_RELEASE:
-		*s++ = notify_on_release(cs) ? '1' : '0';
+	case FILE_SCHED_LOAD_BALANCE:
+		*s++ = is_sched_load_balance(cs) ? '1' : '0';
 		break;
 	case FILE_MEMORY_MIGRATE:
 		*s++ = is_memory_migrate(cs) ? '1' : '0';
@@ -1449,390 +1426,150 @@
 	return retval;
 }
 
-static ssize_t cpuset_file_read(struct file *file, char __user *buf, size_t nbytes,
-								loff_t *ppos)
-{
-	ssize_t retval = 0;
-	struct cftype *cft = __d_cft(file->f_path.dentry);
-	if (!cft)
-		return -ENODEV;
 
-	/* special function ? */
-	if (cft->read)
-		retval = cft->read(file, buf, nbytes, ppos);
-	else
-		retval = cpuset_common_file_read(file, buf, nbytes, ppos);
 
-	return retval;
-}
 
-static int cpuset_file_open(struct inode *inode, struct file *file)
-{
-	int err;
-	struct cftype *cft;
-
-	err = generic_file_open(inode, file);
-	if (err)
-		return err;
-
-	cft = __d_cft(file->f_path.dentry);
-	if (!cft)
-		return -ENODEV;
-	if (cft->open)
-		err = cft->open(inode, file);
-	else
-		err = 0;
-
-	return err;
-}
-
-static int cpuset_file_release(struct inode *inode, struct file *file)
-{
-	struct cftype *cft = __d_cft(file->f_path.dentry);
-	if (cft->release)
-		return cft->release(inode, file);
-	return 0;
-}
-
-/*
- * cpuset_rename - Only allow simple rename of directories in place.
- */
-static int cpuset_rename(struct inode *old_dir, struct dentry *old_dentry,
-                  struct inode *new_dir, struct dentry *new_dentry)
-{
-	if (!S_ISDIR(old_dentry->d_inode->i_mode))
-		return -ENOTDIR;
-	if (new_dentry->d_inode)
-		return -EEXIST;
-	if (old_dir != new_dir)
-		return -EIO;
-	return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
-}
-
-static const struct file_operations cpuset_file_operations = {
-	.read = cpuset_file_read,
-	.write = cpuset_file_write,
-	.llseek = generic_file_llseek,
-	.open = cpuset_file_open,
-	.release = cpuset_file_release,
-};
-
-static const struct inode_operations cpuset_dir_inode_operations = {
-	.lookup = simple_lookup,
-	.mkdir = cpuset_mkdir,
-	.rmdir = cpuset_rmdir,
-	.rename = cpuset_rename,
-};
-
-static int cpuset_create_file(struct dentry *dentry, int mode)
-{
-	struct inode *inode;
-
-	if (!dentry)
-		return -ENOENT;
-	if (dentry->d_inode)
-		return -EEXIST;
-
-	inode = cpuset_new_inode(mode);
-	if (!inode)
-		return -ENOMEM;
-
-	if (S_ISDIR(mode)) {
-		inode->i_op = &cpuset_dir_inode_operations;
-		inode->i_fop = &simple_dir_operations;
-
-		/* start off with i_nlink == 2 (for "." entry) */
-		inc_nlink(inode);
-	} else if (S_ISREG(mode)) {
-		inode->i_size = 0;
-		inode->i_fop = &cpuset_file_operations;
-	}
-
-	d_instantiate(dentry, inode);
-	dget(dentry);	/* Extra count - pin the dentry in core */
-	return 0;
-}
-
-/*
- *	cpuset_create_dir - create a directory for an object.
- *	cs:	the cpuset we create the directory for.
- *		It must have a valid ->parent field
- *		And we are going to fill its ->dentry field.
- *	name:	The name to give to the cpuset directory. Will be copied.
- *	mode:	mode to set on new directory.
- */
-
-static int cpuset_create_dir(struct cpuset *cs, const char *name, int mode)
-{
-	struct dentry *dentry = NULL;
-	struct dentry *parent;
-	int error = 0;
-
-	parent = cs->parent->dentry;
-	dentry = cpuset_get_dentry(parent, name);
-	if (IS_ERR(dentry))
-		return PTR_ERR(dentry);
-	error = cpuset_create_file(dentry, S_IFDIR | mode);
-	if (!error) {
-		dentry->d_fsdata = cs;
-		inc_nlink(parent->d_inode);
-		cs->dentry = dentry;
-	}
-	dput(dentry);
-
-	return error;
-}
-
-static int cpuset_add_file(struct dentry *dir, const struct cftype *cft)
-{
-	struct dentry *dentry;
-	int error;
-
-	mutex_lock(&dir->d_inode->i_mutex);
-	dentry = cpuset_get_dentry(dir, cft->name);
-	if (!IS_ERR(dentry)) {
-		error = cpuset_create_file(dentry, 0644 | S_IFREG);
-		if (!error)
-			dentry->d_fsdata = (void *)cft;
-		dput(dentry);
-	} else
-		error = PTR_ERR(dentry);
-	mutex_unlock(&dir->d_inode->i_mutex);
-	return error;
-}
-
-/*
- * Stuff for reading the 'tasks' file.
- *
- * Reading this file can return large amounts of data if a cpuset has
- * *lots* of attached tasks. So it may need several calls to read(),
- * but we cannot guarantee that the information we produce is correct
- * unless we produce it entirely atomically.
- *
- * Upon tasks file open(), a struct ctr_struct is allocated, that
- * will have a pointer to an array (also allocated here).  The struct
- * ctr_struct * is stored in file->private_data.  Its resources will
- * be freed by release() when the file is closed.  The array is used
- * to sprintf the PIDs and then used by read().
- */
-
-/* cpusets_tasks_read array */
-
-struct ctr_struct {
-	char *buf;
-	int bufsz;
-};
-
-/*
- * Load into 'pidarray' up to 'npids' of the tasks using cpuset 'cs'.
- * Return actual number of pids loaded.  No need to task_lock(p)
- * when reading out p->cpuset, as we don't really care if it changes
- * on the next cycle, and we are not going to try to dereference it.
- */
-static int pid_array_load(pid_t *pidarray, int npids, struct cpuset *cs)
-{
-	int n = 0;
-	struct task_struct *g, *p;
-
-	read_lock(&tasklist_lock);
-
-	do_each_thread(g, p) {
-		if (p->cpuset == cs) {
-			if (unlikely(n == npids))
-				goto array_full;
-			pidarray[n++] = p->pid;
-		}
-	} while_each_thread(g, p);
-
-array_full:
-	read_unlock(&tasklist_lock);
-	return n;
-}
-
-static int cmppid(const void *a, const void *b)
-{
-	return *(pid_t *)a - *(pid_t *)b;
-}
-
-/*
- * Convert array 'a' of 'npids' pid_t's to a string of newline separated
- * decimal pids in 'buf'.  Don't write more than 'sz' chars, but return
- * count 'cnt' of how many chars would be written if buf were large enough.
- */
-static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids)
-{
-	int cnt = 0;
-	int i;
-
-	for (i = 0; i < npids; i++)
-		cnt += snprintf(buf + cnt, max(sz - cnt, 0), "%d\n", a[i]);
-	return cnt;
-}
-
-/*
- * Handle an open on 'tasks' file.  Prepare a buffer listing the
- * process id's of tasks currently attached to the cpuset being opened.
- *
- * Does not require any specific cpuset mutexes, and does not take any.
- */
-static int cpuset_tasks_open(struct inode *unused, struct file *file)
-{
-	struct cpuset *cs = __d_cs(file->f_path.dentry->d_parent);
-	struct ctr_struct *ctr;
-	pid_t *pidarray;
-	int npids;
-	char c;
-
-	if (!(file->f_mode & FMODE_READ))
-		return 0;
-
-	ctr = kmalloc(sizeof(*ctr), GFP_KERNEL);
-	if (!ctr)
-		goto err0;
-
-	/*
-	 * If cpuset gets more users after we read count, we won't have
-	 * enough space - tough.  This race is indistinguishable to the
-	 * caller from the case that the additional cpuset users didn't
-	 * show up until sometime later on.
-	 */
-	npids = atomic_read(&cs->count);
-	pidarray = kmalloc(npids * sizeof(pid_t), GFP_KERNEL);
-	if (!pidarray)
-		goto err1;
-
-	npids = pid_array_load(pidarray, npids, cs);
-	sort(pidarray, npids, sizeof(pid_t), cmppid, NULL);
-
-	/* Call pid_array_to_buf() twice, first just to get bufsz */
-	ctr->bufsz = pid_array_to_buf(&c, sizeof(c), pidarray, npids) + 1;
-	ctr->buf = kmalloc(ctr->bufsz, GFP_KERNEL);
-	if (!ctr->buf)
-		goto err2;
-	ctr->bufsz = pid_array_to_buf(ctr->buf, ctr->bufsz, pidarray, npids);
-
-	kfree(pidarray);
-	file->private_data = ctr;
-	return 0;
-
-err2:
-	kfree(pidarray);
-err1:
-	kfree(ctr);
-err0:
-	return -ENOMEM;
-}
-
-static ssize_t cpuset_tasks_read(struct file *file, char __user *buf,
-						size_t nbytes, loff_t *ppos)
-{
-	struct ctr_struct *ctr = file->private_data;
-
-	return simple_read_from_buffer(buf, nbytes, ppos, ctr->buf, ctr->bufsz);
-}
-
-static int cpuset_tasks_release(struct inode *unused_inode, struct file *file)
-{
-	struct ctr_struct *ctr;
-
-	if (file->f_mode & FMODE_READ) {
-		ctr = file->private_data;
-		kfree(ctr->buf);
-		kfree(ctr);
-	}
-	return 0;
-}
 
 /*
  * for the common functions, 'private' gives the type of file
  */
 
-static struct cftype cft_tasks = {
-	.name = "tasks",
-	.open = cpuset_tasks_open,
-	.read = cpuset_tasks_read,
-	.release = cpuset_tasks_release,
-	.private = FILE_TASKLIST,
-};
-
 static struct cftype cft_cpus = {
 	.name = "cpus",
+	.read = cpuset_common_file_read,
+	.write = cpuset_common_file_write,
 	.private = FILE_CPULIST,
 };
 
 static struct cftype cft_mems = {
 	.name = "mems",
+	.read = cpuset_common_file_read,
+	.write = cpuset_common_file_write,
 	.private = FILE_MEMLIST,
 };
 
 static struct cftype cft_cpu_exclusive = {
 	.name = "cpu_exclusive",
+	.read = cpuset_common_file_read,
+	.write = cpuset_common_file_write,
 	.private = FILE_CPU_EXCLUSIVE,
 };
 
 static struct cftype cft_mem_exclusive = {
 	.name = "mem_exclusive",
+	.read = cpuset_common_file_read,
+	.write = cpuset_common_file_write,
 	.private = FILE_MEM_EXCLUSIVE,
 };
 
-static struct cftype cft_notify_on_release = {
-	.name = "notify_on_release",
-	.private = FILE_NOTIFY_ON_RELEASE,
+static struct cftype cft_sched_load_balance = {
+	.name = "sched_load_balance",
+	.read = cpuset_common_file_read,
+	.write = cpuset_common_file_write,
+	.private = FILE_SCHED_LOAD_BALANCE,
 };
 
 static struct cftype cft_memory_migrate = {
 	.name = "memory_migrate",
+	.read = cpuset_common_file_read,
+	.write = cpuset_common_file_write,
 	.private = FILE_MEMORY_MIGRATE,
 };
 
 static struct cftype cft_memory_pressure_enabled = {
 	.name = "memory_pressure_enabled",
+	.read = cpuset_common_file_read,
+	.write = cpuset_common_file_write,
 	.private = FILE_MEMORY_PRESSURE_ENABLED,
 };
 
 static struct cftype cft_memory_pressure = {
 	.name = "memory_pressure",
+	.read = cpuset_common_file_read,
+	.write = cpuset_common_file_write,
 	.private = FILE_MEMORY_PRESSURE,
 };
 
 static struct cftype cft_spread_page = {
 	.name = "memory_spread_page",
+	.read = cpuset_common_file_read,
+	.write = cpuset_common_file_write,
 	.private = FILE_SPREAD_PAGE,
 };
 
 static struct cftype cft_spread_slab = {
 	.name = "memory_spread_slab",
+	.read = cpuset_common_file_read,
+	.write = cpuset_common_file_write,
 	.private = FILE_SPREAD_SLAB,
 };
 
-static int cpuset_populate_dir(struct dentry *cs_dentry)
+static int cpuset_populate(struct cgroup_subsys *ss, struct cgroup *cont)
 {
 	int err;
 
-	if ((err = cpuset_add_file(cs_dentry, &cft_cpus)) < 0)
+	if ((err = cgroup_add_file(cont, ss, &cft_cpus)) < 0)
 		return err;
-	if ((err = cpuset_add_file(cs_dentry, &cft_mems)) < 0)
+	if ((err = cgroup_add_file(cont, ss, &cft_mems)) < 0)
 		return err;
-	if ((err = cpuset_add_file(cs_dentry, &cft_cpu_exclusive)) < 0)
+	if ((err = cgroup_add_file(cont, ss, &cft_cpu_exclusive)) < 0)
 		return err;
-	if ((err = cpuset_add_file(cs_dentry, &cft_mem_exclusive)) < 0)
+	if ((err = cgroup_add_file(cont, ss, &cft_mem_exclusive)) < 0)
 		return err;
-	if ((err = cpuset_add_file(cs_dentry, &cft_notify_on_release)) < 0)
+	if ((err = cgroup_add_file(cont, ss, &cft_memory_migrate)) < 0)
 		return err;
-	if ((err = cpuset_add_file(cs_dentry, &cft_memory_migrate)) < 0)
+	if ((err = cgroup_add_file(cont, ss, &cft_sched_load_balance)) < 0)
 		return err;
-	if ((err = cpuset_add_file(cs_dentry, &cft_memory_pressure)) < 0)
+	if ((err = cgroup_add_file(cont, ss, &cft_memory_pressure)) < 0)
 		return err;
-	if ((err = cpuset_add_file(cs_dentry, &cft_spread_page)) < 0)
+	if ((err = cgroup_add_file(cont, ss, &cft_spread_page)) < 0)
 		return err;
-	if ((err = cpuset_add_file(cs_dentry, &cft_spread_slab)) < 0)
+	if ((err = cgroup_add_file(cont, ss, &cft_spread_slab)) < 0)
 		return err;
-	if ((err = cpuset_add_file(cs_dentry, &cft_tasks)) < 0)
-		return err;
+	/* memory_pressure_enabled is in root cpuset only */
+	if (err == 0 && !cont->parent)
+		err = cgroup_add_file(cont, ss,
+					 &cft_memory_pressure_enabled);
 	return 0;
 }
 
 /*
+ * post_clone() is called at the end of cgroup_clone().
+ * 'cgroup' was just created automatically as a result of
+ * a cgroup_clone(), and the current task is about to
+ * be moved into 'cgroup'.
+ *
+ * Currently we refuse to set up the cgroup - thereby
+ * refusing the task to be entered, and as a result refusing
+ * the sys_unshare() or clone() which initiated it - if any
+ * sibling cpusets have exclusive cpus or mem.
+ *
+ * If this becomes a problem for some users who wish to
+ * allow that scenario, then cpuset_post_clone() could be
+ * changed to grant parent->cpus_allowed-sibling_cpus_exclusive
+ * (and likewise for mems) to the new cgroup.
+ */
+static void cpuset_post_clone(struct cgroup_subsys *ss,
+			      struct cgroup *cgroup)
+{
+	struct cgroup *parent, *child;
+	struct cpuset *cs, *parent_cs;
+
+	parent = cgroup->parent;
+	list_for_each_entry(child, &parent->children, sibling) {
+		cs = cgroup_cs(child);
+		if (is_mem_exclusive(cs) || is_cpu_exclusive(cs))
+			return;
+	}
+	cs = cgroup_cs(cgroup);
+	parent_cs = cgroup_cs(parent);
+
+	cs->mems_allowed = parent_cs->mems_allowed;
+	cs->cpus_allowed = parent_cs->cpus_allowed;
+	return;
+}
+
+/*
  *	cpuset_create - create a cpuset
  *	parent:	cpuset that will be parent of the new cpuset.
  *	name:		name of the new cpuset. Will be strcpy'ed.
@@ -1841,106 +1578,77 @@
  *	Must be called with the mutex on the parent inode held
  */
 
-static long cpuset_create(struct cpuset *parent, const char *name, int mode)
+static struct cgroup_subsys_state *cpuset_create(
+	struct cgroup_subsys *ss,
+	struct cgroup *cont)
 {
 	struct cpuset *cs;
-	int err;
+	struct cpuset *parent;
 
+	if (!cont->parent) {
+		/* This is early initialization for the top cgroup */
+		top_cpuset.mems_generation = cpuset_mems_generation++;
+		return &top_cpuset.css;
+	}
+	parent = cgroup_cs(cont->parent);
 	cs = kmalloc(sizeof(*cs), GFP_KERNEL);
 	if (!cs)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
-	mutex_lock(&manage_mutex);
 	cpuset_update_task_memory_state();
 	cs->flags = 0;
-	if (notify_on_release(parent))
-		set_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
 	if (is_spread_page(parent))
 		set_bit(CS_SPREAD_PAGE, &cs->flags);
 	if (is_spread_slab(parent))
 		set_bit(CS_SPREAD_SLAB, &cs->flags);
+	set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
 	cs->cpus_allowed = CPU_MASK_NONE;
 	cs->mems_allowed = NODE_MASK_NONE;
-	atomic_set(&cs->count, 0);
-	INIT_LIST_HEAD(&cs->sibling);
-	INIT_LIST_HEAD(&cs->children);
 	cs->mems_generation = cpuset_mems_generation++;
 	fmeter_init(&cs->fmeter);
 
 	cs->parent = parent;
-
-	mutex_lock(&callback_mutex);
-	list_add(&cs->sibling, &cs->parent->children);
 	number_of_cpusets++;
-	mutex_unlock(&callback_mutex);
-
-	err = cpuset_create_dir(cs, name, mode);
-	if (err < 0)
-		goto err;
-
-	/*
-	 * Release manage_mutex before cpuset_populate_dir() because it
-	 * will down() this new directory's i_mutex and if we race with
-	 * another mkdir, we might deadlock.
-	 */
-	mutex_unlock(&manage_mutex);
-
-	err = cpuset_populate_dir(cs->dentry);
-	/* If err < 0, we have a half-filled directory - oh well ;) */
-	return 0;
-err:
-	list_del(&cs->sibling);
-	mutex_unlock(&manage_mutex);
-	kfree(cs);
-	return err;
+	return &cs->css ;
 }
 
-static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+/*
+ * Locking note on the strange update_flag() call below:
+ *
+ * If the cpuset being removed has its flag 'sched_load_balance'
+ * enabled, then simulate turning sched_load_balance off, which
+ * will call rebuild_sched_domains().  The lock_cpu_hotplug()
+ * call in rebuild_sched_domains() must not be made while holding
+ * callback_mutex.  Elsewhere the kernel nests callback_mutex inside
+ * lock_cpu_hotplug() calls.  So the reverse nesting would risk an
+ * ABBA deadlock.
+ */
+
+static void cpuset_destroy(struct cgroup_subsys *ss, struct cgroup *cont)
 {
-	struct cpuset *c_parent = dentry->d_parent->d_fsdata;
+	struct cpuset *cs = cgroup_cs(cont);
 
-	/* the vfs holds inode->i_mutex already */
-	return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR);
-}
-
-static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
-{
-	struct cpuset *cs = dentry->d_fsdata;
-	struct dentry *d;
-	struct cpuset *parent;
-	char *pathbuf = NULL;
-
-	/* the vfs holds both inode->i_mutex already */
-
-	mutex_lock(&manage_mutex);
 	cpuset_update_task_memory_state();
-	if (atomic_read(&cs->count) > 0) {
-		mutex_unlock(&manage_mutex);
-		return -EBUSY;
-	}
-	if (!list_empty(&cs->children)) {
-		mutex_unlock(&manage_mutex);
-		return -EBUSY;
-	}
-	parent = cs->parent;
-	mutex_lock(&callback_mutex);
-	set_bit(CS_REMOVED, &cs->flags);
-	list_del(&cs->sibling);	/* delete my sibling from parent->children */
-	spin_lock(&cs->dentry->d_lock);
-	d = dget(cs->dentry);
-	cs->dentry = NULL;
-	spin_unlock(&d->d_lock);
-	cpuset_d_remove_dir(d);
-	dput(d);
+
+	if (is_sched_load_balance(cs))
+		update_flag(CS_SCHED_LOAD_BALANCE, cs, "0");
+
 	number_of_cpusets--;
-	mutex_unlock(&callback_mutex);
-	if (list_empty(&parent->children))
-		check_for_release(parent, &pathbuf);
-	mutex_unlock(&manage_mutex);
-	cpuset_release_agent(pathbuf);
-	return 0;
+	kfree(cs);
 }
 
+struct cgroup_subsys cpuset_subsys = {
+	.name = "cpuset",
+	.create = cpuset_create,
+	.destroy  = cpuset_destroy,
+	.can_attach = cpuset_can_attach,
+	.attach = cpuset_attach,
+	.populate = cpuset_populate,
+	.post_clone = cpuset_post_clone,
+	.subsys_id = cpuset_subsys_id,
+	.early_init = 1,
+};
+
 /*
  * cpuset_init_early - just enough so that the calls to
  * cpuset_update_task_memory_state() in early init code
@@ -1949,13 +1657,11 @@
 
 int __init cpuset_init_early(void)
 {
-	struct task_struct *tsk = current;
-
-	tsk->cpuset = &top_cpuset;
-	tsk->cpuset->mems_generation = cpuset_mems_generation++;
+	top_cpuset.mems_generation = cpuset_mems_generation++;
 	return 0;
 }
 
+
 /**
  * cpuset_init - initialize cpusets at system boot
  *
@@ -1964,39 +1670,21 @@
 
 int __init cpuset_init(void)
 {
-	struct dentry *root;
-	int err;
+	int err = 0;
 
 	top_cpuset.cpus_allowed = CPU_MASK_ALL;
 	top_cpuset.mems_allowed = NODE_MASK_ALL;
 
 	fmeter_init(&top_cpuset.fmeter);
 	top_cpuset.mems_generation = cpuset_mems_generation++;
-
-	init_task.cpuset = &top_cpuset;
+	set_bit(CS_SCHED_LOAD_BALANCE, &top_cpuset.flags);
 
 	err = register_filesystem(&cpuset_fs_type);
 	if (err < 0)
-		goto out;
-	cpuset_mount = kern_mount(&cpuset_fs_type);
-	if (IS_ERR(cpuset_mount)) {
-		printk(KERN_ERR "cpuset: could not mount!\n");
-		err = PTR_ERR(cpuset_mount);
-		cpuset_mount = NULL;
-		goto out;
-	}
-	root = cpuset_mount->mnt_sb->s_root;
-	root->d_fsdata = &top_cpuset;
-	inc_nlink(root->d_inode);
-	top_cpuset.dentry = root;
-	root->d_inode->i_op = &cpuset_dir_inode_operations;
+		return err;
+
 	number_of_cpusets = 1;
-	err = cpuset_populate_dir(root);
-	/* memory_pressure_enabled is in root cpuset only */
-	if (err == 0)
-		err = cpuset_add_file(root, &cft_memory_pressure_enabled);
-out:
-	return err;
+	return 0;
 }
 
 /*
@@ -2022,10 +1710,12 @@
 
 static void guarantee_online_cpus_mems_in_subtree(const struct cpuset *cur)
 {
+	struct cgroup *cont;
 	struct cpuset *c;
 
 	/* Each of our child cpusets mems must be online */
-	list_for_each_entry(c, &cur->children, sibling) {
+	list_for_each_entry(cont, &cur->css.cgroup->children, sibling) {
+		c = cgroup_cs(cont);
 		guarantee_online_cpus_mems_in_subtree(c);
 		if (!cpus_empty(c->cpus_allowed))
 			guarantee_online_cpus(c, &c->cpus_allowed);
@@ -2053,7 +1743,7 @@
 
 static void common_cpu_mem_hotplug_unplug(void)
 {
-	mutex_lock(&manage_mutex);
+	cgroup_lock();
 	mutex_lock(&callback_mutex);
 
 	guarantee_online_cpus_mems_in_subtree(&top_cpuset);
@@ -2061,7 +1751,7 @@
 	top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
 
 	mutex_unlock(&callback_mutex);
-	mutex_unlock(&manage_mutex);
+	cgroup_unlock();
 }
 
 /*
@@ -2074,8 +1764,8 @@
  * cpu_online_map on each CPU hotplug (cpuhp) event.
  */
 
-static int cpuset_handle_cpuhp(struct notifier_block *nb,
-				unsigned long phase, void *cpu)
+static int cpuset_handle_cpuhp(struct notifier_block *unused_nb,
+				unsigned long phase, void *unused_cpu)
 {
 	if (phase == CPU_DYING || phase == CPU_DYING_FROZEN)
 		return NOTIFY_DONE;
@@ -2113,109 +1803,7 @@
 }
 
 /**
- * cpuset_fork - attach newly forked task to its parents cpuset.
- * @tsk: pointer to task_struct of forking parent process.
- *
- * Description: A task inherits its parent's cpuset at fork().
- *
- * A pointer to the shared cpuset was automatically copied in fork.c
- * by dup_task_struct().  However, we ignore that copy, since it was
- * not made under the protection of task_lock(), so might no longer be
- * a valid cpuset pointer.  attach_task() might have already changed
- * current->cpuset, allowing the previously referenced cpuset to
- * be removed and freed.  Instead, we task_lock(current) and copy
- * its present value of current->cpuset for our freshly forked child.
- *
- * At the point that cpuset_fork() is called, 'current' is the parent
- * task, and the passed argument 'child' points to the child task.
- **/
 
-void cpuset_fork(struct task_struct *child)
-{
-	task_lock(current);
-	child->cpuset = current->cpuset;
-	atomic_inc(&child->cpuset->count);
-	task_unlock(current);
-}
-
-/**
- * cpuset_exit - detach cpuset from exiting task
- * @tsk: pointer to task_struct of exiting process
- *
- * Description: Detach cpuset from @tsk and release it.
- *
- * Note that cpusets marked notify_on_release force every task in
- * them to take the global manage_mutex mutex when exiting.
- * This could impact scaling on very large systems.  Be reluctant to
- * use notify_on_release cpusets where very high task exit scaling
- * is required on large systems.
- *
- * Don't even think about derefencing 'cs' after the cpuset use count
- * goes to zero, except inside a critical section guarded by manage_mutex
- * or callback_mutex.   Otherwise a zero cpuset use count is a license to
- * any other task to nuke the cpuset immediately, via cpuset_rmdir().
- *
- * This routine has to take manage_mutex, not callback_mutex, because
- * it is holding that mutex while calling check_for_release(),
- * which calls kmalloc(), so can't be called holding callback_mutex().
- *
- * the_top_cpuset_hack:
- *
- *    Set the exiting tasks cpuset to the root cpuset (top_cpuset).
- *
- *    Don't leave a task unable to allocate memory, as that is an
- *    accident waiting to happen should someone add a callout in
- *    do_exit() after the cpuset_exit() call that might allocate.
- *    If a task tries to allocate memory with an invalid cpuset,
- *    it will oops in cpuset_update_task_memory_state().
- *
- *    We call cpuset_exit() while the task is still competent to
- *    handle notify_on_release(), then leave the task attached to
- *    the root cpuset (top_cpuset) for the remainder of its exit.
- *
- *    To do this properly, we would increment the reference count on
- *    top_cpuset, and near the very end of the kernel/exit.c do_exit()
- *    code we would add a second cpuset function call, to drop that
- *    reference.  This would just create an unnecessary hot spot on
- *    the top_cpuset reference count, to no avail.
- *
- *    Normally, holding a reference to a cpuset without bumping its
- *    count is unsafe.   The cpuset could go away, or someone could
- *    attach us to a different cpuset, decrementing the count on
- *    the first cpuset that we never incremented.  But in this case,
- *    top_cpuset isn't going away, and either task has PF_EXITING set,
- *    which wards off any attach_task() attempts, or task is a failed
- *    fork, never visible to attach_task.
- *
- *    Another way to do this would be to set the cpuset pointer
- *    to NULL here, and check in cpuset_update_task_memory_state()
- *    for a NULL pointer.  This hack avoids that NULL check, for no
- *    cost (other than this way too long comment ;).
- **/
-
-void cpuset_exit(struct task_struct *tsk)
-{
-	struct cpuset *cs;
-
-	task_lock(current);
-	cs = tsk->cpuset;
-	tsk->cpuset = &top_cpuset;	/* the_top_cpuset_hack - see above */
-	task_unlock(current);
-
-	if (notify_on_release(cs)) {
-		char *pathbuf = NULL;
-
-		mutex_lock(&manage_mutex);
-		if (atomic_dec_and_test(&cs->count))
-			check_for_release(cs, &pathbuf);
-		mutex_unlock(&manage_mutex);
-		cpuset_release_agent(pathbuf);
-	} else {
-		atomic_dec(&cs->count);
-	}
-}
-
-/**
  * cpuset_cpus_allowed - return cpus_allowed mask from a tasks cpuset.
  * @tsk: pointer to task_struct from which to obtain cpuset->cpus_allowed.
  *
@@ -2230,14 +1818,27 @@
 	cpumask_t mask;
 
 	mutex_lock(&callback_mutex);
-	task_lock(tsk);
-	guarantee_online_cpus(tsk->cpuset, &mask);
-	task_unlock(tsk);
+	mask = cpuset_cpus_allowed_locked(tsk);
 	mutex_unlock(&callback_mutex);
 
 	return mask;
 }
 
+/**
+ * cpuset_cpus_allowed_locked - return cpus_allowed mask from a tasks cpuset.
+ * Must be  called with callback_mutex held.
+ **/
+cpumask_t cpuset_cpus_allowed_locked(struct task_struct *tsk)
+{
+	cpumask_t mask;
+
+	task_lock(tsk);
+	guarantee_online_cpus(task_cs(tsk), &mask);
+	task_unlock(tsk);
+
+	return mask;
+}
+
 void cpuset_init_current_mems_allowed(void)
 {
 	current->mems_allowed = NODE_MASK_ALL;
@@ -2259,7 +1860,7 @@
 
 	mutex_lock(&callback_mutex);
 	task_lock(tsk);
-	guarantee_online_mems(tsk->cpuset, &mask);
+	guarantee_online_mems(task_cs(tsk), &mask);
 	task_unlock(tsk);
 	mutex_unlock(&callback_mutex);
 
@@ -2390,7 +1991,7 @@
 	mutex_lock(&callback_mutex);
 
 	task_lock(current);
-	cs = nearest_exclusive_ancestor(current->cpuset);
+	cs = nearest_exclusive_ancestor(task_cs(current));
 	task_unlock(current);
 
 	allowed = node_isset(node, cs->mems_allowed);
@@ -2431,12 +2032,12 @@
 	node = zone_to_nid(z);
 	if (node_isset(node, current->mems_allowed))
 		return 1;
-        /*
-         * Allow tasks that have access to memory reserves because they have
-         * been OOM killed to get memory anywhere.
-         */
-        if (unlikely(test_thread_flag(TIF_MEMDIE)))
-                return 1;
+	/*
+	 * Allow tasks that have access to memory reserves because they have
+	 * been OOM killed to get memory anywhere.
+	 */
+	if (unlikely(test_thread_flag(TIF_MEMDIE)))
+		return 1;
 	return 0;
 }
 
@@ -2550,14 +2151,12 @@
 
 void __cpuset_memory_pressure_bump(void)
 {
-	struct cpuset *cs;
-
 	task_lock(current);
-	cs = current->cpuset;
-	fmeter_markevent(&cs->fmeter);
+	fmeter_markevent(&task_cs(current)->fmeter);
 	task_unlock(current);
 }
 
+#ifdef CONFIG_PROC_PID_CPUSET
 /*
  * proc_cpuset_show()
  *  - Print tasks cpuset path into seq_file.
@@ -2569,11 +2168,12 @@
  *    the_top_cpuset_hack in cpuset_exit(), which sets an exiting tasks
  *    cpuset to top_cpuset.
  */
-static int proc_cpuset_show(struct seq_file *m, void *v)
+static int proc_cpuset_show(struct seq_file *m, void *unused_v)
 {
 	struct pid *pid;
 	struct task_struct *tsk;
 	char *buf;
+	struct cgroup_subsys_state *css;
 	int retval;
 
 	retval = -ENOMEM;
@@ -2588,15 +2188,15 @@
 		goto out_free;
 
 	retval = -EINVAL;
-	mutex_lock(&manage_mutex);
-
-	retval = cpuset_path(tsk->cpuset, buf, PAGE_SIZE);
+	cgroup_lock();
+	css = task_subsys_state(tsk, cpuset_subsys_id);
+	retval = cgroup_path(css->cgroup, buf, PAGE_SIZE);
 	if (retval < 0)
 		goto out_unlock;
 	seq_puts(m, buf);
 	seq_putc(m, '\n');
 out_unlock:
-	mutex_unlock(&manage_mutex);
+	cgroup_unlock();
 	put_task_struct(tsk);
 out_free:
 	kfree(buf);
@@ -2616,6 +2216,7 @@
 	.llseek		= seq_lseek,
 	.release	= single_release,
 };
+#endif /* CONFIG_PROC_PID_CPUSET */
 
 /* Display task cpus_allowed, mems_allowed in /proc/<pid>/status file. */
 char *cpuset_task_status_allowed(struct task_struct *task, char *buffer)
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
index 09e9574..10e43fd 100644
--- a/kernel/delayacct.c
+++ b/kernel/delayacct.c
@@ -115,6 +115,12 @@
 	tmp += timespec_to_ns(&ts);
 	d->cpu_run_real_total = (tmp < (s64)d->cpu_run_real_total) ? 0 : tmp;
 
+	tmp = (s64)d->cpu_scaled_run_real_total;
+	cputime_to_timespec(tsk->utimescaled + tsk->stimescaled, &ts);
+	tmp += timespec_to_ns(&ts);
+	d->cpu_scaled_run_real_total =
+		(tmp < (s64)d->cpu_scaled_run_real_total) ? 0 : tmp;
+
 	/*
 	 * No locking available for sched_info (and too expensive to add one)
 	 * Mitigate by taking snapshot of values
diff --git a/kernel/die_notifier.c b/kernel/die_notifier.c
deleted file mode 100644
index 0d98827..0000000
--- a/kernel/die_notifier.c
+++ /dev/null
@@ -1,38 +0,0 @@
-
-#include <linux/module.h>
-#include <linux/notifier.h>
-#include <linux/vmalloc.h>
-#include <linux/kdebug.h>
-
-
-static ATOMIC_NOTIFIER_HEAD(die_chain);
-
-int notify_die(enum die_val val, const char *str,
-	       struct pt_regs *regs, long err, int trap, int sig)
-{
-	struct die_args args = {
-		.regs		= regs,
-		.str		= str,
-		.err		= err,
-		.trapnr		= trap,
-		.signr		= sig,
-
-	};
-
-	return atomic_notifier_call_chain(&die_chain, val, &args);
-}
-
-int register_die_notifier(struct notifier_block *nb)
-{
-	vmalloc_sync_all();
-	return atomic_notifier_chain_register(&die_chain, nb);
-}
-EXPORT_SYMBOL_GPL(register_die_notifier);
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
-	return atomic_notifier_chain_unregister(&die_chain, nb);
-}
-EXPORT_SYMBOL_GPL(unregister_die_notifier);
-
-
diff --git a/kernel/dma.c b/kernel/dma.c
index 937b13c..6a82bb7 100644
--- a/kernel/dma.c
+++ b/kernel/dma.c
@@ -20,7 +20,7 @@
 #include <asm/dma.h>
 #include <asm/system.h>
 
- 
+
 
 /* A note on resource allocation:
  *
@@ -95,7 +95,7 @@
 	if (xchg(&dma_chan_busy[dmanr].lock, 0) == 0) {
 		printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
 		return;
-	}	
+	}
 
 } /* free_dma */
 
@@ -121,8 +121,8 @@
 
 	for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) {
 		if (dma_chan_busy[i].lock) {
-		    seq_printf(m, "%2d: %s\n", i,
-			       dma_chan_busy[i].device_id);
+			seq_printf(m, "%2d: %s\n", i,
+				   dma_chan_busy[i].device_id);
 		}
 	}
 	return 0;
diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c
index 3c2eaea..a9e6bad 100644
--- a/kernel/exec_domain.c
+++ b/kernel/exec_domain.c
@@ -57,7 +57,7 @@
 {
 	struct exec_domain *	ep;
 	u_long			pers = personality(personality);
-		
+
 	read_lock(&exec_domains_lock);
 	for (ep = exec_domains; ep; ep = ep->next) {
 		if (pers >= ep->pers_low && pers <= ep->pers_high)
diff --git a/kernel/exit.c b/kernel/exit.c
index 2c704c8..f1aec27 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -31,7 +31,7 @@
 #include <linux/taskstats_kern.h>
 #include <linux/delayacct.h>
 #include <linux/freezer.h>
-#include <linux/cpuset.h>
+#include <linux/cgroup.h>
 #include <linux/syscalls.h>
 #include <linux/signal.h>
 #include <linux/posix-timers.h>
@@ -148,6 +148,7 @@
 	int zap_leader;
 repeat:
 	atomic_dec(&p->user->processes);
+	proc_flush_task(p);
 	write_lock_irq(&tasklist_lock);
 	ptrace_unlink(p);
 	BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
@@ -175,7 +176,6 @@
 	}
 
 	write_unlock_irq(&tasklist_lock);
-	proc_flush_task(p);
 	release_thread(p);
 	call_rcu(&p->rcu, delayed_put_task_struct);
 
@@ -221,7 +221,7 @@
 	do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
 		if (p == ignored_task
 				|| p->exit_state
-				|| is_init(p->real_parent))
+				|| is_global_init(p->real_parent))
 			continue;
 		if (task_pgrp(p->real_parent) != pgrp &&
 		    task_session(p->real_parent) == task_session(p)) {
@@ -299,14 +299,14 @@
 {
 	struct task_struct *curr = current->group_leader;
 
-	if (process_session(curr) != session) {
+	if (task_session_nr(curr) != session) {
 		detach_pid(curr, PIDTYPE_SID);
-		set_signal_session(curr->signal, session);
+		set_task_session(curr, session);
 		attach_pid(curr, PIDTYPE_SID, find_pid(session));
 	}
-	if (process_group(curr) != pgrp) {
+	if (task_pgrp_nr(curr) != pgrp) {
 		detach_pid(curr, PIDTYPE_PGID);
-		curr->signal->pgrp = pgrp;
+		set_task_pgrp(curr, pgrp);
 		attach_pid(curr, PIDTYPE_PGID, find_pid(pgrp));
 	}
 }
@@ -400,11 +400,12 @@
 	current->fs = fs;
 	atomic_inc(&fs->count);
 
-	exit_task_namespaces(current);
-	current->nsproxy = init_task.nsproxy;
-	get_task_namespaces(current);
+	if (current->nsproxy != init_task.nsproxy) {
+		get_nsproxy(init_task.nsproxy);
+		switch_task_namespaces(current, init_task.nsproxy);
+	}
 
- 	exit_files(current);
+	exit_files(current);
 	current->files = init_task.files;
 	atomic_inc(&current->files->count);
 
@@ -492,7 +493,7 @@
 }
 EXPORT_SYMBOL(reset_files_struct);
 
-static inline void __exit_files(struct task_struct *tsk)
+static void __exit_files(struct task_struct *tsk)
 {
 	struct files_struct * files = tsk->files;
 
@@ -509,7 +510,7 @@
 	__exit_files(tsk);
 }
 
-static inline void __put_fs_struct(struct fs_struct *fs)
+static void __put_fs_struct(struct fs_struct *fs)
 {
 	/* No need to hold fs->lock if we are killing it */
 	if (atomic_dec_and_test(&fs->count)) {
@@ -530,7 +531,7 @@
 	__put_fs_struct(fs);
 }
 
-static inline void __exit_fs(struct task_struct *tsk)
+static void __exit_fs(struct task_struct *tsk)
 {
 	struct fs_struct * fs = tsk->fs;
 
@@ -665,19 +666,22 @@
  * the child reaper process (ie "init") in our pid
  * space.
  */
-static void
-forget_original_parent(struct task_struct *father, struct list_head *to_release)
+static void forget_original_parent(struct task_struct *father)
 {
-	struct task_struct *p, *reaper = father;
-	struct list_head *_p, *_n;
+	struct task_struct *p, *n, *reaper = father;
+	struct list_head ptrace_dead;
+
+	INIT_LIST_HEAD(&ptrace_dead);
+
+	write_lock_irq(&tasklist_lock);
 
 	do {
 		reaper = next_thread(reaper);
 		if (reaper == father) {
-			reaper = child_reaper(father);
+			reaper = task_child_reaper(father);
 			break;
 		}
-	} while (reaper->exit_state);
+	} while (reaper->flags & PF_EXITING);
 
 	/*
 	 * There are only two places where our children can be:
@@ -687,9 +691,8 @@
 	 *
 	 * Search them and reparent children.
 	 */
-	list_for_each_safe(_p, _n, &father->children) {
+	list_for_each_entry_safe(p, n, &father->children, sibling) {
 		int ptrace;
-		p = list_entry(_p, struct task_struct, sibling);
 
 		ptrace = p->ptrace;
 
@@ -715,13 +718,23 @@
 		 * while it was being traced by us, to be able to see it in wait4.
 		 */
 		if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && p->exit_signal == -1))
-			list_add(&p->ptrace_list, to_release);
+			list_add(&p->ptrace_list, &ptrace_dead);
 	}
-	list_for_each_safe(_p, _n, &father->ptrace_children) {
-		p = list_entry(_p, struct task_struct, ptrace_list);
+
+	list_for_each_entry_safe(p, n, &father->ptrace_children, ptrace_list) {
 		p->real_parent = reaper;
 		reparent_thread(p, father, 1);
 	}
+
+	write_unlock_irq(&tasklist_lock);
+	BUG_ON(!list_empty(&father->children));
+	BUG_ON(!list_empty(&father->ptrace_children));
+
+	list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_list) {
+		list_del_init(&p->ptrace_list);
+		release_task(p);
+	}
+
 }
 
 /*
@@ -732,7 +745,6 @@
 {
 	int state;
 	struct task_struct *t;
-	struct list_head ptrace_dead, *_p, *_n;
 	struct pid *pgrp;
 
 	if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT)
@@ -753,8 +765,6 @@
 		spin_unlock_irq(&tsk->sighand->siglock);
 	}
 
-	write_lock_irq(&tasklist_lock);
-
 	/*
 	 * This does two things:
 	 *
@@ -763,12 +773,10 @@
 	 *	as a result of our exiting, and if they have any stopped
 	 *	jobs, send them a SIGHUP and then a SIGCONT.  (POSIX 3.2.2.2)
 	 */
+	forget_original_parent(tsk);
+	exit_task_namespaces(tsk);
 
-	INIT_LIST_HEAD(&ptrace_dead);
-	forget_original_parent(tsk, &ptrace_dead);
-	BUG_ON(!list_empty(&tsk->children));
-	BUG_ON(!list_empty(&tsk->ptrace_children));
-
+	write_lock_irq(&tasklist_lock);
 	/*
 	 * Check to see if any process groups have become orphaned
 	 * as a result of our exiting, and if they have any stopped
@@ -792,7 +800,7 @@
 	/* Let father know we died
 	 *
 	 * Thread signals are configurable, but you aren't going to use
-	 * that to send signals to arbitary processes. 
+	 * that to send signals to arbitary processes.
 	 * That stops right now.
 	 *
 	 * If the parent exec id doesn't match the exec id we saved
@@ -833,12 +841,6 @@
 
 	write_unlock_irq(&tasklist_lock);
 
-	list_for_each_safe(_p, _n, &ptrace_dead) {
-		list_del_init(_p);
-		t = list_entry(_p, struct task_struct, ptrace_list);
-		release_task(t);
-	}
-
 	/* If the process is dead, release it - nobody will wait for it */
 	if (state == EXIT_DEAD)
 		release_task(tsk);
@@ -874,10 +876,35 @@
 
 static inline void exit_child_reaper(struct task_struct *tsk)
 {
-	if (likely(tsk->group_leader != child_reaper(tsk)))
+	if (likely(tsk->group_leader != task_child_reaper(tsk)))
 		return;
 
-	panic("Attempted to kill init!");
+	if (tsk->nsproxy->pid_ns == &init_pid_ns)
+		panic("Attempted to kill init!");
+
+	/*
+	 * @tsk is the last thread in the 'cgroup-init' and is exiting.
+	 * Terminate all remaining processes in the namespace and reap them
+	 * before exiting @tsk.
+	 *
+	 * Note that @tsk (last thread of cgroup-init) may not necessarily
+	 * be the child-reaper (i.e main thread of cgroup-init) of the
+	 * namespace i.e the child_reaper may have already exited.
+	 *
+	 * Even after a child_reaper exits, we let it inherit orphaned children,
+	 * because, pid_ns->child_reaper remains valid as long as there is
+	 * at least one living sub-thread in the cgroup init.
+
+	 * This living sub-thread of the cgroup-init will be notified when
+	 * a child inherited by the 'child-reaper' exits (do_notify_parent()
+	 * uses __group_send_sig_info()). Further, when reaping child processes,
+	 * do_wait() iterates over children of all living sub threads.
+
+	 * i.e even though 'child_reaper' thread is listed as the parent of the
+	 * orphaned children, any living sub-thread in the cgroup-init can
+	 * perform the role of the child_reaper.
+	 */
+	zap_pid_ns_processes(tsk->nsproxy->pid_ns);
 }
 
 fastcall NORET_TYPE void do_exit(long code)
@@ -932,7 +959,7 @@
 
 	if (unlikely(in_atomic()))
 		printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
-				current->comm, current->pid,
+				current->comm, task_pid_nr(current),
 				preempt_count());
 
 	acct_update_integrals(tsk);
@@ -972,7 +999,7 @@
 	__exit_fs(tsk);
 	check_stack_usage();
 	exit_thread();
-	cpuset_exit(tsk);
+	cgroup_exit(tsk, 1);
 	exit_keys(tsk);
 
 	if (group_dead && tsk->signal->leader)
@@ -983,7 +1010,6 @@
 		module_put(tsk->binfmt->module);
 
 	proc_exit_connector(tsk);
-	exit_task_namespaces(tsk);
 	exit_notify(tsk);
 #ifdef CONFIG_NUMA
 	mpol_free(tsk->mempolicy);
@@ -1086,15 +1112,17 @@
 static int eligible_child(pid_t pid, int options, struct task_struct *p)
 {
 	int err;
+	struct pid_namespace *ns;
 
+	ns = current->nsproxy->pid_ns;
 	if (pid > 0) {
-		if (p->pid != pid)
+		if (task_pid_nr_ns(p, ns) != pid)
 			return 0;
 	} else if (!pid) {
-		if (process_group(p) != process_group(current))
+		if (task_pgrp_nr_ns(p, ns) != task_pgrp_vnr(current))
 			return 0;
 	} else if (pid != -1) {
-		if (process_group(p) != -pid)
+		if (task_pgrp_nr_ns(p, ns) != -pid)
 			return 0;
 	}
 
@@ -1164,9 +1192,12 @@
 {
 	unsigned long state;
 	int retval, status, traced;
+	struct pid_namespace *ns;
+
+	ns = current->nsproxy->pid_ns;
 
 	if (unlikely(noreap)) {
-		pid_t pid = p->pid;
+		pid_t pid = task_pid_nr_ns(p, ns);
 		uid_t uid = p->uid;
 		int exit_code = p->exit_code;
 		int why, status;
@@ -1285,11 +1316,11 @@
 			retval = put_user(status, &infop->si_status);
 	}
 	if (!retval && infop)
-		retval = put_user(p->pid, &infop->si_pid);
+		retval = put_user(task_pid_nr_ns(p, ns), &infop->si_pid);
 	if (!retval && infop)
 		retval = put_user(p->uid, &infop->si_uid);
 	if (!retval)
-		retval = p->pid;
+		retval = task_pid_nr_ns(p, ns);
 
 	if (traced) {
 		write_lock_irq(&tasklist_lock);
@@ -1326,6 +1357,7 @@
 			     int __user *stat_addr, struct rusage __user *ru)
 {
 	int retval, exit_code;
+	struct pid_namespace *ns;
 
 	if (!p->exit_code)
 		return 0;
@@ -1344,11 +1376,12 @@
 	 * keep holding onto the tasklist_lock while we call getrusage and
 	 * possibly take page faults for user memory.
 	 */
+	ns = current->nsproxy->pid_ns;
 	get_task_struct(p);
 	read_unlock(&tasklist_lock);
 
 	if (unlikely(noreap)) {
-		pid_t pid = p->pid;
+		pid_t pid = task_pid_nr_ns(p, ns);
 		uid_t uid = p->uid;
 		int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
 
@@ -1419,11 +1452,11 @@
 	if (!retval && infop)
 		retval = put_user(exit_code, &infop->si_status);
 	if (!retval && infop)
-		retval = put_user(p->pid, &infop->si_pid);
+		retval = put_user(task_pid_nr_ns(p, ns), &infop->si_pid);
 	if (!retval && infop)
 		retval = put_user(p->uid, &infop->si_uid);
 	if (!retval)
-		retval = p->pid;
+		retval = task_pid_nr_ns(p, ns);
 	put_task_struct(p);
 
 	BUG_ON(!retval);
@@ -1443,6 +1476,7 @@
 	int retval;
 	pid_t pid;
 	uid_t uid;
+	struct pid_namespace *ns;
 
 	if (!(p->signal->flags & SIGNAL_STOP_CONTINUED))
 		return 0;
@@ -1457,7 +1491,8 @@
 		p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
 	spin_unlock_irq(&p->sighand->siglock);
 
-	pid = p->pid;
+	ns = current->nsproxy->pid_ns;
+	pid = task_pid_nr_ns(p, ns);
 	uid = p->uid;
 	get_task_struct(p);
 	read_unlock(&tasklist_lock);
@@ -1468,7 +1503,7 @@
 		if (!retval && stat_addr)
 			retval = put_user(0xffff, stat_addr);
 		if (!retval)
-			retval = p->pid;
+			retval = task_pid_nr_ns(p, ns);
 	} else {
 		retval = wait_noreap_copyout(p, pid, uid,
 					     CLD_CONTINUED, SIGCONT,
@@ -1517,12 +1552,9 @@
 	tsk = current;
 	do {
 		struct task_struct *p;
-		struct list_head *_p;
 		int ret;
 
-		list_for_each(_p,&tsk->children) {
-			p = list_entry(_p, struct task_struct, sibling);
-
+		list_for_each_entry(p, &tsk->children, sibling) {
 			ret = eligible_child(pid, options, p);
 			if (!ret)
 				continue;
@@ -1604,9 +1636,8 @@
 			}
 		}
 		if (!flag) {
-			list_for_each(_p, &tsk->ptrace_children) {
-				p = list_entry(_p, struct task_struct,
-						ptrace_list);
+			list_for_each_entry(p, &tsk->ptrace_children,
+					    ptrace_list) {
 				if (!eligible_child(pid, options, p))
 					continue;
 				flag = 1;
diff --git a/kernel/fork.c b/kernel/fork.c
index 490495a..ddafdfa 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -29,7 +29,7 @@
 #include <linux/nsproxy.h>
 #include <linux/capability.h>
 #include <linux/cpu.h>
-#include <linux/cpuset.h>
+#include <linux/cgroup.h>
 #include <linux/security.h>
 #include <linux/swap.h>
 #include <linux/syscalls.h>
@@ -50,6 +50,7 @@
 #include <linux/taskstats_kern.h>
 #include <linux/random.h>
 #include <linux/tty.h>
+#include <linux/proc_fs.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -116,7 +117,7 @@
 
 void __put_task_struct(struct task_struct *tsk)
 {
-	WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
+	WARN_ON(!tsk->exit_state);
 	WARN_ON(atomic_read(&tsk->usage));
 	WARN_ON(tsk == current);
 
@@ -205,7 +206,7 @@
 }
 
 #ifdef CONFIG_MMU
-static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
 {
 	struct vm_area_struct *mpnt, *tmp, **pprev;
 	struct rb_node **rb_link, *rb_parent;
@@ -268,7 +269,7 @@
 			get_file(file);
 			if (tmp->vm_flags & VM_DENYWRITE)
 				atomic_dec(&inode->i_writecount);
-      
+
 			/* insert tmp into the share list, just after mpnt */
 			spin_lock(&file->f_mapping->i_mmap_lock);
 			tmp->vm_truncate_count = mpnt->vm_truncate_count;
@@ -331,7 +332,7 @@
 #define mm_free_pgd(mm)
 #endif /* CONFIG_MMU */
 
- __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock);
+__cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock);
 
 #define allocate_mm()	(kmem_cache_alloc(mm_cachep, GFP_KERNEL))
 #define free_mm(mm)	(kmem_cache_free(mm_cachep, (mm)))
@@ -583,7 +584,7 @@
 	return retval;
 }
 
-static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old)
+static struct fs_struct *__copy_fs_struct(struct fs_struct *old)
 {
 	struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
 	/* We don't need to lock fs - think why ;-) */
@@ -615,7 +616,7 @@
 
 EXPORT_SYMBOL_GPL(copy_fs_struct);
 
-static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk)
+static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
 {
 	if (clone_flags & CLONE_FS) {
 		atomic_inc(&current->fs->count);
@@ -738,8 +739,8 @@
 	/* compute the remainder to be cleared */
 	size = (new_fdt->max_fds - open_files) * sizeof(struct file *);
 
-	/* This is long word aligned thus could use a optimized version */ 
-	memset(new_fds, 0, size); 
+	/* This is long word aligned thus could use a optimized version */
+	memset(new_fds, 0, size);
 
 	if (new_fdt->max_fds > open_files) {
 		int left = (new_fdt->max_fds-open_files)/8;
@@ -818,7 +819,7 @@
 
 EXPORT_SYMBOL(unshare_files);
 
-static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
+static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
 {
 	struct sighand_struct *sig;
 
@@ -841,7 +842,7 @@
 		kmem_cache_free(sighand_cachep, sighand);
 }
 
-static inline int copy_signal(unsigned long clone_flags, struct task_struct * tsk)
+static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
 {
 	struct signal_struct *sig;
 	int ret;
@@ -923,7 +924,7 @@
 	kmem_cache_free(signal_cachep, sig);
 }
 
-static inline void cleanup_signal(struct task_struct *tsk)
+static void cleanup_signal(struct task_struct *tsk)
 {
 	struct signal_struct *sig = tsk->signal;
 
@@ -933,7 +934,7 @@
 		__cleanup_signal(sig);
 }
 
-static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
+static void copy_flags(unsigned long clone_flags, struct task_struct *p)
 {
 	unsigned long new_flags = p->flags;
 
@@ -942,16 +943,17 @@
 	if (!(clone_flags & CLONE_PTRACE))
 		p->ptrace = 0;
 	p->flags = new_flags;
+	clear_freeze_flag(p);
 }
 
 asmlinkage long sys_set_tid_address(int __user *tidptr)
 {
 	current->clear_child_tid = tidptr;
 
-	return current->pid;
+	return task_pid_vnr(current);
 }
 
-static inline void rt_mutex_init_task(struct task_struct *p)
+static void rt_mutex_init_task(struct task_struct *p)
 {
 	spin_lock_init(&p->pi_lock);
 #ifdef CONFIG_RT_MUTEXES
@@ -972,12 +974,12 @@
 					unsigned long stack_start,
 					struct pt_regs *regs,
 					unsigned long stack_size,
-					int __user *parent_tidptr,
 					int __user *child_tidptr,
 					struct pid *pid)
 {
 	int retval;
-	struct task_struct *p = NULL;
+	struct task_struct *p;
+	int cgroup_callbacks_done = 0;
 
 	if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
 		return ERR_PTR(-EINVAL);
@@ -1041,12 +1043,6 @@
 	p->did_exec = 0;
 	delayacct_tsk_init(p);	/* Must remain after dup_task_struct() */
 	copy_flags(clone_flags, p);
-	p->pid = pid_nr(pid);
-	retval = -EFAULT;
-	if (clone_flags & CLONE_PARENT_SETTID)
-		if (put_user(p->pid, parent_tidptr))
-			goto bad_fork_cleanup_delays_binfmt;
-
 	INIT_LIST_HEAD(&p->children);
 	INIT_LIST_HEAD(&p->sibling);
 	p->vfork_done = NULL;
@@ -1058,6 +1054,8 @@
 	p->utime = cputime_zero;
 	p->stime = cputime_zero;
 	p->gtime = cputime_zero;
+	p->utimescaled = cputime_zero;
+	p->stimescaled = cputime_zero;
 
 #ifdef CONFIG_TASK_XACCT
 	p->rchar = 0;		/* I/O counter: bytes read */
@@ -1068,12 +1066,12 @@
 	task_io_accounting_init(p);
 	acct_clear_integrals(p);
 
- 	p->it_virt_expires = cputime_zero;
+	p->it_virt_expires = cputime_zero;
 	p->it_prof_expires = cputime_zero;
- 	p->it_sched_expires = 0;
- 	INIT_LIST_HEAD(&p->cpu_timers[0]);
- 	INIT_LIST_HEAD(&p->cpu_timers[1]);
- 	INIT_LIST_HEAD(&p->cpu_timers[2]);
+	p->it_sched_expires = 0;
+	INIT_LIST_HEAD(&p->cpu_timers[0]);
+	INIT_LIST_HEAD(&p->cpu_timers[1]);
+	INIT_LIST_HEAD(&p->cpu_timers[2]);
 
 	p->lock_depth = -1;		/* -1 = no lock */
 	do_posix_clock_monotonic_gettime(&p->start_time);
@@ -1083,15 +1081,14 @@
 	p->security = NULL;
 #endif
 	p->io_context = NULL;
-	p->io_wait = NULL;
 	p->audit_context = NULL;
-	cpuset_fork(p);
+	cgroup_fork(p);
 #ifdef CONFIG_NUMA
  	p->mempolicy = mpol_copy(p->mempolicy);
  	if (IS_ERR(p->mempolicy)) {
  		retval = PTR_ERR(p->mempolicy);
  		p->mempolicy = NULL;
- 		goto bad_fork_cleanup_cpuset;
+ 		goto bad_fork_cleanup_cgroup;
  	}
 	mpol_fix_fork_child_flag(p);
 #endif
@@ -1124,10 +1121,6 @@
 	p->blocked_on = NULL; /* not blocked yet */
 #endif
 
-	p->tgid = p->pid;
-	if (clone_flags & CLONE_THREAD)
-		p->tgid = current->tgid;
-
 	if ((retval = security_task_alloc(p)))
 		goto bad_fork_cleanup_policy;
 	if ((retval = audit_alloc(p)))
@@ -1153,6 +1146,24 @@
 	if (retval)
 		goto bad_fork_cleanup_namespaces;
 
+	if (pid != &init_struct_pid) {
+		retval = -ENOMEM;
+		pid = alloc_pid(task_active_pid_ns(p));
+		if (!pid)
+			goto bad_fork_cleanup_namespaces;
+
+		if (clone_flags & CLONE_NEWPID) {
+			retval = pid_ns_prepare_proc(task_active_pid_ns(p));
+			if (retval < 0)
+				goto bad_fork_free_pid;
+		}
+	}
+
+	p->pid = pid_nr(pid);
+	p->tgid = p->pid;
+	if (clone_flags & CLONE_THREAD)
+		p->tgid = current->tgid;
+
 	p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
 	/*
 	 * Clear TID on mm_release()?
@@ -1202,6 +1213,12 @@
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 
+	/* Now that the task is set up, run cgroup callbacks if
+	 * necessary. We need to run them before the task is visible
+	 * on the tasklist. */
+	cgroup_fork_callbacks(p);
+	cgroup_callbacks_done = 1;
+
 	/* Need tasklist lock for parent etc handling! */
 	write_lock_irq(&tasklist_lock);
 
@@ -1239,12 +1256,12 @@
 	 * A fatal signal pending means that current will exit, so the new
 	 * thread can't slip out of an OOM kill (or normal SIGKILL).
  	 */
- 	recalc_sigpending();
+	recalc_sigpending();
 	if (signal_pending(current)) {
 		spin_unlock(&current->sighand->siglock);
 		write_unlock_irq(&tasklist_lock);
 		retval = -ERESTARTNOINTR;
-		goto bad_fork_cleanup_namespaces;
+		goto bad_fork_free_pid;
 	}
 
 	if (clone_flags & CLONE_THREAD) {
@@ -1273,11 +1290,22 @@
 			__ptrace_link(p, current->parent);
 
 		if (thread_group_leader(p)) {
-			p->signal->tty = current->signal->tty;
-			p->signal->pgrp = process_group(current);
-			set_signal_session(p->signal, process_session(current));
-			attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
-			attach_pid(p, PIDTYPE_SID, task_session(current));
+			if (clone_flags & CLONE_NEWPID) {
+				p->nsproxy->pid_ns->child_reaper = p;
+				p->signal->tty = NULL;
+				set_task_pgrp(p, p->pid);
+				set_task_session(p, p->pid);
+				attach_pid(p, PIDTYPE_PGID, pid);
+				attach_pid(p, PIDTYPE_SID, pid);
+			} else {
+				p->signal->tty = current->signal->tty;
+				set_task_pgrp(p, task_pgrp_nr(current));
+				set_task_session(p, task_session_nr(current));
+				attach_pid(p, PIDTYPE_PGID,
+						task_pgrp(current));
+				attach_pid(p, PIDTYPE_SID,
+						task_session(current));
+			}
 
 			list_add_tail_rcu(&p->tasks, &init_task.tasks);
 			__get_cpu_var(process_counts)++;
@@ -1290,8 +1318,12 @@
 	spin_unlock(&current->sighand->siglock);
 	write_unlock_irq(&tasklist_lock);
 	proc_fork_connector(p);
+	cgroup_post_fork(p);
 	return p;
 
+bad_fork_free_pid:
+	if (pid != &init_struct_pid)
+		free_pid(pid);
 bad_fork_cleanup_namespaces:
 	exit_task_namespaces(p);
 bad_fork_cleanup_keys:
@@ -1316,10 +1348,9 @@
 bad_fork_cleanup_policy:
 #ifdef CONFIG_NUMA
 	mpol_free(p->mempolicy);
-bad_fork_cleanup_cpuset:
+bad_fork_cleanup_cgroup:
 #endif
-	cpuset_exit(p);
-bad_fork_cleanup_delays_binfmt:
+	cgroup_exit(p, cgroup_callbacks_done);
 	delayacct_tsk_free(p);
 	if (p->binfmt)
 		module_put(p->binfmt->module);
@@ -1346,7 +1377,7 @@
 	struct task_struct *task;
 	struct pt_regs regs;
 
-	task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL, NULL,
+	task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL,
 				&init_struct_pid);
 	if (!IS_ERR(task))
 		init_idle(task, cpu);
@@ -1354,7 +1385,7 @@
 	return task;
 }
 
-static inline int fork_traceflag (unsigned clone_flags)
+static int fork_traceflag(unsigned clone_flags)
 {
 	if (clone_flags & CLONE_UNTRACED)
 		return 0;
@@ -1385,19 +1416,16 @@
 {
 	struct task_struct *p;
 	int trace = 0;
-	struct pid *pid = alloc_pid();
 	long nr;
 
-	if (!pid)
-		return -EAGAIN;
-	nr = pid->nr;
 	if (unlikely(current->ptrace)) {
 		trace = fork_traceflag (clone_flags);
 		if (trace)
 			clone_flags |= CLONE_PTRACE;
 	}
 
-	p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, pid);
+	p = copy_process(clone_flags, stack_start, regs, stack_size,
+			child_tidptr, NULL);
 	/*
 	 * Do this prior waking up the new thread - the thread pointer
 	 * might get invalid after that point, if the thread exits quickly.
@@ -1405,6 +1433,17 @@
 	if (!IS_ERR(p)) {
 		struct completion vfork;
 
+		/*
+		 * this is enough to call pid_nr_ns here, but this if
+		 * improves optimisation of regular fork()
+		 */
+		nr = (clone_flags & CLONE_NEWPID) ?
+			task_pid_nr_ns(p, current->nsproxy->pid_ns) :
+				task_pid_vnr(p);
+
+		if (clone_flags & CLONE_PARENT_SETTID)
+			put_user(nr, parent_tidptr);
+
 		if (clone_flags & CLONE_VFORK) {
 			p->vfork_done = &vfork;
 			init_completion(&vfork);
@@ -1438,7 +1477,6 @@
 			}
 		}
 	} else {
-		free_pid(pid);
 		nr = PTR_ERR(p);
 	}
 	return nr;
@@ -1483,7 +1521,7 @@
  * Check constraints on flags passed to the unshare system call and
  * force unsharing of additional process context as appropriate.
  */
-static inline void check_unshare_flags(unsigned long *flags_ptr)
+static void check_unshare_flags(unsigned long *flags_ptr)
 {
 	/*
 	 * If unsharing a thread from a thread group, must also
@@ -1615,7 +1653,7 @@
 	struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
 	struct files_struct *fd, *new_fd = NULL;
 	struct sem_undo_list *new_ulist = NULL;
-	struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
+	struct nsproxy *new_nsproxy = NULL;
 
 	check_unshare_flags(&unshare_flags);
 
@@ -1645,14 +1683,13 @@
 
 	if (new_fs ||  new_mm || new_fd || new_ulist || new_nsproxy) {
 
-		task_lock(current);
-
 		if (new_nsproxy) {
-			old_nsproxy = current->nsproxy;
-			current->nsproxy = new_nsproxy;
-			new_nsproxy = old_nsproxy;
+			switch_task_namespaces(current, new_nsproxy);
+			new_nsproxy = NULL;
 		}
 
+		task_lock(current);
+
 		if (new_fs) {
 			fs = current->fs;
 			current->fs = new_fs;
diff --git a/kernel/futex.c b/kernel/futex.c
index d725676..32710451 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -53,6 +53,9 @@
 #include <linux/signal.h>
 #include <linux/module.h>
 #include <linux/magic.h>
+#include <linux/pid.h>
+#include <linux/nsproxy.h>
+
 #include <asm/futex.h>
 
 #include "rtmutex_common.h"
@@ -293,7 +296,7 @@
  */
 void drop_futex_key_refs(union futex_key *key)
 {
-	if (key->both.ptr == 0)
+	if (!key->both.ptr)
 		return;
 	switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
 		case FUT_OFF_INODE:
@@ -443,8 +446,7 @@
 	struct task_struct *p;
 
 	rcu_read_lock();
-	p = find_task_by_pid(pid);
-
+	p = find_task_by_vpid(pid);
 	if (!p || ((current->euid != p->euid) && (current->euid != p->uid)))
 		p = ERR_PTR(-ESRCH);
 	else
@@ -653,7 +655,7 @@
 	if (!(uval & FUTEX_OWNER_DIED)) {
 		int ret = 0;
 
-		newval = FUTEX_WAITERS | new_owner->pid;
+		newval = FUTEX_WAITERS | task_pid_vnr(new_owner);
 
 		curval = cmpxchg_futex_value_locked(uaddr, uval, newval);
 
@@ -1046,7 +1048,7 @@
  retry:
 	lock_ptr = q->lock_ptr;
 	barrier();
-	if (lock_ptr != 0) {
+	if (lock_ptr != NULL) {
 		spin_lock(lock_ptr);
 		/*
 		 * q->lock_ptr can change between reading it and
@@ -1106,7 +1108,7 @@
 static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
 				struct task_struct *curr)
 {
-	u32 newtid = curr->pid | FUTEX_WAITERS;
+	u32 newtid = task_pid_vnr(curr) | FUTEX_WAITERS;
 	struct futex_pi_state *pi_state = q->pi_state;
 	u32 uval, curval, newval;
 	int ret;
@@ -1368,7 +1370,7 @@
 	 * (by doing a 0 -> TID atomic cmpxchg), while holding all
 	 * the locks. It will most likely not succeed.
 	 */
-	newval = current->pid;
+	newval = task_pid_vnr(current);
 
 	curval = cmpxchg_futex_value_locked(uaddr, 0, newval);
 
@@ -1379,7 +1381,7 @@
 	 * Detect deadlocks. In case of REQUEUE_PI this is a valid
 	 * situation and we return success to user space.
 	 */
-	if (unlikely((curval & FUTEX_TID_MASK) == current->pid)) {
+	if (unlikely((curval & FUTEX_TID_MASK) == task_pid_vnr(current))) {
 		ret = -EDEADLK;
 		goto out_unlock_release_sem;
 	}
@@ -1408,7 +1410,7 @@
 	 */
 	if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
 		/* Keep the OWNER_DIED bit */
-		newval = (curval & ~FUTEX_TID_MASK) | current->pid;
+		newval = (curval & ~FUTEX_TID_MASK) | task_pid_vnr(current);
 		ownerdied = 0;
 		lock_taken = 1;
 	}
@@ -1587,7 +1589,7 @@
 	/*
 	 * We release only a lock we actually own:
 	 */
-	if ((uval & FUTEX_TID_MASK) != current->pid)
+	if ((uval & FUTEX_TID_MASK) != task_pid_vnr(current))
 		return -EPERM;
 	/*
 	 * First take all the futex related locks:
@@ -1608,7 +1610,7 @@
 	 * anyone else up:
 	 */
 	if (!(uval & FUTEX_OWNER_DIED))
-		uval = cmpxchg_futex_value_locked(uaddr, current->pid, 0);
+		uval = cmpxchg_futex_value_locked(uaddr, task_pid_vnr(current), 0);
 
 
 	if (unlikely(uval == -EFAULT))
@@ -1617,7 +1619,7 @@
 	 * Rare case: we managed to release the lock atomically,
 	 * no need to wake anyone else up:
 	 */
-	if (unlikely(uval == current->pid))
+	if (unlikely(uval == task_pid_vnr(current)))
 		goto out_unlock;
 
 	/*
@@ -1854,7 +1856,7 @@
 
 		ret = -ESRCH;
 		rcu_read_lock();
-		p = find_task_by_pid(pid);
+		p = find_task_by_vpid(pid);
 		if (!p)
 			goto err_unlock;
 		ret = -EPERM;
@@ -1887,7 +1889,7 @@
 	if (get_user(uval, uaddr))
 		return -1;
 
-	if ((uval & FUTEX_TID_MASK) == curr->pid) {
+	if ((uval & FUTEX_TID_MASK) == task_pid_vnr(curr)) {
 		/*
 		 * Ok, this dying thread is truly holding a futex
 		 * of interest. Set the OWNER_DIED bit atomically
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
index 2c2e295..00b5726 100644
--- a/kernel/futex_compat.c
+++ b/kernel/futex_compat.c
@@ -8,6 +8,7 @@
 
 #include <linux/linkage.h>
 #include <linux/compat.h>
+#include <linux/nsproxy.h>
 #include <linux/futex.h>
 
 #include <asm/uaccess.h>
@@ -124,7 +125,7 @@
 
 		ret = -ESRCH;
 		read_lock(&tasklist_lock);
-		p = find_task_by_pid(pid);
+		p = find_task_by_vpid(pid);
 		if (!p)
 			goto err_unlock;
 		ret = -EPERM;
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index dc8a445..b6d2ff7 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -412,7 +412,7 @@
 	/*
 	 * When the callback is running, we do not reprogram the clock event
 	 * device. The timer callback is either running on a different CPU or
-	 * the callback is executed in the hrtimer_interupt context. The
+	 * the callback is executed in the hrtimer_interrupt context. The
 	 * reprogramming is handled either by the softirq, which called the
 	 * callback or at the end of the hrtimer_interrupt.
 	 */
@@ -638,7 +638,7 @@
 #endif
 
 /*
- * Counterpart to lock_timer_base above:
+ * Counterpart to lock_hrtimer_base above:
  */
 static inline
 void unlock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
@@ -1286,8 +1286,7 @@
 long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
 {
 	struct hrtimer_sleeper t;
-	struct timespec __user *rmtp;
-	struct timespec tu;
+	struct timespec *rmtp;
 	ktime_t time;
 
 	restart->fn = do_no_restart_syscall;
@@ -1298,14 +1297,12 @@
 	if (do_nanosleep(&t, HRTIMER_MODE_ABS))
 		return 0;
 
-	rmtp = (struct timespec __user *) restart->arg1;
+	rmtp = (struct timespec *)restart->arg1;
 	if (rmtp) {
 		time = ktime_sub(t.timer.expires, t.timer.base->get_time());
 		if (time.tv64 <= 0)
 			return 0;
-		tu = ktime_to_timespec(time);
-		if (copy_to_user(rmtp, &tu, sizeof(tu)))
-			return -EFAULT;
+		*rmtp = ktime_to_timespec(time);
 	}
 
 	restart->fn = hrtimer_nanosleep_restart;
@@ -1314,12 +1311,11 @@
 	return -ERESTART_RESTARTBLOCK;
 }
 
-long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
+long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp,
 		       const enum hrtimer_mode mode, const clockid_t clockid)
 {
 	struct restart_block *restart;
 	struct hrtimer_sleeper t;
-	struct timespec tu;
 	ktime_t rem;
 
 	hrtimer_init(&t.timer, clockid, mode);
@@ -1335,9 +1331,7 @@
 		rem = ktime_sub(t.timer.expires, t.timer.base->get_time());
 		if (rem.tv64 <= 0)
 			return 0;
-		tu = ktime_to_timespec(rem);
-		if (copy_to_user(rmtp, &tu, sizeof(tu)))
-			return -EFAULT;
+		*rmtp = ktime_to_timespec(rem);
 	}
 
 	restart = &current_thread_info()->restart_block;
@@ -1353,7 +1347,8 @@
 asmlinkage long
 sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
 {
-	struct timespec tu;
+	struct timespec tu, rmt;
+	int ret;
 
 	if (copy_from_user(&tu, rqtp, sizeof(tu)))
 		return -EFAULT;
@@ -1361,7 +1356,15 @@
 	if (!timespec_valid(&tu))
 		return -EINVAL;
 
-	return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
+	ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL,
+				CLOCK_MONOTONIC);
+
+	if (ret && rmtp) {
+		if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
+			return -EFAULT;
+	}
+
+	return ret;
 }
 
 /*
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 80eab7a..1f31422 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -29,12 +29,28 @@
 void synchronize_irq(unsigned int irq)
 {
 	struct irq_desc *desc = irq_desc + irq;
+	unsigned int status;
 
 	if (irq >= NR_IRQS)
 		return;
 
-	while (desc->status & IRQ_INPROGRESS)
-		cpu_relax();
+	do {
+		unsigned long flags;
+
+		/*
+		 * Wait until we're out of the critical section.  This might
+		 * give the wrong answer due to the lack of memory barriers.
+		 */
+		while (desc->status & IRQ_INPROGRESS)
+			cpu_relax();
+
+		/* Ok, that indicated we're done: double-check carefully. */
+		spin_lock_irqsave(&desc->lock, flags);
+		status = desc->status;
+		spin_unlock_irqrestore(&desc->lock, flags);
+
+		/* Oops, that failed? */
+	} while (status & IRQ_INPROGRESS);
 }
 EXPORT_SYMBOL(synchronize_irq);
 
diff --git a/kernel/itimer.c b/kernel/itimer.c
index 3205e8e..2fab344 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -130,7 +130,7 @@
 enum hrtimer_restart it_real_fn(struct hrtimer *timer)
 {
 	struct signal_struct *sig =
-	    container_of(timer, struct signal_struct, real_timer);
+		container_of(timer, struct signal_struct, real_timer);
 
 	send_group_sig_info(SIGALRM, SEND_SIG_PRIV, sig->tsk);
 
@@ -291,6 +291,6 @@
 		return error;
 
 	if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer)))
-		return -EFAULT; 
+		return -EFAULT;
 	return 0;
 }
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 7885269..aa74a1e 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -51,7 +51,7 @@
 
 int kexec_should_crash(struct task_struct *p)
 {
-	if (in_interrupt() || !p->pid || is_init(p) || panic_on_oops)
+	if (in_interrupt() || !p->pid || is_global_init(p) || panic_on_oops)
 		return 1;
 	return 0;
 }
@@ -785,7 +785,7 @@
 		size_t uchunk, mchunk;
 
 		page = kimage_alloc_page(image, GFP_HIGHUSER, maddr);
-		if (page == 0) {
+		if (!page) {
 			result  = -ENOMEM;
 			goto out;
 		}
@@ -844,7 +844,7 @@
 		size_t uchunk, mchunk;
 
 		page = pfn_to_page(maddr >> PAGE_SHIFT);
-		if (page == 0) {
+		if (!page) {
 			result  = -ENOMEM;
 			goto out;
 		}
@@ -1146,6 +1146,172 @@
 }
 module_init(crash_notes_memory_init)
 
+
+/*
+ * parsing the "crashkernel" commandline
+ *
+ * this code is intended to be called from architecture specific code
+ */
+
+
+/*
+ * This function parses command lines in the format
+ *
+ *   crashkernel=ramsize-range:size[,...][@offset]
+ *
+ * The function returns 0 on success and -EINVAL on failure.
+ */
+static int __init parse_crashkernel_mem(char 			*cmdline,
+					unsigned long long	system_ram,
+					unsigned long long	*crash_size,
+					unsigned long long	*crash_base)
+{
+	char *cur = cmdline, *tmp;
+
+	/* for each entry of the comma-separated list */
+	do {
+		unsigned long long start, end = ULLONG_MAX, size;
+
+		/* get the start of the range */
+		start = memparse(cur, &tmp);
+		if (cur == tmp) {
+			pr_warning("crashkernel: Memory value expected\n");
+			return -EINVAL;
+		}
+		cur = tmp;
+		if (*cur != '-') {
+			pr_warning("crashkernel: '-' expected\n");
+			return -EINVAL;
+		}
+		cur++;
+
+		/* if no ':' is here, than we read the end */
+		if (*cur != ':') {
+			end = memparse(cur, &tmp);
+			if (cur == tmp) {
+				pr_warning("crashkernel: Memory "
+						"value expected\n");
+				return -EINVAL;
+			}
+			cur = tmp;
+			if (end <= start) {
+				pr_warning("crashkernel: end <= start\n");
+				return -EINVAL;
+			}
+		}
+
+		if (*cur != ':') {
+			pr_warning("crashkernel: ':' expected\n");
+			return -EINVAL;
+		}
+		cur++;
+
+		size = memparse(cur, &tmp);
+		if (cur == tmp) {
+			pr_warning("Memory value expected\n");
+			return -EINVAL;
+		}
+		cur = tmp;
+		if (size >= system_ram) {
+			pr_warning("crashkernel: invalid size\n");
+			return -EINVAL;
+		}
+
+		/* match ? */
+		if (system_ram >= start && system_ram <= end) {
+			*crash_size = size;
+			break;
+		}
+	} while (*cur++ == ',');
+
+	if (*crash_size > 0) {
+		while (*cur != ' ' && *cur != '@')
+			cur++;
+		if (*cur == '@') {
+			cur++;
+			*crash_base = memparse(cur, &tmp);
+			if (cur == tmp) {
+				pr_warning("Memory value expected "
+						"after '@'\n");
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * That function parses "simple" (old) crashkernel command lines like
+ *
+ * 	crashkernel=size[@offset]
+ *
+ * It returns 0 on success and -EINVAL on failure.
+ */
+static int __init parse_crashkernel_simple(char 		*cmdline,
+					   unsigned long long 	*crash_size,
+					   unsigned long long 	*crash_base)
+{
+	char *cur = cmdline;
+
+	*crash_size = memparse(cmdline, &cur);
+	if (cmdline == cur) {
+		pr_warning("crashkernel: memory value expected\n");
+		return -EINVAL;
+	}
+
+	if (*cur == '@')
+		*crash_base = memparse(cur+1, &cur);
+
+	return 0;
+}
+
+/*
+ * That function is the entry point for command line parsing and should be
+ * called from the arch-specific code.
+ */
+int __init parse_crashkernel(char 		 *cmdline,
+			     unsigned long long system_ram,
+			     unsigned long long *crash_size,
+			     unsigned long long *crash_base)
+{
+	char 	*p = cmdline, *ck_cmdline = NULL;
+	char	*first_colon, *first_space;
+
+	BUG_ON(!crash_size || !crash_base);
+	*crash_size = 0;
+	*crash_base = 0;
+
+	/* find crashkernel and use the last one if there are more */
+	p = strstr(p, "crashkernel=");
+	while (p) {
+		ck_cmdline = p;
+		p = strstr(p+1, "crashkernel=");
+	}
+
+	if (!ck_cmdline)
+		return -EINVAL;
+
+	ck_cmdline += 12; /* strlen("crashkernel=") */
+
+	/*
+	 * if the commandline contains a ':', then that's the extended
+	 * syntax -- if not, it must be the classic syntax
+	 */
+	first_colon = strchr(ck_cmdline, ':');
+	first_space = strchr(ck_cmdline, ' ');
+	if (first_colon && (!first_space || first_colon < first_space))
+		return parse_crashkernel_mem(ck_cmdline, system_ram,
+				crash_size, crash_base);
+	else
+		return parse_crashkernel_simple(ck_cmdline, crash_size,
+				crash_base);
+
+	return 0;
+}
+
+
+
 void crash_save_vmcoreinfo(void)
 {
 	u32 *buf;
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index a6f1ee9..55fe0c7 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -511,11 +511,11 @@
 	int i, depth = curr->lockdep_depth;
 
 	if (!depth) {
-		printk("no locks held by %s/%d.\n", curr->comm, curr->pid);
+		printk("no locks held by %s/%d.\n", curr->comm, task_pid_nr(curr));
 		return;
 	}
 	printk("%d lock%s held by %s/%d:\n",
-		depth, depth > 1 ? "s" : "", curr->comm, curr->pid);
+		depth, depth > 1 ? "s" : "", curr->comm, task_pid_nr(curr));
 
 	for (i = 0; i < depth; i++) {
 		printk(" #%d: ", i);
@@ -904,7 +904,7 @@
 	print_kernel_version();
 	printk(  "-------------------------------------------------------\n");
 	printk("%s/%d is trying to acquire lock:\n",
-		curr->comm, curr->pid);
+		curr->comm, task_pid_nr(curr));
 	print_lock(check_source);
 	printk("\nbut task is already holding lock:\n");
 	print_lock(check_target);
@@ -1085,7 +1085,7 @@
 	print_kernel_version();
 	printk(  "------------------------------------------------------\n");
 	printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] is trying to acquire:\n",
-		curr->comm, curr->pid,
+		curr->comm, task_pid_nr(curr),
 		curr->hardirq_context, hardirq_count() >> HARDIRQ_SHIFT,
 		curr->softirq_context, softirq_count() >> SOFTIRQ_SHIFT,
 		curr->hardirqs_enabled,
@@ -1237,7 +1237,7 @@
 	print_kernel_version();
 	printk(  "---------------------------------------------\n");
 	printk("%s/%d is trying to acquire lock:\n",
-		curr->comm, curr->pid);
+		curr->comm, task_pid_nr(curr));
 	print_lock(next);
 	printk("\nbut task is already holding lock:\n");
 	print_lock(prev);
@@ -1521,7 +1521,7 @@
 }
 
 static int validate_chain(struct task_struct *curr, struct lockdep_map *lock,
-	       	struct held_lock *hlock, int chain_head, u64 chain_key)
+		struct held_lock *hlock, int chain_head, u64 chain_key)
 {
 	/*
 	 * Trylock needs to maintain the stack of held locks, but it
@@ -1641,7 +1641,7 @@
 		usage_str[prev_bit], usage_str[new_bit]);
 
 	printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] takes:\n",
-		curr->comm, curr->pid,
+		curr->comm, task_pid_nr(curr),
 		trace_hardirq_context(curr), hardirq_count() >> HARDIRQ_SHIFT,
 		trace_softirq_context(curr), softirq_count() >> SOFTIRQ_SHIFT,
 		trace_hardirqs_enabled(curr),
@@ -1694,7 +1694,7 @@
 	print_kernel_version();
 	printk(  "---------------------------------------------------------\n");
 	printk("%s/%d just changed the state of lock:\n",
-		curr->comm, curr->pid);
+		curr->comm, task_pid_nr(curr));
 	print_lock(this);
 	if (forwards)
 		printk("but this lock took another, %s-irq-unsafe lock in the past:\n", irqclass);
@@ -2487,7 +2487,7 @@
 	printk(  "[ BUG: bad unlock balance detected! ]\n");
 	printk(  "-------------------------------------\n");
 	printk("%s/%d is trying to release lock (",
-		curr->comm, curr->pid);
+		curr->comm, task_pid_nr(curr));
 	print_lockdep_cache(lock);
 	printk(") at:\n");
 	print_ip_sym(ip);
@@ -2737,7 +2737,7 @@
 	printk(  "[ BUG: bad contention detected! ]\n");
 	printk(  "---------------------------------\n");
 	printk("%s/%d is trying to contend lock (",
-		curr->comm, curr->pid);
+		curr->comm, task_pid_nr(curr));
 	print_lockdep_cache(lock);
 	printk(") at:\n");
 	print_ip_sym(ip);
@@ -3072,7 +3072,7 @@
 	printk(  "[ BUG: held lock freed! ]\n");
 	printk(  "-------------------------\n");
 	printk("%s/%d is freeing memory %p-%p, with a lock still held there!\n",
-		curr->comm, curr->pid, mem_from, mem_to-1);
+		curr->comm, task_pid_nr(curr), mem_from, mem_to-1);
 	print_lock(hlock);
 	lockdep_print_held_locks(curr);
 
@@ -3125,7 +3125,7 @@
 	printk(  "[ BUG: lock held at task exit time! ]\n");
 	printk(  "-------------------------------------\n");
 	printk("%s/%d is exiting with locks still held!\n",
-		curr->comm, curr->pid);
+		curr->comm, task_pid_nr(curr));
 	lockdep_print_held_locks(curr);
 
 	printk("\nstack backtrace:\n");
diff --git a/kernel/marker.c b/kernel/marker.c
new file mode 100644
index 0000000..ccb48d9
--- /dev/null
+++ b/kernel/marker.c
@@ -0,0 +1,525 @@
+/*
+ * Copyright (C) 2007 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/jhash.h>
+#include <linux/list.h>
+#include <linux/rcupdate.h>
+#include <linux/marker.h>
+#include <linux/err.h>
+
+extern struct marker __start___markers[];
+extern struct marker __stop___markers[];
+
+/*
+ * module_mutex nests inside markers_mutex. Markers mutex protects the builtin
+ * and module markers, the hash table and deferred_sync.
+ */
+static DEFINE_MUTEX(markers_mutex);
+
+/*
+ * Marker deferred synchronization.
+ * Upon marker probe_unregister, we delay call to synchronize_sched() to
+ * accelerate mass unregistration (only when there is no more reference to a
+ * given module do we call synchronize_sched()). However, we need to make sure
+ * every critical region has ended before we re-arm a marker that has been
+ * unregistered and then registered back with a different probe data.
+ */
+static int deferred_sync;
+
+/*
+ * Marker hash table, containing the active markers.
+ * Protected by module_mutex.
+ */
+#define MARKER_HASH_BITS 6
+#define MARKER_TABLE_SIZE (1 << MARKER_HASH_BITS)
+
+struct marker_entry {
+	struct hlist_node hlist;
+	char *format;
+	marker_probe_func *probe;
+	void *private;
+	int refcount;	/* Number of times armed. 0 if disarmed. */
+	char name[0];	/* Contains name'\0'format'\0' */
+};
+
+static struct hlist_head marker_table[MARKER_TABLE_SIZE];
+
+/**
+ * __mark_empty_function - Empty probe callback
+ * @mdata: pointer of type const struct marker
+ * @fmt: format string
+ * @...: variable argument list
+ *
+ * Empty callback provided as a probe to the markers. By providing this to a
+ * disabled marker, we make sure the  execution flow is always valid even
+ * though the function pointer change and the marker enabling are two distinct
+ * operations that modifies the execution flow of preemptible code.
+ */
+void __mark_empty_function(const struct marker *mdata, void *private,
+	const char *fmt, ...)
+{
+}
+EXPORT_SYMBOL_GPL(__mark_empty_function);
+
+/*
+ * Get marker if the marker is present in the marker hash table.
+ * Must be called with markers_mutex held.
+ * Returns NULL if not present.
+ */
+static struct marker_entry *get_marker(const char *name)
+{
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct marker_entry *e;
+	u32 hash = jhash(name, strlen(name), 0);
+
+	head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
+	hlist_for_each_entry(e, node, head, hlist) {
+		if (!strcmp(name, e->name))
+			return e;
+	}
+	return NULL;
+}
+
+/*
+ * Add the marker to the marker hash table. Must be called with markers_mutex
+ * held.
+ */
+static int add_marker(const char *name, const char *format,
+	marker_probe_func *probe, void *private)
+{
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct marker_entry *e;
+	size_t name_len = strlen(name) + 1;
+	size_t format_len = 0;
+	u32 hash = jhash(name, name_len-1, 0);
+
+	if (format)
+		format_len = strlen(format) + 1;
+	head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
+	hlist_for_each_entry(e, node, head, hlist) {
+		if (!strcmp(name, e->name)) {
+			printk(KERN_NOTICE
+				"Marker %s busy, probe %p already installed\n",
+				name, e->probe);
+			return -EBUSY;	/* Already there */
+		}
+	}
+	/*
+	 * Using kmalloc here to allocate a variable length element. Could
+	 * cause some memory fragmentation if overused.
+	 */
+	e = kmalloc(sizeof(struct marker_entry) + name_len + format_len,
+			GFP_KERNEL);
+	if (!e)
+		return -ENOMEM;
+	memcpy(&e->name[0], name, name_len);
+	if (format) {
+		e->format = &e->name[name_len];
+		memcpy(e->format, format, format_len);
+		trace_mark(core_marker_format, "name %s format %s",
+				e->name, e->format);
+	} else
+		e->format = NULL;
+	e->probe = probe;
+	e->private = private;
+	e->refcount = 0;
+	hlist_add_head(&e->hlist, head);
+	return 0;
+}
+
+/*
+ * Remove the marker from the marker hash table. Must be called with mutex_lock
+ * held.
+ */
+static void *remove_marker(const char *name)
+{
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct marker_entry *e;
+	int found = 0;
+	size_t len = strlen(name) + 1;
+	void *private = NULL;
+	u32 hash = jhash(name, len-1, 0);
+
+	head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
+	hlist_for_each_entry(e, node, head, hlist) {
+		if (!strcmp(name, e->name)) {
+			found = 1;
+			break;
+		}
+	}
+	if (found) {
+		private = e->private;
+		hlist_del(&e->hlist);
+		kfree(e);
+	}
+	return private;
+}
+
+/*
+ * Set the mark_entry format to the format found in the element.
+ */
+static int marker_set_format(struct marker_entry **entry, const char *format)
+{
+	struct marker_entry *e;
+	size_t name_len = strlen((*entry)->name) + 1;
+	size_t format_len = strlen(format) + 1;
+
+	e = kmalloc(sizeof(struct marker_entry) + name_len + format_len,
+			GFP_KERNEL);
+	if (!e)
+		return -ENOMEM;
+	memcpy(&e->name[0], (*entry)->name, name_len);
+	e->format = &e->name[name_len];
+	memcpy(e->format, format, format_len);
+	e->probe = (*entry)->probe;
+	e->private = (*entry)->private;
+	e->refcount = (*entry)->refcount;
+	hlist_add_before(&e->hlist, &(*entry)->hlist);
+	hlist_del(&(*entry)->hlist);
+	kfree(*entry);
+	*entry = e;
+	trace_mark(core_marker_format, "name %s format %s",
+			e->name, e->format);
+	return 0;
+}
+
+/*
+ * Sets the probe callback corresponding to one marker.
+ */
+static int set_marker(struct marker_entry **entry, struct marker *elem)
+{
+	int ret;
+	WARN_ON(strcmp((*entry)->name, elem->name) != 0);
+
+	if ((*entry)->format) {
+		if (strcmp((*entry)->format, elem->format) != 0) {
+			printk(KERN_NOTICE
+				"Format mismatch for probe %s "
+				"(%s), marker (%s)\n",
+				(*entry)->name,
+				(*entry)->format,
+				elem->format);
+			return -EPERM;
+		}
+	} else {
+		ret = marker_set_format(entry, elem->format);
+		if (ret)
+			return ret;
+	}
+	elem->call = (*entry)->probe;
+	elem->private = (*entry)->private;
+	elem->state = 1;
+	return 0;
+}
+
+/*
+ * Disable a marker and its probe callback.
+ * Note: only after a synchronize_sched() issued after setting elem->call to the
+ * empty function insures that the original callback is not used anymore. This
+ * insured by preemption disabling around the call site.
+ */
+static void disable_marker(struct marker *elem)
+{
+	elem->state = 0;
+	elem->call = __mark_empty_function;
+	/*
+	 * Leave the private data and id there, because removal is racy and
+	 * should be done only after a synchronize_sched(). These are never used
+	 * until the next initialization anyway.
+	 */
+}
+
+/**
+ * marker_update_probe_range - Update a probe range
+ * @begin: beginning of the range
+ * @end: end of the range
+ * @probe_module: module address of the probe being updated
+ * @refcount: number of references left to the given probe_module (out)
+ *
+ * Updates the probe callback corresponding to a range of markers.
+ * Must be called with markers_mutex held.
+ */
+void marker_update_probe_range(struct marker *begin,
+	struct marker *end, struct module *probe_module,
+	int *refcount)
+{
+	struct marker *iter;
+	struct marker_entry *mark_entry;
+
+	for (iter = begin; iter < end; iter++) {
+		mark_entry = get_marker(iter->name);
+		if (mark_entry && mark_entry->refcount) {
+			set_marker(&mark_entry, iter);
+			/*
+			 * ignore error, continue
+			 */
+			if (probe_module)
+				if (probe_module ==
+			__module_text_address((unsigned long)mark_entry->probe))
+					(*refcount)++;
+		} else {
+			disable_marker(iter);
+		}
+	}
+}
+
+/*
+ * Update probes, removing the faulty probes.
+ * Issues a synchronize_sched() when no reference to the module passed
+ * as parameter is found in the probes so the probe module can be
+ * safely unloaded from now on.
+ */
+static void marker_update_probes(struct module *probe_module)
+{
+	int refcount = 0;
+
+	mutex_lock(&markers_mutex);
+	/* Core kernel markers */
+	marker_update_probe_range(__start___markers,
+			__stop___markers, probe_module, &refcount);
+	/* Markers in modules. */
+	module_update_markers(probe_module, &refcount);
+	if (probe_module && refcount == 0) {
+		synchronize_sched();
+		deferred_sync = 0;
+	}
+	mutex_unlock(&markers_mutex);
+}
+
+/**
+ * marker_probe_register -  Connect a probe to a marker
+ * @name: marker name
+ * @format: format string
+ * @probe: probe handler
+ * @private: probe private data
+ *
+ * private data must be a valid allocated memory address, or NULL.
+ * Returns 0 if ok, error value on error.
+ */
+int marker_probe_register(const char *name, const char *format,
+			marker_probe_func *probe, void *private)
+{
+	struct marker_entry *entry;
+	int ret = 0, need_update = 0;
+
+	mutex_lock(&markers_mutex);
+	entry = get_marker(name);
+	if (entry && entry->refcount) {
+		ret = -EBUSY;
+		goto end;
+	}
+	if (deferred_sync) {
+		synchronize_sched();
+		deferred_sync = 0;
+	}
+	ret = add_marker(name, format, probe, private);
+	if (ret)
+		goto end;
+	need_update = 1;
+end:
+	mutex_unlock(&markers_mutex);
+	if (need_update)
+		marker_update_probes(NULL);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(marker_probe_register);
+
+/**
+ * marker_probe_unregister -  Disconnect a probe from a marker
+ * @name: marker name
+ *
+ * Returns the private data given to marker_probe_register, or an ERR_PTR().
+ */
+void *marker_probe_unregister(const char *name)
+{
+	struct module *probe_module;
+	struct marker_entry *entry;
+	void *private;
+	int need_update = 0;
+
+	mutex_lock(&markers_mutex);
+	entry = get_marker(name);
+	if (!entry) {
+		private = ERR_PTR(-ENOENT);
+		goto end;
+	}
+	entry->refcount = 0;
+	/* In what module is the probe handler ? */
+	probe_module = __module_text_address((unsigned long)entry->probe);
+	private = remove_marker(name);
+	deferred_sync = 1;
+	need_update = 1;
+end:
+	mutex_unlock(&markers_mutex);
+	if (need_update)
+		marker_update_probes(probe_module);
+	return private;
+}
+EXPORT_SYMBOL_GPL(marker_probe_unregister);
+
+/**
+ * marker_probe_unregister_private_data -  Disconnect a probe from a marker
+ * @private: probe private data
+ *
+ * Unregister a marker by providing the registered private data.
+ * Returns the private data given to marker_probe_register, or an ERR_PTR().
+ */
+void *marker_probe_unregister_private_data(void *private)
+{
+	struct module *probe_module;
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct marker_entry *entry;
+	int found = 0;
+	unsigned int i;
+	int need_update = 0;
+
+	mutex_lock(&markers_mutex);
+	for (i = 0; i < MARKER_TABLE_SIZE; i++) {
+		head = &marker_table[i];
+		hlist_for_each_entry(entry, node, head, hlist) {
+			if (entry->private == private) {
+				found = 1;
+				goto iter_end;
+			}
+		}
+	}
+iter_end:
+	if (!found) {
+		private = ERR_PTR(-ENOENT);
+		goto end;
+	}
+	entry->refcount = 0;
+	/* In what module is the probe handler ? */
+	probe_module = __module_text_address((unsigned long)entry->probe);
+	private = remove_marker(entry->name);
+	deferred_sync = 1;
+	need_update = 1;
+end:
+	mutex_unlock(&markers_mutex);
+	if (need_update)
+		marker_update_probes(probe_module);
+	return private;
+}
+EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data);
+
+/**
+ * marker_arm - Arm a marker
+ * @name: marker name
+ *
+ * Activate a marker. It keeps a reference count of the number of
+ * arming/disarming done.
+ * Returns 0 if ok, error value on error.
+ */
+int marker_arm(const char *name)
+{
+	struct marker_entry *entry;
+	int ret = 0, need_update = 0;
+
+	mutex_lock(&markers_mutex);
+	entry = get_marker(name);
+	if (!entry) {
+		ret = -ENOENT;
+		goto end;
+	}
+	/*
+	 * Only need to update probes when refcount passes from 0 to 1.
+	 */
+	if (entry->refcount++)
+		goto end;
+	need_update = 1;
+end:
+	mutex_unlock(&markers_mutex);
+	if (need_update)
+		marker_update_probes(NULL);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(marker_arm);
+
+/**
+ * marker_disarm - Disarm a marker
+ * @name: marker name
+ *
+ * Disarm a marker. It keeps a reference count of the number of arming/disarming
+ * done.
+ * Returns 0 if ok, error value on error.
+ */
+int marker_disarm(const char *name)
+{
+	struct marker_entry *entry;
+	int ret = 0, need_update = 0;
+
+	mutex_lock(&markers_mutex);
+	entry = get_marker(name);
+	if (!entry) {
+		ret = -ENOENT;
+		goto end;
+	}
+	/*
+	 * Only permit decrement refcount if higher than 0.
+	 * Do probe update only on 1 -> 0 transition.
+	 */
+	if (entry->refcount) {
+		if (--entry->refcount)
+			goto end;
+	} else {
+		ret = -EPERM;
+		goto end;
+	}
+	need_update = 1;
+end:
+	mutex_unlock(&markers_mutex);
+	if (need_update)
+		marker_update_probes(NULL);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(marker_disarm);
+
+/**
+ * marker_get_private_data - Get a marker's probe private data
+ * @name: marker name
+ *
+ * Returns the private data pointer, or an ERR_PTR.
+ * The private data pointer should _only_ be dereferenced if the caller is the
+ * owner of the data, or its content could vanish. This is mostly used to
+ * confirm that a caller is the owner of a registered probe.
+ */
+void *marker_get_private_data(const char *name)
+{
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct marker_entry *e;
+	size_t name_len = strlen(name) + 1;
+	u32 hash = jhash(name, name_len-1, 0);
+	int found = 0;
+
+	head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
+	hlist_for_each_entry(e, node, head, hlist) {
+		if (!strcmp(name, e->name)) {
+			found = 1;
+			return e->private;
+		}
+	}
+	return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL_GPL(marker_get_private_data);
diff --git a/kernel/module.c b/kernel/module.c
index a389b42..3202c99 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -105,7 +105,7 @@
 	do_exit(code);
 }
 EXPORT_SYMBOL(__module_put_and_exit);
-	
+
 /* Find a module section: 0 means not found. */
 static unsigned int find_sec(Elf_Ehdr *hdr,
 			     Elf_Shdr *sechdrs,
@@ -179,7 +179,7 @@
 	struct module *mod;
 	const struct kernel_symbol *ks;
 
-	/* Core kernel first. */ 
+	/* Core kernel first. */
 	*owner = NULL;
 	ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab);
 	if (ks) {
@@ -231,7 +231,7 @@
 		return ks->value;
 	}
 
-	/* Now try modules. */ 
+	/* Now try modules. */
 	list_for_each_entry(mod, &modules, list) {
 		*owner = mod;
 		ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms);
@@ -285,7 +285,7 @@
 		}
 	}
 	DEBUGP("Failed to find symbol %s\n", name);
- 	return 0;
+	return 0;
 }
 
 /* Search for module by name: must hold module_mutex. */
@@ -441,7 +441,7 @@
 	}
 
 	return 0;
-}	
+}
 __initcall(percpu_modinit);
 #else /* ... !CONFIG_SMP */
 static inline void *percpu_modalloc(unsigned long size, unsigned long align,
@@ -483,8 +483,8 @@
 }                                                                     \
 static void free_modinfo_##field(struct module *mod)                  \
 {                                                                     \
-        kfree(mod->field);                                            \
-        mod->field = NULL;                                            \
+	kfree(mod->field);                                            \
+	mod->field = NULL;                                            \
 }                                                                     \
 static struct module_attribute modinfo_##field = {                    \
 	.attr = { .name = __stringify(field), .mode = 0444 },         \
@@ -990,7 +990,7 @@
 	struct module_sect_attrs *sect_attrs;
 	struct module_sect_attr *sattr;
 	struct attribute **gattr;
-	
+
 	/* Count loaded sections and allocate structures */
 	for (i = 0; i < nsect; i++)
 		if (sechdrs[i].sh_flags & SHF_ALLOC)
@@ -1348,14 +1348,14 @@
 	const unsigned long *crc;
 
 	for (i = 0; i < mod->num_syms; i++)
-	        if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) {
+		if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) {
 			name = mod->syms[i].name;
 			ret = -ENOEXEC;
 			goto dup;
 		}
 
 	for (i = 0; i < mod->num_gpl_syms; i++)
-	        if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) {
+		if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) {
 			name = mod->gpl_syms[i].name;
 			ret = -ENOEXEC;
 			goto dup;
@@ -1673,6 +1673,8 @@
 	unsigned int unusedcrcindex;
 	unsigned int unusedgplindex;
 	unsigned int unusedgplcrcindex;
+	unsigned int markersindex;
+	unsigned int markersstringsindex;
 	struct module *mod;
 	long err = 0;
 	void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -1929,7 +1931,7 @@
 		mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr;
 
 #ifdef CONFIG_MODVERSIONS
-	if ((mod->num_syms && !crcindex) || 
+	if ((mod->num_syms && !crcindex) ||
 	    (mod->num_gpl_syms && !gplcrcindex) ||
 	    (mod->num_gpl_future_syms && !gplfuturecrcindex) ||
 	    (mod->num_unused_syms && !unusedcrcindex) ||
@@ -1939,6 +1941,9 @@
 		add_taint_module(mod, TAINT_FORCED_MODULE);
 	}
 #endif
+	markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");
+ 	markersstringsindex = find_sec(hdr, sechdrs, secstrings,
+					"__markers_strings");
 
 	/* Now do relocations. */
 	for (i = 1; i < hdr->e_shnum; i++) {
@@ -1961,6 +1966,11 @@
 		if (err < 0)
 			goto cleanup;
 	}
+#ifdef CONFIG_MARKERS
+	mod->markers = (void *)sechdrs[markersindex].sh_addr;
+	mod->num_markers =
+		sechdrs[markersindex].sh_size / sizeof(*mod->markers);
+#endif
 
         /* Find duplicate symbols */
 	err = verify_export_symbols(mod);
@@ -1979,6 +1989,11 @@
 
 	add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
 
+#ifdef CONFIG_MARKERS
+	if (!mod->taints)
+		marker_update_probe_range(mod->markers,
+			mod->markers + mod->num_markers, NULL, NULL);
+#endif
 	err = module_finalize(hdr, sechdrs, mod);
 	if (err < 0)
 		goto cleanup;
@@ -2016,7 +2031,7 @@
 	if (err < 0)
 		goto arch_cleanup;
 
-	err = mod_sysfs_setup(mod, 
+	err = mod_sysfs_setup(mod,
 			      (struct kernel_param *)
 			      sechdrs[setupindex].sh_addr,
 			      sechdrs[setupindex].sh_size
@@ -2028,8 +2043,8 @@
 
 	/* Size of section 0 is 0, so this works well if no unwind info. */
 	mod->unwind_info = unwind_add_table(mod,
-	                                    (void *)sechdrs[unwindex].sh_addr,
-	                                    sechdrs[unwindex].sh_size);
+					    (void *)sechdrs[unwindex].sh_addr,
+					    sechdrs[unwindex].sh_size);
 
 	/* Get rid of temporary copy */
 	vfree(hdr);
@@ -2146,7 +2161,7 @@
  */
 static inline int is_arm_mapping_symbol(const char *str)
 {
-	return str[0] == '$' && strchr("atd", str[1]) 
+	return str[0] == '$' && strchr("atd", str[1])
 	       && (str[2] == '\0' || str[2] == '.');
 }
 
@@ -2161,11 +2176,11 @@
 	/* At worse, next value is at end of module */
 	if (within(addr, mod->module_init, mod->init_size))
 		nextval = (unsigned long)mod->module_init+mod->init_text_size;
-	else 
+	else
 		nextval = (unsigned long)mod->module_core+mod->core_text_size;
 
 	/* Scan for closest preceeding symbol, and next symbol. (ELF
-           starts real symbols at 1). */
+	   starts real symbols at 1). */
 	for (i = 1; i < mod->num_symtab; i++) {
 		if (mod->symtab[i].st_shndx == SHN_UNDEF)
 			continue;
@@ -2407,7 +2422,7 @@
 	list_for_each_entry(mod, &modules, list) {
 		if (mod->num_exentries == 0)
 			continue;
-				
+
 		e = search_extable(mod->extable,
 				   mod->extable + mod->num_exentries - 1,
 				   addr);
@@ -2417,7 +2432,7 @@
 	preempt_enable();
 
 	/* Now, if we found one, we are running inside it now, hence
-           we cannot unload the module, hence no refcnt needed. */
+	   we cannot unload the module, hence no refcnt needed. */
 	return e;
 }
 
@@ -2570,3 +2585,18 @@
 void struct_module(struct module *mod) { return; }
 EXPORT_SYMBOL(struct_module);
 #endif
+
+#ifdef CONFIG_MARKERS
+void module_update_markers(struct module *probe_module, int *refcount)
+{
+	struct module *mod;
+
+	mutex_lock(&module_mutex);
+	list_for_each_entry(mod, &modules, list)
+		if (!mod->taints)
+			marker_update_probe_range(mod->markers,
+				mod->markers + mod->num_markers,
+				probe_module, refcount);
+	mutex_unlock(&module_mutex);
+}
+#endif
diff --git a/kernel/notifier.c b/kernel/notifier.c
new file mode 100644
index 0000000..4253f47
--- /dev/null
+++ b/kernel/notifier.c
@@ -0,0 +1,539 @@
+#include <linux/kdebug.h>
+#include <linux/kprobes.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/rcupdate.h>
+#include <linux/vmalloc.h>
+
+/*
+ *	Notifier list for kernel code which wants to be called
+ *	at shutdown. This is used to stop any idling DMA operations
+ *	and the like.
+ */
+BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
+
+/*
+ *	Notifier chain core routines.  The exported routines below
+ *	are layered on top of these, with appropriate locking added.
+ */
+
+static int notifier_chain_register(struct notifier_block **nl,
+		struct notifier_block *n)
+{
+	while ((*nl) != NULL) {
+		if (n->priority > (*nl)->priority)
+			break;
+		nl = &((*nl)->next);
+	}
+	n->next = *nl;
+	rcu_assign_pointer(*nl, n);
+	return 0;
+}
+
+static int notifier_chain_unregister(struct notifier_block **nl,
+		struct notifier_block *n)
+{
+	while ((*nl) != NULL) {
+		if ((*nl) == n) {
+			rcu_assign_pointer(*nl, n->next);
+			return 0;
+		}
+		nl = &((*nl)->next);
+	}
+	return -ENOENT;
+}
+
+/**
+ * notifier_call_chain - Informs the registered notifiers about an event.
+ *	@nl:		Pointer to head of the blocking notifier chain
+ *	@val:		Value passed unmodified to notifier function
+ *	@v:		Pointer passed unmodified to notifier function
+ *	@nr_to_call:	Number of notifier functions to be called. Don't care
+ *			value of this parameter is -1.
+ *	@nr_calls:	Records the number of notifications sent. Don't care
+ *			value of this field is NULL.
+ *	@returns:	notifier_call_chain returns the value returned by the
+ *			last notifier function called.
+ */
+static int __kprobes notifier_call_chain(struct notifier_block **nl,
+					unsigned long val, void *v,
+					int nr_to_call,	int *nr_calls)
+{
+	int ret = NOTIFY_DONE;
+	struct notifier_block *nb, *next_nb;
+
+	nb = rcu_dereference(*nl);
+
+	while (nb && nr_to_call) {
+		next_nb = rcu_dereference(nb->next);
+		ret = nb->notifier_call(nb, val, v);
+
+		if (nr_calls)
+			(*nr_calls)++;
+
+		if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)
+			break;
+		nb = next_nb;
+		nr_to_call--;
+	}
+	return ret;
+}
+
+/*
+ *	Atomic notifier chain routines.  Registration and unregistration
+ *	use a spinlock, and call_chain is synchronized by RCU (no locks).
+ */
+
+/**
+ *	atomic_notifier_chain_register - Add notifier to an atomic notifier chain
+ *	@nh: Pointer to head of the atomic notifier chain
+ *	@n: New entry in notifier chain
+ *
+ *	Adds a notifier to an atomic notifier chain.
+ *
+ *	Currently always returns zero.
+ */
+int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
+		struct notifier_block *n)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&nh->lock, flags);
+	ret = notifier_chain_register(&nh->head, n);
+	spin_unlock_irqrestore(&nh->lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
+
+/**
+ *	atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
+ *	@nh: Pointer to head of the atomic notifier chain
+ *	@n: Entry to remove from notifier chain
+ *
+ *	Removes a notifier from an atomic notifier chain.
+ *
+ *	Returns zero on success or %-ENOENT on failure.
+ */
+int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
+		struct notifier_block *n)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&nh->lock, flags);
+	ret = notifier_chain_unregister(&nh->head, n);
+	spin_unlock_irqrestore(&nh->lock, flags);
+	synchronize_rcu();
+	return ret;
+}
+EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
+
+/**
+ *	__atomic_notifier_call_chain - Call functions in an atomic notifier chain
+ *	@nh: Pointer to head of the atomic notifier chain
+ *	@val: Value passed unmodified to notifier function
+ *	@v: Pointer passed unmodified to notifier function
+ *	@nr_to_call: See the comment for notifier_call_chain.
+ *	@nr_calls: See the comment for notifier_call_chain.
+ *
+ *	Calls each function in a notifier chain in turn.  The functions
+ *	run in an atomic context, so they must not block.
+ *	This routine uses RCU to synchronize with changes to the chain.
+ *
+ *	If the return value of the notifier can be and'ed
+ *	with %NOTIFY_STOP_MASK then atomic_notifier_call_chain()
+ *	will return immediately, with the return value of
+ *	the notifier function which halted execution.
+ *	Otherwise the return value is the return value
+ *	of the last notifier function called.
+ */
+int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh,
+					unsigned long val, void *v,
+					int nr_to_call, int *nr_calls)
+{
+	int ret;
+
+	rcu_read_lock();
+	ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
+	rcu_read_unlock();
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__atomic_notifier_call_chain);
+
+int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh,
+		unsigned long val, void *v)
+{
+	return __atomic_notifier_call_chain(nh, val, v, -1, NULL);
+}
+EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
+
+/*
+ *	Blocking notifier chain routines.  All access to the chain is
+ *	synchronized by an rwsem.
+ */
+
+/**
+ *	blocking_notifier_chain_register - Add notifier to a blocking notifier chain
+ *	@nh: Pointer to head of the blocking notifier chain
+ *	@n: New entry in notifier chain
+ *
+ *	Adds a notifier to a blocking notifier chain.
+ *	Must be called in process context.
+ *
+ *	Currently always returns zero.
+ */
+int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
+		struct notifier_block *n)
+{
+	int ret;
+
+	/*
+	 * This code gets used during boot-up, when task switching is
+	 * not yet working and interrupts must remain disabled.  At
+	 * such times we must not call down_write().
+	 */
+	if (unlikely(system_state == SYSTEM_BOOTING))
+		return notifier_chain_register(&nh->head, n);
+
+	down_write(&nh->rwsem);
+	ret = notifier_chain_register(&nh->head, n);
+	up_write(&nh->rwsem);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
+
+/**
+ *	blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
+ *	@nh: Pointer to head of the blocking notifier chain
+ *	@n: Entry to remove from notifier chain
+ *
+ *	Removes a notifier from a blocking notifier chain.
+ *	Must be called from process context.
+ *
+ *	Returns zero on success or %-ENOENT on failure.
+ */
+int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
+		struct notifier_block *n)
+{
+	int ret;
+
+	/*
+	 * This code gets used during boot-up, when task switching is
+	 * not yet working and interrupts must remain disabled.  At
+	 * such times we must not call down_write().
+	 */
+	if (unlikely(system_state == SYSTEM_BOOTING))
+		return notifier_chain_unregister(&nh->head, n);
+
+	down_write(&nh->rwsem);
+	ret = notifier_chain_unregister(&nh->head, n);
+	up_write(&nh->rwsem);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
+
+/**
+ *	__blocking_notifier_call_chain - Call functions in a blocking notifier chain
+ *	@nh: Pointer to head of the blocking notifier chain
+ *	@val: Value passed unmodified to notifier function
+ *	@v: Pointer passed unmodified to notifier function
+ *	@nr_to_call: See comment for notifier_call_chain.
+ *	@nr_calls: See comment for notifier_call_chain.
+ *
+ *	Calls each function in a notifier chain in turn.  The functions
+ *	run in a process context, so they are allowed to block.
+ *
+ *	If the return value of the notifier can be and'ed
+ *	with %NOTIFY_STOP_MASK then blocking_notifier_call_chain()
+ *	will return immediately, with the return value of
+ *	the notifier function which halted execution.
+ *	Otherwise the return value is the return value
+ *	of the last notifier function called.
+ */
+int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
+				   unsigned long val, void *v,
+				   int nr_to_call, int *nr_calls)
+{
+	int ret = NOTIFY_DONE;
+
+	/*
+	 * We check the head outside the lock, but if this access is
+	 * racy then it does not matter what the result of the test
+	 * is, we re-check the list after having taken the lock anyway:
+	 */
+	if (rcu_dereference(nh->head)) {
+		down_read(&nh->rwsem);
+		ret = notifier_call_chain(&nh->head, val, v, nr_to_call,
+					nr_calls);
+		up_read(&nh->rwsem);
+	}
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__blocking_notifier_call_chain);
+
+int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
+		unsigned long val, void *v)
+{
+	return __blocking_notifier_call_chain(nh, val, v, -1, NULL);
+}
+EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
+
+/*
+ *	Raw notifier chain routines.  There is no protection;
+ *	the caller must provide it.  Use at your own risk!
+ */
+
+/**
+ *	raw_notifier_chain_register - Add notifier to a raw notifier chain
+ *	@nh: Pointer to head of the raw notifier chain
+ *	@n: New entry in notifier chain
+ *
+ *	Adds a notifier to a raw notifier chain.
+ *	All locking must be provided by the caller.
+ *
+ *	Currently always returns zero.
+ */
+int raw_notifier_chain_register(struct raw_notifier_head *nh,
+		struct notifier_block *n)
+{
+	return notifier_chain_register(&nh->head, n);
+}
+EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
+
+/**
+ *	raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
+ *	@nh: Pointer to head of the raw notifier chain
+ *	@n: Entry to remove from notifier chain
+ *
+ *	Removes a notifier from a raw notifier chain.
+ *	All locking must be provided by the caller.
+ *
+ *	Returns zero on success or %-ENOENT on failure.
+ */
+int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
+		struct notifier_block *n)
+{
+	return notifier_chain_unregister(&nh->head, n);
+}
+EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
+
+/**
+ *	__raw_notifier_call_chain - Call functions in a raw notifier chain
+ *	@nh: Pointer to head of the raw notifier chain
+ *	@val: Value passed unmodified to notifier function
+ *	@v: Pointer passed unmodified to notifier function
+ *	@nr_to_call: See comment for notifier_call_chain.
+ *	@nr_calls: See comment for notifier_call_chain
+ *
+ *	Calls each function in a notifier chain in turn.  The functions
+ *	run in an undefined context.
+ *	All locking must be provided by the caller.
+ *
+ *	If the return value of the notifier can be and'ed
+ *	with %NOTIFY_STOP_MASK then raw_notifier_call_chain()
+ *	will return immediately, with the return value of
+ *	the notifier function which halted execution.
+ *	Otherwise the return value is the return value
+ *	of the last notifier function called.
+ */
+int __raw_notifier_call_chain(struct raw_notifier_head *nh,
+			      unsigned long val, void *v,
+			      int nr_to_call, int *nr_calls)
+{
+	return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
+}
+EXPORT_SYMBOL_GPL(__raw_notifier_call_chain);
+
+int raw_notifier_call_chain(struct raw_notifier_head *nh,
+		unsigned long val, void *v)
+{
+	return __raw_notifier_call_chain(nh, val, v, -1, NULL);
+}
+EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
+
+/*
+ *	SRCU notifier chain routines.    Registration and unregistration
+ *	use a mutex, and call_chain is synchronized by SRCU (no locks).
+ */
+
+/**
+ *	srcu_notifier_chain_register - Add notifier to an SRCU notifier chain
+ *	@nh: Pointer to head of the SRCU notifier chain
+ *	@n: New entry in notifier chain
+ *
+ *	Adds a notifier to an SRCU notifier chain.
+ *	Must be called in process context.
+ *
+ *	Currently always returns zero.
+ */
+int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
+		struct notifier_block *n)
+{
+	int ret;
+
+	/*
+	 * This code gets used during boot-up, when task switching is
+	 * not yet working and interrupts must remain disabled.  At
+	 * such times we must not call mutex_lock().
+	 */
+	if (unlikely(system_state == SYSTEM_BOOTING))
+		return notifier_chain_register(&nh->head, n);
+
+	mutex_lock(&nh->mutex);
+	ret = notifier_chain_register(&nh->head, n);
+	mutex_unlock(&nh->mutex);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);
+
+/**
+ *	srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain
+ *	@nh: Pointer to head of the SRCU notifier chain
+ *	@n: Entry to remove from notifier chain
+ *
+ *	Removes a notifier from an SRCU notifier chain.
+ *	Must be called from process context.
+ *
+ *	Returns zero on success or %-ENOENT on failure.
+ */
+int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
+		struct notifier_block *n)
+{
+	int ret;
+
+	/*
+	 * This code gets used during boot-up, when task switching is
+	 * not yet working and interrupts must remain disabled.  At
+	 * such times we must not call mutex_lock().
+	 */
+	if (unlikely(system_state == SYSTEM_BOOTING))
+		return notifier_chain_unregister(&nh->head, n);
+
+	mutex_lock(&nh->mutex);
+	ret = notifier_chain_unregister(&nh->head, n);
+	mutex_unlock(&nh->mutex);
+	synchronize_srcu(&nh->srcu);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);
+
+/**
+ *	__srcu_notifier_call_chain - Call functions in an SRCU notifier chain
+ *	@nh: Pointer to head of the SRCU notifier chain
+ *	@val: Value passed unmodified to notifier function
+ *	@v: Pointer passed unmodified to notifier function
+ *	@nr_to_call: See comment for notifier_call_chain.
+ *	@nr_calls: See comment for notifier_call_chain
+ *
+ *	Calls each function in a notifier chain in turn.  The functions
+ *	run in a process context, so they are allowed to block.
+ *
+ *	If the return value of the notifier can be and'ed
+ *	with %NOTIFY_STOP_MASK then srcu_notifier_call_chain()
+ *	will return immediately, with the return value of
+ *	the notifier function which halted execution.
+ *	Otherwise the return value is the return value
+ *	of the last notifier function called.
+ */
+int __srcu_notifier_call_chain(struct srcu_notifier_head *nh,
+			       unsigned long val, void *v,
+			       int nr_to_call, int *nr_calls)
+{
+	int ret;
+	int idx;
+
+	idx = srcu_read_lock(&nh->srcu);
+	ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
+	srcu_read_unlock(&nh->srcu, idx);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__srcu_notifier_call_chain);
+
+int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
+		unsigned long val, void *v)
+{
+	return __srcu_notifier_call_chain(nh, val, v, -1, NULL);
+}
+EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);
+
+/**
+ *	srcu_init_notifier_head - Initialize an SRCU notifier head
+ *	@nh: Pointer to head of the srcu notifier chain
+ *
+ *	Unlike other sorts of notifier heads, SRCU notifier heads require
+ *	dynamic initialization.  Be sure to call this routine before
+ *	calling any of the other SRCU notifier routines for this head.
+ *
+ *	If an SRCU notifier head is deallocated, it must first be cleaned
+ *	up by calling srcu_cleanup_notifier_head().  Otherwise the head's
+ *	per-cpu data (used by the SRCU mechanism) will leak.
+ */
+void srcu_init_notifier_head(struct srcu_notifier_head *nh)
+{
+	mutex_init(&nh->mutex);
+	if (init_srcu_struct(&nh->srcu) < 0)
+		BUG();
+	nh->head = NULL;
+}
+EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
+
+/**
+ *	register_reboot_notifier - Register function to be called at reboot time
+ *	@nb: Info about notifier function to be called
+ *
+ *	Registers a function with the list of functions
+ *	to be called at reboot time.
+ *
+ *	Currently always returns zero, as blocking_notifier_chain_register()
+ *	always returns zero.
+ */
+int register_reboot_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&reboot_notifier_list, nb);
+}
+EXPORT_SYMBOL(register_reboot_notifier);
+
+/**
+ *	unregister_reboot_notifier - Unregister previously registered reboot notifier
+ *	@nb: Hook to be unregistered
+ *
+ *	Unregisters a previously registered reboot
+ *	notifier function.
+ *
+ *	Returns zero on success, or %-ENOENT on failure.
+ */
+int unregister_reboot_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&reboot_notifier_list, nb);
+}
+EXPORT_SYMBOL(unregister_reboot_notifier);
+
+static ATOMIC_NOTIFIER_HEAD(die_chain);
+
+int notify_die(enum die_val val, const char *str,
+	       struct pt_regs *regs, long err, int trap, int sig)
+{
+	struct die_args args = {
+		.regs	= regs,
+		.str	= str,
+		.err	= err,
+		.trapnr	= trap,
+		.signr	= sig,
+
+	};
+	return atomic_notifier_call_chain(&die_chain, val, &args);
+}
+
+int register_die_notifier(struct notifier_block *nb)
+{
+	vmalloc_sync_all();
+	return atomic_notifier_chain_register(&die_chain, nb);
+}
+EXPORT_SYMBOL_GPL(register_die_notifier);
+
+int unregister_die_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_unregister(&die_chain, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_die_notifier);
diff --git a/kernel/ns_cgroup.c b/kernel/ns_cgroup.c
new file mode 100644
index 0000000..aead4d6
--- /dev/null
+++ b/kernel/ns_cgroup.c
@@ -0,0 +1,100 @@
+/*
+ * ns_cgroup.c - namespace cgroup subsystem
+ *
+ * Copyright 2006, 2007 IBM Corp
+ */
+
+#include <linux/module.h>
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+
+struct ns_cgroup {
+	struct cgroup_subsys_state css;
+	spinlock_t lock;
+};
+
+struct cgroup_subsys ns_subsys;
+
+static inline struct ns_cgroup *cgroup_to_ns(
+		struct cgroup *cgroup)
+{
+	return container_of(cgroup_subsys_state(cgroup, ns_subsys_id),
+			    struct ns_cgroup, css);
+}
+
+int ns_cgroup_clone(struct task_struct *task)
+{
+	return cgroup_clone(task, &ns_subsys);
+}
+
+/*
+ * Rules:
+ *   1. you can only enter a cgroup which is a child of your current
+ *     cgroup
+ *   2. you can only place another process into a cgroup if
+ *     a. you have CAP_SYS_ADMIN
+ *     b. your cgroup is an ancestor of task's destination cgroup
+ *       (hence either you are in the same cgroup as task, or in an
+ *        ancestor cgroup thereof)
+ */
+static int ns_can_attach(struct cgroup_subsys *ss,
+		struct cgroup *new_cgroup, struct task_struct *task)
+{
+	struct cgroup *orig;
+
+	if (current != task) {
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		if (!cgroup_is_descendant(new_cgroup))
+			return -EPERM;
+	}
+
+	if (atomic_read(&new_cgroup->count) != 0)
+		return -EPERM;
+
+	orig = task_cgroup(task, ns_subsys_id);
+	if (orig && orig != new_cgroup->parent)
+		return -EPERM;
+
+	return 0;
+}
+
+/*
+ * Rules: you can only create a cgroup if
+ *     1. you are capable(CAP_SYS_ADMIN)
+ *     2. the target cgroup is a descendant of your own cgroup
+ */
+static struct cgroup_subsys_state *ns_create(struct cgroup_subsys *ss,
+						struct cgroup *cgroup)
+{
+	struct ns_cgroup *ns_cgroup;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return ERR_PTR(-EPERM);
+	if (!cgroup_is_descendant(cgroup))
+		return ERR_PTR(-EPERM);
+
+	ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL);
+	if (!ns_cgroup)
+		return ERR_PTR(-ENOMEM);
+	spin_lock_init(&ns_cgroup->lock);
+	return &ns_cgroup->css;
+}
+
+static void ns_destroy(struct cgroup_subsys *ss,
+			struct cgroup *cgroup)
+{
+	struct ns_cgroup *ns_cgroup;
+
+	ns_cgroup = cgroup_to_ns(cgroup);
+	kfree(ns_cgroup);
+}
+
+struct cgroup_subsys ns_subsys = {
+	.name = "ns",
+	.can_attach = ns_can_attach,
+	.create = ns_create,
+	.destroy  = ns_destroy,
+	.subsys_id = ns_subsys_id,
+};
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 049e7c0..79f871b 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -26,19 +26,6 @@
 
 struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
 
-static inline void get_nsproxy(struct nsproxy *ns)
-{
-	atomic_inc(&ns->count);
-}
-
-void get_task_namespaces(struct task_struct *tsk)
-{
-	struct nsproxy *ns = tsk->nsproxy;
-	if (ns) {
-		get_nsproxy(ns);
-	}
-}
-
 /*
  * creates a copy of "orig" with refcount 1.
  */
@@ -87,7 +74,7 @@
 		goto out_ipc;
 	}
 
-	new_nsp->pid_ns = copy_pid_ns(flags, tsk->nsproxy->pid_ns);
+	new_nsp->pid_ns = copy_pid_ns(flags, task_active_pid_ns(tsk));
 	if (IS_ERR(new_nsp->pid_ns)) {
 		err = PTR_ERR(new_nsp->pid_ns);
 		goto out_pid;
@@ -142,7 +129,8 @@
 
 	get_nsproxy(old_ns);
 
-	if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER | CLONE_NEWNET)))
+	if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
+				CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET)))
 		return 0;
 
 	if (!capable(CAP_SYS_ADMIN)) {
@@ -156,7 +144,14 @@
 		goto out;
 	}
 
+	err = ns_cgroup_clone(tsk);
+	if (err) {
+		put_nsproxy(new_ns);
+		goto out;
+	}
+
 	tsk->nsproxy = new_ns;
+
 out:
 	put_nsproxy(old_ns);
 	return err;
@@ -196,11 +191,46 @@
 
 	*new_nsp = create_new_namespaces(unshare_flags, current,
 				new_fs ? new_fs : current->fs);
-	if (IS_ERR(*new_nsp))
+	if (IS_ERR(*new_nsp)) {
 		err = PTR_ERR(*new_nsp);
+		goto out;
+	}
+
+	err = ns_cgroup_clone(current);
+	if (err)
+		put_nsproxy(*new_nsp);
+
+out:
 	return err;
 }
 
+void switch_task_namespaces(struct task_struct *p, struct nsproxy *new)
+{
+	struct nsproxy *ns;
+
+	might_sleep();
+
+	ns = p->nsproxy;
+
+	rcu_assign_pointer(p->nsproxy, new);
+
+	if (ns && atomic_dec_and_test(&ns->count)) {
+		/*
+		 * wait for others to get what they want from this nsproxy.
+		 *
+		 * cannot release this nsproxy via the call_rcu() since
+		 * put_mnt_ns() will want to sleep
+		 */
+		synchronize_rcu();
+		free_nsproxy(ns);
+	}
+}
+
+void exit_task_namespaces(struct task_struct *p)
+{
+	switch_task_namespaces(p, NULL);
+}
+
 static int __init nsproxy_cache_init(void)
 {
 	nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC);
diff --git a/kernel/panic.c b/kernel/panic.c
index f64f4c1..6f6e03e 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -56,14 +56,14 @@
  *
  *	This function never returns.
  */
- 
+
 NORET_TYPE void panic(const char * fmt, ...)
 {
 	long i;
 	static char buf[1024];
 	va_list args;
 #if defined(CONFIG_S390)
-        unsigned long caller = (unsigned long) __builtin_return_address(0);
+	unsigned long caller = (unsigned long) __builtin_return_address(0);
 #endif
 
 	/*
@@ -128,7 +128,7 @@
 	}
 #endif
 #if defined(CONFIG_S390)
-        disabled_wait(caller);
+	disabled_wait(caller);
 #endif
 	local_irq_enable();
 	for (i = 0;;) {
@@ -148,13 +148,13 @@
  *  'F' - Module has been forcibly loaded.
  *  'S' - SMP with CPUs not designed for SMP.
  *  'R' - User forced a module unload.
- *  'M' - Machine had a machine check experience.
+ *  'M' - System experienced a machine check exception.
  *  'B' - System has hit bad_page.
  *  'U' - Userspace-defined naughtiness.
  *
  *	The string is overwritten by the next call to print_taint().
  */
- 
+
 const char *print_tainted(void)
 {
 	static char buf[20];
@@ -164,7 +164,7 @@
 			tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
 			tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
 			tainted & TAINT_FORCED_RMMOD ? 'R' : ' ',
- 			tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
+			tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
 			tainted & TAINT_BAD_PAGE ? 'B' : ' ',
 			tainted & TAINT_USER ? 'U' : ' ',
 			tainted & TAINT_DIE ? 'D' : ' ');
diff --git a/kernel/params.c b/kernel/params.c
index 1d6aca2..16f269e 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -592,11 +592,17 @@
 
 	for (i=0; i < __stop___param - __start___param; i++) {
 		char *dot;
+		size_t kplen;
 
 		kp = &__start___param[i];
+		kplen = strlen(kp->name);
 
 		/* We do not handle args without periods. */
-		dot = memchr(kp->name, '.', MAX_KBUILD_MODNAME);
+		if (kplen > MAX_KBUILD_MODNAME) {
+			DEBUGP("kernel parameter name is too long: %s\n", kp->name);
+			continue;
+		}
+		dot = memchr(kp->name, '.', kplen);
 		if (!dot) {
 			DEBUGP("couldn't find period in %s\n", kp->name);
 			continue;
diff --git a/kernel/pid.c b/kernel/pid.c
index c6e3f9f..d1db36b 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -18,6 +18,12 @@
  * allocation scenario when all but one out of 1 million PIDs possible are
  * allocated already: the scanning of 32 list entries and at most PAGE_SIZE
  * bytes. The typical fastpath is a single successful setbit. Freeing is O(1).
+ *
+ * Pid namespaces:
+ *    (C) 2007 Pavel Emelyanov <xemul@openvz.org>, OpenVZ, SWsoft Inc.
+ *    (C) 2007 Sukadev Bhattiprolu <sukadev@us.ibm.com>, IBM
+ *     Many thanks to Oleg Nesterov for comments and help
+ *
  */
 
 #include <linux/mm.h>
@@ -28,12 +34,14 @@
 #include <linux/hash.h>
 #include <linux/pid_namespace.h>
 #include <linux/init_task.h>
+#include <linux/syscalls.h>
 
-#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
+#define pid_hashfn(nr, ns)	\
+	hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
 static struct hlist_head *pid_hash;
 static int pidhash_shift;
-static struct kmem_cache *pid_cachep;
 struct pid init_struct_pid = INIT_STRUCT_PID;
+static struct kmem_cache *pid_ns_cachep;
 
 int pid_max = PID_MAX_DEFAULT;
 
@@ -68,8 +76,25 @@
 		[ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL }
 	},
 	.last_pid = 0,
-	.child_reaper = &init_task
+	.level = 0,
+	.child_reaper = &init_task,
 };
+EXPORT_SYMBOL_GPL(init_pid_ns);
+
+int is_container_init(struct task_struct *tsk)
+{
+	int ret = 0;
+	struct pid *pid;
+
+	rcu_read_lock();
+	pid = task_pid(tsk);
+	if (pid != NULL && pid->numbers[pid->level].nr == 1)
+		ret = 1;
+	rcu_read_unlock();
+
+	return ret;
+}
+EXPORT_SYMBOL(is_container_init);
 
 /*
  * Note: disable interrupts while the pidmap_lock is held as an
@@ -176,11 +201,17 @@
 
 fastcall void put_pid(struct pid *pid)
 {
+	struct pid_namespace *ns;
+
 	if (!pid)
 		return;
+
+	ns = pid->numbers[pid->level].ns;
 	if ((atomic_read(&pid->count) == 1) ||
-	     atomic_dec_and_test(&pid->count))
-		kmem_cache_free(pid_cachep, pid);
+	     atomic_dec_and_test(&pid->count)) {
+		kmem_cache_free(ns->pid_cachep, pid);
+		put_pid_ns(ns);
+	}
 }
 EXPORT_SYMBOL_GPL(put_pid);
 
@@ -193,60 +224,94 @@
 fastcall void free_pid(struct pid *pid)
 {
 	/* We can be called with write_lock_irq(&tasklist_lock) held */
+	int i;
 	unsigned long flags;
 
 	spin_lock_irqsave(&pidmap_lock, flags);
-	hlist_del_rcu(&pid->pid_chain);
+	for (i = 0; i <= pid->level; i++)
+		hlist_del_rcu(&pid->numbers[i].pid_chain);
 	spin_unlock_irqrestore(&pidmap_lock, flags);
 
-	free_pidmap(&init_pid_ns, pid->nr);
+	for (i = 0; i <= pid->level; i++)
+		free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr);
+
 	call_rcu(&pid->rcu, delayed_put_pid);
 }
 
-struct pid *alloc_pid(void)
+struct pid *alloc_pid(struct pid_namespace *ns)
 {
 	struct pid *pid;
 	enum pid_type type;
-	int nr = -1;
+	int i, nr;
+	struct pid_namespace *tmp;
+	struct upid *upid;
 
-	pid = kmem_cache_alloc(pid_cachep, GFP_KERNEL);
+	pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);
 	if (!pid)
 		goto out;
 
-	nr = alloc_pidmap(current->nsproxy->pid_ns);
-	if (nr < 0)
-		goto out_free;
+	tmp = ns;
+	for (i = ns->level; i >= 0; i--) {
+		nr = alloc_pidmap(tmp);
+		if (nr < 0)
+			goto out_free;
 
+		pid->numbers[i].nr = nr;
+		pid->numbers[i].ns = tmp;
+		tmp = tmp->parent;
+	}
+
+	get_pid_ns(ns);
+	pid->level = ns->level;
 	atomic_set(&pid->count, 1);
-	pid->nr = nr;
 	for (type = 0; type < PIDTYPE_MAX; ++type)
 		INIT_HLIST_HEAD(&pid->tasks[type]);
 
 	spin_lock_irq(&pidmap_lock);
-	hlist_add_head_rcu(&pid->pid_chain, &pid_hash[pid_hashfn(pid->nr)]);
+	for (i = ns->level; i >= 0; i--) {
+		upid = &pid->numbers[i];
+		hlist_add_head_rcu(&upid->pid_chain,
+				&pid_hash[pid_hashfn(upid->nr, upid->ns)]);
+	}
 	spin_unlock_irq(&pidmap_lock);
 
 out:
 	return pid;
 
 out_free:
-	kmem_cache_free(pid_cachep, pid);
+	for (i++; i <= ns->level; i++)
+		free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr);
+
+	kmem_cache_free(ns->pid_cachep, pid);
 	pid = NULL;
 	goto out;
 }
 
-struct pid * fastcall find_pid(int nr)
+struct pid * fastcall find_pid_ns(int nr, struct pid_namespace *ns)
 {
 	struct hlist_node *elem;
-	struct pid *pid;
+	struct upid *pnr;
 
-	hlist_for_each_entry_rcu(pid, elem,
-			&pid_hash[pid_hashfn(nr)], pid_chain) {
-		if (pid->nr == nr)
-			return pid;
-	}
+	hlist_for_each_entry_rcu(pnr, elem,
+			&pid_hash[pid_hashfn(nr, ns)], pid_chain)
+		if (pnr->nr == nr && pnr->ns == ns)
+			return container_of(pnr, struct pid,
+					numbers[ns->level]);
+
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(find_pid_ns);
+
+struct pid *find_vpid(int nr)
+{
+	return find_pid_ns(nr, current->nsproxy->pid_ns);
+}
+EXPORT_SYMBOL_GPL(find_vpid);
+
+struct pid *find_pid(int nr)
+{
+	return find_pid_ns(nr, &init_pid_ns);
+}
 EXPORT_SYMBOL_GPL(find_pid);
 
 /*
@@ -307,12 +372,32 @@
 /*
  * Must be called under rcu_read_lock() or with tasklist_lock read-held.
  */
-struct task_struct *find_task_by_pid_type(int type, int nr)
+struct task_struct *find_task_by_pid_type_ns(int type, int nr,
+		struct pid_namespace *ns)
 {
-	return pid_task(find_pid(nr), type);
+	return pid_task(find_pid_ns(nr, ns), type);
 }
 
-EXPORT_SYMBOL(find_task_by_pid_type);
+EXPORT_SYMBOL(find_task_by_pid_type_ns);
+
+struct task_struct *find_task_by_pid(pid_t nr)
+{
+	return find_task_by_pid_type_ns(PIDTYPE_PID, nr, &init_pid_ns);
+}
+EXPORT_SYMBOL(find_task_by_pid);
+
+struct task_struct *find_task_by_vpid(pid_t vnr)
+{
+	return find_task_by_pid_type_ns(PIDTYPE_PID, vnr,
+			current->nsproxy->pid_ns);
+}
+EXPORT_SYMBOL(find_task_by_vpid);
+
+struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
+{
+	return find_task_by_pid_type_ns(PIDTYPE_PID, nr, ns);
+}
+EXPORT_SYMBOL(find_task_by_pid_ns);
 
 struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
 {
@@ -339,45 +424,239 @@
 	struct pid *pid;
 
 	rcu_read_lock();
-	pid = get_pid(find_pid(nr));
+	pid = get_pid(find_vpid(nr));
 	rcu_read_unlock();
 
 	return pid;
 }
 
+pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
+{
+	struct upid *upid;
+	pid_t nr = 0;
+
+	if (pid && ns->level <= pid->level) {
+		upid = &pid->numbers[ns->level];
+		if (upid->ns == ns)
+			nr = upid->nr;
+	}
+	return nr;
+}
+
+pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+	return pid_nr_ns(task_pid(tsk), ns);
+}
+EXPORT_SYMBOL(task_pid_nr_ns);
+
+pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+	return pid_nr_ns(task_tgid(tsk), ns);
+}
+EXPORT_SYMBOL(task_tgid_nr_ns);
+
+pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+	return pid_nr_ns(task_pgrp(tsk), ns);
+}
+EXPORT_SYMBOL(task_pgrp_nr_ns);
+
+pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+	return pid_nr_ns(task_session(tsk), ns);
+}
+EXPORT_SYMBOL(task_session_nr_ns);
+
 /*
  * Used by proc to find the first pid that is greater then or equal to nr.
  *
  * If there is a pid at nr this function is exactly the same as find_pid.
  */
-struct pid *find_ge_pid(int nr)
+struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
 {
 	struct pid *pid;
 
 	do {
-		pid = find_pid(nr);
+		pid = find_pid_ns(nr, ns);
 		if (pid)
 			break;
-		nr = next_pidmap(current->nsproxy->pid_ns, nr);
+		nr = next_pidmap(ns, nr);
 	} while (nr > 0);
 
 	return pid;
 }
 EXPORT_SYMBOL_GPL(find_get_pid);
 
+struct pid_cache {
+	int nr_ids;
+	char name[16];
+	struct kmem_cache *cachep;
+	struct list_head list;
+};
+
+static LIST_HEAD(pid_caches_lh);
+static DEFINE_MUTEX(pid_caches_mutex);
+
+/*
+ * creates the kmem cache to allocate pids from.
+ * @nr_ids: the number of numerical ids this pid will have to carry
+ */
+
+static struct kmem_cache *create_pid_cachep(int nr_ids)
+{
+	struct pid_cache *pcache;
+	struct kmem_cache *cachep;
+
+	mutex_lock(&pid_caches_mutex);
+	list_for_each_entry (pcache, &pid_caches_lh, list)
+		if (pcache->nr_ids == nr_ids)
+			goto out;
+
+	pcache = kmalloc(sizeof(struct pid_cache), GFP_KERNEL);
+	if (pcache == NULL)
+		goto err_alloc;
+
+	snprintf(pcache->name, sizeof(pcache->name), "pid_%d", nr_ids);
+	cachep = kmem_cache_create(pcache->name,
+			sizeof(struct pid) + (nr_ids - 1) * sizeof(struct upid),
+			0, SLAB_HWCACHE_ALIGN, NULL);
+	if (cachep == NULL)
+		goto err_cachep;
+
+	pcache->nr_ids = nr_ids;
+	pcache->cachep = cachep;
+	list_add(&pcache->list, &pid_caches_lh);
+out:
+	mutex_unlock(&pid_caches_mutex);
+	return pcache->cachep;
+
+err_cachep:
+	kfree(pcache);
+err_alloc:
+	mutex_unlock(&pid_caches_mutex);
+	return NULL;
+}
+
+static struct pid_namespace *create_pid_namespace(int level)
+{
+	struct pid_namespace *ns;
+	int i;
+
+	ns = kmem_cache_alloc(pid_ns_cachep, GFP_KERNEL);
+	if (ns == NULL)
+		goto out;
+
+	ns->pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!ns->pidmap[0].page)
+		goto out_free;
+
+	ns->pid_cachep = create_pid_cachep(level + 1);
+	if (ns->pid_cachep == NULL)
+		goto out_free_map;
+
+	kref_init(&ns->kref);
+	ns->last_pid = 0;
+	ns->child_reaper = NULL;
+	ns->level = level;
+
+	set_bit(0, ns->pidmap[0].page);
+	atomic_set(&ns->pidmap[0].nr_free, BITS_PER_PAGE - 1);
+
+	for (i = 1; i < PIDMAP_ENTRIES; i++) {
+		ns->pidmap[i].page = 0;
+		atomic_set(&ns->pidmap[i].nr_free, BITS_PER_PAGE);
+	}
+
+	return ns;
+
+out_free_map:
+	kfree(ns->pidmap[0].page);
+out_free:
+	kmem_cache_free(pid_ns_cachep, ns);
+out:
+	return ERR_PTR(-ENOMEM);
+}
+
+static void destroy_pid_namespace(struct pid_namespace *ns)
+{
+	int i;
+
+	for (i = 0; i < PIDMAP_ENTRIES; i++)
+		kfree(ns->pidmap[i].page);
+	kmem_cache_free(pid_ns_cachep, ns);
+}
+
 struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *old_ns)
 {
+	struct pid_namespace *new_ns;
+
 	BUG_ON(!old_ns);
-	get_pid_ns(old_ns);
-	return old_ns;
+	new_ns = get_pid_ns(old_ns);
+	if (!(flags & CLONE_NEWPID))
+		goto out;
+
+	new_ns = ERR_PTR(-EINVAL);
+	if (flags & CLONE_THREAD)
+		goto out_put;
+
+	new_ns = create_pid_namespace(old_ns->level + 1);
+	if (!IS_ERR(new_ns))
+		new_ns->parent = get_pid_ns(old_ns);
+
+out_put:
+	put_pid_ns(old_ns);
+out:
+	return new_ns;
 }
 
 void free_pid_ns(struct kref *kref)
 {
-	struct pid_namespace *ns;
+	struct pid_namespace *ns, *parent;
 
 	ns = container_of(kref, struct pid_namespace, kref);
-	kfree(ns);
+
+	parent = ns->parent;
+	destroy_pid_namespace(ns);
+
+	if (parent != NULL)
+		put_pid_ns(parent);
+}
+
+void zap_pid_ns_processes(struct pid_namespace *pid_ns)
+{
+	int nr;
+	int rc;
+
+	/*
+	 * The last thread in the cgroup-init thread group is terminating.
+	 * Find remaining pid_ts in the namespace, signal and wait for them
+	 * to exit.
+	 *
+	 * Note:  This signals each threads in the namespace - even those that
+	 * 	  belong to the same thread group, To avoid this, we would have
+	 * 	  to walk the entire tasklist looking a processes in this
+	 * 	  namespace, but that could be unnecessarily expensive if the
+	 * 	  pid namespace has just a few processes. Or we need to
+	 * 	  maintain a tasklist for each pid namespace.
+	 *
+	 */
+	read_lock(&tasklist_lock);
+	nr = next_pidmap(pid_ns, 1);
+	while (nr > 0) {
+		kill_proc_info(SIGKILL, SEND_SIG_PRIV, nr);
+		nr = next_pidmap(pid_ns, nr);
+	}
+	read_unlock(&tasklist_lock);
+
+	do {
+		clear_thread_flag(TIF_SIGPENDING);
+		rc = sys_wait4(-1, NULL, __WALL, NULL);
+	} while (rc != -ECHILD);
+
+
+	/* Child reaper for the pid namespace is going away */
+	pid_ns->child_reaper = NULL;
+	return;
 }
 
 /*
@@ -412,5 +691,9 @@
 	set_bit(0, init_pid_ns.pidmap[0].page);
 	atomic_dec(&init_pid_ns.pidmap[0].nr_free);
 
-	pid_cachep = KMEM_CACHE(pid, SLAB_PANIC);
+	init_pid_ns.pid_cachep = create_pid_cachep(1);
+	if (init_pid_ns.pid_cachep == NULL)
+		panic("Can't create pid_1 cachep\n");
+
+	pid_ns_cachep = KMEM_CACHE(pid_namespace, SLAB_PANIC);
 }
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index b53c8fc..68c9637 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -21,8 +21,8 @@
 
 	read_lock(&tasklist_lock);
 	p = find_task_by_pid(pid);
-	if (!p || (CPUCLOCK_PERTHREAD(which_clock) ?
-		   p->tgid != current->tgid : p->tgid != pid)) {
+	if (!p || !(CPUCLOCK_PERTHREAD(which_clock) ?
+		   same_thread_group(p, current) : thread_group_leader(p))) {
 		error = -EINVAL;
 	}
 	read_unlock(&tasklist_lock);
@@ -308,13 +308,13 @@
 		p = find_task_by_pid(pid);
 		if (p) {
 			if (CPUCLOCK_PERTHREAD(which_clock)) {
-				if (p->tgid == current->tgid) {
+				if (same_thread_group(p, current)) {
 					error = cpu_clock_sample(which_clock,
 								 p, &rtn);
 				}
 			} else {
 				read_lock(&tasklist_lock);
-				if (p->tgid == pid && p->signal) {
+				if (thread_group_leader(p) && p->signal) {
 					error =
 					    cpu_clock_sample_group(which_clock,
 							           p, &rtn);
@@ -355,7 +355,7 @@
 			p = current;
 		} else {
 			p = find_task_by_pid(pid);
-			if (p && p->tgid != current->tgid)
+			if (p && !same_thread_group(p, current))
 				p = NULL;
 		}
 	} else {
@@ -363,7 +363,7 @@
 			p = current->group_leader;
 		} else {
 			p = find_task_by_pid(pid);
-			if (p && p->tgid != pid)
+			if (p && !thread_group_leader(p))
 				p = NULL;
 		}
 	}
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index d71ed09..35b4bbf 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -404,7 +404,7 @@
 
 	if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
 		(!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) ||
-		 rtn->tgid != current->tgid ||
+		 !same_thread_group(rtn, current) ||
 		 (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
 		return NULL;
 
@@ -608,7 +608,7 @@
 		spin_lock(&timr->it_lock);
 
 		if ((timr->it_id != timer_id) || !(timr->it_process) ||
-				timr->it_process->tgid != current->tgid) {
+				!same_thread_group(timr->it_process, current)) {
 			spin_unlock(&timr->it_lock);
 			spin_unlock_irqrestore(&idr_lock, *flags);
 			timr = NULL;
@@ -981,9 +981,20 @@
 static int common_nsleep(const clockid_t which_clock, int flags,
 			 struct timespec *tsave, struct timespec __user *rmtp)
 {
-	return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
-				 HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
-				 which_clock);
+	struct timespec rmt;
+	int ret;
+
+	ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL,
+				flags & TIMER_ABSTIME ?
+				HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
+				which_clock);
+
+	if (ret && rmtp) {
+		if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
+			return -EFAULT;
+	}
+
+	return ret;
 }
 
 asmlinkage long
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 14b0e10..8e186c6 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -44,17 +44,6 @@
 	---help---
 	This option enables verbose messages from the Power Management code.
 
-config DISABLE_CONSOLE_SUSPEND
-	bool "Keep console(s) enabled during suspend/resume (DANGEROUS)"
-	depends on PM_DEBUG && PM_SLEEP
-	default n
-	---help---
-	This option turns off the console suspend mechanism that prevents
-	debug messages from reaching the console during the suspend/resume
-	operations.  This may be helpful when debugging device drivers'
-	suspend/resume routines, but may itself lead to problems, for example
-	if netconsole is used.
-
 config PM_TRACE
 	bool "Suspend/resume event tracing"
 	depends on PM_DEBUG && X86 && PM_SLEEP && EXPERIMENTAL
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index eb72255..8b15f77 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -45,17 +45,18 @@
 
 static int hibernation_mode = HIBERNATION_SHUTDOWN;
 
-static struct hibernation_ops *hibernation_ops;
+static struct platform_hibernation_ops *hibernation_ops;
 
 /**
  * hibernation_set_ops - set the global hibernate operations
  * @ops: the hibernation operations to use in subsequent hibernation transitions
  */
 
-void hibernation_set_ops(struct hibernation_ops *ops)
+void hibernation_set_ops(struct platform_hibernation_ops *ops)
 {
-	if (ops && !(ops->prepare && ops->enter && ops->finish
-	    && ops->pre_restore && ops->restore_cleanup)) {
+	if (ops && !(ops->start && ops->pre_snapshot && ops->finish
+	    && ops->prepare && ops->enter && ops->pre_restore
+	    && ops->restore_cleanup)) {
 		WARN_ON(1);
 		return;
 	}
@@ -69,16 +70,37 @@
 	mutex_unlock(&pm_mutex);
 }
 
+/**
+ *	platform_start - tell the platform driver that we're starting
+ *	hibernation
+ */
+
+static int platform_start(int platform_mode)
+{
+	return (platform_mode && hibernation_ops) ?
+		hibernation_ops->start() : 0;
+}
 
 /**
- *	platform_prepare - prepare the machine for hibernation using the
+ *	platform_pre_snapshot - prepare the machine for hibernation using the
  *	platform driver if so configured and return an error code if it fails
  */
 
-static int platform_prepare(int platform_mode)
+static int platform_pre_snapshot(int platform_mode)
 {
 	return (platform_mode && hibernation_ops) ?
-		hibernation_ops->prepare() : 0;
+		hibernation_ops->pre_snapshot() : 0;
+}
+
+/**
+ *	platform_leave - prepare the machine for switching to the normal mode
+ *	of operation using the platform driver (called with interrupts disabled)
+ */
+
+static void platform_leave(int platform_mode)
+{
+	if (platform_mode && hibernation_ops)
+		hibernation_ops->leave();
 }
 
 /**
@@ -118,6 +140,51 @@
 }
 
 /**
+ *	create_image - freeze devices that need to be frozen with interrupts
+ *	off, create the hibernation image and thaw those devices.  Control
+ *	reappears in this routine after a restore.
+ */
+
+int create_image(int platform_mode)
+{
+	int error;
+
+	error = arch_prepare_suspend();
+	if (error)
+		return error;
+
+	local_irq_disable();
+	/* At this point, device_suspend() has been called, but *not*
+	 * device_power_down(). We *must* call device_power_down() now.
+	 * Otherwise, drivers for some devices (e.g. interrupt controllers)
+	 * become desynchronized with the actual state of the hardware
+	 * at resume time, and evil weirdness ensues.
+	 */
+	error = device_power_down(PMSG_FREEZE);
+	if (error) {
+		printk(KERN_ERR "Some devices failed to power down, "
+			KERN_ERR "aborting suspend\n");
+		goto Enable_irqs;
+	}
+
+	save_processor_state();
+	error = swsusp_arch_suspend();
+	if (error)
+		printk(KERN_ERR "Error %d while creating the image\n", error);
+	/* Restore control flow magically appears here */
+	restore_processor_state();
+	if (!in_suspend)
+		platform_leave(platform_mode);
+	/* NOTE:  device_power_up() is just a resume() for devices
+	 * that suspended with irqs off ... no overall powerup.
+	 */
+	device_power_up();
+ Enable_irqs:
+	local_irq_enable();
+	return error;
+}
+
+/**
  *	hibernation_snapshot - quiesce devices and create the hibernation
  *	snapshot image.
  *	@platform_mode - if set, use the platform driver, if available, to
@@ -135,12 +202,16 @@
 	if (error)
 		return error;
 
+	error = platform_start(platform_mode);
+	if (error)
+		return error;
+
 	suspend_console();
 	error = device_suspend(PMSG_FREEZE);
 	if (error)
 		goto Resume_console;
 
-	error = platform_prepare(platform_mode);
+	error = platform_pre_snapshot(platform_mode);
 	if (error)
 		goto Resume_devices;
 
@@ -148,7 +219,7 @@
 	if (!error) {
 		if (hibernation_mode != HIBERNATION_TEST) {
 			in_suspend = 1;
-			error = swsusp_suspend();
+			error = create_image(platform_mode);
 			/* Control returns here after successful restore */
 		} else {
 			printk("swsusp debug: Waiting for 5 seconds.\n");
@@ -207,21 +278,50 @@
 {
 	int error;
 
-	if (hibernation_ops) {
-		kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
-		/*
-		 * We have cancelled the power transition by running
-		 * hibernation_ops->finish() before saving the image, so we
-		 * should let the firmware know that we're going to enter the
-		 * sleep state after all
-		 */
-		error = hibernation_ops->prepare();
-		sysdev_shutdown();
-		if (!error)
-			error = hibernation_ops->enter();
-	} else {
-		error = -ENOSYS;
+	if (!hibernation_ops)
+		return -ENOSYS;
+
+	/*
+	 * We have cancelled the power transition by running
+	 * hibernation_ops->finish() before saving the image, so we should let
+	 * the firmware know that we're going to enter the sleep state after all
+	 */
+	error = hibernation_ops->start();
+	if (error)
+		return error;
+
+	suspend_console();
+	error = device_suspend(PMSG_SUSPEND);
+	if (error)
+		goto Resume_console;
+
+	error = hibernation_ops->prepare();
+	if (error)
+		goto Resume_devices;
+
+	error = disable_nonboot_cpus();
+	if (error)
+		goto Finish;
+
+	local_irq_disable();
+	error = device_power_down(PMSG_SUSPEND);
+	if (!error) {
+		hibernation_ops->enter();
+		/* We should never get here */
+		while (1);
 	}
+	local_irq_enable();
+
+	/*
+	 * We don't need to reenable the nonboot CPUs or resume consoles, since
+	 * the system is going to be halted anyway.
+	 */
+ Finish:
+	hibernation_ops->finish();
+ Resume_devices:
+	device_resume();
+ Resume_console:
+	resume_console();
 	return error;
 }
 
@@ -238,14 +338,14 @@
 	case HIBERNATION_TEST:
 	case HIBERNATION_TESTPROC:
 		break;
-	case HIBERNATION_SHUTDOWN:
-		kernel_power_off();
-		break;
 	case HIBERNATION_REBOOT:
 		kernel_restart(NULL);
 		break;
 	case HIBERNATION_PLATFORM:
 		hibernation_platform_enter();
+	case HIBERNATION_SHUTDOWN:
+		kernel_power_off();
+		break;
 	}
 	kernel_halt();
 	/*
@@ -298,6 +398,10 @@
 	if (error)
 		goto Exit;
 
+	printk("Syncing filesystems ... ");
+	sys_sync();
+	printk("done.\n");
+
 	error = prepare_processes();
 	if (error)
 		goto Finish;
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 350b485..3cdf95b 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -20,6 +20,7 @@
 #include <linux/resume-trace.h>
 #include <linux/freezer.h>
 #include <linux/vmstat.h>
+#include <linux/syscalls.h>
 
 #include "power.h"
 
@@ -32,39 +33,32 @@
 /* This is just an arbitrary number */
 #define FREE_PAGE_NUMBER (100)
 
-struct pm_ops *pm_ops;
+static struct platform_suspend_ops *suspend_ops;
 
 /**
- *	pm_set_ops - Set the global power method table. 
+ *	suspend_set_ops - Set the global suspend method table.
  *	@ops:	Pointer to ops structure.
  */
 
-void pm_set_ops(struct pm_ops * ops)
+void suspend_set_ops(struct platform_suspend_ops *ops)
 {
 	mutex_lock(&pm_mutex);
-	pm_ops = ops;
+	suspend_ops = ops;
 	mutex_unlock(&pm_mutex);
 }
 
 /**
- * pm_valid_only_mem - generic memory-only valid callback
+ * suspend_valid_only_mem - generic memory-only valid callback
  *
- * pm_ops drivers that implement mem suspend only and only need
+ * Platform drivers that implement mem suspend only and only need
  * to check for that in their .valid callback can use this instead
  * of rolling their own .valid callback.
  */
-int pm_valid_only_mem(suspend_state_t state)
+int suspend_valid_only_mem(suspend_state_t state)
 {
 	return state == PM_SUSPEND_MEM;
 }
 
-
-static inline void pm_finish(suspend_state_t state)
-{
-	if (pm_ops->finish)
-		pm_ops->finish(state);
-}
-
 /**
  *	suspend_prepare - Do prep work before entering low-power state.
  *
@@ -76,7 +70,7 @@
 	int error;
 	unsigned int free_pages;
 
-	if (!pm_ops || !pm_ops->enter)
+	if (!suspend_ops || !suspend_ops->enter)
 		return -EPERM;
 
 	error = pm_notifier_call_chain(PM_SUSPEND_PREPARE);
@@ -128,7 +122,7 @@
  *
  *	This function should be called after devices have been suspended.
  */
-int suspend_enter(suspend_state_t state)
+static int suspend_enter(suspend_state_t state)
 {
 	int error = 0;
 
@@ -139,7 +133,7 @@
 		printk(KERN_ERR "Some devices failed to power down\n");
 		goto Done;
 	}
-	error = pm_ops->enter(state);
+	error = suspend_ops->enter(state);
 	device_power_up();
  Done:
 	arch_suspend_enable_irqs();
@@ -156,11 +150,11 @@
 {
 	int error;
 
-	if (!pm_ops)
+	if (!suspend_ops)
 		return -ENOSYS;
 
-	if (pm_ops->set_target) {
-		error = pm_ops->set_target(state);
+	if (suspend_ops->set_target) {
+		error = suspend_ops->set_target(state);
 		if (error)
 			return error;
 	}
@@ -170,8 +164,8 @@
 		printk(KERN_ERR "Some devices failed to suspend\n");
 		goto Resume_console;
 	}
-	if (pm_ops->prepare) {
-		error = pm_ops->prepare(state);
+	if (suspend_ops->prepare) {
+		error = suspend_ops->prepare();
 		if (error)
 			goto Resume_devices;
 	}
@@ -180,7 +174,8 @@
 		suspend_enter(state);
 
 	enable_nonboot_cpus();
-	pm_finish(state);
+	if (suspend_ops->finish)
+		suspend_ops->finish();
  Resume_devices:
 	device_resume();
  Resume_console:
@@ -214,7 +209,7 @@
 	/* All states need lowlevel support and need to be valid
 	 * to the lowlevel implementation, no valid callback
 	 * implies that none are valid. */
-	if (!pm_ops || !pm_ops->valid || !pm_ops->valid(state))
+	if (!suspend_ops || !suspend_ops->valid || !suspend_ops->valid(state))
 		return 0;
 	return 1;
 }
@@ -236,9 +231,14 @@
 
 	if (!valid_state(state))
 		return -ENODEV;
+
 	if (!mutex_trylock(&pm_mutex))
 		return -EBUSY;
 
+	printk("Syncing filesystems ... ");
+	sys_sync();
+	printk("done.\n");
+
 	pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
 	if ((error = suspend_prepare()))
 		goto Unlock;
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 95fbf2d..195dc46 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -11,14 +11,32 @@
 	unsigned long		size;
 } __attribute__((aligned(PAGE_SIZE)));
 
-
-
 #ifdef CONFIG_HIBERNATION
+#ifdef CONFIG_ARCH_HIBERNATION_HEADER
+/* Maximum size of architecture specific data in a hibernation header */
+#define MAX_ARCH_HEADER_SIZE	(sizeof(struct new_utsname) + 4)
+
+extern int arch_hibernation_header_save(void *addr, unsigned int max_size);
+extern int arch_hibernation_header_restore(void *addr);
+
+static inline int init_header_complete(struct swsusp_info *info)
+{
+	return arch_hibernation_header_save(info, MAX_ARCH_HEADER_SIZE);
+}
+
+static inline char *check_image_kernel(struct swsusp_info *info)
+{
+	return arch_hibernation_header_restore(info) ?
+			"architecture specific data" : NULL;
+}
+#endif /* CONFIG_ARCH_HIBERNATION_HEADER */
+
 /*
  * Keep some memory free so that I/O operations can succeed without paging
  * [Might this be more than 4 MB?]
  */
 #define PAGES_FOR_IO	((4096 * 1024) >> PAGE_SHIFT)
+
 /*
  * Keep 1 MB of memory free so that device drivers can allocate some pages in
  * their .suspend() routines without breaking the suspend to disk.
@@ -165,7 +183,6 @@
 extern int swsusp_check(void);
 extern int swsusp_shrink_memory(void);
 extern void swsusp_free(void);
-extern int swsusp_suspend(void);
 extern int swsusp_resume(void);
 extern int swsusp_read(unsigned int *flags_p);
 extern int swsusp_write(unsigned int flags);
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 3434940..6533923 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -75,21 +75,79 @@
 	__set_current_state(save);
 }
 
-static void freeze_task(struct task_struct *p)
+static void fake_signal_wake_up(struct task_struct *p, int resume)
 {
 	unsigned long flags;
 
-	if (!freezing(p)) {
+	spin_lock_irqsave(&p->sighand->siglock, flags);
+	signal_wake_up(p, resume);
+	spin_unlock_irqrestore(&p->sighand->siglock, flags);
+}
+
+static void send_fake_signal(struct task_struct *p)
+{
+	if (p->state == TASK_STOPPED)
+		force_sig_specific(SIGSTOP, p);
+	fake_signal_wake_up(p, p->state == TASK_STOPPED);
+}
+
+static int has_mm(struct task_struct *p)
+{
+	return (p->mm && !(p->flags & PF_BORROWED_MM));
+}
+
+/**
+ *	freeze_task - send a freeze request to given task
+ *	@p: task to send the request to
+ *	@with_mm_only: if set, the request will only be sent if the task has its
+ *		own mm
+ *	Return value: 0, if @with_mm_only is set and the task has no mm of its
+ *		own or the task is frozen, 1, otherwise
+ *
+ *	The freeze request is sent by seting the tasks's TIF_FREEZE flag and
+ *	either sending a fake signal to it or waking it up, depending on whether
+ *	or not it has its own mm (ie. it is a user land task).  If @with_mm_only
+ *	is set and the task has no mm of its own (ie. it is a kernel thread),
+ *	its TIF_FREEZE flag should not be set.
+ *
+ *	The task_lock() is necessary to prevent races with exit_mm() or
+ *	use_mm()/unuse_mm() from occuring.
+ */
+static int freeze_task(struct task_struct *p, int with_mm_only)
+{
+	int ret = 1;
+
+	task_lock(p);
+	if (freezing(p)) {
+		if (has_mm(p)) {
+			if (!signal_pending(p))
+				fake_signal_wake_up(p, 0);
+		} else {
+			if (with_mm_only)
+				ret = 0;
+			else
+				wake_up_state(p, TASK_INTERRUPTIBLE);
+		}
+	} else {
 		rmb();
-		if (!frozen(p)) {
-			set_freeze_flag(p);
-			if (p->state == TASK_STOPPED)
-				force_sig_specific(SIGSTOP, p);
-			spin_lock_irqsave(&p->sighand->siglock, flags);
-			signal_wake_up(p, p->state == TASK_STOPPED);
-			spin_unlock_irqrestore(&p->sighand->siglock, flags);
+		if (frozen(p)) {
+			ret = 0;
+		} else {
+			if (has_mm(p)) {
+				set_freeze_flag(p);
+				send_fake_signal(p);
+			} else {
+				if (with_mm_only) {
+					ret = 0;
+				} else {
+					set_freeze_flag(p);
+					wake_up_state(p, TASK_INTERRUPTIBLE);
+				}
+			}
 		}
 	}
+	task_unlock(p);
+	return ret;
 }
 
 static void cancel_freezing(struct task_struct *p)
@@ -110,6 +168,11 @@
 	struct task_struct *g, *p;
 	unsigned long end_time;
 	unsigned int todo;
+	struct timeval start, end;
+	s64 elapsed_csecs64;
+	unsigned int elapsed_csecs;
+
+	do_gettimeofday(&start);
 
 	end_time = jiffies + TIMEOUT;
 	do {
@@ -119,31 +182,14 @@
 			if (frozen(p) || !freezeable(p))
 				continue;
 
-			if (freeze_user_space) {
-				if (p->state == TASK_TRACED &&
-				    frozen(p->parent)) {
-					cancel_freezing(p);
-					continue;
-				}
-				/*
-				 * Kernel threads should not have TIF_FREEZE set
-				 * at this point, so we must ensure that either
-				 * p->mm is not NULL *and* PF_BORROWED_MM is
-				 * unset, or TIF_FRREZE is left unset.
-				 * The task_lock() is necessary to prevent races
-				 * with exit_mm() or use_mm()/unuse_mm() from
-				 * occuring.
-				 */
-				task_lock(p);
-				if (!p->mm || (p->flags & PF_BORROWED_MM)) {
-					task_unlock(p);
-					continue;
-				}
-				freeze_task(p);
-				task_unlock(p);
-			} else {
-				freeze_task(p);
+			if (p->state == TASK_TRACED && frozen(p->parent)) {
+				cancel_freezing(p);
+				continue;
 			}
+
+			if (!freeze_task(p, freeze_user_space))
+				continue;
+
 			if (!freezer_should_skip(p))
 				todo++;
 		} while_each_thread(g, p);
@@ -153,6 +199,11 @@
 			break;
 	} while (todo);
 
+	do_gettimeofday(&end);
+	elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
+	do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
+	elapsed_csecs = elapsed_csecs64;
+
 	if (todo) {
 		/* This does not unfreeze processes that are already frozen
 		 * (we have slightly ugly calling convention in that respect,
@@ -160,10 +211,9 @@
 		 * but it cleans up leftover PF_FREEZE requests.
 		 */
 		printk("\n");
-		printk(KERN_ERR "Freezing of %s timed out after %d seconds "
+		printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
 				"(%d tasks refusing to freeze):\n",
-				freeze_user_space ? "user space " : "tasks ",
-				TIMEOUT / HZ, todo);
+				elapsed_csecs / 100, elapsed_csecs % 100, todo);
 		show_state();
 		read_lock(&tasklist_lock);
 		do_each_thread(g, p) {
@@ -174,6 +224,9 @@
 			task_unlock(p);
 		} while_each_thread(g, p);
 		read_unlock(&tasklist_lock);
+	} else {
+		printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
+			elapsed_csecs % 100);
 	}
 
 	return todo ? -EBUSY : 0;
@@ -186,19 +239,21 @@
 {
 	int error;
 
-	printk("Stopping tasks ... ");
+	printk("Freezing user space processes ... ");
 	error = try_to_freeze_tasks(FREEZER_USER_SPACE);
 	if (error)
-		return error;
+		goto Exit;
+	printk("done.\n");
 
-	sys_sync();
+	printk("Freezing remaining freezable tasks ... ");
 	error = try_to_freeze_tasks(FREEZER_KERNEL_THREADS);
 	if (error)
-		return error;
-
-	printk("done.\n");
+		goto Exit;
+	printk("done.");
+ Exit:
 	BUG_ON(in_atomic());
-	return 0;
+	printk("\n");
+	return error;
 }
 
 static void thaw_tasks(int thaw_user_space)
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index a686590..78039b4 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1005,11 +1005,12 @@
 	}
 	memory_bm_position_reset(orig_bm);
 	memory_bm_position_reset(copy_bm);
-	do {
+	for(;;) {
 		pfn = memory_bm_next_pfn(orig_bm);
-		if (likely(pfn != BM_END_OF_MAP))
-			copy_data_page(memory_bm_next_pfn(copy_bm), pfn);
-	} while (pfn != BM_END_OF_MAP);
+		if (unlikely(pfn == BM_END_OF_MAP))
+			break;
+		copy_data_page(memory_bm_next_pfn(copy_bm), pfn);
+	}
 }
 
 /* Total number of image pages */
@@ -1239,17 +1240,39 @@
 	return 0;
 }
 
-static void init_header(struct swsusp_info *info)
+#ifndef CONFIG_ARCH_HIBERNATION_HEADER
+static int init_header_complete(struct swsusp_info *info)
+{
+	memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
+	info->version_code = LINUX_VERSION_CODE;
+	return 0;
+}
+
+static char *check_image_kernel(struct swsusp_info *info)
+{
+	if (info->version_code != LINUX_VERSION_CODE)
+		return "kernel version";
+	if (strcmp(info->uts.sysname,init_utsname()->sysname))
+		return "system type";
+	if (strcmp(info->uts.release,init_utsname()->release))
+		return "kernel release";
+	if (strcmp(info->uts.version,init_utsname()->version))
+		return "version";
+	if (strcmp(info->uts.machine,init_utsname()->machine))
+		return "machine";
+	return NULL;
+}
+#endif /* CONFIG_ARCH_HIBERNATION_HEADER */
+
+static int init_header(struct swsusp_info *info)
 {
 	memset(info, 0, sizeof(struct swsusp_info));
-	info->version_code = LINUX_VERSION_CODE;
 	info->num_physpages = num_physpages;
-	memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
-	info->cpus = num_online_cpus();
 	info->image_pages = nr_copy_pages;
 	info->pages = nr_copy_pages + nr_meta_pages + 1;
 	info->size = info->pages;
 	info->size <<= PAGE_SHIFT;
+	return init_header_complete(info);
 }
 
 /**
@@ -1303,7 +1326,11 @@
 			return -ENOMEM;
 	}
 	if (!handle->offset) {
-		init_header((struct swsusp_info *)buffer);
+		int error;
+
+		error = init_header((struct swsusp_info *)buffer);
+		if (error)
+			return error;
 		handle->buffer = buffer;
 		memory_bm_position_reset(&orig_bm);
 		memory_bm_position_reset(&copy_bm);
@@ -1394,22 +1421,13 @@
 	}
 }
 
-static inline int check_header(struct swsusp_info *info)
+static int check_header(struct swsusp_info *info)
 {
-	char *reason = NULL;
+	char *reason;
 
-	if (info->version_code != LINUX_VERSION_CODE)
-		reason = "kernel version";
-	if (info->num_physpages != num_physpages)
+	reason = check_image_kernel(info);
+	if (!reason && info->num_physpages != num_physpages)
 		reason = "memory size";
-	if (strcmp(info->uts.sysname,init_utsname()->sysname))
-		reason = "system type";
-	if (strcmp(info->uts.release,init_utsname()->release))
-		reason = "kernel release";
-	if (strcmp(info->uts.version,init_utsname()->version))
-		reason = "version";
-	if (strcmp(info->uts.machine,init_utsname()->machine))
-		reason = "machine";
 	if (reason) {
 		printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason);
 		return -EPERM;
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 5da304c..e1722d3 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -270,39 +270,6 @@
 	return 0;
 }
 
-int swsusp_suspend(void)
-{
-	int error;
-
-	if ((error = arch_prepare_suspend()))
-		return error;
-
-	local_irq_disable();
-	/* At this point, device_suspend() has been called, but *not*
-	 * device_power_down(). We *must* device_power_down() now.
-	 * Otherwise, drivers for some devices (e.g. interrupt controllers)
-	 * become desynchronized with the actual state of the hardware
-	 * at resume time, and evil weirdness ensues.
-	 */
-	if ((error = device_power_down(PMSG_FREEZE))) {
-		printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
-		goto Enable_irqs;
-	}
-
-	save_processor_state();
-	if ((error = swsusp_arch_suspend()))
-		printk(KERN_ERR "Error %d suspending\n", error);
-	/* Restore control flow magically appears here */
-	restore_processor_state();
-	/* NOTE:  device_power_up() is just a resume() for devices
-	 * that suspended with irqs off ... no overall powerup.
-	 */
-	device_power_up();
- Enable_irqs:
-	local_irq_enable();
-	return error;
-}
-
 int swsusp_resume(void)
 {
 	int error;
diff --git a/kernel/power/user.c b/kernel/power/user.c
index bd0723a..5bd321b 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -153,6 +153,10 @@
 		mutex_lock(&pm_mutex);
 		error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE);
 		if (!error) {
+			printk("Syncing filesystems ... ");
+			sys_sync();
+			printk("done.\n");
+
 			error = freeze_processes();
 			if (error)
 				thaw_processes();
diff --git a/kernel/printk.c b/kernel/printk.c
index 5249347..a30fe33 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -862,7 +862,16 @@
 	return -1;
 }
 
-#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
+int console_suspend_enabled = 1;
+EXPORT_SYMBOL(console_suspend_enabled);
+
+static int __init console_suspend_disable(char *str)
+{
+	console_suspend_enabled = 0;
+	return 1;
+}
+__setup("no_console_suspend", console_suspend_disable);
+
 /**
  * suspend_console - suspend the console subsystem
  *
@@ -870,6 +879,8 @@
  */
 void suspend_console(void)
 {
+	if (!console_suspend_enabled)
+		return;
 	printk("Suspending console(s)\n");
 	acquire_console_sem();
 	console_suspended = 1;
@@ -877,10 +888,11 @@
 
 void resume_console(void)
 {
+	if (!console_suspend_enabled)
+		return;
 	console_suspended = 0;
 	release_console_sem();
 }
-#endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
 
 /**
  * acquire_console_sem - lock the console system for exclusive use.
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index a73ebd3..7c76f2f 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -19,6 +19,7 @@
 #include <linux/security.h>
 #include <linux/signal.h>
 #include <linux/audit.h>
+#include <linux/pid_namespace.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -168,7 +169,7 @@
 	retval = -EPERM;
 	if (task->pid <= 1)
 		goto out;
-	if (task->tgid == current->tgid)
+	if (same_thread_group(task, current))
 		goto out;
 
 repeat:
@@ -443,7 +444,7 @@
 		return ERR_PTR(-EPERM);
 
 	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
+	child = find_task_by_vpid(pid);
 	if (child)
 		get_task_struct(child);
 
diff --git a/kernel/relay.c b/kernel/relay.c
index ad85501..61134eb 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -370,7 +370,7 @@
 	if (!chan)
 		return;
 
- 	if (chan->is_global && chan->buf[0]) {
+	if (chan->is_global && chan->buf[0]) {
 		__relay_reset(chan->buf[0], 0);
 		return;
 	}
@@ -850,13 +850,13 @@
 		buf->subbufs_consumed = consumed;
 		buf->bytes_consumed = 0;
 	}
-	
+
 	produced = (produced % n_subbufs) * subbuf_size + buf->offset;
 	consumed = (consumed % n_subbufs) * subbuf_size + buf->bytes_consumed;
 
 	if (consumed > produced)
 		produced += n_subbufs * subbuf_size;
-	
+
 	if (consumed == produced)
 		return 0;
 
diff --git a/kernel/rtmutex-debug.c b/kernel/rtmutex-debug.c
index 6b0703d..56d73cb 100644
--- a/kernel/rtmutex-debug.c
+++ b/kernel/rtmutex-debug.c
@@ -87,7 +87,7 @@
 static void printk_task(struct task_struct *p)
 {
 	if (p)
-		printk("%16s:%5d [%p, %3d]", p->comm, p->pid, p, p->prio);
+		printk("%16s:%5d [%p, %3d]", p->comm, task_pid_nr(p), p, p->prio);
 	else
 		printk("<none>");
 }
@@ -152,22 +152,25 @@
 	printk(  "[ BUG: circular locking deadlock detected! ]\n");
 	printk(  "--------------------------------------------\n");
 	printk("%s/%d is deadlocking current task %s/%d\n\n",
-	       task->comm, task->pid, current->comm, current->pid);
+	       task->comm, task_pid_nr(task),
+	       current->comm, task_pid_nr(current));
 
 	printk("\n1) %s/%d is trying to acquire this lock:\n",
-	       current->comm, current->pid);
+	       current->comm, task_pid_nr(current));
 	printk_lock(waiter->lock, 1);
 
-	printk("\n2) %s/%d is blocked on this lock:\n", task->comm, task->pid);
+	printk("\n2) %s/%d is blocked on this lock:\n",
+		task->comm, task_pid_nr(task));
 	printk_lock(waiter->deadlock_lock, 1);
 
 	debug_show_held_locks(current);
 	debug_show_held_locks(task);
 
-	printk("\n%s/%d's [blocked] stackdump:\n\n", task->comm, task->pid);
+	printk("\n%s/%d's [blocked] stackdump:\n\n",
+		task->comm, task_pid_nr(task));
 	show_stack(task, NULL);
 	printk("\n%s/%d's [current] stackdump:\n\n",
-	       current->comm, current->pid);
+		current->comm, task_pid_nr(current));
 	dump_stack();
 	debug_show_all_locks();
 
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c
index 8cd9bd2..0deef71 100644
--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -185,7 +185,7 @@
 			prev_max = max_lock_depth;
 			printk(KERN_WARNING "Maximum lock depth %d reached "
 			       "task: %s (%d)\n", max_lock_depth,
-			       top_task->comm, top_task->pid);
+			       top_task->comm, task_pid_nr(top_task));
 		}
 		put_task_struct(task);
 
diff --git a/kernel/sched.c b/kernel/sched.c
index 92721d1..2810e56 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -44,6 +44,7 @@
 #include <linux/vmalloc.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/pid_namespace.h>
 #include <linux/smp.h>
 #include <linux/threads.h>
 #include <linux/timer.h>
@@ -51,6 +52,7 @@
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
 #include <linux/percpu.h>
+#include <linux/cpu_acct.h>
 #include <linux/kthread.h>
 #include <linux/seq_file.h>
 #include <linux/sysctl.h>
@@ -153,10 +155,15 @@
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
 
+#include <linux/cgroup.h>
+
 struct cfs_rq;
 
 /* task group related information */
 struct task_group {
+#ifdef CONFIG_FAIR_CGROUP_SCHED
+	struct cgroup_subsys_state css;
+#endif
 	/* schedulable entities of this group on each cpu */
 	struct sched_entity **se;
 	/* runqueue "owned" by this group on each cpu */
@@ -197,6 +204,9 @@
 
 #ifdef CONFIG_FAIR_USER_SCHED
 	tg = p->user->tg;
+#elif defined(CONFIG_FAIR_CGROUP_SCHED)
+	tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id),
+				struct task_group, css);
 #else
 	tg  = &init_task_group;
 #endif
@@ -266,7 +276,8 @@
  * acquire operations must be ordered by ascending &runqueue.
  */
 struct rq {
-	spinlock_t lock;	/* runqueue lock */
+	/* runqueue lock: */
+	spinlock_t lock;
 
 	/*
 	 * nr_running and cpu_load should be in the same cacheline because
@@ -279,13 +290,15 @@
 #ifdef CONFIG_NO_HZ
 	unsigned char in_nohz_recently;
 #endif
-	struct load_weight load;	/* capture load from *all* tasks on this cpu */
+	/* capture load from *all* tasks on this cpu: */
+	struct load_weight load;
 	unsigned long nr_load_updates;
 	u64 nr_switches;
 
 	struct cfs_rq cfs;
 #ifdef CONFIG_FAIR_GROUP_SCHED
-	struct list_head leaf_cfs_rq_list; /* list of leaf cfs_rq on this cpu */
+	/* list of leaf cfs_rq on this cpu: */
+	struct list_head leaf_cfs_rq_list;
 #endif
 	struct rt_rq  rt;
 
@@ -317,7 +330,8 @@
 	/* For active balancing */
 	int active_balance;
 	int push_cpu;
-	int cpu;		/* cpu of this runqueue */
+	/* cpu of this runqueue: */
+	int cpu;
 
 	struct task_struct *migration_thread;
 	struct list_head migration_queue;
@@ -328,22 +342,22 @@
 	struct sched_info rq_sched_info;
 
 	/* sys_sched_yield() stats */
-	unsigned long yld_exp_empty;
-	unsigned long yld_act_empty;
-	unsigned long yld_both_empty;
-	unsigned long yld_count;
+	unsigned int yld_exp_empty;
+	unsigned int yld_act_empty;
+	unsigned int yld_both_empty;
+	unsigned int yld_count;
 
 	/* schedule() stats */
-	unsigned long sched_switch;
-	unsigned long sched_count;
-	unsigned long sched_goidle;
+	unsigned int sched_switch;
+	unsigned int sched_count;
+	unsigned int sched_goidle;
 
 	/* try_to_wake_up() stats */
-	unsigned long ttwu_count;
-	unsigned long ttwu_local;
+	unsigned int ttwu_count;
+	unsigned int ttwu_local;
 
 	/* BKL stats */
-	unsigned long bkl_count;
+	unsigned int bkl_count;
 #endif
 	struct lock_class_key rq_lock_key;
 };
@@ -449,12 +463,12 @@
 };
 
 const_debug unsigned int sysctl_sched_features =
-		SCHED_FEAT_NEW_FAIR_SLEEPERS	*1 |
-		SCHED_FEAT_START_DEBIT		*1 |
-		SCHED_FEAT_TREE_AVG		*0 |
-		SCHED_FEAT_APPROX_AVG		*0 |
-		SCHED_FEAT_WAKEUP_PREEMPT	*1 |
-		SCHED_FEAT_PREEMPT_RESTRICT	*1;
+		SCHED_FEAT_NEW_FAIR_SLEEPERS	* 1 |
+		SCHED_FEAT_START_DEBIT		* 1 |
+		SCHED_FEAT_TREE_AVG		* 0 |
+		SCHED_FEAT_APPROX_AVG		* 0 |
+		SCHED_FEAT_WAKEUP_PREEMPT	* 1 |
+		SCHED_FEAT_PREEMPT_RESTRICT	* 1;
 
 #define sched_feat(x) (sysctl_sched_features & SCHED_FEAT_##x)
 
@@ -1871,7 +1885,7 @@
 	preempt_enable();
 #endif
 	if (current->set_child_tid)
-		put_user(current->pid, current->set_child_tid);
+		put_user(task_pid_vnr(current), current->set_child_tid);
 }
 
 /*
@@ -3296,16 +3310,19 @@
 /*
  * Account user cpu time to a process.
  * @p: the process that the cpu time gets accounted to
- * @hardirq_offset: the offset to subtract from hardirq_count()
  * @cputime: the cpu time spent in user space since the last update
  */
 void account_user_time(struct task_struct *p, cputime_t cputime)
 {
 	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
 	cputime64_t tmp;
+	struct rq *rq = this_rq();
 
 	p->utime = cputime_add(p->utime, cputime);
 
+	if (p != rq->idle)
+		cpuacct_charge(p, cputime);
+
 	/* Add user time to cpustat. */
 	tmp = cputime_to_cputime64(cputime);
 	if (TASK_NICE(p) > 0)
@@ -3334,6 +3351,16 @@
 }
 
 /*
+ * Account scaled user cpu time to a process.
+ * @p: the process that the cpu time gets accounted to
+ * @cputime: the cpu time spent in user space since the last update
+ */
+void account_user_time_scaled(struct task_struct *p, cputime_t cputime)
+{
+	p->utimescaled = cputime_add(p->utimescaled, cputime);
+}
+
+/*
  * Account system cpu time to a process.
  * @p: the process that the cpu time gets accounted to
  * @hardirq_offset: the offset to subtract from hardirq_count()
@@ -3348,7 +3375,6 @@
 
 	if (p->flags & PF_VCPU) {
 		account_guest_time(p, cputime);
-		p->flags &= ~PF_VCPU;
 		return;
 	}
 
@@ -3360,9 +3386,10 @@
 		cpustat->irq = cputime64_add(cpustat->irq, tmp);
 	else if (softirq_count())
 		cpustat->softirq = cputime64_add(cpustat->softirq, tmp);
-	else if (p != rq->idle)
+	else if (p != rq->idle) {
 		cpustat->system = cputime64_add(cpustat->system, tmp);
-	else if (atomic_read(&rq->nr_iowait) > 0)
+		cpuacct_charge(p, cputime);
+	} else if (atomic_read(&rq->nr_iowait) > 0)
 		cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
 	else
 		cpustat->idle = cputime64_add(cpustat->idle, tmp);
@@ -3371,6 +3398,17 @@
 }
 
 /*
+ * Account scaled system cpu time to a process.
+ * @p: the process that the cpu time gets accounted to
+ * @hardirq_offset: the offset to subtract from hardirq_count()
+ * @cputime: the cpu time spent in kernel space since the last update
+ */
+void account_system_time_scaled(struct task_struct *p, cputime_t cputime)
+{
+	p->stimescaled = cputime_add(p->stimescaled, cputime);
+}
+
+/*
  * Account for involuntary wait time.
  * @p: the process from which the cpu time has been stolen
  * @steal: the cpu time spent in involuntary wait
@@ -3387,8 +3425,10 @@
 			cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
 		else
 			cpustat->idle = cputime64_add(cpustat->idle, tmp);
-	} else
+	} else {
 		cpustat->steal = cputime64_add(cpustat->steal, tmp);
+		cpuacct_charge(p, -tmp);
+	}
 }
 
 /*
@@ -3468,7 +3508,7 @@
 static noinline void __schedule_bug(struct task_struct *prev)
 {
 	printk(KERN_ERR "BUG: scheduling while atomic: %s/0x%08x/%d\n",
-		prev->comm, preempt_count(), prev->pid);
+		prev->comm, preempt_count(), task_pid_nr(prev));
 	debug_show_held_locks(prev);
 	if (irqs_disabled())
 		print_irqtrace_events(prev);
@@ -3859,7 +3899,10 @@
 
 int __sched wait_for_completion_interruptible(struct completion *x)
 {
-	return wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE);
+	long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE);
+	if (t == -ERESTARTSYS)
+		return t;
+	return 0;
 }
 EXPORT_SYMBOL(wait_for_completion_interruptible);
 
@@ -4131,7 +4174,7 @@
  */
 static struct task_struct *find_process_by_pid(pid_t pid)
 {
-	return pid ? find_task_by_pid(pid) : current;
+	return pid ? find_task_by_vpid(pid) : current;
 }
 
 /* Actually do priority change: must hold rq lock. */
@@ -4434,8 +4477,21 @@
 
 	cpus_allowed = cpuset_cpus_allowed(p);
 	cpus_and(new_mask, new_mask, cpus_allowed);
+ again:
 	retval = set_cpus_allowed(p, new_mask);
 
+	if (!retval) {
+		cpus_allowed = cpuset_cpus_allowed(p);
+		if (!cpus_subset(new_mask, cpus_allowed)) {
+			/*
+			 * We must have raced with a concurrent cpuset
+			 * update. Just reset the cpus_allowed to the
+			 * cpuset's cpus_allowed
+			 */
+			new_mask = cpus_allowed;
+			goto again;
+		}
+	}
 out_unlock:
 	put_task_struct(p);
 	mutex_unlock(&sched_hotcpu_mutex);
@@ -4794,18 +4850,18 @@
 	unsigned state;
 
 	state = p->state ? __ffs(p->state) + 1 : 0;
-	printk("%-13.13s %c", p->comm,
+	printk(KERN_INFO "%-13.13s %c", p->comm,
 		state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?');
 #if BITS_PER_LONG == 32
 	if (state == TASK_RUNNING)
-		printk(" running  ");
+		printk(KERN_CONT " running  ");
 	else
-		printk(" %08lx ", thread_saved_pc(p));
+		printk(KERN_CONT " %08lx ", thread_saved_pc(p));
 #else
 	if (state == TASK_RUNNING)
-		printk("  running task    ");
+		printk(KERN_CONT "  running task    ");
 	else
-		printk(" %016lx ", thread_saved_pc(p));
+		printk(KERN_CONT " %016lx ", thread_saved_pc(p));
 #endif
 #ifdef CONFIG_DEBUG_STACK_USAGE
 	{
@@ -4815,7 +4871,8 @@
 		free = (unsigned long)n - (unsigned long)end_of_stack(p);
 	}
 #endif
-	printk("%5lu %5d %6d\n", free, p->pid, p->parent->pid);
+	printk(KERN_CONT "%5lu %5d %6d\n", free,
+		task_pid_nr(p), task_pid_nr(p->parent));
 
 	if (state != TASK_RUNNING)
 		show_stack(p, NULL);
@@ -5087,7 +5144,7 @@
 }
 
 /*
- * Figure out where task on dead CPU should go, use force if neccessary.
+ * Figure out where task on dead CPU should go, use force if necessary.
  * NOTE: interrupts should be disabled by the caller
  */
 static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
@@ -5109,8 +5166,16 @@
 
 		/* No more Mr. Nice Guy. */
 		if (dest_cpu == NR_CPUS) {
+			cpumask_t cpus_allowed = cpuset_cpus_allowed_locked(p);
+			/*
+			 * Try to stay on the same cpuset, where the
+			 * current cpuset may be a subset of all cpus.
+			 * The cpuset_cpus_allowed_locked() variant of
+			 * cpuset_cpus_allowed() will not block.  It must be
+			 * called within calls to cpuset_lock/cpuset_unlock.
+			 */
 			rq = task_rq_lock(p, &flags);
-			cpus_setall(p->cpus_allowed);
+			p->cpus_allowed = cpus_allowed;
 			dest_cpu = any_online_cpu(p->cpus_allowed);
 			task_rq_unlock(rq, &flags);
 
@@ -5122,7 +5187,7 @@
 			if (p->mm && printk_ratelimit())
 				printk(KERN_INFO "process %d (%s) no "
 				       "longer affine to cpu%d\n",
-				       p->pid, p->comm, dead_cpu);
+			       task_pid_nr(p), p->comm, dead_cpu);
 		}
 	} while (!__migrate_task_irq(p, dead_cpu, dest_cpu));
 }
@@ -5229,7 +5294,7 @@
 	struct rq *rq = cpu_rq(dead_cpu);
 
 	/* Must be exiting, otherwise would be on tasklist. */
-	BUG_ON(p->exit_state != EXIT_ZOMBIE && p->exit_state != EXIT_DEAD);
+	BUG_ON(!p->exit_state);
 
 	/* Cannot have done final schedule yet: would have vanished. */
 	BUG_ON(p->state == TASK_DEAD);
@@ -5364,7 +5429,7 @@
 	return table;
 }
 
-static ctl_table *sd_alloc_ctl_cpu_table(int cpu)
+static ctl_table * sd_alloc_ctl_cpu_table(int cpu)
 {
 	struct ctl_table *entry, *table;
 	struct sched_domain *sd;
@@ -5458,7 +5523,7 @@
 
 	case CPU_ONLINE:
 	case CPU_ONLINE_FROZEN:
-		/* Strictly unneccessary, as first user will wake it. */
+		/* Strictly unnecessary, as first user will wake it. */
 		wake_up_process(cpu_rq(cpu)->migration_thread);
 		break;
 
@@ -5476,6 +5541,7 @@
 
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
+		cpuset_lock(); /* around calls to cpuset_cpus_allowed_lock() */
 		migrate_live_tasks(cpu);
 		rq = cpu_rq(cpu);
 		kthread_stop(rq->migration_thread);
@@ -5489,6 +5555,7 @@
 		rq->idle->sched_class = &idle_sched_class;
 		migrate_dead_tasks(cpu);
 		spin_unlock_irq(&rq->lock);
+		cpuset_unlock();
 		migrate_nr_uninterruptible(rq);
 		BUG_ON(rq->nr_running != 0);
 
@@ -5598,20 +5665,20 @@
 			}
 
 			if (!group->__cpu_power) {
-				printk("\n");
+				printk(KERN_CONT "\n");
 				printk(KERN_ERR "ERROR: domain->cpu_power not "
 						"set\n");
 				break;
 			}
 
 			if (!cpus_weight(group->cpumask)) {
-				printk("\n");
+				printk(KERN_CONT "\n");
 				printk(KERN_ERR "ERROR: empty group\n");
 				break;
 			}
 
 			if (cpus_intersects(groupmask, group->cpumask)) {
-				printk("\n");
+				printk(KERN_CONT "\n");
 				printk(KERN_ERR "ERROR: repeated CPUs\n");
 				break;
 			}
@@ -5619,11 +5686,11 @@
 			cpus_or(groupmask, groupmask, group->cpumask);
 
 			cpumask_scnprintf(str, NR_CPUS, group->cpumask);
-			printk(" %s", str);
+			printk(KERN_CONT " %s", str);
 
 			group = group->next;
 		} while (group != sd->groups);
-		printk("\n");
+		printk(KERN_CONT "\n");
 
 		if (!cpus_equal(sd->span, groupmask))
 			printk(KERN_ERR "ERROR: groups don't span "
@@ -6339,26 +6406,31 @@
 	return -ENOMEM;
 #endif
 }
+
+static cpumask_t *doms_cur;	/* current sched domains */
+static int ndoms_cur;		/* number of sched domains in 'doms_cur' */
+
+/*
+ * Special case: If a kmalloc of a doms_cur partition (array of
+ * cpumask_t) fails, then fallback to a single sched domain,
+ * as determined by the single cpumask_t fallback_doms.
+ */
+static cpumask_t fallback_doms;
+
 /*
  * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
+ * For now this just excludes isolated cpus, but could be used to
+ * exclude other special cases in the future.
  */
 static int arch_init_sched_domains(const cpumask_t *cpu_map)
 {
-	cpumask_t cpu_default_map;
-	int err;
-
-	/*
-	 * Setup mask for cpus without special case scheduling requirements.
-	 * For now this just excludes isolated cpus, but could be used to
-	 * exclude other special cases in the future.
-	 */
-	cpus_andnot(cpu_default_map, *cpu_map, cpu_isolated_map);
-
-	err = build_sched_domains(&cpu_default_map);
-
+	ndoms_cur = 1;
+	doms_cur = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
+	if (!doms_cur)
+		doms_cur = &fallback_doms;
+	cpus_andnot(*doms_cur, *cpu_map, cpu_isolated_map);
 	register_sched_domain_sysctl();
-
-	return err;
+	return build_sched_domains(doms_cur);
 }
 
 static void arch_destroy_sched_domains(const cpumask_t *cpu_map)
@@ -6382,6 +6454,68 @@
 	arch_destroy_sched_domains(cpu_map);
 }
 
+/*
+ * Partition sched domains as specified by the 'ndoms_new'
+ * cpumasks in the array doms_new[] of cpumasks.  This compares
+ * doms_new[] to the current sched domain partitioning, doms_cur[].
+ * It destroys each deleted domain and builds each new domain.
+ *
+ * 'doms_new' is an array of cpumask_t's of length 'ndoms_new'.
+ * The masks don't intersect (don't overlap.)  We should setup one
+ * sched domain for each mask.  CPUs not in any of the cpumasks will
+ * not be load balanced.  If the same cpumask appears both in the
+ * current 'doms_cur' domains and in the new 'doms_new', we can leave
+ * it as it is.
+ *
+ * The passed in 'doms_new' should be kmalloc'd.  This routine takes
+ * ownership of it and will kfree it when done with it.  If the caller
+ * failed the kmalloc call, then it can pass in doms_new == NULL,
+ * and partition_sched_domains() will fallback to the single partition
+ * 'fallback_doms'.
+ *
+ * Call with hotplug lock held
+ */
+void partition_sched_domains(int ndoms_new, cpumask_t *doms_new)
+{
+	int i, j;
+
+	if (doms_new == NULL) {
+		ndoms_new = 1;
+		doms_new = &fallback_doms;
+		cpus_andnot(doms_new[0], cpu_online_map, cpu_isolated_map);
+	}
+
+	/* Destroy deleted domains */
+	for (i = 0; i < ndoms_cur; i++) {
+		for (j = 0; j < ndoms_new; j++) {
+			if (cpus_equal(doms_cur[i], doms_new[j]))
+				goto match1;
+		}
+		/* no match - a current sched domain not in new doms_new[] */
+		detach_destroy_domains(doms_cur + i);
+match1:
+		;
+	}
+
+	/* Build new domains */
+	for (i = 0; i < ndoms_new; i++) {
+		for (j = 0; j < ndoms_cur; j++) {
+			if (cpus_equal(doms_new[i], doms_cur[j]))
+				goto match2;
+		}
+		/* no match - add a new doms_new */
+		build_sched_domains(doms_new + i);
+match2:
+		;
+	}
+
+	/* Remember the new sched domains */
+	if (doms_cur != &fallback_doms)
+		kfree(doms_cur);
+	doms_cur = doms_new;
+	ndoms_cur = ndoms_new;
+}
+
 #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
 static int arch_reinit_sched_domains(void)
 {
@@ -6963,3 +7097,116 @@
 }
 
 #endif	/* CONFIG_FAIR_GROUP_SCHED */
+
+#ifdef CONFIG_FAIR_CGROUP_SCHED
+
+/* return corresponding task_group object of a cgroup */
+static inline struct task_group *cgroup_tg(struct cgroup *cont)
+{
+	return container_of(cgroup_subsys_state(cont, cpu_cgroup_subsys_id),
+					 struct task_group, css);
+}
+
+static struct cgroup_subsys_state *
+cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+	struct task_group *tg;
+
+	if (!cont->parent) {
+		/* This is early initialization for the top cgroup */
+		init_task_group.css.cgroup = cont;
+		return &init_task_group.css;
+	}
+
+	/* we support only 1-level deep hierarchical scheduler atm */
+	if (cont->parent->parent)
+		return ERR_PTR(-EINVAL);
+
+	tg = sched_create_group();
+	if (IS_ERR(tg))
+		return ERR_PTR(-ENOMEM);
+
+	/* Bind the cgroup to task_group object we just created */
+	tg->css.cgroup = cont;
+
+	return &tg->css;
+}
+
+static void cpu_cgroup_destroy(struct cgroup_subsys *ss,
+					struct cgroup *cont)
+{
+	struct task_group *tg = cgroup_tg(cont);
+
+	sched_destroy_group(tg);
+}
+
+static int cpu_cgroup_can_attach(struct cgroup_subsys *ss,
+			     struct cgroup *cont, struct task_struct *tsk)
+{
+	/* We don't support RT-tasks being in separate groups */
+	if (tsk->sched_class != &fair_sched_class)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void
+cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cont,
+			struct cgroup *old_cont, struct task_struct *tsk)
+{
+	sched_move_task(tsk);
+}
+
+static ssize_t cpu_shares_write(struct cgroup *cont, struct cftype *cftype,
+				struct file *file, const char __user *userbuf,
+				size_t nbytes, loff_t *ppos)
+{
+	unsigned long shareval;
+	struct task_group *tg = cgroup_tg(cont);
+	char buffer[2*sizeof(unsigned long) + 1];
+	int rc;
+
+	if (nbytes > 2*sizeof(unsigned long))	/* safety check */
+		return -E2BIG;
+
+	if (copy_from_user(buffer, userbuf, nbytes))
+		return -EFAULT;
+
+	buffer[nbytes] = 0;	/* nul-terminate */
+	shareval = simple_strtoul(buffer, NULL, 10);
+
+	rc = sched_group_set_shares(tg, shareval);
+
+	return (rc < 0 ? rc : nbytes);
+}
+
+static u64 cpu_shares_read_uint(struct cgroup *cont, struct cftype *cft)
+{
+	struct task_group *tg = cgroup_tg(cont);
+
+	return (u64) tg->shares;
+}
+
+static struct cftype cpu_shares = {
+	.name = "shares",
+	.read_uint = cpu_shares_read_uint,
+	.write = cpu_shares_write,
+};
+
+static int cpu_cgroup_populate(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+	return cgroup_add_file(cont, ss, &cpu_shares);
+}
+
+struct cgroup_subsys cpu_cgroup_subsys = {
+	.name 	    	= "cpu",
+	.create	    	= cpu_cgroup_create,
+	.destroy    	= cpu_cgroup_destroy,
+	.can_attach 	= cpu_cgroup_can_attach,
+	.attach     	= cpu_cgroup_attach,
+	.populate   	= cpu_cgroup_populate,
+	.subsys_id  	= cpu_cgroup_subsys_id,
+	.early_init	= 1,
+};
+
+#endif	/* CONFIG_FAIR_CGROUP_SCHED */
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index a5e517e..e6fb392 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -137,7 +137,7 @@
 	SEQ_printf(m, "  .%-30s: %ld\n", "nr_running", cfs_rq->nr_running);
 	SEQ_printf(m, "  .%-30s: %ld\n", "load", cfs_rq->load.weight);
 #ifdef CONFIG_SCHEDSTATS
-	SEQ_printf(m, "  .%-30s: %ld\n", "bkl_count",
+	SEQ_printf(m, "  .%-30s: %d\n", "bkl_count",
 			rq->bkl_count);
 #endif
 	SEQ_printf(m, "  .%-30s: %ld\n", "nr_spread_over",
diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h
index 1c08484..ef1a7df 100644
--- a/kernel/sched_stats.h
+++ b/kernel/sched_stats.h
@@ -21,7 +21,7 @@
 
 		/* runqueue-specific stats */
 		seq_printf(seq,
-		    "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %llu %llu %lu",
+		    "cpu%d %u %u %u %u %u %u %u %u %u %llu %llu %lu",
 		    cpu, rq->yld_both_empty,
 		    rq->yld_act_empty, rq->yld_exp_empty, rq->yld_count,
 		    rq->sched_switch, rq->sched_count, rq->sched_goidle,
@@ -42,8 +42,7 @@
 			seq_printf(seq, "domain%d %s", dcount++, mask_str);
 			for (itype = CPU_IDLE; itype < CPU_MAX_IDLE_TYPES;
 					itype++) {
-				seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu "
-						"%lu",
+				seq_printf(seq, " %u %u %u %u %u %u %u %u",
 				    sd->lb_count[itype],
 				    sd->lb_balanced[itype],
 				    sd->lb_failed[itype],
@@ -53,8 +52,7 @@
 				    sd->lb_nobusyq[itype],
 				    sd->lb_nobusyg[itype]);
 			}
-			seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu"
-			    " %lu %lu %lu\n",
+			seq_printf(seq, " %u %u %u %u %u %u %u %u %u %u %u %u\n",
 			    sd->alb_count, sd->alb_failed, sd->alb_pushed,
 			    sd->sbe_count, sd->sbe_balanced, sd->sbe_pushed,
 			    sd->sbf_count, sd->sbf_balanced, sd->sbf_pushed,
diff --git a/kernel/signal.c b/kernel/signal.c
index 2124ffa..1200630 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -99,7 +99,6 @@
 static int recalc_sigpending_tsk(struct task_struct *t)
 {
 	if (t->signal->group_stop_count > 0 ||
-	    (freezing(t)) ||
 	    PENDING(&t->pending, &t->blocked) ||
 	    PENDING(&t->signal->shared_pending, &t->blocked)) {
 		set_tsk_thread_flag(t, TIF_SIGPENDING);
@@ -257,7 +256,7 @@
 
 int unhandled_signal(struct task_struct *tsk, int sig)
 {
-	if (is_init(tsk))
+	if (is_global_init(tsk))
 		return 1;
 	if (tsk->ptrace & PT_PTRACED)
 		return 0;
@@ -537,7 +536,7 @@
 			return error;
 		error = -EPERM;
 		if (((sig != SIGCONT) ||
-			(process_session(current) != process_session(t)))
+			(task_session_nr(current) != task_session_nr(t)))
 		    && (current->euid ^ t->suid) && (current->euid ^ t->uid)
 		    && (current->uid ^ t->suid) && (current->uid ^ t->uid)
 		    && !capable(CAP_KILL))
@@ -695,7 +694,7 @@
 			q->info.si_signo = sig;
 			q->info.si_errno = 0;
 			q->info.si_code = SI_USER;
-			q->info.si_pid = current->pid;
+			q->info.si_pid = task_pid_vnr(current);
 			q->info.si_uid = current->uid;
 			break;
 		case (unsigned long) SEND_SIG_PRIV:
@@ -731,7 +730,7 @@
 static void print_fatal_signal(struct pt_regs *regs, int signr)
 {
 	printk("%s/%d: potentially unexpected fatal signal %d.\n",
-		current->comm, current->pid, signr);
+		current->comm, task_pid_nr(current), signr);
 
 #ifdef __i386__
 	printk("code at %08lx: ", regs->eip);
@@ -1090,7 +1089,7 @@
 {
 	int error;
 	rcu_read_lock();
-	error = kill_pid_info(sig, info, find_pid(pid));
+	error = kill_pid_info(sig, info, find_vpid(pid));
 	rcu_read_unlock();
 	return error;
 }
@@ -1151,7 +1150,7 @@
 
 		read_lock(&tasklist_lock);
 		for_each_process(p) {
-			if (p->pid > 1 && p->tgid != current->tgid) {
+			if (p->pid > 1 && !same_thread_group(p, current)) {
 				int err = group_send_sig_info(sig, info, p);
 				++count;
 				if (err != -EPERM)
@@ -1161,9 +1160,9 @@
 		read_unlock(&tasklist_lock);
 		ret = count ? retval : -ESRCH;
 	} else if (pid < 0) {
-		ret = kill_pgrp_info(sig, info, find_pid(-pid));
+		ret = kill_pgrp_info(sig, info, find_vpid(-pid));
 	} else {
-		ret = kill_pid_info(sig, info, find_pid(pid));
+		ret = kill_pid_info(sig, info, find_vpid(pid));
 	}
 	rcu_read_unlock();
 	return ret;
@@ -1267,7 +1266,12 @@
 int
 kill_proc(pid_t pid, int sig, int priv)
 {
-	return kill_proc_info(sig, __si_special(priv), pid);
+	int ret;
+
+	rcu_read_lock();
+	ret = kill_pid_info(sig, __si_special(priv), find_pid(pid));
+	rcu_read_unlock();
+	return ret;
 }
 
 /*
@@ -1444,7 +1448,22 @@
 
 	info.si_signo = sig;
 	info.si_errno = 0;
-	info.si_pid = tsk->pid;
+	/*
+	 * we are under tasklist_lock here so our parent is tied to
+	 * us and cannot exit and release its namespace.
+	 *
+	 * the only it can is to switch its nsproxy with sys_unshare,
+	 * bu uncharing pid namespaces is not allowed, so we'll always
+	 * see relevant namespace
+	 *
+	 * write_lock() currently calls preempt_disable() which is the
+	 * same as rcu_read_lock(), but according to Oleg, this is not
+	 * correct to rely on this
+	 */
+	rcu_read_lock();
+	info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns);
+	rcu_read_unlock();
+
 	info.si_uid = tsk->uid;
 
 	/* FIXME: find out whether or not this is supposed to be c*time. */
@@ -1509,7 +1528,13 @@
 
 	info.si_signo = SIGCHLD;
 	info.si_errno = 0;
-	info.si_pid = tsk->pid;
+	/*
+	 * see comment in do_notify_parent() abot the following 3 lines
+	 */
+	rcu_read_lock();
+	info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns);
+	rcu_read_unlock();
+
 	info.si_uid = tsk->uid;
 
 	/* FIXME: find out whether or not this is supposed to be c*time. */
@@ -1635,7 +1660,7 @@
 	memset(&info, 0, sizeof info);
 	info.si_signo = SIGTRAP;
 	info.si_code = exit_code;
-	info.si_pid = current->pid;
+	info.si_pid = task_pid_vnr(current);
 	info.si_uid = current->uid;
 
 	/* Let the debugger run.  */
@@ -1805,7 +1830,7 @@
 				info->si_signo = signr;
 				info->si_errno = 0;
 				info->si_code = SI_USER;
-				info->si_pid = current->parent->pid;
+				info->si_pid = task_pid_vnr(current->parent);
 				info->si_uid = current->parent->uid;
 			}
 
@@ -1836,11 +1861,9 @@
 			continue;
 
 		/*
-		 * Init of a pid space gets no signals it doesn't want from
-		 * within that pid space. It can of course get signals from
-		 * its parent pid space.
+		 * Global init gets no signals it doesn't want.
 		 */
-		if (current == child_reaper(current))
+		if (is_global_init(current))
 			continue;
 
 		if (sig_kernel_stop(signr)) {
@@ -2194,7 +2217,7 @@
 	info.si_signo = sig;
 	info.si_errno = 0;
 	info.si_code = SI_USER;
-	info.si_pid = current->tgid;
+	info.si_pid = task_tgid_vnr(current);
 	info.si_uid = current->uid;
 
 	return kill_something_info(sig, &info, pid);
@@ -2210,12 +2233,12 @@
 	info.si_signo = sig;
 	info.si_errno = 0;
 	info.si_code = SI_TKILL;
-	info.si_pid = current->tgid;
+	info.si_pid = task_tgid_vnr(current);
 	info.si_uid = current->uid;
 
 	read_lock(&tasklist_lock);
-	p = find_task_by_pid(pid);
-	if (p && (tgid <= 0 || p->tgid == tgid)) {
+	p = find_task_by_vpid(pid);
+	if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid)) {
 		error = check_kill_permission(sig, &info, p);
 		/*
 		 * The null signal is a permissions and process existence
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index edeeef3..11df812 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -113,7 +113,7 @@
 	spin_lock(&print_lock);
 	printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n",
 			this_cpu, now - touch_timestamp,
-				current->comm, current->pid);
+			current->comm, task_pid_nr(current));
 	if (regs)
 		show_regs(regs);
 	else
diff --git a/kernel/sys.c b/kernel/sys.c
index 8ae2e63..304b541 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -105,538 +105,6 @@
  */
 
 void (*pm_power_off_prepare)(void);
-EXPORT_SYMBOL(pm_power_off_prepare);
-
-/*
- *	Notifier list for kernel code which wants to be called
- *	at shutdown. This is used to stop any idling DMA operations
- *	and the like. 
- */
-
-static BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
-
-/*
- *	Notifier chain core routines.  The exported routines below
- *	are layered on top of these, with appropriate locking added.
- */
-
-static int notifier_chain_register(struct notifier_block **nl,
-		struct notifier_block *n)
-{
-	while ((*nl) != NULL) {
-		if (n->priority > (*nl)->priority)
-			break;
-		nl = &((*nl)->next);
-	}
-	n->next = *nl;
-	rcu_assign_pointer(*nl, n);
-	return 0;
-}
-
-static int notifier_chain_unregister(struct notifier_block **nl,
-		struct notifier_block *n)
-{
-	while ((*nl) != NULL) {
-		if ((*nl) == n) {
-			rcu_assign_pointer(*nl, n->next);
-			return 0;
-		}
-		nl = &((*nl)->next);
-	}
-	return -ENOENT;
-}
-
-/**
- * notifier_call_chain - Informs the registered notifiers about an event.
- *	@nl:		Pointer to head of the blocking notifier chain
- *	@val:		Value passed unmodified to notifier function
- *	@v:		Pointer passed unmodified to notifier function
- *	@nr_to_call:	Number of notifier functions to be called. Don't care
- *		     	value of this parameter is -1.
- *	@nr_calls:	Records the number of notifications sent. Don't care
- *		   	value of this field is NULL.
- * 	@returns:	notifier_call_chain returns the value returned by the
- *			last notifier function called.
- */
-
-static int __kprobes notifier_call_chain(struct notifier_block **nl,
-					unsigned long val, void *v,
-					int nr_to_call,	int *nr_calls)
-{
-	int ret = NOTIFY_DONE;
-	struct notifier_block *nb, *next_nb;
-
-	nb = rcu_dereference(*nl);
-
-	while (nb && nr_to_call) {
-		next_nb = rcu_dereference(nb->next);
-		ret = nb->notifier_call(nb, val, v);
-
-		if (nr_calls)
-			(*nr_calls)++;
-
-		if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)
-			break;
-		nb = next_nb;
-		nr_to_call--;
-	}
-	return ret;
-}
-
-/*
- *	Atomic notifier chain routines.  Registration and unregistration
- *	use a spinlock, and call_chain is synchronized by RCU (no locks).
- */
-
-/**
- *	atomic_notifier_chain_register - Add notifier to an atomic notifier chain
- *	@nh: Pointer to head of the atomic notifier chain
- *	@n: New entry in notifier chain
- *
- *	Adds a notifier to an atomic notifier chain.
- *
- *	Currently always returns zero.
- */
-
-int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
-		struct notifier_block *n)
-{
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&nh->lock, flags);
-	ret = notifier_chain_register(&nh->head, n);
-	spin_unlock_irqrestore(&nh->lock, flags);
-	return ret;
-}
-
-EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
-
-/**
- *	atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
- *	@nh: Pointer to head of the atomic notifier chain
- *	@n: Entry to remove from notifier chain
- *
- *	Removes a notifier from an atomic notifier chain.
- *
- *	Returns zero on success or %-ENOENT on failure.
- */
-int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
-		struct notifier_block *n)
-{
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&nh->lock, flags);
-	ret = notifier_chain_unregister(&nh->head, n);
-	spin_unlock_irqrestore(&nh->lock, flags);
-	synchronize_rcu();
-	return ret;
-}
-
-EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
-
-/**
- *	__atomic_notifier_call_chain - Call functions in an atomic notifier chain
- *	@nh: Pointer to head of the atomic notifier chain
- *	@val: Value passed unmodified to notifier function
- *	@v: Pointer passed unmodified to notifier function
- *	@nr_to_call: See the comment for notifier_call_chain.
- *	@nr_calls: See the comment for notifier_call_chain.
- *
- *	Calls each function in a notifier chain in turn.  The functions
- *	run in an atomic context, so they must not block.
- *	This routine uses RCU to synchronize with changes to the chain.
- *
- *	If the return value of the notifier can be and'ed
- *	with %NOTIFY_STOP_MASK then atomic_notifier_call_chain()
- *	will return immediately, with the return value of
- *	the notifier function which halted execution.
- *	Otherwise the return value is the return value
- *	of the last notifier function called.
- */
- 
-int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh,
-					unsigned long val, void *v,
-					int nr_to_call, int *nr_calls)
-{
-	int ret;
-
-	rcu_read_lock();
-	ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
-	rcu_read_unlock();
-	return ret;
-}
-
-EXPORT_SYMBOL_GPL(__atomic_notifier_call_chain);
-
-int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh,
-		unsigned long val, void *v)
-{
-	return __atomic_notifier_call_chain(nh, val, v, -1, NULL);
-}
-
-EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
-/*
- *	Blocking notifier chain routines.  All access to the chain is
- *	synchronized by an rwsem.
- */
-
-/**
- *	blocking_notifier_chain_register - Add notifier to a blocking notifier chain
- *	@nh: Pointer to head of the blocking notifier chain
- *	@n: New entry in notifier chain
- *
- *	Adds a notifier to a blocking notifier chain.
- *	Must be called in process context.
- *
- *	Currently always returns zero.
- */
- 
-int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
-		struct notifier_block *n)
-{
-	int ret;
-
-	/*
-	 * This code gets used during boot-up, when task switching is
-	 * not yet working and interrupts must remain disabled.  At
-	 * such times we must not call down_write().
-	 */
-	if (unlikely(system_state == SYSTEM_BOOTING))
-		return notifier_chain_register(&nh->head, n);
-
-	down_write(&nh->rwsem);
-	ret = notifier_chain_register(&nh->head, n);
-	up_write(&nh->rwsem);
-	return ret;
-}
-
-EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
-
-/**
- *	blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
- *	@nh: Pointer to head of the blocking notifier chain
- *	@n: Entry to remove from notifier chain
- *
- *	Removes a notifier from a blocking notifier chain.
- *	Must be called from process context.
- *
- *	Returns zero on success or %-ENOENT on failure.
- */
-int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
-		struct notifier_block *n)
-{
-	int ret;
-
-	/*
-	 * This code gets used during boot-up, when task switching is
-	 * not yet working and interrupts must remain disabled.  At
-	 * such times we must not call down_write().
-	 */
-	if (unlikely(system_state == SYSTEM_BOOTING))
-		return notifier_chain_unregister(&nh->head, n);
-
-	down_write(&nh->rwsem);
-	ret = notifier_chain_unregister(&nh->head, n);
-	up_write(&nh->rwsem);
-	return ret;
-}
-
-EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
-
-/**
- *	__blocking_notifier_call_chain - Call functions in a blocking notifier chain
- *	@nh: Pointer to head of the blocking notifier chain
- *	@val: Value passed unmodified to notifier function
- *	@v: Pointer passed unmodified to notifier function
- *	@nr_to_call: See comment for notifier_call_chain.
- *	@nr_calls: See comment for notifier_call_chain.
- *
- *	Calls each function in a notifier chain in turn.  The functions
- *	run in a process context, so they are allowed to block.
- *
- *	If the return value of the notifier can be and'ed
- *	with %NOTIFY_STOP_MASK then blocking_notifier_call_chain()
- *	will return immediately, with the return value of
- *	the notifier function which halted execution.
- *	Otherwise the return value is the return value
- *	of the last notifier function called.
- */
- 
-int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
-				   unsigned long val, void *v,
-				   int nr_to_call, int *nr_calls)
-{
-	int ret = NOTIFY_DONE;
-
-	/*
-	 * We check the head outside the lock, but if this access is
-	 * racy then it does not matter what the result of the test
-	 * is, we re-check the list after having taken the lock anyway:
-	 */
-	if (rcu_dereference(nh->head)) {
-		down_read(&nh->rwsem);
-		ret = notifier_call_chain(&nh->head, val, v, nr_to_call,
-					nr_calls);
-		up_read(&nh->rwsem);
-	}
-	return ret;
-}
-EXPORT_SYMBOL_GPL(__blocking_notifier_call_chain);
-
-int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
-		unsigned long val, void *v)
-{
-	return __blocking_notifier_call_chain(nh, val, v, -1, NULL);
-}
-EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
-
-/*
- *	Raw notifier chain routines.  There is no protection;
- *	the caller must provide it.  Use at your own risk!
- */
-
-/**
- *	raw_notifier_chain_register - Add notifier to a raw notifier chain
- *	@nh: Pointer to head of the raw notifier chain
- *	@n: New entry in notifier chain
- *
- *	Adds a notifier to a raw notifier chain.
- *	All locking must be provided by the caller.
- *
- *	Currently always returns zero.
- */
-
-int raw_notifier_chain_register(struct raw_notifier_head *nh,
-		struct notifier_block *n)
-{
-	return notifier_chain_register(&nh->head, n);
-}
-
-EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
-
-/**
- *	raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
- *	@nh: Pointer to head of the raw notifier chain
- *	@n: Entry to remove from notifier chain
- *
- *	Removes a notifier from a raw notifier chain.
- *	All locking must be provided by the caller.
- *
- *	Returns zero on success or %-ENOENT on failure.
- */
-int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
-		struct notifier_block *n)
-{
-	return notifier_chain_unregister(&nh->head, n);
-}
-
-EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
-
-/**
- *	__raw_notifier_call_chain - Call functions in a raw notifier chain
- *	@nh: Pointer to head of the raw notifier chain
- *	@val: Value passed unmodified to notifier function
- *	@v: Pointer passed unmodified to notifier function
- *	@nr_to_call: See comment for notifier_call_chain.
- *	@nr_calls: See comment for notifier_call_chain
- *
- *	Calls each function in a notifier chain in turn.  The functions
- *	run in an undefined context.
- *	All locking must be provided by the caller.
- *
- *	If the return value of the notifier can be and'ed
- *	with %NOTIFY_STOP_MASK then raw_notifier_call_chain()
- *	will return immediately, with the return value of
- *	the notifier function which halted execution.
- *	Otherwise the return value is the return value
- *	of the last notifier function called.
- */
-
-int __raw_notifier_call_chain(struct raw_notifier_head *nh,
-			      unsigned long val, void *v,
-			      int nr_to_call, int *nr_calls)
-{
-	return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
-}
-
-EXPORT_SYMBOL_GPL(__raw_notifier_call_chain);
-
-int raw_notifier_call_chain(struct raw_notifier_head *nh,
-		unsigned long val, void *v)
-{
-	return __raw_notifier_call_chain(nh, val, v, -1, NULL);
-}
-
-EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
-
-/*
- *	SRCU notifier chain routines.    Registration and unregistration
- *	use a mutex, and call_chain is synchronized by SRCU (no locks).
- */
-
-/**
- *	srcu_notifier_chain_register - Add notifier to an SRCU notifier chain
- *	@nh: Pointer to head of the SRCU notifier chain
- *	@n: New entry in notifier chain
- *
- *	Adds a notifier to an SRCU notifier chain.
- *	Must be called in process context.
- *
- *	Currently always returns zero.
- */
-
-int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
-		struct notifier_block *n)
-{
-	int ret;
-
-	/*
-	 * This code gets used during boot-up, when task switching is
-	 * not yet working and interrupts must remain disabled.  At
-	 * such times we must not call mutex_lock().
-	 */
-	if (unlikely(system_state == SYSTEM_BOOTING))
-		return notifier_chain_register(&nh->head, n);
-
-	mutex_lock(&nh->mutex);
-	ret = notifier_chain_register(&nh->head, n);
-	mutex_unlock(&nh->mutex);
-	return ret;
-}
-
-EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);
-
-/**
- *	srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain
- *	@nh: Pointer to head of the SRCU notifier chain
- *	@n: Entry to remove from notifier chain
- *
- *	Removes a notifier from an SRCU notifier chain.
- *	Must be called from process context.
- *
- *	Returns zero on success or %-ENOENT on failure.
- */
-int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
-		struct notifier_block *n)
-{
-	int ret;
-
-	/*
-	 * This code gets used during boot-up, when task switching is
-	 * not yet working and interrupts must remain disabled.  At
-	 * such times we must not call mutex_lock().
-	 */
-	if (unlikely(system_state == SYSTEM_BOOTING))
-		return notifier_chain_unregister(&nh->head, n);
-
-	mutex_lock(&nh->mutex);
-	ret = notifier_chain_unregister(&nh->head, n);
-	mutex_unlock(&nh->mutex);
-	synchronize_srcu(&nh->srcu);
-	return ret;
-}
-
-EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);
-
-/**
- *	__srcu_notifier_call_chain - Call functions in an SRCU notifier chain
- *	@nh: Pointer to head of the SRCU notifier chain
- *	@val: Value passed unmodified to notifier function
- *	@v: Pointer passed unmodified to notifier function
- *	@nr_to_call: See comment for notifier_call_chain.
- *	@nr_calls: See comment for notifier_call_chain
- *
- *	Calls each function in a notifier chain in turn.  The functions
- *	run in a process context, so they are allowed to block.
- *
- *	If the return value of the notifier can be and'ed
- *	with %NOTIFY_STOP_MASK then srcu_notifier_call_chain()
- *	will return immediately, with the return value of
- *	the notifier function which halted execution.
- *	Otherwise the return value is the return value
- *	of the last notifier function called.
- */
-
-int __srcu_notifier_call_chain(struct srcu_notifier_head *nh,
-			       unsigned long val, void *v,
-			       int nr_to_call, int *nr_calls)
-{
-	int ret;
-	int idx;
-
-	idx = srcu_read_lock(&nh->srcu);
-	ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
-	srcu_read_unlock(&nh->srcu, idx);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(__srcu_notifier_call_chain);
-
-int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
-		unsigned long val, void *v)
-{
-	return __srcu_notifier_call_chain(nh, val, v, -1, NULL);
-}
-EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);
-
-/**
- *	srcu_init_notifier_head - Initialize an SRCU notifier head
- *	@nh: Pointer to head of the srcu notifier chain
- *
- *	Unlike other sorts of notifier heads, SRCU notifier heads require
- *	dynamic initialization.  Be sure to call this routine before
- *	calling any of the other SRCU notifier routines for this head.
- *
- *	If an SRCU notifier head is deallocated, it must first be cleaned
- *	up by calling srcu_cleanup_notifier_head().  Otherwise the head's
- *	per-cpu data (used by the SRCU mechanism) will leak.
- */
-
-void srcu_init_notifier_head(struct srcu_notifier_head *nh)
-{
-	mutex_init(&nh->mutex);
-	if (init_srcu_struct(&nh->srcu) < 0)
-		BUG();
-	nh->head = NULL;
-}
-
-EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
-
-/**
- *	register_reboot_notifier - Register function to be called at reboot time
- *	@nb: Info about notifier function to be called
- *
- *	Registers a function with the list of functions
- *	to be called at reboot time.
- *
- *	Currently always returns zero, as blocking_notifier_chain_register()
- *	always returns zero.
- */
- 
-int register_reboot_notifier(struct notifier_block * nb)
-{
-	return blocking_notifier_chain_register(&reboot_notifier_list, nb);
-}
-
-EXPORT_SYMBOL(register_reboot_notifier);
-
-/**
- *	unregister_reboot_notifier - Unregister previously registered reboot notifier
- *	@nb: Hook to be unregistered
- *
- *	Unregisters a previously registered reboot
- *	notifier function.
- *
- *	Returns zero on success, or %-ENOENT on failure.
- */
- 
-int unregister_reboot_notifier(struct notifier_block * nb)
-{
-	return blocking_notifier_chain_unregister(&reboot_notifier_list, nb);
-}
-
-EXPORT_SYMBOL(unregister_reboot_notifier);
 
 static int set_one_prio(struct task_struct *p, int niceval, int error)
 {
@@ -684,7 +152,7 @@
 	switch (which) {
 		case PRIO_PROCESS:
 			if (who)
-				p = find_task_by_pid(who);
+				p = find_task_by_vpid(who);
 			else
 				p = current;
 			if (p)
@@ -692,7 +160,7 @@
 			break;
 		case PRIO_PGRP:
 			if (who)
-				pgrp = find_pid(who);
+				pgrp = find_vpid(who);
 			else
 				pgrp = task_pgrp(current);
 			do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
@@ -741,7 +209,7 @@
 	switch (which) {
 		case PRIO_PROCESS:
 			if (who)
-				p = find_task_by_pid(who);
+				p = find_task_by_vpid(who);
 			else
 				p = current;
 			if (p) {
@@ -752,7 +220,7 @@
 			break;
 		case PRIO_PGRP:
 			if (who)
-				pgrp = find_pid(who);
+				pgrp = find_vpid(who);
 			else
 				pgrp = task_pgrp(current);
 			do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
@@ -1449,9 +917,10 @@
 	struct task_struct *p;
 	struct task_struct *group_leader = current->group_leader;
 	int err = -EINVAL;
+	struct pid_namespace *ns;
 
 	if (!pid)
-		pid = group_leader->pid;
+		pid = task_pid_vnr(group_leader);
 	if (!pgid)
 		pgid = pid;
 	if (pgid < 0)
@@ -1460,10 +929,12 @@
 	/* From this point forward we keep holding onto the tasklist lock
 	 * so that our parent does not change from under us. -DaveM
 	 */
+	ns = current->nsproxy->pid_ns;
+
 	write_lock_irq(&tasklist_lock);
 
 	err = -ESRCH;
-	p = find_task_by_pid(pid);
+	p = find_task_by_pid_ns(pid, ns);
 	if (!p)
 		goto out;
 
@@ -1489,9 +960,9 @@
 		goto out;
 
 	if (pgid != pid) {
-		struct task_struct *g =
-			find_task_by_pid_type(PIDTYPE_PGID, pgid);
+		struct task_struct *g;
 
+		g = find_task_by_pid_type_ns(PIDTYPE_PGID, pgid, ns);
 		if (!g || task_session(g) != task_session(group_leader))
 			goto out;
 	}
@@ -1500,10 +971,13 @@
 	if (err)
 		goto out;
 
-	if (process_group(p) != pgid) {
+	if (task_pgrp_nr_ns(p, ns) != pgid) {
+		struct pid *pid;
+
 		detach_pid(p, PIDTYPE_PGID);
-		p->signal->pgrp = pgid;
-		attach_pid(p, PIDTYPE_PGID, find_pid(pgid));
+		pid = find_vpid(pgid);
+		attach_pid(p, PIDTYPE_PGID, pid);
+		set_task_pgrp(p, pid_nr(pid));
 	}
 
 	err = 0;
@@ -1516,19 +990,21 @@
 asmlinkage long sys_getpgid(pid_t pid)
 {
 	if (!pid)
-		return process_group(current);
+		return task_pgrp_vnr(current);
 	else {
 		int retval;
 		struct task_struct *p;
+		struct pid_namespace *ns;
+
+		ns = current->nsproxy->pid_ns;
 
 		read_lock(&tasklist_lock);
-		p = find_task_by_pid(pid);
-
+		p = find_task_by_pid_ns(pid, ns);
 		retval = -ESRCH;
 		if (p) {
 			retval = security_task_getpgid(p);
 			if (!retval)
-				retval = process_group(p);
+				retval = task_pgrp_nr_ns(p, ns);
 		}
 		read_unlock(&tasklist_lock);
 		return retval;
@@ -1540,7 +1016,7 @@
 asmlinkage long sys_getpgrp(void)
 {
 	/* SMP - assuming writes are word atomic this is fine */
-	return process_group(current);
+	return task_pgrp_vnr(current);
 }
 
 #endif
@@ -1548,19 +1024,21 @@
 asmlinkage long sys_getsid(pid_t pid)
 {
 	if (!pid)
-		return process_session(current);
+		return task_session_vnr(current);
 	else {
 		int retval;
 		struct task_struct *p;
+		struct pid_namespace *ns;
+
+		ns = current->nsproxy->pid_ns;
 
 		read_lock(&tasklist_lock);
-		p = find_task_by_pid(pid);
-
+		p = find_task_by_pid_ns(pid, ns);
 		retval = -ESRCH;
 		if (p) {
 			retval = security_task_getsid(p);
 			if (!retval)
-				retval = process_session(p);
+				retval = task_session_nr_ns(p, ns);
 		}
 		read_unlock(&tasklist_lock);
 		return retval;
@@ -1587,7 +1065,8 @@
 	 * session id and so the check will always fail and make it so
 	 * init cannot successfully call setsid.
 	 */
-	if (session > 1 && find_task_by_pid_type(PIDTYPE_PGID, session))
+	if (session > 1 && find_task_by_pid_type_ns(PIDTYPE_PGID,
+				session, &init_pid_ns))
 		goto out;
 
 	group_leader->signal->leader = 1;
@@ -1597,7 +1076,7 @@
 	group_leader->signal->tty = NULL;
 	spin_unlock(&group_leader->sighand->siglock);
 
-	err = process_group(group_leader);
+	err = task_pgrp_vnr(group_leader);
 out:
 	write_unlock_irq(&tasklist_lock);
 	return err;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index dde3d53..3b4efbe 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -24,7 +24,7 @@
 #include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
-#include <linux/capability.h>
+#include <linux/security.h>
 #include <linux/ctype.h>
 #include <linux/utsname.h>
 #include <linux/smp_lock.h>
@@ -55,6 +55,8 @@
 #include <asm/stacktrace.h>
 #endif
 
+static int deprecated_sysctl_warning(struct __sysctl_args *args);
+
 #if defined(CONFIG_SYSCTL)
 
 /* External variables not in a header file. */
@@ -142,32 +144,29 @@
 
 #ifdef CONFIG_SYSCTL_SYSCALL
 static int parse_table(int __user *, int, void __user *, size_t __user *,
-		void __user *, size_t, ctl_table *);
+		void __user *, size_t, struct ctl_table *);
 #endif
 
 
 #ifdef CONFIG_PROC_SYSCTL
-static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
+static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
 		  void __user *buffer, size_t *lenp, loff_t *ppos);
-static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp,
+static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
 			       void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
 
-static ctl_table root_table[];
+static struct ctl_table root_table[];
 static struct ctl_table_header root_table_header =
 	{ root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
 
-static ctl_table kern_table[];
-static ctl_table vm_table[];
-static ctl_table fs_table[];
-static ctl_table debug_table[];
-static ctl_table dev_table[];
-extern ctl_table random_table[];
-#ifdef CONFIG_UNIX98_PTYS
-extern ctl_table pty_table[];
-#endif
+static struct ctl_table kern_table[];
+static struct ctl_table vm_table[];
+static struct ctl_table fs_table[];
+static struct ctl_table debug_table[];
+static struct ctl_table dev_table[];
+extern struct ctl_table random_table[];
 #ifdef CONFIG_INOTIFY_USER
-extern ctl_table inotify_table[];
+extern struct ctl_table inotify_table[];
 #endif
 
 #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
@@ -179,7 +178,7 @@
 
 /* The default sysctl tables: */
 
-static ctl_table root_table[] = {
+static struct ctl_table root_table[] = {
 	{
 		.ctl_name	= CTL_KERN,
 		.procname	= "kernel",
@@ -232,7 +231,7 @@
 static unsigned long max_wakeup_granularity_ns = 1000000000;	/* 1 second */
 #endif
 
-static ctl_table kern_table[] = {
+static struct ctl_table kern_table[] = {
 #ifdef CONFIG_SCHED_DEBUG
 	{
 		.ctl_name	= CTL_UNNUMBERED,
@@ -365,7 +364,6 @@
 	},
 #ifdef CONFIG_PROC_SYSCTL
 	{
-		.ctl_name	= KERN_TAINTED,
 		.procname	= "tainted",
 		.data		= &tainted,
 		.maxlen		= sizeof(int),
@@ -373,14 +371,15 @@
 		.proc_handler	= &proc_dointvec_taint,
 	},
 #endif
+#ifdef CONFIG_SECURITY_CAPABILITIES
 	{
-		.ctl_name	= KERN_CAP_BSET,
 		.procname	= "cap-bound",
 		.data		= &cap_bset,
 		.maxlen		= sizeof(kernel_cap_t),
 		.mode		= 0600,
 		.proc_handler	= &proc_dointvec_bset,
 	},
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
 #ifdef CONFIG_BLK_DEV_INITRD
 	{
 		.ctl_name	= KERN_REALROOTDEV,
@@ -514,7 +513,6 @@
 #endif
 #ifdef CONFIG_PROC_SYSCTL
 	{
-		.ctl_name	= KERN_CADPID,
 		.procname	= "cad_pid",
 		.data		= NULL,
 		.maxlen		= sizeof (int),
@@ -536,14 +534,6 @@
 		.mode		= 0555,
 		.child		= random_table,
 	},
-#ifdef CONFIG_UNIX98_PTYS
-	{
-		.ctl_name	= KERN_PTY,
-		.procname	= "pty",
-		.mode		= 0555,
-		.child		= pty_table,
-	},
-#endif
 	{
 		.ctl_name	= KERN_OVERFLOWUID,
 		.procname	= "overflowuid",
@@ -650,7 +640,6 @@
 		.proc_handler   = &proc_dointvec,
 	},
 	{
-		.ctl_name       = KERN_NMI_WATCHDOG,
 		.procname       = "nmi_watchdog",
 		.data           = &nmi_watchdog_enabled,
 		.maxlen         = sizeof (int),
@@ -706,7 +695,6 @@
 #endif
 #if	defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86)
 	{
-		.ctl_name	= KERN_ACPI_VIDEO_FLAGS,
 		.procname	= "acpi_video_flags",
 		.data		= &acpi_realmode_flags,
 		.maxlen		= sizeof (unsigned long),
@@ -783,7 +771,7 @@
 	{ .ctl_name = 0 }
 };
 
-static ctl_table vm_table[] = {
+static struct ctl_table vm_table[] = {
 	{
 		.ctl_name	= VM_OVERCOMMIT_MEMORY,
 		.procname	= "overcommit_memory",
@@ -847,7 +835,6 @@
 		.extra2		= &one_hundred,
 	},
 	{
-		.ctl_name	= VM_DIRTY_WB_CS,
 		.procname	= "dirty_writeback_centisecs",
 		.data		= &dirty_writeback_interval,
 		.maxlen		= sizeof(dirty_writeback_interval),
@@ -855,7 +842,6 @@
 		.proc_handler	= &dirty_writeback_centisecs_handler,
 	},
 	{
-		.ctl_name	= VM_DIRTY_EXPIRE_CS,
 		.procname	= "dirty_expire_centisecs",
 		.data		= &dirty_expire_interval,
 		.maxlen		= sizeof(dirty_expire_interval),
@@ -883,7 +869,6 @@
 	},
 #ifdef CONFIG_HUGETLB_PAGE
 	 {
-		.ctl_name	= VM_HUGETLB_PAGES,
 		.procname	= "nr_hugepages",
 		.data		= &max_huge_pages,
 		.maxlen		= sizeof(unsigned long),
@@ -1093,12 +1078,12 @@
 };
 
 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
-static ctl_table binfmt_misc_table[] = {
+static struct ctl_table binfmt_misc_table[] = {
 	{ .ctl_name = 0 }
 };
 #endif
 
-static ctl_table fs_table[] = {
+static struct ctl_table fs_table[] = {
 	{
 		.ctl_name	= FS_NRINODE,
 		.procname	= "inode-nr",
@@ -1116,7 +1101,6 @@
 		.proc_handler	= &proc_dointvec,
 	},
 	{
-		.ctl_name	= FS_NRFILE,
 		.procname	= "file-nr",
 		.data		= &files_stat,
 		.maxlen		= 3*sizeof(int),
@@ -1192,7 +1176,6 @@
 		.extra2		= &two,
 	},
 	{
-		.ctl_name	= FS_AIO_NR,
 		.procname	= "aio-nr",
 		.data		= &aio_nr,
 		.maxlen		= sizeof(aio_nr),
@@ -1200,7 +1183,6 @@
 		.proc_handler	= &proc_doulongvec_minmax,
 	},
 	{
-		.ctl_name	= FS_AIO_MAX_NR,
 		.procname	= "aio-max-nr",
 		.data		= &aio_max_nr,
 		.maxlen		= sizeof(aio_max_nr),
@@ -1239,7 +1221,7 @@
 	{ .ctl_name = 0 }
 };
 
-static ctl_table debug_table[] = {
+static struct ctl_table debug_table[] = {
 #if defined(CONFIG_X86) || defined(CONFIG_PPC)
 	{
 		.ctl_name	= CTL_UNNUMBERED,
@@ -1253,7 +1235,7 @@
 	{ .ctl_name = 0 }
 };
 
-static ctl_table dev_table[] = {
+static struct ctl_table dev_table[] = {
 	{ .ctl_name = 0 }
 };
 
@@ -1369,10 +1351,15 @@
 	if (copy_from_user(&tmp, args, sizeof(tmp)))
 		return -EFAULT;
 
+	error = deprecated_sysctl_warning(&tmp);
+	if (error)
+		goto out;
+
 	lock_kernel();
 	error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,
 			  tmp.newval, tmp.newlen);
 	unlock_kernel();
+out:
 	return error;
 }
 #endif /* CONFIG_SYSCTL_SYSCALL */
@@ -1393,7 +1380,7 @@
 	return -EACCES;
 }
 
-int sysctl_perm(ctl_table *table, int op)
+int sysctl_perm(struct ctl_table *table, int op)
 {
 	int error;
 	error = security_sysctl(table, op);
@@ -1406,7 +1393,7 @@
 static int parse_table(int __user *name, int nlen,
 		       void __user *oldval, size_t __user *oldlenp,
 		       void __user *newval, size_t newlen,
-		       ctl_table *table)
+		       struct ctl_table *table)
 {
 	int n;
 repeat:
@@ -1437,13 +1424,12 @@
 }
 
 /* Perform the actual read/write of a sysctl table entry. */
-int do_sysctl_strategy (ctl_table *table, 
+int do_sysctl_strategy (struct ctl_table *table,
 			int __user *name, int nlen,
 			void __user *oldval, size_t __user *oldlenp,
 			void __user *newval, size_t newlen)
 {
 	int op = 0, rc;
-	size_t len;
 
 	if (oldval)
 		op |= 004;
@@ -1464,25 +1450,10 @@
 	/* If there is no strategy routine, or if the strategy returns
 	 * zero, proceed with automatic r/w */
 	if (table->data && table->maxlen) {
-		if (oldval && oldlenp) {
-			if (get_user(len, oldlenp))
-				return -EFAULT;
-			if (len) {
-				if (len > table->maxlen)
-					len = table->maxlen;
-				if(copy_to_user(oldval, table->data, len))
-					return -EFAULT;
-				if(put_user(len, oldlenp))
-					return -EFAULT;
-			}
-		}
-		if (newval && newlen) {
-			len = newlen;
-			if (len > table->maxlen)
-				len = table->maxlen;
-			if(copy_from_user(table->data, newval, len))
-				return -EFAULT;
-		}
+		rc = sysctl_data(table, name, nlen, oldval, oldlenp,
+				 newval, newlen);
+		if (rc < 0)
+			return rc;
 	}
 	return 0;
 }
@@ -1499,7 +1470,9 @@
 
 static __init int sysctl_init(void)
 {
+	int err;
 	sysctl_set_parent(NULL, root_table);
+	err = sysctl_check_table(root_table);
 	return 0;
 }
 
@@ -1512,7 +1485,7 @@
  * Register a sysctl table hierarchy. @table should be a filled in ctl_table
  * array. An entry with a ctl_name of 0 terminates the table. 
  *
- * The members of the &ctl_table structure are used as follows:
+ * The members of the &struct ctl_table structure are used as follows:
  *
  * ctl_name - This is the numeric sysctl value used by sysctl(2). The number
  *            must be unique within that level of sysctl
@@ -1573,7 +1546,7 @@
  * This routine returns %NULL on a failure to register, and a pointer
  * to the table header on success.
  */
-struct ctl_table_header *register_sysctl_table(ctl_table * table)
+struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
 {
 	struct ctl_table_header *tmp;
 	tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL);
@@ -1584,6 +1557,10 @@
 	tmp->used = 0;
 	tmp->unregistering = NULL;
 	sysctl_set_parent(NULL, table);
+	if (sysctl_check_table(tmp->ctl_table)) {
+		kfree(tmp);
+		return NULL;
+	}
 	spin_lock(&sysctl_lock);
 	list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
 	spin_unlock(&sysctl_lock);
@@ -1607,7 +1584,7 @@
 }
 
 #else /* !CONFIG_SYSCTL */
-struct ctl_table_header *register_sysctl_table(ctl_table * table)
+struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
 {
 	return NULL;
 }
@@ -1700,7 +1677,7 @@
  *
  * Returns 0 on success.
  */
-int proc_dostring(ctl_table *table, int write, struct file *filp,
+int proc_dostring(struct ctl_table *table, int write, struct file *filp,
 		  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	return _proc_do_string(table->data, table->maxlen, write, filp,
@@ -1727,7 +1704,7 @@
 	return 0;
 }
 
-static int __do_proc_dointvec(void *tbl_data, ctl_table *table,
+static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
 		  int write, struct file *filp, void __user *buffer,
 		  size_t *lenp, loff_t *ppos,
 		  int (*conv)(int *negp, unsigned long *lvalp, int *valp,
@@ -1837,7 +1814,7 @@
 #undef TMPBUFLEN
 }
 
-static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
+static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp,
 		  void __user *buffer, size_t *lenp, loff_t *ppos,
 		  int (*conv)(int *negp, unsigned long *lvalp, int *valp,
 			      int write, void *data),
@@ -1861,7 +1838,7 @@
  *
  * Returns 0 on success.
  */
-int proc_dointvec(ctl_table *table, int write, struct file *filp,
+int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
 		     void __user *buffer, size_t *lenp, loff_t *ppos)
 {
     return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
@@ -1897,11 +1874,12 @@
 	return 0;
 }
 
+#ifdef CONFIG_SECURITY_CAPABILITIES
 /*
  *	init may raise the set.
  */
- 
-int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
+
+int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
 			void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	int op;
@@ -1910,15 +1888,16 @@
 		return -EPERM;
 	}
 
-	op = is_init(current) ? OP_SET : OP_AND;
+	op = is_global_init(current) ? OP_SET : OP_AND;
 	return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
 				do_proc_dointvec_bset_conv,&op);
 }
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
 
 /*
  *	Taint values can only be increased
  */
-static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp,
+static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
 			       void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	int op;
@@ -1977,7 +1956,7 @@
  *
  * Returns 0 on success.
  */
-int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
 		  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	struct do_proc_dointvec_minmax_conv_param param = {
@@ -1988,7 +1967,7 @@
 				do_proc_dointvec_minmax_conv, &param);
 }
 
-static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write,
+static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
 				     struct file *filp,
 				     void __user *buffer,
 				     size_t *lenp, loff_t *ppos,
@@ -2093,7 +2072,7 @@
 #undef TMPBUFLEN
 }
 
-static int do_proc_doulongvec_minmax(ctl_table *table, int write,
+static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,
 				     struct file *filp,
 				     void __user *buffer,
 				     size_t *lenp, loff_t *ppos,
@@ -2121,7 +2100,7 @@
  *
  * Returns 0 on success.
  */
-int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp,
 			   void __user *buffer, size_t *lenp, loff_t *ppos)
 {
     return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l);
@@ -2145,7 +2124,7 @@
  *
  * Returns 0 on success.
  */
-int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
+int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
 				      struct file *filp,
 				      void __user *buffer,
 				      size_t *lenp, loff_t *ppos)
@@ -2238,7 +2217,7 @@
  *
  * Returns 0 on success.
  */
-int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
 			  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
     return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
@@ -2261,7 +2240,7 @@
  *
  * Returns 0 on success.
  */
-int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
 				 void __user *buffer, size_t *lenp, loff_t *ppos)
 {
     return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
@@ -2285,21 +2264,21 @@
  *
  * Returns 0 on success.
  */
-int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
 			     void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
 				do_proc_dointvec_ms_jiffies_conv, NULL);
 }
 
-static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
+static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
 			   void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	struct pid *new_pid;
 	pid_t tmp;
 	int r;
 
-	tmp = pid_nr(cad_pid);
+	tmp = pid_nr_ns(cad_pid, current->nsproxy->pid_ns);
 
 	r = __do_proc_dointvec(&tmp, table, write, filp, buffer,
 			       lenp, ppos, NULL, NULL);
@@ -2316,55 +2295,55 @@
 
 #else /* CONFIG_PROC_FS */
 
-int proc_dostring(ctl_table *table, int write, struct file *filp,
+int proc_dostring(struct ctl_table *table, int write, struct file *filp,
 		  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	return -ENOSYS;
 }
 
-int proc_dointvec(ctl_table *table, int write, struct file *filp,
+int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
 		  void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	return -ENOSYS;
 }
 
-int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
 			void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	return -ENOSYS;
 }
 
-int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
 		    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	return -ENOSYS;
 }
 
-int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
 		    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	return -ENOSYS;
 }
 
-int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
 		    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	return -ENOSYS;
 }
 
-int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
 			     void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	return -ENOSYS;
 }
 
-int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp,
 		    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	return -ENOSYS;
 }
 
-int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
+int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
 				      struct file *filp,
 				      void __user *buffer,
 				      size_t *lenp, loff_t *ppos)
@@ -2381,8 +2360,42 @@
  * General sysctl support routines 
  */
 
+/* The generic sysctl data routine (used if no strategy routine supplied) */
+int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
+		void __user *oldval, size_t __user *oldlenp,
+		void __user *newval, size_t newlen)
+{
+	size_t len;
+
+	/* Get out of I don't have a variable */
+	if (!table->data || !table->maxlen)
+		return -ENOTDIR;
+
+	if (oldval && oldlenp) {
+		if (get_user(len, oldlenp))
+			return -EFAULT;
+		if (len) {
+			if (len > table->maxlen)
+				len = table->maxlen;
+			if (copy_to_user(oldval, table->data, len))
+				return -EFAULT;
+			if (put_user(len, oldlenp))
+				return -EFAULT;
+		}
+	}
+
+	if (newval && newlen) {
+		if (newlen > table->maxlen)
+			newlen = table->maxlen;
+
+		if (copy_from_user(table->data, newval, newlen))
+			return -EFAULT;
+	}
+	return 1;
+}
+
 /* The generic string strategy routine: */
-int sysctl_string(ctl_table *table, int __user *name, int nlen,
+int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
 		  void __user *oldval, size_t __user *oldlenp,
 		  void __user *newval, size_t newlen)
 {
@@ -2428,7 +2441,7 @@
  * are between the minimum and maximum values given in the arrays
  * table->extra1 and table->extra2, respectively.
  */
-int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
+int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
 		void __user *oldval, size_t __user *oldlenp,
 		void __user *newval, size_t newlen)
 {
@@ -2464,7 +2477,7 @@
 }
 
 /* Strategy function to convert jiffies to seconds */ 
-int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
 		void __user *oldval, size_t __user *oldlenp,
 		void __user *newval, size_t newlen)
 {
@@ -2498,7 +2511,7 @@
 }
 
 /* Strategy function to convert jiffies to seconds */ 
-int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
 		void __user *oldval, size_t __user *oldlenp,
 		void __user *newval, size_t newlen)
 {
@@ -2538,59 +2551,50 @@
 
 asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
 {
-	static int msg_count;
 	struct __sysctl_args tmp;
-	int name[CTL_MAXNAME];
-	int i;
+	int error;
 
-	/* Read in the sysctl name for better debug message logging */
 	if (copy_from_user(&tmp, args, sizeof(tmp)))
 		return -EFAULT;
-	if (tmp.nlen <= 0 || tmp.nlen >= CTL_MAXNAME)
-		return -ENOTDIR;
-	for (i = 0; i < tmp.nlen; i++)
-		if (get_user(name[i], tmp.name + i))
-			return -EFAULT;
 
-	/* Ignore accesses to kernel.version */
-	if ((tmp.nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
-		goto out;
+	error = deprecated_sysctl_warning(&tmp);
 
-	if (msg_count < 5) {
-		msg_count++;
-		printk(KERN_INFO
-			"warning: process `%s' used the removed sysctl "
-			"system call with ", current->comm);
-		for (i = 0; i < tmp.nlen; i++)
-			printk("%d.", name[i]);
-		printk("\n");
-	}
-out:
-	return -ENOSYS;
+	/* If no error reading the parameters then just -ENOSYS ... */
+	if (!error)
+		error = -ENOSYS;
+
+	return error;
 }
 
-int sysctl_string(ctl_table *table, int __user *name, int nlen,
+int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
 		  void __user *oldval, size_t __user *oldlenp,
 		  void __user *newval, size_t newlen)
 {
 	return -ENOSYS;
 }
 
-int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
+int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
+		  void __user *oldval, size_t __user *oldlenp,
+		  void __user *newval, size_t newlen)
+{
+	return -ENOSYS;
+}
+
+int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
 		void __user *oldval, size_t __user *oldlenp,
 		void __user *newval, size_t newlen)
 {
 	return -ENOSYS;
 }
 
-int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
 		void __user *oldval, size_t __user *oldlenp,
 		void __user *newval, size_t newlen)
 {
 	return -ENOSYS;
 }
 
-int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
 		void __user *oldval, size_t __user *oldlenp,
 		void __user *newval, size_t newlen)
 {
@@ -2599,6 +2603,33 @@
 
 #endif /* CONFIG_SYSCTL_SYSCALL */
 
+static int deprecated_sysctl_warning(struct __sysctl_args *args)
+{
+	static int msg_count;
+	int name[CTL_MAXNAME];
+	int i;
+
+	/* Read in the sysctl name for better debug message logging */
+	for (i = 0; i < args->nlen; i++)
+		if (get_user(name[i], args->name + i))
+			return -EFAULT;
+
+	/* Ignore accesses to kernel.version */
+	if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
+		return 0;
+
+	if (msg_count < 5) {
+		msg_count++;
+		printk(KERN_INFO
+			"warning: process `%s' used the deprecated sysctl "
+			"system call with ", current->comm);
+		for (i = 0; i < args->nlen; i++)
+			printk("%d.", name[i]);
+		printk("\n");
+	}
+	return 0;
+}
+
 /*
  * No sense putting this after each symbol definition, twice,
  * exception granted :-)
@@ -2616,4 +2647,5 @@
 EXPORT_SYMBOL(sysctl_jiffies);
 EXPORT_SYMBOL(sysctl_ms_jiffies);
 EXPORT_SYMBOL(sysctl_string);
+EXPORT_SYMBOL(sysctl_data);
 EXPORT_SYMBOL(unregister_sysctl_table);
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
new file mode 100644
index 0000000..ed6fe51
--- /dev/null
+++ b/kernel/sysctl_check.c
@@ -0,0 +1,1588 @@
+#include <linux/stat.h>
+#include <linux/sysctl.h>
+#include "../arch/s390/appldata/appldata.h"
+#include "../fs/xfs/linux-2.6/xfs_sysctl.h"
+#include <linux/sunrpc/debug.h>
+#include <linux/string.h>
+#include <net/ip_vs.h>
+
+struct trans_ctl_table {
+	int			ctl_name;
+	const char		*procname;
+	struct trans_ctl_table	*child;
+};
+
+static struct trans_ctl_table trans_random_table[] = {
+	{ RANDOM_POOLSIZE,	"poolsize" },
+	{ RANDOM_ENTROPY_COUNT,	"entropy_avail" },
+	{ RANDOM_READ_THRESH,	"read_wakeup_threshold" },
+	{ RANDOM_WRITE_THRESH,	"write_wakeup_threshold" },
+	{ RANDOM_BOOT_ID,	"boot_id" },
+	{ RANDOM_UUID,		"uuid" },
+	{}
+};
+
+static struct trans_ctl_table trans_pty_table[] = {
+	{ PTY_MAX,		"max" },
+	{ PTY_NR,		"nr" },
+	{}
+};
+
+static struct trans_ctl_table trans_kern_table[] = {
+	{ KERN_OSTYPE,			"ostype" },
+	{ KERN_OSRELEASE,		"osrelease" },
+	/* KERN_OSREV not used */
+	{ KERN_VERSION,			"version" },
+	/* KERN_SECUREMASK not used */
+	/* KERN_PROF not used */
+	{ KERN_NODENAME,		"hostname" },
+	{ KERN_DOMAINNAME,		"domainname" },
+
+#ifdef CONFIG_SECURITY_CAPABILITIES
+	{ KERN_CAP_BSET,		"cap-bound" },
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
+
+	{ KERN_PANIC,			"panic" },
+	{ KERN_REALROOTDEV,		"real-root-dev" },
+
+	{ KERN_SPARC_REBOOT,		"reboot-cmd" },
+	{ KERN_CTLALTDEL,		"ctrl-alt-del" },
+	{ KERN_PRINTK,			"printk" },
+
+	/* KERN_NAMETRANS not used */
+	/* KERN_PPC_HTABRECLAIM not used */
+	/* KERN_PPC_ZEROPAGED not used */
+	{ KERN_PPC_POWERSAVE_NAP,	"powersave-nap" },
+
+	{ KERN_MODPROBE,		"modprobe" },
+	{ KERN_SG_BIG_BUFF,		"sg-big-buff" },
+	{ KERN_ACCT,			"acct" },
+	{ KERN_PPC_L2CR,		"l2cr" },
+
+	/* KERN_RTSIGNR not used */
+	/* KERN_RTSIGMAX not used */
+
+	{ KERN_SHMMAX,			"shmmax" },
+	{ KERN_MSGMAX,			"msgmax" },
+	{ KERN_MSGMNB,			"msgmnb" },
+	/* KERN_MSGPOOL not used*/
+	{ KERN_SYSRQ,			"sysrq" },
+	{ KERN_MAX_THREADS,		"threads-max" },
+	{ KERN_RANDOM,			"random",	trans_random_table },
+	{ KERN_SHMALL,			"shmall" },
+	{ KERN_MSGMNI,			"msgmni" },
+	{ KERN_SEM,			"sem" },
+	{ KERN_SPARC_STOP_A,		"stop-a" },
+	{ KERN_SHMMNI,			"shmmni" },
+
+	{ KERN_OVERFLOWUID,		"overflowuid" },
+	{ KERN_OVERFLOWGID,		"overflowgid" },
+
+	{ KERN_HOTPLUG,			"hotplug", },
+	{ KERN_IEEE_EMULATION_WARNINGS,	"ieee_emulation_warnings" },
+
+	{ KERN_S390_USER_DEBUG_LOGGING,	"userprocess_debug" },
+	{ KERN_CORE_USES_PID,		"core_uses_pid" },
+	{ KERN_TAINTED,			"tainted" },
+	{ KERN_CADPID,			"cad_pid" },
+	{ KERN_PIDMAX,			"pid_max" },
+	{ KERN_CORE_PATTERN,		"core_pattern" },
+	{ KERN_PANIC_ON_OOPS,		"panic_on_oops" },
+	{ KERN_HPPA_PWRSW,		"soft-power" },
+	{ KERN_HPPA_UNALIGNED,		"unaligned-trap" },
+
+	{ KERN_PRINTK_RATELIMIT,	"printk_ratelimit" },
+	{ KERN_PRINTK_RATELIMIT_BURST,	"printk_ratelimit_burst" },
+
+	{ KERN_PTY,			"pty",		trans_pty_table },
+	{ KERN_NGROUPS_MAX,		"ngroups_max" },
+	{ KERN_SPARC_SCONS_PWROFF,	"scons_poweroff" },
+	{ KERN_HZ_TIMER,		"hz_timer" },
+	{ KERN_UNKNOWN_NMI_PANIC,	"unknown_nmi_panic" },
+	{ KERN_BOOTLOADER_TYPE,		"bootloader_type" },
+	{ KERN_RANDOMIZE,		"randomize_va_space" },
+
+	{ KERN_SPIN_RETRY,		"spin_retry" },
+	{ KERN_ACPI_VIDEO_FLAGS,	"acpi_video_flags" },
+	{ KERN_IA64_UNALIGNED,		"ignore-unaligned-usertrap" },
+	{ KERN_COMPAT_LOG,		"compat-log" },
+	{ KERN_MAX_LOCK_DEPTH,		"max_lock_depth" },
+	{ KERN_NMI_WATCHDOG,		"nmi_watchdog" },
+	{ KERN_PANIC_ON_NMI,		"panic_on_unrecovered_nmi" },
+	{}
+};
+
+static struct trans_ctl_table trans_vm_table[] = {
+	{ VM_OVERCOMMIT_MEMORY,		"overcommit_memory" },
+	{ VM_PAGE_CLUSTER,		"page-cluster" },
+	{ VM_DIRTY_BACKGROUND,		"dirty_background_ratio" },
+	{ VM_DIRTY_RATIO,		"dirty_ratio" },
+	{ VM_DIRTY_WB_CS,		"dirty_writeback_centisecs" },
+	{ VM_DIRTY_EXPIRE_CS,		"dirty_expire_centisecs" },
+	{ VM_NR_PDFLUSH_THREADS,	"nr_pdflush_threads" },
+	{ VM_OVERCOMMIT_RATIO,		"overcommit_ratio" },
+	/* VM_PAGEBUF unused */
+	{ VM_HUGETLB_PAGES,		"nr_hugepages" },
+	{ VM_SWAPPINESS,		"swappiness" },
+	{ VM_LOWMEM_RESERVE_RATIO,	"lowmem_reserve_ratio" },
+	{ VM_MIN_FREE_KBYTES,		"min_free_kbytes" },
+	{ VM_MAX_MAP_COUNT,		"max_map_count" },
+	{ VM_LAPTOP_MODE,		"laptop_mode" },
+	{ VM_BLOCK_DUMP,		"block_dump" },
+	{ VM_HUGETLB_GROUP,		"hugetlb_shm_group" },
+	{ VM_VFS_CACHE_PRESSURE,	"vfs_cache_pressure" },
+	{ VM_LEGACY_VA_LAYOUT,		"legacy_va_layout" },
+	/* VM_SWAP_TOKEN_TIMEOUT unused */
+	{ VM_DROP_PAGECACHE,		"drop_caches" },
+	{ VM_PERCPU_PAGELIST_FRACTION,	"percpu_pagelist_fraction" },
+	{ VM_ZONE_RECLAIM_MODE,		"zone_reclaim_mode" },
+	{ VM_MIN_UNMAPPED,		"min_unmapped_ratio" },
+	{ VM_PANIC_ON_OOM,		"panic_on_oom" },
+	{ VM_VDSO_ENABLED,		"vdso_enabled" },
+	{ VM_MIN_SLAB,			"min_slab_ratio" },
+	{ VM_CMM_PAGES,			"cmm_pages" },
+	{ VM_CMM_TIMED_PAGES,		"cmm_timed_pages" },
+	{ VM_CMM_TIMEOUT,		"cmm_timeout" },
+
+	{}
+};
+
+static struct trans_ctl_table trans_net_core_table[] = {
+	{ NET_CORE_WMEM_MAX,		"wmem_max" },
+	{ NET_CORE_RMEM_MAX,		"rmem_max" },
+	{ NET_CORE_WMEM_DEFAULT,	"wmem_default" },
+	{ NET_CORE_RMEM_DEFAULT,	"rmem_default" },
+	/* NET_CORE_DESTROY_DELAY unused */
+	{ NET_CORE_MAX_BACKLOG,		"netdev_max_backlog" },
+	/* NET_CORE_FASTROUTE unused */
+	{ NET_CORE_MSG_COST,		"message_cost" },
+	{ NET_CORE_MSG_BURST,		"message_burst" },
+	{ NET_CORE_OPTMEM_MAX,		"optmem_max" },
+	/* NET_CORE_HOT_LIST_LENGTH unused */
+	/* NET_CORE_DIVERT_VERSION unused */
+	/* NET_CORE_NO_CONG_THRESH unused */
+	/* NET_CORE_NO_CONG unused */
+	/* NET_CORE_LO_CONG unused */
+	/* NET_CORE_MOD_CONG unused */
+	{ NET_CORE_DEV_WEIGHT,		"dev_weight" },
+	{ NET_CORE_SOMAXCONN,		"somaxconn" },
+	{ NET_CORE_BUDGET,		"netdev_budget" },
+	{ NET_CORE_AEVENT_ETIME,	"xfrm_aevent_etime" },
+	{ NET_CORE_AEVENT_RSEQTH,	"xfrm_aevent_rseqth" },
+	{ NET_CORE_WARNINGS,		"warnings" },
+	{},
+};
+
+static struct trans_ctl_table trans_net_unix_table[] = {
+	/* NET_UNIX_DESTROY_DELAY unused */
+	/* NET_UNIX_DELETE_DELAY unused */
+	{ NET_UNIX_MAX_DGRAM_QLEN,	"max_dgram_qlen" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_ipv4_route_table[] = {
+	{ NET_IPV4_ROUTE_FLUSH,			"flush" },
+	{ NET_IPV4_ROUTE_MIN_DELAY,		"min_delay" },
+	{ NET_IPV4_ROUTE_MAX_DELAY,		"max_delay" },
+	{ NET_IPV4_ROUTE_GC_THRESH,		"gc_thresh" },
+	{ NET_IPV4_ROUTE_MAX_SIZE,		"max_size" },
+	{ NET_IPV4_ROUTE_GC_MIN_INTERVAL,	"gc_min_interval" },
+	{ NET_IPV4_ROUTE_GC_TIMEOUT,		"gc_timeout" },
+	{ NET_IPV4_ROUTE_GC_INTERVAL,		"gc_interval" },
+	{ NET_IPV4_ROUTE_REDIRECT_LOAD,		"redirect_load" },
+	{ NET_IPV4_ROUTE_REDIRECT_NUMBER,	"redirect_number" },
+	{ NET_IPV4_ROUTE_REDIRECT_SILENCE,	"redirect_silence" },
+	{ NET_IPV4_ROUTE_ERROR_COST,		"error_cost" },
+	{ NET_IPV4_ROUTE_ERROR_BURST,		"error_burst" },
+	{ NET_IPV4_ROUTE_GC_ELASTICITY,		"gc_elasticity" },
+	{ NET_IPV4_ROUTE_MTU_EXPIRES,		"mtu_expires" },
+	{ NET_IPV4_ROUTE_MIN_PMTU,		"min_pmtu" },
+	{ NET_IPV4_ROUTE_MIN_ADVMSS,		"min_adv_mss" },
+	{ NET_IPV4_ROUTE_SECRET_INTERVAL,	"secret_interval" },
+	{ NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS,	"gc_min_interval_ms" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_ipv4_conf_vars_table[] = {
+	{ NET_IPV4_CONF_FORWARDING,		"forwarding" },
+	{ NET_IPV4_CONF_MC_FORWARDING,		"mc_forwarding" },
+
+	{ NET_IPV4_CONF_PROXY_ARP,		"proxy_arp" },
+	{ NET_IPV4_CONF_ACCEPT_REDIRECTS,	"accept_redirects" },
+	{ NET_IPV4_CONF_SECURE_REDIRECTS,	"secure_redirects" },
+	{ NET_IPV4_CONF_SEND_REDIRECTS,		"send_redirects" },
+	{ NET_IPV4_CONF_SHARED_MEDIA,		"shared_media" },
+	{ NET_IPV4_CONF_RP_FILTER,		"rp_filter" },
+	{ NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE,	"accept_source_route" },
+	{ NET_IPV4_CONF_BOOTP_RELAY,		"bootp_relay" },
+	{ NET_IPV4_CONF_LOG_MARTIANS,		"log_martians" },
+	{ NET_IPV4_CONF_TAG,			"tag" },
+	{ NET_IPV4_CONF_ARPFILTER,		"arp_filter" },
+	{ NET_IPV4_CONF_MEDIUM_ID,		"medium_id" },
+	{ NET_IPV4_CONF_NOXFRM,			"disable_xfrm" },
+	{ NET_IPV4_CONF_NOPOLICY,		"disable_policy" },
+	{ NET_IPV4_CONF_FORCE_IGMP_VERSION,	"force_igmp_version" },
+
+	{ NET_IPV4_CONF_ARP_ANNOUNCE,		"arp_announce" },
+	{ NET_IPV4_CONF_ARP_IGNORE,		"arp_ignore" },
+	{ NET_IPV4_CONF_PROMOTE_SECONDARIES,	"promote_secondaries" },
+	{ NET_IPV4_CONF_ARP_ACCEPT,		"arp_accept" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_ipv4_conf_table[] = {
+	{ NET_PROTO_CONF_ALL,		"all",		trans_net_ipv4_conf_vars_table },
+	{ NET_PROTO_CONF_DEFAULT,	"default",	trans_net_ipv4_conf_vars_table },
+	{ 0, NULL, trans_net_ipv4_conf_vars_table },
+	{}
+};
+
+
+static struct trans_ctl_table trans_net_ipv4_vs_table[] = {
+	{ NET_IPV4_VS_AMEMTHRESH,	"amemthresh" },
+	{ NET_IPV4_VS_DEBUG_LEVEL,	"debug_level" },
+	{ NET_IPV4_VS_AMDROPRATE,	"am_droprate" },
+	{ NET_IPV4_VS_DROP_ENTRY,	"drop_entry" },
+	{ NET_IPV4_VS_DROP_PACKET,	"drop_packet" },
+	{ NET_IPV4_VS_SECURE_TCP,	"secure_tcp" },
+	{ NET_IPV4_VS_TO_ES,		"timeout_established" },
+	{ NET_IPV4_VS_TO_SS,		"timeout_synsent" },
+	{ NET_IPV4_VS_TO_SR,		"timeout_synrecv" },
+	{ NET_IPV4_VS_TO_FW,		"timeout_finwait" },
+	{ NET_IPV4_VS_TO_TW,		"timeout_timewait" },
+	{ NET_IPV4_VS_TO_CL,		"timeout_close" },
+	{ NET_IPV4_VS_TO_CW,		"timeout_closewait" },
+	{ NET_IPV4_VS_TO_LA,		"timeout_lastack" },
+	{ NET_IPV4_VS_TO_LI,		"timeout_listen" },
+	{ NET_IPV4_VS_TO_SA,		"timeout_synack" },
+	{ NET_IPV4_VS_TO_UDP,		"timeout_udp" },
+	{ NET_IPV4_VS_TO_ICMP,		"timeout_icmp" },
+	{ NET_IPV4_VS_CACHE_BYPASS,	"cache_bypass" },
+	{ NET_IPV4_VS_EXPIRE_NODEST_CONN,	"expire_nodest_conn" },
+	{ NET_IPV4_VS_EXPIRE_QUIESCENT_TEMPLATE,	"expire_quiescent_template" },
+	{ NET_IPV4_VS_SYNC_THRESHOLD,		"sync_threshold" },
+	{ NET_IPV4_VS_NAT_ICMP_SEND,	"nat_icmp_send" },
+	{ NET_IPV4_VS_LBLC_EXPIRE,		"lblc_expiration" },
+	{ NET_IPV4_VS_LBLCR_EXPIRE,		"lblcr_expiration" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_neigh_vars_table[] = {
+	{ NET_NEIGH_MCAST_SOLICIT,	"mcast_solicit" },
+	{ NET_NEIGH_UCAST_SOLICIT,	"ucast_solicit" },
+	{ NET_NEIGH_APP_SOLICIT,	"app_solicit" },
+	{ NET_NEIGH_RETRANS_TIME,	"retrans_time" },
+	{ NET_NEIGH_REACHABLE_TIME,	"base_reachable_time" },
+	{ NET_NEIGH_DELAY_PROBE_TIME,	"delay_first_probe_time" },
+	{ NET_NEIGH_GC_STALE_TIME,	"gc_stale_time" },
+	{ NET_NEIGH_UNRES_QLEN,		"unres_qlen" },
+	{ NET_NEIGH_PROXY_QLEN,		"proxy_qlen" },
+	{ NET_NEIGH_ANYCAST_DELAY,	"anycast_delay" },
+	{ NET_NEIGH_PROXY_DELAY,	"proxy_delay" },
+	{ NET_NEIGH_LOCKTIME,		"locktime" },
+	{ NET_NEIGH_GC_INTERVAL,	"gc_interval" },
+	{ NET_NEIGH_GC_THRESH1,		"gc_thresh1" },
+	{ NET_NEIGH_GC_THRESH2,		"gc_thresh2" },
+	{ NET_NEIGH_GC_THRESH3,		"gc_thresh3" },
+	{ NET_NEIGH_RETRANS_TIME_MS,	"retrans_time_ms" },
+	{ NET_NEIGH_REACHABLE_TIME_MS,	"base_reachable_time_ms" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_neigh_table[] = {
+	{ NET_PROTO_CONF_DEFAULT, "default", trans_net_neigh_vars_table },
+	{ 0, NULL, trans_net_neigh_vars_table },
+	{}
+};
+
+static struct trans_ctl_table trans_net_ipv4_netfilter_table[] = {
+	{ NET_IPV4_NF_CONNTRACK_MAX,				"ip_conntrack_max" },
+
+	{ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,		"ip_conntrack_tcp_timeout_syn_sent" },
+	{ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,		"ip_conntrack_tcp_timeout_syn_recv" },
+	{ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,	"ip_conntrack_tcp_timeout_established" },
+	{ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,		"ip_conntrack_tcp_timeout_fin_wait" },
+	{ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,		"ip_conntrack_tcp_timeout_close_wait" },
+	{ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,		"ip_conntrack_tcp_timeout_last_ack" },
+	{ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,		"ip_conntrack_tcp_timeout_time_wait" },
+	{ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,		"ip_conntrack_tcp_timeout_close" },
+
+	{ NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT,			"ip_conntrack_udp_timeout" },
+	{ NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM,		"ip_conntrack_udp_timeout_stream" },
+	{ NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT,			"ip_conntrack_icmp_timeout" },
+	{ NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT,		"ip_conntrack_generic_timeout" },
+
+	{ NET_IPV4_NF_CONNTRACK_BUCKETS,			"ip_conntrack_buckets" },
+	{ NET_IPV4_NF_CONNTRACK_LOG_INVALID,			"ip_conntrack_log_invalid" },
+	{ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,	"ip_conntrack_tcp_timeout_max_retrans" },
+	{ NET_IPV4_NF_CONNTRACK_TCP_LOOSE,			"ip_conntrack_tcp_loose" },
+	{ NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL,			"ip_conntrack_tcp_be_liberal" },
+	{ NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS,		"ip_conntrack_tcp_max_retrans" },
+
+	{ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,		"ip_conntrack_sctp_timeout_closed" },
+	{ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,	"ip_conntrack_sctp_timeout_cookie_wait" },
+	{ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,	"ip_conntrack_sctp_timeout_cookie_echoed" },
+	{ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,	"ip_conntrack_sctp_timeout_established" },
+	{ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,	"ip_conntrack_sctp_timeout_shutdown_sent" },
+	{ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,	"ip_conntrack_sctp_timeout_shutdown_recd" },
+	{ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,	"ip_conntrack_sctp_timeout_shutdown_ack_sent" },
+
+	{ NET_IPV4_NF_CONNTRACK_COUNT,		"ip_conntrack_count" },
+	{ NET_IPV4_NF_CONNTRACK_CHECKSUM,	"ip_conntrack_checksum" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_ipv4_table[] = {
+	{ NET_IPV4_FORWARD,			"ip_forward" },
+	{ NET_IPV4_DYNADDR,			"ip_dynaddr" },
+
+	{ NET_IPV4_CONF,		"conf",		trans_net_ipv4_conf_table },
+	{ NET_IPV4_NEIGH,		"neigh",	trans_net_neigh_table },
+	{ NET_IPV4_ROUTE,		"route",	trans_net_ipv4_route_table },
+	/* NET_IPV4_FIB_HASH unused */
+	{ NET_IPV4_NETFILTER,		"netfilter",	trans_net_ipv4_netfilter_table },
+	{ NET_IPV4_VS,			"vs",		trans_net_ipv4_vs_table },
+
+	{ NET_IPV4_TCP_TIMESTAMPS,		"tcp_timestamps" },
+	{ NET_IPV4_TCP_WINDOW_SCALING,		"tcp_window_scaling" },
+	{ NET_IPV4_TCP_SACK,			"tcp_sack" },
+	{ NET_IPV4_TCP_RETRANS_COLLAPSE,	"tcp_retrans_collapse" },
+	{ NET_IPV4_DEFAULT_TTL,			"ip_default_ttl" },
+	/* NET_IPV4_AUTOCONFIG unused */
+	{ NET_IPV4_NO_PMTU_DISC,		"ip_no_pmtu_disc" },
+	{ NET_IPV4_TCP_SYN_RETRIES,		"tcp_syn_retries" },
+	{ NET_IPV4_IPFRAG_HIGH_THRESH,		"ipfrag_high_thresh" },
+	{ NET_IPV4_IPFRAG_LOW_THRESH,		"ipfrag_low_thresh" },
+	{ NET_IPV4_IPFRAG_TIME,			"ipfrag_time" },
+	/* NET_IPV4_TCP_MAX_KA_PROBES unused */
+	{ NET_IPV4_TCP_KEEPALIVE_TIME,		"tcp_keepalive_time" },
+	{ NET_IPV4_TCP_KEEPALIVE_PROBES,	"tcp_keepalive_probes" },
+	{ NET_IPV4_TCP_RETRIES1,		"tcp_retries1" },
+	{ NET_IPV4_TCP_RETRIES2,		"tcp_retries2" },
+	{ NET_IPV4_TCP_FIN_TIMEOUT,		"tcp_fin_timeout" },
+	/* NET_IPV4_IP_MASQ_DEBUG unused */
+	{ NET_TCP_SYNCOOKIES,			"tcp_syncookies" },
+	{ NET_TCP_STDURG,			"tcp_stdurg" },
+	{ NET_TCP_RFC1337,			"tcp_rfc1337" },
+	/* NET_TCP_SYN_TAILDROP unused */
+	{ NET_TCP_MAX_SYN_BACKLOG,		"tcp_max_syn_backlog" },
+	{ NET_IPV4_LOCAL_PORT_RANGE,		"ip_local_port_range" },
+	{ NET_IPV4_ICMP_ECHO_IGNORE_ALL,	"icmp_echo_ignore_all" },
+	{ NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS,	"icmp_echo_ignore_broadcasts" },
+	/* NET_IPV4_ICMP_SOURCEQUENCH_RATE unused */
+	/* NET_IPV4_ICMP_DESTUNREACH_RATE unused */
+	/* NET_IPV4_ICMP_TIMEEXCEED_RATE unused */
+	/* NET_IPV4_ICMP_PARAMPROB_RATE unused */
+	/* NET_IPV4_ICMP_ECHOREPLY_RATE unused */
+	{ NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES,	"icmp_ignore_bogus_error_responses" },
+	{ NET_IPV4_IGMP_MAX_MEMBERSHIPS,	"igmp_max_memberships" },
+	{ NET_TCP_TW_RECYCLE,			"tcp_tw_recycle" },
+	/* NET_IPV4_ALWAYS_DEFRAG unused */
+	{ NET_IPV4_TCP_KEEPALIVE_INTVL,		"tcp_keepalive_intvl" },
+	{ NET_IPV4_INET_PEER_THRESHOLD,		"inet_peer_threshold" },
+	{ NET_IPV4_INET_PEER_MINTTL,		"inet_peer_minttl" },
+	{ NET_IPV4_INET_PEER_MAXTTL,		"inet_peer_maxttl" },
+	{ NET_IPV4_INET_PEER_GC_MINTIME,	"inet_peer_gc_mintime" },
+	{ NET_IPV4_INET_PEER_GC_MAXTIME,	"inet_peer_gc_maxtime" },
+	{ NET_TCP_ORPHAN_RETRIES,		"tcp_orphan_retries" },
+	{ NET_TCP_ABORT_ON_OVERFLOW,		"tcp_abort_on_overflow" },
+	{ NET_TCP_SYNACK_RETRIES,		"tcp_synack_retries" },
+	{ NET_TCP_MAX_ORPHANS,			"tcp_max_orphans" },
+	{ NET_TCP_MAX_TW_BUCKETS,		"tcp_max_tw_buckets" },
+	{ NET_TCP_FACK,				"tcp_fack" },
+	{ NET_TCP_REORDERING,			"tcp_reordering" },
+	{ NET_TCP_ECN,				"tcp_ecn" },
+	{ NET_TCP_DSACK,			"tcp_dsack" },
+	{ NET_TCP_MEM,				"tcp_mem" },
+	{ NET_TCP_WMEM,				"tcp_wmem" },
+	{ NET_TCP_RMEM,				"tcp_rmem" },
+	{ NET_TCP_APP_WIN,			"tcp_app_win" },
+	{ NET_TCP_ADV_WIN_SCALE,		"tcp_adv_win_scale" },
+	{ NET_IPV4_NONLOCAL_BIND,		"ip_nonlocal_bind" },
+	{ NET_IPV4_ICMP_RATELIMIT,		"icmp_ratelimit" },
+	{ NET_IPV4_ICMP_RATEMASK,		"icmp_ratemask" },
+	{ NET_TCP_TW_REUSE,			"tcp_tw_reuse" },
+	{ NET_TCP_FRTO,				"tcp_frto" },
+	{ NET_TCP_LOW_LATENCY,			"tcp_low_latency" },
+	{ NET_IPV4_IPFRAG_SECRET_INTERVAL,	"ipfrag_secret_interval" },
+	{ NET_IPV4_IGMP_MAX_MSF,		"igmp_max_msf" },
+	{ NET_TCP_NO_METRICS_SAVE,		"tcp_no_metrics_save" },
+	/* NET_TCP_DEFAULT_WIN_SCALE unused */
+	{ NET_TCP_MODERATE_RCVBUF,		"tcp_moderate_rcvbuf" },
+	{ NET_TCP_TSO_WIN_DIVISOR,		"tcp_tso_win_divisor" },
+	/* NET_TCP_BIC_BETA unused */
+	{ NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR,	"icmp_errors_use_inbound_ifaddr" },
+	{ NET_TCP_CONG_CONTROL,			"tcp_congestion_control" },
+	{ NET_TCP_ABC,				"tcp_abc" },
+	{ NET_IPV4_IPFRAG_MAX_DIST,		"ipfrag_max_dist" },
+	{ NET_TCP_MTU_PROBING,			"tcp_mtu_probing" },
+	{ NET_TCP_BASE_MSS,			"tcp_base_mss" },
+	{ NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS,	"tcp_workaround_signed_windows" },
+	{ NET_TCP_DMA_COPYBREAK,		"tcp_dma_copybreak" },
+	{ NET_TCP_SLOW_START_AFTER_IDLE,	"tcp_slow_start_after_idle" },
+	{ NET_CIPSOV4_CACHE_ENABLE,		"cipso_cache_enable" },
+	{ NET_CIPSOV4_CACHE_BUCKET_SIZE,	"cipso_cache_bucket_size" },
+	{ NET_CIPSOV4_RBM_OPTFMT,		"cipso_rbm_optfmt" },
+	{ NET_CIPSOV4_RBM_STRICTVALID,		"cipso_rbm_strictvalid" },
+	{ NET_TCP_AVAIL_CONG_CONTROL,		"tcp_available_congestion_control" },
+	{ NET_TCP_ALLOWED_CONG_CONTROL,		"tcp_allowed_congestion_control" },
+	{ NET_TCP_MAX_SSTHRESH,			"tcp_max_ssthresh" },
+	{ NET_TCP_FRTO_RESPONSE,		"tcp_frto_response" },
+	{ 2088 /* NET_IPQ_QMAX */,		"ip_queue_maxlen" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_ipx_table[] = {
+	{ NET_IPX_PPROP_BROADCASTING,	"ipx_pprop_broadcasting" },
+	/* NET_IPX_FORWARDING unused */
+	{}
+};
+
+static struct trans_ctl_table trans_net_atalk_table[] = {
+	{ NET_ATALK_AARP_EXPIRY_TIME,		"aarp-expiry-time" },
+	{ NET_ATALK_AARP_TICK_TIME,		"aarp-tick-time" },
+	{ NET_ATALK_AARP_RETRANSMIT_LIMIT,	"aarp-retransmit-limit" },
+	{ NET_ATALK_AARP_RESOLVE_TIME,		"aarp-resolve-time" },
+	{},
+};
+
+static struct trans_ctl_table trans_net_netrom_table[] = {
+	{ NET_NETROM_DEFAULT_PATH_QUALITY,		"default_path_quality" },
+	{ NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER,	"obsolescence_count_initialiser" },
+	{ NET_NETROM_NETWORK_TTL_INITIALISER,		"network_ttl_initialiser" },
+	{ NET_NETROM_TRANSPORT_TIMEOUT,			"transport_timeout" },
+	{ NET_NETROM_TRANSPORT_MAXIMUM_TRIES,		"transport_maximum_tries" },
+	{ NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY,	"transport_acknowledge_delay" },
+	{ NET_NETROM_TRANSPORT_BUSY_DELAY,		"transport_busy_delay" },
+	{ NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE,	"transport_requested_window_size" },
+	{ NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT,	"transport_no_activity_timeout" },
+	{ NET_NETROM_ROUTING_CONTROL,			"routing_control" },
+	{ NET_NETROM_LINK_FAILS_COUNT,			"link_fails_count" },
+	{ NET_NETROM_RESET,				"reset" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_ax25_table[] = {
+	{ NET_AX25_IP_DEFAULT_MODE,	"ip_default_mode" },
+	{ NET_AX25_DEFAULT_MODE,	"ax25_default_mode" },
+	{ NET_AX25_BACKOFF_TYPE,	"backoff_type" },
+	{ NET_AX25_CONNECT_MODE,	"connect_mode" },
+	{ NET_AX25_STANDARD_WINDOW,	"standard_window_size" },
+	{ NET_AX25_EXTENDED_WINDOW,	"extended_window_size" },
+	{ NET_AX25_T1_TIMEOUT,		"t1_timeout" },
+	{ NET_AX25_T2_TIMEOUT,		"t2_timeout" },
+	{ NET_AX25_T3_TIMEOUT,		"t3_timeout" },
+	{ NET_AX25_IDLE_TIMEOUT,	"idle_timeout" },
+	{ NET_AX25_N2,			"maximum_retry_count" },
+	{ NET_AX25_PACLEN,		"maximum_packet_length" },
+	{ NET_AX25_PROTOCOL,		"protocol" },
+	{ NET_AX25_DAMA_SLAVE_TIMEOUT,	"dama_slave_timeout" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_bridge_table[] = {
+	{ NET_BRIDGE_NF_CALL_ARPTABLES,		"bridge-nf-call-arptables" },
+	{ NET_BRIDGE_NF_CALL_IPTABLES,		"bridge-nf-call-iptables" },
+	{ NET_BRIDGE_NF_CALL_IP6TABLES,		"bridge-nf-call-ip6tables" },
+	{ NET_BRIDGE_NF_FILTER_VLAN_TAGGED,	"bridge-nf-filter-vlan-tagged" },
+	{ NET_BRIDGE_NF_FILTER_PPPOE_TAGGED,	"bridge-nf-filter-pppoe-tagged" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_rose_table[] = {
+	{ NET_ROSE_RESTART_REQUEST_TIMEOUT,	"restart_request_timeout" },
+	{ NET_ROSE_CALL_REQUEST_TIMEOUT,	"call_request_timeout" },
+	{ NET_ROSE_RESET_REQUEST_TIMEOUT,	"reset_request_timeout" },
+	{ NET_ROSE_CLEAR_REQUEST_TIMEOUT,	"clear_request_timeout" },
+	{ NET_ROSE_ACK_HOLD_BACK_TIMEOUT,	"acknowledge_hold_back_timeout" },
+	{ NET_ROSE_ROUTING_CONTROL,		"routing_control" },
+	{ NET_ROSE_LINK_FAIL_TIMEOUT,		"link_fail_timeout" },
+	{ NET_ROSE_MAX_VCS,			"maximum_virtual_circuits" },
+	{ NET_ROSE_WINDOW_SIZE,			"window_size" },
+	{ NET_ROSE_NO_ACTIVITY_TIMEOUT,		"no_activity_timeout" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_ipv6_conf_var_table[] = {
+	{ NET_IPV6_FORWARDING,			"forwarding" },
+	{ NET_IPV6_HOP_LIMIT,			"hop_limit" },
+	{ NET_IPV6_MTU,				"mtu" },
+	{ NET_IPV6_ACCEPT_RA,			"accept_ra" },
+	{ NET_IPV6_ACCEPT_REDIRECTS,		"accept_redirects" },
+	{ NET_IPV6_AUTOCONF,			"autoconf" },
+	{ NET_IPV6_DAD_TRANSMITS,		"dad_transmits" },
+	{ NET_IPV6_RTR_SOLICITS,		"router_solicitations" },
+	{ NET_IPV6_RTR_SOLICIT_INTERVAL,	"router_solicitation_interval" },
+	{ NET_IPV6_RTR_SOLICIT_DELAY,		"router_solicitation_delay" },
+	{ NET_IPV6_USE_TEMPADDR,		"use_tempaddr" },
+	{ NET_IPV6_TEMP_VALID_LFT,		"temp_valid_lft" },
+	{ NET_IPV6_TEMP_PREFERED_LFT,		"temp_prefered_lft" },
+	{ NET_IPV6_REGEN_MAX_RETRY,		"regen_max_retry" },
+	{ NET_IPV6_MAX_DESYNC_FACTOR,		"max_desync_factor" },
+	{ NET_IPV6_MAX_ADDRESSES,		"max_addresses" },
+	{ NET_IPV6_FORCE_MLD_VERSION,		"force_mld_version" },
+	{ NET_IPV6_ACCEPT_RA_DEFRTR,		"accept_ra_defrtr" },
+	{ NET_IPV6_ACCEPT_RA_PINFO,		"accept_ra_pinfo" },
+	{ NET_IPV6_ACCEPT_RA_RTR_PREF,		"accept_ra_rtr_pref" },
+	{ NET_IPV6_RTR_PROBE_INTERVAL,		"router_probe_interval" },
+	{ NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN,	"accept_ra_rt_info_max_plen" },
+	{ NET_IPV6_PROXY_NDP,			"proxy_ndp" },
+	{ NET_IPV6_ACCEPT_SOURCE_ROUTE,		"accept_source_route" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_ipv6_conf_table[] = {
+	{ NET_PROTO_CONF_ALL,		"all",	trans_net_ipv6_conf_var_table },
+	{ NET_PROTO_CONF_DEFAULT, 	"default", trans_net_ipv6_conf_var_table },
+	{ 0, NULL, trans_net_ipv6_conf_var_table },
+	{}
+};
+
+static struct trans_ctl_table trans_net_ipv6_route_table[] = {
+	{ NET_IPV6_ROUTE_FLUSH,			"flush" },
+	{ NET_IPV6_ROUTE_GC_THRESH,		"gc_thresh" },
+	{ NET_IPV6_ROUTE_MAX_SIZE,		"max_size" },
+	{ NET_IPV6_ROUTE_GC_MIN_INTERVAL,	"gc_min_interval" },
+	{ NET_IPV6_ROUTE_GC_TIMEOUT,		"gc_timeout" },
+	{ NET_IPV6_ROUTE_GC_INTERVAL,		"gc_interval" },
+	{ NET_IPV6_ROUTE_GC_ELASTICITY,		"gc_elasticity" },
+	{ NET_IPV6_ROUTE_MTU_EXPIRES,		"mtu_expires" },
+	{ NET_IPV6_ROUTE_MIN_ADVMSS,		"min_adv_mss" },
+	{ NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS,	"gc_min_interval_ms" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_ipv6_icmp_table[] = {
+	{ NET_IPV6_ICMP_RATELIMIT,	"ratelimit" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_ipv6_table[] = {
+	{ NET_IPV6_CONF,		"conf",		trans_net_ipv6_conf_table },
+	{ NET_IPV6_NEIGH,		"neigh",	trans_net_neigh_table },
+	{ NET_IPV6_ROUTE,		"route",	trans_net_ipv6_route_table },
+	{ NET_IPV6_ICMP,		"icmp",		trans_net_ipv6_icmp_table },
+	{ NET_IPV6_BINDV6ONLY,		"bindv6only" },
+	{ NET_IPV6_IP6FRAG_HIGH_THRESH,	"ip6frag_high_thresh" },
+	{ NET_IPV6_IP6FRAG_LOW_THRESH,	"ip6frag_low_thresh" },
+	{ NET_IPV6_IP6FRAG_TIME,	"ip6frag_time" },
+	{ NET_IPV6_IP6FRAG_SECRET_INTERVAL,	"ip6frag_secret_interval" },
+	{ NET_IPV6_MLD_MAX_MSF,		"mld_max_msf" },
+	{ 2088 /* IPQ_QMAX */,		"ip6_queue_maxlen" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_x25_table[] = {
+	{ NET_X25_RESTART_REQUEST_TIMEOUT,	"restart_request_timeout" },
+	{ NET_X25_CALL_REQUEST_TIMEOUT,		"call_request_timeout" },
+	{ NET_X25_RESET_REQUEST_TIMEOUT,	"reset_request_timeout" },
+	{ NET_X25_CLEAR_REQUEST_TIMEOUT,	"clear_request_timeout" },
+	{ NET_X25_ACK_HOLD_BACK_TIMEOUT,	"acknowledgement_hold_back_timeout" },
+	{ NET_X25_FORWARD,			"x25_forward" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_tr_table[] = {
+	{ NET_TR_RIF_TIMEOUT,	"rif_timeout" },
+	{}
+};
+
+
+static struct trans_ctl_table trans_net_decnet_conf_vars[] = {
+	{ NET_DECNET_CONF_DEV_FORWARDING,	"forwarding" },
+	{ NET_DECNET_CONF_DEV_PRIORITY,		"priority" },
+	{ NET_DECNET_CONF_DEV_T2,		"t2" },
+	{ NET_DECNET_CONF_DEV_T3,		"t3" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_decnet_conf[] = {
+	{ 0, NULL, trans_net_decnet_conf_vars },
+	{}
+};
+
+static struct trans_ctl_table trans_net_decnet_table[] = {
+	{ NET_DECNET_CONF,		"conf",	trans_net_decnet_conf },
+	{ NET_DECNET_NODE_ADDRESS,	"node_address" },
+	{ NET_DECNET_NODE_NAME,		"node_name" },
+	{ NET_DECNET_DEFAULT_DEVICE,	"default_device" },
+	{ NET_DECNET_TIME_WAIT,		"time_wait" },
+	{ NET_DECNET_DN_COUNT,		"dn_count" },
+	{ NET_DECNET_DI_COUNT,		"di_count" },
+	{ NET_DECNET_DR_COUNT,		"dr_count" },
+	{ NET_DECNET_DST_GC_INTERVAL,	"dst_gc_interval" },
+	{ NET_DECNET_NO_FC_MAX_CWND,	"no_fc_max_cwnd" },
+	{ NET_DECNET_MEM,		"decnet_mem" },
+	{ NET_DECNET_RMEM,		"decnet_rmem" },
+	{ NET_DECNET_WMEM,		"decnet_wmem" },
+	{ NET_DECNET_DEBUG_LEVEL,	"debug" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_sctp_table[] = {
+	{ NET_SCTP_RTO_INITIAL,		"rto_initial" },
+	{ NET_SCTP_RTO_MIN,		"rto_min" },
+	{ NET_SCTP_RTO_MAX,		"rto_max" },
+	{ NET_SCTP_RTO_ALPHA,		"rto_alpha_exp_divisor" },
+	{ NET_SCTP_RTO_BETA,		"rto_beta_exp_divisor" },
+	{ NET_SCTP_VALID_COOKIE_LIFE,	"valid_cookie_life" },
+	{ NET_SCTP_ASSOCIATION_MAX_RETRANS,	"association_max_retrans" },
+	{ NET_SCTP_PATH_MAX_RETRANS,	"path_max_retrans" },
+	{ NET_SCTP_MAX_INIT_RETRANSMITS,	"max_init_retransmits" },
+	{ NET_SCTP_HB_INTERVAL,		"hb_interval" },
+	{ NET_SCTP_PRESERVE_ENABLE,	"cookie_preserve_enable" },
+	{ NET_SCTP_MAX_BURST,		"max_burst" },
+	{ NET_SCTP_ADDIP_ENABLE,	"addip_enable" },
+	{ NET_SCTP_PRSCTP_ENABLE,	"prsctp_enable" },
+	{ NET_SCTP_SNDBUF_POLICY,	"sndbuf_policy" },
+	{ NET_SCTP_SACK_TIMEOUT,	"sack_timeout" },
+	{ NET_SCTP_RCVBUF_POLICY,	"rcvbuf_policy" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_llc_llc2_timeout_table[] = {
+	{ NET_LLC2_ACK_TIMEOUT,		"ack" },
+	{ NET_LLC2_P_TIMEOUT,		"p" },
+	{ NET_LLC2_REJ_TIMEOUT,		"rej" },
+	{ NET_LLC2_BUSY_TIMEOUT,	"busy" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_llc_station_table[] = {
+	{ NET_LLC_STATION_ACK_TIMEOUT,	"ack_timeout" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_llc_llc2_table[] = {
+	{ NET_LLC2,		"timeout",	trans_net_llc_llc2_timeout_table },
+	{}
+};
+
+static struct trans_ctl_table trans_net_llc_table[] = {
+	{ NET_LLC2,		"llc2",		trans_net_llc_llc2_table },
+	{ NET_LLC_STATION,	"station",	trans_net_llc_station_table },
+	{}
+};
+
+static struct trans_ctl_table trans_net_netfilter_table[] = {
+	{ NET_NF_CONNTRACK_MAX,				"nf_conntrack_max" },
+	{ NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,	"nf_conntrack_tcp_timeout_syn_sent" },
+	{ NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,	"nf_conntrack_tcp_timeout_syn_recv" },
+	{ NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,	"nf_conntrack_tcp_timeout_established" },
+	{ NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,	"nf_conntrack_tcp_timeout_fin_wait" },
+	{ NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,	"nf_conntrack_tcp_timeout_close_wait" },
+	{ NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,	"nf_conntrack_tcp_timeout_last_ack" },
+	{ NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,	"nf_conntrack_tcp_timeout_time_wait" },
+	{ NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,		"nf_conntrack_tcp_timeout_close" },
+	{ NET_NF_CONNTRACK_UDP_TIMEOUT,			"nf_conntrack_udp_timeout" },
+	{ NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM,		"nf_conntrack_udp_timeout_stream" },
+	{ NET_NF_CONNTRACK_ICMP_TIMEOUT,	"nf_conntrack_icmp_timeout" },
+	{ NET_NF_CONNTRACK_GENERIC_TIMEOUT,		"nf_conntrack_generic_timeout" },
+	{ NET_NF_CONNTRACK_BUCKETS,			"nf_conntrack_buckets" },
+	{ NET_NF_CONNTRACK_LOG_INVALID,			"nf_conntrack_log_invalid" },
+	{ NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,	"nf_conntrack_tcp_timeout_max_retrans" },
+	{ NET_NF_CONNTRACK_TCP_LOOSE,			"nf_conntrack_tcp_loose" },
+	{ NET_NF_CONNTRACK_TCP_BE_LIBERAL,		"nf_conntrack_tcp_be_liberal" },
+	{ NET_NF_CONNTRACK_TCP_MAX_RETRANS,		"nf_conntrack_tcp_max_retrans" },
+	{ NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,		"nf_conntrack_sctp_timeout_closed" },
+	{ NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,	"nf_conntrack_sctp_timeout_cookie_wait" },
+	{ NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,	"nf_conntrack_sctp_timeout_cookie_echoed" },
+	{ NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,	"nf_conntrack_sctp_timeout_established" },
+	{ NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,	"nf_conntrack_sctp_timeout_shutdown_sent" },
+	{ NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,	"nf_conntrack_sctp_timeout_shutdown_recd" },
+	{ NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,	"nf_conntrack_sctp_timeout_shutdown_ack_sent" },
+	{ NET_NF_CONNTRACK_COUNT,			"nf_conntrack_count" },
+	{ NET_NF_CONNTRACK_ICMPV6_TIMEOUT,	"nf_conntrack_icmpv6_timeout" },
+	{ NET_NF_CONNTRACK_FRAG6_TIMEOUT,		"nf_conntrack_frag6_timeout" },
+	{ NET_NF_CONNTRACK_FRAG6_LOW_THRESH,		"nf_conntrack_frag6_low_thresh" },
+	{ NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,		"nf_conntrack_frag6_high_thresh" },
+	{ NET_NF_CONNTRACK_CHECKSUM,			"nf_conntrack_checksum" },
+
+	{}
+};
+
+static struct trans_ctl_table trans_net_dccp_table[] = {
+	{ NET_DCCP_DEFAULT,	"default" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_irda_table[] = {
+	{ NET_IRDA_DISCOVERY,		"discovery" },
+	{ NET_IRDA_DEVNAME,		"devname" },
+	{ NET_IRDA_DEBUG,		"debug" },
+	{ NET_IRDA_FAST_POLL,		"fast_poll_increase" },
+	{ NET_IRDA_DISCOVERY_SLOTS,	"discovery_slots" },
+	{ NET_IRDA_DISCOVERY_TIMEOUT,	"discovery_timeout" },
+	{ NET_IRDA_SLOT_TIMEOUT,	"slot_timeout" },
+	{ NET_IRDA_MAX_BAUD_RATE,	"max_baud_rate" },
+	{ NET_IRDA_MIN_TX_TURN_TIME,	"min_tx_turn_time" },
+	{ NET_IRDA_MAX_TX_DATA_SIZE,	"max_tx_data_size" },
+	{ NET_IRDA_MAX_TX_WINDOW,	"max_tx_window" },
+	{ NET_IRDA_MAX_NOREPLY_TIME,	"max_noreply_time" },
+	{ NET_IRDA_WARN_NOREPLY_TIME,	"warn_noreply_time" },
+	{ NET_IRDA_LAP_KEEPALIVE_TIME,	"lap_keepalive_time" },
+	{}
+};
+
+static struct trans_ctl_table trans_net_table[] = {
+	{ NET_CORE,		"core",		trans_net_core_table },
+	/* NET_ETHER not used */
+	/* NET_802 not used */
+	{ NET_UNIX,		"unix",		trans_net_unix_table },
+	{ NET_IPV4,		"ipv4",		trans_net_ipv4_table },
+	{ NET_IPX,		"ipx",		trans_net_ipx_table },
+	{ NET_ATALK,		"appletalk",	trans_net_atalk_table },
+	{ NET_NETROM,		"netrom",	trans_net_netrom_table },
+	{ NET_AX25,		"ax25",		trans_net_ax25_table },
+	{ NET_BRIDGE,		"bridge",	trans_net_bridge_table },
+	{ NET_ROSE,		"rose",		trans_net_rose_table },
+	{ NET_IPV6,		"ipv6",		trans_net_ipv6_table },
+	{ NET_X25,		"x25",		trans_net_x25_table },
+	{ NET_TR,		"tr",		trans_net_tr_table },
+	{ NET_DECNET,		"decnet",	trans_net_decnet_table },
+	/*  NET_ECONET not used */
+	{ NET_SCTP,		"sctp",		trans_net_sctp_table },
+	{ NET_LLC,		"llc",		trans_net_llc_table },
+	{ NET_NETFILTER,	"netfilter",	trans_net_netfilter_table },
+	{ NET_DCCP,		"dccp",		trans_net_dccp_table },
+	{ NET_IRDA,		"irda",		trans_net_irda_table },
+	{ 2089,			"nf_conntrack_max" },
+	{}
+};
+
+static struct trans_ctl_table trans_fs_quota_table[] = {
+	{ FS_DQ_LOOKUPS,	"lookups" },
+	{ FS_DQ_DROPS,		"drops" },
+	{ FS_DQ_READS,		"reads" },
+	{ FS_DQ_WRITES,		"writes" },
+	{ FS_DQ_CACHE_HITS,	"cache_hits" },
+	{ FS_DQ_ALLOCATED,	"allocated_dquots" },
+	{ FS_DQ_FREE,		"free_dquots" },
+	{ FS_DQ_SYNCS,		"syncs" },
+	{ FS_DQ_WARNINGS,	"warnings" },
+	{}
+};
+
+static struct trans_ctl_table trans_fs_xfs_table[] = {
+	{ XFS_RESTRICT_CHOWN,	"restrict_chown" },
+	{ XFS_SGID_INHERIT,	"irix_sgid_inherit" },
+	{ XFS_SYMLINK_MODE,	"irix_symlink_mode" },
+	{ XFS_PANIC_MASK,	"panic_mask" },
+
+	{ XFS_ERRLEVEL,		"error_level" },
+	{ XFS_SYNCD_TIMER,	"xfssyncd_centisecs" },
+	{ XFS_INHERIT_SYNC,	"inherit_sync" },
+	{ XFS_INHERIT_NODUMP,	"inherit_nodump" },
+	{ XFS_INHERIT_NOATIME,	"inherit_noatime" },
+	{ XFS_BUF_TIMER,	"xfsbufd_centisecs" },
+	{ XFS_BUF_AGE,		"age_buffer_centisecs" },
+	{ XFS_INHERIT_NOSYM,	"inherit_nosymlinks" },
+	{ XFS_ROTORSTEP,	"rotorstep" },
+	{ XFS_INHERIT_NODFRG,	"inherit_nodefrag" },
+	{ XFS_FILESTREAM_TIMER,	"filestream_centisecs" },
+	{ XFS_STATS_CLEAR,	"stats_clear" },
+	{}
+};
+
+static struct trans_ctl_table trans_fs_ocfs2_nm_table[] = {
+	{ 1, "hb_ctl_path" },
+	{}
+};
+
+static struct trans_ctl_table trans_fs_ocfs2_table[] = {
+	{ 1,	"nm",	trans_fs_ocfs2_nm_table },
+	{}
+};
+
+static struct trans_ctl_table trans_inotify_table[] = {
+	{ INOTIFY_MAX_USER_INSTANCES,	"max_user_instances" },
+	{ INOTIFY_MAX_USER_WATCHES,	"max_user_watches" },
+	{ INOTIFY_MAX_QUEUED_EVENTS,	"max_queued_events" },
+	{}
+};
+
+static struct trans_ctl_table trans_fs_table[] = {
+	{ FS_NRINODE,		"inode-nr" },
+	{ FS_STATINODE,		"inode-state" },
+	/* FS_MAXINODE unused */
+	/* FS_NRDQUOT unused */
+	/* FS_MAXDQUOT unused */
+	{ FS_NRFILE,		"file-nr" },
+	{ FS_MAXFILE,		"file-max" },
+	{ FS_DENTRY,		"dentry-state" },
+	/* FS_NRSUPER unused */
+	/* FS_MAXUPSER unused */
+	{ FS_OVERFLOWUID,	"overflowuid" },
+	{ FS_OVERFLOWGID,	"overflowgid" },
+	{ FS_LEASES,		"leases-enable" },
+	{ FS_DIR_NOTIFY,	"dir-notify-enable" },
+	{ FS_LEASE_TIME,	"lease-break-time" },
+	{ FS_DQSTATS,		"quota",		trans_fs_quota_table },
+	{ FS_XFS,		"xfs",			trans_fs_xfs_table },
+	{ FS_AIO_NR,		"aio-nr" },
+	{ FS_AIO_MAX_NR,	"aio-max-nr" },
+	{ FS_INOTIFY,		"inotify",		trans_inotify_table },
+	{ FS_OCFS2,		"ocfs2",		trans_fs_ocfs2_table },
+	{ KERN_SETUID_DUMPABLE,	"suid_dumpable" },
+	{}
+};
+
+static struct trans_ctl_table trans_debug_table[] = {
+	{}
+};
+
+static struct trans_ctl_table trans_cdrom_table[] = {
+	{ DEV_CDROM_INFO,		"info" },
+	{ DEV_CDROM_AUTOCLOSE,		"autoclose" },
+	{ DEV_CDROM_AUTOEJECT,		"autoeject" },
+	{ DEV_CDROM_DEBUG,		"debug" },
+	{ DEV_CDROM_LOCK,		"lock" },
+	{ DEV_CDROM_CHECK_MEDIA,	"check_media" },
+	{}
+};
+
+static struct trans_ctl_table trans_ipmi_table[] = {
+	{ DEV_IPMI_POWEROFF_POWERCYCLE,	"poweroff_powercycle" },
+	{}
+};
+
+static struct trans_ctl_table trans_mac_hid_files[] = {
+	/* DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES unused */
+	/* DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES unused */
+	{ DEV_MAC_HID_MOUSE_BUTTON_EMULATION,	"mouse_button_emulation" },
+	{ DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE,	"mouse_button2_keycode" },
+	{ DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE,	"mouse_button3_keycode" },
+	/* DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES unused */
+	{}
+};
+
+static struct trans_ctl_table trans_raid_table[] = {
+	{ DEV_RAID_SPEED_LIMIT_MIN,	"speed_limit_min" },
+	{ DEV_RAID_SPEED_LIMIT_MAX,	"speed_limit_max" },
+	{}
+};
+
+static struct trans_ctl_table trans_scsi_table[] = {
+	{ DEV_SCSI_LOGGING_LEVEL, "logging_level" },
+	{}
+};
+
+static struct trans_ctl_table trans_parport_default_table[] = {
+	{ DEV_PARPORT_DEFAULT_TIMESLICE,	"timeslice" },
+	{ DEV_PARPORT_DEFAULT_SPINTIME,		"spintime" },
+	{}
+};
+
+static struct trans_ctl_table trans_parport_device_table[] = {
+	{ DEV_PARPORT_DEVICE_TIMESLICE,		"timeslice" },
+	{}
+};
+
+static struct trans_ctl_table trans_parport_devices_table[] = {
+	{ DEV_PARPORT_DEVICES_ACTIVE,		"active" },
+	{ 0, NULL, trans_parport_device_table },
+	{}
+};
+
+static struct trans_ctl_table trans_parport_parport_table[] = {
+	{ DEV_PARPORT_SPINTIME,		"spintime" },
+	{ DEV_PARPORT_BASE_ADDR,	"base-addr" },
+	{ DEV_PARPORT_IRQ,		"irq" },
+	{ DEV_PARPORT_DMA,		"dma" },
+	{ DEV_PARPORT_MODES,		"modes" },
+	{ DEV_PARPORT_DEVICES,		"devices",	trans_parport_devices_table },
+	{ DEV_PARPORT_AUTOPROBE,	"autoprobe" },
+	{ DEV_PARPORT_AUTOPROBE + 1,	"autoprobe0" },
+	{ DEV_PARPORT_AUTOPROBE + 2,	"autoprobe1" },
+	{ DEV_PARPORT_AUTOPROBE + 3,	"autoprobe2" },
+	{ DEV_PARPORT_AUTOPROBE + 4,	"autoprobe3" },
+	{}
+};
+static struct trans_ctl_table trans_parport_table[] = {
+	{ DEV_PARPORT_DEFAULT,	"default",	trans_parport_default_table },
+	{ 0, NULL, trans_parport_parport_table },
+	{}
+};
+
+static struct trans_ctl_table trans_dev_table[] = {
+	{ DEV_CDROM,	"cdrom",	trans_cdrom_table },
+	/* DEV_HWMON unused */
+	{ DEV_PARPORT,	"parport",	trans_parport_table },
+	{ DEV_RAID,	"raid",		trans_raid_table },
+	{ DEV_MAC_HID,	"mac_hid",	trans_mac_hid_files },
+	{ DEV_SCSI,	"scsi",		trans_scsi_table },
+	{ DEV_IPMI,	"ipmi",		trans_ipmi_table },
+	{}
+};
+
+static struct trans_ctl_table trans_bus_isa_table[] = {
+	{ BUS_ISA_MEM_BASE,	"membase" },
+	{ BUS_ISA_PORT_BASE,	"portbase" },
+	{ BUS_ISA_PORT_SHIFT,	"portshift" },
+	{}
+};
+
+static struct trans_ctl_table trans_bus_table[] = {
+	{ CTL_BUS_ISA,	"isa",	trans_bus_isa_table },
+	{}
+};
+
+static struct trans_ctl_table trans_arlan_conf_table0[] = {
+	{ 1,	"spreadingCode" },
+	{ 2,	"channelNumber" },
+	{ 3,	"scramblingDisable" },
+	{ 4,	"txAttenuation" },
+	{ 5,	"systemId" },
+	{ 6,	"maxDatagramSize" },
+	{ 7,	"maxFrameSize" },
+	{ 8,	"maxRetries" },
+	{ 9,	"receiveMode" },
+	{ 10,	"priority" },
+	{ 11,	"rootOrRepeater" },
+	{ 12,	"SID" },
+	{ 13,	"registrationMode" },
+	{ 14,	"registrationFill" },
+	{ 15,	"localTalkAddress" },
+	{ 16,	"codeFormat" },
+	{ 17,	"numChannels" },
+	{ 18,	"channel1" },
+	{ 19,	"channel2" },
+	{ 20,	"channel3" },
+	{ 21,	"channel4" },
+	{ 22,	"txClear" },
+	{ 23,	"txRetries" },
+	{ 24,	"txRouting" },
+	{ 25,	"txScrambled" },
+	{ 26,	"rxParameter" },
+	{ 27,	"txTimeoutMs" },
+	{ 28,	"waitCardTimeout" },
+	{ 29,	"channelSet" },
+	{ 30,	"name" },
+	{ 31,	"waitTime" },
+	{ 32,	"lParameter" },
+	{ 33,	"_15" },
+	{ 34,	"headerSize" },
+	{ 36,	"tx_delay_ms" },
+	{ 37,	"retries" },
+	{ 38,	"ReTransmitPacketMaxSize" },
+	{ 39,	"waitReTransmitPacketMaxSize" },
+	{ 40,	"fastReTransCount" },
+	{ 41,	"driverRetransmissions" },
+	{ 42,	"txAckTimeoutMs" },
+	{ 43,	"registrationInterrupts" },
+	{ 44,	"hardwareType" },
+	{ 45,	"radioType" },
+	{ 46,	"writeEEPROM" },
+	{ 47,	"writeRadioType" },
+	{ 48,	"entry_exit_debug" },
+	{ 49,	"debug" },
+	{ 50,	"in_speed" },
+	{ 51,	"out_speed" },
+	{ 52,	"in_speed10" },
+	{ 53,	"out_speed10" },
+	{ 54,	"in_speed_max" },
+	{ 55,	"out_speed_max" },
+	{ 56,	"measure_rate" },
+	{ 57,	"pre_Command_Wait" },
+	{ 58,	"rx_tweak1" },
+	{ 59,	"rx_tweak2" },
+	{ 60,	"tx_queue_len" },
+
+	{ 150,	"arlan0-txRing" },
+	{ 151,	"arlan0-rxRing" },
+	{ 152,	"arlan0-18" },
+	{ 153,	"arlan0-ring" },
+	{ 154,	"arlan0-shm-cpy" },
+	{ 155,	"config0" },
+	{ 156,	"reset0" },
+	{}
+};
+
+static struct trans_ctl_table trans_arlan_conf_table1[] = {
+	{ 1,	"spreadingCode" },
+	{ 2,	"channelNumber" },
+	{ 3,	"scramblingDisable" },
+	{ 4,	"txAttenuation" },
+	{ 5,	"systemId" },
+	{ 6,	"maxDatagramSize" },
+	{ 7,	"maxFrameSize" },
+	{ 8,	"maxRetries" },
+	{ 9,	"receiveMode" },
+	{ 10,	"priority" },
+	{ 11,	"rootOrRepeater" },
+	{ 12,	"SID" },
+	{ 13,	"registrationMode" },
+	{ 14,	"registrationFill" },
+	{ 15,	"localTalkAddress" },
+	{ 16,	"codeFormat" },
+	{ 17,	"numChannels" },
+	{ 18,	"channel1" },
+	{ 19,	"channel2" },
+	{ 20,	"channel3" },
+	{ 21,	"channel4" },
+	{ 22,	"txClear" },
+	{ 23,	"txRetries" },
+	{ 24,	"txRouting" },
+	{ 25,	"txScrambled" },
+	{ 26,	"rxParameter" },
+	{ 27,	"txTimeoutMs" },
+	{ 28,	"waitCardTimeout" },
+	{ 29,	"channelSet" },
+	{ 30,	"name" },
+	{ 31,	"waitTime" },
+	{ 32,	"lParameter" },
+	{ 33,	"_15" },
+	{ 34,	"headerSize" },
+	{ 36,	"tx_delay_ms" },
+	{ 37,	"retries" },
+	{ 38,	"ReTransmitPacketMaxSize" },
+	{ 39,	"waitReTransmitPacketMaxSize" },
+	{ 40,	"fastReTransCount" },
+	{ 41,	"driverRetransmissions" },
+	{ 42,	"txAckTimeoutMs" },
+	{ 43,	"registrationInterrupts" },
+	{ 44,	"hardwareType" },
+	{ 45,	"radioType" },
+	{ 46,	"writeEEPROM" },
+	{ 47,	"writeRadioType" },
+	{ 48,	"entry_exit_debug" },
+	{ 49,	"debug" },
+	{ 50,	"in_speed" },
+	{ 51,	"out_speed" },
+	{ 52,	"in_speed10" },
+	{ 53,	"out_speed10" },
+	{ 54,	"in_speed_max" },
+	{ 55,	"out_speed_max" },
+	{ 56,	"measure_rate" },
+	{ 57,	"pre_Command_Wait" },
+	{ 58,	"rx_tweak1" },
+	{ 59,	"rx_tweak2" },
+	{ 60,	"tx_queue_len" },
+
+	{ 150,	"arlan1-txRing" },
+	{ 151,	"arlan1-rxRing" },
+	{ 152,	"arlan1-18" },
+	{ 153,	"arlan1-ring" },
+	{ 154,	"arlan1-shm-cpy" },
+	{ 155,	"config1" },
+	{ 156,	"reset1" },
+	{}
+};
+
+static struct trans_ctl_table trans_arlan_conf_table2[] = {
+	{ 1,	"spreadingCode" },
+	{ 2,	"channelNumber" },
+	{ 3,	"scramblingDisable" },
+	{ 4,	"txAttenuation" },
+	{ 5,	"systemId" },
+	{ 6,	"maxDatagramSize" },
+	{ 7,	"maxFrameSize" },
+	{ 8,	"maxRetries" },
+	{ 9,	"receiveMode" },
+	{ 10,	"priority" },
+	{ 11,	"rootOrRepeater" },
+	{ 12,	"SID" },
+	{ 13,	"registrationMode" },
+	{ 14,	"registrationFill" },
+	{ 15,	"localTalkAddress" },
+	{ 16,	"codeFormat" },
+	{ 17,	"numChannels" },
+	{ 18,	"channel1" },
+	{ 19,	"channel2" },
+	{ 20,	"channel3" },
+	{ 21,	"channel4" },
+	{ 22,	"txClear" },
+	{ 23,	"txRetries" },
+	{ 24,	"txRouting" },
+	{ 25,	"txScrambled" },
+	{ 26,	"rxParameter" },
+	{ 27,	"txTimeoutMs" },
+	{ 28,	"waitCardTimeout" },
+	{ 29,	"channelSet" },
+	{ 30,	"name" },
+	{ 31,	"waitTime" },
+	{ 32,	"lParameter" },
+	{ 33,	"_15" },
+	{ 34,	"headerSize" },
+	{ 36,	"tx_delay_ms" },
+	{ 37,	"retries" },
+	{ 38,	"ReTransmitPacketMaxSize" },
+	{ 39,	"waitReTransmitPacketMaxSize" },
+	{ 40,	"fastReTransCount" },
+	{ 41,	"driverRetransmissions" },
+	{ 42,	"txAckTimeoutMs" },
+	{ 43,	"registrationInterrupts" },
+	{ 44,	"hardwareType" },
+	{ 45,	"radioType" },
+	{ 46,	"writeEEPROM" },
+	{ 47,	"writeRadioType" },
+	{ 48,	"entry_exit_debug" },
+	{ 49,	"debug" },
+	{ 50,	"in_speed" },
+	{ 51,	"out_speed" },
+	{ 52,	"in_speed10" },
+	{ 53,	"out_speed10" },
+	{ 54,	"in_speed_max" },
+	{ 55,	"out_speed_max" },
+	{ 56,	"measure_rate" },
+	{ 57,	"pre_Command_Wait" },
+	{ 58,	"rx_tweak1" },
+	{ 59,	"rx_tweak2" },
+	{ 60,	"tx_queue_len" },
+
+	{ 150,	"arlan2-txRing" },
+	{ 151,	"arlan2-rxRing" },
+	{ 152,	"arlan2-18" },
+	{ 153,	"arlan2-ring" },
+	{ 154,	"arlan2-shm-cpy" },
+	{ 155,	"config2" },
+	{ 156,	"reset2" },
+	{}
+};
+
+static struct trans_ctl_table trans_arlan_conf_table3[] = {
+	{ 1,	"spreadingCode" },
+	{ 2,	"channelNumber" },
+	{ 3,	"scramblingDisable" },
+	{ 4,	"txAttenuation" },
+	{ 5,	"systemId" },
+	{ 6,	"maxDatagramSize" },
+	{ 7,	"maxFrameSize" },
+	{ 8,	"maxRetries" },
+	{ 9,	"receiveMode" },
+	{ 10,	"priority" },
+	{ 11,	"rootOrRepeater" },
+	{ 12,	"SID" },
+	{ 13,	"registrationMode" },
+	{ 14,	"registrationFill" },
+	{ 15,	"localTalkAddress" },
+	{ 16,	"codeFormat" },
+	{ 17,	"numChannels" },
+	{ 18,	"channel1" },
+	{ 19,	"channel2" },
+	{ 20,	"channel3" },
+	{ 21,	"channel4" },
+	{ 22,	"txClear" },
+	{ 23,	"txRetries" },
+	{ 24,	"txRouting" },
+	{ 25,	"txScrambled" },
+	{ 26,	"rxParameter" },
+	{ 27,	"txTimeoutMs" },
+	{ 28,	"waitCardTimeout" },
+	{ 29,	"channelSet" },
+	{ 30,	"name" },
+	{ 31,	"waitTime" },
+	{ 32,	"lParameter" },
+	{ 33,	"_15" },
+	{ 34,	"headerSize" },
+	{ 36,	"tx_delay_ms" },
+	{ 37,	"retries" },
+	{ 38,	"ReTransmitPacketMaxSize" },
+	{ 39,	"waitReTransmitPacketMaxSize" },
+	{ 40,	"fastReTransCount" },
+	{ 41,	"driverRetransmissions" },
+	{ 42,	"txAckTimeoutMs" },
+	{ 43,	"registrationInterrupts" },
+	{ 44,	"hardwareType" },
+	{ 45,	"radioType" },
+	{ 46,	"writeEEPROM" },
+	{ 47,	"writeRadioType" },
+	{ 48,	"entry_exit_debug" },
+	{ 49,	"debug" },
+	{ 50,	"in_speed" },
+	{ 51,	"out_speed" },
+	{ 52,	"in_speed10" },
+	{ 53,	"out_speed10" },
+	{ 54,	"in_speed_max" },
+	{ 55,	"out_speed_max" },
+	{ 56,	"measure_rate" },
+	{ 57,	"pre_Command_Wait" },
+	{ 58,	"rx_tweak1" },
+	{ 59,	"rx_tweak2" },
+	{ 60,	"tx_queue_len" },
+
+	{ 150,	"arlan3-txRing" },
+	{ 151,	"arlan3-rxRing" },
+	{ 152,	"arlan3-18" },
+	{ 153,	"arlan3-ring" },
+	{ 154,	"arlan3-shm-cpy" },
+	{ 155,	"config3" },
+	{ 156,	"reset3" },
+	{}
+};
+
+static struct trans_ctl_table trans_arlan_table[] = {
+	{ 1,		"arlan0",	trans_arlan_conf_table0 },
+	{ 2,		"arlan1",	trans_arlan_conf_table1 },
+	{ 3,		"arlan2",	trans_arlan_conf_table2 },
+	{ 4,		"arlan3",	trans_arlan_conf_table3 },
+	{}
+};
+
+static struct trans_ctl_table trans_appldata_table[] = {
+	{ CTL_APPLDATA_TIMER,		"timer" },
+	{ CTL_APPLDATA_INTERVAL,	"interval" },
+	{ CTL_APPLDATA_OS,		"os" },
+	{ CTL_APPLDATA_NET_SUM,		"net_sum" },
+	{ CTL_APPLDATA_MEM,		"mem" },
+	{}
+
+};
+
+static struct trans_ctl_table trans_s390dbf_table[] = {
+	{ 5678 /* CTL_S390DBF_STOPPABLE */,	"debug_stoppable" },
+	{ 5679 /* CTL_S390DBF_ACTIVE */,	"debug_active" },
+	{}
+};
+
+static struct trans_ctl_table trans_sunrpc_table[] = {
+	{ CTL_RPCDEBUG,		"rpc_debug" },
+	{ CTL_NFSDEBUG,		"nfs_debug" },
+	{ CTL_NFSDDEBUG,	"nfsd_debug" },
+	{ CTL_NLMDEBUG,		"nlm_debug" },
+	{ CTL_SLOTTABLE_UDP,	"udp_slot_table_entries" },
+	{ CTL_SLOTTABLE_TCP,	"tcp_slot_table_entries" },
+	{ CTL_MIN_RESVPORT,	"min_resvport" },
+	{ CTL_MAX_RESVPORT,	"max_resvport" },
+	{}
+};
+
+static struct trans_ctl_table trans_pm_table[] = {
+	{ 1 /* CTL_PM_SUSPEND */,	"suspend" },
+	{ 2 /* CTL_PM_CMODE */,		"cmode" },
+	{ 3 /* CTL_PM_P0 */,		"p0" },
+	{ 4 /* CTL_PM_CM */,		"cm" },
+	{}
+};
+
+static struct trans_ctl_table trans_frv_table[] = {
+	{ 1,	"cache-mode" },
+	{ 2,	"pin-cxnr" },
+	{}
+};
+
+static struct trans_ctl_table trans_root_table[] = {
+	{ CTL_KERN,	"kernel",	trans_kern_table },
+	{ CTL_VM,	"vm",		trans_vm_table },
+	{ CTL_NET,	"net",		trans_net_table },
+	/* CTL_PROC not used */
+	{ CTL_FS,	"fs",		trans_fs_table },
+	{ CTL_DEBUG,	"debug",	trans_debug_table },
+	{ CTL_DEV,	"dev",		trans_dev_table },
+	{ CTL_BUS,	"bus",		trans_bus_table },
+	{ CTL_ABI,	"abi" },
+	/* CTL_CPU not used */
+	{ CTL_ARLAN,	"arlan",	trans_arlan_table },
+	{ CTL_APPLDATA,	"appldata",	trans_appldata_table },
+	{ CTL_S390DBF,	"s390dbf",	trans_s390dbf_table },
+	{ CTL_SUNRPC,	"sunrpc",	trans_sunrpc_table },
+	{ CTL_PM,	"pm",		trans_pm_table },
+	{ CTL_FRV,	"frv",		trans_frv_table },
+	{}
+};
+
+
+
+
+static int sysctl_depth(struct ctl_table *table)
+{
+	struct ctl_table *tmp;
+	int depth;
+
+	depth = 0;
+	for (tmp = table; tmp->parent; tmp = tmp->parent)
+		depth++;
+
+	return depth;
+}
+
+static struct ctl_table *sysctl_parent(struct ctl_table *table, int n)
+{
+	int i;
+
+	for (i = 0; table && i < n; i++)
+		table = table->parent;
+
+	return table;
+}
+
+static struct trans_ctl_table *sysctl_binary_lookup(struct ctl_table *table)
+{
+	struct ctl_table *test;
+	struct trans_ctl_table *ref;
+	int depth, cur_depth;
+
+	depth = sysctl_depth(table);
+
+	cur_depth = depth;
+	ref = trans_root_table;
+repeat:
+	test = sysctl_parent(table, cur_depth);
+	for (; ref->ctl_name || ref->procname || ref->child; ref++) {
+		int match = 0;
+
+		if (cur_depth && !ref->child)
+			continue;
+
+		if (test->procname && ref->procname &&
+			(strcmp(test->procname, ref->procname) == 0))
+			match++;
+
+		if (test->ctl_name && ref->ctl_name &&
+			(test->ctl_name == ref->ctl_name))
+			match++;
+
+		if (!ref->ctl_name && !ref->procname)
+			match++;
+
+		if (match) {
+			if (cur_depth != 0) {
+				cur_depth--;
+				ref = ref->child;
+				goto repeat;
+			}
+			goto out;
+		}
+	}
+	ref = NULL;
+out:
+	return ref;
+}
+
+static void sysctl_print_path(struct ctl_table *table)
+{
+	struct ctl_table *tmp;
+	int depth, i;
+	depth = sysctl_depth(table);
+	if (table->procname) {
+		for (i = depth; i >= 0; i--) {
+			tmp = sysctl_parent(table, i);
+			printk("/%s", tmp->procname?tmp->procname:"");
+		}
+	}
+	printk(" ");
+	if (table->ctl_name) {
+		for (i = depth; i >= 0; i--) {
+			tmp = sysctl_parent(table, i);
+			printk(".%d", tmp->ctl_name);
+		}
+	}
+}
+
+static void sysctl_repair_table(struct ctl_table *table)
+{
+	/* Don't complain about the classic default
+	 * sysctl strategy routine.  Maybe later we
+	 * can get the tables fixed and complain about
+	 * this.
+	 */
+	if (table->ctl_name && table->procname &&
+		(table->proc_handler == proc_dointvec) &&
+		(!table->strategy)) {
+		table->strategy = sysctl_data;
+	}
+}
+
+static struct ctl_table *sysctl_check_lookup(struct ctl_table *table)
+{
+	struct ctl_table_header *head;
+	struct ctl_table *ref, *test;
+	int depth, cur_depth;
+
+	depth = sysctl_depth(table);
+
+	for (head = sysctl_head_next(NULL); head;
+	     head = sysctl_head_next(head)) {
+		cur_depth = depth;
+		ref = head->ctl_table;
+repeat:
+		test = sysctl_parent(table, cur_depth);
+		for (; ref->ctl_name || ref->procname; ref++) {
+			int match = 0;
+			if (cur_depth && !ref->child)
+				continue;
+
+			if (test->procname && ref->procname &&
+			    (strcmp(test->procname, ref->procname) == 0))
+					match++;
+
+			if (test->ctl_name && ref->ctl_name &&
+			    (test->ctl_name == ref->ctl_name))
+				match++;
+
+			if (match) {
+				if (cur_depth != 0) {
+					cur_depth--;
+					ref = ref->child;
+					goto repeat;
+				}
+				goto out;
+			}
+		}
+	}
+	ref = NULL;
+out:
+	sysctl_head_finish(head);
+	return ref;
+}
+
+static void set_fail(const char **fail, struct ctl_table *table, const char *str)
+{
+	if (*fail) {
+		printk(KERN_ERR "sysctl table check failed: ");
+		sysctl_print_path(table);
+		printk(" %s\n", *fail);
+	}
+	*fail = str;
+}
+
+static int sysctl_check_dir(struct ctl_table *table)
+{
+	struct ctl_table *ref;
+	int error;
+
+	error = 0;
+	ref = sysctl_check_lookup(table);
+	if (ref) {
+		int match = 0;
+		if ((!table->procname && !ref->procname) ||
+		    (table->procname && ref->procname &&
+		     (strcmp(table->procname, ref->procname) == 0)))
+			match++;
+
+		if ((!table->ctl_name && !ref->ctl_name) ||
+		    (table->ctl_name && ref->ctl_name &&
+		     (table->ctl_name == ref->ctl_name)))
+			match++;
+
+		if (match != 2) {
+			printk(KERN_ERR "%s: failed: ", __func__);
+			sysctl_print_path(table);
+			printk(" ref: ");
+			sysctl_print_path(ref);
+			printk("\n");
+			error = -EINVAL;
+		}
+	}
+	return error;
+}
+
+static void sysctl_check_leaf(struct ctl_table *table, const char **fail)
+{
+	struct ctl_table *ref;
+
+	ref = sysctl_check_lookup(table);
+	if (ref && (ref != table))
+		set_fail(fail, table, "Sysctl already exists");
+}
+
+static void sysctl_check_bin_path(struct ctl_table *table, const char **fail)
+{
+	struct trans_ctl_table *ref;
+
+	ref = sysctl_binary_lookup(table);
+	if (table->ctl_name && !ref)
+		set_fail(fail, table, "Unknown sysctl binary path");
+	if (ref) {
+		if (ref->procname &&
+		    (!table->procname ||
+		     (strcmp(table->procname, ref->procname) != 0)))
+			set_fail(fail, table, "procname does not match binary path procname");
+
+		if (ref->ctl_name && table->ctl_name &&
+		    (table->ctl_name != ref->ctl_name))
+			set_fail(fail, table, "ctl_name does not match binary path ctl_name");
+	}
+}
+
+int sysctl_check_table(struct ctl_table *table)
+{
+	int error = 0;
+	for (; table->ctl_name || table->procname; table++) {
+		const char *fail = NULL;
+
+		sysctl_repair_table(table);
+		if (table->parent) {
+			if (table->procname && !table->parent->procname)
+				set_fail(&fail, table, "Parent without procname");
+			if (table->ctl_name && !table->parent->ctl_name)
+				set_fail(&fail, table, "Parent without ctl_name");
+		}
+		if (!table->procname)
+			set_fail(&fail, table, "No procname");
+		if (table->child) {
+			if (table->data)
+				set_fail(&fail, table, "Directory with data?");
+			if (table->maxlen)
+				set_fail(&fail, table, "Directory with maxlen?");
+			if ((table->mode & (S_IRUGO|S_IXUGO)) != table->mode)
+				set_fail(&fail, table, "Writable sysctl directory");
+			if (table->proc_handler)
+				set_fail(&fail, table, "Directory with proc_handler");
+			if (table->strategy)
+				set_fail(&fail, table, "Directory with strategy");
+			if (table->extra1)
+				set_fail(&fail, table, "Directory with extra1");
+			if (table->extra2)
+				set_fail(&fail, table, "Directory with extra2");
+			if (sysctl_check_dir(table))
+				set_fail(&fail, table, "Inconsistent directory names");
+		} else {
+			if ((table->strategy == sysctl_data) ||
+			    (table->strategy == sysctl_string) ||
+			    (table->strategy == sysctl_intvec) ||
+			    (table->strategy == sysctl_jiffies) ||
+			    (table->strategy == sysctl_ms_jiffies) ||
+			    (table->proc_handler == proc_dostring) ||
+			    (table->proc_handler == proc_dointvec) ||
+#ifdef CONFIG_SECURITY_CAPABILITIES
+			    (table->proc_handler == proc_dointvec_bset) ||
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
+			    (table->proc_handler == proc_dointvec_minmax) ||
+			    (table->proc_handler == proc_dointvec_jiffies) ||
+			    (table->proc_handler == proc_dointvec_userhz_jiffies) ||
+			    (table->proc_handler == proc_dointvec_ms_jiffies) ||
+			    (table->proc_handler == proc_doulongvec_minmax) ||
+			    (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
+				if (!table->data)
+					set_fail(&fail, table, "No data");
+				if (!table->maxlen)
+					set_fail(&fail, table, "No maxlen");
+			}
+			if ((table->proc_handler == proc_doulongvec_minmax) ||
+			    (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
+				if (table->maxlen > sizeof (unsigned long)) {
+					if (!table->extra1)
+						set_fail(&fail, table, "No min");
+					if (!table->extra2)
+						set_fail(&fail, table, "No max");
+				}
+			}
+#ifdef CONFIG_SYSCTL_SYSCALL
+			if (table->ctl_name && !table->strategy)
+				set_fail(&fail, table, "Missing strategy");
+#endif
+#if 0
+			if (!table->ctl_name && table->strategy)
+				set_fail(&fail, table, "Strategy without ctl_name");
+#endif
+#ifdef CONFIG_PROC_FS
+			if (table->procname && !table->proc_handler)
+				set_fail(&fail, table, "No proc_handler");
+#endif
+#if 0
+			if (!table->procname && table->proc_handler)
+				set_fail(&fail, table, "proc_handler without procname");
+#endif
+			sysctl_check_leaf(table, &fail);
+		}
+		sysctl_check_bin_path(table, &fail);
+		if (fail) {
+			set_fail(&fail, table, NULL);
+			error = -EINVAL;
+		}
+		if (table->child)
+			error |= sysctl_check_table(table->child);
+	}
+	return error;
+}
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 7d4d7f9..354e74b 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -22,6 +22,10 @@
 #include <linux/delayacct.h>
 #include <linux/cpumask.h>
 #include <linux/percpu.h>
+#include <linux/cgroupstats.h>
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+#include <linux/file.h>
 #include <net/genetlink.h>
 #include <asm/atomic.h>
 
@@ -49,6 +53,11 @@
 	[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING },
 	[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },};
 
+static struct nla_policy
+cgroupstats_cmd_get_policy[CGROUPSTATS_CMD_ATTR_MAX+1] __read_mostly = {
+	[CGROUPSTATS_CMD_ATTR_FD] = { .type = NLA_U32 },
+};
+
 struct listener {
 	struct list_head list;
 	pid_t pid;
@@ -254,7 +263,7 @@
 
 	stats->version = TASKSTATS_VERSION;
 	/*
-	 * Accounting subsytems can also add calls here to modify
+	 * Accounting subsystems can also add calls here to modify
 	 * fields of taskstats.
 	 */
 	return rc;
@@ -372,6 +381,51 @@
 	return NULL;
 }
 
+static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
+{
+	int rc = 0;
+	struct sk_buff *rep_skb;
+	struct cgroupstats *stats;
+	struct nlattr *na;
+	size_t size;
+	u32 fd;
+	struct file *file;
+	int fput_needed;
+
+	na = info->attrs[CGROUPSTATS_CMD_ATTR_FD];
+	if (!na)
+		return -EINVAL;
+
+	fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]);
+	file = fget_light(fd, &fput_needed);
+	if (file) {
+		size = nla_total_size(sizeof(struct cgroupstats));
+
+		rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb,
+					size);
+		if (rc < 0)
+			goto err;
+
+		na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS,
+					sizeof(struct cgroupstats));
+		stats = nla_data(na);
+		memset(stats, 0, sizeof(*stats));
+
+		rc = cgroupstats_build(stats, file->f_dentry);
+		if (rc < 0)
+			goto err;
+
+		fput_light(file, fput_needed);
+		return send_reply(rep_skb, info->snd_pid);
+	}
+
+err:
+	if (file)
+		fput_light(file, fput_needed);
+	nlmsg_free(rep_skb);
+	return rc;
+}
+
 static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
 {
 	int rc = 0;
@@ -522,6 +576,12 @@
 	.policy		= taskstats_cmd_get_policy,
 };
 
+static struct genl_ops cgroupstats_ops = {
+	.cmd		= CGROUPSTATS_CMD_GET,
+	.doit		= cgroupstats_user_cmd,
+	.policy		= cgroupstats_cmd_get_policy,
+};
+
 /* Needed early in initialization */
 void __init taskstats_init_early(void)
 {
@@ -546,8 +606,15 @@
 	if (rc < 0)
 		goto err;
 
+	rc = genl_register_ops(&family, &cgroupstats_ops);
+	if (rc < 0)
+		goto err_cgroup_ops;
+
 	family_registered = 1;
+	printk("registered taskstats version %d\n", TASKSTATS_GENL_VERSION);
 	return 0;
+err_cgroup_ops:
+	genl_unregister_ops(&family, &taskstats_ops);
 err:
 	genl_unregister_family(&family);
 	return rc;
diff --git a/kernel/time.c b/kernel/time.c
index 2d5b6a6..09d3c45 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -9,9 +9,9 @@
  */
 /*
  * Modification history kernel/time.c
- * 
+ *
  * 1993-09-02    Philip Gladstone
- *      Created file with time related functions from sched.c and adjtimex() 
+ *      Created file with time related functions from sched.c and adjtimex()
  * 1993-10-08    Torsten Duwe
  *      adjtime interface update and CMOS clock write code
  * 1995-08-13    Torsten Duwe
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/timex.h>
 #include <linux/capability.h>
+#include <linux/clocksource.h>
 #include <linux/errno.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
@@ -38,7 +39,7 @@
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 
-/* 
+/*
  * The timezone where the local system is located.  Used as a default by some
  * programs who obtain this value by using gettimeofday.
  */
@@ -71,7 +72,7 @@
  * why not move it into the appropriate arch directory (for those
  * architectures that need it).
  */
- 
+
 asmlinkage long sys_stime(time_t __user *tptr)
 {
 	struct timespec tv;
@@ -110,10 +111,10 @@
 /*
  * Adjust the time obtained from the CMOS to be UTC time instead of
  * local time.
- * 
+ *
  * This is ugly, but preferable to the alternatives.  Otherwise we
  * would either need to write a program to do it in /etc/rc (and risk
- * confusion if the program gets run more than once; it would also be 
+ * confusion if the program gets run more than once; it would also be
  * hard to make the program warp the clock precisely n hours)  or
  * compile in the timezone information into the kernel.  Bad, bad....
  *
@@ -158,6 +159,7 @@
 	if (tz) {
 		/* SMP safe, global irq locking makes it work. */
 		sys_tz = *tz;
+		update_vsyscall_tz();
 		if (firsttime) {
 			firsttime = 0;
 			if (!tv)
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 51b6a6a..c8a9d13 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -207,15 +207,12 @@
  */
 void clocksource_resume(void)
 {
-	struct list_head *tmp;
+	struct clocksource *cs;
 	unsigned long flags;
 
 	spin_lock_irqsave(&clocksource_lock, flags);
 
-	list_for_each(tmp, &clocksource_list) {
-		struct clocksource *cs;
-
-		cs = list_entry(tmp, struct clocksource, list);
+	list_for_each_entry(cs, &clocksource_list, list) {
 		if (cs->resume)
 			cs->resume();
 	}
@@ -369,7 +366,6 @@
 					  const char *buf, size_t count)
 {
 	struct clocksource *ovr = NULL;
-	struct list_head *tmp;
 	size_t ret = count;
 	int len;
 
@@ -389,12 +385,11 @@
 
 	len = strlen(override_name);
 	if (len) {
+		struct clocksource *cs;
+
 		ovr = clocksource_override;
 		/* try to select it: */
-		list_for_each(tmp, &clocksource_list) {
-			struct clocksource *cs;
-
-			cs = list_entry(tmp, struct clocksource, list);
+		list_for_each_entry(cs, &clocksource_list, list) {
 			if (strlen(cs->name) == len &&
 			    !strcmp(cs->name, override_name))
 				ovr = cs;
@@ -422,14 +417,11 @@
 static ssize_t
 sysfs_show_available_clocksources(struct sys_device *dev, char *buf)
 {
-	struct list_head *tmp;
+	struct clocksource *src;
 	char *curr = buf;
 
 	spin_lock_irq(&clocksource_lock);
-	list_for_each(tmp, &clocksource_list) {
-		struct clocksource *src;
-
-		src = list_entry(tmp, struct clocksource, list);
+	list_for_each_entry(src, &clocksource_list, list) {
 		curr += sprintf(curr, "%s ", src->name);
 	}
 	spin_unlock_irq(&clocksource_lock);
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index ce89ffb..10a1347 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -153,6 +153,7 @@
 	unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags;
 	struct tick_sched *ts;
 	ktime_t last_update, expires, now, delta;
+	struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
 	int cpu;
 
 	local_irq_save(flags);
@@ -302,11 +303,26 @@
 out:
 	ts->next_jiffies = next_jiffies;
 	ts->last_jiffies = last_jiffies;
+	ts->sleep_length = ktime_sub(dev->next_event, now);
 end:
 	local_irq_restore(flags);
 }
 
 /**
+ * tick_nohz_get_sleep_length - return the length of the current sleep
+ *
+ * Called from power state control code with interrupts disabled
+ */
+ktime_t tick_nohz_get_sleep_length(void)
+{
+	struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
+
+	return ts->sleep_length;
+}
+
+EXPORT_SYMBOL_GPL(tick_nohz_get_sleep_length);
+
+/**
  * nohz_restart_sched_tick - restart the idle tick from the idle task
  *
  * Restart the idle tick when the CPU is woken up from idle
diff --git a/kernel/timer.c b/kernel/timer.c
index 6ce1952..fb4e67d 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
+#include <linux/pid_namespace.h>
 #include <linux/notifier.h>
 #include <linux/thread_info.h>
 #include <linux/time.h>
@@ -817,7 +818,7 @@
 #endif
 
 /*
- * Called from the timer interrupt handler to charge one tick to the current 
+ * Called from the timer interrupt handler to charge one tick to the current
  * process.  user_tick is 1 if the tick is user time, 0 for system.
  */
 void update_process_times(int user_tick)
@@ -826,10 +827,13 @@
 	int cpu = smp_processor_id();
 
 	/* Note: this timer irq context must be accounted for as well. */
-	if (user_tick)
+	if (user_tick) {
 		account_user_time(p, jiffies_to_cputime(1));
-	else
+		account_user_time_scaled(p, jiffies_to_cputime(1));
+	} else {
 		account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1));
+		account_system_time_scaled(p, jiffies_to_cputime(1));
+	}
 	run_local_timers();
 	if (rcu_pending(cpu))
 		rcu_check_callbacks(cpu, user_tick);
@@ -953,7 +957,7 @@
  */
 asmlinkage long sys_getpid(void)
 {
-	return current->tgid;
+	return task_tgid_vnr(current);
 }
 
 /*
@@ -967,7 +971,7 @@
 	int pid;
 
 	rcu_read_lock();
-	pid = rcu_dereference(current->real_parent)->tgid;
+	pid = task_ppid_nr_ns(current, current->nsproxy->pid_ns);
 	rcu_read_unlock();
 
 	return pid;
@@ -1099,7 +1103,7 @@
 /* Thread ID - the internal kernel "pid" */
 asmlinkage long sys_gettid(void)
 {
-	return current->pid;
+	return task_pid_vnr(current);
 }
 
 /**
diff --git a/kernel/tsacct.c b/kernel/tsacct.c
index c122131..4ab1b58 100644
--- a/kernel/tsacct.c
+++ b/kernel/tsacct.c
@@ -62,6 +62,10 @@
 	rcu_read_unlock();
 	stats->ac_utime	 = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC;
 	stats->ac_stime	 = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC;
+	stats->ac_utimescaled =
+		cputime_to_msecs(tsk->utimescaled) * USEC_PER_MSEC;
+	stats->ac_stimescaled =
+		cputime_to_msecs(tsk->stimescaled) * USEC_PER_MSEC;
 	stats->ac_minflt = tsk->min_flt;
 	stats->ac_majflt = tsk->maj_flt;
 
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index e080d1d..52d5e7c 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -32,6 +32,7 @@
 #include <linux/freezer.h>
 #include <linux/kallsyms.h>
 #include <linux/debug_locks.h>
+#include <linux/lockdep.h>
 
 /*
  * The per-CPU workqueue (if single thread, we always use the first
@@ -61,6 +62,9 @@
 	const char *name;
 	int singlethread;
 	int freezeable;		/* Freeze threads during suspend */
+#ifdef CONFIG_LOCKDEP
+	struct lockdep_map lockdep_map;
+#endif
 };
 
 /* All the per-cpu workqueues on the system, for hotplug cpu to add/remove
@@ -250,6 +254,17 @@
 		struct work_struct *work = list_entry(cwq->worklist.next,
 						struct work_struct, entry);
 		work_func_t f = work->func;
+#ifdef CONFIG_LOCKDEP
+		/*
+		 * It is permissible to free the struct work_struct
+		 * from inside the function that is called from it,
+		 * this we need to take into account for lockdep too.
+		 * To avoid bogus "held lock freed" warnings as well
+		 * as problems when looking into work->lockdep_map,
+		 * make a copy and use that here.
+		 */
+		struct lockdep_map lockdep_map = work->lockdep_map;
+#endif
 
 		cwq->current_work = work;
 		list_del_init(cwq->worklist.next);
@@ -257,13 +272,17 @@
 
 		BUG_ON(get_wq_data(work) != cwq);
 		work_clear_pending(work);
+		lock_acquire(&cwq->wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+		lock_acquire(&lockdep_map, 0, 0, 0, 2, _THIS_IP_);
 		f(work);
+		lock_release(&lockdep_map, 1, _THIS_IP_);
+		lock_release(&cwq->wq->lockdep_map, 1, _THIS_IP_);
 
 		if (unlikely(in_atomic() || lockdep_depth(current) > 0)) {
 			printk(KERN_ERR "BUG: workqueue leaked lock or atomic: "
 					"%s/0x%08x/%d\n",
 					current->comm, preempt_count(),
-				       	current->pid);
+				       	task_pid_nr(current));
 			printk(KERN_ERR "    last function: ");
 			print_symbol("%s\n", (unsigned long)f);
 			debug_show_held_locks(current);
@@ -376,6 +395,8 @@
 	int cpu;
 
 	might_sleep();
+	lock_acquire(&wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+	lock_release(&wq->lockdep_map, 1, _THIS_IP_);
 	for_each_cpu_mask(cpu, *cpu_map)
 		flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu));
 }
@@ -446,6 +467,9 @@
 
 	might_sleep();
 
+	lock_acquire(&work->lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+	lock_release(&work->lockdep_map, 1, _THIS_IP_);
+
 	cwq = get_wq_data(work);
 	if (!cwq)
 		return;
@@ -695,8 +719,10 @@
 	}
 }
 
-struct workqueue_struct *__create_workqueue(const char *name,
-					    int singlethread, int freezeable)
+struct workqueue_struct *__create_workqueue_key(const char *name,
+						int singlethread,
+						int freezeable,
+						struct lock_class_key *key)
 {
 	struct workqueue_struct *wq;
 	struct cpu_workqueue_struct *cwq;
@@ -713,6 +739,7 @@
 	}
 
 	wq->name = name;
+	lockdep_init_map(&wq->lockdep_map, name, key, 0);
 	wq->singlethread = singlethread;
 	wq->freezeable = freezeable;
 	INIT_LIST_HEAD(&wq->list);
@@ -741,7 +768,7 @@
 	}
 	return wq;
 }
-EXPORT_SYMBOL_GPL(__create_workqueue);
+EXPORT_SYMBOL_GPL(__create_workqueue_key);
 
 static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
 {
@@ -752,6 +779,9 @@
 	if (cwq->thread == NULL)
 		return;
 
+	lock_acquire(&cwq->wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+	lock_release(&cwq->wq->lockdep_map, 1, _THIS_IP_);
+
 	flush_cpu_workqueue(cwq);
 	/*
 	 * If the caller is CPU_DEAD and cwq->worklist was not empty,
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7d16e64..1faa508 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -389,6 +389,16 @@
 
 	  If unsure, say N.
 
+config DEBUG_SG
+	bool "Debug SG table operations"
+	depends on DEBUG_KERNEL
+	help
+	  Enable this to turn on checks on scatter-gather tables. This can
+	  help find problems with drivers that do not properly initialize
+	  their sg tables.
+
+	  If unsure, say N.
+
 config FRAME_POINTER
 	bool "Compile the kernel with frame pointers"
 	depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH || BFIN)
@@ -498,3 +508,5 @@
 	select FRAME_POINTER
 	help
 	  Provide stacktrace filter for fault-injection capabilities
+
+source "samples/Kconfig"
diff --git a/lib/Makefile b/lib/Makefile
index c5f215d..3a0983b 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -6,7 +6,7 @@
 	 rbtree.o radix-tree.o dump_stack.o \
 	 idr.o int_sqrt.o bitmap.o extable.o prio_tree.o \
 	 sha1.o irq_regs.o reciprocal_div.o argv_split.o \
-	 proportions.o
+	 proportions.o prio_heap.o
 
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
diff --git a/lib/argv_split.c b/lib/argv_split.c
index fad6ce4..5205a8d 100644
--- a/lib/argv_split.c
+++ b/lib/argv_split.c
@@ -4,7 +4,8 @@
 
 #include <linux/kernel.h>
 #include <linux/ctype.h>
-#include <linux/bug.h>
+#include <linux/slab.h>
+#include <linux/module.h>
 
 static const char *skip_sep(const char *cp)
 {
diff --git a/lib/crc32.c b/lib/crc32.c
index bfc3331..d2c2f25 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -49,7 +49,7 @@
  * @p: pointer to buffer over which CRC is run
  * @len: length of buffer @p
  */
-u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len);
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len);
 
 #if CRC_LE_BITS == 1
 /*
@@ -57,7 +57,7 @@
  * simplified by inlining the table in ?: form.
  */
 
-u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
 {
 	int i;
 	while (len--) {
@@ -69,7 +69,7 @@
 }
 #else				/* Table-based approach */
 
-u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
 {
 # if CRC_LE_BITS == 8
 	const u32      *b =(u32 *)p;
@@ -145,7 +145,7 @@
  * @p: pointer to buffer over which CRC is run
  * @len: length of buffer @p
  */
-u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len);
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len);
 
 #if CRC_BE_BITS == 1
 /*
@@ -153,7 +153,7 @@
  * simplified by inlining the table in ?: form.
  */
 
-u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
 	int i;
 	while (len--) {
@@ -167,7 +167,7 @@
 }
 
 #else				/* Table-based approach */
-u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
 # if CRC_BE_BITS == 8
 	const u32      *b =(u32 *)p;
diff --git a/lib/hweight.c b/lib/hweight.c
index 360556a..389424e 100644
--- a/lib/hweight.c
+++ b/lib/hweight.c
@@ -1,6 +1,6 @@
 #include <linux/module.h>
+#include <linux/bitops.h>
 #include <asm/types.h>
-#include <asm/bitops.h>
 
 /**
  * hweightN - returns the hamming weight of a N-bit word
diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c
index e0fdfdd..f73e2f8 100644
--- a/lib/kernel_lock.c
+++ b/lib/kernel_lock.c
@@ -2,7 +2,7 @@
  * lib/kernel_lock.c
  *
  * This is the traditional BKL - big kernel lock. Largely
- * relegated to obsolescense, but used by various less
+ * relegated to obsolescence, but used by various less
  * important (or lazy) subsystems.
  */
 #include <linux/smp_lock.h>
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 2e4eae5..5886147 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -126,7 +126,7 @@
 	else
 		subsystem = kobject_name(&kset->kobj);
 	if (!subsystem) {
-		pr_debug("unset subsytem caused the event to drop!\n");
+		pr_debug("unset subsystem caused the event to drop!\n");
 		return 0;
 	}
 
diff --git a/lib/libcrc32c.c b/lib/libcrc32c.c
index 60f4680..802f11f 100644
--- a/lib/libcrc32c.c
+++ b/lib/libcrc32c.c
@@ -66,7 +66,7 @@
  * loop below with crc32 and vary the POLY if we don't find value in terms
  * of space and maintainability in keeping the two modules separate.
  */
-u32 __attribute_pure__
+u32 __pure
 crc32c_le(u32 crc, unsigned char const *p, size_t len)
 {
 	int i;
@@ -160,7 +160,7 @@
  * crc using table.
  */
 
-u32 __attribute_pure__
+u32 __pure
 crc32c_le(u32 seed, unsigned char const *data, size_t length)
 {
 	u32 crc = __cpu_to_le32(seed);
@@ -177,7 +177,7 @@
 EXPORT_SYMBOL(crc32c_be);
 
 #if CRC_BE_BITS == 1
-u32 __attribute_pure__
+u32 __pure
 crc32c_be(u32 crc, unsigned char const *p, size_t len)
 {
 	int i;
diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c
index 9659eab..393a0e9 100644
--- a/lib/percpu_counter.c
+++ b/lib/percpu_counter.c
@@ -124,12 +124,13 @@
 	mutex_lock(&percpu_counters_lock);
 	list_for_each_entry(fbc, &percpu_counters, list) {
 		s32 *pcount;
+		unsigned long flags;
 
-		spin_lock(&fbc->lock);
+		spin_lock_irqsave(&fbc->lock, flags);
 		pcount = per_cpu_ptr(fbc->counters, cpu);
 		fbc->count += *pcount;
 		*pcount = 0;
-		spin_unlock(&fbc->lock);
+		spin_unlock_irqrestore(&fbc->lock, flags);
 	}
 	mutex_unlock(&percpu_counters_lock);
 	return NOTIFY_OK;
diff --git a/lib/prio_heap.c b/lib/prio_heap.c
new file mode 100644
index 0000000..471944a
--- /dev/null
+++ b/lib/prio_heap.c
@@ -0,0 +1,70 @@
+/*
+ * Simple insertion-only static-sized priority heap containing
+ * pointers, based on CLR, chapter 7
+ */
+
+#include <linux/slab.h>
+#include <linux/prio_heap.h>
+
+int heap_init(struct ptr_heap *heap, size_t size, gfp_t gfp_mask,
+	      int (*gt)(void *, void *))
+{
+	heap->ptrs = kmalloc(size, gfp_mask);
+	if (!heap->ptrs)
+		return -ENOMEM;
+	heap->size = 0;
+	heap->max = size / sizeof(void *);
+	heap->gt = gt;
+	return 0;
+}
+
+void heap_free(struct ptr_heap *heap)
+{
+	kfree(heap->ptrs);
+}
+
+void *heap_insert(struct ptr_heap *heap, void *p)
+{
+	void *res;
+	void **ptrs = heap->ptrs;
+	int pos;
+
+	if (heap->size < heap->max) {
+		/* Heap insertion */
+		int pos = heap->size++;
+		while (pos > 0 && heap->gt(p, ptrs[(pos-1)/2])) {
+			ptrs[pos] = ptrs[(pos-1)/2];
+			pos = (pos-1)/2;
+		}
+		ptrs[pos] = p;
+		return NULL;
+	}
+
+	/* The heap is full, so something will have to be dropped */
+
+	/* If the new pointer is greater than the current max, drop it */
+	if (heap->gt(p, ptrs[0]))
+		return p;
+
+	/* Replace the current max and heapify */
+	res = ptrs[0];
+	ptrs[0] = p;
+	pos = 0;
+
+	while (1) {
+		int left = 2 * pos + 1;
+		int right = 2 * pos + 2;
+		int largest = pos;
+		if (left < heap->size && heap->gt(ptrs[left], p))
+			largest = left;
+		if (right < heap->size && heap->gt(ptrs[right], ptrs[largest]))
+			largest = right;
+		if (largest == pos)
+			break;
+		/* Push p down the heap one level and bump one up */
+		ptrs[pos] = ptrs[largest];
+		ptrs[largest] = p;
+		pos = largest;
+	}
+	return res;
+}
diff --git a/lib/reed_solomon/decode_rs.c b/lib/reed_solomon/decode_rs.c
index a58df56..0ec3f25 100644
--- a/lib/reed_solomon/decode_rs.c
+++ b/lib/reed_solomon/decode_rs.c
@@ -39,8 +39,7 @@
 
 	/* Check length parameter for validity */
 	pad = nn - nroots - len;
-	if (pad < 0 || pad >= nn)
-		return -ERANGE;
+	BUG_ON(pad < 0 || pad >= nn);
 
 	/* Does the caller provide the syndrome ? */
 	if (s != NULL)
@@ -203,7 +202,7 @@
 		 * deg(lambda) unequal to number of roots => uncorrectable
 		 * error detected
 		 */
-		count = -1;
+		count = -EBADMSG;
 		goto finish;
 	}
 	/*
diff --git a/lib/reed_solomon/reed_solomon.c b/lib/reed_solomon/reed_solomon.c
index 5b0d852..3ea2db9 100644
--- a/lib/reed_solomon/reed_solomon.c
+++ b/lib/reed_solomon/reed_solomon.c
@@ -320,6 +320,7 @@
  *  The syndrome and parity uses a uint16_t data type to enable
  *  symbol size > 8. The calling code must take care of decoding of the
  *  syndrome result and the received parity before calling this code.
+ *  Returns the number of corrected bits or -EBADMSG for uncorrectable errors.
  */
 int decode_rs8(struct rs_control *rs, uint8_t *data, uint16_t *par, int len,
 	       uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
@@ -363,6 +364,7 @@
  *  @corr:	buffer to store correction bitmask on eras_pos
  *
  *  Each field in the data array contains up to symbol size bits of valid data.
+ *  Returns the number of corrected bits or -EBADMSG for uncorrectable errors.
  */
 int decode_rs16(struct rs_control *rs, uint16_t *data, uint16_t *par, int len,
 		uint16_t *s, int no_eras, int *eras_pos, uint16_t invmsk,
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
index 479fd46..9c4b025 100644
--- a/lib/spinlock_debug.c
+++ b/lib/spinlock_debug.c
@@ -60,12 +60,12 @@
 		owner = lock->owner;
 	printk(KERN_EMERG "BUG: spinlock %s on CPU#%d, %s/%d\n",
 		msg, raw_smp_processor_id(),
-		current->comm, current->pid);
+		current->comm, task_pid_nr(current));
 	printk(KERN_EMERG " lock: %p, .magic: %08x, .owner: %s/%d, "
 			".owner_cpu: %d\n",
 		lock, lock->magic,
 		owner ? owner->comm : "<none>",
-		owner ? owner->pid : -1,
+		owner ? task_pid_nr(owner) : -1,
 		lock->owner_cpu);
 	dump_stack();
 }
@@ -116,7 +116,7 @@
 			printk(KERN_EMERG "BUG: spinlock lockup on CPU#%d, "
 					"%s/%d, %p\n",
 				raw_smp_processor_id(), current->comm,
-				current->pid, lock);
+				task_pid_nr(current), lock);
 			dump_stack();
 #ifdef CONFIG_SMP
 			trigger_all_cpu_backtrace();
@@ -161,7 +161,7 @@
 
 	printk(KERN_EMERG "BUG: rwlock %s on CPU#%d, %s/%d, %p\n",
 		msg, raw_smp_processor_id(), current->comm,
-		current->pid, lock);
+		task_pid_nr(current), lock);
 	dump_stack();
 }
 
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 752fd95..1a8050a 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -35,7 +35,7 @@
 #define OFFSET(val,align) ((unsigned long)	\
 	                   ( (val) & ( (align) - 1)))
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg)	(sg_virt((sg)))
 #define SG_ENT_PHYS_ADDRESS(sg)	virt_to_bus(SG_ENT_VIRT_ADDRESS(sg))
 
 /*
diff --git a/mm/Kconfig b/mm/Kconfig
index b1f03b0..c070ec0 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -37,7 +37,7 @@
 	  in their physical address spaces, and this option provides
 	  more efficient handling of these holes.  However, the vast
 	  majority of hardware has quite flat address spaces, and
-	  can have degraded performance from extra overhead that
+	  can have degraded performance from the extra overhead that
 	  this option imposes.
 
 	  Many NUMA configurations will have this as the only option.
diff --git a/mm/filemap.c b/mm/filemap.c
index 79f24a9..5209e47 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -25,6 +25,7 @@
 #include <linux/uio.h>
 #include <linux/hash.h>
 #include <linux/writeback.h>
+#include <linux/backing-dev.h>
 #include <linux/pagevec.h>
 #include <linux/blkdev.h>
 #include <linux/security.h>
@@ -840,7 +841,7 @@
 /**
  * do_generic_mapping_read - generic file read routine
  * @mapping:	address_space to be read
- * @_ra:	file's readahead state
+ * @ra:		file's readahead state
  * @filp:	the file to read
  * @ppos:	current file position
  * @desc:	read_descriptor
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index ae2959b..8b809ec 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1017,10 +1017,10 @@
 
 	/* If we are below the current region then a new region is required.
 	 * Subtle, allocate a new region at the position but make it zero
-	 * size such that we can guarentee to record the reservation. */
+	 * size such that we can guarantee to record the reservation. */
 	if (&rg->link == head || t < rg->from) {
 		nrg = kmalloc(sizeof(*nrg), GFP_KERNEL);
-		if (nrg == 0)
+		if (!nrg)
 			return -ENOMEM;
 		nrg->from = f;
 		nrg->to   = f;
diff --git a/mm/memory.c b/mm/memory.c
index bd16dca..eefd5b6 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -259,9 +259,6 @@
 			continue;
 		free_pud_range(*tlb, pgd, addr, next, floor, ceiling);
 	} while (pgd++, addr = next, addr != end);
-
-	if (!(*tlb)->fullmm)
-		flush_tlb_pgtables((*tlb)->mm, start, end);
 }
 
 void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *vma,
@@ -2716,7 +2713,7 @@
 		return 0;
 
 	down_read(&mm->mmap_sem);
-	/* ignore errors, just check how much was sucessfully transfered */
+	/* ignore errors, just check how much was successfully transferred */
 	while (len) {
 		int bytes, ret, offset;
 		void *maddr;
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 091b9c6..3a47871 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -121,7 +121,7 @@
 		err = __add_section(zone, i << PFN_SECTION_SHIFT);
 
 		/*
-		 * EEXIST is finally dealed with by ioresource collision
+		 * EEXIST is finally dealt with by ioresource collision
 		 * check. see add_memory() => register_memory_resource()
 		 * Warning will be printed if there is collision.
 		 */
@@ -187,7 +187,24 @@
 	unsigned long onlined_pages = 0;
 	struct zone *zone;
 	int need_zonelists_rebuild = 0;
+	int nid;
+	int ret;
+	struct memory_notify arg;
 
+	arg.start_pfn = pfn;
+	arg.nr_pages = nr_pages;
+	arg.status_change_nid = -1;
+
+	nid = page_to_nid(pfn_to_page(pfn));
+	if (node_present_pages(nid) == 0)
+		arg.status_change_nid = nid;
+
+	ret = memory_notify(MEM_GOING_ONLINE, &arg);
+	ret = notifier_to_errno(ret);
+	if (ret) {
+		memory_notify(MEM_CANCEL_ONLINE, &arg);
+		return ret;
+	}
 	/*
 	 * This doesn't need a lock to do pfn_to_page().
 	 * The section can't be removed here because of the
@@ -222,6 +239,10 @@
 		build_all_zonelists();
 	vm_total_pages = nr_free_pagecache_pages();
 	writeback_set_ratelimit();
+
+	if (onlined_pages)
+		memory_notify(MEM_ONLINE, &arg);
+
 	return 0;
 }
 #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
@@ -467,8 +488,9 @@
 {
 	unsigned long pfn, nr_pages, expire;
 	long offlined_pages;
-	int ret, drain, retry_max;
+	int ret, drain, retry_max, node;
 	struct zone *zone;
+	struct memory_notify arg;
 
 	BUG_ON(start_pfn >= end_pfn);
 	/* at least, alignment against pageblock is necessary */
@@ -480,11 +502,27 @@
 	   we assume this for now. .*/
 	if (!test_pages_in_a_zone(start_pfn, end_pfn))
 		return -EINVAL;
+
+	zone = page_zone(pfn_to_page(start_pfn));
+	node = zone_to_nid(zone);
+	nr_pages = end_pfn - start_pfn;
+
 	/* set above range as isolated */
 	ret = start_isolate_page_range(start_pfn, end_pfn);
 	if (ret)
 		return ret;
-	nr_pages = end_pfn - start_pfn;
+
+	arg.start_pfn = start_pfn;
+	arg.nr_pages = nr_pages;
+	arg.status_change_nid = -1;
+	if (nr_pages >= node_present_pages(node))
+		arg.status_change_nid = node;
+
+	ret = memory_notify(MEM_GOING_OFFLINE, &arg);
+	ret = notifier_to_errno(ret);
+	if (ret)
+		goto failed_removal;
+
 	pfn = start_pfn;
 	expire = jiffies + timeout;
 	drain = 0;
@@ -539,20 +577,24 @@
 	/* reset pagetype flags */
 	start_isolate_page_range(start_pfn, end_pfn);
 	/* removal success */
-	zone = page_zone(pfn_to_page(start_pfn));
 	zone->present_pages -= offlined_pages;
 	zone->zone_pgdat->node_present_pages -= offlined_pages;
 	totalram_pages -= offlined_pages;
 	num_physpages -= offlined_pages;
+
 	vm_total_pages = nr_free_pagecache_pages();
 	writeback_set_ratelimit();
+
+	memory_notify(MEM_OFFLINE, &arg);
 	return 0;
 
 failed_removal:
 	printk(KERN_INFO "memory offlining %lx to %lx failed\n",
 		start_pfn, end_pfn);
+	memory_notify(MEM_CANCEL_OFFLINE, &arg);
 	/* pushback to free area */
 	undo_isolate_page_range(start_pfn, end_pfn);
+
 	return ret;
 }
 #else
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 568152a..c1592a9 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -78,6 +78,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/module.h>
+#include <linux/nsproxy.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/compat.h>
@@ -940,7 +941,7 @@
 
 	/* Find the mm_struct */
 	read_lock(&tasklist_lock);
-	task = pid ? find_task_by_pid(pid) : current;
+	task = pid ? find_task_by_vpid(pid) : current;
 	if (!task) {
 		read_unlock(&tasklist_lock);
 		return -ESRCH;
@@ -1388,7 +1389,6 @@
  * keeps mempolicies cpuset relative after its cpuset moves.  See
  * further kernel/cpuset.c update_nodemask().
  */
-void *cpuset_being_rebound;
 
 /* Slow path of a mempolicy copy */
 struct mempolicy *__mpol_copy(struct mempolicy *old)
@@ -2019,4 +2019,3 @@
 		m->version = (vma != priv->tail_vma) ? vma->vm_start : 0;
 	return 0;
 }
-
diff --git a/mm/mempool.c b/mm/mempool.c
index 02d5ec3..a46eb1b 100644
--- a/mm/mempool.c
+++ b/mm/mempool.c
@@ -299,7 +299,7 @@
 
 /*
  * A commonly used alloc and free fn that kmalloc/kfrees the amount of memory
- * specfied by pool_data
+ * specified by pool_data
  */
 void *mempool_kmalloc(gfp_t gfp_mask, void *pool_data)
 {
diff --git a/mm/migrate.c b/mm/migrate.c
index 06d0877..6a207e8 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -19,6 +19,7 @@
 #include <linux/pagemap.h>
 #include <linux/buffer_head.h>
 #include <linux/mm_inline.h>
+#include <linux/nsproxy.h>
 #include <linux/pagevec.h>
 #include <linux/rmap.h>
 #include <linux/topology.h>
@@ -705,7 +706,7 @@
  * The function returns after 10 attempts or if no pages
  * are movable anymore because to has become empty
  * or no retryable pages exist anymore. All pages will be
- * retruned to the LRU or freed.
+ * returned to the LRU or freed.
  *
  * Return: Number of pages not migrated or error code.
  */
@@ -924,7 +925,7 @@
 
 	/* Find the mm_struct */
 	read_lock(&tasklist_lock);
-	task = pid ? find_task_by_pid(pid) : current;
+	task = pid ? find_task_by_vpid(pid) : current;
 	if (!task) {
 		read_unlock(&tasklist_lock);
 		return -ESRCH;
diff --git a/mm/mmap.c b/mm/mmap.c
index 4275e81..facc1a7 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1048,8 +1048,7 @@
 
 	/* The open routine did something to the protections already? */
 	if (pgprot_val(vma->vm_page_prot) !=
-	    pgprot_val(protection_map[vm_flags &
-		    (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]))
+	    pgprot_val(vm_get_page_prot(vm_flags)))
 		return 0;
 
 	/* Specialty mapping? */
@@ -1130,8 +1129,7 @@
 	vma->vm_start = addr;
 	vma->vm_end = addr + len;
 	vma->vm_flags = vm_flags;
-	vma->vm_page_prot = protection_map[vm_flags &
-				(VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
+	vma->vm_page_prot = vm_get_page_prot(vm_flags);
 	vma->vm_pgoff = pgoff;
 
 	if (file) {
@@ -1173,8 +1171,7 @@
 	vm_flags = vma->vm_flags;
 
 	if (vma_wants_writenotify(vma))
-		vma->vm_page_prot =
-			protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
+		vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED);
 
 	if (!file || !vma_merge(mm, prev, addr, vma->vm_end,
 			vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
@@ -2002,8 +1999,7 @@
 	vma->vm_end = addr + len;
 	vma->vm_pgoff = pgoff;
 	vma->vm_flags = flags;
-	vma->vm_page_prot = protection_map[flags &
-				(VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
+	vma->vm_page_prot = vm_get_page_prot(flags);
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 out:
 	mm->total_vm += len >> PAGE_SHIFT;
@@ -2209,7 +2205,7 @@
 	vma->vm_end = addr + len;
 
 	vma->vm_flags = vm_flags | mm->def_flags;
-	vma->vm_page_prot = protection_map[vma->vm_flags & 7];
+	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
 
 	vma->vm_ops = &special_mapping_vmops;
 	vma->vm_private_data = pages;
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 1d4d697..4de5468 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -192,11 +192,9 @@
 	 * held in write mode.
 	 */
 	vma->vm_flags = newflags;
-	vma->vm_page_prot = protection_map[newflags &
-		(VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
+	vma->vm_page_prot = vm_get_page_prot(newflags);
 	if (vma_wants_writenotify(vma)) {
-		vma->vm_page_prot = protection_map[newflags &
-			(VM_READ|VM_WRITE|VM_EXEC)];
+		vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
 		dirty_accountable = 1;
 	}
 
diff --git a/mm/mremap.c b/mm/mremap.c
index 8ea5c24..08e3c7f 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -291,7 +291,7 @@
 		if ((addr <= new_addr) && (addr+old_len) > new_addr)
 			goto out;
 
-		ret = security_file_mmap(0, 0, 0, 0, new_addr, 1);
+		ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
 		if (ret)
 			goto out;
 
@@ -399,7 +399,7 @@
 				goto out;
 			}
 
-			ret = security_file_mmap(0, 0, 0, 0, new_addr, 1);
+			ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
 			if (ret)
 				goto out;
 		}
diff --git a/mm/nommu.c b/mm/nommu.c
index 42fb84e..8f09333 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -175,7 +175,8 @@
 void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
 {
 	/*
-	 * kmalloc doesn't like __GFP_HIGHMEM for some reason
+	 *  You can't specify __GFP_HIGHMEM with kmalloc() since kmalloc()
+	 * returns only a logical address.
 	 */
 	return kmalloc(size, (gfp_mask | __GFP_COMP) & ~__GFP_HIGHMEM);
 }
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index a64decb..91a081a 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -212,7 +212,7 @@
 		if (!p->mm)
 			continue;
 		/* skip the init task */
-		if (is_init(p))
+		if (is_global_init(p))
 			continue;
 
 		/*
@@ -265,7 +265,7 @@
  */
 static void __oom_kill_task(struct task_struct *p, int verbose)
 {
-	if (is_init(p)) {
+	if (is_global_init(p)) {
 		WARN_ON(1);
 		printk(KERN_WARNING "tried to kill init!\n");
 		return;
@@ -278,7 +278,8 @@
 	}
 
 	if (verbose)
-		printk(KERN_ERR "Killed process %d (%s)\n", p->pid, p->comm);
+		printk(KERN_ERR "Killed process %d (%s)\n",
+				task_pid_nr(p), p->comm);
 
 	/*
 	 * We give our sacrificial lamb high priority and access to
@@ -326,7 +327,7 @@
 	 * to memory reserves though, otherwise we might deplete all memory.
 	 */
 	do_each_thread(g, q) {
-		if (q->mm == mm && q->tgid != p->tgid)
+		if (q->mm == mm && !same_thread_group(q, p))
 			force_sig(SIGKILL, q);
 	} while_each_thread(g, q);
 
@@ -337,7 +338,6 @@
 			    unsigned long points, const char *message)
 {
 	struct task_struct *c;
-	struct list_head *tsk;
 
 	if (printk_ratelimit()) {
 		printk(KERN_WARNING "%s invoked oom-killer: "
@@ -357,11 +357,10 @@
 	}
 
 	printk(KERN_ERR "%s: kill process %d (%s) score %li or a child\n",
-					message, p->pid, p->comm, points);
+					message, task_pid_nr(p), p->comm, points);
 
 	/* Try to kill a child first */
-	list_for_each(tsk, &p->children) {
-		c = list_entry(tsk, struct task_struct, sibling);
+	list_for_each_entry(c, &p->children, sibling) {
 		if (c->mm == p->mm)
 			continue;
 		if (!oom_kill_task(c))
@@ -497,7 +496,7 @@
 			panic("Out of memory and no killable processes...\n");
 		}
 
-		if (oom_kill_process(p, points, gfp_mask, order,
+		if (oom_kill_process(p, gfp_mask, order, points,
 				     "Out of memory"))
 			goto retry;
 
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 7845462..838a5e3 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -989,7 +989,7 @@
  * mapping is pinned by the vma's ->vm_file reference.
  *
  * We take care to handle the case where the page was truncated from the
- * mapping by re-checking page_mapping() insode tree_lock.
+ * mapping by re-checking page_mapping() inside tree_lock.
  */
 int __set_page_dirty_nobuffers(struct page *page)
 {
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 43f757f..da69d83 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -123,7 +123,7 @@
 
 #ifdef CONFIG_ARCH_POPULATES_NODE_MAP
   /*
-   * MAX_ACTIVE_REGIONS determines the maxmimum number of distinct
+   * MAX_ACTIVE_REGIONS determines the maximum number of distinct
    * ranges of memory (RAM) that may be registered with add_active_range().
    * Ranges passed to add_active_range() will be merged if possible
    * so the number of times add_active_range() can be called is
@@ -1260,7 +1260,7 @@
  * skip over zones that are not allowed by the cpuset, or that have
  * been recently (in last second) found to be nearly full.  See further
  * comments in mmzone.h.  Reduces cache footprint of zonelist scans
- * that have to skip over alot of full or unallowed zones.
+ * that have to skip over a lot of full or unallowed zones.
  *
  * If the zonelist cache is present in the passed in zonelist, then
  * returns a pointer to the allowed node mask (either the current
@@ -2358,7 +2358,7 @@
 		__build_all_zonelists(NULL);
 		cpuset_init_current_mems_allowed();
 	} else {
-		/* we have to stop all cpus to guaranntee there is no user
+		/* we have to stop all cpus to guarantee there is no user
 		   of zonelist */
 		stop_machine_run(__build_all_zonelists, NULL, NR_CPUS);
 		/* cpuset refresh routine should be here */
@@ -2864,7 +2864,7 @@
 
 /*
  * Basic iterator support. Return the next active range of PFNs for a node
- * Note: nid == MAX_NUMNODES returns next region regardles of node
+ * Note: nid == MAX_NUMNODES returns next region regardless of node
  */
 static int __meminit next_active_region_index_in_nid(int index, int nid)
 {
diff --git a/mm/prio_tree.c b/mm/prio_tree.c
index b4e76c2..603ae98 100644
--- a/mm/prio_tree.c
+++ b/mm/prio_tree.c
@@ -34,7 +34,7 @@
  * Radix priority search tree for address_space->i_mmap
  *
  * For each vma that map a unique set of file pages i.e., unique [radix_index,
- * heap_index] value, we have a corresponing priority search tree node. If
+ * heap_index] value, we have a corresponding priority search tree node. If
  * multiple vmas have identical [radix_index, heap_index] value, then one of
  * them is used as a tree node and others are stored in a vm_set list. The tree
  * node points to the first vma (head) of the list using vm_set.head.
diff --git a/mm/shmem.c b/mm/shmem.c
index 289dbb0..404e53b 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2020,33 +2020,25 @@
 	return ino->i_ino == inum && fh[0] == ino->i_generation;
 }
 
-static struct dentry *shmem_get_dentry(struct super_block *sb, void *vfh)
+static struct dentry *shmem_fh_to_dentry(struct super_block *sb,
+		struct fid *fid, int fh_len, int fh_type)
 {
-	struct dentry *de = NULL;
 	struct inode *inode;
-	__u32 *fh = vfh;
-	__u64 inum = fh[2];
-	inum = (inum << 32) | fh[1];
+	struct dentry *dentry = NULL;
+	u64 inum = fid->raw[2];
+	inum = (inum << 32) | fid->raw[1];
 
-	inode = ilookup5(sb, (unsigned long)(inum+fh[0]), shmem_match, vfh);
+	if (fh_len < 3)
+		return NULL;
+
+	inode = ilookup5(sb, (unsigned long)(inum + fid->raw[0]),
+			shmem_match, fid->raw);
 	if (inode) {
-		de = d_find_alias(inode);
+		dentry = d_find_alias(inode);
 		iput(inode);
 	}
 
-	return de? de: ERR_PTR(-ESTALE);
-}
-
-static struct dentry *shmem_decode_fh(struct super_block *sb, __u32 *fh,
-		int len, int type,
-		int (*acceptable)(void *context, struct dentry *de),
-		void *context)
-{
-	if (len < 3)
-		return ERR_PTR(-ESTALE);
-
-	return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable,
-							context);
+	return dentry;
 }
 
 static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
@@ -2079,11 +2071,10 @@
 	return 1;
 }
 
-static struct export_operations shmem_export_ops = {
+static const struct export_operations shmem_export_ops = {
 	.get_parent     = shmem_get_parent,
-	.get_dentry     = shmem_get_dentry,
 	.encode_fh      = shmem_encode_fh,
-	.decode_fh      = shmem_decode_fh,
+	.fh_to_dentry	= shmem_fh_to_dentry,
 };
 
 static int shmem_parse_options(char *options, int *mode, uid_t *uid,
diff --git a/mm/slab.c b/mm/slab.c
index 3ce9bc0..cfa6be4 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -26,7 +26,7 @@
  * initialized objects.
  *
  * This means, that your constructor is used only for newly allocated
- * slabs and you must pass objects with the same intializations to
+ * slabs and you must pass objects with the same initializations to
  * kmem_cache_free.
  *
  * Each cache can only support one memory type (GFP_DMA, GFP_HIGHMEM,
@@ -1156,105 +1156,187 @@
 }
 #endif
 
-static int __cpuinit cpuup_callback(struct notifier_block *nfb,
-				    unsigned long action, void *hcpu)
+static void __cpuinit cpuup_canceled(long cpu)
 {
-	long cpu = (long)hcpu;
+	struct kmem_cache *cachep;
+	struct kmem_list3 *l3 = NULL;
+	int node = cpu_to_node(cpu);
+
+	list_for_each_entry(cachep, &cache_chain, next) {
+		struct array_cache *nc;
+		struct array_cache *shared;
+		struct array_cache **alien;
+		cpumask_t mask;
+
+		mask = node_to_cpumask(node);
+		/* cpu is dead; no one can alloc from it. */
+		nc = cachep->array[cpu];
+		cachep->array[cpu] = NULL;
+		l3 = cachep->nodelists[node];
+
+		if (!l3)
+			goto free_array_cache;
+
+		spin_lock_irq(&l3->list_lock);
+
+		/* Free limit for this kmem_list3 */
+		l3->free_limit -= cachep->batchcount;
+		if (nc)
+			free_block(cachep, nc->entry, nc->avail, node);
+
+		if (!cpus_empty(mask)) {
+			spin_unlock_irq(&l3->list_lock);
+			goto free_array_cache;
+		}
+
+		shared = l3->shared;
+		if (shared) {
+			free_block(cachep, shared->entry,
+				   shared->avail, node);
+			l3->shared = NULL;
+		}
+
+		alien = l3->alien;
+		l3->alien = NULL;
+
+		spin_unlock_irq(&l3->list_lock);
+
+		kfree(shared);
+		if (alien) {
+			drain_alien_cache(cachep, alien);
+			free_alien_cache(alien);
+		}
+free_array_cache:
+		kfree(nc);
+	}
+	/*
+	 * In the previous loop, all the objects were freed to
+	 * the respective cache's slabs,  now we can go ahead and
+	 * shrink each nodelist to its limit.
+	 */
+	list_for_each_entry(cachep, &cache_chain, next) {
+		l3 = cachep->nodelists[node];
+		if (!l3)
+			continue;
+		drain_freelist(cachep, l3, l3->free_objects);
+	}
+}
+
+static int __cpuinit cpuup_prepare(long cpu)
+{
 	struct kmem_cache *cachep;
 	struct kmem_list3 *l3 = NULL;
 	int node = cpu_to_node(cpu);
 	const int memsize = sizeof(struct kmem_list3);
 
+	/*
+	 * We need to do this right in the beginning since
+	 * alloc_arraycache's are going to use this list.
+	 * kmalloc_node allows us to add the slab to the right
+	 * kmem_list3 and not this cpu's kmem_list3
+	 */
+
+	list_for_each_entry(cachep, &cache_chain, next) {
+		/*
+		 * Set up the size64 kmemlist for cpu before we can
+		 * begin anything. Make sure some other cpu on this
+		 * node has not already allocated this
+		 */
+		if (!cachep->nodelists[node]) {
+			l3 = kmalloc_node(memsize, GFP_KERNEL, node);
+			if (!l3)
+				goto bad;
+			kmem_list3_init(l3);
+			l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
+			    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
+
+			/*
+			 * The l3s don't come and go as CPUs come and
+			 * go.  cache_chain_mutex is sufficient
+			 * protection here.
+			 */
+			cachep->nodelists[node] = l3;
+		}
+
+		spin_lock_irq(&cachep->nodelists[node]->list_lock);
+		cachep->nodelists[node]->free_limit =
+			(1 + nr_cpus_node(node)) *
+			cachep->batchcount + cachep->num;
+		spin_unlock_irq(&cachep->nodelists[node]->list_lock);
+	}
+
+	/*
+	 * Now we can go ahead with allocating the shared arrays and
+	 * array caches
+	 */
+	list_for_each_entry(cachep, &cache_chain, next) {
+		struct array_cache *nc;
+		struct array_cache *shared = NULL;
+		struct array_cache **alien = NULL;
+
+		nc = alloc_arraycache(node, cachep->limit,
+					cachep->batchcount);
+		if (!nc)
+			goto bad;
+		if (cachep->shared) {
+			shared = alloc_arraycache(node,
+				cachep->shared * cachep->batchcount,
+				0xbaadf00d);
+			if (!shared) {
+				kfree(nc);
+				goto bad;
+			}
+		}
+		if (use_alien_caches) {
+			alien = alloc_alien_cache(node, cachep->limit);
+			if (!alien) {
+				kfree(shared);
+				kfree(nc);
+				goto bad;
+			}
+		}
+		cachep->array[cpu] = nc;
+		l3 = cachep->nodelists[node];
+		BUG_ON(!l3);
+
+		spin_lock_irq(&l3->list_lock);
+		if (!l3->shared) {
+			/*
+			 * We are serialised from CPU_DEAD or
+			 * CPU_UP_CANCELLED by the cpucontrol lock
+			 */
+			l3->shared = shared;
+			shared = NULL;
+		}
+#ifdef CONFIG_NUMA
+		if (!l3->alien) {
+			l3->alien = alien;
+			alien = NULL;
+		}
+#endif
+		spin_unlock_irq(&l3->list_lock);
+		kfree(shared);
+		free_alien_cache(alien);
+	}
+	return 0;
+bad:
+	cpuup_canceled(cpu);
+	return -ENOMEM;
+}
+
+static int __cpuinit cpuup_callback(struct notifier_block *nfb,
+				    unsigned long action, void *hcpu)
+{
+	long cpu = (long)hcpu;
+	int err = 0;
+
 	switch (action) {
 	case CPU_LOCK_ACQUIRE:
 		mutex_lock(&cache_chain_mutex);
 		break;
 	case CPU_UP_PREPARE:
 	case CPU_UP_PREPARE_FROZEN:
-		/*
-		 * We need to do this right in the beginning since
-		 * alloc_arraycache's are going to use this list.
-		 * kmalloc_node allows us to add the slab to the right
-		 * kmem_list3 and not this cpu's kmem_list3
-		 */
-
-		list_for_each_entry(cachep, &cache_chain, next) {
-			/*
-			 * Set up the size64 kmemlist for cpu before we can
-			 * begin anything. Make sure some other cpu on this
-			 * node has not already allocated this
-			 */
-			if (!cachep->nodelists[node]) {
-				l3 = kmalloc_node(memsize, GFP_KERNEL, node);
-				if (!l3)
-					goto bad;
-				kmem_list3_init(l3);
-				l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
-				    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
-
-				/*
-				 * The l3s don't come and go as CPUs come and
-				 * go.  cache_chain_mutex is sufficient
-				 * protection here.
-				 */
-				cachep->nodelists[node] = l3;
-			}
-
-			spin_lock_irq(&cachep->nodelists[node]->list_lock);
-			cachep->nodelists[node]->free_limit =
-				(1 + nr_cpus_node(node)) *
-				cachep->batchcount + cachep->num;
-			spin_unlock_irq(&cachep->nodelists[node]->list_lock);
-		}
-
-		/*
-		 * Now we can go ahead with allocating the shared arrays and
-		 * array caches
-		 */
-		list_for_each_entry(cachep, &cache_chain, next) {
-			struct array_cache *nc;
-			struct array_cache *shared = NULL;
-			struct array_cache **alien = NULL;
-
-			nc = alloc_arraycache(node, cachep->limit,
-						cachep->batchcount);
-			if (!nc)
-				goto bad;
-			if (cachep->shared) {
-				shared = alloc_arraycache(node,
-					cachep->shared * cachep->batchcount,
-					0xbaadf00d);
-				if (!shared)
-					goto bad;
-			}
-			if (use_alien_caches) {
-                                alien = alloc_alien_cache(node, cachep->limit);
-                                if (!alien)
-                                        goto bad;
-                        }
-			cachep->array[cpu] = nc;
-			l3 = cachep->nodelists[node];
-			BUG_ON(!l3);
-
-			spin_lock_irq(&l3->list_lock);
-			if (!l3->shared) {
-				/*
-				 * We are serialised from CPU_DEAD or
-				 * CPU_UP_CANCELLED by the cpucontrol lock
-				 */
-				l3->shared = shared;
-				shared = NULL;
-			}
-#ifdef CONFIG_NUMA
-			if (!l3->alien) {
-				l3->alien = alien;
-				alien = NULL;
-			}
-#endif
-			spin_unlock_irq(&l3->list_lock);
-			kfree(shared);
-			free_alien_cache(alien);
-		}
+		err = cpuup_prepare(cpu);
 		break;
 	case CPU_ONLINE:
 	case CPU_ONLINE_FROZEN:
@@ -1287,76 +1369,17 @@
 		 * structure is usually allocated from kmem_cache_create() and
 		 * gets destroyed at kmem_cache_destroy().
 		 */
-		/* fall thru */
+		/* fall through */
 #endif
 	case CPU_UP_CANCELED:
 	case CPU_UP_CANCELED_FROZEN:
-		list_for_each_entry(cachep, &cache_chain, next) {
-			struct array_cache *nc;
-			struct array_cache *shared;
-			struct array_cache **alien;
-			cpumask_t mask;
-
-			mask = node_to_cpumask(node);
-			/* cpu is dead; no one can alloc from it. */
-			nc = cachep->array[cpu];
-			cachep->array[cpu] = NULL;
-			l3 = cachep->nodelists[node];
-
-			if (!l3)
-				goto free_array_cache;
-
-			spin_lock_irq(&l3->list_lock);
-
-			/* Free limit for this kmem_list3 */
-			l3->free_limit -= cachep->batchcount;
-			if (nc)
-				free_block(cachep, nc->entry, nc->avail, node);
-
-			if (!cpus_empty(mask)) {
-				spin_unlock_irq(&l3->list_lock);
-				goto free_array_cache;
-			}
-
-			shared = l3->shared;
-			if (shared) {
-				free_block(cachep, shared->entry,
-					   shared->avail, node);
-				l3->shared = NULL;
-			}
-
-			alien = l3->alien;
-			l3->alien = NULL;
-
-			spin_unlock_irq(&l3->list_lock);
-
-			kfree(shared);
-			if (alien) {
-				drain_alien_cache(cachep, alien);
-				free_alien_cache(alien);
-			}
-free_array_cache:
-			kfree(nc);
-		}
-		/*
-		 * In the previous loop, all the objects were freed to
-		 * the respective cache's slabs,  now we can go ahead and
-		 * shrink each nodelist to its limit.
-		 */
-		list_for_each_entry(cachep, &cache_chain, next) {
-			l3 = cachep->nodelists[node];
-			if (!l3)
-				continue;
-			drain_freelist(cachep, l3, l3->free_objects);
-		}
+		cpuup_canceled(cpu);
 		break;
 	case CPU_LOCK_RELEASE:
 		mutex_unlock(&cache_chain_mutex);
 		break;
 	}
-	return NOTIFY_OK;
-bad:
-	return NOTIFY_BAD;
+	return err ? NOTIFY_BAD : NOTIFY_OK;
 }
 
 static struct notifier_block __cpuinitdata cpucache_notifier = {
@@ -3783,7 +3806,7 @@
 EXPORT_SYMBOL_GPL(kmem_cache_name);
 
 /*
- * This initializes kmem_list3 or resizes varioius caches for all nodes.
+ * This initializes kmem_list3 or resizes various caches for all nodes.
  */
 static int alloc_kmemlist(struct kmem_cache *cachep)
 {
diff --git a/mm/slub.c b/mm/slub.c
index e29a429..aac1dd3 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -20,6 +20,7 @@
 #include <linux/mempolicy.h>
 #include <linux/ctype.h>
 #include <linux/kallsyms.h>
+#include <linux/memory.h>
 
 /*
  * Lock order:
@@ -2694,6 +2695,121 @@
 }
 EXPORT_SYMBOL(kmem_cache_shrink);
 
+#if defined(CONFIG_NUMA) && defined(CONFIG_MEMORY_HOTPLUG)
+static int slab_mem_going_offline_callback(void *arg)
+{
+	struct kmem_cache *s;
+
+	down_read(&slub_lock);
+	list_for_each_entry(s, &slab_caches, list)
+		kmem_cache_shrink(s);
+	up_read(&slub_lock);
+
+	return 0;
+}
+
+static void slab_mem_offline_callback(void *arg)
+{
+	struct kmem_cache_node *n;
+	struct kmem_cache *s;
+	struct memory_notify *marg = arg;
+	int offline_node;
+
+	offline_node = marg->status_change_nid;
+
+	/*
+	 * If the node still has available memory. we need kmem_cache_node
+	 * for it yet.
+	 */
+	if (offline_node < 0)
+		return;
+
+	down_read(&slub_lock);
+	list_for_each_entry(s, &slab_caches, list) {
+		n = get_node(s, offline_node);
+		if (n) {
+			/*
+			 * if n->nr_slabs > 0, slabs still exist on the node
+			 * that is going down. We were unable to free them,
+			 * and offline_pages() function shoudn't call this
+			 * callback. So, we must fail.
+			 */
+			BUG_ON(atomic_read(&n->nr_slabs));
+
+			s->node[offline_node] = NULL;
+			kmem_cache_free(kmalloc_caches, n);
+		}
+	}
+	up_read(&slub_lock);
+}
+
+static int slab_mem_going_online_callback(void *arg)
+{
+	struct kmem_cache_node *n;
+	struct kmem_cache *s;
+	struct memory_notify *marg = arg;
+	int nid = marg->status_change_nid;
+	int ret = 0;
+
+	/*
+	 * If the node's memory is already available, then kmem_cache_node is
+	 * already created. Nothing to do.
+	 */
+	if (nid < 0)
+		return 0;
+
+	/*
+	 * We are bringing a node online. No memory is availabe yet. We must
+	 * allocate a kmem_cache_node structure in order to bring the node
+	 * online.
+	 */
+	down_read(&slub_lock);
+	list_for_each_entry(s, &slab_caches, list) {
+		/*
+		 * XXX: kmem_cache_alloc_node will fallback to other nodes
+		 *      since memory is not yet available from the node that
+		 *      is brought up.
+		 */
+		n = kmem_cache_alloc(kmalloc_caches, GFP_KERNEL);
+		if (!n) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		init_kmem_cache_node(n);
+		s->node[nid] = n;
+	}
+out:
+	up_read(&slub_lock);
+	return ret;
+}
+
+static int slab_memory_callback(struct notifier_block *self,
+				unsigned long action, void *arg)
+{
+	int ret = 0;
+
+	switch (action) {
+	case MEM_GOING_ONLINE:
+		ret = slab_mem_going_online_callback(arg);
+		break;
+	case MEM_GOING_OFFLINE:
+		ret = slab_mem_going_offline_callback(arg);
+		break;
+	case MEM_OFFLINE:
+	case MEM_CANCEL_ONLINE:
+		slab_mem_offline_callback(arg);
+		break;
+	case MEM_ONLINE:
+	case MEM_CANCEL_OFFLINE:
+		break;
+	}
+
+	ret = notifier_from_errno(ret);
+	return ret;
+}
+
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
 /********************************************************************
  *			Basic setup of slabs
  *******************************************************************/
@@ -2715,6 +2831,8 @@
 		sizeof(struct kmem_cache_node), GFP_KERNEL);
 	kmalloc_caches[0].refcount = -1;
 	caches++;
+
+	hotplug_memory_notifier(slab_memory_callback, 1);
 #endif
 
 	/* Able to allocate the per node structures */
diff --git a/mm/swap.c b/mm/swap.c
index a65eff8..9ac8832 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -5,7 +5,7 @@
  */
 
 /*
- * This file contains the default values for the opereation of the
+ * This file contains the default values for the operation of the
  * Linux VM subsystem. Fine-tuning documentation can be found in
  * Documentation/sysctl/vm.txt.
  * Started 18.12.91
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 2e01af3..af77e17 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -247,7 +247,7 @@
 EXPORT_SYMBOL_GPL(__get_vm_area);
 
 /**
- *	get_vm_area  -  reserve a contingous kernel virtual area
+ *	get_vm_area  -  reserve a contiguous kernel virtual area
  *	@size:		size of the area
  *	@flags:		%VM_IOREMAP for I/O mappings or VM_ALLOC
  *
@@ -303,7 +303,7 @@
 }
 
 /**
- *	remove_vm_area  -  find and remove a contingous kernel virtual area
+ *	remove_vm_area  -  find and remove a continuous kernel virtual area
  *	@addr:		base address
  *
  *	Search for the kernel VM area starting at @addr, and remove it.
@@ -364,7 +364,7 @@
  *	vfree  -  release memory allocated by vmalloc()
  *	@addr:		memory base address
  *
- *	Free the virtually contiguous memory area starting at @addr, as
+ *	Free the virtually continuous memory area starting at @addr, as
  *	obtained from vmalloc(), vmalloc_32() or __vmalloc(). If @addr is
  *	NULL, no operation is performed.
  *
diff --git a/mm/vmscan.c b/mm/vmscan.c
index e147138..e5a9597 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -141,7 +141,7 @@
  * percentages of the lru and ageable caches.  This should balance the seeks
  * generated by these structures.
  *
- * If the vm encounted mapped pages on the LRU it increase the pressure on
+ * If the vm encountered mapped pages on the LRU it increase the pressure on
  * slab to avoid swapping.
  *
  * We do weird things to avoid (scanned*seeks*entries) overflowing 32 bits.
@@ -1282,7 +1282,7 @@
 	 */
 	if (priority < 0)
 		priority = 0;
-	for (i = 0; zones[i] != 0; i++) {
+	for (i = 0; zones[i] != NULL; i++) {
 		struct zone *zone = zones[i];
 
 		if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
diff --git a/net/9p/Kconfig b/net/9p/Kconfig
index eecbf12..bafc50c 100644
--- a/net/9p/Kconfig
+++ b/net/9p/Kconfig
@@ -23,9 +23,16 @@
 	  file descriptors.  TCP/IP is the default transport for 9p,
 	  so if you are going to use 9p, you'll likely want this.
 
+config NET_9P_VIRTIO
+	depends on NET_9P && EXPERIMENTAL && VIRTIO
+	tristate "9P Virtio Transport (Experimental)"
+	help
+	  This builds support for a transports between
+	  guest partitions and a host partition.
+
 config NET_9P_DEBUG
 	bool "Debug information"
 	depends on NET_9P
 	help
-	  Say Y if you want the 9P subsistem to log debug information.
+	  Say Y if you want the 9P subsystem to log debug information.
 
diff --git a/net/9p/Makefile b/net/9p/Makefile
index 5059bc0..d3abb24 100644
--- a/net/9p/Makefile
+++ b/net/9p/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_NET_9P) := 9pnet.o
 obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
+obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
 
 9pnet-objs := \
 	mod.o \
@@ -12,3 +13,6 @@
 
 9pnet_fd-objs := \
 	trans_fd.o \
+
+9pnet_virtio-objs := \
+	trans_virtio.o \
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
new file mode 100644
index 0000000..40b71a2
--- /dev/null
+++ b/net/9p/trans_virtio.c
@@ -0,0 +1,353 @@
+/*
+ * The Guest 9p transport driver
+ *
+ * This is a trivial pipe-based transport driver based on the lguest console
+ * code: we use lguest's DMA mechanism to send bytes out, and register a
+ * DMA buffer to receive bytes in.  It is assumed to be present and available
+ * from the very beginning of boot.
+ *
+ * This may be have been done by just instaniating another HVC console,
+ * but HVC's blocksize of 16 bytes is annoying and painful to performance.
+ *
+ * A more efficient transport could be built based on the virtio block driver
+ * but it requires some changes in the 9p transport model (which are in
+ * progress)
+ *
+ */
+/*
+ *  Copyright (C) 2007 Eric Van Hensbergen, IBM Corporation
+ *
+ *  Based on virtio console driver
+ *  Copyright (C) 2006, 2007 Rusty Russell, IBM Corporation
+ *
+ *  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.
+ *
+ *  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:
+ *  Free Software Foundation
+ *  51 Franklin Street, Fifth Floor
+ *  Boston, MA  02111-1301  USA
+ *
+ */
+
+#include <linux/in.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <linux/ipv6.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/un.h>
+#include <linux/uaccess.h>
+#include <linux/inet.h>
+#include <linux/idr.h>
+#include <linux/file.h>
+#include <net/9p/9p.h>
+#include <linux/parser.h>
+#include <net/9p/transport.h>
+#include <linux/scatterlist.h>
+#include <linux/virtio.h>
+#include <linux/virtio_9p.h>
+
+/* a single mutex to manage channel initialization and attachment */
+static DECLARE_MUTEX(virtio_9p_lock);
+/* global which tracks highest initialized channel */
+static int chan_index;
+
+/* We keep all per-channel information in a structure.
+ * This structure is allocated within the devices dev->mem space.
+ * A pointer to the structure will get put in the transport private.
+ */
+static struct virtio_chan {
+	bool initialized;		/* channel is initialized */
+	bool inuse;			/* channel is in use */
+
+	struct virtqueue *in_vq, *out_vq;
+	struct virtio_device *vdev;
+
+	/* This is our input buffer, and how much data is left in it. */
+	unsigned int in_len;
+	char *in, *inbuf;
+
+	wait_queue_head_t wq;		/* waitq for buffer */
+} channels[MAX_9P_CHAN];
+
+/* How many bytes left in this page. */
+static unsigned int rest_of_page(void *data)
+{
+	return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
+}
+
+static int p9_virtio_write(struct p9_trans *trans, void *buf, int count)
+{
+	struct virtio_chan *chan = (struct virtio_chan *) trans->priv;
+	struct virtqueue *out_vq = chan->out_vq;
+	struct scatterlist sg[1];
+	unsigned int len;
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio write (%d)\n", count);
+
+	/* keep it simple - make sure we don't overflow a page */
+	if (rest_of_page(buf) < count)
+		count = rest_of_page(buf);
+
+	sg_init_one(sg, buf, count);
+
+	/* add_buf wants a token to identify this buffer: we hand it any
+	 * non-NULL pointer, since there's only ever one buffer. */
+	if (out_vq->vq_ops->add_buf(out_vq, sg, 1, 0, (void *)1) == 0) {
+		/* Tell Host to go! */
+		out_vq->vq_ops->kick(out_vq);
+		/* Chill out until it's done with the buffer. */
+		while (!out_vq->vq_ops->get_buf(out_vq, &len))
+			cpu_relax();
+	}
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio wrote (%d)\n", count);
+
+	/* We're expected to return the amount of data we wrote: all of it. */
+	return count;
+}
+
+/* Create a scatter-gather list representing our input buffer and put it in the
+ * queue. */
+static void add_inbuf(struct virtio_chan *chan)
+{
+	struct scatterlist sg[1];
+
+	sg_init_one(sg, chan->inbuf, PAGE_SIZE);
+
+	/* We should always be able to add one buffer to an empty queue. */
+	if (chan->in_vq->vq_ops->add_buf(chan->in_vq, sg, 0, 1, chan->inbuf))
+		BUG();
+	chan->in_vq->vq_ops->kick(chan->in_vq);
+}
+
+static int p9_virtio_read(struct p9_trans *trans, void *buf, int count)
+{
+	struct virtio_chan *chan = (struct virtio_chan *) trans->priv;
+	struct virtqueue *in_vq = chan->in_vq;
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio read (%d)\n", count);
+
+	/* If we don't have an input queue yet, we can't get input. */
+	BUG_ON(!in_vq);
+
+	/* No buffer?  Try to get one. */
+	if (!chan->in_len) {
+		chan->in = in_vq->vq_ops->get_buf(in_vq, &chan->in_len);
+		if (!chan->in)
+			return 0;
+	}
+
+	/* You want more than we have to give?  Well, try wanting less! */
+	if (chan->in_len < count)
+		count = chan->in_len;
+
+	/* Copy across to their buffer and increment offset. */
+	memcpy(buf, chan->in, count);
+	chan->in += count;
+	chan->in_len -= count;
+
+	/* Finished?  Re-register buffer so Host will use it again. */
+	if (chan->in_len == 0)
+		add_inbuf(chan);
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio finished read (%d)\n",
+									count);
+
+	return count;
+}
+
+/* The poll function is used by 9p transports to determine if there
+ * is there is activity available on a particular channel.  In our case
+ * we use it to wait for a callback from the input routines.
+ */
+static unsigned int
+p9_virtio_poll(struct p9_trans *trans, struct poll_table_struct *pt)
+{
+	struct virtio_chan *chan = (struct virtio_chan *)trans->priv;
+	struct virtqueue *in_vq = chan->in_vq;
+	int ret = POLLOUT; /* we can always handle more output */
+
+	poll_wait(NULL, &chan->wq, pt);
+
+	/* No buffer?  Try to get one. */
+	if (!chan->in_len)
+		chan->in = in_vq->vq_ops->get_buf(in_vq, &chan->in_len);
+
+	if (chan->in_len)
+		ret |= POLLIN;
+
+	return ret;
+}
+
+static void p9_virtio_close(struct p9_trans *trans)
+{
+	struct virtio_chan *chan = trans->priv;
+
+	down(&virtio_9p_lock);
+	chan->inuse = false;
+	up(&virtio_9p_lock);
+
+	kfree(trans);
+}
+
+static bool p9_virtio_intr(struct virtqueue *q)
+{
+	struct virtio_chan *chan = q->vdev->priv;
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "9p poll_wakeup: %p\n", &chan->wq);
+	wake_up_interruptible(&chan->wq);
+
+	return true;
+}
+
+static int p9_virtio_probe(struct virtio_device *dev)
+{
+	int err;
+	struct virtio_chan *chan;
+	int index;
+
+	down(&virtio_9p_lock);
+	index = chan_index++;
+	chan = &channels[index];
+	up(&virtio_9p_lock);
+
+	if (chan_index > MAX_9P_CHAN) {
+		printk(KERN_ERR "9p: virtio: Maximum channels exceeded\n");
+		BUG();
+	}
+
+	chan->vdev = dev;
+
+	/* This is the scratch page we use to receive console input */
+	chan->inbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!chan->inbuf) {
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	/* Find the input queue. */
+	dev->priv = chan;
+	chan->in_vq = dev->config->find_vq(dev, p9_virtio_intr);
+	if (IS_ERR(chan->in_vq)) {
+		err = PTR_ERR(chan->in_vq);
+		goto free;
+	}
+
+	chan->out_vq = dev->config->find_vq(dev, NULL);
+	if (IS_ERR(chan->out_vq)) {
+		err = PTR_ERR(chan->out_vq);
+		goto free_in_vq;
+	}
+
+	init_waitqueue_head(&chan->wq);
+
+	/* Register the input buffer the first time. */
+	add_inbuf(chan);
+	chan->inuse = false;
+	chan->initialized = true;
+
+	return 0;
+
+free_in_vq:
+	dev->config->del_vq(chan->in_vq);
+free:
+	kfree(chan->inbuf);
+fail:
+	down(&virtio_9p_lock);
+	chan_index--;
+	up(&virtio_9p_lock);
+	return err;
+}
+
+/* This sets up a transport channel for 9p communication.  Right now
+ * we only match the first available channel, but eventually we couldlook up
+ * alternate channels by matching devname versus a virtio_config entry.
+ * We use a simple reference count mechanism to ensure that only a single
+ * mount has a channel open at a time. */
+static struct p9_trans *p9_virtio_create(const char *devname, char *args)
+{
+	struct p9_trans *trans;
+	int index = 0;
+	struct virtio_chan *chan = channels;
+
+	down(&virtio_9p_lock);
+	while (index < MAX_9P_CHAN) {
+		if (chan->initialized && !chan->inuse) {
+			chan->inuse = true;
+			break;
+		} else {
+			index++;
+			chan = &channels[index];
+		}
+	}
+	up(&virtio_9p_lock);
+
+	if (index >= MAX_9P_CHAN) {
+		printk(KERN_ERR "9p: virtio: couldn't find a free channel\n");
+		return NULL;
+	}
+
+	trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
+	if (!trans) {
+		printk(KERN_ERR "9p: couldn't allocate transport\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	trans->write = p9_virtio_write;
+	trans->read = p9_virtio_read;
+	trans->close = p9_virtio_close;
+	trans->poll = p9_virtio_poll;
+	trans->priv = chan;
+
+	return trans;
+}
+
+#define VIRTIO_ID_9P 9
+
+static struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_9P, VIRTIO_DEV_ANY_ID },
+	{ 0 },
+};
+
+/* The standard "struct lguest_driver": */
+static struct virtio_driver p9_virtio_drv = {
+	.driver.name = 	KBUILD_MODNAME,
+	.driver.owner = THIS_MODULE,
+	.id_table =	id_table,
+	.probe = 	p9_virtio_probe,
+};
+
+static struct p9_trans_module p9_virtio_trans = {
+	.name = "virtio",
+	.create = p9_virtio_create,
+	.maxsize = PAGE_SIZE,
+	.def = 0,
+};
+
+/* The standard init function */
+static int __init p9_virtio_init(void)
+{
+	int count;
+
+	for (count = 0; count < MAX_9P_CHAN; count++)
+		channels[count].initialized = false;
+
+	v9fs_register_trans(&p9_virtio_trans);
+	return register_virtio_driver(&p9_virtio_drv);
+}
+
+module_init(p9_virtio_init);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
+MODULE_DESCRIPTION("Virtio 9p Transport");
+MODULE_LICENSE("GPL");
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index c742d37..ba6428f 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -24,16 +24,6 @@
 
 #include "common.h"
 
-/*
- * Define this to use a version of the code which interacts with the higher
- * layers in a more intellegent way, by always reserving enough space for
- * our header at the begining of the packet.  However, there may still be
- * some problems with programs like tcpdump.  In 2.5 we'll sort out what
- * we need to do to get this perfect.  For now we just will copy the packet
- * if we need space for the header
- */
-/* #define FASTER_VERSION */
-
 #ifdef SKB_DEBUG
 static void skb_debug(const struct sk_buff *skb)
 {
@@ -69,9 +59,7 @@
 #ifdef CONFIG_ATM_BR2684_IPFILTER
 	struct br2684_filter filter;
 #endif /* CONFIG_ATM_BR2684_IPFILTER */
-#ifndef FASTER_VERSION
 	unsigned copies_needed, copies_failed;
-#endif /* FASTER_VERSION */
 };
 
 struct br2684_dev {
@@ -147,13 +135,6 @@
 	struct br2684_vcc *brvcc)
 {
 	struct atm_vcc *atmvcc;
-#ifdef FASTER_VERSION
-	if (brvcc->encaps == e_llc)
-		memcpy(skb_push(skb, 8), llc_oui_pid_pad, 8);
-	/* last 2 bytes of llc_oui_pid_pad are managed by header routines;
-	   yes, you got it: 8 + 2 = sizeof(llc_oui_pid_pad)
-	 */
-#else
 	int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2;
 	if (skb_headroom(skb) < minheadroom) {
 		struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom);
@@ -170,7 +151,6 @@
 		skb_copy_to_linear_data(skb, llc_oui_pid_pad, 10);
 	else
 		memset(skb->data, 0, 2);
-#endif /* FASTER_VERSION */
 	skb_debug(skb);
 
 	ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
@@ -237,87 +217,6 @@
 	return &BRPRIV(dev)->stats;
 }
 
-#ifdef FASTER_VERSION
-/*
- * These mirror eth_header and eth_header_cache.  They are not usually
- * exported for use in modules, so we grab them from net_device
- * after ether_setup() is done with it.  Bit of a hack.
- */
-static int (*my_eth_header)(struct sk_buff *, struct net_device *,
-	unsigned short, void *, void *, unsigned);
-static int (*my_eth_header_cache)(struct neighbour *, struct hh_cache *);
-
-static int
-br2684_header(struct sk_buff *skb, struct net_device *dev,
-	      unsigned short type, void *daddr, void *saddr, unsigned len)
-{
-	u16 *pad_before_eth;
-	int t = my_eth_header(skb, dev, type, daddr, saddr, len);
-	if (t > 0) {
-		pad_before_eth = (u16 *) skb_push(skb, 2);
-		*pad_before_eth = 0;
-		return dev->hard_header_len;	/* or return 16; ? */
-	} else
-		return t;
-}
-
-static int
-br2684_header_cache(struct neighbour *neigh, struct hh_cache *hh)
-{
-/* hh_data is 16 bytes long. if encaps is ether-llc we need 24, so
-xmit will add the additional header part in that case */
-	u16 *pad_before_eth = (u16 *)(hh->hh_data);
-	int t = my_eth_header_cache(neigh, hh);
-	DPRINTK("br2684_header_cache, neigh=%p, hh_cache=%p\n", neigh, hh);
-	if (t < 0)
-		return t;
-	else {
-		*pad_before_eth = 0;
-		hh->hh_len = PADLEN + ETH_HLEN;
-	}
-	return 0;
-}
-
-/*
- * This is similar to eth_type_trans, which cannot be used because of
- * our dev->hard_header_len
- */
-static inline __be16 br_type_trans(struct sk_buff *skb, struct net_device *dev)
-{
-	struct ethhdr *eth;
-	unsigned char *rawp;
-	eth = eth_hdr(skb);
-
-	if (is_multicast_ether_addr(eth->h_dest)) {
-		if (!compare_ether_addr(eth->h_dest, dev->broadcast))
-			skb->pkt_type = PACKET_BROADCAST;
-		else
-			skb->pkt_type = PACKET_MULTICAST;
-	}
-
-	else if (compare_ether_addr(eth->h_dest, dev->dev_addr))
-		skb->pkt_type = PACKET_OTHERHOST;
-
-	if (ntohs(eth->h_proto) >= 1536)
-		return eth->h_proto;
-
-	rawp = skb->data;
-
-	/*
-	 * This is a magic hack to spot IPX packets. Older Novell breaks
-	 * the protocol design and runs IPX over 802.3 without an 802.2 LLC
-	 * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
-	 * won't work for fault tolerant netware but does for the rest.
-	 */
-	if (*(unsigned short *) rawp == 0xFFFF)
-		return htons(ETH_P_802_3);
-
-	/*
-	 * Real 802.2 LLC
-	 */
-	return htons(ETH_P_802_2);
-}
-#endif /* FASTER_VERSION */
 
 /*
  * We remember when the MAC gets set, so we don't override it later with
@@ -448,17 +347,8 @@
 		return;
 	}
 
-#ifdef FASTER_VERSION
-	/* FIXME: tcpdump shows that pointer to mac header is 2 bytes earlier,
-	   than should be. What else should I set? */
-	skb_pull(skb, plen);
-	skb_set_mac_header(skb, -ETH_HLEN);
-	skb->pkt_type = PACKET_HOST;
-	skb->protocol = br_type_trans(skb, net_dev);
-#else
 	skb_pull(skb, plen - ETH_HLEN);
 	skb->protocol = eth_type_trans(skb, net_dev);
-#endif /* FASTER_VERSION */
 #ifdef CONFIG_ATM_BR2684_IPFILTER
 	if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) {
 		brdev->stats.rx_dropped++;
@@ -584,13 +474,6 @@
 	ether_setup(netdev);
 	brdev->net_dev = netdev;
 
-#ifdef FASTER_VERSION
-	my_eth_header = netdev->hard_header;
-	netdev->hard_header = br2684_header;
-	my_eth_header_cache = netdev->hard_header_cache;
-	netdev->hard_header_cache = br2684_header_cache;
-	netdev->hard_header_len = sizeof(llc_oui_pid_pad) + ETH_HLEN;	/* 10 + 14 */
-#endif
 	my_eth_mac_addr = netdev->set_mac_address;
 	netdev->set_mac_address = br2684_mac_addr;
 	netdev->hard_start_xmit = br2684_start_xmit;
@@ -719,16 +602,12 @@
 
 	list_for_each_entry(brvcc, &brdev->brvccs, brvccs) {
 		seq_printf(seq, "  vcc %d.%d.%d: encaps=%s"
-#ifndef FASTER_VERSION
 				    ", failed copies %u/%u"
-#endif /* FASTER_VERSION */
 				    "\n", brvcc->atmvcc->dev->number,
 				    brvcc->atmvcc->vpi, brvcc->atmvcc->vci,
 				    (brvcc->encaps == e_llc) ? "LLC" : "VC"
-#ifndef FASTER_VERSION
 				    , brvcc->copies_failed
 				    , brvcc->copies_needed
-#endif /* FASTER_VERSION */
 				    );
 #ifdef CONFIG_ATM_BR2684_IPFILTER
 #define b1(var, byte)	((u8 *) &brvcc->filter.var)[byte]
diff --git a/net/ax25/ax25_ds_in.c b/net/ax25/ax25_ds_in.c
index e37d217..8273b12 100644
--- a/net/ax25/ax25_ds_in.c
+++ b/net/ax25/ax25_ds_in.c
@@ -75,7 +75,7 @@
 		}
 		ax25_dama_on(ax25);
 
-		/* according to DK4EG´s spec we are required to
+		/* according to DK4EG's spec we are required to
 		 * send a RR RESPONSE FINAL NR=0.
 		 */
 
diff --git a/net/ax25/ax25_ds_subr.c b/net/ax25/ax25_ds_subr.c
index a49773f..b5e5978 100644
--- a/net/ax25/ax25_ds_subr.c
+++ b/net/ax25/ax25_ds_subr.c
@@ -41,7 +41,7 @@
 	ax25_cb *ax25o;
 	struct hlist_node *node;
 
-	/* Please note that neither DK4EG´s nor DG2FEF´s
+	/* Please note that neither DK4EG's nor DG2FEF's
 	 * DAMA spec mention the following behaviour as seen
 	 * with TheFirmware:
 	 *
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 1f78c3e..347e935 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -2,7 +2,7 @@
    BNEP implementation for Linux Bluetooth stack (BlueZ).
    Copyright (C) 2001-2002 Inventel Systemes
    Written 2001-2002 by
-	Clément Moreau <clement.moreau@inventel.fr>
+	Clément Moreau <clement.moreau@inventel.fr>
 	David Libault  <david.libault@inventel.fr>
 
    Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index 9092816..95e3837 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -2,7 +2,7 @@
    BNEP implementation for Linux Bluetooth stack (BlueZ).
    Copyright (C) 2001-2002 Inventel Systemes
    Written 2001-2002 by
-	Clément Moreau <clement.moreau@inventel.fr>
+	Clément Moreau <clement.moreau@inventel.fr>
 	David Libault  <david.libault@inventel.fr>
 
    Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 5fdfc9a6..9483320 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -78,11 +78,11 @@
 
 	cp.pkt_type = cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
 	if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
-		cp.role_switch	= 0x01;
+		cp.role_switch = 0x01;
 	else
-		cp.role_switch	= 0x00;
+		cp.role_switch = 0x00;
 
-	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp);
+	hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp);
 }
 
 static void hci_acl_connect_cancel(struct hci_conn *conn)
@@ -95,8 +95,7 @@
 		return;
 
 	bacpy(&cp.bdaddr, &conn->dst);
-	hci_send_cmd(conn->hdev, OGF_LINK_CTL,
-				OCF_CREATE_CONN_CANCEL, sizeof(cp), &cp);
+	hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
 }
 
 void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
@@ -109,8 +108,7 @@
 
 	cp.handle = cpu_to_le16(conn->handle);
 	cp.reason = reason;
-	hci_send_cmd(conn->hdev, OGF_LINK_CTL,
-				OCF_DISCONNECT, sizeof(cp), &cp);
+	hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
 }
 
 void hci_add_sco(struct hci_conn *conn, __u16 handle)
@@ -126,7 +124,29 @@
 	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);
+	hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
+}
+
+void hci_setup_sync(struct hci_conn *conn, __u16 handle)
+{
+	struct hci_dev *hdev = conn->hdev;
+	struct hci_cp_setup_sync_conn cp;
+
+	BT_DBG("%p", conn);
+
+	conn->state = BT_CONNECT;
+	conn->out = 1;
+
+	cp.handle   = cpu_to_le16(handle);
+	cp.pkt_type = cpu_to_le16(hdev->esco_type);
+
+	cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
+	cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
+	cp.max_latency    = cpu_to_le16(0xffff);
+	cp.voice_setting  = cpu_to_le16(hdev->voice_setting);
+	cp.retrans_effort = 0xff;
+
+	hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
 }
 
 static void hci_conn_timeout(unsigned long arg)
@@ -143,7 +163,10 @@
 
 	switch (conn->state) {
 	case BT_CONNECT:
-		hci_acl_connect_cancel(conn);
+		if (conn->type == ACL_LINK)
+			hci_acl_connect_cancel(conn);
+		else
+			hci_acl_disconn(conn, 0x13);
 		break;
 	case BT_CONNECTED:
 		hci_acl_disconn(conn, 0x13);
@@ -330,8 +353,12 @@
 	hci_conn_hold(sco);
 
 	if (acl->state == BT_CONNECTED &&
-			(sco->state == BT_OPEN || sco->state == BT_CLOSED))
-		hci_add_sco(sco, acl->handle);
+			(sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
+		if (lmp_esco_capable(hdev))
+			hci_setup_sync(sco, acl->handle);
+		else
+			hci_add_sco(sco, acl->handle);
+	}
 
 	return sco;
 }
@@ -348,7 +375,7 @@
 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
 		struct hci_cp_auth_requested cp;
 		cp.handle = cpu_to_le16(conn->handle);
-		hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_AUTH_REQUESTED, sizeof(cp), &cp);
+		hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
 	}
 	return 0;
 }
@@ -369,7 +396,7 @@
 		struct hci_cp_set_conn_encrypt cp;
 		cp.handle  = cpu_to_le16(conn->handle);
 		cp.encrypt = 1;
-		hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp);
+		hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp);
 	}
 	return 0;
 }
@@ -383,7 +410,7 @@
 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
 		struct hci_cp_change_conn_link_key cp;
 		cp.handle = cpu_to_le16(conn->handle);
-		hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp);
+		hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp);
 	}
 	return 0;
 }
@@ -401,7 +428,7 @@
 		struct hci_cp_switch_role cp;
 		bacpy(&cp.bdaddr, &conn->dst);
 		cp.role = role;
-		hci_send_cmd(conn->hdev, OGF_LINK_POLICY, OCF_SWITCH_ROLE, sizeof(cp), &cp);
+		hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp);
 	}
 	return 0;
 }
@@ -423,8 +450,7 @@
 	if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
 		struct hci_cp_exit_sniff_mode cp;
 		cp.handle = cpu_to_le16(conn->handle);
-		hci_send_cmd(hdev, OGF_LINK_POLICY,
-				OCF_EXIT_SNIFF_MODE, sizeof(cp), &cp);
+		hci_send_cmd(hdev, HCI_OP_EXIT_SNIFF_MODE, sizeof(cp), &cp);
 	}
 
 timer:
@@ -455,8 +481,7 @@
 		cp.max_latency        = cpu_to_le16(0);
 		cp.min_remote_timeout = cpu_to_le16(0);
 		cp.min_local_timeout  = cpu_to_le16(0);
-		hci_send_cmd(hdev, OGF_LINK_POLICY,
-				OCF_SNIFF_SUBRATE, sizeof(cp), &cp);
+		hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
 	}
 
 	if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
@@ -466,8 +491,7 @@
 		cp.min_interval = cpu_to_le16(hdev->sniff_min_interval);
 		cp.attempt      = cpu_to_le16(4);
 		cp.timeout      = cpu_to_le16(1);
-		hci_send_cmd(hdev, OGF_LINK_POLICY,
-				OCF_SNIFF_MODE, sizeof(cp), &cp);
+		hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp);
 	}
 }
 
@@ -493,6 +517,22 @@
 	}
 }
 
+/* Check pending connect attempts */
+void hci_conn_check_pending(struct hci_dev *hdev)
+{
+	struct hci_conn *conn;
+
+	BT_DBG("hdev %s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
+	if (conn)
+		hci_acl_connect(conn);
+
+	hci_dev_unlock(hdev);
+}
+
 int hci_get_conn_list(void __user *arg)
 {
 	struct hci_conn_list_req req, *cl;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 18e3afc..372b0d3 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -176,7 +176,7 @@
 	BT_DBG("%s %ld", hdev->name, opt);
 
 	/* Reset device */
-	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
+	hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
 }
 
 static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
@@ -202,16 +202,16 @@
 
 	/* Reset */
 	if (test_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks))
-			hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
+			hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
 
 	/* Read Local Supported Features */
-	hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
+	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
 
 	/* Read Local Version */
-	hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION, 0, NULL);
+	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
 
 	/* Read Buffer Size (ACL mtu, max pkt, etc.) */
-	hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
+	hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
 
 #if 0
 	/* Host buffer size */
@@ -221,29 +221,35 @@
 		cp.sco_mtu = HCI_MAX_SCO_SIZE;
 		cp.acl_max_pkt = cpu_to_le16(0xffff);
 		cp.sco_max_pkt = cpu_to_le16(0xffff);
-		hci_send_cmd(hdev, OGF_HOST_CTL, OCF_HOST_BUFFER_SIZE, sizeof(cp), &cp);
+		hci_send_cmd(hdev, HCI_OP_HOST_BUFFER_SIZE, sizeof(cp), &cp);
 	}
 #endif
 
 	/* Read BD Address */
-	hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
+	hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
+
+	/* Read Class of Device */
+	hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
+
+	/* Read Local Name */
+	hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
 
 	/* Read Voice Setting */
-	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_READ_VOICE_SETTING, 0, NULL);
+	hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
 
 	/* Optional initialization */
 
 	/* Clear Event Filters */
 	flt_type = HCI_FLT_CLEAR_ALL;
-	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &flt_type);
+	hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
 
 	/* Page timeout ~20 secs */
 	param = cpu_to_le16(0x8000);
-	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_PG_TIMEOUT, 2, &param);
+	hci_send_cmd(hdev, HCI_OP_WRITE_PG_TIMEOUT, 2, &param);
 
 	/* Connection accept timeout ~20 secs */
 	param = cpu_to_le16(0x7d00);
-	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_CA_TIMEOUT, 2, &param);
+	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
 }
 
 static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
@@ -253,7 +259,7 @@
 	BT_DBG("%s %x", hdev->name, scan);
 
 	/* Inquiry and Page scans */
-	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &scan);
+	hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
 }
 
 static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
@@ -263,7 +269,7 @@
 	BT_DBG("%s %x", hdev->name, auth);
 
 	/* Authentication */
-	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &auth);
+	hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
 }
 
 static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
@@ -273,7 +279,7 @@
 	BT_DBG("%s %x", hdev->name, encrypt);
 
 	/* Authentication */
-	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE, 1, &encrypt);
+	hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
 }
 
 /* Get HCI device by index.
@@ -384,7 +390,7 @@
 	memcpy(&cp.lap, &ir->lap, 3);
 	cp.length  = ir->length;
 	cp.num_rsp = ir->num_rsp;
-	hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, sizeof(cp), &cp);
+	hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
 }
 
 int hci_inquiry(void __user *arg)
@@ -1111,13 +1117,13 @@
 }
 
 /* Send HCI command */
-int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param)
+int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
 {
 	int len = HCI_COMMAND_HDR_SIZE + plen;
 	struct hci_command_hdr *hdr;
 	struct sk_buff *skb;
 
-	BT_DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
+	BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
 
 	skb = bt_skb_alloc(len, GFP_ATOMIC);
 	if (!skb) {
@@ -1126,7 +1132,7 @@
 	}
 
 	hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
-	hdr->opcode = cpu_to_le16(hci_opcode_pack(ogf, ocf));
+	hdr->opcode = cpu_to_le16(opcode);
 	hdr->plen   = plen;
 
 	if (plen)
@@ -1143,7 +1149,7 @@
 }
 
 /* Get data from the previously sent command */
-void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
 {
 	struct hci_command_hdr *hdr;
 
@@ -1152,10 +1158,10 @@
 
 	hdr = (void *) hdev->sent_cmd->data;
 
-	if (hdr->opcode != cpu_to_le16(hci_opcode_pack(ogf, ocf)))
+	if (hdr->opcode != cpu_to_le16(opcode))
 		return NULL;
 
-	BT_DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
+	BT_DBG("%s opcode 0x%x", hdev->name, opcode);
 
 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
 }
@@ -1355,6 +1361,26 @@
 	}
 }
 
+static inline void hci_sched_esco(struct hci_dev *hdev)
+{
+	struct hci_conn *conn;
+	struct sk_buff *skb;
+	int quote;
+
+	BT_DBG("%s", hdev->name);
+
+	while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
+		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+			BT_DBG("skb %p len %d", skb, skb->len);
+			hci_send_frame(skb);
+
+			conn->sent++;
+			if (conn->sent == ~0)
+				conn->sent = 0;
+		}
+	}
+}
+
 static void hci_tx_task(unsigned long arg)
 {
 	struct hci_dev *hdev = (struct hci_dev *) arg;
@@ -1370,6 +1396,8 @@
 
 	hci_sched_sco(hdev);
 
+	hci_sched_esco(hdev);
+
 	/* Send next queued raw (unknown type) packet */
 	while ((skb = skb_dequeue(&hdev->raw_q)))
 		hci_send_frame(skb);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 4baea1e..46df2e4 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -52,213 +52,273 @@
 
 /* Handle HCI Event packets */
 
-/* Command Complete OGF LINK_CTL  */
-static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	__u8 status;
-	struct hci_conn *pend;
+	__u8 status = *((__u8 *) skb->data);
 
-	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+	BT_DBG("%s status 0x%x", hdev->name, status);
 
-	switch (ocf) {
-	case OCF_INQUIRY_CANCEL:
-	case OCF_EXIT_PERIODIC_INQ:
-		status = *((__u8 *) skb->data);
+	if (status)
+		return;
 
-		if (status) {
-			BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status);
-		} else {
-			clear_bit(HCI_INQUIRY, &hdev->flags);
-			hci_req_complete(hdev, status);
-		}
+	clear_bit(HCI_INQUIRY, &hdev->flags);
 
-		hci_dev_lock(hdev);
+	hci_req_complete(hdev, status);
 
-		pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
-		if (pend)
-			hci_acl_connect(pend);
-
-		hci_dev_unlock(hdev);
-
-		break;
-
-	default:
-		BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
-		break;
-	}
+	hci_conn_check_pending(hdev);
 }
 
-/* Command Complete OGF LINK_POLICY  */
-static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
 {
+	__u8 status = *((__u8 *) skb->data);
+
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	if (status)
+		return;
+
+	clear_bit(HCI_INQUIRY, &hdev->flags);
+
+	hci_conn_check_pending(hdev);
+}
+
+static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	BT_DBG("%s", hdev->name);
+}
+
+static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_role_discovery *rp = (void *) skb->data;
 	struct hci_conn *conn;
-	struct hci_rp_role_discovery *rd;
-	struct hci_rp_write_link_policy *lp;
-	void *sent;
 
-	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
 
-	switch (ocf) {
-	case OCF_ROLE_DISCOVERY:
-		rd = (void *) skb->data;
+	if (rp->status)
+		return;
 
-		if (rd->status)
-			break;
+	hci_dev_lock(hdev);
 
-		hci_dev_lock(hdev);
-
-		conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
-		if (conn) {
-			if (rd->role)
-				conn->link_mode &= ~HCI_LM_MASTER;
-			else
-				conn->link_mode |= HCI_LM_MASTER;
-		}
-
-		hci_dev_unlock(hdev);
-		break;
-
-	case OCF_WRITE_LINK_POLICY:
-		sent = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY);
-		if (!sent)
-			break;
-
-		lp = (struct hci_rp_write_link_policy *) skb->data;
-
-		if (lp->status)
-			break;
-
-		hci_dev_lock(hdev);
-
-		conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(lp->handle));
-		if (conn) {
-			__le16 policy = get_unaligned((__le16 *) (sent + 2));
-			conn->link_policy = __le16_to_cpu(policy);
-		}
-
-		hci_dev_unlock(hdev);
-		break;
-
-	default:
-		BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x",
-				hdev->name, ocf);
-		break;
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
+	if (conn) {
+		if (rp->role)
+			conn->link_mode &= ~HCI_LM_MASTER;
+		else
+			conn->link_mode |= HCI_LM_MASTER;
 	}
+
+	hci_dev_unlock(hdev);
 }
 
-/* Command Complete OGF HOST_CTL  */
-static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	__u8 status, param;
+	struct hci_rp_write_link_policy *rp = (void *) skb->data;
+	struct hci_conn *conn;
+	void *sent;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
+	if (!sent)
+		return;
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
+	if (conn) {
+		__le16 policy = get_unaligned((__le16 *) (sent + 2));
+		conn->link_policy = __le16_to_cpu(policy);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
+static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	hci_req_complete(hdev, status);
+}
+
+static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+	void *sent;
+
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
+	if (!sent)
+		return;
+
+	if (!status)
+		memcpy(hdev->dev_name, sent, 248);
+}
+
+static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_read_local_name *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	memcpy(hdev->dev_name, rp->name, 248);
+}
+
+static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+	void *sent;
+
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
+	if (!sent)
+		return;
+
+	if (!status) {
+		__u8 param = *((__u8 *) sent);
+
+		if (param == AUTH_ENABLED)
+			set_bit(HCI_AUTH, &hdev->flags);
+		else
+			clear_bit(HCI_AUTH, &hdev->flags);
+	}
+
+	hci_req_complete(hdev, status);
+}
+
+static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+	void *sent;
+
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
+	if (!sent)
+		return;
+
+	if (!status) {
+		__u8 param = *((__u8 *) sent);
+
+		if (param)
+			set_bit(HCI_ENCRYPT, &hdev->flags);
+		else
+			clear_bit(HCI_ENCRYPT, &hdev->flags);
+	}
+
+	hci_req_complete(hdev, status);
+}
+
+static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+	void *sent;
+
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
+	if (!sent)
+		return;
+
+	if (!status) {
+		__u8 param = *((__u8 *) sent);
+
+		clear_bit(HCI_PSCAN, &hdev->flags);
+		clear_bit(HCI_ISCAN, &hdev->flags);
+
+		if (param & SCAN_INQUIRY)
+			set_bit(HCI_ISCAN, &hdev->flags);
+
+		if (param & SCAN_PAGE)
+			set_bit(HCI_PSCAN, &hdev->flags);
+	}
+
+	hci_req_complete(hdev, status);
+}
+
+static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	memcpy(hdev->dev_class, rp->dev_class, 3);
+
+	BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
+		hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
+}
+
+static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+	void *sent;
+
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
+	if (!sent)
+		return;
+
+	if (!status)
+		memcpy(hdev->dev_class, sent, 3);
+}
+
+static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_read_voice_setting *rp = (void *) skb->data;
 	__u16 setting;
-	struct hci_rp_read_voice_setting *vs;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	setting = __le16_to_cpu(rp->voice_setting);
+
+	if (hdev->voice_setting == setting )
+		return;
+
+	hdev->voice_setting = setting;
+
+	BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
+
+	if (hdev->notify) {
+		tasklet_disable(&hdev->tx_task);
+		hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
+		tasklet_enable(&hdev->tx_task);
+	}
+}
+
+static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
 	void *sent;
 
-	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+	BT_DBG("%s status 0x%x", hdev->name, status);
 
-	switch (ocf) {
-	case OCF_RESET:
-		status = *((__u8 *) skb->data);
-		hci_req_complete(hdev, status);
-		break;
+	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
+	if (!sent)
+		return;
 
-	case OCF_SET_EVENT_FLT:
-		status = *((__u8 *) skb->data);
-		if (status) {
-			BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
-		} else {
-			BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name);
-		}
-		break;
+	if (!status) {
+		__u16 setting = __le16_to_cpu(get_unaligned((__le16 *) sent));
 
-	case OCF_WRITE_AUTH_ENABLE:
-		sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE);
-		if (!sent)
-			break;
-
-		status = *((__u8 *) skb->data);
-		param  = *((__u8 *) sent);
-
-		if (!status) {
-			if (param == AUTH_ENABLED)
-				set_bit(HCI_AUTH, &hdev->flags);
-			else
-				clear_bit(HCI_AUTH, &hdev->flags);
-		}
-		hci_req_complete(hdev, status);
-		break;
-
-	case OCF_WRITE_ENCRYPT_MODE:
-		sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE);
-		if (!sent)
-			break;
-
-		status = *((__u8 *) skb->data);
-		param  = *((__u8 *) sent);
-
-		if (!status) {
-			if (param)
-				set_bit(HCI_ENCRYPT, &hdev->flags);
-			else
-				clear_bit(HCI_ENCRYPT, &hdev->flags);
-		}
-		hci_req_complete(hdev, status);
-		break;
-
-	case OCF_WRITE_CA_TIMEOUT:
-		status = *((__u8 *) skb->data);
-		if (status) {
-			BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
-		} else {
-			BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
-		}
-		break;
-
-	case OCF_WRITE_PG_TIMEOUT:
-		status = *((__u8 *) skb->data);
-		if (status) {
-			BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
-		} else {
-			BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
-		}
-		break;
-
-	case OCF_WRITE_SCAN_ENABLE:
-		sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
-		if (!sent)
-			break;
-
-		status = *((__u8 *) skb->data);
-		param  = *((__u8 *) sent);
-
-		BT_DBG("param 0x%x", param);
-
-		if (!status) {
-			clear_bit(HCI_PSCAN, &hdev->flags);
-			clear_bit(HCI_ISCAN, &hdev->flags);
-			if (param & SCAN_INQUIRY)
-				set_bit(HCI_ISCAN, &hdev->flags);
-
-			if (param & SCAN_PAGE)
-				set_bit(HCI_PSCAN, &hdev->flags);
-		}
-		hci_req_complete(hdev, status);
-		break;
-
-	case OCF_READ_VOICE_SETTING:
-		vs = (struct hci_rp_read_voice_setting *) skb->data;
-
-		if (vs->status) {
-			BT_DBG("%s READ_VOICE_SETTING failed %d", hdev->name, vs->status);
-			break;
-		}
-
-		setting = __le16_to_cpu(vs->voice_setting);
-
-		if (hdev->voice_setting != setting ) {
+		if (hdev->voice_setting != setting) {
 			hdev->voice_setting = setting;
 
-			BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
+			BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
 
 			if (hdev->notify) {
 				tasklet_disable(&hdev->tx_task);
@@ -266,164 +326,153 @@
 				tasklet_enable(&hdev->tx_task);
 			}
 		}
-		break;
-
-	case OCF_WRITE_VOICE_SETTING:
-		sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING);
-		if (!sent)
-			break;
-
-		status = *((__u8 *) skb->data);
-		setting = __le16_to_cpu(get_unaligned((__le16 *) sent));
-
-		if (!status && hdev->voice_setting != setting) {
-			hdev->voice_setting = setting;
-
-			BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
-
-			if (hdev->notify) {
-				tasklet_disable(&hdev->tx_task);
-				hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
-				tasklet_enable(&hdev->tx_task);
-			}
-		}
-		hci_req_complete(hdev, status);
-		break;
-
-	case OCF_HOST_BUFFER_SIZE:
-		status = *((__u8 *) skb->data);
-		if (status) {
-			BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
-			hci_req_complete(hdev, status);
-		}
-		break;
-
-	default:
-		BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
-		break;
 	}
 }
 
-/* Command Complete OGF INFO_PARAM  */
-static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_rp_read_loc_version *lv;
-	struct hci_rp_read_local_features *lf;
-	struct hci_rp_read_buffer_size *bs;
-	struct hci_rp_read_bd_addr *ba;
+	__u8 status = *((__u8 *) skb->data);
 
-	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+	BT_DBG("%s status 0x%x", hdev->name, status);
 
-	switch (ocf) {
-	case OCF_READ_LOCAL_VERSION:
-		lv = (struct hci_rp_read_loc_version *) skb->data;
-
-		if (lv->status) {
-			BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status);
-			break;
-		}
-
-		hdev->hci_ver = lv->hci_ver;
-		hdev->hci_rev = btohs(lv->hci_rev);
-		hdev->manufacturer = btohs(lv->manufacturer);
-
-		BT_DBG("%s: manufacturer %d hci_ver %d hci_rev %d", hdev->name,
-				hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
-
-		break;
-
-	case OCF_READ_LOCAL_FEATURES:
-		lf = (struct hci_rp_read_local_features *) skb->data;
-
-		if (lf->status) {
-			BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
-			break;
-		}
-
-		memcpy(hdev->features, lf->features, sizeof(hdev->features));
-
-		/* Adjust default settings according to features
-		 * supported by device. */
-		if (hdev->features[0] & LMP_3SLOT)
-			hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
-
-		if (hdev->features[0] & LMP_5SLOT)
-			hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
-
-		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);
-			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]);
-
-		break;
-
-	case OCF_READ_BUFFER_SIZE:
-		bs = (struct hci_rp_read_buffer_size *) skb->data;
-
-		if (bs->status) {
-			BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
-			hci_req_complete(hdev, bs->status);
-			break;
-		}
-
-		hdev->acl_mtu  = __le16_to_cpu(bs->acl_mtu);
-		hdev->sco_mtu  = bs->sco_mtu;
-		hdev->acl_pkts = __le16_to_cpu(bs->acl_max_pkt);
-		hdev->sco_pkts = __le16_to_cpu(bs->sco_max_pkt);
-
-		if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
-			hdev->sco_mtu  = 64;
-			hdev->sco_pkts = 8;
-		}
-
-		hdev->acl_cnt = hdev->acl_pkts;
-		hdev->sco_cnt = hdev->sco_pkts;
-
-		BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
-			hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
-		break;
-
-	case OCF_READ_BD_ADDR:
-		ba = (struct hci_rp_read_bd_addr *) skb->data;
-
-		if (!ba->status) {
-			bacpy(&hdev->bdaddr, &ba->bdaddr);
-		} else {
-			BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
-		}
-
-		hci_req_complete(hdev, ba->status);
-		break;
-
-	default:
-		BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-		break;
-	}
+	hci_req_complete(hdev, status);
 }
 
-/* Command Status OGF LINK_CTL  */
+static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_read_local_version *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	hdev->hci_ver = rp->hci_ver;
+	hdev->hci_rev = btohs(rp->hci_rev);
+	hdev->manufacturer = btohs(rp->manufacturer);
+
+	BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
+					hdev->manufacturer,
+					hdev->hci_ver, hdev->hci_rev);
+}
+
+static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_read_local_commands *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
+}
+
+static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_read_local_features *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	memcpy(hdev->features, rp->features, 8);
+
+	/* Adjust default settings according to features
+	 * supported by device. */
+
+	if (hdev->features[0] & LMP_3SLOT)
+		hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
+
+	if (hdev->features[0] & LMP_5SLOT)
+		hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
+
+	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);
+		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%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
+					hdev->features[0], hdev->features[1],
+					hdev->features[2], hdev->features[3],
+					hdev->features[4], hdev->features[5],
+					hdev->features[6], hdev->features[7]);
+}
+
+static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_read_buffer_size *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (rp->status)
+		return;
+
+	hdev->acl_mtu  = __le16_to_cpu(rp->acl_mtu);
+	hdev->sco_mtu  = rp->sco_mtu;
+	hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
+	hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
+
+	if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
+		hdev->sco_mtu  = 64;
+		hdev->sco_pkts = 8;
+	}
+
+	hdev->acl_cnt = hdev->acl_pkts;
+	hdev->sco_cnt = hdev->sco_pkts;
+
+	BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
+					hdev->acl_mtu, hdev->acl_pkts,
+					hdev->sco_mtu, hdev->sco_pkts);
+}
+
+static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_rp_read_bd_addr *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	if (!rp->status)
+		bacpy(&hdev->bdaddr, &rp->bdaddr);
+
+	hci_req_complete(hdev, rp->status);
+}
+
+static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
+{
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	if (status) {
+		hci_req_complete(hdev, status);
+
+		hci_conn_check_pending(hdev);
+	} else
+		set_bit(HCI_INQUIRY, &hdev->flags);
+}
+
 static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
 {
+	struct hci_cp_create_conn *cp;
 	struct hci_conn *conn;
-	struct hci_cp_create_conn *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
 
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
 	if (!cp)
 		return;
 
@@ -431,8 +480,7 @@
 
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
 
-	BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name,
-			status, batostr(&cp->bdaddr), conn);
+	BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
 
 	if (status) {
 		if (conn && conn->state == BT_CONNECT) {
@@ -457,157 +505,138 @@
 	hci_dev_unlock(hdev);
 }
 
-static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
 {
-	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+	struct hci_cp_add_sco *cp;
+	struct hci_conn *acl, *sco;
+	__u16 handle;
 
-	switch (ocf) {
-	case OCF_CREATE_CONN:
-		hci_cs_create_conn(hdev, status);
-		break;
+	BT_DBG("%s status 0x%x", hdev->name, status);
 
-	case OCF_ADD_SCO:
-		if (status) {
-			struct hci_conn *acl, *sco;
-			struct hci_cp_add_sco *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_ADD_SCO);
-			__u16 handle;
+	if (!status)
+		return;
 
-			if (!cp)
-				break;
+	cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
+	if (!cp)
+		return;
 
-			handle = __le16_to_cpu(cp->handle);
+	handle = __le16_to_cpu(cp->handle);
 
-			BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
-
-			hci_dev_lock(hdev);
-
-			acl = hci_conn_hash_lookup_handle(hdev, handle);
-			if (acl && (sco = acl->link)) {
-				sco->state = BT_CLOSED;
-
-				hci_proto_connect_cfm(sco, status);
-				hci_conn_del(sco);
-			}
-
-			hci_dev_unlock(hdev);
-		}
-		break;
-
-	case OCF_INQUIRY:
-		if (status) {
-			BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
-			hci_req_complete(hdev, status);
-		} else {
-			set_bit(HCI_INQUIRY, &hdev->flags);
-		}
-		break;
-
-	default:
-		BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d",
-			hdev->name, ocf, status);
-		break;
-	}
-}
-
-/* Command Status OGF LINK_POLICY */
-static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
-{
-	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-
-	switch (ocf) {
-	case OCF_SNIFF_MODE:
-		if (status) {
-			struct hci_conn *conn;
-			struct hci_cp_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_SNIFF_MODE);
-
-			if (!cp)
-				break;
-
-			hci_dev_lock(hdev);
-
-			conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
-			if (conn) {
-				clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
-			}
-
-			hci_dev_unlock(hdev);
-		}
-		break;
-
-	case OCF_EXIT_SNIFF_MODE:
-		if (status) {
-			struct hci_conn *conn;
-			struct hci_cp_exit_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_EXIT_SNIFF_MODE);
-
-			if (!cp)
-				break;
-
-			hci_dev_lock(hdev);
-
-			conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
-			if (conn) {
-				clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
-			}
-
-			hci_dev_unlock(hdev);
-		}
-		break;
-
-	default:
-		BT_DBG("%s Command status: ogf LINK_POLICY ocf %x", hdev->name, ocf);
-		break;
-	}
-}
-
-/* Command Status OGF HOST_CTL */
-static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-{
-	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-
-	switch (ocf) {
-	default:
-		BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
-		break;
-	}
-}
-
-/* Command Status OGF INFO_PARAM  */
-static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
-{
-	BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
-
-	switch (ocf) {
-	default:
-		BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-		break;
-	}
-}
-
-/* Inquiry Complete */
-static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	__u8 status = *((__u8 *) skb->data);
-	struct hci_conn *pend;
-
-	BT_DBG("%s status %d", hdev->name, status);
-
-	clear_bit(HCI_INQUIRY, &hdev->flags);
-	hci_req_complete(hdev, status);
+	BT_DBG("%s handle %d", hdev->name, handle);
 
 	hci_dev_lock(hdev);
 
-	pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
-	if (pend)
-		hci_acl_connect(pend);
+	acl = hci_conn_hash_lookup_handle(hdev, handle);
+	if (acl && (sco = acl->link)) {
+		sco->state = BT_CLOSED;
+
+		hci_proto_connect_cfm(sco, status);
+		hci_conn_del(sco);
+	}
 
 	hci_dev_unlock(hdev);
 }
 
-/* Inquiry Result */
+static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
+{
+	BT_DBG("%s status 0x%x", hdev->name, status);
+}
+
+static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
+{
+	struct hci_cp_setup_sync_conn *cp;
+	struct hci_conn *acl, *sco;
+	__u16 handle;
+
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	if (!status)
+		return;
+
+	cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
+	if (!cp)
+		return;
+
+	handle = __le16_to_cpu(cp->handle);
+
+	BT_DBG("%s handle %d", hdev->name, handle);
+
+	hci_dev_lock(hdev);
+
+	acl = hci_conn_hash_lookup_handle(hdev, handle);
+	if (acl && (sco = acl->link)) {
+		sco->state = BT_CLOSED;
+
+		hci_proto_connect_cfm(sco, status);
+		hci_conn_del(sco);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
+static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
+{
+	struct hci_cp_sniff_mode *cp;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	if (!status)
+		return;
+
+	cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
+	if (!cp)
+		return;
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
+	if (conn)
+		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
+
+	hci_dev_unlock(hdev);
+}
+
+static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
+{
+	struct hci_cp_exit_sniff_mode *cp;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	if (!status)
+		return;
+
+	cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
+	if (!cp)
+		return;
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
+	if (conn)
+		clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
+
+	hci_dev_unlock(hdev);
+}
+
+static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+
+	BT_DBG("%s status %d", hdev->name, status);
+
+	clear_bit(HCI_INQUIRY, &hdev->flags);
+
+	hci_req_complete(hdev, status);
+
+	hci_conn_check_pending(hdev);
+}
+
 static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct inquiry_data data;
-	struct inquiry_info *info = (struct inquiry_info *) (skb->data + 1);
+	struct inquiry_info *info = (void *) (skb->data + 1);
 	int num_rsp = *((__u8 *) skb->data);
 
 	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
@@ -632,147 +661,18 @@
 	hci_dev_unlock(hdev);
 }
 
-/* Inquiry Result With RSSI */
-static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	struct inquiry_data data;
-	int num_rsp = *((__u8 *) skb->data);
-
-	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
-
-	if (!num_rsp)
-		return;
-
-	hci_dev_lock(hdev);
-
-	if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
-		struct inquiry_info_with_rssi_and_pscan_mode *info =
-			(struct inquiry_info_with_rssi_and_pscan_mode *) (skb->data + 1);
-
-		for (; num_rsp; num_rsp--) {
-			bacpy(&data.bdaddr, &info->bdaddr);
-			data.pscan_rep_mode	= info->pscan_rep_mode;
-			data.pscan_period_mode	= info->pscan_period_mode;
-			data.pscan_mode		= info->pscan_mode;
-			memcpy(data.dev_class, info->dev_class, 3);
-			data.clock_offset	= info->clock_offset;
-			data.rssi		= info->rssi;
-			info++;
-			hci_inquiry_cache_update(hdev, &data);
-		}
-	} else {
-		struct inquiry_info_with_rssi *info =
-			(struct inquiry_info_with_rssi *) (skb->data + 1);
-
-		for (; num_rsp; num_rsp--) {
-			bacpy(&data.bdaddr, &info->bdaddr);
-			data.pscan_rep_mode	= info->pscan_rep_mode;
-			data.pscan_period_mode	= info->pscan_period_mode;
-			data.pscan_mode		= 0x00;
-			memcpy(data.dev_class, info->dev_class, 3);
-			data.clock_offset	= info->clock_offset;
-			data.rssi		= info->rssi;
-			info++;
-			hci_inquiry_cache_update(hdev, &data);
-		}
-	}
-
-	hci_dev_unlock(hdev);
-}
-
-/* Extended Inquiry Result */
-static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	struct inquiry_data data;
-	struct extended_inquiry_info *info = (struct extended_inquiry_info *) (skb->data + 1);
-	int num_rsp = *((__u8 *) skb->data);
-
-	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
-
-	if (!num_rsp)
-		return;
-
-	hci_dev_lock(hdev);
-
-	for (; num_rsp; num_rsp--) {
-		bacpy(&data.bdaddr, &info->bdaddr);
-		data.pscan_rep_mode     = info->pscan_rep_mode;
-		data.pscan_period_mode  = info->pscan_period_mode;
-		data.pscan_mode         = 0x00;
-		memcpy(data.dev_class, info->dev_class, 3);
-		data.clock_offset       = info->clock_offset;
-		data.rssi               = info->rssi;
-		info++;
-		hci_inquiry_cache_update(hdev, &data);
-	}
-
-	hci_dev_unlock(hdev);
-}
-
-/* Connect Request */
-static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	struct hci_ev_conn_request *ev = (struct hci_ev_conn_request *) skb->data;
-	int mask = hdev->link_mode;
-
-	BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
-			batostr(&ev->bdaddr), ev->link_type);
-
-	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
-
-	if (mask & HCI_LM_ACCEPT) {
-		/* Connection accepted */
-		struct hci_conn *conn;
-		struct hci_cp_accept_conn_req cp;
-
-		hci_dev_lock(hdev);
-		conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
-		if (!conn) {
-			if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
-				BT_ERR("No memmory for new connection");
-				hci_dev_unlock(hdev);
-				return;
-			}
-		}
-		memcpy(conn->dev_class, ev->dev_class, 3);
-		conn->state = BT_CONNECT;
-		hci_dev_unlock(hdev);
-
-		bacpy(&cp.bdaddr, &ev->bdaddr);
-
-		if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
-			cp.role = 0x00; /* Become master */
-		else
-			cp.role = 0x01; /* Remain slave */
-
-		hci_send_cmd(hdev, OGF_LINK_CTL,
-				OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp);
-	} else {
-		/* Connection rejected */
-		struct hci_cp_reject_conn_req cp;
-
-		bacpy(&cp.bdaddr, &ev->bdaddr);
-		cp.reason = 0x0f;
-		hci_send_cmd(hdev, OGF_LINK_CTL,
-				OCF_REJECT_CONN_REQ, sizeof(cp), &cp);
-	}
-}
-
-/* Connect Complete */
 static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data;
-	struct hci_conn *conn, *pend;
+	struct hci_ev_conn_complete *ev = (void *) skb->data;
+	struct hci_conn *conn;
 
 	BT_DBG("%s", hdev->name);
 
 	hci_dev_lock(hdev);
 
 	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
-	if (!conn) {
-		hci_dev_unlock(hdev);
-		return;
-	}
+	if (!conn)
+		goto unlock;
 
 	if (!ev->status) {
 		conn->handle = __le16_to_cpu(ev->handle);
@@ -788,8 +688,7 @@
 		if (conn->type == ACL_LINK) {
 			struct hci_cp_read_remote_features cp;
 			cp.handle = ev->handle;
-			hci_send_cmd(hdev, OGF_LINK_CTL,
-				OCF_READ_REMOTE_FEATURES, sizeof(cp), &cp);
+			hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, sizeof(cp), &cp);
 		}
 
 		/* Set link policy */
@@ -797,8 +696,7 @@
 			struct hci_cp_write_link_policy cp;
 			cp.handle = ev->handle;
 			cp.policy = cpu_to_le16(hdev->link_policy);
-			hci_send_cmd(hdev, OGF_LINK_POLICY,
-				OCF_WRITE_LINK_POLICY, sizeof(cp), &cp);
+			hci_send_cmd(hdev, HCI_OP_WRITE_LINK_POLICY, sizeof(cp), &cp);
 		}
 
 		/* Set packet type for incoming connection */
@@ -809,8 +707,7 @@
 				cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
 				cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
 
-			hci_send_cmd(hdev, OGF_LINK_CTL,
-				OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
+			hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
 		} else {
 			/* Update disconnect timer */
 			hci_conn_hold(conn);
@@ -822,9 +719,12 @@
 	if (conn->type == ACL_LINK) {
 		struct hci_conn *sco = conn->link;
 		if (sco) {
-			if (!ev->status)
-				hci_add_sco(sco, conn->handle);
-			else {
+			if (!ev->status) {
+				if (lmp_esco_capable(hdev))
+					hci_setup_sync(sco, conn->handle);
+				else
+					hci_add_sco(sco, conn->handle);
+			} else {
 				hci_proto_connect_cfm(sco, ev->status);
 				hci_conn_del(sco);
 			}
@@ -835,17 +735,82 @@
 	if (ev->status)
 		hci_conn_del(conn);
 
-	pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
-	if (pend)
-		hci_acl_connect(pend);
-
+unlock:
 	hci_dev_unlock(hdev);
+
+	hci_conn_check_pending(hdev);
 }
 
-/* Disconnect Complete */
+static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_conn_request *ev = (void *) skb->data;
+	int mask = hdev->link_mode;
+
+	BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
+					batostr(&ev->bdaddr), ev->link_type);
+
+	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
+
+	if (mask & HCI_LM_ACCEPT) {
+		/* Connection accepted */
+		struct hci_conn *conn;
+
+		hci_dev_lock(hdev);
+
+		conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
+		if (!conn) {
+			if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
+				BT_ERR("No memmory for new connection");
+				hci_dev_unlock(hdev);
+				return;
+			}
+		}
+
+		memcpy(conn->dev_class, ev->dev_class, 3);
+		conn->state = BT_CONNECT;
+
+		hci_dev_unlock(hdev);
+
+		if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
+			struct hci_cp_accept_conn_req cp;
+
+			bacpy(&cp.bdaddr, &ev->bdaddr);
+
+			if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
+				cp.role = 0x00; /* Become master */
+			else
+				cp.role = 0x01; /* Remain slave */
+
+			hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
+							sizeof(cp), &cp);
+		} else {
+			struct hci_cp_accept_sync_conn_req cp;
+
+			bacpy(&cp.bdaddr, &ev->bdaddr);
+			cp.pkt_type = cpu_to_le16(hdev->esco_type);
+
+			cp.tx_bandwidth   = cpu_to_le32(0x00001f40);
+			cp.rx_bandwidth   = cpu_to_le32(0x00001f40);
+			cp.max_latency    = cpu_to_le16(0xffff);
+			cp.content_format = cpu_to_le16(hdev->voice_setting);
+			cp.retrans_effort = 0xff;
+
+			hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
+							sizeof(cp), &cp);
+		}
+	} else {
+		/* Connection rejected */
+		struct hci_cp_reject_conn_req cp;
+
+		bacpy(&cp.bdaddr, &ev->bdaddr);
+		cp.reason = 0x0f;
+		hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
+	}
+}
+
 static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data;
+	struct hci_ev_disconn_complete *ev = (void *) skb->data;
 	struct hci_conn *conn;
 
 	BT_DBG("%s status %d", hdev->name, ev->status);
@@ -865,10 +830,310 @@
 	hci_dev_unlock(hdev);
 }
 
-/* Number of completed packets */
+static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_auth_complete *ev = (void *) skb->data;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status %d", hdev->name, ev->status);
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+	if (conn) {
+		if (!ev->status)
+			conn->link_mode |= HCI_LM_AUTH;
+
+		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
+
+		hci_auth_cfm(conn, ev->status);
+
+		if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
+			if (!ev->status) {
+				struct hci_cp_set_conn_encrypt cp;
+				cp.handle  = cpu_to_le16(conn->handle);
+				cp.encrypt = 1;
+				hci_send_cmd(conn->hdev,
+					HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp);
+			} else {
+				clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
+				hci_encrypt_cfm(conn, ev->status, 0x00);
+			}
+		}
+	}
+
+	hci_dev_unlock(hdev);
+}
+
+static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	BT_DBG("%s", hdev->name);
+
+	hci_conn_check_pending(hdev);
+}
+
+static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_encrypt_change *ev = (void *) skb->data;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status %d", hdev->name, ev->status);
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+	if (conn) {
+		if (!ev->status) {
+			if (ev->encrypt)
+				conn->link_mode |= HCI_LM_ENCRYPT;
+			else
+				conn->link_mode &= ~HCI_LM_ENCRYPT;
+		}
+
+		clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
+
+		hci_encrypt_cfm(conn, ev->status, ev->encrypt);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
+static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status %d", hdev->name, ev->status);
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+	if (conn) {
+		if (!ev->status)
+			conn->link_mode |= HCI_LM_SECURE;
+
+		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
+
+		hci_key_change_cfm(conn, ev->status);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
+static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_remote_features *ev = (void *) skb->data;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status %d", hdev->name, ev->status);
+
+	if (ev->status)
+		return;
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+	if (conn)
+		memcpy(conn->features, ev->features, 8);
+
+	hci_dev_unlock(hdev);
+}
+
+static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	BT_DBG("%s", hdev->name);
+}
+
+static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	BT_DBG("%s", hdev->name);
+}
+
+static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_cmd_complete *ev = (void *) skb->data;
+	__u16 opcode;
+
+	skb_pull(skb, sizeof(*ev));
+
+	opcode = __le16_to_cpu(ev->opcode);
+
+	switch (opcode) {
+	case HCI_OP_INQUIRY_CANCEL:
+		hci_cc_inquiry_cancel(hdev, skb);
+		break;
+
+	case HCI_OP_EXIT_PERIODIC_INQ:
+		hci_cc_exit_periodic_inq(hdev, skb);
+		break;
+
+	case HCI_OP_REMOTE_NAME_REQ_CANCEL:
+		hci_cc_remote_name_req_cancel(hdev, skb);
+		break;
+
+	case HCI_OP_ROLE_DISCOVERY:
+		hci_cc_role_discovery(hdev, skb);
+		break;
+
+	case HCI_OP_WRITE_LINK_POLICY:
+		hci_cc_write_link_policy(hdev, skb);
+		break;
+
+	case HCI_OP_RESET:
+		hci_cc_reset(hdev, skb);
+		break;
+
+	case HCI_OP_WRITE_LOCAL_NAME:
+		hci_cc_write_local_name(hdev, skb);
+		break;
+
+	case HCI_OP_READ_LOCAL_NAME:
+		hci_cc_read_local_name(hdev, skb);
+		break;
+
+	case HCI_OP_WRITE_AUTH_ENABLE:
+		hci_cc_write_auth_enable(hdev, skb);
+		break;
+
+	case HCI_OP_WRITE_ENCRYPT_MODE:
+		hci_cc_write_encrypt_mode(hdev, skb);
+		break;
+
+	case HCI_OP_WRITE_SCAN_ENABLE:
+		hci_cc_write_scan_enable(hdev, skb);
+		break;
+
+	case HCI_OP_READ_CLASS_OF_DEV:
+		hci_cc_read_class_of_dev(hdev, skb);
+		break;
+
+	case HCI_OP_WRITE_CLASS_OF_DEV:
+		hci_cc_write_class_of_dev(hdev, skb);
+		break;
+
+	case HCI_OP_READ_VOICE_SETTING:
+		hci_cc_read_voice_setting(hdev, skb);
+		break;
+
+	case HCI_OP_WRITE_VOICE_SETTING:
+		hci_cc_write_voice_setting(hdev, skb);
+		break;
+
+	case HCI_OP_HOST_BUFFER_SIZE:
+		hci_cc_host_buffer_size(hdev, skb);
+		break;
+
+	case HCI_OP_READ_LOCAL_VERSION:
+		hci_cc_read_local_version(hdev, skb);
+		break;
+
+	case HCI_OP_READ_LOCAL_COMMANDS:
+		hci_cc_read_local_commands(hdev, skb);
+		break;
+
+	case HCI_OP_READ_LOCAL_FEATURES:
+		hci_cc_read_local_features(hdev, skb);
+		break;
+
+	case HCI_OP_READ_BUFFER_SIZE:
+		hci_cc_read_buffer_size(hdev, skb);
+		break;
+
+	case HCI_OP_READ_BD_ADDR:
+		hci_cc_read_bd_addr(hdev, skb);
+		break;
+
+	default:
+		BT_DBG("%s opcode 0x%x", hdev->name, opcode);
+		break;
+	}
+
+	if (ev->ncmd) {
+		atomic_set(&hdev->cmd_cnt, 1);
+		if (!skb_queue_empty(&hdev->cmd_q))
+			hci_sched_cmd(hdev);
+	}
+}
+
+static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_cmd_status *ev = (void *) skb->data;
+	__u16 opcode;
+
+	skb_pull(skb, sizeof(*ev));
+
+	opcode = __le16_to_cpu(ev->opcode);
+
+	switch (opcode) {
+	case HCI_OP_INQUIRY:
+		hci_cs_inquiry(hdev, ev->status);
+		break;
+
+	case HCI_OP_CREATE_CONN:
+		hci_cs_create_conn(hdev, ev->status);
+		break;
+
+	case HCI_OP_ADD_SCO:
+		hci_cs_add_sco(hdev, ev->status);
+		break;
+
+	case HCI_OP_REMOTE_NAME_REQ:
+		hci_cs_remote_name_req(hdev, ev->status);
+		break;
+
+	case HCI_OP_SETUP_SYNC_CONN:
+		hci_cs_setup_sync_conn(hdev, ev->status);
+		break;
+
+	case HCI_OP_SNIFF_MODE:
+		hci_cs_sniff_mode(hdev, ev->status);
+		break;
+
+	case HCI_OP_EXIT_SNIFF_MODE:
+		hci_cs_exit_sniff_mode(hdev, ev->status);
+		break;
+
+	default:
+		BT_DBG("%s opcode 0x%x", hdev->name, opcode);
+		break;
+	}
+
+	if (ev->ncmd) {
+		atomic_set(&hdev->cmd_cnt, 1);
+		if (!skb_queue_empty(&hdev->cmd_q))
+			hci_sched_cmd(hdev);
+	}
+}
+
+static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_role_change *ev = (void *) skb->data;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status %d", hdev->name, ev->status);
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+	if (conn) {
+		if (!ev->status) {
+			if (ev->role)
+				conn->link_mode &= ~HCI_LM_MASTER;
+			else
+				conn->link_mode |= HCI_LM_MASTER;
+		}
+
+		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
+
+		hci_role_switch_cfm(conn, ev->status, ev->role);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
 static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_ev_num_comp_pkts *ev = (struct hci_ev_num_comp_pkts *) skb->data;
+	struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
 	__le16 *ptr;
 	int i;
 
@@ -903,42 +1168,15 @@
 			}
 		}
 	}
+
 	hci_sched_tx(hdev);
 
 	tasklet_enable(&hdev->tx_task);
 }
 
-/* Role Change */
-static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	struct hci_ev_role_change *ev = (struct hci_ev_role_change *) skb->data;
-	struct hci_conn *conn;
-
-	BT_DBG("%s status %d", hdev->name, ev->status);
-
-	hci_dev_lock(hdev);
-
-	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
-	if (conn) {
-		if (!ev->status) {
-			if (ev->role)
-				conn->link_mode &= ~HCI_LM_MASTER;
-			else
-				conn->link_mode |= HCI_LM_MASTER;
-		}
-
-		clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
-
-		hci_role_switch_cfm(conn, ev->status, ev->role);
-	}
-
-	hci_dev_unlock(hdev);
-}
-
-/* Mode Change */
 static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_ev_mode_change *ev = (struct hci_ev_mode_change *) skb->data;
+	struct hci_ev_mode_change *ev = (void *) skb->data;
 	struct hci_conn *conn;
 
 	BT_DBG("%s status %d", hdev->name, ev->status);
@@ -961,129 +1199,24 @@
 	hci_dev_unlock(hdev);
 }
 
-/* Authentication Complete */
-static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data;
-	struct hci_conn *conn;
-
-	BT_DBG("%s status %d", hdev->name, ev->status);
-
-	hci_dev_lock(hdev);
-
-	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
-	if (conn) {
-		if (!ev->status)
-			conn->link_mode |= HCI_LM_AUTH;
-
-		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
-
-		hci_auth_cfm(conn, ev->status);
-
-		if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
-			if (!ev->status) {
-				struct hci_cp_set_conn_encrypt cp;
-				cp.handle  = cpu_to_le16(conn->handle);
-				cp.encrypt = 1;
-				hci_send_cmd(conn->hdev, OGF_LINK_CTL,
-					OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp);
-			} else {
-				clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
-				hci_encrypt_cfm(conn, ev->status, 0x00);
-			}
-		}
-	}
-
-	hci_dev_unlock(hdev);
-}
-
-/* Encryption Change */
-static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	struct hci_ev_encrypt_change *ev = (struct hci_ev_encrypt_change *) skb->data;
-	struct hci_conn *conn;
-
-	BT_DBG("%s status %d", hdev->name, ev->status);
-
-	hci_dev_lock(hdev);
-
-	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
-	if (conn) {
-		if (!ev->status) {
-			if (ev->encrypt)
-				conn->link_mode |= HCI_LM_ENCRYPT;
-			else
-				conn->link_mode &= ~HCI_LM_ENCRYPT;
-		}
-
-		clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
-
-		hci_encrypt_cfm(conn, ev->status, ev->encrypt);
-	}
-
-	hci_dev_unlock(hdev);
-}
-
-/* Change Connection Link Key Complete */
-static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) skb->data;
-	struct hci_conn *conn;
-
-	BT_DBG("%s status %d", hdev->name, ev->status);
-
-	hci_dev_lock(hdev);
-
-	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
-	if (conn) {
-		if (!ev->status)
-			conn->link_mode |= HCI_LM_SECURE;
-
-		clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
-
-		hci_key_change_cfm(conn, ev->status);
-	}
-
-	hci_dev_unlock(hdev);
-}
-
-/* Pin Code Request*/
 static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
+	BT_DBG("%s", hdev->name);
 }
 
-/* Link Key Request */
 static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
+	BT_DBG("%s", hdev->name);
 }
 
-/* Link Key Notification */
 static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
+	BT_DBG("%s", hdev->name);
 }
 
-/* Remote Features */
-static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
-	struct hci_ev_remote_features *ev = (struct hci_ev_remote_features *) skb->data;
-	struct hci_conn *conn;
-
-	BT_DBG("%s status %d", hdev->name, ev->status);
-
-	hci_dev_lock(hdev);
-
-	conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
-	if (conn && !ev->status) {
-		memcpy(conn->features, ev->features, sizeof(conn->features));
-	}
-
-	hci_dev_unlock(hdev);
-}
-
-/* Clock Offset */
 static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data;
+	struct hci_ev_clock_offset *ev = (void *) skb->data;
 	struct hci_conn *conn;
 
 	BT_DBG("%s status %d", hdev->name, ev->status);
@@ -1103,10 +1236,9 @@
 	hci_dev_unlock(hdev);
 }
 
-/* Page Scan Repetition Mode */
 static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_ev_pscan_rep_mode *ev = (struct hci_ev_pscan_rep_mode *) skb->data;
+	struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
 	struct inquiry_entry *ie;
 
 	BT_DBG("%s", hdev->name);
@@ -1121,10 +1253,91 @@
 	hci_dev_unlock(hdev);
 }
 
-/* Sniff Subrate */
+static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct inquiry_data data;
+	int num_rsp = *((__u8 *) skb->data);
+
+	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
+
+	if (!num_rsp)
+		return;
+
+	hci_dev_lock(hdev);
+
+	if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
+		struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
+
+		for (; num_rsp; num_rsp--) {
+			bacpy(&data.bdaddr, &info->bdaddr);
+			data.pscan_rep_mode	= info->pscan_rep_mode;
+			data.pscan_period_mode	= info->pscan_period_mode;
+			data.pscan_mode		= info->pscan_mode;
+			memcpy(data.dev_class, info->dev_class, 3);
+			data.clock_offset	= info->clock_offset;
+			data.rssi		= info->rssi;
+			info++;
+			hci_inquiry_cache_update(hdev, &data);
+		}
+	} else {
+		struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
+
+		for (; num_rsp; num_rsp--) {
+			bacpy(&data.bdaddr, &info->bdaddr);
+			data.pscan_rep_mode	= info->pscan_rep_mode;
+			data.pscan_period_mode	= info->pscan_period_mode;
+			data.pscan_mode		= 0x00;
+			memcpy(data.dev_class, info->dev_class, 3);
+			data.clock_offset	= info->clock_offset;
+			data.rssi		= info->rssi;
+			info++;
+			hci_inquiry_cache_update(hdev, &data);
+		}
+	}
+
+	hci_dev_unlock(hdev);
+}
+
+static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	BT_DBG("%s", hdev->name);
+}
+
+static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
+	struct hci_conn *conn;
+
+	BT_DBG("%s status %d", hdev->name, ev->status);
+
+	hci_dev_lock(hdev);
+
+	conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
+	if (!conn)
+		goto unlock;
+
+	if (!ev->status) {
+		conn->handle = __le16_to_cpu(ev->handle);
+		conn->state  = BT_CONNECTED;
+	} else
+		conn->state = BT_CLOSED;
+
+	hci_proto_connect_cfm(conn, ev->status);
+	if (ev->status)
+		hci_conn_del(conn);
+
+unlock:
+	hci_dev_unlock(hdev);
+}
+
+static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	BT_DBG("%s", hdev->name);
+}
+
 static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_ev_sniff_subrate *ev = (struct hci_ev_sniff_subrate *) skb->data;
+	struct hci_ev_sniff_subrate *ev = (void *) skb->data;
 	struct hci_conn *conn;
 
 	BT_DBG("%s status %d", hdev->name, ev->status);
@@ -1138,22 +1351,42 @@
 	hci_dev_unlock(hdev);
 }
 
+static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct inquiry_data data;
+	struct extended_inquiry_info *info = (void *) (skb->data + 1);
+	int num_rsp = *((__u8 *) skb->data);
+
+	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
+
+	if (!num_rsp)
+		return;
+
+	hci_dev_lock(hdev);
+
+	for (; num_rsp; num_rsp--) {
+		bacpy(&data.bdaddr, &info->bdaddr);
+		data.pscan_rep_mode     = info->pscan_rep_mode;
+		data.pscan_period_mode  = info->pscan_period_mode;
+		data.pscan_mode         = 0x00;
+		memcpy(data.dev_class, info->dev_class, 3);
+		data.clock_offset       = info->clock_offset;
+		data.rssi               = info->rssi;
+		info++;
+		hci_inquiry_cache_update(hdev, &data);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
-	struct hci_ev_cmd_complete *ec;
-	struct hci_ev_cmd_status *cs;
-	u16 opcode, ocf, ogf;
+	struct hci_event_hdr *hdr = (void *) skb->data;
+	__u8 event = hdr->evt;
 
 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
 
-	BT_DBG("%s evt 0x%x", hdev->name, hdr->evt);
-
-	switch (hdr->evt) {
-	case HCI_EV_NUM_COMP_PKTS:
-		hci_num_comp_pkts_evt(hdev, skb);
-		break;
-
+	switch (event) {
 	case HCI_EV_INQUIRY_COMPLETE:
 		hci_inquiry_complete_evt(hdev, skb);
 		break;
@@ -1162,44 +1395,64 @@
 		hci_inquiry_result_evt(hdev, skb);
 		break;
 
-	case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
-		hci_inquiry_result_with_rssi_evt(hdev, skb);
-		break;
-
-	case HCI_EV_EXTENDED_INQUIRY_RESULT:
-		hci_extended_inquiry_result_evt(hdev, skb);
+	case HCI_EV_CONN_COMPLETE:
+		hci_conn_complete_evt(hdev, skb);
 		break;
 
 	case HCI_EV_CONN_REQUEST:
 		hci_conn_request_evt(hdev, skb);
 		break;
 
-	case HCI_EV_CONN_COMPLETE:
-		hci_conn_complete_evt(hdev, skb);
-		break;
-
 	case HCI_EV_DISCONN_COMPLETE:
 		hci_disconn_complete_evt(hdev, skb);
 		break;
 
-	case HCI_EV_ROLE_CHANGE:
-		hci_role_change_evt(hdev, skb);
-		break;
-
-	case HCI_EV_MODE_CHANGE:
-		hci_mode_change_evt(hdev, skb);
-		break;
-
 	case HCI_EV_AUTH_COMPLETE:
 		hci_auth_complete_evt(hdev, skb);
 		break;
 
+	case HCI_EV_REMOTE_NAME:
+		hci_remote_name_evt(hdev, skb);
+		break;
+
 	case HCI_EV_ENCRYPT_CHANGE:
 		hci_encrypt_change_evt(hdev, skb);
 		break;
 
-	case HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE:
-		hci_change_conn_link_key_complete_evt(hdev, skb);
+	case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
+		hci_change_link_key_complete_evt(hdev, skb);
+		break;
+
+	case HCI_EV_REMOTE_FEATURES:
+		hci_remote_features_evt(hdev, skb);
+		break;
+
+	case HCI_EV_REMOTE_VERSION:
+		hci_remote_version_evt(hdev, skb);
+		break;
+
+	case HCI_EV_QOS_SETUP_COMPLETE:
+		hci_qos_setup_complete_evt(hdev, skb);
+		break;
+
+	case HCI_EV_CMD_COMPLETE:
+		hci_cmd_complete_evt(hdev, skb);
+		break;
+
+	case HCI_EV_CMD_STATUS:
+		hci_cmd_status_evt(hdev, skb);
+		break;
+
+	case HCI_EV_ROLE_CHANGE:
+		hci_role_change_evt(hdev, skb);
+		break;
+
+	case HCI_EV_NUM_COMP_PKTS:
+		hci_num_comp_pkts_evt(hdev, skb);
+		break;
+
+	case HCI_EV_MODE_CHANGE:
+		hci_mode_change_evt(hdev, skb);
 		break;
 
 	case HCI_EV_PIN_CODE_REQ:
@@ -1214,10 +1467,6 @@
 		hci_link_key_notify_evt(hdev, skb);
 		break;
 
-	case HCI_EV_REMOTE_FEATURES:
-		hci_remote_features_evt(hdev, skb);
-		break;
-
 	case HCI_EV_CLOCK_OFFSET:
 		hci_clock_offset_evt(hdev, skb);
 		break;
@@ -1226,82 +1475,32 @@
 		hci_pscan_rep_mode_evt(hdev, skb);
 		break;
 
+	case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
+		hci_inquiry_result_with_rssi_evt(hdev, skb);
+		break;
+
+	case HCI_EV_REMOTE_EXT_FEATURES:
+		hci_remote_ext_features_evt(hdev, skb);
+		break;
+
+	case HCI_EV_SYNC_CONN_COMPLETE:
+		hci_sync_conn_complete_evt(hdev, skb);
+		break;
+
+	case HCI_EV_SYNC_CONN_CHANGED:
+		hci_sync_conn_changed_evt(hdev, skb);
+		break;
+
 	case HCI_EV_SNIFF_SUBRATE:
 		hci_sniff_subrate_evt(hdev, skb);
 		break;
 
-	case HCI_EV_CMD_STATUS:
-		cs = (struct hci_ev_cmd_status *) skb->data;
-		skb_pull(skb, sizeof(cs));
-
-		opcode = __le16_to_cpu(cs->opcode);
-		ogf = hci_opcode_ogf(opcode);
-		ocf = hci_opcode_ocf(opcode);
-
-		switch (ogf) {
-		case OGF_INFO_PARAM:
-			hci_cs_info_param(hdev, ocf, cs->status);
-			break;
-
-		case OGF_HOST_CTL:
-			hci_cs_host_ctl(hdev, ocf, cs->status);
-			break;
-
-		case OGF_LINK_CTL:
-			hci_cs_link_ctl(hdev, ocf, cs->status);
-			break;
-
-		case OGF_LINK_POLICY:
-			hci_cs_link_policy(hdev, ocf, cs->status);
-			break;
-
-		default:
-			BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
-			break;
-		}
-
-		if (cs->ncmd) {
-			atomic_set(&hdev->cmd_cnt, 1);
-			if (!skb_queue_empty(&hdev->cmd_q))
-				hci_sched_cmd(hdev);
-		}
+	case HCI_EV_EXTENDED_INQUIRY_RESULT:
+		hci_extended_inquiry_result_evt(hdev, skb);
 		break;
 
-	case HCI_EV_CMD_COMPLETE:
-		ec = (struct hci_ev_cmd_complete *) skb->data;
-		skb_pull(skb, sizeof(*ec));
-
-		opcode = __le16_to_cpu(ec->opcode);
-		ogf = hci_opcode_ogf(opcode);
-		ocf = hci_opcode_ocf(opcode);
-
-		switch (ogf) {
-		case OGF_INFO_PARAM:
-			hci_cc_info_param(hdev, ocf, skb);
-			break;
-
-		case OGF_HOST_CTL:
-			hci_cc_host_ctl(hdev, ocf, skb);
-			break;
-
-		case OGF_LINK_CTL:
-			hci_cc_link_ctl(hdev, ocf, skb);
-			break;
-
-		case OGF_LINK_POLICY:
-			hci_cc_link_policy(hdev, ocf, skb);
-			break;
-
-		default:
-			BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
-			break;
-		}
-
-		if (ec->ncmd) {
-			atomic_set(&hdev->cmd_cnt, 1);
-			if (!skb_queue_empty(&hdev->cmd_q))
-				hci_sched_cmd(hdev);
-		}
+	default:
+		BT_DBG("%s event 0x%x", hdev->name, event);
 		break;
 	}
 
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 43dd637..8825102 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -451,7 +451,7 @@
 			goto drop;
 		}
 
-		if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
+		if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
 			skb_queue_tail(&hdev->raw_q, skb);
 			hci_sched_tx(hdev);
 		} else {
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 2583540..cef1e3e 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -41,6 +41,26 @@
 	return sprintf(buf, "%s\n", typetostr(hdev->type));
 }
 
+static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct hci_dev *hdev = dev_get_drvdata(dev);
+	char name[249];
+	int i;
+
+	for (i = 0; i < 248; i++)
+		name[i] = hdev->dev_name[i];
+
+	name[248] = '\0';
+	return sprintf(buf, "%s\n", name);
+}
+
+static ssize_t show_class(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct hci_dev *hdev = dev_get_drvdata(dev);
+	return sprintf(buf, "0x%.2x%.2x%.2x\n",
+			hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
+}
+
 static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct hci_dev *hdev = dev_get_drvdata(dev);
@@ -49,6 +69,17 @@
 	return sprintf(buf, "%s\n", batostr(&bdaddr));
 }
 
+static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct hci_dev *hdev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+				hdev->features[0], hdev->features[1],
+				hdev->features[2], hdev->features[3],
+				hdev->features[4], hdev->features[5],
+				hdev->features[6], hdev->features[7]);
+}
+
 static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct hci_dev *hdev = dev_get_drvdata(dev);
@@ -170,7 +201,10 @@
 }
 
 static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+static DEVICE_ATTR(class, S_IRUGO, show_class, NULL);
 static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
+static DEVICE_ATTR(features, S_IRUGO, show_features, NULL);
 static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL);
 static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL);
 static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL);
@@ -185,7 +219,10 @@
 
 static struct device_attribute *bt_attrs[] = {
 	&dev_attr_type,
+	&dev_attr_name,
+	&dev_attr_class,
 	&dev_attr_address,
+	&dev_attr_features,
 	&dev_attr_manufacturer,
 	&dev_attr_hci_version,
 	&dev_attr_hci_revision,
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index ff5784b..4bbacdd 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -247,7 +247,7 @@
 {
 	struct sk_buff *skb;
 
-	BT_DBG("session %p hid %p data %p size %d", session, device, data, size);
+	BT_DBG("session %p hid %p data %p size %d", session, session->hid, data, size);
 
 	if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) {
 		BT_ERR("Can't allocate memory for new frame");
@@ -656,11 +656,13 @@
 	}
 
 	if (req->subclass & 0x80) {
-		input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-		input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-		input->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-		input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-		input->relbit[0] |= BIT(REL_WHEEL);
+		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+		input->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+			BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+		input->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+		input->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |
+			BIT_MASK(BTN_EXTRA);
+		input->relbit[0] |= BIT_MASK(REL_WHEEL);
 	}
 
 	input->dev.parent = hidp_get_device(session);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 36ef27b..6fbbae7 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -55,7 +55,9 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "2.8"
+#define VERSION "2.9"
+
+static u32 l2cap_feat_mask = 0x0000;
 
 static const struct proto_ops l2cap_sock_ops;
 
@@ -258,7 +260,119 @@
 		sk->sk_state_change(sk);
 }
 
+static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
+{
+	u8 id;
+
+	/* Get next available identificator.
+	 *    1 - 128 are used by kernel.
+	 *  129 - 199 are reserved.
+	 *  200 - 254 are used by utilities like l2ping, etc.
+	 */
+
+	spin_lock_bh(&conn->lock);
+
+	if (++conn->tx_ident > 128)
+		conn->tx_ident = 1;
+
+	id = conn->tx_ident;
+
+	spin_unlock_bh(&conn->lock);
+
+	return id;
+}
+
+static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
+{
+	struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
+
+	BT_DBG("code 0x%2.2x", code);
+
+	if (!skb)
+		return -ENOMEM;
+
+	return hci_send_acl(conn->hcon, skb, 0);
+}
+
 /* ---- L2CAP connections ---- */
+static void l2cap_conn_start(struct l2cap_conn *conn)
+{
+	struct l2cap_chan_list *l = &conn->chan_list;
+	struct sock *sk;
+
+	BT_DBG("conn %p", conn);
+
+	read_lock(&l->lock);
+
+	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+		bh_lock_sock(sk);
+
+		if (sk->sk_type != SOCK_SEQPACKET) {
+			l2cap_sock_clear_timer(sk);
+			sk->sk_state = BT_CONNECTED;
+			sk->sk_state_change(sk);
+		} else if (sk->sk_state == BT_CONNECT) {
+			struct l2cap_conn_req req;
+			l2cap_pi(sk)->ident = l2cap_get_ident(conn);
+			req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
+			req.psm  = l2cap_pi(sk)->psm;
+			l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
+					L2CAP_CONN_REQ, sizeof(req), &req);
+		}
+
+		bh_unlock_sock(sk);
+	}
+
+	read_unlock(&l->lock);
+}
+
+static void l2cap_conn_ready(struct l2cap_conn *conn)
+{
+	BT_DBG("conn %p", conn);
+
+	if (conn->chan_list.head || !hlist_empty(&l2cap_sk_list.head)) {
+		struct l2cap_info_req req;
+
+		req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
+
+		conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
+		conn->info_ident = l2cap_get_ident(conn);
+
+		mod_timer(&conn->info_timer,
+			jiffies + msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
+
+		l2cap_send_cmd(conn, conn->info_ident,
+					L2CAP_INFO_REQ, sizeof(req), &req);
+	}
+}
+
+/* Notify sockets that we cannot guaranty reliability anymore */
+static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
+{
+	struct l2cap_chan_list *l = &conn->chan_list;
+	struct sock *sk;
+
+	BT_DBG("conn %p", conn);
+
+	read_lock(&l->lock);
+
+	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+		if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
+			sk->sk_err = err;
+	}
+
+	read_unlock(&l->lock);
+}
+
+static void l2cap_info_timeout(unsigned long arg)
+{
+	struct l2cap_conn *conn = (void *) arg;
+
+	conn->info_ident = 0;
+
+	l2cap_conn_start(conn);
+}
+
 static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
 {
 	struct l2cap_conn *conn = hcon->l2cap_data;
@@ -279,6 +393,12 @@
 	conn->src = &hcon->hdev->bdaddr;
 	conn->dst = &hcon->dst;
 
+	conn->feat_mask = 0;
+
+	init_timer(&conn->info_timer);
+	conn->info_timer.function = l2cap_info_timeout;
+	conn->info_timer.data = (unsigned long) conn;
+
 	spin_lock_init(&conn->lock);
 	rwlock_init(&conn->chan_list.lock);
 
@@ -318,40 +438,6 @@
 	write_unlock_bh(&l->lock);
 }
 
-static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
-{
-	u8 id;
-
-	/* Get next available identificator.
-	 *    1 - 128 are used by kernel.
-	 *  129 - 199 are reserved.
-	 *  200 - 254 are used by utilities like l2ping, etc.
-	 */
-
-	spin_lock_bh(&conn->lock);
-
-	if (++conn->tx_ident > 128)
-		conn->tx_ident = 1;
-
-	id = conn->tx_ident;
-
-	spin_unlock_bh(&conn->lock);
-
-	return id;
-}
-
-static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
-{
-	struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
-
-	BT_DBG("code 0x%2.2x", code);
-
-	if (!skb)
-		return -ENOMEM;
-
-	return hci_send_acl(conn->hcon, skb, 0);
-}
-
 /* ---- Socket interface ---- */
 static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
 {
@@ -508,7 +594,6 @@
 
 	/* Default config options */
 	pi->conf_len = 0;
-	pi->conf_mtu = L2CAP_DEFAULT_MTU;
 	pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
 }
 
@@ -530,7 +615,7 @@
 	INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
 
 	sk->sk_destruct = l2cap_sock_destruct;
-	sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
+	sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
 
 	sock_reset_flag(sk, SOCK_ZAPPED);
 
@@ -650,6 +735,11 @@
 	l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
 
 	if (hcon->state == BT_CONNECTED) {
+		if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)) {
+			l2cap_conn_ready(conn);
+			goto done;
+		}
+
 		if (sk->sk_type == SOCK_SEQPACKET) {
 			struct l2cap_conn_req req;
 			l2cap_pi(sk)->ident = l2cap_get_ident(conn);
@@ -958,7 +1048,7 @@
 		opts.imtu     = l2cap_pi(sk)->imtu;
 		opts.omtu     = l2cap_pi(sk)->omtu;
 		opts.flush_to = l2cap_pi(sk)->flush_to;
-		opts.mode     = 0x00;
+		opts.mode     = L2CAP_MODE_BASIC;
 
 		len = min_t(unsigned int, sizeof(opts), optlen);
 		if (copy_from_user((char *) &opts, optval, len)) {
@@ -1007,7 +1097,7 @@
 		opts.imtu     = l2cap_pi(sk)->imtu;
 		opts.omtu     = l2cap_pi(sk)->omtu;
 		opts.flush_to = l2cap_pi(sk)->flush_to;
-		opts.mode     = 0x00;
+		opts.mode     = L2CAP_MODE_BASIC;
 
 		len = min_t(unsigned int, len, sizeof(opts));
 		if (copy_to_user(optval, (char *) &opts, len))
@@ -1084,52 +1174,6 @@
 	return err;
 }
 
-static void l2cap_conn_ready(struct l2cap_conn *conn)
-{
-	struct l2cap_chan_list *l = &conn->chan_list;
-	struct sock *sk;
-
-	BT_DBG("conn %p", conn);
-
-	read_lock(&l->lock);
-
-	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-		bh_lock_sock(sk);
-
-		if (sk->sk_type != SOCK_SEQPACKET) {
-			l2cap_sock_clear_timer(sk);
-			sk->sk_state = BT_CONNECTED;
-			sk->sk_state_change(sk);
-		} else if (sk->sk_state == BT_CONNECT) {
-			struct l2cap_conn_req req;
-			l2cap_pi(sk)->ident = l2cap_get_ident(conn);
-			req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
-			req.psm  = l2cap_pi(sk)->psm;
-			l2cap_send_cmd(conn, l2cap_pi(sk)->ident, L2CAP_CONN_REQ, sizeof(req), &req);
-		}
-
-		bh_unlock_sock(sk);
-	}
-
-	read_unlock(&l->lock);
-}
-
-/* Notify sockets that we cannot guaranty reliability anymore */
-static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
-{
-	struct l2cap_chan_list *l = &conn->chan_list;
-	struct sock *sk;
-
-	BT_DBG("conn %p", conn);
-
-	read_lock(&l->lock);
-	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-		if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
-			sk->sk_err = err;
-	}
-	read_unlock(&l->lock);
-}
-
 static void l2cap_chan_ready(struct sock *sk)
 {
 	struct sock *parent = bt_sk(sk)->parent;
@@ -1256,11 +1300,11 @@
 		break;
 
 	case 2:
-		*val = __le16_to_cpu(*((__le16 *)opt->val));
+		*val = __le16_to_cpu(*((__le16 *) opt->val));
 		break;
 
 	case 4:
-		*val = __le32_to_cpu(*((__le32 *)opt->val));
+		*val = __le32_to_cpu(*((__le32 *) opt->val));
 		break;
 
 	default:
@@ -1332,6 +1376,8 @@
 	int len = pi->conf_len;
 	int type, hint, olen;
 	unsigned long val;
+	struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
+	u16 mtu = L2CAP_DEFAULT_MTU;
 	u16 result = L2CAP_CONF_SUCCESS;
 
 	BT_DBG("sk %p", sk);
@@ -1344,7 +1390,7 @@
 
 		switch (type) {
 		case L2CAP_CONF_MTU:
-			pi->conf_mtu = val;
+			mtu = val;
 			break;
 
 		case L2CAP_CONF_FLUSH_TO:
@@ -1354,6 +1400,11 @@
 		case L2CAP_CONF_QOS:
 			break;
 
+		case L2CAP_CONF_RFC:
+			if (olen == sizeof(rfc))
+				memcpy(&rfc, (void *) val, olen);
+			break;
+
 		default:
 			if (hint)
 				break;
@@ -1368,12 +1419,24 @@
 		/* Configure output options and let the other side know
 		 * which ones we don't like. */
 
-		if (pi->conf_mtu < pi->omtu)
-			result = L2CAP_CONF_UNACCEPT;
-		else
-			pi->omtu = pi->conf_mtu;
+		if (rfc.mode == L2CAP_MODE_BASIC) {
+			if (mtu < pi->omtu)
+				result = L2CAP_CONF_UNACCEPT;
+			else {
+				pi->omtu = mtu;
+				pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
+			}
 
-		l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+			l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+		} else {
+			result = L2CAP_CONF_UNACCEPT;
+
+			memset(&rfc, 0, sizeof(rfc));
+			rfc.mode = L2CAP_MODE_BASIC;
+
+			l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+						sizeof(rfc), (unsigned long) &rfc);
+		}
 	}
 
 	rsp->scid   = cpu_to_le16(pi->dcid);
@@ -1397,6 +1460,23 @@
 	return ptr - data;
 }
 
+static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+{
+	struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
+
+	if (rej->reason != 0x0000)
+		return 0;
+
+	if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
+					cmd->ident == conn->info_ident) {
+		conn->info_ident = 0;
+		del_timer(&conn->info_timer);
+		l2cap_conn_start(conn);
+	}
+
+	return 0;
+}
+
 static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
 {
 	struct l2cap_chan_list *list = &conn->chan_list;
@@ -1577,16 +1657,19 @@
 
 	l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
 
-	/* Output config done. */
-	l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
-
 	/* Reset config buffer. */
 	l2cap_pi(sk)->conf_len = 0;
 
+	if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
+		goto unlock;
+
 	if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
 		sk->sk_state = BT_CONNECTED;
 		l2cap_chan_ready(sk);
-	} else if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
+		goto unlock;
+	}
+
+	if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
 		u8 req[64];
 		l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
 					l2cap_build_conf_req(sk, req), req);
@@ -1646,7 +1729,6 @@
 	if (flags & 0x01)
 		goto done;
 
-	/* Input config done */
 	l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
 
 	if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
@@ -1711,16 +1793,27 @@
 static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
 {
 	struct l2cap_info_req *req = (struct l2cap_info_req *) data;
-	struct l2cap_info_rsp rsp;
 	u16 type;
 
 	type = __le16_to_cpu(req->type);
 
 	BT_DBG("type 0x%4.4x", type);
 
-	rsp.type   = cpu_to_le16(type);
-	rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
-	l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp), &rsp);
+	if (type == L2CAP_IT_FEAT_MASK) {
+		u8 buf[8];
+		struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
+		rsp->type   = cpu_to_le16(L2CAP_IT_FEAT_MASK);
+		rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
+		put_unaligned(cpu_to_le32(l2cap_feat_mask), (__le32 *) rsp->data);
+		l2cap_send_cmd(conn, cmd->ident,
+					L2CAP_INFO_RSP, sizeof(buf), buf);
+	} else {
+		struct l2cap_info_rsp rsp;
+		rsp.type   = cpu_to_le16(type);
+		rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
+		l2cap_send_cmd(conn, cmd->ident,
+					L2CAP_INFO_RSP, sizeof(rsp), &rsp);
+	}
 
 	return 0;
 }
@@ -1735,6 +1828,15 @@
 
 	BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
 
+	conn->info_ident = 0;
+
+	del_timer(&conn->info_timer);
+
+	if (type == L2CAP_IT_FEAT_MASK)
+		conn->feat_mask = __le32_to_cpu(get_unaligned((__le32 *) rsp->data));
+
+	l2cap_conn_start(conn);
+
 	return 0;
 }
 
@@ -1764,7 +1866,7 @@
 
 		switch (cmd.code) {
 		case L2CAP_COMMAND_REJ:
-			/* FIXME: We should process this */
+			l2cap_command_rej(conn, &cmd, data);
 			break;
 
 		case L2CAP_CONN_REQ:
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index bb722077..e7ac6ba 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -33,11 +33,11 @@
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/init.h>
-#include <linux/freezer.h>
 #include <linux/wait.h>
 #include <linux/device.h>
 #include <linux/net.h>
 #include <linux/mutex.h>
+#include <linux/kthread.h>
 
 #include <net/sock.h>
 #include <asm/uaccess.h>
@@ -68,7 +68,6 @@
 static unsigned long rfcomm_event;
 
 static LIST_HEAD(session_list);
-static atomic_t terminate, running;
 
 static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len);
 static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci);
@@ -1850,26 +1849,6 @@
 	rfcomm_unlock();
 }
 
-static void rfcomm_worker(void)
-{
-	BT_DBG("");
-
-	while (!atomic_read(&terminate)) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
-			/* No pending events. Let's sleep.
-			 * Incoming connections and data will wake us up. */
-			schedule();
-		}
-		set_current_state(TASK_RUNNING);
-
-		/* Process stuff */
-		clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
-		rfcomm_process_sessions();
-	}
-	return;
-}
-
 static int rfcomm_add_listener(bdaddr_t *ba)
 {
 	struct sockaddr_l2 addr;
@@ -1935,22 +1914,28 @@
 
 static int rfcomm_run(void *unused)
 {
-	rfcomm_thread = current;
-
-	atomic_inc(&running);
-
-	daemonize("krfcommd");
-	set_user_nice(current, -10);
-
 	BT_DBG("");
 
+	set_user_nice(current, -10);
+
 	rfcomm_add_listener(BDADDR_ANY);
 
-	rfcomm_worker();
+	while (!kthread_should_stop()) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
+			/* No pending events. Let's sleep.
+			 * Incoming connections and data will wake us up. */
+			schedule();
+		}
+		set_current_state(TASK_RUNNING);
+
+		/* Process stuff */
+		clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
+		rfcomm_process_sessions();
+	}
 
 	rfcomm_kill_listener();
 
-	atomic_dec(&running);
 	return 0;
 }
 
@@ -2059,7 +2044,11 @@
 
 	hci_register_cb(&rfcomm_cb);
 
-	kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
+	rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd");
+	if (IS_ERR(rfcomm_thread)) {
+		hci_unregister_cb(&rfcomm_cb);
+		return PTR_ERR(rfcomm_thread);
+	}
 
 	if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
 		BT_ERR("Failed to create RFCOMM info file");
@@ -2081,14 +2070,7 @@
 
 	hci_unregister_cb(&rfcomm_cb);
 
-	/* Terminate working thread.
-	 * ie. Set terminate flag and wake it up */
-	atomic_inc(&terminate);
-	rfcomm_schedule(RFCOMM_SCHED_STATE);
-
-	/* Wait until thread is running */
-	while (atomic_read(&running))
-		schedule();
+	kthread_stop(rfcomm_thread);
 
 #ifdef CONFIG_BT_RFCOMM_TTY
 	rfcomm_cleanup_ttys();
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 22a8320..e447651 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -189,6 +189,23 @@
 	return conn ? &conn->dev : NULL;
 }
 
+static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
+{
+	struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
+	bdaddr_t bdaddr;
+	baswap(&bdaddr, &dev->dst);
+	return sprintf(buf, "%s\n", batostr(&bdaddr));
+}
+
+static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
+{
+	struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
+	return sprintf(buf, "%d\n", dev->channel);
+}
+
+static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
+static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
+
 static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
 {
 	struct rfcomm_dev *dev;
@@ -281,6 +298,14 @@
 		return err;
 	}
 
+	dev_set_drvdata(dev->tty_dev, dev);
+
+	if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
+		BT_ERR("Failed to create address attribute");
+
+	if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0)
+		BT_ERR("Failed to create channel attribute");
+
 	return dev->id;
 }
 
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 65b6fb1..82d0dfdf 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -189,7 +189,7 @@
 	struct sco_conn *conn;
 	struct hci_conn *hcon;
 	struct hci_dev  *hdev;
-	int err = 0;
+	int err, type;
 
 	BT_DBG("%s -> %s", batostr(src), batostr(dst));
 
@@ -200,7 +200,9 @@
 
 	err = -ENOMEM;
 
-	hcon = hci_connect(hdev, SCO_LINK, dst);
+	type = lmp_esco_capable(hdev) ? ESCO_LINK : SCO_LINK;
+
+	hcon = hci_connect(hdev, type, dst);
 	if (!hcon)
 		goto done;
 
@@ -224,6 +226,7 @@
 		sk->sk_state = BT_CONNECT;
 		sco_sock_set_timer(sk, sk->sk_sndtimeo);
 	}
+
 done:
 	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
@@ -846,7 +849,7 @@
 {
 	BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
 
-	if (hcon->type != SCO_LINK)
+	if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
 		return 0;
 
 	if (!status) {
@@ -865,10 +868,11 @@
 {
 	BT_DBG("hcon %p reason %d", hcon, reason);
 
-	if (hcon->type != SCO_LINK)
+	if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
 		return 0;
 
 	sco_conn_del(hcon, bt_err(reason));
+
 	return 0;
 }
 
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index d5a09ea..817169e 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -871,7 +871,7 @@
 				return -EINVAL;
 			}
 
-	/* we now know the following (along with E=mc²):
+	/* we now know the following (along with E=mc²):
 	   - the nr of entries in each chain is right
 	   - the size of the allocated space is right
 	   - all valid hooks have a corresponding chain
diff --git a/net/core/dev.c b/net/core/dev.c
index 38b03da..8726589 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1553,7 +1553,7 @@
 			return rc;
 		}
 		if (unlikely((netif_queue_stopped(dev) ||
-			     netif_subqueue_stopped(dev, skb->queue_mapping)) &&
+			     netif_subqueue_stopped(dev, skb)) &&
 			     skb->next))
 			return NETDEV_TX_BUSY;
 	} while (skb->next);
@@ -1661,7 +1661,7 @@
 		q = dev->qdisc;
 		if (q->enqueue) {
 			/* reset queue_mapping to zero */
-			skb->queue_mapping = 0;
+			skb_set_queue_mapping(skb, 0);
 			rc = q->enqueue(skb, q);
 			qdisc_run(dev);
 			spin_unlock(&dev->queue_lock);
@@ -1692,7 +1692,7 @@
 			HARD_TX_LOCK(dev, cpu);
 
 			if (!netif_queue_stopped(dev) &&
-			    !netif_subqueue_stopped(dev, skb->queue_mapping)) {
+			    !netif_subqueue_stopped(dev, skb)) {
 				rc = 0;
 				if (!dev_hard_start_xmit(skb, dev)) {
 					HARD_TX_UNLOCK(dev);
diff --git a/net/core/filter.c b/net/core/filter.c
index bd903aa..e0a0694 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -387,6 +387,25 @@
 }
 
 /**
+ * 	sk_filter_rcu_release: Release a socket filter by rcu_head
+ *	@rcu: rcu_head that contains the sk_filter to free
+ */
+static void sk_filter_rcu_release(struct rcu_head *rcu)
+{
+	struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
+
+	sk_filter_release(fp);
+}
+
+static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp)
+{
+	unsigned int size = sk_filter_len(fp);
+
+	atomic_sub(size, &sk->sk_omem_alloc);
+	call_rcu_bh(&fp->rcu, sk_filter_rcu_release);
+}
+
+/**
  *	sk_attach_filter - attach a socket filter
  *	@fprog: the filter program
  *	@sk: the socket to use
@@ -398,7 +417,7 @@
  */
 int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
 {
-	struct sk_filter *fp;
+	struct sk_filter *fp, *old_fp;
 	unsigned int fsize = sizeof(struct sock_filter) * fprog->len;
 	int err;
 
@@ -418,19 +437,35 @@
 	fp->len = fprog->len;
 
 	err = sk_chk_filter(fp->insns, fp->len);
-	if (!err) {
-		struct sk_filter *old_fp;
-
-		rcu_read_lock_bh();
-		old_fp = rcu_dereference(sk->sk_filter);
-		rcu_assign_pointer(sk->sk_filter, fp);
-		rcu_read_unlock_bh();
-		fp = old_fp;
+	if (err) {
+		sk_filter_uncharge(sk, fp);
+		return err;
 	}
 
-	if (fp)
-		sk_filter_release(sk, fp);
-	return err;
+	rcu_read_lock_bh();
+	old_fp = rcu_dereference(sk->sk_filter);
+	rcu_assign_pointer(sk->sk_filter, fp);
+	rcu_read_unlock_bh();
+
+	if (old_fp)
+		sk_filter_delayed_uncharge(sk, old_fp);
+	return 0;
+}
+
+int sk_detach_filter(struct sock *sk)
+{
+	int ret = -ENOENT;
+	struct sk_filter *filter;
+
+	rcu_read_lock_bh();
+	filter = rcu_dereference(sk->sk_filter);
+	if (filter) {
+		rcu_assign_pointer(sk->sk_filter, NULL);
+		sk_filter_delayed_uncharge(sk, filter);
+		ret = 0;
+	}
+	rcu_read_unlock_bh();
+	return ret;
 }
 
 EXPORT_SYMBOL(sk_chk_filter);
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
index 590a767..daadbcc 100644
--- a/net/core/gen_estimator.c
+++ b/net/core/gen_estimator.c
@@ -15,7 +15,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index cd3af59..05979e3 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1438,6 +1438,9 @@
 	free_percpu(tbl->stats);
 	tbl->stats = NULL;
 
+	kmem_cache_destroy(tbl->kmem_cachep);
+	tbl->kmem_cachep = NULL;
+
 	return 0;
 }
 
@@ -2496,7 +2499,6 @@
 			.proc_handler	= &proc_dointvec,
 		},
 		{
-			.ctl_name	= NET_NEIGH_RETRANS_TIME,
 			.procname	= "retrans_time",
 			.maxlen		= sizeof(int),
 			.mode		= 0644,
@@ -2541,27 +2543,40 @@
 			.proc_handler	= &proc_dointvec,
 		},
 		{
-			.ctl_name	= NET_NEIGH_ANYCAST_DELAY,
 			.procname	= "anycast_delay",
 			.maxlen		= sizeof(int),
 			.mode		= 0644,
 			.proc_handler	= &proc_dointvec_userhz_jiffies,
 		},
 		{
-			.ctl_name	= NET_NEIGH_PROXY_DELAY,
 			.procname	= "proxy_delay",
 			.maxlen		= sizeof(int),
 			.mode		= 0644,
 			.proc_handler	= &proc_dointvec_userhz_jiffies,
 		},
 		{
-			.ctl_name	= NET_NEIGH_LOCKTIME,
 			.procname	= "locktime",
 			.maxlen		= sizeof(int),
 			.mode		= 0644,
 			.proc_handler	= &proc_dointvec_userhz_jiffies,
 		},
 		{
+			.ctl_name	= NET_NEIGH_RETRANS_TIME_MS,
+			.procname	= "retrans_time_ms",
+			.maxlen		= sizeof(int),
+			.mode		= 0644,
+			.proc_handler	= &proc_dointvec_ms_jiffies,
+			.strategy	= &sysctl_ms_jiffies,
+		},
+		{
+			.ctl_name	= NET_NEIGH_REACHABLE_TIME_MS,
+			.procname	= "base_reachable_time_ms",
+			.maxlen		= sizeof(int),
+			.mode		= 0644,
+			.proc_handler	= &proc_dointvec_ms_jiffies,
+			.strategy	= &sysctl_ms_jiffies,
+		},
+		{
 			.ctl_name	= NET_NEIGH_GC_INTERVAL,
 			.procname	= "gc_interval",
 			.maxlen		= sizeof(int),
@@ -2590,22 +2605,7 @@
 			.mode		= 0644,
 			.proc_handler	= &proc_dointvec,
 		},
-		{
-			.ctl_name	= NET_NEIGH_RETRANS_TIME_MS,
-			.procname	= "retrans_time_ms",
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= &proc_dointvec_ms_jiffies,
-			.strategy	= &sysctl_ms_jiffies,
-		},
-		{
-			.ctl_name	= NET_NEIGH_REACHABLE_TIME_MS,
-			.procname	= "base_reachable_time_ms",
-			.maxlen		= sizeof(int),
-			.mode		= 0644,
-			.proc_handler	= &proc_dointvec_ms_jiffies,
-			.strategy	= &sysctl_ms_jiffies,
-		},
+		{}
 	},
 	.neigh_dev = {
 		{
@@ -2658,42 +2658,48 @@
 	t->neigh_vars[9].data  = &p->anycast_delay;
 	t->neigh_vars[10].data = &p->proxy_delay;
 	t->neigh_vars[11].data = &p->locktime;
+	t->neigh_vars[12].data  = &p->retrans_time;
+	t->neigh_vars[13].data  = &p->base_reachable_time;
 
 	if (dev) {
 		dev_name_source = dev->name;
 		t->neigh_dev[0].ctl_name = dev->ifindex;
-		t->neigh_vars[12].procname = NULL;
-		t->neigh_vars[13].procname = NULL;
-		t->neigh_vars[14].procname = NULL;
-		t->neigh_vars[15].procname = NULL;
+		/* Terminate the table early */
+		memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14]));
 	} else {
 		dev_name_source = t->neigh_dev[0].procname;
-		t->neigh_vars[12].data = (int *)(p + 1);
-		t->neigh_vars[13].data = (int *)(p + 1) + 1;
-		t->neigh_vars[14].data = (int *)(p + 1) + 2;
-		t->neigh_vars[15].data = (int *)(p + 1) + 3;
+		t->neigh_vars[14].data = (int *)(p + 1);
+		t->neigh_vars[15].data = (int *)(p + 1) + 1;
+		t->neigh_vars[16].data = (int *)(p + 1) + 2;
+		t->neigh_vars[17].data = (int *)(p + 1) + 3;
 	}
 
-	t->neigh_vars[16].data  = &p->retrans_time;
-	t->neigh_vars[17].data  = &p->base_reachable_time;
 
 	if (handler || strategy) {
 		/* RetransTime */
 		t->neigh_vars[3].proc_handler = handler;
 		t->neigh_vars[3].strategy = strategy;
 		t->neigh_vars[3].extra1 = dev;
+		if (!strategy)
+			t->neigh_vars[3].ctl_name = CTL_UNNUMBERED;
 		/* ReachableTime */
 		t->neigh_vars[4].proc_handler = handler;
 		t->neigh_vars[4].strategy = strategy;
 		t->neigh_vars[4].extra1 = dev;
+		if (!strategy)
+			t->neigh_vars[4].ctl_name = CTL_UNNUMBERED;
 		/* RetransTime (in milliseconds)*/
-		t->neigh_vars[16].proc_handler = handler;
-		t->neigh_vars[16].strategy = strategy;
-		t->neigh_vars[16].extra1 = dev;
+		t->neigh_vars[12].proc_handler = handler;
+		t->neigh_vars[12].strategy = strategy;
+		t->neigh_vars[12].extra1 = dev;
+		if (!strategy)
+			t->neigh_vars[12].ctl_name = CTL_UNNUMBERED;
 		/* ReachableTime (in milliseconds) */
-		t->neigh_vars[17].proc_handler = handler;
-		t->neigh_vars[17].strategy = strategy;
-		t->neigh_vars[17].extra1 = dev;
+		t->neigh_vars[13].proc_handler = handler;
+		t->neigh_vars[13].strategy = strategy;
+		t->neigh_vars[13].extra1 = dev;
+		if (!strategy)
+			t->neigh_vars[13].ctl_name = CTL_UNNUMBERED;
 	}
 
 	dev_name = kstrdup(dev_name_source, GFP_KERNEL);
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 95daba6..bf8d18f 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -67,7 +67,7 @@
 		local_irq_save(flags);
 		netif_tx_lock(dev);
 		if ((netif_queue_stopped(dev) ||
-		     netif_subqueue_stopped(dev, skb->queue_mapping)) ||
+		     netif_subqueue_stopped(dev, skb)) ||
 		     dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
 			skb_queue_head(&npinfo->txq, skb);
 			netif_tx_unlock(dev);
@@ -269,7 +269,7 @@
 		     tries > 0; --tries) {
 			if (netif_tx_trylock(dev)) {
 				if (!netif_queue_stopped(dev) &&
-				    !netif_subqueue_stopped(dev, skb->queue_mapping))
+				    !netif_subqueue_stopped(dev, skb))
 					status = dev->hard_start_xmit(skb, dev);
 				netif_tx_unlock(dev);
 
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 2100c73..de33f36 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -6,7 +6,7 @@
  *
  * Alexey Kuznetsov  <kuznet@ms2.inr.ac.ru>
  * Ben Greear <greearb@candelatech.com>
- * Jens Låås <jens.laas@data.slu.se>
+ * Jens Låås <jens.laas@data.slu.se>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -161,7 +161,7 @@
 #endif
 #include <asm/byteorder.h>
 #include <linux/rcupdate.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
@@ -2454,7 +2454,7 @@
 	spin_lock(&x->lock);
 	iph = ip_hdr(skb);
 
-	err = x->mode->output(x, skb);
+	err = x->outer_mode->output(x, skb);
 	if (err)
 		goto error;
 	err = x->type->output(x, skb);
@@ -2603,8 +2603,7 @@
 	skb->network_header = skb->tail;
 	skb->transport_header = skb->network_header + sizeof(struct iphdr);
 	skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr));
-	skb->queue_mapping = pkt_dev->cur_queue_map;
-
+	skb_set_queue_mapping(skb, pkt_dev->cur_queue_map);
 	iph = ip_hdr(skb);
 	udph = udp_hdr(skb);
 
@@ -2941,8 +2940,7 @@
 	skb->network_header = skb->tail;
 	skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
 	skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr));
-	skb->queue_mapping = pkt_dev->cur_queue_map;
-
+	skb_set_queue_mapping(skb, pkt_dev->cur_queue_map);
 	iph = ipv6_hdr(skb);
 	udph = udp_hdr(skb);
 
@@ -3385,7 +3383,7 @@
 
 	if ((netif_queue_stopped(odev) ||
 	     (pkt_dev->skb &&
-	      netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping))) ||
+	      netif_subqueue_stopped(odev, pkt_dev->skb))) ||
 	    need_resched()) {
 		idle_start = getCurUs();
 
@@ -3402,7 +3400,7 @@
 		pkt_dev->idle_acc += getCurUs() - idle_start;
 
 		if (netif_queue_stopped(odev) ||
-		    netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) {
+		    netif_subqueue_stopped(odev, pkt_dev->skb)) {
 			pkt_dev->next_tx_us = getCurUs();	/* TODO */
 			pkt_dev->next_tx_ns = 0;
 			goto out;	/* Try the next interface */
@@ -3431,7 +3429,7 @@
 
 	netif_tx_lock_bh(odev);
 	if (!netif_queue_stopped(odev) &&
-	    !netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) {
+	    !netif_subqueue_stopped(odev, pkt_dev->skb)) {
 
 		atomic_inc(&(pkt_dev->skb->users));
 	      retry_now:
@@ -3514,7 +3512,7 @@
 
 	init_waitqueue_head(&t->queue);
 
-	pr_debug("pktgen: starting pktgen/%d:  pid=%d\n", cpu, current->pid);
+	pr_debug("pktgen: starting pktgen/%d:  pid=%d\n", cpu, task_pid_nr(current));
 
 	set_current_state(TASK_INTERRUPTIBLE);
 
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 1072d16..4a2640d 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -744,10 +744,10 @@
 	rcu_read_lock();
 	tsk = find_task_by_pid(pid);
 	if (tsk) {
-		task_lock(tsk);
-		if (tsk->nsproxy)
-			net = get_net(tsk->nsproxy->net_ns);
-		task_unlock(tsk);
+		struct nsproxy *nsproxy;
+		nsproxy = task_nsproxy(tsk);
+		if (nsproxy)
+			net = get_net(nsproxy->net_ns);
 	}
 	rcu_read_unlock();
 	return net;
diff --git a/net/core/scm.c b/net/core/scm.c
index 530bee8..100ba6d 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -24,6 +24,8 @@
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/security.h>
+#include <linux/pid.h>
+#include <linux/nsproxy.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -42,7 +44,7 @@
 
 static __inline__ int scm_check_creds(struct ucred *creds)
 {
-	if ((creds->pid == current->tgid || capable(CAP_SYS_ADMIN)) &&
+	if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) &&
 	    ((creds->uid == current->uid || creds->uid == current->euid ||
 	      creds->uid == current->suid) || capable(CAP_SETUID)) &&
 	    ((creds->gid == current->gid || creds->gid == current->egid ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 70d9b5d..4e2c84f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2045,7 +2045,7 @@
 	if (copy > 0) {
 		if (copy > len)
 			copy = len;
-		sg[elt].page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg[elt], virt_to_page(skb->data + offset));
 		sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg[elt].length = copy;
 		elt++;
@@ -2065,7 +2065,7 @@
 
 			if (copy > len)
 				copy = len;
-			sg[elt].page = frag->page;
+			sg_set_page(&sg[elt], frag->page);
 			sg[elt].offset = frag->page_offset+offset-start;
 			sg[elt].length = copy;
 			elt++;
diff --git a/net/core/sock.c b/net/core/sock.c
index d45ecdc..febbcbc 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -232,7 +232,7 @@
 			warned++;
 			printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) "
 			       "tries to set negative timeout\n",
-				current->comm, current->pid);
+				current->comm, task_pid_nr(current));
 		return 0;
 	}
 	*timeo_p = MAX_SCHEDULE_TIMEOUT;
@@ -428,7 +428,6 @@
 		    char __user *optval, int optlen)
 {
 	struct sock *sk=sock->sk;
-	struct sk_filter *filter;
 	int val;
 	int valbool;
 	struct linger ling;
@@ -652,16 +651,7 @@
 		break;
 
 	case SO_DETACH_FILTER:
-		rcu_read_lock_bh();
-		filter = rcu_dereference(sk->sk_filter);
-		if (filter) {
-			rcu_assign_pointer(sk->sk_filter, NULL);
-			sk_filter_release(sk, filter);
-			rcu_read_unlock_bh();
-			break;
-		}
-		rcu_read_unlock_bh();
-		ret = -ENONET;
+		ret = sk_detach_filter(sk);
 		break;
 
 	case SO_PASSSEC:
@@ -925,7 +915,7 @@
 
 	filter = rcu_dereference(sk->sk_filter);
 	if (filter) {
-		sk_filter_release(sk, filter);
+		sk_filter_uncharge(sk, filter);
 		rcu_assign_pointer(sk->sk_filter, NULL);
 	}
 
diff --git a/net/dccp/diag.c b/net/dccp/diag.c
index 0f37455..d8a3509 100644
--- a/net/dccp/diag.c
+++ b/net/dccp/diag.c
@@ -68,3 +68,4 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
 MODULE_DESCRIPTION("DCCP inet_diag handler");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_INET_DIAG, DCCPDIAG_GETSOCK);
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 19d7e1d..3560a2a 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -19,6 +19,9 @@
 #include "ccid.h"
 #include "dccp.h"
 
+/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */
+int sysctl_dccp_sync_ratelimit	__read_mostly = HZ / 8;
+
 static void dccp_fin(struct sock *sk, struct sk_buff *skb)
 {
 	sk->sk_shutdown |= RCV_SHUTDOWN;
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 44f6e17..222549a 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1037,8 +1037,8 @@
  * values directly, Also cover the case where the protocol is not specified,
  * i.e. net-pf-PF_INET-proto-0-type-SOCK_DCCP
  */
-MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-33-type-6");
-MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-0-type-6");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 33, 6);
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 0, 6);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
 MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol");
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index cac5354..bbadd66 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -1219,8 +1219,8 @@
  * values directly, Also cover the case where the protocol is not specified,
  * i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP
  */
-MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-33-type-6");
-MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-0-type-6");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 33, 6);
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 0, 6);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
 MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol");
diff --git a/net/dccp/sysctl.c b/net/dccp/sysctl.c
index 9364b2f..c62c050 100644
--- a/net/dccp/sysctl.c
+++ b/net/dccp/sysctl.c
@@ -18,9 +18,6 @@
 #error This file should not be compiled without CONFIG_SYSCTL defined
 #endif
 
-/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */
-int sysctl_dccp_sync_ratelimit	__read_mostly = HZ / 8;
-
 static struct ctl_table dccp_default_table[] = {
 	{
 		.procname	= "seq_window",
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 6cc54ee..8117776 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/random.h>
+#include <linux/scatterlist.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/mm.h>
@@ -390,9 +391,7 @@
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
+	sg_init_one(&sg, pos, len + 4);
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -485,9 +484,7 @@
 	plen = skb->len - hdr_len - 12;
 
 	crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG ": TKIP: failed to decrypt "
@@ -539,11 +536,12 @@
 		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
 		return -1;
 	}
-	sg[0].page = virt_to_page(hdr);
+	sg_init_table(sg, 2);
+	sg_set_page(&sg[0], virt_to_page(hdr));
 	sg[0].offset = offset_in_page(hdr);
 	sg[0].length = 16;
 
-	sg[1].page = virt_to_page(data);
+	sg_set_page(&sg[1], virt_to_page(data));
 	sg[1].offset = offset_in_page(data);
 	sg[1].length = data_len;
 
@@ -586,7 +584,7 @@
 	if (stype & IEEE80211_STYPE_QOS_DATA) {
 		const struct ieee80211_hdr_3addrqos *qoshdr =
 			(struct ieee80211_hdr_3addrqos *)skb->data;
-		hdr[12] = qoshdr->qos_ctl & cpu_to_le16(IEEE80211_QCTL_TID);
+		hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID;
 	} else
 		hdr[12] = 0;		/* priority */
 
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 8d18245..9693429 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/random.h>
+#include <linux/scatterlist.h>
 #include <linux/skbuff.h>
 #include <linux/mm.h>
 #include <asm/string.h>
@@ -170,9 +171,7 @@
 	icv[3] = crc >> 24;
 
 	crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
+	sg_init_one(&sg, pos, len + 4);
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
 }
 
@@ -212,9 +211,7 @@
 	plen = skb->len - hdr_len - 8;
 
 	crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
 		return -7;
 
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 9b58dd6..d309e8f 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -409,7 +409,7 @@
 					       (*crypt)->priv);
 		sec.flags |= (1 << key);
 		/* This ensures a key will be activated if no key is
-		 * explicitely set */
+		 * explicitly set */
 		if (key == sec.active_key)
 			sec.flags |= SEC_ACTIVE_KEY;
 
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index d894f61..9f9fd2c 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -560,7 +560,7 @@
 	depends on EXPERIMENTAL
 	default n
 	---help---
-	TCP-Illinois is a sender-side modificatio of TCP Reno for
+	TCP-Illinois is a sender-side modification of TCP Reno for
 	high speed long delay links. It uses round-trip-time to
 	adjust the alpha and beta parameters to achieve a higher average
 	throughput and maintain fairness.
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 81a8285..8d8c291 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -54,7 +54,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 3cef128..8fb6ca2 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -93,7 +93,7 @@
 		int remaining, rover, low, high;
 
 		inet_get_local_port_range(&low, &high);
-		remaining = high - low;
+		remaining = (high - low) + 1;
 		rover = net_random() % remaining + low;
 
 		do {
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 7eb83eb..dc429b6 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -815,6 +815,12 @@
 	    nlmsg_len(nlh) < hdrlen)
 		return -EINVAL;
 
+#ifdef CONFIG_KMOD
+	if (inet_diag_table[nlh->nlmsg_type] == NULL)
+		request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
+			       NETLINK_INET_DIAG, nlh->nlmsg_type);
+#endif
+
 	if (inet_diag_table[nlh->nlmsg_type] == NULL)
 		return -ENOENT;
 
@@ -914,3 +920,4 @@
 module_init(inet_diag_init);
 module_exit(inet_diag_exit);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_INET_DIAG);
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 484cf51..e15e04f 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -136,7 +136,9 @@
 		*work -= f->qsize;
 	atomic_sub(f->qsize, &f->mem);
 
-	f->destructor(q);
+	if (f->destructor)
+		f->destructor(q);
+	kfree(q);
 
 }
 EXPORT_SYMBOL(inet_frag_destroy);
@@ -172,3 +174,88 @@
 	return evicted;
 }
 EXPORT_SYMBOL(inet_frag_evictor);
+
+static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
+		struct inet_frags *f, unsigned int hash, void *arg)
+{
+	struct inet_frag_queue *qp;
+#ifdef CONFIG_SMP
+	struct hlist_node *n;
+#endif
+
+	write_lock(&f->lock);
+#ifdef CONFIG_SMP
+	/* With SMP race we have to recheck hash table, because
+	 * such entry could be created on other cpu, while we
+	 * promoted read lock to write lock.
+	 */
+	hlist_for_each_entry(qp, n, &f->hash[hash], list) {
+		if (f->match(qp, arg)) {
+			atomic_inc(&qp->refcnt);
+			write_unlock(&f->lock);
+			qp_in->last_in |= COMPLETE;
+			inet_frag_put(qp_in, f);
+			return qp;
+		}
+	}
+#endif
+	qp = qp_in;
+	if (!mod_timer(&qp->timer, jiffies + f->ctl->timeout))
+		atomic_inc(&qp->refcnt);
+
+	atomic_inc(&qp->refcnt);
+	hlist_add_head(&qp->list, &f->hash[hash]);
+	list_add_tail(&qp->lru_list, &f->lru_list);
+	f->nqueues++;
+	write_unlock(&f->lock);
+	return qp;
+}
+
+static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg)
+{
+	struct inet_frag_queue *q;
+
+	q = kzalloc(f->qsize, GFP_ATOMIC);
+	if (q == NULL)
+		return NULL;
+
+	f->constructor(q, arg);
+	atomic_add(f->qsize, &f->mem);
+	setup_timer(&q->timer, f->frag_expire, (unsigned long)q);
+	spin_lock_init(&q->lock);
+	atomic_set(&q->refcnt, 1);
+
+	return q;
+}
+
+static struct inet_frag_queue *inet_frag_create(struct inet_frags *f,
+		void *arg, unsigned int hash)
+{
+	struct inet_frag_queue *q;
+
+	q = inet_frag_alloc(f, arg);
+	if (q == NULL)
+		return NULL;
+
+	return inet_frag_intern(q, f, hash, arg);
+}
+
+struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key,
+		unsigned int hash)
+{
+	struct inet_frag_queue *q;
+	struct hlist_node *n;
+
+	read_lock(&f->lock);
+	hlist_for_each_entry(q, n, &f->hash[hash], list) {
+		if (f->match(q, key)) {
+			atomic_inc(&q->refcnt);
+			read_unlock(&f->lock);
+			return q;
+		}
+	}
+	read_unlock(&f->lock);
+
+	return inet_frag_create(f, key, hash);
+}
+EXPORT_SYMBOL(inet_frag_find);
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index fac6398..16eecc7 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -286,7 +286,7 @@
 		struct inet_timewait_sock *tw = NULL;
 
 		inet_get_local_port_range(&low, &high);
-		remaining = high - low;
+		remaining = (high - low) + 1;
 
 		local_bh_disable();
 		for (i = 1; i <= remaining; i++) {
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 443b3f8..2143bf3 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -108,6 +108,11 @@
 static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
 			 struct net_device *dev);
 
+struct ip4_create_arg {
+	struct iphdr *iph;
+	u32 user;
+};
+
 static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
 {
 	return jhash_3words((__force u32)id << 16 | prot,
@@ -123,6 +128,19 @@
 	return ipqhashfn(ipq->id, ipq->saddr, ipq->daddr, ipq->protocol);
 }
 
+static int ip4_frag_match(struct inet_frag_queue *q, void *a)
+{
+	struct ipq *qp;
+	struct ip4_create_arg *arg = a;
+
+	qp = container_of(q, struct ipq, q);
+	return (qp->id == arg->iph->id &&
+			qp->saddr == arg->iph->saddr &&
+			qp->daddr == arg->iph->daddr &&
+			qp->protocol == arg->iph->protocol &&
+			qp->user == arg->user);
+}
+
 /* Memory Tracking Functions. */
 static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
 {
@@ -132,6 +150,20 @@
 	kfree_skb(skb);
 }
 
+static void ip4_frag_init(struct inet_frag_queue *q, void *a)
+{
+	struct ipq *qp = container_of(q, struct ipq, q);
+	struct ip4_create_arg *arg = a;
+
+	qp->protocol = arg->iph->protocol;
+	qp->id = arg->iph->id;
+	qp->saddr = arg->iph->saddr;
+	qp->daddr = arg->iph->daddr;
+	qp->user = arg->user;
+	qp->peer = sysctl_ipfrag_max_dist ?
+		inet_getpeer(arg->iph->saddr, 1) : NULL;
+}
+
 static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
 {
 	struct ipq *qp;
@@ -139,17 +171,6 @@
 	qp = container_of(q, struct ipq, q);
 	if (qp->peer)
 		inet_putpeer(qp->peer);
-	kfree(qp);
-}
-
-static __inline__ struct ipq *frag_alloc_queue(void)
-{
-	struct ipq *qp = kzalloc(sizeof(struct ipq), GFP_ATOMIC);
-
-	if (!qp)
-		return NULL;
-	atomic_add(sizeof(struct ipq), &ip4_frags.mem);
-	return qp;
 }
 
 
@@ -185,7 +206,9 @@
  */
 static void ip_expire(unsigned long arg)
 {
-	struct ipq *qp = (struct ipq *) arg;
+	struct ipq *qp;
+
+	qp = container_of((struct inet_frag_queue *) arg, struct ipq, q);
 
 	spin_lock(&qp->q.lock);
 
@@ -210,110 +233,28 @@
 	ipq_put(qp);
 }
 
-/* Creation primitives. */
-
-static struct ipq *ip_frag_intern(struct ipq *qp_in)
-{
-	struct ipq *qp;
-#ifdef CONFIG_SMP
-	struct hlist_node *n;
-#endif
-	unsigned int hash;
-
-	write_lock(&ip4_frags.lock);
-	hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr,
-			 qp_in->protocol);
-#ifdef CONFIG_SMP
-	/* With SMP race we have to recheck hash table, because
-	 * such entry could be created on other cpu, while we
-	 * promoted read lock to write lock.
-	 */
-	hlist_for_each_entry(qp, n, &ip4_frags.hash[hash], q.list) {
-		if (qp->id == qp_in->id		&&
-		    qp->saddr == qp_in->saddr	&&
-		    qp->daddr == qp_in->daddr	&&
-		    qp->protocol == qp_in->protocol &&
-		    qp->user == qp_in->user) {
-			atomic_inc(&qp->q.refcnt);
-			write_unlock(&ip4_frags.lock);
-			qp_in->q.last_in |= COMPLETE;
-			ipq_put(qp_in);
-			return qp;
-		}
-	}
-#endif
-	qp = qp_in;
-
-	if (!mod_timer(&qp->q.timer, jiffies + ip4_frags_ctl.timeout))
-		atomic_inc(&qp->q.refcnt);
-
-	atomic_inc(&qp->q.refcnt);
-	hlist_add_head(&qp->q.list, &ip4_frags.hash[hash]);
-	INIT_LIST_HEAD(&qp->q.lru_list);
-	list_add_tail(&qp->q.lru_list, &ip4_frags.lru_list);
-	ip4_frags.nqueues++;
-	write_unlock(&ip4_frags.lock);
-	return qp;
-}
-
-/* Add an entry to the 'ipq' queue for a newly received IP datagram. */
-static struct ipq *ip_frag_create(struct iphdr *iph, u32 user)
-{
-	struct ipq *qp;
-
-	if ((qp = frag_alloc_queue()) == NULL)
-		goto out_nomem;
-
-	qp->protocol = iph->protocol;
-	qp->id = iph->id;
-	qp->saddr = iph->saddr;
-	qp->daddr = iph->daddr;
-	qp->user = user;
-	qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
-
-	/* Initialize a timer for this entry. */
-	init_timer(&qp->q.timer);
-	qp->q.timer.data = (unsigned long) qp;	/* pointer to queue	*/
-	qp->q.timer.function = ip_expire;		/* expire function	*/
-	spin_lock_init(&qp->q.lock);
-	atomic_set(&qp->q.refcnt, 1);
-
-	return ip_frag_intern(qp);
-
-out_nomem:
-	LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
-	return NULL;
-}
-
 /* Find the correct entry in the "incomplete datagrams" queue for
  * this IP datagram, and create new one, if nothing is found.
  */
 static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
 {
-	__be16 id = iph->id;
-	__be32 saddr = iph->saddr;
-	__be32 daddr = iph->daddr;
-	__u8 protocol = iph->protocol;
+	struct inet_frag_queue *q;
+	struct ip4_create_arg arg;
 	unsigned int hash;
-	struct ipq *qp;
-	struct hlist_node *n;
 
-	read_lock(&ip4_frags.lock);
-	hash = ipqhashfn(id, saddr, daddr, protocol);
-	hlist_for_each_entry(qp, n, &ip4_frags.hash[hash], q.list) {
-		if (qp->id == id		&&
-		    qp->saddr == saddr	&&
-		    qp->daddr == daddr	&&
-		    qp->protocol == protocol &&
-		    qp->user == user) {
-			atomic_inc(&qp->q.refcnt);
-			read_unlock(&ip4_frags.lock);
-			return qp;
-		}
-	}
-	read_unlock(&ip4_frags.lock);
+	arg.iph = iph;
+	arg.user = user;
+	hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
 
-	return ip_frag_create(iph, user);
+	q = inet_frag_find(&ip4_frags, &arg, hash);
+	if (q == NULL)
+		goto out_nomem;
+
+	return container_of(q, struct ipq, q);
+
+out_nomem:
+	LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
+	return NULL;
 }
 
 /* Is the fragment too far ahead to be part of ipq? */
@@ -545,7 +486,6 @@
 	if (prev) {
 		head = prev->next;
 		fp = skb_clone(head, GFP_ATOMIC);
-
 		if (!fp)
 			goto out_nomem;
 
@@ -571,7 +511,6 @@
 		goto out_oversize;
 
 	/* Head of list must not be cloned. */
-	err = -ENOMEM;
 	if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC))
 		goto out_nomem;
 
@@ -627,6 +566,7 @@
 out_nomem:
 	LIMIT_NETDEBUG(KERN_ERR "IP: queue_glue: no memory for gluing "
 			      "queue %p\n", qp);
+	err = -ENOMEM;
 	goto out_fail;
 out_oversize:
 	if (net_ratelimit())
@@ -671,9 +611,12 @@
 {
 	ip4_frags.ctl = &ip4_frags_ctl;
 	ip4_frags.hashfn = ip4_hashfn;
+	ip4_frags.constructor = ip4_frag_init;
 	ip4_frags.destructor = ip4_frag_free;
 	ip4_frags.skb_free = NULL;
 	ip4_frags.qsize = sizeof(struct ipq);
+	ip4_frags.match = ip4_frag_match;
+	ip4_frags.frag_expire = ip_expire;
 	inet_frags_init(&ip4_frags);
 }
 
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 1960747..c99f2a3 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -794,7 +794,7 @@
 
 	add_wait_queue(&sync_wait, &wait);
 
-	set_sync_pid(state, current->pid);
+	set_sync_pid(state, task_pid_nr(current));
 	complete(tinfo->startup);
 
 	/*
@@ -877,7 +877,7 @@
 	if (!tinfo)
 		return -ENOMEM;
 
-	IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid);
+	IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, task_pid_nr(current));
 	IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %Zd bytes\n",
 		  sizeof(struct ip_vs_sync_conn));
 
@@ -917,7 +917,7 @@
 	    (state == IP_VS_STATE_BACKUP && !sync_backup_pid))
 		return -ESRCH;
 
-	IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid);
+	IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, task_pid_nr(current));
 	IP_VS_INFO("stopping sync thread %d ...\n",
 		   (state == IP_VS_STATE_MASTER) ?
 		   sync_master_pid : sync_backup_pid);
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 11fedc7..adcbaf6 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -281,7 +281,6 @@
 static struct ctl_table_header *icmp_sysctl_header;
 static struct ctl_table icmp_sysctl_table[] = {
 	{
-		.ctl_name	= NET_NF_CONNTRACK_ICMP_TIMEOUT,
 		.procname	= "nf_conntrack_icmp_timeout",
 		.data		= &nf_ct_icmp_timeout,
 		.maxlen		= sizeof(unsigned int),
@@ -295,7 +294,6 @@
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 static struct ctl_table icmp_compat_sysctl_table[] = {
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT,
 		.procname	= "ip_conntrack_icmp_timeout",
 		.data		= &nf_ct_icmp_timeout,
 		.maxlen		= sizeof(unsigned int),
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index c98ef16..ffddd2b 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -122,7 +122,7 @@
 	ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos);
 
 	if (write && ret == 0) {
-		if (range[1] <= range[0])
+		if (range[1] < range[0])
 			ret = -EINVAL;
 		else
 			set_local_port_range(range);
@@ -150,7 +150,7 @@
 
 	ret = sysctl_intvec(&tmp, name, nlen, oldval, oldlenp, newval, newlen);
 	if (ret == 0 && newval && newlen) {
-		if (range[1] <= range[0])
+		if (range[1] < range[0])
 			ret = -EINVAL;
 		else
 			set_local_port_range(range);
@@ -740,7 +740,6 @@
 		.strategy	= &sysctl_jiffies
 	},
 	{
-		.ctl_name	= NET_IPV4_IPFRAG_MAX_DIST,
 		.procname	= "ipfrag_max_dist",
 		.data		= &sysctl_ipfrag_max_dist,
 		.maxlen		= sizeof(int),
@@ -865,7 +864,6 @@
 	},
 #endif /* CONFIG_NETLABEL */
 	{
-		.ctl_name	= NET_TCP_AVAIL_CONG_CONTROL,
 		.procname	= "tcp_available_congestion_control",
 		.maxlen		= TCP_CA_BUF_MAX,
 		.mode		= 0444,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 4f32200..2e6ad6d 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1334,7 +1334,7 @@
 		if ((flags & MSG_PEEK) && peek_seq != tp->copied_seq) {
 			if (net_ratelimit())
 				printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n",
-				       current->comm, current->pid);
+				       current->comm, task_pid_nr(current));
 			peek_seq = tp->copied_seq;
 		}
 		continue;
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
index 3904d21..2fbcc7d 100644
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -56,3 +56,4 @@
 module_init(tcp_diag_init);
 module_exit(tcp_diag_exit);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_INET_DIAG, TCPDIAG_GETSOCK);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 0f00966..9288220 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1121,7 +1121,7 @@
 	struct sk_buff *skb;
 	int flag = 0;
 	int cnt = 0;
-	u32 new_low_seq = 0;
+	u32 new_low_seq = tp->snd_nxt;
 
 	tcp_for_write_queue(skb, sk) {
 		u32 ack_seq = TCP_SKB_CB(skb)->ack_seq;
@@ -1153,7 +1153,7 @@
 				NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT);
 			}
 		} else {
-			if (!new_low_seq || before(ack_seq, new_low_seq))
+			if (before(ack_seq, new_low_seq))
 				new_low_seq = ack_seq;
 			cnt += tcp_skb_pcount(skb);
 		}
@@ -1242,7 +1242,7 @@
 	int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
 	int reord = tp->packets_out;
 	int prior_fackets;
-	u32 highest_sack_end_seq = 0;
+	u32 highest_sack_end_seq = tp->lost_retrans_low;
 	int flag = 0;
 	int found_dup_sack = 0;
 	int cached_fack_count;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index cb9fc58..35d2b0e 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -147,13 +147,14 @@
 	write_lock_bh(&udp_hash_lock);
 
 	if (!snum) {
-		int i, low, high;
+		int i, low, high, remaining;
 		unsigned rover, best, best_size_so_far;
 
 		inet_get_local_port_range(&low, &high);
+		remaining = (high - low) + 1;
 
 		best_size_so_far = UINT_MAX;
-		best = rover = net_random() % (high - low) + low;
+		best = rover = net_random() % remaining + low;
 
 		/* 1st pass: look for empty (or shortest) hash chain */
 		for (i = 0; i < UDP_HTABLE_SIZE; i++) {
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index e9bbfde..5e95c8a 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -16,19 +16,6 @@
 #include <net/ip.h>
 #include <net/xfrm.h>
 
-static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
-{
-	switch (nexthdr) {
-	case IPPROTO_IPIP:
-	case IPPROTO_IPV6:
-		*spi = ip_hdr(skb)->saddr;
-		*seq = 0;
-		return 0;
-	}
-
-	return xfrm_parse_spi(skb, nexthdr, spi, seq);
-}
-
 #ifdef CONFIG_NETFILTER
 static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
 {
@@ -46,28 +33,29 @@
 }
 #endif
 
-static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
+int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
+		    int encap_type)
 {
-	__be32 spi, seq;
+	int err;
+	__be32 seq;
 	struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
 	struct xfrm_state *x;
 	int xfrm_nr = 0;
 	int decaps = 0;
-	int err = xfrm4_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq);
 	unsigned int nhoff = offsetof(struct iphdr, protocol);
 
-	if (err != 0)
+	seq = 0;
+	if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
 		goto drop;
 
 	do {
 		const struct iphdr *iph = ip_hdr(skb);
-		int nexthdr;
 
 		if (xfrm_nr == XFRM_MAX_DEPTH)
 			goto drop;
 
 		x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
-				iph->protocol != IPPROTO_IPV6 ? iph->protocol : IPPROTO_IPIP, AF_INET);
+				      nexthdr, AF_INET);
 		if (x == NULL)
 			goto drop;
 
@@ -103,15 +91,15 @@
 
 		xfrm_vec[xfrm_nr++] = x;
 
-		if (x->mode->input(x, skb))
+		if (x->outer_mode->input(x, skb))
 			goto drop;
 
-		if (x->props.mode == XFRM_MODE_TUNNEL) {
+		if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
 			decaps = 1;
 			break;
 		}
 
-		err = xfrm_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq);
+		err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
 		if (err < 0)
 			goto drop;
 	} while (!err);
@@ -165,6 +153,7 @@
 	kfree_skb(skb);
 	return 0;
 }
+EXPORT_SYMBOL(xfrm4_rcv_encap);
 
 /* If it's a keepalive packet, then just eat it.
  * If it's an encapsulated packet, then pass it to the
@@ -252,11 +241,8 @@
 	__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);
+	ret = xfrm4_rcv_encap(skb, IPPROTO_ESP, 0, encap_type);
 	return ret;
 
 drop:
@@ -266,7 +252,7 @@
 
 int xfrm4_rcv(struct sk_buff *skb)
 {
-	return xfrm4_rcv_encap(skb, 0);
+	return xfrm4_rcv_spi(skb, ip_hdr(skb)->protocol, 0);
 }
 
 EXPORT_SYMBOL(xfrm4_rcv);
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index 73d2338..e42e122 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -114,6 +114,7 @@
 	.output = xfrm4_beet_output,
 	.owner = THIS_MODULE,
 	.encap = XFRM_MODE_BEET,
+	.flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm4_beet_init(void)
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index 1ae9d32..e4deecb 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -139,6 +139,7 @@
 	.output = xfrm4_tunnel_output,
 	.owner = THIS_MODULE,
 	.encap = XFRM_MODE_TUNNEL,
+	.flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm4_tunnel_init(void)
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index a4edd66..c4a7156 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -47,7 +47,7 @@
 	struct iphdr *iph;
 	int err;
 
-	if (x->props.mode == XFRM_MODE_TUNNEL) {
+	if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
 		err = xfrm4_tunnel_check_size(skb);
 		if (err)
 			goto error_nolock;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 329825c..cc86fb1 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -117,7 +117,7 @@
 		header_len += xfrm[i]->props.header_len;
 		trailer_len += xfrm[i]->props.trailer_len;
 
-		if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL) {
+		if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
 			unsigned short encap_family = xfrm[i]->props.family;
 			switch (encap_family) {
 			case AF_INET:
@@ -151,7 +151,6 @@
 	i = 0;
 	for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
 		struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
-		struct xfrm_state_afinfo *afinfo;
 		x->u.rt.fl = *fl;
 
 		dst_prev->xfrm = xfrm[i++];
@@ -169,27 +168,17 @@
 		/* Copy neighbout for reachability confirmation */
 		dst_prev->neighbour	= neigh_clone(rt->u.dst.neighbour);
 		dst_prev->input		= rt->u.dst.input;
-		/* XXX: When IPv6 module can be unloaded, we should manage reference
-		 * to xfrm6_output in afinfo->output. Miyazawa
-		 * */
-		afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family);
-		if (!afinfo) {
-			dst = *dst_p;
-			err = -EAFNOSUPPORT;
-			goto error;
-		}
-		dst_prev->output = afinfo->output;
-		xfrm_state_put_afinfo(afinfo);
-		if (dst_prev->xfrm->props.family == AF_INET && rt->peer)
-			atomic_inc(&rt->peer->refcnt);
-		x->u.rt.peer = rt->peer;
+		dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
+		if (rt0->peer)
+			atomic_inc(&rt0->peer->refcnt);
+		x->u.rt.peer = rt0->peer;
 		/* Sheit... I remember I did this right. Apparently,
 		 * it was magically lost, so this code needs audit */
 		x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
-		x->u.rt.rt_type = rt->rt_type;
+		x->u.rt.rt_type = rt0->rt_type;
 		x->u.rt.rt_src = rt0->rt_src;
 		x->u.rt.rt_dst = rt0->rt_dst;
-		x->u.rt.rt_gateway = rt->rt_gateway;
+		x->u.rt.rt_gateway = rt0->rt_gateway;
 		x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
 		x->u.rt.idev = rt0->idev;
 		in_dev_hold(rt0->idev);
@@ -291,7 +280,7 @@
 
 	if (likely(xdst->u.rt.idev))
 		in_dev_put(xdst->u.rt.idev);
-	if (dst->xfrm && dst->xfrm->props.family == AF_INET && likely(xdst->u.rt.peer))
+	if (likely(xdst->u.rt.peer))
 		inet_putpeer(xdst->u.rt.peer);
 	xfrm_dst_destroy(xdst);
 }
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 93e2c06..13d54a1 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -49,6 +49,7 @@
 
 static struct xfrm_state_afinfo xfrm4_state_afinfo = {
 	.family			= AF_INET,
+	.owner			= THIS_MODULE,
 	.init_flags		= xfrm4_init_flags,
 	.init_tempsel		= __xfrm4_init_tempsel,
 	.output			= xfrm4_output,
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 1312417..3268451 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -18,7 +18,7 @@
 
 static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb)
 {
-	return IPPROTO_IP;
+	return ip_hdr(skb)->protocol;
 }
 
 static int ipip_init_state(struct xfrm_state *x)
@@ -48,20 +48,25 @@
 	.output		= ipip_output
 };
 
+static int xfrm_tunnel_rcv(struct sk_buff *skb)
+{
+	return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr);
+}
+
 static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
 {
 	return -ENOENT;
 }
 
 static struct xfrm_tunnel xfrm_tunnel_handler = {
-	.handler	=	xfrm4_rcv,
+	.handler	=	xfrm_tunnel_rcv,
 	.err_handler	=	xfrm_tunnel_err,
 	.priority	=	2,
 };
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 static struct xfrm_tunnel xfrm64_tunnel_handler = {
-	.handler	=	xfrm4_rcv,
+	.handler	=	xfrm_tunnel_rcv,
 	.err_handler	=	xfrm_tunnel_err,
 	.priority	=	2,
 };
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 52d10d2..348bd8d 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -255,11 +255,6 @@
 
 static int snmp6_alloc_dev(struct inet6_dev *idev)
 {
-	int err = -ENOMEM;
-
-	if (!idev || !idev->dev)
-		return -EINVAL;
-
 	if (snmp_mib_init((void **)idev->stats.ipv6,
 			  sizeof(struct ipstats_mib),
 			  __alignof__(struct ipstats_mib)) < 0)
@@ -280,15 +275,14 @@
 err_icmp:
 	snmp_mib_free((void **)idev->stats.ipv6);
 err_ip:
-	return err;
+	return -ENOMEM;
 }
 
-static int snmp6_free_dev(struct inet6_dev *idev)
+static void snmp6_free_dev(struct inet6_dev *idev)
 {
 	snmp_mib_free((void **)idev->stats.icmpv6msg);
 	snmp_mib_free((void **)idev->stats.icmpv6);
 	snmp_mib_free((void **)idev->stats.ipv6);
-	return 0;
 }
 
 /* Nobody refers to this device, we may destroy it. */
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index bc92938..1b1caf3 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -747,6 +747,7 @@
 {
 	snmp_mib_free((void **)ipv6_statistics);
 	snmp_mib_free((void **)icmpv6_statistics);
+	snmp_mib_free((void **)icmpv6msg_statistics);
 	snmp_mib_free((void **)udp_stats_in6);
 	snmp_mib_free((void **)udplite_stats_in6);
 }
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index f9f6891..66a9139 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -344,6 +344,8 @@
 	    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
 		goto out;
 
+	skb->ip_summed = CHECKSUM_NONE;
+
 	hdr_len = skb->data - skb_network_header(skb);
 	ah = (struct ip_auth_hdr *)skb->data;
 	ahp = x->data;
@@ -475,8 +477,16 @@
 
 	x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) +
 					  ahp->icv_trunc_len);
-	if (x->props.mode == XFRM_MODE_TUNNEL)
+	switch (x->props.mode) {
+	case XFRM_MODE_BEET:
+	case XFRM_MODE_TRANSPORT:
+		break;
+	case XFRM_MODE_TUNNEL:
 		x->props.header_len += sizeof(struct ipv6hdr);
+		break;
+	default:
+		goto error;
+	}
 	x->data = ahp;
 
 	return 0;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 9eb9285..72a6598 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -354,8 +354,16 @@
 				    (x->ealg->alg_key_len + 7) / 8))
 		goto error;
 	x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
-	if (x->props.mode == XFRM_MODE_TUNNEL)
+	switch (x->props.mode) {
+	case XFRM_MODE_BEET:
+	case XFRM_MODE_TRANSPORT:
+		break;
+	case XFRM_MODE_TUNNEL:
 		x->props.header_len += sizeof(struct ipv6hdr);
+		break;
+	default:
+		goto error;
+	}
 	x->data = esp;
 	return 0;
 
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 1c2c276..d6f1026 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -261,7 +261,7 @@
 		struct inet_timewait_sock *tw = NULL;
 
 		inet_get_local_port_range(&low, &high);
-		remaining = high - low;
+		remaining = (high - low) + 1;
 
 		local_bh_disable();
 		for (i = 1; i <= remaining; i++) {
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 217d60f..b12cc22 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -154,8 +154,10 @@
 	write_unlock(&ip6_fl_lock);
 }
 
-static int fl_intern(struct ip6_flowlabel *fl, __be32 label)
+static struct ip6_flowlabel *fl_intern(struct ip6_flowlabel *fl, __be32 label)
 {
+	struct ip6_flowlabel *lfl;
+
 	fl->label = label & IPV6_FLOWLABEL_MASK;
 
 	write_lock_bh(&ip6_fl_lock);
@@ -163,12 +165,26 @@
 		for (;;) {
 			fl->label = htonl(net_random())&IPV6_FLOWLABEL_MASK;
 			if (fl->label) {
-				struct ip6_flowlabel *lfl;
 				lfl = __fl_lookup(fl->label);
 				if (lfl == NULL)
 					break;
 			}
 		}
+	} else {
+		/*
+		 * we dropper the ip6_fl_lock, so this entry could reappear
+		 * and we need to recheck with it.
+		 *
+		 * OTOH no need to search the active socket first, like it is
+		 * done in ipv6_flowlabel_opt - sock is locked, so new entry
+		 * with the same label can only appear on another sock
+		 */
+		lfl = __fl_lookup(fl->label);
+		if (lfl != NULL) {
+			atomic_inc(&lfl->users);
+			write_unlock_bh(&ip6_fl_lock);
+			return lfl;
+		}
 	}
 
 	fl->lastuse = jiffies;
@@ -176,7 +192,7 @@
 	fl_ht[FL_HASH(fl->label)] = fl;
 	atomic_inc(&fl_size);
 	write_unlock_bh(&ip6_fl_lock);
-	return 0;
+	return NULL;
 }
 
 
@@ -190,14 +206,17 @@
 
 	label &= IPV6_FLOWLABEL_MASK;
 
+	read_lock_bh(&ip6_sk_fl_lock);
 	for (sfl=np->ipv6_fl_list; sfl; sfl = sfl->next) {
 		struct ip6_flowlabel *fl = sfl->fl;
 		if (fl->label == label) {
 			fl->lastuse = jiffies;
 			atomic_inc(&fl->users);
+			read_unlock_bh(&ip6_sk_fl_lock);
 			return fl;
 		}
 	}
+	read_unlock_bh(&ip6_sk_fl_lock);
 	return NULL;
 }
 
@@ -409,6 +428,16 @@
 	return 0;
 }
 
+static inline void fl_link(struct ipv6_pinfo *np, struct ipv6_fl_socklist *sfl,
+		struct ip6_flowlabel *fl)
+{
+	write_lock_bh(&ip6_sk_fl_lock);
+	sfl->fl = fl;
+	sfl->next = np->ipv6_fl_list;
+	np->ipv6_fl_list = sfl;
+	write_unlock_bh(&ip6_sk_fl_lock);
+}
+
 int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
 {
 	int err;
@@ -416,7 +445,8 @@
 	struct in6_flowlabel_req freq;
 	struct ipv6_fl_socklist *sfl1=NULL;
 	struct ipv6_fl_socklist *sfl, **sflp;
-	struct ip6_flowlabel *fl;
+	struct ip6_flowlabel *fl, *fl1 = NULL;
+
 
 	if (optlen < sizeof(freq))
 		return -EINVAL;
@@ -472,8 +502,6 @@
 		sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL);
 
 		if (freq.flr_label) {
-			struct ip6_flowlabel *fl1 = NULL;
-
 			err = -EEXIST;
 			read_lock_bh(&ip6_sk_fl_lock);
 			for (sfl = np->ipv6_fl_list; sfl; sfl = sfl->next) {
@@ -492,6 +520,7 @@
 			if (fl1 == NULL)
 				fl1 = fl_lookup(freq.flr_label);
 			if (fl1) {
+recheck:
 				err = -EEXIST;
 				if (freq.flr_flags&IPV6_FL_F_EXCL)
 					goto release;
@@ -513,11 +542,7 @@
 					fl1->linger = fl->linger;
 				if ((long)(fl->expires - fl1->expires) > 0)
 					fl1->expires = fl->expires;
-				write_lock_bh(&ip6_sk_fl_lock);
-				sfl1->fl = fl1;
-				sfl1->next = np->ipv6_fl_list;
-				np->ipv6_fl_list = sfl1;
-				write_unlock_bh(&ip6_sk_fl_lock);
+				fl_link(np, sfl1, fl1);
 				fl_free(fl);
 				return 0;
 
@@ -534,9 +559,9 @@
 		if (sfl1 == NULL || (err = mem_check(sk)) != 0)
 			goto done;
 
-		err = fl_intern(fl, freq.flr_label);
-		if (err)
-			goto done;
+		fl1 = fl_intern(fl, freq.flr_label);
+		if (fl1 != NULL)
+			goto recheck;
 
 		if (!freq.flr_label) {
 			if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label,
@@ -545,9 +570,7 @@
 			}
 		}
 
-		sfl1->fl = fl;
-		sfl1->next = np->ipv6_fl_list;
-		np->ipv6_fl_list = sfl1;
+		fl_link(np, sfl1, fl);
 		return 0;
 
 	default:
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 28fc8ed..80ef2a1 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -411,8 +411,15 @@
 		goto out;
 
 	x->props.header_len = 0;
-	if (x->props.mode == XFRM_MODE_TUNNEL)
+	switch (x->props.mode) {
+	case XFRM_MODE_BEET:
+	case XFRM_MODE_TRANSPORT:
+		break;
+	case XFRM_MODE_TUNNEL:
 		x->props.header_len += sizeof(struct ipv6hdr);
+	default:
+		goto error;
+	}
 
 	mutex_lock(&ipcomp6_resource_mutex);
 	if (!ipcomp6_alloc_scratches())
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 6cc33dc..20cfc90 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1658,30 +1658,26 @@
 	struct inet6_dev *idev;
 	int ret;
 
-	if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
-	    ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
+	if ((strcmp(ctl->procname, "retrans_time") == 0) ||
+	    (strcmp(ctl->procname, "base_reachable_time") == 0))
 		ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
 
-	switch (ctl->ctl_name) {
-	case NET_NEIGH_RETRANS_TIME:
+	if (strcmp(ctl->procname, "retrans_time") == 0)
 		ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
-		break;
-	case NET_NEIGH_REACHABLE_TIME:
+
+	else if (strcmp(ctl->procname, "base_reachable_time") == 0)
 		ret = proc_dointvec_jiffies(ctl, write,
 					    filp, buffer, lenp, ppos);
-		break;
-	case NET_NEIGH_RETRANS_TIME_MS:
-	case NET_NEIGH_REACHABLE_TIME_MS:
+
+	else if ((strcmp(ctl->procname, "retrans_time_ms") == 0) ||
+		 (strcmp(ctl->procname, "base_reacable_time_ms") == 0))
 		ret = proc_dointvec_ms_jiffies(ctl, write,
 					       filp, buffer, lenp, ppos);
-		break;
-	default:
+	else
 		ret = -1;
-	}
 
 	if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
-		if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
-		    ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
+		if (ctl->data == &idev->nd_parms->base_reachable_time)
 			idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
 		idev->tstamp = jiffies;
 		inet6_ifinfo_notify(RTM_NEWLINK, idev);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 0e40948..ad74bab 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -306,7 +306,6 @@
 #ifdef CONFIG_SYSCTL
 static ctl_table nf_ct_ipv6_sysctl_table[] = {
 	{
-		.ctl_name	= NET_NF_CONNTRACK_FRAG6_TIMEOUT,
 		.procname	= "nf_conntrack_frag6_timeout",
 		.data		= &nf_frags_ctl.timeout,
 		.maxlen		= sizeof(unsigned int),
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index fbdc669..fd9123f 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -260,7 +260,6 @@
 static struct ctl_table_header *icmpv6_sysctl_header;
 static struct ctl_table icmpv6_sysctl_table[] = {
 	{
-		.ctl_name	= NET_NF_CONNTRACK_ICMPV6_TIMEOUT,
 		.procname	= "nf_conntrack_icmpv6_timeout",
 		.data		= &nf_ct_icmpv6_timeout,
 		.maxlen		= sizeof(unsigned int),
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 726fafd..e170c67 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -130,22 +130,6 @@
 	kfree_skb(skb);
 }
 
-static void nf_frag_free(struct inet_frag_queue *q)
-{
-	kfree(container_of(q, struct nf_ct_frag6_queue, q));
-}
-
-static inline struct nf_ct_frag6_queue *frag_alloc_queue(void)
-{
-	struct nf_ct_frag6_queue *fq;
-
-	fq = kzalloc(sizeof(struct nf_ct_frag6_queue), GFP_ATOMIC);
-	if (fq == NULL)
-		return NULL;
-	atomic_add(sizeof(struct nf_ct_frag6_queue), &nf_frags.mem);
-	return fq;
-}
-
 /* Destruction primitives. */
 
 static __inline__ void fq_put(struct nf_ct_frag6_queue *fq)
@@ -168,7 +152,10 @@
 
 static void nf_ct_frag6_expire(unsigned long data)
 {
-	struct nf_ct_frag6_queue *fq = (struct nf_ct_frag6_queue *) data;
+	struct nf_ct_frag6_queue *fq;
+
+	fq = container_of((struct inet_frag_queue *)data,
+			struct nf_ct_frag6_queue, q);
 
 	spin_lock(&fq->q.lock);
 
@@ -184,87 +171,27 @@
 
 /* Creation primitives. */
 
-static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
-					  struct nf_ct_frag6_queue *fq_in)
-{
-	struct nf_ct_frag6_queue *fq;
-#ifdef CONFIG_SMP
-	struct hlist_node *n;
-#endif
-
-	write_lock(&nf_frags.lock);
-#ifdef CONFIG_SMP
-	hlist_for_each_entry(fq, n, &nf_frags.hash[hash], q.list) {
-		if (fq->id == fq_in->id &&
-		    ipv6_addr_equal(&fq_in->saddr, &fq->saddr) &&
-		    ipv6_addr_equal(&fq_in->daddr, &fq->daddr)) {
-			atomic_inc(&fq->q.refcnt);
-			write_unlock(&nf_frags.lock);
-			fq_in->q.last_in |= COMPLETE;
-			fq_put(fq_in);
-			return fq;
-		}
-	}
-#endif
-	fq = fq_in;
-
-	if (!mod_timer(&fq->q.timer, jiffies + nf_frags_ctl.timeout))
-		atomic_inc(&fq->q.refcnt);
-
-	atomic_inc(&fq->q.refcnt);
-	hlist_add_head(&fq->q.list, &nf_frags.hash[hash]);
-	INIT_LIST_HEAD(&fq->q.lru_list);
-	list_add_tail(&fq->q.lru_list, &nf_frags.lru_list);
-	nf_frags.nqueues++;
-	write_unlock(&nf_frags.lock);
-	return fq;
-}
-
-
-static struct nf_ct_frag6_queue *
-nf_ct_frag6_create(unsigned int hash, __be32 id, struct in6_addr *src,				   struct in6_addr *dst)
-{
-	struct nf_ct_frag6_queue *fq;
-
-	if ((fq = frag_alloc_queue()) == NULL) {
-		pr_debug("Can't alloc new queue\n");
-		goto oom;
-	}
-
-	fq->id = id;
-	ipv6_addr_copy(&fq->saddr, src);
-	ipv6_addr_copy(&fq->daddr, dst);
-
-	setup_timer(&fq->q.timer, nf_ct_frag6_expire, (unsigned long)fq);
-	spin_lock_init(&fq->q.lock);
-	atomic_set(&fq->q.refcnt, 1);
-
-	return nf_ct_frag6_intern(hash, fq);
-
-oom:
-	return NULL;
-}
-
 static __inline__ struct nf_ct_frag6_queue *
 fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
 {
-	struct nf_ct_frag6_queue *fq;
-	struct hlist_node *n;
-	unsigned int hash = ip6qhashfn(id, src, dst);
+	struct inet_frag_queue *q;
+	struct ip6_create_arg arg;
+	unsigned int hash;
 
-	read_lock(&nf_frags.lock);
-	hlist_for_each_entry(fq, n, &nf_frags.hash[hash], q.list) {
-		if (fq->id == id &&
-		    ipv6_addr_equal(src, &fq->saddr) &&
-		    ipv6_addr_equal(dst, &fq->daddr)) {
-			atomic_inc(&fq->q.refcnt);
-			read_unlock(&nf_frags.lock);
-			return fq;
-		}
-	}
-	read_unlock(&nf_frags.lock);
+	arg.id = id;
+	arg.src = src;
+	arg.dst = dst;
+	hash = ip6qhashfn(id, src, dst);
 
-	return nf_ct_frag6_create(hash, id, src, dst);
+	q = inet_frag_find(&nf_frags, &arg, hash);
+	if (q == NULL)
+		goto oom;
+
+	return container_of(q, struct nf_ct_frag6_queue, q);
+
+oom:
+	pr_debug("Can't alloc new queue\n");
+	return NULL;
 }
 
 
@@ -749,9 +676,12 @@
 {
 	nf_frags.ctl = &nf_frags_ctl;
 	nf_frags.hashfn = nf_hashfn;
-	nf_frags.destructor = nf_frag_free;
+	nf_frags.constructor = ip6_frag_init;
+	nf_frags.destructor = NULL;
 	nf_frags.skb_free = nf_skb_free;
 	nf_frags.qsize = sizeof(struct nf_ct_frag6_queue);
+	nf_frags.match = ip6_frag_match;
+	nf_frags.frag_expire = nf_ct_frag6_expire;
 	inet_frags_init(&nf_frags);
 
 	return 0;
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 6ad19cf..76c88a9 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -143,6 +143,18 @@
 	return ip6qhashfn(fq->id, &fq->saddr, &fq->daddr);
 }
 
+int ip6_frag_match(struct inet_frag_queue *q, void *a)
+{
+	struct frag_queue *fq;
+	struct ip6_create_arg *arg = a;
+
+	fq = container_of(q, struct frag_queue, q);
+	return (fq->id == arg->id &&
+			ipv6_addr_equal(&fq->saddr, arg->src) &&
+			ipv6_addr_equal(&fq->daddr, arg->dst));
+}
+EXPORT_SYMBOL(ip6_frag_match);
+
 /* Memory Tracking Functions. */
 static inline void frag_kfree_skb(struct sk_buff *skb, int *work)
 {
@@ -152,20 +164,16 @@
 	kfree_skb(skb);
 }
 
-static void ip6_frag_free(struct inet_frag_queue *fq)
+void ip6_frag_init(struct inet_frag_queue *q, void *a)
 {
-	kfree(container_of(fq, struct frag_queue, q));
-}
+	struct frag_queue *fq = container_of(q, struct frag_queue, q);
+	struct ip6_create_arg *arg = a;
 
-static inline struct frag_queue *frag_alloc_queue(void)
-{
-	struct frag_queue *fq = kzalloc(sizeof(struct frag_queue), GFP_ATOMIC);
-
-	if(!fq)
-		return NULL;
-	atomic_add(sizeof(struct frag_queue), &ip6_frags.mem);
-	return fq;
+	fq->id = arg->id;
+	ipv6_addr_copy(&fq->saddr, arg->src);
+	ipv6_addr_copy(&fq->daddr, arg->dst);
 }
+EXPORT_SYMBOL(ip6_frag_init);
 
 /* Destruction primitives. */
 
@@ -193,9 +201,11 @@
 
 static void ip6_frag_expire(unsigned long data)
 {
-	struct frag_queue *fq = (struct frag_queue *) data;
+	struct frag_queue *fq;
 	struct net_device *dev = NULL;
 
+	fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
+
 	spin_lock(&fq->q.lock);
 
 	if (fq->q.last_in & COMPLETE)
@@ -230,98 +240,30 @@
 	fq_put(fq);
 }
 
-/* Creation primitives. */
-
-
-static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in)
+static __inline__ struct frag_queue *
+fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
+	struct inet6_dev *idev)
 {
-	struct frag_queue *fq;
+	struct inet_frag_queue *q;
+	struct ip6_create_arg arg;
 	unsigned int hash;
-#ifdef CONFIG_SMP
-	struct hlist_node *n;
-#endif
 
-	write_lock(&ip6_frags.lock);
-	hash = ip6qhashfn(fq_in->id, &fq_in->saddr, &fq_in->daddr);
-#ifdef CONFIG_SMP
-	hlist_for_each_entry(fq, n, &ip6_frags.hash[hash], q.list) {
-		if (fq->id == fq_in->id &&
-		    ipv6_addr_equal(&fq_in->saddr, &fq->saddr) &&
-		    ipv6_addr_equal(&fq_in->daddr, &fq->daddr)) {
-			atomic_inc(&fq->q.refcnt);
-			write_unlock(&ip6_frags.lock);
-			fq_in->q.last_in |= COMPLETE;
-			fq_put(fq_in);
-			return fq;
-		}
-	}
-#endif
-	fq = fq_in;
+	arg.id = id;
+	arg.src = src;
+	arg.dst = dst;
+	hash = ip6qhashfn(id, src, dst);
 
-	if (!mod_timer(&fq->q.timer, jiffies + ip6_frags_ctl.timeout))
-		atomic_inc(&fq->q.refcnt);
-
-	atomic_inc(&fq->q.refcnt);
-	hlist_add_head(&fq->q.list, &ip6_frags.hash[hash]);
-	INIT_LIST_HEAD(&fq->q.lru_list);
-	list_add_tail(&fq->q.lru_list, &ip6_frags.lru_list);
-	ip6_frags.nqueues++;
-	write_unlock(&ip6_frags.lock);
-	return fq;
-}
-
-
-static struct frag_queue *
-ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst,
-		struct inet6_dev *idev)
-{
-	struct frag_queue *fq;
-
-	if ((fq = frag_alloc_queue()) == NULL)
+	q = inet_frag_find(&ip6_frags, &arg, hash);
+	if (q == NULL)
 		goto oom;
 
-	fq->id = id;
-	ipv6_addr_copy(&fq->saddr, src);
-	ipv6_addr_copy(&fq->daddr, dst);
-
-	init_timer(&fq->q.timer);
-	fq->q.timer.function = ip6_frag_expire;
-	fq->q.timer.data = (long) fq;
-	spin_lock_init(&fq->q.lock);
-	atomic_set(&fq->q.refcnt, 1);
-
-	return ip6_frag_intern(fq);
+	return container_of(q, struct frag_queue, q);
 
 oom:
 	IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS);
 	return NULL;
 }
 
-static __inline__ struct frag_queue *
-fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
-	struct inet6_dev *idev)
-{
-	struct frag_queue *fq;
-	struct hlist_node *n;
-	unsigned int hash;
-
-	read_lock(&ip6_frags.lock);
-	hash = ip6qhashfn(id, src, dst);
-	hlist_for_each_entry(fq, n, &ip6_frags.hash[hash], q.list) {
-		if (fq->id == id &&
-		    ipv6_addr_equal(src, &fq->saddr) &&
-		    ipv6_addr_equal(dst, &fq->daddr)) {
-			atomic_inc(&fq->q.refcnt);
-			read_unlock(&ip6_frags.lock);
-			return fq;
-		}
-	}
-	read_unlock(&ip6_frags.lock);
-
-	return ip6_frag_create(id, src, dst, idev);
-}
-
-
 static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
 			   struct frag_hdr *fhdr, int nhoff)
 {
@@ -697,8 +639,11 @@
 
 	ip6_frags.ctl = &ip6_frags_ctl;
 	ip6_frags.hashfn = ip6_hashfn;
-	ip6_frags.destructor = ip6_frag_free;
+	ip6_frags.constructor = ip6_frag_init;
+	ip6_frags.destructor = NULL;
 	ip6_frags.skb_free = NULL;
 	ip6_frags.qsize = sizeof(struct frag_queue);
+	ip6_frags.match = ip6_frag_match;
+	ip6_frags.frag_expire = ip6_frag_expire;
 	inet_frags_init(&ip6_frags);
 }
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index cce9941..95f8e4a 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2397,7 +2397,6 @@
 
 ctl_table ipv6_route_table[] = {
 	{
-		.ctl_name	=	NET_IPV6_ROUTE_FLUSH,
 		.procname	=	"flush",
 		.data		=	&flush_delay,
 		.maxlen		=	sizeof(int),
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 02f69e5..5157837 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -16,7 +16,7 @@
 #include <net/ipv6.h>
 #include <net/xfrm.h>
 
-int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
+int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
 {
 	int err;
 	__be32 seq;
@@ -24,11 +24,9 @@
 	struct xfrm_state *x;
 	int xfrm_nr = 0;
 	int decaps = 0;
-	int nexthdr;
 	unsigned int nhoff;
 
 	nhoff = IP6CB(skb)->nhoff;
-	nexthdr = skb_network_header(skb)[nhoff];
 
 	seq = 0;
 	if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
@@ -41,7 +39,7 @@
 			goto drop;
 
 		x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
-				nexthdr != IPPROTO_IPIP ? nexthdr : IPPROTO_IPV6, AF_INET6);
+				      nexthdr, AF_INET6);
 		if (x == NULL)
 			goto drop;
 		spin_lock(&x->lock);
@@ -70,10 +68,10 @@
 
 		xfrm_vec[xfrm_nr++] = x;
 
-		if (x->mode->input(x, skb))
+		if (x->outer_mode->input(x, skb))
 			goto drop;
 
-		if (x->props.mode == XFRM_MODE_TUNNEL) { /* XXX */
+		if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
 			decaps = 1;
 			break;
 		}
@@ -99,7 +97,6 @@
 	memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
 	       xfrm_nr * sizeof(xfrm_vec[0]));
 	skb->sp->len += xfrm_nr;
-	skb->ip_summed = CHECKSUM_NONE;
 
 	nf_reset(skb);
 
@@ -135,7 +132,8 @@
 
 int xfrm6_rcv(struct sk_buff *skb)
 {
-	return xfrm6_rcv_spi(skb, 0);
+	return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
+			     0);
 }
 
 EXPORT_SYMBOL(xfrm6_rcv);
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index 13bb1e8..2bfb4f0 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -79,6 +79,7 @@
 	.output = xfrm6_beet_output,
 	.owner = THIS_MODULE,
 	.encap = XFRM_MODE_BEET,
+	.flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm6_beet_init(void)
diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c
index 957ae36..a7bc8c6 100644
--- a/net/ipv6/xfrm6_mode_ro.c
+++ b/net/ipv6/xfrm6_mode_ro.c
@@ -58,16 +58,7 @@
 	return 0;
 }
 
-/*
- * Do nothing about routing optimization header unlike IPsec.
- */
-static int xfrm6_ro_input(struct xfrm_state *x, struct sk_buff *skb)
-{
-	return 0;
-}
-
 static struct xfrm_mode xfrm6_ro_mode = {
-	.input = xfrm6_ro_input,
 	.output = xfrm6_ro_output,
 	.owner = THIS_MODULE,
 	.encap = XFRM_MODE_ROUTEOPTIMIZATION,
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index ea22838..fd84e22 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -118,6 +118,7 @@
 	.output = xfrm6_tunnel_output,
 	.owner = THIS_MODULE,
 	.encap = XFRM_MODE_TUNNEL,
+	.flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm6_tunnel_init(void)
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index a5a32c1..6569767 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -50,7 +50,7 @@
 	struct ipv6hdr *iph;
 	int err;
 
-	if (x->props.mode == XFRM_MODE_TUNNEL) {
+	if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
 		err = xfrm6_tunnel_check_size(skb);
 		if (err)
 			goto error_nolock;
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 15aa4c5..82e27b8 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -178,8 +178,7 @@
 		__xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]);
 		trailer_len += xfrm[i]->props.trailer_len;
 
-		if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL ||
-		    xfrm[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION) {
+		if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
 			unsigned short encap_family = xfrm[i]->props.family;
 			switch(encap_family) {
 			case AF_INET:
@@ -215,7 +214,6 @@
 	i = 0;
 	for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
 		struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
-		struct xfrm_state_afinfo *afinfo;
 
 		dst_prev->xfrm = xfrm[i++];
 		dst_prev->dev = rt->u.dst.dev;
@@ -232,18 +230,7 @@
 		/* Copy neighbour for reachability confirmation */
 		dst_prev->neighbour	= neigh_clone(rt->u.dst.neighbour);
 		dst_prev->input		= rt->u.dst.input;
-		/* XXX: When IPv4 is implemented as module and can be unloaded,
-		 * we should manage reference to xfrm4_output in afinfo->output.
-		 * Miyazawa
-		 */
-		afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family);
-		if (!afinfo) {
-			dst = *dst_p;
-			goto error;
-		}
-
-		dst_prev->output = afinfo->output;
-		xfrm_state_put_afinfo(afinfo);
+		dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
 		/* Sheit... I remember I did this right. Apparently,
 		 * it was magically lost, so this code needs audit */
 		x->u.rt6.rt6i_flags    = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index cdadb48..b392bee 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -93,7 +93,8 @@
 	/* Rule 4: select IPsec tunnel */
 	for (i = 0; i < n; i++) {
 		if (src[i] &&
-		    src[i]->props.mode == XFRM_MODE_TUNNEL) {
+		    (src[i]->props.mode == XFRM_MODE_TUNNEL ||
+		     src[i]->props.mode == XFRM_MODE_BEET)) {
 			dst[j++] = src[i];
 			src[i] = NULL;
 		}
@@ -146,7 +147,8 @@
 	/* Rule 3: select IPsec tunnel */
 	for (i = 0; i < n; i++) {
 		if (src[i] &&
-		    src[i]->mode == XFRM_MODE_TUNNEL) {
+		    (src[i]->mode == XFRM_MODE_TUNNEL ||
+		     src[i]->mode == XFRM_MODE_BEET)) {
 			dst[j++] = src[i];
 			src[i] = NULL;
 		}
@@ -168,6 +170,7 @@
 
 static struct xfrm_state_afinfo xfrm6_state_afinfo = {
 	.family			= AF_INET6,
+	.owner			= THIS_MODULE,
 	.init_tempsel		= __xfrm6_init_tempsel,
 	.tmpl_sort		= __xfrm6_tmpl_sort,
 	.state_sort		= __xfrm6_state_sort,
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 3f8a3ab..fae90ff 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -248,7 +248,7 @@
 
 static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 {
-	return 0;
+	return skb_network_header(skb)[IP6CB(skb)->nhoff];
 }
 
 static int xfrm6_tunnel_rcv(struct sk_buff *skb)
@@ -257,7 +257,7 @@
 	__be32 spi;
 
 	spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
-	return xfrm6_rcv_spi(skb, spi) > 0 ? : 0;
+	return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0;
 }
 
 static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
index af0cea7..80c33f4 100644
--- a/net/irda/discovery.c
+++ b/net/irda/discovery.c
@@ -202,7 +202,7 @@
 	/* Drop the spinlock before calling the higher layers, as
 	 * we can't guarantee they won't call us back and create a
 	 * deadlock. We will work on our own private data, so we
-	 * don't care to be interupted. - Jean II */
+	 * don't care to be interrupted. - Jean II */
 	spin_unlock_irqrestore(&log->hb_spinlock, flags);
 
 	if(buffer == NULL)
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c
index 824309d..b5a1388 100644
--- a/net/irda/ircomm/ircomm_tty_attach.c
+++ b/net/irda/ircomm/ircomm_tty_attach.c
@@ -381,18 +381,9 @@
 	info.daddr = discovery->daddr;
 	info.saddr = discovery->saddr;
 
-	/* FIXME. We have a locking problem on the hashbin here.
-	 * We probably need to use hashbin_find_next(), but we first
-	 * need to ensure that "line" is unique. - Jean II */
-	self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty);
-	while (self != NULL) {
-		IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
-
-		ircomm_tty_do_event(self, IRCOMM_TTY_DISCOVERY_INDICATION,
-				    NULL, &info);
-
-		self = (struct ircomm_tty_cb *) hashbin_get_next(ircomm_tty);
-	}
+	self = (struct ircomm_tty_cb *) priv;
+	ircomm_tty_do_event(self, IRCOMM_TTY_DISCOVERY_INDICATION,
+			    NULL, &info);
 }
 
 /*
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index ee3889f..dc5e34a 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/iriap_event.c b/net/irda/iriap_event.c
index 99b18dc..8fb9d72 100644
--- a/net/irda/iriap_event.c
+++ b/net/irda/iriap_event.c
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irias_object.c b/net/irda/irias_object.c
index cf30245..cbcf043 100644
--- a/net/irda/irias_object.c
+++ b/net/irda/irias_object.c
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c
index 87039c2..fff52d5 100644
--- a/net/irda/irlan/irlan_client.c
+++ b/net/irda/irlan/irlan_client.c
@@ -20,7 +20,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlan/irlan_client_event.c b/net/irda/irlan/irlan_client_event.c
index 843ab6f..6afcee5 100644
--- a/net/irda/irlan/irlan_client_event.c
+++ b/net/irda/irlan/irlan_client_event.c
@@ -17,7 +17,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
index f5778ef..a4b56e2 100644
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -17,7 +17,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c
index 340f04a..7f9c854 100644
--- a/net/irda/irlan/irlan_eth.c
+++ b/net/irda/irlan/irlan_eth.c
@@ -19,7 +19,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlan/irlan_event.c b/net/irda/irlan/irlan_event.c
index 623e0fd..a9750a8 100644
--- a/net/irda/irlan/irlan_event.c
+++ b/net/irda/irlan/irlan_event.c
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlan/irlan_filter.c b/net/irda/irlan/irlan_filter.c
index e6346b8..4384be9 100644
--- a/net/irda/irlan/irlan_filter.c
+++ b/net/irda/irlan/irlan_filter.c
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c
index aac6643..13db942 100644
--- a/net/irda/irlan/irlan_provider.c
+++ b/net/irda/irlan/irlan_provider.c
@@ -20,7 +20,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlan/irlan_provider_event.c b/net/irda/irlan/irlan_provider_event.c
index ef401bd..10ece5a 100644
--- a/net/irda/irlan/irlan_provider_event.c
+++ b/net/irda/irlan/irlan_provider_event.c
@@ -16,7 +16,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c
index a8b8873..4c33bf5 100644
--- a/net/irda/irlap_event.c
+++ b/net/irda/irlap_event.c
@@ -19,7 +19,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
index 77ac27e..4f37645 100644
--- a/net/irda/irlap_frame.c
+++ b/net/irda/irlap_frame.c
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
index 7db92ce..cedff80 100644
--- a/net/irda/irlmp.c
+++ b/net/irda/irlmp.c
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlmp_event.c b/net/irda/irlmp_event.c
index 65ffa98..1bba87e7 100644
--- a/net/irda/irlmp_event.c
+++ b/net/irda/irlmp_event.c
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irlmp_frame.c b/net/irda/irlmp_frame.c
index 559302d..0a79d9a 100644
--- a/net/irda/irlmp_frame.c
+++ b/net/irda/irlmp_frame.c
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irmod.c b/net/irda/irmod.c
index 8ba703d..01554b9 100644
--- a/net/irda/irmod.c
+++ b/net/irda/irmod.c
@@ -17,7 +17,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c
index d058b46..40c28ef 100644
--- a/net/irda/irqueue.c
+++ b/net/irda/irqueue.c
@@ -28,7 +28,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/irsysctl.c b/net/irda/irsysctl.c
index 957e04f..565cbf0 100644
--- a/net/irda/irsysctl.c
+++ b/net/irda/irsysctl.c
@@ -17,7 +17,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
@@ -31,12 +31,6 @@
 #include <net/irda/irda.h>		/* irda_debug */
 #include <net/irda/irias_object.h>
 
-#define NET_IRDA 412 /* Random number */
-enum { DISCOVERY=1, DEVNAME, DEBUG, FAST_POLL, DISCOVERY_SLOTS,
-       DISCOVERY_TIMEOUT, SLOT_TIMEOUT, MAX_BAUD_RATE, MIN_TX_TURN_TIME,
-       MAX_TX_DATA_SIZE, MAX_TX_WINDOW, MAX_NOREPLY_TIME, WARN_NOREPLY_TIME,
-       LAP_KEEPALIVE_TIME };
-
 extern int  sysctl_discovery;
 extern int  sysctl_discovery_slots;
 extern int  sysctl_discovery_timeout;
@@ -94,7 +88,7 @@
 /* One file */
 static ctl_table irda_table[] = {
 	{
-		.ctl_name	= DISCOVERY,
+		.ctl_name	= NET_IRDA_DISCOVERY,
 		.procname	= "discovery",
 		.data		= &sysctl_discovery,
 		.maxlen		= sizeof(int),
@@ -102,7 +96,7 @@
 		.proc_handler	= &proc_dointvec
 	},
 	{
-		.ctl_name	= DEVNAME,
+		.ctl_name	= NET_IRDA_DEVNAME,
 		.procname	= "devname",
 		.data		= sysctl_devname,
 		.maxlen		= 65,
@@ -112,7 +106,7 @@
 	},
 #ifdef CONFIG_IRDA_DEBUG
 	{
-		.ctl_name	= DEBUG,
+		.ctl_name	= NET_IRDA_DEBUG,
 		.procname	= "debug",
 		.data		= &irda_debug,
 		.maxlen		= sizeof(int),
@@ -122,7 +116,7 @@
 #endif
 #ifdef CONFIG_IRDA_FAST_RR
 	{
-		.ctl_name	= FAST_POLL,
+		.ctl_name	= NET_IRDA_FAST_POLL,
 		.procname	= "fast_poll_increase",
 		.data		= &sysctl_fast_poll_increase,
 		.maxlen		= sizeof(int),
@@ -131,7 +125,7 @@
 	},
 #endif
 	{
-		.ctl_name	= DISCOVERY_SLOTS,
+		.ctl_name	= NET_IRDA_DISCOVERY_SLOTS,
 		.procname	= "discovery_slots",
 		.data		= &sysctl_discovery_slots,
 		.maxlen		= sizeof(int),
@@ -142,7 +136,7 @@
 		.extra2		= &max_discovery_slots
 	},
 	{
-		.ctl_name	= DISCOVERY_TIMEOUT,
+		.ctl_name	= NET_IRDA_DISCOVERY_TIMEOUT,
 		.procname	= "discovery_timeout",
 		.data		= &sysctl_discovery_timeout,
 		.maxlen		= sizeof(int),
@@ -150,7 +144,7 @@
 		.proc_handler	= &proc_dointvec
 	},
 	{
-		.ctl_name	= SLOT_TIMEOUT,
+		.ctl_name	= NET_IRDA_SLOT_TIMEOUT,
 		.procname	= "slot_timeout",
 		.data		= &sysctl_slot_timeout,
 		.maxlen		= sizeof(int),
@@ -161,7 +155,7 @@
 		.extra2		= &max_slot_timeout
 	},
 	{
-		.ctl_name	= MAX_BAUD_RATE,
+		.ctl_name	= NET_IRDA_MAX_BAUD_RATE,
 		.procname	= "max_baud_rate",
 		.data		= &sysctl_max_baud_rate,
 		.maxlen		= sizeof(int),
@@ -172,7 +166,7 @@
 		.extra2		= &max_max_baud_rate
 	},
 	{
-		.ctl_name	= MIN_TX_TURN_TIME,
+		.ctl_name	= NET_IRDA_MIN_TX_TURN_TIME,
 		.procname	= "min_tx_turn_time",
 		.data		= &sysctl_min_tx_turn_time,
 		.maxlen		= sizeof(int),
@@ -183,7 +177,7 @@
 		.extra2		= &max_min_tx_turn_time
 	},
 	{
-		.ctl_name	= MAX_TX_DATA_SIZE,
+		.ctl_name	= NET_IRDA_MAX_TX_DATA_SIZE,
 		.procname	= "max_tx_data_size",
 		.data		= &sysctl_max_tx_data_size,
 		.maxlen		= sizeof(int),
@@ -194,7 +188,7 @@
 		.extra2		= &max_max_tx_data_size
 	},
 	{
-		.ctl_name	= MAX_TX_WINDOW,
+		.ctl_name	= NET_IRDA_MAX_TX_WINDOW,
 		.procname	= "max_tx_window",
 		.data		= &sysctl_max_tx_window,
 		.maxlen		= sizeof(int),
@@ -205,7 +199,7 @@
 		.extra2		= &max_max_tx_window
 	},
 	{
-		.ctl_name	= MAX_NOREPLY_TIME,
+		.ctl_name	= NET_IRDA_MAX_NOREPLY_TIME,
 		.procname	= "max_noreply_time",
 		.data		= &sysctl_max_noreply_time,
 		.maxlen		= sizeof(int),
@@ -216,7 +210,7 @@
 		.extra2		= &max_max_noreply_time
 	},
 	{
-		.ctl_name	= WARN_NOREPLY_TIME,
+		.ctl_name	= NET_IRDA_WARN_NOREPLY_TIME,
 		.procname	= "warn_noreply_time",
 		.data		= &sysctl_warn_noreply_time,
 		.maxlen		= sizeof(int),
@@ -227,7 +221,7 @@
 		.extra2		= &max_warn_noreply_time
 	},
 	{
-		.ctl_name	= LAP_KEEPALIVE_TIME,
+		.ctl_name	= NET_IRDA_LAP_KEEPALIVE_TIME,
 		.procname	= "lap_keepalive_time",
 		.data		= &sysctl_lap_keepalive_time,
 		.maxlen		= sizeof(int),
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
index 1311976..97db158 100644
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/timer.c b/net/irda/timer.c
index d3a6ee8..d730099 100644
--- a/net/irda/timer.c
+++ b/net/irda/timer.c
@@ -18,7 +18,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/irda/wrapper.c b/net/irda/wrapper.c
index a7a7f19..e712867 100644
--- a/net/irda/wrapper.c
+++ b/net/irda/wrapper.c
@@ -20,7 +20,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index 983058d..a2f5a6e 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -389,7 +389,7 @@
  * iucv_declare_cpu
  * @data: unused
  *
- * Declare a interupt buffer on this cpu.
+ * Declare a interrupt buffer on this cpu.
  */
 static void iucv_declare_cpu(void *data)
 {
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 49eacba..46cf962 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -762,7 +762,7 @@
 			if (net_ratelimit())
 				printk(KERN_DEBUG "LLC(%s:%d): Application "
 						  "bug, race in MSG_PEEK.\n",
-				       current->comm, current->pid);
+				       current->comm, task_pid_nr(current));
 			peek_seq = llc->copied_seq;
 		}
 		continue;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d34a9de..4b4ed2a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -37,8 +37,6 @@
 
 struct ieee80211_local;
 
-#define BIT(x) (1 << (x))
-
 #define IEEE80211_ALIGN32_PAD(a) ((4 - ((a) & 3)) & 3)
 
 /* Maximum number of broadcast/multicast frames to buffer when some of the
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index f0224c2..6caa3ec 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -306,9 +306,12 @@
 			    ((chan->chan == channel) || (chan->freq == freq))) {
 				local->oper_channel = chan;
 				local->oper_hw_mode = mode;
-				set++;
+				set = 1;
+				break;
 			}
 		}
+		if (set)
+			break;
 	}
 
 	if (set) {
@@ -508,10 +511,11 @@
 
 static int ieee80211_ioctl_siwscan(struct net_device *dev,
 				   struct iw_request_info *info,
-				   struct iw_point *data, char *extra)
+				   union iwreq_data *wrqu, char *extra)
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct iw_scan_req *req = NULL;
 	u8 *ssid = NULL;
 	size_t ssid_len = 0;
 
@@ -536,6 +540,14 @@
 		return -EOPNOTSUPP;
 	}
 
+	/* if SSID was specified explicitly then use that */
+	if (wrqu->data.length == sizeof(struct iw_scan_req) &&
+	    wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+		req = (struct iw_scan_req *)extra;
+		ssid = req->essid;
+		ssid_len = req->essid_len;
+	}
+
 	return ieee80211_sta_req_scan(dev, ssid, ssid_len);
 }
 
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 1641e8f..f7ffeec 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -12,7 +12,6 @@
  */
 
 /* TODO:
- * BSS table: use <BSSID,SSID> as the key to support multi-SSID APs
  * order BSS list by RSSI(?) ("quality of AP")
  * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
  *    SSID)
@@ -61,7 +60,8 @@
 static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
 				     u8 *ssid, size_t ssid_len);
 static struct ieee80211_sta_bss *
-ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid);
+ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
+		     u8 *ssid, u8 ssid_len);
 static void ieee80211_rx_bss_put(struct net_device *dev,
 				 struct ieee80211_sta_bss *bss);
 static int ieee80211_sta_find_ibss(struct net_device *dev,
@@ -108,14 +108,11 @@
 	u8 wmm_param_len;
 };
 
-enum ParseRes { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 };
-
-static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
-					    struct ieee802_11_elems *elems)
+static void ieee802_11_parse_elems(u8 *start, size_t len,
+				   struct ieee802_11_elems *elems)
 {
 	size_t left = len;
 	u8 *pos = start;
-	int unknown = 0;
 
 	memset(elems, 0, sizeof(*elems));
 
@@ -126,15 +123,8 @@
 		elen = *pos++;
 		left -= 2;
 
-		if (elen > left) {
-#if 0
-			if (net_ratelimit())
-				printk(KERN_DEBUG "IEEE 802.11 element parse "
-				       "failed (id=%d elen=%d left=%d)\n",
-				       id, elen, left);
-#endif
-			return ParseFailed;
-		}
+		if (elen > left)
+			return;
 
 		switch (id) {
 		case WLAN_EID_SSID:
@@ -201,28 +191,15 @@
 			elems->ext_supp_rates_len = elen;
 			break;
 		default:
-#if 0
-			printk(KERN_DEBUG "IEEE 802.11 element parse ignored "
-				      "unknown element (id=%d elen=%d)\n",
-				      id, elen);
-#endif
-			unknown++;
 			break;
 		}
 
 		left -= elen;
 		pos += elen;
 	}
-
-	/* Do not trigger error if left == 1 as Apple Airport base stations
-	 * send AssocResps that are one spurious byte too long. */
-
-	return unknown ? ParseUnknown : ParseOK;
 }
 
 
-
-
 static int ecw2cw(int ecw)
 {
 	int cw = 1;
@@ -427,7 +404,9 @@
 		if (sdata->type != IEEE80211_IF_TYPE_STA)
 			return;
 
-		bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+		bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
+					   local->hw.conf.channel,
+					   ifsta->ssid, ifsta->ssid_len);
 		if (bss) {
 			if (bss->has_erp_value)
 				ieee80211_handle_erp_ie(dev, bss->erp_value);
@@ -574,7 +553,8 @@
 		capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
 			WLAN_CAPABILITY_SHORT_PREAMBLE;
 	}
-	bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+	bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
+				   ifsta->ssid, ifsta->ssid_len);
 	if (bss) {
 		if (bss->capability & WLAN_CAPABILITY_PRIVACY)
 			capab |= WLAN_CAPABILITY_PRIVACY;
@@ -722,6 +702,7 @@
 static int ieee80211_privacy_mismatch(struct net_device *dev,
 				      struct ieee80211_if_sta *ifsta)
 {
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss;
 	int res = 0;
 
@@ -729,7 +710,8 @@
 	    ifsta->key_management_enabled)
 		return 0;
 
-	bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+	bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
+				   ifsta->ssid, ifsta->ssid_len);
 	if (!bss)
 		return 0;
 
@@ -926,12 +908,7 @@
 
 	printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name);
 	pos = mgmt->u.auth.variable;
-	if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
-	    == ParseFailed) {
-		printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n",
-		       dev->name);
-		return;
-	}
+	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
 	if (!elems.challenge) {
 		printk(KERN_DEBUG "%s: no challenge IE in shared key auth "
 		       "frame\n", dev->name);
@@ -1203,15 +1180,11 @@
 	capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
 	status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
 	aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
-	if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
-		printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
-		       "set\n", dev->name, aid);
-	aid &= ~(BIT(15) | BIT(14));
 
 	printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
 	       "status=%d aid=%d)\n",
 	       dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
-	       capab_info, status_code, aid);
+	       capab_info, status_code, aid & ~(BIT(15) | BIT(14)));
 
 	if (status_code != WLAN_STATUS_SUCCESS) {
 		printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
@@ -1223,13 +1196,13 @@
 		return;
 	}
 
+	if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
+		printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
+		       "set\n", dev->name, aid);
+	aid &= ~(BIT(15) | BIT(14));
+
 	pos = mgmt->u.assoc_resp.variable;
-	if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
-	    == ParseFailed) {
-		printk(KERN_DEBUG "%s: failed to parse AssocResp\n",
-		       dev->name);
-		return;
-	}
+	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
 
 	if (!elems.supp_rates) {
 		printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
@@ -1241,7 +1214,9 @@
 	 * update our stored copy */
 	if (elems.erp_info && elems.erp_info_len >= 1) {
 		struct ieee80211_sta_bss *bss
-			= ieee80211_rx_bss_get(dev, ifsta->bssid);
+			= ieee80211_rx_bss_get(dev, ifsta->bssid,
+					       local->hw.conf.channel,
+					       ifsta->ssid, ifsta->ssid_len);
 		if (bss) {
 			bss->erp_value = elems.erp_info[0];
 			bss->has_erp_value = 1;
@@ -1271,7 +1246,9 @@
 			       " AP\n", dev->name);
 			return;
 		}
-		bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+		bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
+					   local->hw.conf.channel,
+					   ifsta->ssid, ifsta->ssid_len);
 		if (bss) {
 			sta->last_rssi = bss->rssi;
 			sta->last_signal = bss->signal;
@@ -1347,7 +1324,8 @@
 
 
 static struct ieee80211_sta_bss *
-ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
+ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel,
+		     u8 *ssid, u8 ssid_len)
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss;
@@ -1358,6 +1336,11 @@
 	atomic_inc(&bss->users);
 	atomic_inc(&bss->users);
 	memcpy(bss->bssid, bssid, ETH_ALEN);
+	bss->channel = channel;
+	if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
+		memcpy(bss->ssid, ssid, ssid_len);
+		bss->ssid_len = ssid_len;
+	}
 
 	spin_lock_bh(&local->sta_bss_lock);
 	/* TODO: order by RSSI? */
@@ -1369,7 +1352,8 @@
 
 
 static struct ieee80211_sta_bss *
-ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
+ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
+		     u8 *ssid, u8 ssid_len)
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss;
@@ -1377,7 +1361,10 @@
 	spin_lock_bh(&local->sta_bss_lock);
 	bss = local->sta_bss_hash[STA_HASH(bssid)];
 	while (bss) {
-		if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) {
+		if (!memcmp(bss->bssid, bssid, ETH_ALEN) &&
+		    bss->channel == channel &&
+		    bss->ssid_len == ssid_len &&
+		    (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
 			atomic_inc(&bss->users);
 			break;
 		}
@@ -1439,7 +1426,7 @@
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee802_11_elems elems;
 	size_t baselen;
-	int channel, invalid = 0, clen;
+	int channel, clen;
 	struct ieee80211_sta_bss *bss;
 	struct sta_info *sta;
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1485,9 +1472,7 @@
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
 	}
 
-	if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
-				   &elems) == ParseFailed)
-		invalid = 1;
+	ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
 
 	if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
 	    memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
@@ -1545,9 +1530,11 @@
 	else
 		channel = rx_status->channel;
 
-	bss = ieee80211_rx_bss_get(dev, mgmt->bssid);
+	bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel,
+				   elems.ssid, elems.ssid_len);
 	if (!bss) {
-		bss = ieee80211_rx_bss_add(dev, mgmt->bssid);
+		bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel,
+					   elems.ssid, elems.ssid_len);
 		if (!bss)
 			return;
 	} else {
@@ -1573,10 +1560,6 @@
 
 	bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
 	bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
-	if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) {
-		memcpy(bss->ssid, elems.ssid, elems.ssid_len);
-		bss->ssid_len = elems.ssid_len;
-	}
 
 	bss->supp_rates_len = 0;
 	if (elems.supp_rates) {
@@ -1647,7 +1630,6 @@
 
 
 	bss->hw_mode = rx_status->phymode;
-	bss->channel = channel;
 	bss->freq = rx_status->freq;
 	if (channel != rx_status->channel &&
 	    (bss->hw_mode == MODE_IEEE80211G ||
@@ -1707,9 +1689,7 @@
 	if (baselen > len)
 		return;
 
-	if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
-				   &elems) == ParseFailed)
-		return;
+	ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
 
 	if (elems.erp_info && elems.erp_info_len >= 1)
 		ieee80211_handle_erp_ie(dev, elems.erp_info[0]);
@@ -2375,7 +2355,7 @@
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sta_bss *bss;
-	struct ieee80211_sub_if_data *sdata;
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct ieee80211_hw_mode *mode;
 	u8 bssid[ETH_ALEN], *pos;
 	int i;
@@ -2398,18 +2378,17 @@
 	printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n",
 	       dev->name, print_mac(mac, bssid));
 
-	bss = ieee80211_rx_bss_add(dev, bssid);
+	bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel,
+				   sdata->u.sta.ssid, sdata->u.sta.ssid_len);
 	if (!bss)
 		return -ENOMEM;
 
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	mode = local->oper_hw_mode;
 
 	if (local->hw.conf.beacon_int == 0)
 		local->hw.conf.beacon_int = 100;
 	bss->beacon_int = local->hw.conf.beacon_int;
 	bss->hw_mode = local->hw.conf.phymode;
-	bss->channel = local->hw.conf.channel;
 	bss->freq = local->hw.conf.freq;
 	bss->last_update = jiffies;
 	bss->capability = WLAN_CAPABILITY_IBSS;
@@ -2469,7 +2448,8 @@
 	       "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid));
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
 	if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
-	    (bss = ieee80211_rx_bss_get(dev, bssid))) {
+	    (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel,
+					ifsta->ssid, ifsta->ssid_len))) {
 		printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
 		       " based on configured SSID\n",
 		       dev->name, print_mac(mac, bssid));
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 6675261..a84a233 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -16,7 +16,7 @@
 #include <linux/crypto.h>
 #include <linux/err.h>
 #include <linux/mm.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
@@ -138,9 +138,7 @@
 	*icv = cpu_to_le32(~crc32_le(~0, data, data_len));
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
-	sg.offset = offset_in_page(data);
-	sg.length = data_len + WEP_ICV_LEN;
+	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
 }
 
@@ -204,9 +202,7 @@
 	__le32 crc;
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
-	sg.page = virt_to_page(data);
-	sg.offset = offset_in_page(data);
-	sg.length = data_len + WEP_ICV_LEN;
+	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
 
 	crc = cpu_to_le32(~crc32_le(~0, data, data_len));
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index d8b5018..13f8191 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -70,7 +70,6 @@
 static struct ctl_table_header *generic_sysctl_header;
 static struct ctl_table generic_sysctl_table[] = {
 	{
-		.ctl_name	= NET_NF_CONNTRACK_GENERIC_TIMEOUT,
 		.procname	= "nf_conntrack_generic_timeout",
 		.data		= &nf_ct_generic_timeout,
 		.maxlen		= sizeof(unsigned int),
@@ -84,7 +83,6 @@
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 static struct ctl_table generic_compat_sysctl_table[] = {
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT,
 		.procname	= "ip_conntrack_generic_timeout",
 		.data		= &nf_ct_generic_timeout,
 		.maxlen		= sizeof(unsigned int),
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 04192ac..cb04675 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -476,7 +476,6 @@
 static struct ctl_table_header *sctp_sysctl_header;
 static struct ctl_table sctp_sysctl_table[] = {
 	{
-		.ctl_name	= NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
 		.procname	= "nf_conntrack_sctp_timeout_closed",
 		.data		= &nf_ct_sctp_timeout_closed,
 		.maxlen		= sizeof(unsigned int),
@@ -484,7 +483,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
 		.procname	= "nf_conntrack_sctp_timeout_cookie_wait",
 		.data		= &nf_ct_sctp_timeout_cookie_wait,
 		.maxlen		= sizeof(unsigned int),
@@ -492,7 +490,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
 		.procname	= "nf_conntrack_sctp_timeout_cookie_echoed",
 		.data		= &nf_ct_sctp_timeout_cookie_echoed,
 		.maxlen		= sizeof(unsigned int),
@@ -500,7 +497,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
 		.procname	= "nf_conntrack_sctp_timeout_established",
 		.data		= &nf_ct_sctp_timeout_established,
 		.maxlen		= sizeof(unsigned int),
@@ -508,7 +504,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
 		.procname	= "nf_conntrack_sctp_timeout_shutdown_sent",
 		.data		= &nf_ct_sctp_timeout_shutdown_sent,
 		.maxlen		= sizeof(unsigned int),
@@ -516,7 +511,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
 		.procname	= "nf_conntrack_sctp_timeout_shutdown_recd",
 		.data		= &nf_ct_sctp_timeout_shutdown_recd,
 		.maxlen		= sizeof(unsigned int),
@@ -524,7 +518,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
 		.procname	= "nf_conntrack_sctp_timeout_shutdown_ack_sent",
 		.data		= &nf_ct_sctp_timeout_shutdown_ack_sent,
 		.maxlen		= sizeof(unsigned int),
@@ -539,7 +532,6 @@
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 static struct ctl_table sctp_compat_sysctl_table[] = {
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
 		.procname	= "ip_conntrack_sctp_timeout_closed",
 		.data		= &nf_ct_sctp_timeout_closed,
 		.maxlen		= sizeof(unsigned int),
@@ -547,7 +539,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
 		.procname	= "ip_conntrack_sctp_timeout_cookie_wait",
 		.data		= &nf_ct_sctp_timeout_cookie_wait,
 		.maxlen		= sizeof(unsigned int),
@@ -555,7 +546,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
 		.procname	= "ip_conntrack_sctp_timeout_cookie_echoed",
 		.data		= &nf_ct_sctp_timeout_cookie_echoed,
 		.maxlen		= sizeof(unsigned int),
@@ -563,7 +553,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
 		.procname	= "ip_conntrack_sctp_timeout_established",
 		.data		= &nf_ct_sctp_timeout_established,
 		.maxlen		= sizeof(unsigned int),
@@ -571,7 +560,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
 		.procname	= "ip_conntrack_sctp_timeout_shutdown_sent",
 		.data		= &nf_ct_sctp_timeout_shutdown_sent,
 		.maxlen		= sizeof(unsigned int),
@@ -579,7 +567,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
 		.procname	= "ip_conntrack_sctp_timeout_shutdown_recd",
 		.data		= &nf_ct_sctp_timeout_shutdown_recd,
 		.maxlen		= sizeof(unsigned int),
@@ -587,7 +574,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
 		.procname	= "ip_conntrack_sctp_timeout_shutdown_ack_sent",
 		.data		= &nf_ct_sctp_timeout_shutdown_ack_sent,
 		.maxlen		= sizeof(unsigned int),
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index c707534..7a3f64c 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -834,10 +834,12 @@
 	case TCP_CONNTRACK_SYN_SENT:
 		if (old_state < TCP_CONNTRACK_TIME_WAIT)
 			break;
-		if (conntrack->proto.tcp.seen[!dir].flags &
-			IP_CT_TCP_FLAG_CLOSE_INIT) {
-			/* Attempt to reopen a closed connection.
-			* Delete this connection and look up again. */
+		if ((conntrack->proto.tcp.seen[!dir].flags &
+			IP_CT_TCP_FLAG_CLOSE_INIT)
+		    || (conntrack->proto.tcp.last_dir == dir
+		        && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
+			/* Attempt to reopen a closed/aborted connection.
+			 * Delete this connection and look up again. */
 			write_unlock_bh(&tcp_lock);
 			if (del_timer(&conntrack->timeout))
 				conntrack->timeout.function((unsigned long)
@@ -925,6 +927,7 @@
      in_window:
 	/* From now on we have got in-window packets */
 	conntrack->proto.tcp.last_index = index;
+	conntrack->proto.tcp.last_dir = dir;
 
 	pr_debug("tcp_conntracks: ");
 	NF_CT_DUMP_TUPLE(tuple);
@@ -1162,7 +1165,6 @@
 static struct ctl_table_header *tcp_sysctl_header;
 static struct ctl_table tcp_sysctl_table[] = {
 	{
-		.ctl_name	= NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
 		.procname	= "nf_conntrack_tcp_timeout_syn_sent",
 		.data		= &nf_ct_tcp_timeout_syn_sent,
 		.maxlen		= sizeof(unsigned int),
@@ -1170,7 +1172,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
 		.procname	= "nf_conntrack_tcp_timeout_syn_recv",
 		.data		= &nf_ct_tcp_timeout_syn_recv,
 		.maxlen		= sizeof(unsigned int),
@@ -1178,7 +1179,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
 		.procname	= "nf_conntrack_tcp_timeout_established",
 		.data		= &nf_ct_tcp_timeout_established,
 		.maxlen		= sizeof(unsigned int),
@@ -1186,7 +1186,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
 		.procname	= "nf_conntrack_tcp_timeout_fin_wait",
 		.data		= &nf_ct_tcp_timeout_fin_wait,
 		.maxlen		= sizeof(unsigned int),
@@ -1194,7 +1193,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
 		.procname	= "nf_conntrack_tcp_timeout_close_wait",
 		.data		= &nf_ct_tcp_timeout_close_wait,
 		.maxlen		= sizeof(unsigned int),
@@ -1202,7 +1200,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
 		.procname	= "nf_conntrack_tcp_timeout_last_ack",
 		.data		= &nf_ct_tcp_timeout_last_ack,
 		.maxlen		= sizeof(unsigned int),
@@ -1210,7 +1207,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
 		.procname	= "nf_conntrack_tcp_timeout_time_wait",
 		.data		= &nf_ct_tcp_timeout_time_wait,
 		.maxlen		= sizeof(unsigned int),
@@ -1218,7 +1214,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
 		.procname	= "nf_conntrack_tcp_timeout_close",
 		.data		= &nf_ct_tcp_timeout_close,
 		.maxlen		= sizeof(unsigned int),
@@ -1226,7 +1221,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
 		.procname	= "nf_conntrack_tcp_timeout_max_retrans",
 		.data		= &nf_ct_tcp_timeout_max_retrans,
 		.maxlen		= sizeof(unsigned int),
@@ -1265,7 +1259,6 @@
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 static struct ctl_table tcp_compat_sysctl_table[] = {
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
 		.procname	= "ip_conntrack_tcp_timeout_syn_sent",
 		.data		= &nf_ct_tcp_timeout_syn_sent,
 		.maxlen		= sizeof(unsigned int),
@@ -1273,7 +1266,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
 		.procname	= "ip_conntrack_tcp_timeout_syn_recv",
 		.data		= &nf_ct_tcp_timeout_syn_recv,
 		.maxlen		= sizeof(unsigned int),
@@ -1281,7 +1273,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
 		.procname	= "ip_conntrack_tcp_timeout_established",
 		.data		= &nf_ct_tcp_timeout_established,
 		.maxlen		= sizeof(unsigned int),
@@ -1289,7 +1280,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
 		.procname	= "ip_conntrack_tcp_timeout_fin_wait",
 		.data		= &nf_ct_tcp_timeout_fin_wait,
 		.maxlen		= sizeof(unsigned int),
@@ -1297,7 +1287,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
 		.procname	= "ip_conntrack_tcp_timeout_close_wait",
 		.data		= &nf_ct_tcp_timeout_close_wait,
 		.maxlen		= sizeof(unsigned int),
@@ -1305,7 +1294,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
 		.procname	= "ip_conntrack_tcp_timeout_last_ack",
 		.data		= &nf_ct_tcp_timeout_last_ack,
 		.maxlen		= sizeof(unsigned int),
@@ -1313,7 +1301,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
 		.procname	= "ip_conntrack_tcp_timeout_time_wait",
 		.data		= &nf_ct_tcp_timeout_time_wait,
 		.maxlen		= sizeof(unsigned int),
@@ -1321,7 +1308,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
 		.procname	= "ip_conntrack_tcp_timeout_close",
 		.data		= &nf_ct_tcp_timeout_close,
 		.maxlen		= sizeof(unsigned int),
@@ -1329,7 +1315,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
 		.procname	= "ip_conntrack_tcp_timeout_max_retrans",
 		.data		= &nf_ct_tcp_timeout_max_retrans,
 		.maxlen		= sizeof(unsigned int),
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index ba80e1a..b3e7ecb 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -146,7 +146,6 @@
 static struct ctl_table_header *udp_sysctl_header;
 static struct ctl_table udp_sysctl_table[] = {
 	{
-		.ctl_name	= NET_NF_CONNTRACK_UDP_TIMEOUT,
 		.procname	= "nf_conntrack_udp_timeout",
 		.data		= &nf_ct_udp_timeout,
 		.maxlen		= sizeof(unsigned int),
@@ -154,7 +153,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
 		.procname	= "nf_conntrack_udp_timeout_stream",
 		.data		= &nf_ct_udp_timeout_stream,
 		.maxlen		= sizeof(unsigned int),
@@ -168,7 +166,6 @@
 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
 static struct ctl_table udp_compat_sysctl_table[] = {
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT,
 		.procname	= "ip_conntrack_udp_timeout",
 		.data		= &nf_ct_udp_timeout,
 		.maxlen		= sizeof(unsigned int),
@@ -176,7 +173,6 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 	},
 	{
-		.ctl_name	= NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
 		.procname	= "ip_conntrack_udp_timeout_stream",
 		.data		= &nf_ct_udp_timeout_stream,
 		.maxlen		= sizeof(unsigned int),
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index 8cc324b..856793e 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -23,7 +23,7 @@
 #include <linux/ip.h>
 #include <net/checksum.h>
 
-MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
+MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
 MODULE_DESCRIPTION("IP tables CONNMARK matching module");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_CONNMARK");
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index af79423..9ec5013 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -2,13 +2,13 @@
  * GPL (C) 2002 Martin Devera (devik@cdi.cz).
  */
 #include <linux/module.h>
+#include <linux/bitops.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_connbytes.h>
 #include <net/netfilter/nf_conntrack.h>
 
 #include <asm/div64.h>
-#include <asm/bitops.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index 1071fc5..9f67920 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -25,7 +25,7 @@
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_connmark.h>
 
-MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
+MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
 MODULE_DESCRIPTION("IP tables connmark match module");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_connmark");
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c
index 4fcca79..f263a77 100644
--- a/net/netfilter/xt_limit.c
+++ b/net/netfilter/xt_limit.c
@@ -1,5 +1,5 @@
-/* (C) 1999 Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
- * (C) 1999 Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
+/* (C) 1999 Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
+ * (C) 1999 Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c
index f907770..3358273 100644
--- a/net/netfilter/xt_sctp.c
+++ b/net/netfilter/xt_sctp.c
@@ -42,21 +42,21 @@
 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,
+	     const struct xt_sctp_info *info,
 	     bool *hotdrop)
 {
 	u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
 	sctp_chunkhdr_t _sch, *sch;
+	int chunk_match_type = info->chunk_match_type;
+	const struct xt_sctp_flag_info *flag_info = info->flag_info;
+	int flag_count = info->flag_count;
 
 #ifdef DEBUG_SCTP
 	int i = 0;
 #endif
 
 	if (chunk_match_type == SCTP_CHUNK_MATCH_ALL)
-		SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
+		SCTP_CHUNKMAP_COPY(chunkmapcopy, info->chunkmap);
 
 	do {
 		sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch);
@@ -73,7 +73,7 @@
 
 		duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
 
-		if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch->type)) {
+		if (SCTP_CHUNKMAP_IS_SET(info->chunkmap, sch->type)) {
 			switch (chunk_match_type) {
 			case SCTP_CHUNK_MATCH_ANY:
 				if (match_flags(flag_info, flag_count,
@@ -104,7 +104,7 @@
 
 	switch (chunk_match_type) {
 	case SCTP_CHUNK_MATCH_ALL:
-		return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
+		return SCTP_CHUNKMAP_IS_CLEAR(info->chunkmap);
 	case SCTP_CHUNK_MATCH_ANY:
 		return false;
 	case SCTP_CHUNK_MATCH_ONLY:
@@ -148,9 +148,7 @@
 			&& 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,
-					info->flag_info, info->flag_count,
-					hotdrop),
+					info, hotdrop),
 			   XT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
 }
 
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index e11000a..d093650 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1623,11 +1623,6 @@
 	.close =packet_mm_close,
 };
 
-static inline struct page *pg_vec_endpage(char *one_pg_vec, unsigned int order)
-{
-	return virt_to_page(one_pg_vec + (PAGE_SIZE << order) - 1);
-}
-
 static void free_pg_vec(char **pg_vec, unsigned int order, unsigned int len)
 {
 	int i;
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index eaabf08..d1e9d68 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -146,18 +146,18 @@
 static const struct input_device_id rfkill_ids[] = {
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-		.evbit = { BIT(EV_KEY) },
-		.keybit = { [LONG(KEY_WLAN)] = BIT(KEY_WLAN) },
+		.evbit = { BIT_MASK(EV_KEY) },
+		.keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) },
 	},
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-		.evbit = { BIT(EV_KEY) },
-		.keybit = { [LONG(KEY_BLUETOOTH)] = BIT(KEY_BLUETOOTH) },
+		.evbit = { BIT_MASK(EV_KEY) },
+		.keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) },
 	},
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-		.evbit = { BIT(EV_KEY) },
-		.keybit = { [LONG(KEY_UWB)] = BIT(KEY_UWB) },
+		.evbit = { BIT_MASK(EV_KEY) },
+		.keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },
 	},
 	{ }
 };
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 92435a8..9c15c488 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -2,9 +2,7 @@
 # Traffic control configuration.
 # 
 
-menu "QoS and/or fair queueing"
-
-config NET_SCHED
+menuconfig NET_SCHED
 	bool "QoS and/or fair queueing"
 	select NET_SCH_FIFO
 	---help---
@@ -41,9 +39,6 @@
 	  The available schedulers are listed in the following questions; you
 	  can say Y to as many as you like. If unsure, say N now.
 
-config NET_SCH_FIFO
-	bool
-
 if NET_SCHED
 
 comment "Queueing/Scheduling"
@@ -500,4 +495,5 @@
 
 endif # NET_SCHED
 
-endmenu
+config NET_SCH_FIFO
+	bool
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index e998961..ceda889 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -55,7 +55,7 @@
  * 	ppp0..9.
  *
  * 	NOTE: Certain meta values depend on other subsystems and are
- * 	      only available if that subsytem is enabled in the kernel.
+ * 	      only available if that subsystem is enabled in the kernel.
  */
 
 #include <linux/module.h>
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 95ae119..fa1a6f4 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -249,10 +249,11 @@
  */
 void netif_carrier_on(struct net_device *dev)
 {
-	if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state))
+	if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) {
 		linkwatch_fire_event(dev);
-	if (netif_running(dev))
-		__netdev_watchdog_up(dev);
+		if (netif_running(dev))
+			__netdev_watchdog_up(dev);
+	}
 }
 
 /**
@@ -555,6 +556,7 @@
 {
 	struct Qdisc *qdisc;
 	struct sk_buff *skb;
+	int running;
 
 	spin_lock_bh(&dev->queue_lock);
 	qdisc = dev->qdisc;
@@ -570,12 +572,31 @@
 
 	dev_watchdog_down(dev);
 
-	/* Wait for outstanding dev_queue_xmit calls. */
+	/* Wait for outstanding qdisc-less dev_queue_xmit calls. */
 	synchronize_rcu();
 
 	/* Wait for outstanding qdisc_run calls. */
-	while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
-		yield();
+	do {
+		while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
+			yield();
+
+		/*
+		 * Double-check inside queue lock to ensure that all effects
+		 * of the queue run are visible when we return.
+		 */
+		spin_lock_bh(&dev->queue_lock);
+		running = test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
+		spin_unlock_bh(&dev->queue_lock);
+
+		/*
+		 * The running flag should never be set at this point because
+		 * we've already set dev->qdisc to noop_qdisc *inside* the same
+		 * pair of spin locks.  That is, if any qdisc_run starts after
+		 * our initial test it should see the noop_qdisc and then
+		 * clear the RUNNING bit before dropping the queue lock.  So
+		 * if it is set here then we've found a bug.
+		 */
+	} while (WARN_ON_ONCE(running));
 }
 
 void dev_init_scheduler(struct net_device *dev)
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index be57cf3..421281d 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -266,7 +266,7 @@
 	int busy;
 	int nores;
 	int len = skb->len;
-	int subq = skb->queue_mapping;
+	int subq = skb_get_queue_mapping(skb);
 	struct sk_buff *skb_res = NULL;
 
 	start = master->slaves;
@@ -284,7 +284,7 @@
 		if (slave->qdisc_sleeping != q)
 			continue;
 		if (netif_queue_stopped(slave) ||
-		    netif_subqueue_stopped(slave, subq) ||
+		    __netif_subqueue_stopped(slave, subq) ||
 		    !netif_running(slave)) {
 			busy = 1;
 			continue;
@@ -294,7 +294,7 @@
 		case 0:
 			if (netif_tx_trylock(slave)) {
 				if (!netif_queue_stopped(slave) &&
-				    !netif_subqueue_stopped(slave, subq) &&
+				    !__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/auth.c b/net/sctp/auth.c
index 7818107..cbd64b2 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -726,7 +726,8 @@
 
 	/* set up scatter list */
 	end = skb_tail_pointer(skb);
-	sg.page = virt_to_page(auth);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(auth));
 	sg.offset = (unsigned long)(auth) % PAGE_SIZE;
 	sg.length = end - (unsigned char *)auth;
 
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index f983a36..658476c 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -56,7 +56,7 @@
 #include <linux/ipv6.h>
 #include <linux/net.h>
 #include <linux/inet.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <linux/crypto.h>
 #include <net/sock.h>
 
@@ -1513,7 +1513,8 @@
 		struct hash_desc desc;
 
 		/* Sign the message.  */
-		sg.page = virt_to_page(&cookie->c);
+		sg_init_table(&sg, 1);
+		sg_set_page(&sg, virt_to_page(&cookie->c));
 		sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
 		sg.length = bodysize;
 		keylen = SCTP_SECRET_SIZE;
@@ -1585,7 +1586,8 @@
 
 	/* Check the signature.  */
 	keylen = SCTP_SECRET_SIZE;
-	sg.page = virt_to_page(bear_cookie);
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, virt_to_page(bear_cookie));
 	sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
 	sg.length = bodysize;
 	key = (char *)ep->secret_key[ep->current_key];
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index bfb6a29..32be431 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -197,9 +197,9 @@
 		int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
 		in_page = desc->pages[i];
 	} else {
-		in_page = sg->page;
+		in_page = sg_page(sg);
 	}
-	desc->infrags[desc->fragno].page = in_page;
+	sg_set_page(&desc->infrags[desc->fragno], in_page);
 	desc->fragno++;
 	desc->fraglen += sg->length;
 	desc->pos += sg->length;
@@ -215,11 +215,11 @@
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->outfrags[0].page = sg->page;
+		sg_set_page(&desc->outfrags[0], sg_page(sg));
 		desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
 		desc->outfrags[0].length = fraglen;
 		desc->infrags[0] = desc->outfrags[0];
-		desc->infrags[0].page = in_page;
+		sg_set_page(&desc->infrags[0], in_page);
 		desc->fragno = 1;
 		desc->fraglen = fraglen;
 	} else {
@@ -287,7 +287,7 @@
 	if (ret)
 		return ret;
 	if (fraglen) {
-		desc->frags[0].page = sg->page;
+		sg_set_page(&desc->frags[0], sg_page(sg));
 		desc->frags[0].offset = sg->offset + sg->length - fraglen;
 		desc->frags[0].length = fraglen;
 		desc->fragno = 1;
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 3c773c5..c98873f 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -847,7 +847,7 @@
 	task->tk_start = jiffies;
 
 	dprintk("RPC:       new task initialized, procpid %u\n",
-				current->pid);
+				task_pid_nr(current));
 }
 
 static struct rpc_task *
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index 738db32..864b541b 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -114,7 +114,6 @@
 
 static ctl_table debug_table[] = {
 	{
-		.ctl_name	= CTL_RPCDEBUG,
 		.procname	= "rpc_debug",
 		.data		= &rpc_debug,
 		.maxlen		= sizeof(int),
@@ -122,7 +121,6 @@
 		.proc_handler	= &proc_dodebug
 	},
 	{
-		.ctl_name	= CTL_NFSDEBUG,
 		.procname	= "nfs_debug",
 		.data		= &nfs_debug,
 		.maxlen		= sizeof(int),
@@ -130,7 +128,6 @@
 		.proc_handler	= &proc_dodebug
 	},
 	{
-		.ctl_name	= CTL_NFSDDEBUG,
 		.procname	= "nfsd_debug",
 		.data		= &nfsd_debug,
 		.maxlen		= sizeof(int),
@@ -138,7 +135,6 @@
 		.proc_handler	= &proc_dodebug
 	},
 	{
-		.ctl_name	= CTL_NLMDEBUG,
 		.procname	= "nlm_debug",
 		.data		= &nlm_debug,
 		.maxlen		= sizeof(int),
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 6a59180..3d1f7cd 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -1059,7 +1059,7 @@
 		do {
 			if (thislen > page_len)
 				thislen = page_len;
-			sg->page = buf->pages[i];
+			sg_set_page(sg, buf->pages[i]);
 			sg->offset = page_offset;
 			sg->length = thislen;
 			ret = actor(sg, data);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 6996cba..9163ec5 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -483,7 +483,7 @@
 	sk->sk_max_ack_backlog	= backlog;
 	sk->sk_state		= TCP_LISTEN;
 	/* set credentials so connect can copy them */
-	sk->sk_peercred.pid	= current->tgid;
+	sk->sk_peercred.pid	= task_tgid_vnr(current);
 	sk->sk_peercred.uid	= current->euid;
 	sk->sk_peercred.gid	= current->egid;
 	err = 0;
@@ -1133,7 +1133,7 @@
 	unix_peer(newsk)	= sk;
 	newsk->sk_state		= TCP_ESTABLISHED;
 	newsk->sk_type		= sk->sk_type;
-	newsk->sk_peercred.pid	= current->tgid;
+	newsk->sk_peercred.pid	= task_tgid_vnr(current);
 	newsk->sk_peercred.uid	= current->euid;
 	newsk->sk_peercred.gid	= current->egid;
 	newu = unix_sk(newsk);
@@ -1194,7 +1194,7 @@
 	sock_hold(skb);
 	unix_peer(ska)=skb;
 	unix_peer(skb)=ska;
-	ska->sk_peercred.pid = skb->sk_peercred.pid = current->tgid;
+	ska->sk_peercred.pid = skb->sk_peercred.pid = task_tgid_vnr(current);
 	ska->sk_peercred.uid = skb->sk_peercred.uid = current->euid;
 	ska->sk_peercred.gid = skb->sk_peercred.gid = current->egid;
 
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 5ced62c..313d4be 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/pfkeyv2.h>
 #include <linux/crypto.h>
+#include <linux/scatterlist.h>
 #include <net/xfrm.h>
 #if defined(CONFIG_INET_AH) || defined(CONFIG_INET_AH_MODULE) || defined(CONFIG_INET6_AH) || defined(CONFIG_INET6_AH_MODULE)
 #include <net/ah.h>
@@ -552,7 +553,7 @@
 		if (copy > len)
 			copy = len;
 
-		sg.page = virt_to_page(skb->data + offset);
+		sg_set_page(&sg, virt_to_page(skb->data + offset));
 		sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
 		sg.length = copy;
 
@@ -577,7 +578,7 @@
 			if (copy > len)
 				copy = len;
 
-			sg.page = frag->page;
+			sg_set_page(&sg, frag->page);
 			sg.offset = frag->page_offset + offset-start;
 			sg.length = copy;
 
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 113f444..cb97fda 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -49,13 +49,16 @@
 int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
 {
 	int offset, offset_seq;
+	int hlen;
 
 	switch (nexthdr) {
 	case IPPROTO_AH:
+		hlen = sizeof(struct ip_auth_hdr);
 		offset = offsetof(struct ip_auth_hdr, spi);
 		offset_seq = offsetof(struct ip_auth_hdr, seq_no);
 		break;
 	case IPPROTO_ESP:
+		hlen = sizeof(struct ip_esp_hdr);
 		offset = offsetof(struct ip_esp_hdr, spi);
 		offset_seq = offsetof(struct ip_esp_hdr, seq_no);
 		break;
@@ -69,7 +72,7 @@
 		return 1;
 	}
 
-	if (!pskb_may_pull(skb, 16))
+	if (!pskb_may_pull(skb, hlen))
 		return -EINVAL;
 
 	*spi = *(__be32*)(skb_transport_header(skb) + offset);
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 0eb3377..f4bfd6c 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -63,7 +63,7 @@
 				xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
 		}
 
-		err = x->mode->output(x, skb);
+		err = x->outer_mode->output(x, skb);
 		if (err)
 			goto error;
 
@@ -82,7 +82,7 @@
 		}
 		dst = skb->dst;
 		x = dst->xfrm;
-	} while (x && (x->props.mode != XFRM_MODE_TUNNEL));
+	} while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
 
 	err = 0;
 
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index af27c19..b702bd8 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -49,8 +49,6 @@
 
 static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
 static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
-static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family);
-static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo);
 
 static inline int
 __xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
@@ -86,72 +84,6 @@
 	return 0;
 }
 
-int xfrm_register_type(struct xfrm_type *type, unsigned short family)
-{
-	struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family);
-	struct xfrm_type **typemap;
-	int err = 0;
-
-	if (unlikely(afinfo == NULL))
-		return -EAFNOSUPPORT;
-	typemap = afinfo->type_map;
-
-	if (likely(typemap[type->proto] == NULL))
-		typemap[type->proto] = type;
-	else
-		err = -EEXIST;
-	xfrm_policy_unlock_afinfo(afinfo);
-	return err;
-}
-EXPORT_SYMBOL(xfrm_register_type);
-
-int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
-{
-	struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family);
-	struct xfrm_type **typemap;
-	int err = 0;
-
-	if (unlikely(afinfo == NULL))
-		return -EAFNOSUPPORT;
-	typemap = afinfo->type_map;
-
-	if (unlikely(typemap[type->proto] != type))
-		err = -ENOENT;
-	else
-		typemap[type->proto] = NULL;
-	xfrm_policy_unlock_afinfo(afinfo);
-	return err;
-}
-EXPORT_SYMBOL(xfrm_unregister_type);
-
-struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
-{
-	struct xfrm_policy_afinfo *afinfo;
-	struct xfrm_type **typemap;
-	struct xfrm_type *type;
-	int modload_attempted = 0;
-
-retry:
-	afinfo = xfrm_policy_get_afinfo(family);
-	if (unlikely(afinfo == NULL))
-		return NULL;
-	typemap = afinfo->type_map;
-
-	type = typemap[proto];
-	if (unlikely(type && !try_module_get(type->owner)))
-		type = NULL;
-	if (!type && !modload_attempted) {
-		xfrm_policy_put_afinfo(afinfo);
-		request_module("xfrm-type-%d-%d",
-			       (int) family, (int) proto);
-		modload_attempted = 1;
-		goto retry;
-	}
-
-	xfrm_policy_put_afinfo(afinfo);
-	return type;
-}
-
 int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
 		    unsigned short family)
 {
@@ -170,94 +102,6 @@
 }
 EXPORT_SYMBOL(xfrm_dst_lookup);
 
-void xfrm_put_type(struct xfrm_type *type)
-{
-	module_put(type->owner);
-}
-
-int xfrm_register_mode(struct xfrm_mode *mode, int family)
-{
-	struct xfrm_policy_afinfo *afinfo;
-	struct xfrm_mode **modemap;
-	int err;
-
-	if (unlikely(mode->encap >= XFRM_MODE_MAX))
-		return -EINVAL;
-
-	afinfo = xfrm_policy_lock_afinfo(family);
-	if (unlikely(afinfo == NULL))
-		return -EAFNOSUPPORT;
-
-	err = -EEXIST;
-	modemap = afinfo->mode_map;
-	if (likely(modemap[mode->encap] == NULL)) {
-		modemap[mode->encap] = mode;
-		err = 0;
-	}
-
-	xfrm_policy_unlock_afinfo(afinfo);
-	return err;
-}
-EXPORT_SYMBOL(xfrm_register_mode);
-
-int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
-{
-	struct xfrm_policy_afinfo *afinfo;
-	struct xfrm_mode **modemap;
-	int err;
-
-	if (unlikely(mode->encap >= XFRM_MODE_MAX))
-		return -EINVAL;
-
-	afinfo = xfrm_policy_lock_afinfo(family);
-	if (unlikely(afinfo == NULL))
-		return -EAFNOSUPPORT;
-
-	err = -ENOENT;
-	modemap = afinfo->mode_map;
-	if (likely(modemap[mode->encap] == mode)) {
-		modemap[mode->encap] = NULL;
-		err = 0;
-	}
-
-	xfrm_policy_unlock_afinfo(afinfo);
-	return err;
-}
-EXPORT_SYMBOL(xfrm_unregister_mode);
-
-struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
-{
-	struct xfrm_policy_afinfo *afinfo;
-	struct xfrm_mode *mode;
-	int modload_attempted = 0;
-
-	if (unlikely(encap >= XFRM_MODE_MAX))
-		return NULL;
-
-retry:
-	afinfo = xfrm_policy_get_afinfo(family);
-	if (unlikely(afinfo == NULL))
-		return NULL;
-
-	mode = afinfo->mode_map[encap];
-	if (unlikely(mode && !try_module_get(mode->owner)))
-		mode = NULL;
-	if (!mode && !modload_attempted) {
-		xfrm_policy_put_afinfo(afinfo);
-		request_module("xfrm-mode-%d-%d", family, encap);
-		modload_attempted = 1;
-		goto retry;
-	}
-
-	xfrm_policy_put_afinfo(afinfo);
-	return mode;
-}
-
-void xfrm_put_mode(struct xfrm_mode *mode)
-{
-	module_put(mode->owner);
-}
-
 static inline unsigned long make_jiffies(long secs)
 {
 	if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ)
@@ -2096,7 +1940,8 @@
 		if (xdst->genid != dst->xfrm->genid)
 			return 0;
 
-		if (strict && fl && dst->xfrm->props.mode != XFRM_MODE_TUNNEL &&
+		if (strict && fl &&
+		    !(dst->xfrm->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
 		    !xfrm_state_addr_flow_check(dst->xfrm, fl, family))
 			return 0;
 
@@ -2213,23 +2058,6 @@
 	read_unlock(&xfrm_policy_afinfo_lock);
 }
 
-static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family)
-{
-	struct xfrm_policy_afinfo *afinfo;
-	if (unlikely(family >= NPROTO))
-		return NULL;
-	write_lock_bh(&xfrm_policy_afinfo_lock);
-	afinfo = xfrm_policy_afinfo[family];
-	if (unlikely(!afinfo))
-		write_unlock_bh(&xfrm_policy_afinfo_lock);
-	return afinfo;
-}
-
-static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo)
-{
-	write_unlock_bh(&xfrm_policy_afinfo_lock);
-}
-
 static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
 	struct net_device *dev = ptr;
@@ -2464,7 +2292,8 @@
 			if (!migrate_tmpl_match(mp, &pol->xfrm_vec[i]))
 				continue;
 			n++;
-			if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL)
+			if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL &&
+			    pol->xfrm_vec[i].mode != XFRM_MODE_BEET)
 				continue;
 			/* update endpoints */
 			memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr,
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 344f0a6..224b44e 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -57,6 +57,9 @@
 static unsigned int xfrm_state_num;
 static unsigned int xfrm_state_genid;
 
+static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
+static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
+
 static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr,
 					 xfrm_address_t *saddr,
 					 u32 reqid,
@@ -187,6 +190,184 @@
 int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
 void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
 
+static struct xfrm_state_afinfo *xfrm_state_lock_afinfo(unsigned int family)
+{
+	struct xfrm_state_afinfo *afinfo;
+	if (unlikely(family >= NPROTO))
+		return NULL;
+	write_lock_bh(&xfrm_state_afinfo_lock);
+	afinfo = xfrm_state_afinfo[family];
+	if (unlikely(!afinfo))
+		write_unlock_bh(&xfrm_state_afinfo_lock);
+	return afinfo;
+}
+
+static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo)
+{
+	write_unlock_bh(&xfrm_state_afinfo_lock);
+}
+
+int xfrm_register_type(struct xfrm_type *type, unsigned short family)
+{
+	struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
+	struct xfrm_type **typemap;
+	int err = 0;
+
+	if (unlikely(afinfo == NULL))
+		return -EAFNOSUPPORT;
+	typemap = afinfo->type_map;
+
+	if (likely(typemap[type->proto] == NULL))
+		typemap[type->proto] = type;
+	else
+		err = -EEXIST;
+	xfrm_state_unlock_afinfo(afinfo);
+	return err;
+}
+EXPORT_SYMBOL(xfrm_register_type);
+
+int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
+{
+	struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
+	struct xfrm_type **typemap;
+	int err = 0;
+
+	if (unlikely(afinfo == NULL))
+		return -EAFNOSUPPORT;
+	typemap = afinfo->type_map;
+
+	if (unlikely(typemap[type->proto] != type))
+		err = -ENOENT;
+	else
+		typemap[type->proto] = NULL;
+	xfrm_state_unlock_afinfo(afinfo);
+	return err;
+}
+EXPORT_SYMBOL(xfrm_unregister_type);
+
+static struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
+{
+	struct xfrm_state_afinfo *afinfo;
+	struct xfrm_type **typemap;
+	struct xfrm_type *type;
+	int modload_attempted = 0;
+
+retry:
+	afinfo = xfrm_state_get_afinfo(family);
+	if (unlikely(afinfo == NULL))
+		return NULL;
+	typemap = afinfo->type_map;
+
+	type = typemap[proto];
+	if (unlikely(type && !try_module_get(type->owner)))
+		type = NULL;
+	if (!type && !modload_attempted) {
+		xfrm_state_put_afinfo(afinfo);
+		request_module("xfrm-type-%d-%d", family, proto);
+		modload_attempted = 1;
+		goto retry;
+	}
+
+	xfrm_state_put_afinfo(afinfo);
+	return type;
+}
+
+static void xfrm_put_type(struct xfrm_type *type)
+{
+	module_put(type->owner);
+}
+
+int xfrm_register_mode(struct xfrm_mode *mode, int family)
+{
+	struct xfrm_state_afinfo *afinfo;
+	struct xfrm_mode **modemap;
+	int err;
+
+	if (unlikely(mode->encap >= XFRM_MODE_MAX))
+		return -EINVAL;
+
+	afinfo = xfrm_state_lock_afinfo(family);
+	if (unlikely(afinfo == NULL))
+		return -EAFNOSUPPORT;
+
+	err = -EEXIST;
+	modemap = afinfo->mode_map;
+	if (modemap[mode->encap])
+		goto out;
+
+	err = -ENOENT;
+	if (!try_module_get(afinfo->owner))
+		goto out;
+
+	mode->afinfo = afinfo;
+	modemap[mode->encap] = mode;
+	err = 0;
+
+out:
+	xfrm_state_unlock_afinfo(afinfo);
+	return err;
+}
+EXPORT_SYMBOL(xfrm_register_mode);
+
+int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
+{
+	struct xfrm_state_afinfo *afinfo;
+	struct xfrm_mode **modemap;
+	int err;
+
+	if (unlikely(mode->encap >= XFRM_MODE_MAX))
+		return -EINVAL;
+
+	afinfo = xfrm_state_lock_afinfo(family);
+	if (unlikely(afinfo == NULL))
+		return -EAFNOSUPPORT;
+
+	err = -ENOENT;
+	modemap = afinfo->mode_map;
+	if (likely(modemap[mode->encap] == mode)) {
+		modemap[mode->encap] = NULL;
+		module_put(mode->afinfo->owner);
+		err = 0;
+	}
+
+	xfrm_state_unlock_afinfo(afinfo);
+	return err;
+}
+EXPORT_SYMBOL(xfrm_unregister_mode);
+
+static struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
+{
+	struct xfrm_state_afinfo *afinfo;
+	struct xfrm_mode *mode;
+	int modload_attempted = 0;
+
+	if (unlikely(encap >= XFRM_MODE_MAX))
+		return NULL;
+
+retry:
+	afinfo = xfrm_state_get_afinfo(family);
+	if (unlikely(afinfo == NULL))
+		return NULL;
+
+	mode = afinfo->mode_map[encap];
+	if (unlikely(mode && !try_module_get(mode->owner)))
+		mode = NULL;
+	if (!mode && !modload_attempted) {
+		xfrm_state_put_afinfo(afinfo);
+		request_module("xfrm-mode-%d-%d", family, encap);
+		modload_attempted = 1;
+		goto retry;
+	}
+
+	xfrm_state_put_afinfo(afinfo);
+	return mode;
+}
+
+static void xfrm_put_mode(struct xfrm_mode *mode)
+{
+	module_put(mode->owner);
+}
+
 static void xfrm_state_gc_destroy(struct xfrm_state *x)
 {
 	del_timer_sync(&x->timer);
@@ -196,8 +377,10 @@
 	kfree(x->calg);
 	kfree(x->encap);
 	kfree(x->coaddr);
-	if (x->mode)
-		xfrm_put_mode(x->mode);
+	if (x->inner_mode)
+		xfrm_put_mode(x->inner_mode);
+	if (x->outer_mode)
+		xfrm_put_mode(x->outer_mode);
 	if (x->type) {
 		x->type->destructor(x);
 		xfrm_put_type(x->type);
@@ -1699,7 +1882,7 @@
 }
 EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
 
-struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family)
+static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
 {
 	struct xfrm_state_afinfo *afinfo;
 	if (unlikely(family >= NPROTO))
@@ -1711,14 +1894,11 @@
 	return afinfo;
 }
 
-void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
+static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
 {
 	read_unlock(&xfrm_state_afinfo_lock);
 }
 
-EXPORT_SYMBOL(xfrm_state_get_afinfo);
-EXPORT_SYMBOL(xfrm_state_put_afinfo);
-
 /* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
 void xfrm_state_delete_tunnel(struct xfrm_state *x)
 {
@@ -1769,6 +1949,14 @@
 		goto error;
 
 	err = -EPROTONOSUPPORT;
+	x->inner_mode = xfrm_get_mode(x->props.mode, x->sel.family);
+	if (x->inner_mode == NULL)
+		goto error;
+
+	if (!(x->inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
+	    family != x->sel.family)
+		goto error;
+
 	x->type = xfrm_get_type(x->id.proto, family);
 	if (x->type == NULL)
 		goto error;
@@ -1777,8 +1965,8 @@
 	if (err)
 		goto error;
 
-	x->mode = xfrm_get_mode(x->props.mode, family);
-	if (x->mode == NULL)
+	x->outer_mode = xfrm_get_mode(x->props.mode, family);
+	if (x->outer_mode == NULL)
 		goto error;
 
 	x->km.state = XFRM_STATE_VALID;
diff --git a/samples/Kconfig b/samples/Kconfig
new file mode 100644
index 0000000..57bb223
--- /dev/null
+++ b/samples/Kconfig
@@ -0,0 +1,16 @@
+# samples/Kconfig
+
+menuconfig SAMPLES
+	bool "Sample kernel code"
+	help
+	  You can build and test sample kernel code here.
+
+if SAMPLES
+
+config SAMPLE_MARKERS
+	tristate "Build markers examples -- loadable modules only"
+	depends on MARKERS && m
+	help
+	  This build markers example modules.
+
+endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
new file mode 100644
index 0000000..5a4f0b6
--- /dev/null
+++ b/samples/Makefile
@@ -0,0 +1,3 @@
+# Makefile for Linux samples code
+
+obj-$(CONFIG_SAMPLES)	+= markers/
diff --git a/samples/markers/Makefile b/samples/markers/Makefile
new file mode 100644
index 0000000..6d72312
--- /dev/null
+++ b/samples/markers/Makefile
@@ -0,0 +1,4 @@
+# builds the kprobes example kernel modules;
+# then to use one (as root):  insmod <module_name.ko>
+
+obj-$(CONFIG_SAMPLE_MARKERS) += probe-example.o marker-example.o
diff --git a/samples/markers/marker-example.c b/samples/markers/marker-example.c
new file mode 100644
index 0000000..e787c6d
--- /dev/null
+++ b/samples/markers/marker-example.c
@@ -0,0 +1,54 @@
+/* marker-example.c
+ *
+ * Executes a marker when /proc/marker-example is opened.
+ *
+ * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/marker.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+
+struct proc_dir_entry *pentry_example;
+
+static int my_open(struct inode *inode, struct file *file)
+{
+	int i;
+
+	trace_mark(subsystem_event, "%d %s", 123, "example string");
+	for (i = 0; i < 10; i++)
+		trace_mark(subsystem_eventb, MARK_NOARGS);
+	return -EPERM;
+}
+
+static struct file_operations mark_ops = {
+	.open = my_open,
+};
+
+static int example_init(void)
+{
+	printk(KERN_ALERT "example init\n");
+	pentry_example = create_proc_entry("marker-example", 0444, NULL);
+	if (pentry_example)
+		pentry_example->proc_fops = &mark_ops;
+	else
+		return -EPERM;
+	return 0;
+}
+
+static void example_exit(void)
+{
+	printk(KERN_ALERT "example exit\n");
+	remove_proc_entry("marker-example", NULL);
+}
+
+module_init(example_init)
+module_exit(example_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Marker example");
diff --git a/samples/markers/probe-example.c b/samples/markers/probe-example.c
new file mode 100644
index 0000000..238b2e3
--- /dev/null
+++ b/samples/markers/probe-example.c
@@ -0,0 +1,98 @@
+/* probe-example.c
+ *
+ * Connects two functions to marker call sites.
+ *
+ * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/marker.h>
+#include <asm/atomic.h>
+
+struct probe_data {
+	const char *name;
+	const char *format;
+	marker_probe_func *probe_func;
+};
+
+void probe_subsystem_event(const struct marker *mdata, void *private,
+	const char *format, ...)
+{
+	va_list ap;
+	/* Declare args */
+	unsigned int value;
+	const char *mystr;
+
+	/* Assign args */
+	va_start(ap, format);
+	value = va_arg(ap, typeof(value));
+	mystr = va_arg(ap, typeof(mystr));
+
+	/* Call printk */
+	printk(KERN_DEBUG "Value %u, string %s\n", value, mystr);
+
+	/* or count, check rights, serialize data in a buffer */
+
+	va_end(ap);
+}
+
+atomic_t eventb_count = ATOMIC_INIT(0);
+
+void probe_subsystem_eventb(const struct marker *mdata, void *private,
+	const char *format, ...)
+{
+	/* Increment counter */
+	atomic_inc(&eventb_count);
+}
+
+static struct probe_data probe_array[] =
+{
+	{	.name = "subsystem_event",
+		.format = "%d %s",
+		.probe_func = probe_subsystem_event },
+	{	.name = "subsystem_eventb",
+		.format = MARK_NOARGS,
+		.probe_func = probe_subsystem_eventb },
+};
+
+static int __init probe_init(void)
+{
+	int result;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(probe_array); i++) {
+		result = marker_probe_register(probe_array[i].name,
+				probe_array[i].format,
+				probe_array[i].probe_func, &probe_array[i]);
+		if (result)
+			printk(KERN_INFO "Unable to register probe %s\n",
+				probe_array[i].name);
+		result = marker_arm(probe_array[i].name);
+		if (result)
+			printk(KERN_INFO "Unable to arm probe %s\n",
+				probe_array[i].name);
+	}
+	return 0;
+}
+
+static void __exit probe_fini(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(probe_array); i++)
+		marker_probe_unregister(probe_array[i].name);
+	printk(KERN_INFO "Number of event b : %u\n",
+			atomic_read(&eventb_count));
+}
+
+module_init(probe_init);
+module_exit(probe_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("SUBSYSTEM Probe");
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index de7bb28..b96ea8d 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -56,6 +56,17 @@
 # gcc support functions
 # See documentation in Documentation/kbuild/makefiles.txt
 
+# cc-cross-prefix
+# Usage: CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu- m68k-linux-)
+# Return first prefix where a prefix$(CC) is found in PATH.
+# If no $(CC) found in PATH with listed prefixes return nothing
+cc-cross-prefix =  \
+	$(word 1, $(foreach c,$(1),                                   \
+		$(shell set -e;                                       \
+		if (which $(strip $(c))$(CC)) > /dev/null 2>&1 ; then \
+			echo $(c);                                    \
+		fi)))
+
 # output directory for tests below
 TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/)
 
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index e5c6ac7..0e4bd54 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -66,12 +66,15 @@
 #define FUNCTION      "-function"
 #define NOFUNCTION    "-nofunction"
 
+char *srctree;
+
 void usage (void)
 {
 	fprintf(stderr, "Usage: docproc {doc|depend} file\n");
 	fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n");
 	fprintf(stderr, "doc: frontend when generating kernel documentation\n");
 	fprintf(stderr, "depend: generate list of files referenced within file\n");
+	fprintf(stderr, "Environment variable SRCTREE: absolute path to kernel source tree.\n");
 }
 
 /*
@@ -90,7 +93,7 @@
 			exit(1);
 		case  0:
 			memset(real_filename, 0, sizeof(real_filename));
-			strncat(real_filename, getenv("SRCTREE"), PATH_MAX);
+			strncat(real_filename, srctree, PATH_MAX);
 			strncat(real_filename, KERNELDOCPATH KERNELDOC,
 					PATH_MAX - strlen(real_filename));
 			execvp(real_filename, svec);
@@ -171,7 +174,7 @@
 	if (filename_exist(filename) == NULL) {
 		char real_filename[PATH_MAX + 1];
 		memset(real_filename, 0, sizeof(real_filename));
-		strncat(real_filename, getenv("SRCTREE"), PATH_MAX);
+		strncat(real_filename, srctree, PATH_MAX);
 		strncat(real_filename, filename,
 				PATH_MAX - strlen(real_filename));
 		sym = add_new_file(filename);
@@ -338,6 +341,10 @@
 int main(int argc, char *argv[])
 {
 	FILE * infile;
+
+	srctree = getenv("SRCTREE");
+	if (!srctree)
+		srctree = getcwd(NULL, 0);
 	if (argc != 3) {
 		usage();
 		exit(1);
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 59ad83c..cbb4258 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -9,7 +9,7 @@
 my $P = $0;
 $P =~ s@.*/@@g;
 
-my $V = '0.10';
+my $V = '0.11';
 
 use Getopt::Long qw(:config no_auto_abbrev);
 
@@ -18,12 +18,21 @@
 my $chk_signoff = 1;
 my $chk_patch = 1;
 my $tst_type = 0;
+my $emacs = 0;
+my $file = 0;
+my $check = 0;
+my $root;
 GetOptions(
-	'q|quiet'	=> \$quiet,
+	'q|quiet+'	=> \$quiet,
 	'tree!'		=> \$tree,
 	'signoff!'	=> \$chk_signoff,
 	'patch!'	=> \$chk_patch,
 	'test-type!'	=> \$tst_type,
+	'emacs!'	=> \$emacs,
+	'file!'		=> \$file,
+	'subjective!'	=> \$check,
+	'strict!'	=> \$check,
+	'root=s'	=> \$root,
 ) or exit;
 
 my $exit = 0;
@@ -33,19 +42,110 @@
 	print "version: $V\n";
 	print "options: -q           => quiet\n";
 	print "         --no-tree    => run without a kernel tree\n";
+	print "         --emacs      => emacs compile window format\n";
+	print "         --file       => check a source file\n";
+	print "         --strict     => enable more subjective tests\n";
+	print "         --root       => path to the kernel tree root\n";
 	exit(1);
 }
 
-if ($tree && !top_of_kernel_tree()) {
-	print "Must be run from the top-level dir. of a kernel tree\n";
-	exit(2);
+if ($tree) {
+	if (defined $root) {
+		if (!top_of_kernel_tree($root)) {
+			die "$P: $root: --root does not point at a valid tree\n";
+		}
+	} else {
+		if (top_of_kernel_tree('.')) {
+			$root = '.';
+		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
+						top_of_kernel_tree($1)) {
+			$root = $1;
+		}
+	}
+
+	if (!defined $root) {
+		print "Must be run from the top-level dir. of a kernel tree\n";
+		exit(2);
+	}
 }
 
+my $emitted_corrupt = 0;
+
+our $Ident       = qr{[A-Za-z_][A-Za-z\d_]*};
+our $Storage	= qr{extern|static|asmlinkage};
+our $Sparse	= qr{
+			__user|
+			__kernel|
+			__force|
+			__iomem|
+			__must_check|
+			__init_refok|
+			__kprobes|
+			fastcall
+		}x;
+our $Attribute	= qr{
+			const|
+			__read_mostly|
+			__kprobes|
+			__(?:mem|cpu|dev|)(?:initdata|init)
+		  }x;
+our $Inline	= qr{inline|__always_inline|noinline};
+our $NonptrType	= qr{
+			\b
+			(?:const\s+)?
+			(?:unsigned\s+)?
+			(?:
+				void|
+				char|
+				short|
+				int|
+				long|
+				unsigned|
+				float|
+				double|
+				bool|
+				long\s+int|
+				long\s+long|
+				long\s+long\s+int|
+				(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
+				struct\s+$Ident|
+				union\s+$Ident|
+				enum\s+$Ident|
+				${Ident}_t|
+				${Ident}_handler|
+				${Ident}_handler_fn
+			)
+			(?:\s+$Sparse)*
+			\b
+		  }x;
+
+our $Type	= qr{
+			\b$NonptrType\b
+			(?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
+			(?:\s+$Sparse|\s+$Attribute)*
+		  }x;
+our $Declare	= qr{(?:$Storage\s+)?$Type};
+our $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
+our $Lval	= qr{$Ident(?:$Member)*};
+
+our $Constant	= qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*};
+our $Assignment	= qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
+our $Operators	= qr{
+			<=|>=|==|!=|
+			=>|->|<<|>>|<|>|!|~|
+			&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/
+		  }x;
+
+our $Bare = '';
+
+$chk_signoff = 0 if ($file);
+
 my @dep_includes = ();
 my @dep_functions = ();
-my $removal = 'Documentation/feature-removal-schedule.txt';
-if ($tree && -f $removal) {
-	open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n";
+my $removal = "Documentation/feature-removal-schedule.txt";
+if ($tree && -f "$root/$removal") {
+	open(REMOVE, "<$root/$removal") ||
+				die "$P: $removal: open failed - $!\n";
 	while (<REMOVE>) {
 		if (/^Check:\s+(.*\S)/) {
 			for my $entry (split(/[, ]+/, $1)) {
@@ -61,28 +161,42 @@
 }
 
 my @rawlines = ();
-while (<>) {
-	chomp;
-	push(@rawlines, $_);
-	if (eof(ARGV)) {
-		if (!process($ARGV, @rawlines)) {
-			$exit = 1;
-		}
-		@rawlines = ();
+for my $filename (@ARGV) {
+	if ($file) {
+		open(FILE, "diff -u /dev/null $filename|") ||
+			die "$P: $filename: diff failed - $!\n";
+	} else {
+		open(FILE, "<$filename") ||
+			die "$P: $filename: open failed - $!\n";
 	}
+	while (<FILE>) {
+		chomp;
+		push(@rawlines, $_);
+	}
+	close(FILE);
+	if (!process($filename, @rawlines)) {
+		$exit = 1;
+	}
+	@rawlines = ();
 }
 
 exit($exit);
 
 sub top_of_kernel_tree {
-	if ((-f "COPYING") && (-f "CREDITS") && (-f "Kbuild") &&
-	    (-f "MAINTAINERS") && (-f "Makefile") && (-f "README") &&
-	    (-d "Documentation") && (-d "arch") && (-d "include") &&
-	    (-d "drivers") && (-d "fs") && (-d "init") && (-d "ipc") &&
-	    (-d "kernel") && (-d "lib") && (-d "scripts")) {
-		return 1;
+	my ($root) = @_;
+
+	my @tree_check = (
+		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
+		"README", "Documentation", "arch", "include", "drivers",
+		"fs", "init", "ipc", "kernel", "lib", "scripts",
+	);
+
+	foreach my $check (@tree_check) {
+		if (! -e $root . '/' . $check) {
+			return 0;
+		}
 	}
-	return 0;
+	return 1;
 }
 
 sub expand_tabs {
@@ -105,6 +219,20 @@
 
 	return $res;
 }
+sub copy_spacing {
+	my ($str) = @_;
+
+	my $res = '';
+	for my $c (split(//, $str)) {
+		if ($c eq "\t") {
+			$res .= $c;
+		} else {
+			$res .= ' ';
+		}
+	}
+
+	return $res;
+}
 
 sub line_stats {
 	my ($line) = @_;
@@ -260,47 +388,138 @@
 	return ($cmt ne '');
 }
 
-sub ctx_expr_before {
-	my ($line) = @_;
-
-	##print "CHECK<$line>\n";
-
-	my $pos = length($line) - 1;
-	my $count = 0;
-	my $c;
-
-	for (; $pos >= 0; $pos--) {
-		$c = substr($line, $pos, 1);
-		##print "CHECK: c<$c> count<$count>\n";
-		if ($c eq ')') {
-			$count++;
-		} elsif ($c eq '(') {
-			last if (--$count == 0);
-		}
-	}
-
-	##print "CHECK: result<" . substr($line, 0, $pos) . ">\n";
-
-	return substr($line, 0, $pos);
-}
-
 sub cat_vet {
 	my ($vet) = @_;
 	my ($res, $coded);
 
 	$res = '';
-	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]])/g) {
-		$coded = sprintf("^%c", unpack('C', $2) + 64);
-		$res .= $1 . $coded;
+	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
+		$res .= $1;
+		if ($2 ne '') {
+			$coded = sprintf("^%c", unpack('C', $2) + 64);
+			$res .= $coded;
+		}
 	}
 	$res =~ s/$/\$/;
 
 	return $res;
 }
 
+sub annotate_values {
+	my ($stream, $type) = @_;
+
+	my $res;
+	my $cur = $stream;
+
+	my $debug = 0;
+
+	print "$stream\n" if ($debug);
+
+	##my $type = 'N';
+	my $pos = 0;
+	my $preprocessor = 0;
+	my $paren = 0;
+	my @paren_type;
+
+	# Include any user defined types we may have found as we went.
+	my $type_match = "(?:$Type$Bare)";
+
+	while (length($cur)) {
+		print " <$type> " if ($debug);
+		if ($cur =~ /^(\s+)/o) {
+			print "WS($1)\n" if ($debug);
+			if ($1 =~ /\n/ && $preprocessor) {
+				$preprocessor = 0;
+				$type = 'N';
+			}
+
+		} elsif ($cur =~ /^($type_match)/) {
+			print "DECLARE($1)\n" if ($debug);
+			$type = 'T';
+
+		} elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) {
+			print "DEFINE($1)\n" if ($debug);
+			$preprocessor = 1;
+			$paren_type[$paren] = 'N';
+
+		} elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|endif))/o) {
+			print "PRE($1)\n" if ($debug);
+			$preprocessor = 1;
+			$type = 'N';
+
+		} elsif ($cur =~ /^(\\\n)/o) {
+			print "PRECONT($1)\n" if ($debug);
+
+		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
+			print "SIZEOF($1)\n" if ($debug);
+			if (defined $2) {
+				$paren_type[$paren] = 'V';
+			}
+			$type = 'N';
+
+		} elsif ($cur =~ /^(if|while|typeof)\b/o) {
+			print "COND($1)\n" if ($debug);
+			$paren_type[$paren] = 'N';
+			$type = 'N';
+
+		} elsif ($cur =~/^(return|case|else)/o) {
+			print "KEYWORD($1)\n" if ($debug);
+			$type = 'N';
+
+		} elsif ($cur =~ /^(\()/o) {
+			print "PAREN('$1')\n" if ($debug);
+			$paren++;
+			$type = 'N';
+
+		} elsif ($cur =~ /^(\))/o) {
+			$paren-- if ($paren > 0);
+			if (defined $paren_type[$paren]) {
+				$type = $paren_type[$paren];
+				undef $paren_type[$paren];
+				print "PAREN('$1') -> $type\n" if ($debug);
+			} else {
+				print "PAREN('$1')\n" if ($debug);
+			}
+
+		} elsif ($cur =~ /^($Ident)\(/o) {
+			print "FUNC($1)\n" if ($debug);
+			$paren_type[$paren] = 'V';
+
+		} elsif ($cur =~ /^($Ident|$Constant)/o) {
+			print "IDENT($1)\n" if ($debug);
+			$type = 'V';
+
+		} elsif ($cur =~ /^($Assignment)/o) {
+			print "ASSIGN($1)\n" if ($debug);
+			$type = 'N';
+
+		} elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) {
+			print "END($1)\n" if ($debug);
+			$type = 'N';
+
+		} elsif ($cur =~ /^($Operators)/o) {
+			print "OP($1)\n" if ($debug);
+			if ($1 ne '++' && $1 ne '--') {
+				$type = 'N';
+			}
+
+		} elsif ($cur =~ /(^.)/o) {
+			print "C($1)\n" if ($debug);
+		}
+		if (defined $1) {
+			$cur = substr($cur, length($1));
+			$res .= $type x length($1);
+		}
+	}
+
+	return $res;
+}
+
+my $prefix = '';
+
 my @report = ();
 sub report {
-	push(@report, $_[0]);
+	push(@report, $prefix . $_[0]);
 }
 sub report_dump {
 	@report;
@@ -308,14 +527,19 @@
 sub ERROR {
 	report("ERROR: $_[0]\n");
 	our $clean = 0;
+	our $cnt_error++;
 }
 sub WARN {
 	report("WARNING: $_[0]\n");
 	our $clean = 0;
+	our $cnt_warn++;
 }
 sub CHK {
-	report("CHECK: $_[0]\n");
-	our $clean = 0;
+	if ($check) {
+		report("CHECK: $_[0]\n");
+		our $clean = 0;
+		our $cnt_chk++;
+	}
 }
 
 sub process {
@@ -335,6 +559,11 @@
 	my $signoff = 0;
 	my $is_patch = 0;
 
+	our $cnt_lines = 0;
+	our $cnt_error = 0;
+	our $cnt_warn = 0;
+	our $cnt_chk = 0;
+
 	# Trace the real file/line as we go.
 	my $realfile = '';
 	my $realline = 0;
@@ -343,62 +572,10 @@
 	my $in_comment = 0;
 	my $first_line = 0;
 
-	my $Ident	= qr{[A-Za-z\d_]+};
-	my $Storage	= qr{extern|static|asmlinkage};
-	my $Sparse	= qr{
-				__user|
-				__kernel|
-				__force|
-				__iomem|
-				__must_check|
-				__init_refok|
-				fastcall
-			}x;
-	my $Inline	= qr{inline|__always_inline|noinline};
-	my $NonptrType	= qr{
-				\b
-				(?:const\s+)?
-				(?:unsigned\s+)?
-				(?:
-					void|
-					char|
-					short|
-					int|
-					long|
-					unsigned|
-					float|
-					double|
-					bool|
-					long\s+int|
-					long\s+long|
-					long\s+long\s+int|
-					u8|u16|u32|u64|
-					s8|s16|s32|s64|
-					struct\s+$Ident|
-					union\s+$Ident|
-					enum\s+$Ident|
-					${Ident}_t
-				)
-				(?:\s+$Sparse)*
-				\b
-			  }x;
-	my $Type	= qr{
-				\b$NonptrType\b
-				(?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
-				(?:\s+$Sparse)*
-			  }x;
-	my $Declare	= qr{(?:$Storage\s+)?$Type};
-	my $Attribute	= qr{
-				const|
-				__read_mostly|
-				__(?:mem|cpu|dev|)(?:initdata|init)
-			  }x;
-	my $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
-	my $Lval	= qr{$Ident(?:$Member)*};
+	my $prev_values = 'N';
 
 	# Possible bare types.
 	my @bare = ();
-	my $Bare = $NonptrType;
 
 	# Pre-scan the patch looking for any __setup documentation.
 	my @setup_docs = ();
@@ -417,11 +594,14 @@
 		}
 	}
 
+	$prefix = '';
+
 	foreach my $line (@lines) {
 		$linenr++;
 
 		my $rawline = $line;
 
+
 #extract the filename as it passes
 		if ($line=~/^\+\+\+\s+(\S+)/) {
 			$realfile=$1;
@@ -430,7 +610,7 @@
 			next;
 		}
 #extract the line range in the file after the patch is applied
-		if ($line=~/^\@\@ -\d+,\d+ \+(\d+)(,(\d+))? \@\@/) {
+		if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
 			$is_patch = 1;
 			$first_line = $linenr + 1;
 			$in_comment = 0;
@@ -440,6 +620,7 @@
 			} else {
 				$realcnt=1+1;
 			}
+			$prev_values = 'N';
 			next;
 		}
 
@@ -473,18 +654,24 @@
 			# Track the previous line.
 			($prevline, $stashline) = ($stashline, $line);
 			($previndent, $stashindent) = ($stashindent, $indent);
+
 		} elsif ($realcnt == 1) {
 			$realcnt--;
 		}
 
 #make up the handle for any error we report on this line
-		$here = "#$linenr: ";
+		$here = "#$linenr: " if (!$file);
+		$here = "#$realline: " if ($file);
 		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
 
 		my $hereline = "$here\n$line\n";
 		my $herecurr = "$here\n$line\n";
 		my $hereprev = "$here\n$prevline\n$line\n";
 
+		$prefix = "$filename:$realline: " if ($emacs && $file);
+		$prefix = "$filename:$linenr: " if ($emacs && !$file);
+		$cnt_lines++ if ($realcnt != 0);
+
 #check the patch for a signoff:
 		if ($line =~ /^\s*signed-off-by:/i) {
 			# This is a signoff, if ugly, so do not double report.
@@ -502,7 +689,7 @@
 # Check for wrappage within a valid hunk of the file
 		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) {
 			ERROR("patch seems to be corrupt (line wrapped?)\n" .
-				$herecurr);
+				$herecurr) if (!$emitted_corrupt++);
 		}
 
 # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
@@ -568,8 +755,12 @@
 		    $line !~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?$Type\b/ &&
 		    $line !~ /$Ident:\s*$/ &&
 		    $line !~ /^.\s*$Ident\s*\(/ &&
+		     # definitions in global scope can only start with types
 		    ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?($Ident)\b/ ||
-		     $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/)) {
+		     # declarations always start with types
+		     $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/) ||
+		     # any (foo ... *) is a pointer cast, and foo is a type
+		     $line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/) {
 			my $possible = $1;
 			if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ &&
 			    $possible ne 'goto' && $possible ne 'return' &&
@@ -579,7 +770,7 @@
 				#print "POSSIBLE<$possible>\n";
 				push(@bare, $possible);
 				my $bare = join("|", @bare);
-				$Bare	= qr{
+				$Bare	= '|' . qr{
 						\b(?:$bare)\b
 						(?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
 						(?:\s+$Sparse)*
@@ -641,6 +832,14 @@
 			}
 		}
 
+		# Track the 'values' across context and added lines.
+		my $opline = $line; $opline =~ s/^./ /;
+		my $curr_values = annotate_values($opline . "\n", $prev_values);
+		$curr_values = $prev_values . $curr_values;
+		#warn "--> $opline\n";
+		#warn "--> $curr_values ($prev_values)\n";
+		$prev_values = substr($curr_values, -1);
+
 #ignore lines not being added
 		if ($line=~/^[^\+]/) {next;}
 
@@ -678,6 +877,7 @@
 		}
 		# Remove C99 comments.
 		$line =~ s@//.*@@;
+		$opline =~ s@//.*@@;
 
 #EXPORT_SYMBOL should immediately follow its function closing }.
 		if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) ||
@@ -766,18 +966,13 @@
 		}
 
 # check for spaces between functions and their parentheses.
-		if ($line =~ /($Ident)\s+\(/ &&
-		    $1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright)$/ &&
-		    $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) {
-			WARN("no space between function name and open parenthesis '('\n" . $herecurr);
+		while ($line =~ /($Ident)\s+\(/g) {
+			if ($1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case)$/ &&
+		            $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) {
+				WARN("no space between function name and open parenthesis '('\n" . $herecurr);
+			}
 		}
 # Check operator spacing.
-		# Note we expand the line with the leading + as the real
-		# line will be displayed with the leading + and the tabs
-		# will therefore also expand that way.
-		my $opline = $line;
-		$opline = expand_tabs($opline);
-		$opline =~ s/^./ /;
 		if (!($line=~/\#\s*include/)) {
 			my $ops = qr{
 				<<=|>>=|<=|>=|==|!=|
@@ -787,6 +982,9 @@
 			}x;
 			my @elements = split(/($ops|;)/, $opline);
 			my $off = 0;
+
+			my $blank = copy_spacing($opline);
+
 			for (my $n = 0; $n < $#elements; $n += 2) {
 				$off += length($elements[$n]);
 
@@ -822,62 +1020,24 @@
 
 				my $at = "(ctx:$ctx)";
 
-				my $ptr = (" " x $off) . "^";
+				my $ptr = substr($blank, 0, $off) . "^";
 				my $hereptr = "$hereline$ptr\n";
 
 				# Classify operators into binary, unary, or
 				# definitions (* only) where they have more
 				# than one mode.
-				my $unary_ctx = $prevline . $ca;
-				$unary_ctx =~ s/^./ /;
-				my $is_unary = 0;
-				my $Unary = qr{
-					(?:
-						^|;|,|$ops|\(|\?|:|
-						\(\s*$Type\s*\)|
-						$Type|
-						return|case|else|
-						\{|\}|
-						\[|
-						^.\#\s*define\s+$Ident\s*(?:\([^\)]*\))?|
-						^.\#\s*else|
-						^.\#\s*endif|
-						^.\#\s*(?:if|ifndef|ifdef)\b.*
-					)\s*(?:|\\)\s*$
-				}x;
-				my $UnaryFalse = qr{
-					sizeof\s*\(\s*$Type\s*\)\s*$
-				}x;
-				my $UnaryDefine = qr{
-					 (?:$Type|$Bare)\s*|
-					 (?:$Type|$Bare).*,\s*\**
-				}x;
-				if ($op eq '-' || $op eq '&' || $op eq '*') {
-					# An operator is binary if the left hand
-					# side is a value.  Pick out the known
-					# non-values.
-					if ($unary_ctx =~ /$Unary$/s &&
-					    $unary_ctx !~ /$UnaryFalse$/s) {
-						$is_unary = 1;
-
-					# Special handling for ')' check if this
-					# brace represents a conditional, if so
-					# we are unary.
-					} elsif ($unary_ctx =~ /\)\s*$/) {
-						my $before = ctx_expr_before($unary_ctx);
-						if ($before =~ /(?:for|if|while)\s*$/) {
-							$is_unary = 1;
-						}
-					}
-
-					# Check for type definition for of '*'.
-					if ($op eq '*' && $unary_ctx =~ /$UnaryDefine$/) {
-						$is_unary = 2;
-					}
+				my $op_type = substr($curr_values, $off + 1, 1);
+				my $op_left = substr($curr_values, $off, 1);
+				my $is_unary;
+				if ($op_type eq 'T') {
+					$is_unary = 2;
+				} elsif ($op_left eq 'V') {
+					$is_unary = 0;
+				} else {
+					$is_unary = 1;
 				}
-
 				#if ($op eq '-' || $op eq '&' || $op eq '*') {
-				#	print "UNARY: <$is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n";
+				#	print "UNARY: <$op_left$op_type $is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n";
 				#}
 
 				# ; should have either the end of line or a space or \ after it
@@ -952,7 +1112,7 @@
 
 # check for multiple assignments
 		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
-			WARN("multiple assignments should be avoided\n" . $herecurr);
+			CHK("multiple assignments should be avoided\n" . $herecurr);
 		}
 
 ## # check for multiple declarations, allowing for a function declaration
@@ -1012,7 +1172,7 @@
 		}
 
 # Check for illegal assignment in if conditional.
-		if ($line=~/\bif\s*\(.*[^<>!=]=[^=].*\)/) {
+		if ($line=~/\bif\s*\(.*[^<>!=]=[^=]/) {
 			#next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/);
 			ERROR("do not use assignment in if condition\n" . $herecurr);
 		}
@@ -1038,8 +1198,8 @@
 
 #warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
 		if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) {
-			my $checkfile = "include/linux/$1.h";
-			if (-f $checkfile) {
+			my $checkfile = "$root/include/linux/$1.h";
+			if (-f $checkfile && $1 ne 'irq.h') {
 				CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" .
 					$herecurr);
 			}
@@ -1151,7 +1311,8 @@
 		}
 
 # no volatiles please
-		if ($line =~ /\bvolatile\b/ && $line !~ /\basm\s+volatile\b/) {
+		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
+		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
 			WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
 		}
 
@@ -1240,6 +1401,11 @@
 
 	if ($clean == 0 && ($chk_patch || $is_patch)) {
 		print report_dump();
+		if ($quiet < 2) {
+			print "total: $cnt_error errors, $cnt_warn warnings, " .
+				(($check)? "$cnt_chk checks, " : "") .
+				"$cnt_lines lines checked\n";
+		}
 	}
 	if ($clean == 1 && $quiet == 0) {
 		print "Your patch has no obvious style problems and is ready for submission.\n"
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index b458e2a..d716b76 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -13,9 +13,10 @@
 #	Random bits by Matt Mackall <mpm@selenic.com>
 #	M68k port by Geert Uytterhoeven and Andreas Schwab
 #	AVR32 port by Haavard Skinnemoen <hskinnemoen@atmel.com>
+#	PARISC port by Kyle McMartin <kyle@parisc-linux.org>
 #
 #	Usage:
-#	objdump -d vmlinux | stackcheck.pl [arch]
+#	objdump -d vmlinux | scripts/checkstack.pl [arch]
 #
 #	TODO :	Port to all architectures (one regex per arch)
 
@@ -61,6 +62,8 @@
 	} elsif ($arch eq 'mips') {
 		#88003254:       27bdffe0        addiu   sp,sp,-32
 		$re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
+	} elsif ($arch eq 'parisc' || $arch eq 'parisc64') {
+		$re = qr/.*ldo ($x{1,8})\(sp\),sp/o;
 	} elsif ($arch eq 'ppc') {
 		#c00029f4:       94 21 ff 30     stwu    r1,-208(r1)
 		$re = qr/.*stwu.*r1,-($x{1,8})\(r1\)/o;
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index bb08069..83c5e76 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -84,7 +84,7 @@
 # lxdialog stuff
 check-lxdialog  := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
 
-# Use reursively expanded variables so we do not call gcc unless
+# Use recursively expanded variables so we do not call gcc unless
 # we really need to do so. (Do not call gcc as part of make mrproper)
 HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
 HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 7bfa181..f9d0d91 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -235,23 +235,16 @@
 	sym = parent->sym;
 	if (parent->list) {
 		if (sym && sym_is_choice(sym)) {
-			/* find out choice type */
-			enum symbol_type type = S_UNKNOWN;
-
+			/* find the first choice value and find out choice type */
 			for (menu = parent->list; menu; menu = menu->next) {
-				if (menu->sym && menu->sym->type != S_UNKNOWN) {
-					if (type == S_UNKNOWN)
-						type = menu->sym->type;
-					if (type != S_BOOLEAN)
-						break;
-					if (menu->sym->type == S_TRISTATE) {
-						type = S_TRISTATE;
-						break;
-					}
+				if (menu->sym) {
+					current_entry = parent;
+					menu_set_type(menu->sym->type);
+					current_entry = menu;
+					menu_set_type(sym->type);
+					break;
 				}
 			}
-			current_entry = parent;
-			menu_set_type(type);
 			parentdep = expr_alloc_symbol(sym);
 		} else if (parent->prompt)
 			parentdep = parent->prompt->visible.expr;
@@ -260,16 +253,7 @@
 
 		for (menu = parent->list; menu; menu = menu->next) {
 			basedep = expr_transform(menu->dep);
-			dep = parentdep;
-			if (sym && sym_is_choice(sym) && menu->sym) {
-				enum symbol_type type = menu->sym->type;
-
-				if (type == S_UNKNOWN)
-					type = sym->type;
-			     if (type != S_TRISTATE)
-					dep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes);
-			}
-			basedep = expr_alloc_and(expr_copy(dep), basedep);
+			basedep = expr_alloc_and(expr_copy(parentdep), basedep);
 			basedep = expr_eliminate_dups(basedep);
 			menu->dep = basedep;
 			if (menu->sym)
@@ -342,8 +326,7 @@
 					    "values not supported");
 			}
 			current_entry = menu;
-			if (menu->sym->type == S_UNKNOWN)
-				menu_set_type(sym->type);
+			menu_set_type(sym->type);
 			menu_add_symbol(P_CHOICE, sym, NULL);
 			prop = sym_get_choice_prop(sym);
 			for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index e4eeb59..b9bb32d 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -1274,8 +1274,12 @@
 	QMenuBar* menu;
 	bool ok;
 	int x, y, width, height;
+	char title[256];
 
 	QWidget *d = configApp->desktop();
+	snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration"),
+		getenv("KERNELVERSION"));
+	setCaption(title);
 
 	width = configSettings->readNumEntry("/window width", d->width() - 64);
 	height = configSettings->readNumEntry("/window height", d->height() - 64);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 91c15da..d802b5a 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -525,6 +525,20 @@
 	return 1;
 }
 
+/* Looks like: virtio:dNvN */
+static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
+			   char *alias)
+{
+	id->device = TO_NATIVE(id->device);
+	id->vendor = TO_NATIVE(id->vendor);
+
+	strcpy(alias, "virtio:");
+	ADD(alias, "d", 1, id->device);
+	ADD(alias, "v", id->vendor != VIRTIO_DEV_ANY_ID, id->vendor);
+
+	return 1;
+}
+
 /* Ignore any prefix, eg. v850 prepends _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -651,6 +665,10 @@
 		do_table(symval, sym->st_size,
 			 sizeof(struct ssb_device_id), "ssb",
 			 do_ssb_entry, mod);
+	else if (sym_is(symname, "__mod_virtio_device_table"))
+		do_table(symval, sym->st_size,
+			 sizeof(struct virtio_device_id), "virtio",
+			 do_virtio_entry, mod);
 	free(zeros);
 }
 
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 2ef9a19..93ac52a 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -268,6 +268,9 @@
 			     "was in %s%s\n", mod->name, name,
 			     s->module->name,
 			     is_vmlinux(s->module->name) ?"":".ko");
+		} else {
+			/* In case Modules.symvers was out of date */
+			s->module = mod;
 		}
 	}
 	s->preloaded = 0;
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 6edb29f..0f657b5 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -83,6 +83,7 @@
 Standards-Version: 3.6.1
 
 Package: $packagename
+Provides: kernel-image-$version, linux-image-$version
 Architecture: any
 Description: User Mode Linux kernel, version $version
  User-mode Linux is a port of the Linux kernel to its own system call
@@ -104,6 +105,7 @@
 Standards-Version: 3.6.1
 
 Package: $packagename
+Provides: kernel-image-$version, linux-image-$version
 Architecture: any
 Description: Linux kernel, version $version
  This package contains the Linux kernel, modules and corresponding other
diff --git a/security/commoncap.c b/security/commoncap.c
index 778cb0c..bf67871 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -23,6 +23,26 @@
 #include <linux/xattr.h>
 #include <linux/hugetlb.h>
 #include <linux/mount.h>
+#include <linux/sched.h>
+
+#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
+/*
+ * Because of the reduced scope of CAP_SETPCAP when filesystem
+ * capabilities are in effect, it is safe to allow this capability to
+ * be available in the default configuration.
+ */
+# define CAP_INIT_BSET  CAP_FULL_SET
+#else /* ie. ndef CONFIG_SECURITY_FILE_CAPABILITIES */
+# define CAP_INIT_BSET  CAP_INIT_EFF_SET
+#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
+
+kernel_cap_t cap_bset = CAP_INIT_BSET;    /* systemwide capability bound */
+EXPORT_SYMBOL(cap_bset);
+
+/* Global security state */
+
+unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
+EXPORT_SYMBOL(securebits);
 
 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
 {
@@ -73,14 +93,44 @@
 	return 0;
 }
 
+#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
+
+static inline int cap_block_setpcap(struct task_struct *target)
+{
+	/*
+	 * No support for remote process capability manipulation with
+	 * filesystem capability support.
+	 */
+	return (target != current);
+}
+
+static inline int cap_inh_is_capped(void)
+{
+	/*
+	 * return 1 if changes to the inheritable set are limited
+	 * to the old permitted set.
+	 */
+	return !cap_capable(current, CAP_SETPCAP);
+}
+
+#else /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */
+
+static inline int cap_block_setpcap(struct task_struct *t) { return 0; }
+static inline int cap_inh_is_capped(void) { return 1; }
+
+#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
+
 int cap_capset_check (struct task_struct *target, kernel_cap_t *effective,
 		      kernel_cap_t *inheritable, kernel_cap_t *permitted)
 {
-	/* Derived from kernel/capability.c:sys_capset. */
-	/* verify restrictions on target's new Inheritable set */
-	if (!cap_issubset (*inheritable,
-			   cap_combine (target->cap_inheritable,
-					current->cap_permitted))) {
+	if (cap_block_setpcap(target)) {
+		return -EPERM;
+	}
+	if (cap_inh_is_capped()
+	    && !cap_issubset(*inheritable,
+			     cap_combine(target->cap_inheritable,
+					 current->cap_permitted))) {
+		/* incapable of using this inheritable set */
 		return -EPERM;
 	}
 
@@ -140,7 +190,8 @@
 	return inode->i_op->removexattr(dentry, XATTR_NAME_CAPS);
 }
 
-static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm,
+static inline int cap_from_disk(struct vfs_cap_data *caps,
+				struct linux_binprm *bprm,
 				int size)
 {
 	__u32 magic_etc;
@@ -148,7 +199,7 @@
 	if (size != XATTR_CAPS_SZ)
 		return -EINVAL;
 
-	magic_etc = le32_to_cpu(caps[0]);
+	magic_etc = le32_to_cpu(caps->magic_etc);
 
 	switch ((magic_etc & VFS_CAP_REVISION_MASK)) {
 	case VFS_CAP_REVISION:
@@ -156,8 +207,8 @@
 			bprm->cap_effective = true;
 		else
 			bprm->cap_effective = false;
-		bprm->cap_permitted = to_cap_t( le32_to_cpu(caps[1]) );
-		bprm->cap_inheritable = to_cap_t( le32_to_cpu(caps[2]) );
+		bprm->cap_permitted = to_cap_t(le32_to_cpu(caps->permitted));
+		bprm->cap_inheritable = to_cap_t(le32_to_cpu(caps->inheritable));
 		return 0;
 	default:
 		return -EINVAL;
@@ -169,7 +220,7 @@
 {
 	struct dentry *dentry;
 	int rc = 0;
-	__le32 v1caps[XATTR_CAPS_SZ];
+	struct vfs_cap_data incaps;
 	struct inode *inode;
 
 	if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) {
@@ -182,8 +233,14 @@
 	if (!inode->i_op || !inode->i_op->getxattr)
 		goto out;
 
-	rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, &v1caps,
-							XATTR_CAPS_SZ);
+	rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, NULL, 0);
+	if (rc > 0) {
+		if (rc == XATTR_CAPS_SZ)
+			rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS,
+						&incaps, XATTR_CAPS_SZ);
+		else
+			rc = -EINVAL;
+	}
 	if (rc == -ENODATA || rc == -EOPNOTSUPP) {
 		/* no data, that's ok */
 		rc = 0;
@@ -192,7 +249,7 @@
 	if (rc < 0)
 		goto out;
 
-	rc = cap_from_disk(v1caps, bprm, rc);
+	rc = cap_from_disk(&incaps, bprm, rc);
 	if (rc)
 		printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n",
 			__FUNCTION__, rc, bprm->filename);
@@ -285,7 +342,7 @@
 	/* For init, we want to retain the capabilities set
 	 * in the init_task struct. Thus we skip the usual
 	 * capability rules */
-	if (!is_init(current)) {
+	if (!is_global_init(current)) {
 		current->cap_permitted = new_permitted;
 		current->cap_effective = bprm->cap_effective ?
 				new_permitted : 0;
diff --git a/security/dummy.c b/security/dummy.c
index bc43d4c..6d895ad 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -37,15 +37,13 @@
 			 kernel_cap_t * inheritable, kernel_cap_t * permitted)
 {
 	*effective = *inheritable = *permitted = 0;
-	if (!issecure(SECURE_NOROOT)) {
-		if (target->euid == 0) {
-			*permitted |= (~0 & ~CAP_FS_MASK);
-			*effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK);
-		}
-		if (target->fsuid == 0) {
-			*permitted |= CAP_FS_MASK;
-			*effective |= CAP_FS_MASK;
-		}
+	if (target->euid == 0) {
+		*permitted |= (~0 & ~CAP_FS_MASK);
+		*effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK);
+	}
+	if (target->fsuid == 0) {
+		*permitted |= CAP_FS_MASK;
+		*effective |= CAP_FS_MASK;
 	}
 	return 0;
 }
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 24e1b18..9f3124b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2977,11 +2977,7 @@
 
 static int selinux_task_wait(struct task_struct *p)
 {
-	u32 perm;
-
-	perm = signal_to_av(p->exit_signal);
-
-	return task_has_perm(p, current, perm);
+	return task_has_perm(p, current, PROCESS__SIGCHLD);
 }
 
 static void selinux_task_reparent_to_init(struct task_struct *p)
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index cb008d9..36a191e 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -448,7 +448,7 @@
 	if (dst) {
 		struct dst_entry *dst_test;
 
-		for (dst_test = dst; dst_test != 0;
+		for (dst_test = dst; dst_test != NULL;
 		     dst_test = dst_test->child) {
 			struct xfrm_state *x = dst_test->xfrm;
 
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index b9eca9f..3b73ba7 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -209,7 +209,7 @@
 		void *ptr;
 
 		if (!aacirun->substream || !aacirun->start) {
-			dev_warn(&aaci->dev->dev, "RX interrupt???");
+			dev_warn(&aaci->dev->dev, "RX interrupt???\n");
 			writel(0, aacirun->base + AACI_IE);
 			return;
 		}
@@ -263,7 +263,7 @@
 		void *ptr;
 
 		if (!aacirun->substream || !aacirun->start) {
-			dev_warn(&aaci->dev->dev, "TX interrupt???");
+			dev_warn(&aaci->dev->dev, "TX interrupt???\n");
 			writel(0, aacirun->base + AACI_IE);
 			return;
 		}
diff --git a/sound/core/control.c b/sound/core/control.c
index 4c3aa8e..df0774c 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -93,15 +93,16 @@
 
 static void snd_ctl_empty_read_queue(struct snd_ctl_file * ctl)
 {
+	unsigned long flags;
 	struct snd_kctl_event *cread;
 	
-	spin_lock(&ctl->read_lock);
+	spin_lock_irqsave(&ctl->read_lock, flags);
 	while (!list_empty(&ctl->events)) {
 		cread = snd_kctl_event(ctl->events.next);
 		list_del(&cread->list);
 		kfree(cread);
 	}
-	spin_unlock(&ctl->read_lock);
+	spin_unlock_irqrestore(&ctl->read_lock, flags);
 }
 
 static int snd_ctl_release(struct inode *inode, struct file *file)
diff --git a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c
index d7c4fb8..17b3e6f 100644
--- a/sound/core/seq/seq_midi_emul.c
+++ b/sound/core/seq/seq_midi_emul.c
@@ -71,7 +71,7 @@
  * such as GM, GS and XG.
  * There modes that this module will run in are:
  *   Generic MIDI - no interpretation at all, it will just save current values
- *                  of controlers etc.
+ *                  of controllers etc.
  *   GM - You can use all gm_ prefixed elements of chan.  Controls, RPN, NRPN,
  *        SysEx will be interpreded as defined in General Midi.
  *   GS - You can use all gs_ prefixed elements of chan. Codes for GS will be
@@ -176,7 +176,7 @@
 				   ev->data.control.value);
 		break;
 	case SNDRV_SEQ_EVENT_NONREGPARAM:
-		/* Break it back into its controler values */
+		/* Break it back into its controller values */
 		chan->param_type = SNDRV_MIDI_PARAM_TYPE_NONREGISTERED;
 		chan->control[MIDI_CTL_MSB_DATA_ENTRY]
 			= (ev->data.control.value >> 7) & 0x7f;
@@ -189,7 +189,7 @@
 		nrpn(ops, drv, chan, chanset);
 		break;
 	case SNDRV_SEQ_EVENT_REGPARAM:
-		/* Break it back into its controler values */
+		/* Break it back into its controller values */
 		chan->param_type = SNDRV_MIDI_PARAM_TYPE_REGISTERED;
 		chan->control[MIDI_CTL_MSB_DATA_ENTRY]
 			= (ev->data.control.value >> 7) & 0x7f;
@@ -267,7 +267,7 @@
 }
 
 /*
- * Do all driver independent operations for this controler and pass
+ * Do all driver independent operations for this controller and pass
  * events that need to take place immediately to the driver.
  */
 static void
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index 1b6f227..3557b6e 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -808,7 +808,7 @@
 }
 
 /*
- * Deal with a controler type event.  This includes all types of
+ * Deal with a controller type event.  This includes all types of
  * control events, not just the midi controllers
  */
 void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan)
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index fe31bb5..37c47fb 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -189,7 +189,6 @@
 	tea->vd.owner = tea->card->module;
 	strcpy(tea->vd.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 radio");
 	tea->vd.type = VID_TYPE_TUNER;
-	tea->vd.hardware = VID_HARDWARE_RTRACK;	/* FIXME: assign new number */
 	tea->vd.release = snd_tea575x_release;
 	video_set_drvdata(&tea->vd, tea);
 	tea->vd.fops = &tea->fops;
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 4a7367a..c1af28f 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -623,7 +623,7 @@
                          (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) |
                          (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20));
 
-        /* Set DMA controler */
+        /* Set DMA controller */
         snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
 
 	return 0;
@@ -689,7 +689,7 @@
                          (snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) |
                          (snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20));
 
-        /* Set DMA controler */
+        /* Set DMA controller */
         snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
 
 	return 0;
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index 8a61a11..24460a5 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -498,8 +498,8 @@
 	int             i;
 
 	spin_lock(&au1000->ac97_lock);
-/* would rather use the interupt than this polling but it works and I can't
-get the interupt driven case to work efficiently */
+/* would rather use the interrupt than this polling but it works and I can't
+get the interrupt driven case to work efficiently */
 	for (i = 0; i < 0x5000; i++)
 		if (!(au1000->ac97_ioport->status & AC97C_CP))
 			break;
@@ -535,8 +535,8 @@
 	int i;
 
 	spin_lock(&au1000->ac97_lock);
-/* would rather use the interupt than this polling but it works and I can't
-get the interupt driven case to work efficiently */
+/* would rather use the interrupt than this polling but it works and I can't
+get the interrupt driven case to work efficiently */
 	for (i = 0; i < 0x5000; i++)
 		if (!(au1000->ac97_ioport->status & AC97C_CP))
 			break;
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index 1200670..f883c4b 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -36,7 +36,6 @@
 obj-$(CONFIG_SOUND_MSNDPIN)	+= msnd.o msnd_pinnacle.o
 obj-$(CONFIG_SOUND_VWSND)	+= vwsnd.o
 obj-$(CONFIG_SOUND_ICH)		+= i810_audio.o ac97_codec.o
-obj-$(CONFIG_SOUND_ES1371)	+= es1371.o ac97_codec.o
 obj-$(CONFIG_SOUND_AU1550_AC97)	+= au1550_ac97.o ac97_codec.o
 obj-$(CONFIG_SOUND_TRIDENT)	+= trident.o ac97_codec.o
 obj-$(CONFIG_SOUND_BCM_CS4297A)	+= swarm_cs4297a.o
diff --git a/sound/oss/dmasound/Makefile b/sound/oss/dmasound/Makefile
index 4611636..3c15316 100644
--- a/sound/oss/dmasound/Makefile
+++ b/sound/oss/dmasound/Makefile
@@ -2,12 +2,6 @@
 # Makefile for the DMA sound driver
 #
 
-dmasound_pmac-y			+= dmasound_awacs.o \
-				   trans_16.o dac3550a.o tas_common.o \
-				   tas3001c.o tas3001c_tables.o \
-				   tas3004.o tas3004_tables.o
-
 obj-$(CONFIG_DMASOUND_ATARI)	+= dmasound_core.o dmasound_atari.o
-obj-$(CONFIG_DMASOUND_PMAC)	+= dmasound_core.o dmasound_pmac.o
 obj-$(CONFIG_DMASOUND_PAULA)	+= dmasound_core.o dmasound_paula.o
 obj-$(CONFIG_DMASOUND_Q40)	+= dmasound_core.o dmasound_q40.o
diff --git a/sound/oss/dmasound/awacs_defs.h b/sound/oss/dmasound/awacs_defs.h
deleted file mode 100644
index 2194f46..0000000
--- a/sound/oss/dmasound/awacs_defs.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*********************************************************/
-/* This file was written by someone, somewhere, sometime */
-/* And is released into the Public Domain                */
-/*********************************************************/
-
-#ifndef _AWACS_DEFS_H_
-#define _AWACS_DEFS_H_
-
-/*******************************/
-/* AWACs Audio Register Layout */
-/*******************************/
-
-struct awacs_regs {
-    unsigned	control;	/* Audio control register */
-    unsigned	pad0[3];
-    unsigned	codec_ctrl;	/* Codec control register */
-    unsigned	pad1[3];
-    unsigned	codec_stat;	/* Codec status register */
-    unsigned	pad2[3];
-    unsigned	clip_count;	/* Clipping count register */
-    unsigned	pad3[3];
-    unsigned	byteswap;	/* Data is little-endian if 1 */
-};
-
-/*******************/
-/* Audio Bit Masks */
-/*******************/
-
-/* Audio Control Reg Bit Masks */
-/* ----- ------- --- --- ----- */
-#define MASK_ISFSEL	(0xf)		/* Input SubFrame Select */
-#define MASK_OSFSEL	(0xf << 4)	/* Output SubFrame Select */
-#define MASK_RATE	(0x7 << 8)	/* Sound Rate */
-#define MASK_CNTLERR	(0x1 << 11)	/* Error */
-#define MASK_PORTCHG	(0x1 << 12)	/* Port Change */
-#define MASK_IEE	(0x1 << 13)	/* Enable Interrupt on Error */
-#define MASK_IEPC	(0x1 << 14)	/* Enable Interrupt on Port Change */
-#define MASK_SSFSEL	(0x3 << 15)	/* Status SubFrame Select */
-
-/* Audio Codec Control Reg Bit Masks */
-/* ----- ----- ------- --- --- ----- */
-#define MASK_NEWECMD	(0x1 << 24)	/* Lock: don't write to reg when 1 */
-#define MASK_EMODESEL	(0x3 << 22)	/* Send info out on which frame? */
-#define MASK_EXMODEADDR	(0x3ff << 12)	/* Extended Mode Address -- 10 bits */
-#define MASK_EXMODEDATA	(0xfff)		/* Extended Mode Data -- 12 bits */
-
-/* Audio Codec Control Address Values / Masks */
-/* ----- ----- ------- ------- ------ - ----- */
-#define MASK_ADDR0	(0x0 << 12)	/* Expanded Data Mode Address 0 */
-#define MASK_ADDR_MUX	MASK_ADDR0	/* Mux Control */
-#define MASK_ADDR_GAIN	MASK_ADDR0
-
-#define MASK_ADDR1	(0x1 << 12)	/* Expanded Data Mode Address 1 */
-#define MASK_ADDR_MUTE	MASK_ADDR1
-#define MASK_ADDR_RATE	MASK_ADDR1
-
-#define MASK_ADDR2	(0x2 << 12)	/* Expanded Data Mode Address 2 */
-#define MASK_ADDR_VOLA	MASK_ADDR2	/* Volume Control A -- Headphones */
-#define MASK_ADDR_VOLHD MASK_ADDR2
-
-#define MASK_ADDR4	(0x4 << 12)	/* Expanded Data Mode Address 4 */
-#define MASK_ADDR_VOLC	MASK_ADDR4	/* Volume Control C -- Speaker */
-#define MASK_ADDR_VOLSPK MASK_ADDR4
-
-/* additional registers of screamer */
-#define MASK_ADDR5	(0x5 << 12)	/* Expanded Data Mode Address 5 */
-#define MASK_ADDR6	(0x6 << 12)	/* Expanded Data Mode Address 6 */
-#define MASK_ADDR7	(0x7 << 12)	/* Expanded Data Mode Address 7 */
-
-/* Address 0 Bit Masks & Macros */
-/* ------- - --- ----- - ------ */
-#define MASK_GAINRIGHT	(0xf)		/* Gain Right Mask */
-#define MASK_GAINLEFT	(0xf << 4)	/* Gain Left Mask */
-#define MASK_GAINLINE	(0x1 << 8)	/* Disable Mic preamp */
-#define MASK_GAINMIC	(0x0 << 8)	/* Enable Mic preamp */
-
-#define MASK_MUX_CD	(0x1 << 9)	/* Select CD in MUX */
-#define MASK_MUX_MIC	(0x1 << 10)	/* Select Mic in MUX */
-#define MASK_MUX_AUDIN	(0x1 << 11)	/* Select Audio In in MUX */
-#define MASK_MUX_LINE	MASK_MUX_AUDIN
-
-#define GAINRIGHT(x)	((x) & MASK_GAINRIGHT)
-#define GAINLEFT(x)	(((x) << 4) & MASK_GAINLEFT)
-
-#define DEF_CD_GAIN 0x00bb
-#define DEF_MIC_GAIN 0x00cc
-
-/* Address 1 Bit Masks */
-/* ------- - --- ----- */
-#define MASK_ADDR1RES1	(0x3)		/* Reserved */
-#define MASK_RECALIBRATE (0x1 << 2)	/* Recalibrate */
-#define MASK_SAMPLERATE	(0x7 << 3)	/* Sample Rate: */
-#define MASK_LOOPTHRU	(0x1 << 6)	/* Loopthrough Enable */
-#define MASK_CMUTE	(0x1 << 7)	/* Output C (Speaker) Mute when 1 */
-#define MASK_SPKMUTE	MASK_CMUTE
-#define MASK_ADDR1RES2	(0x1 << 8)	/* Reserved */
-#define MASK_AMUTE	(0x1 << 9)	/* Output A (Headphone) Mute when 1 */
-#define MASK_HDMUTE	MASK_AMUTE
-#define MASK_PAROUT0	(0x1 << 10)	/* Parallel Output 0 */
-#define MASK_PAROUT1	(0x2 << 10)	/* Parallel Output 1 */
-
-#define MASK_MIC_BOOST  (0x4)           /* screamer mic boost */
-
-#define SAMPLERATE_48000	(0x0 << 3)	/* 48 or 44.1 kHz */
-#define SAMPLERATE_32000	(0x1 << 3)	/* 32 or 29.4 kHz */
-#define SAMPLERATE_24000	(0x2 << 3)	/* 24 or 22.05 kHz */
-#define SAMPLERATE_19200	(0x3 << 3)	/* 19.2 or 17.64 kHz */
-#define SAMPLERATE_16000	(0x4 << 3)	/* 16 or 14.7 kHz */
-#define SAMPLERATE_12000	(0x5 << 3)	/* 12 or 11.025 kHz */
-#define SAMPLERATE_9600		(0x6 << 3)	/* 9.6 or 8.82 kHz */
-#define SAMPLERATE_8000		(0x7 << 3)	/* 8 or 7.35 kHz */
-
-/* Address 2 & 4 Bit Masks & Macros */
-/* ------- - - - --- ----- - ------ */
-#define MASK_OUTVOLRIGHT (0xf)		/* Output Right Volume */
-#define MASK_ADDR2RES1	(0x2 << 4)	/* Reserved */
-#define MASK_ADDR4RES1	MASK_ADDR2RES1
-#define MASK_OUTVOLLEFT	(0xf << 6)	/* Output Left Volume */
-#define MASK_ADDR2RES2	(0x2 << 10)	/* Reserved */
-#define MASK_ADDR4RES2	MASK_ADDR2RES2
-
-#define VOLRIGHT(x)	(((~(x)) & MASK_OUTVOLRIGHT))
-#define VOLLEFT(x)	(((~(x)) << 6) & MASK_OUTVOLLEFT)
-
-/* Audio Codec Status Reg Bit Masks */
-/* ----- ----- ------ --- --- ----- */
-#define MASK_EXTEND	(0x1 << 23)	/* Extend */
-#define MASK_VALID	(0x1 << 22)	/* Valid Data? */
-#define MASK_OFLEFT	(0x1 << 21)	/* Overflow Left */
-#define MASK_OFRIGHT	(0x1 << 20)	/* Overflow Right */
-#define MASK_ERRCODE	(0xf << 16)	/* Error Code */
-#define MASK_REVISION	(0xf << 12)	/* Revision Number */
-#define MASK_MFGID	(0xf << 8)	/* Mfg. ID */
-#define MASK_CODSTATRES	(0xf << 4)	/* bits 4 - 7 reserved */
-#define MASK_INPPORT	(0xf)		/* Input Port */
-#define MASK_HDPCONN	8		/* headphone plugged in */
-
-/* Clipping Count Reg Bit Masks */
-/* -------- ----- --- --- ----- */
-#define MASK_CLIPLEFT	(0xff << 7)	/* Clipping Count, Left Channel */
-#define MASK_CLIPRIGHT	(0xff)		/* Clipping Count, Right Channel */
-
-/* DBDMA ChannelStatus Bit Masks */
-/* ----- ------------- --- ----- */
-#define MASK_CSERR	(0x1 << 7)	/* Error */
-#define MASK_EOI	(0x1 << 6)	/* End of Input -- only for Input Channel */
-#define MASK_CSUNUSED	(0x1f << 1)	/* bits 1-5 not used */
-#define MASK_WAIT	(0x1)		/* Wait */
-
-/* Various Rates */
-/* ------- ----- */
-#define RATE_48000	(0x0 << 8)	/* 48 kHz */
-#define RATE_44100	(0x0 << 8)	/* 44.1 kHz */
-#define RATE_32000	(0x1 << 8)	/* 32 kHz */
-#define RATE_29400	(0x1 << 8)	/* 29.4 kHz */
-#define RATE_24000	(0x2 << 8)	/* 24 kHz */
-#define RATE_22050	(0x2 << 8)	/* 22.05 kHz */
-#define RATE_19200	(0x3 << 8)	/* 19.2 kHz */
-#define RATE_17640	(0x3 << 8)	/* 17.64 kHz */
-#define RATE_16000	(0x4 << 8)	/* 16 kHz */
-#define RATE_14700	(0x4 << 8)	/* 14.7 kHz */
-#define RATE_12000	(0x5 << 8)	/* 12 kHz */
-#define RATE_11025	(0x5 << 8)	/* 11.025 kHz */
-#define RATE_9600	(0x6 << 8)	/* 9.6 kHz */
-#define RATE_8820	(0x6 << 8)	/* 8.82 kHz */
-#define RATE_8000	(0x7 << 8)	/* 8 kHz */
-#define RATE_7350	(0x7 << 8)	/* 7.35 kHz */
-
-#define RATE_LOW	1	/* HIGH = 48kHz, etc;  LOW = 44.1kHz, etc. */
-
-/*******************/
-/* Burgundy values */
-/*******************/
-
-#define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12)
-#define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12)
-
-#define MASK_ADDR_BURGUNDY_GAINCH1 (0x13 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH2 (0x14 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH3 (0x15 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH4 (0x16 << 12)
-
-#define MASK_ADDR_BURGUNDY_VOLCH1 (0x20 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH2 (0x21 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH3 (0x22 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH4 (0x23 << 12)
-
-#define MASK_ADDR_BURGUNDY_OUTPUTSELECTS (0x2B << 12)
-#define MASK_ADDR_BURGUNDY_OUTPUTENABLES (0x2F << 12)
-
-#define MASK_ADDR_BURGUNDY_MASTER_VOLUME (0x30 << 12)
-
-#define MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES (0x60 << 12)
-
-#define MASK_ADDR_BURGUNDY_ATTENSPEAKER (0x62 << 12)
-#define MASK_ADDR_BURGUNDY_ATTENLINEOUT (0x63 << 12)
-#define MASK_ADDR_BURGUNDY_ATTENHP (0x64 << 12)
-
-#define MASK_ADDR_BURGUNDY_VOLCD (MASK_ADDR_BURGUNDY_VOLCH1)
-#define MASK_ADDR_BURGUNDY_VOLLINE (MASK_ADDR_BURGUNDY_VOLCH2)
-#define MASK_ADDR_BURGUNDY_VOLMIC (MASK_ADDR_BURGUNDY_VOLCH3)
-#define MASK_ADDR_BURGUNDY_VOLMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
-
-#define MASK_ADDR_BURGUNDY_GAINCD (MASK_ADDR_BURGUNDY_GAINCH1)
-#define MASK_ADDR_BURGUNDY_GAINLINE (MASK_ADDR_BURGUNDY_GAINCH2)
-#define MASK_ADDR_BURGUNDY_GAINMIC (MASK_ADDR_BURGUNDY_GAINCH3)
-#define MASK_ADDR_BURGUNDY_GAINMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
-
-
-/* These are all default values for the burgundy */
-#define DEF_BURGUNDY_INPSEL21 (0xAA)
-#define DEF_BURGUNDY_INPSEL3 (0x0A)
-
-#define DEF_BURGUNDY_GAINCD (0x33)
-#define DEF_BURGUNDY_GAINLINE (0x44)
-#define DEF_BURGUNDY_GAINMIC (0x44)
-#define DEF_BURGUNDY_GAINMODEM (0x06)
-
-/* Remember: lowest volume here is 0x9b */
-#define DEF_BURGUNDY_VOLCD (0xCCCCCCCC)
-#define DEF_BURGUNDY_VOLLINE (0x00000000)
-#define DEF_BURGUNDY_VOLMIC (0x00000000)
-#define DEF_BURGUNDY_VOLMODEM (0xCCCCCCCC)
-
-#define DEF_BURGUNDY_OUTPUTSELECTS (0x010f010f)
-#define DEF_BURGUNDY_OUTPUTENABLES (0x0A)
-
-#define DEF_BURGUNDY_MASTER_VOLUME (0xFFFFFFFF)
-
-#define DEF_BURGUNDY_MORE_OUTPUTENABLES (0x7E)
-
-#define DEF_BURGUNDY_ATTENSPEAKER (0x44)
-#define DEF_BURGUNDY_ATTENLINEOUT (0xCC)
-#define DEF_BURGUNDY_ATTENHP (0xCC)
-
-/*********************/
-/* i2s layout values */
-/*********************/
-
-#define I2S_REG_INT_CTL			0x00
-#define I2S_REG_SERIAL_FORMAT		0x10
-#define I2S_REG_CODEC_MSG_OUT		0x20
-#define I2S_REG_CODEC_MSG_IN		0x30
-#define I2S_REG_FRAME_COUNT		0x40
-#define I2S_REG_FRAME_MATCH		0x50
-#define I2S_REG_DATAWORD_SIZES		0x60
-#define I2S_REG_PEAKLEVEL_SEL		0x70
-#define I2S_REG_PEAKLEVEL_IN0		0x80
-#define I2S_REG_PEAKLEVEL_IN1		0x90
-
-#endif /* _AWACS_DEFS_H_ */
diff --git a/sound/oss/dmasound/dac3550a.c b/sound/oss/dmasound/dac3550a.c
deleted file mode 100644
index 0f0d03a..0000000
--- a/sound/oss/dmasound/dac3550a.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Driver for the i2c/i2s based DAC3550a sound chip used
- * on some Apple iBooks. Also known as "DACA".
- *
- *  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.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-
-#include "dmasound.h"
-
-/* FYI: This code was derived from the tas3001c.c Texas/Tumbler mixer
- * control code, as well as info derived from the AppleDACAAudio driver
- * from Darwin CVS (main thing I derived being register numbers and 
- * values, as well as when to make the calls). */
-
-#define I2C_DRIVERID_DACA (0xFDCB)
-
-#define DACA_VERSION	"0.1"
-#define DACA_DATE "20010930"
-
-static int cur_left_vol;
-static int cur_right_vol;
-static struct i2c_client *daca_client;
-
-static int daca_attach_adapter(struct i2c_adapter *adapter);
-static int daca_detect_client(struct i2c_adapter *adapter, int address);
-static int daca_detach_client(struct i2c_client *client);
-
-struct i2c_driver daca_driver = {  
-	.driver = {
-		.name		= "DAC3550A driver  V " DACA_VERSION,
-	},
-	.id			= I2C_DRIVERID_DACA,
-	.attach_adapter		= daca_attach_adapter,
-	.detach_client		= daca_detach_client,
-};
-
-#define VOL_MAX ((1<<20) - 1)
-
-void daca_get_volume(uint * left_vol, uint  *right_vol)
-{
-	*left_vol = cur_left_vol >> 5;
-	*right_vol = cur_right_vol >> 5;
-}
-
-int daca_set_volume(uint left_vol, uint right_vol)
-{
-	unsigned short voldata;
-  
-	if (!daca_client)
-		return -1;
-
-	/* Derived from experience, not from any specific values */
-	left_vol <<= 5;
-	right_vol <<= 5;
-
-	if (left_vol > VOL_MAX)
-		left_vol = VOL_MAX;
-	if (right_vol > VOL_MAX)
-		right_vol = VOL_MAX;
-
-	voldata = ((left_vol >> 14)  & 0x3f) << 8;
-	voldata |= (right_vol >> 14)  & 0x3f;
-  
-	if (i2c_smbus_write_word_data(daca_client, 2, voldata) < 0) {
-		printk("daca: failed to set volume \n");
-		return -1; 
-	}
-
-	cur_left_vol = left_vol;
-	cur_right_vol = right_vol;
-  
-	return 0;
-}
-
-int daca_leave_sleep(void)
-{
-	if (!daca_client)
-		return -1;
-  
-	/* Do a short sleep, just to make sure I2C bus is awake and paying
-	 * attention to us
-	 */
-	msleep(20);
-	/* Write the sample rate reg the value it needs */
-	i2c_smbus_write_byte_data(daca_client, 1, 8);
-	daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
-	/* Another short delay, just to make sure the other I2C bus writes
-	 * have taken...
-	 */
-	msleep(20);
-	/* Write the global config reg - invert right power amp,
-	 * DAC on, use 5-volt mode */
-	i2c_smbus_write_byte_data(daca_client, 3, 0x45);
-
-	return 0;
-}
-
-int daca_enter_sleep(void)
-{
-	if (!daca_client)
-		return -1;
-
-	i2c_smbus_write_byte_data(daca_client, 1, 8);
-	daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
-
-	/* Write the global config reg - invert right power amp,
-	 * DAC on, enter low-power mode, use 5-volt mode
-	 */
-	i2c_smbus_write_byte_data(daca_client, 3, 0x65);
-
-	return 0;
-}
-
-static int daca_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!strncmp(adapter->name, "mac-io", 6))
-		daca_detect_client(adapter, 0x4d);
-	return 0;
-}
-
-static int daca_init_client(struct i2c_client * new_client)
-{
-	/* 
-	 * Probe is not working with the current i2c-keywest
-	 * driver. We try to use addr 0x4d on each adapters
-	 * instead, by setting the format register.
-	 * 
-	 * FIXME: I'm sure that can be obtained from the
-	 * device-tree. --BenH.
-	 */
-  
-	/* Write the global config reg - invert right power amp,
-	 * DAC on, use 5-volt mode
-	 */
-	if (i2c_smbus_write_byte_data(new_client, 3, 0x45))
-		return -1;
-
-	i2c_smbus_write_byte_data(new_client, 1, 8);
-	daca_client = new_client;
-	daca_set_volume(15000, 15000);
-
-	return 0;
-}
-
-static int daca_detect_client(struct i2c_adapter *adapter, int address)
-{
-	const char *client_name = "DAC 3550A Digital Equalizer";
-	struct i2c_client *new_client;
-	int rc = -ENODEV;
-
-	new_client = kzalloc(sizeof(*new_client), GFP_KERNEL);
-	if (!new_client)
-		return -ENOMEM;
-
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &daca_driver;
-	new_client->flags = 0;
-	strcpy(new_client->name, client_name);
-
-	if (daca_init_client(new_client))
-		goto bail;
-
-	/* Tell the i2c layer a new client has arrived */
-	if (i2c_attach_client(new_client))
-		goto bail;
-
-	return 0;
- bail:
-	kfree(new_client);
-	return rc;
-}
-
-
-static int daca_detach_client(struct i2c_client *client)
-{
-	if (client == daca_client)
-		daca_client = NULL;
-
-  	i2c_detach_client(client);
-	kfree(client);
-	return 0;
-}
-
-void daca_cleanup(void)
-{
-	i2c_del_driver(&daca_driver);
-}
-
-int daca_init(void)
-{
-	printk("dac3550a driver version %s (%s)\n",DACA_VERSION,DACA_DATE);
-	return i2c_add_driver(&daca_driver);
-}
diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h
index 25dd5a3..d978b00 100644
--- a/sound/oss/dmasound/dmasound.h
+++ b/sound/oss/dmasound/dmasound.h
@@ -59,7 +59,6 @@
      */
 
 #undef HAS_8BIT_TABLES
-#undef HAS_RECORD
 
 #if defined(CONFIG_DMASOUND_ATARI) || defined(CONFIG_DMASOUND_ATARI_MODULE) ||\
     defined(CONFIG_DMASOUND_PAULA) || defined(CONFIG_DMASOUND_PAULA_MODULE) ||\
@@ -83,10 +82,6 @@
 #define DEFAULT_N_BUFFERS 4
 #define DEFAULT_BUFF_SIZE (1<<15)
 
-#if defined(CONFIG_DMASOUND_PMAC) || defined(CONFIG_DMASOUND_PMAC_MODULE)
-#define HAS_RECORD
-#endif
-
     /*
      *  Initialization
      */
@@ -168,9 +163,6 @@
     SETTINGS soft;	/* software settings */
     SETTINGS dsp;	/* /dev/dsp default settings */
     TRANS *trans_write;	/* supported translations */
-#ifdef HAS_RECORD
-    TRANS *trans_read;	/* supported translations */
-#endif
     int volume_left;	/* volume (range is machine dependent) */
     int volume_right;
     int bass;		/* tone (range is machine dependent) */
@@ -253,11 +245,6 @@
 extern struct sound_queue dmasound_write_sq;
 #define write_sq	dmasound_write_sq
 
-#ifdef HAS_RECORD
-extern struct sound_queue dmasound_read_sq;
-#define read_sq		dmasound_read_sq
-#endif
-
 extern int dmasound_catchRadius;
 #define catchRadius	dmasound_catchRadius
 
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
deleted file mode 100644
index 8f63880..0000000
--- a/sound/oss/dmasound/dmasound_awacs.c
+++ /dev/null
@@ -1,3215 +0,0 @@
-/*
- *  linux/sound/oss/dmasound/dmasound_awacs.c
- *
- *  PowerMac `AWACS' and `Burgundy' DMA Sound Driver
- *  with some limited support for DACA & Tumbler
- *
- *  See linux/sound/oss/dmasound/dmasound_core.c for copyright and
- *  history prior to 2001/01/26.
- *
- *	26/01/2001 ed 0.1 Iain Sandoe
- *		- added version info.
- *		- moved dbdma command buffer allocation to PMacXXXSqSetup()
- *		- fixed up beep dbdma cmd buffers
- *
- *	08/02/2001 [0.2]
- *		- make SNDCTL_DSP_GETFMTS return the correct info for the h/w
- *		- move soft format translations to a separate file
- *		- [0.3] make SNDCTL_DSP_GETCAPS return correct info.
- *		- [0.4] more informative machine name strings.
- *		- [0.5]
- *		- record changes.
- *		- made the default_hard/soft entries.
- *	04/04/2001 [0.6]
- *		- minor correction to bit assignments in awacs_defs.h
- *		- incorporate mixer changes from 2.2.x back-port.
- *		- take out passthru as a rec input (it isn't).
- *              - make Input Gain slider work the 'right way up'.
- *              - try to make the mixer sliders more logical - so now the
- *                input selectors are just two-state (>50% == ON) and the
- *                Input Gain slider handles the rest of the gain issues.
- *              - try to pick slider representations that most closely match
- *                the actual use - e.g. IGain for input gain... 
- *              - first stab at over/under-run detection.
- *		- minor cosmetic changes to IRQ identification.
- *		- fix bug where rates > max would be reported as supported.
- *              - first stab at over/under-run detection.
- *              - make use of i2c for mixer settings conditional on perch
- *                rather than cuda (some machines without perch have cuda).
- *              - fix bug where TX stops when dbdma status comes up "DEAD"
- *		  so far only reported on PowerComputing clones ... but.
- *		- put in AWACS/Screamer register write timeouts.
- *		- part way to partitioning the init() stuff
- *		- first pass at 'tumbler' stuff (not support - just an attempt
- *		  to allow the driver to load on new G4s).
- *      01/02/2002 [0.7] - BenH
- *	        - all sort of minor bits went in since the latest update, I
- *	          bumped the version number for that reason
- *
- *      07/26/2002 [0.8] - BenH
- *	        - More minor bits since last changelog (I should be more careful
- *	          with those)
- *	        - Support for snapper & better tumbler integration by Toby Sargeant
- *	        - Headphone detect for scremer by Julien Blache
- *	        - More tumbler fixed by Andreas Schwab
- *	11/29/2003 [0.8.1] - Renzo Davoli (King Enzo)
- *		- Support for Snapper line in
- *		- snapper input resampling (for rates < 44100)
- *		- software line gain control
- */
-
-/* GENERAL FIXME/TODO: check that the assumptions about what is written to
-   mac-io is valid for DACA & Tumbler.
-
-   This driver is in bad need of a rewrite. The dbdma code has to be split,
-   some proper device-tree parsing code has to be written, etc...
-*/
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/soundcard.h>
-#include <linux/adb.h>
-#include <linux/nvram.h>
-#include <linux/tty.h>
-#include <linux/vt_kern.h>
-#include <linux/spinlock.h>
-#include <linux/kmod.h>
-#include <linux/interrupt.h>
-#include <linux/input.h>
-#include <linux/mutex.h>
-#ifdef CONFIG_ADB_CUDA
-#include <linux/cuda.h>
-#endif
-#ifdef CONFIG_ADB_PMU
-#include <linux/pmu.h>
-#endif
-
-#include <asm/uaccess.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/io.h>
-#include <asm/dbdma.h>
-#include <asm/pmac_feature.h>
-#include <asm/irq.h>
-#include <asm/nvram.h>
-
-#include "awacs_defs.h"
-#include "dmasound.h"
-#include "tas3001c.h"
-#include "tas3004.h"
-#include "tas_common.h"
-
-#define DMASOUND_AWACS_REVISION	0
-#define DMASOUND_AWACS_EDITION	7
-
-#define AWACS_SNAPPER   110	/* fake revision # for snapper */
-#define AWACS_BURGUNDY	100	/* fake revision # for burgundy */
-#define AWACS_TUMBLER    90	/* fake revision # for tumbler */
-#define AWACS_DACA	 80	/* fake revision # for daca (ibook) */
-#define AWACS_AWACS       2     /* holding revision for AWACS */
-#define AWACS_SCREAMER    3     /* holding revision for Screamer */
-/*
- * Interrupt numbers and addresses, & info obtained from the device tree.
- */
-static int awacs_irq, awacs_tx_irq, awacs_rx_irq;
-static volatile struct awacs_regs __iomem *awacs;
-static volatile u32 __iomem *i2s;
-static volatile struct dbdma_regs __iomem *awacs_txdma, *awacs_rxdma;
-static int awacs_rate_index;
-static int awacs_subframe;
-static struct device_node* awacs_node;
-static struct device_node* i2s_node;
-static struct resource awacs_rsrc[3];
-
-static char awacs_name[64];
-static int awacs_revision;
-static int awacs_sleeping;
-static DEFINE_MUTEX(dmasound_mutex);
-
-static int sound_device_id;		/* exists after iMac revA */
-static int hw_can_byteswap = 1 ;	/* most pmac sound h/w can */
-
-/* model info */
-/* To be replaced with better interaction with pmac_feature.c */
-static int is_pbook_3X00;
-static int is_pbook_g3;
-
-/* expansion info */
-static int has_perch;
-static int has_ziva;
-
-/* for earlier powerbooks which need fiddling with mac-io to enable
- * cd etc.
-*/
-static unsigned char __iomem *latch_base;
-static unsigned char __iomem *macio_base;
-
-/*
- * Space for the DBDMA command blocks.
- */
-static void *awacs_tx_cmd_space;
-static volatile struct dbdma_cmd *awacs_tx_cmds;
-static int number_of_tx_cmd_buffers;
-
-static void *awacs_rx_cmd_space;
-static volatile struct dbdma_cmd *awacs_rx_cmds;
-static int number_of_rx_cmd_buffers;
-
-/*
- * Cached values of AWACS registers (we can't read them).
- * Except on the burgundy (and screamer). XXX
- */
-
-int awacs_reg[8];
-int awacs_reg1_save;
-
-/* tracking values for the mixer contents
-*/
-
-static int spk_vol;
-static int line_vol;
-static int passthru_vol;
-
-static int ip_gain;           /* mic preamp settings */
-static int rec_lev = 0x4545 ; /* default CD gain 69 % */
-static int mic_lev;
-static int cd_lev = 0x6363 ; /* 99 % */
-static int line_lev;
-
-static int hdp_connected;
-
-/*
- * Stuff for outputting a beep.  The values range from -327 to +327
- * so we can multiply by an amplitude in the range 0..100 to get a
- * signed short value to put in the output buffer.
- */
-static short beep_wform[256] = {
-	0,	40,	79,	117,	153,	187,	218,	245,
-	269,	288,	304,	316,	323,	327,	327,	324,
-	318,	310,	299,	288,	275,	262,	249,	236,
-	224,	213,	204,	196,	190,	186,	183,	182,
-	182,	183,	186,	189,	192,	196,	200,	203,
-	206,	208,	209,	209,	209,	207,	204,	201,
-	197,	193,	188,	183,	179,	174,	170,	166,
-	163,	161,	160,	159,	159,	160,	161,	162,
-	164,	166,	168,	169,	171,	171,	171,	170,
-	169,	167,	163,	159,	155,	150,	144,	139,
-	133,	128,	122,	117,	113,	110,	107,	105,
-	103,	103,	103,	103,	104,	104,	105,	105,
-	105,	103,	101,	97,	92,	86,	78,	68,
-	58,	45,	32,	18,	3,	-11,	-26,	-41,
-	-55,	-68,	-79,	-88,	-95,	-100,	-102,	-102,
-	-99,	-93,	-85,	-75,	-62,	-48,	-33,	-16,
-	0,	16,	33,	48,	62,	75,	85,	93,
-	99,	102,	102,	100,	95,	88,	79,	68,
-	55,	41,	26,	11,	-3,	-18,	-32,	-45,
-	-58,	-68,	-78,	-86,	-92,	-97,	-101,	-103,
-	-105,	-105,	-105,	-104,	-104,	-103,	-103,	-103,
-	-103,	-105,	-107,	-110,	-113,	-117,	-122,	-128,
-	-133,	-139,	-144,	-150,	-155,	-159,	-163,	-167,
-	-169,	-170,	-171,	-171,	-171,	-169,	-168,	-166,
-	-164,	-162,	-161,	-160,	-159,	-159,	-160,	-161,
-	-163,	-166,	-170,	-174,	-179,	-183,	-188,	-193,
-	-197,	-201,	-204,	-207,	-209,	-209,	-209,	-208,
-	-206,	-203,	-200,	-196,	-192,	-189,	-186,	-183,
-	-182,	-182,	-183,	-186,	-190,	-196,	-204,	-213,
-	-224,	-236,	-249,	-262,	-275,	-288,	-299,	-310,
-	-318,	-324,	-327,	-327,	-323,	-316,	-304,	-288,
-	-269,	-245,	-218,	-187,	-153,	-117,	-79,	-40,
-};
-
-/* beep support */
-#define BEEP_SRATE	22050	/* 22050 Hz sample rate */
-#define BEEP_BUFLEN	512
-#define BEEP_VOLUME	15	/* 0 - 100 */
-
-static int beep_vol = BEEP_VOLUME;
-static int beep_playing;
-static int awacs_beep_state;
-static short *beep_buf;
-static void *beep_dbdma_cmd_space;
-static volatile struct dbdma_cmd *beep_dbdma_cmd;
-
-/* Burgundy functions */
-static void awacs_burgundy_wcw(unsigned addr,unsigned newval);
-static unsigned awacs_burgundy_rcw(unsigned addr);
-static void awacs_burgundy_write_volume(unsigned address, int volume);
-static int awacs_burgundy_read_volume(unsigned address);
-static void awacs_burgundy_write_mvolume(unsigned address, int volume);
-static int awacs_burgundy_read_mvolume(unsigned address);
-
-/* we will allocate a single 'emergency' dbdma cmd block to use if the
-   tx status comes up "DEAD".  This happens on some PowerComputing Pmac
-   clones, either owing to a bug in dbdma or some interaction between
-   IDE and sound.  However, this measure would deal with DEAD status if
-   if appeared elsewhere.
-
-   for the sake of memory efficiency we'll allocate this cmd as part of
-   the beep cmd stuff.
-*/
-
-static volatile struct dbdma_cmd *emergency_dbdma_cmd;
-
-#ifdef CONFIG_PM
-/*
- * Stuff for restoring after a sleep.
- */
-static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when);
-struct pmu_sleep_notifier awacs_sleep_notifier = {
-	awacs_sleep_notify, SLEEP_LEVEL_SOUND,
-};
-#endif /* CONFIG_PM */
-
-/* for (soft) sample rate translations */
-int expand_bal;		/* Balance factor for expanding (not volume!) */
-int expand_read_bal;	/* Balance factor for expanding reads (not volume!) */
-
-/*** Low level stuff *********************************************************/
-
-static void *PMacAlloc(unsigned int size, gfp_t flags);
-static void PMacFree(void *ptr, unsigned int size);
-static int PMacIrqInit(void);
-#ifdef MODULE
-static void PMacIrqCleanup(void);
-#endif
-static void PMacSilence(void);
-static void PMacInit(void);
-static int PMacSetFormat(int format);
-static int PMacSetVolume(int volume);
-static void PMacPlay(void);
-static void PMacRecord(void);
-static irqreturn_t pmac_awacs_tx_intr(int irq, void *devid);
-static irqreturn_t pmac_awacs_rx_intr(int irq, void *devid);
-static irqreturn_t pmac_awacs_intr(int irq, void *devid);
-static void awacs_write(int val);
-static int awacs_get_volume(int reg, int lshift);
-static int awacs_volume_setter(int volume, int n, int mute, int lshift);
-
-
-/*** Mid level stuff **********************************************************/
-
-static int PMacMixerIoctl(u_int cmd, u_long arg);
-static int PMacWriteSqSetup(void);
-static int PMacReadSqSetup(void);
-static void PMacAbortRead(void);
-
-extern TRANS transAwacsNormal ;
-extern TRANS transAwacsExpand ;
-extern TRANS transAwacsNormalRead ;
-extern TRANS transAwacsExpandRead ;
-
-extern int daca_init(void);
-extern void daca_cleanup(void);
-extern int daca_set_volume(uint left_vol, uint right_vol);
-extern void daca_get_volume(uint * left_vol, uint  *right_vol);
-extern int daca_enter_sleep(void);
-extern int daca_leave_sleep(void);
-
-#define TRY_LOCK()	\
-	if ((rc = mutex_lock_interruptible(&dmasound_mutex)) != 0)	\
-		return rc;
-#define LOCK()		mutex_lock(&dmasound_mutex);
-
-#define UNLOCK()	mutex_unlock(&dmasound_mutex);
-
-/* We use different versions that the ones provided in dmasound.h
- * 
- * FIXME: Use different names ;)
- */
-#undef IOCTL_IN
-#undef IOCTL_OUT
-
-#define IOCTL_IN(arg, ret)	\
-	rc = get_user(ret, (int __user *)(arg)); \
-	if (rc) break;
-#define IOCTL_OUT(arg, ret)	\
-	ioctl_return2((int __user *)(arg), ret)
-
-static inline int ioctl_return2(int __user *addr, int value)
-{
-	return value < 0 ? value : put_user(value, addr);
-}
-
-
-/*** AE - TUMBLER / SNAPPER START ************************************************/
-
-
-int gpio_audio_reset, gpio_audio_reset_pol;
-int gpio_amp_mute, gpio_amp_mute_pol;
-int gpio_headphone_mute, gpio_headphone_mute_pol;
-int gpio_headphone_detect, gpio_headphone_detect_pol;
-int gpio_headphone_irq;
-
-int
-setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int* gpio_pol)
-{
-	struct device_node *gpiop;
-	struct device_node *np;
-	const u32* pp;
-	int ret = -ENODEV;
-
-	gpiop = of_find_node_by_name(NULL, "gpio");
-	if (!gpiop)
-		goto done;
-
-	np = of_get_next_child(gpiop, NULL);
-	while(np != 0) {
-		if (name) {
-			const char *property =
-				of_get_property(np,"audio-gpio",NULL);
-			if (property != 0 && strcmp(property,name) == 0)
-				break;
-		} else if (compatible && of_device_is_compatible(np, compatible))
-			break;
-		np = of_get_next_child(gpiop, np);
-	}
-	if (!np)
-		goto done;
-	pp = of_get_property(np, "AAPL,address", NULL);
-	if (!pp)
-		goto done;
-	*gpio_addr = (*pp) & 0x0000ffff;
-	pp = of_get_property(np, "audio-gpio-active-state", NULL);
-	if (pp)
-		*gpio_pol = *pp;
-	else
-		*gpio_pol = 1;
-	ret = irq_of_parse_and_map(np, 0);
-done:
-	of_node_put(np);
-	of_node_put(gpiop);
-	return ret;
-}
-
-static inline void
-write_audio_gpio(int gpio_addr, int data)
-{
-	if (!gpio_addr)
-		return;
-	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_addr, data ? 0x05 : 0x04);
-}
-
-static inline int
-read_audio_gpio(int gpio_addr)
-{
-	if (!gpio_addr)
-		return 0;
-	return ((pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_addr, 0) & 0x02) !=0);
-}
-
-/*
- * Headphone interrupt via GPIO (Tumbler, Snapper, DACA)
- */
-static irqreturn_t
-headphone_intr(int irq, void *devid)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&dmasound.lock, flags);
-	if (read_audio_gpio(gpio_headphone_detect) == gpio_headphone_detect_pol) {
-		printk(KERN_INFO "Audio jack plugged, muting speakers.\n");
-		write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
-		write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
-		tas_output_device_change(sound_device_id,TAS_OUTPUT_HEADPHONES,0);
-	} else {
-		printk(KERN_INFO "Audio jack unplugged, enabling speakers.\n");
-		write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
-		write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
-		tas_output_device_change(sound_device_id,TAS_OUTPUT_INTERNAL_SPKR,0);
-	}
-	spin_unlock_irqrestore(&dmasound.lock, flags);
-	return IRQ_HANDLED;
-}
-
-
-/* Initialize tumbler */
-
-static int
-tas_dmasound_init(void)
-{
-	setup_audio_gpio(
-		"audio-hw-reset",
-		NULL,
-		&gpio_audio_reset,
-		&gpio_audio_reset_pol);
-	setup_audio_gpio(
-		"amp-mute",
-		NULL,
-		&gpio_amp_mute,
-		&gpio_amp_mute_pol);
-	setup_audio_gpio("headphone-mute",
-		NULL,
-		&gpio_headphone_mute,
-		&gpio_headphone_mute_pol);
-	gpio_headphone_irq = setup_audio_gpio(
-		"headphone-detect",
-		NULL,
-		&gpio_headphone_detect,
-		&gpio_headphone_detect_pol);
-	/* Fix some broken OF entries in desktop machines */
-	if (!gpio_headphone_irq)
-		gpio_headphone_irq = setup_audio_gpio(
-			NULL,
-			"keywest-gpio15",
-			&gpio_headphone_detect,
-			&gpio_headphone_detect_pol);
-
-	write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
-	msleep(100);
-	write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
-	msleep(100);
-  	if (gpio_headphone_irq) {
-		if (request_irq(gpio_headphone_irq,headphone_intr,0,"Headphone detect",NULL) < 0) {
-    			printk(KERN_ERR "tumbler: Can't request headphone interrupt\n");
-    			gpio_headphone_irq = 0;
-    		} else {
-			u8 val;
-			/* Activate headphone status interrupts */
-			val = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_headphone_detect, 0);
-			pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_headphone_detect, val | 0x80);
-			/* Trigger it */
-  			headphone_intr(0, NULL);
-  		}
-  	}
-  	if (!gpio_headphone_irq) {
-  		/* Some machine enter this case ? */
-  		printk(KERN_WARNING "tumbler: Headphone detect IRQ not found, enabling all outputs !\n");
-  		write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
-  		write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
-  	}
-	return 0;
-}
-
-
-static int
-tas_dmasound_cleanup(void)
-{
-	if (gpio_headphone_irq)
-		free_irq(gpio_headphone_irq, NULL);
-	return 0;
-}
-
-/* We don't support 48k yet */
-static int tas_freqs[1] = { 44100 } ;
-static int tas_freqs_ok[1] = { 1 } ;
-
-/* don't know what to do really - just have to leave it where
- * OF left things
-*/
-
-static int
-tas_set_frame_rate(void)
-{
-	if (i2s) {
-		out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
-		out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
-	}
-	dmasound.hard.speed = 44100 ;
-	awacs_rate_index = 0 ;
-	return 44100 ;
-}
-
-static int
-tas_mixer_ioctl(u_int cmd, u_long arg)
-{
-	int __user *argp = (int __user *)arg;
-	int data;
-	int rc;
-
-        rc=tas_device_ioctl(cmd, arg);
-        if (rc != -EINVAL) {
-        	return rc;
-        }
-
-        if ((cmd & ~0xff) == MIXER_WRITE(0) &&
-            tas_supported_mixers() & (1<<(cmd & 0xff))) {
-		rc = get_user(data, argp);
-                if (rc<0) return rc;
-		tas_set_mixer_level(cmd & 0xff, data);
-		tas_get_mixer_level(cmd & 0xff, &data);
-		return ioctl_return2(argp, data);
-        }
-        if ((cmd & ~0xff) == MIXER_READ(0) &&
-            tas_supported_mixers() & (1<<(cmd & 0xff))) {
-		tas_get_mixer_level(cmd & 0xff, &data);
-		return ioctl_return2(argp, data);
-        }
-
-	switch(cmd) {
-	case SOUND_MIXER_READ_DEVMASK:
-		data = tas_supported_mixers() | SOUND_MASK_SPEAKER;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_STEREODEVS:
-		data = tas_stereo_mixers();
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_CAPS:
-		rc = IOCTL_OUT(arg, 0);
-		break;
-	case SOUND_MIXER_READ_RECMASK:
-		// XXX FIXME: find a way to check what is really available */
-		data = SOUND_MASK_LINE | SOUND_MASK_MIC;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_RECSRC:
-		if (awacs_reg[0] & MASK_MUX_AUDIN)
-			data |= SOUND_MASK_LINE;
-		if (awacs_reg[0] & MASK_MUX_MIC)
-			data |= SOUND_MASK_MIC;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_WRITE_RECSRC:
- 		IOCTL_IN(arg, data);
-		data =0;
- 		rc = IOCTL_OUT(arg, data);
- 		break;
-	case SOUND_MIXER_WRITE_SPEAKER:	/* really bell volume */
- 		IOCTL_IN(arg, data);
- 		beep_vol = data & 0xff;
- 		/* fall through */
-	case SOUND_MIXER_READ_SPEAKER:
-		rc = IOCTL_OUT(arg, (beep_vol<<8) | beep_vol);
- 		break;
-	case SOUND_MIXER_OUTMASK:
-	case SOUND_MIXER_OUTSRC:
-	default:
-		rc = -EINVAL;
-	}
-
-	return rc;
-}
-
-static void __init
-tas_init_frame_rates(const unsigned int *prop, unsigned int l)
-{
-	int i ;
-	if (prop) {
-		for (i=0; i<1; i++)
-			tas_freqs_ok[i] = 0;
-		for (l /= sizeof(int); l > 0; --l) {
-			unsigned int r = *prop++;
-			/* Apple 'Fixed' format */
-			if (r >= 0x10000)
-				r >>= 16;
-			for (i = 0; i < 1; ++i) {
-				if (r == tas_freqs[i]) {
-					tas_freqs_ok[i] = 1;
-					break;
-				}
-			}
-		}
-	}
-	/* else we assume that all the rates are available */
-}
-
-
-/*** AE - TUMBLER / SNAPPER END ************************************************/
-
-
-
-/*** Low level stuff *********************************************************/
-
-/*
- * PCI PowerMac, with AWACS, Screamer, Burgundy, DACA or Tumbler and DBDMA.
- */
-static void *PMacAlloc(unsigned int size, gfp_t flags)
-{
-	return kmalloc(size, flags);
-}
-
-static void PMacFree(void *ptr, unsigned int size)
-{
-	kfree(ptr);
-}
-
-static int __init PMacIrqInit(void)
-{
-	if (awacs)
-		if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", NULL))
-			return 0;
-	if (request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", NULL)
-	    || request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "Built-in Sound in", NULL))
-		return 0;
-	return 1;
-}
-
-#ifdef MODULE
-static void PMacIrqCleanup(void)
-{
-	/* turn off input & output dma */
-	DBDMA_DO_STOP(awacs_txdma);
-	DBDMA_DO_STOP(awacs_rxdma);
-
-	if (awacs)
-		/* disable interrupts from awacs interface */
-		out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
-	
-	/* Switch off the sound clock */
-	pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
-	/* Make sure proper bits are set on pismo & tipb */
-	if ((machine_is_compatible("PowerBook3,1") ||
-	    machine_is_compatible("PowerBook3,2")) && awacs) {
-		awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
-		awacs_write(MASK_ADDR1 | awacs_reg[1]);
-		msleep(200);
-	}
-	if (awacs)
-		free_irq(awacs_irq, NULL);
-	free_irq(awacs_tx_irq, NULL);
-	free_irq(awacs_rx_irq, NULL);
-	
-	if (awacs)
-		iounmap(awacs);
-	if (i2s)
-		iounmap(i2s);
-	iounmap(awacs_txdma);
-	iounmap(awacs_rxdma);
-
-	release_mem_region(awacs_rsrc[0].start,
-			   awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
-	release_mem_region(awacs_rsrc[1].start,
-			   awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
-	release_mem_region(awacs_rsrc[2].start,
-			   awacs_rsrc[2].end - awacs_rsrc[2].start + 1);
-
-	kfree(awacs_tx_cmd_space);
-	kfree(awacs_rx_cmd_space);
-	kfree(beep_dbdma_cmd_space);
-	kfree(beep_buf);
-#ifdef CONFIG_PM
-	pmu_unregister_sleep_notifier(&awacs_sleep_notifier);
-#endif
-}
-#endif /* MODULE */
-
-static void PMacSilence(void)
-{
-	/* turn off output dma */
-	DBDMA_DO_STOP(awacs_txdma);
-}
-
-/* don't know what to do really - just have to leave it where
- * OF left things
-*/
-
-static int daca_set_frame_rate(void)
-{
-	if (i2s) {
-		out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
-		out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
-	}
-	dmasound.hard.speed = 44100 ;
-	awacs_rate_index = 0 ;
-	return 44100 ;
-}
-
-static int awacs_freqs[8] = {
-	44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350
-};
-static int awacs_freqs_ok[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
-
-static int
-awacs_set_frame_rate(int desired, int catch_r)
-{
-	int tolerance, i = 8 ;
-	/*
-	 * If we have a sample rate which is within catchRadius percent
-	 * of the requested value, we don't have to expand the samples.
-	 * Otherwise choose the next higher rate.
-	 * N.B.: burgundy awacs only works at 44100 Hz.
-	 */
-	do {
-		tolerance = catch_r * awacs_freqs[--i] / 100;
-		if (awacs_freqs_ok[i]
-		    && dmasound.soft.speed <= awacs_freqs[i] + tolerance)
-			break;
-	} while (i > 0);
-	dmasound.hard.speed = awacs_freqs[i];
-	awacs_rate_index = i;
-
-	out_le32(&awacs->control, MASK_IEPC | (i << 8) | 0x11 );
-	awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) | (i << 3);
-	awacs_write(awacs_reg[1] | MASK_ADDR1);
-	return dmasound.hard.speed;
-}
-
-static int
-burgundy_set_frame_rate(void)
-{
-	awacs_rate_index = 0 ;
-	awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) ;
-	/* XXX disable error interrupt on burgundy for now */
-	out_le32(&awacs->control, MASK_IEPC | 0 | 0x11 | MASK_IEE);
-	return 44100 ;
-}
-
-static int
-set_frame_rate(int desired, int catch_r)
-{
-	switch (awacs_revision) {
-		case AWACS_BURGUNDY:
-			dmasound.hard.speed = burgundy_set_frame_rate();
-			break ;
-		case AWACS_TUMBLER:
-		case AWACS_SNAPPER:
-			dmasound.hard.speed = tas_set_frame_rate();
-			break ;
-		case AWACS_DACA:
-			dmasound.hard.speed =
-			  daca_set_frame_rate();
-			break ;
-		default:
-			dmasound.hard.speed = awacs_set_frame_rate(desired,
-						catch_r);
-			break ;
-	}
-	return dmasound.hard.speed ;
-}
-
-static void
-awacs_recalibrate(void)
-{
-	/* Sorry for the horrible delays... I hope to get that improved
-	 * by making the whole PM process asynchronous in a future version
-	 */
-	msleep(750);
-	awacs_reg[1] |= MASK_CMUTE | MASK_AMUTE;
-	awacs_write(awacs_reg[1] | MASK_RECALIBRATE | MASK_ADDR1);
-	msleep(1000);
-	awacs_write(awacs_reg[1] | MASK_ADDR1);
-}
-
-static void PMacInit(void)
-{
-	int tolerance;
-
-	switch (dmasound.soft.format) {
-	    case AFMT_S16_LE:
-	    case AFMT_U16_LE:
-		if (hw_can_byteswap)
-			dmasound.hard.format = AFMT_S16_LE;
-		else
-			dmasound.hard.format = AFMT_S16_BE;
-		break;
-	default:
-		dmasound.hard.format = AFMT_S16_BE;
-		break;
-	}
-	dmasound.hard.stereo = 1;
-	dmasound.hard.size = 16;
-
-	/* set dmasound.hard.speed - on the basis of what we want (soft)
-	 * and the tolerance we'll allow.
-	*/
-	set_frame_rate(dmasound.soft.speed, catchRadius) ;
-
-	tolerance = (catchRadius * dmasound.hard.speed) / 100;
-	if (dmasound.soft.speed >= dmasound.hard.speed - tolerance) {
-		dmasound.trans_write = &transAwacsNormal;
-		dmasound.trans_read = &transAwacsNormalRead;
-	} else {
-		dmasound.trans_write = &transAwacsExpand;
-		dmasound.trans_read = &transAwacsExpandRead;
-	}
-
-	if (awacs) {
-		if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
-			out_le32(&awacs->byteswap, BS_VAL);
-		else
-			out_le32(&awacs->byteswap, 0);
-	}
-	
-	expand_bal = -dmasound.soft.speed;
-	expand_read_bal = -dmasound.soft.speed;
-}
-
-static int PMacSetFormat(int format)
-{
-	int size;
-	int req_format = format;
-		
-	switch (format) {
-	case AFMT_QUERY:
-		return dmasound.soft.format;
-	case AFMT_MU_LAW:
-	case AFMT_A_LAW:
-	case AFMT_U8:
-	case AFMT_S8:
-		size = 8;
-		break;
-	case AFMT_S16_LE:
-		if(!hw_can_byteswap)
-			format = AFMT_S16_BE;
-	case AFMT_S16_BE:
-		size = 16;
-		break;
-	case AFMT_U16_LE:
-		if(!hw_can_byteswap)
-			format = AFMT_U16_BE;
-	case AFMT_U16_BE:
-		size = 16;
-		break;
-	default: /* :-) */
-		printk(KERN_ERR "dmasound: unknown format 0x%x, using AFMT_U8\n",
-		       format);
-		size = 8;
-		format = AFMT_U8;
-	}
-	
-	if (req_format == format) {
-		dmasound.soft.format = format;
-		dmasound.soft.size = size;
-		if (dmasound.minDev == SND_DEV_DSP) {
-			dmasound.dsp.format = format;
-			dmasound.dsp.size = size;
-		}
-	}
-
-	return format;
-}
-
-#define AWACS_VOLUME_TO_MASK(x)	(15 - ((((x) - 1) * 15) / 99))
-#define AWACS_MASK_TO_VOLUME(y)	(100 - ((y) * 99 / 15))
-
-static int awacs_get_volume(int reg, int lshift)
-{
-	int volume;
-
-	volume = AWACS_MASK_TO_VOLUME((reg >> lshift) & 0xf);
-	volume |= AWACS_MASK_TO_VOLUME(reg & 0xf) << 8;
-	return volume;
-}
-
-static int awacs_volume_setter(int volume, int n, int mute, int lshift)
-{
-	int r1, rn;
-
-	if (mute && volume == 0) {
-		r1 = awacs_reg[1] | mute;
-	} else {
-		r1 = awacs_reg[1] & ~mute;
-		rn = awacs_reg[n] & ~(0xf | (0xf << lshift));
-		rn |= ((AWACS_VOLUME_TO_MASK(volume & 0xff) & 0xf) << lshift);
-		rn |= AWACS_VOLUME_TO_MASK((volume >> 8) & 0xff) & 0xf;
-		awacs_reg[n] = rn;
-		awacs_write((n << 12) | rn);
-		volume = awacs_get_volume(rn, lshift);
-	}
-	if (r1 != awacs_reg[1]) {
-		awacs_reg[1] = r1;
-		awacs_write(r1 | MASK_ADDR1);
-	}
-	return volume;
-}
-
-static int PMacSetVolume(int volume)
-{
-	printk(KERN_WARNING "Bogus call to PMacSetVolume !\n");
-	return 0;
-}
-
-static void awacs_setup_for_beep(int speed)
-{
-	out_le32(&awacs->control,
-		 (in_le32(&awacs->control) & ~0x1f00)
-		 | ((speed > 0 ? speed : awacs_rate_index) << 8));
-
-	if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE) && speed == -1)
-		out_le32(&awacs->byteswap, BS_VAL);
-	else
-		out_le32(&awacs->byteswap, 0);
-}
-
-/* CHECK: how much of this *really* needs IRQs masked? */
-static void __PMacPlay(void)
-{
-	volatile struct dbdma_cmd *cp;
-	int next_frg, count;
-
-	count = 300 ; /* > two cycles at the lowest sample rate */
-
-	/* what we want to send next */
-	next_frg = (write_sq.front + write_sq.active) % write_sq.max_count;
-
-	if (awacs_beep_state) {
-		/* sound takes precedence over beeps */
-		/* stop the dma channel */
-		out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
-		while ( (in_le32(&awacs_txdma->status) & RUN) && count--)
-			udelay(1);
-		if (awacs)
-			awacs_setup_for_beep(-1);
-		out_le32(&awacs_txdma->cmdptr,
-			 virt_to_bus(&(awacs_tx_cmds[next_frg])));
-
-		beep_playing = 0;
-		awacs_beep_state = 0;
-	}
-	/* this won't allow more than two frags to be in the output queue at
-	   once. (or one, if the max frags is 2 - because count can't exceed
-	   2 in that case)
-	*/
-	while (write_sq.active < 2 && write_sq.active < write_sq.count) {
-		count = (write_sq.count == write_sq.active + 1) ?
-				write_sq.rear_size:write_sq.block_size ;
-		if (count < write_sq.block_size) {
-			if (!write_sq.syncing) /* last block not yet filled,*/
-				break; 	/* and we're not syncing or POST-ed */
-			else {
-				/* pretend the block is full to force a new
-				   block to be started on the next write */
-				write_sq.rear_size = write_sq.block_size ;
-				write_sq.syncing &= ~2 ; /* clear POST */
-			}
-		}
-		cp = &awacs_tx_cmds[next_frg];
-		st_le16(&cp->req_count, count);
-		st_le16(&cp->xfer_status, 0);
-		st_le16(&cp->command, OUTPUT_MORE + INTR_ALWAYS);
-		/* put a STOP at the end of the queue - but only if we have
-		   space for it.  This means that, if we under-run and we only
-		   have two fragments, we might re-play sound from an existing
-		   queued frag.  I guess the solution to that is not to set two
-		   frags if you are likely to under-run...
-		*/
-		if (write_sq.count < write_sq.max_count) {
-			if (++next_frg >= write_sq.max_count)
-				next_frg = 0 ; /* wrap */
-			/* if we get here then we've underrun so we will stop*/
-			st_le16(&awacs_tx_cmds[next_frg].command, DBDMA_STOP);
-		}
-		/* set the dbdma controller going, if it is not already */
-		if (write_sq.active == 0)
-			out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp));
-		(void)in_le32(&awacs_txdma->status);
-		out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
-		++write_sq.active;
-	}
-}
-
-static void PMacPlay(void)
-{
-	LOCK();
-	if (!awacs_sleeping) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&dmasound.lock, flags);
-		__PMacPlay();
-		spin_unlock_irqrestore(&dmasound.lock, flags);
-	}
-	UNLOCK();
-}
-
-static void PMacRecord(void)
-{
-	unsigned long flags;
-
-	if (read_sq.active)
-		return;
-
-	spin_lock_irqsave(&dmasound.lock, flags);
-
-	/* This is all we have to do......Just start it up.
-	*/
-	out_le32(&awacs_rxdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
-	read_sq.active = 1;
-
-	spin_unlock_irqrestore(&dmasound.lock, flags);
-}
-
-/* if the TX status comes up "DEAD" - reported on some Power Computing machines
-   we need to re-start the dbdma - but from a different physical start address
-   and with a different transfer length.  It would get very messy to do this
-   with the normal dbdma_cmd blocks - we would have to re-write the buffer start
-   addresses each time.  So, we will keep a single dbdma_cmd block which can be
-   fiddled with.
-   When DEAD status is first reported the content of the faulted dbdma block is
-   copied into the emergency buffer and we note that the buffer is in use.
-   we then bump the start physical address by the amount that was successfully
-   output before it died.
-   On any subsequent DEAD result we just do the bump-ups (we know that we are
-   already using the emergency dbdma_cmd).
-   CHECK: this just tries to "do it".  It is possible that we should abandon
-   xfers when the number of residual bytes gets below a certain value - I can
-   see that this might cause a loop-forever if too small a transfer causes
-   DEAD status.  However this is a TODO for now - we'll see what gets reported.
-   When we get a successful transfer result with the emergency buffer we just
-   pretend that it completed using the original dmdma_cmd and carry on.  The
-   'next_cmd' field will already point back to the original loop of blocks.
-*/
-
-static irqreturn_t
-pmac_awacs_tx_intr(int irq, void *devid)
-{
-	int i = write_sq.front;
-	int stat;
-	int i_nowrap = write_sq.front;
-	volatile struct dbdma_cmd *cp;
-	/* != 0 when we are dealing with a DEAD xfer */
-	static int emergency_in_use;
-
-	spin_lock(&dmasound.lock);
-	while (write_sq.active > 0) { /* we expect to have done something*/
-		if (emergency_in_use) /* we are dealing with DEAD xfer */
-			cp = emergency_dbdma_cmd ;
-		else
-			cp = &awacs_tx_cmds[i];
-		stat = ld_le16(&cp->xfer_status);
-		if (stat & DEAD) {
-			unsigned short req, res ;
-			unsigned int phy ;
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: tx-irq: xfer died - patching it up...\n") ;
-#endif
-			/* to clear DEAD status we must first clear RUN
-			   set it to quiescent to be on the safe side */
-			(void)in_le32(&awacs_txdma->status);
-			out_le32(&awacs_txdma->control,
-				(RUN|PAUSE|FLUSH|WAKE) << 16);
-			write_sq.died++ ;
-			if (!emergency_in_use) { /* new problem */
-				memcpy((void *)emergency_dbdma_cmd, (void *)cp,
-					sizeof(struct dbdma_cmd));
-				emergency_in_use = 1;
-				cp = emergency_dbdma_cmd;
-			}
-			/* now bump the values to reflect the amount
-			   we haven't yet shifted */
-			req = ld_le16(&cp->req_count);
-			res = ld_le16(&cp->res_count);
-			phy = ld_le32(&cp->phy_addr);
-			phy += (req - res);
-			st_le16(&cp->req_count, res);
-			st_le16(&cp->res_count, 0);
-			st_le16(&cp->xfer_status, 0);
-			st_le32(&cp->phy_addr, phy);
-			st_le32(&cp->cmd_dep, virt_to_bus(&awacs_tx_cmds[(i+1)%write_sq.max_count]));
-			st_le16(&cp->command, OUTPUT_MORE | BR_ALWAYS | INTR_ALWAYS);
-			
-			/* point at our patched up command block */
-			out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp));
-			/* we must re-start the controller */
-			(void)in_le32(&awacs_txdma->status);
-			/* should complete clearing the DEAD status */
-			out_le32(&awacs_txdma->control,
-				((RUN|WAKE) << 16) + (RUN|WAKE));
-			break; /* this block is still going */
-		}
-		if ((stat & ACTIVE) == 0)
-			break;	/* this frame is still going */
-		if (emergency_in_use)
-			emergency_in_use = 0 ; /* done that */
-		--write_sq.count;
-		--write_sq.active;
-		i_nowrap++;
-		if (++i >= write_sq.max_count)
-			i = 0;
-	}
-
-	/* if we stopped and we were not sync-ing - then we under-ran */
-	if( write_sq.syncing == 0 ){
-		stat = in_le32(&awacs_txdma->status) ;
-		/* we hit the dbdma_stop */
-		if( (stat & ACTIVE) == 0 ) write_sq.xruns++ ;
-	}
-
-	/* if we used some data up then wake the writer to supply some more*/
-	if (i_nowrap != write_sq.front)
-		WAKE_UP(write_sq.action_queue);
-	write_sq.front = i;
-
-	/* but make sure we funnel what we've already got */\
-	 if (!awacs_sleeping)
-		__PMacPlay();
-
-	/* make the wake-on-empty conditional on syncing */
-	if (!write_sq.active && (write_sq.syncing & 1))
-		WAKE_UP(write_sq.sync_queue); /* any time we're empty */
-	spin_unlock(&dmasound.lock);
-	return IRQ_HANDLED;
-}
-
-
-static irqreturn_t
-pmac_awacs_rx_intr(int irq, void *devid)
-{
-	int stat ;
-	/* For some reason on my PowerBook G3, I get one interrupt
-	 * when the interrupt vector is installed (like something is
-	 * pending).  This happens before the dbdma is initialized by
-	 * us, so I just check the command pointer and if it is zero,
-	 * just blow it off.
-	 */
-	if (in_le32(&awacs_rxdma->cmdptr) == 0)
-		return IRQ_HANDLED;
-
-	/* We also want to blow 'em off when shutting down.
-	*/
-	if (read_sq.active == 0)
-		return IRQ_HANDLED;
-
-	spin_lock(&dmasound.lock);
-	/* Check multiple buffers in case we were held off from
-	 * interrupt processing for a long time.  Geeze, I really hope
-	 * this doesn't happen.
-	 */
-	while ((stat=awacs_rx_cmds[read_sq.rear].xfer_status)) {
-
-		/* if we got a "DEAD" status then just log it for now.
-		   and try to restart dma.
-		   TODO: figure out how best to fix it up
-		*/
-		if (stat & DEAD){
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n");
-#endif
-			/* to clear DEAD status we must first clear RUN
-			   set it to quiescent to be on the safe side */
-			(void)in_le32(&awacs_txdma->status);
-			out_le32(&awacs_txdma->control,
-				(RUN|PAUSE|FLUSH|WAKE) << 16);
-			awacs_rx_cmds[read_sq.rear].xfer_status = 0;
-			awacs_rx_cmds[read_sq.rear].res_count = 0;
-			read_sq.died++ ;
-			(void)in_le32(&awacs_txdma->status);
-			/* re-start the same block */
-			out_le32(&awacs_rxdma->cmdptr,
-				virt_to_bus(&awacs_rx_cmds[read_sq.rear]));
-			/* we must re-start the controller */
-			(void)in_le32(&awacs_rxdma->status);
-			/* should complete clearing the DEAD status */
-			out_le32(&awacs_rxdma->control,
-				((RUN|WAKE) << 16) + (RUN|WAKE));
-			spin_unlock(&dmasound.lock);
-			return IRQ_HANDLED; /* try this block again */
-		}
-		/* Clear status and move on to next buffer.
-		*/
-		awacs_rx_cmds[read_sq.rear].xfer_status = 0;
-		read_sq.rear++;
-
-		/* Wrap the buffer ring.
-		*/
-		if (read_sq.rear >= read_sq.max_active)
-			read_sq.rear = 0;
-
-		/* If we have caught up to the front buffer, bump it.
-		 * This will cause weird (but not fatal) results if the
-		 * read loop is currently using this buffer.  The user is
-		 * behind in this case anyway, so weird things are going
-		 * to happen.
-		 */
-		if (read_sq.rear == read_sq.front) {
-			read_sq.front++;
-			read_sq.xruns++ ; /* we overan */
-			if (read_sq.front >= read_sq.max_active)
-				read_sq.front = 0;
-		}
-	}
-
-	WAKE_UP(read_sq.action_queue);
-	spin_unlock(&dmasound.lock);
-	return IRQ_HANDLED;
-}
-
-
-static irqreturn_t
-pmac_awacs_intr(int irq, void *devid)
-{
-	int ctrl;
-	int status;
-	int r1;
-
-	spin_lock(&dmasound.lock);
-	ctrl = in_le32(&awacs->control);
-	status = in_le32(&awacs->codec_stat);
-
-	if (ctrl & MASK_PORTCHG) {
-		/* tested on Screamer, should work on others too */
-		if (awacs_revision == AWACS_SCREAMER) {
-			if (((status & MASK_HDPCONN) >> 3) && (hdp_connected == 0)) {
-				hdp_connected = 1;
-				
-				r1 = awacs_reg[1] | MASK_SPKMUTE;
-				awacs_reg[1] = r1;
-				awacs_write(r1 | MASK_ADDR_MUTE);
-			} else if (((status & MASK_HDPCONN) >> 3 == 0) && (hdp_connected == 1)) {
-				hdp_connected = 0;
-				
-				r1 = awacs_reg[1] & ~MASK_SPKMUTE;
-				awacs_reg[1] = r1;
-				awacs_write(r1 | MASK_ADDR_MUTE);
-			}
-		}
-	}
-	if (ctrl & MASK_CNTLERR) {
-		int err = (in_le32(&awacs->codec_stat) & MASK_ERRCODE) >> 16;
-		/* CHECK: we just swallow burgundy errors at the moment..*/
-		if (err != 0 && awacs_revision != AWACS_BURGUNDY)
-			printk(KERN_ERR "dmasound_pmac: error %x\n", err);
-	}
-	/* Writing 1s to the CNTLERR and PORTCHG bits clears them... */
-	out_le32(&awacs->control, ctrl);
-	spin_unlock(&dmasound.lock);
-	return IRQ_HANDLED;
-}
-
-static void
-awacs_write(int val)
-{
-	int count = 300 ;
-	if (awacs_revision >= AWACS_DACA || !awacs)
-		return ;
-
-	while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
-		udelay(1) ;	/* timeout is > 2 samples at lowest rate */
-	out_le32(&awacs->codec_ctrl, val | (awacs_subframe << 22));
-	(void)in_le32(&awacs->byteswap);
-}
-
-/* this is called when the beep timer expires... it will be called even
-   if the beep has been overidden by other sound output.
-*/
-static void awacs_nosound(unsigned long xx)
-{
-	unsigned long flags;
-	int count = 600 ; /* > four samples at lowest rate */
-
-	spin_lock_irqsave(&dmasound.lock, flags);
-	if (beep_playing) {
-		st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
-		out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
-		while ((in_le32(&awacs_txdma->status) & RUN) && count--)
-			udelay(1);
-		if (awacs)
-			awacs_setup_for_beep(-1);
-		beep_playing = 0;
-	}
-	spin_unlock_irqrestore(&dmasound.lock, flags);
-}
-
-/*
- * We generate the beep with a single dbdma command that loops a buffer
- * forever - without generating interrupts.
- *
- * So, to stop it you have to stop dma output as per awacs_nosound.
- */
-static int awacs_beep_event(struct input_dev *dev, unsigned int type,
-		unsigned int code, int hz)
-{
-	unsigned long flags;
-	int beep_speed = 0;
-	int srate;
-	int period, ncycles, nsamples;
-	int i, j, f;
-	short *p;
-	static int beep_hz_cache;
-	static int beep_nsamples_cache;
-	static int beep_volume_cache;
-
-	if (type != EV_SND)
-		return -1;
-	switch (code) {
-	case SND_BELL:
-		if (hz)
-			hz = 1000;
-		break;
-	case SND_TONE:
-		break;
-	default:
-		return -1;
-	}
-
-	if (beep_buf == NULL)
-		return -1;
-
-	/* quick-hack fix for DACA, Burgundy & Tumbler */
-
-	if (awacs_revision >= AWACS_DACA){
-		srate = 44100 ;
-	} else {
-		for (i = 0; i < 8 && awacs_freqs[i] >= BEEP_SRATE; ++i)
-			if (awacs_freqs_ok[i])
-				beep_speed = i;
-		srate = awacs_freqs[beep_speed];
-	}
-
-	if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) {
-		/* cancel beep currently playing */
-		awacs_nosound(0);
-		return 0;
-	}
-
-	spin_lock_irqsave(&dmasound.lock, flags);
-	if (beep_playing || write_sq.active || beep_buf == NULL) {
-		spin_unlock_irqrestore(&dmasound.lock, flags);
-		return -1;		/* too hard, sorry :-( */
-	}
-	beep_playing = 1;
-	st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS);
-	spin_unlock_irqrestore(&dmasound.lock, flags);
-
-	if (hz == beep_hz_cache && beep_vol == beep_volume_cache) {
-		nsamples = beep_nsamples_cache;
-	} else {
-		period = srate * 256 / hz;	/* fixed point */
-		ncycles = BEEP_BUFLEN * 256 / period;
-		nsamples = (period * ncycles) >> 8;
-		f = ncycles * 65536 / nsamples;
-		j = 0;
-		p = beep_buf;
-		for (i = 0; i < nsamples; ++i, p += 2) {
-			p[0] = p[1] = beep_wform[j >> 8] * beep_vol;
-			j = (j + f) & 0xffff;
-		}
-		beep_hz_cache = hz;
-		beep_volume_cache = beep_vol;
-		beep_nsamples_cache = nsamples;
-	}
-
-	st_le16(&beep_dbdma_cmd->req_count, nsamples*4);
-	st_le16(&beep_dbdma_cmd->xfer_status, 0);
-	st_le32(&beep_dbdma_cmd->cmd_dep, virt_to_bus(beep_dbdma_cmd));
-	st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf));
-	awacs_beep_state = 1;
-
-	spin_lock_irqsave(&dmasound.lock, flags);
-	if (beep_playing) {	/* i.e. haven't been terminated already */
-		int count = 300 ;
-		out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
-		while ((in_le32(&awacs_txdma->status) & RUN) && count--)
-			udelay(1); /* timeout > 2 samples at lowest rate*/
-		if (awacs)
-			awacs_setup_for_beep(beep_speed);
-		out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
-		(void)in_le32(&awacs_txdma->status);
-		out_le32(&awacs_txdma->control, RUN | (RUN << 16));
-	}
-	spin_unlock_irqrestore(&dmasound.lock, flags);
-
-	return 0;
-}
-
-/* used in init and for wake-up */
-
-static void
-load_awacs(void)
-{
-	awacs_write(awacs_reg[0] + MASK_ADDR0);
-	awacs_write(awacs_reg[1] + MASK_ADDR1);
-	awacs_write(awacs_reg[2] + MASK_ADDR2);
-	awacs_write(awacs_reg[4] + MASK_ADDR4);
-
-	if (awacs_revision == AWACS_SCREAMER) {
-		awacs_write(awacs_reg[5] + MASK_ADDR5);
-		msleep(100);
-		awacs_write(awacs_reg[6] + MASK_ADDR6);
-		msleep(2);
-		awacs_write(awacs_reg[1] + MASK_ADDR1);
-		awacs_write(awacs_reg[7] + MASK_ADDR7);
-	}
-	if (awacs) {
-		if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
-			out_le32(&awacs->byteswap, BS_VAL);
-		else
-			out_le32(&awacs->byteswap, 0);
-	}
-}
-
-#ifdef CONFIG_PM
-/*
- * Save state when going to sleep, restore it afterwards.
- */
-/* FIXME: sort out disabling/re-enabling of read stuff as well */
-static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when)
-{
-	unsigned long flags;
-
-	switch (when) {
-	case PBOOK_SLEEP_NOW:		
-		LOCK();
-		awacs_sleeping = 1;
-		/* Tell the rest of the driver we are now going to sleep */
-		mb();
-		if (awacs_revision == AWACS_SCREAMER ||
-		    awacs_revision == AWACS_AWACS) {
-			awacs_reg1_save = awacs_reg[1];
-			awacs_reg[1] |= MASK_AMUTE | MASK_CMUTE;
-			awacs_write(MASK_ADDR1 | awacs_reg[1]);
-		}
-
-		PMacSilence();
-		/* stop rx - if going - a bit of a daft user... but */
-		out_le32(&awacs_rxdma->control, (RUN|WAKE|FLUSH << 16));
-		/* deny interrupts */
-		if (awacs)
-			disable_irq(awacs_irq);
-		disable_irq(awacs_tx_irq);
-		disable_irq(awacs_rx_irq);
-		/* Chip specific sleep code */
-		switch (awacs_revision) {
-			case AWACS_TUMBLER:
-			case AWACS_SNAPPER:
-				write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
-				write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
-				tas_enter_sleep();
-				write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
-				break ;
-			case AWACS_DACA:
-				daca_enter_sleep();
-				break ;
-			case AWACS_BURGUNDY:
-				break ;
-			case AWACS_SCREAMER:
-			case AWACS_AWACS:
-			default:
-				out_le32(&awacs->control, 0x11) ;
-				break ;
-		}
-		/* Disable sound clock */
-		pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
-		/* According to Darwin, we do that after turning off the sound
-		 * chip clock. All this will have to be cleaned up once we properly
-		 * parse the OF sound-objects
-		 */
-		if ((machine_is_compatible("PowerBook3,1") ||
-		    machine_is_compatible("PowerBook3,2")) && awacs) {
-			awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
-			awacs_write(MASK_ADDR1 | awacs_reg[1]);
-			msleep(200);
-		}
-		break;
-	case PBOOK_WAKE:
-		/* Enable sound clock */
-		pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 1);
-		if ((machine_is_compatible("PowerBook3,1") ||
-		    machine_is_compatible("PowerBook3,2")) && awacs) {
-			msleep(100);
-			awacs_reg[1] &= ~(MASK_PAROUT0 | MASK_PAROUT1);
-			awacs_write(MASK_ADDR1 | awacs_reg[1]);
-			msleep(300);
-		} else
-			msleep(1000);
- 		/* restore settings */
-		switch (awacs_revision) {
-			case AWACS_TUMBLER:
-			case AWACS_SNAPPER:
-				write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
-				write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
-				write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
-				msleep(100);
-				write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
-				msleep(150);
-				tas_leave_sleep(); /* Stub for now */
-				headphone_intr(0, NULL);
-				break;
-			case AWACS_DACA:
-				msleep(10); /* Check this !!! */
-				daca_leave_sleep();
-				break ;		/* dont know how yet */
-			case AWACS_BURGUNDY:
-				break ;
-			case AWACS_SCREAMER:
-			case AWACS_AWACS:
-			default:
-		 		load_awacs() ;
-				break ;
-		}
-		/* Recalibrate chip */
-		if (awacs_revision == AWACS_SCREAMER && awacs)
-			awacs_recalibrate();
-		/* Make sure dma is stopped */
-		PMacSilence();
-		if (awacs)
-			enable_irq(awacs_irq);
-		enable_irq(awacs_tx_irq);
- 		enable_irq(awacs_rx_irq);
- 		if (awacs) {
- 			/* OK, allow ints back again */
-	 		out_le32(&awacs->control, MASK_IEPC
- 			 	| (awacs_rate_index << 8) | 0x11
- 				 | (awacs_revision < AWACS_DACA ? MASK_IEE: 0));
- 		}
- 		if (macio_base && is_pbook_g3) {
-			/* FIXME: should restore the setup we had...*/
-			out_8(macio_base + 0x37, 3);
- 		} else if (is_pbook_3X00) {
-			in_8(latch_base + 0x190);
-		}
-		/* Remove mute */
-		if (awacs_revision == AWACS_SCREAMER ||
-		    awacs_revision == AWACS_AWACS) {
-			awacs_reg[1] = awacs_reg1_save;
-			awacs_write(MASK_ADDR1 | awacs_reg[1]);
-		}
- 		awacs_sleeping = 0;
-		/* Resume pending sounds. */
-		/* we don't try to restart input... */
-		spin_lock_irqsave(&dmasound.lock, flags);
-		__PMacPlay();
-		spin_unlock_irqrestore(&dmasound.lock, flags);
-		UNLOCK();
-	}
-}
-#endif /* CONFIG_PM */
-
-
-/* All the burgundy functions: */
-
-/* Waits for busy flag to clear */
-static inline void
-awacs_burgundy_busy_wait(void)
-{
-	int count = 50; /* > 2 samples at 44k1 */
-	while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
-		udelay(1) ;
-}
-
-static inline void
-awacs_burgundy_extend_wait(void)
-{
-	int count = 50 ; /* > 2 samples at 44k1 */
-	while ((!(in_le32(&awacs->codec_stat) & MASK_EXTEND)) && count--)
-		udelay(1) ;
-	count = 50;
-	while ((in_le32(&awacs->codec_stat) & MASK_EXTEND) && count--)
-		udelay(1);
-}
-
-static void
-awacs_burgundy_wcw(unsigned addr, unsigned val)
-{
-	out_le32(&awacs->codec_ctrl, addr + 0x200c00 + (val & 0xff));
-	awacs_burgundy_busy_wait();
-	out_le32(&awacs->codec_ctrl, addr + 0x200d00 +((val>>8) & 0xff));
-	awacs_burgundy_busy_wait();
-	out_le32(&awacs->codec_ctrl, addr + 0x200e00 +((val>>16) & 0xff));
-	awacs_burgundy_busy_wait();
-	out_le32(&awacs->codec_ctrl, addr + 0x200f00 +((val>>24) & 0xff));
-	awacs_burgundy_busy_wait();
-}
-
-static unsigned
-awacs_burgundy_rcw(unsigned addr)
-{
-	unsigned val = 0;
-	unsigned long flags;
-
-	/* should have timeouts here */
-	spin_lock_irqsave(&dmasound.lock, flags);
-
-	out_le32(&awacs->codec_ctrl, addr + 0x100000);
-	awacs_burgundy_busy_wait();
-	awacs_burgundy_extend_wait();
-	val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;
-
-	out_le32(&awacs->codec_ctrl, addr + 0x100100);
-	awacs_burgundy_busy_wait();
-	awacs_burgundy_extend_wait();
-	val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<8;
-
-	out_le32(&awacs->codec_ctrl, addr + 0x100200);
-	awacs_burgundy_busy_wait();
-	awacs_burgundy_extend_wait();
-	val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<16;
-
-	out_le32(&awacs->codec_ctrl, addr + 0x100300);
-	awacs_burgundy_busy_wait();
-	awacs_burgundy_extend_wait();
-	val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<24;
-
-	spin_unlock_irqrestore(&dmasound.lock, flags);
-
-	return val;
-}
-
-
-static void
-awacs_burgundy_wcb(unsigned addr, unsigned val)
-{
-	out_le32(&awacs->codec_ctrl, addr + 0x300000 + (val & 0xff));
-	awacs_burgundy_busy_wait();
-}
-
-static unsigned
-awacs_burgundy_rcb(unsigned addr)
-{
-	unsigned val = 0;
-	unsigned long flags;
-
-	/* should have timeouts here */
-	spin_lock_irqsave(&dmasound.lock, flags);
-
-	out_le32(&awacs->codec_ctrl, addr + 0x100000);
-	awacs_burgundy_busy_wait();
-	awacs_burgundy_extend_wait();
-	val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;
-
-	spin_unlock_irqrestore(&dmasound.lock, flags);
-
-	return val;
-}
-
-static int
-awacs_burgundy_check(void)
-{
-	/* Checks to see the chip is alive and kicking */
-	int error = in_le32(&awacs->codec_ctrl) & MASK_ERRCODE;
-
-	return error == 0xf0000;
-}
-
-static int
-awacs_burgundy_init(void)
-{
-	if (awacs_burgundy_check()) {
-		printk(KERN_WARNING "dmasound_pmac: burgundy not working :-(\n");
-		return 1;
-	}
-
-	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_OUTPUTENABLES,
-			   DEF_BURGUNDY_OUTPUTENABLES);
-	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
-			   DEF_BURGUNDY_MORE_OUTPUTENABLES);
-	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_OUTPUTSELECTS,
-			   DEF_BURGUNDY_OUTPUTSELECTS);
-
-	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL21,
-			   DEF_BURGUNDY_INPSEL21);
-	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL3,
-			   DEF_BURGUNDY_INPSEL3);
-	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINCD,
-			   DEF_BURGUNDY_GAINCD);
-	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINLINE,
-			   DEF_BURGUNDY_GAINLINE);
-	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMIC,
-			   DEF_BURGUNDY_GAINMIC);
-	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMODEM,
-			   DEF_BURGUNDY_GAINMODEM);
-
-	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER,
-			   DEF_BURGUNDY_ATTENSPEAKER);
-	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENLINEOUT,
-			   DEF_BURGUNDY_ATTENLINEOUT);
-	awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENHP,
-			   DEF_BURGUNDY_ATTENHP);
-
-	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_MASTER_VOLUME,
-			   DEF_BURGUNDY_MASTER_VOLUME);
-	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLCD,
-			   DEF_BURGUNDY_VOLCD);
-	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLLINE,
-			   DEF_BURGUNDY_VOLLINE);
-	awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLMIC,
-			   DEF_BURGUNDY_VOLMIC);
-	return 0;
-}
-
-static void
-awacs_burgundy_write_volume(unsigned address, int volume)
-{
-	int hardvolume,lvolume,rvolume;
-
-	lvolume = (volume & 0xff) ? (volume & 0xff) + 155 : 0;
-	rvolume = ((volume >>8)&0xff) ? ((volume >> 8)&0xff ) + 155 : 0;
-
-	hardvolume = lvolume + (rvolume << 16);
-
-	awacs_burgundy_wcw(address, hardvolume);
-}
-
-static int
-awacs_burgundy_read_volume(unsigned address)
-{
-	int softvolume,wvolume;
-
-	wvolume = awacs_burgundy_rcw(address);
-
-	softvolume = (wvolume & 0xff) - 155;
-	softvolume += (((wvolume >> 16) & 0xff) - 155)<<8;
-
-	return softvolume > 0 ? softvolume : 0;
-}
-
-static int
-awacs_burgundy_read_mvolume(unsigned address)
-{
-	int lvolume,rvolume,wvolume;
-
-	wvolume = awacs_burgundy_rcw(address);
-
-	wvolume &= 0xffff;
-
-	rvolume = (wvolume & 0xff) - 155;
-	lvolume = ((wvolume & 0xff00)>>8) - 155;
-
-	return lvolume + (rvolume << 8);
-}
-
-static void
-awacs_burgundy_write_mvolume(unsigned address, int volume)
-{
-	int lvolume,rvolume,hardvolume;
-
-	lvolume = (volume &0xff) ? (volume & 0xff) + 155 :0;
-	rvolume = ((volume >>8) & 0xff) ? (volume >> 8) + 155 :0;
-
-	hardvolume = lvolume + (rvolume << 8);
-	hardvolume += (hardvolume << 16);
-
-	awacs_burgundy_wcw(address, hardvolume);
-}
-
-/* End burgundy functions */
-
-/* Set up output volumes on machines with the 'perch/whisper' extension card.
- * this has an SGS i2c chip (7433) which is accessed using the cuda.
- *
- * TODO: split this out and make use of the other parts of the SGS chip to
- * do Bass, Treble etc.
- */
-
-static void
-awacs_enable_amp(int spkr_vol)
-{
-#ifdef CONFIG_ADB_CUDA
-	struct adb_request req;
-
-	if (sys_ctrler != SYS_CTRLER_CUDA)
-		return;
-
-	/* turn on headphones */
-	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
-		     0x8a, 4, 0);
-	while (!req.complete) cuda_poll();
-	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
-		     0x8a, 6, 0);
-	while (!req.complete) cuda_poll();
-
-	/* turn on speaker */
-	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
-		     0x8a, 3, (100 - (spkr_vol & 0xff)) * 32 / 100);
-	while (!req.complete) cuda_poll();
-	cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
-		     0x8a, 5, (100 - ((spkr_vol >> 8) & 0xff)) * 32 / 100);
-	while (!req.complete) cuda_poll();
-
-	cuda_request(&req, NULL, 5, CUDA_PACKET,
-		     CUDA_GET_SET_IIC, 0x8a, 1, 0x29);
-	while (!req.complete) cuda_poll();
-#endif /* CONFIG_ADB_CUDA */
-}
-
-
-/*** Mid level stuff *********************************************************/
-
-
-/*
- * /dev/mixer abstraction
- */
-
-static void do_line_lev(int data)
-{
-		line_lev = data ;
-		awacs_reg[0] &= ~MASK_MUX_AUDIN;
-		if ((data & 0xff) >= 50)
-			awacs_reg[0] |= MASK_MUX_AUDIN;
-		awacs_write(MASK_ADDR0 | awacs_reg[0]);
-}
-
-static void do_ip_gain(int data)
-{
-	ip_gain = data ;
-	data &= 0xff;
-	awacs_reg[0] &= ~MASK_GAINLINE;
-	if (awacs_revision == AWACS_SCREAMER) {
-		awacs_reg[6] &= ~MASK_MIC_BOOST ;
-		if (data >= 33) {
-			awacs_reg[0] |= MASK_GAINLINE;
-			if( data >= 66)
-				awacs_reg[6] |= MASK_MIC_BOOST ;
-		}
-		awacs_write(MASK_ADDR6 | awacs_reg[6]) ;
-	} else {
-		if (data >= 50)
-			awacs_reg[0] |= MASK_GAINLINE;
-	}
-	awacs_write(MASK_ADDR0 | awacs_reg[0]);
-}
-
-static void do_mic_lev(int data)
-{
-	mic_lev = data ;
-	data &= 0xff;
-	awacs_reg[0] &= ~MASK_MUX_MIC;
-	if (data >= 50)
-		awacs_reg[0] |= MASK_MUX_MIC;
-	awacs_write(MASK_ADDR0 | awacs_reg[0]);
-}
-
-static void do_cd_lev(int data)
-{
-	cd_lev = data ;
-	awacs_reg[0] &= ~MASK_MUX_CD;
-	if ((data & 0xff) >= 50)
-		awacs_reg[0] |= MASK_MUX_CD;
-	awacs_write(MASK_ADDR0 | awacs_reg[0]);
-}
-
-static void do_rec_lev(int data)
-{
-	int left, right ;
-	rec_lev = data ;
-	/* need to fudge this to use the volume setter routine */
-	left = 100 - (data & 0xff) ; if( left < 0 ) left = 0 ;
-	right = 100 - ((data >> 8) & 0xff) ; if( right < 0 ) right = 0 ;
-	left |= (right << 8 );
-	left = awacs_volume_setter(left, 0, 0, 4);
-}
-
-static void do_passthru_vol(int data)
-{
-	passthru_vol = data ;
-	awacs_reg[1] &= ~MASK_LOOPTHRU;
-	if (awacs_revision == AWACS_SCREAMER) {
-		if( data ) { /* switch it on for non-zero */
-			awacs_reg[1] |= MASK_LOOPTHRU;
-			awacs_write(MASK_ADDR1 | awacs_reg[1]);
-		}
-		data = awacs_volume_setter(data, 5, 0, 6) ;
-	} else {
-		if ((data & 0xff) >= 50)
-			awacs_reg[1] |= MASK_LOOPTHRU;
-		awacs_write(MASK_ADDR1 | awacs_reg[1]);
-		data = (awacs_reg[1] & MASK_LOOPTHRU)? 100: 0;
-	}
-}
-
-static int awacs_mixer_ioctl(u_int cmd, u_long arg)
-{
-	int data;
-	int rc;
-
-	switch (cmd) {
-	case SOUND_MIXER_READ_CAPS:
-		/* say we will allow multiple inputs?  prob. wrong
-			so I'm switching it to single */
-		return IOCTL_OUT(arg, 1);
-	case SOUND_MIXER_READ_DEVMASK:
-		data  = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
-			| SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD
-			| SOUND_MASK_IGAIN | SOUND_MASK_RECLEV
-			| SOUND_MASK_ALTPCM
-			| SOUND_MASK_MONITOR;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_RECMASK:
-		data = SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_RECSRC:
-		data = 0;
-		if (awacs_reg[0] & MASK_MUX_AUDIN)
-			data |= SOUND_MASK_LINE;
-		if (awacs_reg[0] & MASK_MUX_MIC)
-			data |= SOUND_MASK_MIC;
-		if (awacs_reg[0] & MASK_MUX_CD)
-			data |= SOUND_MASK_CD;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_WRITE_RECSRC:
-		IOCTL_IN(arg, data);
-		data &= (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD);
-		awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC
-				  | MASK_MUX_AUDIN);
-		if (data & SOUND_MASK_LINE)
-			awacs_reg[0] |= MASK_MUX_AUDIN;
-		if (data & SOUND_MASK_MIC)
-			awacs_reg[0] |= MASK_MUX_MIC;
-		if (data & SOUND_MASK_CD)
-			awacs_reg[0] |= MASK_MUX_CD;
-		awacs_write(awacs_reg[0] | MASK_ADDR0);
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_STEREODEVS:
-		data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER| SOUND_MASK_RECLEV  ;
-		if (awacs_revision == AWACS_SCREAMER)
-			data |= SOUND_MASK_MONITOR ;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_WRITE_VOLUME:
-		IOCTL_IN(arg, data);
-		line_vol = data ;
-		awacs_volume_setter(data, 2, 0, 6);
-		/* fall through */
-	case SOUND_MIXER_READ_VOLUME:
-		rc = IOCTL_OUT(arg, line_vol);
-		break;
-	case SOUND_MIXER_WRITE_SPEAKER:
-		IOCTL_IN(arg, data);
-		spk_vol = data ;
-		if (has_perch)
-			awacs_enable_amp(data);
-		else
-			(void)awacs_volume_setter(data, 4, MASK_CMUTE, 6);
-		/* fall though */
-	case SOUND_MIXER_READ_SPEAKER:
-		rc = IOCTL_OUT(arg, spk_vol);
-		break;
-	case SOUND_MIXER_WRITE_ALTPCM:	/* really bell volume */
-		IOCTL_IN(arg, data);
-		beep_vol = data & 0xff;
-		/* fall through */
-	case SOUND_MIXER_READ_ALTPCM:
-		rc = IOCTL_OUT(arg, beep_vol);
-		break;
-	case SOUND_MIXER_WRITE_LINE:
-		IOCTL_IN(arg, data);
-		do_line_lev(data) ;
-		/* fall through */
-	case SOUND_MIXER_READ_LINE:
-		rc = IOCTL_OUT(arg, line_lev);
-		break;
-	case SOUND_MIXER_WRITE_IGAIN:
-		IOCTL_IN(arg, data);
-		do_ip_gain(data) ;
-		/* fall through */
-	case SOUND_MIXER_READ_IGAIN:
-		rc = IOCTL_OUT(arg, ip_gain);
-		break;
-	case SOUND_MIXER_WRITE_MIC:
-		IOCTL_IN(arg, data);
-		do_mic_lev(data);
-		/* fall through */
-	case SOUND_MIXER_READ_MIC:
-		rc = IOCTL_OUT(arg, mic_lev);
-		break;
-	case SOUND_MIXER_WRITE_CD:
-		IOCTL_IN(arg, data);
-		do_cd_lev(data);
-		/* fall through */
-	case SOUND_MIXER_READ_CD:
-		rc = IOCTL_OUT(arg, cd_lev);
-		break;
-	case SOUND_MIXER_WRITE_RECLEV:
-		IOCTL_IN(arg, data);
-		do_rec_lev(data) ;
-		/* fall through */
-	case SOUND_MIXER_READ_RECLEV:
-		rc = IOCTL_OUT(arg, rec_lev);
-		break;
-	case MIXER_WRITE(SOUND_MIXER_MONITOR):
-		IOCTL_IN(arg, data);
-		do_passthru_vol(data) ;
-		/* fall through */
-	case MIXER_READ(SOUND_MIXER_MONITOR):
-		rc = IOCTL_OUT(arg, passthru_vol);
-		break;
-	default:
-		rc = -EINVAL;
-	}
-	
-	return rc;
-}
-
-static void awacs_mixer_init(void)
-{
-	awacs_volume_setter(line_vol, 2, 0, 6);
-	if (has_perch)
-		awacs_enable_amp(spk_vol);
-	else
-		(void)awacs_volume_setter(spk_vol, 4, MASK_CMUTE, 6);
-	do_line_lev(line_lev) ;
-	do_ip_gain(ip_gain) ;
-	do_mic_lev(mic_lev) ;
-	do_cd_lev(cd_lev) ;
-	do_rec_lev(rec_lev) ;
-	do_passthru_vol(passthru_vol) ;
-}
-
-static int burgundy_mixer_ioctl(u_int cmd, u_long arg)
-{
-	int data;
-	int rc;
-
-	/* We are, we are, we are... Burgundy or better */
-	switch(cmd) {
-	case SOUND_MIXER_READ_DEVMASK:
-		data = SOUND_MASK_VOLUME | SOUND_MASK_CD |
-			SOUND_MASK_LINE | SOUND_MASK_MIC |
-			SOUND_MASK_SPEAKER | SOUND_MASK_ALTPCM;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_RECMASK:
-		data = SOUND_MASK_LINE | SOUND_MASK_MIC
-			| SOUND_MASK_CD;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_RECSRC:
-		data = 0;
-		if (awacs_reg[0] & MASK_MUX_AUDIN)
-			data |= SOUND_MASK_LINE;
-		if (awacs_reg[0] & MASK_MUX_MIC)
-			data |= SOUND_MASK_MIC;
-		if (awacs_reg[0] & MASK_MUX_CD)
-			data |= SOUND_MASK_CD;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_WRITE_RECSRC:
-		IOCTL_IN(arg, data);
-		data &= (SOUND_MASK_LINE
-			 | SOUND_MASK_MIC | SOUND_MASK_CD);
-		awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC
-				  | MASK_MUX_AUDIN);
-		if (data & SOUND_MASK_LINE)
-			awacs_reg[0] |= MASK_MUX_AUDIN;
-		if (data & SOUND_MASK_MIC)
-			awacs_reg[0] |= MASK_MUX_MIC;
-		if (data & SOUND_MASK_CD)
-			awacs_reg[0] |= MASK_MUX_CD;
-		awacs_write(awacs_reg[0] | MASK_ADDR0);
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_STEREODEVS:
-		data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
-			| SOUND_MASK_RECLEV | SOUND_MASK_CD
-			| SOUND_MASK_LINE;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_CAPS:
-		rc = IOCTL_OUT(arg, 0);
-		break;
-	case SOUND_MIXER_WRITE_VOLUME:
-		IOCTL_IN(arg, data);
-		awacs_burgundy_write_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME, data);
-				/* Fall through */
-	case SOUND_MIXER_READ_VOLUME:
-		rc = IOCTL_OUT(arg, awacs_burgundy_read_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME));
-		break;
-	case SOUND_MIXER_WRITE_SPEAKER:
-		IOCTL_IN(arg, data);
-		if (!(data & 0xff)) {
-			/* Mute the left speaker */
-			awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
-					   awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x2);
-		} else {
-			/* Unmute the left speaker */
-			awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
-					   awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x2);
-		}
-		if (!(data & 0xff00)) {
-			/* Mute the right speaker */
-			awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
-					   awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x4);
-		} else {
-			/* Unmute the right speaker */
-			awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
-					   awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x4);
-		}
-
-		data = (((data&0xff)*16)/100 > 0xf ? 0xf :
-			(((data&0xff)*16)/100)) +
-			((((data>>8)*16)/100 > 0xf ? 0xf :
-			  ((((data>>8)*16)/100)))<<4);
-
-		awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER, ~data);
-				/* Fall through */
-	case SOUND_MIXER_READ_SPEAKER:
-		data = awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER);
-		data = (((data & 0xf)*100)/16) + ((((data>>4)*100)/16)<<8);
-		rc = IOCTL_OUT(arg, (~data) & 0x0000ffff);
-		break;
-	case SOUND_MIXER_WRITE_ALTPCM:	/* really bell volume */
-		IOCTL_IN(arg, data);
-		beep_vol = data & 0xff;
-				/* fall through */
-	case SOUND_MIXER_READ_ALTPCM:
-		rc = IOCTL_OUT(arg, beep_vol);
-		break;
-	case SOUND_MIXER_WRITE_LINE:
-		IOCTL_IN(arg, data);
-		awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLLINE, data);
-
-				/* fall through */
-	case SOUND_MIXER_READ_LINE:
-		data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLLINE);
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_WRITE_MIC:
-		IOCTL_IN(arg, data);
-				/* Mic is mono device */
-		data = (data << 8) + (data << 24);
-		awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLMIC, data);
-				/* fall through */
-	case SOUND_MIXER_READ_MIC:
-		data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLMIC);
-		data <<= 24;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_WRITE_CD:
-		IOCTL_IN(arg, data);
-		awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLCD, data);
-				/* fall through */
-	case SOUND_MIXER_READ_CD:
-		data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLCD);
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_WRITE_RECLEV:
-		IOCTL_IN(arg, data);
-		data = awacs_volume_setter(data, 0, 0, 4);
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_RECLEV:
-		data = awacs_get_volume(awacs_reg[0], 4);
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_OUTMASK:
-	case SOUND_MIXER_OUTSRC:
-	default:
-		rc = -EINVAL;
-	}
-	
-	return rc;
-}
-
-static int daca_mixer_ioctl(u_int cmd, u_long arg)
-{
-	int data;
-	int rc;
-
-	/* And the DACA's no genius either! */
-
-	switch(cmd) {
-	case SOUND_MIXER_READ_DEVMASK:
-		data = SOUND_MASK_VOLUME;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_RECMASK:
-		data = 0;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_RECSRC:
-		data = 0;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_WRITE_RECSRC:
-		IOCTL_IN(arg, data);
-		data =0;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_STEREODEVS:
-		data = SOUND_MASK_VOLUME;
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_READ_CAPS:
-		rc = IOCTL_OUT(arg, 0);
-		break;
-	case SOUND_MIXER_WRITE_VOLUME:
-		IOCTL_IN(arg, data);
-		daca_set_volume(data, data);
-		/* Fall through */
-	case SOUND_MIXER_READ_VOLUME:
-		daca_get_volume(& data, &data);
-		rc = IOCTL_OUT(arg, data);
-		break;
-	case SOUND_MIXER_OUTMASK:
-	case SOUND_MIXER_OUTSRC:
-	default:
-		rc = -EINVAL;
-	}
-	return rc;
-}
-
-static int PMacMixerIoctl(u_int cmd, u_long arg)
-{
-	int rc;
-	
-	/* Different IOCTLS for burgundy and, eventually, DACA & Tumbler */
-
-	TRY_LOCK();
-	
-	switch (awacs_revision){
-		case AWACS_BURGUNDY:
-			rc = burgundy_mixer_ioctl(cmd, arg);
-			break ;
-		case AWACS_DACA:
-			rc = daca_mixer_ioctl(cmd, arg);
-			break;
-		case AWACS_TUMBLER:
-		case AWACS_SNAPPER:
-			rc = tas_mixer_ioctl(cmd, arg);
-			break ;
-		default: /* ;-)) */
-			rc = awacs_mixer_ioctl(cmd, arg);
-	}
-
-	UNLOCK();
-	
-	return rc;
-}
-
-static void PMacMixerInit(void)
-{
-	switch (awacs_revision) {
-		case AWACS_TUMBLER:
-		  printk("AE-Init tumbler mixer\n");
-		  break ;
-		case AWACS_SNAPPER:
-		  printk("AE-Init snapper mixer\n");
-		  break ;
-		case AWACS_DACA:
-		case AWACS_BURGUNDY:
-			break ;	/* don't know yet */
-		case AWACS_AWACS:
-		case AWACS_SCREAMER:
-		default:
-			awacs_mixer_init() ;
-			break ;
-	}
-}
-
-/* Write/Read sq setup functions:
-   Check to see if we have enough (or any) dbdma cmd buffers for the
-   user's fragment settings.  If not, allocate some. If this fails we will
-   point at the beep buffer - as an emergency provision - to stop dma tromping
-   on some random bit of memory (if someone lets it go anyway).
-   The command buffers are then set up to point to the fragment buffers
-   (allocated elsewhere).  We need n+1 commands the last of which holds
-   a NOP + loop to start.
-*/
-
-static int PMacWriteSqSetup(void)
-{
-	int i, count = 600 ;
-	volatile struct dbdma_cmd *cp;
-
-	LOCK();
-	
-	/* stop the controller from doing any output - if it isn't already.
-	   it _should_ be before this is called anyway */
-
-	out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
-	while ((in_le32(&awacs_txdma->status) & RUN) && count--)
-		udelay(1);
-#ifdef DEBUG_DMASOUND
-if (count <= 0)
-	printk("dmasound_pmac: write sq setup: timeout waiting for dma to stop\n");
-#endif
-
-	if ((write_sq.max_count + 1) > number_of_tx_cmd_buffers) {
-		kfree(awacs_tx_cmd_space);
-		number_of_tx_cmd_buffers = 0;
-
-		/* we need nbufs + 1 (for the loop) and we should request + 1
-		   again because the DBDMA_ALIGN might pull the start up by up
-		   to sizeof(struct dbdma_cmd) - 4.
-		*/
-
-		awacs_tx_cmd_space = kmalloc
-			((write_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd),
-			 GFP_KERNEL);
-		if (awacs_tx_cmd_space == NULL) {
-			/* don't leave it dangling - nasty but better than a
-			   random address */
-			out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
-			printk(KERN_ERR
-			   "dmasound_pmac: can't allocate dbdma cmd buffers"
-			   ", driver disabled\n");
-			UNLOCK();
-			return -ENOMEM;
-		}
-		awacs_tx_cmds = (volatile struct dbdma_cmd *)
-			DBDMA_ALIGN(awacs_tx_cmd_space);
-		number_of_tx_cmd_buffers = write_sq.max_count + 1;
-	}
-
-	cp = awacs_tx_cmds;
-	memset((void *)cp, 0, (write_sq.max_count+1) * sizeof(struct dbdma_cmd));
-	for (i = 0; i < write_sq.max_count; ++i, ++cp) {
-		st_le32(&cp->phy_addr, virt_to_bus(write_sq.buffers[i]));
-	}
-	st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS);
-	st_le32(&cp->cmd_dep, virt_to_bus(awacs_tx_cmds));
-	/* point the controller at the command stack - ready to go */
-	out_le32(&awacs_txdma->cmdptr, virt_to_bus(awacs_tx_cmds));
-	UNLOCK();
-	return 0;
-}
-
-static int PMacReadSqSetup(void)
-{
-	int i, count = 600;
-	volatile struct dbdma_cmd *cp;
-
-	LOCK();
-	
-	/* stop the controller from doing any input - if it isn't already.
-	   it _should_ be before this is called anyway */
-	
-	out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
-	while ((in_le32(&awacs_rxdma->status) & RUN) && count--)
-		udelay(1);
-#ifdef DEBUG_DMASOUND
-if (count <= 0)
-	printk("dmasound_pmac: read sq setup: timeout waiting for dma to stop\n");
-#endif
-
-	if ((read_sq.max_count+1) > number_of_rx_cmd_buffers ) {
-		kfree(awacs_rx_cmd_space);
-		number_of_rx_cmd_buffers = 0;
-
-		/* we need nbufs + 1 (for the loop) and we should request + 1 again
-		   because the DBDMA_ALIGN might pull the start up by up to
-		   sizeof(struct dbdma_cmd) - 4 (assuming kmalloc aligns 32 bits).
-		*/
-
-		awacs_rx_cmd_space = kmalloc
-			((read_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd),
-			 GFP_KERNEL);
-		if (awacs_rx_cmd_space == NULL) {
-			/* don't leave it dangling - nasty but better than a
-			   random address */
-			out_le32(&awacs_rxdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
-			printk(KERN_ERR
-			   "dmasound_pmac: can't allocate dbdma cmd buffers"
-			   ", driver disabled\n");
-			UNLOCK();
-			return -ENOMEM;
-		}
-		awacs_rx_cmds = (volatile struct dbdma_cmd *)
-			DBDMA_ALIGN(awacs_rx_cmd_space);
-		number_of_rx_cmd_buffers = read_sq.max_count + 1 ;
-	}
-	cp = awacs_rx_cmds;
-	memset((void *)cp, 0, (read_sq.max_count+1) * sizeof(struct dbdma_cmd));
-
-	/* Set dma buffers up in a loop */
-	for (i = 0; i < read_sq.max_count; i++,cp++) {
-		st_le32(&cp->phy_addr, virt_to_bus(read_sq.buffers[i]));
-		st_le16(&cp->command, INPUT_MORE + INTR_ALWAYS);
-		st_le16(&cp->req_count, read_sq.block_size);
-		st_le16(&cp->xfer_status, 0);
-	}
-
-	/* The next two lines make the thing loop around.
-	*/
-	st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS);
-	st_le32(&cp->cmd_dep, virt_to_bus(awacs_rx_cmds));
-	/* point the controller at the command stack - ready to go */
-	out_le32(&awacs_rxdma->cmdptr, virt_to_bus(awacs_rx_cmds));
-
-	UNLOCK();
-	return 0;
-}
-
-/* TODO: this needs work to guarantee that when it returns DMA has stopped
-   but in a more elegant way than is done here....
-*/
-
-static void PMacAbortRead(void)
-{
-	int i;
-	volatile struct dbdma_cmd *cp;
-
-	LOCK();
-	/* give it a chance to update the output and provide the IRQ
-	   that is expected.
-	*/
-
-	out_le32(&awacs_rxdma->control, ((FLUSH) << 16) + FLUSH );
-
-	cp = awacs_rx_cmds;
-	for (i = 0; i < read_sq.max_count; i++,cp++)
-		st_le16(&cp->command, DBDMA_STOP);
-	/*
-	 * We should probably wait for the thing to stop before we
-	 * release the memory.
-	 */
-
-	msleep(100) ; /* give it a (small) chance to act */
-
-	/* apply the sledgehammer approach - just stop it now */
-
-	out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
-	UNLOCK();
-}
-
-extern char *get_afmt_string(int);
-static int PMacStateInfo(char *b, size_t sp)
-{
-	int i, len = 0;
-	len = sprintf(b,"HW rates: ");
-	switch (awacs_revision){
-		case AWACS_DACA:
-		case AWACS_BURGUNDY:
-			len += sprintf(b,"44100 ") ;
-			break ;
-		case AWACS_TUMBLER:
-		case AWACS_SNAPPER:
-			for (i=0; i<1; i++){
-				if (tas_freqs_ok[i])
-					len += sprintf(b+len,"%d ", tas_freqs[i]) ;
-			}
-			break ;
-		case AWACS_AWACS:
-		case AWACS_SCREAMER:
-		default:
-			for (i=0; i<8; i++){
-				if (awacs_freqs_ok[i])
-					len += sprintf(b+len,"%d ", awacs_freqs[i]) ;
-			}
-			break ;
-	}
-	len += sprintf(b+len,"s/sec\n") ;
-	if (len < sp) {
-		len += sprintf(b+len,"HW AFMTS: ");
-		i = AFMT_U16_BE ;
-		while (i) {
-			if (i & dmasound.mach.hardware_afmts)
-				len += sprintf(b+len,"%s ",
-					get_afmt_string(i & dmasound.mach.hardware_afmts));
-			i >>= 1 ;
-		}
-		len += sprintf(b+len,"\n") ;
-	}
-	return len ;
-}
-
-/*** Machine definitions *****************************************************/
-
-static SETTINGS def_hard = {
-	.format	= AFMT_S16_BE,
-	.stereo	= 1,
-	.size	= 16,
-	.speed	= 44100
-} ;
-
-static SETTINGS def_soft = {
-	.format	= AFMT_S16_BE,
-	.stereo	= 1,
-	.size	= 16,
-	.speed	= 44100
-} ;
-
-static MACHINE machPMac = {
-	.name		= awacs_name,
-	.name2		= "PowerMac Built-in Sound",
-	.owner		= THIS_MODULE,
-	.dma_alloc	= PMacAlloc,
-	.dma_free	= PMacFree,
-	.irqinit	= PMacIrqInit,
-#ifdef MODULE
-	.irqcleanup	= PMacIrqCleanup,
-#endif /* MODULE */
-	.init		= PMacInit,
-	.silence	= PMacSilence,
-	.setFormat	= PMacSetFormat,
-	.setVolume	= PMacSetVolume,
-	.play		= PMacPlay,
-	.record		= NULL,		/* default to no record */
-	.mixer_init	= PMacMixerInit,
-	.mixer_ioctl	= PMacMixerIoctl,
-	.write_sq_setup	= PMacWriteSqSetup,
-	.read_sq_setup	= PMacReadSqSetup,
-	.state_info	= PMacStateInfo,
-	.abort_read	= PMacAbortRead,
-	.min_dsp_speed	= 7350,
-	.max_dsp_speed	= 44100,
-	.version	= ((DMASOUND_AWACS_REVISION<<8) + DMASOUND_AWACS_EDITION)
-};
-
-
-/*** Config & Setup **********************************************************/
-
-/* Check for pmac models that we care about in terms of special actions.
-*/
-
-void __init
-set_model(void)
-{
-	/* portables/lap-tops */
-
-	if (machine_is_compatible("AAPL,3400/2400") ||
-	    machine_is_compatible("AAPL,3500"))	{
-		is_pbook_3X00 = 1 ;
-	}
-	if (machine_is_compatible("PowerBook1,1")  || /* lombard */
-	    machine_is_compatible("AAPL,PowerBook1998")){ /* wallstreet */
-		is_pbook_g3 = 1 ;
-		return ;
-	}
-}
-
-/* Get the OF node that tells us about the registers, interrupts etc. to use
-   for sound IO.
-
-   On most machines the sound IO OF node is the 'davbus' node.  On newer pmacs
-   with DACA (& Tumbler) the node to use is i2s-a.  On much older machines i.e.
-   before 9500 there is no davbus node and we have to use the 'awacs' property.
-
-  In the latter case we signal this by setting the codec value - so that the
-  code that looks for chip properties knows how to go about it.
-*/
-
-static struct device_node* __init
-get_snd_io_node(void)
-{
-	struct device_node *np;
-
-	/* set up awacs_node for early OF which doesn't have a full set of
-	 * properties on davbus
-	 */
-	awacs_node = of_find_node_by_name(NULL, "awacs");
-	if (awacs_node)
-		awacs_revision = AWACS_AWACS;
-
-	/* powermac models after 9500 (other than those which use DACA or
-	 * Tumbler) have a node called "davbus".
-	 */
-	np = of_find_node_by_name(NULL, "davbus");
-	/*
-	 * if we didn't find a davbus device, try 'i2s-a' since
-	 * this seems to be what iBooks (& Tumbler) have.
-	 */
-	if (np == NULL) {
-		i2s_node = of_find_node_by_name(NULL, "i2s-a");
-		np = of_node_get(i2s_node);
-	}
-
-	/* if we didn't find this - perhaps we are on an early model
-	 * which _only_ has an 'awacs' node
-	*/
-	if (np == NULL && awacs_node)
-		np = of_node_get(awacs_node);
-
-	/* if we failed all these return null - this will cause the
-	 * driver to give up...
-	*/
-	return np ;
-}
-
-/* Get the OF node that contains the info about the sound chip, inputs s-rates
-   etc.
-   This node does not exist (or contains much reduced info) on earlier machines
-   we have to deduce the info other ways for these.
-*/
-
-static struct device_node* __init
-get_snd_info_node(struct device_node *io)
-{
-	struct device_node *info;
-
-	for_each_node_by_name(info, "sound")
-		if (info->parent == io)
-			break;
-	return info;
-}
-
-/* Find out what type of codec we have.
-*/
-
-static int __init
-get_codec_type(struct device_node *info)
-{
-	/* already set if pre-davbus model and info will be NULL */
-	int codec = awacs_revision ;
-
-	if (info) {
-		/* must do awacs first to allow screamer to overide it */
-		if (of_device_is_compatible(info, "awacs"))
-			codec = AWACS_AWACS ;
-		if (of_device_is_compatible(info, "screamer"))
-			codec = AWACS_SCREAMER;
-		if (of_device_is_compatible(info, "burgundy"))
-			codec = AWACS_BURGUNDY ;
-		if (of_device_is_compatible(info, "daca"))
-			codec = AWACS_DACA;
-		if (of_device_is_compatible(info, "tumbler"))
-			codec = AWACS_TUMBLER;
-		if (of_device_is_compatible(info, "snapper"))
-			codec = AWACS_SNAPPER;
-	}
-	return codec ;
-}
-
-/* find out what type, if any, of expansion card we have
-*/
-static void __init
-get_expansion_type(void)
-{
-	struct device_node *dn;
-
-	dn = of_find_node_by_name(NULL, "perch");
-	if (dn != NULL)
-		has_perch = 1;
-	of_node_put(dn);
-
-	dn = of_find_node_by_name(NULL, "pb-ziva-pc");
-	if (dn != NULL)
-		has_ziva = 1;
-	of_node_put(dn);
-	/* need to work out how we deal with iMac SRS module */
-}
-
-/* set up frame rates.
- * I suspect that these routines don't quite go about it the right way:
- * - where there is more than one rate - I think that the first property
- * value is the number of rates.
- * TODO: check some more device trees and modify accordingly
- *       Set dmasound.mach.max_dsp_rate on the basis of these routines.
-*/
-
-static void __init
-awacs_init_frame_rates(const unsigned int *prop, unsigned int l)
-{
-	int i ;
-	if (prop) {
-		for (i=0; i<8; i++)
-			awacs_freqs_ok[i] = 0 ;
-		for (l /= sizeof(int); l > 0; --l) {
-			unsigned int r = *prop++;
-			/* Apple 'Fixed' format */
-			if (r >= 0x10000)
-				r >>= 16;
-			for (i = 0; i < 8; ++i) {
-				if (r == awacs_freqs[i]) {
-					awacs_freqs_ok[i] = 1;
-					break;
-				}
-			}
-		}
-	}
-	/* else we assume that all the rates are available */
-}
-
-static void __init
-burgundy_init_frame_rates(const unsigned int *prop, unsigned int l)
-{
-	int temp[9] ;
-	int i = 0 ;
-	if (prop) {
-		for (l /= sizeof(int); l > 0; --l) {
-			unsigned int r = *prop++;
-			/* Apple 'Fixed' format */
-			if (r >= 0x10000)
-				r >>= 16;
-			temp[i] = r ;
-			i++ ; if(i>=9) i=8;
-		}
-	}
-#ifdef DEBUG_DMASOUND
-if (i > 1){
-	int j;
-	printk("dmasound_pmac: burgundy with multiple frame rates\n");
-	for(j=0; j<i; j++)
-		printk("%d ", temp[j]) ;
-	printk("\n") ;
-}
-#endif
-}
-
-static void __init
-daca_init_frame_rates(const unsigned int *prop, unsigned int l)
-{
-	int temp[9] ;
-	int i = 0 ;
-	if (prop) {
-		for (l /= sizeof(int); l > 0; --l) {
-			unsigned int r = *prop++;
-			/* Apple 'Fixed' format */
-			if (r >= 0x10000)
-				r >>= 16;
-			temp[i] = r ;
-			i++ ; if(i>=9) i=8;
-
-		}
-	}
-#ifdef DEBUG_DMASOUND
-if (i > 1){
-	int j;
-	printk("dmasound_pmac: DACA with multiple frame rates\n");
-	for(j=0; j<i; j++)
-		printk("%d ", temp[j]) ;
-	printk("\n") ;
-}
-#endif
-}
-
-static void __init
-init_frame_rates(const unsigned int *prop, unsigned int l)
-{
-	switch (awacs_revision) {
-		case AWACS_TUMBLER:
-		case AWACS_SNAPPER:
-			tas_init_frame_rates(prop, l);
-			break ;
-		case AWACS_DACA:
-			daca_init_frame_rates(prop, l);
-			break ;
-		case AWACS_BURGUNDY:
-			burgundy_init_frame_rates(prop, l);
-			break ;
-		default:
-			awacs_init_frame_rates(prop, l);
-			break ;
-	}
-}
-
-/* find things/machines that can't do mac-io byteswap
-*/
-
-static void __init
-set_hw_byteswap(struct device_node *io)
-{
-	struct device_node *mio ;
-	unsigned int kl = 0 ;
-
-	/* if seems that Keylargo can't byte-swap  */
-
-	for (mio = io->parent; mio ; mio = mio->parent) {
-		if (strcmp(mio->name, "mac-io") == 0) {
-			if (of_device_is_compatible(mio, "Keylargo"))
-				kl = 1;
-			break;
-		}
-	}
-	hw_can_byteswap = !kl;
-}
-
-/* Allocate the resources necessary for beep generation.  This cannot be (quite)
-   done statically (yet) because we cannot do virt_to_bus() on static vars when
-   the code is loaded as a module.
-
-   for the sake of saving the possibility that two allocations will incur the
-   overhead of two pull-ups in DBDMA_ALIGN() we allocate the 'emergency' dmdma
-   command here as well... even tho' it is not part of the beep process.
-*/
-
-int32_t
-__init setup_beep(void)
-{
-	/* Initialize beep stuff */
-	/* want one cmd buffer for beeps, and a second one for emergencies
-	   - i.e. dbdma error conditions.
-	   ask for three to allow for pull up in DBDMA_ALIGN().
-	*/
-	beep_dbdma_cmd_space =
-		kmalloc((2 + 1) * sizeof(struct dbdma_cmd), GFP_KERNEL);
-	if(beep_dbdma_cmd_space == NULL) {
-		printk(KERN_ERR "dmasound_pmac: no beep dbdma cmd space\n") ;
-		return -ENOMEM ;
-	}
-	beep_dbdma_cmd = (volatile struct dbdma_cmd *)
-			DBDMA_ALIGN(beep_dbdma_cmd_space);
-	/* set up emergency dbdma cmd */
-	emergency_dbdma_cmd = beep_dbdma_cmd+1 ;
-	beep_buf = kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
-	if (beep_buf == NULL) {
-		printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n");
-		kfree(beep_dbdma_cmd_space) ;
-		return -ENOMEM ;
-	}
-	return 0 ;
-}
-
-static struct input_dev *awacs_beep_dev;
-
-int __init dmasound_awacs_init(void)
-{
-	struct device_node *io = NULL, *info = NULL;
-	int vol, res;
-
-	if (!machine_is(powermac))
-		return -ENODEV;
-
-	awacs_subframe = 0;
-	awacs_revision = 0;
-	hw_can_byteswap = 1 ; /* most can */
-
-	/* look for models we need to handle specially */
-	set_model() ;
-
-	/* find the OF node that tells us about the dbdma stuff
-	*/
-	io = get_snd_io_node();
-	if (io == NULL) {
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: couldn't find sound io OF node\n");
-#endif
-		goto no_device;
-	}
-
-	/* find the OF node that tells us about the sound sub-system
-	 * this doesn't exist on pre-davbus machines (earlier than 9500)
-	*/
-	if (awacs_revision != AWACS_AWACS) { /* set for pre-davbus */
-		info = get_snd_info_node(io) ;
-		if (info == NULL){
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: couldn't find 'sound' OF node\n");
-#endif
-			goto no_device;
-		}
-	}
-
-	awacs_revision = get_codec_type(info) ;
-	if (awacs_revision == 0) {
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: couldn't find a Codec we can handle\n");
-#endif
-		goto no_device; /* we don't know this type of h/w */
-	}
-
-	/* set up perch, ziva, SRS or whatever else we have as sound
-	 *  expansion.
-	*/
-	get_expansion_type();
-
-	/* we've now got enough information to make up the audio topology.
-	 * we will map the sound part of mac-io now so that we can probe for
-	 * other info if necessary (early AWACS we want to read chip ids)
-	 */
-
-	if (of_get_address(io, 2, NULL, NULL) == NULL) {
-		/* OK - maybe we need to use the 'awacs' node (on earlier
-		 * machines).
-		 */
-		if (awacs_node) {
-			of_node_put(io);
-			io = of_node_get(awacs_node);
-			if (of_get_address(io, 2, NULL, NULL) == NULL) {
-				printk("dmasound_pmac: can't use %s\n",
-				       io->full_name);
-				goto no_device;
-			}
-		} else
-			printk("dmasound_pmac: can't use %s\n", io->full_name);
-	}
-
-	if (of_address_to_resource(io, 0, &awacs_rsrc[0]) ||
-	    request_mem_region(awacs_rsrc[0].start,
-			       awacs_rsrc[0].end - awacs_rsrc[0].start + 1,
-			       " (IO)") == NULL) {
-		printk(KERN_ERR "dmasound: can't request IO resource !\n");
-		goto no_device;
-	}
-	if (of_address_to_resource(io, 1, &awacs_rsrc[1]) ||
-	    request_mem_region(awacs_rsrc[1].start,
-			       awacs_rsrc[1].end - awacs_rsrc[1].start + 1,
-			       " (tx dma)") == NULL) {
-		release_mem_region(awacs_rsrc[0].start,
-				   awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
-		printk(KERN_ERR "dmasound: can't request Tx DMA resource !\n");
-		goto no_device;
-	}
-	if (of_address_to_resource(io, 2, &awacs_rsrc[2]) ||
-	    request_mem_region(awacs_rsrc[2].start,
-			       awacs_rsrc[2].end - awacs_rsrc[2].start + 1,
-			       " (rx dma)") == NULL) {
-		release_mem_region(awacs_rsrc[0].start,
-				   awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
-		release_mem_region(awacs_rsrc[1].start,
-				   awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
-		printk(KERN_ERR "dmasound: can't request Rx DMA resource !\n");
-		goto no_device;
-	}
-
-	awacs_beep_dev = input_allocate_device();
-	if (!awacs_beep_dev) {
-		release_mem_region(awacs_rsrc[0].start,
-				   awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
-		release_mem_region(awacs_rsrc[1].start,
-				   awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
-		release_mem_region(awacs_rsrc[2].start,
-				   awacs_rsrc[2].end - awacs_rsrc[2].start + 1);
-		printk(KERN_ERR "dmasound: can't allocate input device !\n");
-		goto no_device;
-	}
-
-	awacs_beep_dev->name = "dmasound beeper";
-	awacs_beep_dev->phys = "macio/input0";
-	awacs_beep_dev->id.bustype = BUS_HOST;
-	awacs_beep_dev->event = awacs_beep_event;
-	awacs_beep_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
-	awacs_beep_dev->evbit[0] = BIT(EV_SND);
-
-	/* all OF versions I've seen use this value */
-	if (i2s_node)
-		i2s = ioremap(awacs_rsrc[0].start, 0x1000);
-	else
-		awacs = ioremap(awacs_rsrc[0].start, 0x1000);
-	awacs_txdma = ioremap(awacs_rsrc[1].start, 0x100);
-	awacs_rxdma = ioremap(awacs_rsrc[2].start, 0x100);
-
-	/* first of all make sure that the chip is powered up....*/
-	pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1);
-	if (awacs_revision == AWACS_SCREAMER && awacs)
-		awacs_recalibrate();
-
-	awacs_irq = irq_of_parse_and_map(io, 0);
-	awacs_tx_irq = irq_of_parse_and_map(io, 1);
-	awacs_rx_irq = irq_of_parse_and_map(io, 2);
-
-	/* Hack for legacy crap that will be killed someday */
-	of_node_put(awacs_node);
-	awacs_node = of_node_get(io);
-
-	/* if we have an awacs or screamer - probe the chip to make
-	 * sure we have the right revision.
-	*/
-
-	if (awacs_revision <= AWACS_SCREAMER){
-		uint32_t temp, rev, mfg ;
-		/* find out the awacs revision from the chip */
-		temp = in_le32(&awacs->codec_stat);
-		rev = (temp >> 12) & 0xf;
-		mfg = (temp >>  8) & 0xf;
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev);
-#endif
-		if (rev >= AWACS_SCREAMER)
-			awacs_revision = AWACS_SCREAMER ;
-		else
-			awacs_revision = rev ;
-	}
-
-	dmasound.mach = machPMac;
-
-	/* find out other bits & pieces from OF, these may be present
-	   only on some models ... so be careful.
-	*/
-
-	/* in the absence of a frame rates property we will use the defaults
-	*/
-
-	if (info) {
-		const unsigned int *prop;
-		unsigned int l;
-
-		sound_device_id = 0;
-		/* device ID appears post g3 b&w */
-		prop = of_get_property(info, "device-id", NULL);
-		if (prop != 0)
-			sound_device_id = *prop;
-
-		/* look for a property saying what sample rates
-		   are available */
-
-		prop = of_get_property(info, "sample-rates", &l);
-		if (prop == 0)
-			prop = of_get_property(info, "output-frame-rates", &l);
-
-		/* if it's there use it to set up frame rates */
-		init_frame_rates(prop, l) ;
-		of_node_put(info);
-		info = NULL;
-	}
-
-	if (awacs)
-		out_le32(&awacs->control, 0x11); /* set everything quiesent */
-
-	set_hw_byteswap(io) ; /* figure out if the h/w can do it */
-
-#ifdef CONFIG_NVRAM
-	/* get default volume from nvram */
-	vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 );
-#else
-	vol = 0;
-#endif
-
-	/* set up tracking values */
-	spk_vol = vol * 100 ;
-	spk_vol /= 7 ; /* get set value to a percentage */
-	spk_vol |= (spk_vol << 8) ; /* equal left & right */
- 	line_vol = passthru_vol = spk_vol ;
-
-	/* fill regs that are shared between AWACS & Burgundy */
-
-	awacs_reg[2] = vol + (vol << 6);
-	awacs_reg[4] = vol + (vol << 6);
-	awacs_reg[5] = vol + (vol << 6); /* screamer has loopthru vol control */
-	awacs_reg[6] = 0; /* maybe should be vol << 3 for PCMCIA speaker */
-	awacs_reg[7] = 0;
-
-	awacs_reg[0] = MASK_MUX_CD;
-	awacs_reg[1] = MASK_LOOPTHRU;
-
-	/* FIXME: Only machines with external SRS module need MASK_PAROUT */
-	if (has_perch || sound_device_id == 0x5
-	    || /*sound_device_id == 0x8 ||*/ sound_device_id == 0xb)
-		awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
-
-	switch (awacs_revision) {
-		case AWACS_TUMBLER:
-                        tas_register_driver(&tas3001c_hooks);
-			tas_init(I2C_DRIVERID_TAS3001C, I2C_DRIVERNAME_TAS3001C);
-			tas_dmasound_init();
-			tas_post_init();
-			break ;
-		case AWACS_SNAPPER:
-                        tas_register_driver(&tas3004_hooks);
-			tas_init(I2C_DRIVERID_TAS3004,I2C_DRIVERNAME_TAS3004);
-			tas_dmasound_init();
-			tas_post_init();
-			break;
-		case AWACS_DACA:
-			daca_init();
-			break;	
-		case AWACS_BURGUNDY:
-			awacs_burgundy_init();
-			break ;
-		case AWACS_SCREAMER:
-		case AWACS_AWACS:
-		default:
-			load_awacs();
-			break ;
-	}
-
-	/* enable/set-up external modules - when we know how */
-
-	if (has_perch)
-		awacs_enable_amp(100 * 0x101);
-
-	/* Reset dbdma channels */
-	out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
-	while (in_le32(&awacs_txdma->status) & RUN)
-		udelay(1);
-	out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
-	while (in_le32(&awacs_rxdma->status) & RUN)
-		udelay(1);
-
-	/* Initialize beep stuff */
-	if ((res=setup_beep()))
-		return res ;
-
-#ifdef CONFIG_PM
-	pmu_register_sleep_notifier(&awacs_sleep_notifier);
-#endif /* CONFIG_PM */
-
-	/* Powerbooks have odd ways of enabling inputs such as
-	   an expansion-bay CD or sound from an internal modem
-	   or a PC-card modem. */
-	if (is_pbook_3X00) {
-		/*
-		 * Enable CD and PC-card sound inputs.
-		 * This is done by reading from address
-		 * f301a000, + 0x10 to enable the expansion-bay
-		 * CD sound input, + 0x80 to enable the PC-card
-		 * sound input.  The 0x100 enables the SCSI bus
-		 * terminator power.
-		 */
-		latch_base = ioremap (0xf301a000, 0x1000);
-		in_8(latch_base + 0x190);
-
-	} else if (is_pbook_g3) {
-		struct device_node* mio;
-		macio_base = NULL;
-		for (mio = io->parent; mio; mio = mio->parent) {
-			if (strcmp(mio->name, "mac-io") == 0) {
-				struct resource r;
-				if (of_address_to_resource(mio, 0, &r) == 0)
-					macio_base = ioremap(r.start, 0x40);
-				break;
-			}
-		}
-		/*
-		 * Enable CD sound input.
-		 * The relevant bits for writing to this byte are 0x8f.
-		 * I haven't found out what the 0x80 bit does.
-		 * For the 0xf bits, writing 3 or 7 enables the CD
-		 * input, any other value disables it.  Values
-		 * 1, 3, 5, 7 enable the microphone.  Values 0, 2,
-		 * 4, 6, 8 - f enable the input from the modem.
-		 *  -- paulus.
-		 */
-		if (macio_base)
-			out_8(macio_base + 0x37, 3);
-	}
-
-	if (hw_can_byteswap)
- 		dmasound.mach.hardware_afmts = (AFMT_S16_BE | AFMT_S16_LE) ;
- 	else
-		dmasound.mach.hardware_afmts = AFMT_S16_BE ;
-
-	/* shut out chips that do output only.
-	 * may need to extend this to machines which have no inputs - even tho'
-	 * they use screamer - IIRC one of the powerbooks is like this.
-	 */
-
-	if (awacs_revision != AWACS_DACA) {
-		dmasound.mach.capabilities = DSP_CAP_DUPLEX ;
-		dmasound.mach.record = PMacRecord ;
-	}
-
-	dmasound.mach.default_hard = def_hard ;
-	dmasound.mach.default_soft = def_soft ;
-
-	switch (awacs_revision) {
-		case AWACS_BURGUNDY:
-			sprintf(awacs_name, "PowerMac Burgundy ") ;
-			break ;
-		case AWACS_DACA:
-			sprintf(awacs_name, "PowerMac DACA ") ;
-			break ;
-		case AWACS_TUMBLER:
-			sprintf(awacs_name, "PowerMac Tumbler ") ;
-			break ;
-		case AWACS_SNAPPER:
-			sprintf(awacs_name, "PowerMac Snapper ") ;
-			break ;
-		case AWACS_SCREAMER:
-			sprintf(awacs_name, "PowerMac Screamer ") ;
-			break ;
-		case AWACS_AWACS:
-		default:
-			sprintf(awacs_name, "PowerMac AWACS rev %d ", awacs_revision) ;
-			break ;
-	}
-
-	/*
-	 * XXX: we should handle errors here, but that would mean
-	 * rewriting the whole init code.  later..
-	 */
-	input_register_device(awacs_beep_dev);
-
-	of_node_put(io);
-
-	return dmasound_init();
-
-no_device:
-	of_node_put(info);
-	of_node_put(awacs_node);
-	of_node_put(i2s_node);
-	of_node_put(io);
-	return -ENODEV ;
-}
-
-static void __exit dmasound_awacs_cleanup(void)
-{
-	input_unregister_device(awacs_beep_dev);
-
-	switch (awacs_revision) {
-		case AWACS_TUMBLER:
-		case AWACS_SNAPPER:
-			tas_dmasound_cleanup();
-			tas_cleanup();
-			break ;
-		case AWACS_DACA:
-			daca_cleanup();
-			break;
-	}
-	dmasound_deinit();
-
-	of_node_put(awacs_node);
-	of_node_put(i2s_node);
-}
-
-MODULE_DESCRIPTION("PowerMac built-in audio driver.");
-MODULE_LICENSE("GPL");
-
-module_init(dmasound_awacs_init);
-module_exit(dmasound_awacs_cleanup);
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index f4056a9..a003c0e 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -202,13 +202,6 @@
 static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ;	/* in bytes */
 module_param(writeBufSize, int, 0);
 
-#ifdef HAS_RECORD
-static unsigned int numReadBufs = DEFAULT_N_BUFFERS;
-module_param(numReadBufs, int, 0);
-static unsigned int readBufSize = DEFAULT_BUFF_SIZE;	/* in bytes */
-module_param(readBufSize, int, 0);
-#endif
-
 MODULE_LICENSE("GPL");
 
 #ifdef MODULE
@@ -403,10 +396,6 @@
 
 struct sound_queue dmasound_write_sq;
 static void sq_reset_output(void) ;
-#ifdef HAS_RECORD
-struct sound_queue dmasound_read_sq;
-static void sq_reset_input(void) ;
-#endif
 
 static int sq_allocate_buffers(struct sound_queue *sq, int num, int size)
 {
@@ -530,12 +519,6 @@
 	    sq->rear = -1;
 	    setup_func = dmasound.mach.write_sq_setup;
 	}
-#ifdef HAS_RECORD
-	else {
-	    sq->rear = 0;
-	    setup_func = dmasound.mach.read_sq_setup;
-	}
-#endif
 	if (setup_func)
 	    return setup_func();
 	return 0 ;
@@ -672,13 +655,6 @@
 	}
 	if (file->f_mode & FMODE_WRITE )
 		poll_wait(file, &write_sq.action_queue, wait);
-#ifdef HAS_RECORD
-	if (file->f_mode & FMODE_READ)
-		poll_wait(file, &read_sq.action_queue, wait);
-	if (file->f_mode & FMODE_READ)
-		if (read_sq.block_size - read_sq.rear_size > 0)
-			mask |= POLLIN | POLLRDNORM;
-#endif
 	if (file->f_mode & FMODE_WRITE)
 		if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0)
 			mask |= POLLOUT | POLLWRNORM;
@@ -686,101 +662,6 @@
 
 }
 
-#ifdef HAS_RECORD
-    /*
-     *  Here is how the values are used for reading.
-     *  The value 'active' simply indicates the DMA is running.  This is done
-     *  so the driver semantics are DMA starts when the first read is posted.
-     *  The value 'front' indicates the buffer we should next send to the user.
-     *  The value 'rear' indicates the buffer the DMA is currently filling.
-     *  When 'front' == 'rear' the buffer "ring" is empty (we always have an
-     *  empty available).  The 'rear_size' is used to track partial offsets
-     *  into the buffer we are currently returning to the user.
-
-     *  This level (> [1.5]) doesn't care what strategy the LL driver uses with
-     *  DMA on over-run.  It can leave it running (and keep active == 1) or it
-     *  can kill it and set active == 0 in which case this routine will spot
-     *  it and restart the DMA.
-     */
-
-static ssize_t sq_read(struct file *file, char __user *dst, size_t uLeft,
-		       loff_t *ppos)
-{
-
-	ssize_t	uRead, bLeft, bUsed, uUsed;
-
-	if (uLeft == 0)
-		return 0;
-
-	/* cater for the compatibility mode - record compiled in but no LL */
-	if (dmasound.mach.record == NULL)
-		return -EINVAL ;
-
-	/* see comment in sq_write()
-	*/
-
-	if( shared_resources_initialised == 0) {
-		dmasound.mach.init() ;
-		shared_resources_initialised = 1 ;
-	}
-
-	/* set up the sq if it is not already done. see comments in sq_write().
-	*/
-
-	if (read_sq.locked == 0) {
-		if ((uRead = sq_setup(&read_sq)) < 0)
-			return uRead ;
-	}
-
-	uRead = 0;
-
-	/* Move what the user requests, depending upon other options.
-	*/
-	while (uLeft > 0) {
-
-		/* we happened to get behind and the LL driver killed DMA
-		   then we should set it going again.  This also sets it
-		   going the first time through.
-		*/
-		if ( !read_sq.active )
-			dmasound.mach.record();
-
-		/* When front == rear, the DMA is not done yet.
-		*/
-		while (read_sq.front == read_sq.rear) {
-			if (read_sq.open_mode & O_NONBLOCK) {
-			       return uRead > 0 ? uRead : -EAGAIN;
-			}
-			SLEEP(read_sq.action_queue);
-			if (signal_pending(current))
-				return uRead > 0 ? uRead : -EINTR;
-		}
-
-		/* The amount we move is either what is left in the
-		 * current buffer or what the user wants.
-		 */
-		bLeft = read_sq.block_size - read_sq.rear_size;
-		bUsed = read_sq.rear_size;
-		uUsed = sound_copy_translate(dmasound.trans_read, dst, uLeft,
-					     read_sq.buffers[read_sq.front],
-					     &bUsed, bLeft);
-		if (uUsed <= 0)
-			return uUsed;
-		dst += uUsed;
-		uRead += uUsed;
-		uLeft -= uUsed;
-		read_sq.rear_size += bUsed;
-		if (read_sq.rear_size >= read_sq.block_size) {
-			read_sq.rear_size = 0;
-			read_sq.front++;
-			if (read_sq.front >= read_sq.max_active)
-				read_sq.front = 0;
-		}
-	}
-	return uRead;
-}
-#endif /* HAS_RECORD */
-
 static inline void sq_init_waitqueue(struct sound_queue *sq)
 {
 	init_waitqueue_head(&sq->action_queue);
@@ -854,23 +735,6 @@
 #define write_sq_open(file)	\
 	sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize )
 
-#ifdef HAS_RECORD
-#define read_sq_init_waitqueue()	sq_init_waitqueue(&read_sq)
-#if 0 /* blocking open() */
-#define read_sq_wake_up(file)		sq_wake_up(&read_sq, file, FMODE_READ)
-#endif
-#define read_sq_release_buffers()	sq_release_buffers(&read_sq)
-#define read_sq_open(file)	\
-	sq_open2(&read_sq, file, FMODE_READ, numReadBufs, readBufSize )
-#else
-#define read_sq_init_waitqueue()	do {} while (0)
-#if 0 /* blocking open() */
-#define read_sq_wake_up(file)		do {} while (0)
-#endif
-#define read_sq_release_buffers()	do {} while (0)
-#define sq_reset_input()		do {} while (0)
-#endif
-
 static int sq_open(struct inode *inode, struct file *file)
 {
 	int rc;
@@ -881,25 +745,11 @@
 	rc = write_sq_open(file); /* checks the f_mode */
 	if (rc)
 		goto out;
-#ifdef HAS_RECORD
-	if (dmasound.mach.record) {
-		rc = read_sq_open(file); /* checks the f_mode */
-		if (rc)
-			goto out;
-	} else { /* no record function installed; in compat mode */
-		if (file->f_mode & FMODE_READ) {
-			/* TODO: if O_RDWR, release any resources grabbed by write part */
-			rc = -ENXIO;
-			goto out;
-		}
-	}
-#else /* !HAS_RECORD */
 	if (file->f_mode & FMODE_READ) {
 		/* TODO: if O_RDWR, release any resources grabbed by write part */
 		rc = -ENXIO ; /* I think this is what is required by open(2) */
 		goto out;
 	}
-#endif /* HAS_RECORD */
 
 	if (dmasound.mach.sq_open)
 	    dmasound.mach.sq_open(file->f_mode);
@@ -956,43 +806,9 @@
 	write_sq.user_frag_size = 0 ;
 }
 
-#ifdef HAS_RECORD
-
-static void sq_reset_input(void)
-{
-	if (dmasound.mach.record && read_sq.active) {
-		if (dmasound.mach.abort_read) { /* this routine must really be present */
-			read_sq.syncing = 1 ;
-			/* this can use the read_sq.sync_queue to sleep if
-			   necessary - it should not return until DMA
-			   is really stopped - because we might deallocate
-			   the buffers as the next action...
-			*/
-			dmasound.mach.abort_read() ;
-		} else {
-			printk(KERN_ERR
-			"dmasound_core: %s has no abort_read()!! all bets are off\n",
-				dmasound.mach.name) ;
-		}
-	}
-	read_sq.syncing =
-	read_sq.active =
-	read_sq.front =
-	read_sq.count =
-	read_sq.rear = 0 ;
-
-	/* OK - we can unlock the parameters and fragment settings */
-	read_sq.locked = 0 ;
-	read_sq.user_frags = 0 ;
-	read_sq.user_frag_size = 0 ;
-}
-
-#endif
-
 static void sq_reset(void)
 {
 	sq_reset_output() ;
-	sq_reset_input() ;
 	/* we could consider resetting the shared_resources_owner here... but I
 	   think it is probably still rather non-obvious to application writer
 	*/
@@ -1038,17 +854,6 @@
 
 	lock_kernel();
 
-#ifdef HAS_RECORD
-	/* probably best to do the read side first - so that time taken to do it
-	   overlaps with playing any remaining output samples.
-	*/
-	if (file->f_mode & FMODE_READ) {
-		sq_reset_input() ; /* make sure dma is stopped and all is quiet */
-		read_sq_release_buffers();
-		read_sq.busy = 0;
-	}
-#endif
-
 	if (file->f_mode & FMODE_WRITE) {
 		if (write_sq.busy)
 			rc = sq_fsync(file, file->f_path.dentry);
@@ -1105,11 +910,6 @@
 
 static int queues_are_quiescent(void)
 {
-#ifdef HAS_RECORD
-	if (dmasound.mach.record)
-		if (read_sq.locked)
-			return 0 ;
-#endif
 	if (write_sq.locked)
 		return 0 ;
 	return 1 ;
@@ -1185,13 +985,6 @@
 		   the read_sq ones.
 		*/
 		size = 0 ;
-#ifdef HAS_RECORD
-		if (dmasound.mach.record && (file->f_mode & FMODE_READ)) {
-			if ( !read_sq.locked )
-				sq_setup(&read_sq) ; /* set params */
-			size = read_sq.user_frag_size ;
-		}
-#endif
 		if (file->f_mode & FMODE_WRITE) {
 			if ( !write_sq.locked )
 				sq_setup(&write_sq) ;
@@ -1214,8 +1007,6 @@
 		   everything - read, however, is killed imediately.
 		*/
 		result = 0 ;
-		if ((file->f_mode & FMODE_READ) && dmasound.mach.record)
-			sq_reset_input() ;
 		if (file->f_mode & FMODE_WRITE) {
 			result = sq_fsync(file, file->f_path.dentry);
 			sq_reset_output() ;
@@ -1294,13 +1085,6 @@
 		result = 0 ;
 		nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */
 		size = data & 0xffff;
-#ifdef HAS_RECORD
-		if ((file->f_mode & FMODE_READ) && dmasound.mach.record) {
-			result = set_queue_frags(&read_sq, nbufs, size) ;
-			if (result)
-				return result ;
-		}
-#endif
 		if (file->f_mode & FMODE_WRITE) {
 			result = set_queue_frags(&write_sq, nbufs, size) ;
 			if (result)
@@ -1348,20 +1132,6 @@
 	.release	= sq_release,
 };
 
-#ifdef HAS_RECORD
-static const struct file_operations sq_fops_record =
-{
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.write		= sq_write,
-	.poll		= sq_poll,
-	.ioctl		= sq_ioctl,
-	.open		= sq_open,
-	.release	= sq_release,
-	.read		= sq_read,
-};
-#endif
-
 static int sq_init(void)
 {
 	const struct file_operations *fops = &sq_fops;
@@ -1369,10 +1139,6 @@
 	int sq_unit;
 #endif
 
-#ifdef HAS_RECORD
-	if (dmasound.mach.record)
-		fops = &sq_fops_record;
-#endif
 	sq_unit = register_sound_dsp(fops, -1);
 	if (sq_unit < 0) {
 		printk(KERN_ERR "dmasound_core: couldn't register fops\n") ;
@@ -1380,7 +1146,6 @@
 	}
 
 	write_sq_init_waitqueue();
-	read_sq_init_waitqueue();
 
 	/* These parameters will be restored for every clean open()
 	 * in the case of multiple open()s (e.g. dsp0 & dsp1) they
@@ -1406,11 +1171,7 @@
    driver.
 */
 
-#ifdef HAS_RECORD
-#define STAT_BUFF_LEN 1024
-#else
 #define STAT_BUFF_LEN 768
-#endif
 
 /* this is how much space we will allow the low-level driver to use
    in the stat buffer.  Currently, 2 * (80 character line + <NL>).
@@ -1518,11 +1279,6 @@
 	len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ;
 	len += sprintf(buffer+len,"%9s:%8d%6d\n",
 		"write", write_sq.numBufs, write_sq.bufSize) ;
-#ifdef HAS_RECORD
-	if (dmasound.mach.record)
-		len += sprintf(buffer+len,"%9s:%8d%6d\n",
-			"read", read_sq.numBufs, read_sq.bufSize) ;
-#endif
 	len += sprintf(buffer+len,
 		"Current  : MaxFrg FragSiz MaxAct Frnt Rear "
 		"Cnt RrSize A B S L  xruns\n") ;
@@ -1531,14 +1287,6 @@
 		write_sq.max_active, write_sq.front, write_sq.rear,
 		write_sq.count, write_sq.rear_size, write_sq.active,
 		write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ;
-#ifdef HAS_RECORD
-	if (dmasound.mach.record)
-		len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",
-			"read", read_sq.max_count, read_sq.block_size,
-			read_sq.max_active, read_sq.front, read_sq.rear,
-			read_sq.count, read_sq.rear_size, read_sq.active,
-			read_sq.busy, read_sq.syncing, read_sq.locked, read_sq.xruns) ;
-#endif
 #ifdef DEBUG_DMASOUND
 printk("dmasound: stat buffer used %d bytes\n", len) ;
 #endif
@@ -1638,13 +1386,6 @@
 		(dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
 	printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n",
 		numWriteBufs, writeBufSize) ;
-#ifdef HAS_RECORD
-	if (dmasound.mach.record)
-		printk(KERN_INFO
-			"Read  will use %4d fragments of %7d bytes as default\n",
-			numReadBufs, readBufSize) ;
-#endif
-
 	return 0;
 }
 
@@ -1659,7 +1400,6 @@
 	}
 
 	write_sq_release_buffers();
-	read_sq_release_buffers();
 
 	if (mixer_unit >= 0)
 		unregister_sound_mixer(mixer_unit);
@@ -1684,36 +1424,12 @@
 	 */
 
 	switch (ints[0]) {
-#ifdef HAS_RECORD
-        case 5:
-                if ((ints[5] < 0) || (ints[5] > MAX_CATCH_RADIUS))
-                        printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
-                else
-                        catchRadius = ints[5];
-                /* fall through */
-        case 4:
-                if (ints[4] < MIN_BUFFERS)
-                        printk("dmasound_setup: invalid number of read buffers, using default = %d\n",
-                                 numReadBufs);
-                else
-                        numReadBufs = ints[4];
-                /* fall through */
-        case 3:
-		if ((size = ints[3]) < 256)  /* check for small buffer specs */
-			size <<= 10 ;
-                if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)
-                        printk("dmasound_setup: invalid read buffer size, using default = %d\n", readBufSize);
-                else
-                        readBufSize = size;
-                /* fall through */
-#else
 	case 3:
 		if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
 			printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
 		else
 			catchRadius = ints[3];
 		/* fall through */
-#endif
 	case 2:
 		if (ints[1] < MIN_BUFFERS)
 			printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs);
@@ -1830,9 +1546,6 @@
 EXPORT_SYMBOL(dmasound_deinit);
 #endif
 EXPORT_SYMBOL(dmasound_write_sq);
-#ifdef HAS_RECORD
-EXPORT_SYMBOL(dmasound_read_sq);
-#endif
 EXPORT_SYMBOL(dmasound_catchRadius);
 #ifdef HAS_8BIT_TABLES
 EXPORT_SYMBOL(dmasound_ulaw2dma8);
diff --git a/sound/oss/dmasound/tas3001c.c b/sound/oss/dmasound/tas3001c.c
deleted file mode 100644
index 4b7dbdd..0000000
--- a/sound/oss/dmasound/tas3001c.c
+++ /dev/null
@@ -1,849 +0,0 @@
-/*
- * Driver for the i2c/i2s based TA3004 sound chip used
- * on some Apple hardware. Also known as "snapper".
- *
- * Tobias Sargeant <tobias.sargeant@bigpond.com>
- * Based upon, tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
- *
- *   TODO:
- *   -----
- *   * Enable control over input line 2 (is this connected?)
- *   * Implement sleep support (at least mute everything and
- *   * set gains to minimum during sleep)
- *   * Look into some of Darwin's tweaks regarding the mute
- *   * lines (delays & different behaviour on some HW)
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/soundcard.h>
-#include <linux/workqueue.h>
-#include <asm/uaccess.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-
-#include "dmasound.h"
-#include "tas_common.h"
-#include "tas3001c.h"
-
-#include "tas_ioctl.h"
-
-#define TAS3001C_BIQUAD_FILTER_COUNT  6
-#define TAS3001C_BIQUAD_CHANNEL_COUNT 2
-
-#define VOL_DEFAULT	(100 * 4 / 5)
-#define INPUT_DEFAULT	(100 * 4 / 5)
-#define BASS_DEFAULT	(100 / 2)
-#define TREBLE_DEFAULT	(100 / 2)
-
-struct tas3001c_data_t {
-	struct tas_data_t super;
-	int device_id;
-	int output_id;
-	int speaker_id;
-	struct tas_drce_t drce_state;
-	struct work_struct change;
-};
-
-
-static const union tas_biquad_t
-tas3001c_eq_unity={
-	.buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 }
-};
-
-
-static inline unsigned char db_to_regval(short db) {
-	int r=0;
-
-	r=(db+0x59a0) / 0x60;
-
-	if (r < 0x91) return 0x91;
-	if (r > 0xef) return 0xef;
-	return r;
-}
-
-static inline short quantize_db(short db) {
-	return db_to_regval(db) * 0x60 - 0x59a0;
-}
-
-
-static inline int
-register_width(enum tas3001c_reg_t r)
-{
-	switch(r) {
-	case TAS3001C_REG_MCR:
- 	case TAS3001C_REG_TREBLE:
-	case TAS3001C_REG_BASS:
-		return 1;
-
-	case TAS3001C_REG_DRC:
-		return 2;
-
-	case TAS3001C_REG_MIXER1:
-	case TAS3001C_REG_MIXER2:
-		return 3;
-
-	case TAS3001C_REG_VOLUME:
-		return 6;
-
-	case TAS3001C_REG_LEFT_BIQUAD0:
-	case TAS3001C_REG_LEFT_BIQUAD1:
-	case TAS3001C_REG_LEFT_BIQUAD2:
-	case TAS3001C_REG_LEFT_BIQUAD3:
-	case TAS3001C_REG_LEFT_BIQUAD4:
-	case TAS3001C_REG_LEFT_BIQUAD5:
-	case TAS3001C_REG_LEFT_BIQUAD6:
-
-	case TAS3001C_REG_RIGHT_BIQUAD0:
-	case TAS3001C_REG_RIGHT_BIQUAD1:
-	case TAS3001C_REG_RIGHT_BIQUAD2:
-	case TAS3001C_REG_RIGHT_BIQUAD3:
-	case TAS3001C_REG_RIGHT_BIQUAD4:
-	case TAS3001C_REG_RIGHT_BIQUAD5:
-	case TAS3001C_REG_RIGHT_BIQUAD6:
-		return 15;
-
-	default:
-		return 0;
-	}
-}
-
-static int
-tas3001c_write_register(	struct tas3001c_data_t *self,
-				enum tas3001c_reg_t reg_num,
-				char *data,
-				uint write_mode)
-{
-	if (reg_num==TAS3001C_REG_MCR ||
-	    reg_num==TAS3001C_REG_BASS ||
-	    reg_num==TAS3001C_REG_TREBLE) {
-		return tas_write_byte_register(&self->super,
-					       (uint)reg_num,
-					       *data,
-					       write_mode);
-	} else {
-		return tas_write_register(&self->super,
-					  (uint)reg_num,
-					  register_width(reg_num),
-					  data,
-					  write_mode);
-	}
-}
-
-static int
-tas3001c_sync_register(	struct tas3001c_data_t *self,
-			enum tas3001c_reg_t reg_num)
-{
-	if (reg_num==TAS3001C_REG_MCR ||
-	    reg_num==TAS3001C_REG_BASS ||
-	    reg_num==TAS3001C_REG_TREBLE) {
-		return tas_sync_byte_register(&self->super,
-					      (uint)reg_num,
-					      register_width(reg_num));
-	} else {
-		return tas_sync_register(&self->super,
-					 (uint)reg_num,
-					 register_width(reg_num));
-	}
-}
-
-static int
-tas3001c_read_register(	struct tas3001c_data_t *self,
-			enum tas3001c_reg_t reg_num,
-			char *data,
-			uint write_mode)
-{
-	return tas_read_register(&self->super,
-				 (uint)reg_num,
-				 register_width(reg_num),
-				 data);
-}
-
-static inline int
-tas3001c_fast_load(struct tas3001c_data_t *self, int fast)
-{
-	if (fast)
-		self->super.shadow[TAS3001C_REG_MCR][0] |= 0x80;
-	else
-		self->super.shadow[TAS3001C_REG_MCR][0] &= 0x7f;
-	return tas3001c_sync_register(self,TAS3001C_REG_MCR);
-}
-
-static uint
-tas3001c_supported_mixers(struct tas3001c_data_t *self)
-{
-	return SOUND_MASK_VOLUME |
-		SOUND_MASK_PCM |
-		SOUND_MASK_ALTPCM |
-		SOUND_MASK_TREBLE |
-		SOUND_MASK_BASS;
-}
-
-static int
-tas3001c_mixer_is_stereo(struct tas3001c_data_t *self,int mixer)
-{
-	switch(mixer) {
-	case SOUND_MIXER_VOLUME:
-		return 1;
-	default:
-		return 0;
-	}
-}
-
-static uint
-tas3001c_stereo_mixers(struct tas3001c_data_t *self)
-{
-	uint r=tas3001c_supported_mixers(self);
-	uint i;
-	
-	for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
-		if (r&(1<<i) && !tas3001c_mixer_is_stereo(self,i))
-			r &= ~(1<<i);
-	return r;
-}
-
-static int
-tas3001c_get_mixer_level(struct tas3001c_data_t *self,int mixer,uint *level)
-{
-	if (!self)
-		return -1;
-		
-	*level=self->super.mixer[mixer];
-	
-	return 0;
-}
-
-static int
-tas3001c_set_mixer_level(struct tas3001c_data_t *self,int mixer,uint level)
-{
-	int rc;
-	tas_shadow_t *shadow;
-
-	uint temp;
-	uint offset=0;
-
-	if (!self)
-		return -1;
-		
-	shadow=self->super.shadow;
-
-	if (!tas3001c_mixer_is_stereo(self,mixer))
-		level = tas_mono_to_stereo(level);
-
-	switch(mixer) {
-	case SOUND_MIXER_VOLUME:
-		temp = tas3001c_gain.master[level&0xff];
-		shadow[TAS3001C_REG_VOLUME][0] = (temp >> 16) & 0xff;
-		shadow[TAS3001C_REG_VOLUME][1] = (temp >> 8)  & 0xff;
-		shadow[TAS3001C_REG_VOLUME][2] = (temp >> 0)  & 0xff;
-		temp = tas3001c_gain.master[(level>>8)&0xff];
-		shadow[TAS3001C_REG_VOLUME][3] = (temp >> 16) & 0xff;
-		shadow[TAS3001C_REG_VOLUME][4] = (temp >> 8)  & 0xff;
-		shadow[TAS3001C_REG_VOLUME][5] = (temp >> 0)  & 0xff;
-		rc = tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
-		break;
-	case SOUND_MIXER_ALTPCM:
-		/* tas3001c_fast_load(self, 1); */
-		level = tas_mono_to_stereo(level);
-		temp = tas3001c_gain.mixer[level&0xff];
-		shadow[TAS3001C_REG_MIXER2][offset+0] = (temp >> 16) & 0xff;
-		shadow[TAS3001C_REG_MIXER2][offset+1] = (temp >> 8)  & 0xff;
-		shadow[TAS3001C_REG_MIXER2][offset+2] = (temp >> 0)  & 0xff;
-		rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
-		/* tas3001c_fast_load(self, 0); */
-		break;
-	case SOUND_MIXER_PCM:
-		/* tas3001c_fast_load(self, 1); */
-		level = tas_mono_to_stereo(level);
-		temp = tas3001c_gain.mixer[level&0xff];
-		shadow[TAS3001C_REG_MIXER1][offset+0] = (temp >> 16) & 0xff;
-		shadow[TAS3001C_REG_MIXER1][offset+1] = (temp >> 8)  & 0xff;
-		shadow[TAS3001C_REG_MIXER1][offset+2] = (temp >> 0)  & 0xff;
-		rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
-		/* tas3001c_fast_load(self, 0); */
-		break;
-	case SOUND_MIXER_TREBLE:
-		temp = tas3001c_gain.treble[level&0xff];
-		shadow[TAS3001C_REG_TREBLE][0]=temp&0xff;
-		rc = tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
-		break;
-	case SOUND_MIXER_BASS:
-		temp = tas3001c_gain.bass[level&0xff];
-		shadow[TAS3001C_REG_BASS][0]=temp&0xff;
-		rc = tas3001c_sync_register(self,TAS3001C_REG_BASS);
-		break;
-	default:
-		rc = -1;
-		break;
-	}
-	if (rc < 0)
-		return rc;
-	self->super.mixer[mixer]=level;
-	return 0;
-}
-
-static int
-tas3001c_leave_sleep(struct tas3001c_data_t *self)
-{
-	unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
-
-	if (!self)
-		return -1;
-
-	/* Make sure something answers on the i2c bus */
-	if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
-	    WRITE_NORMAL|FORCE_WRITE) < 0)
-	    	return -1;
-
-	tas3001c_fast_load(self, 1);
-
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
-
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
-
-	tas3001c_fast_load(self, 0);
-
-	(void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
-
-	return 0;
-}
-
-static int
-tas3001c_enter_sleep(struct tas3001c_data_t *self)
-{
-	/* Stub for now, but I have the details on low-power mode */
-	if (!self)
-		return -1; 
-	return 0;
-}
-
-static int
-tas3001c_sync_biquad(	struct tas3001c_data_t *self,
-			u_int channel,
-			u_int filter)
-{
-	enum tas3001c_reg_t reg;
-
-	if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
-	    filter  >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
-
-	reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
-
-	return tas3001c_sync_register(self,reg);
-}
-
-static int
-tas3001c_write_biquad_shadow(	struct tas3001c_data_t *self,
-				u_int channel,
-				u_int filter,
-				const union tas_biquad_t *biquad)
-{
-	tas_shadow_t *shadow=self->super.shadow;
-	enum tas3001c_reg_t reg;
-
-	if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
-	    filter  >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
-
-	reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
-
-	SET_4_20(shadow[reg], 0,biquad->coeff.b0);
-	SET_4_20(shadow[reg], 3,biquad->coeff.b1);
-	SET_4_20(shadow[reg], 6,biquad->coeff.b2);
-	SET_4_20(shadow[reg], 9,biquad->coeff.a1);
-	SET_4_20(shadow[reg],12,biquad->coeff.a2);
-
-	return 0;
-}
-
-static int
-tas3001c_write_biquad(	struct tas3001c_data_t *self,
-			u_int channel,
-			u_int filter,
-			const union tas_biquad_t *biquad)
-{
-	int rc;
-
-	rc=tas3001c_write_biquad_shadow(self, channel, filter, biquad);
-	if (rc < 0) return rc;
-
-	return tas3001c_sync_biquad(self, channel, filter);
-}
-
-static int
-tas3001c_write_biquad_list(	struct tas3001c_data_t *self,
-				u_int filter_count,
-				u_int flags,
-				struct tas_biquad_ctrl_t *biquads)
-{
-	int i;
-	int rc;
-
-	if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
-
-	for (i=0; i<filter_count; i++) {
-		rc=tas3001c_write_biquad(self,
-					 biquads[i].channel,
-					 biquads[i].filter,
-					 &biquads[i].data);
-		if (rc < 0) break;
-	}
-
-	if (flags & TAS_BIQUAD_FAST_LOAD) {
-		tas3001c_fast_load(self,0);
-
-		(void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
-		(void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
-		(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
-		(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
-		(void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
-	}
-
-	return rc;
-}
-
-static int
-tas3001c_read_biquad(	struct tas3001c_data_t *self,
-			u_int channel,
-			u_int filter,
-			union tas_biquad_t *biquad)
-{
-	tas_shadow_t *shadow=self->super.shadow;
-	enum tas3001c_reg_t reg;
-
-	if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
-	    filter  >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
-
-	reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
-
-	biquad->coeff.b0=GET_4_20(shadow[reg], 0);
-	biquad->coeff.b1=GET_4_20(shadow[reg], 3);
-	biquad->coeff.b2=GET_4_20(shadow[reg], 6);
-	biquad->coeff.a1=GET_4_20(shadow[reg], 9);
-	biquad->coeff.a2=GET_4_20(shadow[reg],12);
-	
-	return 0;	
-}
-
-static int
-tas3001c_eq_rw(	struct tas3001c_data_t *self,
-		u_int cmd,
-		u_long arg)
-{
-	int rc;
-	struct tas_biquad_ctrl_t biquad;
-	void __user *argp = (void __user *)arg;
-
-	if (copy_from_user(&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
-		return -EFAULT;
-	}
-
-	if (cmd & SIOC_IN) {
-		rc=tas3001c_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
-		if (rc != 0) return rc;
-	}
-
-	if (cmd & SIOC_OUT) {
-		rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
-		if (rc != 0) return rc;
-
-		if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) {
-			return -EFAULT;
-		}
-
-	}
-	return 0;
-}
-
-static int
-tas3001c_eq_list_rw(	struct tas3001c_data_t *self,
-			u_int cmd,
-			u_long arg)
-{
-	int rc;
-	int filter_count;
-	int flags;
-	int i,j;
-	char sync_required[2][6];
-	struct tas_biquad_ctrl_t biquad;
-	struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg;
-
-	memset(sync_required,0,sizeof(sync_required));
-
-	if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int)))
-		return -EFAULT;
-
-	if (copy_from_user(&flags, &argp->flags, sizeof(int)))
-		return -EFAULT;
-
-	if (cmd & SIOC_IN) {
-	}
-
-	for (i=0; i < filter_count; i++) {
-		if (copy_from_user(&biquad, &argp->biquads[i],
-				   sizeof(struct tas_biquad_ctrl_t))) {
-			return -EFAULT;
-		}
-
-		if (cmd & SIOC_IN) {
-			sync_required[biquad.channel][biquad.filter]=1;
-			rc=tas3001c_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
-			if (rc != 0) return rc;
-		}
-
-		if (cmd & SIOC_OUT) {
-			rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
-			if (rc != 0) return rc;
-
-			if (copy_to_user(&argp->biquads[i], &biquad,
-					 sizeof(struct tas_biquad_ctrl_t))) {
-				return -EFAULT;
-			}
-		}
-	}
-
-	if (cmd & SIOC_IN) {
-		if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
-		for (i=0; i<2; i++) {
-			for (j=0; j<6; j++) {
-				if (sync_required[i][j]) {
-					rc=tas3001c_sync_biquad(self, i, j);
-					if (rc < 0) return rc;
-				}
-			}
-		}
-		if (flags & TAS_BIQUAD_FAST_LOAD) {
-			tas3001c_fast_load(self,0);
-			/* now we need to set up the mixers again,
-			   because leaving fast mode resets them. */
-			(void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
-			(void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
-			(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
-			(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
-			(void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
-		}
-	}
-
-	return 0;
-}
-
-static int
-tas3001c_update_drce(	struct tas3001c_data_t *self,
-			int flags,
-			struct tas_drce_t *drce)
-{
-	tas_shadow_t *shadow;
-	shadow=self->super.shadow;
-
-	shadow[TAS3001C_REG_DRC][1] = 0xc1;
-
-	if (flags & TAS_DRCE_THRESHOLD) {
-		self->drce_state.threshold=quantize_db(drce->threshold);
-		shadow[TAS3001C_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
-	}
-
-	if (flags & TAS_DRCE_ENABLE) {
-		self->drce_state.enable = drce->enable;
-	}
-
-	if (!self->drce_state.enable) {
-		shadow[TAS3001C_REG_DRC][0] = 0xf0;
-	}
-
-#ifdef DEBUG_DRCE
-	printk("DRCE IOCTL: set [ ENABLE:%x THRESH:%x\n",
-	       self->drce_state.enable,
-	       self->drce_state.threshold);
-
-	printk("DRCE IOCTL: reg [ %02x %02x ]\n",
-	       (unsigned char)shadow[TAS3001C_REG_DRC][0],
-	       (unsigned char)shadow[TAS3001C_REG_DRC][1]);
-#endif
-
-	return tas3001c_sync_register(self, TAS3001C_REG_DRC);
-}
-
-static int
-tas3001c_drce_rw(	struct tas3001c_data_t *self,
-			u_int cmd,
-			u_long arg)
-{
-	int rc;
-	struct tas_drce_ctrl_t drce_ctrl;
-	void __user *argp = (void __user *)arg;
-
-	if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t)))
-		return -EFAULT;
-
-#ifdef DEBUG_DRCE
-	printk("DRCE IOCTL: input [ FLAGS:%x ENABLE:%x THRESH:%x\n",
-	       drce_ctrl.flags,
-	       drce_ctrl.data.enable,
-	       drce_ctrl.data.threshold);
-#endif
-
-	if (cmd & SIOC_IN) {
-		rc = tas3001c_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
-		if (rc < 0)
-			return rc;
-	}
-
-	if (cmd & SIOC_OUT) {
-		if (drce_ctrl.flags & TAS_DRCE_ENABLE)
-			drce_ctrl.data.enable = self->drce_state.enable;
-
-		if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
-			drce_ctrl.data.threshold = self->drce_state.threshold;
-
-		if (copy_to_user(argp, &drce_ctrl,
-				 sizeof(struct tas_drce_ctrl_t))) {
-			return -EFAULT;
-		}
-	}
-
-	return 0;
-}
-
-static void
-tas3001c_update_device_parameters(struct tas3001c_data_t *self)
-{
-	int i,j;
-
-	if (!self) return;
-
-	if (self->output_id == TAS_OUTPUT_HEADPHONES) {
-		tas3001c_fast_load(self, 1);
-
-		for (i=0; i<TAS3001C_BIQUAD_CHANNEL_COUNT; i++) {
-			for (j=0; j<TAS3001C_BIQUAD_FILTER_COUNT; j++) {
-				tas3001c_write_biquad(self, i, j, &tas3001c_eq_unity);
-			}
-		}
-
-		tas3001c_fast_load(self, 0);
-
-		(void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
-		(void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
-		(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
-		(void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
-		(void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
-
-		return;
-	}
-
-	for (i=0; tas3001c_eq_prefs[i]; i++) {
-		struct tas_eq_pref_t *eq = tas3001c_eq_prefs[i];
-
-		if (eq->device_id == self->device_id &&
-		    (eq->output_id == 0 || eq->output_id == self->output_id) &&
-		    (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
-
-			tas3001c_update_drce(self, TAS_DRCE_ALL, eq->drce);
-			tas3001c_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
-
-			break;
-		}
-	}
-}
-
-static void
-tas3001c_device_change_handler(struct work_struct *work)
-{
-	struct tas3001c_data_t *self;
-	self = container_of(work, struct tas3001c_data_t, change);
-	tas3001c_update_device_parameters(self);
-}
-
-static int
-tas3001c_output_device_change(	struct tas3001c_data_t *self,
-				int device_id,
-				int output_id,
-				int speaker_id)
-{
-	self->device_id=device_id;
-	self->output_id=output_id;
-	self->speaker_id=speaker_id;
-
-	schedule_work(&self->change);
-	return 0;
-}
-
-static int
-tas3001c_device_ioctl(	struct tas3001c_data_t *self,
-			u_int cmd,
-			u_long arg)
-{
-	uint __user *argp = (void __user *)arg;
-	switch (cmd) {
-	case TAS_READ_EQ:
-	case TAS_WRITE_EQ:
-		return tas3001c_eq_rw(self, cmd, arg);
-
-	case TAS_READ_EQ_LIST:
-	case TAS_WRITE_EQ_LIST:
-		return tas3001c_eq_list_rw(self, cmd, arg);
-
-	case TAS_READ_EQ_FILTER_COUNT:
-		put_user(TAS3001C_BIQUAD_FILTER_COUNT, argp);
-		return 0;
-
-	case TAS_READ_EQ_CHANNEL_COUNT:
-		put_user(TAS3001C_BIQUAD_CHANNEL_COUNT, argp);
-		return 0;
-
-	case TAS_READ_DRCE:
-	case TAS_WRITE_DRCE:
-		return tas3001c_drce_rw(self, cmd, arg);
-
-	case TAS_READ_DRCE_CAPS:
-		put_user(TAS_DRCE_ENABLE | TAS_DRCE_THRESHOLD, argp);
-		return 0;
-
-	case TAS_READ_DRCE_MIN:
-	case TAS_READ_DRCE_MAX: {
-		struct tas_drce_ctrl_t drce_ctrl;
-
-		if (copy_from_user(&drce_ctrl, argp,
-				   sizeof(struct tas_drce_ctrl_t))) {
-			return -EFAULT;
-		}
-
-		if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
-			if (cmd == TAS_READ_DRCE_MIN) {
-				drce_ctrl.data.threshold=-36<<8;
-			} else {
-				drce_ctrl.data.threshold=-6<<8;
-			}
-		}
-
-		if (copy_to_user(argp, &drce_ctrl,
-				 sizeof(struct tas_drce_ctrl_t))) {
-			return -EFAULT;
-		}
-	}
-	}
-
-	return -EINVAL;
-}
-
-static int
-tas3001c_init_mixer(struct tas3001c_data_t *self)
-{
-	unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
-
-	/* Make sure something answers on the i2c bus */
-	if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
-	    WRITE_NORMAL|FORCE_WRITE) < 0)
-		return -1;
-
-	tas3001c_fast_load(self, 1);
-
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD6);
-
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
-	(void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD6);
-
-	tas3001c_fast_load(self, 0);
-
-	tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
-	tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
-	tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
-
-	tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
-	tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
-
-	return 0;
-}
-
-static int
-tas3001c_uninit_mixer(struct tas3001c_data_t *self)
-{
-	tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
-	tas3001c_set_mixer_level(self, SOUND_MIXER_PCM,    0);
-	tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
-
-	tas3001c_set_mixer_level(self, SOUND_MIXER_BASS,   0);
-	tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
-
-	return 0;
-}
-
-static int
-tas3001c_init(struct i2c_client *client)
-{
-	struct tas3001c_data_t *self;
-	size_t sz = sizeof(*self) + (TAS3001C_REG_MAX*sizeof(tas_shadow_t));
-	int i, j;
-
-	self = kzalloc(sz, GFP_KERNEL);
-	if (!self)
-		return -ENOMEM;
-
-	self->super.client = client;
-	self->super.shadow = (tas_shadow_t *)(self+1);
-	self->output_id = TAS_OUTPUT_HEADPHONES;
-
-	dev_set_drvdata(&client->dev, self);
-
-	for (i = 0; i < TAS3001C_BIQUAD_CHANNEL_COUNT; i++)
-		for (j = 0; j < TAS3001C_BIQUAD_FILTER_COUNT; j++)
-			tas3001c_write_biquad_shadow(self, i, j,
-				&tas3001c_eq_unity);
-
-	INIT_WORK(&self->change, tas3001c_device_change_handler);
-	return 0;
-}
-
-static void
-tas3001c_uninit(struct tas3001c_data_t *self)
-{
-	tas3001c_uninit_mixer(self);
-	kfree(self);
-}
-
-struct tas_driver_hooks_t tas3001c_hooks = {
-	.init			= (tas_hook_init_t)tas3001c_init,
-	.post_init		= (tas_hook_post_init_t)tas3001c_init_mixer,
-	.uninit			= (tas_hook_uninit_t)tas3001c_uninit,
-	.get_mixer_level	= (tas_hook_get_mixer_level_t)tas3001c_get_mixer_level,
-	.set_mixer_level	= (tas_hook_set_mixer_level_t)tas3001c_set_mixer_level,
-	.enter_sleep		= (tas_hook_enter_sleep_t)tas3001c_enter_sleep,
-	.leave_sleep		= (tas_hook_leave_sleep_t)tas3001c_leave_sleep,
-	.supported_mixers	= (tas_hook_supported_mixers_t)tas3001c_supported_mixers,
-	.mixer_is_stereo	= (tas_hook_mixer_is_stereo_t)tas3001c_mixer_is_stereo,
-	.stereo_mixers		= (tas_hook_stereo_mixers_t)tas3001c_stereo_mixers,
-	.output_device_change	= (tas_hook_output_device_change_t)tas3001c_output_device_change,
-	.device_ioctl		= (tas_hook_device_ioctl_t)tas3001c_device_ioctl
-};
diff --git a/sound/oss/dmasound/tas3001c.h b/sound/oss/dmasound/tas3001c.h
deleted file mode 100644
index 3660da3..0000000
--- a/sound/oss/dmasound/tas3001c.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Header file for the i2c/i2s based TA3001c sound chip used
- * on some Apple hardware. Also known as "tumbler".
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive
- *  for more details.
- *
- * Written by Christopher C. Chimelis <chris@debian.org>
- */
-
-#ifndef _TAS3001C_H_
-#define _TAS3001C_H_
-
-#include <linux/types.h>
-
-#include "tas_common.h"
-#include "tas_eq_prefs.h"
-
-/*
- * Macros that correspond to the registers that we write to
- * when setting the various values.
- */
-
-#define TAS3001C_VERSION	"0.3"
-#define TAS3001C_DATE	        "20011214"
-
-#define I2C_DRIVERNAME_TAS3001C "TAS3001c driver V " TAS3001C_VERSION
-#define I2C_DRIVERID_TAS3001C   (I2C_DRIVERID_TAS_BASE+0)
-
-extern  struct tas_driver_hooks_t tas3001c_hooks;
-extern struct tas_gain_t tas3001c_gain;
-extern struct tas_eq_pref_t *tas3001c_eq_prefs[];
-
-enum tas3001c_reg_t {
-  TAS3001C_REG_MCR                    = 0x01,
-  TAS3001C_REG_DRC                    = 0x02,
-
-  TAS3001C_REG_VOLUME                 = 0x04,
-  TAS3001C_REG_TREBLE                 = 0x05,
-  TAS3001C_REG_BASS                   = 0x06,
-  TAS3001C_REG_MIXER1                 = 0x07,
-  TAS3001C_REG_MIXER2                 = 0x08,
-
-  TAS3001C_REG_LEFT_BIQUAD0           = 0x0a,
-  TAS3001C_REG_LEFT_BIQUAD1           = 0x0b,
-  TAS3001C_REG_LEFT_BIQUAD2           = 0x0c,
-  TAS3001C_REG_LEFT_BIQUAD3           = 0x0d,
-  TAS3001C_REG_LEFT_BIQUAD4           = 0x0e,
-  TAS3001C_REG_LEFT_BIQUAD5           = 0x0f,
-  TAS3001C_REG_LEFT_BIQUAD6           = 0x10,
-  
-  TAS3001C_REG_RIGHT_BIQUAD0          = 0x13,
-  TAS3001C_REG_RIGHT_BIQUAD1          = 0x14,
-  TAS3001C_REG_RIGHT_BIQUAD2          = 0x15,
-  TAS3001C_REG_RIGHT_BIQUAD3          = 0x16,
-  TAS3001C_REG_RIGHT_BIQUAD4          = 0x17,
-  TAS3001C_REG_RIGHT_BIQUAD5          = 0x18,
-  TAS3001C_REG_RIGHT_BIQUAD6          = 0x19,
-
-  TAS3001C_REG_MAX                    = 0x20
-};
-
-#endif /* _TAS3001C_H_ */
diff --git a/sound/oss/dmasound/tas3001c_tables.c b/sound/oss/dmasound/tas3001c_tables.c
deleted file mode 100644
index 1768fa9..0000000
--- a/sound/oss/dmasound/tas3001c_tables.c
+++ /dev/null
@@ -1,375 +0,0 @@
-#include "tas_common.h"
-#include "tas_eq_prefs.h"
-
-static struct tas_drce_t eqp_0e_2_1_drce = {
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -15.33  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_0e_2_1_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
-};
-
-static struct tas_eq_pref_t eqp_0e_2_1 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x0e,
-  .output_id     = TAS_OUTPUT_EXTERNAL_SPKR,
-  .speaker_id    = 0x01,
-
-  .drce          = &eqp_0e_2_1_drce,
-
-  .filter_count  = 12,
-  .biquads       = eqp_0e_2_1_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_10_1_0_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -12.46  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_10_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-};
-
-static struct tas_eq_pref_t eqp_10_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x10,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_10_1_0_drce,
-
-  .filter_count  = 12,
-  .biquads       = eqp_10_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_15_2_1_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -15.33  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_15_2_1_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
-};
-
-static struct tas_eq_pref_t eqp_15_2_1 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x15,
-  .output_id     = TAS_OUTPUT_EXTERNAL_SPKR,
-  .speaker_id    = 0x01,
-
-  .drce          = &eqp_15_2_1_drce,
-
-  .filter_count  = 12,
-  .biquads       = eqp_15_2_1_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_15_1_0_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = 0.0     * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_15_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
-};
-
-static struct tas_eq_pref_t eqp_15_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x15,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_15_1_0_drce,
-
-  .filter_count  = 12,
-  .biquads       = eqp_15_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_0f_2_1_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -15.33  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_0f_2_1_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
-};
-
-static struct tas_eq_pref_t eqp_0f_2_1 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x0f,
-  .output_id     = TAS_OUTPUT_EXTERNAL_SPKR,
-  .speaker_id    = 0x01,
-
-  .drce          = &eqp_0f_2_1_drce,
-
-  .filter_count  = 12,
-  .biquads       = eqp_0f_2_1_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_0f_1_0_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -15.33  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_0f_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
-};
-
-static struct tas_eq_pref_t eqp_0f_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x0f,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_0f_1_0_drce,
-
-  .filter_count  = 12,
-  .biquads       = eqp_0f_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static uint tas3001c_master_tab[]={
-	       0x0,       0x75,       0x9c,       0xbb,
-	      0xdb,       0xfb,      0x11e,      0x143,
-	     0x16b,      0x196,      0x1c3,      0x1f5,
-	     0x229,      0x263,      0x29f,      0x2e1,
-	     0x328,      0x373,      0x3c5,      0x41b,
-	     0x478,      0x4dc,      0x547,      0x5b8,
-	     0x633,      0x6b5,      0x740,      0x7d5,
-	     0x873,      0x91c,      0x9d2,      0xa92,
-	     0xb5e,      0xc39,      0xd22,      0xe19,
-	     0xf20,     0x1037,     0x1161,     0x129e,
-	    0x13ed,     0x1551,     0x16ca,     0x185d,
-	    0x1a08,     0x1bcc,     0x1dac,     0x1fa7,
-	    0x21c1,     0x23fa,     0x2655,     0x28d6,
-	    0x2b7c,     0x2e4a,     0x3141,     0x3464,
-	    0x37b4,     0x3b35,     0x3ee9,     0x42d3,
-	    0x46f6,     0x4b53,     0x4ff0,     0x54ce,
-	    0x59f2,     0x5f5f,     0x6519,     0x6b24,
-	    0x7183,     0x783c,     0x7f53,     0x86cc,
-	    0x8ead,     0x96fa,     0x9fba,     0xa8f2,
-	    0xb2a7,     0xbce1,     0xc7a5,     0xd2fa,
-	    0xdee8,     0xeb75,     0xf8aa,    0x1068e,
-	   0x1152a,    0x12487,    0x134ad,    0x145a5,
-	   0x1577b,    0x16a37,    0x17df5,    0x192bd,
-	   0x1a890,    0x1bf7b,    0x1d78d,    0x1f0d1,
-	   0x20b55,    0x22727,    0x24456,    0x262f2,
-	   0x2830b
-};
-
-static uint tas3001c_mixer_tab[]={
-	       0x0,      0x748,      0x9be,      0xbaf,
-	     0xda4,      0xfb1,     0x11de,     0x1431,
-	    0x16ad,     0x1959,     0x1c37,     0x1f4b,
-	    0x2298,     0x2628,     0x29fb,     0x2e12,
-	    0x327d,     0x3734,     0x3c47,     0x41b4,
-	    0x4787,     0x4dbe,     0x546d,     0x5b86,
-	    0x632e,     0x6b52,     0x7400,     0x7d54,
-	    0x873b,     0x91c6,     0x9d1a,     0xa920,
-	    0xb5e5,     0xc38c,     0xd21b,     0xe18f,
-	    0xf1f5,    0x1036a,    0x1160f,    0x129d6,
-	   0x13ed0,    0x1550c,    0x16ca0,    0x185c9,
-	   0x1a07b,    0x1bcc3,    0x1dab9,    0x1fa75,
-	   0x21c0f,    0x23fa3,    0x26552,    0x28d64,
-	   0x2b7c9,    0x2e4a2,    0x31411,    0x3463b,
-	   0x37b44,    0x3b353,    0x3ee94,    0x42d30,
-	   0x46f55,    0x4b533,    0x4fefc,    0x54ce5,
-	   0x59f25,    0x5f5f6,    0x65193,    0x6b23c,
-	   0x71835,    0x783c3,    0x7f52c,    0x86cc0,
-	   0x8eacc,    0x96fa5,    0x9fba0,    0xa8f1a,
-	   0xb2a71,    0xbce0a,    0xc7a4a,    0xd2fa0,
-	   0xdee7b,    0xeb752,    0xf8a9f,   0x1068e4,
-	  0x1152a3,   0x12486a,   0x134ac8,   0x145a55,
-	  0x1577ac,   0x16a370,   0x17df51,   0x192bc2,
-	  0x1a88f8,   0x1bf7b7,   0x1d78c9,   0x1f0d04,
-	  0x20b542,   0x227268,   0x244564,   0x262f26,
-	  0x2830af
-};
-
-static uint tas3001c_treble_tab[]={
-	      0x96,       0x95,       0x95,       0x94,
-	      0x93,       0x92,       0x92,       0x91,
-	      0x90,       0x90,       0x8f,       0x8e,
-	      0x8d,       0x8d,       0x8c,       0x8b,
-	      0x8a,       0x8a,       0x89,       0x88,
-	      0x88,       0x87,       0x86,       0x85,
-	      0x85,       0x84,       0x83,       0x83,
-	      0x82,       0x81,       0x80,       0x80,
-	      0x7f,       0x7e,       0x7e,       0x7d,
-	      0x7c,       0x7b,       0x7b,       0x7a,
-	      0x79,       0x78,       0x78,       0x77,
-	      0x76,       0x76,       0x75,       0x74,
-	      0x73,       0x73,       0x72,       0x71,
-	      0x71,       0x70,       0x6e,       0x6d,
-	      0x6d,       0x6c,       0x6b,       0x6a,
-	      0x69,       0x68,       0x67,       0x66,
-	      0x65,       0x63,       0x62,       0x62,
-	      0x60,       0x5f,       0x5d,       0x5c,
-	      0x5a,       0x58,       0x56,       0x55,
-	      0x53,       0x51,       0x4f,       0x4c,
-	      0x4a,       0x48,       0x45,       0x43,
-	      0x40,       0x3d,       0x3a,       0x37,
-	      0x35,       0x32,       0x2e,       0x2a,
-	      0x27,       0x22,       0x1e,       0x1a,
-	      0x15,       0x11,        0xc,        0x7,
-	       0x1
-};
-
-static uint tas3001c_bass_tab[]={
-	      0x86,       0x83,       0x81,       0x7f,
-	      0x7d,       0x7b,       0x79,       0x78,
-	      0x76,       0x75,       0x74,       0x72,
-	      0x71,       0x6f,       0x6e,       0x6d,
-	      0x6c,       0x6b,       0x69,       0x67,
-	      0x65,       0x64,       0x61,       0x60,
-	      0x5e,       0x5d,       0x5c,       0x5b,
-	      0x5a,       0x59,       0x58,       0x57,
-	      0x56,       0x55,       0x55,       0x54,
-	      0x53,       0x52,       0x50,       0x4f,
-	      0x4d,       0x4c,       0x4b,       0x49,
-	      0x47,       0x45,       0x44,       0x42,
-	      0x41,       0x3f,       0x3e,       0x3d,
-	      0x3c,       0x3b,       0x39,       0x38,
-	      0x37,       0x36,       0x35,       0x34,
-	      0x33,       0x31,       0x30,       0x2f,
-	      0x2e,       0x2c,       0x2b,       0x2b,
-	      0x29,       0x28,       0x27,       0x26,
-	      0x25,       0x24,       0x22,       0x21,
-	      0x20,       0x1e,       0x1c,       0x19,
-	      0x18,       0x18,       0x17,       0x16,
-	      0x15,       0x14,       0x13,       0x12,
-	      0x11,       0x10,        0xf,        0xe,
-	       0xd,        0xb,        0xa,        0x9,
-	       0x8,        0x6,        0x4,        0x2,
-	       0x1
-};
-
-struct tas_gain_t tas3001c_gain = {
-  .master  = tas3001c_master_tab,
-  .treble  = tas3001c_treble_tab,
-  .bass    = tas3001c_bass_tab,
-  .mixer   = tas3001c_mixer_tab
-};
-
-struct tas_eq_pref_t *tas3001c_eq_prefs[]={
-  &eqp_0e_2_1,
-  &eqp_10_1_0,
-  &eqp_15_2_1,
-  &eqp_15_1_0,
-  &eqp_0f_2_1,
-  &eqp_0f_1_0,
-  NULL
-};
diff --git a/sound/oss/dmasound/tas3004.c b/sound/oss/dmasound/tas3004.c
deleted file mode 100644
index 678bf0f..0000000
--- a/sound/oss/dmasound/tas3004.c
+++ /dev/null
@@ -1,1138 +0,0 @@
-/*
- * Driver for the i2c/i2s based TA3004 sound chip used
- * on some Apple hardware. Also known as "snapper".
- *
- * Tobias Sargeant <tobias.sargeant@bigpond.com>
- * Based upon tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
- *
- * Input support by Renzo Davoli <renzo@cs.unibo.it>
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/soundcard.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-
-#include <asm/uaccess.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-
-#include "dmasound.h"
-#include "tas_common.h"
-#include "tas3004.h"
-
-#include "tas_ioctl.h"
-
-/* #define DEBUG_DRCE */
-
-#define TAS3004_BIQUAD_FILTER_COUNT  7
-#define TAS3004_BIQUAD_CHANNEL_COUNT 2
-
-#define VOL_DEFAULT	(100 * 4 / 5)
-#define INPUT_DEFAULT	(100 * 4 / 5)
-#define BASS_DEFAULT	(100 / 2)
-#define TREBLE_DEFAULT	(100 / 2)
-
-struct tas3004_data_t {
-	struct tas_data_t super;
-	int device_id;
-	int output_id;
-	int speaker_id;
-	struct tas_drce_t drce_state;
-	struct work_struct change;
-};
-
-#define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000)
-
-#define MAKE_RATIO(i,f) (((i)<<8) + ((500+(f)*(1<<8))/1000))
-
-
-static const union tas_biquad_t tas3004_eq_unity = {
-	.buf		 = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 },
-};
-
-
-static const struct tas_drce_t tas3004_drce_min = {
-	.enable		= 1,
-	.above		= { .val = MAKE_RATIO(16,0), .expand = 0 },
-	.below		= { .val = MAKE_RATIO(2,0), .expand = 0 },
-	.threshold	= -0x59a0,
-	.energy		= MAKE_TIME(0,  1700),
-	.attack		= MAKE_TIME(0,  1700),
-	.decay		= MAKE_TIME(0,  1700),
-};
-
-
-static const struct tas_drce_t tas3004_drce_max = {
-	.enable		= 1,
-	.above		= { .val = MAKE_RATIO(1,500), .expand = 1 },
-	.below		= { .val = MAKE_RATIO(2,0), .expand = 1 },
-	.threshold	= -0x0,
-	.energy		= MAKE_TIME(2,400000),
-	.attack		= MAKE_TIME(2,400000),
-	.decay		= MAKE_TIME(2,400000),
-};
-
-
-static const unsigned short time_constants[]={
-	MAKE_TIME(0,  1700),
-	MAKE_TIME(0,  3500),
-	MAKE_TIME(0,  6700),
-	MAKE_TIME(0, 13000),
-	MAKE_TIME(0, 26000),
-	MAKE_TIME(0, 53000),
-	MAKE_TIME(0,106000),
-	MAKE_TIME(0,212000),
-	MAKE_TIME(0,425000),
-	MAKE_TIME(0,850000),
-	MAKE_TIME(1,700000),
-	MAKE_TIME(2,400000),
-};
-
-static const unsigned short above_threshold_compression_ratio[]={
-	MAKE_RATIO( 1, 70),
-	MAKE_RATIO( 1,140),
-	MAKE_RATIO( 1,230),
-	MAKE_RATIO( 1,330),
-	MAKE_RATIO( 1,450),
-	MAKE_RATIO( 1,600),
-	MAKE_RATIO( 1,780),
-	MAKE_RATIO( 2,  0),
-	MAKE_RATIO( 2,290),
-	MAKE_RATIO( 2,670),
-	MAKE_RATIO( 3,200),
-	MAKE_RATIO( 4,  0),
-	MAKE_RATIO( 5,330),
-	MAKE_RATIO( 8,  0),
-	MAKE_RATIO(16,  0),
-};
-
-static const unsigned short above_threshold_expansion_ratio[]={
-	MAKE_RATIO(1, 60),
-	MAKE_RATIO(1,130),
-	MAKE_RATIO(1,190),
-	MAKE_RATIO(1,250),
-	MAKE_RATIO(1,310),
-	MAKE_RATIO(1,380),
-	MAKE_RATIO(1,440),
-	MAKE_RATIO(1,500)
-};
-
-static const unsigned short below_threshold_compression_ratio[]={
-	MAKE_RATIO(1, 70),
-	MAKE_RATIO(1,140),
-	MAKE_RATIO(1,230),
-	MAKE_RATIO(1,330),
-	MAKE_RATIO(1,450),
-	MAKE_RATIO(1,600),
-	MAKE_RATIO(1,780),
-	MAKE_RATIO(2,  0)
-};
-
-static const unsigned short below_threshold_expansion_ratio[]={
-	MAKE_RATIO(1, 60),
-	MAKE_RATIO(1,130),
-	MAKE_RATIO(1,190),
-	MAKE_RATIO(1,250),
-	MAKE_RATIO(1,310),
-	MAKE_RATIO(1,380),
-	MAKE_RATIO(1,440),
-	MAKE_RATIO(1,500),
-	MAKE_RATIO(1,560),
-	MAKE_RATIO(1,630),
-	MAKE_RATIO(1,690),
-	MAKE_RATIO(1,750),
-	MAKE_RATIO(1,810),
-	MAKE_RATIO(1,880),
-	MAKE_RATIO(1,940),
-	MAKE_RATIO(2,  0)
-};
-
-static inline int
-search(	unsigned short val,
-	const unsigned short *arr,
-	const int arrsize) {
-	/*
-	 * This could be a binary search, but for small tables,
-	 * a linear search is likely to be faster
-	 */
-
-	int i;
-
-	for (i=0; i < arrsize; i++)
-		if (arr[i] >= val)
-			goto _1;
-	return arrsize-1;
- _1:
-	if (i == 0)
-		return 0;
-	return (arr[i]-val < val-arr[i-1]) ? i : i-1;
-}
-
-#define SEARCH(a, b) search(a, b, ARRAY_SIZE(b))
-
-static inline int
-time_index(unsigned short time)
-{
-	return SEARCH(time, time_constants);
-}
-
-
-static inline int
-above_threshold_compression_index(unsigned short ratio)
-{
-	return SEARCH(ratio, above_threshold_compression_ratio);
-}
-
-
-static inline int
-above_threshold_expansion_index(unsigned short ratio)
-{
-	return SEARCH(ratio, above_threshold_expansion_ratio);
-}
-
-
-static inline int
-below_threshold_compression_index(unsigned short ratio)
-{
-	return SEARCH(ratio, below_threshold_compression_ratio);
-}
-
-
-static inline int
-below_threshold_expansion_index(unsigned short ratio)
-{
-	return SEARCH(ratio, below_threshold_expansion_ratio);
-}
-
-static inline unsigned char db_to_regval(short db) {
-	int r=0;
-
-	r=(db+0x59a0) / 0x60;
-
-	if (r < 0x91) return 0x91;
-	if (r > 0xef) return 0xef;
-	return r;
-}
-
-static inline short quantize_db(short db)
-{
-	return db_to_regval(db) * 0x60 - 0x59a0;
-}
-
-static inline int
-register_width(enum tas3004_reg_t r)
-{
-	switch(r) {
-	case TAS3004_REG_MCR:
- 	case TAS3004_REG_TREBLE:
-	case TAS3004_REG_BASS:
-	case TAS3004_REG_ANALOG_CTRL:
-	case TAS3004_REG_TEST1:
-	case TAS3004_REG_TEST2:
-	case TAS3004_REG_MCR2:
-		return 1;
-
-	case TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN:
-	case TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN:
-		return 3;
-
-	case TAS3004_REG_DRC:
-	case TAS3004_REG_VOLUME:
-		return 6;
-
-	case TAS3004_REG_LEFT_MIXER:
-	case TAS3004_REG_RIGHT_MIXER:
-		return 9;
-
-	case TAS3004_REG_TEST:
-		return 10;
-
-	case TAS3004_REG_LEFT_BIQUAD0:
-	case TAS3004_REG_LEFT_BIQUAD1:
-	case TAS3004_REG_LEFT_BIQUAD2:
-	case TAS3004_REG_LEFT_BIQUAD3:
-	case TAS3004_REG_LEFT_BIQUAD4:
-	case TAS3004_REG_LEFT_BIQUAD5:
-	case TAS3004_REG_LEFT_BIQUAD6:
-
-	case TAS3004_REG_RIGHT_BIQUAD0:
-	case TAS3004_REG_RIGHT_BIQUAD1:
-	case TAS3004_REG_RIGHT_BIQUAD2:
-	case TAS3004_REG_RIGHT_BIQUAD3:
-	case TAS3004_REG_RIGHT_BIQUAD4:
-	case TAS3004_REG_RIGHT_BIQUAD5:
-	case TAS3004_REG_RIGHT_BIQUAD6:
-
-	case TAS3004_REG_LEFT_LOUD_BIQUAD:
-	case TAS3004_REG_RIGHT_LOUD_BIQUAD:
-		return 15;
-
-	default:
-		return 0;
-	}
-}
-
-static int
-tas3004_write_register(	struct tas3004_data_t *self,
-			enum tas3004_reg_t reg_num,
-			char *data,
-			uint write_mode)
-{
-	if (reg_num==TAS3004_REG_MCR ||
-	    reg_num==TAS3004_REG_BASS ||
-	    reg_num==TAS3004_REG_TREBLE ||
-	    reg_num==TAS3004_REG_ANALOG_CTRL) {
-		return tas_write_byte_register(&self->super,
-					       (uint)reg_num,
-					       *data,
-					       write_mode);
-	} else {
-		return tas_write_register(&self->super,
-					  (uint)reg_num,
-					  register_width(reg_num),
-					  data,
-					  write_mode);
-	}
-}
-
-static int
-tas3004_sync_register(	struct tas3004_data_t *self,
-			enum tas3004_reg_t reg_num)
-{
-	if (reg_num==TAS3004_REG_MCR ||
-	    reg_num==TAS3004_REG_BASS ||
-	    reg_num==TAS3004_REG_TREBLE ||
-	    reg_num==TAS3004_REG_ANALOG_CTRL) {
-		return tas_sync_byte_register(&self->super,
-					      (uint)reg_num,
-					      register_width(reg_num));
-	} else {
-		return tas_sync_register(&self->super,
-					 (uint)reg_num,
-					 register_width(reg_num));
-	}
-}
-
-static int
-tas3004_read_register(	struct tas3004_data_t *self,
-			enum tas3004_reg_t reg_num,
-			char *data,
-			uint write_mode)
-{
-	return tas_read_register(&self->super,
-				 (uint)reg_num,
-				 register_width(reg_num),
-				 data);
-}
-
-static inline int
-tas3004_fast_load(struct tas3004_data_t *self, int fast)
-{
-	if (fast)
-		self->super.shadow[TAS3004_REG_MCR][0] |= 0x80;
-	else
-		self->super.shadow[TAS3004_REG_MCR][0] &= 0x7f;
-	return tas3004_sync_register(self,TAS3004_REG_MCR);
-}
-
-static uint
-tas3004_supported_mixers(struct tas3004_data_t *self)
-{
-	return SOUND_MASK_VOLUME |
-		SOUND_MASK_PCM |
-		SOUND_MASK_ALTPCM |
-		SOUND_MASK_IMIX |
-		SOUND_MASK_TREBLE |
-		SOUND_MASK_BASS |
-		SOUND_MASK_MIC |
-		SOUND_MASK_LINE;
-}
-
-static int
-tas3004_mixer_is_stereo(struct tas3004_data_t *self, int mixer)
-{
-	switch(mixer) {
-	case SOUND_MIXER_VOLUME:
-	case SOUND_MIXER_PCM:
-	case SOUND_MIXER_ALTPCM:
-	case SOUND_MIXER_IMIX:
-		return 1;
-	default:
-		return 0;
-	}
-}
-
-static uint
-tas3004_stereo_mixers(struct tas3004_data_t *self)
-{
-	uint r = tas3004_supported_mixers(self);
-	uint i;
-	
-	for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
-		if (r&(1<<i) && !tas3004_mixer_is_stereo(self,i))
-			r &= ~(1<<i);
-	return r;
-}
-
-static int
-tas3004_get_mixer_level(struct tas3004_data_t *self, int mixer, uint *level)
-{
-	if (!self)
-		return -1;
-
-	*level = self->super.mixer[mixer];
-
-	return 0;
-}
-
-static int
-tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level)
-{
-	int rc;
-	tas_shadow_t *shadow;
-	uint temp;
-	uint offset=0;
-
-	if (!self)
-		return -1;
-
-	shadow = self->super.shadow;
-
-	if (!tas3004_mixer_is_stereo(self,mixer))
-		level = tas_mono_to_stereo(level);
-	switch(mixer) {
-	case SOUND_MIXER_VOLUME:
-		temp = tas3004_gain.master[level&0xff];
-		SET_4_20(shadow[TAS3004_REG_VOLUME], 0, temp);
-		temp = tas3004_gain.master[(level>>8)&0xff];
-		SET_4_20(shadow[TAS3004_REG_VOLUME], 3, temp);
-		rc = tas3004_sync_register(self,TAS3004_REG_VOLUME);
-		break;
-	case SOUND_MIXER_IMIX:
-		offset += 3;
-	case SOUND_MIXER_ALTPCM:
-		offset += 3;
-	case SOUND_MIXER_PCM:
-		/*
-		 * Don't load these in fast mode. The documentation
-		 * says it can be done in either mode, but testing it
-		 * shows that fast mode produces ugly clicking.
-		*/
-		/* tas3004_fast_load(self,1); */
-		temp = tas3004_gain.mixer[level&0xff];
-		SET_4_20(shadow[TAS3004_REG_LEFT_MIXER], offset, temp);
-		temp = tas3004_gain.mixer[(level>>8)&0xff];
-		SET_4_20(shadow[TAS3004_REG_RIGHT_MIXER], offset, temp);
-		rc = tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
-		if (rc == 0)
-			rc=tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
-		/* tas3004_fast_load(self,0); */
-		break;
-	case SOUND_MIXER_TREBLE:
-		temp = tas3004_gain.treble[level&0xff];
-		shadow[TAS3004_REG_TREBLE][0]=temp&0xff;
-		rc = tas3004_sync_register(self,TAS3004_REG_TREBLE);
-		break;
-	case SOUND_MIXER_BASS:
-		temp = tas3004_gain.bass[level&0xff];
-		shadow[TAS3004_REG_BASS][0]=temp&0xff;
-		rc = tas3004_sync_register(self,TAS3004_REG_BASS);
-		break;
-	case SOUND_MIXER_MIC:
-		if ((level&0xff)>0) {
-			software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
-			if (self->super.mixer[mixer] == 0) {
-				self->super.mixer[SOUND_MIXER_LINE] = 0;
-				shadow[TAS3004_REG_ANALOG_CTRL][0]=0xc2;
-				rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
-			} else rc=0;
-		} else {
-			self->super.mixer[SOUND_MIXER_LINE] = SW_INPUT_VOLUME_DEFAULT;
-			software_input_volume = SW_INPUT_VOLUME_SCALE *
-				(self->super.mixer[SOUND_MIXER_LINE]&0xff);
-			shadow[TAS3004_REG_ANALOG_CTRL][0]=0x00;
-			rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
-		}
-		break;
-	case SOUND_MIXER_LINE:
-		if (self->super.mixer[SOUND_MIXER_MIC] == 0) {
-			software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
-			rc=0;
-		}
-		break;
-	default:
-		rc = -1;
-		break;
-	}
-	if (rc < 0)
-		return rc;
-	self->super.mixer[mixer] = level;
-	
-	return 0;
-}
-
-static int
-tas3004_leave_sleep(struct tas3004_data_t *self)
-{
-	unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
-
-	if (!self)
-		return -1;
-
-	/* Make sure something answers on the i2c bus */
-	if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
-	    WRITE_NORMAL | FORCE_WRITE) < 0)
-		return -1;
-
-	tas3004_fast_load(self, 1);
-
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
-
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
-
-	tas3004_fast_load(self, 0);
-
-	(void)tas3004_sync_register(self,TAS3004_REG_VOLUME);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
-	(void)tas3004_sync_register(self,TAS3004_REG_TREBLE);
-	(void)tas3004_sync_register(self,TAS3004_REG_BASS);
-	(void)tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
-
-	return 0;
-}
-
-static int
-tas3004_enter_sleep(struct tas3004_data_t *self)
-{
-	if (!self)
-		return -1; 
-	return 0;
-}
-
-static int
-tas3004_sync_biquad(	struct tas3004_data_t *self,
-			u_int channel,
-			u_int filter)
-{
-	enum tas3004_reg_t reg;
-
-	if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
-	    filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
-
-	reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
-
-	return tas3004_sync_register(self,reg);
-}
-
-static int
-tas3004_write_biquad_shadow(	struct tas3004_data_t *self,
-				u_int channel,
-				u_int filter,
-				const union tas_biquad_t *biquad)
-{
-	tas_shadow_t *shadow=self->super.shadow;
-	enum tas3004_reg_t reg;
-
-	if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
-	    filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
-
-	reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
-
-	SET_4_20(shadow[reg], 0,biquad->coeff.b0);
-	SET_4_20(shadow[reg], 3,biquad->coeff.b1);
-	SET_4_20(shadow[reg], 6,biquad->coeff.b2);
-	SET_4_20(shadow[reg], 9,biquad->coeff.a1);
-	SET_4_20(shadow[reg],12,biquad->coeff.a2);
-
-	return 0;
-}
-
-static int
-tas3004_write_biquad(	struct tas3004_data_t *self,
-			u_int channel,
-			u_int filter,
-			const union tas_biquad_t *biquad)
-{
-	int rc;
-
-	rc=tas3004_write_biquad_shadow(self, channel, filter, biquad);
-	if (rc < 0) return rc;
-
-	return tas3004_sync_biquad(self, channel, filter);
-}
-
-static int
-tas3004_write_biquad_list(	struct tas3004_data_t *self,
-				u_int filter_count,
-				u_int flags,
-				struct tas_biquad_ctrl_t *biquads)
-{
-	int i;
-	int rc;
-
-	if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
-
-	for (i=0; i<filter_count; i++) {
-		rc=tas3004_write_biquad(self,
-					biquads[i].channel,
-					biquads[i].filter,
-					&biquads[i].data);
-		if (rc < 0) break;
-	}
-
-	if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,0);
-
-	return rc;
-}
-
-static int
-tas3004_read_biquad(	struct tas3004_data_t *self,
-			u_int channel,
-			u_int filter,
-			union tas_biquad_t *biquad)
-{
-	tas_shadow_t *shadow=self->super.shadow;
-	enum tas3004_reg_t reg;
-
-	if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
-	    filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
-
-	reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
-
-	biquad->coeff.b0=GET_4_20(shadow[reg], 0);
-	biquad->coeff.b1=GET_4_20(shadow[reg], 3);
-	biquad->coeff.b2=GET_4_20(shadow[reg], 6);
-	biquad->coeff.a1=GET_4_20(shadow[reg], 9);
-	biquad->coeff.a2=GET_4_20(shadow[reg],12);
-	
-	return 0;	
-}
-
-static int
-tas3004_eq_rw(	struct tas3004_data_t *self,
-		u_int cmd,
-		u_long arg)
-{
-	void __user *argp = (void __user *)arg;
-	int rc;
-	struct tas_biquad_ctrl_t biquad;
-
-	if (copy_from_user((void *)&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
-		return -EFAULT;
-	}
-
-	if (cmd & SIOC_IN) {
-		rc=tas3004_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
-		if (rc != 0) return rc;
-	}
-
-	if (cmd & SIOC_OUT) {
-		rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
-		if (rc != 0) return rc;
-
-		if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) {
-			return -EFAULT;
-		}
-
-	}
-	return 0;
-}
-
-static int
-tas3004_eq_list_rw(	struct tas3004_data_t *self,
-			u_int cmd,
-			u_long arg)
-{
-	int rc = 0;
-	int filter_count;
-	int flags;
-	int i,j;
-	char sync_required[TAS3004_BIQUAD_CHANNEL_COUNT][TAS3004_BIQUAD_FILTER_COUNT];
-	struct tas_biquad_ctrl_t biquad;
-	struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg;
-
-	memset(sync_required,0,sizeof(sync_required));
-
-	if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int)))
-		return -EFAULT;
-
-	if (copy_from_user(&flags, &argp->flags, sizeof(int)))
-		return -EFAULT;
-
-	if (cmd & SIOC_IN) {
-	}
-
-	for (i=0; i < filter_count; i++) {
-		if (copy_from_user(&biquad, &argp->biquads[i],
-				   sizeof(struct tas_biquad_ctrl_t))) {
-			return -EFAULT;
-		}
-
-		if (cmd & SIOC_IN) {
-			sync_required[biquad.channel][biquad.filter]=1;
-			rc=tas3004_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
-			if (rc != 0) return rc;
-		}
-
-		if (cmd & SIOC_OUT) {
-			rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
-			if (rc != 0) return rc;
-
-			if (copy_to_user(&argp->biquads[i], &biquad,
-					 sizeof(struct tas_biquad_ctrl_t))) {
-				return -EFAULT;
-			}
-		}
-	}
-
-	if (cmd & SIOC_IN) {
-		/*
-		 * This is OK for the tas3004. For the
-		 * tas3001c, going into fast load mode causes
-		 * the treble and bass to be reset to 0dB, and
-		 * volume controls to be muted.
-		 */
-		if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
-		for (i=0; i<TAS3004_BIQUAD_CHANNEL_COUNT; i++) {
-			for (j=0; j<TAS3004_BIQUAD_FILTER_COUNT; j++) {
-				if (sync_required[i][j]) {
-					rc=tas3004_sync_biquad(self, i, j);
-					if (rc < 0) goto out;
-				}
-			}
-		}
-	out:
-		if (flags & TAS_BIQUAD_FAST_LOAD)
-			tas3004_fast_load(self,0);
-	}
-
-	return rc;
-}
-
-static int
-tas3004_update_drce(	struct tas3004_data_t *self,
-			int flags,
-			struct tas_drce_t *drce)
-{
-	tas_shadow_t *shadow;
-	int i;
-	shadow=self->super.shadow;
-
-	if (flags & TAS_DRCE_ABOVE_RATIO) {
-		self->drce_state.above.expand = drce->above.expand;
-		if (drce->above.val == (1<<8)) {
-			self->drce_state.above.val = 1<<8;
-			shadow[TAS3004_REG_DRC][0] = 0x02;
-					
-		} else if (drce->above.expand) {
-			i=above_threshold_expansion_index(drce->above.val);
-			self->drce_state.above.val=above_threshold_expansion_ratio[i];
-			shadow[TAS3004_REG_DRC][0] = 0x0a + (i<<3);
-		} else {
-			i=above_threshold_compression_index(drce->above.val);
-			self->drce_state.above.val=above_threshold_compression_ratio[i];
-			shadow[TAS3004_REG_DRC][0] = 0x08 + (i<<3);
-		}
-	}
-
-	if (flags & TAS_DRCE_BELOW_RATIO) {
-		self->drce_state.below.expand = drce->below.expand;
-		if (drce->below.val == (1<<8)) {
-			self->drce_state.below.val = 1<<8;
-			shadow[TAS3004_REG_DRC][1] = 0x02;
-					
-		} else if (drce->below.expand) {
-			i=below_threshold_expansion_index(drce->below.val);
-			self->drce_state.below.val=below_threshold_expansion_ratio[i];
-			shadow[TAS3004_REG_DRC][1] = 0x08 + (i<<3);
-		} else {
-			i=below_threshold_compression_index(drce->below.val);
-			self->drce_state.below.val=below_threshold_compression_ratio[i];
-			shadow[TAS3004_REG_DRC][1] = 0x0a + (i<<3);
-		}
-	}
-
-	if (flags & TAS_DRCE_THRESHOLD) {
-		self->drce_state.threshold=quantize_db(drce->threshold);
-		shadow[TAS3004_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
-	}
-
-	if (flags & TAS_DRCE_ENERGY) {
-		i=time_index(drce->energy);
-		self->drce_state.energy=time_constants[i];
-		shadow[TAS3004_REG_DRC][3] = 0x40 + (i<<4);
-	}
-
-	if (flags & TAS_DRCE_ATTACK) {
-		i=time_index(drce->attack);
-		self->drce_state.attack=time_constants[i];
-		shadow[TAS3004_REG_DRC][4] = 0x40 + (i<<4);
-	}
-
-	if (flags & TAS_DRCE_DECAY) {
-		i=time_index(drce->decay);
-		self->drce_state.decay=time_constants[i];
-		shadow[TAS3004_REG_DRC][5] = 0x40 + (i<<4);
-	}
-
-	if (flags & TAS_DRCE_ENABLE) {
-		self->drce_state.enable = drce->enable;
-	}
-
-	if (!self->drce_state.enable) {
-		shadow[TAS3004_REG_DRC][0] |= 0x01;
-	}
-
-#ifdef DEBUG_DRCE
-	printk("DRCE: set [ ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
-	       self->drce_state.enable,
-	       self->drce_state.above.expand,self->drce_state.above.val,
-	       self->drce_state.below.expand,self->drce_state.below.val,
-	       self->drce_state.threshold,
-	       self->drce_state.energy,
-	       self->drce_state.attack,
-	       self->drce_state.decay);
-
-	printk("DRCE: reg [ %02x %02x %02x %02x %02x %02x ]\n",
-	       (unsigned char)shadow[TAS3004_REG_DRC][0],
-	       (unsigned char)shadow[TAS3004_REG_DRC][1],
-	       (unsigned char)shadow[TAS3004_REG_DRC][2],
-	       (unsigned char)shadow[TAS3004_REG_DRC][3],
-	       (unsigned char)shadow[TAS3004_REG_DRC][4],
-	       (unsigned char)shadow[TAS3004_REG_DRC][5]);
-#endif
-
-	return tas3004_sync_register(self, TAS3004_REG_DRC);
-}
-
-static int
-tas3004_drce_rw(	struct tas3004_data_t *self,
-			u_int cmd,
-			u_long arg)
-{
-	int rc;
-	struct tas_drce_ctrl_t drce_ctrl;
-	void __user *argp = (void __user *)arg;
-
-	if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t)))
-		return -EFAULT;
-
-#ifdef DEBUG_DRCE
-	printk("DRCE: input [ FLAGS:%x ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
-	       drce_ctrl.flags,
-	       drce_ctrl.data.enable,
-	       drce_ctrl.data.above.expand,drce_ctrl.data.above.val,
-	       drce_ctrl.data.below.expand,drce_ctrl.data.below.val,
-	       drce_ctrl.data.threshold,
-	       drce_ctrl.data.energy,
-	       drce_ctrl.data.attack,
-	       drce_ctrl.data.decay);
-#endif
-
-	if (cmd & SIOC_IN) {
-		rc = tas3004_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
-		if (rc < 0) return rc;
-	}
-
-	if (cmd & SIOC_OUT) {
-		if (drce_ctrl.flags & TAS_DRCE_ENABLE)
-			drce_ctrl.data.enable = self->drce_state.enable;
-		if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO)
-			drce_ctrl.data.above = self->drce_state.above;
-		if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO)
-			drce_ctrl.data.below = self->drce_state.below;
-		if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
-			drce_ctrl.data.threshold = self->drce_state.threshold;
-		if (drce_ctrl.flags & TAS_DRCE_ENERGY)
-			drce_ctrl.data.energy = self->drce_state.energy;
-		if (drce_ctrl.flags & TAS_DRCE_ATTACK)
-			drce_ctrl.data.attack = self->drce_state.attack;
-		if (drce_ctrl.flags & TAS_DRCE_DECAY)
-			drce_ctrl.data.decay = self->drce_state.decay;
-
-		if (copy_to_user(argp, &drce_ctrl,
-				 sizeof(struct tas_drce_ctrl_t))) {
-			return -EFAULT;
-		}
-	}
-
-	return 0;
-}
-
-static void
-tas3004_update_device_parameters(struct tas3004_data_t *self)
-{
-	char data;
-	int i;
-
-	if (!self) return;
-
-	if (self->output_id == TAS_OUTPUT_HEADPHONES) {
-		/* turn on allPass when headphones are plugged in */
-		data = 0x02;
-	} else {
-		data = 0x00;
-	}
-
-	tas3004_write_register(self, TAS3004_REG_MCR2, &data, WRITE_NORMAL | FORCE_WRITE);
-
-	for (i=0; tas3004_eq_prefs[i]; i++) {
-		struct tas_eq_pref_t *eq = tas3004_eq_prefs[i];
-
-		if (eq->device_id == self->device_id &&
-		    (eq->output_id == 0 || eq->output_id == self->output_id) &&
-		    (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
-
-			tas3004_update_drce(self, TAS_DRCE_ALL, eq->drce);
-			tas3004_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
-
-			break;
-		}
-	}
-}
-
-static void
-tas3004_device_change_handler(struct work_struct *work)
-{
-	struct tas3004_data_t *self;
-	self = container_of(work, struct tas3004_data_t, change);
-	tas3004_update_device_parameters(self);
-}
-
-static int
-tas3004_output_device_change(	struct tas3004_data_t *self,
-				int device_id,
-				int output_id,
-				int speaker_id)
-{
-	self->device_id=device_id;
-	self->output_id=output_id;
-	self->speaker_id=speaker_id;
-
-	schedule_work(&self->change);
-
-	return 0;
-}
-
-static int
-tas3004_device_ioctl(	struct tas3004_data_t *self,
-			u_int cmd,
-			u_long arg)
-{
-	uint __user *argp = (void __user *)arg;
-	switch (cmd) {
-	case TAS_READ_EQ:
-	case TAS_WRITE_EQ:
-		return tas3004_eq_rw(self, cmd, arg);
-
-	case TAS_READ_EQ_LIST:
-	case TAS_WRITE_EQ_LIST:
-		return tas3004_eq_list_rw(self, cmd, arg);
-
-	case TAS_READ_EQ_FILTER_COUNT:
-		put_user(TAS3004_BIQUAD_FILTER_COUNT, argp);
-		return 0;
-
-	case TAS_READ_EQ_CHANNEL_COUNT:
-		put_user(TAS3004_BIQUAD_CHANNEL_COUNT, argp);
-		return 0;
-
-	case TAS_READ_DRCE:
-	case TAS_WRITE_DRCE:
-		return tas3004_drce_rw(self, cmd, arg);
-
-	case TAS_READ_DRCE_CAPS:
-		put_user(TAS_DRCE_ENABLE         |
-			 TAS_DRCE_ABOVE_RATIO    |
-			 TAS_DRCE_BELOW_RATIO    |
-			 TAS_DRCE_THRESHOLD      |
-			 TAS_DRCE_ENERGY         |
-			 TAS_DRCE_ATTACK         |
-			 TAS_DRCE_DECAY,
-			 argp);
-		return 0;
-
-	case TAS_READ_DRCE_MIN:
-	case TAS_READ_DRCE_MAX: {
-		struct tas_drce_ctrl_t drce_ctrl;
-		const struct tas_drce_t *drce_copy;
-
-		if (copy_from_user(&drce_ctrl, argp,
-				   sizeof(struct tas_drce_ctrl_t))) {
-			return -EFAULT;
-		}
-
-		if (cmd == TAS_READ_DRCE_MIN) {
-			drce_copy=&tas3004_drce_min;
-		} else {
-			drce_copy=&tas3004_drce_max;
-		}
-
-		if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) {
-			drce_ctrl.data.above=drce_copy->above;
-		}
-		if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) {
-			drce_ctrl.data.below=drce_copy->below;
-		}
-		if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
-			drce_ctrl.data.threshold=drce_copy->threshold;
-		}
-		if (drce_ctrl.flags & TAS_DRCE_ENERGY) {
-			drce_ctrl.data.energy=drce_copy->energy;
-		}
-		if (drce_ctrl.flags & TAS_DRCE_ATTACK) {
-			drce_ctrl.data.attack=drce_copy->attack;
-		}
-		if (drce_ctrl.flags & TAS_DRCE_DECAY) {
-			drce_ctrl.data.decay=drce_copy->decay;
-		}
-
-		if (copy_to_user(argp, &drce_ctrl,
-				 sizeof(struct tas_drce_ctrl_t))) {
-			return -EFAULT;
-		}
-	}
-	}
-
-	return -EINVAL;
-}
-
-static int
-tas3004_init_mixer(struct tas3004_data_t *self)
-{
-	unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
-
-	/* Make sure something answers on the i2c bus */
-	if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
-	    WRITE_NORMAL | FORCE_WRITE) < 0)
-		return -1;
-
-	tas3004_fast_load(self, 1);
-
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
-	(void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
-
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
-	(void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
-
-	tas3004_sync_register(self, TAS3004_REG_DRC);
-
-	tas3004_sync_register(self, TAS3004_REG_MCR2);
-
-	tas3004_fast_load(self, 0);
-
-	tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
-	tas3004_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
-	tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
-	tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
-
-	tas3004_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
-	tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
-
-	tas3004_set_mixer_level(self, SOUND_MIXER_LINE,SW_INPUT_VOLUME_DEFAULT);
-
-	return 0;
-}
-
-static int
-tas3004_uninit_mixer(struct tas3004_data_t *self)
-{
-	tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
-	tas3004_set_mixer_level(self, SOUND_MIXER_PCM, 0);
-	tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
-	tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
-
-	tas3004_set_mixer_level(self, SOUND_MIXER_BASS, 0);
-	tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
-
-	tas3004_set_mixer_level(self, SOUND_MIXER_LINE, 0);
-
-	return 0;
-}
-
-static int
-tas3004_init(struct i2c_client *client)
-{
-	struct tas3004_data_t *self;
-	size_t sz = sizeof(*self) + (TAS3004_REG_MAX*sizeof(tas_shadow_t));
-	char drce_init[] = { 0x69, 0x22, 0x9f, 0xb0, 0x60, 0xa0 };
-	char mcr2 = 0;
-	int i, j;
-
-	self = kzalloc(sz, GFP_KERNEL);
-	if (!self)
-		return -ENOMEM;
-
-	self->super.client = client;
-	self->super.shadow = (tas_shadow_t *)(self+1);
-	self->output_id = TAS_OUTPUT_HEADPHONES;
-
-	dev_set_drvdata(&client->dev, self);
-
-	for (i = 0; i < TAS3004_BIQUAD_CHANNEL_COUNT; i++)
-		for (j = 0; j<TAS3004_BIQUAD_FILTER_COUNT; j++)
-			tas3004_write_biquad_shadow(self, i, j,
-					&tas3004_eq_unity);
-
-	tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW);
-	tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW);
-
-	INIT_WORK(&self->change, tas3004_device_change_handler);
-	return 0;
-}
-
-static void 
-tas3004_uninit(struct tas3004_data_t *self)
-{
-	tas3004_uninit_mixer(self);
-	kfree(self);
-}
-
-
-struct tas_driver_hooks_t tas3004_hooks = {
-	.init			= (tas_hook_init_t)tas3004_init,
-	.post_init		= (tas_hook_post_init_t)tas3004_init_mixer,
-	.uninit			= (tas_hook_uninit_t)tas3004_uninit,
-	.get_mixer_level	= (tas_hook_get_mixer_level_t)tas3004_get_mixer_level,
-	.set_mixer_level	= (tas_hook_set_mixer_level_t)tas3004_set_mixer_level,
-	.enter_sleep		= (tas_hook_enter_sleep_t)tas3004_enter_sleep,
-	.leave_sleep		= (tas_hook_leave_sleep_t)tas3004_leave_sleep,
-	.supported_mixers	= (tas_hook_supported_mixers_t)tas3004_supported_mixers,
-	.mixer_is_stereo	= (tas_hook_mixer_is_stereo_t)tas3004_mixer_is_stereo,
-	.stereo_mixers		= (tas_hook_stereo_mixers_t)tas3004_stereo_mixers,
-	.output_device_change	= (tas_hook_output_device_change_t)tas3004_output_device_change,
-	.device_ioctl		= (tas_hook_device_ioctl_t)tas3004_device_ioctl
-};
diff --git a/sound/oss/dmasound/tas3004.h b/sound/oss/dmasound/tas3004.h
deleted file mode 100644
index c6d584b..0000000
--- a/sound/oss/dmasound/tas3004.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Header file for the i2c/i2s based TA3004 sound chip used
- * on some Apple hardware. Also known as "tumbler".
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive
- *  for more details.
- *
- * Written by Christopher C. Chimelis <chris@debian.org>
- */
-
-#ifndef _TAS3004_H_
-#define _TAS3004_H_
-
-#include <linux/types.h>
-
-#include "tas_common.h"
-#include "tas_eq_prefs.h"
-
-/*
- * Macros that correspond to the registers that we write to
- * when setting the various values.
- */
-
-#define TAS3004_VERSION	        "0.3"
-#define TAS3004_DATE	        "20011214"
-
-#define I2C_DRIVERNAME_TAS3004 "TAS3004 driver V " TAS3004_VERSION
-#define I2C_DRIVERID_TAS3004    (I2C_DRIVERID_TAS_BASE+1)
-
-extern  struct tas_driver_hooks_t tas3004_hooks;
-extern struct tas_gain_t tas3004_gain;
-extern struct tas_eq_pref_t *tas3004_eq_prefs[];
-
-enum tas3004_reg_t {
-  TAS3004_REG_MCR                    = 0x01,
-  TAS3004_REG_DRC                    = 0x02,
-
-  TAS3004_REG_VOLUME                 = 0x04,
-  TAS3004_REG_TREBLE                 = 0x05,
-  TAS3004_REG_BASS                   = 0x06,
-  TAS3004_REG_LEFT_MIXER             = 0x07,
-  TAS3004_REG_RIGHT_MIXER            = 0x08,
-
-  TAS3004_REG_LEFT_BIQUAD0           = 0x0a,
-  TAS3004_REG_LEFT_BIQUAD1           = 0x0b,
-  TAS3004_REG_LEFT_BIQUAD2           = 0x0c,
-  TAS3004_REG_LEFT_BIQUAD3           = 0x0d,
-  TAS3004_REG_LEFT_BIQUAD4           = 0x0e,
-  TAS3004_REG_LEFT_BIQUAD5           = 0x0f,
-  TAS3004_REG_LEFT_BIQUAD6           = 0x10,
-  
-  TAS3004_REG_RIGHT_BIQUAD0          = 0x13,
-  TAS3004_REG_RIGHT_BIQUAD1          = 0x14,
-  TAS3004_REG_RIGHT_BIQUAD2          = 0x15,
-  TAS3004_REG_RIGHT_BIQUAD3          = 0x16,
-  TAS3004_REG_RIGHT_BIQUAD4          = 0x17,
-  TAS3004_REG_RIGHT_BIQUAD5          = 0x18,
-  TAS3004_REG_RIGHT_BIQUAD6          = 0x19,
-
-  TAS3004_REG_LEFT_LOUD_BIQUAD       = 0x21,
-  TAS3004_REG_RIGHT_LOUD_BIQUAD      = 0x22,
-
-  TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN  = 0x23,
-  TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN = 0x24,
-
-  TAS3004_REG_TEST                   = 0x29,
-
-  TAS3004_REG_ANALOG_CTRL            = 0x40,
-  TAS3004_REG_TEST1                  = 0x41,
-  TAS3004_REG_TEST2                  = 0x42,
-  TAS3004_REG_MCR2                   = 0x43,
-
-  TAS3004_REG_MAX                    = 0x44
-};
-
-#endif /* _TAS3004_H_ */
diff --git a/sound/oss/dmasound/tas3004_tables.c b/sound/oss/dmasound/tas3004_tables.c
deleted file mode 100644
index b910e0a..0000000
--- a/sound/oss/dmasound/tas3004_tables.c
+++ /dev/null
@@ -1,301 +0,0 @@
-#include "tas3004.h"
-#include "tas_eq_prefs.h"
-
-static struct tas_drce_t eqp_17_1_0_drce={
-    .enable     = 1,
-    .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-    .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-    .threshold  = -19.12  * (1<<8),
-    .energy     = 2.4     * (1<<12),
-    .attack     = 0.013   * (1<<12),
-    .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_17_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
-  { .channel = 0, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
-  { .channel = 1, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } }
-};
-
-static struct tas_eq_pref_t eqp_17_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x17,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_17_1_0_drce,
-
-  .filter_count  = 14,
-  .biquads       = eqp_17_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_18_1_0_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -13.14  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_18_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
-  { .channel = 0, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
-  { .channel = 1, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }
-};
-
-static struct tas_eq_pref_t eqp_18_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x18,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_18_1_0_drce,
-
-  .filter_count  = 14,
-  .biquads       = eqp_18_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_1a_1_0_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -10.75  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_1a_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
-  { .channel = 0, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
-  { .channel = 1, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } }
-};
-
-static struct tas_eq_pref_t eqp_1a_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x1a,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_1a_1_0_drce,
-
-  .filter_count  = 14,
-  .biquads       = eqp_1a_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_1c_1_0_drce={
-  .enable     = 1,
-  .above      = { .val = 3.0 * (1<<8), .expand = 0 },
-  .below      = { .val = 1.0 * (1<<8), .expand = 0 },
-  .threshold  = -14.34  * (1<<8),
-  .energy     = 2.4     * (1<<12),
-  .attack     = 0.013   * (1<<12),
-  .decay      = 0.212   * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_1c_1_0_biquads[]={
-  { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
-  { .channel = 0, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
-  { .channel = 0, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
-  { .channel = 0, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
-  { .channel = 0, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
-  { .channel = 0, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
-  { .channel = 0, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } },
-
-  { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
-  { .channel = 1, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
-  { .channel = 1, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
-  { .channel = 1, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
-  { .channel = 1, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
-  { .channel = 1, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
-  { .channel = 1, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } }
-};
-
-static struct tas_eq_pref_t eqp_1c_1_0 = {
-  .sample_rate   = 44100,
-  .device_id     = 0x1c,
-  .output_id     = TAS_OUTPUT_INTERNAL_SPKR,
-  .speaker_id    = 0x00,
-
-  .drce          = &eqp_1c_1_0_drce,
-
-  .filter_count  = 14,
-  .biquads       = eqp_1c_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static uint tas3004_master_tab[]={
-	       0x0,       0x75,       0x9c,       0xbb,
-	      0xdb,       0xfb,      0x11e,      0x143,
-	     0x16b,      0x196,      0x1c3,      0x1f5,
-	     0x229,      0x263,      0x29f,      0x2e1,
-	     0x328,      0x373,      0x3c5,      0x41b,
-	     0x478,      0x4dc,      0x547,      0x5b8,
-	     0x633,      0x6b5,      0x740,      0x7d5,
-	     0x873,      0x91c,      0x9d2,      0xa92,
-	     0xb5e,      0xc39,      0xd22,      0xe19,
-	     0xf20,     0x1037,     0x1161,     0x129e,
-	    0x13ed,     0x1551,     0x16ca,     0x185d,
-	    0x1a08,     0x1bcc,     0x1dac,     0x1fa7,
-	    0x21c1,     0x23fa,     0x2655,     0x28d6,
-	    0x2b7c,     0x2e4a,     0x3141,     0x3464,
-	    0x37b4,     0x3b35,     0x3ee9,     0x42d3,
-	    0x46f6,     0x4b53,     0x4ff0,     0x54ce,
-	    0x59f2,     0x5f5f,     0x6519,     0x6b24,
-	    0x7183,     0x783c,     0x7f53,     0x86cc,
-	    0x8ead,     0x96fa,     0x9fba,     0xa8f2,
-	    0xb2a7,     0xbce1,     0xc7a5,     0xd2fa,
-	    0xdee8,     0xeb75,     0xf8aa,    0x1068e,
-	   0x1152a,    0x12487,    0x134ad,    0x145a5,
-	   0x1577b,    0x16a37,    0x17df5,    0x192bd,
-	   0x1a890,    0x1bf7b,    0x1d78d,    0x1f0d1,
-	   0x20b55,    0x22727,    0x24456,    0x262f2,
-	   0x2830b
-};
-
-static uint tas3004_mixer_tab[]={
-	       0x0,      0x748,      0x9be,      0xbaf,
-	     0xda4,      0xfb1,     0x11de,     0x1431,
-	    0x16ad,     0x1959,     0x1c37,     0x1f4b,
-	    0x2298,     0x2628,     0x29fb,     0x2e12,
-	    0x327d,     0x3734,     0x3c47,     0x41b4,
-	    0x4787,     0x4dbe,     0x546d,     0x5b86,
-	    0x632e,     0x6b52,     0x7400,     0x7d54,
-	    0x873b,     0x91c6,     0x9d1a,     0xa920,
-	    0xb5e5,     0xc38c,     0xd21b,     0xe18f,
-	    0xf1f5,    0x1036a,    0x1160f,    0x129d6,
-	   0x13ed0,    0x1550c,    0x16ca0,    0x185c9,
-	   0x1a07b,    0x1bcc3,    0x1dab9,    0x1fa75,
-	   0x21c0f,    0x23fa3,    0x26552,    0x28d64,
-	   0x2b7c9,    0x2e4a2,    0x31411,    0x3463b,
-	   0x37b44,    0x3b353,    0x3ee94,    0x42d30,
-	   0x46f55,    0x4b533,    0x4fefc,    0x54ce5,
-	   0x59f25,    0x5f5f6,    0x65193,    0x6b23c,
-	   0x71835,    0x783c3,    0x7f52c,    0x86cc0,
-	   0x8eacc,    0x96fa5,    0x9fba0,    0xa8f1a,
-	   0xb2a71,    0xbce0a,    0xc7a4a,    0xd2fa0,
-	   0xdee7b,    0xeb752,    0xf8a9f,   0x1068e4,
-	  0x1152a3,   0x12486a,   0x134ac8,   0x145a55,
-	  0x1577ac,   0x16a370,   0x17df51,   0x192bc2,
-	  0x1a88f8,   0x1bf7b7,   0x1d78c9,   0x1f0d04,
-	  0x20b542,   0x227268,   0x244564,   0x262f26,
-	  0x2830af
-};
-
-static uint tas3004_treble_tab[]={
-	      0x96,       0x95,       0x95,       0x94,
-	      0x93,       0x92,       0x92,       0x91,
-	      0x90,       0x90,       0x8f,       0x8e,
-	      0x8d,       0x8d,       0x8c,       0x8b,
-	      0x8a,       0x8a,       0x89,       0x88,
-	      0x88,       0x87,       0x86,       0x85,
-	      0x85,       0x84,       0x83,       0x83,
-	      0x82,       0x81,       0x80,       0x80,
-	      0x7f,       0x7e,       0x7e,       0x7d,
-	      0x7c,       0x7b,       0x7b,       0x7a,
-	      0x79,       0x78,       0x78,       0x77,
-	      0x76,       0x76,       0x75,       0x74,
-	      0x73,       0x73,       0x72,       0x71,
-	      0x71,       0x68,       0x45,       0x5b,
-	      0x6d,       0x6c,       0x6b,       0x6a,
-	      0x69,       0x68,       0x67,       0x66,
-	      0x65,       0x63,       0x62,       0x62,
-	      0x60,       0x5e,       0x5c,       0x5b,
-	      0x59,       0x57,       0x55,       0x53,
-	      0x52,       0x4f,       0x4d,       0x4a,
-	      0x48,       0x46,       0x43,       0x40,
-	      0x3d,       0x3a,       0x36,       0x33,
-	      0x2f,       0x2c,       0x27,       0x23,
-	      0x1f,       0x1a,       0x15,        0xf,
-	       0x8,        0x5,        0x2,        0x1,
-	       0x1
-};
-
-static uint tas3004_bass_tab[]={
-	      0x96,       0x95,       0x95,       0x94,
-	      0x93,       0x92,       0x92,       0x91,
-	      0x90,       0x90,       0x8f,       0x8e,
-	      0x8d,       0x8d,       0x8c,       0x8b,
-	      0x8a,       0x8a,       0x89,       0x88,
-	      0x88,       0x87,       0x86,       0x85,
-	      0x85,       0x84,       0x83,       0x83,
-	      0x82,       0x81,       0x80,       0x80,
-	      0x7f,       0x7e,       0x7e,       0x7d,
-	      0x7c,       0x7b,       0x7b,       0x7a,
-	      0x79,       0x78,       0x78,       0x77,
-	      0x76,       0x76,       0x75,       0x74,
-	      0x73,       0x73,       0x72,       0x71,
-	      0x70,       0x6f,       0x6e,       0x6d,
-	      0x6c,       0x6b,       0x6a,       0x6a,
-	      0x69,       0x67,       0x66,       0x66,
-	      0x65,       0x63,       0x62,       0x62,
-	      0x61,       0x60,       0x5e,       0x5d,
-	      0x5b,       0x59,       0x57,       0x55,
-	      0x53,       0x51,       0x4f,       0x4c,
-	      0x4a,       0x48,       0x46,       0x44,
-	      0x41,       0x3e,       0x3b,       0x38,
-	      0x36,       0x33,       0x2f,       0x2b,
-	      0x28,       0x24,       0x20,       0x1c,
-	      0x17,       0x12,        0xd,        0x7,
-	       0x1
-};
-
-struct tas_gain_t tas3004_gain={
-  .master  = tas3004_master_tab,
-  .treble  = tas3004_treble_tab,
-  .bass    = tas3004_bass_tab,
-  .mixer   = tas3004_mixer_tab
-};
-
-struct tas_eq_pref_t *tas3004_eq_prefs[]={
-  &eqp_17_1_0,
-  &eqp_18_1_0,
-  &eqp_1a_1_0,
-  &eqp_1c_1_0,
-  NULL
-};
diff --git a/sound/oss/dmasound/tas_common.c b/sound/oss/dmasound/tas_common.c
deleted file mode 100644
index b295ef6..0000000
--- a/sound/oss/dmasound/tas_common.c
+++ /dev/null
@@ -1,214 +0,0 @@
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/soundcard.h>
-#include <asm/uaccess.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-
-#include "tas_common.h"
-
-#define CALL0(proc)								\
-	do {									\
-		struct tas_data_t *self;					\
-		if (!tas_client || driver_hooks == NULL)			\
-			return -1;						\
-		self = dev_get_drvdata(&tas_client->dev);			\
-		if (driver_hooks->proc)						\
-			return driver_hooks->proc(self);			\
-		else								\
-			return -EINVAL;						\
-	} while (0)
-
-#define CALL(proc,arg...)							\
-	do {									\
-		struct tas_data_t *self;					\
-		if (!tas_client || driver_hooks == NULL)			\
-			return -1;						\
-		self = dev_get_drvdata(&tas_client->dev);			\
-		if (driver_hooks->proc)						\
-			return driver_hooks->proc(self, ## arg);		\
-		else								\
-			return -EINVAL;						\
-	} while (0)
-
-
-static u8 tas_i2c_address = 0x34;
-static struct i2c_client *tas_client;
-
-static int tas_attach_adapter(struct i2c_adapter *);
-static int tas_detach_client(struct i2c_client *);
-
-struct i2c_driver tas_driver = {
-	.driver = {
-		.name	= "tas",
-	},
-	.attach_adapter	= tas_attach_adapter,
-	.detach_client	= tas_detach_client,
-};
-
-struct tas_driver_hooks_t *driver_hooks;
-
-int
-tas_register_driver(struct tas_driver_hooks_t *hooks)
-{
-	driver_hooks = hooks;
-	return 0;
-}
-
-int
-tas_get_mixer_level(int mixer, uint *level)
-{
-	CALL(get_mixer_level,mixer,level);
-}
-
-int
-tas_set_mixer_level(int mixer,uint level)
-{
-	CALL(set_mixer_level,mixer,level);
-}
-
-int
-tas_enter_sleep(void)
-{
-	CALL0(enter_sleep);
-}
-
-int
-tas_leave_sleep(void)
-{
-	CALL0(leave_sleep);
-}
-
-int
-tas_supported_mixers(void)
-{
-	CALL0(supported_mixers);
-}
-
-int
-tas_mixer_is_stereo(int mixer)
-{
-	CALL(mixer_is_stereo,mixer);
-}
-
-int
-tas_stereo_mixers(void)
-{
-	CALL0(stereo_mixers);
-}
-
-int
-tas_output_device_change(int device_id,int layout_id,int speaker_id)
-{
-	CALL(output_device_change,device_id,layout_id,speaker_id);
-}
-
-int
-tas_device_ioctl(u_int cmd, u_long arg)
-{
-	CALL(device_ioctl,cmd,arg);
-}
-
-int
-tas_post_init(void)
-{
-	CALL0(post_init);
-}
-
-static int
-tas_detect_client(struct i2c_adapter *adapter, int address)
-{
-	static const char *client_name = "tas Digital Equalizer";
-	struct i2c_client *new_client;
-	int rc = -ENODEV;
-
-	if (!driver_hooks) {
-		printk(KERN_ERR "tas_detect_client called with no hooks !\n");
-		return -ENODEV;
-	}
-	
-	new_client = kzalloc(sizeof(*new_client), GFP_KERNEL);
-	if (!new_client)
-		return -ENOMEM;
-
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &tas_driver;
-	strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
-
-        if (driver_hooks->init(new_client))
-		goto bail;
-
-	/* Tell the i2c layer a new client has arrived */
-	if (i2c_attach_client(new_client)) {
-		driver_hooks->uninit(dev_get_drvdata(&new_client->dev));
-		goto bail;
-	}
-
-	tas_client = new_client;
-	return 0;
- bail:
-	tas_client = NULL;
-	kfree(new_client);
-	return rc;
-}
-
-static int
-tas_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!strncmp(adapter->name, "mac-io", 6))
-		return tas_detect_client(adapter, tas_i2c_address);
-	return 0;
-}
-
-static int
-tas_detach_client(struct i2c_client *client)
-{
-	if (client == tas_client) {
-		driver_hooks->uninit(dev_get_drvdata(&client->dev));
-
-		i2c_detach_client(client);
-		kfree(client);
-	}
-	return 0;
-}
-
-void
-tas_cleanup(void)
-{
-	i2c_del_driver(&tas_driver);
-}
-
-int __init
-tas_init(int driver_id, const char *driver_name)
-{
-	const u32* paddr;
-	struct device_node *tas_node;
-
-	printk(KERN_INFO "tas driver [%s])\n", driver_name);
-
-#ifndef CONFIG_I2C_POWERMAC
-	request_module("i2c-powermac");
-#endif
-	tas_node = of_find_node_by_name("deq");
-	if (tas_node == NULL)
-		return -ENODEV;
-	paddr = of_get_property(tas_node, "i2c-address", NULL);
-	if (paddr) {
-		tas_i2c_address = (*paddr) >> 1;
-		printk(KERN_INFO "using i2c address: 0x%x from device-tree\n",
-				tas_i2c_address);
-	} else    
-		printk(KERN_INFO "using i2c address: 0x%x (default)\n",
-				tas_i2c_address);
-	of_node_put(tas_node);
-
-	return i2c_add_driver(&tas_driver);
-}
diff --git a/sound/oss/dmasound/tas_common.h b/sound/oss/dmasound/tas_common.h
deleted file mode 100644
index 0741c28..0000000
--- a/sound/oss/dmasound/tas_common.h
+++ /dev/null
@@ -1,284 +0,0 @@
-#ifndef _TAS_COMMON_H_
-#define _TAS_COMMON_H_
-
-#include <linux/i2c.h>
-#include <linux/soundcard.h>
-#include <asm/string.h>
-
-#define I2C_DRIVERID_TAS_BASE   (0xFEBA)
-
-#define SET_4_20(shadow, offset, val)                        \
-	do {                                                 \
-		(shadow)[(offset)+0] = ((val) >> 16) & 0xff; \
-		(shadow)[(offset)+1] = ((val) >> 8)  & 0xff; \
-		(shadow)[(offset)+2] = ((val) >> 0)  & 0xff; \
-	} while (0)
-
-#define GET_4_20(shadow, offset)                             \
-	(((u_int)((shadow)[(offset)+0]) << 16) |             \
-	 ((u_int)((shadow)[(offset)+1]) <<  8) |             \
-	 ((u_int)((shadow)[(offset)+2]) <<  0))
-
-
-#define TAS_BIQUAD_FAST_LOAD 0x01
-
-#define TAS_DRCE_ENABLE           0x01
-#define TAS_DRCE_ABOVE_RATIO      0x02
-#define TAS_DRCE_BELOW_RATIO      0x04
-#define TAS_DRCE_THRESHOLD        0x08
-#define TAS_DRCE_ENERGY           0x10
-#define TAS_DRCE_ATTACK           0x20
-#define TAS_DRCE_DECAY            0x40
-
-#define TAS_DRCE_ALL              0x7f
-
-
-#define TAS_OUTPUT_HEADPHONES     0x00
-#define TAS_OUTPUT_INTERNAL_SPKR  0x01
-#define TAS_OUTPUT_EXTERNAL_SPKR  0x02
-
-
-union tas_biquad_t {
-	struct {
-		int b0,b1,b2,a1,a2;
-	} coeff;
-	int buf[5];
-};
-
-struct tas_biquad_ctrl_t {
-	u_int channel:4;
-	u_int filter:4;
-
-	union tas_biquad_t data;
-};
-
-struct tas_biquad_ctrl_list_t {
-	int flags;
-	int filter_count;
-	struct tas_biquad_ctrl_t biquads[0];
-};
-
-struct tas_ratio_t {
-	unsigned short val;    /* 8.8                        */
-	unsigned short expand; /* 0 = compress, !0 = expand. */
-};
-
-struct tas_drce_t {
-	unsigned short enable;
-	struct tas_ratio_t above;
-	struct tas_ratio_t below;
-	short threshold;       /* dB,       8.8 signed    */
-	unsigned short energy; /* seconds,  4.12 unsigned */
-	unsigned short attack; /* seconds,  4.12 unsigned */
-	unsigned short decay;  /* seconds,  4.12 unsigned */
-};
-
-struct tas_drce_ctrl_t {
-	uint flags;
-
-	struct tas_drce_t data;
-};
-
-struct tas_gain_t
-{
-  unsigned int *master;
-  unsigned int *treble;
-  unsigned int *bass;
-  unsigned int *mixer;
-};
-
-typedef char tas_shadow_t[0x45];
-
-struct tas_data_t
-{
-	struct i2c_client *client;
-	tas_shadow_t *shadow;
-	uint mixer[SOUND_MIXER_NRDEVICES];
-};
-
-typedef int (*tas_hook_init_t)(struct i2c_client *);
-typedef int (*tas_hook_post_init_t)(struct tas_data_t *);
-typedef void (*tas_hook_uninit_t)(struct tas_data_t *);
-
-typedef int (*tas_hook_get_mixer_level_t)(struct tas_data_t *,int,uint *);
-typedef int (*tas_hook_set_mixer_level_t)(struct tas_data_t *,int,uint);
-
-typedef int (*tas_hook_enter_sleep_t)(struct tas_data_t *);
-typedef int (*tas_hook_leave_sleep_t)(struct tas_data_t *);
-
-typedef int (*tas_hook_supported_mixers_t)(struct tas_data_t *);
-typedef int (*tas_hook_mixer_is_stereo_t)(struct tas_data_t *,int);
-typedef int (*tas_hook_stereo_mixers_t)(struct tas_data_t *);
-
-typedef int (*tas_hook_output_device_change_t)(struct tas_data_t *,int,int,int);
-typedef int (*tas_hook_device_ioctl_t)(struct tas_data_t *,u_int,u_long);
-
-struct tas_driver_hooks_t {
-	/*
-	 * All hardware initialisation must be performed in
-	 * post_init(), as tas_dmasound_init() does a hardware reset.
-	 *
-	 * init() is called before tas_dmasound_init() so that
-	 * ouput_device_change() is always called after i2c driver
-	 * initialisation. The implication is that
-	 * output_device_change() must cope with the fact that it
-	 * may be called before post_init().
-	 */
-
-	tas_hook_init_t                   init;
-	tas_hook_post_init_t              post_init;
-	tas_hook_uninit_t                 uninit;
-
-	tas_hook_get_mixer_level_t        get_mixer_level;
-	tas_hook_set_mixer_level_t        set_mixer_level;
-
-	tas_hook_enter_sleep_t            enter_sleep;
-	tas_hook_leave_sleep_t            leave_sleep;
-
-	tas_hook_supported_mixers_t       supported_mixers;
-	tas_hook_mixer_is_stereo_t        mixer_is_stereo;
-	tas_hook_stereo_mixers_t          stereo_mixers;
-
-	tas_hook_output_device_change_t   output_device_change;
-	tas_hook_device_ioctl_t           device_ioctl;
-};
-
-enum tas_write_mode_t {
-	WRITE_HW     = 0x01,
-	WRITE_SHADOW = 0x02,
-	WRITE_NORMAL = 0x03,
-	FORCE_WRITE  = 0x04
-};
-
-static inline uint
-tas_mono_to_stereo(uint mono)
-{
-	mono &=0xff;
-	return mono | (mono<<8);
-}
-
-/*
- * Todo: make these functions a bit more efficient !
- */
-static inline int
-tas_write_register(	struct tas_data_t *self,
-			uint reg_num,
-			uint reg_width,
-			char *data,
-			uint write_mode)
-{
-	int rc;
-
-	if (reg_width==0 || data==NULL || self==NULL)
-		return -EINVAL;
-	if (!(write_mode & FORCE_WRITE) &&
-	    !memcmp(data,self->shadow[reg_num],reg_width))
-	    	return 0;
-
-	if (write_mode & WRITE_SHADOW)
-		memcpy(self->shadow[reg_num],data,reg_width);
-	if (write_mode & WRITE_HW) {
-		rc=i2c_smbus_write_i2c_block_data(self->client,
-						  reg_num,
-						  reg_width,
-						  data);
-		if (rc < 0) {
-			printk("tas: I2C block write failed \n");  
-			return rc; 
-		}
-	}
-	return 0;
-}
-
-static inline int
-tas_sync_register(	struct tas_data_t *self,
-			uint reg_num,
-			uint reg_width)
-{
-	int rc;
-
-	if (reg_width==0 || self==NULL)
-		return -EINVAL;
-	rc=i2c_smbus_write_i2c_block_data(self->client,
-					  reg_num,
-					  reg_width,
-					  self->shadow[reg_num]);
-	if (rc < 0) {
-		printk("tas: I2C block write failed \n");
-		return rc;
-	}
-	return 0;
-}
-
-static inline int
-tas_write_byte_register(	struct tas_data_t *self,
-				uint reg_num,
-				char data,
-				uint write_mode)
-{
-	if (self==NULL)
-		return -1;
-	if (!(write_mode & FORCE_WRITE) && data != self->shadow[reg_num][0])
-		return 0;
-	if (write_mode & WRITE_SHADOW)
-		self->shadow[reg_num][0]=data;
-	if (write_mode & WRITE_HW) {
-		if (i2c_smbus_write_byte_data(self->client, reg_num, data) < 0) {
-			printk("tas: I2C byte write failed \n");  
-			return -1; 
-		}
-	}
-	return 0;
-}
-
-static inline int
-tas_sync_byte_register(	struct tas_data_t *self,
-			uint reg_num,
-			uint reg_width)
-{
-	if (reg_width==0 || self==NULL)
-		return -1;
-	if (i2c_smbus_write_byte_data(
-	    self->client, reg_num, self->shadow[reg_num][0]) < 0) {
-		printk("tas: I2C byte write failed \n");
-		return -1;
-	}
-	return 0;
-}
-
-static inline int
-tas_read_register(	struct tas_data_t *self,
-			uint reg_num,
-			uint reg_width,
-			char *data)
-{
-	if (reg_width==0 || data==NULL || self==NULL)
-		return -1;
-	memcpy(data,self->shadow[reg_num],reg_width);
-	return 0;
-}
-
-extern int tas_register_driver(struct tas_driver_hooks_t *hooks);
-
-extern int tas_get_mixer_level(int mixer,uint *level);
-extern int tas_set_mixer_level(int mixer,uint level);
-extern int tas_enter_sleep(void);
-extern int tas_leave_sleep(void);
-extern int tas_supported_mixers(void);
-extern int tas_mixer_is_stereo(int mixer);
-extern int tas_stereo_mixers(void);
-extern int tas_output_device_change(int,int,int);
-extern int tas_device_ioctl(u_int, u_long);
-
-extern void tas_cleanup(void);
-extern int tas_init(int driver_id,const char *driver_name);
-extern int tas_post_init(void);
-
-#endif /* _TAS_COMMON_H_ */
-/*
- * Local Variables:
- * tab-width: 8
- * indent-tabs-mode: t
- * c-basic-offset: 8
- * End:
- */
diff --git a/sound/oss/dmasound/tas_eq_prefs.h b/sound/oss/dmasound/tas_eq_prefs.h
deleted file mode 100644
index 3a994ed..0000000
--- a/sound/oss/dmasound/tas_eq_prefs.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _TAS_EQ_PREFS_H_
-#define _TAS_EQ_PREFS_H_
-
-struct tas_eq_pref_t {
-	u_int sample_rate;
-	u_int device_id;
-	u_int output_id;
-	u_int speaker_id;
-
-	struct tas_drce_t *drce;
-
-	u_int filter_count;
-	struct tas_biquad_ctrl_t *biquads;
-};
-
-#endif /* _TAS_EQ_PREFS_H_ */
-
-/*
- * Local Variables:
- * tab-width: 8
- * indent-tabs-mode: t
- * c-basic-offset: 8
- * End:
- */
diff --git a/sound/oss/dmasound/tas_ioctl.h b/sound/oss/dmasound/tas_ioctl.h
deleted file mode 100644
index 9d12b37..0000000
--- a/sound/oss/dmasound/tas_ioctl.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _TAS_IOCTL_H_
-#define _TAS_IOCTL_H_
-
-#include <linux/soundcard.h>
-
-
-#define TAS_READ_EQ              _SIOR('t',0,struct tas_biquad_ctrl_t)
-#define TAS_WRITE_EQ             _SIOW('t',0,struct tas_biquad_ctrl_t)
-
-#define TAS_READ_EQ_LIST         _SIOR('t',1,struct tas_biquad_ctrl_t)
-#define TAS_WRITE_EQ_LIST        _SIOW('t',1,struct tas_biquad_ctrl_t)
-
-#define TAS_READ_EQ_FILTER_COUNT  _SIOR('t',2,int)
-#define TAS_READ_EQ_CHANNEL_COUNT _SIOR('t',3,int)
-
-#define TAS_READ_DRCE            _SIOR('t',4,struct tas_drce_ctrl_t)
-#define TAS_WRITE_DRCE           _SIOW('t',4,struct tas_drce_ctrl_t)
-
-#define TAS_READ_DRCE_CAPS       _SIOR('t',5,int)
-#define TAS_READ_DRCE_MIN        _SIOR('t',6,int)
-#define TAS_READ_DRCE_MAX        _SIOR('t',7,int)
-
-#endif
diff --git a/sound/oss/dmasound/trans_16.c b/sound/oss/dmasound/trans_16.c
deleted file mode 100644
index ca973ac..0000000
--- a/sound/oss/dmasound/trans_16.c
+++ /dev/null
@@ -1,898 +0,0 @@
-/*
- *  linux/sound/oss/dmasound/trans_16.c
- *
- *  16 bit translation routines.  Only used by Power mac at present.
- *
- *  See linux/sound/oss/dmasound/dmasound_core.c for copyright and
- *  history prior to 08/02/2001.
- *
- *  08/02/2001 Iain Sandoe
- *		split from dmasound_awacs.c
- *  11/29/2003 Renzo Davoli (King Enzo)
- *  	- input resampling (for soft rate < hard rate)
- *  	- software line in gain control
- */
-
-#include <linux/soundcard.h>
-#include <asm/uaccess.h>
-#include "dmasound.h"
-
-extern int expand_bal;	/* Balance factor for expanding (not volume!) */
-static short dmasound_alaw2dma16[] ;
-static short dmasound_ulaw2dma16[] ;
-
-static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft);
-static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
-			  u_char frame[], ssize_t *frameUsed,
-			  ssize_t frameLeft);
-static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
-			  u_char frame[], ssize_t *frameUsed,
-			  ssize_t frameLeft);
-static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft);
-static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft);
-
-static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
-			    u_char frame[], ssize_t *frameUsed,
-			    ssize_t frameLeft);
-static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft);
-static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft);
-static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
-			    u_char frame[], ssize_t *frameUsed,
-			    ssize_t frameLeft);
-static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
-			    u_char frame[], ssize_t *frameUsed,
-			    ssize_t frameLeft);
-
-static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft);
-static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft);
-
-/*** Translations ************************************************************/
-
-static int expand_data;	/* Data for expanding */
-
-static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft)
-{
-	short *table = dmasound.soft.format == AFMT_MU_LAW
-		? dmasound_ulaw2dma16 : dmasound_alaw2dma16;
-	ssize_t count, used;
-	short *p = (short *) &frame[*frameUsed];
-	int val, stereo = dmasound.soft.stereo;
-
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	used = count = min_t(unsigned long, userCount, frameLeft);
-	while (count > 0) {
-		u_char data;
-		if (get_user(data, userPtr++))
-			return -EFAULT;
-		val = table[data];
-		*p++ = val;
-		if (stereo) {
-			if (get_user(data, userPtr++))
-				return -EFAULT;
-			val = table[data];
-		}
-		*p++ = val;
-		count--;
-	}
-	*frameUsed += used * 4;
-	return stereo? used * 2: used;
-}
-
-
-static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
-			  u_char frame[], ssize_t *frameUsed,
-			  ssize_t frameLeft)
-{
-	ssize_t count, used;
-	short *p = (short *) &frame[*frameUsed];
-	int val, stereo = dmasound.soft.stereo;
-
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	used = count = min_t(unsigned long, userCount, frameLeft);
-	while (count > 0) {
-		u_char data;
-		if (get_user(data, userPtr++))
-			return -EFAULT;
-		val = data << 8;
-		*p++ = val;
-		if (stereo) {
-			if (get_user(data, userPtr++))
-				return -EFAULT;
-			val = data << 8;
-		}
-		*p++ = val;
-		count--;
-	}
-	*frameUsed += used * 4;
-	return stereo? used * 2: used;
-}
-
-
-static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
-			  u_char frame[], ssize_t *frameUsed,
-			  ssize_t frameLeft)
-{
-	ssize_t count, used;
-	short *p = (short *) &frame[*frameUsed];
-	int val, stereo = dmasound.soft.stereo;
-
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	used = count = min_t(unsigned long, userCount, frameLeft);
-	while (count > 0) {
-		u_char data;
-		if (get_user(data, userPtr++))
-			return -EFAULT;
-		val = (data ^ 0x80) << 8;
-		*p++ = val;
-		if (stereo) {
-			if (get_user(data, userPtr++))
-				return -EFAULT;
-			val = (data ^ 0x80) << 8;
-		}
-		*p++ = val;
-		count--;
-	}
-	*frameUsed += used * 4;
-	return stereo? used * 2: used;
-}
-
-
-static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft)
-{
-	ssize_t count, used;
-	int stereo = dmasound.soft.stereo;
-	short *fp = (short *) &frame[*frameUsed];
-
-	frameLeft >>= 2;
-	userCount >>= (stereo? 2: 1);
-	used = count = min_t(unsigned long, userCount, frameLeft);
-	if (!stereo) {
-		short __user *up = (short __user *) userPtr;
-		while (count > 0) {
-			short data;
-			if (get_user(data, up++))
-				return -EFAULT;
-			*fp++ = data;
-			*fp++ = data;
-			count--;
-		}
-	} else {
-		if (copy_from_user(fp, userPtr, count * 4))
-			return -EFAULT;
-	}
-	*frameUsed += used * 4;
-	return stereo? used * 4: used * 2;
-}
-
-static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft)
-{
-	ssize_t count, used;
-	int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-	int stereo = dmasound.soft.stereo;
-	short *fp = (short *) &frame[*frameUsed];
-	short __user *up = (short __user *) userPtr;
-
-	frameLeft >>= 2;
-	userCount >>= (stereo? 2: 1);
-	used = count = min_t(unsigned long, userCount, frameLeft);
-	while (count > 0) {
-		short data;
-		if (get_user(data, up++))
-			return -EFAULT;
-		data ^= mask;
-		*fp++ = data;
-		if (stereo) {
-			if (get_user(data, up++))
-				return -EFAULT;
-			data ^= mask;
-		}
-		*fp++ = data;
-		count--;
-	}
-	*frameUsed += used * 4;
-	return stereo? used * 4: used * 2;
-}
-
-
-static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
-			    u_char frame[], ssize_t *frameUsed,
-			    ssize_t frameLeft)
-{
-	unsigned short *table = (unsigned short *)
-		(dmasound.soft.format == AFMT_MU_LAW
-		 ? dmasound_ulaw2dma16 : dmasound_alaw2dma16);
-	unsigned int data = expand_data;
-	unsigned int *p = (unsigned int *) &frame[*frameUsed];
-	int bal = expand_bal;
-	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-	int utotal, ftotal;
-	int stereo = dmasound.soft.stereo;
-
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	ftotal = frameLeft;
-	utotal = userCount;
-	while (frameLeft) {
-		u_char c;
-		if (bal < 0) {
-			if (userCount == 0)
-				break;
-			if (get_user(c, userPtr++))
-				return -EFAULT;
-			data = table[c];
-			if (stereo) {
-				if (get_user(c, userPtr++))
-					return -EFAULT;
-				data = (data << 16) + table[c];
-			} else
-				data = (data << 16) + data;
-			userCount--;
-			bal += hSpeed;
-		}
-		*p++ = data;
-		frameLeft--;
-		bal -= sSpeed;
-	}
-	expand_bal = bal;
-	expand_data = data;
-	*frameUsed += (ftotal - frameLeft) * 4;
-	utotal -= userCount;
-	return stereo? utotal * 2: utotal;
-}
-
-static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft)
-{
-	unsigned int *p = (unsigned int *) &frame[*frameUsed];
-	unsigned int data = expand_data;
-	int bal = expand_bal;
-	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-	int stereo = dmasound.soft.stereo;
-	int utotal, ftotal;
-
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	ftotal = frameLeft;
-	utotal = userCount;
-	while (frameLeft) {
-		u_char c;
-		if (bal < 0) {
-			if (userCount == 0)
-				break;
-			if (get_user(c, userPtr++))
-				return -EFAULT;
-			data = c << 8;
-			if (stereo) {
-				if (get_user(c, userPtr++))
-					return -EFAULT;
-				data = (data << 16) + (c << 8);
-			} else
-				data = (data << 16) + data;
-			userCount--;
-			bal += hSpeed;
-		}
-		*p++ = data;
-		frameLeft--;
-		bal -= sSpeed;
-	}
-	expand_bal = bal;
-	expand_data = data;
-	*frameUsed += (ftotal - frameLeft) * 4;
-	utotal -= userCount;
-	return stereo? utotal * 2: utotal;
-}
-
-
-static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft)
-{
-	unsigned int *p = (unsigned int *) &frame[*frameUsed];
-	unsigned int data = expand_data;
-	int bal = expand_bal;
-	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-	int stereo = dmasound.soft.stereo;
-	int utotal, ftotal;
-
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	ftotal = frameLeft;
-	utotal = userCount;
-	while (frameLeft) {
-		u_char c;
-		if (bal < 0) {
-			if (userCount == 0)
-				break;
-			if (get_user(c, userPtr++))
-				return -EFAULT;
-			data = (c ^ 0x80) << 8;
-			if (stereo) {
-				if (get_user(c, userPtr++))
-					return -EFAULT;
-				data = (data << 16) + ((c ^ 0x80) << 8);
-			} else
-				data = (data << 16) + data;
-			userCount--;
-			bal += hSpeed;
-		}
-		*p++ = data;
-		frameLeft--;
-		bal -= sSpeed;
-	}
-	expand_bal = bal;
-	expand_data = data;
-	*frameUsed += (ftotal - frameLeft) * 4;
-	utotal -= userCount;
-	return stereo? utotal * 2: utotal;
-}
-
-
-static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
-			    u_char frame[], ssize_t *frameUsed,
-			    ssize_t frameLeft)
-{
-	unsigned int *p = (unsigned int *) &frame[*frameUsed];
-	unsigned int data = expand_data;
-	unsigned short __user *up = (unsigned short __user *) userPtr;
-	int bal = expand_bal;
-	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-	int stereo = dmasound.soft.stereo;
-	int utotal, ftotal;
-
-	frameLeft >>= 2;
-	userCount >>= (stereo? 2: 1);
-	ftotal = frameLeft;
-	utotal = userCount;
-	while (frameLeft) {
-		unsigned short c;
-		if (bal < 0) {
-			if (userCount == 0)
-				break;
-			if (get_user(data, up++))
-				return -EFAULT;
-			if (stereo) {
-				if (get_user(c, up++))
-					return -EFAULT;
-				data = (data << 16) + c;
-			} else
-				data = (data << 16) + data;
-			userCount--;
-			bal += hSpeed;
-		}
-		*p++ = data;
-		frameLeft--;
-		bal -= sSpeed;
-	}
-	expand_bal = bal;
-	expand_data = data;
-	*frameUsed += (ftotal - frameLeft) * 4;
-	utotal -= userCount;
-	return stereo? utotal * 4: utotal * 2;
-}
-
-
-static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
-			    u_char frame[], ssize_t *frameUsed,
-			    ssize_t frameLeft)
-{
-	int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-	unsigned int *p = (unsigned int *) &frame[*frameUsed];
-	unsigned int data = expand_data;
-	unsigned short __user *up = (unsigned short __user *) userPtr;
-	int bal = expand_bal;
-	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-	int stereo = dmasound.soft.stereo;
-	int utotal, ftotal;
-
-	frameLeft >>= 2;
-	userCount >>= (stereo? 2: 1);
-	ftotal = frameLeft;
-	utotal = userCount;
-	while (frameLeft) {
-		unsigned short c;
-		if (bal < 0) {
-			if (userCount == 0)
-				break;
-			if (get_user(data, up++))
-				return -EFAULT;
-			data ^= mask;
-			if (stereo) {
-				if (get_user(c, up++))
-					return -EFAULT;
-				data = (data << 16) + (c ^ mask);
-			} else
-				data = (data << 16) + data;
-			userCount--;
-			bal += hSpeed;
-		}
-		*p++ = data;
-		frameLeft--;
-		bal -= sSpeed;
-	}
-	expand_bal = bal;
-	expand_data = data;
-	*frameUsed += (ftotal - frameLeft) * 4;
-	utotal -= userCount;
-	return stereo? utotal * 4: utotal * 2;
-}
-
-/* data in routines... */
-
-static ssize_t pmac_ct_s8_read(const u_char __user *userPtr, size_t userCount,
-			  u_char frame[], ssize_t *frameUsed,
-			  ssize_t frameLeft)
-{
-	ssize_t count, used;
-	short *p = (short *) &frame[*frameUsed];
-	int val, stereo = dmasound.soft.stereo;
-
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	used = count = min_t(unsigned long, userCount, frameLeft);
-	while (count > 0) {
-		u_char data;
-
-		val = *p++;
-		val = (val * software_input_volume) >> 7;
-		data = val >> 8;
-		if (put_user(data, (u_char __user *)userPtr++))
-			return -EFAULT;
-		if (stereo) {
-			val = *p;
-			val = (val * software_input_volume) >> 7;
-			data = val >> 8;
-			if (put_user(data, (u_char __user *)userPtr++))
-				return -EFAULT;
-		}
-		p++;
-		count--;
-	}
-	*frameUsed += used * 4;
-	return stereo? used * 2: used;
-}
-
-
-static ssize_t pmac_ct_u8_read(const u_char __user *userPtr, size_t userCount,
-			  u_char frame[], ssize_t *frameUsed,
-			  ssize_t frameLeft)
-{
-	ssize_t count, used;
-	short *p = (short *) &frame[*frameUsed];
-	int val, stereo = dmasound.soft.stereo;
-
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	used = count = min_t(unsigned long, userCount, frameLeft);
-	while (count > 0) {
-		u_char data;
-
-		val = *p++;
-		val = (val * software_input_volume) >> 7;
-		data = (val >> 8) ^ 0x80;
-		if (put_user(data, (u_char __user *)userPtr++))
-			return -EFAULT;
-		if (stereo) {
-			val = *p;
-			val = (val * software_input_volume) >> 7;
-			data = (val >> 8) ^ 0x80;
-			if (put_user(data, (u_char __user *)userPtr++))
-				return -EFAULT;
-		}
-		p++;
-		count--;
-	}
-	*frameUsed += used * 4;
-	return stereo? used * 2: used;
-}
-
-static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft)
-{
-	ssize_t count, used;
-	int stereo = dmasound.soft.stereo;
-	short *fp = (short *) &frame[*frameUsed];
-	short __user *up = (short __user *) userPtr;
-
-	frameLeft >>= 2;
-	userCount >>= (stereo? 2: 1);
-	used = count = min_t(unsigned long, userCount, frameLeft);
-	while (count > 0) {
-		short data;
-
-		data = *fp++;
-		data = (data * software_input_volume) >> 7;
-		if (put_user(data, up++))
-			return -EFAULT;
-		if (stereo) {
-			data = *fp;
-			data = (data * software_input_volume) >> 7;
-			if (put_user(data, up++))
-				return -EFAULT;
-		}
-		fp++;
-		count--;
- 	}
-	*frameUsed += used * 4;
-	return stereo? used * 4: used * 2;
-}
-
-static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft)
-{
-	ssize_t count, used;
-	int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-	int stereo = dmasound.soft.stereo;
-	short *fp = (short *) &frame[*frameUsed];
-	short __user *up = (short __user *) userPtr;
-
-	frameLeft >>= 2;
-	userCount >>= (stereo? 2: 1);
-	used = count = min_t(unsigned long, userCount, frameLeft);
-	while (count > 0) {
-		int data;
-
-		data = *fp++;
-		data = (data * software_input_volume) >> 7;
-		data ^= mask;
-		if (put_user(data, up++))
-			return -EFAULT;
-		if (stereo) {
-			data = *fp;
-			data = (data * software_input_volume) >> 7;
-			data ^= mask;
-			if (put_user(data, up++))
-				return -EFAULT;
-		}
-		fp++;
-		count--;
-	}
-	*frameUsed += used * 4;
-	return stereo? used * 4: used * 2;
-}
-
-/* data in routines (reducing speed)... */
-
-static ssize_t pmac_ctx_s8_read(const u_char __user *userPtr, size_t userCount,
-			  u_char frame[], ssize_t *frameUsed,
-			  ssize_t frameLeft)
-{
-	short *p = (short *) &frame[*frameUsed];
-	int bal = expand_read_bal;
-	int vall,valr, stereo = dmasound.soft.stereo;
-	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-	int utotal, ftotal;
-
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	ftotal = frameLeft;
-	utotal = userCount;
-	while (frameLeft) {
-		u_char data;
-
-		if (bal<0 && userCount == 0)
-			break;
-		vall = *p++;
-		vall = (vall * software_input_volume) >> 7;
-		if (stereo) {
-			valr = *p;
-			valr = (valr * software_input_volume) >> 7;
-		}
-		p++;
-		if (bal < 0) {
-			data = vall >> 8;
-			if (put_user(data, (u_char __user *)userPtr++))
-				return -EFAULT;
-			if (stereo) {
-				data = valr >> 8;
-				if (put_user(data, (u_char __user *)userPtr++))
-					return -EFAULT;
-			}
-			userCount--;
-			bal += hSpeed;
-		}
-		frameLeft--;
-		bal -= sSpeed;
-	}
-	expand_read_bal=bal;
-	*frameUsed += (ftotal - frameLeft) * 4;
-	utotal -= userCount;
-	return stereo? utotal * 2: utotal;
-}
-
-
-static ssize_t pmac_ctx_u8_read(const u_char __user *userPtr, size_t userCount,
-			  u_char frame[], ssize_t *frameUsed,
-			  ssize_t frameLeft)
-{
-	short *p = (short *) &frame[*frameUsed];
-	int bal = expand_read_bal;
-	int vall,valr, stereo = dmasound.soft.stereo;
-	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-	int utotal, ftotal;
-
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	ftotal = frameLeft;
-	utotal = userCount;
-	while (frameLeft) {
-		u_char data;
-
-		if (bal<0 && userCount == 0)
-			break;
-
-		vall = *p++;
-		vall = (vall * software_input_volume) >> 7;
-		if (stereo) {
-			valr = *p;
-			valr = (valr * software_input_volume) >> 7;
-		}
-		p++;
-		if (bal < 0) {
-			data = (vall >> 8) ^ 0x80;
-			if (put_user(data, (u_char __user *)userPtr++))
-				return -EFAULT;
-			if (stereo) {
-				data = (valr >> 8) ^ 0x80;
-				if (put_user(data, (u_char __user *)userPtr++))
-					return -EFAULT;
-			}
-			userCount--;
-			bal += hSpeed;
-		}
-		frameLeft--;
-		bal -= sSpeed;
-	}
-	expand_read_bal=bal;
-	*frameUsed += (ftotal - frameLeft) * 4;
-	utotal -= userCount;
-	return stereo? utotal * 2: utotal;
-}
-
-static ssize_t pmac_ctx_s16_read(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft)
-{
-	int bal = expand_read_bal;
-	short *fp = (short *) &frame[*frameUsed];
-	short __user *up = (short __user *) userPtr;
-	int stereo = dmasound.soft.stereo;
-	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-	int utotal, ftotal;
-
-	frameLeft >>= 2;
-	userCount >>= (stereo? 2: 1);
-	ftotal = frameLeft;
-	utotal = userCount;
-	while (frameLeft) {
-		int datal,datar;
-
-		if (bal<0 && userCount == 0)
-			break;
-
-		datal = *fp++;
-		datal = (datal * software_input_volume) >> 7;
-		if (stereo) {
-			datar = *fp;
-			datar = (datar * software_input_volume) >> 7;
-		}
-		fp++;
-		if (bal < 0) {
-			if (put_user(datal, up++))
-				return -EFAULT;
-			if (stereo) {
-				if (put_user(datar, up++))
-					return -EFAULT;
-			}
-			userCount--;
-			bal += hSpeed;
-		}
-		frameLeft--;
-		bal -= sSpeed;
-	}
-	expand_read_bal=bal;
-	*frameUsed += (ftotal - frameLeft) * 4;
-	utotal -= userCount;
-	return stereo? utotal * 4: utotal * 2;
-}
-
-static ssize_t pmac_ctx_u16_read(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft)
-{
-	int bal = expand_read_bal;
-	int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-	short *fp = (short *) &frame[*frameUsed];
-	short __user *up = (short __user *) userPtr;
-	int stereo = dmasound.soft.stereo;
-	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-	int utotal, ftotal;
-
-	frameLeft >>= 2;
-	userCount >>= (stereo? 2: 1);
-	ftotal = frameLeft;
-	utotal = userCount;
-	while (frameLeft) {
-		int datal,datar;
-
-		if (bal<0 && userCount == 0)
-			break;
-
-		datal = *fp++;
-		datal = (datal * software_input_volume) >> 7;
-		datal ^= mask;
-		if (stereo) {
-			datar = *fp;
-			datar = (datar * software_input_volume) >> 7;
-			datar ^= mask;
-		}
-		fp++;
-		if (bal < 0) {
-			if (put_user(datal, up++))
-				return -EFAULT;
-			if (stereo) {
-				if (put_user(datar, up++))
-					return -EFAULT;
-			}
-			userCount--;
-			bal += hSpeed;
-		}
-		frameLeft--;
-		bal -= sSpeed;
-	}
-	expand_read_bal=bal;
-	*frameUsed += (ftotal - frameLeft) * 4;
-	utotal -= userCount;
-	return stereo? utotal * 4: utotal * 2;
-}
-
-
-TRANS transAwacsNormal = {
-	.ct_ulaw=	pmac_ct_law,
-	.ct_alaw=	pmac_ct_law,
-	.ct_s8=		pmac_ct_s8,
-	.ct_u8=		pmac_ct_u8,
-	.ct_s16be=	pmac_ct_s16,
-	.ct_u16be=	pmac_ct_u16,
-	.ct_s16le=	pmac_ct_s16,
-	.ct_u16le=	pmac_ct_u16,
-};
-
-TRANS transAwacsExpand = {
-	.ct_ulaw=	pmac_ctx_law,
-	.ct_alaw=	pmac_ctx_law,
-	.ct_s8=		pmac_ctx_s8,
-	.ct_u8=		pmac_ctx_u8,
-	.ct_s16be=	pmac_ctx_s16,
-	.ct_u16be=	pmac_ctx_u16,
-	.ct_s16le=	pmac_ctx_s16,
-	.ct_u16le=	pmac_ctx_u16,
-};
-
-TRANS transAwacsNormalRead = {
-	.ct_s8=		pmac_ct_s8_read,
-	.ct_u8=		pmac_ct_u8_read,
-	.ct_s16be=	pmac_ct_s16_read,
-	.ct_u16be=	pmac_ct_u16_read,
-	.ct_s16le=	pmac_ct_s16_read,
-	.ct_u16le=	pmac_ct_u16_read,
-};
-
-TRANS transAwacsExpandRead = {
-	.ct_s8=		pmac_ctx_s8_read,
-	.ct_u8=		pmac_ctx_u8_read,
-	.ct_s16be=	pmac_ctx_s16_read,
-	.ct_u16be=	pmac_ctx_u16_read,
-	.ct_s16le=	pmac_ctx_s16_read,
-	.ct_u16le=	pmac_ctx_u16_read,
-};
-
-/* translation tables */
-/* 16 bit mu-law */
-
-static short dmasound_ulaw2dma16[] = {
-	-32124,	-31100,	-30076,	-29052,	-28028,	-27004,	-25980,	-24956,
-	-23932,	-22908,	-21884,	-20860,	-19836,	-18812,	-17788,	-16764,
-	-15996,	-15484,	-14972,	-14460,	-13948,	-13436,	-12924,	-12412,
-	-11900,	-11388,	-10876,	-10364,	-9852,	-9340,	-8828,	-8316,
-	-7932,	-7676,	-7420,	-7164,	-6908,	-6652,	-6396,	-6140,
-	-5884,	-5628,	-5372,	-5116,	-4860,	-4604,	-4348,	-4092,
-	-3900,	-3772,	-3644,	-3516,	-3388,	-3260,	-3132,	-3004,
-	-2876,	-2748,	-2620,	-2492,	-2364,	-2236,	-2108,	-1980,
-	-1884,	-1820,	-1756,	-1692,	-1628,	-1564,	-1500,	-1436,
-	-1372,	-1308,	-1244,	-1180,	-1116,	-1052,	-988,	-924,
-	-876,	-844,	-812,	-780,	-748,	-716,	-684,	-652,
-	-620,	-588,	-556,	-524,	-492,	-460,	-428,	-396,
-	-372,	-356,	-340,	-324,	-308,	-292,	-276,	-260,
-	-244,	-228,	-212,	-196,	-180,	-164,	-148,	-132,
-	-120,	-112,	-104,	-96,	-88,	-80,	-72,	-64,
-	-56,	-48,	-40,	-32,	-24,	-16,	-8,	0,
-	32124,	31100,	30076,	29052,	28028,	27004,	25980,	24956,
-	23932,	22908,	21884,	20860,	19836,	18812,	17788,	16764,
-	15996,	15484,	14972,	14460,	13948,	13436,	12924,	12412,
-	11900,	11388,	10876,	10364,	9852,	9340,	8828,	8316,
-	7932,	7676,	7420,	7164,	6908,	6652,	6396,	6140,
-	5884,	5628,	5372,	5116,	4860,	4604,	4348,	4092,
-	3900,	3772,	3644,	3516,	3388,	3260,	3132,	3004,
-	2876,	2748,	2620,	2492,	2364,	2236,	2108,	1980,
-	1884,	1820,	1756,	1692,	1628,	1564,	1500,	1436,
-	1372,	1308,	1244,	1180,	1116,	1052,	988,	924,
-	876,	844,	812,	780,	748,	716,	684,	652,
-	620,	588,	556,	524,	492,	460,	428,	396,
-	372,	356,	340,	324,	308,	292,	276,	260,
-	244,	228,	212,	196,	180,	164,	148,	132,
-	120,	112,	104,	96,	88,	80,	72,	64,
-	56,	48,	40,	32,	24,	16,	8,	0,
-};
-
-/* 16 bit A-law */
-
-static short dmasound_alaw2dma16[] = {
-	-5504,	-5248,	-6016,	-5760,	-4480,	-4224,	-4992,	-4736,
-	-7552,	-7296,	-8064,	-7808,	-6528,	-6272,	-7040,	-6784,
-	-2752,	-2624,	-3008,	-2880,	-2240,	-2112,	-2496,	-2368,
-	-3776,	-3648,	-4032,	-3904,	-3264,	-3136,	-3520,	-3392,
-	-22016,	-20992,	-24064,	-23040,	-17920,	-16896,	-19968,	-18944,
-	-30208,	-29184,	-32256,	-31232,	-26112,	-25088,	-28160,	-27136,
-	-11008,	-10496,	-12032,	-11520,	-8960,	-8448,	-9984,	-9472,
-	-15104,	-14592,	-16128,	-15616,	-13056,	-12544,	-14080,	-13568,
-	-344,	-328,	-376,	-360,	-280,	-264,	-312,	-296,
-	-472,	-456,	-504,	-488,	-408,	-392,	-440,	-424,
-	-88,	-72,	-120,	-104,	-24,	-8,	-56,	-40,
-	-216,	-200,	-248,	-232,	-152,	-136,	-184,	-168,
-	-1376,	-1312,	-1504,	-1440,	-1120,	-1056,	-1248,	-1184,
-	-1888,	-1824,	-2016,	-1952,	-1632,	-1568,	-1760,	-1696,
-	-688,	-656,	-752,	-720,	-560,	-528,	-624,	-592,
-	-944,	-912,	-1008,	-976,	-816,	-784,	-880,	-848,
-	5504,	5248,	6016,	5760,	4480,	4224,	4992,	4736,
-	7552,	7296,	8064,	7808,	6528,	6272,	7040,	6784,
-	2752,	2624,	3008,	2880,	2240,	2112,	2496,	2368,
-	3776,	3648,	4032,	3904,	3264,	3136,	3520,	3392,
-	22016,	20992,	24064,	23040,	17920,	16896,	19968,	18944,
-	30208,	29184,	32256,	31232,	26112,	25088,	28160,	27136,
-	11008,	10496,	12032,	11520,	8960,	8448,	9984,	9472,
-	15104,	14592,	16128,	15616,	13056,	12544,	14080,	13568,
-	344,	328,	376,	360,	280,	264,	312,	296,
-	472,	456,	504,	488,	408,	392,	440,	424,
-	88,	72,	120,	104,	24,	8,	56,	40,
-	216,	200,	248,	232,	152,	136,	184,	168,
-	1376,	1312,	1504,	1440,	1120,	1056,	1248,	1184,
-	1888,	1824,	2016,	1952,	1632,	1568,	1760,	1696,
-	688,	656,	752,	720,	560,	528,	624,	592,
-	944,	912,	1008,	976,	816,	784,	880,	848,
-};
diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c
deleted file mode 100644
index 5264857..0000000
--- a/sound/oss/es1371.c
+++ /dev/null
@@ -1,3131 +0,0 @@
-/*****************************************************************************/
-
-/*
- *      es1371.c  --  Creative Ensoniq ES1371.
- *
- *      Copyright (C) 1998-2001, 2003  Thomas Sailer (t.sailer@alumni.ethz.ch)
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Special thanks to Ensoniq
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/dsp1   additional DAC, like /dev/dsp, but outputs to mixer "SYNTH" setting
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  NOTE: the card does not have any FM/Wavetable synthesizer, it is supposed
- *  to be done in software. That is what /dev/dac is for. By now (Q2 1998)
- *  there are several MIDI to PCM (WAV) packages, one of them is timidity.
- *
- *  Revision history
- *    04.06.1998   0.1   Initial release
- *                       Mixer stuff should be overhauled; especially optional AC97 mixer bits
- *                       should be detected. This results in strange behaviour of some mixer
- *                       settings, like master volume and mic.
- *    08.06.1998   0.2   First release using Alan Cox' soundcore instead of miscdevice
- *    03.08.1998   0.3   Do not include modversions.h
- *                       Now mixer behaviour can basically be selected between
- *                       "OSS documented" and "OSS actual" behaviour
- *    31.08.1998   0.4   Fix realplayer problems - dac.count issues
- *    27.10.1998   0.5   Fix joystick support
- *                       -- Oliver Neukum (c188@org.chemie.uni-muenchen.de)
- *    10.12.1998   0.6   Fix drain_dac trying to wait on not yet initialized DMA
- *    23.12.1998   0.7   Fix a few f_file & FMODE_ bugs
- *                       Don't wake up app until there are fragsize bytes to read/write
- *    06.01.1999   0.8   remove the silly SA_INTERRUPT flag.
- *                       hopefully killed the egcs section type conflict
- *    12.03.1999   0.9   cinfo.blocks should be reset after GETxPTR ioctl.
- *                       reported by Johan Maes <joma@telindus.be>
- *    22.03.1999   0.10  return EAGAIN instead of EBUSY when O_NONBLOCK
- *                       read/write cannot be executed
- *    07.04.1999   0.11  implemented the following ioctl's: SOUND_PCM_READ_RATE, 
- *                       SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 
- *                       Alpha fixes reported by Peter Jones <pjones@redhat.com>
- *                       Another Alpha fix (wait_src_ready in init routine)
- *                       reported by "Ivan N. Kokshaysky" <ink@jurassic.park.msu.ru>
- *                       Note: joystick address handling might still be wrong on archs
- *                       other than i386
- *    15.06.1999   0.12  Fix bad allocation bug.
- *                       Thanks to Deti Fliegl <fliegl@in.tum.de>
- *    28.06.1999   0.13  Add pci_set_master
- *    03.08.1999   0.14  adapt to Linus' new __setup/__initcall
- *                       added kernel command line option "es1371=joystickaddr"
- *                       removed CONFIG_SOUND_ES1371_JOYPORT_BOOT kludge
- *    10.08.1999   0.15  (Re)added S/PDIF module option for cards revision >= 4.
- *                       Initial version by Dave Platt <dplatt@snulbug.mtview.ca.us>.
- *                       module_init/__setup fixes
- *    08.16.1999   0.16  Joe Cotellese <joec@ensoniq.com>
- *                       Added detection for ES1371 revision ID so that we can
- *                       detect the ES1373 and later parts.
- *                       added AC97 #defines for readability
- *                       added a /proc file system for dumping hardware state
- *                       updated SRC and CODEC w/r functions to accommodate bugs
- *                       in some versions of the ES137x chips.
- *    31.08.1999   0.17  add spin_lock_init
- *                       replaced current->state = x with set_current_state(x)
- *    03.09.1999   0.18  change read semantics for MIDI to match
- *                       OSS more closely; remove possible wakeup race
- *    21.10.1999   0.19  Round sampling rates, requested by
- *                       Kasamatsu Kenichi <t29w0267@ip.media.kyoto-u.ac.jp>
- *    27.10.1999   0.20  Added SigmaTel 3D enhancement string
- *                       Codec ID printing changes
- *    28.10.1999   0.21  More waitqueue races fixed
- *                       Joe Cotellese <joec@ensoniq.com>
- *                       Changed PCI detection routine so we can more easily
- *                       detect ES137x chip and derivatives.
- *    05.01.2000   0.22  Should now work with rev7 boards; patch by
- *                       Eric Lemar, elemar@cs.washington.edu
- *    08.01.2000   0.23  Prevent some ioctl's from returning bad count values on underrun/overrun;
- *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
- *    07.02.2000   0.24  Use pci_alloc_consistent and pci_register_driver
- *    07.02.2000   0.25  Use ac97_codec
- *    01.03.2000   0.26  SPDIF patch by Mikael Bouillot <mikael.bouillot@bigfoot.com>
- *                       Use pci_module_init
- *    21.11.2000   0.27  Initialize dma buffers in poll, otherwise poll may return a bogus mask
- *    12.12.2000   0.28  More dma buffer initializations, patch from
- *                       Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
- *    05.01.2001   0.29  Hopefully updates will not be required anymore when Creative bumps
- *                       the CT5880 revision.
- *                       suggested by Stephan Müller <smueller@chronox.de>
- *    31.01.2001   0.30  Register/Unregister gameport
- *                       Fix SETTRIGGER non OSS API conformity
- *    14.07.2001   0.31  Add list of laptops needing amplifier control
- *    03.01.2003   0.32  open_mode fixes from Georg Acher <acher@in.tum.de>
- */
-
-/*****************************************************************************/
-      
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/bitops.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/ac97_codec.h>
-#include <linux/gameport.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK
-#endif
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#define ES1371_DEBUG
-#define DBG(x) {}
-/*#define DBG(x) {x}*/
-
-/* --------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_ENSONIQ
-#define PCI_VENDOR_ID_ENSONIQ        0x1274    
-#endif
-
-#ifndef PCI_VENDOR_ID_ECTIVA
-#define PCI_VENDOR_ID_ECTIVA         0x1102
-#endif
-
-#ifndef PCI_DEVICE_ID_ENSONIQ_ES1371
-#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371
-#endif
-
-#ifndef PCI_DEVICE_ID_ENSONIQ_CT5880
-#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880
-#endif
-
-#ifndef PCI_DEVICE_ID_ECTIVA_EV1938
-#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938
-#endif
-
-/* ES1371 chip ID */
-/* This is a little confusing because all ES1371 compatible chips have the
-   same DEVICE_ID, the only thing differentiating them is the REV_ID field.
-   This is only significant if you want to enable features on the later parts.
-   Yes, I know it's stupid and why didn't we use the sub IDs?
-*/
-#define ES1371REV_ES1373_A  0x04
-#define ES1371REV_ES1373_B  0x06
-#define ES1371REV_CT5880_A  0x07
-#define CT5880REV_CT5880_C  0x02
-#define CT5880REV_CT5880_D  0x03
-#define ES1371REV_ES1371_B  0x09
-#define EV1938REV_EV1938_A  0x00
-#define ES1371REV_ES1373_8  0x08
-
-#define ES1371_MAGIC  ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1371)
-
-#define ES1371_EXTENT             0x40
-#define JOY_EXTENT                8
-
-#define ES1371_REG_CONTROL        0x00
-#define ES1371_REG_STATUS         0x04 /* on the 5880 it is control/status */
-#define ES1371_REG_UART_DATA      0x08
-#define ES1371_REG_UART_STATUS    0x09
-#define ES1371_REG_UART_CONTROL   0x09
-#define ES1371_REG_UART_TEST      0x0a
-#define ES1371_REG_MEMPAGE        0x0c
-#define ES1371_REG_SRCONV         0x10
-#define ES1371_REG_CODEC          0x14
-#define ES1371_REG_LEGACY         0x18
-#define ES1371_REG_SERIAL_CONTROL 0x20
-#define ES1371_REG_DAC1_SCOUNT    0x24
-#define ES1371_REG_DAC2_SCOUNT    0x28
-#define ES1371_REG_ADC_SCOUNT     0x2c
-
-#define ES1371_REG_DAC1_FRAMEADR  0xc30
-#define ES1371_REG_DAC1_FRAMECNT  0xc34
-#define ES1371_REG_DAC2_FRAMEADR  0xc38
-#define ES1371_REG_DAC2_FRAMECNT  0xc3c
-#define ES1371_REG_ADC_FRAMEADR   0xd30
-#define ES1371_REG_ADC_FRAMECNT   0xd34
-
-#define ES1371_FMT_U8_MONO     0
-#define ES1371_FMT_U8_STEREO   1
-#define ES1371_FMT_S16_MONO    2
-#define ES1371_FMT_S16_STEREO  3
-#define ES1371_FMT_STEREO      1
-#define ES1371_FMT_S16         2
-#define ES1371_FMT_MASK        3
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-#define CTRL_RECEN_B    0x08000000  /* 1 = don't mix analog in to digital out */
-#define CTRL_SPDIFEN_B  0x04000000
-#define CTRL_JOY_SHIFT  24
-#define CTRL_JOY_MASK   3
-#define CTRL_JOY_200    0x00000000  /* joystick base address */
-#define CTRL_JOY_208    0x01000000
-#define CTRL_JOY_210    0x02000000
-#define CTRL_JOY_218    0x03000000
-#define CTRL_GPIO_IN0   0x00100000  /* general purpose inputs/outputs */
-#define CTRL_GPIO_IN1   0x00200000
-#define CTRL_GPIO_IN2   0x00400000
-#define CTRL_GPIO_IN3   0x00800000
-#define CTRL_GPIO_OUT0  0x00010000
-#define CTRL_GPIO_OUT1  0x00020000
-#define CTRL_GPIO_OUT2  0x00040000
-#define CTRL_GPIO_OUT3  0x00080000
-#define CTRL_MSFMTSEL   0x00008000  /* MPEG serial data fmt: 0 = Sony, 1 = I2S */
-#define CTRL_SYNCRES    0x00004000  /* AC97 warm reset */
-#define CTRL_ADCSTOP    0x00002000  /* stop ADC transfers */
-#define CTRL_PWR_INTRM  0x00001000  /* 1 = power level ints enabled */
-#define CTRL_M_CB       0x00000800  /* recording source: 0 = ADC, 1 = MPEG */
-#define CTRL_CCB_INTRM  0x00000400  /* 1 = CCB "voice" ints enabled */
-#define CTRL_PDLEV0     0x00000000  /* power down level */
-#define CTRL_PDLEV1     0x00000100
-#define CTRL_PDLEV2     0x00000200
-#define CTRL_PDLEV3     0x00000300
-#define CTRL_BREQ       0x00000080  /* 1 = test mode (internal mem test) */
-#define CTRL_DAC1_EN    0x00000040  /* enable DAC1 */
-#define CTRL_DAC2_EN    0x00000020  /* enable DAC2 */
-#define CTRL_ADC_EN     0x00000010  /* enable ADC */
-#define CTRL_UART_EN    0x00000008  /* enable MIDI uart */
-#define CTRL_JYSTK_EN   0x00000004  /* enable Joystick port */
-#define CTRL_XTALCLKDIS 0x00000002  /* 1 = disable crystal clock input */
-#define CTRL_PCICLKDIS  0x00000001  /* 1 = disable PCI clock distribution */
-
-
-#define STAT_INTR       0x80000000  /* wired or of all interrupt bits */
-#define CSTAT_5880_AC97_RST 0x20000000 /* CT5880 Reset bit */
-#define STAT_EN_SPDIF   0x00040000  /* enable S/PDIF circuitry */
-#define STAT_TS_SPDIF   0x00020000  /* test S/PDIF circuitry */
-#define STAT_TESTMODE   0x00010000  /* test ASIC */
-#define STAT_SYNC_ERR   0x00000100  /* 1 = codec sync error */
-#define STAT_VC         0x000000c0  /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */
-#define STAT_SH_VC      6
-#define STAT_MPWR       0x00000020  /* power level interrupt */
-#define STAT_MCCB       0x00000010  /* CCB int pending */
-#define STAT_UART       0x00000008  /* UART int pending */
-#define STAT_DAC1       0x00000004  /* DAC1 int pending */
-#define STAT_DAC2       0x00000002  /* DAC2 int pending */
-#define STAT_ADC        0x00000001  /* ADC int pending */
-
-#define USTAT_RXINT     0x80        /* UART rx int pending */
-#define USTAT_TXINT     0x04        /* UART tx int pending */
-#define USTAT_TXRDY     0x02        /* UART tx ready */
-#define USTAT_RXRDY     0x01        /* UART rx ready */
-
-#define UCTRL_RXINTEN   0x80        /* 1 = enable RX ints */
-#define UCTRL_TXINTEN   0x60        /* TX int enable field mask */
-#define UCTRL_ENA_TXINT 0x20        /* enable TX int */
-#define UCTRL_CNTRL     0x03        /* control field */
-#define UCTRL_CNTRL_SWR 0x03        /* software reset command */
-
-/* sample rate converter */
-#define SRC_OKSTATE        1
-
-#define SRC_RAMADDR_MASK   0xfe000000
-#define SRC_RAMADDR_SHIFT  25
-#define SRC_DAC1FREEZE     (1UL << 21)
-#define SRC_DAC2FREEZE      (1UL << 20)
-#define SRC_ADCFREEZE      (1UL << 19)
-
-
-#define SRC_WE             0x01000000  /* read/write control for SRC RAM */
-#define SRC_BUSY           0x00800000  /* SRC busy */
-#define SRC_DIS            0x00400000  /* 1 = disable SRC */
-#define SRC_DDAC1          0x00200000  /* 1 = disable accum update for DAC1 */
-#define SRC_DDAC2          0x00100000  /* 1 = disable accum update for DAC2 */
-#define SRC_DADC           0x00080000  /* 1 = disable accum update for ADC2 */
-#define SRC_CTLMASK        0x00780000
-#define SRC_RAMDATA_MASK   0x0000ffff
-#define SRC_RAMDATA_SHIFT  0
-
-#define SRCREG_ADC      0x78
-#define SRCREG_DAC1     0x70
-#define SRCREG_DAC2     0x74
-#define SRCREG_VOL_ADC  0x6c
-#define SRCREG_VOL_DAC1 0x7c
-#define SRCREG_VOL_DAC2 0x7e
-
-#define SRCREG_TRUNC_N     0x00
-#define SRCREG_INT_REGS    0x01
-#define SRCREG_ACCUM_FRAC  0x02
-#define SRCREG_VFREQ_FRAC  0x03
-
-#define CODEC_PIRD        0x00800000  /* 0 = write AC97 register */
-#define CODEC_PIADD_MASK  0x007f0000
-#define CODEC_PIADD_SHIFT 16
-#define CODEC_PIDAT_MASK  0x0000ffff
-#define CODEC_PIDAT_SHIFT 0
-
-#define CODEC_RDY         0x80000000  /* AC97 read data valid */
-#define CODEC_WIP         0x40000000  /* AC97 write in progress */
-#define CODEC_PORD        0x00800000  /* 0 = write AC97 register */
-#define CODEC_POADD_MASK  0x007f0000
-#define CODEC_POADD_SHIFT 16
-#define CODEC_PODAT_MASK  0x0000ffff
-#define CODEC_PODAT_SHIFT 0
-
-
-#define LEGACY_JFAST      0x80000000  /* fast joystick timing */
-#define LEGACY_FIRQ       0x01000000  /* force IRQ */
-
-#define SCTRL_DACTEST     0x00400000  /* 1 = DAC test, test vector generation purposes */
-#define SCTRL_P2ENDINC    0x00380000  /*  */
-#define SCTRL_SH_P2ENDINC 19
-#define SCTRL_P2STINC     0x00070000  /*  */
-#define SCTRL_SH_P2STINC  16
-#define SCTRL_R1LOOPSEL   0x00008000  /* 0 = loop mode */
-#define SCTRL_P2LOOPSEL   0x00004000  /* 0 = loop mode */
-#define SCTRL_P1LOOPSEL   0x00002000  /* 0 = loop mode */
-#define SCTRL_P2PAUSE     0x00001000  /* 1 = pause mode */
-#define SCTRL_P1PAUSE     0x00000800  /* 1 = pause mode */
-#define SCTRL_R1INTEN     0x00000400  /* enable interrupt */
-#define SCTRL_P2INTEN     0x00000200  /* enable interrupt */
-#define SCTRL_P1INTEN     0x00000100  /* enable interrupt */
-#define SCTRL_P1SCTRLD    0x00000080  /* reload sample count register for DAC1 */
-#define SCTRL_P2DACSEN    0x00000040  /* 1 = DAC2 play back last sample when disabled */
-#define SCTRL_R1SEB       0x00000020  /* 1 = 16bit */
-#define SCTRL_R1SMB       0x00000010  /* 1 = stereo */
-#define SCTRL_R1FMT       0x00000030  /* format mask */
-#define SCTRL_SH_R1FMT    4
-#define SCTRL_P2SEB       0x00000008  /* 1 = 16bit */
-#define SCTRL_P2SMB       0x00000004  /* 1 = stereo */
-#define SCTRL_P2FMT       0x0000000c  /* format mask */
-#define SCTRL_SH_P2FMT    2
-#define SCTRL_P1SEB       0x00000002  /* 1 = 16bit */
-#define SCTRL_P1SMB       0x00000001  /* 1 = stereo */
-#define SCTRL_P1FMT       0x00000003  /* format mask */
-#define SCTRL_SH_P1FMT    0
-
-
-/* misc stuff */
-#define POLL_COUNT   0x1000
-#define FMODE_DAC         4           /* slight misuse of mode_t */
-
-/* MIDI buffer sizes */
-
-#define MIDIINBUF  256
-#define MIDIOUTBUF 256
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define ES1371_MODULE_NAME "es1371"
-#define PFX ES1371_MODULE_NAME ": "
-
-/* --------------------------------------------------------------------- */
-
-struct es1371_state {
-	/* magic */
-	unsigned int magic;
-
-	/* list of es1371 devices */
-	struct list_head devs;
-
-	/* the corresponding pci_dev structure */
-	struct pci_dev *dev;
-
-	/* soundcore stuff */
-	int dev_audio;
-	int dev_dac;
-	int dev_midi;
-	
-	/* hardware resources */
-	unsigned long io; /* long for SPARC */
-	unsigned int irq;
-
-	/* PCI ID's */
-	u16 vendor;
-	u16 device;
-        u8 rev; /* the chip revision */
-
-	/* options */
-	int spdif_volume; /* S/PDIF output is enabled if != -1 */
-
-#ifdef ES1371_DEBUG
-        /* debug /proc entry */
-	struct proc_dir_entry *ps;
-#endif /* ES1371_DEBUG */
-
-	struct ac97_codec *codec;
-
-	/* wave stuff */
-	unsigned ctrl;
-	unsigned sctrl;
-	unsigned dac1rate, dac2rate, adcrate;
-
-	spinlock_t lock;
-	struct mutex open_mutex;
-	mode_t open_mode;
-	wait_queue_head_t open_wait;
-
-	struct dmabuf {
-		void *rawbuf;
-		dma_addr_t dmaaddr;
-		unsigned buforder;
-		unsigned numfrag;
-		unsigned fragshift;
-		unsigned hwptr, swptr;
-		unsigned total_bytes;
-		int count;
-		unsigned error; /* over/underrun */
-		wait_queue_head_t wait;
-		/* redundant, but makes calculations easier */
-		unsigned fragsize;
-		unsigned dmasize;
-		unsigned fragsamples;
-		/* OSS stuff */
-		unsigned mapped:1;
-		unsigned ready:1;
-		unsigned endcleared:1;
-		unsigned enabled:1;
-		unsigned ossfragshift;
-		int ossmaxfrags;
-		unsigned subdivision;
-	} dma_dac1, dma_dac2, dma_adc;
-
-	/* midi stuff */
-	struct {
-		unsigned ird, iwr, icnt;
-		unsigned ord, owr, ocnt;
-		wait_queue_head_t iwait;
-		wait_queue_head_t owait;
-		unsigned char ibuf[MIDIINBUF];
-		unsigned char obuf[MIDIOUTBUF];
-	} midi;
-
-#ifdef SUPPORT_JOYSTICK
-	struct gameport *gameport;
-#endif
-
-	struct mutex sem;
-};
-
-/* --------------------------------------------------------------------- */
-
-static LIST_HEAD(devs);
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-	unsigned r = 0;
-	
-	if (x >= 0x10000) {
-		x >>= 16;
-		r += 16;
-	}
-	if (x >= 0x100) {
-		x >>= 8;
-		r += 8;
-	}
-	if (x >= 0x10) {
-		x >>= 4;
-		r += 4;
-	}
-	if (x >= 4) {
-		x >>= 2;
-		r += 2;
-	}
-	if (x >= 2)
-		r++;
-	return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static unsigned wait_src_ready(struct es1371_state *s)
-{
-	unsigned int t, r;
-
-	for (t = 0; t < POLL_COUNT; t++) {
-		if (!((r = inl(s->io + ES1371_REG_SRCONV)) & SRC_BUSY))
-			return r;
-		udelay(1);
-	}
-	printk(KERN_DEBUG PFX "sample rate converter timeout r = 0x%08x\n", r);
-	return r;
-}
-
-static unsigned src_read(struct es1371_state *s, unsigned reg)
-{
-        unsigned int temp,i,orig;
-
-        /* wait for ready */
-        temp = wait_src_ready (s);
-
-        /* we can only access the SRC at certain times, make sure
-           we're allowed to before we read */
-           
-        orig = temp;
-        /* expose the SRC state bits */
-        outl ( (temp & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT) | 0x10000UL,
-               s->io + ES1371_REG_SRCONV);
-
-        /* now, wait for busy and the correct time to read */
-        temp = wait_src_ready (s);
-
-        if ( (temp & 0x00870000UL ) != ( SRC_OKSTATE << 16 )){
-                /* wait for the right state */
-                for (i=0; i<POLL_COUNT; i++){
-                        temp = inl (s->io + ES1371_REG_SRCONV);
-                        if ( (temp & 0x00870000UL ) == ( SRC_OKSTATE << 16 ))
-                                break;
-                }
-        }
-
-        /* hide the state bits */
-        outl ((orig & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT), s->io + ES1371_REG_SRCONV);
-        return temp;
-                        
-                
-}
-
-static void src_write(struct es1371_state *s, unsigned reg, unsigned data)
-{
-      
-	unsigned int r;
-
-	r = wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC);
-	r |= (reg << SRC_RAMADDR_SHIFT) & SRC_RAMADDR_MASK;
-	r |= (data << SRC_RAMDATA_SHIFT) & SRC_RAMDATA_MASK;
-	outl(r | SRC_WE, s->io + ES1371_REG_SRCONV);
-
-}
-
-/* --------------------------------------------------------------------- */
-
-/* most of the following here is black magic */
-static void set_adc_rate(struct es1371_state *s, unsigned rate)
-{
-	unsigned long flags;
-	unsigned int n, truncm, freq;
-
-	if (rate > 48000)
-		rate = 48000;
-	if (rate < 4000)
-		rate = 4000;
-	n = rate / 3000;
-	if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
-		n--;
-	truncm = (21 * n - 1) | 1;
-        freq = ((48000UL << 15) / rate) * n;
-	s->adcrate = (48000UL << 15) / (freq / n);
-	spin_lock_irqsave(&s->lock, flags);
-	if (rate >= 24000) {
-		if (truncm > 239)
-			truncm = 239;
-		src_write(s, SRCREG_ADC+SRCREG_TRUNC_N, 
-			  (((239 - truncm) >> 1) << 9) | (n << 4));
-	} else {
-		if (truncm > 119)
-			truncm = 119;
-		src_write(s, SRCREG_ADC+SRCREG_TRUNC_N, 
-			  0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));
-	}		
-	src_write(s, SRCREG_ADC+SRCREG_INT_REGS, 
-		  (src_read(s, SRCREG_ADC+SRCREG_INT_REGS) & 0x00ff) |
-		  ((freq >> 5) & 0xfc00));
-	src_write(s, SRCREG_ADC+SRCREG_VFREQ_FRAC, freq & 0x7fff);
-	src_write(s, SRCREG_VOL_ADC, n << 8);
-	src_write(s, SRCREG_VOL_ADC+1, n << 8);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void set_dac1_rate(struct es1371_state *s, unsigned rate)
-{
-	unsigned long flags;
-	unsigned int freq, r;
-
-	if (rate > 48000)
-		rate = 48000;
-	if (rate < 4000)
-		rate = 4000;
-        freq = ((rate << 15) + 1500) / 3000;
-	s->dac1rate = (freq * 3000 + 16384) >> 15;
-	spin_lock_irqsave(&s->lock, flags);
-	r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC2 | SRC_DADC)) | SRC_DDAC1;
-	outl(r, s->io + ES1371_REG_SRCONV);
-	src_write(s, SRCREG_DAC1+SRCREG_INT_REGS, 
-		  (src_read(s, SRCREG_DAC1+SRCREG_INT_REGS) & 0x00ff) |
-		  ((freq >> 5) & 0xfc00));
-	src_write(s, SRCREG_DAC1+SRCREG_VFREQ_FRAC, freq & 0x7fff);
-	r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC2 | SRC_DADC));
-	outl(r, s->io + ES1371_REG_SRCONV);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void set_dac2_rate(struct es1371_state *s, unsigned rate)
-{
-	unsigned long flags;
-	unsigned int freq, r;
-
-	if (rate > 48000)
-		rate = 48000;
-	if (rate < 4000)
-		rate = 4000;
-        freq = ((rate << 15) + 1500) / 3000;
-	s->dac2rate = (freq * 3000 + 16384) >> 15;
-	spin_lock_irqsave(&s->lock, flags);
-	r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DADC)) | SRC_DDAC2;
-	outl(r, s->io + ES1371_REG_SRCONV);
-	src_write(s, SRCREG_DAC2+SRCREG_INT_REGS, 
-		  (src_read(s, SRCREG_DAC2+SRCREG_INT_REGS) & 0x00ff) |
-		  ((freq >> 5) & 0xfc00));
-	src_write(s, SRCREG_DAC2+SRCREG_VFREQ_FRAC, freq & 0x7fff);
-	r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DADC));
-	outl(r, s->io + ES1371_REG_SRCONV);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static void __devinit src_init(struct es1371_state *s)
-{
-        unsigned int i;
-
-        /* before we enable or disable the SRC we need
-           to wait for it to become ready */
-        wait_src_ready(s);
-
-        outl(SRC_DIS, s->io + ES1371_REG_SRCONV);
-
-        for (i = 0; i < 0x80; i++)
-                src_write(s, i, 0);
-
-        src_write(s, SRCREG_DAC1+SRCREG_TRUNC_N, 16 << 4);
-        src_write(s, SRCREG_DAC1+SRCREG_INT_REGS, 16 << 10);
-        src_write(s, SRCREG_DAC2+SRCREG_TRUNC_N, 16 << 4);
-        src_write(s, SRCREG_DAC2+SRCREG_INT_REGS, 16 << 10);
-        src_write(s, SRCREG_VOL_ADC, 1 << 12);
-        src_write(s, SRCREG_VOL_ADC+1, 1 << 12);
-        src_write(s, SRCREG_VOL_DAC1, 1 << 12);
-        src_write(s, SRCREG_VOL_DAC1+1, 1 << 12);
-        src_write(s, SRCREG_VOL_DAC2, 1 << 12);
-        src_write(s, SRCREG_VOL_DAC2+1, 1 << 12);
-        set_adc_rate(s, 22050);
-        set_dac1_rate(s, 22050);
-        set_dac2_rate(s, 22050);
-
-        /* WARNING:
-         * enabling the sample rate converter without properly programming
-         * its parameters causes the chip to lock up (the SRC busy bit will
-         * be stuck high, and I've found no way to rectify this other than
-         * power cycle)
-         */
-        wait_src_ready(s);
-        outl(0, s->io+ES1371_REG_SRCONV);
-}
-
-/* --------------------------------------------------------------------- */
-
-static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
-{
-	struct es1371_state *s = (struct es1371_state *)codec->private_data;
-	unsigned long flags;
-	unsigned t, x;
-        
-	spin_lock_irqsave(&s->lock, flags);
-	for (t = 0; t < POLL_COUNT; t++)
-		if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
-			break;
-
-        /* save the current state for later */
-        x = wait_src_ready(s);
-
-        /* enable SRC state data in SRC mux */
-	outl((x & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)) | 0x00010000,
-	     s->io+ES1371_REG_SRCONV);
-
-        /* wait for not busy (state 0) first to avoid
-           transition states */
-        for (t=0; t<POLL_COUNT; t++){
-                if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0 )
-                    break;
-                udelay(1);
-        }
-        
-        /* wait for a SAFE time to write addr/data and then do it, dammit */
-        for (t=0; t<POLL_COUNT; t++){
-                if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0x00010000)
-                    break;
-                udelay(1);
-        }
-
-	outl(((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) |
-	     ((data << CODEC_PODAT_SHIFT) & CODEC_PODAT_MASK), s->io+ES1371_REG_CODEC);
-
-	/* restore SRC reg */
-	wait_src_ready(s);
-	outl(x, s->io+ES1371_REG_SRCONV);
-	spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static u16 rdcodec(struct ac97_codec *codec, u8 addr)
-{
-	struct es1371_state *s = (struct es1371_state *)codec->private_data;
-	unsigned long flags;
-	unsigned t, x;
-
-	spin_lock_irqsave(&s->lock, flags);
-	
-        /* wait for WIP to go away */
-	for (t = 0; t < 0x1000; t++)
-		if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
-			break;
-
-	/* save the current state for later */
-	x = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC));
-
-	/* enable SRC state data in SRC mux */
-	outl( x | 0x00010000,
-              s->io+ES1371_REG_SRCONV);
-
-        /* wait for not busy (state 0) first to avoid
-           transition states */
-        for (t=0; t<POLL_COUNT; t++){
-                if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0 )
-                    break;
-                udelay(1);
-        }
-        
-        /* wait for a SAFE time to write addr/data and then do it, dammit */
-        for (t=0; t<POLL_COUNT; t++){
-                if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0x00010000)
-                    break;
-                udelay(1);
-        }
-
-	outl(((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | CODEC_PORD, s->io+ES1371_REG_CODEC);
-	/* restore SRC reg */
-	wait_src_ready(s);
-	outl(x, s->io+ES1371_REG_SRCONV);
-
-        /* wait for WIP again */
-	for (t = 0; t < 0x1000; t++)
-		if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
-			break;
-        
-	/* now wait for the stinkin' data (RDY) */
-	for (t = 0; t < POLL_COUNT; t++)
-		if ((x = inl(s->io+ES1371_REG_CODEC)) & CODEC_RDY)
-			break;
-        
-	spin_unlock_irqrestore(&s->lock, flags);
-	return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT);
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_adc(struct es1371_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->ctrl &= ~CTRL_ADC_EN;
-	outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static inline void stop_dac1(struct es1371_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->ctrl &= ~CTRL_DAC1_EN;
-	outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static inline void stop_dac2(struct es1371_state *s)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->lock, flags);
-	s->ctrl &= ~CTRL_DAC2_EN;
-	outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static void start_dac1(struct es1371_state *s)
-{
-	unsigned long flags;
-	unsigned fragremain, fshift;
-
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->ctrl & CTRL_DAC1_EN) && (s->dma_dac1.mapped || s->dma_dac1.count > 0)
-	    && s->dma_dac1.ready) {
-		s->ctrl |= CTRL_DAC1_EN;
-		s->sctrl = (s->sctrl & ~(SCTRL_P1LOOPSEL | SCTRL_P1PAUSE | SCTRL_P1SCTRLD)) | SCTRL_P1INTEN;
-		outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-		fragremain = ((- s->dma_dac1.hwptr) & (s->dma_dac1.fragsize-1));
-		fshift = sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
-		if (fragremain < 2*fshift)
-			fragremain = s->dma_dac1.fragsize;
-		outl((fragremain >> fshift) - 1, s->io+ES1371_REG_DAC1_SCOUNT);
-		outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-		outl((s->dma_dac1.fragsize >> fshift) - 1, s->io+ES1371_REG_DAC1_SCOUNT);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static void start_dac2(struct es1371_state *s)
-{
-	unsigned long flags;
-	unsigned fragremain, fshift;
-
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->ctrl & CTRL_DAC2_EN) && (s->dma_dac2.mapped || s->dma_dac2.count > 0)
-	    && s->dma_dac2.ready) {
-		s->ctrl |= CTRL_DAC2_EN;
-		s->sctrl = (s->sctrl & ~(SCTRL_P2LOOPSEL | SCTRL_P2PAUSE | SCTRL_P2DACSEN | 
-					 SCTRL_P2ENDINC | SCTRL_P2STINC)) | SCTRL_P2INTEN |
-			(((s->sctrl & SCTRL_P2FMT) ? 2 : 1) << SCTRL_SH_P2ENDINC) | 
-			(0 << SCTRL_SH_P2STINC);
-		outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-		fragremain = ((- s->dma_dac2.hwptr) & (s->dma_dac2.fragsize-1));
-		fshift = sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
-		if (fragremain < 2*fshift)
-			fragremain = s->dma_dac2.fragsize;
-		outl((fragremain >> fshift) - 1, s->io+ES1371_REG_DAC2_SCOUNT);
-		outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-		outl((s->dma_dac2.fragsize >> fshift) - 1, s->io+ES1371_REG_DAC2_SCOUNT);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-static void start_adc(struct es1371_state *s)
-{
-	unsigned long flags;
-	unsigned fragremain, fshift;
-
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->ctrl & CTRL_ADC_EN) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
-	    && s->dma_adc.ready) {
-		s->ctrl |= CTRL_ADC_EN;
-		s->sctrl = (s->sctrl & ~SCTRL_R1LOOPSEL) | SCTRL_R1INTEN;
-		outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-		fragremain = ((- s->dma_adc.hwptr) & (s->dma_adc.fragsize-1));
-		fshift = sample_shift[(s->sctrl & SCTRL_R1FMT) >> SCTRL_SH_R1FMT];
-		if (fragremain < 2*fshift)
-			fragremain = s->dma_adc.fragsize;
-		outl((fragremain >> fshift) - 1, s->io+ES1371_REG_ADC_SCOUNT);
-		outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-		outl((s->dma_adc.fragsize >> fshift) - 1, s->io+ES1371_REG_ADC_SCOUNT);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-}	
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-
-static inline void dealloc_dmabuf(struct es1371_state *s, struct dmabuf *db)
-{
-	struct page *page, *pend;
-
-	if (db->rawbuf) {
-		/* undo marking the pages as reserved */
-		pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			ClearPageReserved(page);
-		pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-	}
-	db->rawbuf = NULL;
-	db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct es1371_state *s, struct dmabuf *db, unsigned rate, unsigned fmt, unsigned reg)
-{
-	int order;
-	unsigned bytepersec;
-	unsigned bufs;
-	struct page *page, *pend;
-
-	db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-	if (!db->rawbuf) {
-		db->ready = db->mapped = 0;
-		for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-			if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-				break;
-		if (!db->rawbuf)
-			return -ENOMEM;
-		db->buforder = order;
-		/* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-		pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-			SetPageReserved(page);
-	}
-	fmt &= ES1371_FMT_MASK;
-	bytepersec = rate << sample_shift[fmt];
-	bufs = PAGE_SIZE << db->buforder;
-	if (db->ossfragshift) {
-		if ((1000 << db->ossfragshift) < bytepersec)
-			db->fragshift = ld2(bytepersec/1000);
-		else
-			db->fragshift = db->ossfragshift;
-	} else {
-		db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-		if (db->fragshift < 3)
-			db->fragshift = 3;
-	}
-	db->numfrag = bufs >> db->fragshift;
-	while (db->numfrag < 4 && db->fragshift > 3) {
-		db->fragshift--;
-		db->numfrag = bufs >> db->fragshift;
-	}
-	db->fragsize = 1 << db->fragshift;
-	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-		db->numfrag = db->ossmaxfrags;
-	db->fragsamples = db->fragsize >> sample_shift[fmt];
-	db->dmasize = db->numfrag << db->fragshift;
-	memset(db->rawbuf, (fmt & ES1371_FMT_S16) ? 0 : 0x80, db->dmasize);
-	outl((reg >> 8) & 15, s->io+ES1371_REG_MEMPAGE);
-	outl(db->dmaaddr, s->io+(reg & 0xff));
-	outl((db->dmasize >> 2)-1, s->io+((reg + 4) & 0xff));
-	db->enabled = 1;
-	db->ready = 1;
-	return 0;
-}
-
-static inline int prog_dmabuf_adc(struct es1371_state *s)
-{
-	stop_adc(s);
-	return prog_dmabuf(s, &s->dma_adc, s->adcrate, (s->sctrl >> SCTRL_SH_R1FMT) & ES1371_FMT_MASK, 
-			   ES1371_REG_ADC_FRAMEADR);
-}
-
-static inline int prog_dmabuf_dac2(struct es1371_state *s)
-{
-	stop_dac2(s);
-	return prog_dmabuf(s, &s->dma_dac2, s->dac2rate, (s->sctrl >> SCTRL_SH_P2FMT) & ES1371_FMT_MASK, 
-			   ES1371_REG_DAC2_FRAMEADR);
-}
-
-static inline int prog_dmabuf_dac1(struct es1371_state *s)
-{
-	stop_dac1(s);
-	return prog_dmabuf(s, &s->dma_dac1, s->dac1rate, (s->sctrl >> SCTRL_SH_P1FMT) & ES1371_FMT_MASK,
-			   ES1371_REG_DAC1_FRAMEADR);
-}
-
-static inline unsigned get_hwptr(struct es1371_state *s, struct dmabuf *db, unsigned reg)
-{
-	unsigned hwptr, diff;
-
-	outl((reg >> 8) & 15, s->io+ES1371_REG_MEMPAGE);
-	hwptr = (inl(s->io+(reg & 0xff)) >> 14) & 0x3fffc;
-	diff = (db->dmasize + hwptr - db->hwptr) % db->dmasize;
-	db->hwptr = hwptr;
-	return diff;
-}
-
-static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c)
-{
-	if (bptr + len > bsize) {
-		unsigned x = bsize - bptr;
-		memset(((char *)buf) + bptr, c, x);
-		bptr = 0;
-		len -= x;
-	}
-	memset(((char *)buf) + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void es1371_update_ptr(struct es1371_state *s)
-{
-	int diff;
-
-	/* update ADC pointer */
-	if (s->ctrl & CTRL_ADC_EN) {
-		diff = get_hwptr(s, &s->dma_adc, ES1371_REG_ADC_FRAMECNT);
-		s->dma_adc.total_bytes += diff;
-		s->dma_adc.count += diff;
-		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-			wake_up(&s->dma_adc.wait);
-		if (!s->dma_adc.mapped) {
-			if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-				s->ctrl &= ~CTRL_ADC_EN;
-				outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-				s->dma_adc.error++;
-			}
-		}
-	}
-	/* update DAC1 pointer */
-	if (s->ctrl & CTRL_DAC1_EN) {
-		diff = get_hwptr(s, &s->dma_dac1, ES1371_REG_DAC1_FRAMECNT);
-		s->dma_dac1.total_bytes += diff;
-		if (s->dma_dac1.mapped) {
-			s->dma_dac1.count += diff;
-			if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
-				wake_up(&s->dma_dac1.wait);
-		} else {
-			s->dma_dac1.count -= diff;
-			if (s->dma_dac1.count <= 0) {
-				s->ctrl &= ~CTRL_DAC1_EN;
-				outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-				s->dma_dac1.error++;
-			} else if (s->dma_dac1.count <= (signed)s->dma_dac1.fragsize && !s->dma_dac1.endcleared) {
-				clear_advance(s->dma_dac1.rawbuf, s->dma_dac1.dmasize, s->dma_dac1.swptr, 
-					      s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80);
-				s->dma_dac1.endcleared = 1;
-			}
-			if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize)
-				wake_up(&s->dma_dac1.wait);
-		}
-	}
-	/* update DAC2 pointer */
-	if (s->ctrl & CTRL_DAC2_EN) {
-		diff = get_hwptr(s, &s->dma_dac2, ES1371_REG_DAC2_FRAMECNT);
-		s->dma_dac2.total_bytes += diff;
-		if (s->dma_dac2.mapped) {
-			s->dma_dac2.count += diff;
-			if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize)
-				wake_up(&s->dma_dac2.wait);
-		} else {
-			s->dma_dac2.count -= diff;
-			if (s->dma_dac2.count <= 0) {
-				s->ctrl &= ~CTRL_DAC2_EN;
-				outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-				s->dma_dac2.error++;
-			} else if (s->dma_dac2.count <= (signed)s->dma_dac2.fragsize && !s->dma_dac2.endcleared) {
-				clear_advance(s->dma_dac2.rawbuf, s->dma_dac2.dmasize, s->dma_dac2.swptr, 
-					      s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80);
-				s->dma_dac2.endcleared = 1;
-			}
-			if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize)
-				wake_up(&s->dma_dac2.wait);
-		}
-	}
-}
-
-/* hold spinlock for the following! */
-static void es1371_handle_midi(struct es1371_state *s)
-{
-	unsigned char ch;
-	int wake;
-
-	if (!(s->ctrl & CTRL_UART_EN))
-		return;
-	wake = 0;
-	while (inb(s->io+ES1371_REG_UART_STATUS) & USTAT_RXRDY) {
-		ch = inb(s->io+ES1371_REG_UART_DATA);
-		if (s->midi.icnt < MIDIINBUF) {
-			s->midi.ibuf[s->midi.iwr] = ch;
-			s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-			s->midi.icnt++;
-		}
-		wake = 1;
-	}
-	if (wake)
-		wake_up(&s->midi.iwait);
-	wake = 0;
-	while ((inb(s->io+ES1371_REG_UART_STATUS) & USTAT_TXRDY) && s->midi.ocnt > 0) {
-		outb(s->midi.obuf[s->midi.ord], s->io+ES1371_REG_UART_DATA);
-		s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-		s->midi.ocnt--;
-		if (s->midi.ocnt < MIDIOUTBUF-16)
-			wake = 1;
-	}
-	if (wake)
-		wake_up(&s->midi.owait);
-	outb((s->midi.ocnt > 0) ? UCTRL_RXINTEN | UCTRL_ENA_TXINT : UCTRL_RXINTEN, s->io+ES1371_REG_UART_CONTROL);
-}
-
-static irqreturn_t es1371_interrupt(int irq, void *dev_id)
-{
-        struct es1371_state *s = dev_id;
-	unsigned int intsrc, sctl;
-	
-	/* fastpath out, to ease interrupt sharing */
-	intsrc = inl(s->io+ES1371_REG_STATUS);
-	if (!(intsrc & 0x80000000))
-		return IRQ_NONE;
-	spin_lock(&s->lock);
-	/* clear audio interrupts first */
-	sctl = s->sctrl;
-	if (intsrc & STAT_ADC)
-		sctl &= ~SCTRL_R1INTEN;
-	if (intsrc & STAT_DAC1)
-		sctl &= ~SCTRL_P1INTEN;
-	if (intsrc & STAT_DAC2)
-		sctl &= ~SCTRL_P2INTEN;
-	outl(sctl, s->io+ES1371_REG_SERIAL_CONTROL);
-	outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-	es1371_update_ptr(s);
-	es1371_handle_midi(s);
-	spin_unlock(&s->lock);
-	return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT PFX "invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-	if (!(s) || (s)->magic != ES1371_MAGIC) { \
-		printk(invalid_magic);            \
-		return -ENXIO;                    \
-	}                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-/* Conversion table for S/PDIF PCM volume emulation through the SRC */
-/* dB-linear table of DAC vol values; -0dB to -46.5dB with mute */
-static const unsigned short DACVolTable[101] =
-{
-	0x1000, 0x0f2a, 0x0e60, 0x0da0, 0x0cea, 0x0c3e, 0x0b9a, 0x0aff,
-	0x0a6d, 0x09e1, 0x095e, 0x08e1, 0x086a, 0x07fa, 0x078f, 0x072a,
-	0x06cb, 0x0670, 0x061a, 0x05c9, 0x057b, 0x0532, 0x04ed, 0x04ab,
-	0x046d, 0x0432, 0x03fa, 0x03c5, 0x0392, 0x0363, 0x0335, 0x030b,
-	0x02e2, 0x02bc, 0x0297, 0x0275, 0x0254, 0x0235, 0x0217, 0x01fb,
-	0x01e1, 0x01c8, 0x01b0, 0x0199, 0x0184, 0x0170, 0x015d, 0x014b,
-	0x0139, 0x0129, 0x0119, 0x010b, 0x00fd, 0x00f0, 0x00e3, 0x00d7,
-	0x00cc, 0x00c1, 0x00b7, 0x00ae, 0x00a5, 0x009c, 0x0094, 0x008c,
-	0x0085, 0x007e, 0x0077, 0x0071, 0x006b, 0x0066, 0x0060, 0x005b,
-	0x0057, 0x0052, 0x004e, 0x004a, 0x0046, 0x0042, 0x003f, 0x003c,
-	0x0038, 0x0036, 0x0033, 0x0030, 0x002e, 0x002b, 0x0029, 0x0027,
-	0x0025, 0x0023, 0x0021, 0x001f, 0x001e, 0x001c, 0x001b, 0x0019,
-	0x0018, 0x0017, 0x0016, 0x0014, 0x0000
-};
-
-/*
- * when we are in S/PDIF mode, we want to disable any analog output so
- * we filter the mixer ioctls 
- */
-static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg)
-{
-	struct es1371_state *s = (struct es1371_state *)codec->private_data;
-	int val;
-	unsigned long flags;
-	unsigned int left, right;
-
-	VALIDATE_STATE(s);
-	/* filter mixer ioctls to catch PCM and MASTER volume when in S/PDIF mode */
-	if (s->spdif_volume == -1)
-		return codec->mixer_ioctl(codec, cmd, arg);
-	switch (cmd) {
-	case SOUND_MIXER_WRITE_VOLUME:
-		return 0;
-
-	case SOUND_MIXER_WRITE_PCM:   /* use SRC for PCM volume */
-		if (get_user(val, (int __user *)arg))
-			return -EFAULT;
-		right = ((val >> 8)  & 0xff);
-		left = (val  & 0xff);
-		if (right > 100)
-			right = 100;
-		if (left > 100)
-			left = 100;
-		s->spdif_volume = (right << 8) | left;
-		spin_lock_irqsave(&s->lock, flags);
-		src_write(s, SRCREG_VOL_DAC2, DACVolTable[100 - left]);
-		src_write(s, SRCREG_VOL_DAC2+1, DACVolTable[100 - right]);
-		spin_unlock_irqrestore(&s->lock, flags);
-		return 0;
-	
-	case SOUND_MIXER_READ_PCM:
-		return put_user(s->spdif_volume, (int __user *)arg);
-	}
-	return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * AC97 Mixer Register to Connections mapping of the Concert 97 board
- *
- * AC97_MASTER_VOL_STEREO   Line Out
- * AC97_MASTER_VOL_MONO     TAD Output
- * AC97_PCBEEP_VOL          none
- * AC97_PHONE_VOL           TAD Input (mono)
- * AC97_MIC_VOL             MIC Input (mono)
- * AC97_LINEIN_VOL          Line Input (stereo)
- * AC97_CD_VOL              CD Input (stereo)
- * AC97_VIDEO_VOL           none
- * AC97_AUX_VOL             Aux Input (stereo)
- * AC97_PCMOUT_VOL          Wave Output (stereo)
- */
-
-static int es1371_open_mixdev(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	struct list_head *list;
-	struct es1371_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct es1371_state, devs);
-		if (s->codec->dev_mixer == minor)
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	return nonseekable_open(inode, file);
-}
-
-static int es1371_release_mixdev(struct inode *inode, struct file *file)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	
-	VALIDATE_STATE(s);
-	return 0;
-}
-
-static int es1371_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	struct ac97_codec *codec = s->codec;
-
-	return mixdev_ioctl(codec, cmd, arg);
-}
-
-static /*const*/ struct file_operations es1371_mixer_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.ioctl		= es1371_ioctl_mixdev,
-	.open		= es1371_open_mixdev,
-	.release	= es1371_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac1(struct es1371_state *s, int nonblock)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	int count, tmo;
-	
-	if (s->dma_dac1.mapped || !s->dma_dac1.ready)
-		return 0;
-        add_wait_queue(&s->dma_dac1.wait, &wait);
-        for (;;) {
-		__set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac1.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0)
-			break;
-		if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac1.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-		tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 / s->dac1rate;
-		tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
-		if (!schedule_timeout(tmo + 1))
-			DBG(printk(KERN_DEBUG PFX "dac1 dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac1.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-static int drain_dac2(struct es1371_state *s, int nonblock)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	int count, tmo;
-
-	if (s->dma_dac2.mapped || !s->dma_dac2.ready)
-		return 0;
-        add_wait_queue(&s->dma_dac2.wait, &wait);
-        for (;;) {
-		__set_current_state(TASK_UNINTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-		count = s->dma_dac2.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-		if (count <= 0)
-			break;
-		if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac2.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-		tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 / s->dac2rate;
-		tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
-		if (!schedule_timeout(tmo + 1))
-			DBG(printk(KERN_DEBUG PFX "dac2 dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac2.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret = 0;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (s->dma_adc.mapped)
-		return -ENXIO;
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	mutex_lock(&s->sem);
-	if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-		goto out2;
-	
-	add_wait_queue(&s->dma_adc.wait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		swptr = s->dma_adc.swptr;
-		cnt = s->dma_adc.dmasize-swptr;
-		if (s->dma_adc.count < cnt)
-			cnt = s->dma_adc.count;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (s->dma_adc.enabled)
-				start_adc(s);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				goto out;
-			}
-			mutex_unlock(&s->sem);
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				goto out2;
-			}
-			mutex_lock(&s->sem);
-			if (s->dma_adc.mapped)
-			{
-				ret = -ENXIO;
-				goto out;
-			}
-			continue;
-		}
-		if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			goto out;
-		}
-		swptr = (swptr + cnt) % s->dma_adc.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_adc.swptr = swptr;
-		s->dma_adc.count -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		if (s->dma_adc.enabled)
-			start_adc(s);
-	}
-out:
-	mutex_unlock(&s->sem);
-out2:
-	remove_wait_queue(&s->dma_adc.wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (s->dma_dac2.mapped)
-		return -ENXIO;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	mutex_lock(&s->sem);
-	if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-		goto out3;
-	ret = 0;
-	add_wait_queue(&s->dma_dac2.wait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		if (s->dma_dac2.count < 0) {
-			s->dma_dac2.count = 0;
-			s->dma_dac2.swptr = s->dma_dac2.hwptr;
-		}
-		swptr = s->dma_dac2.swptr;
-		cnt = s->dma_dac2.dmasize-swptr;
-		if (s->dma_dac2.count + cnt > s->dma_dac2.dmasize)
-			cnt = s->dma_dac2.dmasize - s->dma_dac2.count;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (s->dma_dac2.enabled)
-				start_dac2(s);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				goto out;
-			}	
-			mutex_unlock(&s->sem);
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				goto out2;
-			}
-			mutex_lock(&s->sem);
-			if (s->dma_dac2.mapped)
-			{
-				ret = -ENXIO;
-				goto out;
-			}
-			continue;
-		}
-		if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			goto out;
-		}
-		swptr = (swptr + cnt) % s->dma_dac2.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_dac2.swptr = swptr;
-		s->dma_dac2.count += cnt;
-		s->dma_dac2.endcleared = 0;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		if (s->dma_dac2.enabled)
-			start_dac2(s);
-	}
-out:
-	mutex_unlock(&s->sem);
-out2:
-	remove_wait_queue(&s->dma_dac2.wait, &wait);
-out3:	
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1371_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE) {
-		if (!s->dma_dac2.ready && prog_dmabuf_dac2(s))
-			return 0;
-		poll_wait(file, &s->dma_dac2.wait, wait);
-	}
-	if (file->f_mode & FMODE_READ) {
-		if (!s->dma_adc.ready && prog_dmabuf_adc(s))
-			return 0;
-		poll_wait(file, &s->dma_adc.wait, wait);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	es1371_update_ptr(s);
-	if (file->f_mode & FMODE_READ) {
-			if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-				mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->dma_dac2.mapped) {
-			if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) 
-				mask |= POLLOUT | POLLWRNORM;
-		} else {
-			if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize)
-				mask |= POLLOUT | POLLWRNORM;
-		}
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int es1371_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	struct dmabuf *db;
-	int ret = 0;
-	unsigned long size;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	mutex_lock(&s->sem);
-	
-	if (vma->vm_flags & VM_WRITE) {
-		if ((ret = prog_dmabuf_dac2(s)) != 0) {
-			goto out;
-		}
-		db = &s->dma_dac2;
-	} else if (vma->vm_flags & VM_READ) {
-		if ((ret = prog_dmabuf_adc(s)) != 0) {
-			goto out;
-		}
-		db = &s->dma_adc;
-	} else {
-		ret = -EINVAL;
-		goto out;
-	}
-	if (vma->vm_pgoff != 0) {
-		ret = -EINVAL;
-		goto out;
-	}
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << db->buforder)) {
-		ret = -EINVAL;
-		goto out;
-	}
-	if (remap_pfn_range(vma, vma->vm_start,
-				virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-				size, vma->vm_page_prot)) {
-		ret = -EAGAIN;
-		goto out;
-	}
-	db->mapped = 1;
-out:
-	mutex_unlock(&s->sem);
-	unlock_kernel();
-	return ret;
-}
-
-static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-	int count;
-	int val, mapped, ret;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac2.mapped) ||
-		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-	switch (cmd) {
-	case OSS_GETVERSION:
-		return put_user(SOUND_VERSION, p);
-
-	case SNDCTL_DSP_SYNC:
-		if (file->f_mode & FMODE_WRITE)
-			return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/);
-		return 0;
-		
-	case SNDCTL_DSP_SETDUPLEX:
-		return 0;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-		
-        case SNDCTL_DSP_RESET:
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac2(s);
-			synchronize_irq(s->irq);
-			s->dma_dac2.swptr = s->dma_dac2.hwptr = s->dma_dac2.count = s->dma_dac2.total_bytes = 0;
-		}
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			synchronize_irq(s->irq);
-			s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-		}
-		return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val >= 0) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				set_adc_rate(s, val);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac2(s);
-				s->dma_dac2.ready = 0;
-				set_dac2_rate(s, val);
-			}
-		}
-		return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p);
-
-        case SNDCTL_DSP_STEREO:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			stop_adc(s);
-			s->dma_adc.ready = 0;
-			spin_lock_irqsave(&s->lock, flags);
-			if (val)
-				s->sctrl |= SCTRL_R1SMB;
-			else
-				s->sctrl &= ~SCTRL_R1SMB;
-			outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-			spin_unlock_irqrestore(&s->lock, flags);
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			stop_dac2(s);
-			s->dma_dac2.ready = 0;
-			spin_lock_irqsave(&s->lock, flags);
-			if (val)
-				s->sctrl |= SCTRL_P2SMB;
-			else
-				s->sctrl &= ~SCTRL_P2SMB;
-			outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-			spin_unlock_irqrestore(&s->lock, flags);
-                }
-		return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 0) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				spin_lock_irqsave(&s->lock, flags);
-				if (val >= 2)
-					s->sctrl |= SCTRL_R1SMB;
-				else
-					s->sctrl &= ~SCTRL_R1SMB;
-				outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac2(s);
-				s->dma_dac2.ready = 0;
-				spin_lock_irqsave(&s->lock, flags);
-				if (val >= 2)
-					s->sctrl |= SCTRL_P2SMB;
-				else
-					s->sctrl &= ~SCTRL_P2SMB;
-				outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-		}
-		return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p);
-		
-	case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-		
-	case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != AFMT_QUERY) {
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(s);
-				s->dma_adc.ready = 0;
-				spin_lock_irqsave(&s->lock, flags);
-				if (val == AFMT_S16_LE)
-					s->sctrl |= SCTRL_R1SEB;
-				else
-					s->sctrl &= ~SCTRL_R1SEB;
-				outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac2(s);
-				s->dma_dac2.ready = 0;
-				spin_lock_irqsave(&s->lock, flags);
-				if (val == AFMT_S16_LE)
-					s->sctrl |= SCTRL_P2SEB;
-				else
-					s->sctrl &= ~SCTRL_P2SEB;
-				outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-				spin_unlock_irqrestore(&s->lock, flags);
-			}
-		}
-		return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 
-				AFMT_S16_LE : AFMT_U8, p);
-		
-	case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-		val = 0;
-		if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) 
-			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) 
-			val |= PCM_ENABLE_OUTPUT;
-		return put_user(val, p);
-		
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			if (val & PCM_ENABLE_INPUT) {
-				if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-					return ret;
-				s->dma_adc.enabled = 1;
-				start_adc(s);
-			} else {
-				s->dma_adc.enabled = 0;
-				stop_adc(s);
-			}
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			if (val & PCM_ENABLE_OUTPUT) {
-				if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-					return ret;
-				s->dma_dac2.enabled = 1;
-				start_dac2(s);
-			} else {
-				s->dma_dac2.enabled = 0;
-				stop_dac2(s);
-			}
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1371_update_ptr(s);
-		abinfo.fragsize = s->dma_dac2.fragsize;
-		count = s->dma_dac2.count;
-		if (count < 0)
-			count = 0;
-                abinfo.bytes = s->dma_dac2.dmasize - count;
-                abinfo.fragstotal = s->dma_dac2.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift;      
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-	case SNDCTL_DSP_GETISPACE:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1371_update_ptr(s);
-		abinfo.fragsize = s->dma_adc.fragsize;
-		count = s->dma_adc.count;
-		if (count < 0)
-			count = 0;
-                abinfo.bytes = count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-		
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1371_update_ptr(s);
-                count = s->dma_dac2.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		return put_user(count, p);
-
-        case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1371_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-		count = s->dma_adc.count;
-		if (count < 0)
-			count = 0;
-                cinfo.blocks = count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-		if (s->dma_adc.mapped)
-			s->dma_adc.count &= s->dma_adc.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1371_update_ptr(s);
-                cinfo.bytes = s->dma_dac2.total_bytes;
-		count = s->dma_dac2.count;
-		if (count < 0)
-			count = 0;
-                cinfo.blocks = count >> s->dma_dac2.fragshift;
-                cinfo.ptr = s->dma_dac2.hwptr;
-		if (s->dma_dac2.mapped)
-			s->dma_dac2.count &= s->dma_dac2.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-		if (file->f_mode & FMODE_WRITE) {
-			if ((val = prog_dmabuf_dac2(s)))
-				return val;
-			return put_user(s->dma_dac2.fragsize, p);
-		}
-		if ((val = prog_dmabuf_adc(s)))
-			return val;
-		return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (file->f_mode & FMODE_READ) {
-			s->dma_adc.ossfragshift = val & 0xffff;
-			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_adc.ossfragshift < 4)
-				s->dma_adc.ossfragshift = 4;
-			if (s->dma_adc.ossfragshift > 15)
-				s->dma_adc.ossfragshift = 15;
-			if (s->dma_adc.ossmaxfrags < 4)
-				s->dma_adc.ossmaxfrags = 4;
-		}
-		if (file->f_mode & FMODE_WRITE) {
-			s->dma_dac2.ossfragshift = val & 0xffff;
-			s->dma_dac2.ossmaxfrags = (val >> 16) & 0xffff;
-			if (s->dma_dac2.ossfragshift < 4)
-				s->dma_dac2.ossfragshift = 4;
-			if (s->dma_dac2.ossfragshift > 15)
-				s->dma_dac2.ossfragshift = 15;
-			if (s->dma_dac2.ossmaxfrags < 4)
-				s->dma_dac2.ossmaxfrags = 4;
-		}
-		return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-		    (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
-			return -EINVAL;
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		if (file->f_mode & FMODE_READ)
-			s->dma_adc.subdivision = val;
-		if (file->f_mode & FMODE_WRITE)
-			s->dma_dac2.subdivision = val;
-		return 0;
-
-        case SOUND_PCM_READ_RATE:
-		return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-		return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p);
-		
-        case SOUND_PCM_READ_BITS:
-		return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-		
-	}
-	return mixdev_ioctl(s->codec, cmd, arg);
-}
-
-static int es1371_open(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	struct list_head *list;
-	struct es1371_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct es1371_state, devs);
-		if (!((s->dev_audio ^ minor) & ~0xf))
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & file->f_mode) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	if (file->f_mode & FMODE_READ) {
-		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-		s->dma_adc.enabled = 1;
-		set_adc_rate(s, 8000);
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->dma_dac2.ossfragshift = s->dma_dac2.ossmaxfrags = s->dma_dac2.subdivision = 0;
-		s->dma_dac2.enabled = 1;
-		set_dac2_rate(s, 8000);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	if (file->f_mode & FMODE_READ) {
-		s->sctrl &= ~SCTRL_R1FMT;
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_R1FMT;
-		else
-			s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_R1FMT;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->sctrl &= ~SCTRL_P2FMT;
-		if ((minor & 0xf) == SND_DEV_DSP16)
-			s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_P2FMT;
-		else
-			s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_P2FMT;
-	}
-	outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-	mutex_unlock(&s->open_mutex);
-	mutex_init(&s->sem);
-	return nonseekable_open(inode, file);
-}
-
-static int es1371_release(struct inode *inode, struct file *file)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	if (file->f_mode & FMODE_WRITE)
-		drain_dac2(s, file->f_flags & O_NONBLOCK);
-	mutex_lock(&s->open_mutex);
-	if (file->f_mode & FMODE_WRITE) {
-		stop_dac2(s);
-		dealloc_dmabuf(s, &s->dma_dac2);
-	}
-	if (file->f_mode & FMODE_READ) {
-		stop_adc(s);
-		dealloc_dmabuf(s, &s->dma_adc);
-	}
-	s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
-	mutex_unlock(&s->open_mutex);
-	wake_up(&s->open_wait);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations es1371_audio_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= es1371_read,
-	.write		= es1371_write,
-	.poll		= es1371_poll,
-	.ioctl		= es1371_ioctl,
-	.mmap		= es1371_mmap,
-	.open		= es1371_open,
-	.release	= es1371_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1371_write_dac(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret = 0;
-	unsigned long flags;
-	unsigned swptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (s->dma_dac1.mapped)
-		return -ENXIO;
-	if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
-		return ret;
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	add_wait_queue(&s->dma_dac1.wait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		if (s->dma_dac1.count < 0) {
-			s->dma_dac1.count = 0;
-			s->dma_dac1.swptr = s->dma_dac1.hwptr;
-		}
-		swptr = s->dma_dac1.swptr;
-		cnt = s->dma_dac1.dmasize-swptr;
-		if (s->dma_dac1.count + cnt > s->dma_dac1.dmasize)
-			cnt = s->dma_dac1.dmasize - s->dma_dac1.count;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (s->dma_dac1.enabled)
-				start_dac1(s);
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		swptr = (swptr + cnt) % s->dma_dac1.dmasize;
-		spin_lock_irqsave(&s->lock, flags);
-		s->dma_dac1.swptr = swptr;
-		s->dma_dac1.count += cnt;
-		s->dma_dac1.endcleared = 0;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		if (s->dma_dac1.enabled)
-			start_dac1(s);
-	}
-	remove_wait_queue(&s->dma_dac1.wait, &wait);
-	set_current_state(TASK_RUNNING);
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1371_poll_dac(struct file *file, struct poll_table_struct *wait)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (!s->dma_dac1.ready && prog_dmabuf_dac1(s))
-		return 0;
-	poll_wait(file, &s->dma_dac1.wait, wait);
-	spin_lock_irqsave(&s->lock, flags);
-	es1371_update_ptr(s);
-	if (s->dma_dac1.mapped) {
-		if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
-			mask |= POLLOUT | POLLWRNORM;
-	} else {
-		if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize)
-			mask |= POLLOUT | POLLWRNORM;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int es1371_mmap_dac(struct file *file, struct vm_area_struct *vma)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	int ret;
-	unsigned long size;
-
-	VALIDATE_STATE(s);
-	if (!(vma->vm_flags & VM_WRITE))
-		return -EINVAL;
-	lock_kernel();
-	if ((ret = prog_dmabuf_dac1(s)) != 0)
-		goto out;
-	ret = -EINVAL;
-	if (vma->vm_pgoff != 0)
-		goto out;
-	size = vma->vm_end - vma->vm_start;
-	if (size > (PAGE_SIZE << s->dma_dac1.buforder))
-		goto out;
-	ret = -EAGAIN;
-	if (remap_pfn_range(vma, vma->vm_start,
-			virt_to_phys(s->dma_dac1.rawbuf) >> PAGE_SHIFT,
-			size, vma->vm_page_prot))
-		goto out;
-	s->dma_dac1.mapped = 1;
-	ret = 0;
-out:
-	unlock_kernel();
-	return ret;
-}
-
-static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-	int count;
-	int val, ret;
-	int __user *p = (int __user *)arg;
-
-	VALIDATE_STATE(s);
-	switch (cmd) {
-	case OSS_GETVERSION:
-		return put_user(SOUND_VERSION, p);
-
-	case SNDCTL_DSP_SYNC:
-		return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/);
-		
-	case SNDCTL_DSP_SETDUPLEX:
-		return -EINVAL;
-
-	case SNDCTL_DSP_GETCAPS:
-		return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-		
-        case SNDCTL_DSP_RESET:
-		stop_dac1(s);
-		synchronize_irq(s->irq);
-		s->dma_dac1.swptr = s->dma_dac1.hwptr = s->dma_dac1.count = s->dma_dac1.total_bytes = 0;
-		return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val >= 0) {
-			stop_dac1(s);
-			s->dma_dac1.ready = 0;
-			set_dac1_rate(s, val);
-		}
-		return put_user(s->dac1rate, p);
-
-        case SNDCTL_DSP_STEREO:
-		if (get_user(val, p))
-			return -EFAULT;
-		stop_dac1(s);
-		s->dma_dac1.ready = 0;
-		spin_lock_irqsave(&s->lock, flags);
-		if (val)
-			s->sctrl |= SCTRL_P1SMB;
-		else
-			s->sctrl &= ~SCTRL_P1SMB;
-		outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-		spin_unlock_irqrestore(&s->lock, flags);
-		return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 0) {
-			stop_dac1(s);
-			s->dma_dac1.ready = 0;
-			spin_lock_irqsave(&s->lock, flags);
-			if (val >= 2)
-				s->sctrl |= SCTRL_P1SMB;
-			else
-				s->sctrl &= ~SCTRL_P1SMB;
-			outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-			spin_unlock_irqrestore(&s->lock, flags);
-		}
-		return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
-		
-        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-		
-        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val != AFMT_QUERY) {
-			stop_dac1(s);
-			s->dma_dac1.ready = 0;
-			spin_lock_irqsave(&s->lock, flags);
-			if (val == AFMT_S16_LE)
-				s->sctrl |= SCTRL_P1SEB;
-			else
-				s->sctrl &= ~SCTRL_P1SEB;
-			outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-			spin_unlock_irqrestore(&s->lock, flags);
-		}
-		return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, p);
-
-        case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-		return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p);
-						
-	case SNDCTL_DSP_SETTRIGGER:
-		if (get_user(val, p))
-			return -EFAULT;
-		if (val & PCM_ENABLE_OUTPUT) {
-			if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
-				return ret;
-			s->dma_dac1.enabled = 1;
-			start_dac1(s);
-		} else {
-			s->dma_dac1.enabled = 0;
-			stop_dac1(s);
-		}
-		return 0;
-
-	case SNDCTL_DSP_GETOSPACE:
-		if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1371_update_ptr(s);
-		abinfo.fragsize = s->dma_dac1.fragsize;
-		count = s->dma_dac1.count;
-		if (count < 0)
-			count = 0;
-                abinfo.bytes = s->dma_dac1.dmasize - count;
-                abinfo.fragstotal = s->dma_dac1.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac1.fragshift;      
-		spin_unlock_irqrestore(&s->lock, flags);
-		return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-		if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1371_update_ptr(s);
-                count = s->dma_dac1.count;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (count < 0)
-			count = 0;
-		return put_user(count, p);
-
-        case SNDCTL_DSP_GETOPTR:
-		if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-			return val;
-		spin_lock_irqsave(&s->lock, flags);
-		es1371_update_ptr(s);
-                cinfo.bytes = s->dma_dac1.total_bytes;
-		count = s->dma_dac1.count;
-		if (count < 0)
-			count = 0;
-                cinfo.blocks = count >> s->dma_dac1.fragshift;
-                cinfo.ptr = s->dma_dac1.hwptr;
-		if (s->dma_dac1.mapped)
-			s->dma_dac1.count &= s->dma_dac1.fragsize-1;
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
-			return -EFAULT;
-		return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-		if ((val = prog_dmabuf_dac1(s)))
-			return val;
-                return put_user(s->dma_dac1.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-			return -EFAULT;
-		s->dma_dac1.ossfragshift = val & 0xffff;
-		s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff;
-		if (s->dma_dac1.ossfragshift < 4)
-			s->dma_dac1.ossfragshift = 4;
-		if (s->dma_dac1.ossfragshift > 15)
-			s->dma_dac1.ossfragshift = 15;
-		if (s->dma_dac1.ossmaxfrags < 4)
-			s->dma_dac1.ossmaxfrags = 4;
-		return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-		if (s->dma_dac1.subdivision)
-			return -EINVAL;
-                if (get_user(val, p))
-			return -EFAULT;
-		if (val != 1 && val != 2 && val != 4)
-			return -EINVAL;
-		s->dma_dac1.subdivision = val;
-		return 0;
-
-        case SOUND_PCM_READ_RATE:
-		return put_user(s->dac1rate, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-		return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-		return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-		
-	}
-	return mixdev_ioctl(s->codec, cmd, arg);
-}
-
-static int es1371_open_dac(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	struct list_head *list;
-	struct es1371_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct es1371_state, devs);
-		if (!((s->dev_dac ^ minor) & ~0xf))
-			break;
-	}
-       	VALIDATE_STATE(s);
-       	/* we allow opening with O_RDWR, most programs do it although they will only write */
-#if 0
-	if (file->f_mode & FMODE_READ)
-		return -EPERM;
-#endif
-	if (!(file->f_mode & FMODE_WRITE))
-		return -EINVAL;
-       	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & FMODE_DAC) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0;
-	s->dma_dac1.enabled = 1;
-	set_dac1_rate(s, 8000);
-	spin_lock_irqsave(&s->lock, flags);
-	s->sctrl &= ~SCTRL_P1FMT;
-	if ((minor & 0xf) == SND_DEV_DSP16)
-		s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_P1FMT;
-	else
-		s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_P1FMT;
-	outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->open_mode |= FMODE_DAC;
-	mutex_unlock(&s->open_mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int es1371_release_dac(struct inode *inode, struct file *file)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	drain_dac1(s, file->f_flags & O_NONBLOCK);
-	mutex_lock(&s->open_mutex);
-	stop_dac1(s);
-	dealloc_dmabuf(s, &s->dma_dac1);
-	s->open_mode &= ~FMODE_DAC;
-	mutex_unlock(&s->open_mutex);
-	wake_up(&s->open_wait);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations es1371_dac_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.write		= es1371_write_dac,
-	.poll		= es1371_poll_dac,
-	.ioctl		= es1371_ioctl_dac,
-	.mmap		= es1371_mmap_dac,
-	.open		= es1371_open_dac,
-	.release	= es1371_release_dac,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1371_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned ptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (!access_ok(VERIFY_WRITE, buffer, count))
-		return -EFAULT;
-	if (count == 0)
-		return 0;
-	ret = 0;
-        add_wait_queue(&s->midi.iwait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		ptr = s->midi.ird;
-		cnt = MIDIINBUF - ptr;
-		if (s->midi.icnt < cnt)
-			cnt = s->midi.icnt;
-		if (cnt <= 0)
-			__set_current_state(TASK_INTERRUPTIBLE);
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		ptr = (ptr + cnt) % MIDIINBUF;
-		spin_lock_irqsave(&s->lock, flags);
-		s->midi.ird = ptr;
-		s->midi.icnt -= cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		break;
-	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&s->midi.iwait, &wait);
-	return ret;
-}
-
-static ssize_t es1371_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t ret;
-	unsigned long flags;
-	unsigned ptr;
-	int cnt;
-
-	VALIDATE_STATE(s);
-	if (!access_ok(VERIFY_READ, buffer, count))
-		return -EFAULT;
-	if (count == 0)
-		return 0;
-	ret = 0;
-        add_wait_queue(&s->midi.owait, &wait);
-	while (count > 0) {
-		spin_lock_irqsave(&s->lock, flags);
-		ptr = s->midi.owr;
-		cnt = MIDIOUTBUF - ptr;
-		if (s->midi.ocnt + cnt > MIDIOUTBUF)
-			cnt = MIDIOUTBUF - s->midi.ocnt;
-		if (cnt <= 0) {
-			__set_current_state(TASK_INTERRUPTIBLE);
-			es1371_handle_midi(s);
-		}
-		spin_unlock_irqrestore(&s->lock, flags);
-		if (cnt > count)
-			cnt = count;
-		if (cnt <= 0) {
-			if (file->f_flags & O_NONBLOCK) {
-				if (!ret)
-					ret = -EAGAIN;
-				break;
-			}
-			schedule();
-			if (signal_pending(current)) {
-				if (!ret)
-					ret = -ERESTARTSYS;
-				break;
-			}
-			continue;
-		}
-		if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
-			if (!ret)
-				ret = -EFAULT;
-			break;
-		}
-		ptr = (ptr + cnt) % MIDIOUTBUF;
-		spin_lock_irqsave(&s->lock, flags);
-		s->midi.owr = ptr;
-		s->midi.ocnt += cnt;
-		spin_unlock_irqrestore(&s->lock, flags);
-		count -= cnt;
-		buffer += cnt;
-		ret += cnt;
-		spin_lock_irqsave(&s->lock, flags);
-		es1371_handle_midi(s);
-		spin_unlock_irqrestore(&s->lock, flags);
-	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&s->midi.owait, &wait);
-	return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1371_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	unsigned long flags;
-	unsigned int mask = 0;
-
-	VALIDATE_STATE(s);
-	if (file->f_mode & FMODE_WRITE)
-		poll_wait(file, &s->midi.owait, wait);
-	if (file->f_mode & FMODE_READ)
-		poll_wait(file, &s->midi.iwait, wait);
-	spin_lock_irqsave(&s->lock, flags);
-	if (file->f_mode & FMODE_READ) {
-		if (s->midi.icnt > 0)
-			mask |= POLLIN | POLLRDNORM;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		if (s->midi.ocnt < MIDIOUTBUF)
-			mask |= POLLOUT | POLLWRNORM;
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	return mask;
-}
-
-static int es1371_midi_open(struct inode *inode, struct file *file)
-{
-	int minor = iminor(inode);
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	struct list_head *list;
-	struct es1371_state *s;
-
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct es1371_state, devs);
-		if (s->dev_midi == minor)
-			break;
-	}
-       	VALIDATE_STATE(s);
-	file->private_data = s;
-	/* wait for device to become free */
-	mutex_lock(&s->open_mutex);
-	while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-		if (file->f_flags & O_NONBLOCK) {
-			mutex_unlock(&s->open_mutex);
-			return -EBUSY;
-		}
-		add_wait_queue(&s->open_wait, &wait);
-		__set_current_state(TASK_INTERRUPTIBLE);
-		mutex_unlock(&s->open_mutex);
-		schedule();
-		remove_wait_queue(&s->open_wait, &wait);
-		set_current_state(TASK_RUNNING);
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-		mutex_lock(&s->open_mutex);
-	}
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-		outb(UCTRL_CNTRL_SWR, s->io+ES1371_REG_UART_CONTROL);
-		outb(0, s->io+ES1371_REG_UART_CONTROL);
-		outb(0, s->io+ES1371_REG_UART_TEST);
-	}
-	if (file->f_mode & FMODE_READ) {
-		s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-	}
-	if (file->f_mode & FMODE_WRITE) {
-		s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-	}
-	s->ctrl |= CTRL_UART_EN;
-	outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-	es1371_handle_midi(s);
-	spin_unlock_irqrestore(&s->lock, flags);
-	s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-	mutex_unlock(&s->open_mutex);
-	return nonseekable_open(inode, file);
-}
-
-static int es1371_midi_release(struct inode *inode, struct file *file)
-{
-	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	unsigned count, tmo;
-
-	VALIDATE_STATE(s);
-	lock_kernel();
-	if (file->f_mode & FMODE_WRITE) {
-		add_wait_queue(&s->midi.owait, &wait);
-		for (;;) {
-			__set_current_state(TASK_INTERRUPTIBLE);
-			spin_lock_irqsave(&s->lock, flags);
-			count = s->midi.ocnt;
-			spin_unlock_irqrestore(&s->lock, flags);
-			if (count <= 0)
-				break;
-			if (signal_pending(current))
-				break;
-			if (file->f_flags & O_NONBLOCK)
-				break;
-			tmo = (count * HZ) / 3100;
-			if (!schedule_timeout(tmo ? : 1) && tmo)
-				printk(KERN_DEBUG PFX "midi timed out??\n");
-		}
-		remove_wait_queue(&s->midi.owait, &wait);
-		set_current_state(TASK_RUNNING);
-	}
-	mutex_lock(&s->open_mutex);
-	s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
-	spin_lock_irqsave(&s->lock, flags);
-	if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-		s->ctrl &= ~CTRL_UART_EN;
-		outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-	}
-	spin_unlock_irqrestore(&s->lock, flags);
-	mutex_unlock(&s->open_mutex);
-	wake_up(&s->open_wait);
-	unlock_kernel();
-	return 0;
-}
-
-static /*const*/ struct file_operations es1371_midi_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= es1371_midi_read,
-	.write		= es1371_midi_write,
-	.poll		= es1371_midi_poll,
-	.open		= es1371_midi_open,
-	.release	= es1371_midi_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-/*
- * for debugging purposes, we'll create a proc device that dumps the
- * CODEC chipstate
- */
-
-#ifdef ES1371_DEBUG
-static int proc_es1371_dump (char *buf, char **start, off_t fpos, int length, int *eof, void *data)
-{
-	struct es1371_state *s;
-        int cnt, len = 0;
-
-	if (list_empty(&devs))
-		return 0;
-	s = list_entry(devs.next, struct es1371_state, devs);
-        /* print out header */
-        len += sprintf(buf + len, "\t\tCreative ES137x Debug Dump-o-matic\n");
-
-        /* print out CODEC state */
-        len += sprintf (buf + len, "AC97 CODEC state\n");
-	for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
-                len+= sprintf (buf + len, "reg:0x%02x  val:0x%04x\n", cnt, rdcodec(s->codec, cnt));
-
-        if (fpos >=len){
-                *start = buf;
-                *eof =1;
-                return 0;
-        }
-        *start = buf + fpos;
-        if ((len -= fpos) > length)
-                return length;
-        *eof =1;
-        return len;
-
-}
-#endif /* ES1371_DEBUG */
-
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices; only used for command line params */
-#define NR_DEVICE 5
-
-static int spdif[NR_DEVICE];
-static int nomix[NR_DEVICE];
-static int amplifier[NR_DEVICE];
-
-static unsigned int devindex;
-
-module_param_array(spdif, bool, NULL, 0);
-MODULE_PARM_DESC(spdif, "if 1 the output is in S/PDIF digital mode");
-module_param_array(nomix, bool, NULL, 0);
-MODULE_PARM_DESC(nomix, "if 1 no analog audio is mixed to the digital output");
-module_param_array(amplifier, bool, NULL, 0);
-MODULE_PARM_DESC(amplifier, "Set to 1 if the machine needs the amp control enabling (many laptops)");
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver");
-MODULE_LICENSE("GPL");
-
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-	int mixch;
-	int vol;
-} initvol[] __devinitdata = {
-	{ SOUND_MIXER_WRITE_LINE, 0x4040 },
-	{ SOUND_MIXER_WRITE_CD, 0x4040 },
-	{ MIXER_WRITE(SOUND_MIXER_VIDEO), 0x4040 },
-	{ SOUND_MIXER_WRITE_LINE1, 0x4040 },
-	{ SOUND_MIXER_WRITE_PCM, 0x4040 },
-	{ SOUND_MIXER_WRITE_VOLUME, 0x4040 },
-	{ MIXER_WRITE(SOUND_MIXER_PHONEOUT), 0x4040 },
-	{ SOUND_MIXER_WRITE_OGAIN, 0x4040 },
-	{ MIXER_WRITE(SOUND_MIXER_PHONEIN), 0x4040 },
-	{ SOUND_MIXER_WRITE_SPEAKER, 0x4040 },
-	{ SOUND_MIXER_WRITE_MIC, 0x4040 },
-	{ SOUND_MIXER_WRITE_RECLEV, 0x4040 },
-	{ SOUND_MIXER_WRITE_IGAIN, 0x4040 }
-};
-
-static struct
-{
-	short svid, sdid;
-} amplifier_needed[] = 
-{
-	{ 0x107B, 0x2150 },		/* Gateway Solo 2150 */
-	{ 0x13BD, 0x100C },		/* Mebius PC-MJ100V */
-	{ 0x1102, 0x5938 },		/* Targa Xtender 300 */
-	{ 0x1102, 0x8938 },		/* IPC notebook */
-	{ PCI_ANY_ID, PCI_ANY_ID }
-};
-
-#ifdef SUPPORT_JOYSTICK
-
-static int __devinit es1371_register_gameport(struct es1371_state *s)
-{
-	struct gameport *gp;
-	int gpio;
-
-	for (gpio = 0x218; gpio >= 0x200; gpio -= 0x08)
-		if (request_region(gpio, JOY_EXTENT, "es1371"))
-			break;
-
-	if (gpio < 0x200) {
-		printk(KERN_ERR PFX "no free joystick address found\n");
-		return -EBUSY;
-	}
-
-	s->gameport = gp = gameport_allocate_port();
-	if (!gp) {
-		printk(KERN_ERR PFX "can not allocate memory for gameport\n");
-		release_region(gpio, JOY_EXTENT);
-		return -ENOMEM;
-	}
-
-	gameport_set_name(gp, "ESS1371 Gameport");
-	gameport_set_phys(gp, "isa%04x/gameport0", gpio);
-	gp->dev.parent = &s->dev->dev;
-	gp->io = gpio;
-
-	s->ctrl |= CTRL_JYSTK_EN | (((gpio >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT);
-	outl(s->ctrl, s->io + ES1371_REG_CONTROL);
-
-	gameport_register_port(gp);
-
-	return 0;
-}
-
-static inline void es1371_unregister_gameport(struct es1371_state *s)
-{
-	if (s->gameport) {
-		int gpio = s->gameport->io;
-		gameport_unregister_port(s->gameport);
-		release_region(gpio, JOY_EXTENT);
-
-	}
-}
-
-#else
-static inline int es1371_register_gameport(struct es1371_state *s) { return -ENOSYS; }
-static inline void es1371_unregister_gameport(struct es1371_state *s) { }
-#endif /* SUPPORT_JOYSTICK */
-
-
-static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-	struct es1371_state *s;
-	mm_segment_t fs;
-	int i, val, res = -1;
-	int idx;
-	unsigned long tmo;
-	signed long tmo2;
-	unsigned int cssr;
-
-	if ((res=pci_enable_device(pcidev)))
-		return res;
-
-	if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO))
-		return -ENODEV;
-	if (pcidev->irq == 0) 
-		return -ENODEV;
-	i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
-	if (i) {
-		printk(KERN_WARNING "es1371: architecture does not support 32bit PCI busmaster DMA\n");
-		return i;
-	}
-	if (!(s = kzalloc(sizeof(struct es1371_state), GFP_KERNEL))) {
-		printk(KERN_WARNING PFX "out of memory\n");
-		return -ENOMEM;
-	}
-	
-	s->codec = ac97_alloc_codec();
-	if(s->codec == NULL)
-		goto err_codec;
-		
-	init_waitqueue_head(&s->dma_adc.wait);
-	init_waitqueue_head(&s->dma_dac1.wait);
-	init_waitqueue_head(&s->dma_dac2.wait);
-	init_waitqueue_head(&s->open_wait);
-	init_waitqueue_head(&s->midi.iwait);
-	init_waitqueue_head(&s->midi.owait);
-	mutex_init(&s->open_mutex);
-	spin_lock_init(&s->lock);
-	s->magic = ES1371_MAGIC;
-	s->dev = pcidev;
-	s->io = pci_resource_start(pcidev, 0);
-	s->irq = pcidev->irq;
-	s->vendor = pcidev->vendor;
-	s->device = pcidev->device;
-	s->rev = pcidev->revision;
-	s->codec->private_data = s;
-	s->codec->id = 0;
-	s->codec->codec_read = rdcodec;
-	s->codec->codec_write = wrcodec;
-	printk(KERN_INFO PFX "found chip, vendor id 0x%04x device id 0x%04x revision 0x%02x\n",
-	       s->vendor, s->device, s->rev);
-	if (!request_region(s->io, ES1371_EXTENT, "es1371")) {
-		printk(KERN_ERR PFX "io ports %#lx-%#lx in use\n", s->io, s->io+ES1371_EXTENT-1);
-		res = -EBUSY;
-		goto err_region;
-	}
-	if ((res=request_irq(s->irq, es1371_interrupt, IRQF_SHARED, "es1371",s))) {
-		printk(KERN_ERR PFX "irq %u in use\n", s->irq);
-		goto err_irq;
-	}
-	printk(KERN_INFO PFX "found es1371 rev %d at io %#lx irq %u\n",
-	       s->rev, s->io, s->irq);
-	/* register devices */
-	if ((res=(s->dev_audio = register_sound_dsp(&es1371_audio_fops,-1)))<0)
-		goto err_dev1;
-	if ((res=(s->codec->dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1))) < 0)
-		goto err_dev2;
-	if ((res=(s->dev_dac = register_sound_dsp(&es1371_dac_fops, -1))) < 0)
-		goto err_dev3;
-	if ((res=(s->dev_midi = register_sound_midi(&es1371_midi_fops, -1)))<0 )
-		goto err_dev4;
-#ifdef ES1371_DEBUG
-	/* initialize the debug proc device */
-	s->ps = create_proc_read_entry("es1371",0,NULL,proc_es1371_dump,NULL);
-#endif /* ES1371_DEBUG */
-	
-	/* initialize codec registers */
-	s->ctrl = 0;
-
-	/* Check amplifier requirements */
-	
-	if (amplifier[devindex])
-		s->ctrl |= CTRL_GPIO_OUT0;
-	else for(idx = 0; amplifier_needed[idx].svid != PCI_ANY_ID; idx++)
-	{
-		if(pcidev->subsystem_vendor == amplifier_needed[idx].svid &&
-		   pcidev->subsystem_device == amplifier_needed[idx].sdid)
-		{
-                    	s->ctrl |= CTRL_GPIO_OUT0;   /* turn internal amplifier on */
-                    	printk(KERN_INFO PFX "Enabling internal amplifier.\n");
-		}
-	}
-
-	s->sctrl = 0;
-	cssr = 0;
-	s->spdif_volume = -1;
-	/* check to see if s/pdif mode is being requested */
-	if (spdif[devindex]) {
-		if (s->rev >= 4) {
-			printk(KERN_INFO PFX "enabling S/PDIF output\n");
-			s->spdif_volume = 0;
-			cssr |= STAT_EN_SPDIF;
-			s->ctrl |= CTRL_SPDIFEN_B;
-			if (nomix[devindex]) /* don't mix analog inputs to s/pdif output */
-				s->ctrl |= CTRL_RECEN_B;
-		} else {
-			printk(KERN_ERR PFX "revision %d does not support S/PDIF\n", s->rev);
-		}
-	}
-	/* initialize the chips */
-	outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-	outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
-	outl(LEGACY_JFAST, s->io+ES1371_REG_LEGACY);
-	pci_set_master(pcidev);  /* enable bus mastering */
-	/* if we are a 5880 turn on the AC97 */
-	if (s->vendor == PCI_VENDOR_ID_ENSONIQ &&
-	    ((s->device == PCI_DEVICE_ID_ENSONIQ_CT5880 && s->rev >= CT5880REV_CT5880_C) || 
-	     (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_CT5880_A) || 
-	     (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_ES1373_8))) { 
-		cssr |= CSTAT_5880_AC97_RST;
-		outl(cssr, s->io+ES1371_REG_STATUS);
-		/* need to delay around 20ms(bleech) to give
-		   some CODECs enough time to wakeup */
-		tmo = jiffies + (HZ / 50) + 1;
-		for (;;) {
-			tmo2 = tmo - jiffies;
-			if (tmo2 <= 0)
-				break;
-			schedule_timeout(tmo2);
-		}
-	}
-	/* AC97 warm reset to start the bitclk */
-	outl(s->ctrl | CTRL_SYNCRES, s->io+ES1371_REG_CONTROL);
-	udelay(2);
-	outl(s->ctrl, s->io+ES1371_REG_CONTROL);
-	/* init the sample rate converter */
-	src_init(s);
-	/* codec init */
-	if (!ac97_probe_codec(s->codec)) {
-		res = -ENODEV;
-		goto err_gp;
-	}
-	/* set default values */
-
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	val = SOUND_MASK_LINE;
-	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-	for (i = 0; i < ARRAY_SIZE(initvol); i++) {
-		val = initvol[i].vol;
-		mixdev_ioctl(s->codec, initvol[i].mixch, (unsigned long)&val);
-	}
-	/* mute master and PCM when in S/PDIF mode */
-	if (s->spdif_volume != -1) {
-		val = 0x0000;
-		s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_VOLUME, (unsigned long)&val);
-		s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_PCM, (unsigned long)&val);
-	}
-	set_fs(fs);
-	/* turn on S/PDIF output driver if requested */
-	outl(cssr, s->io+ES1371_REG_STATUS);
-
-	es1371_register_gameport(s);
-
-	/* store it in the driver field */
-	pci_set_drvdata(pcidev, s);
-	/* put it into driver list */
-	list_add_tail(&s->devs, &devs);
-	/* increment devindex */
-	if (devindex < NR_DEVICE-1)
-		devindex++;
-	return 0;
-
- err_gp:
-#ifdef ES1371_DEBUG
-	if (s->ps)
-		remove_proc_entry("es1371", NULL);
-#endif
-	unregister_sound_midi(s->dev_midi);
- err_dev4:
-	unregister_sound_dsp(s->dev_dac);
- err_dev3:
-	unregister_sound_mixer(s->codec->dev_mixer);
- err_dev2:
-	unregister_sound_dsp(s->dev_audio);
- err_dev1:
-	printk(KERN_ERR PFX "cannot register misc device\n");
-	free_irq(s->irq, s);
- err_irq:
-	release_region(s->io, ES1371_EXTENT);
- err_region:
- err_codec:
-	ac97_release_codec(s->codec);
-	kfree(s);
-	return res;
-}
-
-static void __devexit es1371_remove(struct pci_dev *dev)
-{
-	struct es1371_state *s = pci_get_drvdata(dev);
-
-	if (!s)
-		return;
-	list_del(&s->devs);
-#ifdef ES1371_DEBUG
-	if (s->ps)
-		remove_proc_entry("es1371", NULL);
-#endif /* ES1371_DEBUG */
-	outl(0, s->io+ES1371_REG_CONTROL); /* switch everything off */
-	outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */
-	synchronize_irq(s->irq);
-	free_irq(s->irq, s);
-	es1371_unregister_gameport(s);
-	release_region(s->io, ES1371_EXTENT);
-	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->codec->dev_mixer);
-	unregister_sound_dsp(s->dev_dac);
-	unregister_sound_midi(s->dev_midi);
-	ac97_release_codec(s->codec);
-	kfree(s);
-	pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] = {
-	{ PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-	{ PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_CT5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-	{ PCI_VENDOR_ID_ECTIVA, PCI_DEVICE_ID_ECTIVA_EV1938, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver es1371_driver = {
-	.name		= "es1371",
-	.id_table	= id_table,
-	.probe		= es1371_probe,
-	.remove		= __devexit_p(es1371_remove),
-};
-
-static int __init init_es1371(void)
-{
-	printk(KERN_INFO PFX "version v0.32 time " __TIME__ " " __DATE__ "\n");
-	return pci_register_driver(&es1371_driver);
-}
-
-static void __exit cleanup_es1371(void)
-{
-	printk(KERN_INFO PFX "unloading\n");
-	pci_unregister_driver(&es1371_driver);
-}
-
-module_init(init_es1371);
-module_exit(cleanup_es1371);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/* format is: es1371=[spdif,[nomix,[amplifier]]] */
-
-static int __init es1371_setup(char *str)
-{
-	static unsigned __initdata nr_dev = 0;
-
-	if (nr_dev >= NR_DEVICE)
-		return 0;
-
-	(void)
-        ((get_option(&str, &spdif[nr_dev]) == 2)
-         && (get_option(&str, &nomix[nr_dev]) == 2)
-         && (get_option(&str, &amplifier[nr_dev])));
-
-	nr_dev++;
-	return 1;
-}
-
-__setup("es1371=", es1371_setup);
-
-#endif /* MODULE */
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index f70286a..26819e2 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -191,7 +191,7 @@
 
 	/* Init audio core.
 	 * This must be done before we do request_irq otherwise we can get spurious
-	 * interupts that we do not handle properly and make a mess of things */
+	 * interrupts that we do not handle properly and make a mess of things */
 	if ((err = vortex_core_init(chip)) != 0) {
 		printk(KERN_ERR "hw core init failed\n");
 		goto core_out;
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 91f9e6a..2dba752 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -165,7 +165,7 @@
 	unsigned no_digital:1;	/* No digital input */
 };
 
-static const __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = {
+static __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = {
 	[SND_BT87X_BOARD_UNKNOWN] = {
 		.dig_rate = 32000, /* just a guess */
 	},
@@ -848,7 +848,7 @@
 	int i;
 	const struct pci_device_id *supported;
 
-	supported = pci_match_device(&driver, pci);
+	supported = pci_match_id(snd_bt87x_ids, pci);
 	if (supported && supported->driver_data > 0)
 		return supported->driver_data;
 
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 187533e..ad4cb38 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -626,24 +626,19 @@
 		snd_hda_get_codec_name(codec, bus->card->mixername,
 				       sizeof(bus->card->mixername));
 
-#ifdef CONFIG_SND_HDA_GENERIC
 	if (is_generic_config(codec)) {
 		err = snd_hda_parse_generic_codec(codec);
 		goto patched;
 	}
-#endif
 	if (codec->preset && codec->preset->patch) {
 		err = codec->preset->patch(codec);
 		goto patched;
 	}
 
 	/* call the default parser */
-#ifdef CONFIG_SND_HDA_GENERIC
 	err = snd_hda_parse_generic_codec(codec);
-#else
-	printk(KERN_ERR "hda-codec: No codec parser is available\n");
-	err = -ENODEV;
-#endif
+	if (err < 0)
+		printk(KERN_ERR "hda-codec: No codec parser is available\n");
 
  patched:
 	if (err < 0) {
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index a79d0ed..20c5e62 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -245,7 +245,14 @@
 /*
  * generic codec parser
  */
+#ifdef CONFIG_SND_HDA_GENERIC
 int snd_hda_parse_generic_codec(struct hda_codec *codec);
+#else
+static inline int snd_hda_parse_generic_codec(struct hda_codec *codec)
+{
+	return -ENODEV;
+}
+#endif
 
 /*
  * generic proc interface
@@ -303,16 +310,17 @@
 
 extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST];
 
+#define AUTO_CFG_MAX_OUTS	5
+
 struct auto_pin_cfg {
 	int line_outs;
-	hda_nid_t line_out_pins[5]; /* sorted in the order of
-				     * Front/Surr/CLFE/Side
-				     */
+	/* sorted in the order of Front/Surr/CLFE/Side */
+	hda_nid_t line_out_pins[AUTO_CFG_MAX_OUTS];
 	int speaker_outs;
-	hda_nid_t speaker_pins[5];
+	hda_nid_t speaker_pins[AUTO_CFG_MAX_OUTS];
 	int hp_outs;
 	int line_out_type;	/* AUTO_PIN_XXX_OUT */
-	hda_nid_t hp_pins[5];
+	hda_nid_t hp_pins[AUTO_CFG_MAX_OUTS];
 	hda_nid_t input_pins[AUTO_PIN_LAST];
 	hda_nid_t dig_out_pin;
 	hda_nid_t dig_in_pin;
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 54cfd45..0ee8ae4 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -72,7 +72,7 @@
 	unsigned int num_kctl_alloc, num_kctl_used;
 	struct snd_kcontrol_new *kctl_alloc;
 	struct hda_input_mux private_imux;
-	hda_nid_t private_dac_nids[4];
+	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 
 	unsigned int jack_present :1;
 
@@ -612,7 +612,8 @@
 	unsigned int present;
 
 	present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0);
-	spec->jack_present = (present & 0x80000000) != 0;
+	/* Lenovo N100 seems to report the reversed bit for HP jack-sensing */
+	spec->jack_present = !(present & 0x80000000);
 	ad1986a_update_hp(codec);
 }
 
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 2468f31..6c54793 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -50,7 +50,7 @@
 
 	/* playback */
 	struct hda_multi_out multiout;
-	hda_nid_t dac_nids[4];		/* NID for each DAC */
+	hda_nid_t dac_nids[AUTO_CFG_MAX_OUTS];	/* NID for each DAC */
 	int num_dacs;
 
 	/* capture */
@@ -73,7 +73,6 @@
 	unsigned int pin_def_confs;
 
 	/* multichannel pins */
-	hda_nid_t multich_pin[4];	/* max 8-channel */
 	struct hda_verb multi_init[9];	/* 2 verbs for each pin + terminator */
 };
 
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 080e300..6aa0739 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -85,7 +85,7 @@
 	unsigned int num_kctl_alloc, num_kctl_used;
 	struct snd_kcontrol_new *kctl_alloc;
 	struct hda_input_mux private_imux;
-	hda_nid_t private_dac_nids[4];
+	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 
 };
 
@@ -554,10 +554,16 @@
 		.get = conexant_mux_enum_get,
 		.put = conexant_mux_enum_put
 	},
-	HDA_CODEC_VOLUME("Int Mic Volume", 0x1a, 0x01, HDA_INPUT),
-	HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT),
-	HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
+	HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
+	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
 	HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -576,16 +582,15 @@
 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
 	/* HP, Amp  */
-	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
-	{0x17, AC_VERB_SET_CONNECT_SEL,0x01},
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE,
-	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x01},
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE,
-	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x02},
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE,
-	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE,
-	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04},
+	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
+	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 	/* Record selector: Int mic */
 	{0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 53b0428..d9f78c8 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -238,7 +238,7 @@
 	unsigned int num_kctl_alloc, num_kctl_used;
 	struct snd_kcontrol_new *kctl_alloc;
 	struct hda_input_mux private_imux;
-	hda_nid_t private_dac_nids[5];
+	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 
 	/* hooks */
 	void (*init_hook)(struct hda_codec *codec);
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index bf95019..f9b2c43 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -111,6 +111,7 @@
 	unsigned int alt_switch: 1;
 	unsigned int hp_detect: 1;
 	unsigned int gpio_mute: 1;
+	unsigned int no_vol_knob :1;
 
 	unsigned int gpio_mask, gpio_data;
 
@@ -1930,7 +1931,8 @@
 	}
 	if (spec->multiout.hp_nid) {
 		const char *pfx;
-		if (old_num_dacs == spec->multiout.num_dacs)
+		if (old_num_dacs == spec->multiout.num_dacs &&
+		    spec->no_vol_knob)
 			pfx = "Master";
 		else
 			pfx = "Headphone";
@@ -2487,6 +2489,7 @@
 	codec->spec = spec;
 	spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
 	spec->pin_nids = stac9200_pin_nids;
+	spec->no_vol_knob = 1;
 	spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
 							stac9200_models,
 							stac9200_cfg_tbl);
@@ -2541,6 +2544,7 @@
 	codec->spec = spec;
 	spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
 	spec->pin_nids = stac925x_pin_nids;
+	spec->no_vol_knob = 1;
 	spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
 							stac925x_models,
 							stac925x_cfg_tbl);
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 33b5e1f..4cdf3e6 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -114,7 +114,7 @@
 	unsigned int num_kctl_alloc, num_kctl_used;
 	struct snd_kcontrol_new *kctl_alloc;
 	struct hda_input_mux private_imux;
-	hda_nid_t private_dac_nids[4];	
+	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 	struct hda_loopback_check loopback;
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
index a1aa89f..566b5ab 100644
--- a/sound/ppc/beep.c
+++ b/sound/ppc/beep.c
@@ -236,8 +236,8 @@
 	input_dev->id.product = 0x0001;
 	input_dev->id.version = 0x0100;
 
-	input_dev->evbit[0] = BIT(EV_SND);
-	input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+	input_dev->evbit[0] = BIT_MASK(EV_SND);
+	input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
 	input_dev->event = snd_pmac_beep_event;
 	input_dev->dev.parent = &chip->pdev->dev;
 	input_set_drvdata(input_dev, chip);
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 131ec48..88dc840 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -106,11 +106,14 @@
 static void spu_memset(u32 toi, u32 what, int length)
 {
 	int i;
+	unsigned long flags;
 	snd_assert(length % 4 == 0, return);
 	for (i = 0; i < length; i++) {
 		if (!(i % 8))
 			spu_write_wait();
+		local_irq_save(flags);
 		writel(what, toi + SPU_MEMORY_BASE);
+		local_irq_restore(flags);
 		toi++;
 	}
 }
@@ -118,6 +121,7 @@
 /* spu_memload - write to SPU address space */
 static void spu_memload(u32 toi, void *from, int length)
 {
+	unsigned long flags;
 	u32 *froml = from;
 	u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi);
 	int i;
@@ -128,7 +132,9 @@
 		if (!(i % 8))
 			spu_write_wait();
 		val = *froml;
+		local_irq_save(flags);
 		writel(val, to);
+		local_irq_restore(flags);
 		froml++;
 		to++;
 	}
@@ -138,28 +144,36 @@
 static void spu_disable(void)
 {
 	int i;
+	unsigned long flags;
 	u32 regval;
 	spu_write_wait();
 	regval = readl(ARM_RESET_REGISTER);
 	regval |= 1;
 	spu_write_wait();
+	local_irq_save(flags);
 	writel(regval, ARM_RESET_REGISTER);
+	local_irq_restore(flags);
 	for (i = 0; i < 64; i++) {
 		spu_write_wait();
 		regval = readl(SPU_REGISTER_BASE + (i * 0x80));
 		regval = (regval & ~0x4000) | 0x8000;
 		spu_write_wait();
+		local_irq_save(flags);
 		writel(regval, SPU_REGISTER_BASE + (i * 0x80));
+		local_irq_restore(flags);
 	}
 }
 
 /* spu_enable - set spu registers to enable sound output */
 static void spu_enable(void)
 {
+	unsigned long flags;
 	u32 regval = readl(ARM_RESET_REGISTER);
 	regval &= ~1;
 	spu_write_wait();
+	local_irq_save(flags);
 	writel(regval, ARM_RESET_REGISTER);
+	local_irq_restore(flags);
 }
 
 /* 
@@ -168,25 +182,34 @@
 */
 static void spu_reset(void)
 {
+	unsigned long flags;
 	spu_disable();
 	spu_memset(0, 0, 0x200000 / 4);
 	/* Put ARM7 in endless loop */
+	local_irq_save(flags);
 	ctrl_outl(0xea000002, SPU_MEMORY_BASE);
+	local_irq_restore(flags);
 	spu_enable();
 }
 
 /* aica_chn_start - write to spu to start playback */
 static void aica_chn_start(void)
 {
+	unsigned long flags;
 	spu_write_wait();
+	local_irq_save(flags);
 	writel(AICA_CMD_KICK | AICA_CMD_START, (u32 *) AICA_CONTROL_POINT);
+	local_irq_restore(flags);
 }
 
 /* aica_chn_halt - write to spu to halt playback */
 static void aica_chn_halt(void)
 {
+	unsigned long flags;
 	spu_write_wait();
+	local_irq_save(flags);
 	writel(AICA_CMD_KICK | AICA_CMD_STOP, (u32 *) AICA_CONTROL_POINT);
+	local_irq_restore(flags);
 }
 
 /* ALSA code below */
@@ -213,12 +236,13 @@
 	int q, err, period_offset;
 	struct snd_card_aica *dreamcastcard;
 	struct snd_pcm_runtime *runtime;
-	err = 0;
+	unsigned long flags;
 	dreamcastcard = substream->pcm->private_data;
 	period_offset = dreamcastcard->clicks;
 	period_offset %= (AICA_PERIOD_NUMBER / channels);
 	runtime = substream->runtime;
 	for (q = 0; q < channels; q++) {
+		local_irq_save(flags);
 		err = dma_xfer(AICA_DMA_CHANNEL,
 			       (unsigned long) (runtime->dma_area +
 						(AICA_BUFFER_SIZE * q) /
@@ -228,9 +252,12 @@
 			       AICA_CHANNEL0_OFFSET + q * CHANNEL_OFFSET +
 			       AICA_PERIOD_SIZE * period_offset,
 			       buffer_size / channels, AICA_DMA_MODE);
-		if (unlikely(err < 0))
+		if (unlikely(err < 0)) {
+			local_irq_restore(flags);
 			break;
+		}
 		dma_wait_for_completion(AICA_DMA_CHANNEL);
+		local_irq_restore(flags);
 	}
 	return err;
 }
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 91651bd..e6a67b5 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -264,7 +264,7 @@
 }
 
 /*
- * Power down the audio subsytem pmdown_time msecs after close is called.
+ * Power down the audio subsystem pmdown_time msecs after close is called.
  * This is to ensure there are no pops or clicks in between any music tracks
  * due to DAPM power cycling.
  */
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b3193e6..29a546f 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -24,7 +24,7 @@
  *    o Automatic Mic Bias support
  *    o Jack insertion power event initiation - e.g. hp insertion will enable
  *      sinks, dacs, etc
- *    o Delayed powerdown of audio susbsytem to reduce pops between a quick
+ *    o Delayed powerdown of audio susbsystem to reduce pops between a quick
  *      device reopen.
  *
  *  Todo:
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 9785382..f8c7a12 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -400,65 +400,44 @@
 
 static void snd_cs4231_mce_down(struct snd_cs4231 *chip)
 {
-	unsigned long flags;
-	unsigned long end_time;
-	int timeout;
+	unsigned long flags, timeout;
+	int reg;
 
-	spin_lock_irqsave(&chip->lock, flags);
 	snd_cs4231_busy_wait(chip);
+	spin_lock_irqsave(&chip->lock, flags);
 #ifdef CONFIG_SND_DEBUG
 	if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
 		snd_printdd("mce_down [%p] - auto calibration time out (0)\n",
 			    CS4231U(chip, REGSEL));
 #endif
 	chip->mce_bit &= ~CS4231_MCE;
-	timeout = __cs4231_readb(chip, CS4231U(chip, REGSEL));
-	__cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f),
+	reg = __cs4231_readb(chip, CS4231U(chip, REGSEL));
+	__cs4231_writeb(chip, chip->mce_bit | (reg & 0x1f),
 			CS4231U(chip, REGSEL));
-	if (timeout == 0x80)
-		snd_printdd("mce_down [%p]: serious init problem - "
-			    "codec still busy\n",
-			    chip->port);
-	if ((timeout & CS4231_MCE) == 0) {
+	if (reg == 0x80)
+		snd_printdd("mce_down [%p]: serious init problem "
+			    "- codec still busy\n", chip->port);
+	if ((reg & CS4231_MCE) == 0) {
 		spin_unlock_irqrestore(&chip->lock, flags);
 		return;
 	}
 
 	/*
-	 * Wait for (possible -- during init auto-calibration may not be set)
-	 * calibration process to start. Needs upto 5 sample periods on AD1848
-	 * which at the slowest possible rate of 5.5125 kHz means 907 us.
+	 * Wait for auto-calibration (AC) process to finish, i.e. ACI to go low.
 	 */
-	msleep(1);
-
-	/* check condition up to 250ms */
-	end_time = jiffies + msecs_to_jiffies(250);
-	while (snd_cs4231_in(chip, CS4231_TEST_INIT) &
-		CS4231_CALIB_IN_PROGRESS) {
-
+	timeout = jiffies + msecs_to_jiffies(250);
+	do {
 		spin_unlock_irqrestore(&chip->lock, flags);
-		if (time_after(jiffies, end_time)) {
-			snd_printk("mce_down - "
-				   "auto calibration time out (2)\n");
-			return;
-		}
 		msleep(1);
 		spin_lock_irqsave(&chip->lock, flags);
-	}
-
-	/* check condition up to 100ms */
-	end_time = jiffies + msecs_to_jiffies(100);
-	while (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) {
-		spin_unlock_irqrestore(&chip->lock, flags);
-		if (time_after(jiffies, end_time)) {
-			snd_printk("mce_down - "
-				   "auto calibration time out (3)\n");
-			return;
-		}
-		msleep(1);
-		spin_lock_irqsave(&chip->lock, flags);
-	}
+		reg = snd_cs4231_in(chip, CS4231_TEST_INIT);
+		reg &= CS4231_CALIB_IN_PROGRESS;
+	} while (reg && time_before(jiffies, timeout));
 	spin_unlock_irqrestore(&chip->lock, flags);
+
+	if (reg)
+		snd_printk(KERN_ERR
+			   "mce_down - auto calibration time out (2)\n");
 }
 
 static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont,
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
index 3733118..478369b 100644
--- a/sound/synth/emux/emux_synth.c
+++ b/sound/synth/emux/emux_synth.c
@@ -317,7 +317,7 @@
 
 
 /*
- * Deal with a controler type event.  This includes all types of
+ * Deal with a controller type event.  This includes all types of
  * control events, not just the midi controllers
  */
 void
diff --git a/sound/usb/caiaq/caiaq-input.c b/sound/usb/caiaq/caiaq-input.c
index a1de0c6..cd536ca 100644
--- a/sound/usb/caiaq/caiaq-input.c
+++ b/sound/usb/caiaq/caiaq-input.c
@@ -200,8 +200,9 @@
 
         switch (dev->chip.usb_id) {
 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
-		input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-		input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z);
+		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+		input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+			BIT_MASK(ABS_Z);
 		input->keycode = keycode_rk2;
 		input->keycodesize = sizeof(char);
 		input->keycodemax = ARRAY_SIZE(keycode_rk2);
@@ -228,8 +229,8 @@
 		snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
 		break;
 	case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
-		input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-		input->absbit[0] = BIT(ABS_X);
+		input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+		input->absbit[0] = BIT_MASK(ABS_X);
 		input->keycode = keycode_ak1;
 		input->keycodesize = sizeof(char);
 		input->keycodemax = ARRAY_SIZE(keycode_ak1);
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 743568f..59410f4 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -84,6 +84,15 @@
 		       USB_DEVICE_ID_MATCH_INT_CLASS |
 		       USB_DEVICE_ID_MATCH_INT_SUBCLASS,
 	.idVendor = 0x046d,
+	.idProduct = 0x08f5,
+	.bInterfaceClass = USB_CLASS_AUDIO,
+	.bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
+},
+{
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+		       USB_DEVICE_ID_MATCH_INT_CLASS |
+		       USB_DEVICE_ID_MATCH_INT_SUBCLASS,
+	.idVendor = 0x046d,
 	.idProduct = 0x08f6,
 	.bInterfaceClass = USB_CLASS_AUDIO,
 	.bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL