linux-cvs-patches
[Top] [All Lists]

CVS Update@linux-mips.org: linux

To: linux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: linux
From: ralf@linux-mips.org
Date: Mon, 08 Aug 2005 13:30:49 +0100
Reply-to: linux-mips@linux-mips.org
Sender: linux-cvs-patches-bounce@linux-mips.org
CVSROOT:        /home/cvs
Module name:    linux
Changes by:     ralf@ftp.linux-mips.org 05/08/08 13:30:41

Modified files:
        .              : Makefile REPORTING-BUGS 
        Documentation  : dontdiff 
        Documentation/usb: usbmon.txt 
        Documentation/video4linux/bttv: Insmod-options 
        Documentation/x86_64: boot-options.txt 
        arch/alpha/kernel: pci.c 
        arch/arm/kernel: bios32.c 
        arch/arm/mach-ixp4xx: coyote-setup.c gtwx5715-setup.c 
                              ixdp425-setup.c 
        arch/arm/mach-s3c2410: mach-bast.c 
        arch/arm/mach-sa1100: jornada720.c 
        arch/arm/mm    : fault.c proc-xscale.S 
        arch/arm/nwfpe : double_cpdo.c extended_cpdo.c fpa11.c fpa11.h 
                         fpa11_cpdo.c fpa11_cpdt.c fpa11_cprt.c 
                         fpmodule.c single_cpdo.c softfloat.c 
                         softfloat.h 
        arch/arm/oprofile: backtrace.c 
        arch/arm/vfp   : vfpdouble.c 
        arch/arm26/mm  : fault.c 
        arch/cris/mm   : fault.c 
        arch/frv/mm    : fault.c 
        arch/i386      : Kconfig 
        arch/i386/mach-visws: reboot.c setup.c 
        arch/i386/mach-voyager: voyager_basic.c 
        arch/i386/mm   : discontig.c 
        arch/i386/pci  : visws.c 
        arch/m68k/mm   : fault.c 
        arch/mips      : defconfig 
        arch/mips/configs: atlas_defconfig capcella_defconfig 
                           cobalt_defconfig db1000_defconfig 
                           db1100_defconfig db1500_defconfig 
                           db1550_defconfig ddb5476_defconfig 
                           ddb5477_defconfig decstation_defconfig 
                           e55_defconfig ev64120_defconfig 
                           ev96100_defconfig ip22_defconfig 
                           ip27_defconfig ip32_defconfig 
                           it8172_defconfig ivr_defconfig 
                           jaguar-atx_defconfig jmr3927_defconfig 
                           lasat200_defconfig malta_defconfig 
                           mpc30x_defconfig ocelot_3_defconfig 
                           ocelot_c_defconfig ocelot_defconfig 
                           ocelot_g_defconfig pb1100_defconfig 
                           pb1500_defconfig pb1550_defconfig 
                           pnx8550-jbs_defconfig pnx8550-v2pci_defconfig 
                           qemu_defconfig rbhma4500_defconfig 
                           rm200_defconfig sb1250-swarm_defconfig 
                           sead_defconfig tb0226_defconfig 
                           tb0229_defconfig workpad_defconfig 
                           yosemite_defconfig 
        arch/parisc/mm : fault.c 
        arch/ppc/8xx_io: Kconfig commproc.c fec.c 
        arch/ppc/kernel: pci.c ppc_ksyms.c 
        arch/ppc/syslib: m8xx_setup.c 
        arch/ppc64/boot: zlib.c 
        arch/ppc64/kernel: head.S machine_kexec.c mpic.c mpic.h pci.c 
                           xics.c 
        arch/ppc64/xmon: xmon.c 
        arch/sh64/mm   : fault.c 
        arch/sparc64/kernel: pci.c 
        arch/x86_64/ia32: ptrace32.c 
        arch/x86_64/kernel: mce.c setup.c 
        arch/x86_64/mm : fault.c 
        drivers/acpi   : Kconfig button.c ec.c hotkey.c motherboard.c 
                         osl.c pci_link.c processor_idle.c 
        drivers/acpi/dispatcher: dswload.c 
        drivers/block  : cfq-iosched.c ll_rw_blk.c 
        drivers/bluetooth: bpa10x.c hci_bcsp.c hci_h4.c hci_ldisc.c 
                           hci_usb.c 
        drivers/char   : rtc.c 
        drivers/char/tpm: Kconfig tpm_infineon.c 
        drivers/char/watchdog: sa1100_wdt.c 
        drivers/fc4    : fc.c 
        drivers/ide    : ide-probe.c 
        drivers/infiniband/include: ib_cm.h 
        drivers/infiniband/ulp/ipoib: ipoib_main.c 
        drivers/md     : bitmap.c dm-raid1.c md.c raid1.c 
        drivers/media/video: bttv-cards.c bttv-driver.c 
        drivers/pci    : bus.c pci.c setup-res.c 
        drivers/pcmcia : yenta_socket.c 
        drivers/sbus/char: vfc.h vfc_dev.c vfc_i2c.c 
        drivers/scsi   : ips.c ips.h st.c 
        drivers/scsi/aic7xxx: aic7xxx_osm.c 
        drivers/scsi/aic7xxx/aicasm: aicasm.c aicasm_insformat.h 
        drivers/scsi/ibmvscsi: srp.h 
        drivers/usb/host: ehci-dbg.c ehci-q.c ehci-sched.c ehci.h 
                          isp116x-hcd.c 
        drivers/usb/mon: Kconfig Makefile 
        fs             : Kconfig bio.c namei.c namespace.c 
        fs/isofs       : compress.c 
        include/asm-alpha: pci.h 
        include/asm-arm: pci.h 
        include/asm-generic: pci.h 
        include/asm-i386: pci.h 
        include/asm-i386/mach-visws: do_timer.h 
        include/asm-parisc: pci.h 
        include/asm-ppc: pci.h pgtable.h 
        include/asm-ppc64: machdep.h pci.h xics.h 
        include/asm-x86_64: pci.h 
        include/linux  : blkdev.h fsnotify.h mm.h pci.h swap.h zlib.h 
        include/linux/raid: bitmap.h 
        include/net/bluetooth: bluetooth.h 
        ipc            : sem.c 
        kernel         : exit.c posix-timers.c sys.c 
        lib            : crc32.c inflate.c 
        lib/zlib_inflate: inftrees.c 
        mm             : hugetlb.c memory.c mmap.c mremap.c nommu.c 
        net/bluetooth  : hci_core.c hci_event.c lib.c 
        net/bluetooth/rfcomm: core.c 
        net/ipv4       : fib_semantics.c tcp_output.c 
        security/keys  : keyctl.c keyring.c process_keys.c request_key.c 
Added files:
        Documentation  : kprobes.txt 

Log message:
        Merge with Linux 2.6.13-rc6.

diff -urN linux/Makefile linux/Makefile
--- linux/Makefile      2005/08/03 15:50:22     1.259
+++ linux/Makefile      2005/08/08 12:30:24     1.260
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 13
-EXTRAVERSION =-rc5
+EXTRAVERSION =-rc6
 NAME=Woozy Numbat
 
 # *DOCUMENTATION*
diff -urN linux/REPORTING-BUGS linux/REPORTING-BUGS
--- linux/REPORTING-BUGS        2005/03/18 17:36:42     1.6
+++ linux/REPORTING-BUGS        2005/08/08 12:30:24     1.7
@@ -41,18 +41,19 @@
 [2.] Full description of the problem/report:
 [3.] Keywords (i.e., modules, networking, kernel):
 [4.] Kernel version (from /proc/version):
-[5.] Output of Oops.. message (if applicable) with symbolic information 
+[5.] Most recent kernel version which did not have the bug:
+[6.] Output of Oops.. message (if applicable) with symbolic information
      resolved (see Documentation/oops-tracing.txt)
-[6.] A small shell script or example program which triggers the
+[7.] A small shell script or example program which triggers the
      problem (if possible)
-[7.] Environment
-[7.1.] Software (add the output of the ver_linux script here)
-[7.2.] Processor information (from /proc/cpuinfo):
-[7.3.] Module information (from /proc/modules):
-[7.4.] Loaded driver and hardware information (/proc/ioports, /proc/iomem)
-[7.5.] PCI information ('lspci -vvv' as root)
-[7.6.] SCSI information (from /proc/scsi/scsi)
-[7.7.] Other information that might be relevant to the problem
+[8.] Environment
+[8.1.] Software (add the output of the ver_linux script here)
+[8.2.] Processor information (from /proc/cpuinfo):
+[8.3.] Module information (from /proc/modules):
+[8.4.] Loaded driver and hardware information (/proc/ioports, /proc/iomem)
+[8.5.] PCI information ('lspci -vvv' as root)
+[8.6.] SCSI information (from /proc/scsi/scsi)
+[8.7.] Other information that might be relevant to the problem
        (please look in /proc and include all information that you
        think to be relevant):
 [X.] Other notes, patches, fixes, workarounds:
diff -urN linux/Documentation/kprobes.txt linux/Documentation/kprobes.txt
--- linux/Documentation/kprobes.txt     1970/01/01 00:00:00
+++ linux/Documentation/kprobes.txt     2005-08-08 13:30:24.329538000 +0100     
1.1
@@ -0,0 +1,588 @@
+Title  : Kernel Probes (Kprobes)
+Authors        : Jim Keniston <jkenisto@us.ibm.com>
+       : Prasanna S Panchamukhi <prasanna@in.ibm.com>
+
+CONTENTS
+
+1. Concepts: Kprobes, Jprobes, Return Probes
+2. Architectures Supported
+3. Configuring Kprobes
+4. API Reference
+5. Kprobes Features and Limitations
+6. Probe Overhead
+7. TODO
+8. Kprobes Example
+9. Jprobes Example
+10. Kretprobes Example
+
+1. Concepts: Kprobes, Jprobes, Return Probes
+
+Kprobes enables you to dynamically break into any kernel routine and
+collect debugging and performance information non-disruptively. You
+can trap at almost any kernel code address, specifying a handler
+routine to be invoked when the breakpoint is hit.
+
+There are currently three types of probes: kprobes, jprobes, and
+kretprobes (also called return probes).  A kprobe can be inserted
+on virtually any instruction in the kernel.  A jprobe is inserted at
+the entry to a kernel function, and provides convenient access to the
+function's arguments.  A return probe fires when a specified function
+returns.
+
+In the typical case, Kprobes-based instrumentation is packaged as
+a kernel module.  The module's init function installs ("registers")
+one or more probes, and the exit function unregisters them.  A
+registration function such as register_kprobe() specifies where
+the probe is to be inserted and what handler is to be called when
+the probe is hit.
+
+The next three subsections explain how the different types of
+probes work.  They explain certain things that you'll need to
+know in order to make the best use of Kprobes -- e.g., the
+difference between a pre_handler and a post_handler, and how
+to use the maxactive and nmissed fields of a kretprobe.  But
+if you're in a hurry to start using Kprobes, you can skip ahead
+to section 2.
+
+1.1 How Does a Kprobe Work?
+
+When a kprobe is registered, Kprobes makes a copy of the probed
+instruction and replaces the first byte(s) of the probed instruction
+with a breakpoint instruction (e.g., int3 on i386 and x86_64).
+
+When a CPU hits the breakpoint instruction, a trap occurs, the CPU's
+registers are saved, and control passes to Kprobes via the
+notifier_call_chain mechanism.  Kprobes executes the "pre_handler"
+associated with the kprobe, passing the handler the addresses of the
+kprobe struct and the saved registers.
+
+Next, Kprobes single-steps its copy of the probed instruction.
+(It would be simpler to single-step the actual instruction in place,
+but then Kprobes would have to temporarily remove the breakpoint
+instruction.  This would open a small time window when another CPU
+could sail right past the probepoint.)
+
+After the instruction is single-stepped, Kprobes executes the
+"post_handler," if any, that is associated with the kprobe.
+Execution then continues with the instruction following the probepoint.
+
+1.2 How Does a Jprobe Work?
+
+A jprobe is implemented using a kprobe that is placed on a function's
+entry point.  It employs a simple mirroring principle to allow
+seamless access to the probed function's arguments.  The jprobe
+handler routine should have the same signature (arg list and return
+type) as the function being probed, and must always end by calling
+the Kprobes function jprobe_return().
+
+Here's how it works.  When the probe is hit, Kprobes makes a copy of
+the saved registers and a generous portion of the stack (see below).
+Kprobes then points the saved instruction pointer at the jprobe's
+handler routine, and returns from the trap.  As a result, control
+passes to the handler, which is presented with the same register and
+stack contents as the probed function.  When it is done, the handler
+calls jprobe_return(), which traps again to restore the original stack
+contents and processor state and switch to the probed function.
+
+By convention, the callee owns its arguments, so gcc may produce code
+that unexpectedly modifies that portion of the stack.  This is why
+Kprobes saves a copy of the stack and restores it after the jprobe
+handler has run.  Up to MAX_STACK_SIZE bytes are copied -- e.g.,
+64 bytes on i386.
+
+Note that the probed function's args may be passed on the stack
+or in registers (e.g., for x86_64 or for an i386 fastcall function).
+The jprobe will work in either case, so long as the handler's
+prototype matches that of the probed function.
+
+1.3 How Does a Return Probe Work?
+
+When you call register_kretprobe(), Kprobes establishes a kprobe at
+the entry to the function.  When the probed function is called and this
+probe is hit, Kprobes saves a copy of the return address, and replaces
+the return address with the address of a "trampoline."  The trampoline
+is an arbitrary piece of code -- typically just a nop instruction.
+At boot time, Kprobes registers a kprobe at the trampoline.
+
+When the probed function executes its return instruction, control
+passes to the trampoline and that probe is hit.  Kprobes' trampoline
+handler calls the user-specified handler associated with the kretprobe,
+then sets the saved instruction pointer to the saved return address,
+and that's where execution resumes upon return from the trap.
+
+While the probed function is executing, its return address is
+stored in an object of type kretprobe_instance.  Before calling
+register_kretprobe(), the user sets the maxactive field of the
+kretprobe struct to specify how many instances of the specified
+function can be probed simultaneously.  register_kretprobe()
+pre-allocates the indicated number of kretprobe_instance objects.
+
+For example, if the function is non-recursive and is called with a
+spinlock held, maxactive = 1 should be enough.  If the function is
+non-recursive and can never relinquish the CPU (e.g., via a semaphore
+or preemption), NR_CPUS should be enough.  If maxactive <= 0, it is
+set to a default value.  If CONFIG_PREEMPT is enabled, the default
+is max(10, 2*NR_CPUS).  Otherwise, the default is NR_CPUS.
+
+It's not a disaster if you set maxactive too low; you'll just miss
+some probes.  In the kretprobe struct, the nmissed field is set to
+zero when the return probe is registered, and is incremented every
+time the probed function is entered but there is no kretprobe_instance
+object available for establishing the return probe.
+
+2. Architectures Supported
+
+Kprobes, jprobes, and return probes are implemented on the following
+architectures:
+
+- i386
+- x86_64 (AMD-64, E64MT)
+- ppc64
+- ia64 (Support for probes on certain instruction types is still in progress.)
+- sparc64 (Return probes not yet implemented.)
+
+3. Configuring Kprobes
+
+When configuring the kernel using make menuconfig/xconfig/oldconfig,
+ensure that CONFIG_KPROBES is set to "y".  Under "Kernel hacking",
+look for "Kprobes".  You may have to enable "Kernel debugging"
+(CONFIG_DEBUG_KERNEL) before you can enable Kprobes.
+
+You may also want to ensure that CONFIG_KALLSYMS and perhaps even
+CONFIG_KALLSYMS_ALL are set to "y", since kallsyms_lookup_name()
+is a handy, version-independent way to find a function's address.
+
+If you need to insert a probe in the middle of a function, you may find
+it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
+so you can use "objdump -d -l vmlinux" to see the source-to-object
+code mapping.
+
+4. API Reference
+
+The Kprobes API includes a "register" function and an "unregister"
+function for each type of probe.  Here are terse, mini-man-page
+specifications for these functions and the associated probe handlers
+that you'll write.  See the latter half of this document for examples.
+
+4.1 register_kprobe
+
+#include <linux/kprobes.h>
+int register_kprobe(struct kprobe *kp);
+
+Sets a breakpoint at the address kp->addr.  When the breakpoint is
+hit, Kprobes calls kp->pre_handler.  After the probed instruction
+is single-stepped, Kprobe calls kp->post_handler.  If a fault
+occurs during execution of kp->pre_handler or kp->post_handler,
+or during single-stepping of the probed instruction, Kprobes calls
+kp->fault_handler.  Any or all handlers can be NULL.
+
+register_kprobe() returns 0 on success, or a negative errno otherwise.
+
+User's pre-handler (kp->pre_handler):
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
+int pre_handler(struct kprobe *p, struct pt_regs *regs);
+
+Called with p pointing to the kprobe associated with the breakpoint,
+and regs pointing to the struct containing the registers saved when
+the breakpoint was hit.  Return 0 here unless you're a Kprobes geek.
+
+User's post-handler (kp->post_handler):
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
+void post_handler(struct kprobe *p, struct pt_regs *regs,
+       unsigned long flags);
+
+p and regs are as described for the pre_handler.  flags always seems
+to be zero.
+
+User's fault-handler (kp->fault_handler):
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
+int fault_handler(struct kprobe *p, struct pt_regs *regs, int trapnr);
+
+p and regs are as described for the pre_handler.  trapnr is the
+architecture-specific trap number associated with the fault (e.g.,
+on i386, 13 for a general protection fault or 14 for a page fault).
+Returns 1 if it successfully handled the exception.
+
+4.2 register_jprobe
+
+#include <linux/kprobes.h>
+int register_jprobe(struct jprobe *jp)
+
+Sets a breakpoint at the address jp->kp.addr, which must be the address
+of the first instruction of a function.  When the breakpoint is hit,
+Kprobes runs the handler whose address is jp->entry.
+
+The handler should have the same arg list and return type as the probed
+function; and just before it returns, it must call jprobe_return().
+(The handler never actually returns, since jprobe_return() returns
+control to Kprobes.)  If the probed function is declared asmlinkage,
+fastcall, or anything else that affects how args are passed, the
+handler's declaration must match.
+
+register_jprobe() returns 0 on success, or a negative errno otherwise.
+
+4.3 register_kretprobe
+
+#include <linux/kprobes.h>
+int register_kretprobe(struct kretprobe *rp);
+
+Establishes a return probe for the function whose address is
+rp->kp.addr.  When that function returns, Kprobes calls rp->handler.
+You must set rp->maxactive appropriately before you call
+register_kretprobe(); see "How Does a Return Probe Work?" for details.
+
+register_kretprobe() returns 0 on success, or a negative errno
+otherwise.
+
+User's return-probe handler (rp->handler):
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
+int kretprobe_handler(struct kretprobe_instance *ri, struct pt_regs *regs);
+
+regs is as described for kprobe.pre_handler.  ri points to the
+kretprobe_instance object, of which the following fields may be
+of interest:
+- ret_addr: the return address
+- rp: points to the corresponding kretprobe object
+- task: points to the corresponding task struct
+The handler's return value is currently ignored.
+
+4.4 unregister_*probe
+
+#include <linux/kprobes.h>
+void unregister_kprobe(struct kprobe *kp);
+void unregister_jprobe(struct jprobe *jp);
+void unregister_kretprobe(struct kretprobe *rp);
+
+Removes the specified probe.  The unregister function can be called
+at any time after the probe has been registered.
+
+5. Kprobes Features and Limitations
+
+As of Linux v2.6.12, Kprobes allows multiple probes at the same
+address.  Currently, however, there cannot be multiple jprobes on
+the same function at the same time.
+
+In general, you can install a probe anywhere in the kernel.
+In particular, you can probe interrupt handlers.  Known exceptions
+are discussed in this section.
+
+For obvious reasons, it's a bad idea to install a probe in
+the code that implements Kprobes (mostly kernel/kprobes.c and
+arch/*/kernel/kprobes.c).  A patch in the v2.6.13 timeframe instructs
+Kprobes to reject such requests.
+
+If you install a probe in an inline-able function, Kprobes makes
+no attempt to chase down all inline instances of the function and
+install probes there.  gcc may inline a function without being asked,
+so keep this in mind if you're not seeing the probe hits you expect.
+
+A probe handler can modify the environment of the probed function
+-- e.g., by modifying kernel data structures, or by modifying the
+contents of the pt_regs struct (which are restored to the registers
+upon return from the breakpoint).  So Kprobes can be used, for example,
+to install a bug fix or to inject faults for testing.  Kprobes, of
+course, has no way to distinguish the deliberately injected faults
+from the accidental ones.  Don't drink and probe.
+
+Kprobes makes no attempt to prevent probe handlers from stepping on
+each other -- e.g., probing printk() and then calling printk() from a
+probe handler.  As of Linux v2.6.12, if a probe handler hits a probe,
+that second probe's handlers won't be run in that instance.
+
+In Linux v2.6.12 and previous versions, Kprobes' data structures are
+protected by a single lock that is held during probe registration and
+unregistration and while handlers are run.  Thus, no two handlers
+can run simultaneously.  To improve scalability on SMP systems,
+this restriction will probably be removed soon, in which case
+multiple handlers (or multiple instances of the same handler) may
+run concurrently on different CPUs.  Code your handlers accordingly.
+
+Kprobes does not use semaphores or allocate memory except during
+registration and unregistration.
+
+Probe handlers are run with preemption disabled.  Depending on the
+architecture, handlers may also run with interrupts disabled.  In any
+case, your handler should not yield the CPU (e.g., by attempting to
+acquire a semaphore).
+
+Since a return probe is implemented by replacing the return
+address with the trampoline's address, stack backtraces and calls
+to __builtin_return_address() will typically yield the trampoline's
+address instead of the real return address for kretprobed functions.
+(As far as we can tell, __builtin_return_address() is used only
+for instrumentation and error reporting.)
+
+If the number of times a function is called does not match the
+number of times it returns, registering a return probe on that
+function may produce undesirable results.  We have the do_exit()
+and do_execve() cases covered.  do_fork() is not an issue.  We're
+unaware of other specific cases where this could be a problem.
+
+6. Probe Overhead
+
+On a typical CPU in use in 2005, a kprobe hit takes 0.5 to 1.0
+microseconds to process.  Specifically, a benchmark that hits the same
+probepoint repeatedly, firing a simple handler each time, reports 1-2
+million hits per second, depending on the architecture.  A jprobe or
+return-probe hit typically takes 50-75% longer than a kprobe hit.
+When you have a return probe set on a function, adding a kprobe at
+the entry to that function adds essentially no overhead.
+
+Here are sample overhead figures (in usec) for different architectures.
+k = kprobe; j = jprobe; r = return probe; kr = kprobe + return probe
+on same function; jr = jprobe + return probe on same function
+
+i386: Intel Pentium M, 1495 MHz, 2957.31 bogomips
+k = 0.57 usec; j = 1.00; r = 0.92; kr = 0.99; jr = 1.40
+
+x86_64: AMD Opteron 246, 1994 MHz, 3971.48 bogomips
+k = 0.49 usec; j = 0.76; r = 0.80; kr = 0.82; jr = 1.07
+
+ppc64: POWER5 (gr), 1656 MHz (SMT disabled, 1 virtual CPU per physical CPU)
+k = 0.77 usec; j = 1.31; r = 1.26; kr = 1.45; jr = 1.99
+
+7. TODO
+
+a. SystemTap (http://sourceware.org/systemtap): Work in progress
+to provide a simplified programming interface for probe-based
+instrumentation.
+b. Improved SMP scalability: Currently, work is in progress to handle
+multiple kprobes in parallel.
+c. Kernel return probes for sparc64.
+d. Support for other architectures.
+e. User-space probes.
+
+8. Kprobes Example
+
+Here's a sample kernel module showing the use of kprobes to dump a
+stack trace and selected i386 registers when do_fork() is called.
+----- cut here -----
+/*kprobe_example.c*/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/kallsyms.h>
+#include <linux/sched.h>
+
+/*For each probe you need to allocate a kprobe structure*/
+static struct kprobe kp;
+
+/*kprobe pre_handler: called just before the probed instruction is executed*/
+int handler_pre(struct kprobe *p, struct pt_regs *regs)
+{
+       printk("pre_handler: p->addr=0x%p, eip=%lx, eflags=0x%lx\n",
+               p->addr, regs->eip, regs->eflags);
+       dump_stack();
+       return 0;
+}
+
+/*kprobe post_handler: called after the probed instruction is executed*/
+void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags)
+{
+       printk("post_handler: p->addr=0x%p, eflags=0x%lx\n",
+               p->addr, regs->eflags);
+}
+
+/* fault_handler: this is called if an exception is generated for any
+ * instruction within the pre- or post-handler, or when Kprobes
+ * single-steps the probed instruction.
+ */
+int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
+{
+       printk("fault_handler: p->addr=0x%p, trap #%dn",
+               p->addr, trapnr);
+       /* Return 0 because we don't handle the fault. */
+       return 0;
+}
+
+int init_module(void)
+{
+       int ret;
+       kp.pre_handler = handler_pre;
+       kp.post_handler = handler_post;
+       kp.fault_handler = handler_fault;
+       kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("do_fork");
+       /* register the kprobe now */
+       if (!kp.addr) {
+               printk("Couldn't find %s to plant kprobe\n", "do_fork");
+               return -1;
+       }
+       if ((ret = register_kprobe(&kp) < 0)) {
+               printk("register_kprobe failed, returned %d\n", ret);
+               return -1;
+       }
+       printk("kprobe registered\n");
+       return 0;
+}
+
+void cleanup_module(void)
+{
+       unregister_kprobe(&kp);
+       printk("kprobe unregistered\n");
+}
+
+MODULE_LICENSE("GPL");
+----- cut here -----
+
+You can build the kernel module, kprobe-example.ko, using the following
+Makefile:
+----- cut here -----
+obj-m := kprobe-example.o
+KDIR := /lib/modules/$(shell uname -r)/build
+PWD := $(shell pwd)
+default:
+       $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+clean:
+       rm -f *.mod.c *.ko *.o
+----- cut here -----
+
+$ make
+$ su -
+...
+# insmod kprobe-example.ko
+
+You will see the trace data in /var/log/messages and on the console
+whenever do_fork() is invoked to create a new process.
+
+9. Jprobes Example
+
+Here's a sample kernel module showing the use of jprobes to dump
+the arguments of do_fork().
+----- cut here -----
+/*jprobe-example.c */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/uio.h>
+#include <linux/kprobes.h>
+#include <linux/kallsyms.h>
+
+/*
+ * Jumper probe for do_fork.
+ * Mirror principle enables access to arguments of the probed routine
+ * from the probe handler.
+ */
+
+/* Proxy routine having the same arguments as actual do_fork() routine */
+long jdo_fork(unsigned long clone_flags, unsigned long stack_start,
+             struct pt_regs *regs, unsigned long stack_size,
+             int __user * parent_tidptr, int __user * child_tidptr)
+{
+       printk("jprobe: clone_flags=0x%lx, stack_size=0x%lx, regs=0x%p\n",
+              clone_flags, stack_size, regs);
+       /* Always end with a call to jprobe_return(). */
+       jprobe_return();
+       /*NOTREACHED*/
+       return 0;
+}
+
+static struct jprobe my_jprobe = {
+       .entry = (kprobe_opcode_t *) jdo_fork
+};
+
+int init_module(void)
+{
+       int ret;
+       my_jprobe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("do_fork");
+       if (!my_jprobe.kp.addr) {
+               printk("Couldn't find %s to plant jprobe\n", "do_fork");
+               return -1;
+       }
+
+       if ((ret = register_jprobe(&my_jprobe)) <0) {
+               printk("register_jprobe failed, returned %d\n", ret);
+               return -1;
+       }
+       printk("Planted jprobe at %p, handler addr %p\n",
+              my_jprobe.kp.addr, my_jprobe.entry);
+       return 0;
+}
+
+void cleanup_module(void)
+{
+       unregister_jprobe(&my_jprobe);
+       printk("jprobe unregistered\n");
+}
+
+MODULE_LICENSE("GPL");
+----- cut here -----
+
+Build and insert the kernel module as shown in the above kprobe
+example.  You will see the trace data in /var/log/messages and on
+the console whenever do_fork() is invoked to create a new process.
+(Some messages may be suppressed if syslogd is configured to
+eliminate duplicate messages.)
+
+10. Kretprobes Example
+
+Here's a sample kernel module showing the use of return probes to
+report failed calls to sys_open().
+----- cut here -----
+/*kretprobe-example.c*/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/kallsyms.h>
+
+static const char *probed_func = "sys_open";
+
+/* Return-probe handler: If the probed function fails, log the return value. */
+static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+       // Substitute the appropriate register name for your architecture --
+       // e.g., regs->rax for x86_64, regs->gpr[3] for ppc64.
+       int retval = (int) regs->eax;
+       if (retval < 0) {
+               printk("%s returns %d\n", probed_func, retval);
+       }
+       return 0;
+}
+
+static struct kretprobe my_kretprobe = {
+       .handler = ret_handler,
+       /* Probe up to 20 instances concurrently. */
+       .maxactive = 20
+};
+
+int init_module(void)
+{
+       int ret;
+       my_kretprobe.kp.addr =
+               (kprobe_opcode_t *) kallsyms_lookup_name(probed_func);
+       if (!my_kretprobe.kp.addr) {
+               printk("Couldn't find %s to plant return probe\n", probed_func);
+               return -1;
+       }
+       if ((ret = register_kretprobe(&my_kretprobe)) < 0) {
+               printk("register_kretprobe failed, returned %d\n", ret);
+               return -1;
+       }
+       printk("Planted return probe at %p\n", my_kretprobe.kp.addr);
+       return 0;
+}
+
+void cleanup_module(void)
+{
+       unregister_kretprobe(&my_kretprobe);
+       printk("kretprobe unregistered\n");
+       /* nmissed > 0 suggests that maxactive was set too low. */
+       printk("Missed probing %d instances of %s\n",
+               my_kretprobe.nmissed, probed_func);
+}
+
+MODULE_LICENSE("GPL");
+----- cut here -----
+
+Build and insert the kernel module as shown in the above kprobe
+example.  You will see the trace data in /var/log/messages and on the
+console whenever sys_open() returns a negative value.  (Some messages
+may be suppressed if syslogd is configured to eliminate duplicate
+messages.)
+
+For additional information on Kprobes, refer to the following URLs:
+http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe
+http://www.redhat.com/magazine/005mar05/features/kprobes/
diff -urN linux/Documentation/dontdiff linux/Documentation/dontdiff
--- linux/Documentation/dontdiff        2005/08/01 18:23:35     1.4
+++ linux/Documentation/dontdiff        2005/08/08 12:30:24     1.5
@@ -104,6 +104,7 @@
 logo_*_clut224.c
 logo_*_mono.c
 lxdialog
+mach-types
 mach-types.h
 make_times_h
 map
diff -urN linux/Documentation/usb/usbmon.txt linux/Documentation/usb/usbmon.txt
--- linux/Documentation/usb/usbmon.txt  2005/07/13 11:48:49     1.2
+++ linux/Documentation/usb/usbmon.txt  2005/08/08 12:30:24     1.3
@@ -102,7 +102,7 @@
 - URB Status. This field makes no sense for submissions, but is present
   to help scripts with parsing. In error case, it contains the error code.
   In case of a setup packet, it contains a Setup Tag. If scripts read a number
-  in this field, the proceed to read Data Length. Otherwise, they read
+  in this field, they proceed to read Data Length. Otherwise, they read
   the setup packet before reading the Data Length.
 - Setup packet, if present, consists of 5 words: one of each for bmRequestType,
   bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0.
diff -urN linux/Documentation/video4linux/bttv/Insmod-options 
linux/Documentation/video4linux/bttv/Insmod-options
--- linux/Documentation/video4linux/bttv/Insmod-options 2004/02/05 02:39:51     
1.12
+++ linux/Documentation/video4linux/bttv/Insmod-options 2005/08/08 12:30:24     
1.13
@@ -44,6 +44,9 @@
                                push used by bttv.  bttv will disable overlay
                                by default on this hardware to avoid crashes.
                                With this insmod option you can override this.
+               no_overlay=1    Disable overlay. It should be used by broken
+                               hardware that doesn't support PCI2PCI direct
+                               transfers.
                automute=0/1    Automatically mutes the sound if there is
                                no TV signal, on by default.  You might try
                                to disable this if you have bad input signal
diff -urN linux/Documentation/x86_64/boot-options.txt 
linux/Documentation/x86_64/boot-options.txt
--- linux/Documentation/x86_64/boot-options.txt 2005/08/03 15:50:23     1.10
+++ linux/Documentation/x86_64/boot-options.txt 2005/08/08 12:30:24     1.11
@@ -6,6 +6,11 @@
 Machine check
 
    mce=off disable machine check
+   mce=bootlog Enable logging of machine checks left over from booting.
+               Disabled by default because some BIOS leave bogus ones.
+               If your BIOS doesn't do that it's a good idea to enable though
+               to make sure you log even machine check events that result
+               in a reboot.
 
    nomce (for compatibility with i386): same as mce=off
 
diff -urN linux/arch/alpha/kernel/pci.c linux/arch/alpha/kernel/pci.c
--- linux/arch/alpha/kernel/pci.c       2004/10/25 20:44:09     1.41
+++ linux/arch/alpha/kernel/pci.c       2005/08/08 12:30:24     1.42
@@ -350,8 +350,24 @@
        region->end = res->end - offset;
 }
 
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                            struct pci_bus_region *region)
+{
+       struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
+       unsigned long offset = 0;
+
+       if (res->flags & IORESOURCE_IO)
+               offset = hose->io_space->start;
+       else if (res->flags & IORESOURCE_MEM)
+               offset = hose->mem_space->start;
+
+       res->start = region->start + offset;
+       res->end = region->end + offset;
+}
+
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(pcibios_bus_to_resource);
 #endif
 
 int
diff -urN linux/arch/arm/kernel/bios32.c linux/arch/arm/kernel/bios32.c
--- linux/arch/arm/kernel/bios32.c      2004/11/15 11:49:14     1.47
+++ linux/arch/arm/kernel/bios32.c      2005/08/08 12:30:24     1.48
@@ -447,9 +447,26 @@
        region->end   = res->end - offset;
 }
 
+void __devinit
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                       struct pci_bus_region *region)
+{
+       struct pci_sys_data *root = dev->sysdata;
+       unsigned long offset = 0;
+
+       if (res->flags & IORESOURCE_IO)
+               offset = root->io_offset;
+       if (res->flags & IORESOURCE_MEM)
+               offset = root->mem_offset;
+
+       res->start = region->start + offset;
+       res->end   = region->end + offset;
+}
+
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pcibios_fixup_bus);
 EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(pcibios_bus_to_resource);
 #endif
 
 /*
diff -urN linux/arch/arm/mach-ixp4xx/coyote-setup.c 
linux/arch/arm/mach-ixp4xx/coyote-setup.c
--- linux/arch/arm/mach-ixp4xx/coyote-setup.c   2005/07/13 11:48:50     1.10
+++ linux/arch/arm/mach-ixp4xx/coyote-setup.c   2005/08/08 12:30:24     1.11
@@ -61,7 +61,7 @@
                .mapbase        = IXP4XX_UART2_BASE_PHYS,
                .membase        = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
                .irq            = IRQ_IXP4XX_UART2,
-               .flags          = UPF_BOOT_AUTOCONF,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
                .iotype         = UPIO_MEM,
                .regshift       = 2,
                .uartclk        = IXP4XX_UART_XTAL,
diff -urN linux/arch/arm/mach-ixp4xx/gtwx5715-setup.c 
linux/arch/arm/mach-ixp4xx/gtwx5715-setup.c
--- linux/arch/arm/mach-ixp4xx/gtwx5715-setup.c 2005/07/12 09:18:57     1.2
+++ linux/arch/arm/mach-ixp4xx/gtwx5715-setup.c 2005/08/08 12:30:24     1.3
@@ -83,7 +83,7 @@
        .mapbase        = IXP4XX_UART2_BASE_PHYS,
        .membase        = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
        .irq            = IRQ_IXP4XX_UART2,
-       .flags          = UPF_BOOT_AUTOCONF,
+       .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
        .iotype         = UPIO_MEM,
        .regshift       = 2,
        .uartclk        = IXP4XX_UART_XTAL,
diff -urN linux/arch/arm/mach-ixp4xx/ixdp425-setup.c 
linux/arch/arm/mach-ixp4xx/ixdp425-setup.c
--- linux/arch/arm/mach-ixp4xx/ixdp425-setup.c  2005/07/13 11:48:50     1.9
+++ linux/arch/arm/mach-ixp4xx/ixdp425-setup.c  2005/08/08 12:30:24     1.10
@@ -82,7 +82,7 @@
                .mapbase        = IXP4XX_UART1_BASE_PHYS,
                .membase        = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
                .irq            = IRQ_IXP4XX_UART1,
-               .flags          = UPF_BOOT_AUTOCONF,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
                .iotype         = UPIO_MEM,
                .regshift       = 2,
                .uartclk        = IXP4XX_UART_XTAL,
@@ -91,7 +91,7 @@
                .mapbase        = IXP4XX_UART2_BASE_PHYS,
                .membase        = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
                .irq            = IRQ_IXP4XX_UART1,
-               .flags          = UPF_BOOT_AUTOCONF,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
                .iotype         = UPIO_MEM,
                .regshift       = 2,
                .uartclk        = IXP4XX_UART_XTAL,
diff -urN linux/arch/arm/mach-s3c2410/mach-bast.c 
linux/arch/arm/mach-s3c2410/mach-bast.c
--- linux/arch/arm/mach-s3c2410/mach-bast.c     2005/08/01 18:23:38     1.13
+++ linux/arch/arm/mach-s3c2410/mach-bast.c     2005/08/08 12:30:25     1.14
@@ -30,6 +30,7 @@
  *     28-Jun-2005 BJD  Moved pm functionality out to common code
  *     17-Jul-2005 BJD  Changed to platform device for SuperIO 16550s
  *     25-Jul-2005 BJD  Removed ASIX static mappings
+ *     27-Jul-2005 BJD  Ensure maximum frequency of i2c bus
 */
 
 #include <linux/kernel.h>
@@ -60,6 +61,7 @@
 #include <asm/arch/regs-mem.h>
 #include <asm/arch/regs-lcd.h>
 #include <asm/arch/nand.h>
+#include <asm/arch/iic.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
@@ -304,7 +306,7 @@
 }
 
 static struct s3c2410_platform_nand bast_nand_info = {
-       .tacls          = 80,
+       .tacls          = 40,
        .twrph0         = 80,
        .twrph1         = 80,
        .nr_sets        = ARRAY_SIZE(bast_nand_sets),
@@ -385,6 +387,17 @@
        },
 };
 
+/* we have devices on the bus which cannot work much over the
+ * standard 100KHz i2c bus frequency
+*/
+
+static struct s3c2410_platform_i2c bast_i2c_info = {
+       .flags          = 0,
+       .slave_addr     = 0x10,
+       .bus_freq       = 100*1000,
+       .max_freq       = 130*1000,
+};
+
 /* Standard BAST devices */
 
 static struct platform_device *bast_devices[] __initdata = {
@@ -431,6 +444,7 @@
        s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
        s3c_device_nand.dev.platform_data = &bast_nand_info;
+       s3c_device_i2c.dev.platform_data = &bast_i2c_info;
 
        s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
        s3c24xx_init_clocks(0);
diff -urN linux/arch/arm/mach-sa1100/jornada720.c 
linux/arch/arm/mach-sa1100/jornada720.c
--- linux/arch/arm/mach-sa1100/jornada720.c     2005/07/12 09:18:59     1.15
+++ linux/arch/arm/mach-sa1100/jornada720.c     2005/08/08 12:30:25     1.16
@@ -97,6 +97,7 @@
 }
 
 MACHINE_START(JORNADA720, "HP Jornada 720")
+       /* Maintainer: Michael Gernoth <michael@gernoth.net> */
        .phys_ram       = 0xc0000000,
        .phys_io        = 0x80000000,
        .io_pg_offst    = ((0xf8000000) >> 18) & 0xfffc,
diff -urN linux/arch/arm/mm/fault.c linux/arch/arm/mm/fault.c
--- linux/arch/arm/mm/fault.c   2005/07/12 09:19:00     1.6
+++ linux/arch/arm/mm/fault.c   2005/08/08 12:30:25     1.7
@@ -238,9 +238,9 @@
        up_read(&mm->mmap_sem);
 
        /*
-        * Handle the "normal" case first
+        * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR
         */
-       if (fault > 0)
+       if (fault >= VM_FAULT_MINOR)
                return 0;
 
        /*
@@ -261,7 +261,7 @@
                do_exit(SIGKILL);
                return 0;
 
-       case 0:
+       case VM_FAULT_SIGBUS:
                /*
                 * We had some memory, but were unable to
                 * successfully fix up this page fault.
diff -urN linux/arch/arm/mm/proc-xscale.S linux/arch/arm/mm/proc-xscale.S
--- linux/arch/arm/mm/proc-xscale.S     2005/01/13 14:05:19     1.22
+++ linux/arch/arm/mm/proc-xscale.S     2005/08/08 12:30:25     1.23
@@ -370,142 +370,6 @@
        bhi     1b
        mov     pc, lr
 
-/* ================================ CACHE LOCKING============================
- *
- * The XScale MicroArchitecture implements support for locking entries into
- * the data and instruction cache.  The following functions implement the core
- * low level instructions needed to accomplish the locking.  The developer's
- * manual states that the code that performs the locking must be in non-cached
- * memory.  To accomplish this, the code in xscale-cache-lock.c copies the
- * following functions from the cache into a non-cached memory region that
- * is allocated through consistent_alloc().
- *
- */
-       .align  5
-/*
- * xscale_icache_lock
- *
- * r0: starting address to lock
- * r1: end address to lock
- */
-ENTRY(xscale_icache_lock)
-
-iLockLoop:
-       bic     r0, r0, #CACHELINESIZE - 1
-       mcr     p15, 0, r0, c9, c1, 0   @ lock into cache
-       cmp     r0, r1                  @ are we done?
-       add     r0, r0, #CACHELINESIZE  @ advance to next cache line
-       bls     iLockLoop
-       mov     pc, lr
-
-/*
- * xscale_icache_unlock
- */
-ENTRY(xscale_icache_unlock)
-       mcr     p15, 0, r0, c9, c1, 1   @ Unlock icache
-       mov     pc, lr
-
-/*
- * xscale_dcache_lock
- *
- * r0: starting address to lock
- * r1: end address to lock
- */
-ENTRY(xscale_dcache_lock)
-       mcr     p15, 0, ip, c7, c10, 4          @ Drain Write (& Fill) Buffer
-       mov     r2, #1
-       mcr     p15, 0, r2, c9, c2, 0   @ Put dcache in lock mode
-       cpwait  ip                      @ Wait for completion
-
-       mrs     r2, cpsr
-       orr     r3, r2, #PSR_F_BIT | PSR_I_BIT
-dLockLoop:
-       msr     cpsr_c, r3
-       mcr     p15, 0, r0, c7, c10, 1  @ Write back line if it is dirty
-       mcr     p15, 0, r0, c7, c6, 1   @ Flush/invalidate line
-       msr     cpsr_c, r2
-       ldr     ip, [r0], #CACHELINESIZE @ Preload 32 bytes into cache from
-                                       @ location [r0]. Post-increment
-                                       @ r3 to next cache line
-       cmp     r0, r1                  @ Are we done?
-       bls     dLockLoop
-
-       mcr     p15, 0, ip, c7, c10, 4          @ Drain Write (& Fill) Buffer
-       mov     r2, #0
-       mcr     p15, 0, r2, c9, c2, 0   @ Get out of lock mode
-       cpwait_ret lr, ip
-
-/*
- * xscale_dcache_unlock
- */
-ENTRY(xscale_dcache_unlock)
-       mcr     p15, 0, ip, c7, c10, 4          @ Drain Write (& Fill) Buffer
-       mcr     p15, 0, ip, c9, c2, 1   @ Unlock cache
-       mov     pc, lr
-
-/*
- * Needed to determine the length of the code that needs to be copied.
- */
-       .align  5
-ENTRY(xscale_cache_dummy)
-       mov     pc, lr
-
-/* ================================ TLB LOCKING==============================
- *
- * The XScale MicroArchitecture implements support for locking entries into
- * the Instruction and Data TLBs.  The following functions provide the
- * low level support for supporting these under Linux.  xscale-lock.c
- * implements some higher level management code.  Most of the following
- * is taken straight out of the Developer's Manual.
- */
-
-/*
- * Lock I-TLB entry
- *
- * r0: Virtual address to translate and lock
- */
-       .align  5
-ENTRY(xscale_itlb_lock)
-       mrs     r2, cpsr
-       orr     r3, r2, #PSR_F_BIT | PSR_I_BIT
-       msr     cpsr_c, r3                      @ Disable interrupts
-       mcr     p15, 0, r0, c8, c5, 1           @ Invalidate I-TLB entry
-       mcr     p15, 0, r0, c10, c4, 0          @ Translate and lock
-       msr     cpsr_c, r2                      @ Restore interrupts
-       cpwait_ret lr, ip
-
-/*
- * Lock D-TLB entry
- *
- * r0: Virtual address to translate and lock
- */
-       .align  5
-ENTRY(xscale_dtlb_lock)
-       mrs     r2, cpsr
-       orr     r3, r2, #PSR_F_BIT | PSR_I_BIT
-       msr     cpsr_c, r3                      @ Disable interrupts
-       mcr     p15, 0, r0, c8, c6, 1           @ Invalidate D-TLB entry
-       mcr     p15, 0, r0, c10, c8, 0          @ Translate and lock
-       msr     cpsr_c, r2                      @ Restore interrupts
-       cpwait_ret lr, ip
-
-/*
- * Unlock all I-TLB entries
- */
-       .align  5
-ENTRY(xscale_itlb_unlock)
-       mcr     p15, 0, ip, c10, c4, 1          @ Unlock I-TLB
-       mcr     p15, 0, ip, c8, c5, 0           @ Invalidate I-TLB
-       cpwait_ret lr, ip
-
-/*
- * Unlock all D-TLB entries
- */
-ENTRY(xscale_dtlb_unlock)
-       mcr     p15, 0, ip, c10, c8, 1          @ Unlock D-TBL
-       mcr     p15, 0, ip, c8, c6, 0           @ Invalidate D-TLB
-       cpwait_ret lr, ip
-
 /* =============================== PageTable ============================== */
 
 #define PTE_CACHE_WRITE_ALLOCATE 0
diff -urN linux/arch/arm/nwfpe/double_cpdo.c linux/arch/arm/nwfpe/double_cpdo.c
--- linux/arch/arm/nwfpe/double_cpdo.c  2004/11/15 11:49:15     1.9
+++ linux/arch/arm/nwfpe/double_cpdo.c  2005/08/08 12:30:25     1.10
@@ -40,17 +40,17 @@
 float64 float64_pow(float64 rFn, float64 rFm);
 float64 float64_pol(float64 rFn, float64 rFm);
 
-static float64 float64_rsf(float64 rFn, float64 rFm)
+static float64 float64_rsf(struct roundingData *roundData, float64 rFn, 
float64 rFm)
 {
-       return float64_sub(rFm, rFn);
+       return float64_sub(roundData, rFm, rFn);
 }
 
-static float64 float64_rdv(float64 rFn, float64 rFm)
+static float64 float64_rdv(struct roundingData *roundData, float64 rFn, 
float64 rFm)
 {
-       return float64_div(rFm, rFn);
+       return float64_div(roundData, rFm, rFn);
 }
 
-static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = {
+static float64 (*const dyadic_double[16])(struct roundingData*, float64 rFn, 
float64 rFm) = {
        [ADF_CODE >> 20] = float64_add,
        [MUF_CODE >> 20] = float64_mul,
        [SUF_CODE >> 20] = float64_sub,
@@ -65,12 +65,12 @@
        [FRD_CODE >> 20] = float64_rdv,
 };
 
-static float64 float64_mvf(float64 rFm)
+static float64 float64_mvf(struct roundingData *roundData,float64 rFm)
 {
        return rFm;
 }
 
-static float64 float64_mnf(float64 rFm)
+static float64 float64_mnf(struct roundingData *roundData,float64 rFm)
 {
        union float64_components u;
 
@@ -84,7 +84,7 @@
        return u.f64;
 }
 
-static float64 float64_abs(float64 rFm)
+static float64 float64_abs(struct roundingData *roundData,float64 rFm)
 {
        union float64_components u;
 
@@ -98,7 +98,7 @@
        return u.f64;
 }
 
-static float64 (*const monadic_double[16])(float64 rFm) = {
+static float64 (*const monadic_double[16])(struct roundingData *, float64 rFm) 
= {
        [MVF_CODE >> 20] = float64_mvf,
        [MNF_CODE >> 20] = float64_mnf,
        [ABS_CODE >> 20] = float64_abs,
@@ -108,7 +108,7 @@
        [NRM_CODE >> 20] = float64_mvf,
 };
 
-unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd)
+unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int 
opcode, FPREG * rFd)
 {
        FPA11 *fpa11 = GET_FPA11();
        float64 rFm;
@@ -151,13 +151,13 @@
                }
 
                if (dyadic_double[opc_mask_shift]) {
-                       rFd->fDouble = dyadic_double[opc_mask_shift](rFn, rFm);
+                       rFd->fDouble = dyadic_double[opc_mask_shift](roundData, 
rFn, rFm);
                } else {
                        return 0;
                }
        } else {
                if (monadic_double[opc_mask_shift]) {
-                       rFd->fDouble = monadic_double[opc_mask_shift](rFm);
+                       rFd->fDouble = 
monadic_double[opc_mask_shift](roundData, rFm);
                } else {
                        return 0;
                }
diff -urN linux/arch/arm/nwfpe/extended_cpdo.c 
linux/arch/arm/nwfpe/extended_cpdo.c
--- linux/arch/arm/nwfpe/extended_cpdo.c        2003/06/05 14:43:25     1.8
+++ linux/arch/arm/nwfpe/extended_cpdo.c        2005/08/08 12:30:25     1.9
@@ -35,17 +35,17 @@
 floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm);
 floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm);
 
-static floatx80 floatx80_rsf(floatx80 rFn, floatx80 rFm)
+static floatx80 floatx80_rsf(struct roundingData *roundData, floatx80 rFn, 
floatx80 rFm)
 {
-       return floatx80_sub(rFm, rFn);
+       return floatx80_sub(roundData, rFm, rFn);
 }
 
-static floatx80 floatx80_rdv(floatx80 rFn, floatx80 rFm)
+static floatx80 floatx80_rdv(struct roundingData *roundData, floatx80 rFn, 
floatx80 rFm)
 {
-       return floatx80_div(rFm, rFn);
+       return floatx80_div(roundData, rFm, rFn);
 }
 
-static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = {
+static floatx80 (*const dyadic_extended[16])(struct roundingData*, floatx80 
rFn, floatx80 rFm) = {
        [ADF_CODE >> 20] = floatx80_add,
        [MUF_CODE >> 20] = floatx80_mul,
        [SUF_CODE >> 20] = floatx80_sub,
@@ -60,24 +60,24 @@
        [FRD_CODE >> 20] = floatx80_rdv,
 };
 
-static floatx80 floatx80_mvf(floatx80 rFm)
+static floatx80 floatx80_mvf(struct roundingData *roundData, floatx80 rFm)
 {
        return rFm;
 }
 
-static floatx80 floatx80_mnf(floatx80 rFm)
+static floatx80 floatx80_mnf(struct roundingData *roundData, floatx80 rFm)
 {
        rFm.high ^= 0x8000;
        return rFm;
 }
 
-static floatx80 floatx80_abs(floatx80 rFm)
+static floatx80 floatx80_abs(struct roundingData *roundData, floatx80 rFm)
 {
        rFm.high &= 0x7fff;
        return rFm;
 }
 
-static floatx80 (*const monadic_extended[16])(floatx80 rFm) = {
+static floatx80 (*const monadic_extended[16])(struct roundingData*, floatx80 
rFm) = {
        [MVF_CODE >> 20] = floatx80_mvf,
        [MNF_CODE >> 20] = floatx80_mnf,
        [ABS_CODE >> 20] = floatx80_abs,
@@ -87,7 +87,7 @@
        [NRM_CODE >> 20] = floatx80_mvf,
 };
 
-unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd)
+unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int 
opcode, FPREG * rFd)
 {
        FPA11 *fpa11 = GET_FPA11();
        floatx80 rFm;
@@ -138,13 +138,13 @@
                }
 
                if (dyadic_extended[opc_mask_shift]) {
-                       rFd->fExtended = dyadic_extended[opc_mask_shift](rFn, 
rFm);
+                       rFd->fExtended = 
dyadic_extended[opc_mask_shift](roundData, rFn, rFm);
                } else {
                        return 0;
                }
        } else {
                if (monadic_extended[opc_mask_shift]) {
-                       rFd->fExtended = monadic_extended[opc_mask_shift](rFm);
+                       rFd->fExtended = 
monadic_extended[opc_mask_shift](roundData, rFm);
                } else {
                        return 0;
                }
diff -urN linux/arch/arm/nwfpe/fpa11.c linux/arch/arm/nwfpe/fpa11.c
--- linux/arch/arm/nwfpe/fpa11.c        2003/09/30 14:27:17     1.12
+++ linux/arch/arm/nwfpe/fpa11.c        2005/08/08 12:30:25     1.13
@@ -51,48 +51,42 @@
        fpa11->fpsr = FP_EMULATOR | BIT_AC;
 }
 
-void SetRoundingMode(const unsigned int opcode)
+int8 SetRoundingMode(const unsigned int opcode)
 {
        switch (opcode & MASK_ROUNDING_MODE) {
        default:
        case ROUND_TO_NEAREST:
-               float_rounding_mode = float_round_nearest_even;
-               break;
+               return float_round_nearest_even;
 
        case ROUND_TO_PLUS_INFINITY:
-               float_rounding_mode = float_round_up;
-               break;
+               return float_round_up;
 
        case ROUND_TO_MINUS_INFINITY:
-               float_rounding_mode = float_round_down;
-               break;
+               return float_round_down;
 
        case ROUND_TO_ZERO:
-               float_rounding_mode = float_round_to_zero;
-               break;
+               return float_round_to_zero;
        }
 }
 
-void SetRoundingPrecision(const unsigned int opcode)
+int8 SetRoundingPrecision(const unsigned int opcode)
 {
 #ifdef CONFIG_FPE_NWFPE_XP
        switch (opcode & MASK_ROUNDING_PRECISION) {
        case ROUND_SINGLE:
-               floatx80_rounding_precision = 32;
-               break;
+               return 32;
 
        case ROUND_DOUBLE:
-               floatx80_rounding_precision = 64;
-               break;
+               return 64;
 
        case ROUND_EXTENDED:
-               floatx80_rounding_precision = 80;
-               break;
+               return 80;
 
        default:
-               floatx80_rounding_precision = 80;
+               return 80;
        }
 #endif
+       return 80;
 }
 
 void nwfpe_init_fpa(union fp_state *fp)
@@ -103,8 +97,6 @@
 #endif
        memset(fpa11, 0, sizeof(FPA11));
        resetFPA11();
-       SetRoundingMode(ROUND_TO_NEAREST);
-       SetRoundingPrecision(ROUND_EXTENDED);
        fpa11->initflag = 1;
 }
 
diff -urN linux/arch/arm/nwfpe/fpa11.h linux/arch/arm/nwfpe/fpa11.h
--- linux/arch/arm/nwfpe/fpa11.h        2005/08/01 18:23:38     1.10
+++ linux/arch/arm/nwfpe/fpa11.h        2005/08/08 12:30:25     1.11
@@ -37,6 +37,13 @@
 /* includes */
 #include "fpsr.h"              /* FP control and status register definitions */
 #include "milieu.h"
+
+struct roundingData {
+    int8 mode;
+    int8 precision;
+    signed char exception;
+};
+
 #include "softfloat.h"
 
 #define                typeNone                0x00
@@ -84,8 +91,8 @@
                                   initialised. */
 } FPA11;
 
-extern void SetRoundingMode(const unsigned int);
-extern void SetRoundingPrecision(const unsigned int);
+extern int8 SetRoundingMode(const unsigned int);
+extern int8 SetRoundingPrecision(const unsigned int);
 extern void nwfpe_init_fpa(union fp_state *fp);
 
 #endif
diff -urN linux/arch/arm/nwfpe/fpa11_cpdo.c linux/arch/arm/nwfpe/fpa11_cpdo.c
--- linux/arch/arm/nwfpe/fpa11_cpdo.c   2003/09/30 14:27:17     1.8
+++ linux/arch/arm/nwfpe/fpa11_cpdo.c   2005/08/08 12:30:25     1.9
@@ -24,15 +24,16 @@
 #include "fpa11.h"
 #include "fpopcode.h"
 
-unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd);
-unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd);
-unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd);
+unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int 
opcode, FPREG * rFd);
+unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int 
opcode, FPREG * rFd);
+unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int 
opcode, FPREG * rFd);
 
 unsigned int EmulateCPDO(const unsigned int opcode)
 {
        FPA11 *fpa11 = GET_FPA11();
        FPREG *rFd;
        unsigned int nType, nDest, nRc;
+       struct roundingData roundData;
 
        /* Get the destination size.  If not valid let Linux perform
           an invalid instruction trap. */
@@ -40,7 +41,9 @@
        if (typeNone == nDest)
                return 0;
 
-       SetRoundingMode(opcode);
+       roundData.mode = SetRoundingMode(opcode);
+       roundData.precision = SetRoundingPrecision(opcode);
+       roundData.exception = 0;
 
        /* Compare the size of the operands in Fn and Fm.
           Choose the largest size and perform operations in that size,
@@ -63,14 +66,14 @@
 
        switch (nType) {
        case typeSingle:
-               nRc = SingleCPDO(opcode, rFd);
+               nRc = SingleCPDO(&roundData, opcode, rFd);
                break;
        case typeDouble:
-               nRc = DoubleCPDO(opcode, rFd);
+               nRc = DoubleCPDO(&roundData, opcode, rFd);
                break;
 #ifdef CONFIG_FPE_NWFPE_XP
        case typeExtended:
-               nRc = ExtendedCPDO(opcode, rFd);
+               nRc = ExtendedCPDO(&roundData, opcode, rFd);
                break;
 #endif
        default:
@@ -93,9 +96,9 @@
                        case typeSingle:
                                {
                                        if (typeDouble == nType)
-                                               rFd->fSingle = 
float64_to_float32(rFd->fDouble);
+                                               rFd->fSingle = 
float64_to_float32(&roundData, rFd->fDouble);
                                        else
-                                               rFd->fSingle = 
floatx80_to_float32(rFd->fExtended);
+                                               rFd->fSingle = 
floatx80_to_float32(&roundData, rFd->fExtended);
                                }
                                break;
 
@@ -104,7 +107,7 @@
                                        if (typeSingle == nType)
                                                rFd->fDouble = 
float32_to_float64(rFd->fSingle);
                                        else
-                                               rFd->fDouble = 
floatx80_to_float64(rFd->fExtended);
+                                               rFd->fDouble = 
floatx80_to_float64(&roundData, rFd->fExtended);
                                }
                                break;
 
@@ -121,12 +124,15 @@
 #else
                if (nDest != nType) {
                        if (nDest == typeSingle)
-                               rFd->fSingle = float64_to_float32(rFd->fDouble);
+                               rFd->fSingle = float64_to_float32(&roundData, 
rFd->fDouble);
                        else
                                rFd->fDouble = float32_to_float64(rFd->fSingle);
                }
 #endif
        }
 
+       if (roundData.exception)
+               float_raise(roundData.exception);
+
        return nRc;
 }
diff -urN linux/arch/arm/nwfpe/fpa11_cpdt.c linux/arch/arm/nwfpe/fpa11_cpdt.c
--- linux/arch/arm/nwfpe/fpa11_cpdt.c   2004/09/19 12:30:02     1.11
+++ linux/arch/arm/nwfpe/fpa11_cpdt.c   2005/08/08 12:30:25     1.12
@@ -96,7 +96,7 @@
        }
 }
 
-static inline void storeSingle(const unsigned int Fn, unsigned int __user 
*pMem)
+static inline void storeSingle(struct roundingData *roundData, const unsigned 
int Fn, unsigned int __user *pMem)
 {
        FPA11 *fpa11 = GET_FPA11();
        union {
@@ -106,12 +106,12 @@
 
        switch (fpa11->fType[Fn]) {
        case typeDouble:
-               val.f = float64_to_float32(fpa11->fpreg[Fn].fDouble);
+               val.f = float64_to_float32(roundData, fpa11->fpreg[Fn].fDouble);
                break;
 
 #ifdef CONFIG_FPE_NWFPE_XP
        case typeExtended:
-               val.f = floatx80_to_float32(fpa11->fpreg[Fn].fExtended);
+               val.f = floatx80_to_float32(roundData, 
fpa11->fpreg[Fn].fExtended);
                break;
 #endif
 
@@ -122,7 +122,7 @@
        put_user(val.i[0], pMem);
 }
 
-static inline void storeDouble(const unsigned int Fn, unsigned int __user 
*pMem)
+static inline void storeDouble(struct roundingData *roundData, const unsigned 
int Fn, unsigned int __user *pMem)
 {
        FPA11 *fpa11 = GET_FPA11();
        union {
@@ -137,7 +137,7 @@
 
 #ifdef CONFIG_FPE_NWFPE_XP
        case typeExtended:
-               val.f = floatx80_to_float64(fpa11->fpreg[Fn].fExtended);
+               val.f = floatx80_to_float64(roundData, 
fpa11->fpreg[Fn].fExtended);
                break;
 #endif
 
@@ -259,8 +259,11 @@
 {
        unsigned int __user *pBase, *pAddress, *pFinal;
        unsigned int nRc = 1, write_back = WRITE_BACK(opcode);
+       struct roundingData roundData;
 
-       SetRoundingMode(ROUND_TO_NEAREST);
+       roundData.mode = SetRoundingMode(opcode);
+       roundData.precision = SetRoundingPrecision(opcode);
+       roundData.exception = 0;
 
        pBase = (unsigned int __user *) readRegister(getRn(opcode));
        if (REG_PC == getRn(opcode)) {
@@ -281,10 +284,10 @@
 
        switch (opcode & MASK_TRANSFER_LENGTH) {
        case TRANSFER_SINGLE:
-               storeSingle(getFd(opcode), pAddress);
+               storeSingle(&roundData, getFd(opcode), pAddress);
                break;
        case TRANSFER_DOUBLE:
-               storeDouble(getFd(opcode), pAddress);
+               storeDouble(&roundData, getFd(opcode), pAddress);
                break;
 #ifdef CONFIG_FPE_NWFPE_XP
        case TRANSFER_EXTENDED:
@@ -295,6 +298,9 @@
                nRc = 0;
        }
 
+       if (roundData.exception)
+               float_raise(roundData.exception);
+
        if (write_back)
                writeRegister(getRn(opcode), (unsigned long) pFinal);
        return nRc;
diff -urN linux/arch/arm/nwfpe/fpa11_cprt.c linux/arch/arm/nwfpe/fpa11_cprt.c
--- linux/arch/arm/nwfpe/fpa11_cprt.c   2003/09/30 14:27:17     1.9
+++ linux/arch/arm/nwfpe/fpa11_cprt.c   2005/08/08 12:30:25     1.10
@@ -33,8 +33,6 @@
 extern flag float64_is_nan(float64);
 extern flag float32_is_nan(float32);
 
-void SetRoundingMode(const unsigned int opcode);
-
 unsigned int PerformFLT(const unsigned int opcode);
 unsigned int PerformFIX(const unsigned int opcode);
 
@@ -77,14 +75,17 @@
 unsigned int PerformFLT(const unsigned int opcode)
 {
        FPA11 *fpa11 = GET_FPA11();
-       SetRoundingMode(opcode);
-       SetRoundingPrecision(opcode);
+       struct roundingData roundData;
+
+       roundData.mode = SetRoundingMode(opcode);
+       roundData.precision = SetRoundingPrecision(opcode);
+       roundData.exception = 0;
 
        switch (opcode & MASK_ROUNDING_PRECISION) {
        case ROUND_SINGLE:
                {
                        fpa11->fType[getFn(opcode)] = typeSingle;
-                       fpa11->fpreg[getFn(opcode)].fSingle = 
int32_to_float32(readRegister(getRd(opcode)));
+                       fpa11->fpreg[getFn(opcode)].fSingle = 
int32_to_float32(&roundData, readRegister(getRd(opcode)));
                }
                break;
 
@@ -108,6 +109,9 @@
                return 0;
        }
 
+       if (roundData.exception)
+               float_raise(roundData.exception);
+
        return 1;
 }
 
@@ -115,26 +119,29 @@
 {
        FPA11 *fpa11 = GET_FPA11();
        unsigned int Fn = getFm(opcode);
+       struct roundingData roundData;
 
-       SetRoundingMode(opcode);
+       roundData.mode = SetRoundingMode(opcode);
+       roundData.precision = SetRoundingPrecision(opcode);
+       roundData.exception = 0;
 
        switch (fpa11->fType[Fn]) {
        case typeSingle:
                {
-                       writeRegister(getRd(opcode), 
float32_to_int32(fpa11->fpreg[Fn].fSingle));
+                       writeRegister(getRd(opcode), 
float32_to_int32(&roundData, fpa11->fpreg[Fn].fSingle));
                }
                break;
 
        case typeDouble:
                {
-                       writeRegister(getRd(opcode), 
float64_to_int32(fpa11->fpreg[Fn].fDouble));
+                       writeRegister(getRd(opcode), 
float64_to_int32(&roundData, fpa11->fpreg[Fn].fDouble));
                }
                break;
 
 #ifdef CONFIG_FPE_NWFPE_XP
        case typeExtended:
                {
-                       writeRegister(getRd(opcode), 
floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
+                       writeRegister(getRd(opcode), 
floatx80_to_int32(&roundData, fpa11->fpreg[Fn].fExtended));
                }
                break;
 #endif
@@ -143,6 +150,9 @@
                return 0;
        }
 
+       if (roundData.exception)
+               float_raise(roundData.exception);
+
        return 1;
 }
 
diff -urN linux/arch/arm/nwfpe/fpmodule.c linux/arch/arm/nwfpe/fpmodule.c
--- linux/arch/arm/nwfpe/fpmodule.c     2005/08/01 18:23:38     1.15
+++ linux/arch/arm/nwfpe/fpmodule.c     2005/08/08 12:30:25     1.16
@@ -116,8 +116,6 @@
 code to access data in user space in some other source files at the 
 moment (grep for get_user / put_user calls).  --philb]
 
-float_exception_flags is a global variable in SoftFloat.
-
 This function is called by the SoftFloat routines to raise a floating
 point exception.  We check the trap enable byte in the FPSR, and raise
 a SIGFPE exception if necessary.  If not the relevant bits in the 
@@ -129,15 +127,14 @@
        register unsigned int fpsr, cumulativeTraps;
 
 #ifdef CONFIG_DEBUG_USER
-       printk(KERN_DEBUG
-              "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n",
-              current->comm, current->pid, flags,
-              __builtin_return_address(0), GET_USERREG()->ARM_pc);
+       /* Ignore inexact errors as there are far too many of them to log */
+       if (flags & ~BIT_IXC)
+               printk(KERN_DEBUG
+                      "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n",
+                      current->comm, current->pid, flags,
+                      __builtin_return_address(0), GET_USERREG()->ARM_pc);
 #endif
 
-       /* Keep SoftFloat exception flags up to date.  */
-       float_exception_flags |= flags;
-
        /* Read fpsr and initialize the cumulativeTraps.  */
        fpsr = readFPSR();
        cumulativeTraps = 0;
diff -urN linux/arch/arm/nwfpe/single_cpdo.c linux/arch/arm/nwfpe/single_cpdo.c
--- linux/arch/arm/nwfpe/single_cpdo.c  2003/06/05 14:43:25     1.7
+++ linux/arch/arm/nwfpe/single_cpdo.c  2005/08/08 12:30:25     1.8
@@ -36,17 +36,17 @@
 float32 float32_pow(float32 rFn, float32 rFm);
 float32 float32_pol(float32 rFn, float32 rFm);
 
-static float32 float32_rsf(float32 rFn, float32 rFm)
+static float32 float32_rsf(struct roundingData *roundData, float32 rFn, 
float32 rFm)
 {
-       return float32_sub(rFm, rFn);
+       return float32_sub(roundData, rFm, rFn);
 }
 
-static float32 float32_rdv(float32 rFn, float32 rFm)
+static float32 float32_rdv(struct roundingData *roundData, float32 rFn, 
float32 rFm)
 {
-       return float32_div(rFm, rFn);
+       return float32_div(roundData, rFm, rFn);
 }
 
-static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = {
+static float32 (*const dyadic_single[16])(struct roundingData *, float32 rFn, 
float32 rFm) = {
        [ADF_CODE >> 20] = float32_add,
        [MUF_CODE >> 20] = float32_mul,
        [SUF_CODE >> 20] = float32_sub,
@@ -60,22 +60,22 @@
        [FRD_CODE >> 20] = float32_rdv,
 };
 
-static float32 float32_mvf(float32 rFm)
+static float32 float32_mvf(struct roundingData *roundData, float32 rFm)
 {
        return rFm;
 }
 
-static float32 float32_mnf(float32 rFm)
+static float32 float32_mnf(struct roundingData *roundData, float32 rFm)
 {
        return rFm ^ 0x80000000;
 }
 
-static float32 float32_abs(float32 rFm)
+static float32 float32_abs(struct roundingData *roundData, float32 rFm)
 {
        return rFm & 0x7fffffff;
 }
 
-static float32 (*const monadic_single[16])(float32 rFm) = {
+static float32 (*const monadic_single[16])(struct roundingData*, float32 rFm) 
= {
        [MVF_CODE >> 20] = float32_mvf,
        [MNF_CODE >> 20] = float32_mnf,
        [ABS_CODE >> 20] = float32_abs,
@@ -85,7 +85,7 @@
        [NRM_CODE >> 20] = float32_mvf,
 };
 
-unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd)
+unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int 
opcode, FPREG * rFd)
 {
        FPA11 *fpa11 = GET_FPA11();
        float32 rFm;
@@ -108,13 +108,13 @@
                if (fpa11->fType[Fn] == typeSingle &&
                    dyadic_single[opc_mask_shift]) {
                        rFn = fpa11->fpreg[Fn].fSingle;
-                       rFd->fSingle = dyadic_single[opc_mask_shift](rFn, rFm);
+                       rFd->fSingle = dyadic_single[opc_mask_shift](roundData, 
rFn, rFm);
                } else {
                        return 0;
                }
        } else {
                if (monadic_single[opc_mask_shift]) {
-                       rFd->fSingle = monadic_single[opc_mask_shift](rFm);
+                       rFd->fSingle = 
monadic_single[opc_mask_shift](roundData, rFm);
                } else {
                        return 0;
                }
diff -urN linux/arch/arm/nwfpe/softfloat.c linux/arch/arm/nwfpe/softfloat.c
--- linux/arch/arm/nwfpe/softfloat.c    2005/07/11 20:46:04     1.6
+++ linux/arch/arm/nwfpe/softfloat.c    2005/08/08 12:30:25     1.7
@@ -36,16 +36,6 @@
 
 /*
 -------------------------------------------------------------------------------
-Floating-point rounding mode, extended double-precision rounding precision,
-and exception flags.
--------------------------------------------------------------------------------
-*/
-int8 float_rounding_mode = float_round_nearest_even;
-int8 floatx80_rounding_precision = 80;
-int8 float_exception_flags;
-
-/*
--------------------------------------------------------------------------------
 Primitive arithmetic functions, including multi-word arithmetic, and
 division and square root approximations.  (Can be specialized to target if
 desired.)
@@ -77,14 +67,14 @@
 positive or negative integer is returned.
 -------------------------------------------------------------------------------
 */
-static int32 roundAndPackInt32( flag zSign, bits64 absZ )
+static int32 roundAndPackInt32( struct roundingData *roundData, flag zSign, 
bits64 absZ )
 {
     int8 roundingMode;
     flag roundNearestEven;
     int8 roundIncrement, roundBits;
     int32 z;
 
-    roundingMode = float_rounding_mode;
+    roundingMode = roundData->mode;
     roundNearestEven = ( roundingMode == float_round_nearest_even );
     roundIncrement = 0x40;
     if ( ! roundNearestEven ) {
@@ -107,10 +97,10 @@
     z = absZ;
     if ( zSign ) z = - z;
     if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
-        float_exception_flags |= float_flag_invalid;
+        roundData->exception |= float_flag_invalid;
         return zSign ? 0x80000000 : 0x7FFFFFFF;
     }
-    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    if ( roundBits ) roundData->exception |= float_flag_inexact;
     return z;
 
 }
@@ -224,14 +214,14 @@
 Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
+static float32 roundAndPackFloat32( struct roundingData *roundData, flag 
zSign, int16 zExp, bits32 zSig )
 {
     int8 roundingMode;
     flag roundNearestEven;
     int8 roundIncrement, roundBits;
     flag isTiny;
 
-    roundingMode = float_rounding_mode;
+    roundingMode = roundData->mode;
     roundNearestEven = ( roundingMode == float_round_nearest_even );
     roundIncrement = 0x40;
     if ( ! roundNearestEven ) {
@@ -254,7 +244,7 @@
              || (    ( zExp == 0xFD )
                   && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
            ) {
-            float_raise( float_flag_overflow | float_flag_inexact );
+            roundData->exception |= float_flag_overflow | float_flag_inexact;
             return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
         }
         if ( zExp < 0 ) {
@@ -265,10 +255,10 @@
             shift32RightJamming( zSig, - zExp, &zSig );
             zExp = 0;
             roundBits = zSig & 0x7F;
-            if ( isTiny && roundBits ) float_raise( float_flag_underflow );
+            if ( isTiny && roundBits ) roundData->exception |= 
float_flag_underflow;
         }
     }
-    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    if ( roundBits ) roundData->exception |= float_flag_inexact;
     zSig = ( zSig + roundIncrement )>>7;
     zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
     if ( zSig == 0 ) zExp = 0;
@@ -287,12 +277,12 @@
 -------------------------------------------------------------------------------
 */
 static float32
- normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
+ normalizeRoundAndPackFloat32( struct roundingData *roundData, flag zSign, 
int16 zExp, bits32 zSig )
 {
     int8 shiftCount;
 
     shiftCount = countLeadingZeros32( zSig ) - 1;
-    return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount );
+    return roundAndPackFloat32( roundData, zSign, zExp - shiftCount, 
zSig<<shiftCount );
 
 }
 
@@ -395,14 +385,14 @@
 Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
+static float64 roundAndPackFloat64( struct roundingData *roundData, flag 
zSign, int16 zExp, bits64 zSig )
 {
     int8 roundingMode;
     flag roundNearestEven;
     int16 roundIncrement, roundBits;
     flag isTiny;
 
-    roundingMode = float_rounding_mode;
+    roundingMode = roundData->mode;
     roundNearestEven = ( roundingMode == float_round_nearest_even );
     roundIncrement = 0x200;
     if ( ! roundNearestEven ) {
@@ -427,7 +417,7 @@
            ) {
             //register int lr = __builtin_return_address(0);
             //printk("roundAndPackFloat64 called from 0x%08x\n",lr);
-            float_raise( float_flag_overflow | float_flag_inexact );
+            roundData->exception |= float_flag_overflow | float_flag_inexact;
             return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
         }
         if ( zExp < 0 ) {
@@ -438,10 +428,10 @@
             shift64RightJamming( zSig, - zExp, &zSig );
             zExp = 0;
             roundBits = zSig & 0x3FF;
-            if ( isTiny && roundBits ) float_raise( float_flag_underflow );
+            if ( isTiny && roundBits ) roundData->exception |= 
float_flag_underflow;
         }
     }
-    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    if ( roundBits ) roundData->exception |= float_flag_inexact;
     zSig = ( zSig + roundIncrement )>>10;
     zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
     if ( zSig == 0 ) zExp = 0;
@@ -460,12 +450,12 @@
 -------------------------------------------------------------------------------
 */
 static float64
- normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
+ normalizeRoundAndPackFloat64( struct roundingData *roundData, flag zSign, 
int16 zExp, bits64 zSig )
 {
     int8 shiftCount;
 
     shiftCount = countLeadingZeros64( zSig ) - 1;
-    return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount );
+    return roundAndPackFloat64( roundData, zSign, zExp - shiftCount, 
zSig<<shiftCount );
 
 }
 
@@ -572,14 +562,15 @@
 */
 static floatx80
  roundAndPackFloatx80(
-     int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
+     struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, 
bits64 zSig1
  )
 {
-    int8 roundingMode;
+    int8 roundingMode, roundingPrecision;
     flag roundNearestEven, increment, isTiny;
     int64 roundIncrement, roundMask, roundBits;
 
-    roundingMode = float_rounding_mode;
+    roundingMode = roundData->mode;
+    roundingPrecision = roundData->precision;
     roundNearestEven = ( roundingMode == float_round_nearest_even );
     if ( roundingPrecision == 80 ) goto precision80;
     if ( roundingPrecision == 64 ) {
@@ -623,8 +614,8 @@
             shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
             zExp = 0;
             roundBits = zSig0 & roundMask;
-            if ( isTiny && roundBits ) float_raise( float_flag_underflow );
-            if ( roundBits ) float_exception_flags |= float_flag_inexact;
+            if ( isTiny && roundBits ) roundData->exception |= 
float_flag_underflow;
+            if ( roundBits ) roundData->exception |= float_flag_inexact;
             zSig0 += roundIncrement;
             if ( (sbits64) zSig0 < 0 ) zExp = 1;
             roundIncrement = roundMask + 1;
@@ -635,7 +626,7 @@
             return packFloatx80( zSign, zExp, zSig0 );
         }
     }
-    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    if ( roundBits ) roundData->exception |= float_flag_inexact;
     zSig0 += roundIncrement;
     if ( zSig0 < roundIncrement ) {
         ++zExp;
@@ -672,7 +663,7 @@
            ) {
             roundMask = 0;
  overflow:
-            float_raise( float_flag_overflow | float_flag_inexact );
+            roundData->exception |= float_flag_overflow | float_flag_inexact;
             if (    ( roundingMode == float_round_to_zero )
                  || ( zSign && ( roundingMode == float_round_up ) )
                  || ( ! zSign && ( roundingMode == float_round_down ) )
@@ -689,8 +680,8 @@
                 || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
             shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
             zExp = 0;
-            if ( isTiny && zSig1 ) float_raise( float_flag_underflow );
-            if ( zSig1 ) float_exception_flags |= float_flag_inexact;
+            if ( isTiny && zSig1 ) roundData->exception |= 
float_flag_underflow;
+            if ( zSig1 ) roundData->exception |= float_flag_inexact;
             if ( roundNearestEven ) {
                 increment = ( (sbits64) zSig1 < 0 );
             }
@@ -710,7 +701,7 @@
             return packFloatx80( zSign, zExp, zSig0 );
         }
     }
-    if ( zSig1 ) float_exception_flags |= float_flag_inexact;
+    if ( zSig1 ) roundData->exception |= float_flag_inexact;
     if ( increment ) {
         ++zSig0;
         if ( zSig0 == 0 ) {
@@ -740,7 +731,7 @@
 */
 static floatx80
  normalizeRoundAndPackFloatx80(
-     int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
+     struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, 
bits64 zSig1
  )
 {
     int8 shiftCount;
@@ -754,7 +745,7 @@
     shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
     zExp -= shiftCount;
     return
-        roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 );
+        roundAndPackFloatx80( roundData, zSign, zExp, zSig0, zSig1 );
 
 }
 
@@ -767,14 +758,14 @@
 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 int32_to_float32( int32 a )
+float32 int32_to_float32(struct roundingData *roundData, int32 a)
 {
     flag zSign;
 
     if ( a == 0 ) return 0;
     if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
     zSign = ( a < 0 );
-    return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a );
+    return normalizeRoundAndPackFloat32( roundData, zSign, 0x9C, zSign ? - a : 
a );
 
 }
 
@@ -840,7 +831,7 @@
 largest integer with the same sign as `a' is returned.
 -------------------------------------------------------------------------------
 */
-int32 float32_to_int32( float32 a )
+int32 float32_to_int32( struct roundingData *roundData, float32 a )
 {
     flag aSign;
     int16 aExp, shiftCount;
@@ -856,7 +847,7 @@
     zSig = aSig;
     zSig <<= 32;
     if ( 0 < shiftCount ) shift64RightJamming( zSig, shiftCount, &zSig );
-    return roundAndPackInt32( aSign, zSig );
+    return roundAndPackInt32( roundData, aSign, zSig );
 
 }
 
@@ -889,13 +880,13 @@
         return 0x80000000;
     }
     else if ( aExp <= 0x7E ) {
-        if ( aExp | aSig ) float_exception_flags |= float_flag_inexact;
+        if ( aExp | aSig ) float_raise( float_flag_inexact );
         return 0;
     }
     aSig = ( aSig | 0x00800000 )<<8;
     z = aSig>>( - shiftCount );
     if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
-        float_exception_flags |= float_flag_inexact;
+        float_raise( float_flag_inexact );
     }
     return aSign ? - z : z;
 
@@ -973,7 +964,7 @@
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_round_to_int( float32 a )
+float32 float32_round_to_int( struct roundingData *roundData, float32 a )
 {
     flag aSign;
     int16 aExp;
@@ -988,11 +979,12 @@
         }
         return a;
     }
+    roundingMode = roundData->mode;
     if ( aExp <= 0x7E ) {
         if ( (bits32) ( a<<1 ) == 0 ) return a;
-        float_exception_flags |= float_flag_inexact;
+        roundData->exception |= float_flag_inexact;
         aSign = extractFloat32Sign( a );
-        switch ( float_rounding_mode ) {
+        switch ( roundingMode ) {
          case float_round_nearest_even:
             if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
                 return packFloat32( aSign, 0x7F, 0 );
@@ -1009,7 +1001,6 @@
     lastBitMask <<= 0x96 - aExp;
     roundBitsMask = lastBitMask - 1;
     z = a;
-    roundingMode = float_rounding_mode;
     if ( roundingMode == float_round_nearest_even ) {
         z += lastBitMask>>1;
         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
@@ -1020,7 +1011,7 @@
         }
     }
     z &= ~ roundBitsMask;
-    if ( z != a ) float_exception_flags |= float_flag_inexact;
+    if ( z != a ) roundData->exception |= float_flag_inexact;
     return z;
 
 }
@@ -1034,7 +1025,7 @@
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
+static float32 addFloat32Sigs( struct roundingData *roundData, float32 a, 
float32 b, flag zSign )
 {
     int16 aExp, bExp, zExp;
     bits32 aSig, bSig, zSig;
@@ -1093,7 +1084,7 @@
         ++zExp;
     }
  roundAndPack:
-    return roundAndPackFloat32( zSign, zExp, zSig );
+    return roundAndPackFloat32( roundData, zSign, zExp, zSig );
 
 }
 
@@ -1106,7 +1097,7 @@
 Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
+static float32 subFloat32Sigs( struct roundingData *roundData, float32 a, 
float32 b, flag zSign )
 {
     int16 aExp, bExp, zExp;
     bits32 aSig, bSig, zSig;
@@ -1123,7 +1114,7 @@
     if ( expDiff < 0 ) goto bExpBigger;
     if ( aExp == 0xFF ) {
         if ( aSig | bSig ) return propagateFloat32NaN( a, b );
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float32_default_nan;
     }
     if ( aExp == 0 ) {
@@ -1132,7 +1123,7 @@
     }
     if ( bSig < aSig ) goto aBigger;
     if ( aSig < bSig ) goto bBigger;
-    return packFloat32( float_rounding_mode == float_round_down, 0, 0 );
+    return packFloat32( roundData->mode == float_round_down, 0, 0 );
  bExpBigger:
     if ( bExp == 0xFF ) {
         if ( bSig ) return propagateFloat32NaN( a, b );
@@ -1169,7 +1160,7 @@
     zExp = aExp;
  normalizeRoundAndPack:
     --zExp;
-    return normalizeRoundAndPackFloat32( zSign, zExp, zSig );
+    return normalizeRoundAndPackFloat32( roundData, zSign, zExp, zSig );
 
 }
 
@@ -1180,17 +1171,17 @@
 Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_add( float32 a, float32 b )
+float32 float32_add( struct roundingData *roundData, float32 a, float32 b )
 {
     flag aSign, bSign;
 
     aSign = extractFloat32Sign( a );
     bSign = extractFloat32Sign( b );
     if ( aSign == bSign ) {
-        return addFloat32Sigs( a, b, aSign );
+        return addFloat32Sigs( roundData, a, b, aSign );
     }
     else {
-        return subFloat32Sigs( a, b, aSign );
+        return subFloat32Sigs( roundData, a, b, aSign );
     }
 
 }
@@ -1202,17 +1193,17 @@
 for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_sub( float32 a, float32 b )
+float32 float32_sub( struct roundingData *roundData, float32 a, float32 b )
 {
     flag aSign, bSign;
 
     aSign = extractFloat32Sign( a );
     bSign = extractFloat32Sign( b );
     if ( aSign == bSign ) {
-        return subFloat32Sigs( a, b, aSign );
+        return subFloat32Sigs( roundData, a, b, aSign );
     }
     else {
-        return addFloat32Sigs( a, b, aSign );
+        return addFloat32Sigs( roundData, a, b, aSign );
     }
 
 }
@@ -1224,7 +1215,7 @@
 for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_mul( float32 a, float32 b )
+float32 float32_mul( struct roundingData *roundData, float32 a, float32 b )
 {
     flag aSign, bSign, zSign;
     int16 aExp, bExp, zExp;
@@ -1244,7 +1235,7 @@
             return propagateFloat32NaN( a, b );
         }
         if ( ( bExp | bSig ) == 0 ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float32_default_nan;
         }
         return packFloat32( zSign, 0xFF, 0 );
@@ -1252,7 +1243,7 @@
     if ( bExp == 0xFF ) {
         if ( bSig ) return propagateFloat32NaN( a, b );
         if ( ( aExp | aSig ) == 0 ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float32_default_nan;
         }
         return packFloat32( zSign, 0xFF, 0 );
@@ -1274,7 +1265,7 @@
         zSig <<= 1;
         --zExp;
     }
-    return roundAndPackFloat32( zSign, zExp, zSig );
+    return roundAndPackFloat32( roundData, zSign, zExp, zSig );
 
 }
 
@@ -1285,7 +1276,7 @@
 IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_div( float32 a, float32 b )
+float32 float32_div( struct roundingData *roundData, float32 a, float32 b )
 {
     flag aSign, bSign, zSign;
     int16 aExp, bExp, zExp;
@@ -1302,7 +1293,7 @@
         if ( aSig ) return propagateFloat32NaN( a, b );
         if ( bExp == 0xFF ) {
             if ( bSig ) return propagateFloat32NaN( a, b );
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float32_default_nan;
         }
         return packFloat32( zSign, 0xFF, 0 );
@@ -1314,10 +1305,10 @@
     if ( bExp == 0 ) {
         if ( bSig == 0 ) {
             if ( ( aExp | aSig ) == 0 ) {
-                float_raise( float_flag_invalid );
+                roundData->exception |= float_flag_invalid;
                 return float32_default_nan;
             }
-            float_raise( float_flag_divbyzero );
+            roundData->exception |= float_flag_divbyzero;
             return packFloat32( zSign, 0xFF, 0 );
         }
         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
@@ -1341,7 +1332,7 @@
     if ( ( zSig & 0x3F ) == 0 ) {
         zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 );
     }
-    return roundAndPackFloat32( zSign, zExp, zSig );
+    return roundAndPackFloat32( roundData, zSign, zExp, zSig );
 
 }
 
@@ -1352,7 +1343,7 @@
 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_rem( float32 a, float32 b )
+float32 float32_rem( struct roundingData *roundData, float32 a, float32 b )
 {
     flag aSign, bSign, zSign;
     int16 aExp, bExp, expDiff;
@@ -1372,7 +1363,7 @@
         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
             return propagateFloat32NaN( a, b );
         }
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float32_default_nan;
     }
     if ( bExp == 0xFF ) {
@@ -1381,7 +1372,7 @@
     }
     if ( bExp == 0 ) {
         if ( bSig == 0 ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float32_default_nan;
         }
         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
@@ -1444,7 +1435,7 @@
     }
     zSign = ( (sbits32) aSig < 0 );
     if ( zSign ) aSig = - aSig;
-    return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig );
+    return normalizeRoundAndPackFloat32( roundData, aSign ^ zSign, bExp, aSig 
);
 
 }
 
@@ -1455,7 +1446,7 @@
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_sqrt( float32 a )
+float32 float32_sqrt( struct roundingData *roundData, float32 a )
 {
     flag aSign;
     int16 aExp, zExp;
@@ -1468,12 +1459,12 @@
     if ( aExp == 0xFF ) {
         if ( aSig ) return propagateFloat32NaN( a, 0 );
         if ( ! aSign ) return a;
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float32_default_nan;
     }
     if ( aSign ) {
         if ( ( aExp | aSig ) == 0 ) return a;
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float32_default_nan;
     }
     if ( aExp == 0 ) {
@@ -1499,7 +1490,7 @@
         }
     }
     shift32RightJamming( zSig, 1, &zSig );
-    return roundAndPackFloat32( 0, zExp, zSig );
+    return roundAndPackFloat32( roundData, 0, zExp, zSig );
 
 }
 
@@ -1661,7 +1652,7 @@
 largest integer with the same sign as `a' is returned.
 -------------------------------------------------------------------------------
 */
-int32 float64_to_int32( float64 a )
+int32 float64_to_int32( struct roundingData *roundData, float64 a )
 {
     flag aSign;
     int16 aExp, shiftCount;
@@ -1674,7 +1665,7 @@
     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
     shiftCount = 0x42C - aExp;
     if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
-    return roundAndPackInt32( aSign, aSig );
+    return roundAndPackInt32( roundData, aSign, aSig );
 
 }
 
@@ -1705,7 +1696,7 @@
         goto invalid;
     }
     else if ( 52 < shiftCount ) {
-        if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
+        if ( aExp || aSig ) float_raise( float_flag_inexact );
         return 0;
     }
     aSig |= LIT64( 0x0010000000000000 );
@@ -1715,11 +1706,11 @@
     if ( aSign ) z = - z;
     if ( ( z < 0 ) ^ aSign ) {
  invalid:
-        float_exception_flags |= float_flag_invalid;
+        float_raise( float_flag_invalid );
         return aSign ? 0x80000000 : 0x7FFFFFFF;
     }
     if ( ( aSig<<shiftCount ) != savedASig ) {
-        float_exception_flags |= float_flag_inexact;
+        float_raise( float_flag_inexact );
     }
     return z;
 
@@ -1736,7 +1727,7 @@
 largest positive integer is returned.
 -------------------------------------------------------------------------------
 */
-int32 float64_to_uint32( float64 a )
+int32 float64_to_uint32( struct roundingData *roundData, float64 a )
 {
     flag aSign;
     int16 aExp, shiftCount;
@@ -1749,7 +1740,7 @@
     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
     shiftCount = 0x42C - aExp;
     if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
-    return roundAndPackInt32( aSign, aSig );
+    return roundAndPackInt32( roundData, aSign, aSig );
 }
 
 /*
@@ -1778,7 +1769,7 @@
         goto invalid;
     }
     else if ( 52 < shiftCount ) {
-        if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
+        if ( aExp || aSig ) float_raise( float_flag_inexact );
         return 0;
     }
     aSig |= LIT64( 0x0010000000000000 );
@@ -1788,11 +1779,11 @@
     if ( aSign ) z = - z;
     if ( ( z < 0 ) ^ aSign ) {
  invalid:
-        float_exception_flags |= float_flag_invalid;
+        float_raise( float_flag_invalid );
         return aSign ? 0x80000000 : 0x7FFFFFFF;
     }
     if ( ( aSig<<shiftCount ) != savedASig ) {
-        float_exception_flags |= float_flag_inexact;
+        float_raise( float_flag_inexact );
     }
     return z;
 }
@@ -1805,7 +1796,7 @@
 Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float64_to_float32( float64 a )
+float32 float64_to_float32( struct roundingData *roundData, float64 a )
 {
     flag aSign;
     int16 aExp;
@@ -1825,7 +1816,7 @@
         zSig |= 0x40000000;
         aExp -= 0x381;
     }
-    return roundAndPackFloat32( aSign, aExp, zSig );
+    return roundAndPackFloat32( roundData, aSign, aExp, zSig );
 
 }
 
@@ -1872,7 +1863,7 @@
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_round_to_int( float64 a )
+float64 float64_round_to_int( struct roundingData *roundData, float64 a )
 {
     flag aSign;
     int16 aExp;
@@ -1889,9 +1880,9 @@
     }
     if ( aExp <= 0x3FE ) {
         if ( (bits64) ( a<<1 ) == 0 ) return a;
-        float_exception_flags |= float_flag_inexact;
+        roundData->exception |= float_flag_inexact;
         aSign = extractFloat64Sign( a );
-        switch ( float_rounding_mode ) {
+        switch ( roundData->mode ) {
          case float_round_nearest_even:
             if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
                 return packFloat64( aSign, 0x3FF, 0 );
@@ -1909,7 +1900,7 @@
     lastBitMask <<= 0x433 - aExp;
     roundBitsMask = lastBitMask - 1;
     z = a;
-    roundingMode = float_rounding_mode;
+    roundingMode = roundData->mode;
     if ( roundingMode == float_round_nearest_even ) {
         z += lastBitMask>>1;
         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
@@ -1920,7 +1911,7 @@
         }
     }
     z &= ~ roundBitsMask;
-    if ( z != a ) float_exception_flags |= float_flag_inexact;
+    if ( z != a ) roundData->exception |= float_flag_inexact;
     return z;
 
 }
@@ -1934,7 +1925,7 @@
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static float64 addFloat64Sigs( float64 a, float64 b, flag zSign )
+static float64 addFloat64Sigs( struct roundingData *roundData, float64 a, 
float64 b, flag zSign )
 {
     int16 aExp, bExp, zExp;
     bits64 aSig, bSig, zSig;
@@ -1993,7 +1984,7 @@
         ++zExp;
     }
  roundAndPack:
-    return roundAndPackFloat64( zSign, zExp, zSig );
+    return roundAndPackFloat64( roundData, zSign, zExp, zSig );
 
 }
 
@@ -2006,7 +1997,7 @@
 Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
+static float64 subFloat64Sigs( struct roundingData *roundData, float64 a, 
float64 b, flag zSign )
 {
     int16 aExp, bExp, zExp;
     bits64 aSig, bSig, zSig;
@@ -2023,7 +2014,7 @@
     if ( expDiff < 0 ) goto bExpBigger;
     if ( aExp == 0x7FF ) {
         if ( aSig | bSig ) return propagateFloat64NaN( a, b );
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float64_default_nan;
     }
     if ( aExp == 0 ) {
@@ -2032,7 +2023,7 @@
     }
     if ( bSig < aSig ) goto aBigger;
     if ( aSig < bSig ) goto bBigger;
-    return packFloat64( float_rounding_mode == float_round_down, 0, 0 );
+    return packFloat64( roundData->mode == float_round_down, 0, 0 );
  bExpBigger:
     if ( bExp == 0x7FF ) {
         if ( bSig ) return propagateFloat64NaN( a, b );
@@ -2069,7 +2060,7 @@
     zExp = aExp;
  normalizeRoundAndPack:
     --zExp;
-    return normalizeRoundAndPackFloat64( zSign, zExp, zSig );
+    return normalizeRoundAndPackFloat64( roundData, zSign, zExp, zSig );
 
 }
 
@@ -2080,17 +2071,17 @@
 Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_add( float64 a, float64 b )
+float64 float64_add( struct roundingData *roundData, float64 a, float64 b )
 {
     flag aSign, bSign;
 
     aSign = extractFloat64Sign( a );
     bSign = extractFloat64Sign( b );
     if ( aSign == bSign ) {
-        return addFloat64Sigs( a, b, aSign );
+        return addFloat64Sigs( roundData, a, b, aSign );
     }
     else {
-        return subFloat64Sigs( a, b, aSign );
+        return subFloat64Sigs( roundData, a, b, aSign );
     }
 
 }
@@ -2102,17 +2093,17 @@
 for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_sub( float64 a, float64 b )
+float64 float64_sub( struct roundingData *roundData, float64 a, float64 b )
 {
     flag aSign, bSign;
 
     aSign = extractFloat64Sign( a );
     bSign = extractFloat64Sign( b );
     if ( aSign == bSign ) {
-        return subFloat64Sigs( a, b, aSign );
+        return subFloat64Sigs( roundData, a, b, aSign );
     }
     else {
-        return addFloat64Sigs( a, b, aSign );
+        return addFloat64Sigs( roundData, a, b, aSign );
     }
 
 }
@@ -2124,7 +2115,7 @@
 for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_mul( float64 a, float64 b )
+float64 float64_mul( struct roundingData *roundData, float64 a, float64 b )
 {
     flag aSign, bSign, zSign;
     int16 aExp, bExp, zExp;
@@ -2142,7 +2133,7 @@
             return propagateFloat64NaN( a, b );
         }
         if ( ( bExp | bSig ) == 0 ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float64_default_nan;
         }
         return packFloat64( zSign, 0x7FF, 0 );
@@ -2150,7 +2141,7 @@
     if ( bExp == 0x7FF ) {
         if ( bSig ) return propagateFloat64NaN( a, b );
         if ( ( aExp | aSig ) == 0 ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float64_default_nan;
         }
         return packFloat64( zSign, 0x7FF, 0 );
@@ -2172,7 +2163,7 @@
         zSig0 <<= 1;
         --zExp;
     }
-    return roundAndPackFloat64( zSign, zExp, zSig0 );
+    return roundAndPackFloat64( roundData, zSign, zExp, zSig0 );
 
 }
 
@@ -2183,7 +2174,7 @@
 the IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_div( float64 a, float64 b )
+float64 float64_div( struct roundingData *roundData, float64 a, float64 b )
 {
     flag aSign, bSign, zSign;
     int16 aExp, bExp, zExp;
@@ -2202,7 +2193,7 @@
         if ( aSig ) return propagateFloat64NaN( a, b );
         if ( bExp == 0x7FF ) {
             if ( bSig ) return propagateFloat64NaN( a, b );
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float64_default_nan;
         }
         return packFloat64( zSign, 0x7FF, 0 );
@@ -2214,10 +2205,10 @@
     if ( bExp == 0 ) {
         if ( bSig == 0 ) {
             if ( ( aExp | aSig ) == 0 ) {
-                float_raise( float_flag_invalid );
+                roundData->exception |= float_flag_invalid;
                 return float64_default_nan;
             }
-            float_raise( float_flag_divbyzero );
+            roundData->exception |= float_flag_divbyzero;
             return packFloat64( zSign, 0x7FF, 0 );
         }
         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
@@ -2243,7 +2234,7 @@
         }
         zSig |= ( rem1 != 0 );
     }
-    return roundAndPackFloat64( zSign, zExp, zSig );
+    return roundAndPackFloat64( roundData, zSign, zExp, zSig );
 
 }
 
@@ -2254,7 +2245,7 @@
 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_rem( float64 a, float64 b )
+float64 float64_rem( struct roundingData *roundData, float64 a, float64 b )
 {
     flag aSign, bSign, zSign;
     int16 aExp, bExp, expDiff;
@@ -2272,7 +2263,7 @@
         if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
             return propagateFloat64NaN( a, b );
         }
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float64_default_nan;
     }
     if ( bExp == 0x7FF ) {
@@ -2281,7 +2272,7 @@
     }
     if ( bExp == 0 ) {
         if ( bSig == 0 ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float64_default_nan;
         }
         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
@@ -2329,7 +2320,7 @@
     }
     zSign = ( (sbits64) aSig < 0 );
     if ( zSign ) aSig = - aSig;
-    return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig );
+    return normalizeRoundAndPackFloat64( roundData, aSign ^ zSign, bExp, aSig 
);
 
 }
 
@@ -2340,7 +2331,7 @@
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_sqrt( float64 a )
+float64 float64_sqrt( struct roundingData *roundData, float64 a )
 {
     flag aSign;
     int16 aExp, zExp;
@@ -2354,12 +2345,12 @@
     if ( aExp == 0x7FF ) {
         if ( aSig ) return propagateFloat64NaN( a, a );
         if ( ! aSign ) return a;
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float64_default_nan;
     }
     if ( aSign ) {
         if ( ( aExp | aSig ) == 0 ) return a;
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float64_default_nan;
     }
     if ( aExp == 0 ) {
@@ -2390,7 +2381,7 @@
         }
     }
     shift64RightJamming( zSig, 1, &zSig );
-    return roundAndPackFloat64( 0, zExp, zSig );
+    return roundAndPackFloat64( roundData, 0, zExp, zSig );
 
 }
 
@@ -2554,7 +2545,7 @@
 overflows, the largest integer with the same sign as `a' is returned.
 -------------------------------------------------------------------------------
 */
-int32 floatx80_to_int32( floatx80 a )
+int32 floatx80_to_int32( struct roundingData *roundData, floatx80 a )
 {
     flag aSign;
     int32 aExp, shiftCount;
@@ -2567,7 +2558,7 @@
     shiftCount = 0x4037 - aExp;
     if ( shiftCount <= 0 ) shiftCount = 1;
     shift64RightJamming( aSig, shiftCount, &aSig );
-    return roundAndPackInt32( aSign, aSig );
+    return roundAndPackInt32( roundData, aSign, aSig );
 
 }
 
@@ -2598,7 +2589,7 @@
         goto invalid;
     }
     else if ( 63 < shiftCount ) {
-        if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
+        if ( aExp || aSig ) float_raise( float_flag_inexact );
         return 0;
     }
     savedASig = aSig;
@@ -2607,11 +2598,11 @@
     if ( aSign ) z = - z;
     if ( ( z < 0 ) ^ aSign ) {
  invalid:
-        float_exception_flags |= float_flag_invalid;
+        float_raise( float_flag_invalid );
         return aSign ? 0x80000000 : 0x7FFFFFFF;
     }
     if ( ( aSig<<shiftCount ) != savedASig ) {
-        float_exception_flags |= float_flag_inexact;
+        float_raise( float_flag_inexact );
     }
     return z;
 
@@ -2625,7 +2616,7 @@
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 floatx80_to_float32( floatx80 a )
+float32 floatx80_to_float32( struct roundingData *roundData, floatx80 a )
 {
     flag aSign;
     int32 aExp;
@@ -2642,7 +2633,7 @@
     }
     shift64RightJamming( aSig, 33, &aSig );
     if ( aExp || aSig ) aExp -= 0x3F81;
-    return roundAndPackFloat32( aSign, aExp, aSig );
+    return roundAndPackFloat32( roundData, aSign, aExp, aSig );
 
 }
 
@@ -2654,7 +2645,7 @@
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 floatx80_to_float64( floatx80 a )
+float64 floatx80_to_float64( struct roundingData *roundData, floatx80 a )
 {
     flag aSign;
     int32 aExp;
@@ -2671,7 +2662,7 @@
     }
     shift64RightJamming( aSig, 1, &zSig );
     if ( aExp || aSig ) aExp -= 0x3C01;
-    return roundAndPackFloat64( aSign, aExp, zSig );
+    return roundAndPackFloat64( roundData, aSign, aExp, zSig );
 
 }
 
@@ -2683,7 +2674,7 @@
 Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_round_to_int( floatx80 a )
+floatx80 floatx80_round_to_int( struct roundingData *roundData, floatx80 a )
 {
     flag aSign;
     int32 aExp;
@@ -2703,9 +2694,9 @@
              && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
             return a;
         }
-        float_exception_flags |= float_flag_inexact;
+        roundData->exception |= float_flag_inexact;
         aSign = extractFloatx80Sign( a );
-        switch ( float_rounding_mode ) {
+        switch ( roundData->mode ) {
          case float_round_nearest_even:
             if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
                ) {
@@ -2729,7 +2720,7 @@
     lastBitMask <<= 0x403E - aExp;
     roundBitsMask = lastBitMask - 1;
     z = a;
-    roundingMode = float_rounding_mode;
+    roundingMode = roundData->mode;
     if ( roundingMode == float_round_nearest_even ) {
         z.low += lastBitMask>>1;
         if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
@@ -2744,7 +2735,7 @@
         ++z.high;
         z.low = LIT64( 0x8000000000000000 );
     }
-    if ( z.low != a.low ) float_exception_flags |= float_flag_inexact;
+    if ( z.low != a.low ) roundData->exception |= float_flag_inexact;
     return z;
 
 }
@@ -2758,7 +2749,7 @@
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
+static floatx80 addFloatx80Sigs( struct roundingData *roundData, floatx80 a, 
floatx80 b, flag zSign )
 {
     int32 aExp, bExp, zExp;
     bits64 aSig, bSig, zSig0, zSig1;
@@ -2814,7 +2805,7 @@
  roundAndPack:
     return
         roundAndPackFloatx80(
-            floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+            roundData, zSign, zExp, zSig0, zSig1 );
 
 }
 
@@ -2827,7 +2818,7 @@
 Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
+static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, 
floatx80 b, flag zSign )
 {
     int32 aExp, bExp, zExp;
     bits64 aSig, bSig, zSig0, zSig1;
@@ -2845,7 +2836,7 @@
         if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
             return propagateFloatx80NaN( a, b );
         }
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         z.low = floatx80_default_nan_low;
         z.high = floatx80_default_nan_high;
         return z;
@@ -2857,7 +2848,7 @@
     zSig1 = 0;
     if ( bSig < aSig ) goto aBigger;
     if ( aSig < bSig ) goto bBigger;
-    return packFloatx80( float_rounding_mode == float_round_down, 0, 0 );
+    return packFloatx80( roundData->mode == float_round_down, 0, 0 );
  bExpBigger:
     if ( bExp == 0x7FFF ) {
         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
@@ -2883,7 +2874,7 @@
  normalizeRoundAndPack:
     return
         normalizeRoundAndPackFloatx80(
-            floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+            roundData, zSign, zExp, zSig0, zSig1 );
 
 }
 
@@ -2894,17 +2885,17 @@
 Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_add( floatx80 a, floatx80 b )
+floatx80 floatx80_add( struct roundingData *roundData, floatx80 a, floatx80 b )
 {
     flag aSign, bSign;
     
     aSign = extractFloatx80Sign( a );
     bSign = extractFloatx80Sign( b );
     if ( aSign == bSign ) {
-        return addFloatx80Sigs( a, b, aSign );
+        return addFloatx80Sigs( roundData, a, b, aSign );
     }
     else {
-        return subFloatx80Sigs( a, b, aSign );
+        return subFloatx80Sigs( roundData, a, b, aSign );
     }
     
 }
@@ -2916,17 +2907,17 @@
 IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_sub( floatx80 a, floatx80 b )
+floatx80 floatx80_sub( struct roundingData *roundData, floatx80 a, floatx80 b )
 {
     flag aSign, bSign;
 
     aSign = extractFloatx80Sign( a );
     bSign = extractFloatx80Sign( b );
     if ( aSign == bSign ) {
-        return subFloatx80Sigs( a, b, aSign );
+        return subFloatx80Sigs( roundData, a, b, aSign );
     }
     else {
-        return addFloatx80Sigs( a, b, aSign );
+        return addFloatx80Sigs( roundData, a, b, aSign );
     }
 
 }
@@ -2938,7 +2929,7 @@
 IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_mul( floatx80 a, floatx80 b )
+floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b )
 {
     flag aSign, bSign, zSign;
     int32 aExp, bExp, zExp;
@@ -2964,7 +2955,7 @@
         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
         if ( ( aExp | aSig ) == 0 ) {
  invalid:
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             z.low = floatx80_default_nan_low;
             z.high = floatx80_default_nan_high;
             return z;
@@ -2987,7 +2978,7 @@
     }
     return
         roundAndPackFloatx80(
-            floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+            roundData, zSign, zExp, zSig0, zSig1 );
 
 }
 
@@ -2998,7 +2989,7 @@
 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_div( floatx80 a, floatx80 b )
+floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b )
 {
     flag aSign, bSign, zSign;
     int32 aExp, bExp, zExp;
@@ -3029,12 +3020,12 @@
         if ( bSig == 0 ) {
             if ( ( aExp | aSig ) == 0 ) {
  invalid:
-                float_raise( float_flag_invalid );
+                roundData->exception |= float_flag_invalid;
                 z.low = floatx80_default_nan_low;
                 z.high = floatx80_default_nan_high;
                 return z;
             }
-            float_raise( float_flag_divbyzero );
+            roundData->exception |= float_flag_divbyzero;
             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
         }
         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
@@ -3068,7 +3059,7 @@
     }
     return
         roundAndPackFloatx80(
-            floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+            roundData, zSign, zExp, zSig0, zSig1 );
 
 }
 
@@ -3079,7 +3070,7 @@
 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_rem( floatx80 a, floatx80 b )
+floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b )
 {
     flag aSign, bSign, zSign;
     int32 aExp, bExp, expDiff;
@@ -3107,7 +3098,7 @@
     if ( bExp == 0 ) {
         if ( bSig == 0 ) {
  invalid:
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             z.low = floatx80_default_nan_low;
             z.high = floatx80_default_nan_high;
             return z;
@@ -3164,9 +3155,10 @@
         aSig1 = alternateASig1;
         zSign = ! zSign;
     }
+
     return
         normalizeRoundAndPackFloatx80(
-            80, zSign, bExp + expDiff, aSig0, aSig1 );
+            roundData, zSign, bExp + expDiff, aSig0, aSig1 );
 
 }
 
@@ -3177,7 +3169,7 @@
 for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_sqrt( floatx80 a )
+floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a )
 {
     flag aSign;
     int32 aExp, zExp;
@@ -3197,7 +3189,7 @@
     if ( aSign ) {
         if ( ( aExp | aSig0 ) == 0 ) return a;
  invalid:
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         z.low = floatx80_default_nan_low;
         z.high = floatx80_default_nan_high;
         return z;
@@ -3242,7 +3234,7 @@
     }
     return
         roundAndPackFloatx80(
-            floatx80_rounding_precision, 0, zExp, zSig0, zSig1 );
+            roundData, 0, zExp, zSig0, zSig1 );
 
 }
 
@@ -3264,7 +3256,7 @@
        ) {
         if (    floatx80_is_signaling_nan( a )
              || floatx80_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
         }
         return 0;
     }
@@ -3294,7 +3286,7 @@
          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
        ) {
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return 0;
     }
     aSign = extractFloatx80Sign( a );
@@ -3328,7 +3320,7 @@
          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
        ) {
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return 0;
     }
     aSign = extractFloatx80Sign( a );
@@ -3361,7 +3353,7 @@
          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
        ) {
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return 0;
     }
     return
@@ -3392,7 +3384,7 @@
        ) {
         if (    floatx80_is_signaling_nan( a )
              || floatx80_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
         }
         return 0;
     }
@@ -3429,7 +3421,7 @@
        ) {
         if (    floatx80_is_signaling_nan( a )
              || floatx80_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
         }
         return 0;
     }
diff -urN linux/arch/arm/nwfpe/softfloat.h linux/arch/arm/nwfpe/softfloat.h
--- linux/arch/arm/nwfpe/softfloat.h    2003/09/30 14:27:17     1.4
+++ linux/arch/arm/nwfpe/softfloat.h    2005/08/08 12:30:25     1.5
@@ -74,7 +74,7 @@
 Software IEC/IEEE floating-point rounding mode.
 -------------------------------------------------------------------------------
 */
-extern signed char float_rounding_mode;
+//extern int8 float_rounding_mode;
 enum {
     float_round_nearest_even = 0,
     float_round_to_zero      = 1,
@@ -86,7 +86,6 @@
 -------------------------------------------------------------------------------
 Software IEC/IEEE floating-point exception flags.
 -------------------------------------------------------------------------------
-extern signed char float_exception_flags;
 enum {
     float_flag_inexact   =  1,
     float_flag_underflow =  2,
@@ -99,7 +98,6 @@
 Changed the enumeration to match the bit order in the FPA11.
 */
 
-extern signed char float_exception_flags;
 enum {
     float_flag_invalid   =  1,
     float_flag_divbyzero =  2,
@@ -121,7 +119,7 @@
 Software IEC/IEEE integer-to-floating-point conversion routines.
 -------------------------------------------------------------------------------
 */
-float32 int32_to_float32( signed int );
+float32 int32_to_float32( struct roundingData *, signed int );
 float64 int32_to_float64( signed int );
 #ifdef FLOATX80
 floatx80 int32_to_floatx80( signed int );
@@ -132,7 +130,7 @@
 Software IEC/IEEE single-precision conversion routines.
 -------------------------------------------------------------------------------
 */
-signed int float32_to_int32( float32 );
+signed int float32_to_int32( struct roundingData *, float32 );
 signed int float32_to_int32_round_to_zero( float32 );
 float64 float32_to_float64( float32 );
 #ifdef FLOATX80
@@ -144,13 +142,13 @@
 Software IEC/IEEE single-precision operations.
 -------------------------------------------------------------------------------
 */
-float32 float32_round_to_int( float32 );
-float32 float32_add( float32, float32 );
-float32 float32_sub( float32, float32 );
-float32 float32_mul( float32, float32 );
-float32 float32_div( float32, float32 );
-float32 float32_rem( float32, float32 );
-float32 float32_sqrt( float32 );
+float32 float32_round_to_int( struct roundingData*, float32 );
+float32 float32_add( struct roundingData *, float32, float32 );
+float32 float32_sub( struct roundingData *, float32, float32 );
+float32 float32_mul( struct roundingData *, float32, float32 );
+float32 float32_div( struct roundingData *, float32, float32 );
+float32 float32_rem( struct roundingData *, float32, float32 );
+float32 float32_sqrt( struct roundingData*, float32 );
 char float32_eq( float32, float32 );
 char float32_le( float32, float32 );
 char float32_lt( float32, float32 );
@@ -164,9 +162,9 @@
 Software IEC/IEEE double-precision conversion routines.
 -------------------------------------------------------------------------------
 */
-signed int float64_to_int32( float64 );
+signed int float64_to_int32( struct roundingData *, float64 );
 signed int float64_to_int32_round_to_zero( float64 );
-float32 float64_to_float32( float64 );
+float32 float64_to_float32( struct roundingData *, float64 );
 #ifdef FLOATX80
 floatx80 float64_to_floatx80( float64 );
 #endif
@@ -176,13 +174,13 @@
 Software IEC/IEEE double-precision operations.
 -------------------------------------------------------------------------------
 */
-float64 float64_round_to_int( float64 );
-float64 float64_add( float64, float64 );
-float64 float64_sub( float64, float64 );
-float64 float64_mul( float64, float64 );
-float64 float64_div( float64, float64 );
-float64 float64_rem( float64, float64 );
-float64 float64_sqrt( float64 );
+float64 float64_round_to_int( struct roundingData *, float64 );
+float64 float64_add( struct roundingData *, float64, float64 );
+float64 float64_sub( struct roundingData *, float64, float64 );
+float64 float64_mul( struct roundingData *, float64, float64 );
+float64 float64_div( struct roundingData *, float64, float64 );
+float64 float64_rem( struct roundingData *, float64, float64 );
+float64 float64_sqrt( struct roundingData *, float64 );
 char float64_eq( float64, float64 );
 char float64_le( float64, float64 );
 char float64_lt( float64, float64 );
@@ -198,31 +196,23 @@
 Software IEC/IEEE extended double-precision conversion routines.
 -------------------------------------------------------------------------------
 */
-signed int floatx80_to_int32( floatx80 );
+signed int floatx80_to_int32( struct roundingData *, floatx80 );
 signed int floatx80_to_int32_round_to_zero( floatx80 );
-float32 floatx80_to_float32( floatx80 );
-float64 floatx80_to_float64( floatx80 );
-
-/*
--------------------------------------------------------------------------------
-Software IEC/IEEE extended double-precision rounding precision.  Valid
-values are 32, 64, and 80.
--------------------------------------------------------------------------------
-*/
-extern signed char floatx80_rounding_precision;
+float32 floatx80_to_float32( struct roundingData *, floatx80 );
+float64 floatx80_to_float64( struct roundingData *, floatx80 );
 
 /*
 -------------------------------------------------------------------------------
 Software IEC/IEEE extended double-precision operations.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_round_to_int( floatx80 );
-floatx80 floatx80_add( floatx80, floatx80 );
-floatx80 floatx80_sub( floatx80, floatx80 );
-floatx80 floatx80_mul( floatx80, floatx80 );
-floatx80 floatx80_div( floatx80, floatx80 );
-floatx80 floatx80_rem( floatx80, floatx80 );
-floatx80 floatx80_sqrt( floatx80 );
+floatx80 floatx80_round_to_int( struct roundingData *, floatx80 );
+floatx80 floatx80_add( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_div( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_sqrt( struct roundingData *, floatx80 );
 char floatx80_eq( floatx80, floatx80 );
 char floatx80_le( floatx80, floatx80 );
 char floatx80_lt( floatx80, floatx80 );
diff -urN linux/arch/arm/oprofile/backtrace.c 
linux/arch/arm/oprofile/backtrace.c
--- linux/arch/arm/oprofile/backtrace.c 2005/07/11 20:46:05     1.1
+++ linux/arch/arm/oprofile/backtrace.c 2005/08/08 12:30:26     1.2
@@ -115,7 +115,7 @@
        return (tailaddr > stack) && (tailaddr < stack_base);
 }
 
-void arm_backtrace(struct pt_regs const *regs, unsigned int depth)
+void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
 {
        struct frame_tail *tail;
        unsigned long last_address = 0;
diff -urN linux/arch/arm/vfp/vfpdouble.c linux/arch/arm/vfp/vfpdouble.c
--- linux/arch/arm/vfp/vfpdouble.c      2005/07/12 09:19:00     1.5
+++ linux/arch/arm/vfp/vfpdouble.c      2005/08/08 12:30:26     1.6
@@ -770,6 +770,9 @@
                if ((s64)m_sig < 0) {
                        vdd->sign = vfp_sign_negate(vdd->sign);
                        m_sig = -m_sig;
+               } else if (m_sig == 0) {
+                       vdd->sign = (fpscr & FPSCR_RMODE_MASK) ==
+                                     FPSCR_ROUND_MINUSINF ? 0x8000 : 0;
                }
        } else {
                m_sig += vdn->significand;
diff -urN linux/arch/arm26/mm/fault.c linux/arch/arm26/mm/fault.c
--- linux/arch/arm26/mm/fault.c 2005/01/13 14:05:21     1.3
+++ linux/arch/arm26/mm/fault.c 2005/08/08 12:30:26     1.4
@@ -176,12 +176,12 @@
         * Handle the "normal" cases first - successful and sigbus
         */
        switch (fault) {
-       case 2:
+       case VM_FAULT_MAJOR:
                tsk->maj_flt++;
                return fault;
-       case 1:
+       case VM_FAULT_MINOR:
                tsk->min_flt++;
-       case 0:
+       case VM_FAULT_SIGBUS:
                return fault;
        }
 
@@ -226,14 +226,11 @@
        /*
         * Handle the "normal" case first
         */
-       if (fault > 0)
+       switch (fault) {
+       case VM_FAULT_MINOR:
+       case VM_FAULT_MAJOR:
                return 0;
-
-       /*
-        * We had some memory, but were unable to
-        * successfully fix up this page fault.
-        */
-       if (fault == 0){
+       case VM_FAULT_SIGBUS:
                goto do_sigbus;
        }
 
diff -urN linux/arch/cris/mm/fault.c linux/arch/cris/mm/fault.c
--- linux/arch/cris/mm/fault.c  2005/08/01 18:23:44     1.13
+++ linux/arch/cris/mm/fault.c  2005/08/08 12:30:26     1.14
@@ -284,13 +284,13 @@
         */
 
        switch (handle_mm_fault(mm, vma, address, writeaccess & 1)) {
-       case 1:
+       case VM_FAULT_MINOR:
                tsk->min_flt++;
                break;
-       case 2:
+       case VM_FAULT_MAJOR:
                tsk->maj_flt++;
                break;
-       case 0:
+       case VM_FAULT_SIGBUS:
                goto do_sigbus;
        default:
                goto out_of_memory;
diff -urN linux/arch/frv/mm/fault.c linux/arch/frv/mm/fault.c
--- linux/arch/frv/mm/fault.c   2005/01/13 14:05:23     1.1
+++ linux/arch/frv/mm/fault.c   2005/08/08 12:30:26     1.2
@@ -163,13 +163,13 @@
         * the fault.
         */
        switch (handle_mm_fault(mm, vma, ear0, write)) {
-       case 1:
+       case VM_FAULT_MINOR:
                current->min_flt++;
                break;
-       case 2:
+       case VM_FAULT_MAJOR:
                current->maj_flt++;
                break;
-       case 0:
+       case VM_FAULT_SIGBUS:
                goto do_sigbus;
        default:
                goto out_of_memory;
diff -urN linux/arch/i386/Kconfig linux/arch/i386/Kconfig
--- linux/arch/i386/Kconfig     2005/07/13 11:48:54     1.57
+++ linux/arch/i386/Kconfig     2005/08/08 12:30:26     1.58
@@ -454,8 +454,9 @@
          Choose N to continue using the legacy 8254 timer.
 
 config HPET_EMULATE_RTC
-       bool "Provide RTC interrupt"
+       bool
        depends on HPET_TIMER && RTC=y
+       default y
 
 config SMP
        bool "Symmetric multi-processing support"
diff -urN linux/arch/i386/mach-visws/reboot.c 
linux/arch/i386/mach-visws/reboot.c
--- linux/arch/i386/mach-visws/reboot.c 2005/08/01 18:23:45     1.4
+++ linux/arch/i386/mach-visws/reboot.c 2005/08/08 12:30:26     1.5
@@ -9,12 +9,15 @@
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
-void machine_restart(char * __unused)
+void machine_shutdown(void)
 {
 #ifdef CONFIG_SMP
        smp_send_stop();
 #endif
+}
 
+void machine_emergency_restart(void)
+{
        /*
         * Visual Workstations restart after this
         * register is poked on the PIIX4
@@ -22,6 +25,12 @@
        outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT);
 }
 
+void machine_restart(char * __unused)
+{
+       machine_shutdown();
+       machine_emergency_restart();
+}
+
 void machine_power_off(void)
 {
        unsigned short pm_status;
diff -urN linux/arch/i386/mach-visws/setup.c linux/arch/i386/mach-visws/setup.c
--- linux/arch/i386/mach-visws/setup.c  2003/06/04 16:08:01     1.2
+++ linux/arch/i386/mach-visws/setup.c  2005/08/08 12:30:26     1.3
@@ -14,6 +14,8 @@
 #include "cobalt.h"
 #include "piix4.h"
 
+int no_broadcast;
+
 char visws_board_type = -1;
 char visws_board_rev = -1;
 
diff -urN linux/arch/i386/mach-voyager/voyager_basic.c 
linux/arch/i386/mach-voyager/voyager_basic.c
--- linux/arch/i386/mach-voyager/voyager_basic.c        2005/08/01 18:23:45     
1.9
+++ linux/arch/i386/mach-voyager/voyager_basic.c        2005/08/08 12:30:27     
1.10
@@ -252,6 +252,12 @@
 }
 
 void
+machine_shutdown(void)
+{
+       /* Architecture specific shutdown needed before a kexec */
+}
+
+void
 machine_restart(char *cmd)
 {
        printk("Voyager Warm Restart\n");
@@ -279,6 +285,13 @@
 }
 
 void
+machine_emergency_restart(void)
+{
+       /*for now, just hook this to a warm restart */
+       machine_restart(NULL);
+}
+
+void
 mca_nmi_hook(void)
 {
        __u8 dumpval __attribute__((unused)) = inb(0xf823);
diff -urN linux/arch/i386/mm/discontig.c linux/arch/i386/mm/discontig.c
--- linux/arch/i386/mm/discontig.c      2005/08/03 15:50:25     1.23
+++ linux/arch/i386/mm/discontig.c      2005/08/08 12:30:27     1.24
@@ -243,14 +243,6 @@
                /* now the roundup is correct, convert to PAGE_SIZE pages */
                size = size * PTRS_PER_PTE;
 
-               if (node_end_pfn[nid] & (PTRS_PER_PTE-1)) {
-                       /*
-                        * Adjust size if node_end_pfn is not on a proper
-                        * pmd boundary. remap_numa_kva will barf otherwise.
-                        */
-                       size +=  node_end_pfn[nid] & (PTRS_PER_PTE-1);
-               }
-
                /*
                 * Validate the region we are allocating only contains valid
                 * pages.
@@ -270,6 +262,17 @@
                reserve_pages += size;
                printk("Shrinking node %d from %ld pages to %ld pages\n",
                        nid, node_end_pfn[nid], node_end_pfn[nid] - size);
+
+               if (node_end_pfn[nid] & (PTRS_PER_PTE-1)) {
+                       /*
+                        * Align node_end_pfn[] and node_remap_start_pfn[] to
+                        * pmd boundary. remap_numa_kva will barf otherwise.
+                        */
+                       printk("Shrinking node %d further by %ld pages for 
proper alignment\n",
+                               nid, node_end_pfn[nid] & (PTRS_PER_PTE-1));
+                       size +=  node_end_pfn[nid] & (PTRS_PER_PTE-1);
+               }
+
                node_end_pfn[nid] -= size;
                node_remap_start_pfn[nid] = node_end_pfn[nid];
        }
diff -urN linux/arch/i386/pci/visws.c linux/arch/i386/pci/visws.c
--- linux/arch/i386/pci/visws.c 2005/07/13 11:48:56     1.8
+++ linux/arch/i386/pci/visws.c 2005/08/08 12:30:27     1.9
@@ -18,8 +18,10 @@
 extern struct pci_raw_ops pci_direct_conf1;
 
 static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; }
+static void pci_visws_disable_irq(struct pci_dev *dev) { }
 
 int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq;
+void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq;
 
 void __init pcibios_penalize_isa_irq(int irq, int active) {}
 
diff -urN linux/arch/m68k/mm/fault.c linux/arch/m68k/mm/fault.c
--- linux/arch/m68k/mm/fault.c  2004/06/06 02:12:38     1.13
+++ linux/arch/m68k/mm/fault.c  2005/08/08 12:30:27     1.14
@@ -160,13 +160,13 @@
        printk("handle_mm_fault returns %d\n",fault);
 #endif
        switch (fault) {
-       case 1:
+       case VM_FAULT_MINOR:
                current->min_flt++;
                break;
-       case 2:
+       case VM_FAULT_MAJOR:
                current->maj_flt++;
                break;
-       case 0:
+       case VM_FAULT_SIGBUS:
                goto bus_err;
        default:
                goto out_of_memory;
diff -urN linux/arch/mips/defconfig linux/arch/mips/defconfig
--- linux/arch/mips/defconfig   2005/08/05 15:04:35     1.305
+++ linux/arch/mips/defconfig   2005/08/08 12:30:27     1.306
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:09 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:28 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/atlas_defconfig 
linux/arch/mips/configs/atlas_defconfig
--- linux/arch/mips/configs/atlas_defconfig     2005/08/05 15:04:35     1.70
+++ linux/arch/mips/configs/atlas_defconfig     2005/08/08 12:30:27     1.71
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:11 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:29 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/capcella_defconfig 
linux/arch/mips/configs/capcella_defconfig
--- linux/arch/mips/configs/capcella_defconfig  2005/08/05 15:04:35     1.69
+++ linux/arch/mips/configs/capcella_defconfig  2005/08/08 12:30:27     1.70
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:14 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:30 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/cobalt_defconfig 
linux/arch/mips/configs/cobalt_defconfig
--- linux/arch/mips/configs/cobalt_defconfig    2005/08/05 15:04:35     1.66
+++ linux/arch/mips/configs/cobalt_defconfig    2005/08/08 12:30:27     1.67
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:16 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:30 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/db1000_defconfig 
linux/arch/mips/configs/db1000_defconfig
--- linux/arch/mips/configs/db1000_defconfig    2005/08/05 15:04:35     1.72
+++ linux/arch/mips/configs/db1000_defconfig    2005/08/08 12:30:27     1.73
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:18 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:31 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/db1100_defconfig 
linux/arch/mips/configs/db1100_defconfig
--- linux/arch/mips/configs/db1100_defconfig    2005/08/05 15:04:35     1.71
+++ linux/arch/mips/configs/db1100_defconfig    2005/08/08 12:30:27     1.72
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:21 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:32 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/db1500_defconfig 
linux/arch/mips/configs/db1500_defconfig
--- linux/arch/mips/configs/db1500_defconfig    2005/08/05 15:04:35     1.74
+++ linux/arch/mips/configs/db1500_defconfig    2005/08/08 12:30:27     1.75
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:24 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:33 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/db1550_defconfig 
linux/arch/mips/configs/db1550_defconfig
--- linux/arch/mips/configs/db1550_defconfig    2005/08/05 15:04:35     1.49
+++ linux/arch/mips/configs/db1550_defconfig    2005/08/08 12:30:27     1.50
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:26 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:33 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ddb5476_defconfig 
linux/arch/mips/configs/ddb5476_defconfig
--- linux/arch/mips/configs/ddb5476_defconfig   2005/08/05 15:04:35     1.66
+++ linux/arch/mips/configs/ddb5476_defconfig   2005/08/08 12:30:27     1.67
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:29 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:34 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ddb5477_defconfig 
linux/arch/mips/configs/ddb5477_defconfig
--- linux/arch/mips/configs/ddb5477_defconfig   2005/08/05 15:04:35     1.66
+++ linux/arch/mips/configs/ddb5477_defconfig   2005/08/08 12:30:27     1.67
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:31 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:35 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/decstation_defconfig 
linux/arch/mips/configs/decstation_defconfig
--- linux/arch/mips/configs/decstation_defconfig        2005/08/05 15:04:35     
1.84
+++ linux/arch/mips/configs/decstation_defconfig        2005/08/08 12:30:27     
1.85
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:33 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:36 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/e55_defconfig 
linux/arch/mips/configs/e55_defconfig
--- linux/arch/mips/configs/e55_defconfig       2005/08/05 15:04:35     1.69
+++ linux/arch/mips/configs/e55_defconfig       2005/08/08 12:30:27     1.70
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:35 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:37 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ev64120_defconfig 
linux/arch/mips/configs/ev64120_defconfig
--- linux/arch/mips/configs/ev64120_defconfig   2005/08/05 15:04:35     1.65
+++ linux/arch/mips/configs/ev64120_defconfig   2005/08/08 12:30:27     1.66
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:37 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:37 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ev96100_defconfig 
linux/arch/mips/configs/ev96100_defconfig
--- linux/arch/mips/configs/ev96100_defconfig   2005/08/05 15:04:35     1.66
+++ linux/arch/mips/configs/ev96100_defconfig   2005/08/08 12:30:27     1.67
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:40 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:38 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ip22_defconfig 
linux/arch/mips/configs/ip22_defconfig
--- linux/arch/mips/configs/ip22_defconfig      2005/08/05 15:04:35     1.76
+++ linux/arch/mips/configs/ip22_defconfig      2005/08/08 12:30:27     1.77
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:42 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:39 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ip27_defconfig 
linux/arch/mips/configs/ip27_defconfig
--- linux/arch/mips/configs/ip27_defconfig      2005/08/05 15:04:35     1.82
+++ linux/arch/mips/configs/ip27_defconfig      2005/08/08 12:30:27     1.83
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:45 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:40 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ip32_defconfig 
linux/arch/mips/configs/ip32_defconfig
--- linux/arch/mips/configs/ip32_defconfig      2005/08/05 15:04:35     1.69
+++ linux/arch/mips/configs/ip32_defconfig      2005/08/08 12:30:27     1.70
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:47 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:41 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/it8172_defconfig 
linux/arch/mips/configs/it8172_defconfig
--- linux/arch/mips/configs/it8172_defconfig    2005/08/05 15:04:35     1.65
+++ linux/arch/mips/configs/it8172_defconfig    2005/08/08 12:30:27     1.66
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:49 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:41 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ivr_defconfig 
linux/arch/mips/configs/ivr_defconfig
--- linux/arch/mips/configs/ivr_defconfig       2005/08/05 15:04:35     1.65
+++ linux/arch/mips/configs/ivr_defconfig       2005/08/08 12:30:28     1.66
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:52 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:42 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/jaguar-atx_defconfig 
linux/arch/mips/configs/jaguar-atx_defconfig
--- linux/arch/mips/configs/jaguar-atx_defconfig        2005/08/05 15:04:35     
1.70
+++ linux/arch/mips/configs/jaguar-atx_defconfig        2005/08/08 12:30:28     
1.71
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:54 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:43 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/jmr3927_defconfig 
linux/arch/mips/configs/jmr3927_defconfig
--- linux/arch/mips/configs/jmr3927_defconfig   2005/08/05 15:04:35     1.66
+++ linux/arch/mips/configs/jmr3927_defconfig   2005/08/08 12:30:28     1.67
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:56 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:44 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/lasat200_defconfig 
linux/arch/mips/configs/lasat200_defconfig
--- linux/arch/mips/configs/lasat200_defconfig  2005/08/05 15:04:35     1.66
+++ linux/arch/mips/configs/lasat200_defconfig  2005/08/08 12:30:28     1.67
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:02:58 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:45 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/malta_defconfig 
linux/arch/mips/configs/malta_defconfig
--- linux/arch/mips/configs/malta_defconfig     2005/08/05 15:04:35     1.70
+++ linux/arch/mips/configs/malta_defconfig     2005/08/08 12:30:28     1.71
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:01 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:45 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/mpc30x_defconfig 
linux/arch/mips/configs/mpc30x_defconfig
--- linux/arch/mips/configs/mpc30x_defconfig    2005/08/05 15:04:35     1.70
+++ linux/arch/mips/configs/mpc30x_defconfig    2005/08/08 12:30:28     1.71
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:04 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:46 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ocelot_3_defconfig 
linux/arch/mips/configs/ocelot_3_defconfig
--- linux/arch/mips/configs/ocelot_3_defconfig  2005/08/05 15:04:35     1.38
+++ linux/arch/mips/configs/ocelot_3_defconfig  2005/08/08 12:30:28     1.39
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:06 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:47 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ocelot_c_defconfig 
linux/arch/mips/configs/ocelot_c_defconfig
--- linux/arch/mips/configs/ocelot_c_defconfig  2005/08/05 15:04:35     1.64
+++ linux/arch/mips/configs/ocelot_c_defconfig  2005/08/08 12:30:28     1.65
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:08 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:48 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ocelot_defconfig 
linux/arch/mips/configs/ocelot_defconfig
--- linux/arch/mips/configs/ocelot_defconfig    2005/08/05 15:04:35     1.66
+++ linux/arch/mips/configs/ocelot_defconfig    2005/08/08 12:30:28     1.67
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:10 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:48 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/ocelot_g_defconfig 
linux/arch/mips/configs/ocelot_g_defconfig
--- linux/arch/mips/configs/ocelot_g_defconfig  2005/08/05 15:04:35     1.59
+++ linux/arch/mips/configs/ocelot_g_defconfig  2005/08/08 12:30:28     1.60
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:13 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:49 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/pb1100_defconfig 
linux/arch/mips/configs/pb1100_defconfig
--- linux/arch/mips/configs/pb1100_defconfig    2005/08/05 15:04:35     1.68
+++ linux/arch/mips/configs/pb1100_defconfig    2005/08/08 12:30:28     1.69
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:16 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:50 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/pb1500_defconfig 
linux/arch/mips/configs/pb1500_defconfig
--- linux/arch/mips/configs/pb1500_defconfig    2005/08/05 15:04:35     1.74
+++ linux/arch/mips/configs/pb1500_defconfig    2005/08/08 12:30:28     1.75
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:18 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:51 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/pb1550_defconfig 
linux/arch/mips/configs/pb1550_defconfig
--- linux/arch/mips/configs/pb1550_defconfig    2005/08/05 15:04:36     1.64
+++ linux/arch/mips/configs/pb1550_defconfig    2005/08/08 12:30:28     1.65
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:21 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:52 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/pnx8550-jbs_defconfig 
linux/arch/mips/configs/pnx8550-jbs_defconfig
--- linux/arch/mips/configs/pnx8550-jbs_defconfig       2005/08/05 15:04:36     
1.7
+++ linux/arch/mips/configs/pnx8550-jbs_defconfig       2005/08/08 12:30:28     
1.8
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:23 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:52 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/pnx8550-v2pci_defconfig 
linux/arch/mips/configs/pnx8550-v2pci_defconfig
--- linux/arch/mips/configs/pnx8550-v2pci_defconfig     2005/08/05 15:04:36     
1.6
+++ linux/arch/mips/configs/pnx8550-v2pci_defconfig     2005/08/08 12:30:28     
1.7
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:26 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:53 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/qemu_defconfig 
linux/arch/mips/configs/qemu_defconfig
--- linux/arch/mips/configs/qemu_defconfig      2005/08/05 15:04:36     1.11
+++ linux/arch/mips/configs/qemu_defconfig      2005/08/08 12:30:28     1.12
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:28 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:54 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/rbhma4500_defconfig 
linux/arch/mips/configs/rbhma4500_defconfig
--- linux/arch/mips/configs/rbhma4500_defconfig 2005/08/05 15:04:36     1.5
+++ linux/arch/mips/configs/rbhma4500_defconfig 2005/08/08 12:30:28     1.6
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:31 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:55 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/rm200_defconfig 
linux/arch/mips/configs/rm200_defconfig
--- linux/arch/mips/configs/rm200_defconfig     2005/08/05 15:04:36     1.76
+++ linux/arch/mips/configs/rm200_defconfig     2005/08/08 12:30:28     1.77
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:35 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:56 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/sb1250-swarm_defconfig 
linux/arch/mips/configs/sb1250-swarm_defconfig
--- linux/arch/mips/configs/sb1250-swarm_defconfig      2005/08/05 15:04:36     
1.73
+++ linux/arch/mips/configs/sb1250-swarm_defconfig      2005/08/08 12:30:28     
1.74
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:37 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:56 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/sead_defconfig 
linux/arch/mips/configs/sead_defconfig
--- linux/arch/mips/configs/sead_defconfig      2005/08/05 15:04:36     1.65
+++ linux/arch/mips/configs/sead_defconfig      2005/08/08 12:30:28     1.66
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:39 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:57 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/tb0226_defconfig 
linux/arch/mips/configs/tb0226_defconfig
--- linux/arch/mips/configs/tb0226_defconfig    2005/08/05 15:04:36     1.68
+++ linux/arch/mips/configs/tb0226_defconfig    2005/08/08 12:30:28     1.69
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:41 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:58 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/tb0229_defconfig 
linux/arch/mips/configs/tb0229_defconfig
--- linux/arch/mips/configs/tb0229_defconfig    2005/08/05 15:04:36     1.71
+++ linux/arch/mips/configs/tb0229_defconfig    2005/08/08 12:30:28     1.72
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:44 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:59 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/workpad_defconfig 
linux/arch/mips/configs/workpad_defconfig
--- linux/arch/mips/configs/workpad_defconfig   2005/08/05 15:04:36     1.69
+++ linux/arch/mips/configs/workpad_defconfig   2005/08/08 12:30:28     1.70
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:46 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:49:59 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/mips/configs/yosemite_defconfig 
linux/arch/mips/configs/yosemite_defconfig
--- linux/arch/mips/configs/yosemite_defconfig  2005/08/05 15:04:36     1.70
+++ linux/arch/mips/configs/yosemite_defconfig  2005/08/08 12:30:28     1.71
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 16:03:49 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 11:50:00 2005
 #
 CONFIG_MIPS=y
 
diff -urN linux/arch/parisc/mm/fault.c linux/arch/parisc/mm/fault.c
--- linux/arch/parisc/mm/fault.c        2005/03/18 17:36:55     1.6
+++ linux/arch/parisc/mm/fault.c        2005/08/08 12:30:29     1.7
@@ -178,17 +178,17 @@
         */
 
        switch (handle_mm_fault(mm, vma, address, (acc_type & VM_WRITE) != 0)) {
-             case 1:
+             case VM_FAULT_MINOR:
                ++current->min_flt;
                break;
-             case 2:
+             case VM_FAULT_MAJOR:
                ++current->maj_flt;
                break;
-             case 0:
+             case VM_FAULT_SIGBUS:
                /*
-                * We ran out of memory, or some other thing happened
-                * to us that made us unable to handle the page fault
-                * gracefully.
+                * We hit a hared mapping outside of the file, or some
+                * other thing happened to us that made us unable to
+                * handle the page fault gracefully.
                 */
                goto bad_area;
              default:
diff -urN linux/arch/ppc/8xx_io/Kconfig linux/arch/ppc/8xx_io/Kconfig
--- linux/arch/ppc/8xx_io/Kconfig       2005/01/25 04:28:01     1.4
+++ linux/arch/ppc/8xx_io/Kconfig       2005/08/08 12:30:29     1.5
@@ -69,9 +69,9 @@
        
 config ENET_BIG_BUFFERS
        bool "Use Big CPM Ethernet Buffers"
-       depends on NET_ETHERNET
+       depends on SCC_ENET || FEC_ENET
        help
-         Allocate large buffers for MPC8xx Etherenet.  Increases throughput
+         Allocate large buffers for MPC8xx Ethernet. Increases throughput
          and decreases the likelihood of dropped packets, but costs memory.
 
 config HTDMSOUND
diff -urN linux/arch/ppc/8xx_io/commproc.c linux/arch/ppc/8xx_io/commproc.c
--- linux/arch/ppc/8xx_io/commproc.c    2004/11/15 11:49:19     1.19
+++ linux/arch/ppc/8xx_io/commproc.c    2005/08/08 12:30:29     1.20
@@ -39,8 +39,6 @@
 #include <asm/tlbflush.h>
 #include <asm/rheap.h>
 
-extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep);
-
 static void m8xx_cpm_dpinit(void);
 static uint    host_buffer;    /* One page of host buffer */
 static uint    host_end;       /* end + 1 */
@@ -108,14 +106,11 @@
        .end            = cpm_eoi,
 };
 
-extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
-
 void
-m8xx_cpm_reset(uint bootpage)
+m8xx_cpm_reset(void)
 {
        volatile immap_t         *imp;
        volatile cpm8xx_t       *commproc;
-       pte_t *pte;
 
        imp = (immap_t *)IMAP_ADDR;
        commproc = (cpm8xx_t *)&imp->im_cpm;
@@ -143,17 +138,6 @@
        /* Reclaim the DP memory for our use. */
        m8xx_cpm_dpinit();
 
-       /* get the PTE for the bootpage */
-       if (!get_pteptr(&init_mm, bootpage, &pte))
-              panic("get_pteptr failed\n");
-                                                                               
                                                                                
                        
-       /* and make it uncachable */
-       pte_val(*pte) |= _PAGE_NO_CACHE;
-       _tlbie(bootpage);
-
-       host_buffer = bootpage;
-       host_end = host_buffer + PAGE_SIZE;
-
        /* Tell everyone where the comm processor resides.
        */
        cpmp = (cpm8xx_t *)commproc;
@@ -384,8 +368,6 @@
 
 void m8xx_cpm_dpinit(void)
 {
-       cpm8xx_t *cp = &((immap_t *)IMAP_ADDR)->im_cpm;
-
        spin_lock_init(&cpm_dpmem_lock);
 
        /* Initialize the info header */
diff -urN linux/arch/ppc/8xx_io/fec.c linux/arch/ppc/8xx_io/fec.c
--- linux/arch/ppc/8xx_io/fec.c 2005/03/18 17:36:55     1.24
+++ linux/arch/ppc/8xx_io/fec.c 2005/08/08 12:30:29     1.25
@@ -173,7 +173,7 @@
        uint    phy_status;
        uint    phy_speed;
        phy_info_t      *phy;
-       struct tq_struct phy_task;
+       struct work_struct phy_task;
 
        uint    sequence_done;
 
@@ -199,7 +199,8 @@
 #ifdef CONFIG_USE_MDIO
 static void fec_enet_mii(struct net_device *dev);
 #endif /* CONFIG_USE_MDIO */
-static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs);
+static irqreturn_t fec_enet_interrupt(int irq, void * dev_id,
+                                                       struct pt_regs * regs);
 #ifdef CONFIG_FEC_PACKETHOOK
 static void  fec_enet_tx(struct net_device *dev, __u32 regval);
 static void  fec_enet_rx(struct net_device *dev, __u32 regval);
@@ -471,7 +472,7 @@
 /* The interrupt handler.
  * This is called from the MPC core interrupt.
  */
-static void
+static irqreturn_t
 fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
 {
        struct  net_device *dev = dev_id;
@@ -525,6 +526,7 @@
                }
 
        }
+       return IRQ_RETVAL(IRQ_HANDLED);
 }
 
 
@@ -1263,8 +1265,9 @@
        printk(".\n");
 }
 
-static void mii_display_config(struct net_device *dev)
+static void mii_display_config(void *priv)
 {
+       struct net_device *dev = (struct net_device *)priv;
        struct fec_enet_private *fep = dev->priv;
        volatile uint *s = &(fep->phy_status);
 
@@ -1294,8 +1297,9 @@
        fep->sequence_done = 1;
 }
 
-static void mii_relink(struct net_device *dev)
+static void mii_relink(void *priv)
 {
+       struct net_device *dev = (struct net_device *)priv;
        struct fec_enet_private *fep = dev->priv;
        int duplex;
 
@@ -1323,18 +1327,16 @@
 {
        struct fec_enet_private *fep = dev->priv;
 
-       fep->phy_task.routine = (void *)mii_relink;
-       fep->phy_task.data = dev;
-       schedule_task(&fep->phy_task);
+       INIT_WORK(&fep->phy_task, mii_relink, (void *)dev);
+       schedule_work(&fep->phy_task);
 }
 
 static void mii_queue_config(uint mii_reg, struct net_device *dev)
 {
        struct fec_enet_private *fep = dev->priv;
 
-       fep->phy_task.routine = (void *)mii_display_config;
-       fep->phy_task.data = dev;
-       schedule_task(&fep->phy_task);
+       INIT_WORK(&fep->phy_task, mii_display_config, (void *)dev);
+       schedule_work(&fep->phy_task);
 }
 
 
@@ -1403,11 +1405,11 @@
 
 /* This interrupt occurs when the PHY detects a link change.
 */
-static void
+static
 #ifdef CONFIG_RPXCLASSIC
-mii_link_interrupt(void *dev_id)
+void mii_link_interrupt(void *dev_id)
 #else
-mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+irqreturn_t mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
 #endif
 {
 #ifdef CONFIG_USE_MDIO
@@ -1440,6 +1442,9 @@
 printk("%s[%d] %s: unexpected Link interrupt\n", 
__FILE__,__LINE__,__FUNCTION__);
 #endif /* CONFIG_USE_MDIO */
 
+#ifndef CONFIG_RPXCLASSIC
+       return IRQ_RETVAL(IRQ_HANDLED);
+#endif /* CONFIG_RPXCLASSIC */
 }
 
 static int
@@ -1575,7 +1580,7 @@
        struct fec_enet_private *fep;
        int i, j, k, err;
        unsigned char   *eap, *iap, *ba;
-       unsigned long   mem_addr;
+       dma_addr_t      mem_addr;
        volatile        cbd_t   *bdp;
        cbd_t           *cbd_base;
        volatile        immap_t *immap;
@@ -1640,7 +1645,8 @@
                printk("FEC initialization failed.\n");
                return 1;
        }
-       cbd_base = (cbd_t *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
+       cbd_base = (cbd_t *)dma_alloc_coherent(dev->class_dev.dev, PAGE_SIZE,
+                                              &mem_addr, GFP_KERNEL);
 
        /* Set receive and transmit descriptor base.
        */
@@ -1657,7 +1663,10 @@
 
                /* Allocate a page.
                */
-               ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, 
&mem_addr);
+               ba = (unsigned char *)dma_alloc_coherent(dev->class_dev.dev,
+                                                        PAGE_SIZE,
+                                                        &mem_addr,
+                                                        GFP_KERNEL);
                /* BUG: no check for failure */
 
                /* Initialize the BD for every fragment in the page.
diff -urN linux/arch/ppc/kernel/pci.c linux/arch/ppc/kernel/pci.c
--- linux/arch/ppc/kernel/pci.c 2005/07/11 20:46:30     1.59
+++ linux/arch/ppc/kernel/pci.c 2005/08/08 12:30:30     1.60
@@ -160,6 +160,21 @@
 }
 EXPORT_SYMBOL(pcibios_resource_to_bus);
 
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                            struct pci_bus_region *region)
+{
+       unsigned long offset = 0;
+       struct pci_controller *hose = dev->sysdata;
+
+       if (hose && res->flags & IORESOURCE_IO)
+               offset = (unsigned long)hose->io_base_virt - isa_io_base;
+       else if (hose && res->flags & IORESOURCE_MEM)
+               offset = hose->pci_mem_offset;
+       res->start = region->start + offset;
+       res->end = region->end + offset;
+}
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+
 /*
  * We need to avoid collisions with `mirrored' VGA ports
  * and other strange ISA hardware, so we always want the
diff -urN linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c
--- linux/arch/ppc/kernel/ppc_ksyms.c   2005/07/11 20:46:30     1.77
+++ linux/arch/ppc/kernel/ppc_ksyms.c   2005/08/08 12:30:30     1.78
@@ -324,7 +324,7 @@
 
 EXPORT_SYMBOL(next_mmu_context);
 EXPORT_SYMBOL(set_context);
-EXPORT_SYMBOL(handle_mm_fault); /* For MOL */
+EXPORT_SYMBOL_GPL(__handle_mm_fault); /* For MOL */
 EXPORT_SYMBOL(disarm_decr);
 #ifdef CONFIG_PPC_STD_MMU
 extern long mol_trampoline;
diff -urN linux/arch/ppc/syslib/m8xx_setup.c linux/arch/ppc/syslib/m8xx_setup.c
--- linux/arch/ppc/syslib/m8xx_setup.c  2005/01/25 04:28:03     1.7
+++ linux/arch/ppc/syslib/m8xx_setup.c  2005/08/08 12:30:30     1.8
@@ -57,7 +57,7 @@
 extern void m8xx_ide_init(void);
 
 extern unsigned long find_available_memory(void);
-extern void m8xx_cpm_reset(uint cpm_page);
+extern void m8xx_cpm_reset();
 extern void m8xx_wdt_handler_install(bd_t *bp);
 extern void rpxfb_alloc_pages(void);
 extern void cpm_interrupt_init(void);
@@ -70,13 +70,9 @@
 void __init
 m8xx_setup_arch(void)
 {
-       int     cpm_page;
-
-       cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE);
-
        /* Reset the Communication Processor Module.
        */
-       m8xx_cpm_reset(cpm_page);
+       m8xx_cpm_reset();
 
 #ifdef CONFIG_FB_RPX
        rpxfb_alloc_pages();
diff -urN linux/arch/ppc64/boot/zlib.c linux/arch/ppc64/boot/zlib.c
--- linux/arch/ppc64/boot/zlib.c        2004/02/19 03:06:24     1.5
+++ linux/arch/ppc64/boot/zlib.c        2005/08/08 12:30:30     1.6
@@ -1307,7 +1307,7 @@
   {
     *t = (inflate_huft *)Z_NULL;
     *m = 0;
-    return Z_OK;
+    return Z_DATA_ERROR;
   }
 
 
@@ -1351,6 +1351,7 @@
     if ((j = *p++) != 0)
       v[x[j]++] = i;
   } while (++i < n);
+  n = x[g];                    /* set n to length of v */
 
 
   /* Generate the Huffman codes and for each, make the table entries */
diff -urN linux/arch/ppc64/kernel/head.S linux/arch/ppc64/kernel/head.S
--- linux/arch/ppc64/kernel/head.S      2005/08/01 18:23:54     1.45
+++ linux/arch/ppc64/kernel/head.S      2005/08/08 12:30:30     1.46
@@ -2071,7 +2071,7 @@
        blr
 #endif
 
-#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)
+#if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && 
!defined(CONFIG_PPC_ISERIES))
 _GLOBAL(smp_release_cpus)
        /* All secondary cpus are spinning on a common
         * spinloop, release them all now so they can start
diff -urN linux/arch/ppc64/kernel/machine_kexec.c 
linux/arch/ppc64/kernel/machine_kexec.c
--- linux/arch/ppc64/kernel/machine_kexec.c     2005/07/11 20:46:34     1.1
+++ linux/arch/ppc64/kernel/machine_kexec.c     2005/08/08 12:30:30     1.2
@@ -185,7 +185,7 @@
 void kexec_smp_down(void *arg)
 {
        if (ppc_md.cpu_irq_down)
-               ppc_md.cpu_irq_down();
+               ppc_md.cpu_irq_down(1);
 
        local_irq_disable();
        kexec_smp_wait();
@@ -232,7 +232,7 @@
 
        /* after we tell the others to go down */
        if (ppc_md.cpu_irq_down)
-               ppc_md.cpu_irq_down();
+               ppc_md.cpu_irq_down(0);
 
        put_cpu();
 
@@ -243,15 +243,19 @@
 
 static void kexec_prepare_cpus(void)
 {
+       extern void smp_release_cpus(void);
        /*
         * move the secondarys to us so that we can copy
         * the new kernel 0-0x100 safely
         *
         * do this if kexec in setup.c ?
+        *
+        * We need to release the cpus if we are ever going from an
+        * UP to an SMP kernel.
         */
-       smp_relase_cpus();
+       smp_release_cpus();
        if (ppc_md.cpu_irq_down)
-               ppc_md.cpu_irq_down();
+               ppc_md.cpu_irq_down(0);
        local_irq_disable();
 }
 
diff -urN linux/arch/ppc64/kernel/mpic.c linux/arch/ppc64/kernel/mpic.c
--- linux/arch/ppc64/kernel/mpic.c      2005/07/11 20:46:34     1.4
+++ linux/arch/ppc64/kernel/mpic.c      2005/08/08 12:30:30     1.5
@@ -794,10 +794,10 @@
 
 /*
  * XXX: someone who knows mpic should check this.
- * do we need to eoi the ipi here (see xics comments)?
+ * do we need to eoi the ipi including for kexec cpu here (see xics comments)?
  * or can we reset the mpic in the new kernel?
  */
-void mpic_teardown_this_cpu(void)
+void mpic_teardown_this_cpu(int secondary)
 {
        struct mpic *mpic = mpic_primary;
        unsigned long flags;
diff -urN linux/arch/ppc64/kernel/mpic.h linux/arch/ppc64/kernel/mpic.h
--- linux/arch/ppc64/kernel/mpic.h      2005/07/11 20:46:34     1.2
+++ linux/arch/ppc64/kernel/mpic.h      2005/08/08 12:30:30     1.3
@@ -256,7 +256,7 @@
 extern void mpic_setup_this_cpu(void);
 
 /* Clean up for kexec (or cpu offline or ...) */
-extern void mpic_teardown_this_cpu(void);
+extern void mpic_teardown_this_cpu(int secondary);
 
 /* Request IPIs on primary mpic */
 extern void mpic_request_ipis(void);
diff -urN linux/arch/ppc64/kernel/pci.c linux/arch/ppc64/kernel/pci.c
--- linux/arch/ppc64/kernel/pci.c       2005/07/11 20:46:34     1.34
+++ linux/arch/ppc64/kernel/pci.c       2005/08/08 12:30:30     1.35
@@ -108,8 +108,28 @@
        region->end = res->end - offset;
 }
 
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                             struct pci_bus_region *region)
+{
+       unsigned long offset = 0;
+       struct pci_controller *hose = pci_bus_to_host(dev->bus);
+
+       if (!hose)
+               return;
+
+       if (res->flags & IORESOURCE_IO)
+               offset = (unsigned long)hose->io_base_virt - pci_io_base;
+
+       if (res->flags & IORESOURCE_MEM)
+               offset = hose->pci_mem_offset;
+
+       res->start = region->start + offset;
+       res->end = region->end + offset;
+}
+
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(pcibios_bus_to_resource);
 #endif
 
 /*
diff -urN linux/arch/ppc64/kernel/xics.c linux/arch/ppc64/kernel/xics.c
--- linux/arch/ppc64/kernel/xics.c      2005/07/11 20:46:34     1.33
+++ linux/arch/ppc64/kernel/xics.c      2005/08/08 12:30:30     1.34
@@ -647,29 +647,30 @@
        }
 }
 
-void xics_teardown_cpu(void)
+void xics_teardown_cpu(int secondary)
 {
        int cpu = smp_processor_id();
-       int status;
 
        ops->cppr_info(cpu, 0x00);
        iosync();
 
        /*
-        * we need to EOI the IPI if we got here from kexec down IPI
-        *
-        * xics doesn't care if we duplicate an EOI as long as we
-        * don't EOI and raise priority.
-        *
-        * probably need to check all the other interrupts too
-        * should we be flagging idle loop instead?
-        * or creating some task to be scheduled?
+        * Some machines need to have at least one cpu in the GIQ,
+        * so leave the master cpu in the group.
         */
-       ops->xirr_info_set(cpu, XICS_IPI);
-
-       status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
-               (1UL << interrupt_server_size) - 1 - default_distrib_server, 0);
-       WARN_ON(status != 0);
+       if (secondary) {
+               /*
+                * we need to EOI the IPI if we got here from kexec down IPI
+                *
+                * probably need to check all the other interrupts too
+                * should we be flagging idle loop instead?
+                * or creating some task to be scheduled?
+                */
+               ops->xirr_info_set(cpu, XICS_IPI);
+               rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+                       (1UL << interrupt_server_size) - 1 -
+                       default_distrib_server, 0);
+       }
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
diff -urN linux/arch/ppc64/xmon/xmon.c linux/arch/ppc64/xmon/xmon.c
--- linux/arch/ppc64/xmon/xmon.c        2005/07/11 20:46:37     1.32
+++ linux/arch/ppc64/xmon/xmon.c        2005/08/08 12:30:31     1.33
@@ -329,13 +329,16 @@
                printf("cpu 0x%x: Exception %lx %s in xmon, "
                       "returning to main loop\n",
                       cpu, regs->trap, getvecname(TRAP(regs)));
+               release_output_lock();
                longjmp(xmon_fault_jmp[cpu], 1);
        }
 
        if (setjmp(recurse_jmp) != 0) {
                if (!in_xmon || !xmon_gate) {
+                       get_output_lock();
                        printf("xmon: WARNING: bad recursive fault "
                               "on cpu 0x%x\n", cpu);
+                       release_output_lock();
                        goto waiting;
                }
                secondary = !(xmon_taken && cpu == xmon_owner);
diff -urN linux/arch/sh64/mm/fault.c linux/arch/sh64/mm/fault.c
--- linux/arch/sh64/mm/fault.c  2005/03/18 17:37:04     1.4
+++ linux/arch/sh64/mm/fault.c  2005/08/08 12:30:31     1.5
@@ -223,13 +223,13 @@
         */
 survive:
        switch (handle_mm_fault(mm, vma, address, writeaccess)) {
-       case 1:
+       case VM_FAULT_MINOR:
                tsk->min_flt++;
                break;
-       case 2:
+       case VM_FAULT_MAJOR:
                tsk->maj_flt++;
                break;
-       case 0:
+       case VM_FAULT_SIGBUS:
                goto do_sigbus;
        default:
                goto out_of_memory;
diff -urN linux/arch/sparc64/kernel/pci.c linux/arch/sparc64/kernel/pci.c
--- linux/arch/sparc64/kernel/pci.c     2005/04/08 18:58:04     1.40
+++ linux/arch/sparc64/kernel/pci.c     2005/08/08 12:30:31     1.41
@@ -413,6 +413,12 @@
        return -EBUSY;
 }
 
+void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
+{
+       /* Not implemented for sparc64... */
+       BUG();
+}
+
 int pci_assign_resource(struct pci_dev *pdev, int resource)
 {
        struct pcidev_cookie *pcp = pdev->sysdata;
diff -urN linux/arch/x86_64/ia32/ptrace32.c linux/arch/x86_64/ia32/ptrace32.c
--- linux/arch/x86_64/ia32/ptrace32.c   2005/02/07 02:54:39     1.16
+++ linux/arch/x86_64/ia32/ptrace32.c   2005/08/08 12:30:31     1.17
@@ -43,11 +43,11 @@
        switch (regno) {
        case offsetof(struct user32, regs.fs):
                if (val && (val & 3) != 3) return -EIO; 
-               child->thread.fs = val & 0xffff; 
+               child->thread.fsindex = val & 0xffff;
                break;
        case offsetof(struct user32, regs.gs):
                if (val && (val & 3) != 3) return -EIO; 
-               child->thread.gs = val & 0xffff;
+               child->thread.gsindex = val & 0xffff;
                break;
        case offsetof(struct user32, regs.ds):
                if (val && (val & 3) != 3) return -EIO; 
@@ -138,10 +138,10 @@
 
        switch (regno) {
        case offsetof(struct user32, regs.fs):
-               *val = child->thread.fs; 
+               *val = child->thread.fsindex;
                break;
        case offsetof(struct user32, regs.gs):
-               *val = child->thread.gs;
+               *val = child->thread.gsindex;
                break;
        case offsetof(struct user32, regs.ds):
                *val = child->thread.ds;
diff -urN linux/arch/x86_64/kernel/mce.c linux/arch/x86_64/kernel/mce.c
--- linux/arch/x86_64/kernel/mce.c      2005/08/03 15:50:31     1.18
+++ linux/arch/x86_64/kernel/mce.c      2005/08/08 12:30:31     1.19
@@ -36,6 +36,7 @@
 static unsigned long console_logged;
 static int notify_user;
 static int rip_msr;
+static int mce_bootlog;
 
 /*
  * Lockless MCE logging infrastructure.
@@ -197,10 +198,11 @@
                        rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr);
 
                mce_get_rip(&m, regs);
-               if (error_code != -1)
+               if (error_code >= 0)
                        rdtscll(m.tsc);
                wrmsrl(MSR_IA32_MC0_STATUS + i*4, 0);
-               mce_log(&m);
+               if (error_code != -2)
+                       mce_log(&m);
 
                /* Did this bank cause the exception? */
                /* Assume that the bank with uncorrectable errors did it,
@@ -315,7 +317,7 @@
 
        /* Log the machine checks left over from the previous reset.
           This also clears all registers */
-       do_machine_check(NULL, -1);
+       do_machine_check(NULL, mce_bootlog ? -1 : -2);
 
        set_in_cr4(X86_CR4_MCE);
 
@@ -476,11 +478,17 @@
 }
 
 /* mce=off disables machine check. Note you can reenable it later
-   using sysfs */
+   using sysfs.
+   mce=bootlog Log MCEs from before booting. Disabled by default to work
+   around buggy BIOS that leave bogus MCEs.  */
 static int __init mcheck_enable(char *str)
 {
+       if (*str == '=')
+               str++;
        if (!strcmp(str, "off"))
                mce_dont_init = 1;
+       else if (!strcmp(str, "bootlog"))
+               mce_bootlog = 1;
        else
                printk("mce= argument %s ignored. Please use /sys", str); 
        return 0;
diff -urN linux/arch/x86_64/kernel/setup.c linux/arch/x86_64/kernel/setup.c
--- linux/arch/x86_64/kernel/setup.c    2005/08/03 15:50:31     1.48
+++ linux/arch/x86_64/kernel/setup.c    2005/08/08 12:30:31     1.49
@@ -645,15 +645,15 @@
                }
        }
 #endif
-
-       sparse_init();
-
 #ifdef CONFIG_KEXEC
        if (crashk_res.start != crashk_res.end) {
                reserve_bootmem(crashk_res.start,
                        crashk_res.end - crashk_res.start + 1);
        }
 #endif
+
+       sparse_init();
+
        paging_init();
 
        check_ioapic();
diff -urN linux/arch/x86_64/mm/fault.c linux/arch/x86_64/mm/fault.c
--- linux/arch/x86_64/mm/fault.c        2005/08/03 15:50:32     1.31
+++ linux/arch/x86_64/mm/fault.c        2005/08/08 12:30:31     1.32
@@ -439,13 +439,13 @@
         * the fault.
         */
        switch (handle_mm_fault(mm, vma, address, write)) {
-       case 1:
+       case VM_FAULT_MINOR:
                tsk->min_flt++;
                break;
-       case 2:
+       case VM_FAULT_MAJOR:
                tsk->maj_flt++;
                break;
-       case 0:
+       case VM_FAULT_SIGBUS:
                goto do_sigbus;
        default:
                goto out_of_memory;
diff -urN linux/drivers/acpi/Kconfig linux/drivers/acpi/Kconfig
--- linux/drivers/acpi/Kconfig  2005/07/13 11:49:11     1.27
+++ linux/drivers/acpi/Kconfig  2005/08/08 12:30:31     1.28
@@ -133,9 +133,10 @@
        depends on ACPI_INTERPRETER
        depends on EXPERIMENTAL
        depends on !IA64_SGI_SN
-       default m
+       default n
        help
-       ACPI generic hotkey
+         Experimental consolidated hotkey driver.
+         If you are unsure, say N.
 
 config ACPI_FAN
        tristate "Fan"
diff -urN linux/drivers/acpi/button.c linux/drivers/acpi/button.c
--- linux/drivers/acpi/button.c 2005/07/13 11:49:11     1.19
+++ linux/drivers/acpi/button.c 2005/08/08 12:30:31     1.20
@@ -26,6 +26,9 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -33,6 +36,9 @@
 #define ACPI_BUTTON_COMPONENT          0x00080000
 #define ACPI_BUTTON_DRIVER_NAME                "ACPI Button Driver"
 #define ACPI_BUTTON_CLASS              "button"
+#define ACPI_BUTTON_FILE_INFO          "info"
+#define ACPI_BUTTON_FILE_STATE         "state"
+#define ACPI_BUTTON_TYPE_UNKNOWN       0x00
 #define ACPI_BUTTON_NOTIFY_STATUS      0x80
 
 #define ACPI_BUTTON_SUBCLASS_POWER     "power"
@@ -64,6 +70,8 @@
 
 static int acpi_button_add (struct acpi_device *device);
 static int acpi_button_remove (struct acpi_device *device, int type);
+static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
+static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 
 static struct acpi_driver acpi_button_driver = {
        .name =         ACPI_BUTTON_DRIVER_NAME,
@@ -82,6 +90,179 @@
        unsigned long           pushed;
 };
 
+static struct file_operations acpi_button_info_fops = {
+       .open           = acpi_button_info_open_fs,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static struct file_operations acpi_button_state_fops = {
+       .open           = acpi_button_state_open_fs,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- 
*/
+
+static struct proc_dir_entry   *acpi_button_dir;
+
+static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
+{
+       struct acpi_button      *button = (struct acpi_button *) seq->private;
+
+       ACPI_FUNCTION_TRACE("acpi_button_info_seq_show");
+
+       if (!button || !button->device)
+               return_VALUE(0);
+
+       seq_printf(seq, "type:                    %s\n", 
+               acpi_device_name(button->device));
+
+       return_VALUE(0);
+}
+
+static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
+{
+       return single_open(file, acpi_button_info_seq_show, PDE(inode)->data);
+}
+       
+static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
+{
+       struct acpi_button      *button = (struct acpi_button *) seq->private;
+       acpi_status             status;
+       unsigned long           state;
+
+       ACPI_FUNCTION_TRACE("acpi_button_state_seq_show");
+
+       if (!button || !button->device)
+               return_VALUE(0);
+
+       status = acpi_evaluate_integer(button->handle,"_LID",NULL,&state);
+       if (ACPI_FAILURE(status)) {
+               seq_printf(seq, "state:      unsupported\n");
+       }
+       else{
+               seq_printf(seq, "state:      %s\n", (state ? "open" : 
"closed")); 
+       }
+
+       return_VALUE(0);
+}
+
+static int acpi_button_state_open_fs(struct inode *inode, struct file *file)
+{
+       return single_open(file, acpi_button_state_seq_show, PDE(inode)->data);
+}
+
+static struct proc_dir_entry *acpi_power_dir;
+static struct proc_dir_entry *acpi_sleep_dir;
+static struct proc_dir_entry *acpi_lid_dir;
+
+static int
+acpi_button_add_fs (
+       struct acpi_device      *device)
+{
+       struct proc_dir_entry   *entry = NULL;
+       struct acpi_button      *button = NULL;
+
+       ACPI_FUNCTION_TRACE("acpi_button_add_fs");
+
+       if (!device || !acpi_driver_data(device))
+               return_VALUE(-EINVAL);
+
+       button = acpi_driver_data(device);
+
+       switch (button->type) {
+       case ACPI_BUTTON_TYPE_POWER:
+       case ACPI_BUTTON_TYPE_POWERF:
+               if (!acpi_power_dir)
+                       acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, 
+                               acpi_button_dir);
+               entry = acpi_power_dir;
+               break;
+       case ACPI_BUTTON_TYPE_SLEEP:
+       case ACPI_BUTTON_TYPE_SLEEPF:
+               if (!acpi_sleep_dir)
+                       acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP, 
+                               acpi_button_dir);
+               entry = acpi_sleep_dir;
+               break;
+       case ACPI_BUTTON_TYPE_LID:
+               if (!acpi_lid_dir)
+                       acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, 
+                               acpi_button_dir);
+               entry = acpi_lid_dir;
+               break;
+       }
+
+       if (!entry)
+               return_VALUE(-ENODEV);
+       entry->owner = THIS_MODULE;
+
+       acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry);
+       if (!acpi_device_dir(device))
+               return_VALUE(-ENODEV);
+       acpi_device_dir(device)->owner = THIS_MODULE;
+
+       /* 'info' [R] */
+       entry = create_proc_entry(ACPI_BUTTON_FILE_INFO,
+               S_IRUGO, acpi_device_dir(device));
+       if (!entry)
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                       "Unable to create '%s' fs entry\n",
+                       ACPI_BUTTON_FILE_INFO));
+       else {
+               entry->proc_fops = &acpi_button_info_fops;
+               entry->data = acpi_driver_data(device);
+               entry->owner = THIS_MODULE;
+       }
+
+       /* show lid state [R] */
+       if (button->type == ACPI_BUTTON_TYPE_LID) {
+               entry = create_proc_entry(ACPI_BUTTON_FILE_STATE,
+                       S_IRUGO, acpi_device_dir(device));
+               if (!entry)
+                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                               "Unable to create '%s' fs entry\n",
+                               ACPI_BUTTON_FILE_INFO));
+               else {
+                       entry->proc_fops = &acpi_button_state_fops;
+                       entry->data = acpi_driver_data(device);
+                       entry->owner = THIS_MODULE;
+               }
+       }
+
+       return_VALUE(0);
+}
+
+
+static int
+acpi_button_remove_fs (
+       struct acpi_device      *device)
+{
+       struct acpi_button      *button = NULL;
+
+       ACPI_FUNCTION_TRACE("acpi_button_remove_fs");
+
+       button = acpi_driver_data(device);
+       if (acpi_device_dir(device)) {
+               if (button->type == ACPI_BUTTON_TYPE_LID)
+                       remove_proc_entry(ACPI_BUTTON_FILE_STATE,
+                                            acpi_device_dir(device));
+               remove_proc_entry(ACPI_BUTTON_FILE_INFO,
+                                    acpi_device_dir(device));
+
+               remove_proc_entry(acpi_device_bid(device),
+                                    acpi_device_dir(device)->parent);
+               acpi_device_dir(device) = NULL;
+       }
+
+       return_VALUE(0);
+}
+
+
 /* --------------------------------------------------------------------------
                                 Driver Interface
    -------------------------------------------------------------------------- 
*/
@@ -121,7 +302,8 @@
        
        ACPI_FUNCTION_TRACE("acpi_button_notify_fixed");
 
-       BUG_ON(!button);
+       if (!button)
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
 
        acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button);
 
@@ -197,6 +379,10 @@
                goto end;
        }
 
+       result = acpi_button_add_fs(device);
+       if (result)
+               goto end;
+
        switch (button->type) {
        case ACPI_BUTTON_TYPE_POWERF:
                status = acpi_install_fixed_event_handler (
@@ -240,6 +426,7 @@
 
 end:
        if (result) {
+               acpi_button_remove_fs(device);
                kfree(button);
        }
 
@@ -280,6 +467,8 @@
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                        "Error removing notify handler\n"));
 
+       acpi_button_remove_fs(device);  
+
        kfree(button);
 
        return_VALUE(0);
@@ -293,14 +482,20 @@
 
        ACPI_FUNCTION_TRACE("acpi_button_init");
 
+       acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
+       if (!acpi_button_dir)
+               return_VALUE(-ENODEV);
+       acpi_button_dir->owner = THIS_MODULE;
        result = acpi_bus_register_driver(&acpi_button_driver);
        if (result < 0) {
+               remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
                return_VALUE(-ENODEV);
        }
 
        return_VALUE(0);
 }
 
+
 static void __exit
 acpi_button_exit (void)
 {
@@ -308,8 +503,17 @@
 
        acpi_bus_unregister_driver(&acpi_button_driver);
 
+       if (acpi_power_dir) 
+               remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, acpi_button_dir);
+       if (acpi_sleep_dir)
+               remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, acpi_button_dir);
+       if (acpi_lid_dir)
+               remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
+       remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
+
        return_VOID;
 }
 
+
 module_init(acpi_button_init);
 module_exit(acpi_button_exit);
diff -urN linux/drivers/acpi/ec.c linux/drivers/acpi/ec.c
--- linux/drivers/acpi/ec.c     2005/08/03 15:50:33     1.36
+++ linux/drivers/acpi/ec.c     2005/08/08 12:30:31     1.37
@@ -76,13 +76,14 @@
 static int acpi_ec_start (struct acpi_device *device);
 static int acpi_ec_stop (struct acpi_device *device, int type);
 static int acpi_ec_burst_add ( struct acpi_device *device);
+static int acpi_ec_polling_add ( struct acpi_device    *device);
 
 static struct acpi_driver acpi_ec_driver = {
        .name =         ACPI_EC_DRIVER_NAME,
        .class =        ACPI_EC_CLASS,
        .ids =          ACPI_EC_HID,
        .ops =          {
-                               .add =          acpi_ec_burst_add,
+                               .add =          acpi_ec_polling_add,
                                .remove =       acpi_ec_remove,
                                .start =        acpi_ec_start,
                                .stop =         acpi_ec_stop,
@@ -164,7 +165,7 @@
 
 /* External interfaces use first EC only, so remember */
 static struct acpi_device *first_ec;
-static int acpi_ec_polling_mode;
+static int acpi_ec_polling_mode = EC_POLLING;
 
 /* --------------------------------------------------------------------------
                              Transaction Management
@@ -1710,11 +1711,24 @@
        acpi_fake_ecdt_enabled = 1;
        return 0;
 }
+
 __setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
 static int __init acpi_ec_set_polling_mode(char *str)
 {
-       acpi_ec_polling_mode = EC_POLLING;
-       acpi_ec_driver.ops.add = acpi_ec_polling_add;
+       int burst;
+
+       if (!get_option(&str, &burst))
+               return 0;
+
+       if (burst) {
+               acpi_ec_polling_mode = EC_BURST;
+               acpi_ec_driver.ops.add = acpi_ec_burst_add;
+       } else {
+               acpi_ec_polling_mode = EC_POLLING;
+               acpi_ec_driver.ops.add = acpi_ec_polling_add;
+       }
+       printk(KERN_INFO PREFIX "EC %s mode.\n",
+               burst ? "burst": "polling");
        return 0;
 }
-__setup("ec_polling", acpi_ec_set_polling_mode);
+__setup("ec_burst=", acpi_ec_set_polling_mode);
diff -urN linux/drivers/acpi/hotkey.c linux/drivers/acpi/hotkey.c
--- linux/drivers/acpi/hotkey.c 2005/07/13 11:49:11     1.1
+++ linux/drivers/acpi/hotkey.c 2005/08/08 12:30:31     1.2
@@ -1,5 +1,5 @@
-/* 
- *  hotkey.c - ACPI Hotkey Driver ($Revision:$)
+/*
+ *  hotkey.c - ACPI Hotkey Driver ($Revision: 0.2 $)
  *
  *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
  *
@@ -51,17 +51,18 @@
 #define ACPI_HOTKEY_POLLING 0x2
 #define ACPI_UNDEFINED_EVENT    0xf
 
-#define MAX_CONFIG_RECORD_LEN   80
-#define MAX_NAME_PATH_LEN   80
-#define MAX_CALL_PARM       80
+#define RESULT_STR_LEN     80
 
-#define IS_EVENT(e)       0xff /* ((e) & 0x40000000)  */
-#define IS_POLL(e)      0xff   /* (~((e) & 0x40000000))  */
+#define ACTION_METHOD  0
+#define POLL_METHOD    1
 
+#define IS_EVENT(e)            ((e) <= 10000 && (e) >0)
+#define IS_POLL(e)             ((e) > 10000)
+#define IS_OTHERS(e)           ((e)<=0 || (e)>=20000)
 #define _COMPONENT              ACPI_HOTKEY_COMPONENT
 ACPI_MODULE_NAME("acpi_hotkey")
 
-    MODULE_AUTHOR("luming.yu@intel.com");
+MODULE_AUTHOR("luming.yu@intel.com");
 MODULE_DESCRIPTION(ACPI_HOTK_NAME);
 MODULE_LICENSE("GPL");
 
@@ -114,7 +115,7 @@
        char *action_method;    /* action method */
 };
 
-/* 
+/*
  * There are two ways to poll status
  * 1. directy call read_xxx method, without any arguments passed in
  * 2. call write_xxx method, with arguments passed in, you need
@@ -131,7 +132,7 @@
        char *poll_method;      /* poll method */
        acpi_handle action_handle;      /* acpi handle attached action method */
        char *action_method;    /* action method */
-       void *poll_result;      /* polling_result */
+       union acpi_object *poll_result; /* polling_result */
        struct proc_dir_entry *proc;
 };
 
@@ -162,20 +163,25 @@
                },
 };
 
+static void free_hotkey_device(union acpi_hotkey *key);
+static void free_hotkey_buffer(union acpi_hotkey *key);
+static void free_poll_hotkey_buffer(union acpi_hotkey *key);
 static int hotkey_open_config(struct inode *inode, struct file *file);
+static int hotkey_poll_open_config(struct inode *inode, struct file *file);
 static ssize_t hotkey_write_config(struct file *file,
                                   const char __user * buffer,
                                   size_t count, loff_t * data);
-static ssize_t hotkey_write_poll_config(struct file *file,
-                                       const char __user * buffer,
-                                       size_t count, loff_t * data);
 static int hotkey_info_open_fs(struct inode *inode, struct file *file);
 static int hotkey_action_open_fs(struct inode *inode, struct file *file);
 static ssize_t hotkey_execute_aml_method(struct file *file,
                                         const char __user * buffer,
                                         size_t count, loff_t * data);
 static int hotkey_config_seq_show(struct seq_file *seq, void *offset);
+static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset);
 static int hotkey_polling_open_fs(struct inode *inode, struct file *file);
+static union acpi_hotkey *get_hotkey_by_event(struct
+                             acpi_hotkey_list
+                             *hotkey_list, int event);
 
 /* event based config */
 static struct file_operations hotkey_config_fops = {
@@ -188,9 +194,9 @@
 
 /* polling based config */
 static struct file_operations hotkey_poll_config_fops = {
-       .open = hotkey_open_config,
+       .open = hotkey_poll_open_config,
        .read = seq_read,
-       .write = hotkey_write_poll_config,
+       .write = hotkey_write_config,
        .llseek = seq_lseek,
        .release = single_release,
 };
@@ -227,7 +233,7 @@
 {
        ACPI_FUNCTION_TRACE("hotkey_info_seq_show");
 
-       seq_printf(seq, "Hotkey generic driver ver: %s", HOTKEY_ACPI_VERSION);
+       seq_printf(seq, "Hotkey generic driver ver: %s\n", HOTKEY_ACPI_VERSION);
 
        return_VALUE(0);
 }
@@ -239,27 +245,35 @@
 
 static char *format_result(union acpi_object *object)
 {
-       char *buf = (char *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
-
-       memset(buf, 0, sizeof(union acpi_object));
+       char *buf = NULL;
+       
+       buf = (char *)kmalloc(RESULT_STR_LEN, GFP_KERNEL);
+       if (buf)
+               memset(buf, 0, RESULT_STR_LEN);
+       else
+               goto do_fail;
 
        /* Now, just support integer type */
        if (object->type == ACPI_TYPE_INTEGER)
-               sprintf(buf, "%d", (u32) object->integer.value);
-
-       return buf;
+               sprintf(buf, "%d\n", (u32) object->integer.value);
+do_fail:
+       return (buf);
 }
 
 static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
 {
        struct acpi_polling_hotkey *poll_hotkey =
            (struct acpi_polling_hotkey *)seq->private;
+       char *buf;
 
        ACPI_FUNCTION_TRACE("hotkey_polling_seq_show");
 
-       if (poll_hotkey->poll_result)
-               seq_printf(seq, "%s", format_result(poll_hotkey->poll_result));
-
+       if (poll_hotkey->poll_result){
+               buf = format_result(poll_hotkey->poll_result);
+               if(buf)
+                       seq_printf(seq, "%s", buf);
+               kfree(buf);
+       }
        return_VALUE(0);
 }
 
@@ -276,19 +290,19 @@
 /* Mapping external hotkey number to standardized hotkey event num */
 static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list)
 {
-       struct list_head *entries, *next;
-       int val = 0;
+       struct list_head *entries;
+       int val = -1;
 
        ACPI_FUNCTION_TRACE("hotkey_get_internal_event");
 
-       list_for_each_safe(entries, next, list->entries) {
+       list_for_each(entries, list->entries) {
                union acpi_hotkey *key =
                    container_of(entries, union acpi_hotkey, entries);
                if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
-                   && key->event_hotkey.external_hotkey_num == event)
+                   && key->event_hotkey.external_hotkey_num == event){
                        val = key->link.hotkey_standard_num;
-               else
-                       val = -1;
+                       break;
+               }
        }
 
        return_VALUE(val);
@@ -306,7 +320,7 @@
                return_VOID;
 
        internal_event = hotkey_get_internal_event(event, &global_hotkey_list);
-       acpi_bus_generate_event(device, event, 0);
+       acpi_bus_generate_event(device, internal_event, 0);
 
        return_VOID;
 }
@@ -329,13 +343,17 @@
 static int create_polling_proc(union acpi_hotkey *device)
 {
        struct proc_dir_entry *proc;
+       char  proc_name[80];
        mode_t mode;
 
        ACPI_FUNCTION_TRACE("create_polling_proc");
        mode = S_IFREG | S_IRUGO | S_IWUGO;
 
-       proc = create_proc_entry(device->poll_hotkey.action_method,
-                                mode, hotkey_proc_dir);
+       sprintf(proc_name, "%d", device->link.hotkey_standard_num);
+       /*
+       strcat(proc_name, device->poll_hotkey.poll_method);
+       */
+       proc = create_proc_entry(proc_name, mode, hotkey_proc_dir);
 
        if (!proc) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -353,23 +371,6 @@
        return_VALUE(0);
 }
 
-static int is_valid_acpi_path(const char *pathname)
-{
-       acpi_handle handle;
-       acpi_status status;
-       ACPI_FUNCTION_TRACE("is_valid_acpi_path");
-
-       status = acpi_get_handle(NULL, (char *)pathname, &handle);
-       return_VALUE(!ACPI_FAILURE(status));
-}
-
-static int is_valid_hotkey(union acpi_hotkey *device)
-{
-       ACPI_FUNCTION_TRACE("is_valid_hotkey");
-       /* Implement valid check */
-       return_VALUE(1);
-}
-
 static int hotkey_add(union acpi_hotkey *device)
 {
        int status = 0;
@@ -378,15 +379,11 @@
        ACPI_FUNCTION_TRACE("hotkey_add");
 
        if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) {
-               status =
-                   acpi_bus_get_device(device->event_hotkey.bus_handle, &dev);
-               if (status)
-                       return_VALUE(status);
-
+               acpi_bus_get_device(device->event_hotkey.bus_handle, &dev);
                status = acpi_install_notify_handler(dev->handle,
-                                                    ACPI_SYSTEM_NOTIFY,
+                                                    ACPI_DEVICE_NOTIFY,
                                                     acpi_hotkey_notify_handler,
-                                                    device);
+                                                    dev);
        } else                  /* Add polling hotkey */
                create_polling_proc(device);
 
@@ -409,84 +406,143 @@
                if (key->link.hotkey_standard_num ==
                    device->link.hotkey_standard_num) {
                        list_del(&key->link.entries);
-                       remove_proc_entry(key->poll_hotkey.action_method,
-                                         hotkey_proc_dir);
+                       free_hotkey_device(key);
                        global_hotkey_list.count--;
                        break;
                }
        }
+       kfree(device);
        return_VALUE(0);
 }
 
-static void hotkey_update(union acpi_hotkey *key)
+static int  hotkey_update(union acpi_hotkey *key)
 {
-       struct list_head *entries, *next;
+       struct list_head *entries;
 
        ACPI_FUNCTION_TRACE("hotkey_update");
 
-       list_for_each_safe(entries, next, global_hotkey_list.entries) {
-               union acpi_hotkey *key =
+       list_for_each(entries, global_hotkey_list.entries) {
+               union acpi_hotkey *tmp=
                    container_of(entries, union acpi_hotkey, entries);
-               if (key->link.hotkey_standard_num ==
+               if (tmp->link.hotkey_standard_num ==
                    key->link.hotkey_standard_num) {
-                       key->event_hotkey.bus_handle =
-                           key->event_hotkey.bus_handle;
-                       key->event_hotkey.external_hotkey_num =
-                           key->event_hotkey.external_hotkey_num;
-                       key->event_hotkey.action_handle =
-                           key->event_hotkey.action_handle;
-                       key->event_hotkey.action_method =
-                           key->event_hotkey.action_method;
+                       if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
+                               free_hotkey_buffer(tmp);
+                               tmp->event_hotkey.bus_handle =
+                                       key->event_hotkey.bus_handle;
+                               tmp->event_hotkey.external_hotkey_num =
+                                       key->event_hotkey.external_hotkey_num;
+                               tmp->event_hotkey.action_handle =
+                                       key->event_hotkey.action_handle;
+                               tmp->event_hotkey.action_method =
+                                       key->event_hotkey.action_method;
+                               kfree(key);
+                       } else {
+                               /*
+                               char  proc_name[80];
+
+                               sprintf(proc_name, "%d", 
tmp->link.hotkey_standard_num);
+                               strcat(proc_name, tmp->poll_hotkey.poll_method);
+                               remove_proc_entry(proc_name,hotkey_proc_dir);
+                               */
+                               free_poll_hotkey_buffer(tmp);
+                               tmp->poll_hotkey.poll_handle =
+                                       key->poll_hotkey.poll_handle;
+                               tmp->poll_hotkey.poll_method =
+                                       key->poll_hotkey.poll_method;
+                               tmp->poll_hotkey.action_handle =
+                                       key->poll_hotkey.action_handle;
+                               tmp->poll_hotkey.action_method =
+                                       key->poll_hotkey.action_method;
+                               tmp->poll_hotkey.poll_result =
+                                       key->poll_hotkey.poll_result;
+                               /*
+                               create_polling_proc(tmp);
+                               */
+                               kfree(key);
+                       }
+                       return_VALUE(0);
                        break;
                }
        }
 
-       return_VOID;
+       return_VALUE(-ENODEV);
 }
 
 static void free_hotkey_device(union acpi_hotkey *key)
 {
        struct acpi_device *dev;
-       int status;
 
        ACPI_FUNCTION_TRACE("free_hotkey_device");
 
        if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
-               status =
-                   acpi_bus_get_device(key->event_hotkey.bus_handle, &dev);
+               acpi_bus_get_device(key->event_hotkey.bus_handle, &dev);
                if (dev->handle)
                        acpi_remove_notify_handler(dev->handle,
-                                                  ACPI_SYSTEM_NOTIFY,
+                                                  ACPI_DEVICE_NOTIFY,
                                                   acpi_hotkey_notify_handler);
-       } else
-               remove_proc_entry(key->poll_hotkey.action_method,
-                                 hotkey_proc_dir);
+               free_hotkey_buffer(key);
+       } else {
+               char  proc_name[80];
+
+               sprintf(proc_name, "%d", key->link.hotkey_standard_num);
+               /*
+               strcat(proc_name, key->poll_hotkey.poll_method);
+               */
+               remove_proc_entry(proc_name,hotkey_proc_dir);
+               free_poll_hotkey_buffer(key);
+       }
        kfree(key);
        return_VOID;
 }
 
+static void
+free_hotkey_buffer(union acpi_hotkey *key)
+{
+       kfree(key->event_hotkey.action_method);
+}
+
+static void
+free_poll_hotkey_buffer(union acpi_hotkey *key)
+{
+       kfree(key->poll_hotkey.action_method);
+       kfree(key->poll_hotkey.poll_method);
+       kfree(key->poll_hotkey.poll_result);
+}
 static int
 init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str,
                   char *method, int std_num, int external_num)
 {
+       acpi_handle     tmp_handle;
+       acpi_status status = AE_OK;
+
        ACPI_FUNCTION_TRACE("init_hotkey_device");
 
+       if(std_num < 0 || IS_POLL(std_num) || !key )
+               goto do_fail;
+
+       if(!bus_str || !action_str || !method)
+               goto do_fail;
+
        key->link.hotkey_type = ACPI_HOTKEY_EVENT;
        key->link.hotkey_standard_num = std_num;
        key->event_hotkey.flag = 0;
-       if (is_valid_acpi_path(bus_str))
-               acpi_get_handle((acpi_handle) 0,
-                               bus_str, &(key->event_hotkey.bus_handle));
-       else
-               return_VALUE(-ENODEV);
-       key->event_hotkey.external_hotkey_num = external_num;
-       if (is_valid_acpi_path(action_str))
-               acpi_get_handle((acpi_handle) 0,
-                               action_str, &(key->event_hotkey.action_handle));
-       key->event_hotkey.action_method = kmalloc(sizeof(method), GFP_KERNEL);
-       strcpy(key->event_hotkey.action_method, method);
+       key->event_hotkey.action_method = method;
 
-       return_VALUE(!is_valid_hotkey(key));
+       status = acpi_get_handle(NULL,bus_str, &(key->event_hotkey.bus_handle));
+       if(ACPI_FAILURE(status))
+               goto do_fail;
+       key->event_hotkey.external_hotkey_num = external_num;
+       status = acpi_get_handle(NULL,action_str, 
&(key->event_hotkey.action_handle));
+       if(ACPI_FAILURE(status))
+               goto do_fail;
+       status = acpi_get_handle(key->event_hotkey.action_handle,
+                               method, &tmp_handle);
+       if (ACPI_FAILURE(status))
+               goto do_fail;
+       return_VALUE(AE_OK);
+do_fail:
+       return_VALUE(-ENODEV);
 }
 
 static int
@@ -495,34 +551,46 @@
                        char *poll_method,
                        char *action_str, char *action_method, int std_num)
 {
+       acpi_status status = AE_OK;
+       acpi_handle     tmp_handle;
+
        ACPI_FUNCTION_TRACE("init_poll_hotkey_device");
 
+       if(std_num < 0 || IS_EVENT(std_num) || !key)
+               goto do_fail;
+
+       if(!poll_str || !poll_method || !action_str || !action_method)
+               goto do_fail;
+
        key->link.hotkey_type = ACPI_HOTKEY_POLLING;
        key->link.hotkey_standard_num = std_num;
        key->poll_hotkey.flag = 0;
-       if (is_valid_acpi_path(poll_str))
-               acpi_get_handle((acpi_handle) 0,
-                               poll_str, &(key->poll_hotkey.poll_handle));
-       else
-               return_VALUE(-ENODEV);
        key->poll_hotkey.poll_method = poll_method;
-       if (is_valid_acpi_path(action_str))
-               acpi_get_handle((acpi_handle) 0,
-                               action_str, &(key->poll_hotkey.action_handle));
-       key->poll_hotkey.action_method =
-           kmalloc(sizeof(action_method), GFP_KERNEL);
-       strcpy(key->poll_hotkey.action_method, action_method);
+       key->poll_hotkey.action_method = action_method;
+
+       status = acpi_get_handle(NULL,poll_str, 
&(key->poll_hotkey.poll_handle));
+       if(ACPI_FAILURE(status))
+               goto do_fail;
+       status = acpi_get_handle(key->poll_hotkey.poll_handle,
+                               poll_method, &tmp_handle);
+        if (ACPI_FAILURE(status))
+                       goto do_fail;
+       status = acpi_get_handle(NULL,action_str, 
&(key->poll_hotkey.action_handle));
+       if (ACPI_FAILURE(status))
+               goto do_fail;
+       status = acpi_get_handle(key->poll_hotkey.action_handle,
+                               action_method, &tmp_handle);
+       if (ACPI_FAILURE(status))
+               goto do_fail;
        key->poll_hotkey.poll_result =
            (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
-       return_VALUE(is_valid_hotkey(key));
+       if(!key->poll_hotkey.poll_result)
+               goto do_fail;
+       return_VALUE(AE_OK);
+do_fail:
+       return_VALUE(-ENODEV);
 }
 
-static int check_hotkey_valid(union acpi_hotkey *key,
-                             struct acpi_hotkey_list *list)
-{
-       ACPI_FUNCTION_TRACE("check_hotkey_valid");
-       return_VALUE(0);
-}
 
 static int hotkey_open_config(struct inode *inode, struct file *file)
 {
@@ -531,10 +599,17 @@
                     (file, hotkey_config_seq_show, PDE(inode)->data));
 }
 
+static int hotkey_poll_open_config(struct inode *inode, struct file *file)
+{
+       ACPI_FUNCTION_TRACE("hotkey_poll_open_config");
+       return_VALUE(single_open
+                    (file, hotkey_poll_config_seq_show, PDE(inode)->data));
+}
+
 static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
 {
        struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
-       struct list_head *entries, *next;
+       struct list_head *entries;
        char bus_name[ACPI_PATHNAME_MAX] = { 0 };
        char action_name[ACPI_PATHNAME_MAX] = { 0 };
        struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
@@ -542,10 +617,7 @@
 
        ACPI_FUNCTION_TRACE(("hotkey_config_seq_show"));
 
-       if (!hotkey_list)
-               goto end;
-
-       list_for_each_safe(entries, next, hotkey_list->entries) {
+       list_for_each(entries, hotkey_list->entries) {
                union acpi_hotkey *key =
                    container_of(entries, union acpi_hotkey, entries);
                if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
@@ -553,18 +625,37 @@
                                      ACPI_NAME_TYPE_MAX, &bus);
                        acpi_get_name(key->event_hotkey.action_handle,
                                      ACPI_NAME_TYPE_MAX, &act);
-                       seq_printf(seq, "%s:%s:%s:%d:%d", bus_name,
+                       seq_printf(seq, "%s:%s:%s:%d:%d\n", bus_name,
                                   action_name,
                                   key->event_hotkey.action_method,
                                   key->link.hotkey_standard_num,
                                   key->event_hotkey.external_hotkey_num);
-               } /* ACPI_HOTKEY_POLLING */
-               else {
+               }
+       }
+       seq_puts(seq, "\n");
+       return_VALUE(0);
+}
+
+static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset)
+{
+       struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
+       struct list_head *entries;
+       char bus_name[ACPI_PATHNAME_MAX] = { 0 };
+       char action_name[ACPI_PATHNAME_MAX] = { 0 };
+       struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
+       struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
+
+       ACPI_FUNCTION_TRACE(("hotkey_config_seq_show"));
+
+       list_for_each(entries, hotkey_list->entries) {
+               union acpi_hotkey *key =
+                   container_of(entries, union acpi_hotkey, entries);
+               if (key->link.hotkey_type == ACPI_HOTKEY_POLLING) {
                        acpi_get_name(key->poll_hotkey.poll_handle,
                                      ACPI_NAME_TYPE_MAX, &bus);
                        acpi_get_name(key->poll_hotkey.action_handle,
                                      ACPI_NAME_TYPE_MAX, &act);
-                       seq_printf(seq, "%s:%s:%s:%s:%d", bus_name,
+                       seq_printf(seq, "%s:%s:%s:%s:%d\n", bus_name,
                                   key->poll_hotkey.poll_method,
                                   action_name,
                                   key->poll_hotkey.action_method,
@@ -572,49 +663,83 @@
                }
        }
        seq_puts(seq, "\n");
-      end:
        return_VALUE(0);
 }
 
 static int
 get_parms(char *config_record,
          int *cmd,
-         char *bus_handle,
-         char *bus_method,
-         char *action_handle,
-         char *method, int *internal_event_num, int *external_event_num)
+         char **bus_handle,
+         char **bus_method,
+         char **action_handle,
+         char **method, int *internal_event_num, int *external_event_num)
 {
-       char *tmp, *tmp1;
+       char *tmp, *tmp1, count;
        ACPI_FUNCTION_TRACE(("get_parms"));
 
        sscanf(config_record, "%d", cmd);
 
+       if(*cmd == 1){
+               if(sscanf(config_record, "%d:%d", cmd, internal_event_num)!=2)
+                       goto do_fail;
+               else
+                       return (6);
+       }
        tmp = strchr(config_record, ':');
+       if (!tmp)
+               goto do_fail;
        tmp++;
        tmp1 = strchr(tmp, ':');
-       strncpy(bus_handle, tmp, tmp1 - tmp);
-       bus_handle[tmp1 - tmp] = 0;
+       if (!tmp1)
+               goto do_fail;
+
+       count = tmp1 - tmp;
+       *bus_handle = (char *) kmalloc(count+1, GFP_KERNEL);
+       if(!*bus_handle)
+               goto do_fail;
+       strncpy(*bus_handle, tmp, count);
+       *(*bus_handle + count) = 0;
 
        tmp = tmp1;
        tmp++;
        tmp1 = strchr(tmp, ':');
-       strncpy(bus_method, tmp, tmp1 - tmp);
-       bus_method[tmp1 - tmp] = 0;
+       if (!tmp1)
+               goto do_fail;
+       count = tmp1 - tmp;
+       *bus_method = (char *) kmalloc(count+1, GFP_KERNEL);
+       if(!*bus_method)
+               goto do_fail;
+       strncpy(*bus_method, tmp, count);
+       *(*bus_method + count) = 0;
 
        tmp = tmp1;
        tmp++;
        tmp1 = strchr(tmp, ':');
-       strncpy(action_handle, tmp, tmp1 - tmp);
-       action_handle[tmp1 - tmp] = 0;
+       if (!tmp1)
+               goto do_fail;
+       count = tmp1 - tmp;
+       *action_handle = (char *) kmalloc(count+1, GFP_KERNEL);
+       strncpy(*action_handle, tmp, count);
+       *(*action_handle + count) = 0;
 
        tmp = tmp1;
        tmp++;
        tmp1 = strchr(tmp, ':');
-       strncpy(method, tmp, tmp1 - tmp);
-       method[tmp1 - tmp] = 0;
+       if (!tmp1)
+               goto do_fail;
+       count = tmp1 - tmp;
+       *method = (char *) kmalloc(count+1, GFP_KERNEL);
+       if(!*method)
+               goto do_fail;
+       strncpy(*method, tmp, count);
+       *(*method + count) = 0;
+
+       if(sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num)<=0)
+               goto do_fail;
 
-       sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num);
        return_VALUE(6);
+do_fail:
+       return_VALUE(-1);
 }
 
 /*  count is length for one input record */
@@ -622,135 +747,117 @@
                                   const char __user * buffer,
                                   size_t count, loff_t * data)
 {
-       struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
-       char config_record[MAX_CONFIG_RECORD_LEN];
-       char bus_handle[MAX_NAME_PATH_LEN];
-       char bus_method[MAX_NAME_PATH_LEN];
-       char action_handle[MAX_NAME_PATH_LEN];
-       char method[20];
+       char *config_record = NULL;
+       char *bus_handle = NULL;
+       char *bus_method = NULL;
+       char *action_handle = NULL;
+       char *method = NULL;
        int cmd, internal_event_num, external_event_num;
        int ret = 0;
        union acpi_hotkey *key = NULL;
 
        ACPI_FUNCTION_TRACE(("hotkey_write_config"));
 
-       if (!hotkey_list || count > MAX_CONFIG_RECORD_LEN) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid arguments\n"));
-               return_VALUE(-EINVAL);
-       }
+       config_record = (char *) kmalloc(count+1, GFP_KERNEL);
+       if(!config_record)
+               return_VALUE(-ENOMEM);
 
        if (copy_from_user(config_record, buffer, count)) {
+               kfree(config_record);
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data \n"));
                return_VALUE(-EINVAL);
        }
-       config_record[count] = '\0';
+       config_record[count] = 0;
 
        ret = get_parms(config_record,
                        &cmd,
-                       bus_handle,
-                       bus_method,
-                       action_handle,
-                       method, &internal_event_num, &external_event_num);
+                       &bus_handle,
+                       &bus_method,
+                       &action_handle,
+                       &method, &internal_event_num, &external_event_num);
+
+       kfree(config_record);
+       if(IS_OTHERS(internal_event_num))
+               goto do_fail;
        if (ret != 6) {
+do_fail:       
+               kfree(bus_handle);
+               kfree(bus_method);
+               kfree(action_handle);
+               kfree(method);
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                                  "Invalid data format ret=%d\n", ret));
                return_VALUE(-EINVAL);
        }
 
        key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
-       ret = init_hotkey_device(key, bus_handle, action_handle, method,
+       if(!key)
+               goto do_fail;
+       memset(key, 0, sizeof(union acpi_hotkey));
+       if(cmd == 1) {
+               union acpi_hotkey *tmp = NULL;
+               tmp = get_hotkey_by_event(&global_hotkey_list,
+                               internal_event_num);
+               if(!tmp)
+                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid key"));
+               else
+                       memcpy(key, tmp, sizeof(union acpi_hotkey));
+               goto cont_cmd;
+       }
+       if (IS_EVENT(internal_event_num)) {
+               kfree(bus_method);
+               ret = init_hotkey_device(key, bus_handle, action_handle, method,
                                 internal_event_num, external_event_num);
-
-       if (ret || check_hotkey_valid(key, hotkey_list)) {
+       } else
+               ret = init_poll_hotkey_device(key, bus_handle, bus_method,
+                                     action_handle, method,
+                                     internal_event_num);
+       if (ret) {
+               kfree(bus_handle);
+               kfree(action_handle);
+               if(IS_EVENT(internal_event_num))
+                       free_hotkey_buffer(key);
+               else
+                       free_poll_hotkey_buffer(key);
                kfree(key);
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid hotkey \n"));
                return_VALUE(-EINVAL);
        }
-       switch (cmd) {
-       case 0:
-               hotkey_add(key);
-               break;
-       case 1:
-               hotkey_remove(key);
-               free_hotkey_device(key);
-               break;
-       case 2:
-               hotkey_update(key);
-               break;
-       default:
-               break;
-       }
-       return_VALUE(count);
-}
-
-/*  count is length for one input record */
-static ssize_t hotkey_write_poll_config(struct file *file,
-                                       const char __user * buffer,
-                                       size_t count, loff_t * data)
-{
-       struct seq_file *m = (struct seq_file *)file->private_data;
-       struct acpi_hotkey_list *hotkey_list =
-           (struct acpi_hotkey_list *)m->private;
-
-       char config_record[MAX_CONFIG_RECORD_LEN];
-       char polling_handle[MAX_NAME_PATH_LEN];
-       char action_handle[MAX_NAME_PATH_LEN];
-       char poll_method[20], action_method[20];
-       int ret, internal_event_num, cmd, external_event_num;
-       union acpi_hotkey *key = NULL;
-
-       ACPI_FUNCTION_TRACE("hotkey_write_poll_config");
-
-       if (!hotkey_list || count > MAX_CONFIG_RECORD_LEN) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid arguments\n"));
-               return_VALUE(-EINVAL);
-       }
 
-       if (copy_from_user(config_record, buffer, count)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data \n"));
-               return_VALUE(-EINVAL);
-       }
-       config_record[count] = '\0';
-
-       ret = get_parms(config_record,
-                       &cmd,
-                       polling_handle,
-                       poll_method,
-                       action_handle,
-                       action_method,
-                       &internal_event_num, &external_event_num);
-
-       if (ret != 6) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
-               return_VALUE(-EINVAL);
-       }
+cont_cmd:
+       kfree(bus_handle);
+       kfree(action_handle);
 
-       key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
-       ret = init_poll_hotkey_device(key, polling_handle, poll_method,
-                                     action_handle, action_method,
-                                     internal_event_num);
-       if (ret || check_hotkey_valid(key, hotkey_list)) {
-               kfree(key);
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid hotkey \n"));
-               return_VALUE(-EINVAL);
-       }
        switch (cmd) {
        case 0:
-               hotkey_add(key);
+               
if(get_hotkey_by_event(&global_hotkey_list,key->link.hotkey_standard_num))
+                       goto fail_out;
+               else
+                       hotkey_add(key);
                break;
        case 1:
                hotkey_remove(key);
                break;
        case 2:
-               hotkey_update(key);
+               if(hotkey_update(key))
+                       goto fail_out;
                break;
        default:
+               goto fail_out;
                break;
        }
        return_VALUE(count);
+fail_out:
+       if(IS_EVENT(internal_event_num))
+               free_hotkey_buffer(key);
+       else
+               free_poll_hotkey_buffer(key);
+       kfree(key);
+       ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "invalid key\n"));
+       return_VALUE(-EINVAL);
 }
 
-/*  
+/*
  * This function evaluates an ACPI method, given an int as parameter, the
  * method is searched within the scope of the handle, can be NULL. The output
  * of the method is written is output, which can also be NULL
@@ -775,7 +882,7 @@
        return_VALUE(status == AE_OK);
 }
 
-static int read_acpi_int(acpi_handle handle, const char *method, int *val)
+static int read_acpi_int(acpi_handle handle, const char *method, union 
acpi_object *val)
 {
        struct acpi_buffer output;
        union acpi_object out_obj;
@@ -786,62 +893,32 @@
        output.pointer = &out_obj;
 
        status = acpi_evaluate_object(handle, (char *)method, NULL, &output);
-       *val = out_obj.integer.value;
+       if(val){
+               val->integer.value = out_obj.integer.value;
+               val->type = out_obj.type;
+       } else
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "null val pointer"));
        return_VALUE((status == AE_OK)
                     && (out_obj.type == ACPI_TYPE_INTEGER));
 }
 
-static acpi_handle
-get_handle_from_hotkeylist(struct acpi_hotkey_list *hotkey_list, int event_num)
-{
-       struct list_head *entries, *next;
-
-       list_for_each_safe(entries, next, hotkey_list->entries) {
-               union acpi_hotkey *key =
-                   container_of(entries, union acpi_hotkey, entries);
-               if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
-                   && key->link.hotkey_standard_num == event_num) {
-                       return (key->event_hotkey.action_handle);
-               }
-       }
-       return (NULL);
-}
-
-static
-char *get_method_from_hotkeylist(struct acpi_hotkey_list *hotkey_list,
-                                int event_num)
+static union acpi_hotkey *get_hotkey_by_event(struct
+                             acpi_hotkey_list
+                             *hotkey_list, int event)
 {
-       struct list_head *entries, *next;
-
-       list_for_each_safe(entries, next, hotkey_list->entries) {
-               union acpi_hotkey *key =
-                   container_of(entries, union acpi_hotkey, entries);
-
-               if (key->link.hotkey_type == ACPI_HOTKEY_EVENT &&
-                   key->link.hotkey_standard_num == event_num)
-                       return (key->event_hotkey.action_method);
-       }
-       return (NULL);
-}
-
-static struct acpi_polling_hotkey *get_hotkey_by_event(struct
-                                                      acpi_hotkey_list
-                                                      *hotkey_list, int event)
-{
-       struct list_head *entries, *next;
+       struct list_head *entries;
 
-       list_for_each_safe(entries, next, hotkey_list->entries) {
+       list_for_each(entries, hotkey_list->entries) {
                union acpi_hotkey *key =
                    container_of(entries, union acpi_hotkey, entries);
-               if (key->link.hotkey_type == ACPI_HOTKEY_POLLING
-                   && key->link.hotkey_standard_num == event) {
-                       return (&key->poll_hotkey);
+               if (key->link.hotkey_standard_num == event) {
+                       return(key);
                }
        }
-       return (NULL);
+       return(NULL);
 }
 
-/*  
+/*
  * user call AML method interface:
  * Call convention:
  * echo "event_num: arg type : value"
@@ -854,48 +931,56 @@
                                         size_t count, loff_t * data)
 {
        struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
-       char arg[MAX_CALL_PARM];
-       int event, type, value;
-
-       char *method;
-       acpi_handle handle;
+       char *arg;
+       int event,method_type,type, value;
+       union acpi_hotkey *key;
 
        ACPI_FUNCTION_TRACE("hotkey_execte_aml_method");
 
-       if (!hotkey_list || count > MAX_CALL_PARM) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 1"));
-               return_VALUE(-EINVAL);
-       }
+       arg = (char *) kmalloc(count+1, GFP_KERNEL);
+       if(!arg)
+               return_VALUE(-ENOMEM);
+       arg[count]=0;
 
        if (copy_from_user(arg, buffer, count)) {
+               kfree(arg);
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 2"));
                return_VALUE(-EINVAL);
        }
 
-       arg[count] = '\0';
-
-       if (sscanf(arg, "%d:%d:%d", &event, &type, &value) != 3) {
+       if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) != 
4) {
+               kfree(arg);
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 3"));
                return_VALUE(-EINVAL);
        }
-
+       kfree(arg);
        if (type == ACPI_TYPE_INTEGER) {
-               handle = get_handle_from_hotkeylist(hotkey_list, event);
-               method = (char *)get_method_from_hotkeylist(hotkey_list, event);
+               key = get_hotkey_by_event(hotkey_list, event);
+               if(!key)
+                       goto do_fail;
                if (IS_EVENT(event))
-                       write_acpi_int(handle, method, value, NULL);
+                       write_acpi_int(key->event_hotkey.action_handle,
+                                       key->event_hotkey.action_method, value, 
NULL);
                else if (IS_POLL(event)) {
-                       struct acpi_polling_hotkey *key;
-                       key = (struct acpi_polling_hotkey *)
-                           get_hotkey_by_event(hotkey_list, event);
-                       read_acpi_int(handle, method, key->poll_result);
+                       if ( method_type == POLL_METHOD )
+                               read_acpi_int(key->poll_hotkey.poll_handle,
+                                       key->poll_hotkey.poll_method,
+                                       key->poll_hotkey.poll_result);
+                       else if ( method_type == ACTION_METHOD )
+                               write_acpi_int(key->poll_hotkey.action_handle,
+                                       key->poll_hotkey.action_method, value, 
NULL);
+                       else
+                               goto do_fail;
+
                }
        } else {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Not supported"));
                return_VALUE(-EINVAL);
        }
-
        return_VALUE(count);
+do_fail:
+       return_VALUE(-EINVAL);
+
 }
 
 static int __init hotkey_init(void)
@@ -928,7 +1013,7 @@
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                                  "Hotkey: Unable to create %s entry\n",
                                  HOTKEY_EV_CONFIG));
-               return (-ENODEV);
+               goto do_fail1;
        } else {
                hotkey_config->proc_fops = &hotkey_config_fops;
                hotkey_config->data = &global_hotkey_list;
@@ -943,7 +1028,8 @@
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                                  "Hotkey: Unable to create %s entry\n",
                                  HOTKEY_EV_CONFIG));
-               return (-ENODEV);
+
+               goto do_fail2;
        } else {
                hotkey_poll_config->proc_fops = &hotkey_poll_config_fops;
                hotkey_poll_config->data = &global_hotkey_list;
@@ -957,7 +1043,7 @@
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                                  "Hotkey: Unable to create %s entry\n",
                                  HOTKEY_ACTION));
-               return (-ENODEV);
+               goto do_fail3;
        } else {
                hotkey_action->proc_fops = &hotkey_action_fops;
                hotkey_action->owner = THIS_MODULE;
@@ -970,7 +1056,7 @@
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                                  "Hotkey: Unable to create %s entry\n",
                                  HOTKEY_INFO));
-               return (-ENODEV);
+               goto do_fail4;
        } else {
                hotkey_info->proc_fops = &hotkey_info_fops;
                hotkey_info->owner = THIS_MODULE;
@@ -979,23 +1065,33 @@
        }
 
        result = acpi_bus_register_driver(&hotkey_driver);
-       if (result < 0) {
-               remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
-               return (-ENODEV);
-       }
+       if (result < 0)
+               goto do_fail5;
        global_hotkey_list.count = 0;
        global_hotkey_list.entries = &hotkey_entries;
 
        INIT_LIST_HEAD(&hotkey_entries);
 
        return (0);
+
+do_fail5:
+       remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
+do_fail4:
+       remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
+do_fail3:
+       remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
+do_fail2:
+       remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
+do_fail1:
+       remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
+       return (-ENODEV);
 }
 
 static void __exit hotkey_exit(void)
 {
        struct list_head *entries, *next;
 
-       ACPI_FUNCTION_TRACE("hotkey_remove");
+       ACPI_FUNCTION_TRACE("hotkey_exit");
 
        list_for_each_safe(entries, next, global_hotkey_list.entries) {
                union acpi_hotkey *key =
diff -urN linux/drivers/acpi/motherboard.c linux/drivers/acpi/motherboard.c
--- linux/drivers/acpi/motherboard.c    2004/11/15 11:49:22     1.3
+++ linux/drivers/acpi/motherboard.c    2005/08/08 12:30:31     1.4
@@ -43,7 +43,7 @@
  */
 #define IS_RESERVED_ADDR(base, len) \
        (((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \
-       && ((base) + (len) > PCIBIOS_MIN_IO))
+       && ((base) + (len) > 0x1000))
 
 /*
  * Clearing the flag (IORESOURCE_BUSY) allows drivers to use
diff -urN linux/drivers/acpi/osl.c linux/drivers/acpi/osl.c
--- linux/drivers/acpi/osl.c    2005/07/13 11:49:11     1.40
+++ linux/drivers/acpi/osl.c    2005/08/08 12:30:31     1.41
@@ -145,10 +145,14 @@
 #endif
 }
 
+extern int acpi_in_resume;
 void *
 acpi_os_allocate(acpi_size size)
 {
-       return kmalloc(size, GFP_KERNEL);
+       if (acpi_in_resume)
+               return kmalloc(size, GFP_ATOMIC);
+       else
+               return kmalloc(size, GFP_KERNEL);
 }
 
 void
diff -urN linux/drivers/acpi/pci_link.c linux/drivers/acpi/pci_link.c
--- linux/drivers/acpi/pci_link.c       2005/08/03 15:50:33     1.27
+++ linux/drivers/acpi/pci_link.c       2005/08/08 12:30:32     1.28
@@ -692,7 +692,18 @@
                return_VALUE(-1);
        }
 
+#ifdef FUTURE_USE
+       /*
+        * The Link reference count allows us to _DISable an unused link
+        * and suspend time, and set it again  on resume.
+        * However, 2.6.12 still has irq_router.resume
+        * which blindly restores the link state.
+        * So we disable the reference count method
+        * to prevent duplicate acpi_pci_link_set()
+        * which would harm some systems
+        */
        link->refcnt --;
+#endif
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                "Link %s is dereferenced\n", acpi_device_bid(link->device)));
 
@@ -787,6 +798,11 @@
                return_VALUE(0);
 }
 
+/*
+ * FIXME: this is a workaround to avoid nasty warning.  It will be removed
+ * after every device calls pci_disable_device in .resume.
+ */
+int acpi_in_resume;
 static int
 irqrouter_resume(
        struct sys_device *dev)
@@ -796,6 +812,7 @@
 
        ACPI_FUNCTION_TRACE("irqrouter_resume");
 
+       acpi_in_resume = 1;
        list_for_each(node, &acpi_link.entries) {
                link = list_entry(node, struct acpi_pci_link, node);
                if (!link) {
@@ -805,6 +822,7 @@
                }
                acpi_pci_link_resume(link);
        }
+       acpi_in_resume = 0;
        return_VALUE(0);
 }
 
diff -urN linux/drivers/acpi/processor_idle.c 
linux/drivers/acpi/processor_idle.c
--- linux/drivers/acpi/processor_idle.c 2005/08/03 15:50:33     1.6
+++ linux/drivers/acpi/processor_idle.c 2005/08/08 12:30:32     1.7
@@ -86,12 +86,11 @@
        if (max_cstate > ACPI_PROCESSOR_MAX_POWER)
                return 0;
 
-       printk(KERN_NOTICE PREFIX "%s detected - %s disabled."
+       printk(KERN_NOTICE PREFIX "%s detected - limiting to C%ld max_cstate."
                " Override with \"processor.max_cstate=%d\"\n", id->ident,
-               ((int)id->driver_data == 1)? "C2,C3":"C3",
-              ACPI_PROCESSOR_MAX_POWER + 1);
+               (long)id->driver_data, ACPI_PROCESSOR_MAX_POWER + 1);
 
-       max_cstate = (int)id->driver_data;
+       max_cstate = (long)id->driver_data;
 
        return 0;
 }
diff -urN linux/drivers/acpi/dispatcher/dswload.c 
linux/drivers/acpi/dispatcher/dswload.c
--- linux/drivers/acpi/dispatcher/dswload.c     2005/07/13 11:49:12     1.29
+++ linux/drivers/acpi/dispatcher/dswload.c     2005/08/08 12:30:32     1.30
@@ -491,12 +491,6 @@
                if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
                          (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
                        (!(walk_state->op_info->flags & AML_NAMED))) {
-                       if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
-                               (walk_state->op_info->class == 
AML_CLASS_CONTROL)) {
-                               ACPI_REPORT_WARNING ((
-                                       "Encountered executable code at module 
level, [%s]\n",
-                                       acpi_ps_get_opcode_name 
(walk_state->opcode)));
-                       }
                        return_ACPI_STATUS (AE_OK);
                }
 
diff -urN linux/drivers/block/cfq-iosched.c linux/drivers/block/cfq-iosched.c
--- linux/drivers/block/cfq-iosched.c   2005/07/11 20:46:51     1.14
+++ linux/drivers/block/cfq-iosched.c   2005/08/08 12:30:32     1.15
@@ -1281,6 +1281,7 @@
                         */
                        if (!cfq_crq_in_driver(crq) &&
                            !cfq_cfqq_idle_window(cfqq) &&
+                           !blk_barrier_rq(rq) &&
                            cfqd->rq_in_driver >= cfqd->cfq_max_depth)
                                return NULL;
 
diff -urN linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- linux/drivers/block/ll_rw_blk.c     2005/07/12 09:19:10     1.146
+++ linux/drivers/block/ll_rw_blk.c     2005/08/08 12:30:32     1.147
@@ -719,7 +719,7 @@
 {
        struct blk_queue_tag *bqt = q->queue_tags;
 
-       if (unlikely(bqt == NULL || tag >= bqt->max_depth))
+       if (unlikely(bqt == NULL || tag >= bqt->real_max_depth))
                return NULL;
 
        return bqt->tag_index[tag];
@@ -798,6 +798,7 @@
 
        memset(tag_index, 0, depth * sizeof(struct request *));
        memset(tag_map, 0, nr_ulongs * sizeof(unsigned long));
+       tags->real_max_depth = depth;
        tags->max_depth = depth;
        tags->tag_index = tag_index;
        tags->tag_map = tag_map;
@@ -872,11 +873,22 @@
                return -ENXIO;
 
        /*
+        * if we already have large enough real_max_depth.  just
+        * adjust max_depth.  *NOTE* as requests with tag value
+        * between new_depth and real_max_depth can be in-flight, tag
+        * map can not be shrunk blindly here.
+        */
+       if (new_depth <= bqt->real_max_depth) {
+               bqt->max_depth = new_depth;
+               return 0;
+       }
+
+       /*
         * save the old state info, so we can copy it back
         */
        tag_index = bqt->tag_index;
        tag_map = bqt->tag_map;
-       max_depth = bqt->max_depth;
+       max_depth = bqt->real_max_depth;
 
        if (init_tag_map(q, bqt, new_depth))
                return -ENOMEM;
@@ -913,7 +925,7 @@
 
        BUG_ON(tag == -1);
 
-       if (unlikely(tag >= bqt->max_depth))
+       if (unlikely(tag >= bqt->real_max_depth))
                /*
                 * This can happen after tag depth has been reduced.
                 * FIXME: how about a warning or info message here?
diff -urN linux/drivers/bluetooth/bpa10x.c linux/drivers/bluetooth/bpa10x.c
--- linux/drivers/bluetooth/bpa10x.c    2005/02/13 20:16:21     1.1
+++ linux/drivers/bluetooth/bpa10x.c    2005/08/08 12:30:32     1.2
@@ -367,11 +367,8 @@
        if (!urb)
                return;
 
-       if (urb->setup_packet)
-               kfree(urb->setup_packet);
-
-       if (urb->transfer_buffer)
-               kfree(urb->transfer_buffer);
+       kfree(urb->setup_packet);
+       kfree(urb->transfer_buffer);
 
        usb_free_urb(urb);
 }
diff -urN linux/drivers/bluetooth/hci_bcsp.c linux/drivers/bluetooth/hci_bcsp.c
--- linux/drivers/bluetooth/hci_bcsp.c  2005/04/08 18:58:11     1.10
+++ linux/drivers/bluetooth/hci_bcsp.c  2005/08/08 12:30:32     1.11
@@ -58,8 +58,6 @@
 #ifndef CONFIG_BT_HCIUART_DEBUG
 #undef  BT_DBG
 #define BT_DBG( A... )
-#undef  BT_DMP
-#define BT_DMP( A... )
 #endif
 
 static int hciextn = 1;
diff -urN linux/drivers/bluetooth/hci_h4.c linux/drivers/bluetooth/hci_h4.c
--- linux/drivers/bluetooth/hci_h4.c    2004/03/11 16:46:47     1.10
+++ linux/drivers/bluetooth/hci_h4.c    2005/08/08 12:30:32     1.11
@@ -57,8 +57,6 @@
 #ifndef CONFIG_BT_HCIUART_DEBUG
 #undef  BT_DBG
 #define BT_DBG( A... )
-#undef  BT_DMP
-#define BT_DMP( A... )
 #endif
 
 /* Initialize protocol */
@@ -125,7 +123,6 @@
 
        BT_DBG("len %d room %d", len, room);
        if (!len) {
-               BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
                hci_recv_frame(h4->rx_skb);
        } else if (len > room) {
                BT_ERR("Data length is too large");
@@ -169,8 +166,6 @@
                        case H4_W4_DATA:
                                BT_DBG("Complete data");
 
-                               BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
-
                                hci_recv_frame(h4->rx_skb);
 
                                h4->rx_state = H4_W4_PACKET_TYPE;
diff -urN linux/drivers/bluetooth/hci_ldisc.c 
linux/drivers/bluetooth/hci_ldisc.c
--- linux/drivers/bluetooth/hci_ldisc.c 2005/07/11 20:46:53     1.18
+++ linux/drivers/bluetooth/hci_ldisc.c 2005/08/08 12:30:32     1.19
@@ -57,8 +57,6 @@
 #ifndef CONFIG_BT_HCIUART_DEBUG
 #undef  BT_DBG
 #define BT_DBG( A... )
-#undef  BT_DMP
-#define BT_DMP( A... )
 #endif
 
 static int reset = 0;
diff -urN linux/drivers/bluetooth/hci_usb.c linux/drivers/bluetooth/hci_usb.c
--- linux/drivers/bluetooth/hci_usb.c   2005/03/18 17:37:11     1.42
+++ linux/drivers/bluetooth/hci_usb.c   2005/08/08 12:30:32     1.43
@@ -57,8 +57,6 @@
 #ifndef CONFIG_BT_HCIUSB_DEBUG
 #undef  BT_DBG
 #define BT_DBG(D...)
-#undef  BT_DMP
-#define BT_DMP(D...)
 #endif
 
 #ifndef CONFIG_BT_HCIUSB_ZERO_PACKET
@@ -110,6 +108,9 @@
        /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
        { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
 
+       /* Kensington Bluetooth USB adapter */
+       { USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET },
+
        /* ISSC Bluetooth Adapter v3.1 */
        { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
 
@@ -387,10 +388,8 @@
                        urb = &_urb->urb;
                        BT_DBG("%s freeing _urb %p type %d urb %p",
                                        husb->hdev->name, _urb, _urb->type, 
urb);
-                       if (urb->setup_packet)
-                               kfree(urb->setup_packet);
-                       if (urb->transfer_buffer)
-                               kfree(urb->transfer_buffer);
+                       kfree(urb->setup_packet);
+                       kfree(urb->transfer_buffer);
                        _urb_free(_urb);
                }
 
diff -urN linux/drivers/char/rtc.c linux/drivers/char/rtc.c
--- linux/drivers/char/rtc.c    2005/07/11 20:46:53     1.80
+++ linux/drivers/char/rtc.c    2005/08/08 12:30:33     1.81
@@ -1231,6 +1231,7 @@
 
 void rtc_get_rtc_time(struct rtc_time *rtc_tm)
 {
+       unsigned long uip_watchdog = jiffies;
        unsigned char ctrl;
 #ifdef CONFIG_MACH_DECSTATION
        unsigned int real_year;
@@ -1246,8 +1247,10 @@
         * Once the read clears, read the RTC time (again via ioctl). Easy.
         */
 
-       if (rtc_is_updating() != 0)
-               msleep(20);
+       while (rtc_is_updating() != 0 && jiffies - uip_watchdog < 2*HZ/100) {
+               barrier();
+               cpu_relax();
+       }
 
        /*
         * Only the values that we read from the RTC are set. We leave
diff -urN linux/drivers/char/tpm/Kconfig linux/drivers/char/tpm/Kconfig
--- linux/drivers/char/tpm/Kconfig      2005/08/01 18:24:09     1.3
+++ linux/drivers/char/tpm/Kconfig      2005/08/08 12:30:33     1.4
@@ -17,6 +17,8 @@
          obtained at: <http://sourceforge.net/projects/trousers>.  To 
          compile this driver as a module, choose M here; the module 
          will be called tpm. If unsure, say N.
+         Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI_BUS
+         and CONFIG_PNPACPI.
 
 config TCG_NSC
        tristate "National Semiconductor TPM Interface"
@@ -36,12 +38,13 @@
          as a module, choose M here; the module will be called tpm_atmel.
 
 config TCG_INFINEON
-       tristate "Infineon Technologies SLD 9630 TPM Interface"
-       depends on TCG_TPM
+       tristate "Infineon Technologies TPM Interface"
+       depends on TCG_TPM && PNPACPI
        ---help---
          If you have a TPM security chip from Infineon Technologies
-         say Yes and it will be accessible from within Linux.  To
-         compile this driver as a module, choose M here; the module
+         (either SLD 9630 TT 1.1 or SLB 9635 TT 1.2) say Yes and it
+         will be accessible from within Linux.
+         To compile this driver as a module, choose M here; the module
          will be called tpm_infineon.
          Further information on this driver and the supported hardware
          can be found at http://www.prosec.rub.de/tpm
diff -urN linux/drivers/char/tpm/tpm_infineon.c 
linux/drivers/char/tpm/tpm_infineon.c
--- linux/drivers/char/tpm/tpm_infineon.c       2005/08/01 18:24:09     1.1
+++ linux/drivers/char/tpm/tpm_infineon.c       2005/08/08 12:30:33     1.2
@@ -1,7 +1,7 @@
 /*
  * Description:
  * Device Driver for the Infineon Technologies
- * SLD 9630 TT Trusted Platform Module
+ * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module
  * Specifications at www.trustedcomputinggroup.org
  *
  * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de>
@@ -12,9 +12,10 @@
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation, version 2 of the
  * License.
- *
  */
 
+#include <acpi/acpi_bus.h>
+#include <linux/pnp.h>
 #include "tpm.h"
 
 /* Infineon specific definitions */
@@ -26,8 +27,11 @@
 #define        TPM_MSLEEP_TIME         3
 /* gives number of max. msleep()-calls before throwing timeout */
 #define        TPM_MAX_TRIES           5000
-#define        TCPA_INFINEON_DEV_VEN_VALUE     0x15D1
-#define        TPM_DATA                        (TPM_ADDR + 1) & 0xff
+#define        TPM_INFINEON_DEV_VEN_VALUE      0x15D1
+
+/* These values will be filled after ACPI-call */
+static int TPM_INF_DATA = 0;
+static int TPM_INF_ADDR = 0;
 
 /* TPM header definitions */
 enum infineon_tpm_header {
@@ -305,9 +309,10 @@
 
 static void tpm_inf_cancel(struct tpm_chip *chip)
 {
-       /* Nothing yet!
-          This has something to do with the internal functions
-          of the TPM. Abort isn't really necessary...
+       /*
+          Since we are using the legacy mode to communicate
+          with the TPM, we have no cancel functions, but have
+          a workaround for interrupting the TPM through WTX.
         */
 }
 
@@ -345,6 +350,32 @@
        .miscdev = {.fops = &inf_ops,},
 };
 
+static const struct pnp_device_id tpm_pnp_tbl[] = {
+       /* Infineon TPMs */
+       {"IFX0101", 0},
+       {"IFX0102", 0},
+       {"", 0}
+};
+
+static int __devinit tpm_inf_acpi_probe(struct pnp_dev *dev,
+                                       const struct pnp_device_id *dev_id)
+{
+       TPM_INF_ADDR = (pnp_port_start(dev, 0) & 0xff);
+       TPM_INF_DATA = ((TPM_INF_ADDR + 1) & 0xff);
+       tpm_inf.base = pnp_port_start(dev, 1);
+       dev_info(&dev->dev, "Found %s with ID %s\n",
+                dev->name, dev_id->id);
+       if (!((tpm_inf.base >> 8) & 0xff))
+               tpm_inf.base = 0;
+       return 0;
+}
+
+static struct pnp_driver tpm_inf_pnp = {
+       .name = "tpm_inf_pnp",
+       .id_table = tpm_pnp_tbl,
+       .probe = tpm_inf_acpi_probe,
+};
+
 static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
                                   const struct pci_device_id *pci_id)
 {
@@ -353,64 +384,99 @@
        int vendorid[2];
        int version[2];
        int productid[2];
+       char chipname[20];
 
        if (pci_enable_device(pci_dev))
                return -EIO;
 
        dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device);
 
+       /* read IO-ports from ACPI */
+       pnp_register_driver(&tpm_inf_pnp);
+       pnp_unregister_driver(&tpm_inf_pnp);
+
+       /* Make sure, we have received valid config ports */
+       if (!TPM_INF_ADDR) {
+               pci_disable_device(pci_dev);
+               return -EIO;
+       }
+
        /* query chip for its vendor, its version number a.s.o. */
-       outb(ENABLE_REGISTER_PAIR, TPM_ADDR);
-       outb(IDVENL, TPM_ADDR);
-       vendorid[1] = inb(TPM_DATA);
-       outb(IDVENH, TPM_ADDR);
-       vendorid[0] = inb(TPM_DATA);
-       outb(IDPDL, TPM_ADDR);
-       productid[1] = inb(TPM_DATA);
-       outb(IDPDH, TPM_ADDR);
-       productid[0] = inb(TPM_DATA);
-       outb(CHIP_ID1, TPM_ADDR);
-       version[1] = inb(TPM_DATA);
-       outb(CHIP_ID2, TPM_ADDR);
-       version[0] = inb(TPM_DATA);
-
-       if ((vendorid[0] << 8 | vendorid[1]) == (TCPA_INFINEON_DEV_VEN_VALUE)) {
-
-               /* read IO-ports from TPM */
-               outb(IOLIMH, TPM_ADDR);
-               ioh = inb(TPM_DATA);
-               outb(IOLIML, TPM_ADDR);
-               iol = inb(TPM_DATA);
-               tpm_inf.base = (ioh << 8) | iol;
+       outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
+       outb(IDVENL, TPM_INF_ADDR);
+       vendorid[1] = inb(TPM_INF_DATA);
+       outb(IDVENH, TPM_INF_ADDR);
+       vendorid[0] = inb(TPM_INF_DATA);
+       outb(IDPDL, TPM_INF_ADDR);
+       productid[1] = inb(TPM_INF_DATA);
+       outb(IDPDH, TPM_INF_ADDR);
+       productid[0] = inb(TPM_INF_DATA);
+       outb(CHIP_ID1, TPM_INF_ADDR);
+       version[1] = inb(TPM_INF_DATA);
+       outb(CHIP_ID2, TPM_INF_ADDR);
+       version[0] = inb(TPM_INF_DATA);
+
+       switch ((productid[0] << 8) | productid[1]) {
+       case 6:
+               sprintf(chipname, " (SLD 9630 TT 1.1)");
+               break;
+       case 11:
+               sprintf(chipname, " (SLB 9635 TT 1.2)");
+               break;
+       default:
+               sprintf(chipname, " (unknown chip)");
+               break;
+       }
+       chipname[19] = 0;
+
+       if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
 
                if (tpm_inf.base == 0) {
-                       dev_err(&pci_dev->dev, "No IO-ports set!\n");
+                       dev_err(&pci_dev->dev, "No IO-ports found!\n");
                        pci_disable_device(pci_dev);
-                       return -ENODEV;
+                       return -EIO;
+               }
+               /* configure TPM with IO-ports */
+               outb(IOLIMH, TPM_INF_ADDR);
+               outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
+               outb(IOLIML, TPM_INF_ADDR);
+               outb((tpm_inf.base & 0xff), TPM_INF_DATA);
+
+               /* control if IO-ports are set correctly */
+               outb(IOLIMH, TPM_INF_ADDR);
+               ioh = inb(TPM_INF_DATA);
+               outb(IOLIML, TPM_INF_ADDR);
+               iol = inb(TPM_INF_DATA);
+
+               if ((ioh << 8 | iol) != tpm_inf.base) {
+                       dev_err(&pci_dev->dev,
+                               "Could not set IO-ports to %04x\n",
+                               tpm_inf.base);
+                       pci_disable_device(pci_dev);
+                       return -EIO;
                }
 
                /* activate register */
-               outb(TPM_DAR, TPM_ADDR);
-               outb(0x01, TPM_DATA);
-               outb(DISABLE_REGISTER_PAIR, TPM_ADDR);
+               outb(TPM_DAR, TPM_INF_ADDR);
+               outb(0x01, TPM_INF_DATA);
+               outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
 
                /* disable RESET, LP and IRQC */
                outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
 
                /* Finally, we're done, print some infos */
                dev_info(&pci_dev->dev, "TPM found: "
+                        "config base 0x%x, "
                         "io base 0x%x, "
                         "chip version %02x%02x, "
                         "vendor id %x%x (Infineon), "
                         "product id %02x%02x"
                         "%s\n",
+                        TPM_INF_ADDR,
                         tpm_inf.base,
                         version[0], version[1],
                         vendorid[0], vendorid[1],
-                        productid[0], productid[1], ((productid[0] == 0)
-                                                     && (productid[1] ==
-                                                         6)) ?
-                        " (SLD 9630 TT 1.1)" : "");
+                        productid[0], productid[1], chipname);
 
                rc = tpm_register_hardware(pci_dev, &tpm_inf);
                if (rc < 0) {
@@ -462,6 +528,6 @@
 module_exit(cleanup_inf);
 
 MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
-MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT");
-MODULE_VERSION("1.4");
+MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 
1.2");
+MODULE_VERSION("1.5");
 MODULE_LICENSE("GPL");
diff -urN linux/drivers/char/watchdog/sa1100_wdt.c 
linux/drivers/char/watchdog/sa1100_wdt.c
--- linux/drivers/char/watchdog/sa1100_wdt.c    2005/08/01 18:24:12     1.12
+++ linux/drivers/char/watchdog/sa1100_wdt.c    2005/08/08 12:30:33     1.13
@@ -36,13 +36,10 @@
 #include <asm/uaccess.h>
 
 #define OSCR_FREQ              CLOCK_TICK_RATE
-#define SA1100_CLOSE_MAGIC     (0x5afc4453)
 
 static unsigned long sa1100wdt_users;
-static int expect_close;
 static int pre_margin;
 static int boot_status;
-static int nowayout = WATCHDOG_NOWAYOUT;
 
 /*
  *     Allow only one person to hold it open
@@ -62,55 +59,33 @@
 }
 
 /*
- *     Shut off the timer.
- *     Lock it in if it's a module and we defined ...NOWAYOUT
- *     Oddly, the watchdog can only be enabled, but we can turn off
- *     the interrupt, which appears to prevent the watchdog timing out.
+ * The watchdog cannot be disabled.
+ *
+ * Previous comments suggested that turning off the interrupt by
+ * clearing OIER[E3] would prevent the watchdog timing out but this
+ * does not appear to be true (at least on the PXA255).
  */
 static int sa1100dog_release(struct inode *inode, struct file *file)
 {
-       OSMR3 = OSCR + pre_margin;
-
-       if (expect_close == SA1100_CLOSE_MAGIC) {
-               OIER &= ~OIER_E3;
-       } else {
-               printk(KERN_CRIT "WATCHDOG: WDT device closed unexpectedly.  
WDT will not stop!\n");
-       }
+       printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n");
 
        clear_bit(1, &sa1100wdt_users);
-       expect_close = 0;
 
        return 0;
 }
 
 static ssize_t sa1100dog_write(struct file *file, const char *data, size_t 
len, loff_t *ppos)
 {
-       if (len) {
-               if (!nowayout) {
-                       size_t i;
-
-                       expect_close = 0;
-
-                       for (i = 0; i != len; i++) {
-                               char c;
-
-                               if (get_user(c, data + i))
-                                       return -EFAULT;
-                               if (c == 'V')
-                                       expect_close = SA1100_CLOSE_MAGIC;
-                       }
-               }
+       if (len)
                /* Refresh OSMR3 timer. */
                OSMR3 = OSCR + pre_margin;
-       }
 
        return len;
 }
 
 static struct watchdog_info ident = {
-       .options        = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
-                         WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
-       .identity       = "SA1100 Watchdog",
+       .options        = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | 
WDIOF_KEEPALIVEPING,
+       .identity       = "SA1100/PXA255 Watchdog",
 };
 
 static int sa1100dog_ioctl(struct inode *inode, struct file *file,
@@ -172,7 +147,7 @@
 static struct miscdevice sa1100dog_miscdev =
 {
        .minor          = WATCHDOG_MINOR,
-       .name           = "SA1100/PXA2xx watchdog",
+       .name           = "watchdog",
        .fops           = &sa1100dog_fops,
 };
 
@@ -194,7 +169,6 @@
        if (ret == 0)
                printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n",
                       margin);
-
        return ret;
 }
 
@@ -212,8 +186,5 @@
 module_param(margin, int, 0);
 MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)");
 
-module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
-
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff -urN linux/drivers/fc4/fc.c linux/drivers/fc4/fc.c
--- linux/drivers/fc4/fc.c      2005/08/01 18:24:13     1.24
+++ linux/drivers/fc4/fc.c      2005/08/08 12:30:33     1.25
@@ -1004,8 +1004,8 @@
                return FAILED;
        }
        fc->rst_pkt->eh_state = SCSI_STATE_UNUSED;
-       return SUCCESS;
 #endif
+       return SUCCESS;
 }
 
 static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
diff -urN linux/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux/drivers/ide/ide-probe.c       2005/07/11 20:47:04     1.80
+++ linux/drivers/ide/ide-probe.c       2005/08/08 12:30:33     1.81
@@ -960,6 +960,15 @@
 }
 #endif /* MAX_HWIFS > 1 */
 
+static inline int hwif_to_node(ide_hwif_t *hwif)
+{
+       if (hwif->pci_dev)
+               return pcibus_to_node(hwif->pci_dev->bus);
+       else
+               /* Add ways to determine the node of other busses here */
+               return -1;
+}
+
 /*
  * init request queue
  */
@@ -978,8 +987,7 @@
         *      do not.
         */
 
-       q = blk_init_queue_node(do_ide_request, &ide_lock,
-                               pcibus_to_node(drive->hwif->pci_dev->bus));
+       q = blk_init_queue_node(do_ide_request, &ide_lock, hwif_to_node(hwif));
        if (!q)
                return 1;
 
@@ -1048,6 +1056,8 @@
 
        BUG_ON(in_interrupt());
        BUG_ON(irqs_disabled());        
+       BUG_ON(hwif == NULL);
+
        down(&ide_cfg_sem);
        hwif->hwgroup = NULL;
 #if MAX_HWIFS > 1
@@ -1097,7 +1107,7 @@
                spin_unlock_irq(&ide_lock);
        } else {
                hwgroup = kmalloc_node(sizeof(ide_hwgroup_t), GFP_KERNEL,
-                       pcibus_to_node(hwif->drives[0].hwif->pci_dev->bus));
+                                       hwif_to_node(hwif->drives[0].hwif));
                if (!hwgroup)
                        goto out_up;
 
diff -urN linux/drivers/infiniband/include/ib_cm.h 
linux/drivers/infiniband/include/ib_cm.h
--- linux/drivers/infiniband/include/ib_cm.h    2005/08/01 18:24:16     1.1
+++ linux/drivers/infiniband/include/ib_cm.h    2005/08/08 12:30:33     1.2
@@ -169,7 +169,8 @@
        IB_CM_REJ_INVALID_ALT_TRAFFIC_CLASS     = __constant_htons(21),
        IB_CM_REJ_INVALID_ALT_HOP_LIMIT         = __constant_htons(22),
        IB_CM_REJ_INVALID_ALT_PACKET_RATE       = __constant_htons(23),
-       IB_CM_REJ_PORT_REDIRECT                 = __constant_htons(24),
+       IB_CM_REJ_PORT_CM_REDIRECT              = __constant_htons(24),
+       IB_CM_REJ_PORT_REDIRECT                 = __constant_htons(25),
        IB_CM_REJ_INVALID_MTU                   = __constant_htons(26),
        IB_CM_REJ_INSUFFICIENT_RESP_RESOURCES   = __constant_htons(27),
        IB_CM_REJ_CONSUMER_DEFINED              = __constant_htons(28),
diff -urN linux/drivers/infiniband/ulp/ipoib/ipoib_main.c 
linux/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- linux/drivers/infiniband/ulp/ipoib/ipoib_main.c     2005/04/29 11:15:07     
1.5
+++ linux/drivers/infiniband/ulp/ipoib/ipoib_main.c     2005/08/08 12:30:33     
1.6
@@ -600,9 +600,10 @@
 
                        ipoib_mcast_send(dev, (union ib_gid *) (phdr->hwaddr + 
4), skb);
                } else {
-                       /* unicast GID -- should be ARP reply */
+                       /* unicast GID -- should be ARP or RARP reply */
 
-                       if (be16_to_cpup((u16 *) skb->data) != ETH_P_ARP) {
+                       if ((be16_to_cpup((__be16 *) skb->data) != ETH_P_ARP) &&
+                           (be16_to_cpup((__be16 *) skb->data) != ETH_P_RARP)) 
{
                                ipoib_warn(priv, "Unicast, no %s: type %04x, 
QPN %06x "
                                           IPOIB_GID_FMT "\n",
                                           skb->dst ? "neigh" : "dst",
diff -urN linux/drivers/md/bitmap.c linux/drivers/md/bitmap.c
--- linux/drivers/md/bitmap.c   2005/08/01 18:24:17     1.2
+++ linux/drivers/md/bitmap.c   2005/08/08 12:30:33     1.3
@@ -818,8 +818,7 @@
        return 0;
 }
 
-static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset,
-       unsigned long sectors, int in_sync);
+static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset);
 /* * bitmap_init_from_disk -- called at bitmap_create time to initialize
  * the in-memory bitmap from the on-disk bitmap -- also, sets up the
  * memory mapping of the bitmap file
@@ -828,7 +827,7 @@
  *   previously kicked from the array, we mark all the bits as
  *   1's in order to cause a full resync.
  */
-static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync)
+static int bitmap_init_from_disk(struct bitmap *bitmap)
 {
        unsigned long i, chunks, index, oldindex, bit;
        struct page *page = NULL, *oldpage = NULL;
@@ -929,8 +928,7 @@
                }
                if (test_bit(bit, page_address(page))) {
                        /* if the disk bit is set, set the memory bit */
-                       bitmap_set_memory_bits(bitmap,
-                                       i << CHUNK_BLOCK_SHIFT(bitmap), 1, 
in_sync);
+                       bitmap_set_memory_bits(bitmap, i << 
CHUNK_BLOCK_SHIFT(bitmap));
                        bit_cnt++;
                }
        }
@@ -1426,35 +1424,53 @@
        }
 }
 
-static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset,
-                                  unsigned long sectors, int in_sync)
+static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset)
 {
        /* For each chunk covered by any of these sectors, set the
-        * counter to 1 and set resync_needed unless in_sync.  They should all
+        * counter to 1 and set resync_needed.  They should all
         * be 0 at this point
         */
-       while (sectors) {
-               int secs;
-               bitmap_counter_t *bmc;
-               spin_lock_irq(&bitmap->lock);
-               bmc = bitmap_get_counter(bitmap, offset, &secs, 1);
-               if (!bmc) {
-                       spin_unlock_irq(&bitmap->lock);
-                       return;
-               }
-               if (! *bmc) {
-                       struct page *page;
-                       *bmc = 1 | (in_sync? 0 : NEEDED_MASK);
-                       bitmap_count_page(bitmap, offset, 1);
-                       page = filemap_get_page(bitmap, offset >> 
CHUNK_BLOCK_SHIFT(bitmap));
-                       set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
-               }
+
+       int secs;
+       bitmap_counter_t *bmc;
+       spin_lock_irq(&bitmap->lock);
+       bmc = bitmap_get_counter(bitmap, offset, &secs, 1);
+       if (!bmc) {
                spin_unlock_irq(&bitmap->lock);
-               if (sectors > secs)
-                       sectors -= secs;
-               else
-                       sectors = 0;
+               return;
+       }
+       if (! *bmc) {
+               struct page *page;
+               *bmc = 1 | NEEDED_MASK;
+               bitmap_count_page(bitmap, offset, 1);
+               page = filemap_get_page(bitmap, offset >> 
CHUNK_BLOCK_SHIFT(bitmap));
+               set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
        }
+       spin_unlock_irq(&bitmap->lock);
+
+}
+
+/*
+ * flush out any pending updates
+ */
+void bitmap_flush(mddev_t *mddev)
+{
+       struct bitmap *bitmap = mddev->bitmap;
+       int sleep;
+
+       if (!bitmap) /* there was no bitmap */
+               return;
+
+       /* run the daemon_work three time to ensure everything is flushed
+        * that can be
+        */
+       sleep = bitmap->daemon_sleep;
+       bitmap->daemon_sleep = 0;
+       bitmap_daemon_work(bitmap);
+       bitmap_daemon_work(bitmap);
+       bitmap_daemon_work(bitmap);
+       bitmap->daemon_sleep = sleep;
+       bitmap_update_sb(bitmap);
 }
 
 /*
@@ -1565,7 +1581,8 @@
 
        /* now that we have some pages available, initialize the in-memory
         * bitmap from the on-disk bitmap */
-       err = bitmap_init_from_disk(bitmap, mddev->recovery_cp == MaxSector);
+       err = bitmap_init_from_disk(bitmap);
+
        if (err)
                return err;
 
diff -urN linux/drivers/md/dm-raid1.c linux/drivers/md/dm-raid1.c
--- linux/drivers/md/dm-raid1.c 2005/07/13 11:49:36     1.9
+++ linux/drivers/md/dm-raid1.c 2005/08/08 12:30:33     1.10
@@ -1230,7 +1230,7 @@
        if (r)
                return r;
 
-       _kmirrord_wq = create_workqueue("kmirrord");
+       _kmirrord_wq = create_singlethread_workqueue("kmirrord");
        if (!_kmirrord_wq) {
                DMERR("couldn't start kmirrord");
                dm_dirty_log_exit();
diff -urN linux/drivers/md/md.c linux/drivers/md/md.c
--- linux/drivers/md/md.c       2005/08/01 18:24:17     1.85
+++ linux/drivers/md/md.c       2005/08/08 12:30:33     1.86
@@ -1798,6 +1798,8 @@
                                goto out;
                        mddev->ro = 1;
                } else {
+                       bitmap_flush(mddev);
+                       wait_event(mddev->sb_wait, 
atomic_read(&mddev->pending_writes)==0);
                        if (mddev->ro)
                                set_disk_ro(disk, 0);
                        blk_queue_make_request(mddev->queue, md_fail_request);
@@ -3484,7 +3486,6 @@
                        goto skip;
                }
                ITERATE_MDDEV(mddev2,tmp) {
-                       printk(".");
                        if (mddev2 == mddev)
                                continue;
                        if (mddev2->curr_resync && 
@@ -4007,3 +4008,4 @@
 EXPORT_SYMBOL(md_print_devices);
 EXPORT_SYMBOL(md_check_recovery);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("md");
diff -urN linux/drivers/md/raid1.c linux/drivers/md/raid1.c
--- linux/drivers/md/raid1.c    2005/08/01 18:24:17     1.55
+++ linux/drivers/md/raid1.c    2005/08/08 12:30:33     1.56
@@ -893,7 +893,6 @@
        if (!uptodate) {
                md_error(r1_bio->mddev,
                         conf->mirrors[r1_bio->read_disk].rdev);
-               set_bit(R1BIO_Degraded, &r1_bio->state);
        } else
                set_bit(R1BIO_Uptodate, &r1_bio->state);
        rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev);
@@ -918,10 +917,9 @@
                        mirror = i;
                        break;
                }
-       if (!uptodate) {
+       if (!uptodate)
                md_error(mddev, conf->mirrors[mirror].rdev);
-               set_bit(R1BIO_Degraded, &r1_bio->state);
-       }
+
        update_head_pos(mirror, r1_bio);
 
        if (atomic_dec_and_test(&r1_bio->remaining)) {
@@ -1109,6 +1107,7 @@
        int i;
        int write_targets = 0;
        int sync_blocks;
+       int still_degraded = 0;
 
        if (!conf->r1buf_pool)
        {
@@ -1137,7 +1136,10 @@
                return 0;
        }
 
-       if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 
mddev->degraded) &&
+       /* before building a request, check if we can skip these blocks..
+        * This call the bitmap_start_sync doesn't actually record anything
+        */
+       if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
            !conf->fullsync) {
                /* We can skip this block, and probably several more */
                *skipped = 1;
@@ -1203,24 +1205,23 @@
                if (i == disk) {
                        bio->bi_rw = READ;
                        bio->bi_end_io = end_sync_read;
-               } else if (conf->mirrors[i].rdev &&
-                          !conf->mirrors[i].rdev->faulty &&
-                          (!conf->mirrors[i].rdev->in_sync ||
-                           sector_nr + RESYNC_SECTORS > mddev->recovery_cp)) {
+               } else if (conf->mirrors[i].rdev == NULL ||
+                          conf->mirrors[i].rdev->faulty) {
+                       still_degraded = 1;
+                       continue;
+               } else if (!conf->mirrors[i].rdev->in_sync ||
+                          sector_nr + RESYNC_SECTORS > mddev->recovery_cp) {
                        bio->bi_rw = WRITE;
                        bio->bi_end_io = end_sync_write;
                        write_targets ++;
                } else
+                       /* no need to read or write here */
                        continue;
                bio->bi_sector = sector_nr + conf->mirrors[i].rdev->data_offset;
                bio->bi_bdev = conf->mirrors[i].rdev->bdev;
                bio->bi_private = r1_bio;
        }
 
-       if (write_targets + 1 < conf->raid_disks)
-               /* array degraded, can't clear bitmap */
-               set_bit(R1BIO_Degraded, &r1_bio->state);
-
        if (write_targets == 0) {
                /* There is nowhere to write, so all non-sync
                 * drives must be failed - so we are finished
@@ -1243,7 +1244,7 @@
                        break;
                if (sync_blocks == 0) {
                        if (!bitmap_start_sync(mddev->bitmap, sector_nr,
-                                       &sync_blocks, mddev->degraded) &&
+                                       &sync_blocks, still_degraded) &&
                                        !conf->fullsync)
                                break;
                        if (sync_blocks < (PAGE_SIZE>>9))
diff -urN linux/drivers/media/video/bttv-cards.c 
linux/drivers/media/video/bttv-cards.c
--- linux/drivers/media/video/bttv-cards.c      2005/08/01 18:24:18     1.39
+++ linux/drivers/media/video/bttv-cards.c      2005/08/08 12:30:34     1.40
@@ -95,7 +95,7 @@
 static unsigned int triton1=0;
 static unsigned int vsfx=0;
 static unsigned int latency = UNSET;
-static unsigned int no_overlay=-1;
+int no_overlay=-1;
 
 static unsigned int card[BTTV_MAX]   = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
 static unsigned int pll[BTTV_MAX]    = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
@@ -4296,9 +4296,11 @@
                printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n");
        if (pcipci_fail) {
                printk(KERN_WARNING "bttv: BT848 and your chipset may not work 
together.\n");
-               if (UNSET == no_overlay) {
-                       printk(KERN_WARNING "bttv: going to disable 
overlay.\n");
+               if (!no_overlay) {
+                       printk(KERN_WARNING "bttv: overlay will be 
disabled.\n");
                        no_overlay = 1;
+               } else {
+                       printk(KERN_WARNING "bttv: overlay forced. Use this 
option at your own risk.\n");
                }
        }
        if (UNSET != latency)
diff -urN linux/drivers/media/video/bttv-driver.c 
linux/drivers/media/video/bttv-driver.c
--- linux/drivers/media/video/bttv-driver.c     2005/08/03 15:50:36     1.51
+++ linux/drivers/media/video/bttv-driver.c     2005/08/08 12:30:34     1.52
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-driver.c,v 1.45 2005/07/20 19:43:24 mkrufky Exp $
+    $Id: bttv-driver.c,v 1.52 2005/08/04 00:55:16 mchehab Exp $
 
     bttv - Bt848 frame grabber driver
 
@@ -80,6 +80,7 @@
 static unsigned int uv_ratio    = 50;
 static unsigned int full_luma_range = 0;
 static unsigned int coring      = 0;
+extern int no_overlay;
 
 /* API features (turn on/off stuff for testing) */
 static unsigned int v4l2        = 1;
@@ -2151,6 +2152,10 @@
                return 0;
        }
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+               if (no_overlay > 0) {
+                       printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
+                       return -EINVAL;
+               }
                return setup_window(fh, btv, &f->fmt.win, 1);
        case V4L2_BUF_TYPE_VBI_CAPTURE:
                retval = bttv_switch_type(fh,f->type);
@@ -2224,9 +2229,11 @@
                        /* others */
                        cap->type = VID_TYPE_CAPTURE|
                                VID_TYPE_TUNER|
-                               VID_TYPE_OVERLAY|
                                VID_TYPE_CLIPPING|
                                VID_TYPE_SCALES;
+                       if (no_overlay <= 0)
+                               cap->type |= VID_TYPE_OVERLAY;
+
                        cap->maxwidth  = bttv_tvnorms[btv->tvnorm].swidth;
                        cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
                        cap->minwidth  = 48;
@@ -2302,6 +2309,11 @@
                struct video_window *win = arg;
                struct v4l2_window w2;
 
+               if (no_overlay > 0) {
+                       printk ("VIDIOCSWIN: no_overlay\n");
+                       return -EINVAL;
+               }
+
                w2.field = V4L2_FIELD_ANY;
                w2.w.left    = win->x;
                w2.w.top     = win->y;
@@ -2577,10 +2589,12 @@
                cap->version = BTTV_VERSION_CODE;
                cap->capabilities =
                        V4L2_CAP_VIDEO_CAPTURE |
-                       V4L2_CAP_VIDEO_OVERLAY |
                        V4L2_CAP_VBI_CAPTURE |
                        V4L2_CAP_READWRITE |
                        V4L2_CAP_STREAMING;
+               if (no_overlay <= 0)
+                       cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
+
                if (bttv_tvcards[btv->c.type].tuner != UNSET &&
                    bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
                        cap->capabilities |= V4L2_CAP_TUNER;
@@ -3076,7 +3090,7 @@
 static struct video_device bttv_video_template =
 {
        .name     = "UNSET",
-       .type     = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
+       .type     = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
                    VID_TYPE_CLIPPING|VID_TYPE_SCALES,
        .hardware = VID_HARDWARE_BT848,
        .fops     = &bttv_fops,
@@ -3756,6 +3770,12 @@
 /* register video4linux devices */
 static int __devinit bttv_register_video(struct bttv *btv)
 {
+       if (no_overlay <= 0) {
+               bttv_video_template.type |= VID_TYPE_OVERLAY;
+       } else {
+               printk("bttv: Overlay support disabled.\n");
+       }
+
        /* video */
        btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
         if (NULL == btv->video_dev)
diff -urN linux/drivers/pci/bus.c linux/drivers/pci/bus.c
--- linux/drivers/pci/bus.c     2005/07/11 20:47:42     1.9
+++ linux/drivers/pci/bus.c     2005/08/08 12:30:34     1.10
@@ -60,7 +60,9 @@
                        continue;
 
                /* Ok, try it out.. */
-               ret = allocate_resource(r, res, size, min, -1, align,
+               ret = allocate_resource(r, res, size,
+                                       r->start ? : min,
+                                       -1, align,
                                        alignf, alignf_data);
                if (ret == 0)
                        break;
diff -urN linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- linux/drivers/pci/pci.c     2005/07/13 11:49:52     1.86
+++ linux/drivers/pci/pci.c     2005/08/08 12:30:34     1.87
@@ -222,6 +222,37 @@
 }
 
 /**
+ * pci_restore_bars - restore a devices BAR values (e.g. after wake-up)
+ * @dev: PCI device to have its BARs restored
+ *
+ * Restore the BAR values for a given device, so as to make it
+ * accessible by its driver.
+ */
+void
+pci_restore_bars(struct pci_dev *dev)
+{
+       int i, numres;
+
+       switch (dev->hdr_type) {
+       case PCI_HEADER_TYPE_NORMAL:
+               numres = 6;
+               break;
+       case PCI_HEADER_TYPE_BRIDGE:
+               numres = 2;
+               break;
+       case PCI_HEADER_TYPE_CARDBUS:
+               numres = 1;
+               break;
+       default:
+               /* Should never get here, but just in case... */
+               return;
+       }
+
+       for (i = 0; i < numres; i ++)
+               pci_update_resource(dev, &dev->resource[i], i);
+}
+
+/**
  * pci_set_power_state - Set the power state of a PCI device
  * @dev: PCI device to be suspended
  * @state: PCI power state (D0, D1, D2, D3hot, D3cold) we're entering
@@ -239,7 +270,7 @@
 int
 pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
-       int pm;
+       int pm, need_restore = 0;
        u16 pmcsr, pmc;
 
        /* bound the state we're entering */
@@ -278,14 +309,17 @@
                        return -EIO;
        }
 
+       pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
+
        /* If we're in D3, force entire word to 0.
         * This doesn't affect PME_Status, disables PME_En, and
         * sets PowerState to 0.
         */
-       if (dev->current_state >= PCI_D3hot)
+       if (dev->current_state >= PCI_D3hot) {
+               if (!(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
+                       need_restore = 1;
                pmcsr = 0;
-       else {
-               pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
+       } else {
                pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
                pmcsr |= state;
        }
@@ -308,6 +342,22 @@
                platform_pci_set_power_state(dev, state);
 
        dev->current_state = state;
+
+       /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
+        * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
+        * from D3hot to D0 _may_ perform an internal reset, thereby
+        * going to "D0 Uninitialized" rather than "D0 Initialized".
+        * For example, at least some versions of the 3c905B and the
+        * 3c556B exhibit this behaviour.
+        *
+        * At least some laptop BIOSen (e.g. the Thinkpad T21) leave
+        * devices in a D3hot state at boot.  Consequently, we need to
+        * restore at least the BARs so that the device will be
+        * accessible to its driver.
+        */
+       if (need_restore)
+               pci_restore_bars(dev);
+
        return 0;
 }
 
@@ -805,6 +855,7 @@
 EXPORT_SYMBOL(isa_bridge);
 #endif
 
+EXPORT_SYMBOL_GPL(pci_restore_bars);
 EXPORT_SYMBOL(pci_enable_device_bars);
 EXPORT_SYMBOL(pci_enable_device);
 EXPORT_SYMBOL(pci_disable_device);
diff -urN linux/drivers/pci/setup-res.c linux/drivers/pci/setup-res.c
--- linux/drivers/pci/setup-res.c       2005/04/08 18:58:21     1.29
+++ linux/drivers/pci/setup-res.c       2005/08/08 12:30:34     1.30
@@ -26,13 +26,18 @@
 #include "pci.h"
 
 
-static void
+void
 pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
 {
        struct pci_bus_region region;
        u32 new, check, mask;
        int reg;
 
+       /* Ignore resources for unimplemented BARs and unused resource slots
+          for 64 bit BARs. */
+       if (!res->flags)
+               return;
+
        pcibios_resource_to_bus(dev, &region, res);
 
        pr_debug("  got res [%lx:%lx] bus [%lx:%lx] flags %lx for "
@@ -67,7 +72,7 @@
 
        if ((new & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
            (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) {
-               new = 0; /* currently everyone zeros the high address */
+               new = region.start >> 16 >> 16;
                pci_write_config_dword(dev, reg + 4, new);
                pci_read_config_dword(dev, reg + 4, &check);
                if (check != new) {
diff -urN linux/drivers/pcmcia/yenta_socket.c 
linux/drivers/pcmcia/yenta_socket.c
--- linux/drivers/pcmcia/yenta_socket.c 2005/08/03 15:50:38     1.27
+++ linux/drivers/pcmcia/yenta_socket.c 2005/08/08 12:30:34     1.28
@@ -605,9 +605,8 @@
 
 static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned 
type, int addr_start, int addr_end)
 {
-       struct pci_bus *bus;
        struct resource *root, *res;
-       u32 start, end;
+       struct pci_bus_region region;
        unsigned mask;
 
        res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
@@ -620,15 +619,13 @@
        if (type & IORESOURCE_IO)
                mask = ~3;
 
-       bus = socket->dev->subordinate;
-       res->name = bus->name;
+       res->name = socket->dev->subordinate->name;
        res->flags = type;
 
-       start = config_readl(socket, addr_start) & mask;
-       end = config_readl(socket, addr_end) | ~mask;
-       if (start && end > start && !override_bios) {
-               res->start = start;
-               res->end = end;
+       region.start = config_readl(socket, addr_start) & mask;
+       region.end = config_readl(socket, addr_end) | ~mask;
+       if (region.start && region.end > region.start && !override_bios) {
+               pcibios_bus_to_resource(socket->dev, res, &region);
                root = pci_find_parent_resource(socket->dev, res);
                if (root && (request_resource(root, res) == 0))
                        return;
@@ -642,6 +639,7 @@
                    (yenta_search_res(socket, res, BRIDGE_IO_MIN))) {
                        config_writel(socket, addr_start, res->start);
                        config_writel(socket, addr_end, res->end);
+                       return;
                }
        } else {
                if (type & IORESOURCE_PREFETCH) {
@@ -650,6 +648,7 @@
                            (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
                                config_writel(socket, addr_start, res->start);
                                config_writel(socket, addr_end, res->end);
+                               return;
                        }
                        /* Approximating prefetchable by non-prefetchable */
                        res->flags = IORESOURCE_MEM;
@@ -659,6 +658,7 @@
                    (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
                        config_writel(socket, addr_start, res->start);
                        config_writel(socket, addr_end, res->end);
+                       return;
                }
        }
 
diff -urN linux/drivers/sbus/char/vfc.h linux/drivers/sbus/char/vfc.h
--- linux/drivers/sbus/char/vfc.h       2003/06/01 12:07:42     1.4
+++ linux/drivers/sbus/char/vfc.h       2005/08/08 12:30:34     1.5
@@ -129,8 +129,6 @@
        struct vfc_regs *phys_regs;
        unsigned int control_reg;
        struct semaphore device_lock_sem;
-       struct timer_list poll_timer;
-       wait_queue_head_t poll_wait;
        int instance;
        int busy;
        unsigned long which_io;
diff -urN linux/drivers/sbus/char/vfc_dev.c linux/drivers/sbus/char/vfc_dev.c
--- linux/drivers/sbus/char/vfc_dev.c   2005/04/08 18:58:23     1.37
+++ linux/drivers/sbus/char/vfc_dev.c   2005/08/08 12:30:34     1.38
@@ -137,7 +137,6 @@
        dev->instance=instance;
        init_MUTEX(&dev->device_lock_sem);
        dev->control_reg=0;
-       init_waitqueue_head(&dev->poll_wait);
        dev->busy=0;
        return 0;
 }
diff -urN linux/drivers/sbus/char/vfc_i2c.c linux/drivers/sbus/char/vfc_i2c.c
--- linux/drivers/sbus/char/vfc_i2c.c   2005/08/01 18:24:25     1.7
+++ linux/drivers/sbus/char/vfc_i2c.c   2005/08/08 12:30:34     1.8
@@ -79,25 +79,10 @@
        return 0;
 }
 
-void vfc_i2c_delay_wakeup(struct vfc_dev *dev) 
-{
-       /* Used to profile code and eliminate too many delays */
-       VFC_I2C_DEBUG_PRINTK(("vfc%d: Delaying\n", dev->instance));
-       wake_up(&dev->poll_wait);
-}
-
 void vfc_i2c_delay_no_busy(struct vfc_dev *dev, unsigned long usecs) 
 {
-       DEFINE_WAIT(wait);
-       init_timer(&dev->poll_timer);
-       dev->poll_timer.expires = jiffies + usecs_to_jiffies(usecs);
-       dev->poll_timer.data=(unsigned long)dev;
-       dev->poll_timer.function=(void *)(unsigned long)vfc_i2c_delay_wakeup;
-       add_timer(&dev->poll_timer);
-       prepare_to_wait(&dev->poll_wait, &wait, TASK_UNINTERRUPTIBLE);
-       schedule();
-       del_timer(&dev->poll_timer);
-       finish_wait(&dev->poll_wait, &wait);
+       set_current_state(TASK_UNINTERRUPTIBLE);
+       schedule_timeout(usecs_to_jiffies(usecs));
 }
 
 void inline vfc_i2c_delay(struct vfc_dev *dev) 
diff -urN linux/drivers/scsi/ips.c linux/drivers/scsi/ips.c
--- linux/drivers/scsi/ips.c    2005/07/11 20:47:52     1.56
+++ linux/drivers/scsi/ips.c    2005/08/08 12:30:35     1.57
@@ -133,10 +133,12 @@
 /* 6.10.00  - Remove 1G Addressing Limitations                               */
 /* 6.11.xx  - Get VersionInfo buffer off the stack !              DDTS 60401 */
 /* 6.11.xx  - Make Logical Drive Info structure safe for DMA      DDTS 60639 */
-/* 7.10.xx  - Add highmem_io flag in SCSI Templete for 2.4 kernels           */
+/* 7.10.18  - Add highmem_io flag in SCSI Templete for 2.4 kernels           */
 /*          - Fix path/name for scsi_hosts.h include for 2.6 kernels         */
 /*          - Fix sort order of 7k                                           */
 /*          - Remove 3 unused "inline" functions                             */
+/* 7.12.xx  - Use STATIC functions whereever possible                        */
+/*          - Clean up deprecated MODULE_PARM calls                          */
 /*****************************************************************************/
 
 /*
@@ -207,8 +209,8 @@
 /*
  * DRIVER_VER
  */
-#define IPS_VERSION_HIGH        "7.10"
-#define IPS_VERSION_LOW         ".18 "
+#define IPS_VERSION_HIGH        "7.12"
+#define IPS_VERSION_LOW         ".02 "
 
 #if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
 #warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
diff -urN linux/drivers/scsi/ips.h linux/drivers/scsi/ips.h
--- linux/drivers/scsi/ips.h    2005/08/01 18:24:26     1.31
+++ linux/drivers/scsi/ips.h    2005/08/08 12:30:35     1.32
@@ -87,15 +87,14 @@
       #define scsi_set_pci_device(sh,dev) (0)
    #endif
 
-   #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-   
-      #ifndef irqreturn_t
-         typedef void irqreturn_t;
-      #endif 
-      
+   #ifndef IRQ_NONE
+      typedef void irqreturn_t;
       #define IRQ_NONE
       #define IRQ_HANDLED
       #define IRQ_RETVAL(x)
+   #endif
+   
+   #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
       #define IPS_REGISTER_HOSTS(SHT)      
scsi_register_module(MODULE_SCSI_HA,SHT)
       #define IPS_UNREGISTER_HOSTS(SHT)    
scsi_unregister_module(MODULE_SCSI_HA,SHT)
       #define IPS_ADD_HOST(shost,device)
@@ -123,6 +122,10 @@
    #ifndef min
       #define min(x,y) ((x) < (y) ? x : y)
    #endif
+   
+   #ifndef __iomem       /* For clean compiles in earlier kernels without 
__iomem annotations */
+      #define __iomem
+   #endif
 
    #define pci_dma_hi32(a)         ((a >> 16) >> 16)
    #define pci_dma_lo32(a)         (a & 0xffffffff)
@@ -1206,13 +1209,13 @@
 
 #define IPS_VER_MAJOR 7
 #define IPS_VER_MAJOR_STRING "7"
-#define IPS_VER_MINOR 10
-#define IPS_VER_MINOR_STRING "10"
-#define IPS_VER_BUILD 18
-#define IPS_VER_BUILD_STRING "18"
-#define IPS_VER_STRING "7.10.18"
+#define IPS_VER_MINOR 12
+#define IPS_VER_MINOR_STRING "12"
+#define IPS_VER_BUILD 02
+#define IPS_VER_BUILD_STRING "02"
+#define IPS_VER_STRING "7.12.02"
 #define IPS_RELEASE_ID 0x00020000
-#define IPS_BUILD_IDENT 731
+#define IPS_BUILD_IDENT 761
 #define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All 
Rights Reserved."
 #define IPS_ADAPTECCOPYRIGHT_STRING "(c) Copyright Adaptec, Inc. 2002 to 2004. 
All Rights Reserved."
 #define IPS_DELLCOPYRIGHT_STRING "(c) Copyright Dell 2004. All Rights 
Reserved."
@@ -1223,12 +1226,12 @@
 #define IPS_VER_SERVERAID2 "2.88.13"
 #define IPS_VER_NAVAJO "2.88.13"
 #define IPS_VER_SERVERAID3 "6.10.24"
-#define IPS_VER_SERVERAID4H "7.10.11"
-#define IPS_VER_SERVERAID4MLx "7.10.18"
-#define IPS_VER_SARASOTA "7.10.18"
-#define IPS_VER_MARCO "7.10.18"
-#define IPS_VER_SEBRING "7.10.18"
-#define IPS_VER_KEYWEST "7.10.18"
+#define IPS_VER_SERVERAID4H "7.12.02"
+#define IPS_VER_SERVERAID4MLx "7.12.02"
+#define IPS_VER_SARASOTA "7.12.02"
+#define IPS_VER_MARCO "7.12.02"
+#define IPS_VER_SEBRING "7.12.02"
+#define IPS_VER_KEYWEST "7.12.02"
 
 /* Compatability IDs for various adapters */
 #define IPS_COMPAT_UNKNOWN ""
diff -urN linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- linux/drivers/scsi/st.c     2005/07/11 20:47:52     1.93
+++ linux/drivers/scsi/st.c     2005/08/08 12:30:35     1.94
@@ -4149,12 +4149,10 @@
                        do_create_driverfs_files();
                        return 0;
                }
-               if (st_sysfs_class)
-                       class_destroy(st_sysfs_class);
                unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
-
                                         ST_MAX_TAPE_ENTRIES);
        }
+       class_destroy(st_sysfs_class);
 
        printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", 
SCSI_TAPE_MAJOR);
        return 1;
@@ -4162,13 +4160,11 @@
 
 static void __exit exit_st(void)
 {
-       if (st_sysfs_class)
-               class_destroy(st_sysfs_class);
-       st_sysfs_class = NULL;
        do_remove_driverfs_files();
        scsi_unregister_driver(&st_template.gendrv);
        unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
                                 ST_MAX_TAPE_ENTRIES);
+       class_destroy(st_sysfs_class);
        kfree(scsi_tapes);
        printk(KERN_INFO "st: Unloaded.\n");
 }
diff -urN linux/drivers/scsi/aic7xxx/aic7xxx_osm.c 
linux/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- linux/drivers/scsi/aic7xxx/aic7xxx_osm.c    2005/08/01 18:24:29     1.30
+++ linux/drivers/scsi/aic7xxx/aic7xxx_osm.c    2005/08/08 12:30:35     1.31
@@ -1264,14 +1264,12 @@
        }
        switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
        case AHC_DEV_Q_BASIC:
-               scsi_adjust_queue_depth(sdev,
-                                       MSG_SIMPLE_TASK,
-                                       dev->openings + dev->active);
+               scsi_set_tag_type(sdev, MSG_SIMPLE_TAG);
+               scsi_activate_tcq(sdev, dev->openings + dev->active);
                break;
        case AHC_DEV_Q_TAGGED:
-               scsi_adjust_queue_depth(sdev,
-                                       MSG_ORDERED_TASK,
-                                       dev->openings + dev->active);
+               scsi_set_tag_type(sdev, MSG_ORDERED_TAG);
+               scsi_activate_tcq(sdev, dev->openings + dev->active);
                break;
        default:
                /*
@@ -1280,9 +1278,7 @@
                 * serially on the controller/device.  This should
                 * remove some latency.
                 */
-               scsi_adjust_queue_depth(sdev,
-                                       /*NON-TAGGED*/0,
-                                       /*queue depth*/2);
+               scsi_deactivate_tcq(sdev, 2);
                break;
        }
 }
@@ -1635,9 +1631,9 @@
                spi_period(starget) = tinfo->curr.period;
                spi_width(starget) = tinfo->curr.width;
                spi_offset(starget) = tinfo->curr.offset;
-               spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ;
-               spi_qas(starget) = tinfo->curr.ppr_options & 
MSG_EXT_PPR_QAS_REQ;
-               spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ;
+               spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ 
? 1 : 0;
+               spi_qas(starget) = tinfo->curr.ppr_options & 
MSG_EXT_PPR_QAS_REQ ? 1 : 0;
+               spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ 
? 1 : 0;
                spi_display_xfer_agreement(starget);
                break;
        }
@@ -2429,12 +2425,14 @@
        unsigned int ppr_options = tinfo->goal.ppr_options
                & ~MSG_EXT_PPR_DT_REQ;
        unsigned int period = tinfo->goal.period;
+       unsigned int width = tinfo->goal.width;
        unsigned long flags;
        struct ahc_syncrate *syncrate;
 
        if (dt) {
-               period = 9;     /* 12.5ns is the only period valid for DT */
                ppr_options |= MSG_EXT_PPR_DT_REQ;
+               if (!width)
+                       ahc_linux_set_width(starget, 1);
        } else if (period == 9)
                period = 10;    /* if resetting DT, period must be >= 25ns */
 
diff -urN linux/drivers/scsi/aic7xxx/aicasm/aicasm.c 
linux/drivers/scsi/aic7xxx/aicasm/aicasm.c
--- linux/drivers/scsi/aic7xxx/aicasm/aicasm.c  2003/06/02 12:08:54     1.4
+++ linux/drivers/scsi/aic7xxx/aicasm/aicasm.c  2005/08/08 12:30:35     1.5
@@ -369,7 +369,7 @@
 
                fprintf(ofile, "%s\t0x%02x, 0x%02x, 0x%02x, 0x%02x",
                        cur_instr == STAILQ_FIRST(&seq_program) ? "" : ",\n",
-#if BYTE_ORDER == LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN
                        cur_instr->format.bytes[0],
                        cur_instr->format.bytes[1],
                        cur_instr->format.bytes[2],
@@ -613,7 +613,7 @@
                                line++;
                }
                fprintf(listfile, "%03x %02x%02x%02x%02x", instrptr,
-#if BYTE_ORDER == LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN
                        cur_instr->format.bytes[0],
                        cur_instr->format.bytes[1],
                        cur_instr->format.bytes[2],
diff -urN linux/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h 
linux/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
--- linux/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h        2003/06/02 
12:08:54     1.3
+++ linux/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h        2005/08/08 
12:30:35     1.4
@@ -42,8 +42,10 @@
  * $FreeBSD$
  */
 
+#include <asm/byteorder.h>
+
 struct ins_format1 {
-#if BYTE_ORDER == LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN
        uint32_t        immediate       : 8,
                        source          : 9,
                        destination     : 9,
@@ -61,7 +63,7 @@
 };
 
 struct ins_format2 {
-#if BYTE_ORDER == LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN
        uint32_t        shift_control   : 8,
                        source          : 9,
                        destination     : 9,
@@ -79,7 +81,7 @@
 };
 
 struct ins_format3 {
-#if BYTE_ORDER == LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN
        uint32_t        immediate       : 8,
                        source          : 9,
                        address         : 10,
diff -urN linux/drivers/scsi/ibmvscsi/srp.h linux/drivers/scsi/ibmvscsi/srp.h
--- linux/drivers/scsi/ibmvscsi/srp.h   2005/08/01 18:24:30     1.2
+++ linux/drivers/scsi/ibmvscsi/srp.h   2005/08/08 12:30:35     1.3
@@ -35,7 +35,7 @@
 enum srp_types {
        SRP_LOGIN_REQ_TYPE = 0x00,
        SRP_LOGIN_RSP_TYPE = 0xC0,
-       SRP_LOGIN_REJ_TYPE = 0x80,
+       SRP_LOGIN_REJ_TYPE = 0xC2,
        SRP_I_LOGOUT_TYPE = 0x03,
        SRP_T_LOGOUT_TYPE = 0x80,
        SRP_TSK_MGMT_TYPE = 0x01,
diff -urN linux/drivers/usb/host/ehci-dbg.c linux/drivers/usb/host/ehci-dbg.c
--- linux/drivers/usb/host/ehci-dbg.c   2005/07/11 20:48:07     1.30
+++ linux/drivers/usb/host/ehci-dbg.c   2005/08/08 12:30:36     1.31
@@ -527,7 +527,7 @@
                                                p.qh->period,
                                                le32_to_cpup (&p.qh->hw_info2)
                                                        /* uframe masks */
-                                                       & 0xffff,
+                                                       & (QH_CMASK | QH_SMASK),
                                                p.qh);
                                size -= temp;
                                next += temp;
diff -urN linux/drivers/usb/host/ehci-q.c linux/drivers/usb/host/ehci-q.c
--- linux/drivers/usb/host/ehci-q.c     2005/08/03 15:50:40     1.44
+++ linux/drivers/usb/host/ehci-q.c     2005/08/08 12:30:36     1.45
@@ -222,7 +222,7 @@
                struct ehci_qh  *qh = (struct ehci_qh *) urb->hcpriv;
 
                /* S-mask in a QH means it's an interrupt urb */
-               if ((qh->hw_info2 & __constant_cpu_to_le32 (0x00ff)) != 0) {
+               if ((qh->hw_info2 & __constant_cpu_to_le32 (QH_SMASK)) != 0) {
 
                        /* ... update hc-wide periodic stats (for usbfs) */
                        ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
@@ -428,7 +428,8 @@
                        /* should be rare for periodic transfers,
                         * except maybe high bandwidth ...
                         */
-                       if (qh->period) {
+                       if ((__constant_cpu_to_le32 (QH_SMASK)
+                                       & qh->hw_info2) != 0) {
                                intr_deschedule (ehci, qh);
                                (void) qh_schedule (ehci, qh);
                        } else
diff -urN linux/drivers/usb/host/ehci-sched.c 
linux/drivers/usb/host/ehci-sched.c
--- linux/drivers/usb/host/ehci-sched.c 2005/07/13 11:49:57     1.32
+++ linux/drivers/usb/host/ehci-sched.c 2005/08/08 12:30:36     1.33
@@ -301,7 +301,7 @@
 
        dev_dbg (&qh->dev->dev,
                "link qh%d-%04x/%p start %d [%d/%d us]\n",
-               period, le32_to_cpup (&qh->hw_info2) & 0xffff,
+               period, le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK),
                qh, qh->start, qh->usecs, qh->c_usecs);
 
        /* high bandwidth, or otherwise every microframe */
@@ -385,7 +385,8 @@
 
        dev_dbg (&qh->dev->dev,
                "unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-               qh->period, le32_to_cpup (&qh->hw_info2) & 0xffff,
+               qh->period,
+               le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK),
                qh, qh->start, qh->usecs, qh->c_usecs);
 
        /* qh->qh_next still "live" to HC */
@@ -411,7 +412,7 @@
         * active high speed queues may need bigger delays...
         */
        if (list_empty (&qh->qtd_list)
-                       || (__constant_cpu_to_le32 (0x0ff << 8)
+                       || (__constant_cpu_to_le32 (QH_CMASK)
                                        & qh->hw_info2) != 0)
                wait = 2;
        else
@@ -533,7 +534,7 @@
 
        /* reuse the previous schedule slots, if we can */
        if (frame < qh->period) {
-               uframe = ffs (le32_to_cpup (&qh->hw_info2) & 0x00ff);
+               uframe = ffs (le32_to_cpup (&qh->hw_info2) & QH_SMASK);
                status = check_intr_schedule (ehci, frame, --uframe,
                                qh, &c_mask);
        } else {
@@ -569,10 +570,10 @@
                qh->start = frame;
 
                /* reset S-frame and (maybe) C-frame masks */
-               qh->hw_info2 &= __constant_cpu_to_le32 (~0xffff);
+               qh->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK));
                qh->hw_info2 |= qh->period
                        ? cpu_to_le32 (1 << uframe)
-                       : __constant_cpu_to_le32 (0xff);
+                       : __constant_cpu_to_le32 (QH_SMASK);
                qh->hw_info2 |= c_mask;
        } else
                ehci_dbg (ehci, "reused qh %p schedule\n", qh);
diff -urN linux/drivers/usb/host/ehci.h linux/drivers/usb/host/ehci.h
--- linux/drivers/usb/host/ehci.h       2005/05/19 12:08:31     1.29
+++ linux/drivers/usb/host/ehci.h       2005/08/08 12:30:36     1.30
@@ -385,6 +385,11 @@
        __le32                  hw_info1;        /* see EHCI 3.6.2 */
 #define        QH_HEAD         0x00008000
        __le32                  hw_info2;        /* see EHCI 3.6.2 */
+#define        QH_SMASK        0x000000ff
+#define        QH_CMASK        0x0000ff00
+#define        QH_HUBADDR      0x007f0000
+#define        QH_HUBPORT      0x3f800000
+#define        QH_MULT         0xc0000000
        __le32                  hw_current;      /* qtd list - see EHCI 3.6.4 */
        
        /* qtd overlay (hardware parts of a struct ehci_qtd) */
diff -urN linux/drivers/usb/host/isp116x-hcd.c 
linux/drivers/usb/host/isp116x-hcd.c
--- linux/drivers/usb/host/isp116x-hcd.c        2005/07/13 11:49:57     1.2
+++ linux/drivers/usb/host/isp116x-hcd.c        2005/08/08 12:30:36     1.3
@@ -229,9 +229,11 @@
        struct isp116x_ep *ep;
        struct urb *urb;
        struct ptd *ptd;
-       u16 toggle = 0, dir = PTD_DIR_SETUP, len;
+       u16 len;
 
        for (ep = isp116x->atl_active; ep; ep = ep->active) {
+               u16 toggle = 0, dir = PTD_DIR_SETUP;
+
                BUG_ON(list_empty(&ep->hep->urb_list));
                urb = container_of(ep->hep->urb_list.next,
                                   struct urb, urb_list);
diff -urN linux/drivers/usb/mon/Kconfig linux/drivers/usb/mon/Kconfig
--- linux/drivers/usb/mon/Kconfig       2005/07/11 20:48:10     1.2
+++ linux/drivers/usb/mon/Kconfig       2005/08/08 12:30:36     1.3
@@ -9,9 +9,8 @@
        help
          If you say Y here, a component which captures the USB traffic
          between peripheral-specific drivers and HC drivers will be built.
-         The USB_MON is similar in spirit and may be compatible with Dave
-         Harding's USBMon.
+         For more information, see <file:Documentation/usb/usbmon.txt>.
 
-         This is somewhat experimental at this time, but it should be safe,
-         as long as you aren't using modular USB and try to remove this
-         module.
+         This is somewhat experimental at this time, but it should be safe.
+
+         If unsure, say Y.
diff -urN linux/drivers/usb/mon/Makefile linux/drivers/usb/mon/Makefile
--- linux/drivers/usb/mon/Makefile      2005/07/11 20:48:10     1.2
+++ linux/drivers/usb/mon/Makefile      2005/08/08 12:30:36     1.3
@@ -4,4 +4,5 @@
 
 usbmon-objs    := mon_main.o mon_stat.o mon_text.o
 
+# This does not use CONFIG_USB_MON because we want this to use a tristate.
 obj-$(CONFIG_USB)      += usbmon.o
diff -urN linux/fs/Kconfig linux/fs/Kconfig
--- linux/fs/Kconfig    2005/07/13 11:50:01     1.39
+++ linux/fs/Kconfig    2005/08/08 12:30:36     1.40
@@ -363,12 +363,15 @@
        bool "Inotify file change notification support"
        default y
        ---help---
-         Say Y here to enable inotify support and the /dev/inotify character
-         device.  Inotify is a file change notification system and a
+         Say Y here to enable inotify support and the associated system
+         calls.  Inotify is a file change notification system and a
          replacement for dnotify.  Inotify fixes numerous shortcomings in
          dnotify and introduces several new features.  It allows monitoring
-         of both files and directories via a single open fd.  Multiple file
-         events are supported.
+         of both files and directories via a single open fd.  Other features
+         include multiple file events, one-shot support, and unmount
+         notification.
+
+         For more information, see Documentation/filesystems/inotify.txt
 
          If unsure, say Y.
 
diff -urN linux/fs/bio.c linux/fs/bio.c
--- linux/fs/bio.c      2005/08/01 18:24:39     1.44
+++ linux/fs/bio.c      2005/08/08 12:30:36     1.45
@@ -248,17 +248,13 @@
 {
        request_queue_t *q = bdev_get_queue(bio_src->bi_bdev);
 
-       memcpy(bio->bi_io_vec, bio_src->bi_io_vec, bio_src->bi_max_vecs * 
sizeof(struct bio_vec));
+       memcpy(bio->bi_io_vec, bio_src->bi_io_vec,
+               bio_src->bi_max_vecs * sizeof(struct bio_vec));
 
        bio->bi_sector = bio_src->bi_sector;
        bio->bi_bdev = bio_src->bi_bdev;
        bio->bi_flags |= 1 << BIO_CLONED;
        bio->bi_rw = bio_src->bi_rw;
-
-       /*
-        * notes -- maybe just leave bi_idx alone. assume identical mapping
-        * for the clone
-        */
        bio->bi_vcnt = bio_src->bi_vcnt;
        bio->bi_size = bio_src->bi_size;
        bio->bi_idx = bio_src->bi_idx;
diff -urN linux/fs/namei.c linux/fs/namei.c
--- linux/fs/namei.c    2005/08/03 15:50:42     1.118
+++ linux/fs/namei.c    2005/08/08 12:30:36     1.119
@@ -1801,8 +1801,8 @@
        }
        up(&dentry->d_inode->i_sem);
        if (!error) {
-               fsnotify_rmdir(dentry, dentry->d_inode, dir);
                d_delete(dentry);
+               fsnotify_rmdir(dentry, dentry->d_inode, dir);
        }
        dput(dentry);
 
@@ -1874,8 +1874,9 @@
 
        /* We don't d_delete() NFS sillyrenamed files--they still exist. */
        if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) {
-               fsnotify_unlink(dentry, dir);
+               struct inode *inode = dentry->d_inode;
                d_delete(dentry);
+               fsnotify_unlink(dentry, inode, dir);
        }
 
        return error;
diff -urN linux/fs/namespace.c linux/fs/namespace.c
--- linux/fs/namespace.c        2005/07/13 11:50:01     1.45
+++ linux/fs/namespace.c        2005/08/08 12:30:36     1.46
@@ -160,7 +160,7 @@
                mnt->mnt_root = dget(root);
                mnt->mnt_mountpoint = mnt->mnt_root;
                mnt->mnt_parent = mnt;
-               mnt->mnt_namespace = old->mnt_namespace;
+               mnt->mnt_namespace = current->namespace;
 
                /* stick the duplicate mount on the same expiry list
                 * as the original if that was on one */
diff -urN linux/fs/isofs/compress.c linux/fs/isofs/compress.c
--- linux/fs/isofs/compress.c   2005/05/19 12:08:36     1.15
+++ linux/fs/isofs/compress.c   2005/08/08 12:30:36     1.16
@@ -129,8 +129,14 @@
        cend = le32_to_cpu(*(__le32 *)(bh->b_data + (blockendptr & bufmask)));
        brelse(bh);
 
+       if (cstart > cend)
+               goto eio;
+               
        csize = cend-cstart;
 
+       if (csize > deflateBound(1UL << zisofs_block_shift))
+               goto eio;
+
        /* Now page[] contains an array of pages, any of which can be NULL,
           and the locks on which we hold.  We should now read the data and
           release the pages.  If the pages are NULL the decompressed data
diff -urN linux/include/asm-alpha/pci.h linux/include/asm-alpha/pci.h
--- linux/include/asm-alpha/pci.h       2005/07/13 11:50:09     1.36
+++ linux/include/asm-alpha/pci.h       2005/08/08 12:30:37     1.37
@@ -251,6 +251,9 @@
 extern void pcibios_resource_to_bus(struct pci_dev *, struct pci_bus_region *,
                                    struct resource *);
 
+extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                                   struct pci_bus_region *region);
+
 #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
 
 static inline int pci_proc_domain(struct pci_bus *bus)
diff -urN linux/include/asm-arm/pci.h linux/include/asm-arm/pci.h
--- linux/include/asm-arm/pci.h 2005/07/13 11:50:09     1.29
+++ linux/include/asm-arm/pci.h 2005/08/08 12:30:37     1.30
@@ -60,6 +60,10 @@
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
                         struct resource *res);
 
+extern void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                       struct pci_bus_region *region);
+
 static inline void pcibios_add_platform_entries(struct pci_dev *dev)
 {
 }
diff -urN linux/include/asm-generic/pci.h linux/include/asm-generic/pci.h
--- linux/include/asm-generic/pci.h     2004/11/15 11:49:38     1.3
+++ linux/include/asm-generic/pci.h     2005/08/08 12:30:37     1.4
@@ -22,6 +22,14 @@
        region->end = res->end;
 }
 
+static inline void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                       struct pci_bus_region *region)
+{
+       res->start = region->start;
+       res->end = region->end;
+}
+
 #define pcibios_scan_all_fns(a, b)     0
 
 #ifndef HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ
diff -urN linux/include/asm-i386/pci.h linux/include/asm-i386/pci.h
--- linux/include/asm-i386/pci.h        2005/07/13 11:50:10     1.28
+++ linux/include/asm-i386/pci.h        2005/08/08 12:30:37     1.29
@@ -18,11 +18,9 @@
 #define pcibios_scan_all_fns(a, b)     0
 
 extern unsigned long pci_mem_start;
-#define PCIBIOS_MIN_IO         0x1000
+#define PCIBIOS_MIN_IO         0x4000
 #define PCIBIOS_MIN_MEM                (pci_mem_start)
 
-#define PCIBIOS_MIN_CARDBUS_IO 0x4000
-
 void pcibios_config_init(void);
 struct pci_bus * pcibios_scan_root(int bus);
 
diff -urN linux/include/asm-i386/mach-visws/do_timer.h 
linux/include/asm-i386/mach-visws/do_timer.h
--- linux/include/asm-i386/mach-visws/do_timer.h        2004/10/25 20:44:43     
1.4
+++ linux/include/asm-i386/mach-visws/do_timer.h        2005/08/08 12:30:37     
1.5
@@ -1,6 +1,7 @@
 /* defines for inline arch setup functions */
 
 #include <asm/fixmap.h>
+#include <asm/i8259.h>
 #include "cobalt.h"
 
 static inline void do_timer_interrupt_hook(struct pt_regs *regs)
diff -urN linux/include/asm-parisc/pci.h linux/include/asm-parisc/pci.h
--- linux/include/asm-parisc/pci.h      2005/07/11 20:48:37     1.15
+++ linux/include/asm-parisc/pci.h      2005/08/08 12:30:37     1.16
@@ -253,6 +253,10 @@
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
                         struct resource *res);
 
+extern void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                       struct pci_bus_region *region);
+
 static inline void pcibios_add_platform_entries(struct pci_dev *dev)
 {
 }
diff -urN linux/include/asm-ppc/pci.h linux/include/asm-ppc/pci.h
--- linux/include/asm-ppc/pci.h 2005/07/13 11:50:12     1.35
+++ linux/include/asm-ppc/pci.h 2005/08/08 12:30:37     1.36
@@ -105,6 +105,10 @@
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
                        struct resource *res);
 
+extern void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                       struct pci_bus_region *region);
+
 extern void pcibios_add_platform_entries(struct pci_dev *dev);
 
 struct file;
diff -urN linux/include/asm-ppc/pgtable.h linux/include/asm-ppc/pgtable.h
--- linux/include/asm-ppc/pgtable.h     2005/07/11 20:48:38     1.67
+++ linux/include/asm-ppc/pgtable.h     2005/08/08 12:30:37     1.68
@@ -202,18 +202,64 @@
  *
  * Note that these bits preclude future use of a page size
  * less than 4KB.
+ *
+ *
+ * PPC 440 core has following TLB attribute fields;
+ *
+ *   TLB1:
+ *   0  1  2  3  4  ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ *   RPN.................................  -  -  -  -  -  - ERPN.......
+ *
+ *   TLB2:
+ *   0  1  2  3  4  ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ *   -  -  -  -  -    - U0 U1 U2 U3 W  I  M  G  E   - UX UW UR SX SW SR
+ *
+ * There are some constrains and options, to decide mapping software bits
+ * into TLB entry.
+ *
+ *   - PRESENT *must* be in the bottom three bits because swap cache
+ *     entries use the top 29 bits for TLB2.
+ *
+ *   - FILE *must* be in the bottom three bits because swap cache
+ *     entries use the top 29 bits for TLB2.
+ *
+ *   - CACHE COHERENT bit (M) has no effect on PPC440 core, because it
+ *     doesn't support SMP. So we can use this as software bit, like
+ *     DIRTY.
+ *
+ * With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used
+ * for memory protection related functions (see PTE structure in
+ * include/asm-ppc/mmu.h).  The _PAGE_XXX definitions in this file map to the
+ * above bits.  Note that the bit values are CPU specific, not architecture
+ * specific.
+ *
+ * The kernel PTE entry holds an arch-dependent swp_entry structure under
+ * certain situations. In other words, in such situations some portion of
+ * the PTE bits are used as a swp_entry. In the PPC implementation, the
+ * 3-24th LSB are shared with swp_entry, however the 0-2nd three LSB still
+ * hold protection values. That means the three protection bits are
+ * reserved for both PTE and SWAP entry at the most significant three
+ * LSBs.
+ *
+ * There are three protection bits available for SWAP entry:
+ *     _PAGE_PRESENT
+ *     _PAGE_FILE
+ *     _PAGE_HASHPTE (if HW has)
+ *
+ * So those three bits have to be inside of 0-2nd LSB of PTE.
+ *
  */
+
 #define _PAGE_PRESENT  0x00000001              /* S: PTE valid */
 #define        _PAGE_RW        0x00000002              /* S: Write permission 
*/
-#define        _PAGE_DIRTY     0x00000004              /* S: Page dirty */
+#define _PAGE_FILE     0x00000004              /* S: nonlinear file mapping */
 #define _PAGE_ACCESSED 0x00000008              /* S: Page referenced */
 #define _PAGE_HWWRITE  0x00000010              /* H: Dirty & RW */
 #define _PAGE_HWEXEC   0x00000020              /* H: Execute permission */
 #define        _PAGE_USER      0x00000040              /* S: User page */
 #define        _PAGE_ENDIAN    0x00000080              /* H: E bit */
 #define        _PAGE_GUARDED   0x00000100              /* H: G bit */
-#define        _PAGE_COHERENT  0x00000200              /* H: M bit */
-#define _PAGE_FILE     0x00000400              /* S: nonlinear file mapping */
+#define        _PAGE_DIRTY     0x00000200              /* S: Page dirty */
 #define        _PAGE_NO_CACHE  0x00000400              /* H: I bit */
 #define        _PAGE_WRITETHRU 0x00000800              /* H: W bit */
 
diff -urN linux/include/asm-ppc64/machdep.h linux/include/asm-ppc64/machdep.h
--- linux/include/asm-ppc64/machdep.h   2005/08/01 18:24:52     1.27
+++ linux/include/asm-ppc64/machdep.h   2005/08/08 12:30:38     1.28
@@ -84,7 +84,7 @@
 
        void            (*init_IRQ)(void);
        int             (*get_irq)(struct pt_regs *);
-       void            (*cpu_irq_down)(void);
+       void            (*cpu_irq_down)(int secondary);
 
        /* PCI stuff */
        void            (*pcibios_fixup)(void);
diff -urN linux/include/asm-ppc64/pci.h linux/include/asm-ppc64/pci.h
--- linux/include/asm-ppc64/pci.h       2005/07/13 11:50:12     1.21
+++ linux/include/asm-ppc64/pci.h       2005/08/08 12:30:38     1.22
@@ -134,6 +134,10 @@
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
                        struct resource *res);
 
+extern void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                       struct pci_bus_region *region);
+
 extern int
 unmap_bus_range(struct pci_bus *bus);
 
diff -urN linux/include/asm-ppc64/xics.h linux/include/asm-ppc64/xics.h
--- linux/include/asm-ppc64/xics.h      2005/07/11 20:48:38     1.6
+++ linux/include/asm-ppc64/xics.h      2005/08/08 12:30:38     1.7
@@ -17,7 +17,7 @@
 void xics_init_IRQ(void);
 int xics_get_irq(struct pt_regs *);
 void xics_setup_cpu(void);
-void xics_teardown_cpu(void);
+void xics_teardown_cpu(int secondary);
 void xics_cause_IPI(int cpu);
 void xics_request_IPIs(void);
 void xics_migrate_irqs_away(void);
diff -urN linux/include/asm-x86_64/pci.h linux/include/asm-x86_64/pci.h
--- linux/include/asm-x86_64/pci.h      2005/07/13 11:50:13     1.20
+++ linux/include/asm-x86_64/pci.h      2005/08/08 12:30:38     1.21
@@ -22,11 +22,9 @@
 extern int no_iommu, force_iommu;
 
 extern unsigned long pci_mem_start;
-#define PCIBIOS_MIN_IO         0x1000
+#define PCIBIOS_MIN_IO         0x4000
 #define PCIBIOS_MIN_MEM                (pci_mem_start)
 
-#define PCIBIOS_MIN_CARDBUS_IO 0x4000
-
 void pcibios_config_init(void);
 struct pci_bus * pcibios_scan_root(int bus);
 extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int 
len, u32 *value);
diff -urN linux/include/linux/blkdev.h linux/include/linux/blkdev.h
--- linux/include/linux/blkdev.h        2005/07/11 20:48:47     1.104
+++ linux/include/linux/blkdev.h        2005/08/08 12:30:38     1.105
@@ -301,6 +301,7 @@
        struct list_head busy_list;     /* fifo list of busy tags */
        int busy;                       /* current depth */
        int max_depth;                  /* what we will send to device */
+       int real_max_depth;             /* what the array can hold */
        atomic_t refcnt;                /* map can be shared */
 };
 
diff -urN linux/include/linux/fsnotify.h linux/include/linux/fsnotify.h
--- linux/include/linux/fsnotify.h      2005/08/03 15:50:44     1.3
+++ linux/include/linux/fsnotify.h      2005/08/08 12:30:38     1.4
@@ -46,10 +46,8 @@
 /*
  * fsnotify_unlink - file was unlinked
  */
-static inline void fsnotify_unlink(struct dentry *dentry, struct inode *dir)
+static inline void fsnotify_unlink(struct dentry *dentry, struct inode *inode, 
struct inode *dir)
 {
-       struct inode *inode = dentry->d_inode;
-
        inode_dir_notify(dir, DN_DELETE);
        inotify_inode_queue_event(dir, IN_DELETE, 0, dentry->d_name.name);
        inotify_inode_queue_event(inode, IN_DELETE_SELF, 0, NULL);
diff -urN linux/include/linux/mm.h linux/include/linux/mm.h
--- linux/include/linux/mm.h    2005/07/11 20:48:48     1.131
+++ linux/include/linux/mm.h    2005/08/08 12:30:38     1.132
@@ -625,10 +625,16 @@
  * Used to decide whether a process gets delivered SIGBUS or
  * just gets major/minor fault counters bumped up.
  */
-#define VM_FAULT_OOM   (-1)
-#define VM_FAULT_SIGBUS        0
-#define VM_FAULT_MINOR 1
-#define VM_FAULT_MAJOR 2
+#define VM_FAULT_OOM   0x00
+#define VM_FAULT_SIGBUS        0x01
+#define VM_FAULT_MINOR 0x02
+#define VM_FAULT_MAJOR 0x03
+
+/* 
+ * Special case for get_user_pages.
+ * Must be in a distinct bit from the above VM_FAULT_ flags.
+ */
+#define VM_FAULT_WRITE 0x10
 
 #define offset_in_page(p)      ((unsigned long)(p) & ~PAGE_MASK)
 
@@ -704,7 +710,13 @@
 extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, 
unsigned long address));
 extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, 
unsigned long addr, struct page *page, pgprot_t prot);
 extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, 
unsigned long addr, unsigned long pgoff, pgprot_t prot);
-extern int handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, 
unsigned long address, int write_access);
+extern int __handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, 
unsigned long address, int write_access);
+
+static inline int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct 
*vma, unsigned long address, int write_access)
+{
+       return __handle_mm_fault(mm, vma, address, write_access) & 
(~VM_FAULT_WRITE);
+}
+
 extern int make_pages_present(unsigned long addr, unsigned long end);
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void 
*buf, int len, int write);
 void install_arg_page(struct vm_area_struct *, struct page *, unsigned long);
diff -urN linux/include/linux/pci.h linux/include/linux/pci.h
--- linux/include/linux/pci.h   2005/08/03 15:50:44     1.107
+++ linux/include/linux/pci.h   2005/08/08 12:30:38     1.108
@@ -225,6 +225,7 @@
 #define  PCI_PM_CAP_PME_D3cold  0x8000  /* PME# from D3 (cold) */
 #define PCI_PM_CTRL            4       /* PM control and status register */
 #define  PCI_PM_CTRL_STATE_MASK        0x0003  /* Current power state (D0 to 
D3) */
+#define  PCI_PM_CTRL_NO_SOFT_RESET     0x0004  /* No reset for D3hot->D0 */
 #define  PCI_PM_CTRL_PME_ENABLE        0x0100  /* PME pin enable */
 #define  PCI_PM_CTRL_DATA_SEL_MASK     0x1e00  /* Data select (??) */
 #define  PCI_PM_CTRL_DATA_SCALE_MASK   0x6000  /* Data scale (??) */
@@ -816,7 +817,9 @@
 void pci_clear_mwi(struct pci_dev *dev);
 int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask);
+void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
 int pci_assign_resource(struct pci_dev *dev, int i);
+void pci_restore_bars(struct pci_dev *dev);
 
 /* ROM control related routines */
 void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size);
diff -urN linux/include/linux/swap.h linux/include/linux/swap.h
--- linux/include/linux/swap.h  2005/07/13 11:50:14     1.92
+++ linux/include/linux/swap.h  2005/08/08 12:30:38     1.93
@@ -7,7 +7,6 @@
 #include <linux/mmzone.h>
 #include <linux/list.h>
 #include <linux/sched.h>
-#include <linux/pagemap.h>
 
 #include <asm/atomic.h>
 #include <asm/page.h>
@@ -255,6 +254,8 @@
 
 #define si_swapinfo(val) \
        do { (val)->freeswap = (val)->totalswap = 0; } while (0)
+/* only sparc can not include linux/pagemap.h in this file
+ * so leave page_cache_release and release_pages undeclared... */
 #define free_page_and_swap_cache(page) \
        page_cache_release(page)
 #define free_pages_and_swap_cache(pages, nr) \
diff -urN linux/include/linux/zlib.h linux/include/linux/zlib.h
--- linux/include/linux/zlib.h  2003/06/22 23:09:59     1.3
+++ linux/include/linux/zlib.h  2005/08/08 12:30:38     1.4
@@ -506,6 +506,11 @@
    stream state was inconsistent (such as zalloc or state being NULL).
 */
 
+static inline unsigned long deflateBound(unsigned long s)
+{
+       return s + ((s + 7) >> 3) + ((s + 63) >> 6) + 11;
+}
+
 extern int zlib_deflateParams (z_streamp strm, int level, int strategy);
 /*
      Dynamically update the compression level and compression strategy.  The
diff -urN linux/include/linux/raid/bitmap.h linux/include/linux/raid/bitmap.h
--- linux/include/linux/raid/bitmap.h   2005/08/01 18:24:55     1.2
+++ linux/include/linux/raid/bitmap.h   2005/08/08 12:30:38     1.3
@@ -248,6 +248,7 @@
 
 /* these are used only by md/bitmap */
 int  bitmap_create(mddev_t *mddev);
+void bitmap_flush(mddev_t *mddev);
 void bitmap_destroy(mddev_t *mddev);
 int  bitmap_active(struct bitmap *bitmap);
 
diff -urN linux/include/net/bluetooth/bluetooth.h 
linux/include/net/bluetooth/bluetooth.h
--- linux/include/net/bluetooth/bluetooth.h     2005/04/08 18:58:46     1.15
+++ linux/include/net/bluetooth/bluetooth.h     2005/08/08 12:30:39     1.16
@@ -57,12 +57,6 @@
 #define BT_DBG(fmt, arg...)  printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , 
## arg)
 #define BT_ERR(fmt, arg...)  printk(KERN_ERR  "%s: " fmt "\n" , __FUNCTION__ , 
## arg)
 
-#ifdef HCI_DATA_DUMP
-#define BT_DMP(buf, len) bt_dump(__FUNCTION__, buf, len)
-#else
-#define BT_DMP(D...)
-#endif
-
 extern struct proc_dir_entry *proc_bt;
 
 /* Connection and socket states */
@@ -174,8 +168,6 @@
        return n;
 }
 
-void bt_dump(char *pref, __u8 *buf, int count);
-
 int bt_err(__u16 code);
 
 #endif /* __BLUETOOTH_H */
diff -urN linux/ipc/sem.c linux/ipc/sem.c
--- linux/ipc/sem.c     2005/07/11 20:48:59     1.49
+++ linux/ipc/sem.c     2005/08/08 12:30:39     1.50
@@ -895,7 +895,7 @@
        struct sem_undo_list *undo_list;
 
        undo_list = current->sysvsem.undo_list;
-       if ((undo_list != NULL) && (atomic_read(&undo_list->refcnt) != 1))
+       if (undo_list)
                spin_lock(&undo_list->lock);
 }
 
@@ -915,7 +915,7 @@
        struct sem_undo_list *undo_list;
 
        undo_list = current->sysvsem.undo_list;
-       if ((undo_list != NULL) && (atomic_read(&undo_list->refcnt) != 1))
+       if (undo_list)
                spin_unlock(&undo_list->lock);
 }
 
@@ -943,9 +943,7 @@
                if (undo_list == NULL)
                        return -ENOMEM;
                memset(undo_list, 0, size);
-               /* don't initialize unodhd->lock here.  It's done
-                * in copy_semundo() instead.
-                */
+               spin_lock_init(&undo_list->lock);
                atomic_set(&undo_list->refcnt, 1);
                current->sysvsem.undo_list = undo_list;
        }
@@ -1231,8 +1229,6 @@
                error = get_undo_list(&undo_list);
                if (error)
                        return error;
-               if (atomic_read(&undo_list->refcnt) == 1)
-                       spin_lock_init(&undo_list->lock);
                atomic_inc(&undo_list->refcnt);
                tsk->sysvsem.undo_list = undo_list;
        } else 
diff -urN linux/kernel/exit.c linux/kernel/exit.c
--- linux/kernel/exit.c 2005/07/11 20:48:59     1.123
+++ linux/kernel/exit.c 2005/08/08 12:30:39     1.124
@@ -829,8 +829,10 @@
        acct_update_integrals(tsk);
        update_mem_hiwater(tsk);
        group_dead = atomic_dec_and_test(&tsk->signal->live);
-       if (group_dead)
+       if (group_dead) {
+               del_timer_sync(&tsk->signal->real_timer);
                acct_process(code);
+       }
        exit_mm(tsk);
 
        exit_sem(tsk);
diff -urN linux/kernel/posix-timers.c linux/kernel/posix-timers.c
--- linux/kernel/posix-timers.c 2005/08/03 15:50:45     1.32
+++ linux/kernel/posix-timers.c 2005/08/08 12:30:39     1.33
@@ -1166,7 +1166,6 @@
                tmr = list_entry(sig->posix_timers.next, struct k_itimer, list);
                itimer_delete(tmr);
        }
-       del_timer_sync(&sig->real_timer);
 }
 
 /*
diff -urN linux/kernel/sys.c linux/kernel/sys.c
--- linux/kernel/sys.c  2005/08/03 15:50:45     1.97
+++ linux/kernel/sys.c  2005/08/08 12:30:39     1.98
@@ -404,7 +404,6 @@
 {
        notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
        system_state = SYSTEM_HALT;
-       device_suspend(PMSG_SUSPEND);
        device_shutdown();
        printk(KERN_EMERG "System halted.\n");
        machine_halt();
@@ -415,7 +414,6 @@
 {
        notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
        system_state = SYSTEM_POWER_OFF;
-       device_suspend(PMSG_SUSPEND);
        device_shutdown();
        printk(KERN_EMERG "Power down.\n");
        machine_power_off();
diff -urN linux/lib/crc32.c linux/lib/crc32.c
--- linux/lib/crc32.c   2004/05/10 14:25:36     1.10
+++ linux/lib/crc32.c   2005/08/08 12:30:39     1.11
@@ -473,7 +473,7 @@
        init = bitreverse(init);
        crc2 = bitreverse(crc1);
        if (crc1 != bitreverse(crc2))
-               printf("\nBit reversal fail: 0x%08x -> %0x08x -> 0x%08x\n",
+               printf("\nBit reversal fail: 0x%08x -> 0x%08x -> 0x%08x\n",
                       crc1, crc2, bitreverse(crc2));
        crc1 = crc32_le(init, buf, len);
        if (crc1 != crc2)
diff -urN linux/lib/inflate.c linux/lib/inflate.c
--- linux/lib/inflate.c 2004/11/15 11:49:46     1.10
+++ linux/lib/inflate.c 2005/08/08 12:30:39     1.11
@@ -326,7 +326,7 @@
   {
     *t = (struct huft *)NULL;
     *m = 0;
-    return 0;
+    return 2;
   }
 
 DEBG("huft2 ");
@@ -374,6 +374,7 @@
     if ((j = *p++) != 0)
       v[x[j]++] = i;
   } while (++i < n);
+  n = x[g];                   /* set n to length of v */
 
 DEBG("h6 ");
 
@@ -410,12 +411,13 @@
 DEBG1("2 ");
           f -= a + 1;           /* deduct codes from patterns left */
           xp = c + k;
-          while (++j < z)       /* try smaller tables up to z bits */
-          {
-            if ((f <<= 1) <= *++xp)
-              break;            /* enough codes to use up j bits */
-            f -= *xp;           /* else deduct codes from patterns */
-          }
+          if (j < z)
+            while (++j < z)       /* try smaller tables up to z bits */
+            {
+              if ((f <<= 1) <= *++xp)
+                break;            /* enough codes to use up j bits */
+              f -= *xp;           /* else deduct codes from patterns */
+            }
         }
 DEBG1("3 ");
         z = 1 << j;             /* table entries for j-bit table */
diff -urN linux/lib/zlib_inflate/inftrees.c linux/lib/zlib_inflate/inftrees.c
--- linux/lib/zlib_inflate/inftrees.c   2004/09/19 12:30:22     1.4
+++ linux/lib/zlib_inflate/inftrees.c   2005/08/08 12:30:39     1.5
@@ -141,7 +141,7 @@
   {
     *t = NULL;
     *m = 0;
-    return Z_OK;
+    return Z_DATA_ERROR;
   }
 
 
diff -urN linux/mm/hugetlb.c linux/mm/hugetlb.c
--- linux/mm/hugetlb.c  2005/07/11 20:49:02     1.9
+++ linux/mm/hugetlb.c  2005/08/08 12:30:39     1.10
@@ -301,6 +301,7 @@
 {
        struct mm_struct *mm = vma->vm_mm;
        unsigned long address;
+       pte_t *ptep;
        pte_t pte;
        struct page *page;
 
@@ -309,9 +310,17 @@
        BUG_ON(end & ~HPAGE_MASK);
 
        for (address = start; address < end; address += HPAGE_SIZE) {
-               pte = huge_ptep_get_and_clear(mm, address, huge_pte_offset(mm, 
address));
+               ptep = huge_pte_offset(mm, address);
+               if (! ptep)
+                       /* This can happen on truncate, or if an
+                        * mmap() is aborted due to an error before
+                        * the prefault */
+                       continue;
+
+               pte = huge_ptep_get_and_clear(mm, address, ptep);
                if (pte_none(pte))
                        continue;
+
                page = pte_page(pte);
                put_page(page);
        }
diff -urN linux/mm/memory.c linux/mm/memory.c
--- linux/mm/memory.c   2005/08/03 15:50:46     1.137
+++ linux/mm/memory.c   2005/08/08 12:30:39     1.138
@@ -811,15 +811,18 @@
        pte = *ptep;
        pte_unmap(ptep);
        if (pte_present(pte)) {
-               if (write && !pte_dirty(pte))
+               if (write && !pte_write(pte))
                        goto out;
                if (read && !pte_read(pte))
                        goto out;
                pfn = pte_pfn(pte);
                if (pfn_valid(pfn)) {
                        page = pfn_to_page(pfn);
-                       if (accessed)
+                       if (accessed) {
+                               if (write && !pte_dirty(pte) &&!PageDirty(page))
+                                       set_page_dirty(page);
                                mark_page_accessed(page);
+                       }
                        return page;
                }
        }
@@ -941,10 +944,13 @@
                }
                spin_lock(&mm->page_table_lock);
                do {
+                       int write_access = write;
                        struct page *page;
 
                        cond_resched_lock(&mm->page_table_lock);
-                       while (!(page = follow_page(mm, start, write))) {
+                       while (!(page = follow_page(mm, start, write_access))) {
+                               int ret;
+
                                /*
                                 * Shortcut for anonymous pages. We don't want
                                 * to force the creation of pages tables for
@@ -957,7 +963,18 @@
                                        break;
                                }
                                spin_unlock(&mm->page_table_lock);
-                               switch (handle_mm_fault(mm,vma,start,write)) {
+                               ret = __handle_mm_fault(mm, vma, start, 
write_access);
+
+                               /*
+                                * The VM_FAULT_WRITE bit tells us that 
do_wp_page has
+                                * broken COW when necessary, even if 
maybe_mkwrite
+                                * decided not to set pte_write. We can thus 
safely do
+                                * subsequent page lookups as if they were 
reads.
+                                */
+                               if (ret & VM_FAULT_WRITE)
+                                       write_access = 0;
+                               
+                               switch (ret & ~VM_FAULT_WRITE) {
                                case VM_FAULT_MINOR:
                                        tsk->min_flt++;
                                        break;
@@ -1220,6 +1237,7 @@
        struct page *old_page, *new_page;
        unsigned long pfn = pte_pfn(pte);
        pte_t entry;
+       int ret;
 
        if (unlikely(!pfn_valid(pfn))) {
                /*
@@ -1247,7 +1265,7 @@
                        lazy_mmu_prot_update(entry);
                        pte_unmap(page_table);
                        spin_unlock(&mm->page_table_lock);
-                       return VM_FAULT_MINOR;
+                       return VM_FAULT_MINOR|VM_FAULT_WRITE;
                }
        }
        pte_unmap(page_table);
@@ -1274,6 +1292,7 @@
        /*
         * Re-check the pte - we dropped the lock
         */
+       ret = VM_FAULT_MINOR;
        spin_lock(&mm->page_table_lock);
        page_table = pte_offset_map(pmd, address);
        if (likely(pte_same(*page_table, pte))) {
@@ -1290,12 +1309,13 @@
 
                /* Free the old page.. */
                new_page = old_page;
+               ret |= VM_FAULT_WRITE;
        }
        pte_unmap(page_table);
        page_cache_release(new_page);
        page_cache_release(old_page);
        spin_unlock(&mm->page_table_lock);
-       return VM_FAULT_MINOR;
+       return ret;
 
 no_new_page:
        page_cache_release(old_page);
@@ -1987,7 +2007,6 @@
        if (write_access) {
                if (!pte_write(entry))
                        return do_wp_page(mm, vma, address, pte, pmd, entry);
-
                entry = pte_mkdirty(entry);
        }
        entry = pte_mkyoung(entry);
@@ -2002,7 +2021,7 @@
 /*
  * By the time we get here, we already hold the mm semaphore
  */
-int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,
+int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,
                unsigned long address, int write_access)
 {
        pgd_t *pgd;
diff -urN linux/mm/mmap.c linux/mm/mmap.c
--- linux/mm/mmap.c     2005/07/11 20:49:02     1.122
+++ linux/mm/mmap.c     2005/08/08 12:30:39     1.123
@@ -143,7 +143,11 @@
           leave 3% of the size of this process for other processes */
        allowed -= current->mm->total_vm / 32;
 
-       if (atomic_read(&vm_committed_space) < allowed)
+       /*
+        * cast `allowed' as a signed long because vm_committed_space
+        * sometimes has a negative value
+        */
+       if (atomic_read(&vm_committed_space) < (long)allowed)
                return 0;
 
        vm_unacct_memory(pages);
diff -urN linux/mm/mremap.c linux/mm/mremap.c
--- linux/mm/mremap.c   2005/05/26 09:12:49     1.61
+++ linux/mm/mremap.c   2005/08/08 12:30:39     1.62
@@ -229,6 +229,7 @@
         * since do_munmap() will decrement it by old_len == new_len
         */
        mm->total_vm += new_len >> PAGE_SHIFT;
+       __vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
 
        if (do_munmap(mm, old_addr, old_len) < 0) {
                /* OOM: unable to split vma, just get accounts right */
@@ -243,7 +244,6 @@
                        vma->vm_next->vm_flags |= VM_ACCOUNT;
        }
 
-       __vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
        if (vm_flags & VM_LOCKED) {
                mm->locked_vm += new_len >> PAGE_SHIFT;
                if (new_len > old_len)
diff -urN linux/mm/nommu.c linux/mm/nommu.c
--- linux/mm/nommu.c    2005/07/11 20:49:02     1.19
+++ linux/mm/nommu.c    2005/08/08 12:30:39     1.20
@@ -1167,7 +1167,11 @@
           leave 3% of the size of this process for other processes */
        allowed -= current->mm->total_vm / 32;
 
-       if (atomic_read(&vm_committed_space) < allowed)
+       /*
+        * cast `allowed' as a signed long because vm_committed_space
+        * sometimes has a negative value
+        */
+       if (atomic_read(&vm_committed_space) < (long)allowed)
                return 0;
 
        vm_unacct_memory(pages);
diff -urN linux/net/bluetooth/hci_core.c linux/net/bluetooth/hci_core.c
--- linux/net/bluetooth/hci_core.c      2005/05/19 12:08:49     1.24
+++ linux/net/bluetooth/hci_core.c      2005/08/08 12:30:40     1.25
@@ -299,7 +299,6 @@
        read_unlock(&hci_dev_list_lock);
        return hdev;
 }
-EXPORT_SYMBOL(hci_dev_get);
 
 /* ---- Inquiry support ---- */
 static void inquiry_cache_flush(struct hci_dev *hdev)
@@ -1042,7 +1041,6 @@
 
        return 0;
 }
-EXPORT_SYMBOL(hci_send_cmd);
 
 /* Get data from the previously sent command */
 void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
diff -urN linux/net/bluetooth/hci_event.c linux/net/bluetooth/hci_event.c
--- linux/net/bluetooth/hci_event.c     2005/05/19 12:08:49     1.19
+++ linux/net/bluetooth/hci_event.c     2005/08/08 12:30:40     1.20
@@ -1035,9 +1035,11 @@
        ev->type = type;
        memcpy(ev->data, data, dlen);
 
+       bt_cb(skb)->incoming = 1;
+       do_gettimeofday(&skb->stamp);
+
        skb->pkt_type = HCI_EVENT_PKT;
        skb->dev = (void *) hdev;
        hci_send_to_sock(hdev, skb);
        kfree_skb(skb);
 }
-EXPORT_SYMBOL(hci_si_event);
diff -urN linux/net/bluetooth/lib.c linux/net/bluetooth/lib.c
--- linux/net/bluetooth/lib.c   2004/11/15 11:49:51     1.7
+++ linux/net/bluetooth/lib.c   2005/08/08 12:30:40     1.8
@@ -34,31 +34,6 @@
 
 #include <net/bluetooth/bluetooth.h>
 
-void bt_dump(char *pref, __u8 *buf, int count)
-{
-       char *ptr;
-       char line[100];
-       unsigned int i;
-
-       printk(KERN_INFO "%s: dump, len %d\n", pref, count);
-
-       ptr = line;
-       *ptr = 0;
-       for (i = 0; i < count; i++) {
-               ptr += sprintf(ptr, " %2.2X", buf[i]);
-
-               if (i && !((i + 1) % 20)) {
-                       printk(KERN_INFO "%s:%s\n", pref, line);
-                       ptr = line;
-                       *ptr = 0;
-               }
-       }
-
-       if (line[0])
-               printk(KERN_INFO "%s:%s\n", pref, line);
-}
-EXPORT_SYMBOL(bt_dump);
-
 void baswap(bdaddr_t *dst, bdaddr_t *src)
 {
        unsigned char *d = (unsigned char *) dst;
diff -urN linux/net/bluetooth/rfcomm/core.c linux/net/bluetooth/rfcomm/core.c
--- linux/net/bluetooth/rfcomm/core.c   2005/04/08 18:58:49     1.25
+++ linux/net/bluetooth/rfcomm/core.c   2005/08/08 12:30:40     1.26
@@ -389,8 +389,6 @@
                rfcomm_dlc_unlock(d);
 
                skb_queue_purge(&d->tx_queue);
-               rfcomm_session_put(s);
-
                rfcomm_dlc_unlink(d);
        }
 
@@ -600,8 +598,6 @@
                goto failed;
        }
 
-       rfcomm_session_hold(s);
-
        s->initiator = 1;
 
        bacpy(&addr.l2_bdaddr, dst);
diff -urN linux/net/ipv4/fib_semantics.c linux/net/ipv4/fib_semantics.c
--- linux/net/ipv4/fib_semantics.c      2005/07/11 20:49:10     1.28
+++ linux/net/ipv4/fib_semantics.c      2005/08/08 12:30:40     1.29
@@ -593,10 +593,13 @@
                          struct hlist_head *new_laddrhash,
                          unsigned int new_size)
 {
+       struct hlist_head *old_info_hash, *old_laddrhash;
        unsigned int old_size = fib_hash_size;
-       unsigned int i;
+       unsigned int i, bytes;
 
        write_lock(&fib_info_lock);
+       old_info_hash = fib_info_hash;
+       old_laddrhash = fib_info_laddrhash;
        fib_hash_size = new_size;
 
        for (i = 0; i < old_size; i++) {
@@ -636,6 +639,10 @@
        fib_info_laddrhash = new_laddrhash;
 
        write_unlock(&fib_info_lock);
+
+       bytes = old_size * sizeof(struct hlist_head *);
+       fib_hash_free(old_info_hash, bytes);
+       fib_hash_free(old_laddrhash, bytes);
 }
 
 struct fib_info *
diff -urN linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- linux/net/ipv4/tcp_output.c 2005/07/13 11:50:24     1.72
+++ linux/net/ipv4/tcp_output.c 2005/08/08 12:30:40     1.73
@@ -403,11 +403,9 @@
                sk->sk_send_head = skb;
 }
 
-static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb)
+static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, 
unsigned int mss_now)
 {
-       struct tcp_sock *tp = tcp_sk(sk);
-
-       if (skb->len <= tp->mss_cache ||
+       if (skb->len <= mss_now ||
            !(sk->sk_route_caps & NETIF_F_TSO)) {
                /* Avoid the costly divide in the normal
                 * non-TSO case.
@@ -417,10 +415,10 @@
        } else {
                unsigned int factor;
 
-               factor = skb->len + (tp->mss_cache - 1);
-               factor /= tp->mss_cache;
+               factor = skb->len + (mss_now - 1);
+               factor /= mss_now;
                skb_shinfo(skb)->tso_segs = factor;
-               skb_shinfo(skb)->tso_size = tp->mss_cache;
+               skb_shinfo(skb)->tso_size = mss_now;
        }
 }
 
@@ -429,7 +427,7 @@
  * packet to the list.  This won't be called frequently, I hope. 
  * Remember, these are still headerless SKBs at this point.
  */
-static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
+static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, 
unsigned int mss_now)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *buff;
@@ -492,8 +490,8 @@
        }
 
        /* Fix up tso_factor for both original and new SKB.  */
-       tcp_set_skb_tso_segs(sk, skb);
-       tcp_set_skb_tso_segs(sk, buff);
+       tcp_set_skb_tso_segs(sk, skb, mss_now);
+       tcp_set_skb_tso_segs(sk, buff, mss_now);
 
        if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
                tp->lost_out += tcp_skb_pcount(skb);
@@ -569,7 +567,7 @@
         * factor and mss.
         */
        if (tcp_skb_pcount(skb) > 1)
-               tcp_set_skb_tso_segs(sk, skb);
+               tcp_set_skb_tso_segs(sk, skb, tcp_current_mss(sk, 1));
 
        return 0;
 }
@@ -734,12 +732,14 @@
 /* This must be invoked the first time we consider transmitting
  * SKB onto the wire.
  */
-static inline int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb)
+static inline int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb, 
unsigned int mss_now)
 {
        int tso_segs = tcp_skb_pcount(skb);
 
-       if (!tso_segs) {
-               tcp_set_skb_tso_segs(sk, skb);
+       if (!tso_segs ||
+           (tso_segs > 1 &&
+            skb_shinfo(skb)->tso_size != mss_now)) {
+               tcp_set_skb_tso_segs(sk, skb, mss_now);
                tso_segs = tcp_skb_pcount(skb);
        }
        return tso_segs;
@@ -817,7 +817,7 @@
        struct tcp_sock *tp = tcp_sk(sk);
        unsigned int cwnd_quota;
 
-       tcp_init_tso_segs(sk, skb);
+       tcp_init_tso_segs(sk, skb, cur_mss);
 
        if (!tcp_nagle_test(tp, skb, cur_mss, nonagle))
                return 0;
@@ -854,7 +854,7 @@
  * know that all the data is in scatter-gather pages, and that the
  * packet has never been sent out before (and thus is not cloned).
  */
-static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len)
+static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int 
len, unsigned int mss_now)
 {
        struct sk_buff *buff;
        int nlen = skb->len - len;
@@ -887,8 +887,8 @@
        skb_split(skb, buff, len);
 
        /* Fix up tso_factor for both original and new SKB.  */
-       tcp_set_skb_tso_segs(sk, skb);
-       tcp_set_skb_tso_segs(sk, buff);
+       tcp_set_skb_tso_segs(sk, skb, mss_now);
+       tcp_set_skb_tso_segs(sk, buff, mss_now);
 
        /* Link BUFF into the send queue. */
        skb_header_release(buff);
@@ -972,19 +972,18 @@
        if (unlikely(sk->sk_state == TCP_CLOSE))
                return 0;
 
-       skb = sk->sk_send_head;
-       if (unlikely(!skb))
-               return 0;
-
-       tso_segs = tcp_init_tso_segs(sk, skb);
-       cwnd_quota = tcp_cwnd_test(tp, skb);
-       if (unlikely(!cwnd_quota))
-               goto out;
-
        sent_pkts = 0;
-       while (likely(tcp_snd_wnd_test(tp, skb, mss_now))) {
+       while ((skb = sk->sk_send_head)) {
+               tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
                BUG_ON(!tso_segs);
 
+               cwnd_quota = tcp_cwnd_test(tp, skb);
+               if (!cwnd_quota)
+                       break;
+
+               if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now)))
+                       break;
+
                if (tso_segs == 1) {
                        if (unlikely(!tcp_nagle_test(tp, skb, mss_now,
                                                     (tcp_skb_is_last(sk, skb) ?
@@ -1006,11 +1005,11 @@
                                        limit = skb->len - trim;
                        }
                        if (skb->len > limit) {
-                               if (tso_fragment(sk, skb, limit))
+                               if (tso_fragment(sk, skb, limit, mss_now))
                                        break;
                        }
                } else if (unlikely(skb->len > mss_now)) {
-                       if (unlikely(tcp_fragment(sk, skb,  mss_now)))
+                       if (unlikely(tcp_fragment(sk, skb,  mss_now, mss_now)))
                                break;
                }
 
@@ -1026,27 +1025,12 @@
 
                tcp_minshall_update(tp, mss_now, skb);
                sent_pkts++;
-
-               /* Do not optimize this to use tso_segs. If we chopped up
-                * the packet above, tso_segs will no longer be valid.
-                */
-               cwnd_quota -= tcp_skb_pcount(skb);
-
-               BUG_ON(cwnd_quota < 0);
-               if (!cwnd_quota)
-                       break;
-
-               skb = sk->sk_send_head;
-               if (!skb)
-                       break;
-               tso_segs = tcp_init_tso_segs(sk, skb);
        }
 
        if (likely(sent_pkts)) {
                tcp_cwnd_validate(sk, tp);
                return 0;
        }
-out:
        return !tp->packets_out && sk->sk_send_head;
 }
 
@@ -1076,7 +1060,7 @@
 
        BUG_ON(!skb || skb->len < mss_now);
 
-       tso_segs = tcp_init_tso_segs(sk, skb);
+       tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
        cwnd_quota = tcp_snd_test(sk, skb, mss_now, TCP_NAGLE_PUSH);
 
        if (likely(cwnd_quota)) {
@@ -1093,11 +1077,11 @@
                                        limit = skb->len - trim;
                        }
                        if (skb->len > limit) {
-                               if (unlikely(tso_fragment(sk, skb, limit)))
+                               if (unlikely(tso_fragment(sk, skb, limit, 
mss_now)))
                                        return;
                        }
                } else if (unlikely(skb->len > mss_now)) {
-                       if (unlikely(tcp_fragment(sk, skb, mss_now)))
+                       if (unlikely(tcp_fragment(sk, skb, mss_now, mss_now)))
                                return;
                }
 
@@ -1388,7 +1372,7 @@
                int old_factor = tcp_skb_pcount(skb);
                int new_factor;
 
-               if (tcp_fragment(sk, skb, cur_mss))
+               if (tcp_fragment(sk, skb, cur_mss, cur_mss))
                        return -ENOMEM; /* We'll try again later. */
 
                /* New SKB created, account for it. */
@@ -1991,7 +1975,7 @@
                            skb->len > mss) {
                                seg_size = min(seg_size, mss);
                                TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
-                               if (tcp_fragment(sk, skb, seg_size))
+                               if (tcp_fragment(sk, skb, seg_size, mss))
                                        return -1;
                                /* SWS override triggered forced fragmentation.
                                 * Disable TSO, the connection is too sick. */
@@ -2000,7 +1984,7 @@
                                        sk->sk_route_caps &= ~NETIF_F_TSO;
                                }
                        } else if (!tcp_skb_pcount(skb))
-                               tcp_set_skb_tso_segs(sk, skb);
+                               tcp_set_skb_tso_segs(sk, skb, mss);
 
                        TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
                        TCP_SKB_CB(skb)->when = tcp_time_stamp;
diff -urN linux/security/keys/keyctl.c linux/security/keys/keyctl.c
--- linux/security/keys/keyctl.c        2005/07/11 20:49:18     1.4
+++ linux/security/keys/keyctl.c        2005/08/08 12:30:40     1.5
@@ -49,9 +49,6 @@
                goto error;
        type[31] = '\0';
 
-       if (!type[0])
-               goto error;
-
        ret = -EPERM;
        if (type[0] == '.')
                goto error;
@@ -144,6 +141,10 @@
                goto error;
        type[31] = '\0';
 
+       ret = -EPERM;
+       if (type[0] == '.')
+               goto error;
+
        /* pull the description into kernel space */
        ret = -EFAULT;
        dlen = strnlen_user(_description, PAGE_SIZE - 1);
@@ -362,7 +363,7 @@
 
        key_put(key);
  error:
-       return 0;
+       return ret;
 
 } /* end keyctl_revoke_key() */
 
@@ -685,6 +686,8 @@
                        goto can_read_key2;
 
                ret = PTR_ERR(skey);
+               if (ret == -EAGAIN)
+                       ret = -EACCES;
                goto error2;
        }
 
diff -urN linux/security/keys/keyring.c linux/security/keys/keyring.c
--- linux/security/keys/keyring.c       2005/07/13 11:50:29     1.4
+++ linux/security/keys/keyring.c       2005/08/08 12:30:40     1.5
@@ -201,7 +201,11 @@
 
        if (keyring->description) {
                write_lock(&keyring_name_lock);
-               list_del(&keyring->type_data.link);
+
+               if (keyring->type_data.link.next != NULL &&
+                   !list_empty(&keyring->type_data.link))
+                       list_del(&keyring->type_data.link);
+
                write_unlock(&keyring_name_lock);
        }
 
diff -urN linux/security/keys/process_keys.c linux/security/keys/process_keys.c
--- linux/security/keys/process_keys.c  2005/07/11 20:49:18     1.3
+++ linux/security/keys/process_keys.c  2005/08/08 12:30:40     1.4
@@ -678,7 +678,7 @@
                keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL);
                if (IS_ERR(keyring)) {
                        ret = PTR_ERR(keyring);
-                       goto error;
+                       goto error2;
                }
        }
        else if (IS_ERR(keyring)) {
diff -urN linux/security/keys/request_key.c linux/security/keys/request_key.c
--- linux/security/keys/request_key.c   2005/07/11 20:49:19     1.3
+++ linux/security/keys/request_key.c   2005/08/08 12:30:40     1.4
@@ -405,7 +405,7 @@
                key_user_put(user);
 
                /* link the new key into the appropriate keyring */
-               if (!PTR_ERR(key))
+               if (!IS_ERR(key))
                        request_key_link(key, dest_keyring);
        }
 

<Prev in Thread] Current Thread [Next in Thread>